summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/reVC_msvc_amd64.yml (renamed from .github/workflows/re3_msvc_amd64.yml)10
-rw-r--r--.github/workflows/reVC_msvc_x86.yml (renamed from .github/workflows/re3_msvc_x86.yml)12
-rw-r--r--.gitignore3
-rw-r--r--CMakeLists.txt30
-rw-r--r--README.md36
-rw-r--r--gamefiles/TEXT/JAPANESE.gxtbin122022 -> 0 bytes
-rw-r--r--gamefiles/TEXT/american.gxtbin220080 -> 423398 bytes
-rw-r--r--gamefiles/TEXT/french.gxtbin244494 -> 467752 bytes
-rw-r--r--gamefiles/TEXT/german.gxtbin240448 -> 459466 bytes
-rw-r--r--gamefiles/TEXT/italian.gxtbin239912 -> 456762 bytes
-rw-r--r--gamefiles/TEXT/polish.gxtbin239930 -> 0 bytes
-rw-r--r--gamefiles/TEXT/russian.gxtbin220670 -> 0 bytes
-rw-r--r--gamefiles/TEXT/spanish.gxtbin234866 -> 454498 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 -> 0 bytes
-rw-r--r--gamefiles/models/menu.txdbin10244648 -> 0 bytes
-rw-r--r--gamefiles/models/x360btns.txdbin126760 -> 0 bytes
-rw-r--r--premake5.lua808
-rw-r--r--sdk/milessdk/include/mss.h14
-rw-r--r--sdk/milessdk/lib/mss32.libbin15316 -> 15570 bytes
-rw-r--r--sdk/rwsdk/include/d3d8/baaplylt.c793
-rw-r--r--sdk/rwsdk/include/d3d8/rpanisot.h4
-rw-r--r--sdk/rwsdk/include/d3d8/rpanisot.rpe466
-rw-r--r--sdk/rwsdk/include/d3d8/rpcollis.h12
-rw-r--r--sdk/rwsdk/include/d3d8/rpcollis.rpe466
-rw-r--r--sdk/rwsdk/include/d3d8/rpcriter.h488
-rw-r--r--sdk/rwsdk/include/d3d8/rpdbgerr.c2
-rw-r--r--sdk/rwsdk/include/d3d8/rpdbgerr.h19
-rw-r--r--sdk/rwsdk/include/d3d8/rpdmorph.h4
-rw-r--r--sdk/rwsdk/include/d3d8/rpdmorph.rpe466
-rw-r--r--sdk/rwsdk/include/d3d8/rphanim.h756
-rw-r--r--sdk/rwsdk/include/d3d8/rphanim.rpe471
-rw-r--r--sdk/rwsdk/include/d3d8/rplodatm.h5
-rw-r--r--sdk/rwsdk/include/d3d8/rplodatm.rpe466
-rw-r--r--sdk/rwsdk/include/d3d8/rplogo.h2
-rw-r--r--sdk/rwsdk/include/d3d8/rplogo.rpe466
-rw-r--r--sdk/rwsdk/include/d3d8/rpltmap.h11
-rw-r--r--sdk/rwsdk/include/d3d8/rpltmap.rpe466
-rw-r--r--sdk/rwsdk/include/d3d8/rpmatfx.h6
-rw-r--r--sdk/rwsdk/include/d3d8/rpmatfx.rpe466
-rw-r--r--sdk/rwsdk/include/d3d8/rpmipkl.h28
-rw-r--r--sdk/rwsdk/include/d3d8/rpmipkl.rpe466
-rw-r--r--sdk/rwsdk/include/d3d8/rpmorph.h3
-rw-r--r--sdk/rwsdk/include/d3d8/rpmorph.rpe466
-rw-r--r--sdk/rwsdk/include/d3d8/rppatch.h22
-rw-r--r--sdk/rwsdk/include/d3d8/rppatch.rpe466
-rw-r--r--sdk/rwsdk/include/d3d8/rpprtstd.h153
-rw-r--r--sdk/rwsdk/include/d3d8/rpprtstd.rpe472
-rw-r--r--sdk/rwsdk/include/d3d8/rpptank.h113
-rw-r--r--sdk/rwsdk/include/d3d8/rpptank.rpe466
-rw-r--r--sdk/rwsdk/include/d3d8/rppvs.h59
-rw-r--r--sdk/rwsdk/include/d3d8/rppvs.rpe466
-rw-r--r--sdk/rwsdk/include/d3d8/rprandom.h2
-rw-r--r--sdk/rwsdk/include/d3d8/rprandom.rpe466
-rw-r--r--sdk/rwsdk/include/d3d8/rpskin.h60
-rw-r--r--sdk/rwsdk/include/d3d8/rpskin.rpe466
-rw-r--r--sdk/rwsdk/include/d3d8/rpspline.h2
-rw-r--r--sdk/rwsdk/include/d3d8/rpspline.rpe466
-rw-r--r--sdk/rwsdk/include/d3d8/rpstereo.h141
-rw-r--r--sdk/rwsdk/include/d3d8/rpstereo.rpe641
-rw-r--r--sdk/rwsdk/include/d3d8/rpusrdat.h2
-rw-r--r--sdk/rwsdk/include/d3d8/rpusrdat.rpe466
-rw-r--r--sdk/rwsdk/include/d3d8/rpworld.h775
-rw-r--r--sdk/rwsdk/include/d3d8/rt2d.h195
-rw-r--r--sdk/rwsdk/include/d3d8/rt2d.rpe467
-rw-r--r--sdk/rwsdk/include/d3d8/rt2danim.h233
-rw-r--r--sdk/rwsdk/include/d3d8/rt2danim.rpe472
-rw-r--r--sdk/rwsdk/include/d3d8/rtanim.h638
-rw-r--r--sdk/rwsdk/include/d3d8/rtanim.rpe168
-rw-r--r--sdk/rwsdk/include/d3d8/rtbary.h6
-rw-r--r--sdk/rwsdk/include/d3d8/rtbary.rpe466
-rw-r--r--sdk/rwsdk/include/d3d8/rtbezpat.h11
-rw-r--r--sdk/rwsdk/include/d3d8/rtbezpat.rpe466
-rw-r--r--sdk/rwsdk/include/d3d8/rtbmp.h2
-rw-r--r--sdk/rwsdk/include/d3d8/rtbmp.rpe466
-rw-r--r--sdk/rwsdk/include/d3d8/rtcharse.h4
-rw-r--r--sdk/rwsdk/include/d3d8/rtcharse.rpe466
-rw-r--r--sdk/rwsdk/include/d3d8/rtgncpip.h256
-rw-r--r--sdk/rwsdk/include/d3d8/rtgncpip.rpe172
-rw-r--r--sdk/rwsdk/include/d3d8/rtimport.h420
-rw-r--r--sdk/rwsdk/include/d3d8/rtimport.rpe466
-rw-r--r--sdk/rwsdk/include/d3d8/rtintel.h1206
-rw-r--r--sdk/rwsdk/include/d3d8/rtintel.rpe645
-rw-r--r--sdk/rwsdk/include/d3d8/rtintsec.h4
-rw-r--r--sdk/rwsdk/include/d3d8/rtintsec.rpe466
-rw-r--r--sdk/rwsdk/include/d3d8/rtltmap.h95
-rw-r--r--sdk/rwsdk/include/d3d8/rtltmap.rpe466
-rw-r--r--sdk/rwsdk/include/d3d8/rtmipk.h4
-rw-r--r--sdk/rwsdk/include/d3d8/rtmipk.rpe466
-rw-r--r--sdk/rwsdk/include/d3d8/rtpick.h2
-rw-r--r--sdk/rwsdk/include/d3d8/rtpick.rpe466
-rw-r--r--sdk/rwsdk/include/d3d8/rtpitexd.h2
-rw-r--r--sdk/rwsdk/include/d3d8/rtpitexd.rpe466
-rw-r--r--sdk/rwsdk/include/d3d8/rtpng.h2
-rw-r--r--sdk/rwsdk/include/d3d8/rtpng.rpe466
-rw-r--r--sdk/rwsdk/include/d3d8/rtquat.h4
-rw-r--r--sdk/rwsdk/include/d3d8/rtquat.rpe466
-rw-r--r--sdk/rwsdk/include/d3d8/rtras.h2
-rw-r--r--sdk/rwsdk/include/d3d8/rtras.rpe466
-rw-r--r--sdk/rwsdk/include/d3d8/rtray.h6
-rw-r--r--sdk/rwsdk/include/d3d8/rtray.rpe466
-rw-r--r--sdk/rwsdk/include/d3d8/rtskinsp.h57
-rw-r--r--sdk/rwsdk/include/d3d8/rtskinsp.rpe163
-rw-r--r--sdk/rwsdk/include/d3d8/rtslerp.h2
-rw-r--r--sdk/rwsdk/include/d3d8/rtslerp.rpe466
-rw-r--r--sdk/rwsdk/include/d3d8/rtsplpvs.h2
-rw-r--r--sdk/rwsdk/include/d3d8/rtsplpvs.rpe466
-rw-r--r--sdk/rwsdk/include/d3d8/rttiff.h2
-rw-r--r--sdk/rwsdk/include/d3d8/rttiff.rpe466
-rw-r--r--sdk/rwsdk/include/d3d8/rttilerd.h2
-rw-r--r--sdk/rwsdk/include/d3d8/rttilerd.rpe466
-rw-r--r--sdk/rwsdk/include/d3d8/rttoc.h47
-rw-r--r--sdk/rwsdk/include/d3d8/rttoc.rpe466
-rw-r--r--sdk/rwsdk/include/d3d8/rtvcat.rpe466
-rw-r--r--sdk/rwsdk/include/d3d8/rtworld.h2
-rw-r--r--sdk/rwsdk/include/d3d8/rtworld.rpe466
-rw-r--r--sdk/rwsdk/include/d3d8/rwcore.h715
-rw-r--r--sdk/rwsdk/include/d3d8/rwplcore.h1071
-rw-r--r--src/CMakeLists.txt32
-rw-r--r--src/animation/AnimBlendAssocGroup.cpp53
-rw-r--r--src/animation/AnimBlendAssocGroup.h4
-rw-r--r--src/animation/AnimBlendAssociation.cpp45
-rw-r--r--src/animation/AnimBlendAssociation.h26
-rw-r--r--src/animation/AnimBlendClumpData.cpp1
-rw-r--r--src/animation/AnimBlendClumpData.h18
-rw-r--r--src/animation/AnimBlendHierarchy.cpp67
-rw-r--r--src/animation/AnimBlendHierarchy.h5
-rw-r--r--src/animation/AnimBlendNode.cpp55
-rw-r--r--src/animation/AnimBlendNode.h2
-rw-r--r--src/animation/AnimBlendSequence.cpp135
-rw-r--r--src/animation/AnimBlendSequence.h27
-rw-r--r--src/animation/AnimManager.cpp1073
-rw-r--r--src/animation/AnimManager.h59
-rw-r--r--src/animation/AnimationId.h169
-rw-r--r--src/animation/Bones.cpp73
-rw-r--r--src/animation/Bones.h38
-rw-r--r--src/animation/CutsceneMgr.cpp530
-rw-r--r--src/animation/CutsceneMgr.h12
-rw-r--r--src/animation/FrameUpdate.cpp33
-rw-r--r--src/animation/RpAnimBlend.cpp105
-rw-r--r--src/animation/RpAnimBlend.h5
-rw-r--r--src/audio/AudioCollision.h2
-rw-r--r--src/audio/AudioLogic.cpp10022
-rw-r--r--src/audio/AudioManager.cpp355
-rw-r--r--src/audio/AudioManager.h542
-rw-r--r--src/audio/AudioSamples.h3608
-rw-r--r--src/audio/DMAudio.cpp88
-rw-r--r--src/audio/DMAudio.h34
-rw-r--r--src/audio/MusicManager.cpp1629
-rw-r--r--src/audio/MusicManager.h82
-rw-r--r--src/audio/PoliceRadio.cpp707
-rw-r--r--src/audio/PoliceRadio.h2
-rw-r--r--src/audio/audio_enums.h1442
-rw-r--r--src/audio/oal/stream.cpp54
-rw-r--r--src/audio/sampman.h1768
-rw-r--r--src/audio/sampman_miles.cpp661
-rw-r--r--src/audio/sampman_null.cpp19
-rw-r--r--src/audio/sampman_oal.cpp127
-rw-r--r--src/audio/soundlist.h293
-rw-r--r--src/collision/ColBox.h12
-rw-r--r--src/collision/ColModel.cpp19
-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.cpp236
-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.cpp397
-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.cpp10
-rw-r--r--src/control/AutoPilot.h14
-rw-r--r--src/control/Bridge.cpp16
-rw-r--r--src/control/CarAI.cpp260
-rw-r--r--src/control/CarAI.h5
-rw-r--r--src/control/CarCtrl.cpp1277
-rw-r--r--src/control/CarCtrl.h69
-rw-r--r--src/control/Curves.cpp20
-rw-r--r--src/control/Darkel.cpp182
-rw-r--r--src/control/Darkel.h4
-rw-r--r--src/control/GameLogic.cpp330
-rw-r--r--src/control/GameLogic.h38
-rw-r--r--src/control/Garages.cpp1082
-rw-r--r--src/control/Garages.h97
-rw-r--r--src/control/OnscreenTimer.cpp162
-rw-r--r--src/control/OnscreenTimer.h36
-rw-r--r--src/control/PathFind.cpp1113
-rw-r--r--src/control/PathFind.h196
-rw-r--r--src/control/Phones.cpp93
-rw-r--r--src/control/Phones.h10
-rw-r--r--src/control/Pickups.cpp1374
-rw-r--r--src/control/Pickups.h50
-rw-r--r--src/control/Record.cpp425
-rw-r--r--src/control/Remote.cpp21
-rw-r--r--src/control/Remote.h2
-rw-r--r--src/control/Replay.cpp528
-rw-r--r--src/control/Replay.h126
-rw-r--r--src/control/Restart.cpp10
-rw-r--r--src/control/RoadBlocks.cpp258
-rw-r--r--src/control/RoadBlocks.h18
-rw-r--r--src/control/SceneEdit.cpp12
-rw-r--r--src/control/Script.cpp2563
-rw-r--r--src/control/Script.h111
-rw-r--r--src/control/Script2.cpp355
-rw-r--r--src/control/Script3.cpp244
-rw-r--r--src/control/Script4.cpp397
-rw-r--r--src/control/Script5.cpp306
-rw-r--r--src/control/Script6.cpp635
-rw-r--r--src/control/Script7.cpp1402
-rw-r--r--src/control/Script8.cpp612
-rw-r--r--src/control/ScriptCommands.h330
-rw-r--r--src/control/SetPieces.cpp319
-rw-r--r--src/control/SetPieces.h48
-rw-r--r--src/control/TrafficLights.cpp488
-rw-r--r--src/control/TrafficLights.h7
-rw-r--r--src/core/Accident.cpp2
-rw-r--r--src/core/AnimViewer.cpp66
-rw-r--r--src/core/Cam.cpp3342
-rw-r--r--src/core/Camera.cpp1862
-rw-r--r--src/core/Camera.h110
-rw-r--r--src/core/Clock.cpp10
-rw-r--r--src/core/ControllerConfig.cpp124
-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.cpp30
-rw-r--r--src/core/EventList.h9
-rw-r--r--src/core/FileLoader.cpp901
-rw-r--r--src/core/FileLoader.h19
-rw-r--r--src/core/FileMgr.cpp4
-rw-r--r--src/core/FileMgr.h4
-rw-r--r--src/core/Fire.cpp129
-rw-r--r--src/core/Fire.h12
-rw-r--r--src/core/Frontend.cpp7275
-rw-r--r--src/core/Frontend.h780
-rw-r--r--src/core/Frontend_PS2.cpp31
-rw-r--r--src/core/Frontend_PS2.h6
-rw-r--r--src/core/Game.cpp632
-rw-r--r--src/core/Game.h37
-rw-r--r--src/core/General.h16
-rw-r--r--src/core/IniFile.cpp7
-rw-r--r--src/core/MenuScreens.cpp626
-rw-r--r--src/core/MenuScreensCustom.cpp718
-rw-r--r--src/core/Pad.cpp1136
-rw-r--r--src/core/Pad.h33
-rw-r--r--src/core/Placeable.cpp2
-rw-r--r--src/core/Placeable.h1
-rw-r--r--src/core/PlayerInfo.cpp362
-rw-r--r--src/core/PlayerInfo.h45
-rw-r--r--src/core/Pools.cpp98
-rw-r--r--src/core/Pools.h7
-rw-r--r--src/core/Radar.cpp1046
-rw-r--r--src/core/Radar.h183
-rw-r--r--src/core/Ropes.cpp173
-rw-r--r--src/core/Ropes.h31
-rw-r--r--src/core/Stats.cpp1287
-rw-r--r--src/core/Stats.h108
-rw-r--r--src/core/Streaming.cpp1329
-rw-r--r--src/core/Streaming.h40
-rw-r--r--src/core/SurfaceTable.cpp17
-rw-r--r--src/core/SurfaceTable.h28
-rw-r--r--src/core/Timer.cpp16
-rw-r--r--src/core/Timer.h12
-rw-r--r--src/core/User.cpp18
-rw-r--r--src/core/User.h1
-rw-r--r--src/core/Wanted.cpp148
-rw-r--r--src/core/Wanted.h7
-rw-r--r--src/core/World.cpp416
-rw-r--r--src/core/World.h49
-rw-r--r--src/core/ZoneCull.cpp1479
-rw-r--r--src/core/ZoneCull.h88
-rw-r--r--src/core/Zones.cpp733
-rw-r--r--src/core/Zones.h54
-rw-r--r--src/core/common.h45
-rw-r--r--src/core/config.h206
-rw-r--r--src/core/main.cpp560
-rw-r--r--src/core/main.h5
-rw-r--r--src/core/re3.cpp211
-rw-r--r--src/core/templates.h19
-rw-r--r--src/core/timebars.cpp2
-rw-r--r--src/entities/Building.cpp22
-rw-r--r--src/entities/Building.h3
-rw-r--r--src/entities/Dummy.cpp17
-rw-r--r--src/entities/Dummy.h3
-rw-r--r--src/entities/Entity.cpp665
-rw-r--r--src/entities/Entity.h37
-rw-r--r--src/entities/Physical.cpp537
-rw-r--r--src/entities/Physical.h24
-rw-r--r--src/entities/Treadable.h5
-rw-r--r--src/extras/custompipes.cpp4
-rw-r--r--src/extras/custompipes_d3d9.cpp15
-rw-r--r--src/extras/custompipes_gl.cpp8
-rw-r--r--src/extras/frontendoption.cpp50
-rw-r--r--src/extras/frontendoption.h17
-rw-r--r--src/extras/postfx.cpp197
-rw-r--r--src/extras/postfx.h12
-rw-r--r--src/extras/shaders/Makefile21
-rw-r--r--src/extras/shaders/colourfilterIII_PS.csobin452 -> 0 bytes
-rw-r--r--src/extras/shaders/colourfilterIII_PS.inc40
-rw-r--r--src/extras/shaders/colourfilterVC.frag (renamed from src/extras/shaders/colourfilterIII.frag)5
-rw-r--r--src/extras/shaders/colourfilterVC_PS.csobin0 -> 648 bytes
-rw-r--r--src/extras/shaders/colourfilterVC_PS.hlsl (renamed from src/extras/shaders/colourfilterIII_PS.hlsl)10
-rw-r--r--src/extras/shaders/colourfilterVC_PS.inc56
-rw-r--r--src/extras/shaders/colourfilterVC_fs_gl.inc (renamed from src/extras/shaders/colourfilterIII_fs_gl.inc)7
-rw-r--r--src/extras/shaders/neoWorldIII_PS.csobin528 -> 0 bytes
-rw-r--r--src/extras/shaders/neoWorldVC.frag (renamed from src/extras/shaders/neoWorldIII.frag)3
-rw-r--r--src/extras/shaders/neoWorldVC_PS.csobin0 -> 524 bytes
-rw-r--r--src/extras/shaders/neoWorldVC_PS.hlsl (renamed from src/extras/shaders/neoWorldIII_PS.hlsl)2
-rw-r--r--src/extras/shaders/neoWorldVC_PS.inc (renamed from src/extras/shaders/neoWorldIII_PS.inc)30
-rw-r--r--src/extras/shaders/neoWorldVC_fs_gl.inc (renamed from src/extras/shaders/neoWorldIII_fs_gl.inc)5
-rw-r--r--src/fakerw/fake.cpp1
-rw-r--r--src/math/Matrix.cpp29
-rw-r--r--src/math/Matrix.h25
-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.cpp63
-rw-r--r--src/modelinfo/ClumpModelInfo.h14
-rw-r--r--src/modelinfo/MloModelInfo.cpp39
-rw-r--r--src/modelinfo/MloModelInfo.h14
-rw-r--r--src/modelinfo/ModelIndices.h726
-rw-r--r--src/modelinfo/ModelInfo.cpp104
-rw-r--r--src/modelinfo/ModelInfo.h16
-rw-r--r--src/modelinfo/PedModelInfo.cpp293
-rw-r--r--src/modelinfo/PedModelInfo.h43
-rw-r--r--src/modelinfo/SimpleModelInfo.cpp61
-rw-r--r--src/modelinfo/SimpleModelInfo.h20
-rw-r--r--src/modelinfo/TimeModelInfo.h3
-rw-r--r--src/modelinfo/VehicleModelInfo.cpp276
-rw-r--r--src/modelinfo/VehicleModelInfo.h51
-rw-r--r--src/modelinfo/WeaponModelInfo.cpp55
-rw-r--r--src/modelinfo/WeaponModelInfo.h23
-rw-r--r--src/modelinfo/XtraCompsModelInfo.h12
-rw-r--r--src/objects/CutsceneHead.cpp231
-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.cpp3
-rw-r--r--src/objects/DummyObject.h2
-rw-r--r--src/objects/Object.cpp737
-rw-r--r--src/objects/Object.h46
-rw-r--r--src/objects/ObjectData.cpp73
-rw-r--r--src/objects/ParticleObject.cpp876
-rw-r--r--src/objects/ParticleObject.h22
-rw-r--r--src/objects/Projectile.cpp2
-rw-r--r--src/objects/Stinger.cpp232
-rw-r--r--src/objects/Stinger.h40
-rw-r--r--src/peds/CivilianPed.cpp383
-rw-r--r--src/peds/CivilianPed.h16
-rw-r--r--src/peds/CopPed.cpp406
-rw-r--r--src/peds/CopPed.h28
-rw-r--r--src/peds/DummyPed.h2
-rw-r--r--src/peds/EmergencyPed.cpp47
-rw-r--r--src/peds/EmergencyPed.h4
-rw-r--r--src/peds/Gangs.cpp71
-rw-r--r--src/peds/Gangs.h31
-rw-r--r--src/peds/Ped.cpp5042
-rw-r--r--src/peds/Ped.h526
-rw-r--r--src/peds/PedAI.cpp4490
-rw-r--r--src/peds/PedAttractor.cpp785
-rw-r--r--src/peds/PedAttractor.h196
-rw-r--r--src/peds/PedChat.cpp183
-rw-r--r--src/peds/PedDebug.cpp58
-rw-r--r--src/peds/PedFight.cpp2902
-rw-r--r--src/peds/PedIK.cpp491
-rw-r--r--src/peds/PedIK.h2
-rw-r--r--src/peds/PedPlacement.cpp16
-rw-r--r--src/peds/PedPlacement.h4
-rw-r--r--src/peds/PedRoutes.cpp2
-rw-r--r--src/peds/PedType.cpp2
-rw-r--r--src/peds/PedType.h11
-rw-r--r--src/peds/PlayerPed.cpp1109
-rw-r--r--src/peds/PlayerPed.h48
-rw-r--r--src/peds/Population.cpp1325
-rw-r--r--src/peds/Population.h51
-rw-r--r--src/render/2dEffect.h16
-rw-r--r--src/render/Antennas.cpp2
-rw-r--r--src/render/Clouds.cpp225
-rw-r--r--src/render/Clouds.h2
-rw-r--r--src/render/Console.cpp2
-rw-r--r--src/render/Coronas.cpp162
-rw-r--r--src/render/Coronas.h30
-rw-r--r--src/render/Credits.cpp1170
-rw-r--r--src/render/CutsceneShadow.cpp269
-rw-r--r--src/render/CutsceneShadow.h52
-rw-r--r--src/render/Draw.cpp36
-rw-r--r--src/render/Draw.h6
-rw-r--r--src/render/Fluff.cpp1491
-rw-r--r--src/render/Fluff.h181
-rw-r--r--src/render/Font.cpp613
-rw-r--r--src/render/Font.h51
-rw-r--r--src/render/Glass.cpp478
-rw-r--r--src/render/Glass.h9
-rw-r--r--src/render/Hud.cpp1631
-rw-r--r--src/render/Hud.h80
-rw-r--r--src/render/MBlur.cpp536
-rw-r--r--src/render/MBlur.h22
-rw-r--r--src/render/Occlusion.cpp495
-rw-r--r--src/render/Occlusion.h62
-rw-r--r--src/render/Particle.cpp1527
-rw-r--r--src/render/Particle.h40
-rw-r--r--src/render/ParticleMgr.cpp12
-rw-r--r--src/render/ParticleMgr.h26
-rw-r--r--src/render/ParticleType.h17
-rw-r--r--src/render/PlayerSkin.cpp14
-rw-r--r--src/render/PointLights.cpp59
-rw-r--r--src/render/PointLights.h5
-rw-r--r--src/render/RenderBuffer.cpp2
-rw-r--r--src/render/RenderBuffer.h11
-rw-r--r--src/render/Renderer.cpp1187
-rw-r--r--src/render/Renderer.h24
-rw-r--r--src/render/Rubbish.cpp67
-rw-r--r--src/render/Rubbish.h2
-rw-r--r--src/render/ShadowCamera.cpp549
-rw-r--r--src/render/ShadowCamera.h54
-rw-r--r--src/render/Shadows.cpp1265
-rw-r--r--src/render/Shadows.h108
-rw-r--r--src/render/Skidmarks.cpp101
-rw-r--r--src/render/Skidmarks.h25
-rw-r--r--src/render/SpecialFX.cpp569
-rw-r--r--src/render/SpecialFX.h45
-rw-r--r--src/render/Sprite.cpp14
-rw-r--r--src/render/Sprite.h3
-rw-r--r--src/render/Sprite2d.cpp386
-rw-r--r--src/render/Sprite2d.h21
-rw-r--r--src/render/Timecycle.cpp370
-rw-r--r--src/render/Timecycle.h133
-rw-r--r--src/render/WaterCannon.cpp28
-rw-r--r--src/render/WaterCreatures.cpp274
-rw-r--r--src/render/WaterCreatures.h48
-rw-r--r--src/render/WaterLevel.cpp3020
-rw-r--r--src/render/WaterLevel.h118
-rw-r--r--src/render/Weather.cpp473
-rw-r--r--src/render/Weather.h36
-rw-r--r--src/render/WindModifiers.cpp52
-rw-r--r--src/render/WindModifiers.h11
-rw-r--r--src/rw/ClumpRead.cpp1
-rw-r--r--src/rw/Lights.cpp54
-rw-r--r--src/rw/Lights.h1
-rw-r--r--src/rw/MemoryHeap.cpp2
-rw-r--r--src/rw/MemoryHeap.h20
-rw-r--r--src/rw/RwHelper.cpp191
-rw-r--r--src/rw/RwHelper.h11
-rw-r--r--src/rw/TexRead.cpp47
-rw-r--r--src/rw/TxdStore.cpp2
-rw-r--r--src/rw/VisibilityPlugins.cpp530
-rw-r--r--src/rw/VisibilityPlugins.h20
-rw-r--r--src/save/GenericGameStorage.cpp170
-rw-r--r--src/save/GenericGameStorage.h8
-rw-r--r--src/save/PCSave.cpp18
-rw-r--r--src/save/PCSave.h2
-rw-r--r--src/skel/crossplatform.cpp30
-rw-r--r--src/skel/crossplatform.h4
-rw-r--r--src/skel/events.cpp2
-rw-r--r--src/skel/glfw/glfw.cpp96
-rw-r--r--src/skel/platform.h4
-rw-r--r--src/skel/skeleton.cpp6
-rw-r--r--src/skel/win/gta3.icobin2238 -> 0 bytes
-rw-r--r--src/skel/win/gtavc.icobin0 -> 3262 bytes
-rw-r--r--src/skel/win/resource.h2
-rw-r--r--src/skel/win/win.cpp106
-rw-r--r--src/skel/win/win.rc2
-rw-r--r--src/text/Messages.cpp10
-rw-r--r--src/text/Text.cpp295
-rw-r--r--src/text/Text.h41
-rw-r--r--src/vehicles/Automobile.cpp2489
-rw-r--r--src/vehicles/Automobile.h97
-rw-r--r--src/vehicles/Bike.cpp2949
-rw-r--r--src/vehicles/Bike.h160
-rw-r--r--src/vehicles/Boat.cpp1041
-rw-r--r--src/vehicles/Boat.h35
-rw-r--r--src/vehicles/CarGen.cpp174
-rw-r--r--src/vehicles/CarGen.h7
-rw-r--r--src/vehicles/Cranes.cpp45
-rw-r--r--src/vehicles/Cranes.h1
-rw-r--r--src/vehicles/DamageManager.cpp20
-rw-r--r--src/vehicles/Floater.cpp173
-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.cpp211
-rw-r--r--src/vehicles/Heli.h12
-rw-r--r--src/vehicles/Plane.cpp244
-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.cpp78
-rw-r--r--src/vehicles/Vehicle.cpp1676
-rw-r--r--src/vehicles/Vehicle.h219
-rw-r--r--src/weapons/BulletInfo.cpp192
-rw-r--r--src/weapons/Explosion.cpp183
-rw-r--r--src/weapons/Explosion.h27
-rw-r--r--src/weapons/ProjectileInfo.cpp263
-rw-r--r--src/weapons/ProjectileInfo.h1
-rw-r--r--src/weapons/ShotInfo.cpp4
-rw-r--r--src/weapons/Weapon.cpp1841
-rw-r--r--src/weapons/Weapon.h30
-rw-r--r--src/weapons/WeaponEffects.cpp73
-rw-r--r--src/weapons/WeaponInfo.cpp185
-rw-r--r--src/weapons/WeaponInfo.h35
-rw-r--r--src/weapons/WeaponType.h57
-rw-r--r--utils/gxt/american.txt16001
-rw-r--r--utils/gxt/build.bat12
-rw-r--r--utils/gxt/english.txt7026
-rw-r--r--utils/gxt/french.txt17183
-rw-r--r--utils/gxt/german.txt17022
-rw-r--r--utils/gxt/italian.txt17005
-rw-r--r--utils/gxt/russian.txt7979
-rw-r--r--utils/gxt/spanish.txt16777
517 files changed, 142418 insertions, 111935 deletions
diff --git a/.github/workflows/re3_msvc_amd64.yml b/.github/workflows/reVC_msvc_amd64.yml
index 8f22af56..2053a770 100644
--- a/.github/workflows/re3_msvc_amd64.yml
+++ b/.github/workflows/reVC_msvc_amd64.yml
@@ -1,4 +1,4 @@
-name: re3_msvc_amd64
+name: reVC_msvc_amd64
on:
pull_request:
@@ -47,19 +47,19 @@ jobs:
./premake5 vs2019 --with-librw --glewdir=${{env.GLEW_BASE}} --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: Upload artifact to actions
uses: actions/upload-artifact@v2
with:
- name: re3_${{matrix.buildtype}}_${{matrix.platform}}
+ name: reVC_${{matrix.buildtype}}_${{matrix.platform}}
path: ./bin/${{matrix.platform}}/${{matrix.buildtype}}
# - 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 c0432280..99079608 100644
--- a/.github/workflows/re3_msvc_x86.yml
+++ b/.github/workflows/reVC_msvc_x86.yml
@@ -1,4 +1,4 @@
-name: re3_msvc_x86
+name: reVC_msvc_x86
on:
pull_request:
@@ -47,19 +47,19 @@ jobs:
./premake5 vs2019 --with-librw --glewdir=${{env.GLEW_BASE}} --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: Upload artifact to actions
uses: actions/upload-artifact@v2
with:
- name: re3_${{matrix.buildtype}}_${{matrix.platform}}
- path: re3_${{matrix.buildtype}}_${{matrix.platform}}.zip
+ name: reVC_${{matrix.buildtype}}_${{matrix.platform}}
+ path: reVC_${{matrix.buildtype}}_${{matrix.platform}}.zip
# - 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 c7ebb3d1..cfb56bb6 100644
--- a/.gitignore
+++ b/.gitignore
@@ -351,4 +351,5 @@ MigrationBackup/
vendor/glew-2.1.0/
vendor/glfw-3.3.2.bin.WIN32/
-vendor/glfw-3.3.2.bin.WIN64/ \ No newline at end of file
+vendor/glfw-3.3.2.bin.WIN64/
+/vendor/glfw-3.3.2
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5daf1d15..387400b3 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,42 +1,42 @@
cmake_minimum_required(VERSION 3.8)
-project(re3 C CXX)
+project(reVC C CXX)
list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake")
if(WIN32)
- set(RE3_AUDIOS "NULL" "OAL" "MSS")
+ set(REVC_AUDIOS "NULL" "OAL" "MSS")
else()
- set(RE3_AUDIOS "NULL" "OAL")
+ set(REVC_AUDIOS "NULL" "OAL")
endif()
-set(RE3_AUDIO "OAL" CACHE STRING "Audio")
+set(REVC_AUDIO "OAL" CACHE STRING "Audio")
-set_property(CACHE RE3_AUDIO PROPERTY STRINGS ${RE3_AUDIOS})
-message(STATUS "RE3_AUDIO = ${RE3_AUDIO} (choices=${RE3_AUDIOS})")
-set("RE3_AUDIO_${RE3_AUDIO}" ON)
-if(NOT RE3_AUDIO IN_LIST RE3_AUDIOS)
- message(FATAL_ERROR "Illegal RE3_AUDIO=${RE3_AUDIO}")
+set_property(CACHE REVC_AUDIO PROPERTY STRINGS ${REVC_AUDIOS})
+message(STATUS "REVC_AUDIO = ${REVC_AUDIO} (choices=${REVC_AUDIOS})")
+set("REVC_AUDIO_${REVC_AUDIO}" ON)
+if(NOT REVC_AUDIO IN_LIST REVC_AUDIOS)
+ message(FATAL_ERROR "Illegal REVC_AUDIO=${REVC_AUDIO}")
endif()
-if(RE3_INSTALL)
+if(REVC_INSTALL)
include(GNUInstallDirs)
- set(RE3_INSTALL_INCLUDEDIR "${CMAKE_INSTALL_INCLUDEDIR}/re3")
+ set(REVC_INSTALL_INCLUDEDIR "${CMAKE_INSTALL_INCLUDEDIR}/reVC")
endif()
add_subdirectory("vendor/librw")
add_subdirectory(src)
-if(RE3_INSTALL)
+if(REVC_INSTALL)
include(CMakePackageConfigHelpers)
- configure_package_config_file(re3-config.cmake.in re3-config.cmake
+ configure_package_config_file(reVC-config.cmake.in reVC-config.cmake
INSTALL_DESTINATION "${CMAKE_INSTALL_PREFIX}"
)
install(
- FILES "${CMAKE_CURRENT_BINARY_DIR}/re3-config.cmake"
+ FILES "${CMAKE_CURRENT_BINARY_DIR}/reVC-config.cmake"
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
)
install(
- EXPORT re3-targets
+ EXPORT reVC-targets
DESTINATION "${CMAKE_INSTALL_LIBDIR}/cmake/${PROJECT_NAME}"
)
diff --git a/README.md b/README.md
index 27b8d8e9..c0e17db3 100644
--- a/README.md
+++ b/README.md
@@ -1,23 +1,21 @@
-# re3
-[![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)
+# reVC
+[![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/aKYAwCx92H"><img src="https://img.shields.io/badge/discord-join-7289DA.svg?logo=discord&longCache=true&style=flat" /></a>
## Intro
-The aim of this project is to reverse GTA III for PC by replacing
-parts of the game [one by one](https://en.wikipedia.org/wiki/Ship_of_Theseus)
-such that we have a working game at all times.
+The aim of this project is to reverse GTA Vice City for PC.
## How can I try it?
-- re3 requires 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 it from one of the above links (Debug or Release).
-- (Optional) If you want to use optional features like Russian language or menu map, copy the files in /gamefiles folder to your game root folder.
-- Move re3.exe to GTA 3 directory and run it.
+- 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 it from one of the above links (Debug or Release).
+- (Optional) If you want to use optional features, copy the files in /gamefiles folder to your game root folder.
+- Move reVC.exe to GTA VC directory and run it.
## Preparing the environment for building
-You may want to point GTA_III_RE_DIR environment variable to GTA3 root folder if you want executable to be moved there via post-build script.
+You may want to point GTA_VC_RE_DIR environment variable to GTA VC root folder if you want executable to be moved there via post-build script.
- For Linux, proceed: [Building on Linux](https://github.com/GTAmodding/re3/wiki/Building-on-Linux)
- For FreeBSD, proceed: [Building on FreeBSD](https://github.com/GTAmodding/re3/wiki/Building-on-FreeBSD)
@@ -28,27 +26,15 @@ You may want to point GTA_III_RE_DIR environment variable to GTA3 root folder if
**If you use 64-bit D3D9**: We don't ship 64-bit Dx9 SDK. You need to download it from Microsoft if you don't have it(although it should come pre-installed after some Windows version)
-There are various settings at the very bottom of [config.h](https://github.com/GTAmodding/re3/tree/master/src/core/config.h), you may want to take a look there. i.e. FIX_BUGS define fixes the bugs we've come across.
+There are various settings at the very bottom of [config.h](https://github.com/GTAmodding/re3/tree/miami/src/core/config.h), you may want to take a look there. i.e. FIX_BUGS define fixes the bugs we've come across.
> :information_source: **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).
-> :information_source: **Did you notice librw?** 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: **Did you notice librw?** reVC uses completely homebrew RenderWare-replacement rendering engine; [librw](https://github.com/aap/librw/). librw comes as submodule of reVC, but you also can use LIBRW enviorenment variable to specify path to your own librw.
## Contributing
Please read the [Coding Style](https://github.com/GTAmodding/re3/blob/master/CODING_STYLE.md) Document
### Unreversed / incomplete classes (at least the ones we know)
-The following classes have only unused or practically unused code left:
-```
-CMemoryHeap - only on PS2
-NameGrid.cpp - only on mobile (a player name grid, either a very early player name code ala GTA1 or a multiplayer leftover)
-PedDebug.cpp - only on mobile (debug code)
-HandlingMgr.cpp - debug functions from mobile
-CVehicle::ProcessBikeWheel - early bike code (only on mobile)
-CAutomobile::DebugCode - debug function from mobile
-CBoat::DebugCode - debug function from mobile
-CBoat::ModifyHandlingValue - debug function from mobile
-CBoat::DisplayHandlingData - debug function from mobile
-TexturePools - only on PC (slight RW modification that we don't actually need)
-```
+See [VC todo list](https://github.com/GTAmodding/re3/wiki/VC-todo)
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 1054ca12..eaeab8bb 100644
--- a/gamefiles/TEXT/american.gxt
+++ b/gamefiles/TEXT/american.gxt
Binary files differ
diff --git a/gamefiles/TEXT/french.gxt b/gamefiles/TEXT/french.gxt
index cb2874f9..cff9f3dc 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 d5a986cf..a418a5bc 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 95e2dd36..95758c81 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 100644
index 1782ef87..00000000
--- a/gamefiles/TEXT/polish.gxt
+++ /dev/null
Binary files differ
diff --git a/gamefiles/TEXT/russian.gxt b/gamefiles/TEXT/russian.gxt
deleted file mode 100644
index 026222ac..00000000
--- a/gamefiles/TEXT/russian.gxt
+++ /dev/null
Binary files differ
diff --git a/gamefiles/TEXT/spanish.gxt b/gamefiles/TEXT/spanish.gxt
index 384c79a0..ccab7047 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
deleted file mode 100644
index 4b89e449..00000000
--- a/gamefiles/models/fonts_r.txd
+++ /dev/null
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/x360btns.txd b/gamefiles/models/x360btns.txd
deleted file mode 100644
index 27837c2f..00000000
--- a/gamefiles/models/x360btns.txd
+++ /dev/null
Binary files differ
diff --git a/premake5.lua b/premake5.lua
index 85f4d082..10ab7b71 100644
--- a/premake5.lua
+++ b/premake5.lua
@@ -1,403 +1,405 @@
-newoption {
- trigger = "glewdir",
- value = "PATH",
- description = "Directory of GLEW",
- default = "vendor/glew-2.1.0"
-}
-
-newoption {
- trigger = "glfwdir64",
- value = "PATH",
- description = "Directory of glfw",
- default = "vendor/glfw-3.3.2.bin.WIN64",
-}
-
-newoption {
- trigger = "glfwdir32",
- value = "PATH",
- description = "Directory of glfw",
- default = "vendor/glfw-3.3.2.bin.WIN32",
-}
-
-newoption {
- trigger = "with-asan",
- description = "Build with address sanitizer"
-}
-
-newoption {
- trigger = "with-librw",
- description = "Build and use librw from this solution"
-}
-
-newoption {
- trigger = "with-opus",
- description = "Build with opus"
-}
-
-if(_OPTIONS["with-librw"]) then
- Librw = "vendor/librw"
-else
- Librw = os.getenv("LIBRW") or "vendor/librw"
-end
-
-function getsys(a)
- if a == 'windows' then
- return 'win'
- end
- return a
-end
-
-function getarch(a)
- if a == 'x86_64' then
- return 'amd64'
- elseif a == 'ARM' then
- return 'arm'
- elseif a == 'ARM64' then
- return 'arm64'
- end
- return a
-end
-
-workspace "re3"
- language "C++"
- configurations { "Debug", "Release" }
- location "build"
- symbols "Full"
- staticruntime "off"
-
- if _OPTIONS["with-asan"] then
- buildoptions { "-fsanitize=address -g3 -fno-omit-frame-pointer" }
- linkoptions { "-fsanitize=address" }
- end
-
- filter { "system:windows" }
- platforms {
- "win-x86-RW33_d3d8-mss",
- "win-x86-librw_d3d9-mss",
- "win-x86-librw_gl3_glfw-mss",
- "win-x86-RW33_d3d8-oal",
- "win-x86-librw_d3d9-oal",
- "win-x86-librw_gl3_glfw-oal",
- "win-amd64-librw_d3d9-oal",
- "win-amd64-librw_gl3_glfw-oal",
- }
-
- filter { "system:linux" }
- platforms {
- "linux-x86-librw_gl3_glfw-oal",
- "linux-amd64-librw_gl3_glfw-oal",
- "linux-arm-librw_gl3_glfw-oal",
- "linux-arm64-librw_gl3_glfw-oal",
- }
-
- filter { "system:bsd" }
- platforms {
- "bsd-x86-librw_gl3_glfw-oal",
- "bsd-amd64-librw_gl3_glfw-oal",
- "bsd-arm-librw_gl3_glfw-oal",
- "bsd-arm64-librw_gl3_glfw-oal"
- }
-
- filter { "system:macosx" }
- platforms {
- "macosx-arm64-librw_gl3_glfw-oal",
- "macosx-amd64-librw_gl3_glfw-oal",
- }
-
- filter "configurations:Debug"
- defines { "DEBUG" }
-
- filter "configurations:Release"
- defines { "NDEBUG" }
- optimize "On"
-
- filter { "platforms:win*" }
- system "windows"
-
- filter { "platforms:linux*" }
- system "linux"
-
- filter { "platforms:bsd*" }
- system "bsd"
-
- filter { "platforms:macosx*" }
- system "macosx"
-
- filter { "platforms:*x86*" }
- architecture "x86"
- floatingpoint "Fast"
-
- filter { "platforms:*amd64*" }
- architecture "amd64"
- floatingpoint "Fast"
-
- filter { "platforms:*arm*" }
- architecture "ARM"
-
- filter { "platforms:macosx-arm64-*" }
- buildoptions { "-target", "arm64-apple-macos11", "-std=gnu++14" }
-
- filter { "platforms:macosx-amd64-*" }
- buildoptions { "-target", "x86_64-apple-macos10.12", "-std=gnu++14" }
-
- filter { "platforms:*librw_d3d9*" }
- defines { "RW_D3D9" }
- if(not _OPTIONS["with-librw"]) then
- libdirs { path.join(Librw, "lib/win-%{getarch(cfg.architecture)}-d3d9/%{cfg.buildcfg}") }
- end
-
- filter "platforms:*librw_gl3_glfw*"
- defines { "RW_GL3" }
- includedirs { path.join(_OPTIONS["glewdir"], "include") }
- if(not _OPTIONS["with-librw"]) then
- libdirs { path.join(Librw, "lib/%{getsys(cfg.system)}-%{getarch(cfg.architecture)}-gl3/%{cfg.buildcfg}") }
- end
-
- filter "platforms:*x86-librw_gl3_glfw*"
- includedirs { path.join(_OPTIONS["glfwdir32"], "include") }
-
- filter "platforms:*amd64-librw_gl3_glfw*"
- includedirs { path.join(_OPTIONS["glfwdir64"], "include") }
-
- filter "platforms:win*librw_gl3_glfw*"
- defines { "GLEW_STATIC" }
-
- filter {}
-
- function setpaths (gamepath, exepath, scriptspath)
- scriptspath = scriptspath or ""
- if (gamepath) then
- postbuildcommands {
- '{COPY} "%{cfg.buildtarget.abspath}" "' .. gamepath .. scriptspath .. '%{cfg.buildtarget.name}"'
- }
- debugdir (gamepath)
- if (exepath) then
- -- Used VS variable $(TargetFileName) because it doesn't accept premake tokens. Does debugcommand even work outside VS??
- debugcommand (gamepath .. "$(TargetFileName)")
- dir, file = exepath:match'(.*/)(.*)'
- debugdir (gamepath .. (dir or ""))
- end
- end
- --targetdir ("bin/%{prj.name}/" .. scriptspath)
- end
-
-if(_OPTIONS["with-librw"]) then
-project "librw"
- kind "StaticLib"
- targetname "rw"
- targetdir(path.join(Librw, "lib/%{cfg.platform}/%{cfg.buildcfg}"))
- files { path.join(Librw, "src/*.*") }
- files { path.join(Librw, "src/*/*.*") }
-
- filter { "platforms:*x86*" }
- architecture "x86"
- floatingpoint "Fast"
-
- filter { "platforms:*amd64*" }
- architecture "amd64"
- floatingpoint "Fast"
-
- filter "platforms:win*"
- staticruntime "on"
- buildoptions { "/Zc:sizedDealloc-" }
-
- filter "platforms:bsd*"
- includedirs { "/usr/local/include" }
- libdirs { "/usr/local/lib" }
-
- filter "platforms:macosx*"
- -- Support MacPorts and Homebrew
- includedirs { "/opt/local/include" }
- includedirs {"/usr/local/include" }
- libdirs { "/opt/local/lib" }
- libdirs { "/usr/local/lib" }
-
- filter "platforms:*gl3_glfw*"
- staticruntime "off"
-
- filter "platforms:*RW33*"
- flags { "ExcludeFromBuild" }
- filter {}
-end
-
-local function addSrcFiles( prefix )
- return prefix .. "/*cpp", prefix .. "/*.h", prefix .. "/*.c", prefix .. "/*.ico", prefix .. "/*.rc"
-end
-
-project "re3"
- kind "WindowedApp"
- targetname "re3"
- targetdir "bin/%{cfg.platform}/%{cfg.buildcfg}"
-
- files { addSrcFiles("src") }
- files { addSrcFiles("src/animation") }
- files { addSrcFiles("src/audio") }
- files { addSrcFiles("src/audio/eax") }
- files { addSrcFiles("src/audio/oal") }
- files { addSrcFiles("src/collision") }
- files { addSrcFiles("src/control") }
- files { addSrcFiles("src/core") }
- files { addSrcFiles("src/entities") }
- files { addSrcFiles("src/math") }
- files { addSrcFiles("src/modelinfo") }
- files { addSrcFiles("src/objects") }
- files { addSrcFiles("src/peds") }
- files { addSrcFiles("src/render") }
- files { addSrcFiles("src/rw") }
- files { addSrcFiles("src/save") }
- files { addSrcFiles("src/skel") }
- files { addSrcFiles("src/skel/glfw") }
- files { addSrcFiles("src/text") }
- files { addSrcFiles("src/vehicles") }
- files { addSrcFiles("src/weapons") }
- files { addSrcFiles("src/extras") }
-
- includedirs { "src" }
- includedirs { "src/animation" }
- includedirs { "src/audio" }
- includedirs { "src/audio/eax" }
- includedirs { "src/audio/oal" }
- includedirs { "src/collision" }
- includedirs { "src/control" }
- includedirs { "src/core" }
- includedirs { "src/entities" }
- includedirs { "src/math" }
- includedirs { "src/modelinfo" }
- includedirs { "src/objects" }
- includedirs { "src/peds" }
- includedirs { "src/render" }
- includedirs { "src/rw" }
- includedirs { "src/save/" }
- includedirs { "src/skel/" }
- includedirs { "src/skel/glfw" }
- includedirs { "src/text" }
- includedirs { "src/vehicles" }
- includedirs { "src/weapons" }
- includedirs { "src/extras" }
-
- if _OPTIONS["with-opus"] then
- includedirs { "vendor/ogg/include" }
- includedirs { "vendor/opus/include" }
- includedirs { "vendor/opusfile/include" }
- end
-
- filter "platforms:*mss"
- defines { "AUDIO_MSS" }
- includedirs { "sdk/milessdk/include" }
- libdirs { "sdk/milessdk/lib" }
-
- if _OPTIONS["with-opus"] then
- filter "platforms:win*"
- libdirs { "vendor/ogg/win32/VS2015/Win32/%{cfg.buildcfg}" }
- libdirs { "vendor/opus/win32/VS2015/Win32/%{cfg.buildcfg}" }
- libdirs { "vendor/opusfile/win32/VS2015/Win32/Release-NoHTTP" }
- filter {}
- defines { "AUDIO_OPUS" }
- end
-
- filter "platforms:*oal"
- defines { "AUDIO_OAL" }
-
- filter {}
- if(os.getenv("GTA_III_RE_DIR")) then
- setpaths("$(GTA_III_RE_DIR)/", "%(cfg.buildtarget.name)", "")
- end
-
- filter "platforms:win*"
- files { addSrcFiles("src/skel/win") }
- includedirs { "src/skel/win" }
- buildoptions { "/Zc:sizedDealloc-" }
- linkoptions "/SAFESEH:NO"
- characterset ("MBCS")
- targetextension ".exe"
- if(_OPTIONS["with-librw"]) then
- -- external librw is dynamic
- staticruntime "on"
- end
-
- filter "platforms:win*glfw*"
- staticruntime "off"
-
- filter "platforms:win*oal"
- includedirs { "vendor/openal-soft/include" }
- includedirs { "vendor/libsndfile/include" }
- includedirs { "vendor/mpg123/include" }
-
- filter "platforms:win-x86*oal"
- libdirs { "vendor/mpg123/lib/Win32" }
- libdirs { "vendor/libsndfile/lib/Win32" }
- libdirs { "vendor/openal-soft/libs/Win32" }
-
- filter "platforms:win-amd64*oal"
- libdirs { "vendor/mpg123/lib/Win64" }
- libdirs { "vendor/libsndfile/lib/Win64" }
- libdirs { "vendor/openal-soft/libs/Win64" }
-
- filter "platforms:linux*oal"
- links { "openal", "mpg123", "sndfile", "pthread" }
-
- filter "platforms:bsd*oal"
- links { "openal", "mpg123", "sndfile", "pthread" }
-
- filter "platforms:macosx*oal"
- links { "openal", "mpg123", "sndfile", "pthread" }
- includedirs { "/usr/local/opt/openal-soft/include" }
- libdirs { "/usr/local/opt/openal-soft/lib" }
-
- if _OPTIONS["with-opus"] then
- filter {}
- links { "libogg" }
- links { "opus" }
- links { "opusfile" }
- end
-
- filter "platforms:*RW33*"
- includedirs { "sdk/rwsdk/include/d3d8" }
- libdirs { "sdk/rwsdk/lib/d3d8/release" }
- links { "rwcore", "rpworld", "rpmatfx", "rpskin", "rphanim", "rtbmp", "rtquat", "rtcharse" }
- defines { "RWLIBS" }
- linkoptions "/SECTION:_rwcseg,ER!W /MERGE:_rwcseg=.text"
-
- filter "platforms:*librw*"
- defines { "LIBRW" }
- files { addSrcFiles("src/fakerw") }
- includedirs { "src/fakerw" }
- includedirs { Librw }
- if(_OPTIONS["with-librw"]) then
- libdirs { "vendor/librw/lib/%{cfg.platform}/%{cfg.buildcfg}" }
- end
- links { "rw" }
-
- filter "platforms:*d3d9*"
- defines { "USE_D3D9" }
- links { "d3d9" }
-
- filter "platforms:*x86*d3d*"
- includedirs { "sdk/dx8sdk/include" }
- libdirs { "sdk/dx8sdk/lib" }
-
- filter "platforms:win-x86*gl3_glfw*"
- libdirs { path.join(_OPTIONS["glewdir"], "lib/Release/Win32") }
- libdirs { path.join(_OPTIONS["glfwdir32"], "lib-" .. string.gsub(_ACTION or '', "vs", "vc")) }
- links { "opengl32", "glew32s", "glfw3" }
-
- filter "platforms:win-amd64*gl3_glfw*"
- libdirs { path.join(_OPTIONS["glewdir"], "lib/Release/x64") }
- libdirs { path.join(_OPTIONS["glfwdir64"], "lib-" .. string.gsub(_ACTION or '', "vs", "vc")) }
- links { "opengl32", "glew32s", "glfw3" }
-
- filter "platforms:linux*gl3_glfw*"
- links { "GL", "GLEW", "glfw" }
-
- filter "platforms:bsd*gl3_glfw*"
- links { "GL", "GLEW", "glfw", "sysinfo" }
- includedirs { "/usr/local/include" }
- libdirs { "/usr/local/lib" }
-
- filter "platforms:macosx*gl3_glfw*"
- links { "GLEW", "glfw" }
- linkoptions { "-framework OpenGL" }
- includedirs { "/opt/local/include" }
- includedirs { "/usr/local/include" }
- libdirs { "/opt/local/lib" }
- libdirs { "/usr/local/lib" }
+newoption {
+ trigger = "glewdir",
+ value = "PATH",
+ description = "Directory of GLEW",
+ default = "vendor/glew-2.1.0"
+}
+
+newoption {
+ trigger = "glfwdir64",
+ value = "PATH",
+ description = "Directory of glfw",
+ default = "vendor/glfw-3.3.2.bin.WIN64",
+}
+
+newoption {
+ trigger = "glfwdir32",
+ value = "PATH",
+ description = "Directory of glfw",
+ default = "vendor/glfw-3.3.2.bin.WIN32",
+}
+
+newoption {
+ trigger = "with-asan",
+ description = "Build with address sanitizer"
+}
+
+newoption {
+ trigger = "with-librw",
+ description = "Build and use librw from this solution"
+}
+
+newoption {
+ trigger = "with-opus",
+ description = "Build with opus"
+}
+
+if(_OPTIONS["with-librw"]) then
+ Librw = "vendor/librw"
+else
+ Librw = os.getenv("LIBRW") or "vendor/librw"
+end
+
+function getsys(a)
+ if a == 'windows' then
+ return 'win'
+ end
+ return a
+end
+
+function getarch(a)
+ if a == 'x86_64' then
+ return 'amd64'
+ elseif a == 'ARM' then
+ return 'arm'
+ elseif a == 'ARM64' then
+ return 'arm64'
+ end
+ return a
+end
+
+workspace "reVC"
+ language "C++"
+ configurations { "Debug", "Release" }
+ location "build"
+ symbols "Full"
+ staticruntime "off"
+
+ if _OPTIONS["with-asan"] then
+ buildoptions { "-fsanitize=address -g3 -fno-omit-frame-pointer" }
+ linkoptions { "-fsanitize=address" }
+ end
+
+ filter { "system:windows" }
+ platforms {
+ "win-x86-RW34_d3d8-mss",
+ "win-x86-librw_d3d9-mss",
+ "win-x86-librw_gl3_glfw-mss",
+ "win-x86-RW34_d3d8-oal",
+ "win-x86-librw_d3d9-oal",
+ "win-x86-librw_gl3_glfw-oal",
+ "win-amd64-librw_d3d9-oal",
+ "win-amd64-librw_gl3_glfw-oal",
+ }
+
+ filter { "system:linux" }
+ platforms {
+ "linux-x86-librw_gl3_glfw-oal",
+ "linux-amd64-librw_gl3_glfw-oal",
+ "linux-arm-librw_gl3_glfw-oal",
+ "linux-arm64-librw_gl3_glfw-oal",
+ }
+
+ filter { "system:bsd" }
+ platforms {
+ "bsd-x86-librw_gl3_glfw-oal",
+ "bsd-amd64-librw_gl3_glfw-oal",
+ "bsd-arm-librw_gl3_glfw-oal",
+ "bsd-arm64-librw_gl3_glfw-oal"
+ }
+
+ filter { "system:macosx" }
+ platforms {
+ "macosx-arm64-librw_gl3_glfw-oal",
+ "macosx-amd64-librw_gl3_glfw-oal",
+ }
+
+ filter "configurations:Debug"
+ defines { "DEBUG" }
+
+ filter "configurations:Release"
+ defines { "NDEBUG" }
+ optimize "On"
+
+ filter { "platforms:win*" }
+ system "windows"
+
+ filter { "platforms:linux*" }
+ system "linux"
+
+ filter { "platforms:bsd*" }
+ system "bsd"
+
+ filter { "platforms:macosx*" }
+ system "macosx"
+
+ filter { "platforms:*x86*" }
+ architecture "x86"
+ floatingpoint "Fast"
+
+ filter { "platforms:*amd64*" }
+ architecture "amd64"
+ floatingpoint "Fast"
+
+ filter { "platforms:*arm*" }
+ architecture "ARM"
+
+ filter { "platforms:macosx-arm64-*" }
+ buildoptions { "-target", "arm64-apple-macos11", "-std=gnu++14" }
+
+ filter { "platforms:macosx-amd64-*" }
+ buildoptions { "-target", "x86_64-apple-macos10.12", "-std=gnu++14" }
+
+
+ filter { "platforms:*librw_d3d9*" }
+ defines { "RW_D3D9" }
+ if(not _OPTIONS["with-librw"]) then
+ libdirs { path.join(Librw, "lib/win-%{getarch(cfg.architecture)}-d3d9/%{cfg.buildcfg}") }
+ end
+
+ filter "platforms:*librw_gl3_glfw*"
+ defines { "RW_GL3" }
+ includedirs { path.join(_OPTIONS["glewdir"], "include") }
+ if(not _OPTIONS["with-librw"]) then
+ libdirs { path.join(Librw, "lib/%{getsys(cfg.system)}-%{getarch(cfg.architecture)}-gl3/%{cfg.buildcfg}") }
+ end
+
+ filter "platforms:*x86-librw_gl3_glfw*"
+ includedirs { path.join(_OPTIONS["glfwdir32"], "include") }
+
+ filter "platforms:*amd64-librw_gl3_glfw*"
+ includedirs { path.join(_OPTIONS["glfwdir64"], "include") }
+
+ filter "platforms:win*librw_gl3_glfw*"
+ defines { "GLEW_STATIC" }
+
+ filter {}
+
+ function setpaths (gamepath, exepath, scriptspath)
+ scriptspath = scriptspath or ""
+ if (gamepath) then
+ postbuildcommands {
+ '{COPY} "%{cfg.buildtarget.abspath}" "' .. gamepath .. scriptspath .. '%{cfg.buildtarget.name}"'
+ }
+ debugdir (gamepath)
+ if (exepath) then
+ -- Used VS variable $(TargetFileName) because it doesn't accept premake tokens. Does debugcommand even work outside VS??
+ debugcommand (gamepath .. "$(TargetFileName)")
+ dir, file = exepath:match'(.*/)(.*)'
+ debugdir (gamepath .. (dir or ""))
+ end
+ end
+ --targetdir ("bin/%{prj.name}/" .. scriptspath)
+ end
+
+if(_OPTIONS["with-librw"]) then
+project "librw"
+ kind "StaticLib"
+ targetname "rw"
+ targetdir(path.join(Librw, "lib/%{cfg.platform}/%{cfg.buildcfg}"))
+ files { path.join(Librw, "src/*.*") }
+ files { path.join(Librw, "src/*/*.*") }
+
+ filter { "platforms:*x86*" }
+ architecture "x86"
+ floatingpoint "Fast"
+
+ filter { "platforms:*amd64*" }
+ architecture "amd64"
+ floatingpoint "Fast"
+
+ filter "platforms:win*"
+ staticruntime "on"
+ buildoptions { "/Zc:sizedDealloc-" }
+
+ filter "platforms:bsd*"
+ includedirs { "/usr/local/include" }
+ libdirs { "/usr/local/lib" }
+
+ filter "platforms:macosx*"
+ -- Support MacPorts and Homebrew
+ includedirs { "/opt/local/include" }
+ includedirs {"/usr/local/include" }
+ libdirs { "/opt/local/lib" }
+ libdirs { "/usr/local/lib" }
+
+ filter "platforms:*gl3_glfw*"
+ staticruntime "off"
+
+ filter "platforms:*RW34*"
+ flags { "ExcludeFromBuild" }
+ filter {}
+end
+
+local function addSrcFiles( prefix )
+ return prefix .. "/*cpp", prefix .. "/*.h", prefix .. "/*.c", prefix .. "/*.ico", prefix .. "/*.rc"
+end
+
+project "reVC"
+ kind "WindowedApp"
+ targetname "reVC"
+ targetdir "bin/%{cfg.platform}/%{cfg.buildcfg}"
+ defines { "MIAMI" }
+
+ files { addSrcFiles("src") }
+ files { addSrcFiles("src/animation") }
+ files { addSrcFiles("src/audio") }
+ files { addSrcFiles("src/audio/eax") }
+ files { addSrcFiles("src/audio/oal") }
+ files { addSrcFiles("src/collision") }
+ files { addSrcFiles("src/control") }
+ files { addSrcFiles("src/core") }
+ files { addSrcFiles("src/entities") }
+ files { addSrcFiles("src/math") }
+ files { addSrcFiles("src/modelinfo") }
+ files { addSrcFiles("src/objects") }
+ files { addSrcFiles("src/peds") }
+ files { addSrcFiles("src/render") }
+ files { addSrcFiles("src/rw") }
+ files { addSrcFiles("src/save") }
+ files { addSrcFiles("src/skel") }
+ files { addSrcFiles("src/skel/glfw") }
+ files { addSrcFiles("src/text") }
+ files { addSrcFiles("src/vehicles") }
+ files { addSrcFiles("src/weapons") }
+ files { addSrcFiles("src/extras") }
+
+ includedirs { "src" }
+ includedirs { "src/animation" }
+ includedirs { "src/audio" }
+ includedirs { "src/audio/eax" }
+ includedirs { "src/audio/oal" }
+ includedirs { "src/collision" }
+ includedirs { "src/control" }
+ includedirs { "src/core" }
+ includedirs { "src/entities" }
+ includedirs { "src/math" }
+ includedirs { "src/modelinfo" }
+ includedirs { "src/objects" }
+ includedirs { "src/peds" }
+ includedirs { "src/render" }
+ includedirs { "src/rw" }
+ includedirs { "src/save/" }
+ includedirs { "src/skel/" }
+ includedirs { "src/skel/glfw" }
+ includedirs { "src/text" }
+ includedirs { "src/vehicles" }
+ includedirs { "src/weapons" }
+ includedirs { "src/extras" }
+
+ if _OPTIONS["with-opus"] then
+ includedirs { "vendor/ogg/include" }
+ includedirs { "vendor/opus/include" }
+ includedirs { "vendor/opusfile/include" }
+ end
+
+ filter "platforms:*mss"
+ defines { "AUDIO_MSS" }
+ includedirs { "sdk/milessdk/include" }
+ libdirs { "sdk/milessdk/lib" }
+
+ if _OPTIONS["with-opus"] then
+ filter "platforms:win*"
+ libdirs { "vendor/ogg/win32/VS2015/Win32/%{cfg.buildcfg}" }
+ libdirs { "vendor/opus/win32/VS2015/Win32/%{cfg.buildcfg}" }
+ libdirs { "vendor/opusfile/win32/VS2015/Win32/Release-NoHTTP" }
+ filter {}
+ defines { "AUDIO_OPUS" }
+ end
+
+ filter "platforms:*oal"
+ defines { "AUDIO_OAL" }
+
+ filter {}
+ if(os.getenv("GTA_VC_RE_DIR")) then
+ setpaths("$(GTA_VC_RE_DIR)/", "%(cfg.buildtarget.name)", "")
+ end
+
+ filter "platforms:win*"
+ files { addSrcFiles("src/skel/win") }
+ includedirs { "src/skel/win" }
+ buildoptions { "/Zc:sizedDealloc-" }
+ linkoptions "/SAFESEH:NO"
+ characterset ("MBCS")
+ targetextension ".exe"
+ if(_OPTIONS["with-librw"]) then
+ -- external librw is dynamic
+ staticruntime "on"
+ end
+
+ filter "platforms:win*glfw*"
+ staticruntime "off"
+
+ filter "platforms:win*oal"
+ includedirs { "vendor/openal-soft/include" }
+ includedirs { "vendor/libsndfile/include" }
+ includedirs { "vendor/mpg123/include" }
+
+ filter "platforms:win-x86*oal"
+ libdirs { "vendor/mpg123/lib/Win32" }
+ libdirs { "vendor/libsndfile/lib/Win32" }
+ libdirs { "vendor/openal-soft/libs/Win32" }
+
+ filter "platforms:win-amd64*oal"
+ libdirs { "vendor/mpg123/lib/Win64" }
+ libdirs { "vendor/libsndfile/lib/Win64" }
+ libdirs { "vendor/openal-soft/libs/Win64" }
+
+ filter "platforms:linux*oal"
+ links { "openal", "mpg123", "sndfile", "pthread" }
+
+ filter "platforms:bsd*oal"
+ links { "openal", "mpg123", "sndfile", "pthread" }
+
+ filter "platforms:macosx*oal"
+ links { "openal", "mpg123", "sndfile", "pthread" }
+ includedirs { "/usr/local/opt/openal-soft/include" }
+ libdirs { "/usr/local/opt/openal-soft/lib" }
+
+ if _OPTIONS["with-opus"] then
+ filter {}
+ links { "libogg" }
+ links { "opus" }
+ links { "opusfile" }
+ end
+
+ filter "platforms:*RW34*"
+ includedirs { "sdk/rwsdk/include/d3d8" }
+ libdirs { "sdk/rwsdk/lib/d3d8/release" }
+ links { "rwcore", "rpworld", "rpmatfx", "rpskin", "rphanim", "rtbmp", "rtquat", "rtanim", "rtcharse", "rpanisot" }
+ defines { "RWLIBS" }
+ linkoptions "/SECTION:_rwcseg,ER!W /MERGE:_rwcseg=.text"
+
+ filter "platforms:*librw*"
+ defines { "LIBRW" }
+ files { addSrcFiles("src/fakerw") }
+ includedirs { "src/fakerw" }
+ includedirs { Librw }
+ if(_OPTIONS["with-librw"]) then
+ libdirs { "vendor/librw/lib/%{cfg.platform}/%{cfg.buildcfg}" }
+ end
+ links { "rw" }
+
+ filter "platforms:*d3d9*"
+ defines { "USE_D3D9" }
+ links { "d3d9" }
+
+ filter "platforms:*x86*d3d*"
+ includedirs { "sdk/dx8sdk/include" }
+ libdirs { "sdk/dx8sdk/lib" }
+
+ filter "platforms:win-x86*gl3_glfw*"
+ libdirs { path.join(_OPTIONS["glewdir"], "lib/Release/Win32") }
+ libdirs { path.join(_OPTIONS["glfwdir32"], "lib-" .. string.gsub(_ACTION or '', "vs", "vc")) }
+ links { "opengl32", "glew32s", "glfw3" }
+
+ filter "platforms:win-amd64*gl3_glfw*"
+ libdirs { path.join(_OPTIONS["glewdir"], "lib/Release/x64") }
+ libdirs { path.join(_OPTIONS["glfwdir64"], "lib-" .. string.gsub(_ACTION or '', "vs", "vc")) }
+ links { "opengl32", "glew32s", "glfw3" }
+
+ filter "platforms:linux*gl3_glfw*"
+ links { "GL", "GLEW", "glfw" }
+
+ filter "platforms:bsd*gl3_glfw*"
+ links { "GL", "GLEW", "glfw", "sysinfo" }
+ includedirs { "/usr/local/include" }
+ libdirs { "/usr/local/lib" }
+
+ filter "platforms:macosx*gl3_glfw*"
+ links { "GLEW", "glfw" }
+ linkoptions { "-framework OpenGL" }
+ includedirs { "/opt/local/include" }
+ includedirs { "/usr/local/include" }
+ libdirs { "/opt/local/lib" }
+ libdirs { "/usr/local/lib" }
diff --git a/sdk/milessdk/include/mss.h b/sdk/milessdk/include/mss.h
index 38371eb9..94bfc065 100644
--- a/sdk/milessdk/include/mss.h
+++ b/sdk/milessdk/include/mss.h
@@ -114,3 +114,17 @@ DLLEXPORT void WINAPI AIL_set_stream_ms_position(HSTREAM S, S32 milliseconds);
DLLEXPORT void WINAPI AIL_set_stream_volume(HSTREAM stream, S32 volume);
DLLEXPORT void WINAPI AIL_set_stream_pan(HSTREAM stream, S32 pan);
DLLEXPORT S32 WINAPI AIL_stream_status(HSTREAM stream);
+
+typedef U32(WINAPI* AIL_file_open_callback)(char const * Filename, U32 * FileHandle);
+
+typedef void (WINAPI* AIL_file_close_callback) (U32 FileHandle);
+
+#define AIL_FILE_SEEK_BEGIN 0
+#define AIL_FILE_SEEK_CURRENT 1
+#define AIL_FILE_SEEK_END 2
+
+typedef S32(WINAPI* AIL_file_seek_callback) (U32 FileHandle, S32 Offset, U32 Type);
+
+typedef U32(WINAPI* AIL_file_read_callback) (U32 FileHandle, void* Buffer, U32 Bytes);
+
+DLLEXPORT void WINAPI AIL_set_file_callbacks(AIL_file_open_callback opencb, AIL_file_close_callback closecb, AIL_file_seek_callback seekcb, AIL_file_read_callback readcb); \ No newline at end of file
diff --git a/sdk/milessdk/lib/mss32.lib b/sdk/milessdk/lib/mss32.lib
index f97091c7..49cea2d2 100644
--- a/sdk/milessdk/lib/mss32.lib
+++ b/sdk/milessdk/lib/mss32.lib
Binary files differ
diff --git a/sdk/rwsdk/include/d3d8/baaplylt.c b/sdk/rwsdk/include/d3d8/baaplylt.c
deleted file mode 100644
index ad518e6a..00000000
--- a/sdk/rwsdk/include/d3d8/baaplylt.c
+++ /dev/null
@@ -1,793 +0,0 @@
-
-/* If this file is used outside of the core RW SDK,
- * the following things need to be defined
- */
-#if (!defined(RWASSERT))
-#define RWASSERT(_assertval) /* No op */
-#endif
-#if (!defined(RWFUNCTION))
-#define RWFUNCTION(_rwfunctionstring) /* No op */
-#endif
-#if (!defined(RWRETURN))
-#define RWRETURN(_rwreturnval) return(_rwreturnval)
-#endif
-#if (!defined(RWRETURNVOID))
-#define RWRETURNVOID() return
-#endif
-
-/* These are used by specular lighting,
- * sorry I have to leave them in here... IDBS
- * I'll make it neater when I have time.
- */
-#if (!defined(FALLOFFAMBIENT))
-#define FALLOFFAMBIENT() /* No op */
-#endif
-#if (!defined(FALLOFFDIRECTIONAL))
-#define FALLOFFDIRECTIONAL() /* No op */
-#endif
-#if (!defined(FALLOFFPOINT))
-#define FALLOFFPOINT() /* No op */
-#endif
-#if (!defined(FALLOFFSPOT))
-#define FALLOFFSPOT() /* No op */
-#endif
-#if (!defined(FALLOFFSOFTSPOT))
-#define FALLOFFSOFTSPOT() /* No op */
-#endif
-
-/***************************************************************************
- _rwApplyAmbientLight
-
- On entry : Instanced data
- : Light
- : Optional inverse object matrix
- : (to transform light to object space)
- : Inverse scale of object
- : Surface properties of the light
- On exit :
- */
-
-static void
-_rwApplyAmbientLight(VERTSARG,
- const void *voidLight,
- const RwMatrix * __RWUNUSED__ inverseMat,
- RwReal __RWUNUSED__ invScale,
- const RwSurfaceProperties * surfaceProps)
-{
- CAMVERTDECL;
- NUMVERTDECL;
- const RpLight *light = (const RpLight *) voidLight;
- RwReal scale;
- RwV3d vertToLight;
-
- RWFUNCTION(RWSTRING("_rwApplyAmbientLight"));
- RWASSERT(light);
- RWASSERT(surfaceProps);
-
- CAMVERTINIT();
- NUMVERTINIT();
-
- /* No directional component:
- * (this is used in CAMVERTADDRGBA in a specular lighting node) */
- vertToLight.x = 0;
- vertToLight.y = 0;
- vertToLight.z = 0;
-
- /* rpLIGHTAMBIENT - Constant illumination on all vertices
- */
- if (rwObjectTestPrivateFlags(light, rpLIGHTPRIVATENOCHROMA))
- {
- scale = 255.0f * light->color.red * surfaceProps->ambient;
-
- /* Ambient light affects all vertices the same */
- while (numVert--)
- {
- RwReal lum = scale;
-
-#undef FALLOFFCALC
-#define FALLOFFCALC FALLOFFAMBIENT
- CAMVERTADDRGBA(1, 1, 1, 0);
- CAMVERTINC();
- }
- }
- else
- /* perform for coloured lights */
- {
- scale = 255.0f * surfaceProps->ambient;
-
- /* Ambient light affects all vertices the same */
- while (numVert--)
- {
- RwReal lum = scale;
-
-#undef FALLOFFCALC
-#define FALLOFFCALC FALLOFFAMBIENT
- CAMVERTADDRGBA(light->color.red, light->color.green,
- light->color.blue, 0);
- CAMVERTINC();
- }
- }
- RWRETURNVOID();
-}
-
-/***************************************************************************
- _rwApplyDirectionalLight
-
- On entry : Instanced data
- : Light
- : Optional inverse object matrix
- : (to transform light to object space)
- : Inverse scale of object
- : Surface properties of the light
- On exit :
- */
-
-static void
-_rwApplyDirectionalLight(VERTSARG,
- const void *voidLight,
- const RwMatrix * inverseMat,
- RwReal __RWUNUSED__ invScale,
- const RwSurfaceProperties * surfaceProps)
-{
- OBJCAMVERTDECL;
- NUMVERTDECL;
- const RpLight *light = (const RpLight *) voidLight;
- RwV3d vertToLight;
- RwReal scale;
- RwReal dot;
- RwFrame *lightFrame;
-
- RWFUNCTION(RWSTRING("_rwApplyDirectionalLight"));
- RWASSERT(light);
- RWASSERT(surfaceProps);
-
- OBJCAMVERTINIT();
- NUMVERTINIT();
-
- /* rpLIGHTDIRECTIONAL - Lighting scaled by dot product
- * of vertex normal and light lookAt vector.
- */
- /* This may not have a frame - we need to check */
- lightFrame = RpLightGetFrame(light);
- if (lightFrame)
- {
- vertToLight = RwFrameGetLTM(lightFrame)->at;
-
- /* Transform the light into object space if necessary */
- if (inverseMat)
- {
- RwV3dTransformVectors(&vertToLight, &vertToLight, 1, inverseMat);
- _rwV3dNormalize(&vertToLight, &vertToLight);
- }
-
- /* Vert TO light */
- RwV3dScale(&vertToLight, &vertToLight, -1);
-
- /* Optimise for grey lights? */
- if (rwObjectTestPrivateFlags(light, rpLIGHTPRIVATENOCHROMA))
- {
- /* Use one of the light colour intensities as general intensity */
- /* light vector tests are to be identical to others */
- scale = 255.0f * light->color.red * surfaceProps->diffuse;
-
- /* Loop through each of the vertices */
- while (numVert--)
- {
- RwV3d objNormal;
-
- OBJVERTGETNORMAL(&objNormal);
- /* Calculate angle between vertex normal and light vector */
- dot = RwV3dDotProduct(&vertToLight, &objNormal);
-
- /* Ensure vector is facing light,
- * don't light areas not facing */
-
- if (dot > 0.0f)
- {
- RwReal lum = dot * scale;
-
-#undef FALLOFFCALC
-#define FALLOFFCALC FALLOFFDIRECTIONAL
- CAMVERTADDRGBA(1, 1, 1, 0);
- }
-
- /* Next vertex */
- OBJCAMVERTINC();
- }
- }
- else
- /* perform for coloured lights */
- {
- scale = 255.0f * surfaceProps->diffuse;
-
- /* Loop through each of the vertices */
- while (numVert--)
- {
- RwV3d objNormal;
-
- OBJVERTGETNORMAL(&objNormal);
- /* Calculate angle between vertex normal and light vector */
- dot = RwV3dDotProduct(&vertToLight, &objNormal);
-
- /* Ensure vector is facing light,
- * don't light areas not facing */
-
- if (dot > 0.0f)
- {
- RwReal lum = dot * scale;
-
-#define FALLOFFCALC FALLOFFDIRECTIONAL
- CAMVERTADDRGBA(light->color.red, light->color.green,
- light->color.blue, 0);
- }
-
- /* Next vertex */
- OBJCAMVERTINC();
- }
- }
- }
-
- RWRETURNVOID();
-}
-
-/***************************************************************************
- _rwApplyPointLight
-
- On entry : Instanced data
- : Light
- : Optional inverse object matrix
- : (to transform light to object space)
- : Inverse scale of object
- : Surface properties of the light
- On exit :
- */
-
-static void
-_rwApplyPointLight(VERTSARG, const void *voidLight,
- const RwMatrix * inverseMat,
- RwReal invScale, const RwSurfaceProperties * surfaceProps)
-{
- OBJCAMVERTDECL;
- NUMVERTDECL;
- const RpLight *light = (const RpLight *) voidLight;
- RwReal scale, recipRad;
- RwV3d lightPos, vertToLight;
- RwReal radSquared;
-
- RWFUNCTION(RWSTRING("_rwApplyPointLight"));
- RWASSERT(light);
- RWASSERT(surfaceProps);
-
- OBJCAMVERTINIT();
- NUMVERTINIT();
-
- /* rpLIGHTPOINT - Linear falloff with distance, scaled by
- * dot product of vertex normal and light to vertex vector.
- */
- lightPos = RwFrameGetLTM(RpLightGetFrame(light))->pos;
-
- if (inverseMat)
- {
- RwReal scaledRad;
-
- scaledRad = ((light->radius) * (invScale));
- radSquared = ((scaledRad) * (scaledRad));
- recipRad = (((RwReal) (1)) / (scaledRad));
-
- /* Transform light into object space */
- RwV3dTransformPoints(&lightPos, &lightPos, 1, inverseMat);
- }
- else
- {
- radSquared = ((light->radius) * (light->radius));
- recipRad = (((RwReal) (1)) / (light->radius));
- }
-
- if (rwObjectTestPrivateFlags(light, rpLIGHTPRIVATENOCHROMA))
- {
- /* The scale encapsulates the common elements to do
- * with light intensity and surface lighting properties
- */
- scale =
- ((((RwReal) (255)) * (light->color.red))) *
- (surfaceProps->diffuse);
-
- while (numVert--)
- {
- RwV3d objVertex, objNormal;
- RwReal dot, dist2;
-
- OBJVERTGETPOS(&objVertex);
- OBJVERTGETNORMAL(&objNormal);
-
- /* Discover the vector between vertex and light and it's length */
- RwV3dSub(&vertToLight, &lightPos, &objVertex);
-
- /* Ensure that this vertex is facing the light source */
- dot = RwV3dDotProduct(&vertToLight, &objNormal);
- if (dot > 0.0f)
- {
- /* Ensure vertex lies within the light's radius */
- dist2 = RwV3dDotProduct(&vertToLight, &vertToLight);
- if (dist2 < radSquared)
- {
- RwReal lum;
- RwReal recipDist;
- RwReal dist;
-
- rwSqrt(&dist, dist2);
- recipDist =
- (dist > 0.0f) ? (((RwReal) 1) / dist) : 0.0f;
-
- /*
- * The following simplifies down to:
- *
- * -scale *
- * (dot/dist) *
- * (1 - dist/lightRadius)
- *
- * Where
- * scale
- * takes care of the light intensity and
- * diffuse lighting coefficient
- * (dot/dist)
- * is a normalised dot product of
- * light->vertex vector and vertex normal
- * (1 - dist/lightRadius)
- * is a linear falloff factor
- */
- lum = scale * dot * (recipDist - recipRad);
-
- /* Calculate the luminance at vertex */
-#undef FALLOFFCALC
-#define FALLOFFCALC FALLOFFPOINT
- CAMVERTADDRGBA(1, 1, 1, 0);
- }
- }
-
- OBJCAMVERTINC();
- }
- }
- else
- {
- scale = (((RwReal) (255)) * (surfaceProps->diffuse));
-
- while (numVert--)
- {
- RwV3d objVertex, objNormal;
- RwReal dot, dist2;
-
- OBJVERTGETPOS(&objVertex);
- OBJVERTGETNORMAL(&objNormal);
-
- /* Discover the vector between vertex and light and it's length */
- RwV3dSub(&vertToLight, &lightPos, &objVertex);
-
- /* Ensure that this vertex is facing the light source */
- dot = RwV3dDotProduct(&vertToLight, &objNormal);
- if (dot > 0.0f)
- {
- dist2 = RwV3dDotProduct(&vertToLight, &vertToLight);
-
- /* Ensure vertex lies within the light's radius */
- if (dist2 < radSquared)
- {
- RwReal lum;
- RwReal recipDist;
- RwReal dist;
-
- /* Only now calculate the actual length of vector */
- rwSqrt(&dist, dist2);
- recipDist =
- (dist > 0.0f) ? (((RwReal) 1) / dist) : 0.0f;
-
- lum = scale * dot * (recipDist - recipRad);
- /* Alter the luminance according to light colour */
-#define FALLOFFCALC FALLOFFPOINT
- CAMVERTADDRGBA(light->color.red, light->color.green,
- light->color.blue, 0);
- }
- }
-
- /* Next point */
- OBJCAMVERTINC();
- }
- }
- RWRETURNVOID();
-}
-
-/***************************************************************************
- _rwApplySpotLight
-
- On entry : Instanced data
- : Light
- : Optional inverse object matrix
- : (to transform light to object space)
- : Inverse scale of object
- : Surface properties of the light
- On exit :
- */
-
-static void
-_rwApplySpotLight(VERTSARG,
- const void *voidLight,
- const RwMatrix * inverseMat,
- RwReal invScale, const RwSurfaceProperties * surfaceProps)
-{
- OBJCAMVERTDECL;
- NUMVERTDECL;
- const RpLight *light = (const RpLight *) voidLight;
- RwReal recipRad;
- RwReal radSquared;
- RwV3d lightPos, at;
-
- RWFUNCTION(RWSTRING("_rwApplySpotLight"));
- RWASSERT(light);
- RWASSERT(surfaceProps);
-
- OBJCAMVERTINIT();
- NUMVERTINIT();
-
- /* rpLIGHTSPOT - Linear falloff with distance, cone to restrict
- * angle that light has effect, constant intensity across cone,
- * scaled by dot product of vertex normal and light to vertex vector.
- */
-
- lightPos = RwFrameGetLTM(RpLightGetFrame(light))->pos;
- at = RwFrameGetLTM(RpLightGetFrame(light))->at;
-
- if (inverseMat)
- {
- RwReal scaledRad;
-
- scaledRad = ((light->radius) * (invScale));
- recipRad = (((RwReal) (1)) / (scaledRad));
- radSquared = ((scaledRad) * (scaledRad));
-
- /* Transform light into object space */
- /* The at is required to ensure within cone */
- RwV3dTransformPoints(&lightPos, &lightPos, 1, inverseMat);
- RwV3dTransformVectors(&at, &at, 1, inverseMat);
- _rwV3dNormalize(&at, &at);
- }
- else
- {
- recipRad = (((RwReal) (1)) / (light->radius));
- radSquared = ((light->radius) * (light->radius));
- }
-
- if (rwObjectTestPrivateFlags(light, rpLIGHTPRIVATENOCHROMA))
- {
- RwReal scale =
-
- ((RwReal) 255) * (light->color.red) * (surfaceProps->diffuse);
-
- while (numVert--)
- {
- RwV3d vertToLight, objVertex, objNormal;
- RwReal dot;
-
- OBJVERTGETPOS(&objVertex);
- OBJVERTGETNORMAL(&objNormal);
-
- /* Find the squared distance from light point to vertex */
- RwV3dSub(&vertToLight, &lightPos, &objVertex);
-
- /* Ensure that this vertex is facing the light source */
- dot = RwV3dDotProduct(&vertToLight, &objNormal);
- if (dot > 0.0f)
- {
- RwReal dist2;
-
- /* Ensure vertex lies within the light's radius */
- dist2 = RwV3dDotProduct(&vertToLight, &vertToLight);
- if (dist2 < radSquared)
- {
- RwReal dist;
- RwReal compare;
- RwReal proj;
-
- rwSqrt(&dist, dist2);
- compare = dist * light->minusCosAngle;
- proj = RwV3dDotProduct(&vertToLight, &at);
-
- if (proj < compare)
- {
- RwReal lum;
- RwReal recipDist;
-
- /* Get the real distance from the light
- * to the vertex (not squared) */
- recipDist =
- (dist > 0.0f) ? (((RwReal) 1) / dist) : 0.0f;
-
- /* This model is the same as the point source
- * inside the cone, zero outside the cone */
- lum = scale * dot * (recipDist - recipRad);
-#undef FALLOFFCALC
-#define FALLOFFCALC FALLOFFSPOT
- CAMVERTADDRGBA(1, 1, 1, 0);
- }
- }
- /* Next vertex */
- OBJCAMVERTINC();
- }
- }
- }
- else
- {
- RwReal scale =
-
- (((RwReal) (255)) * (surfaceProps->diffuse));
-
- while (numVert--)
- {
- RwV3d vertToLight, objVertex, objNormal;
- RwReal dot;
-
- OBJVERTGETPOS(&objVertex);
- OBJVERTGETNORMAL(&objNormal);
-
- /* Find the squared distance from light point to vertex */
- RwV3dSub(&vertToLight, &lightPos, &objVertex);
-
- /* Ensure that this vertex is facing the light source */
- dot = RwV3dDotProduct(&vertToLight, &objNormal);
- if (dot > 0.0f)
- {
- RwReal dist2;
-
- /* Ensure vertex lies within the light's radius */
- dist2 = RwV3dDotProduct(&vertToLight, &vertToLight);
- if (dist2 < radSquared)
- {
- RwReal dist;
- RwReal compare;
- RwReal proj;
-
- rwSqrt(&dist, dist2);
- compare = dist * light->minusCosAngle;
- proj = RwV3dDotProduct(&vertToLight, &at);
-
- if (proj < compare)
- {
- RwReal lum;
- RwReal recipDist;
-
- recipDist =
- (dist > 0.0f) ? (((RwReal) 1) / dist) : 0.0f;
-
- /* This model is the same as the point source
- * inside the cone, zero outside the cone */
- lum = scale * dot * (recipDist - recipRad);
-
- /* Introduce the light colours as a
- * scaling factor for luminance */
-#define FALLOFFCALC FALLOFFSPOT
- CAMVERTADDRGBA(light->color.red,
- light->color.green, light->color.blue,
- 0);
- }
- }
- }
-
- /* Next */
- OBJCAMVERTINC();
- }
- }
-
- RWRETURNVOID();
-}
-
-/***************************************************************************
- _rwApplySpotSoftLight
-
- On entry : Instanced data
- : Light
- : Optional inverse object matrix
- : (to transform light to object space)
- : Inverse scale of object
- : Surface properties of the light
- On exit :
- */
-
-static void
-_rwApplySpotSoftLight(VERTSARG, const void *voidLight,
- const RwMatrix * inverseMat, RwReal invScale,
- const RwSurfaceProperties * surfaceProps)
-{
- OBJCAMVERTDECL;
- NUMVERTDECL;
- const RpLight *light = (const RpLight *) voidLight;
- RwReal recipRad;
- RwReal radSquared;
- RwV3d lightPos, at;
-
- RWFUNCTION(RWSTRING("_rwApplySpotSoftLight"));
- RWASSERT(light);
- RWASSERT(surfaceProps);
-
- OBJCAMVERTINIT();
- NUMVERTINIT();
-
- /* rpLIGHTSPOTSOFT - Linear falloff with distance, cone to restrict
- * angle that light has effect, falloff to edge of cone, scaled by
- * dot product of vertex normal and light to vertex vector.
- */
-
- lightPos = RwFrameGetLTM(RpLightGetFrame(light))->pos;
- at = RwFrameGetLTM(RpLightGetFrame(light))->at;
-
- if (inverseMat)
- {
- RwReal scaledRad;
-
- scaledRad = ((light->radius) * (invScale));
- recipRad = (((RwReal) (1)) / (scaledRad));
- radSquared = ((scaledRad) * (scaledRad));
-
- /* Transform light into object space */
- /* The at is required to ensure within cone */
- RwV3dTransformPoints(&lightPos, &lightPos, 1, inverseMat);
- RwV3dTransformVectors(&at, &at, 1, inverseMat);
- _rwV3dNormalize(&at, &at);
- }
- else
- {
- recipRad = 1.0f / light->radius;
- radSquared = light->radius * light->radius;
- }
-
- if (rwObjectTestPrivateFlags(light, rpLIGHTPRIVATENOCHROMA))
- {
- RwReal scale =
-
- ((RwReal) 255) * (light->color.red) * (surfaceProps->diffuse);
-
- while (numVert--)
- {
- RwV3d vertToLight, objVertex, objNormal;
- RwReal dot;
-
- OBJVERTGETPOS(&objVertex);
- OBJVERTGETNORMAL(&objNormal);
-
- /* Find the squared distance from light point to vertex */
- RwV3dSub(&vertToLight, &lightPos, &objVertex);
-
- /* Ensure that this vertex is facing the light source */
- dot = RwV3dDotProduct(&vertToLight, &objNormal);
- if (dot > 0.0f)
- {
- RwReal dist2;
-
- /* Ensure vertex lies within the light's radius */
- dist2 = RwV3dDotProduct(&vertToLight, &vertToLight);
- if (dist2 < radSquared)
- {
- RwReal dist;
- RwReal compare;
- RwReal proj;
-
- rwSqrt(&dist, dist2);
- compare = dist * light->minusCosAngle;
- proj = RwV3dDotProduct(&vertToLight, &at);
-
- if (proj < compare)
- {
- RwReal lum;
- RwReal recipDist;
- RwReal normalise;
-
- recipDist =
- (dist > 0.0f) ? (((RwReal) 1) / dist) : 0.0f;
-
- /* This model is the same as the point source
- * inside the cone, zero outside the cone */
- lum = scale * dot * (recipDist - recipRad);
-
- /* It has an extra term for quadratic falloff
- * across the cone though */
- normalise = (dist + compare);
- RWASSERT(normalise >= 0.0f);
- if (normalise > 0.0f)
- {
- normalise = (dist + proj) / normalise;
-
- normalise *= normalise;
- lum *= (((RwReal) 1) - normalise);
- }
-
-#undef FALLOFFCALC
-#define FALLOFFCALC FALLOFFSOFTSPOT
- CAMVERTADDRGBA(1, 1, 1, 0);
- }
- }
- }
-
- /* Next */
- OBJCAMVERTINC();
- }
- }
-
- else
- {
- RwReal scale = 255.0f * surfaceProps->diffuse;
-
- while (numVert--)
- {
- RwV3d vertToLight, objVertex, objNormal;
- RwReal dot;
-
- OBJVERTGETPOS(&objVertex);
- OBJVERTGETNORMAL(&objNormal);
-
- /* Find the squared distance from light point to vertex */
- RwV3dSub(&vertToLight, &lightPos, &objVertex);
-
- /* Ensure that this vertex is facing the light source */
- dot = RwV3dDotProduct(&vertToLight, &objNormal);
- if (dot > 0.0f)
- {
- RwReal dist2;
-
- /* Ensure vertex lies within the light's radius */
- dist2 = RwV3dDotProduct(&vertToLight, &vertToLight);
- if (dist2 < radSquared)
- {
- RwReal dist;
- RwReal compare;
- RwReal proj;
-
- rwSqrt(&dist, dist2);
- compare = dist * light->minusCosAngle;
- proj = RwV3dDotProduct(&vertToLight, &at);
-
- if (proj < compare)
- {
-
- RwReal lum;
- RwReal normalise;
- RwReal recipDist;
-
- /* Get the real distance from the light
- * to the vertex (not squared) */
- recipDist =
- (dist > 0.0f) ? (((RwReal) 1) / dist) : 0.0f;
-
- /* This model is the same as the point source
- * inside the cone, zero outside the cone */
- lum = scale * dot * (recipDist - recipRad);
-
- /* It has an extra term for quadratic falloff
- * across the cone though */
- /* It has an extra term for quadratic falloff
- * across the cone though */
- normalise = (dist + compare);
- RWASSERT(normalise >= 0.0f);
- if (normalise > 0.0f)
- {
- normalise = (dist + proj) / normalise;
-
- normalise *= normalise;
- lum *= (((RwReal) 1) - normalise);
-
- }
- /* Introduce the light colours as a
- * scaling factor for luminance */
-#undef FALLOFFCALC
-#define FALLOFFCALC FALLOFFSOFTSPOT
- CAMVERTADDRGBA(light->color.red,
- light->color.green,
- light->color.blue, 0);
- }
- }
- }
-
- /* Next */
- OBJCAMVERTINC();
- }
- }
-
- RWRETURNVOID();
-}
diff --git a/sdk/rwsdk/include/d3d8/rpanisot.h b/sdk/rwsdk/include/d3d8/rpanisot.h
index 4f4445a4..323786f4 100644
--- a/sdk/rwsdk/include/d3d8/rpanisot.h
+++ b/sdk/rwsdk/include/d3d8/rpanisot.h
@@ -7,7 +7,7 @@
/**
* \defgroup rpanisot RpAnisot
- * \ingroup rpplugin
+ * \ingroup mipmapping
*
* Anisotropic Texture Sampling Plugin for RenderWare Graphics.
*/
@@ -22,7 +22,7 @@
* \li \b Plugin \b attachments: \ref RpWorldPluginAttach, \ref RpAnisotPluginAttach
*
* \subsection anisotoverview Overview
- * The RpAnisot plugin is used to extend an RwTexture with a maximum
+ * The RpAnisot plugin is used to extend an \ref RwTexture with a maximum
* anisotropy value that will be used when a particular texture is drawn.
* When textured polygons are viewed nearly edge on, for example when looking
* dowm a road or a football pitch, distant pixels are not sampled very well
diff --git a/sdk/rwsdk/include/d3d8/rpanisot.rpe b/sdk/rwsdk/include/d3d8/rpanisot.rpe
index 5216ec9c..0464081f 100644
--- a/sdk/rwsdk/include/d3d8/rpanisot.rpe
+++ b/sdk/rwsdk/include/d3d8/rpanisot.rpe
@@ -160,472 +160,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
enum e_rwdb_CriterionLabel
{
diff --git a/sdk/rwsdk/include/d3d8/rpcollis.h b/sdk/rwsdk/include/d3d8/rpcollis.h
index 908fb68e..23e67f35 100644
--- a/sdk/rwsdk/include/d3d8/rpcollis.h
+++ b/sdk/rwsdk/include/d3d8/rpcollis.h
@@ -31,7 +31,7 @@
/**
* \defgroup rpcollis RpCollision
- * \ingroup rpplugin
+ * \ingroup collisiondetection
*
* Collision Plugin for RenderWare Graphics.
*/
@@ -67,12 +67,12 @@ enum RpIntersectType
};
typedef enum RpIntersectType RpIntersectType;
+typedef union RpIntersectData RpIntersectData;
/**
* \ingroup rpcollis
* RpIntersectData, this union type is used to specify the parameters
* for an intersection primitive of the desired type (\ref RpIntersectType)
*/
-typedef union RpIntersectData RpIntersectData;
union RpIntersectData
{
RwLine line; /**<For type rpINTERSECTLINE */
@@ -144,7 +144,6 @@ struct RpCollisionBuildParam
/**
* \ingroup rpcollis
- * \typedef RpIntersectionCallBackWorldTriangle
* \ref RpIntersectionCallBackWorldTriangle represents the function called
* from \ref RpCollisionWorldForAllIntersections for all intersections between
* the specified primitive and the static geometry in a given world. This
@@ -152,6 +151,10 @@ struct RpCollisionBuildParam
* indicate success. The callback may return NULL to terminate further
* callbacks on the world.
*
+ * \note The memory pointed to by collTriangle is stored on the stack.
+ * This memory should be considered volatile. To use this data outside
+ * of the iterator, copy the contents.
+ *
* \param intersection Pointer to the intersection primitive.
* \param sector Pointer to the world sector containing the triangle.
* \param collTriangle Pointer to the \ref RpCollisionTriangle representing
@@ -181,7 +184,6 @@ typedef RpCollisionTriangle *(*RpIntersectionCallBackWorldTriangle)
/**
* \ingroup rpcollis
- * \typedef RpIntersectionCallBackAtomic
* \ref RpIntersectionCallBackAtomic represents the function called from
* \ref RpWorldForAllAtomicIntersections for all intersections between the
* specified primitive and collision atomics in a given world. This function
@@ -215,7 +217,6 @@ typedef RpAtomic *(*RpIntersectionCallBackAtomic)
/**
* \ingroup rpcollis
- * \typedef RpIntersectionCallBackWorldSector
* \ref RpIntersectionCallBackWorldSector represents the function called from
* \ref RpWorldForAllWorldSectorIntersections for all intersections between the
* specified primitive and world sectors in a given world. This function should
@@ -234,7 +235,6 @@ typedef RpWorldSector *(*RpIntersectionCallBackWorldSector)
/**
* \ingroup rpcollis
- * \typedef RpIntersectionCallBackGeometryTriangle
* \ref RpIntersectionCallBackGeometryTriangle represents the function called
* from \ref RpAtomicForAllIntersections and
* \ref RpCollisionGeometryForAllIntersections
diff --git a/sdk/rwsdk/include/d3d8/rpcollis.rpe b/sdk/rwsdk/include/d3d8/rpcollis.rpe
index 3e891755..49ad286f 100644
--- a/sdk/rwsdk/include/d3d8/rpcollis.rpe
+++ b/sdk/rwsdk/include/d3d8/rpcollis.rpe
@@ -158,472 +158,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
enum e_rwdb_CriterionCollis
{
diff --git a/sdk/rwsdk/include/d3d8/rpcriter.h b/sdk/rwsdk/include/d3d8/rpcriter.h
index c1af25b8..de55389f 100644
--- a/sdk/rwsdk/include/d3d8/rpcriter.h
+++ b/sdk/rwsdk/include/d3d8/rpcriter.h
@@ -1,261 +1,6 @@
-/* Doxygen Core Library groups */
-
-/**
- * \defgroup rwcore Core Library
- *
- * Core Library
- */
-
-/**
- * \defgroup datatypes Data Types
- * \ingroup rwcore
- *
- * Basic Data Types
- */
-
-#ifndef RWPLCORE
-/**
- * \defgroup rwbbox RwBBox
- * \ingroup rwcore
- *
- * Bounding Box
- */
-#endif /* RWPLCORE */
-
-#ifndef RWPLCORE
-/**
- * \defgroup rwcamera RwCamera
- * \ingroup rwcore
- *
- * Cameras define how and what things can be seen. They also define the
- * depth and width of the view by the use of clip-planes and the view
- * window.
- */
-#endif /* RWPLCORE */
-
-#ifndef RWPLCORE
-/**
- * \defgroup rwcameravertex RwCameraVertex
- * \ingroup rwcore
- *
- * Camera space vertex data access
- */
-#endif /* RWPLCORE */
-
-/**
- * \defgroup rwdebug RwDebug
- * \ingroup rwcore
- *
- * Debug handling
- */
-
-/**
- * \defgroup rwengine RwEngine
- * \ingroup rwcore
- *
- * Device handling.
- */
-
-/**
- * \defgroup rwerror RwError
- * \ingroup rwcore
- *
- * Error code handling
- */
-
-#ifndef RWPLCORE
-/**
- * \defgroup rwframe RwFrame
- * \ingroup rwcore
- *
- * Frames define relationships between objects and the world
- */
-#endif /* RWPLCORE */
-
-/**
- * \defgroup rwfreelist RwFreeList
- * \ingroup rwcore
- *
- * Free lists
- */
-
-#ifndef RWPLCORE
-/**
- * \defgroup rwimage RwImage
- * \ingroup rwcore
- *
- * Image handling.
- */
-#endif /* RWPLCORE */
-
-/**
- * \defgroup rwim2d RwIm2D
- * \ingroup rwcore
- *
- * 2D immediate mode support
- */
-
-#ifndef RWPLCORE
-/**
- * \defgroup rwim2dcameravertex RwIm2DCameraVertex
- * \ingroup rwcore
- *
- * 2D Camera space vertex data access
- */
-#endif /* RWPLCORE */
-
-#ifndef RWPLCORE
-/**
- * \defgroup rwim2dvertex RwIm2DVertex
- * \ingroup rwcore
- *
- * Im2D Vertex data access
- */
-#endif /* RWPLCORE */
-
-#ifndef RWPLCORE
-/**
- * \defgroup rwim3d RwIm3D
- * \ingroup rwcore
- *
- * 3D immediate mode support
- */
-#endif /* RWPLCORE */
-
-#ifndef RWPLCORE
-/**
- * \defgroup rwim3dvertex RwIm3DVertex
- * \ingroup rwcore
- *
- * Im3D Vertex data access
- */
-#endif /* RWPLCORE */
-
-/**
- * \defgroup rwmatrix RwMatrix
- * \ingroup rwcore
- *
- * Handling binary matrix representations.
- */
-
-/**
- * \defgroup rwmem RwMem
- * \ingroup rwcore
- *
- * Memory
- */
-
-#ifndef RWPLCORE
-/**
- * \defgroup rwobject RwObject
- * \ingroup rwcore
- *
- * object
- */
-#endif /* RWPLCORE */
-
-/**
- * \defgroup rwos RwOs
- * \ingroup rwcore
- *
- * Operating System
- */
-
-#ifndef RWPLCORE
-/**
- * \defgroup rwraster RwRaster
- * \ingroup rwcore
- *
- * Image/raster coupling handling.
- */
-#endif /* RWPLCORE */
-
-/**
- * \defgroup rwrenderstate RwRenderState
- * \ingroup rwcore
- *
- * Render states
- */
-
-/**
- * \defgroup rwresources RwResources
- * \ingroup rwcore
- *
- * Resource handling.
- * Resources are used to instance objects into.
- */
-
-
-/**
- * \defgroup rwrgba RwRGBA
- * \ingroup rwcore
- *
- * Color space functionality.
- */
-
-
-/**
- * \defgroup rwstream RwStream
- * \ingroup rwcore
- *
- * Stream
- */
-
-#ifndef RWPLCORE
-/**
- * \defgroup rwtexdict RwTexDictionary
- * \ingroup rwcore
- *
- * Texture Dictionary
- */
-#endif /* RWPLCORE */
-
-#ifndef RWPLCORE
-/**
- * \defgroup rwtexture RwTexture
- * \ingroup rwcore
- *
- * Texture handling.
- * Textures are special cases of rasters that can be applied to polygons.
- */
-#endif /* RWPLCORE */
-
-#ifndef RWPLCORE
-/**
- * \defgroup rwv2d RwV2d
- * \ingroup rwcore
- *
- * 2D Vector mathematics.
- */
-#endif /* RWPLCORE */
-
-#ifndef RWPLCORE
-/**
- * \defgroup rwv3d RwV3d
- * \ingroup rwcore
- *
- * 3D Vector mathematics.
- */
-#endif /* RWPLCORE */
-
-#ifndef RWPLCORE
-/**
- * \defgroup rwcorepowerpipe PowerPipe
- * \ingroup rwcore
- *
- * PowerPipe
- */
-#endif /* RWPLCORE */
-
-#ifndef RWPLCORE
-/**
- * \defgroup rwcoregeneric Generic
- * \ingroup rwcorepowerpipe
- *
- * Generic Pipeline
- *
- */
-#endif /* RWPLCORE */
+#ifdef DOXYGEN
+#include "doxygen.h"
+#endif /* DOXYGEN */
/* These are plugins */
#define rwID_METRICSPLUGIN MAKECHUNKID(rwVENDORID_CRITERIONTK, 0x01)
@@ -306,137 +51,10 @@
#define rwID_MULTITEXPLUGIN MAKECHUNKID(rwVENDORID_CRITERIONTK, 0x2c)
#define rwID_CHAINPLUGIN MAKECHUNKID(rwVENDORID_CRITERIONTK, 0x2d)
#define rwID_TOONPLUGIN MAKECHUNKID(rwVENDORID_CRITERIONTK, 0x2e)
-#define rwID_PTANKPLUGIN MAKECHUNKID(rwVENDORID_CRITERIONTK, 0x2f)
-
-#define rwID_PRTSTDPLUGIN MAKECHUNKID(rwVENDORID_CRITERIONTK, 0x30)
-
-
-/********************************************************/
-
-/* Doxygen plugin groups. */
-
-#ifndef RWPLCORE
-
-/**
- * \defgroup rpplugin Plugins
- *
- * API Plugins
- *
- */
-
-/**
- * \defgroup rpworld RpWorld
- * \ingroup rpplugin
- *
- * World handling Plugin
- *
- * Gives objects context,
- * and provides a mechanism for efficient static object rendering.
- */
-
-/********************************************************/
-
-/**
- * \defgroup rpworlddatatypes Data Types
- * \ingroup rpworld
- *
- * RpWorld Data types
- */
-
-/**
- * \defgroup rpatomic RpAtomic
- * \ingroup rpworld
- *
- * Atomics
- */
-
-/**
- * \defgroup rpclump RpClump
- * \ingroup rpworld
- *
- * Clumps
- */
-
-/**
- * \defgroup rpgeometry RpGeometry
- * \ingroup rpworld
- *
- * Handling atomic's geometry
- */
-
-
-/**
- * \defgroup rpinterpolator RpInterpolator
- * \ingroup rpworld
- *
- * Interpolators
- */
-
-/**
- * \defgroup rplight RpLight
- * \ingroup rpworld
- *
- * Lighting 3D objects.
- * Lights are used to illuminate atomics and worlds
- */
-
-/**
- * \defgroup rpmaterial RpMaterial
- * \ingroup rpworld
- *
- * Handling surface materials
- * Materials describe how things are to appear when rendered
- */
-
-/**
- * \defgroup rpmesh RpMesh
- * \ingroup rpworld
- *
- * Provide construction and enumeration facilities for meshes.
- */
-
-/**
- * \defgroup rpmorphtarget RpMorphTarget
- * \ingroup rpworld
- *
- * Morph Targets
- */
-
-/**
- * \defgroup rpworldsub RpWorld
- * \ingroup rpworld
- *
- * RpWorld sub group
- */
-
-/**
- * \defgroup rpworldsector RpWorldSector
- * \ingroup rpworld
- *
- * Handling atomic sectors
- */
-
-/**
- * \defgroup rpworldrwcamera RwCamera
- * \ingroup rpworld
- *
- * Cameras
- */
-
-/**
- * \defgroup rpworldpowerpipe PowerPipe
- * \ingroup rpworld
- *
- * PowerPipe
- */
-
-/**
- * \defgroup rpworldp2generic Generic
- * \ingroup rpworldpowerpipe
- *
- * Generic
- */
-#endif /* RWPLCORE */
+#define rwID_PTANKPLUGIN MAKECHUNKID(rwVENDORID_CRITERIONTK, 0x2f)
+#define rwID_PRTSTDPLUGIN MAKECHUNKID(rwVENDORID_CRITERIONTK, 0x30)
+#define rwID_PDSPLUGIN MAKECHUNKID(rwVENDORID_CRITERIONTK, 0x31)
+#define rwID_PRTADVPLUGIN MAKECHUNKID(rwVENDORID_CRITERIONTK, 0x32)
/* These are toolkits */
#define rwID_CHARSEPLUGIN MAKECHUNKID(rwVENDORID_CRITERIONTK, 0x80)
@@ -480,93 +98,9 @@
#define rwID_BARYCENTRIC MAKECHUNKID(rwVENDORID_CRITERIONTK, 0xb2)
#define rwID_PITEXDICTIONARYTK MAKECHUNKID(rwVENDORID_CRITERIONTK, 0xb3)
#define rwID_TOCTOOLKIT MAKECHUNKID(rwVENDORID_CRITERIONTK, 0xb4)
-
-/**********************************************************************/
-
-/* Doxygen Toolkit groups */
-
-/**
- * \defgroup rttool Toolkits
- *
- * API Toolkits
- */
-
-/**
- * \defgroup fxpack FXPack
- *
- * FXPack component group
- */
-
-/**********************************************************************/
-
-/**
- * \defgroup platformspecific Platform Specific
- *
- * Links to all platform specific information in the API Reference can
- * be found in this folder.
- */
-
-/**********************************************************************/
-
-/* Index Page definition for API Reference. Don't mess with it unless you know what you're doing. */
+#define rwID_TPLTOOLKIT MAKECHUNKID(rwVENDORID_CRITERIONTK, 0xb5)
+#define rwID_ALTPIPETOOLKIT MAKECHUNKID(rwVENDORID_CRITERIONTK, 0xb6)
+#define rwID_ANIMTOOLKIT MAKECHUNKID(rwVENDORID_CRITERIONTK, 0xb7)
+#define rwID_SKINSPLITTOOKIT MAKECHUNKID(rwVENDORID_CRITERIONTK, 0xb8)
-/**
- * \mainpage RenderWare Graphics API Reference
- *
- * \image html rwglogo.jpg
- *
- * This document provides an API Reference for release 3.3 of the RenderWare
- * Graphics SDK.
- *
- * You do not have to wait for a major release to obtain a current API
- * Reference. An up-to-date API Reference is compiled every week and goes out
- * with the weekly build. The footer declares when it was generated.
- *
- * \section otherdocs Documentation Available
- * RenderWare Graphics is supplied with:
- *
- * - A top-level README.PDF -- If you read nothing else, at least read this!
- * - this API Reference
- * - the User Guide
- * - Artist's documentation (if installed)
- * - Examples documentation
- * - Maestro documentation
- * - Tools documentation
- * - White Papers
- * - readme.txt files for each of the supplied Examples
- *
- * \section contactus Contact Us
- *
- * \subsection csl Criterion Software Ltd.
- * For general information about RenderWare e-mail info@csl.com.
- *
- * \subsection devrels Developer Relations
- *
- * For information regarding Support please email devrels@csl.com
- *
- * \subsection sales Sales
- *
- * For sales information contact: rw-sales@csl.com
- *
- * \section copyright Copyright Notice
- *
- * The information in this document is subject to change without notice and does not represent
- * a commitment on the part of Criterion Software Ltd. The software described in this document is
- * furnished under a license agreement or a non-disclosure agreement. The software may be used or
- * copied only in accordance with the terms of the agreement. It is against the law to copy the
- * software on any medium except as specifically allowed in the license or non-disclosure agreement.
- *
- * No part of this documentation may be reproduced or transmitted in any form or by any means for any
- * purpose without the express written permission of Criterion Software Ltd.
- *
- * Copyright 1993 - 2002 Criterion Software Ltd. All rights reserved.
- *
- * Canon and RenderWare are registered trademarks of Canon Inc. Nintendo is a registered trademark
- * and NINTENDO GAMECUBE a trademark of Nintendo Co., Ltd. Microsoft is a registered trademark and
- * Xbox is a trademark of Microsoft Corporation. PlayStation is a registered trademark of Sony Computer
- * Entertainment Inc.
- *
- * All other trademarks mentioned herein are the property of their respective companies.
- *
- */
diff --git a/sdk/rwsdk/include/d3d8/rpdbgerr.c b/sdk/rwsdk/include/d3d8/rpdbgerr.c
index 0c83c04e..70bc941d 100644
--- a/sdk/rwsdk/include/d3d8/rpdbgerr.c
+++ b/sdk/rwsdk/include/d3d8/rpdbgerr.c
@@ -31,7 +31,7 @@
#include <rwcore.h>
#include <rpdbgerr.h>
-static const char rcsid[] __RWUNUSED__ = "@@(#)$Id: //RenderWare/RW33Active/dev/rwsdk/src/plcore/rpdbgerr.c#1 $";
+static const char rcsid[] __RWUNUSED__ = "@@(#)$Id: rpdbgerr.c,v 1.2 2004/08/31 17:40:34 gtristram Exp $";
#ifdef RWDEBUG
diff --git a/sdk/rwsdk/include/d3d8/rpdbgerr.h b/sdk/rwsdk/include/d3d8/rpdbgerr.h
index 6918469a..e0500057 100644
--- a/sdk/rwsdk/include/d3d8/rpdbgerr.h
+++ b/sdk/rwsdk/include/d3d8/rpdbgerr.h
@@ -16,8 +16,6 @@
/* Pick up _ASSERTE macro */
#ifdef _XBOX
#include <xtl.h>
-#else /* _XBOX */
-#include <windows.h>
#endif /* _XBOX */
#if (defined(RWMEMDEBUG) && !defined(_CRTDBG_MAP_ALLOC))
#define _CRTDBG_MAP_ALLOC
@@ -235,6 +233,22 @@ do \
} \
while (0)
+#define RWASSERTM(condition, messageArgs) \
+do \
+{ \
+ if (!(condition)) \
+ { \
+ RwDebugSendMessage(rwDEBUGASSERT, \
+ __dbFunctionName, \
+ RWSTRING(#condition)); \
+ RwDebugSendMessage(rwDEBUGMESSAGE, \
+ __dbFunctionName, \
+ _rwdbsprintf messageArgs); \
+ } \
+ RWASSERTE(condition); \
+} \
+while (0)
+
#else /* RWDEBUG */
#define RWRETURN(value) return(value)
@@ -253,6 +267,7 @@ while (0)
#define RWFUNCTION(name)
#define RWAPIFUNCTION(name)
#define RWASSERT(condition)
+#define RWASSERTM(condition, messageArgs)
#define RWMESSAGE(args)
#endif
diff --git a/sdk/rwsdk/include/d3d8/rpdmorph.h b/sdk/rwsdk/include/d3d8/rpdmorph.h
index 1494bf3d..89c51b31 100644
--- a/sdk/rwsdk/include/d3d8/rpdmorph.h
+++ b/sdk/rwsdk/include/d3d8/rpdmorph.h
@@ -28,7 +28,7 @@
/**
* \defgroup rpdmorph RpDMorph
- * \ingroup rpplugin
+ * \ingroup deltamorphing
* \file rpdmorph.h
*
* Delta Morphing Plugin for RenderWare Graphics.
@@ -153,7 +153,7 @@ RpDMorphTargetGetFlags( RpDMorphTarget *dMorphTarget );
* These functions work at the DMorphAtomic level.
*/
extern RpAtomic *
-RpDMorphAtomicInitalize( RpAtomic *atomic );
+RpDMorphAtomicInitialize( RpAtomic *atomic );
extern RwReal *
RpDMorphAtomicGetDMorphValues( RpAtomic *atomic );
diff --git a/sdk/rwsdk/include/d3d8/rpdmorph.rpe b/sdk/rwsdk/include/d3d8/rpdmorph.rpe
index a5202425..b35acc4e 100644
--- a/sdk/rwsdk/include/d3d8/rpdmorph.rpe
+++ b/sdk/rwsdk/include/d3d8/rpdmorph.rpe
@@ -160,472 +160,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
enum e_rwdb_CriterionDMorph
{
diff --git a/sdk/rwsdk/include/d3d8/rphanim.h b/sdk/rwsdk/include/d3d8/rphanim.h
index a9b0438a..0d1bba7a 100644
--- a/sdk/rwsdk/include/d3d8/rphanim.h
+++ b/sdk/rwsdk/include/d3d8/rphanim.h
@@ -26,7 +26,6 @@
* Purpose : Hierarchical animation *
* *
**************************************************************************/
-
#ifndef RPHANIM_H
#define RPHANIM_H
@@ -38,7 +37,7 @@
/**
* \defgroup rphanim RpHAnim
- * \ingroup rpplugin
+ * \ingroup objectframehanim
*
* Hierarchical Animation Plugin for RenderWare Graphics.
*/
@@ -66,45 +65,26 @@
*/
#include <rphanim.rpe> /* automatically generated header file */
#include <rtquat.h>
+#include <rtanim.h>
#define rpHANIMSTREAMCURRENTVERSION 0x100
-/**
- * \ingroup rphanim
- * \ref RpHAnimAtomicGlobalVars typedef for struct RpHAnimAtomicGlobalVars
- */
+#if (!defined(DOXYGEN))
+
typedef struct RpHAnimAtomicGlobalVars RpHAnimAtomicGlobalVars;
-/**
- * \ingroup rphanim
- * \struct RpHAnimAtomicGlobalVars
- */
struct RpHAnimAtomicGlobalVars
{
- RwInt32 engineOffset ; /* Offset into global data */
+ RwInt32 engineOffset;
RwFreeList *HAnimFreeList;
- RwFreeList *HAnimAnimationFreeList;
};
-extern RpHAnimAtomicGlobalVars RpHAnimAtomicGlobals;
+#endif /* (!defined(DOXYGEN)) */
-#define rpHANIMSTDKEYFRAMESIZE sizeof(RpHAnimStdKeyFrame)
+#define rpHANIMSTDKEYFRAMESIZE sizeof(RpHAnimKeyFrame)
#define rpHANIMSTDKEYFRAMETYPEID 0x1
-#define RwAnimMalloc() \
- RwFreeListAlloc(RpHAnimAtomicGlobals.HAnimFreeList)
-
-#define RwAnimFree(_anim) \
- RwFreeListFree(RpHAnimAtomicGlobals.HAnimFreeList, (_anim))
-
-#define RwAnimAnimationMalloc() \
- RwFreeListAlloc(RpHAnimAtomicGlobals.HAnimAnimationFreeList)
-
-#define RwAnimAnimationFree(_animAnimation) \
- RwFreeListFree(RpHAnimAtomicGlobals.HAnimAnimationFreeList, \
- (_animAnimation))
-
-#define RpV3dInterpolate(o, a, s, b) \
+#define RpV3dInterpolate(o,a,s,b) \
MACRO_START \
{ \
(o)->x = (((a)->x) + ((s)) * (((b)->x) - ((a)->x))); \
@@ -113,223 +93,57 @@ MACRO_START \
} \
MACRO_STOP
-/**
- * \ingroup rphanim
- * \ref RpHAnimHierarchy typedef for struct RpHAnimHierarchy
- */
-typedef struct RpHAnimHierarchy RpHAnimHierarchy;
-
-/**
- * \ingroup rphanim
- * \ref RpHAnimAnimation typedef for struct RpHAnimAnimation
- */
-typedef struct RpHAnimAnimation RpHAnimAnimation;
-
-/**
- * \ingroup rphanim
- * \ref RpHAnimHierarchyCallBack
- * This typedef defines a callback function for use with the
- * \ref RpHAnimHierarchySetAnimCallBack and
- * \ref RpHAnimHierarchySetAnimLoopCallBack functions.
- *
- * \param hierarchy
- * A pointer to the AnimHierarchy structure.
- *
- * \param data User-defined data.
- * You can use this to pass your own data
- * structure(s) to the callback function.
- *
- * \see RpHAnimHierarchySetAnimCallBack
- * \see RpHAnimHierarchySetAnimLoopCallBack
- *
- */
-
-typedef RpHAnimHierarchy * (*RpHAnimHierarchyCallBack) (RpHAnimHierarchy *hierarchy,
- void *data);
-
-/*
- * The following CallBacks are needed for each overloaded interpolation
- * scheme. See RpHAnimInterpolatorInfo.
- */
-
-/**
- * \ingroup rphanim
- * \ref RpHAnimKeyFrameToMatrixCallBack
- * This typedef defines a callback function for converting
- * an animation keyframe into a modeling matrix. The output matrix will be
- * used to construct the array of world or local space matrices for the
- * hierarchy as obtained with \ref RpHAnimHierarchyGetMatrixArray, and
- * possibly used for updating an external \ref RwFrame hierarchy.
- *
- * \param matrix This is the matrix to store the output of the conversion
- * \param voidIFrame This is a void pointer to the keyframe and should be cast
- * to the keyframe type this callback is for.
- */
-typedef void (*RpHAnimKeyFrameToMatrixCallBack) (RwMatrix *matrix, void *voidIFrame);
-
-/**
- * \ingroup rphanim
- * \ref RpHAnimKeyFrameBlendCallBack
- * This typedef defines a callback function for blending between two animation
- * keyframes by the given blend factor.
- *
- * \param voidOut This is the void pointer for the output of the blend
- * \param voidIn1 First input keyframe
- * \param voidIn2 Second input keyframe
- * \param alpha Blend factor
- */
-typedef void (*RpHAnimKeyFrameBlendCallBack) (void *voidOut, void *voidIn1,
- void *voidIn2, RwReal alpha);
-
-/**
- * \ingroup rphanim
- * \ref RpHAnimKeyFrameInterpolateCallBack
- * This typedef defines a callback function for interpolating between two
- * animation keyframes according to the given time.
- *
- * \param voidOut This is the void pointer for the output of the
- * interpolation
- * \param voidIn1 First input keyframe
- * \param voidIn2 Second input keyframe
- * \param time Time at which to interpolate
- */
-typedef void (*RpHAnimKeyFrameInterpolateCallBack) (void *voidOut, void *voidIn1,
- void *voidIn2, RwReal time);
-
-/**
- * \ingroup rphanim
- * \ref RpHAnimKeyFrameAddCallBack
- * This typedef defines a callback function for adding together two animation
- * keyframes. One of the keyframes would usually be a delta.
- *
- * \param voidOut This is the void pointer for the output summed keyframe
- * \param voidIn1 First input keyframe
- * \param voidIn2 Second input keyframe
- */
-typedef void (*RpHAnimKeyFrameAddCallBack) (void *voidOut, void *voidIn1,
- void *voidIn2);
-
-/**
- * \ingroup rphanim
- * \ref RpHAnimKeyFrameMulRecipCallBack
- * This typedef defines a callback function for multiplying a keyframe
- * by the inverse of another keyframe
- *
- * \param voidFrame This is the void pointer for the keyframe to be modified
- * \param voidStart First start keyframe to take the reciprocal of.
- */
-typedef void (*RpHAnimKeyFrameMulRecipCallBack) (void *voidFrame, void *voidStart);
-
-/**
- * \ingroup rphanim
- * \ref RpHAnimKeyFrameStreamReadCallBack
- * This typedef defines a callback function for reading in keyframes
- * from an \ref RwStream for the given animation.
- *
- * \param stream The stream to read the keyframes from
- * \param animation The animation to read the keyframes into
- *
- * \return Pointer to the animation.
- */
-typedef RpHAnimAnimation * (*RpHAnimKeyFrameStreamReadCallBack) (RwStream *stream, RpHAnimAnimation *animation);
-
-/**
- * \ingroup rphanim
- * \ref RpHAnimKeyFrameStreamWriteCallBack
- * This typedef defines a callback function for writing keyframes from the
- * given animation to an \ref RwStream.
- *
- * \param animation The animation to write out from
- * \param stream The stream to write the keyframes to
- *
- * \return TRUE if successful.
- */
-typedef RwBool (*RpHAnimKeyFrameStreamWriteCallBack) (RpHAnimAnimation *animation, RwStream *stream);
-
-/**
- * \ingroup rphanim
- * \ref RpHAnimKeyFrameStreamGetSizeCallBack
- * This typedef defines a callback function for calculating the binary stream
- * size of keyframe data within an animation.
- *
- * \param animation The animation to calculate sizes of
- *
- * \return Size in bytes of the keyframe data.
- */
-typedef RwInt32 (*RpHAnimKeyFrameStreamGetSizeCallBack) (RpHAnimAnimation *animation);
/**
* \ingroup rphanim
- * \ref RpHAnimInterpolatorInfo
- * typedef for struct \ref RpHAnimInterpolatorInfo
+ * \ref RpHAnimKeyFrame
+ * typedef for struct RpHAnimKeyFrame. Based on \ref RtAnimKeyFrameHeader.
*/
-typedef struct RpHAnimInterpolatorInfo RpHAnimInterpolatorInfo;
+typedef struct RpHAnimKeyFrame RpHAnimKeyFrame;
/**
* \ingroup rphanim
- * \struct RpHAnimInterpolatorInfo
- * This is used to hold information for a keyframe interpolation scheme.
- *
- * \see RpHAnimRegisterInterpolationScheme
- * \see RpHAnimGetInterpolatorInfo
+ * \struct RpHAnimKeyFrame
+ * A structure representing the standard keyframe data. Sequences of
+ * such keyframes in an \ref RtAnimAnimation defines the animation of each
+ * node in a hierarchy.
*/
-struct RpHAnimInterpolatorInfo
+struct RpHAnimKeyFrame
{
- RwInt32 typeID; /**< The ID of the interpolation scheme */
- RwInt32 keyFrameSize; /**< Size in bytes of the keyframe structure */
- RpHAnimKeyFrameToMatrixCallBack keyFrameToMatrixCB; /**< Pointer to a function that converts a keyframe to a matrix */
- RpHAnimKeyFrameBlendCallBack keyFrameBlendCB; /**< Pointer to a function that blends between a pair of keyframes for a given delta value */
- RpHAnimKeyFrameInterpolateCallBack keyFrameInterpolateCB; /**< Pointer to a function that interpolates between two keyframes for a given time in between */
- RpHAnimKeyFrameAddCallBack keyFrameAddCB; /**< Pointer to a function that adds two keyframes (one of which may be a delta) */
- RpHAnimKeyFrameMulRecipCallBack keyFrameMulRecipCB; /**< Pointer to a function that multiplies a keyframe by the reciprocal of another */
- RpHAnimKeyFrameStreamReadCallBack keyFrameStreamReadCB; /**< Pointer to a function that reads the keyframes from a stream for a given animation */
- RpHAnimKeyFrameStreamWriteCallBack keyFrameStreamWriteCB; /**< Pointer to a function that writes the keyframes to a stream for a given animation */
- RpHAnimKeyFrameStreamGetSizeCallBack keyFrameStreamGetSizeCB; /**< Pointer to a function that returns the binary stream size of the keyframes for a given animation */
+ RpHAnimKeyFrame *prevFrame; /**< Pointer to the previous keyframe */
+ RwReal time; /**< Time at keyframe */
+ RtQuat q; /**< Quaternion rotation at keyframe */
+ RwV3d t; /**< Translation at keyframe */
};
/**
* \ingroup rphanim
- * \ref RpHAnimKeyFrameHeader
- * typedef for struct RpHAnimKeyFrameHeader
+ * \ref RpHAnimInterpFrame
+ * typedef for struct RpHAnimInterpFrame. Based on \ref RtAnimInterpFrameHeader.
*/
-typedef struct RpHAnimKeyFrameHeader RpHAnimKeyFrameHeader;
+typedef struct RpHAnimInterpFrame RpHAnimInterpFrame;
/**
* \ingroup rphanim
- * \struct RpHAnimKeyFrameHeader
- * Holds header information for a keyframe. All keyframe structures used with
- * the overloadable interpolation system should start with this data.
- *
- * \see RpHAnimStdKeyFrame
- * \see RpHAnimRegisterInterpolationScheme
+ * \struct RpHAnimInterpFrame
+ * A structure representing an interpolated keyframe. The initial part of the
+ * structure matches \ref RtAnimInterpFrameHeader.
*/
-struct RpHAnimKeyFrameHeader
+struct RpHAnimInterpFrame
{
- void *prevFrame; /**< Previous keyframe for particular hierarchy node */
- RwReal time; /**< Time at keyframe */
+ RpHAnimKeyFrame *keyFrame1;
+ /**< Pointer to 1st keyframe of current interpolation pair */
+ RpHAnimKeyFrame *keyFrame2;
+ /**< Pointer to 2nd keyframe of current interpolation pair */
+ RtQuat q; /**< Quaternion rotation */
+ RwV3d t; /**< Translation */
};
/**
* \ingroup rphanim
- * \ref RpHAnimStdKeyFrame
- * typedef for struct RpHAnimStdKeyFrame
- */
-typedef struct RpHAnimStdKeyFrame RpHAnimStdKeyFrame;
-
-/**
- * \ingroup rphanim
- * \struct RpHAnimStdKeyFrame
- * A structure representing the standard keyframe data. Sequences of
- * such keyframes in an \ref RpHAnimAnimation defines the animation of each
- * node in a hierarchy.
+ * \ref RpHAnimHierarchy typedef for struct RpHAnimHierarchy
*/
-struct RpHAnimStdKeyFrame
-{
- RpHAnimStdKeyFrame *prevFrame; /**< Previous keyframe for particular hierarchy node */
- RwReal time; /**< Time at keyframe */
- RtQuat q; /**< Quaternion rotation at keyframe */
- RwV3d t; /**< Translation at keyframe */
-};
+typedef struct RpHAnimHierarchy RpHAnimHierarchy;
/* Flags for FrameInfos */
@@ -347,54 +161,23 @@ typedef struct RpHAnimNodeInfo RpHAnimNodeInfo;
* \ingroup rphanim
* \struct RpHAnimNodeInfo
*
+ * Used to describe a hierarchy toplogy.
+ * It holds flags representing its position in the
+ * hierarchy as well as a pointer to the matching \ref RwFrame if the
+ * hierarchy has been attached to a \ref RwFrame hierarchy.
+ *
*/
struct RpHAnimNodeInfo
{
- RwInt32 nodeID; /**< User defined ID for this node */
- RwInt32 nodeIndex; /**< Array index of node */
+ RwInt32 nodeID; /**< User defined ID for this node */
+ RwInt32 nodeIndex; /**< Array index of node */
RwInt32 flags; /**< Matrix push/pop flags */
RwFrame * pFrame; /**< Pointer to an attached RwFrame (see \ref RpHAnimHierarchyAttach) */
};
/**
* \ingroup rphanim
- * \struct RpHAnimAnimation
- * A hierarchical animation consists of an array of keyframe structures,
- * along with some flags and a duration.
- *
- * The keyframes should be presented in the order they are needed
- * to animate forwards through time. Pointers link all of the keyframes
- * for a particular node backwards through time in a list.
- *
- * For example, a 3 node animation, with keyframes at the following times:
- *
- * Node 1: 0.0, 1.0, 2.0, 3.0
- * Node 2: 0.0, 3.0
- * Node 3: 0.0, 2.0, 2.5, 3.0
- *
- * should be formatted in an RpHAnimAnimation animation like this:
- *
- * B1,0.0 B2,0.0 B3,0.0 B1,1.0, B2,3.0, B3,2.0, B1,2.0, B1,3.0, B3,2.5 B3,3.0
- *
- * Each node MUST start at time = 0.0, and each node must terminate with a keyframe
- * at time = duration of animation.
- *
- * \see RpHAnimAnimationCreate
- */
-struct RpHAnimAnimation
-{
- RpHAnimInterpolatorInfo *interpInfo; /**< Pointer to interpolation scheme information */
- RwInt32 numFrames; /**< Number of keyframes in the animation */
- RwInt32 flags; /**< Specifies details about animation, relative translation modes etc */
- RwReal duration; /**< Duration of animation in seconds */
- void *pFrames; /**< Pointer to the animation keyframes */
-};
-
-/**
- * \ingroup rphanim
* \ref RpHAnimHierarchyFlag defines type and update modes in HAnimHierarchies
- *
- * \see RpAnimHierarchyFlag
*/
enum RpHAnimHierarchyFlag
{
@@ -411,9 +194,7 @@ enum RpHAnimHierarchyFlag
rpHANIMHIERARCHYFLAGFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
};
-/**
- * \ingroup rphanim
- * \typedef RpHAnimHierarchyFlag
+/*
* These flags are used to control the creation and
* update status of the hierarchy
*/
@@ -422,13 +203,7 @@ typedef enum RpHAnimHierarchyFlag RpHAnimHierarchyFlag;
/**
* \ingroup rphanim
* \struct RpHAnimHierarchy
- * An RpHAnimHierarchy is used to "play back" an animation - it holds the
- * interpolated keyframe data for the current state of an animation
- * concatenated on the end of the structure.
- *
- * The rpHANIMHIERARCHYGETINTERPFRAME() macro can be used to access the current
- * interpolated data, for the current time or to write to this data to override
- * it with procedural animation.
+ * An RpHAnimHierarchy is used to "play back" an animation.
*
* The structure of a hierarchy is defined by an array
* of \ref RpHAnimNodeInfo structures.
@@ -443,48 +218,18 @@ struct RpHAnimHierarchy
{
RwInt32 flags; /**< Flags for the hierarchy */
RwInt32 numNodes; /**< Number of nodes in the hierarchy */
- RpHAnimAnimation *pCurrentAnim; /**< Current animation applied to hierarchy */
- RwReal currentTime; /**< Current animation time */
- void *pNextFrame; /**< Next animation keyframe to be played */
- RpHAnimHierarchyCallBack pAnimCallBack; /**< Animation callback function pointer */
- void *pAnimCallBackData; /**< Animation callback function user data */
- RwReal animCallBackTime; /**< Trigger time for callback function */
- RpHAnimHierarchyCallBack pAnimLoopCallBack; /**< Animation loop callback function pointer */
- void *pAnimLoopCallBackData; /**< Animation loop callback function data */
+
RwMatrix *pMatrixArray; /**< Pointer to node matrices*/
void *pMatrixArrayUnaligned; /**< Pointer to memory used for node matrices
* from which the aligned pMatrixArray is allocated */
RpHAnimNodeInfo *pNodeInfo; /**< Array of node information (push/pop flags etc) */
RwFrame *parentFrame; /**< Pointer to the Root RwFrame of the hierarchy this
* RpHAnimHierarchy represents */
- RwInt32 maxKeyFrameSize; /**< Maximum size of keyframes usable on this hierarhcy
- * (set at creation time) */
- RwInt32 currentKeyFrameSize; /**< Size of keyframes in the current animation */
- RpHAnimKeyFrameToMatrixCallBack keyFrameToMatrixCB; /**< Internal use */
- RpHAnimKeyFrameBlendCallBack keyFrameBlendCB; /**< Internal use */
- RpHAnimKeyFrameInterpolateCallBack keyFrameInterpolateCB; /**< Internal use */
- RpHAnimKeyFrameAddCallBack keyFrameAddCB; /**< Internal use */
RpHAnimHierarchy *parentHierarchy; /**< Internal use */
- RwInt32 offsetInParent; /**< Internal use */
RwInt32 rootParentOffset; /**< Internal use */
-};
-#define rpHANIMHIERARCHYGETINTERPFRAME( hierarchy, nodeIndex ) \
- ( (void *)( ( (RwUInt8 *)&(hierarchy[1]) + \
- ((nodeIndex) * \
- hierarchy->currentKeyFrameSize) ) ) )
-
-#define rpHANIMHIERARCHYGETINTERPFRAME1( hierarchy, nodeIndex ) \
- ( (void *)( ( (RwUInt8 *)&(hierarchy[1]) + \
- ((hierarchy->numNodes + \
- (nodeIndex)) * \
- hierarchy->currentKeyFrameSize) ) ) )
-
-#define rpHANIMHIERARCHYGETINTERPFRAME2( hierarchy, nodeIndex ) \
- ( (void *)( ( (RwUInt8 *)&(hierarchy[1]) + \
- ((hierarchy->numNodes * 2 + \
- (nodeIndex)) * \
- hierarchy->currentKeyFrameSize) ) ) )
+ RtAnimInterpolator *currentAnim; /**< Internal use */
+};
/**
* \ingroup rphanim
@@ -496,36 +241,40 @@ typedef struct RpHAnimFrameExtension RpHAnimFrameExtension;
/**
* \ingroup rphanim
* \struct RpHAnimFrameExtension
+ *
+ * Used to extend \ref RwFrame objects, and thus
+ * allow the mapping between animation hierarchy node ID and \ref RwFrame.
+ *
*/
struct RpHAnimFrameExtension
{
- RwInt32 id; /**< ID given to this RwFrame (default of -1) */
+ RwInt32 id; /**< ID given to this RwFrame (default of -1) */
RpHAnimHierarchy *hierarchy; /**< Pointer to Animation hierarchy attached to this RwFrame */
};
/*--- Plugin API Functions ---*/
-#define RpHAnimHierarchySetFlagsMacro(hierarchy, _flags) \
+#define RpHAnimHierarchySetFlagsMacro(hierarchy,_flags) \
MACRO_START \
{ \
- (hierarchy)->flags = _flags; \
+ (hierarchy)->flags = _flags; \
} \
MACRO_STOP
#define RpHAnimHierarchyGetFlagsMacro(hierarchy) \
((hierarchy)->flags)
-#define RpHAnimStdKeyFrameToMatrixMacro(_matrix, _voidIFrame) \
+#define RpHAnimKeyFrameToMatrixMacro(_matrix,_voidIFrame) \
MACRO_START \
{ \
- RpHAnimStdKeyFrame * iFrame = (RpHAnimStdKeyFrame *)(_voidIFrame); \
+ RpHAnimInterpFrame * iFrame = (RpHAnimInterpFrame *)(_voidIFrame); \
\
/* \
* RpHAnim uses the same types of quaternion as RtQuat \
* hence no conjugate call as in RpSkin \
*/ \
\
- RtQuatUnitConvertToMatrix(&iFrame->q, (_matrix)); \
+ RtQuatUnitConvertToMatrix(&iFrame->q,(_matrix)); \
\
(_matrix)->pos.x = iFrame->t.x; \
(_matrix)->pos.y = iFrame->t.y; \
@@ -534,14 +283,14 @@ MACRO_START \
MACRO_STOP
+
#if (! defined(RWDEBUG))
-#define RpHAnimHierarchySetFlags(hierarchy, _flags) \
- RpHAnimHierarchySetFlagsMacro(hierarchy, _flags)
+#define RpHAnimHierarchySetFlags(hierarchy,_flags) \
+ RpHAnimHierarchySetFlagsMacro(hierarchy,_flags)
#define RpHAnimHierarchyGetFlags(hierarchy) \
(RpHAnimHierarchyFlag)RpHAnimHierarchyGetFlagsMacro(hierarchy)
-
#endif /* (! defined(RWDEBUG)) */
#ifdef __cplusplus
@@ -549,6 +298,8 @@ extern "C"
{
#endif /* __cplusplus */
+extern RpHAnimAtomicGlobalVars RpHAnimAtomicGlobals;
+
#if (defined(RWDEBUG))
extern RpHAnimHierarchy *
@@ -560,15 +311,9 @@ RpHAnimHierarchyGetFlags(RpHAnimHierarchy *hierarchy);
#endif /* (defined(RWDEBUG)) */
-/* Keyframe Interpolator Types */
-
-extern RwBool
-RpHAnimRegisterInterpolationScheme(RpHAnimInterpolatorInfo *interpolatorInfo);
-
-extern RpHAnimInterpolatorInfo *
-RpHAnimGetInterpolatorInfo(RwInt32 typeID);
-
/* Animation hierarchy creation */
+extern void
+RpHAnimHierarchySetFreeListCreateParams(RwInt32 blockSize,RwInt32 numBlocksToPrealloc);
extern RpHAnimHierarchy *
RpHAnimHierarchyCreate(RwInt32 numNodes,
@@ -613,45 +358,10 @@ extern RpHAnimHierarchy *
RpHAnimFrameGetHierarchy(RwFrame *frame);
/* Macros for legacy support of old function names */
-#define RpHAnimSetHierarchy(frame, hierarchy) \
- RpHAnimFrameSetHierarchy(frame, hierarchy)
+#define RpHAnimSetHierarchy(frame,hierarchy) \
+ RpHAnimFrameSetHierarchy(frame,hierarchy)
#define RpHAnimGetHierarchy(frame) RpHAnimFrameGetHierarchy(frame)
-extern RwBool
-RpHAnimHierarchySetKeyFrameCallBacks(RpHAnimHierarchy *hierarchy,
- RwInt32 keyFrameTypeID);
-
-extern RwBool
-RpHAnimHierarchySetCurrentAnim(RpHAnimHierarchy *hierarchy,
- RpHAnimAnimation *anim);
-
-extern RwBool
-RpHAnimHierarchySetCurrentAnimTime(RpHAnimHierarchy *hierarchy,
- RwReal time);
-
-extern RwBool
-RpHAnimHierarchySubAnimTime(RpHAnimHierarchy *hierarchy,
- RwReal time);
-
-extern RwBool
-RpHAnimHierarchyStdKeyFrameAddAnimTime(RpHAnimHierarchy *hierarchy,
- RwReal time);
-
-extern RwBool
-RpHAnimHierarchyAddAnimTime(RpHAnimHierarchy *hierarchy,
- RwReal time);
-
-extern RpHAnimHierarchy *
-RpHAnimHierarchySetAnimCallBack(RpHAnimHierarchy *hierarchy,
- RpHAnimHierarchyCallBack callBack,
- RwReal time,
- void *data );
-
-extern RpHAnimHierarchy *
-RpHAnimHierarchySetAnimLoopCallBack(RpHAnimHierarchy *hierarchy,
- RpHAnimHierarchyCallBack callBack,
- void *data );
-
extern RwMatrix *
RpHAnimHierarchyGetMatrixArray(RpHAnimHierarchy *hierarchy);
@@ -665,209 +375,267 @@ extern RwInt32
RpHAnimIDGetIndex(RpHAnimHierarchy *hierarchy,
RwInt32 ID);
-/* Animations */
-
-extern RpHAnimAnimation *
-RpHAnimAnimationCreate(RwInt32 typeID,
- RwInt32 numFrames,
- RwInt32 flags,
- RwReal duration);
-
-extern RpHAnimAnimation *
-RpHAnimAnimationDestroy(RpHAnimAnimation *animation);
+/* Plugin support */
-#ifdef RWDEBUG
+extern RwBool
+RpHAnimPluginAttach(void);
-extern RwInt32
-RpHAnimAnimationGetTypeID(RpHAnimAnimation *animation);
+/* Hanim keyframe functions */
-#else /* RWDEBUG */
+extern void
+RpHAnimKeyFrameApply(void *matrix,
+ void *voidIFrame);
-#define RpHAnimAnimationGetTypeID(animation) \
- (animation->interpInfo->typeID)
+extern void
+RpHAnimKeyFrameBlend(void *voidOut,
+ void *voidIn1,
+ void *voidIn2,
+ RwReal alpha);
-#endif /* RWDEBUG */
+extern void
+RpHAnimKeyFrameInterpolate(void *voidOut,
+ void *voidIn1,
+ void *voidIn2,
+ RwReal time);
-extern RpHAnimAnimation *
-RpHAnimAnimationRead(const RwChar * filename);
+extern void
+RpHAnimKeyFrameAdd(void *voidOut,
+ void *voidIn1,
+ void *voidIn2);
-extern RwBool
-RpHAnimAnimationWrite(RpHAnimAnimation *animation,
- const RwChar * filename);
+extern void
+RpHAnimKeyFrameMulRecip(void *voidFrame,
+ void *voidStart);
-extern RpHAnimAnimation *
-RpHAnimAnimationStreamRead(RwStream *stream);
+extern RtAnimAnimation *
+RpHAnimKeyFrameStreamRead(RwStream *stream,
+ RtAnimAnimation *animation);
extern RwBool
-RpHAnimAnimationStreamWrite(RpHAnimAnimation *animation,
- RwStream *stream);
+RpHAnimKeyFrameStreamWrite(RtAnimAnimation *animation,
+ RwStream *stream);
extern RwInt32
-RpHAnimAnimationStreamGetSize(RpHAnimAnimation *animation);
+RpHAnimKeyFrameStreamGetSize(RtAnimAnimation *animation);
-extern RwBool
-RpHAnimAnimationMakeDelta(RpHAnimAnimation *animation,
- RwInt32 numNodes,
- RwReal time);
-
-/* Plugin support */
+/* Access to RwFrame ID's */
extern RwBool
-RpHAnimPluginAttach(void);
+RpHAnimFrameSetID(RwFrame *frame,
+ RwInt32 id);
-/* Overloadable keyframe functions */
+extern RwInt32
+RpHAnimFrameGetID(RwFrame *frame);
-#define RpHAnimFrameToMatrixMacro(hierarchy, matrix, iFrame) \
-MACRO_START \
-{ \
- const RpHAnimKeyFrameToMatrixCallBack keyFrameToMatrixCB = \
- (hierarchy)->keyFrameToMatrixCB; \
- \
- if (RpHAnimStdKeyFrameToMatrix == keyFrameToMatrixCB) \
- { \
- RpHAnimStdKeyFrameToMatrixMacro((matrix), (iFrame)); \
- } \
- else \
- { \
- keyFrameToMatrixCB((matrix), (iFrame)); \
- } \
-} \
-MACRO_STOP
+/*
+ * Utility Functions
+ */
+#define RpHAnimHierarchySetCurrentAnimMacro(hierarchy,anim)\
+ RtAnimInterpolatorSetCurrentAnim((hierarchy)->currentAnim,anim)
-#define RpHAnimFrameInterpolateMacro(hierarchy, out, in1, in2, time) \
-MACRO_START \
-{ \
- (hierarchy)->keyFrameInterpolateCB((out), (in1), (in2), (time)); \
-} \
-MACRO_STOP
+#define RpHAnimHierarchyGetCurrentAnimMacro(hierarchy)\
+ RtAnimInterpolatorGetCurrentAnim((hierarchy)->currentAnim)
-#define RpHAnimFrameBlendMacro(hierarchy, out, in1, in2, fAlpha) \
-MACRO_START \
-{ \
- (hierarchy)->keyFrameBlendCB((out), (in1), (in2), (fAlpha)); \
-} \
-MACRO_STOP
+#define RpHAnimHierarchySetCurrentAnimTimeMacro(hierarchy,time)\
+ RtAnimInterpolatorSetCurrentTime((hierarchy)->currentAnim,time)
-#define RpHAnimFrameAddTogetherMacro(hierarchy, out, in1, in2) \
-MACRO_START \
-{ \
- (hierarchy)->keyFrameAddCB((out), (in1), (in2)); \
-} \
-MACRO_STOP
+#define RpHAnimHierarchyAddAnimTimeMacro(hierarchy,time)\
+ RtAnimInterpolatorAddAnimTime((hierarchy)->currentAnim,time)
-#ifdef RWDEBUG
-void
-RpHAnimFrameInterpolate(RpHAnimHierarchy *hierarchy,
- void *out, void *in1,
- void *in2, RwReal time);
+#define RpHAnimHierarchySubAnimTimeMacro(hierarchy,time)\
+ RtAnimInterpolatorSubAnimTime((hierarchy)->currentAnim,time)
-void
-RpHAnimFrameBlend(RpHAnimHierarchy *hierarchy,
- void *out,
- void *in1,
- void *in2,
- RwReal alpha);
+#define RpHAnimHierarchySetKeyFrameCallBacksMacro(hierarchy,keyFrameTypeID) \
+ RtAnimInterpolatorSetKeyFrameCallBacks((hierarchy)->currentAnim,\
+ keyFrameTypeID)
-void
-RpHAnimFrameToMatrix(RpHAnimHierarchy *hierarchy,
- RwMatrix *matrix, void *iFrame);
+#define RpHAnimHierarchyBlendMacro(outHierarchy,inHierarchy1,inHierarchy2,alpha)\
+ RtAnimInterpolatorBlend((outHierarchy)->currentAnim,\
+ (inHierarchy1)->currentAnim,\
+ (inHierarchy2)->currentAnim,\
+ alpha)
-void
-RpHAnimFrameAddTogether(RpHAnimHierarchy *hierarchy,
- void *out, void *in1, void *in2);
+#define RpHAnimHierarchyAddTogetherMacro(outHierarchy,inHierarchy1,inHierarchy2)\
+ RtAnimInterpolatorAddTogether((outHierarchy)->currentAnim,\
+ (inHierarchy1)->currentAnim,\
+ (inHierarchy2)->currentAnim)
-#else /* RWDEBUG */
-#define RpHAnimFrameToMatrix(hierarchy, matrix, iFrame) \
- RpHAnimFrameToMatrixMacro(hierarchy, matrix, iFrame)
+#define RpHAnimHierarchySetAnimCallBackMacro(hierarchy,callBack,time,data)\
+ RtAnimInterpolatorSetAnimCallBack((hierarchy)->currentAnim,callBack,time,data)
-#define RpHAnimFrameInterpolate(hierarchy, out, in1, in2, time) \
- RpHAnimFrameInterpolateMacro(hierarchy, out, in1, in2, time)
+#define RpHAnimHierarchySetAnimLoopCallBackMacro(hierarchy,callBack,data)\
+ RtAnimInterpolatorSetAnimLoopCallBack((hierarchy)->currentAnim,callBack,data)
-#define RpHAnimFrameBlend(hierarchy, out, in1, in2, alpha) \
- RpHAnimFrameBlendMacro(hierarchy, out, in1, in2, alpha)
+#define RpHAnimHierarchyBlendSubHierarchyMacro(outHierarchy,inHierarchy1,inHierarchy2,alpha)\
+ RtAnimInterpolatorBlendSubInterpolator((outHierarchy)->currentAnim,(inHierarchy1)->currentAnim,(inHierarchy2)->currentAnim,alpha)
-#define RpHAnimFrameAddTogether(hierarchy, out, in1, in2) \
- RpHAnimFrameAddTogetherMacro(hierarchy, out, in1, in2)
+#define RpHAnimHierarchyAddSubHierarchyMacro(outHierarchy,mainHierarchy,subHierarchy)\
+ RtAnimInterpolatorAddSubInterpolator((outHierarchy)->currentAnim,(mainHierarchy)->currentAnim,(subHierarchy)->currentAnim)
-#endif /* RWDEBUG */
-
-/* Standard keyframe functions */
+#define RpHAnimHierarchyCopyMacro(outHierarchy,inHierarchy)\
+ RtAnimInterpolatorCopy((outHierarchy)->currentAnim,(inHierarchy)->currentAnim)
-extern void
-RpHAnimStdKeyFrameToMatrix(RwMatrix *matrix,
- void * voidIFrame);
-extern void
-RpHAnimStdKeyFrameBlend(void *voidOut,
- void *voidIn1,
- void *voidIn2,
- RwReal alpha);
-extern void
-RpHAnimStdKeyFrameInterpolate(void *voidOut,
- void *voidIn1,
- void *voidIn2,
- RwReal time);
+#ifdef RWDEBUG
+extern RwBool
+RpHAnimHierarchySetCurrentAnim(RpHAnimHierarchy *hierarchy,
+ RtAnimAnimation *anim);
-extern void
-RpHAnimStdKeyFrameAdd(void *voidOut,
- void *voidIn1,
- void *voidIn2);
+extern RtAnimAnimation *
+RpHAnimHierarchyGetCurrentAnim(RpHAnimHierarchy *hierarchy);
-extern void
-RpHAnimStdKeyFrameMulRecip(void *voidFrame,
- void *voidStart);
+extern RwBool
+RpHAnimHierarchySetCurrentAnimTime(RpHAnimHierarchy *hierarchy,
+ RwReal time);
-extern RpHAnimAnimation *
-RpHAnimStdKeyFrameStreamRead(RwStream *stream,
- RpHAnimAnimation *animation);
+extern RwBool
+RpHAnimHierarchyAddAnimTime(RpHAnimHierarchy *hierarchy,
+ RwReal time);
extern RwBool
-RpHAnimStdKeyFrameStreamWrite(RpHAnimAnimation *animation,
- RwStream *stream);
+RpHAnimHierarchySubAnimTime(RpHAnimHierarchy *hierarchy,
+ RwReal time);
-extern RwInt32
-RpHAnimStdKeyFrameStreamGetSize(RpHAnimAnimation *animation);
+extern RwBool
+RpHAnimHierarchySetKeyFrameCallBacks(RpHAnimHierarchy *hierarchy,
+ RwInt32 keyFrameTypeID);
-/* Hierarchy blending/combination functions */
+extern void
+RpHAnimHierarchySetAnimCallBack(RpHAnimHierarchy *hierarchy,
+ RtAnimCallBack callBack,
+ RwReal time,
+ void *data);
extern RwBool
RpHAnimHierarchyBlend(RpHAnimHierarchy *outHierarchy,
RpHAnimHierarchy *inHierarchy1,
RpHAnimHierarchy *inHierarchy2,
RwReal alpha);
+
extern RwBool
RpHAnimHierarchyAddTogether(RpHAnimHierarchy *outHierarchy,
RpHAnimHierarchy *inHierarchy1,
RpHAnimHierarchy *inHierarchy2);
+extern void
+RpHAnimHierarchySetAnimLoopCallBack(RpHAnimHierarchy *hierarchy,
+ RtAnimCallBack callBack,
+ void *data);
extern RwBool
RpHAnimHierarchyBlendSubHierarchy(RpHAnimHierarchy *outHierarchy,
- RpHAnimHierarchy *inHierarchy1,
- RpHAnimHierarchy *inHierarchy2,
- RwReal alpha);
+ RpHAnimHierarchy *inHierarchy1,
+ RpHAnimHierarchy *inHierarchy2,
+ RwReal alpha);
extern RwBool
RpHAnimHierarchyAddSubHierarchy(RpHAnimHierarchy *outHierarchy,
- RpHAnimHierarchy *mainHierarchy,
- RpHAnimHierarchy *subHierarchy);
-
+ RpHAnimHierarchy *mainHierarchy1,
+ RpHAnimHierarchy *subHierarchy2);
extern RwBool
RpHAnimHierarchyCopy(RpHAnimHierarchy *outHierarchy,
RpHAnimHierarchy *inHierarchy);
-/* Access to RwFrame ID's */
+#else
-extern RwBool
-RpHAnimFrameSetID(RwFrame *frame,
- RwInt32 id);
+#define RpHAnimHierarchySetCurrentAnim(hierarchy,anim) \
+ RpHAnimHierarchySetCurrentAnimMacro((hierarchy),(anim))
-extern RwInt32
-RpHAnimFrameGetID(RwFrame *frame);
+#define RpHAnimHierarchyGetCurrentAnim(hierarchy) \
+ RpHAnimHierarchyGetCurrentAnimMacro((hierarchy))
+
+#define RpHAnimHierarchySetCurrentAnimTime(hierarchy,time) \
+ RpHAnimHierarchySetCurrentAnimTimeMacro((hierarchy),(time))
+
+#define RpHAnimHierarchyAddAnimTime(hierarchy,time) \
+ RpHAnimHierarchyAddAnimTimeMacro((hierarchy),(time))
+
+#define RpHAnimHierarchySubAnimTime(hierarchy,time) \
+ RpHAnimHierarchySubAnimTimeMacro((hierarchy),(time))
+
+#define RpHAnimHierarchySetKeyFrameCallBacks(hierarchy,keyFrameTypeID) \
+ RpHAnimHierarchySetKeyFrameCallBacksMacro((hierarchy),(keyFrameTypeID))
+
+#define RpHAnimHierarchyBlend(outHierarchy,inHierarchy1,inHierarchy2,alpha) \
+ RpHAnimHierarchyBlendMacro((outHierarchy),(inHierarchy1),(inHierarchy2),(alpha))
+
+#define RpHAnimHierarchyAddTogether(outHierarchy,inHierarchy1,inHierarchy2) \
+ RpHAnimHierarchyAddTogetherMacro((outHierarchy),(inHierarchy1),(inHierarchy2))
+
+#define RpHAnimHierarchySetAnimCallBack(hierarchy,callBack,time,data)\
+ RpHAnimHierarchySetAnimCallBackMacro((hierarchy),(callBack),(time),(data))
+
+#define RpHAnimHierarchySetAnimLoopCallBack(hierarchy,callBack,data)\
+ RpHAnimHierarchySetAnimLoopCallBackMacro((hierarchy),(callBack),(data))
+
+#define RpHAnimHierarchyBlendSubHierarchy(outHierarchy,inHierarchy1,inHierarchy2,alpha)\
+ RpHAnimHierarchyBlendSubHierarchyMacro((outHierarchy),(inHierarchy1),(inHierarchy2),(alpha))
+
+#define RpHAnimHierarchyAddSubHierarchy(outHierarchy,mainHierarchy,subHierarchy)\
+ RpHAnimHierarchyAddSubHierarchyMacro((outHierarchy),(mainHierarchy),(subHierarchy))
+
+#define RpHAnimHierarchyCopy(outHierarchy,inHierarchy)\
+ RpHAnimHierarchyCopyMacro((outHierarchy),(inHierarchy))
+
+#endif /* RWDEBUG */
#ifdef __cplusplus
}
#endif /* __cplusplus */
+/* Legacy TypeDef */
+
+
+typedef RtAnimAnimation RpHAnimAnimation;
+typedef RpHAnimKeyFrame RpHAnimStdKeyFrame;
+
+/* Legacy Macros */
+
+
+/* Animations */
+
+
+#define RpHAnimAnimationCreate(typeID,numFrames,flags,duration)\
+ RtAnimAnimationCreate((typeID),(numFrames),(flags),(duration))
+
+
+#define RpHAnimAnimationDestroy(animation)\
+ RtAnimAnimationDestroy((animation))
+
+#define RpHAnimAnimationGetTypeID(animation)\
+ RtAnimAnimationGetTypeID((animation))
+
+
+#define RpHAnimAnimationRead(filename)\
+ RtAnimAnimationRead((filename))
+
+
+#define RpHAnimAnimationWrite(animation,filename)\
+ RtAnimAnimationWrite((animation),(filename))
+
+
+#define RpHAnimAnimationStreamRead(stream)\
+ RtAnimAnimationStreamRead((stream))
+
+
+#define RpHAnimAnimationStreamWrite(animation,stream)\
+ RtAnimAnimationStreamWrite((animation),(stream))
+
+
+#define RpHAnimAnimationStreamGetSize(animation)\
+ RtAnimAnimationStreamGetSize((animation))
+
+
+#define RpHAnimAnimationMakeDelta(animation,numNodes,time)\
+ RtAnimAnimationMakeDelta((animation),(numNodes),(time))
+
+
+/* Animation Interpolator */
+
+#define RpHAnimHierarchyStdKeyFrameAddAnimTime(hierarchy,time)\
+ RpHAnimHierarchyHAnimKeyFrameAddAnimTime((hierarchy),(time))
+
+#define RpHAnimHierarchyHAnimKeyFrameAddAnimTime(hierarchy,time)\
+ RpHAnimHierarchyAddAnimTime((hierarchy),(time))
#endif /* RPHANIM_H */
diff --git a/sdk/rwsdk/include/d3d8/rphanim.rpe b/sdk/rwsdk/include/d3d8/rphanim.rpe
index c60f8591..1c05d0e9 100644
--- a/sdk/rwsdk/include/d3d8/rphanim.rpe
+++ b/sdk/rwsdk/include/d3d8/rphanim.rpe
@@ -160,481 +160,10 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
enum e_rwdb_CriterionHANIM
{
-E_RP_HANIM_INTERP_IDINUSE,
-
-E_RP_HANIM_INTERP_BLOCKFULL,
-
-E_RP_HANIM_INTERP_IDUNKNOWN,
e_rwdb_CriterionHANIMLAST = RWFORCEENUMSIZEINT
};
diff --git a/sdk/rwsdk/include/d3d8/rplodatm.h b/sdk/rwsdk/include/d3d8/rplodatm.h
index d4583338..4e9c8648 100644
--- a/sdk/rwsdk/include/d3d8/rplodatm.h
+++ b/sdk/rwsdk/include/d3d8/rplodatm.h
@@ -34,7 +34,7 @@
/**
* \defgroup rplodatm RpLODAtomic
- * \ingroup rpplugin
+ * \ingroup scenemanagement
*
* Level of Detail Management Plugin for RenderWare Graphics.
*/
@@ -72,6 +72,9 @@ extern "C"
{
#endif /* __cplusplus */
+ extern void
+ RpLODAtomicCacheSetFreeListCreateParams( RwInt32 blockSize, RwInt32 numBlocksToPrealloc );
+
extern RwBool
RpLODAtomicPluginAttach( void );
diff --git a/sdk/rwsdk/include/d3d8/rplodatm.rpe b/sdk/rwsdk/include/d3d8/rplodatm.rpe
index 649bc3bc..a5764cfc 100644
--- a/sdk/rwsdk/include/d3d8/rplodatm.rpe
+++ b/sdk/rwsdk/include/d3d8/rplodatm.rpe
@@ -163,472 +163,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
enum e_rwdb_CriterionLODATM
{
diff --git a/sdk/rwsdk/include/d3d8/rplogo.h b/sdk/rwsdk/include/d3d8/rplogo.h
index ed527a29..a46823ac 100644
--- a/sdk/rwsdk/include/d3d8/rplogo.h
+++ b/sdk/rwsdk/include/d3d8/rplogo.h
@@ -33,7 +33,7 @@
/**
* \defgroup rplogo RpLogo
- * \ingroup rpplugin
+ * \ingroup 2dtools
*
* Logo Plugin for RenderWare Graphics.
*/
diff --git a/sdk/rwsdk/include/d3d8/rplogo.rpe b/sdk/rwsdk/include/d3d8/rplogo.rpe
index f37b6920..a7f66565 100644
--- a/sdk/rwsdk/include/d3d8/rplogo.rpe
+++ b/sdk/rwsdk/include/d3d8/rplogo.rpe
@@ -160,472 +160,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
enum e_rwdb_CriterionLogo
{
diff --git a/sdk/rwsdk/include/d3d8/rpltmap.h b/sdk/rwsdk/include/d3d8/rpltmap.h
index 5add9a26..18c91955 100644
--- a/sdk/rwsdk/include/d3d8/rpltmap.h
+++ b/sdk/rwsdk/include/d3d8/rpltmap.h
@@ -1,7 +1,7 @@
/**
* \defgroup rpltmap RpLtMap
- * \ingroup rpplugin
+ * \ingroup lighting
*
* Lightmap Plugin for RenderWare Graphics.
*/
@@ -17,6 +17,15 @@
#include "rpworld.h"
+/* Used during lightmap illumination (sliver triangles are skipped
+ * (their texels should be filled by dilate()), because their normals
+ * can't be accurately calculated) */
+#define rpLTMAPDEFAULTSLIVERAREATHRESHOLD (0.001f)
+
+/* Used during lightmap UV calculation (polySets may be
+ * joined on the basis of vertices with equal positions) */
+#define rpLTMAPDEFAULTVERTEXWELDTHRESHOLD (0.1f)
+
#define rpLTMAPDEFAULTLIGHTMAPSIZE 128
#define rpLTMAPMINLIGHTMAPSIZE 16
#define rpLTMAPMAXLIGHTMAPSIZE 512/*?? any better way of determining this ??*/
diff --git a/sdk/rwsdk/include/d3d8/rpltmap.rpe b/sdk/rwsdk/include/d3d8/rpltmap.rpe
index 413caf4c..6e58b62b 100644
--- a/sdk/rwsdk/include/d3d8/rpltmap.rpe
+++ b/sdk/rwsdk/include/d3d8/rpltmap.rpe
@@ -159,472 +159,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
enum e_rwdb_CriterionLTMAP
{
diff --git a/sdk/rwsdk/include/d3d8/rpmatfx.h b/sdk/rwsdk/include/d3d8/rpmatfx.h
index 9b091dd8..fb7ade45 100644
--- a/sdk/rwsdk/include/d3d8/rpmatfx.h
+++ b/sdk/rwsdk/include/d3d8/rpmatfx.h
@@ -17,7 +17,7 @@
/**
* \defgroup rpmatfx RpMatFX
- * \ingroup rpplugin
+ * \ingroup materials
*
* Material Effects Plugin for RenderWare Graphics.
*/
@@ -58,6 +58,10 @@ extern "C"
#endif /* __cplusplus */
/*--- Plugin functions ------------------------------------------------------*/
+extern void
+RpMatFXMaterialDataSetFreeListCreateParams( RwInt32 blockSize,
+ RwInt32 numBlocksToPrealloc );
+
extern RwBool
RpMatFXPluginAttach( void );
diff --git a/sdk/rwsdk/include/d3d8/rpmatfx.rpe b/sdk/rwsdk/include/d3d8/rpmatfx.rpe
index bbc588e3..ba83d96a 100644
--- a/sdk/rwsdk/include/d3d8/rpmatfx.rpe
+++ b/sdk/rwsdk/include/d3d8/rpmatfx.rpe
@@ -159,472 +159,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
enum e_rwdb_CriterionMATERIALEFFECTS
{
diff --git a/sdk/rwsdk/include/d3d8/rpmipkl.h b/sdk/rwsdk/include/d3d8/rpmipkl.h
index 5b8f7e51..82ad7f03 100644
--- a/sdk/rwsdk/include/d3d8/rpmipkl.h
+++ b/sdk/rwsdk/include/d3d8/rpmipkl.h
@@ -7,9 +7,9 @@
/**
* \defgroup rpmipkl RpMipmapKL
- * \ingroup rpplugin
+ * \ingroup mipmapping
*
- * PS2/MipMap KL Value Plugin for RenderWare Graphics.
+ * PlayStation 2 / MipMap KL Value Plugin for RenderWare Graphics.
*/
#include <rwcore.h>
@@ -19,6 +19,28 @@ extern "C"
{
#endif
+#if (defined(SKY2_DRVMODEL_H)) || (defined(NULLSKY_DRVMODEL_H))
+
+#define RpMipmapKLTextureSetDefaultK RpSkyTextureSetDefaultMipmapK
+
+#define RpMipmapKLTextureSetDefaultL RpSkyTextureSetDefaultMipmapL
+
+#define RpMipmapKLTextureGetDefaultK RpSkyTextureGetDefaultMipmapK
+
+#define RpMipmapKLTextureGetDefaultL RpSkyTextureGetDefaultMipmapL
+
+#define RpMipmapKLTextureSetK RpSkyTextureSetMipmapK
+
+#define RpMipmapKLTextureSetL RpSkyTextureSetMipmapL
+
+#define RpMipmapKLTextureGetK RpSkyTextureGetMipmapK
+
+#define RpMipmapKLTextureGetL RpSkyTextureGetMipmapL
+
+#define RpMipmapKLPluginAttach() (TRUE)
+
+#else /* (defined(SKY2_DRVMODEL_H)) || (defined(NULLSKY_DRVMODEL_H)) */
+
extern RwReal RpMipmapKLTextureSetDefaultK(RwReal val);
extern RwUInt32 RpMipmapKLTextureSetDefaultL(RwUInt32 val);
extern RwReal RpMipmapKLTextureGetDefaultK(void);
@@ -31,6 +53,8 @@ extern RwUInt32 RpMipmapKLTextureGetL(RwTexture *tex);
extern RwBool RpMipmapKLPluginAttach(void);
+#endif /* (defined(SKY2_DRVMODEL_H)) || (defined(NULLSKY_DRVMODEL_H)) */
+
#ifdef __cplusplus
}
#endif
diff --git a/sdk/rwsdk/include/d3d8/rpmipkl.rpe b/sdk/rwsdk/include/d3d8/rpmipkl.rpe
index 5216ec9c..0464081f 100644
--- a/sdk/rwsdk/include/d3d8/rpmipkl.rpe
+++ b/sdk/rwsdk/include/d3d8/rpmipkl.rpe
@@ -160,472 +160,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
enum e_rwdb_CriterionLabel
{
diff --git a/sdk/rwsdk/include/d3d8/rpmorph.h b/sdk/rwsdk/include/d3d8/rpmorph.h
index 4177fba8..52ea70df 100644
--- a/sdk/rwsdk/include/d3d8/rpmorph.h
+++ b/sdk/rwsdk/include/d3d8/rpmorph.h
@@ -38,7 +38,7 @@
/**
* \defgroup rpmorph RpMorph
- * \ingroup rpplugin
+ * \ingroup morphing
*
* Morphing Plugin for RenderWare Graphics.
*/
@@ -76,7 +76,6 @@ struct RpMorphInterpolator
/**
* \ingroup rpmorph
- * \typedef RpMorphGeometryCallBack
* This is the callback function supplied to \ref RpMorphGeometrySetCallBack
* and returned from \ref RpMorphGeometryGetCallBack.
* The supplied function will be passed a pointer to the geometry's parent atomic,
diff --git a/sdk/rwsdk/include/d3d8/rpmorph.rpe b/sdk/rwsdk/include/d3d8/rpmorph.rpe
index 14b13076..47834a81 100644
--- a/sdk/rwsdk/include/d3d8/rpmorph.rpe
+++ b/sdk/rwsdk/include/d3d8/rpmorph.rpe
@@ -159,472 +159,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
enum e_rwdb_CriterionMorph
{
diff --git a/sdk/rwsdk/include/d3d8/rppatch.h b/sdk/rwsdk/include/d3d8/rppatch.h
index eb80663f..0b54fb1b 100644
--- a/sdk/rwsdk/include/d3d8/rppatch.h
+++ b/sdk/rwsdk/include/d3d8/rppatch.h
@@ -4,7 +4,7 @@
/**
* \defgroup rppatch RpPatch
- * \ingroup rpplugin
+ * \ingroup bezierpatches
*
* Bezier patch library
*
@@ -124,7 +124,7 @@
* \ingroup rppatch
* \ref RpPatchMeshFlag
* When creating a \ref RpPatchMesh, these flags can be OR'ed together to
- * specify the format along with the \ref rpPATCHMESHTEXCOORDSETS (n) macro
+ * specify the format along with the \ref rpPATCHMESHTEXCOORDSETS(num) macro
* to specify the number of texture coordinate sets required.
*
* \see RpPatchMeshCreate
@@ -220,7 +220,7 @@ typedef struct RpPatchMesh RpPatchMesh;
* The patch mesh should be unlocked with \ref RpPatchMeshUnlock before it is
* added to an \ref RpAtomic with \ref RpPatchAtomicSetPatchMesh.
*
- * \see RpPatchMesDefinition
+ * \see RpPatchMeshDefinition
*/
struct RpPatchMesh
{
@@ -278,7 +278,7 @@ struct RpPatchLODRange
/**
* \ingroup rppatch
- * \typedef RpPatchLODUserData
+ * \ref RpPatchLODUserData
* typedef for the user data passed to the \ref RpPatchLODCallBack
* function which calculates the atomics' LOD.
*
@@ -289,9 +289,14 @@ typedef void *RpPatchLODUserData;
/**
* \ingroup rppatch
- * \typedef RpPatchLODCallBack
+ * \ref RpPatchLODCallBack
* typedef for the patch atomic LOD calculation function.
*
+ * \param atomic
+ * \param userData
+ *
+ * \return
+ *
* \see RpPatchAtomicSetPatchLODCallBack
* \see RpPatchAtomicGetPatchLODCallBack
*/
@@ -309,6 +314,13 @@ extern "C"
/*---------------------------------------------------------------------------*
*- Plugin functions -*
*---------------------------------------------------------------------------*/
+extern void
+RpPatchGeometrySetFreeListCreateParams( RwInt32 blockSize, RwInt32 numBlocksToPrealloc );
+
+extern void
+RpPatchAtomicSetFreeListCreateParams( RwInt32 blockSize, RwInt32 numBlocksToPrealloc );
+
+
extern RwBool
RpPatchPluginAttach(void);
diff --git a/sdk/rwsdk/include/d3d8/rppatch.rpe b/sdk/rwsdk/include/d3d8/rppatch.rpe
index 6d433990..85dca470 100644
--- a/sdk/rwsdk/include/d3d8/rppatch.rpe
+++ b/sdk/rwsdk/include/d3d8/rppatch.rpe
@@ -159,472 +159,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
enum e_rwdb_CriterionPATCH
{
diff --git a/sdk/rwsdk/include/d3d8/rpprtstd.h b/sdk/rwsdk/include/d3d8/rpprtstd.h
index ad1b87f7..ba0bf1d6 100644
--- a/sdk/rwsdk/include/d3d8/rpprtstd.h
+++ b/sdk/rwsdk/include/d3d8/rpprtstd.h
@@ -28,7 +28,7 @@
/**
* \defgroup rpprtstd RpPrtStd
- * \ingroup rpplugin
+ * \ingroup particles
*
* Particle Animation Plugin for RenderWare Graphics.
*/
@@ -52,7 +52,7 @@
-#define PRTSTD_RSRAND2(_seed) (((RwReal)((RwReal) (_seed) * PRTSTD_SRAND_IMAX) * \
+#define PRTSTD_2RSRAND2(_seed) (((RwReal)((RwReal) (_seed) * PRTSTD_SRAND_IMAX) * \
(RwReal)1.0))
/**
@@ -84,6 +84,8 @@ enum RpPrtStdEmitterFlags
rpPRTSTDEMITTERFLAGUPDATEPARTICLE = 0x00000020, /**< This indicated if the emitter's particles are updated. */
rpPRTSTDEMITTERFLAGRENDER = 0x00000040, /**< This indicates if the emitter is rendered. */
rpPRTSTDEMITTERFLAGRENDERPARTICLE = 0x00000080, /**< This indicates if the emitter's particles are rendered. */
+ rpPRTSTDEMITTERFLAGNOBUFFERSWAP = 0x00000100, /**< Internal usage */
+ rpPRTSTDEMITTERFLAGSTREAMREAD = 0x00000200, /**< Internal usage */
rpPRTSTDEMITTERFLAGFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
};
@@ -109,15 +111,12 @@ enum RpPrtStdParticleCallBackCode
rpPRTSTDPARTICLECALLBACKRENDER, /**< Particle render callback */
rpPRTSTDPARTICLECALLBACKCREATE, /**< Particle create callback */
rpPRTSTDPARTICLECALLBACKDESTROY, /**< Particle destroy callback */
- rpPRTSTDPARTICLECALLBACKSTREAMREAD, /**< Particle stream input callback */
- rpPRTSTDPARTICLECALLBACKSTREAMWRITE, /**< Particle stream outout callback */
- rpPRTSTDPARTICLECALLBACKSTREAMGETSIZE, /**< Particle stream get size callback */
rpPRTSTDPARTICLECALLBACKFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
};
typedef enum RpPrtStdParticleCallBackCode RpPrtStdParticleCallBackCode;
-#define rpPRTSTDEMITTERCALLBACKMAX 10
+#define rpPRTSTDEMITTERCALLBACKMAX 11
/**
* \ingroup rpprtstd
@@ -137,6 +136,7 @@ enum RpPrtStdEmitterCallBackCode
rpPRTSTDEMITTERCALLBACKSTREAMREAD, /**< Emitter stream input callback */
rpPRTSTDEMITTERCALLBACKSTREAMWRITE, /**< Emitter stream output callback */
rpPRTSTDEMITTERCALLBACKSTREAMGETSIZE, /**< Emitter stream get size callback */
+ rpPRTSTDEMITTERCALLBACKCLONE, /**< Emitter clone callback */
rpPRTSTDEMITTERCALLBACKFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
};
@@ -154,7 +154,7 @@ typedef struct RpPrtStdEmitter RWALIGN(RpPrtStdEmitter, rwMATRIXALIGNMENT);
/**
* \ingroup rpprtstd
- * \typedef RpPrtStdEmitterCallBack
+ * \ref RpPrtStdEmitterCallBack
* \ref RpPrtStdEmitterCallBack represents the function called for processing
* a \ref RpPrtStdEmitter. There can several types of the functions, each performing a
* specific task defined by \ref RpPrtStdEmitterCallBackCode.
@@ -172,7 +172,6 @@ typedef RpPrtStdEmitter *
typedef struct RpPrtStdParticleBatch RWALIGN(RpPrtStdParticleBatch, rwMATRIXALIGNMENT);
/**
* \ingroup rpprtstd
- * \typedef RpPrtStdParticleCallBack
* \ref RpPrtStdParticleCallBack represents the function called for processing
* a \ref RpPrtStdParticleBatch. There can be several types of the functions, each
* performing a specific task defined by \ref RpPrtStdParticleCallBackCode.
@@ -189,7 +188,6 @@ typedef RpPrtStdParticleBatch *
/**
* \ingroup rpprtstd
- * \typedef RpPrtStdEmitterCallBackArray
* \ref RpPrtStdEmitterCallBackArray represents a set of callback functions for
* processing a \ref RpPrtStdEmitter. All the functions are of the type \ref
* RpPrtStdEmitterCallBack.
@@ -201,7 +199,6 @@ typedef RpPrtStdEmitterCallBack
/**
* \ingroup rpprtstd
- * \typedef RpPrtStdParticleCallBackArray
* \ref RpPrtStdParticleCallBackArray represents a set of callback functions for
* processing a \ref RpPrtStdParticleBatch. All the functions are of the type \ref
* RpPrtStdParticleCallBack.
@@ -221,7 +218,6 @@ typedef RpPrtStdParticleCallBack
typedef struct RpPrtStdEmitterClass RpPrtStdEmitterClass;
/**
* \ingroup rpprtstd
- * \typedef RpPrtStdEClassSetupCallBack
* \ref RpPrtStdEClassSetupCallBack represents the function called for setting up an
* emitter class's set of callback function. The callback function is called
* after an emitter class is streamed in.
@@ -237,7 +233,6 @@ typedef RpPrtStdEmitterClass *
typedef struct RpPrtStdParticleClass RpPrtStdParticleClass;
/**
* \ingroup rpprtstd
- * \typedef RpPrtStdPClassSetupCallBack
* \ref RpPrtStdPClassSetupCallBack represents the function called for setting up an
* emitter class's set of callback function. The callback function is called
* after an emitter class is streamed in.
@@ -273,6 +268,7 @@ struct RpPrtStdPropertyTable
RpPrtStdPropertyTable *next; /**< Internal usage */
RwInt32 id; /**< Property table's id */
+ RwInt32 refCount; /**< Reference count. Internal usage */
RwInt32 numProp; /**< Number of properties in the table */
RwInt32 maxProp; /**< Internal usage */
@@ -295,6 +291,7 @@ struct RpPrtStdEmitterClass
RpPrtStdEmitterClass *next; /**< Internal usage */
RwInt32 id; /**< Emitter class's id */
+ RwInt32 refCount; /**< Reference count. Internal usage */
RwInt32 objSize; /**< Size of the emitter */
RpPrtStdPropertyTable *propTab; /**< Reference to a table of emitter properties */
@@ -316,6 +313,7 @@ struct RpPrtStdParticleClass
RpPrtStdParticleClass *next; /**< Internal usage */
RwInt32 id; /**< Particle class's id */
+ RwInt32 refCount; /**< Reference count. Internal usage */
RwInt32 objSize; /**< Size of a particle */
RpPrtStdPropertyTable *propTab; /**< Reference to a table of particle properties */
@@ -403,7 +401,6 @@ struct RpPrtStdEmitter
#define rpPRTSTDPROPERTYCODEEMITTERSTANDARD 1
#define rpPRTSTDPROPERTYCODEEMITTERPRTCOLOR 2
#define rpPRTSTDPROPERTYCODEEMITTERPRTTEXCOORDS 3
-#define rpPRTSTDPROPERTYCODEEMITTERPRTANIMFRAME 4
#define rpPRTSTDPROPERTYCODEEMITTERPRTSIZE 5
#define rpPRTSTDPROPERTYCODEEMITTERPTANK 6
#define rpPRTSTDPROPERTYCODEEMITTERPRTVELOCITY 7
@@ -414,7 +411,6 @@ struct RpPrtStdEmitter
#define rpPRTSTDEMITTERDATAFLAGSTANDARD 0x00000001
#define rpPRTSTDEMITTERDATAFLAGPRTCOLOR 0x00000002
#define rpPRTSTDEMITTERDATAFLAGPRTTEXCOORDS 0x00000004
-#define rpPRTSTDEMITTERDATAFLAGPRTANIMFRAME 0x00000008
#define rpPRTSTDEMITTERDATAFLAGPRTSIZE 0x00000010
#define rpPRTSTDEMITTERDATAFLAGPTANK 0x00000020
#define rpPRTSTDEMITTERDATAFLAGPRTMATRIX 0x00000040
@@ -436,7 +432,7 @@ typedef struct RpPrtStdEmitterStandard RpPrtStdEmitterStandard;
* particles. Once an emitter has reached its maximum number of particles, no further particles are
* emitted until some of the existing particles have died.
*
- * Most properties have a bias value to vary the property value. This uses the seed field
+ * Most properties have a bias value to vary the property's value. This uses the seed field
* to give a degreee of randomness.
*/
struct RpPrtStdEmitterStandard
@@ -522,15 +518,6 @@ struct RpPrtStdEmitterPrtTexCoords
prtEndUV1Bias; /**< Particle end bottom right texcoords bias */
};
-typedef struct RpPrtStdEmitterPrtAnimFrame RpPrtStdEmitterPrtAnimFrame;
-
-struct RpPrtStdEmitterPrtAnimFrame
-{
- RwInt32 prtNumFrames;
-
- RwTexCoords *prtAnimFrameTexCoords;
-};
-
typedef struct RpPrtStdEmitterPrtSize RpPrtStdEmitterPrtSize;
/**
@@ -550,18 +537,47 @@ struct RpPrtStdEmitterPrtSize
prtEndSizeBias; /**< Particle end size bias */
};
+
+/**
+ * \ingroup rpprtstd
+ * A set of flag settings for use in the \ref RpPrtStdEmitterPrtMatrix flag
+ */
+enum RpPrtStdEmitterPrtMatrixFlags
+{
+ rpPRTSTDEMITTERPRTMTXFLAGSCNSMTX = 0x00000001, /**< Apply the prtCnsMtx matrix to
+ * each particle if set */
+ RPPRTSTDEMITTERPRTMTXFLAGSFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
+};
+
+typedef enum RpPrtStdEmitterPrtMatrixFlags RpPrtStdEmitterPrtMatrixFlags;
+
typedef struct RpPrtStdEmitterPrtMatrix RWALIGN(RpPrtStdEmitterPrtMatrix, rwMATRIXALIGNMENT);
+/**
+ * \ingroup rpprtstd
+ * \struct RpPrtStdEmitterPrtMatrix
+ *
+ * An optional structure to construct a matrix for each particle during emissions. A particle
+ * can be represented as a single matrix. This gives the particles an orientation rather than
+ * just a simple position.
+ *
+ * This allows transformation to be applied to the particles, such as rotation. If
+ * \ref rpPRTSTDEMITTERPRTMTXFLAGSCNSMTX is set in the flag, then the prtCnsMatrix is applied to each
+ * particle during particle update.
+ *
+ * If this structure is not present, then it assumes the particles will have just a position
+ * property.
+ */
struct RpPrtStdEmitterPrtMatrix
{
- RwMatrix prtCnsMtx;
+ RwMatrix prtCnsMtx; /**< Transformation matrix to be applied to each particle */
- RwV3d prtPosMtxAt,
- prtPosMtxAtBias;
- RwV3d prtPosMtxUp,
- prtPosMtxUpBias;
+ RwV3d prtPosMtxAt, /**< Particle initial look at vector */
+ prtPosMtxAtBias; /**< Particle initial look at vector bias */
+ RwV3d prtPosMtxUp, /**< Particle initial up vector. */
+ prtPosMtxUpBias; /**< Particle initial up vector bias */
- RwInt32 flags;
+ RwInt32 flags; /**< Particle matrix flag. See \ref RpPrtStdEmitterPrtMatrixFlags */
};
/************************************************************************
@@ -584,18 +600,42 @@ enum RpPrtStdPTankPropertyCode
typedef enum RpPrtStdPTankPropertyCode RpPrtStdPTankPropertyCode;
typedef struct RpPrtStdEmitterPTank RpPrtStdEmitterPTank;
+
+/**
+ * \ingroup rpprtstd
+ * \struct RpPrtStdEmitterPTank
+ *
+ * A structure for storing the data required to create a RpPTank for use
+ * with the emitter. The structure allows the user to create a RpPTank
+ * manually.
+ */
struct RpPrtStdEmitterPTank
{
- RwUInt32 dataFlags,
- platFlags,
- numPrt,
- maxPrt,
- updateFlags,
- emitFlags;
- RpAtomic *pTank;
- RwChar **dataInPtrs,
- **dataOutPtrs;
- RwInt32 *dataStride;
+ RwUInt32 dataFlags, /**< Data flag used in RpPTank creation. See
+ * \ref RpPTankAtomicCreate */
+ platFlags, /**< Platform flag used in RpPTank creation. See
+ * \ref RpPTankAtomicCreate */
+ numPrt, /**< An integer representing the current number of active
+ * particles */
+ maxPrt, /**< An integer representing the maxiumum number of particles
+ * stored in the RpPTank */
+ updateFlags, /**< A flag representing the properties to be updated by
+ * the particle emiiter during update. A user may select to
+ * update some properties manually by unsetting the relevant
+ * bits in the flag.
+ * The flag settings are the same as \ref RpPTankDataFlags */
+ emitFlags; /**< A flag representing the properties to be initialised
+ * by the particle emitter during particles emission. A user
+ * may select to initialise some properties manually by
+ * unsetting the relevant bits in the flag.
+ * The flag settings are the same as \ref RpPTankDataFlags */
+ RpAtomic *pTank; /**< Pointer to the RpPTank */
+ RwChar **dataInPtrs, /**< Internal usage */
+ **dataOutPtrs; /**< Internal usage */
+ RwInt32 *dataStride; /**< Internal usage */
+ RwUInt32 strSrcBlend; /**< Internal usage */
+ RwUInt32 strDstBlend; /**< Internal usage */
+ RwBool strVtxABlend; /**< Internal usage */
};
/************************************************************************
@@ -608,7 +648,6 @@ struct RpPrtStdEmitterPTank
#define rpPRTSTDPROPERTYCODEPARTICLEPOSITION 1
#define rpPRTSTDPROPERTYCODEPARTICLECOLOR 2
#define rpPRTSTDPROPERTYCODEPARTICLETEXCOORDS 3
-#define rpPRTSTDPROPERTYCODEPARTICLEANIMFRAME 4
#define rpPRTSTDPROPERTYCODEPARTICLESIZE 5
#define rpPRTSTDPROPERTYCODEPARTICLEVELOCITY 6
#define rpPRTSTDPROPERTYCODEPARTICLEMATRIX 7
@@ -619,7 +658,6 @@ struct RpPrtStdEmitterPTank
#define rpPRTSTDPARTICLEDATAFLAGPOSITION 0x00000002
#define rpPRTSTDPARTICLEDATAFLAGCOLOR 0x00000004
#define rpPRTSTDPARTICLEDATAFLAGTEXCOORDS 0x00000008
-#define rpPRTSTDPARTICLEDATAFLAGANIMFRAME 0x00000010
#define rpPRTSTDPARTICLEDATAFLAGSIZE 0x00000020
#define rpPRTSTDPARTICLEDATAFLAGVELOCITY 0x00000040
#define rpPRTSTDPARTICLEDATAFLAGMATRIX 0x00000080
@@ -675,15 +713,6 @@ struct RpPrtStdParticleTexCoords
deltaUV1; /**< Particle's bottom right texcoords rate of change */
};
-typedef struct RpPrtStdParticleAnimFrame RpPrtStdParticleAnimFrame;
-
-struct RpPrtStdParticleAnimFrame
-{
- RwInt32 frame;
-
- RwReal delta;
-};
-
typedef struct RpPrtStdParticleSize RpPrtStdParticleSize;
/**
@@ -714,10 +743,13 @@ extern "C"
/************************************************************************/
extern RwBool
-RpParticleStandardPluginAttach( void );
+RpPrtStdPluginAttach( void );
/************************************************************************/
+extern RwBool
+RpAtomicIsParticleEmitter(RpAtomic *atomic);
+
extern RpAtomic *
RpPrtStdAtomicCreate(RpPrtStdEmitterClass *eClass, void *data);
@@ -750,6 +782,9 @@ extern RwBool
RpPrtStdEmitterDestroy(RpPrtStdEmitter *emt);
extern RpPrtStdEmitter *
+RpPrtStdEmitterClone(RpPrtStdEmitter *emt);
+
+extern RpPrtStdEmitter *
RpPrtStdEmitterForAllParticleBatch(RpPrtStdEmitter *emt,
RpPrtStdParticleCallBack callback,
void * data);
@@ -835,7 +870,6 @@ RpPrtStdPropTabStreamWrite(RpPrtStdPropertyTable *eClass,
extern RwInt32
RpPrtStdPropTabStreamGetSize(RpPrtStdPropertyTable *eClass);
-
/************************************************************************/
extern RwBool
@@ -941,6 +975,11 @@ RpPrtStdGlobalDataStreamWrite(RwStream *stream);
extern RwInt32
RpPrtStdGlobalDataStreamGetSize( void );
+extern void
+RpPrtStdGlobalDataSetStreamEmbedded( RwBool embedded );
+
+extern RwBool
+RpPrtStdGlobalDataGetStreamEmbedded( void );
/************************************************************************/
@@ -964,10 +1003,18 @@ RpPrtStdEmitterStdEmitCB(RpAtomic *atomic,
RpPrtStdEmitter *emt, void *data);
extern RpPrtStdEmitter *
+RpPrtStdEmitterStdCloneCB(RpAtomic *atomic,
+ RpPrtStdEmitter *emt, void *data);
+
+extern RpPrtStdEmitter *
RpPrtStdEmitterStdCreateCB(RpAtomic *atomic,
RpPrtStdEmitter *emt, void *data);
extern RpPrtStdEmitter *
+RpPrtStdEmitterStdDestroyCB(RpAtomic *atomic,
+ RpPrtStdEmitter *emt, void *data);
+
+extern RpPrtStdEmitter *
RpPrtStdEmitterStdBeginUpdateCB(RpAtomic *atomic,
RpPrtStdEmitter *emt, void *data);
diff --git a/sdk/rwsdk/include/d3d8/rpprtstd.rpe b/sdk/rwsdk/include/d3d8/rpprtstd.rpe
index df860d45..d628c6c0 100644
--- a/sdk/rwsdk/include/d3d8/rpprtstd.rpe
+++ b/sdk/rwsdk/include/d3d8/rpprtstd.rpe
@@ -160,480 +160,14 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-enum e_rwdb_CriterionParticleStandard
+enum e_rwdb_CriterionPrtStandard
{
- e_rwdb_CriterionParticleStandardLAST = RWFORCEENUMSIZEINT
+ e_rwdb_CriterionPrtStandardLAST = RWFORCEENUMSIZEINT
};
-typedef enum e_rwdb_CriterionParticleStandard e_rwdb_CriterionParticleStandard;
+typedef enum e_rwdb_CriterionPrtStandard e_rwdb_CriterionPrtStandard;
diff --git a/sdk/rwsdk/include/d3d8/rpptank.h b/sdk/rwsdk/include/d3d8/rpptank.h
index 20931f21..d4c1116d 100644
--- a/sdk/rwsdk/include/d3d8/rpptank.h
+++ b/sdk/rwsdk/include/d3d8/rpptank.h
@@ -13,12 +13,13 @@
/**
* \defgroup rpptank RpPTank
- * \ingroup rpplugin
+ * \ingroup particles
*
* PTank Plugin for RenderWare.
*/
/*--- Include files ---*/
+
#include <string.h>
#include "rwcore.h"
@@ -139,7 +140,7 @@ enum RpPTankInstanceFlags
rpPTANKIFLAGCENTER = ((int)0x01000000), /**<Center position changed*/
/* free = ((int)0x04000000), */
/* free = ((int)0x08000000), */
-/* free = ((int)0x10000000), */
+ rpPTANKIFLAGALPHABLENDING = ((int)0x10000000), /**<Internal Use*/
rpPTANKIFLAGALL = ((int)0xFFFFFFFF),
RPPTANKINSTANCEFLAGSFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
@@ -244,20 +245,22 @@ extern const RwInt32 datasize[];
/**
* \ingroup rpptank
- * \typedef rpptankAllocCallBack
+ * \ref RpPTankAllocCallBack
+ *
* ...
*/
-typedef void *(* rpPTankAllocCallBack)(RpPTankData *ptankGlobal,
+typedef void *(* RpPTankAllocCallBack)(RpPTankData *ptankGlobal,
RwInt32 maxPCount,
RwUInt32 dataFlags,
RwUInt32 platFlags);
/**
* \ingroup rpptank
- * \typedef rpPTankCreateCallBack
+ * \ref RpPTankCreateCallBack
+ *
* ...
*/
-typedef RwBool (* rpPTankCreateCallBack)(RpAtomic *atomic,
+typedef RwBool (* RpPTankCreateCallBack)(RpAtomic *atomic,
RpPTankData *ptankGlobal,
RwInt32 maxPCount,
RwUInt32 dataFlags,
@@ -265,37 +268,37 @@ typedef RwBool (* rpPTankCreateCallBack)(RpAtomic *atomic,
/**
* \ingroup rpptank
- * \typedef rpPTankInstanceCallBack
+ * \ref RpPTankInstanceCallBack
* ...
*/
-typedef RwBool (* rpPTankInstanceCallBack)(RpAtomic *atomic,
+typedef RwBool (* RpPTankInstanceCallBack)(RpAtomic *atomic,
RpPTankData *ptankGlobal,
RwInt32 actPCount,
RwUInt32 instFlags);
/**
* \ingroup rpptank
- * \typedef rpPTankRenderCallBack
+ * \ref RpPTankRenderCallBack
* ...
*/
-typedef RwBool (* rpPTankRenderCallBack)(RpAtomic *atomic,
+typedef RwBool (* RpPTankRenderCallBack)(RpAtomic *atomic,
RpPTankData *ptankGlobal,
RwInt32 actPCount);
-typedef struct rpPTankCallBacks rpPTankCallBacks;
+typedef struct RpPTankCallBacks RpPTankCallBacks;
-struct rpPTankCallBacks
+struct RpPTankCallBacks
{
- rpPTankAllocCallBack alloc;
- rpPTankCreateCallBack create;
- rpPTankInstanceCallBack instance;
- rpPTankRenderCallBack render;
+ RpPTankAllocCallBack alloc;
+ RpPTankCreateCallBack create;
+ RpPTankInstanceCallBack instance;
+ RpPTankRenderCallBack render;
};
/* private typedefs */
-typedef struct rpPTANKInstanceSetupData rpPTANKInstanceSetupData;
+typedef struct RpPTANKInstanceSetupData RpPTANKInstanceSetupData;
-struct rpPTANKInstanceSetupData
+struct RpPTANKInstanceSetupData
{
RwBool instancePositions;
RwBool instanceUVs;
@@ -312,27 +315,27 @@ struct rpPTANKInstanceSetupData
};
-typedef void (* rpPTankGENInstancePosCallback)(
+typedef void (* RpPTankGENInstancePosCallback)(
RpPTankLockStruct *dstCluster,
RwV3d *right,
RwV3d *up,
RwInt32 pCount,
RpPTankData *ptankGlobal);
-typedef void (* rpPTankGENInstanceCallback)(
+typedef void (* RpPTankGENInstanceCallback)(
RpPTankLockStruct *dstCluster,
RwInt32 pCount,
RpPTankData *ptankGlobal);
-typedef void (* rpPTankGENInstanceSetupCallback)(
- rpPTANKInstanceSetupData *data,
+typedef void (* RpPTankGENInstanceSetupCallback)(
+ RpPTANKInstanceSetupData *data,
RpAtomic *atomic,
RpPTankData *ptankGlobal,
RwInt32 actPCount,
RwUInt32 instFlags);
-typedef void (* rpPTankGENInstanceEndingCallback)(
- rpPTANKInstanceSetupData *data,
+typedef void (* RpPTankGENInstanceEndingCallback)(
+ RpPTANKInstanceSetupData *data,
RpAtomic *atomic,
RpPTankData *ptankGlobal,
RwInt32 actPCount,
@@ -351,15 +354,15 @@ struct RpPTankAtomicExtPrv
/* Rendering callback */
RpAtomicCallBackRender defaultRenderCB;
- rpPTankCallBacks ptankCallBacks;
+ RpPTankCallBacks ptankCallBacks;
/* Instancing CallBacks */
- rpPTankGENInstanceSetupCallback insSetupCB;
- rpPTankGENInstancePosCallback insPosCB;
- rpPTankGENInstanceCallback insUVCB;
- rpPTankGENInstanceCallback insColorsCB;
- rpPTankGENInstanceCallback insNormalsCB;
- rpPTankGENInstanceEndingCallback insEndingCB;
+ RpPTankGENInstanceSetupCallback insSetupCB;
+ RpPTankGENInstancePosCallback insPosCB;
+ RpPTankGENInstanceCallback insUVCB;
+ RpPTankGENInstanceCallback insColorsCB;
+ RpPTankGENInstanceCallback insNormalsCB;
+ RpPTankGENInstanceEndingCallback insEndingCB;
RwUInt32 lockFlags;
RwUInt32 instFlags;
@@ -390,7 +393,6 @@ extern RwInt32 _rpPTankGlobalsOffset; /* Offset in RwEngine */
#endif
-
extern RwBool
RpPTankPluginAttach(void);
@@ -523,7 +525,7 @@ MACRO_START\
RPATOMICPTANKPLUGINDATA(atm_)->publicData.cColor = *col_;\
if( RpGeometryGetMaterial(RpAtomicGetGeometry(atm_),0) )\
{\
- RpMaterialSetColor(\
+ (void)RpMaterialSetColor(\
RpGeometryGetMaterial(RpAtomicGetGeometry(atm_),0),\
&RPATOMICPTANKPLUGINDATA(atm_)->publicData.cColor);\
}\
@@ -759,6 +761,14 @@ extern RpAtomic *
RpPTankAtomicUnlock(RpAtomic *atomic);
+/*
+ * Stealth functions *********************************************************
+ */
+RpAtomic*
+_rpPTankAtomicCreateCustom(RwInt32 maxParticleNum,
+ RwUInt32 dataFlags, RwUInt32 platFlags,
+ RpPTankCallBacks *callbacks);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
@@ -767,6 +777,41 @@ RpPTankAtomicUnlock(RpAtomic *atomic);
/*---- start: c:/daily/rwsdk/plugin/ptank/d3d8/ptankplatform.h----*/
+/**
+ * \defgroup rpptankd3d8 D3D8
+ * \ingroup rpptank
+ *
+ * D3D8 specific documentation.
+ */
+
+/**
+ * \ingroup rpptankd3d8
+ * \par D3D8 specific data flags
+ *
+ * <ul>
+ * <li> rpPTANKD3D8FLAGSUSEPOINTSPRITES selects the D3D8 optimized pipeline. At the
+ * moment, this pipeline use point sprites when the hardware supports them,
+ * which don't allow use of all the PTank flags. Only the following flags are
+ * supported when using the D3D8 optimized pipes:
+ *
+ * <ul>
+ * <li> rpPTANKDFLAGPOSITION
+ * <li> rpPTANKDFLAGNORMAL
+ * <li> rpPTANKDFLAGSIZE (if the hardware supports the D3DFVF_PSIZE vertex format flag)
+ * <li> rpPTANKDFLAGCOLOR
+ * <li> rpPTANKDFLAGUSECENTER
+ * <li> rpPTANKDFLAGARRAY
+ * <li> rpPTANKDFLAGSTRUCTURE
+ * </ul>
+ *
+ * The texture coordinates are generated by the hardware and can't be specified.
+ * </ul>
+ *
+ * If the hardware does not support point sprites, the default pipeline is used
+ * instead.
+ *
+ */
+
enum RpPTankD3D8Flags
{
rpPTANKD3D8FLAGSUSEPOINTSPRITES = 0x00000001,
@@ -774,6 +819,8 @@ enum RpPTankD3D8Flags
rpPTANKD3D8FLAGFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
};
+typedef enum RpPTankD3D8Flags RpPTankD3D8Flags;
+
/*---- end: c:/daily/rwsdk/plugin/ptank/d3d8/ptankplatform.h----*/
#endif /* RPPTANK_H */
diff --git a/sdk/rwsdk/include/d3d8/rpptank.rpe b/sdk/rwsdk/include/d3d8/rpptank.rpe
index 485b5dd8..2a9b45d3 100644
--- a/sdk/rwsdk/include/d3d8/rpptank.rpe
+++ b/sdk/rwsdk/include/d3d8/rpptank.rpe
@@ -146,472 +146,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/sdk/rwsdk/include/d3d8/rppvs.h b/sdk/rwsdk/include/d3d8/rppvs.h
index 29fc2343..08738933 100644
--- a/sdk/rwsdk/include/d3d8/rppvs.h
+++ b/sdk/rwsdk/include/d3d8/rppvs.h
@@ -32,7 +32,7 @@
/**
* \defgroup rppvs RpPVS
- * \ingroup rpplugin
+ * \ingroup pvs
*
* Geometric Potentially Visible Set Plugin for RenderWare Graphics.
*/
@@ -122,11 +122,14 @@ typedef RpWorldSector *(*RpPVSCallBack) (RpWorldSector * worldSector,
#define RpPVSCallback RpPVSCallBack
typedef struct _RpPVSCallBack _RpPVSCallBack;
+
+#if (!defined(DOXYGEN))
struct _RpPVSCallBack
{
RpPVSCallBack callback;
void *data;
};
+#endif /* (!defined(DOXYGEN)) */
enum _rpPVSPartitionId
{
@@ -145,6 +148,7 @@ typedef struct _rpPVSPolyList *_rpPVSPolyListPtr;
typedef struct _rpPVSPoly _rpPVSPoly;
typedef struct _rpPVSPoly *_rpPVSPolyPtr;
+#if (!defined(DOXYGEN))
typedef struct _rpPVSPlaneEq _rpPVSPlaneEq;
struct _rpPVSPlaneEq
{
@@ -158,12 +162,13 @@ struct _rpPVSPlaneEq
_rpPVSPartitionId lastresult; /* temp: stores result of last polygon wrt this plane */
};
-typedef struct
+typedef struct RwV3i RwV3i;
+struct RwV3i
{
RwInt32 x;
RwInt32 y;
RwInt32 z;
-}RwV3i;
+};
typedef struct _rpPVSPolyRecord _rpPVSPolyRecord;
struct _rpPVSPolyRecord
@@ -205,47 +210,45 @@ struct _rpPVSPolyList
};
typedef struct RpPVS RpPVS;
+
struct RpPVS
{
- RwInt32 sectorID; /* Id of the sector */
- RwInt32 vismaplength; /* Length of vismap */
- RwInt32 sampleKey; /* Currently unused, for future use */
+ RwInt32 sectorID;
+ RwInt32 vismaplength;
+ RwInt32 sampleKey;
RpPVSVisMap *vismap;
- _rpPVSPolyListPtr sectailpoly; /* Pointer to last polygon in polygons list that is in this sector */
+ _rpPVSPolyListPtr sectailpoly;
+ _rpPVSPartitionId potential;
- _rpPVSPartitionId potential; /* temp: is sector in out or split from current shadow volume - for heirarchical clip */
RwUInt32 numpols;
- RwBBox sbox; /* Bounding box of the sector */
- RwBBox gbox; /* Bounding box of the geometry of the sector */
- RwReal diagonal; /* Diagonal size of bounding box of the sector */
- RwV3d centre; /* Centre of the sector */
- RwInt32 axessig[3]; /* sampling significance of the axes of the gbox */
+ RwBBox sbox;
+ RwBBox gbox;
+ RwReal diagonal;
+ RwV3d centre;
+ RwInt32 axessig[3];
};
typedef struct RpPVSCache RpPVSCache;
struct RpPVSCache
{
- RwBool processed; /* flag to indicate exisiting PVS data for the world */
- RwBool formatted; /* flag to indicate exisiting intermediate polygonal data for PVS generation */
+ RwBool processed;
+ RwBool formatted;
+ RwInt32 NumWorldSectors;
- /* stats collection */
RwInt32 ptotal;
RwInt32 paccept;
- /* pipeline hooking */
RwBool hooked;
- /* used during vismap allocation */
RwUInt32 nextID;
RwInt32 viscount;
- /* Used during construction */
RpPVSProgressCallBack progressCallBack;
- _rpPVSPolyListPtr polygons; /* A copy of the input data set of all world polygons */
+ _rpPVSPolyListPtr polygons;
RpWorldSectorCallBackRender renderCallBack;
};
@@ -255,23 +258,23 @@ struct RpPVSGlobalVars
{
RpWorld *World;
- RwInt32 worldOffset; /* Offset into global data */
- RwInt32 sectorOffset; /* Offset into global data */
+ RwInt32 worldOffset;
+ RwInt32 sectorOffset;
- RwBool collis; /* Collision detection */
- RwBool bfc; /* Backface culling */
+ RwBool collis;
+ RwBool bfc;
- RwInt32 NumWorldSectors;
RwInt32 progress_count;
RwReal diagonal;
RwReal gran;
- RwInt32 InSector; /* Current sector id */
- RwV3d ViewPos; /* Current view pos */
- RpPVS *CurrPVS; /* Current PVS sector */
+ RwInt32 InSector;
+ RwV3d ViewPos;
+ RpPVS *CurrPVS;
};
+#endif /* (!defined(DOXYGEN)) */
/****************************************************************************
diff --git a/sdk/rwsdk/include/d3d8/rppvs.rpe b/sdk/rwsdk/include/d3d8/rppvs.rpe
index dc060cff..62c983b0 100644
--- a/sdk/rwsdk/include/d3d8/rppvs.rpe
+++ b/sdk/rwsdk/include/d3d8/rppvs.rpe
@@ -161,472 +161,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
enum e_rwdb_CriterionGPVS
{
diff --git a/sdk/rwsdk/include/d3d8/rprandom.h b/sdk/rwsdk/include/d3d8/rprandom.h
index 8690c69a..aebbfed9 100644
--- a/sdk/rwsdk/include/d3d8/rprandom.h
+++ b/sdk/rwsdk/include/d3d8/rprandom.h
@@ -28,7 +28,7 @@
/**
* \defgroup rprandom RpRandom
- * \ingroup rpplugin
+ * \ingroup mathtools
*
* Random Number Generation Plugin for RenderWare Graphics.
*/
diff --git a/sdk/rwsdk/include/d3d8/rprandom.rpe b/sdk/rwsdk/include/d3d8/rprandom.rpe
index 8e267eee..d3fe964b 100644
--- a/sdk/rwsdk/include/d3d8/rprandom.rpe
+++ b/sdk/rwsdk/include/d3d8/rprandom.rpe
@@ -159,472 +159,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
enum e_rwdb_CriterionRandom
{
diff --git a/sdk/rwsdk/include/d3d8/rpskin.h b/sdk/rwsdk/include/d3d8/rpskin.h
index df446c1b..8a6ea204 100644
--- a/sdk/rwsdk/include/d3d8/rpskin.h
+++ b/sdk/rwsdk/include/d3d8/rpskin.h
@@ -4,7 +4,7 @@
/**
* \defgroup rpskin RpSkin
- * \ingroup rpplugin
+ * \ingroup skinning
*
* Skin Plugin for RenderWare Graphics.
*/
@@ -48,7 +48,7 @@ struct RwMatrixWeights
/**
* \ingroup rpskin
- * \typedef RpSkin
+ * \struct RpSkin
*
* Skin object. This should be considered an opaque type.
* Use the RpSkin API functions to access.
@@ -69,6 +69,9 @@ extern "C"
/*---------------------------------------------------------------------------*
*- Plugin functions -*
*---------------------------------------------------------------------------*/
+extern void RpSkinSetFreeListCreateParams(
+ RwInt32 blockSize, RwInt32 numBlocksToPrealloc );
+
extern RwBool
RpSkinPluginAttach(void);
@@ -114,6 +117,9 @@ RpSkinGetVertexBoneIndices( RpSkin *skin );
extern const RwMatrix *
RpSkinGetSkinToBoneMatrices( RpSkin *skin );
+extern RwBool
+RpSkinIsSplit( RpSkin *skin );
+
/*---------------------------------------------------------------------------*
*- Skin pipeline -*
*---------------------------------------------------------------------------*/
@@ -131,7 +137,6 @@ enum RpSkinType
rpSKINTYPEGENERIC = 1, /**<Generic skin rendering. */
rpSKINTYPEMATFX = 2, /**<Material effects skin rendering. */
rpSKINTYPETOON = 3, /**<Toon skin rendering. */
- rpSKINTYPEMATFXTOON = 4, /**<Note Toon + MatFX on same object NOT currently supported */
rpSKINTYPEFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
};
typedef enum RpSkinType RpSkinType;
@@ -143,6 +148,32 @@ RpSkinAtomicSetType( RpAtomic *atomic,
extern RpSkinType
RpSkinAtomicGetType( RpAtomic *atomic );
+/*---------------------------------------------------------------------------*
+ *- Internal API -*
+ *---------------------------------------------------------------------------*/
+extern RpGeometry *
+_rpSkinInitialize(RpGeometry *geometry);
+
+extern RpGeometry *
+_rpSkinDeinitialize(RpGeometry *geometry);
+
+extern RwUInt8 *
+_rpSkinGetMeshBoneRemapIndices( RpSkin *skin );
+
+extern RwUInt8 *
+_rpSkinGetMeshBoneRLECount( RpSkin *skin );
+
+extern RwUInt8 *
+_rpSkinGetMeshBoneRLE( RpSkin *skin );
+
+extern RpSkin *
+_rpSkinSplitDataCreate( RpSkin *skin, RwUInt32 boneLimit,
+ RwUInt32 numMatrices, RwUInt32 numMeshes,
+ RwUInt32 numRLE );
+
+extern RwBool
+_rpSkinSplitDataDestroy( RpSkin *skin );
+
/*---------------------------------------------------------------------------*/
#ifdef __cplusplus
@@ -167,6 +198,29 @@ RpSkinAtomicGetType( RpAtomic *atomic );
* D3D8 skin pipeline extension.
*/
+/**
+ * \defgroup rpskind3d8features Features
+ * \ingroup rpskind3d8
+ *
+ * D3D8 skin pipeline features.
+ */
+
+/**
+ * \defgroup rpskind3d8restrictions Restrictions
+ * \ingroup rpskind3d8
+ *
+ * D3D8 skin pipeline restrictions.
+ */
+
+/**
+ * \defgroup rpskinbonelimit Bone limit
+ * \ingroup rpskind3d8restrictions
+ *
+ * \par Bone limit
+ * The bone limit is 256 as skinning is performed on the CPU.
+ *
+ */
+
/*===========================================================================*
*--- D3D8 Defines -----------------------------------------------------------*
diff --git a/sdk/rwsdk/include/d3d8/rpskin.rpe b/sdk/rwsdk/include/d3d8/rpskin.rpe
index 57cecd5e..02d7e162 100644
--- a/sdk/rwsdk/include/d3d8/rpskin.rpe
+++ b/sdk/rwsdk/include/d3d8/rpskin.rpe
@@ -159,472 +159,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
enum e_rwdb_CriterionSKIN
{
diff --git a/sdk/rwsdk/include/d3d8/rpspline.h b/sdk/rwsdk/include/d3d8/rpspline.h
index 53fd8484..df3a21d9 100644
--- a/sdk/rwsdk/include/d3d8/rpspline.h
+++ b/sdk/rwsdk/include/d3d8/rpspline.h
@@ -39,7 +39,7 @@
/**
* \defgroup rpspline RpSpline
- * \ingroup rpplugin
+ * \ingroup mathtools
*
* Spline Plugin for RenderWare Graphics.
*/
diff --git a/sdk/rwsdk/include/d3d8/rpspline.rpe b/sdk/rwsdk/include/d3d8/rpspline.rpe
index 27670751..55748bdd 100644
--- a/sdk/rwsdk/include/d3d8/rpspline.rpe
+++ b/sdk/rwsdk/include/d3d8/rpspline.rpe
@@ -159,472 +159,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
enum e_rwdb_CriterionSpline
{
diff --git a/sdk/rwsdk/include/d3d8/rpstereo.h b/sdk/rwsdk/include/d3d8/rpstereo.h
deleted file mode 100644
index 5a8db912..00000000
--- a/sdk/rwsdk/include/d3d8/rpstereo.h
+++ /dev/null
@@ -1,141 +0,0 @@
-/*
- * Stereo camera plugin
- */
-
-/**********************************************************************
- *
- * File : rpstereo.h
- *
- * Abstract : Add Stereo Camera support to RenderWare
- *
- **********************************************************************
- *
- * This file is a product of Criterion Software Ltd.
- *
- * This file is provided as is with no warranties of any kind and is
- * provided without any obligation on Criterion Software Ltd. or
- * Canon Inc. to assist in its use or modification.
- *
- * Criterion Software Ltd. will not, under any
- * circumstances, be liable for any lost revenue or other damages arising
- * from the use of this file.
- *
- * Copyright (c) 1998 Criterion Software Ltd.
- * All Rights Reserved.
- *
- * RenderWare is a trademark of Canon Inc.
- *
- ************************************************************************/
-
-#ifndef RPSTEREO_H
-#define RPSTEREO_H
-
-/**
- * \defgroup rpstereo RpStereo
- * \ingroup rpplugin
- *
- * Stereo Camera Plugin for RenderWare Graphics.
- */
-
-/*--- Include files ---*/
-#include <rwcore.h>
-#include <rpworld.h>
-
-#include "rpstereo.rpe" /* automatically generated header file */
-
-/*--- Global Structures ---*/
-
-/* Supported Stereo Modes */
-
-/**
- * \ingroup rpstereo
- * \ref RpStereoCameraMode
- * Stereo camera mode enumeration.
- */
-enum RpStereoCameraMode
-{
- rpNASTEREOMODE = 0,
- rpSTEREOMONO, /**< Render as Mono camera - single
- * image
- */
- rpSTEREOLEFTRIGHT, /**< Vertical split screen. Left eye
- * image on left of screen. Right eye
- * image on right of screen.
- */
- rpSTEREORIGHTLEFT, /**< Vertical split screen. Right eye
- * image on left of screen. Left eye image
- * on right of screen.
- */
-
- rpSTEREOROTATE90, /**< As for rpSTEREOLEFTRIGHT - with
- * the images rotated inwards by 90 degrees
- */
- rpSTEREOINTERLACEDLEFTRIGHT, /**< Left and right eye images on
- * alternate scanlines. The left eye image
- * on the topmost line of the display.
- */
-
- rpSTEREOINTERLACEDRIGHTLEFT, /**< Left and right eye images on
- * alternate scanlines. The right eye
- * image is on the topmost line of the
- * display.
- */
- rpSTEREOLASTMODE,
- rpSTEREOCAMERAMODEFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
-};
-
-/*
- * typedef for stereo camera mode enumeration.
- */
-typedef enum RpStereoCameraMode RpStereoCameraMode;
-
-/*--- Constants ---*/
-
-/* These may be used to quickly adapt an existing application to a
- * stereo version.
- */
-
-#ifdef RPSTEREO_OVERLOAD
-#define RwCameraBeginUpdate RpStereoCameraBeginUpdate
-#define RwCameraEndUpdate RpStereoCameraEndUpdate
-#undef RpWorldRender
-#define RpWorldRender RpStereoWorldRender
-#undef RpClumpRender
-#define RpClumpRender RpStereoClumpRender
-#undef RpAtomicRender
-#define RpAtomicRender RpStereoAtomicRender
-#undef RpWorldSectorRender
-#define RpWorldSectorRender RpStereoWorldSectorRender
-#endif
-
-/*--- Plugin API Functions ---*/
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-RwBool RpStereoPluginAttach(void);
-
-RpWorld *RpStereoWorldRender(RpWorld *world);
-RpClump *RpStereoClumpRender(RpClump *clump);
-RpAtomic *RpStereoAtomicRender(RpAtomic *atomic);
-RpWorldSector *RpStereoWorldSectorRender(RpWorldSector *sector);
-
-RwCamera *RpStereoCameraBeginUpdate(RwCamera *camera);
-RwCamera *RpStereoCameraEndUpdate(RwCamera *stereoCam);
-
-RwReal RpStereoCameraGetSeparation(RwCamera *stereoCam);
-RwReal RpStereoCameraGetFocal(RwCamera *stereoCam);
-RpStereoCameraMode RpStereoCameraGetMode(RwCamera *stereoCam);
-
-RwCamera *RpStereoCameraSetSeparation(RwCamera *stereoCam, RwReal dist);
-RwCamera *RpStereoCameraSetFocal(RwCamera *stereoCam, RwReal focal);
-RwCamera *RpStereoCameraSetMode(RwCamera *stereoCam, RpStereoCameraMode newMode);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-#endif /* RPSTEREO_H */
-
diff --git a/sdk/rwsdk/include/d3d8/rpstereo.rpe b/sdk/rwsdk/include/d3d8/rpstereo.rpe
deleted file mode 100644
index b89dde2e..00000000
--- a/sdk/rwsdk/include/d3d8/rpstereo.rpe
+++ /dev/null
@@ -1,641 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-enum e_rwdb_CriterionStereo
-{
-
-
-E_RP_STEREO_INVMODE,
-
-E_RP_STEREO_INVFOCAL,
-
- e_rwdb_CriterionStereoLAST = RWFORCEENUMSIZEINT
-};
-
-typedef enum e_rwdb_CriterionStereo e_rwdb_CriterionStereo;
-
-
diff --git a/sdk/rwsdk/include/d3d8/rpusrdat.h b/sdk/rwsdk/include/d3d8/rpusrdat.h
index 3665e064..92a56e31 100644
--- a/sdk/rwsdk/include/d3d8/rpusrdat.h
+++ b/sdk/rwsdk/include/d3d8/rpusrdat.h
@@ -3,7 +3,7 @@
/**
* \defgroup rpuserdata RpUserData
- * \ingroup rpplugin
+ * \ingroup scenemanagement
*
* User Data Plugin for RenderWare Graphics.
*/
diff --git a/sdk/rwsdk/include/d3d8/rpusrdat.rpe b/sdk/rwsdk/include/d3d8/rpusrdat.rpe
index 31c37fd1..f5879a00 100644
--- a/sdk/rwsdk/include/d3d8/rpusrdat.rpe
+++ b/sdk/rwsdk/include/d3d8/rpusrdat.rpe
@@ -160,472 +160,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
enum e_rwdb_CriterionUserData
{
diff --git a/sdk/rwsdk/include/d3d8/rpworld.h b/sdk/rwsdk/include/d3d8/rpworld.h
index 21fdc31b..0d0489ce 100644
--- a/sdk/rwsdk/include/d3d8/rpworld.h
+++ b/sdk/rwsdk/include/d3d8/rpworld.h
@@ -22,7 +22,7 @@
/*************************************************************************
*
* Filename: <C:/daily/rwsdk/include/d3d8/rpworld.h>
- * Automatically Generated on: Wed Jul 10 10:45:01 2002
+ * Automatically Generated on: Thu Jan 23 11:06:24 2003
*
************************************************************************/
@@ -75,135 +75,32 @@ extern RxNodeDefinition *RxNodeDefinitionGetD3D8AtomicAllInOne(void);
extern "C"
{
#endif /* __cplusplus */
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-/*--- Automatically derived from: C:/daily/rwsdk/world/pipe/p2/nodeWorldSectorInstance.h ---*/
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-extern RxNodeDefinition *RxNodeDefinitionGetWorldSectorInstance(void);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-
-/*--- Automatically derived from: C:/daily/rwsdk/world/pipe/p2/nodeWorldSectorEnumerateLights.h ---*/
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-extern RxNodeDefinition *RxNodeDefinitionGetWorldSectorEnumerateLights(void);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-
-/*--- Automatically derived from: C:/daily/rwsdk/world/pipe/p2/nodePreLight.h ---*/
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-extern RxNodeDefinition *RxNodeDefinitionGetPreLight(void);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-
-/*--- Automatically derived from: C:/daily/rwsdk/world/pipe/p2/nodePostLight.h ---*/
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-extern RxNodeDefinition *RxNodeDefinitionGetPostLight(void);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-
-/*--- Automatically derived from: C:/daily/rwsdk/world/pipe/p2/nodeMaterialScatter.h ---*/
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-extern RxNodeDefinition *RxNodeDefinitionGetMaterialScatter(void);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-
-/*--- Automatically derived from: C:/daily/rwsdk/world/pipe/p2/nodeLight.h ---*/
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-extern RxNodeDefinition *RxNodeDefinitionGetLight(void);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-
-/*--- Automatically derived from: C:/daily/rwsdk/world/pipe/p2/nodeFastPathSplitter.h ---*/
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-extern RxNodeDefinition *RxNodeDefinitionGetFastPathSplitter(void);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
+extern void RwD3D8VertexBufferManagerChangeDefaultSize(RwUInt32 defaultSize);
-/*--- Automatically derived from: C:/daily/rwsdk/world/pipe/p2/nodeAtomicInstance.h ---*/
+extern RwBool _rxD3D8VertexBufferManagerCreate(RwUInt32 fvf,
+ RwUInt32 size,
+ void **vertexBuffer,
+ RwUInt32 *baseIndex);
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-extern RxNodeDefinition *RxNodeDefinitionGetAtomicInstance(void);
+extern void _rxD3D8VertexBufferManagerDestroy(RwUInt32 fvf,
+ RwUInt32 size,
+ void *vertexBuffer,
+ RwUInt32 baseIndex);
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-
-/*--- Automatically derived from: C:/daily/rwsdk/world/pipe/p2/nodeAtomicEnumerateLights.h ---*/
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
+extern RwBool _rxD3D8VertexBufferManagerCreateNoFVF(RwUInt32 stride,
+ RwUInt32 size,
+ void **vertexBuffer,
+ RwUInt32 *baseIndex);
-extern RxNodeDefinition *RxNodeDefinitionGetAtomicEnumerateLights(void);
+extern void _rxD3D8VertexBufferManagerDestroyNoFVF(RwUInt32 stride,
+ RwUInt32 size,
+ void *vertexBuffer,
+ RwUInt32 baseIndex);
#ifdef __cplusplus
}
-#endif /* __cplusplus */
-
+#endif /* __cplusplus */
/*--- Automatically derived from: c:/daily/rwsdk/world/bamateri.h ---*/
@@ -222,15 +119,17 @@ extern RxNodeDefinition *RxNodeDefinitionGetAtomicEnumerateLights(void);
typedef struct RpMaterialChunkInfo RpMaterialChunkInfo;
typedef struct RpMaterialChunkInfo _rpMaterial;
+#if (!defined(DOXYGEN))
struct RpMaterialChunkInfo
{
- RwInt32 flags; /**< Material flags - unused currently -
- for future expansion */
- RwRGBA color; /**< Colour of material. */
- RwInt32 unused; /**< Not used */
- RwBool textured; /**< Are we textured? */
- RwSurfaceProperties surfaceProps; /**< Surface properties */
+ RwInt32 flags; /* Material flags - unused currently -
+ * for future expansion */
+ RwRGBA color; /* Color of material. */
+ RwInt32 unused; /* Not used */
+ RwBool textured; /* Are we textured? */
+ RwSurfaceProperties surfaceProps;/* Surface properties */
};
+#endif /* (!defined(DOXYGEN)) */
#if (!defined(RwMaterialAssign))
#define RwMaterialAssign(_target, _source) \
@@ -238,8 +137,8 @@ struct RpMaterialChunkInfo
#endif /* (!defined(RwMaterialAssign)) */
/**
- * \ingroup rpworlddatatypes
- * \typedef RpMaterial
+ * \ingroup rpmaterial
+ * \struct RpMaterial
* Material object. This should be
* considered an opaque type. Use the RpMaterial API functions to access.
*/
@@ -258,9 +157,8 @@ struct RpMaterial
#endif /* (!defined(DOXYGEN)) */
/**
- * \ingroup rpworlddatatypes
- * \typedef RpMaterialCallBack
- \ref RpMaterialCallBack
+ * \ingroup rpmaterial
+ * \ref RpMaterialCallBack
* represents the function called from \ref RpGeometryForAllMaterials and
* \ref RpWorldForAllMaterials for all materials referenced by polygons in a
* given geometry. This function should return a pointer to the current
@@ -268,7 +166,7 @@ struct RpMaterial
* further callbacks on the materials.
*
* \param material Pointer to the current material
- * \param data Pointer to developer-defined data structure.
+ * \param data Pointer to developer-defined data structure.
*
* \return Pointer to the current material.
*/
@@ -346,6 +244,9 @@ extern "C"
#endif /* __cplusplus */
+extern void RpMaterialSetFreeListCreateParams( RwInt32 blockSize,
+ RwInt32 numBlocksToPrealloc );
+
/* Creating, destroying and referencing materials */
extern RpMaterial *RpMaterialCreate(void);
extern RwBool RpMaterialDestroy(RpMaterial *material);
@@ -388,6 +289,8 @@ extern RwInt32 RpMaterialRegisterPluginStream(RwUInt32 pluginID,
extern RwInt32 RpMaterialSetStreamAlwaysCallBack(
RwUInt32 pluginID,
RwPluginDataChunkAlwaysCallBack alwaysCB);
+extern RwInt32 RpMaterialSetStreamRightsCallBack(RwUInt32 pluginID,
+ RwPluginDataChunkRightsCallBack rightsCB);
extern RwInt32 RpMaterialGetPluginOffset(RwUInt32 pluginID);
extern RwBool RpMaterialValidatePlugins(const RpMaterial *material);
@@ -414,12 +317,15 @@ _rpMaterialChunkInfoRead(RwStream *stream,
*/
typedef struct RpMaterialList RpMaterialList;
+
+#if (!defined(DOXYGEN))
struct RpMaterialList
{
RpMaterial **materials;
RwInt32 numMaterials;
RwInt32 space;
};
+#endif /* (!defined(DOXYGEN)) */
/****************************************************************************
Function prototypes
@@ -531,16 +437,14 @@ extern RwModuleInfo meshModule;
Global types
*/
-/**
- * \ingroup rpworlddatatypes
- * \typedef RpMeshHeader
+/*
* typedef for header structure listing all meshes
* constituting a single RpGeometry or RpWorldSector
*/
typedef struct RpMeshHeader RpMeshHeader;
/**
- * \ingroup rpworlddatatypes
+ * \ingroup rpmesh
* \ref RpMeshHeaderFlags
* represents the different types of mesh.
* \see RpMeshHeader
@@ -549,18 +453,18 @@ enum RpMeshHeaderFlags
{
/* NOTE: trilists are denoted by absence of any other
* primtype flags, so be careful that you test:
- * (triListFlag == flags&triListFlag)
+ * (triListFlag == (flags&triListFlag))
* or:
- * (0 == flags&rpMESHHEADERPRIMMASK)
+ * (0 == (flags&rpMESHHEADERPRIMMASK))
* and not:
* (flags&triListFlag)
*/
rpMESHHEADERTRISTRIP = 0x0001, /**< Render as tristrips */
- rpMESHHEADERTRIFAN = 0x0002, /**< On PS2 these will be converted to trilists */
+ rpMESHHEADERTRIFAN = 0x0002, /**< On PlayStation 2 these will be converted to trilists */
rpMESHHEADERLINELIST = 0x0004, /**< Render as linelists */
- rpMESHHEADERPOLYLINE = 0x0008, /**< On PS2 these will be converted to linelists */
+ rpMESHHEADERPOLYLINE = 0x0008, /**< On PlayStation 2 these will be converted to linelists */
rpMESHHEADERPOINTLIST = 0x0010, /**< Pointlists are supported only if rendered by
- * custom pipelines; there is no default RenderWare
+ * custom pipelines; there is no default RenderWare
* way to render pointlists. */
rpMESHHEADERPRIMMASK = 0x00FF, /**< All bits reserved for specifying primitive type */
@@ -576,6 +480,8 @@ enum RpMeshHeaderFlags
typedef enum RpMeshHeaderFlags RpMeshHeaderFlags;
typedef struct rpMeshGlobals rpMeshGlobals;
+
+#if (!defined(DOXYGEN))
struct rpMeshGlobals
{
RwInt16 nextSerialNum;
@@ -583,11 +489,12 @@ struct rpMeshGlobals
RwUInt8 meshFlagsToPrimType[rpMESHHEADERPRIMTYPEOR];
RwUInt8 primTypeToMeshFlags[rwPRIMTYPEOR];
};
+#endif /* (!defined(DOXYGEN)) */
typedef struct RpBuildMeshTriangle RpBuildMeshTriangle;
/**
- * \ingroup rpworlddatatypes
+ * \ingroup rpmesh
* \struct RpBuildMeshTriangle
* This type represents an array of indices into
* the object vertex array. Used during the construction
@@ -613,7 +520,7 @@ struct RpBuildMeshTriangle
typedef struct RpBuildMesh RpBuildMesh;
/**
- * \ingroup rpworlddatatypes
+ * \ingroup rpmesh
* \struct RpBuildMesh
* This type represents a mesh ready for tri stripping.
*
@@ -640,7 +547,7 @@ struct RpBuildMesh
typedef struct RpMesh RpMesh;
/**
- * \ingroup rpworlddatatypes
+ * \ingroup rpmesh
* \struct RpMesh
* This type represents a single polygon mesh.
* A mesh is defined as a collection of triangles derived from an RpGeometry
@@ -659,7 +566,7 @@ struct RpMesh
};
/**
- * \ingroup rpworlddatatypes
+ * \ingroup rpmesh
* \struct RpMeshHeader
* Header for all meshes that constitute a single RpGeometry or RpWorldSector
*/
@@ -679,9 +586,8 @@ struct RpMeshHeader
};
/**
- * \ingroup rpworlddatatypes
- * \typedef RpMeshCallBack
- * \ref RpMeshCallBack is the callback
+ * \ingroup rpmesh
+ * \ref RpMeshCallBack is the callback
* function supplied to \ref RpGeometryForAllMeshes and
* \ref RpWorldSectorForAllMeshes for all meshes in a given geometry.
*
@@ -689,14 +595,13 @@ struct RpMeshHeader
* success. The callback may return NULL to terminate further callbacks
* on the meshes.
*
- * \param mesh Pointer to the current mesh, supplied by
- * iterator.
- * \param meshHeader Pointer to the meshes header
- * \param data Pointer to developer-defined data structure.
+ * \param mesh Pointer to the current mesh, supplied by
+ * iterator.
+ * \param meshHeader Pointer to the meshes header
+ * \param data Pointer to developer-defined data structure.
*
- * \return
- * Returns a pointer to the current mesh if successful or NULL if an error
- * occurred.
+ * \return Returns a pointer to the current mesh if successful or NULL
+ * if an error occurred.
*/
typedef RpMesh *(*RpMeshCallBack) (RpMesh * mesh,
RpMeshHeader * meshHeader,
@@ -823,29 +728,29 @@ extern RpMeshHeader * _rpMeshHeaderCreate(RwUInt32 size);
naTmp[1] = RwRealToFixed((v).y); \
naTmp[2] = RwRealToFixed((v).z); \
\
- if (naTmp[0] >= RwFixedCast(1)) \
+ if (naTmp[0] >= RwIntToFixed(1)) \
{ \
- naTmp[0] = RwFixedCast(1)-1; \
+ naTmp[0] = RwIntToFixed(1)-1; \
} \
- if (naTmp[0] <= RwFixedCast(-1)) \
+ if (naTmp[0] <= RwIntToFixed(-1)) \
{ \
- naTmp[0] = RwFixedCast(-1)+1; \
+ naTmp[0] = RwIntToFixed(-1)+1; \
} \
- if (naTmp[1] >= RwFixedCast(1)) \
+ if (naTmp[1] >= RwIntToFixed(1)) \
{ \
- naTmp[1] = RwFixedCast(1)-1; \
+ naTmp[1] = RwIntToFixed(1)-1; \
} \
- if (naTmp[1] <= RwFixedCast(-1)) \
+ if (naTmp[1] <= RwIntToFixed(-1)) \
{ \
- naTmp[1] = RwFixedCast(-1)+1; \
+ naTmp[1] = RwIntToFixed(-1)+1; \
} \
- if (naTmp[2] >= RwFixedCast(1)) \
+ if (naTmp[2] >= RwIntToFixed(1)) \
{ \
- naTmp[2] = RwFixedCast(1)-1; \
+ naTmp[2] = RwIntToFixed(1)-1; \
} \
- if (naTmp[2] <= RwFixedCast(-1)) \
+ if (naTmp[2] <= RwIntToFixed(-1)) \
{ \
- naTmp[2] = RwFixedCast(-1)+1; \
+ naTmp[2] = RwIntToFixed(-1)+1; \
} \
\
(n).x = (RwInt8)(naTmp[0]>>9); \
@@ -853,37 +758,13 @@ extern RpMeshHeader * _rpMeshHeaderCreate(RwUInt32 size);
(n).z = (RwInt8)(naTmp[2]>>9); \
}
-/* RpCollSector access macros - for pre v304 data */
-#define RWCOLLSECTORGETTYPE(sect) \
- ((sect).cType&0x80)
-
-#define RWCOLLSECTORGETPLANE(sect) \
- ((((sect).cType)>>3)&0xc)
-
-#define RWCOLLSECTORGETON(sect) \
- (((sect).cType)&0x1f)
-
-#define RWCOLLSECTORGETVERTEX(sect) \
- (sect).vertex
-
-#define RWCOLLSECTORGETSTART(sect) \
- (sect).start
-
-#define RWCOLLSECTORGETNOPOLYS(sect) \
- (sect).cType
-
-#define RWCOLLSECTORSETPOLYGONS(sect,no,st) \
- (sect).cType = (RwUInt8)(no); \
- (sect).start = (RwUInt8)(st)
-
-#define rwMAXCOLLISIONCUTS 7
-
/****************************************************************************
Global types
*/
typedef struct RpVertexNormal RpVertexNormal;
+#if (!defined(DOXYGEN))
struct RpVertexNormal
{
RwInt8 x;
@@ -899,28 +780,11 @@ struct RpPolygon
RwUInt16 matIndex;
RwUInt16 vertIndex[3];
};
-
-/* RpCollSector - for pre v304 data */
-#define RWCOLLSECTORSETPLANE(sect,plane,vert,no,st) \
- (sect).cType = (RwUInt8)(0x80|((plane)<<3)|(no)); \
- (sect).vertex = (RwUInt8)(vert); \
- (sect).start = (RwUInt8)(st)
-
-typedef struct RpCollSector RpCollSector;
-
-struct RpCollSector
-{
- RwUInt8 cType; /* Bit 7 - 1 plane */
- /* 0 polygons */
- /* Bit 6-5 - plane */
- /* Bit 4-0 - amount ON plane */
- RwUInt8 vertex; /* Vertex index used for the split */
- RwUInt8 start; /* Starting polygon */
-};
+#endif /* (!defined(DOXYGEN)) */
/**
- * \ingroup rpworlddatatypes
- * \typedef RpWorldSector
+ * \ingroup rpworldsector
+ * \struct RpWorldSector
* World Sector object. This should be
* considered an opaque type. Use the RpWorldSector API functions to access.
*/
@@ -958,9 +822,6 @@ struct RpWorldSector
/* Bounding box tightly enclosing geometry */
RwBBox tightBoundingBox;
- /* The root of the bsp collision tree for pre v304 data */
- RpCollSector *colSectorRoot;
-
/* The mesh which groups same material polygons together */
RpMeshHeader *mesh;
@@ -981,9 +842,8 @@ struct RpWorldSector
#endif /* (!defined(DOXYGEN)) */
/**
- * \ingroup rpworlddatatypes
- * \typedef RpWorldSectorCallBack
- \ref RpWorldSectorCallBack
+ * \ingroup rpworldsector
+ * \ref RpWorldSectorCallBack
* represents the function called from \ref RpWorldForAllWorldSectors,
* \ref RpAtomicForAllWorldSectors and \ref RpLightForAllWorldSectors for all
* world sectors in a given world or world sectors a given atomic or light lies
@@ -991,15 +851,17 @@ struct RpWorldSector
* indicate success. The callback may return NULL to terminate further
* callbacks on the atomic or light.
*
+ * \param sector Pointer to the current world sector
+ * \param data Pointer to developer-defined data structure.
+ *
* \return Pointer to the current world sector.
*
- * \param sector Pointer to the current world sector
- * \param data Pointer to developer-defined data structure.
*/
typedef RpWorldSector *(*RpWorldSectorCallBack)(RpWorldSector *worldSector, void *data);
typedef struct RpSector RpSector;
+#if (!defined(DOXYGEN))
struct RpSector
{
RwInt32 type;
@@ -1022,7 +884,7 @@ struct RpPlaneSector
RwReal leftValue;
RwReal rightValue;
};
-
+#endif /* (!defined(DOXYGEN)) */
#ifdef __cplusplus
extern "C"
@@ -1101,15 +963,16 @@ extern RwBool RpWorldSectorValidatePlugins(const RpWorldSector *sector);
Defines
*/
+#define RPTRISTRIPPOLYGONMAXEDGES 3
+
/**
- * \ingroup rpworlddatatypes
- * \typedef RpTriStripMeshCallBack
+ * \ingroup rpmesh
* \ref RpTriStripMeshCallBack is the callback to generate triangle strips
* when the triangle stripped geometries or world sectors are unlocked.
*
* \param buildMesh pointer to the mesh which the triangle strip will be
- * generated from.
- * \param data pointer to user-supplied data to pass to the callback
+ * generated from.
+ * \param data pointer to user-supplied data to pass to the callback
* function.
*
* \return a pointer to the constructed mesh header.
@@ -1119,10 +982,156 @@ typedef RpMeshHeader *
(*RpTriStripMeshCallBack) (RpBuildMesh *buildMesh, void *data);
+
/****************************************************************************
Global types
*/
+typedef struct RpTriStripEdge RpTriStripEdge;
+
+typedef struct RpTriStripPolygon RpTriStripPolygon;
+/**
+ * \ingroup rpmesh
+ * \struct RpTriStripPolygon
+ * This type represents a polygon.
+ *
+ * \see RpTriStripPolygonFollowStrip
+ * \see RpBuildMeshGenerateTriStrip
+ * \see RpTriStripMeshTunnel
+ */
+struct RpTriStripPolygon
+{
+ RwLLLink inEndLink; /**< link for list of polygons joined by fewer than
+ 2 strip edges */
+ RwLLLink inUsedLink; /**< link for list of used polygons */
+ RwLLLink inFreeLink; /**< link for list of free polygons */
+ RwUInt32 numEdges; /**< number of edges */
+ RpTriStripEdge *edges[RPTRISTRIPPOLYGONMAXEDGES]; /**< polygon edges */
+ RxVertexIndex vertIndex[RPTRISTRIPPOLYGONMAXEDGES]; /**< polygon vertex
+ indices */
+ RwUInt32 testFrame; /**< used to prevent a tri-strip being counted by
+ the cost function more than once */
+};
+
+/**
+ * \ingroup rpmesh
+ * \struct RpTriStripEdge
+ * This type represents a polygon edge which may be part of a tri-strip.
+ *
+ * \see RpTriStripPolygonFollowStrip
+ * \see RpBuildMeshGenerateTriStrip
+ * \see RpTriStripMeshTunnel
+ */
+struct RpTriStripEdge
+{
+ RwLLLink inUsedLink; /**< link for list of used edges */
+ RwLLLink inFreeLink; /**< link for list of free edges */
+ RpTriStripPolygon *poly1; /**< first polygon including this edge */
+ RpTriStripPolygon *poly2; /**< second polygon including this edge or NULL
+ if this edge is only included in one */
+ RxVertexIndex vert1; /**< index of first vertex of edge */
+ RxVertexIndex vert2; /**< index of second vertex of edge */
+ RwBool strip; /**< TRUE if the edge is part of a tri-strip */
+};
+
+typedef struct RpTriStripMesh RpTriStripMesh;
+/**
+ * \ingroup rpmesh
+ * \struct RpTriStripMesh
+ * This type represents a mesh and the tri-strips it contains.
+ *
+ * \see RpBuildMeshGenerateTriStrip
+ * \see RpTriStripMeshTunnel
+ */
+struct RpTriStripMesh
+{
+ RwUInt32 numPolygons; /**< the number of polygons in the mesh */
+ RwLinkList polygonEndList; /**< linked list of polygons joined by fewer
+ than 2 strip edges. */
+ RwLinkList polygonUsedList; /**< linked list of used polygons */
+ RwLinkList polygonFreeList; /**< linked list of free polygons */
+ RwLinkList edgeUsedList; /**< linked list of used edges */
+ RwLinkList edgeFreeList; /**< linked list of free edges */
+};
+
+/**
+ * \ingroup rpmesh
+ * \ref RpTriStripMeshStripCallBack represents the callback function to
+ * tri-strip a mesh.
+ *
+ * \param mesh Pointer to the mesh to tri-strip.
+ * \param data Pointer to user-supplied data.
+ *
+ * \return Returns a pointer to the current mesh if successful or NULL if an
+ * error occurred.
+ */
+typedef RpTriStripMesh *
+(*RpTriStripMeshStripCallBack) (RpTriStripMesh *mesh, void *data);
+
+typedef struct RpTriStripData RpTriStripData;
+/**
+ * \ingroup rpmesh
+ * \struct RpTriStripData
+ * This type represents the data required by the
+ * \ref RpBuildMeshGenerateTriStrip function to tri-strip a mesh. This data must
+ * be the user-supplied data passed into RpMeshSetTriStripMethod when using
+ * \ref RpBuildMeshGenerateTriStrip.
+ *
+ * \see RpMeshGetTriStripMethod
+ * \see RpMeshSetTriStripMethod
+ * \see RpBuildMeshGenerateTriStrip
+ * \see RpTriStripMeshTunnel
+ */
+struct RpTriStripData
+{
+ RwBool ignoreWinding; /**< TRUE to ignore winding order */
+ RpTriStripMeshStripCallBack stripCB; /**< callback to tri-strip mesh */
+ void *data; /**< data to supply to callback */
+};
+
+/**
+ * \ingroup rpmesh
+ * \ref RpTriStripCostCallBack represents the callback function used by the
+ * tunnelling tri-stripper to determine the cost of a tri-strip.
+ *
+ * \param startPolygon Pointer to polygon at the start of the tri-strip.
+ * \param testFrame Value that must be written to the testFrame of all
+ * polygons in the tri-strip
+ * \param data Pointer to user-supplied data.
+ *
+ * \return Returns the cost of the tri-strip.
+ */
+typedef RwUInt32
+(*RpTriStripCostCallBack) (RpTriStripPolygon *startPolygon, RwUInt32 testFrame, void *data);
+
+typedef struct RpTriStripTunnelData RpTriStripTunnelData;
+/**
+ * \ingroup rpmesh
+ * \struct RpTriStripTunnelData
+ * This type represents the data required by the
+ * \ref RpTriStripMeshTunnel function to tri-strip a mesh. This data must
+ * be the user-supplied data in the RpTriStripData structure passed into
+ * \ref RpMeshSetTriStripMethod as the user-supplied data when using
+ * \ref RpTriStripMeshTunnel.
+ *
+ * \see RpMeshGetTriStripMethod
+ * \see RpMeshSetTriStripMethod
+ * \see RpBuildMeshGenerateTriStrip
+ * \see RpTriStripMeshTunnel
+ * \see RpTriStripDefaultCost
+ */
+struct RpTriStripTunnelData
+{
+ RwReal quality; /**< the higher the value the better the
+ output but the longer it will take;
+ values greater than 1 are unlikely to
+ be useful */
+ RwUInt32 lengthLimit; /**< the maximum tunnel length to use */
+ RpTriStripCostCallBack costCB; /**< callback to determine tri-strip cost */
+ void *data; /**< data to supply to callbacks */
+};
+
+
/****************************************************************************
Global Variables
@@ -1138,8 +1147,27 @@ extern "C"
{
#endif /* __cplusplus */
+/* Tri-strip manipulating functions */
+extern RpTriStripPolygon *
+RpTriStripPolygonFollowStrip(RpTriStripPolygon *curr, RpTriStripPolygon *prev);
+
+/* Callback strip costing functions */
+extern RwUInt32
+RpTriStripDefaultCost(RpTriStripPolygon *startPolygon, RwUInt32 testFrame,
+ void *data);
+
+/* Callback mesh stripping functions */
+extern RpTriStripMesh *
+RpTriStripMeshTunnel(RpTriStripMesh *mesh, void *data);
-/* Callback mesh generating functions */
+extern RpTriStripMesh *
+RpTriStripMeshQuick(RpTriStripMesh *mesh, void *data);
+
+/* New callback mesh generating function */
+extern RpMeshHeader *
+RpBuildMeshGenerateTriStrip(RpBuildMesh *buildMesh, void *data);
+
+/* Old callback mesh generating functions. Probably obsolete */
extern RpMeshHeader *
RpBuildMeshGenerateTrivialTriStrip(RpBuildMesh *buildMesh, void *data);
@@ -1164,7 +1192,7 @@ extern RpMeshHeader *
RpBuildMeshGenerateExhaustiveIgnoreWindingTriStrip(RpBuildMesh *buildmesh,
void *data);
-/* Functions to set and get the global mesh tristrip algorithm */
+/* Functions to set and get the global mesh tri-strip algorithm */
extern RwBool
RpMeshSetTriStripMethod(RpTriStripMeshCallBack callback, void *data);
@@ -1225,6 +1253,7 @@ _rpMeshOptimise(RpBuildMesh *buildmesh, RwUInt32 flags);
typedef struct RpLightChunkInfo RpLightChunkInfo;
typedef struct RpLightChunkInfo _rpLight;
+#if (!defined(DOXYGEN))
struct RpLightChunkInfo
{
RwReal radius; /**< radius */
@@ -1234,6 +1263,7 @@ struct RpLightChunkInfo
RwReal minusCosAngle; /**< minusCosAngle */
RwUInt32 typeAndFlags; /**< typeAndFlags */
};
+#endif /* (!defined(DOXYGEN)) */
/* Type ID */
#define rpLIGHT 3
@@ -1242,7 +1272,7 @@ struct RpLightChunkInfo
#define rpLIGHTPOSITIONINGSTART 0x80
/**
- * \ingroup rpworlddatatypes
+ * \ingroup rplight
* \ref RpLightType are
* light sub types. This type represents the different
* types of light source that can be created using the API function \ref RpLightCreate.
@@ -1265,12 +1295,17 @@ enum RpLightType
typedef enum RpLightType RpLightType;
#define rpLIGHTMINCONEANGLE ((RwReal)0.0f)
-#if ((defined(XBOX_DRVMODEL_H)) || (defined(OPENGL_DRVMODEL_H)) || (defined(GCN_DRVMODEL_H)))
-/* XBox has Micro$oft-penned drivers, no wonder it crashes... */
-/* OpenGL and GCN clamp to 90 internally, so we mirror that behaviour */
-#define rpLIGHTMAXCONEANGLE ((RwReal)89.9999f)
+
+#if (defined(XBOX_DRVMODEL_H))
+#define rpLIGHTMAXCONEANGLE (rwPIOVER2)
+#elif (defined(OPENGL_DRVMODEL_H))
+#define rpLIGHTMAXCONEANGLE (rwPIOVER2)
+#elif (defined(GCN_DRVMODEL_H))
+#define rpLIGHTMAXCONEANGLE (rwPIOVER2)
+#elif (defined(D3D8_DRVMODEL_H))
+#define rpLIGHTMAXCONEANGLE (rwPIOVER2)
#else
-#define rpLIGHTMAXCONEANGLE ((RwReal)180.0f)
+#define rpLIGHTMAXCONEANGLE (rwPI)
#endif
/*************/
@@ -1280,7 +1315,7 @@ typedef enum RpLightType RpLightType;
/*************/
/**
- * \ingroup rpworlddatatypes
+ * \ingroup rplight
* \ref RpLightFlag defines what geometry is influenced by the light.
* The bit-field RpLightFlag specifies the options available for controlling the scope
* of a light source (see API function \ref RpLightSetFlags):*/
@@ -1327,10 +1362,10 @@ MACRO_STOP
/**
- * \ingroup rpworlddatatypes
- * \typedef RpLight
- * Light. This should be
- * considered an opaque type. User the RpLight API functions to access.
+ * \ingroup rplight
+ * \struct RpLight
+ * Light object. This should be
+ * considered an opaque type. Use the RpLight API functions to access.
*/
typedef struct RpLight RpLight;
@@ -1349,8 +1384,7 @@ struct RpLight
#endif /* (!defined(DOXYGEN)) */
/**
- * \ingroup rpworlddatatypes
- * \typedef RpLightCallBack
+ * \ingroup rplight
* \ref RpLightCallBack
* represents the function called from \ref RpWorldForAllLights and
* \ref RpWorld SectorForAllLights for all lights in a given world or world
@@ -1358,25 +1392,34 @@ struct RpLight
* indicate success. The callback may return NULL to terminate further
* callbacks on the world sector.
*
+ * \param light Pointer to the current light in the world
+ * sector.
+ * \param data Pointer to developer-defined data structure.
+ *
* \return Pointer to the current light.
- *
- * \param light Pointer to the current light in the world
- * sector.
- * \param data Pointer to developer-defined data structure.
*/
typedef RpLight *(*RpLightCallBack) (RpLight * light, void *data);
typedef struct RpLightTie RpLightTie;
+/**
+ * \ingroup rplight
+ * \struct RpLightTie
+ *
+ * RpLightTie is a linked list of lights inside world sectors. These are
+ * created when frame hierarchies are updated as part of an \ref RwCameraBeginUpdate.
+ * This is used for determining which lights influence a world sector and the atomics inside it.
+ * Creation and destruction of RpLightTies is internal to the world plugin.
+ */
struct RpLightTie
{
/* Information for an atomic sector */
- RwLLLink lightInWorldSector; /* Lights IN this ATOMIC SECTOR */
- RpLight *light;
+ RwLLLink lightInWorldSector; /**< Lights IN this ATOMIC SECTOR */
+ RpLight *light; /**< A pointer to a light */
/* Information for a atomic */
- RwLLLink WorldSectorInLight; /* Atomic sectors HOLDING this Light */
- RpWorldSector *sect;
+ RwLLLink WorldSectorInLight; /**< Atomic sectors HOLDING this Light */
+ RpWorldSector *sect; /**< A pointer to a world sector */
};
@@ -1453,6 +1496,7 @@ extern RwUInt32 RpLightGetFlags(const RpLight *light);
#endif /* (defined(RWDEBUG) || defined(RWSUPPRESSINLINE)) */
/* API Functions */
+extern void RpLightSetFreeListCreateParams( RwInt32 blockSize, RwInt32 numBlocksToPrealloc );
extern RpLight *RpLightCreate(RwInt32 type);
extern RwBool RpLightDestroy(RpLight *light);
extern RpLight *RpLightSetRadius(RpLight *light, RwReal radius);
@@ -1491,9 +1535,7 @@ extern RwBool RpLightValidatePlugins(const RpLight * light);
/*--- Automatically derived from: C:/daily/rwsdk/world/pipe/p2/d3d8/D3D8lights.h ---*/
-/**
- * \ingroup rplightd3d8
- * \typedef RpD3D8AttenuationParams
+/*
* typedef for struct RpD3D8AttenuationParams
*/
typedef struct RpD3D8AttenuationParams RpD3D8AttenuationParams;
@@ -1546,21 +1588,6 @@ _rwD3D8LightsClose(void);
#endif /* __cplusplus */
-/*--- Automatically derived from: C:/daily/rwsdk/world/pipe/p2/p2stdclsw.h ---*/
-typedef RpLight *RxLight;
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-extern RxClusterDefinition RxClLights; /* Uses the RxLight type (see above) */
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-
-
/*--- Automatically derived from: c:/daily/rwsdk/world/bageomet.h ---*/
/*
@@ -1579,7 +1606,7 @@ extern RxClusterDefinition RxClLights; /* Uses the RxLight type (see above) */
#define rpGEOMETRY 8
/**
- * \ingroup rpworlddatatypes
+ * \ingroup rpgeometry
* RpGeometryFlag
* Geometry type flags
*
@@ -1630,7 +1657,7 @@ typedef enum RpGeometryFlag RpGeometryFlag;
#define rpGEOMETRYTEXCOORDSETS(_num) ((_num & 0xff) << 16)
/**
- * \ingroup rpworlddatatypes
+ * \ingroup rpgeometry
* RpGeometryLockMode
* Geometry lock flags
*/
@@ -1665,22 +1692,25 @@ typedef enum RpGeometryLockMode RpGeometryLockMode;
*/
typedef struct rpGeometryGlobals rpGeometryGlobals;
+
+#if (!defined(DOXYGEN))
struct rpGeometryGlobals
{
RwFreeList *geomFreeList;
};
+#endif /* (!defined(DOXYGEN)) */
/**
- * \ingroup rpworlddatatypes
- * \typedef RpGeometry
+ * \ingroup rpgeometry
+ * \struct RpGeometry
* Geometry object. This should be considered an opaque type.
* Use the RpGeometry API functions to access.
*/
typedef struct RpGeometry RpGeometry;
/**
- * \ingroup rpworlddatatypes
- * \typedef RpMorphTarget
+ * \ingroup rpmorphtarget
+ * \struct RpMorphTarget
* Morph target -- vertex positions and normals.
* This should be considered an opaque type.
* Use RpMorphTarget API functions to access.
@@ -1700,7 +1730,7 @@ struct RpMorphTarget
typedef struct RpTriangle RpTriangle;
/**
- * \ingroup rpworlddatatypes
+ * \ingroup rpgeometry
* \struct RpTriangle
* This type represents a triangle in a geometry specified
* by three indices into the geometry's vertex list (vertIndex)
@@ -1736,18 +1766,12 @@ struct RpGeometry
RwTexCoords *texCoords[rwMAXTEXTURECOORDS]; /* Texture coordinates */
- RwSurfaceProperties ignoredSurfaceProps; /* Not used in pp rendering, but present
- * so if pipe1 files are read and written these
- * values are not lost
- */
-
RpMeshHeader *mesh; /* The mesh - groups polys of the same material */
RwResEntry *repEntry; /* Information for an instance */
RpMorphTarget *morphTarget; /* The Morph Target */
};
-#endif /* (!defined(DOXYGEN)) */
typedef struct RpGeometryChunkInfo RpGeometryChunkInfo;
typedef struct RpGeometryChunkInfo _rpGeometry;
@@ -1760,27 +1784,27 @@ struct RpGeometryChunkInfo
RwInt32 numVertices;
RwInt32 numMorphTargets;
-
- RwSurfaceProperties ignoredSurfaceProps;
};
+#endif /* (!defined(DOXYGEN)) */
/* Callbacks */
/**
- * \ingroup rpworlddatatypes
- * \typedef RpGeometryCallBack
+ * \ingroup rpgeometry
* \ref RpGeometryCallBack represents the simple callback function for the \ref RpGeometry object.
* The callback may return NULL to terminate further callbacks on
* the geometry.
*
* \param geometry Pointer to the current geometry, supplied by iterator.
- * \param data Pointer to developer-defined data structure.
+ * \param data Pointer to developer-defined data structure.
+ *
+ * \return
*/
typedef RpGeometry *(*RpGeometryCallBack)(RpGeometry *geometry, void *data);
/**
- * \ingroup rpworlddatatypes
- * \typedef RpGeometrySortByMaterialCallBack
+ * \ingroup rpgeometry
+ * \ref RpGeometrySortByMaterialCallBack
* \ref RpGeometrySortByMaterialCallBack is used by
* \ref RpGeometrySortByMaterial in order to preserve the validity of plugin
* data when the vertices in an \ref RpGeometry are sorted (and some possibly
@@ -1790,11 +1814,11 @@ typedef RpGeometry *(*RpGeometryCallBack)(RpGeometry *geometry, void *data);
* vertex in the new geometry, the index of the corresponding vertex in the
* original geometry.
*
- * \param oldGeom Pointer to the source geometry.
- * \param newGeom Pointer to the new, sorted geometry.
- * \param remapTable pointer to the vertex map table
+ * \param oldGeom Pointer to the source geometry.
+ * \param newGeom Pointer to the new, sorted geometry.
+ * \param remapTable Pointer to the vertex map table
* \param numberOfEntries Number of vertices in the new
- * geometry (size of the map table)
+ * geometry (size of the map table)
*/
typedef void (*RpGeometrySortByMaterialCallBack)(const RpGeometry *oldGeom,
RpGeometry *newGeom,
@@ -2106,25 +2130,10 @@ RpGeometrySetFlags(RpGeometry *geometry,
#endif
-/* Lighting characteristics */
-
-extern const RwSurfaceProperties *
-_rpGeometryGetSurfaceProperties(const RpGeometry *geometry);
-
-extern RpGeometry *
-_rpGeometrySetSurfaceProperties(RpGeometry *geometry,
- const RwSurfaceProperties *surfaceProperties);
-
#ifdef __cplusplus
}
#endif /* __cplusplus */
-#define RpGeometryGetSurfaceProperties(_geometry) \
- _rpGeometryGetSurfaceProperties(_geometry)
-
-#define RpGeometrySetSurfaceProperties(_geometry, _surfaceProperties) \
- _rpGeometrySetSurfaceProperties(_geometry, _surfaceProperties)
-
#define rpGeometryAddRef(_geometry) \
_rpGeometryAddRef(_geometry)
@@ -2164,7 +2173,7 @@ enum RpInterpolatorFlag
typedef enum RpInterpolatorFlag rpInterpolatorFlag;
/**
- * \ingroup rpworlddatatypes
+ * \ingroup rpatomic
* The bit-field type RpAtomicFlag specifies the options available for
* controlling the behavior of atomics. See API function \ref RpAtomicSetFlags.
*
@@ -2188,7 +2197,7 @@ enum RpAtomicFlag
typedef enum RpAtomicFlag RpAtomicFlag;
/**
- * \ingroup rpworlddatatypes
+ * \ingroup rpatomic
* \ref RpAtomicSetGeomFlag defines how an atomic references a new geometry
*
* \see RpAtomicSetGeometry
@@ -2214,16 +2223,16 @@ typedef enum RpAtomicPrivateFlag rpAtomicPrivateFlag;
/**
- * \ingroup rpworlddatatypes
- * \typedef RpAtomic
+ * \ingroup rpatomic
+ * \struct RpAtomic
* Atomic Geometry object. This should be
* considered an opaque type. Use the RpAtomic API functions to access.
*/
typedef struct RpAtomic RpAtomic;
/**
- * \ingroup rpworlddatatypes
- * \typedef RpInterpolator
+ * \ingroup rpinterpolator
+ * \struct RpInterpolator
* Morph Target Interpolator.
* This should be considered an opaque type.
* Use the RpInterpolator API functions to access.
@@ -2245,16 +2254,15 @@ struct RpInterpolator
/* More callbacks */
/**
- * \ingroup rpworlddatatypes
- * \typedef RpClump
+ * \ingroup rpclump
+ * \struct RpClump
* Clump Geometry object. This should be
* considered an opaque type. Use the RpClump API functions to access.
*/
typedef struct RpClump RpClump;
/**
- * \ingroup rpworlddatatypes
- * \typedef RpClumpCallBack
+ * \ingroup rpclump
* \ref RpClumpCallBack represents the
* function called from \ref RwCameraForAllClumpsInFrustum and
* \ref RwCameraForAllClumpsNotInFrustum when a clump lies inside the current camera's
@@ -2263,8 +2271,8 @@ typedef struct RpClump RpClump;
* NULL to terminate further callbacks on the clumps.
*
* \param clump Pointer to the current clump, supplied by
- * iterator.
- * \param data Pointer to developer-defined data structure.
+ * iterator.
+ * \param data Pointer to developer-defined data structure.
*
* \return Pointer to the current clump.
*
@@ -2303,8 +2311,7 @@ struct RpClump
#endif /* (!defined(DOXYGEN)) */
/**
- * \ingroup rpworlddatatypes
- * \typedef RpAtomicCallBackRender
+ * \ingroup rpatomic
* \ref RpAtomicCallBackRender represents the function called from
* \ref RpAtomicRender when the specified atomic
* lies inside the current camera's view frustum. The default callback
@@ -2312,10 +2319,13 @@ struct RpClump
* return a pointer to the atomic to indicate success.
*
* \param atomic Pointer to the current atomic, supplied by
- * iterator.
+ * iterator.
+ *
+ * \return Returns a pointer to the atomic to indicate success.
*
* \see RpAtomicRender
*/
+
typedef RpAtomic *(*RpAtomicCallBackRender) (RpAtomic * atomic);
#if (!defined(DOXYGEN))
@@ -2356,8 +2366,7 @@ struct RpAtomic
#endif /* (!defined(DOXYGEN)) */
/**
- * \ingroup rpworlddatatypes
- * \typedef RpAtomicCallBack
+ * \ingroup rpatomic
* \ref RpAtomicCallBack represents the function called from \ref RpWorldSectorForAllAtomics and
* \ref RpClumpForAllAtomics for all atomics in a given world sector or clump.
* This function should return a pointer to the current atomic to indicate
@@ -2365,28 +2374,40 @@ struct RpAtomic
* the world sector.
*
* \param atomic Pointer to the current atomic, supplied by
- * iterator.
- * \param data Pointer to developer-defined data structure.
+ * iterator.
+ * \param data Pointer to developer-defined data structure.
+ *
+ * \return Returns a pointer to the current atomic
*/
typedef RpAtomic *(*RpAtomicCallBack) (RpAtomic * atomic, void *data);
typedef struct RpTie RpTie;
+/**
+ * \ingroup rpatomic
+ * \struct RpTie
+ *
+ * RpTie is a linked list of atomics inside world sectors. These are
+ * created when frame hierarchies are updated as part of an \ref RwCameraBeginUpdate.
+ * This is used for frustum culling atomics by world sector.
+ * Creation and destruction of RpTies is internal to the world plugin.
+ */
struct RpTie
{
/* Information for an atomic sector */
- RwLLLink lAtomicInWorldSector; /* Atomics IN this ATOMIC SECTOR */
- RpAtomic *apAtom;
+ RwLLLink lAtomicInWorldSector; /**< Atomics IN this ATOMIC SECTOR */
+ RpAtomic *apAtom; /**< An atomic */
/* Information for a atomic */
- RwLLLink lWorldSectorInAtomic; /* Atomic sectors HOLDING this atomic */
- RpWorldSector *worldSector;
+ RwLLLink lWorldSectorInAtomic; /**< Atomic sectors HOLDING this atomic */
+ RpWorldSector *worldSector; /**< A world sector */
};
typedef struct RpClumpChunkInfo RpClumpChunkInfo;
typedef struct RpClumpChunkInfo _rpClump;
typedef struct RpClumpChunkInfo33000 _rpClump33000;
+#if (!defined(DOXYGEN))
struct RpClumpChunkInfo
{
RwInt32 numAtomics;
@@ -2398,6 +2419,7 @@ struct RpClumpChunkInfo33000
{
RwInt32 numAtomics;
};
+#endif /* (!defined(DOXYGEN)) */
/****************************************************************************
<macro/inline functionality
@@ -2608,6 +2630,12 @@ extern "C"
#endif /* __cplusplus */
+extern void
+RpAtomicSetFreeListCreateParams( RwInt32 blockSize, RwInt32 numBlocksToPrealloc );
+
+extern void
+RpClumpSetFreeListCreateParams( RwInt32 blockSize, RwInt32 numBlocksToPrealloc );
+
/* Macro version of RpAtomicSetRenderCallBack needs this */
extern RpAtomic *
AtomicDefaultRenderCallBack(RpAtomic * atomic);
@@ -2918,7 +2946,7 @@ enum RpWorldPrivateFlag
typedef enum RpWorldPrivateFlag RpWorldPrivateFlag;
/**
- * \ingroup rpworlddatatypes
+ * \ingroup rpworldsub
* The bit-field type \ref RpWorldFlag specifies the options available
* for creating the static geometry component of a world (see API function \ref RpWorldSetFlags):
*/
@@ -3027,7 +3055,7 @@ typedef enum RpWorldFlag RpWorldFlag;
/**
- * \ingroup rpworlddatatypes
+ * \ingroup rpworldsub
* \ref RpWorldRenderOrder
* represents the options available for
* the rendering order of world sectors in the camera's view frustum (see
@@ -3043,25 +3071,25 @@ enum RpWorldRenderOrder
typedef enum RpWorldRenderOrder RpWorldRenderOrder;
/**
- * \ingroup rpworlddatatypes
- * \typedef RpWorldSectorCallBackRender
+ * \ingroup rpworldsector
* \ref RpWorldSectorCallBackRender represents the function called from
* \ref RpWorldSectorRender when the specified world sector lies inside the
* current camera's view frustum. The default callback initiates execution of
* the world sector rendering pipeline. This function should return a pointer
* to the world sector to indicate success
*
+ * \param worldSector Pointer to the world sector to be
+ * rendered
+ *
* \return Pointer to the world sector.
*
- * \param worldSector Pointer to the world sector to be
- * rendered
*/
typedef RpWorldSector *(*RpWorldSectorCallBackRender) (RpWorldSector *
worldSector);
/**
- * \ingroup rpworlddatatypes
- * \typedef RpWorld
+ * \ingroup rpworldsub
+ * \struct RpWorld
* World object. This should be considered an opaque type.
* Use the RpWorld API functions to access.
*/
@@ -3104,9 +3132,6 @@ struct RpWorld
/* Bounding box around the whole world */
RwBBox boundingBox;
- /* Surface properties */
- RwSurfaceProperties surfaceProps;
-
/* The callbacks functions */
RpWorldSectorCallBackRender renderCallBack;
@@ -3191,13 +3216,6 @@ extern RwBool RpWorldDestroy(RpWorld * world);
extern RpWorld *RpWorldCreate(RwBBox * boundingBox);
extern RwBool RpWorldInstance(RpWorld *world);
-/* Getting/setting */
-extern RpWorld *_rpWorldSetSurfaceProperties(RpWorld * world,
- const RwSurfaceProperties
- * surface);
-extern const RwSurfaceProperties *
- _rpWorldGetSurfaceProperties(const RpWorld *world);
-
/* Sector callbacks */
extern RpWorld *RpWorldSetSectorRenderCallBack(RpWorld * world,
RpWorldSectorCallBackRender
@@ -3260,12 +3278,6 @@ extern RwUInt32 RpWorldGetFlags(const RpWorld *world);
}
#endif /* __cplusplus */
-#define RpWorldSetSurfaceProperties(_world, _surface) \
- _rpWorldSetSurfaceProperties(_world, _surface)
-
-#define RpWorldGetSurfaceProperties(_world) \
- _rpWorldGetSurfaceProperties(_world)
-
#define rpWorldFindBBox(_world, _boundingBox) \
_rpWorldFindBBox(_world, _boundingBox)
@@ -3292,7 +3304,7 @@ extern RwUInt32 RpWorldGetFlags(const RpWorld *world);
typedef struct RxD3D8ResEntryHeader RxD3D8ResEntryHeader;
/**
- * \ingroup rpworldd3d8
+ * \ingroup worldextensionsd3d8
* \struct RxD3D8ResEntryHeader
* This structure contains D3D8 resource specific components.
*/
@@ -3305,7 +3317,7 @@ struct RxD3D8ResEntryHeader
/* This is what I keep in memory as part of the instance data setup */
typedef struct RxD3D8InstanceData RxD3D8InstanceData;
/**
- * \ingroup rpworldd3d8
+ * \ingroup worldextensionsd3d8
* \struct RxD3D8InstanceData
* This structure contains D3D8 resource specific components.
*/
@@ -3337,7 +3349,7 @@ struct RxD3D8InstanceData
};
/**
- * \ingroup rpworldd3d8
+ * \ingroup worldextensionsd3d8
* \ref RxD3D8AllInOneInstanceCallBack callback function.
*
* \param object Pointer to the object.
@@ -3354,7 +3366,7 @@ typedef RwBool (*RxD3D8AllInOneInstanceCallBack)(void *object,
RwBool reinstance);
/**
- * \ingroup rpworldd3d8
+ * \ingroup worldextensionsd3d8
* \ref RxD3D8AllInOneReinstanceCallBack callback function.
*
* \param object Pointer to the object.
@@ -3373,7 +3385,7 @@ typedef RwBool (*RxD3D8AllInOneReinstanceCallBack)(void *object,
RxD3D8AllInOneInstanceCallBack instanceCallback);
/**
- * \ingroup rpworldd3d8
+ * \ingroup worldextensionsd3d8
* \ref RxD3D8AllInOneLightingCallBack callback function.
*
* \param object Void pointer to the object.
@@ -3386,7 +3398,7 @@ typedef RwBool (*RxD3D8AllInOneReinstanceCallBack)(void *object,
typedef void (*RxD3D8AllInOneLightingCallBack)(void *object);
/**
- * \ingroup rpworldd3d8
+ * \ingroup worldextensionsd3d8
* \ref RxD3D8AllInOneRenderCallBack callback function.
*
* \param repEntry Pointer to a resource entry.
@@ -3443,9 +3455,6 @@ RxD3D8AllInOneGetRenderCallBack(RxPipelineNode *node);
/*--- Automatically derived from: C:/daily/rwsdk/world/pipe/p2/bapipew.h ---*/
-#define RpWorldGetGenericSectorPipelineMacro() \
- (RXPIPELINEGLOBAL(genericWorldSectorPipeline))
-
#define RpWorldGetDefaultSectorPipelineMacro() \
(RXPIPELINEGLOBAL(currentWorldSectorPipeline))
@@ -3461,9 +3470,6 @@ RxD3D8AllInOneGetRenderCallBack(RxPipelineNode *node);
#define RpWorldSectorGetPipelineMacro(_sector, _pipeline) \
( (*(_pipeline) = (_sector)->pipeline), _sector )
-#define RpAtomicGetGenericPipelineMacro() \
- (RXPIPELINEGLOBAL(genericAtomicPipeline))
-
#define RpAtomicGetDefaultPipelineMacro() \
(RXPIPELINEGLOBAL(currentAtomicPipeline))
@@ -3473,9 +3479,6 @@ RxD3D8AllInOneGetRenderCallBack(RxPipelineNode *node);
#define RpAtomicGetPipelineMacro(_atomic, _pipeline) \
( (*(_pipeline) = (_atomic)->pipeline), _atomic )
-#define RpMaterialGetGenericPipelineMacro() \
- (RXPIPELINEGLOBAL(genericMaterialPipeline))
-
#define RpMaterialGetDefaultPipelineMacro() \
(RXPIPELINEGLOBAL(currentMaterialPipeline))
@@ -3488,19 +3491,16 @@ RxD3D8AllInOneGetRenderCallBack(RxPipelineNode *node);
#if !(defined(RWDEBUG) || defined(RWSUPPRESSINLINE))
-#define RpWorldGetGenericSectorPipeline RpWorldGetGenericSectorPipelineMacro
#define RpWorldGetDefaultSectorPipeline RpWorldGetDefaultSectorPipelineMacro
#define RpWorldSetSectorPipeline RpWorldSetSectorPipelineMacro
#define RpWorldGetSectorPipeline RpWorldGetSectorPipelineMacro
#define RpWorldSectorSetPipeline RpWorldSectorSetPipelineMacro
#define RpWorldSectorGetPipeline RpWorldSectorGetPipelineMacro
-#define RpAtomicGetGenericPipeline RpAtomicGetGenericPipelineMacro
#define RpAtomicGetDefaultPipeline RpAtomicGetDefaultPipelineMacro
#define RpAtomicSetPipeline RpAtomicSetPipelineMacro
#define RpAtomicGetPipeline RpAtomicGetPipelineMacro
-#define RpMaterialGetGenericPipeline RpMaterialGetGenericPipelineMacro
#define RpMaterialGetDefaultPipeline RpMaterialGetDefaultPipelineMacro
#define RpMaterialSetPipeline RpMaterialSetPipelineMacro
#define RpMaterialGetPipeline RpMaterialGetPipelineMacro
@@ -3556,7 +3556,6 @@ extern RpGeometry *RpGeometrySortByMaterial(const RpGeometry * geometry,
#endif /* __cplusplus */
/* LEGACY-SUPPORT macros */
-#define RpWorldGetGenericSectorInstancePipeline RpWorldGetGenericSectorPipeline
#define RpWorldSetDefaultSectorInstancePipeline RpWorldSetDefaultSectorPipeline
#define RpWorldGetDefaultSectorInstancePipeline RpWorldGetDefaultSectorPipeline
#define RpWorldSetSectorInstancePipeline RpWorldSetSectorPipeline
@@ -3564,13 +3563,11 @@ extern RpGeometry *RpGeometrySortByMaterial(const RpGeometry * geometry,
#define RpWorldSectorSetInstancePipeline RpWorldSectorSetPipeline
#define RpWorldSectorGetInstancePipeline RpWorldSectorGetPipeline
-#define RpAtomicGetGenericInstancePipeline RpAtomicGetGenericPipeline
#define RpAtomicGetDefaultInstancePipeline RpAtomicGetDefaultPipeline
#define RpAtomicSetDefaultInstancePipeline RpAtomicSetDefaultPipeline
#define RpAtomicSetInstancePipeline RpAtomicSetPipeline
#define RpAtomicGetInstancePipeline RpAtomicGetPipeline
-#define RpMaterialGetGenericRenderPipeline RpMaterialGetGenericPipeline
#define RpMaterialSetDefaultRenderPipeline RpMaterialSetDefaultPipeline
#define RpMaterialGetDefaultRenderPipeline RpMaterialGetDefaultPipeline
#define RpMaterialSetRenderPipeline RpMaterialSetPipeline
@@ -3587,6 +3584,9 @@ extern "C"
{
#endif /* __cplusplus */
+extern void RpTieSetFreeListCreateParams( RwInt32 blockSize, RwInt32 numBlocksToPrealloc );
+extern void RpLightTieSetFreeListCreateParams( RwInt32 blockSize, RwInt32 numBlocksToPrealloc );
+
/* Adding and removing cameras to/from the world */
extern RpWorld *RpWorldRemoveCamera(RpWorld *world, RwCamera *camera);
extern RpWorld *RpWorldAddCamera(RpWorld *world, RwCamera *camera);
@@ -3648,6 +3648,7 @@ extern RpWorldSector *RpWorldSectorForAllLights(RpWorldSector *sector,
typedef struct RpWorldChunkInfoSector RpWorldSectorChunkInfo;
typedef struct RpWorldChunkInfoSector _rpWorldSector;
+#if (!defined(DOXYGEN))
struct RpWorldChunkInfoSector
{
RwInt32 matListWindowBase;
@@ -3655,10 +3656,11 @@ struct RpWorldChunkInfoSector
RwInt32 numVertices;
RwV3d inf;
RwV3d sup;
- RwBool collSectorPresent;
+ RwBool collSectorPresent; /* unused but retains same struct size */
RwBool unused;
};
+
typedef struct RpPlaneSectorChunkInfo RpPlaneSectorChunkInfo;
typedef struct RpPlaneSectorChunkInfo _rpPlaneSector;
@@ -3681,6 +3683,26 @@ struct RpWorldChunkInfo
RwV3d invWorldOrigin;
+ RwInt32 numPolygons;
+ RwInt32 numVertices;
+ RwInt32 numPlaneSectors;
+ RwInt32 numWorldSectors;
+ RwInt32 colSectorSize;
+
+ RwInt32 format; /* Flags about the world */
+
+ /* Added in 34003 */
+ RwBBox boundingBox;
+};
+
+typedef struct rpWorldChunkInfo34000 rpWorldChunkInfo34000;
+
+struct rpWorldChunkInfo34000
+{
+ RwBool rootIsWorldSector;
+
+ RwV3d invWorldOrigin;
+
RwSurfaceProperties surfaceProps;
RwInt32 numPolygons;
@@ -3691,6 +3713,7 @@ struct RpWorldChunkInfo
RwInt32 format; /* Flags about the world */
};
+#endif /* (!defined(DOXYGEN)) */
/****************************************************************************
Function prototypes
diff --git a/sdk/rwsdk/include/d3d8/rt2d.h b/sdk/rwsdk/include/d3d8/rt2d.h
index 5bf1faea..0584d3a5 100644
--- a/sdk/rwsdk/include/d3d8/rt2d.h
+++ b/sdk/rwsdk/include/d3d8/rt2d.h
@@ -17,7 +17,7 @@
/**
* \defgroup rt2d Rt2d
- * \ingroup rttool
+ * \ingroup 2dtools
*
* 2D Rendering Toolkit for RenderWare.
*/
@@ -117,6 +117,7 @@
Includes
*/
+#include "rpworld.h"
#include "rt2d.rpe" /* automatically generated header file */
/****************************************************************************
@@ -132,6 +133,13 @@
#define Rt2dCTMReadMacro(_result) \
(RwMatrixCopy((_result), _rt2dCTMGet()), (_result))
+#if defined (GCN_DRVMODEL_H)
+ #define VERTEXCACHESIZE 64
+#else
+ #define VERTEXCACHESIZE 256
+#endif
+
+
/****************************************************************************
Global Types
*/
@@ -152,16 +160,21 @@ typedef struct rt2dShadeParameters rt2dShadeParameters;
* rt2dShadeParameters
* describes Shade Parameters
*/
+
+#if (!defined(DOXYGEN))
struct rt2dShadeParameters
{
RwRGBAReal col; /* col */
RwV2d uv; /* uv */
};
+#endif /* (!defined(DOXYGEN)) */
/**
* \ingroup rt2ddatatypes
- * \typedef Rt2dBrush
- * typedef for a structure describing a Brush (opaque)
+ * \struct Rt2dBrush
+ * Brush object.
+ * This should be considered an opaque type.
+ * Use Rt2dBrush API functions to access.
*/
typedef struct Rt2dBrush Rt2dBrush;
@@ -169,35 +182,37 @@ typedef struct Rt2dBrush Rt2dBrush;
* Rt2dBrush
* structure describing a Brush
*/
-#if defined (GCN_DRVMODEL_H)
- #define VERTEXCACHESIZE 64
-#else
- #define VERTEXCACHESIZE 256
-#endif
-
+#if (!defined(DOXYGEN))
struct Rt2dBrush
{
- RWIM3DVERTEX vertex[VERTEXCACHESIZE];
rt2dShadeParameters top;
rt2dShadeParameters dtop;
rt2dShadeParameters bottom;
rt2dShadeParameters dbottom;
- RwInt32 calcFields;
+ RwRGBA colorCache;
+ RwInt32 flag;
RwTexture *texture;
+ RpMaterial *material;
RwReal halfwidth;
+ RwInt32 refCount;
};
+#endif /* (!defined(DOXYGEN)) */
/**
* \ingroup rt2ddatatypes
- * \typedef Rt2dPath
- * typedef for a structure describing a Path (opaque)
+ * \struct Rt2dPath
+ * Path object.
+ * This should be considered an opaque type.
+ * Use Rt2dPath API functions to access.
*/
typedef struct Rt2dPath Rt2dPath;
/**
* \ingroup rt2ddatatypes
- * \typedef Rt2dFont
- * typedef for a structure describing a Font (opaque)
+ * \struct Rt2dFont
+ * Font object.
+ * This should be considered an opaque type.
+ * Use Rt2dFont API functions to access.
*/
typedef struct Rt2dFont Rt2dFont;
@@ -206,11 +221,6 @@ typedef struct Rt2dFont Rt2dFont;
*/
typedef struct _rt2dFontDictionaryNode _rt2dFontDictionaryNode;
-/**
- * \ingroup rt2ddatatypes
- * \typedef Rt2dBBox
- * typedef for a structure describing a Bounding Box
- */
typedef struct Rt2dBBox Rt2dBBox;
/**
@@ -228,8 +238,8 @@ struct Rt2dBBox
/**
* \ingroup rt2ddatatypes
- * \typedef Rt2dObject
- * typedef for a structure describing a 2d Object
+ * \struct Rt2dObject
+ * Structure describing a 2d Object
* This should be considered an opaque type.
* Use Rt2dObject, Rt2dScene, Rt2dShape, Rt2dPickRegion or Rt2dObjectString
* API functions to access.
@@ -246,6 +256,7 @@ typedef struct _rt2dScene _rt2dScene;
*/
typedef struct _rt2dDepthOfObject _rt2dDepthOfObject;
+#if (!defined(DOXYGEN))
/*
* typedef for a structure describing the depth of an object
*/
@@ -265,15 +276,47 @@ struct _rt2dScene
RwSList *depths; /* depths for depthsort */
RwBool isDirtyDepths; /* depthsort needs updating */
};
+#endif /* (!defined(DOXYGEN)) */
/*
* typedef for a structure describing a shape (opaque)
*/
typedef struct _rt2dShape _rt2dShape;
+#if (!defined(DOXYGEN))
+typedef struct _rt2dShapeRep _rt2dShapeRep;
+struct _rt2dShapeRep
+{
+ RwSList *nodes; /* individual stroked/filled regions of the shape */
+ RwUInt32 refCount; /* number of shapes referencing this rep */
+ RpGeometry *geometry; /* Shareable geometry */
+};
+
+extern _rt2dShapeRep *
+ _rt2dShapeRepCreate();
+
+extern RwBool
+_rt2dShapeRepDestroy(_rt2dShapeRep *);
+
+extern RwUInt32
+_rt2dShapeRepAddRef(_rt2dShapeRep *);
+
+typedef struct _rt2dSceneResourcePool _rt2dSceneResourcePool;
+struct _rt2dSceneResourcePool
+{
+ _rt2dShapeRep **shapeReps;
+ RwUInt32 numShapeReps;
+};
+
+extern RwBool
+_rt2dSceneResourcePoolFindShapeRep(const _rt2dSceneResourcePool * pool,
+ const _rt2dShapeRep * rep, RwInt32 * npIndex);
+
struct _rt2dShape
{
- RwSList *nodes; /* individual stroked/filled regions of the shape */
+ _rt2dShapeRep *rep;
+ RwRGBA *colorCache; /* Shape's color cache */
+ RpAtomic *atomic; /* Atomic repn */
};
/*
@@ -295,6 +338,7 @@ struct _rt2dPickRegion
/*
* structure describing a renderable text string
*/
+
struct _rt2dObjectString
{
RwChar *textString; /* Text string to be rendered */
@@ -303,6 +347,7 @@ struct _rt2dObjectString
RwReal height; /* Font rendering Height */
_rt2dFontDictionaryNode *font; /* Dictionary node identifying font to be used */
};
+#endif /* (!defined(DOXYGEN)) */
/*
* typedef for a renderable string
@@ -324,6 +369,7 @@ enum Rt2dObjectTypeEnum {
typedef union _rt2dObjectdata _rt2dObjectdata;
+#if (!defined(DOXYGEN))
union _rt2dObjectdata
{
_rt2dShape shape;
@@ -335,11 +381,13 @@ union _rt2dObjectdata
/*
* A base structure for forming a hierarchy of 2D shapes
*/
-#if (!defined(DOXYGEN))
-#define Rt2dObjectIsLocked 0x00000001
-#define Rt2dObjectDirtyLTM 0x00000002
-#define Rt2dObjectVisible 0x00000004
+#define Rt2dObjectIsLocked 0x00000001
+#define Rt2dObjectDirtyLTM 0x00000002
+#define Rt2dObjectVisible 0x00000004
+#define Rt2dObjectDirtyColor 0x00000008
+
+#define Rt2dObjectStringGotNoFonts 0x01000000
struct Rt2dObject
{
@@ -357,13 +405,37 @@ struct Rt2dObject
/**
* \ingroup rt2ddatatypes
- * \typedef Rt2dObjectCallBack
- * typedef for a callback on an object
+ * \ref Rt2dObjectCallBack
+ * typedef for a callback on an object in a collection
+ *
+ * \param object is a specific object
+ * \param parent is the containing scene
+ * \param data is user data
+ *
+ * \return return value is ignored
*/
typedef Rt2dObject *(* Rt2dObjectCallBack)(Rt2dObject *object, Rt2dObject *parent, void *data);
/**
* \ingroup rt2ddatatypes
+ * \ref Rt2dFontCallBackRead
+ * Rt2dFontCallBackRead represents the function used by Rt2dFontRead to read
+ * the specified font from a disk file. This function should return a
+ * pointer to the font to indicate success. The returned font is owned by
+ * the Rt2d internal font dictionary, and is destroyed on calling
+ * \ref Rt2dClose
+ *
+ * \param name is the name of the font to read
+ *
+ * \return return the font if successful, NULL otherwise
+ *
+ * \see Rt2dFontSetReadCallBack
+ * \see Rt2dFontGetReadCallBack
+ */
+typedef Rt2dFont*(* Rt2dFontCallBackRead)(const RwChar *name);
+
+/**
+ * \ingroup rt2ddatatypes
* \ref Rt2dJustificationType
* enumeration describing Justification
*/
@@ -381,6 +453,20 @@ enum Rt2dJustificationType
*/
typedef enum Rt2dJustificationType Rt2dJustificationType;
+/**
+ * \ingroup rt2ddatatypes
+ * \ref Rt2dShapeNodeFlag
+ * Passed to \ref Rt2dShapeAddNode, these flags specify
+ * the type and properties of the path.
+ */
+enum Rt2dShapeNodeFlag
+{
+ rt2dSHAPENODEFLAGNONE = 0x0000,
+ rt2dSHAPENODEFLAGSOLID = 0x0001, /**< Shape's node is a solid, not outline */
+ rt2dSHAPENODEFLAGFORCEENUMSIZEINT = RWFORCEENUMSIZEINT /* Ensure sizeof(enum) == sizeof(RwInt32) */
+};
+
+
#if (! ( defined(RWDEBUG) || defined(RWSUPPRESSINLINE) ))
#define Rt2dBrushSetWidth(_brush, _width) \
@@ -397,7 +483,20 @@ typedef enum Rt2dJustificationType Rt2dJustificationType;
/****************************************************************************
Function prototypes
*/
+extern void
+Rt2dBrushSetFreeListCreateParams( RwInt32 blockSize, RwInt32 numBlocksToPrealloc );
+
+extern void
+Rt2dFontSetFreeListCreateParams( RwInt32 blockSize, RwInt32 numBlocksToPrealloc );
+
+extern void
+Rt2dFontDictNodeSetFreeListCreateParams( RwInt32 blockSize, RwInt32 numBlocksToPrealloc );
+extern void
+Rt2dObjectSetFreeListCreateParams( RwInt32 blockSize, RwInt32 numBlocksToPrealloc );
+
+extern void
+Rt2dPathSetFreeListCreateParams( RwInt32 blockSize, RwInt32 numBlocksToPrealloc );
/*
* INITIALIZE
@@ -407,6 +506,13 @@ Rt2dOpen(RwCamera *cam);
extern void
Rt2dClose(void);
+
+extern void
+Rt2dTriVertSetFreeListCreateParams( RwInt32 blockSize, RwInt32 numBlocksToPrealloc );
+
+extern void
+Rt2dTriPolySetFreeListCreateParams( RwInt32 blockSize, RwInt32 numBlocksToPrealloc );
+
/*
* PATHS
*/
@@ -518,6 +624,12 @@ Rt2dFontSetPath(const RwChar *path);
extern Rt2dFont *
Rt2dFontRead(const RwChar *name);
+extern RwBool
+Rt2dFontSetReadCallBack(Rt2dFontCallBackRead fpCallBack);
+
+extern Rt2dFontCallBackRead
+Rt2dFontGetReadCallBack (void);
+
extern RwUInt32
_rt2dFontStreamGetSize(Rt2dFont *font);
@@ -695,6 +807,10 @@ Rt2dObjectIsObjectString(Rt2dObject *object);
extern Rt2dObject *
Rt2dObjectCopy(Rt2dObject *dst, Rt2dObject *src);
+/* in-place dst version, destruction not req */
+extern Rt2dObject *
+_rt2dObjectCopy(Rt2dObject *dst, Rt2dObject *src);
+
/*
* HIERARCHICAL SCENE FUNCTIONS - SCENE
*/
@@ -766,14 +882,8 @@ Rt2dShapeCreate(void);
extern RwBool
Rt2dShapeDestroy(Rt2dObject * shape);
-extern Rt2dBrush *
-Rt2dShapeGetNewBrush(Rt2dObject *shape);
-
-extern Rt2dPath *
-Rt2dShapeGetNewPath(Rt2dObject *shape);
-
extern Rt2dObject *
-Rt2dShapeAddNode(Rt2dObject *shape, Rt2dPath *path, Rt2dBrush *fill, Rt2dBrush *stroke );
+Rt2dShapeAddNode(Rt2dObject *shape, RwUInt32 flag, Rt2dPath *path, Rt2dBrush *brush );
extern RwInt32
Rt2dShapeGetNodeCount(Rt2dObject *shape);
@@ -792,9 +902,15 @@ Rt2dShapeRender(Rt2dObject *object);
extern Rt2dObject *
Rt2dShapeMorph(Rt2dObject *result,
- Rt2dObject *source,
- Rt2dObject *destination,
- RwReal alpha);
+ Rt2dObject *source,
+ Rt2dObject *destination,
+ RwReal alpha);
+
+extern Rt2dObject *
+Rt2dShapeLock(Rt2dObject * shape);
+
+extern Rt2dObject *
+Rt2dShapeUnlock(Rt2dObject * shape);
/*
* HIERARCHICAL SCENE FUNCTIONS - PICK REGION
@@ -895,6 +1011,7 @@ Rt2dCTMRead(RwMatrix * result);
#endif /* ( defined(RWDEBUG) || defined(RWSUPPRESSINLINE) ) */
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/sdk/rwsdk/include/d3d8/rt2d.rpe b/sdk/rwsdk/include/d3d8/rt2d.rpe
index 1f9f8881..b18db155 100644
--- a/sdk/rwsdk/include/d3d8/rt2d.rpe
+++ b/sdk/rwsdk/include/d3d8/rt2d.rpe
@@ -150,476 +150,11 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
enum e_rwdb_Criterion2D
{
+E_RW_FONTNOTFOUND,
e_rwdb_Criterion2DLAST = RWFORCEENUMSIZEINT
};
diff --git a/sdk/rwsdk/include/d3d8/rt2danim.h b/sdk/rwsdk/include/d3d8/rt2danim.h
index cd593a8e..996262af 100644
--- a/sdk/rwsdk/include/d3d8/rt2danim.h
+++ b/sdk/rwsdk/include/d3d8/rt2danim.h
@@ -10,8 +10,8 @@
#define RT2DANIM_H
/**
- * \defgroup rt2danim Rt2dAnim
- * \ingroup rttool
+ * \defgroup rt2danim Rt2dAnim (inc. Maestro)
+ * \ingroup 2dtools
*
* A toolkit to coordinate the display, storage and manipulation of 2D
* animations.
@@ -166,101 +166,132 @@ typedef enum Rt2dStringLabelType Rt2dStringLabelType;
/**
* \ingroup rt2danimsub
- * \typedef Rt2dAnimProps
- * typedef for a structure describing the current state of a scene (opaque)
+ * \struct Rt2dAnimProps
+ * Structure describing the current state of a scene.
+ * This should be considered an opaque type. Use the
+ * Rt2dAnim API functions to access.
*/
typedef struct Rt2dAnimProps Rt2dAnimProps;
/**
* \ingroup rt2danimsub
- * \typedef Rt2dKeyFrameList
- * typedef for a structure describing a list of keyframes
+ * \struct Rt2dKeyFrameList
+ * Structure describing an entire list of keyframes
+ * This should be considered an opaque type. Use the
+ * Rt2dKeyFrameList API functions to access.
*/
typedef struct Rt2dKeyFrameList Rt2dKeyFrameList;
/**
* \ingroup rt2danimsub
- * \typedef Rt2dAnimObjectUpdate
- * typedef for a structure describing a set of changes to a 2d object (opaque)
+ * \struct Rt2dKeyFrameSet
+ * structure describing a set of keyframe actions to be applied to a 2D object.
+ * This should be considered an opaque type. Use the
+ * Rt2dAnim API functions to access.
*/
-typedef struct Rt2dAnimObjectUpdate Rt2dAnimObjectUpdate;
+typedef struct Rt2dKeyFrameSet Rt2dKeyFrameSet;
/**
* \ingroup rt2danimsub
- * \typedef Rt2dKeyFrameTransform
- * typedef for a structure describing a transform change to a 2d object (opaque)
+ * \struct Rt2dAnimObjectUpdate
+ * Structure describing an unoptimized update to an object
+ * This should be considered an opaque type. Use the
+ * Rt2dAnim API functions to access.
*/
-typedef struct Rt2dKeyFrameTransform Rt2dKeyFrameTransform;
+typedef struct Rt2dAnimObjectUpdate Rt2dAnimObjectUpdate;
/**
* \ingroup rt2danimsub
- * \typedef Rt2dKeyFrameColor
- * typedef for a structure describing a color change to a 2d object (opaque)
+ * \struct Rt2dKeyFrameTransform
+ * Structure describing a transform change to a 2d object.
+ * This should be considered an opaque type. Use the
+ * Rt2dAnim API functions to access.
+ */
+typedef struct Rt2dKeyFrameTransform Rt2dKeyFrameTransform;
+
+/*
+ * Typedef for struct Rt2dKeyFrameColor describing a color
+ * change to a 2d object.
*/
typedef struct Rt2dKeyFrameColor Rt2dKeyFrameColor;
-/**
- * \ingroup rt2danimsub
- * \typedef Rt2dKeyFrameShow
- * typedef for a structure describing a displayable or depth change to a 2d object (opaque)
+/*
+ * Structure describing a displayable or depth change to a 2d object.
*/
typedef struct Rt2dKeyFrameShow Rt2dKeyFrameShow;
-/**
- * \ingroup rt2danimsub
- * \typedef Rt2dKeyFrameMorph
- * typedef for a structure describing a morph change to a 2d object (opaque)
+/*
+ * Structure describing a morph change to a 2d object.
*/
typedef struct Rt2dKeyFrameMorph Rt2dKeyFrameMorph;
/**
* \ingroup rt2danimsub
- * \typedef Rt2dAnim
- * typedef for a structure describing a 2d animation (opaque)
+ * \struct Rt2dAnim
+ * Structure describing a 2d animation.
+ * This should be considered an opaque type. Use the
+ * Rt2dAnim API functions to access.
*/
typedef struct Rt2dAnim Rt2dAnim;
/**
* \ingroup rt2dbutton
- * \typedef Rt2dButton
- * typedef for a structure describing a button (opaque)
+ * \struct Rt2dButton
+ * Structure describing a button.
+ * This should be considered an opaque type. Use the
+ * Rt2dButton API functions to access.
*/
typedef struct Rt2dButton Rt2dButton;
/**
* \ingroup rt2dcel
- * \typedef Rt2dCel
- * typedef for a structure describing a cel (opaque)
+ * \struct Rt2dCel
+ * Structure describing a cel.
+ * This should be considered an opaque type. Use the
+ * Rt2dCel API functions to access.
*/
typedef struct Rt2dCel Rt2dCel;
/**
* \ingroup rt2dcel
- * \typedef Rt2dCelList
- * typedef for a structure describing a cel list (opaque)
+ * \struct Rt2dCelList
+ * Structure describing a cel list.
+ * This should be considered an opaque type. Use the
+ * Rt2dCel API functions to access.
*/
typedef struct Rt2dCelList Rt2dCelList;
/**
* \ingroup rt2dmaestro
- * \typedef Rt2dMaestro
- * typedef for a structure describing a maestro (opaque)
+ * \struct Rt2dMaestro
+ * Structure describing a maestro.
+ * This should be considered an opaque type. Use the
+ * Rt2dMaestro API functions to access.
*/
typedef struct Rt2dMaestro Rt2dMaestro;
-/**
- * \ingroup rt2dmessage
- * \typedef Rt2dMessage
- * typedef for a structure describing a message (opaque)
+/*
+ * Structure describing a message.
*/
typedef struct Rt2dMessage Rt2dMessage;
+/**
+ * \ingroup rt2dmessage
+ * \struct Rt2dMessageList
+ * Structure describing a message.
+ * This should be considered an opaque type. Use the
+ * Rt2dMessage API functions to access.
+ */
typedef struct Rt2dMessageList Rt2dMessageList;
/**
* \ingroup rt2dstringlabel
- * \typedef Rt2dStringLabel
- * typedef for a structure describing a string label (opaque)
+ * \struct Rt2dStringLabel
+ * Structure used to store and access named data, either internal or user.
+ * A type and a name may be used to access internal and user data.
+ *
+ * This should be considered an opaque type. Use the
+ * Rt2dStringLabel API functions to access.
*/
typedef struct Rt2dStringLabel Rt2dStringLabel;
@@ -277,7 +308,8 @@ struct Rt2dKeyFrameTransform
/**
* \ingroup rt2danimsub
* \struct Rt2dKeyFrameColor
- * structure describing a color setting action
+ * Structure describing a color
+ * change to a 2d object.
*/
struct Rt2dKeyFrameColor
{
@@ -287,7 +319,7 @@ struct Rt2dKeyFrameColor
/**
* \ingroup rt2danimsub
* \struct Rt2dKeyFrameShow
- * structure describing a show/hide action
+ * Structure describing a show/hide change and a depth change to a 2d object.
*/
struct Rt2dKeyFrameShow
{
@@ -299,7 +331,7 @@ struct Rt2dKeyFrameShow
/**
* \ingroup rt2danimsub
* \struct Rt2dKeyFrameMorph
- * structure describing a morph action
+ * Structure describing a morph change to a 2d object.
*/
struct Rt2dKeyFrameMorph
{
@@ -355,69 +387,73 @@ MACRO_START \
} \
MACRO_STOP
-/**
- * \ingroup rt2dstringlabel
- * \struct Rt2dStringLabel
- * structure containing label information. The enitityType identifies the type
+/*
+ * structure containing label information. The entityType identifies the type
* of the label. The label's name is stored as an index
* in common storage area. The entityType and name of the label are used as keys
* during a search. Additional internal and user data can be stored with the
* label.
*/
+
+#if (!defined(DOXYGEN))
struct Rt2dStringLabel
{
- RwUInt32 entityType; /**< type of the label
- (\ref Rt2dStringLabelType) */
- RwInt32 nameIndex; /**< index of name in internal data
+ RwUInt32 entityType; /* type of the label
+ (see Rt2dStringLabelType) */
+ RwInt32 nameIndex; /* index of name in internal data
area */
- void *internalData; /**< internal data */
- void *userData; /**< customizable data */
+ void *internalData; /* internal data */
+ void *userData; /* customizable data */
};
+#endif /* (!defined(DOXYGEN)) */
+
#define _rt2dStringLabelGetStringLabelTypeMacro(_strLabel) \
- ((_strLabel)->entityType);
+ ((_strLabel)->entityType)
#define _rt2dStringLabelSetStringLabelTypeMacro(_strLabel, _entityType) \
- ((_strLabel)->entityType = (_entityType));
+ ((_strLabel)->entityType = (_entityType))
#define _rt2dStringLabelGetNameIndexMacro(_strLabel) \
- ((_strLabel)->nameIndex);
+ ((_strLabel)->nameIndex)
#define _rt2dStringLabelSetNameIndexMacro(_strLabel, _index) \
- ((_strLabel)->nameIndex = (_index));
+ ((_strLabel)->nameIndex = (_index))
#define _rt2dStringLabelGetInternalDataMacro(_strLabel) \
- ((_strLabel)->internalData);
+ ((_strLabel)->internalData)
#define _rt2dStringLabelSetInternalDataMacro(_strLabel, _internalData) \
- ((_strLabel)->internalData = (_internalData));
+ ((_strLabel)->internalData = (_internalData))
#define _rt2dStringLabelGetUserDataMacro(_strLabel) \
- ((_strLabel)->userData);
+ ((_strLabel)->userData)
#define _rt2dStringLabelSetUserDataMacro(_strLabel, _userData) \
- ((_strLabel)->userData = (_userData));
+ ((_strLabel)->userData = (_userData))
-/**
- * \ingroup rt2dcel
- * \struct Rt2dCel
+/*
* structure containing cel information. The name of the cel is stored as an
* index into a label table. The buttons in the cel are stored as indices. These
- * reference a list of buttons held by the cel's parent maestro. Any messages
+ * reference a list of buttons held by the cel's parent maestro. Any messages
* to be process when the cel is active is stored as index into the parent's
* maestro's message storage area.
*/
+
+#if (!defined(DOXYGEN))
struct Rt2dCel
{
- RwInt32 strLabelIndex; /**< Frame label */
- RwInt32 celIndex; /**< Frame number */
- RwSList *buttonIndices; /**< List of buttons active in
- this frame */
- RwInt32 messageListIndex; /**< Messages to be posted after
- displaying this frame */
+ RwInt32 strLabelIndex; /* Frame label */
+ RwInt32 celIndex; /* Frame number */
+ RwSList *buttonIndices; /* List of buttons active in
+ this frame */
+ RwInt32 messageListIndex; /* Messages to be posted after
+ displaying this frame */
};
+#endif /* (!defined(DOXYGEN)) */
+
#define _rt2dCelGetStringLabelIndexMacro(_cel) \
((_cel)->strLabelIndex);
@@ -443,14 +479,16 @@ typedef Rt2dAnim *(*Rt2dAnimCallBack)(Rt2dAnim *object,
void *data);
/**
* \ingroup rt2danimsub
- * \typedef Rt2dKeyFrameListCallBack
+ * \ref Rt2dKeyFrameListCallBack
* This typedef defines a callback function to apply to a frame list.
*
- * \param anim Pointer to the animation
- * \param props Pointer to the props that the animation acts upon
- * \param keyframeList The key frame list
+ * \param anim Pointer to the animation
+ * \param props Pointer to the props that the animation acts upon
+ * \param keyframeList The key frame list
* \param keyframeListTime The key frame list time
- * \param data User defined data
+ * \param data User defined data
+ *
+ * \return return value is ignored
*/
typedef Rt2dKeyFrameList *(Rt2dKeyFrameListCallBack)(
Rt2dAnim *anim,
@@ -461,12 +499,14 @@ typedef Rt2dKeyFrameList *(Rt2dKeyFrameListCallBack)(
/**
* \ingroup rt2danimsub
- * \typedef Rt2dAnimOnEndReachedCallBack
+ * \ref Rt2dAnimOnEndReachedCallBack
* This typedef defines a callback function called at the end of an animation.
*
- * \param anim Pointer to the animation ending
- * \param props Pointer to the props that the animation acts upon
+ * \param anim Pointer to the animation ending
+ * \param props Pointer to the props that the animation acts upon
* \param remainingDeltaTime Remaining time
+ *
+ * \return return value is ignored
*/
typedef Rt2dAnim *(*Rt2dAnimOnEndReachedCallBack)(Rt2dAnim *anim,
Rt2dAnimProps *props,
@@ -474,14 +514,14 @@ typedef Rt2dAnim *(*Rt2dAnimOnEndReachedCallBack)(Rt2dAnim *anim,
/**
* \ingroup rt2dmaestro
- * \typedef Rt2dMaestroAnimationsCallBack
+ * \ref Rt2dMaestroAnimationsCallBack
* \ref Rt2dMaestroAnimationsCallBack represents the function called from
* \ref Rt2dMaestroForAllAnimations for all animations in the maestro.
* This function
* should return the current maestro to indicate success. The callback may
* return NULL to terminate further callbacks on the maestro.
*
- * \param maestro Pointer to parent maestro.
+ * \param maestro Pointer to parent maestro.
* \param anim Pointer to the animation.
* \param props Pointer to the anim's props.
* \param pData Pointer to private data.
@@ -494,7 +534,6 @@ typedef Rt2dMaestro *(*Rt2dMaestroAnimationsCallBack)
/**
* \ingroup rt2dmessage
- * \typedef Rt2dMessageHandlerCallBack
* \ref Rt2dMessageHandlerCallBack represents the function called from
* \ref Rt2dMaestroProcessMessages for all messages in the maestro's
* process message queue. The maestro does not filter any messages. The
@@ -504,7 +543,7 @@ typedef Rt2dMaestro *(*Rt2dMaestroAnimationsCallBack)
* callback may return NULL to terminate further callbacks on the maestro.
*
* \param maestro Pointer to parent maestro.
- * \param message Pointer to the message.
+ * \param message Pointer to the message.
*
* \return Pointer to the message.
*/
@@ -531,6 +570,18 @@ typedef Rt2dMessage *
*/
/*
+ * Toolkit-level initialization / finalization
+ */
+/*
+ * INITIALIZE
+ */
+extern void
+Rt2dAnimOpen(void);
+
+extern void
+Rt2dAnimClose(void);
+
+/*
* Rt2dAnim
*/
@@ -747,7 +798,7 @@ Rt2dMaestroAddButton(Rt2dMaestro *maestro, RwInt32 strLabelIdx, RwInt32 objectId
extern Rt2dCel *
Rt2dCelCreate(Rt2dMaestro *maestro,
- RwChar *name,
+ const RwChar *name,
RwInt32 celIndex, RwInt32 messageListIndex);
extern Rt2dCelList *
@@ -966,7 +1017,7 @@ Rt2dMessageHandlerDefaultCallBack(Rt2dMaestro *maestro, Rt2dMessage *message);
*/
extern Rt2dStringLabel *
Rt2dMaestroFindStringLabel(Rt2dMaestro *maestro,
- Rt2dStringLabelType entityType, RwChar *lookupName,
+ Rt2dStringLabelType entityType, const RwChar *lookupName,
RwInt32 *index);
extern Rt2dStringLabel *
@@ -974,7 +1025,7 @@ Rt2dMaestroGetStringLabelByIndex(Rt2dMaestro *maestro, RwInt32 index);
extern Rt2dMaestro *
Rt2dMaestroAddStringLabel(Rt2dMaestro *maestro,
- Rt2dStringLabelType entityType, RwChar *name,
+ Rt2dStringLabelType entityType, const RwChar *name,
void *internalData, RwInt32 *index);
extern const RwChar *
@@ -985,28 +1036,28 @@ Rt2dMaestroGetStringLabelName(Rt2dMaestro *maestro,
#if !(defined(RWDEBUG) || defined(RWSUPPRESSINLINE))
#define Rt2dStringLabelGetStringLabelType(_strLabel) \
- _rt2dStringLabelGetStringLabelTypeMacro((_strLabel));
+ _rt2dStringLabelGetStringLabelTypeMacro((_strLabel))
#define Rt2dStringLabelSetStringLabelType(_strLabel, _entityType) \
- _rt2dStringLabelSetStringLabelTypeMacro((_strLabel), (_entityType));
+ _rt2dStringLabelSetStringLabelTypeMacro((_strLabel), (_entityType))
#define Rt2dStringLabelGetNameIndex(_strLabel) \
- _rt2dStringLabelGetNameIndexMacro((_strLabel));
+ _rt2dStringLabelGetNameIndexMacro((_strLabel))
#define Rt2dStringLabelSetNameIndex(_strLabel, _index) \
- _rt2dStringLabelSetNameIndexMacro((_strLabel), (_index));
+ _rt2dStringLabelSetNameIndexMacro((_strLabel), (_index))
#define Rt2dStringLabelGetInternalData(_strLabel) \
- _rt2dStringLabelGetInternalDataMacro((_strLabel));
+ _rt2dStringLabelGetInternalDataMacro((_strLabel))
#define Rt2dStringLabelSetInternalData(_strLabel, _internalData) \
- _rt2dStringLabelSetInternalDataMacro((_strLabel), (_internalData));
+ _rt2dStringLabelSetInternalDataMacro((_strLabel), (_internalData))
#define Rt2dStringLabelGetUserData(_strLabel) \
- _rt2dStringLabelGetUserDataMacro((_strLabel));
+ _rt2dStringLabelGetUserDataMacro((_strLabel))
#define Rt2dStringLabelSetUserData(_strLabel, _userData) \
- _rt2dStringLabelSetUserDataMacro((_strLabel), (_userData));
+ _rt2dStringLabelSetUserDataMacro((_strLabel), (_userData))
#else /* !(defined(RWDEBUG) || defined(RWSUPPRESSINLINE)) */
diff --git a/sdk/rwsdk/include/d3d8/rt2danim.rpe b/sdk/rwsdk/include/d3d8/rt2danim.rpe
index 82a9dac9..0e61ec5c 100644
--- a/sdk/rwsdk/include/d3d8/rt2danim.rpe
+++ b/sdk/rwsdk/include/d3d8/rt2danim.rpe
@@ -150,480 +150,14 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-enum rwPLUGIN_ERRENUM
+enum e_rwdb_Criterion2DAnim
{
- rwPLUGIN_ERRENUMLAST = RWFORCEENUMSIZEINT
+ e_rwdb_Criterion2DAnimLAST = RWFORCEENUMSIZEINT
};
-typedef enum rwPLUGIN_ERRENUM rwPLUGIN_ERRENUM;
+typedef enum e_rwdb_Criterion2DAnim e_rwdb_Criterion2DAnim;
diff --git a/sdk/rwsdk/include/d3d8/rtanim.h b/sdk/rwsdk/include/d3d8/rtanim.h
new file mode 100644
index 00000000..4def7f1f
--- /dev/null
+++ b/sdk/rwsdk/include/d3d8/rtanim.h
@@ -0,0 +1,638 @@
+#ifndef RTANIM_H
+#define RTANIM_H
+
+#include <rtanim.rpe> /* automatically generated header file */
+
+#define rtANIMSTREAMCURRENTVERSION 0x100
+
+/* Doxygen plugin groups. */
+
+/**
+ * \defgroup rtanim RtAnim
+ * \ingroup animtools
+ *
+ * Animation Toolkit for RenderWare Graphics.
+ */
+
+/**
+ * \ingroup rtanim
+ * Typedef for struct \ref RtAnimAnimation.
+ */
+typedef struct RtAnimAnimation RtAnimAnimation;
+
+/*
+ * The following CallBacks are needed for each interpolation scheme.
+ * See RtAnimInterpolatorInfo.
+ */
+
+/**
+ * \ingroup rtanim
+ * \ref RtAnimKeyFrameApplyCallBack
+ * defines a callback function for converting
+ * an interpolated animation keyframe into the required result.
+ *
+ * \param result Void pointer to store the output of the conversion.
+ * \param voidIFrame Void pointer to the keyframe and should be cast
+ * to the interpolated keyframe type this callback
+ * is for.
+ */
+typedef void (*RtAnimKeyFrameApplyCallBack) (void *result, void *voidIFrame);
+
+/**
+ * \ingroup rtanim
+ * \ref RtAnimKeyFrameBlendCallBack
+ * defines a callback function for blending between two
+ * interpolated keyframes by the given blend factor. This is used for
+ * blending the states of two different \ref RtAnimInterpolator objects.
+ * The \ref RtAnimKeyFrameInterpolateCallBack is used for interpolating
+ * actual animation keyframes into an interpolated frame.
+ *
+ * \param voidOut Void pointer to store the output of the blend.
+ * \param voidIn1 Void pointer containing the first input
+ * interpolated keyframe.
+ * \param voidIn2 Void pointer containing the second input
+ * interpolated keyframe.
+ * \param alpha \ref RwReal containing the blend factor.
+ */
+typedef void (*RtAnimKeyFrameBlendCallBack) (void *voidOut, void *voidIn1,
+ void *voidIn2, RwReal alpha);
+
+/**
+ * \ingroup rtanim
+ * \ref RtAnimKeyFrameInterpolateCallBack
+ * defines a callback function for interpolating between two
+ * animation keyframes according to the given time. The output is
+ * an interpolated frame object residing in an \ref RtAnimInterpolator
+ * and will usually have the same structure as the keyframe apart from
+ * the header data (\ref RtAnimInterpFrameHeader).
+ *
+ * \param voidOut Void pointer for the output of the interpolation.
+ * \param voidIn1 Void pointer containing the first input keyframe.
+ * \param voidIn2 Void pointer containing the second input keyframe.
+ * \param time \ref RwReal containing the time at which to interpolate.
+ */
+typedef void (*RtAnimKeyFrameInterpolateCallBack) (void *voidOut, void *voidIn1,
+ void *voidIn2, RwReal time);
+
+/**
+ * \ingroup rtanim
+ * \ref RtAnimKeyFrameAddCallBack
+ * defines a callback function for adding two interpolated
+ * keyframes together. This is used when adding the states of two
+ * \ref RtAnimInterpolator objects, such as when adding a delta animation
+ * to a base animation.
+ *
+ * \param voidOut Void pointer for the output interpolated frame.
+ * \param voidIn1 Void pointer containing the first input
+ * interpoalted keyframe.
+ * \param voidIn2 Void pointer containing the second input
+ * interpolated keyframe.
+ */
+typedef void (*RtAnimKeyFrameAddCallBack) (void *voidOut, void *voidIn1,
+ void *voidIn2);
+
+/**
+ * \ingroup rtanim
+ * \ref RtAnimKeyFrameMulRecipCallBack
+ * defines a callback function for multiplying a keyframe
+ * by the inverse of another keyframe. This is used for creating delta
+ * animations.
+ *
+ * \param voidFrame Void pointer for the keyframe to be modified.
+ * \param voidStart Void pointer for the start keyframe to take the reciprocal of.
+ */
+typedef void (*RtAnimKeyFrameMulRecipCallBack)
+ (void *voidFrame, void *voidStart);
+
+/**
+ * \ingroup rtanim
+ * \ref RtAnimKeyFrameStreamReadCallBack
+ * defines a callback function for reading in keyframes
+ * from an \ref RwStream for the given animation.
+ *
+ * \param stream Pointer to the \ref RwStream to read the keyframes from.
+ * \param animation Pointer to the \ref RtAnimAnimation to read the keyframes into.
+ *
+ * \return Pointer to the \ref RtAnimAnimation.
+ */
+typedef RtAnimAnimation * (*RtAnimKeyFrameStreamReadCallBack)
+ (RwStream *stream, RtAnimAnimation *animation);
+
+/**
+ * \ingroup rtanim
+ * \ref RtAnimKeyFrameStreamWriteCallBack
+ * defines a callback function for writing keyframes from the
+ * given animation to an \ref RwStream.
+ *
+ * \param animation Pointer to the \ref RtAnimAnimation to write out from.
+ * \param stream Pointer to the \ref RwStream to write the keyframes to.
+ *
+ * \return \ref RwBool, TRUE if successful.
+ */
+typedef RwBool (*RtAnimKeyFrameStreamWriteCallBack)
+ (RtAnimAnimation *animation, RwStream *stream);
+
+/**
+ * \ingroup rtanim
+ * \ref RtAnimKeyFrameStreamGetSizeCallBack
+ * defines a callback function for calculating the binary stream
+ * size of keyframe data within an animation.
+ *
+ * \param animation Pointer to the \ref RtAnimAnimation to calculate sizes from.
+ *
+ * \return \ref RwInt32 containing the size, in bytes, of the keyframe data.
+ */
+typedef RwInt32 (*RtAnimKeyFrameStreamGetSizeCallBack)
+ (RtAnimAnimation *animation);
+
+/**
+ * \ingroup rtanim
+ * \ref RtAnimInterpolatorInfo
+ * Typedef for struct \ref RtAnimInterpolatorInfo
+ */
+typedef struct RtAnimInterpolatorInfo RtAnimInterpolatorInfo;
+
+/**
+ * \ingroup rtanim
+ * \struct RtAnimInterpolatorInfo
+ * This structure is used to hold information for a keyframe interpolation scheme.
+ *
+ * \see RtAnimRegisterInterpolationScheme
+ * \see RtAnimGetInterpolatorInfo
+ */
+struct RtAnimInterpolatorInfo
+{
+ RwInt32 typeID;
+ /**< The ID of the interpolation scheme. */
+ RwInt32 keyFrameSize;
+ /**< Size, in bytes, of the keyframe structure. */
+ RtAnimKeyFrameApplyCallBack keyFrameApplyCB;
+ /**< Pointer to a function that converts a keyframe to the needed
+ * format. This function is never called from the \ref rtanim
+ * toolkit (as the toolit doesn't know the data layout of the
+ * results) but is stored to ease the creation of overloaded
+ * interpolators. */
+ RtAnimKeyFrameBlendCallBack keyFrameBlendCB;
+ /**< Pointer to a function that blends between two
+ * interpolated keyframes, for the purpose of blending
+ * between the states of two \ref RtAnimInterpolator objects. */
+ RtAnimKeyFrameInterpolateCallBack keyFrameInterpolateCB;
+ /**< Pointer to a function that interpolates between two keyframes
+ * for a given time in between. */
+ RtAnimKeyFrameAddCallBack keyFrameAddCB;
+ /**< Pointer to a function that adds two interpolated keyframes
+ * for the purpose of adding the states of two
+ * \ref RtAnimInterpolator objects. */
+ RtAnimKeyFrameMulRecipCallBack keyFrameMulRecipCB;
+ /**< Pointer to a function that multiplies a keyframe by the
+ * reciprocal of another. */
+ RtAnimKeyFrameStreamReadCallBack keyFrameStreamReadCB;
+ /**< Pointer to a function that reads the keyframes from a stream
+ * for a given animation. */
+ RtAnimKeyFrameStreamWriteCallBack keyFrameStreamWriteCB;
+ /**< Pointer to a function that writes the keyframes to a stream for
+ * a given animation. */
+ RtAnimKeyFrameStreamGetSizeCallBack keyFrameStreamGetSizeCB;
+ /**< Pointer to a function that returns the binary stream size of
+ * the keyframes for a given animation. */
+};
+
+
+/**
+ * \ingroup rtanim
+ * \struct RtAnimAnimation
+ * A keyframed animation consists of an array of keyframe structures,
+ * along with some flags and a duration.
+ *
+ * The keyframes should be presented in the order they are needed
+ * to animate forwards through time. That is, the next keyframe
+ * at some point in the sequence should correspond to the node whose
+ * previous two keyframes are next to expire as an interpolation
+ * pair.
+ *
+ * Put another way, the correct ordering can be achieved by sorting
+ * an unordered keyframe array using the following primary and secondary
+ * sort keys:-
+ *
+ * - time of previous keyframe for node
+ * - node index
+ *
+ * An example is shown in the following diagram, where each vertical bar
+ * indicates a keyframe point in time. The position of the keyframe
+ * within the animation sequence is shown by an index to the left of
+ * each bar.
+ *
+ * \verbatim
+
+ t=0 t=duration
+ node 0 kf0..| kf3.......| kf8....| kf10....|
+ node 1 kf1..| kf4...| kf6........| kf11....|
+ node 2 kf2..| kf5.....| kf7..| kf9.........|
+
+ \endverbatim
+ *
+ * Each node MUST have an initial keyframe at time = 0.0, and a terminal
+ * keyframe at time = duration of the animation.
+ *
+ * Pointers link all of the keyframes for a particular node backwards
+ * through time in a list.
+ *
+ * \see RtAnimAnimationCreate
+ */
+struct RtAnimAnimation
+{
+ RtAnimInterpolatorInfo *interpInfo;
+ /**< Pointer to interpolation scheme information */
+ RwInt32 numFrames;
+ /**< Number of keyframes in the animation */
+ RwInt32 flags;
+ /**< Specifies details about animation,
+ * relative translation modes etc. */
+ RwReal duration;
+ /**< Duration of animation in seconds */
+ void *pFrames;
+ /**< Pointer to the animation keyframes */
+};
+
+/**
+ * \ingroup rtanim
+ * \ref RtAnimKeyFrameHeader
+ * Typedef for struct RtAnimKeyFrameHeader
+ */
+typedef struct RtAnimKeyFrameHeader RtAnimKeyFrameHeader;
+
+/**
+ * \ingroup rtanim
+ * \struct RtAnimKeyFrameHeader
+ * holds header information for a keyframe. All keyframe structures used with
+ * the overloadable interpolation system should start with this data.
+ *
+ * \see RtAnimRegisterInterpolationScheme
+ */
+struct RtAnimKeyFrameHeader
+{
+ void *prevFrame;
+ /**< Previous keyframe for particular hierarchy node */
+ RwReal time;
+ /**< Time at keyframe */
+};
+
+/**
+ * \ingroup rtanim
+ * \ref RtAnimInterpFrameHeader
+ * Typedef for struct RtAnimInterpFrameHeader
+ */
+typedef struct RtAnimInterpFrameHeader RtAnimInterpFrameHeader;
+
+/**
+ * \ingroup rtanim
+ * \struct RtAnimInterpFrameHeader
+ * is the header for an interpolated animation frame, intermediate
+ * between a keyframe pair. This structure is intentionally the same size as an
+ * \ref RtAnimKeyFrameHeader, so that an interpolated frame and key frame data
+ * block can be otherwise identical. It relies on the
+ * fact that the prevFrame and time fields of a keyframe header are not
+ * relevant to an interpolated frame. These fields should therefore not be
+ * be modified by a custom keyframe interpolator.
+ *
+ * \see RtAnimRegisterInterpolationScheme
+ */
+struct RtAnimInterpFrameHeader
+{
+ RtAnimKeyFrameHeader *keyFrame1;
+ /**< Pointer to the first of the current pair of keyframes in
+ the associated \ref RtAnimAnimation */
+ RtAnimKeyFrameHeader *keyFrame2;
+ /**< Pointer to the second of the current pair of keyframes in
+ the associated \ref RtAnimAnimation */
+};
+
+/**
+ * \ingroup rtanim
+ * \ref RtAnimInterpolator
+ * Typedef for struct \ref RtAnimInterpolator
+ */
+typedef struct RtAnimInterpolator RtAnimInterpolator;
+
+/**
+ * \ingroup rtanim
+ * \ref RtAnimCallBack
+ * defines a callback function for use with the
+ * \ref RtAnimInterpolatorSetAnimCallBack and
+ * \ref RtAnimInterpolatorSetAnimLoopCallBack functions.
+ *
+ * \param animInstance
+ * A pointer to the \ref RtAnimInterpolator structure.
+ *
+ * \param data Void pointer for user-defined data.
+ * You can use this to pass your own data
+ * structure(s) to the callback function.
+ *
+ * \see RtAnimInterpolatorSetAnimCallBack
+ * \see RtAnimInterpolatorSetAnimLoopCallBack
+ *
+ */
+
+typedef RtAnimInterpolator * (*RtAnimCallBack)
+ (RtAnimInterpolator *animInstance,
+ void *data);
+
+/**
+ * \ingroup rtanim
+ * \struct RtAnimInterpolator
+ * holds the current state for a particular instance of an animation,
+ * corresponding to a specific point in time.
+ *
+ * The current interpolated keyframes are stored in an array after the
+ * end of this structure. For advanced use, these may be accessed
+ * using the macro rtANIMGETINTERPFRAME(interpolator, nodeIndex)
+ * which takes a pointer to the interpolator and the node index
+ * for the interpolated keyframe required.
+ *
+ * \see \ref RtAnimInterpolatorCreate
+ * \see \ref RtAnimInterpolatorDestroy
+ * \see \ref RtAnimInterpolatorSetCurrentAnim
+ * \see \ref RtAnimInterpolatorGetCurrentAnim
+ * \see \ref RtAnimInterpolatorSetKeyFrameCallBacks
+ * \see \ref RtAnimInterpolatorSetAnimLoopCallBack
+ * \see \ref RtAnimInterpolatorSetAnimCallBack
+ * \see \ref RtAnimInterpolatorCopy
+ * \see \ref RtAnimInterpolatorSubAnimTime
+ * \see \ref RtAnimInterpolatorAddAnimTime
+ * \see \ref RtAnimInterpolatorSetCurrentTime
+ * \see \ref RtAnimCallBack
+ */
+struct RtAnimInterpolator
+{
+ RtAnimAnimation *pCurrentAnim;
+ /**< Current \ref RtAnimAnimation applied */
+ RwReal currentTime;
+ /**< Current animation time */
+ void *pNextFrame;
+ /**< Next animation keyframe to be played */
+ RtAnimCallBack pAnimCallBack;
+ /**< Animation callback function pointer */
+ void *pAnimCallBackData;
+ /**< Animation callback function user data */
+ RwReal animCallBackTime;
+ /**< Trigger time for callback function */
+ RtAnimCallBack pAnimLoopCallBack;
+ /**< Animation loop callback function pointer */
+ void *pAnimLoopCallBackData;
+ /**< Animation loop callback function data */
+ RwInt32 maxKeyFrameSize;
+ /**< Maximum size of keyframes usable on
+ * this animation (set at creation time) */
+ RwInt32 currentKeyFrameSize;
+ /**< Size of keyframes in the current
+ * animation */
+ RwInt32 numNodes;
+ /**< Number of nodes driven by the animation */
+ RwBool isSubInterpolator;
+ /**< Internal use */
+ RwInt32 offsetInParent;
+ /**< Internal use */
+ RtAnimInterpolator *parentAnimation;
+ /**< Internal use */
+
+ RtAnimKeyFrameApplyCallBack keyFrameApplyCB;
+ /**< Internal use */
+ RtAnimKeyFrameBlendCallBack keyFrameBlendCB;
+ /**< Internal use */
+ RtAnimKeyFrameInterpolateCallBack keyFrameInterpolateCB;
+ /**< Internal use */
+ RtAnimKeyFrameAddCallBack keyFrameAddCB;
+ /**< Internal use */
+};
+
+/* Access to array of interpolated frames occupying a block of memory
+ * after the end of the RtAnimInterpolator structure.
+ */
+#define rtANIMGETINTERPFRAME( anim, nodeIndex ) \
+ ( (void *)( ( (RwUInt8 *)&(anim[1]) + \
+ ((nodeIndex) * \
+ anim->currentKeyFrameSize) ) ) )
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+
+/* Engine functions */
+extern void
+RtAnimAnimationFreeListCreateParams( RwInt32 blockSize, RwInt32 numBlocksToPrealloc );
+
+extern RwBool
+RtAnimInitialize(void);
+
+extern RwBool
+RtAnimRegisterInterpolationScheme(RtAnimInterpolatorInfo *interpolatorInfo);
+
+extern RtAnimInterpolatorInfo *
+RtAnimGetInterpolatorInfo(RwInt32 typeID);
+
+/* RtAnimAnimation */
+extern RtAnimAnimation *
+RtAnimAnimationCreate(RwInt32 typeID,
+ RwInt32 numFrames,
+ RwInt32 flags,
+ RwReal duration);
+
+extern RtAnimAnimation *
+RtAnimAnimationDestroy(RtAnimAnimation *animation);
+
+extern RtAnimAnimation *
+RtAnimAnimationRead(const RwChar * filename);
+
+extern RwBool
+RtAnimAnimationWrite(RtAnimAnimation *animation,
+ const RwChar * filename);
+
+extern RtAnimAnimation *
+RtAnimAnimationStreamRead(RwStream *stream);
+
+extern RwBool
+RtAnimAnimationStreamWrite(RtAnimAnimation *animation,
+ RwStream *stream);
+
+extern RwInt32
+RtAnimAnimationStreamGetSize(RtAnimAnimation *animation);
+
+extern RwUInt32
+RtAnimAnimationGetNumNodes(RtAnimAnimation *animation);
+
+#ifdef RWDEBUG
+
+extern RwInt32
+RtAnimAnimationGetTypeID(RtAnimAnimation *animation);
+
+#else /* RWDEBUG */
+
+#define RtAnimAnimationGetTypeID(animation) \
+ (animation->interpInfo->typeID)
+
+#endif /* RWDEBUG */
+
+/* RtAnimInterpolator */
+extern RtAnimInterpolator *
+RtAnimInterpolatorCreate(RwInt32 numNodes,
+ RwInt32 maxKeyFrameSize);
+
+extern void
+RtAnimInterpolatorDestroy(RtAnimInterpolator *anim);
+
+extern RwBool
+RtAnimInterpolatorSetCurrentAnim(RtAnimInterpolator *animI,
+ RtAnimAnimation *anim);
+
+
+#ifdef RWDEBUG
+
+extern RtAnimAnimation *
+RtAnimInterpolatorGetCurrentAnim(RtAnimInterpolator *animI);
+
+#else /* RWDEBUG */
+
+#define RtAnimInterpolatorGetCurrentAnim(animI) \
+ (animI->pCurrentAnim)
+
+#endif /* RWDEBUG */
+
+
+extern RwBool
+RtAnimInterpolatorSetKeyFrameCallBacks(RtAnimInterpolator *anim,
+ RwInt32 keyFrameTypeID);
+
+
+extern void
+RtAnimInterpolatorSetAnimLoopCallBack(RtAnimInterpolator *anim,
+ RtAnimCallBack callBack,
+ void *data );
+
+extern void
+RtAnimInterpolatorSetAnimCallBack(RtAnimInterpolator *anim,
+ RtAnimCallBack callBack,
+ RwReal time,
+ void *data );
+
+extern RwBool
+RtAnimInterpolatorCopy(RtAnimInterpolator *outAnim,
+ RtAnimInterpolator *inAnim);
+
+extern RwBool
+RtAnimInterpolatorSubAnimTime(RtAnimInterpolator *anim,
+ RwReal time);
+
+extern RwBool
+RtAnimInterpolatorAddAnimTime(RtAnimInterpolator *anim,
+ RwReal time);
+
+extern RwBool
+RtAnimInterpolatorSetCurrentTime(RtAnimInterpolator *anim,
+ RwReal time);
+
+extern RwBool
+RtAnimAnimationMakeDelta(RtAnimAnimation *animation,
+ RwInt32 numNodes,
+ RwReal time);
+
+
+extern RwBool
+RtAnimInterpolatorBlend(RtAnimInterpolator *outAnim,
+ RtAnimInterpolator *inAnim1,
+ RtAnimInterpolator *inAnim2,
+ RwReal alpha);
+
+extern RwBool
+RtAnimInterpolatorAddTogether(RtAnimInterpolator *outAnim,
+ RtAnimInterpolator *inAnim1,
+ RtAnimInterpolator *inAnim2);
+
+#define RtAnimKeyFrameApplyMacro(animation, out, in) \
+MACRO_START \
+{ \
+ (anim)->keyFrameApplyCB((out), (in1), (in2), (time)); \
+} \
+MACRO_STOP
+
+
+#define RtAnimKeyFrameInterpolateMacro(anim, out, in1, in2, time) \
+MACRO_START \
+{ \
+ (anim)->keyFrameInterpolateCB((out), (in1), (in2), (time)); \
+} \
+MACRO_STOP
+
+#define RtAnimKeyFrameBlendMacro(anim, out, in1, in2, fAlpha) \
+MACRO_START \
+{ \
+ (anim)->keyFrameBlendCB((out), (in1), (in2), (fAlpha)); \
+} \
+MACRO_STOP
+
+#define RtAnimKeyFrameAddTogetherMacro(anim, out, in1, in2) \
+MACRO_START \
+{ \
+ (anim)->keyFrameAddCB((out), (in1), (in2)); \
+} \
+MACRO_STOP
+
+#ifdef RWDEBUG
+extern void
+RtAnimKeyFrameApply(RtAnimInterpolator *animation,
+ void *result, void *iFrame);
+
+extern void
+RtAnimKeyFrameInterpolate(RtAnimInterpolator *animation,
+ void *out, void *in1,
+ void *in2, RwReal time);
+
+extern void
+RtAnimKeyFrameBlend(RtAnimInterpolator *animation,
+ void *out,
+ void *in1,
+ void *in2,
+ RwReal alpha);
+
+extern void
+RtAnimKeyFrameAddTogether(RtAnimInterpolator *animation,
+ void *out, void *in1, void *in2);
+
+#else /* RWDEBUG */
+#define RtAnimKeyFrameApply(animation, out, in) \
+ RtAnimKeyFrameApplyMacro(animation, out, in)
+
+#define RtAnimKeyFrameInterpolate(animation, out, in1, in2, time) \
+ RtAnimKeyFrameInterpolateMacro(animation, out, in1, in2, time)
+
+#define RtAnimKeyFrameBlend(animation, out, in1, in2, alpha) \
+ RtAnimKeyFrameBlendMacro(animation, out, in1, in2, alpha)
+
+#define RtAnimKeyFrameAddTogether(animation, out, in1, in2) \
+ RtAnimKeyFrameAddTogetherMacro(animation, out, in1, in2)
+#endif /* RWDEBUG */
+
+extern RtAnimInterpolator *
+RtAnimInterpolatorCreateSubInterpolator(
+ RtAnimInterpolator *parentAnim,
+ RwInt32 startNode,
+ RwInt32 numNodes,
+ RwInt32 maxKeyFrameSize);
+
+extern RwBool
+RtAnimInterpolatorBlendSubInterpolator(RtAnimInterpolator *outAnim,
+ RtAnimInterpolator *inAnim1,
+ RtAnimInterpolator *inAnim2,
+ RwReal alpha);
+
+extern RwBool
+RtAnimInterpolatorAddSubInterpolator(RtAnimInterpolator *outAnim,
+ RtAnimInterpolator *mainAnim,
+ RtAnimInterpolator *subAnim);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* RTANIM_H */
diff --git a/sdk/rwsdk/include/d3d8/rtanim.rpe b/sdk/rwsdk/include/d3d8/rtanim.rpe
new file mode 100644
index 00000000..ae8fcf33
--- /dev/null
+++ b/sdk/rwsdk/include/d3d8/rtanim.rpe
@@ -0,0 +1,168 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+enum e_rwdb_CriterionAnim
+{
+
+
+E_RT_ANIM_INTERP_IDINUSE,
+
+E_RT_ANIM_INTERP_BLOCKFULL,
+
+E_RT_ANIM_INTERP_IDUNKNOWN,
+
+ e_rwdb_CriterionAnimLAST = RWFORCEENUMSIZEINT
+};
+
+typedef enum e_rwdb_CriterionAnim e_rwdb_CriterionAnim;
+
+
diff --git a/sdk/rwsdk/include/d3d8/rtbary.h b/sdk/rwsdk/include/d3d8/rtbary.h
index 61c39b07..2531914d 100644
--- a/sdk/rwsdk/include/d3d8/rtbary.h
+++ b/sdk/rwsdk/include/d3d8/rtbary.h
@@ -11,7 +11,7 @@
/**
* \defgroup rtbary RtBary
- * \ingroup rttool
+ * \ingroup mathtools
*
* Barycentric Toolkit for RenderWare.
*/
@@ -32,7 +32,7 @@
/**
* \ingroup rtbary
- * \typedef RtBaryV4d
+ * \ref RtBaryV4d
* typedef for the 4 element homogeneous row of a transform matrix mapping
* a point from Cartesian space to the barycentric space defined by a triangle.
*/
@@ -40,7 +40,7 @@ typedef RwReal RtBaryV4d[4];
/**
* \ingroup rtbary
- * \typedef RtBaryTransform
+ * \ref RtBaryTransform
* typedef for the 4x4 homogeneous transform matrix mapping a point
* from Cartesian space to the barycentric space defined by a triangle.
*/
diff --git a/sdk/rwsdk/include/d3d8/rtbary.rpe b/sdk/rwsdk/include/d3d8/rtbary.rpe
index fdfe3afe..0fec6a77 100644
--- a/sdk/rwsdk/include/d3d8/rtbary.rpe
+++ b/sdk/rwsdk/include/d3d8/rtbary.rpe
@@ -166,472 +166,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
enum e_rwdb_CriterionBary
{
diff --git a/sdk/rwsdk/include/d3d8/rtbezpat.h b/sdk/rwsdk/include/d3d8/rtbezpat.h
index 8a5960cb..f25f5ce9 100644
--- a/sdk/rwsdk/include/d3d8/rtbezpat.h
+++ b/sdk/rwsdk/include/d3d8/rtbezpat.h
@@ -8,17 +8,12 @@
/**
* \defgroup rtbezpatch RtBezPat
- * \ingroup rttool
+ * \ingroup mathtools
*
* The Bezier Patch Toolkit is a group of functions that support the way
* RenderWare processes patches.
*/
-/**
- * \ingroup rtbezpatch
- * \typedef RtBezierV4d
- * typedef for struct RtBezierV4d.
- */
typedef struct RtBezierV4d RtBezierV4d;
/**
@@ -42,7 +37,7 @@ struct RtBezierV4d
/**
* \ingroup rtbezpatch
- * \typedef RtBezierRow
+ * \ref RtBezierRow
* typedef for a row of vectors.
* RtBezierRow is an array of 4 vectors
*/
@@ -50,7 +45,7 @@ typedef RtBezierV4d RtBezierRow[4];
/**
* \ingroup rtbezpatch
- * \typedef RtBezierMatrix
+ * \ref RtBezierMatrix
* typedef for a matrix of 4*4 vectors.
* RtBezierMatrix is an array of 4 rows.
*/
diff --git a/sdk/rwsdk/include/d3d8/rtbezpat.rpe b/sdk/rwsdk/include/d3d8/rtbezpat.rpe
index e49b65b4..0f6dc700 100644
--- a/sdk/rwsdk/include/d3d8/rtbezpat.rpe
+++ b/sdk/rwsdk/include/d3d8/rtbezpat.rpe
@@ -150,472 +150,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
enum e_rwdb_CriterionBEZPATCH
{
diff --git a/sdk/rwsdk/include/d3d8/rtbmp.h b/sdk/rwsdk/include/d3d8/rtbmp.h
index 37b5c97b..c3bb5c95 100644
--- a/sdk/rwsdk/include/d3d8/rtbmp.h
+++ b/sdk/rwsdk/include/d3d8/rtbmp.h
@@ -12,7 +12,7 @@
/**
* \defgroup rtbmp RtBMP
- * \ingroup rttool
+ * \ingroup imageconversiontools
*
* BMP Image Format Toolkit for RenderWare.
*
diff --git a/sdk/rwsdk/include/d3d8/rtbmp.rpe b/sdk/rwsdk/include/d3d8/rtbmp.rpe
index 29dad089..37c546f9 100644
--- a/sdk/rwsdk/include/d3d8/rtbmp.rpe
+++ b/sdk/rwsdk/include/d3d8/rtbmp.rpe
@@ -150,472 +150,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
enum e_rwdb_CriterionBMP
{
diff --git a/sdk/rwsdk/include/d3d8/rtcharse.h b/sdk/rwsdk/include/d3d8/rtcharse.h
index 4fdc2568..6c7a3902 100644
--- a/sdk/rwsdk/include/d3d8/rtcharse.h
+++ b/sdk/rwsdk/include/d3d8/rtcharse.h
@@ -16,7 +16,7 @@
/**
* \defgroup rtcharset RtCharset
- * \ingroup rttool
+ * \ingroup 2dtools
*
* Character Set/Foot Toolkit for RenderWare.
*/
@@ -61,7 +61,7 @@ struct RtCharsetDesc
/**
* \ingroup rtcharset
- * \typedef RtCharset
+ * \ref RtCharset
* typedef for a structure defining a character set (opaque).
* \see RtCharsetCreate
*/
diff --git a/sdk/rwsdk/include/d3d8/rtcharse.rpe b/sdk/rwsdk/include/d3d8/rtcharse.rpe
index 39c37312..30c5ff4d 100644
--- a/sdk/rwsdk/include/d3d8/rtcharse.rpe
+++ b/sdk/rwsdk/include/d3d8/rtcharse.rpe
@@ -150,472 +150,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
enum e_rwdb_CriterionCharset
{
diff --git a/sdk/rwsdk/include/d3d8/rtgncpip.h b/sdk/rwsdk/include/d3d8/rtgncpip.h
new file mode 100644
index 00000000..b18f2bb7
--- /dev/null
+++ b/sdk/rwsdk/include/d3d8/rtgncpip.h
@@ -0,0 +1,256 @@
+/* *INDENT-OFF* */
+
+/* RWPUBLIC */
+
+/****************************************************************************
+ *
+ * File: rwg/rwsdk/tool/gencpipe/rtgncpip.h
+ *
+ * Copyright (C) 2002 Criterion Technologies.
+ *
+ * Purpose: Toolkit containing generic C rendering pipeline nodes.
+ *
+ ****************************************************************************/
+
+#if (!defined(_RTGNCPIP_H))
+#define _RTGNCPIP_H
+
+/*===========================================================================*
+ *--- Include files ---------------------------------------------------------*
+ *===========================================================================*/
+
+#include "rwcore.h"
+#include "rpworld.h"
+
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+
+/****************************************************************************
+ global types
+ */
+
+typedef RpLight *RxLight;
+
+
+/* RGBA Interpolation node structures */
+#if (!defined(DOXYGEN))
+struct NodeRGBAInterpData
+{
+ RwBool rgbaInterpOn;
+ RxRenderStateVector state;
+};
+#endif /* (!defined(DOXYGEN)) */
+
+typedef struct NodeRGBAInterpData NodeRGBAInterpData;
+
+/* UV Interpolation node structures */
+typedef struct RxNodeUVInterpSettings RxNodeUVInterpSettings;
+
+/**
+ * \ingroup rtgencpipe
+ * \struct RxNodeUVInterpSettings
+ *
+ * TODO
+ */
+struct RxNodeUVInterpSettings
+{
+ RwBool uvInterpOn; /**< TODO */
+ RxRenderStateVector state; /**< TODO */
+};
+
+/* Cloning node structures */
+typedef struct RxPacketCacheCluster RxPacketCacheCluster;
+
+/**
+ * \ingroup rtgencpipe
+ * \struct RxPacketCacheCluster
+ * structure containing a cache of an \ref RxCluster's
+ * within an \ref RxPacketCache
+ */
+struct RxPacketCacheCluster
+{
+ RwUInt32 slot; /**< A \ref RwUInt32 index into the \ref RxPacketCache's
+ * array of RxPacketCacheCluster's */
+ RwUInt16 flags; /**< A cache of the original cluster's flags */
+ RwUInt16 stride; /**< A cache of the original cluster's stride */
+ void *data; /**< A cache of the original cluster's data */
+ RwUInt32 numAlloced; /**< A cache of the original cluster's numAlloced */
+ RwUInt32 numUsed; /**< A cache of the original cluster's numUsed */
+ RxPipelineCluster *clusterRef; /**< A cache of the original cluster's \ref RxPipelineCluster */
+};
+typedef struct RxPacketCache RxPacketCache;
+
+/**
+ * \ingroup rtgencpipe
+ * \struct RxPacketCache
+ * structure containing a cache of a \ref RxPacket */
+struct RxPacketCache
+{
+ RwUInt16 packetFlags; /**< A cache of the original packet's flags */
+ RwUInt16 pad[1]; /**< Alignment padding */
+ RwUInt32 numClusters; /**< The number of present clusters in the
+ * original packet when it was cloned */
+ RwBool lastCloneDone;/**< Once the cache has been cloned by \ref RxPacketCacheClone
+ * with (lastClone == TRUE), it should not be used again! */
+ RwUInt32 pad2[1]; /**< Alignment padding */
+ RxPacketCacheCluster clusters[1]; /**< An array of \ref RxPacketCacheCluster's,
+ * extending beyond 1 element */
+};
+
+
+typedef struct RxNodeCloneInitData RxNodeCloneInitData;
+/**
+ * \ingroup rtgencpipe
+ * \struct RxNodeCloneInitData
+ * structure with which to initialize
+ * clone a \ref RxNodeDefinition,
+ * through \ref RxNodeDefinitionCloneCreate and
+ * set up cloned \ref RxPipelineNode modes, through
+ * \ref RxPipelineNodeCloneDefineModes */
+struct RxNodeCloneInitData
+{
+ RwUInt32 numModes; /**< Specifies the number of modes in
+ which the node should operate */
+ RwUInt32 numOutputs; /**< Specifies the number of outputs of this
+ Clone node, which is also the maximum
+ number of outputs to which any one mode
+ may dispatch packets */
+ RwUInt32 *modeSizes; /**< Specifies the number of outputs to which
+ each mode dispatches packets */
+ RwUInt32 **modes; /**< An array of numModes pointers to arrays
+ (of length numOutputs) specifying the
+ outputs, in order, to which each mode
+ should dispatch packets (output zero is
+ the first output) */
+};
+
+/**
+ * \ingroup rtgencpipe
+ * \struct RxNodeCloneData
+ * structure which is the private
+ * data of Clone nodes \ref RxPipelineNode */
+typedef struct RxNodeCloneData RxNodeCloneData;
+struct RxNodeCloneData
+{
+ RwBool optimized; /**< \ref RwBool specifying whether \ref RxPipelineNodeCloneOptimize
+ * has been run on this \ref RxPipelineNode yet */
+ RwUInt32 currentMode; /**< \ref RwUInt32 The current mode of operation */
+ RxNodeCloneInitData *data;/**< A pointer to \ref RxNodeCloneInitData data
+ * specifying the modes of operation */
+};
+
+/****************************************************************************
+ global prototypes
+ */
+
+extern RxClusterDefinition RxClLights; /* Uses the RxLight type (see above) */
+
+
+/*********************************************************************************
+
+ Generic Nodes
+
+ *******************************************************************************/
+
+extern RxNodeDefinition *RxNodeDefinitionGetAtomicInstance(void);
+extern RxNodeDefinition *RxNodeDefinitionGetClipLine(void);
+extern RxNodeDefinition *RxNodeDefinitionGetClipTriangle(void);
+extern RxNodeDefinition *RxNodeDefinitionGetWorldSectorEnumerateLights(void);
+extern RxNodeDefinition *RxNodeDefinitionGetCullTriangle(void);
+extern RxNodeDefinition *RxNodeDefinitionGetFastPathSplitter(void);
+extern RxNodeDefinition *RxNodeDefinitionGetImmInstance(void);
+extern RxNodeDefinition *RxNodeDefinitionGetImmMangleLineIndices(void);
+extern RxNodeDefinition *RxNodeDefinitionGetImmMangleTriangleIndices(void);
+extern RxNodeDefinition *RxNodeDefinitionGetImmRenderSetup(void);
+extern RxNodeDefinition *RxNodeDefinitionGetImmStash(void);
+extern RxNodeDefinition *RxNodeDefinitionGetLight(void);
+extern RxNodeDefinition *RxNodeDefinitionGetMaterialScatter(void);
+extern RxNodeDefinition *RxNodeDefinitionGetPostLight(void);
+extern RxNodeDefinition *RxNodeDefinitionGetPreLight(void);
+extern RxNodeDefinition *RxNodeDefinitionGetRGBAInterp(void);
+extern RxNodeDefinition *RxNodeDefinitionGetUVInterp(void);
+extern RxNodeDefinition *RxNodeDefinitionGetScatter(void);
+extern RxNodeDefinition *RxNodeDefinitionGetSubmitLine(void);
+extern RxNodeDefinition *RxNodeDefinitionGetSubmitTriangle(void);
+extern RxNodeDefinition *RxNodeDefinitionGetTransform(void);
+extern RxNodeDefinition *RxNodeDefinitionGetAtomicEnumerateLights(void);
+extern RxNodeDefinition *RxNodeDefinitionGetWorldSectorInstance(void);
+extern RxNodeDefinition *RxNodeDefinitionCloneCreate(RxNodeCloneInitData *data);
+extern RwBool RxPipelineNodeCloneDefineModes(
+ RxPipeline *pipeline,
+ RxPipelineNode *node,
+ RxNodeCloneInitData *data);
+extern RwBool RxNodeDefinitionCloneDestroy(RxNodeDefinition *def);
+extern RwBool RxPipelineNodeCloneOptimize(RxPipeline *pipeline,
+ RxPipelineNode *node);
+
+
+/*********************************************************************************
+
+ Generic Core Pipes
+
+ *******************************************************************************/
+
+
+extern RwBool RtGenCPipeCreateGenericIm3DTransformPipeline(void);
+extern void RtGenCPipeDestroyGenericIm3DTransformPipeline(void);
+extern RwBool RtGenCPipeCreateGenericIm3DRenderPipelines(void);
+extern void RtGenCPipeDestroyGenericIm3DRenderPipelines(void);
+
+extern RxPipeline *RwIm3DGetGenericTransformPipeline(void);
+extern RxPipeline *RwIm3DGetGenericRenderPipeline(RwPrimitiveType primType);
+
+
+/*********************************************************************************
+
+ Generic World Pipes
+
+ *******************************************************************************/
+
+extern RwBool RtGenCPipeCreateGenericWorldPipelines(void);
+extern void RtGenCPipeDestroyGenericWorldPipelines(void);
+
+#define RpWorldGetGenericSectorPipelineMacro() \
+ (RXPIPELINEGLOBAL(genericWorldSectorPipeline))
+
+#define RpAtomicGetGenericPipelineMacro() \
+ (RXPIPELINEGLOBAL(genericAtomicPipeline))
+
+#define RpMaterialGetGenericPipelineMacro() \
+ (RXPIPELINEGLOBAL(genericMaterialPipeline))
+
+
+#if !(defined(RWDEBUG) || defined(RWSUPPRESSINLINE))
+
+#define RpWorldGetGenericSectorPipeline RpWorldGetGenericSectorPipelineMacro
+#define RpAtomicGetGenericPipeline RpAtomicGetGenericPipelineMacro
+#define RpMaterialGetGenericPipeline RpMaterialGetGenericPipelineMacro
+
+#endif /* !(defined(RWDEBUG) || defined(RWSUPPRESSINLINE)) */
+
+
+#if (defined(RWDEBUG) || defined(RWSUPPRESSINLINE))
+
+extern RxPipeline *RpWorldGetGenericSectorPipeline(void);
+
+extern RxPipeline *RpAtomicGetGenericPipeline(void);
+
+extern RxPipeline *RpMaterialGetGenericPipeline(void);
+
+#endif /* (defined(RWDEBUG) || defined(RWSUPPRESSINLINE)) */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* (!defined(_RTGNCPIP_H)) */
+
+/* RWPUBLICEND */
+
+/* *INDENT-ON* */
diff --git a/sdk/rwsdk/include/d3d8/rtgncpip.rpe b/sdk/rwsdk/include/d3d8/rtgncpip.rpe
new file mode 100644
index 00000000..4f676526
--- /dev/null
+++ b/sdk/rwsdk/include/d3d8/rtgncpip.rpe
@@ -0,0 +1,172 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+enum e_rwdb_CriterionGENCPIPETOOL
+{
+
+
+
+ e_rwdb_CriterionGENCPIPETOOLLAST = RWFORCEENUMSIZEINT
+};
+
+typedef enum e_rwdb_CriterionGENCPIPETOOL e_rwdb_CriterionGENCPIPETOOL;
+
+
diff --git a/sdk/rwsdk/include/d3d8/rtimport.h b/sdk/rwsdk/include/d3d8/rtimport.h
index cf4e6283..2cc6383b 100644
--- a/sdk/rwsdk/include/d3d8/rtimport.h
+++ b/sdk/rwsdk/include/d3d8/rtimport.h
@@ -10,15 +10,15 @@
#define RTIMPORT_H
/**
- * \defgroup rtimport RtWorldImport
- * \ingroup rttool
+ * \defgroup rtworldimport RtWorldImport
+ * \ingroup basicgeometry
*
- * World Import Toolkit for Renderware.
+ * World Import Toolkit for RenderWare.
*/
/**
* \defgroup selectors RtWorldImportPartitionSelectors
- * \ingroup rtimport
+ * \ingroup rtworldimport
*
* The set of provided RtWorldImportPartitionSelectors:
* Selects a good partition by calling one of the
@@ -29,7 +29,7 @@
/**
* \defgroup iterators RtWorldImportPartitionIterators
- * \ingroup rtimport
+ * \ingroup rtworldimport
*
* The set of provided RtWorldImportPartitionIterators:
* Iterates through a set of candidate partitions, possibly
@@ -39,7 +39,7 @@
/**
* \defgroup evaluators RtWorldImportPartitionEvaluators
- * \ingroup rtimport
+ * \ingroup rtworldimport
*
* The set of provided RtWorldImportPartitionEvaluators:
* Uses a combination of statistics, build sector, build status, and
@@ -51,7 +51,7 @@
/**
* \defgroup terminators RtWorldImportPartitionTerminators
- * \ingroup rtimport
+ * \ingroup rtworldimport
*
* The set of provided RtWorldImportPartitionTerminators:
* Checks given criteria about the statistics, build sector, build status, and
@@ -61,7 +61,7 @@
/**
* \defgroup kd RtWorldImportGuideKD
- * \ingroup rtimport
+ * \ingroup rtworldimport
*
* Tools to manipulate the \ref RtWorldImportGuideKDTree that is used to
* manually build the sectors of a world.
@@ -69,7 +69,7 @@
/**
* \defgroup hints RtWorldImportHints
- * \ingroup rtimport
+ * \ingroup rtworldimport
*
* Tools to aid the build process by giving hints as to what geometry should
* not be split, and what geometry makes for a good partitioning guide.
@@ -96,7 +96,7 @@
#define rtWORLDIMPORTPROGRESSBSPCOMPRESSEND 5
/**
- * \ingroup rtimport
+ * \ingroup rtworldimport
* \def rtWORLDIMPORTINVALIDPARTITION
*
* This value means that no partition was found, or that the partition was
@@ -104,51 +104,61 @@
*/
#define rtWORLDIMPORTINVALIDPARTITION RwRealMAXVAL
-/****************************************************************************
- Global types
- */
-
-/**
- * Internal use only
- */
-typedef union RtWorldImportVertexState RtWorldImportVertexState;
+/* maintained in Bin-tree */
+#define CONGRUENTVERTEXCHILDREN 2
+/* maintained in Quad-tree */
+#define WELDVERTEXCHILDREN 4
-/**
- * \ingroup rtimport
- * \typedef RtWorldImportVertex
- *
- * typedef for struct \ref RtWorldImportVertex
+/****************************************************************************
+ Global types
*/
+#if (!defined(DOXYGEN))
typedef struct RtWorldImportVertex RtWorldImportVertex;
-/**
- * \ingroup rtimport
- * \typedef RtWorldImportWeldVertex
- *
- * typedef for struct \ref RtWorldImportWeldVertex
- */
typedef struct RtWorldImportWeldVertex RtWorldImportWeldVertex;
-/**
- * \ingroup rtimport
- * \typedef RtWorldImportBuildVertex
- *
- * typedef for struct \ref RtWorldImportBuildVertex
- */
typedef struct RtWorldImportBuildVertex RtWorldImportBuildVertex;
+/* Internal use only */
+typedef union RtWorldImportVertexState RtWorldImportVertexState;
+/* Internal use only */
+union RtWorldImportVertexState
+{
+ /* clipFlags, two types, first is based on partition only, 2nd is
+ * also based on partition, but takes overlaps into consideration. i.e.
+ * number splits is usually higher in clipFlags[0] than [1] */
+ RwInt32 clipFlags[2]; /* Internal use only */
+ RwInt32 forwardingAddress; /* Internal use only */
+ RtWorldImportVertex *vpVert; /* Internal use only */
+ RtWorldImportWeldVertex *vpWeldVert; /* Internal use only */
+ RtWorldImportBuildVertex *vpBuildVert; /* Internal use only */
+ RwSList *slist; /* Internal use only */
+};
+#endif /* (!defined(DOXYGEN)) */
/**
- * \ingroup rtimport
- * \typedef RtWorldImportBuildPolyInfo
+ * \ingroup rtworldimport
+ * \struct RtWorldImportVertex
+ * Holds data for each vertex in the import world.
*
- * typedef for struct \ref RtWorldImportBuildPolyInfo
*/
+struct RtWorldImportVertex
+{
+ RwV3d OC; /**< World space vertex position */
+ RwV3d normal; /**< World space vertex normal */
+ RwRGBA preLitCol; /**< Vertex Prelight color */
+ RwTexCoords texCoords[rwMAXTEXTURECOORDS];
+ /**< Vertex texture coordinates */
+ RtWorldImportVertexState state; /**< Internal use only */
+ RwInt32 matIndex; /**< Vertex material index */
+ void *pUserdata; /**< Pointer to unspecified per vertex user data */
+};
+
typedef struct RtWorldImportBuildPolyInfo RtWorldImportBuildPolyInfo;
/**
- * \ingroup rtimport
+ * \ingroup rtworldimport
* \struct RtWorldImportBuildPolyInfo
*
* Information about a polygon
@@ -167,7 +177,7 @@ struct RtWorldImportBuildPolyInfo
typedef union RtWorldImportBuildVertexMode RtWorldImportBuildVertexMode;
/**
- * \ingroup rtimport
+ * \ingroup rtworldimport
* \struct RtWorldImportBuildVertexMode
*
* Mode of the vertex.
@@ -182,7 +192,7 @@ union RtWorldImportBuildVertexMode
};
/**
- * \ingroup rtimport
+ * \ingroup rtworldimport
* \struct RtWorldImportBuildVertex
*
* A list of polygons as a list of vertices where the end of poly boundary
@@ -198,30 +208,16 @@ struct RtWorldImportBuildVertex
/**< we store some poly info in the end marker of a boundary */
};
-
-
-/**
- * \ingroup rtimport
- * \typedef RtWorldImportGuideKDTree
- *
- * typedef for struct \ref RtWorldImportGuideKDTree
- */
-typedef struct RtWorldImportGuideKDTree RtWorldImportGuideKDTree;
-
/* NB Merged RtWorldImportPartition with RtWorldImportBuildClipStatistics because
* there was a unique one-to-one relationship between them, and it made things easier
* just updating one stucture, without having to update both in sequence...
*/
-/**
- * \ingroup rtimport
- * \typedef RtWorldImportBuildClipStatistics
- *
- * typedef for struct \ref RtWorldImportBuildClipStatistics
- */
+
typedef struct RtWorldImportBuildClipStatistics RtWorldImportBuildClipStatistics;
+
/**
- * \ingroup rtimport
+ * \ingroup rtworldimport
* \struct RtWorldImportBuildClipStatistics
*
* Holds statistics about a partition or candidate partition during
@@ -231,15 +227,15 @@ struct RtWorldImportBuildClipStatistics
{
RwInt32 numPotentialSplit;
/**< The number of polygons split by the partition,
- * disgregarding overlaps */
+ * disregarding overlaps */
RwInt32 numPotentialLeft;
/**< The number of potential polygons and fragments on the
- * left of the partition, disgregarding overlaps */
+ * left of the partition, disregarding overlaps */
RwInt32 numPotentialRight;
/**< The number of potential polygons and fragments on the
- * right of the partition, disgregarding overlaps */
+ * right of the partition, disregarding overlaps */
RwInt32 numActualSplit;
@@ -276,15 +272,13 @@ struct RtWorldImportBuildClipStatistics
/**< The actual, relative size of the overlap on the right of the partition */
};
-/**
- * \ingroup rtimport
- * \typedef RtWorldImportPartition
- *
- * typedef for struct \ref RtWorldImportPartition
+/*
+ * typedef for struct RtWorldImportPartition
*/
typedef struct RtWorldImportPartition RtWorldImportPartition;
+
/**
- * \ingroup rtimport
+ * \ingroup rtworldimport
* \struct RtWorldImportPartition
*
* A partitioning plane.
@@ -311,8 +305,14 @@ struct RtWorldImportPartition
/**< The statistics for the partition */
};
+/*
+ * typedef for struct \ref RtWorldImportGuideKDTree
+ */
+typedef struct RtWorldImportGuideKDTree RtWorldImportGuideKDTree;
+
+
/**
- * \ingroup rtimport
+ * \ingroup rtworldimport
* \struct RtWorldImportGuideKDTree
* Represents the structure of a binary tree with
* no contents per se. It is used to build a BSP in a user specified
@@ -342,6 +342,7 @@ struct RtWorldImportGuideKDTree
typedef struct _rtWorldImportGuideKDStackElement _rtWorldImportGuideKDStackElement;
+#if (!defined(DOXYGEN))
struct _rtWorldImportGuideKDStackElement
{
RwBool terminal;
@@ -357,16 +358,15 @@ struct _rtWorldImportGuideKDStack
_rtWorldImportGuideKDStackElement *current;
_rtWorldImportGuideKDStackElement *bottom;
};
+#endif /* (!defined(DOXYGEN)) */
-/**
- * \ingroup rtimport
- * \typedef RtWorldImportBuildSector
- *
- * typedef for struct \ref RtWorldImportBuildSector
+/*
+ * typedef for struct RtWorldImportBuildSector
*/
typedef struct RtWorldImportBuildSector RtWorldImportBuildSector;
+
/**
- * \ingroup rtimport
+ * \ingroup rtworldimport
* \struct RtWorldImportBuildSector
*
* Holds information about the sector that is being subdivided
@@ -401,15 +401,13 @@ struct RtWorldImportBuildSector
/**< Maximum number of materials in the in the world */
};
-/**
- * \ingroup rtimport
- * \typedef RtWorldImportBuildStatus
- *
- * typedef for struct \ref RtWorldImportBuildStatus
+/*
+ * typedef for struct RtWorldImportBuildStatus
*/
typedef struct RtWorldImportBuildStatus RtWorldImportBuildStatus;
+
/**
- * \ingroup rtimport
+ * \ingroup rtworldimport
* \struct RtWorldImportBuildStatus
* World Import Build Status Structure
* Used to store the current tree's build status
@@ -419,50 +417,41 @@ struct RtWorldImportBuildStatus
RwInt32 depth; /**< current depth in the tree */
};
-/**
- * Internal use only
- */
-union RtWorldImportVertexState
+typedef struct RwRGBAUInt32 RwRGBAUInt32;
+
+#if (!defined(DOXYGEN))
+struct RwRGBAUInt32
{
- /* clipFlags, two types, first is based on partition only, 2nd is
- * also based on partition, but takes overlaps into consideration. i.e.
- * number splits is usually higher in clipFlags[0] than [1] */
- RwInt32 clipFlags[2]; /**< Internal use only */
- RwInt32 forwardingAddress; /**< Internal use only */
- RtWorldImportVertex *vpVert; /**< Internal use only */
- RtWorldImportWeldVertex *vpWeldVert; /**< Internal use only */
- RtWorldImportBuildVertex *vpBuildVert; /**< Internal use only */
- RwSList *slist; /**< Internal use only */
+ RwUInt32 red, green, blue, alpha;
};
-/**
- * \ingroup rtimport
- * \struct RtWorldImportVertex
- * Holds data for each vertex in the import world.
- *
- */
-struct RtWorldImportVertex
+typedef struct RtWorldImportCongruentVertex RtWorldImportCongruentVertex;
+
+struct RtWorldImportCongruentVertex
{
- RwV3d OC; /**< World space vertex position */
- RwV3d normal; /**< World space vertex normal */
- RwRGBA preLitCol; /**< Vertex Prelight color */
- RwTexCoords texCoords[rwMAXTEXTURECOORDS];
- /**< Vertex texture coordinates */
- RtWorldImportVertexState state; /**< Internal use only */
- RwInt32 matIndex; /**< Vertex material index */
- void *pUserdata; /**< Pointer to unspecified per vertex user data */
+ RwInt32 destIdx;
+ RtWorldImportVertex vertex;
+ RtWorldImportVertex Mean;
+ RwRGBAUInt32 preLitMean;
+ RwInt32 refCount;
+ RtWorldImportCongruentVertex *child[CONGRUENTVERTEXCHILDREN];
};
-/**
- * \ingroup rtimport
- * \typedef RtWorldImportTriangle
+struct RtWorldImportWeldVertex
+{
+ RtWorldImportVertex *sourcePtr;
+ RtWorldImportCongruentVertex *CongruentVertex;
+ RtWorldImportWeldVertex *child[WELDVERTEXCHILDREN];
+};
+#endif /* (!defined(DOXYGEN)) */
+
+/*
* Holds data for each triangle in the import world.
- *
- * \see RtWorldImportTriangle
*/
typedef struct RtWorldImportTriangle RtWorldImportTriangle;
+
/**
- * \ingroup rtimport
+ * \ingroup rtworldimport
* \struct RtWorldImportTriangle
* Holds data for each triangle in the import world.
*
@@ -476,38 +465,69 @@ struct RtWorldImportTriangle
};
+
+
+/*
+ * typedef for struct RtWorldImportBBoxHintDesc
+ */
+typedef struct RtWorldImportBBoxHintDesc RtWorldImportBBoxHintDesc;
/**
- * \ingroup rtimport
- * \typedef RtWorldImportHints
- *
- * typedef for struct \ref RtWorldImportHints
+ * \ingroup rtworldimport
+ * \struct RtWorldImportBBoxHintDesc
+ * Bounding box hints and (priority) values used to control the world
+ * sectorization process.
+ */
+struct RtWorldImportBBoxHintDesc
+{
+ RwBBox bBox; /**< The (necessarily orthogonal) bounding box */
+ RwReal value; /**< The value or priority of the hint (highest is most important) */
+};
+
+/*
+ * typedef for struct RtWorldImportHints
*/
typedef struct RtWorldImportHints RtWorldImportHints;
/**
- * \ingroup rtimport
+ * \ingroup rtworldimport
* \struct RtWorldImportHints
* Bounding box hints used to control the world sectorization process.
* \see RtWorldImportHintsSet
*/
struct RtWorldImportHints
{
- /** The bounding box hints */
- RwBBox *boundingBoxes;
- /** The number of bounding box hints */
- RwInt32 numBoundingBoxes;
+ RtWorldImportBBoxHintDesc *boundingBoxes; /**< The bounding box hints */
+ RwInt32 numBoundingBoxes; /**< The number of bounding box hints */
};
+
/**
- * \ingroup rtimport
- * \typedef RtWorldImportParameters
+ * \ingroup rtworldimport
+ * \ref RtWorldImportHintGroup
*
+ * An enumeration that can be passed to
+ * \ref RtWorldImportHintsSetGroup and \ref RtWorldImportHintsGetGroup to determine
+ * whether hints will contribute towards the shield hint group or partition hint group
+ */
+typedef enum
+{
+ rtWORLDIMPORTSHIELDHINT = 0,
+ rtWORLDIMPORTPARTITIONHINT,
+
+ rtWORLDIMPORTFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
+}
+RtWorldImportHintGroup;
+
+
+
+
+/*
* typedef for struct \ref RtWorldImportParameters
*/
typedef struct RtWorldImportParameters RtWorldImportParameters;
/**
- * \ingroup rtimport
+ * \ingroup rtworldimport
* \struct RtWorldImportParameters
* Parameters used with \ref RtWorldImportCreateWorld.
* They are initialized to default values using \ref RtWorldImportParametersInit.
@@ -563,15 +583,13 @@ struct RtWorldImportParameters
/**< If TRUE the world will be checked for validity during the build process. */
};
-/**
- * \ingroup rtimport
- * \typedef RtWorldImport
- *
- * typedef for struct \ref RtWorldImport
+/*
+ * typedef for struct RtWorldImport
*/
typedef struct RtWorldImport RtWorldImport;
+
/**
- * \ingroup rtimport
+ * \ingroup rtworldimport
* \struct RtWorldImport
* World Import State Structure
*/
@@ -583,14 +601,10 @@ struct RtWorldImport
RtWorldImportTriangle *polygons; /**< Triangle array */
RwInt32 numPolygons; /**< Triangle count */
-
-
- RwSurfaceProperties surfaceProps; /**< The world's surface
- lighting properties */
};
/**
- * \ingroup rtimport
+ * \ingroup rtworldimport
* \ref RtWorldImportProgressCallBack is the type for the callback function supplied to
* \ref RtWorldImportSetProgressCallBack.
*
@@ -626,65 +640,102 @@ struct RtWorldImport
typedef RwBool (*RtWorldImportProgressCallBack)(RwInt32 msg, RwReal value);
/**
- * \ingroup rtimport
- * \typedef RtWorldImportDestroyVertexUserdataCallBack
+ * \ingroup rtworldimport
+ * \ref RtWorldImportDestroyVertexUserdataCallBack
*
* A pointer to the CallBack function that will be called during
* vertex destruction.
+ *
+ * \param pUserdata
+ *
+ * \return
*/
typedef RwBool (*RtWorldImportDestroyVertexUserdataCallBack)(void **pUserdata);
/**
- * \ingroup rtimport
- * \typedef RtWorldImportCloneVertexUserdataCallBack
+ * \ingroup rtworldimport
+ * \ref RtWorldImportCloneVertexUserdataCallBack
*
* A pointer to the CallBack function that will be called during
* vertex cloning.
+ *
+ * \param pUserdataDst
+ * \param pUserdataSrc
+ *
+ * \return
*/
typedef RwBool (*RtWorldImportCloneVertexUserdataCallBack)(void **pUserdataDst, void **pUserdataSrc);
/**
- * \ingroup rtimport
- * \typedef RtWorldImportInterpVertexUserdataCallBack
+ * \ingroup rtworldimport
+ * \ref RtWorldImportInterpVertexUserdataCallBack
*
* A pointer to the CallBack function that will be called during
* vertex interpolation.
+ *
+ * \param pUserdataDst
+ * \param pUserdata1
+ * \param pUserdata2
+ * \param delta
+ *
+ * \return
*/
typedef RwBool (*RtWorldImportInterpVertexUserdataCallBack)(void **pUserdataDst, void **pUserdata1, void **pUserdata2, RwReal delta);
/**
- * \ingroup rtimport
- * \typedef RtWorldImportDestroyPolygonUserdataCallBack
+ * \ingroup rtworldimport
+ * \ref RtWorldImportDestroyPolygonUserdataCallBack
*
* A pointer to the CallBack function that will be called during
* polygon destruction.
+ *
+ * \param pUserdata
+ *
+ * \return
*/
typedef RwBool (*RtWorldImportDestroyPolygonUserdataCallBack)(void **pUserdata);
/**
- * \ingroup rtimport
- * \typedef RtWorldImportSplitPolygonUserdataCallBack
+ * \ingroup rtworldimport
+ * \ref RtWorldImportSplitPolygonUserdataCallBack
*
* A pointer to the CallBack function that will be called during
* polygon division.
+ *
+ * \param pUserdataDst
+ * \param pUserdataSrc
+ *
+ * \return
*/
typedef RwBool (*RtWorldImportSplitPolygonUserdataCallBack)(void **pUserdataDst, void **pUserdataSrc);
/**
- * \ingroup rtimport
- * \typedef RtWorldImportSectorSetVertexUserdataCallBack
+ * \ingroup rtworldimport
+ * \ref RtWorldImportSectorSetVertexUserdataCallBack
*
* A pointer to the CallBack function that will be called during
* the setting of the vertex user data.
+ *
+ * \param pUserdata
+ * \param sector
+ * \param index
+ *
+ * \return
*/
typedef RwBool (*RtWorldImportSectorSetVertexUserdataCallBack)(void **pUserdata, RpWorldSector *sector, RwInt32 index);
/**
- * \ingroup rtimport
- * \typedef RtWorldImportSectorSetPolygonUserdataCallBack
+ * \ingroup rtworldimport
+ * \ref RtWorldImportSectorSetPolygonUserdataCallBack
*
* A pointer to the CallBack function that will be called during
* the setting of the polygon user data.
+ *
+ * \param pUserdata
+ * \param sector
+ * \param index
+ *
+ * \return
*/
typedef RwBool (*RtWorldImportSectorSetPolygonUserdataCallBack)(void **pUserdata, RpWorldSector *sector, RwInt32 index);
@@ -692,12 +743,18 @@ typedef RwBool (*RtWorldImportSectorSetPolygonUserdataCallBack)(void **pUserdata
/**
- * \ingroup rtimport
- * \typedef RtWorldImportTerminationBuildCallBack
+ * \ingroup rtworldimport
+ * \ref RtWorldImportTerminationBuildCallBack
*
* A pointer to the function that will be called during the
* build process to determine whether the current sector should
* be subdivided further, or terminated.
+ *
+ * \param buildSector
+ * \param buildStatus
+ * \param pData
+ *
+ * \return
*/
typedef RwBool (*RtWorldImportTerminationBuildCallBack)
(RtWorldImportBuildSector *buildSector,
@@ -705,11 +762,17 @@ typedef RwBool (*RtWorldImportTerminationBuildCallBack)
void *pData);
/**
- * \ingroup rtimport
- * \typedef RtWorldImportPartitionBuildCallBack
+ * \ingroup rtworldimport
+ * \ref RtWorldImportPartitionBuildCallBack
*
* A pointer to the function that will be called during the
* build process to select a suitable sector partition.
+ *
+ * \param buildSector
+ * \param buildStatus
+ * \param partition
+ *
+ * \return
*/
typedef RwReal (*RtWorldImportPartitionBuildCallBack)
(RtWorldImportBuildSector *buildSector,
@@ -717,15 +780,13 @@ typedef RwReal (*RtWorldImportPartitionBuildCallBack)
RtWorldImportPartition *partition,
void *pData);
-/**
- * \ingroup rtimport
- * \typedef RtWorldImportBuildCallBacks
- *
+/*
* typedef for struct \ref RtWorldImportBuildCallBacks
*/
typedef struct RtWorldImportBuildCallBacks RtWorldImportBuildCallBacks; /* MAYBE: rename to SectorCallBacks ?*/
+
/**
- * \ingroup rtimport
+ * \ingroup rtworldimport
* \struct RtWorldImportBuildCallBacks
* Sectorization callbacks
*/
@@ -741,15 +802,13 @@ struct RtWorldImportBuildCallBacks
/**< Termination callback user data */
};
-/**
- * \ingroup rtimport
- * \typedef RtWorldImportUserdataCallBacks
- *
+/*
* typedef for struct \ref RtWorldImportUserdataCallBacks
*/
typedef struct RtWorldImportUserdataCallBacks RtWorldImportUserdataCallBacks;
+
/**
- * \ingroup rtimport
+ * \ingroup rtworldimport
* \struct RtWorldImportUserdataCallBacks
* Bundle of callbacks
*/
@@ -772,8 +831,8 @@ struct RtWorldImportUserdataCallBacks
};
/**
- * \ingroup rtimport
- * \typedef RtWorldImportBuildPartitionSelector
+ * \ingroup rtworldimport
+ * \ref RtWorldImportBuildPartitionSelector
*
* An enumeration that can be passed to
* \ref RtWorldImportSetStandardBuildPartitionSelector to determine
@@ -821,8 +880,6 @@ extern "C"
extern RwBool
_rtImportBuildSectorFindBBox(RtWorldImportBuildSector *buildSector, RwBBox *bbpOut);
-/* TODO: decide where these scheme functions are going and which ones are public and
- whether _rt or RT should be used */
extern void
_rtWorldImportGuideKDCopy(RtWorldImportGuideKDTree *KD, RpSector *spSector, RwInt32 depth);
extern void _rtWorldImportGuideKDStackDestroy(_rtWorldImportGuideKDStack *stack);
@@ -862,6 +919,12 @@ RtWorldImportMaterialSeparatePartitionSelector(RtWorldImportBuildSector *buildSe
RtWorldImportBuildStatus *buildStatus,
RtWorldImportPartition *partition,
void *userData);
+extern RwReal
+RtWorldImportPartitionHintPartitionSelector(RtWorldImportBuildSector *buildSector,
+ RtWorldImportBuildStatus *buildStatus,
+ RtWorldImportPartition *partition,
+ void * __RWUNUSED__ userData);
+
extern RwReal
RtWorldImportMaximumOccluderPartitionSelector(RtWorldImportBuildSector *buildSector,
@@ -1109,14 +1172,13 @@ RtWorldImportSectorAspectSizePartitionTerminator(RtWorldImportBuildSector * buil
-/* END TODO */
/* WorldImport hints */
extern void
-RtWorldImportHintsSet(RtWorldImportHints *hints);
+RtWorldImportHintsSetGroup(RtWorldImportHints *hints, RtWorldImportHintGroup group);
extern RtWorldImportHints *
-RtWorldImportHintsGet(void);
+RtWorldImportHintsGetGroup(RtWorldImportHintGroup group);
extern RtWorldImportHints *
RtWorldImportHintsCreate(void);
@@ -1175,14 +1237,6 @@ extern RwInt32 RtWorldImportGetNumTriangles(RtWorldImport * nohsworld);
extern RtWorldImportTriangle *
RtWorldImportGetTriangles(RtWorldImport * nohsworld);
-/* Surface lighting characteristics */
-extern RtWorldImport *
-RtWorldImportSetSurfaceProperties(RtWorldImport * world,
- RwSurfaceProperties *
- surface);
-
-extern RwSurfaceProperties *
-RtWorldImportGetSurfaceProperties(RtWorldImport * world);
/* Progress callbacks */
extern void
@@ -1254,6 +1308,12 @@ RtWorldImportSetStandardBuildPartitionSelector(RtWorldImportBuildPartitionSelect
#define RtWorldImportParametersInitialize(_paramsPtr) \
*(_paramsPtr) = *RtWorldImportParametersInit();
+/* Back compatibility with former hints which only permitted type zero (shield) hints... */
+#define RtWorldImportHintsSet(_hints) \
+RtWorldImportHintsSetGroup(_hints, rtWORLDIMPORTSHIELDHINT);
+
+#define RtWorldImportHintsGet() \
+RtWorldImportHintsGetGroup(rtWORLDIMPORTSHIELDHINT);
#endif /* RTIMPORT_H */
diff --git a/sdk/rwsdk/include/d3d8/rtimport.rpe b/sdk/rwsdk/include/d3d8/rtimport.rpe
index d4b7ad2b..ff8d3d5c 100644
--- a/sdk/rwsdk/include/d3d8/rtimport.rpe
+++ b/sdk/rwsdk/include/d3d8/rtimport.rpe
@@ -149,472 +149,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
enum e_rwdb_CriterionNoHSWorld
{
diff --git a/sdk/rwsdk/include/d3d8/rtintel.h b/sdk/rwsdk/include/d3d8/rtintel.h
deleted file mode 100644
index c11329df..00000000
--- a/sdk/rwsdk/include/d3d8/rtintel.h
+++ /dev/null
@@ -1,1206 +0,0 @@
-/**
- * Intel specific support toolkit
- */
-
-/**********************************************************************
- *
- * File : rtintel.h
- *
- * Abstract : Intel specific support/emulation
- *
- **********************************************************************
- *
- * This file is a product of Criterion Software Ltd.
- *
- * This file is provided as is with no warranties of any kind and is
- * provided without any obligation on Criterion Software Ltd. or
- * Canon Inc. to assist in its use or modification.
- *
- * Criterion Software Ltd. will not, under any
- * circumstances, be liable for any lost revenue or other damages arising
- * from the use of this file.
- *
- * Copyright (c) 1998 Criterion Software Ltd.
- * All Rights Reserved.
- *
- * RenderWare is a trademark of Canon Inc.
- *
- ************************************************************************/
-
-#ifndef RTINTEL_H
-#define RTINTEL_H
-
-/**
- * \defgroup rtintel RtIntel
- * \ingroup rttool
- *
- * Intel CPU Toolkit for RenderWare.
- */
-
-/****************************************************************************
- Include files
- */
-
-/*
- * Pick up
- * typedef struct _rwResEntryTag RwResEntry;
- * from baresour.h (internal) / rwcore.h (external)
- */
-
-/****************************************************************************
- Global Types
- */
-
-#include "rtintel.rpe" /* automatically generated header file */
-
-#if (!defined(RW_FIXED_64))
-typedef struct RwFixed64 RwFixed64;
-struct RwFixed64
-{
- RwInt32 msb;
- RwUInt32 lsb;
-};
-
-#define RW_FIXED_64
-#endif /* (!defined(RW_FIXED_64)) */
-
-#define doubleFromRwFixed64(x) \
- ( ((double)((x).msb))*((double)(1<<16))*((double)(1<<16)) \
- + ((double)((x).lsb)) )
-
-#if (!defined(RPINTELTIMEFUNCTION))
-typedef RwBool(*RtIntelTimeFunction) (void *data);
-
-#define RPINTELTIMEFUNCTION
-#endif /* (!defined(RPINTELTIMEFUNCTION)) */
-
-typedef struct RtIntelOverload RtIntelOverload;
-
-typedef void (*RwTransformFunction) (RwResEntry * repEntry);
-
-struct RtIntelOverload
-{
- rwMatrixMultFn MatrixMultiplyFunction;
- rwVectorMultFn VectorMultPointFunction;
- rwVectorMultFn VectorMultVectorFunction;
- RwTransformFunction TransformFunction;
-};
-
-#if (defined(__ICL))
-#define DEFINED__ICL " __ICL"
-#define UNDEFINED__ICL ""
-#else /* (defined(__ICL)) */
-#define DEFINED__ICL ""
-#define UNDEFINED__ICL " __ICL"
-#endif /* (defined(__ICL)) */
-
-#if (defined(_MSC_VER))
-
-# pragma comment ( user, "comment:" __FILE__ "(" RW_STRINGIFY_EXPANDED(__LINE__) ") : " "DEFINED " DEFINED__ICL " ; UNDEFINED " UNDEFINED__ICL )
-/* # pragma message (__FILE__ "(" RW_STRINGIFY_EXPANDED(__LINE__) ") : " "DEFINED " DEFINED__ICL " ; UNDEFINED " UNDEFINED__ICL ) */
-/* # pragma comment ( user, "comment:" __FILE__ "(" RW_STRINGIFY_EXPANDED(__LINE__) ") : " "DEFINED " DEFINED__ICL " ; UNDEFINED " UNDEFINED__ICL ) */
-#if (! (defined(__ICL) || defined(XBOX_DRVMODEL_H)) )
-#pragma message (__DATE__ " " __TIME__ " " __FILE__ "(" RW_STRINGIFY_EXPANDED(__LINE__) ") : No MMX intrinsics - defaulting to software emulation")
-#pragma message (__DATE__ " " __TIME__ " " __FILE__ "(" RW_STRINGIFY_EXPANDED(__LINE__) ") : No SSE intrinsics - defaulting to software emulation")
-#pragma comment ( user, "comment:" __FILE__ "(" RW_STRINGIFY_EXPANDED(__LINE__) ") : No MMX intrinsics - defaulting to software emulation")
-#endif /* (! (defined(__ICL) || defined(XBOX_DRVMODEL_H)) ) */
-#endif /* (defined(_MSC_VER)) */
-
-/*
- * MMX
- */
-
-#if (defined(__ICL))
-
-#if (!defined(MMINTRIN_H))
-#include "mmintrin.h"
-#define MMINTRIN_H
-#endif /* (!defined(MMINTRIN_H)) */
-
-#else /* (defined(__ICL)) */
-
-#if (defined(_MSC_VER))
-
-#if (!defined(__M64))
-typedef __int64 Rt_m64;
-
-#define __M64
-#endif /* (!defined(__M64)) */
-
-#else /* (defined(_MSC_VER)) -- e.g. __GNUC__ */
-
-#if (!defined(__M64))
-
-typedef RwInt64 Rt_m64;
-
-#define __M64
-
-#endif /* (!defined(__M64)) */
-
-#endif /* (defined(_MSC_VER)) */
-
-#endif /* (defined(__ICL)) */
-
-/*
- * SSE
- */
-
-/*
- * From
- * ccomp.pdf
- * 12 Intel C/C++ Compiler User's Guide
- * for Win32 Systems With Katmai New Instruction Support
- * --------------------------------------------------------
- * Functionality Intrinsics Usage
- * You need only define one preprocessor symbol and include the header file
- * xmmintrin.h in your application to use the following functionality
- * intrinsics:
- * #define _MM_FUNCTIONALITY
- * #include "xmmintrin.h"
- * To encourage the compiler to inline the functionality intrinsic functions for
- * better performance, consider using the -Qip and -Qipo compiler switches.
- */
-
-#if (defined(__ICL))
-
-/* #define _MM2_FUNCTIONALITY */
-
-/* #define _MM_FUNCTIONALITY */
-
-/* #define _MM_NO_ABORT */
-
-/* #define _MM_NO_ACCURACY */
-
-/* #define _MM_NO_ALIGN_CHECK */
-
-/* #define _MM_NO_INLINE */
-
-/*
- * Undefine "or", since this is valid assembler; e.g. in
- * SDK10/include/xmm_func.h
- * _asm {
- * push eax
- * fld f
- * fstcw saved_cw
- * mov eax, saved_cw
- * or eax, 3072
- * mov new_cw, eax
- * fldcw new_cw
- * fistp ret
- * fldcw saved_cw
- * pop eax
- * }
- */
-
-#if (!defined(XMMINTRIN_H))
-#include "xmmintrin.h"
-#define XMMINTRIN_H
-#endif /* (!defined(XMMINTRIN_H)) */
-
-typedef __m64 Rt_m64;
-typedef __m128 Rt_m128;
-
-#if (450 <= __ICL)
-#if (!defined(EMMINTRIN_H))
-#include "emmintrin.h"
-#define EMMINTRIN_H
-typedef __m128d Rt_m128d;
-typedef __m128i Rt_m128i;
-#endif /* (!defined(EMMINTRIN_H)) */
-#else /* (450 <= __ICL) */
-typedef __m128 Rt_m128d;
-typedef __m128 Rt_m128i;
-#endif /* (450 <= __ICL) */
-
-/*
- * Report SSE options as compiler messages and object file comments
- */
-
-#ifdef _MM2_FUNCTIONALITY
-#define DEFINED__MM2_FUNCTIONALITY " _MM2_FUNCTIONALITY"
-#define UNDEFINED__MM2_FUNCTIONALITY ""
-#else /* _MM2_FUNCTIONALITY */
-#define DEFINED__MM2_FUNCTIONALITY ""
-#define UNDEFINED__MM2_FUNCTIONALITY " _MM2_FUNCTIONALITY"
-#endif /* _MM2_FUNCTIONALITY */
-
-#ifdef _MM_FUNCTIONALITY
-#define DEFINED__MM_FUNCTIONALITY DEFINED__MM2_FUNCTIONALITY ## " _MM_FUNCTIONALITY"
-#define UNDEFINED__MM_FUNCTIONALITY UNDEFINED__MM2_FUNCTIONALITY
-#else /* _MM_FUNCTIONALITY */
-#define DEFINED__MM_FUNCTIONALITY DEFINED__MM2_FUNCTIONALITY
-#define UNDEFINED__MM_FUNCTIONALITY UNDEFINED__MM2_FUNCTIONALITY ## " _MM_FUNCTIONALITY"
-#endif /* _MM_FUNCTIONALITY */
-
-#ifdef _MM_NO_ABORT
-#define DEFINED__MM_NO_ABORT DEFINED__MM_FUNCTIONALITY ## " _MM_NO_ABORT"
-#define UNDEFINED__MM_NO_ABORT UNDEFINED__MM_FUNCTIONALITY
-#else /* _MM_NO_ABORT */
-#define DEFINED__MM_NO_ABORT DEFINED__MM_FUNCTIONALITY
-#define UNDEFINED__MM_NO_ABORT UNDEFINED__MM_FUNCTIONALITY ## " _MM_NO_ABORT"
-#endif /* _MM_NO_ABORT */
-
-#ifdef _MM_NO_ACCURACY
-#define DEFINED__MM_NO_ACCURACY DEFINED__MM_NO_ABORT ## " _MM_NO_ACCURACY"
-#define UNDEFINED__MM_NO_ACCURACY UNDEFINED__MM_NO_ABORT
-#else /* _MM_NO_ACCURACY */
-#define DEFINED__MM_NO_ACCURACY DEFINED__MM_NO_ABORT
-#define UNDEFINED__MM_NO_ACCURACY UNDEFINED__MM_NO_ABORT ## " _MM_NO_ACCURACY"
-#endif /* _MM_NO_ACCURACY */
-
-#ifdef _MM_NO_ALIGN_CHECK
-#define DEFINED__MM_NO_ALIGN_CHECK DEFINED__MM_NO_ACCURACY ## " _MM_NO_ALIGN_CHECK"
-#define UNDEFINED__MM_NO_ALIGN_CHECK UNDEFINED__MM_NO_ACCURACY
-#else /* _MM_NO_ALIGN_CHECK */
-#define DEFINED__MM_NO_ALIGN_CHECK DEFINED__MM_NO_ACCURACY
-#define UNDEFINED__MM_NO_ALIGN_CHECK UNDEFINED__MM_NO_ACCURACY ## " _MM_NO_ALIGN_CHECK"
-#endif /* _MM_NO_ALIGN_CHECK */
-
-#ifdef _MM_NO_INLINE
-#define DEFINED__MM_NO_INLINE DEFINED__MM_NO_ALIGN_CHECK ## " _MM_NO_INLINE"
-#define UNDEFINED__MM_NO_INLINE UNDEFINED__MM_NO_ALIGN_CHECK
-#else /* _MM_NO_INLINE */
-#define DEFINED__MM_NO_INLINE DEFINED__MM_NO_ALIGN_CHECK
-#define UNDEFINED__MM_NO_INLINE UNDEFINED__MM_NO_ALIGN_CHECK ## " _MM_NO_INLINE"
-#endif /* _MM_NO_INLINE */
-
-#pragma comment ( user, "comment:" __DATE__" " __TIME__ " - " __FILE__ ":" RW_STRINGIFY_EXPANDED(__LINE__) )
-#pragma comment ( user, "comment:" "DEFINED :" DEFINED__MM_NO_INLINE )
-#pragma comment ( user, "comment:" "UNDEFINED:" UNDEFINED__MM_NO_INLINE )
-
-#pragma message (__DATE__" " __TIME__ " - " __FILE__ ":" RW_STRINGIFY_EXPANDED(__LINE__) )
-#pragma message ("DEFINED :" DEFINED__MM_NO_INLINE )
-#pragma message ("UNDEFINED:" UNDEFINED__MM_NO_INLINE )
-
-#else /* (defined(__ICL)) */
-
-#define _MM_HINT_T0 1
-#define _MM_HINT_T1 2
-#define _MM_HINT_T2 3
-#define _MM_HINT_NTA 0
-
-#if (defined(__R5900__))
-typedef RwInt128 Rt_m128;
-#else /* (defined(__R5900__)) */
-#if (!defined(_PAIR__M64))
-struct Rt_m128
-{
- Rt_m64 lo;
- Rt_m64 hi;
-};
-#define _PAIR__M64
-typedef struct Rt_m128 Rt_m128;
-#endif /* (!defined(_PAIR__M64)) */
-#endif /* (defined(__R5900__)) */
-
-typedef Rt_m128 Rt_m128d;
-typedef Rt_m128 Rt_m128i;
-#endif /* (defined(__ICL)) */
-
-typedef struct RtIntelV4d RtIntelV4d;
-struct RtIntelV4d
-{
- RwReal w;
- RwV3d v3d;
-};
-
-typedef union _RpSSEOverlayM128 RpSSEOverlayM128;
-
-union _RpSSEOverlayM128
-{
- float _f[4];
- RwInt32 _d[4];
- RwUInt32 ud[4];
- RwInt16 _w[8];
- RwUInt16 uw[8];
- RwInt8 _b[16];
- RwUInt8 ub[16];
- Rt_m64 m64[2];
- Rt_m128 m128;
- RtIntelV4d v4d;
- RwSplitBits bits[4];
-};
-
-typedef RpSSEOverlayM128 RpWNIOverlayM128;
-
-typedef union _RpWNIOverlayM128d RpWNIOverlayM128d;
-
-union _RpWNIOverlayM128d
-{
- double df[2];
- float _f[4];
- RwInt32 _d[4];
- RwUInt32 ud[4];
- RwInt16 _w[8];
- RwUInt16 uw[8];
- RwInt8 _b[16];
- RwUInt8 ub[16];
- Rt_m64 m64[2];
- Rt_m128d m128d;
- RtIntelV4d v4d;
- RwSplitBits bits[4];
-};
-
-typedef union _RpWNIOverlayM128i RpWNIOverlayM128i;
-
-union _RpWNIOverlayM128i
-{
- double df[2];
- float _f[4];
- RwInt32 _d[4];
- RwUInt32 ud[4];
- RwInt16 _w[8];
- RwUInt16 uw[8];
- RwInt8 _b[16];
- RwUInt8 ub[16];
- Rt_m64 m64[2];
- Rt_m128i m128i;
- RtIntelV4d v4d;
- RwSplitBits bits[4];
-};
-
-#define RWUNALIGNED16BYTE(ptr) (0x0000000FUL & ((RwUInt32)(ptr)))
-
-/*--- Plugin API Functions ---*/
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-/*
- * MMX
- */
-
-/* General support intrinsics */
-extern void Rt_m_empty(void);
-extern Rt_m64 Rt_m_from_int(int i);
-extern int Rt_m_to_int(Rt_m64 m);
-extern Rt_m64 Rt_m_packsswb(Rt_m64 m1, Rt_m64 m2);
-extern Rt_m64 Rt_m_packssdw(Rt_m64 m1, Rt_m64 m2);
-extern Rt_m64 Rt_m_packuswb(Rt_m64 m1, Rt_m64 m2);
-extern Rt_m64 Rt_m_punpckhbw(Rt_m64 m1, Rt_m64 m2);
-extern Rt_m64 Rt_m_punpckhwd(Rt_m64 m1, Rt_m64 m2);
-extern Rt_m64 Rt_m_punpckhdq(Rt_m64 m1, Rt_m64 m2);
-extern Rt_m64 Rt_m_punpcklbw(Rt_m64 m1, Rt_m64 m2);
-extern Rt_m64 Rt_m_punpcklwd(Rt_m64 m1, Rt_m64 m2);
-extern Rt_m64 Rt_m_punpckldq(Rt_m64 m1, Rt_m64 m2);
-
-/* Packed arithmetic intrinsics */
-extern Rt_m64 Rt_m_paddb(Rt_m64 m1, Rt_m64 m2);
-extern Rt_m64 Rt_m_paddw(Rt_m64 m1, Rt_m64 m2);
-extern Rt_m64 Rt_m_paddd(Rt_m64 m1, Rt_m64 m2);
-extern Rt_m64 Rt_m_paddsb(Rt_m64 m1, Rt_m64 m2);
-extern Rt_m64 Rt_m_paddsw(Rt_m64 m1, Rt_m64 m2);
-extern Rt_m64 Rt_m_paddusb(Rt_m64 m1, Rt_m64 m2);
-extern Rt_m64 Rt_m_paddusw(Rt_m64 m1, Rt_m64 m2);
-extern Rt_m64 Rt_m_psubb(Rt_m64 m1, Rt_m64 m2);
-extern Rt_m64 Rt_m_psubw(Rt_m64 m1, Rt_m64 m2);
-extern Rt_m64 Rt_m_psubd(Rt_m64 m1, Rt_m64 m2);
-extern Rt_m64 Rt_m_psubsb(Rt_m64 m1, Rt_m64 m2);
-extern Rt_m64 Rt_m_psubsw(Rt_m64 m1, Rt_m64 m2);
-extern Rt_m64 Rt_m_psubusb(Rt_m64 m1, Rt_m64 m2);
-extern Rt_m64 Rt_m_psubusw(Rt_m64 m1, Rt_m64 m2);
-extern Rt_m64 Rt_m_pmaddwd(Rt_m64 m1, Rt_m64 m2);
-extern Rt_m64 Rt_m_pmulhw(Rt_m64 m1, Rt_m64 m2);
-extern Rt_m64 Rt_m_pmullw(Rt_m64 m1, Rt_m64 m2);
-
-/* Shift intrinsics */
-extern Rt_m64 Rt_m_psllw(Rt_m64 m, Rt_m64 count);
-extern Rt_m64 Rt_m_psllwi(Rt_m64 m, int count);
-extern Rt_m64 Rt_m_pslld(Rt_m64 m, Rt_m64 count);
-extern Rt_m64 Rt_m_pslldi(Rt_m64 m, int count);
-extern Rt_m64 Rt_m_psllq(Rt_m64 m, Rt_m64 count);
-extern Rt_m64 Rt_m_psllqi(Rt_m64 m, int count);
-extern Rt_m64 Rt_m_psraw(Rt_m64 m, Rt_m64 count);
-extern Rt_m64 Rt_m_psrawi(Rt_m64 m, int count);
-extern Rt_m64 Rt_m_psrad(Rt_m64 m, Rt_m64 count);
-extern Rt_m64 Rt_m_psradi(Rt_m64 m, int count);
-extern Rt_m64 Rt_m_psrlw(Rt_m64 m, Rt_m64 count);
-extern Rt_m64 Rt_m_psrlwi(Rt_m64 m, int count);
-extern Rt_m64 Rt_m_psrld(Rt_m64 m, Rt_m64 count);
-extern Rt_m64 Rt_m_psrldi(Rt_m64 m, int count);
-extern Rt_m64 Rt_m_psrlq(Rt_m64 m, Rt_m64 count);
-extern Rt_m64 Rt_m_psrlqi(Rt_m64 m, int count);
-
-/* Logical intrinsics */
-extern Rt_m64 Rt_m_pand(Rt_m64 m1, Rt_m64 m2);
-extern Rt_m64 Rt_m_pandn(Rt_m64 m1, Rt_m64 m2);
-extern Rt_m64 Rt_m_por(Rt_m64 m1, Rt_m64 m2);
-extern Rt_m64 Rt_m_pxor(Rt_m64 m1, Rt_m64 m2);
-
-/* Comparision intrinsics */
-extern Rt_m64 Rt_m_pcmpeqb(Rt_m64 m1, Rt_m64 m2);
-extern Rt_m64 Rt_m_pcmpeqw(Rt_m64 m1, Rt_m64 m2);
-extern Rt_m64 Rt_m_pcmpeqd(Rt_m64 m1, Rt_m64 m2);
-extern Rt_m64 Rt_m_pcmpgtb(Rt_m64 m1, Rt_m64 m2);
-extern Rt_m64 Rt_m_pcmpgtw(Rt_m64 m1, Rt_m64 m2);
-extern Rt_m64 Rt_m_pcmpgtd(Rt_m64 m1, Rt_m64 m2);
-
-/*
- * SSE
- */
-
-/*
- * Arithmetic Operations
- */
-
-extern Rt_m128 Rt_mm_add_ss(Rt_m128 a, Rt_m128 b) /* ADDSS */ ;
-extern Rt_m128 Rt_mm_add_ps(Rt_m128 a, Rt_m128 b) /* ADDPS */ ;
-extern Rt_m128 Rt_mm_sub_ss(Rt_m128 a, Rt_m128 b) /* SUBSS */ ;
-extern Rt_m128 Rt_mm_sub_ps(Rt_m128 a, Rt_m128 b) /* SUBPS */ ;
-extern Rt_m128 Rt_mm_mul_ss(Rt_m128 a, Rt_m128 b) /* MULSS */ ;
-extern Rt_m128 Rt_mm_mul_ps(Rt_m128 a, Rt_m128 b) /* MULPS */ ;
-extern Rt_m128 Rt_mm_div_ss(Rt_m128 a, Rt_m128 b) /* DIVSS */ ;
-extern Rt_m128 Rt_mm_div_ps(Rt_m128 a, Rt_m128 b) /* DIVPS */ ;
-extern Rt_m128 Rt_mm_sqrt_ss(Rt_m128 a) /* SQRTSS */ ;
-extern Rt_m128 Rt_mm_sqrt_ps(Rt_m128 a) /* SQRTPS */ ;
-extern Rt_m128 Rt_mm_rcp_ss(Rt_m128 a) /* RCPSS */ ;
-extern Rt_m128 Rt_mm_rcp_ps(Rt_m128 a) /* RCPPS */ ;
-extern Rt_m128 Rt_mm_rsqrt_ss(Rt_m128 a) /* RSQRTSS */ ;
-extern Rt_m128 Rt_mm_rsqrt_ps(Rt_m128 a) /* RSQRTPS */ ;
-extern Rt_m128 Rt_mm_min_ss(Rt_m128 a, Rt_m128 b) /* MINSS */ ;
-extern Rt_m128 Rt_mm_min_ps(Rt_m128 a, Rt_m128 b) /* MINPS */ ;
-extern Rt_m128 Rt_mm_max_ss(Rt_m128 a, Rt_m128 b) /* MAXSS */ ;
-extern Rt_m128 Rt_mm_max_ps(Rt_m128 a, Rt_m128 b) /* MAXPS */ ;
-
-/*
- * Logical Operations
- */
-
-extern Rt_m128 Rt_mm_and_ps(Rt_m128 a, Rt_m128 b) /* ANDPS */ ;
-extern Rt_m128 Rt_mm_andnot_ps(Rt_m128 a,
- Rt_m128 b) /* ANDNPS */ ;
-extern Rt_m128 Rt_mm_or_ps(Rt_m128 a, Rt_m128 b) /* ORPS */ ;
-extern Rt_m128 Rt_mm_xor_ps(Rt_m128 a, Rt_m128 b) /* XORPS */ ;
-
-/*
- * Comparisons
- */
-
-extern Rt_m128 Rt_mm_cmpeq_ss(Rt_m128 a,
- Rt_m128 b) /* CMPEQSS */ ;
-extern Rt_m128 Rt_mm_cmpeq_ps(Rt_m128 a,
- Rt_m128 b) /* CMPEQPS */ ;
-extern Rt_m128 Rt_mm_cmplt_ss(Rt_m128 a,
- Rt_m128 b) /* CMPLTSS */ ;
-extern Rt_m128 Rt_mm_cmplt_ps(Rt_m128 a,
- Rt_m128 b) /* CMPLTPS */ ;
-extern Rt_m128 Rt_mm_cmple_ss(Rt_m128 a,
- Rt_m128 b) /* CMPLESS */ ;
-extern Rt_m128 Rt_mm_cmple_ps(Rt_m128 a,
- Rt_m128 b) /* CMPLEPS */ ;
-extern Rt_m128 Rt_mm_cmpgt_ss(Rt_m128 a, Rt_m128 b) /* CMPLTSS r */
- ;
-extern Rt_m128 Rt_mm_cmpgt_ps(Rt_m128 a, Rt_m128 b) /* CMPLTPS r */
- ;
-extern Rt_m128 Rt_mm_cmpge_ss(Rt_m128 a, Rt_m128 b) /* CMPLESS r */
- ;
-extern Rt_m128 Rt_mm_cmpge_ps(Rt_m128 a, Rt_m128 b) /* CMPLEPS r */
- ;
-extern Rt_m128 Rt_mm_cmpneq_ss(Rt_m128 a,
- Rt_m128 b) /* CMPNEQSS */ ;
-extern Rt_m128 Rt_mm_cmpneq_ps(Rt_m128 a,
- Rt_m128 b) /* CMPNEQPS */ ;
-extern Rt_m128 Rt_mm_cmpnlt_ss(Rt_m128 a,
- Rt_m128 b) /* CMPNLTSS */ ;
-extern Rt_m128 Rt_mm_cmpnlt_ps(Rt_m128 a,
- Rt_m128 b) /* CMPNLTPS */ ;
-extern Rt_m128 Rt_mm_cmpnle_ss(Rt_m128 a,
- Rt_m128 b) /* CMPNLESS */ ;
-extern Rt_m128 Rt_mm_cmpnle_ps(Rt_m128 a,
- Rt_m128 b) /* CMPNLEPS */ ;
-extern Rt_m128 Rt_mm_cmpngt_ss(Rt_m128 a, Rt_m128 b)
- /* CMPNLTSS r */ ;
-extern Rt_m128 Rt_mm_cmpngt_ps(Rt_m128 a, Rt_m128 b)
- /* CMPNLTPS r */ ;
-extern Rt_m128 Rt_mm_cmpnge_ss(Rt_m128 a, Rt_m128 b)
- /* CMPNLESS r */ ;
-extern Rt_m128 Rt_mm_cmpnge_ps(Rt_m128 a, Rt_m128 b)
- /* CMPNLEPS r */ ;
-extern Rt_m128 Rt_mm_cmpord_ss(Rt_m128 a,
- Rt_m128 b) /* CMPORDSS */ ;
-extern Rt_m128 Rt_mm_cmpord_ps(Rt_m128 a,
- Rt_m128 b) /* CMPORDPS */ ;
-extern Rt_m128 Rt_mm_cmpunord_ss(Rt_m128 a,
- Rt_m128 b) /* CMPUNORDSS */ ;
-extern Rt_m128 Rt_mm_cmpunord_ps(Rt_m128 a,
- Rt_m128 b) /* CMPUNORDPS */ ;
-extern int Rt_mm_comieq_ss(Rt_m128 a,
- Rt_m128 b) /* COMISS */ ;
-extern int Rt_mm_comilt_ss(Rt_m128 a,
- Rt_m128 b) /* COMISS */ ;
-extern int Rt_mm_comile_ss(Rt_m128 a,
- Rt_m128 b) /* COMISS */ ;
-extern int Rt_mm_comigt_ss(Rt_m128 a,
- Rt_m128 b) /* COMISS */ ;
-extern int Rt_mm_comige_ss(Rt_m128 a,
- Rt_m128 b) /* COMISS */ ;
-extern int Rt_mm_comineq_ss(Rt_m128 a,
- Rt_m128 b) /* COMISS */ ;
-extern int Rt_mm_ucomieq_ss(Rt_m128 a,
- Rt_m128 b) /* UCOMISS */ ;
-extern int Rt_mm_ucomilt_ss(Rt_m128 a,
- Rt_m128 b) /* UCOMISS */ ;
-extern int Rt_mm_ucomile_ss(Rt_m128 a,
- Rt_m128 b) /* UCOMISS */ ;
-extern int Rt_mm_ucomigt_ss(Rt_m128 a,
- Rt_m128 b) /* UCOMISS */ ;
-extern int Rt_mm_ucomige_ss(Rt_m128 a,
- Rt_m128 b) /* UCOMISS */ ;
-extern int Rt_mm_ucomineq_ss(Rt_m128 a,
- Rt_m128 b) /* UCOMISS */ ;
-
-/*
- * Conversion Operations
- */
-
-extern int Rt_mm_cvt_ss2si(Rt_m128 a) /* CVTSS2SI */ ;
-extern Rt_m64 Rt_mm_cvt_ps2pi(Rt_m128 a) /* CVTPS2PI */ ;
-extern int Rt_mm_cvtt_ss2si(Rt_m128 a) /* CVTTSS2SI */ ;
-extern Rt_m64 Rt_mm_cvtt_ps2pi(Rt_m128 a) /* CVTTPS2PI */ ;
-extern Rt_m128 Rt_mm_cvt_si2ss(Rt_m128 a,
- int b) /* CVTSI2SS */ ;
-extern Rt_m128 Rt_mm_cvt_pi2ps(Rt_m128 a,
- Rt_m64 b) /* CVTPI2PS */ ;
-
-/*
- * Miscellaneous
- */
-
-extern Rt_m128 Rt_mm_shuffle_ps(Rt_m128 a, Rt_m128 b,
- int i) /* SHUFPS */ ;
-extern Rt_m128 Rt_mm_unpackhi_ps(Rt_m128 a,
- Rt_m128 b) /* UNPCKHPS */ ;
-extern Rt_m128 Rt_mm_unpacklo_ps(Rt_m128 a,
- Rt_m128 b) /* UNPCKLPS */ ;
-extern Rt_m128 Rt_mm_loadh_pi(Rt_m128 a, Rt_m64 * p) /* MOVHPS reg, mem */
- ;
-extern void Rt_mm_storeh_pi(Rt_m64 * p, Rt_m128 a) /* MOVHPS mem, reg */
- ;
-extern Rt_m128 Rt_mm_movehl_ps(Rt_m128 a,
- Rt_m128 b) /* MOVHLPS */ ;
-extern Rt_m128 Rt_mm_movelh_ps(Rt_m128 a,
- Rt_m128 b) /* MOVLHPS */ ;
-extern Rt_m128 Rt_mm_loadl_pi(Rt_m128 a, Rt_m64 * p)
- /* MOVLPS reg, mem */ ;
-extern void Rt_mm_storel_pi(Rt_m64 * p, Rt_m128 a) /* MOVLPS mem, reg */
- ;
-extern int Rt_mm_movemask_ps(Rt_m128 a) /* MOVMSKPS */ ;
-extern unsigned int Rt_mm_getcsr(void) /* STMXCSR */ ;
-extern void Rt_mm_setcsr(unsigned int i) /* LDMXCSR */ ;
-
-/*
- * Load Operations
- */
-
-extern Rt_m128 Rt_mm_load_ss(float *p) /* MOVSS */ ;
-extern Rt_m128 Rt_mm_load_ps1(float *p) /* MOVSS + shuffling */
- ;
-extern Rt_m128 Rt_mm_load_ps(float *p) /* MOVAPS */ ;
-extern Rt_m128 Rt_mm_loadu_ps(float *p) /* MOVUPS */ ;
-extern Rt_m128 Rt_mm_loadr_ps(float *p)
- /* MOVAPS + shuffling */ ;
-
-/*
- * Set Operations
- */
-
-extern Rt_m128 Rt_mm_set_ss(float w) /* (composite) */ ;
-extern Rt_m128 Rt_mm_set_ps1(float w) /* (composite) */ ;
-extern Rt_m128 Rt_mm_set_ps(float z, float y, float x,
- float w) /* (composite) */ ;
-extern Rt_m128 Rt_mm_setr_ps(float z, float y, float x,
- float w) /* (composite) */ ;
-extern Rt_m128 Rt_mm_setzero_ps(void) /* (composite) */ ;
-
-/*
- * Store Operations
- */
-
-extern void Rt_mm_store_ss(float *p,
- Rt_m128 a) /* MOVSS */ ;
-extern void Rt_mm_store_ps1(float *p, Rt_m128 a)
- /* MOVSS + shuffling */ ;
-extern void Rt_mm_store_ps(float *p,
- Rt_m128 a) /* MOVAPS */ ;
-extern void Rt_mm_storeu_ps(float *p,
- Rt_m128 a) /* MOVUPS */ ;
-extern void Rt_mm_storer_ps(float *p, Rt_m128 a)
- /* MOVAPS + shuffling */ ;
-extern Rt_m128 Rt_mm_move_ss(Rt_m128 a,
- Rt_m128 b) /* MOVSS */ ;
-
-/*
- * Integer Intrinsics
- */
-
-extern int Rt_m_pextrw(Rt_m64 a, int n) /* PEXTRW */ ;
-extern Rt_m64 Rt_m_pinsrw(Rt_m64 a, int d,
- int n) /* PINSRW */ ;
-extern Rt_m64 Rt_m_pmaxsw(Rt_m64 a, Rt_m64 b) /* PMAXSW */ ;
-extern Rt_m64 Rt_m_pmaxub(Rt_m64 a, Rt_m64 b) /* PMAXUB */ ;
-extern Rt_m64 Rt_m_pminsw(Rt_m64 a, Rt_m64 b) /* PMINSW */ ;
-extern Rt_m64 Rt_m_pminub(Rt_m64 a, Rt_m64 b) /* PMINUB */ ;
-extern int Rt_m_pmovmskb(Rt_m64 a) /* PMOVMSKB */ ;
-extern Rt_m64 Rt_m_pmulhuw(Rt_m64 a, Rt_m64 b) /* PMULHUW */ ;
-extern Rt_m64 Rt_m_pshufw(Rt_m64 a, int n) /* PSHUFW */ ;
-extern void Rt_m_lwmaskmovq(Rt_m64 d, Rt_m64 n,
- char *p) /* MASKMOVQ */ ;
-
-/*
- * Cacheability Support
- */
-
-extern void Rt_mm_prefetch(char *p, int i) /* PREFETCH */ ;
-extern void Rt_mm_stream_pi(Rt_m64 * p,
- Rt_m64 a) /* MOVNTQ */ ;
-extern void Rt_mm_stream_ps(float *p,
- Rt_m128 a) /* MOVNTPS */ ;
-extern void Rt_mm_sfence(void) /* SFENCE */ ;
-
-/*
- * WNI
- */
-
-/* Arithmetic Operations */
-
-extern Rt_m128d Rt_mm_add_sd(Rt_m128d a, Rt_m128d b);
-extern Rt_m128d Rt_mm_add_pd(Rt_m128d a, Rt_m128d b);
-extern Rt_m128d Rt_mm_div_sd(Rt_m128d a, Rt_m128d b);
-extern Rt_m128d Rt_mm_div_pd(Rt_m128d a, Rt_m128d b);
-extern Rt_m128d Rt_mm_max_sd(Rt_m128d a, Rt_m128d b);
-extern Rt_m128d Rt_mm_max_pd(Rt_m128d a, Rt_m128d b);
-extern Rt_m128d Rt_mm_min_sd(Rt_m128d a, Rt_m128d b);
-extern Rt_m128d Rt_mm_min_pd(Rt_m128d a, Rt_m128d b);
-extern Rt_m128d Rt_mm_mul_sd(Rt_m128d a, Rt_m128d b);
-extern Rt_m128d Rt_mm_mul_pd(Rt_m128d a, Rt_m128d b);
-extern Rt_m128d Rt_mm_sqrt_sd(Rt_m128d a, Rt_m128d b);
-extern Rt_m128d Rt_mm_sqrt_pd(Rt_m128d a);
-extern Rt_m128d Rt_mm_sub_sd(Rt_m128d a, Rt_m128d b);
-extern Rt_m128d Rt_mm_sub_pd(Rt_m128d a, Rt_m128d b);
-extern Rt_m128d Rt_mm_andnot_pd(Rt_m128d a, Rt_m128d b);
-extern Rt_m128d Rt_mm_and_pd(Rt_m128d a, Rt_m128d b);
-extern Rt_m128d Rt_mm_or_pd(Rt_m128d a, Rt_m128d b);
-extern Rt_m128d Rt_mm_xor_pd(Rt_m128d a, Rt_m128d b);
-
-/* Comparisons */
-
-extern Rt_m128d Rt_mm_cmpeq_pd(Rt_m128d a, Rt_m128d b);
-extern Rt_m128d Rt_mm_cmplt_pd(Rt_m128d a, Rt_m128d b);
-extern Rt_m128d Rt_mm_cmple_pd(Rt_m128d a, Rt_m128d b);
-extern Rt_m128d Rt_mm_cmpgt_pd(Rt_m128d a, Rt_m128d b);
-extern Rt_m128d Rt_mm_cmpge_pd(Rt_m128d a, Rt_m128d b);
-extern Rt_m128d Rt_mm_cmpord_pd(Rt_m128d a, Rt_m128d b);
-extern Rt_m128d Rt_mm_cmpunord_pd(Rt_m128d a, Rt_m128d b);
-extern Rt_m128d Rt_mm_cmpneq_pd(Rt_m128d a, Rt_m128d b);
-extern Rt_m128d Rt_mm_cmpnlt_pd(Rt_m128d a, Rt_m128d b);
-extern Rt_m128d Rt_mm_cmpnle_pd(Rt_m128d a, Rt_m128d b);
-extern Rt_m128d Rt_mm_cmpngt_pd(Rt_m128d a, Rt_m128d b);
-extern Rt_m128d Rt_mm_cmpnge_pd(Rt_m128d a, Rt_m128d b);
-extern Rt_m128d Rt_mm_cmpeq_sd(Rt_m128d a, Rt_m128d b);
-extern Rt_m128d Rt_mm_cmplt_sd(Rt_m128d a, Rt_m128d b);
-extern Rt_m128d Rt_mm_cmple_sd(Rt_m128d a, Rt_m128d b);
-extern Rt_m128d Rt_mm_cmpgt_sd(Rt_m128d a, Rt_m128d b);
-extern Rt_m128d Rt_mm_cmpge_sd(Rt_m128d a, Rt_m128d b);
-extern Rt_m128d Rt_mm_cmpord_sd(Rt_m128d a, Rt_m128d b);
-extern Rt_m128d Rt_mm_cmpunord_sd(Rt_m128d a, Rt_m128d b);
-extern Rt_m128d Rt_mm_cmpneq_sd(Rt_m128d a, Rt_m128d b);
-extern Rt_m128d Rt_mm_cmpnlt_sd(Rt_m128d a, Rt_m128d b);
-extern Rt_m128d Rt_mm_cmpnle_sd(Rt_m128d a, Rt_m128d b);
-extern Rt_m128d Rt_mm_cmpngt_sd(Rt_m128d a, Rt_m128d b);
-extern Rt_m128d Rt_mm_cmpnge_sd(Rt_m128d a, Rt_m128d b);
-extern int Rt_mm_comieq_sd(Rt_m128d a, Rt_m128d b);
-extern int Rt_mm_comilt_sd(Rt_m128d a, Rt_m128d b);
-extern int Rt_mm_comile_sd(Rt_m128d a, Rt_m128d b);
-extern int Rt_mm_comigt_sd(Rt_m128d a, Rt_m128d b);
-extern int Rt_mm_comige_sd(Rt_m128d a, Rt_m128d b);
-extern int Rt_mm_comineq_sd(Rt_m128d a, Rt_m128d b);
-extern int Rt_mm_ucomieq_sd(Rt_m128d a, Rt_m128d b);
-extern int Rt_mm_ucomilt_sd(Rt_m128d a, Rt_m128d b);
-extern int Rt_mm_ucomile_sd(Rt_m128d a, Rt_m128d b);
-extern int Rt_mm_ucomigt_sd(Rt_m128d a, Rt_m128d b);
-extern int Rt_mm_ucomige_sd(Rt_m128d a, Rt_m128d b);
-extern int Rt_mm_ucomineq_sd(Rt_m128d a, Rt_m128d b);
-
-/* Conversion Operations */
-
-extern Rt_m128 Rt_mm_cvtpd_ps(Rt_m128d a);
-extern Rt_m128d Rt_mm_cvtps_pd(Rt_m128 a);
-extern Rt_m128d Rt_mm_cvtepi32_pd(Rt_m128i a);
-extern Rt_m128i Rt_mm_cvtpd_epi32(Rt_m128d a);
-extern int Rt_mm_cvtsd_si32(Rt_m128d a);
-extern Rt_m128 Rt_mm_cvtsd_ss(Rt_m128 a, Rt_m128d b);
-extern Rt_m128d Rt_mm_cvtsi32_sd(Rt_m128d a, int b);
-extern Rt_m128d Rt_mm_cvtss_sd(Rt_m128d a, Rt_m128 b);
-extern Rt_m128i Rt_mm_cvttpd_epi32(Rt_m128d a);
-extern int Rt_mm_cvttsd_si32(Rt_m128d a);
-extern Rt_m128 Rt_mm_cvtepi32_ps(Rt_m128i a);
-extern Rt_m128i Rt_mm_cvtps_epi32(Rt_m128 a);
-extern Rt_m128i Rt_mm_cvttps_epi32(Rt_m128 a);
-extern Rt_m64 Rt_mm_cvtpd_pi32(Rt_m128d a);
-extern Rt_m64 Rt_mm_cvttpd_pi32(Rt_m128d a);
-extern Rt_m128d Rt_mm_cvtpi32_pd(Rt_m64 a);
-
-/* Miscellaneous Operations */
-
-extern Rt_m128d Rt_mm_unpackhi_pd(Rt_m128d a, Rt_m128d b);
-extern Rt_m128d Rt_mm_unpacklo_pd(Rt_m128d a, Rt_m128d b);
-extern int Rt_mm_movemask_pd(Rt_m128d a);
-extern Rt_m128d Rt_mm_shuffle_pd(Rt_m128d a, Rt_m128d b, int i);
-extern Rt_m128d Rt_mm_load_pd(const double *p);
-extern Rt_m128d Rt_mm_load1_pd(const double *p);
-extern Rt_m128d Rt_mm_loadr_pd(const double *p);
-extern Rt_m128d Rt_mm_loadu_pd(const double *p);
-extern Rt_m128d Rt_mm_load_sd(const double *p);
-extern Rt_m128d Rt_mm_loadh_pd(Rt_m128d a, const double *p);
-extern Rt_m128d Rt_mm_loadl_pd(Rt_m128d a, const double *p);
-extern Rt_m128d Rt_mm_set_sd(double w);
-extern Rt_m128d Rt_mm_set1_pd(double w);
-extern Rt_m128d Rt_mm_set_pd(double w, double x);
-extern Rt_m128d Rt_mm_setr_pd(double w, double x);
-extern Rt_m128d Rt_mm_setzero_pd(void);
-extern Rt_m128d Rt_mm_move_sd(Rt_m128d a, Rt_m128d b);
-extern void Rt_mm_stream_pd(double *p, Rt_m128d a);
-extern void Rt_mm_store_sd(double *p, Rt_m128d a);
-extern void Rt_mm_store1_pd(double *p, Rt_m128d a);
-extern void Rt_mm_store_pd(double *p, Rt_m128d a);
-extern void Rt_mm_storeu_pd(double *p, Rt_m128d a);
-extern void Rt_mm_storer_pd(double *p, Rt_m128d a);
-extern void Rt_mm_storeh_pd(double *p, Rt_m128d a);
-extern void Rt_mm_storel_pd(double *p, Rt_m128d a);
-extern Rt_m128i Rt_mm_add_epi8(Rt_m128i a, Rt_m128i b);
-extern Rt_m128i Rt_mm_add_epi16(Rt_m128i a, Rt_m128i b);
-extern Rt_m128i Rt_mm_add_epi32(Rt_m128i a, Rt_m128i b);
-extern Rt_m64 Rt_mm_add_si64(Rt_m64 a, Rt_m64 b);
-extern Rt_m128i Rt_mm_add_epi64(Rt_m128i a, Rt_m128i b);
-extern Rt_m128i Rt_mm_adds_epi8(Rt_m128i a, Rt_m128i b);
-extern Rt_m128i Rt_mm_adds_epi16(Rt_m128i a, Rt_m128i b);
-extern Rt_m128i Rt_mm_adds_epu8(Rt_m128i a, Rt_m128i b);
-extern Rt_m128i Rt_mm_adds_epu16(Rt_m128i a, Rt_m128i b);
-extern Rt_m128i Rt_mm_avg_epu8(Rt_m128i a, Rt_m128i b);
-extern Rt_m128i Rt_mm_avg_epu16(Rt_m128i a, Rt_m128i b);
-extern Rt_m128i Rt_mm_madd_epi16(Rt_m128i a, Rt_m128i b);
-extern Rt_m128i Rt_mm_max_epi16(Rt_m128i a, Rt_m128i b);
-extern Rt_m128i Rt_mm_max_epu8(Rt_m128i a, Rt_m128i b);
-extern Rt_m128i Rt_mm_min_epi16(Rt_m128i a, Rt_m128i b);
-extern Rt_m128i Rt_mm_min_epu8(Rt_m128i a, Rt_m128i b);
-extern Rt_m128i Rt_mm_mulhi_epi16(Rt_m128i a, Rt_m128i b);
-extern Rt_m128i Rt_mm_mulhi_epu16(Rt_m128i a, Rt_m128i b);
-extern Rt_m128i Rt_mm_mullo_epi16(Rt_m128i a, Rt_m128i b);
-extern Rt_m64 Rt_mm_mul_su32(Rt_m64 a, Rt_m64 b);
-extern Rt_m128i Rt_mm_mul_epu32(Rt_m128i a, Rt_m128i b);
-extern Rt_m128i Rt_mm_sad_epu8(Rt_m128i a, Rt_m128i b);
-extern Rt_m128i Rt_mm_sub_epi8(Rt_m128i a, Rt_m128i b);
-extern Rt_m128i Rt_mm_sub_epi16(Rt_m128i a, Rt_m128i b);
-extern Rt_m128i Rt_mm_sub_epi32(Rt_m128i a, Rt_m128i b);
-extern Rt_m64 Rt_mm_sub_si64(Rt_m64 a, Rt_m64 b);
-extern Rt_m128i Rt_mm_sub_epi64(Rt_m128i a, Rt_m128i b);
-extern Rt_m128i Rt_mm_subs_epi8(Rt_m128i a, Rt_m128i b);
-extern Rt_m128i Rt_mm_subs_epi16(Rt_m128i a, Rt_m128i b);
-extern Rt_m128i Rt_mm_subs_epu8(Rt_m128i a, Rt_m128i b);
-extern Rt_m128i Rt_mm_subs_epu16(Rt_m128i a, Rt_m128i b);
-extern Rt_m128i Rt_mm_and_si128(Rt_m128i a, Rt_m128i b);
-extern Rt_m128i Rt_mm_andnot_si128(Rt_m128i a, Rt_m128i b);
-extern Rt_m128i Rt_mm_or_si128(Rt_m128i a, Rt_m128i b);
-extern Rt_m128i Rt_mm_xor_si128(Rt_m128i a, Rt_m128i b);
-extern Rt_m128i Rt_mm_slli_si128(Rt_m128i a, int imm);
-extern Rt_m128i Rt_mm_slli_epi16(Rt_m128i a, int count);
-extern Rt_m128i Rt_mm_sll_epi16(Rt_m128i a, Rt_m128i count);
-extern Rt_m128i Rt_mm_slli_epi32(Rt_m128i a, int count);
-extern Rt_m128i Rt_mm_sll_epi32(Rt_m128i a, Rt_m128i count);
-extern Rt_m128i Rt_mm_slli_epi64(Rt_m128i a, int count);
-extern Rt_m128i Rt_mm_sll_epi64(Rt_m128i a, Rt_m128i count);
-extern Rt_m128i Rt_mm_srai_epi16(Rt_m128i a, int count);
-extern Rt_m128i Rt_mm_sra_epi16(Rt_m128i a, Rt_m128i count);
-extern Rt_m128i Rt_mm_srai_epi32(Rt_m128i a, int count);
-extern Rt_m128i Rt_mm_sra_epi32(Rt_m128i a, Rt_m128i count);
-extern Rt_m128i Rt_mm_srli_si128(Rt_m128i a, int imm);
-extern Rt_m128i Rt_mm_srli_epi16(Rt_m128i a, int count);
-extern Rt_m128i Rt_mm_srl_epi16(Rt_m128i a, Rt_m128i count);
-extern Rt_m128i Rt_mm_srli_epi32(Rt_m128i a, int count);
-extern Rt_m128i Rt_mm_srl_epi32(Rt_m128i a, Rt_m128i count);
-extern Rt_m128i Rt_mm_srli_epi64(Rt_m128i a, int count);
-extern Rt_m128i Rt_mm_srl_epi64(Rt_m128i a, Rt_m128i count);
-extern Rt_m128i Rt_mm_cmpeq_epi8(Rt_m128i a, Rt_m128i b);
-extern Rt_m128i Rt_mm_cmpeq_epi16(Rt_m128i a, Rt_m128i b);
-extern Rt_m128i Rt_mm_cmpeq_epi32(Rt_m128i a, Rt_m128i b);
-extern Rt_m128i Rt_mm_cmpgt_epi8(Rt_m128i a, Rt_m128i b);
-extern Rt_m128i Rt_mm_cmpgt_epi16(Rt_m128i a, Rt_m128i b);
-extern Rt_m128i Rt_mm_cmpgt_epi32(Rt_m128i a, Rt_m128i b);
-extern Rt_m128i Rt_mm_cmplt_epi8(Rt_m128i a, Rt_m128i b);
-extern Rt_m128i Rt_mm_cmplt_epi16(Rt_m128i a, Rt_m128i b);
-extern Rt_m128i Rt_mm_cmplt_epi32(Rt_m128i a, Rt_m128i b);
-extern Rt_m128i Rt_mm_cvtsi32_si128(int a);
-extern int Rt_mm_cvtsi128_si32(Rt_m128i a);
-
-/* Miscellaneous Operations */
-
-extern Rt_m64 Rt_mm_movepi64_pi64(Rt_m128i a);
-extern Rt_m128i Rt_mm_movpi64_epi64(Rt_m64 a);
-extern Rt_m128i Rt_mm_move_epi64(Rt_m128i a);
-extern Rt_m128i Rt_mm_packs_epi16(Rt_m128i a, Rt_m128i b);
-extern Rt_m128i Rt_mm_packs_epi32(Rt_m128i a, Rt_m128i b);
-extern Rt_m128i Rt_mm_packus_epi16(Rt_m128i a, Rt_m128i b);
-extern int Rt_mm_extract_epi16(Rt_m128i a, int imm);
-extern Rt_m128i Rt_mm_insert_epi16(Rt_m128i a, int b, int imm);
-extern int Rt_mm_movemask_epi8(Rt_m128i a);
-extern Rt_m128i Rt_mm_shuffle_epi32(Rt_m128i a, int imm);
-extern Rt_m128i Rt_mm_shufflehi_epi16(Rt_m128i a, int imm);
-extern Rt_m128i Rt_mm_shufflelo_epi16(Rt_m128i a, int imm);
-extern Rt_m128i Rt_mm_unpackhi_epi8(Rt_m128i a, Rt_m128i b);
-extern Rt_m128i Rt_mm_unpackhi_epi16(Rt_m128i a, Rt_m128i b);
-extern Rt_m128i Rt_mm_unpackhi_epi32(Rt_m128i a, Rt_m128i b);
-extern Rt_m128i Rt_mm_unpackhi_epi64(Rt_m128i a, Rt_m128i b);
-extern Rt_m128i Rt_mm_unpacklo_epi8(Rt_m128i a, Rt_m128i b);
-extern Rt_m128i Rt_mm_unpacklo_epi16(Rt_m128i a, Rt_m128i b);
-extern Rt_m128i Rt_mm_unpacklo_epi32(Rt_m128i a, Rt_m128i b);
-extern Rt_m128i Rt_mm_unpacklo_epi64(Rt_m128i a, Rt_m128i b);
-extern Rt_m128i Rt_mm_loadl_epi64(Rt_m128i const *p);
-extern Rt_m128i Rt_mm_load_si128(const Rt_m128i * p);
-extern Rt_m128i Rt_mm_loadu_si128(const Rt_m128i * p);
-extern Rt_m128i Rt_mm_set_epi64(Rt_m64 q1, Rt_m64 q0);
-extern Rt_m128i Rt_mm_set_epi32(int i3, int i2, int i1, int i0);
-extern Rt_m128i
- Rt_mm_set_epi16(short w7, short w6,
- short w5, short w4, short w3, short w2,
- short w1, short w0);
-extern Rt_m128i Rt_mm_set_epi8(char b15, char b14,
- char b13, char b12,
- char b11, char b10,
- char b9, char b8,
- char b7, char b6,
- char b5, char b4,
- char b3, char b2,
- char b1, char b0);
-extern Rt_m128i Rt_mm_set1_epi64(Rt_m64 q);
-extern Rt_m128i Rt_mm_set1_epi32(int i);
-extern Rt_m128i Rt_mm_set1_epi16(short w);
-extern Rt_m128i Rt_mm_set1_epi8(char b);
-extern Rt_m128i Rt_mm_setr_epi64(Rt_m64 q0, Rt_m64 q1);
-extern Rt_m128i Rt_mm_setr_epi32(int i0, int i1, int i2,
- int i3);
-extern Rt_m128i Rt_mm_setr_epi16(short w0, short w1,
- short w2, short w3,
- short w4, short w5,
- short w6, short w7);
-extern Rt_m128i Rt_mm_setr_epi8(char b0, char b1,
- char b2, char b3,
- char b4, char b5,
- char b6, char b7,
- char b8, char b9,
- char b10, char b11,
- char b12, char b13,
- char b14, char b15);
-extern Rt_m128i Rt_mm_setzero_si128(void);
-
-/* Store Operations */
-
-extern void Rt_mm_store_si128(Rt_m128i * p, Rt_m128i a);
-extern void Rt_mm_storeu_si128(Rt_m128i * p, Rt_m128i a);
-extern void Rt_mm_maskmoveu_si128(Rt_m128i s, Rt_m128i n,
- char *p);
-extern void Rt_mm_storel_epi64(Rt_m128i * p, Rt_m128i a);
-extern void Rt_mm_stream_si128(Rt_m128i * p, Rt_m128i a);
-extern void Rt_mm_stream_si32(int *p, int a);
-extern void Rt_mm_clflush(void const *p);
-extern void Rt_mm_lfence(void);
-extern void Rt_mm_mfence(void);
-
-/*
- * API
- */
-extern RwUInt32 RtIntelRDTSC(void);
-extern RwUInt32 RtIntelToggleEFLAGS(int mask);
-extern RwUInt32 RtIntelCPUID(RwUInt32 level,
- void *pb, void *pc, void *pd);
-extern RwUInt32 RtIntelHaveCPUID(void);
-extern RwUInt32 RtIntelHaveRDTSC(void);
-extern RwUInt32 RtIntelHaveMMX(void);
-extern RwUInt32 RtIntelHaveSSE(void);
-extern RwUInt32 RtIntelHaveWNI(void);
-extern RwUInt32 RtIntelCpuType(void);
-
-extern RwBool RtIntelStartTiming(void * data);
-extern RwBool RtIntelStopTiming(void *data);
-extern RwBool RtIntelTime(RwFixed64 * result,
- RtIntelTimeFunction func,
- void *data);
-
-extern RwBool RtIntelPluginAttach(void);
-
-extern RtIntelOverload *_rtIntelOverloadGetHandle(void);
-
-extern RxNodeDefinition *RxNodeDefinitionGetSSETransformCSL(void);
-
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-/*
- * LEGACY-SUPPORT -- e.g.
- * rwsdk/driver/d3d/baintd3d.c
- * is locked at time of writing
- */
-
-#define RpIntelRDTSC() RtIntelRDTSC()
-#define RpIntelToggleEFLAGS(_mask) RtIntelToggleEFLAGS(_mask)
-#define RpIntelCPUID(_level, _pb, _pc, _pd) \
- RtIntelCPUID(_level, _pb, _pc, _pd)
-#define RpIntelHaveCPUID() RtIntelHaveCPUID()
-#define RpIntelHaveRDTSC() RtIntelHaveRDTSC()
-#define RpIntelHaveMMX() RtIntelHaveMMX()
-#define RpIntelHaveSSE() RtIntelHaveSSE()
-#define RpIntelHaveWNI() RtIntelHaveWNI()
-#define RpIntelCpuType() RtIntelCpuType()
-#define RpIntelStartTiming(_data) RtIntelStartTiming(_data)
-#define RpIntelStopTiming(_data) RtIntelStopTiming(_data)
-#define RpIntelTime(_result, _func, _data) \
- RtIntelTime(_result, _func, _data)
-#define RpIntelPluginAttach() RtIntelPluginAttach()
-#define RpNodeDefinitionGetSSETransformCSL() \
- RxNodeDefinitionGetSSETransformCSL()
-
-typedef RtIntelOverload RwIntelOverload;
-typedef RtIntelOverload RpIntelOverload;
-
-#define _rwIntelOverloadGetHandle() _rtIntelOverloadGetHandle()
-#define _rpIntelOverloadGetHandle() _rtIntelOverloadGetHandle()
-#define RwIntelHaveSSE() RtIntelHaveSSE()
-#define RpIntelHaveSSE() RtIntelHaveSSE()
-
-#if (defined(RWEMULATEINTELSIMD) || !defined(__ICL))
-
-/*
- * MMX
- */
-
-/* General support intrinsics */
-#define _m_empty() Rt_m_empty()
-#define _m_from_int(i) Rt_m_from_int(i)
-#define _m_to_int(m) Rt_m_to_int(m)
-#define _m_packsswb(m1, m2) Rt_m_packsswb(m1, m2)
-#define _m_packssdw(m1, m2) Rt_m_packssdw(m1, m2)
-#define _m_packuswb(m1, m2) Rt_m_packuswb(m1, m2)
-#define _m_punpckhbw(m1, m2) Rt_m_punpckhbw(m1, m2)
-#define _m_punpckhwd(m1, m2) Rt_m_punpckhwd(m1, m2)
-#define _m_punpckhdq(m1, m2) Rt_m_punpckhdq(m1, m2)
-#define _m_punpcklbw(m1, m2) Rt_m_punpcklbw(m1, m2)
-#define _m_punpcklwd(m1, m2) Rt_m_punpcklwd(m1, m2)
-#define _m_punpckldq(m1, m2) Rt_m_punpckldq(m1, m2)
-
-/* Packed arithmetic intrinsics */
-#define _m_paddb(m1, m2) Rt_m_paddb(m1, m2)
-#define _m_paddw(m1, m2) Rt_m_paddw(m1, m2)
-#define _m_paddd(m1, m2) Rt_m_paddd(m1, m2)
-#define _m_paddsb(m1, m2) Rt_m_paddsb(m1, m2)
-#define _m_paddsw(m1, m2) Rt_m_paddsw(m1, m2)
-#define _m_paddusb(m1, m2) Rt_m_paddusb(m1, m2)
-#define _m_paddusw(m1, m2) Rt_m_paddusw(m1, m2)
-#define _m_psubb(m1, m2) Rt_m_psubb(m1, m2)
-#define _m_psubw(m1, m2) Rt_m_psubw(m1, m2)
-#define _m_psubd(m1, m2) Rt_m_psubd(m1, m2)
-#define _m_psubsb(m1, m2) Rt_m_psubsb(m1, m2)
-#define _m_psubsw(m1, m2) Rt_m_psubsw(m1, m2)
-#define _m_psubusb(m1, m2) Rt_m_psubusb(m1, m2)
-#define _m_psubusw(m1, m2) Rt_m_psubusw(m1, m2)
-#define _m_pmaddwd(m1, m2) Rt_m_pmaddwd(m1, m2)
-#define _m_pmulhw(m1, m2) Rt_m_pmulhw(m1, m2)
-#define _m_pmullw(m1, m2) Rt_m_pmullw(m1, m2)
-
-/* Shift intrinsics */
-#define _m_psllw(m, count) Rt_m_psllw(m, count)
-#define _m_psllwi(m, count) Rt_m_psllwi(m, count)
-#define _m_pslld(m, count) Rt_m_pslld(m, count)
-#define _m_pslldi(m, count) Rt_m_pslldi(m, count)
-#define _m_psllq(m, count) Rt_m_psllq(m, count)
-#define _m_psllqi(m, count) Rt_m_psllqi(m, count)
-#define _m_psraw(m, count) Rt_m_psraw(m, count)
-#define _m_psrawi(m, count) Rt_m_psrawi(m, count)
-#define _m_psrad(m, count) Rt_m_psrad(m, count)
-#define _m_psradi(m, count) Rt_m_psradi(m, count)
-#define _m_psrlw(m, count) Rt_m_psrlw(m, count)
-#define _m_psrlwi(m, count) Rt_m_psrlwi(m, count)
-#define _m_psrld(m, count) Rt_m_psrld(m, count)
-#define _m_psrldi(m, count) Rt_m_psrldi(m, count)
-#define _m_psrlq(m, count) Rt_m_psrlq(m, count)
-#define _m_psrlqi(m, count) Rt_m_psrlqi(m, count)
-
-/* Logical intrinsics */
-#define _m_pand(m1, m2) Rt_m_pand(m1, m2)
-#define _m_pandn(m1, m2) Rt_m_pandn(m1, m2)
-#define _m_por(m1, m2) Rt_m_por(m1, m2)
-#define _m_pxor(m1, m2) Rt_m_pxor(m1, m2)
-
-/* Comparison intrinsics */
-#define _m_pcmpeqb(m1, m2) Rt_m_pcmpeqb(m1, m2)
-#define _m_pcmpeqw(m1, m2) Rt_m_pcmpeqw(m1, m2)
-#define _m_pcmpeqd(m1, m2) Rt_m_pcmpeqd(m1, m2)
-#define _m_pcmpgtb(m1, m2) Rt_m_pcmpgtb(m1, m2)
-#define _m_pcmpgtw(m1, m2) Rt_m_pcmpgtw(m1, m2)
-#define _m_pcmpgtd(m1, m2) Rt_m_pcmpgtd(m1, m2)
-
-/*
- * SSE
- */
-
-/*
- * Arithmetic Operations
- */
-
-#define _mm_add_ss(a, b) Rt_mm_add_ss(a, b)
-#define _mm_add_ps(a, b) Rt_mm_add_ps(a, b)
-#define _mm_sub_ss(a, b) Rt_mm_sub_ss(a, b)
-#define _mm_sub_ps(a, b) Rt_mm_sub_ps(a, b)
-#define _mm_mul_ss(a, b) Rt_mm_mul_ss(a, b)
-#define _mm_mul_ps(a, b) Rt_mm_mul_ps(a, b)
-#define _mm_div_ss(a, b) Rt_mm_div_ss(a, b)
-#define _mm_div_ps(a, b) Rt_mm_div_ps(a, b)
-#define _mm_sqrt_ss(a) Rt_mm_sqrt_ss(a)
-#define _mm_sqrt_ps(a) Rt_mm_sqrt_ps(a)
-#define _mm_rcp_ss(a) Rt_mm_rcp_ss(a)
-#define _mm_rcp_ps(a) Rt_mm_rcp_ps(a)
-#define _mm_rsqrt_ss(a) Rt_mm_rsqrt_ss(a)
-#define _mm_rsqrt_ps(a) Rt_mm_rsqrt_ps(a)
-#define _mm_min_ss(a, b) Rt_mm_min_ss(a, b)
-#define _mm_min_ps(a, b) Rt_mm_min_ps(a, b)
-#define _mm_max_ss(a, b) Rt_mm_max_ss(a, b)
-#define _mm_max_ps(a, b) Rt_mm_max_ps(a, b)
-
-/*
- * Logical Operations
- */
-
-#define _mm_and_ps(a, b) Rt_mm_and_ps(a, b)
-#define _mm_andnot_ps(a, b) Rt_mm_andnot_ps(a, b)
-#define _mm_or_ps(a, b) Rt_mm_or_ps(a, b)
-#define _mm_xor_ps(a, b) Rt_mm_xor_ps(a, b)
-
-/*
- * Comparisons
- */
-
-#define _mm_cmpeq_ss(a, b) Rt_mm_cmpeq_ss(a, b)
-#define _mm_cmpeq_ps(a, b) Rt_mm_cmpeq_ps(a, b)
-#define _mm_cmplt_ss(a, b) Rt_mm_cmplt_ss(a, b)
-#define _mm_cmplt_ps(a, b) Rt_mm_cmplt_ps(a, b)
-#define _mm_cmple_ss(a, b) Rt_mm_cmple_ss(a, b)
-#define _mm_cmple_ps(a, b) Rt_mm_cmple_ps(a, b)
-#define _mm_cmpgt_ss(a, b) Rt_mm_cmpgt_ss(a, b)
-#define _mm_cmpgt_ps(a, b) Rt_mm_cmpgt_ps(a, b)
-#define _mm_cmpge_ss(a, b) Rt_mm_cmpge_ss(a, b)
-#define _mm_cmpge_ps(a, b) Rt_mm_cmpge_ps(a, b)
-#define _mm_cmpneq_ss(a, b) Rt_mm_cmpneq_ss(a, b)
-#define _mm_cmpneq_ps(a, b) Rt_mm_cmpneq_ps(a, b)
-#define _mm_cmpnlt_ss(a, b) Rt_mm_cmpnlt_ss(a, b)
-#define _mm_cmpnlt_ps(a, b) Rt_mm_cmpnlt_ps(a, b)
-#define _mm_cmpnle_ss(a, b) Rt_mm_cmpnle_ss(a, b)
-#define _mm_cmpnle_ps(a, b) Rt_mm_cmpnle_ps(a, b)
-#define _mm_cmpngt_ss(a, b) Rt_mm_cmpngt_ss(a, b)
-#define _mm_cmpngt_ps(a, b) Rt_mm_cmpngt_ps(a, b)
-#define _mm_cmpnge_ss(a, b) Rt_mm_cmpnge_ss(a, b)
-#define _mm_cmpnge_ps(a, b) Rt_mm_cmpnge_ps(a, b)
-#define _mm_cmpord_ss(a, b) Rt_mm_cmpord_ss(a, b)
-#define _mm_cmpord_ps(a, b) Rt_mm_cmpord_ps(a, b)
-#define _mm_cmpunord_ss(a, b) Rt_mm_cmpunord_ss(a, b)
-#define _mm_cmpunord_ps(a, b) Rt_mm_cmpunord_ps(a, b)
-#define _mm_comieq_ss(a, b) Rt_mm_comieq_ss(a, b)
-#define _mm_comilt_ss(a, b) Rt_mm_comilt_ss(a, b)
-#define _mm_comile_ss(a, b) Rt_mm_comile_ss(a, b)
-#define _mm_comigt_ss(a, b) Rt_mm_comigt_ss(a, b)
-#define _mm_comige_ss(a, b) Rt_mm_comige_ss(a, b)
-#define _mm_comineq_ss(a, b) Rt_mm_comineq_ss(a, b)
-#define _mm_ucomieq_ss(a, b) Rt_mm_ucomieq_ss(a, b)
-#define _mm_ucomilt_ss(a, b) Rt_mm_ucomilt_ss(a, b)
-#define _mm_ucomile_ss(a, b) Rt_mm_ucomile_ss(a, b)
-#define _mm_ucomigt_ss(a, b) Rt_mm_ucomigt_ss(a, b)
-#define _mm_ucomige_ss(a, b) Rt_mm_ucomige_ss(a, b)
-#define _mm_ucomineq_ss(a, b) Rt_mm_ucomineq_ss(a, b)
-
-/*
- * Conversion Operations
- */
-
-#define _mm_cvt_ss2si(a) Rt_mm_cvt_ss2si(a)
-#define _mm_cvt_ps2pi(a) Rt_mm_cvt_ps2pi(a)
-#define _mm_cvtt_ss2si(a) Rt_mm_cvtt_ss2si(a)
-#define _mm_cvtt_ps2pi(a) Rt_mm_cvtt_ps2pi(a)
-#define _mm_cvt_si2ss(a, b) Rt_mm_cvt_si2ss(a, b)
-#define _mm_cvt_pi2ps(a, b) Rt_mm_cvt_pi2ps(a, b)
-
-/*
- * Miscellaneous
- */
-
-#define _mm_shuffle_ps(a, b, i) Rt_mm_shuffle_ps(a, b, i)
-#define _mm_unpackhi_ps(a, b) Rt_mm_unpackhi_ps(a, b)
-#define _mm_unpacklo_ps(a, b) Rt_mm_unpacklo_ps(a, b)
-#define _mm_loadh_pi(a, p) Rt_mm_loadh_pi(a, p)
-#define _mm_storeh_pi(p, a) Rt_mm_storeh_pi(p, a)
-#define _mm_movehl_ps(a, b) Rt_mm_movehl_ps(a, b)
-#define _mm_movelh_ps(a, b) Rt_mm_movelh_ps(a, b)
-#define _mm_loadl_pi(a, p) Rt_mm_loadl_pi(a, p)
-#define _mm_storel_pi(p, a) Rt_mm_storel_pi(p, a)
-#define _mm_movemask_ps(a) Rt_mm_movemask_ps(a)
-#define _mm_getcsr() Rt_mm_getcsr()
-#define _mm_setcsr(i) Rt_mm_setcsr(i)
-
-/*
- *Load Operations
- */
-
-#define _mm_load_ss(p) Rt_mm_load_ss(p)
-#define _mm_load_ps1(p) Rt_mm_load_ps1(p)
-#define _mm_load_ps(p) Rt_mm_load_ps(p)
-#define _mm_loadu_ps(p) Rt_mm_loadu_ps(p)
-#define _mm_loadr_ps(p) Rt_mm_loadr_ps(p)
-
-/*
- * Set Operations
- */
-
-#define _mm_set_ss(w) Rt_mm_set_ss(w)
-#define _mm_set_ps1(w) Rt_mm_set_ps1(w)
-#define _mm_set_ps(z, y, x, w) Rt_mm_set_ps(z, y, x, w)
-#define _mm_setr_ps(z, y, x, w) Rt_mm_setr_ps(z, y, x, w)
-#define _mm_setzero_ps() Rt_mm_setzero_ps()
-
-/*
- * Store Operations
- */
-
-#define _mm_store_ss(p, a) Rt_mm_store_ss(p, a)
-#define _mm_store_ps1(p, a) Rt_mm_store_ps1(p, a)
-#define _mm_store_ps(p, a) Rt_mm_store_ps(p, a)
-#define _mm_storeu_ps(p, a) Rt_mm_storeu_ps(p, a)
-#define _mm_storer_ps(p, a) Rt_mm_storer_ps(p, a)
-#define _mm_move_ss(a, b) Rt_mm_move_ss(a, b)
-
-/*
- * Integer Intrinsics
- */
-
-#define _m_pextrw(a, n) Rt_m_pextrw(a, n)
-#define _m_pinsrw(a, d, n) Rt_m_pinsrw(a, d, n)
-#define _m_pmaxsw(a, b) Rt_m_pmaxsw(a, b)
-#define _m_pmaxub(a, b) Rt_m_pmaxub(a, b)
-#define _m_pminsw(a, b) Rt_m_pminsw(a, b)
-#define _m_pminub(a, b) Rt_m_pminub(a, b)
-#define _m_pmovmskb(a) Rt_m_pmovmskb(a)
-#define _m_pmulhuw(a, b) Rt_m_pmulhuw(a, b)
-#define _m_pshufw(a, n) Rt_m_pshufw(a, n)
-#define _m_lwmaskmovq(d, n, p) Rt_m_lwmaskmovq(d, n, p)
-
-/*
- * Cacheability Support
- */
-
-#define _mm_prefetch(p, i) Rt_mm_prefetch(p, i)
-#define _mm_stream_pi(p, a) Rt_mm_stream_pi(p, a)
-#define _mm_stream_ps(p, a) Rt_mm_stream_ps(p, a)
-#define _mm_sfence() Rt_mm_sfence()
-
-#endif /* (defined(RWEMULATEINTELSIMD) || !defined(__ICL)) */
-
-#endif /* RTINTEL_H */
diff --git a/sdk/rwsdk/include/d3d8/rtintel.rpe b/sdk/rwsdk/include/d3d8/rtintel.rpe
deleted file mode 100644
index bf297ca0..00000000
--- a/sdk/rwsdk/include/d3d8/rtintel.rpe
+++ /dev/null
@@ -1,645 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-enum e_rwdb_CriterionIntel
-{
-
-
-
- e_rwdb_CriterionIntelLAST = RWFORCEENUMSIZEINT
-};
-
-typedef enum e_rwdb_CriterionIntel e_rwdb_CriterionIntel;
-
-
diff --git a/sdk/rwsdk/include/d3d8/rtintsec.h b/sdk/rwsdk/include/d3d8/rtintsec.h
index cb482b17..a2e4c3d6 100644
--- a/sdk/rwsdk/include/d3d8/rtintsec.h
+++ b/sdk/rwsdk/include/d3d8/rtintsec.h
@@ -10,8 +10,8 @@
#define RTINTSEC_H
/**
- * \defgroup rtintersect RtIntersection
- * \ingroup rttool
+ * \defgroup rtintersection RtIntersection
+ * \ingroup mathtools
*
* Object Intersection Toolkit for RenderWare.
*/
diff --git a/sdk/rwsdk/include/d3d8/rtintsec.rpe b/sdk/rwsdk/include/d3d8/rtintsec.rpe
index 7b2ce6e1..3c7f7bf3 100644
--- a/sdk/rwsdk/include/d3d8/rtintsec.rpe
+++ b/sdk/rwsdk/include/d3d8/rtintsec.rpe
@@ -149,472 +149,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
enum e_rwdb_CriterionIntsec
{
diff --git a/sdk/rwsdk/include/d3d8/rtltmap.h b/sdk/rwsdk/include/d3d8/rtltmap.h
index 1a53b185..8ee15a43 100644
--- a/sdk/rwsdk/include/d3d8/rtltmap.h
+++ b/sdk/rwsdk/include/d3d8/rtltmap.h
@@ -1,7 +1,7 @@
/**
* \defgroup rtltmap RtLtMap
- * \ingroup rttool
+ * \ingroup lighting
*
* Lightmap Generation Toolkit for RenderWare.
*/
@@ -21,7 +21,6 @@
/**
* \ingroup rtltmap
- * \typedef RtLtMapIlluminateSampleCallBack
* \ref RtLtMapIlluminateSampleCallBack is the callback to be called, from
* within \ref RtLtMapIlluminate, for groups of samples in the objects
* currently being illuminated.
@@ -32,7 +31,7 @@
*
* This callback will receive an array of color values to fill in, each
* representing one sample in the current object - this may correspond to
- * a texel in the current object's lightmap or the prelight colour of a
+ * a texel in the current object's lightmap or the prelight color of a
* vertex, depending on whether the object is lightmapped and/or vertex-lit.
* It will receive positions (in world-space) for each sample and the normal
* vector (again, in world-space) of each sample (normals are interpolated
@@ -44,7 +43,7 @@
* The barycentric coordinates may be used, for example, to allow a callback
* to easily import existing lighting data (e.g from previously generated
* lightmaps in a different format, or from an art package with lighting
- * functionality).
+ * functionality).
*
* NOTE: The alpha channel of the RwRGBA results array must NOT be modified.
* These values are used internally and their modification may result in
@@ -82,7 +81,6 @@ typedef RwRGBA *(*RtLtMapIlluminateSampleCallBack)(RwRGBA *results,
/**
* \ingroup rtltmap
- * \typedef RtLtMapIlluminateVisCallBack
* \ref RtLtMapIlluminateVisCallBack is the callback to be called, from
* within \ref RtLtMapIlluminate, to determine the visibility between a
* sample and a light.
@@ -94,7 +92,7 @@ typedef RwRGBA *(*RtLtMapIlluminateSampleCallBack)(RwRGBA *results,
* Each sample may represent a texel in the current object's lightmap
* or the prelight color of a vertex, depending on whether the object
* is lightmapped and/or vertex-lit (see \ref RtLtMapObjectFlags).
- *
+ *
* The callback will receive a pointer to the world of the current
* \ref RtLtMapLightingSession (this may be used to perform intersection
* tests), the world-space position of the sample, the world-space
@@ -111,15 +109,15 @@ typedef RwRGBA *(*RtLtMapIlluminateSampleCallBack)(RwRGBA *results,
* expressed by modifying the RwRGBAReal value. This defaults to bright
* white but may be reduced to signify that the light from the light
* source should be attenuated. This could be used to take into account
- * light-filtering objects in the scene (such as coloured glass or fog).
+ * light-filtering objects in the scene (such as colored glass or fog).
*
* The default RtLtMapIlluminateVisCallBack supplied with RtLtMap is
* \ref RtLtMapDefaultVisCallBack. This callback performs visibility
- * tests using the line-intersection tests from \ref rtintersect. It tests
+ * tests using the line-intersection tests from \ref rtintersection. It tests
* for occlusion by RpWorldSectors and RpAtomics and it respects the
* relevant \ref RtLtMapObjectFlags and \ref RtLtMapMaterialFlags but it
* does not filter light; visibility is determined to be either one or zero.
- *
+ *
* \param world The world of the current RtLtMapLightingSession
* \param result An RwRGBAReal value to attentuate this light's
* contribution to the current sample
@@ -141,7 +139,6 @@ typedef RwBool (*RtLtMapIlluminateVisCallBack)(RpWorld *world,
/**
* \ingroup rtltmap
- * \typedef RtLtMapIlluminateProgressCallBack
* \ref RtLtMapIlluminateProgressCallBack is the callback to be called, from
* within \ref RtLtMapIlluminate, to allow a user to track lighting progress.
*
@@ -214,17 +211,17 @@ typedef enum RtLtMapProgressMessage RtLtMapProgressMessage;
typedef struct RtLtMapLightingSession RtLtMapLightingSession;
/**
* \ingroup rtltmap
- * \typedef RtLtMapLightingSession
- * The \ref RtLtMapLightingSession structure holds information to be passed to
+ * \struct RtLtMapLightingSession
+ * The RtLtMapLightingSession structure holds information to be passed to
* \ref RtLtMapIlluminate. It is used to parameterize the lighting process.
*
- * The \ref RtLtMapLightingSession structure encapsulates a set of objects and
+ * The RtLtMapLightingSession structure encapsulates a set of objects and
* keeps track of the proportion of samples, within that set, that have already
* been lit by calls to \ref RtLtMapIlluminate. Each call performs lighting for
* one 'slice' of the whole 'session'. If the camera member is non-NULL, it is
* important that the camera is not moved between lighting slices.
*
- * The \ref RtLtMapLightingSession is also passed to
+ * The RtLtMapLightingSession is also passed to
* \ref RtLtMapLightMapsCreate, \ref RtLtMapLightMapsClear,
* \ref RtLtMapLightMapsDestroy and \ref RtLtMapAreaLightGroupCreate,
* though not all of the session structure's member will be used in
@@ -327,7 +324,7 @@ typedef enum RtLtMapMaterialFlags RtLtMapMaterialFlags;
/**
* \ingroup rtltmap
- * \ref RtLtMapObjectFlags is an enumerated type specifying the different
+ * RtLtMapObjectFlags is an enumerated type specifying the different
* lightmap-related flags which may be applied to world sectors and
* atomics. These values will be taken into consideration within
* \ref RtLtMapLightMapsCreate and \ref RtLtMapIlluminate.
@@ -345,11 +342,11 @@ enum RtLtMapObjectFlags
rtLTMAPOBJECTNAFLAG = 0,
rtLTMAPOBJECTLIGHTMAP = 1, /**< This object is to be lightmapped */
- rtLTMAPOBJECTVERTEXLIGHT = 2, /**< This object's vertex prelight colours should
- * be lit within \ref RtLtMapIlluminate. */
+ rtLTMAPOBJECTVERTEXLIGHT = 2, /**< This object's vertex prelight colors should
+ be lit within \ref RtLtMapIlluminate. */
rtLTMAPOBJECTNOSHADOW = 4, /**< This object does not cast shadows (useful, for
- * example, for moving objects for which dynamic
- * shadows are to be rendered - such as doors) */
+ example, for moving objects for which dynamic
+ shadows are to be rendered - such as doors) */
rtLTMAPOBJECTFLAGFORCEENUMSIZEINT = 0x7FFFFFFF
};
@@ -358,10 +355,13 @@ typedef enum RtLtMapObjectFlags RtLtMapObjectFlags;
/* Area-lighting stuff:*
***********************/
+
+typedef struct RtLtMapAreaLightGroup RtLtMapAreaLightGroup;
+
/**
* \ingroup rtltmap
- * \typedef RtLtMapAreaLightGroup
- * \ref RtLtMapAreaLightGroup is a structure which acts as a container
+ * \struct RtLtMapAreaLightGroup
+ * RtLtMapAreaLightGroup is a structure which acts as a container
* for area lights created by a call to \ref RtLtMapAreaLightGroupCreate.
* The containers may be chained and passed to \ref RtLtMapIlluminate.
* Each container has an optional pointer to a RwFrame which is used to
@@ -376,7 +376,6 @@ typedef enum RtLtMapObjectFlags RtLtMapObjectFlags;
* \see RtLtMapIlluminate
* \see RtLtMapIlluminateVisCallBack
*/
-typedef struct RtLtMapAreaLightGroup RtLtMapAreaLightGroup;
struct RtLtMapAreaLightGroup
{
RwSList *meshes; /**< A list of hierarchically-grouped area lights */
@@ -388,13 +387,15 @@ struct RtLtMapAreaLightGroup
/* Area light triangles are grouped by source mesh (this may change) */
typedef struct LtMapAreaLightMesh LtMapAreaLightMesh;
+
+#if (!defined(DOXYGEN))
struct LtMapAreaLightMesh
{
RwUInt32 flags; /* To hold hierarchical visibility culling flags,
* relevant to the object/triangle *currently* being lit. */
- RpMaterial *material; /* The emitter material, containing colour, etc */
+ RpMaterial *material; /* The emitter material, containing color, etc */
RwSphere sphere; /* Each mesh has an associated center and radius */
- RwReal ROI; /* Centred on the above sphere, the R.O.I. of the
+ RwReal ROI; /* Centered on the above sphere, the R.O.I. of the
* samples in this mesh (a conservative estimate) */
RwSList *triangles; /* A list of the area light triangles in this mesh */
};
@@ -412,6 +413,37 @@ struct LtMapAreaLight
* not worth storing 3 points, coarse culling is fine) */
RwV3d *lights; /* Array of area light sample positions (in world-space) */
};
+#endif /* (!defined(DOXYGEN)) */
+
+#if (defined(SKY2_DRVMODEL_H) || defined(NULLSKY_DRVMODEL_H))
+
+/**
+ * \ingroup rtltmapps2
+ * \ref RtLtMapSkyLumCalcCallBack is the callback to be called, from
+ * within \ref RtLtMapSkyBaseTextureProcess, to allow a user to select the
+ * function to process the textures for rendering on the PlayStation 2.
+ *
+ * The function is called for each span of a full color image, or for the
+ * CLUT in a palettised image, to compute the luminance and stores it in
+ * the alpha component of the texel.
+ *
+ * \param scanline A pointer to a scanline of \ref RwRGBA data.
+ * \param width Width of the scanline, in pixels.
+ *
+ * \return A pointer to the scanline on success, NULL otherwise.
+ *
+ * \see RtLtMapSkyBaseTextureProcess
+ * \see RtLtMapSkyLightingSessionBaseTexturesProcess
+ * \see RtLtMapSkyLightMapMakeDarkMap
+ * \see RtLtMapSkyLumCalcMaxCallBack
+ * \see RtLtMapSkyLumCalcSigmaCallBack
+ * \see RtLtMapSkySetLumCalcCallBack
+ * \see RtLtMapSkyGetLumCalcCallBack
+ */
+typedef RwRGBA *(*RtLtMapSkyLumCalcCallBack)(RwRGBA *scanline,
+ RwUInt32 width );
+
+#endif /* (defined(SKY2_DRVMODEL_H) || defined(NULLSKY_DRVMODEL_H)) */
#ifdef __cplusplus
@@ -487,6 +519,12 @@ RtLtMapDefaultVisCallBack(RpWorld *world,
RwV3d *lightPos,
RpLight __RWUNUSED__ *light);
+extern void
+RtLtMapSetVisCallBackCollisionScalar(RwReal scalar);
+
+extern RwReal
+RtLtMapGetVisCallBackCollisionScalar(void);
+
extern RtLtMapLightingSession *
RtLtMapLightingSessionInitialize(RtLtMapLightingSession *session,
RpWorld *world);
@@ -562,7 +600,6 @@ extern RwBool
RtLtMapSetAreaLightErrorCutoff(RwReal tolerance);
-
/* Texture-saving functionality: */
extern RwTexDictionary *
RtLtMapTexDictionaryCreate(RtLtMapLightingSession *session);
@@ -588,7 +625,13 @@ extern RpAtomic *RtLtMapSkyAtomicBaseTexturesProcess(RpAtomic *atomic);
extern RpWorldSector *
RtLtMapSkyWorldSectorBaseTexturesProcess(RpWorldSector *sector);
extern RtLtMapLightingSession *
-RtLtMapSkyBaseTexturesProcess(RtLtMapLightingSession *session);
+RtLtMapSkyLightingSessionBaseTexturesProcess(RtLtMapLightingSession *session);
+
+extern RwRGBA *RtLtMapSkyLumCalcMaxCallBack( RwRGBA *scanline, RwUInt32 width );
+extern RwRGBA *RtLtMapSkyLumCalcSigmaCallBack( RwRGBA *scanline, RwUInt32 width );
+
+extern RwBool RtLtMapSkySetLumCalcCallBack(RtLtMapSkyLumCalcCallBack cback);
+extern RtLtMapSkyLumCalcCallBack RtLtMapSkyGetLumCalcCallBack( void );
#endif /* (defined(SKY2_DRVMODEL_H) || defined(NULLSKY_DRVMODEL_H)) */
diff --git a/sdk/rwsdk/include/d3d8/rtltmap.rpe b/sdk/rwsdk/include/d3d8/rtltmap.rpe
index e510d78b..fb171c51 100644
--- a/sdk/rwsdk/include/d3d8/rtltmap.rpe
+++ b/sdk/rwsdk/include/d3d8/rtltmap.rpe
@@ -159,472 +159,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
enum e_rwdb_CriterionLTMAPTOOL
{
diff --git a/sdk/rwsdk/include/d3d8/rtmipk.h b/sdk/rwsdk/include/d3d8/rtmipk.h
index c06a3879..6c777b41 100644
--- a/sdk/rwsdk/include/d3d8/rtmipk.h
+++ b/sdk/rwsdk/include/d3d8/rtmipk.h
@@ -15,9 +15,9 @@
/**
* \defgroup rtmipk RtMipmapK
- * \ingroup rttool
+ * \ingroup mipmapping
*
- * Ps2/Mipmap K Value Toolkit for RenderWare.
+ * PlayStation 2 / Mipmap K Value Toolkit for RenderWare.
*/
/****************************************************************************
diff --git a/sdk/rwsdk/include/d3d8/rtmipk.rpe b/sdk/rwsdk/include/d3d8/rtmipk.rpe
index 24e1fd33..04500e1d 100644
--- a/sdk/rwsdk/include/d3d8/rtmipk.rpe
+++ b/sdk/rwsdk/include/d3d8/rtmipk.rpe
@@ -149,472 +149,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
enum e_rwdb_CriterionMipmapK
{
diff --git a/sdk/rwsdk/include/d3d8/rtpick.h b/sdk/rwsdk/include/d3d8/rtpick.h
index 5ea78058..62f564a3 100644
--- a/sdk/rwsdk/include/d3d8/rtpick.h
+++ b/sdk/rwsdk/include/d3d8/rtpick.h
@@ -11,7 +11,7 @@
/**
* \defgroup rtpick RtPick
- * \ingroup rttool
+ * \ingroup collisiondetection
*
* Picking Toolkit for RenderWare.
*/
diff --git a/sdk/rwsdk/include/d3d8/rtpick.rpe b/sdk/rwsdk/include/d3d8/rtpick.rpe
index 055ea9ff..779e2f9a 100644
--- a/sdk/rwsdk/include/d3d8/rtpick.rpe
+++ b/sdk/rwsdk/include/d3d8/rtpick.rpe
@@ -149,472 +149,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
enum e_rwdb_CriterionPick
{
diff --git a/sdk/rwsdk/include/d3d8/rtpitexd.h b/sdk/rwsdk/include/d3d8/rtpitexd.h
index 39287bcd..602c608a 100644
--- a/sdk/rwsdk/include/d3d8/rtpitexd.h
+++ b/sdk/rwsdk/include/d3d8/rtpitexd.h
@@ -11,7 +11,7 @@
/**
* \defgroup rtpitexd RtPITexD
- * \ingroup rttool
+ * \ingroup texturedictionaries
*
* Platform Independent Texture Dictionaries
*
diff --git a/sdk/rwsdk/include/d3d8/rtpitexd.rpe b/sdk/rwsdk/include/d3d8/rtpitexd.rpe
index 0650ea5c..290ac864 100644
--- a/sdk/rwsdk/include/d3d8/rtpitexd.rpe
+++ b/sdk/rwsdk/include/d3d8/rtpitexd.rpe
@@ -203,472 +203,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
enum e_rwdb_CriterionPITexDict
{
diff --git a/sdk/rwsdk/include/d3d8/rtpng.h b/sdk/rwsdk/include/d3d8/rtpng.h
index 694c8400..4ba8cf0f 100644
--- a/sdk/rwsdk/include/d3d8/rtpng.h
+++ b/sdk/rwsdk/include/d3d8/rtpng.h
@@ -12,7 +12,7 @@
/**
* \defgroup rtpng RtPNG
- * \ingroup rttool
+ * \ingroup imageconversiontools
*
* PNG/Portable Network Graphics Image Format Toolkit for RenderWare.
*
diff --git a/sdk/rwsdk/include/d3d8/rtpng.rpe b/sdk/rwsdk/include/d3d8/rtpng.rpe
index 7a6b6cc2..e3f6f0d7 100644
--- a/sdk/rwsdk/include/d3d8/rtpng.rpe
+++ b/sdk/rwsdk/include/d3d8/rtpng.rpe
@@ -150,472 +150,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
enum e_rwdb_CriterionPNG
{
diff --git a/sdk/rwsdk/include/d3d8/rtquat.h b/sdk/rwsdk/include/d3d8/rtquat.h
index 05e971d0..a0a6e89d 100644
--- a/sdk/rwsdk/include/d3d8/rtquat.h
+++ b/sdk/rwsdk/include/d3d8/rtquat.h
@@ -10,7 +10,7 @@
/**
* \defgroup rtquat RtQuat
- * \ingroup rttool
+ * \ingroup mathtools
*
* Quaternion Toolkit for RenderWare.
*
@@ -392,7 +392,7 @@ MACRO_START \
\
/* Matrix is orthogonal */ \
rwMatrixSetFlags((mpMatrix), \
- (rwMATRIXTYPEORTHOGANAL & \
+ (rwMATRIXTYPEORTHOGONAL & \
~rwMATRIXINTERNALIDENTITY) ); \
\
} \
diff --git a/sdk/rwsdk/include/d3d8/rtquat.rpe b/sdk/rwsdk/include/d3d8/rtquat.rpe
index e43bb50c..b239aba0 100644
--- a/sdk/rwsdk/include/d3d8/rtquat.rpe
+++ b/sdk/rwsdk/include/d3d8/rtquat.rpe
@@ -166,472 +166,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
enum e_rwdb_CriterionQuat
{
diff --git a/sdk/rwsdk/include/d3d8/rtras.h b/sdk/rwsdk/include/d3d8/rtras.h
index 0a9064a8..957e21e6 100644
--- a/sdk/rwsdk/include/d3d8/rtras.h
+++ b/sdk/rwsdk/include/d3d8/rtras.h
@@ -11,7 +11,7 @@
/**
* \defgroup rtras RtRAS
- * \ingroup rttool
+ * \ingroup imageconversiontools
*
* RAS/Sun Raster Fule Format Image Format Toolkit for RenderWare.
*
diff --git a/sdk/rwsdk/include/d3d8/rtras.rpe b/sdk/rwsdk/include/d3d8/rtras.rpe
index 3398c3cc..a242ef49 100644
--- a/sdk/rwsdk/include/d3d8/rtras.rpe
+++ b/sdk/rwsdk/include/d3d8/rtras.rpe
@@ -150,472 +150,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
enum e_rwdb_CriterionRAS
{
diff --git a/sdk/rwsdk/include/d3d8/rtray.h b/sdk/rwsdk/include/d3d8/rtray.h
index 4bf0a343..b2f3d4bc 100644
--- a/sdk/rwsdk/include/d3d8/rtray.h
+++ b/sdk/rwsdk/include/d3d8/rtray.h
@@ -11,7 +11,7 @@
/**
* \defgroup rtray RtRay
- * \ingroup rttool
+ * \ingroup mathtools
*
* Line Toolkit for RenderWare.
*/
@@ -46,7 +46,9 @@ extern "C"
/* Line intersections */
extern RwReal RtLineTriangleIntersectionTest(RwLine *line, RwV3d *normal,
RwV3d *v0, RwV3d *v1, RwV3d *v2);
-extern RwReal RtLineSphereIntersectionTest(RwLine *line, RwSphere *sphere);
+extern RwBool RtLineSphereIntersectionTest(RwLine *line,
+ RwSphere *sphere,
+ RwReal *centerDist);
/* Line clipping */
extern RwLine *RtLineClipPlane(RwLine *line, RwPlane *plane);
diff --git a/sdk/rwsdk/include/d3d8/rtray.rpe b/sdk/rwsdk/include/d3d8/rtray.rpe
index 27788d94..c1ff4458 100644
--- a/sdk/rwsdk/include/d3d8/rtray.rpe
+++ b/sdk/rwsdk/include/d3d8/rtray.rpe
@@ -149,472 +149,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
enum e_rwdb_CriterionRay
{
diff --git a/sdk/rwsdk/include/d3d8/rtskinsp.h b/sdk/rwsdk/include/d3d8/rtskinsp.h
new file mode 100644
index 00000000..7e40c13f
--- /dev/null
+++ b/sdk/rwsdk/include/d3d8/rtskinsp.h
@@ -0,0 +1,57 @@
+/***************************************************************************
+ * *
+ * Module : *
+ * *
+ * Purpose : *
+ * *
+ **************************************************************************/
+
+/* RWPUBLIC */
+
+#ifndef RTSKINSP_H
+#define RTSKINSP_H
+
+/**
+ * \defgroup rtskinsplit RtSkinSplit
+ * \ingroup skinning
+ *
+ * Skin Splitting Toolkit for RenderWare Graphics.
+ */
+
+/****************************************************************************
+ Includes
+ */
+#include <rwcore.h>
+#include <rpworld.h>
+
+/****************************************************************************
+ Defines
+ */
+
+/****************************************************************************
+ Global Types
+ */
+
+/****************************************************************************
+ Global variables (across program)
+ */
+
+/****************************************************************************
+ Function prototypes
+ */
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cpluscplus */
+
+extern RpAtomic *
+RtSkinSplitAtomicSplitGeometry( RpAtomic *atomic, RwUInt32 boneLimit );
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* RTSKINSP_H */
+
+/* RWPUBLICEND */
diff --git a/sdk/rwsdk/include/d3d8/rtskinsp.rpe b/sdk/rwsdk/include/d3d8/rtskinsp.rpe
new file mode 100644
index 00000000..f86623b4
--- /dev/null
+++ b/sdk/rwsdk/include/d3d8/rtskinsp.rpe
@@ -0,0 +1,163 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+enum e_rwdb_CriterionSkinSplit
+{
+
+
+
+ e_rwdb_CriterionSkinSplitLAST = RWFORCEENUMSIZEINT
+};
+
+typedef enum e_rwdb_CriterionSkinSplit e_rwdb_CriterionSkinSplit;
+
+
diff --git a/sdk/rwsdk/include/d3d8/rtslerp.h b/sdk/rwsdk/include/d3d8/rtslerp.h
index ec41752c..4262b894 100644
--- a/sdk/rwsdk/include/d3d8/rtslerp.h
+++ b/sdk/rwsdk/include/d3d8/rtslerp.h
@@ -18,7 +18,7 @@
/**
* \defgroup rtslerp RtSlerp
- * \ingroup rttool
+ * \ingroup mathtools
*
* Slerp/Spherical Linear Interpolations Toolkit for RenderWare.
*
diff --git a/sdk/rwsdk/include/d3d8/rtslerp.rpe b/sdk/rwsdk/include/d3d8/rtslerp.rpe
index 847ccb00..64bd7571 100644
--- a/sdk/rwsdk/include/d3d8/rtslerp.rpe
+++ b/sdk/rwsdk/include/d3d8/rtslerp.rpe
@@ -167,472 +167,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
enum e_rwdb_CriterionSlerp
{
diff --git a/sdk/rwsdk/include/d3d8/rtsplpvs.h b/sdk/rwsdk/include/d3d8/rtsplpvs.h
index 38ae118f..419717a1 100644
--- a/sdk/rwsdk/include/d3d8/rtsplpvs.h
+++ b/sdk/rwsdk/include/d3d8/rtsplpvs.h
@@ -12,7 +12,7 @@
/**
* \defgroup rtsplinepvs RtSplinePVS
- * \ingroup rttool
+ * \ingroup pvs
*
* Spline PVS Toolkit for RenderWare.
*/
diff --git a/sdk/rwsdk/include/d3d8/rtsplpvs.rpe b/sdk/rwsdk/include/d3d8/rtsplpvs.rpe
index d436b610..9736cbbc 100644
--- a/sdk/rwsdk/include/d3d8/rtsplpvs.rpe
+++ b/sdk/rwsdk/include/d3d8/rtsplpvs.rpe
@@ -149,472 +149,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
enum e_rwdb_CriterionSplinePVS
{
diff --git a/sdk/rwsdk/include/d3d8/rttiff.h b/sdk/rwsdk/include/d3d8/rttiff.h
index 9dbf22c8..b5d0ec00 100644
--- a/sdk/rwsdk/include/d3d8/rttiff.h
+++ b/sdk/rwsdk/include/d3d8/rttiff.h
@@ -11,7 +11,7 @@
/**
* \defgroup rttiff RtTIFF
- * \ingroup rttool
+ * \ingroup imageconversiontools
*
* TIFF/Tag Image File Format Image Format Toolkit for RenderWare.
*
diff --git a/sdk/rwsdk/include/d3d8/rttiff.rpe b/sdk/rwsdk/include/d3d8/rttiff.rpe
index f82c7d82..260b2329 100644
--- a/sdk/rwsdk/include/d3d8/rttiff.rpe
+++ b/sdk/rwsdk/include/d3d8/rttiff.rpe
@@ -150,472 +150,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
enum e_rwdb_CriterionTIFF
{
diff --git a/sdk/rwsdk/include/d3d8/rttilerd.h b/sdk/rwsdk/include/d3d8/rttilerd.h
index f11b703b..7cb8f887 100644
--- a/sdk/rwsdk/include/d3d8/rttilerd.h
+++ b/sdk/rwsdk/include/d3d8/rttilerd.h
@@ -11,7 +11,7 @@
/**
* \defgroup rttilerender RtTileRender
- * \ingroup rttool
+ * \ingroup cameras
*
* Tile renderer - e.g. grabbing screen shots - Toolkit for RenderWare.
*/
diff --git a/sdk/rwsdk/include/d3d8/rttilerd.rpe b/sdk/rwsdk/include/d3d8/rttilerd.rpe
index 78222d06..15c929f9 100644
--- a/sdk/rwsdk/include/d3d8/rttilerd.rpe
+++ b/sdk/rwsdk/include/d3d8/rttilerd.rpe
@@ -150,472 +150,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
enum e_rwdb_CriterionTileRend
{
diff --git a/sdk/rwsdk/include/d3d8/rttoc.h b/sdk/rwsdk/include/d3d8/rttoc.h
index 02893aa8..88926062 100644
--- a/sdk/rwsdk/include/d3d8/rttoc.h
+++ b/sdk/rwsdk/include/d3d8/rttoc.h
@@ -1,37 +1,38 @@
-/***************************************************************************
- * *
- * Module : rttoc.h *
- * *
- * Purpose : Table Of Contents (TOC) *
- * *
- **************************************************************************/
+/******************************************************************************
+ * *
+ * Module : rttoc.h *
+ * *
+ * Purpose : Table Of Contents (TOC) *
+ * *
+ ******************************************************************************/
#ifndef RTTOC_H
#define RTTOC_H
/**
* \defgroup rttoc RtTOC
- * \ingroup rttool
+ * \ingroup streaming
*
- * Table Of Contents (TOC) - e.g. creating a TOC for a RwStream.
+ * Table Of Contents (TOC) - creating a TOC for a stream.
*/
-/****************************************************************************
+/******************************************************************************
Includes
*/
#include "rwcore.h"
#include "rpcriter.h"
-/****************************************************************************
+/******************************************************************************
Defines
*/
-/****************************************************************************
+/******************************************************************************
Global Types
*/
typedef struct _rtTOCGUID _rtTOCGUID;
+#if (!defined(DOXYGEN))
struct _rtTOCGUID
{
RwUInt32 data1;
@@ -39,20 +40,22 @@ struct _rtTOCGUID
RwUInt16 data3;
RwUInt8 data4[8];
};
+#endif /* (!defined(DOXYGEN)) */
typedef struct RtTOCEntry RtTOCEntry;
/**
* \ingroup rttoc
* \struct RtTOCEntry
*
- * BLAH
+ * A Table Of Contents (TOC) entry structure.
*/
struct RtTOCEntry
{
- RwCorePluginID id; /**< Chunk ID */
- RwUInt32 offset;/**< Offset of chunk from the start of the file
- * including TOC */
- _rtTOCGUID guid; /**< GUID */
+ RwCorePluginID id; /**< Chunk ID */
+ RwUInt32 gid; /**< Game ID */
+ RwUInt32 offset; /**< Offset of chunk from the start of the file
+ including TOC */
+ _rtTOCGUID guid; /**< GUID */
};
typedef struct RtTOC RtTOC;
@@ -60,16 +63,16 @@ typedef struct RtTOC RtTOC;
/**
* \ingroup rttoc
* \struct RtTOC
- *
- * BLAH
+ *
+ * Table Of Contents (TOC) structure.
*/
struct RtTOC
{
- RwInt32 numEntries; /**< Number of entries*/
- RtTOCEntry entry[1]; /**< Entry*/
+ RwInt32 numEntries; /**< Number of entries */
+ RtTOCEntry entry[1]; /**< Entry */
};
-/****************************************************************************
+/******************************************************************************
Function prototypes
*/
diff --git a/sdk/rwsdk/include/d3d8/rttoc.rpe b/sdk/rwsdk/include/d3d8/rttoc.rpe
index 796f8de5..706372f2 100644
--- a/sdk/rwsdk/include/d3d8/rttoc.rpe
+++ b/sdk/rwsdk/include/d3d8/rttoc.rpe
@@ -150,472 +150,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
enum e_rwdb_CriterionTOC
{
diff --git a/sdk/rwsdk/include/d3d8/rtvcat.rpe b/sdk/rwsdk/include/d3d8/rtvcat.rpe
index 464ca886..ef5e286e 100644
--- a/sdk/rwsdk/include/d3d8/rtvcat.rpe
+++ b/sdk/rwsdk/include/d3d8/rtvcat.rpe
@@ -150,472 +150,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
enum e_rwdb_CriterionVextexCacheStrip
{
diff --git a/sdk/rwsdk/include/d3d8/rtworld.h b/sdk/rwsdk/include/d3d8/rtworld.h
index fef3e17c..727d8122 100644
--- a/sdk/rwsdk/include/d3d8/rtworld.h
+++ b/sdk/rwsdk/include/d3d8/rtworld.h
@@ -14,7 +14,7 @@
/**
* \defgroup rtworld RtWorld
- * \ingroup rttool
+ * \ingroup basicgeometry
*
* World Import Toolkit for RenderWare.
*/
diff --git a/sdk/rwsdk/include/d3d8/rtworld.rpe b/sdk/rwsdk/include/d3d8/rtworld.rpe
index bc20947e..83449720 100644
--- a/sdk/rwsdk/include/d3d8/rtworld.rpe
+++ b/sdk/rwsdk/include/d3d8/rtworld.rpe
@@ -149,472 +149,6 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
enum e_rwdb_CriterionTlWorld
{
diff --git a/sdk/rwsdk/include/d3d8/rwcore.h b/sdk/rwsdk/include/d3d8/rwcore.h
index b9214c63..583de35f 100644
--- a/sdk/rwsdk/include/d3d8/rwcore.h
+++ b/sdk/rwsdk/include/d3d8/rwcore.h
@@ -22,7 +22,7 @@
/*************************************************************************
*
* Filename: <C:/daily/rwsdk/include/d3d8/rwcore.h>
- * Automatically Generated on: Wed Jul 10 10:45:00 2002
+ * Automatically Generated on: Thu Jan 23 11:06:24 2003
*
************************************************************************/
@@ -94,6 +94,7 @@ typedef struct rxHeapSuperBlockDescriptor rxHeapSuperBlockDescriptor;
typedef struct RxHeap RxHeap;
typedef struct rxHeapBlockHeader rxHeapBlockHeader;
+#if (!defined(DOXYGEN))
struct rxHeapFreeBlock
{
RwUInt32 size;
@@ -106,6 +107,7 @@ struct rxHeapSuperBlockDescriptor
RwUInt32 size;
rxHeapSuperBlockDescriptor *next;
};
+#endif /* (!defined(DOXYGEN)) */
/**
* \ingroup rwcoregeneric
@@ -124,6 +126,7 @@ struct RxHeap
* the heap needs resetting or not. */
};
+#if (!defined(DOXYGEN))
struct rxHeapBlockHeader
{
/* present in all blocks (used & unused) */
@@ -132,6 +135,7 @@ struct rxHeapBlockHeader
rxHeapFreeBlock *freeEntry; /* (or null) */
RwUInt32 pad[4]; /* alignment padding to 32 bytes */
};
+#endif /* (!defined(DOXYGEN)) */
/* This wrapper cheaply early-outs when a heap doesn't *need* resetting */
#define RxHeapReset(heap) \
@@ -356,8 +360,7 @@ struct RxIoSpec
/**
* \ingroup rwcoregeneric
- * \typedef RxNodeBodyFn
- * is the callback to be
+ * \ref RxNodeBodyFn is the callback to be
* called during pipeline execution -- and, typically, process
* \ref RxPacket's -- for the owning pipeline node.
*
@@ -373,7 +376,7 @@ typedef RwBool (*RxNodeBodyFn) (RxPipelineNode * self,
/**
* \ingroup rwcoregeneric
- * \typedef RxNodeInitFn
+ * \ref RxNodeInitFn
* is the callback to be called,
* for the owning node definition, the first time an \ref RxPipeline
* referencing that node definition is unlocked.
@@ -388,7 +391,7 @@ typedef RwBool (*RxNodeInitFn) (RxNodeDefinition * self);
/**
* \ingroup rwcoregeneric
- * \typedef RxNodeTermFn
+ * \ref RxNodeTermFn
* is the callback to be called,
* for the owning node definition, the last time an \ref RxPipeline
* referencing that node definition is destroyed or locked.
@@ -403,7 +406,7 @@ typedef void (*RxNodeTermFn) (RxNodeDefinition * self);
/**
* \ingroup rwcoregeneric
- * \typedef RxPipelineNodeInitFn
+ * \ref RxPipelineNodeInitFn
* is the callback to be called, for the owning pipeline node, whenever a
* \ref RxPipeline containing that that pipeline node is unlocked.
*
@@ -417,7 +420,7 @@ typedef RwBool (*RxPipelineNodeInitFn) (RxPipelineNode * self);
/**
* \ingroup rwcoregeneric
- * \typedef RxPipelineNodeTermFn
+ * \ref RxPipelineNodeTermFn
* is the callback to be called, for the owning pipeline node, whenever a
* \ref RxPipeline containing that that pipeline node is locked or
* destroyed.
@@ -432,14 +435,14 @@ typedef void (*RxPipelineNodeTermFn) (RxPipelineNode * self);
/**
* \ingroup rwcoregeneric
- * \typedef RxPipelineNodeConfigFn
+ * \ref RxPipelineNodeConfigFn
* is the callback to be called, for the owning pipeline node, whenever a
* \ref RxPipeline containing that that pipeline node is unlocked,
* *after* all \ref RxPipelineNodeInitFn's have been called for the
* pipeline in question. This func is to be used as described in
* RxPipelineNodeSendConfigMsg.
*
- * \param self A pointer to the pipeline node
+ * \param self A pointer to the pipeline node
* \param pipeline A pointer to the containing pipeline
*
* \return TRUE on success, FALSE otherwise.
@@ -449,21 +452,22 @@ typedef void (*RxPipelineNodeTermFn) (RxPipelineNode * self);
typedef RwBool (*RxPipelineNodeConfigFn) (RxPipelineNode * self,
RxPipeline * pipeline);
-/* - removed from the API Reference January 2002 -
- typedef RxConfigMsgHandlerFn
- is the callback to be called, for the owning pipeline node, whenever
- a message is sent to it by the ref RxPipelineNodeConfigFn of another
- pipeline node in the same pipeline. See ref RxPipelineNodeSendConfigMsg.
-
- param self A pointer to the pipeline node
- param msg Message ID
- param intparam Meaning is message-specific
- param ptrparam Meaning is message-specific
-
- return A RwInt32 value, 0: unserviced; -ve: error; +ve: informative success
-
- see RxNodeMethods
- */
+/**
+ * \ingroup rwcoregeneric
+ * \ref RxConfigMsgHandlerFn
+ * is the callback to be called, for the owning pipeline node, whenever
+ * a message is sent to it by the \ref RxPipelineNodeConfigFn of another
+ * pipeline node in the same pipeline. See \ref RxPipelineNodeSendConfigMsg.
+ *
+ * \param self A pointer to the pipeline node
+ * \param msg Message ID
+ * \param intparam Meaning is message-specific
+ * \param ptrparam Meaning is message-specific
+ *
+ * \return A RwInt32 value, 0: unserviced; -ve: error; +ve: informative success
+ *
+ * \see RxNodeMethods
+ */
typedef RwUInt32 (*RxConfigMsgHandlerFn) (RxPipelineNode * self,
RwUInt32 msg,
RwUInt32 intparam,
@@ -706,7 +710,7 @@ struct RxPipeline
/**
* \ingroup rwcoregeneric
- * \typedef RxPipelineNodeOutputCallBack
+ * \ref RxPipelineNodeOutputCallBack
* is the callback function supplied
* to \ref RxPipelineNodeForAllConnectedOutputs.
*
@@ -716,11 +720,11 @@ struct RxPipeline
* data structure (callbackdata). If no such structure was specified, this
* will be NULL.
*
- * \param node A pointer to the pipeline node whose outputs
- * are being traversed
+ * \param node A pointer to the pipeline node whose outputs
+ * are being traversed
* \param outputnode A pointer to the current output
- * pipeline node
- * \param callbackdata A pointer to optional user-supplied data
+ * pipeline node
+ * \param callbackdata A pointer to optional user-supplied data
*
* \return Returns a pointer to the \ref RxPipelineNode whose outputs are being
* traversed, or NULL to terminate traversal
@@ -744,6 +748,9 @@ extern "C"
{
#endif /* __cplusplus */
+extern void
+RxPipelineSetFreeListCreateParams( RwInt32 blockSize, RwInt32 numBlocksToPrealloc );
+
extern RwBool
_rxPipelineOpen(void);
@@ -988,19 +995,19 @@ MACRO_STOP
/**
* \ingroup rwcoregeneric
- * \typedef RxNodeOutput
+ * \ref RxNodeOutput
* typedef for a reference to an output of a pipeline node */
typedef RwUInt32 *RxNodeOutput;
/**
* \ingroup rwcoregeneric
- * \typedef RxNodeInput
+ * \ref RxNodeInput
* typedef for a reference to the input of a pipeline node */
typedef RxPipelineNode *RxNodeInput;
/**
* \ingroup rwcoregeneric
- * \typedef RxLockedPipe
+ * \ref RxLockedPipe
* typedef for a reference to a locked pipeline
*/
typedef RxPipeline RxLockedPipe;
@@ -1119,275 +1126,6 @@ RxPipelineInsertDebugNode(RxPipeline *pipeline,
/*--- Automatically derived from: C:/daily/rwsdk/src/pipe/p2/p2altmdl.h ---*/
-/*--- Automatically derived from: C:/daily/rwsdk/src/pipe/p2/nodeTransform.h ---*/
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-extern RxNodeDefinition *RxNodeDefinitionGetTransform(void);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-
-/*--- Automatically derived from: C:/daily/rwsdk/src/pipe/p2/nodeSubmitTriangle.h ---*/
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-extern RxNodeDefinition * RxNodeDefinitionGetSubmitTriangle(void);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-
-/*--- Automatically derived from: C:/daily/rwsdk/src/pipe/p2/nodeSubmitLine.h ---*/
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-extern RxNodeDefinition * RxNodeDefinitionGetSubmitLine(void);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-
-/*--- Automatically derived from: C:/daily/rwsdk/src/pipe/p2/nodeScatter.h ---*/
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-extern RxNodeDefinition * RxNodeDefinitionGetScatter(void);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-
-/*--- Automatically derived from: C:/daily/rwsdk/src/pipe/p2/nodeClone.h ---*/
-
-typedef struct RxPacketCacheCluster RxPacketCacheCluster;
-
-/**
- * \ingroup rwcoregeneric
- * \struct RxPacketCacheCluster
- * structure containing a cache of an \ref RxCluster's
- * within an \ref RxPacketCache
- */
-struct RxPacketCacheCluster
-{
- RwUInt32 slot; /**< A \ref RwUInt32 index into the \ref RxPacketCache's
- * array of RxPacketCacheCluster's */
- RwUInt16 flags; /**< A cache of the original cluster's flags */
- RwUInt16 stride; /**< A cache of the original cluster's stride */
- void *data; /**< A cache of the original cluster's data */
- RwUInt32 numAlloced; /**< A cache of the original cluster's numAlloced */
- RwUInt32 numUsed; /**< A cache of the original cluster's numUsed */
- RxPipelineCluster *clusterRef; /**< A cache of the original cluster's \ref RxPipelineCluster */
-};
-typedef struct RxPacketCache RxPacketCache;
-
-/**
- * \ingroup rwcoregeneric
- * \struct RxPacketCache
- * structure containing a cache of a \ref RxPacket */
-struct RxPacketCache
-{
- RwUInt16 packetFlags; /**< A cache of the original packet's flags */
- RwUInt16 pad[1]; /**< Alignment padding */
- RwUInt32 numClusters; /**< The number of present clusters in the
- * original packet when it was cloned */
- RwBool lastCloneDone;/**< Once the cache has been cloned by \ref RxPacketCacheClone
- * with (lastClone == TRUE), it should not be used again! */
- RwUInt32 pad2[1]; /**< Alignment padding */
- RxPacketCacheCluster clusters[1]; /**< An array of \ref RxPacketCacheCluster's,
- * extending beyond 1 element */
-};
-
-
-typedef struct RxNodeCloneInitData RxNodeCloneInitData;
-/**
- * \ingroup rwcoregeneric
- * \struct RxNodeCloneInitData
- * structure with which to initialize
- * clone a \ref RxNodeDefinition,
- * through \ref RxNodeDefinitionCloneCreate and
- * set up cloned \ref RxPipelineNode modes, through
- * \ref RxPipelineNodeCloneDefineModes */
-struct RxNodeCloneInitData
-{
- RwUInt32 numModes; /**< Specifies the number of modes in
- which the node should operate */
- RwUInt32 numOutputs; /**< Specifies the number of outputs of this
- Clone node, which is also the maximum
- number of outputs to which any one mode
- may dispatch packets */
- RwUInt32 *modeSizes; /**< Specifies the number of outputs to which
- each mode dispatches packets */
- RwUInt32 **modes; /**< An array of numModes pointers to arrays
- (of length numOutputs) specifying the
- outputs, in order, to which each mode
- should dispatch packets (output zero is
- the first output) */
-};
-
-/**
- * \ingroup rwcoregeneric
- * \struct RxNodeCloneData
- * structure which is the private
- * data of Clone nodes \ref RxPipelineNode */
-typedef struct RxNodeCloneData RxNodeCloneData;
-struct RxNodeCloneData
-{
- RwBool optimized; /**< \ref RwBool specifying whether \ref RxPipelineNodeCloneOptimize
- * has been run on this \ref RxPipelineNode yet */
- RwUInt32 currentMode; /**< \ref RwUInt32 The current mode of operation */
- RxNodeCloneInitData *data;/**< A pointer to \ref RxNodeCloneInitData data
- * specifying the modes of operation */
-};
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-extern RxNodeDefinition *RxNodeDefinitionCloneCreate(RxNodeCloneInitData *data);
-extern RwBool RxPipelineNodeCloneDefineModes(
- RxPipeline *pipeline,
- RxPipelineNode *node,
- RxNodeCloneInitData *data);
-extern RwBool RxNodeDefinitionCloneDestroy(RxNodeDefinition *def);
-extern RwBool RxPipelineNodeCloneOptimize(RxPipeline *pipeline,
- RxPipelineNode *node);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-
-/*--- Automatically derived from: C:/daily/rwsdk/src/pipe/p2/nodeImmStash.h ---*/
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-extern RxNodeDefinition *RxNodeDefinitionGetImmStash(void);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-
-/*--- Automatically derived from: C:/daily/rwsdk/src/pipe/p2/nodeImmRenderSetup.h ---*/
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-extern RxNodeDefinition * RxNodeDefinitionGetImmRenderSetup(void);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-
-/*--- Automatically derived from: C:/daily/rwsdk/src/pipe/p2/nodeImmMangleTriangleIndices.h ---*/
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-extern RxNodeDefinition *RxNodeDefinitionGetImmMangleTriangleIndices(void);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-
-/*--- Automatically derived from: C:/daily/rwsdk/src/pipe/p2/nodeImmMangleLineIndices.h ---*/
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-extern RxNodeDefinition * RxNodeDefinitionGetImmMangleLineIndices(void);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-
-/*--- Automatically derived from: C:/daily/rwsdk/src/pipe/p2/nodeImmInstance.h ---*/
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-extern RxNodeDefinition * RxNodeDefinitionGetImmInstance(void);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-
-/*--- Automatically derived from: C:/daily/rwsdk/src/pipe/p2/nodeCullTriangle.h ---*/
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-extern RxNodeDefinition * RxNodeDefinitionGetCullTriangle(void);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-
-/*--- Automatically derived from: C:/daily/rwsdk/src/pipe/p2/nodeClipTriangle.h ---*/
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-extern RxNodeDefinition *RxNodeDefinitionGetClipTriangle(void);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-
-/*--- Automatically derived from: C:/daily/rwsdk/src/pipe/p2/nodeClipLine.h ---*/
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-extern RxNodeDefinition *RxNodeDefinitionGetClipLine(void);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-
/*--- Automatically derived from: C:/daily/rwsdk/driver/d3d8/d3d8texdic.h ---*/
/*--- Automatically derived from: C:/daily/rwsdk/driver/d3d8/d3d8rendst.h ---*/
@@ -1415,7 +1153,7 @@ extern RxNodeDefinition *RxNodeDefinitionGetClipLine(void);
*/
/**
- * \ingroup datatypes
+ * \ingroup rwraster
* \ref RwRasterLockMode represents the options available for locking
* a raster so that it may be modified (see API function \ref RwRasterLock). An
* application may wish to write to the raster, read from the raster or
@@ -1445,7 +1183,7 @@ enum RwRasterLockMode
typedef enum RwRasterLockMode RwRasterLockMode;
/**
- * \ingroup datatypes
+ * \ingroup rwraster
* \ref RwRasterFlipMode represents
* raster flip modes */
enum RwRasterFlipMode
@@ -1457,7 +1195,7 @@ enum RwRasterFlipMode
typedef enum RwRasterFlipMode RwRasterFlipMode;
/**
- * \ingroup datatypes
+ * \ingroup rwraster
* RwRasterType
* This type represents the options available for creating a new
* raster (se API function \ref RwRasterCreate)*/
@@ -1476,7 +1214,7 @@ enum RwRasterType
typedef enum RwRasterType RwRasterType;
/**
- * \ingroup datatypes
+ * \ingroup rwraster
* \ref RwRasterFormat is a set of values and flags which may be combined to
* specify a raster format. The format chosen for a particular raster depends
* on the hardware device and the raster type specified at creation time
@@ -1569,8 +1307,8 @@ typedef enum RwRasterPrivateFlag RwRasterPrivateFlag;
*/
/**
- * \ingroup datatypes
- * \typedef RwRaster
+ * \ingroup rwraster
+ * \struct RwRaster
* Raster containing device-dependent pixels.
* This should be considered an opaque type.
* Use the RwRaster API functions to access.
@@ -1661,6 +1399,8 @@ extern "C"
#endif /* __cplusplus */
/* Creating destroying rasters */
+extern void RwRasterSetFreeListCreateParams( RwInt32 blockSize, RwInt32 numBlocksToPrealloc );
+
extern RwRaster *RwRasterCreate(RwInt32 width, RwInt32 height,
RwInt32 depth, RwInt32 flags);
extern RwBool RwRasterDestroy(RwRaster * raster);
@@ -1743,8 +1483,6 @@ extern RwBool RwRasterValidatePlugins(const RwRaster * raster);
#endif /* (defined(__ICL)) */
-#include <windows.h>
-
#if (defined(RWDEBUG))
#if (defined(RWMEMDEBUG) && !defined(_CRTDBG_MAP_ALLOC))
#define _CRTDBG_MAP_ALLOC
@@ -1837,48 +1575,16 @@ MACRO_START \
} \
MACRO_STOP
-/* LEGACY-SUPPORT macros */
-#define RWIM2DVERTEXSetCameraX(vert, camx) RwIm2DVertexSetCameraX(vert, camx)
-#define RWIM2DVERTEXSetCameraY(vert, camy) RwIm2DVertexSetCameraY(vert, camy)
-#define RWIM2DVERTEXSetCameraZ(vert, camz) RwIm2DVertexSetCameraZ(vert, camz)
-#define RWIM2DVERTEXSetRecipCameraZ(vert, recipz) \
- RwIm2DVertexSetRecipCameraZ(vert, recipz)
-#define RWIM2DVERTEXGetCameraX(vert) RwIm2DVertexGetCameraX(vert)
-#define RWIM2DVERTEXGetCameraY(vert) RwIm2DVertexGetCameraY(vert)
-#define RWIM2DVERTEXGetCameraZ(vert) RwIm2DVertexGetCameraZ(vert)
-#define RWIM2DVERTEXGetRecipCameraZ(vert) RwIm2DVertexGetRecipCameraZ(vert)
-#define RWIM2DVERTEXSetScreenX(vert, scrnx) RwIm2DVertexSetScreenX(vert, scrnx)
-#define RWIM2DVERTEXSetScreenY(vert, scrny) RwIm2DVertexSetScreenY(vert, scrny)
-#define RWIM2DVERTEXSetScreenZ(vert, scrnz) RwIm2DVertexSetScreenZ(vert, scrnz)
-#define RWIM2DVERTEXGetScreenX(vert) RwIm2DVertexGetScreenX(vert)
-#define RWIM2DVERTEXGetScreenY(vert) RwIm2DVertexGetScreenY(vert)
-#define RWIM2DVERTEXGetScreenZ(vert) RwIm2DVertexGetScreenZ(vert)
-#define RWIM2DVERTEXSetU(vert, u, recipz) RwIm2DVertexSetU(vert, u, recipz)
-#define RWIM2DVERTEXSetV(vert, v, recipz) RwIm2DVertexSetV(vert, v, recipz)
-#define RWIM2DVERTEXGetU(vert) RwIm2DVertexGetU(vert)
-#define RWIM2DVERTEXGetV(vert) RwIm2DVertexGetV(vert)
-#define RWIM2DVERTEXSetRealRGBA(vert, red, green, blue, alpha) \
- RwIm2DVertexSetRealRGBA(vert, red, green, blue, alpha)
-#define RWIM2DVERTEXSetIntRGBA(vert, red, green, blue, alpha) \
- RwIm2DVertexSetIntRGBA(vert, red, green, blue, alpha)
-#define RWIM2DVERTEXGetRed(vert) RwIm2DVertexGetRed(vert)
-#define RWIM2DVERTEXGetGreen(vert) RwIm2DVertexGetGreen(vert)
-#define RWIM2DVERTEXGetBlue(vert) RwIm2DVertexGetBlue(vert)
-#define RWIM2DVERTEXGetAlpha(vert) RwIm2DVertexGetAlpha(vert)
-#define RWIM2DVERTEXCopyRGBA(dst, src) RwIm2DVertexCopyRGBA(dst, src)
-#define RWIM2DVERTEXClipRGBA(o, i, n, f) RwIm2DVertexClipRGBA(o, i, n, f)
-
/****************************************************************************
Global Types
*/
/* We use RwD3D8Vertex to drive the hardware in 2D mode */
-/**
- * \ingroup rwcoredriverd3d8
- * \typedef RwD3D8Vertex
+/*
* D3D8 vertex structure definition for 2D geometry
*/
+#if !defined(RWADOXYGENEXTERNAL)
typedef struct RwD3D8Vertex RwD3D8Vertex;
/**
* \ingroup rwcoredriverd3d8
@@ -1897,47 +1603,41 @@ struct RwD3D8Vertex
RwReal u; /**< Texture coordinate U */
RwReal v; /**< Texture coordinate V */
};
+#endif /* !defined(RWADOXYGENEXTERNAL) */
/* Define types used */
+#if !defined(RWADOXYGENEXTERNAL)
/**
* \ingroup rwcoredriverd3d8
- * \typedef RwIm2DVertex
+ * \ref RwIm2DVertex
* Typedef for a RenderWare Graphics Immediate Mode 2D Vertex
*/
typedef RwD3D8Vertex RwIm2DVertex;
+#endif /* !defined(RWADOXYGENEXTERNAL) */
-/* LEGACY-SUPPORT macro */
+#if !defined(RWADOXYGENEXTERNAL)
/**
* \ingroup rwcoredriverd3d8
- * \def RWIM2DVERTEX
- * RWIM2DVERTEX is a legacy macro for RwIm2DVertex
- */
-#define RWIM2DVERTEX RwIm2DVertex
-
-/**
- * \ingroup rwcoredriverd3d8
- * \typedef RxVertexIndex
+ * \ref RxVertexIndex
*
* Typedef for a RenderWare Graphics PowerPipe Immediate
* Mode Vertex
*/
typedef RwUInt16 RxVertexIndex;
+#endif /* !defined(RWADOXYGENEXTERNAL) */
+
+#if !defined(RWADOXYGENEXTERNAL)
/**
* \ingroup rwcoredriverd3d8
- * \typedef RwImVertexIndex
+ * \ref RwImVertexIndex
* Typedef for a RenderWare Graphics Immediate Mode Vertex.
*/
typedef RxVertexIndex RwImVertexIndex;
+#endif /* !defined(RWADOXYGENEXTERNAL) */
-/* LEGACY-SUPPORT macro */
-/**
- * \ingroup rwcoredriverd3d8
- * \def RWIMVERTEXINDEX
- * RWIMVERTEXINDEX is a legacy macro for RwImVertexIndex
- */
-#define RWIMVERTEXINDEX RwImVertexIndex
+#if !defined(RWADOXYGENEXTERNAL)
/**
* \ingroup rwcoredriverd3d8
@@ -1950,8 +1650,10 @@ typedef struct
RwUInt32 numTextureStageStateChanges; /**< Number of Texture Stage States changed */
RwUInt32 numMaterialChanges; /**< Number of Material changes */
RwUInt32 numLightsChanged; /**< Number of Lights changed */
+ RwUInt32 numVBSwitches; /**< Number of Vertex Buffer switches */
}
RwD3D8Metrics;
+#endif /* !defined(RWADOXYGENEXTERNAL) */
#endif /* D3D8_DRVMODEL_H */
@@ -1973,15 +1675,13 @@ RwD3D8Metrics;
/* We use D3D8 formats for the instanced versions, to allow hardware T&L */
-/**
- * \ingroup corep2d3d8
- * \typedef RxObjSpace3DVertex
+/*
* Typedef for an RxObjSpace3DVertex.
*/
typedef struct RxObjSpace3DVertex RxObjSpace3DVertex;
/**
- * \ingroup corep2d3d8
+ * \ingroup cored3d8
* \struct RxObjSpace3DVertex
* Structure representing object space vertex.
*/
@@ -2000,21 +1700,25 @@ struct RxObjSpace3DVertex
#define RxObjSpace3DVertexFullSize (sizeof(RxObjSpace3DVertex))
/**
- * \ingroup corep2d3d8
- * \typedef RxObjSpace3DLitVertex
+ * \ingroup cored3d8
+ * \ref RxObjSpace3DLitVertex
* Typedef for an RxObjSpace3DLitVertex.
*/
typedef RxObjSpace3DVertex RxObjSpace3DLitVertex;
/**
- * \ingroup corep2d3d8
- * \typedef RwIm3DVertex
+ * \ingroup cored3d8
+ * \ref RwIm3DVertex
* Typedef for an RwIm3DVertex.
*/
typedef RxObjSpace3DLitVertex RwIm3DVertex;
/* LEGACY-SUPPORT macro */
-#define RWIM3DVERTEX RwIm3DVertex
+/**
+ * \ingroup cored3d8
+ * \ref RxScrSpace2DVertex
+ * Typedef for an RxScrSpace2DVertex structure
+ */
typedef RwIm2DVertex RxScrSpace2DVertex;
/****************************************************************************
@@ -2161,55 +1865,6 @@ MACRO_STOP
#define RwIm3DVertexCopyRGBA(_dst, _src) (((_dst)->color) = ((_src)->color))
-/* LEGACY-SUPPORT macros */
-#define RWIM2DCAMERAVERTEXSetU(_devvert, _camvert, _u, _recipz) \
- RwIm2DCameraVertexSetU(_devvert, _camvert, _u, _recipz)
-#define RWIM2DCAMERAVERTEXSetV(_devvert, _camvert, _v, _recipz) \
- RwIm2DCameraVertexSetV(_devvert, _camvert, _v, _recipz)
-#define RWIM3DVERTEXGetNext(vert) RwIm3DVertexGetNext(vert)
-#define RWIM3DVERTEXSetPos(vert, imx, imy, imz) RwIm3DVertexSetPos(vert, imx, imy, imz)
-#define RWIM3DVERTEXGetPos(vert) RwIm3DVertexGetPos(vert)
-#define RWIM3DVERTEXSetU(vert, imu) RwIm3DVertexSetU(vert, imu)
-#define RWIM3DVERTEXSetV(vert, imv) RwIm3DVertexSetV(vert, imv)
-#define RWIM3DVERTEXSetRGBA(vert, r, g, b, a) RwIm3DVertexSetRGBA(vert, r, g, b, a)
-#define RWIM3DVERTEXSetNormal(vert, imx, imy, imz) RwIm3DVertexSetNormal(vert, imx, imy, imz)
-#define RWIM3DVERTEXCopyRGBA(dst,src) RwIm3DVertexCopyRGBA(dst,src)
-#define RXOBJSPACE3DVERTEXGetPos(_vert, _pos) \
- RxObjSpace3DVertexGetPos(_vert, _pos)
-#define RXOBJSPACE3DVERTEXSetPos(_vert, _pos) \
- RxObjSpace3DVertexSetPos(_vert, _pos)
-#define RXOBJSPACE3DVERTEXGetPreLitColor(_vert, _col) \
- RxObjSpace3DVertexGetPreLitColor(_vert, _col)
-#define RXOBJSPACE3DVERTEXSetPreLitColor(_vert, _col) \
- RxObjSpace3DVertexSetPreLitColor(_vert, _col)
-#define RXOBJSPACE3DVERTEXGetColor RxObjSpace3DVertexGetColor
-#define RXOBJSPACE3DVERTEXGetNormal(_vert, _normal) \
- RxObjSpace3DVertexGetNormal(_vert, _normal)
-#define RXOBJSPACE3DVERTEXSetNormal(_vert, _normal) \
- RxObjSpace3DVertexSetNormal(_vert, _normal)
-#define RXOBJSPACE3DVERTEXGetU(_vert) RxObjSpace3DVertexGetU(_vert)
-#define RXOBJSPACE3DVERTEXGetV(_vert) RxObjSpace3DVertexGetV(_vert)
-#define RXOBJSPACE3DVERTEXSetU(_vert, _imu) \
- RxObjSpace3DVertexSetU(_vert, _imu)
-#define RXOBJSPACE3DVERTEXSetV(_vert, _imv) \
- RxObjSpace3DVertexSetV(_vert, _imv)
-#define RXOBJSPACE3DLITVERTEXGetPos(vert, pos) \
- RxObjSpace3DLitVertexGetPos(vert, pos)
-#define RXOBJSPACE3DLITVERTEXSetPos(vert, pos) \
- RxObjSpace3DLitVertexSetPos(vert, pos)
-#define RXOBJSPACE3DLITVERTEXGetColor(vert, col) \
- RxObjSpace3DLitVertexGetColor(vert, col)
-#define RXOBJSPACE3DLITVERTEXSetColor(vert, col) \
- RxObjSpace3DLitVertexSetColor(vert, col)
-#define RXOBJSPACE3DLITVERTEXGetU(vert) \
- RxObjSpace3DLitVertexGetU(vert)
-#define RXOBJSPACE3DLITVERTEXGetV(vert) \
- RxObjSpace3DLitVertexGetV(vert)
-#define RXOBJSPACE3DLITVERTEXSetU(vert, imu) \
- RxObjSpace3DLitVertexSetU(vert, imu)
-#define RXOBJSPACE3DLITVERTEXSetV(vert, imv) \
- RxObjSpace3DLitVertexSetV(vert, imv)
-
/*--- Automatically derived from: C:/daily/rwsdk/src/pipe/p2/p2renderstate.h ---*/
@@ -2224,7 +1879,6 @@ enum RxRenderStateFlag
rxRENDERSTATEFLAG_ZWRITEENABLE = 0x00000004, /**<Z-Buffer writing is to be enabled */
rxRENDERSTATEFLAG_VERTEXALPHAENABLE = 0x00000008, /**<Vertex alpha is to be enabled */
rxRENDERSTATEFLAG_FOGENABLE = 0x00000010, /**<Fog is to be enabled */
- rxRENDERSTATEFLAG_ALPHAPRIMITIVEBUFFER = 0x00000020, /**<Alpha primitive buffering is to be enabled */
rxRENDERSTATEFLAGFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
};
typedef enum RxRenderStateFlag RxRenderStateFlag;
@@ -2248,7 +1902,6 @@ struct RxRenderStateVector
RwRGBA BorderColor; /**< Border color for texturing address mode border */
RwFogType FogType; /**< Select the type of fogging to use */
RwRGBA FogColor; /**< Color used for fogging */
- RwUInt8 *FogTable; /**< A 256 entry fog table */
};
#if (!defined(RxRenderStateVectorAssign))
@@ -2274,52 +1927,6 @@ extern RxRenderStateVector *RxRenderStateVectorLoadDriverState(RxRenderSta
#endif /* __cplusplus */
-/*--- Automatically derived from: C:/daily/rwsdk/src/pipe/p2/p2clpcom.h ---*/
-
-/*--- Automatically derived from: C:/daily/rwsdk/src/pipe/p2/nodeRGBAInterp.h ---*/
-
-struct NodeRGBAInterpData
-{
- RwBool rgbaInterpOn;
- RxRenderStateVector state;
-};
-typedef struct NodeRGBAInterpData NodeRGBAInterpData;
-
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-extern RxNodeDefinition *RxNodeDefinitionGetRGBAInterp(void);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-
-/*--- Automatically derived from: C:/daily/rwsdk/src/pipe/p2/nodeUVInterp.h ---*/
-
-typedef struct RxNodeUVInterpSettings RxNodeUVInterpSettings;
-struct RxNodeUVInterpSettings
-{
- RwBool uvInterpOn;
- RxRenderStateVector state;
-};
-
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif /* __cplusplus */
-
-extern RxNodeDefinition * RxNodeDefinitionGetUVInterp(void);
-
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
-
-
/*--- Automatically derived from: C:/daily/rwsdk/src/baimage.h ---*/
/****************************************************************************
@@ -2342,8 +1949,8 @@ typedef enum RwImageFlag RwImageFlag;
*/
/**
- * \ingroup datatypes
- * \typedef RwImage
+ * \ingroup rwimage
+ * \struct RwImage
* Image containing device-independent pixels.
* This should be considered an opaque type.
* Use the RwImage API functions to access.
@@ -2367,7 +1974,7 @@ struct RwImage
#endif /* (!defined(DOXYGEN)) */
/**
- * \ingroup datatypes
+ * \ingroup rwimage
* \ref RwImageCallBackRead
* is the function registered with \ref RwImageRegisterImageFormat that is used,
* for example by \ref RwImageRead and \ref RwImageReadMaskedImage,
@@ -2375,13 +1982,15 @@ struct RwImage
*
* \param imageName Pointer to a string containing the file name of the image.
*
+ * \return Returns a pointer to the image read.
+ *
* \see RwImageRegisterImageFormat
*
*/
typedef RwImage *(*RwImageCallBackRead)(const RwChar * imageName);
/**
- * \ingroup datatypes
+ * \ingroup rwimage
* \ref RwImageCallBackWrite
* is the function registered with \ref RwImageRegisterImageFormat that is used,
* for example by \ref RwImageWrite,
@@ -2474,6 +2083,11 @@ extern "C"
#endif /* __cplusplus */
/* Creating and destroying */
+
+extern void RwImageSetFreeListCreateParams( RwInt32 blockSize, RwInt32 numBlocksToPrealloc );
+
+extern void RwImageFormatSetFreeListCreateParams( RwInt32 blockSize, RwInt32 numBlocksToPrealloc );
+
extern RwImage *RwImageCreate(RwInt32 width, RwInt32 height,
RwInt32 depth);
extern RwBool RwImageDestroy(RwImage * image);
@@ -2505,6 +2119,8 @@ extern RwImage *RwImageWrite(RwImage * image,
/* Setting and getting the default path for images */
extern RwChar *RwImageGetPath(void);
extern const RwChar *RwImageSetPath(const RwChar * path);
+ /* Fast image path change */
+extern void _rwImageSwapPath(RwChar **path, RwInt32 *size);
/* Setting */
#if (defined(RWDEBUG) || defined(RWSUPPRESSINLINE))
@@ -2593,8 +2209,8 @@ extern const RwImage *RwImageStreamWrite(const RwImage * image,
*/
/**
- * \ingroup datatypes
- * \typedef RwTexDictionary
+ * \ingroup rwtexdict
+ * \struct RwTexDictionary
* is a texture dictionary containing textures.
* This should be considered an opaque type.
* Use the RwTexDictionary API functions to access.
@@ -2615,8 +2231,8 @@ struct RwTexDictionary
/* Parent is the dictionary */
/**
- * \ingroup datatypes
- * \typedef RwTexture
+ * \ingroup rwtexture
+ * \struct RwTexture
* is a texture object.
* This should be considered an opaque type.
* Use the RwTexture API functions to access.
@@ -2641,7 +2257,7 @@ struct RwTexture
#endif /* (!defined(DOXYGEN)) */
/**
- * \ingroup datatypes
+ * \ingroup rwtexture
* \ref RwTextureCallBackRead
* represents the function used by \ref RwTextureRead to read the specified
* texture from a disk file. This function should return a pointer to the
@@ -2662,7 +2278,7 @@ typedef RwTexture *(*RwTextureCallBackRead)(const RwChar *name,
const RwChar *maskName);
/**
- * \ingroup datatypes
+ * \ingroup rwtexture
* \ref RwTextureCallBack
* represents the function called from \ref RwTexDictionaryForAllTextures
* for all textures in a given texture dictionary. This function should
@@ -2681,7 +2297,7 @@ typedef RwTexture *(*RwTextureCallBack)(RwTexture *texture, void *pData);
/**
- * \ingroup datatypes
+ * \ingroup rwtexdict
* \ref RwTexDictionaryCallBack
* represents the function called from \ref RwTexDictionaryForAllTexDictionaries
* for all texture dictionaries that currently exist. This function should
@@ -2702,7 +2318,7 @@ typedef RwTexDictionary *(*RwTexDictionaryCallBack)(RwTexDictionary *dict, void
/**
- * \ingroup datatypes
+ * \ingroup rwtexture
* \ref RwTextureCallBackMipmapGeneration
* is the callback function supplied to \ref RwTextureSetMipmapGenerationCallBack
* and returned from \ref RwTextureGetMipmapGenerationCallBack.
@@ -2726,7 +2342,7 @@ typedef RwRaster *(*RwTextureCallBackMipmapGeneration)(RwRaster * raster,
RwImage * image);
/**
- * \ingroup datatypes
+ * \ingroup rwtexture
* \ref RwTextureCallBackMipmapName
* is the callback function supplied to \ref RwTextureSetMipmapNameCallBack and
* returned from \ref RwTextureGetMipmapNameCallBack.
@@ -2926,10 +2542,14 @@ extern RwTexture *RwTextureSetMaskName(RwTexture * texture,
const RwChar * maskName);
/* Creating/destroying dictionaries */
+extern void RwTexDictionarySetFreeListCreateParams( RwInt32 blockSize, RwInt32 numBlocksToPrealloc );
+
extern RwTexDictionary *RwTexDictionaryCreate(void);
extern RwBool RwTexDictionaryDestroy(RwTexDictionary * dict);
/* Textures */
+void RwTextureSetFreeListCreateParams( RwInt32 blockSize, RwInt32 numBlocksToPrealloc );
+
extern RwTexture *RwTextureCreate(RwRaster * raster);
extern RwBool RwTextureDestroy(RwTexture * texture);
@@ -3071,13 +2691,11 @@ enum RwClipFlag
rwCLIPFLAGFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
};
-typedef enum RwClipFlag RwClipFlag;
-
-/**
- * \ingroup rwcoregeneric
- * \typedef RwClipFlag
+/*
* Typedef for RwClipFlag enumeration specifying the clipping status of a vertex
*/
+typedef enum RwClipFlag RwClipFlag;
+
typedef struct RxCamSpace3DVertex RxCamSpace3DVertex;
@@ -3094,8 +2712,8 @@ struct RxCamSpace3DVertex
/* Clip flags on this vertex */
RwUInt8 clipFlags; /**< Clip flags for the vertex generated during transformation into camera-space, see \ref RwClipFlag */
RwUInt8 pad[3]; /**< Alignment padding */
- /* Lit colour */
- RwRGBAReal col; /**< Accumulated \ref RwReal light values (initialized to zero or prelight colours) */
+ /* Lit color */
+ RwRGBAReal col; /**< Accumulated \ref RwReal light values (initialized to zero or prelight colors) */
/* Only used by the clipper */
RwReal u; /**< Texture U coordinate */
RwReal v; /**< Texture V coordinate */
@@ -3103,8 +2721,8 @@ struct RxCamSpace3DVertex
/* Supports pipeline1 apps: */
/**
- * \ingroup datatypes
- * \typedef RwCameraVertex
+ * \ingroup rwcoregeneric
+ * \ref RwCameraVertex
* typedef for a structure describing a camera-space 3D vertex.
*/
typedef RxCamSpace3DVertex RwCameraVertex;
@@ -3159,9 +2777,7 @@ enum RxGeometryFlag
rxGEOMETRYFLAGFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
};
-/**
- * \ingroup rwcoregeneric
- * \typedef RxGeometryFlag
+/*
* Typedef for RxGeometryFlag enumeration describing geometry properties
*/
typedef enum RxGeometryFlag RxGeometryFlag;
@@ -3186,7 +2802,7 @@ struct RxMeshStateVector
/* We can't necessarily reference an RpMaterial in here (i.e with Im3D),
* because RpMaterials are defined in RpWorld not RwCore */
RwTexture *Texture; /**< A pointer to a \ref RwTexture */
- RwRGBA MatCol; /**< \ref RwRGBA material colour */
+ RwRGBA MatCol; /**< \ref RwRGBA material color */
RxPipeline *Pipeline; /**< A pointer to the material pipeline where appropriate */
/* rwPRIMTYPETRILIST/TRIFAN/TRISTRIP/LINELIST/POLYLINE */
RwPrimitiveType PrimType; /**< \ref RwPrimitiveType primitive type */
@@ -3295,7 +2911,7 @@ struct RxVStep
/* CamNorms.csl */
/**
* \ingroup rwcoregeneric
- * \typedef RxCamNorm
+ * \ref RxCamNorm
* typedef for \ref RwV3d used by the RxClVStep cluster */
typedef RwV3d RxCamNorm;
@@ -3342,7 +2958,7 @@ extern RxClusterDefinition RxClTriPlanes;
/*--- Automatically derived from: C:/daily/rwsdk/src/pipe/p2/baim3d.h ---*/
/**
- * \ingroup datatypes
+ * \ingroup rwim3d
* RwIm3DTransformFlags
* The bit-field type RwIm3DTransformFlags
* specifies options available for controlling execution of the 3D immediate
@@ -3373,6 +2989,8 @@ typedef struct rwIm3DVertexCache RwIm3DVertexCache;
#endif /* (0&& defined(SKY2)) */
/* complete information to reconstruct post-transform Im3D "mesh" packet */
+
+#if (!defined(DOXYGEN))
struct _rwIm3DPoolStash
{
RwUInt32 flags; /* rwIM3D_VERTEXUV, rwIM3D_ALLOPAQUE, rwIM3D_NOCLIP etc */
@@ -3413,14 +3031,11 @@ struct rwIm3DRenderPipelines
struct rwImmediGlobals
{
- RxPipeline *genericIm3DTransformPipeline;
- rwIm3DRenderPipelines genericIm3DRenderPipelines;
-
RxPipeline *im3DTransformPipeline;
rwIm3DRenderPipelines im3DRenderPipelines;
/* Platforms that have their own non-generic pipelines
- * (OPENGL, D3D7, SKY2, KAMUI2, DOLPHIN) put them here: */
+ * (OPENGL, D3D8, SKY2, KAMUI2, DOLPHIN) put them here: */
RxPipeline *platformIm3DTransformPipeline;
rwIm3DRenderPipelines platformIm3DRenderPipelines;
@@ -3431,12 +3046,11 @@ struct rwImmediGlobals
/* The line PS2All render pipe automatically
* calls this PS2AllMat pipeline: */
RxPipeline *ps2AllMatIm3DLinePipeline;
- /* PS2Manager pipelines */
- RxPipeline *ps2ManagerIm3DRenderPipeline;
#endif /* (defined(SKY2_DRVMODEL_H)) */
rwIm3DPool curPool; /* The current cache of transformed vertices */
};
+#endif /* (!defined(DOXYGEN)) */
#ifdef __cplusplus
@@ -3458,9 +3072,6 @@ extern RwBool RwIm3DRenderIndexedPrimitive(RwPrimitiveType primType,
RwInt32 numIndices);
extern RwBool RwIm3DRenderPrimitive(RwPrimitiveType primType);
-extern RxPipeline *RwIm3DGetGenericTransformPipeline(void);
-extern RxPipeline *RwIm3DGetGenericRenderPipeline(RwPrimitiveType primType);
-
extern RxPipeline *RwIm3DGetTransformPipeline(void);
extern RxPipeline *RwIm3DGetRenderPipeline( RwPrimitiveType primType);
extern RxPipeline *RwIm3DSetTransformPipeline(RxPipeline *pipeline);
@@ -3670,8 +3281,23 @@ extern RwBool RwD3D8CameraIsBBoxFullyInsideFrustum(const void *camera, const voi
* Cheking the CPU capabilities
*/
-extern RwBool _rwIntelSSEsupported(void);
+#if (defined(RWDEBUG) || defined(RWSUPPRESSINLINE))
extern RwBool _rwIntelMMXsupported(void);
+extern RwBool _rwIntelSSEsupported(void);
+extern RwBool _rwIntelSSE2supported(void);
+extern RwBool _rwAMD3DNowSupported(void);
+
+#else
+extern RwBool _rwD3D8CPUSupportsMMX;
+extern RwBool _rwD3D8CPUSupportsSSE;
+extern RwBool _rwD3D8CPUSupportsSSE2;
+extern RwBool _rwD3D8CPUSupports3DNow;
+
+#define _rwIntelMMXsupported() _rwD3D8CPUSupportsMMX
+#define _rwIntelSSEsupported() _rwD3D8CPUSupportsSSE
+#define _rwIntelSSE2supported() _rwD3D8CPUSupportsSSE2
+#define _rwAMD3DNowSupported() _rwD3D8CPUSupports3DNow
+#endif
/*
* Enabling texture format conversions when loading textures from a texture
@@ -3680,6 +3306,8 @@ extern RwBool _rwIntelMMXsupported(void);
extern void
_rwD3D8TexDictionaryEnableRasterFormatConversion(RwBool enable);
+/* Called from RwEngineInit to give the driver a chance to register plugins */
+extern RwBool _rwDeviceRegisterPlugin(void);
#ifdef __cplusplus
}
@@ -3689,7 +3317,7 @@ _rwD3D8TexDictionaryEnableRasterFormatConversion(RwBool enable);
/* LEGACY-MACRO */
/**
* \ingroup rwcoredriverd3d8
- * \ref RwD3DLoadNativeTexture is a legacy macro for compatability with
+ * \ref RwD3DLoadNativeTexture is a legacy macro for compatibility with
* RWD3D7 applications that can be used to read a compressed texture from
* the specified DDS file on disk.
*
@@ -3820,17 +3448,16 @@ struct RwFrame
#endif /* (!defined(DOXYGEN)) */
/**
- * \ingroup datatypes
- * \typedef RwFrame
- Frame for defining object position and orientation.
+ * \ingroup rwframe
+ * \struct RwFrame
+ * Frame for defining object position and orientation.
* This should be considered an opaque type.
* Use the RwFrame API functions to access.
*/
typedef struct RwFrame RWALIGN(RwFrame, rwFRAMEALIGNMENT);
/**
- * \ingroup datatypes
- * \typedef RwFrameCallBack
+ * \ingroup rwframe
* \ref RwFrameCallBack type represents the function
* called from \ref RwFrameForAllChildren for all child frames linked to a given frame.
* This function should return a pointer to the current frame to indicate success.
@@ -3840,6 +3467,8 @@ typedef struct RwFrame RWALIGN(RwFrame, rwFRAMEALIGNMENT);
* iterator.
* \param data Pointer to developer-defined data structure.
*
+ * \return
+ *
* \see RwFrameForAllChildren
*
*/
@@ -3867,6 +3496,9 @@ extern "C"
{
#endif /* __cplusplus */
+extern void RwFrameSetFreeListCreateParams(RwInt32 blockSize,
+ RwInt32 numBlocksToPrealloc );
+
/* Finding what is attached to a frame */
extern RwFrame *
RwFrameForAllObjects(RwFrame * frame,
@@ -3945,6 +3577,9 @@ extern RwFrame *
RwFrameUpdateObjects(RwFrame * frame);
/* Creating destroying frames */
+extern void
+RwFrameSetFreeListCreateParams( RwInt32 blockSize, RwInt32 numBlocksToPrealloc );
+
extern RwFrame *
RwFrameCreate(void);
@@ -4030,12 +3665,15 @@ _rwFramePurgeClone(RwFrame *root);
typedef struct RwObjectHasFrame RwObjectHasFrame;
typedef RwObjectHasFrame * (*RwObjectHasFrameSyncFunction)(RwObjectHasFrame *object);
+
+#if (!defined(DOXYGEN))
struct RwObjectHasFrame
{
RwObject object;
RwLLLink lFrame;
RwObjectHasFrameSyncFunction sync;
};
+#endif /* (!defined(DOXYGEN)) */
/****************************************************************************
Function prototypes
@@ -4082,12 +3720,15 @@ MACRO_STOP
Global types
*/
typedef struct rpTextureChunkInfo RwTextureChunkInfo;
+
+#if (!defined(DOXYGEN))
struct rpTextureChunkInfo
{
RwTextureFilterMode filtering;
RwTextureAddressMode addressingU;
RwTextureAddressMode addressingV;
};
+#endif /* (!defined(DOXYGEN)) */
/* Bit flags defining properties of textures when stream */
enum RwTextureStreamFlags
@@ -4169,11 +3810,14 @@ _rwTextureChunkInfoRead(RwStream *stream,
*/
typedef struct rwFrameList rwFrameList;
+
+#if (!defined(DOXYGEN))
struct rwFrameList
{
RwFrame **frames;
RwInt32 numFrames;
};
+#endif /* (!defined(DOXYGEN)) */
/****************************************************************************
Global Variables
@@ -4257,7 +3901,7 @@ _rwFrameListStreamWrite(const rwFrameList *frameList,
typedef struct RwBBox RwBBox;
/**
- * \ingroup datatypes
+ * \ingroup rwbbox
* \struct RwBBox
* This type represents a 3D axis-aligned bounding-box
* specified by the positions of two corners which lie on a diagonal.
@@ -4442,7 +4086,7 @@ MACRO_STOP
*/
/**
- * \ingroup datatypes
+ * \ingroup rwcamera
* RwCameraClearMode
* Camera clear flags */
enum RwCameraClearMode
@@ -4458,7 +4102,7 @@ enum RwCameraClearMode
typedef enum RwCameraClearMode RwCameraClearMode;
/**
- * \ingroup datatypes
+ * \ingroup rwcamera
* RwCameraProjection
* This type represents the options available for
* setting the camera projection model, either perspective projection or
@@ -4473,7 +4117,7 @@ enum RwCameraProjection
typedef enum RwCameraProjection RwCameraProjection;
/**
- * \ingroup datatypes
+ * \ingroup rwcamera
* RwFrustumTestResult
* This type represents the results from a
* camera frustum test on a given sphere (see API function
@@ -4489,8 +4133,8 @@ typedef enum RwFrustumTestResult RwFrustumTestResult;
/**
- * \ingroup datatypes
- * \typedef RwCamera
+ * \ingroup rwcamera
+ * \struct RwCamera
* Camera object for rendering a view.
* This should be considered an opaque type.
* Use the RwCamera API functions to access.
@@ -4502,6 +4146,8 @@ typedef RwCamera *(*RwCameraBeginUpdateFunc) (RwCamera * camera);
typedef RwCamera *(*RwCameraEndUpdateFunc) (RwCamera * camera);
typedef struct RwFrustumPlane RwFrustumPlane;
+
+#if (!defined(DOXYGEN))
/*
* Structure describing a frustrum plane.
*/
@@ -4514,7 +4160,7 @@ struct RwFrustumPlane
RwUInt8 pad;
};
-#if (!defined(DOXYGEN))
+
struct RwCamera
{
RwObjectHasFrame object;
@@ -4560,8 +4206,7 @@ struct RwCamera
#endif /* (!defined(DOXYGEN)) */
/**
- * \ingroup datatypes
- * \typedef RwCameraCallBack
+ * \ingroup rwcamera
* \ref RwCameraCallBack type represents a function called from any camera
* iterator that may be implemented in plugins. This function should return a
* pointer to the current camera to indicate success. The callback may return
@@ -4569,6 +4214,8 @@ struct RwCamera
*
* \param camera Pointer to the current camera, supplied by iterator.
* \param data Pointer to developer-defined data structure.
+ *
+ * \return
*/
typedef RwCamera *(*RwCameraCallBack)(RwCamera *camera, void *data);
@@ -4594,6 +4241,8 @@ extern RwCamera *RwCameraShowRaster(RwCamera * camera, void *pDev,
RwUInt32 flags);
/* Creation and destruction */
+extern void RwCameraSetFreeListCreateParams( RwInt32 blockSize,
+ RwInt32 numBlocksToPrealloc );
extern RwBool RwCameraDestroy(RwCamera * camera);
extern RwCamera *RwCameraCreate(void);
extern RwCamera *RwCameraClone(RwCamera * camera);
@@ -4669,10 +4318,9 @@ extern RwFrame *RwCameraGetFrame(const RwCamera *camera);
/*--- Automatically derived from: C:/daily/rwsdk/driver/common/barwtyp.h ---*/
-/*--- Automatically derived from: C:/daily/rwsdk/src/bacamval.h ---*/
-
/*--- Automatically derived from: C:/daily/rwsdk/src/pipe/p2/bapipe.h ---*/
+#if (!defined(DOXYGEN))
struct rwPipeGlobals
{
RwFreeList *pipesFreeList; /* Save mallocs, use a freelist */
@@ -4695,24 +4343,12 @@ struct rwPipeGlobals
RxPipeline *genericWorldSectorPipeline;
RxPipeline *genericMaterialPipeline;
/* Platforms that have their own non-generic pipelines
- * (OPENGL, D3D7, SKY2, KAMUI2, DOLPHIN) put them here: */
+ * (OPENGL, D3D8, SKY2, KAMUI2, DOLPHIN) put them here: */
RxPipeline *platformAtomicPipeline;
RxPipeline *platformWorldSectorPipeline;
RxPipeline *platformMaterialPipeline;
-#if (defined(SKY2_DRVMODEL_H))
- /* We have extra flavours of pipe under SKY2.
- * PS2All and PS2AllMat are the defaults.
- * - see RpWorldSectorSkyGetPS2AllPipeline, etc */
- RxPipeline *ps2ManagerAtomicPipeline;
- RxPipeline *allInOneAtomicPipeline;
- RxPipeline *vanillaAtomicPipeline;
- RxPipeline *ps2ManagerWorldSectorPipeline;
- RxPipeline *allInOneWorldSectorPipeline;
- RxPipeline *vanillaWorldSectorPipeline;
- RxPipeline *vanillaMaterialPipeline;
-#endif /* (SKY2_DRVMODEL_H) */
-
};
+#endif /* (!defined(DOXYGEN)) */
typedef struct rwPipeGlobals rwPipeGlobals;
@@ -4740,9 +4376,7 @@ extern RwInt32 _rxPipelineGlobalsOffset;
/* Camera stream format */
/**
- * \ingroup datatypes
- * \typedef RwCameraChunkInfo
- *
+ * \ingroup rwcamera
* \ref RwCameraChunkInfo is typedef'd to a structure that holds camera
* data. This should be considered an opaque type. Use the RwCamera
* API functions to access it.
@@ -4750,6 +4384,8 @@ extern RwInt32 _rxPipelineGlobalsOffset;
typedef struct rwStreamCamera RwCameraChunkInfo;
typedef struct rwStreamCamera rwStreamCamera;
+
+#if (!defined(DOXYGEN))
struct rwStreamCamera
{
RwV2d viewWindow;
@@ -4758,6 +4394,7 @@ struct rwStreamCamera
RwReal fogPlane;
RwUInt32 projection;
};
+#endif /* (!defined(DOXYGEN)) */
/****************************************************************************
Function prototypes
diff --git a/sdk/rwsdk/include/d3d8/rwplcore.h b/sdk/rwsdk/include/d3d8/rwplcore.h
index b0ff7dfa..3740ae60 100644
--- a/sdk/rwsdk/include/d3d8/rwplcore.h
+++ b/sdk/rwsdk/include/d3d8/rwplcore.h
@@ -22,7 +22,7 @@
/*************************************************************************
*
* Filename: <C:/daily/rwsdk/include/d3d8/rwplcore.h>
- * Automatically Generated on: Wed Jul 10 10:45:00 2002
+ * Automatically Generated on: Thu Jan 23 11:06:23 2003
*
************************************************************************/
@@ -68,6 +68,7 @@ typedef struct _RwUInt64 RwUInt64;
typedef struct _RwInt64 RwInt64;
/* We'll do it with structures (can't do maths on these, but OK for allocation): */
+#if (!defined(DOXYGEN))
#ifdef rwBIGENDIAN
struct _RwUInt64
{
@@ -99,6 +100,7 @@ struct _RwInt64
#error "ENDIAN-ness undefined!"
#endif /* rwLITTLEENDIAN */
#endif /* rwBIGENDIAN */
+#endif /* (!defined(DOXYGEN)) */
#define RWZERO64 { (RwUInt32)0, (RwUInt32)0 }
#endif /* _MSC_VER */
@@ -108,7 +110,8 @@ typedef struct _RwInt128 RwInt128;
/* We'll do it with structures
* (can't do maths on these, but OK for allocation): */
-#ifdef rwBIGENDIAN
+#if (!defined(DOXYGEN))
+#ifdef rwBIGENDIAN
struct _RwUInt128
{
RwUInt64 top;
@@ -139,6 +142,7 @@ struct _RwInt128
#error "ENDIAN-ness undefined!"
#endif /* rwLITTLEENDIAN */
#endif /* rwBIGENDIAN */
+#endif /* (!defined(DOXYGEN)) */
#define RWZERO128 { RWZERO64, RWZERO64 }
@@ -160,6 +164,10 @@ struct _RwInt128
#define rwFRAMEALIGNMENT sizeof(RwUInt32)
#define rwV4DALIGNMENT sizeof(RwUInt32)
+#if (!defined(rwMALLOCALIGNMENT))
+#define rwMALLOCALIGNMENT sizeof(RwUInt32)
+#endif /* (!defined(rwMALLOCALIGNMENT) */
+
#if (defined(_MSC_VER))
#if (defined(RWVERBOSE))
@@ -501,7 +509,7 @@ int32fromreal(RwReal x)
#if (!defined(NOASM))
static __inline RwUInt32
-RwFastRealToUInt32(RwReal x)
+RwFastRealToUInt32Inline(RwReal x)
{
RwUInt32 res;
@@ -510,6 +518,9 @@ RwFastRealToUInt32(RwReal x)
return(res);
}
+
+#define RwFastRealToUInt32 RwFastRealToUInt32Inline
+
#endif /* (defined(NOASM)) */
#endif /* (defined(_MSC_VER)) */
@@ -627,11 +638,14 @@ do \
while(0)
typedef union _rwIEEEFloatShapeType _rwIEEEFloatShapeType;
+
+#if (!defined(DOXYGEN))
union _rwIEEEFloatShapeType
{
float value;
unsigned int word;
};
+#endif /* (!defined(DOXYGEN)) */
#define _RW_GET_FLOAT_WORD(i,d) \
do { \
@@ -949,13 +963,13 @@ while(0)
#if (!defined(rwSqrt))
/* NOTE: this is overloaded in drvmodel.h for some targets (SKY2 and XBOX atm)
* [we do in fact do overload w/ sqrtf there, if RW_USE_SPF,
- * for D3D7, D3D8, OpenGL and SoftRas] */
+ * for D3D8, OpenGL and SoftRas] */
#define rwSqrt(_result, _x) rwSqrtMacro(_result, _x)
#endif /* (!defined(rwSqrt)) */
#if (!defined(rwInvSqrt))
/* NOTE: this is overloaded in drvmodel.h for some targets (SKY2 and XBOX atm)
* [we do in fact do overload w/ (1 / sqrtf) there, if RW_USE_SPF,
- * for D3D7, D3D8, OpenGL and SoftRas] */
+ * for D3D8, OpenGL and SoftRas] */
#define rwInvSqrt(_recip, _x) rwInvSqrtMacro(_recip, _x)
#endif /* (!defined(rwInvSqrt)) */
#if (!defined(RwTan))
@@ -977,7 +991,22 @@ while(0)
/*--- Automatically derived from: C:/daily/rwsdk/src/plcore/batypes.h ---*/
#define rwLIBRARYBASEVERSION 0x31000
-#define rwLIBRARYCURRENTVERSION 0x33002
+#define rwLIBRARYCURRENTVERSION 0x34005
+
+#define rwLIBRARYVERSION31000 0x31000
+#if (rwLIBRARYVERSION31000 < rwLIBRARYBASEVERSION)
+#error "Time to remove all rwLIBRARYVERSION31000 code"
+#endif
+
+#define rwLIBRARYVERSION34001 0x34001
+#if (rwLIBRARYVERSION34001 < rwLIBRARYBASEVERSION)
+#error "Time to remove all rwLIBRARYVERSION34001 code"
+#endif
+
+#define rwLIBRARYVERSION34002 0x34002
+#if (rwLIBRARYVERSION34002 < rwLIBRARYBASEVERSION)
+#error "Time to remove all rwLIBRARYVERSION34002 code"
+#endif
/*
* RWBUILDNUMBER
@@ -993,14 +1022,16 @@ while(0)
* The following Doxygen comment MUST be copied into RwCore.h,
* so don't move it from here. */
+#ifndef RWADOXYGENEXTERNAL
/**
- * \ingroup rwcore
- * \page rwcoreoverview Core Library Overview
+ * \ingroup fundamentaltypes
+ * \page fundtypesoverview Fundamental Types Overview
*
- * LIBRARY: rwcore.lib
- * HEADER: rwcore.h
+ * \par Requirements
+ * \li \b Headers: rwcore.h
+ * \li \b Libraries: rwcore.lib
*
- * This library provides the fundamental RenderWare features.
+ * The rwcore.lib library provides the fundamental RenderWare features.
*
* When creating a RenderWare application, this library must always be
* linked.
@@ -1024,7 +1055,7 @@ while(0)
* supplied User Guide. The RenderWare Engine \ref rwengine API is
* usually the starting point for new developers.
*/
-
+#endif /* RWADOXYGENEXTERNAL */
#if (!defined(RWFORCEENUMSIZEINT))
#define RWFORCEENUMSIZEINT ((RwInt32)((~((RwUInt32)0))>>1))
@@ -1157,7 +1188,6 @@ while(0)
#if (defined(RWDEBUG) && defined(RWVERBOSE))
-/* #include <windows.h> */
#if (defined(RWMEMDEBUG) && !defined(_CRTDBG_MAP_ALLOC))
#define _CRTDBG_MAP_ALLOC
#endif /* defined(RWMEMDEBUG) && !defined(_CRTDBG_MAP_ALLOC)) */
@@ -1189,6 +1219,8 @@ while(0)
/* NB volatile keyword required for VC5.0 to ensure a reload - AMB */
typedef union RwSplitBits RwSplitBits;
+
+#if (!defined(DOXYGEN))
union RwSplitBits
{
RwReal nReal;
@@ -1219,6 +1251,7 @@ struct RwSplitFixed
#endif /* rwBIGENDIAN */
typedef union RwUnionReal RwUnionReal;
+
union RwUnionReal /* MSB is sign bit in any circumstance */
{
RwReal real; /* 4 bytes interpreted as RwReal */
@@ -1226,6 +1259,7 @@ union RwUnionReal /* MSB is sign bit in any circumstance */
RwFixed fixed; /* 4 bytes interpreted as 16:16 fixed */
RwSplitFixed splitfixed; /* 4 bytes interpreted as 16:16 fixed */
};
+#endif /* (!defined(DOXYGEN)) */
/*****************/
@@ -1233,14 +1267,9 @@ union RwUnionReal /* MSB is sign bit in any circumstance */
/*****************/
-/**
- * \ingroup datatypes
- * \typedef RwV2d
- * typedef for struct RwV2d
- */
typedef struct RwV2d RwV2d;
/**
- * \ingroup datatypes
+ * \ingroup rwv2d
* \struct RwV2d
* This type represents points in a 2D space, such as device
* space, specified by the (x, y) coordinates of the point.
@@ -1251,14 +1280,9 @@ struct RwV2d
RwReal y; /**< Y vlaue */
};
-/**
- * \ingroup datatypes
- * \typedef RwV3d
- * typedef for struct RwV3d
- */
typedef struct RwV3d RwV3d;
/**
- * \ingroup datatypes
+ * \ingroup rwv3d
* \struct RwV3d
* This type represents 3D points and vectors specified by
* the (x, y, z) coordinates of a 3D point or the (x, y, z) components of a
@@ -1274,13 +1298,16 @@ struct RwV3d
#define RWV4DALIGNMENT(_v4d) \
(! (((rwV4DALIGNMENT)-1) & ((RwUInt32)(_v4d))))
+#ifndef RWADOXYGENEXTERNAL
/**
- * \ingroup datatypes
+ * \ingroup rwv4d
* \struct RwV4d
* This type represents 4D points and vectors specified by
* the (x, y, z, w) coordinates of a 4D point or the (x, y, z, w) components of a
* 4D vector.
*/
+#endif /* RWADOXYGENEXTERNAL */
+
struct RwV4d
{
RwReal x; /**< X value */
@@ -1289,27 +1316,21 @@ struct RwV4d
RwReal w; /**< W value */
};
-/**
- * \ingroup datatypes
- * \typedef RwV4d
- * typedef for struct RwV4d
- */
typedef struct RwV4d RWALIGN(RwV4d, rwV4DALIGNMENT);
-/**
- * \ingroup datatypes
- * \typedef RwRect
- * typedef for struct RwRect
- */
typedef struct RwRect RwRect;
+
+#ifndef RWADOXYGENEXTERNAL
/**
- * \ingroup datatypes
+ * \ingroup geometricaltypes
* \struct RwRect
* This type represents a 2D device space rectangle specified
* by the position of the top-left corner (the offset x, y) and its width (w)
* and height (h).
*/
+#endif /* RWADOXYGENEXTERNAL */
+
struct RwRect
{
RwInt32 x; /**< X value of the top-left corner */
@@ -1318,18 +1339,15 @@ struct RwRect
RwInt32 h; /**< Height of the rectangle */
};
-/**
- * \ingroup datatypes
- * \typedef RwSphere
- * typedef for struct RwSphere
- */
typedef struct RwSphere RwSphere;
+#ifndef RWADOXYGENEXTERNAL
/**
- * \ingroup datatypes
+ * \ingroup geometricaltypes
* \struct RwSphere
* This type represents a sphere specified by the position
* of its center and its radius
*/
+#endif /* RWADOXYGENEXTERNAL */
struct RwSphere
{
RwV3d center; /**< Sphere center */
@@ -1341,18 +1359,16 @@ struct RwSphere
( *(_target) = *(_source) )
#endif /* (!defined(RwSphereAssign)) */
-/**
- * \ingroup datatypes
- * \typedef RwLine
- * typedef for struct RwLine
- */
typedef struct RwLine RwLine;
+
+#ifndef RWADOXYGENEXTERNAL
/**
- * \ingroup datatypes
+ * \ingroup geometricaltypes
* \struct RwLine
* This type represents a 3D line specified by the position
* of its start and end points.
*/
+#endif /* RWADOXYGENEXTERNAL */
struct RwLine
{
RwV3d start; /**< Line start */
@@ -1367,11 +1383,13 @@ struct RwLine
/* The maximum number of texture coordinates */
#define rwMAXTEXTURECOORDS 8
+#ifndef RWADOXYGENEXTERNAL
/**
- * \ingroup datatypes
+ * \ingroup fundtypesdatatypes
* RwTextureCoordinateIndex
* This type represents the index for texture coordinates.
*/
+#endif /* RWADOXYGENEXTERNAL */
enum RwTextureCoordinateIndex
{
rwNARWTEXTURECOORDINATEINDEX = 0,
@@ -1387,18 +1405,16 @@ enum RwTextureCoordinateIndex
};
typedef enum RwTextureCoordinateIndex RwTextureCoordinateIndex;
-/**
- * \ingroup datatypes
- * \typedef RwTexCoords
- * typedef for struct RwTexCoords
- */
typedef struct RwTexCoords RwTexCoords;
+
+#ifndef RWADOXYGENEXTERNAL
/**
- * \ingroup datatypes
+ * \ingroup fundtypesdatatypes
* \struct RwTexCoords
* This type represents the the u and v texture
* coordinates of a particular vertex.
*/
+#endif /* RWADOXYGENEXTERNAL */
struct RwTexCoords
{
RwReal u; /**< U value */
@@ -1409,10 +1425,13 @@ struct RwTexCoords
/* Singley linked list macros. End marked as NULL */
typedef struct RwSLLink RwSLLink; /*** RwSLLink ***/
+
+#if (!defined(DOXYGEN))
struct RwSLLink
{
RwSLLink *next;
};
+#endif /* (!defined(DOXYGEN)) */
#define rwSLLinkGetData(link,type,entry) \
((type *)(((RwUInt8 *)(link))-offsetof(type,entry)))
@@ -1427,10 +1446,13 @@ struct RwSLLink
((linkvar)->next)
typedef struct RwSingleList RwSingleList;
+
+#if (!defined(DOXYGEN))
struct RwSingleList
{
RwSLLink link;
};
+#endif /* (!defined(DOXYGEN)) */
#define rwSingleListInitialize(list) \
(list)->link.next= NULL;
@@ -1446,11 +1468,14 @@ struct RwSingleList
/* Doubly linked list. End marked as start (its a ring) */
typedef struct RwLLLink RwLLLink; /*** RwLLLink ***/
+
+#if (!defined(DOXYGEN))
struct RwLLLink
{
RwLLLink *next;
RwLLLink *prev;
};
+#endif /* (!defined(DOXYGEN)) */
#define rwLLLinkGetData(linkvar,type,entry) \
((type *)(((RwUInt8 *)(linkvar))-offsetof(type,entry)))
@@ -1472,10 +1497,13 @@ struct RwLLLink
((linkvar)->next)
typedef struct RwLinkList RwLinkList;
+
+#if (!defined(DOXYGEN))
struct RwLinkList
{
RwLLLink link;
};
+#endif /* (!defined(DOXYGEN)) */
#define rwLinkListInitialize(list) \
( (list)->link.next = ((RwLLLink *)(list)), \
@@ -1497,19 +1525,17 @@ struct RwLinkList
#define rwLinkListGetTerminator(list) \
(&((list)->link))
-/**
- * \ingroup datatypes
- * \typedef RwSurfaceProperties
- * typedef for struct RwSurfaceProperties
- */
typedef struct RwSurfaceProperties RwSurfaceProperties;
+
+#ifndef RWADOXYGENEXTERNAL
/**
- * \ingroup datatypes
+ * \ingroup fundtypesdatatypes
* \struct RwSurfaceProperties
* This type represents the ambient, diffuse and
* specular reflection coefficients of a particular geometry. Each coefficient
* is specified in the range 0.0 (no reflection) to 1.0 (maximum reflection).
*/
+#endif /* RWADOXYGENEXTERNAL */
struct RwSurfaceProperties
{
RwReal ambient; /**< ambient reflection coefficient */
@@ -1541,10 +1567,10 @@ struct RwSurfaceProperties
*/
#define RWFIX_MIN (1)
#define RWFIX_MAX (0x7fffffff)
-#define RwFixedCast(A) (RwInt32FromRealMacro((A) * 65536.0f))
-#define RwFixedToInt(A) ((A) >> 16)
-#define RwFixedToFloat(A) ((float)(((float)(A)) * (1.0f / 65536.0f)))
+#define RwFixedToInt(a) ((a) >> 16)
+#define RwFixedToFloat(a) ((float)(((float)(a)) * (1.0f / 65536.0f)))
#define RwFixedToReal(a) ((RwReal)(((RwReal)(a)) * (1.0f / 65536.0f)))
+#define RwIntToFixed(a) ((a) << 16)
#define RwRealToFixed(a) (RwInt32FromRealMacro((a) * 65536.0f))
#define RwRealAbs(a) ((RwReal)((a) >= (RwReal)(0.0) ? (a) : (-(a))))
#define RwRealMin2(a,b) ((RwReal)( ((a) <= (b)) ? (a) : (b)))
@@ -1555,7 +1581,6 @@ struct RwSurfaceProperties
#ifndef NORWREALSHORTCUT
#define RToFixed RwRealToFixed
#define RAbs RwRealAbs
-#define FxCast RwFixedCast
#define FxToInt RwFixedToInt
#define FxToFloat RwFixedToFloat
#define FxToReal RwFixedToFloat
@@ -1580,6 +1605,8 @@ struct RwSurfaceProperties
* typedef for struct RwPlane
*/
typedef struct RwPlane RwPlane;
+
+#if (!defined(DOXYGEN))
/*
* This type represents a plane
*/
@@ -1588,7 +1615,7 @@ struct RwPlane
RwV3d normal; /**< Normal to the plane */
RwReal distance; /**< Distance to plane from origin in normal direction*/
};
-
+#endif /* (!defined(DOXYGEN)) */
/****************************************************************************
Defines
@@ -1613,7 +1640,7 @@ typedef enum RwPlaneType RwPlaneType;
(*(const RwReal *)(((const RwUInt8 *)(&((vect).x)))+(RwInt32)(y)))
#define SETCOORD(vect,y,value) \
(((*(RwReal *)(((RwUInt8 *)(&((vect).x)))+(RwInt32)(y))))=(value))
-#define SETCONTCOORD(vect,y,value) \
+#define SETCONSTCOORD(vect,y,value) \
(((*(const RwReal *) \
(((const RwUInt8 *) \
(&((vect).x)))+(RwInt32)(y))))=(value))
@@ -1624,7 +1651,7 @@ typedef enum RwPlaneType RwPlaneType;
/**
- * \ingroup rwcore
+ * \ingroup integertypes
* \page inttypes Integer Types
*
* RenderWare supports a number of integer types:
@@ -1661,7 +1688,7 @@ typedef enum RwPlaneType RwPlaneType;
*/
/**
- * \ingroup datatypes
+ * \ingroup realtypes
* \typedef RwReal
*
* RenderWare supports a single RwReal floating-point type to aid portability
@@ -1683,7 +1710,7 @@ typedef enum RwPlaneType RwPlaneType;
*/
/**
- * \ingroup datatypes
+ * \ingroup realtypes
* \typedef RwFixed
*
* RenderWare supports a single RwFixed fixed-point type.
@@ -1696,15 +1723,15 @@ typedef enum RwPlaneType RwPlaneType;
* RWFIX_MAX and RWFIX_MIN respectively.
*
* The following macros are provided to help you work with RwFixed datatypes:
- * \li RwFixedCast(x) Cast the integer portion of an RwFixed to another type.
* \li RwFixedToInt(x) Convert an RwFixed to an integer. (The fractional portion is lost.)
* \li RwFixedToFloat(x) Convert an RwFixed to a float.
* \li RwFixedToReal(x) Convert an RwFixed to an RwReal.
* \li RwRealToFixed(x) Convert an RwReal to an RwFixed. (Some precision may be lost.)
+ * \li RwIntToFixed(x) Convert an RwInt32 to an RwFixed. (Some precision may be lost.)
*/
/**
- * \ingroup datatypes
+ * \ingroup integertypes
* \typedef RwInt8
*
* Signed 8 bit integer type.
@@ -1712,7 +1739,7 @@ typedef enum RwPlaneType RwPlaneType;
*/
/**
- * \ingroup datatypes
+ * \ingroup integertypes
* \typedef RwUInt8
*
* Unsigned 8bit integer type.
@@ -1720,7 +1747,7 @@ typedef enum RwPlaneType RwPlaneType;
*/
/**
- * \ingroup datatypes
+ * \ingroup integertypes
* \typedef RwChar
*
* Character type.
@@ -1728,7 +1755,7 @@ typedef enum RwPlaneType RwPlaneType;
*/
/**
- * \ingroup datatypes
+ * \ingroup integertypes
* \typedef RwInt16
*
* Signed 16 bit integer type.
@@ -1736,7 +1763,7 @@ typedef enum RwPlaneType RwPlaneType;
*/
/**
- * \ingroup datatypes
+ * \ingroup integertypes
* \typedef RwUInt16
*
* Unsigned 16 bit integer type.
@@ -1744,7 +1771,7 @@ typedef enum RwPlaneType RwPlaneType;
*/
/**
- * \ingroup datatypes
+ * \ingroup integertypes
* \typedef RwInt32
*
* Signed 32 bit integer type.
@@ -1752,7 +1779,7 @@ typedef enum RwPlaneType RwPlaneType;
*/
/**
- * \ingroup datatypes
+ * \ingroup integertypes
* \typedef RwUInt32
*
* Unsigned 32 bit integer type.
@@ -1760,7 +1787,7 @@ typedef enum RwPlaneType RwPlaneType;
*/
/**
- * \ingroup datatypes
+ * \ingroup integertypes
* \typedef RwInt64
*
* Signed 64 bit integer type.
@@ -1768,7 +1795,7 @@ typedef enum RwPlaneType RwPlaneType;
*/
/**
- * \ingroup datatypes
+ * \ingroup integertypes
* \typedef RwUInt64
*
* Unsigned 64 bit integer type.
@@ -1776,7 +1803,7 @@ typedef enum RwPlaneType RwPlaneType;
*/
/**
- * \ingroup datatypes
+ * \ingroup integertypes
* \typedef RwInt128
*
* Signed 128 bit integer type.
@@ -1784,7 +1811,7 @@ typedef enum RwPlaneType RwPlaneType;
*/
/**
- * \ingroup datatypes
+ * \ingroup integertypes
* \typedef RwUInt128
*
* Unsigned 128 bit integer type.
@@ -1792,7 +1819,7 @@ typedef enum RwPlaneType RwPlaneType;
*/
/**
- * \ingroup datatypes
+ * \ingroup integertypes
* \typedef RwBool
*
* Boolean type.
@@ -1894,8 +1921,10 @@ enum RwCorePluginID
rwID_PITEXDICTIONARY = 0x23,
rwID_TOC = 0x24,
rwID_PRTSTDGLOBALDATA = 0x25,
+ rwID_ALTPIPE = 0x26,
+ rwID_PIPEDS = 0x27,
/* Insert before MAX and increment MAX */
- rwID_COREPLUGINIDMAX = 0x26,
+ rwID_COREPLUGINIDMAX = 0x28,
rwCOREPLUGINIDFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
};
typedef enum RwCorePluginID RwCorePluginID ;
@@ -1944,12 +1973,15 @@ typedef enum RwPlatformID RwPlatformID;
*/
typedef struct RwObject RwObject;
+#ifndef RWADOXYGENEXTERNAL
/**
- * \ingroup datatypes
+ * \ingroup rwobject
* \struct RwObject
* This should be considered an opaque type. Use
* the RwObject API functions to access.
*/
+#endif /* RWADOXYGENEXTERNAL */
+
struct RwObject
{
RwUInt8 type; /**< Internal Use */
@@ -1960,20 +1992,23 @@ struct RwObject
/* Often a Frame */
};
+#ifndef RWADOXYGENEXTERNAL
/**
- * \ingroup datatypes
- * \typedef RwObjectCallBack
+ * \ingroup rwobject
+ * \ref RwObjectCallBack
* callback function supplied for object callback functions.
*
- * \return Pointer to the current object
- *
* \param object Pointer to the current object, supplied by
- * iterator.
- * \param data Pointer to developer-defined data structure.
+ * iterator.
+ * \param data Pointer to developer-defined data structure.
+ *
+ * \return Pointer to the current object
*
* \see RwFrameForAllObjects
*
*/
+#endif /* RWADOXYGENEXTERNAL */
+
typedef RwObject *(*RwObjectCallBack)(RwObject *object, void *data);
/****************************************************************************
@@ -2128,6 +2163,8 @@ typedef int (*vecSscanfFunc)(const RwChar *buffer,
...) /* __RWFORMAT__(scanf, 2, 3) */;
typedef struct RwStringFunctions RwStringFunctions;
+
+#if (!defined(DOXYGEN))
struct RwStringFunctions
{
vecSprintfFunc vecSprintf ;
@@ -2147,6 +2184,7 @@ struct RwStringFunctions
vecStrtokFunc vecStrtok;
vecSscanfFunc vecSscanf;
};
+#endif /* (!defined(DOXYGEN)) */
/*--- Automatically derived from: C:/daily/rwsdk/src/plcore/rwdbgerr.h ---*/
@@ -2203,32 +2241,32 @@ typedef enum RwErrorCodePlugin_errcore RwErrorCodePlugin_errcore;
#endif /* (!defined(rwFREELISTCLEANLANDFILL)) */
#define RWFREELISTALIGNED(_pData, _freelist) \
- (! (((RwUInt32)(_pData)) & ((_freelist)->alignmentMinusOne)) )
+ (! (((RwUInt32)(_pData)) & ((_freelist)->alignment - 1)) )
/*****************************
* REGULAR MEMORY ALLOCATION *
*****************************/
/**
- * \ingroup rwmem
+ * \ingroup memoryfileinterface
* \def RwMalloc
* RwMalloc(_s) is a macro for malloc(_s).
*/
/**
- * \ingroup rwmem
+ * \ingroup memoryfileinterface
* \def RwFree
* RwFree(_p) is a macro for free(_p).
*/
/**
- * \ingroup rwmem
+ * \ingroup memoryfileinterface
* \def RwCalloc
* RwCalloc(_n, _s) is a macro for calloc(_n, _s).
*/
/**
- * \ingroup rwmem
+ * \ingroup memoryfileinterface
* \def RwRealloc
* RwRealloc(_p, _s) is a macro for realloc(_p, _s).
*/
@@ -2252,8 +2290,6 @@ typedef enum RwErrorCodePlugin_errcore RwErrorCodePlugin_errcore;
# if (defined(_MSC_VER))
# if ((_MSC_VER>=1000) && defined(_DEBUG))
-/* Pick up _ASSERTE() macro */
-/* #include <windows.h> */
#if (defined(RWMEMDEBUG) && !defined(_CRTDBG_MAP_ALLOC))
#define _CRTDBG_MAP_ALLOC
#endif /* defined(RWMEMDEBUG) && !defined(_CRTDBG_MAP_ALLOC)) */
@@ -2556,12 +2592,12 @@ typedef enum RwErrorCodePlugin_errcore RwErrorCodePlugin_errcore;
typedef struct RwMemoryFunctions RwMemoryFunctions;
/**
- * \ingroup datatypes
+ * \ingroup memoryfileinterface
* \struct RwMemoryFunctions
* This type represents the memory functions used
* by RenderWare. By default, the standard ANSI functions are used. The
* application may install an alternative interface providing that it is ANSI
- * compliant (see API function \ref RwEngineInit):
+ * compliant (in RenderWare Graphics see API function RwEngineInit):
*/
struct RwMemoryFunctions
{
@@ -2574,60 +2610,44 @@ struct RwMemoryFunctions
void *(*rwcalloc)(size_t numObj, size_t sizeObj); /**< calloc calloc */
};
-typedef struct RwFreeBlock RwFreeBlock;
-/*
- * Freelists -- from Page 131
- * Advanced Animation and Rendering Techniques
- * Alan Watt and Mark Watt
- * Addison-Wesley 1993,
- * ISBN 0-201-54412-1:
+ /**
+ * \ingroup rwfreelist
+ * The free list was statically allocated
*
- * "Lastly, on a more general note concerning speedups for renderers, the
- * implementor should be aware that a lot of suggestions for improving
- * efficiency fall into the category of ingenious, but complex,
- * algorithms for very specific contexts that may save a few microseconds
- * but which make your code unreadable. A more general computer science
- * perspective that takes a `global view' of the renderer can be more
- * fruitful. For example, the renderer devotes a lot of time to
- * allocating and deallocating chunks of memory for storing data. A lot
- * of these chunks are always the same size - such as those that are
- * continually required to store the data structure for fragment lists.
- * Using memory management techniques that recognize this fact can yield
- * considerable dividends. One such scheme would be to hold a series of
- * empty lists in memory for all the commonly used data structures. An
- * empty list for fragments, say, would contain a list of previously
- * allocated, but no longer needed, fragment structures. When the
- * renderer needs memory for a new fragment, it looks first at this empty
- * list. If there is nothing there it allocates space directly,
- * otherwise it takes a fragments off the end of the list and uses that.
- * Conversely, when the renderer no longer needs a fragment, instead of
- * freeing it, it goes onto the end of the empty list. In the authors'
- * experience, replacing the naive allocate/deallocate scheme with this
- * way of managing memory can result in 100% speedup. "
- */
-struct RwFreeBlock
-{
- RwFreeBlock *nextBlock;
-};
-
-typedef struct RwFreeList RwFreeList;
-struct RwFreeList
-{
- void **freeListStack; /* Stack of unused entries */
- void **freeListStackTop; /* Pointer to the top of the stack */
+ * \see RwFreeListSetFlags
+ */
+#define rwFREELISTFLAG_STATIC 0x00000001
- RwFreeBlock *firstBlock; /* Data start */
+/**
+ * \ingroup rwfreelist
+ * \hideinitializer
+ * Free blocks as soon as they are empty
+ *
+ * \see RwFreeListSetFlags
+ */
+#define rwFREELISTFLAG_FREEBLOCKS 0x00000002
- RwInt32 blockSize; /* Size of block in bytes */
- RwInt32 entrySize; /* Entry size */
- RwInt32 alignmentMinusOne; /* Entry alignment minus 1 */
- RwInt32 entriesPerBlock; /* Amount of space in a block */
- RwInt32 entriesAllocated; /* Total slots allocated
- * (but not necessarily being used */
+typedef struct RwFreeList RwFreeList;
- /* All freelists */
- RwLLLink lFreeList;
+/**
+ * \ingroup rwfreelist
+ * Holds free list info, should be considered opaque. Use API functions to access.
+ */
+struct RwFreeList
+{
+ RwUInt32 entrySize; /**<size of an entry in the free list */
+#if (defined(RWDEBUG) && !defined(DOXYGEN))
+ RwUInt32 nonAlignedEntrySize;
+#endif /* (defined(RWDEBUG) && !defined(DOXYGEN)) */
+ RwUInt32 entriesPerBlock; /**<number of entries per free list block */
+ RwUInt32 heapSize; /**<size of the heap */
+ RwUInt32 alignment; /**<alignment of a free list entry */
+ RwLinkList blockList; /**<list of data blocks */
+ RwUInt32 flags; /**<flags which affect the behavior of the
+ free list <BR>
+ rwFREELISTFLAG_FREEBLOCKS */
+ RwLLLink link; /**<link to the free list linked list */
#if (defined(RWDEBUG) && !defined(DOXYGEN))
const RwChar *fileCreate;
@@ -2635,8 +2655,9 @@ struct RwFreeList
#endif /* (defined(RWDEBUG) && !defined(DOXYGEN)) */
};
+#ifndef RWADOXYGENEXTERNAL
/**
- * \ingroup datatypes
+ * \ingroup rwfreelist
* \ref RwFreeListCallBack represents
* the function called from \ref RwFreeListForAllUsed for all used entries in a
* given free list.
@@ -2648,6 +2669,8 @@ struct RwFreeList
* \see RwFreeListForAllUsed
*
*/
+#endif /* RWADOXYGENEXTERNAL */
+
typedef void (*RwFreeListCallBack) (void *pMem, void *pData);
typedef void *(*RwMemoryAllocFn) (RwFreeList * fl);
typedef RwFreeList *(*RwMemoryFreeFn) (RwFreeList * fl, void *pData);
@@ -2684,12 +2707,25 @@ extern RwFreeList *_rwFreeListCreate(RwInt32 entrySize,
__LINE__)
#else /* (defined(RWDEBUG) && !defined(DOXYGEN)) */
+/* legacy freelist create */
+
extern RwFreeList *RwFreeListCreate(RwInt32 entrySize,
RwInt32 entriesPerBlock,
RwInt32 alignment);
#endif /* (defined(RWDEBUG) && !defined(DOXYGEN)) */
+extern RwFreeList*
+RwFreeListCreateAndPreallocateSpace(RwInt32 entrySize,
+ RwInt32 entriesPerBlock,
+ RwInt32 alignment,
+ RwInt32 numBlocksToPreallocate,
+ RwFreeList *inPlaceSpaceForFreeListStruct );
+
extern RwBool RwFreeListDestroy(RwFreeList * freelist);
+
+extern void RwFreeListSetFlags( RwFreeList *freeList, RwUInt32 flags );
+extern RwUInt32 RwFreeListGetFlags( RwFreeList *freeList );
+
/* Garbage collection/enumeration */
extern RwInt32 RwFreeListPurge(RwFreeList * freelist);
extern RwFreeList *RwFreeListForAllUsed(RwFreeList * freelist,
@@ -2712,7 +2748,7 @@ extern RwInt32 RwFreeListPurgeAllFreeLists(void);
#include <rtdbmalloc.h>
#define RwFreeListAlloc(_f) \
- memalign((1 + (_f)->alignmentMinusOne), (_f)->entrySize)
+ memalign(((_f)->alignment), (_f)->entrySize)
#else /* ((defined(__MWERKS__) || defined(__GNUC__)) && defined(__R5900__)) */
@@ -2750,7 +2786,7 @@ extern RwInt32 RwFreeListPurgeAllFreeLists(void);
*/
/**
- * \ingroup datatypes
+ * \ingroup rwstream
* \ref RwStreamType
* This type represents the different types of stream that
* can be used.
@@ -2768,7 +2804,7 @@ enum RwStreamType
typedef enum RwStreamType RwStreamType;
/**
- * \ingroup datatypes
+ * \ingroup rwstream
* \ref RwStreamAccessType
* This type represents the options available for
* accessing a stream when it is opened.
@@ -2785,8 +2821,8 @@ typedef enum RwStreamAccessType RwStreamAccessType;
/* Memory stream */
/**
- * \ingroup datatypes
- * \typedef RwStreamMemory
+ * \ingroup rwstream
+ * \struct RwStreamMemory
* This should be considered an opaque type.
* Use the RwStream API functions to access.
*/
@@ -2803,7 +2839,7 @@ struct RwStreamMemory
typedef union RwStreamFile RwStreamFile;
/**
- * \ingroup datatypes
+ * \ingroup rwstream
* \union RwStreamFile
* This type is used to represent a file pointer for
* accessing data on disk through the stream mechanism.
@@ -2829,8 +2865,8 @@ typedef RwBool(*rwCustomStreamFnSkip) (void *data,
/* Custom stream */
/**
- * \ingroup datatypes
- * \typedef RwStreamCustom
+ * \ingroup rwstream
+ * \struct RwStreamCustom
* This should be considered an opaque type.
* Use the RwStream API functions to access.
*/
@@ -2850,7 +2886,7 @@ struct RwStreamCustom
typedef union RwStreamUnion RwStreamUnion;
/**
- * \ingroup datatypes
+ * \ingroup rwstream
* \union RwStreamUnion
* The union of all supported stream types
*/
@@ -2862,8 +2898,8 @@ union RwStreamUnion
};
/**
- * \ingroup datatypes
- * \typedef RwStream
+ * \ingroup rwstream
+ * \struct RwStream
* Binary stream for reading or writing object data.
* This should be considered an opaque type.
* Use the RwStream API functions to access.
@@ -2883,7 +2919,7 @@ struct RwStream
typedef struct RwMemory RwMemory;
/**
- * \ingroup datatypes
+ * \ingroup rwstream
* \struct RwMemory
* This type represents a block of allocated memory.
* It is used to specify an area of memory connected to a stream of type
@@ -2905,6 +2941,9 @@ extern "C"
{
#endif /* __cplusplus */
+extern void
+RwStreamSetFreeListCreateParams( RwInt32 blockSize, RwInt32 numBlocksToPrealloc );
+
/* Open/Close streams */
extern RwStream *
@@ -2953,8 +2992,9 @@ RwStreamSkip(RwStream * stream,
Global Types
*/
+#ifndef RWADOXYGENEXTERNAL
/**
- * \ingroup datatypes
+ * \ingroup rwplugin
* \ref RwPluginDataChunkWriteCallBack represents the function
* registered by \ref RwCameraRegisterPluginStream, etc. as the function that
* writes extension data to a binary stream.
@@ -2979,7 +3019,7 @@ RwStreamSkip(RwStream * stream,
typedef RwStream *(*RwPluginDataChunkWriteCallBack)(RwStream *stream, RwInt32 binaryLength, const void *object, RwInt32 offsetInObject, RwInt32 sizeInObject);
/**
- * \ingroup datatypes
+ * \ingroup rwplugin
* \ref RwPluginDataChunkReadCallBack represents the function
* registered by \ref RwCameraRegisterPluginStream, etc. as the function that
* reads extension data from a binary stream.
@@ -3004,7 +3044,7 @@ typedef RwStream *(*RwPluginDataChunkWriteCallBack)(RwStream *stream, RwInt32 bi
typedef RwStream *(*RwPluginDataChunkReadCallBack)(RwStream *stream, RwInt32 binaryLength, void *object, RwInt32 offsetInObject, RwInt32 sizeInObject);
/**
- * \ingroup datatypes
+ * \ingroup rwplugin
* \ref RwPluginDataChunkGetSizeCallBack represents the callback
* registered by \ref RwCameraRegisterPluginStream, etc. as the function that
* determines the binary size of the extension data.
@@ -3022,7 +3062,7 @@ typedef RwStream *(*RwPluginDataChunkReadCallBack)(RwStream *stream, RwInt32 bin
typedef RwInt32(*RwPluginDataChunkGetSizeCallBack)(const void *object, RwInt32 offsetInObject, RwInt32 sizeInObject);
/**
- * \ingroup datatypes
+ * \ingroup rwplugin
* \ref RwPluginDataChunkAlwaysCallBack represents the callback
* registered by \ref RwCameraSetStreamAlwaysCallBack, etc. as the
* function that is called after the reading of plugin stream data is
@@ -3037,11 +3077,13 @@ typedef RwInt32(*RwPluginDataChunkGetSizeCallBack)(const void *object, RwInt32 o
*
* \param sizeInObject A RwInt32 value equal to the size
* (in bytes) of the extension data.
+ *
+ * \return Returns TRUE if successful, FALSE otherwise.
*/
typedef RwBool(*RwPluginDataChunkAlwaysCallBack)(void *object, RwInt32 offsetInObject, RwInt32 sizeInObject);
/**
- * \ingroup datatypes
+ * \ingroup rwplugin
* \ref RwPluginDataChunkRightsCallBack represents the callback
* registered by RwCameraSetStreamRightsCallBack, etc. as the
* function that is called after the reading of plugin stream data is
@@ -3058,11 +3100,13 @@ typedef RwBool(*RwPluginDataChunkAlwaysCallBack)(void *object, RwInt32 offsetInO
* (in bytes) of the extension data.
*
* \param extraData An RwUInt32 writen with the plugin id.
+ *
+ * \return Returns TRUE if successful, FALSE otherwise.
*/
typedef RwBool(*RwPluginDataChunkRightsCallBack)(void *object, RwInt32 offsetInObject, RwInt32 sizeInObject, RwUInt32 extraData);
/**
- * \ingroup datatypes
+ * \ingroup rwplugin
* \ref RwPluginObjectConstructor represents the callback
* registered by \ref RwEngineRegisterPlugin, \ref RwCameraRegisterPlugin, etc.
* as the function that initializes either the global extension data (in the
@@ -3083,7 +3127,7 @@ typedef RwBool(*RwPluginDataChunkRightsCallBack)(void *object, RwInt32 offsetInO
typedef void *(*RwPluginObjectConstructor)(void *object, RwInt32 offsetInObject, RwInt32 sizeInObject);
/**
- * \ingroup datatypes
+ * \ingroup rwplugin
* \ref RwPluginObjectCopy represents the callback registered by
* \ref RwCameraRegisterPlugin, etc. as the function that copies the object
* extension data when an object is duplicated.
@@ -3105,7 +3149,7 @@ typedef void *(*RwPluginObjectConstructor)(void *object, RwInt32 offsetInObject,
typedef void *(*RwPluginObjectCopy)(void *dstObject, const void *srcObject, RwInt32 offsetInObject, RwInt32 sizeInObject);
/**
- * \ingroup datatypes
+ * \ingroup rwplugin
* \ref RwPluginObjectDestructor represents the callback registered
* by \ref RwEngineRegisterPlugin, \ref RwCameraRegisterPlugin, etc. as the
* function that destroys either the global extension data (in the case of
@@ -3123,6 +3167,8 @@ typedef void *(*RwPluginObjectCopy)(void *dstObject, const void *srcObject, RwIn
*
* \return Pointer to the object.
*/
+#endif /* RWADOXYGENEXTERNAL */
+
typedef void *(*RwPluginObjectDestructor)(void *object, RwInt32 offsetInObject, RwInt32 sizeInObject);
typedef void *(*RwPluginErrorStrCallBack)(void *);
@@ -3130,6 +3176,7 @@ typedef void *(*RwPluginErrorStrCallBack)(void *);
typedef struct RwPluginRegistry RwPluginRegistry;
typedef struct RwPluginRegEntry RwPluginRegEntry;
+#if (!defined(DOXYGEN))
struct RwPluginRegistry
{
RwInt32 sizeOfStruct;
@@ -3158,6 +3205,7 @@ struct RwPluginRegEntry
RwPluginRegEntry *prevRegEntry;
RwPluginRegistry *parentRegistry;
};
+#endif /* (!defined(DOXYGEN)) */
@@ -3172,6 +3220,9 @@ extern "C"
/* Registering toolkits and allocating memory */
+extern void
+RwPluginRegistrySetFreeListCreateParams( RwInt32 blockSize, RwInt32 numBlocksToPrealloc );
+
extern RwBool
_rwPluginRegistrySetStaticPluginsSize(RwPluginRegistry * reg,
RwInt32 size);
@@ -3355,14 +3406,17 @@ MACRO_STOP
#define RWMATRIXPRINT(_matrix) /* No op */
#endif /* (!(defined(RWMATRIXPRINT))) */
+#ifndef RWADOXYGENEXTERNAL
/**
- * \ingroup datatypes
+ * \ingroup rwmatrix
* enum RwOpCombineType
* This type represents a combination operator which
* can be applied to frames and matrices.
* The operator determines the order
* in which one object is combined with another
*/
+#endif /* RWADOXYGENEXTERNAL */
+
enum RwOpCombineType
{
rwCOMBINEREPLACE = 0, /**<Replace -
@@ -3376,9 +3430,8 @@ enum RwOpCombineType
rwOPCOMBINETYPEFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
};
-/**
- * \ingroup datatypes
- * \typedef RwOpCombineType typedef for enum RwOpCombineType
+/*
+ * RwOpCombineType typedef for enum RwOpCombineType
*/
typedef enum RwOpCombineType RwOpCombineType;
@@ -3388,7 +3441,7 @@ typedef enum RwOpCombineType RwOpCombineType;
enum RwMatrixType
{
rwMATRIXTYPENORMAL = 0x00000001,
- rwMATRIXTYPEORTHOGANAL = 0x00000002,
+ rwMATRIXTYPEORTHOGONAL = 0x00000002,
rwMATRIXTYPEORTHONORMAL = 0x00000003,
rwMATRIXTYPEMASK = 0x00000003,
rwMATRIXTYPEFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
@@ -3442,8 +3495,8 @@ typedef struct RwMatrixTag RWALIGN(RwMatrix, rwMATRIXALIGNMENT);
*/
/**
- * \ingroup datatypes
- * \typedef RwMatrix
+ * \ingroup rwmatrix
+ * \struct RwMatrix
* Matrix to define transformations.
* This should be considered an opaque type.
* Use the RwMatrix API functions to access.
@@ -3476,18 +3529,15 @@ typedef void (RWASMCALL * rwMatrixMultFn) (RwMatrix * dstMat,
const RwMatrix * matA,
const RwMatrix * matB);
-/*
- * \ingroup datatypes
- * \typedef RwMatrixTolerance
- * Typedef for RwMatrixTolerance structure
- */
typedef struct RwMatrixTolerance RwMatrixTolerance;
-/*
- * \ingroup datatypes
+#ifndef RWADOXYGENEXTERNAL
+/**
+ * \ingroup rwmatrix
* \struct RwMatrixTolerance
* Holds tolerances for matrix optimizations with \ref RwMatrixOptimize
*/
+#endif /* RWADOXYGENEXTERNAL */
struct RwMatrixTolerance
{
RwReal Normal;
@@ -3522,6 +3572,9 @@ RwEngineSetMatrixTolerances(const RwMatrixTolerance * const tolerance);
#define rwMatrixTestFlags(m, flagsbit) ((m)->flags & (RwInt32)(flagsbit))
/* Creation/destruction */
+extern void
+RwMatrixSetFreeListCreateParams( RwInt32 blockSize, RwInt32 numBlocksToPrealloc );
+
extern RwBool
RwMatrixDestroy(RwMatrix * mpMat);
@@ -3693,7 +3746,7 @@ MACRO_STOP
rwMATRIXTYPENORMAL) ) || /* ... or actually is */ \
rwMatrixIsNormal(_matrix, _epsilon)) && \
( ( !( rwMatrixGetFlags(_matrix) & /* not flagged as orthogonal */ \
- rwMATRIXTYPEORTHOGANAL) ) || /* ... or actually is */ \
+ rwMATRIXTYPEORTHOGONAL) ) || /* ... or actually is */ \
rwMatrixIsOrthogonal(_matrix, _epsilon)) )
#define rwMat01Det(_mAA) \
@@ -3906,8 +3959,6 @@ MACRO_STOP
#pragma warning( disable : 344 )
#endif /* (defined(__ICL)) */
-//nobody needed that - AAP
-//#include <windows.h>
#if (defined(RWDEBUG))
#if (defined(RWMEMDEBUG) && !defined(_CRTDBG_MAP_ALLOC))
@@ -4001,48 +4052,16 @@ MACRO_START \
} \
MACRO_STOP
-/* LEGACY-SUPPORT macros */
-#define RWIM2DVERTEXSetCameraX(vert, camx) RwIm2DVertexSetCameraX(vert, camx)
-#define RWIM2DVERTEXSetCameraY(vert, camy) RwIm2DVertexSetCameraY(vert, camy)
-#define RWIM2DVERTEXSetCameraZ(vert, camz) RwIm2DVertexSetCameraZ(vert, camz)
-#define RWIM2DVERTEXSetRecipCameraZ(vert, recipz) \
- RwIm2DVertexSetRecipCameraZ(vert, recipz)
-#define RWIM2DVERTEXGetCameraX(vert) RwIm2DVertexGetCameraX(vert)
-#define RWIM2DVERTEXGetCameraY(vert) RwIm2DVertexGetCameraY(vert)
-#define RWIM2DVERTEXGetCameraZ(vert) RwIm2DVertexGetCameraZ(vert)
-#define RWIM2DVERTEXGetRecipCameraZ(vert) RwIm2DVertexGetRecipCameraZ(vert)
-#define RWIM2DVERTEXSetScreenX(vert, scrnx) RwIm2DVertexSetScreenX(vert, scrnx)
-#define RWIM2DVERTEXSetScreenY(vert, scrny) RwIm2DVertexSetScreenY(vert, scrny)
-#define RWIM2DVERTEXSetScreenZ(vert, scrnz) RwIm2DVertexSetScreenZ(vert, scrnz)
-#define RWIM2DVERTEXGetScreenX(vert) RwIm2DVertexGetScreenX(vert)
-#define RWIM2DVERTEXGetScreenY(vert) RwIm2DVertexGetScreenY(vert)
-#define RWIM2DVERTEXGetScreenZ(vert) RwIm2DVertexGetScreenZ(vert)
-#define RWIM2DVERTEXSetU(vert, u, recipz) RwIm2DVertexSetU(vert, u, recipz)
-#define RWIM2DVERTEXSetV(vert, v, recipz) RwIm2DVertexSetV(vert, v, recipz)
-#define RWIM2DVERTEXGetU(vert) RwIm2DVertexGetU(vert)
-#define RWIM2DVERTEXGetV(vert) RwIm2DVertexGetV(vert)
-#define RWIM2DVERTEXSetRealRGBA(vert, red, green, blue, alpha) \
- RwIm2DVertexSetRealRGBA(vert, red, green, blue, alpha)
-#define RWIM2DVERTEXSetIntRGBA(vert, red, green, blue, alpha) \
- RwIm2DVertexSetIntRGBA(vert, red, green, blue, alpha)
-#define RWIM2DVERTEXGetRed(vert) RwIm2DVertexGetRed(vert)
-#define RWIM2DVERTEXGetGreen(vert) RwIm2DVertexGetGreen(vert)
-#define RWIM2DVERTEXGetBlue(vert) RwIm2DVertexGetBlue(vert)
-#define RWIM2DVERTEXGetAlpha(vert) RwIm2DVertexGetAlpha(vert)
-#define RWIM2DVERTEXCopyRGBA(dst, src) RwIm2DVertexCopyRGBA(dst, src)
-#define RWIM2DVERTEXClipRGBA(o, i, n, f) RwIm2DVertexClipRGBA(o, i, n, f)
-
/****************************************************************************
Global Types
*/
/* We use RwD3D8Vertex to drive the hardware in 2D mode */
-/**
- * \ingroup rwcoredriverd3d8
- * \typedef RwD3D8Vertex
+/*
* D3D8 vertex structure definition for 2D geometry
*/
+#if !defined(RWADOXYGENEXTERNAL)
typedef struct RwD3D8Vertex RwD3D8Vertex;
/**
* \ingroup rwcoredriverd3d8
@@ -4061,47 +4080,41 @@ struct RwD3D8Vertex
RwReal u; /**< Texture coordinate U */
RwReal v; /**< Texture coordinate V */
};
+#endif /* !defined(RWADOXYGENEXTERNAL) */
/* Define types used */
+#if !defined(RWADOXYGENEXTERNAL)
/**
* \ingroup rwcoredriverd3d8
- * \typedef RwIm2DVertex
+ * \ref RwIm2DVertex
* Typedef for a RenderWare Graphics Immediate Mode 2D Vertex
*/
typedef RwD3D8Vertex RwIm2DVertex;
+#endif /* !defined(RWADOXYGENEXTERNAL) */
-/* LEGACY-SUPPORT macro */
+#if !defined(RWADOXYGENEXTERNAL)
/**
* \ingroup rwcoredriverd3d8
- * \def RWIM2DVERTEX
- * RWIM2DVERTEX is a legacy macro for RwIm2DVertex
- */
-#define RWIM2DVERTEX RwIm2DVertex
-
-/**
- * \ingroup rwcoredriverd3d8
- * \typedef RxVertexIndex
+ * \ref RxVertexIndex
*
* Typedef for a RenderWare Graphics PowerPipe Immediate
* Mode Vertex
*/
typedef RwUInt16 RxVertexIndex;
+#endif /* !defined(RWADOXYGENEXTERNAL) */
+
+#if !defined(RWADOXYGENEXTERNAL)
/**
* \ingroup rwcoredriverd3d8
- * \typedef RwImVertexIndex
+ * \ref RwImVertexIndex
* Typedef for a RenderWare Graphics Immediate Mode Vertex.
*/
typedef RxVertexIndex RwImVertexIndex;
+#endif /* !defined(RWADOXYGENEXTERNAL) */
-/* LEGACY-SUPPORT macro */
-/**
- * \ingroup rwcoredriverd3d8
- * \def RWIMVERTEXINDEX
- * RWIMVERTEXINDEX is a legacy macro for RwImVertexIndex
- */
-#define RWIMVERTEXINDEX RwImVertexIndex
+#if !defined(RWADOXYGENEXTERNAL)
/**
* \ingroup rwcoredriverd3d8
@@ -4114,8 +4127,10 @@ typedef struct
RwUInt32 numTextureStageStateChanges; /**< Number of Texture Stage States changed */
RwUInt32 numMaterialChanges; /**< Number of Material changes */
RwUInt32 numLightsChanged; /**< Number of Lights changed */
+ RwUInt32 numVBSwitches; /**< Number of Vertex Buffer switches */
}
RwD3D8Metrics;
+#endif /* !defined(RWADOXYGENEXTERNAL) */
#endif /* D3D8_DRVMODEL_H */
@@ -4125,7 +4140,7 @@ RwD3D8Metrics;
* Typedef for pointer to Vector multiplication by Matrix function
*/
-typedef RwV3d *(*rwVectorMultFn) (RwV3d * pointsOut,
+typedef RwV3d *(*rwVectorMultFn) (RwV3d * pointsOut,
const RwV3d * pointsIn,
RwInt32 numPoints,
const RwMatrix * matrix);
@@ -4136,7 +4151,7 @@ typedef RwV3d *(*rwVectorMultFn) (RwV3d * pointsOut,
* currently applies to SKY2 and XBOX - IDBS [2/11/2001]
* [and, if using the intel compiler version 400 or above,
* we will use the single-precision float "sqrtf" under
- * D3D7, D3D8, OpenGL or SoftRas] */
+ * D3D8, OpenGL or SoftRas] */
#if (defined(rwSqrtMacro))
#define RWNOSQRTTABLE
#endif /* (defined(rwSqrtMacro)) */
@@ -4198,7 +4213,7 @@ MACRO_STOP
#define RwV2dDotProductMacro(a,b) \
(( ((((a)->x) * ( (b)->x))) + \
- ( (((a)->y) * ( (b)->y))))) \
+ ( (((a)->y) * ( (b)->y)))))
#define _rwV2dNormalizeMacro(_result, _out, _in) \
MACRO_START \
@@ -4303,7 +4318,7 @@ MACRO_STOP
#define RwV3dDotProductMacro(a, b) \
((((( (((a)->x) * ((b)->x))) + \
( (((a)->y) * ((b)->y))))) + \
- ( (((a)->z) * ((b)->z))))) \
+ ( (((a)->z) * ((b)->z)))))
#define RwV3dCrossProductMacro(o, a, b) \
MACRO_START \
@@ -4375,7 +4390,7 @@ MACRO_STOP
#endif /* (!defined(rw4OVERPISQ)) */
#if (!defined(rwPI3))
-#define rwPI3 (rwPI * (RwReal)3)
+#define rwPI3 (rwPI * (RwReal)3)
#endif /* (!defined(rwPI3)) */
#if (!defined(rwPI3OVER2))
@@ -4463,7 +4478,7 @@ extern void RwV3dSub(RwV3d * out,
const RwV3d * ina, const RwV3d * inb);
extern void RwV3dScale(RwV3d * out,
const RwV3d * in, RwReal scalar);
-extern void RwV3dIncrementScaled(RwV3d * out,
+extern void RwV3dIncrementScaled(RwV3d * out,
const RwV3d * in, RwReal scalar);
extern void RwV3dNegate(RwV3d * out, const RwV3d * in);
extern RwReal RwV3dDotProduct(const RwV3d * ina, const RwV3d * inb);
@@ -4513,6 +4528,8 @@ extern RwReal _rwV3dNormalize(RwV3d * out, const RwV3d * in);
*/
typedef struct RwSList RwSList;
+
+#if (!defined(DOXYGEN))
struct RwSList
{
RwUInt8 *listElements;
@@ -4520,7 +4537,7 @@ struct RwSList
RwInt32 numElementsAlloced;
RwInt32 entrySize;
};
-
+#endif /* (!defined(DOXYGEN) */
/****************************************************************************
@@ -4595,99 +4612,169 @@ extern void *_rwSListToArray(RwSList *sList);
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */
+#ifndef RWADOXYGENEXTERNAL
/**
- * \ingroup datatypes
- * RwRenderState
- * This type represents the various render states that
- * can be set using the API function \ref RwRenderStateSet. This function also
- * takes a render state value or pointer to an object depending on the type.
- * For render states that are toggles, the value should be TRUE to switch the
- * state on and FALSE to turn it off.
+ * \ingroup rwrenderstate
+ * RwRenderState represents the global state variables that control
+ * rendering. These may be set and queried using the
+ * \ref RwRenderStateSet and \ref RwRenderStateGet functions respectively.
+ *
+ * Refer to the \ref rwrenderstateoverview for an overview of this system.
*
- * Note that many of these render states may not be supported on certain
- * platforms. The \ref RwRenderStateSet functions will return FALSE in such cases.
+ * \note The texture render states (raster, address & filter modes) would
+ * normally just be used when rendering in immediate mode and should be
+ * specificied completely every time a texture is used. Retained mode
+ * pipelines will frequently set theses states internally, usually based on
+ * \ref RwTexture objects.
*/
+#endif /* RWADOXYGENEXTERNAL */
enum RwRenderState
{
rwRENDERSTATENARENDERSTATE = 0,
- rwRENDERSTATETEXTURERASTER, /**<Raster to texture with. \ref RwRenderStateSet
- * takes a pointer to an \ref RwRaster */
- rwRENDERSTATETEXTUREADDRESS, /**<\ref RwTextureAddressMode: wrap, clamp, mirror or border */
- rwRENDERSTATETEXTUREADDRESSU, /**<\ref RwTextureAddressMode in u only */
- rwRENDERSTATETEXTUREADDRESSV, /**<\ref RwTextureAddressMode in v only */
- rwRENDERSTATETEXTUREPERSPECTIVE, /**<Perspective correction on/off */
- rwRENDERSTATEZTESTENABLE, /**<Z-buffer test on/off */
- rwRENDERSTATESHADEMODE, /**<\ref RwShadeMode: flat or gouraud shading */
- rwRENDERSTATEZWRITEENABLE, /**<Z-buffer write on/off */
- rwRENDERSTATETEXTUREFILTER, /**<\ref RwTextureFilterMode: point sample, bilinear, trilinear, etc */
- rwRENDERSTATESRCBLEND, /**<Source alpha \ref RwBlendFunction: src alpha, 1-src alpha, etc */
- rwRENDERSTATEDESTBLEND, /**<Destination alpha \ref RwBlendFunction */
- rwRENDERSTATEVERTEXALPHAENABLE, /**<Vertex alpha transparency on/off */
- rwRENDERSTATEBORDERCOLOR, /**<Border color for \ref RwTextureAddressMode rwTEXTUREADDRESSBORDER.
- * The value should be a packed RwUInt32 in ARGB form. The macro
- * RWRGBALONG(r, g, b, a) may be used to construct this using 8-bit
- * color components. */
- rwRENDERSTATEFOGENABLE, /**<Fogging on/off (all polygons will be fogged) */
- rwRENDERSTATEFOGCOLOR, /**<Color used for fogging. The value should be a packed RwUInt32
- * in ARGB form. The macro RWRGBALONG(r, g, b, a) may be used to
- * construct this using 8-bit color components */
- rwRENDERSTATEFOGTYPE, /**<Sets \ref RwFogType, the type of fogging to use */
- rwRENDERSTATEFOGDENSITY, /**<Select the fog density for \ref RwFogType of rwFOGTYPEEXPONENTIAL
- * or rwFOGTYPEEXPONENTIAL2. The value should be a pointer to
- * an RwReal in the range 0 to 1. */
- rwRENDERSTATEFOGTABLE, /**<Install a 256 entry fog table placed between fog distance and far
- * clip-plane */
- rwRENDERSTATEALPHAPRIMITIVEBUFFER, /**<Render transparent alpha polygons last - on/off. \e Not \e supported
- * \e on \e any \e platform.*/
- rwRENDERSTATECULLMODE, /**<Sets \ref RwCullMode, for selecting face culling. */
- rwRENDERSTATESTENCILENABLE, /**< TRUE to enable stenciling, or FALSE to disable stenciling.
- * \e Supported \e on \e Xbox, \e D3D8, \e and \e OpenGL \e only. */
- rwRENDERSTATESTENCILFAIL, /**< Stencil test operator for the fail case.
- * \e Supported \e on \e Xbox, \e D3D8, \e and \e OpenGL \e only */
- rwRENDERSTATESTENCILZFAIL, /**< Stencil operation to perform if the stencil test passes
- * and the depth test (z-test) fails.
- * \e Supported \e on \e Xbox, \e D3D8, \e and \e OpenGL \e only */
- rwRENDERSTATESTENCILPASS, /**< Stencil operation to perform if both the stencil and the
- * depth (z) tests pass.
- * \e Supported \e on \e Xbox, \e D3D8, \e and \e OpenGL \e only */
- rwRENDERSTATESTENCILFUNCTION, /**< Comparison function for the stencil test.
- * \e Supported \e on \e Xbox, \e D3D8, \e and \e OpenGL \e only */
- rwRENDERSTATESTENCILFUNCTIONREF, /**< Integer reference value for the stencil test.
- * \e Supported \e on \e Xbox, \e D3D8, \e and \e OpenGL \e only */
- rwRENDERSTATESTENCILFUNCTIONMASK, /**< Mask applied to the reference value and each stencil buffer
- * entry to determine the significant bits for the stencil test.
- * \e Supported \e on \e Xbox, \e D3D8, \e and \e OpenGL \e only */
- rwRENDERSTATESTENCILFUNCTIONWRITEMASK, /**< Write mask applied to values written into the stencil buffer.
- * \e Supported \e on \e Xbox, \e D3D8, \e and \e OpenGL \e only */
+
+ rwRENDERSTATETEXTURERASTER,
+ /**<Raster used for texturing (normally used in immediate mode).
+ * The value is a pointer to an \ref RwRaster.
+ */
+ rwRENDERSTATETEXTUREADDRESS,
+ /**<\ref RwTextureAddressMode: wrap, clamp, mirror or border.
+ */
+ rwRENDERSTATETEXTUREADDRESSU,
+ /**<\ref RwTextureAddressMode in u only.
+ */
+ rwRENDERSTATETEXTUREADDRESSV,
+ /**<\ref RwTextureAddressMode in v only.
+ */
+ rwRENDERSTATETEXTUREPERSPECTIVE,
+ /**<Perspective correction on/off (always enabled on many platforms).
+ */
+ rwRENDERSTATEZTESTENABLE,
+ /**<Z-buffer test on/off.
+ */
+ rwRENDERSTATESHADEMODE,
+ /**<\ref RwShadeMode: flat or gouraud shading.
+ */
+ rwRENDERSTATEZWRITEENABLE,
+ /**<Z-buffer write on/off.
+ */
+ rwRENDERSTATETEXTUREFILTER,
+ /**<\ref RwTextureFilterMode: point sample, bilinear, trilinear, etc.
+ */
+ rwRENDERSTATESRCBLEND,
+ /**<\ref RwBlendFunction used to modulate the source pixel color
+ * when blending to the frame buffer.
+ */
+ rwRENDERSTATEDESTBLEND,
+ /**<\ref RwBlendFunction used to modulate the destination pixel
+ * color in the frame buffer when blending. The resulting pixel
+ * color is given by the formula
+ * (SRCBLEND * srcColor + DESTBLEND * destColor) for each RGB
+ * component. For a particular platform, not all combinations
+ * of blend function are allowed (see platform specific
+ * restrictions).
+ */
+ rwRENDERSTATEVERTEXALPHAENABLE,
+ /**<Alpha blending on/off (always enabled on some platforms).
+ * This is normally used in immediate mode to enable alpha blending
+ * when vertex colors or texture rasters have transparency. Retained
+ * mode pipelines will usually set this state based on material colors
+ * and textures.
+ */
+ rwRENDERSTATEBORDERCOLOR,
+ /**<Border color for \ref RwTextureAddressMode
+ * \ref rwTEXTUREADDRESSBORDER. The value should be a packed
+ * RwUInt32 in a platform specific format. The macro
+ * RWRGBALONG(r, g, b, a) may be used to construct this using
+ * 8-bit color components.
+ */
+ rwRENDERSTATEFOGENABLE,
+ /**<Fogging on/off (all polygons will be fogged).
+ */
+ rwRENDERSTATEFOGCOLOR,
+ /**<Color used for fogging. The value should be a packed RwUInt32
+ * in a platform specific format. The macro RWRGBALONG(r, g, b, a)
+ * may be used to construct this using 8-bit color components.
+ */
+ rwRENDERSTATEFOGTYPE,
+ /**<\ref RwFogType, the type of fogging to use.
+ */
+ rwRENDERSTATEFOGDENSITY,
+ /**<Fog density for \ref RwFogType of
+ * \ref rwFOGTYPEEXPONENTIAL or \ref rwFOGTYPEEXPONENTIAL2.
+ * The value should be a pointer to an RwReal in the
+ * range 0 to 1.
+ */
+ rwRENDERSTATECULLMODE = 20,
+ /**<\ref RwCullMode, for selecting front/back face culling, or
+ * no culling.
+ */
+ rwRENDERSTATESTENCILENABLE,
+ /**<Stenciling on/off.
+ * <i> Supported on Xbox, D3D8, and OpenGL only. </i>
+ */
+ rwRENDERSTATESTENCILFAIL,
+ /**<\ref RwStencilOperation used when the stencil test passes.
+ * <i> Supported on Xbox, D3D8, and OpenGL only. </i>
+ */
+ rwRENDERSTATESTENCILZFAIL,
+ /**<\ref RwStencilOperation used when the stencil test passes and
+ * the depth test (z-test) fails.
+ * <i> Supported on Xbox, D3D8, and OpenGL only. </i>
+ */
+ rwRENDERSTATESTENCILPASS,
+ /**<Stencil operation used when both the stencil and the depth
+ * (z) tests pass.
+ * <i> Supported on Xbox, D3D8, and OpenGL only. </i>
+ */
+ rwRENDERSTATESTENCILFUNCTION,
+ /**<\ref RwStencilFunction for the stencil test.
+ * <i> Supported on Xbox, D3D8, and OpenGL only. </i>
+ */
+ rwRENDERSTATESTENCILFUNCTIONREF,
+ /**<Integer reference value for the stencil test.
+ * <i> Supported on Xbox, D3D8, and OpenGL only. </i>
+ */
+ rwRENDERSTATESTENCILFUNCTIONMASK,
+ /**<Mask applied to the reference value and each stencil buffer
+ * entry to determine the significant bits for the stencil test.
+ * <i> Supported on Xbox, D3D8, and OpenGL only. </i>
+ */
+ rwRENDERSTATESTENCILFUNCTIONWRITEMASK,
+ /**<Write mask applied to values written into the stencil buffer.
+ * <i> Supported on Xbox, D3D8, and OpenGL only. </i>
+ */
rwRENDERSTATEFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
};
typedef enum RwRenderState RwRenderState;
-
+#ifndef RWADOXYGENEXTERNAL
/**
- * \ingroup datatypes
- * RwShadeMode
- * This type represents the options available for setting the
- * rwRENDERSTATESHADEMODE render state */
+ * \ingroup rwrenderstate
+ * RwShadeMode represents the available shading modes that may be
+ * set using the \ref RwRenderState \ref rwRENDERSTATESHADEMODE.
+ */
+#endif /* RWADOXYGENEXTERNAL */
enum RwShadeMode
{
- rwSHADEMODENASHADEMODE = 0, /**<Invalid shading mode */
+ rwSHADEMODENASHADEMODE = 0,
rwSHADEMODEFLAT, /**<Flat shading */
rwSHADEMODEGOURAUD, /**<Gouraud shading */
rwSHADEMODEFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
};
typedef enum RwShadeMode RwShadeMode;
-
+#ifndef RWADOXYGENEXTERNAL
/**
- * \ingroup datatypes
- * RwTextureFilterMode
- * This type represents the options available for texture
- * filtering (see API functions \ref RwTextureSetFilterMode and \ref RwRenderStateSet)*/
+ * \ingroup rwrenderstate
+ * RwTextureFilterMode represents the texture filtering modes that may
+ * be set using the \ref RwRenderState \ref rwRENDERSTATETEXTUREFILTER in
+ * immediate mode, or \ref RwTextureSetFilterMode in retained mode.
+ */
+#endif /* RWADOXYGENEXTERNAL */
enum RwTextureFilterMode
{
- rwFILTERNAFILTERMODE = 0, /**<Invalid filter mode */
+ rwFILTERNAFILTERMODE = 0,
rwFILTERNEAREST, /**<Point sampled */
rwFILTERLINEAR, /**<Bilinear */
rwFILTERMIPNEAREST, /**<Point sampled per pixel mip map */
@@ -4698,15 +4785,18 @@ enum RwTextureFilterMode
};
typedef enum RwTextureFilterMode RwTextureFilterMode;
-
+#ifndef RWADOXYGENEXTERNAL
/**
- * \ingroup datatypes
- * RwFogType
- * This type represents the options available to the
- * rwRENDERSTATEFOGTYPE render state (see \ref RwRenderState);*/
+ * \ingroup rwrenderstate
+ * RwFogType represents the fog modes available when setting the
+ * \ref RwRenderState \ref rwRENDERSTATEFOGTYPE. Note that a particular
+ * platform may not support all of these modes (see platform specific
+ * restrictions).
+ */
+#endif /* RWADOXYGENEXTERNAL */
enum RwFogType
{
- rwFOGTYPENAFOGTYPE = 0, /**<Invalid fog type */
+ rwFOGTYPENAFOGTYPE = 0,
rwFOGTYPELINEAR, /**<Linear fog */
rwFOGTYPEEXPONENTIAL, /**<Exponential fog */
rwFOGTYPEEXPONENTIAL2, /**<Exponential^2 fog */
@@ -4714,18 +4804,28 @@ enum RwFogType
};
typedef enum RwFogType RwFogType;
-
+#ifndef RWADOXYGENEXTERNAL
/**
- * \ingroup datatypes
- * RwBlendFunction
- * This type represents the options available
- * to the rwRENDERSTATESRCBLEND and rwRENDERSTATEDESTBLEND render states
- * (see \ref RwRenderState). In the following description,
- * a subscript s refers to a source value while subscript d refers to a
- * destination value.*/
+ * \ingroup rwrenderstate
+ * RwBlendFunction represents the options available when changing the
+ * \ref RwRenderState setting for \ref rwRENDERSTATESRCBLEND and
+ * \ref rwRENDERSTATEDESTBLEND. The values are factors used to modulate
+ * either the source or destination pixel color when blending to
+ * the frame buffer. Note the some combinations are not allowed on
+ * certain platforms (see platform specific restrictions).
+ *
+ * In the following list, the factors applied to each color component are
+ * listed explicitly. A subscript s refers to a source value while a subscript
+ * d refers to a destination value. Note that blending in the alpha channel is
+ * only applicable when the frame buffer actually contains alpha, and that
+ * the precise operation is platform specific. For instance, the
+ * source alpha value might simply be written to the alpha channel with
+ * no blending.
+ */
+#endif /* RWADOXYGENEXTERNAL */
enum RwBlendFunction
{
- rwBLENDNABLEND = 0, /**<Invalid blend mode */
+ rwBLENDNABLEND = 0,
rwBLENDZERO, /**<(0, 0, 0, 0 ) */
rwBLENDONE, /**<(1, 1, 1, 1 ) */
rwBLENDSRCCOLOR, /**<(Rs, Gs, Bs, As ) */
@@ -4741,93 +4841,139 @@ enum RwBlendFunction
};
typedef enum RwBlendFunction RwBlendFunction;
-
+#ifndef RWADOXYGENEXTERNAL
/**
- * \ingroup datatypes
- * RwTextureAddressMode
- * This type represents the options available for
- * applying textures to polygons (see API functions \ref RwTextureSetAddressing
- * and \ref RwRenderStateSet, and the \ref RwRenderState type) */
+ * \ingroup rwrenderstate
+ * RwTextureAddressMode represents the addressing modes available
+ * when mapping textures to polygons using UV texture coordinates.
+ * This may be set in immediate mode via the \ref RwRenderState
+ * \ref rwRENDERSTATETEXTUREADDRESS, or via \ref RwTextureSetAddressing
+ * for an \ref RwTexture object.
+ */
+#endif /* RWADOXYGENEXTERNAL */
enum RwTextureAddressMode
{
- rwTEXTUREADDRESSNATEXTUREADDRESS = 0, /**<Invalid addressing mode */
- rwTEXTUREADDRESSWRAP, /**<UV wraps (tiles) */
- rwTEXTUREADDRESSMIRROR, /**<Alternate UV is flipped */
- rwTEXTUREADDRESSCLAMP, /**<UV is clamped to 0-1 */
- rwTEXTUREADDRESSBORDER, /**<Border colour takes effect outside of 0-1 */
+ rwTEXTUREADDRESSNATEXTUREADDRESS = 0,
+ rwTEXTUREADDRESSWRAP, /**<UV wraps (tiles) */
+ rwTEXTUREADDRESSMIRROR, /**<Alternate UV is flipped */
+ rwTEXTUREADDRESSCLAMP, /**<UV is clamped to 0-1 */
+ rwTEXTUREADDRESSBORDER, /**<Border color takes effect outside of 0-1 */
rwTEXTUREADDRESSMODEFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
};
typedef enum RwTextureAddressMode RwTextureAddressMode;
+#ifndef RWADOXYGENEXTERNAL
/**
- * \ingroup datatypes
- * RwStencilOperation
- * This type represents the stencil operations to perform
- * based on the results of the
- * \ref rwRENDERSTATESTENCILFAIL, \ref rwRENDERSTATESTENCILZFAIL
- * and \ref rwRENDERSTATESTENCILPASS tests.
+ * \ingroup rwrenderstate
+ * RwStencilOperation represents the stencil operations that may be
+ * performed depending on the results of stencil/z-buffer tests.
+ * The operation may be set for the various tests
+ * via the \ref RwRenderState settings \ref rwRENDERSTATESTENCILFAIL,
+ * \ref rwRENDERSTATESTENCILZFAIL and \ref rwRENDERSTATESTENCILPASS.
*/
+#endif /* RWADOXYGENEXTERNAL */
enum RwStencilOperation
{
rwSTENCILOPERATIONNASTENCILOPERATION = 0,
- rwSTENCILOPERATIONKEEP, /* Do not update the entry in the stencil buffer */
- rwSTENCILOPERATIONZERO, /* Set the stencil-buffer entry to 0 */
- rwSTENCILOPERATIONREPLACE, /* Replace the stencil-buffer entry with reference value */
- rwSTENCILOPERATIONINCRSAT, /* Increment the stencil-buffer entry, clamping to the maximum value */
- rwSTENCILOPERATIONDECRSAT, /* Decrement the stencil-buffer entry, clamping to zero */
- rwSTENCILOPERATIONINVERT, /* Invert the bits in the stencil-buffer entry */
- rwSTENCILOPERATIONINCR, /* Increment the stencil-buffer entry, wrapping to zero if the new value exceeds the maximum value */
- rwSTENCILOPERATIONDECR, /* Decrement the stencil-buffer entry, wrapping to the maximum value if the new value is less than zero */
+
+ rwSTENCILOPERATIONKEEP,
+ /**<Do not update the entry in the stencil buffer */
+ rwSTENCILOPERATIONZERO,
+ /**<Set the stencil-buffer entry to 0 */
+ rwSTENCILOPERATIONREPLACE,
+ /**<Replace the stencil-buffer entry with reference value */
+ rwSTENCILOPERATIONINCRSAT,
+ /**<Increment the stencil-buffer entry, clamping to the
+ * maximum value */
+ rwSTENCILOPERATIONDECRSAT,
+ /**<Decrement the stencil-buffer entry, clamping to zero */
+ rwSTENCILOPERATIONINVERT,
+ /**<Invert the bits in the stencil-buffer entry */
+ rwSTENCILOPERATIONINCR,
+ /**<Increment the stencil-buffer entry, wrapping to zero if
+ * the new value exceeds the maximum value */
+ rwSTENCILOPERATIONDECR,
+ /**<Decrement the stencil-buffer entry, wrapping to the maximum
+ * value if the new value is less than zero */
+
rwSTENCILOPERATIONFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
};
typedef enum RwStencilOperation RwStencilOperation;
+#ifndef RWADOXYGENEXTERNAL
/**
- * \ingroup datatypes
- * RwStencilFunction
- * This type represents the options available for
- * the comparison function for the stencil test \ref rwRENDERSTATESTENCILFUNCTION.
+ * \ingroup rwrenderstate
+ * RwStencilFunction represents the comparison functions available for
+ * a stencil test. The function may be selected via the
+ * \ref RwRenderState setting \ref rwRENDERSTATESTENCILFUNCTION.
*/
+#endif /* RWADOXYGENEXTERNAL */
enum RwStencilFunction
{
rwSTENCILFUNCTIONNASTENCILFUNCTION = 0,
- rwSTENCILFUNCTIONNEVER, /* Always fail the test */
- rwSTENCILFUNCTIONLESS, /* Accept the new pixel if its value is less than the value of the current pixel */
- rwSTENCILFUNCTIONEQUAL, /* Accept the new pixel if its value equals the value of the current pixel */
- rwSTENCILFUNCTIONLESSEQUAL, /* Accept the new pixel if its value is less than or equal to the value of the current pixel */
- rwSTENCILFUNCTIONGREATER, /* Accept the new pixel if its value is greater than the value of the current pixel */
- rwSTENCILFUNCTIONNOTEQUAL, /* Accept the new pixel if its value does not equal the value of the current pixel */
- rwSTENCILFUNCTIONGREATEREQUAL, /* Accept the new pixel if its value is greater than or equal to the value of the current pixel */
- rwSTENCILFUNCTIONALWAYS, /* Always pass the test */
+
+ rwSTENCILFUNCTIONNEVER,
+ /**<Always fail the test */
+ rwSTENCILFUNCTIONLESS,
+ /**<Accept the new pixel if its value is less than the value of
+ * the current pixel */
+ rwSTENCILFUNCTIONEQUAL,
+ /**<Accept the new pixel if its value equals the value of the
+ * current pixel */
+ rwSTENCILFUNCTIONLESSEQUAL,
+ /**<Accept the new pixel if its value is less than or equal to
+ * the value of the current pixel */
+ rwSTENCILFUNCTIONGREATER,
+ /**<Accept the new pixel if its value is greater than the value
+ * of the current pixel */
+ rwSTENCILFUNCTIONNOTEQUAL,
+ /**<Accept the new pixel if its value does not equal the value of
+ * the current pixel */
+ rwSTENCILFUNCTIONGREATEREQUAL,
+ /**<Accept the new pixel if its value is greater than or equal
+ * to the value of the current pixel */
+ rwSTENCILFUNCTIONALWAYS,
+ /**<Always pass the test */
+
rwSTENCILFUNCTIONFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
};
typedef enum RwStencilFunction RwStencilFunction;
+#ifndef RWADOXYGENEXTERNAL
/**
- * \ingroup datatypes
- * RwCullMode
- * This type represents the options available for culling polygons during rendering.
- * and \ref RwRenderStateSet, and the \ref RwRenderState type) */
+ * \ingroup rwrenderstate
+ * RwCullMode represents the options available for culling polygons
+ * during rendering. The cull mode may be set via the \ref RwRenderState
+ * setting \ref rwRENDERSTATECULLMODE.
+ */
+#endif /* RWADOXYGENEXTERNAL */
enum RwCullMode
{
rwCULLMODENACULLMODE = 0,
- rwCULLMODECULLNONE, /**< Both front and back-facing triangles are drawn. */
- rwCULLMODECULLBACK, /**< Just front-facing triangles are drawn */
- rwCULLMODECULLFRONT, /**< Just rear-facing triangles are drawn */
+
+ rwCULLMODECULLNONE,
+ /**<Both front and back-facing triangles are drawn. */
+ rwCULLMODECULLBACK,
+ /**<Only front-facing triangles are drawn */
+ rwCULLMODECULLFRONT,
+ /**<Only back-facing triangles are drawn */
rwCULLMODEFORCEENUMSIZEINT = RWFORCEENUMSIZEINT
};
typedef enum RwCullMode RwCullMode;
+#ifndef RWADOXYGENEXTERNAL
/**
- * \ingroup datatypes
+ * \ingroup immediatemodedatatypes
* RwPrimitiveType
* This type represents the different types of indexed
* line and indexed triangle primitives that are available when rendering 2D
* and 3D immediate mode objects (see API functions \ref RwIm2DRenderIndexedPrimitive,
* \ref RwIm2DRenderPrimitive, \ref RwIm3DRenderIndexedPrimitive and \ref RwIm3DRenderPrimitive).
* Indices are into a vertex list and must be defined in a counter-clockwise order
- * (as seen from the camera) to be visible.*/
+ * (as seen from the camera) to be visible.
+ */
+#endif /* RWADOXYGENEXTERNAL */
enum RwPrimitiveType
{
rwPRIMTYPENAPRIMTYPE = 0, /**<Invalid primative type */
@@ -4994,8 +5140,9 @@ typedef RwBool (*RwStandardFunc)(void *pOut,void *pInOut,RwInt32 nI);
typedef struct RwEngineOpenParams RwEngineOpenParams;
+#ifndef RWADOXYGENEXTERNAL
/**
- * \ingroup datatypes
+ * \ingroup rwengine
* \struct RwEngineOpenParams
* This type is used to specify device dependent parameters
* for use by the API function \ref RwEngineOpen.
@@ -5003,6 +5150,7 @@ typedef struct RwEngineOpenParams RwEngineOpenParams;
* should be set to the window's handle (of type HWND).
* For NULL and sky libraries displayID=0:
*/
+#endif /* RWADOXYGENEXTERNAL */
struct RwEngineOpenParams
{
void *displayID; /**< Display Identifier */
@@ -5066,37 +5214,41 @@ typedef RwBool
typedef struct RwDevice RwDevice;
-/**
- * \ingroup datatypes
- * \struct RwDevice
+
+#if (!defined(DOXYGEN))
+/*
+ * struct RwDevice
* Structure describing a display device
*/
struct RwDevice
{
- RwReal gammaCorrection; /**<Gamma correction */
- RwSystemFunc fpSystem; /**< System handler */
- RwReal zBufferNear; /**< Near Z buffer value */
- RwReal zBufferFar; /**< Far Z buffer value */
+ RwReal gammaCorrection; /* Gamma correction */
+ RwSystemFunc fpSystem; /* System handler */
+ RwReal zBufferNear; /* Near Z buffer value */
+ RwReal zBufferFar; /* Far Z buffer value */
/* Immediate mode functions */
- RwRenderStateSetFunction fpRenderStateSet; /**< Internal Use */
- RwRenderStateGetFunction fpRenderStateGet; /**< Internal Use */
+ RwRenderStateSetFunction fpRenderStateSet; /* Internal Use */
+ RwRenderStateGetFunction fpRenderStateGet; /* Internal Use */
/* Render functions */
- RwIm2DRenderLineFunction fpIm2DRenderLine; /**< Internal Use */
- RwIm2DRenderTriangleFunction fpIm2DRenderTriangle; /**< Internal Use */
- RwIm2DRenderPrimitiveFunction fpIm2DRenderPrimitive; /**< Internal Use */
- RwIm2DRenderIndexedPrimitiveFunction fpIm2DRenderIndexedPrimitive; /**< Internal Use */
-
- RwIm3DRenderLineFunction fpIm3DRenderLine; /**< Internal Use */
- RwIm3DRenderTriangleFunction fpIm3DRenderTriangle; /**< Internal Use */
- RwIm3DRenderPrimitiveFunction fpIm3DRenderPrimitive; /**< Internal Use */
- RwIm3DRenderIndexedPrimitiveFunction fpIm3DRenderIndexedPrimitive; /**< Internal Use */
+ RwIm2DRenderLineFunction fpIm2DRenderLine; /* Internal Use */
+ RwIm2DRenderTriangleFunction fpIm2DRenderTriangle; /* Internal Use */
+ RwIm2DRenderPrimitiveFunction fpIm2DRenderPrimitive; /* Internal Use */
+ RwIm2DRenderIndexedPrimitiveFunction fpIm2DRenderIndexedPrimitive; /* Internal Use */
+
+ RwIm3DRenderLineFunction fpIm3DRenderLine; /* Internal Use */
+ RwIm3DRenderTriangleFunction fpIm3DRenderTriangle; /* Internal Use */
+ RwIm3DRenderPrimitiveFunction fpIm3DRenderPrimitive; /* Internal Use */
+ RwIm3DRenderIndexedPrimitiveFunction fpIm3DRenderIndexedPrimitive; /* Internal Use */
};
+#endif /* (!defined(DOXYGEN)) */
+
typedef struct RwMetrics RwMetrics;
+#ifndef RWADOXYGENEXTERNAL
/**
- * \ingroup datatypes
+ * \ingroup rwengine
* \struct RwMetrics
* This structure provides information about the performance
* of the application. The metrics are recorded only in the metrics
@@ -5109,6 +5261,7 @@ typedef struct RwMetrics RwMetrics;
* be considered as bad news and will indicate a significantly
* reduced rendering performance.
*/
+#endif /* RWADOXYGENEXTERNAL */
struct RwMetrics
{
RwUInt32 numTriangles; /**< Number of triangles processed */
@@ -5123,13 +5276,15 @@ struct RwMetrics
#define SUBSYSTEMNAME_MAXLEN 80
typedef struct RwSubSystemInfo RwSubSystemInfo;
+#ifndef RWADOXYGENEXTERNAL
/**
- * \ingroup datatypes
+ * \ingroup rwengine
* \struct RwSubSystemInfo
* This type is used to represent information about a device.
* The only available field specifies a character string
* which identifies the subsystem
* (see API function \ref RwEngineGetSubSystemInfo). */
+#endif /* RWADOXYGENEXTERNAL */
struct RwSubSystemInfo
{
RwChar name[SUBSYSTEMNAME_MAXLEN]; /**< Sub system string */
@@ -5139,13 +5294,15 @@ struct RwSubSystemInfo
/* Video modes */
/* These are flag bits which may be ORd */
+#ifndef RWADOXYGENEXTERNAL
/**
- * \ingroup datatypes
+ * \ingroup rwengine
* RwVideoModeFlag
* These flags specify the type of display that RenderWare
* will use. The flags may be OR'd together to build composite modes.
* Note that not all modes are supported on all platforms.
*/
+#endif /* RWADOXYGENEXTERNAL */
enum RwVideoModeFlag
{
rwVIDEOMODEEXCLUSIVE = 0x1, /**<Exclusive (i.e. full-screen) */
@@ -5162,13 +5319,16 @@ enum RwVideoModeFlag
typedef enum RwVideoModeFlag RwVideoModeFlag;
typedef struct RwVideoMode RwVideoMode;
+#ifndef RWADOXYGENEXTERNAL
/**
- * \ingroup datatypes
+ * \ingroup rwengine
* \struct RwVideoMode
* This type represents a video mode available on a device specified
* by the frame buffer resolution (width and height) and depth,
* and a flag indicating whether the device has exclusive use of
- * the mode (see API function \ref RwEngineGetVideoModeInfo): */
+ * the mode (see API function \ref RwEngineGetVideoModeInfo):
+ */
+#endif /* RWADOXYGENEXTERNAL */
struct RwVideoMode
{
RwInt32 width; /**< Width */
@@ -5177,8 +5337,9 @@ struct RwVideoMode
RwVideoModeFlag flags; /**< Flags */
};
+#ifndef RWADOXYGENEXTERNAL
/**
- * \ingroup datatypes
+ * \ingroup rwengine
* RwEngineInitFlag
* Engine initialization flags. An application can use
* these to control the memory manager that RenderWare uses for dynamic
@@ -5190,6 +5351,7 @@ struct RwVideoMode
* RwMalloc and RwFree. This will result in more memory management
* related calls.
*/
+#endif /* RWADOXYGENEXTERNAL */
enum RwEngineInitFlag
{
rwENGINEINITFREELISTS = 0, /**<Use Freelists */
@@ -5211,7 +5373,9 @@ extern "C"
extern RwInt32 RwEngineGetVersion(void);
/* Sequence of events to get RenderWare up and running */
-extern RwBool RwEngineInit(RwMemoryFunctions *memFuncs, RwUInt32 initFlags, RwUInt32 resArenaSize);
+extern RwBool RwEngineInit(const RwMemoryFunctions *memFuncs,
+ RwUInt32 initFlags,
+ RwUInt32 resArenaSize);
extern RwInt32 RwEngineRegisterPlugin(RwInt32 size, RwUInt32 pluginID,
RwPluginObjectConstructor initCB,
RwPluginObjectDestructor termCB);
@@ -5256,80 +5420,75 @@ extern RwMetrics *RwEngineGetMetrics(void);
*/
/*
- * \typedef rwFnFexist
+ * rwFnFexist
* Returns TRUE if file with given name exists, FALSE if it doesn't.
*/
typedef RwBool (*rwFnFexist)(const RwChar *name);
/*
- * \typedef rwFnFopen
+ * rwFnFopen
* Mimics ANSI C Standard Library fopen.
*/
typedef void *(*rwFnFopen)(const RwChar *name, const RwChar *mode);
/*
- * \typedef rwFnFclose
+ * rwFnFclose
* Mimics ANSI C Standard Library fclose.
*/
typedef int (*rwFnFclose)(void *fptr);
/*
- * \typedef rwFnFread
+ * rwFnFread
* Mimics ANSI C Standard Library fread.
*/
typedef size_t (*rwFnFread)(void *addr, size_t size, size_t count, void *fptr);
/*
- * \typedef rwFnFwrite
+ * rwFnFwrite
* Mimics ANSI C Standard Library fwrite.
*/
typedef size_t (*rwFnFwrite)(const void *addr, size_t size, size_t count, void *fptr);
/*
- * \typedef rwFnFgets
+ * rwFnFgets
* Mimics ANSI C Standard Library fgets.
*/
typedef RwChar *(*rwFnFgets)(RwChar *buffer, int maxLen, void *fptr);
/*
- * \typedef rwFnFputs
+ * rwFnFputs
* Mimics ANSI C Standard Library fputs.
*/
typedef int (*rwFnFputs)(const RwChar *buffer, void *fptr);
/*
- * \typedef rwFnFeof
+ * rwFnFeof
* Mimics ANSI C Standard Library feof.
*/
typedef int (*rwFnFeof)(void *fptr);
/*
- * \typedef rwFnFseek
+ * rwFnFseek
* Mimics ANSI C Standard Library fseek.
*/
typedef int (*rwFnFseek)(void *fptr, long offset, int origin);
/*
- * \typedef rwFnFflush
+ * rwFnFflush
* Mimics ANSI C Standard Library fflush.
*/
typedef int (*rwFnFflush)(void *fptr);
/*
- * \typedef rwFnFtell
+ * rwFnFtell
* Mimics ANSI C Standard Library ftell.
*/
typedef int (*rwFnFtell)(void *fptr);
-/**
- * \ingroup datatypes
- * \typedef RwFileFunctions
- * typedef for struct RwFileFunctions
- */
typedef struct RwFileFunctions RwFileFunctions;
/**
- * \ingroup datatypes
+ * \ingroup memoryfileinterface
* \struct RwFileFunctions
* This type is used to specify the file access
* functions used by RenderWare. The default file system uses the standard
@@ -5390,8 +5549,9 @@ extern RwFileFunctions *RwOsGetFileInterface(void);
*/
typedef struct RwError RwError;
+#ifndef RWADOXYGENEXTERNAL
/**
- * \ingroup datatypes
+ * \ingroup rwerror
* \struct RwError
* This type represents a RenderWare error specified by the
* ID of the plugin that the error was issued from (pluginID) and the error
@@ -5399,6 +5559,7 @@ typedef struct RwError RwError;
* \param pluginID The ID of the plugin that issued the error.
* \param errorCode A value representing the error code.
*/
+#endif /* RWADOXYGENEXTERNAL */
struct RwError
{
RwInt32 pluginID; /**< Internal Use */
@@ -5444,7 +5605,7 @@ extern RwInt32 _rwerror(RwInt32 code, ...);
*/
/**
- * \ingroup datatypes
+ * \ingroup rwdebug
* RwDebugType
* This type represents the different types of debug and
* trace messages that can be sent to the currently installed debug handler
@@ -5461,7 +5622,7 @@ enum RwDebugType
typedef enum RwDebugType RwDebugType;
/**
- * \ingroup datatypes
+ * \ingroup rwdebug
* \ref RwDebugHandler
* This type represents the
* function called from \ref RwDebugSendMessage for sending a message to the
@@ -5508,9 +5669,12 @@ extern void _rwDebugSendMessage(RwDebugType type,
/* Sending a message */
extern RwChar *_rwdberrcommon(RwInt32 code, ...);
+
+#if (!defined(DOXYGEN))
+/* Doxy doesn't appear to like the __RWFORMAT__ attribute */
extern RwChar *_rwdbsprintf(const RwChar * format,
...) __RWFORMAT__(printf, 1, 2);
-
+#endif /* (!defined(DOXYGEN)) */
#ifdef __cplusplus
}
@@ -5574,6 +5738,8 @@ enum RwEngineStatus
typedef enum RwEngineStatus RwEngineStatus;
typedef struct RwGlobals RwGlobals;
+
+#if (!defined(DOXYGEN))
struct RwGlobals
{
#ifdef RWDEBUG
@@ -5632,6 +5798,7 @@ struct RwModuleInfo
RwInt32 globalsOffset;
RwInt32 numInstances;
};
+#endif /* (!defined(DOXYGEN)) */
@@ -5648,7 +5815,13 @@ extern "C"
extern RwUInt32 ourGlobals[RWGLOBALSIZE / sizeof(RwUInt32)];
#define RwEngineInstance ourGlobals
#else /* RWGLOBALSIZE */
+
+#ifdef _RWDLL
+__declspec(dllimport) extern void *RwEngineInstance;
+#else
extern void *RwEngineInstance;
+#endif
+
#endif /* RWGLOBALSIZE */
extern RwInt8 _rwMsbBit[];
@@ -5663,39 +5836,45 @@ extern RwInt8 _rwMsbBit[];
#define RWRESOURCESGLOBAL(var) (RWPLUGINOFFSET(rwResourcesGlobals, \
RwEngineInstance, resourcesModule.globalsOffset)->var)
+#ifndef RWADOXYGENEXTERNAL
/**
- * \ingroup datatypes
- * \typedef RwResEntry
+ * \ingroup rwresources
+ * \struct RwResEntry
* RwResEntry object. Instanced data block in resources arena.
* This should be considered an opaque
* type. Use the RwResEntry API functions to access.
*/
+#endif /* RWADOXYGENEXTERNAL */
+
typedef struct RwResEntry RwResEntry;
+#ifndef RWADOXYGENEXTERNAL
/**
- * \ingroup datatypes
- * \typedef RwResEntryDestroyNotify
- * This type represents the function
+ * \ingroup rwresources
+ * \ref RwResEntryDestroyNotify type represents the function
* called from \ref RwResourcesFreeResEntry (and indirectly from
* \ref RwResourcesEmptyArena) immediately before the memory used by the
* specified resources entry is released.
*
* \param resEntry Pointer to the instanced data.
*/
+#endif /* RWADOXYGENEXTERNAL */
typedef void (*RwResEntryDestroyNotify) (RwResEntry * resEntry);
#if (!defined(DOXYGEN))
struct RwResEntry
{
- RwLLLink link; /**< Node in the list of resource elements */
- RwInt32 size; /**< Size of this node */
- void *owner; /**< Owner of this node */
- RwResEntry **ownerRef; /**< Pointer to pointer to this (enables de-alloc) */
- RwResEntryDestroyNotify destroyNotify; /**< This is called right before destruction */
+ RwLLLink link; /* Node in the list of resource elements */
+ RwInt32 size; /* Size of this node */
+ void *owner; /* Owner of this node */
+ RwResEntry **ownerRef; /* Pointer to pointer to this (enables de-alloc) */
+ RwResEntryDestroyNotify destroyNotify; /* This is called right before destruction */
};
#endif /* (!defined(DOXYGEN)) */
typedef struct rwResources rwResources;
+
+#if (!defined(DOXYGEN))
struct rwResources
{
RwInt32 maxSize;
@@ -5711,11 +5890,13 @@ struct rwResources
RwLinkList *usedEntries;
};
+
typedef struct rwResourcesGlobals rwResourcesGlobals;
struct rwResourcesGlobals
{
rwResources res;
};
+#endif /* (!defined(DOXYGEN)) */
#ifdef __cplusplus
@@ -5768,8 +5949,9 @@ extern RwModuleInfo resourcesModule;
*/
typedef struct RwRGBAReal RwRGBAReal;
+#ifndef RWADOXYGENEXTERNAL
/**
- * \ingroup datatypes
+ * \ingroup rwrgba
* \struct RwRGBAReal
* This structure represents a RGBA color which has
* components specified as real values.
@@ -5785,6 +5967,7 @@ typedef struct RwRGBAReal RwRGBAReal;
* value 0 generally corresponds to the associcated component in an
* RwRGBAReal with the value 0.0.
*/
+#endif /* RWADOXYGENEXTERNAL */
struct RwRGBAReal
{
RwReal red; /**< red component */
@@ -5799,11 +5982,14 @@ struct RwRGBAReal
#endif /* (!defined(RwRGBARealAssign)) */
typedef struct RwRGBA RwRGBA;
+#ifndef RWADOXYGENEXTERNAL
/**
- * \ingroup datatypes
+ * \ingroup rwrgba
* \struct RwRGBA
* This structure represents a RGBA color
- * which has integer components specified in the range 0 to 255. */
+ * which has integer components specified in the range 0 to 255.
+ */
+#endif /* RWADOXYGENEXTERNAL */
struct RwRGBA
{
RwUInt8 red; /**< red component */
@@ -5947,6 +6133,7 @@ extern void RwRGBARealFromRwRGBA(RwRGBAReal *result,
/* Matrix stream format */
typedef struct rwStreamMatrix RwMatrixChunkInfo;
typedef struct rwStreamMatrix rwStreamMatrix;
+#if (!defined(DOXYGEN))
struct rwStreamMatrix
{
RwV3d right;
@@ -5955,6 +6142,7 @@ struct rwStreamMatrix
RwV3d pos;
RwInt32 type;
};
+#endif /* (!defined(DOXYGEN)) */
/****************************************************************************
@@ -6009,11 +6197,14 @@ extern RwMatrixChunkInfo *RwMatrixChunkInfoRead(RwStream * stream,
*/
typedef struct RwChunkHeaderInfo RwChunkHeaderInfo;
+#ifndef RWADOXYGENEXTERNAL
/**
- * \ingroup datatypes
+ * \ingroup rwstream
* \struct RwChunkHeaderInfo
* Holds data for a chunk header read from a
- * stream with \ref RwStreamReadChunkHeaderInfo. */
+ * stream with \ref RwStreamReadChunkHeaderInfo.
+ */
+#endif /* RWADOXYGENEXTERNAL */
struct RwChunkHeaderInfo
{
RwUInt32 type; /**< chunk ID - see \ref RwStreamFindChunk */
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index ef322a9a..e3985365 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -42,37 +42,37 @@ HEADER_DIRECTORIES(header_list)
include_directories(${header_list})
-add_executable(re3 ${Sources})
-target_link_libraries(re3 librw)
-target_link_libraries(re3 Threads::Threads)
+add_executable(reVC ${Sources})
+target_link_libraries(reVC librw)
+target_link_libraries(reVC Threads::Threads)
if(${RE3_AUDIO} STREQUAL "OAL")
- target_link_libraries(re3 ${OPENAL_LIBRARY})
- target_link_libraries(re3 ${MPG123_LIBRARIES})
- target_link_libraries(re3 ${SNDFILE_LIBRARIES})
+ target_link_libraries(reVC ${OPENAL_LIBRARY})
+ target_link_libraries(reVC ${MPG123_LIBRARIES})
+ target_link_libraries(reVC ${SNDFILE_LIBRARIES})
endif()
-target_include_directories(re3
+target_include_directories(reVC
INTERFACE
$<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}>
)
-target_compile_definitions(re3
+target_compile_definitions(reVC
PRIVATE
"$<IF:$<CONFIG:DEBUG>,DEBUG,NDEBUG>"
PUBLIC
"RW_${RE3_PLATFORM}"
)
-target_compile_definitions(re3 PRIVATE LIBRW=1 AUDIO_OAL=1)
+target_compile_definitions(reVC PRIVATE LIBRW=1 AUDIO_OAL=1)
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
- target_compile_options(re3
+ target_compile_options(reVC
PRIVATE
"-Wall"
)
if (NOT RE3_PLATFORM_PS2)
- target_compile_options(re3
+ target_compile_options(reVC
PRIVATE
"-Wextra"
"-Wdouble-promotion"
@@ -80,13 +80,13 @@ if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" OR CMAKE_CXX_COMPILER_ID STREQUAL "Clang
)
endif()
elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
- target_compile_options(re3
+ target_compile_options(reVC
PUBLIC
/wd4996 /wd4244
)
endif()
-set_target_properties(re3
+set_target_properties(reVC
PROPERTIES
C_STANDARD 11
C_EXTENSIONS OFF
@@ -98,14 +98,14 @@ set_target_properties(re3
)
if(RE3_INSTALL)
- target_include_directories(re3
+ target_include_directories(reVC
INTERFACE
$<INSTALL_INTERFACE:${RE3_INSTALL_INCLUDEDIR}>
)
install(
- TARGETS re3
- EXPORT re3-targets
+ TARGETS reVC
+ EXPORT reVC-targets
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
diff --git a/src/animation/AnimBlendAssocGroup.cpp b/src/animation/AnimBlendAssocGroup.cpp
index fe419f2a..83c1742a 100644
--- a/src/animation/AnimBlendAssocGroup.cpp
+++ b/src/animation/AnimBlendAssocGroup.cpp
@@ -8,16 +8,22 @@
#include "General.h"
#include "RwHelper.h"
+#include "ModelIndices.h"
#include "ModelInfo.h"
#include "AnimManager.h"
#include "RpAnimBlend.h"
#include "AnimBlendAssociation.h"
#include "AnimBlendAssocGroup.h"
+//--MIAMI: file done
+
CAnimBlendAssocGroup::CAnimBlendAssocGroup(void)
{
+ animBlock = nil;
assocList = nil;
numAssociations = 0;
+ firstAnimId = 0;
+ groupId = -1;
}
CAnimBlendAssocGroup::~CAnimBlendAssocGroup(void)
@@ -38,7 +44,7 @@ CAnimBlendAssocGroup::DestroyAssociations(void)
CAnimBlendAssociation*
CAnimBlendAssocGroup::GetAnimation(uint32 id)
{
- return &assocList[id];
+ return &assocList[id - firstAnimId];
}
CAnimBlendAssociation*
@@ -48,6 +54,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;
}
@@ -97,7 +104,7 @@ strcmpIgnoringDigits(const char *s1, const char *s2)
c2 = toupper(c2);
#endif
- if(c1 != c2)
+ if(c1 && c2 && c1 != c2)
return false;
}
}
@@ -107,6 +114,15 @@ GetModelFromName(const char *name)
{
int i;
CBaseModelInfo *mi;
+ char playername[32];
+
+ if(strncasecmp(name, "CSplay", 6) == 0 &&
+ strncasecmp(CModelInfo::GetModelInfo(MI_PLAYER)->GetName(), "ig", 2) == 0){
+ strcpy(playername, CModelInfo::GetModelInfo(MI_PLAYER)->GetName());
+ playername[0] = 'C';
+ playername[1] = 'S';
+ name = playername;
+ }
for(i = 0; i < MODELINFOSIZE; i++){
mi = CModelInfo::GetModelInfo(i);
@@ -123,8 +139,7 @@ CAnimBlendAssocGroup::CreateAssociations(const char *name)
int i;
CAnimBlock *animBlock;
- if(assocList)
- DestroyAssociations();
+ DestroyAssociations();
animBlock = CAnimManager::GetAnimationBlock(name);
assocList = new CAnimBlendAssociation[animBlock->numAnims];
@@ -133,17 +148,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->GetName());
- 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->GetName());
+ 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;
}
@@ -153,10 +169,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];
@@ -164,7 +178,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..2f4739a6 100644
--- a/src/animation/AnimBlendAssociation.cpp
+++ b/src/animation/AnimBlendAssociation.cpp
@@ -7,8 +7,11 @@
#include "AnimBlendAssociation.h"
#include "MemoryMgr.h"
+//--MIAMI: file done
+
CAnimBlendAssociation::CAnimBlendAssociation(void)
{
+ groupId = -1;
nodes = nil;
blendAmount = 1.0f;
blendDelta = 0.0f;
@@ -54,8 +57,8 @@ CAnimBlendAssociation::AllocateAnimBlendNodeArray(int n)
void
CAnimBlendAssociation::FreeAnimBlendNodeArray(void)
{
- assert(nodes != nil);
- RwFreeAlign(nodes);
+ if(nodes)
+ RwFreeAlign(nodes);
}
void
@@ -75,7 +78,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 +96,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 +133,21 @@ 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);
+ if(hierarchy->compressed2){
+ for(i = 0; i < numNodes; i++)
+ if(nodes[i].sequence)
+ nodes[i].SetupKeyFrameCompressed();
+ }else{
+ for(i = 0; i < numNodes; i++)
+ if(nodes[i].sequence)
+ nodes[i].FindKeyFrame(currentTime);
+ }
}
void
@@ -147,13 +163,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 +189,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 80927da2..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;
- int 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.cpp b/src/animation/AnimBlendClumpData.cpp
index 92515427..4e8f3153 100644
--- a/src/animation/AnimBlendClumpData.cpp
+++ b/src/animation/AnimBlendClumpData.cpp
@@ -3,6 +3,7 @@
#include "AnimBlendClumpData.h"
#include "MemoryMgr.h"
+//--MIAMI: file done
CAnimBlendClumpData::CAnimBlendClumpData(void)
{
diff --git a/src/animation/AnimBlendClumpData.h b/src/animation/AnimBlendClumpData.h
index fc74b42d..315cbd8a 100644
--- a/src/animation/AnimBlendClumpData.h
+++ b/src/animation/AnimBlendClumpData.h
@@ -11,23 +11,19 @@ struct AnimBlendFrameData
IGNORE_TRANSLATION = 4,
VELOCITY_EXTRACTION = 8,
VELOCITY_EXTRACTION_3D = 0x10,
+ UPDATE_KEYFRAMES = 0x20,
+ UNK_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
@@ -35,9 +31,6 @@ class CAnimBlendClumpData
public:
CAnimBlendLink link;
int32 numFrames;
-#ifdef PED_SKIN
- int32 modelNumber; // doesn't seem to be used
-#endif
CVector *velocity;
// order of frames is determined by RW hierarchy
AnimBlendFrameData *frames;
@@ -45,11 +38,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 c7800de5..f3e90818 100644
--- a/src/animation/AnimBlendHierarchy.cpp
+++ b/src/animation/AnimBlendHierarchy.cpp
@@ -2,6 +2,9 @@
#include "AnimBlendSequence.h"
#include "AnimBlendHierarchy.h"
+#include "AnimManager.h"
+
+//--MIAMI: file done
CAnimBlendHierarchy::CAnimBlendHierarchy(void)
{
@@ -15,9 +18,10 @@ CAnimBlendHierarchy::CAnimBlendHierarchy(void)
void
CAnimBlendHierarchy::Shutdown(void)
{
+ CAnimManager::RemoveFromUncompressedCache(this);
RemoveAnimSequences();
+ totalLength = 0.0f;
compressed = 0;
- linkPtr = nil;
}
void
@@ -30,13 +34,43 @@ void
CAnimBlendHierarchy::CalcTotalTime(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].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++){
- 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].GetKeyFrameCompressed(sequences[i].numFrames-1)->deltaTime/60.0f);
+ for(j = sequences[i].numFrames-1; j >= 1; j--){
+ KeyFrame *kf1 = sequences[i].GetKeyFrameCompressed(j);
+ KeyFrame *kf2 = sequences[i].GetKeyFrameCompressed(j-1);
+ kf1->deltaTime -= kf2->deltaTime;
+ }
}
}
@@ -52,34 +86,25 @@ CAnimBlendHierarchy::RemoveQuaternionFlips(void)
void
CAnimBlendHierarchy::RemoveAnimSequences(void)
{
- if(sequences)
- delete[] sequences;
+ delete[] sequences;
+ sequences = nil;
numSequences = 0;
}
void
CAnimBlendHierarchy::Uncompress(void)
{
-#ifdef ANIM_COMPRESSION
- int i;
- assert(compressed);
- for(i = 0; i < numSequences; i++)
- sequences[i].Uncompress();
-#endif
- if(totalLength == 0.0f)
- CalcTotalTime();
compressed = 0;
+ if(totalLength == 0.0f){
+ RemoveQuaternionFlips();
+ CalcTotalTime();
+ }
}
void
CAnimBlendHierarchy::RemoveUncompressedData(void)
{
-#ifdef ANIM_COMPRESSION
- int i;
- assert(!compressed);
- for(i = 0; i < numSequences; i++)
- sequences[i].RemoveUncompressedData();
-#endif
+ // useless
compressed = 1;
}
diff --git a/src/animation/AnimBlendHierarchy.h b/src/animation/AnimBlendHierarchy.h
index e35b4925..424a925d 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; // not really used
+ bool compressed; // not really used
+ bool compressed2; // not really used
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..ac1328eb 100644
--- a/src/animation/AnimBlendNode.cpp
+++ b/src/animation/AnimBlendNode.cpp
@@ -3,6 +3,8 @@
#include "AnimBlendAssociation.h"
#include "AnimBlendNode.h"
+//--MIAMI: file done
+
void
CAnimBlendNode::Init(void)
{
@@ -92,20 +94,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 +119,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)->deltaTime/60.0f;
+
+ CalcDeltasCompressed();
+ return true;
+}
+
void
CAnimBlendNode::CalcDeltas(void)
{
@@ -130,6 +153,20 @@ CAnimBlendNode::CalcDeltas(void)
}
void
+CAnimBlendNode::CalcDeltasCompressed(void)
+{
+ if((sequence->type & CAnimBlendSequence::KF_ROT) == 0)
+ return;
+ KeyFrame *kfA = sequence->GetKeyFrameCompressed(frameA);
+ KeyFrame *kfB = sequence->GetKeyFrameCompressed(frameB);
+ float cos = DotProduct(kfA->rotation, kfB->rotation);
+ 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 +175,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;
diff --git a/src/animation/AnimBlendNode.h b/src/animation/AnimBlendNode.h
index 89924d6a..9446e1ae 100644
--- a/src/animation/AnimBlendNode.h
+++ b/src/animation/AnimBlendNode.h
@@ -22,7 +22,9 @@ public:
bool Update(CVector &trans, CQuaternion &rot, float weight);
bool NextKeyFrame(void);
bool FindKeyFrame(float t);
+ bool SetupKeyFrameCompressed(void);
void CalcDeltas(void);
+ void CalcDeltasCompressed(void);
void GetCurrentTranslation(CVector &trans, float weight);
void GetEndTranslation(CVector &trans, float weight);
};
diff --git a/src/animation/AnimBlendSequence.cpp b/src/animation/AnimBlendSequence.cpp
index c958b71a..3c675d4e 100644
--- a/src/animation/AnimBlendSequence.cpp
+++ b/src/animation/AnimBlendSequence.cpp
@@ -3,22 +3,23 @@
#include "AnimBlendSequence.h"
#include "MemoryHeap.h"
+//--MIAMI: file done
+
CAnimBlendSequence::CAnimBlendSequence(void)
{
type = 0;
numFrames = 0;
keyFrames = nil;
keyFramesCompressed = nil;
-#ifdef PED_SKIN
boneTag = -1;
-#endif
}
CAnimBlendSequence::~CAnimBlendSequence(void)
{
- assert(keyFramesCompressed == nil);
if(keyFrames)
RwFree(keyFrames);
+ if(keyFramesCompressed)
+ RwFree(keyFramesCompressed);
}
void
@@ -28,18 +29,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;
}
@@ -63,119 +67,6 @@ CAnimBlendSequence::RemoveQuaternionFlips(void)
}
}
-void
-CAnimBlendSequence::Uncompress(void)
-{
- int i;
-
- if(numFrames == 0)
- return;
-
- PUSH_MEMID(MEMID_ANIMATION);
-
- float rotScale = 1.0f/4096.0f;
- float timeScale = 1.0f/60.0f;
- float transScale = 1.0f/128.0f;
- if(type & KF_TRANS){
- void *newKfs = RwMalloc(numFrames * sizeof(KeyFrameTrans));
- KeyFrameTransCompressed *ckf = (KeyFrameTransCompressed*)keyFramesCompressed;
- KeyFrameTrans *kf = (KeyFrameTrans*)newKfs;
- for(i = 0; i < numFrames; i++){
- kf->rotation.x = ckf->rot[0]*rotScale;
- kf->rotation.y = ckf->rot[1]*rotScale;
- kf->rotation.z = ckf->rot[2]*rotScale;
- kf->rotation.w = ckf->rot[3]*rotScale;
- kf->deltaTime = ckf->deltaTime*timeScale;
- kf->translation.x = ckf->trans[0]*transScale;
- kf->translation.y = ckf->trans[1]*transScale;
- kf->translation.z = ckf->trans[2]*transScale;
- kf++;
- ckf++;
- }
- keyFrames = newKfs;
- }else{
- void *newKfs = RwMalloc(numFrames * sizeof(KeyFrame));
- KeyFrameCompressed *ckf = (KeyFrameCompressed*)keyFramesCompressed;
- KeyFrame *kf = (KeyFrame*)newKfs;
- for(i = 0; i < numFrames; i++){
- kf->rotation.x = ckf->rot[0]*rotScale;
- kf->rotation.y = ckf->rot[1]*rotScale;
- kf->rotation.z = ckf->rot[2]*rotScale;
- kf->rotation.w = ckf->rot[3]*rotScale;
- kf->deltaTime = ckf->deltaTime*timeScale;
- kf++;
- ckf++;
- }
- keyFrames = newKfs;
- }
- REGISTER_MEMPTR(&keyFrames);
-
- RwFree(keyFramesCompressed);
- keyFramesCompressed = nil;
-
- POP_MEMID();
-}
-
-void
-CAnimBlendSequence::CompressKeyframes(void)
-{
- int i;
-
- if(numFrames == 0)
- return;
-
- PUSH_MEMID(MEMID_ANIMATION);
-
- float rotScale = 4096.0f;
- float timeScale = 60.0f;
- float transScale = 128.0f;
- if(type & KF_TRANS){
- void *newKfs = RwMalloc(numFrames * sizeof(KeyFrameTransCompressed));
- KeyFrameTransCompressed *ckf = (KeyFrameTransCompressed*)newKfs;
- KeyFrameTrans *kf = (KeyFrameTrans*)keyFrames;
- for(i = 0; i < numFrames; i++){
- ckf->rot[0] = kf->rotation.x*rotScale;
- ckf->rot[1] = kf->rotation.y*rotScale;
- ckf->rot[2] = kf->rotation.z*rotScale;
- ckf->rot[3] = kf->rotation.w*rotScale;
- ckf->deltaTime = kf->deltaTime*timeScale + 0.5f;
- ckf->trans[0] = kf->translation.x*transScale;
- ckf->trans[1] = kf->translation.y*transScale;
- ckf->trans[2] = kf->translation.z*transScale;
- kf++;
- ckf++;
- }
- keyFramesCompressed = newKfs;
- }else{
- void *newKfs = RwMalloc(numFrames * sizeof(KeyFrameCompressed));
- KeyFrameCompressed *ckf = (KeyFrameCompressed*)newKfs;
- KeyFrame *kf = (KeyFrame*)keyFrames;
- for(i = 0; i < numFrames; i++){
- ckf->rot[0] = kf->rotation.x*rotScale;
- ckf->rot[1] = kf->rotation.y*rotScale;
- ckf->rot[2] = kf->rotation.z*rotScale;
- ckf->rot[3] = kf->rotation.w*rotScale;
- ckf->deltaTime = kf->deltaTime*timeScale + 0.5f;
- kf++;
- ckf++;
- }
- keyFramesCompressed = newKfs;
- }
- REGISTER_MEMPTR(&keyFramesCompressed);
-
- POP_MEMID();
-}
-
-void
-CAnimBlendSequence::RemoveUncompressedData(void)
-{
- if(numFrames == 0)
- return;
- CompressKeyframes();
- RwFree(keyFrames);
- keyFrames = nil;
-}
-
#ifdef USE_CUSTOM_ALLOCATOR
bool
CAnimBlendSequence::MoveMemory(void)
diff --git a/src/animation/AnimBlendSequence.h b/src/animation/AnimBlendSequence.h
index c6e70f22..1c2531ce 100644
--- a/src/animation/AnimBlendSequence.h
+++ b/src/animation/AnimBlendSequence.h
@@ -16,15 +16,6 @@ struct KeyFrameTrans : KeyFrame {
CVector translation;
};
-struct KeyFrameCompressed {
- int16 rot[4]; // 4096
- int16 deltaTime; // 60
-};
-
-struct KeyFrameTransCompressed : KeyFrameCompressed {
- int16 trans[3]; // 128
-};
-
// The sequence of key frames of one animated node
class CAnimBlendSequence
@@ -37,32 +28,28 @@ 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];
}
+ KeyFrame *GetKeyFrameCompressed(int n) {
+ return type & KF_TRANS ?
+ &((KeyFrameTrans*)keyFramesCompressed)[n] :
+ &((KeyFrame*)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 877dcd76..0aa6486b 100644
--- a/src/animation/AnimManager.cpp
+++ b/src/animation/AnimManager.cpp
@@ -10,6 +10,9 @@
#include "AnimBlendAssociation.h"
#include "AnimBlendAssocGroup.h"
#include "AnimManager.h"
+#include "Streaming.h"
+
+//--MIAMI: file done
CAnimBlock CAnimManager::ms_aAnimBlocks[NUMANIMBLOCKS];
CAnimBlendHierarchy CAnimManager::ms_aAnimations[NUMANIMATIONS];
@@ -32,26 +35,26 @@ AnimAssocDesc aStdAnimDescs[] = {
{ ANIM_IDLE_ARMED, ASSOC_REPEAT | ASSOC_PARTIAL },
{ ANIM_IDLE_CHAT, ASSOC_REPEAT | ASSOC_PARTIAL },
{ ANIM_IDLE_TAXI, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_KO_SHOT_FRONT1, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION | ASSOC_FRONTAL },
- { ANIM_KO_SHOT_FRONT2, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION | ASSOC_FRONTAL },
- { ANIM_KO_SHOT_FRONT3, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION | ASSOC_FRONTAL },
- { ANIM_KO_SHOT_FRONT4, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION | ASSOC_FRONTAL },
- { ANIM_KO_SHOT_FACE, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION | ASSOC_FRONTAL },
+ { ANIM_KO_SHOT_FRONT1, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION | ASSOC_FRONTAL },
+ { ANIM_KO_SHOT_FRONT2, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION | ASSOC_FRONTAL },
+ { ANIM_KO_SHOT_FRONT3, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION | ASSOC_FRONTAL },
+ { ANIM_KO_SHOT_FRONT4, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION | ASSOC_FRONTAL },
+ { ANIM_KO_SHOT_FACE, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION | ASSOC_FRONTAL },
{ ANIM_KO_SHOT_STOM, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
- { ANIM_KO_SHOT_ARML, ASSOC_PARTIAL | ASSOC_FRONTAL },
- { ANIM_KO_SHOT_ARMR, ASSOC_PARTIAL | ASSOC_FRONTAL },
+ { ANIM_KO_SHOT_ARML, ASSOC_PARTIAL | ASSOC_FRONTAL },
+ { ANIM_KO_SHOT_ARMR, ASSOC_PARTIAL | ASSOC_FRONTAL },
{ ANIM_KO_SHOT_LEGL, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
{ ANIM_KO_SHOT_LEGR, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
- { ANIM_KD_LEFT, ASSOC_PARTIAL | ASSOC_FRONTAL },
- { ANIM_KD_RIGHT, ASSOC_PARTIAL | ASSOC_FRONTAL },
+ { ANIM_KD_LEFT, ASSOC_PARTIAL | ASSOC_FRONTAL },
+ { ANIM_KD_RIGHT, ASSOC_PARTIAL | ASSOC_FRONTAL },
{ ANIM_KO_SKID_FRONT, ASSOC_PARTIAL },
{ ANIM_KO_SPIN_R, ASSOC_PARTIAL },
- { ANIM_KO_SKID_BACK, ASSOC_PARTIAL | ASSOC_FRONTAL },
+ { ANIM_KO_SKID_BACK, ASSOC_PARTIAL | ASSOC_FRONTAL },
{ ANIM_KO_SPIN_L, ASSOC_PARTIAL },
- { ANIM_SHOT_FRONT_PARTIAL, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_NOWALK },
- { ANIM_SHOT_LEFT_PARTIAL, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_NOWALK },
- { ANIM_SHOT_BACK_PARTIAL, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_NOWALK },
- { ANIM_SHOT_RIGHT_PARTIAL, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_NOWALK },
+ { ANIM_SHOT_FRONT_PARTIAL, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_NOWALK },
+ { ANIM_SHOT_LEFT_PARTIAL, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_NOWALK },
+ { ANIM_SHOT_BACK_PARTIAL, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_NOWALK },
+ { ANIM_SHOT_RIGHT_PARTIAL, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_NOWALK },
{ ANIM_HIT_FRONT, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
{ ANIM_HIT_LEFT, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_HIT_BACK, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
@@ -62,29 +65,8 @@ AnimAssocDesc aStdAnimDescs[] = {
{ ANIM_HIT_HEAD, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
{ ANIM_HIT_WALK, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
{ ANIM_HIT_WALL, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
- { ANIM_FLOOR_HIT_F, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_FRONTAL },
+ { ANIM_FLOOR_HIT_F, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_FRONTAL },
{ ANIM_HIT_BEHIND, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_PUNCH_R, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_KICK_FLOOR, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_WEAPON_BAT_H, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_WEAPON_BAT_V, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_WEAPON_HGUN_BODY, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_NOWALK },
- { ANIM_WEAPON_AK_BODY, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_WEAPON_PUMP, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_WEAPON_SNIPER, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_WEAPON_THROW, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_WEAPON_THROWU, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_WEAPON_START_THROW, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_BOMBER, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_NOWALK },
- { ANIM_HGUN_RELOAD, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_NOWALK },
- { ANIM_AK_RELOAD, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_NOWALK },
- { 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 },
{ ANIM_FIGHT_IDLE, ASSOC_REPEAT },
{ ANIM_FIGHT2_IDLE, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_FIGHT_SH_F, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
@@ -96,7 +78,18 @@ AnimAssocDesc aStdAnimDescs[] = {
{ ANIM_FIGHT_PUNCH, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_FIGHT_ROUNDHOUSE, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
{ ANIM_FIGHT_LONGKICK, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
- { ANIM_FIGHT_PPUNCH, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_NOWALK },
+ { ANIM_FIGHT_PPUNCH, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_NOWALK },
+ { ANIM_FIGHT_JAB, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_FIGHT_ELBOW_L, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_FIGHT_ELBOW_R, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_FIGHT_BKICK_L, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_FIGHT_BKICK_R, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_BOMBER, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_PUNCH_R, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_FIGHT_PPUNCH2, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_KICK_FLOOR, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_WEAPON_THROWU, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_FIGHT_SH_BACK, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
{ ANIM_CAR_JACKED_RHS, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
{ ANIM_CAR_LJACKED_RHS, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
{ ANIM_CAR_JACKED_LHS, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
@@ -115,6 +108,7 @@ AnimAssocDesc aStdAnimDescs[] = {
{ ANIM_CAR_CLOSEDOOR_LOW_LHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_CAR_ROLLDOOR, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_CAR_ROLLDOOR_LOW, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_CAR_JUMPIN_LHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_CAR_GETOUT_LHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_CAR_GETOUT_LOW_LHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_CAR_CLOSE_LHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
@@ -130,39 +124,41 @@ AnimAssocDesc aStdAnimDescs[] = {
{ ANIM_CAR_CLOSEDOOR_LOW_RHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_CAR_SHUFFLE_RHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_CAR_LSHUFFLE_RHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_CAR_SIT, ASSOC_DELETEFADEDOUT },
- { ANIM_CAR_LSIT, ASSOC_DELETEFADEDOUT },
- { ANIM_CAR_SITP, ASSOC_DELETEFADEDOUT },
- { ANIM_CAR_SITPLO, ASSOC_DELETEFADEDOUT },
- { ANIM_DRIVE_L, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
- { ANIM_DRIVE_R, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
- { ANIM_DRIVE_LOW_L, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
- { ANIM_DRIVE_LOW_R, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
- { ANIM_DRIVEBY_L, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
- { ANIM_DRIVEBY_R, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
- { ANIM_CAR_LB, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
- { ANIM_DRIVE_BOAT, ASSOC_DELETEFADEDOUT },
+ { ANIM_CAR_SIT, ASSOC_DELETEFADEDOUT},
+ { ANIM_CAR_LSIT, ASSOC_DELETEFADEDOUT},
+ { ANIM_CAR_SITP, ASSOC_DELETEFADEDOUT},
+ { ANIM_CAR_SITPLO, ASSOC_DELETEFADEDOUT},
+ { ANIM_DRIVE_L, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
+ { ANIM_DRIVE_R, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
+ { ANIM_DRIVE_LOW_L, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
+ { ANIM_DRIVE_LOW_R, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
+ { ANIM_DRIVEBY_L, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
+ { ANIM_DRIVEBY_R, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
+ { ANIM_DRIVEBY_LOW_L, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
+ { ANIM_DRIVEBY_LOW_R, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
+ { ANIM_CAR_LB, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
+ { ANIM_DRIVE_BOAT, ASSOC_DELETEFADEDOUT | ASSOC_DRIVING },
+ { ANIM_DRIVE_BOAT_L, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
+ { ANIM_DRIVE_BOAT_R, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
+ { ANIM_BOAT_LB, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
+ { ANIM_BIKE_PICKUP_R, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_BIKE_PICKUP_L, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_BIKE_PULLUP_R, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_BIKE_PULLUP_L, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_BIKE_ELBOW_R, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_BIKE_ELBOW_L, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_BIKE_FALL_OFF, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
+ { ANIM_BIKE_FALL_R, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
{ ANIM_CAR_GETOUT_RHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_CAR_GETOUT_LOW_RHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_CAR_CLOSE_RHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_CAR_HOOKERTALK, ASSOC_REPEAT | ASSOC_PARTIAL },
- { ANIM_COACH_OPEN_L, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_COACH_OPEN_R, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_COACH_IN_L, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_COACH_IN_R, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_COACH_OUT_L, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_TRAIN_GETIN, ASSOC_PARTIAL },
- { ANIM_TRAIN_GETOUT, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_IDLE_STANCE2, ASSOC_PARTIAL },
+ { ANIM_IDLE_STANCE3, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_CAR_CRAWLOUT_RHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_CAR_CRAWLOUT_RHS2, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_VAN_OPEN_L, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_VAN_GETIN_L, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_VAN_CLOSE_L, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_VAN_GETOUT_L, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_VAN_OPEN, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_VAN_GETIN, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_VAN_CLOSE, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
- { ANIM_VAN_GETOUT, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_CAR_ROLLOUT_LHS, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION | ASSOC_HAS_X_TRANSLATION },
+ { ANIM_CAR_ROLLOUT_RHS, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION | ASSOC_HAS_X_TRANSLATION },
{ ANIM_GETUP1, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
{ ANIM_GETUP2, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
{ ANIM_GETUP3, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
@@ -174,33 +170,132 @@ AnimAssocDesc aStdAnimDescs[] = {
{ ANIM_FALL_GLIDE, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
{ ANIM_FALL_LAND, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
{ ANIM_FALL_COLLAPSE, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
+ { ANIM_FALL_BACK, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
+ { ANIM_FALL_FRONT, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_FRONTAL },
{ ANIM_EV_STEP, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
- { ANIM_EV_DIVE, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION | ASSOC_FRONTAL },
- { ANIM_XPRESS_SCRATCH, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_IDLE },
+ { ANIM_EV_DIVE, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION | ASSOC_FRONTAL },
+ { ANIM_XPRESS_SCRATCH, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_IDLE },
{ ANIM_ROAD_CROSS, ASSOC_REPEAT | ASSOC_PARTIAL },
{ ANIM_TURN_180, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_ARREST_GUN, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
{ ANIM_DROWN, ASSOC_PARTIAL },
- { ANIM_CPR, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_DUCK_DOWN, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
{ ANIM_DUCK_LOW, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
+ { ANIM_WEAPON_CROUCH, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
{ ANIM_RBLOCK_CSHOOT, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
- { ANIM_WEAPON_THROWU2, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_HANDSUP, ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
{ ANIM_HANDSCOWER, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
- { ANIM_FUCKU, ASSOC_DELETEFADEDOUT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_NOWALK },
- { ANIM_PHONE_IN, ASSOC_PARTIAL },
+ { ANIM_FUCKU, ASSOC_DELETEFADEDOUT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_NOWALK },
+ { ANIM_PHONE_IN, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_PHONE_OUT, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_PHONE_TALK, ASSOC_REPEAT | ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
+ { ANIM_SEAT_DOWN, ASSOC_DELETEFADEDOUT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_SEAT_UP, ASSOC_DELETEFADEDOUT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_SEAT_IDLE, ASSOC_REPEAT | ASSOC_DELETEFADEDOUT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_SEAT_DOWN2, ASSOC_DELETEFADEDOUT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_ATM, ASSOC_DELETEFADEDOUT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_ABSEIL, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL },
+};
+AnimAssocDesc aVanAnimDescs[] = {
+ { ANIM_VAN_OPEN_L, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_VAN_GETIN_L, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_VAN_CLOSE_L, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_VAN_GETOUT_L, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_VAN_OPEN, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_VAN_GETIN, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_VAN_CLOSE, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_VAN_GETOUT, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+};
+AnimAssocDesc aCoachAnimDescs[] = {
+ { ANIM_COACH_OPEN_L, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_COACH_OPEN_R, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_COACH_IN_L, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_COACH_IN_R, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_COACH_OUT_L, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+};
+AnimAssocDesc aBikeAnimDescs[] = {
+ { ANIM_BIKE_RIDE, ASSOC_DELETEFADEDOUT},
+ { ANIM_BIKE_STILL, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
+ { ANIM_BIKE_LEFT, ASSOC_PARTIAL | ASSOC_DRIVING },
+ { ANIM_BIKE_RIGHT, ASSOC_PARTIAL | ASSOC_DRIVING },
+ { ANIM_BIKE_BACK, ASSOC_PARTIAL | ASSOC_DRIVING },
+ { ANIM_BIKE_FWD, ASSOC_PARTIAL | ASSOC_DRIVING },
+ { ANIM_BIKE_PUSHES, ASSOC_REPEAT | ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
+ { ANIM_BIKE_JUMPON_R, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_BIKE_JUMPON_L, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_BIKE_KICK, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_BIKE_HIT, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_BIKE_GETOFF_RHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_BIKE_GETOFF_LHS, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_BIKE_GETOFF_BACK, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL | ASSOC_HAS_TRANSLATION },
+ { ANIM_BIKE_DRIVEBY_RHS, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
+ { ANIM_BIKE_DRIVEBY_LHS, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
+ { ANIM_BIKE_DRIVEBY_FT, ASSOC_DELETEFADEDOUT | ASSOC_PARTIAL | ASSOC_DRIVING },
+ { ANIM_BIKE_PASSENGER, 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_SPECIAL, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+};
+AnimAssocDesc aMedicAnimDescs[] = {
+ { ANIM_CPR, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+};
+AnimAssocDesc aSunbatheAnimDescs[] = {
+ { ANIM_SUNBATHE, 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_IDLE_STRETCH, ASSOC_DELETEFADEDOUT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_IDLE_TIME, ASSOC_DELETEFADEDOUT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_IDLE_SHOULDER, ASSOC_DELETEFADEDOUT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
+ { ANIM_IDLE_STRETCH_LEG, 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_FUKU, 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 },
};
AnimAssocDesc aStdAnimDescsSide[] = {
- { ANIM_WALK, ASSOC_REPEAT | ASSOC_MOVEMENT | ASSOC_HAS_TRANSLATION | ASSOC_WALK | ASSOC_HAS_X_TRANSLATION },
- { ANIM_RUN, ASSOC_REPEAT | ASSOC_MOVEMENT | ASSOC_HAS_TRANSLATION | ASSOC_WALK | ASSOC_HAS_X_TRANSLATION },
- { ANIM_SPRINT, ASSOC_REPEAT | ASSOC_MOVEMENT | ASSOC_HAS_TRANSLATION | ASSOC_WALK | ASSOC_HAS_X_TRANSLATION },
+ { ANIM_WALK, ASSOC_REPEAT | ASSOC_MOVEMENT | ASSOC_HAS_TRANSLATION | ASSOC_HAS_X_TRANSLATION | ASSOC_WALK },
+ { ANIM_RUN, ASSOC_REPEAT | ASSOC_MOVEMENT | ASSOC_HAS_TRANSLATION | ASSOC_HAS_X_TRANSLATION | ASSOC_WALK },
+ { ANIM_SPRINT, ASSOC_REPEAT | ASSOC_MOVEMENT | ASSOC_HAS_TRANSLATION | ASSOC_HAS_X_TRANSLATION | ASSOC_WALK },
{ ANIM_IDLE_STANCE, ASSOC_REPEAT },
{ ANIM_WALK_START, ASSOC_HAS_TRANSLATION | ASSOC_HAS_X_TRANSLATION },
};
-char const *aStdAnimations[] = {
+
+char const* aStdAnimations[] = {
"walk_civi",
"run_civi",
"sprint_panic",
@@ -208,7 +303,7 @@ char const *aStdAnimations[] = {
"walk_start",
"run_stop",
"run_stopR",
- "idle_cam",
+ "idle_hbhb",
"idle_hbhb",
"idle_tired",
"idle_armed",
@@ -246,27 +341,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",
- "FPS_PUNCH",
- "FPS_BAT",
- "FPS_UZI",
- "FPS_PUMP",
- "FPS_AK",
- "FPS_M16",
- "FPS_ROCKET",
"FIGHTIDLE",
"FIGHT2IDLE",
"FIGHTsh_F",
@@ -279,6 +353,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",
@@ -297,6 +382,7 @@ char const *aStdAnimations[] = {
"CAR_closedoorL_LHS",
"CAR_rolldoor",
"CAR_rolldoorLO",
+ "CAR_jumpin_LHS",
"CAR_getout_LHS",
"CAR_getoutL_LHS",
"CAR_close_LHS",
@@ -322,29 +408,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",
@@ -356,6 +444,8 @@ char const *aStdAnimations[] = {
"FALL_glide",
"FALL_land",
"FALL_collapse",
+ "FALL_back",
+ "FALL_front",
"EV_step",
"EV_dive",
"XPRESSscratch",
@@ -363,201 +453,515 @@ 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 *aPlayerAnimations[] = {
+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* 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 *aPlayerStrafeBackAnimations[] = {
- "walk_player_back",
- "run_player_back",
- "run_player_back",
+char const* aSkateAnimations[] = {
+ "skate_run",
+ "skate_sprint",
+ "skate_sprint",
+ "skate_idle",
+};
+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",
+};
+
#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 },
{ "playerback", "ped", MI_COP, awc(aPlayerStrafeBackAnimations), aStdAnimDescs },
{ "playerleft", "ped", MI_COP, awc(aPlayerStrafeLeftAnimations), aStdAnimDescsSide },
{ "playerright", "ped", MI_COP, awc(aPlayerStrafeRightAnimations), aStdAnimDescsSide },
{ "rocketback", "ped", MI_COP, awc(aRocketStrafeBackAnimations), aStdAnimDescs },
{ "rocketleft", "ped", MI_COP, awc(aRocketStrafeLeftAnimations), aStdAnimDescsSide },
{ "rocketright", "ped", MI_COP, awc(aRocketStrafeRightAnimations), aStdAnimDescsSide },
+ { "csawback", "ped", MI_COP, awc(aChainsawStrafeBackAnimations), aStdAnimDescs },
+ { "csawleft", "ped", MI_COP, awc(aChainsawStrafeLeftAnimations), aStdAnimDescsSide },
+ { "csawright", "ped", MI_COP, awc(aChainsawStrafeRightAnimations), aStdAnimDescsSide },
};
#undef awc
@@ -567,8 +971,6 @@ CAnimManager::Initialise(void)
ms_numAnimations = 0;
ms_numAnimBlocks = 0;
ms_animCache.Init(25);
-
-// dumpanimdata();
}
void
@@ -576,31 +978,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->compressed2){
+ 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;
}
}
@@ -615,6 +1036,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)
{
@@ -622,7 +1110,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++;
}
@@ -743,26 +1231,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);
}
}
@@ -770,15 +1266,16 @@ 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);
}
+//--MIAMI: done
void
-CAnimManager::LoadAnimFile(int fd, bool compress)
+CAnimManager::LoadAnimFile(RwStream *stream, bool compress, char (*somename)[32])
{
#define ROUNDSIZE(x) if((x) & 3) (x) += 4 - ((x)&3)
struct IfpHeader {
@@ -786,127 +1283,136 @@ 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(strncmp(anpk.ident, "ANLF", 4) == 0){
- ROUNDSIZE(anpk.size);
- CFileMgr::Read(fd, buf, anpk.size);
- numANPK = *(int*)buf;
- }else if(strncmp(anpk.ident, "ANPK", 4) == 0){
- CFileMgr::Seek(fd, -8, 1);
- numANPK = 1;
+ // 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(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);
- animBlock->numAnims = *(int*)buf;
+ debug("Loading ANIMS %s\n", animBlock->name);
+ animBlock->isLoaded = true;
- animBlock->firstIndex = ms_numAnimations;
+ int animIndex = animBlock->firstIndex;
+ for(j = 0; j < animBlock->numAnims; j++){
+ assert(animIndex < ARRAY_SIZE(ms_aAnimations));
+ CAnimBlendHierarchy *hier = &ms_aAnimations[animIndex++];
+
+ // animation name
+ RwStreamRead(stream, &name, sizeof(IfpHeader));
+ ROUNDSIZE(name.size);
+ RwStreamRead(stream, buf, name.size);
+ hier->SetName(buf);
+
+ // Unimplemented uncompressed anim thing
+ if (somename) {
+ for (int i = 0; somename[i][0]; i++) {
+ if (!CGeneral::faststricmp(somename[i], hier->name))
+ debug("Loading %s uncompressed\n", hier->name);
+ }
+ }
- for(j = 0; j < animBlock->numAnims; j++){
- CAnimBlendHierarchy *hier = &ms_aAnimations[ms_numAnimations++];
+ hier->compressed = false;
+ hier->compressed2 = false;
- // animation name
- CFileMgr::Read(fd, (char*)&name, sizeof(IfpHeader));
- ROUNDSIZE(name.size);
- CFileMgr::Read(fd, buf, name.size);
- hier->SetName(buf);
+ // 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];
- // DG info has number of nodes/sequences
- CFileMgr::Read(fd, (char*)&dgan, sizeof(IfpHeader));
+ 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);
- 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);
-#ifdef PED_SKIN
- if(anim.size == 44)
- seq->SetBoneTag(*(int*)(buf+40));
-#endif
- seq->SetName(buf);
- if(numFrames == 0)
- continue;
-
- CFileMgr::Read(fd, (char*)&info, sizeof(info));
- if(strncmp(info.ident, "KR00", 4) == 0){
- seq->SetNumFrames(numFrames, false);
- KeyFrame *kf = seq->GetKeyFrame(0);
- for(l = 0; l < numFrames; l++, kf++){
- CFileMgr::Read(fd, buf, 0x14);
- kf->rotation.x = -fbuf[0];
- kf->rotation.y = -fbuf[1];
- kf->rotation.z = -fbuf[2];
- kf->rotation.w = fbuf[3];
- kf->deltaTime = fbuf[4]; // absolute time here
- }
- }else if(strncmp(info.ident, "KRT0", 4) == 0){
- seq->SetNumFrames(numFrames, true);
- KeyFrameTrans *kf = (KeyFrameTrans*)seq->GetKeyFrame(0);
- for(l = 0; l < numFrames; l++, kf++){
- CFileMgr::Read(fd, buf, 0x20);
- kf->rotation.x = -fbuf[0];
- kf->rotation.y = -fbuf[1];
- kf->rotation.z = -fbuf[2];
- kf->rotation.w = fbuf[3];
- kf->translation.x = fbuf[4];
- kf->translation.y = fbuf[5];
- kf->translation.z = fbuf[6];
- kf->deltaTime = fbuf[7]; // absolute time here
- }
- }else if(strncmp(info.ident, "KRTS", 4) == 0){
- seq->SetNumFrames(numFrames, true);
- KeyFrameTrans *kf = (KeyFrameTrans*)seq->GetKeyFrame(0);
- for(l = 0; l < numFrames; l++, kf++){
- CFileMgr::Read(fd, buf, 0x2C);
- kf->rotation.x = -fbuf[0];
- kf->rotation.y = -fbuf[1];
- kf->rotation.z = -fbuf[2];
- kf->rotation.w = fbuf[3];
- kf->translation.x = fbuf[4];
- kf->translation.y = fbuf[5];
- kf->translation.z = fbuf[6];
- // scaling ignored
- kf->deltaTime = fbuf[10]; // absolute time here
- }
+ RwStreamRead(stream, &anim, sizeof(IfpHeader));
+ ROUNDSIZE(anim.size);
+ RwStreamRead(stream, buf, anim.size);
+ int numFrames = *(int*)(buf+28);
+ if(anim.size == 44)
+ seq->SetBoneTag(*(int*)(buf+40));
+ seq->SetName(buf);
+ if(numFrames == 0)
+ continue;
+
+ RwStreamRead(stream, &info, sizeof(info));
+ if(strncmp(info.ident, "KR00", 4) == 0){
+ seq->SetNumFrames(numFrames, false, false);
+ KeyFrame *kf = seq->GetKeyFrame(0);
+ if (strstr(seq->name, "L Toe"))
+ debug("anim %s has toe keyframes\n", hier->name); // , seq->name);
+
+ for(l = 0; l < numFrames; l++, kf++){
+ RwStreamRead(stream, buf, 0x14);
+ kf->rotation.x = -fbuf[0];
+ kf->rotation.y = -fbuf[1];
+ kf->rotation.z = -fbuf[2];
+ kf->rotation.w = fbuf[3];
+ kf->deltaTime = fbuf[4]; // absolute time here
}
+ }else if(strncmp(info.ident, "KRT0", 4) == 0){
+ seq->SetNumFrames(numFrames, true, false);
+ KeyFrameTrans *kf = (KeyFrameTrans*)seq->GetKeyFrame(0);
+ if (strstr(seq->name, "L Toe"))
+ debug("anim %s has toe keyframes\n", hier->name); // , seq->name);
- // 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;
+ for(l = 0; l < numFrames; l++, kf++){
+ RwStreamRead(stream, buf, 0x20);
+ kf->rotation.x = -fbuf[0];
+ kf->rotation.y = -fbuf[1];
+ kf->rotation.z = -fbuf[2];
+ kf->rotation.w = fbuf[3];
+ kf->translation.x = fbuf[4];
+ kf->translation.y = fbuf[5];
+ kf->translation.z = fbuf[6];
+ kf->deltaTime = fbuf[7]; // absolute time here
}
- }
+ }else if(strncmp(info.ident, "KRTS", 4) == 0){
+ seq->SetNumFrames(numFrames, true, false);
+ KeyFrameTrans *kf = (KeyFrameTrans*)seq->GetKeyFrame(0);
+ if (strstr(seq->name, "L Toe"))
+ debug("anim %s has toe keyframes\n", hier->name); // , seq->name);
- hier->RemoveQuaternionFlips();
- if(compress)
- hier->RemoveUncompressedData();
- else
- hier->CalcTotalTime();
+ for(l = 0; l < numFrames; l++, kf++){
+ RwStreamRead(stream, buf, 0x2C);
+ kf->rotation.x = -fbuf[0];
+ kf->rotation.y = -fbuf[1];
+ kf->rotation.z = -fbuf[2];
+ kf->rotation.w = fbuf[3];
+ kf->translation.x = fbuf[4];
+ kf->translation.y = fbuf[5];
+ kf->translation.z = fbuf[6];
+ // scaling ignored
+ kf->deltaTime = fbuf[10]; // absolute time here
+ }
+ }
}
+
+ hier->RemoveQuaternionFlips();
+ hier->CalcTotalTime();
}
+ if(animIndex > ms_numAnimations)
+ ms_numAnimations = animIndex;
}
void
@@ -916,5 +1422,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 de15602c..a55577b1 100644
--- a/src/animation/AnimManager.h
+++ b/src/animation/AnimManager.h
@@ -6,30 +6,66 @@
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,
ASSOCGRP_PLAYERBACK,
ASSOCGRP_PLAYERLEFT,
ASSOCGRP_PLAYERRIGHT,
ASSOCGRP_ROCKETBACK,
ASSOCGRP_ROCKETLEFT,
ASSOCGRP_ROCKETRIGHT,
+ ASSOCGRP_CHAINSAWBACK,
+ ASSOCGRP_CHAINSAWLEFT,
+ ASSOCGRP_CHAINSAWRIGHT,
NUM_ANIM_ASSOC_GROUPS
};
@@ -37,11 +73,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;
};
@@ -75,7 +115,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);
@@ -87,6 +136,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 (*somename)[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 82fed8bd..f2ef3dfd 100644
--- a/src/animation/AnimationId.h
+++ b/src/animation/AnimationId.h
@@ -47,27 +47,6 @@ enum AnimationId
ANIM_HIT_WALL,
ANIM_FLOOR_HIT_F,
ANIM_HIT_BEHIND,
- ANIM_PUNCH_R,
- ANIM_KICK_FLOOR,
- ANIM_WEAPON_BAT_H,
- ANIM_WEAPON_BAT_V,
- ANIM_WEAPON_HGUN_BODY,
- ANIM_WEAPON_AK_BODY,
- ANIM_WEAPON_PUMP,
- ANIM_WEAPON_SNIPER,
- ANIM_WEAPON_THROW,
- ANIM_WEAPON_THROWU,
- ANIM_WEAPON_START_THROW,
- ANIM_BOMBER,
- ANIM_HGUN_RELOAD,
- ANIM_AK_RELOAD,
- ANIM_FPS_PUNCH,
- ANIM_FPS_BAT,
- ANIM_FPS_UZI,
- ANIM_FPS_PUMP,
- ANIM_FPS_AK,
- ANIM_FPS_M16,
- ANIM_FPS_ROCKET,
ANIM_FIGHT_IDLE,
ANIM_FIGHT2_IDLE,
ANIM_FIGHT_SH_F,
@@ -80,6 +59,21 @@ enum AnimationId
ANIM_FIGHT_ROUNDHOUSE,
ANIM_FIGHT_LONGKICK,
ANIM_FIGHT_PPUNCH,
+
+ ANIM_FIGHT_JAB,
+ ANIM_FIGHT_ELBOW_L,
+ ANIM_FIGHT_ELBOW_R,
+ ANIM_FIGHT_BKICK_L,
+ ANIM_FIGHT_BKICK_R,
+
+ ANIM_BOMBER,
+ ANIM_PUNCH_R,
+ ANIM_FIGHT_PPUNCH2,
+ ANIM_KICK_FLOOR,
+
+ ANIM_WEAPON_THROWU,
+ ANIM_FIGHT_SH_BACK,
+
ANIM_CAR_JACKED_RHS,
ANIM_CAR_LJACKED_RHS,
ANIM_CAR_JACKED_LHS,
@@ -98,6 +92,7 @@ enum AnimationId
ANIM_CAR_CLOSEDOOR_LOW_LHS,
ANIM_CAR_ROLLDOOR,
ANIM_CAR_ROLLDOOR_LOW,
+ ANIM_CAR_JUMPIN_LHS,
ANIM_CAR_GETOUT_LHS,
ANIM_CAR_GETOUT_LOW_LHS,
ANIM_CAR_CLOSE_LHS,
@@ -123,29 +118,36 @@ enum AnimationId
ANIM_DRIVE_LOW_R,
ANIM_DRIVEBY_L,
ANIM_DRIVEBY_R,
+ ANIM_DRIVEBY_LOW_L,
+ ANIM_DRIVEBY_LOW_R,
ANIM_CAR_LB,
ANIM_DRIVE_BOAT,
+ ANIM_DRIVE_BOAT_L,
+ ANIM_DRIVE_BOAT_R,
+ ANIM_BOAT_LB,
+
+ ANIM_BIKE_PICKUP_R,
+ ANIM_BIKE_PICKUP_L,
+ ANIM_BIKE_PULLUP_R,
+ ANIM_BIKE_PULLUP_L,
+ ANIM_BIKE_ELBOW_R,
+ ANIM_BIKE_ELBOW_L,
+ ANIM_BIKE_FALL_OFF,
+ ANIM_BIKE_FALL_R,
+
ANIM_CAR_GETOUT_RHS,
ANIM_CAR_GETOUT_LOW_RHS,
ANIM_CAR_CLOSE_RHS,
ANIM_CAR_HOOKERTALK,
- ANIM_COACH_OPEN_L,
- ANIM_COACH_OPEN_R,
- ANIM_COACH_IN_L,
- ANIM_COACH_IN_R,
- ANIM_COACH_OUT_L,
- ANIM_TRAIN_GETIN,
- ANIM_TRAIN_GETOUT,
+
+ ANIM_IDLE_STANCE2,
+ ANIM_IDLE_STANCE3,
+
ANIM_CAR_CRAWLOUT_RHS,
ANIM_CAR_CRAWLOUT_RHS2,
- ANIM_VAN_OPEN_L,
- ANIM_VAN_GETIN_L,
- ANIM_VAN_CLOSE_L,
- ANIM_VAN_GETOUT_L,
- ANIM_VAN_OPEN,
- ANIM_VAN_GETIN,
- ANIM_VAN_CLOSE,
- ANIM_VAN_GETOUT,
+ ANIM_CAR_ROLLOUT_LHS,
+ ANIM_CAR_ROLLOUT_RHS,
+
ANIM_GETUP1,
ANIM_GETUP2,
ANIM_GETUP3,
@@ -157,6 +159,9 @@ enum AnimationId
ANIM_FALL_GLIDE,
ANIM_FALL_LAND,
ANIM_FALL_COLLAPSE,
+ ANIM_FALL_BACK,
+ ANIM_FALL_FRONT,
+
ANIM_EV_STEP,
ANIM_EV_DIVE,
ANIM_XPRESS_SCRATCH,
@@ -164,11 +169,12 @@ enum AnimationId
ANIM_TURN_180,
ANIM_ARREST_GUN,
ANIM_DROWN,
- ANIM_CPR,
ANIM_DUCK_DOWN,
ANIM_DUCK_LOW,
+
+ ANIM_WEAPON_CROUCH,
+
ANIM_RBLOCK_CSHOOT,
- ANIM_WEAPON_THROWU2,
ANIM_HANDSUP,
ANIM_HANDSCOWER,
ANIM_FUCKU,
@@ -176,5 +182,92 @@ enum AnimationId
ANIM_PHONE_OUT,
ANIM_PHONE_TALK,
+ ANIM_SEAT_DOWN,
+ ANIM_SEAT_UP,
+ ANIM_SEAT_IDLE,
+ ANIM_SEAT_DOWN2,
+ ANIM_ATM,
+ ANIM_ABSEIL,
+
+ NUM_STD_ANIMS,
+
+ ANIM_VAN_OPEN_L,
+ ANIM_VAN_GETIN_L,
+ ANIM_VAN_CLOSE_L,
+ ANIM_VAN_GETOUT_L,
+ ANIM_VAN_OPEN,
+ ANIM_VAN_GETIN,
+ ANIM_VAN_CLOSE,
+ ANIM_VAN_GETOUT,
+
+ ANIM_COACH_OPEN_L,
+ ANIM_COACH_OPEN_R,
+ ANIM_COACH_IN_L,
+ ANIM_COACH_IN_R,
+ ANIM_COACH_OUT_L,
+
+ ANIM_BIKE_RIDE,
+ ANIM_BIKE_STILL,
+ ANIM_BIKE_LEFT,
+ ANIM_BIKE_RIGHT,
+ ANIM_BIKE_BACK,
+ ANIM_BIKE_FWD,
+ ANIM_BIKE_PUSHES,
+ ANIM_BIKE_JUMPON_R,
+ ANIM_BIKE_JUMPON_L,
+ ANIM_BIKE_KICK,
+ ANIM_BIKE_HIT,
+ ANIM_BIKE_GETOFF_RHS,
+ ANIM_BIKE_GETOFF_LHS,
+ ANIM_BIKE_GETOFF_BACK,
+ ANIM_BIKE_DRIVEBY_RHS,
+ ANIM_BIKE_DRIVEBY_LHS,
+ ANIM_BIKE_DRIVEBY_FT,
+ ANIM_BIKE_PASSENGER,
+
+ ANIM_WEAPON_FIRE,
+ ANIM_WEAPON_CROUCHFIRE,
+ ANIM_WEAPON_RELOAD,
+ ANIM_WEAPON_CROUCHRELOAD,
+ ANIM_WEAPON_SPECIAL,
+ ANIM_MELEE_ATTACK = ANIM_WEAPON_FIRE,
+ ANIM_MELEE_ATTACK_2ND,
+ ANIM_MELEE_ATTACK_START,
+ ANIM_MELEE_IDLE_FIGHTMODE,
+ ANIM_MELEE_ATTACK_FINISH,
+ ANIM_THROWABLE_THROW = ANIM_WEAPON_FIRE,
+ ANIM_THROWABLE_THROWU,
+ ANIM_THROWABLE_START_THROW,
+ ANIM_WEAPON_FIRE_2ND = ANIM_WEAPON_CROUCHFIRE,
+ ANIM_WEAPON_FIRE_3RD = ANIM_WEAPON_SPECIAL,
+
+ ANIM_SUNBATHE,
+ ANIM_SUNBATHE_DOWN,
+ ANIM_SUNBATHE_UP,
+ ANIM_SUNBATHE_ESCAPE,
+
+ ANIM_CPR,
+
+ ANIM_IDLE_STRETCH,
+ ANIM_IDLE_TIME,
+ ANIM_IDLE_SHOULDER,
+ ANIM_IDLE_STRETCH_LEG,
+
+ ANIM_RIOT_ANGRY,
+ ANIM_RIOT_ANGRY_B,
+ ANIM_RIOT_CHANT,
+ ANIM_RIOT_PUNCHES,
+ ANIM_RIOT_SHOUT,
+ ANIM_RIOT_CHALLENGE,
+ ANIM_RIOT_FUKU,
+
+ ANIM_STRIP_A,
+ ANIM_STRIP_B,
+ ANIM_STRIP_C,
+ ANIM_STRIP_D,
+ ANIM_STRIP_E,
+ ANIM_STRIP_F,
+ ANIM_STRIP_G,
+
NUM_ANIMS
}; \ 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..64951a87 100644
--- a/src/animation/CutsceneMgr.cpp
+++ b/src/animation/CutsceneMgr.cpp
@@ -16,94 +16,94 @@
#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"
+
+//--MIAMI: file done
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 +128,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 +161,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 +189,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 +201,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 +251,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 +276,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 +288,24 @@ 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 {
+ KeyFrameTrans* keyFrames;
+ if (pAnimBlendAssoc->hierarchy->IsCompressed())
+ keyFrames = ((KeyFrameTrans*)pAnimBlendAssoc->hierarchy->sequences[0].GetKeyFrameCompressed(0));
+ else
+ 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 +321,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->compressed2 = 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->compressed2)
+ pAnimBlendClumpData->frames->flag |= AnimBlendFrameData::UNK_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 +377,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)->GetName());
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 +403,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 +414,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 +428,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 +456,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 +508,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 +526,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())->GetName(), CModelInfo::GetModelInfo(pAttachTo->GetModelIndex())->GetName());
+}
+
+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())->GetName(),
+ frame,
+ CModelInfo::GetModelInfo(pAttachTo->GetModelIndex())->GetName());
+ 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())->GetName(),
+ CModelInfo::GetModelInfo(pAttachTo->GetModelIndex())->GetName());
+}
+
+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_HMOCA);
+ CStreaming::SetModelTxdIsDeletable(MI_HMOCA);
+ 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 6e5501cb..faeea709 100644
--- a/src/animation/FrameUpdate.cpp
+++ b/src/animation/FrameUpdate.cpp
@@ -6,6 +6,8 @@
#include "AnimBlendAssociation.h"
#include "RpAnimBlend.h"
+//--MIAMI: file done
+
CAnimBlendClumpData *gpAnimBlendClump;
// PS2 names without "NonSkinned"
@@ -17,7 +19,6 @@ void FrameUpdateCallBackSkinned(AnimBlendFrameData *frame, void *arg);
void FrameUpdateCallBackWithVelocityExtractionSkinned(AnimBlendFrameData *frame, void *arg);
void FrameUpdateCallBackWith3dVelocityExtractionSkinned(AnimBlendFrameData *frame, void *arg);
-
void
FrameUpdateCallBackNonSkinned(AnimBlendFrameData *frame, void *arg)
{
@@ -228,12 +229,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 +257,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 +278,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 +319,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 +440,9 @@ FrameUpdateCallBackWith3dVelocityExtractionSkinned(AnimBlendFrameData *frame, vo
}
}
-#endif
+void
+FrameUpdateCallBackOffscreen(AnimBlendFrameData *frame, void *arg)
+{
+ if(frame->flag & AnimBlendFrameData::VELOCITY_EXTRACTION && gpAnimBlendClump->velocity)
+ FrameUpdateCallBackWithVelocityExtractionSkinned(frame, arg);
+}
diff --git a/src/animation/RpAnimBlend.cpp b/src/animation/RpAnimBlend.cpp
index dcb656ee..e93615b7 100644
--- a/src/animation/RpAnimBlend.cpp
+++ b/src/animation/RpAnimBlend.cpp
@@ -9,9 +9,9 @@
#include "AnimBlendHierarchy.h"
#include "AnimBlendAssociation.h"
#include "RpAnimBlend.h"
-#ifdef PED_SKIN
#include "PedModelInfo.h"
-#endif
+
+//--MIAMI: file done
RwInt32 ClumpOffset;
@@ -141,7 +141,6 @@ FrameInitCBskin(AnimBlendFrameData *frameData, void*)
frameData->flag = 0;
}
-#ifdef PED_SKIN
void
RpAnimBlendClumpInitSkinned(RpClump *clump)
{
@@ -155,7 +154,7 @@ RpAnimBlendClumpInitSkinned(RpClump *clump)
RpAnimBlendAllocateData(clump);
clumpData = *RPANIMBLENDCLUMPDATA(clump);
- atomic = IsClumpSkinned(clump);
+ atomic = GetFirstAtomic(clump);
assert(atomic);
skin = RpSkinGeometryGetSkin(RpAtomicGetGeometry(atomic));
assert(skin);
@@ -170,12 +169,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)
@@ -199,11 +201,9 @@ RpAnimBlendClumpInitNotSkinned(RpClump *clump)
void
RpAnimBlendClumpInit(RpClump *clump)
{
-#ifdef PED_SKIN
if(IsClumpSkinned(clump))
RpAnimBlendClumpInitSkinned(clump);
else
-#endif
RpAnimBlendClumpInitNotSkinned(clump);
}
@@ -363,7 +363,6 @@ FillFrameArrayCBnonskin(AnimBlendFrameData *frame, void *arg)
frames[CVisibilityPlugins::GetFrameHierarchyId(frame->frame)] = frame;
}
-#ifdef PED_SKIN
void
RpAnimBlendClumpFillFrameArraySkin(RpClump *clump, AnimBlendFrameData **frames)
{
@@ -373,22 +372,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)
{
@@ -397,7 +392,6 @@ FrameFindByNameCBnonskin(AnimBlendFrameData *frame, void *arg)
pFrameDataFound = frame;
}
-#ifdef PED_SKIN
void
FrameFindByNameCBskin(AnimBlendFrameData *frame, void *arg)
{
@@ -405,25 +399,55 @@ 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->velocity == nil){
+ if((*node)[i].sequence)
+ (*node)[i].FindKeyFrame(a->currentTime - a->timeStep);
+ }
+ }
+}
+
+void
+RpAnimBlendClumpUpdateAnimations(RpClump *clump, float timeDelta, bool doRender)
+{
+ int i;
+ CAnimBlendAssociation *assoc;
AnimBlendFrameUpdateData updateData;
float totalLength = 0.0f;
float totalBlend = 0.0f;
@@ -439,30 +463,45 @@ 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(v6->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(v6->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
-#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..d0f7a114 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,11 @@ 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);
diff --git a/src/audio/AudioCollision.h b/src/audio/AudioCollision.h
index 0a058916..a00b16d9 100644
--- a/src/audio/AudioCollision.h
+++ b/src/audio/AudioCollision.h
@@ -35,4 +35,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 ca395136..69c17c28 100644
--- a/src/audio/AudioLogic.cpp
+++ b/src/audio/AudioLogic.cpp
@@ -37,21 +37,16 @@
#include "Weather.h"
#include "ZoneCull.h"
#include "sampman.h"
+#include "Bike.h"
+#include "WindModifiers.h"
+#include "Fluff.h"
+#include "Script.h"
+
const int channels = ARRAY_SIZE(cAudioManager::m_asActiveSamples);
const int policeChannel = channels + 1;
const int allChannels = channels + 2;
-uint32 gPornNextTime;
-uint32 gSawMillNextTime;
-uint32 gShopNextTime;
-uint32 gAirportNextTime;
-uint32 gCinemaNextTime;
-uint32 gDocksNextTime;
-uint32 gHomeNextTime;
-uint32 gCellNextTime;
-uint32 gNextCryTime;
-
enum PLAY_STATUS { PLAY_STATUS_STOPPED = 0, PLAY_STATUS_PLAYING, PLAY_STATUS_FINISHED };
enum LOADING_STATUS { LOADING_STATUS_NOT_LOADED = 0, LOADING_STATUS_LOADED, LOADING_STATUS_FAILED };
@@ -60,65 +55,65 @@ cAudioManager::PreInitialiseGameSpecificSetup() const
{
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;
}
@@ -149,27 +144,62 @@ cAudioManager::PostInitialiseGameSpecificSetup()
m_nPoliceChannelEntity = CreateEntity(AUDIOTYPE_POLICERADIO, (void *)1);
if (m_nPoliceChannelEntity >= 0)
SetEntityStatus(m_nPoliceChannelEntity, 1);
-
- m_nBridgeEntity = CreateEntity(AUDIOTYPE_BRIDGE, (void *)1);
+#ifdef GTA_BRIDGE
+ m_nBridgeEntity = CreateEntity(AUDIOTYPE_BRIDGE, (void*)1);
if (m_nBridgeEntity >= 0)
SetEntityStatus(m_nBridgeEntity, 1);
+#endif // GTA_BRIDGE
+ m_nEscalatorEntity = CreateEntity(AUDIOTYPE_ESCALATOR, (void*)1);
+ if (m_nEscalatorEntity >= 0)
+ SetEntityStatus(m_nEscalatorEntity, 1);
+
+ m_nExtraSoundsEntity = CreateEntity(AUDIOTYPE_EXTRA_SOUNDS, (void*)1);
+ if (m_nExtraSoundsEntity >= 0)
+ SetEntityStatus(m_nExtraSoundsEntity, 1);
+
+
+ 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;
@@ -205,15 +235,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;
@@ -223,22 +244,22 @@ cAudioManager::ResetAudioLogicTimers(uint32 timer)
}
}
}
- ClearMissionAudio();
+ ClearMissionAudio(0);
+ ClearMissionAudio(1);
SampleManager.StopChannel(policeChannel);
}
void
cAudioManager::ProcessReverb() const
{
- if (SampleManager.UpdateReverb() && m_bDynamicAcousticModelingStatus) {
- for (uint32 i = 0; i <
#ifdef FIX_BUGS
- channels
+ const uint32 numChannels = channels;
#else
- 28
+ const uint32 numChannels = 28;
#endif
- ;
- i++) {
+
+ if (SampleManager.UpdateReverb() && m_bDynamicAcousticModelingStatus) {
+ for (uint32 i = 0; i < numChannels; i++) {
if (m_asActiveSamples[i].m_bReverbFlag)
SampleManager.SetChannelReverbFlag(i, 1);
}
@@ -256,30 +277,83 @@ void
cAudioManager::CalculateDistance(bool &distCalculated, float dist)
{
if (!distCalculated) {
- m_sQueueSample.m_fDistance = Sqrt(dist);
+ if (dist > 0.0f)
+ m_sQueueSample.m_fDistance = Sqrt(dist);
+ else
+ m_sQueueSample.m_fDistance = 0.0f;
distCalculated = true;
}
}
+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::ProcessPlayerMood()
+{
+ CPlayerPed *playerPed;
+ uint32& lastMissionPassedTime = CTheScripts::GetLastMissionPassedTime();
+ uint32 curTime = CTimer::GetTimeInMilliseconds();
+
+ if (m_nPlayerMoodTimer <= curTime) {
+ playerPed = FindPlayerPed();
+ if (playerPed != nil) {
+
+ if (playerPed->m_pWanted->m_nWantedLevel > 3) {
+ m_nPlayerMood = PLAYER_MOOD_ANGRY;
+ return;
+ }
+ if (playerPed->m_pWanted->m_nWantedLevel > 1) {
+ m_nPlayerMood = PLAYER_MOOD_PISSED_OFF;
+ return;
+ }
+
+ //lastMissionPassedTime = CTheScripts::GetLastMissionPassedTime();
+ 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::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) {
- const PedState &state = playerPed->m_nPedState;
- if (state != PED_ENTER_CAR && state != PED_STEAL_CAR && !playerPed->bInVehicle)
- SampleManager.StopChannel(m_nActiveSamples);
+ 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(m_nActiveSamples);
+ }
+ }
}
}
}
@@ -287,7 +361,7 @@ cAudioManager::ProcessSpecial()
void
cAudioManager::ProcessEntity(int32 id)
{
- if (m_asAudioEntities[id].m_nStatus) {
+ if (m_asAudioEntities[id].m_nStatus != STATUS_PLAYER) {
m_sQueueSample.m_nEntityIndex = id;
switch (m_asAudioEntities[id].m_nType) {
case AUDIOTYPE_PHYSICAL:
@@ -311,27 +385,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();
@@ -358,6 +435,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;
}
@@ -390,13 +479,13 @@ enum eVehicleModel {
LINERUN,
PEREN,
SENTINEL,
- PATRIOT,
+ RIO,
FIRETRUK,
TRASH,
STRETCH,
MANANA,
INFERNUS,
- BLISTA,
+ VOODOO,
PONY,
MULE,
CHEETAH,
@@ -405,11 +494,11 @@ enum eVehicleModel {
MOONBEAM,
ESPERANT,
TAXI,
- KURUMA,
+ WASHING,
BOBCAT,
MRWHOOP,
BFINJECT,
- CORPSE,
+ HUNTER,
POLICE,
ENFORCER,
SECURICA,
@@ -418,43 +507,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
@@ -477,76 +610,117 @@ 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} };
+
bool bPlayerJustEnteredCar;
@@ -570,129 +744,161 @@ const bool 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)
+void cAudioManager::ProcessVehicle(CVehicle* veh)
{
- tHandlingData *handling = veh->pHandling;
- float velChange;
+ CVehicle* playerVeh;
cVehicleParams params;
- m_sQueueSample.m_vecPos = veh->GetPosition();
-
- params.m_bDistanceCalculated = false;
- params.m_fDistance = GetDistanceSquared(m_sQueueSample.m_vecPos);
- params.m_pVehicle = veh;
- params.m_pTransmission = nil;
- params.m_nIndex = 0;
- params.m_fVelocityChange = 0.0f;
-
- if (handling != nil)
- params.m_pTransmission = &handling->Transmission;
-
- params.m_nIndex = veh->GetModelIndex() - MI_FIRST_VEHICLE;
- if (params.m_pVehicle->GetStatus() == STATUS_SIMPLE)
- velChange = params.m_pVehicle->AutoPilot.m_fMaxTrafficSpeed * 0.02f;
- else
- velChange = DotProduct(params.m_pVehicle->m_vecMoveSpeed, params.m_pVehicle->GetForward());
- params.m_fVelocityChange = velChange;
- switch (params.m_pVehicle->m_vehType) {
- case VEHICLE_TYPE_CAR:
- UpdateGasPedalAudio((CAutomobile *)veh);
- if (params.m_nIndex == RCBANDIT) {
- ProcessModelCarEngine(params);
+ 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);
- ((CAutomobile *)veh)->m_fVelocityChangeForAudio = params.m_fVelocityChange;
- break;
+ ProcessVehicleSirenOrAlarm(params);
+ ProcessEngineDamage(params);
+ return;
}
- if (params.m_nIndex == DODO) {
- if (!ProcessVehicleRoadNoise(params)) {
- ProcessVehicleOneShots(params);
- ((CAutomobile *)veh)->m_fVelocityChangeForAudio = params.m_fVelocityChange;
- break;
+ 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;
+ }
}
- if (CWeather::WetRoads > 0.f)
- ProcessWetRoadNoise(params);
- ProcessVehicleSkidding(params);
- } else {
- if (!ProcessVehicleRoadNoise(params)) {
- ProcessVehicleOneShots(params);
- ((CAutomobile *)veh)->m_fVelocityChangeForAudio = params.m_fVelocityChange;
- 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);
}
- 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;
+ ProcessVehicleOneShots(params);
+ bike->m_fVelocityChangeForAudio = params.m_fVelocityChange;
+ break;
+ default:
+ break;
+ }
+ ProcessRainOnVehicle(params);
}
- 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;
- CalculateDistance(params.m_bDistanceCalculated, params.m_fDistance);
- float emittingVol = 30.f * CWeather::Rain;
- m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, rainOnVehicleIntensity, m_sQueueSample.m_fDistance);
- if (m_sQueueSample.m_nVolume != 0) {
- m_sQueueSample.m_nCounter = veh->m_bRainSamplesCounter++;
- if (veh->m_bRainSamplesCounter > 4)
- veh->m_bRainSamplesCounter = 68;
- m_sQueueSample.m_nSampleIndex = (m_anRandomTable[1] & 3) + SFX_CAR_RAIN_1;
- m_sQueueSample.m_nBankIndex = 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;
- m_sQueueSample.m_nLoopStart = 0;
- m_sQueueSample.m_nLoopEnd = -1;
- m_sQueueSample.m_fSpeedMultiplier = 0.0f;
- m_sQueueSample.m_fSoundIntensity = rainOnVehicleIntensity;
- m_sQueueSample.m_bReleasingSoundFlag = true;
- m_sQueueSample.m_bReverbFlag = false;
- m_sQueueSample.m_bRequireReflection = false;
- AddSampleToRequestedQueue();
- }
+ 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;
+ m_sQueueSample.m_nLoopStart = 0;
+ m_sQueueSample.m_nLoopEnd = -1;
+ 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();
}
}
}
@@ -702,27 +908,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;
@@ -734,9 +941,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;
m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
m_sQueueSample.m_fSpeedMultiplier = 3.0f;
@@ -752,59 +959,196 @@ cAudioManager::ProcessReverseGear(cVehicleParams& params)
}
void
-cAudioManager::ProcessModelCarEngine(cVehicleParams& params)
+cAudioManager::ProcessModelVehicle(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 = 14000;
+ static uint8 prevVolume = 0;
+
+ uint32 freq;
+ int16 acceletateState;
+ int16 brakeState;
+ uint8 volume;
+ bool isPlayerVeh;
+ bool 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;
+ m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(SFX_RC_REV);
+ m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(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;
- m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_fSpeedMultiplier = 3.0f;
- m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY;
- m_sQueueSample.m_bReleasingSoundFlag = false;
- m_sQueueSample.m_nReleasingVolumeDivider = 3;
- m_sQueueSample.m_bReverbFlag = true;
- m_sQueueSample.m_bRequireReflection = false;
- AddSampleToRequestedQueue();
- }
+ }
+ 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;
+ m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_fSpeedMultiplier = 3.0f;
+ m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY;
+ m_sQueueSample.m_bReleasingSoundFlag = false;
+ m_sQueueSample.m_bReverbFlag = true;
+ m_sQueueSample.m_bRequireReflection = false;
+ AddSampleToRequestedQueue();
+ }
+ }
+ if (isPlayerVeh) {
+ if (vehSlowdown) {
+ prevFreq = freq;
+ prevVolume = volume;
}
}
}
}
+void
+cAudioManager::ProcessModelHeliVehicle(cVehicleParams& params)
+{
+ const float SOUND_INTENSITY = 35.0f;
+
+ static uint32 prevFreq = 22050;
+ uint32 freq;
+ bool 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;
+ m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(SFX_CAR_RC_HELI);
+ m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(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;
+}
bool
cAudioManager::ProcessVehicleRoadNoise(cVehicleParams& params)
@@ -816,46 +1160,61 @@ 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;
- m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_fSpeedMultiplier = 6.0f;
- m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY;
- m_sQueueSample.m_bReleasingSoundFlag = false;
- m_sQueueSample.m_nReleasingVolumeDivider = 4;
- m_sQueueSample.m_bReverbFlag = true;
- m_sQueueSample.m_bRequireReflection = false;
- AddSampleToRequestedQueue();
- }
+
+ 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;
+ m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_fSpeedMultiplier = 6.0f;
+ m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY;
+ m_sQueueSample.m_bReleasingSoundFlag = false;
+ m_sQueueSample.m_nReleasingVolumeDivider = 4;
+ m_sQueueSample.m_bReverbFlag = true;
+ m_sQueueSample.m_bRequireReflection = false;
+ AddSampleToRequestedQueue();
}
}
+
return true;
}
@@ -868,46 +1227,54 @@ 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;
- m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_fSpeedMultiplier = 6.0f;
- m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY;
- m_sQueueSample.m_bReleasingSoundFlag = false;
- m_sQueueSample.m_nReleasingVolumeDivider = 4;
- m_sQueueSample.m_bReverbFlag = true;
- m_sQueueSample.m_bRequireReflection = false;
- AddSampleToRequestedQueue();
- }
- }
+ 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;
+ m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_fSpeedMultiplier = 6.0f;
+ m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY;
+ m_sQueueSample.m_bReleasingSoundFlag = false;
+ m_sQueueSample.m_nReleasingVolumeDivider = 4;
+ m_sQueueSample.m_bReverbFlag = true;
+ m_sQueueSample.m_bRequireReflection = false;
+ AddSampleToRequestedQueue();
}
}
+
return true;
}
@@ -916,156 +1283,242 @@ 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;
+ bool isMoped;
+ bool caddyBool;
- if (params.m_fDistance < SQR(SOUND_INTENSITY)) {
- playerVeh = FindPlayerVehicle();
- veh = params.m_pVehicle;
- if (playerVeh == veh && veh->GetStatus() == STATUS_WRECKED) {
- SampleManager.StopChannel(m_nActiveSamples);
+ 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(m_nActiveSamples);
+ 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.0) {
+ 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.0, 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;
- m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_fSpeedMultiplier = 6.0f;
- m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY;
- m_sQueueSample.m_bReleasingSoundFlag = false;
- m_sQueueSample.m_nReleasingVolumeDivider = 8;
- m_sQueueSample.m_bReverbFlag = true;
- m_sQueueSample.m_bRequireReflection = false;
- AddSampleToRequestedQueue();
}
+ 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;
+ m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_fSpeedMultiplier = 6.0f;
+ m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY;
+ m_sQueueSample.m_bReleasingSoundFlag = false;
+ m_sQueueSample.m_nReleasingVolumeDivider = 8;
+ m_sQueueSample.m_bReverbFlag = true;
+ m_sQueueSample.m_bRequireReflection = false;
+ AddSampleToRequestedQueue();
}
}
void
-cAudioManager::UpdateGasPedalAudio(CAutomobile *automobile)
+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;
+ case VEHICLE_TYPE_BIKE:
+ gasPealAudioPtr = &((CBike*)veh)->m_fGasPedalAudio;
+ default:
+ return;
+ break;
+ }
+ 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
@@ -1182,41 +1635,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;
bool channelUsed;
bool lostTraction;
+ bool noGearBox;
+ bool stuckInSand;
bool processedAccelSampleStopped;
- uint8 currentGear;
- float gasPedalAudio;
- CVector pos;
+ bool isMoped;
+ static uint32 gearSoundStartTime = CTimer::GetTimeInMilliseconds();
+ static int32 nCruising = 0;
static int16 LastAccel = 0;
- static int16 LastBrake = 0;
static uint8 CurrentPretendGear = 1;
static bool bLostTractionLastFrame = false;
static bool bHandbrakeOnLastFrame = false;
- static int32 nCruising = 0;
static bool bAccelSampleStopped = true;
lostTraction = false;
+ isMoped = params.m_pVehicle->m_modelIndex == MI_PIZZABOY || params.m_pVehicle->m_modelIndex == MI_FAGGIO;
processedAccelSampleStopped = false;
if (bPlayerJustEnteredCar) {
bAccelSampleStopped = true;
@@ -1224,48 +1688,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(m_nActiveSamples);
- transmission = params.m_pTransmission;
- velocityChange = params.m_fVelocityChange;
- relativeVelocityChange = 2.0f * velocityChange / transmission->fMaxVelocity;
-
- accelerationMultipler = clamp(relativeVelocityChange, 0.0f, 1.0f);
- gasPedalAudio = accelerationMultipler;
- currentGear = params.m_pVehicle->m_nCurrentGear;
+ 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
@@ -1274,63 +1781,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(m_nActiveSamples);
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(m_nActiveSamples);
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)
@@ -1339,57 +1938,96 @@ cAudioManager::ProcessPlayersVehicleEngine(cVehicleParams& params, CAutomobile *
SampleManager.StopChannel(m_nActiveSamples);
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(m_nActiveSamples, 120);
+ SampleManager.SetChannel3DPosition(m_nActiveSamples, pos.x, pos.y, pos.z);
+ SampleManager.SetChannel3DDistances(m_nActiveSamples, 50.0f, 12.5f);
+ freq = (GearFreqAdj[CurrentPretendGear] + freqModifier + 22050) ;
+ if (engineSoundType == SFX_BANK_TRUCK)
+ freq /= 2;
+ SampleManager.SetChannelFrequency(m_nActiveSamples, freq);
+ if (!channelUsed) {
+ SampleManager.SetChannelReverbFlag(m_nActiveSamples, m_bDynamicAcousticModelingStatus != false);
+ SampleManager.StartChannel(m_nActiveSamples);
}
+ } else if (processedAccelSampleStopped) {
+ gearSoundStartTime = CTimer::GetTimeInMilliseconds();
+ params.m_pVehicle->bAudioChangingGear = true;
+ if (!SampleManager.InitialiseChannel(m_nActiveSamples, soundOffset + SFX_CAR_ACCEL_1, SFX_BANK_0))
+ return;
+ SampleManager.SetChannelLoopCount(m_nActiveSamples, 1);
+ SampleManager.SetChannelLoopPoints(m_nActiveSamples, 0, -1);
+ SampleManager.SetChannelEmittingVolume(m_nActiveSamples, 120);
+ SampleManager.SetChannel3DPosition(m_nActiveSamples, pos.x, pos.y, pos.z);
+ SampleManager.SetChannel3DDistances(m_nActiveSamples, 50.0f, 12.5f);
+ freq = (GearFreqAdj[CurrentPretendGear] + freqModifier + 22050);
+ if (engineSoundType == SFX_BANK_TRUCK)
+ freq /= 2;
+ SampleManager.SetChannelFrequency(m_nActiveSamples, freq);
+ if (!channelUsed) {
+ SampleManager.SetChannelReverbFlag(m_nActiveSamples, m_bDynamicAcousticModelingStatus != false);
+ SampleManager.StartChannel(m_nActiveSamples);
+ }
+ } else if (CurrentPretendGear < params.m_pTransmission->nNumberOfGears - 1) {
+ ++CurrentPretendGear;
+ gearSoundStartTime = CTimer::GetTimeInMilliseconds();
+ params.m_pVehicle->bAudioChangingGear = true;
if (!SampleManager.InitialiseChannel(m_nActiveSamples, soundOffset + SFX_CAR_ACCEL_1, SFX_BANK_0))
return;
SampleManager.SetChannelLoopCount(m_nActiveSamples, 1);
SampleManager.SetChannelLoopPoints(m_nActiveSamples, 0, -1);
- }
- SampleManager.SetChannelEmittingVolume(m_nActiveSamples, 85);
- SampleManager.SetChannel3DPosition(m_nActiveSamples, pos.x, pos.y, pos.z);
- SampleManager.SetChannel3DDistances(m_nActiveSamples, 50.f, 12.5f);
- freq = GearFreqAdj[CurrentPretendGear] + freqModifier + 22050;
- if (engineSoundType == SFX_BANK_TRUCK)
- freq /= 2;
- SampleManager.SetChannelFrequency(m_nActiveSamples, freq);
- if (!channelUsed) {
- SampleManager.SetChannelReverbFlag(m_nActiveSamples, m_bDynamicAcousticModelingStatus != false);
- SampleManager.StartChannel(m_nActiveSamples);
+ SampleManager.SetChannelEmittingVolume(m_nActiveSamples, 120);
+ SampleManager.SetChannel3DPosition(m_nActiveSamples, pos.x, pos.y, pos.z);
+ SampleManager.SetChannel3DDistances(m_nActiveSamples, 50.0f, 12.5f);
+ freq = (GearFreqAdj[CurrentPretendGear] + freqModifier + 22050);
+ if (engineSoundType == SFX_BANK_TRUCK)
+ freq /= 2;
+ SampleManager.SetChannelFrequency(m_nActiveSamples, freq);
+ if (!channelUsed) {
+ SampleManager.SetChannelReverbFlag(m_nActiveSamples, m_bDynamicAcousticModelingStatus != false);
+ SampleManager.StartChannel(m_nActiveSamples);
+ }
+ } else {
+ nCruising = 1;
+ params.m_pVehicle->bAudioChangingGear = true;
+ bAccelSampleStopped = true;
+ SampleManager.StopChannel(m_nActiveSamples);
+ 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) {
+ --nCruising;
+ }
+ freq = 27 * nCruising + freqModifier + 22050;
+ if (engineSoundType == SFX_BANK_TRUCK)
+ freq /= 2;
+ AudioManager.AddPlayerCarSample(120, freq, soundOffset + SFX_CAR_AFTER_ACCEL_1, engineSoundType, 64, true);
+ } else {
+ nCruising = 0;
+ }
}
}
- break;
- }
- if (nCruising != 0) {
+ } else {
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(m_nActiveSamples);
+ 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) {
@@ -1398,14 +2036,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);
+ AudioManager.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;
}
bool
@@ -1414,6 +2054,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;
@@ -1421,29 +2068,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;
@@ -1470,6 +2136,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;
@@ -1477,6 +2144,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;
}
@@ -1500,18 +2169,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);
@@ -1532,93 +2200,94 @@ 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
+bool
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;
- m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_fSpeedMultiplier = 5.0f;
- m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY;
- m_sQueueSample.m_bReleasingSoundFlag = false;
- m_sQueueSample.m_nReleasingVolumeDivider = 3;
- m_sQueueSample.m_bReverbFlag = true;
- m_sQueueSample.m_bRequireReflection = false;
- AddSampleToRequestedQueue();
- }
- }
+ veh = params.m_pVehicle;
+ if (veh->m_bSirenOrAlarm && UsesSirenSwitching(params))
+ return true;
+
+ if (veh->m_modelIndex == MI_MRWHOOP)
+ return true;
+
+ veh->m_nAlarmState;
+ 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
+ m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_fSpeedMultiplier = 5.0f;
+ m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY;
+ m_sQueueSample.m_bReleasingSoundFlag = false;
+ m_sQueueSample.m_nReleasingVolumeDivider = 4;
+ m_sQueueSample.m_bReverbFlag = true;
+ m_sQueueSample.m_bRequireReflection = false;
+ AddSampleToRequestedQueue();
}
}
+ return true;
}
bool
-cAudioManager::UsesSiren(int32 model) const
-{
- switch (model) {
- case FIRETRUK:
- case AMBULAN:
- case FBICAR:
- case POLICE:
- case ENFORCER:
- case PREDATOR:
- return true;
- default:
- return false;
- }
+cAudioManager::UsesSiren(cVehicleParams& params) const
+{
+ return params.m_pVehicle->UsesSiren();
}
bool
-cAudioManager::UsesSirenSwitching(int32 model) const
+cAudioManager::UsesSirenSwitching(cVehicleParams& params) const
{
- 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);
}
bool
@@ -1626,58 +2295,72 @@ 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;
- m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_fSpeedMultiplier = 7.0f;
- m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY;
- m_sQueueSample.m_bReleasingSoundFlag = false;
- m_sQueueSample.m_nReleasingVolumeDivider = 5;
- m_sQueueSample.m_bReverbFlag = true;
- m_sQueueSample.m_bRequireReflection = false;
- AddSampleToRequestedQueue();
- return 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;
+ m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_fSpeedMultiplier = 7.0f;
+ m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY;
+ m_sQueueSample.m_bReleasingSoundFlag = false;
+ m_sQueueSample.m_nReleasingVolumeDivider = 5;
+ m_sQueueSample.m_bReverbFlag = true;
+ m_sQueueSample.m_bRequireReflection = false;
+ AddSampleToRequestedQueue();
+ }
+ return true;
}
bool
cAudioManager::UsesReverseWarning(int32 model) const
{
- return model == LINERUN || model == FIRETRUK || model == TRASH || model == BUS || model == COACH;
+ return model == LINERUN || model == FIRETRUK || model == BUS || model == COACH || model == PACKER || model == FLATBED;
}
bool
@@ -1686,13 +2369,15 @@ cAudioManager::ProcessVehicleReverseWarning(cVehicleParams& params)
const float SOUND_INTENSITY = 50.0f;
CVehicle *veh = params.m_pVehicle;
+ uint8 volume;
if (params.m_fDistance >= SQR(SOUND_INTENSITY))
return false;
if (veh->bEngineOn && veh->m_fGasPedal < 0.0f) {
CalculateDistance(params.m_bDistanceCalculated, params.m_fDistance);
- m_sQueueSample.m_nVolume = ComputeVolume(60, SOUND_INTENSITY, m_sQueueSample.m_fDistance);
+ volume = veh->bIsDrowning ? 15 : 60;
+ m_sQueueSample.m_nVolume = ComputeVolume(volume, SOUND_INTENSITY, m_sQueueSample.m_fDistance);
if (m_sQueueSample.m_nVolume != 0) {
m_sQueueSample.m_nCounter = 12;
m_sQueueSample.m_nSampleIndex = SFX_REVERSE_WARNING;
@@ -1701,7 +2386,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
m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
m_sQueueSample.m_fSpeedMultiplier = 3.0f;
@@ -1737,7 +2426,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;
@@ -1767,10 +2456,11 @@ cAudioManager::ProcessVehicleDoors(cVehicleParams& params)
bool
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)
@@ -1781,8 +2471,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;
@@ -1792,11 +2482,11 @@ 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;
m_sQueueSample.m_nLoopStart = 0;
m_sQueueSample.m_nLoopEnd = -1;
m_sQueueSample.m_fSpeedMultiplier = 0.0f;
- m_sQueueSample.m_fSoundIntensity = 30.0f;
+ m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY;
m_sQueueSample.m_bReleasingSoundFlag = true;
m_sQueueSample.m_bReverbFlag = true;
m_sQueueSample.m_bRequireReflection = false;
@@ -1809,38 +2499,41 @@ cAudioManager::ProcessAirBrakes(cVehicleParams& params)
bool
cAudioManager::HasAirBrakes(int32 model) const
{
- 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;
}
bool
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;
@@ -1850,7 +2543,7 @@ cAudioManager::ProcessEngineDamage(cVehicleParams& params)
m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
m_sQueueSample.m_fSpeedMultiplier = 2.0f;
- m_sQueueSample.m_fSoundIntensity = engineDamageIntensity;
+ m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY;
m_sQueueSample.m_bReleasingSoundFlag = false;
m_sQueueSample.m_nReleasingVolumeDivider = 3;
m_sQueueSample.m_bReverbFlag = true;
@@ -1864,32 +2557,48 @@ cAudioManager::ProcessEngineDamage(cVehicleParams& params)
bool
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;
- m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_fSpeedMultiplier = 2.0f;
- m_sQueueSample.m_fSoundIntensity = 40.0f;
- m_sQueueSample.m_bReleasingSoundFlag = false;
- m_sQueueSample.m_nReleasingVolumeDivider = 3;
- m_sQueueSample.m_bReverbFlag = true;
- m_sQueueSample.m_bRequireReflection = false;
- AddSampleToRequestedQueue();
+ 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;
+ m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
+ m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY;
+ m_sQueueSample.m_bReleasingSoundFlag = false;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ m_sQueueSample.m_bReverbFlag = true;
+ m_sQueueSample.m_bRequireReflection = false;
+ AddSampleToRequestedQueue();
+ }
}
}
return true;
@@ -1903,16 +2612,17 @@ cAudioManager::ProcessVehicleOneShots(cVehicleParams& params)
float relVol;
float vol;
bool noReflections;
+ bool isHeli;
float maxDist;
cPedParams pedParams;
-
- static uint8 WaveIndex = 41;
static uint8 GunIndex = 53;
- static uint8 iWheelIndex = 82;
- static uint8 CrunchOffset = 0;
+ pedParams.m_pPed = nil;
+ pedParams.m_bDistanceCalculated = false;
+ pedParams.m_fDistance = 0.0f;
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) {
@@ -1948,7 +2658,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;
@@ -1969,16 +2682,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
@@ -1986,7 +2698,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;
@@ -1995,39 +2710,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; //GetRandomNumberInRange(1, 80, 109)
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;
@@ -2102,27 +2846,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;
@@ -2134,7 +2879,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;
@@ -2149,20 +2895,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;
@@ -2194,23 +2941,92 @@ 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);
+ m_sQueueSample.m_nSampleIndex = SFX_UZI_LEFT;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;
+ m_sQueueSample.m_nCounter = GunIndex++;
+ emittingVol = m_anRandomTable[2] % 15 + 65;
+ if (GunIndex > 58)
+ GunIndex = 53;
+ m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_UZI_LEFT);
+ m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 16);
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
+ m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY;
+ 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;
@@ -2226,7 +3042,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;
@@ -2242,24 +3058,31 @@ cAudioManager::ProcessVehicleOneShots(cVehicleParams& params)
maxDist = SQR(SOUND_INTENSITY);
break;
}
- case SOUND_PED_HELI_PLAYER_FOUND:
- pedParams.m_pPed = nil;
- pedParams.m_bDistanceCalculated = false;
- pedParams.m_fDistance = 0.0f;
+ case SOUND_PED_HELI_PLAYER_FOUND: {
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;
+ SetupPedComments(&pedParams, SOUND_PED_BODYCAST_HIT);
+ continue; */
+ case SOUND_PED_VCPA_PLAYER_FOUND: {
+ pedParams.m_bDistanceCalculated = params.m_bDistanceCalculated;
+ pedParams.m_fDistance = params.m_fDistance;
+ SetupPedComments(pedParams, SOUND_PED_VCPA_PLAYER_FOUND);
+ }
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;
@@ -2274,13 +3097,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;
@@ -2291,14 +3115,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;
@@ -2323,13 +3148,50 @@ cAudioManager::ProcessVehicleOneShots(cVehicleParams& params)
m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(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 = 0;
+ 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
bool
cAudioManager::ProcessTrainNoise(cVehicleParams& params)
{
@@ -2395,7 +3257,7 @@ cAudioManager::ProcessTrainNoise(cVehicleParams& params)
}
return true;
}
-
+#endif
bool
cAudioManager::ProcessBoatEngine(cVehicleParams& params)
{
@@ -2459,7 +3321,7 @@ cAudioManager::ProcessBoatEngine(cVehicleParams& params)
if (!m_sQueueSample.m_nVolume)
return true;
m_sQueueSample.m_nCounter = 40;
- m_sQueueSample.m_nSampleIndex = SFX_POLICE_BOAT_ACCEL;
+ m_sQueueSample.m_nSampleIndex = SFX_FISHING_BOAT_IDLE;
m_sQueueSample.m_nFrequency += (m_sQueueSample.m_nEntityIndex * 65536) % 1000;
m_sQueueSample.m_nBankIndex = SFX_BANK_0;
m_sQueueSample.m_bIs2D = false;
@@ -2481,7 +3343,7 @@ cAudioManager::ProcessBoatEngine(cVehicleParams& params)
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;
+ m_sQueueSample.m_nSampleIndex = SFX_FISHING_BOAT_IDLE;
if (LastAccel > 20) {
oneShotVol = LastVol;
PlayOneShot(m_sQueueSample.m_nEntityIndex, SOUND_BOAT_SLOWDOWN, oneShotVol);
@@ -2492,7 +3354,7 @@ cAudioManager::ProcessBoatEngine(cVehicleParams& params)
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;
+ m_sQueueSample.m_nSampleIndex = SFX_FISHING_BOAT_IDLE;
}
LastVol = emittingVol;
LastAccel = padAccelerate;
@@ -2502,14 +3364,14 @@ cAudioManager::ProcessBoatEngine(cVehicleParams& params)
m_sQueueSample.m_nFrequency = 11025;
emittingVol = 45;
m_sQueueSample.m_nCounter = 39;
- m_sQueueSample.m_nSampleIndex = SFX_POLICE_BOAT_IDLE;
+ m_sQueueSample.m_nSampleIndex = SFX_FISHING_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;
+ m_sQueueSample.m_nSampleIndex = SFX_FISHING_BOAT_IDLE;
}
}
CalculateDistance(params.m_bDistanceCalculated, params.m_fDistance);
@@ -2579,52 +3441,404 @@ cAudioManager::ProcessBoatMovingOverWater(cVehicleParams& params)
return true;
}
-struct tHelicopterSampleData {
- float m_fMaxDistance;
- float m_fBaseDistance;
- uint8 m_bBaseVolume;
-};
-
-bool
-cAudioManager::ProcessHelicopter(cVehicleParams& params)
+void
+cAudioManager::ProcessCarHeli(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}};
+ const float SOUND_INTENSITY = 250.0f;
- if (SQR(gHeliSfxRanges[0].m_fMaxDistance) <= params.m_fDistance)
- return false;
+ 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;
+ bool distanceCalculatedOld;
+ float distanceOld;
+ CVector vecPosOld;
+
+ float volumeModifier;//TODO find better name
+ bool 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->m_matrix.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);
- 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);
+
+ //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 = i + 65;
- m_sQueueSample.m_nSampleIndex = i + SFX_HELI_1;
+ 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;
+ m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_fSpeedMultiplier = 6.0f;
+ m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY;
+ m_sQueueSample.m_bReleasingSoundFlag = false;
+ m_sQueueSample.m_nReleasingVolumeDivider = 5;
+ m_sQueueSample.m_bReverbFlag = true;
+ m_sQueueSample.m_bRequireReflection = false;
+ AddSampleToRequestedQueue();
+ }
+ }
+
+ if (params.m_fDistance >= SQR(140.0f))
+ return;
+
+ if (propellerSpeed >= 0.4f)
+ volumeModifier = (propellerSpeed - 0.4f) * 5.0f / 3.0f;
+ else
+ 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 = 0;
- m_sQueueSample.m_nFrequency = 1200 * heli->m_nHeliId + SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nReleasingVolumeModificator = 1;
+ m_sQueueSample.m_nLoopCount = 0;
+ m_sQueueSample.m_nEmittingVolume = emittingVol;
+ m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_fSpeedMultiplier = 6.0f;
+ m_sQueueSample.m_fSoundIntensity = 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;
+ m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_fSpeedMultiplier = 6.0f;
+ m_sQueueSample.m_fSoundIntensity = 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;
m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
m_sQueueSample.m_fSpeedMultiplier = 6.0f;
- m_sQueueSample.m_fSoundIntensity = gHeliSfxRanges[i].m_fMaxDistance;
+ m_sQueueSample.m_fSoundIntensity = 140.0f;
+ m_sQueueSample.m_bReleasingSoundFlag = false;
+ m_sQueueSample.m_nReleasingVolumeDivider = 5;
+ m_sQueueSample.m_bReverbFlag = true;
+ m_sQueueSample.m_bRequireReflection = false;
+ AddSampleToRequestedQueue();
+ }
+ }
+
+
+ //after accel rotor sound
+ emittingVol = ((cameraAngle + 1.0f) * volumeModifier * 127.0f) / 2.0f;
+ m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, 140.0, 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 {
+ 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;
+ m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_fSpeedMultiplier = 6.0f;
+ m_sQueueSample.m_fSoundIntensity = 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.0, 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;
+ m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_fSpeedMultiplier = 6.0f;
+ m_sQueueSample.m_fSoundIntensity = 30.0f;
+ m_sQueueSample.m_bReleasingSoundFlag = false;
+ m_sQueueSample.m_nReleasingVolumeDivider = 30;
+ m_sQueueSample.m_bReverbFlag = true;
+ m_sQueueSample.m_bRequireReflection = false;
+ AddSampleToRequestedQueue();
+ }
+ }
+ }
+ }
+
+
+ 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.0)
+ 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;
+ m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(SFX_SEAPLANE_PRO4);
+ m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(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;
+
+ if (automobile != nil)
+ automobile->GetComponentWorldPosition(CAR_BOOT, m_sQueueSample.m_vecPos);
+ else if (params.m_VehicleType == VEHICLE_TYPE_HELI)
+ m_sQueueSample.m_vecPos = CVector(0.0f, -10.0f, 0.0f); //this is from android, but for real it's not used
+
+ 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);
+ 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 = 0;
+ m_sQueueSample.m_bIs2D = 0;
+ 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;
+ m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_fSpeedMultiplier = 6.0f;
+ m_sQueueSample.m_fSoundIntensity = 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::ProcessVehicleFlatTyre(cVehicleParams& params)
+{
+ const float SOUND_INTENSITY = 60.0f;
+
+ CAutomobile* automobile;
+ CBike* bike;
+ bool 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;
+ m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(SFX_TYRE_BURST_L);
+ m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(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;
@@ -2632,9 +3846,9 @@ cAudioManager::ProcessHelicopter(cVehicleParams& params)
AddSampleToRequestedQueue();
}
}
- return true;
}
+//TODO use it in ProcessVehicle
void
cAudioManager::ProcessPlane(cVehicleParams& params)
{
@@ -2646,7 +3860,6 @@ cAudioManager::ProcessPlane(cVehicleParams& params)
ProcessCesna(params);
break;
default:
- debug("Plane Model Id is %d\n, ", params.m_pVehicle->GetModelIndex());
break;
}
}
@@ -2667,33 +3880,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();
}
}
@@ -2711,25 +3920,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);
}
}
}
@@ -2961,66 +4168,13 @@ cAudioManager::ProcessPed(CPhysical *ped)
m_sQueueSample.m_vecPos = ped->GetPosition();
- // params.m_bDistanceCalculated = false;
+ //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;
- m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_fSpeedMultiplier = 4.0f;
- m_sQueueSample.m_fSoundIntensity = 7.0f;
- m_sQueueSample.m_bReleasingSoundFlag = false;
- m_sQueueSample.m_nReleasingVolumeDivider = 5;
- m_sQueueSample.m_bReverbFlag = true;
- m_sQueueSample.m_bRequireReflection = false;
- AddSampleToRequestedQueue();
- }
- return;
- }
- }
-}
-
-void
cAudioManager::ProcessPedOneShots(cPedParams &params)
{
uint8 emittingVol;
@@ -3035,6 +4189,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++) {
@@ -3091,7 +4246,7 @@ cAudioManager::ProcessPedOneShots(cPedParams &params)
}
m_sQueueSample.m_nSampleIndex = sampleIndex;
m_sQueueSample.m_nBankIndex = SFX_BANK_0;
- m_sQueueSample.m_nCounter = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_awAudioEvent[i] - 28;
+ m_sQueueSample.m_nCounter = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_awAudioEvent[i] - 32;
m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex);
m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 17);
switch (params.m_pPed->m_nMoveState) {
@@ -3149,54 +4304,83 @@ cAudioManager::ProcessPedOneShots(cPedParams &params)
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:
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:
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? stroring 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;
@@ -3215,11 +4399,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? stroring 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;
@@ -3231,14 +4452,101 @@ 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;
+ }
+ // TODO: breaks the game right now, probably needs AudioManager.cpp to be done first
+ /*
+ case SOUND_WEAPON_CHAINSAW_ATTACK:
+ if (FindVehicleOfPlayer())
+ continue;
+ m_sQueueSample.m_nSampleIndex = SFX_CAR_ACCEL_13;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0; // SFX_BANK_CAR_CHAINSAW
+ m_sQueueSample.m_nCounter = 64;
+ 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;
+ m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(SFX_CAR_ACCEL_13);
+ m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(SFX_CAR_ACCEL_13);
+ m_sQueueSample.m_nEmittingVolume = 100;
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_bReverbFlag = false;
+ m_sQueueSample.m_nReleasingVolumeDivider = 5;
+ break;
+ case SOUND_WEAPON_CHAINSAW_IDLE:
+ if (FindVehicleOfPlayer())
+ continue;
+ m_sQueueSample.m_nSampleIndex = SFX_CAR_AFTER_ACCEL_13;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0; // SFX_BANK_CAR_CHAINSAW
+ 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;
+ m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(SFX_CAR_AFTER_ACCEL_13);
+ m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopStartOffset(SFX_CAR_AFTER_ACCEL_13);
+ 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_AFTER_ACCEL_13;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0; // SFX_BANK_CAR_CHAINSAW
+ 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;
+ m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(SFX_CAR_AFTER_ACCEL_13);
+ m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopStartOffset(SFX_CAR_AFTER_ACCEL_13);
+ 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;
+ m_sQueueSample.m_nLoopStart = 0;
+ m_sQueueSample.m_nLoopEnd = -1;
+ emittingVol = m_anRandomTable[0] % 20 + 80;
+ m_sQueueSample.m_nEmittingVolume = emittingVol;
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_bReleasingSoundFlag = true;
+ 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;
@@ -3248,8 +4556,8 @@ 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;
m_sQueueSample.m_nLoopStart = 0;
m_sQueueSample.m_nLoopEnd = -1;
@@ -3257,31 +4565,32 @@ 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;
+ 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;
m_sQueueSample.m_nLoopStart = 0;
- emittingVol = m_anRandomTable[3] % 15 + 70;
m_sQueueSample.m_nLoopEnd = -1;
+ 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++;
@@ -3290,8 +4599,8 @@ 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;
m_sQueueSample.m_nLoopStart = 0;
m_sQueueSample.m_nLoopEnd = -1;
@@ -3299,94 +4608,172 @@ 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;
+ 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;
+ m_sQueueSample.m_nLoopStart = 0;
+ m_sQueueSample.m_nLoopEnd = -1;
+ emittingVol = m_anRandomTable[2] % 10 + 100;
+ m_sQueueSample.m_nEmittingVolume = emittingVol;
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_bReleasingSoundFlag = true;
+ m_sQueueSample.m_bRequireReflection = true;
+ stereo = true;
+ break;
+ case WEAPONTYPE_TEC9:
+ m_sQueueSample.m_nSampleIndex = SFX_TEC_LEFT;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;
+ m_sQueueSample.m_nCounter = iSound++;
+ narrowSoundRange = true;
+ m_sQueueSample.m_nFrequency = RandomDisplacement(500) + 17000;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
+ m_sQueueSample.m_fSoundIntensity = 120.0f;
+ maxDist = SQR(120);
m_sQueueSample.m_nLoopCount = 1;
m_sQueueSample.m_nLoopStart = 0;
- emittingVol = m_anRandomTable[1] % 15 + 70;
+ emittingVol = m_anRandomTable[3] % 15 + 70;
m_sQueueSample.m_nLoopEnd = -1;
m_sQueueSample.m_nEmittingVolume = emittingVol;
m_sQueueSample.m_bIs2D = false;
m_sQueueSample.m_bReleasingSoundFlag = true;
+ stereo = true;
break;
- case WEAPONTYPE_M16:
- m_sQueueSample.m_nSampleIndex = SFX_M16_LEFT;
+ case WEAPONTYPE_UZI:
+ case WEAPONTYPE_MINIGUN:
+ m_sQueueSample.m_nSampleIndex = SFX_UZI_LEFT;
m_sQueueSample.m_nBankIndex = SFX_BANK_0;
m_sQueueSample.m_nCounter = iSound++;
narrowSoundRange = true;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_M16_LEFT);
+ m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_UZI_LEFT);
m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32);
m_sQueueSample.m_nReleasingVolumeModificator = 3;
m_sQueueSample.m_fSpeedMultiplier = 0.0f;
- m_sQueueSample.m_fSoundIntensity = 80.0f;
- maxDist = SQR(80);
+ m_sQueueSample.m_fSoundIntensity = 120.0f;
+ maxDist = SQR(120);
m_sQueueSample.m_nLoopCount = 1;
m_sQueueSample.m_nLoopStart = 0;
- emittingVol = m_anRandomTable[4] % 15 + 70;
+ emittingVol = m_anRandomTable[3] % 15 + 70;
m_sQueueSample.m_nLoopEnd = -1;
m_sQueueSample.m_nEmittingVolume = emittingVol;
m_sQueueSample.m_bIs2D = false;
m_sQueueSample.m_bReleasingSoundFlag = true;
+ 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;
+ m_sQueueSample.m_nLoopStart = 0;
+ emittingVol = m_anRandomTable[3] % 15 + 70;
+ m_sQueueSample.m_nLoopEnd = -1;
+ m_sQueueSample.m_nEmittingVolume = emittingVol;
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_bReleasingSoundFlag = true;
+ 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;
m_sQueueSample.m_nLoopStart = 0;
+ emittingVol = m_anRandomTable[3] % 15 + 70;
m_sQueueSample.m_nLoopEnd = -1;
- emittingVol = m_anRandomTable[4] % 10 + 110;
m_sQueueSample.m_nEmittingVolume = emittingVol;
m_sQueueSample.m_bIs2D = false;
m_sQueueSample.m_bReleasingSoundFlag = true;
- if (m_bDynamicAcousticModelingStatus)
- m_sQueueSample.m_bRequireReflection = true;
- else
- 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;
+ m_sQueueSample.m_nLoopStart = 0;
+ emittingVol = m_anRandomTable[3] % 15 + 90;
+ m_sQueueSample.m_nLoopEnd = -1;
+ 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;
m_sQueueSample.m_nLoopStart = 0;
+ emittingVol = m_anRandomTable[3] % 15 + 90;
m_sQueueSample.m_nLoopEnd = -1;
- emittingVol = m_anRandomTable[0] % 20 + 80;
m_sQueueSample.m_nEmittingVolume = emittingVol;
m_sQueueSample.m_bIs2D = false;
m_sQueueSample.m_bReleasingSoundFlag = true;
- if (m_bDynamicAcousticModelingStatus)
- m_sQueueSample.m_bRequireReflection = true;
+ 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;
+ m_sQueueSample.m_nLoopStart = 0;
+ m_sQueueSample.m_nLoopEnd = -1;
+ emittingVol = m_anRandomTable[4] % 10 + 110;
+ m_sQueueSample.m_nEmittingVolume = emittingVol;
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_bReleasingSoundFlag = true;
+ m_sQueueSample.m_bRequireReflection = true;
+ stereo = true;
break;
case WEAPONTYPE_FLAMETHROWER:
m_sQueueSample.m_nSampleIndex = SFX_FLAMETHROWER_LEFT;
@@ -3405,47 +4792,67 @@ 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;
+ m_sQueueSample.m_nLoopStart = 0;
+ m_sQueueSample.m_nLoopEnd = -1;
+ 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;
}
@@ -3467,30 +4874,71 @@ 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;
m_sQueueSample.m_nLoopStart = 0;
m_sQueueSample.m_nLoopEnd = -1;
- 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;
@@ -3529,6 +4977,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++;
@@ -3547,6 +4998,170 @@ 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;
+ m_sQueueSample.m_nLoopStart = 0;
+ m_sQueueSample.m_nLoopEnd = -1;
+ m_sQueueSample.m_nEmittingVolume = emittingVol;
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_bReleasingSoundFlag = true;
+ m_sQueueSample.m_bRequireReflection = true;
+ break;
+ }
+ case SOUND_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 = 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;
+ m_sQueueSample.m_nLoopStart = 0;
+ m_sQueueSample.m_nLoopEnd = -1;
+ 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;
+ m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(SFX_MINIGUN_FIRE_LEFT);
+ m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(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;
+ m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(SFX_MINIGUN_FIRE_RIGHT);
+ m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(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;
+ m_sQueueSample.m_nLoopStart = 0;
+ m_sQueueSample.m_nLoopEnd = -1;
+ 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()) {
+ 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;
+ m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nEmittingVolume = emittingVol;
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_bReleasingSoundFlag = false;
+ m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ }
+ }
+ break;
default:
SetupPedComments(params, sound);
continue;
@@ -3587,6 +5202,25 @@ cAudioManager::ProcessPedOneShots(cPedParams &params)
}
void
+cAudioManager::SetPedTalkingStatus(CPed *ped, uint8 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::SetupPedComments(cPedParams &params, uint16 sound)
{
CPed *ped = params.m_pPed;
@@ -3594,236 +5228,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 = GetRandomNumberInRange(m_sQueueSample.m_nEntityIndex % 4, SFX_POLICE_HELI_1, SFX_POLICE_HELI_29);
+ pedComment.m_nSampleIndex = GetRandomNumberInRange(m_sQueueSample.m_nEntityIndex % 4, SFX_POLICE_HELI_1, SFX_POLICE_HELI_20);
break;
- case SOUND_PED_BODYCAST_HIT:
- if (CTimer::GetTimeInMilliseconds() <= gNextCryTime)
- return;
- soundIntensity = 50.0f;
- gNextCryTime = CTimer::GetTimeInMilliseconds() + 500;
- pedComment.m_nSampleIndex = GetRandomNumberInRange(m_sQueueSample.m_nEntityIndex % 4, SFX_PLASTER_BLOKE_1, SFX_PLASTER_BLOKE_4);
+ 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 = GetRandomNumberInRange(m_sQueueSample.m_nEntityIndex % 4, SFX_GENERIC_MALE_GRUNT_1, SFX_GENERIC_MALE_GRUNT_15);
+ soundIntensity = 40.0f;
+ pedComment.m_nSampleIndex = GetRandomNumberInRange(m_sQueueSample.m_nEntityIndex % 4, SFX_GENERIC_MALE_GRUNT_1, SFX_GENERIC_MALE_GRUNT_41);
break;
case SOUND_INJURED_PED_FEMALE:
- soundIntensity = 50.0f;
- pedComment.m_nSampleIndex = GetRandomNumberInRange(m_sQueueSample.m_nEntityIndex % 4, SFX_GENERIC_FEMALE_GRUNT_1, SFX_GENERIC_FEMALE_GRUNT_11);
+ soundIntensity = 40.0f;
+ pedComment.m_nSampleIndex = GetRandomNumberInRange(m_sQueueSample.m_nEntityIndex % 4, SFX_GENERIC_FEMALE_GRUNT_1, SFX_GENERIC_FEMALE_GRUNT_33);
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, int32 sound)
{
- if (ped->IsPlayer())
- return GetPlayerTalkSfx(sound);
-
- switch (ped->GetModelIndex()) {
- case MI_COP:
- return GetCopTalkSfx(sound);
- case MI_SWAT:
- return GetSwatTalkSfx(sound);
- case MI_FBI:
- return GetFBITalkSfx(sound);
- case MI_ARMY:
- return GetArmyTalkSfx(sound);
- case MI_MEDIC:
- return GetMedicTalkSfx(sound);
- case MI_FIREMAN:
- return GetFiremanTalkSfx(sound);
- case MI_MALE01:
- return GetNormalMaleTalkSfx(sound);
- case MI_TAXI_D:
- return GetTaxiDriverTalkSfx(sound);
- case MI_PIMP:
- return GetPimpTalkSfx(sound);
- case MI_GANG01:
- case MI_GANG02:
- return GetMafiaTalkSfx(sound);
- case MI_GANG03:
- case MI_GANG04:
- return GetTriadTalkSfx(sound);
- case MI_GANG05:
- case MI_GANG06:
- return GetDiabloTalkSfx(sound);
- case MI_GANG07:
- case MI_GANG08:
- return GetYakuzaTalkSfx(sound);
- case MI_GANG09:
- case MI_GANG10:
- return GetYardieTalkSfx(sound);
- case MI_GANG11:
- case MI_GANG12:
- return GetColumbianTalkSfx(sound);
- case MI_GANG13:
- case MI_GANG14:
- return GetHoodTalkSfx(sound);
- case MI_CRIMINAL01:
- return GetBlackCriminalTalkSfx(sound);
- case MI_CRIMINAL02:
- return GetWhiteCriminalTalkSfx(sound);
- case MI_SPECIAL01:
- case MI_SPECIAL02:
- case MI_SPECIAL03:
- case MI_SPECIAL04:
- return GetSpecialCharacterTalkSfx(ped->GetModelIndex(), sound);
- case MI_MALE02:
- return GetMaleNo2TalkSfx(sound);
- case MI_MALE03:
- case MI_P_MAN1:
- case MI_P_MAN2:
- return GetBlackProjectMaleTalkSfx(sound, ped->GetModelIndex());
- case MI_FATMALE01:
- return GetWhiteFatMaleTalkSfx(sound);
- case MI_FATMALE02:
- return GetBlackFatMaleTalkSfx(sound);
- case MI_FEMALE01:
- return GetBlackCasualFemaleTalkSfx(sound);
- case MI_FEMALE02:
- case MI_CAS_WOM:
- return GetWhiteCasualFemaleTalkSfx(sound);
- case MI_FEMALE03:
- return GetFemaleNo3TalkSfx(sound);
- case MI_FATFEMALE01:
- return GetBlackFatFemaleTalkSfx(sound);
- case MI_FATFEMALE02:
- return GetWhiteFatFemaleTalkSfx(sound);
- case MI_PROSTITUTE:
- return GetBlackFemaleProstituteTalkSfx(sound);
- case MI_PROSTITUTE2:
- return GetWhiteFemaleProstituteTalkSfx(sound);
- case MI_P_WOM1:
- return GetBlackProjectFemaleOldTalkSfx(sound);
- case MI_P_WOM2:
- return GetBlackProjectFemaleYoungTalkSfx(sound);
- case MI_CT_MAN1:
- return GetChinatownMaleOldTalkSfx(sound);
- case MI_CT_MAN2:
- return GetChinatownMaleYoungTalkSfx(sound);
- case MI_CT_WOM1:
- return GetChinatownFemaleOldTalkSfx(sound);
- case MI_CT_WOM2:
- return GetChinatownFemaleYoungTalkSfx(sound);
- case MI_LI_MAN1:
- case MI_LI_MAN2:
- return GetLittleItalyMaleTalkSfx(sound);
- case MI_LI_WOM1:
- return GetLittleItalyFemaleOldTalkSfx(sound);
- case MI_LI_WOM2:
- return GetLittleItalyFemaleYoungTalkSfx(sound);
- case MI_DOCKER1:
- return GetWhiteDockerMaleTalkSfx(sound);
- case MI_DOCKER2:
- return GetBlackDockerMaleTalkSfx(sound);
- case MI_SCUM_MAN:
- return GetScumMaleTalkSfx(sound);
- case MI_SCUM_WOM:
- return GetScumFemaleTalkSfx(sound);
- case MI_WORKER1:
- return GetWhiteWorkerMaleTalkSfx(sound);
- case MI_WORKER2:
- return GetBlackWorkerMaleTalkSfx(sound);
- case MI_B_MAN1:
- case MI_B_MAN3:
- return GetBusinessMaleYoungTalkSfx(sound, ped->GetModelIndex());
- case MI_B_MAN2:
- return GetBusinessMaleOldTalkSfx(sound);
- case MI_B_WOM1:
- case MI_B_WOM2:
- return GetWhiteBusinessFemaleTalkSfx(sound, ped->GetModelIndex());
- case MI_B_WOM3:
- return GetBlackBusinessFemaleTalkSfx(sound);
- case MI_MOD_MAN:
- return GetSupermodelMaleTalkSfx(sound);
- case MI_MOD_WOM:
- return GetSupermodelFemaleTalkSfx(sound);
- case MI_ST_MAN:
- return GetStewardMaleTalkSfx(sound);
- case MI_ST_WOM:
- return GetStewardFemaleTalkSfx(sound);
- case MI_FAN_MAN1:
- case MI_FAN_MAN2:
- return GetFanMaleTalkSfx(sound, ped->GetModelIndex());
- case MI_FAN_WOM:
- return GetFanFemaleTalkSfx(sound);
- case MI_HOS_MAN:
- return GetHospitalMaleTalkSfx(sound);
- case MI_HOS_WOM:
- return GetHospitalFemaleTalkSfx(sound);
- case MI_CONST1:
- return GetWhiteConstructionWorkerTalkSfx(sound);
- case MI_CONST2:
- return GetBlackConstructionWorkerTalkSfx(sound);
- case MI_SHOPPER1:
- case MI_SHOPPER2:
- case MI_SHOPPER3:
- return GetShopperFemaleTalkSfx(sound, ped->GetModelIndex());
- case MI_STUD_MAN:
- return GetStudentMaleTalkSfx(sound);
- case MI_STUD_WOM:
- return GetStudentFemaleTalkSfx(sound);
- case MI_CAS_MAN:
- return GetCasualMaleOldTalkSfx(sound);
- default:
- return GetGenericMaleTalkSfx(sound);
+ if(ped->m_nPedState != PED_FALL || sound == MI_VICE8 || sound == MI_WFYG1 || sound == MI_WFYG2) {
+ 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 GetGenericMaleTalkSfx(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_VICE6:
+ case MI_VICE7:
+ case MI_VICE8: return GetVICETalkSfx(ped, sound, ped->GetModelIndex());
+ 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 NO_SAMPLE;
+ default: return GetGenericMaleTalkSfx(ped, sound);
+ }
}
+
+ return NO_SAMPLE;
}
void
@@ -3840,2204 +5437,2343 @@ 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(int16 sound)
+cAudioManager::GetPlayerTalkSfx(CPed *ped, int16 sound)
{
uint32 sfx;
- static uint32 lastSfx = NO_SAMPLE;
- switch (sound) {
+ if(this->m_bIsPlayerShutUp) return NO_SAMPLE;
+ switch(sound) {
+ case SOUND_PED_DEATH: return 9796;
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, 9815, 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, 9883, 42); break;
+ case SOUND_PED_LAND: GetPhrase(sfx, ped->m_lastComment, 9848, 35); break;
+ case SOUND_PED_BURNING: GetPhrase(sfx, ped->m_lastComment, 9925, 16); break;
+ case SOUND_PED_PLAYER_REACTTOCOP:
+ switch(m_nPlayerMood) {
+ case PLAYER_MOOD_ANGRY:
+ GetPhrase(sfx, ped->m_lastComment, 8694, 38);
+ break;
+ case PLAYER_MOOD_WISECRACKING:
+ GetPhrase(sfx, ped->m_lastComment, 9615, 20);
+ break;
+ default:
+ GetPhrase(sfx, ped->m_lastComment, 9046, 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, 9586, 29);
+ break;
+ case PLAYER_MOOD_ANGRY:
+ GetPhrase(sfx, ped->m_lastComment, 9007, 39);
+ break;
+ case PLAYER_MOOD_WISECRACKING:
+ GetPhrase(sfx, ped->m_lastComment, 9787, 9);
+ break;
+ default:
+ GetPhrase(sfx, ped->m_lastComment, 9322, 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, 9561, 25);
+ break;
+ case PLAYER_MOOD_ANGRY:
+ GetPhrase(sfx, ped->m_lastComment, 8937, 52);
+ break;
+ case PLAYER_MOOD_WISECRACKING:
+ GetPhrase(sfx, ped->m_lastComment, 9758, 19);
+ break;
+ default:
+ GetPhrase(sfx, ped->m_lastComment, 9275, 39);
+ break;
+ }
break;
}
+ case SOUND_PED_CAR_JACKING: {
+ cooldown_phrase(4);
+ switch(m_nPlayerMood) {
+ case PLAYER_MOOD_PISSED_OFF:
+ GetPhrase(sfx, ped->m_lastComment, 9483, 36);
+ break;
+ case PLAYER_MOOD_ANGRY:
+ GetPhrase(sfx, ped->m_lastComment, 8876, 43);
+ break;
+ case PLAYER_MOOD_WISECRACKING:
+ GetPhrase(sfx, ped->m_lastComment, 9706, 18);
+ break;
+ default:
+ GetPhrase(sfx, ped->m_lastComment, 9202, 40);
+ break;
+ }
+ break;
+ }
+ case SOUND_PED_MUGGING: {
+ cooldown_phrase(8);
+ switch(m_nPlayerMood) {
+ case PLAYER_MOOD_PISSED_OFF:
+ GetPhrase(sfx, ped->m_lastComment, 9519, 25);
+ break;
+ case PLAYER_MOOD_ANGRY:
+ GetPhrase(sfx, ped->m_lastComment, 8919, 12);
+ break;
+ case PLAYER_MOOD_WISECRACKING:
+ GetPhrase(sfx, ped->m_lastComment, 9724, 23);
+ break;
+ default:
+ GetPhrase(sfx, ped->m_lastComment, 9242, 11);
+ break;
+ }
+ break;
+ }
+ case SOUND_PED_CAR_JACKED: {
+ cooldown_phrase(4);
+ switch(m_nPlayerMood) {
+ case PLAYER_MOOD_PISSED_OFF:
+ GetPhrase(sfx, ped->m_lastComment, 9462, 21);
+ break;
+ case PLAYER_MOOD_ANGRY:
+ GetPhrase(sfx, ped->m_lastComment, 8843, 33);
+ break;
+ case PLAYER_MOOD_WISECRACKING:
+ GetPhrase(sfx, ped->m_lastComment, 9688, 18);
+ break;
+ default:
+ GetPhrase(sfx, ped->m_lastComment, 9178, 24);
+ break;
+ }
+ break;
+ }
+ case SOUND_PED_PLAYER_AFTERSEX: GetPhrase(sfx, ped->m_lastComment, 9797, 18); break;
+ case SOUND_PED_PLAYER_BEFORESEX:
+ switch(m_nPlayerMood) {
+ case PLAYER_MOOD_ANGRY:
+ GetPhrase(sfx, ped->m_lastComment, 8989, 18);
+ break;
+ case PLAYER_MOOD_WISECRACKING:
+ GetPhrase(sfx, ped->m_lastComment, 9777, 10);
+ break;
+ default:
+ GetPhrase(sfx, ped->m_lastComment, 9314, 8);
+ break;
+ }
+ break;
+ case SOUND_PED_PLAYER_FARFROMCOPS: {
+ cooldown_phrase(4);
+ switch(m_nPlayerMood) {
+ case PLAYER_MOOD_ANGRY:
+ GetPhrase(sfx, ped->m_lastComment, 8732, 9);
+ break;
+ case PLAYER_MOOD_WISECRACKING:
+ GetPhrase(sfx, ped->m_lastComment, 9635, 7);
+ break;
+ default:
+ GetPhrase(sfx, ped->m_lastComment, 9068, 20);
+ break;
+ }
+ break;
+ }
+ case SOUND_PED_ATTACK: {
+ cooldown_phrase(4);
+ switch(m_nPlayerMood) {
+ case PLAYER_MOOD_PISSED_OFF:
+ GetPhrase(sfx, ped->m_lastComment, 9401, 61);
+ break;
+ case PLAYER_MOOD_ANGRY:
+ GetPhrase(sfx, ped->m_lastComment, 8782, 61);
+ break;
+ case PLAYER_MOOD_WISECRACKING:
+ GetPhrase(sfx, ped->m_lastComment, 9661, 27);
+ break;
+ default:
+ GetPhrase(sfx, ped->m_lastComment, 9131, 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, 9357, 44);
+ break;
+ case PLAYER_MOOD_ANGRY:
+ GetPhrase(sfx, ped->m_lastComment, 8741, 41);
+ break;
+ case PLAYER_MOOD_WISECRACKING:
+ GetPhrase(sfx, ped->m_lastComment, 9642, 19);
+ break;
+ default:
+ GetPhrase(sfx, ped->m_lastComment, 9088, 43);
+ break;
+ }
+ break;
+ }
+ case SOUND_PED_SOLICIT: {
+ cooldown_phrase(4);
+ switch(m_nPlayerMood) {
+ case PLAYER_MOOD_PISSED_OFF:
+ GetPhrase(sfx, ped->m_lastComment, 9544, 17);
+ break;
+ case PLAYER_MOOD_ANGRY:
+ GetPhrase(sfx, ped->m_lastComment, 8931, 6);
+ break;
+ case PLAYER_MOOD_WISECRACKING:
+ GetPhrase(sfx, ped->m_lastComment, 9747, 11);
+ break;
+ default:
+ GetPhrase(sfx, ped->m_lastComment, 9253, 22);
+ break;
+ }
+ break;
+ }
+ default: return GetGenericMaleTalkSfx(ped, sound);
+ }
return sfx;
}
uint32
-cAudioManager::GetCopTalkSfx(int16 sound)
+cAudioManager::GetCopTalkSfx(CPed *ped, int16 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);
+ PedState objective;
+ switch(sound) {
+ case SOUND_PED_ARREST_COP: GetPhrase(sfx, ped->m_lastComment, 8469, 4); break;
+ case SOUND_PED_PULLOUTWEAPON: GetPhrase(sfx, ped->m_lastComment, 8473, 3); break;
+ case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, 8500, 2); break;
+ case SOUND_PED_COP_UNK_129: GetPhrase(sfx, ped->m_lastComment, 8510, 4); break;
+ case SOUND_PED_COP_MANYCOPSAROUND: GetPhrase(sfx, ped->m_lastComment, 8508, 2); break;
+ case SOUND_PED_GUNAIMEDAT2: GetPhrase(sfx, ped->m_lastComment, 8498, 2); break;
+ case SOUND_PED_COP_ALONE: GetPhrase(sfx, ped->m_lastComment, 8504, 4); break;
+ case SOUND_PED_GUNAIMEDAT3: GetPhrase(sfx, ped->m_lastComment, 8485, 2); break;
+ case SOUND_PED_COP_REACTION: {
+ cooldown_phrase(4);
+ GetPhrase(sfx, ped->m_lastComment, 8502, 2);
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);
+ }
+ 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, 8481, 4);
break;
- default:
- return GetGenericMaleTalkSfx(sound);
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 8494, 4); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 8491, 3); break;
+ case SOUND_PED_PED_COLLISION:
+ if(FindPlayerPed()->m_pWanted->m_nWantedLevel <= 0) return NO_SAMPLE;
+ GetPhrase(sfx, ped->m_lastComment, 8476, 5);
+ break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
+ return 45 * (m_sQueueSample.m_nEntityIndex % 5) + sfx;
+}
- return (SFX_COP_VOICE_2_ARREST_1 - SFX_COP_VOICE_1_ARREST_1) * (m_sQueueSample.m_nEntityIndex % 5) + sfx;
+uint32
+cAudioManager::GetSwatTalkSfx(CPed *ped, int16 sound)
+{
+ uint32 sfx;
+ switch(sound) {
+ case SOUND_PED_COP_HELIPILOTPHRASE: GetPhrase(sfx, ped->m_lastComment, 3285, 7); break;
+ case SOUND_PED_COP_UNK_129: GetPhrase(sfx, ped->m_lastComment, 3292, 4); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 3282, 3); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
+ }
+ sfx += 14 * (m_sQueueSample.m_nEntityIndex % 3);
+ return sfx;
}
uint32
-cAudioManager::GetSwatTalkSfx(int16 sound)
+cAudioManager::GetFBITalkSfx(CPed *ped, int16 sound)
{
uint32 sfx;
- PedState pedState;
- static uint32 lastSfx = NO_SAMPLE;
+ switch(sound) {
+ case SOUND_PED_COP_UNK_129: GetPhrase(sfx, ped->m_lastComment, 3240u, 4u); break;
+ case SOUND_PED_COP_MANYCOPSAROUND: GetPhrase(sfx, ped->m_lastComment, 3237u, 3u); break;
+ case SOUND_PED_GUNAIMEDAT2: sfx = 3236; break;
+ case SOUND_PED_GUNAIMEDAT3: GetPhrase(sfx, ped->m_lastComment, 3228u, 4u); break;
+ case SOUND_PED_CRASH_VEHICLE:
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 3232u, 4u); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
+ }
+ sfx += 16 * (m_sQueueSample.m_nEntityIndex % 3);
+ return sfx;
+}
- 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);
+uint32
+cAudioManager::GetArmyTalkSfx(CPed *ped, int16 sound)
+{
+ return GetGenericMaleTalkSfx(ped, sound);
+}
+
+uint32
+cAudioManager::GetMedicTalkSfx(CPed *ped, int16 sound)
+{
+ uint32 sfx;
+ switch(sound) {
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 3162, 6); break;
+ case SOUND_PED_HEALING: GetPhrase(sfx, ped->m_lastComment, 3178, 17); break;
+ case SOUND_PED_LEAVE_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 3168, 10); break; // SFX_MEDIC_VOICE_1_GET_OUT_VAN_CHAT_1
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
+ sfx += 33 * (m_sQueueSample.m_nEntityIndex % 2);
+ return sfx;
+}
- return (SFX_SWAT_VOICE_2_CHASE_1 - SFX_SWAT_VOICE_1_CHASE_1) * (m_sQueueSample.m_nEntityIndex % 4) + sfx;
+uint32
+cAudioManager::GetFiremanTalkSfx(CPed *ped, int16 sound)
+{
+ return GetGenericMaleTalkSfx(ped, sound);
}
uint32
-cAudioManager::GetFBITalkSfx(int16 sound)
+cAudioManager::GetDefaultTalkSfx(CPed *ped, int16 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)
- return NO_SAMPLE;
- GetPhrase(sfx, lastSfx, SFX_FBI_VOICE_1_CHASE_1, 6);
- break;
- default:
- return GetGenericMaleTalkSfx(sound);
+ switch(sound) {
+ case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, 2033, 12); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 2045, 12); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 2075, 4); break;
+ case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, 2098, 4); break;
+ case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, 2108, 5); break;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 2004, 16); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 1979, 19); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 2079, 19); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 2020, 13); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 1939, 15); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 1898, 16); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 2070, 5); break;
+ case SOUND_153: GetPhrase(sfx, ped->m_lastComment, 1998, 6); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 2102, 6); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 1914, 25); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 1954, 25); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
+ return sfx;
+}
- return (SFX_FBI_VOICE_2_CHASE_1 - SFX_FBI_VOICE_1_CHASE_1) * (m_sQueueSample.m_nEntityIndex % 3) + sfx;
+uint32
+cAudioManager::GetHFYSTTalkSfx(CPed *ped, int16 sound)
+{
+ uint32 sfx;
+ switch(sound) {
+ case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, 5736, 5); break;
+ case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, 5747, 4); break;
+ case SOUND_PED_MUGGING: GetPhrase(sfx, ped->m_lastComment, 5755, 4); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 5741, 6); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 5753, 2); break;
+ case SOUND_PED_TAXI_WAIT: return 5759;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 5722, 7); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 5712, 10); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 5729, 7); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 5695, 8); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 5678, 7); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 5751, 2); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 5685, 10); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 5703, 9); break;
+ default: return GetGenericFemaleTalkSfx(ped, sound);
+ }
+ return sfx;
}
uint32
-cAudioManager::GetArmyTalkSfx(int16 sound)
+cAudioManager::GetHFOSTTalkSfx(CPed *ped, int16 sound)
{
uint32 sfx;
- PedState pedState;
- static uint32 lastSfx = NO_SAMPLE;
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);
+ case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, 4382, 6); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 4388, 8); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 4398, 3); break;
+ case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, 4401, 2); break;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 4363, 8); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 4353, 10); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 4371, 11); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 4334, 8); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 4313, 9); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 4396, 2); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 4322, 12); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 4342, 11); break;
+ default: return GetGenericFemaleTalkSfx(ped, sound);
}
-
- return (SFX_ARMY_VOICE_2_CHASE_1 - SFX_ARMY_VOICE_1_CHASE_1) * (m_sQueueSample.m_nEntityIndex % 2) + sfx;
+ return sfx;
}
uint32
-cAudioManager::GetMedicTalkSfx(int16 sound)
+cAudioManager::GetHMYSTTalkSfx(CPed *ped, int16 sound)
{
uint32 sfx;
- static uint32 lastSfx = NO_SAMPLE;
- switch (sound) {
- case SOUND_PED_HANDS_COWER:
- GetPhrase(sfx, lastSfx, SFX_MEDIC_VOICE_1_GUN_PANIC_1, 5);
- break;
- case SOUND_PED_CAR_JACKED:
- GetPhrase(sfx, lastSfx, SFX_MEDIC_VOICE_1_CARJACKED_1, 5);
- break;
- case SOUND_PED_HEALING:
- GetPhrase(sfx, lastSfx, SFX_MEDIC_VOICE_1_AT_VICTIM_1, 12);
- break;
- case SOUND_PED_LEAVE_VEHICLE:
- GetPhrase(sfx, lastSfx, SFX_MEDIC_VOICE_1_GET_OUT_VAN_CHAT_1, 9);
- break;
- case SOUND_PED_FLEE_RUN:
- GetPhrase(sfx, lastSfx, SFX_MEDIC_VOICE_1_RUN_FROM_FIGHT_1, 6);
- break;
- default:
- return GetGenericMaleTalkSfx(sound);
+ switch(sound) {
+ case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, 7961, 6); break;
+ case SOUND_PED_ACCIDENTREACTION1: return 7971;
+ case SOUND_PED_TAXI_WAIT: return 7974;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 7946, 6); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 7967, 4); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 7954, 7); break;
+ case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, ped->m_lastComment, 7952, 2); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 7972, 2); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 7922, 13); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 7935, 11); 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;
+ return sfx;
}
uint32
-cAudioManager::GetFiremanTalkSfx(int16 sound)
+cAudioManager::GetHMOSTTalkSfx(CPed *ped, int16 sound)
{
- return GetGenericMaleTalkSfx(sound);
+ uint32 sfx;
+
+ switch(sound) {
+ case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, 5820, 5); break;
+ case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, 5831, 3); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 5825, 6); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 5836, 2); break;
+ case SOUND_PED_TAXI_WAIT: return 5838;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 5805, 8); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 5795, 9); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 5813, 7); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 5777, 7); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 5760, 7); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 5834, 2); break;
+ case SOUND_PED_CHAT_SEXY: return 5804;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 5767, 10); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 5784, 11); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
+ }
+ return sfx;
}
uint32
-cAudioManager::GetNormalMaleTalkSfx(int16 sound)
+cAudioManager::GetHFYRITalkSfx(CPed *ped, int16 sound)
{
uint32 sfx;
- static uint32 lastSfx = NO_SAMPLE;
- switch (sound) {
- case SOUND_PED_HANDS_COWER:
- GetPhrase(sfx, lastSfx, SFX_NORMAL_MALE_GUN_PANIC_1, 7);
- break;
- case SOUND_PED_CAR_JACKED:
- GetPhrase(sfx, lastSfx, SFX_NORMAL_MALE_CARJACKED_1, 7);
- break;
- case SOUND_PED_EVADE:
- GetPhrase(sfx, lastSfx, SFX_NORMAL_MALE_DODGE_1, 9);
- break;
- case SOUND_PED_FLEE_RUN:
- GetPhrase(sfx, lastSfx, SFX_NORMAL_MALE_RUN_FROM_FIGHT_1, 5);
- break;
- case SOUND_PED_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);
- break;
- default:
- return GetGenericMaleTalkSfx(sound);
+ switch(sound) {
+ case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, 6965, 5); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 6970, 6); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 6978, 4); break;
+ case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, 6986, 2); break;
+ case SOUND_PED_TAXI_WAIT: return 6991;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 6948, 10); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 6982, 4); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 6958, 7); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 6940, 8); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 6923, 8); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 6976, 2); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 6988, 3); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 6931, 9); break;
+ default: return GetGenericFemaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetTaxiDriverTalkSfx(int16 sound)
+cAudioManager::GetHFORITalkSfx(CPed *ped, int16 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_COWER: GetPhrase(sfx, ped->m_lastComment, 7244, 6); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 7250, 9); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 7261, 2); break;
+ case SOUND_PED_ACCIDENTREACTION1: return 7267;
+ case SOUND_PED_TAXI_WAIT: return 7270;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 7229, 6); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 7263, 4); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 7237, 7); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 7222, 7); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 7206, 6); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 7259, 2); break;
+ case SOUND_153: GetPhrase(sfx, ped->m_lastComment, 7235, 2); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 7268, 2); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 7212, 10); break;
+ default: return GetGenericFemaleTalkSfx(ped, sound);
}
-
- 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;
+ return sfx;
}
uint32
-cAudioManager::GetPimpTalkSfx(int16 sound)
+cAudioManager::GetHMYRITalkSfx(CPed *ped, int16 sound)
{
uint32 sfx;
- static uint32 lastSfx = NO_SAMPLE;
- switch (sound) {
- case SOUND_PED_HANDS_UP:
- GetPhrase(sfx, lastSfx, SFX_PIMP_GUN_COOL_1, 7);
- break;
- case SOUND_PED_CAR_JACKED:
- GetPhrase(sfx, lastSfx, SFX_PIMP_CARJACKED_1, 4);
- break;
- case SOUND_PED_DEFEND:
- GetPhrase(sfx, lastSfx, SFX_PIMP_FIGHT_1, 9);
- break;
- case SOUND_PED_EVADE:
- GetPhrase(sfx, lastSfx, SFX_PIMP_DODGE_1, 6);
- break;
- case SOUND_PED_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);
+ switch(sound) {
+ case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, 5890, 7); break;
+ case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, 5905, 3); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 5897, 8); break;
+ case SOUND_PED_ROBBED: return 5908;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 5873, 5); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 5864, 9); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 5878, 12); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 5856, 8); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 5839, 7); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 5909, 3); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 5846, 10); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetMafiaTalkSfx(int16 sound)
+cAudioManager::GetHMORITalkSfx(CPed *ped, int16 sound)
{
+
uint32 sfx;
- static uint32 lastSfx = NO_SAMPLE;
- switch (sound) {
- case SOUND_PED_CAR_JACKING:
- GetPhrase(sfx, lastSfx, SFX_MAFIA_MALE_VOICE_1_CARJACKING_1, 2);
- break;
- case SOUND_PED_CAR_JACKED:
- GetPhrase(sfx, lastSfx, SFX_MAFIA_MALE_VOICE_1_CARJACKED_1, 2);
- break;
- case SOUND_PED_ATTACK:
- GetPhrase(sfx, lastSfx, SFX_MAFIA_MALE_VOICE_1_FIGHT_1, 5);
- break;
- case SOUND_PED_EVADE:
- GetPhrase(sfx, lastSfx, SFX_MAFIA_MALE_VOICE_1_DODGE_1, 5);
- break;
- case SOUND_PED_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_COWER: GetPhrase(sfx, ped->m_lastComment, 4454, 5); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 4459, 8); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 4469, 3); break;
+ case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, 4478, 2); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 4436, 7); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 4472, 6); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 4443, 11); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 4422, 6); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 4403, 8); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 4467, 2); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 4411, 11); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 4428, 8); break;
+ default: return GetGenericMaleTalkSfx(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(int16 sound)
+cAudioManager::GetHFYBETalkSfx(CPed *ped, int16 sound)
{
uint32 sfx;
- static uint32 lastSfx = NO_SAMPLE;
- switch (sound) {
- case SOUND_PED_HANDS_UP:
- GetPhrase(sfx, lastSfx, SFX_TRIAD_MALE_VOICE_1_GUN_COOL_1, 3);
- break;
- case SOUND_PED_CAR_JACKING:
- GetPhrase(sfx, lastSfx, SFX_TRIAD_MALE_VOICE_1_CARJACKING_1, 2);
- break;
- case SOUND_PED_CAR_JACKED:
- GetPhrase(sfx, lastSfx, SFX_TRIAD_MALE_VOICE_1_CARJACKED_1, 2);
- break;
- case SOUND_PED_ATTACK:
- GetPhrase(sfx, lastSfx, SFX_TRIAD_MALE_VOICE_1_FIGHT_1, 5);
- break;
- case SOUND_PED_EVADE:
- GetPhrase(sfx, lastSfx, SFX_TRIAD_MALE_VOICE_1_DODGE_1, 4);
- break;
- case SOUND_PED_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_COWER: GetPhrase(sfx, ped->m_lastComment, 6897, 7); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 6904, 7); break;
+ case SOUND_PED_TAXI_WAIT: return 6922;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 6878, 11); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 6889, 8); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 6862, 6); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 6911, 2); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 6920, 2); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 6854, 8); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 6868, 10); break;
+ default: return GetGenericFemaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetDiabloTalkSfx(int16 sound)
+cAudioManager::GetHFOBETalkSfx(CPed *ped, int16 sound)
{
uint32 sfx;
- static uint32 lastSfx = NO_SAMPLE;
- switch (sound) {
- case SOUND_PED_HANDS_UP:
- GetPhrase(sfx, lastSfx, SFX_DIABLO_MALE_VOICE_1_GUN_COOL_1, 4);
- break;
- case SOUND_PED_HANDS_COWER:
- sound = SOUND_PED_FLEE_SPRINT;
- return GetGenericMaleTalkSfx(sound);
- break;
- case SOUND_PED_CAR_JACKING:
- GetPhrase(sfx, lastSfx, SFX_DIABLO_MALE_VOICE_1_CARJACKING_1, 2);
- break;
- case SOUND_PED_CAR_JACKED:
- GetPhrase(sfx, lastSfx, SFX_DIABLO_MALE_VOICE_1_CARJACKED_1, 2);
- break;
- case SOUND_PED_ATTACK:
- GetPhrase(sfx, lastSfx, SFX_DIABLO_MALE_VOICE_1_FIGHT_1, 4);
- break;
- case SOUND_PED_EVADE:
- GetPhrase(sfx, lastSfx, SFX_DIABLO_MALE_VOICE_1_DODGE_1, 4);
- break;
- case SOUND_PED_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, 1018, 5); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 1023, 6); break;
+ case SOUND_PED_ACCIDENTREACTION1: return 1035;
+ case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, 1038, 2); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 1006, 7); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 1031, 4); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 1013, 5); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 990, 6); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 973, 6); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 1029, 2); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 1036, 2); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 979, 11); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 996, 10); break;
+ default: return GetGenericFemaleTalkSfx(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(int16 sound)
+cAudioManager::GetHMYBETalkSfx(CPed *ped, int16 sound)
{
uint32 sfx;
- static uint32 lastSfx = NO_SAMPLE;
- switch (sound) {
- case SOUND_PED_CAR_JACKING:
- GetPhrase(sfx, lastSfx, SFX_YAKUZA_MALE_VOICE_1_CARJACKING_1, 2);
- break;
- case SOUND_PED_CAR_JACKED:
- GetPhrase(sfx, lastSfx, SFX_YAKUZA_MALE_VOICE_1_CARJACKED_1, 2);
- break;
- case SOUND_PED_ATTACK:
- GetPhrase(sfx, lastSfx, SFX_YAKUZA_MALE_VOICE_1_FIGHT_1, 5);
- break;
- case SOUND_PED_EVADE:
- GetPhrase(sfx, lastSfx, SFX_YAKUZA_MALE_VOICE_1_DODGE_1, 4);
- break;
- case SOUND_PED_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_COWER: GetPhrase(sfx, ped->m_lastComment, 4892, 6); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 4902, 12); break;
+ case SOUND_PED_ACCIDENTREACTION1: return 4917;
+ case SOUND_PED_UNK_126: GetPhrase(sfx, ped->m_lastComment, 4898, 4); break;
+ case SOUND_PED_TAXI_WAIT: return 4920;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 4874, 8); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 4862, 7); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 4882, 10); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 4845, 7); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 4914, 3); break;
+ case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, ped->m_lastComment, 4869, 5); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 4918, 2); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 4835, 10); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 4852, 10); 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(int16 sound)
+cAudioManager::GetHMOBETalkSfx(CPed *ped, int16 sound)
{
uint32 sfx;
- static uint32 lastSfx = NO_SAMPLE;
- switch (sound) {
- case SOUND_PED_HANDS_UP:
- sfx = SFX_YARDIE_MALE_VOICE_1_GUN_COOL_1;
- break;
- case SOUND_PED_CAR_JACKING:
- GetPhrase(sfx, lastSfx, SFX_YARDIE_MALE_VOICE_1_CARJACKING_1, 2);
- break;
- case SOUND_PED_CAR_JACKED:
- sfx = SFX_YARDIE_MALE_VOICE_1_CARJACKED_1;
- break;
- case SOUND_PED_ATTACK:
- GetPhrase(sfx, lastSfx, SFX_YARDIE_MALE_VOICE_1_FIGHT_1, 6);
- break;
- case SOUND_PED_EVADE:
- GetPhrase(sfx, lastSfx, SFX_YARDIE_MALE_VOICE_1_DODGE_1, 5);
- break;
- case SOUND_PED_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, 4703, 3); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 4709, 6); break;
+ case SOUND_PED_UNK_126: GetPhrase(sfx, ped->m_lastComment, 4706, 3); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 4690, 9); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 4672, 10); break;
+ case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, ped->m_lastComment, 4699, 4); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 4682, 8); break;
+ default: return GetGenericMaleTalkSfx(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(int16 sound)
+cAudioManager::GetHFYBUTalkSfx(CPed *ped, int16 sound)
{
+
uint32 sfx;
- static uint32 lastSfx = NO_SAMPLE;
- switch (sound) {
- case SOUND_PED_CAR_JACKING:
- GetPhrase(sfx, lastSfx, SFX_COLUMBIAN_MALE_VOICE_1_CARJACKING_1, 2);
- break;
- case SOUND_PED_CAR_JACKED:
- GetPhrase(sfx, lastSfx, SFX_COLUMBIAN_MALE_VOICE_1_CARJACKED_1, 2);
- break;
- case SOUND_PED_ATTACK:
- GetPhrase(sfx, lastSfx, SFX_COLUMBIAN_MALE_VOICE_1_FIGHT_1, 5);
- break;
- case SOUND_PED_EVADE:
- GetPhrase(sfx, lastSfx, SFX_COLUMBIAN_MALE_VOICE_1_DODGE_1, 5);
- break;
- case SOUND_PED_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, 4771, 5); break;
+ case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, 4782, 3); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 4776, 6); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 4787, 2); break;
+ case SOUND_PED_ACCIDENTREACTION1: return 4789;
+ case SOUND_PED_TAXI_WAIT: return 4790;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 4752, 7); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 4742, 10); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 4759, 12); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 4734, 8); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 4715, 8); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 4785, 2); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 4723, 11); 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(int16 sound)
+cAudioManager::GetHFYMDTalkSfx(CPed *ped, int16 sound)
{
uint32 sfx;
- static uint32 lastSfx = NO_SAMPLE;
-
- switch (sound) {
- case SOUND_PED_HANDS_UP:
- GetPhrase(sfx, lastSfx, SFX_HOOD_MALE_VOICE_1_GUN_COOL_1, 5);
- break;
- case SOUND_PED_CAR_JACKING:
- GetPhrase(sfx, lastSfx, SFX_HOOD_MALE_VOICE_1_CARJACKING_1, 2);
- break;
- case SOUND_PED_CAR_JACKED:
- GetPhrase(sfx, lastSfx, SFX_HOOD_MALE_VOICE_1_CARJACKED_1, 2);
- break;
- case SOUND_PED_ATTACK:
- GetPhrase(sfx, lastSfx, SFX_HOOD_MALE_VOICE_1_FIGHT_1, 6);
- break;
- case SOUND_PED_EVADE:
- GetPhrase(sfx, lastSfx, SFX_HOOD_MALE_VOICE_1_DODGE_1, 5);
- break;
- case SOUND_PED_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, 6014, 5); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 6019, 2); break;
+ case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, 6021, 3); break;
+ case SOUND_PED_TAXI_WAIT: return 8231;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 6005, 9); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 5997, 8); break;
+ case SOUND_PED_SOLICIT: GetPhrase(sfx, ped->m_lastComment, 6024, 15); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 5988, 9); break;
+ default: return GetGenericFemaleTalkSfx(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(int16 sound)
+cAudioManager::GetHFYCGTalkSfx(CPed *ped, int16 sound)
{
uint32 sfx;
- static uint32 lastSfx = NO_SAMPLE;
- switch (sound) {
- case SOUND_PED_HANDS_UP:
- GetPhrase(sfx, lastSfx, SFX_BLACK_CRIMINAL_VOICE_1_GUN_COOL_1, 4);
- break;
- case SOUND_PED_CAR_JACKING:
- sfx = SFX_BLACK_CRIMINAL_VOICE_1_CARJACKING_1;
- break;
- case SOUND_PED_MUGGING:
- GetPhrase(sfx, lastSfx, SFX_BLACK_CRIMINAL_VOICE_1_MUGGING_1, 2);
- break;
- case SOUND_PED_ATTACK:
- GetPhrase(sfx, lastSfx, SFX_BLACK_CRIMINAL_VOICE_1_FIGHT_1, 5);
- break;
- case SOUND_PED_EVADE:
- GetPhrase(sfx, lastSfx, SFX_BLACK_CRIMINAL_VOICE_1_DODGE_1, 6);
- break;
- case SOUND_PED_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, 4808, 5); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 4813, 2); break;
+ case SOUND_PED_ACCIDENTREACTION1: return 4819;
+ case SOUND_PED_TAXI_WAIT: return 8231;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 4800, 8); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 4815, 4); break;
+ case SOUND_PED_SOLICIT: GetPhrase(sfx, ped->m_lastComment, 4820, 14); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 4791, 9); break;
+ default: return GetGenericFemaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetWhiteCriminalTalkSfx(int16 sound)
+cAudioManager::GetHFYPRTalkSfx(CPed *ped, int16 sound)
{
uint32 sfx;
- static uint32 lastSfx = NO_SAMPLE;
- switch (sound) {
- case SOUND_PED_HANDS_UP:
- GetPhrase(sfx, lastSfx, SFX_WHITE_CRIMINAL_VOICE_1_GUN_COOL_1, 3);
- break;
- case SOUND_PED_CAR_JACKING:
- sfx = SFX_WHITE_CRIMINAL_VOICE_1_CARJACKING_1;
- break;
- case SOUND_PED_MUGGING:
- GetPhrase(sfx, lastSfx, SFX_WHITE_CRIMINAL_VOICE_1_MUGGING_1, 2);
- break;
- case SOUND_PED_ATTACK:
- GetPhrase(sfx, lastSfx, SFX_WHITE_CRIMINAL_VOICE_1_FIGHT_1, 4);
- break;
- case SOUND_PED_EVADE:
- GetPhrase(sfx, lastSfx, SFX_WHITE_CRIMINAL_VOICE_1_DODGE_1, 5);
- break;
- case SOUND_PED_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_UP: GetPhrase(sfx, ped->m_lastComment, 5964, 6); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 5970, 2); break;
+ case SOUND_PED_ACCIDENTREACTION1: return 5972;
+ case SOUND_PED_PLAYER_BEFORESEX: GetPhrase(sfx, ped->m_lastComment, 5956, 8); break;
+ case SOUND_PED_TAXI_WAIT: return 5987;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 5946, 10); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 5934, 9); break;
+ case SOUND_PED_SOLICIT: GetPhrase(sfx, ped->m_lastComment, 5973, 14); break;
+ case SOUND_153: GetPhrase(sfx, ped->m_lastComment, 5943, 3); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 5912, 10); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 5922, 12); break;
+ default: return GetGenericFemaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetMaleNo2TalkSfx(int16 sound)
+cAudioManager::GetHFOTRTalkSfx(CPed *ped, int16 sound)
{
uint32 sfx;
- static uint32 lastSfx = NO_SAMPLE;
- switch (sound) {
- case SOUND_PED_CAR_JACKED:
- GetPhrase(sfx, lastSfx, SFX_CASUAL_MALE_OLD_VOICE_1_CARJACKED_1, 3);
- break;
- case SOUND_PED_ROBBED:
- GetPhrase(sfx, lastSfx, SFX_CASUAL_MALE_OLD_VOICE_1_MUGGED_1, 4);
- break;
- case SOUND_PED_ATTACK:
- GetPhrase(sfx, lastSfx, SFX_CASUAL_MALE_OLD_VOICE_1_FIGHT_1, 4);
- break;
- case SOUND_PED_EVADE:
- GetPhrase(sfx, lastSfx, SFX_CASUAL_MALE_OLD_VOICE_1_DODGE_1, 4);
- break;
- case SOUND_PED_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_UP: GetPhrase(sfx, ped->m_lastComment, 4660, 5); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 4665, 2); break;
+ case SOUND_PED_ACCIDENTREACTION1: return 4667;
+ case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, 4670, 2); break;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 4654, 6); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 4646, 8); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 4668, 2); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 4623, 11); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 4634, 12); break;
+ default: return GetGenericFemaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetBlackProjectMaleTalkSfx(int16 sound, int32 model)
+cAudioManager::GetHMOTRTalkSfx(CPed *ped, int16 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_UP: GetPhrase(sfx, ped->m_lastComment, 4515, 6); break;
+ case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, 4521, 2); break;
+ case SOUND_PED_TAXI_WAIT: return 4534;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 4508, 7); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 4497, 11); break;
+ case SOUND_PED_SOLICIT: GetPhrase(sfx, ped->m_lastComment, 4526, 8); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 4523, 3); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 4480, 8); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 4488, 9); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
+ }
return sfx;
}
uint32
-cAudioManager::GetWhiteFatMaleTalkSfx(int16 sound)
+cAudioManager::GetHMYAPTalkSfx(CPed *ped, int16 sound)
{
uint32 sfx;
- static uint32 lastSfx = NO_SAMPLE;
switch(sound) {
- case SOUND_PED_CAR_JACKED: GetPhrase(sfx, lastSfx, SFX_WHITE_FAT_MALE_VOICE_1_CARJACKED_1, 3); break;
- case SOUND_PED_ROBBED: GetPhrase(sfx, lastSfx, SFX_WHITE_FAT_MALE_VOICE_1_MUGGED_1, 3); break;
- case SOUND_PED_EVADE: GetPhrase(sfx, lastSfx, SFX_WHITE_FAT_MALE_VOICE_1_DODGE_1, 9); break;
- case SOUND_PED_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_COWER: GetPhrase(sfx, ped->m_lastComment, 4591, 7); break;
+ case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, 4605, 4); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 4598, 7); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 4611, 2); break;
+ case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, 4619, 2); break;
+ case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, 4621, 2); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 4573, 9); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 4613, 6); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 4585, 6); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 4555, 9); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 4535, 9); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 4609, 2); break;
+ case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, ped->m_lastComment, 4582, 3); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 4544, 11); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 4564, 9); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetBlackFatMaleTalkSfx(int16 sound)
+cAudioManager::GetHMOCATalkSfx(CPed *ped, int16 sound)
{
uint32 sfx;
- static uint32 lastSfx = NO_SAMPLE;
- switch (sound) {
- case SOUND_PED_CAR_JACKED:
- GetPhrase(sfx, lastSfx, SFX_BLACK_FAT_MALE_VOICE_1_CARJACKED_1, 4);
- break;
- case SOUND_PED_ROBBED:
- GetPhrase(sfx, lastSfx, SFX_BLACK_FAT_MALE_VOICE_1_MUGGED_1, 3);
- break;
- case SOUND_PED_EVADE:
- GetPhrase(sfx, lastSfx, SFX_BLACK_FAT_MALE_VOICE_1_DODGE_1, 7);
- break;
- case SOUND_PED_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_COWER: GetPhrase(sfx, ped->m_lastComment, 3506, 5); break;
+ case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, 3521, 11); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 3511, 10); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 3532, 7); break;
+ case SOUND_PED_TAXI_WAIT: return 3541;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 3539, 2); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 3486, 8); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 3478, 8); break;
+ case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, ped->m_lastComment, 3504, 2); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 3494, 10); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetBlackCasualFemaleTalkSfx(int16 sound)
+cAudioManager::GetBMODKTalkSfx(CPed *ped, int16 sound)
{
uint32 sfx;
- static uint32 lastSfx = NO_SAMPLE;
- switch (sound) {
- case SOUND_PED_HANDS_COWER:
- GetPhrase(sfx, lastSfx, SFX_FEMALE_1_VOICE_1_GUN_PANIC_1, 2);
- break;
- case SOUND_PED_CAR_JACKED:
- GetPhrase(sfx, lastSfx, SFX_FEMALE_1_VOICE_1_CARJACKED_1, 2);
- break;
- case SOUND_PED_ROBBED:
- GetPhrase(sfx, lastSfx, SFX_FEMALE_1_VOICE_1_MUGGED_1, 3);
- break;
- case SOUND_PED_EVADE:
- GetPhrase(sfx, lastSfx, SFX_FEMALE_1_VOICE_1_DODGE_1, 6);
- break;
- case SOUND_PED_FLEE_RUN:
- GetPhrase(sfx, lastSfx, SFX_FEMALE_1_VOICE_1_RUN_FROM_FIGHT_1, 2);
- break;
- case SOUND_PED_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);
+ switch(sound) {
+ case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, 6831, 4); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 6838, 9); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 6847, 2); break;
+ case SOUND_PED_UNK_126: GetPhrase(sfx, ped->m_lastComment, 6835, 3); break;
+ case SOUND_PED_TAXI_WAIT: return 6853;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 6817, 7); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 6849, 4); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 6824, 7); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 6794, 10); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 6776, 8); break;
+ case SOUND_PED_147:
+ GetPhrase(sfx, ped->m_lastComment, 6805, 11);
+ switch(sfx) {
+ case 6809:
+ case 6810:
+ case 6811: GetPhrase(sfx, ped->m_lastComment, 6805, 4); break;
+ default: break;
+ }
break;
- default:
- return GetGenericFemaleTalkSfx(sound);
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 6784, 10); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetWhiteCasualFemaleTalkSfx(int16 sound)
+cAudioManager::GetBMYCRTalkSfx(CPed *ped, int16 sound)
{
uint32 sfx;
- static uint32 lastSfx = NO_SAMPLE;
- switch (sound) {
- case SOUND_PED_HANDS_COWER:
- GetPhrase(sfx, lastSfx, SFX_WHITE_CASUAL_FEMALE_VOICE_1_GUN_PANIC_1, 2);
- break;
- case SOUND_PED_CAR_JACKED:
- GetPhrase(sfx, lastSfx, SFX_WHITE_CASUAL_FEMALE_VOICE_1_CARJACKED_1, 2);
- break;
- case SOUND_PED_ROBBED:
- sfx = SFX_WHITE_CASUAL_FEMALE_VOICE_1_MUGGED_1;
- break;
- case SOUND_PED_EVADE:
- GetPhrase(sfx, lastSfx, SFX_WHITE_CASUAL_FEMALE_VOICE_1_DODGE_1, 3);
- break;
- case SOUND_PED_FLEE_RUN:
- GetPhrase(sfx, lastSfx, SFX_WHITE_CASUAL_FEMALE_VOICE_1_RUN_FROM_FIGHT_1, 2);
- break;
- case SOUND_PED_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_UP: GetPhrase(sfx, ped->m_lastComment, 6578, 6); break;
+ case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, 6594, 12); break;
+ case SOUND_PED_MUGGING: GetPhrase(sfx, ped->m_lastComment, 6609, 6); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 6588, 6); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 6606, 3); break;
+ case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, 6615, 2); break;
+ case SOUND_PED_UNK_126: GetPhrase(sfx, ped->m_lastComment, 6584, 4); break;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 6563, 8); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 6553, 8); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 6571, 7); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 6544, 9); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 6521, 12); break;
+ case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, ped->m_lastComment, 6561, 2); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 6533, 11); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetFemaleNo3TalkSfx(int16 sound)
+cAudioManager::GetBFYSTTalkSfx(CPed *ped, int16 sound)
{
uint32 sfx;
- static uint32 lastSfx = NO_SAMPLE;
- switch (sound) {
- case SOUND_PED_HANDS_COWER:
- GetPhrase(sfx, lastSfx, SFX_FEMALE_3_VOICE_1_GUN_PANIC_1, 5);
- break;
- case SOUND_PED_CAR_JACKED:
- GetPhrase(sfx, lastSfx, SFX_FEMALE_3_VOICE_1_CARJACKED_1, 3);
- break;
- case SOUND_PED_ROBBED:
- GetPhrase(sfx, lastSfx, SFX_FEMALE_3_VOICE_1_MUGGED_1, 3);
- break;
- case SOUND_PED_EVADE:
- GetPhrase(sfx, lastSfx, SFX_FEMALE_3_VOICE_1_DODGE_1, 6);
- break;
- case SOUND_PED_FLEE_RUN:
- GetPhrase(sfx, lastSfx, SFX_FEMALE_3_VOICE_1_RUN_FROM_FIGHT_1, 4);
- break;
- case SOUND_PED_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, 7184, 4); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 7188, 5); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 7195, 2); break;
+ case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, 7203, 2); break;
+ case SOUND_PED_TAXI_WAIT: return 7205;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 7167, 9); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 7197, 6); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 7176, 8); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 7149, 9); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 7132, 8); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 7193, 2); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 7140, 9); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 7158, 9); break;
+ default: return GetGenericFemaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetBlackFatFemaleTalkSfx(int16 sound)
+cAudioManager::GetBFOSTTalkSfx(CPed *ped, int16 sound)
{
uint32 sfx;
- static uint32 lastSfx = NO_SAMPLE;
- switch (sound) {
- case SOUND_PED_HANDS_COWER:
- GetPhrase(sfx, lastSfx, SFX_BLACK_FAT_FEMALE_VOICE_1_GUN_PANIC_1, 4);
- break;
- case SOUND_PED_CAR_JACKED:
- GetPhrase(sfx, lastSfx, SFX_BLACK_FAT_FEMALE_VOICE_1_CARJACKED_1, 2);
- break;
- case SOUND_PED_ROBBED:
- GetPhrase(sfx, lastSfx, SFX_BLACK_FAT_FEMALE_VOICE_1_MUGGED_1, 2);
- break;
- case SOUND_PED_EVADE:
- GetPhrase(sfx, lastSfx, SFX_BLACK_FAT_FEMALE_VOICE_1_DODGE_1, 5);
- break;
- case SOUND_PED_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_COWER: GetPhrase(sfx, ped->m_lastComment, 7046, 5); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 7051, 8); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 7061, 2); break;
+ case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, 7067, 2); break;
+ case SOUND_PED_TAXI_WAIT: return 7069;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 7027, 11); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 7063, 4); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 7038, 8); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 7009, 8); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 6992, 7); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 7059, 2); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 6999, 10); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 7017, 10); break;
+ default: return GetGenericFemaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetWhiteFatFemaleTalkSfx(int16 sound)
+cAudioManager::GetBMYSTTalkSfx(CPed *ped, int16 sound)
{
uint32 sfx;
- static uint32 lastSfx = NO_SAMPLE;
- switch (sound) {
- case SOUND_PED_CAR_JACKED:
- GetPhrase(sfx, lastSfx, SFX_WHITE_FAT_FEMALE_VOICE_1_CARJACKED_1, 2);
- break;
- case SOUND_PED_ROBBED:
- GetPhrase(sfx, lastSfx, SFX_WHITE_FAT_FEMALE_VOICE_1_MUGGED_1, 2);
- break;
- case SOUND_PED_EVADE:
- GetPhrase(sfx, lastSfx, SFX_WHITE_FAT_FEMALE_VOICE_1_DODGE_1, 6);
- break;
- case SOUND_PED_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_UP: GetPhrase(sfx, ped->m_lastComment, 6413, 6); break;
+ case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, 6427, 4); break;
+ case SOUND_PED_MUGGING: GetPhrase(sfx, ped->m_lastComment, 6433, 4); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 6419, 8); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 6431, 2); break;
+ case SOUND_PED_TAXI_WAIT: return 6437;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 6400, 6); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 6392, 8); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 6406, 7); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 6371, 9); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 6352, 8); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 6360, 11); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 6380, 12); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetBlackFemaleProstituteTalkSfx(int16 sound)
+cAudioManager::GetBMOSTTalkSfx(CPed *ped, int16 sound)
{
uint32 sfx;
- static uint32 lastSfx = NO_SAMPLE;
- switch (sound) {
- case SOUND_PED_HANDS_UP:
- GetPhrase(sfx, lastSfx, SFX_BLACK_PROSTITUTE_VOICE_1_GUN_COOL_1, 4);
- break;
- case SOUND_PED_ROBBED:
- sfx = SFX_BLACK_PROSTITUTE_VOICE_1_MUGGED_1;
- break;
- case SOUND_PED_ATTACK:
- GetPhrase(sfx, lastSfx, SFX_BLACK_PROSTITUTE_VOICE_1_FIGHT_1, 4);
- break;
- case SOUND_PED_EVADE:
- GetPhrase(sfx, lastSfx, SFX_BLACK_PROSTITUTE_VOICE_1_DODGE_1, 3);
- break;
- case SOUND_PED_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_COWER: GetPhrase(sfx, ped->m_lastComment, 4292, 9); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 4307, 4); break;
+ case SOUND_PED_ACCIDENTREACTION1: return 4311;
+ case SOUND_PED_TAXI_WAIT: return 4312;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 4272, 7); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 4258, 8); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 4279, 13); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 4232, 8); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 4301, 6); break;
+ case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, ped->m_lastComment, 4266, 6); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 4215, 17); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 4240, 18); 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(int16 sound)
+cAudioManager::GetBFYRITalkSfx(CPed *ped, int16 sound)
{
uint32 sfx;
- static uint32 lastSfx = NO_SAMPLE;
- switch (sound) {
- case SOUND_PED_ROBBED:
- GetPhrase(sfx, lastSfx, SFX_WHITE_PROSTITUTE_VOICE_1_MUGGED_1, 2);
- break;
- case SOUND_PED_ATTACK:
- GetPhrase(sfx, lastSfx, SFX_WHITE_PROSTITUTE_VOICE_1_FIGHT_1, 4);
- break;
- case SOUND_PED_EVADE:
- GetPhrase(sfx, lastSfx, SFX_WHITE_PROSTITUTE_VOICE_1_DODGE_1, 3);
- break;
- case SOUND_PED_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, 6161, 4); break;
+ case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, 6173, 4); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 6165, 8); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 6179, 3); break;
+ case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, 6188, 2); break;
+ case SOUND_PED_TAXI_WAIT: return 6194;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 6143, 8); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 6182, 6); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 6154, 7); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 6135, 8); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 6117, 9); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 6177, 2); break;
+ case SOUND_153: GetPhrase(sfx, ped->m_lastComment, 6151, 3); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 6190, 4); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 6126, 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::GetBlackProjectFemaleOldTalkSfx(int16 sound)
+cAudioManager::GetBFORITalkSfx(CPed *ped, int16 sound)
{
uint32 sfx;
- static uint32 lastSfx = NO_SAMPLE;
- switch (sound) {
- case SOUND_PED_CAR_JACKED:
- GetPhrase(sfx, lastSfx, SFX_BLACK_PROJECT_FEMALE_OLD_VOICE_1_CARJACKED_1, 6);
- break;
- case SOUND_PED_ROBBED:
- GetPhrase(sfx, lastSfx, SFX_BLACK_PROJECT_FEMALE_OLD_VOICE_1_MUGGED_1, 2);
- break;
- case SOUND_PED_EVADE:
- GetPhrase(sfx, lastSfx, SFX_BLACK_PROJECT_FEMALE_OLD_VOICE_1_DODGE_1, 10);
- break;
- case SOUND_PED_FLEE_RUN:
- GetPhrase(sfx, lastSfx, SFX_BLACK_PROJECT_FEMALE_OLD_VOICE_1_RUN_FROM_FIGHT_1, 6);
- break;
- case SOUND_PED_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_COWER: GetPhrase(sfx, ped->m_lastComment, 7110, 5); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 7115, 4); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 7121, 2); break;
+ case SOUND_PED_ACCIDENTREACTION1: return 7127;
+ case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, 7130, 2); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 7094, 9); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 7123, 4); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 7103, 7); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 7087, 7); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 7070, 8); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 7119, 2); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 7128, 2); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 7078, 9); break;
+ default: return GetGenericFemaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetBlackProjectFemaleYoungTalkSfx(int16 sound)
+cAudioManager::GetBMYRITalkSfx(CPed *ped, int16 sound)
{
+
uint32 sfx;
- static uint32 lastSfx = NO_SAMPLE;
- switch (sound) {
- case SOUND_PED_HANDS_COWER:
- GetPhrase(sfx, lastSfx, SFX_BLACK_PROJECT_FEMALE_YOUNG_VOICE_1_GUN_PANIC_1, 4);
- break;
- case SOUND_PED_CAR_JACKED:
- sfx = SFX_BLACK_PROJECT_FEMALE_YOUNG_VOICE_1_CARJACKED_1;
- break;
- case SOUND_PED_ROBBED:
- GetPhrase(sfx, lastSfx, SFX_BLACK_PROJECT_FEMALE_YOUNG_VOICE_1_MUGGED_1, 2);
- break;
- case SOUND_PED_EVADE:
- GetPhrase(sfx, lastSfx, SFX_BLACK_PROJECT_FEMALE_YOUNG_VOICE_1_DODGE_1, 5);
- break;
- case SOUND_PED_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, 5430, 7); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 5437, 4); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 5443, 2); break;
+ case SOUND_PED_ACCIDENTREACTION1: return 5449;
+ case SOUND_PED_TAXI_WAIT: return 5453;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 5414, 8); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 5445, 4); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 5423, 7); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 5407, 7); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 5394, 6); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 5441, 2); break;
+ case SOUND_PED_CHAT_SEXY: return 5422;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 5450, 3); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 5400, 7); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetChinatownMaleOldTalkSfx(int16 sound)
+cAudioManager::GetBFYBETalkSfx(CPed *ped, int16 sound)
{
uint32 sfx;
- static uint32 lastSfx = NO_SAMPLE;
- switch (sound) {
- case SOUND_PED_HANDS_COWER:
- GetPhrase(sfx, lastSfx, SFX_CHINATOWN_MALE_OLD_VOICE_1_GUN_PANIC_1, 3);
- break;
- case SOUND_PED_CAR_JACKED:
- GetPhrase(sfx, lastSfx, SFX_CHINATOWN_MALE_OLD_VOICE_1_CARJACKED_1, 2);
- break;
- case SOUND_PED_ATTACK:
- GetPhrase(sfx, lastSfx, SFX_CHINATOWN_MALE_OLD_VOICE_1_FIGHT_1, 5);
- break;
- case SOUND_PED_EVADE:
- GetPhrase(sfx, lastSfx, SFX_CHINATOWN_MALE_OLD_VOICE_1_DODGE_1, 6);
- break;
- case SOUND_PED_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_UP: GetPhrase(sfx, ped->m_lastComment, 6255, 6); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 6261, 8); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 6273, 5); break;
+ case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, 6284, 2); break;
+ case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, 6290, 3); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 6233, 10); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 6278, 6); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 6247, 8); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 6207, 8); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 6195, 12); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 6269, 4); break;
+ case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, ped->m_lastComment, 6243, 4); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 6286, 4); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 6217, 16); break;
+ default: return GetGenericFemaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetChinatownMaleYoungTalkSfx(int16 sound)
+cAudioManager::GetBMYBETalkSfx(CPed *ped, int16 sound)
{
uint32 sfx;
- static uint32 lastSfx = NO_SAMPLE;
- switch (sound) {
- case SOUND_PED_HANDS_COWER:
- GetPhrase(sfx, lastSfx, SFX_CHINATOWN_MALE_YOUNG_VOICE_1_GUN_PANIC_1, 2);
- break;
- case SOUND_PED_CAR_JACKED:
- GetPhrase(sfx, lastSfx, SFX_CHINATOWN_MALE_YOUNG_VOICE_1_CARJACKED_1, 2);
- break;
- case SOUND_PED_ATTACK:
- GetPhrase(sfx, lastSfx, SFX_CHINATOWN_MALE_YOUNG_VOICE_1_FIGHT_1, 6);
- break;
- case SOUND_PED_EVADE:
- GetPhrase(sfx, lastSfx, SFX_CHINATOWN_MALE_YOUNG_VOICE_1_DODGE_1, 5);
- break;
- case SOUND_PED_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_UP: GetPhrase(sfx, ped->m_lastComment, 956, 4); break;
+ case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, 966, 3); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 960, 6); break;
+ case SOUND_PED_ROBBED: return 970;
+ case SOUND_PED_ACCIDENTREACTION1: return 971;
+ case SOUND_PED_TAXI_WAIT: return 972;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 940, 8); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 928, 10); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 948, 8); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 910, 8); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 892, 8); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: return 969;
+ case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, ped->m_lastComment, 938, 2); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 900, 10); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 918, 10); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetChinatownFemaleOldTalkSfx(int16 sound)
+cAudioManager::GetBFOBETalkSfx(CPed *ped, int16 sound)
{
+
uint32 sfx;
- static uint32 lastSfx = NO_SAMPLE;
- switch (sound) {
- case SOUND_PED_HANDS_COWER:
- GetPhrase(sfx, lastSfx, SFX_CHINATOWN_OLD_FEMALE_VOICE_1_GUN_PANIC_1, 3);
- break;
- case SOUND_PED_ROBBED:
- GetPhrase(sfx, lastSfx, SFX_CHINATOWN_OLD_FEMALE_VOICE_1_MUGGED_1, 2);
- break;
- case SOUND_PED_EVADE:
- GetPhrase(sfx, lastSfx, SFX_CHINATOWN_OLD_FEMALE_VOICE_1_DODGE_1, 5);
- break;
- case SOUND_PED_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, 8213, 5); break;
+ case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, 8223, 4); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 8218, 5); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 8227, 2); break;
+ case SOUND_PED_TAXI_WAIT: return 8231;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 8197, 9); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 8206, 7); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 8182, 7); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 8166, 8); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 8229, 2); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 8174, 8); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 8189, 8); break;
+ default: return GetGenericFemaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetChinatownFemaleYoungTalkSfx(int16 sound)
+cAudioManager::GetBMOBETalkSfx(CPed *ped, int16 sound)
{
uint32 sfx;
- static uint32 lastSfx = NO_SAMPLE;
- switch (sound) {
- case SOUND_PED_CAR_JACKED:
- GetPhrase(sfx, lastSfx, SFX_CHINATOWN_YOUNG_FEMALE_VOICE_1_CARJACKED_1, 2);
- break;
- case SOUND_PED_ROBBED:
- GetPhrase(sfx, lastSfx, SFX_CHINATOWN_YOUNG_FEMALE_VOICE_1_MUGGED_1, 2);
- break;
- case SOUND_PED_EVADE:
- GetPhrase(sfx, lastSfx, SFX_CHINATOWN_YOUNG_FEMALE_VOICE_1_DODGE_1, 6);
- break;
- case SOUND_PED_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_COWER: GetPhrase(sfx, ped->m_lastComment, 7611, 5); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 7616, 6); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 7622, 4); break;
+ case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, 7626, 3); break;
+ case SOUND_PED_TAXI_WAIT: return 7632;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 7594, 10); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 7583, 11); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 7604, 7); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 7564, 9); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 7629, 3); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 7559, 5); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 7573, 10); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetLittleItalyMaleTalkSfx(int16 sound)
+cAudioManager::GetBMYBUTalkSfx(CPed *ped, int16 sound)
{
uint32 sfx;
- static uint32 lastSfx = NO_SAMPLE;
- switch (sound) {
- case SOUND_PED_HANDS_COWER:
- GetPhrase(sfx, lastSfx, SFX_LITTLE_ITALY_MALE_VOICE_1_GUN_PANIC_1, 3);
- break;
- case SOUND_PED_CAR_JACKED:
- GetPhrase(sfx, lastSfx, SFX_LITTLE_ITALY_MALE_VOICE_1_CARJACKED_1, 2);
- break;
- case SOUND_PED_ROBBED:
- GetPhrase(sfx, lastSfx, SFX_LITTLE_ITALY_MALE_VOICE_1_MUGGED_1, 2);
- break;
- case SOUND_PED_ATTACK:
- GetPhrase(sfx, lastSfx, SFX_LITTLE_ITALY_MALE_VOICE_1_FIGHT_1, 5);
- break;
- case SOUND_PED_EVADE:
- GetPhrase(sfx, lastSfx, SFX_LITTLE_ITALY_MALE_VOICE_1_DODGE_1, 5);
- break;
- case SOUND_PED_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_COWER: GetPhrase(sfx, ped->m_lastComment, 5500, 5); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 5507, 6); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 5513, 2); break;
+ case SOUND_PED_ACCIDENTREACTION1: return 5515;
+ case SOUND_PED_UNK_126: GetPhrase(sfx, ped->m_lastComment, 5505, 2); break;
+ case SOUND_PED_TAXI_WAIT: return 5518;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 5488, 5); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 5476, 10); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 5493, 7); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 5469, 7); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 5454, 8); break;
+ case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, ped->m_lastComment, 5486, 2); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 5516, 2); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 5462, 7); 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(int16 sound)
+cAudioManager::GetBFYPRTalkSfx(CPed *ped, int16 sound)
{
uint32 sfx;
- static uint32 lastSfx = NO_SAMPLE;
- switch (sound) {
- case SOUND_PED_CAR_JACKED:
- GetPhrase(sfx, lastSfx, SFX_LITTLE_ITALY_OLD_FEMALE_VOICE_1_CARJACKED_1, 2);
- break;
- case SOUND_PED_ROBBED:
- GetPhrase(sfx, lastSfx, SFX_LITTLE_ITALY_OLD_FEMALE_VOICE_1_MUGGED_1, 2);
- break;
- case SOUND_PED_EVADE:
- GetPhrase(sfx, lastSfx, SFX_LITTLE_ITALY_OLD_FEMALE_VOICE_1_DODGE_1, 6);
- break;
- case SOUND_PED_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_UP: GetPhrase(sfx, ped->m_lastComment, 5369, 5); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 5374, 2); break;
+ case SOUND_PED_ACCIDENTREACTION1: return 5376;
+ case SOUND_PED_PLAYER_BEFORESEX: GetPhrase(sfx, ped->m_lastComment, 5362, 7); break;
+ case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, 5392, 2); break;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 5355, 7); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 5348, 7); break;
+ case SOUND_PED_SOLICIT: GetPhrase(sfx, ped->m_lastComment, 5379, 13); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 5377, 2); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 5324, 11); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 5335, 13); break;
+ default: return GetGenericFemaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetLittleItalyFemaleYoungTalkSfx(int16 sound)
+cAudioManager::GetBFOTRTalkSfx(CPed *ped, int16 sound)
{
uint32 sfx;
- static uint32 lastSfx = NO_SAMPLE;
- switch (sound) {
- case SOUND_PED_CAR_JACKED:
- GetPhrase(sfx, lastSfx, SFX_LITTLE_ITALY_YOUNG_FEMALE_VOICE_1_CARJACKED_1, 2);
- break;
- case SOUND_PED_ROBBED:
- GetPhrase(sfx, lastSfx, SFX_LITTLE_ITALY_YOUNG_FEMALE_VOICE_1_MUGGED_1, 2);
- break;
- case SOUND_PED_EVADE:
- GetPhrase(sfx, lastSfx, SFX_LITTLE_ITALY_YOUNG_FEMALE_VOICE_1_DODGE_1, 7);
- break;
- case SOUND_PED_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_UP: GetPhrase(sfx, ped->m_lastComment, 5232, 6); break;
+ case SOUND_PED_MUGGING: GetPhrase(sfx, ped->m_lastComment, 5240, 3); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 5238, 2); break;
+ case SOUND_PED_ACCIDENTREACTION1: return 5243;
+ case SOUND_PED_TAXI_WAIT: return 5252;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 5226, 6); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 5217, 9); break;
+ case SOUND_PED_SOLICIT: GetPhrase(sfx, ped->m_lastComment, 5247, 5); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 5244, 3); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 5192, 10); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 5202, 15); break;
+ default: return GetGenericFemaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetWhiteDockerMaleTalkSfx(int16 sound)
+cAudioManager::GetBMOTRTalkSfx(CPed *ped, int16 sound)
{
uint32 sfx;
- static uint32 lastSfx = NO_SAMPLE;
- switch (sound) {
- case SOUND_PED_HANDS_COWER:
- GetPhrase(sfx, lastSfx, SFX_WHITE_DOCKER_MALE_VOICE_1_GUN_PANIC_1, 2);
- break;
- case SOUND_PED_ATTACK:
- GetPhrase(sfx, lastSfx, SFX_WHITE_DOCKER_MALE_VOICE_1_FIGHT_1, 3);
- break;
- case SOUND_PED_EVADE:
- GetPhrase(sfx, lastSfx, SFX_WHITE_DOCKER_MALE_VOICE_1_DODGE_1, 4);
- break;
- case SOUND_PED_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_UP: GetPhrase(sfx, ped->m_lastComment, 6327, 5); break;
+ case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, 6343, 1); break;
+ case SOUND_PED_UNK_126: GetPhrase(sfx, ped->m_lastComment, 6332, 4); break;
+ case SOUND_PED_TAXI_WAIT: return 6351;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 6313, 11); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 6336, 7); break;
+ case SOUND_PED_SOLICIT: GetPhrase(sfx, ped->m_lastComment, 6344, 7); break;
+ case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, ped->m_lastComment, 6324, 3); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 6293, 10); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 6303, 10); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetBlackDockerMaleTalkSfx(int16 sound)
+cAudioManager::GetBMYPITalkSfx(CPed *ped, int16 sound)
{
uint32 sfx;
- static uint32 lastSfx = NO_SAMPLE;
- switch (sound) {
- case SOUND_PED_HANDS_COWER:
- GetPhrase(sfx, lastSfx, SFX_BLACK_DOCKER_VOICE_1_GUN_PANIC_1, 3);
- break;
- case SOUND_PED_ATTACK:
- GetPhrase(sfx, lastSfx, SFX_BLACK_DOCKER_VOICE_1_FIGHT_1, 5);
- break;
- case SOUND_PED_EVADE:
- GetPhrase(sfx, lastSfx, SFX_BLACK_DOCKER_VOICE_1_DODGE_1, 5);
- break;
- case SOUND_PED_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, 4033, 5); break;
+ case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, 4044, 4); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 4038, 6); break;
+ case SOUND_PED_ROBBED: return 4048;
+ case SOUND_PED_ACCIDENTREACTION1: return 4049;
+ case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, 4050, 2); break;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 4012, 8); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 3998, 10); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 4020, 13); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 3993, 5); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 3978, 6); break;
+ case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, ped->m_lastComment, 4008, 4); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 3984, 9); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetScumMaleTalkSfx(int16 sound)
+cAudioManager::GetBMYBBTalkSfx(CPed *ped, int16 sound)
{
uint32 sfx;
- static uint32 lastSfx = NO_SAMPLE;
- switch (sound) {
- case SOUND_PED_HANDS_COWER:
- GetPhrase(sfx, lastSfx, SFX_SCUM_MALE_VOICE_1_GUN_PANIC_1, 5);
- break;
- case SOUND_PED_ROBBED:
- sfx = SFX_SCUM_MALE_VOICE_1_MUGGED_1;
- break;
- case SOUND_PED_ATTACK:
- GetPhrase(sfx, lastSfx, SFX_SCUM_MALE_VOICE_1_FIGHT_1, 10);
- break;
- case SOUND_PED_EVADE:
- GetPhrase(sfx, lastSfx, SFX_SCUM_MALE_VOICE_1_DODGE_1, 5);
- break;
- case SOUND_PED_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, 639, 5); break;
+ case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, 659, 9); break;
+ case SOUND_PED_MUGGING: GetPhrase(sfx, ped->m_lastComment, 691, 8); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 648, 11); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 686, 5); break;
+ case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, 699, 6); break;
+ case SOUND_PED_UNK_126: GetPhrase(sfx, ped->m_lastComment, 644, 4); break;
+ case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, 711, 3); break;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 618, 12); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 584, 18); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 630, 9); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 554, 9); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 524, 13); break;
+ case SOUND_PED_149: GetPhrase(sfx, ped->m_lastComment, 668, 16); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 684, 2); break;
+ case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, ped->m_lastComment, 602, 16); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 705, 6); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 537, 17); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 563, 21); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetScumFemaleTalkSfx(int16 sound)
+cAudioManager::GetWMYCRTalkSfx(CPed *ped, int16 sound)
{
uint32 sfx;
- static uint32 lastSfx = NO_SAMPLE;
- switch (sound) {
- case SOUND_PED_HANDS_COWER:
- GetPhrase(sfx, lastSfx, SFX_SCUM_FEMALE_VOICE_1_GUN_PANIC_1, 4);
- break;
- case SOUND_PED_ROBBED:
- GetPhrase(sfx, lastSfx, SFX_SCUM_FEMALE_VOICE_1_MUGGED_1, 2);
- break;
- case SOUND_PED_ATTACK:
- GetPhrase(sfx, lastSfx, SFX_SCUM_FEMALE_VOICE_1_FIGHT_1, 4);
- break;
- case SOUND_PED_EVADE:
- GetPhrase(sfx, lastSfx, SFX_SCUM_FEMALE_VOICE_1_DODGE_1, 8);
- break;
- case SOUND_PED_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, 5056, 5); break;
+ case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, 5061, 6); break;
+ case SOUND_PED_MUGGING: GetPhrase(sfx, ped->m_lastComment, 5070, 5); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 5067, 3); break;
+ case SOUND_PED_TAXI_WAIT: return 5075;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 5040, 7); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 5030, 10); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 5047, 9); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 5021, 9); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 5003, 18); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetWhiteWorkerMaleTalkSfx(int16 sound)
+cAudioManager::GetWFYSTTalkSfx(CPed *ped, int16 sound)
{
uint32 sfx;
- static uint32 lastSfx = NO_SAMPLE;
- switch (sound) {
- case SOUND_PED_HANDS_COWER:
- GetPhrase(sfx, lastSfx, SFX_WHITE_WORKER_MALE_VOICE_1_GUN_PANIC_1, 3);
- break;
- case SOUND_PED_ATTACK:
- GetPhrase(sfx, lastSfx, SFX_WHITE_WORKER_MALE_VOICE_1_FIGHT_1, 3);
- break;
- case SOUND_PED_EVADE:
- GetPhrase(sfx, lastSfx, SFX_WHITE_WORKER_MALE_VOICE_1_DODGE_1, 4);
- break;
- case SOUND_PED_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, 8445, 5); break;
+ case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, 8456, 4); break;
+ case SOUND_PED_MUGGING: GetPhrase(sfx, ped->m_lastComment, 8463, 4); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 8450, 6); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 8461, 2); break;
+ case SOUND_PED_ACCIDENTREACTION1: return 8467;
+ case SOUND_PED_TAXI_WAIT: return 8468;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 8430, 7); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 8420, 10); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 8437, 8); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 8402, 8); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 8386, 6); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: return 8460;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 8392, 10); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 8410, 10); break;
+ default: return GetGenericFemaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetBlackWorkerMaleTalkSfx(int16 sound)
+cAudioManager::GetWFOSTTalkSfx(CPed *ped, int16 sound)
{
uint32 sfx;
- static uint32 lastSfx = NO_SAMPLE;
- switch (sound) {
- case SOUND_PED_HANDS_COWER:
- GetPhrase(sfx, lastSfx, SFX_BLACK_WORKER_MALE_VOICE_1_GUN_PANIC_1, 4);
- break;
- case SOUND_PED_ATTACK:
- GetPhrase(sfx, lastSfx, SFX_BLACK_WORKER_MALE_VOICE_1_FIGHT_1, 3);
- break;
- case SOUND_PED_EVADE:
- GetPhrase(sfx, lastSfx, SFX_BLACK_WORKER_MALE_VOICE_1_DODGE_1, 3);
- break;
- case SOUND_PED_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_COWER: GetPhrase(sfx, ped->m_lastComment, 8354, 4); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 8358, 8); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 8369, 5); break;
+ case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, 8381, 4); break;
+ case SOUND_PED_TAXI_WAIT: return 8385;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 8332, 12); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 8374, 7); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 8344, 10); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 8305, 11); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 8274, 12); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 8366, 3); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 8286, 19); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 8316, 16); break;
+ default: return GetGenericFemaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetBusinessMaleYoungTalkSfx(int16 sound, int32 model)
+cAudioManager::GetWMYSTTalkSfx(CPed *ped, int16 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_COWER: GetPhrase(sfx, ped->m_lastComment, 3947, 5); break;
+ case SOUND_PED_MUGGING: GetPhrase(sfx, ped->m_lastComment, 3963, 5); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 3955, 5); break;
+ case SOUND_PED_ROBBED: return 3962;
+ case SOUND_PED_ACCIDENTREACTION1: return 3975;
+ case SOUND_PED_UNK_126: GetPhrase(sfx, ped->m_lastComment, 3952, 3); break;
+ case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, 3976, 2); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 3930, 10); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 3968, 7); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 3942, 5); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 3912, 8); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 3893, 8); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 3960, 2); break;
+ case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, ped->m_lastComment, 3940, 2); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 3901, 11); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 3920, 10); break;
+ default: return GetGenericMaleTalkSfx(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::GetBusinessMaleOldTalkSfx(int16 sound)
+cAudioManager::GetWMOSTTalkSfx(CPed *ped, int16 sound)
{
uint32 sfx;
- static uint32 lastSfx = NO_SAMPLE;
- switch (sound) {
- case SOUND_PED_HANDS_COWER:
- GetPhrase(sfx, lastSfx, SFX_BUSINESS_MALE_OLD_VOICE_1_GUN_PANIC_1, 3);
- break;
- case SOUND_PED_CAR_JACKED:
- GetPhrase(sfx, lastSfx, SFX_BUSINESS_MALE_OLD_VOICE_1_CARJACKED_1, 2);
- break;
- case SOUND_PED_ROBBED:
- GetPhrase(sfx, lastSfx, SFX_BUSINESS_MALE_OLD_VOICE_1_MUGGED_1, 2);
- break;
- case SOUND_PED_ATTACK:
- GetPhrase(sfx, lastSfx, SFX_BUSINESS_MALE_OLD_VOICE_1_FIGHT_1, 5);
- break;
- case SOUND_PED_EVADE:
- GetPhrase(sfx, lastSfx, SFX_BUSINESS_MALE_OLD_VOICE_1_DODGE_1, 4);
- break;
- case SOUND_PED_FLEE_RUN:
- GetPhrase(sfx, lastSfx, SFX_BUSINESS_MALE_OLD_VOICE_1_MRUN_FROM_FIGHT_1, 5);
- break;
- case SOUND_PED_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, 5170, 5); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 5178, 4); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 5188, 2); break;
+ case SOUND_PED_ACCIDENTREACTION1: return 5190;
+ case SOUND_PED_UNK_126: GetPhrase(sfx, ped->m_lastComment, 5175, 3); break;
+ case SOUND_PED_TAXI_WAIT: return 5191;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 5155, 8); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 5145, 8); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 5163, 7); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 5129, 7); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 5111, 8); break;
+ case SOUND_PED_149: GetPhrase(sfx, ped->m_lastComment, 5182, 4); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 5186, 2); break;
+ case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, ped->m_lastComment, 5153, 2); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 5119, 10); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 5136, 9); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetWhiteBusinessFemaleTalkSfx(int16 sound, int32 model)
+cAudioManager::GetWFYRITalkSfx(CPed *ped, int16 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, 5299, 5); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 5304, 7); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 5313, 2); break;
+ case SOUND_PED_ACCIDENTREACTION1: return 5320;
+ case SOUND_PED_TAXI_WAIT: return 5323;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 5280, 9); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 5315, 5); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 5291, 8); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 5271, 9); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 5253, 8); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 5311, 2); break;
+ case SOUND_153: GetPhrase(sfx, ped->m_lastComment, 5289, 2); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 5321, 2); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 5261, 10); 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::GetBlackBusinessFemaleTalkSfx(int16 sound)
+cAudioManager::GetWFORITalkSfx(CPed *ped, int16 sound)
{
uint32 sfx;
- static uint32 lastSfx = NO_SAMPLE;
- switch (sound) {
- case SOUND_PED_HANDS_COWER:
- GetPhrase(sfx, lastSfx, SFX_BLACK_BUSINESS_FEMALE_VOICE_1_GUN_PANIC_1, 5);
- break;
- case SOUND_PED_CAR_JACKED:
- GetPhrase(sfx, lastSfx, SFX_BLACK_BUSINESS_FEMALE_VOICE_1_CARAJACKED_1, 4);
- break;
- case SOUND_PED_ROBBED:
- GetPhrase(sfx, lastSfx, SFX_BLACK_BUSINESS_FEMALE_VOICE_1_MUGGED_1, 3);
- break;
- case SOUND_PED_EVADE:
- GetPhrase(sfx, lastSfx, SFX_BLACK_BUSINESS_FEMALE_VOICE_1_DODGE_1, 6);
- break;
- case SOUND_PED_FLEE_RUN:
- GetPhrase(sfx, lastSfx, SFX_BLACK_BUSINESS_FEMALE_VOICE_1_RUN_FROM_FIGHT_1, 6);
- break;
- case SOUND_PED_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_COWER: GetPhrase(sfx, ped->m_lastComment, 7825, 6); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 7831, 6); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 7839, 3); break;
+ case SOUND_PED_ACCIDENTREACTION1: return 7842;
+ case SOUND_PED_TAXI_WAIT: return 7846;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 7810, 7); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 7799, 11); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 7817, 8); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 7789, 10); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 7771, 7); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 7837, 2); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 7843, 3); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 7778, 11); break;
+ default: return GetGenericFemaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetSupermodelMaleTalkSfx(int16 sound)
+cAudioManager::GetWMYRITalkSfx(CPed *ped, int16 sound)
{
uint32 sfx;
- static uint32 lastSfx = NO_SAMPLE;
- switch (sound) {
- case SOUND_PED_CAR_JACKED:
- GetPhrase(sfx, lastSfx, SFX_MODEL_MALE_VOICE_1_CARJACKED_1, 2);
- break;
- case SOUND_PED_ROBBED:
- GetPhrase(sfx, lastSfx, SFX_MODEL_MALE_VOICE_1_MUGGED_1, 2);
- break;
- case SOUND_PED_ATTACK:
- GetPhrase(sfx, lastSfx, SFX_MODEL_MALE_VOICE_1_FIGHT_1, 5);
- break;
- case SOUND_PED_EVADE:
- GetPhrase(sfx, lastSfx, SFX_MODEL_MALE_VOICE_1_DODGE_1, 6);
- break;
- case SOUND_PED_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_COWER: GetPhrase(sfx, ped->m_lastComment, 4186, 8); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 4194, 8); break;
+ case SOUND_PED_ACCIDENTREACTION1: return 4208;
+ case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, 4213, 2); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 4163, 9); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 4203, 5); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 4175, 11); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 4144, 9); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 4126, 10); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: return 4202;
+ case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, ped->m_lastComment, 4172, 3); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 4209, 4); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 4136, 8); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetSupermodelFemaleTalkSfx(int16 sound)
+cAudioManager::GetWMORITalkSfx(CPed *ped, int16 sound)
{
uint32 sfx;
- static uint32 lastSfx = NO_SAMPLE;
- switch (sound) {
- case SOUND_PED_HANDS_COWER:
- GetPhrase(sfx, lastSfx, SFX_MODEL_FEMALE_VOICE_1_GUN_PANIC_1, 4);
- break;
- case SOUND_PED_ROBBED:
- GetPhrase(sfx, lastSfx, SFX_MODEL_FEMALE_VOICE_1_MUGGED_1, 3);
- break;
- case SOUND_PED_EVADE:
- GetPhrase(sfx, lastSfx, SFX_MODEL_FEMALE_VOICE_1_DODGE_1, 4);
- break;
- case SOUND_PED_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, 6668, 9); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 6677, 6); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 6685, 4); break;
+ case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, 6701, 2); break;
+ case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, 6707, 2); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 6647, 10); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 6689, 12); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 6660, 8); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 6641, 6); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 6617, 10); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 6683, 2); break;
+ case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, ped->m_lastComment, 6657, 3); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 6703, 4); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 6627, 14); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetStewardMaleTalkSfx(int16 sound)
+cAudioManager::GetWFYBETalkSfx(CPed *ped, int16 sound)
{
uint32 sfx;
- static uint32 lastSfx = NO_SAMPLE;
- switch (sound) {
- case SOUND_PED_HANDS_COWER:
- GetPhrase(sfx, lastSfx, SFX_STEWARD_MALE_VOICE_1_GUN_PANIC_1, 3);
- break;
- case SOUND_PED_ATTACK:
- GetPhrase(sfx, lastSfx, SFX_STEWARD_MALE_VOICE_1_FIGHT_1, 4);
- break;
- case SOUND_PED_EVADE:
- GetPhrase(sfx, lastSfx, SFX_STEWARD_MALE_VOICE_1_DODGE_1, 3);
- break;
- case SOUND_PED_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, 7752, 5); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 7757, 4); break;
+ case SOUND_PED_ACCIDENTREACTION1: return 7766;
+ case SOUND_PED_TAXI_WAIT: return 7770;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 7738, 8); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 7761, 5); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 7746, 6); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 7722, 6); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 7704, 7); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 7767, 3); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 7711, 11); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 7728, 10); break;
+ default: return GetGenericFemaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetStewardFemaleTalkSfx(int16 sound)
+cAudioManager::GetWMYBETalkSfx(CPed *ped, int16 sound)
{
uint32 sfx;
- static uint32 lastSfx = NO_SAMPLE;
- switch (sound) {
- case SOUND_PED_HANDS_COWER:
- GetPhrase(sfx, lastSfx, SFX_STEWARD_FEMALE_VOICE_1_GUN_PANIC_1, 3);
- break;
- case SOUND_PED_EVADE:
- GetPhrase(sfx, lastSfx, SFX_STEWARD_FEMALE_VOICE_1_DODGE_1, 5);
- break;
- case SOUND_PED_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, 8127, 8); break;
+ case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, 8142, 3); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 8135, 7); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 8105, 12); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 8155, 5); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 8119, 8); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 8086, 8); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 8063, 9); break;
+ case SOUND_PED_149: GetPhrase(sfx, ped->m_lastComment, 8145, 7); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 8152, 3); break;
+ case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, ped->m_lastComment, 8117, 2); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 8160, 6); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 8072, 14); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 8094, 11); break;
+ default: return GetGenericMaleTalkSfx(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(int16 sound, int32 model)
+cAudioManager::GetWFOBETalkSfx(CPed *ped, int16 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, 6093, 5); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 6098, 4); break;
+ case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, 6109, 3); break;
+ case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, 6115, 2); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 6075, 8); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 6102, 7); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 6083, 10); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 6058, 7); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 6040, 8); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 6112, 3); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 6048, 10); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 6065, 10); break;
+ default: return GetGenericFemaleTalkSfx(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(int16 sound)
+cAudioManager::GetWMOBETalkSfx(CPed *ped, int16 sound)
{
uint32 sfx;
- static uint32 lastSfx = NO_SAMPLE;
- switch (sound) {
- case SOUND_PED_ROBBED:
- sfx = SFX_FOOTBALL_FEMALE_VOICE_1_MUGGED_1;
- break;
- case SOUND_PED_EVADE:
- GetPhrase(sfx, lastSfx, SFX_FOOTBALL_FEMALE_VOICE_1_DODGE_1, 4);
- break;
- case SOUND_PED_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_COWER: GetPhrase(sfx, ped->m_lastComment, 3759, 5); break;
+ case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, 3772, 4); break;
+ case SOUND_PED_MUGGING: GetPhrase(sfx, ped->m_lastComment, 3792, 6); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 3764, 8); break;
+ case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, 3802, 2); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 3742, 8); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 3798, 4); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 3752, 7); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 3724, 8); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 3706, 6); break;
+ case SOUND_PED_149: GetPhrase(sfx, ped->m_lastComment, 3776, 16); break;
+ case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, ped->m_lastComment, 3750, 2); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 3804, 2); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 3712, 12); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 3732, 10); 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(int16 sound)
+cAudioManager::GetWMYCWTalkSfx(CPed *ped, int16 sound)
{
uint32 sfx;
- static uint32 lastSfx = NO_SAMPLE;
- switch (sound) {
- case SOUND_PED_HANDS_COWER:
- GetPhrase(sfx, lastSfx, SFX_HOSPITAL_MALE_VOICE_1_GUN_PANIC_1, 4);
- break;
- case SOUND_PED_ATTACK:
- GetPhrase(sfx, lastSfx, SFX_HOSPITAL_MALE_VOICE_1_FIGHT_1, 4);
- break;
- case SOUND_PED_EVADE:
- GetPhrase(sfx, lastSfx, SFX_HOSPITAL_MALE_VOICE_1_DODGE_1, 4);
- break;
- case SOUND_PED_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, 5650, 6); break;
+ case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, 5670, 4); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 5659, 6); break;
+ case SOUND_PED_ROBBED: return 5676;
+ case SOUND_PED_TAXI_WAIT: return 5677;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 5635, 8); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 5622, 10); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 5643, 7); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 5598, 9); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 5580, 9); break;
+ case SOUND_PED_149: GetPhrase(sfx, ped->m_lastComment, 5665, 5); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 5674, 2); break;
+ case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, ped->m_lastComment, 5632, 3); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 5589, 9); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 5607, 15); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetHospitalFemaleTalkSfx(int16 sound)
+cAudioManager::GetWMYGOTalkSfx(CPed *ped, int16 sound)
{
uint32 sfx;
- static uint32 lastSfx = NO_SAMPLE;
- switch (sound) {
- case SOUND_PED_EVADE:
- GetPhrase(sfx, lastSfx, SFX_HOSPITAL_FEMALE_VOICE_1_DODGE_1, 5);
- break;
- case SOUND_PED_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, 7679, 5); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 7684, 6); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 7690, 2); break;
+ case SOUND_PED_ACCIDENTREACTION1: return 7698;
+ case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, 7701, 3); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 7659, 11); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 7692, 6); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 7672, 7); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 7642, 7); break;
+ case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, ped->m_lastComment, 7670, 2); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 7699, 2); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 7633, 9); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 7649, 10); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetWhiteConstructionWorkerTalkSfx(int16 sound)
+cAudioManager::GetWFOGOTalkSfx(CPed *ped, int16 sound)
{
uint32 sfx;
- static uint32 lastSfx = NO_SAMPLE;
- switch (sound) {
- case SOUND_PED_HANDS_COWER:
- GetPhrase(sfx, lastSfx, SFX_WHITE_MALE_CONSTRUCTION_VOICE_1_GUN_PANIC_1, 3);
- break;
- case SOUND_PED_CAR_JACKED:
- sfx = SFX_WHITE_MALE_CONSTRUCTION_VOICE_1_CARJACKED_1;
- break;
- case SOUND_PED_ATTACK:
- GetPhrase(sfx, lastSfx, SFX_WHITE_MALE_CONSTRUCTION_VOICE_1_FIGHT_1, 5);
- break;
- case SOUND_PED_EVADE:
- GetPhrase(sfx, lastSfx, SFX_WHITE_MALE_CONSTRUCTION_VOICE_1_DODGE_1, 5);
- break;
- case SOUND_PED_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, 7904, 5); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 7909, 6); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 7915, 2); break;
+ case SOUND_PED_ACCIDENTREACTION1: return 7919;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 7883, 14); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 7874, 9); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 7917, 2); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 7897, 7); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 7855, 8); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 7920, 2); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 7847, 8); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 7863, 11); break;
+ default: return GetGenericFemaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetBlackConstructionWorkerTalkSfx(int16 sound)
+cAudioManager::GetWMOGOTalkSfx(CPed *ped, int16 sound)
{
uint32 sfx;
- static uint32 lastSfx = NO_SAMPLE;
- switch (sound) {
- case SOUND_PED_HANDS_COWER:
- GetPhrase(sfx, lastSfx, SFX_BLACK_CONSTRUCTION_MALE_VOICE_1_GUN_PANIC_1, 3);
- break;
- case SOUND_PED_CAR_JACKED:
- GetPhrase(sfx, lastSfx, SFX_BLACK_CONSTRUCTION_MALE_VOICE_1_CARJACKED_1, 2);
- break;
- case SOUND_PED_ATTACK:
- GetPhrase(sfx, lastSfx, SFX_BLACK_CONSTRUCTION_MALE_VOICE_1_FIGHT_1, 5);
- break;
- case SOUND_PED_EVADE:
- GetPhrase(sfx, lastSfx, SFX_BLACK_CONSTRUCTION_MALE_VOICE_1_DODGE_1, 5);
- break;
- case SOUND_PED_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, 4982, 5); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 4987, 6); break;
+ case SOUND_PED_ACCIDENTREACTION1: return 4998;
+ case SOUND_PED_TAXI_WAIT: return 5002;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 4961, 13); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 4947, 12); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 4993, 5); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 4974, 8); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 4929, 9); break;
+ case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, ped->m_lastComment, 4959, 2); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 4999, 3); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 4921, 8); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 4938, 9); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetShopperFemaleTalkSfx(int16 sound, int32 model)
+cAudioManager::GetWFYLGTalkSfx(CPed *ped, int16 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_UP: GetPhrase(sfx, ped->m_lastComment, 8267, 5); break;
+ case SOUND_PED_ACCIDENTREACTION1: return 8272;
+ case SOUND_PED_TAXI_WAIT: return 8273;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 8260, 7); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 8252, 8); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 8232, 10); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 8242, 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::GetWMYLGTalkSfx(CPed *ped, int16 sound)
+{
+ uint32 sfx;
+
+ switch(sound) {
+ case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, 3698, 6); break;
+ case SOUND_PED_ACCIDENTREACTION1: return 3704;
+ case SOUND_PED_TAXI_WAIT: return 3705;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 3691, 7); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 3682, 9); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 3662, 10); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 3672, 10); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetStudentMaleTalkSfx(int16 sound)
+cAudioManager::GetWFYBUTalkSfx(CPed *ped, int16 sound)
{
uint32 sfx;
- static uint32 lastSfx = NO_SAMPLE;
- switch (sound) {
- case SOUND_PED_HANDS_COWER:
- GetPhrase(sfx, lastSfx, SFX_STUDENT_MALE_VOICE_1_GUN_PANIC_1, 2);
- break;
- case SOUND_PED_ROBBED:
- GetPhrase(sfx, lastSfx, SFX_STUDENT_MALE_VOICE_1_MUGGED_1, 2);
- break;
- case SOUND_PED_ATTACK:
- GetPhrase(sfx, lastSfx, SFX_STUDENT_MALE_VOICE_1_FIGHT_1, 4);
- break;
- case SOUND_PED_EVADE:
- GetPhrase(sfx, lastSfx, SFX_STUDENT_MALE_VOICE_1_DODGE_1, 4);
- break;
- case SOUND_PED_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, 7309, 8); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 7317, 8); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 7325, 4); break;
+ case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, 7340, 2); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 7329, 8); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 7301, 8); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 7292, 9); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 7337, 3); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 7271, 21); break;
+ default: return GetGenericFemaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetStudentFemaleTalkSfx(int16 sound)
+cAudioManager::GetWMYBUTalkSfx(CPed *ped, int16 sound)
{
uint32 sfx;
- static uint32 lastSfx = NO_SAMPLE;
- switch (sound) {
- case SOUND_PED_HANDS_COWER:
- GetPhrase(sfx, lastSfx, SFX_STUDENT_FEMALE_VOICE_1_GUN_PANIC_1, 4);
- break;
- case SOUND_PED_ROBBED:
- GetPhrase(sfx, lastSfx, SFX_STUDENT_FEMALE_VOICE_1_MUGGED_1, 2);
- break;
- case SOUND_PED_ATTACK:
- GetPhrase(sfx, lastSfx, SFX_STUDENT_FEMALE_VOICE_1_FIGHT_1, 4);
- break;
- case SOUND_PED_EVADE:
- GetPhrase(sfx, lastSfx, SFX_STUDENT_FEMALE_VOICE_1_DODGE_1, 4);
- break;
- case SOUND_PED_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, 3862, 6); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 3870, 5); break;
+ case SOUND_PED_ROBBED: return 3880;
+ case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, 3884, 2); break;
+ case SOUND_PED_UNK_126: GetPhrase(sfx, ped->m_lastComment, 3868, 2); break;
+ case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, 3891, 2); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 3845, 10); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 3881, 3); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 3857, 5); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 3826, 9); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 3706, 6); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 3875, 5); break;
+ case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, ped->m_lastComment, 3855, 2); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 3886, 5); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 3815, 11); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 3835, 10); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetCasualMaleOldTalkSfx(int16 sound)
+cAudioManager::GetWMOBUTalkSfx(CPed *ped, int16 sound)
{
- return GetGenericMaleTalkSfx(sound);
+ uint32 sfx;
+
+ switch(sound) {
+ case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, 6753, 6); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 6759, 7); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 6769, 2); break;
+ case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, 6771, 3); break;
+ case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, 6774, 2); break;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 6743, 3); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 6733, 8); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 6746, 7); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 6726, 7); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 6709, 7); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 6766, 3); break;
+ case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, ped->m_lastComment, 6741, 2); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 6716, 10); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
+ }
+ return sfx;
}
uint32
-cAudioManager::GetSpecialCharacterTalkSfx(int32 modelIndex, int32 sound)
+cAudioManager::GetWFYPRTalkSfx(CPed *ped, int16 sound)
{
- char *modelName = CModelInfo::GetModelInfo(modelIndex)->GetName();
- if (!CGeneral::faststricmp(modelName, "eight") || !CGeneral::faststricmp(modelName, "eight2")) {
- return GetEightTalkSfx(sound);
- }
- if (!CGeneral::faststricmp(modelName, "frankie")) {
- return GetFrankieTalkSfx(sound);
+ uint32 sfx;
+
+ switch(sound) {
+ case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, 4101, 6); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 4107, 2); break;
+ case SOUND_PED_ACCIDENTREACTION1: return 4109;
+ case SOUND_PED_PLAYER_BEFORESEX: GetPhrase(sfx, ped->m_lastComment, 4096, 5); break;
+ case SOUND_PED_TAXI_WAIT: return 4125;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 4087, 9); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 4077, 10); break;
+ case SOUND_PED_SOLICIT: GetPhrase(sfx, ped->m_lastComment, 4110, 15); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 4052, 11); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 4063, 14); break;
+ default: return GetGenericFemaleTalkSfx(ped, sound);
}
- if (!CGeneral::faststricmp(modelName, "misty")) {
- return GetMistyTalkSfx(sound);
+ return sfx;
+}
+
+uint32
+cAudioManager::GetWFOTRTalkSfx(CPed *ped, int16 sound)
+{
+ uint32 sfx;
+
+ switch(sound) {
+ case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, 7371, 6); break;
+ case SOUND_PED_ACCIDENTREACTION1: return 7383;
+ case SOUND_PED_TAXI_WAIT: return 7393;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 7362, 9); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 7377, 6); break;
+ case SOUND_PED_SOLICIT: GetPhrase(sfx, ped->m_lastComment, 7384, 9); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 7342, 11); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 7353, 9); break;
+ default: return GetGenericFemaleTalkSfx(ped, sound);
}
- if (!CGeneral::faststricmp(modelName, "ojg") || !CGeneral::faststricmp(modelName, "ojg_p")) {
- return GetOJGTalkSfx(sound);
+ return sfx;
+}
+
+uint32
+cAudioManager::GetWMOTRTalkSfx(CPed *ped, int16 sound)
+{
+ uint32 sfx;
+
+ switch(sound) {
+ case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, 7542, 5); break;
+ case SOUND_PED_ACCIDENTREACTION1: return 7547;
+ case SOUND_PED_TAXI_WAIT: return 7558;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 7536, 6); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 7517, 17); break;
+ case SOUND_PED_SOLICIT: GetPhrase(sfx, ped->m_lastComment, 7551, 7); break;
+ case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, ped->m_lastComment, 7534, 2); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 7548, 3); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 7494, 10); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 7504, 13); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
- if (!CGeneral::faststricmp(modelName, "cat")) {
- return GetCatatalinaTalkSfx(sound);
+ return sfx;
+}
+
+uint32
+cAudioManager::GetWMYPITalkSfx(CPed *ped, int16 sound)
+{
+ uint32 sfx;
+
+ switch(sound) {
+ case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, 6496, 5); break;
+ case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, 6509, 4); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 6503, 6); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 6513, 2); break;
+ case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, 6515, 2); break;
+ case SOUND_PED_UNK_126: GetPhrase(sfx, ped->m_lastComment, 6501, 2); break;
+ case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, 6517, 4); break;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 6479, 7); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 6465, 8); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 6488, 8); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 6457, 8); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 6439, 8); break;
+ case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, ped->m_lastComment, 6473, 6); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 6447, 10); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
- if (!CGeneral::faststricmp(modelName, "bomber")) {
- return GetBomberTalkSfx(sound);
+ return sfx;
+}
+
+uint32
+cAudioManager::GetWMOCATalkSfx(CPed *ped, int16 sound)
+{
+ uint32 sfx;
+
+ switch(sound) {
+ case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, 8032, 6); break;
+ case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, 8048, 11); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 8038, 10); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 8059, 2); break;
+ case SOUND_PED_ACCIDENTREACTION1: return 8061;
+ case SOUND_PED_TAXI_WAIT: return 8062;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 8015, 8); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 8003, 10); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 8023, 9); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 7993, 10); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 7975, 12); break;
+ case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, ped->m_lastComment, 8013, 2); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 7987, 6); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
- if (!CGeneral::faststricmp(modelName, "s_guard")) {
- return GetSecurityGuardTalkSfx(sound);
+ return sfx;
+}
+
+uint32
+cAudioManager::GetWFYJGTalkSfx(CPed *ped, int16 sound)
+{
+ uint32 sfx;
+ switch(sound) {
+ case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, 7414, 4); break;
+ case SOUND_PED_ACCIDENTREACTION1: sfx = 7424; break;
+ case SOUND_PED_TAXI_WAIT: sfx = 7425; break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 7406, 8); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 7418, 6); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 7394, 12); break;
+ default: return GetGenericFemaleTalkSfx(ped, sound);
}
- if (!CGeneral::faststricmp(modelName, "chunky")) {
- return GetChunkyTalkSfx(sound);
+ return sfx;
+}
+
+uint32
+cAudioManager::GetWMYJGTalkSfx(CPed *ped, int16 sound)
+{
+ uint32 sfx;
+
+ switch(sound) {
+ case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, 5098, 4); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 5102, 2); break;
+ case SOUND_PED_ACCIDENTREACTION1: return 5109;
+ case SOUND_PED_TAXI_WAIT: return 5110;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 5104, 5); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 5076, 10); break;
+ case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, ped->m_lastComment, 5096, 2); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 5086, 10); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
- if (!CGeneral::faststricmp(modelName, "asuka")) {
- return GetGenericFemaleTalkSfx(sound);
+ return sfx;
+}
+
+uint32
+cAudioManager::GetWFYSKTalkSfx(CPed *ped, int16 sound)
+{
+ uint32 sfx;
+
+ switch(sound) {
+ case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, 3652, 5); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 3657, 2); break;
+ case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, 3659, 2); break;
+ case SOUND_PED_TAXI_WAIT: return 3661;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 3641, 11); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 3632, 9); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 3603, 11); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 3614, 18); break;
+ default: return GetGenericFemaleTalkSfx(ped, sound);
}
- if (!CGeneral::faststricmp(modelName, "maria")) {
- return GetGenericFemaleTalkSfx(sound);
+ return sfx;
+}
+
+uint32
+cAudioManager::GetWMYSKTalkSfx(CPed *ped, int16 sound)
+{
+ uint32 sfx;
+
+ switch(sound) {
+ case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, 5563, 5); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 5573, 2); break;
+ case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, 5575, 2); break;
+ case SOUND_PED_UNK_126: GetPhrase(sfx, ped->m_lastComment, 5568, 3); break;
+ case SOUND_PED_TAXI_WAIT: return 5579;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 5558, 5); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 5546, 10); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 5571, 2); break;
+ case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, ped->m_lastComment, 5556, 2); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 5577, 2); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 5519, 14); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 5533, 13); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
+ return sfx;
+}
- return GetGenericMaleTalkSfx(sound);
+uint32
+cAudioManager::GetWFYSHTalkSfx(CPed *ped, int16 sound)
+{
+ uint32 sfx;
+
+ switch(sound) {
+ case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, 7459, 9); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 7470, 2); break;
+ case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, 7483, 4); break;
+ case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, 7492, 2); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 7448, 11); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 7472, 11); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 7468, 2); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 7487, 5); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 7426, 12); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 7438, 10); break;
+ default: return GetGenericFemaleTalkSfx(ped, sound);
+ }
+ return sfx;
}
+
uint32
-cAudioManager::GetEightTalkSfx(int16 sound)
+cAudioManager::GetWFOSHTalkSfx(CPed *ped, int16 sound)
{
uint32 sfx;
- static uint32 lastSfx = NO_SAMPLE;
- switch (sound) {
- case SOUND_PED_HANDS_UP:
- GetPhrase(sfx, lastSfx, SFX_8BALL_GUN_COOL_1, 2);
- break;
- case SOUND_PED_ROBBED:
- GetPhrase(sfx, lastSfx, SFX_8BALL_MUGGED_1, 2);
- break;
- case SOUND_PED_ATTACK:
- GetPhrase(sfx, lastSfx, SFX_8BALL_FIGHT_1, 6);
- break;
- case SOUND_PED_EVADE:
- GetPhrase(sfx, lastSfx, SFX_8BALL_DODGE_1, 7);
- break;
- default:
- return GetGenericMaleTalkSfx(sound);
+ switch(sound) {
+ case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, 3571, 10); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 3583, 2); break;
+ case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, 3594, 3); break;
+ case SOUND_PED_TAXI_WAIT: return 3602;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 3561, 10); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 3585, 9); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 3581, 2); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 3597, 5); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 3542, 10); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 3552, 9); break;
+ default: return GetGenericFemaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetFrankieTalkSfx(int16 sound)
+cAudioManager::GetJFOTOTalkSfx(CPed *ped, int16 sound)
{
uint32 sfx;
- static uint32 lastSfx = NO_SAMPLE;
- switch (sound) {
- case SOUND_PED_HANDS_UP:
- GetPhrase(sfx, lastSfx, SFX_SALVATORE_GUN_COOL_1, 4);
- break;
- case SOUND_PED_ROBBED:
- GetPhrase(sfx, lastSfx, SFX_SALVATORE_MUGGED_1, 2);
- break;
- case SOUND_PED_ATTACK:
- GetPhrase(sfx, lastSfx, SFX_SALVATORE_FIGHT_1, 6);
- break;
- case SOUND_PED_EVADE:
- GetPhrase(sfx, lastSfx, SFX_SALVATORE_DODGE_1, 3);
- break;
- default:
- return GetGenericMaleTalkSfx(sound);
+ switch(sound) {
+ case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, 811, 4); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 815, 5); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 821, 2); break;
+ case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, 828, 2); break;
+ case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, 831, 2); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 796, 9); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 823, 5); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 805, 6); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 775, 8); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 757, 8); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: return 820;
+ case SOUND_PED_CHAT_EVENT: return 830;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 765, 10); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 783, 13); break;
+ default: return GetGenericFemaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetMistyTalkSfx(int16 sound)
+cAudioManager::GetJMOTOTalkSfx(CPed *ped, int16 sound)
{
uint32 sfx;
- static uint32 lastSfx = NO_SAMPLE;
- switch (sound) {
- case SOUND_PED_HANDS_UP:
- GetPhrase(sfx, lastSfx, SFX_MISTY_GUN_COOL_1, 5);
- break;
- case SOUND_PED_ROBBED:
- GetPhrase(sfx, lastSfx, SFX_MISTY_MUGGED_1, 2);
- break;
- case SOUND_PED_ATTACK:
- GetPhrase(sfx, lastSfx, SFX_MISTY_FIGHT_1, 4);
- break;
- case SOUND_PED_EVADE:
- GetPhrase(sfx, lastSfx, SFX_MISTY_DODGE_1, 5);
- break;
- case SOUND_PED_TAXI_CALL:
- GetPhrase(sfx, lastSfx, SFX_MISTY_HERE_1, 4);
- break;
- default:
- return GetGenericFemaleTalkSfx(sound);
- break;
+ switch(sound) {
+ case SOUND_PED_HANDS_COWER: GetPhrase(sfx, ped->m_lastComment, 874, 4); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 878, 4); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 883, 2); break;
+ case SOUND_PED_ACCIDENTREACTION1: return 889;
+ case SOUND_PED_TAXI_WAIT: return 891;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 862, 6); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 885, 4); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 868, 6); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 849, 6); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 833, 8); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: return 882;
+ case SOUND_PED_CHAT_EVENT: return 890;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 841, 8); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 855, 7); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetOJGTalkSfx(int16 sound)
+cAudioManager::GetCBTalkSfx(CPed *ped, int16 sound)
+{
+ uint32 sfx;
+
+ switch(sound) {
+ case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, 2178, 5); break;
+ case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, 2187, 5); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 2183, 4); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 2194, 2); break;
+ case SOUND_PED_ACCIDENTREACTION1: sfx = 2196; break;
+ case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, 2197, 2); break;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 2161, 9); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 2150, 9); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 2170, 8); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 2132, 8); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 2113, 8); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 2192, 2); break;
+ case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, ped->m_lastComment, 2159, 2); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 2121, 11); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 2140, 10); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
+ }
+ return 86 * (m_sQueueSample.m_nEntityIndex % 3) + sfx;
+}
+
+uint32
+cAudioManager::GetHNTalkSfx(CPed *ped, int16 sound)
+{
+ uint32 sfx;
+
+ switch(sound) {
+ case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, 2692, 5); break;
+ case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, 2703, 4); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 2697, 6); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 2711, 3); break;
+ case SOUND_PED_ACCIDENTREACTION1: sfx = 2714; break;
+ case SOUND_PED_TAXI_WAIT: sfx = 2715; break;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 2673, 10); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 2661, 10); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 2683, 9); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 2638, 9); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 2617, 9); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 2707, 4); break;
+ case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, ped->m_lastComment, 2671, 2); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 2626, 12); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 2647, 14); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
+ }
+ return 99 * (m_sQueueSample.m_nEntityIndex % 3) + sfx;
+}
+
+uint32
+cAudioManager::GetSGTalkSfx(CPed *ped, int16 sound)
+{
+ uint32 sfx;
+
+ switch(sound) {
+ case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, 1104, 5); break;
+ case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, 1114, 5); break;
+ case SOUND_PED_MUGGING: GetPhrase(sfx, ped->m_lastComment, 1124, 5); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 1109, 5); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 1121, 3); break;
+ case SOUND_PED_ACCIDENTREACTION1: sfx = 1129; break;
+ case SOUND_PED_TAXI_WAIT: sfx = 1132; break;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 1088, 10); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 1076, 9); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 1098, 6); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 1058, 6); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 1040, 8); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 1119, 2); break;
+ case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, ped->m_lastComment, 1085, 3); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 1130, 2); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 1048, 10); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 1064, 12); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
+ }
+ if(ped->GetModelIndex() == MI_SGB) sfx += 93;
+ return sfx;
+}
+
+uint32
+cAudioManager::GetCLTalkSfx(CPed *ped, int16 sound)
{
- return GetGenericMaleTalkSfx(sound);
+ uint32 sfx;
+
+ switch(sound) {
+ case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, 1299, 5); break;
+ case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, 1310, 5); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 1304, 6); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 1317, 2); break;
+ case SOUND_PED_ACCIDENTREACTION1: sfx = 1319; break;
+ case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, 1320, 2); break;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 1281, 10); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 1266, 13); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 1291, 8); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 1246, 10); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 1226, 10); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 1315, 2); break;
+ case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, ped->m_lastComment, 1279, 2); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 1236, 10); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 1256, 10); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
+ }
+ return 96 * (m_sQueueSample.m_nEntityIndex % 3) + sfx;
}
uint32
-cAudioManager::GetCatatalinaTalkSfx(int16 sound)
+cAudioManager::GetGDTalkSfx(CPed *ped, int16 sound)
{
- return GetGenericFemaleTalkSfx(sound);
+ uint32 sfx;
+
+ switch(sound) {
+ case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, 1762, 6); break;
+ case SOUND_PED_ACCIDENTREACTION1: GetPhrase(sfx, ped->m_lastComment, 1770, 2); break;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 1755, 7); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 1744, 9); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 1768, 2); break;
+ case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, ped->m_lastComment, 1753, 2); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 1772, 2); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 1724, 10); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 1734, 10); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
+ }
+ return 50 * (m_sQueueSample.m_nEntityIndex % 3) + sfx;
}
uint32
-cAudioManager::GetBomberTalkSfx(int16 sound)
+cAudioManager::GetBKTalkSfx(CPed *ped, int16 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, 2429, 5); break;
+ case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, 2442, 4); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 2434, 8); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 2448, 2); break;
+ case SOUND_PED_ACCIDENTREACTION1: sfx = 2450; break;
+ case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, 2451, 2); break;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 2412, 9); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 2403, 9); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 2421, 8); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 2371, 10); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 2446, 2); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 2381, 10); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 2391, 12); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
+ }
+ return 82 * (m_sQueueSample.m_nEntityIndex % 3) + sfx;
+}
+
+uint32
+cAudioManager::GetPGTalkSfx(CPed *ped, int16 sound)
+{
+ uint32 sfx;
+
+ switch(sound) {
+ case SOUND_PED_HANDS_UP: GetPhrase(sfx, ped->m_lastComment, 1561, 4); break;
+ case SOUND_PED_CAR_JACKING: GetPhrase(sfx, ped->m_lastComment, 1570, 5); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 1565, 5); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 1577, 2); break;
+ case SOUND_PED_ACCIDENTREACTION1: sfx = 1579; break;
+ case SOUND_PED_TAXI_WAIT: GetPhrase(sfx, ped->m_lastComment, 1582, 2); break;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 1551, 5); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 1542, 7); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 1556, 5); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 1529, 5); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 1514, 10); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 1575, 2); break;
+ case SOUND_PED_CHAT_SEXY: GetPhrase(sfx, ped->m_lastComment, 1549, 2); break;
+ case SOUND_PED_CHAT_EVENT: GetPhrase(sfx, ped->m_lastComment, 1580, 2); break;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 1524, 5); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 1534, 8); break;
+ default: return GetGenericMaleTalkSfx(ped, sound);
+ }
+ return 70 * (m_sQueueSample.m_nEntityIndex % 3) + sfx;
+}
+
+uint32
+cAudioManager::GetVICETalkSfx(CPed *ped, int16 sound, int16 model)
+{
+ uint32 sfx;
+ if(model == MI_VICE6) {
+
+ switch(sound) {
+ case SOUND_PED_ARREST_COP: GetPhrase(sfx, ped->m_lastComment, 1894, 3); break;
+ case SOUND_PED_MIAMIVICE_EXITING_CAR: return 1897;
+ default: return GetGenericMaleTalkSfx(ped, sound);
+ }
+ }
+ switch(sound) {
+ case SOUND_PED_ARREST_COP: GetPhrase(sfx, ped->m_lastComment, 1874, 3); break;
+ case SOUND_PED_MIAMIVICE_EXITING_CAR: sfx = 1877; break;
+
+ default: return GetGenericMaleTalkSfx(ped, sound);
}
+ sfx += 4 * (m_sQueueSample.m_nEntityIndex % 5);
return sfx;
}
uint32
-cAudioManager::GetSecurityGuardTalkSfx(int16 sound)
+cAudioManager::GetWFYG1TalkSfx(CPed *ped, int16 sound)
{
uint32 sfx;
- static uint32 lastSfx = NO_SAMPLE;
- switch (sound) {
- case SOUND_PED_HANDS_UP:
- GetPhrase(sfx, lastSfx, SFX_SECURITY_GUARD_VOICE_1_GUN_COOL_1, 2);
- break;
- case SOUND_PED_HANDS_COWER:
- sfx = SFX_SECURITY_GUARD_VOICE_1_GUN_PANIC_1;
- break;
- case SOUND_PED_CAR_JACKED:
- case SOUND_PED_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_UP: GetPhrase(sfx, ped->m_lastComment, 3383, 6); break;
+ case SOUND_PED_MUGGING: GetPhrase(sfx, ped->m_lastComment, 3399, 2); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 3389, 5); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 3397, 2); break;
+ case SOUND_PED_ACCIDENTREACTION1: return 3403;
+ case SOUND_PED_TAXI_WAIT: return 3405;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 3372, 4); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 3361, 9); break;
+ case SOUND_PED_FLEE_RUN: GetPhrase(sfx, ped->m_lastComment, 3401, 2); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 3376, 7); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 3342, 9); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 3324, 7); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: GetPhrase(sfx, ped->m_lastComment, 3394, 3); break;
+ case SOUND_153: GetPhrase(sfx, ped->m_lastComment, 3370, 2); break;
+ case SOUND_PED_CHAT_EVENT: return 3404;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 3331, 11); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 3351, 10); break;
+ default: return GetGenericFemaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetChunkyTalkSfx(int16 sound)
+cAudioManager::GetWFYG2TalkSfx(CPed *ped, int16 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_UP: GetPhrase(sfx, ped->m_lastComment, 3464, 3); break;
+ case SOUND_PED_CAR_JACKED: GetPhrase(sfx, ped->m_lastComment, 3467, 5); break;
+ case SOUND_PED_ROBBED: GetPhrase(sfx, ped->m_lastComment, 3473, 2); break;
+ case SOUND_PED_TAXI_WAIT: return 3476;
+ case SOUND_PED_ATTACK: GetPhrase(sfx, ped->m_lastComment, 3452, 5); break;
+ case SOUND_PED_EVADE: GetPhrase(sfx, ped->m_lastComment, 3440, 8); break;
+ case SOUND_PED_CRASH_VEHICLE: GetPhrase(sfx, ped->m_lastComment, 3457, 7); break;
+ case SOUND_PED_CRASH_CAR: GetPhrase(sfx, ped->m_lastComment, 3422, 9); break;
+ case SOUND_PED_ANNOYED_DRIVER: GetPhrase(sfx, ped->m_lastComment, 3406, 5); break;
+ case SOUND_PED_WAIT_DOUBLEBACK: return 3472;
+ case SOUND_153: GetPhrase(sfx, ped->m_lastComment, 3448, 4); break;
+ case SOUND_PED_CHAT_EVENT: return 3475;
+ case SOUND_PED_PED_COLLISION: GetPhrase(sfx, ped->m_lastComment, 3411, 11); break;
+ case SOUND_PED_CHAT: GetPhrase(sfx, ped->m_lastComment, 3431, 9); break;
+ default: return GetGenericFemaleTalkSfx(ped, sound);
}
return sfx;
}
uint32
-cAudioManager::GetGenericMaleTalkSfx(int16 sound)
+cAudioManager::GetGenericMaleTalkSfx(CPed *ped, int16 sound)
{
uint32 sfx;
- static uint32 lastSfx = NO_SAMPLE;
- switch (sound) {
- case SOUND_PED_DEATH:
- GetPhrase(sfx, lastSfx, SFX_GENERIC_MALE_DEATH_1, 8);
- break;
+ 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, 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;
+ 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;
}
uint32
-cAudioManager::GetGenericFemaleTalkSfx(int16 sound)
+cAudioManager::GetGenericFemaleTalkSfx(CPed *ped, int16 sound)
{
uint32 sfx;
- static uint32 lastSfx = NO_SAMPLE;
-
- switch (sound) {
- case SOUND_PED_DEATH:
- GetPhrase(sfx, lastSfx, SFX_GENERIC_FEMALE_DEATH_1, 10);
- break;
+ m_bGenericSfx = true;
+ switch(sound) {
+ case SOUND_PED_DEATH: GetPhrase(sfx, ped->m_lastComment, 2931, 22); 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;
+ case SOUND_PED_DEFEND: GetPhrase(sfx, ped->m_lastComment, 2953, 33); break;
+ case SOUND_PED_BURNING: GetPhrase(sfx, ped->m_lastComment, 2914, 17); break;
+ case SOUND_PED_FLEE_SPRINT: GetPhrase(sfx, ped->m_lastComment, 2986, 27); break;
+ default: return NO_SAMPLE;
}
return sfx;
}
@@ -6075,57 +7811,69 @@ 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;
- AudioManager.m_sQueueSample.m_nLoopStart = 0;
- AudioManager.m_sQueueSample.m_nLoopEnd = -1;
- AudioManager.m_sQueueSample.m_nEmittingVolume = MAX_VOLUME;
- AudioManager.m_sQueueSample.m_fSpeedMultiplier = 3.0f;
- switch (sampleIndex) {
- case SFX_POLICE_HELI_1:
- case SFX_POLICE_HELI_2:
- case SFX_POLICE_HELI_3:
- AudioManager.m_sQueueSample.m_fSoundIntensity = 400.0f;
- break;
- default:
- AudioManager.m_sQueueSample.m_fSoundIntensity = 50.0f;
- break;
+ bool 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;
+ AudioManager.m_sQueueSample.m_nLoopStart = 0;
+ AudioManager.m_sQueueSample.m_nLoopEnd = -1;
+ AudioManager.m_sQueueSample.m_nEmittingVolume = MAX_VOLUME;
+ AudioManager.m_sQueueSample.m_fSpeedMultiplier = 3.0f;
+ 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 >= 8694 && sampleIndex < TOTAL_AUDIO_SAMPLES) { // check if player sfx, TODO: enum
+ 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
@@ -6148,8 +7896,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
@@ -6158,11 +7912,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) {
@@ -6170,42 +7923,44 @@ 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);
+ m_sQueueSample.m_fDistance = distSquared <= 0.0f ? 0.0f : Sqrt(distSquared);
m_sQueueSample.m_nVolume = ComputeVolume(MAX_VOLUME, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance);
if (m_sQueueSample.m_nVolume != 0) {
m_sQueueSample.m_nCounter = i;
@@ -6213,12 +7968,10 @@ 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;
m_sQueueSample.m_nLoopStart = 0;
m_sQueueSample.m_nLoopEnd = -1;
m_sQueueSample.m_bReverbFlag = true;
- m_sQueueSample.m_bRequireReflection = true;
AddSampleToRequestedQueue();
}
}
@@ -6239,7 +7992,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;
@@ -6255,7 +8008,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);
@@ -6263,17 +8016,16 @@ 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;
}
m_sQueueSample.m_vecPos = gFireManager.m_aFires[i].m_vecPos;
distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos);
if (distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) {
- m_sQueueSample.m_fDistance = Sqrt(distSquared);
+ m_sQueueSample.m_fDistance = distSquared < 0.0f ? 0.0f : Sqrt(distSquared);
m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance);
if (m_sQueueSample.m_nVolume != 0) {
m_sQueueSample.m_nCounter = i;
@@ -6291,6 +8043,30 @@ 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;
+ m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_bReverbFlag = true;
+ m_sQueueSample.m_bRequireReflection = false;
+ AddSampleToRequestedQueue();
+ }
+ }
}
}
}
@@ -6305,18 +8081,10 @@ cAudioManager::ProcessWaterCannon(int32)
m_sQueueSample.m_vecPos = CWaterCannons::aCannons[0].m_avecPos[CWaterCannons::aCannons[i].m_nCur];
float distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos);
if (distSquared < SQR(SOUND_INTENSITY)) {
- m_sQueueSample.m_fDistance = Sqrt(distSquared);
-#ifdef FIX_BUGS
+ m_sQueueSample.m_fDistance = distSquared <= 0.0f ? 0.0f : Sqrt(distSquared);
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;
@@ -6339,6 +8107,91 @@ cAudioManager::ProcessWaterCannon(int32)
}
}
+//positon of arcade machines
+CVector aVecExtraSoundPosition[] = { {-1042.546f, 88.794f, 11.324f}, {-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)) {
+ if (distance > 0.0f)
+ m_sQueueSample.m_fDistance = Sqrt(distance);
+ else
+ m_sQueueSample.m_fDistance = 0.0f;
+ 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;
+ m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(SFX_ARCADE);
+ m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(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::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)) {
+ if (distance > 0.0f)
+ m_sQueueSample.m_fDistance = Sqrt(distance);
+ else
+ m_sQueueSample.m_fDistance = 0.0f;
+ 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;
+ m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(SFX_BOAT_V12_LOOP);
+ m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(SFX_BOAT_V12_LOOP);
+ m_sQueueSample.m_bReverbFlag = true;
+ m_sQueueSample.m_bReleasingSoundFlag = false;
+ m_sQueueSample.m_bRequireReflection = false;
+ AddSampleToRequestedQueue();
+ }
+ }
+ }
+}
+
#pragma region SCRIPT_OBJECTS
const int SCRIPT_OBJECT_INTENSITY_S = 30;
const int SCRIPT_OBJECT_INTENSITY_L = 80;
@@ -6346,13 +8199,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);
+ }
}
}
@@ -6369,7 +8224,7 @@ 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_S:
case SCRIPT_SOUND_INJURED_PED_MALE_OUCH_L:
male.m_pPed = nil;
male.m_bDistanceCalculated = false;
@@ -6397,7 +8252,7 @@ cAudioManager::ProcessOneShotScriptObject(uint8 sound)
m_sQueueSample.m_bIs2D = false;
m_sQueueSample.m_bRequireReflection = true;
emittingVolume = RandomDisplacement(10) + 50;
- break;
+ break;*/
case SCRIPT_SOUND_BULLET_HIT_GROUND_1:
case SCRIPT_SOUND_BULLET_HIT_GROUND_2:
case SCRIPT_SOUND_BULLET_HIT_GROUND_3:
@@ -6411,19 +8266,20 @@ 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))
+ if (!SampleManager.IsSampleBankLoaded(SAMPLEBANK_TRAIN))
return;
m_sQueueSample.m_fSoundIntensity = 80.0f;
m_sQueueSample.m_nSampleIndex = SFX_TRAIN_STATION_ANNOUNCE;
- m_sQueueSample.m_nBankIndex = SFX_BANK_TRAIN;
+ m_sQueueSample.m_nBankIndex = SAMPLEBANK_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;
m_sQueueSample.m_bIs2D = false;
- break;
+ break;*/
case SCRIPT_SOUND_PAYPHONE_RINGING:
m_sQueueSample.m_fSoundIntensity = 80.0f;
m_sQueueSample.m_nSampleIndex = SFX_PHONE_RING;
@@ -6611,10 +8467,10 @@ cAudioManager::ProcessLoopingScriptObject(uint8 sound)
float distSquared;
switch (sound) {
- case SCRIPT_SOUND_PARTY_1_LOOP_S:
+ /*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;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;//SAMPLEBANK_BUILDING_CLUB_1;
emittingVolume = MAX_VOLUME;
m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_1);
m_sQueueSample.m_nReleasingVolumeModificator = 3;
@@ -6624,7 +8480,7 @@ cAudioManager::ProcessLoopingScriptObject(uint8 sound)
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;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;//SAMPLEBANK_BUILDING_CLUB_1;
emittingVolume = MAX_VOLUME;
m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_1);
m_sQueueSample.m_nReleasingVolumeModificator = 3;
@@ -6634,7 +8490,7 @@ cAudioManager::ProcessLoopingScriptObject(uint8 sound)
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;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;//SAMPLEBANK_BUILDING_CLUB_2;
emittingVolume = MAX_VOLUME;
m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_2);
m_sQueueSample.m_nReleasingVolumeModificator = 3;
@@ -6644,7 +8500,7 @@ cAudioManager::ProcessLoopingScriptObject(uint8 sound)
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;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;//SAMPLEBANK_BUILDING_CLUB_2;
emittingVolume = MAX_VOLUME;
m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_2);
m_sQueueSample.m_nReleasingVolumeModificator = 3;
@@ -6654,7 +8510,7 @@ cAudioManager::ProcessLoopingScriptObject(uint8 sound)
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;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;//SAMPLEBANK_BUILDING_CLUB_3;
emittingVolume = MAX_VOLUME;
m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_3);
m_sQueueSample.m_nReleasingVolumeModificator = 3;
@@ -6664,7 +8520,7 @@ cAudioManager::ProcessLoopingScriptObject(uint8 sound)
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;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;//SAMPLEBANK_BUILDING_CLUB_3;
emittingVolume = MAX_VOLUME;
m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_3);
m_sQueueSample.m_nReleasingVolumeModificator = 3;
@@ -6674,7 +8530,7 @@ cAudioManager::ProcessLoopingScriptObject(uint8 sound)
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;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;//SAMPLEBANK_BUILDING_CLUB_4;
emittingVolume = MAX_VOLUME;
m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_4);
m_sQueueSample.m_nReleasingVolumeModificator = 3;
@@ -6684,501 +8540,23 @@ cAudioManager::ProcessLoopingScriptObject(uint8 sound)
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;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;//SAMPLEBANK_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;
- m_sQueueSample.m_nReleasingVolumeDivider = 3;
- m_sQueueSample.m_fSpeedMultiplier = 2.0f;
- break;
- case SCRIPT_SOUND_STRIP_CLUB_LOOP_2_L:
- m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_L;
- m_sQueueSample.m_nSampleIndex = SFX_STRIP_CLUB_2;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_STRIP_CLUB_2;
- emittingVolume = MAX_VOLUME;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_STRIP_CLUB_2);
- m_sQueueSample.m_nReleasingVolumeModificator = 3;
- m_sQueueSample.m_nReleasingVolumeDivider = 3;
- m_sQueueSample.m_fSpeedMultiplier = 2.0f;
- break;
- case SCRIPT_SOUND_WORK_SHOP_LOOP_S:
- case SCRIPT_SOUND_WORK_SHOP_LOOP_L:
- ProcessWorkShopScriptObject(sound);
- return;
- case SCRIPT_SOUND_SAWMILL_LOOP_S:
- case SCRIPT_SOUND_SAWMILL_LOOP_L:
- ProcessSawMillScriptObject(sound);
- return;
- case SCRIPT_SOUND_38:
- m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_S;
- m_sQueueSample.m_nSampleIndex = SFX_DOG_FOOD_FACTORY;
- m_sQueueSample.m_nBankIndex = 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);
- 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;
- 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;
- m_sQueueSample.m_nReleasingVolumeDivider = 3;
- m_sQueueSample.m_fSpeedMultiplier = 2.0f;
- break;
- case SCRIPT_SOUND_47_L:
- m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_L;
- m_sQueueSample.m_nSampleIndex = SFX_RESTAURANT_GENERIC_1;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_RESTAURANT_GENERIC_1;
- emittingVolume = 110;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_RESTAURANT_GENERIC_1);
- m_sQueueSample.m_nReleasingVolumeModificator = 3;
- m_sQueueSample.m_nReleasingVolumeDivider = 3;
- m_sQueueSample.m_fSpeedMultiplier = 2.0f;
- break;
- case SCRIPT_SOUND_MARCO_BISTRO_S:
- m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_S;
- m_sQueueSample.m_nSampleIndex = SFX_RESTAURANT_GENERIC_2;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_RESTAURANT_GENERIC_2;
- emittingVolume = 110;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_RESTAURANT_GENERIC_2);
- m_sQueueSample.m_nReleasingVolumeModificator = 3;
- m_sQueueSample.m_nReleasingVolumeDivider = 3;
- m_sQueueSample.m_fSpeedMultiplier = 2.0f;
- break;
- case SCRIPT_SOUND_MARCO_BISTRO_L:
- m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_L;
- m_sQueueSample.m_nSampleIndex = SFX_RESTAURANT_GENERIC_2;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_RESTAURANT_GENERIC_2;
- emittingVolume = 110;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_RESTAURANT_GENERIC_2);
- m_sQueueSample.m_nReleasingVolumeModificator = 3;
- m_sQueueSample.m_nReleasingVolumeDivider = 3;
- m_sQueueSample.m_fSpeedMultiplier = 2.0f;
- break;
- case SCRIPT_SOUND_AIRPORT_LOOP_S:
- case SCRIPT_SOUND_AIRPORT_LOOP_L:
- ProcessAirportScriptObject(sound);
- return;
- case SCRIPT_SOUND_SHOP_LOOP_S:
- case SCRIPT_SOUND_SHOP_LOOP_L:
- ProcessShopScriptObject(sound);
- return;
- case SCRIPT_SOUND_CINEMA_LOOP_S:
- case SCRIPT_SOUND_CINEMA_LOOP_L:
- ProcessCinemaScriptObject(sound);
- return;
- case SCRIPT_SOUND_DOCKS_LOOP_S:
- case SCRIPT_SOUND_DOCKS_LOOP_L:
- ProcessDocksScriptObject(sound);
- return;
- case SCRIPT_SOUND_HOME_LOOP_S:
- case SCRIPT_SOUND_HOME_LOOP_L:
- ProcessHomeScriptObject(sound);
- return;
- case SCRIPT_SOUND_FRANKIE_PIANO:
- m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_S;
- m_sQueueSample.m_nSampleIndex = SFX_PIANO_BAR_1;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_PIANO_BAR;
- emittingVolume = MAX_VOLUME;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_PIANO_BAR_1);
- m_sQueueSample.m_nReleasingVolumeModificator = 3;
- m_sQueueSample.m_nReleasingVolumeDivider = 3;
- m_sQueueSample.m_fSpeedMultiplier = 2.0f;
- break;
case SCRIPT_SOUND_PARTY_1_LOOP:
m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_L;
m_sQueueSample.m_nSampleIndex = SFX_CLUB_1;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_CLUB_1;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;//SAMPLEBANK_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_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;
- 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);
- m_sQueueSample.m_nReleasingVolumeModificator = 3;
- m_sQueueSample.m_nReleasingVolumeDivider = 3;
- m_sQueueSample.m_fSpeedMultiplier = 2.0f;
- break;
- case SCRIPT_SOUND_RAVE_LOOP_INDUSTRIAL_L:
- m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_L;
- m_sQueueSample.m_nSampleIndex = SFX_RAVE_INDUSTRIAL;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_RAVE_INDUSTRIAL;
- emittingVolume = MAX_VOLUME;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_RAVE_INDUSTRIAL);
- m_sQueueSample.m_nReleasingVolumeModificator = 3;
- m_sQueueSample.m_nReleasingVolumeDivider = 3;
- m_sQueueSample.m_fSpeedMultiplier = 2.0f;
- break;
- case SCRIPT_SOUND_POLICE_CELL_BEATING_LOOP_S:
- case SCRIPT_SOUND_POLICE_CELL_BEATING_LOOP_L:
- ProcessPoliceCellBeatingScriptObject(sound);
- return;
- case SCRIPT_SOUND_RAVE_1_LOOP_S:
- case SCRIPT_SOUND_RAVE_2_LOOP_S:
- m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_S;
- m_sQueueSample.m_nSampleIndex = SFX_RAVE_COMMERCIAL;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_RAVE_COMMERCIAL;
- emittingVolume = MAX_VOLUME;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_nReleasingVolumeModificator = 3;
- m_sQueueSample.m_nReleasingVolumeDivider = 3;
- m_sQueueSample.m_fSpeedMultiplier = 2.0f;
- break;
- case SCRIPT_SOUND_RAVE_1_LOOP_L:
- case SCRIPT_SOUND_RAVE_2_LOOP_L:
- m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_L;
- m_sQueueSample.m_nSampleIndex = SFX_RAVE_COMMERCIAL;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_RAVE_COMMERCIAL;
- emittingVolume = MAX_VOLUME;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_nReleasingVolumeModificator = 3;
- m_sQueueSample.m_nReleasingVolumeDivider = 3;
- m_sQueueSample.m_fSpeedMultiplier = 2.0f;
- break;
- case SCRIPT_SOUND_RAVE_3_LOOP_S:
- m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_S;
- m_sQueueSample.m_nSampleIndex = SFX_RAVE_SUBURBAN;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_RAVE_SUBURBAN;
- emittingVolume = MAX_VOLUME;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_RAVE_SUBURBAN);
- m_sQueueSample.m_nReleasingVolumeModificator = 3;
- m_sQueueSample.m_nReleasingVolumeDivider = 3;
- m_sQueueSample.m_fSpeedMultiplier = 2.0f;
- break;
- case SCRIPT_SOUND_RAVE_3_LOOP_L:
- m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_L;
- m_sQueueSample.m_nSampleIndex = SFX_RAVE_SUBURBAN;
- m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_RAVE_SUBURBAN;
- emittingVolume = MAX_VOLUME;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_RAVE_SUBURBAN);
- m_sQueueSample.m_nReleasingVolumeModificator = 3;
- m_sQueueSample.m_nReleasingVolumeDivider = 3;
- m_sQueueSample.m_fSpeedMultiplier = 2.0f;
- break;
case SCRIPT_SOUND_PRETEND_FIRE_LOOP:
m_sQueueSample.m_fSoundIntensity = 50.0f;
m_sQueueSample.m_nSampleIndex = SFX_CAR_ON_FIRE;
@@ -7188,7 +8566,7 @@ cAudioManager::ProcessLoopingScriptObject(uint8 sound)
m_sQueueSample.m_nReleasingVolumeModificator = 8;
m_sQueueSample.m_nReleasingVolumeDivider = 10;
m_sQueueSample.m_fSpeedMultiplier = 2.0f;
- break;
+ break;*/
default:
return;
}
@@ -7211,574 +8589,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;
- m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_bReverbFlag = true;
- m_sQueueSample.m_bRequireReflection = false;
- AddSampleToRequestedQueue();
- }
- }
-
- time = CTimer::GetTimeInMilliseconds();
- if (time > gPornNextTime) {
- m_sQueueSample.m_nVolume = ComputeVolume(90, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance);
- if (m_sQueueSample.m_nVolume != 0) {
- rand = m_anRandomTable[1] & 1;
- m_sQueueSample.m_nSampleIndex = rand + sample;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 16);
- m_sQueueSample.m_nCounter = rand + 1;
- m_sQueueSample.m_bIs2D = false;
- m_sQueueSample.m_nLoopCount = 1;
- m_sQueueSample.m_bReleasingSoundFlag = true;
- m_sQueueSample.m_nReleasingVolumeModificator = 6;
- m_sQueueSample.m_fSpeedMultiplier = 0.0f;
- m_sQueueSample.m_nLoopStart = 0;
- m_sQueueSample.m_nLoopEnd = -1;
- m_sQueueSample.m_bReverbFlag = true;
- m_sQueueSample.m_bRequireReflection = false;
- AddSampleToRequestedQueue();
- gPornNextTime = time + 2000 + m_anRandomTable[3] % 6000;
- }
- }
- }
-}
-
-void
-cAudioManager::ProcessWorkShopScriptObject(uint8 sound)
-{
- float distSquared;
-
- switch (sound) {
- case SCRIPT_SOUND_WORK_SHOP_LOOP_S:
- case SCRIPT_SOUND_WORK_SHOP_LOOP_L:
- m_sQueueSample.m_fSoundIntensity = 20.0f;
- break;
- default:
- return;
- }
- distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos);
- if (distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) {
- m_sQueueSample.m_fDistance = Sqrt(distSquared);
- m_sQueueSample.m_nVolume = ComputeVolume(30, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance);
- if (m_sQueueSample.m_nVolume != 0) {
- m_sQueueSample.m_nSampleIndex = SFX_WORKSHOP_1;
- m_sQueueSample.m_nBankIndex = 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;
- m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_bReverbFlag = true;
- m_sQueueSample.m_bRequireReflection = false;
- AddSampleToRequestedQueue();
- }
- }
-}
-
-void
-cAudioManager::ProcessSawMillScriptObject(uint8 sound)
-{
-
- uint32 time;
- float distSquared;
-
- switch (sound) {
- case SCRIPT_SOUND_SAWMILL_LOOP_S:
- case SCRIPT_SOUND_SAWMILL_LOOP_L:
- m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_S;
- break;
- default:
- return;
- }
- distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos);
- if (distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) {
- m_sQueueSample.m_fDistance = Sqrt(distSquared);
- m_sQueueSample.m_nVolume = ComputeVolume(30, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance);
- if (m_sQueueSample.m_nVolume != 0) {
- m_sQueueSample.m_nSampleIndex = SFX_SAWMILL_LOOP;
- m_sQueueSample.m_nBankIndex = 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;
- m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_bReverbFlag = true;
- m_sQueueSample.m_bRequireReflection = false;
- AddSampleToRequestedQueue();
- }
- time = CTimer::GetTimeInMilliseconds();
- if (time > gSawMillNextTime) {
- m_sQueueSample.m_nVolume = ComputeVolume(70, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance);
- if (m_sQueueSample.m_nVolume != 0) {
- m_sQueueSample.m_nSampleIndex = SFX_SAWMILL_CUT_WOOD;
- m_sQueueSample.m_nBankIndex = 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;
- m_sQueueSample.m_nLoopStart = 0;
- m_sQueueSample.m_nLoopEnd = -1;
- m_sQueueSample.m_bReverbFlag = true;
- m_sQueueSample.m_bRequireReflection = false;
- AddSampleToRequestedQueue();
- gSawMillNextTime = time + 2000 + m_anRandomTable[3] % 4000;
- }
- }
- }
-}
-
-void
-cAudioManager::ProcessLaunderetteScriptObject(uint8 sound)
-{
- switch (sound) {
- case SCRIPT_SOUND_LAUNDERETTE_LOOP_S:
- case SCRIPT_SOUND_LAUNDERETTE_LOOP_L:
- m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_S;
- break;
- default:
- return;
- }
- float distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos);
- if (distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) {
- m_sQueueSample.m_fDistance = Sqrt(distSquared);
- m_sQueueSample.m_nVolume = ComputeVolume(45, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance);
- if (m_sQueueSample.m_nVolume != 0) {
- m_sQueueSample.m_nSampleIndex = SFX_LAUNDERETTE_LOOP;
- m_sQueueSample.m_nBankIndex = 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;
- m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_bReverbFlag = true;
- m_sQueueSample.m_bRequireReflection = false;
- AddSampleToRequestedQueue();
- }
- m_sQueueSample.m_nVolume = ComputeVolume(110, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance);
- if (m_sQueueSample.m_nVolume != 0) {
- m_sQueueSample.m_nSampleIndex = SFX_LAUNDERETTE_SONG_LOOP;
- m_sQueueSample.m_nBankIndex = 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;
- m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_bReverbFlag = true;
- m_sQueueSample.m_bRequireReflection = false;
- AddSampleToRequestedQueue();
- }
- }
-}
-
-void
-cAudioManager::ProcessShopScriptObject(uint8 sound)
-{
- uint32 time;
- int32 rand;
- float distSquared;
-
- switch (sound) {
- case SCRIPT_SOUND_SHOP_LOOP_S:
- case SCRIPT_SOUND_SHOP_LOOP_L:
- m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_S;
- break;
- default:
- return;
- }
- distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos);
- if (distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) {
- m_sQueueSample.m_fDistance = Sqrt(distSquared);
- m_sQueueSample.m_nVolume = ComputeVolume(30, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance);
- if (m_sQueueSample.m_nVolume != 0) {
- m_sQueueSample.m_nSampleIndex = SFX_SHOP_LOOP;
- m_sQueueSample.m_nBankIndex = 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;
- m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_bReverbFlag = true;
- m_sQueueSample.m_bRequireReflection = false;
- AddSampleToRequestedQueue();
- }
- time = CTimer::GetTimeInMilliseconds();
- if (time > gShopNextTime) {
- m_sQueueSample.m_nVolume = ComputeVolume(70, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance);
- if (m_sQueueSample.m_nVolume != 0) {
- rand = m_anRandomTable[1] & 1;
- m_sQueueSample.m_nSampleIndex = rand + SFX_SHOP_TILL_1;
- m_sQueueSample.m_nBankIndex = 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;
- m_sQueueSample.m_nLoopStart = 0;
- m_sQueueSample.m_nLoopEnd = -1;
- m_sQueueSample.m_bReverbFlag = true;
- m_sQueueSample.m_bRequireReflection = false;
- AddSampleToRequestedQueue();
- gShopNextTime = time + 3000 + m_anRandomTable[3] % 7000;
- }
- }
- }
-}
-
-void
-cAudioManager::ProcessAirportScriptObject(uint8 sound)
-{
- static uint8 iSound = 0;
-
- uint32 time = CTimer::GetTimeInMilliseconds();
- if (time > gAirportNextTime) {
- switch (sound) {
- case SCRIPT_SOUND_AIRPORT_LOOP_S:
- m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_S;
- break;
- case SCRIPT_SOUND_AIRPORT_LOOP_L:
- m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_L;
- break;
- default:
- return;
- }
- float distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos);
- if (distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) {
- m_sQueueSample.m_fDistance = Sqrt(distSquared);
- m_sQueueSample.m_nVolume = ComputeVolume(110, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance);
- if (m_sQueueSample.m_nVolume != 0) {
- m_sQueueSample.m_nSampleIndex = (m_anRandomTable[1] & 3) + SFX_AIRPORT_ANNOUNCEMENT_1;
- m_sQueueSample.m_nBankIndex = 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;
- m_sQueueSample.m_nLoopStart = 0;
- m_sQueueSample.m_nLoopEnd = -1;
- m_sQueueSample.m_bReverbFlag = true;
- m_sQueueSample.m_bRequireReflection = false;
- AddSampleToRequestedQueue();
- gAirportNextTime = time + 10000 + m_anRandomTable[3] % 20000;
- }
- }
- }
-}
-
-void
-cAudioManager::ProcessCinemaScriptObject(uint8 sound)
-{
- uint8 rand;
-
- static uint8 iSound = 0;
-
- uint32 time = CTimer::GetTimeInMilliseconds();
- if (time > gCinemaNextTime) {
- switch (sound) {
- case SCRIPT_SOUND_CINEMA_LOOP_S:
- m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_S;
- break;
- case SCRIPT_SOUND_CINEMA_LOOP_L:
- m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_L;
- break;
- default:
- return;
- }
- float distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos);
- if (distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) {
- m_sQueueSample.m_fDistance = Sqrt(distSquared);
- rand = m_anRandomTable[0] % 90 + 30;
- m_sQueueSample.m_nVolume = ComputeVolume(rand, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance);
- if (m_sQueueSample.m_nVolume != 0) {
- m_sQueueSample.m_nSampleIndex = iSound % 3 + SFX_CINEMA_BASS_1;
- m_sQueueSample.m_nBankIndex = 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;
- m_sQueueSample.m_nLoopStart = 0;
- m_sQueueSample.m_nLoopEnd = -1;
- m_sQueueSample.m_bReverbFlag = true;
- m_sQueueSample.m_bRequireReflection = false;
- AddSampleToRequestedQueue();
- gCinemaNextTime = time + 1000 + m_anRandomTable[3] % 4000;
- }
- }
- }
-}
-
-void
-cAudioManager::ProcessDocksScriptObject(uint8 sound)
-{
- uint32 time;
- uint8 rand;
- float distSquared;
-
- static uint8 iSound = 0;
-
- time = CTimer::GetTimeInMilliseconds();
- if (time > gDocksNextTime) {
- switch (sound) {
- case SCRIPT_SOUND_DOCKS_LOOP_S:
- m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_S;
- break;
- case SCRIPT_SOUND_DOCKS_LOOP_L:
- m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_L;
- break;
- default:
- return;
- }
- distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos);
- if (distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) {
- m_sQueueSample.m_fDistance = Sqrt(distSquared);
- rand = m_anRandomTable[0] % 60 + 40;
- m_sQueueSample.m_nVolume = ComputeVolume(rand, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance);
- if (m_sQueueSample.m_nVolume != 0) {
- m_sQueueSample.m_nSampleIndex = SFX_DOCKS_FOGHORN;
- m_sQueueSample.m_nBankIndex = 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;
- m_sQueueSample.m_nLoopStart = 0;
- m_sQueueSample.m_nLoopEnd = -1;
- m_sQueueSample.m_bReverbFlag = true;
- m_sQueueSample.m_bRequireReflection = false;
- AddSampleToRequestedQueue();
- gDocksNextTime = time + 10000 + m_anRandomTable[3] % 40000;
- }
- }
- }
-}
-void
-cAudioManager::ProcessHomeScriptObject(uint8 sound)
-{
- uint32 time;
- uint8 rand;
- float dist;
-
- static uint8 iSound = 0;
-
- time = CTimer::GetTimeInMilliseconds();
- if (time > gHomeNextTime) {
- switch (sound) {
- case SCRIPT_SOUND_HOME_LOOP_S:
- m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_S;
- break;
- case SCRIPT_SOUND_HOME_LOOP_L:
- m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_L;
- break;
- default:
- return;
- }
- dist = GetDistanceSquared(m_sQueueSample.m_vecPos);
- if (dist < SQR(m_sQueueSample.m_fSoundIntensity)) {
- m_sQueueSample.m_fDistance = Sqrt(dist);
- rand = m_anRandomTable[0] % 30 + 40;
- m_sQueueSample.m_nVolume = ComputeVolume(rand, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance);
- if (m_sQueueSample.m_nVolume != 0) {
- m_sQueueSample.m_nSampleIndex = m_anRandomTable[0] % 5 + SFX_HOME_1;
- m_sQueueSample.m_nBankIndex = 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;
- m_sQueueSample.m_nLoopStart = 0;
- m_sQueueSample.m_nLoopEnd = -1;
- m_sQueueSample.m_bReverbFlag = true;
- m_sQueueSample.m_bRequireReflection = true;
- AddSampleToRequestedQueue();
- gHomeNextTime = time + 1000 + m_anRandomTable[3] % 4000;
- }
- }
- }
-}
-void
-cAudioManager::ProcessPoliceCellBeatingScriptObject(uint8 sound)
-{
- uint32 time = CTimer::GetTimeInMilliseconds();
- int32 sampleIndex;
- uint8 emittingVol;
- float distSquared;
- cPedParams params;
-
- static uint8 iSound = 0;
-
- if (time > gCellNextTime) {
- switch (sound) {
- case SCRIPT_SOUND_POLICE_CELL_BEATING_LOOP_S:
- m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_S;
- break;
- case SCRIPT_SOUND_POLICE_CELL_BEATING_LOOP_L:
- m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_L;
- break;
- default:
- return;
- }
- distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos);
- if (distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) {
- m_sQueueSample.m_fDistance = Sqrt(distSquared);
- if (m_FrameCounter & 1)
- sampleIndex = (m_anRandomTable[1] & 3) + SFX_FIGHT_1;
- else
- sampleIndex = (m_anRandomTable[3] & 1) + SFX_BAT_HIT_LEFT;
- m_sQueueSample.m_nSampleIndex = sampleIndex;
- emittingVol = m_anRandomTable[0] % 50 + 55;
- m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance);
- if (m_sQueueSample.m_nVolume != 0) {
- m_sQueueSample.m_nBankIndex = 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;
- m_sQueueSample.m_nLoopStart = 0;
- m_sQueueSample.m_nLoopEnd = -1;
- m_sQueueSample.m_bReverbFlag = true;
- m_sQueueSample.m_bRequireReflection = false;
- AddSampleToRequestedQueue();
- params.m_bDistanceCalculated = true;
- params.m_fDistance = distSquared;
- params.m_pPed = nil;
- SetupPedComments(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;
@@ -7786,7 +8615,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;
@@ -7806,7 +8635,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;
@@ -7822,6 +8651,32 @@ 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.0) {
+ 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;
+ m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_bRequireReflection = false;
+ AddSampleToRequestedQueue();
+ CObject::fDistToNearestTree = 999999.9f;
+ }
}
void
@@ -7830,18 +8685,21 @@ cAudioManager::ProcessFrontEnd()
bool stereo;
bool processedPickup;
bool processedMission;
- bool frontendBank;
+ bool staticFreq;
+ bool 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;
@@ -7852,112 +8710,120 @@ 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_PICKUP_WEAPON_BOUGHT:
- case SOUND_PICKUP_WEAPON:
- m_sQueueSample.m_nSampleIndex = SFX_PICKUP_1_LEFT;
+ case SOUND_GARAGE_BOMB1_SET:
+ case SOUND_GARAGE_BOMB2_SET:
+ case SOUND_GARAGE_BOMB3_SET:
+ 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_SOUND:
+ 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_NO_RADIO:
+ case SOUND_FRONTEND_RADIO_CHANGE:
+ 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_RADIO_CHANGE_2:
+ 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_NO_RADIO:
- 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;
@@ -7974,43 +8840,70 @@ cAudioManager::ProcessFrontEnd()
}
sample = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_awAudioEvent[i];
- if (sample == SFX_RAIN) {
+
+ if (sample == SOUND_FRONTEND_NO_RADIO)
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_CHANGE)
+ 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;
m_sQueueSample.m_nLoopStart = 0;
m_sQueueSample.m_nLoopEnd = -1;
- if (stereo)
- m_sQueueSample.m_nOffset = m_anRandomTable[0] & 31;
- else
+ m_sQueueSample.m_fDistance = 1.0f;
+ if (stereo)
+ m_sQueueSample.m_nOffset = 0;
+ 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;
+ }
+ 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;
+ }
m_sQueueSample.m_nOffset = 63;
+ }
m_sQueueSample.m_bReverbFlag = false;
m_sQueueSample.m_bRequireReflection = false;
AddSampleToRequestedQueue();
if (stereo) {
++m_sQueueSample.m_nSampleIndex;
m_sQueueSample.m_nCounter = iSound++;
- m_sQueueSample.m_nOffset = MAX_VOLUME - m_sQueueSample.m_nOffset;
+ 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;
@@ -8059,44 +8952,50 @@ 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_fDistance = distSquared <= 0.0f ? 0.0f : Sqrt(distSquared);
m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance);
if (m_sQueueSample.m_nVolume != 0) {
m_sQueueSample.m_nCounter = i;
@@ -8242,37 +9141,37 @@ cAudioManager::ProcessGarages()
void
cAudioManager::ProcessFireHydrant()
{
+ const float SOUND_INTENSITY = 35;
+
float distSquared;
- bool distCalculated = false;
- static const int intensity = 35;
+ bool distCalculated = 0;
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;
m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_fSpeedMultiplier = 2.0f;
- m_sQueueSample.m_fSoundIntensity = intensity;
+ m_sQueueSample.m_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;
@@ -8314,7 +9213,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);
@@ -8394,50 +9293,392 @@ cAudioManager::ProcessBridgeOneShots()
}
}
#pragma endregion
+#endif
#pragma region MISSION_AUDIO
-bool g_bMissionAudioLoadFailed;
+bool 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)
@@ -8453,97 +9694,110 @@ FindMissionAudioSfx(const char *name)
bool
cAudioManager::MissionScriptAudioUsesPoliceChannel(int32 soundMission) const
{
- switch (soundMission) {
- case STREAMED_SOUND_MISSION_J6_D:
- case STREAMED_SOUND_MISSION_T4_A:
- case STREAMED_SOUND_MISSION_S1_H:
- case STREAMED_SOUND_MISSION_S3_B:
- case STREAMED_SOUND_MISSION_EL3_A:
- case STREAMED_SOUND_MISSION_A3_A:
- case STREAMED_SOUND_MISSION_A5_A:
- case STREAMED_SOUND_MISSION_K1_A:
- case STREAMED_SOUND_MISSION_R1_A:
- case STREAMED_SOUND_MISSION_R5_A:
- case STREAMED_SOUND_MISSION_LO2_A:
- case STREAMED_SOUND_MISSION_LO6_A:
- return true;
- default:
- return false;
- }
+ 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() const
+cAudioManager::GetMissionAudioLoadingStatus(uint8 slot) const
{
- 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;
}
bool
-cAudioManager::IsMissionAudioSampleFinished()
+cAudioManager::ShouldDuckMissionAudio(uint8 slot) const
{
- 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;
+}
+
+bool
+cAudioManager::IsMissionAudioSamplePlaying(uint8 slot) const
+{
+ 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 };
- static int32 cPretendFrame = 1;
+ return (cPretendFrame[slot]++ % 64) != 0;
+ }
+}
- return (cPretendFrame++ & 63) == 0;
+bool
+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[MISSION_AUDIO_SLOTS] = { 1, 1 };
+
+ 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;
@@ -8551,104 +9805,135 @@ 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] < 120) {
+ 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(1, 1);
+ SampleManager.PauseStream(1, slot + 1);
if (m_sMissionAudio.m_bPredefinedProperties) {
- SampleManager.SetStreamedVolumeAndPan(80, 63, 1, 1);
+ if (m_sMissionAudio.m_nSampleIndex[slot] == STREAMED_SOUND_MISSION_CAMERAL)
+ SampleManager.SetStreamedVolumeAndPan(80, 0, 1, slot + 1);
+ else if (m_sMissionAudio.m_nSampleIndex[slot] == STREAMED_SOUND_MISSION_CAMERAR)
+ SampleManager.SetStreamedVolumeAndPan(80, 127, 1, slot + 1);
+ else
+ SampleManager.SetStreamedVolumeAndPan(80, 63, 1, 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, 1, 1);
+ SampleManager.SetStreamedVolumeAndPan(emittingVol, pan, 1, 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 (GetMissionScriptPoliceAudioPlayingStatus() == PLAY_STATUS_FINISHED || m_sMissionAudio.m_nMissionAudioCounter[slot]-- == 0) {
+ m_sMissionAudio.m_nPlayStatus[slot] = PLAY_STATUS_FINISHED;
+ 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(1, 1);
+ SampleManager.PauseStream(1, slot + 1);
else
- SampleManager.PauseStream(0, 1);
+ {
+ SampleManager.PauseStream(0, slot + 1);
+ if (!m_sMissionAudio.m_bPredefinedProperties) {
+ 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, 1, 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:
@@ -8656,15 +9941,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] >= 90) {
+ 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 947bda40..fbfdb855 100644
--- a/src/audio/AudioManager.cpp
+++ b/src/audio/AudioManager.cpp
@@ -169,11 +169,11 @@ cAudioManager::SetEntityStatus(int32 id, uint8 status)
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) {
@@ -217,6 +217,12 @@ cAudioManager::PlayOneShot(int32 index, uint16 sound, float vol)
}
void
+cAudioManager::SetMP3BoostVolume(uint8 volume) const
+{
+ SampleManager.SetMP3BoostVolume(volume);
+}
+
+void
cAudioManager::SetEffectsMasterVolume(uint8 volume) const
{
SampleManager.SetEffectsMasterVolume(volume);
@@ -263,11 +269,13 @@ cAudioManager::ResetTimers(uint32 time)
m_nActiveSampleQueue = 0;
}
ClearActiveSamples();
- ClearMissionAudio();
+ ClearMissionAudio(0);
+ ClearMissionAudio(1);
SampleManager.StopChannel(policeChannel);
SampleManager.SetEffectsFadeVolume(0);
SampleManager.SetMusicFadeVolume(0);
MusicManager.ResetMusicAfterReload();
+ m_bIsPlayerShutUp = false;
#ifdef AUDIO_OAL
SampleManager.Service();
#endif
@@ -286,7 +294,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);
@@ -341,6 +349,15 @@ cAudioManager::GetCurrent3DProviderIndex() const
}
int8
+cAudioManager::AutoDetect3DProviders() const
+{
+ if (m_bIsInitialised)
+ return SampleManager.AutoDetect3DProviders();
+
+ return -1;
+}
+
+int8
cAudioManager::SetCurrent3DProvider(uint8 which)
{
if (!m_bIsInitialised)
@@ -409,10 +426,7 @@ cAudioManager::CheckForAnAudioFileOnCD() const
uint8
cAudioManager::GetCDAudioDriveLetter() const
{
- if (m_bIsInitialised)
- return SampleManager.GetCDAudioDriveLetter();
-
- return 0;
+ return SampleManager.GetCDAudioDriveLetter();
}
bool
@@ -471,12 +485,18 @@ uint8
cAudioManager::ComputeVolume(uint8 emittingVolume, float soundIntensity, float distance) const
{
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
@@ -488,17 +508,16 @@ cAudioManager::TranslateEntity(Const CVector *in, CVector *out) const
int32
cAudioManager::ComputePan(float dist, CVector *vec)
{
- const uint8 PanTable[64] = {0, 3, 8, 12, 16, 19, 22, 24, 26, 28, 30, 31, 33, 34, 36, 37, 39, 40, 41, 42, 44, 45, 46, 47, 48, 49, 49, 50, 51, 52, 53, 53,
- 54, 55, 55, 56, 56, 57, 57, 58, 58, 58, 59, 59, 59, 60, 60, 61, 61, 61, 61, 62, 62, 62, 62, 62, 63, 63, 63, 63, 63, 63, 63, 63};
-
- int32 index = Min(63, Abs(vec->x / (dist / 64.f)));
+ 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->x / (dist / 64.f))));
if (vec->x > 0.f)
return Max(20, 63 - PanTable[index]);
return Min(107, PanTable[index] + 63);
}
-int32
+uint32
cAudioManager::ComputeDopplerEffectedFrequency(uint32 oldFreq, float position1, float position2, float speedMultiplier) const
{
uint32 newFreq = oldFreq;
@@ -507,11 +526,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);
}
}
@@ -611,26 +626,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 = (m_sQueueSample.m_nVolume / 2) + (m_sQueueSample.m_nVolume / 16);
+ }
+ m_sQueueSample.m_fSoundIntensity = 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] = GetRandomNumberInRange(i % 4, 0, 2) * 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];
@@ -639,50 +680,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;
}
}
@@ -738,39 +813,41 @@ cAudioManager::AddReleasingSounds()
void
cAudioManager::ProcessActiveQueues()
{
- bool 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;
+ bool flag;
+ bool 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;
@@ -778,6 +855,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;
@@ -793,37 +872,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;
}
@@ -832,10 +913,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
}
}
}
@@ -847,59 +929,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);
+ bool 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;
@@ -908,6 +1000,7 @@ cAudioManager::ProcessActiveQueues()
}
}
}
+ field_6 %= m_nActiveSamples;
}
void
@@ -922,7 +1015,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;
@@ -945,7 +1038,7 @@ cAudioManager::ClearActiveSamples()
m_asActiveSamples[i].m_nCalculatedVolume = 0;
m_asActiveSamples[i].m_nReleasingVolumeDivider = 0;
m_asActiveSamples[i].m_nVolumeChange = -1;
- m_asActiveSamples[i].m_vecPos = {0.0f, 0.0f, 0.0f};
+ m_asActiveSamples[i].m_vecPos = CVector(0.0f, 0.0f, 0.0f);
m_asActiveSamples[i].m_bReverbFlag = false;
m_asActiveSamples[i].m_nLoopsRemaining = 0;
m_asActiveSamples[i].m_bRequireReflection = false;
@@ -981,4 +1074,4 @@ cAudioManager::ComputeEmittingVolume(uint8 emittingVolume, float intensity, floa
return (quatIntensity - (dist - diffIntensity)) * (float)emittingVolume / quatIntensity;
return emittingVolume;
}
-#endif \ No newline at end of file
+#endif
diff --git a/src/audio/AudioManager.h b/src/audio/AudioManager.h
index d781ad71..dff7d9c8 100644
--- a/src/audio/AudioManager.h
+++ b/src/audio/AudioManager.h
@@ -1,8 +1,10 @@
-#pragma once
+#pragma once
#include "audio_enums.h"
#include "AudioCollision.h"
#include "PoliceRadio.h"
+#include "VehicleModelInfo.h"
+#include "Vehicle.h"
class tSound
{
@@ -28,6 +30,7 @@ public:
uint8 m_nLoopsRemaining;
bool m_bRequireReflection; // Used for oneshots
uint8 m_nOffset;
+ uint8 field_4C;
int32 m_nReleasingVolumeDivider;
bool m_bIsProcessed;
bool m_bLoopEnded;
@@ -35,7 +38,7 @@ public:
int8 m_nVolumeChange;
};
-VALIDATE_SIZE(tSound, 92);
+VALIDATE_SIZE(tSound, 96);
class CPhysical;
class CAutomobile;
@@ -57,7 +60,7 @@ VALIDATE_SIZE(tAudioEntity, 40);
class tPedComment
{
public:
- int32 m_nSampleIndex;
+ uint32 m_nSampleIndex;
int32 m_nEntityIndex;
CVector m_vecPos;
float m_fDistance;
@@ -74,6 +77,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
+ bool m_bDelay;
+ uint32 m_nDelayTimer;
+#endif
cPedComments()
{
@@ -87,27 +94,32 @@ public:
m_nCommentsInBank[i] = 0;
m_nActiveBank = 0;
}
- void Add(tPedComment *com);
- void Process();
+ void Add(tPedComment *com); // done
+ void Process(); // done
};
-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;
- bool m_bPredefinedProperties;
- int32 m_nSampleIndex;
- uint8 m_nLoadingStatus;
- uint8 m_nPlayStatus;
- bool m_bIsPlaying;
- int32 m_nMissionAudioCounter;
- bool m_bIsPlayed;
+ CVector m_vecPos[MISSION_AUDIO_SLOTS];
+ bool m_bPredefinedProperties[MISSION_AUDIO_SLOTS];
+ int32 m_nSampleIndex[MISSION_AUDIO_SLOTS];
+ uint8 m_nLoadingStatus[MISSION_AUDIO_SLOTS];
+ uint8 m_nPlayStatus[MISSION_AUDIO_SLOTS];
+ bool m_bIsPlaying[MISSION_AUDIO_SLOTS];
+ int32 m_nMissionAudioCounter[MISSION_AUDIO_SLOTS];
+ bool m_bIsPlayed[MISSION_AUDIO_SLOTS];
+ bool m_bIsMobile[MISSION_AUDIO_SLOTS];
};
-VALIDATE_SIZE(cMissionAudio, 32);
+VALIDATE_SIZE(cMissionAudio, 0x38);
// name made up
class cAudioScriptObjectManager
@@ -137,6 +149,7 @@ public:
class cVehicleParams
{
public:
+ uint8 m_VehicleType;
bool m_bDistanceCalculated;
float m_fDistance;
CVehicle *m_pVehicle;
@@ -148,19 +161,14 @@ public:
VALIDATE_SIZE(cVehicleParams, 0x18);
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,
};
@@ -173,6 +181,7 @@ public:
uint8 m_nActiveSamples;
uint8 field_4; // unused
bool m_bDynamicAcousticModelingStatus;
+ int8 field_6;
float m_fSpeedOfSound;
bool m_bTimerJustReset;
int32 m_nTimer;
@@ -188,6 +197,14 @@ public:
CVector m_avecReflectionsPos[NUM_AUDIO_REFLECTIONS];
float m_afReflectionsDistances[NUM_AUDIO_REFLECTIONS];
cAudioScriptObjectManager m_sAudioScriptObjectManager;
+
+ // miami
+ uint8 m_bIsPlayerShutUp;
+ uint8 m_nPlayerMood;
+ uint32 m_nPlayerMoodTimer;
+ uint8 field_rest[4];
+ bool m_bGenericSfx;
+
cPedComments m_sPedComments;
int32 m_nFireAudioEntity;
int32 m_nWaterCannonEntity;
@@ -197,8 +214,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;
@@ -209,236 +231,251 @@ public:
~cAudioManager();
// getters
- uint32 GetFrameCounter() const { return m_FrameCounter; }
- float GetReflectionsDistance(int32 idx) const { return m_afReflectionsDistances[idx]; }
+ uint32 GetFrameCounter() const { return m_FrameCounter; } // done
+ float GetReflectionsDistance(int32 idx) const { return m_afReflectionsDistances[idx]; } // done
int32 GetRandomNumber(int32 idx) const { return m_anRandomTable[idx]; }
int32 GetRandomNumberInRange(int32 idx, int32 low, int32 high) const { return (m_anRandomTable[idx] % (high - low + 1)) + low; }
- bool ShouldDuckMissionAudio() const { return m_sMissionAudio.m_nPlayStatus == 1; }
+ bool IsMissionAudioSamplePlaying(uint8 slot) const; // { return m_sMissionAudio.m_nPlayStatus == 1; }
+ bool ShouldDuckMissionAudio(uint8 slot) const;
// "Should" be in alphabetic order, except "getXTalkSfx"
- void AddDetailsToRequestedOrderList(uint8 sample);
- void AddPlayerCarSample(uint8 emittingVolume, int32 freq, uint32 sample, uint8 bank,
- uint8 counter, bool notLooping);
- void AddReflectionsToRequestedQueue();
- void AddReleasingSounds();
- void AddSampleToRequestedQueue();
- void AgeCrimes();
-
- void CalculateDistance(bool &condition, float dist);
- bool CheckForAnAudioFileOnCD() const;
- void ClearActiveSamples();
- void ClearMissionAudio();
- void ClearRequestedQueue();
- int32 ComputeDopplerEffectedFrequency(uint32 oldFreq, float position1, float position2,
- float speedMultiplier) const;
- int32 ComputePan(float, CVector *);
- uint8 ComputeVolume(uint8 emittingVolume, float soundIntensity, float distance) const;
- int32 CreateEntity(eAudioType type, void *entity);
-
- void DestroyAllGameCreatedEntities();
- void DestroyEntity(int32 id);
- void DoPoliceRadioCrackle();
+ void AddDetailsToRequestedOrderList(uint8 sample); // done (inlined in vc)
+ void AddPlayerCarSample(uint8 emittingVolume, int32 freq, uint32 sample, uint8 bank, uint8 counter, bool notLooping); // done
+ void AddReflectionsToRequestedQueue(); // done
+ void AddReleasingSounds(); // done
+ void AddSampleToRequestedQueue(); // done
+ void AgeCrimes(); // done (inlined in vc)
+
+ void CalculateDistance(bool &condition, float dist); // done
+ bool CheckForAnAudioFileOnCD() const; // done
+ void ClearActiveSamples(); // done
+ void ClearMissionAudio(uint8 slot); // done (inlined in vc)
+ void ClearRequestedQueue(); // done (inlined in vc)
+ uint32 ComputeDopplerEffectedFrequency(uint32 oldFreq, float position1, float position2, float speedMultiplier) const; // done
+ int32 ComputePan(float, CVector *); // done
+ uint8 ComputeVolume(uint8 emittingVolume, float soundIntensity, float distance) const; // done
+ int32 CreateEntity(eAudioType type, void *entity); // done
+
+ void DestroyAllGameCreatedEntities(); // done ? I don't seed pEntity = nil;
+ void DestroyEntity(int32 id); // done (inlined in vc) ? I not seen id checks
+ void DoPoliceRadioCrackle(); // done
// functions returning talk sfx,
// order from GetPedCommentSfx
- uint32 GetPlayerTalkSfx(int16 sound);
- uint32 GetCopTalkSfx(int16 sound);
- uint32 GetSwatTalkSfx(int16 sound);
- uint32 GetFBITalkSfx(int16 sound);
- uint32 GetArmyTalkSfx(int16 sound);
- uint32 GetMedicTalkSfx(int16 sound);
- uint32 GetFiremanTalkSfx(int16 sound);
- uint32 GetNormalMaleTalkSfx(int16 sound);
- uint32 GetTaxiDriverTalkSfx(int16 sound);
- uint32 GetPimpTalkSfx(int16 sound);
- uint32 GetMafiaTalkSfx(int16 sound);
- uint32 GetTriadTalkSfx(int16 sound);
- uint32 GetDiabloTalkSfx(int16 sound);
- uint32 GetYakuzaTalkSfx(int16 sound);
- uint32 GetYardieTalkSfx(int16 sound);
- uint32 GetColumbianTalkSfx(int16 sound);
- uint32 GetHoodTalkSfx(int16 sound);
- uint32 GetBlackCriminalTalkSfx(int16 sound);
- uint32 GetWhiteCriminalTalkSfx(int16 sound);
- uint32 GetMaleNo2TalkSfx(int16 sound);
- uint32 GetBlackProjectMaleTalkSfx(int16 sound, int32 model);
- uint32 GetWhiteFatMaleTalkSfx(int16 sound);
- uint32 GetBlackFatMaleTalkSfx(int16 sound);
- uint32 GetBlackCasualFemaleTalkSfx(int16 sound);
- uint32 GetWhiteCasualFemaleTalkSfx(int16 sound);
- uint32 GetFemaleNo3TalkSfx(int16 sound);
- uint32 GetBlackFatFemaleTalkSfx(int16 sound);
- uint32 GetWhiteFatFemaleTalkSfx(int16 sound);
- uint32 GetBlackFemaleProstituteTalkSfx(int16 sound);
- uint32 GetWhiteFemaleProstituteTalkSfx(int16 sound);
- uint32 GetBlackProjectFemaleOldTalkSfx(int16 sound);
- uint32 GetBlackProjectFemaleYoungTalkSfx(int16 sound);
- uint32 GetChinatownMaleOldTalkSfx(int16 sound);
- uint32 GetChinatownMaleYoungTalkSfx(int16 sound);
- uint32 GetChinatownFemaleOldTalkSfx(int16 sound);
- uint32 GetChinatownFemaleYoungTalkSfx(int16 sound);
- uint32 GetLittleItalyMaleTalkSfx(int16 sound);
- uint32 GetLittleItalyFemaleOldTalkSfx(int16 sound);
- uint32 GetLittleItalyFemaleYoungTalkSfx(int16 sound);
- uint32 GetWhiteDockerMaleTalkSfx(int16 sound);
- uint32 GetBlackDockerMaleTalkSfx(int16 sound);
- uint32 GetScumMaleTalkSfx(int16 sound);
- uint32 GetScumFemaleTalkSfx(int16 sound);
- uint32 GetWhiteWorkerMaleTalkSfx(int16 sound);
- uint32 GetBlackWorkerMaleTalkSfx(int16 sound);
- uint32 GetBusinessMaleYoungTalkSfx(int16 sound, int32 model);
- uint32 GetBusinessMaleOldTalkSfx(int16 sound);
- uint32 GetWhiteBusinessFemaleTalkSfx(int16 sound, int32 model);
- uint32 GetBlackBusinessFemaleTalkSfx(int16 sound);
- uint32 GetSupermodelMaleTalkSfx(int16 sound);
- uint32 GetSupermodelFemaleTalkSfx(int16 sound);
- uint32 GetStewardMaleTalkSfx(int16 sound);
- uint32 GetStewardFemaleTalkSfx(int16 sound);
- uint32 GetFanMaleTalkSfx(int16 sound, int32 model);
- uint32 GetFanFemaleTalkSfx(int16 sound);
- uint32 GetHospitalMaleTalkSfx(int16 sound);
- uint32 GetHospitalFemaleTalkSfx(int16 sound);
- uint32 GetWhiteConstructionWorkerTalkSfx(int16 sound);
- uint32 GetBlackConstructionWorkerTalkSfx(int16 sound);
- uint32 GetShopperFemaleTalkSfx(int16 sound, int32 model);
- uint32 GetStudentMaleTalkSfx(int16 sound);
- uint32 GetStudentFemaleTalkSfx(int16 sound);
- uint32 GetCasualMaleOldTalkSfx(int16 sound);
-
- uint32 GetSpecialCharacterTalkSfx(int32 modelIndex, int32 sound);
- uint32 GetEightTalkSfx(int16 sound);
- uint32 GetFrankieTalkSfx(int16 sound);
- uint32 GetMistyTalkSfx(int16 sound);
- uint32 GetOJGTalkSfx(int16 sound);
- uint32 GetCatatalinaTalkSfx(int16 sound);
- uint32 GetBomberTalkSfx(int16 sound);
- uint32 GetSecurityGuardTalkSfx(int16 sound);
- uint32 GetChunkyTalkSfx(int16 sound);
-
- uint32 GetGenericMaleTalkSfx(int16 sound);
- uint32 GetGenericFemaleTalkSfx(int16 sound);
+ uint32 GetPlayerTalkSfx(CPed *ped, int16 sound);
+ uint32 GetCopTalkSfx(CPed *ped, int16 sound);
+ uint32 GetSwatTalkSfx(CPed *ped, int16 sound);
+ uint32 GetFBITalkSfx(CPed *ped, int16 sound);
+ uint32 GetArmyTalkSfx(CPed *ped, int16 sound);
+ uint32 GetMedicTalkSfx(CPed *ped, int16 sound);
+ uint32 GetFiremanTalkSfx(CPed *ped, int16 sound);
+ uint32 GetDefaultTalkSfx(CPed *ped, int16 sound);
+ uint32 GetHFYSTTalkSfx(CPed *ped, int16 sound);
+ uint32 GetHFOSTTalkSfx(CPed *ped, int16 sound);
+ uint32 GetHMYSTTalkSfx(CPed *ped, int16 sound);
+ uint32 GetHMOSTTalkSfx(CPed *ped, int16 sound);
+ uint32 GetHFYRITalkSfx(CPed *ped, int16 sound);
+ uint32 GetHFORITalkSfx(CPed *ped, int16 sound);
+ uint32 GetHMYRITalkSfx(CPed *ped, int16 sound);
+ uint32 GetHMORITalkSfx(CPed *ped, int16 sound);
+ uint32 GetHFYBETalkSfx(CPed *ped, int16 sound);
+ uint32 GetHFOBETalkSfx(CPed *ped, int16 sound);
+ uint32 GetHMYBETalkSfx(CPed *ped, int16 sound);
+ uint32 GetHMOBETalkSfx(CPed *ped, int16 sound);
+ uint32 GetHFYBUTalkSfx(CPed *ped, int16 sound);
+ uint32 GetHFYMDTalkSfx(CPed *ped, int16 sound);
+ uint32 GetHFYCGTalkSfx(CPed *ped, int16 sound);
+ uint32 GetHFYPRTalkSfx(CPed *ped, int16 sound);
+ uint32 GetHFOTRTalkSfx(CPed *ped, int16 sound);
+ uint32 GetHMOTRTalkSfx(CPed *ped, int16 sound);
+ uint32 GetHMYAPTalkSfx(CPed *ped, int16 sound);
+ uint32 GetHMOCATalkSfx(CPed *ped, int16 sound);
+ uint32 GetBMODKTalkSfx(CPed *ped, int16 sound);
+ uint32 GetBMYCRTalkSfx(CPed *ped, int16 sound);
+ uint32 GetBFYSTTalkSfx(CPed *ped, int16 sound);
+ uint32 GetBFOSTTalkSfx(CPed *ped, int16 sound);
+ uint32 GetBMYSTTalkSfx(CPed *ped, int16 sound);
+ uint32 GetBMOSTTalkSfx(CPed *ped, int16 sound);
+ uint32 GetBFYRITalkSfx(CPed *ped, int16 sound);
+ uint32 GetBFORITalkSfx(CPed *ped, int16 sound);
+ uint32 GetBMYRITalkSfx(CPed *ped, int16 sound);
+ uint32 GetBFYBETalkSfx(CPed *ped, int16 sound);
+ uint32 GetBMYBETalkSfx(CPed *ped, int16 sound);
+ uint32 GetBFOBETalkSfx(CPed *ped, int16 sound);
+ uint32 GetBMOBETalkSfx(CPed *ped, int16 sound);
+ uint32 GetBMYBUTalkSfx(CPed *ped, int16 sound);
+ uint32 GetBFYPRTalkSfx(CPed *ped, int16 sound);
+ uint32 GetBFOTRTalkSfx(CPed *ped, int16 sound);
+ uint32 GetBMOTRTalkSfx(CPed *ped, int16 sound);
+ uint32 GetBMYPITalkSfx(CPed *ped, int16 sound);
+ uint32 GetBMYBBTalkSfx(CPed *ped, int16 sound);
+ uint32 GetWMYCRTalkSfx(CPed *ped, int16 sound);
+ uint32 GetWFYSTTalkSfx(CPed *ped, int16 sound);
+ uint32 GetWFOSTTalkSfx(CPed *ped, int16 sound);
+ uint32 GetWMYSTTalkSfx(CPed *ped, int16 sound);
+ uint32 GetWMOSTTalkSfx(CPed *ped, int16 sound);
+ uint32 GetWFYRITalkSfx(CPed *ped, int16 sound);
+ uint32 GetWFORITalkSfx(CPed *ped, int16 sound);
+ uint32 GetWMYRITalkSfx(CPed *ped, int16 sound);
+ uint32 GetWMORITalkSfx(CPed *ped, int16 sound);
+ uint32 GetWFYBETalkSfx(CPed *ped, int16 sound);
+ uint32 GetWMYBETalkSfx(CPed *ped, int16 sound);
+ uint32 GetWFOBETalkSfx(CPed *ped, int16 sound);
+ uint32 GetWMOBETalkSfx(CPed *ped, int16 sound);
+ uint32 GetWMYCWTalkSfx(CPed *ped, int16 sound);
+ uint32 GetWMYGOTalkSfx(CPed *ped, int16 sound);
+ uint32 GetWFOGOTalkSfx(CPed *ped, int16 sound);
+ uint32 GetWMOGOTalkSfx(CPed *ped, int16 sound);
+ uint32 GetWFYLGTalkSfx(CPed *ped, int16 sound);
+ uint32 GetWMYLGTalkSfx(CPed *ped, int16 sound);
+ uint32 GetWFYBUTalkSfx(CPed *ped, int16 sound);
+ uint32 GetWMYBUTalkSfx(CPed *ped, int16 sound);
+ uint32 GetWMOBUTalkSfx(CPed *ped, int16 sound);
+ uint32 GetWFYPRTalkSfx(CPed *ped, int16 sound);
+ uint32 GetWFOTRTalkSfx(CPed *ped, int16 sound);
+ uint32 GetWMOTRTalkSfx(CPed *ped, int16 sound);
+ uint32 GetWMYPITalkSfx(CPed *ped, int16 sound);
+ uint32 GetWMOCATalkSfx(CPed *ped, int16 sound);
+ uint32 GetWFYJGTalkSfx(CPed *ped, int16 sound);
+ uint32 GetWMYJGTalkSfx(CPed *ped, int16 sound);
+ uint32 GetWFYSKTalkSfx(CPed *ped, int16 sound);
+ uint32 GetWMYSKTalkSfx(CPed *ped, int16 sound);
+ uint32 GetWFYSHTalkSfx(CPed *ped, int16 sound);
+ uint32 GetWFOSHTalkSfx(CPed *ped, int16 sound);
+ uint32 GetJFOTOTalkSfx(CPed *ped, int16 sound);
+ uint32 GetJMOTOTalkSfx(CPed *ped, int16 sound);
+ uint32 GetCBTalkSfx(CPed *ped, int16 sound);
+ uint32 GetHNTalkSfx(CPed *ped, int16 sound);
+ uint32 GetSGTalkSfx(CPed *ped, int16 sound);
+ uint32 GetCLTalkSfx(CPed *ped, int16 sound);
+ uint32 GetGDTalkSfx(CPed *ped, int16 sound);
+ uint32 GetBKTalkSfx(CPed *ped, int16 sound);
+ uint32 GetPGTalkSfx(CPed *ped, int16 sound);
+ uint32 GetVICETalkSfx(CPed *ped, int16 sound, int16 model);
+ uint32 GetWFYG1TalkSfx(CPed *ped, int16 sound);
+ uint32 GetWFYG2TalkSfx(CPed *ped, int16 sound);
+
+ uint32 GetGenericMaleTalkSfx(CPed *ped, int16 sound); // todo names (inlined in vc)
+ uint32 GetGenericFemaleTalkSfx(CPed *ped, int16 sound); // todo names (inlined in vc)
// end of functions returning talk sfx
- void GenerateIntegerRandomNumberTable();
+ void GenerateIntegerRandomNumberTable(); // done
char *Get3DProviderName(uint8 id) const;
uint8 GetCDAudioDriveLetter() const;
int8 GetCurrent3DProviderIndex() const;
+ int8 AutoDetect3DProviders() const; // done
float GetCollisionLoopingRatio(uint32 a, uint32 b, float c) const; // not used
float GetCollisionOneShotRatio(int32 a, float b) const;
float GetCollisionRatio(float a, float b, float c, float d) const;
- float GetDistanceSquared(const CVector &v) const;
+ float GetDistanceSquared(const CVector &v) const; // done (inlined in vc)
int32 GetJumboTaxiFreq() const;
- uint8 GetMissionAudioLoadingStatus() const;
+ uint8 GetMissionAudioLoadingStatus(uint8 slot) const; // done
int8 GetMissionScriptPoliceAudioPlayingStatus() const;
- uint8 GetNum3DProvidersAvailable() const;
- int32 GetPedCommentSfx(CPed *ped, int32 sound);
+ uint8 GetNum3DProvidersAvailable() const; // done
+ uint32 GetPedCommentSfx(CPed *ped, int32 sound);
void GetPhrase(uint32 &phrase, uint32 &prevPhrase, uint32 sample, uint32 maxOffset) const;
- float GetVehicleDriveWheelSkidValue(uint8 wheel, CAutomobile *automobile,
- cTransmission *transmission, float velocityChange);
- float GetVehicleNonDriveWheelSkidValue(uint8 wheel, CAutomobile *automobile,
- cTransmission *transmission, float velocityChange);
-
- bool HasAirBrakes(int32 model) const;
-
- void Initialise();
- void InitialisePoliceRadio();
- void InitialisePoliceRadioZones();
- void InterrogateAudioEntities();
- bool IsAudioInitialised() const;
- bool IsMissionAudioSampleFinished();
- bool IsMP3RadioChannelAvailable() const;
-
- bool MissionScriptAudioUsesPoliceChannel(int32 soundMission) const;
-
- void PlayLoadedMissionAudio();
- void PlayOneShot(int32 index, uint16 sound, float vol);
- void PlaySuspectLastSeen(float x, float y, float z);
- void PlayerJustGotInCar() const;
- void PlayerJustLeftCar() const;
- void PostInitialiseGameSpecificSetup();
- void PostTerminateGameSpecificShutdown();
- void PreInitialiseGameSpecificSetup() const;
- void PreloadMissionAudio(Const char *name);
- void PreTerminateGameSpecificShutdown();
+ float GetVehicleDriveWheelSkidValue(CVehicle* veh, tWheelState wheelState, float gasPedalAudio, cTransmission* transmission, float velocityChange); // done
+ float GetVehicleNonDriveWheelSkidValue(CVehicle* veh, tWheelState wheelState, cTransmission* transmission, float velocityChange); // done
+
+ bool HasAirBrakes(int32 model) const; // done
+
+ void Initialise(); // done
+ void InitialisePoliceRadio(); //done
+ void InitialisePoliceRadioZones(); //done
+ void InterrogateAudioEntities(); // done
+ bool IsAudioInitialised() const; // done
+ bool IsMissionAudioSampleFinished(uint8 slot); // done
+ bool IsMP3RadioChannelAvailable() const; // done
+
+ bool MissionScriptAudioUsesPoliceChannel(int32 soundMission) const; //done
+
+ void PlayLoadedMissionAudio(uint8 slot); // done
+ void PlayOneShot(int32 index, uint16 sound, float vol); // done
+ void PlaySuspectLastSeen(float x, float y, float z); // done
+ void PlayerJustGotInCar() const; // done
+ void PlayerJustLeftCar() const; // done
+ void PostInitialiseGameSpecificSetup(); // done
+ void PostTerminateGameSpecificShutdown(); // done
+ void PreInitialiseGameSpecificSetup() const; // done
+ void PreloadMissionAudio(uint8 slot, Const char *name); // done
+ void PreTerminateGameSpecificShutdown(); // done
/// processX - main logic of adding new sounds
- void ProcessActiveQueues();
- bool ProcessAirBrakes(cVehicleParams& params);
- void ProcessAirportScriptObject(uint8 sound);
- bool ProcessBoatEngine(cVehicleParams& params);
- bool ProcessBoatMovingOverWater(cVehicleParams& params);
- void ProcessBridge();
- void ProcessBridgeMotor();
- void ProcessBridgeOneShots();
- void ProcessBridgeWarning();
- bool ProcessCarBombTick(cVehicleParams& params);
- void ProcessCesna(cVehicleParams& params);
- void ProcessCinemaScriptObject(uint8 sound);
- void ProcessCrane();
- void ProcessDocksScriptObject(uint8 sound);
- bool ProcessEngineDamage(cVehicleParams& params);
- void ProcessEntity(int32 sound);
- void ProcessExplosions(int32 explosion);
- void ProcessFireHydrant();
- void ProcessFires(int32 entity);
- void ProcessFrontEnd();
- void ProcessGarages();
- bool ProcessHelicopter(cVehicleParams& params);
- void ProcessHomeScriptObject(uint8 sound);
- void ProcessJumbo(cVehicleParams& params);
- void ProcessJumboAccel(CPlane *plane);
- void ProcessJumboDecel(CPlane *plane);
- void ProcessJumboFlying();
- void ProcessJumboLanding(CPlane *plane);
- void ProcessJumboTakeOff(CPlane *plane);
- void ProcessJumboTaxi();
- void ProcessLaunderetteScriptObject(uint8 sound);
- void ProcessLoopingScriptObject(uint8 sound);
- void ProcessMissionAudio();
- void ProcessModelCarEngine(cVehicleParams& params);
- void ProcessOneShotScriptObject(uint8 sound);
- void ProcessPed(CPhysical *ped);
- void ProcessPedHeadphones(cPedParams &params);
- void ProcessPedOneShots(cPedParams &params);
- void ProcessPhysical(int32 id);
- void ProcessPlane(cVehicleParams& params);
- void ProcessPlayersVehicleEngine(cVehicleParams& params, CAutomobile *automobile);
- void ProcessPoliceCellBeatingScriptObject(uint8 sound);
- void ProcessPornCinema(uint8 sound);
- void ProcessProjectiles();
- void ProcessRainOnVehicle(cVehicleParams& params);
- void ProcessReverb() const;
- bool ProcessReverseGear(cVehicleParams& params);
- void ProcessSawMillScriptObject(uint8 sound);
- void ProcessScriptObject(int32 id);
- void ProcessShopScriptObject(uint8 sound);
- void ProcessSpecial();
- bool ProcessTrainNoise(cVehicleParams& params);
- void ProcessVehicle(CVehicle *vehicle);
- bool ProcessVehicleDoors(cVehicleParams& params);
- void ProcessVehicleEngine(cVehicleParams& params);
- void ProcessVehicleHorn(cVehicleParams& params);
- void ProcessVehicleOneShots(cVehicleParams& params);
- bool ProcessVehicleReverseWarning(cVehicleParams& params);
- bool ProcessVehicleRoadNoise(cVehicleParams& params);
- bool ProcessVehicleSirenOrAlarm(cVehicleParams& params);
- bool ProcessVehicleSkidding(cVehicleParams& params);
- void ProcessWaterCannon(int32);
- void ProcessWeather(int32 id);
- bool ProcessWetRoadNoise(cVehicleParams& params);
- void ProcessWorkShopScriptObject(uint8 sound);
-
- int32 RandomDisplacement(uint32 seed) const;
- void ReacquireDigitalHandle() const;
- void ReleaseDigitalHandle() const;
- void ReportCollision(CEntity *entity1, CEntity *entity2, uint8 surface1, uint8 surface2,
- float collisionPower, float intensity2);
- void ReportCrime(eCrimeType crime, const CVector &pos);
- void ResetAudioLogicTimers(uint32 timer);
- void ResetPoliceRadio();
- void ResetTimers(uint32 time);
-
- void Service();
- void ServiceCollisions();
+ void ProcessActiveQueues(); // done
+ bool ProcessAirBrakes(cVehicleParams& params); // done
+ bool ProcessBoatEngine(cVehicleParams& params);
+ bool ProcessBoatMovingOverWater(cVehicleParams& params);
+#ifdef GTA_BRIDGE
+ void ProcessBridge(); // done(bcs not exists in VC)
+ void ProcessBridgeMotor(); // done(bcs not exists in VC)
+ void ProcessBridgeOneShots(); // done(bcs not exists in VC)
+ void ProcessBridgeWarning(); // done(bcs not exists in VC)
+#endif
+ bool ProcessCarBombTick(cVehicleParams& params); // done
+ void ProcessCarHeli(cVehicleParams& params); // done
+ void ProcessCesna(cVehicleParams& params); //
+ //void ProcessCrane(); // done(bcs not exists in VC)
+ bool ProcessEngineDamage(cVehicleParams& params); // done
+ void ProcessEntity(int32 sound); // done
+ void ProcessExplosions(int32 explosion); // done
+ void ProcessFireHydrant(); // done
+ void ProcessFires(int32 entity); // done
+ void ProcessFrontEnd(); // done
+ void ProcessGarages(); //
+ void ProcessJumbo(cVehicleParams& params); // done
+ void ProcessJumboAccel(CPlane *plane); // done
+ void ProcessJumboDecel(CPlane *plane); // done
+ void ProcessJumboFlying(); // done
+ void ProcessJumboLanding(CPlane *plane); // done
+ void ProcessJumboTakeOff(CPlane *plane); // done
+ void ProcessJumboTaxi(); // done
+ void ProcessLoopingScriptObject(uint8 sound); //
+ void ProcessMissionAudio(); //
+ void ProcessMissionAudioSlot(uint8 slot); //
+ void ProcessModelHeliVehicle(cVehicleParams& params); // done
+ void ProcessModelVehicle(cVehicleParams& params); // done
+ void ProcessOneShotScriptObject(uint8 sound); //
+ void ProcessPed(CPhysical *ped); // done
+ void ProcessPedOneShots(cPedParams &params); //
+ void ProcessPhysical(int32 id); // done
+ void ProcessPlane(cVehicleParams& params); // done
+ void ProcessPlayerMood(); // done
+ void ProcessPlayersVehicleEngine(cVehicleParams& params, CVehicle* veh); // done
+ void ProcessProjectiles(); // done
+ void ProcessRainOnVehicle(cVehicleParams& params); // done
+ void ProcessReverb() const; // done
+ bool ProcessReverseGear(cVehicleParams& params); // done
+ void ProcessScriptObject(int32 id); // done
+ void ProcessSpecial(); // done
+#ifdef GTA_TRAIN
+ bool ProcessTrainNoise(cVehicleParams *params); //done(bcs not exists in VC)
+#endif
+ void ProcessVehicle(CVehicle *vehicle); // done
+ bool ProcessVehicleDoors(cVehicleParams& params); // done
+ void ProcessVehicleEngine(cVehicleParams& params); // done
+ void ProcessVehicleFlatTyre(cVehicleParams& params); // done
+ bool ProcessVehicleHorn(cVehicleParams& params); // done
+ void ProcessVehicleOneShots(cVehicleParams& params); // done
+ bool ProcessVehicleReverseWarning(cVehicleParams& params); // done
+ bool ProcessVehicleRoadNoise(cVehicleParams& params); // done
+ bool ProcessVehicleSirenOrAlarm(cVehicleParams& params); // done
+ bool ProcessVehicleSkidding(cVehicleParams& params); // done
+ void ProcessWaterCannon(int32); // done
+ void ProcessWeather(int32 id); // done
+ bool ProcessWetRoadNoise(cVehicleParams& params); // done
+ void ProcessEscalators(); // done
+ void ProcessExtraSounds(); // done
+
+ int32 RandomDisplacement(uint32 seed) const; // done
+ void ReacquireDigitalHandle() const; // done
+ void ReleaseDigitalHandle() const; // done
+ void ReportCollision(CEntity *entity1, CEntity *entity2, uint8 surface1, uint8 surface2, float collisionPower, float intensity2); // done
+ void ReportCrime(eCrimeType crime, const CVector &pos); // done
+ void ResetAudioLogicTimers(uint32 timer); // done
+ void ResetPoliceRadio(); // done
+ void ResetTimers(uint32 time); // done
+
+ void Service(); //done
+ void ServiceCollisions(); //done
void ServicePoliceRadio();
void ServicePoliceRadioChannel(uint8 wantedLevel);
void ServiceSoundEffects();
@@ -446,9 +483,10 @@ public:
void SetDynamicAcousticModelingStatus(uint8 status);
void SetEffectsFadeVol(uint8 volume) const;
void SetEffectsMasterVolume(uint8 volume) const;
- void SetEntityStatus(int32 id, uint8 status);
+ void SetMP3BoostVolume(uint8 volume) const;
+ void SetEntityStatus(int32 id, uint8 status); //done
uint32 SetLoopingCollisionRequestedSfxFreqAndGetVol(const cAudioCollision &audioCollision);
- void SetMissionAudioLocation(float x, float y, float z);
+ void SetMissionAudioLocation(uint8 slot, float x, float y, float z);
void SetMissionScriptPoliceAudio(int32 sfx) const;
void SetMonoMode(uint8 mono);
void SetMusicFadeVol(uint8 volume) const;
@@ -462,17 +500,21 @@ public:
bool SetupJumboRumbleSound(uint8 emittingVol);
bool SetupJumboTaxiSound(uint8 vol);
bool SetupJumboWhineSound(uint8 emittingVol, uint32 freq);
- void SetupPedComments(cPedParams &params, uint16 sound);
+ void SetupPedComments(cPedParams &params, uint16 sound); // done
void SetupSuspectLastSeenReport();
- void Terminate();
- void TranslateEntity(Const CVector *v1, CVector *v2) const;
+ void Terminate(); //done
+ void TranslateEntity(Const CVector *v1, CVector *v2) const; //done
+
+ void UpdateGasPedalAudio(CVehicle* veh, int vehType); // done
+ void UpdateReflections(); //done
+ bool UsesReverseWarning(int32 model) const; //done
+ bool UsesSiren(cVehicleParams& params) const; //done
+ bool UsesSirenSwitching(cVehicleParams& params) const; //done
- void UpdateGasPedalAudio(CAutomobile *automobile);
- void UpdateReflections();
- bool UsesReverseWarning(int32 model) const;
- bool UsesSiren(int32 model) const;
- bool UsesSirenSwitching(int32 model) const;
+ CVehicle *FindVehicleOfPlayer(); //done
+ void SetPedTalkingStatus(CPed *ped, uint8 status);
+ void SetPlayersMood(uint8 mood, uint32 time);
#ifdef GTA_PC
// only used in pc
@@ -482,7 +524,7 @@ public:
};
#ifdef AUDIO_MSS
-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..a68cf768 100644
--- a/src/audio/AudioSamples.h
+++ b/src/audio/AudioSamples.h
@@ -1,4 +1,4 @@
-#pragma once
+#pragma once
#include "common.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_STRAFISH_ISLAND, //???????????
+ SFX_POLICE_RADIO_VICE_PORT,
+ 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,418 +242,364 @@ 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_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_TRUCK,
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,
-
- // bank 11
- SFX_TRAIN_STATION_AMBIENCE_LOOP,
- SFX_TRAIN_STATION_ANNOUNCE,
-
- // bank 12
- SFX_CLUB_1,
-
- // bank 13
- SFX_CLUB_2,
-
- // bank 14
- SFX_CLUB_3,
-
- // bank 15
- SFX_CLUB_4,
-
- // bank 16
- SFX_CLUB_5,
-
- // bank 17
- SFX_CLUB_6,
-
- // bank 18
- SFX_CLUB_7,
-
- // bank 19
- SFX_CLUB_8,
-
- // bank 20
- SFX_CLUB_9,
-
- // bank 21
- SFX_CLUB_10,
-
- // bank 22
- SFX_CLUB_11,
-
- // bank 23
- SFX_CLUB_12,
-
- // bank 24
- SFX_CLUB_RAGGA,
-
- // bank 25
- SFX_STRIP_CLUB_1,
-
- // bank 26
- SFX_STRIP_CLUB_2,
-
- // bank 27
- SFX_WORKSHOP_1,
-
- // bank 28
- SFX_PIANO_BAR_1,
-
- // bank 29
- SFX_SAWMILL_LOOP,
- SFX_SAWMILL_CUT_WOOD,
-
- // bank 30
- SFX_DOG_FOOD_FACTORY,
-
- // bank 31
- SFX_LAUNDERETTE_LOOP,
- SFX_LAUNDERETTE_SONG_LOOP,
-
- // bank 32
- SFX_RESTAURANT_CHINATOWN,
-
- // bank 33
- SFX_RESTAURANT_ITALY,
-
- // bank 34
- SFX_RESTAURANT_GENERIC_1,
-
- // bank 35
- SFX_RESTAURANT_GENERIC_2,
-
- // bank 36
- SFX_AIRPORT_ANNOUNCEMENT_1,
- SFX_AIRPORT_ANNOUNCEMENT_2,
- SFX_AIRPORT_ANNOUNCEMENT_3,
- SFX_AIRPORT_ANNOUNCEMENT_4,
-
- // bank 37
- SFX_SHOP_LOOP,
- SFX_SHOP_TILL_1,
- SFX_SHOP_TILL_2,
-
- // bank 38
- SFX_CINEMA_BASS_1,
- SFX_CINEMA_BASS_2,
- SFX_CINEMA_BASS_3,
-
- // bank 39
- SFX_DOCKS_FOGHORN,
-
- // bank 40
- SFX_HOME_1,
- SFX_HOME_2,
- SFX_HOME_3,
- SFX_HOME_4,
- SFX_HOME_5,
-
- // bank 41
- SFX_PORN_1_LOOP,
- SFX_PORN_1_GROAN_1,
- SFX_PORN_1_GROAN_2,
-
- // bank 42
- SFX_PORN_2_LOOP,
- SFX_PORN_2_GROAN_1,
- SFX_PORN_2_GROAN_2,
+ SFX_CAR_ACCEL_10,
+ SFX_CAR_AFTER_ACCEL_10,
+ SFX_CAR_FINGER_OFF_ACCEL_10,
+
+ SFX_CAR_ACCEL_11,
+ SFX_CAR_AFTER_ACCEL_11,
+ SFX_CAR_FINGER_OFF_ACCEL_11,
+
+ SFX_CAR_ACCEL_12,
+ SFX_CAR_AFTER_ACCEL_12,
+ SFX_CAR_FINGER_OFF_ACCEL_12,
+
+ // some CHAINSAW STUFF
+ // SFX_CAR_CHAINSAW, //10973
+ // SFX_CAR_CHAINSAW, //10974
+ // SFX_CAR_CHAINSAW, //10975
+ SFX_CAR_ACCEL_13,
+ SFX_CAR_AFTER_ACCEL_13,
+ SFX_CAR_FINGER_OFF_ACCEL_13,
+
+ SFX_RC_IDLE, // 10976
+ SFX_RC_REV, // 10977
+ SFX_RC_EMPTY, // 10978
+
+ SFX_CAR_RC_HELI, // 10979
+ SFX_CAR_AFTER_ACCEL_15, // empty
+ SFX_CAR_FINGER_OFF_ACCEL_15, // empty
+
+ SFX_CAR_ACCEL_16, // empty
+ SFX_CAR_AFTER_ACCEL_16, // empty
+ SFX_CAR_FINGER_OFF_ACCEL_16, // empty
+
+ // bike stuff apparently
+ SFX_CAR_ACCEL_17,
+ SFX_CAR_AFTER_ACCEL_17,
+ SFX_CAR_FINGER_OFF_ACCEL_17,
+ SFX_CAR_WIND_17,
+
+ SFX_CAR_ACCEL_18,
+ SFX_CAR_AFTER_ACCEL_18,
+ SFX_CAR_FINGER_OFF_ACCEL_18,
+ SFX_CAR_WIND_18,
+
+ SFX_CAR_ACCEL_19,
+ SFX_CAR_AFTER_ACCEL_19,
+ SFX_CAR_FINGER_OFF_ACCEL_19,
+ SFX_CAR_WIND_19,
+
+ SFX_CAR_ACCEL_20,
+ SFX_CAR_AFTER_ACCEL_20,
+ SFX_CAR_FINGER_OFF_ACCEL_20,
+ SFX_CAR_WIND_20,
+
+ // 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,
+
+ SFX_HELI_APACHE_1,
+ SFX_HELI_APACHE_2,
+ SFX_HELI_APACHE_3,
+ SFX_HELI_APACHE_4,
+
+ // something padded for more heli?
+ SFX_HELI_UNUSED_1,
+ SFX_HELI_UNUSED_2,
+ SFX_HELI_UNUSED_3,
+ SFX_HELI_UNUSED_4,
+
+ SFX_SEAPLANE_PRO1, // 11018
+ SFX_SEAPLANE_PRO2, // 11019
+ SFX_SEAPLANE_PRO3, // 11020
+ SFX_SEAPLANE_PRO4, // 11021
+ // low fuel
+ SFX_SEAPLANE_LOW, // 11022
+
+ // something padded for more plane?
+ SFX_PLANE_UNUSED_1,
+ SFX_PLANE_UNUSED_2,
+ SFX_PLANE_UNUSED_3,
+ SFX_PLANE_UNUSED_4,
+
+ // 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 43
- SFX_PORN_3_LOOP,
- SFX_PORN_3_GROAN_1,
- SFX_PORN_3_GROAN_2,
-
- // bank 44
- SFX_POLICE_BALL_1,
-
- // bank 45
- SFX_BANK_ALARM_1,
-
- // bank 46
- SFX_RAVE_INDUSTRIAL,
-
- // bank 47
- SFX_RAVE_COMMERCIAL,
-
- // bank 48
- SFX_RAVE_SUBURBAN,
-
- // bank 49
- SFX_RAVE_COMMERCIAL_2,
-
- // 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,
-
- // bank 59
- SFX_EXPLOSION_1,
- SFX_BRIDGE_OPEN_WARNING,
+ 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_PAGER, // used to be ped comment on PS2
+ // TODO: miami ped comments... THERE'S OVER 9000
+ SFX_POLICE_BOAT_1 = 714,
+ 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,
- 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,
@@ -694,2460 +620,198 @@ enum eSfxSample
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_GENERIC_FEMALE_DEATH_1,
- SFX_GENERIC_FEMALE_DEATH_2,
- SFX_GENERIC_FEMALE_DEATH_3,
- SFX_GENERIC_FEMALE_DEATH_4,
- SFX_GENERIC_FEMALE_DEATH_5,
- SFX_GENERIC_FEMALE_DEATH_6,
- SFX_GENERIC_FEMALE_DEATH_7,
- 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_GRUNT_1,
- SFX_GENERIC_FEMALE_GRUNT_2,
- SFX_GENERIC_FEMALE_GRUNT_3,
- SFX_GENERIC_FEMALE_GRUNT_4,
- SFX_GENERIC_FEMALE_GRUNT_5,
- SFX_GENERIC_FEMALE_GRUNT_6,
- SFX_GENERIC_FEMALE_GRUNT_7,
- SFX_GENERIC_FEMALE_GRUNT_8,
- SFX_GENERIC_FEMALE_GRUNT_9,
- SFX_GENERIC_FEMALE_GRUNT_10,
- SFX_GENERIC_FEMALE_GRUNT_11,
- SFX_GENERIC_FEMALE_PANIC_1,
- SFX_GENERIC_FEMALE_PANIC_2,
- SFX_GENERIC_FEMALE_PANIC_3,
- SFX_GENERIC_FEMALE_PANIC_4,
- SFX_GENERIC_FEMALE_PANIC_5,
- 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_MALE_FIRE_1,
- SFX_GENERIC_MALE_FIRE_2,
- SFX_GENERIC_MALE_FIRE_3,
- SFX_GENERIC_MALE_FIRE_4,
- SFX_GENERIC_MALE_FIRE_5,
- SFX_GENERIC_MALE_FIRE_6,
- SFX_GENERIC_MALE_FIRE_7,
- SFX_GENERIC_MALE_FIRE_8,
- SFX_GENERIC_MALE_GRUNT_1,
- SFX_GENERIC_MALE_GRUNT_2,
- SFX_GENERIC_MALE_GRUNT_3,
- SFX_GENERIC_MALE_GRUNT_4,
- SFX_GENERIC_MALE_GRUNT_5,
- SFX_GENERIC_MALE_GRUNT_6,
- SFX_GENERIC_MALE_GRUNT_7,
- SFX_GENERIC_MALE_GRUNT_8,
- SFX_GENERIC_MALE_GRUNT_9,
- SFX_GENERIC_MALE_GRUNT_10,
- SFX_GENERIC_MALE_GRUNT_11,
- SFX_GENERIC_MALE_GRUNT_12,
- SFX_GENERIC_MALE_GRUNT_13,
- SFX_GENERIC_MALE_GRUNT_14,
- SFX_GENERIC_MALE_GRUNT_15,
- 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,
- TOTAL_AUDIO_SAMPLES,
+
+ SFX_GENERIC_FEMALE_GRUNT_1 = 2953,
+ SFX_GENERIC_FEMALE_GRUNT_2 = 2954,
+ SFX_GENERIC_FEMALE_GRUNT_3 = 2955,
+ SFX_GENERIC_FEMALE_GRUNT_4 = 2956,
+ SFX_GENERIC_FEMALE_GRUNT_5 = 2957,
+ SFX_GENERIC_FEMALE_GRUNT_6 = 2958,
+ SFX_GENERIC_FEMALE_GRUNT_7 = 2959,
+ SFX_GENERIC_FEMALE_GRUNT_8 = 2960,
+ SFX_GENERIC_FEMALE_GRUNT_9 = 2961,
+ SFX_GENERIC_FEMALE_GRUNT_10 = 2962,
+ SFX_GENERIC_FEMALE_GRUNT_11 = 2963,
+ SFX_GENERIC_FEMALE_GRUNT_12 = 2964,
+ SFX_GENERIC_FEMALE_GRUNT_13 = 2965,
+ SFX_GENERIC_FEMALE_GRUNT_14 = 2966,
+ SFX_GENERIC_FEMALE_GRUNT_15 = 2967,
+ SFX_GENERIC_FEMALE_GRUNT_16 = 2968,
+ SFX_GENERIC_FEMALE_GRUNT_17 = 2969,
+ SFX_GENERIC_FEMALE_GRUNT_18 = 2970,
+ SFX_GENERIC_FEMALE_GRUNT_19 = 2971,
+ SFX_GENERIC_FEMALE_GRUNT_20 = 2972,
+ SFX_GENERIC_FEMALE_GRUNT_21 = 2973,
+ SFX_GENERIC_FEMALE_GRUNT_22 = 2974,
+ SFX_GENERIC_FEMALE_GRUNT_23 = 2975,
+ SFX_GENERIC_FEMALE_GRUNT_24 = 2976,
+ SFX_GENERIC_FEMALE_GRUNT_25 = 2977,
+ SFX_GENERIC_FEMALE_GRUNT_26 = 2978,
+ SFX_GENERIC_FEMALE_GRUNT_27 = 2979,
+ SFX_GENERIC_FEMALE_GRUNT_28 = 2980,
+ SFX_GENERIC_FEMALE_GRUNT_29 = 2981,
+ SFX_GENERIC_FEMALE_GRUNT_30 = 2982,
+ SFX_GENERIC_FEMALE_GRUNT_31 = 2983,
+ SFX_GENERIC_FEMALE_GRUNT_32 = 2984,
+ SFX_GENERIC_FEMALE_GRUNT_33 = 2985,
+ SFX_GENERIC_MALE_FIRE_1 = 3013,
+ SFX_GENERIC_MALE_FIRE_2 = 3014,
+ SFX_GENERIC_MALE_FIRE_3 = 3015,
+ SFX_GENERIC_MALE_FIRE_4 = 3016,
+ SFX_GENERIC_MALE_FIRE_5 = 3017,
+ SFX_GENERIC_MALE_FIRE_6 = 3018,
+ SFX_GENERIC_MALE_FIRE_7 = 3019,
+ SFX_GENERIC_MALE_FIRE_8 = 3020,
+ SFX_GENERIC_MALE_FIRE_9 = 3021,
+ SFX_GENERIC_MALE_FIRE_10 = 3022,
+ SFX_GENERIC_MALE_FIRE_11 = 3023,
+ SFX_GENERIC_MALE_FIRE_12 = 3024,
+ SFX_GENERIC_MALE_FIRE_13 = 3025,
+ SFX_GENERIC_MALE_FIRE_14 = 3026,
+ SFX_GENERIC_MALE_FIRE_15 = 3027,
+ SFX_GENERIC_MALE_FIRE_16 = 3028,
+ SFX_GENERIC_MALE_FIRE_17 = 3029,
+ SFX_GENERIC_MALE_FIRE_18 = 3030,
+ SFX_GENERIC_MALE_FIRE_19 = 3031,
+ SFX_GENERIC_MALE_FIRE_20 = 3032,
+ SFX_GENERIC_MALE_FIRE_21 = 3033,
+ SFX_GENERIC_MALE_FIRE_22 = 3034,
+ SFX_GENERIC_MALE_FIRE_23 = 3035,
+ SFX_GENERIC_MALE_FIRE_24 = 3036,
+ SFX_GENERIC_MALE_FIRE_25 = 3037,
+ SFX_GENERIC_MALE_FIRE_26 = 3038,
+ SFX_GENERIC_MALE_FIRE_27 = 3039,
+ SFX_GENERIC_MALE_FIRE_28 = 3040,
+ SFX_GENERIC_MALE_FIRE_29 = 3041,
+ SFX_GENERIC_MALE_FIRE_30 = 3042,
+ SFX_GENERIC_MALE_FIRE_31 = 3043,
+ SFX_GENERIC_MALE_FIRE_32 = 3044,
+ SFX_GENERIC_MALE_DEATH_1 = 3045,
+ SFX_GENERIC_MALE_DEATH_2 = 3046,
+ SFX_GENERIC_MALE_DEATH_3 = 3047,
+ SFX_GENERIC_MALE_DEATH_4 = 3048,
+ SFX_GENERIC_MALE_DEATH_5 = 3049,
+ SFX_GENERIC_MALE_DEATH_6 = 3050,
+ SFX_GENERIC_MALE_DEATH_7 = 3051,
+ SFX_GENERIC_MALE_DEATH_8 = 3052,
+ SFX_GENERIC_MALE_DEATH_9 = 3053,
+ SFX_GENERIC_MALE_DEATH_10 = 3054,
+ SFX_GENERIC_MALE_DEATH_11 = 3055,
+ SFX_GENERIC_MALE_DEATH_12 = 3056,
+ SFX_GENERIC_MALE_DEATH_13 = 3057,
+ SFX_GENERIC_MALE_DEATH_14 = 3058,
+ SFX_GENERIC_MALE_DEATH_15 = 3059,
+ SFX_GENERIC_MALE_DEATH_16 = 3060,
+ SFX_GENERIC_MALE_DEATH_17 = 3061,
+ SFX_GENERIC_MALE_DEATH_18 = 3062,
+ SFX_GENERIC_MALE_DEATH_19 = 3063,
+ SFX_GENERIC_MALE_DEATH_20 = 3064,
+ SFX_GENERIC_MALE_DEATH_21 = 3065,
+ SFX_GENERIC_MALE_DEATH_22 = 3066,
+ SFX_GENERIC_MALE_DEATH_23 = 3067,
+ SFX_GENERIC_MALE_DEATH_24 = 3068,
+ SFX_GENERIC_MALE_DEATH_25 = 3069,
+ SFX_GENERIC_MALE_DEATH_26 = 3070,
+ SFX_GENERIC_MALE_DEATH_27 = 3071,
+ SFX_GENERIC_MALE_DEATH_28 = 3072,
+ SFX_GENERIC_MALE_DEATH_29 = 3073,
+ SFX_GENERIC_MALE_DEATH_30 = 3074,
+ SFX_GENERIC_MALE_DEATH_31 = 3075,
+ SFX_GENERIC_MALE_DEATH_32 = 3076,
+ SFX_GENERIC_MALE_DEATH_33 = 3077,
+ SFX_GENERIC_MALE_DEATH_34 = 3078,
+ SFX_GENERIC_MALE_DEATH_35 = 3079,
+ SFX_GENERIC_MALE_DEATH_36 = 3080,
+ SFX_GENERIC_MALE_DEATH_37 = 3081,
+ SFX_GENERIC_MALE_DEATH_38 = 3082,
+ SFX_GENERIC_MALE_DEATH_39 = 3083,
+ SFX_GENERIC_MALE_DEATH_40 = 3084,
+ SFX_GENERIC_MALE_DEATH_41 = 3085,
+ SFX_GENERIC_MALE_GRUNT_1 = 3086,
+ SFX_GENERIC_MALE_GRUNT_2 = 3087,
+ SFX_GENERIC_MALE_GRUNT_3 = 3088,
+ SFX_GENERIC_MALE_GRUNT_4 = 3089,
+ SFX_GENERIC_MALE_GRUNT_5 = 3090,
+ SFX_GENERIC_MALE_GRUNT_6 = 3091,
+ SFX_GENERIC_MALE_GRUNT_7 = 3092,
+ SFX_GENERIC_MALE_GRUNT_8 = 3093,
+ SFX_GENERIC_MALE_GRUNT_9 = 3094,
+ SFX_GENERIC_MALE_GRUNT_10 = 3095,
+ SFX_GENERIC_MALE_GRUNT_11 = 3096,
+ SFX_GENERIC_MALE_GRUNT_12 = 3097,
+ SFX_GENERIC_MALE_GRUNT_13 = 3098,
+ SFX_GENERIC_MALE_GRUNT_14 = 3099,
+ SFX_GENERIC_MALE_GRUNT_15 = 3100,
+ SFX_GENERIC_MALE_GRUNT_16 = 3101,
+ SFX_GENERIC_MALE_GRUNT_17 = 3102,
+ SFX_GENERIC_MALE_GRUNT_18 = 3103,
+ SFX_GENERIC_MALE_GRUNT_19 = 3104,
+ SFX_GENERIC_MALE_GRUNT_20 = 3105,
+ SFX_GENERIC_MALE_GRUNT_21 = 3106,
+ SFX_GENERIC_MALE_GRUNT_22 = 3107,
+ SFX_GENERIC_MALE_GRUNT_23 = 3108,
+ SFX_GENERIC_MALE_GRUNT_24 = 3109,
+ SFX_GENERIC_MALE_GRUNT_25 = 3110,
+ SFX_GENERIC_MALE_GRUNT_26 = 3111,
+ SFX_GENERIC_MALE_GRUNT_27 = 3112,
+ SFX_GENERIC_MALE_GRUNT_28 = 3113,
+ SFX_GENERIC_MALE_GRUNT_29 = 3114,
+ SFX_GENERIC_MALE_GRUNT_30 = 3115,
+ SFX_GENERIC_MALE_GRUNT_31 = 3116,
+ SFX_GENERIC_MALE_GRUNT_32 = 3117,
+ SFX_GENERIC_MALE_GRUNT_33 = 3118,
+ SFX_GENERIC_MALE_GRUNT_34 = 3119,
+ SFX_GENERIC_MALE_GRUNT_35 = 3120,
+ SFX_GENERIC_MALE_GRUNT_36 = 3121,
+ SFX_GENERIC_MALE_GRUNT_37 = 3122,
+ SFX_GENERIC_MALE_GRUNT_38 = 3123,
+ SFX_GENERIC_MALE_GRUNT_39 = 3124,
+ SFX_GENERIC_MALE_GRUNT_40 = 3125,
+ SFX_GENERIC_MALE_GRUNT_41 = 3126,
+ SFX_GENERIC_MALE_PANIC_1 = 3127,
+ SFX_GENERIC_MALE_PANIC_2 = 3128,
+ SFX_GENERIC_MALE_PANIC_3 = 3129,
+ SFX_GENERIC_MALE_PANIC_4 = 3130,
+ SFX_GENERIC_MALE_PANIC_5 = 3131,
+ SFX_GENERIC_MALE_PANIC_6 = 3132,
+ SFX_GENERIC_MALE_PANIC_7 = 3133,
+ SFX_GENERIC_MALE_PANIC_8 = 3134,
+ SFX_GENERIC_MALE_PANIC_9 = 3135,
+ SFX_GENERIC_MALE_PANIC_10 = 3136,
+ SFX_GENERIC_MALE_PANIC_11 = 3137,
+ SFX_GENERIC_MALE_PANIC_12 = 3138,
+ SFX_GENERIC_MALE_PANIC_13 = 3139,
+ SFX_GENERIC_MALE_PANIC_14 = 3140,
+ SFX_GENERIC_MALE_PANIC_15 = 3141,
+ SFX_GENERIC_MALE_PANIC_16 = 3142,
+ SFX_GENERIC_MALE_PANIC_17 = 3143,
+ SFX_GENERIC_MALE_PANIC_18 = 3144,
+ SFX_GENERIC_MALE_PANIC_19 = 3145,
+ SFX_GENERIC_MALE_PANIC_20 = 3146,
+ SFX_GENERIC_MALE_PANIC_21 = 3147,
+ SFX_GENERIC_MALE_PANIC_22 = 3148,
+ SFX_GENERIC_MALE_PANIC_23 = 3149,
+ SFX_GENERIC_MALE_PANIC_24 = 3150,
+ SFX_GENERIC_MALE_PANIC_25 = 3151,
+ SFX_GENERIC_MALE_PANIC_26 = 3152,
+ SFX_GENERIC_MALE_PANIC_27 = 3153,
+ SFX_GENERIC_MALE_PANIC_28 = 3154,
+ SFX_GENERIC_MALE_PANIC_29 = 3155,
+ SFX_GENERIC_MALE_PANIC_30 = 3156,
+ SFX_GENERIC_MALE_PANIC_31 = 3157,
+ SFX_GENERIC_MALE_PANIC_32 = 3158,
+ SFX_GENERIC_MALE_PANIC_33 = 3159,
+ SFX_GENERIC_MALE_PANIC_34 = 3160,
+ SFX_GENERIC_MALE_PANIC_35 = 3161,
+
+ TOTAL_AUDIO_SAMPLES = 9941,
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/DMAudio.cpp b/src/audio/DMAudio.cpp
index 1027a084..7c99e89f 100644
--- a/src/audio/DMAudio.cpp
+++ b/src/audio/DMAudio.cpp
@@ -63,6 +63,15 @@ cDMAudio::SetMonoMode(uint8 mono)
}
void
+cDMAudio::SetMP3BoostVolume(uint8 volume)
+{
+ uint8 vol = volume;
+ if (vol > MAX_VOLUME) vol = MAX_VOLUME;
+
+ AudioManager.SetMP3BoostVolume(vol);
+}
+
+void
cDMAudio::SetEffectsMasterVolume(uint8 volume)
{
uint8 vol = volume;
@@ -110,6 +119,11 @@ cDMAudio::Get3DProviderName(uint8 id)
return AudioManager.Get3DProviderName(id);
}
+int8 cDMAudio::AutoDetect3DProviders(void)
+{
+ return AudioManager.AutoDetect3DProviders();
+}
+
int8
cDMAudio::GetCurrent3DProviderIndex(void)
{
@@ -224,13 +238,13 @@ cDMAudio::PlayFrontEndSound(uint16 frontend, uint32 volume)
}
void
-cDMAudio::PlayRadioAnnouncement(uint8 announcement)
+cDMAudio::PlayRadioAnnouncement(uint32 announcement)
{
MusicManager.PlayAnnouncement(announcement);
}
void
-cDMAudio::PlayFrontEndTrack(uint8 track, uint8 frontendFlag)
+cDMAudio::PlayFrontEndTrack(uint32 track, uint8 frontendFlag)
{
MusicManager.PlayFrontEndTrack(track, frontendFlag);
}
@@ -254,7 +268,7 @@ cDMAudio::ChangeMusicMode(uint8 mode)
}
void
-cDMAudio::PreloadCutSceneMusic(uint8 track)
+cDMAudio::PreloadCutSceneMusic(uint32 track)
{
MusicManager.PreloadCutSceneMusic(track);
}
@@ -272,39 +286,39 @@ 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);
}
bool
-cDMAudio::IsMissionAudioSampleFinished(void)
+cDMAudio::IsMissionAudioSampleFinished(uint8 slot)
{
- return AudioManager.IsMissionAudioSampleFinished();
+ return AudioManager.IsMissionAudioSampleFinished(slot);
}
void
-cDMAudio::ClearMissionAudio(void)
+cDMAudio::ClearMissionAudio(uint8 slot)
{
- AudioManager.ClearMissionAudio();
+ AudioManager.ClearMissionAudio(slot);
}
uint8
@@ -320,7 +334,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(uint8 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, uint8 status)
+{
+ return AudioManager.SetPedTalkingStatus(ped, status);
+}
+
+void
+cDMAudio::SetPlayersMood(uint8 mood, uint32 time)
+{
+ return AudioManager.SetPlayersMood(mood, time);
+}
+
+void
+cDMAudio::ShutUpPlayerTalking(uint8 state)
+{
+ AudioManager.m_bIsPlayerShutUp = state;
+} \ No newline at end of file
diff --git a/src/audio/DMAudio.h b/src/audio/DMAudio.h
index 3e6d5603..2c10043f 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,6 +30,7 @@ public:
void DestroyAllGameCreatedEntities(void);
void SetMonoMode(uint8 mono);
+ void SetMP3BoostVolume(uint8 volume);
void SetEffectsMasterVolume(uint8 volume);
void SetMusicMasterVolume(uint8 volume);
void SetEffectsFadeVol(uint8 volume);
@@ -35,6 +39,8 @@ public:
uint8 GetNum3DProvidersAvailable(void);
char *Get3DProviderName(uint8 id);
+ int8 AutoDetect3DProviders(void);
+
int8 GetCurrent3DProviderIndex(void);
int8 SetCurrent3DProvider(uint8 which);
@@ -63,27 +69,35 @@ 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, uint8 frontendFlag);
+ void PlayRadioAnnouncement(uint32 announcement);
+ void PlayFrontEndTrack(uint32 track, uint8 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);
- bool 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);
+ bool IsMissionAudioSampleFinished(uint8 slot);
+ void ClearMissionAudio(uint8 slot);
uint8 GetRadioInCar(void);
void SetRadioInCar(uint32 radio);
- void SetRadioChannel(uint8 radio, int32 pos);
+ void SetRadioChannel(uint32 radio, int32 pos);
+
+ void SetStartingTrackPositions(uint8 isStartGame);
+ float *GetListenTimeArray();
+ uint32 GetFavouriteRadioStation();
+ int32 GetRadioPosition(uint32 station);
+ void SetPedTalkingStatus(class CPed *ped, uint8 status);
+ void SetPlayersMood(uint8 mood, uint32 time);
+ void ShutUpPlayerTalking(uint8 state);
};
extern cDMAudio DMAudio;
diff --git a/src/audio/MusicManager.cpp b/src/audio/MusicManager.cpp
index 5519d899..8aedf306 100644
--- a/src/audio/MusicManager.cpp
+++ b/src/audio/MusicManager.cpp
@@ -14,178 +14,123 @@
#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"
cMusicManager MusicManager;
int32 gNumRetunePresses;
int32 gRetuneCounter;
-bool bHasStarted;
+bool g_bAnnouncementReadPosAlready;
+uint8 RadioStaticCounter;
+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_nFrontendTrack = NO_TRACK;
+ m_nPlayingTrack = NO_TRACK;
+ m_nUpcomingMusicMode = MUSICMODE_DISABLED;
m_nMusicMode = MUSICMODE_DISABLED;
- m_nCurrentStreamedSound = NO_TRACK;
- m_nPreviousStreamedSound = NO_TRACK;
- m_bFrontendTrackFinished = false;
- m_bPlayInFrontend = false;
- m_bSetNextStation = false;
- m_nAnnouncement = NO_TRACK;
- m_bPreviousPlayerInCar = false;
- m_bPlayerInCar = false;
- m_bAnnouncementInProgress = false;
- m_bDontServiceAmbienceTrack = false;
- bHasStarted = false;
-}
+ field_2 = false;
-bool
-cMusicManager::PlayerInCar()
-{
- if(!FindPlayerVehicle())
- return false;
-
- int32 State = FindPlayerPed()->m_nPedState;
+ for (int i = 0; i < NUM_RADIOS; i++)
+ aListenTimeArray[i] = 0.0f;
- if(State == PED_DRAG_FROM_CAR || State == PED_EXIT_CAR || State == PED_ARRESTED)
- return false;
-
- 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;
-
- if(SampleManager.IsMP3RadioChannelAvailable()) {
- gStreamedSound = m_nCurrentStreamedSound;
+ float afRadioTime[NUM_RADIOS];
- if(gStreamedSound == STREAMED_SOUND_CITY_AMBIENT ||
- gStreamedSound == STREAMED_SOUND_WATER_AMBIENT) {
- gStreamedSound = STREAMED_SOUND_RADIO_POLICE;
- } else {
-
- if(gStreamedSound >
- STREAMED_SOUND_RADIO_MP3_PLAYER)
- return;
- }
-
- pRetune = gNumRetunePresses + gStreamedSound;
-
- if(pRetune == POLICE_RADIO) {
- pRetune = RADIO_OFF;
- } else if(pRetune > POLICE_RADIO) {
- pRetune = pRetune - RADIO_OFF;
- }
- } else {
- gStreamedSound = m_nCurrentStreamedSound;
- pRetune = gNumRetunePresses + gStreamedSound;
-
- if(pRetune >= USERTRACK) {
- gRetuneCounter = gNumRetunePresses;
- pRetune = m_nCurrentStreamedSound;
-
- if(gStreamedSound == STREAMED_SOUND_WATER_AMBIENT)
- pRetune = RADIO_OFF;
+ m_bRadioSetByScript = false;
+ m_nRadioStation = WILDSTYLE;
+ m_nRadioPosition = -1;
+ m_nAnnouncement = NO_TRACK;
+ m_bAnnouncementInProgress = false;
+ field_2 = false;
+ RadioStaticTimer = 0;
+ gNumRetunePresses = 0;
+ gRetuneCounter = 0;
+ m_nFrontendTrack = NO_TRACK;
+ m_nPlayingTrack = NO_TRACK;
+ field_398E = false;
+ field_398F = false;
+ m_nStreamedTrack = NO_TRACK;
+ field_3994 = false;
+ field_3995 = false;
+ field_3996 = false;
+ field_3997 = false;
+ nFramesSinceCutsceneEnded = -1;
+ field_3999 = false;
+ field_399A = false;
+ field_399C = false;
+ m_nVolumeLatency = 0;
+ m_nCurrentVolume = 0;
+ m_nMaxVolume = 0;
+
+ bool bRadioWasEverListened = false;
+
+ for (int i = 0; i < NUM_RADIOS; i++) {
+ afRadioTime[i] = CStats::GetFavoriteRadioStationList(i);
+ if (!bRadioWasEverListened && afRadioTime[i] != 0.0f)
+ bRadioWasEverListened = true;
+ }
- while(gRetuneCounter) {
- if(pRetune == RADIO_OFF) {
- pRetune = HEAD_RADIO;
- } else if(pRetune < USERTRACK) {
- pRetune = pRetune + 1;
- }
- if(pRetune == USERTRACK) pRetune = RADIO_OFF;
+ if (!bRadioWasEverListened) return;
- --gRetuneCounter;
- }
+ for (int i = 0; i < NUM_RADIOS; i++) {
+ aListenTimeArray[i] = afRadioTime[i];
+ uint32 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;
}
+ m_aTracks[i].m_nPosition = trackPos;
+ m_aTracks[i].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode();
}
-
- wchar *string = nil;
-
- 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: string = TheText.Get("FEA_FM9"); break;
- default: return;
- };
-
- if(pRetune > CHATTERBOX && !SampleManager.IsMP3RadioChannelAvailable()) { return; }
-
- if(string && pCurrentStation != string ||
- m_nCurrentStreamedSound == STREAMED_SOUND_RADIO_MP3_PLAYER &&
- m_nPreviousStreamedSound != STREAMED_SOUND_RADIO_MP3_PLAYER) {
- pCurrentStation = string;
- cDisplay = 60;
- } else {
- if(cDisplay == 0) return;
- cDisplay--;
- }
-
- CFont::SetJustifyOff();
- CFont::SetBackgroundOff();
- CFont::SetScale(SCREEN_SCALE_X(0.8f), SCREEN_SCALE_Y(1.35f));
- CFont::SetPropOn();
- CFont::SetFontStyle(FONT_HEADING);
- 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();
}
}
-bool
-cMusicManager::Initialise()
+void
+cMusicManager::SetStartingTrackPositions(uint8 isNewGameTimer)
{
int pos;
- if (!IsInitialised()) {
+ if (IsInitialised()) {
time_t timevalue = time(0);
if (timevalue == -1) {
pos = AudioManager.GetRandomNumber(0);
} else {
- tm *pTm = localtime(&timevalue);
+ tm* pTm = localtime(&timevalue);
if (pTm->tm_sec == 0)
pTm->tm_sec = AudioManager.GetRandomNumber(0);
if (pTm->tm_min == 0)
@@ -212,22 +157,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.GetRandomNumber(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.GetRandomNumber(i % 5)) % m_aTracks[i].m_nLength;
+ else
+ m_aTracks[i].m_nPosition = 0;
+
m_aTracks[i].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode();
}
+ }
+}
+bool
+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_nRadioStation = HEAD_RADIO;
+ m_nRadioStation = 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;
+ field_398E = false;
+ field_398F = false;
+ m_nStreamedTrack = NO_TRACK;
+ field_3994 = false;
+ field_3995 = false;
+ field_3996 = false;
+ field_3997 = false;
+ nFramesSinceCutsceneEnded = -1;
+ field_3999 = false;
+ field_399A = false;
+ m_nMusicModeToBeSet = MUSICMODE_DISABLED;
+ field_399C = false;
+ m_nVolumeLatency = 0;
+ m_nCurrentVolume = 0;
+ m_nMaxVolume = 0;
}
return m_bIsInitialised;
}
@@ -239,72 +214,56 @@ cMusicManager::Terminate()
if (SampleManager.IsStreamPlaying(0)) {
SampleManager.StopStreamedFile(0);
- m_nCurrentStreamedSound = NO_TRACK;
- m_nPreviousStreamedSound = 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; 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(0)) {
- if (m_nCurrentStreamedSound < TOTAL_STREAMED_SOUNDS) {
- m_aTracks[m_nCurrentStreamedSound].m_nPosition = SampleManager.GetStreamedFilePosition(0);
- m_aTracks[m_nCurrentStreamedSound].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode();
- }
- SampleManager.StopStreamedFile(0);
- }
- m_nCurrentStreamedSound = NO_TRACK;
- m_nPreviousStreamedSound = 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_bDontServiceAmbienceTrack = false;
- m_nMusicMode = mode2;
- break;
- default: return;
+ if (m_bIsInitialised) {
+ if (station == USERTRACK)
+ station = RADIO_OFF;
+ if (station <= STREAMED_SOUND_RADIO_POLICE) {
+ m_bRadioSetByScript = true;
+ m_nRadioStation = station;
+ m_nRadioPosition = pos == -1 ? -1 : pos % m_aTracks[station].m_nLength;
}
}
}
-uint8
+bool
+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;
+}
+
+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;
}
}
@@ -321,9 +280,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;
@@ -331,29 +290,52 @@ cMusicManager::SetRadioInCar(uint32 station)
}
void
-cMusicManager::SetRadioChannelByScript(uint8 station, int32 pos)
+cMusicManager::RecordRadioStats()
{
- if (m_bIsInitialised && station < RADIO_OFF) {
- m_bRadioSetByScript = true;
- m_nRadioStation = station;
- m_nRadioPosition = pos == -1 ? -1 : pos % m_aTracks[station].m_nLength;
+ if (m_nPlayingTrack < STREAMED_SOUND_CITY_AMBIENT) {
+ 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_nRadioStation = 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; break;
+ case MUSICMODE_GAME: m_nUpcomingMusicMode = MUSICMODE_GAME; break;
+ case MUSICMODE_CUTSCENE:
+ m_nUpcomingMusicMode = MUSICMODE_CUTSCENE;
+ if (SampleManager.IsStreamPlaying(0)) {
+ if (m_nPlayingTrack != NO_TRACK) {
+ RecordRadioStats();
+ m_aTracks[m_nPlayingTrack].m_nPosition = SampleManager.GetStreamedFilePosition(0);
+ m_aTracks[m_nPlayingTrack].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode();
+ }
+ }
+ SampleManager.StopStreamedFile(0);
+ while (SampleManager.IsStreamPlaying(0))
+ SampleManager.StopStreamedFile(0);
+ m_nMusicMode = m_nUpcomingMusicMode;
+ field_399A = false;
+ field_398F = false;
+ m_nStreamedTrack = NO_TRACK;
+ field_3994 = false;
+ field_3995 = 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)
@@ -370,303 +352,675 @@ cMusicManager::Service()
m_nLastTrackServiceTime = m_nResetTime;
}
- if (!m_bIsInitialised || m_bDisabled) return;
-
- if (m_nMusicMode == MUSICMODE_CUTSCENE) {
- SampleManager.SetStreamedVolumeAndPan(MAX_VOLUME, 63, 1, 0);
- return;
- }
+ static bool 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_nCurrentStreamedSound == NO_TRACK && SampleManager.IsStreamPlaying(0))
- SampleManager.StopStreamedFile(0);
- else switch (m_nMusicMode) {
- case MUSICMODE_FRONTEND: ServiceFrontEndMode(); break;
- case MUSICMODE_GAME: ServiceGameMode(); break;
+ if (!field_399A)
+ 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, 1, 0); break;
+ }
+ }
+ else
+ m_nMusicMode = MUSICMODE_DISABLED;
+ } else {
+ field_399A = true;
+ if (!field_3999 && !AudioManager.m_nUserPause && AudioManager.m_nPreviousUserPause)
+ field_3999 = true;
+ if (AudioManager.m_FrameCounter % 4 == 0) {
+ gNumRetunePresses = 0;
+ gRetuneCounter = 0;
+ field_2 = false;
+ if (SampleManager.IsStreamPlaying(0)) {
+ if (m_nPlayingTrack != NO_TRACK && !bRadioStatsRecorded)
+ {
+ RecordRadioStats();
+ m_aTracks[m_nPlayingTrack].m_nPosition = SampleManager.GetStreamedFilePosition(0);
+ m_aTracks[m_nPlayingTrack].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode();
+ bRadioStatsRecorded = true;
+ }
+ SampleManager.StopStreamedFile(0);
+ } else {
+ bRadioStatsRecorded = false;
+ m_nMusicMode = m_nMusicModeToBeSet;
+ field_399A = false;
+ field_398F = false;
+ m_nStreamedTrack = NO_TRACK;
+ field_3994 = false;
+ field_3995 = false;
+ m_nPlayingTrack = NO_TRACK;
+ if (field_399C)
+ field_399C = false;
+ else
+ m_nFrontendTrack = NO_TRACK;
+ }
}
+ }
}
void
cMusicManager::ServiceFrontEndMode()
{
- if (m_nCurrentStreamedSound < TOTAL_STREAMED_SOUNDS) {
- if (m_bFrontendTrackFinished) {
- if (!SampleManager.IsStreamPlaying(0)) {
- switch (m_nCurrentStreamedSound)
- {
- case STREAMED_SOUND_MISSION_COMPLETED:
- if (!AudioManager.m_nUserPause)
- ChangeMusicMode(MUSICMODE_GAME);
- break;
- case STREAMED_SOUND_GAME_COMPLETED:
- ChangeMusicMode(MUSICMODE_GAME);
- break;
- default:
- break;
+ static bool bRadioStatsRecorded = false;
+
+ if (m_bAnnouncementInProgress) {
+ SampleManager.StopStreamedFile(0);
+ if (SampleManager.IsStreamPlaying(0))
+ return;
+ g_bAnnouncementReadPosAlready = false;
+ m_nAnnouncement = NO_TRACK;
+ m_bAnnouncementInProgress = false;
+ m_nStreamedTrack = NO_TRACK;
+ m_nFrontendTrack = NO_TRACK;
+ m_nPlayingTrack = NO_TRACK;
+ }
+
+ if (AudioManager.m_FrameCounter % 4 != 0) return;
+
+ if (!field_398F && !field_3995) {
+ m_nStreamedTrack = m_nFrontendTrack;
+ field_3994 = field_398E;
+ }
+
+ if (m_nStreamedTrack == m_nPlayingTrack) {
+ if (SampleManager.IsStreamPlaying(0)) {
+ if (m_nVolumeLatency > 0) m_nVolumeLatency--;
+ else {
+ if (m_nCurrentVolume < m_nMaxVolume)
+ m_nCurrentVolume = Min(m_nMaxVolume, m_nCurrentVolume + 6);
+ SampleManager.SetStreamedVolumeAndPan(m_nCurrentVolume, 63u, 0, 0);
+ }
+ } else {
+ if (m_nPlayingTrack == STREAMED_SOUND_RADIO_MP3_PLAYER)
+ SampleManager.StartStreamedFile(STREAMED_SOUND_RADIO_MP3_PLAYER, 0, 0);
+ else if (m_nPlayingTrack == STREAMED_SOUND_MISSION_COMPLETED && AudioManager.m_nUserPause == 0)
+ ChangeMusicMode(MUSICMODE_GAME);
+ }
+ } else {
+ field_398F = true;
+ if (field_3995 || !SampleManager.IsStreamPlaying(0)) {
+ bRadioStatsRecorded = false;
+ if (SampleManager.IsStreamPlaying(0) || m_nStreamedTrack == NO_TRACK) {
+ m_nPlayingTrack = m_nStreamedTrack;
+ field_3995 = false;
+ field_398F = false;
+ } else {
+ uint32 trackStartPos = (m_nStreamedTrack > STREAMED_SOUND_RADIO_POLICE) ? 0 : GetTrackStartPos(m_nStreamedTrack);
+ if (m_nStreamedTrack != NO_TRACK) {
+ SampleManager.SetStreamedFileLoopFlag(field_3994, 0);
+ SampleManager.StartStreamedFile(m_nStreamedTrack, trackStartPos, 0);
+ m_nVolumeLatency = 3;
+ m_nCurrentVolume = 0;
+ m_nMaxVolume = 100;
+ SampleManager.SetStreamedVolumeAndPan(m_nCurrentVolume, 63, 0, 0);
+ if (m_nStreamedTrack < STREAMED_SOUND_CITY_AMBIENT)
+ m_nLastTrackServiceTime = CTimer::GetTimeInMillisecondsPauseMode();
+ field_3995 = true;
}
- m_nCurrentStreamedSound = NO_TRACK;
- m_nPreviousStreamedSound = NO_TRACK;
}
- } else if (bHasStarted) {
- if (!SampleManager.IsStreamPlaying(0))
- SampleManager.StartStreamedFile(m_nCurrentStreamedSound, 0, 0);
} else {
+ if (m_nPlayingTrack != NO_TRACK && !bRadioStatsRecorded) {
+ m_aTracks[m_nPlayingTrack].m_nPosition = SampleManager.GetStreamedFilePosition(0);
+ m_aTracks[m_nPlayingTrack].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode();
+ RecordRadioStats();
+ bRadioStatsRecorded = true;
+ }
SampleManager.SetStreamedVolumeAndPan(0, 63, 0, 0);
- if (!SampleManager.StartStreamedFile(m_nCurrentStreamedSound, m_nCurrentStreamedSound < STREAMED_SOUND_RADIO_POLICE ? GetTrackStartPos(m_nCurrentStreamedSound) : 0, 0))
- return;
- SampleManager.SetStreamedVolumeAndPan(100, 63, 0, 0);
- if (m_bPlayInFrontend) bHasStarted = true;
- else m_bFrontendTrackFinished = true;
+ SampleManager.StopStreamedFile(0);
}
}
- if (SampleManager.IsStreamPlaying(0))
- SampleManager.SetStreamedVolumeAndPan((CPad::GetPad(0)->bDisplayNoControllerMessage || CPad::GetPad(0)->bObsoleteControllerMessage) ? 0 : 100, 63, 0, 0);
}
void
cMusicManager::ServiceGameMode()
{
- bool bRadioOff = false;
- static int8 nFramesSinceCutsceneEnded = -1;
- uint8 volume;
+ CPed *ped = FindPlayerPed();
+ CVehicle *vehicle = AudioManager.FindVehicleOfPlayer();
+ field_3997 = field_3996;
+ field_3996 = false;
+
+ 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:
+ field_3996 = false;
+ break;
+ default:
+ if (SampleManager.GetMusicVolume()) {
+ if (PlayerInCar())
+ field_3996 = true;
+ } else
+ field_3996 = false;
+ break;
+ }
- m_bPreviousPlayerInCar = m_bPlayerInCar;
- m_bPlayerInCar = PlayerInCar();
- m_nPreviousStreamedSound = m_nCurrentStreamedSound;
- if (m_bPlayerInCar) {
- if (FindPlayerPed() != nil
- && !FindPlayerPed()->DyingOrDead()
- && CPad::GetPad(0)->ChangeStationJustDown()
- && !CReplay::IsPlayingBack()
- && FindPlayerVehicle() != nil
- && !UsesPoliceRadio(FindPlayerVehicle())) {
- gRetuneCounter = 30;
- gNumRetunePresses++;
- AudioManager.PlayOneShot(AudioManager.m_nFrontEndEntity, SOUND_FRONTEND_RADIO_CHANGE, 1.0f);
- if (SampleManager.IsMP3RadioChannelAvailable()) {
- if (gNumRetunePresses > RADIO_OFF)
- gNumRetunePresses -= RADIO_OFF;
+ if (!field_3996) {
+ nFramesSinceCutsceneEnded = -1;
+ gNumRetunePresses = 0;
+ gRetuneCounter = 0;
+ field_2 = false;
+ } else if (ped) {
+ if (ped->m_objective != OBJECTIVE_WAIT_ON_FOOT_AT_ICE_CREAM_VAN && ped->m_objective != OBJ_55) {
+#ifdef GTA_PC
+ if (SampleManager.IsMP3RadioChannelAvailable()
+ && vehicle->m_nRadioStation < USERTRACK
+ && ControlsManager.GetIsKeyboardKeyJustDown(rsF9)
+ && vehicle)
+ {
+ 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() && vehicle)
+ {
+ if (!UsesPoliceRadio(vehicle) && !UsesTaxiRadio(vehicle)) {
+ gNumRetunePresses++;
+ gRetuneCounter = 20;
+ RadioStaticCounter = 0;
}
+ }
+
}
- } else {
- nFramesSinceCutsceneEnded = -1;
}
- if (AudioManager.m_nPreviousUserPause)
- m_bPreviousPlayerInCar = false;
- if (!m_bPlayerInCar) {
- if (m_bPreviousPlayerInCar) {
- if (m_nCurrentStreamedSound != STREAMED_SOUND_RADIO_POLICE)
- m_nRadioInCar = m_nCurrentStreamedSound;
- }
- ServiceAmbience();
- return;
+ if (field_3999)
+ {
+ field_3997 = false;
+ field_3999 = false;
}
+ if (m_nPlayingTrack == NO_TRACK && m_nFrontendTrack == NO_TRACK)
+ field_3997 = false;
- if (m_bPreviousPlayerInCar) {
- if (m_nAnnouncement < TOTAL_STREAMED_SOUNDS
- && (m_nCurrentStreamedSound < STREAMED_SOUND_CITY_AMBIENT || m_bAnnouncementInProgress)
- && ServiceAnnouncement())
+ if (field_3996)
+ {
+ if (field_3997)
{
- if (m_bAnnouncementInProgress) {
- m_bSetNextStation = false;
- return;
+ if (m_nAnnouncement < NO_TRACK) {
+ if ((m_bAnnouncementInProgress || m_nFrontendTrack == m_nPlayingTrack) && ServiceAnnouncement()) {
+ if (m_bAnnouncementInProgress) {
+ field_2 = false;
+ gNumRetunePresses = 0;
+ gRetuneCounter = 0;
+ return;
+ }
+ if (m_nAnnouncement == NO_TRACK)
+ {
+ m_nFrontendTrack = GetCarTuning();
+ field_2 = false;
+ gRetuneCounter = 0;
+ gNumRetunePresses = 0;
+ }
+ }
}
- m_nPreviousStreamedSound = m_nCurrentStreamedSound;
- m_nCurrentStreamedSound = GetCarTuning();
- }
- if (SampleManager.IsMP3RadioChannelAvailable()
- && m_nCurrentStreamedSound != STREAMED_SOUND_RADIO_MP3_PLAYER
- && ControlsManager.GetIsKeyboardKeyJustDown(rsF9))
- {
- m_nPreviousStreamedSound = m_nCurrentStreamedSound;
- m_nCurrentStreamedSound = 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;
- }
- if (gNumRetunePresses) {
- if (gRetuneCounter != 0) gRetuneCounter--;
- else m_bSetNextStation = true;
- }
- if (gRetuneCounter)
- AudioManager.DoPoliceRadioCrackle();
- if (m_bSetNextStation) {
- m_bSetNextStation = false;
- m_nPreviousStreamedSound = m_nCurrentStreamedSound;
- m_nCurrentStreamedSound = GetNextCarTuning();
- if (m_nCurrentStreamedSound == STREAMED_SOUND_CITY_AMBIENT || m_nCurrentStreamedSound == STREAMED_SOUND_WATER_AMBIENT)
- bRadioOff = true;
-
- if (m_nPreviousStreamedSound == STREAMED_SOUND_CITY_AMBIENT || m_nPreviousStreamedSound == STREAMED_SOUND_WATER_AMBIENT)
- AudioManager.PlayOneShot(AudioManager.m_nFrontEndEntity, SOUND_FRONTEND_RADIO_CHANGE, 0.0f);
- }
- if (m_nCurrentStreamedSound < STREAMED_SOUND_CITY_AMBIENT) {
- if (ChangeRadioChannel()) {
- ServiceTrack();
- } else {
- m_bPlayerInCar = false;
- if (FindPlayerVehicle())
- FindPlayerVehicle()->m_nRadioStation = m_nCurrentStreamedSound;
- m_nCurrentStreamedSound = NO_TRACK;
+ if (!m_bAnnouncementInProgress
+ && m_nAnnouncement == NO_TRACK
+ && m_nPlayingTrack == STREAMED_SOUND_RADIO_MP3_PLAYER
+ && !SampleManager.IsStreamPlaying(0))
+ {
+ SampleManager.StartStreamedFile(STREAMED_SOUND_RADIO_MP3_PLAYER, 0, 0);
}
- if (CTimer::GetIsSlowMotionActive()) {
- if (TheCamera.pTargetEntity != nil) {
- float DistToTargetSq = (TheCamera.pTargetEntity->GetPosition() - TheCamera.GetPosition()).MagnitudeSqr();
- if (DistToTargetSq >= SQR(55.0f)) {
- SampleManager.SetStreamedVolumeAndPan(0, 63, 0, 0);
- } 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 (!m_bRadioSetByScript)
+ {
+ if (gNumRetunePresses != 0)
+ {
+ if (--gRetuneCounter == 0)
+ {
+ field_2 = true;
+ gRetuneCounter = 0;
+ }
+ }
+ if (gRetuneCounter)
+ {
+ int32 station = gNumRetunePresses + vehicle->m_nRadioStation;
+ while (station >= RADIO_OFF) station -= RADIO_OFF;
+
+ if (!DMAudio.IsMP3RadioChannelAvailable() && station == USERTRACK)
+ {
+ ++gNumRetunePresses;
+ station = NUM_RADIOS;
+ }
+ if (station == NUM_RADIOS)
+ {
+ if (gRetuneCounter == NUM_RADIOS + 9)
+ {
+ AudioManager.PlayOneShot(AudioManager.m_nFrontEndEntity, SOUND_FRONTEND_NO_RADIO, 0.0f);
+ RadioStaticCounter = 5;
}
- if (gRetuneCounter)
- volume /= 4;
- SampleManager.SetStreamedVolumeAndPan(volume, pan, 0, 0);
- } else if (AudioManager.ShouldDuckMissionAudio()) {
- SampleManager.SetStreamedVolumeAndPan(25, 63, 0, 0);
- } else if (gRetuneCounter) {
- SampleManager.SetStreamedVolumeAndPan(25, 63, 0, 0);
- } else {
- SampleManager.SetStreamedVolumeAndPan(100, 63, 0, 0);
+ }
+ else
+ {
+ if (station == WILDSTYLE && gRetuneCounter == NUM_RADIOS + 9)
+ AudioManager.PlayOneShot(AudioManager.m_nFrontEndEntity, SOUND_FRONTEND_RADIO_CHANGE, 0.0f);
+ AudioManager.DoPoliceRadioCrackle();
}
}
- } else if (AudioManager.ShouldDuckMissionAudio()) {
- SampleManager.SetStreamedVolumeAndPan(25, 63, 0, 0);
- 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;
+ if (RadioStaticCounter < 2 && CTimer::GetTimeInMilliseconds() > RadioStaticTimer + 800)
+ {
+ AudioManager.PlayOneShot(AudioManager.m_nFrontEndEntity, SOUND_RADIO_CHANGE, 0.0f);
+ RadioStaticCounter++;
+ RadioStaticTimer = CTimer::GetTimeInMilliseconds();
}
- if (gRetuneCounter != 0)
- volume /= 4;
- SampleManager.SetStreamedVolumeAndPan(volume, 63, 0, 0);
+ if (field_2)
+ m_nFrontendTrack = GetNextCarTuning();
+ if (m_nFrontendTrack >= STREAMED_SOUND_CITY_AMBIENT && m_nFrontendTrack <= STREAMED_SOUND_AMBSIL_AMBIENT)
+ SetUpCorrectAmbienceTrack();
+ ServiceTrack(vehicle, ped);
+ if (field_2)
+ field_2 = false;
+ return;
+ }
+ if (UsesPoliceRadio(vehicle))
+ m_nFrontendTrack = STREAMED_SOUND_RADIO_POLICE;
+ else if (UsesTaxiRadio(vehicle))
+ m_nFrontendTrack = STREAMED_SOUND_RADIO_TAXI;
+ else {
+ m_nFrontendTrack = m_nRadioStation;
+ vehicle->m_nRadioStation = m_nRadioStation;
}
+
+ if (m_nRadioPosition != -1) {
+ m_aTracks[m_nFrontendTrack].m_nPosition = m_nRadioPosition;
+ m_aTracks[m_nFrontendTrack].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode();
+ }
+
+ gRetuneCounter = 0;
+ gNumRetunePresses = 0;
+ field_2 = false;
+ m_bRadioSetByScript = false;
+ if (m_nFrontendTrack >= STREAMED_SOUND_CITY_AMBIENT && m_nFrontendTrack <= STREAMED_SOUND_AMBSIL_AMBIENT)
+ SetUpCorrectAmbienceTrack();
+ ServiceTrack(vehicle, ped);
+ if (field_2)
+ field_2 = false;
return;
}
- if (bRadioOff) {
- m_nCurrentStreamedSound = m_nPreviousStreamedSound;
- if (FindPlayerVehicle() != nil)
- FindPlayerVehicle()->m_nRadioStation = RADIO_OFF;
- AudioManager.PlayOneShot(AudioManager.m_nFrontEndEntity, SOUND_FRONTEND_NO_RADIO, 0.0f);
+ if (vehicle == nil)
+ {
+ m_nFrontendTrack = STREAMED_SOUND_RADIO_WAVE; // huh?
+ return;
}
- ServiceAmbience();
- return;
- }
- if (m_bRadioSetByScript) {
- if (UsesPoliceRadio(FindPlayerVehicle())) {
- m_nCurrentStreamedSound = STREAMED_SOUND_RADIO_POLICE;
- } else {
- m_nCurrentStreamedSound = m_nRadioStation;
- if (FindPlayerVehicle()->m_nRadioStation == m_nCurrentStreamedSound) {
- m_nPreviousStreamedSound = NO_TRACK;
- SampleManager.SetStreamedVolumeAndPan(0, 63, 0, 0);
- SampleManager.StopStreamedFile(0);
+ 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_nRadioStation;
+ vehicle->m_nRadioStation = m_nRadioStation;
}
- if (m_nRadioPosition != -1) {
- m_aTracks[m_nCurrentStreamedSound].m_nPosition = m_nRadioPosition;
- m_aTracks[m_nCurrentStreamedSound].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode();
+ if (m_nRadioPosition != -1)
+ {
+ m_aTracks[m_nFrontendTrack].m_nPosition = m_nRadioPosition;
+ m_aTracks[m_nFrontendTrack].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode();
}
+ m_bRadioSetByScript = false;
+ return;
}
- } else {
- m_nCurrentStreamedSound = GetCarTuning();
- }
- if (m_nCurrentStreamedSound >= RADIO_OFF) {
- ServiceAmbience();
+
+ m_nFrontendTrack = GetCarTuning();
return;
}
- if (ChangeRadioChannel()) {
- if (m_bRadioSetByScript) {
- m_bRadioSetByScript = false;
- FindPlayerVehicle()->m_nRadioStation = m_nCurrentStreamedSound;
- }
- } else {
- m_bPlayerInCar = false;
- m_nCurrentStreamedSound = NO_TRACK;
+
+ if (m_bAnnouncementInProgress)
+ {
+ SampleManager.StopStreamedFile(0);
+ if (SampleManager.IsStreamPlaying(0))
+ return;
+ g_bAnnouncementReadPosAlready = false;
+ m_nAnnouncement = NO_TRACK;
+ m_bAnnouncementInProgress = false;
+ m_nStreamedTrack = NO_TRACK;
+ m_nFrontendTrack = NO_TRACK;
+ m_nPlayingTrack = NO_TRACK;
}
+ SetUpCorrectAmbienceTrack();
+ ServiceTrack(nil, ped);
}
void
-cMusicManager::StopFrontEndTrack()
+cMusicManager::SetUpCorrectAmbienceTrack()
{
- if (IsInitialised() && !m_bDisabled && m_nMusicMode == MUSICMODE_FRONTEND && m_nCurrentStreamedSound != NO_TRACK) {
- m_aTracks[m_nCurrentStreamedSound].m_nPosition = SampleManager.GetStreamedFilePosition(0);
- m_aTracks[m_nCurrentStreamedSound].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode();
- SampleManager.StopStreamedFile(0);
- m_nPreviousStreamedSound = NO_TRACK;
- m_nCurrentStreamedSound = NO_TRACK;
+ 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 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;
+ }
+}
+
+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::PlayAnnouncement(uint8 announcement)
+cMusicManager::ComputeAmbienceVol(uint8 reset, uint8& outVolume)
{
- if (IsInitialised() && !m_bDisabled && !m_bAnnouncementInProgress)
- m_nAnnouncement = announcement;
+ 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 (CWeather::OldWeatherType == WEATHER_HURRICANE || CWeather::NewWeatherType == WEATHER_HURRICANE) {
+ if (CWeather::Wind > 1.0f) {
+ outVolume = (CWeather::Wind - 1.0f) * fVol;
+ return;
+ }
+ 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;
+}
+
+bool
+cMusicManager::ServiceAnnouncement()
+{
+ if (m_bAnnouncementInProgress) {
+ if (SampleManager.IsStreamPlaying(0))
+ m_nPlayingTrack = m_nStreamedTrack;
+ else if (m_nPlayingTrack != NO_TRACK) {
+ m_nAnnouncement = NO_TRACK;
+ m_bAnnouncementInProgress = false;
+ m_nPlayingTrack = NO_TRACK;
+ }
+ return true;
+ } else if (SampleManager.IsStreamPlaying(0)) {
+ if (m_nPlayingTrack != NO_TRACK && !g_bAnnouncementReadPosAlready) {
+ RecordRadioStats();
+ m_aTracks[m_nPlayingTrack].m_nPosition = SampleManager.GetStreamedFilePosition(0);
+ g_bAnnouncementReadPosAlready = true;
+ m_aTracks[m_nPlayingTrack].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode();
+ }
+ SampleManager.StopStreamedFile(0);
+ } else {
+ g_bAnnouncementReadPosAlready = false;
+ m_nPlayingTrack = NO_TRACK;
+ m_nStreamedTrack = m_nAnnouncement;
+ SampleManager.SetStreamedFileLoopFlag(0, false);
+ SampleManager.StartStreamedFile(m_nStreamedTrack, 0, 0);
+ SampleManager.SetStreamedVolumeAndPan(MAX_VOLUME, 63, 0, 0);
+ m_bAnnouncementInProgress = true;
+ }
+
+ return true;
}
void
-cMusicManager::PlayFrontEndTrack(uint8 track, uint8 bPlayInFrontend)
-{
- if (IsInitialised() && !m_bDisabled && track < TOTAL_STREAMED_SOUNDS) {
- if (m_nMusicMode == MUSICMODE_GAME) {
- if (m_nCurrentStreamedSound != NO_TRACK) {
- if (m_bAnnouncementInProgress) {
- m_nAnnouncement = NO_TRACK;
- m_bAnnouncementInProgress = false;
- }
- m_aTracks[m_nCurrentStreamedSound].m_nPosition = SampleManager.GetStreamedFilePosition(0);
- m_aTracks[m_nCurrentStreamedSound].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode();
+cMusicManager::ServiceTrack(CVehicle *veh, CPed *ped)
+{
+ static bool bRadioStatsRecorded = false;
+ static bool bRadioStatsRecorded2 = false;
+ uint8 volume;
+ if (!field_398F)
+ m_nStreamedTrack = m_nFrontendTrack;
+ if (gRetuneCounter != 0 || field_2) {
+ if (SampleManager.IsStreamPlaying(0)) {
+ if (m_nPlayingTrack != NO_TRACK && !bRadioStatsRecorded) {
+ m_aTracks[m_nPlayingTrack].m_nPosition = SampleManager.GetStreamedFilePosition(0);
+ m_aTracks[m_nPlayingTrack].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode();
+ RecordRadioStats();
+ bRadioStatsRecorded = true;
}
+ SampleManager.SetStreamedVolumeAndPan(0, 63, 0, 0);
SampleManager.StopStreamedFile(0);
- } else if (m_nMusicMode == MUSICMODE_FRONTEND) {
- if (m_nCurrentStreamedSound != NO_TRACK) {
- m_aTracks[m_nCurrentStreamedSound].m_nPosition = SampleManager.GetStreamedFilePosition(0);
- m_aTracks[m_nCurrentStreamedSound].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode();
+ }
+ return;
+ }
+
+ if (bRadioStatsRecorded) {
+ bRadioStatsRecorded = false;
+ m_nPlayingTrack = NO_TRACK;
+ }
+
+ if (m_nStreamedTrack != m_nPlayingTrack)
+ {
+ field_398F = true;
+ SampleManager.SetStreamedVolumeAndPan(0, 63, 0, 0);
+ if (!(AudioManager.m_FrameCounter & 1)) {
+ if (field_3995 || !SampleManager.IsStreamPlaying(0)) {
+ bRadioStatsRecorded2 = false;
+ if (SampleManager.IsStreamPlaying(0)) {
+ m_nPlayingTrack = m_nStreamedTrack;
+ field_3995 = false;
+ field_398F = false;
+ if (veh) {
+ if (veh->m_nRadioStation < STREAMED_SOUND_CITY_AMBIENT || veh->m_nRadioStation > STREAMED_SOUND_AMBSIL_AMBIENT)
+ veh->m_nRadioStation = m_nPlayingTrack;
+ else
+ veh->m_nRadioStation = STREAMED_SOUND_CITY_AMBIENT;
+ }
+ } else {
+ uint32 pos = GetTrackStartPos(m_nStreamedTrack);
+ if (m_nStreamedTrack != NO_TRACK) {
+ SampleManager.SetStreamedFileLoopFlag(1, 0);
+ SampleManager.StartStreamedFile(m_nStreamedTrack, pos, 0);
+ 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, 0, 0);
+ }
+ else
+ {
+ ComputeAmbienceVol(true, volume);
+ SampleManager.SetStreamedVolumeAndPan(volume, 63, 1, 0);
+ }
+ if (m_nStreamedTrack < STREAMED_SOUND_CITY_AMBIENT)
+ m_nLastTrackServiceTime = CTimer::GetTimeInMillisecondsPauseMode();
+ field_3995 = 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(0);
+ 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_nStreamedTrack >= STREAMED_SOUND_HAVANA_CITY_AMBIENT && m_nStreamedTrack <= STREAMED_SOUND_HAVANA_BEACH_AMBIENT)
+ AudioManager.PlayOneShot(AudioManager.m_nFrontEndEntity, SOUND_FRONTEND_RADIO_CHANGE_2, 0.0);
+ }
+ }
+ SampleManager.SetStreamedVolumeAndPan(0, 63, 0, 0);
+ SampleManager.StopStreamedFile(0);
}
- SampleManager.StopStreamedFile(0);
}
+ return;
+ }
- m_nPreviousStreamedSound = m_nCurrentStreamedSound;
- m_nCurrentStreamedSound = track;
- m_bPlayInFrontend = !!bPlayInFrontend;
- m_bFrontendTrackFinished = false;
- m_bDoTrackService = true;
- bHasStarted = false;
- if (m_nCurrentStreamedSound < STREAMED_SOUND_RADIO_POLICE) {
- gRetuneCounter = 0;
- gNumRetunePresses = 0;
+ if (m_nPlayingTrack >= STREAMED_SOUND_CITY_AMBIENT && m_nPlayingTrack <= STREAMED_SOUND_AMBSIL_AMBIENT)
+ {
+ ComputeAmbienceVol(false, volume);
+ SampleManager.SetStreamedVolumeAndPan(volume, 63, 1, 0);
+ return;
+ }
+ if (CTimer::GetIsSlowMotionActive())
+ {
+ if (TheCamera.pTargetEntity)
+ {
+ float DistToTargetSq = (TheCamera.pTargetEntity->GetPosition() - TheCamera.GetPosition()).MagnitudeSqr();
+ if (DistToTargetSq >= SQR(55.0f))
+ {
+ SampleManager.SetStreamedVolumeAndPan(0, 63, 0, 0);
+ }
+ 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, 0, 0);
+ }
+ else if (AudioManager.ShouldDuckMissionAudio(0) || AudioManager.ShouldDuckMissionAudio(1))
+ SampleManager.SetStreamedVolumeAndPan(m_nCurrentVolume, 63, 0, 0);
+ else if (gRetuneCounter != 0)
+ SampleManager.SetStreamedVolumeAndPan(0, 63, 0, 0);
+ else
+ SampleManager.SetStreamedVolumeAndPan(m_nCurrentVolume, 63, 0, 0);
+ }
+ } else if (AudioManager.ShouldDuckMissionAudio(0) || AudioManager.ShouldDuckMissionAudio(1)) {
+ SampleManager.SetStreamedVolumeAndPan(Min(m_nCurrentVolume, 25), 63, 0, 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, 0, 0);
}
+ 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();
@@ -674,7 +1028,7 @@ cMusicManager::PreloadCutSceneMusic(uint8 track)
SampleManager.StopStreamedFile(0);
SampleManager.PreloadStreamedFile(track, 0);
SampleManager.SetStreamedVolumeAndPan(MAX_VOLUME, 63, 1, 0);
- m_nCurrentStreamedSound = track;
+ m_nPlayingTrack = track;
}
}
@@ -690,16 +1044,79 @@ cMusicManager::StopCutSceneMusic(void)
{
if (IsInitialised() && !m_bDisabled && m_nMusicMode == MUSICMODE_CUTSCENE) {
SampleManager.StopStreamedFile(0);
- m_nCurrentStreamedSound = NO_TRACK;
+ m_nPlayingTrack = NO_TRACK;
+ }
+}
+
+void
+cMusicManager::PlayFrontEndTrack(uint32 track, uint8 bPlayInFrontend)
+{
+ if (IsInitialised() && !m_bDisabled && track < TOTAL_STREAMED_SOUNDS && (m_nUpcomingMusicMode == MUSICMODE_FRONTEND || m_nMusicMode == MUSICMODE_FRONTEND))
+ {
+ m_nFrontendTrack = track;
+ field_398E = bPlayInFrontend;
+ if (m_nMusicMode != MUSICMODE_FRONTEND)
+ field_399C = 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) {
+ veh->m_nRadioStation += gNumRetunePresses;
+ while (veh->m_nRadioStation >= RADIO_OFF)
+ veh->m_nRadioStation -= RADIO_OFF;
+ DMAudio.IsMP3RadioChannelAvailable(); // woof, just call and do nothing =P
+ gNumRetunePresses = 0;
}
+ return veh->m_nRadioStation;
+}
+
+uint32
+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.GetRandomNumber(2) % USERTRACK;
+ return veh->m_nRadioStation;
+}
+
+float*
+cMusicManager::GetListenTimeArray()
+{
+ return aListenTimeArray;
}
uint32
-cMusicManager::GetTrackStartPos(uint8 track)
+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();
@@ -708,202 +1125,190 @@ cMusicManager::GetTrackStartPos(uint8 track)
return pos;
}
-
-bool
-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 < STREAMED_SOUND_CITY_AMBIENT)
+ 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_nCurrentStreamedSound < STREAMED_SOUND_CITY_AMBIENT) {
- if (SampleManager.IsStreamPlaying(0)) {
- m_aTracks[m_nCurrentStreamedSound].m_nPosition = SampleManager.GetStreamedFilePosition(0);
- m_aTracks[m_nCurrentStreamedSound].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode();
- SampleManager.StopStreamedFile(0);
- m_nCurrentStreamedSound = NO_TRACK;
- return;
- }
- m_nCurrentStreamedSound = STREAMED_SOUND_CITY_AMBIENT;
- }
- if (CWorld::Players[CWorld::PlayerInFocus].m_WBState != WBSTATE_PLAYING && !SampleManager.IsStreamPlaying(0)) {
- m_nCurrentStreamedSound = NO_TRACK;
- return;
+ for (int i = 1; i < NUM_RADIOS; i++) {
+ if (aListenTimeArray[i] > aListenTimeArray[favstation])
+ favstation = i;
}
- m_nPreviousStreamedSound = m_nCurrentStreamedSound;
- m_nCurrentStreamedSound = TheCamera.DistanceToWater <= 45.0f ? STREAMED_SOUND_WATER_AMBIENT : STREAMED_SOUND_CITY_AMBIENT;
-
- if (m_nCurrentStreamedSound == m_nPreviousStreamedSound) {
- ComputeAmbienceVol(false, volume);
- SampleManager.SetStreamedVolumeAndPan(volume, 63, 1, 0);
- if (m_bDontServiceAmbienceTrack) {
- if (SampleManager.IsStreamPlaying(0))
- m_bDontServiceAmbienceTrack = false;
- } else ServiceTrack();
- } else {
- if (m_nPreviousStreamedSound < TOTAL_STREAMED_SOUNDS) {
- m_aTracks[m_nPreviousStreamedSound].m_nPosition = SampleManager.GetStreamedFilePosition(0);
- m_aTracks[m_nPreviousStreamedSound].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode();
- SampleManager.StopStreamedFile(0);
- }
- uint32 pos = GetTrackStartPos(m_nCurrentStreamedSound);
- SampleManager.SetStreamedVolumeAndPan(0, 63, 1, 0);
- if (SampleManager.StartStreamedFile(m_nCurrentStreamedSound, pos, 0)) {
- ComputeAmbienceVol(true, volume);
- SampleManager.SetStreamedVolumeAndPan(volume, 63, 1, 0);
- m_bDontServiceAmbienceTrack = true;
- } else
- m_nCurrentStreamedSound = NO_TRACK;
- }
+ return favstation;
}
-void
-cMusicManager::ComputeAmbienceVol(uint8 reset, uint8 &outVolume)
+bool
+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(0))
- SampleManager.StartStreamedFile(m_nCurrentStreamedSound, 0, 0);
+ if (!IsInitialised())
+ m_aTracks[STREAMED_SOUND_MALIBU_AMBIENT].m_nPosition = 8640;
+ if (m_nStreamedTrack != 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();
}
}
-bool
-cMusicManager::ServiceAnnouncement()
+void
+cMusicManager::SetStripClubTrackPos(uint8 scriptObject)
{
- static int8 cCheck = 0;
- if (m_bAnnouncementInProgress) {
- if (!SampleManager.IsStreamPlaying(0)) {
- m_nAnnouncement = NO_TRACK;
- m_bAnnouncementInProgress = false;
+ if (!IsInitialised())
+ m_aTracks[STREAMED_SOUND_STRIPCLUB_AMBIENT].m_nPosition = 0;
+ if (m_nStreamedTrack != 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(0);
- if (SampleManager.IsStreamPlaying(0)) {
- if (m_nCurrentStreamedSound != NO_TRACK) {
- m_aTracks[m_nCurrentStreamedSound].m_nPosition = pos;
- m_aTracks[m_nCurrentStreamedSound].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode();
- SampleManager.StopStreamedFile(0);
+void
+cMusicManager::DisplayRadioStationName()
+{
+ int8 gStreamedSound;
+ static wchar *pCurrentStation = nil;
+ static uint8 cDisplay = 0;
+
+ if(!CTimer::GetIsPaused() && !TheCamera.m_WideScreenOn && PlayerInCar() &&
+ !CReplay::IsPlayingBack()) {
+ CVehicle *vehicle = AudioManager.FindVehicleOfPlayer();
+
+ if (vehicle)
+ {
+ uint8 track;
+ gStreamedSound = vehicle->m_nRadioStation;
+ if (gStreamedSound >= STREAMED_SOUND_CITY_AMBIENT && gStreamedSound <= STREAMED_SOUND_AMBSIL_AMBIENT)
+ gStreamedSound = STREAMED_SOUND_CITY_AMBIENT;
+ if (gNumRetunePresses != 0)
+ {
+ track = gNumRetunePresses + gStreamedSound;
+ while (track >= RADIO_OFF) track -= RADIO_OFF;
+ if (!DMAudio.IsMP3RadioChannelAvailable() && track == USERTRACK)
+ gNumRetunePresses++;
}
- }
+ else
+ track = m_nFrontendTrack;
+
+
+ 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;
+ default: return;
+ };
- SampleManager.SetStreamedVolumeAndPan(0, 63, 0, 0);
- if (SampleManager.StartStreamedFile(m_nAnnouncement, 0, 0)) {
- SampleManager.SetStreamedVolumeAndPan(AudioManager.ShouldDuckMissionAudio() ? 25 : 100, 63, 0, 0);
- m_bAnnouncementInProgress = true;
- m_nPreviousStreamedSound = m_nCurrentStreamedSound;
- m_nCurrentStreamedSound = m_nAnnouncement;
- return true;
+ if (pCurrentStation != string) {
+ pCurrentStation = string;
+ cDisplay = 60;
+ }
+ else {
+ if (cDisplay == 0) return;
+ cDisplay--;
+ }
+
+ 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();
}
+ }
+}
- if (cCheck != 0) cCheck--;
- else cCheck = 30;
+bool
+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()
+bool
+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.GetRandomNumber(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) {
- if (SampleManager.IsMP3RadioChannelAvailable()) {
- if (veh->m_nRadioStation == RADIO_OFF)
- veh->m_nRadioStation = POLICE_RADIO;
- veh->m_nRadioStation += gNumRetunePresses;
- if (veh->m_nRadioStation == POLICE_RADIO)
- veh->m_nRadioStation = RADIO_OFF;
- else if (veh->m_nRadioStation > POLICE_RADIO)
- veh->m_nRadioStation -= RADIO_OFF;
- } 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;
}
bool
cMusicManager::ChangeRadioChannel()
{
- if (m_nCurrentStreamedSound != m_nPreviousStreamedSound) {
- if (m_nPreviousStreamedSound < TOTAL_STREAMED_SOUNDS) {
- m_aTracks[m_nPreviousStreamedSound].m_nPosition = SampleManager.GetStreamedFilePosition(0);
- m_aTracks[m_nPreviousStreamedSound].m_nLastPosCheckTimer = CTimer::GetTimeInMillisecondsPauseMode();
- SampleManager.SetStreamedVolumeAndPan(0, 63, 0, 0);
- SampleManager.StopStreamedFile(0);
- }
- if (SampleManager.IsStreamPlaying(0))
- return false;
- if (!SampleManager.StartStreamedFile(m_nCurrentStreamedSound, GetTrackStartPos(m_nCurrentStreamedSound), 0))
- return false;
- SampleManager.SetStreamedVolumeAndPan(AudioManager.ShouldDuckMissionAudio() ? 25 : 100, 63, 0, 0);
- }
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 e8b94da6..f103e84e 100644
--- a/src/audio/MusicManager.h
+++ b/src/audio/MusicManager.h
@@ -11,41 +11,53 @@ public:
};
class CVehicle;
+class CPed;
class cMusicManager
{
public:
bool m_bIsInitialised;
bool m_bDisabled;
- uint8 m_nMusicMode;
- uint8 m_nCurrentStreamedSound;
- uint8 m_nPreviousStreamedSound;
- bool m_bFrontendTrackFinished;
- bool m_bPlayInFrontend;
- bool m_bSetNextStation;
- uint8 m_nAnnouncement;
- bool m_bPreviousPlayerInCar;
- bool m_bPlayerInCar;
+ bool field_2;
+ uint8 m_nVolumeLatency;
+ uint8 m_nCurrentVolume;
+ uint8 m_nMaxVolume;
+ uint32 m_nAnnouncement;
bool m_bAnnouncementInProgress;
tStreamedSample m_aTracks[TOTAL_STREAMED_SOUNDS];
bool m_bResetTimers;
uint32 m_nResetTime;
- uint32 m_nLastTrackServiceTime;
- uint32 m_nTimer;
- bool m_bDoTrackService;
- bool m_bIgnoreTimeDelay;
- bool m_bDontServiceAmbienceTrack;
bool m_bRadioSetByScript;
uint8 m_nRadioStation;
- int32 m_nRadioPosition;
- uint8 m_nRadioInCar;
+ uint32 m_nRadioPosition;
+ uint32 m_nRadioInCar;
+ uint32 m_nFrontendTrack;
+ uint32 m_nPlayingTrack;
+ uint8 m_nUpcomingMusicMode;
+ uint8 m_nMusicMode;
+ bool field_398E;
+ bool field_398F;
+ uint32 m_nStreamedTrack;
+ bool field_3994;
+ bool field_3995;
+ bool field_3996;
+ bool field_3997;
+ int8 nFramesSinceCutsceneEnded;
+ bool field_3999;
+ bool field_399A;
+ uint8 m_nMusicModeToBeSet;
+ bool field_399C;
+ float aListenTimeArray[NUM_RADIOS];
+ float m_nLastTrackServiceTime;
public:
cMusicManager();
bool IsInitialised() { return m_bIsInitialised; }
- uint32 GetMusicMode() { return m_nMusicMode; }
- uint8 GetCurrentTrack() { return m_nCurrentStreamedSound; }
+ uint8 GetMusicMode() { return m_nMusicMode; }
+ uint32 GetCurrentTrack() { return m_nPlayingTrack; }
+ void ResetMusicAfterReload();
+ void SetStartingTrackPositions(uint8 isNewGameTimer);
bool Initialise();
void Terminate();
@@ -55,35 +67,47 @@ public:
bool PlayerInCar();
void DisplayRadioStationName();
- void PlayAnnouncement(uint8);
- void PlayFrontEndTrack(uint8, uint8);
- void PreloadCutSceneMusic(uint8);
+ void PlayAnnouncement(uint32);
+ void PlayFrontEndTrack(uint32, uint8);
+ 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);
bool UsesPoliceRadio(CVehicle *veh);
- uint32 GetTrackStartPos(uint8);
+ bool UsesTaxiRadio(CVehicle *veh);
+ uint32 GetTrackStartPos(uint32 track);
void ComputeAmbienceVol(uint8 reset, uint8& outVolume);
bool ServiceAnnouncement();
- uint8 GetCarTuning();
- uint8 GetNextCarTuning();
+ uint32 GetCarTuning();
+ uint32 GetNextCarTuning();
bool ChangeRadioChannel();
+ void RecordRadioStats();
+ void SetUpCorrectAmbienceTrack();
+ float *GetListenTimeArray();
+ uint32 GetRadioPosition(uint32 station);
+ uint32 GetFavouriteRadioStation();
+ void SetMalibuClubTrackPos(uint8 pos);
+ void SetStripClubTrackPos(uint8 pos);
+ bool CheckForMusicInterruptions();
+
+ void Enable();
+ void Disable();
};
VALIDATE_SIZE(cMusicManager, 0x95C);
extern cMusicManager MusicManager;
+extern bool g_bAnnouncementReadPosAlready; // we have a symbol of this so it was declared in .h
+float GetHeightScale();
diff --git a/src/audio/PoliceRadio.cpp b/src/audio/PoliceRadio.cpp
index 665494a3..781040d6 100644
--- a/src/audio/PoliceRadio.cpp
+++ b/src/audio/PoliceRadio.cpp
@@ -24,8 +24,6 @@ struct tPoliceRadioZone {
};
tPoliceRadioZone ZoneSfx[NUMAUDIOZONES];
-char SubZo2Label[8];
-char SubZo3Label[8];
int32 g_nMissionAudioSfx = TOTAL_AUDIO_SAMPLES;
int8 g_nMissionAudioPlayingStatus = 2;
@@ -42,46 +40,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_STRAFISH_ISLAND);
+ SETZONESFX(8, "DOCKS", SFX_POLICE_RADIO_VICE_PORT);
+ 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
@@ -160,14 +134,17 @@ cAudioManager::ServicePoliceRadio()
if(CReplay::IsPlayingBack() || !FindPlayerPed() || !FindPlayerPed()->m_pWanted)
return;
#endif
- wantedLevel = FindPlayerPed()->m_pWanted->m_nWantedLevel;
- if(!crimeReport) {
- if(wantedLevel != 0) {
- if(nLastSeen != 0) {
- --nLastSeen;
- } else {
- nLastSeen = m_anRandomTable[1] % 1000 + 2000;
- SetupSuspectLastSeenReport();
+ CPlayerPed *playerPed = FindPlayerPed();
+ if (playerPed) {
+ wantedLevel = playerPed->m_pWanted->m_nWantedLevel;
+ if (!crimeReport) {
+ if (wantedLevel != 0) {
+ if (nLastSeen != 0)
+ --nLastSeen;
+ else {
+ nLastSeen = m_anRandomTable[1] % 1000 + 2000;
+ SetupSuspectLastSeenReport();
+ }
}
}
}
@@ -185,18 +162,18 @@ cAudioManager::ServicePoliceRadioChannel(uint8 wantedLevel)
static int cWait = 0;
static bool 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(policeChannel)) SampleManager.StopChannel(policeChannel);
- if (g_nMissionAudioSfx != TOTAL_AUDIO_SAMPLES && bMissionAudioPhysicalPlayingStatus == 1 &&
+ if (g_nMissionAudioSfx != NO_SAMPLE && bMissionAudioPhysicalPlayingStatus == 1 &&
SampleManager.IsStreamPlaying(1)) {
SampleManager.PauseStream(1, 1);
}
} else {
- if (m_nPreviousUserPause && g_nMissionAudioSfx != TOTAL_AUDIO_SAMPLES &&
+ if (m_nPreviousUserPause && g_nMissionAudioSfx != NO_SAMPLE &&
bMissionAudioPhysicalPlayingStatus == 1) {
SampleManager.PauseStream(0, 1);
}
@@ -205,7 +182,7 @@ cAudioManager::ServicePoliceRadioChannel(uint8 wantedLevel)
--cWait;
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)) {
@@ -217,7 +194,7 @@ cAudioManager::ServicePoliceRadioChannel(uint8 wantedLevel)
} else {
bMissionAudioPhysicalPlayingStatus = 2;
g_nMissionAudioPlayingStatus = 2;
- g_nMissionAudioSfx = TOTAL_AUDIO_SAMPLES;
+ g_nMissionAudioSfx = NO_SAMPLE;
cWait = 30;
}
return;
@@ -232,31 +209,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(policeChannel) && 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(policeChannel, sample, 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;
@@ -309,49 +284,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;
}
}
@@ -373,161 +353,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;
@@ -538,142 +462,193 @@ 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_2_DOOR;
+ 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);
}
}
}
-
-
void
cAudioManager::ReportCrime(eCrimeType type, const CVector &pos)
{
@@ -681,15 +656,14 @@ cAudioManager::ReportCrime(eCrimeType type, const CVector &pos)
if (m_bIsInitialised && MusicManager.m_nMusicMode != MUSICMODE_CUTSCENE && FindPlayerPed()->m_pWanted->m_nWantedLevel > 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)) {
@@ -725,41 +699,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;
}
@@ -773,7 +740,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/PoliceRadio.h b/src/audio/PoliceRadio.h
index c01f21ce..e9a0fde0 100644
--- a/src/audio/PoliceRadio.h
+++ b/src/audio/PoliceRadio.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 8c6d35aa..91fcec49 100644
--- a/src/audio/audio_enums.h
+++ b/src/audio/audio_enums.h
@@ -2,17 +2,19 @@
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,
+ NUM_RADIOS = 10,
+ POLICE_RADIO = 10,
+ //TAXI_RADIO,
RADIO_OFF,
};
@@ -25,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,
};
@@ -241,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,
};
diff --git a/src/audio/oal/stream.cpp b/src/audio/oal/stream.cpp
index 90e90dd8..3a1f748f 100644
--- a/src/audio/oal/stream.cpp
+++ b/src/audio/oal/stream.cpp
@@ -87,10 +87,17 @@ public:
class CMP3File : public IDecoder
{
+protected:
mpg123_handle *m_pMH;
bool m_bOpened;
uint32 m_nRate;
uint32 m_nChannels;
+
+ CMP3File() :
+ m_pMH(nil),
+ m_bOpened(false),
+ m_nRate(0),
+ m_nChannels(0) {}
public:
CMP3File(const char *path) :
m_pMH(nil),
@@ -272,6 +279,51 @@ public:
};
#endif
+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 (int 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)
+ {
+ long rate = 0;
+ int channels = 0;
+ int encoding = 0;
+
+ FILE* f = fopen(path, "rb");
+
+ m_bOpened = 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);
+ }
+ }
+ }
+};
+
void CStream::Initialise()
{
#ifndef AUDIO_OPUS
@@ -319,6 +371,8 @@ CStream::CStream(char *filename, ALuint &source, ALuint (&buffers)[NUM_STREAMBUF
m_pSoundFile = new CMP3File(m_aFilename);
else if (!strcasecmp(&m_aFilename[strlen(m_aFilename) - strlen(".wav")], ".wav"))
m_pSoundFile = new CSndFile(m_aFilename);
+ else if (!strcasecmp(&m_aFilename[strlen(m_aFilename) - strlen(".adf")], ".adf"))
+ m_pSoundFile = new CADFFile(m_aFilename);
#else
if (!strcasecmp(&m_aFilename[strlen(m_aFilename) - strlen(".opus")], ".opus"))
m_pSoundFile = new COpusFile(m_aFilename);
diff --git a/src/audio/sampman.h b/src/audio/sampman.h
index 2284d385..d3e4415f 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
@@ -105,7 +121,7 @@ enum
#define MAX2DCHANNELS 1
#define CHANNEL2D MAXCHANNELS
-#define MAX_STREAMS 2
+#define MAX_STREAMS 3
#define DIGITALRATE 32000
#define DIGITALBITS 16
@@ -117,15 +133,19 @@ class cSampleManager
{
uint8 m_nEffectsVolume;
uint8 m_nMusicVolume;
+ uint8 m_nMP3BoostVolume;
uint8 m_nEffectsFadeVolume;
uint8 m_nMusicFadeVolume;
uint8 m_nMonoMode;
- char unk;
char m_szCDRomRootPath[80];
bool 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:
@@ -145,6 +165,8 @@ public:
int8 GetCurrent3DProviderIndex(void);
int8 SetCurrent3DProvider(uint8 which);
+
+ int8 AutoDetect3DProviders();
bool IsMP3RadioChannelAvailable(void);
@@ -161,6 +183,7 @@ public:
void SetEffectsMasterVolume(uint8 nVolume);
void SetMusicMasterVolume (uint8 nVolume);
+ void SetMP3BoostVolume (uint8 nVolume);
void SetEffectsFadeVolume (uint8 nVolume);
void SetMusicFadeVolume (uint8 nVolume);
void SetMonoMode (uint8 nMode);
@@ -196,10 +219,10 @@ public:
void StartChannel (uint32 nChannel);
void StopChannel (uint32 nChannel);
- void PreloadStreamedFile (uint8 nFile, uint8 nStream);
+ void PreloadStreamedFile (uint32 nFile, uint8 nStream);
void PauseStream (uint8 nPauseFlag, uint8 nStream);
void StartPreloadedStreamedFile (uint8 nStream);
- bool StartStreamedFile (uint8 nFile, uint32 nPos, uint8 nStream);
+ bool StartStreamedFile (uint32 nFile, uint32 nPos, uint8 nStream);
void StopStreamedFile (uint8 nStream);
int32 GetStreamedFilePosition (uint8 nStream);
void SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, uint8 nEffectFlag, uint8 nStream);
@@ -209,15 +232,14 @@ public:
void Service(void);
#endif
bool InitialiseSampleBanks(void);
+
+ uint8 GetMusicVolume() const { return m_nMusicVolume; }
+ void SetStreamedFileLoopFlag(uint8 nLoopFlag, uint8 nStream);
};
extern cSampleManager SampleManager;
extern uint32 BankStartOffset[MAX_SFX_BANKS];
-#ifdef AUDIO_OAL
-extern int defaultProvider;
-#endif
-
#ifdef AUDIO_OPUS
static char StreamedNameTable[][25] = {
"AUDIO\\HEAD.OPUS", "AUDIO\\CLASS.OPUS", "AUDIO\\KJAH.OPUS", "AUDIO\\RISE.OPUS", "AUDIO\\LIPS.OPUS", "AUDIO\\GAME.OPUS",
@@ -254,301 +276,1339 @@ static char StreamedNameTable[][25] = {
"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
-static char StreamedNameTable[][25]=
-{
#ifdef PS2_AUDIO
- "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",
+static char StreamedNameTable[][40] =
+{
+ "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\\MISCOM.VB",
"AUDIO\\MUSIC\\MISCOM.VB",
- "AUDIO\\MUSIC\\END.VB",
#else
- "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",
+static char StreamedNameTable[][25] =
+{
+ "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",
#endif
- "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\\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 \ No newline at end of file
diff --git a/src/audio/sampman_miles.cpp b/src/audio/sampman_miles.cpp
index db38da64..3fc43a6e 100644
--- a/src/audio/sampman_miles.cpp
+++ b/src/audio/sampman_miles.cpp
@@ -16,10 +16,12 @@
#include "MusicManager.h"
#include "Frontend.h"
#include "Timer.h"
-
+#include "crossplatform.h"
#pragma comment( lib, "mss32.lib" )
+// --MIAMI: file done
+
cSampleManager SampleManager;
uint32 BankStartOffset[MAX_SFX_BANKS];
///////////////////////////////////////////////////////////////
@@ -61,14 +63,10 @@ char _mp3DirectoryPath[MAX_PATH];
HSTREAM mp3Stream [MAX_STREAMS];
int8 nStreamPan [MAX_STREAMS];
int8 nStreamVolume[MAX_STREAMS];
+uint8 nStreamLoopedFlag[MAX_STREAMS];
uint32 _CurMP3Index;
int32 _CurMP3Pos;
bool _bIsMp3Active;
-
-#if GTA_VERSION >= GTA3_PC_11 || defined(NO_CDCHECK)
-bool _bUseHDDAudio;
-char _aHDDPath[MAX_PATH];
-#endif
///////////////////////////////////////////////////////////////
@@ -264,10 +262,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 +405,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 bool
_ResolveLink(char const *path, char *out)
{
@@ -449,15 +557,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 +566,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 +589,6 @@ _FindMP3s(void)
if ( _pMP3List == NULL )
{
FindClose(hFind);
-
- if ( f )
- fclose(f);
-
return;
}
@@ -522,9 +611,6 @@ _FindMP3s(void)
{
_pMP3List->pLinkPath = NULL;
}
-
- if ( f ) fprintf(f, " - OK\n");
-
bInitFirstEntry = false;
}
else
@@ -533,8 +619,6 @@ _FindMP3s(void)
OutputDebugString(filepath);
- if ( f ) fprintf(f, " - not an MP3 or supported MP3 type\n");
-
bInitFirstEntry = true;
}
@@ -550,8 +634,6 @@ _FindMP3s(void)
int32 filepathlen = strlen(filepath);
- if ( f ) fprintf(f, "\"%s\"", fd.cFileName);
-
if ( filepathlen > 0 )
{
if ( filepathlen > 4 )
@@ -562,12 +644,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 +654,6 @@ _FindMP3s(void)
if ( filepathlen > MAX_PATH )
{
- if ( f ) fprintf(f, " - Filename and path too long - %s - IGNORED)\n", filepath);
-
continue;
}
}
@@ -618,17 +692,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 +711,6 @@ _FindMP3s(void)
if ( filepathlen > 0 )
{
- if ( f ) fprintf(f, "\"%s\"", fd.cFileName);
-
if ( filepathlen > 4 )
{
if ( !strcmp(&filepath[filepathlen - 4], ".lnk") )
@@ -651,12 +719,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 +763,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 +984,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");
+ bool 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];
+ bool 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];
@@ -1000,93 +1035,35 @@ cSampleManager::Initialise(void)
if ( f )
{
fclose(f);
-
- bool bFileNotFound = false;
-
- for ( int32 i = 0; i < TOTAL_STREAMED_SOUNDS; i++ )
- {
- 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];
-
- bool bFileNotFound = false;
- char rootpath[MAX_PATH];
-
- strcpy(_aHDDPath, m_szCDRomRootPath);
- rootpath[0] = '\0';
-
- FILE *f = fopen(StreamedNameTable[0], "rb");
-
- if ( f )
- {
- fclose(f);
-
- for ( int32 i = 0; i < TOTAL_STREAMED_SOUNDS; i++ )
+ m_szCDRomRootPath[0] = '\0';
+
+ strcpy(m_WavFilesPath, m_szCDRomRootPath);
+
+#ifdef AUDIO_CACHE
+ if ( CreateCache )
+#endif
+ for ( int32 i = STREAMED_SOUND_MISSION_MOBR1; i < TOTAL_STREAMED_SOUNDS; i++ )
{
- strcpy(filepath, rootpath);
+ strcpy(filepath, m_szCDRomRootPath);
strcat(filepath, StreamedNameTable[i]);
mp3Stream[0] = AIL_open_stream(DIG, filepath, 0);
@@ -1098,39 +1075,149 @@ 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++)
+ {
+ 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++ )
+ {
+ 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++ )
@@ -1159,7 +1246,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;
@@ -1174,10 +1261,6 @@ cSampleManager::Initialise(void)
}
}
- TRACE("bank");
-
- LoadSampleBank(SFX_BANK_0);
-
// mp3
TRACE("mp3");
{
@@ -1297,60 +1380,42 @@ cSampleManager::Terminate(void)
bool
cSampleManager::CheckForAnAudioFileOnCD(void)
{
-#if GTA_VERSION < GTA3_PC_STEAM && !defined(NO_CDCHECK)
+#if !defined(NO_CDCHECK) // TODO: figure out defines
char filepath[MAX_PATH];
-#if GTA_VERSION >= GTA3_PC_11
- if (_bUseHDDAudio)
- strcpy(filepath, _aHDDPath);
- else
- strcpy(filepath, m_szCDRomRootPath);
-#else
- strcpy(filepath, m_szCDRomRootPath);
-#endif // #if GTA_VERSION >= GTA3_PC_11
+ strcpy(filepath, m_MiscomPath);
+ strcat(filepath, StreamedNameTable[STREAMED_SOUND_MISSION_COMPLETED4]);
- strcat(filepath, StreamedNameTable[AudioManager.GetRandomNumber(1) % TOTAL_STREAMED_SOUNDS]);
-
FILE *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
@@ -1403,6 +1468,12 @@ cSampleManager::SetMusicMasterVolume(uint8 nVolume)
}
void
+cSampleManager::SetMP3BoostVolume(uint8 nVolume)
+{
+ m_nMP3BoostVolume = nVolume;
+}
+
+void
cSampleManager::SetEffectsFadeVolume(uint8 nVolume)
{
m_nEffectsFadeVolume = nVolume;
@@ -1512,14 +1583,6 @@ cSampleManager::LoadPedComment(uint32 nComment)
break;
}
-
- case MUSICMODE_FRONTEND:
- {
- if ( MusicManager.GetCurrentTrack() == STREAMED_SOUND_GAME_COMPLETED )
- return false;
-
- break;
- }
}
}
@@ -1582,69 +1645,45 @@ cSampleManager::UpdateReverb(void)
if ( AudioManager.GetFrameCounter() & 15 )
return false;
-
- float y = AudioManager.GetReflectionsDistance(REFLECTION_TOP) + AudioManager.GetReflectionsDistance(REFLECTION_BOTTOM);
- float x = AudioManager.GetReflectionsDistance(REFLECTION_LEFT) + AudioManager.GetReflectionsDistance(REFLECTION_RIGHT);
- float z = AudioManager.GetReflectionsDistance(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.GetReflectionsDistance(REFLECTION_CEIL_NORTH), 10.0f, 1/2.f);
+ fRatio += CALCULATE_RATIO(AudioManager.GetReflectionsDistance(REFLECTION_CEIL_SOUTH), 10.0f, 1/2.f);
+ fRatio += CALCULATE_RATIO(AudioManager.GetReflectionsDistance(REFLECTION_CEIL_WEST), 10.0f, 1/2.f);
+ fRatio += CALCULATE_RATIO(AudioManager.GetReflectionsDistance(REFLECTION_CEIL_EAST), 10.0f, 1/2.f);
+
+ fRatio += CALCULATE_RATIO((AudioManager.GetReflectionsDistance(REFLECTION_NORTH) + AudioManager.GetReflectionsDistance(REFLECTION_SOUTH)) / 2.f, 4.0f, 1/3.f);
+ fRatio += CALCULATE_RATIO((AudioManager.GetReflectionsDistance(REFLECTION_WEST) + AudioManager.GetReflectionsDistance(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;
@@ -1753,11 +1792,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.GetCurrentTrack() != STREAMED_SOUND_NEWS_INTRO
- && MusicManager.GetCurrentTrack() != 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] )
@@ -1793,8 +1832,7 @@ cSampleManager::SetChannelVolume(uint32 nChannel, uint32 nVolume)
// increase the volume for JB.MP3 and S4_BDBD.MP3
if ( MusicManager.GetMusicMode() == MUSICMODE_CUTSCENE
- && MusicManager.GetCurrentTrack() != STREAMED_SOUND_NEWS_INTRO
- && MusicManager.GetCurrentTrack() != STREAMED_SOUND_CUTSCENE_SAL4_BDBD )
+ && MusicManager.GetCurrentTrack() != STREAMED_SOUND_CUTSCENE_FINALE )
{
nChannelVolume[nChannel] >>= 2;
}
@@ -1994,7 +2032,7 @@ cSampleManager::StopChannel(uint32 nChannel)
}
void
-cSampleManager::PreloadStreamedFile(uint8 nFile, uint8 nStream)
+cSampleManager::PreloadStreamedFile(uint32 nFile, uint8 nStream)
{
if ( m_bInitialised )
{
@@ -2008,7 +2046,7 @@ cSampleManager::PreloadStreamedFile(uint8 nFile, uint8 nStream)
char filepath[MAX_PATH];
- 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);
@@ -2045,7 +2083,7 @@ cSampleManager::StartPreloadedStreamedFile(uint8 nStream)
}
bool
-cSampleManager::StartStreamedFile(uint8 nFile, uint32 nPos, uint8 nStream)
+cSampleManager::StartStreamedFile(uint32 nFile, uint32 nPos, uint8 nStream)
{
uint32 position = nPos;
char filename[MAX_PATH];
@@ -2074,14 +2112,15 @@ cSampleManager::StartStreamedFile(uint8 nFile, uint32 nPos, uint8 nStream)
if(mp3 == NULL) {
_bIsMp3Active = false;
nFile = 0;
- 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);
+ mp3Stream[nStream], nStreamLoopedFlag[nStream] ? 0 : 1);
+ nStreamLoopedFlag[nStream] = true;
AIL_set_stream_ms_position(
mp3Stream[nStream], position);
AIL_pause_stream(mp3Stream[nStream],
@@ -2123,15 +2162,14 @@ cSampleManager::StartStreamedFile(uint8 nFile, uint32 nPos, uint8 nStream)
if ( e == NULL )
{
nFile = 0;
- 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_ms_position(
- mp3Stream[nStream], position);
+ 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;
}
@@ -2169,13 +2207,14 @@ cSampleManager::StartStreamedFile(uint8 nFile, uint32 nPos, uint8 nStream)
nFile = 0;
}
- 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;
@@ -2239,11 +2278,14 @@ void
cSampleManager::SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, uint8 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;
@@ -2251,9 +2293,14 @@ cSampleManager::SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, uint8 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);
}
@@ -2331,4 +2378,12 @@ cSampleManager::InitialiseSampleBanks(void)
return true;
}
+
+void
+cSampleManager::SetStreamedFileLoopFlag(uint8 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 e44e5b57..e9a9eaa1 100644
--- a/src/audio/sampman_null.cpp
+++ b/src/audio/sampman_null.cpp
@@ -114,6 +114,11 @@ cSampleManager::SetMusicMasterVolume(uint8 nVolume)
}
void
+cSampleManager::SetMusicMasterVolume(uint8 nVolume)
+{
+}
+
+void
cSampleManager::SetEffectsFadeVolume(uint8 nVolume)
{
}
@@ -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)
}
bool
-cSampleManager::StartStreamedFile(uint8 nFile, uint32 nPos, uint8 nStream)
+cSampleManager::StartStreamedFile(uint32 nFile, uint32 nPos, uint8 nStream)
{
ASSERT( nStream < MAX_STREAMS );
@@ -365,4 +370,14 @@ cSampleManager::InitialiseSampleBanks(void)
return true;
}
+void
+cSampleManager::SetStreamedFileLoopFlag(uint8 nLoopFlag, uint8 nChannel)
+{
+}
+
+int8 cSampleManager::AutoDetect3DProviders()
+{
+ return -1;
+}
+
#endif
diff --git a/src/audio/sampman_oal.cpp b/src/audio/sampman_oal.cpp
index eec5ca5f..80f19e50 100644
--- a/src/audio/sampman_oal.cpp
+++ b/src/audio/sampman_oal.cpp
@@ -446,6 +446,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 bool
_ResolveLink(char const *path, char *out)
{
@@ -1166,6 +1191,12 @@ cSampleManager::SetMusicMasterVolume(uint8 nVolume)
}
void
+cSampleManager::SetMP3BoostVolume(uint8 nVolume)
+{
+ m_nMP3BoostVolume = nVolume;
+}
+
+void
cSampleManager::SetEffectsFadeVolume(uint8 nVolume)
{
m_nEffectsFadeVolume = nVolume;
@@ -1301,14 +1332,6 @@ cSampleManager::LoadPedComment(uint32 nComment)
break;
}
-
- case MUSICMODE_FRONTEND:
- {
- if ( MusicManager.GetCurrentTrack() == STREAMED_SOUND_GAME_COMPLETED )
- return false;
-
- break;
- }
}
}
@@ -1317,7 +1340,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;
@@ -1388,24 +1411,24 @@ bool cSampleManager::UpdateReverb(void)
if ( AudioManager.GetFrameCounter() & 15 )
return false;
-
- float y = AudioManager.GetReflectionsDistance(REFLECTION_TOP) + AudioManager.GetReflectionsDistance(REFLECTION_BOTTOM);
- float x = AudioManager.GetReflectionsDistance(REFLECTION_LEFT) + AudioManager.GetReflectionsDistance(REFLECTION_RIGHT);
- float z = AudioManager.GetReflectionsDistance(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 ZE
+
+ 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.GetReflectionsDistance(REFLECTION_CEIL_NORTH), 10.0f, 1/2.f);
+ fRatio += CALCULATE_RATIO(AudioManager.GetReflectionsDistance(REFLECTION_CEIL_SOUTH), 10.0f, 1/2.f);
+ fRatio += CALCULATE_RATIO(AudioManager.GetReflectionsDistance(REFLECTION_CEIL_WEST), 10.0f, 1/2.f);
+ fRatio += CALCULATE_RATIO(AudioManager.GetReflectionsDistance(REFLECTION_CEIL_EAST), 10.0f, 1/2.f);
+
+ fRatio += CALCULATE_RATIO((AudioManager.GetReflectionsDistance(REFLECTION_NORTH) + AudioManager.GetReflectionsDistance(REFLECTION_SOUTH)) / 2.f, 4.0f, 1/3.f);
+ fRatio += CALCULATE_RATIO((AudioManager.GetReflectionsDistance(REFLECTION_WEST) + AudioManager.GetReflectionsDistance(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;
@@ -1416,6 +1439,7 @@ bool cSampleManager::UpdateReverb(void)
if ( usingEAX3 )
#endif
{
+ fRatio = Min(fRatio * 1.67f, 1.0f);
if ( EAX3ListenerInterpolate(&StartEAX3, &FinishEAX3, fRatio, &EAX3Params, false) )
{
EAX_SetAll(&EAX3Params);
@@ -1430,16 +1454,17 @@ bool 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;
@@ -1517,10 +1542,8 @@ 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.GetCurrentTrack() != STREAMED_SOUND_NEWS_INTRO
- && MusicManager.GetCurrentTrack() != STREAMED_SOUND_CUTSCENE_SAL4_BDBD )
+ && MusicManager.GetCurrentTrack() != STREAMED_SOUND_CUTSCENE_FINALE )
{
nChannelVolume[nChannel] = vol / 4;
}
@@ -1559,14 +1582,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.GetCurrentTrack() != STREAMED_SOUND_NEWS_INTRO
- && MusicManager.GetCurrentTrack() != 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);
}
}
@@ -1632,7 +1655,7 @@ cSampleManager::StopChannel(uint32 nChannel)
}
void
-cSampleManager::PreloadStreamedFile(uint8 nFile, uint8 nStream)
+cSampleManager::PreloadStreamedFile(uint32 nFile, uint8 nStream)
{
char filename[MAX_PATH];
@@ -1690,7 +1713,7 @@ cSampleManager::StartPreloadedStreamedFile(uint8 nStream)
}
bool
-cSampleManager::StartStreamedFile(uint8 nFile, uint32 nPos, uint8 nStream)
+cSampleManager::StartStreamedFile(uint32 nFile, uint32 nPos, uint8 nStream)
{
uint32 position = nPos;
char filename[256];
@@ -1893,11 +1916,16 @@ cSampleManager::SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, uint8 nEffect
{
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;
@@ -1906,10 +1934,14 @@ cSampleManager::SetStreamedVolumeAndPan(uint8 nVolume, uint8 nPan, uint8 nEffect
if ( stream )
{
- 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);
}
@@ -2000,4 +2032,11 @@ cSampleManager::InitialiseSampleBanks(void)
return true;
}
+
+void
+cSampleManager::SetStreamedFileLoopFlag(uint8 nLoopFlag, uint8 nChannel)
+{
+ nStreamLoopedFlag[nChannel] = nLoopFlag;
+}
+
#endif
diff --git a/src/audio/soundlist.h b/src/audio/soundlist.h
index 7c3b30a7..98982f61 100644
--- a/src/audio/soundlist.h
+++ b/src/audio/soundlist.h
@@ -1,4 +1,4 @@
-#pragma once
+#pragma once
enum eSound
{
@@ -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_ATTACK,
+ SOUND_WEAPON_CHAINSAW_IDLE,
+ 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_HELI_PLAYER_FOUND,
+ SOUND_PED_MIAMIVICE_EXITING_CAR,
+ SOUND_PED_COP_HELIPILOTPHRASE,
+ SOUND_PED_PULLOUTWEAPON,
+ SOUND_PED_HELI_PLAYER_FOUND = 114,
+ SOUND_PED_VCPA_PLAYER_FOUND = 115,
+ 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_UNK_126,
+ SOUND_PED_PLAYER_AFTERSEX,
+ SOUND_PED_PLAYER_BEFORESEX,
+ SOUND_PED_COP_UNK_129, // 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_REACTION,
+ 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_149,
+ SOUND_PED_150,
SOUND_PED_EXTINGUISHING_FIRE,
SOUND_PED_WAIT_DOUBLEBACK,
+ SOUND_153,
SOUND_PED_CHAT_SEXY,
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_NO_RADIO,
+ SOUND_FRONTEND_MENU_STARTING, // same with SOUND_HUD_SOUND
+
+ // TODO(Miami): What are 170-175??
+
+ SOUND_FRONTEND_NO_RADIO = 176, // those 3 are all same sound
SOUND_FRONTEND_RADIO_CHANGE,
- SOUND_HUD,
- SOUND_AMMUNATION_WELCOME_1,
- SOUND_AMMUNATION_WELCOME_2,
- SOUND_AMMUNATION_WELCOME_3,
+ SOUND_FRONTEND_RADIO_CHANGE_2,
+ SOUND_HUD_SOUND,
+ 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 with 40
+ SOUND_187, // makes same sound with 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/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..d2e01f50 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,7 +17,7 @@ CColModel::CColModel(void)
vertices = nil;
triangles = nil;
trianglePlanes = nil;
- level = CGame::currLevel;
+ level = LEVEL_GENERIC; // generic col slot
ownsCollisionVolumes = true;
}
@@ -25,6 +27,20 @@ CColModel::~CColModel(void)
RemoveTrianglePlanes();
}
+void*
+CColModel::operator new(size_t)
+{
+ CColModel* node = CPools::GetColModelPool()->New();
+ assert(node);
+ return node;
+}
+
+void
+CColModel::operator delete(void *p, size_t)
+{
+ CPools::GetColModelPool()->Delete((CColModel*)p);
+}
+
void
CColModel::RemoveCollisionVolumes(void)
{
@@ -34,6 +50,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..cd5ae651 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);
+ void operator delete(void *p, size_t);
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..bca1e9b7
--- /dev/null
+++ b/src/collision/ColStore.cpp
@@ -0,0 +1,236 @@
+#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"
+
+CPool<ColDef,ColDef> *CColStore::ms_pColPool;
+
+void
+CColStore::Initialise(void)
+{
+ if(ms_pColPool == nil)
+ ms_pColPool = new CPool<ColDef,ColDef>(COLSTORESIZE, "CollisionFiles");
+ AddColSlot("generic"); // slot 0. not streamed
+}
+
+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) ||
+ CGeneral::faststrcmp(GetColName(i), "yacht") == 0){
+ wantThisOne = true;
+ }else{
+ for (int j = 0; j < MAX_CLEANUP; j++) {
+ CPhysical* pEntity = CTheScripts::MissionCleanup.DoesThisEntityWaitForCollision(j);
+ 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 7fb5c30b..c90390c4 100644
--- a/src/collision/Collision.cpp
+++ b/src/collision/Collision.cpp
@@ -21,7 +21,10 @@
#include "SurfaceTable.h"
#include "Lines.h"
#include "Collision.h"
-#include "Frontend.h"
+#include "Camera.h"
+#include "ColStore.h"
+
+//--MIAMI: file done
#ifdef VU_COLLISION
#include "VuCollision.h"
@@ -75,52 +78,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);
}
+//--MIAMI: unused
eLevelName
GetCollisionInSectorList(CPtrList &list)
{
@@ -137,6 +110,7 @@ GetCollisionInSectorList(CPtrList &list)
return LEVEL_GENERIC;
}
+//--MIAMI: unused
// Get a level this sector is in based on collision models
eLevelName
GetCollisionInSector(CSector &sect)
@@ -160,155 +134,13 @@ 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
@@ -332,14 +164,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 +183,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 +268,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;
@@ -628,6 +460,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();
@@ -656,7 +490,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;
@@ -737,12 +571,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;
}
@@ -750,6 +586,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;
}
@@ -758,6 +595,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
@@ -1038,6 +876,7 @@ CCollision::ProcessLineSphere(const CColLine &line, const CColSphere &sphere, CC
return true;
}
+//--MIAMI: unused
bool
CCollision::ProcessVerticalLineTriangle(const CColLine &line,
const CompressedVector *verts, const CColTriangle &tri, const CColTrianglePlane &plane,
@@ -1254,7 +1093,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
@@ -1349,6 +1188,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
@@ -1419,6 +1264,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;
@@ -1465,7 +1312,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;
@@ -1569,17 +1416,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);
}
@@ -1596,7 +1446,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;
@@ -1723,28 +1573,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){
@@ -2302,6 +2151,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;
@@ -2523,15 +2381,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;
@@ -2550,53 +2468,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();
@@ -2637,47 +2510,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 dabb6ebb..f8b26450 100644
--- a/src/collision/TempColModels.cpp
+++ b/src/collision/TempColModels.cpp
@@ -15,6 +15,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];
@@ -292,5 +293,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 3e1dd5e1..0c936d6f 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 4038c93e..a899518b 100644
--- a/src/control/AutoPilot.cpp
+++ b/src/control/AutoPilot.cpp
@@ -6,6 +6,8 @@
#include "Curves.h"
#include "PathFind.h"
+//--MIAMI: file done
+
void CAutoPilot::ModifySpeed(float speed)
{
m_fMaxTrafficSpeed = Max(0.01f, speed);
@@ -70,6 +72,9 @@ void CAutoPilot::Save(uint8*& buf)
WriteSaveBuf<uint32>(buf, m_nTimeTempAction);
WriteSaveBuf<float>(buf, m_fMaxTrafficSpeed);
WriteSaveBuf<uint8>(buf, m_nCruiseSpeed);
+ WriteSaveBuf<uint8>(buf, m_nCruiseSpeedMultiplierType);
+ SkipSaveBuf(buf, 2);
+ WriteSaveBuf<float>(buf, m_fCruiseSpeedMultiplier);
uint8 flags = 0;
if (m_bSlowedDownBecauseOfCars) flags |= BIT(0);
if (m_bSlowedDownBecauseOfPeds) flags |= BIT(1);
@@ -77,6 +82,7 @@ void CAutoPilot::Save(uint8*& buf)
if (m_bStayInFastLane) flags |= BIT(3);
if (m_bIgnorePathfinding) flags |= BIT(4);
WriteSaveBuf<uint8>(buf, flags);
+ WriteSaveBuf<uint8>(buf, m_nSwitchDistance);
SkipSaveBuf(buf, 2);
WriteSaveBuf<float>(buf, m_vecDestinationCoors.x);
WriteSaveBuf<float>(buf, m_vecDestinationCoors.y);
@@ -109,12 +115,16 @@ void CAutoPilot::Load(uint8*& buf)
m_nTimeTempAction = ReadSaveBuf<uint32>(buf);
m_fMaxTrafficSpeed = ReadSaveBuf<float>(buf);
m_nCruiseSpeed = ReadSaveBuf<uint8>(buf);
+ m_nCruiseSpeedMultiplierType = ReadSaveBuf<uint8>(buf);
+ SkipSaveBuf(buf, 2);
+ m_fCruiseSpeedMultiplier = ReadSaveBuf<float>(buf);
uint8 flags = ReadSaveBuf<uint8>(buf);
m_bSlowedDownBecauseOfCars = !!(flags & BIT(0));
m_bSlowedDownBecauseOfPeds = !!(flags & BIT(1));
m_bStayInCurrentLevel = !!(flags & BIT(2));
m_bStayInFastLane = !!(flags & BIT(3));
m_bIgnorePathfinding = !!(flags & BIT(4));
+ m_nSwitchDistance = ReadSaveBuf<uint8>(buf);
SkipSaveBuf(buf, 2);
m_vecDestinationCoors.x = ReadSaveBuf<float>(buf);
m_vecDestinationCoors.y = ReadSaveBuf<float>(buf);
diff --git a/src/control/AutoPilot.h b/src/control/AutoPilot.h
index 6349fce6..aa14ccdd 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..1a1c03bd 100644
--- a/src/control/Bridge.cpp
+++ b/src/control/Bridge.cpp
@@ -6,6 +6,8 @@
#include "PathFind.h"
#include "Stats.h"
+//--MIAMI: file done
+
CEntity *CBridge::pLiftRoad;
CEntity *CBridge::pLiftPart;
CEntity *CBridge::pWeight;
@@ -23,6 +25,7 @@ uint32 CBridge::TimeOfBridgeBecomingOperational;
void CBridge::Init()
{
+#ifdef GTA_BRIDGE
FindBridgeEntities();
OldLift = -1.0f;
if (pLiftPart && pWeight)
@@ -35,10 +38,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 +118,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 +149,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 8c0c5966..e7f3a546 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"
@@ -21,9 +22,11 @@
#define DISTANCE_TO_SWITCH_DISTANCE_GOTO 20.0f
+//--MIAMI: file done
+
float CCarAI::FindSwitchDistanceClose(CVehicle* pVehicle)
{
- return 30.0f;
+ return pVehicle->AutoPilot.m_nSwitchDistance;
}
float CCarAI::FindSwitchDistanceFarNormalVehicle(CVehicle* pVehicle)
@@ -38,6 +41,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->m_nWantedLevel == 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 +80,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->m_nWantedLevel == 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 +128,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->m_nWantedLevel == 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->m_nWantedLevel == 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 +153,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 +169,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->m_nWantedLevel == 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 +183,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 +236,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 +246,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 +269,10 @@ void CCarAI::UpdateCarAI(CVehicle* pVehicle)
break;
case MISSION_RAMCAR_CLOSE:
if (pVehicle->AutoPilot.m_pTargetCar){
- if
-#ifdef FIX_BUGS
- (FindPlayerVehicle() == pVehicle->AutoPilot.m_pTargetCar &&
+#ifdef FIX_BUGS // btw fixed in SA
+ if (FindPlayerVehicle() == pVehicle->AutoPilot.m_pTargetCar)
#endif
- (FindPlayerPed()->m_pWanted->m_bIgnoredByEveryone || pVehicle->bIsLawEnforcer &&
- (FindPlayerPed()->m_pWanted->m_nWantedLevel == 0 || FindPlayerPed()->m_pWanted->m_bIgnoredByCops || CCullZones::NoPolice()))
-#ifdef FIX_BUGS
- )
-#endif
- {
- CCarCtrl::JoinCarWithRoadSystem(pVehicle);
- pVehicle->AutoPilot.m_nCarMission = MISSION_CRUISE;
- pVehicle->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_STOP_FOR_CARS;
- pVehicle->m_bSirenOrAlarm = false;
- if (CCullZones::NoPolice())
- pVehicle->AutoPilot.m_nCarMission = MISSION_NONE;
- }
+ BackToCruisingIfNoWantedLevel(pVehicle);
if ((pVehicle->AutoPilot.m_pTargetCar->GetPosition() - pVehicle->GetPosition()).Magnitude2D() <= FindSwitchDistanceFar(pVehicle) ||
pVehicle->AutoPilot.m_bIgnorePathfinding){
if (pVehicle->GetHasCollidedWith(pVehicle->AutoPilot.m_pTargetCar)){
@@ -316,7 +294,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 +314,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->m_nWantedLevel == 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->m_nWantedLevel > 0 && !CCullZones::NoPolice()){
if (ABS(FindPlayerCoors().x - pVehicle->GetPosition().x) > 10.0f ||
@@ -343,7 +356,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 +377,11 @@ void CCarAI::UpdateCarAI(CVehicle* pVehicle)
pVehicle->AutoPilot.m_nCruiseSpeed = 0;
break;
}
+ if (pVehicle->bIsLawEnforcer && FindPlayerPed()->m_pWanted->m_nWantedLevel >= 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 +390,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 +427,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 +474,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->m_nWantedLevel > 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 +526,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 +553,18 @@ void CCarAI::AddPoliceCarOccupants(CVehicle* pVehicle)
if (FindPlayerPed()->m_pWanted->m_nWantedLevel > 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 +592,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 +648,20 @@ uint8 CCarAI::FindPoliceCarMissionForWantedLevel()
}
}
+uint8 CCarAI::FindPoliceBoatMissionForWantedLevel()
+{
+ switch (CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_pWanted->m_nWantedLevel) {
+ 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->m_nWantedLevel) {
@@ -605,6 +714,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->m_nWantedLevel) {
+ 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 +755,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 cb4229eb..1023f2a3 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,59 @@
#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
-
+#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)
+
+//--MIAMI: file done
+
+bool CCarCtrl::bMadDriversCheat;
int CCarCtrl::NumLawEnforcerCars;
int CCarCtrl::NumAmbulancesOnDuty;
int CCarCtrl::NumFiretrucksOnDuty;
@@ -81,23 +99,31 @@ int32 CCarCtrl::MaxNumberOfCarsInUse = 12;
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];
+//--MIAMI: done except heli/plane functions
+
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 +137,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 +152,7 @@ CCarCtrl::GenerateOneRandomCar()
int carClass;
int carModel;
if (pWanted->m_nWantedLevel > 1 && NumLawEnforcerCars < pWanted->m_MaximumLawEnforcerVehicles &&
- pWanted->m_CurrentCops < pWanted->m_MaxCops && (
+ pWanted->m_CurrentCops < pWanted->m_MaxCops && !CGame::IsInInterior() && (
pWanted->m_nWantedLevel > 3 ||
pWanted->m_nWantedLevel > 2 && CTimer::GetTimeInMilliseconds() > LastTimeLawEnforcerCreated + 5000 ||
pWanted->m_nWantedLevel > 1 && CTimer::GetTimeInMilliseconds() > LastTimeLawEnforcerCreated + 8000)) {
@@ -134,8 +161,8 @@ CCarCtrl::GenerateOneRandomCar()
carClass = COPS;
carModel = ChoosePoliceCarModel();
}else{
- carModel = ChooseModel(&zone, &vecTargetPos, &carClass);
- if (carClass == COPS && pWanted->m_nWantedLevel >= 1)
+ carModel = ChooseModel(&zone, &carClass);
+ if (carModel == -1 || (carClass == COPS && pWanted->m_nWantedLevel >= 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 +186,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 +202,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 +224,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 +252,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 +267,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 +282,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->m_nWantedLevel >= 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 +343,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->m_nWantedLevel != 0){
@@ -342,19 +370,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 +527,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 +549,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 +634,156 @@ CCarCtrl::GenerateOneRandomCar()
}
pVehicleModel->AvoidSameVehicleColour(&pVehicle->m_currentColour1, &pVehicle->m_currentColour2);
CWorld::Add(pVehicle);
- if (carClass == COPS)
+ if (carClass == COPS || carClass == COPS_BOAT)
CCarAI::AddPoliceCarOccupants(pVehicle);
- else
+ else {
pVehicle->SetUpDriver();
- if ((CGeneral::GetRandomNumber() & 0x3F) == 0){ /* 1/64 probability */
+ int32 passengers = 0;
+ for (int i = 0; i < pVehicle->m_nNumMaxPassengers; i++)
+ passengers += (CGeneral::GetRandomNumberInRange(0.0f, 1.0f) < PROBABILITY_OF_PASSENGER_IN_VEHICLE) ? 1 : 0;
+ if (CModelInfo::IsCarModel(carModel) && (CModelInfo::GetModelInfo(carModel)->GetAnimFileIndex() == CAnimManager::GetAnimationBlockIndex("van") && passengers >= 1))
+ passengers = 1;
+ for (int i = 0; i < passengers; i++) {
+ CPed* pPassenger = pVehicle->SetupPassenger(i);
+ if (pPassenger) {
+ ++CPopulation::ms_nTotalCarPassengerPeds;
+ pPassenger->bCarPassenger = true;
+ }
+ }
+ }
+ int nMadDrivers;
+ switch (pVehicle->GetVehicleAppearance()) {
+ case VEHICLE_APPEARANCE_BIKE:
+ nMadDrivers = 30;
+ break;
+ case VEHICLE_APPEARANCE_BOAT:
+ nMadDrivers = 40;
+ break;
+ default:
+ nMadDrivers = 6;
+ break;
+ }
+ if ((CGeneral::GetRandomNumber() & 0x7F) < nMadDrivers || bMadDriversCheat) {
pVehicle->SetStatus(STATUS_PHYSICS);
pVehicle->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_AVOID_CARS;
pVehicle->AutoPilot.m_nCruiseSpeed += 10;
}
if (carClass == COPS)
LastTimeLawEnforcerCreated = CTimer::GetTimeInMilliseconds();
+ if (pVehicle->GetModelIndex() == MI_CADDY) {
+ pVehicle->SetStatus(STATUS_PHYSICS);
+ pVehicle->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_AVOID_CARS;
+ }
+ if (carClass == COPS && pVehicle->GetModelIndex() == MI_VICECHEE) {
+ CVehicleModelInfo* pVehicleModel = (CVehicleModelInfo*)CModelInfo::GetModelInfo(MI_VICECHEE);
+ switch (MiamiViceCycle) {
+ case 0:
+ pVehicleModel->SetVehicleColour(53, 77);
+ break;
+ case 1:
+ pVehicleModel->SetVehicleColour(15, 77);
+ break;
+ case 2:
+ pVehicleModel->SetVehicleColour(41, 77);
+ break;
+ case 3:
+ pVehicleModel->SetVehicleColour(61, 77);
+ break;
+ default:
+ break;
+ }
+ }
+ if (CGeneral::GetRandomNumberInRange(0.0f, 1.0f) >= (1 - PROBABILITY_OF_DEAD_PED_ACCIDENT)) {
+ if (CModelInfo::IsCarModel(pVehicle->GetModelIndex()) && !pVehicle->bIsLawEnforcer) {
+ if (CPopulation::AddDeadPedInFrontOfCar(pVehicle->GetPosition() + pVehicle->GetForward() * DISTANCE_BETWEEN_CAR_AND_DEAD_PED, pVehicle)) {
+ pVehicle->AutoPilot.m_nCruiseSpeed = 0;
+ pVehicle->SetMoveSpeed(0.0f, 0.0f, 0.0f);
+ for (int i = 0; i < pVehicle->m_nNumPassengers; i++) {
+ if (pVehicle->pPassengers[i]) {
+ pVehicle->pPassengers[i]->SetObjective(OBJECTIVE_LEAVE_CAR, pVehicle);
+ pVehicle->pPassengers[i]->m_nLastPedState = PED_WANDER_PATH;
+ pVehicle->pPassengers[i]->m_vehicleInAccident = pVehicle;
+ pVehicle->pPassengers[i]->bDeadPedInFrontOfCar = true;
+ pVehicle->RegisterReference((CEntity**)&pVehicle->pPassengers[i]->m_vehicleInAccident);
+ }
+ }
+ if (pVehicle->pDriver) {
+ pVehicle->pDriver->SetObjective(OBJECTIVE_LEAVE_CAR, pVehicle);
+ pVehicle->pDriver->m_nLastPedState = PED_WANDER_PATH;
+ pVehicle->pDriver->m_vehicleInAccident = pVehicle;
+ pVehicle->pDriver->bDeadPedInFrontOfCar = true;
+ pVehicle->RegisterReference((CEntity**)&pVehicle->pDriver->m_vehicleInAccident);
+ }
+ }
+ }
+ }
+}
+
+bool
+CCarCtrl::BoatWithTallMast(int32 mi)
+{
+ return mi == MI_RIO || mi == MI_TROPIC || mi == MI_MARQUIS;
+}
+
+int32
+CCarCtrl::ChooseBoatModel(int32 rating)
+{
+ ++NumRequestsOfCarRating[rating];
+ return ChooseCarModel(rating);
+}
+
+int32
+CCarCtrl::ChooseBoatRating(CZoneInfo* pZoneInfo)
+{
+ int rnd = CGeneral::GetRandomNumberInRange(0, 1000);
+ for (int i = 0; i < NUM_BOAT_CLASSES - 1; i++) {
+ if (rnd < pZoneInfo->boatThreshold[i])
+ return FIRST_BOAT_RATING + i;
+ }
+ return FIRST_BOAT_RATING + NUM_BOAT_CLASSES - 1;
}
int32
-CCarCtrl::ChooseModel(CZoneInfo* pZone, CVector* pPos, int* pClass) {
+CCarCtrl::ChooseCarRating(CZoneInfo* pZoneInfo)
+{
+ int rnd = CGeneral::GetRandomNumberInRange(0, 1000);
+ for (int i = 0; i < NUM_CAR_CLASSES - 1; i++) {
+ if (rnd < pZoneInfo->carThreshold[i])
+ return i;
+ }
+ return FIRST_CAR_RATING + NUM_CAR_CLASSES - 1;
+}
+
+int32
+CCarCtrl::ChooseModel(CZoneInfo* pZone, int* pClass) {
int32 model = -1;
- while (model == -1 || !CStreaming::HasModelLoaded(model)){
+ int32 i;
+ for (i = 10; i > 0 && (model == -1 || !CStreaming::HasModelLoaded(model)); i--) {
int rnd = CGeneral::GetRandomNumberInRange(0, 1000);
- if (rnd < pZone->carThreshold[0])
- model = CCarCtrl::ChooseCarModel((*pClass = POOR));
- else if (rnd < pZone->carThreshold[1])
- model = CCarCtrl::ChooseCarModel((*pClass = RICH));
- else if (rnd < pZone->carThreshold[2])
- model = CCarCtrl::ChooseCarModel((*pClass = EXEC));
- else if (rnd < pZone->carThreshold[3])
- model = CCarCtrl::ChooseCarModel((*pClass = WORKER));
- else if (rnd < pZone->carThreshold[4])
- model = CCarCtrl::ChooseCarModel((*pClass = SPECIAL));
- else if (rnd < pZone->carThreshold[5])
- model = CCarCtrl::ChooseCarModel((*pClass = BIG));
- else if (rnd < pZone->copThreshold)
- *pClass = COPS, model = CCarCtrl::ChoosePoliceCarModel();
- else if (rnd < pZone->gangThreshold[0])
- model = CCarCtrl::ChooseGangCarModel((*pClass = MAFIA) - MAFIA);
- else if (rnd < pZone->gangThreshold[1])
- model = CCarCtrl::ChooseGangCarModel((*pClass = TRIAD) - MAFIA);
- else if (rnd < pZone->gangThreshold[2])
- model = CCarCtrl::ChooseGangCarModel((*pClass = DIABLO) - MAFIA);
- else if (rnd < pZone->gangThreshold[3])
- model = CCarCtrl::ChooseGangCarModel((*pClass = YAKUZA) - MAFIA);
- else if (rnd < pZone->gangThreshold[4])
- model = CCarCtrl::ChooseGangCarModel((*pClass = YARDIE) - MAFIA);
- else if (rnd < pZone->gangThreshold[5])
- model = CCarCtrl::ChooseGangCarModel((*pClass = COLOMB) - MAFIA);
- else if (rnd < pZone->gangThreshold[6])
- model = CCarCtrl::ChooseGangCarModel((*pClass = NINES) - MAFIA);
- else if (rnd < pZone->gangThreshold[7])
- model = CCarCtrl::ChooseGangCarModel((*pClass = GANG8) - MAFIA);
- else if (rnd < pZone->gangThreshold[8])
- model = CCarCtrl::ChooseGangCarModel((*pClass = GANG9) - MAFIA);
- else
- model = CCarCtrl::ChooseCarModel((*pClass = TAXI));
+
+ if (rnd < pZone->copThreshold) {
+ *pClass = COPS;
+ model = ChoosePoliceCarModel();
+ continue;
+ }
+
+ int32 j;
+ for (j = 0; j < NUM_GANG_CAR_CLASSES; j++) {
+ if (rnd < pZone->gangThreshold[j]) {
+ *pClass = j + FIRST_GANG_CAR_RATING;
+ model = ChooseGangCarModel(j);
+ break;
+ }
+ }
+
+ if (j != NUM_GANG_CAR_CLASSES)
+ continue;
+
+ *pClass = ChooseCarRating(pZone);
+ model = ChooseCarModel(*pClass);
}
+ if (i == 0)
+ return -1;
return model;
}
@@ -637,42 +791,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 +890,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 +898,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 +912,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 +920,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 +966,7 @@ CCarCtrl::PossiblyRemoveVehicle(CVehicle* pVehicle)
return;
}
float distanceToPlayer = (pVehicle->GetPosition() - vecPlayerPos).Magnitude2D();
- float threshold = 50.0f;
+ float threshold = OFFSCREEN_DESPAWN_RANGE;
if (pVehicle->GetIsOnScreen() ||
TheCamera.Cams[TheCamera.ActiveCam].LookingLeft ||
TheCamera.Cams[TheCamera.ActiveCam].LookingRight ||
@@ -740,14 +976,17 @@ CCarCtrl::PossiblyRemoveVehicle(CVehicle* pVehicle)
pVehicle->GetModelIndex() == MI_AMBULAN ||
pVehicle->GetModelIndex() == MI_FIRETRUCK ||
pVehicle->bIsLawEnforcer ||
- pVehicle->bIsCarParkVehicle
+ pVehicle->bIsCarParkVehicle ||
+ CTimer::GetTimeInMilliseconds() < pVehicle->m_nSetPieceExtendedRangeTime
){
- threshold = 130.0f * TheCamera.GenerationDistMultiplier;
+ threshold = ONSCREEN_DESPAWN_RANGE * TheCamera.GenerationDistMultiplier;
}
+ if (TheCamera.GetForward().z < -0.9f)
+ threshold = 70.0f;
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);
@@ -756,10 +995,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() &&
@@ -773,7 +1013,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);
@@ -797,6 +1037,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)
{
@@ -829,8 +1079,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(
@@ -853,7 +1107,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;
@@ -865,33 +1119,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));
@@ -932,7 +1186,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()));
}
}
@@ -978,14 +1232,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
@@ -1035,7 +1287,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;
@@ -1070,11 +1322,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? */
@@ -1085,8 +1337,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);
}
@@ -1233,7 +1485,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;
@@ -1312,22 +1564,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));
@@ -1367,7 +1621,7 @@ void CCarCtrl::WeaveThroughPedsSectorList(CPtrList& lst, CVehicle* pVehicle, CPh
continue;
if (Abs(pPed->GetPosition().z - pVehicle->GetPosition().z) >= PED_HEIGHT_DIFF_TO_CONSIDER_WEAVING)
continue;
- if (pPed->m_pCurSurface != pVehicle)
+ if (pPed->m_pCurSurface != pVehicle && pPed->m_attachedTo != pVehicle)
WeaveForPed(pPed, pVehicle, pAngleToWeaveLeft, pAngleToWeaveRight);
}
@@ -1472,6 +1726,7 @@ void CCarCtrl::WeaveForObject(CEntity* pOtherEntity, CVehicle* pVehicle, float*
bool CCarCtrl::PickNextNodeAccordingStrategy(CVehicle* pVehicle)
{
+ pVehicle->AutoPilot.m_nCruiseSpeedMultiplierType = ThePaths.m_pathNodes[pVehicle->AutoPilot.m_nNextRouteNode].speedLimit;
switch (pVehicle->AutoPilot.m_nCarMission){
case MISSION_RAMPLAYER_FARAWAY:
case MISSION_BLOCKPLAYER_FARAWAY:
@@ -1498,23 +1753,30 @@ bool CCarCtrl::PickNextNodeAccordingStrategy(CVehicle* pVehicle)
return false;
default:
PickNextNodeRandomly(pVehicle);
+ if (ThePaths.GetNode(pVehicle->AutoPilot.m_nNextRouteNode)->bOnlySmallBoats && BoatWithTallMast(pVehicle->GetModelIndex()))
+ pVehicle->AutoPilot.m_nCruiseSpeed = 0;
return false;
}
}
void CCarCtrl::PickNextNodeRandomly(CVehicle* pVehicle)
{
+ if (pVehicle->m_nRouteSeed)
+ CGeneral::SetRandomSeed(pVehicle->m_nRouteSeed);
int32 prevNode = pVehicle->AutoPilot.m_nCurrentRouteNode;
int32 curNode = pVehicle->AutoPilot.m_nNextRouteNode;
uint8 totalLinks = ThePaths.m_pathNodes[curNode].numLinks;
CCarPathLink* pCurLink = &ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nNextPathNodeInfo];
-#ifdef FIX_BUGS
- uint8 lanesOnCurrentPath = pCurLink->pathNodeIndex == curNode ?
- pCurLink->numLeftLanes : pCurLink->numRightLanes;
-#else
- uint8 lanesOnCurrentPath = pCurLink->pathNodeIndex == curNode ?
- pCurLink->numRightLanes : pCurLink->numLeftLanes;
-#endif
+ uint8 lanesOnCurrentPath;
+ bool isOnOneWayRoad;
+ if (pCurLink->pathNodeIndex == curNode) {
+ lanesOnCurrentPath = pCurLink->numLeftLanes;
+ isOnOneWayRoad = pCurLink->numRightLanes == 0;
+ }
+ else {
+ lanesOnCurrentPath = pCurLink->numRightLanes;
+ isOnOneWayRoad = pCurLink->numLeftLanes == 0;
+ }
uint8 allowedDirections = PATH_DIRECTION_NONE;
uint8 nextLane = pVehicle->AutoPilot.m_nNextLane;
if (nextLane == 0)
@@ -1536,6 +1798,7 @@ void CCarCtrl::PickNextNodeRandomly(CVehicle* pVehicle)
CCarPathLink* pNextLink;
CPathNode* pNextPathNode;
bool goingAgainstOneWayRoad;
+ bool nextNodeIsOneWayRoad;
uint8 direction;
for(attempt = 0; attempt < ATTEMPTS_TO_FIND_NEXT_NODE; attempt++){
if (attempt != 0){
@@ -1545,7 +1808,7 @@ void CCarCtrl::PickNextNodeRandomly(CVehicle* pVehicle)
if ((!pNextPathNode->bDeadEnd || pPrevPathNode->bDeadEnd) &&
(!pNextPathNode->bDisabled || pPrevPathNode->bDisabled) &&
(!pNextPathNode->bBetweenLevels || pPrevPathNode->bBetweenLevels || !pVehicle->AutoPilot.m_bStayInCurrentLevel) &&
- !goingAgainstOneWayRoad)
+ !goingAgainstOneWayRoad && (!isOnOneWayRoad || !nextNodeIsOneWayRoad))
break;
}
}
@@ -1555,9 +1818,10 @@ void CCarCtrl::PickNextNodeRandomly(CVehicle* pVehicle)
direction = FindPathDirection(prevNode, curNode, pVehicle->AutoPilot.m_nNextRouteNode);
pNextLink = &ThePaths.m_carPathLinks[ThePaths.m_carPathConnections[nextLink + pCurPathNode->firstLink]];
goingAgainstOneWayRoad = pNextLink->pathNodeIndex == curNode ? pNextLink->numRightLanes == 0 : pNextLink->numLeftLanes == 0;
+ nextNodeIsOneWayRoad = pNextLink->pathNodeIndex == curNode ? pNextLink->numLeftLanes == 0 : pNextLink->numRightLanes == 0;
}
if (attempt >= ATTEMPTS_TO_FIND_NEXT_NODE) {
- /* If we failed 15 times, then remove dead end and current lane limitations */
+ /* If we failed 15 times, then remove dead end, one way road and current lane limitations */
for (attempt = 0; attempt < ATTEMPTS_TO_FIND_NEXT_NODE; attempt++) {
if (attempt != 0) {
if (pVehicle->AutoPilot.m_nNextRouteNode != prevNode) {
@@ -1702,74 +1966,57 @@ void CCarCtrl::PickNextNodeToChaseCar(CVehicle* pVehicle, float targetX, float t
void CCarCtrl::PickNextNodeToChaseCar(CVehicle* pVehicle, float targetX, float targetY, CVehicle* pTarget)
#endif
{
+ if (pVehicle->m_nRouteSeed)
+ CGeneral::SetRandomSeed(pVehicle->m_nRouteSeed);
int prevNode = pVehicle->AutoPilot.m_nCurrentRouteNode;
int curNode = pVehicle->AutoPilot.m_nNextRouteNode;
CPathNode* pPrevNode = &ThePaths.m_pathNodes[prevNode];
CPathNode* pCurNode = &ThePaths.m_pathNodes[curNode];
- CPathNode* pTargetNode;
+ CPathNode* pTargetNode[2];
int16 numNodes;
float distanceToTargetNode;
- if (pTarget && pTarget->m_pCurGroundEntity &&
- pTarget->m_pCurGroundEntity->IsBuilding() &&
- ((CBuilding*)pTarget->m_pCurGroundEntity)->GetIsATreadable() &&
- ((CTreadable*)pTarget->m_pCurGroundEntity)->m_nodeIndices[0][0] >= 0){
- CTreadable* pCurrentMapObject = (CTreadable*)pTarget->m_pCurGroundEntity;
- int closestNode = -1;
- float minDist = 100000.0f;
- for (int i = 0; i < 12; i++){
- int node = pCurrentMapObject->m_nodeIndices[0][i];
- if (node < 0)
- break;
- float dist = (ThePaths.m_pathNodes[node].GetPosition() - pTarget->GetPosition()).Magnitude();
- if (dist < minDist){
- minDist = dist;
- closestNode = node;
- }
- }
- ThePaths.DoPathSearch(0, pCurNode->GetPosition(), curNode,
+ 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, closestNode);
- }else
- {
-
- 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, -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++)
;
}
@@ -1789,11 +2036,11 @@ void CCarCtrl::PickNextNodeToChaseCar(CVehicle* pVehicle, float targetX, float t
int8 lanesOnNextNode;
if (curNode >= pVehicle->AutoPilot.m_nNextRouteNode) {
pVehicle->AutoPilot.m_nNextDirection = 1;
- lanesOnNextNode = pNextLink->numLeftLanes;
+ lanesOnNextNode = pNextLink->numRightLanes;
}
else {
pVehicle->AutoPilot.m_nNextDirection = -1;
- lanesOnNextNode = pNextLink->numRightLanes;
+ lanesOnNextNode = pNextLink->numLeftLanes;
}
float currentPathLinkForwardX = pVehicle->AutoPilot.m_nCurrentDirection * pCurLink->GetDirX();
float currentPathLinkForwardY = pVehicle->AutoPilot.m_nCurrentDirection * pCurLink->GetDirY();
@@ -1848,6 +2095,8 @@ void CCarCtrl::PickNextNodeToChaseCar(CVehicle* pVehicle, float targetX, float t
bool CCarCtrl::PickNextNodeToFollowPath(CVehicle* pVehicle)
{
+ if (pVehicle->m_nRouteSeed)
+ CGeneral::SetRandomSeed(pVehicle->m_nRouteSeed);
int curNode = pVehicle->AutoPilot.m_nNextRouteNode;
CPathNode* pCurNode = &ThePaths.m_pathNodes[curNode];
if (pVehicle->AutoPilot.m_nPathFindNodesCount == 0){
@@ -1855,8 +2104,9 @@ bool CCarCtrl::PickNextNodeToFollowPath(CVehicle* pVehicle)
pVehicle->AutoPilot.m_vecDestinationCoors, pVehicle->AutoPilot.m_aPathFindNodesInfo,
&pVehicle->AutoPilot.m_nPathFindNodesCount, NUM_PATH_NODES_IN_AUTOPILOT,
pVehicle, nil, 999999.9f, -1);
- if (pVehicle->AutoPilot.m_nPathFindNodesCount < 1)
+ if (pVehicle->AutoPilot.m_nPathFindNodesCount < 2)
return true;
+ pVehicle->AutoPilot.RemoveOnePathNode();
}
CPathNode* pNextPathNode = &ThePaths.m_pathNodes[pVehicle->AutoPilot.m_nNextRouteNode];
CCarPathLink* pCurLink = &ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nNextPathNodeInfo];
@@ -1940,6 +2190,7 @@ void CCarCtrl::Init(void)
LastTimeAmbulanceCreated = 0;
#ifdef FIX_BUGS
LastTimeLawEnforcerCreated = 0;
+ LastTimeMiamiViceGenerated = 0;
#endif
bCarsGeneratedAroundCamera = false;
CountDownToCarsAtStart = 2;
@@ -1947,9 +2198,11 @@ void CCarCtrl::Init(void)
for (int i = 0; i < MAX_CARS_TO_KEEP; i++)
apCarsToKeep[i] = nil;
for (int i = 0; i < TOTAL_CUSTOM_CLASSES; i++){
- for (int j = 0; j < MAX_CAR_MODELS_IN_ARRAY; j++)
- CarArrays[i][j] = 0;
- NextCarOfRating[i] = 0;
+ for (int j = 0; j < MAX_CAR_MODELS_IN_ARRAY; j++) {
+ LoadedCarsArray[i][j] = -1;
+ }
+ NumOfLoadedCarsOfRating[i] = 0;
+ NumRequestsOfCarRating[i] = 0;
TotalNumOfCarsOfRating[i] = 0;
}
}
@@ -1967,13 +2220,14 @@ void CCarCtrl::ReInit(void)
LastTimeFireTruckCreated = 0;
LastTimeAmbulanceCreated = 0;
LastTimeLawEnforcerCreated = 0;
+ LastTimeMiamiViceGenerated = 0;
#endif
CountDownToCarsAtStart = 2;
CarDensityMultiplier = 1.0f;
for (int i = 0; i < MAX_CARS_TO_KEEP; i++)
apCarsToKeep[i] = nil;
for (int i = 0; i < TOTAL_CUSTOM_CLASSES; i++)
- NextCarOfRating[i] = 0;
+ NumRequestsOfCarRating[i] = 0;
}
void CCarCtrl::DragCarToPoint(CVehicle* pVehicle, CVector* pPoint)
@@ -2083,7 +2337,7 @@ void CCarCtrl::SteerAICarWithPhysics(CVehicle* pVehicle)
pVehicle->AutoPilot.m_nTempAction = TEMPACT_NONE;
break;
case TEMPACT_HANDBRAKETURNLEFT:
- swerve = -1.0f; // It seems like this should be swerve = 1.0f (fixed in VC)
+ swerve = 1.0f;
accel = 0.0f;
brake = 0.0f;
handbrake = true;
@@ -2091,7 +2345,7 @@ void CCarCtrl::SteerAICarWithPhysics(CVehicle* pVehicle)
pVehicle->AutoPilot.m_nTempAction = TEMPACT_NONE;
break;
case TEMPACT_HANDBRAKETURNRIGHT:
- swerve = 1.0f; // It seems like this should be swerve = -1.0f (fixed in VC)
+ swerve = -1.0f;
accel = 0.0f;
brake = 0.0f;
handbrake = true;
@@ -2167,7 +2421,13 @@ void CCarCtrl::SteerAICarWithPhysics_OnlyMission(CVehicle* pVehicle, float* pSwe
case MISSION_GOTOCOORDS_ACCURATE:
case MISSION_RAMCAR_FARAWAY:
case MISSION_BLOCKCAR_FARAWAY:
- SteerAICarWithPhysicsFollowPath(pVehicle, pSwerve, pAccel, pBrake, pHandbrake);
+ if (pVehicle->AutoPilot.m_bIgnorePathfinding) {
+ *pSwerve = 0.0f;
+ *pAccel = 1.0f;
+ *pBrake = 0.0f;
+ *pHandbrake = false;
+ }else
+ SteerAICarWithPhysicsFollowPath(pVehicle, pSwerve, pAccel, pBrake, pHandbrake);
return;
case MISSION_RAMPLAYER_CLOSE:
{
@@ -2202,6 +2462,9 @@ void CCarCtrl::SteerAICarWithPhysics_OnlyMission(CVehicle* pVehicle, float* pSwe
SteerAICarWithPhysicsTryingToBlockTarget_Stop(pVehicle, FindPlayerCoors().x, FindPlayerCoors().y,
FindPlayerSpeed().x, FindPlayerSpeed().y, pSwerve, pAccel, pBrake, pHandbrake);
return;
+ case MISSION_WAITFORDELETION:
+ case MISSION_HELI_LAND:
+ return;
case MISSION_GOTOCOORDS_STRAIGHT:
case MISSION_GOTO_COORDS_STRAIGHT_ACCURATE:
SteerAICarWithPhysicsHeadingForTarget(pVehicle, nil,
@@ -2215,6 +2478,12 @@ void CCarCtrl::SteerAICarWithPhysics_OnlyMission(CVehicle* pVehicle, float* pSwe
*pHandbrake = true;
*pBrake = 0.5f;
return;
+ case MISSION_GOTOCOORDS_ASTHECROWSWIMS:
+ SteerAIBoatWithPhysicsHeadingForTarget(pVehicle,
+ pVehicle->AutoPilot.m_vecDestinationCoors.x, pVehicle->AutoPilot.m_vecDestinationCoors.y,
+ pSwerve, pAccel, pBrake);
+ *pHandbrake = false;
+ return;
case MISSION_RAMCAR_CLOSE:
SteerAICarWithPhysicsHeadingForTarget(pVehicle, pVehicle->AutoPilot.m_pTargetCar,
pVehicle->AutoPilot.m_pTargetCar->GetPosition().x, pVehicle->AutoPilot.m_pTargetCar->GetPosition().y,
@@ -2236,26 +2505,132 @@ void CCarCtrl::SteerAICarWithPhysics_OnlyMission(CVehicle* pVehicle, float* pSwe
pVehicle->AutoPilot.m_pTargetCar->GetMoveSpeed().y,
pSwerve, pAccel, pBrake, pHandbrake);
return;
+ case MISSION_HELI_FLYTOCOORS:
+ SteerAIHeliTowardsTargetCoors((CAutomobile*)pVehicle);
+ return;
+ case MISSION_ATTACKPLAYER:
+ SteerAIBoatWithPhysicsAttackingPlayer(pVehicle, pSwerve, pAccel, pBrake, pHandbrake);
+ return;
+ case MISSION_PLANE_FLYTOCOORS:
+ SteerAIPlaneTowardsTargetCoors((CAutomobile*)pVehicle);
+ return;
+ case MISSION_SLOWLY_DRIVE_TOWARDS_PLAYER_1:
+ SteerAICarWithPhysicsHeadingForTarget(pVehicle, nil,
+ pVehicle->AutoPilot.m_vecDestinationCoors.x, pVehicle->AutoPilot.m_vecDestinationCoors.y,
+ pSwerve, pAccel, pBrake, pHandbrake);
+ return;
+ case MISSION_SLOWLY_DRIVE_TOWARDS_PLAYER_2:
+ SteerAICarWithPhysicsHeadingForTarget(pVehicle, nil, FindPlayerCoors().x, FindPlayerCoors().y,
+ pSwerve, pAccel, pBrake, pHandbrake);
+ return;
+ case MISSION_BLOCKPLAYER_FORWARDANDBACK:
+ SteerAICarBlockingPlayerForwardAndBack(pVehicle, pSwerve, pAccel, pBrake, pHandbrake);
+ return;
default:
+ assert(0);
return;
}
}
-void CCarCtrl::SteerAIBoatWithPhysics(CBoat* pBoat)
+void CCarCtrl::SteerAICarBlockingPlayerForwardAndBack(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;
+ *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;
}
- pBoat->m_fSteerAngle = pBoat->m_fSteeringLeftRight;
- pBoat->m_fGasPedal = pBoat->m_fAccelerate;
- pBoat->m_fBrakePedal = pBoat->m_fBrake;
- pBoat->bIsHandbrakeOn = false;
+}
+
+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::SteerAIBoatWithPhysicsAttackingPlayer(CVehicle* pVehicle, float* pSwerve, float* pAccel, float* pBrake, bool* pHandbrake)
+{
+ 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;
+ }
+ 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)
@@ -2263,10 +2638,151 @@ float CCarCtrl::FindMaxSteerAngle(CVehicle* pVehicle)
return pVehicle->GetModelIndex() == MI_ENFORCER ? 0.7f : DEFAULT_MAX_STEER_ANGLE;
}
+void CCarCtrl::SteerAIHeliTowardsTargetCoors(CAutomobile* pHeli)
+{
+ if (pHeli->m_aWheelSpeed[1] < 0.22f)
+ pHeli->m_aWheelSpeed[1] += 0.001f;
+ if (pHeli->m_aWheelSpeed[1] < 0.15f)
+ return;
+ CVector2D vecToTarget = pHeli->AutoPilot.m_vecDestinationCoors - pHeli->GetPosition();
+ float distanceToTarget = vecToTarget.Magnitude();
+#ifdef FIX_BUGS
+ float speed = pHeli->AutoPilot.GetCruiseSpeed() * 0.01f;
+#else
+ float speed = pHeli->AutoPilot.m_nCruiseSpeed * 0.01f;
+#endif
+ if (distanceToTarget <= 100.0f)
+ {
+ if (distanceToTarget > 75.0f)
+ speed *= 0.7f;
+ else if (distanceToTarget > 10.0f)
+ speed *= 0.4f;
+ else
+ speed *= 0.2f;
+ }
+ vecToTarget.Normalise();
+ CVector2D vecAdvanceThisFrame(vecToTarget * speed);
+ float resistance = Pow(0.997f, CTimer::GetTimeStep());
+ pHeli->m_vecMoveSpeed.x *= resistance;
+ pHeli->m_vecMoveSpeed.y *= resistance;
+ CVector2D vecSpeedDirection = vecAdvanceThisFrame - pHeli->m_vecMoveSpeed;
+ float vecSpeedChangeLength = vecSpeedDirection.Magnitude();
+ vecSpeedDirection.Normalise();
+ float changeMultiplier = 0.002f * CTimer::GetTimeStep();
+ if (distanceToTarget < 5.0f)
+ changeMultiplier /= 5.0f;
+ if (vecSpeedChangeLength < changeMultiplier)
+ pHeli->SetMoveSpeed(vecAdvanceThisFrame.x, vecAdvanceThisFrame.y, pHeli->GetMoveSpeed().z);
+ else
+ pHeli->AddToMoveSpeed(vecSpeedDirection * changeMultiplier);
+ pHeli->GetMatrix().Translate(CTimer::GetTimeStep() * pHeli->GetMoveSpeed().x, CTimer::GetTimeStep() * pHeli->GetMoveSpeed().y, 0.0f);
+ float ZTarget = pHeli->AutoPilot.m_vecDestinationCoors.z;
+ if (CTimer::GetTimeInMilliseconds() & 0x800) // switch every ~2 seconds
+ ZTarget += 2.0f;
+ float ZSpeedTarget = (ZTarget - pHeli->GetPosition().z) * 0.01f;
+ float ZSpeedChangeTarget = ZSpeedTarget - pHeli->GetMoveSpeed().z;
+ float ZSpeedChangeMax = 0.001f * CTimer::GetTimeStep();
+ if (!pHeli->bHeliDestroyed) {
+ if (Abs(ZSpeedChangeTarget) < ZSpeedChangeMax)
+ pHeli->SetMoveSpeed(pHeli->GetMoveSpeed().x, pHeli->GetMoveSpeed().y, ZSpeedTarget);
+ else if (ZSpeedChangeTarget < 0.0f)
+ pHeli->AddToMoveSpeed(0.0f, 0.0f, -ZSpeedChangeMax);
+ else
+ pHeli->AddToMoveSpeed(0.0f, 0.0f, 1.5f * ZSpeedChangeMax);
+ }
+ pHeli->GetMatrix().Translate(0.0f, 0.0f, CTimer::GetTimeStep() * pHeli->GetMoveSpeed().z);
+ pHeli->m_vecTurnSpeed.z *= Pow(0.99f, CTimer::GetTimeStep());
+ float ZTurnSpeedTarget;
+ if (distanceToTarget < 8.0f && pHeli->m_fHeliOrientation < 0.0f)
+ ZTurnSpeedTarget = 0.0f;
+ else {
+ float fAngleTarget = CGeneral::GetATanOfXY(vecToTarget.x, vecToTarget.y) + PI;
+ if (pHeli->m_fHeliOrientation >= 0.0f)
+ fAngleTarget = pHeli->m_fHeliOrientation;
+ fAngleTarget -= pHeli->m_fOrientation;
+ while (fAngleTarget < -PI)
+ fAngleTarget += TWOPI;
+ while (fAngleTarget > PI)
+ fAngleTarget -= TWOPI;
+ if (Abs(fAngleTarget) <= 0.4f)
+ ZTurnSpeedTarget = 0.0f;
+ else if (fAngleTarget < 0.0f)
+ ZTurnSpeedTarget = -0.03f;
+ else
+ ZTurnSpeedTarget = 0.03f;
+ }
+ float ZTurnSpeedChangeTarget = ZTurnSpeedTarget - pHeli->GetTurnSpeed().z;
+ float ZTurnSpeedLimit = 0.0002f * CTimer::GetTimeStep();
+ if (Abs(ZTurnSpeedChangeTarget) < ZTurnSpeedLimit)
+ pHeli->m_vecTurnSpeed.z = ZTurnSpeedTarget;
+ else if (ZTurnSpeedChangeTarget < 0.0f)
+ pHeli->m_vecTurnSpeed.z -= ZTurnSpeedLimit;
+ else
+ pHeli->m_vecTurnSpeed.z += ZTurnSpeedLimit;
+ pHeli->m_fOrientation += pHeli->GetTurnSpeed().z * CTimer::GetTimeStep();
+ CVector up;
+ if (pHeli->bHeliMinimumTilt)
+ up = CVector(0.5f * pHeli->GetMoveSpeed().x, 0.5f * pHeli->GetMoveSpeed().y, 1.0f);
+ else
+ up = CVector(3.0f * pHeli->GetMoveSpeed().x, 3.0f * pHeli->GetMoveSpeed().y, 1.0f);
+ up.Normalise();
+ CVector forward(Cos(pHeli->m_fOrientation), Sin(pHeli->m_fOrientation), 0.0f);
+ CVector right = CrossProduct(up, forward);
+ forward = CrossProduct(up, right);
+ pHeli->GetMatrix().GetRight() = right;
+ pHeli->GetMatrix().GetForward() = forward;
+ pHeli->GetMatrix().GetUp() = up;
+}
+
+void CCarCtrl::SteerAIPlaneTowardsTargetCoors(CAutomobile* pPlane)
+{
+ CVector2D vecToTarget = pPlane->AutoPilot.m_vecDestinationCoors - pPlane->GetPosition();
+ float fForwardZ = (pPlane->AutoPilot.m_vecDestinationCoors.z - pPlane->GetPosition().z) / vecToTarget.Magnitude();
+ fForwardZ = clamp(fForwardZ, -0.3f, 0.3f);
+ float angle = CGeneral::GetATanOfXY(vecToTarget.x, vecToTarget.y);
+ while (angle > TWOPI)
+ angle -= TWOPI;
+ float difference = LimitRadianAngle(angle - pPlane->m_fOrientation);
+ float steer = difference > 0.0f ? 0.04f : -0.04f;
+ if (Abs(difference) < 0.2f)
+ steer *= 5.0f * Abs(difference);
+ pPlane->m_fPlaneSteer *= Pow(0.96f, CTimer::GetTimeStep());
+ float steerChange = steer - pPlane->m_fPlaneSteer;
+ float maxChange = 0.003f * CTimer::GetTimeStep();
+ if (Abs(steerChange) < maxChange)
+ pPlane->m_fPlaneSteer = steer;
+ else if (steerChange < 0.0f)
+ pPlane->m_fPlaneSteer -= maxChange;
+ else
+ pPlane->m_fPlaneSteer += maxChange;
+ pPlane->m_fOrientation += pPlane->m_fPlaneSteer * CTimer::GetTimeStep();
+ CVector up(0.0f, 0.0f, 1.0f);
+ up.Normalise();
+ CVector forward(Cos(pPlane->m_fOrientation), Sin(pPlane->m_fOrientation), fForwardZ);
+ forward.Normalise();
+ CVector right = CrossProduct(forward, up);
+ 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,
@@ -2291,17 +2807,13 @@ void CCarCtrl::SteerAICarWithPhysicsFollowPath(CVehicle* pVehicle, float* pSwerv
switch (pVehicle->AutoPilot.m_nCarMission){
case MISSION_GOTOCOORDS:
pVehicle->AutoPilot.m_nCarMission = MISSION_GOTOCOORDS_STRAIGHT;
- *pSwerve = 0.0f;
- *pAccel = 0.0f;
- *pBrake = 0.0f;
- *pHandbrake = false;
+ SteerAICarWithPhysicsHeadingForTarget(pVehicle, nil, pVehicle->AutoPilot.m_vecDestinationCoors.x,
+ pVehicle->AutoPilot.m_vecDestinationCoors.y, pSwerve, pAccel, pBrake, pHandbrake);
return;
case MISSION_GOTOCOORDS_ACCURATE:
pVehicle->AutoPilot.m_nCarMission = MISSION_GOTO_COORDS_STRAIGHT_ACCURATE;
- *pSwerve = 0.0f;
- *pAccel = 0.0f;
- *pBrake = 0.0f;
- *pHandbrake = false;
+ SteerAICarWithPhysicsHeadingForTarget(pVehicle, nil, pVehicle->AutoPilot.m_vecDestinationCoors.x,
+ pVehicle->AutoPilot.m_vecDestinationCoors.y, pSwerve, pAccel, pBrake, pHandbrake);
return;
default: break;
}
@@ -2338,11 +2850,14 @@ void CCarCtrl::SteerAICarWithPhysicsFollowPath(CVehicle* pVehicle, float* pSwerv
switch (pVehicle->AutoPilot.m_nDrivingStyle) {
case DRIVINGSTYLE_STOP_FOR_CARS:
case DRIVINGSTYLE_SLOW_DOWN_FOR_CARS:
+ case DRIVINGSTYLE_STOP_FOR_CARS_IGNORE_LIGHTS:
speedStyleMultiplier = FindMaximumSpeedForThisCarInTraffic(pVehicle);
#ifdef FIX_BUGS
- if (pVehicle->AutoPilot.m_nCruiseSpeed != 0)
+ if (pVehicle->AutoPilot.GetCruiseSpeed() != 0)
+ speedStyleMultiplier /= pVehicle->AutoPilot.GetCruiseSpeed();
+#else
+ speedStyleMultiplier /= pVehicle->AutoPilot.m_nCruiseSpeed;
#endif
- speedStyleMultiplier /= pVehicle->AutoPilot.m_nCruiseSpeed;
break;
default:
speedStyleMultiplier = 1.0f;
@@ -2404,7 +2919,7 @@ void CCarCtrl::SteerAICarWithPhysicsHeadingForTarget(CVehicle* pVehicle, CPhysic
{
*pHandbrake = false;
CVector2D forward = pVehicle->GetForward();
- forward.NormaliseSafe();
+ forward.Normalise();
float angleToTarget = CGeneral::GetATanOfXY(targetX - pVehicle->GetPosition().x, targetY - pVehicle->GetPosition().y);
float angleForward = CGeneral::GetATanOfXY(forward.x, forward.y);
if (pVehicle->AutoPilot.m_nDrivingStyle == DRIVINGSTYLE_AVOID_CARS)
@@ -2422,7 +2937,7 @@ void CCarCtrl::SteerAICarWithPhysicsHeadingForTarget(CVehicle* pVehicle, CPhysic
float speedDiff = speedTarget - currentSpeed;
if (speedDiff <= 0.0f){
*pAccel = 0.0f;
- *pBrake = Min(0.5f, -speedDiff * 0.05f);
+ *pBrake = Min(0.5f, -speedDiff / 20.0f);
}else if (currentSpeed < 25.0f){
*pAccel = Min(1.0f, speedDiff * 0.1f);
*pBrake = 0.0f;
@@ -2447,6 +2962,7 @@ void CCarCtrl::SteerAICarWithPhysicsTryingToBlockTarget(CVehicle* pVehicle, floa
pVehicle->AutoPilot.m_nCarMission = (pVehicle->AutoPilot.m_nCarMission == MISSION_BLOCKCAR_CLOSE) ?
MISSION_BLOCKCAR_HANDBRAKESTOP : MISSION_BLOCKPLAYER_HANDBRAKESTOP;
}
+
void CCarCtrl::SteerAICarWithPhysicsTryingToBlockTarget_Stop(CVehicle* pVehicle, float targetX, float targetY, float targetSpeedX, float targetSpeedY, float* pSwerve, float* pAccel, float* pBrake, bool* pHandbrake)
{
*pSwerve = 0.0f;
@@ -2488,26 +3004,6 @@ void CCarCtrl::SteerAICarWithPhysicsTryingToBlockTarget_Stop(CVehicle* pVehicle,
}
}
-void CCarCtrl::SteerAIBoatWithPhysicsHeadingForTarget(CBoat* pBoat, float targetX, float targetY, float* pSwerve, float* pAccel, float* pBrake)
-{
- CVector2D forward(pBoat->GetForward());
- forward.NormaliseSafe();
- CVector2D distanceToTarget = CVector2D(targetX, targetY) - pBoat->GetPosition();
- float angleToTarget = CGeneral::GetATanOfXY(distanceToTarget.x, distanceToTarget.y);
- float angleForward = CGeneral::GetATanOfXY(forward.x, forward.y);
- float angleDiff = LimitRadianAngle(angleToTarget - angleForward);
- angleDiff = Min(DEFAULT_MAX_STEER_ANGLE, Max(-DEFAULT_MAX_STEER_ANGLE, angleDiff));
- float currentSpeed = pBoat->GetMoveSpeed().Magnitude2D(); // +0.0f for some reason
- float speedDiff = pBoat->AutoPilot.m_nCruiseSpeed - currentSpeed * 60.0f;
- if (speedDiff > 0.0f){
- float accRemaining = speedDiff / pBoat->AutoPilot.m_nCruiseSpeed;
- *pAccel = (accRemaining > 0.25f) ? 1.0f : 1.0f - (0.25f - accRemaining) * 4.0f;
- }else
- *pAccel = (speedDiff < -5.0f) ? -0.2f : -0.1f;
- *pBrake = 0.0f;
- *pSwerve = angleDiff;
-}
-
void
CCarCtrl::RegisterVehicleOfInterest(CVehicle* pVehicle)
{
@@ -2615,6 +3111,7 @@ bool CCarCtrl::JoinCarWithRoadSystemGotoCoors(CVehicle* pVehicle, CVector vecTar
pVehicle->AutoPilot.m_aPathFindNodesInfo, &pVehicle->AutoPilot.m_nPathFindNodesCount);
if (pVehicle->AutoPilot.m_nPathFindNodesCount < 2){
pVehicle->AutoPilot.m_nPrevRouteNode = pVehicle->AutoPilot.m_nCurrentRouteNode = pVehicle->AutoPilot.m_nNextRouteNode = 0;
+ pVehicle->AutoPilot.m_nPathFindNodesCount = 0;
return true;
}
pVehicle->AutoPilot.m_nPrevRouteNode = 0;
@@ -2629,6 +3126,8 @@ bool CCarCtrl::JoinCarWithRoadSystemGotoCoors(CVehicle* pVehicle, CVector vecTar
void CCarCtrl::FindLinksToGoWithTheseNodes(CVehicle* pVehicle)
{
+ if (pVehicle->m_nRouteSeed)
+ CGeneral::SetRandomSeed(pVehicle->m_nRouteSeed);
int nextLink;
CPathNode* pCurNode = &ThePaths.m_pathNodes[pVehicle->AutoPilot.m_nCurrentRouteNode];
for (nextLink = 0; nextLink < 12; nextLink++)
@@ -2642,11 +3141,23 @@ void CCarCtrl::FindLinksToGoWithTheseNodes(CVehicle* pVehicle)
curLink = 0;
curConnection = ThePaths.m_carPathConnections[pCurNode->firstLink];
}else{
- curConnection = pVehicle->AutoPilot.m_nNextPathNodeInfo;
- while (curConnection == pVehicle->AutoPilot.m_nNextPathNodeInfo){
- curLink = CGeneral::GetRandomNumber() % pCurNode->numLinks;
- curConnection = ThePaths.m_carPathConnections[curLink + pCurNode->firstLink];
+ int closestLink = -1;
+ float md = 999999.9f;
+
+ for (curLink = 0; curLink < pCurNode->numLinks; curLink++) {
+ int node = ThePaths.ConnectedNode(curLink + pCurNode->firstLink);
+ CPathNode* pNode = &ThePaths.m_pathNodes[node];
+ if (node == pVehicle->AutoPilot.m_nNextRouteNode)
+ continue;
+ CVector vCurPos = pCurNode->GetPosition();
+ CVector vNextPos = pNode->GetPosition();
+ float dist = CCollision::DistToLine(&vCurPos, &vNextPos, &pVehicle->GetPosition());
+ if (dist < md) {
+ md = dist;
+ closestLink = curLink;
+ }
}
+ curConnection = ThePaths.m_carPathConnections[closestLink + pCurNode->firstLink];
}
pVehicle->AutoPilot.m_nCurrentPathNodeInfo = curConnection;
pVehicle->AutoPilot.m_nCurrentDirection = (ThePaths.ConnectedNode(curLink + pCurNode->firstLink) >= pVehicle->AutoPilot.m_nCurrentRouteNode) ? 1 : -1;
@@ -2656,6 +3167,8 @@ void CCarCtrl::GenerateEmergencyServicesCar(void)
{
if (FindPlayerPed()->m_pWanted->m_nWantedLevel > 3)
return;
+ if (CGame::IsInInterior())
+ return;
if (NumFiretrucksOnDuty + NumAmbulancesOnDuty + NumParkedCars + NumMissionCars +
NumLawEnforcerCars + NumRandomCars > MaxNumberOfCarsInUse)
return;
@@ -2708,12 +3221,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;
}
@@ -2727,7 +3242,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);
@@ -2772,18 +3287,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;
}
}
@@ -2801,7 +3322,7 @@ void CCarCtrl::UpdateCarCount(CVehicle* pVehicle, bool remove)
++NumParkedCars;
return;
case PERMANENT_VEHICLE:
- ++NumPermanentCars;;
+ ++NumPermanentCars;
return;
}
}
@@ -2809,12 +3330,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..29471608 100644
--- a/src/control/Curves.cpp
+++ b/src/control/Curves.cpp
@@ -2,6 +2,8 @@
#include "Curves.h"
+//--MIAMI: file done
+
float CCurves::CalcSpeedScaleFactor(CVector* pPoint1, CVector* pPoint2, float dir1X, float dir1Y, float dir2X, float dir2Y)
{
CVector2D dir1(dir1X, dir1Y);
@@ -11,7 +13,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 +21,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 afdfcb82..722ebbcd 100644
--- a/src/control/Darkel.cpp
+++ b/src/control/Darkel.cpp
@@ -7,15 +7,16 @@
#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"
+
+//--MIAMI: file done
#define FRENZY_ANY_PED -1
#define FRENZY_ANY_CAR -2
@@ -26,9 +27,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 +62,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:
{
@@ -75,13 +76,13 @@ CDarkel::DrawMessages()
CFont::SetCentreSize(SCREEN_SCALE_X(610.0f));
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) {
CFont::SetScale(SCREEN_SCALE_X(1.3f), SCREEN_SCALE_Y(1.3f));
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);
}
@@ -91,7 +92,7 @@ CDarkel::DrawMessages()
CFont::SetScale(SCREEN_SCALE_X(1.3f), SCREEN_SCALE_Y(1.3f));
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);
}
@@ -101,43 +102,37 @@ 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));
CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(35.0f), SCREEN_SCALE_Y(109.0f), gUString);
- CFont::SetColor(CRGBA(150, 100, 255, 255));
+ 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
- CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(35.0f), SCREEN_SCALE_Y(DARKEL_COUNTER_HEIGHT + 1.0f), gUString);
- 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();
CFont::SetCentreSize(SCREEN_SCALE_X(620.0f));
CFont::SetCentreOn();
CFont::SetScale(SCREEN_SCALE_X(1.5f), SCREEN_SCALE_Y(1.5f));
CFont::SetJustifyOff();
CFont::SetColor(CRGBA(128, 255, 128, CalcFade(timePassedSinceStart, 0, 5000)));
- CFont::SetFontStyle(FONT_BANK);
+ CFont::SetFontStyle(FONT_STANDARD);
int y = SCREEN_HEIGHT / 2 + SCREEN_SCALE_Y(25.0f - timePassedSinceStart * 0.01f);
CFont::PrintString(SCREEN_WIDTH / 2, y, TheText.Get("KF_3"));
}
@@ -190,7 +185,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
@@ -249,28 +257,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;
@@ -300,16 +294,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();
}
}
@@ -345,24 +347,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);
@@ -379,25 +364,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 59c75dd4..e7f7d525 100644
--- a/src/control/GameLogic.cpp
+++ b/src/control/GameLogic.cpp
@@ -19,14 +19,45 @@
#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"
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;
+
+//--MIAMI: file done
+
+#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 +90,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();
}
@@ -71,7 +105,9 @@ CGameLogic::Update()
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 +138,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();
}
@@ -129,17 +165,20 @@ CGameLogic::Update()
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 +190,35 @@ CGameLogic::Update()
TheCamera.SetFadeColour(0, 0, 0);
TheCamera.Fade(2.0f, FADE_OUT);
}
+
+
+ if (!CTheScripts::IsPlayerOnAMission() && pPlayerInfo.m_nBustedAudioStatus == 0) {
+ 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;
@@ -211,18 +274,21 @@ CGameLogic::Update()
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:
@@ -267,7 +333,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 +348,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 +367,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);
pPlayerPed->RestoreHeadingRate();
+ CGame::currArea = AREA_MAIN_MAP;
+ CStreaming::RemoveBuildingsNotInArea(0);
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, 0);
+ 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, 1);
+ 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
+ NumAfterDeathStartPoints = ReadSaveBuf<uint32>(buf);
+ for (int i = 0; i < NUM_SHORTCUT_START_POINTS; i++) {
+ AfterDeathStartPoints[i].x = ReadSaveBuf<float>(buf);
+ AfterDeathStartPoints[i].y = ReadSaveBuf<float>(buf);
+ AfterDeathStartPoints[i].z = ReadSaveBuf<float>(buf);
+ AfterDeathStartPointOrientation[i] = ReadSaveBuf<float>(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 07fc0612..61c1a8fc 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"
@@ -25,6 +24,8 @@
#include "Wanted.h"
#include "World.h"
+//--MIAMI: file done
+
#define CRUSHER_GARAGE_X1 (1135.5f)
#define CRUSHER_GARAGE_Y1 (57.0f)
#define CRUSHER_GARAGE_Z1 (-1.0f)
@@ -39,21 +40,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)
@@ -68,7 +69,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)
@@ -81,8 +82,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)
@@ -91,26 +92,23 @@
#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 }; // what is this?
+
int32 CGarages::BankVansCollected;
bool CGarages::BombsAreFree;
bool CGarages::RespraysAreFree;
@@ -126,9 +124,7 @@ 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;
@@ -150,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, 1);
- 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;
@@ -174,23 +163,30 @@ 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;
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;
@@ -200,23 +196,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;
@@ -238,7 +242,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;
@@ -259,6 +262,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;
@@ -312,10 +326,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;
}
@@ -329,11 +343,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;
@@ -341,7 +392,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);
}
@@ -355,13 +406,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;
@@ -377,19 +430,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->m_nWantedLevel != 0)
+ if (FindPlayerPed()->m_pWanted->m_nWantedLevel != 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
@@ -397,18 +451,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);
@@ -423,16 +489,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]);
}
}
@@ -440,8 +499,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) {
@@ -453,10 +514,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());
@@ -481,12 +542,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);
@@ -504,6 +561,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;
@@ -511,62 +570,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:
@@ -591,14 +660,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;
@@ -606,6 +678,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);
@@ -650,92 +724,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())) {
@@ -768,6 +760,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;
@@ -855,75 +849,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:
@@ -942,6 +867,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);
@@ -1037,6 +964,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:
{
@@ -1049,7 +985,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)) {
@@ -1065,12 +1001,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;
@@ -1079,30 +1010,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;
}
@@ -1132,6 +1052,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;
@@ -1162,8 +1084,39 @@ 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;
+ }
+ 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);
+ }
+ 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;
}
@@ -1173,15 +1126,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 ||
@@ -1192,35 +1145,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;
+ return true;
+}
+
+bool CGarage::IsPointInsideGarage(CVector pos, float m_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;
- 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::IsEntityEntirelyInside3D(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 ||
- pEntity->GetPosition().z < m_fZ1 - fMargin || pEntity->GetPosition().z > m_fZ2 + 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;
@@ -1228,15 +1204,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;
@@ -1245,8 +1220,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()
@@ -1256,20 +1238,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;
@@ -1281,9 +1261,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;
@@ -1302,15 +1280,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();
@@ -1324,9 +1322,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;
}
}
@@ -1346,9 +1342,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;
}
}
@@ -1363,9 +1357,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;
@@ -1380,14 +1372,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
}
}
@@ -1397,40 +1387,33 @@ void CGarage::RemoveCarsBlockingDoorNotInside()
void CGarages::PrintMessages()
{
if (CTimer::GetTimeInMilliseconds() > MessageStartTime && CTimer::GetTimeInMilliseconds() < MessageEndTime) {
- CFont::SetScale(SCREEN_SCALE_X(1.2f), SCREEN_SCALE_Y(1.5f)); // BUG: game doesn't use macro here.
+ CFont::DrawFonts();
+ CFont::SetScale(SCREEN_SCALE_X(1.2f), SCREEN_SCALE_Y(1.5f));
CFont::SetPropOn();
CFont::SetJustifyOff();
CFont::SetBackgroundOff();
CFont::SetCentreSize(SCREEN_SCALE_X(590.0f));
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(GTA_PS2) || defined (FIX_BUGS)
- float y_offset = SCREEN_HEIGHT / 3; // THIS is PS2 calculation
+ float y_offset = SCREEN_HEIGHT / 3 - SCREEN_SCALE_Y(40.0f); // 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
if (MessageNumberInString2 >= 0) {
CMessages::InsertNumberInString(TheText.Get(MessageIDString), MessageNumberInString, MessageNumberInString2, -1, -1, -1, -1, gUString);
- CFont::PrintString(SCREEN_WIDTH / 2 + SCREEN_SCALE_X(2.0f), y_offset - SCREEN_SCALE_Y(40.0f) + SCREEN_SCALE_Y(2.0f), gUString);
-
- CFont::SetColor(CRGBA(89, 115, 150, 255));
- CFont::PrintString(SCREEN_WIDTH / 2, y_offset - SCREEN_SCALE_Y(40.0f), gUString);
+ 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);
-
- CFont::PrintString(SCREEN_WIDTH / 2 + SCREEN_SCALE_X(2.0f), y_offset - SCREEN_SCALE_Y(40.0f) + SCREEN_SCALE_Y(2.0f), gUString);
-
- CFont::SetColor(CRGBA(89, 115, 150, 255));
- CFont::PrintString(SCREEN_WIDTH / 2, y_offset - SCREEN_SCALE_Y(40.0f), gUString);
+ CFont::PrintString(SCREEN_WIDTH / 2, y_offset - SCREEN_SCALE_Y(30.0f), gUString);
}
else {
- CFont::PrintString(SCREEN_WIDTH / 2 - SCREEN_SCALE_X(2.0f), y_offset - SCREEN_SCALE_Y(2.0f), TheText.Get(MessageIDString));
-
- CFont::SetColor(CRGBA(89, 115, 150, 255));
CFont::PrintString(SCREEN_WIDTH / 2, y_offset, TheText.Get(MessageIDString));
}
}
@@ -1448,6 +1431,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;
@@ -1460,15 +1446,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();
}
@@ -1578,11 +1576,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;
}
@@ -1634,11 +1633,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;
@@ -1646,11 +1643,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;
@@ -1658,12 +1653,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)
@@ -1696,16 +1689,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);
@@ -1726,10 +1719,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()));
+ int xend = Min(NUMSECTORS_X - 1, CWorld::GetSectorIndexX(m_fSupX));
+ int ystart = Max(0, CWorld::GetSectorIndexY(GetGarageCenterY()));
+ int yend = Min(NUMSECTORS_Y - 1, CWorld::GetSectorIndexY(m_fSupY));
assert(xstart <= xend);
assert(ystart <= yend);
@@ -1744,20 +1737,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)
@@ -1770,29 +1765,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)
+ if (!IsPointInsideGarage(pEntity->GetPosition(), 2.0f))
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;
- continue;
- }
if (!m_pDoor1) {
m_pDoor1 = pEntity;
m_bDoor1IsDummy = dummy;
@@ -1827,6 +1801,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)
@@ -1859,8 +1835,8 @@ void CStoredCar::StoreCar(CVehicle* pVehicle)
m_bExplosionproof = pVehicle->bExplosionProof;
m_bCollisionproof = pVehicle->bCollisionProof;
m_bMeleeproof = pVehicle->bMeleeProof;
- 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()
@@ -1876,15 +1852,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;
@@ -1895,9 +1873,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
@@ -1925,9 +1901,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);
@@ -1962,24 +1936,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;
}
@@ -1994,8 +1967,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)
@@ -2008,14 +1986,12 @@ void CGarage::TidyUpGarage()
uint32 i = CPools::GetVehiclePool()->GetSize();
while (i--) {
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;
+ }
}
}
}
@@ -2026,9 +2002,9 @@ void CGarage::TidyUpGarageClose()
uint32 i = CPools::GetVehiclePool()->GetSize();
while (i--) {
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) {
@@ -2036,11 +2012,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
@@ -2056,7 +2029,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();
}
@@ -2083,6 +2060,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:
@@ -2134,39 +2122,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();
}
}
@@ -2174,46 +2149,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;
}
@@ -2223,14 +2184,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;
}
}
@@ -2239,7 +2202,11 @@ 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;
@@ -2269,12 +2236,9 @@ 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
+//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));
CloseHideOutGaragesBeforeSave();
WriteSaveBuf(buf, NumGarages);
WriteSaveBuf(buf, (uint32)BombsAreFree);
@@ -2286,15 +2250,13 @@ 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++)
WriteSaveBuf(buf, aGarages[i]);
-#ifdef FIX_GARAGE_SIZE
- VALIDATESAVEBUF(*size);
-#endif
+//VALIDATESAVEBUF(*size);
}
const CStoredCar &CStoredCar::operator=(const CStoredCar & other)
@@ -2318,12 +2280,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();
NumGarages = ReadSaveBuf<uint32>(buf);
BombsAreFree = ReadSaveBuf<uint32>(buf);
@@ -2335,16 +2294,15 @@ void CGarages::Load(uint8* buf, uint32 size)
CarTypesCollected[i] = ReadSaveBuf<uint32>(buf);
LastTimeHelpMessage = ReadSaveBuf<uint32>(buf);
for (int i = 0; i < NUM_GARAGE_STORED_CARS; i++) {
- aCarsInSafeHouse1[i] = ReadSaveBuf<CStoredCar>(buf);
- aCarsInSafeHouse2[i] = ReadSaveBuf<CStoredCar>(buf);
- aCarsInSafeHouse3[i] = ReadSaveBuf<CStoredCar>(buf);
+ for (int j = 0; j < TOTAL_HIDEOUT_GARAGES; j++) {
+ aCarsInSafeHouses[j][i] = ReadSaveBuf<CStoredCar>(buf);
+ }
}
for (int i = 0; i < NUM_GARAGES; i++) {
aGarages[i] = ReadSaveBuf<CGarage>(buf);
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)
@@ -2352,9 +2310,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;
@@ -2364,8 +2320,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 ||
@@ -2379,7 +2334,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 ||
@@ -2388,13 +2342,5 @@ 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;
}
diff --git a/src/control/Garages.h b/src/control/Garages.h
index 34b74fb6..46ae1542 100644
--- a/src/control/Garages.h
+++ b/src/control/Garages.h
@@ -42,12 +42,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
@@ -83,6 +95,7 @@ class CGarage
{
uint8 m_eGarageType;
uint8 m_eGarageState;
+ uint8 m_nMaxStoredCars;
bool field_2; // unused
bool m_bClosingWithoutTargetCar;
bool m_bDeactivated;
@@ -97,12 +110,17 @@ class CGarage
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;
@@ -114,7 +132,6 @@ class CGarage
uint32 m_nTimeToStartAction;
uint8 m_bCollectedCarsState;
CVehicle *m_pTarget;
- void* field_96; // unused
CStoredCar m_sStoredCar; // not needed
void OpenThisGarage();
@@ -123,16 +140,16 @@ class CGarage
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();
@@ -142,7 +159,6 @@ class CGarage
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);
@@ -167,17 +183,21 @@ class CGarage
void FindDoorsEntitiesSectorList(CPtrList&, bool);
void PlayerArrestedOrDied();
+ bool IsPointInsideGarage(CVector);
+ bool IsPointInsideGarage(CVector, float);
+ void ThrowCarsNearDoorOutOfGarage(CVehicle*);
+
+ int32 FindMaxNumStoredCarsForGarage() { return Min(NUM_GARAGE_STORED_CARS, m_nMaxStoredCars); }
+
friend class CGarages;
friend class cAudioManager;
friend class CCamera;
};
-VALIDATE_SIZE(CGarage, 140);
-
class CGarages
{
enum {
- MESSAGE_LENGTH = 8
+ MESSAGE_LENGTH = 8,
};
static int32 BankVansCollected;
static bool BombsAreFree;
@@ -195,9 +215,7 @@ class CGarages
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;
public:
@@ -207,7 +225,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);
@@ -239,19 +257,46 @@ public:
static bool IsModelIndexADoor(uint32 id);
static void SetFreeBombs(bool bValue) { BombsAreFree = bValue; }
static void SetFreeResprays(bool bValue) { RespraysAreFree = bValue; }
+ static void SetMaxNumStoredCarsForGarage(int16 garage, uint8 num) { aGarages[garage].m_nMaxStoredCars = num; }
private:
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; }
friend class cAudioManager;
- friend class CGarage;
-#ifdef FIX_BUGS
friend class CReplay;
-#endif
+ friend class CGarage;
};
diff --git a/src/control/OnscreenTimer.cpp b/src/control/OnscreenTimer.cpp
index d128efeb..52d00f43 100644
--- a/src/control/OnscreenTimer.cpp
+++ b/src/control/OnscreenTimer.cpp
@@ -7,28 +7,38 @@
#include "Timer.h"
#include "Script.h"
#include "OnscreenTimer.h"
+#include "Camera.h"
+
+// --MIAMI: file done
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 < ARRAY_SIZE(COnscreenCounterEntry::m_aCounterText); j++) {
+ m_sCounters[i].m_aCounterText[j] = 0;
+ }
- for(uint32 j = 0; j < 10; j++) {
- m_sEntries[i].m_aTimerText[j] = 0;
- m_sEntries[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;
+
+ for(uint32 j = 0; j < ARRAY_SIZE(COnscreenTimerEntry::m_aClockText); j++) {
+ m_sClocks[i].m_aClockText[j] = 0;
}
- m_sEntries[i].m_nType = COUNTER_DISPLAY_NUMBER;
- m_sEntries[i].m_bTimerProcessed = 0;
- m_sEntries[i].m_bCounterProcessed = 0;
+ m_sClocks[i].m_bClockProcessed = false;
+ m_sClocks[i].m_bClockGoingDown = true;
}
}
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();
}
}
}
@@ -36,8 +46,19 @@ void COnscreenTimer::Process() {
void 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;
}
}
@@ -45,111 +66,96 @@ void COnscreenTimer::ProcessForDisplay() {
}
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 = 0;
+ 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 = 0;
}
}
}
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 = 0;
+ 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 = 0;
+ m_sClocks[i].m_bClockGoingDown = true;
}
}
}
-void COnscreenTimer::AddCounter(uint32 offset, uint16 type, char* text) {
- uint32 i = 0;
- for(uint32 i = 0; i < NUMONSCREENTIMERENTRIES; i++) {
- if(m_sEntries[i].m_nCounterOffset == 0) {
- break;
- }
+void COnscreenTimer::AddCounter(uint32 offset, uint16 type, char* text, uint16 pos) {
+
+ if (m_sCounters[pos].m_aCounterText[0] != '\0')
return;
- }
- m_sEntries[i].m_nCounterOffset = offset;
+ m_sCounters[pos].m_nCounterOffset = offset;
if(text) {
- strncpy(m_sEntries[i].m_aCounterText, text, 10);
+ strncpy(m_sCounters[pos].m_aCounterText, text, ARRAY_SIZE(COnscreenCounterEntry::m_aCounterText));
} else {
- m_sEntries[i].m_aCounterText[0] = 0;
+ m_sCounters[pos].m_aCounterText[0] = 0;
}
- m_sEntries[i].m_nType = type;
+ m_sCounters[pos].m_nType = type;
}
-void COnscreenTimer::AddClock(uint32 offset, char* text) {
- uint32 i = 0;
- for(uint32 i = 0; i < NUMONSCREENTIMERENTRIES; i++) {
- if(m_sEntries[i].m_nTimerOffset == 0) {
+void COnscreenTimer::AddClock(uint32 offset, char* text, bool bGoingDown) {
+
+ // dead code in here
+ uint32 i;
+ for(i = 0; i < NUMONSCREENCLOCKS; i++) {
+ if(m_sClocks[i].m_nClockOffset == 0) {
break;
}
return;
}
- m_sEntries[i].m_nTimerOffset = offset;
+ m_sClocks[i].m_nClockOffset = offset;
+ m_sClocks[i].m_bClockGoingDown = bGoingDown;
if(text) {
- strncpy(m_sEntries[i].m_aTimerText, text, 10);
+ strncpy(m_sClocks[i].m_aClockText, text, ARRAY_SIZE(COnscreenTimerEntry::m_aClockText));
} else {
- m_sEntries[i].m_aTimerText[0] = 0;
+ m_sClocks[i].m_aClockText[0] = 0;
}
}
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::GetTimeStepInSeconds() * 1000);
- if(newTime < 0) {
- *timerPtr = 0;
- m_bTimerProcessed = 0;
- 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() {
+void 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 49e43c81..aa453701 100644
--- a/src/control/PathFind.cpp
+++ b/src/control/PathFind.cpp
@@ -8,6 +8,8 @@
#include "Lines.h" // for debug
#include "PathFind.h"
+//--MIAMI: file done except mobile unused function
+
bool gbShowPedPaths;
bool gbShowCarPaths;
bool gbShowCarPathsLinks;
@@ -18,21 +20,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 +198,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 +228,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 +257,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 +271,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 +302,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;
+ InfoForTilePeds[i].width = 8.0f*Min(width, 15.0f);
InfoForTileCars[i].numLeftLanes = numLeft;
InfoForTileCars[i].numRightLanes = numRight;
+ InfoForTilePeds[i].crossing = false;
+ 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)
+ 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 +442,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 +467,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 +491,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 +519,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 +571,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 +602,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 +639,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 +782,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 +819,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 +838,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 +845,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 +861,7 @@ CPathFind::PreparePathDataForType(uint8 type, CTempNode *tempnodes, CPathInfoFor
mag = Sqrt(dx*dx + dy*dy);
dx /= mag;
dy /= mag;
+ int width = Max(m_pathNodes[i].width, m_pathNodes[j].width);
if(i < j){
dx = -dx;
dy = -dy;
@@ -761,20 +869,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 +894,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 +909,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 +917,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 +968,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 +980,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 +1012,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 +1035,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 +1094,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 +1106,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 +1248,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 +1270,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 +1305,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 +1472,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 +1486,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 +1530,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 +1609,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 +1666,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 +1683,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 +1710,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 +1734,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 +1753,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 +1771,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
@@ -1828,3 +1947,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..acf9929a 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...
+ int8 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;
+ int8 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;
+ int8 width;
+ bool isCross;
int8 linkState;
};
-struct CTempDetachedNode // unused
+struct CTempNodeExternal // made up name
+{
+ CVector pos;
+ int16 next;
+ int8 numLeftLanes;
+ int8 numRightLanes;
+ int8 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 4769559c..cc80360d 100644
--- a/src/control/Phones.cpp
+++ b/src/control/Phones.cpp
@@ -17,6 +17,8 @@
#include "Replay.h"
#endif
+// --MIAMI: file done
+
CPhoneInfo gPhoneInfo;
bool CPhoneInfo::bDisplayingPhoneMessage; // is phone picked up
@@ -34,17 +36,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_nLastPedState != PED_SEEK_POS &&
- (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)
{
@@ -161,14 +152,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) {
@@ -213,42 +199,8 @@ void
CPhoneInfo::Load(uint8 *buf, uint32 size)
{
INITSAVEBUF
- int max = ReadSaveBuf<int32>(buf);
- int scriptPhonesMax = ReadSaveBuf<int32>(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 = ReadSaveBuf<CPhone>(buf);
-
- 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;
-
+ m_nMax = ReadSaveBuf<int32>(buf);
+ m_nScriptPhonesMax = ReadSaveBuf<int32>(buf);
for (int i = 0; i < NUMPHONES; i++) {
m_aPhones[i] = ReadSaveBuf<CPhone>(buf);
// It's saved as building pool index in save file, convert it to true entity
@@ -256,7 +208,6 @@ INITSAVEBUF
m_aPhones[i].m_pEntity = CPools::GetBuildingPool()->GetSlot((uintptr)m_aPhones[i].m_pEntity - 1);
}
}
-#endif
VALIDATESAVEBUF(size)
}
@@ -294,31 +245,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)
{
@@ -360,7 +286,6 @@ CPhoneInfo::Initialise(void)
CBuilding *building = pool->GetSlot(i);
if (building) {
if (building->GetModelIndex() == MI_PHONEBOOTH1) {
- assert(m_nMax < ARRAY_SIZE(m_aPhones) && "NUMPHONES should be increased");
CPhone *maxPhone = &m_aPhones[m_nMax];
maxPhone->m_nState = PHONE_STATE_FREE;
maxPhone->m_vecPos = building->GetPosition();
@@ -378,11 +303,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++) {
CPhone* phone = WriteSaveBuf(buf, m_aPhones[phoneId]);
// Convert entity pointer to building pool index while saving
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 19b3d3a7..23b5d9ff 100644
--- a/src/control/Pickups.cpp
+++ b/src/control/Pickups.cpp
@@ -30,12 +30,20 @@
#include "Timer.h"
#include "WaterLevel.h"
#include "World.h"
+#include "Hud.h"
+#include "Messages.h"
+#include "Streaming.h"
+
+// --MIAMI: file done
CPickup CPickups::aPickUps[NUMPICKUPS];
int16 CPickups::NumMessages;
int32 CPickups::aPickUpsCollected[NUMCOLLECTEDPICKUPS];
int16 CPickups::CollectedPickUpIndex;
+int32 CPickups::PlayerOnWeaponPickup;
+int32 CollectPickupBuffer;
+
// unused
bool CPickups::bPickUpcamActivated;
CVehicle *CPickups::pPlayerVehicle;
@@ -44,38 +52,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)
{
- CWorld::Remove(m_pObject);
- delete m_pObject;
+ 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)
+{
+ 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;
@@ -88,14 +212,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:
@@ -124,11 +272,12 @@ CPickup::GiveUsAPickUpObject(int32 handle)
}
bool
-CPickup::CanBePickedUp(CPlayerPed *player)
+CPickup::CanBePickedUp(CPlayerPed *player, int playerId)
{
+ assert(m_pObject != nil);
bool cannotBePickedUp =
- (m_pObject->GetModelIndex() == MI_PICKUP_BODYARMOUR && player->m_fArmour > 99.5f)
- || (m_pObject->GetModelIndex() == MI_PICKUP_HEALTH && player->m_fHealth > 99.5f)
+ (m_pObject->GetModelIndex() == MI_PICKUP_BODYARMOUR && player->m_fArmour > CWorld::Players[playerId].m_nMaxArmour - 0.5f)
+ || (m_pObject->GetModelIndex() == MI_PICKUP_HEALTH && player->m_fHealth > CWorld::Players[playerId].m_nMaxHealth - 0.5f)
|| (m_pObject->GetModelIndex() == MI_PICKUP_BRIBE && player->m_pWanted->m_nWantedLevel == 0)
|| (m_pObject->GetModelIndex() == MI_PICKUP_KILLFRENZY && (CTheScripts::IsPlayerOnAMission() || CDarkel::FrenzyOnGoing() || !CGame::nastyGame));
return !cannotBePickedUp;
@@ -137,15 +286,32 @@ CPickup::CanBePickedUp(CPlayerPed *player)
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;
@@ -155,6 +321,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()) {
@@ -184,37 +358,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);
@@ -224,9 +455,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
@@ -234,32 +465,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);
@@ -276,6 +512,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;
@@ -304,7 +573,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
}
}
@@ -336,7 +605,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
}
}
@@ -371,12 +640,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;
@@ -384,6 +689,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++)
@@ -393,6 +699,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++) {
@@ -408,7 +736,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
@@ -442,22 +770,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->m_nWantedLevel - 1;
- if (level < 0) level = 0;
+ int32 level = Max(FindPlayerPed()->m_pWanted->m_nWantedLevel - 1, 0);
player->SetWantedLevel(level);
DMAudio.PlayFrontEndSound(SOUND_PICKUP_BONUS, 0);
return true;
@@ -469,23 +796,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) {
@@ -493,24 +806,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;
@@ -526,10 +845,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();
}
}
@@ -538,8 +858,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) {
@@ -550,10 +877,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);
}
@@ -576,50 +910,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
@@ -664,27 +965,46 @@ 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;
@@ -692,42 +1012,113 @@ CPickups::DoPickUpEffects(CEntity *entity)
float s = Sin((float)((CTimer::GetTimeInMilliseconds() + (uintptr)entity) & 0x7FF) * DEGTORAD(360.0f / 0x800));
float modifiedSin = 0.3f * (s + 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;
@@ -738,18 +1129,76 @@ 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++;
}
}
}
- entity->GetMatrix().SetRotateZOnlyScaled((float)(CTimer::GetTimeInMilliseconds() & 0x7FF) * DEGTORAD(360.0f / 0x800), aWeaponScale[colorId]);
+ 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;
+
+ entity->GetMatrix().SetRotateZOnlyScaled((float)(CTimer::GetTimeInMilliseconds() & 0x7FF) * DEGTORAD(360.0f / 0x800), 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);
+ }
+ }
+
+ 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);
}
}
@@ -815,13 +1264,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");
@@ -833,135 +1286,63 @@ 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
+ const 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;
CFont::SetScale(fScaleX, fScaleY);
@@ -971,13 +1352,77 @@ CPickups::RenderPickUpText()
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
@@ -985,8 +1430,13 @@ INITSAVEBUF
for (int32 i = 0; i < NUMPICKUPS; i++) {
aPickUps[i] = ReadSaveBuf<CPickup>(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);
+ }
+
}
CollectedPickUpIndex = ReadSaveBuf<uint16>(buf);
@@ -1002,14 +1452,19 @@ VALIDATESAVEBUF(size)
void
CPickups::Save(uint8 *buf, uint32 *size)
{
- *size = sizeof(aPickUps) + sizeof(uint16) + sizeof(uint16) + sizeof(aPickUpsCollected);
+ *size = sizeof(aPickUps);
+ *size += sizeof(uint16) + sizeof(uint16) + sizeof(aPickUpsCollected);
INITSAVEBUF
for (int32 i = 0; i < NUMPICKUPS; i++) {
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);
+ }
}
WriteSaveBuf(buf, CollectedPickUpIndex);
@@ -1024,40 +1479,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;
@@ -1071,96 +1492,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
@@ -1170,269 +1511,72 @@ 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;
-
- 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);
}
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;
- }
}
+// --MIAMI: Done
void
CPed::CreateDeadPedMoney(void)
{
@@ -1441,54 +1585,62 @@ 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;
}
+// --MIAMI: Done
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();
+}
+
+// --MIAMI: Done
+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;
@@ -1496,21 +1648,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 72a37d99..af9503e0 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..d3e48647 100644
--- a/src/control/Record.cpp
+++ b/src/control/Record.cpp
@@ -9,386 +9,64 @@
#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;
+//--MIAMI: file done
-#define MEMORY_FOR_GAME_RECORD (150000)
+uint16 CRecordDataForGame::RecordingState;
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)
@@ -405,125 +83,34 @@ bool CRecordDataForChase::ShouldThisPadBeLeftAlone(uint8 pad)
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..164a2f4c 100644
--- a/src/control/Remote.cpp
+++ b/src/control/Remote.cpp
@@ -9,6 +9,8 @@
#include "PlayerInfo.h"
#include "Vehicle.h"
+//--MIAMI: file done
+
void
CRemote::GivePlayerRemoteControlledCar(float x, float y, float z, float rot, uint16 model)
{
@@ -35,17 +37,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 d9e5e675..8d28970f 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,10 @@
#include "Text.h"
#include "Camera.h"
#include "Radar.h"
+#include "Fluff.h"
+#include "WaterCreatures.h"
+
+//--MIAMI: file done
uint8 CReplay::Mode;
CAddressInReplayBuffer CReplay::Record;
@@ -55,7 +63,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 +117,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 +151,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 +255,7 @@ void CReplay::Init(void)
SlowMotion = 1;
FramesActiveLookAroundCam = 0;
bDoLoadSceneWhenDone = false;
+ MarkEverythingAsNew();
}
void CReplay::DisableReplays(void)
@@ -236,8 +271,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 +305,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 +332,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 +358,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 +387,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 +415,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 +447,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 +467,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 +493,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 +512,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 +528,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 +538,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 +555,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 +577,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 +588,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 <= 3)
+ 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_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 +631,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 > 3) ? (AssocGroupId)state->secGroupId : ped->m_animGroup,
(AnimationId)state->secAnimId, 100.0f);
anim2->SetCurrentTime(time);
anim2->speed = speed;
@@ -558,9 +643,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_IDLE_STANCE){
+ if (blend > 0.0f && state->partAnimId != ANIM_IDLE_STANCE && 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 +655,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] == NUM_ANIMS)
continue;
-#ifdef FIX_REPLAY_BUGS
CAnimBlendAssociation* anim = CAnimManager::AddAnimation(ped->GetClump(),
- state->aAnimId[i] > 3 ? ASSOCGRP_STD : ped->m_animGroup,
+ state->aAnimId[i] > 3 ? (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 +681,12 @@ void CReplay::RetrieveDetailedPedAnimation(CPed *ped, CStoredDetailedAnimationSt
for (int i = 0; i < NUM_PARTIAL_ANIMS_IN_REPLAY; i++) {
if (state->aAnimId2[i] == NUM_ANIMS)
continue;
-#ifdef FIX_REPLAY_BUGS
CAnimBlendAssociation* anim = CAnimManager::AddAnimation(ped->GetClump(),
- state->aAnimId2[i] > 3 ? ASSOCGRP_STD : ped->m_animGroup,
+ state->aAnimId2[i] > 3 ? (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 +725,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 +778,38 @@ 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;
+ 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];
+ }
+ 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 +878,46 @@ 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;
-#endif
+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;
+ 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);
+ // NB: technically last assignment overflows - there are 2 wheels of bike
+ // however it saves two useful fields; this looks like unrolled loop, not sequential assignments
+ }
+ 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 +963,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 +994,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 +1116,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 +1252,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 +1270,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 +1304,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 +1319,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 +1358,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 +1387,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 +1396,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 +1451,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 +1481,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_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);
+ }
+ else if (vehicle->IsRealHeli()) {
+ 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 +1547,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 +1558,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 +1576,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 +1603,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 +1616,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 +1755,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 +1854,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 +1863,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;
@@ -1621,7 +1883,7 @@ void CReplay::Display()
CFont::SetScale(SCREEN_SCALE_X(1.5f), SCREEN_SCALE_Y(1.5f));
CFont::SetAlignment(ALIGN_LEFT);
CFont::SetColor(CRGBA(255, 255, 200, 200));
- CFont::SetFontStyle(FONT_BANK);
+ CFont::SetFontStyle(FONT_STANDARD);
if (Mode == MODE_PLAYBACK)
CFont::PrintString(SCREEN_SCALE_X(63.5f), SCREEN_SCALE_Y(30.0f), TheText.Get("REPLAY"));
}
diff --git a/src/control/Replay.h b/src/control/Replay.h
index aa2ecd86..84a6bef0 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];
};
void PlayReplayFromHD(void);
@@ -78,21 +81,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 {
@@ -181,8 +187,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);
@@ -208,8 +215,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;
@@ -220,7 +284,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;
@@ -274,12 +338,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
@@ -293,6 +377,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; }
@@ -314,7 +399,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);
@@ -326,6 +413,7 @@ private:
static void FindFirstFocusCoordinate(CVector *coord);
static void ProcessLookAroundCam(void);
static size_t FindSizeOfPacket(uint8);
+ static void GoToNextBlock(void);
/* Absolute nonsense, but how could this function end up being outside of class? */
friend void PlayReplayFromHD(void);
diff --git a/src/control/Restart.cpp b/src/control/Restart.cpp
index 4ca18c3b..f63d2c07 100644
--- a/src/control/Restart.cpp
+++ b/src/control/Restart.cpp
@@ -4,6 +4,8 @@
#include "Zones.h"
#include "PathFind.h"
+//--MIAMI: file done
+
uint8 CRestart::OverrideHospitalLevel;
uint8 CRestart::OverridePoliceStationLevel;
bool CRestart::bFadeInAfterNextArrest;
@@ -80,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;
@@ -127,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 170c5ff8..260978b3 100644
--- a/src/control/RoadBlocks.cpp
+++ b/src/control/RoadBlocks.cpp
@@ -14,23 +14,28 @@
#include "Camera.h"
#include "CarCtrl.h"
#include "General.h"
+#include "Object.h"
-#define ROADBLOCKDIST (80.0f)
+//--MIAMI: file done
+
+#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];
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 +46,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] = { {-1.5, 1.8f, 0.0f}, {-1.5f, -1.8f, 0.0f}, {1.5f, 1.8f, 0.0f},
{1.5f, -1.8f, 0.0f}, {-1.5f, 0.0f, 0.0f}, {1.5, 0.0, 0.0} };
@@ -60,7 +67,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;
@@ -80,15 +87,15 @@ CRoadBlocks::GenerateRoadBlockCopsForCar(CVehicle* pVehicle, int32 roadBlockType
pCopPed->SetCurrentWeapon(WEAPONTYPE_COLT45);
CPedPlacement::FindZCoorForPed(&posForZ);
pCopPed->SetPosition(posForZ);
- CVector vecSavedPos = pCopPed->GetPosition();
- pCopPed->m_matrix.SetRotate(0.0f, 0.0f, -HALFPI);
- pCopPed->m_matrix.GetPosition() += vecSavedPos;
+ pCopPed->SetOrientation(0.0f, 0.0f, -HALFPI);
pCopPed->m_bIsDisabledCop = true;
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);
@@ -104,96 +111,179 @@ 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->m_matrix * 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->m_matrix = vehicleMatrix;
- pVehicle->PlaceOnRoadProperly();
- pVehicle->SetIsStatic(false);
- pVehicle->m_matrix.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)
+{
+ 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->m_matrix = tmp;
+ pVehicle->PlaceOnRoadProperly();
+ pVehicle->SetIsStatic(false);
+ pVehicle->m_matrix.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 8224c1d4..582f7a12 100644
--- a/src/control/SceneEdit.cpp
+++ b/src/control/SceneEdit.cpp
@@ -20,6 +20,8 @@
#include "WeaponInfo.h"
#include "World.h"
+//--MIAMI: file done
+
bool CSceneEdit::m_bEditOn;
int32 CSceneEdit::m_bCameraFollowActor;
bool CSceneEdit::m_bRecording;
@@ -88,7 +90,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 +271,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);
@@ -292,7 +294,7 @@ void CSceneEdit::Draw(void)
CFont::SetCentreOff();
CFont::SetScale(SCREEN_SCALE_X(0.7f), SCREEN_SCALE_Y(0.7f));
#ifdef FIX_BUGS
- CFont::SetFontStyle(FONT_BANK);
+ CFont::SetFontStyle(FONT_STANDARD);
#else
CFont::SetFontStyle(FONT_HEADING);
#endif
@@ -1070,7 +1072,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);
@@ -1078,7 +1080,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 67d2e618..5ff5a383 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,19 +37,30 @@
#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
+//--MIAMI: file done
+
uint8 CTheScripts::ScriptSpace[SIZE_SCRIPT_SPACE];
CRunningScript CTheScripts::ScriptsArray[MAX_NUM_SCRIPTS];
-int32 CTheScripts::BaseBriefIdForContact[MAX_NUM_CONTACTS];
-int32 CTheScripts::OnAMissionForContactFlag[MAX_NUM_CONTACTS];
intro_text_line CTheScripts::IntroTextLines[MAX_NUM_INTRO_TEXT_LINES];
intro_script_rectangle CTheScripts::IntroRectangles[MAX_NUM_INTRO_RECTANGLES];
CSprite2d CTheScripts::ScriptSprites[MAX_NUM_SCRIPT_SRPITES];
script_sphere_struct CTheScripts::ScriptSphereArray[MAX_NUM_SCRIPT_SPHERES];
-tCollectiveData CTheScripts::CollectiveArray[MAX_NUM_COLLECTIVES];
tUsedObject CTheScripts::UsedObjectArray[MAX_NUM_USED_OBJECTS];
int32 CTheScripts::MultiScriptArray[MAX_NUM_MISSION_SCRIPTS];
tBuildingSwap CTheScripts::BuildingSwapArray[MAX_NUM_BUILDING_SWAPS];
@@ -67,8 +81,6 @@ uint16 CTheScripts::NumberOfMissionScripts;
uint32 CTheScripts::LargestMissionScriptSize;
uint32 CTheScripts::MainScriptSize;
uint8 CTheScripts::FailCurrentMission;
-uint8 CTheScripts::CountdownToMakePlayerUnsafe;
-uint8 CTheScripts::DelayMakingPlayerUnsafeThisTime;
uint16 CTheScripts::NumScriptDebugLines;
uint16 CTheScripts::NumberOfIntroRectanglesThisFrame;
uint16 CTheScripts::NumberOfIntroTextLinesThisFrame;
@@ -79,6 +91,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
@@ -109,6 +130,9 @@ float oldTargetX;
float oldTargetY;
int missionRetryScriptIndex;
bool doingMissionRetry;
+bool gbTryingPorn4Again;
+int IsInAmmunation;
+int MissionSkipLevel;
#endif
@@ -335,947 +359,1257 @@ const tScriptCommandData commands[] = {
REGISTER_COMMAND(COMMAND_ANDOR, INPUT_ARGUMENTS(ARGTYPE_ANDOR,), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_LAUNCH_MISSION, INPUT_ARGUMENTS(ARGTYPE_LABEL,), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_MISSION_HAS_FINISHED, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_STORE_CAR_CHAR_IS_IN, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_STORE_CAR_PLAYER_IS_IN, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_CHAR_IN_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_PLAYER_IN_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_CHAR_IN_MODEL, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_PLAYER_IN_MODEL, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_CHAR_IN_ANY_CAR, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_PLAYER_IN_ANY_CAR, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_BUTTON_PRESSED, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_GET_PAD_STATE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_LOCATE_PLAYER_ANY_MEANS_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_LOCATE_PLAYER_ON_FOOT_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_LOCATE_PLAYER_IN_CAR_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_LOCATE_STOPPED_PLAYER_ANY_MEANS_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_LOCATE_STOPPED_PLAYER_ON_FOOT_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_LOCATE_STOPPED_PLAYER_IN_CAR_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_LOCATE_PLAYER_ANY_MEANS_CHAR_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_LOCATE_PLAYER_ON_FOOT_CHAR_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_LOCATE_PLAYER_IN_CAR_CHAR_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_LOCATE_CHAR_ANY_MEANS_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_LOCATE_CHAR_ON_FOOT_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_LOCATE_CHAR_IN_CAR_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_LOCATE_STOPPED_CHAR_ANY_MEANS_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_LOCATE_STOPPED_CHAR_ON_FOOT_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_LOCATE_STOPPED_CHAR_IN_CAR_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_LOCATE_CHAR_ANY_MEANS_CHAR_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_LOCATE_CHAR_ON_FOOT_CHAR_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_LOCATE_CHAR_IN_CAR_CHAR_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_LOCATE_PLAYER_ANY_MEANS_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_LOCATE_PLAYER_ON_FOOT_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_LOCATE_PLAYER_IN_CAR_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_LOCATE_STOPPED_PLAYER_ANY_MEANS_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_LOCATE_STOPPED_PLAYER_ON_FOOT_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_LOCATE_STOPPED_PLAYER_IN_CAR_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_LOCATE_PLAYER_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_PLAYER_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_PLAYER_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_LOCATE_CHAR_ANY_MEANS_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_LOCATE_CHAR_ON_FOOT_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_LOCATE_CHAR_IN_CAR_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_LOCATE_STOPPED_CHAR_ANY_MEANS_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_LOCATE_STOPPED_CHAR_ON_FOOT_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_LOCATE_STOPPED_CHAR_IN_CAR_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_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_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, ""),
- REGISTER_COMMAND(COMMAND_STORE_SCORE, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_GIVE_REMOTE_CONTROLLED_CAR_TO_PLAYER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_ALTER_WANTED_LEVEL, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_ALTER_WANTED_LEVEL_NO_DROP, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_WANTED_LEVEL_GREATER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_CLEAR_WANTED_LEVEL, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_DEATHARREST_STATE, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_STORE_CAR_CHAR_IS_IN, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_STORE_CAR_PLAYER_IS_IN, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_CHAR_IN_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_PLAYER_IN_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_CHAR_IN_MODEL, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_PLAYER_IN_MODEL, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_CHAR_IN_ANY_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_PLAYER_IN_ANY_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_BUTTON_PRESSED, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_PAD_STATE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_LOCATE_PLAYER_ANY_MEANS_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_LOCATE_PLAYER_ON_FOOT_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_LOCATE_PLAYER_IN_CAR_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_LOCATE_STOPPED_PLAYER_ANY_MEANS_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_LOCATE_STOPPED_PLAYER_ON_FOOT_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_LOCATE_STOPPED_PLAYER_IN_CAR_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_LOCATE_PLAYER_ANY_MEANS_CHAR_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_LOCATE_PLAYER_ON_FOOT_CHAR_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_LOCATE_PLAYER_IN_CAR_CHAR_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_LOCATE_CHAR_ANY_MEANS_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_LOCATE_CHAR_ON_FOOT_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_LOCATE_CHAR_IN_CAR_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_LOCATE_STOPPED_CHAR_ANY_MEANS_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_LOCATE_STOPPED_CHAR_ON_FOOT_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_LOCATE_STOPPED_CHAR_IN_CAR_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_LOCATE_CHAR_ANY_MEANS_CHAR_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_LOCATE_CHAR_ON_FOOT_CHAR_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_LOCATE_CHAR_IN_CAR_CHAR_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_LOCATE_PLAYER_ANY_MEANS_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_LOCATE_PLAYER_ON_FOOT_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_LOCATE_PLAYER_IN_CAR_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_LOCATE_STOPPED_PLAYER_ANY_MEANS_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_LOCATE_STOPPED_PLAYER_ON_FOOT_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_LOCATE_STOPPED_PLAYER_IN_CAR_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_LOCATE_PLAYER_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_PLAYER_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_PLAYER_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_LOCATE_CHAR_ANY_MEANS_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_LOCATE_CHAR_ON_FOOT_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_LOCATE_CHAR_IN_CAR_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_LOCATE_STOPPED_CHAR_ANY_MEANS_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_LOCATE_STOPPED_CHAR_ON_FOOT_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_LOCATE_STOPPED_CHAR_IN_CAR_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_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, ), 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, ""),
+ REGISTER_COMMAND(COMMAND_STORE_SCORE, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_GIVE_REMOTE_CONTROLLED_CAR_TO_PLAYER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ALTER_WANTED_LEVEL, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ALTER_WANTED_LEVEL_NO_DROP, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_WANTED_LEVEL_GREATER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_CLEAR_WANTED_LEVEL, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_DEATHARREST_STATE, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_HAS_DEATHARREST_BEEN_EXECUTED, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_ADD_AMMO_TO_PLAYER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_ADD_AMMO_TO_CHAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_ADD_AMMO_TO_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_PLAYER_STILL_ALIVE, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_PLAYER_DEAD, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_CHAR_DEAD, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_CAR_DEAD, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CHAR_THREAT_SEARCH, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CHAR_THREAT_REACTION, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_NO_OBJ, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_ORDER_DRIVER_OUT_OF_CAR, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_ORDER_CHAR_TO_DRIVE_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_ADD_PATROL_POINT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_PLAYER_IN_GANGZONE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_PLAYER_IN_ZONE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_STRING,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_PLAYER_PRESSING_HORN, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_HAS_CHAR_SPOTTED_PLAYER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_ORDER_CHAR_TO_BACKDOOR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_ADD_CHAR_TO_GANG, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_CHAR_OBJECTIVE_PASSED, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CHAR_DRIVE_AGGRESSION, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CHAR_MAX_DRIVESPEED, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_CREATE_CHAR_INSIDE_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_WARP_PLAYER_FROM_CAR_TO_COORD, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_MAKE_CHAR_DO_NOTHING, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CHAR_INVINCIBLE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_PLAYER_INVINCIBLE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CHAR_GRAPHIC_TYPE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_PLAYER_GRAPHIC_TYPE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_HAS_PLAYER_BEEN_ARRESTED, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_STOP_CHAR_DRIVING, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_KILL_CHAR, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_FAVOURITE_CAR_MODEL_FOR_CHAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CHAR_OCCUPATION, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_CHANGE_CAR_LOCK, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SHAKE_CAM_WITH_POINT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_CAR_MODEL, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_CAR_REMAP, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_HAS_CAR_JUST_SUNK, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CAR_NO_COLLIDE, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_CAR_DEAD_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_CAR_DEAD_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_IS_TRAILER_ATTACHED, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_CAR_ON_TRAILER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_HAS_CAR_GOT_WEAPON, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_PARK, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ADD_AMMO_TO_PLAYER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ADD_AMMO_TO_CHAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ADD_AMMO_TO_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_PLAYER_STILL_ALIVE, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_PLAYER_DEAD, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_CHAR_DEAD, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_CAR_DEAD, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_THREAT_SEARCH, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_THREAT_REACTION, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_NO_OBJ, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ORDER_DRIVER_OUT_OF_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ORDER_CHAR_TO_DRIVE_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ADD_PATROL_POINT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_PLAYER_IN_GANGZONE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_PLAYER_IN_ZONE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_STRING, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_PLAYER_PRESSING_HORN, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_HAS_CHAR_SPOTTED_PLAYER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_ORDER_CHAR_TO_BACKDOOR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ADD_CHAR_TO_GANG, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_CHAR_OBJECTIVE_PASSED, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_DRIVE_AGGRESSION, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_MAX_DRIVESPEED, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_CREATE_CHAR_INSIDE_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_WARP_PLAYER_FROM_CAR_TO_COORD, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_MAKE_CHAR_DO_NOTHING, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_INVINCIBLE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_PLAYER_INVINCIBLE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_GRAPHIC_TYPE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_PLAYER_GRAPHIC_TYPE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_HAS_PLAYER_BEEN_ARRESTED, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_STOP_CHAR_DRIVING, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_KILL_CHAR, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_FAVOURITE_CAR_MODEL_FOR_CHAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_OCCUPATION, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_CHANGE_CAR_LOCK, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SHAKE_CAM_WITH_POINT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_CAR_MODEL, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_CAR_REMAP, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_HAS_CAR_JUST_SUNK, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CAR_NO_COLLIDE, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_CAR_DEAD_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_CAR_DEAD_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_IS_TRAILER_ATTACHED, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_CAR_ON_TRAILER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_HAS_CAR_GOT_WEAPON, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_PARK, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_HAS_PARK_FINISHED, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_KILL_ALL_PASSENGERS, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CAR_BULLETPROOF, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CAR_FLAMEPROOF, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CAR_ROCKETPROOF, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_CARBOMB_ACTIVE, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_GIVE_CAR_ALARM, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_PUT_CAR_ON_TRAILER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_CAR_CRUSHED, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- 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_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_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, ""),
- REGISTER_COMMAND(COMMAND_SET_PED_DENSITY, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_POINT_CAMERA_AT_PLAYER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_POINT_CAMERA_AT_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_POINT_CAMERA_AT_CHAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_KILL_ALL_PASSENGERS, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CAR_BULLETPROOF, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CAR_FLAMEPROOF, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CAR_ROCKETPROOF, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_CARBOMB_ACTIVE, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_GIVE_CAR_ALARM, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_PUT_CAR_ON_TRAILER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_CAR_CRUSHED, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ 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(), 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, ), 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, ""),
+ REGISTER_COMMAND(COMMAND_SET_PED_DENSITY, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_POINT_CAMERA_AT_PLAYER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_POINT_CAMERA_AT_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ 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_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, ""),
- REGISTER_COMMAND(COMMAND_POINT_CAMERA_AT_POINT, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_ADD_BLIP_FOR_CAR_OLD, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_ADD_BLIP_FOR_CHAR_OLD, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_ADD_BLIP_FOR_OBJECT_OLD, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_REMOVE_BLIP, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_CHANGE_BLIP_COLOUR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_DIM_BLIP, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_ADD_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_CHANGE_BLIP_SCALE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_FADING_COLOUR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_DO_FADE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), 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, 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, ""),
+ REGISTER_COMMAND(COMMAND_POINT_CAMERA_AT_POINT, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ADD_BLIP_FOR_CAR_OLD, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ADD_BLIP_FOR_CHAR_OLD, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ADD_BLIP_FOR_OBJECT_OLD, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_REMOVE_BLIP, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_CHANGE_BLIP_COLOUR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_DIM_BLIP, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ADD_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_CHANGE_BLIP_SCALE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_FADING_COLOUR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_DO_FADE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_GET_FADING_STATUS, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_ADD_HOSPITAL_RESTART, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_ADD_POLICE_RESTART, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_OVERRIDE_NEXT_RESTART, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_DRAW_SHADOW, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_GET_PLAYER_HEADING, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_PLAYER_HEADING, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_GET_CHAR_HEADING, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CHAR_HEADING, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_GET_CAR_HEADING, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CAR_HEADING, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_GET_OBJECT_HEADING, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_OBJECT_HEADING, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_PLAYER_TOUCHING_OBJECT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_CHAR_TOUCHING_OBJECT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_PLAYER_AMMO, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CHAR_AMMO, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CAR_AMMO, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_LOAD_CAMERA_SPLINE, INPUT_ARGUMENTS(ARGTYPE_STRING,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_MOVE_CAMERA_ALONG_SPLINE, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_GET_CAMERA_POSITION_ALONG_SPLINE, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_DECLARE_MISSION_FLAG, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_DECLARE_MISSION_FLAG_FOR_CONTACT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_DECLARE_BASE_BRIEF_ID_FOR_CONTACT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_PLAYER_HEALTH_GREATER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_CHAR_HEALTH_GREATER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_CAR_HEALTH_GREATER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_ADD_BLIP_FOR_CAR, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_ADD_BLIP_FOR_CHAR, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_ADD_BLIP_FOR_OBJECT, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_ADD_BLIP_FOR_CONTACT_POINT, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_ADD_BLIP_FOR_COORD, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_CHANGE_BLIP_DISPLAY, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_ADD_ONE_OFF_SOUND, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_ADD_CONTINUOUS_SOUND, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_REMOVE_SOUND, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_CAR_STUCK_ON_ROOF, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_ADD_UPSIDEDOWN_CAR_CHECK, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_REMOVE_UPSIDEDOWN_CAR_CHECK, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_WAIT_ON_FOOT, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_FLEE_ON_FOOT_TILL_SAFE, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_GUARD_SPOT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_GUARD_AREA, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_WAIT_IN_CAR, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_PLAYER_IN_AREA_ON_FOOT_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_PLAYER_IN_AREA_IN_CAR_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_PLAYER_STOPPED_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_PLAYER_STOPPED_IN_AREA_ON_FOOT_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_PLAYER_STOPPED_IN_AREA_IN_CAR_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_PLAYER_IN_AREA_ON_FOOT_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_PLAYER_IN_AREA_IN_CAR_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_PLAYER_STOPPED_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_IS_PLAYER_STOPPED_IN_AREA_ON_FOOT_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_PLAYER_STOPPED_IN_AREA_IN_CAR_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_CHAR_IN_AREA_ON_FOOT_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_CHAR_IN_AREA_IN_CAR_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_CHAR_STOPPED_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_CHAR_STOPPED_IN_AREA_ON_FOOT_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_CHAR_STOPPED_IN_AREA_IN_CAR_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_CHAR_IN_AREA_ON_FOOT_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_CHAR_IN_AREA_IN_CAR_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_CHAR_STOPPED_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_IS_CHAR_STOPPED_IN_AREA_ON_FOOT_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_CHAR_STOPPED_IN_AREA_IN_CAR_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_CAR_STOPPED_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_CAR_STOPPED_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_LOCATE_CAR_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_LOCATE_STOPPED_CAR_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_LOCATE_CAR_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_LOCATE_STOPPED_CAR_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_GIVE_WEAPON_TO_PLAYER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_GIVE_WEAPON_TO_CHAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_GIVE_WEAPON_TO_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_PLAYER_CONTROL, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_FORCE_WEATHER, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_FORCE_WEATHER_NOW, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ADD_HOSPITAL_RESTART, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ADD_POLICE_RESTART, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_OVERRIDE_NEXT_RESTART, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_DRAW_SHADOW, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_PLAYER_HEADING, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_PLAYER_HEADING, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_CHAR_HEADING, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_HEADING, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_CAR_HEADING, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CAR_HEADING, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_OBJECT_HEADING, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_OBJECT_HEADING, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_PLAYER_TOUCHING_OBJECT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_CHAR_TOUCHING_OBJECT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_PLAYER_AMMO, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_AMMO, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CAR_AMMO, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_LOAD_CAMERA_SPLINE, INPUT_ARGUMENTS(ARGTYPE_STRING, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_MOVE_CAMERA_ALONG_SPLINE, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_CAMERA_POSITION_ALONG_SPLINE, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_DECLARE_MISSION_FLAG, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_DECLARE_MISSION_FLAG_FOR_CONTACT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_DECLARE_BASE_BRIEF_ID_FOR_CONTACT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_PLAYER_HEALTH_GREATER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_CHAR_HEALTH_GREATER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_CAR_HEALTH_GREATER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_ADD_BLIP_FOR_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ADD_BLIP_FOR_CHAR, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ADD_BLIP_FOR_OBJECT, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ADD_BLIP_FOR_CONTACT_POINT, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ADD_BLIP_FOR_COORD, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_CHANGE_BLIP_DISPLAY, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ADD_ONE_OFF_SOUND, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ADD_CONTINUOUS_SOUND, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_REMOVE_SOUND, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_CAR_STUCK_ON_ROOF, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_ADD_UPSIDEDOWN_CAR_CHECK, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_REMOVE_UPSIDEDOWN_CAR_CHECK, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_WAIT_ON_FOOT, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_FLEE_ON_FOOT_TILL_SAFE, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_GUARD_SPOT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_GUARD_AREA, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_WAIT_IN_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_PLAYER_IN_AREA_ON_FOOT_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_PLAYER_IN_AREA_IN_CAR_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_PLAYER_STOPPED_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_PLAYER_STOPPED_IN_AREA_ON_FOOT_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_PLAYER_STOPPED_IN_AREA_IN_CAR_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_PLAYER_IN_AREA_ON_FOOT_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_PLAYER_IN_AREA_IN_CAR_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_PLAYER_STOPPED_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_IS_PLAYER_STOPPED_IN_AREA_ON_FOOT_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_PLAYER_STOPPED_IN_AREA_IN_CAR_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_CHAR_IN_AREA_ON_FOOT_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_CHAR_IN_AREA_IN_CAR_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_CHAR_STOPPED_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_CHAR_STOPPED_IN_AREA_ON_FOOT_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_CHAR_STOPPED_IN_AREA_IN_CAR_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_CHAR_IN_AREA_ON_FOOT_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_CHAR_IN_AREA_IN_CAR_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_CHAR_STOPPED_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_IS_CHAR_STOPPED_IN_AREA_ON_FOOT_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_CHAR_STOPPED_IN_AREA_IN_CAR_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_CAR_STOPPED_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_CAR_STOPPED_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_LOCATE_CAR_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_LOCATE_STOPPED_CAR_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_LOCATE_CAR_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_LOCATE_STOPPED_CAR_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_GIVE_WEAPON_TO_PLAYER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_GIVE_WEAPON_TO_CHAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_GIVE_WEAPON_TO_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_PLAYER_CONTROL, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_FORCE_WEATHER, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_FORCE_WEATHER_NOW, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_RELEASE_WEATHER, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CURRENT_PLAYER_WEAPON, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CURRENT_CHAR_WEAPON, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CURRENT_CAR_WEAPON, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_GET_OBJECT_COORDINATES, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_OBJECT_COORDINATES, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_GET_GAME_TIMER, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_TURN_CHAR_TO_FACE_COORD, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_TURN_PLAYER_TO_FACE_COORD, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_STORE_WANTED_LEVEL, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_CAR_STOPPED, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_MARK_CHAR_AS_NO_LONGER_NEEDED, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_MARK_CAR_AS_NO_LONGER_NEEDED, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_MARK_OBJECT_AS_NO_LONGER_NEEDED, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_DONT_REMOVE_CHAR, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_DONT_REMOVE_CAR, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_DONT_REMOVE_OBJECT, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_CREATE_CHAR_AS_PASSENGER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_KILL_CHAR_ON_FOOT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_KILL_PLAYER_ON_FOOT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_KILL_CHAR_ANY_MEANS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_KILL_PLAYER_ANY_MEANS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_FLEE_CHAR_ON_FOOT_TILL_SAFE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_FLEE_PLAYER_ON_FOOT_TILL_SAFE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_FLEE_CHAR_ON_FOOT_ALWAYS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_FLEE_PLAYER_ON_FOOT_ALWAYS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_GOTO_CHAR_ON_FOOT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_GOTO_PLAYER_ON_FOOT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_LEAVE_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_ENTER_CAR_AS_PASSENGER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_ENTER_CAR_AS_DRIVER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_FOLLOW_CAR_IN_CAR, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_FIRE_AT_OBJECT_FROM_VEHICLE, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_DESTROY_OBJECT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_DESTROY_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_GOTO_AREA_ON_FOOT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_GOTO_AREA_IN_CAR, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_FOLLOW_CAR_ON_FOOT_WITH_OFFSET, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_GUARD_ATTACK, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CHAR_AS_LEADER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_PLAYER_AS_LEADER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_LEAVE_GROUP, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_FOLLOW_ROUTE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_ADD_ROUTE_POINT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_PRINT_WITH_NUMBER_BIG, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_PRINT_WITH_NUMBER, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_PRINT_WITH_NUMBER_NOW, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_PRINT_WITH_NUMBER_SOON, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SWITCH_ROADS_ON, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SWITCH_ROADS_OFF, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_GET_NUMBER_OF_PASSENGERS, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_GET_MAXIMUM_NUMBER_OF_PASSENGERS, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CAR_DENSITY_MULTIPLIER, INPUT_ARGUMENTS(ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CAR_HEAVY, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_CLEAR_CHAR_THREAT_SEARCH, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_ACTIVATE_CRANE, INPUT_ARGUMENTS(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_DEACTIVATE_CRANE, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_MAX_WANTED_LEVEL, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CURRENT_PLAYER_WEAPON, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CURRENT_CHAR_WEAPON, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CURRENT_CAR_WEAPON, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_OBJECT_COORDINATES, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_OBJECT_COORDINATES, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_GAME_TIMER, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_TURN_CHAR_TO_FACE_COORD, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_TURN_PLAYER_TO_FACE_COORD, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_STORE_WANTED_LEVEL, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_CAR_STOPPED, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_MARK_CHAR_AS_NO_LONGER_NEEDED, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_MARK_CAR_AS_NO_LONGER_NEEDED, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_MARK_OBJECT_AS_NO_LONGER_NEEDED, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_DONT_REMOVE_CHAR, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_DONT_REMOVE_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_DONT_REMOVE_OBJECT, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_CREATE_CHAR_AS_PASSENGER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_KILL_CHAR_ON_FOOT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_KILL_PLAYER_ON_FOOT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_KILL_CHAR_ANY_MEANS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_KILL_PLAYER_ANY_MEANS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_FLEE_CHAR_ON_FOOT_TILL_SAFE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_FLEE_PLAYER_ON_FOOT_TILL_SAFE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_FLEE_CHAR_ON_FOOT_ALWAYS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_FLEE_PLAYER_ON_FOOT_ALWAYS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_GOTO_CHAR_ON_FOOT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_GOTO_PLAYER_ON_FOOT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_LEAVE_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_ENTER_CAR_AS_PASSENGER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_ENTER_CAR_AS_DRIVER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_FOLLOW_CAR_IN_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_FIRE_AT_OBJECT_FROM_VEHICLE, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_DESTROY_OBJECT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_DESTROY_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_GOTO_AREA_ON_FOOT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_GOTO_AREA_IN_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_FOLLOW_CAR_ON_FOOT_WITH_OFFSET, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_GUARD_ATTACK, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_AS_LEADER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_PLAYER_AS_LEADER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_LEAVE_GROUP, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_FOLLOW_ROUTE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ADD_ROUTE_POINT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_PRINT_WITH_NUMBER_BIG, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_PRINT_WITH_NUMBER, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_PRINT_WITH_NUMBER_NOW, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_PRINT_WITH_NUMBER_SOON, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SWITCH_ROADS_ON, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SWITCH_ROADS_OFF, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_NUMBER_OF_PASSENGERS, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_MAXIMUM_NUMBER_OF_PASSENGERS, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CAR_DENSITY_MULTIPLIER, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CAR_HEAVY, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_CLEAR_CHAR_THREAT_SEARCH, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ACTIVATE_CRANE, INPUT_ARGUMENTS(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_DEACTIVATE_CRANE, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_MAX_WANTED_LEVEL, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_SAVE_VAR_INT, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_SAVE_VAR_FLOAT, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_CAR_IN_AIR_PROPER, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_CAR_UPSIDEDOWN, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_GET_PLAYER_CHAR, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_CAR_IN_AIR_PROPER, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_CAR_UPSIDEDOWN, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_PLAYER_CHAR, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -1, ""),
REGISTER_COMMAND(COMMAND_CANCEL_OVERRIDE_RESTART, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_POLICE_IGNORE_PLAYER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_ADD_PAGER_MESSAGE_WITH_NUMBER, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_START_KILL_FRENZY, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_READ_KILL_FRENZY_STATUS, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SQRT, INPUT_ARGUMENTS(ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_LOCATE_PLAYER_ANY_MEANS_CAR_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_LOCATE_PLAYER_ON_FOOT_CAR_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_LOCATE_PLAYER_IN_CAR_CAR_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_LOCATE_PLAYER_ANY_MEANS_CAR_3D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_LOCATE_PLAYER_ON_FOOT_CAR_3D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_LOCATE_PLAYER_IN_CAR_CAR_3D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_LOCATE_CHAR_ANY_MEANS_CAR_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_LOCATE_CHAR_ON_FOOT_CAR_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_LOCATE_CHAR_IN_CAR_CAR_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_LOCATE_CHAR_ANY_MEANS_CAR_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_CAR_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_CAR_3D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_GENERATE_RANDOM_FLOAT_IN_RANGE, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_GENERATE_RANDOM_INT_IN_RANGE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_LOCK_CAR_DOORS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_EXPLODE_CAR, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_ADD_EXPLOSION, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_CAR_UPRIGHT, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_TURN_CHAR_TO_FACE_CHAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_TURN_CHAR_TO_FACE_PLAYER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_TURN_PLAYER_TO_FACE_CHAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_GOTO_COORD_ON_FOOT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_GOTO_COORD_IN_CAR, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_CREATE_PICKUP, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_HAS_PICKUP_BEEN_COLLECTED, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_REMOVE_PICKUP, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- 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_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, ""),
- REGISTER_COMMAND(COMMAND_SET_POWERPOINT, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_ALL_TAXI_LIGHTS, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_CAR_ARMED_WITH_ANY_BOMB, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_APPLY_BRAKES_TO_PLAYERS_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_PLAYER_HEALTH, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CHAR_HEALTH, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CAR_HEALTH, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_GET_PLAYER_HEALTH, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_GET_CHAR_HEALTH, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_GET_CAR_HEALTH, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_CAR_ARMED_WITH_BOMB, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_CHANGE_CAR_COLOUR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SWITCH_PED_ROADS_ON, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SWITCH_PED_ROADS_OFF, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_CHAR_LOOK_AT_CHAR_ALWAYS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_CHAR_LOOK_AT_PLAYER_ALWAYS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_PLAYER_LOOK_AT_CHAR_ALWAYS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_STOP_CHAR_LOOKING, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_STOP_PLAYER_LOOKING, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SWITCH_HELICOPTER, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_GANG_ATTITUDE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_GANG_GANG_ATTITUDE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_GANG_PLAYER_ATTITUDE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_GANG_PED_MODELS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_GANG_CAR_MODEL, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_GANG_WEAPONS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_RUN_TO_AREA, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_RUN_TO_COORD, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_PLAYER_TOUCHING_OBJECT_ON_FOOT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_CHAR_TOUCHING_OBJECT_ON_FOOT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_LOAD_SPECIAL_CHARACTER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_STRING,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_HAS_SPECIAL_CHARACTER_LOADED, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_FLASH_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_FLASH_CHAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_FLASH_OBJECT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_PLAYER_IN_REMOTE_MODE, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_ARM_CAR_WITH_BOMB, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CHAR_PERSONALITY, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CUTSCENE_OFFSET, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_ANIM_GROUP_FOR_CHAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_ANIM_GROUP_FOR_PLAYER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_REQUEST_MODEL, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_HAS_MODEL_LOADED, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_MARK_MODEL_AS_NO_LONGER_NEEDED, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_GRAB_PHONE, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_REPEATED_PHONE_MESSAGE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_STRING,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_PHONE_MESSAGE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_STRING,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_HAS_PHONE_DISPLAYED_MESSAGE, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_TURN_PHONE_OFF, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_DRAW_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_DRAW_LIGHT, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_POLICE_IGNORE_PLAYER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ADD_PAGER_MESSAGE_WITH_NUMBER, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_START_KILL_FRENZY, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_READ_KILL_FRENZY_STATUS, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SQRT, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_LOCATE_PLAYER_ANY_MEANS_CAR_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_LOCATE_PLAYER_ON_FOOT_CAR_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_LOCATE_PLAYER_IN_CAR_CAR_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_LOCATE_PLAYER_ANY_MEANS_CAR_3D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_LOCATE_PLAYER_ON_FOOT_CAR_3D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_LOCATE_PLAYER_IN_CAR_CAR_3D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_LOCATE_CHAR_ANY_MEANS_CAR_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_LOCATE_CHAR_ON_FOOT_CAR_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_LOCATE_CHAR_IN_CAR_CAR_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_LOCATE_CHAR_ANY_MEANS_CAR_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_CAR_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_CAR_3D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_GENERATE_RANDOM_FLOAT_IN_RANGE, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_GENERATE_RANDOM_INT_IN_RANGE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_LOCK_CAR_DOORS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_EXPLODE_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ADD_EXPLOSION, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_CAR_UPRIGHT, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_TURN_CHAR_TO_FACE_CHAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_TURN_CHAR_TO_FACE_PLAYER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_TURN_PLAYER_TO_FACE_CHAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_GOTO_COORD_ON_FOOT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_GOTO_COORD_IN_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_CREATE_PICKUP, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_HAS_PICKUP_BEEN_COLLECTED, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_REMOVE_PICKUP, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ 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_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, ""),
+ REGISTER_COMMAND(COMMAND_SET_POWERPOINT, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_ALL_TAXI_LIGHTS, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_CAR_ARMED_WITH_ANY_BOMB, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_APPLY_BRAKES_TO_PLAYERS_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_PLAYER_HEALTH, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_HEALTH, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CAR_HEALTH, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_PLAYER_HEALTH, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_CHAR_HEALTH, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_CAR_HEALTH, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_CAR_ARMED_WITH_BOMB, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_CHANGE_CAR_COLOUR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SWITCH_PED_ROADS_ON, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SWITCH_PED_ROADS_OFF, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_CHAR_LOOK_AT_CHAR_ALWAYS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_CHAR_LOOK_AT_PLAYER_ALWAYS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_PLAYER_LOOK_AT_CHAR_ALWAYS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_STOP_CHAR_LOOKING, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_STOP_PLAYER_LOOKING, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SWITCH_HELICOPTER, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_GANG_ATTITUDE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_GANG_GANG_ATTITUDE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_GANG_PLAYER_ATTITUDE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_GANG_PED_MODELS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_GANG_CAR_MODEL, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_GANG_WEAPONS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_RUN_TO_AREA, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_RUN_TO_COORD, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_PLAYER_TOUCHING_OBJECT_ON_FOOT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_CHAR_TOUCHING_OBJECT_ON_FOOT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_LOAD_SPECIAL_CHARACTER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_STRING, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_HAS_SPECIAL_CHARACTER_LOADED, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_FLASH_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_FLASH_CHAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_FLASH_OBJECT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_PLAYER_IN_REMOTE_MODE, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_ARM_CAR_WITH_BOMB, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_PERSONALITY, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CUTSCENE_OFFSET, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_ANIM_GROUP_FOR_CHAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_ANIM_GROUP_FOR_PLAYER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_REQUEST_MODEL, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_HAS_MODEL_LOADED, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_MARK_MODEL_AS_NO_LONGER_NEEDED, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_GRAB_PHONE, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_REPEATED_PHONE_MESSAGE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_STRING, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_PHONE_MESSAGE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_STRING, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_HAS_PHONE_DISPLAYED_MESSAGE, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_TURN_PHONE_OFF, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_DRAW_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_DRAW_LIGHT, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_STORE_WEATHER, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_RESTORE_WEATHER, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_STORE_CLOCK, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_RESTORE_CLOCK, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_RESTART_CRITICAL_MISSION, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_PLAYER_PLAYING, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_COLL_OBJ_NO_OBJ, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_COLL_OBJ_WAIT_ON_FOOT, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_COLL_OBJ_FLEE_ON_FOOT_TILL_SAFE, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_COLL_OBJ_GUARD_SPOT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_COLL_OBJ_GUARD_AREA, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_COLL_OBJ_WAIT_IN_CAR, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_COLL_OBJ_KILL_CHAR_ON_FOOT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_COLL_OBJ_KILL_PLAYER_ON_FOOT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_COLL_OBJ_KILL_CHAR_ANY_MEANS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_COLL_OBJ_KILL_PLAYER_ANY_MEANS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_COLL_OBJ_FLEE_CHAR_ON_FOOT_TILL_SAFE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_COLL_OBJ_FLEE_PLAYER_ON_FOOT_TILL_SAFE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_COLL_OBJ_FLEE_CHAR_ON_FOOT_ALWAYS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_COLL_OBJ_FLEE_PLAYER_ON_FOOT_ALWAYS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_COLL_OBJ_GOTO_CHAR_ON_FOOT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_COLL_OBJ_GOTO_PLAYER_ON_FOOT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_COLL_OBJ_LEAVE_CAR, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_COLL_OBJ_ENTER_CAR_AS_PASSENGER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_COLL_OBJ_ENTER_CAR_AS_DRIVER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_COLL_OBJ_FOLLOW_CAR_IN_CAR, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_COLL_OBJ_FIRE_AT_OBJECT_FROM_VEHICLE, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_COLL_OBJ_DESTROY_OBJECT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_COLL_OBJ_DESTROY_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_COLL_OBJ_GOTO_AREA_ON_FOOT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_COLL_OBJ_GOTO_AREA_IN_CAR, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_COLL_OBJ_FOLLOW_CAR_ON_FOOT_WITH_OFFSET, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_COLL_OBJ_GUARD_ATTACK, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_COLL_OBJ_FOLLOW_ROUTE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_COLL_OBJ_GOTO_COORD_ON_FOOT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_COLL_OBJ_GOTO_COORD_IN_CAR, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_COLL_OBJ_RUN_TO_AREA, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_COLL_OBJ_RUN_TO_COORD, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_ADD_PEDS_IN_AREA_TO_COLL, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_ADD_PEDS_IN_VEHICLE_TO_COLL, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_CLEAR_COLL, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_COLL_IN_CARS, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_LOCATE_COLL_ANY_MEANS_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_LOCATE_COLL_ON_FOOT_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_LOCATE_COLL_IN_CAR_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_LOCATE_STOPPED_COLL_ANY_MEANS_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_LOCATE_STOPPED_COLL_ON_FOOT_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_LOCATE_STOPPED_COLL_IN_CAR_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_LOCATE_COLL_ANY_MEANS_CHAR_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_LOCATE_COLL_ON_FOOT_CHAR_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_LOCATE_COLL_IN_CAR_CHAR_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_LOCATE_COLL_ANY_MEANS_CAR_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_LOCATE_COLL_ON_FOOT_CAR_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_LOCATE_COLL_IN_CAR_CAR_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_LOCATE_COLL_ANY_MEANS_PLAYER_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_LOCATE_COLL_ON_FOOT_PLAYER_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_LOCATE_COLL_IN_CAR_PLAYER_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_COLL_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_COLL_IN_AREA_ON_FOOT_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_COLL_IN_AREA_IN_CAR_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_COLL_STOPPED_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_COLL_STOPPED_IN_AREA_ON_FOOT_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_COLL_STOPPED_IN_AREA_IN_CAR_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_GET_NUMBER_OF_PEDS_IN_COLL, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CHAR_HEED_THREATS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_PLAYER_HEED_THREATS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_GET_CONTROLLER_MODE, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CAN_RESPRAY_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_TAXI, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_UNLOAD_SPECIAL_CHARACTER, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_RESTART_CRITICAL_MISSION, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_PLAYER_PLAYING, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_COLL_OBJ_NO_OBJ, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_COLL_OBJ_WAIT_ON_FOOT, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_COLL_OBJ_FLEE_ON_FOOT_TILL_SAFE, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_COLL_OBJ_GUARD_SPOT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_COLL_OBJ_GUARD_AREA, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_COLL_OBJ_WAIT_IN_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_COLL_OBJ_KILL_CHAR_ON_FOOT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_COLL_OBJ_KILL_PLAYER_ON_FOOT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_COLL_OBJ_KILL_CHAR_ANY_MEANS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_COLL_OBJ_KILL_PLAYER_ANY_MEANS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_COLL_OBJ_FLEE_CHAR_ON_FOOT_TILL_SAFE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_COLL_OBJ_FLEE_PLAYER_ON_FOOT_TILL_SAFE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_COLL_OBJ_FLEE_CHAR_ON_FOOT_ALWAYS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_COLL_OBJ_FLEE_PLAYER_ON_FOOT_ALWAYS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_COLL_OBJ_GOTO_CHAR_ON_FOOT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_COLL_OBJ_GOTO_PLAYER_ON_FOOT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_COLL_OBJ_LEAVE_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_COLL_OBJ_ENTER_CAR_AS_PASSENGER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_COLL_OBJ_ENTER_CAR_AS_DRIVER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_COLL_OBJ_FOLLOW_CAR_IN_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_COLL_OBJ_FIRE_AT_OBJECT_FROM_VEHICLE, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_COLL_OBJ_DESTROY_OBJECT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_COLL_OBJ_DESTROY_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_COLL_OBJ_GOTO_AREA_ON_FOOT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_COLL_OBJ_GOTO_AREA_IN_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_COLL_OBJ_FOLLOW_CAR_ON_FOOT_WITH_OFFSET, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_COLL_OBJ_GUARD_ATTACK, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_COLL_OBJ_FOLLOW_ROUTE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_COLL_OBJ_GOTO_COORD_ON_FOOT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_COLL_OBJ_GOTO_COORD_IN_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_COLL_OBJ_RUN_TO_AREA, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_COLL_OBJ_RUN_TO_COORD, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ADD_PEDS_IN_AREA_TO_COLL, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ADD_PEDS_IN_VEHICLE_TO_COLL, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_CLEAR_COLL, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_COLL_IN_CARS, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_LOCATE_COLL_ANY_MEANS_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_LOCATE_COLL_ON_FOOT_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_LOCATE_COLL_IN_CAR_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_LOCATE_STOPPED_COLL_ANY_MEANS_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_LOCATE_STOPPED_COLL_ON_FOOT_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_LOCATE_STOPPED_COLL_IN_CAR_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_LOCATE_COLL_ANY_MEANS_CHAR_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_LOCATE_COLL_ON_FOOT_CHAR_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_LOCATE_COLL_IN_CAR_CHAR_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_LOCATE_COLL_ANY_MEANS_CAR_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_LOCATE_COLL_ON_FOOT_CAR_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_LOCATE_COLL_IN_CAR_CAR_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_LOCATE_COLL_ANY_MEANS_PLAYER_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_LOCATE_COLL_ON_FOOT_PLAYER_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_LOCATE_COLL_IN_CAR_PLAYER_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_COLL_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_COLL_IN_AREA_ON_FOOT_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_COLL_IN_AREA_IN_CAR_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_COLL_STOPPED_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_COLL_STOPPED_IN_AREA_ON_FOOT_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_COLL_STOPPED_IN_AREA_IN_CAR_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_NUMBER_OF_PEDS_IN_COLL, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_HEED_THREATS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_PLAYER_HEED_THREATS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_CONTROLLER_MODE, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CAN_RESPRAY_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_TAXI, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_UNLOAD_SPECIAL_CHARACTER, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_RESET_NUM_OF_MODELS_KILLED_BY_PLAYER, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_GET_NUM_OF_MODELS_KILLED_BY_PLAYER, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_ACTIVATE_GARAGE, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SWITCH_TAXI_TIMER, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_CREATE_OBJECT_NO_OFFSET, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_BOAT, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_GOTO_AREA_ANY_MEANS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_COLL_OBJ_GOTO_AREA_ANY_MEANS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_PLAYER_STOPPED, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_CHAR_STOPPED, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_MESSAGE_WAIT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_ADD_PARTICLE_EFFECT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SWITCH_WIDESCREEN, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_ADD_SPRITE_BLIP_FOR_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_ADD_SPRITE_BLIP_FOR_CHAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_ADD_SPRITE_BLIP_FOR_OBJECT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_ADD_SPRITE_BLIP_FOR_CONTACT_POINT, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_ADD_SPRITE_BLIP_FOR_COORD, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CHAR_ONLY_DAMAGED_BY_PLAYER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CAR_ONLY_DAMAGED_BY_PLAYER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CHAR_PROOFS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CAR_PROOFS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_PLAYER_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_PLAYER_IN_ANGLED_AREA_ON_FOOT_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_PLAYER_IN_ANGLED_AREA_IN_CAR_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_PLAYER_STOPPED_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_PLAYER_STOPPED_IN_ANGLED_AREA_ON_FOOT_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_PLAYER_STOPPED_IN_ANGLED_AREA_IN_CAR_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_PLAYER_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_IS_PLAYER_IN_ANGLED_AREA_ON_FOOT_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_IS_PLAYER_IN_ANGLED_AREA_IN_CAR_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_IS_PLAYER_STOPPED_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_IS_PLAYER_STOPPED_IN_ANGLED_AREA_ON_FOOT_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_IS_PLAYER_STOPPED_IN_ANGLED_AREA_IN_CAR_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_DEACTIVATE_GARAGE, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_GET_NUMBER_OF_CARS_COLLECTED_BY_GARAGE, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_HAS_CAR_BEEN_TAKEN_TO_GARAGE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_SWAT_REQUIRED, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_FBI_REQUIRED, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_ARMY_REQUIRED, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_CAR_IN_WATER, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_GET_CLOSEST_CHAR_NODE, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_GET_CLOSEST_CAR_NODE, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_CAR_GOTO_COORDINATES_ACCURATE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_START_PACMAN_RACE, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_NUM_OF_MODELS_KILLED_BY_PLAYER, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ACTIVATE_GARAGE, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SWITCH_TAXI_TIMER, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_CREATE_OBJECT_NO_OFFSET, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_BOAT, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_GOTO_AREA_ANY_MEANS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_COLL_OBJ_GOTO_AREA_ANY_MEANS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_PLAYER_STOPPED, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_CHAR_STOPPED, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_MESSAGE_WAIT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ADD_PARTICLE_EFFECT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SWITCH_WIDESCREEN, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ADD_SPRITE_BLIP_FOR_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ADD_SPRITE_BLIP_FOR_CHAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ADD_SPRITE_BLIP_FOR_OBJECT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ADD_SPRITE_BLIP_FOR_CONTACT_POINT, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ADD_SPRITE_BLIP_FOR_COORD, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_ONLY_DAMAGED_BY_PLAYER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CAR_ONLY_DAMAGED_BY_PLAYER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_PROOFS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CAR_PROOFS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_PLAYER_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_PLAYER_IN_ANGLED_AREA_ON_FOOT_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_PLAYER_IN_ANGLED_AREA_IN_CAR_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_PLAYER_STOPPED_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_PLAYER_STOPPED_IN_ANGLED_AREA_ON_FOOT_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_PLAYER_STOPPED_IN_ANGLED_AREA_IN_CAR_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_PLAYER_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_IS_PLAYER_IN_ANGLED_AREA_ON_FOOT_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_IS_PLAYER_IN_ANGLED_AREA_IN_CAR_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_IS_PLAYER_STOPPED_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_IS_PLAYER_STOPPED_IN_ANGLED_AREA_ON_FOOT_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_IS_PLAYER_STOPPED_IN_ANGLED_AREA_IN_CAR_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_DEACTIVATE_GARAGE, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_NUMBER_OF_CARS_COLLECTED_BY_GARAGE, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_HAS_CAR_BEEN_TAKEN_TO_GARAGE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_SWAT_REQUIRED, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_FBI_REQUIRED, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_ARMY_REQUIRED, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_CAR_IN_WATER, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_CLOSEST_CHAR_NODE, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_CLOSEST_CAR_NODE, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_CAR_GOTO_COORDINATES_ACCURATE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_START_PACMAN_RACE, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_START_PACMAN_RECORD, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_GET_NUMBER_OF_POWER_PILLS_EATEN, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_NUMBER_OF_POWER_PILLS_EATEN, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -1, ""),
REGISTER_COMMAND(COMMAND_CLEAR_PACMAN, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_START_PACMAN_SCRAMBLE, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_GET_NUMBER_OF_POWER_PILLS_CARRIED, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_START_PACMAN_SCRAMBLE, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_NUMBER_OF_POWER_PILLS_CARRIED, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -1, ""),
REGISTER_COMMAND(COMMAND_CLEAR_NUMBER_OF_POWER_PILLS_CARRIED, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
- 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_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, ""),
- REGISTER_COMMAND(COMMAND_REMOVE_SCRIPT_FIRE, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_COMEDY_CONTROLS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_BOAT_GOTO_COORDS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_BOAT_STOP, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_PLAYER_SHOOTING_IN_AREA, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_CHAR_SHOOTING_IN_AREA, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_CURRENT_PLAYER_WEAPON, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_CURRENT_CHAR_WEAPON, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ 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(), 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, ""),
+ REGISTER_COMMAND(COMMAND_REMOVE_SCRIPT_FIRE, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_COMEDY_CONTROLS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_BOAT_GOTO_COORDS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_BOAT_STOP, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_PLAYER_SHOOTING_IN_AREA, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_CHAR_SHOOTING_IN_AREA, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_CURRENT_PLAYER_WEAPON, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_CURRENT_CHAR_WEAPON, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
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_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, ""),
- REGISTER_COMMAND(COMMAND_CREATE_MONEY_PICKUP, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CHAR_ACCURACY, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_GET_CAR_SPEED, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_LOAD_CUTSCENE, INPUT_ARGUMENTS(ARGTYPE_STRING,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_CREATE_CUTSCENE_OBJECT, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CUTSCENE_ANIM, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_STRING,), 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, 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, ""),
+ REGISTER_COMMAND(COMMAND_CREATE_MONEY_PICKUP, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_ACCURACY, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_CAR_SPEED, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_LOAD_CUTSCENE, INPUT_ARGUMENTS(ARGTYPE_STRING, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_CREATE_CUTSCENE_OBJECT, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -1, ""),
+ 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_GET_CUTSCENE_TIME, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -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, ""),
- REGISTER_COMMAND(COMMAND_SET_COLLECTABLE1_TOTAL, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_PROJECTILE_IN_AREA, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_DESTROY_PROJECTILES_IN_AREA, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_DROP_MINE, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_DROP_NAUTICAL_MINE, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_CHAR_MODEL, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_LOAD_SPECIAL_MODEL, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_STRING,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_CREATE_CUTSCENE_HEAD, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CUTSCENE_HEAD_ANIM, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_STRING,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SIN, INPUT_ARGUMENTS(ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_COS, INPUT_ARGUMENTS(ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_GET_CAR_FORWARD_X, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_GET_CAR_FORWARD_Y, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_CHANGE_GARAGE_TYPE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_ACTIVATE_CRUSHER_CRANE, INPUT_ARGUMENTS(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_PRINT_WITH_2_NUMBERS, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_PRINT_WITH_2_NUMBERS_NOW, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_PRINT_WITH_2_NUMBERS_SOON, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_PRINT_WITH_3_NUMBERS, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_PRINT_WITH_3_NUMBERS_NOW, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_PRINT_WITH_3_NUMBERS_SOON, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_PRINT_WITH_4_NUMBERS, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_PRINT_WITH_4_NUMBERS_NOW, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_PRINT_WITH_4_NUMBERS_SOON, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_PRINT_WITH_5_NUMBERS, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_PRINT_WITH_5_NUMBERS_NOW, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_PRINT_WITH_5_NUMBERS_SOON, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_PRINT_WITH_6_NUMBERS, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_PRINT_WITH_6_NUMBERS_NOW, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_PRINT_WITH_6_NUMBERS_SOON, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_FOLLOW_CHAR_IN_FORMATION, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_PLAYER_MADE_PROGRESS, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_PROGRESS_TOTAL, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_REGISTER_JUMP_DISTANCE, INPUT_ARGUMENTS(ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_REGISTER_JUMP_HEIGHT, INPUT_ARGUMENTS(ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_REGISTER_JUMP_FLIPS, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_REGISTER_JUMP_SPINS, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_REGISTER_JUMP_STUNT, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_CREATE_COLLECTABLE1, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_COLLECTABLE1_TOTAL, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_PROJECTILE_IN_AREA, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_DESTROY_PROJECTILES_IN_AREA, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_DROP_MINE, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_DROP_NAUTICAL_MINE, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_CHAR_MODEL, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_LOAD_SPECIAL_MODEL, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_STRING, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_CREATE_CUTSCENE_HEAD, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CUTSCENE_HEAD_ANIM, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_STRING, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SIN, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_COS, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_CAR_FORWARD_X, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_CAR_FORWARD_Y, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_CHANGE_GARAGE_TYPE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ACTIVATE_CRUSHER_CRANE, INPUT_ARGUMENTS(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_PRINT_WITH_2_NUMBERS, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_PRINT_WITH_2_NUMBERS_NOW, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_PRINT_WITH_2_NUMBERS_SOON, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_PRINT_WITH_3_NUMBERS, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_PRINT_WITH_3_NUMBERS_NOW, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_PRINT_WITH_3_NUMBERS_SOON, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_PRINT_WITH_4_NUMBERS, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_PRINT_WITH_4_NUMBERS_NOW, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_PRINT_WITH_4_NUMBERS_SOON, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_PRINT_WITH_5_NUMBERS, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_PRINT_WITH_5_NUMBERS_NOW, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_PRINT_WITH_5_NUMBERS_SOON, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_PRINT_WITH_6_NUMBERS, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_PRINT_WITH_6_NUMBERS_NOW, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_PRINT_WITH_6_NUMBERS_SOON, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_FOLLOW_CHAR_IN_FORMATION, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_PLAYER_MADE_PROGRESS, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_PROGRESS_TOTAL, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_REGISTER_JUMP_DISTANCE, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_REGISTER_JUMP_HEIGHT, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_REGISTER_JUMP_FLIPS, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_REGISTER_JUMP_SPINS, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_REGISTER_JUMP_STUNT, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_REGISTER_UNIQUE_JUMP_FOUND, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_UNIQUE_JUMPS_TOTAL, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_UNIQUE_JUMPS_TOTAL, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_REGISTER_PASSENGER_DROPPED_OFF_TAXI, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_REGISTER_MONEY_MADE_TAXI, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_REGISTER_MONEY_MADE_TAXI, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_REGISTER_MISSION_GIVEN, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_REGISTER_MISSION_PASSED, INPUT_ARGUMENTS(ARGTYPE_STRING,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CHAR_RUNNING, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_REGISTER_MISSION_PASSED, INPUT_ARGUMENTS(ARGTYPE_STRING, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_RUNNING, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
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_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, ""),
- REGISTER_COMMAND(COMMAND_EXPLODE_PLAYER_HEAD, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_ANCHOR_BOAT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_ZONE_GROUP, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_START_CAR_FIRE, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
- 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_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, ""),
- REGISTER_COMMAND(COMMAND_SET_CAR_BLOCK_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_CATCH_TRAIN, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_COLL_OBJ_CATCH_TRAIN, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_PLAYER_NEVER_GETS_TIRED, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_PLAYER_FAST_RELOAD, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CHAR_BLEEDING, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CAR_FUNNY_SUSPENSION, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CAR_BIG_WHEELS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_FREE_RESPRAYS, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_PLAYER_VISIBLE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CHAR_VISIBLE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- 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_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(), 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, ""),
+ REGISTER_COMMAND(COMMAND_EXPLODE_PLAYER_HEAD, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ANCHOR_BOAT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_ZONE_GROUP, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_START_CAR_FIRE, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -1, ""),
+ 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(), 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, ""),
+ REGISTER_COMMAND(COMMAND_SET_CAR_BLOCK_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_CATCH_TRAIN, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_COLL_OBJ_CATCH_TRAIN, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_PLAYER_NEVER_GETS_TIRED, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_PLAYER_FAST_RELOAD, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_BLEEDING, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CAR_FUNNY_SUSPENSION, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CAR_BIG_WHEELS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_FREE_RESPRAYS, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_PLAYER_VISIBLE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_VISIBLE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ 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_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, ""),
- REGISTER_COMMAND(COMMAND_SET_TEXT_COLOUR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_TEXT_JUSTIFY, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_TEXT_CENTRE, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_TEXT_WRAPX, INPUT_ARGUMENTS(ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_TEXT_CENTRE_SIZE, INPUT_ARGUMENTS(ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_TEXT_BACKGROUND, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_TEXT_BACKGROUND_COLOUR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_TEXT_BACKGROUND_ONLY_TEXT, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_TEXT_PROPORTIONAL, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_TEXT_FONT, INPUT_ARGUMENTS(ARGTYPE_INT,), 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, ""),
+ REGISTER_COMMAND(COMMAND_SET_TEXT_COLOUR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_TEXT_JUSTIFY, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_TEXT_CENTRE, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_TEXT_WRAPX, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_TEXT_CENTRE_SIZE, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_TEXT_BACKGROUND, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_TEXT_BACKGROUND_COLOUR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_TEXT_BACKGROUND_ONLY_TEXT, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_TEXT_PROPORTIONAL, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_TEXT_FONT, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_INDUSTRIAL_PASSED, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_COMMERCIAL_PASSED, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_SUBURBAN_PASSED, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_ROTATE_OBJECT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_SLIDE_OBJECT, 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_REMOVE_CHAR_ELEGANTLY, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CHAR_STAY_IN_SAME_PLACE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ROTATE_OBJECT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_SLIDE_OBJECT, 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_REMOVE_CHAR_ELEGANTLY, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_STAY_IN_SAME_PLACE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_IS_NASTY_GAME, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_UNDRESS_CHAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_STRING,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_DRESS_CHAR, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_START_CHASE_SCENE, INPUT_ARGUMENTS(ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_UNDRESS_CHAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_STRING, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_DRESS_CHAR, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_START_CHASE_SCENE, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_STOP_CHASE_SCENE, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
- 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_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_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, ""),
- REGISTER_COMMAND(COMMAND_MAKE_OBJECT_TARGETTABLE, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_ADD_ARMOUR_TO_PLAYER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_ADD_ARMOUR_TO_CHAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_OPEN_GARAGE, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_CLOSE_GARAGE, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_WARP_CHAR_FROM_CAR_TO_COORD, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_VISIBILITY_OF_CLOSEST_OBJECT_OF_TYPE, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_HAS_CHAR_SPOTTED_CHAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_HAIL_TAXI, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_HAS_OBJECT_BEEN_DAMAGED, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_START_KILL_FRENZY_HEADSHOT, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_ACTIVATE_MILITARY_CRANE, INPUT_ARGUMENTS(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_WARP_PLAYER_INTO_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_WARP_CHAR_INTO_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SWITCH_CAR_RADIO, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_AUDIO_STREAM, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_PRINT_WITH_2_NUMBERS_BIG, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_PRINT_WITH_3_NUMBERS_BIG, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_PRINT_WITH_4_NUMBERS_BIG, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_PRINT_WITH_5_NUMBERS_BIG, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_PRINT_WITH_6_NUMBERS_BIG, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CHAR_WAIT_STATE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), 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, ""),
+ REGISTER_COMMAND(COMMAND_MAKE_OBJECT_TARGETTABLE, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ADD_ARMOUR_TO_PLAYER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ADD_ARMOUR_TO_CHAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_OPEN_GARAGE, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_CLOSE_GARAGE, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_WARP_CHAR_FROM_CAR_TO_COORD, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_VISIBILITY_OF_CLOSEST_OBJECT_OF_TYPE, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_HAS_CHAR_SPOTTED_CHAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_HAIL_TAXI, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_HAS_OBJECT_BEEN_DAMAGED, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_START_KILL_FRENZY_HEADSHOT, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ACTIVATE_MILITARY_CRANE, INPUT_ARGUMENTS(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_WARP_PLAYER_INTO_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_WARP_CHAR_INTO_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SWITCH_CAR_RADIO, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_AUDIO_STREAM, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_PRINT_WITH_2_NUMBERS_BIG, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_PRINT_WITH_3_NUMBERS_BIG, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_PRINT_WITH_4_NUMBERS_BIG, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_PRINT_WITH_5_NUMBERS_BIG, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_PRINT_WITH_6_NUMBERS_BIG, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_WAIT_STATE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_SET_CAMERA_BEHIND_PLAYER, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_MOTION_BLUR, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_PRINT_STRING_IN_STRING, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_CREATE_RANDOM_CHAR, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_STEAL_ANY_CAR, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_2_REPEATED_PHONE_MESSAGES, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_STRING, ARGTYPE_STRING,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_2_PHONE_MESSAGES, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_STRING, ARGTYPE_STRING,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_3_REPEATED_PHONE_MESSAGES, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_STRING, ARGTYPE_STRING, ARGTYPE_STRING,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_3_PHONE_MESSAGES, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_STRING, ARGTYPE_STRING, ARGTYPE_STRING,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_4_REPEATED_PHONE_MESSAGES, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_STRING, ARGTYPE_STRING, ARGTYPE_STRING, ARGTYPE_STRING,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_4_PHONE_MESSAGES, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_STRING, ARGTYPE_STRING, ARGTYPE_STRING, ARGTYPE_STRING,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_SNIPER_BULLET_IN_AREA, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_MOTION_BLUR, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_PRINT_STRING_IN_STRING, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_CREATE_RANDOM_CHAR, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_STEAL_ANY_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_2_REPEATED_PHONE_MESSAGES, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_STRING, ARGTYPE_STRING, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_2_PHONE_MESSAGES, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_STRING, ARGTYPE_STRING, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_3_REPEATED_PHONE_MESSAGES, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_STRING, ARGTYPE_STRING, ARGTYPE_STRING, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_3_PHONE_MESSAGES, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_STRING, ARGTYPE_STRING, ARGTYPE_STRING, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_4_REPEATED_PHONE_MESSAGES, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_STRING, ARGTYPE_STRING, ARGTYPE_STRING, ARGTYPE_STRING, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_4_PHONE_MESSAGES, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_STRING, ARGTYPE_STRING, ARGTYPE_STRING, ARGTYPE_STRING, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_SNIPER_BULLET_IN_AREA, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
REGISTER_COMMAND(COMMAND_GIVE_PLAYER_DETONATOR, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_COLL_OBJ_STEAL_ANY_CAR, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_OBJECT_VELOCITY, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_OBJECT_COLLISION, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_ICECREAM_JINGLE_ON, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_PRINT_STRING_IN_STRING_NOW, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_PRINT_STRING_IN_STRING_SOON, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_5_REPEATED_PHONE_MESSAGES, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_STRING, ARGTYPE_STRING, ARGTYPE_STRING, ARGTYPE_STRING, ARGTYPE_STRING,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_5_PHONE_MESSAGES, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_STRING, ARGTYPE_STRING, ARGTYPE_STRING, ARGTYPE_STRING, ARGTYPE_STRING,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_6_REPEATED_PHONE_MESSAGES, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_STRING, ARGTYPE_STRING, ARGTYPE_STRING, ARGTYPE_STRING, ARGTYPE_STRING, ARGTYPE_STRING,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_6_PHONE_MESSAGES, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_STRING, ARGTYPE_STRING, ARGTYPE_STRING, ARGTYPE_STRING, ARGTYPE_STRING, ARGTYPE_STRING,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_POINT_OBSCURED_BY_A_MISSION_ENTITY, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_COLL_OBJ_STEAL_ANY_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_OBJECT_VELOCITY, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_OBJECT_COLLISION, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_ICECREAM_JINGLE_ON, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_PRINT_STRING_IN_STRING_NOW, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_PRINT_STRING_IN_STRING_SOON, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_5_REPEATED_PHONE_MESSAGES, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_STRING, ARGTYPE_STRING, ARGTYPE_STRING, ARGTYPE_STRING, ARGTYPE_STRING, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_5_PHONE_MESSAGES, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_STRING, ARGTYPE_STRING, ARGTYPE_STRING, ARGTYPE_STRING, ARGTYPE_STRING, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_6_REPEATED_PHONE_MESSAGES, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_STRING, ARGTYPE_STRING, ARGTYPE_STRING, ARGTYPE_STRING, ARGTYPE_STRING, ARGTYPE_STRING, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_6_PHONE_MESSAGES, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_STRING, ARGTYPE_STRING, ARGTYPE_STRING, ARGTYPE_STRING, ARGTYPE_STRING, ARGTYPE_STRING, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_POINT_OBSCURED_BY_A_MISSION_ENTITY, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
REGISTER_COMMAND(COMMAND_LOAD_ALL_MODELS_NOW, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_ADD_TO_OBJECT_VELOCITY, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_DRAW_SPRITE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_DRAW_RECT, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_LOAD_SPRITE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_STRING,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_LOAD_TEXTURE_DICTIONARY, INPUT_ARGUMENTS(ARGTYPE_STRING,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ADD_TO_OBJECT_VELOCITY, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_DRAW_SPRITE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_DRAW_RECT, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_LOAD_SPRITE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_STRING, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_LOAD_TEXTURE_DICTIONARY, INPUT_ARGUMENTS(ARGTYPE_STRING, ), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_REMOVE_TEXTURE_DICTIONARY, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_OBJECT_DYNAMIC, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CHAR_ANIM_SPEED, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_PLAY_MISSION_PASSED_TUNE, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_CLEAR_AREA, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_FREEZE_ONSCREEN_TIMER, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SWITCH_CAR_SIREN, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SWITCH_PED_ROADS_ON_ANGLED, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SWITCH_PED_ROADS_OFF_ANGLED, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SWITCH_ROADS_ON_ANGLED, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SWITCH_ROADS_OFF_ANGLED, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CAR_WATERTIGHT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_ADD_MOVING_PARTICLE_EFFECT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CHAR_CANT_BE_DRAGGED_OUT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_TURN_CAR_TO_FACE_COORD, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_CRANE_LIFTING_CAR, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_DRAW_SPHERE, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CAR_STATUS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_CHAR_MALE, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_SCRIPT_NAME, INPUT_ARGUMENTS(ARGTYPE_STRING,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_CHANGE_GARAGE_TYPE_WITH_CAR_MODEL, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_FIND_DRUG_PLANE_COORDINATES, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SAVE_INT_TO_DEBUG_FILE, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SAVE_FLOAT_TO_DEBUG_FILE, INPUT_ARGUMENTS(ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_OBJECT_DYNAMIC, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_ANIM_SPEED, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_PLAY_MISSION_PASSED_TUNE, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_CLEAR_AREA, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_FREEZE_ONSCREEN_TIMER, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SWITCH_CAR_SIREN, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SWITCH_PED_ROADS_ON_ANGLED, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SWITCH_PED_ROADS_OFF_ANGLED, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SWITCH_ROADS_ON_ANGLED, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SWITCH_ROADS_OFF_ANGLED, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CAR_WATERTIGHT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ADD_MOVING_PARTICLE_EFFECT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_CANT_BE_DRAGGED_OUT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_TURN_CAR_TO_FACE_COORD, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_CRANE_LIFTING_CAR, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_DRAW_SPHERE, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CAR_STATUS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_CHAR_MALE, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_SCRIPT_NAME, INPUT_ARGUMENTS(ARGTYPE_STRING, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_CHANGE_GARAGE_TYPE_WITH_CAR_MODEL, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_FIND_DRUG_PLANE_COORDINATES, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SAVE_INT_TO_DEBUG_FILE, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SAVE_FLOAT_TO_DEBUG_FILE, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_SAVE_NEWLINE_TO_DEBUG_FILE, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_POLICE_RADIO_MESSAGE, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CAR_STRONG, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_REMOVE_ROUTE, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SWITCH_RUBBISH, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_REMOVE_PARTICLE_EFFECTS_IN_AREA, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SWITCH_STREAMING, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_GARAGE_OPEN, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_GARAGE_CLOSED, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_POLICE_RADIO_MESSAGE, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CAR_STRONG, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_REMOVE_ROUTE, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SWITCH_RUBBISH, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_REMOVE_PARTICLE_EFFECTS_IN_AREA, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SWITCH_STREAMING, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_GARAGE_OPEN, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_GARAGE_CLOSED, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
REGISTER_COMMAND(COMMAND_START_CATALINA_HELI, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_CATALINA_HELI_TAKE_OFF, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_REMOVE_CATALINA_HELI, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_HAS_CATALINA_HELI_BEEN_SHOT_DOWN, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_SWAP_NEAREST_BUILDING_MODEL, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SWITCH_WORLD_PROCESSING, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_REMOVE_ALL_PLAYER_WEAPONS, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_GRAB_CATALINA_HELI, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_CLEAR_AREA_OF_CARS, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_ROTATING_GARAGE_DOOR, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_ADD_SPHERE, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_REMOVE_SPHERE, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SWAP_NEAREST_BUILDING_MODEL, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SWITCH_WORLD_PROCESSING, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_REMOVE_ALL_PLAYER_WEAPONS, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_GRAB_CATALINA_HELI, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_CLEAR_AREA_OF_CARS, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_ROTATING_GARAGE_DOOR, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ADD_SPHERE, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_REMOVE_SPHERE, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_CATALINA_HELI_FLY_AWAY, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_EVERYONE_IGNORE_PLAYER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- 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_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, ""),
- REGISTER_COMMAND(COMMAND_SET_WANTED_MULTIPLIER, INPUT_ARGUMENTS(ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_EVERYONE_IGNORE_PLAYER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ 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_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, ""),
+ REGISTER_COMMAND(COMMAND_SET_WANTED_MULTIPLIER, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_SET_CAMERA_IN_FRONT_OF_PLAYER, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_CAR_VISIBLY_DAMAGED, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_DOES_OBJECT_EXIST, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_LOAD_SCENE, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- 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_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_IS_CAR_VISIBLY_DAMAGED, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_DOES_OBJECT_EXIST, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_LOAD_SCENE, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ 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_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_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, ""),
- REGISTER_COMMAND(COMMAND_ADD_BLIP_FOR_PICKUP_OLD, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_ADD_BLIP_FOR_PICKUP, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_ADD_SPRITE_BLIP_FOR_PICKUP, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_PED_DENSITY_MULTIPLIER, INPUT_ARGUMENTS(ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- 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_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, ""),
+ REGISTER_COMMAND(COMMAND_NO_SPECIAL_CAMERA_FOR_THIS_GARAGE, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ADD_BLIP_FOR_PICKUP_OLD, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ADD_BLIP_FOR_PICKUP, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ADD_SPRITE_BLIP_FOR_PICKUP, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_PED_DENSITY_MULTIPLIER, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ 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_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, ""),
REGISTER_COMMAND(COMMAND_CLEAR_HELP, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_FLASH_HUD_OBJECT, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_FLASH_RADAR_BLIP, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_CHAR_IN_CONTROL, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_GENERATE_CARS_AROUND_CAMERA, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_FLASH_HUD_OBJECT, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_FLASH_RADAR_BLIP, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_CHAR_IN_CONTROL, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_GENERATE_CARS_AROUND_CAMERA, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_CLEAR_SMALL_PRINTS, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_HAS_MILITARY_CRANE_COLLECTED_ALL_CARS, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_UPSIDEDOWN_CAR_NOT_DAMAGED, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_CAN_PLAYER_START_MISSION, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_MAKE_PLAYER_SAFE_FOR_CUTSCENE, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- 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_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, ""),
- REGISTER_COMMAND(COMMAND_LOAD_COLLISION, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_GET_BODY_CAST_HEALTH, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CHARS_CHATTING, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- 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_UPSIDEDOWN_CAR_NOT_DAMAGED, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_CAN_PLAYER_START_MISSION, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_MAKE_PLAYER_SAFE_FOR_CUTSCENE, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ 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, ), 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, ""),
+ REGISTER_COMMAND(COMMAND_LOAD_COLLISION, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_BODY_CAST_HEALTH, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHARS_CHATTING, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ 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_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_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_SET_TOTAL_NUMBER_OF_KILL_FRENZIES, INPUT_ARGUMENTS(ARGTYPE_INT,), 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_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_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_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, ""),
- REGISTER_COMMAND(COMMAND_SET_CHAR_USE_PEDNODE_SEEK, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SWITCH_VEHICLE_WEAPONS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_GET_OUT_OF_JAIL_FREE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_FREE_HEALTH_CARE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_CAR_DOOR_CLOSED, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -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, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_USE_PEDNODE_SEEK, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SWITCH_VEHICLE_WEAPONS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_GET_OUT_OF_JAIL_FREE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_FREE_HEALTH_CARE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_CAR_DOOR_CLOSED, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
REGISTER_COMMAND(COMMAND_LOAD_AND_LAUNCH_MISSION, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_LOAD_AND_LAUNCH_MISSION_INTERNAL, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_OBJECT_DRAW_LAST, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_GET_AMMO_IN_PLAYER_WEAPON, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_GET_AMMO_IN_CHAR_WEAPON, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_LOAD_AND_LAUNCH_MISSION_INTERNAL, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_OBJECT_DRAW_LAST, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_AMMO_IN_PLAYER_WEAPON, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_AMMO_IN_CHAR_WEAPON, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -1, ""),
REGISTER_COMMAND(COMMAND_REGISTER_KILL_FRENZY_PASSED, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CHAR_SAY, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_NEAR_CLIP, INPUT_ARGUMENTS(ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_RADIO_CHANNEL, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_OVERRIDE_HOSPITAL_LEVEL, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_OVERRIDE_POLICE_STATION_LEVEL, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_FORCE_RAIN, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_DOES_GARAGE_CONTAIN_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CAR_TRACTION, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_SAY, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_NEAR_CLIP, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_RADIO_CHANNEL, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_OVERRIDE_HOSPITAL_LEVEL, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_OVERRIDE_POLICE_STATION_LEVEL, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_FORCE_RAIN, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_DOES_GARAGE_CONTAIN_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CAR_TRACTION, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_ARE_MEASUREMENTS_IN_METRES, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_CONVERT_METRES_TO_FEET, INPUT_ARGUMENTS(ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_MARK_ROADS_BETWEEN_LEVELS, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_MARK_PED_ROADS_BETWEEN_LEVELS, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CAR_AVOID_LEVEL_TRANSITIONS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CHAR_AVOID_LEVEL_TRANSITIONS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_THREAT_FOR_PED_TYPE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_CLEAR_AREA_OF_CHARS, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_TOTAL_NUMBER_OF_MISSIONS, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_CONVERT_METRES_TO_FEET_INT, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_REGISTER_FASTEST_TIME, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_REGISTER_HIGHEST_SCORE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_WARP_CHAR_INTO_CAR_AS_PASSENGER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_CAR_PASSENGER_SEAT_FREE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_GET_CHAR_IN_CAR_PASSENGER_SEAT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CHAR_IS_CHRIS_CRIMINAL, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_CONVERT_METRES_TO_FEET, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_MARK_ROADS_BETWEEN_LEVELS, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_MARK_PED_ROADS_BETWEEN_LEVELS, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CAR_AVOID_LEVEL_TRANSITIONS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_AVOID_LEVEL_TRANSITIONS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_THREAT_FOR_PED_TYPE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_CLEAR_AREA_OF_CHARS, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_TOTAL_NUMBER_OF_MISSIONS, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_CONVERT_METRES_TO_FEET_INT, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_REGISTER_FASTEST_TIME, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_REGISTER_HIGHEST_SCORE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_WARP_CHAR_INTO_CAR_AS_PASSENGER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_CAR_PASSENGER_SEAT_FREE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_CHAR_IN_CAR_PASSENGER_SEAT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_IS_CHRIS_CRIMINAL, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_START_CREDITS, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_STOP_CREDITS, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_ARE_CREDITS_FINISHED, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_CREATE_SINGLE_PARTICLE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CHAR_IGNORE_LEVEL_TRANSITIONS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_GET_CHASE_CAR, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_CREATE_SINGLE_PARTICLE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_IGNORE_LEVEL_TRANSITIONS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_CHASE_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -1, ""),
REGISTER_COMMAND(COMMAND_START_BOAT_FOAM_ANIMATION, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_UPDATE_BOAT_FOAM_ANIMATION, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_MUSIC_DOES_FADE, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_INTRO_IS_PLAYING, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_PLAYER_HOOKER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_UPDATE_BOAT_FOAM_ANIMATION, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_MUSIC_DOES_FADE, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_INTRO_IS_PLAYING, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_PLAYER_HOOKER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_PLAY_END_OF_GAME_TUNE, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_STOP_END_OF_GAME_TUNE, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_GET_CAR_MODEL, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_PLAYER_SITTING_IN_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_PLAYER_SITTING_IN_ANY_CAR, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_SCRIPT_FIRE_AUDIO, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_CAR_MODEL, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_PLAYER_SITTING_IN_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_PLAYER_SITTING_IN_ANY_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_SCRIPT_FIRE_AUDIO, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_ARE_ANY_CAR_CHEATS_ACTIVATED, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CHAR_SUFFERS_CRITICAL_HITS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_PLAYER_LIFTING_A_PHONE, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_CHAR_SITTING_IN_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_CHAR_SITTING_IN_ANY_CAR, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_PLAYER_ON_FOOT, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_CHAR_ON_FOOT, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_LOAD_COLLISION_WITH_SCREEN, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_LOAD_SPLASH_SCREEN, INPUT_ARGUMENTS(ARGTYPE_STRING,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CAR_IGNORE_LEVEL_TRANSITIONS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_MAKE_CRAIGS_CAR_A_BIT_STRONGER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_JAMES_CAR_ON_PATH_TO_PLAYER, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_SUFFERS_CRITICAL_HITS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_PLAYER_LIFTING_A_PHONE, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_CHAR_SITTING_IN_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_CHAR_SITTING_IN_ANY_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_PLAYER_ON_FOOT, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_CHAR_ON_FOOT, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_LOAD_COLLISION_WITH_SCREEN, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_LOAD_SPLASH_SCREEN, INPUT_ARGUMENTS(ARGTYPE_STRING, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CAR_IGNORE_LEVEL_TRANSITIONS, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_MAKE_CRAIGS_CAR_A_BIT_STRONGER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ 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, ""),
-#ifndef GTA_PS2
- 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, ""),
- REGISTER_COMMAND(COMMAND_IS_PLAYER_TARGETTING_ANY_CHAR, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_PLAYER_TARGETTING_CHAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_IS_PLAYER_TARGETTING_OBJECT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_TERMINATE_ALL_SCRIPTS_WITH_THIS_NAME, INPUT_ARGUMENTS(ARGTYPE_STRING,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_DISPLAY_TEXT_WITH_NUMBER, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_STRING, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_DISPLAY_TEXT_WITH_2_NUMBERS, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
+ 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, ""),
+ REGISTER_COMMAND(COMMAND_IS_PLAYER_TARGETTING_ANY_CHAR, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_PLAYER_TARGETTING_CHAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_IS_PLAYER_TARGETTING_OBJECT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_TERMINATE_ALL_SCRIPTS_WITH_THIS_NAME, INPUT_ARGUMENTS(ARGTYPE_STRING, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_DISPLAY_TEXT_WITH_NUMBER, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_STRING, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_DISPLAY_TEXT_WITH_2_NUMBERS, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
REGISTER_COMMAND(COMMAND_FAIL_CURRENT_MISSION, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_GET_CLOSEST_OBJECT_OF_TYPE, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_PLACE_OBJECT_RELATIVE_TO_OBJECT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_ALL_OCCUPANTS_OF_CAR_LEAVE_CAR, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_INTERPOLATION_PARAMETERS, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_GET_CLOSEST_CAR_NODE_WITH_HEADING_TOWARDS_POINT, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_GET_CLOSEST_CAR_NODE_WITH_HEADING_AWAY_POINT, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_GET_DEBUG_CAMERA_POINT_AT, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_ATTACH_CHAR_TO_CAR, 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_DETACH_CHAR_FROM_CAR, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CAR_CHANGE_LANE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_CLEAR_CHAR_LAST_WEAPON_DAMAGE, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_CLEAR_CAR_LAST_WEAPON_DAMAGE, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_GET_RANDOM_COP_IN_AREA, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_GET_RANDOM_COP_IN_ZONE, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_FLEE_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_GET_DRIVER_OF_CAR, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_GET_NUMBER_OF_FOLLOWERS, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_GIVE_REMOTE_CONTROLLED_MODEL_TO_PLAYER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, -1, ""),
- REGISTER_COMMAND(COMMAND_GET_CURRENT_PLAYER_WEAPON, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_GET_CURRENT_CHAR_WEAPON, INPUT_ARGUMENTS(ARGTYPE_INT,), OUTPUT_ARGUMENTS(ARGTYPE_INT,), false, -1, ""),
- REGISTER_COMMAND(COMMAND_LOCATE_CHAR_ANY_MEANS_OBJECT_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_LOCATE_CHAR_ON_FOOT_OBJECT_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- REGISTER_COMMAND(COMMAND_LOCATE_CHAR_IN_CAR_OBJECT_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), true, -1, ""),
- 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_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_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_GET_CLOSEST_OBJECT_OF_TYPE, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_PLACE_OBJECT_RELATIVE_TO_OBJECT, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_ALL_OCCUPANTS_OF_CAR_LEAVE_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_INTERPOLATION_PARAMETERS, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_CLOSEST_CAR_NODE_WITH_HEADING_TOWARDS_POINT, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_CLOSEST_CAR_NODE_WITH_HEADING_AWAY_POINT, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_DEBUG_CAMERA_POINT_AT, INPUT_ARGUMENTS(), OUTPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_ATTACH_CHAR_TO_CAR, 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_DETACH_CHAR_FROM_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CAR_CHANGE_LANE, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_CLEAR_CHAR_LAST_WEAPON_DAMAGE, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_CLEAR_CAR_LAST_WEAPON_DAMAGE, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_RANDOM_COP_IN_AREA, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_RANDOM_COP_IN_ZONE, INPUT_ARGUMENTS(ARGTYPE_STRING, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_SET_CHAR_OBJ_FLEE_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_DRIVER_OF_CAR, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_NUMBER_OF_FOLLOWERS, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_GIVE_REMOTE_CONTROLLED_MODEL_TO_PLAYER, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_CURRENT_PLAYER_WEAPON, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_GET_CURRENT_CHAR_WEAPON, INPUT_ARGUMENTS(ARGTYPE_INT, ), OUTPUT_ARGUMENTS(ARGTYPE_INT, ), false, -1, ""),
+ REGISTER_COMMAND(COMMAND_LOCATE_CHAR_ANY_MEANS_OBJECT_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_LOCATE_CHAR_ON_FOOT_OBJECT_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ REGISTER_COMMAND(COMMAND_LOCATE_CHAR_IN_CAR_OBJECT_2D, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT, ARGTYPE_FLOAT, ARGTYPE_FLOAT, ARGTYPE_INT, ), OUTPUT_ARGUMENTS(), true, -1, ""),
+ 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_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(), 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, ""),
+ 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
@@ -1318,7 +1652,6 @@ void FlushLog()
#endif
}
-
const uint32 CRunningScript::nSaveStructSize =
#ifdef COMPATIBLE_SAVES
136;
@@ -1360,10 +1693,46 @@ void CMissionCleanup::AddEntityToList(int32 id, uint8 type)
m_nCount++;
}
+static void PossiblyWakeThisEntity(CPhysical* pEntity, bool ifColLoaded = false)
+{
+ if (!pEntity->bIsStaticWaitingForCollision)
+ return;
+ if (!ifColLoaded || CColStore::HasCollisionLoaded(pEntity->GetPosition())) {
+ pEntity->bIsStaticWaitingForCollision = false;
+ if (!pEntity->GetIsStatic())
+ pEntity->AddToMovingList();
+ }
+}
+
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* v = CPools::GetVehiclePool()->GetAt(m_sEntities[i].id);
+ if (v)
+ PossiblyWakeThisEntity(v);
+ break;
+ }
+ case CLEANUP_CHAR:
+ {
+ CPed* p = CPools::GetPedPool()->GetAt(m_sEntities[i].id);
+ if (p)
+ PossiblyWakeThisEntity(p);
+ break;
+ }
+ case CLEANUP_OBJECT:
+ {
+ CObject* o = CPools::GetObjectPool()->GetAt(m_sEntities[i].id);
+ if (o)
+ PossiblyWakeThisEntity(o);
+ break;
+ }
+ default:
+ break;
+ }
m_sEntities[i].id = 0;
m_sEntities[i].type = CLEANUP_UNUSED;
m_nCount--;
@@ -1371,15 +1740,70 @@ 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* v = CPools::GetVehiclePool()->GetAt(m_sEntities[i].id);
+ if (v)
+ PossiblyWakeThisEntity(v, true);
+ break;
+ }
+ case CLEANUP_CHAR:
+ {
+ CPed* p = CPools::GetPedPool()->GetAt(m_sEntities[i].id);
+ if (p)
+ PossiblyWakeThisEntity(p, true);
+ break;
+ }
+ case CLEANUP_OBJECT:
+ {
+ CObject* o = CPools::GetObjectPool()->GetAt(m_sEntities[i].id);
+ if (o)
+ PossiblyWakeThisEntity(o, true);
+ break;
+ }
+ default:
+ break;
+ }
+ }
+}
+
+CPhysical* CMissionCleanup::DoesThisEntityWaitForCollision(int i)
+{
+ if (m_sEntities[i].type == CLEANUP_CAR) {
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(m_sEntities[i].id);
+ if (pVehicle && pVehicle->GetStatus() != STATUS_WRECKED)
+ return pVehicle;
+ }
+ else if (m_sEntities[i].type == CLEANUP_CHAR) {
+ CPed* pPed = CPools::GetPedPool()->GetAt(m_sEntities[i].id);
+ if (pPed && !pPed->DyingOrDead())
+ return pPed;
+ }
+ return nil;
+}
+
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);
@@ -1389,9 +1813,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(0);
+ CVehicle::bDisableRemoteDetonation = false;
+ CVehicle::bDisableRemoteDetonationOnContact = false;
+ CGameLogic::ClearShortCut();
+ CTheScripts::RiotIntensity = 0;
CTheScripts::StoreVehicleIndex = -1;
CTheScripts::StoreVehicleWasRandom = true;
CTheScripts::UpsideDownCars.Init();
@@ -1581,11 +2015,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:
@@ -1604,10 +2038,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;
@@ -1618,13 +2048,13 @@ void CRunningScript::CollectParameters(uint32* pIp, int16 total)
#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);
@@ -1644,9 +2074,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);
@@ -1680,7 +2107,6 @@ void CRunningScript::GetStoredParameterForDebug(char* buf)
int32 CRunningScript::CollectNextParameterWithoutIncreasingPC(uint32 ip)
{
uint32* pIp = &ip;
- float tmp;
switch (CTheScripts::Read1ByteFromScript(pIp))
{
case ARGUMENT_INT32:
@@ -1694,8 +2120,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);
}
@@ -1743,6 +2168,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;
@@ -1757,6 +2183,7 @@ void CRunningScript::Init()
#ifdef USE_DEBUG_SCRIPT_LOADER
int scriptToLoad = 0;
+const char *scriptfile = "main.scm";
#ifdef _WIN32
#include <Windows.h>
@@ -1773,11 +2200,11 @@ int open_script()
scriptToLoad = 2;
#endif
switch (scriptToLoad) {
- case 0: return CFileMgr::OpenFile("main.scm", "rb");
- case 1: return CFileMgr::OpenFile("main_freeroam.scm", "rb");
- case 2: return CFileMgr::OpenFile("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("main.scm", "rb");
+ return CFileMgr::OpenFile(scriptfile, "rb");
}
#endif
@@ -1805,15 +2232,7 @@ void CTheScripts::Init()
StoreVehicleIndex = -1;
StoreVehicleWasRandom = true;
OnAMissionFlag = 0;
- for (int i = 0; i < MAX_NUM_CONTACTS; i++){
- BaseBriefIdForContact[i] = 0;
- OnAMissionForContactFlag[i] = 0;
- }
- for (int i = 0; i < MAX_NUM_COLLECTIVES; i++){
- CollectiveArray[i].index = -1;
- CollectiveArray[i].unk_data = 0;
- }
- 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));
@@ -1826,15 +2245,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;
@@ -1855,6 +2276,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;
@@ -1874,6 +2296,15 @@ void CTheScripts::Init()
#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)
{
if (prev)
@@ -1901,6 +2332,7 @@ CRunningScript* CTheScripts::StartNewScript(uint32 ip)
pNew->Init();
pNew->SetIP(ip);
pNew->AddScriptToList(&pActiveScripts);
+ pNew->m_bIsActive = true;
return pNew;
}
@@ -1913,13 +2345,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();
@@ -1988,6 +2417,8 @@ void CTheScripts::Process()
script->UpdateTimers(timeStep);
script->Process();
script = next;
+ if (script && !script->m_bIsActive)
+ script = nil;
}
DbgFlag = false;
#ifdef USE_ADVANCED_SCRIPT_DEBUG_OUTPUT
@@ -2054,7 +2485,7 @@ int8 CRunningScript::ProcessOneCommand()
if (commands[command].position == -1)
strcat(commandInfo, commands[command].name + sizeof("COMMAND_") - 1);
for (int i = 0; commands[command].input[i] != ARGTYPE_NONE; i++) {
- char tmp[16];
+ char tmp[32];
bool var = false;
int value;
switch (commands[command].input[i]) {
@@ -2098,15 +2529,16 @@ int8 CRunningScript::ProcessOneCommand()
retval = ProcessCommands800To899(command);
else if (command < 1000)
retval = ProcessCommands900To999(command);
-#ifdef GTA_PS2
- else if (command < 1200)
- retval = ProcessCommands1000To1099(command);
-#else
else if (command < 1100)
retval = ProcessCommands1000To1099(command);
else if (command < 1200)
retval = ProcessCommands1100To1199(command);
-#endif
+ else if (command < 1300)
+ retval = ProcessCommands1200To1299(command);
+ else if (command < 1400)
+ retval = ProcessCommands1300To1399(command);
+ else if (command < 1500)
+ retval = ProcessCommands1400To1499(command);
#ifdef USE_ADVANCED_SCRIPT_DEBUG_OUTPUT
if (command < ARRAY_SIZE(commands)) {
if (commands[command].cond || commands[command].output[0] != ARGTYPE_NONE) {
@@ -2117,7 +2549,7 @@ int8 CRunningScript::ProcessOneCommand()
m_nIp = ip;
ip = t;
for (int i = 0; commands[command].output[i] != ARGTYPE_NONE; i++) {
- char tmp[16];
+ char tmp[32];
switch (commands[command].output[i]) {
case ARGTYPE_INT:
case ARGTYPE_PED_HANDLE:
@@ -2572,13 +3004,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);
@@ -2614,19 +3044,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)
@@ -2638,6 +3067,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];
@@ -2657,6 +3087,7 @@ int8 CRunningScript::ProcessCommands0To99(int32 command)
CollectParameters(&m_nIp, 1);
script_assert(ScriptParams[0] >= 0);
CRunningScript* pNew = CTheScripts::StartNewScript(ScriptParams[0]);
+ m_bIsActive = true;
int8 type = CTheScripts::Read1ByteFromScript(&m_nIp);
float tmp;
for (int i = 0; type != ARGUMENT_END; type = CTheScripts::Read1ByteFromScript(&m_nIp), i++) {
@@ -2704,7 +3135,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);
@@ -2744,20 +3175,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:
@@ -3193,6 +3653,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);
@@ -3200,6 +3661,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++;
@@ -3213,24 +3676,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;
@@ -3249,22 +3695,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:
@@ -3309,44 +3764,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);
@@ -3354,6 +3792,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);
@@ -3419,15 +3858,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);
@@ -3438,13 +3884,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);
}
@@ -3482,7 +3930,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;
}
@@ -3494,7 +3942,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;
}
@@ -3566,6 +4014,7 @@ int8 CRunningScript::ProcessCommands100To199(int32 command)
}
return 0;
}
+ /*
case COMMAND_IS_CAR_STILL_ALIVE:
{
CollectParameters(&m_nIp, 1);
@@ -3573,6 +4022,7 @@ int8 CRunningScript::ProcessCommands100To199(int32 command)
UpdateCompareFlag(car && car->GetStatus() != STATUS_WRECKED && (car->IsBoat() || !car->bIsInWater));
return 0;
}
+ */
case COMMAND_SET_CAR_CRUISE_SPEED:
{
CollectParameters(&m_nIp, 2);
@@ -3652,40 +4102,38 @@ 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;
#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;
@@ -3718,15 +4166,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;
@@ -3779,8 +4227,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;
}
@@ -3923,29 +4369,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);
@@ -3953,6 +4393,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:
@@ -4019,6 +4460,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);
@@ -4043,6 +4487,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);
@@ -4085,12 +4531,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);
@@ -4099,10 +4547,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);
@@ -4111,14 +4557,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:
@@ -4129,9 +4575,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);
@@ -4141,23 +4585,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;
}
@@ -4165,8 +4607,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:
{
@@ -4176,10 +4616,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);
@@ -4235,6 +4673,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);
@@ -4250,13 +4691,7 @@ int8 CRunningScript::ProcessCommands200To299(int32 command)
pVehicle->AutoPilot.m_nCarMission = MISSION_CRUISE;
pVehicle->bEngineOn = true;
pPed->bUsesCollision = false;
-#ifdef FIX_BUGS
- AnimationId anim = pVehicle->GetDriverAnim();
-#else
- AnimationId anim = pVehicle->bLowVehicle ? ANIM_CAR_LSIT : ANIM_CAR_SIT;
-#endif
- pPed->m_pVehicleAnim = CAnimManager::BlendAnimation(pPed->GetClump(), ASSOCGRP_STD, anim, 100.0f);
- pPed->StopNonPartialAnims();
+ pPed->AddInCarAnims(pVehicle, true);
pPed->m_nZoneLevel = CTheZones::GetLevelFromPosition(&pPed->GetPosition());
CWorld::Add(pPed);
ScriptParams[0] = CPools::GetPedPool()->GetIndex(pPed);
@@ -4285,18 +4720,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_IDLE_STANCE, 100.0f);
+ CAnimManager::BlendAnimation(pPlayer->m_pPed->GetClump(), pPlayer->m_pPed->m_animGroup, ANIM_IDLE_STANCE, 1000.0f);
pPlayer->m_pPed->RestartNonPartialAnims();
AudioManager.PlayerJustLeftCar();
pos.z += pPlayer->m_pPed->GetDistanceFromCentreOfMassToBaseOfModel();
@@ -4304,9 +4739,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;
@@ -4417,7 +4850,7 @@ void RetryMission(int type, int unk)
{
if (type == 0) {
doingMissionRetry = true;
- FrontEndMenuManager.m_nCurrScreen = MENUPAGE_MISSION_RETRY;
+ FrontEndMenuManager.m_nCurrScreen = 57; // MENUPAGE_MISSION_RETRY
FrontEndMenuManager.RequestFrontEndStartUp();
}
else if (type == 2) {
@@ -4450,6 +4883,9 @@ CTheScripts::SwitchToMission(int32 mission)
CMessages::ClearMessages();
}
+ if (CTheScripts::NumberOfExclusiveMissionScripts > 0 && mission <= UINT16_MAX - 2)
+ return;
+
#ifdef MISSION_REPLAY
missionRetryScriptIndex = mission;
if (missionRetryScriptIndex == 19)
@@ -4457,8 +4893,14 @@ CTheScripts::SwitchToMission(int32 mission)
#endif
CTimer::Suspend();
int offset = CTheScripts::MultiScriptArray[mission];
+#ifdef USE_DEBUG_SCRIPT_LOADER
+ CFileMgr::ChangeDir("\\data\\");
+ int handle = CFileMgr::OpenFile(scriptfile, "rb");
+ CFileMgr::ChangeDir("\\");
+#else
CFileMgr::ChangeDir("\\");
int handle = CFileMgr::OpenFile("data\\main.scm", "rb");
+#endif
CFileMgr::Seek(handle, offset, 0);
CFileMgr::Read(handle, (const char*)&CTheScripts::ScriptSpace[SIZE_MAIN_SCRIPT], SIZE_MISSION_SCRIPT);
CFileMgr::CloseFile(handle);
@@ -4467,5 +4909,6 @@ CTheScripts::SwitchToMission(int32 mission)
pMissionScript->m_bIsMissionScript = true;
pMissionScript->m_bMissionFlag = true;
CTheScripts::bAlreadyRunningAMissionScript = true;
+ CGameLogic::ClearShortCut();
}
#endif
diff --git a/src/control/Script.h b/src/control/Script.h
index 7fc18727..983cf6e5 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,11 +21,12 @@ void FlushLog();
#define PICKUP_PLACEMENT_OFFSET 0.5f
#define PED_FIND_Z_OFFSET 5.0f
+#define COP_PED_FIND_Z_OFFSET 10.0f
-#define SPHERE_MARKER_R 0
-#define SPHERE_MARKER_G 128
-#define SPHERE_MARKER_B 255
-#define SPHERE_MARKER_A 128
+#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
@@ -53,7 +55,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
@@ -138,7 +140,7 @@ struct CMissionCleanupEntity
enum {
MAX_CLEANUP = 50,
MAX_UPSIDEDOWN_CAR_CHECKS = 6,
- MAX_STUCK_CAR_CHECKS = 6
+ MAX_STUCK_CAR_CHECKS = 16
};
class CMissionCleanup
@@ -154,6 +156,8 @@ public:
void AddEntityToList(int32, uint8);
void RemoveEntityFromList(int32, uint8);
void Process();
+ void CheckIfCollisionHasLoadedForMissionObjects();
+ CPhysical* DoesThisEntityWaitForCollision(int i);
};
struct CUpsideDownCarCheckEntry
@@ -241,20 +245,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_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,
@@ -265,13 +271,10 @@ class CTheScripts
{
static uint8 ScriptSpace[SIZE_SCRIPT_SPACE];
static CRunningScript ScriptsArray[MAX_NUM_SCRIPTS];
- static int32 BaseBriefIdForContact[MAX_NUM_CONTACTS];
- static int32 OnAMissionForContactFlag[MAX_NUM_CONTACTS];
static intro_text_line IntroTextLines[MAX_NUM_INTRO_TEXT_LINES];
static intro_script_rectangle IntroRectangles[MAX_NUM_INTRO_RECTANGLES];
static CSprite2d ScriptSprites[MAX_NUM_SCRIPT_SRPITES];
static script_sphere_struct ScriptSphereArray[MAX_NUM_SCRIPT_SPHERES];
- static tCollectiveData CollectiveArray[MAX_NUM_COLLECTIVES];
static tUsedObject UsedObjectArray[MAX_NUM_USED_OBJECTS];
static int32 MultiScriptArray[MAX_NUM_MISSION_SCRIPTS];
static tBuildingSwap BuildingSwapArray[MAX_NUM_BUILDING_SWAPS];
@@ -295,15 +298,27 @@ class CTheScripts
static uint32 LargestMissionScriptSize;
static uint32 MainScriptSize;
static uint8 FailCurrentMission;
- static uint8 CountdownToMakePlayerUnsafe;
- static uint8 DelayMakingPlayerUnsafeThisTime;
static uint16 NumScriptDebugLines;
static uint16 NumberOfIntroRectanglesThisFrame;
static uint16 NumberOfIntroTextLinesThisFrame;
static uint8 UseTextCommands;
static uint16 CommandsExecuted;
static uint16 ScriptsUpdated;
-
+ static 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
+public:
+ static bool bPlayerIsInTheStatium;
+ static uint8 RiotIntensity;
+ static bool bPlayerHasMetDebbieHarry;
public:
static void Init();
static void Process();
@@ -326,9 +341,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;
@@ -392,18 +404,22 @@ private:
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
friend class CRunningScript;
friend class CHud;
friend void CMissionCleanup::Process();
-#ifdef MISSION_REPLAY
+ friend class CColStore;
+#ifdef FIX_BUGS
friend void RetryMission(int, int);
#endif
-
-#ifdef MISSION_SWITCHER
-public:
- static void SwitchToMission(int32 mission);
-#endif
};
@@ -442,6 +458,7 @@ class CRunningScript
uint32 m_anStack[MAX_STACK_DEPTH];
uint16 m_nStackPointer;
int32 m_anLocalVariables[NUM_LOCAL_VARS + NUM_TIMERS];
+ bool m_bIsActive;
bool m_bCondResult;
bool m_bIsMissionScript;
bool m_bSkipWakeTime;
@@ -494,9 +511,11 @@ private:
int8 ProcessCommands800To899(int32);
int8 ProcessCommands900To999(int32);
int8 ProcessCommands1000To1099(int32);
-#ifndef GTA_PS2
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*);
@@ -510,6 +529,8 @@ private:
void PlayerInAngledAreaCheckCommand(int32, uint32*);
void CharInAreaCheckCommand(int32, uint32*);
void CarInAreaCheckCommand(int32, uint32*);
+ void LocateObjectCommand(int32, uint32*);
+ void ObjectInAreaCheckCommand(int32, uint32*);
#ifdef MISSION_REPLAY
bool CanAllowMissionReplay();
@@ -522,37 +543,29 @@ private:
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 ThisIsAValidRandomPed(uint32 pedtype, int civ, int gang, int criminal);
+
+ bool CheckDamagedWeaponType(int32 actual, int32 type);
+
+ static bool ThisIsAValidRandomCop(int32 mi, bool cop, bool swat, bool fbi, bool army, bool miami);
friend class CTheScripts;
};
+#ifdef USE_DEBUG_SCRIPT_LOADER
+extern int scriptToLoad;
+#endif
#ifdef MISSION_REPLAY
+static_assert(false, "Mission replay is not supported");
extern int AllowMissionReplay;
extern uint32 WaitForMissionActivate;
extern uint32 WaitForSave;
extern uint32 MissionStartTime;
extern int missionRetryScriptIndex;
extern bool doingMissionRetry;
+extern bool gbTryingPorn4Again;
+extern int IsInAmmunation;
+extern int MissionSkipLevel;
uint32 AddExtraDeathDelay();
void RetryMission(int, int);
@@ -560,4 +573,4 @@ void RetryMission(int, int);
#ifdef USE_DEBUG_SCRIPT_LOADER
extern int scriptToLoad;
-#endif \ No newline at end of file
+#endif
diff --git a/src/control/Script2.cpp b/src/control/Script2.cpp
index 562125c6..93098dac 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_IDLE_STANCE, 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,9 +1136,11 @@ int8 CRunningScript::ProcessCommands400To499(int32 command)
pPed->CharCreatedBy = MISSION_CHAR;
pPed->bRespondsToThreats = false;
pPed->bAllowMedicsToReviveMe = false;
+ pPed->bIsPlayerFriend = false;
+ if (pVehicle->bIsBus)
+ pPed->bRenderPedInCar = false;
pPed->SetPosition(pVehicle->GetPosition());
pPed->SetOrientation(0.0f, 0.0f, 0.0f);
- pPed->SetPedState(PED_DRIVING);
CPopulation::ms_nTotalMissionPeds++;
if (ScriptParams[3] >= 0)
pVehicle->AddPassenger(pPed, ScriptParams[3]);
@@ -1150,16 +1149,10 @@ int8 CRunningScript::ProcessCommands400To499(int32 command)
pPed->m_pMyVehicle = pVehicle;
pPed->m_pMyVehicle->RegisterReference((CEntity**)&pPed->m_pMyVehicle);
pPed->bInVehicle = true;
- pPed->SetPedState(PED_DRIVING);
pVehicle->SetStatus(STATUS_PHYSICS);
+ pPed->SetPedState(PED_DRIVING);
pPed->bUsesCollision = false;
-#ifdef FIX_BUGS
- AnimationId anim = pVehicle->GetDriverAnim();
-#else
- AnimationId anim = pVehicle->bLowVehicle ? ANIM_CAR_LSIT : ANIM_CAR_SIT;
-#endif
- pPed->m_pVehicleAnim = CAnimManager::BlendAnimation(pPed->GetClump(), ASSOCGRP_STD, anim, 100.0f);
- pPed->StopNonPartialAnims();
+ pPed->AddInCarAnims(pVehicle, false);
pPed->m_nZoneLevel = CTheZones::GetLevelFromPosition(&pPed->GetPosition());
CWorld::Add(pPed);
ScriptParams[0] = CPools::GetPedPool()->GetIndex(pPed);
@@ -1208,6 +1201,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 +1212,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 +1293,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);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[1]);
+ pPed->bScriptObjectiveCompleted = false;
+ pPed->SetObjective(OBJECTIVE_DESTROY_OBJECT, pVehicle);
+ return 0;
+ }
case COMMAND_SET_CHAR_OBJ_DESTROY_CAR:
{
CollectParameters(&m_nIp, 2);
@@ -1313,6 +1315,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 +1342,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 +1408,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 +1486,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 +1506,7 @@ int8 CRunningScript::ProcessCommands400To499(int32 command)
pPed->m_fearFlags = 0;
return 0;
}
+ /*
case COMMAND_ACTIVATE_CRANE:
{
CollectParameters(&m_nIp, 10);
@@ -1524,28 +1534,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 1f1ed537..2fe8b41f 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"
int8 CRunningScript::ProcessCommands500To599(int32 command)
{
@@ -70,6 +72,7 @@ int8 CRunningScript::ProcessCommands500To599(int32 command)
}
return 0;
}
+ /*
case COMMAND_ADD_PAGER_MESSAGE_WITH_NUMBER:
{
wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
@@ -78,6 +81,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);
@@ -144,7 +148,7 @@ int8 CRunningScript::ProcessCommands500To599(int32 command)
}
case COMMAND_ADD_EXPLOSION:
CollectParameters(&m_nIp, 4);
- CExplosion::AddExplosion(nil, nil, (eExplosionType)ScriptParams[3], *(CVector*)&ScriptParams[0], 0);
+ CExplosion::AddExplosion(nil, nil, (eExplosionType)ScriptParams[3], *(CVector*)&ScriptParams[0], 0, true);
return 0;
case COMMAND_IS_CAR_UPRIGHT:
@@ -222,7 +226,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:
{
@@ -262,6 +265,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);
@@ -270,56 +274,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);
@@ -377,6 +364,7 @@ int8 CRunningScript::ProcessCommands500To599(int32 command)
return 0;
}
#endif // GTA_PS2
+ /*
case COMMAND_SET_ALL_TAXI_LIGHTS:
CollectParameters(&m_nIp, 1);
CAutomobile::SetAllTaxiLights(ScriptParams[0] != 0);
@@ -390,6 +378,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);
@@ -399,7 +388,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:
@@ -416,7 +405,7 @@ int8 CRunningScript::ProcessCommands500To599(int32 command)
pPed->FlagToDestroyWhenNextProcessed();
}
else {
- pPed->SetDie(ANIM_KO_SHOT_FRONT1, 4.0f, 0.0f);
+ pPed->SetDie();
}
return 0;
}
@@ -433,7 +422,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;
}
@@ -442,7 +431,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;
}
@@ -451,19 +440,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);
@@ -577,15 +568,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]);
@@ -594,6 +589,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);
@@ -620,6 +616,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);
@@ -633,6 +630,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);
@@ -661,6 +659,7 @@ int8 CRunningScript::ProcessCommands500To599(int32 command)
UpdateCompareFlag(isTouching);
return 0;
}
+ */
case COMMAND_LOAD_SPECIAL_CHARACTER:
{
CollectParameters(&m_nIp, 1);
@@ -678,6 +677,7 @@ int8 CRunningScript::ProcessCommands500To599(int32 command)
UpdateCompareFlag(CStreaming::HasSpecialCharLoaded(ScriptParams[0] - 1));
return 0;
}
+ /*
case COMMAND_FLASH_CAR:
{
CollectParameters(&m_nIp, 2);
@@ -702,10 +702,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);
@@ -716,6 +718,7 @@ int8 CRunningScript::ProcessCommands500To599(int32 command)
((CAutomobile*)pVehicle)->m_pBombRigger = FindPlayerPed();
return 0;
}
+ */
case COMMAND_SET_CHAR_PERSONALITY:
{
CollectParameters(&m_nIp, 2);
@@ -736,6 +739,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);
@@ -744,6 +748,7 @@ int8 CRunningScript::ProcessCommands500To599(int32 command)
pPed->m_animGroup = (AssocGroupId)ScriptParams[1];
return 0;
}
+ */
case COMMAND_REQUEST_MODEL:
{
CollectParameters(&m_nIp, 1);
@@ -778,6 +783,7 @@ int8 CRunningScript::ProcessCommands500To599(int32 command)
StoreParameters(&m_nIp, 1);
return 0;
}
+ /*
case COMMAND_SET_REPEATED_PHONE_MESSAGE:
{
CollectParameters(&m_nIp, 1);
@@ -798,6 +804,7 @@ int8 CRunningScript::ProcessCommands500To599(int32 command)
UpdateCompareFlag(gPhoneInfo.HasMessageBeenDisplayed(ScriptParams[0]));
return 0;
}
+ */
case COMMAND_TURN_PHONE_OFF:
{
CollectParameters(&m_nIp, 1);
@@ -823,18 +830,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);
@@ -847,6 +851,7 @@ int8 CRunningScript::ProcessCommands500To599(int32 command)
CWorld::Players[CWorld::PlayerInFocus].PlayerFailedCriticalMission();
return 0;
}
+ */
case COMMAND_IS_PLAYER_PLAYING:
{
CollectParameters(&m_nIp, 1);
@@ -951,19 +956,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);
@@ -976,6 +987,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]);
@@ -991,12 +1003,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);
@@ -1004,6 +1017,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);
@@ -1012,6 +1028,7 @@ int8 CRunningScript::ProcessCommands600To699(int32 command)
CTheScripts::MissionCleanup.AddEntityToList(ScriptParams[0], CLEANUP_OBJECT);
return 0;
}
+ /*
case COMMAND_IS_BOAT:
{
CollectParameters(&m_nIp, 1);
@@ -1046,6 +1063,7 @@ int8 CRunningScript::ProcessCommands600To699(int32 command)
pPed->SetObjective(OBJECTIVE_GOTO_AREA_ANY_MEANS, pos, radius);
return 0;
}
+ */
//case COMMAND_SET_COLL_OBJ_GOTO_AREA_ANY_MEANS:
case COMMAND_IS_PLAYER_STOPPED:
{
@@ -1053,7 +1071,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);
@@ -1076,6 +1096,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)
@@ -1083,6 +1104,7 @@ int8 CRunningScript::ProcessCommands600To699(int32 command)
else
TheCamera.SetWideScreenOff();
return 0;
+ /*
case COMMAND_ADD_SPRITE_BLIP_FOR_CAR:
{
CollectParameters(&m_nIp, 2);
@@ -1119,6 +1141,7 @@ int8 CRunningScript::ProcessCommands600To699(int32 command)
StoreParameters(&m_nIp, 1);
return 0;
}
+ */
case COMMAND_ADD_SPRITE_BLIP_FOR_CONTACT_POINT:
{
CollectParameters(&m_nIp, 4);
@@ -1199,6 +1222,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]);
@@ -1212,6 +1236,7 @@ int8 CRunningScript::ProcessCommands600To699(int32 command)
CollectParameters(&m_nIp, 2);
UpdateCompareFlag(CGarages::HasThisCarBeenCollected(ScriptParams[0], ScriptParams[1] - 1));
return 0;
+ */
default:
script_assert(0);
}
@@ -1221,6 +1246,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);
@@ -1233,6 +1259,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);
@@ -1246,7 +1273,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;
@@ -1257,8 +1284,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;
}
@@ -1277,10 +1303,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]);
@@ -1311,6 +1338,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);
@@ -1335,6 +1363,7 @@ int8 CRunningScript::ProcessCommands700To799(int32 command)
UpdateCompareFlag(TheCamera.IsSphereVisible(pObject->GetBoundCentre(), pObject->GetBoundRadius()));
return 0;
}
+ /*
case COMMAND_GOSUB_FILE:
{
CollectParameters(&m_nIp, 2);
@@ -1344,6 +1373,7 @@ int8 CRunningScript::ProcessCommands700To799(int32 command)
// ScriptParams[1] == filename
return 0;
}
+ */
case COMMAND_GET_GROUND_Z_FOR_3D_COORD:
{
CollectParameters(&m_nIp, 3);
@@ -1371,6 +1401,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);
@@ -1379,6 +1410,7 @@ int8 CRunningScript::ProcessCommands700To799(int32 command)
pVehicle->bComedyControls = (ScriptParams[1] != 0);
return 0;
}
+ */
case COMMAND_BOAT_GOTO_COORDS:
{
CollectParameters(&m_nIp, 4);
@@ -1392,7 +1424,7 @@ int8 CRunningScript::ProcessCommands700To799(int32 command)
pBoat->AutoPilot.m_nCarMission = MISSION_GOTOCOORDS_ASTHECROWSWIMS;
pBoat->AutoPilot.m_vecDestinationCoors = pos;
pBoat->SetStatus(STATUS_PHYSICS);
- pBoat->AutoPilot.m_nCruiseSpeed = Max(6, pBoat->AutoPilot.m_nCruiseSpeed);
+ pBoat->AutoPilot.m_nCruiseSpeed = Max(1, pBoat->AutoPilot.m_nCruiseSpeed);
pBoat->AutoPilot.m_nAntiReverseTimer = CTimer::GetTimeInMilliseconds();
return 0;
}
@@ -1446,7 +1478,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:
@@ -1454,9 +1486,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;
@@ -1469,6 +1502,7 @@ int8 CRunningScript::ProcessCommands700To799(int32 command)
CPacManPickups::GenerateOnePMPickUp(pos);
return 0;
}
+ */
case COMMAND_SET_BOAT_CRUISE_SPEED:
{
CollectParameters(&m_nIp, 2);
@@ -1479,6 +1513,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);
@@ -1503,8 +1538,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)
@@ -1527,14 +1562,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();
@@ -1552,9 +1589,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;
@@ -1564,6 +1601,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;
@@ -1684,6 +1725,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);
@@ -1754,6 +1796,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);
@@ -1773,29 +1816,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]));
@@ -1828,6 +1850,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);
@@ -1856,6 +1879,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);
@@ -1863,6 +1887,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);
@@ -1870,6 +1895,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);
@@ -1877,6 +1903,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);
@@ -1891,6 +1918,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);
@@ -1898,6 +1926,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);
@@ -1933,6 +1962,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);
@@ -1940,6 +1970,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);
@@ -1965,6 +1996,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];
@@ -1972,6 +2004,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);
@@ -2018,6 +2052,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:
@@ -2031,6 +2067,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);
@@ -2047,22 +2084,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:
diff --git a/src/control/Script4.cpp b/src/control/Script4.cpp
index afd6eba4..e8475473 100644
--- a/src/control/Script4.cpp
+++ b/src/control/Script4.cpp
@@ -38,6 +38,24 @@
#include "WaterLevel.h"
#include "World.h"
#include "Zones.h"
+#include "Bike.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)
{
@@ -58,17 +76,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_KO_SHOT_FRONT1, 4.0f, 0.0f);
- }
+ pPed->InflictDamage(nil, WEAPONTYPE_SNIPERRIFLE, 1000.0f, PEDPIECE_HEAD, 0);
return 0;
}
case COMMAND_EXPLODE_PLAYER_HEAD:
@@ -76,12 +84,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_KO_SHOT_FRONT1, 4.0f, 0.0f);
- }
+ pPed->InflictDamage(nil, WEAPONTYPE_SNIPERRIFLE, 1000.0f, PEDPIECE_HEAD, 0);
return 0;
}
case COMMAND_ANCHOR_BOAT:
@@ -89,7 +92,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
CollectParameters(&m_nIp, 2);
CBoat* pBoat = (CBoat*)CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
script_assert(pBoat && pBoat->m_vehType == VEHICLE_TYPE_BOAT);
- pBoat->m_bIsAnchored = (ScriptParams[1] != 0);
+ pBoat->m_bIsAnchored = (ScriptParams[1] == 0);
return 0;
}
case COMMAND_SET_ZONE_GROUP:
@@ -98,7 +101,7 @@ 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;
@@ -137,6 +140,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)
@@ -154,14 +161,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();
@@ -186,6 +194,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
StoreParameters(&m_nIp, 1);
return 0;
}
+ */
case COMMAND_HAS_RESPRAY_HAPPENED:
{
CollectParameters(&m_nIp, 1);
@@ -225,6 +234,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
CCarAI::TellCarToRamOtherCar(pVehicle, pTarget);
return 0;
}
+ /*
case COMMAND_SET_CAR_BLOCK_CAR:
{
CollectParameters(&m_nIp, 2);
@@ -244,6 +254,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
pPed->SetObjective(OBJECTIVE_CATCH_TRAIN);
return 0;
}
+ */
//case COMMAND_SET_COLL_OBJ_CATCH_TRAIN:
case COMMAND_SET_PLAYER_NEVER_GETS_TIRED:
{
@@ -267,6 +278,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
pPed->bPedIsBleeding = (ScriptParams[1] != 0);
return 0;
}
+ /*
case COMMAND_SET_CAR_FUNNY_SUSPENSION:
{
CollectParameters(&m_nIp, 2);
@@ -285,6 +297,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);
@@ -305,6 +318,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
pPed->bIsVisible = (ScriptParams[1] != 0);
return 0;
}
+ /*
case COMMAND_SET_CAR_VISIBLE:
{
CollectParameters(&m_nIp, 2);
@@ -313,6 +327,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
pVehicle->bIsVisible = (ScriptParams[1] != 0);
return 0;
}
+ */
case COMMAND_IS_AREA_OCCUPIED:
{
CollectParameters(&m_nIp, 11);
@@ -340,6 +355,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
UpdateCompareFlag(total > 0);
return 0;
}
+ /*
case COMMAND_START_DRUG_RUN:
CPlane::CreateIncomingCesna();
return 0;
@@ -353,6 +369,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);
@@ -399,18 +416,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);
@@ -424,12 +444,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);
@@ -447,6 +469,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
case COMMAND_SUBURBAN_PASSED:
CStats::SuburbanPassed = true;
return 0;
+ */
case COMMAND_ROTATE_OBJECT:
{
CollectParameters(&m_nIp, 4);
@@ -508,10 +531,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);
@@ -564,28 +591,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)
@@ -600,9 +615,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);
@@ -612,13 +629,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:
@@ -626,12 +638,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();
@@ -672,10 +682,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;
@@ -703,6 +713,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
StoreParameters(&m_nIp, 1);
return 0;
}
+ */
case COMMAND_PLACE_OBJECT_RELATIVE_TO_CAR:
{
CollectParameters(&m_nIp, 5);
@@ -729,7 +740,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:
@@ -755,7 +766,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)
@@ -768,26 +779,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_vehEnterType) {
+ if (pPed->GetPedState() == PED_EXIT_CAR || pPed->GetPedState() == PED_DRAG_FROM_CAR) {
+ uint8 flags = 0;
+ if (pPed->m_pMyVehicle->IsBike()) {
+ if (pPed->m_vehEnterType == CAR_DOOR_LF ||
+ pPed->m_vehEnterType == CAR_DOOR_RF ||
+ pPed->m_vehEnterType == CAR_WINDSCREEN)
+ flags = CAR_DOOR_FLAG_LF | CAR_DOOR_FLAG_RF;
+ else if (pPed->m_vehEnterType == CAR_DOOR_LR ||
+ pPed->m_vehEnterType == CAR_DOOR_RR)
+ flags = CAR_DOOR_FLAG_LR | CAR_DOOR_FLAG_RR;
+ }
+ else {
+ switch (pPed->m_vehEnterType) {
+ case CAR_DOOR_LF:
+ flags = pPed->m_pMyVehicle->m_nNumMaxPassengers != 0 ? CAR_DOOR_FLAG_LF : CAR_DOOR_FLAG_LF | CAR_DOOR_FLAG_LR;
+ 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_vehEnterType, NUM_STD_ANIMS, 0.0f);
+ }
+ }
}
+ pPed->RemoveInCarAnims();
pPed->bInVehicle = false;
pPed->m_pMyVehicle = nil;
pPed->SetPedState(PED_IDLE);
pPed->m_nLastPedState = PED_NONE;
pPed->bUsesCollision = true;
pPed->SetMoveSpeed(0.0f, 0.0f, 0.0f);
- pPed->AddWeaponModel(CWeaponInfo::GetWeaponInfo(pPed->m_weapons[pPed->m_currentWeapon].m_eWeaponType)->m_nModelId);
- pPed->RemoveInCarAnims();
+ pPed->ReplaceWeaponWhenExitingVehicle();
if (pPed->m_pVehicleAnim)
pPed->m_pVehicleAnim->blendDelta = -1000.0f;
pPed->m_pVehicleAnim = nil;
pPed->RestartNonPartialAnims();
pPed->SetMoveState(PEDMOVE_NONE);
- CAnimManager::BlendAnimation(pPed->GetClump(), pPed->m_animGroup, ANIM_IDLE_STANCE, 100.0f);
+ CAnimManager::BlendAnimation(pPed->GetClump(), pPed->m_animGroup, ANIM_IDLE_STANCE, 1000.0f);
pos.z += pPed->GetDistanceFromCentreOfMassToBaseOfModel();
pPed->Teleport(pos);
CTheScripts::ClearSpaceForMissionEntity(pos, pPed);
@@ -807,7 +850,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++) {
@@ -823,6 +866,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
}
return 0;
}
+ /*
case COMMAND_HAS_CHAR_SPOTTED_CHAR:
{
CollectParameters(&m_nIp, 2);
@@ -833,6 +877,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
UpdateCompareFlag(pPed->OurPedCanSeeThisOne(pTarget));
return 0;
}
+ */
case COMMAND_SET_CHAR_OBJ_HAIL_TAXI:
{
CollectParameters(&m_nIp, 1);
@@ -850,6 +895,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);
@@ -880,6 +926,7 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
*(float*)&ScriptParams[0], *(float*)&ScriptParams[1]);
return 0;
}
+ */
case COMMAND_WARP_PLAYER_INTO_CAR:
{
CollectParameters(&m_nIp, 2);
@@ -911,6 +958,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);
@@ -939,6 +987,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);
@@ -950,6 +999,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]);
@@ -962,6 +1012,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);
@@ -984,6 +1035,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);
@@ -991,6 +1043,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++;
@@ -1009,6 +1063,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);
@@ -1063,6 +1118,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);
@@ -1087,9 +1143,11 @@ int8 CRunningScript::ProcessCommands800To899(int32 command)
UpdateCompareFlag(CBulletInfo::TestForSniperBullet(infX, supX, infY, supY, infZ, supZ));
return 0;
}
+ /*
case COMMAND_GIVE_PLAYER_DETONATOR:
CGarages::GivePlayerDetonator();
return 0;
+ */
//case COMMAND_SET_COLL_OBJ_STEAL_ANY_CAR:
case COMMAND_SET_OBJECT_VELOCITY:
{
@@ -1139,6 +1197,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);
@@ -1185,6 +1244,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);
@@ -1215,16 +1275,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:
@@ -1278,9 +1346,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:
@@ -1302,6 +1368,7 @@ int8 CRunningScript::ProcessCommands900To999(int32 command)
}
return 0;
}
+ /*
case COMMAND_SET_CHAR_ANIM_SPEED:
{
CollectParameters(&m_nIp, 2);
@@ -1312,6 +1379,7 @@ int8 CRunningScript::ProcessCommands900To999(int32 command)
pAssoc->speed = *(float*)&ScriptParams[1];
return 0;
}
+ */
case COMMAND_PLAY_MISSION_PASSED_TUNE:
{
CollectParameters(&m_nIp, 1);
@@ -1340,6 +1408,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);
@@ -1362,14 +1431,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:
@@ -1413,6 +1488,7 @@ int8 CRunningScript::ProcessCommands900To999(int32 command)
pVehicle->SetHeading(heading);
return 0;
}
+ /*
case COMMAND_IS_CRANE_LIFTING_CAR:
{
CollectParameters(&m_nIp, 3);
@@ -1420,6 +1496,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);
@@ -1456,6 +1533,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);
@@ -1466,6 +1544,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);
@@ -1493,7 +1572,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:
{
@@ -1532,6 +1611,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;
@@ -1544,6 +1624,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);
@@ -1559,7 +1640,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++) {
@@ -1590,6 +1671,7 @@ int8 CRunningScript::ProcessCommands900To999(int32 command)
pPed->ClearWeapons();
return 0;
}
+ /*
case COMMAND_GRAB_CATALINA_HELI:
{
CHeli* pHeli = CHeli::FindPointerToCatalinasHeli();
@@ -1597,6 +1679,7 @@ int8 CRunningScript::ProcessCommands900To999(int32 command)
StoreParameters(&m_nIp, 1);
return 0;
}
+ */
case COMMAND_CLEAR_AREA_OF_CARS:
{
CollectParameters(&m_nIp, 6);
@@ -1641,9 +1724,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);
@@ -1678,18 +1763,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:
@@ -1700,7 +1788,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:
@@ -1717,23 +1805,21 @@ int8 CRunningScript::ProcessCommands900To999(int32 command)
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:
@@ -1741,56 +1827,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]);
@@ -1806,7 +1931,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();
@@ -1827,10 +1956,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];
@@ -1838,6 +1969,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);
@@ -1846,6 +1978,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]));
@@ -1854,9 +1987,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:
@@ -1878,21 +2019,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);
@@ -1900,7 +2051,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;
@@ -1925,21 +2076,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);
@@ -1949,6 +2106,7 @@ int8 CRunningScript::ProcessCommands900To999(int32 command)
StoreParameters(&m_nIp, 1);
return 0;
}
+ */
case COMMAND_ADD_BLIP_FOR_PICKUP:
{
CollectParameters(&m_nIp, 1);
@@ -1960,6 +2118,7 @@ int8 CRunningScript::ProcessCommands900To999(int32 command)
StoreParameters(&m_nIp, 1);
return 0;
}
+ /*
case COMMAND_ADD_SPRITE_BLIP_FOR_PICKUP:
{
CollectParameters(&m_nIp, 2);
@@ -1971,6 +2130,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];
@@ -1979,18 +2139,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;
@@ -2004,8 +2171,8 @@ int8 CRunningScript::ProcessCommands900To999(int32 command)
if (CCamera::m_bUseMouse3rdPerson && (
strncmp((char*)&CTheScripts::ScriptSpace[m_nIp], "HELP15", 7) == 0 ||
strncmp((char*)&CTheScripts::ScriptSpace[m_nIp], "GUN_2A", 7) == 0 ||
- strncmp((char*)&CTheScripts::ScriptSpace[m_nIp], "GUN_3A", 7) == 0 ||
- strncmp((char*)&CTheScripts::ScriptSpace[m_nIp], "GUN_4A", 7) == 0)) {
+ strncmp((char*)&CTheScripts::ScriptSpace[m_nIp], "GUN_2C", 7) == 0 ||
+ strncmp((char*)&CTheScripts::ScriptSpace[m_nIp], "GUN_2D", 7) == 0)) {
m_nIp += KEY_LENGTH_IN_SCRIPT;
return 0;
}
diff --git a/src/control/Script5.cpp b/src/control/Script5.cpp
index 153f2393..5b7b34c5 100644
--- a/src/control/Script5.cpp
+++ b/src/control/Script5.cpp
@@ -330,7 +330,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:
@@ -731,6 +731,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;
@@ -1032,7 +1090,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:
@@ -1228,6 +1286,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)
@@ -1235,7 +1375,7 @@ 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)
@@ -1247,29 +1387,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;
@@ -1304,6 +1422,75 @@ int16 CRunningScript::GetPadState(uint16 pad, uint16 button)
return 0;
}
+bool CRunningScript::CheckDamagedWeaponType(int32 actual, int32 type)
+{
+ if (actual == -1)
+ return false;
+
+ if (type == WEAPONTYPE_ANYMELEE) {
+ if (actual <= WEAPONTYPE_CHAINSAW)
+ return true;
+ if (actual - WEAPONTYPE_GRENADE <= WEAPONTYPE_MINIGUN)
+ return false;
+ return false;
+ }
+
+ if (type != WEAPONTYPE_ANYWEAPON)
+ return false;
+
+ switch (actual) {
+ case WEAPONTYPE_UNARMED:
+ case WEAPONTYPE_BRASSKNUCKLE:
+ case WEAPONTYPE_SCREWDRIVER:
+ case WEAPONTYPE_GOLFCLUB:
+ case WEAPONTYPE_NIGHTSTICK:
+ case WEAPONTYPE_KNIFE:
+ case WEAPONTYPE_BASEBALLBAT:
+ case WEAPONTYPE_HAMMER:
+ case WEAPONTYPE_CLEAVER:
+ case WEAPONTYPE_MACHETE:
+ case WEAPONTYPE_KATANA:
+ case WEAPONTYPE_CHAINSAW:
+ case WEAPONTYPE_GRENADE:
+ case WEAPONTYPE_DETONATOR_GRENADE:
+ case WEAPONTYPE_TEARGAS:
+ case WEAPONTYPE_MOLOTOV:
+ case WEAPONTYPE_ROCKET:
+ case WEAPONTYPE_COLT45:
+ case WEAPONTYPE_PYTHON:
+ case WEAPONTYPE_SHOTGUN:
+ case WEAPONTYPE_SPAS12_SHOTGUN:
+ case WEAPONTYPE_STUBBY_SHOTGUN:
+ case WEAPONTYPE_TEC9:
+ case WEAPONTYPE_UZI:
+ case WEAPONTYPE_SILENCED_INGRAM:
+ case WEAPONTYPE_MP5:
+ case WEAPONTYPE_M4:
+ case WEAPONTYPE_RUGER:
+ case WEAPONTYPE_SNIPERRIFLE:
+ case WEAPONTYPE_LASERSCOPE:
+ case WEAPONTYPE_ROCKETLAUNCHER:
+ case WEAPONTYPE_FLAMETHROWER:
+ case WEAPONTYPE_M60:
+ case WEAPONTYPE_MINIGUN:
+ case WEAPONTYPE_DETONATOR:
+ case WEAPONTYPE_HELICANNON:
+ case WEAPONTYPE_CAMERA:
+ case WEAPONTYPE_EXPLOSION:
+ case WEAPONTYPE_UZI_DRIVEBY:
+ return true;
+ case WEAPONTYPE_HEALTH:
+ case WEAPONTYPE_ARMOUR:
+ case WEAPONTYPE_RAMMEDBYCAR:
+ case WEAPONTYPE_RUNOVERBYCAR:
+ case WEAPONTYPE_DROWNING:
+ case WEAPONTYPE_FALL:
+ case WEAPONTYPE_UNIDENTIFIED:
+ return false;
+ }
+
+ return false;
+}
void CTheScripts::PrintListSizes()
{
@@ -1427,8 +1614,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)
{
@@ -1448,13 +1635,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;
@@ -1504,12 +1685,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);
@@ -1526,13 +1707,7 @@ INITSAVEBUF
ScriptSpace[i] = ReadSaveBuf<uint8>(buf);
script_assert(ReadSaveBuf<uint32>(buf) == SCRIPT_DATA_SIZE);
OnAMissionFlag = ReadSaveBuf<uint32>(buf);
- for (uint32 i = 0; i < MAX_NUM_CONTACTS; i++) {
- OnAMissionForContactFlag[i] = ReadSaveBuf<uint32>(buf);
- BaseBriefIdForContact[i] = ReadSaveBuf<uint32>(buf);
- }
- for (uint32 i = 0; i < MAX_NUM_COLLECTIVES; i++)
- CollectiveArray[i] = ReadSaveBuf<tCollectiveData>(buf);
- NextFreeCollectiveIndex = ReadSaveBuf<uint32>(buf);
+ LastMissionPassedTime = ReadSaveBuf<uint32>(buf);
for (uint32 i = 0; i < MAX_NUM_BUILDING_SWAPS; i++) {
uint32 type = ReadSaveBuf<uint32>(buf);
uint32 handle = ReadSaveBuf<uint32>(buf);
@@ -1580,12 +1755,12 @@ INITSAVEBUF
InvisibilitySettingArray[i]->bIsVisible = false;
}
script_assert(ReadSaveBuf<bool>(buf) == bUsingAMultiScriptFile);
- ReadSaveBuf<uint8>(buf);
+ bPlayerHasMetDebbieHarry = ReadSaveBuf<uint8>(buf);
ReadSaveBuf<uint16>(buf);
script_assert(ReadSaveBuf<uint32>(buf) == MainScriptSize);
script_assert(ReadSaveBuf<uint32>(buf) == LargestMissionScriptSize);
script_assert(ReadSaveBuf<uint16>(buf) == NumberOfMissionScripts);
- ReadSaveBuf<uint16>(buf);
+ script_assert(ReadSaveBuf<uint16>(buf) == NumberOfExclusiveMissionScripts);
uint32 runningScripts = ReadSaveBuf<uint32>(buf);
for (uint32 i = 0; i < runningScripts; i++)
StartNewScript(0)->Load(buf);
@@ -1719,22 +1894,24 @@ void CTheScripts::HighlightImportantAngledArea(uint32 id, float x1, float y1, fl
bool CTheScripts::IsPedStopped(CPed* pPed)
{
- if (pPed->bInVehicle)
+ if (pPed->InVehicle())
return IsVehicleStopped(pPed->m_pMyVehicle);
- return pPed->m_nMoveState == eMoveState::PEDMOVE_NONE || pPed->m_nMoveState == eMoveState::PEDMOVE_STILL;
+ return (pPed->m_nMoveState == eMoveState::PEDMOVE_NONE || pPed->m_nMoveState == eMoveState::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_RUN_STOP) ||
RpAnimBlendClumpGetAssociation(pPed->GetClump(), ANIM_RUN_STOP_R) ||
RpAnimBlendClumpGetAssociation(pPed->GetClump(), ANIM_JUMP_LAUNCH) ||
RpAnimBlendClumpGetAssociation(pPed->GetClump(), ANIM_JUMP_GLIDE))
return false;
- return pPed->m_nMoveState == eMoveState::PEDMOVE_NONE || pPed->m_nMoveState == eMoveState::PEDMOVE_STILL;
+ return (pPed->m_nMoveState == eMoveState::PEDMOVE_NONE || pPed->m_nMoveState == eMoveState::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)
@@ -1742,6 +1919,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)
@@ -1751,7 +1952,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);
@@ -1776,6 +1977,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);
@@ -1806,7 +2008,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;
@@ -1863,7 +2065,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 c2937e1d..272ecd4b 100644
--- a/src/control/Script6.cpp
+++ b/src/control/Script6.cpp
@@ -31,14 +31,59 @@
#include "Weather.h"
#include "Zones.h"
#include "main.h"
+#include "Bike.h"
+#include "GameLogic.h"
+#include "Sprite.h"
+#include "CarAI.h"
+#include "Pickups.h"
+#include "Fluff.h"
+
+#ifdef USE_DEBUG_SCRIPT_LOADER
+extern const char* scriptfile;
+#endif
+
+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;
+ }
+}
+
+bool CRunningScript::ThisIsAValidRandomCop(int32 mi, bool cop, bool swat, bool fbi, bool army, bool miami)
+{
+ switch (mi)
+ {
+ case MI_COP: if (cop) return true;
+ case MI_SWAT: if (swat) return true;
+ case MI_FBI: if (fbi) return true;
+ case MI_ARMY: if (army) return true;
+ default:
+ return miami && (mi >= MI_VICE1 && mi <= MI_VICE8);
+ }
+}
int8 CRunningScript::ProcessCommands1000To1099(int32 command)
{
-#ifdef GTA_PS2
- char tmp[48];
-#endif
switch (command) {
//case COMMAND_FLASH_RADAR_BLIP:
+ /*
case COMMAND_IS_CHAR_IN_CONTROL:
{
CollectParameters(&m_nIp, 1);
@@ -46,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);
@@ -53,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);
@@ -125,6 +173,7 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command)
return 0;
}
//case COMMAND_MAKE_PLAYER_UNSAFE:
+ /*
case COMMAND_LOAD_COLLISION:
{
CollectParameters(&m_nIp, 1);
@@ -145,9 +194,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);
@@ -159,6 +209,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);
@@ -181,22 +232,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;
@@ -214,25 +277,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;
@@ -240,8 +313,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];
@@ -254,6 +329,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);
@@ -264,6 +340,7 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command)
pPed->bUsePedNodeSeek = !!ScriptParams[1];
return 0;
}
+ /*
case COMMAND_SWITCH_VEHICLE_WEAPONS:
{
CollectParameters(&m_nIp, 2);
@@ -276,10 +353,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);
@@ -288,11 +367,15 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command)
UpdateCompareFlag(!pVehicle->IsDoorMissing((eDoors)ScriptParams[1]) && pVehicle->IsDoorClosed((eDoors)ScriptParams[1]));
return 0;
}
+ */
case COMMAND_LOAD_AND_LAUNCH_MISSION:
return 0;
case COMMAND_LOAD_AND_LAUNCH_MISSION_INTERNAL:
{
CollectParameters(&m_nIp, 1);
+
+ if (CTheScripts::NumberOfExclusiveMissionScripts > 0 && ScriptParams[0] <= UINT16_MAX - 2)
+ return 0;
#ifdef MISSION_REPLAY
missionRetryScriptIndex = ScriptParams[0];
if (missionRetryScriptIndex == 19)
@@ -300,8 +383,14 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command)
#endif
CTimer::Suspend();
int offset = CTheScripts::MultiScriptArray[ScriptParams[0]];
+#ifdef USE_DEBUG_SCRIPT_LOADER
+ CFileMgr::ChangeDir("\\data\\");
+ int handle = CFileMgr::OpenFile(scriptfile, "rb");
+ CFileMgr::ChangeDir("\\");
+#else
CFileMgr::ChangeDir("\\");
int handle = CFileMgr::OpenFile("data\\main.scm", "rb");
+#endif
CFileMgr::Seek(handle, offset, 0);
CFileMgr::Read(handle, (const char*)&CTheScripts::ScriptSpace[SIZE_MAIN_SCRIPT], SIZE_MISSION_SCRIPT);
CFileMgr::CloseFile(handle);
@@ -310,6 +399,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:
@@ -325,14 +415,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);
@@ -377,6 +468,7 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command)
}
return 0;
}
+ */
case COMMAND_SET_NEAR_CLIP:
CollectParameters(&m_nIp, 1);
TheCamera.SetNearClipScript(*(float*)&ScriptParams[0]);
@@ -385,6 +477,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];
@@ -405,6 +498,7 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command)
UpdateCompareFlag(CGarages::IsThisCarWithinGarageArea(ScriptParams[0], pVehicle));
return 0;
}
+ */
case COMMAND_SET_CAR_TRACTION:
{
CollectParameters(&m_nIp, 2);
@@ -414,16 +508,14 @@ 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;
- *(float*)(((char*)pVehicle) + 1088) = fTraction;
+ ((CBike*)pVehicle)->m_fTraction = fTraction;
return 0;
}
case COMMAND_ARE_MEASUREMENTS_IN_METRES:
#ifdef USE_MEASUREMENTS_IN_METERS
UpdateCompareFlag(true);
#else
- UpdateCompareFlag(false)
+ UpdateCompareFlag(false);
#endif
return 0;
case COMMAND_CONVERT_METRES_TO_FEET:
@@ -435,6 +527,7 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command)
StoreParameters(&m_nIp, 1);
return 0;
}
+ /*
case COMMAND_MARK_ROADS_BETWEEN_LEVELS:
{
CollectParameters(&m_nIp, 6);
@@ -483,6 +576,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);
@@ -491,6 +585,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);
@@ -503,6 +598,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);
@@ -529,7 +625,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);
@@ -553,6 +649,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);
@@ -564,6 +661,7 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command)
StoreParameters(&m_nIp, 1);
return 0;
}
+ */
case COMMAND_SET_CHAR_IS_CHRIS_CRIMINAL:
{
CollectParameters(&m_nIp, 2);
@@ -586,6 +684,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);
@@ -618,10 +717,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]) {
@@ -636,6 +737,7 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command)
CStreaming::LoadAllRequestedModels(false);
}
return 0;
+ */
case COMMAND_SET_PLAYER_HOOKER:
{
CollectParameters(&m_nIp, 2);
@@ -648,6 +750,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;
}
@@ -675,8 +778,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:
@@ -684,24 +786,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);
@@ -710,6 +815,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);
@@ -717,7 +823,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:
@@ -725,7 +831,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:
@@ -746,7 +852,6 @@ int8 CRunningScript::ProcessCommands1000To1099(int32 command)
pPed->m_objective != OBJECTIVE_ENTER_CAR_AS_DRIVER);
return 0;
}
-#ifndef GTA_PS2
default:
script_assert(0);
}
@@ -757,7 +862,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command)
{
char tmp[48];
switch (command) {
-#endif
+ /*
case COMMAND_LOAD_COLLISION_WITH_SCREEN:
CollectParameters(&m_nIp, 1);
CTimer::Stop();
@@ -793,6 +898,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++)
@@ -800,6 +906,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command)
m_nIp += 8;
LoadSplash(tmp);
return 0;
+ /*
case COMMAND_SET_CAR_IGNORE_LEVEL_TRANSITIONS:
{
CollectParameters(&m_nIp, 2);
@@ -821,6 +928,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);
@@ -832,15 +940,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;
-#ifndef GTA_PS2
- // To be precise, on PS2 previous handlers were in 1000-1099 function
- // These are "beta" VC commands (with bugs)
+ */
case COMMAND_SET_OBJECT_ROTATION:
{
CollectParameters(&m_nIp, 4);
@@ -860,6 +967,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);
@@ -873,6 +981,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command)
UpdateCompareFlag(pTarget && pTarget->IsPed());
return 0;
}
+ */
case COMMAND_IS_PLAYER_TARGETTING_CHAR:
{
CollectParameters(&m_nIp, 2);
@@ -881,9 +990,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);
@@ -895,6 +1033,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);
@@ -939,6 +1078,8 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command)
return 0;
case COMMAND_GET_CLOSEST_OBJECT_OF_TYPE:
{
+ return 0;
+/*
CollectParameters(&m_nIp, 5);
CVector pos = *(CVector*)&ScriptParams[0];
if (pos.z <= MAP_Z_LOW_LIMIT)
@@ -982,7 +1123,9 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command)
}
StoreParameters(&m_nIp, 1);
return 0;
+*/
}
+ /*
case COMMAND_PLACE_OBJECT_RELATIVE_TO_OBJECT:
{
CollectParameters(&m_nIp, 5);
@@ -994,28 +1137,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);
@@ -1046,16 +1181,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(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);
@@ -1068,20 +1214,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];
@@ -1097,9 +1248,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;
@@ -1109,9 +1262,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;
@@ -1125,14 +1278,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();
@@ -1156,9 +1310,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;
@@ -1172,6 +1326,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command)
StoreParameters(&m_nIp, 1);
return 0;
}
+ */
case COMMAND_SET_CHAR_OBJ_FLEE_CAR:
{
CollectParameters(&m_nIp, 2);
@@ -1228,7 +1383,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;
}
@@ -1237,7 +1392,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;
}
@@ -1249,15 +1404,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);
@@ -1276,18 +1432,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;
@@ -1298,9 +1457,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);
@@ -1309,6 +1469,7 @@ int8 CRunningScript::ProcessCommands1100To1199(int32 command)
UpdateCompareFlag(pPed->bFallenDown);
return 0;
}
+ */
case COMMAND_CAN_CHAR_SEE_DEAD_CHAR:
{
CollectParameters(&m_nIp, 2);
@@ -1326,23 +1487,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..1bad3407
--- /dev/null
+++ b/src/control/Script7.cpp
@@ -0,0 +1,1402 @@
+#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]).m_eWeaponType;
+ ScriptParams[1] = pPed->GetWeapon(ScriptParams[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->bIsDucking = true;
+ pPed->SetDuck(ScriptParams[2], true);
+ }
+ else {
+ pPed->ClearDuck(true);
+ pPed->bIsDucking = false;
+ }
+ return 0;
+ }
+ case COMMAND_SET_ZONE_CIVILIAN_CAR_INFO:
+ {
+ char label[12];
+ 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;
+ ScriptParams[1] = *(int*)&pPlayerInfo->m_nLastDistanceCarTravelledOnTwoWheels;
+ ScriptParams[2] = pPlayerInfo->m_nLastTimeSpentOnWheelie;
+ ScriptParams[3] = *(int*)&pPlayerInfo->m_nLastDistanceTravelledOnWheelie;
+ ScriptParams[4] = pPlayerInfo->m_nLastTimeSpentOnStoppie;
+ ScriptParams[5] = *(int*)&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())->GetName()) == 0);
+ return 0;
+ }
+ case COMMAND_SET_PLAYER_CAN_DO_DRIVE_BY:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPlayerInfo* pPlayerInfo = &CWorld::Players[ScriptParams[0]];
+ pPlayerInfo->m_bDriveByAllowed = ScriptParams[1];
+ return 0;
+ }
+ case COMMAND_SET_CHAR_OBJ_SPRINT_TO_COORD:
+ {
+ CollectParameters(&m_nIp, 3);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ 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];
+ 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];
+ 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..08965e72
--- /dev/null
+++ b/src/control/Script8.cpp
@@ -0,0 +1,612 @@
+#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_IDLE_STANCE);
+ pPed->bIsPedDieAnimPlaying = false;
+ }
+ return 0;
+ }
+ case COMMAND_SET_MAXIMUM_NUMBER_OF_CARS_IN_GARAGE:
+ CollectParameters(&m_nIp, 2);
+ CGarages::SetMaxNumStoredCarsForGarage(ScriptParams[0], ScriptParams[1]);
+ return 0;
+ case COMMAND_WANTED_STARS_ARE_FLASHING:
+ {
+ CWanted *pWanted = CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_pWanted;
+ UpdateCompareFlag(pWanted->m_nMinWantedLevel - pWanted->m_nWantedLevel > 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];
+ 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);
+ 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_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 == 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]);
+ break;
+#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 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 b9067bea..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,
-#ifndef GTA_PS2
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/SetPieces.cpp b/src/control/SetPieces.cpp
new file mode 100644
index 00000000..c5142a0a
--- /dev/null
+++ b/src/control/SetPieces.cpp
@@ -0,0 +1,319 @@
+#include "common.h"
+
+#include "SetPieces.h"
+#include "Automobile.h"
+#include "CarAI.h"
+#include "CopPed.h"
+#include "GenericGameStorage.h"
+#include "PlayerPed.h"
+#include "Timer.h"
+#include "Vehicle.h"
+#include "Wanted.h"
+#include "World.h"
+
+#define TIME_BETWEEN_SETPIECE_SPAWNS 20000
+
+//--MIAMI: file done
+
+bool CSetPieces::bDebug;
+uint32 CSetPieces::NumSetPieces;
+CSetPiece CSetPieces::aSetPieces[NUM_SETPIECES];
+
+void CSetPieces::Init(void)
+{
+ bDebug = false;
+ NumSetPieces = 0;
+}
+
+void CSetPieces::AddOne(uint8 type, CVector2D vTriggerInf, CVector2D vTriggerSup, CVector2D vSpawn1, CVector2D vTarget1, CVector2D vSpawn2, CVector2D vTarget2)
+{
+ if (NumSetPieces >= NUM_SETPIECES)
+ return;
+ aSetPieces[NumSetPieces].m_nType = type;
+ aSetPieces[NumSetPieces].m_vTriggerInf.x = Min(vTriggerInf.x, vTriggerSup.x);
+ aSetPieces[NumSetPieces].m_vTriggerInf.y = Min(vTriggerInf.y, vTriggerSup.y);
+ aSetPieces[NumSetPieces].m_vTriggerSup.x = Max(vTriggerInf.x, vTriggerSup.x);
+ aSetPieces[NumSetPieces].m_vTriggerSup.y = Max(vTriggerInf.y, vTriggerSup.y);
+ aSetPieces[NumSetPieces].m_vSpawn1 = vSpawn1;
+ aSetPieces[NumSetPieces].m_vSpawn2 = vSpawn2;
+ aSetPieces[NumSetPieces].m_vTarget1 = vTarget1;
+ aSetPieces[NumSetPieces].m_vTarget2 = vTarget2;
+ ++NumSetPieces;
+}
+
+void CSetPieces::Update(void)
+{
+ int nFirst = NumSetPieces * (CTimer::GetFrameCounter() % 8) / 8;
+ int nLast = NumSetPieces * (CTimer::GetFrameCounter() % 8 + 1) / 8;
+ for (int i = nFirst; i < nLast; i++)
+ aSetPieces[i].Update();
+}
+
+void CSetPieces::Save(uint8* buf, uint32* size)
+{
+INITSAVEBUF
+ WriteSaveBuf(buf, NumSetPieces);
+ for (int i = 0; i < NUM_SETPIECES; i++)
+ WriteSaveBuf(buf, aSetPieces[i]);
+ *size = sizeof(NumSetPieces) + NUM_SETPIECES * sizeof(CSetPiece);
+VALIDATESAVEBUF(*size)
+}
+
+void CSetPieces::Load(uint8* buf, uint32 size)
+{
+INITSAVEBUF
+ NumSetPieces = ReadSaveBuf<uint32>(buf);
+ for (int i = 0; i < NUM_SETPIECES; i++)
+ aSetPieces[i] = ReadSaveBuf<CSetPiece>(buf);
+VALIDATESAVEBUF(size)
+}
+
+void CSetPiece::Update(void)
+{
+ if (m_nLastTimeCreated != 0 && CTimer::GetTimeInMilliseconds() <= m_nLastTimeCreated + TIME_BETWEEN_SETPIECE_SPAWNS)
+ return;
+ CVector pos = FindPlayerCoors();
+ if (pos.x < m_vTriggerInf.x || pos.x > m_vTriggerSup.x ||
+ pos.y < m_vTriggerInf.y || pos.y > m_vTriggerSup.y)
+ return;
+ switch (m_nType) {
+ case SETPIECE_TWOCOPCARSINALLEY:
+ {
+ if (FindPlayerPed()->m_pWanted->m_nWantedLevel < 1 || FindPlayerVehicle())
+ return;
+ CVehicle* pVehicle1 = TryToGenerateCopCar(m_vSpawn1, m_vTarget1);
+ if (!pVehicle1)
+ return;
+ CVehicle* pVehicle2 = TryToGenerateCopCar(m_vSpawn2, m_vTarget2);
+ if (!pVehicle2) {
+ CWorld::Remove(pVehicle1);
+ delete pVehicle1;
+ return;
+ }
+ pVehicle1->SetStatus(STATUS_PHYSICS);
+ pVehicle1->AutoPilot.m_fMaxTrafficSpeed = pVehicle1->AutoPilot.m_nCruiseSpeed = 4;
+ pVehicle1->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_SLOW_DOWN_FOR_CARS;
+ pVehicle1->AutoPilot.m_nCarMission = MISSION_SLOWLY_DRIVE_TOWARDS_PLAYER_1;
+ pVehicle1->AutoPilot.m_vecDestinationCoors.x = m_vTarget1.x;
+ pVehicle1->AutoPilot.m_vecDestinationCoors.y = m_vTarget1.y;
+ pVehicle1->AutoPilot.m_vecDestinationCoors.z = 0.0f;
+ pVehicle1->m_nSetPieceExtendedRangeTime = CTimer::GetTimeInMilliseconds() + 25000;
+ CCarAI::AddPoliceCarOccupants(pVehicle1);
+ pVehicle2->SetStatus(STATUS_PHYSICS);
+ pVehicle2->AutoPilot.m_fMaxTrafficSpeed = pVehicle2->AutoPilot.m_nCruiseSpeed = 4;
+ pVehicle2->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_SLOW_DOWN_FOR_CARS;
+ pVehicle2->AutoPilot.m_nCarMission = MISSION_SLOWLY_DRIVE_TOWARDS_PLAYER_1;
+ pVehicle2->AutoPilot.m_vecDestinationCoors.x = m_vTarget2.x;
+ pVehicle2->AutoPilot.m_vecDestinationCoors.y = m_vTarget2.y;
+ pVehicle2->AutoPilot.m_vecDestinationCoors.z = 0.0f;
+ pVehicle2->m_nSetPieceExtendedRangeTime = CTimer::GetTimeInMilliseconds() + 25000;
+ CCarAI::AddPoliceCarOccupants(pVehicle2);
+ m_nLastTimeCreated = CTimer::GetTimeInMilliseconds();
+ break;
+ }
+ case SETPIECE_CARBLOCKINGPLAYERFROMSIDE:
+ {
+ if (FindPlayerPed()->m_pWanted->m_nWantedLevel < 2)
+ return;
+ if (!FindPlayerVehicle())
+ return;
+ if (DotProduct2D(FindPlayerSpeed(), (CVector2D)FindPlayerCoors() - m_vSpawn1) >= 0.0f)
+ return;
+ CVehicle* pVehicle1 = TryToGenerateCopCar(m_vSpawn1, m_vTarget1);
+ if (!pVehicle1)
+ return;
+ pVehicle1->SetStatus(STATUS_PHYSICS);
+ pVehicle1->AutoPilot.m_fMaxTrafficSpeed = pVehicle1->AutoPilot.m_nCruiseSpeed = 16;
+ pVehicle1->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_PLOUGH_THROUGH;
+ pVehicle1->AutoPilot.m_nCarMission = MISSION_BLOCKPLAYER_FORWARDANDBACK;
+ pVehicle1->AutoPilot.m_nTempAction = TEMPACT_GOFORWARD;
+ pVehicle1->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + 100;
+ pVehicle1->m_nSetPieceExtendedRangeTime = CTimer::GetTimeInMilliseconds() + 10000;
+ pVehicle1->SetMoveSpeed(2.0f * pVehicle1->GetForward() / 3.0f);
+ CCarAI::AddPoliceCarOccupants(pVehicle1);
+ m_nLastTimeCreated = CTimer::GetTimeInMilliseconds();
+ return;
+ }
+ case SETPIECE_CARRAMMINGPLAYERFROMSIDE:
+ {
+ if (FindPlayerPed()->m_pWanted->m_nWantedLevel < 2)
+ return;
+ if (!FindPlayerVehicle())
+ return;
+ if (DotProduct2D(FindPlayerSpeed(), (CVector2D)FindPlayerCoors() - m_vSpawn1) >= 0.0f)
+ return;
+ CVehicle* pVehicle1 = TryToGenerateCopCar(m_vSpawn1, m_vTarget1);
+ if (!pVehicle1)
+ return;
+ pVehicle1->SetStatus(STATUS_PHYSICS);
+ pVehicle1->AutoPilot.m_fMaxTrafficSpeed = pVehicle1->AutoPilot.m_nCruiseSpeed = 16;
+ pVehicle1->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_AVOID_CARS;
+ pVehicle1->AutoPilot.m_nCarMission = MISSION_RAMCAR_CLOSE;
+ pVehicle1->AutoPilot.m_nTempAction = TEMPACT_GOFORWARD;
+ pVehicle1->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + 100;
+ pVehicle1->m_nSetPieceExtendedRangeTime = CTimer::GetTimeInMilliseconds() + 10000;
+ pVehicle1->SetMoveSpeed(2.0f * pVehicle1->GetForward() / 3.0f);
+ CCarAI::AddPoliceCarOccupants(pVehicle1);
+ m_nLastTimeCreated = CTimer::GetTimeInMilliseconds();
+ return;
+ }
+ case SETPIECE_CREATECOPPERONFOOT:
+ {
+ if (FindPlayerPed()->m_pWanted->m_nWantedLevel < 1 || FindPlayerVehicle())
+ return;
+ CCopPed* pCop = TryToGenerateCopPed(m_vSpawn1);
+ if (!pCop)
+ return;
+ float z = CWorld::FindGroundZForCoord(m_vTarget1.x, m_vTarget1.y);
+ pCop->bScriptObjectiveCompleted = false;
+ pCop->SetObjective(OBJECTIVE_GOTO_AREA_ON_FOOT, CVector(m_vTarget1.x, m_vTarget1.y, z));
+ pCop->m_nExtendedRangeTimer = CTimer::GetTimeInMilliseconds() + 10000;
+ m_nLastTimeCreated = CTimer::GetTimeInMilliseconds();
+ return;
+ }
+ case SETPIECE_CREATETWOCOPPERSONFOOT:
+ {
+ if (FindPlayerPed()->m_pWanted->m_nWantedLevel < 1 || FindPlayerVehicle())
+ return;
+ CCopPed* pCop = TryToGenerateCopPed(m_vSpawn1);
+ if (!pCop)
+ return;
+ float z = CWorld::FindGroundZForCoord(m_vTarget1.x, m_vTarget1.y);
+ pCop->bScriptObjectiveCompleted = false;
+ pCop->SetObjective(OBJECTIVE_GOTO_AREA_ON_FOOT, CVector(m_vTarget1.x, m_vTarget1.y, z));
+ pCop->m_nExtendedRangeTimer = CTimer::GetTimeInMilliseconds() + 10000;
+ CCopPed* pCop2 = TryToGenerateCopPed(m_vSpawn2);
+ if (!pCop2) {
+ CWorld::Remove(pCop);
+ delete pCop;
+ return;
+ }
+ z = CWorld::FindGroundZForCoord(m_vTarget2.x, m_vTarget2.y);
+ pCop2->bScriptObjectiveCompleted = false;
+ pCop2->SetObjective(OBJECTIVE_GOTO_AREA_ON_FOOT, CVector(m_vTarget2.x, m_vTarget2.y, z));
+ pCop2->m_nExtendedRangeTimer = CTimer::GetTimeInMilliseconds() + 10000;
+ m_nLastTimeCreated = CTimer::GetTimeInMilliseconds();
+ return;
+ }
+ case SETPIECE_TWOCARSBLOCKINGPLAYERFROMSIDE:
+ {
+ if (FindPlayerPed()->m_pWanted->m_nWantedLevel < 2)
+ return;
+ if (!FindPlayerVehicle())
+ return;
+ if (DotProduct2D(FindPlayerSpeed(), (CVector2D)FindPlayerCoors() - m_vSpawn1) >= 0.0f)
+ return;
+ CVehicle* pVehicle1 = TryToGenerateCopCar(m_vSpawn1, m_vTarget1);
+ if (!pVehicle1)
+ return;
+ pVehicle1->SetStatus(STATUS_PHYSICS);
+ pVehicle1->AutoPilot.m_fMaxTrafficSpeed = pVehicle1->AutoPilot.m_nCruiseSpeed = 16;
+ pVehicle1->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_PLOUGH_THROUGH;
+ pVehicle1->AutoPilot.m_nCarMission = MISSION_BLOCKPLAYER_FORWARDANDBACK;
+ pVehicle1->AutoPilot.m_nTempAction = TEMPACT_GOFORWARD;
+ pVehicle1->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + 100;
+ pVehicle1->m_nSetPieceExtendedRangeTime = CTimer::GetTimeInMilliseconds() + 10000;
+ pVehicle1->SetMoveSpeed(2.0f * pVehicle1->GetForward() / 3.0f);
+ CCarAI::AddPoliceCarOccupants(pVehicle1);
+ CVehicle* pVehicle2 = TryToGenerateCopCar(m_vSpawn2, m_vTarget2);
+ if (!pVehicle2) {
+ CWorld::Remove(pVehicle1);
+ delete pVehicle1;
+ return;
+ }
+ pVehicle2->SetStatus(STATUS_PHYSICS);
+ pVehicle2->AutoPilot.m_fMaxTrafficSpeed = pVehicle1->AutoPilot.m_nCruiseSpeed = 16;
+ pVehicle2->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_PLOUGH_THROUGH;
+ pVehicle2->AutoPilot.m_nCarMission = MISSION_BLOCKPLAYER_FORWARDANDBACK;
+ pVehicle2->AutoPilot.m_nTempAction = TEMPACT_GOFORWARD;
+ pVehicle2->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + 100;
+ pVehicle2->m_nSetPieceExtendedRangeTime = CTimer::GetTimeInMilliseconds() + 10000;
+ pVehicle2->SetMoveSpeed(2.0f * pVehicle2->GetForward() / 3.0f);
+ CCarAI::AddPoliceCarOccupants(pVehicle2);
+ m_nLastTimeCreated = CTimer::GetTimeInMilliseconds();
+ return;
+ }
+ case SETPIECE_TWOCARSRAMMINGPLAYERFROMSIDE:
+ {
+ if (FindPlayerPed()->m_pWanted->m_nWantedLevel < 2)
+ return;
+ if (!FindPlayerVehicle())
+ return;
+ if (DotProduct2D(FindPlayerSpeed(), (CVector2D)FindPlayerCoors() - m_vSpawn1) >= 0.0f)
+ return;
+ CVehicle* pVehicle1 = TryToGenerateCopCar(m_vSpawn1, m_vTarget1);
+ if (!pVehicle1)
+ return;
+ pVehicle1->SetStatus(STATUS_PHYSICS);
+ pVehicle1->AutoPilot.m_fMaxTrafficSpeed = pVehicle1->AutoPilot.m_nCruiseSpeed = 16;
+ pVehicle1->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_AVOID_CARS;
+ pVehicle1->AutoPilot.m_nCarMission = MISSION_RAMCAR_CLOSE;
+ pVehicle1->AutoPilot.m_nTempAction = TEMPACT_GOFORWARD;
+ pVehicle1->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + 100;
+ pVehicle1->m_nSetPieceExtendedRangeTime = CTimer::GetTimeInMilliseconds() + 10000;
+ pVehicle1->SetMoveSpeed(2.0f * pVehicle1->GetForward() / 3.0f);
+ CCarAI::AddPoliceCarOccupants(pVehicle1);
+ CVehicle* pVehicle2 = TryToGenerateCopCar(m_vSpawn2, m_vTarget2);
+ if (!pVehicle2) {
+ CWorld::Remove(pVehicle2);
+ delete pVehicle2;
+ return;
+ }
+ pVehicle2->SetStatus(STATUS_PHYSICS);
+ pVehicle2->AutoPilot.m_fMaxTrafficSpeed = pVehicle2->AutoPilot.m_nCruiseSpeed = 16;
+ pVehicle2->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_AVOID_CARS;
+ pVehicle2->AutoPilot.m_nCarMission = MISSION_RAMCAR_CLOSE;
+ pVehicle2->AutoPilot.m_nTempAction = TEMPACT_GOFORWARD;
+ pVehicle2->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + 100;
+ pVehicle2->m_nSetPieceExtendedRangeTime = CTimer::GetTimeInMilliseconds() + 10000;
+ pVehicle2->SetMoveSpeed(2.0f * pVehicle2->GetForward() / 3.0f);
+ CCarAI::AddPoliceCarOccupants(pVehicle2);
+ m_nLastTimeCreated = CTimer::GetTimeInMilliseconds();
+ return;
+ }
+ }
+}
+
+CVehicle* CSetPiece::TryToGenerateCopCar(CVector2D vSpawn, CVector2D vTarget)
+{
+ CVehicle* pVehicle = new CAutomobile(MI_POLICE, RANDOM_VEHICLE);
+ CVector pos(vSpawn.x, vSpawn.y, 1000.0f);
+ CColPoint point;
+ CEntity* pEntity;
+ if (CWorld::ProcessVerticalLine(pos, -1000.0f, point, pEntity, true, false, false, false, true, false, nil))
+ pos.z = point.point.z + pVehicle->GetHeightAboveRoad();
+ CVector vDirection(vTarget.x - vSpawn.x, vTarget.y - vSpawn.y, 0.0f);
+ vDirection.Normalise();
+ pVehicle->GetForward() = CVector(vDirection.x, vDirection.y, 0.0f);
+ pVehicle->GetRight() = CVector(vDirection.y, -vDirection.x, 0.0f);
+ pVehicle->GetUp() = CVector(0.0f, 0.0f, 1.0f);
+ pVehicle->SetPosition(pos);
+ int16 total;
+ CWorld::FindObjectsKindaColliding(pos, pVehicle->GetColModel()->spheres->radius, false, &total, 16, nil, false, true, true, false, false);
+ if (total != 0) {
+ delete pVehicle;
+ return nil;
+ }
+ pVehicle->ChangeLawEnforcerState(true);
+ CWorld::Add(pVehicle);
+ return pVehicle;
+}
+
+CCopPed* CSetPiece::TryToGenerateCopPed(CVector2D vSpawn)
+{
+ CCopPed* pCop = new CCopPed(COP_STREET);
+ CVector pos(vSpawn.x, vSpawn.y, 1000.0f);
+ CColPoint point;
+ CEntity* pEntity;
+ if (CWorld::ProcessVerticalLine(pos, -1000.0f, point, pEntity, true, false, false, false, true, false, nil))
+ pos.z = point.point.z + 0.9f;
+ pCop->SetPosition(pos);
+ int16 total;
+ CWorld::FindObjectsKindaColliding(pos, pCop->GetColModel()->spheres->radius, false, &total, 16, nil, false, true, true, false, false);
+ if (total != 0) {
+ delete pCop;
+ return nil;
+ }
+ CWorld::Add(pCop);
+ return pCop;
+} \ No newline at end of file
diff --git a/src/control/SetPieces.h b/src/control/SetPieces.h
new file mode 100644
index 00000000..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..ecfc7207 100644
--- a/src/control/TrafficLights.cpp
+++ b/src/control/TrafficLights.cpp
@@ -15,8 +15,9 @@
#include "Weather.h"
#include "World.h"
-// TODO: figure out the meaning of this
-enum { SOME_FLAG = 0x80 };
+//--MIAMI: file done
+
+bool CTrafficLights::bGreenLightsCheat;
void
CTrafficLights::DisplayActualLight(CEntity *ent)
@@ -26,113 +27,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;
+ }
- 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;
+ CBrightLights::RegisterOne(pos1, 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,
+ 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 +321,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 +376,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 +402,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 +424,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 +450,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 +484,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 +503,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 +520,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/Accident.cpp b/src/core/Accident.cpp
index c8611323..cb46e181 100644
--- a/src/core/Accident.cpp
+++ b/src/core/Accident.cpp
@@ -6,6 +6,8 @@
#include "Pools.h"
#include "World.h"
+// --MIAMI: File done
+
CAccidentManager gAccidentManager;
CAccident*
diff --git a/src/core/AnimViewer.cpp b/src/core/AnimViewer.cpp
index a888d528..30050624 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"
@@ -48,11 +50,9 @@ CAnimViewer::Render(void) {
// 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 +61,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 +77,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 +90,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,7 +107,6 @@ CAnimViewer::Initialise(void) {
CAnimManager::LoadAnimFiles();
CWorld::PlayerInFocus = 0;
CWeapon::InitialiseWeapons();
- CShadows::Init();
CPed::Initialise();
CTimer::Initialise();
CClock::Initialise(60000);
@@ -138,12 +139,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 +286,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 +318,6 @@ CAnimViewer::Update(void)
pTarget->GetMatrix().GetPosition().z = 10.0f;
#else
pTarget->GetMatrix().GetPosition().z = 0.0f;
-
#endif
if (modelInfo->GetModelType() == MITYPE_PED) {
@@ -325,7 +342,7 @@ CAnimViewer::Update(void)
} else if (pad->GetDPadUpJustDown()) {
animId--;
if (animId < 0) {
- animId = NUM_ANIMS - 1;
+ animId = NUM_STD_ANIMS - 1;
}
PlayAnimation(pTarget->GetClump(), animGroup, (AnimationId)animId);
@@ -334,7 +351,7 @@ CAnimViewer::Update(void)
CMessages::AddMessage(gUString, 1000, 0);
} else if (pad->GetDPadDownJustDown()) {
- animId = (animId == (NUM_ANIMS - 1) ? 0 : animId + 1);
+ animId = (animId == (NUM_STD_ANIMS - 1) ? 0 : animId + 1);
PlayAnimation(pTarget->GetClump(), animGroup, (AnimationId)animId);
sprintf(gString, "Current anim: %d", animId);
@@ -349,16 +366,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 5906310b..98d0369f 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,17 @@
#include "Debug.h"
#include "Camera.h"
#include "DMAudio.h"
+#include "Bike.h"
+#include "Pickups.h"
+
+//--MIAMI: file done
bool PrintDebugCode = false;
int16 DebugCamMode;
+extern float fRangePlayerRadius;
+extern float fCloseNearClipLimit;
+
#ifdef FREE_CAM
bool CCamera::bFreeCam = false;
int nPreviousMode = -1;
@@ -56,6 +65,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 +90,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 +102,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 +141,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 +174,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);
@@ -159,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:
@@ -167,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:
@@ -197,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)
@@ -217,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;
@@ -244,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:
@@ -253,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:
@@ -290,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)
@@ -325,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();
}
@@ -369,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;
@@ -396,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
@@ -463,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;
@@ -512,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;
}
@@ -622,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();
@@ -648,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();
}
@@ -664,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)
@@ -722,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();
@@ -731,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;
}
}
@@ -744,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)
@@ -771,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();
@@ -780,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;
}
}
@@ -859,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
@@ -875,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
@@ -908,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);
@@ -972,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)
@@ -1014,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);
@@ -1114,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)
@@ -1142,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
-
- 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;
- }
+ }else if(Abs(TheCamera.m_fAvoidTheGeometryProbsTimer) > fAvoidGeomThreshhold && !Rotating ){
- 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;
@@ -1311,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();
@@ -1332,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;
@@ -1357,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);
@@ -1376,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{
@@ -1447,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;
@@ -1472,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;
}
@@ -1481,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)
@@ -1508,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)
@@ -1551,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))
@@ -1566,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;
@@ -1606,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);
@@ -1627,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
@@ -1640,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_WEAPON_PUMP) ||
- RpAnimBlendClumpGetAssociation(CamTargetEntity->GetClump(), ANIM_WEAPON_THROW) ||
- RpAnimBlendClumpGetAssociation(CamTargetEntity->GetClump(), ANIM_WEAPON_THROWU) ||
- RpAnimBlendClumpGetAssociation(CamTargetEntity->GetClump(), ANIM_WEAPON_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;
@@ -1660,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;
@@ -1690,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;
@@ -1708,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;
+ 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 car center
- float CarRoof = CWorld::FindRoofZFor3DCoord(TargetCoors.x, TargetCoors.y, CarBottom, &FoundRoofCenter);
-
- // 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);
@@ -2021,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;
@@ -2045,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)
@@ -2124,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;
}
@@ -2163,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;
@@ -2447,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;
@@ -2472,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;
@@ -2503,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;
@@ -2547,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;
@@ -2572,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();
@@ -2596,6 +2357,11 @@ 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;
@@ -2607,62 +2373,134 @@ CCam::Process_M16_1stPerson(const CVector &CameraTarget, float, float, float)
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 += 2*PI;
+ while(Beta >= PI) Beta -= 2*PI;
+ }
- 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 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;
@@ -2680,6 +2518,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;
}
@@ -2700,11 +2539,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();
@@ -2760,16 +2610,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)
@@ -2787,9 +2669,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();
@@ -2820,16 +2702,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;
@@ -2898,6 +2776,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;
@@ -2937,12 +2841,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;
@@ -2963,11 +2870,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;
@@ -3036,8 +2955,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();
@@ -3070,6 +2994,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();
@@ -3078,6 +3004,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)
{
@@ -3088,82 +3020,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();
}
@@ -3180,8 +3153,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;
@@ -3212,22 +3183,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)
{
@@ -3238,118 +3211,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)
{
@@ -3357,26 +3347,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;
@@ -3400,32 +3389,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
@@ -3433,6 +3405,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();
@@ -3551,6 +3525,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)
@@ -3629,37 +3608,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();
@@ -3673,7 +3720,22 @@ CCam::Process_Fixed(const CVector &CameraTarget, float, float, float)
if(TheCamera.m_bUseSpecialFovTrain)
FOV = TheCamera.m_fFovForTrain;
- if(CMenuManager::m_ControlMethod == CONTROL_STANDARD && Using3rdPersonMouseCam()){
+ 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);
+ }
+ }
+
+ if(FrontEndMenuManager.m_ControlMethod == CONTROL_STANDARD && Using3rdPersonMouseCam()){
CPed *player = FindPlayerPed();
if(player && player->CanStrafeOrMouseControl()){
float Heading = Front.Heading();
@@ -3686,16 +3748,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;
@@ -3707,20 +3834,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)
{
@@ -3728,6 +3841,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();
@@ -3825,11 +3940,11 @@ CCam::Process_Debug(const CVector&, float, float, float)
}
// stay inside sectors
- while(CWorld::GetSectorX(Source.x) > 95.0f)
+ while(CWorld::GetSectorX(Source.x) > 75.0f)
Source.x -= 1.0f;
while(CWorld::GetSectorX(Source.x) < 5.0f)
Source.x += 1.0f;
- while(CWorld::GetSectorY(Source.y) > 95.0f)
+ while(CWorld::GetSectorY(Source.y) > 75.0f)
Source.y -= 1.0f;
while(CWorld::GetSectorY(Source.y) < 5.0f)
Source.y += 1.0f;
@@ -3844,7 +3959,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];
@@ -3896,11 +4011,11 @@ CCam::Process_Debug(const CVector&, float, float, float)
}
// stay inside sectors
- while(CWorld::GetSectorX(Source.x) > 95.0f)
+ while(CWorld::GetSectorX(Source.x) > 75.0f)
Source.x -= 1.0f;
while(CWorld::GetSectorX(Source.x) < 5.0f)
Source.x += 1.0f;
- while(CWorld::GetSectorY(Source.y) > 95.0f)
+ while(CWorld::GetSectorY(Source.y) > 75.0f)
Source.y -= 1.0f;
while(CWorld::GetSectorY(Source.y) < 5.0f)
Source.y += 1.0f;
@@ -3977,11 +4092,11 @@ CCam::Process_Editor(const CVector&, float, float, float)
}
// stay inside sectors
- while(CWorld::GetSectorX(Source.x) > 95.0f)
+ while(CWorld::GetSectorX(Source.x) > 75.0f)
Source.x -= 1.0f;
while(CWorld::GetSectorX(Source.x) < 5.0f)
Source.x += 1.0f;
- while(CWorld::GetSectorY(Source.y) > 95.0f)
+ while(CWorld::GetSectorY(Source.y) > 75.0f)
Source.y -= 1.0f;
while(CWorld::GetSectorY(Source.y) < 5.0f)
Source.y += 1.0f;
@@ -3990,7 +4105,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];
@@ -4030,109 +4145,372 @@ 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, 0.1f) > 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, 0.1f) > 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;
+ }
+
+ 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);
+ if(CamSource.z > Source.z + ARRESTCAM_S_ROTATION_UP*CTimer::GetTimeStep())
+ CamSource.z = Source.z + ARRESTCAM_S_ROTATION_UP*CTimer::GetTimeStep();
+ }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;
}
@@ -4182,376 +4560,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)
@@ -4627,7 +4635,7 @@ CCam::Process_FollowPed_Rotation(const CVector &CameraTarget, float TargetOrient
*/
{
LookLeftRight = -CPad::GetPad(0)->LookAroundLeftRight();
- LookUpDown = -CPad::GetPad(0)->LookAroundUpDown();
+ LookUpDown = CPad::GetPad(0)->LookAroundUpDown();
}
float AlphaOffset, BetaOffset;
if(UseMouse){
@@ -4679,6 +4687,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));
@@ -4726,7 +4736,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);
@@ -4782,9 +4792,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);
@@ -4795,8 +4805,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) {
@@ -4853,6 +4865,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) {
@@ -4867,6 +4887,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)) {
@@ -4880,10 +4903,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
@@ -4913,17 +4932,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;
@@ -4938,7 +4954,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;
}
@@ -4990,9 +5006,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();
@@ -5046,7 +5062,7 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
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 {
@@ -5150,8 +5166,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;
}
@@ -5236,7 +5252,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;
@@ -5261,14 +5277,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);
@@ -5310,19 +5326,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;
diff --git a/src/core/Camera.cpp b/src/core/Camera.cpp
index 4551e36f..531c3417 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
};
@@ -62,6 +71,11 @@ enum
CCamera TheCamera;
bool CCamera::m_bUseMouse3rdPerson = true;
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)
@@ -72,46 +86,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;
@@ -120,8 +115,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;
@@ -178,26 +186,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;
@@ -216,6 +216,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;
@@ -235,21 +237,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;
@@ -277,6 +276,7 @@ CCamera::Process(void)
if(m_WideScreenOn)
ProcessWideScreenOn();
+#ifndef MASTER
#ifdef IMPROVED_CAMERA
if(CPad::GetPad(1)->GetCircleJustDown() || CTRLJUSTDOWN('B')){
#else
@@ -288,6 +288,7 @@ CCamera::Process(void)
else
CPad::m_bMapPadOneToPadTwo = false;
}
+#endif
RwCameraSetNearClipPlane(Scene.camera, DEFAULT_NEAR);
@@ -307,19 +308,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)
@@ -331,169 +324,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;
@@ -504,37 +378,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);
@@ -565,33 +424,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);
@@ -623,21 +469,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)
@@ -650,6 +509,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;
@@ -666,13 +556,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;
@@ -693,7 +591,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();
@@ -702,11 +602,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)
@@ -715,16 +613,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){
@@ -740,8 +644,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;
@@ -759,6 +661,7 @@ CCamera::Process(void)
}
m_bCameraJustRestored = false;
+ m_bMoveCamToAvoidGeom = false;
}
void
@@ -766,10 +669,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;
@@ -782,20 +685,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;
@@ -804,11 +699,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;
@@ -824,25 +719,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;
@@ -852,45 +757,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
@@ -901,9 +849,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));
@@ -933,33 +887,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;
@@ -967,7 +926,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){
@@ -1011,7 +970,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;
}
}
@@ -1021,49 +981,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;
@@ -1072,7 +1038,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
@@ -1110,6 +1076,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);
@@ -1124,15 +1092,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;
@@ -1167,20 +1133,37 @@ CCamera::CamControl(void)
}else{
whichDoor = 1;
garageDoorPos1 = Cams[ActiveCam].Source;
+ garageCenter = CVector((stairsZone->minx+stairsZone->maxx)/2.0f, (stairsZone->miny+stairsZone->maxy)/2.0f, 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){
+// 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;
+ }
}
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 == nil) // how can this be true?
garageCenter = CVector(pTargetEntity->GetPosition().x, pTargetEntity->GetPosition().y, 0.0f);
}
if(whichDoor == 1)
@@ -1194,9 +1177,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;
@@ -1204,8 +1193,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));
@@ -1233,6 +1222,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())
@@ -1255,8 +1251,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){
@@ -1266,7 +1264,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;
@@ -1308,7 +1306,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){
@@ -1334,8 +1332,6 @@ CCamera::CamControl(void)
}
}
- m_bIdleOn = false;
-
if(DebugCamMode)
ReqMode = DebugCamMode;
@@ -1344,56 +1340,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();
@@ -1405,7 +1411,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;
@@ -1439,16 +1444,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;
@@ -1472,6 +1481,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)
@@ -1486,7 +1499,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())
@@ -1504,11 +1517,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 ||
@@ -1523,8 +1541,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 ||
@@ -1535,7 +1555,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;
@@ -1544,7 +1565,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
@@ -1563,7 +1584,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;
@@ -1583,12 +1609,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();
}
@@ -1622,8 +1647,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;
@@ -1636,7 +1659,6 @@ CCamera::CamControl(void)
m_bWaitForInterpolToFinish = true;
}
}
-#endif
if(m_bWaitForInterpolToFinish)
startTransition = false;
@@ -1646,19 +1668,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);
@@ -1669,10 +1704,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;
@@ -1698,23 +1738,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_SOUND, 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){
@@ -1732,7 +1791,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 ||
@@ -1742,14 +1800,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){
@@ -1761,16 +1826,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)
@@ -1801,6 +1859,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())
@@ -1819,33 +1878,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
@@ -1890,6 +1922,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
@@ -1919,7 +2092,6 @@ CCamera::TakeControl(CEntity *target, int16 mode, int16 typeOfSwitch, int32 cont
m_iTypeOfSwitch = typeOfSwitch;
m_bLookingAtPlayer = false;
m_bStartInterScript = true;
- // FindPlayerPed(); // unused
}
}
@@ -1949,8 +2121,6 @@ CCamera::TakeControlWithSpline(int16 typeOfSwitch)
m_bcutsceneFinished = false;
m_iTypeOfSwitch = typeOfSwitch;
m_bStartInterScript = true;
-
- //FindPlayerPed(); // unused
};
void
@@ -1985,10 +2155,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
@@ -2005,6 +2178,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;
@@ -2034,27 +2209,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;
@@ -2067,20 +2240,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;
@@ -2092,6 +2266,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;
@@ -2099,12 +2274,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;
@@ -2119,70 +2288,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;
@@ -2194,11 +2335,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
@@ -2247,6 +2384,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
@@ -2254,10 +2392,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;
@@ -2265,73 +2399,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_vehEnterType;
- 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;
@@ -2339,7 +2417,6 @@ CCamera::StartTransition(int16 newMode)
break;
}
-#ifndef PS2_CAM_TRANSITION
Cams[ActiveCam].Init();
Cams[ActiveCam].Mode = newMode;
@@ -2349,30 +2426,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;
@@ -2403,28 +2481,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)
{
@@ -2437,7 +2519,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
@@ -2471,26 +2553,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));
}
@@ -2508,7 +2588,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;
@@ -2518,7 +2600,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;
@@ -2527,14 +2609,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;
@@ -2546,10 +2628,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:
@@ -2560,13 +2642,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;
@@ -2575,7 +2657,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:
@@ -2639,6 +2721,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;
}
@@ -2648,7 +2814,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;
@@ -2658,7 +2825,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();
@@ -2673,7 +2840,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);
@@ -2690,17 +2857,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();
@@ -2723,10 +2890,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));
@@ -2783,7 +2950,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){
@@ -2811,7 +2978,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){
@@ -2906,12 +3073,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,
@@ -2927,19 +3301,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]);
}
}
@@ -2947,6 +3321,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
@@ -2974,6 +3382,7 @@ CCamera::DontProcessObbeCinemaCamera(void)
bDidWeProcessAnyCinemaCam = false;
}
+#ifdef GTA_TRAIN
void
CCamera::LoadTrainCamNodes(char const *name)
{
@@ -3158,6 +3567,7 @@ CCamera::Process_Train_Camera_Control(void)
}
}
}
+#endif
void
@@ -3169,9 +3579,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;
@@ -3208,6 +3623,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;
}
@@ -3215,6 +3632,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);
@@ -3275,26 +3703,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
@@ -3309,33 +3753,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;
}
}
@@ -3346,46 +3780,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);
}
}
@@ -3401,22 +3817,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;
@@ -3523,6 +3930,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;
@@ -3532,6 +3940,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;
@@ -3575,6 +3984,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
@@ -3599,8 +4020,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
@@ -3685,7 +4107,5 @@ CCamera::IsBoxVisible(RwV3d *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 ca1bd135..4da7b499 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..6c54ac63 100644
--- a/src/core/Clock.cpp
+++ b/src/core/Clock.cpp
@@ -5,6 +5,8 @@
#include "Clock.h"
#include "Stats.h"
+// --MIAMI: File done
+
_TODO("gbFastTime");
bool gbFastTime;
@@ -73,8 +75,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 cadba7f2..fe865865 100644
--- a/src/core/ControllerConfig.cpp
+++ b/src/core/ControllerConfig.cpp
@@ -21,6 +21,8 @@
#include "Camera.h"
#include "GenericGameStorage.h"
+// --MIAMI: file done
+
CControllerConfigManager ControlsManager;
CControllerConfigManager::CControllerConfigManager()
@@ -131,6 +133,7 @@ void CControllerConfigManager::SaveSettings(int32 file)
void CControllerConfigManager::LoadSettings(int32 file)
{
bool bValid = true;
+ int nVersion = 0;
if (file)
{
@@ -139,11 +142,13 @@ void CControllerConfigManager::LoadSettings(int32 file)
if (!strncmp(buff, TopLineEmptyFile, sizeof(TopLineEmptyFile)-1))
bValid = false;
- else
+ else {
CFileMgr::Seek(file, 0, 0);
+ CFileMgr::Read(file, (char*)&nVersion, sizeof(nVersion));
+ }
}
- if (bValid)
+ if (bValid && nVersion >= 3)
{
ControlsManager.MakeControllerActionsBlank();
@@ -202,9 +207,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);
@@ -220,6 +229,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 ?
@@ -262,7 +273,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++)
{
@@ -305,6 +316,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);
}
}
@@ -342,13 +357,14 @@ void CControllerConfigManager::InitDefaultControlConfigJoyPad(uint32 buttons)
SetControllerKeyAssociatedWithAction(TOGGLE_SUBMISSIONS, 11, JOYSTICK);
case 10:
SetControllerKeyAssociatedWithAction(VEHICLE_HORN, 10, JOYSTICK);
+ SetControllerKeyAssociatedWithAction(PED_DUCK, 10, JOYSTICK);
case 9:
SetControllerKeyAssociatedWithAction(CAMERA_CHANGE_VIEW_ALL_SITUATIONS, 9, JOYSTICK);
case 8:
SetControllerKeyAssociatedWithAction(VEHICLE_HANDBRAKE, 8, JOYSTICK);
SetControllerKeyAssociatedWithAction(PED_LOCK_TARGET, 8, JOYSTICK);
case 7:
- SetControllerKeyAssociatedWithAction(PED_CENTER_CAMERA_BEHIND_PLAYER, 7, JOYSTICK);
+ SetControllerKeyAssociatedWithAction(PED_ANSWER_PHONE, 7, JOYSTICK);
SetControllerKeyAssociatedWithAction(VEHICLE_CHANGE_RADIO_STATION, 7, JOYSTICK);
case 6:
SetControllerKeyAssociatedWithAction(PED_CYCLE_WEAPON_RIGHT, 6, JOYSTICK);
@@ -393,13 +409,14 @@ void CControllerConfigManager::InitDefaultControlConfigJoyPad(uint32 buttons)
SetControllerKeyAssociatedWithAction(TOGGLE_SUBMISSIONS, 11, JOYSTICK);
case 10:
SetControllerKeyAssociatedWithAction(VEHICLE_HORN, 10, JOYSTICK);
+ SetControllerKeyAssociatedWithAction(PED_DUCK, 10, JOYSTICK);
case 9:
SetControllerKeyAssociatedWithAction(CAMERA_CHANGE_VIEW_ALL_SITUATIONS, 9, JOYSTICK);
case 8:
SetControllerKeyAssociatedWithAction(VEHICLE_HANDBRAKE, 8, JOYSTICK);
SetControllerKeyAssociatedWithAction(PED_LOCK_TARGET, 8, JOYSTICK);
case 7:
- SetControllerKeyAssociatedWithAction(PED_CENTER_CAMERA_BEHIND_PLAYER, 7, JOYSTICK);
+ SetControllerKeyAssociatedWithAction(PED_ANSWER_PHONE, 7, JOYSTICK);
SetControllerKeyAssociatedWithAction(VEHICLE_CHANGE_RADIO_STATION, 7, JOYSTICK);
case 6:
SetControllerKeyAssociatedWithAction(PED_CYCLE_WEAPON_RIGHT, 6, JOYSTICK);
@@ -442,8 +459,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);
@@ -469,6 +489,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);
@@ -498,11 +522,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;
@@ -606,6 +631,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;
@@ -714,10 +740,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
)))
{
@@ -778,6 +801,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)
@@ -786,14 +811,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;
@@ -863,7 +892,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))
{
@@ -1621,12 +1650,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);
@@ -1639,13 +1668,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);
@@ -1665,7 +1696,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);
@@ -1682,16 +1713,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);
@@ -1730,36 +1760,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;
}
@@ -1795,25 +1825,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:
@@ -1823,15 +1855,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:
@@ -1846,13 +1878,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;
diff --git a/src/core/ControllerConfig.h b/src/core/ControllerConfig.h
index 92017a93..eb66937a 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 8dfae5b8..3c3e2b26 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 8d69ba78..fc345163 100644
--- a/src/core/EventList.cpp
+++ b/src/core/EventList.cpp
@@ -10,6 +10,8 @@
#include "main.h"
#include "Accident.h"
+// --MIAMI: file done
+
int32 CEventList::ms_nFirstFreeSlotIndex;
CEvent gaEvent[NUMEVENTS];
@@ -75,8 +77,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);
@@ -198,7 +198,7 @@ CEventList::FindClosestEvent(eEventType type, CVector posn, int32 *event)
}
void
-CEventList::ReportCrimeForEvent(eEventType type, int32 crimeId, bool copsDontCare)
+CEventList::ReportCrimeForEvent(eEventType type, size_t crimeId, bool copsDontCare)
{
eCrimeType crime;
switch(type){
@@ -211,27 +211,43 @@ CEventList::ReportCrimeForEvent(eEventType type, int32 crimeId, bool copsDontCar
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->m_nWantedLevel == 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 8840afc4..dcca1270 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
};
@@ -59,7 +62,7 @@ public:
static bool GetEvent(eEventType type, int32 *event);
static void ClearEvent(int32 event);
static bool FindClosestEvent(eEventType type, CVector posn, int32 *event);
- static void ReportCrimeForEvent(eEventType type, int32, bool);
+ static void ReportCrimeForEvent(eEventType type, size_t, bool);
};
extern CEvent gaEvent[NUMEVENTS]; \ No newline at end of file
diff --git a/src/core/FileLoader.cpp b/src/core/FileLoader.cpp
index 0ad03f61..d66a1b88 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,11 @@
#include "CdStream.h"
#include "FileLoader.h"
#include "MemoryHeap.h"
+#include "Streaming.h"
+#include "ColStore.h"
+#include "Occlusion.h"
+
+//--MIAMI: file done
char CFileLoader::ms_line[256];
@@ -47,25 +53,17 @@ 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)){
@@ -86,12 +84,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);
@@ -103,19 +97,19 @@ CFileLoader::LoadLevel(const char *filename)
LoadObjectTypes(line + 4);
}else if(strncmp(line, "IPL", 3) == 0){
if(!objectsLoaded){
- PUSH_MEMID(MEMID_DEF_MODELS);
- CModelInfo::ConstructMloClumps();
+ LoadingScreenLoadingFile("Collision");
POP_MEMID();
CObjectData::Initialise("DATA\\OBJECT.DAT");
+ CStreaming::Init();
+ CColStore::LoadAllCollision();
+ 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());
@@ -127,30 +121,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*
@@ -194,7 +171,7 @@ struct ColHeader
};
void
-CFileLoader::LoadCollisionFile(const char *filename)
+CFileLoader::LoadCollisionFile(const char *filename, uint8 colSlot)
{
int fd;
char modelname[24];
@@ -205,6 +182,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(strncmp(header.ident, "COLL", 4) == 0);
@@ -213,10 +191,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);
}
@@ -230,6 +209,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(strncmp(header->ident, "COLL", 4) != 0)
+ 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(strncmp(header->ident, "COLL", 4) != 0)
+ 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)
{
@@ -260,14 +312,15 @@ CFileLoader::LoadCollisionModel(uint8 *buf, CColModel &model, char *modelname)
model.numLines = *(int16*)buf;
buf += 4;
if(model.numLines > 0){
- model.lines = (CColLine*)RwMalloc(model.numLines*sizeof(CColLine));
- REGISTER_MEMPTR(&model.lines);
+ //model.lines = (CColLine*)RwMalloc(model.numLines*sizeof(CColLine));
for(i = 0; i < model.numLines; i++){
- model.lines[i].Set(*(CVector*)buf, *(CVector*)(buf+12));
+ //model.lines[i].Set(*(CVector*)buf, *(CVector*)(buf+12));
buf += 24;
}
}else
model.lines = nil;
+ model.numLines = 0;
+ model.lines = nil;
model.numBoxes = *(int16*)buf;
buf += 4;
@@ -288,10 +341,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
@@ -303,7 +358,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
@@ -315,7 +370,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){
@@ -341,11 +396,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);
}
@@ -421,17 +476,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;
}
@@ -486,334 +533,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",
- "newdockbuilding",
- "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",
- ""
-};
-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)
{
@@ -823,11 +542,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;
}
@@ -867,8 +586,9 @@ CFileLoader::LoadObjectTypes(const char *filename)
enum {
NONE,
OBJS,
- MLO,
+ MLO, // unused but enum still has it
TOBJ,
+ WEAP,
HIER,
CARS,
PEDS,
@@ -879,16 +599,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;
@@ -896,25 +617,27 @@ CFileLoader::LoadObjectTypes(const char *filename)
if(section == NONE){
if(strncmp(line, "objs", 4) == 0) section = OBJS;
else if(strncmp(line, "tobj", 4) == 0) section = TOBJ;
+ else if(strncmp(line, "weap", 4) == 0) section = WEAP;
else if(strncmp(line, "hier", 4) == 0) section = HIER;
else if(strncmp(line, "cars", 4) == 0) section = CARS;
else if(strncmp(line, "peds", 4) == 0) section = PEDS;
else if(strncmp(line, "path", 4) == 0) section = PATH;
else if(strncmp(line, "2dfx", 4) == 0) section = TWODFX;
}else if(strncmp(line, "end", 3) == 0){
- section = section == MLO ? OBJS : NONE;
+ section = NONE;
}else switch(section){
case OBJS:
- if(strncmp(line, "sta", 3) == 0)
- 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);
@@ -927,17 +650,15 @@ CFileLoader::LoadObjectTypes(const char *filename)
break;
case PATH:
if(pathIndex == -1){
- id = LoadPathHeader(line, pathTypeStr);
- if(strncmp(pathTypeStr, "ped", 4) == 0)
- pathType = 1;
- else if(strncmp(pathTypeStr, "car", 4) == 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;
@@ -950,41 +671,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->GetName(), DoubleSidedNames)) mi->m_bIsDoubleSided = true;
- if(MatchModelName(mi->GetName(), TreeNames)) mi->m_bIsTree = true;
- if(MatchModelName(mi->GetName(), 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;
@@ -995,7 +705,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:
@@ -1027,60 +737,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 someFloat;
-
- sscanf(line, "%s %s %d %f", smth, name, &modelIndex, &someFloat);
- CMloModelInfo *minfo = CModelInfo::AddMloModel(modelIndex);
- minfo->SetName(name);
- minfo->field_34 = someFloat;
- 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;
@@ -1092,7 +753,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:
@@ -1128,6 +789,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->SetName(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
@@ -1150,21 +834,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->SetName(model);
mi->SetTexDictionary(txd);
+ mi->SetAnimFile(animFile);
for(p = gamename; *p; p++)
if(*p == '_') *p = ' ';
strcpy(mi->m_gameName, gamename);
@@ -1194,36 +879,34 @@ CFileLoader::LoadVehicleObject(const char *line)
mi->m_handlingId = mod_HandlingManager.GetHandlingId(handlingId);
- // Well this is kinda dumb....
- if(strncmp(vehclass, "poorfamily", 11) == 0){
+ if(strncmp(vehclass, "normal", 7) == 0)
+ mi->m_vehicleClass = CCarCtrl::NORMAL;
+ else if(strncmp(vehclass, "poorfamily", 11) == 0)
mi->m_vehicleClass = CCarCtrl::POOR;
- while(frequency-- > 0)
- CCarCtrl::AddToCarArray(id, CCarCtrl::POOR);
- }else if(strncmp(vehclass, "richfamily", 11) == 0){
+ else if(strncmp(vehclass, "richfamily", 11) == 0)
mi->m_vehicleClass = CCarCtrl::RICH;
- while(frequency-- > 0)
- CCarCtrl::AddToCarArray(id, CCarCtrl::RICH);
- }else if(strncmp(vehclass, "executive", 10) == 0){
+ else if(strncmp(vehclass, "executive", 10) == 0)
mi->m_vehicleClass = CCarCtrl::EXEC;
- while(frequency-- > 0)
- CCarCtrl::AddToCarArray(id, CCarCtrl::EXEC);
- }else if(strncmp(vehclass, "worker", 7) == 0){
+ else if(strncmp(vehclass, "worker", 7) == 0)
mi->m_vehicleClass = CCarCtrl::WORKER;
- while(frequency-- > 0)
- CCarCtrl::AddToCarArray(id, CCarCtrl::WORKER);
- }else if(strncmp(vehclass, "special", 8) == 0){
- mi->m_vehicleClass = CCarCtrl::SPECIAL;
- while(frequency-- > 0)
- CCarCtrl::AddToCarArray(id, CCarCtrl::SPECIAL);
- }else if(strncmp(vehclass, "big", 4) == 0){
+ else if(strncmp(vehclass, "big", 4) == 0)
mi->m_vehicleClass = CCarCtrl::BIG;
- while(frequency-- > 0)
- CCarCtrl::AddToCarArray(id, CCarCtrl::BIG);
- }else if(strncmp(vehclass, "taxi", 5) == 0){
+ else if(strncmp(vehclass, "taxi", 5) == 0)
mi->m_vehicleClass = CCarCtrl::TAXI;
- while(frequency-- > 0)
- CCarCtrl::AddToCarArray(id, CCarCtrl::TAXI);
+ else if(strncmp(vehclass, "moped", 6) == 0)
+ mi->m_vehicleClass = CCarCtrl::MOPED;
+ else if(strncmp(vehclass, "motorbike", 10) == 0)
+ mi->m_vehicleClass = CCarCtrl::MOTORBIKE;
+ else if(strncmp(vehclass, "leisureboat", 12) == 0)
+ mi->m_vehicleClass = CCarCtrl::LEISUREBOAT;
+ else if(strncmp(vehclass, "workerboat", 11) == 0)
+ mi->m_vehicleClass = CCarCtrl::WORKERBOAT;
+ else if(strncmp(vehclass, "ignore", 11) == 0){
+ mi->m_vehicleClass = -1;
+ return;
}
+ CCarCtrl::AddToCarArray(id, mi->m_vehicleClass);
+ mi->m_frequency = frequency;
}
void
@@ -1231,67 +914,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->SetName(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;
@@ -1368,6 +1071,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();
@@ -1381,20 +1096,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;
@@ -1405,6 +1121,7 @@ CFileLoader::LoadScene(const char *filename)
else if(strncmp(line, "cull", 4) == 0) section = CULL;
else if(strncmp(line, "pick", 4) == 0) section = PICK;
else if(strncmp(line, "path", 4) == 0) section = PATH;
+ else if(strncmp(line, "occl", 4) == 0) section = OCCL;
}else if(strncmp(line, "end", 3) == 0){
section = NONE;
}else switch(section){
@@ -1417,18 +1134,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);
- // 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;
@@ -1451,18 +1174,30 @@ 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());
+ if(!CStreaming::IsObjectInCdImage(id))
+ debug("Not in cdimage %s\n", mi->GetName());
+
angle = -RADTODEG(2.0f * acosf(angle));
xform = RwMatrixCreate();
RwMatrixRotate(xform, &axis, angle, rwCOMBINEREPLACE);
@@ -1477,7 +1212,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)
@@ -1486,14 +1222,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);
@@ -1539,53 +1286,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(strncmp(line, "zone", 4) == 0) section = ZONE;
- }else if(strncmp(line, "end", 3) == 0){
- 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);
}
+
+//--MIAMI: unused
void
CFileLoader::ReloadPaths(const char *filename)
{
@@ -1596,10 +1311,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;
@@ -1615,17 +1330,15 @@ CFileLoader::ReloadPaths(const char *filename)
switch (section) {
case PATH:
if (pathIndex == -1) {
- id = LoadPathHeader(line, pathTypeStr);
- if (strncmp(pathTypeStr, "ped", 4) == 0)
- pathType = 1;
- else if (strncmp(pathTypeStr, "car", 4) == 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;
@@ -1655,6 +1368,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 == '#')
@@ -1730,6 +1444,7 @@ 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)) {
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/FileMgr.cpp b/src/core/FileMgr.cpp
index 6e6a8efc..d3695cb4 100644
--- a/src/core/FileMgr.cpp
+++ b/src/core/FileMgr.cpp
@@ -274,13 +274,13 @@ CFileMgr::OpenFileForWriting(const char *file)
}
size_t
-CFileMgr::Read(int fd, const char *buf, int len)
+CFileMgr::Read(int fd, const char *buf, size_t len)
{
return myfread((void*)buf, 1, len, fd);
}
size_t
-CFileMgr::Write(int fd, const char *buf, int len)
+CFileMgr::Write(int fd, const char *buf, size_t len)
{
return myfwrite((void*)buf, 1, len, fd);
}
diff --git a/src/core/FileMgr.h b/src/core/FileMgr.h
index 4734720e..8278953b 100644
--- a/src/core/FileMgr.h
+++ b/src/core/FileMgr.h
@@ -13,8 +13,8 @@ public:
static int OpenFile(const char *file, const char *mode);
static int OpenFile(const char *file) { return OpenFile(file, "rb"); }
static int OpenFileForWriting(const char *file);
- static size_t Read(int fd, const char *buf, int len);
- static size_t Write(int fd, const char *buf, int len);
+ static size_t Read(int fd, const char *buf, size_t len);
+ static size_t Write(int fd, const char *buf, size_t len);
static bool Seek(int fd, int offset, int whence);
static bool ReadLine(int fd, char *buf, int len);
static int CloseFile(int fd);
diff --git a/src/core/Fire.cpp b/src/core/Fire.cpp
index 2c57c066..e73ffea1 100644
--- a/src/core/Fire.cpp
+++ b/src/core/Fire.cpp
@@ -15,6 +15,10 @@
#include "DamageManager.h"
#include "Ped.h"
#include "Fire.h"
+#include "GameLogic.h"
+#include "CarAI.h"
+
+// --MIAMI: file done
CFireManager gFireManager;
@@ -25,14 +29,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 +54,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 +64,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 +95,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 +109,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 +117,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()) {
@@ -161,11 +178,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;
}
@@ -175,7 +204,7 @@ CFire::Extinguish(void)
}
void
-CFireManager::StartFire(CVector pos, float size, bool propagation)
+CFireManager::StartFire(CVector pos, float size, uint8 propagation)
{
CFire *fire = GetNextFreeFire();
@@ -192,11 +221,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;
@@ -225,6 +255,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();
@@ -242,6 +273,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);
@@ -250,6 +284,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();
@@ -288,26 +323,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;
}
@@ -360,8 +392,39 @@ CFireManager::ExtinguishPoint(CVector point, float range)
}
}
+bool
+CFireManager::ExtinguishPointWithWater(CVector point, float range)
+{
+ int fireI = 0;
+ for (int i = 0; i < NUM_FIRES; i++) {
+ if (m_aFires[i].m_bIsOngoing) {
+ if ((point - m_aFires[i].m_vecPos).MagnitudeSqr() < sq(range)) {
+ fireI = i;
+ break;
+ }
+ }
+ }
+ if (fireI == NUM_FIRES)
+ return false;
+
+ CFire *fireToExtinguish = &m_aFires[fireI];
+ 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;
@@ -388,12 +451,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;
@@ -421,8 +487,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 5ea756e7..18554a4d 100644
--- a/src/core/Frontend.cpp
+++ b/src/core/Frontend.cpp
@@ -36,47 +36,37 @@
#include "Stats.h"
#include "Messages.h"
#include "FileLoader.h"
-#include "frontendoption.h"
+#include "User.h"
+#include "sampman.h"
+// --MIAMI: file done
+
+// 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)
@@ -98,9 +88,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
@@ -114,94 +107,23 @@ 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 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 CMenuManager::OS_Language = LANG_ENGLISH;
-int8 CMenuManager::m_PrefsUseVibration;
-int8 CMenuManager::m_DisplayControllerOnFoot;
-int8 CMenuManager::m_PrefsVsync = 1;
-int8 CMenuManager::m_PrefsVsyncDisp = 1;
-int8 CMenuManager::m_PrefsFrameLimiter = 1;
-int8 CMenuManager::m_PrefsShowSubtitles = 1;
-int8 CMenuManager::m_PrefsSpeakers;
-int32 CMenuManager::m_ControlMethod;
-int8 CMenuManager::m_PrefsDMA = 1;
-int32 CMenuManager::m_PrefsLanguage;
-uint8 CMenuManager::m_PrefsStereoMono; // unused except restore settings
-
-bool CMenuManager::m_PrefsAllowNastyGame = true;
-bool CMenuManager::m_bStartUpFrontEndRequested;
-bool CMenuManager::m_bShutDownFrontEndRequested;
-
-int8 CMenuManager::m_PrefsUseWideScreen;
-int8 CMenuManager::m_PrefsRadioStation;
-int32 CMenuManager::m_PrefsBrightness = 256;
-float CMenuManager::m_PrefsLOD = CRenderer::ms_lodDistScale;
-int8 CMenuManager::m_bFrontEnd_ReloadObrTxtGxt;
-int32 CMenuManager::m_PrefsMusicVolume = 102;
-int32 CMenuManager::m_PrefsSfxVolume = 102;
-
-char CMenuManager::m_PrefsSkinFile[256] = DEFAULT_SKIN_NAME;
-
-int32 CMenuManager::m_KeyPressedCode = -1;
-
-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;
@@ -209,73 +131,32 @@ 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 MENU_MAP
-const char* MapFilenames[][2] = {
+ {"background", ""},
+ {"vc_logo", "vc_logom"},
+ {"mouse", "mousea"},
+ {"mapTop01", "mapTop01A"},
+ {"mapTop02", "mapTop02A"},
+ {"mapTop03", "mapTop03A"},
{"mapMid01", "mapMid01A"},
{"mapMid02", "mapMid02A"},
{"mapMid03", "mapMid03A"},
{"mapBot01", "mapBot01A"},
{"mapBot02", "mapBot02A"},
{"mapBot03", "mapBot03A"},
- {"mapTop01", "mapTop01A"},
- {"mapTop02", "mapTop02A"},
- {"mapTop03", "mapTop03A"},
-};
-CSprite2d CMenuManager::m_aMapSprites[NUM_MAP_SPRITES];
-#endif
-
-// 0x5F3344
-const char* MenuFilenames[][2] = {
- {"connection24", ""},
- {"findgame24", ""},
- {"hostgame24", ""},
- {"mainmenu24", ""},
- {"Playersetup24", ""},
- {"singleplayer24", ""},
- {"multiplayer24", ""},
- {"dmalogo128", "dmalogo128m"},
- {"gtaLogo128", "gtaLogo128"},
- {"rockstarLogo128", "rockstarlogo128m"},
- {"gamespy256", "gamespy256a"},
- {"mouse", "mousetimera"},
- {"mousetimer", "mousetimera"},
- {"mp3logo", "mp3logoA"},
- {"downOFF", "buttonA"},
- {"downON", "buttonA"},
+ {"wildstyle", "wildstyleA"},
+ {"flash", "flashA"},
+ {"kchat", "kchatA"},
+ {"fever", "feverA"},
+ {"vrock", "vrockA"},
+ {"vcpr", "vcprA"},
+ {"espantoso", "espantosoA"},
+ {"emotion", "emotionA"},
+ {"wave103", "wave103A"},
+ {"mp3", "mp3A"},
+ {"downOff", "buttonA"},
+ {"downOn", "buttonA"},
{"upOff", "buttonA"},
- {"upON", "buttonA"},
- {"gta3logo256", "gta3logo256m"},
- { nil, nil }
+ {"upOn", "buttonA"}
};
#define MENU_X_RIGHT_ALIGNED(x) SCALE_AND_CENTER_X(DEFAULT_SCREEN_WIDTH - (x))
@@ -291,31 +172,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;
+PauseModeTime 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(); \
@@ -326,46 +200,34 @@ 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));
+ CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(MENU_X_MARGIN));
-#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));
-
-#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) {
@@ -379,7 +241,7 @@ CMenuManager::ScrollUpListByOne()
}
}
-void
+inline void
CMenuManager::ScrollDownListByOne()
{
if (m_nSelectedListRow == m_nFirstVisibleRowOnList + MAX_VISIBLE_OPTION_ON_SCREEN - 1) {
@@ -395,13 +257,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);
@@ -413,13 +275,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);
@@ -432,6 +294,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++) {
@@ -440,30 +303,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;
}
@@ -471,10 +325,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;
@@ -483,7 +333,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)
@@ -496,16 +345,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;
@@ -522,271 +368,206 @@ 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;
- }
-
- 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;
- }
- }
-
-#ifndef TIDY_UP_PBP
- if (CPad::GetPad(0)->GetEscapeJustDown() || CPad::GetPad(0)->GetBackJustDown()) {
- m_bShowMouse = false;
- goBack = true;
+ m_nCurrOption = 0;
+ m_nCurrScreen = screen;
}
-#endif
+ SETUP_SCROLLING(m_nCurrScreen)
+
+ if (hasNativeList(m_nPrevScreen))
+ m_nTotalListRow = 0;
- 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();
- }
- }
- }
+ if (m_nCurrScreen == MENUPAGE_CHOOSE_SAVE_SLOT)
+ m_nCurrOption = 8;
+ m_nMenuFadeAlpha = 0;
+ m_nOptionHighlightTransitionBlend = 0;
+ m_LastScreenSwitch = CTimer::GetTimeInMillisecondsPauseMode();
+}
- 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;
- }
+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;
+ m_PrefsUseWideScreen = 0;
+ m_PrefsVsync = 0;
+ m_PrefsVsyncDisp = 1;
+ m_PrefsFrameLimiter = 1;
+ m_PrefsLanguage = 0;
+ field_54 = 0;
+ m_PrefsAllowNastyGame = 1;
+ m_PrefsSpeakers = 0;
+ field_8 = 0;
+ m_PrefsUseVibration = 0;
+ m_PrefsShowHud = 1;
+ m_PrefsRadarMode = 0;
+ 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;
+ CCamera::m_bUseMouse3rdPerson = true;
+ 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)->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;
- }
- }
- }
+ 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);
}
-// ------ 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
-#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);
- } else
- gString2[0] = '\0';
+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();
+ if (!m_OnlySaveMenu)
+ m_nCurrScreen = MENUPAGE_NONE;
+ DMAudio.ChangeMusicMode(MUSICMODE_FRONTEND);
+ DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_STARTING, 0);
+ DMAudio.Service();
+ DMAudio.SetMusicMasterVolume(m_PrefsMusicVolume);
+ DMAudio.SetEffectsMasterVolume(m_PrefsSfxVolume);
+ m_PrefsRadioStation = DMAudio.GetRadioInCar();
+ DMAudio.SetMP3BoostVolume(m_PrefsMP3BoostVolume);
+ if (DMAudio.IsMP3RadioChannelAvailable()) {
+ if (m_PrefsRadioStation < WILDSTYLE || m_PrefsRadioStation > USERTRACK)
+ m_PrefsRadioStation = CGeneral::GetRandomNumber() % 10;
+ } else if (m_PrefsRadioStation < WILDSTYLE || m_PrefsRadioStation > WAVE)
+ m_PrefsRadioStation = CGeneral::GetRandomNumber() % 9;
- UnicodeStrcpy(gUString, TheText.Get(text));
- AsciiToUnicode(gString2, gUString2);
+ CFileMgr::SetDir("");
+ //CFileMgr::SetDir("");
+ PcSaveHelper.PopulateSlotInfo();
+ CTimer::StartUserPause();
}
void
@@ -843,26 +624,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;
@@ -870,14 +648,6 @@ CMenuManager::CheckCodesForControls(int typeOfControl)
m_bStartWaitingForKeyBind = false;
SaveSettings();
}
-
- if (escPressed) {
- pControlEdit = nil;
- m_bWaitingForNewKeyBind = false;
- m_KeyPressedCode = -1;
- m_bStartWaitingForKeyBind = false;
- SaveSettings();
- }
}
bool
@@ -892,31 +662,43 @@ CMenuManager::CheckSliderMovement(int value)
{
switch (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action) {
case MENUACTION_BRIGHTNESS:
- m_PrefsBrightness += value * (512/16);
- m_PrefsBrightness = clamp(m_PrefsBrightness, 0, 511);
+ m_PrefsBrightness += value * 24.19f;
+ m_PrefsBrightness = clamp(m_PrefsBrightness, 0, 384);
break;
case MENUACTION_DRAWDIST:
if(value > 0)
- m_PrefsLOD += ((1.8f - 0.8f) / 16.0f);
+ m_PrefsLOD += ((1.8f - 0.925f) / 16.0f);
else
- m_PrefsLOD -= ((1.8f - 0.8f) / 16.0f);
- m_PrefsLOD = clamp(m_PrefsLOD, 0.8f, 1.8f);
+ m_PrefsLOD -= ((1.8f - 0.925f) / 16.0f);
+ m_PrefsLOD = clamp(m_PrefsLOD, 0.925f, 1.8f);
CRenderer::ms_lodDistScale = m_PrefsLOD;
break;
case MENUACTION_MUSICVOLUME:
- m_PrefsMusicVolume += value * (128/16);
- m_PrefsMusicVolume = clamp(m_PrefsMusicVolume, 0, 127);
- DMAudio.SetMusicMasterVolume(m_PrefsMusicVolume);
+ if (m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER) {
+ m_PrefsMusicVolume += value * (128 / 32);
+ m_PrefsMusicVolume = clamp(m_PrefsMusicVolume, 0, 65);
+ DMAudio.SetMusicMasterVolume(m_PrefsMusicVolume);
+ }
break;
case MENUACTION_SFXVOLUME:
- m_PrefsSfxVolume += value * (128/16);
- m_PrefsSfxVolume = clamp(m_PrefsSfxVolume, 0, 127);
- DMAudio.SetEffectsMasterVolume(m_PrefsSfxVolume);
+ if (m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER) {
+ m_PrefsSfxVolume += value * (128 / 32);
+ 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 * (128 / 32);
+ 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; // ???
TheCamera.m_fMouseAccelHorzntl = clamp(TheCamera.m_fMouseAccelHorzntl, 1.0f/3200.0f, 1.0f/200.0f);
- TheCamera.m_fMouseAccelVertical = TheCamera.m_fMouseAccelHorzntl;
break;
default:
return;
@@ -925,77 +707,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;
+ static PauseModeTime LastFlash = 0;
+ 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
- static float fadeAlpha = 0.0f; // To keep it precisely
- if (m_nHelperTextAlpha >= 255 && fadeAlpha < 250) fadeAlpha = m_nHelperTextAlpha;
- // -2 per every 33 ms (1000.f/30.f - original frame limiter fps)
- fadeAlpha -= (frameTime / 33.0f) * 2.0f;
- m_nHelperTextAlpha = fadeAlpha;
-#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 < 16; i++) {
curBarX = i * rectSize/16.0f + x;
@@ -1022,80 +837,91 @@ CMenuManager::DisplaySlider(float x, float y, float mostLeftBarSize, float mostR
void
CMenuManager::DoSettingsBeforeStartingAGame()
{
- CCamera::m_bUseMouse3rdPerson = m_ControlMethod == CONTROL_STANDARD;
+#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)
@@ -1103,8 +929,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);
@@ -1120,699 +951,553 @@ 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));
}
-#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;
- 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];
char asciiTemp[32];
-#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') && strncmp(aScreens[m_nCurrScreen].m_aEntries[i].m_EntryName, "FEDS_TB", 8) == 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();
+
+ leftText = nil;
+ if (Slots[i] == SLOT_OK) {
+ leftText = GetNameOfSavedGame(i);
+ rightText = GetSavedGameDateAndTime(i);
+ }
- if (leftText[0] == '\0') {
- sprintf(gString, "FEM_SL%d", i);
- leftText = TheText.Get(gString);
+ 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 (strncmp(aScreens[m_nCurrScreen].m_aEntries[i].m_EntryName, "FEO_AUD", 8) == 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 LEGACY_MENU_OPTIONS
+ 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:
- sprintf(asciiTemp, "AUTO");
+ switch (m_PrefsUseWideScreen) {
+ case AR_AUTO:
+ sprintf(asciiTemp, "AUTO");
+ break;
+ case AR_4_3:
+ sprintf(asciiTemp, "4:3");
+ break;
+ case AR_16_9:
+ sprintf(asciiTemp, "16:9");
+ break;
+ }
+
+ AsciiToUnicode(asciiTemp, unicodeTemp);
+ rightText = unicodeTemp;
+#endif
+ break;
+
+ case MENUACTION_MUSICVOLUME:
+ case MENUACTION_SFXVOLUME:
+ if (m_nPrefsAudio3DProviderIndex == NO_AUDIO_PROVIDER)
+ rightText = TheText.Get("FEA_NAH");
+
+ break;
+ 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 MENUACTION_LEGENDS:
+ rightText = TheText.Get(m_PrefsShowLegends ? "FEM_ON" : "FEM_OFF");
+ break;
+ 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_4_3:
- sprintf(asciiTemp, "4:3");
+ case MENUACTION_HUD:
+ rightText = TheText.Get(m_PrefsShowHud ? "FEM_ON" : "FEM_OFF");
break;
- case AR_16_9:
- sprintf(asciiTemp, "16:9");
+#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;
- }
-
- AsciiToUnicode(asciiTemp, unicodeTemp);
- rightText = unicodeTemp;
#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) {
+ // To whom manipulate option.m_CFO->value of static options externally (like RestoreDef functions)
+ if (*option.m_CFO->value != option.m_CFOSelect->lastSavedValue)
+ option.m_CFOSelect->displayedValue = option.m_CFOSelect->lastSavedValue = *option.m_CFO->value;
- 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 = *option.m_CFO->value;
+ rightText = TheText.Get(option.m_CFOSelect->rightTexts[option.m_CFOSelect->displayedValue]);
- } else {
- if (option.m_CFOSelect->displayedValue != *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 (*option.m_CFO->value != option.m_CFOSelect->lastSavedValue)
- option.m_CFOSelect->displayedValue = option.m_CFOSelect->lastSavedValue = *option.m_CFO->value;
-
- if (option.m_CFOSelect->displayedValue >= option.m_CFOSelect->numRightTexts || option.m_CFOSelect->displayedValue < 0)
- option.m_CFOSelect->displayedValue = 0;
-
- rightText = TheText.Get(option.m_CFOSelect->rightTexts[option.m_CFOSelect->displayedValue]);
+ // Highlight trapezoid
+ if (activeScreen && i == m_nCurrOption && itemsAreSelectable && section == 0) {
- } 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);
- }
+ int leftXMax, rightXMin;
- if (option.m_CFODynamic->drawFunc) {
- rightText = option.m_CFODynamic->drawFunc(&isOptionDisabled, m_nCurrOption == i);
- }
- }
- break;
-#endif
- }
+ // 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);
- 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') &&
- strncmp(aScreens[m_nCurrScreen].m_aEntries[rowToCheck].m_EntryName, "FEDS_TB", 8) == 0)
- break;
-#endif
+ 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);
- int extraOffset = 0;
- if (aScreens[m_nCurrScreen].m_aEntries[rowToCheck].m_Action == MENUACTION_RADIO)
- extraOffset = MENURADIO_ICON_SCALE;
+ } 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);
- // There were many unused codes in here to calculate how much space will texts gonna take.
+ } else {
+ leftXMax = Max(0, aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_X - curOptionWidth);
+ rightXMin = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_X;
+ }
+ CFont::SetScale(MENU_X(BIGTEXT_X_SCALE), MENU_Y(BIGTEXT_Y_SCALE));
+
+ 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) {
+ rightXMin = 600;
+ leftXMax = 40;
+ }
- // 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;
+ static PauseModeTime lastBlendChange = 0;
+ if (m_nOptionHighlightTransitionBlend <= 255) {
+ static uint32 blendChangeCounter = 0;
+ if (CTimer::GetTimeInMillisecondsPauseMode() - lastBlendChange > 20
+#ifndef FIX_HIGH_FPS_BUGS_ON_FRONTEND // Dirty dirty hack
+ || blendChangeCounter > 20
+#endif
+ ) {
+ m_nOptionHighlightTransitionBlend += 50;
+ lastBlendChange = CTimer::GetTimeInMillisecondsPauseMode();
+ blendChangeCounter = 0;
+ }
+ ++blendChangeCounter;
}
- 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)));
-#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)));
-#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
-#ifdef CUSTOM_FRONTEND_OPTIONS
- || isOptionDisabled
-#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)));
- }
- }
+ 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
- // To make assigning built-in actions to new custom options possible.
+ 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
- && ScreenHasOption(m_nCurrScreen, "FEA_3DH")
+ && ScreenHasOption(m_nCurrScreen, "FEA_3DH")
#else
- && m_nCurrScreen == MENUPAGE_SOUND_SETTINGS
+ && m_nCurrScreen == MENUPAGE_SOUND_SETTINGS
#endif
- && m_nPrefsAudio3DProviderIndex != -1) {
+ && m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER) {
- 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.
+ 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, "FED_RES")
+ && ScreenHasOption(m_nCurrScreen, "FED_RES")) {
#else
- && m_nCurrScreen == MENUPAGE_DISPLAY_SETTINGS
+ && m_nCurrScreen == MENUPAGE_DISPLAY_SETTINGS) {
#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;
- }
+ m_nDisplayVideoMode = m_nPrefsVideoMode;
+ SetHelperText(3);
+ }
+ }
- // Needed after the bug fix in Font.cpp
-#ifdef FIX_BUGS
- if (!CFont::Details.centre)
- CFont::SetRightJustifyOff();
+ // Sliders
+ int lastActiveBarX;
+ switch (aScreens[m_nCurrScreen].m_aEntries[i].m_Action) {
+ case MENUACTION_BRIGHTNESS:
+ ProcessSlider(m_PrefsBrightness / 384.0f, 70.0f, HOVEROPTION_INCREASE_BRIGHTNESS, HOVEROPTION_DECREASE_BRIGHTNESS, SCREEN_WIDTH, true);
+ break;
+ case MENUACTION_DRAWDIST:
+ ProcessSlider((m_PrefsLOD - 0.925f) / 0.875f, 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, 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, 99.0f, HOVEROPTION_INCREASE_SFXVOLUME, HOVEROPTION_DECREASE_SFXVOLUME, SCREEN_WIDTH, true);
+ break;
+ case MENUACTION_MOUSESENS:
+ ProcessSlider(TheCamera.m_fMouseAccelHorzntl * 200.0f, 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, 128.0f, HOVEROPTION_INCREASE_MP3BOOST, HOVEROPTION_DECREASE_MP3BOOST, SCREEN_WIDTH, true);
+ break;
+ }
+
+ // 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)),
@@ -1827,32 +1512,36 @@ 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;
+ 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
@@ -1860,19 +1549,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;
@@ -1900,12 +1591,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) {
@@ -1943,10 +1633,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:
@@ -1961,34 +1651,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:
@@ -2010,11 +1706,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:
@@ -2047,32 +1745,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) {
@@ -2081,58 +1778,38 @@ 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));
for (; contSetOrder < MAX_SETORDERS && controllerAction != -1; contSetOrder++) {
wchar *settingText = ControlsManager.GetControllerSettingTextWithOrderNumber((e_ControllerAction)controllerAction, (eContSetOrder)contSetOrder);
if (settingText) {
++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);
@@ -2145,23 +1822,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
}
@@ -2179,40 +1860,32 @@ CMenuManager::DrawControllerBound(int32 yStart, int32 xStart, int32 unused, int8
CFont::PrintString(nextX, nextY, seperator);
nextX += CFont::GetStringWidth(seperator, true) + bindingMargin;
}
- static uint32 lastWaitingTextFlash = 0;
+ static PauseModeTime lastWaitingTextFlash = 0;
if (CTimer::GetTimeInMillisecondsPauseMode() - lastWaitingTextFlash > 150) {
showWaitingText = !showWaitingText;
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
}
}
@@ -2252,7 +1925,7 @@ CMenuManager::DrawControllerScreenExtraText(int yStart, int xStart, int lineHeig
CFont::PrintString(nextX, MENU_Y(yStart), TheText.Get("FEC_IBT"));
nextX = CFont::GetStringWidth(TheText.Get("FEC_IBT"), true) + spacing + nextX;
}
- static uint32 lastStateChange = 0;
+ static PauseModeTime lastStateChange = 0;
if (CTimer::GetTimeInMillisecondsPauseMode() - lastStateChange > 150) {
waitingTextVisible = !waitingTextVisible;
lastStateChange = CTimer::GetTimeInMillisecondsPauseMode();
@@ -2260,7 +1933,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;
@@ -2290,22 +1963,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");
@@ -2324,32 +2000,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)));
@@ -2363,16 +2041,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) {
@@ -2380,49 +2060,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_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)) {
- 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);
-
- 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)
@@ -2431,616 +2104,313 @@ 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));
+ if (m_nMenuFadeAlpha != 0) {
- 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;
- }
+ if (m_nMenuFadeAlpha < 255) {
- static float fadeAlpha = 0.0f;
+ 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();
- if (m_nMenuFadeAlpha < 255) {
- if (m_nMenuFadeAlpha == 0 && fadeAlpha > 1.0f) fadeAlpha = 0.0f;
-
- // +20 per every 33 ms (1000.f/30.f - original frame limiter fps)
- fadeAlpha += (frameTime) * 20.f / 33.f;
- m_nMenuFadeAlpha = fadeAlpha;
- } else {
- // TODO: what is this? waiting mouse?
- if(field_518 == 4){
- if(m_nHoverOption == HOVEROPTION_3 || m_nHoverOption == HOVEROPTION_4 ||
- m_nHoverOption == HOVEROPTION_5 || m_nHoverOption == HOVEROPTION_6 || m_nHoverOption == HOVEROPTION_7)
-
- field_518 = 2;
- else
- field_518 = 1;
- }
- }
+ // 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));
- 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));
+ // 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));
- 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;
- }
+ // 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));
- // Positions/style from PS2 menu, credits to Fire_Head
- /* Draw controller buttons */
- CFont::SetFontStyle(FONT_BANK);
- CFont::SetBackgroundOff();
- CFont::SetScale(SCREEN_SCALE_X(0.35f), SCREEN_SCALE_Y(0.64f));
- CFont::SetPropOn();
- CFont::SetCentreOff();
- CFont::SetJustifyOn();
- CFont::SetRightJustifyOff();
- CFont::SetBackGroundOnlyTextOn();
- CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENU_X_MARGIN)); // 600.0f
- CFont::SetColor(CRGBA(16, 16, 16, 255));
- switch (m_nCurrScreen) {
-
- // Page names overlaps buttons on those.
- case MENUPAGE_MOUSE_CONTROLS:
- case MENUPAGE_KEYBOARD_CONTROLS:
- break;
-
- default:
- {
- CFont::PrintString(MENU_X_LEFT_ALIGNED(52.0f), MENU_Y(360.0f), TheText.Get("FEDS_SE"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(52.0f), MENU_Y(372.0f), TheText.Get("FEDS_BA"));
- if (!m_bGameNotLoaded)
- CFont::PrintString(MENU_X_LEFT_ALIGNED(52.0f), MENU_Y(384.0f), TheText.Get("FEDS_ST"));
-
- if (bottomBarActive)
- CFont::PrintString(MENU_X_LEFT_ALIGNED(242.0f), MENU_Y(372.0f), TheText.Get("FEDS_AM")); // <>-CHANGE MENU
- else if (m_nCurrScreen != MENUPAGE_STATS && m_nCurrScreen != MENUPAGE_BRIEFS) {
- CFont::PrintString(MENU_X_LEFT_ALIGNED(242.0f), MENU_Y(360.0f + 3.5f), TheText.Get("FEA_UP")); // ;
- CFont::PrintString(MENU_X_LEFT_ALIGNED(242.0f), MENU_Y(384.0f - 3.5f), TheText.Get("FEA_DO")); // =
- CFont::PrintString(MENU_X_LEFT_ALIGNED(242.0f - 10.0f), MENU_Y(372.0f), TheText.Get("FEA_LE")); // <
- CFont::PrintString(MENU_X_LEFT_ALIGNED(242.0f + 11.0f), MENU_Y(372.0f), TheText.Get("FEA_RI")); // >
- CFont::PrintString(MENU_X_LEFT_ALIGNED(242.0f + 20.0f), MENU_Y(372.0f), TheText.Get("FEDSAS3")); // - CHANGE SELECTION
- }
-
- break;
- }
- }
-
- #define optionWidth MENU_X(66.0f)
- #define rawOptionHeight 22.0f
- #define optionBottom SCREEN_SCALE_FROM_BOTTOM(20.0f)
- #define optionTop SCREEN_SCALE_FROM_BOTTOM(20.0f + rawOptionHeight)
- #define leftPadding MENU_X_LEFT_ALIGNED(90.0f)
- wchar *str;
- hoveredBottomBarOption = -1;
- if (curBottomBarOption != -1) {
-
- // 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
- static float fadeAlpha = 0.0f;
- if (m_nMenuFadeAlpha == 0 && fadeAlpha > 1.0f) fadeAlpha = 0.0f;
-
- // +20 per every 33 ms (1000.f/30.f - original frame limiter fps)
- fadeAlpha += (frameTime) * 20.f / 33.f;
- m_nMenuFadeAlpha = fadeAlpha;
-#else
- static uint32 LastFade = 0;
+ static PauseModeTime LastFade = 0;
- if(CTimer::GetTimeInMillisecondsPauseMode() - LastFade > 10){
+ if (m_nMenuFadeAlpha < 255) {
+ static uint8 forceFadeInCounter = 0;
+ if (CTimer::GetTimeInMillisecondsPauseMode() - LastFade > 30
+#ifndef FIX_HIGH_FPS_BUGS_ON_FRONTEND // Dirty dirty hack
+ || forceFadeInCounter > 30
+#endif
+ ) {
m_nMenuFadeAlpha += 20;
+ if (m_firstStartCounter < 255) {
+ m_firstStartCounter = Min(m_firstStartCounter + 20, 255);
+ }
LastFade = CTimer::GetTimeInMillisecondsPauseMode();
}
-#endif
-
- if (m_nMenuFadeAlpha > 255){
- m_aMenuSprites[currentSprite].Draw(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), CRGBA(255, 255, 255, 255));
- } 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;
+ forceFadeInCounter++;
+ } else if (m_nMenuFadeAlpha > 255)
+ m_nMenuFadeAlpha = 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;
}
}
-#ifdef RED_DELETE_BACKGROUND
- if (m_nCurrScreen == MENUPAGE_CHOOSE_DELETE_SLOT || m_nCurrScreen == MENUPAGE_DELETE_SLOT_CONFIRM) {
- CSprite2d::Draw2DPolygon(SCREEN_STRETCH_X(18.0f), MENU_Y(8.0f),
- SCREEN_WIDTH - SCREEN_STRETCH_X(20.0f), MENU_Y(8.0f),
- SCREEN_STRETCH_X(12.0f), MENU_Y(11.0f),
- SCREEN_WIDTH - SCREEN_STRETCH_X(14.0f), MENU_Y(11.0f),
- CRGBA(150, 0, 0, 140));
-
- CSprite2d::Draw2DPolygon(SCREEN_STRETCH_X(12.0f), MENU_Y(11.0f),
- SCREEN_WIDTH - SCREEN_STRETCH_X(14.0f), MENU_Y(11.0f),
- SCREEN_STRETCH_X(10.0f), MENU_Y(16.0f),
- SCREEN_WIDTH - SCREEN_STRETCH_X(12.0f), MENU_Y(16.0f),
- CRGBA(150, 0, 0, 140));
-
- CSprite2d::Draw2DPolygon(SCREEN_STRETCH_X(10.0f), MENU_Y(16.0f),
- SCREEN_WIDTH - SCREEN_STRETCH_X(12.0f), MENU_Y(16.0f),
- SCREEN_STRETCH_X(10.0f), SCREEN_SCALE_Y(431.0f),
- SCREEN_WIDTH - SCREEN_STRETCH_X(12.0f), SCREEN_SCALE_Y(431.0f),
- CRGBA(150, 0, 0, 140));
-
- CSprite2d::Draw2DPolygon(SCREEN_STRETCH_X(10.0f), SCREEN_SCALE_Y(431.0f),
- SCREEN_WIDTH - SCREEN_STRETCH_X(12.0f), SCREEN_SCALE_Y(431.0f),
- SCREEN_STRETCH_X(12.0f), SCREEN_SCALE_Y(435.0f),
- SCREEN_WIDTH - SCREEN_STRETCH_X(14.0f), SCREEN_SCALE_Y(435.0f),
- CRGBA(150, 0, 0, 140));
-
- CSprite2d::Draw2DPolygon(SCREEN_STRETCH_X(12.0f), SCREEN_SCALE_Y(435.0f),
- SCREEN_WIDTH - SCREEN_STRETCH_X(14.0f), SCREEN_SCALE_Y(435.0f),
- SCREEN_STRETCH_X(18.0f), SCREEN_SCALE_Y(438.0f),
- SCREEN_WIDTH - SCREEN_STRETCH_X(20.0f), SCREEN_SCALE_Y(438.0f),
- CRGBA(150, 0, 0, 140));
-
- // yellow bar
- CSprite2d::DrawRect(CRect(MENU_X(13.0f), SCREEN_STRETCH_FROM_BOTTOM(96.0f),
- SCREEN_STRETCH_FROM_RIGHT(11.0f), SCREEN_STRETCH_FROM_BOTTOM(59.0f)),
- CRGBA(235, 170, 50, 255));
- }
-#endif
-
- // GTA LOGO
- RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
- RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
- if (m_nCurrScreen == MENUPAGE_START_MENU || m_nCurrScreen == MENUPAGE_PAUSE_MENU) {
- if (CGame::frenchGame || CGame::germanGame || !CGame::nastyGame)
- m_aMenuSprites[MENUSPRITE_GTA3LOGO].Draw(CRect(MENU_X_LEFT_ALIGNED(205.0f), MENU_Y(70.0f), MENU_X_LEFT_ALIGNED(435.0f), MENU_Y(180.0f)), CRGBA(255, 255, 255, FadeIn(255)));
- else
- m_aMenuSprites[MENUSPRITE_GTALOGO].Draw(CRect(MENU_X_LEFT_ALIGNED(225.0f), MENU_Y(40.0f), MENU_X_LEFT_ALIGNED(415.0f), MENU_Y(210.0f)), CRGBA(255, 255, 255, FadeIn(255)));
- }
-
- RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERNEAREST);
- RwRenderStateSet(rwRENDERSTATETEXTUREADDRESS, (void*)rwTEXTUREADDRESSCLAMP);
- RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
switch (m_nCurrScreen) {
case MENUPAGE_SKIN_SELECT:
- DrawPlayerSetupScreen();
+ DrawPlayerSetupScreen(true);
break;
case MENUPAGE_KEYBOARD_CONTROLS:
DrawControllerSetupScreen();
break;
+ case MENUPAGE_OUTRO:
+ DrawQuitGameScreen();
+ break;
default:
- Draw();
+ DrawStandardMenus(true);
break;
}
CFont::DrawFonts();
+ SetFrontEndRenderStates();
- // Draw mouse
- RwRenderStateSet(rwRENDERSTATETEXTUREFILTER, (void*)rwFILTERLINEAR);
- RwRenderStateSet(rwRENDERSTATETEXTUREADDRESS, (void*)rwTEXTUREADDRESSCLAMP);
- if (m_bShowMouse) {
- RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
- RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
- RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
+ if (m_nCurrScreen != MENUPAGE_OUTRO)
+ if (m_firstStartCounter == 255) {
+ m_aFrontEndSprites[MENUSPRITE_VCLOGO].Draw(CRect(SCREEN_STRETCH_X(27.0f), MENU_Y(8.0f), SCREEN_STRETCH_X(27.0f) + MENU_X(130.f), MENU_Y(138.0f)), CRGBA(255, 255, 255, 255));
+ } else {
+ m_aFrontEndSprites[MENUSPRITE_VCLOGO].Draw(CRect(SCREEN_STRETCH_X(27.0f), MENU_Y(8.0f), SCREEN_STRETCH_X(27.0f) + MENU_X(130.f), MENU_Y(138.0f)), CRGBA(255, 255, 255, FadeIn(255)));
+ }
+
+ if (m_ShowEmptyBindingError) {
+ static PauseModeTime lastBindingError = CTimer::GetTimeInMillisecondsPauseMode();
+ static bool bindingErrorShown = false;
+ if (bindingErrorShown) {
+ lastBindingError = CTimer::GetTimeInMillisecondsPauseMode();
+ bindingErrorShown = false;
+ }
+ SmallMessageScreen("FEC_ERI");
+ CFont::DrawFonts();
+ if (CTimer::GetTimeInMillisecondsPauseMode() - lastBindingError > 4000) {
+ m_ShowEmptyBindingError = false;
+ bindingErrorShown = true;
+ }
+ }
- CRect mouse(0.0f, 0.0f, MENU_X(75.0f), MENU_Y(75.0f));
- CRect shad(MENU_X(10.0f), MENU_Y(3.0f), MENU_X(85.0f), MENU_Y(78.0f));
+ if (m_bShowMouse) {
+ CRect mouse(0.0f, 0.0f, MENU_X(35.0f), MENU_Y(35.0f));
+ CRect shad(MENU_X(10.0f), MENU_Y(3.0f), MENU_X(45.0f), MENU_Y(38.0f));
mouse.Translate(m_nMousePosX, m_nMousePosY);
shad.Translate(m_nMousePosX, m_nMousePosY);
- if(field_518 == 4){
- m_aMenuSprites[MENUSPRITE_MOUSET].Draw(shad, CRGBA(100, 100, 100, 50));
- RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
- m_aMenuSprites[MENUSPRITE_MOUSET].Draw(mouse, CRGBA(255, 255, 255, 255));
- }else{
- m_aMenuSprites[MENUSPRITE_MOUSE].Draw(shad, CRGBA(100, 100, 100, 50));
- RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
- m_aMenuSprites[MENUSPRITE_MOUSE].Draw(mouse, CRGBA(255, 255, 255, 255));
- }
+ m_aFrontEndSprites[MENUSPRITE_MOUSE].Draw(shad, CRGBA(100, 100, 100, 50));
+ m_aFrontEndSprites[MENUSPRITE_MOUSE].Draw(mouse, CRGBA(255, 255, 255, 255));
}
}
-#endif
void
-CMenuManager::DrawPlayerSetupScreen()
+CMenuManager::DrawPlayerSetupScreen(bool activeScreen)
{
RESET_FONT_FOR_NEW_PAGE
- SET_FONT_FOR_MENU_HEADER
-
- CFont::PrintString(PAGE_NAME_X(MENUHEADER_POS_X), SCREEN_SCALE_FROM_BOTTOM(MENUHEADER_POS_Y), TheText.Get("FET_PS"));
-
// lstrcpy's changed with strcpy
-
if (!m_bSkinsEnumerated) {
OutputDebugString("Enumerating skin filenames from skins...");
m_pSkinListHead.nextSkin = nil;
@@ -3123,8 +2493,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) {
@@ -3132,7 +2508,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"));
@@ -3147,6 +2524,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
@@ -3171,13 +2549,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;
@@ -3220,7 +2596,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)));
@@ -3257,21 +2633,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
@@ -3279,27 +2655,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) {
@@ -3319,35 +2696,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)
@@ -3402,86 +2773,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;
@@ -3539,6 +2870,7 @@ CMenuManager::InitialiseChangedLanguageSettings()
default:
break;
}
+
}
}
@@ -3548,97 +2880,85 @@ CMenuManager::LoadAllTextures()
if (m_bSpritesLoaded)
return;
- CentreMousePointer();
- DMAudio.ChangeMusicMode(MUSICMODE_FRONTEND);
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_STARTING, 0);
- m_nCurrOption = 0;
- m_PrefsRadioStation = DMAudio.GetRadioInCar();
-
- if (DMAudio.IsMP3RadioChannelAvailable()) {
- if (m_PrefsRadioStation > USERTRACK)
- m_PrefsRadioStation = CGeneral::GetRandomNumber() % 10;
- } else if (m_PrefsRadioStation > CHATTERBOX)
- m_PrefsRadioStation = CGeneral::GetRandomNumber() % 9;
-
- CFileMgr::SetDir("");
- //CFileMgr::SetDir("");
+ // 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);
}
- int menuTxdSlot = CTxdStore::FindTxdSlot("menu");
+ CTxdStore::PopCurrentTxd();
+ CStreaming::IHaveUsedStreamingMemory();
- if (menuTxdSlot == -1)
- menuTxdSlot = CTxdStore::AddTxdSlot("menu");
+ if (!m_OnlySaveMenu) {
+ CStreaming::MakeSpaceFor(692 * CDSTREAM_SECTOR_SIZE); // twice of it in mobile
+ CStreaming::ImGonnaUseStreamingMemory();
+ CTxdStore::PushCurrentTxd();
- printf("LOAD sprite\n");
- CTxdStore::LoadTxd(menuTxdSlot, "MODELS/MENU.TXD");
- CTxdStore::AddRef(menuTxdSlot);
- CTxdStore::SetCurrentTxd(menuTxdSlot);
+ int frontendTxdSlot2 = CTxdStore::FindTxdSlot("frontend2");
- for (int i = 0; i < ARRAY_SIZE(MenuFilenames); i++) {
- m_aMenuSprites[i].SetTexture(MenuFilenames[i][0], MenuFilenames[i][1]);
- m_aMenuSprites[i].SetAddressing(rwTEXTUREADDRESSBORDER);
- }
-#ifdef MENU_MAP
- for (int i = 0; i < ARRAY_SIZE(MapFilenames); i++) {
- m_aMapSprites[i].SetTexture(MapFilenames[i][0], MapFilenames[i][1]);
- m_aMapSprites[i].SetAddressing(rwTEXTUREADDRESSBORDER);
+ if (frontendTxdSlot2 == -1)
+ frontendTxdSlot2 = CTxdStore::AddTxdSlot("frontend2");
+
+ printf("LOAD frontend2\n");
+ CTxdStore::LoadTxd(frontendTxdSlot2, "MODELS/FRONTEN2.TXD");
+ CTxdStore::AddRef(frontendTxdSlot2);
+ CTxdStore::SetCurrentTxd(frontendTxdSlot2);
+
+ for (int i = 3; i < NUM_MENU_SPRITES; i++) {
+ m_aFrontEndSprites[i].SetTexture(FrontendFilenames[i][0], FrontendFilenames[i][1]);
+ m_aFrontEndSprites[i].SetAddressing(rwTEXTUREADDRESSBORDER);
+ }
+
+ CTxdStore::PopCurrentTxd();
+ CStreaming::IHaveUsedStreamingMemory();
}
- 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();
+ CTimer::Update();
}
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));
@@ -3663,51 +2983,59 @@ 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);
}
}
CFileMgr::CloseFile(fileHandle);
CFileMgr::SetDir("");
+ CCamera::m_bUseMouse3rdPerson = m_ControlMethod == CONTROL_STANDARD;
+#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();
@@ -3740,11 +3068,13 @@ void
CMenuManager::SaveSettings()
{
static char RubbishString[48] = "stuffmorestuffevenmorestuff etc";
+ static int SomeVersion = 3;
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));
@@ -3759,45 +3089,49 @@ 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("");
-
+
#ifdef LOAD_INI_SETTINGS
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))
@@ -3807,54 +3141,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,
@@ -3863,358 +3201,977 @@ CMenuManager::PrintBriefs()
brief.m_nNumber[4], brief.m_nNumber[5], gUString);
CMessages::InsertStringInString(gUString, brief.m_pString);
CMessages::InsertPlayerControlKeysInString(gUString);
- newColor = TEXT_COLOR;
- FilterOutColorMarkersFromString(gUString, newColor);
- if (newColor != TEXT_COLOR) {
- newColor.r /= 2;
- newColor.g /= 2;
- newColor.b /= 2;
- }
+ CFont::FilterOutTokensFromString(gUString);
-#ifdef PS2_LIKE_MENU
- CFont::SetDropColor(CRGBA(0, 0, 0, FadeIn(255)));
- CFont::SetDropShadowPosition(1);
-#endif
-
-#if defined(FIX_BUGS) || defined(PS2_LIKE_MENU)
- newColor.a = FadeIn(255);
- CFont::SetColor(newColor);
-#endif
- CFont::PrintString(MENU_X_LEFT_ALIGNED(BRIEFS_LINE_X), nextY, gUString);
- nextY += MENU_Y(BRIEFS_LINE_HEIGHT);
+ nextY -= CFont::GetNumberLines(MENU_X_LEFT_ALIGNED(BRIEFS_LINE_X), nextY, gUString) * BRIEFS_LINE_HEIGHT + BRIEFS_LINE_SPACING;
+ CFont::PrintString(MENU_X_LEFT_ALIGNED(BRIEFS_LINE_X), MENU_Y(nextY), gUString);
}
}
-
-#ifdef PS2_LIKE_MENU
- CFont::SetDropShadowPosition(0);
-#endif
}
-// Not sure about name. Not to be confused with CPad::PrintErrorMessage
void
-CMenuManager::PrintErrorMessage()
+CMenuManager::PrintStats()
{
- if (!CPad::bDisplayNoControllerMessage && !CPad::bObsoleteControllerMessage)
- return;
+ static uint8 pirateCheck = 0;
+ 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));
-#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;
+ if (pirateCheck == 0)
+ // if not pirated game
+ pirateCheck = 46;
+ // else
+ // pirateCheck = 45;
- // 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 PauseModeTime 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;
-#endif
+ if (pirateCheck == 45)
+ return;
+
+ 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;
+ }
- CFont::SetColor(CRGBA(LABEL_COLOR.r, LABEL_COLOR.g, LABEL_COLOR.b, FadeIn(255.0f * alphaMult)));
+ // 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(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 PauseModeTime 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
- TheCamera.m_bUseMouse3rdPerson = m_ControlMethod == CONTROL_STANDARD;
- if (m_PrefsVsyncDisp != m_PrefsVsync)
- m_PrefsVsync = m_PrefsVsyncDisp;
- DMAudio.Service();
- m_bWantToRestart = true;
- RequestFrontEndShutDown();
- m_bWantToLoad = true;
- b_FoundRecentSavedGameWantToLoad = true;
- DMAudio.SetEffectsFadeVol(0);
- DMAudio.SetMusicFadeVol(0);
- DMAudio.ResetTimers(CTimer::GetTimeInMilliseconds());
- } else
- SaveLoadFileError_SetUpErrorScreen();
- }
- ProcessButtonPresses();
+ 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
+ CentreMousePointer();
+ }
+ }
+ if (!CPad::GetPad(0)->GetLeftMouse() && !m_bShowMouse && (m_nMouseOldPosX != m_nMousePosX || m_nMouseOldPosY != m_nMousePosY)) {
+ m_bShowMouse = true;
+ }
+
+ 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 = 1;
- else if (CPad::GetPad(0)->GetRightMouseJustUp())
- MouseButtonJustClicked = 3;
- else if (CPad::GetPad(0)->GetMiddleMouseJustUp())
- MouseButtonJustClicked = 2;
- else if (CPad::GetPad(0)->GetMouseWheelUpJustUp())
- MouseButtonJustClicked = 4;
- else if (CPad::GetPad(0)->GetMouseWheelDownJustUp())
- MouseButtonJustClicked = 5;
- else if (CPad::GetPad(0)->GetMouseX1JustUp())
- MouseButtonJustClicked = 6;
- else if (CPad::GetPad(0)->GetMouseX2JustUp())
- MouseButtonJustClicked = 7;
-
- 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] = 0xBA; // 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");
+
+ char *statValue = UnicodeToAscii(gUString2);
+ for (int l = 0; statValue[l] != '\0'; ++l) {
+ if (statValue[l] == '_')
+ statValue[l] = 0xBA; // 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 PauseModeTime 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)));
- // Reset pad shaking.
- if (TimeToStopPadShaking && TimeToStopPadShaking < CTimer::GetTimeInMillisecondsPauseMode()) {
- CPad::StopPadsShaking();
- TimeToStopPadShaking = 0;
+ int rightMostSprite, rightMostStation;
+ if (DMAudio.IsMP3RadioChannelAvailable()) {
+ rightMostSprite = MENUSPRITE_MP3;
+ rightMostStation = USERTRACK;
+ } else {
+ 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 {
- UnloadTextures();
- m_bRenderGameInMenu = false;
- // byte_5F33E4 = 1; // unused
- ChangeScreen(MENUPAGE_NONE, 0, false, false);
- pEditString = nil;
- m_bWaitingForNewKeyBind = false;
+ 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)));
+ }
}
- if (!m_bWantToRestart) {
- if (m_bGameNotLoaded)
- DMAudio.Service();
+ // 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)));
+ }
+
+ // 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 PauseModeTime 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, 1);
+ 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 PauseModeTime 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) {
-#ifdef RW_GL3
- if (glfwGetKey(PSGLOBAL(window), GLFW_KEY_R) == GLFW_PRESS) {
- scriptToLoad = 1;
- DoSettingsBeforeStartingAGame();
- return;
- }
- if (glfwGetKey(PSGLOBAL(window), GLFW_KEY_D) == GLFW_PRESS) {
- scriptToLoad = 2;
- DoSettingsBeforeStartingAGame();
- return;
- }
-#elif defined _WIN32
- if (GetAsyncKeyState('R') & 0x8000) {
- 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)
+ m_nHoverOption = HOVEROPTION_RANDOM_ITEM;
+
+ break;
}
- if (GetAsyncKeyState('D') & 0x8000) {
- scriptToLoad = 2;
- DoSettingsBeforeStartingAGame();
- return;
+ if (m_bShowMouse && m_nMenuFadeAlpha == 255) {
+ m_nOptionMouseHovering = oldOption;
+ m_nCurrOption = oldOption;
}
-#endif
}
-#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;
@@ -4227,33 +4184,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;
@@ -4265,231 +4214,37 @@ 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, 1);
- 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, 1);
- 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, 1);
- 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, 1);
- 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, 1);
- 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, 1);
- 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, 1);
- 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, 1);
- 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, 1);
- 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, 1);
- 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, 1);
- 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 + 32;
- if (m_PrefsBrightness < 0) {
- m_PrefsBrightness = 0;
- }
- if (510 < m_PrefsBrightness) {
- m_PrefsBrightness = 511;
- }
- SaveSettings();
- break;
- case HOVEROPTION_DECREASE_BRIGHTNESS:
- m_PrefsBrightness = m_PrefsBrightness - 32;
- 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 / 16);
- m_PrefsLOD = min(1.8f, m_PrefsLOD);
- CRenderer::ms_lodDistScale = m_PrefsLOD;
- SaveSettings();
- break;
- case HOVEROPTION_DECREASE_DRAWDIST:
- m_PrefsLOD = m_PrefsLOD - (1.0f / 16);
- m_PrefsLOD = max(0.8f, m_PrefsLOD);
- CRenderer::ms_lodDistScale = m_PrefsLOD;
- SaveSettings();
- break;
case HOVEROPTION_INCREASE_MUSICVOLUME:
- m_PrefsMusicVolume = m_PrefsMusicVolume + 8;
- m_PrefsMusicVolume = clamp(m_PrefsMusicVolume, 0, 127);
- DMAudio.SetMusicMasterVolume(uchar)(m_PrefsMusicVolume);
- SaveSettings();
- break;
- case HOVEROPTION_DECREASE_MUSICVOLUME:
- m_PrefsMusicVolume = m_PrefsMusicVolume - 8;
- 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 + 8;
- 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 - 8;
- 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 / 3000);
- TheCamera.m_fMouseAccelHorzntl = clamp(TheCamera.m_fMouseAccelHorzntl, 1.0f / 3200, 1.0f / 200);
- TheCamera.m_fMouseAccelVertical = TheCamera.m_fMouseAccelHorzntl;
- 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 / 3000);
- TheCamera.m_fMouseAccelHorzntl = clamp(TheCamera.m_fMouseAccelHorzntl, 1.0f / 3200, 1.0f / 200);
- TheCamera.m_fMouseAccelVertical = TheCamera.m_fMouseAccelHorzntl;
- SaveSettings();
+ CheckSliderMovement(-1);
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:
- CheckSliderMovement(1);
- break;
- case HOVEROPTION_DECREASE_BRIGHTNESS:
- case HOVEROPTION_DECREASE_DRAWDIST:
- case HOVEROPTION_DECREASE_MUSICVOLUME:
- case HOVEROPTION_DECREASE_SFXVOLUME:
- case HOVEROPTION_DECREASE_MOUSESENS:
- CheckSliderMovement(-1);
- break;
- }
-#endif
}
-
+
#ifdef SCROLLABLE_PAGES
if (m_nTotalListRow > MAX_VISIBLE_OPTION) {
bool temp = false;
@@ -4503,36 +4258,32 @@ 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)
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_MENU_SETTING_CHANGE, 0);
+ if (option == MENUACTION_BRIGHTNESS)
+ 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;
}
@@ -4541,92 +4292,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 PauseModeTime 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)
+ 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 PauseModeTime 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)
+ 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 = *oldEntry.m_CFO->value;
}
+ } else if (oldEntry.m_Action == MENUACTION_CFO_SELECT && oldEntry.m_CFOSelect->onlyApplyOnEnter) {
+ if (oldEntry.m_CFOSelect->displayedValue != *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, 1);
+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, 1);
+ if (m_bWaitingForNewKeyBind) {
+ if (m_bStartWaitingForKeyBind)
+ m_bStartWaitingForKeyBind = false;
+ else {
+ pControlEdit = CPad::EditCodesForControls(pControlEdit, 1);
+ JoyButtonJustClicked = false;
+ MouseButtonJustClicked = false;
+
+ if (CPad::GetPad(0)->GetLeftMouseJustDown())
+ MouseButtonJustClicked = 1;
+ else if (CPad::GetPad(0)->GetRightMouseJustUp())
+ MouseButtonJustClicked = 3;
+ else if (CPad::GetPad(0)->GetMiddleMouseJustUp())
+ MouseButtonJustClicked = 2;
+ else if (CPad::GetPad(0)->GetMouseWheelUpJustUp())
+ MouseButtonJustClicked = 4;
+ else if (CPad::GetPad(0)->GetMouseWheelDownJustUp())
+ MouseButtonJustClicked = 5;
+ else if (CPad::GetPad(0)->GetMouseX1JustUp())
+ MouseButtonJustClicked = 6;
+ else if (CPad::GetPad(0)->GetMouseX2JustUp())
+ MouseButtonJustClicked = 7;
+
+ 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) {
+#ifdef RW_GL3
+ if (glfwGetKey(PSGLOBAL(window), GLFW_KEY_R) == GLFW_PRESS) {
+ scriptToLoad = 1;
+ DoSettingsBeforeStartingAGame();
return;
}
- optionSelected = false;
- goDown = false;
- goUp = false;
+#elif defined _WIN32
+ if (GetAsyncKeyState('R') & 0x8000) {
+ scriptToLoad = 1;
+ DoSettingsBeforeStartingAGame();
+ return;
+ }
+#endif
}
#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) {
@@ -4635,585 +4487,355 @@ 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 && strncmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FEDS_TB", 8) == 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 (strncmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FEDS_TB", 8) != 0 &&
- strncmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FESZ_CA", 8) != 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) {
-
- 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, 1);
- 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;
+ 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 >= 2 && saveSlot <= 9) {
+ m_nCurrSaveSlot = saveSlot - 2;
+ 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 (strncmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FEDS_TB", 8) == 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, 1);
+ OutputDebugString("STARTED PLAYING FRONTEND AUDIO TRACK");
}
- case MENUACTION_CHECKSAVE:
- {
- 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;
+ break;
+ case MENUACTION_SAVEGAME:
+ {
+ int saveSlot = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_SaveSlot;
+
+ 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, 1);
- 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;
- m_PrefsUseWideScreen = false;
- 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);
- }
-#else
- CMBlur::BlurOn = true;
-#endif
+ 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, 1);
+ 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;
+ m_PrefsUseWideScreen = false;
+ 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);
- }
-#else
- if (PSGLOBAL(joy1id) != -1 && glfwJoystickPresent(PSGLOBAL(joy1id))) {
- int count;
- glfwGetJoystickButtons(PSGLOBAL(joy1id), &count);
- ControlsManager.InitDefaultControlConfigJoyPad(count);
- }
-#endif
- m_ControlMethod = CONTROL_STANDARD;
- MousePointerStateHelper.bInvertVertically = false;
- TheCamera.m_fMouseAccelHorzntl = 0.0025f;
- CVehicle::m_bDisableMouseSteering = true;
- TheCamera.m_bHeadBob = false;
- SaveSettings();
- }
- 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;
+ if (AllValidWinJoys.m_aJoys[JOYSTICK1].m_bInitialised) {
+ DIDEVCAPS devCaps;
+ devCaps.dwSize = sizeof(DIDEVCAPS);
+ PSGLOBAL(joy1)->GetCapabilities(&devCaps);
+ ControlsManager.InitDefaultControlConfigJoyPad(devCaps.dwButtons);
}
- SaveSettings();
#else
- assumeIncrease = true;
-#endif
- break;
- case MENUACTION_LOADRADIO:
- ChangeScreen(MENUPAGE_SOUND_SETTINGS, 0, true, true);
- DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, 1);
- 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;
+ if (PSGLOBAL(joy1id) != -1 && glfwJoystickPresent(PSGLOBAL(joy1id))) {
+ int count;
+ glfwGetJoystickButtons(PSGLOBAL(joy1id), &count);
+ ControlsManager.InitDefaultControlConfigJoyPad(count);
+ }
#endif
+ MousePointerStateHelper.bInvertVertically = true;
+ TheCamera.m_bHeadBob = false;
+ TheCamera.m_fMouseAccelHorzntl = 0.0025f;
+ CVehicle::m_bDisableMouseSteering = true;
+ m_ControlMethod = CONTROL_STANDARD;
+ TheCamera.m_bUseMouse3rdPerson = true;
+ SaveSettings();
+ }
+ 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->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 = *option.m_CFO->value;
-
- *option.m_CFO->value = option.m_CFOSelect->lastSavedValue = option.m_CFOSelect->displayedValue;
-
- if (option.m_CFOSelect->save)
- SaveSettings();
+ 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->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 = *option.m_CFO->value;
- if (option.m_CFOSelect->displayedValue != oldValue && option.m_CFOSelect->changeFunc)
- option.m_CFOSelect->changeFunc(oldValue, option.m_CFOSelect->displayedValue);
+ *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);
- }
+ 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);
- }
+ ProcessOnOffMenuOptions();
+ if (!goBack) {
+ int saveSlot = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_SaveSlot;
- // We will go back for sure at this point, why process other things?!
-#ifdef FIX_BUGS
- return;
-#endif
+ if (saveSlot >= 2 && saveSlot <= 9 && Slots[m_nCurrOption] != SLOT_OK)
+ DMAudio.PlayFrontEndSound(SOUND_FRONTEND_FAIL, 0);
+ else
+ DMAudio.PlayFrontEndSound(SOUND_FRONTEND_ENTER_OR_ADJUST, 0);
}
}
-#ifdef PS2_LIKE_MENU
- if (bottomBarActive)
- return;
-#endif
-
- int changeValueBy = 0;
- bool decrease = false;
-#ifdef TIDY_UP_PBP
- bool increase = assumeIncrease;
-#else
- bool increase = false;
-#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();
+ 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 (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 (increase)
- changeValueBy++;
- else if (decrease)
- changeValueBy--;
-
- if (changeValueBy != 0) {
+ if (changeAmount != 0) {
switch (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action) {
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, 1);
- 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 > 2)
m_PrefsUseWideScreen = 0;
@@ -5222,15 +4844,13 @@ CMenuManager::ProcessButtonPresses(void)
if (m_PrefsUseWideScreen < 0)
m_PrefsUseWideScreen = 2;
}
- 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;
@@ -5248,25 +4868,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
@@ -5274,7 +4918,7 @@ CMenuManager::ProcessButtonPresses(void)
case MENUACTION_CFO_DYNAMIC:
CMenuScreenCustom::CMenuEntry &option = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption];
if (option.m_Action == MENUACTION_CFO_SELECT) {
- if (changeValueBy > 0) {
+ if (changeAmount > 0) {
option.m_CFOSelect->displayedValue++;
if (option.m_CFOSelect->displayedValue >= option.m_CFOSelect->numRightTexts)
option.m_CFOSelect->displayedValue = 0;
@@ -5295,21 +4939,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);
}
}
}
@@ -5318,101 +4960,81 @@ void
CMenuManager::ProcessOnOffMenuOptions()
{
switch (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action) {
+#ifdef LEGACY_MENU_OPTIONS
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);
break;
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);
+ break;
+#endif
+ case MENUACTION_INVERTPADY:
+ CPad::bInvertLook4Pad = !CPad::bInvertLook4Pad;
+ SaveSettings(); // FIX: Why don't SaveSettings? Because of it's an hidden option? :(
break;
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;
}
}
@@ -5421,7 +5043,6 @@ void
CMenuManager::RequestFrontEndShutDown()
{
m_bShutDownFrontEndRequested = true;
- DMAudio.ChangeMusicMode(MUSICMODE_GAME);
}
void
@@ -5438,49 +5059,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)
{
@@ -5500,86 +5084,344 @@ float CMenuManager::StretchY(float y)
return SCREEN_STRETCH_Y(y);
}
+#ifdef XBOX_MESSAGE_SCREEN
void
-CMenuManager::SwitchMenuOnAndOff()
+CMenuManager::CloseDialog(void)
{
- bool menuWasActive = GetIsMenuActive();
+ // 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);
+ }
- // Reminder: You need REGISTER_START_BUTTON defined to make it work.
- if (CPad::GetPad(0)->GetStartJustDown()
-#ifdef FIX_BUGS
- && !m_bGameNotLoaded
+}
+
+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
- || m_bShutDownFrontEndRequested || m_bStartUpFrontEndRequested) {
- m_bMenuActive = !m_bMenuActive;
+void
+CMenuManager::ProcessFileActions()
+{
+ switch (m_nCurrScreen) {
+ case MENUPAGE_LOADING_IN_PROGRESS:
+ if (CheckSlotDataValid(m_nCurrSaveSlot)) {
+#ifdef USE_DEBUG_SCRIPT_LOADER
+ scriptToLoad = 0;
+#endif
- if (m_bShutDownFrontEndRequested)
- m_bMenuActive = false;
- if (m_bStartUpFrontEndRequested)
- m_bMenuActive = true;
+#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);
- if (m_bMenuActive) {
- CTimer::StartUserPause();
- } else {
-#ifdef PS2_LIKE_MENU
- bottomBarActive = false;
+ 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")) {
+ PauseModeTime 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
-#ifdef FIX_BUGS
- ThingsToDoBeforeGoingBack();
+
+ 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
- ShutdownJustMenu();
- SaveSettings();
- m_bStartUpFrontEndRequested = false;
- pControlEdit = nil;
- m_bShutDownFrontEndRequested = false;
- DisplayComboButtonErrMsg = false;
+ break;
+ }
+ }
+}
+
+void
+CMenuManager::SwitchMenuOnAndOff()
+{
+ if (!TheCamera.m_WideScreenOn) {
+ // 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
- 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;
+ || CPad::GetPad(0)->GetStartJustDown() && !m_bGameNotLoaded
#endif
- CPad::GetPad(0)->Clear(false);
- CPad::GetPad(1)->Clear(false);
+ ) {
+
+ 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;
+ else if (m_bStartUpFrontEndRequested)
+ m_bMenuActive = true;
+ else
+ m_bMenuActive = !m_bMenuActive;
+
+ if (m_bMenuActive) {
+ if (_InputMouseNeedsExclusive()) {
+ _InputShutdownMouse();
+ _InputInitialiseMouse(false);
+ }
+ Initialise();
+ LoadAllTextures();
+ } else {
+ if (CMBlur::BlurOn)
+ CMBlur::MotionBlurOpen(Scene.camera);
+ else
+ CMBlur::MotionBlurClose();
+ DoRWStuffStartOfFrame(0, 0, 0, 0, 0, 0, 255);
+ DoRWStuffEndOfFrame();
+ DoRWStuffStartOfFrame(0, 0, 0, 0, 0, 0, 255);
+ DoRWStuffEndOfFrame();
+ if (_InputMouseNeedsExclusive()) {
+ _InputShutdownMouse();
+ _InputInitialiseMouse(true);
+ }
+
+ m_StatsScrollSpeed = 150.0f;
+#ifdef FIX_BUGS
+ ThingsToDoBeforeLeavingPage();
+#endif
+ SaveSettings();
+ pControlEdit = nil;
+ pEditString = nil;
+ DisplayComboButtonErrMsg = false;
+ m_bShutDownFrontEndRequested = false;
+ m_bStartUpFrontEndRequested = false;
+ m_bWaitingForNewKeyBind = 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;
+ 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
- m_nCurrScreen = MENUPAGE_NONE;
+ 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
+ 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;
@@ -5589,27 +5431,31 @@ CMenuManager::SwitchMenuOnAndOff()
void
CMenuManager::UnloadTextures()
{
- if (!m_bSpritesLoaded)
- return;
+ if (m_nCurrScreen == MENUPAGE_SOUND_SETTINGS)
+ DMAudio.StopFrontEndTrack();
+
+ 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();
- printf("REMOVE frontend\n");
- for (int i = 0; i < ARRAY_SIZE(FrontendFilenames); ++i)
- m_aFrontEndSprites[i].Delete();
+ CTxdStore::RemoveTxd(frontend);
- int frontend = CTxdStore::FindTxdSlot("frontend");
- CTxdStore::RemoveTxd(frontend);
+ 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();
-#endif
- int menu = CTxdStore::FindTxdSlot("menu");
- CTxdStore::RemoveTxd(menu);
+ CTxdStore::RemoveTxd(frontend2);
+ }
- m_bSpritesLoaded = false;
+ m_bSpritesLoaded = false;
+ }
+ m_OnlySaveMenu = false;
+ CUserDisplay::PlaceName.ProcessAfterFrontEndShutDown();
}
void
@@ -5618,13 +5464,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)
@@ -5632,7 +5471,7 @@ CMenuManager::WaitForUserCD()
HandleExit();
CPad::UpdatePads();
- MessageScreen("NO_PCCD");
+ MessageScreen("NO_PCCD", true);
if (CPad::GetPad(0)->GetEscapeJustDown()) {
m_bQuitGameNoCD = true;
@@ -5641,317 +5480,148 @@ CMenuManager::WaitForUserCD()
}
void
-CMenuManager::PrintController(void)
+CMenuManager::DrawQuitGameScreen(void)
{
- // FIX: Originally this function doesn't have StretchX/Y, everything had constant pixel size (due to screen was abandoned early?)
- // Also texts and their alignment were very bad, so I tried to make them readable (commented out the original code, and marked the ones I added with X)
-
- m_aFrontEndSprites[FE_CONTROLLERSH].Draw(MENU_X_LEFT_ALIGNED(160.0f), MENU_Y(160.0f), MENU_X(240.0f), MENU_Y(180.0f), CRGBA(0, 0, 0, 255));
- m_aFrontEndSprites[FE_CONTROLLER].Draw(MENU_X_LEFT_ALIGNED(160.0f), MENU_Y(160.0f), MENU_X(235.2f), MENU_Y(175.2f), CRGBA(255, 255, 255, 255));
- if (m_DisplayControllerOnFoot) {
- if (CTimer::GetTimeInMillisecondsPauseMode() & 0x400)
- m_aFrontEndSprites[FE_ARROWS1].Draw(MENU_X_LEFT_ALIGNED(160.0f), MENU_Y(160.0f), MENU_X(235.2f), MENU_Y(175.2f), CRGBA(255, 255, 255, 255));
- else
- m_aFrontEndSprites[FE_ARROWS3].Draw(MENU_X_LEFT_ALIGNED(160.0f), MENU_Y(160.0f), MENU_X(235.2f), MENU_Y(175.2f), CRGBA(255, 255, 255, 255));
- } else {
- if (CTimer::GetTimeInMillisecondsPauseMode() & 0x400)
- m_aFrontEndSprites[FE_ARROWS2].Draw(MENU_X_LEFT_ALIGNED(160.0f), MENU_Y(160.0f), MENU_X(235.2f), MENU_Y(175.2f), CRGBA(255, 255, 255, 255));
- else
- m_aFrontEndSprites[FE_ARROWS4].Draw(MENU_X_LEFT_ALIGNED(160.0f), MENU_Y(160.0f), MENU_X(235.2f), MENU_Y(175.2f), CRGBA(255, 255, 255, 255));
- }
-
- CFont::SetFontStyle(FONT_LOCALE(FONT_BANK)); // X
-
- // CFont::SetScale(0.4f, 0.4f);
- CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE), MENU_Y(SMALLESTTEXT_Y_SCALE)); // X
-
- // CFont::SetColor(CRGBA(128, 128, 128, FadeIn(255)));
- CFont::SetDropColor(CRGBA(0, 0, 0, FadeIn(255))); // X
- CFont::SetDropShadowPosition(1); // X
- CFont::SetColor(CRGBA(255, 255, 255, FadeIn(255))); // X
-
- if (m_DisplayControllerOnFoot) {
- switch (CPad::GetPad(0)->Mode) {
- case 0:
- CFont::SetRightJustifyOn(); // X
- CFont::PrintString(MENU_X_LEFT_ALIGNED(210.0f), MENU_Y(146.0f), TheText.Get("FEC_CWL"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(185.0f), TheText.Get("FEC_LOF"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(225.0f), TheText.Get("FEC_MOV"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(257.0f), TheText.Get("FEC_MOV"));
- CFont::SetJustifyOn(); // X
- CFont::PrintString(MENU_X_LEFT_ALIGNED(263.0f), MENU_Y(301.0f), TheText.Get("FEC_CAM"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(290.0f), MENU_Y(288.0f), TheText.Get("FEC_PAU"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(344.0f), MENU_Y(146.0f), TheText.Get("FEC_CWR"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(185.0f), TheText.Get("FEC_TAR"));
- CFont::SetRightJustifyOn(); // X
- CFont::PrintString(MENU_X_LEFT_ALIGNED(304.0f), MENU_Y(178.0f), TheText.Get("FEC_JUM"));
- CFont::SetJustifyOn(); // X
- CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(212.0f), TheText.Get("FEC_ENV"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(225.0f), TheText.Get("FEC_ATT"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(238.0f), TheText.Get("FEC_RUN"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(254.0f), TheText.Get("FEC_FPC"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(269.0f), TheText.Get("FEC_LB3"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(282.0f), TheText.Get("FEC_R3"));
- break;
- case 1:
- CFont::SetRightJustifyOn(); // X
- CFont::PrintString(MENU_X_LEFT_ALIGNED(210.0f), MENU_Y(146.0f), TheText.Get("FEC_CWL"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(185.0f), TheText.Get("FEC_LOF"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(225.0f), TheText.Get("FEC_CAM"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(257.0f), TheText.Get("FEC_MOV"));
- CFont::SetJustifyOn(); // X
- CFont::PrintString(MENU_X_LEFT_ALIGNED(263.0f), MENU_Y(301.0f), TheText.Get("FEC_NA"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(290.0f), MENU_Y(288.0f), TheText.Get("FEC_PAU"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(344.0f), MENU_Y(146.0f), TheText.Get("FEC_CWR"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(185.0f), TheText.Get("FEC_TAR"));
- CFont::SetRightJustifyOn(); // X
- CFont::PrintString(MENU_X_LEFT_ALIGNED(304.0f), MENU_Y(178.0f), TheText.Get("FEC_JUM"));
- CFont::SetJustifyOn(); // X
- CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(212.0f), TheText.Get("FEC_ENV"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(225.0f), TheText.Get("FEC_ATT"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(238.0f), TheText.Get("FEC_RUN"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(254.0f), TheText.Get("FEC_FPC"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(269.0f), TheText.Get("FEC_LB3"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(282.0f), TheText.Get("FEC_R3"));
- break;
- case 2:
- CFont::SetRightJustifyOn(); // X
- CFont::PrintString(MENU_X_LEFT_ALIGNED(210.0f), MENU_Y(146.0f), TheText.Get("FEC_CWL"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(185.0f), TheText.Get("FEC_ENV"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(225.0f), TheText.Get("FEC_MOV"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(257.0f), TheText.Get("FEC_MOV"));
- CFont::SetJustifyOn(); // X
- CFont::PrintString(MENU_X_LEFT_ALIGNED(263.0f), MENU_Y(301.0f), TheText.Get("FEC_CAM"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(290.0f), MENU_Y(288.0f), TheText.Get("FEC_PAU"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(344.0f), MENU_Y(146.0f), TheText.Get("FEC_CWR"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(185.0f), TheText.Get("FEC_TAR"));
- CFont::SetRightJustifyOn(); // X
- CFont::PrintString(MENU_X_LEFT_ALIGNED(304.0f), MENU_Y(178.0f), TheText.Get("FEC_JUM"));
- CFont::SetJustifyOn(); // X
- CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(212.0f), TheText.Get("FEC_LOF"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(225.0f), TheText.Get("FEC_RUN"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(238.0f), TheText.Get("FEC_ATT"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(254.0f), TheText.Get("FEC_FPC"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(269.0f), TheText.Get("FEC_LB3"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(282.0f), TheText.Get("FEC_R3"));
- break;
- case 3:
- CFont::SetRightJustifyOn(); // X
- CFont::PrintString(MENU_X_LEFT_ALIGNED(210.0f), MENU_Y(146.0f), TheText.Get("FEC_CWL"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(185.0f), TheText.Get("FEC_TAR"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(225.0f), TheText.Get("FEC_NA"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(257.0f), TheText.Get("FEC_MOV"));
- CFont::SetJustifyOn(); // X
- CFont::PrintString(MENU_X_LEFT_ALIGNED(263.0f), MENU_Y(301.0f), TheText.Get("FEC_CAM"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(290.0f), MENU_Y(288.0f), TheText.Get("FEC_PAU"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(344.0f), MENU_Y(146.0f), TheText.Get("FEC_CWR"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(185.0f), TheText.Get("FEC_TAR"));
- CFont::SetRightJustifyOn(); // X
- CFont::PrintString(MENU_X_LEFT_ALIGNED(304.0f), MENU_Y(178.0f), TheText.Get("FEC_JUM"));
- CFont::SetJustifyOn(); // X
- CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(212.0f), TheText.Get("FEC_LOF"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(225.0f), TheText.Get("FEC_RUN"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(238.0f), TheText.Get("FEC_ATT"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(254.0f), TheText.Get("FEC_FPC"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(269.0f), TheText.Get("FEC_LB3"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(282.0f), TheText.Get("FEC_R3"));
- break;
- default:
- return;
- }
- } else {
- switch (CPad::GetPad(0)->Mode) {
- case 0:
- CFont::SetRightJustifyOn(); // X
- CFont::PrintString(MENU_X_LEFT_ALIGNED(210.0f), MENU_Y(146.0f), TheText.Get("FEC_LL"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(185.0f), TheText.Get("FEC_RSC"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(225.0f), TheText.Get("FEC_VES"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(257.0f), TheText.Get("FEC_VES"));
- CFont::SetJustifyOn(); // X
- CFont::PrintString(MENU_X_LEFT_ALIGNED(263.0f), MENU_Y(301.0f), TheText.Get("FEC_HO3"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(290.0f), MENU_Y(288.0f), TheText.Get("FEC_CAM"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(344.0f), MENU_Y(146.0f), TheText.Get("FEC_PAU"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(185.0f), TheText.Get("FEC_LB"));
- CFont::SetRightJustifyOn(); // X
- CFont::PrintString(MENU_X_LEFT_ALIGNED(304.0f), MENU_Y(178.0f), TheText.Get("FEC_LR"));
- CFont::SetJustifyOn(); // X
- CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(212.0f), TheText.Get("FEC_HAB"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(225.0f), TheText.Get("FEC_BRA"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(238.0f), TheText.Get("FEC_EXV"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(254.0f), TheText.Get("FEC_CAW"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(269.0f), TheText.Get("FEC_ACC"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(282.0f), TheText.Get("FEC_TUC"));
- // FIX: Coordinates of this line is undefined in PC...
- CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(304.0f), TheText.Get("FEC_SM3"));
- break;
- case 1:
- CFont::SetRightJustifyOn(); // X
- CFont::PrintString(MENU_X_LEFT_ALIGNED(210.0f), MENU_Y(146.0f), TheText.Get("FEC_LL"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(185.0f), TheText.Get("FEC_HOR"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(225.0f), TheText.Get("FEC_CAM"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(257.0f), TheText.Get("FEC_VES"));
- CFont::SetJustifyOn(); // X
- CFont::PrintString(MENU_X_LEFT_ALIGNED(263.0f), MENU_Y(301.0f), TheText.Get("FEC_NA"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(290.0f), MENU_Y(288.0f), TheText.Get("FEC_RSC"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(344.0f), MENU_Y(146.0f), TheText.Get("FEC_PAU"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(185.0f), TheText.Get("FEC_LB"));
- CFont::SetRightJustifyOn(); // X
- CFont::PrintString(MENU_X_LEFT_ALIGNED(304.0f), MENU_Y(178.0f), TheText.Get("FEC_LR"));
- CFont::SetJustifyOn(); // X
- CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(212.0f), TheText.Get("FEC_HAB"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(225.0f), TheText.Get("FEC_BRA"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(238.0f), TheText.Get("FEC_EXV"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(254.0f), TheText.Get("FEC_CAW"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(269.0f), TheText.Get("FEC_ACC"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(282.0f), TheText.Get("FEC_TUC"));
- // FIX: Coordinates of this line is undefined in PC...
- CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(304.0f), TheText.Get("FEC_SM3"));
- break;
- case 2:
- CFont::SetRightJustifyOn(); // X
- CFont::PrintString(MENU_X_LEFT_ALIGNED(210.0f), MENU_Y(146.0f), TheText.Get("FEC_LL"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(185.0f), TheText.Get("FEC_EXV"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(225.0f), TheText.Get("FEC_VES"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(257.0f), TheText.Get("FEC_VES"));
- CFont::SetJustifyOn(); // X
- CFont::PrintString(MENU_X_LEFT_ALIGNED(263.0f), MENU_Y(301.0f), TheText.Get("FEC_RS3"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(290.0f), MENU_Y(288.0f), TheText.Get("FEC_CAM"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(344.0f), MENU_Y(146.0f), TheText.Get("FEC_PAU"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(185.0f), TheText.Get("FEC_LB"));
- CFont::SetRightJustifyOn(); // X
- CFont::PrintString(MENU_X_LEFT_ALIGNED(304.0f), MENU_Y(178.0f), TheText.Get("FEC_LR"));
- CFont::SetJustifyOn(); // X
- CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(212.0f), TheText.Get("FEC_HOR"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(225.0f), TheText.Get("FEC_BRA"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(238.0f), TheText.Get("FEC_HAB"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(254.0f), TheText.Get("FEC_CAW"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(269.0f), TheText.Get("FEC_ACC"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(282.0f), TheText.Get("FEC_TUC"));
- // FIX: Coordinates of this line is undefined in PC...
- CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(304.0f), TheText.Get("FEC_SM3"));
- break;
- case 3:
- CFont::SetRightJustifyOn(); // X
- CFont::PrintString(MENU_X_LEFT_ALIGNED(210.0f), MENU_Y(146.0f), TheText.Get("FEC_LL"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(185.0f), TheText.Get("FEC_HAB"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(225.0f), TheText.Get("FEC_TUC"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(156.0f), MENU_Y(257.0f), TheText.Get("FEC_VES"));
- CFont::SetJustifyOn(); // X
- CFont::PrintString(MENU_X_LEFT_ALIGNED(263.0f), MENU_Y(301.0f), TheText.Get("FEC_HO3"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(290.0f), MENU_Y(288.0f), TheText.Get("FEC_CAM"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(344.0f), MENU_Y(146.0f), TheText.Get("FEC_PAU"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(185.0f), TheText.Get("FEC_LB"));
- CFont::SetRightJustifyOn(); // X
- CFont::PrintString(MENU_X_LEFT_ALIGNED(304.0f), MENU_Y(178.0f), TheText.Get("FEC_LR"));
- CFont::SetJustifyOn(); // X
- CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(212.0f), TheText.Get("FEC_CAW"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(225.0f), TheText.Get("FEC_SMT"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(238.0f), TheText.Get("FEC_EXV"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(254.0f), TheText.Get("FEC_RSC"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(269.0f), TheText.Get("FEC_NA"));
- CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(282.0f), TheText.Get("FEC_ACC"));
- // FIX: Coordinates of this line is undefined in PC...
- CFont::PrintString(MENU_X_LEFT_ALIGNED(398.0f), MENU_Y(304.0f), TheText.Get("FEC_BRA"));
- break;
- default:
- return;
- }
+ static int32 exitSignalTimer = 0;
+#ifndef MUCH_SHORTER_OUTRO_SCREEN
+ static PauseModeTime lastTickIncrease = 0;
+ if (m_nMenuFadeAlpha == 255 && CTimer::GetTimeInMillisecondsPauseMode() - lastTickIncrease > 10) {
+ exitSignalTimer++;
+ lastTickIncrease = CTimer::GetTimeInMillisecondsPauseMode();
}
+#else
+ static PauseModeTime sincePress = 0;
+ sincePress += frameTime;
+ if (sincePress > 500)
+ exitSignalTimer = 150;
+#endif
+ static CSprite2d *splash = nil;
- CFont::SetDropShadowPosition(0); // X
-}
+ if (splash == nil)
+ splash = LoadSplash("OUTRO");
-#ifdef MENU_MAP
+ m_aFrontEndSprites[MENUSPRITE_VCLOGO].Draw(CRect(MENU_X(28.0f), MENU_Y(8.0f), MENU_X(157.0f), MENU_Y(138.0f)), CRGBA(255, 255, 255, -(m_nMenuFadeAlpha + 1)));
-#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) \
+ // 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, m_nMenuFadeAlpha));
+ CSprite2d::DrawRect(CRect(MENU_X_RIGHT_ALIGNED(0.f), 0, SCREEN_WIDTH, SCREEN_HEIGHT), CRGBA(0, 0, 0, m_nMenuFadeAlpha));
+#endif
+
+ splash->Draw(CRect(MENU_X_LEFT_ALIGNED(0.f), 0, MENU_X_RIGHT_ALIGNED(0.f), SCREEN_HEIGHT), CRGBA(255, 255, 255, m_nMenuFadeAlpha));
+ if (m_nMenuFadeAlpha == 255 && exitSignalTimer == 150)
+ RsEventHandler(rsQUITAPP, nil);
+
+ m_bShowMouse = false;
+ m_AllowNavigation = false;
+}
void
CMenuManager::PrintMap(void)
{
- CFont::SetJustifyOn();
- bMenuMapActive = true;
+ m_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)));
+ // 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 >= fMapCenterX - fMapSize || SCREEN_HEIGHT >= fMapCenterY - fMapSize) {
- m_aMapSprites[MAPTOP1].Draw(CRect(fMapCenterX - fMapSize, fMapCenterY - fMapSize,
- fMapCenterX - halfTile, fMapCenterY - halfTile), CRGBA(255, 255, 255, FadeIn(255)));
+ if (SCREEN_WIDTH >= m_fMapCenterX - m_fMapSize || SCREEN_HEIGHT >= m_fMapCenterY - m_fMapSize) {
+ m_aFrontEndSprites[MENUSPRITE_MAPTOP01].Draw(CRect(m_fMapCenterX - m_fMapSize, m_fMapCenterY - m_fMapSize,
+ m_fMapCenterX - halfTile, m_fMapCenterY - halfTile), CRGBA(255, 255, 255, FadeIn(255)));
}
- if (SCREEN_WIDTH >= fMapCenterX - halfTile || SCREEN_HEIGHT >= fMapCenterY - fMapSize) {
- m_aMapSprites[MAPTOP2].Draw(CRect(fMapCenterX - halfTile, fMapCenterY - fMapSize,
- fMapCenterX + halfTile, fMapCenterY - halfTile), CRGBA(255, 255, 255, FadeIn(255)));
+ if (SCREEN_WIDTH >= m_fMapCenterX - halfTile || SCREEN_HEIGHT >= m_fMapCenterY - m_fMapSize) {
+ m_aFrontEndSprites[MENUSPRITE_MAPTOP02].Draw(CRect(m_fMapCenterX - halfTile, m_fMapCenterY - m_fMapSize,
+ m_fMapCenterX + halfTile, m_fMapCenterY - halfTile), CRGBA(255, 255, 255, FadeIn(255)));
}
- if (SCREEN_WIDTH >= fMapCenterX + halfTile || SCREEN_HEIGHT >= fMapCenterY - fMapSize) {
- m_aMapSprites[MAPTOP3].Draw(CRect(fMapCenterX + halfTile, fMapCenterY - fMapSize,
- fMapCenterX + fMapSize, fMapCenterY - halfTile), CRGBA(255, 255, 255, FadeIn(255)));
+ if (SCREEN_WIDTH >= m_fMapCenterX + halfTile || SCREEN_HEIGHT >= m_fMapCenterY - m_fMapSize) {
+ m_aFrontEndSprites[MENUSPRITE_MAPTOP03].Draw(CRect(m_fMapCenterX + halfTile, m_fMapCenterY - m_fMapSize,
+ m_fMapCenterX + m_fMapSize, m_fMapCenterY - halfTile), CRGBA(255, 255, 255, FadeIn(255)));
}
- if (SCREEN_WIDTH >= fMapCenterX - fMapSize || SCREEN_HEIGHT >= fMapCenterY - halfTile) {
- m_aMapSprites[MAPMID1].Draw(CRect(fMapCenterX - fMapSize, fMapCenterY - halfTile,
- fMapCenterX - halfTile, fMapCenterY + halfTile), CRGBA(255, 255, 255, FadeIn(255)));
+ if (SCREEN_WIDTH >= m_fMapCenterX - m_fMapSize || SCREEN_HEIGHT >= m_fMapCenterY - halfTile) {
+ m_aFrontEndSprites[MENUSPRITE_MAPMID01].Draw(CRect(m_fMapCenterX - m_fMapSize, m_fMapCenterY - halfTile,
+ m_fMapCenterX - halfTile, m_fMapCenterY + halfTile), CRGBA(255, 255, 255, FadeIn(255)));
}
- if (SCREEN_WIDTH >= fMapCenterX - halfTile || SCREEN_HEIGHT >= fMapCenterY - halfTile) {
- m_aMapSprites[MAPMID2].Draw(CRect(fMapCenterX - halfTile, fMapCenterY - halfTile,
- fMapCenterX + halfTile, fMapCenterY + halfTile), CRGBA(255, 255, 255, FadeIn(255)));
+ if (SCREEN_WIDTH >= m_fMapCenterX - halfTile || SCREEN_HEIGHT >= m_fMapCenterY - halfTile) {
+ m_aFrontEndSprites[MENUSPRITE_MAPMID02].Draw(CRect(m_fMapCenterX - halfTile, m_fMapCenterY - halfTile,
+ m_fMapCenterX + halfTile, m_fMapCenterY + halfTile), CRGBA(255, 255, 255, FadeIn(255)));
}
- if (SCREEN_WIDTH >= fMapCenterX + halfTile || SCREEN_HEIGHT >= fMapCenterY - halfTile) {
- m_aMapSprites[MAPMID3].Draw(CRect(fMapCenterX + halfTile, fMapCenterY - halfTile,
- fMapCenterX + fMapSize, fMapCenterY + halfTile), CRGBA(255, 255, 255, FadeIn(255)));
+ if (SCREEN_WIDTH >= m_fMapCenterX + halfTile || SCREEN_HEIGHT >= m_fMapCenterY - halfTile) {
+ m_aFrontEndSprites[MENUSPRITE_MAPMID03].Draw(CRect(m_fMapCenterX + halfTile, m_fMapCenterY - halfTile,
+ m_fMapCenterX + m_fMapSize, m_fMapCenterY + halfTile), CRGBA(255, 255, 255, FadeIn(255)));
}
- if (SCREEN_WIDTH >= fMapCenterX - fMapSize || SCREEN_HEIGHT >= fMapCenterY + halfTile) {
- m_aMapSprites[MAPBOT1].Draw(CRect(fMapCenterX - fMapSize, fMapCenterY + halfTile,
- fMapCenterX - halfTile, fMapCenterY + fMapSize), CRGBA(255, 255, 255, FadeIn(255)));
+ if (SCREEN_WIDTH >= m_fMapCenterX - m_fMapSize || SCREEN_HEIGHT >= m_fMapCenterY + halfTile) {
+ m_aFrontEndSprites[MENUSPRITE_MAPBOT01].Draw(CRect(m_fMapCenterX - m_fMapSize, m_fMapCenterY + halfTile,
+ m_fMapCenterX - halfTile, m_fMapCenterY + m_fMapSize), CRGBA(255, 255, 255, FadeIn(255)));
}
- if (SCREEN_WIDTH >= fMapCenterX - halfTile || SCREEN_HEIGHT >= fMapCenterY + halfTile) {
- m_aMapSprites[MAPBOT2].Draw(CRect(fMapCenterX - halfTile, fMapCenterY + halfTile,
- fMapCenterX + halfTile, fMapCenterY + fMapSize), CRGBA(255, 255, 255, FadeIn(255)));
+ if (SCREEN_WIDTH >= m_fMapCenterX - halfTile || SCREEN_HEIGHT >= m_fMapCenterY + halfTile) {
+ m_aFrontEndSprites[MENUSPRITE_MAPBOT02].Draw(CRect(m_fMapCenterX - halfTile, m_fMapCenterY + halfTile,
+ m_fMapCenterX + halfTile, m_fMapCenterY + m_fMapSize), CRGBA(255, 255, 255, FadeIn(255)));
}
- if (SCREEN_WIDTH >= fMapCenterX + halfTile || SCREEN_HEIGHT >= fMapCenterY + halfTile) {
- m_aMapSprites[MAPBOT3].Draw(CRect(fMapCenterX + halfTile, fMapCenterY + halfTile,
- fMapCenterX + fMapSize, fMapCenterY + fMapSize), CRGBA(255, 255, 255, FadeIn(255)));
+ if (SCREEN_WIDTH >= m_fMapCenterX + halfTile || SCREEN_HEIGHT >= m_fMapCenterY + halfTile) {
+ m_aFrontEndSprites[MENUSPRITE_MAPBOT03].Draw(CRect(m_fMapCenterX + halfTile, m_fMapCenterY + halfTile,
+ m_fMapCenterX + m_fMapSize, m_fMapCenterY + m_fMapSize), CRGBA(255, 255, 255, FadeIn(255)));
}
CRadar::DrawBlips();
- static CVector2D mapCrosshair;
+ 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;
@@ -5967,341 +5637,58 @@ CMenuManager::PrintMap(void)
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);
- }
-
- 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
+ m_bMenuMapActive = false;
- 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("FEC_TAR"));
-#undef TEXT_PIECE
+ CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENU_X_MARGIN));
+ CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(MENU_X_MARGIN));
+ DisplayHelperText("FEH_MPH");
}
-#undef ZOOM
-#endif
-
-// rowIdx 99999 returns total numbers of rows. otherwise it returns 0.
-int
-CMenuManager::ConstructStatLine(int rowIdx)
+void
+CMenuManager::ChangeRadioStation(int8 increaseBy)
{
-#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;
- }
-
- int percentCompleted = (CStats::TotalProgressInGame == 0 ? 0 :
- CStats::ProgressMade * 100.0f / (CGame::nastyGame ? CStats::TotalProgressInGame : CStats::TotalProgressInGame - 1));
- percentCompleted = Min(percentCompleted, 100);
-
- 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;
- }
- }
- 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;
+ if (m_ScrollRadioBy != 0)
+ return;
- 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);
+ 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));
}
- 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]);
+ 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);
+}
- 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:
+#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;
- }
- 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;
+ ++Rows;
}
-
- 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
+ return Rows;
}
+#endif
#undef GetBackJustUp
#undef GetBackJustDown
-#undef ChangeScreen
-
-#endif
diff --git a/src/core/Frontend.h b/src/core/Frontend.h
index 8cf3dd28..58701ecf 100644
--- a/src/core/Frontend.h
+++ b/src/core/Frontend.h
@@ -4,41 +4,57 @@
#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 MENU_X_MARGIN 40.0f
-#define MENUACTION_POS_Y 60.0f
-#define MENUACTION_SCALE_MULT 0.9f
+#define MENUHEADER_POS_X 10.0f
+#define MENUHEADER_POS_Y 10.0f
+#define MENUHEADER_HEIGHT 2.0f
+#define MENUHEADER_WIDTH 1.0f
-#define MENURADIO_ICON_SCALE 60.0f
+#define MENU_X_MARGIN 10.0f
-#define MENUSLIDER_X 256.0f
-#define MENUSLIDER_UNK 256.0f
-
-#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 MENUACTION_SCALE_MULT 0.9f
-#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
@@ -50,96 +66,77 @@
#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,
NUM_MENU_SPRITES
};
@@ -155,88 +152,54 @@ enum eSaveSlot
SAVESLOT_6,
SAVESLOT_7,
SAVESLOT_8,
- SAVESLOT_LABEL = 36,
+ SAVESLOT_LABEL = 36
};
-#ifdef MENU_MAP
-enum MapSprites
-{
- MAPMID1,
- MAPMID2,
- MAPMID3,
- MAPBOT1,
- MAPBOT2,
- MAPBOT3,
- MAPTOP1,
- MAPTOP2,
- MAPTOP3,
- NUM_MAP_SPRITES
-};
-#endif
-
enum eMenuScreen
{
MENUPAGE_DISABLED = -1,
- MENUPAGE_NONE = 0,
- MENUPAGE_STATS = 1,
- MENUPAGE_NEW_GAME = 2,
- MENUPAGE_BRIEFS = 3,
- MENUPAGE_CONTROLLER_SETTINGS = 4,
- MENUPAGE_SOUND_SETTINGS = 5,
- MENUPAGE_DISPLAY_SETTINGS = 6,
- MENUPAGE_LANGUAGE_SETTINGS = 7,
+ MENUPAGE_STATS = 0,
+ MENUPAGE_NEW_GAME = 1,
+ MENUPAGE_BRIEFS = 2,
+ MENUPAGE_SOUND_SETTINGS = 3,
+ MENUPAGE_DISPLAY_SETTINGS = 4,
+ MENUPAGE_LANGUAGE_SETTINGS = 5,
+ MENUPAGE_MAP = 6,
+ MENUPAGE_NEW_GAME_RELOAD = 7,
MENUPAGE_CHOOSE_LOAD_SLOT = 8,
MENUPAGE_CHOOSE_DELETE_SLOT = 9,
- MENUPAGE_NEW_GAME_RELOAD = 10,
- MENUPAGE_LOAD_SLOT_CONFIRM = 11,
- MENUPAGE_DELETE_SLOT_CONFIRM = 12,
- MENUPAGE_NO_MEMORY_CARD = 13, // hud adjustment page in mobile
- MENUPAGE_LOADING_IN_PROGRESS = 14,
- MENUPAGE_DELETING_IN_PROGRESS = 15,
- MENUPAGE_PS2_LOAD_FAILED = 16,
- MENUPAGE_DELETE_FAILED = 17,
- MENUPAGE_DEBUG_MENU = 18,
- MENUPAGE_MEMORY_CARD_DEBUG = 19,
- MENUPAGE_MEMORY_CARD_TEST = 20,
- MENUPAGE_MULTIPLAYER_MAIN = 21,
- MENUPAGE_PS2_SAVE_FAILED = 22,
- MENUPAGE_PS2_SAVE_FAILED_2 = 23,
- MENUPAGE_SAVE = 24,
- MENUPAGE_NO_MEMORY_CARD_2 = 25,
- MENUPAGE_CHOOSE_SAVE_SLOT = 26,
- MENUPAGE_SAVE_OVERWRITE_CONFIRM = 27,
- MENUPAGE_MULTIPLAYER_MAP = 28,
- MENUPAGE_MULTIPLAYER_CONNECTION = 29,
- MENUPAGE_MULTIPLAYER_FIND_GAME = 30,
- MENUPAGE_MULTIPLAYER_MODE = 31,
- MENUPAGE_MULTIPLAYER_CREATE = 32,
- MENUPAGE_MULTIPLAYER_START = 33,
- MENUPAGE_SKIN_SELECT_OLD = 34,
- MENUPAGE_CONTROLLER_PC = 35,
- MENUPAGE_CONTROLLER_PC_OLD1 = 36,
- MENUPAGE_CONTROLLER_PC_OLD2 = 37,
- MENUPAGE_CONTROLLER_PC_OLD3 = 38,
- MENUPAGE_CONTROLLER_PC_OLD4 = 39,
- MENUPAGE_CONTROLLER_DEBUG = 40,
- MENUPAGE_OPTIONS = 41,
- MENUPAGE_EXIT = 42,
- MENUPAGE_SAVING_IN_PROGRESS = 43,
- MENUPAGE_SAVE_SUCCESSFUL = 44,
- MENUPAGE_DELETING = 45,
- MENUPAGE_DELETE_SUCCESS = 46,
- MENUPAGE_SAVE_FAILED = 47,
- MENUPAGE_LOAD_FAILED = 48,
- MENUPAGE_LOAD_FAILED_2 = 49,
- MENUPAGE_FILTER_GAME = 50,
- MENUPAGE_START_MENU = 51,
- MENUPAGE_PAUSE_MENU = 52,
- MENUPAGE_CHOOSE_MODE = 53,
- MENUPAGE_SKIN_SELECT = 54,
- MENUPAGE_KEYBOARD_CONTROLS = 55,
- MENUPAGE_MOUSE_CONTROLS = 56,
- MENUPAGE_MISSION_RETRY = 57,
-#ifdef MENU_MAP
- MENUPAGE_MAP = 58,
+ 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 LEGACY_MENU_OPTIONS
+ MENUPAGE_CONTROLLER_SETTINGS,
+ 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
@@ -248,9 +211,8 @@ enum eMenuScreen
#endif
#endif
- MENUPAGE_UNK, // originally 58. Custom screens are inserted above, because last screen in CMenuScreens should always be empty to make CFO work
+ MENUPAGE_OUTRO, // Originally 34, but CFO needs last screen to be empty to count number of menu pages
MENUPAGES
-
};
enum eMenuAction
@@ -261,9 +223,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,
@@ -271,10 +234,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,
@@ -283,74 +244,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,
@@ -360,24 +271,14 @@ 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_REJECT_RETRY,
- MENUACTION_UNK114,
-//#ifdef ANISOTROPIC_FILTERING
-// MENUACTION_MIPMAPS,
-// MENUACTION_TEXTURE_FILTERING,
-//#endif
+ MENUACTION_DRAWDIST,
+ MENUACTION_MOUSESENS,
+ MENUACTION_MP3VOLUMEBOOST,
+#ifdef LEGACY_MENU_OPTIONS
+ MENUACTION_CTRLVIBRATION,
+ MENUACTION_CTRLCONFIG,
+#endif
};
enum eCheckHover
@@ -404,16 +305,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,
@@ -424,12 +317,18 @@ enum eCheckHover
HOVEROPTION_DECREASE_SFXVOLUME,
HOVEROPTION_INCREASE_MOUSESENS,
HOVEROPTION_DECREASE_MOUSESENS,
+ HOVEROPTION_INCREASE_MP3BOOST,
+ HOVEROPTION_DECREASE_MP3BOOST,
HOVEROPTION_NOT_HOVERING,
};
enum
{
+#if defined LEGACY_MENU_OPTIONS || defined CUSTOM_FRONTEND_OPTIONS
NUM_MENUROWS = 18,
+#else
+ NUM_MENUROWS = 12,
+#endif
};
enum eControlMethod
@@ -442,7 +341,7 @@ enum eControlMethod
enum ControllerSetupColumn
{
CONTSETUP_PED_COLUMN = 0,
- CONTSETUP_VEHICLE_COLUMN = 14,
+ CONTSETUP_VEHICLE_COLUMN = 16,
};
struct tSkinInfo
@@ -464,9 +363,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
{
@@ -474,21 +372,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
@@ -537,7 +435,7 @@ struct CCFODynamic : CCFO
struct CMenuScreenCustom
{
char m_ScreenName[8];
- int32 m_PreviousPage[2]; // eMenuScreen
+ int32 m_PreviousPage; // eMenuScreen
CCustomScreenLayout *layout;
ReturnPrevPageFunc returnPrevPageFunc;
@@ -554,74 +452,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;
+ uint8 m_PrefsMP3BoostVolume;
+ uint8 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;
@@ -649,42 +676,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
@@ -694,14 +687,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
@@ -720,69 +707,86 @@ public:
#define ISLAND_LOADING_ISNT(p)
#endif
-public:
- static void BuildStatLine(Const char *text, void *stat, bool itsFloat, void *stat2);
+#ifdef XBOX_MESSAGE_SCREEN
+ static uint32 m_nDialogHideTimer;
+ static PauseModeTime 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
+
+ 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();
};
#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 824f342b..1ccb658b 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 33302653..3f759794 100644
--- a/src/core/Game.cpp
+++ b/src/core/Game.cpp
@@ -44,6 +44,7 @@
#include "MBlur.h"
#include "Messages.h"
#include "MemoryCard.h"
+#include "MemoryHeap.h"
#include "Pad.h"
#include "Particle.h"
#include "ParticleObject.h"
@@ -65,6 +66,7 @@
#include "Script.h"
#include "Shadows.h"
#include "Skidmarks.h"
+#include "SetPieces.h"
#include "SpecialFX.h"
#include "Sprite2d.h"
#include "Stats.h"
@@ -85,17 +87,20 @@
#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"
#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;
@@ -110,6 +115,7 @@ bool CGame::japaneseGame = false;
int gameTxdSlot;
+// --MIAMI: File done
bool DoRWStuffStartOfFrame(int16 TopRed, int16 TopGreen, int16 TopBlue, int16 BottomRed, int16 BottomGreen, int16 BottomBlue, int16 Alpha);
void DoRWStuffEndOfFrame(void);
@@ -136,7 +142,7 @@ void MessageScreen(char *msg)
CFont::SetWrapx(SCREEN_SCALE_FROM_RIGHT(190.0f)); // 450.0f
CFont::SetScale(SCREEN_SCALE_X(1.0f), SCREEN_SCALE_Y(1.0f));
CFont::SetCentreOn();
- CFont::SetCentreSize(SCREEN_SCALE_X(450.0f)); // 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));
@@ -154,7 +160,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
@@ -173,14 +183,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
+ CTxdStore::Initialise();
+ CVisibilityPlugins::Initialise();
//InitialiseScene(Scene); // PS2 only, only clears Scene.camera
@@ -226,11 +235,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
@@ -247,15 +252,11 @@ 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();
-#endif
- // TODO: define
+
CPlayerSkin::Initialise();
return (true);
@@ -264,7 +265,6 @@ CGame::InitialiseRenderWare(void)
// missing altogether on PS2
void CGame::ShutdownRenderWare(void)
{
- CMBlur::MotionBlurClose();
DestroySplashScreen();
CHud::Shutdown();
CFont::Shutdown();
@@ -298,56 +298,30 @@ void CGame::ShutdownRenderWare(void)
// 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();
-#endif
-
+ DMAudio.Initialise();
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);
- CWorld::Players[0].SetPlayerSkin(CMenuManager::m_PrefsSkinFile);
-
return true;
}
@@ -366,17 +340,18 @@ bool CGame::Initialise(const char* datFile)
// 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
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());
@@ -403,18 +378,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();
@@ -422,22 +395,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();
@@ -447,76 +408,52 @@ bool CGame::Initialise(const char* datFile)
CCarCtrl::Init();
POP_MEMID();
-#if GTA_VERSION > GTA3_PS2_160
InitModelIndices();
-#endif
PUSH_MEMID(MEMID_DEF_MODELS);
CModelInfo::Initialise();
-#if GTA_VERSION <= GTA3_PS2_160
- CPedStats::Initialise(); // InitialiseOnceAfterRW
-#else
- // probably moved before LoadLevel for multiplayer maps?
CPickups::Init();
CTheCarGenerators::Init();
-#endif
#ifndef GTA_PS2 // or GTA_VERSION?
CdStreamAddImage("MODELS\\GTA3.IMG");
#endif
-#if GTA_VERSION > GTA3_PS2_160
CFileLoader::LoadLevel("DATA\\DEFAULT.DAT");
CFileLoader::LoadLevel(datFile);
-#else
- CFileLoader::LoadLevel("GTA3.DAT");
-#endif
-
#ifdef EXTENDED_PIPELINES
// for generic fallback
CustomPipes::SetTxdFindCallback();
#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
+ WaterLevelInitialise("DATA\\WATER.DAT");
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);
+ CStreaming::RemoveIslandsNotUsed(currLevel);
printf("Streaming uses %zuK of its memory", CStreaming::ms_memoryUsed / 1024); // original modifier was %d
-
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();
@@ -537,11 +474,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();
@@ -553,7 +485,6 @@ bool CGame::Initialise(const char* datFile)
#ifdef GTA_SCENE_EDIT
CSceneEdit::Initialise();
#endif
-
LoadingScreen("Loading the Game", "Load scripts", nil);
PUSH_MEMID(MEMID_SCRIPT);
CTheScripts::Init();
@@ -561,47 +492,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();
@@ -619,22 +527,30 @@ 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
+ 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();
@@ -665,7 +581,7 @@ bool CGame::ShutDown(void)
CStreaming::Shutdown();
CTxdStore::GameShutdown();
CCollision::Shutdown();
- CWaterLevel::Shutdown();
+ CWaterLevel::DestroyWavyAtomic();
CRubbish::Shutdown();
CClouds::Shutdown();
CShadows::Shutdown();
@@ -673,11 +589,13 @@ bool CGame::ShutDown(void)
CSkidmarks::Shutdown();
CWeaponEffects::Shutdown();
CParticle::Shutdown();
-#if GTA_VERSION > GTA3_PS2_160
CPools::ShutDown();
-#endif
CTxdStore::RemoveTxdSlot(gameTxdSlot);
+ CMBlur::MotionBlurClose();
CdStreamRemoveImages();
+#ifdef USE_TEXTURE_POOL
+ _TexturePoolsFinalShutdown();
+#endif
return true;
}
@@ -699,17 +617,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
@@ -722,10 +638,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();
@@ -745,14 +657,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 )
@@ -774,31 +683,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();
@@ -807,19 +703,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)
@@ -830,103 +723,39 @@ 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);
- 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(?);
- CFont::SetBackgroundOff();
- CFont::SetWrapx(SCREEN_SCALE_FROM_RIGHT(160.0f)); // 480.0f
- 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();
- CFont::PrintString(SCREEN_SCALE_X(320.0f), SCREEN_SCALE_Y(130.0f), TheText.Get("MC_LDFL")); // Load Failed!
- CFont::PrintString(SCREEN_SCALE_X(320.0f), SCREEN_SCALE_Y(170.0f), TheText.Get("FES_NOC")); // No Memory Card (PS2) in MEMORY CARD slot 1.
- CFont::PrintString(SCREEN_SCALE_X(320.0f), SCREEN_SCALE_Y(240.0f), TheText.Get("MC_NWRE")); // Now Restarting Game.
- 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;
+ // TODO(Miami)
+ //InitRadioStationPositionList();
if ( GenericLoad() == true )
{
DMAudio.ResetTimers(CTimer::GetTimeInMilliseconds());
@@ -938,23 +767,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)
@@ -963,9 +798,6 @@ 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
@@ -974,12 +806,14 @@ void CGame::Process(void)
PUSH_MEMID(MEMID_FRONTEND);
if (!CCutsceneMgr::IsCutsceneProcessing() && !CTimer::GetIsCodePaused())
FrontEndMenuManager.Process();
- POP_MEMID();
-
+ CTheZones::Update();
+ // DRM call in here
+ uint32 startTime = CTimer::GetCurrentTimeInCycles() / CTimer::GetCyclesPerMillisecond();
CStreaming::Update();
+ uint32 processTime = CTimer::GetCurrentTimeInCycles() / CTimer::GetCyclesPerMillisecond() - startTime;
+ CWindModifiers::Number = 0;
if (!CTimer::GetIsPaused())
{
- CTheZones::Update();
CSprite2d::SetRecipNearClip();
CSprite2d::InitPerFrame();
CFont::InitPerFrame();
@@ -994,6 +828,7 @@ void CGame::Process(void)
POP_MEMID();
CCollision::Update();
+ CScriptPaths::Update();
CTrain::UpdateTrains();
CPlane::UpdatePlanes();
CHeli::UpdateHelis();
@@ -1004,10 +839,17 @@ void CGame::Process(void)
#ifdef GTA_SCENE_EDIT
CSceneEdit::Update();
#endif
+ CSetPieces::Update();
CEventList::Update();
CParticle::Update();
gFireManager.Update();
- CPopulation::Update();
+ if (processTime >= 2) {
+ 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();
@@ -1029,6 +871,7 @@ void CGame::Process(void)
CGarages::Update();
CRubbish::Update();
CSpecialFX::Update();
+ CRopes::Update();
CTimeCycle::Update();
if (CReplay::ShouldStandardCameraBeProcessed())
TheCamera.Process();
@@ -1043,11 +886,11 @@ void CGame::Process(void)
gPhoneInfo.Update();
if (!CReplay::IsPlayingBack())
{
- PUSH_MEMID(MEMID_CARS);
- CCarCtrl::GenerateRandomCars();
+ if (processTime < 2)
+ CCarCtrl::GenerateRandomCars();
CRoadBlocks::GenerateRoadBlocks();
CCarCtrl::RemoveDistantCars();
- POP_MEMID();
+ CCarCtrl::RemoveCarsIfThePoolGetsFull();
}
}
#ifdef GTA_PS2
@@ -1060,12 +903,12 @@ void CGame::Process(void)
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;
}
@@ -1095,21 +938,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,
@@ -1126,24 +969,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;
}
@@ -1155,42 +998,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
@@ -1200,37 +1043,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;
}
@@ -1238,34 +1081,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
@@ -1273,32 +1117,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);
@@ -1310,49 +1154,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)
{
@@ -1361,52 +1205,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 b55793af..ee9ca943 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;
@@ -37,9 +60,17 @@ public:
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 dde43c0f..7e06b96e 100644
--- a/src/core/General.h
+++ b/src/core/General.h
@@ -2,6 +2,8 @@
#include <ctype.h>
+// --MIAMI: file done
+
class CGeneral
{
public:
@@ -134,6 +136,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; }
@@ -145,4 +159,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 df01b440..f7e2bfdd 100644
--- a/src/core/IniFile.cpp
+++ b/src/core/IniFile.cpp
@@ -7,8 +7,10 @@
#include "main.h"
#include "Population.h"
-float CIniFile::PedNumberMultiplier = 1.0f;
-float CIniFile::CarNumberMultiplier = 1.0f;
+// --MIAMI: file done
+
+float CIniFile::PedNumberMultiplier = 0.6f;
+float CIniFile::CarNumberMultiplier = 0.6f;
void CIniFile::LoadIniFile()
{
@@ -24,5 +26,6 @@ void CIniFile::LoadIniFile()
CFileMgr::CloseFile(f);
}
CPopulation::MaxNumberOfPedsInUse = 25.0f * PedNumberMultiplier;
+ CPopulation::MaxNumberOfPedsInUseInterior = 40.0f * PedNumberMultiplier;
CCarCtrl::MaxNumberOfCarsInUse = 12.0f * CarNumberMultiplier;
} \ No newline at end of file
diff --git a/src/core/MenuScreens.cpp b/src/core/MenuScreens.cpp
index 9eff09e6..d4d028c9 100644
--- a/src/core/MenuScreens.cpp
+++ b/src/core/MenuScreens.cpp
@@ -6,452 +6,334 @@
// 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_LOADING_IN_PROGRESS = 14
- { "FET_LG", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
- MENUACTION_LABEL, "FED_LDW", SAVESLOT_NONE, MENUPAGE_LOAD_SLOT_CONFIRM,
+ // 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_DELETING_IN_PROGRESS = 15
- { "FET_DG", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
- MENUACTION_LABEL, "FEDL_WR", SAVESLOT_NONE, MENUPAGE_NONE,
+ // MENUPAGE_MAP = 6
+ { "FEH_MAP", MENUPAGE_NONE, 2,
+ MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 70, 380, 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_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_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_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_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_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_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_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_TEST = 20
- { "FEM_MC2", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
-
+ // 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_MULTIPLAYER_MAIN = 21
- { "FET_MP", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
-
+ // MENUPAGE_LOADING_IN_PROGRESS = 12
+ { "FET_LG", MENUPAGE_CHOOSE_LOAD_SLOT, 0,
},
- // MENUPAGE_PS2_SAVE_FAILED = 22
- { "MCDNSP", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
- MENUACTION_MEMCARDSAVECONFIRM, "JAILB_U", SAVESLOT_NONE, MENUPAGE_NONE,
+ // MENUPAGE_DELETING_IN_PROGRESS = 13
+ { "FES_DEL", MENUPAGE_CHOOSE_DELETE_SLOT, 0,
},
- // MENUPAGE_PS2_SAVE_FAILED_2 = 23
- { "MCGNSP", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
- MENUACTION_MEMCARDSAVECONFIRM, "JAILB_U", SAVESLOT_NONE, MENUPAGE_NONE,
+ // 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,
},
- // Unused in PC but anyway
- // MENUPAGE_SAVE = 24
-#ifdef PS2_SAVE_DIALOG
- { "FET_SG", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
- MENUACTION_CHANGEMENU, "FESZ_SA", SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT,
- MENUACTION_RESUME_FROM_SAVEZONE, "FESZ_CA", SAVESLOT_NONE, MENUPAGE_NONE,
- },
-#else
- { "FET_SG", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
- MENUACTION_LABEL, "FES_SCG", SAVESLOT_NONE, MENUPAGE_NONE,
- MENUACTION_POPULATESLOTS_CHANGEMENU, "GMSAVE", SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT,
- MENUACTION_RESUME_FROM_SAVEZONE, "FESZ_CA", SAVESLOT_NONE, MENUPAGE_NONE,
+ // 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,
},
-#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_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_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_SAVING_IN_PROGRESS = 17
+ { "FET_SG", MENUPAGE_CHOOSE_SAVE_SLOT, 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_SUCCESSFUL = 18
+ { "FET_SG", MENUPAGE_CHOOSE_SAVE_SLOT, 0,
+ MENUACTION_LABEL, "FES_SSC", SAVESLOT_LABEL, MENUPAGE_NONE, 0, 0, 0,
+ MENUACTION_RESUME_FROM_SAVEZONE, "FEM_OK", SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT, 320, 225, MENUALIGN_CENTER,
},
- // MENUPAGE_MULTIPLAYER_MAP = 28
- { "FET_MAP", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
-
+ // 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,
},
- // MENUPAGE_MULTIPLAYER_CONNECTION = 29
- { "FET_CON", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
-
+ // 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_MULTIPLAYER_FIND_GAME = 30
- { "FET_FG", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
-
+ // MENUPAGE_SKIN_SELECT = 21
+ { "FET_PS", MENUPAGE_OPTIONS, 4,
+ MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_OPTIONS, 0, 0, 0,
},
- // MENUPAGE_MULTIPLAYER_MODE = 31
- { "FET_GT", 1, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 0, 0,
-
+ // 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_CREATE = 32
- { "FET_HG", 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_MULTIPLAYER_START = 33
- { "FEN_STA", 2, MENUPAGE_DISABLED, MENUPAGE_DISABLED, 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_SKIN_SELECT_OLD = 34
- { "FET_PS", 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,
+ 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,
+ 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_CONTROLLER_PC = 35
- { "FET_CTL", 1, MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, 0, 0,
- MENUACTION_CTRLMETHOD, "FET_CME", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC,
- 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_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_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_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_CONTROLLER_PC_OLD2 = 37
- { "FET_CTL", 1, MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC, 1, 1,
+ // 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_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_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_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_CONTROLLER_PC_OLD4 = 39
- { "FET_CTL", 1, MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC, 3, 3,
+ // MENUPAGE_NONE = 33
+ { "", 0, 0, },
- },
+#ifdef LEGACY_MENU_OPTIONS
+ // MENUPAGE_CONTROLLER_SETTINGS
+ { "FET_CON", MENUPAGE_OPTIONS, 0,
+ MENUACTION_CTRLCONFIG, "FEC_CCF", SAVESLOT_NONE, MENUPAGE_CONTROLLER_SETTINGS, 0, 0, 0,
+ MENUACTION_CTRLVIBRATION, "FEC_VIB", SAVESLOT_NONE, MENUPAGE_CONTROLLER_SETTINGS, 0, 0, 0,
+ MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, 0,
+ },
- // 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_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_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_CONTROLLER_PC_OLD2
+ { "FET_CTL", MENUPAGE_CONTROLLER_PC, 1,
- // 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_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_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_CONTROLLER_PC_OLD4
+ { "FET_CTL", MENUPAGE_CONTROLLER_PC, 3,
- // 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,
-#ifdef MENU_MAP
- MENUACTION_CHANGEMENU, "FEG_MAP", SAVESLOT_NONE, MENUPAGE_MAP,
-#endif
- 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
-
- { "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
- },
-#endif
+ },
-#ifdef MENU_MAP
- // MENUPAGE_MAP
- { "FEG_MAP", 1, MENUPAGE_NONE, MENUPAGE_NONE, 2, 2,
- MENUACTION_UNK110, "", SAVESLOT_NONE, MENUPAGE_NONE, // to prevent cross/enter to go back
- MENUACTION_CHANGEMENU, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE,
+ // 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
- // 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 3a6d9c8b..c14f938b 100644
--- a/src/core/MenuScreensCustom.cpp
+++ b/src/core/MenuScreensCustom.cpp
@@ -24,61 +24,61 @@
#ifdef CUSTOM_FRONTEND_OPTIONS
#ifdef IMPROVED_VIDEOMODE
- #define VIDEOMODE_SELECTOR MENUACTION_CFO_SELECT, "FEM_SCF", { new CCFOSelect((int8*)&FrontEndMenuManager.m_nPrefsWindowed, nil, screenModes, 2, true, ScreenModeAfterChange) },
+ #define VIDEOMODE_SELECTOR MENUACTION_CFO_SELECT, "FEM_SCF", { new CCFOSelect((int8*)&FrontEndMenuManager.m_nPrefsWindowed, nil, screenModes, 2, true, ScreenModeAfterChange) }, 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, "MultiSampling", MultiSamplingDraw, MultiSamplingButtonPress) },
+ #define MULTISAMPLING_SELECTOR MENUACTION_CFO_DYNAMIC, "FED_AAS", { new CCFODynamic((int8*)&FrontEndMenuManager.m_nPrefsMSAALevel, "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, "CutsceneBorders", off_on, 2, false, nil) },
+ #define CUTSCENE_BORDERS_TOGGLE MENUACTION_CFO_SELECT, "FEM_CSB", { new CCFOSelect((int8 *)&FrontEndMenuManager.m_PrefsCutsceneBorders, "CutsceneBorders", off_on, 2, false, nil) }, 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, "FreeCam", off_on, 2, false, nil) },
+ #define FREE_CAM_TOGGLE MENUACTION_CFO_SELECT, "FEC_FRC", { new CCFOSelect((int8*)&TheCamera.bFreeCam, "FreeCam", off_on, 2, false, nil) }, 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, "PS2AlphaTest", off_on, 2, false, nil) },
+ #define DUALPASS_SELECTOR MENUACTION_CFO_SELECT, "FEM_2PR", { new CCFOSelect((int8*)&gPS2alphaTest, "PS2AlphaTest", off_on, 2, false, nil) }, 0, 0, MENUALIGN_LEFT,
#else
#define DUALPASS_SELECTOR
#endif
#ifdef NO_ISLAND_LOADING
- #define ISLAND_LOADING_SELECTOR MENUACTION_CFO_SELECT, "FEM_ISL", { new CCFOSelect((int8*)&CMenuManager::m_PrefsIslandLoading, "IslandLoading", islandLoadingOpts, ARRAY_SIZE(islandLoadingOpts), true, IslandLoadingAfterChange) },
+ #define ISLAND_LOADING_SELECTOR MENUACTION_CFO_SELECT, "FEM_ISL", { new CCFOSelect((int8*)&FrontEndMenuManager.m_PrefsIslandLoading, "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, "ColourFilter", filterNames, ARRAY_SIZE(filterNames), false, nil) }, \
- MENUACTION_CFO_SELECT, "FED_MBL", { new CCFOSelect((int8*)&CPostFX::MotionBlurOn, "MotionBlur", off_on, 2, false, nil) },
+ MENUACTION_CFO_SELECT, "FED_CLF", { new CCFOSelect((int8*)&CPostFX::EffectSwitch, "ColourFilter", filterNames, ARRAY_SIZE(filterNames), false, nil) }, 0, 0, MENUALIGN_LEFT, \
+ MENUACTION_CFO_SELECT, "FED_MBL", { new CCFOSelect((int8*)&CPostFX::MotionBlurOn, "MotionBlur", off_on, 2, false, nil) }, 0, 0, MENUALIGN_LEFT,
#else
#define POSTFX_SELECTORS
#endif
#ifdef EXTENDED_PIPELINES
#define PIPELINES_SELECTOR \
- MENUACTION_CFO_SELECT, "FED_VPL", { new CCFOSelect((int8*)&CustomPipes::VehiclePipeSwitch, "VehiclePipeline", vehPipelineNames, ARRAY_SIZE(vehPipelineNames), false, nil) }, \
- MENUACTION_CFO_SELECT, "FED_PRM", { new CCFOSelect((int8*)&CustomPipes::RimlightEnable, "NeoRimLight", off_on, 2, false, nil) }, \
- MENUACTION_CFO_SELECT, "FED_WLM", { new CCFOSelect((int8*)&CustomPipes::LightmapEnable, "NeoLightMaps", off_on, 2, false, nil) }, \
- MENUACTION_CFO_SELECT, "FED_RGL", { new CCFOSelect((int8*)&CustomPipes::GlossEnable, "NeoRoadGloss", off_on, 2, false, nil) },
+ MENUACTION_CFO_SELECT, "FED_VPL", { new CCFOSelect((int8*)&CustomPipes::VehiclePipeSwitch, "VehiclePipeline", vehPipelineNames, ARRAY_SIZE(vehPipelineNames), false, nil) }, 0, 0, MENUALIGN_LEFT, \
+ MENUACTION_CFO_SELECT, "FED_PRM", { new CCFOSelect((int8*)&CustomPipes::RimlightEnable, "NeoRimLight", off_on, 2, false, nil) }, 0, 0, MENUALIGN_LEFT, \
+ MENUACTION_CFO_SELECT, "FED_WLM", { new CCFOSelect((int8*)&CustomPipes::LightmapEnable, "NeoLightMaps", off_on, 2, false, nil) }, 0, 0, MENUALIGN_LEFT, \
+ MENUACTION_CFO_SELECT, "FED_RGL", { new CCFOSelect((int8*)&CustomPipes::GlossEnable, "NeoRoadGloss", off_on, 2, false, nil) }, 0, 0, MENUALIGN_LEFT,
#else
#define PIPELINES_SELECTOR
#endif
#ifdef INVERT_LOOK_FOR_PAD
- #define INVERT_PAD_SELECTOR MENUACTION_CFO_SELECT, "FEC_IVP", { new CCFOSelect((int8*)&CPad::bInvertLook4Pad, "InvertPad", off_on, 2, false, nil) },
+ #define INVERT_PAD_SELECTOR MENUACTION_CFO_SELECT, "FEC_ILU", { new CCFOSelect((int8*)&CPad::bInvertLook4Pad, nil, off_on, 2, false, nil) }, 150, 0, MENUALIGN_LEFT,
#else
#define INVERT_PAD_SELECTOR
#endif
@@ -110,22 +110,14 @@ void RestoreDefGraphics(int8 action) {
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
}
@@ -135,16 +127,19 @@ void RestoreDefDisplay(int8 action) {
return;
#ifdef CUTSCENE_BORDERS_SWITCH
- CMenuManager::m_PrefsCutsceneBorders = true;
+ FrontEndMenuManager.m_PrefsCutsceneBorders = true;
#endif
#ifdef FREE_CAM
TheCamera.bFreeCam = false;
#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
}
@@ -342,61 +337,56 @@ wchar* DetectJoystickDraw(bool* disabled, bool userHovering) {
}
#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 },
- },
-
- // 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 },
+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_BRIEFS = 3
- { "FET_BRE", MENUPAGE_NONE, MENUPAGE_NONE, nil, nil,
- 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_CONTROLLER_SETTINGS = 4
- { "FET_CON", MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, nil, nil,
- MENUACTION_CTRLCONFIG, "FEC_CCF", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_SETTINGS },
- MENUACTION_CTRLDISPLAY, "FEC_CDP", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_SETTINGS },
- MENUACTION_CTRLVIBRATION, "FEC_VIB", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_SETTINGS },
- 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_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 },
- 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 },
+ { "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 },
- MENUACTION_WIDESCREEN, "FED_WIS", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS },
- MENUACTION_SCREENRES, "FED_RES", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS },
+ 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
@@ -405,459 +395,339 @@ CMenuScreenCustom aScreens[MENUPAGES] = {
FREE_CAM_TOGGLE
POSTFX_SELECTORS
PIPELINES_SELECTOR
- MENUACTION_RESTOREDEF, "FET_DEF", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS },
- MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
+ MENUACTION_RESTOREDEF, "FET_DEF", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 320, 0, MENUALIGN_CENTER,
+ MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 320, 0, MENUALIGN_CENTER,
},
#else
- // MENUPAGE_DISPLAY_SETTINGS = 6
- { "FET_DIS", MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, nil, nil,
- MENUACTION_BRIGHTNESS, "FED_BRI", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS },
- MENUACTION_DRAWDIST, "FEM_LOD", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS },
+ { "FEH_DIS", MENUPAGE_OPTIONS, new CCustomScreenLayout({40, 78, 25, true}), nil,
+ MENUACTION_BRIGHTNESS, "FED_BRI", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS }, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_DRAWDIST, "FEM_LOD", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS }, 0, 0, MENUALIGN_LEFT,
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, RestoreDefDisplay) },
- MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
+ MENUACTION_LEGENDS, "MAP_LEG", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS }, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_RADARMODE, "FED_RDR", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS }, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_HUD, "FED_HUD", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS }, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_SUBTITLES, "FED_SUB", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS }, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_CFO_DYNAMIC, "FET_DEF", { new CCFODynamic(nil, nil, nil, 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 },
+ // 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,
#ifdef MORE_LANGUAGES
- MENUACTION_CFO_DYNAMIC, "FEL_POL", { new CCFODynamic(nil, nil, nil, LangPolSelect) },
- MENUACTION_CFO_DYNAMIC, "FEL_RUS", { new CCFODynamic(nil, nil, nil, LangRusSelect) },
- MENUACTION_CFO_DYNAMIC, "FEL_JAP", { new CCFODynamic(nil, nil, nil, LangJapSelect) },
+ MENUACTION_CFO_DYNAMIC, "FEL_POL", { new CCFODynamic(nil, nil, nil, LangPolSelect) }, 0, 0, MENUALIGN_CENTER,
+ MENUACTION_CFO_DYNAMIC, "FEL_RUS", { new CCFODynamic(nil, nil, nil, LangRusSelect) }, 0, 0, MENUALIGN_CENTER
+ MENUACTION_CFO_DYNAMIC, "FEL_JAP", { new CCFODynamic(nil, nil, nil, LangJapSelect) }, 0, 0, MENUALIGN_CENTER,
#endif
- MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
- },
-
- // MENUPAGE_CHOOSE_LOAD_SLOT = 8
- { "FET_LG", MENUPAGE_NEW_GAME, MENUPAGE_NEW_GAME, nil, nil,
- MENUACTION_CHANGEMENU, "FESZ_CA", { nil, SAVESLOT_NONE, MENUPAGE_NEW_GAME },
- MENUACTION_CHECKSAVE, "FEM_SL0", { nil, SAVESLOT_1, MENUPAGE_LOAD_SLOT_CONFIRM },
- MENUACTION_CHECKSAVE, "FEM_SL1", { nil, SAVESLOT_2, MENUPAGE_LOAD_SLOT_CONFIRM },
- MENUACTION_CHECKSAVE, "FEM_SL2", { nil, SAVESLOT_3, MENUPAGE_LOAD_SLOT_CONFIRM },
- MENUACTION_CHECKSAVE, "FEM_SL3", { nil, SAVESLOT_4, MENUPAGE_LOAD_SLOT_CONFIRM },
- MENUACTION_CHECKSAVE, "FEM_SL4", { nil, SAVESLOT_5, MENUPAGE_LOAD_SLOT_CONFIRM },
- MENUACTION_CHECKSAVE, "FEM_SL5", { nil, SAVESLOT_6, MENUPAGE_LOAD_SLOT_CONFIRM },
- MENUACTION_CHECKSAVE, "FEM_SL6", { nil, SAVESLOT_7, MENUPAGE_LOAD_SLOT_CONFIRM },
- MENUACTION_CHECKSAVE, "FEM_SL7", { nil, SAVESLOT_8, MENUPAGE_LOAD_SLOT_CONFIRM },
- },
-
- // MENUPAGE_CHOOSE_DELETE_SLOT = 9
- { "FET_DG", MENUPAGE_NEW_GAME, MENUPAGE_NEW_GAME, nil, nil,
- MENUACTION_CHANGEMENU, "FESZ_CA", { nil, SAVESLOT_NONE, MENUPAGE_NEW_GAME },
- MENUACTION_CHANGEMENU, "FEM_SL0", { nil, SAVESLOT_1, MENUPAGE_DELETE_SLOT_CONFIRM },
- MENUACTION_CHANGEMENU, "FEM_SL1", { nil, SAVESLOT_2, MENUPAGE_DELETE_SLOT_CONFIRM },
- MENUACTION_CHANGEMENU, "FEM_SL2", { nil, SAVESLOT_3, MENUPAGE_DELETE_SLOT_CONFIRM },
- MENUACTION_CHANGEMENU, "FEM_SL3", { nil, SAVESLOT_4, MENUPAGE_DELETE_SLOT_CONFIRM },
- MENUACTION_CHANGEMENU, "FEM_SL4", { nil, SAVESLOT_5, MENUPAGE_DELETE_SLOT_CONFIRM },
- MENUACTION_CHANGEMENU, "FEM_SL5", { nil, SAVESLOT_6, MENUPAGE_DELETE_SLOT_CONFIRM },
- MENUACTION_CHANGEMENU, "FEM_SL6", { nil, SAVESLOT_7, MENUPAGE_DELETE_SLOT_CONFIRM },
- MENUACTION_CHANGEMENU, "FEM_SL7", { nil, SAVESLOT_8, MENUPAGE_DELETE_SLOT_CONFIRM },
- },
-
- // MENUPAGE_NEW_GAME_RELOAD = 10
- { "FET_NG", MENUPAGE_NEW_GAME, MENUPAGE_NEW_GAME, nil, nil,
- MENUACTION_LABEL, "FESZ_QR", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
- MENUACTION_CHANGEMENU, "FEM_NO", { nil, SAVESLOT_NONE, MENUPAGE_NEW_GAME },
- MENUACTION_NEWGAME, "FEM_YES", { nil, SAVESLOT_NONE, MENUPAGE_NEW_GAME_RELOAD },
- },
-
- // MENUPAGE_LOAD_SLOT_CONFIRM = 11
- { "FET_LG", MENUPAGE_CHOOSE_LOAD_SLOT, MENUPAGE_CHOOSE_LOAD_SLOT, nil, nil,
- MENUACTION_LABEL, "FESZ_QL", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
- MENUACTION_CHANGEMENU, "FEM_NO", { nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_LOAD_SLOT },
- MENUACTION_CHANGEMENU, "FEM_YES", { nil, SAVESLOT_NONE, MENUPAGE_LOADING_IN_PROGRESS },
- },
-
- // MENUPAGE_DELETE_SLOT_CONFIRM = 12
- { "FET_DG", MENUPAGE_CHOOSE_DELETE_SLOT, MENUPAGE_CHOOSE_DELETE_SLOT, nil, nil,
- MENUACTION_LABEL, "FESZ_QD", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
- MENUACTION_CHANGEMENU, "FEM_NO", { nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_DELETE_SLOT },
- MENUACTION_CHANGEMENU, "FEM_YES", { nil, SAVESLOT_NONE, MENUPAGE_DELETING },
+ MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, MENUALIGN_CENTER,
},
- // MENUPAGE_NO_MEMORY_CARD = 13
- { "FES_NOC", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
- // hud adjustment page in mobile
+ // MENUPAGE_MAP = 6
+ { "FEH_MAP", MENUPAGE_NONE, nil, nil,
+ MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 70, 380, MENUALIGN_CENTER,
},
- // MENUPAGE_LOADING_IN_PROGRESS = 14
- { "FET_LG", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
- MENUACTION_LABEL, "FED_LDW", { nil, SAVESLOT_NONE, MENUPAGE_LOAD_SLOT_CONFIRM },
+ // MENUPAGE_NEW_GAME_RELOAD = 7
+ { "FES_NGA", MENUPAGE_NEW_GAME, nil, nil,
+ MENUACTION_LABEL, "FESZ_QR", {nil, SAVESLOT_NONE, 0}, 0, 0, 0,
+ MENUACTION_NO, "FEM_NO", {nil, SAVESLOT_NONE, MENUPAGE_NEW_GAME}, 320, 200, MENUALIGN_CENTER,
+ MENUACTION_NEWGAME, "FEM_YES", {nil, SAVESLOT_NONE, MENUPAGE_NEW_GAME_RELOAD}, 320, 225, MENUALIGN_CENTER,
},
- // MENUPAGE_DELETING_IN_PROGRESS = 15
- { "FET_DG", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
- MENUACTION_LABEL, "FEDL_WR", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
- },
-
- // MENUPAGE_PS2_LOAD_FAILED = 16
- { "FET_LG", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
- MENUACTION_LABEL, "FES_LOE", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
- },
-
- // 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_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_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_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_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_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_MEMORY_CARD_TEST = 20
- { "FEM_MC2", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
-
+ // 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_MULTIPLAYER_MAIN = 21
- { "FET_MP", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
-
+ // MENUPAGE_LOADING_IN_PROGRESS = 12
+ { "FET_LG", MENUPAGE_CHOOSE_LOAD_SLOT, nil, nil,
},
- // MENUPAGE_PS2_SAVE_FAILED = 22
- { "MCDNSP", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
- MENUACTION_MEMCARDSAVECONFIRM, "JAILB_U", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
+ // MENUPAGE_DELETING_IN_PROGRESS = 13
+ { "FES_DEL", MENUPAGE_CHOOSE_DELETE_SLOT, nil, nil,
},
- // MENUPAGE_PS2_SAVE_FAILED_2 = 23
- { "MCGNSP", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
- MENUACTION_MEMCARDSAVECONFIRM, "JAILB_U", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
+ // 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,
},
- // 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_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,
},
-#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_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_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_SAVING_IN_PROGRESS = 17
+ { "FET_SG", MENUPAGE_CHOOSE_SAVE_SLOT, nil, nil,
},
- // 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_SAVE_SUCCESSFUL = 18
+ { "FET_SG", MENUPAGE_CHOOSE_SAVE_SLOT, nil, nil,
+ MENUACTION_LABEL, "FES_SSC", {nil, SAVESLOT_LABEL, MENUPAGE_NONE}, 0, 0, 0,
+ MENUACTION_RESUME_FROM_SAVEZONE, "FEM_OK", {nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT}, 320, 225, MENUALIGN_CENTER,
},
- // MENUPAGE_MULTIPLAYER_MAP = 28
- { "FET_MAP", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
-
+ // MENUPAGE_SAVE_CUSTOM_WARNING = 19
+ { "FET_SG", MENUPAGE_NONE, nil, nil,
+ MENUACTION_LABEL, "", {nil, SAVESLOT_NONE, 0}, 0, 0, 0,
+ MENUACTION_CHANGEMENU, "FEM_OK", {nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT}, 320, 225, MENUALIGN_CENTER,
},
- // MENUPAGE_MULTIPLAYER_CONNECTION = 29
- { "FET_CON", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
-
+ // MENUPAGE_SAVE_CHEAT_WARNING = 20
+ { "FET_SG", MENUPAGE_NEW_GAME, nil, nil,
+ MENUACTION_LABEL, "FES_CHE", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, 0,
+ MENUACTION_CHANGEMENU, "FEM_OK", {nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT}, 320, 225, MENUALIGN_CENTER,
},
- // MENUPAGE_MULTIPLAYER_FIND_GAME = 30
- { "FET_FG", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
-
+ // MENUPAGE_SKIN_SELECT = 21
+ { "FET_PS", MENUPAGE_OPTIONS, nil, nil,
+ MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_OPTIONS}, 0, 0, 0,
},
- // MENUPAGE_MULTIPLAYER_MODE = 31
- { "FET_GT", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
-
+ // MENUPAGE_SAVE_UNUSED = 22
+ { "FET_SG", MENUPAGE_NEW_GAME, nil, nil,
+ MENUACTION_LABEL, "FED_LWR", {nil, SAVESLOT_NONE, 0}, 0, 0, 0,
+ MENUACTION_CHANGEMENU, "FEC_OKK", {nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT}, 0, 0, 0,
},
- // MENUPAGE_MULTIPLAYER_CREATE = 32
- { "FET_HG", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
-
+ // MENUPAGE_SAVE_FAILED = 23
+ { "FET_SG", MENUPAGE_CHOOSE_SAVE_SLOT, nil, nil,
+ MENUACTION_LABEL, "FEC_SVU", {nil, SAVESLOT_NONE, 0}, 0, 0, 0,
+ MENUACTION_CHANGEMENU, "FEC_OKK", {nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT}, 0, 0, 0,
},
- // MENUPAGE_MULTIPLAYER_START = 33
- { "FEN_STA", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
-
+ // MENUPAGE_SAVE_FAILED_2 = 24
+ { "FET_LG", MENUPAGE_CHOOSE_SAVE_SLOT, nil, nil,
+ MENUACTION_LABEL, "FEC_SVU", {nil, SAVESLOT_NONE, 0}, 0, 0, 0,
},
- // MENUPAGE_SKIN_SELECT_OLD = 34
- { "FET_PS", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
-
+ // MENUPAGE_LOAD_FAILED = 25
+ { "FET_LG", MENUPAGE_NEW_GAME, nil, nil,
+ MENUACTION_LABEL, "FEC_LUN", {nil, SAVESLOT_NONE, 0}, 0, 0, 0,
+ MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NEW_GAME}, 0, 0, 0,
},
- // MENUPAGE_CONTROLLER_PC = 35
- { "FET_CTL", MENUPAGE_OPTIONS, MENUPAGE_OPTIONS, nil, nil,
- MENUACTION_CTRLMETHOD, "FET_CME", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC },
- MENUACTION_KEYBOARDCTRLS,"FET_RDK", { nil, SAVESLOT_NONE, MENUPAGE_KEYBOARD_CONTROLS },
+ // MENUPAGE_CONTROLLER_PC = 26
+ { "FET_CTL", MENUPAGE_OPTIONS, new CCustomScreenLayout({0, 0, MENU_DEFAULT_LINE_HEIGHT, false, false, 150}), nil,
+ 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,
#ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS
- MENUACTION_CHANGEMENU, "FEC_JOD", { nil, SAVESLOT_NONE, MENUPAGE_DETECT_JOYSTICK },
+ MENUACTION_CHANGEMENU, "FEC_JOD", {nil, SAVESLOT_NONE, MENUPAGE_DETECT_JOYSTICK}, 0, 0, MENUALIGN_CENTER,
#endif
- MENUACTION_CHANGEMENU, "FET_AMS", { nil, SAVESLOT_NONE, MENUPAGE_MOUSE_CONTROLS },
- MENUACTION_RESTOREDEF, "FET_DEF", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC },
- MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
- },
-
- // MENUPAGE_CONTROLLER_PC_OLD1 = 36
- { "FET_CTL", MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC, nil, nil,
- MENUACTION_GETKEY, "FEC_PLB", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1 },
- MENUACTION_GETKEY, "FEC_CWL", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1 },
- MENUACTION_GETKEY, "FEC_CWR", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1 },
- MENUACTION_GETKEY, "FEC_LKT", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1 },
- MENUACTION_GETKEY, "FEC_PJP", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1 },
- MENUACTION_GETKEY, "FEC_PSP", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1 },
- MENUACTION_GETKEY, "FEC_TLF", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1 },
- MENUACTION_GETKEY, "FEC_TRG", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1 },
- MENUACTION_GETKEY, "FEC_CCM", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD1 },
- MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
- },
-
- // MENUPAGE_CONTROLLER_PC_OLD2 = 37
- { "FET_CTL", MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC, nil, nil,
-
- },
-
- // MENUPAGE_CONTROLLER_PC_OLD3 = 38
- { "FET_CTL", MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC, nil, nil,
- MENUACTION_GETKEY, "FEC_LUP", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD3 },
- MENUACTION_GETKEY, "FEC_LDN", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD3 },
- MENUACTION_GETKEY, "FEC_SMS", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD3 },
- MENUACTION_SHOWHEADBOB, "FEC_GSL", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC_OLD3 },
- MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
- },
-
- // MENUPAGE_CONTROLLER_PC_OLD4 = 39
- { "FET_CTL", MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC, nil, nil,
-
+ MENUACTION_CHANGEMENU, "FEC_MOU", {nil, SAVESLOT_NONE, MENUPAGE_MOUSE_CONTROLS}, 0, 0, MENUALIGN_CENTER,
+ INVERT_PAD_SELECTOR
+ MENUACTION_RESTOREDEF, "FET_DEF", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC}, 320, 0, MENUALIGN_CENTER,
+ MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, 0}, 320, 0, MENUALIGN_CENTER,
},
- // MENUPAGE_CONTROLLER_DEBUG = 40
- { "FEC_DBG", MENUPAGE_CONTROLLER_PC, MENUPAGE_CONTROLLER_PC, nil, nil,
- MENUACTION_GETKEY, "FEC_TGD", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_DEBUG },
- MENUACTION_GETKEY, "FEC_TDO", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_DEBUG },
- MENUACTION_GETKEY, "FEC_TSS", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_DEBUG },
- MENUACTION_GETKEY, "FEC_SMS", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_DEBUG },
- MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
- },
-
- // MENUPAGE_OPTIONS = 41
- { "FET_OPT", MENUPAGE_NONE, MENUPAGE_NONE, nil, nil,
- MENUACTION_CHANGEMENU, "FET_CTL", { nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC },
- MENUACTION_LOADRADIO, "FET_AUD", { nil, SAVESLOT_NONE, MENUPAGE_SOUND_SETTINGS },
- MENUACTION_CHANGEMENU, "FET_DIS", { nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS },
+ // MENUPAGE_OPTIONS = 27
+ { "FET_OPT", MENUPAGE_NONE, nil, nil,
+ 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_GRA", { nil, SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS },
+ MENUACTION_CHANGEMENU, "FET_GRA", {nil, SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS}, 0, 0, MENUALIGN_CENTER,
#endif
- MENUACTION_CHANGEMENU, "FET_LAN", { nil, SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS },
- MENUACTION_PLAYERSETUP, "FET_PSU", { nil, SAVESLOT_NONE, MENUPAGE_SKIN_SELECT },
- MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
- },
-
- // MENUPAGE_EXIT = 42
- { "FET_QG", MENUPAGE_NONE, MENUPAGE_NONE, nil, nil,
- MENUACTION_LABEL, "FEQ_SRE", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
- MENUACTION_DONTCANCEL, "FEM_NO", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
- MENUACTION_CANCELGAME, "FEM_YES", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
+ MENUACTION_CHANGEMENU, "FEO_LAN", {nil, SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS}, 0, 0, MENUALIGN_CENTER,
+ MENUACTION_PLAYERSETUP, "FET_PS", {nil, SAVESLOT_NONE, MENUPAGE_SKIN_SELECT}, 0, 0, MENUALIGN_CENTER,
+ MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, 0}, 0, 0, MENUALIGN_CENTER,
},
- // MENUPAGE_SAVING_IN_PROGRESS = 43
- { "", MENUPAGE_CHOOSE_SAVE_SLOT, MENUPAGE_CHOOSE_SAVE_SLOT, nil, nil,
- MENUACTION_LABEL, "FES_WAR", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
+ // MENUPAGE_EXIT = 28
+ { "FET_QG", MENUPAGE_NONE, nil, nil,
+ MENUACTION_LABEL, "FEQ_SRE", {nil, SAVESLOT_NONE, 0}, 0, 0, 0,
+ MENUACTION_DONTCANCEL, "FEM_NO", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 320, 200, MENUALIGN_CENTER,
+ MENUACTION_CANCELGAME, "FEM_YES", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 320, 225, MENUALIGN_CENTER,
},
- // MENUPAGE_SAVE_SUCCESSFUL = 44
- { "FET_SG", MENUPAGE_CHOOSE_SAVE_SLOT, MENUPAGE_CHOOSE_SAVE_SLOT, nil, nil,
- MENUACTION_LABEL, "FES_SSC", { nil, SAVESLOT_LABEL, MENUPAGE_NONE },
- MENUACTION_RESUME_FROM_SAVEZONE, "FEC_OKK", { nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT },
+ // MENUPAGE_START_MENU = 29
+ { "FEM_MM", MENUPAGE_DISABLED, nil, nil,
+ MENUACTION_CHANGEMENU, "FEP_STG", {nil, SAVESLOT_NONE, MENUPAGE_NEW_GAME}, 320, 170, MENUALIGN_CENTER,
+ MENUACTION_CHANGEMENU, "FEP_OPT", {nil, SAVESLOT_NONE, MENUPAGE_OPTIONS}, 0, 0, MENUALIGN_CENTER,
+ MENUACTION_CHANGEMENU, "FEP_QUI", {nil, SAVESLOT_NONE, MENUPAGE_EXIT}, 0, 0, MENUALIGN_CENTER,
},
- // MENUPAGE_DELETING = 45
- { "FET_DG", MENUPAGE_CHOOSE_DELETE_SLOT, MENUPAGE_CHOOSE_DELETE_SLOT, nil, nil,
- MENUACTION_LABEL, "FED_DLW", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
+ // MENUPAGE_KEYBOARD_CONTROLS = 30
+ { "FET_STI", MENUPAGE_CONTROLLER_PC, nil, nil,
},
- // MENUPAGE_DELETE_SUCCESS = 46
- { "FET_DG", MENUPAGE_CHOOSE_DELETE_SLOT, MENUPAGE_CHOOSE_DELETE_SLOT, nil, nil,
- MENUACTION_LABEL, "DEL_FNM", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
- MENUACTION_CHANGEMENU, "FEC_OKK", { nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_DELETE_SLOT },
+ // MENUPAGE_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,
+ MENUACTION_MOUSESTEER, "FET_MST", {nil, SAVESLOT_NONE, MENUPAGE_MOUSE_CONTROLS}, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, 0}, 320, 260, MENUALIGN_CENTER,
},
- // 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_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_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_NONE = 33
+ { "", 0, nil, nil, },
- // 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_FILTER_GAME = 50
- { "FIL_FLT", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
+#ifdef LEGACY_MENU_OPTIONS
+ // MENUPAGE_CONTROLLER_SETTINGS = 4
+ { "FET_CON", MENUPAGE_OPTIONS, nil, nil,
+ MENUACTION_CTRLCONFIG, "FEC_CCF", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_SETTINGS}, 0, 0, 0,
+ MENUACTION_CTRLVIBRATION, "FEC_VIB", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_SETTINGS}, 0, 0, 0,
+ MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, 0,
},
- // MENUPAGE_START_MENU = 51
- { "FEM_MM", MENUPAGE_DISABLED, MENUPAGE_DISABLED, nil, nil,
- MENUACTION_CHANGEMENU, "FEN_STA", { nil, SAVESLOT_NONE, MENUPAGE_NEW_GAME },
- MENUACTION_CHANGEMENU, "FET_OPT", { nil, SAVESLOT_NONE, MENUPAGE_OPTIONS },
- MENUACTION_CHANGEMENU, "FEM_QT", { nil, SAVESLOT_NONE, MENUPAGE_EXIT },
+ // MENUPAGE_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 },
-#ifdef MENU_MAP
- MENUACTION_CHANGEMENU, "FEG_MAP", { nil, SAVESLOT_NONE, MENUPAGE_MAP },
-#endif
- 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 },
- INVERT_PAD_SELECTOR
- 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_GRA", 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_GRA", 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
#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
PIPELINES_SELECTOR
ISLAND_LOADING_SELECTOR
DUALPASS_SELECTOR
- MENUACTION_CFO_DYNAMIC, "FET_DEF", { new CCFODynamic(nil, nil, nil, RestoreDefGraphics) },
- MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
+ MENUACTION_CFO_DYNAMIC, "FET_DEF", { new CCFODynamic(nil, nil, nil, RestoreDefGraphics) }, 320, 0, MENUALIGN_CENTER,
+ MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 320, 0, MENUALIGN_CENTER,
},
#endif
#ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS
// 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}), nil,
+ { "FEC_JOD", MENUPAGE_CONTROLLER_PC, new CCustomScreenLayout({0, 0, 0, false, false, 30}), nil,
- MENUACTION_LABEL, "FEC_JPR", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
- MENUACTION_CFO_DYNAMIC, "FEC_JDE", { new CCFODynamic(nil, nil, DetectJoystickDraw, nil) },
- MENUACTION_CHANGEMENU, "FEDS_TB", { nil, SAVESLOT_NONE, MENUPAGE_NONE },
+ MENUACTION_LABEL, "FEC_JPR", { nil, SAVESLOT_NONE, MENUPAGE_NONE }, 0, 0, 0,
+ MENUACTION_CFO_DYNAMIC, "FEC_JDE", { new CCFODynamic(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,
-
- },
-
+ // MENUPAGE_OUTRO = 34
+ { "", 0, nil, nil, },
};
#endif
diff --git a/src/core/Pad.cpp b/src/core/Pad.cpp
index b971f3ec..91e2d704 100644
--- a/src/core/Pad.cpp
+++ b/src/core/Pad.cpp
@@ -40,13 +40,22 @@
#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"
#include "libpad.h"
#endif
+// --MIAMI: file done except Mobile(see TODOs) and PS2 stuff
+
CPad Pads[MAX_PADS];
#ifdef GTA_PS2
u_long128 pad_dma_buf[scePadDmaBufferMax] __attribute__((aligned(64)));
@@ -59,9 +68,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];
@@ -71,7 +80,7 @@ CKeyboardState CPad::OldKeyState;
CKeyboardState CPad::NewKeyState;
CKeyboardState CPad::TempKeyState;
-char CPad::KeyBoardCheatString[20];
+char CPad::KeyBoardCheatString[30];
CMouseControllerState CPad::OldMouseControllerState;
CMouseControllerState CPad::NewMouseControllerState;
@@ -84,62 +93,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()->m_vehType == 5 )
+ {
+ 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);
@@ -153,7 +360,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);
@@ -161,25 +369,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);
@@ -189,6 +406,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()
@@ -196,12 +415,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()
@@ -227,19 +451,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->m_nWantedLevel + 2, 6));
+ FindPlayerPed()->m_pWanted->CheatWantedLevel(Min(FindPlayerPed()->m_pWanted->m_nWantedLevel + 2, 6));
}
void WantedLevelDownCheat()
{
CHud::SetHelpMessage(TheText.Get("CHEAT5"), true);
- FindPlayerPed()->SetWantedLevel(0);
+ FindPlayerPed()->m_pWanted->CheatWantedLevel(0);
}
void SunnyWeatherCheat()
@@ -248,6 +472,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);
@@ -276,25 +506,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 NastyLimbsCheat()
+void TrafficLightsCheat()
{
- CPed::bNastyLimbsCheat = !CPed::bNastyLimbsCheat;
+ 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 RenderWaterLayersCheat(void)
+{
+ 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
@@ -319,7 +625,7 @@ void KangarooCheat()
}
#endif
-#ifdef ALLCARSHELI_CHEAT
+#ifdef RESTORE_ALLCARSHELI_CHEAT
void AllCarsHeliCheat(void)
{
wchar* string;
@@ -335,22 +641,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)
{
@@ -421,6 +739,8 @@ void CPad::Initialise(void)
bObsoleteControllerMessage = false;
bOldDisplayNoControllerMessage = false;
bDisplayNoControllerMessage = false;
+ m_bMapPadOneToPadTwo = false;
+ m_bDebugCamPCOn = false;
}
#endif
@@ -445,12 +765,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;
@@ -464,6 +789,11 @@ void CPad::Clear(bool bResetPlayerControls)
AverageEntries = 0;
}
+uint32 CPad::InputHowLongAgo()
+{
+ return CTimer::GetTimeInMilliseconds() - LastTimeTouched;
+}
+
void CPad::ClearMouseHistory()
{
PCTempMouseControllerState.Clear();
@@ -471,6 +801,14 @@ void CPad::ClearMouseHistory()
OldMouseControllerState.Clear();
}
+// unused
+void CPad::ClearKeyBoardHistory()
+{
+ NewKeyState.Clear();
+ OldKeyState.Clear();
+ TempKeyState.Clear();
+}
+
CMouseControllerState::CMouseControllerState()
{
LMB = 0;
@@ -502,7 +840,7 @@ CMouseControllerState CMousePointerStateHelper::GetMouseSetUp()
#if defined RW_D3D9 || defined RWLIBS
if ( PSGLOBAL(mouse) == nil )
- _InputInitialiseMouse();
+ _InputInitialiseMouse(!FrontEndMenuManager.m_bMenuActive && _InputMouseNeedsExclusive());
if ( PSGLOBAL(mouse) != nil )
{
@@ -556,7 +894,7 @@ void CPad::UpdateMouse()
if ( IsForegroundApp() )
{
if ( PSGLOBAL(mouse) == nil )
- _InputInitialiseMouse();
+ _InputInitialiseMouse(!FrontEndMenuManager.m_bMenuActive && _InputMouseNeedsExclusive());
DIMOUSESTATE2 state;
@@ -700,7 +1038,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 )
@@ -722,7 +1060,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 )
@@ -749,7 +1087,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 )
@@ -783,7 +1121,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") )
@@ -823,7 +1161,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") )
@@ -869,119 +1207,322 @@ 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();
#undef _CHEATCMP
}
#endif
+int Cheat_strncmp(char* sourceStr, char* origCheatStr)
+{
+ char cheatCodeVals[] = { 3,5,7,1,13,27,3,7,1,11,13,8,7,32,13,6,28,19,10,3,3,5,7,1,13,27,3,7 };
+
+ for (uint32 i = 0; i < strlen(origCheatStr); i++) {
+ if ((sourceStr[i] != origCheatStr[i] - cheatCodeVals[i]) || i >= ARRAY_SIZE(cheatCodeVals)) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+// 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)
+#define _CHEATCMP(str) strncmp(str, KeyBoardCheatString, sizeof(str)-1)
- // "GUNSGUNSGUNS"
- if ( !_CHEATCMP("SNUGSNUGSNUG") )
- WeaponCheat();
-
- // "IFIWEREARICHMAN"
- if ( !_CHEATCMP("NAMHCIRAEREWIFI") )
- MoneyCheat();
-
- // "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"
@@ -995,19 +1536,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
- #undef _CHEATCMP
+#if !defined(PC_WATER) && defined(WATER_CHEATS)
+ // SEABEDCHEAT
+ if (!_CHEATCMP("TAEHCDEBAESON"))
+ NoSeaBedCheat();
+
+ // WATERLAYERSCHEAT
+ if (!_CHEATCMP("TAEHCSREYALRETAW"))
+ RenderWaterLayersCheat();
+#endif
+
+#undef _CHEATCMP
}
#ifdef XINPUT
@@ -1105,15 +1656,13 @@ void CPad::UpdatePads(void)
IsAffectedByController = false;
#endif
- if ( CReplay::IsPlayingBackFromFile() )
+ if ( CReplay::IsPlayingBackFromFile() && !FrontEndMenuManager.m_bMenuActive )
bUpdate = false;
if ( bUpdate )
{
GetPad(0)->Update(0);
-#ifndef SQUEEZE_PERFORMANCE
- GetPad(1)->Update(0);
-#endif
+ // GetPad(1)->Update(0); // not in VC
}
#if defined(MASTER) && !defined(XINPUT)
@@ -1408,14 +1957,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)
@@ -1500,12 +2058,12 @@ CPad *CPad::GetPad(int32 pad)
#define CURMODE (Mode)
#endif
-
int16 CPad::GetSteeringLeftRight(void)
{
if ( ArePlayerControlsDisabled() )
return 0;
+ int16 value;
switch (CURMODE)
{
case 0:
@@ -1515,9 +2073,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;
}
@@ -1525,13 +2086,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)
@@ -1545,7 +2111,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;
@@ -1654,7 +2220,6 @@ int16 CPad::GetPedWalkLeftRight(void)
return 0;
}
-
int16 CPad::GetPedWalkUpDown(void)
{
if ( ArePlayerControlsDisabled() )
@@ -1718,6 +2283,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() )
@@ -1829,7 +2424,6 @@ bool CPad::HornJustDown(void)
return false;
}
-
bool CPad::GetCarGunFired(void)
{
if ( ArePlayerControlsDisabled() )
@@ -1960,6 +2554,10 @@ bool CPad::GetExitVehicle(void)
if ( ArePlayerControlsDisabled() )
return false;
+
+ if ( JustOutOfFrontend != 0 )
+ return false;
+
switch (CURMODE)
{
case 0:
@@ -1987,6 +2585,9 @@ bool CPad::ExitVehicleJustDown(void)
if ( ArePlayerControlsDisabled() )
return false;
+ if ( JustOutOfFrontend != 0 )
+ return false;
+
switch (CURMODE)
{
case 0:
@@ -2113,6 +2714,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)
@@ -2200,7 +2848,6 @@ bool CPad::ChangeStationJustDown(void)
return false;
}
-
bool CPad::CycleWeaponLeftJustDown(void)
{
if ( ArePlayerControlsDisabled() )
@@ -2271,6 +2918,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() )
@@ -2319,23 +3006,23 @@ bool CPad::ShiftTargetRightJustDown(void)
if ( ArePlayerControlsDisabled() )
return false;
- return !!(NewState.RightShoulder2 && !OldState.RightShoulder2);
+ return !!(NewState.LeftShoulder1 && !OldState.LeftShoulder1) || !!(NewState.RightShoulder2 && !OldState.RightShoulder2);
}
bool CPad::GetAnaloguePadUp(void)
{
static int16 oldfStickY = 0;
- int16 Y = CPad::GetPad(0)->GetAnalogueUpDown();
+ int16 leftStickY = CPad::GetPad(0)->GetLeftStickY();
- if ( Y < 0 && oldfStickY >= 0 )
+ if ( leftStickY < -15 && oldfStickY >= -5 )
{
- oldfStickY = Y;
+ oldfStickY = leftStickY;
return true;
}
else
{
- oldfStickY = Y;
+ oldfStickY = leftStickY;
return false;
}
}
@@ -2344,16 +3031,16 @@ bool CPad::GetAnaloguePadDown(void)
{
static int16 oldfStickY = 0;
- int16 Y = CPad::GetPad(0)->GetAnalogueUpDown();
+ int16 leftStickY = CPad::GetPad(0)->GetLeftStickY();
- if ( Y > 0 && oldfStickY <= 0 )
+ if ( leftStickY > 15 && oldfStickY <= 5 )
{
- oldfStickY = Y;
+ oldfStickY = leftStickY;
return true;
}
else
{
- oldfStickY = Y;
+ oldfStickY = leftStickY;
return false;
}
}
@@ -2362,16 +3049,16 @@ bool CPad::GetAnaloguePadLeft(void)
{
static int16 oldfStickX = 0;
- int16 X = CPad::GetPad(0)->GetPedWalkLeftRight();
+ int16 leftStickX = CPad::GetPad(0)->GetLeftStickX();
- if ( X < 0 && oldfStickX >= 0 )
+ if ( leftStickX < -15 && oldfStickX >= -5 )
{
- oldfStickX = X;
+ oldfStickX = leftStickX;
return true;
}
else
{
- oldfStickX = X;
+ oldfStickX = leftStickX;
return false;
}
}
@@ -2380,16 +3067,16 @@ bool CPad::GetAnaloguePadRight(void)
{
static int16 oldfStickX = 0;
- int16 X = CPad::GetPad(0)->GetPedWalkLeftRight();
+ int16 leftStickX = CPad::GetPad(0)->GetLeftStickX();
- if ( X > 0 && oldfStickX <= 0 )
+ if ( leftStickX > 15 && oldfStickX <= 5 )
{
- oldfStickX = X;
+ oldfStickX = leftStickX;
return true;
}
else
{
- oldfStickX = X;
+ oldfStickX = leftStickX;
return false;
}
}
@@ -2528,9 +3215,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;
}
@@ -2538,23 +3229,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;
}
@@ -2576,14 +3268,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) )
@@ -2596,7 +3285,6 @@ int16 CPad::LookAroundUpDown(void)
return 0;
}
-
void CPad::ResetAverageWeapon(void)
{
AverageWeapon = GetWeapon();
@@ -2605,37 +3293,42 @@ void CPad::ResetAverageWeapon(void)
void CPad::PrintErrorMessage(void)
{
+ if (TheCamera.m_WideScreenOn)
+ return;
+
if ( bDisplayNoControllerMessage && !CGame::playingIntro && !FrontEndMenuManager.m_bMenuActive )
{
- CFont::SetScale(0.85f, 1.0f);
+ 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));
+ CFont::SetScale(SCREEN_SCALE_X(0.85f), SCREEN_SCALE_Y(1.0f));
CFont::SetJustifyOff();
CFont::SetBackgroundOff();
- CFont::SetCentreSize(SCREEN_SCALE_X(SCREEN_WIDTH - 20));
+ CFont::SetCentreSize(SCREEN_SCALE_X(590.0f));
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 )
{
- CFont::SetScale(0.85f, 1.0f);
+ 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));
+ CFont::SetScale(SCREEN_SCALE_X(0.85f), SCREEN_SCALE_Y(1.0f));
CFont::SetJustifyOff();
CFont::SetBackgroundOff();
- CFont::SetCentreSize(SCREEN_SCALE_X(SCREEN_WIDTH - 20));
+ CFont::SetCentreSize(SCREEN_SCALE_X(590.0f));
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).
);
}
@@ -2653,20 +3346,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)
@@ -2871,3 +3577,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 20a676ef..9f9f81b6 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
void AffectFromXinput(uint32 pad);
@@ -423,6 +436,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); }
@@ -448,15 +462,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; }
@@ -466,7 +481,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 69b3d3ea..6efc1540 100644
--- a/src/core/Placeable.cpp
+++ b/src/core/Placeable.cpp
@@ -7,8 +7,6 @@ CPlaceable::CPlaceable(void)
m_matrix.SetScale(1.0f);
}
-CPlaceable::~CPlaceable(void) = default;
-
void
CPlaceable::SetHeading(float angle)
{
diff --git a/src/core/Placeable.h b/src/core/Placeable.h
index 970c0d48..22f7583c 100644
--- a/src/core/Placeable.h
+++ b/src/core/Placeable.h
@@ -9,7 +9,6 @@ public:
CMatrix m_matrix;
CPlaceable(void);
- virtual ~CPlaceable(void);
const CVector &GetPosition(void) { return m_matrix.GetPosition(); }
void SetPosition(float x, float y, float z) {
m_matrix.GetPosition().x = x;
diff --git a/src/core/PlayerInfo.cpp b/src/core/PlayerInfo.cpp
index 07424736..77ddfdb1 100644
--- a/src/core/PlayerInfo.cpp
+++ b/src/core/PlayerInfo.cpp
@@ -31,7 +31,13 @@
#include "World.h"
#include "ZoneCull.h"
#include "main.h"
+#include "Bike.h"
+#include "Automobile.h"
+#include "GameLogic.h"
+
+// --MIAMI: File done
+CVector lastPlayerPos;
void
CPlayerInfo::Clear(void)
@@ -49,6 +55,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 +68,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 +110,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 +122,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::GetTimeInMilliseconds();
+ 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 +301,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 +310,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_IDLE_STANCE, 100.0f);
- CAnimManager::BlendAnimation(m_pPed->GetClump(), ASSOCGRP_STD, ANIM_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 +349,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 +400,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 +420,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 +430,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 +457,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->m_nWantedLevel && !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->m_nWantedLevel) {
+ 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 +552,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 +578,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 +604,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 +778,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 +809,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 +829,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 +845,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 +869,6 @@ CPlayerInfo::LoadPlayerSkin()
DeletePlayerSkin();
m_pSkinTexture = CPlayerSkin::GetSkinTexture(m_aSkinName);
- if (!m_pSkinTexture)
- m_pSkinTexture = CPlayerSkin::GetSkinTexture(DEFAULT_SKIN_NAME);
}
void
@@ -659,4 +879,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 49424b8b..a3896ebb 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;
+ int32 m_nDistanceCarTravelledOnTwoWheels;
+ int32 m_nTimeNotFullyOnGround;
+ int32 m_nTimeSpentOnWheelie;
+ float m_nDistanceTravelledOnWheelie;
+ int32 m_nTimeSpentOnStoppie;
+ float m_nDistanceTravelledOnStoppie;
+ int32 m_nCancelWheelStuntTimer;
+ int32 m_nLastTimeCarSpentOnTwoWheels;
+ int32 m_nLastDistanceCarTravelledOnTwoWheels;
+ int32 m_nLastTimeSpentOnWheelie;
+ int32 m_nLastDistanceTravelledOnWheelie;
+ int32 m_nLastTimeSpentOnStoppie;
+ int32 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 79841c14..68e6f391 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,8 @@
#include "World.h"
#include "MemoryHeap.h"
+//--MIAMI: file done
+
CCPtrNodePool *CPools::ms_pPtrNodePool;
CEntryInfoNodePool *CPools::ms_pEntryInfoNodePool;
CPedPool *CPools::ms_pPedPool;
@@ -23,6 +26,7 @@ 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
#define CHECKMEM(msg) CMemCheck::AllocateMemCheckBlock(msg)
@@ -35,23 +39,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();
}
@@ -68,6 +74,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;
@@ -79,6 +86,7 @@ CPools::ShutDown(void)
delete ms_pObjectPool;
delete ms_pDummyPool;
delete ms_pAudioScriptObjectPool;
+ delete ms_pColModelPool;
printf("Shutdown pool done\n");
}
@@ -132,7 +140,8 @@ void CPools::LoadVehiclePool(uint8* buf, uint32 size)
INITSAVEBUF
int nNumCars = ReadSaveBuf<int>(buf);
int nNumBoats = ReadSaveBuf<int>(buf);
- for (int i = 0; i < nNumCars + nNumBoats; i++) {
+ int nNumBikes = ReadSaveBuf<int>(buf);
+ for (int i = 0; i < nNumCars + nNumBoats + nNumBikes; i++) {
uint32 type = ReadSaveBuf<uint32>(buf);
int16 model = ReadSaveBuf<int16>(buf);
CStreaming::RequestModel(model, STREAMFLAGS_DEPENDENCY);
@@ -144,13 +153,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));
@@ -169,6 +180,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;
@@ -206,6 +228,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
@@ -218,6 +241,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);
@@ -239,19 +263,25 @@ INITSAVEBUF
++nNumCars;
if (pVehicle->IsBoat() && (pVehicle->VehicleCreatedBy == MISSION_VEHICLE || bForceSaving))
++nNumBoats;
+ if (pVehicle->IsBike() && (pVehicle->VehicleCreatedBy == MISSION_VEHICLE || bForceSaving))
+ ++nNumBoats;
#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)
+ ++nNumBoats;
#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)
@@ -271,9 +301,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<uint32>(buf, pVehicle->m_vehType);
WriteSaveBuf<int16>(buf, pVehicle->GetModelIndex());
@@ -303,6 +333,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, (uint32)pVehicle->m_vehType);
+ WriteSaveBuf(buf, pVehicle->GetModelIndex());
+ WriteSaveBuf(buf, GetVehicleRef(pVehicle));
+ memcpy(buf, pVehicle, sizeof(CBike));
+ SkipSaveBuf(buf, sizeof(CBike));
+ }
#endif
}
}
@@ -324,8 +365,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);
@@ -356,6 +398,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);
@@ -405,6 +450,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);
@@ -439,6 +487,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;
}
@@ -561,8 +611,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 816da6b9..8fe900ae 100644
--- a/src/core/Radar.cpp
+++ b/src/core/Radar.cpp
@@ -15,55 +15,96 @@
#include "World.h"
#include "Streaming.h"
#include "SpecialFX.h"
+#include "Font.h"
+
+// --MIAMI: file done
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
@@ -83,12 +124,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;
@@ -219,18 +263,16 @@ int LineRadarBoxCollision(CVector2D &out, const CVector2D &p1, const CVector2D &
return edge;
}
-
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;
}
@@ -269,12 +311,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
}
}
@@ -374,9 +413,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;
@@ -394,7 +432,7 @@ void CRadar::Draw3dMarkers()
if (ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY) {
CVector pos = entity->GetPosition();
pos.z += 1.2f * CModelInfo::GetModelInfo(entity->GetModelIndex())->GetColModel()->boundingBox.max.z + 2.5f;
- C3dMarkers::PlaceMarker(i | (ms_RadarTrace[i].m_BlipIndex << 16), 1, pos, 2.5f, 0, 128, 255, 255, 1024, 0.2f, 5);
+ C3dMarkers::PlaceMarker(i | (ms_RadarTrace[i].m_BlipIndex << 16), 1, pos, 2.5f, CARBLIP_MARKER_COLOR_R, CARBLIP_MARKER_COLOR_G, CARBLIP_MARKER_COLOR_B, CARBLIP_MARKER_COLOR_A, 1024, 0.2f, 5);
}
break;
}
@@ -408,7 +446,7 @@ void CRadar::Draw3dMarkers()
if (ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY) {
CVector pos = entity->GetPosition();
pos.z += 3.0f;
- C3dMarkers::PlaceMarker(i | (ms_RadarTrace[i].m_BlipIndex << 16), 1, pos, 1.5f, 0, 128, 255, 255, 1024, 0.2f, 5);
+ C3dMarkers::PlaceMarker(i | (ms_RadarTrace[i].m_BlipIndex << 16), 1, pos, 1.5f, CHARBLIP_MARKER_COLOR_R, CHARBLIP_MARKER_COLOR_G, CHARBLIP_MARKER_COLOR_B, CHARBLIP_MARKER_COLOR_A, 1024, 0.2f, 5);
}
break;
}
@@ -418,7 +456,7 @@ void CRadar::Draw3dMarkers()
if (ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY) {
CVector pos = entity->GetPosition();
pos.z += CModelInfo::GetModelInfo(entity->GetModelIndex())->GetColModel()->boundingBox.max.z + 1.0f + 1.0f;
- C3dMarkers::PlaceMarker(i | (ms_RadarTrace[i].m_BlipIndex << 16), 1, pos, 1.0f, 0, 128, 255, 255, 1024, 0.2f, 5);
+ C3dMarkers::PlaceMarker(i | (ms_RadarTrace[i].m_BlipIndex << 16), 1, pos, 1.0f, OBJECTBLIP_MARKER_COLOR_R, OBJECTBLIP_MARKER_COLOR_G, OBJECTBLIP_MARKER_COLOR_B, OBJECTBLIP_MARKER_COLOR_A, 1024, 0.2f, 5);
}
break;
}
@@ -427,7 +465,7 @@ void CRadar::Draw3dMarkers()
case BLIP_CONTACT_POINT:
if (!CTheScripts::IsPlayerOnAMission()) {
if (ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_BOTH || ms_RadarTrace[i].m_eBlipDisplay == BLIP_DISPLAY_MARKER_ONLY)
- C3dMarkers::PlaceMarkerSet(i | (ms_RadarTrace[i].m_BlipIndex << 16), 4, ms_RadarTrace[i].m_vecPos, 2.0f, 0, 128, 255, 128, 2048, 0.2f, 0);
+ C3dMarkers::PlaceMarkerSet(i | (ms_RadarTrace[i].m_BlipIndex << 16), 4, ms_RadarTrace[i].m_vecPos, 2.0f, COORDBLIP_MARKER_COLOR_R, COORDBLIP_MARKER_COLOR_G, COORDBLIP_MARKER_COLOR_B, COORDBLIP_MARKER_COLOR_A, 2048, 0.2f, 0);
}
break;
}
@@ -449,9 +487,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();
@@ -471,17 +507,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;
@@ -489,165 +517,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;
@@ -660,65 +588,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)
@@ -732,14 +630,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)
@@ -817,6 +714,7 @@ void CRadar::DrawRadarMask()
#if !defined(GTA_PS2_STUFF) && defined(RWLIBS)
RwD3D8SetRenderState(D3DRS_ALPHAFUNC, D3DCMP_GREATER);
#endif
+
}
void CRadar::DrawRadarSection(int32 x, int32 y)
@@ -834,11 +732,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++)
@@ -856,8 +751,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);
@@ -866,6 +768,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)
@@ -974,6 +888,7 @@ CRadar::Initialise()
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;
@@ -989,10 +904,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;
@@ -1007,37 +922,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++)
- ms_RadarTrace[i] = ReadSaveBuf<sRadarTrace>(buf);
+ for (int i = 0; i < NUMRADARBLIPS; i++) {
+ ms_RadarTrace[i].m_nColor = ReadSaveBuf<uint32>(buf);
+ ms_RadarTrace[i].m_Radius = ReadSaveBuf<float>(buf);
+ ms_RadarTrace[i].m_eBlipType = ReadSaveBuf<uint32>(buf);
+ ms_RadarTrace[i].m_nEntityHandle = ReadSaveBuf<int32>(buf);
+ ms_RadarTrace[i].m_vec2DPos.x = ReadSaveBuf<float>(buf); // CVector2D
+ ms_RadarTrace[i].m_vec2DPos.y = ReadSaveBuf<float>(buf);
+ ms_RadarTrace[i].m_vecPos = ReadSaveBuf<CVector>(buf);
+ ms_RadarTrace[i].m_BlipIndex = ReadSaveBuf<uint16>(buf);
+ ms_RadarTrace[i].m_bDim = ReadSaveBuf<bool>(buf);
+ ms_RadarTrace[i].m_bInUse = ReadSaveBuf<bool>(buf);
+ ms_RadarTrace[i].m_bShortRange = ReadSaveBuf<bool>(buf);
+ ms_RadarTrace[i].m_unused = ReadSaveBuf<bool>(buf);
+ ms_RadarTrace[i].m_wScale = ReadSaveBuf<int16>(buf);
+ ms_RadarTrace[i].m_eBlipDisplay = ReadSaveBuf<uint16>(buf);
+ ms_RadarTrace[i].m_eRadarSprite = ReadSaveBuf<uint16>(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();
}
@@ -1048,25 +1035,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
- if (TargetMarkerId != -1) {
- ClearBlip(TargetMarkerId);
- TargetMarkerId = -1;
- }
-#endif
-
- for (int i = 0; i < NUMRADARBLIPS; i++)
- WriteSaveBuf(buf, ms_RadarTrace[i]);
-
-VALIDATESAVEBUF(*size);
-}
-
void CRadar::SetBlipSprite(int32 i, int32 icon)
{
int index = CRadar::GetActualBlipArrayIndex(i);
@@ -1075,7 +1043,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++) {
@@ -1087,9 +1055,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;
@@ -1100,7 +1069,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++) {
@@ -1112,9 +1090,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;
@@ -1183,12 +1162,12 @@ void CRadar::ShowRadarTraceWithHeight(float x, float y, uint32 size, uint8 red,
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;
@@ -1201,32 +1180,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)
@@ -1252,33 +1251,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;
@@ -1289,14 +1263,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
@@ -1309,35 +1279,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);
@@ -1349,11 +1292,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) {
@@ -1374,20 +1314,25 @@ 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
CRadar::DrawYouAreHereSprite(float x, float y)
{
- static uint32 lastChange = 0;
+ static PauseModeTime lastChange = 0;
static bool show = true;
if (show) {
@@ -1403,14 +1348,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)
{
@@ -1420,10 +1384,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;
@@ -1445,3 +1409,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 PauseModeTime 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 793d62b0..8f2e7069 100644
--- a/src/core/Radar.h
+++ b/src/core/Radar.h
@@ -1,6 +1,35 @@
#pragma once
#include "Sprite2d.h"
+#define CARBLIP_MARKER_COLOR_R 252
+#define CARBLIP_MARKER_COLOR_G 138
+#define CARBLIP_MARKER_COLOR_B 242
+#define CARBLIP_MARKER_COLOR_A 255
+
+#define CHARBLIP_MARKER_COLOR_R 252
+#define CHARBLIP_MARKER_COLOR_G 138
+#define CHARBLIP_MARKER_COLOR_B 242
+#define CHARBLIP_MARKER_COLOR_A 255
+
+#define OBJECTBLIP_MARKER_COLOR_R 252
+#define OBJECTBLIP_MARKER_COLOR_G 138
+#define OBJECTBLIP_MARKER_COLOR_B 242
+#define OBJECTBLIP_MARKER_COLOR_A 255
+
+#define COORDBLIP_MARKER_COLOR_R 252
+#define COORDBLIP_MARKER_COLOR_G 138
+#define COORDBLIP_MARKER_COLOR_B 242
+#define COORDBLIP_MARKER_COLOR_A 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,
@@ -21,31 +50,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
};
@@ -72,21 +119,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)
-#define RADAR_BOTTOM (47.0f)
+#define RADAR_BOTTOM (40.0f)
#define RADAR_WIDTH (94.0f)
#define RADAR_HEIGHT (76.0f)
@@ -95,35 +164,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);
@@ -153,8 +248,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);
@@ -166,7 +262,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/Ropes.cpp b/src/core/Ropes.cpp
new file mode 100644
index 00000000..dbae9ee3
--- /dev/null
+++ b/src/core/Ropes.cpp
@@ -0,0 +1,173 @@
+#include "common.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;
+ for(i = 0; i < ARRAY_SIZE(aRopes); i++)
+ if(aRopes[i].m_bActive)
+ aRopes[i].Render();
+}
+
+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(CRope::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(CRope::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_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..8d61c484 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,158 @@ 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;
+
+// --MIAMI: functions below are done, but there are some to be moved from Frontend
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 +241,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 +262,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 +296,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 +499,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 +524,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 +614,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 +689,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 +714,728 @@ 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])
+ STAT_LINE_1(float, "STFT_22", FastestTimes[21] / 1000, 1);
+
+ 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 5dfcf803..7fa69396 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 03b49fd6..afc6704d 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"
+
+//--MIAMI: file done (possibly bugs)
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,10 @@ 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;
bool
CStreamingInfo::GetCdPosnAndSize(uint32 &posn, uint32 &size)
@@ -189,14 +185,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();
@@ -214,77 +213,78 @@ 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);
-
- 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;
- }
+ pIslandLODmainlandEntity = nil;
+ pIslandLODbeachEntity = nil;
+ islandLODmainland = -1;
+ islandLODbeach = -1;
+ CModelInfo::GetModelInfo("IslandLODmainland", &islandLODmainland);
+ CModelInfo::GetModelInfo("IslandLODbeach", &islandLODbeach);
}
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;
@@ -300,7 +300,6 @@ uint64 timeProcessingDFF;
void
CStreaming::Update(void)
{
- CEntity *train;
CStreamingInfo *si, *prev;
bool requestedSubway = false;
@@ -319,39 +318,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;
@@ -373,12 +369,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
@@ -398,8 +388,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;
@@ -410,24 +399,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
@@ -437,55 +425,61 @@ 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);
}
-#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
- return atomic;
+static char*
+GetObjectName(int streamId)
+{
+ static char objname[32];
+ if(streamId < STREAM_OFFSET_TXD)
+ sprintf(objname, "%s.dff", CModelInfo::GetModelInfo(streamId)->GetName());
+ 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;
}
-#endif
+
bool
CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId)
@@ -508,26 +502,27 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId)
// Model
mi = CModelInfo::GetModelInfo(streamId);
- // Txd has to be loaded
- if(CTxdStore::GetSlot(mi->GetTxdSlot())->texDict == nil){
- debug("failed to load %s because TXD %s is not in memory\n", mi->GetName(), CTxdStore::GetTxdName(mi->GetTxdSlot()));
+ // Txd and anim have to be loaded
+ int animId = mi->GetAnimFileIndex();
+ if(CTxdStore::GetSlot(mi->GetTxdSlot())->texDict == nil ||
+ animId != -1 && !CAnimManager::GetAnimationBlock(animId)->isLoaded){
RemoveModel(streamId);
- RemoveTxd(mi->GetTxdSlot());
ReRequestModel(streamId);
RwStreamClose(stream, &mem);
return false;
}
- // Set Txd to use
+ // Set Txd and anims to use
CTxdStore::AddRef(mi->GetTxdSlot());
+ if(animId != -1)
+ CAnimManager::AddAnimBlockRef(animId);
+ CTxdStore::SetCurrentTxd(mi->GetTxdSlot());
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();
@@ -544,9 +539,12 @@ 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(animId != -1)
+ CAnimManager::RemoveAnimBlockRefWithoutDelete(animId);
+ }
if(!success){
debug("Failed to load %s\n", CModelInfo::GetModelInfo(streamId)->GetName());
@@ -555,9 +553,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);
@@ -582,20 +579,28 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId)
RwStreamClose(stream, &mem);
return false;
}
+ }else if(streamId >= STREAM_OFFSET_COL && streamId < STREAM_OFFSET_ANIM){
+ if(!CColStore::LoadCol(streamId-STREAM_OFFSET_COL, mem.start, mem.length)){
+ 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;
+ }
+ CAnimManager::LoadAnimFile(stream, true, nil);
+ CAnimManager::CreateAnimAssocGroups();
}
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->GetName());
- 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
@@ -610,12 +615,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);
}
@@ -629,17 +636,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)->GetName(), 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)
{
@@ -676,13 +678,17 @@ CStreaming::FinishLoadingLargeFile(int8 *buf, int32 streamId)
POP_MEMID();
mi->RemoveRef();
CTxdStore::RemoveRefWithoutDelete(mi->GetTxdSlot());
- }else{
+ if(mi->GetAnimFileIndex() != -1)
+ CAnimManager::RemoveAnimBlockRefWithoutDelete(mi->GetAnimFileIndex());
+ }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);
@@ -703,12 +709,8 @@ CStreaming::FinishLoadingLargeFile(int8 *buf, int32 streamId)
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)->GetName(), 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;
}
@@ -741,15 +743,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)
@@ -761,52 +768,26 @@ 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 && b->m_level == level)
+ 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;
@@ -815,41 +796,142 @@ CStreaming::RequestBigBuildings(eLevelName level)
for(i = n; i >= 0; i--){
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)
- ) || (b->m_level == level))
-#else
+#ifndef NO_ISLAND_LOADING
&& 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
CStreaming::RequestIslands(eLevelName level)
{
- ISLAND_LOADING_ISNT(HIGH)
+#ifndef NO_ISLAND_LOADING
switch(level){
- case LEVEL_INDUSTRIAL:
- RequestModel(islandLODcomInd, BIGBUILDINGFLAGS);
- RequestModel(islandLODsubInd, BIGBUILDINGFLAGS);
- break;
- case LEVEL_COMMERCIAL:
- RequestModel(islandLODindust, BIGBUILDINGFLAGS);
- RequestModel(islandLODsubCom, BIGBUILDINGFLAGS);
+ case LEVEL_MAINLAND:
+ if(islandLODbeach != -1)
+ RequestModel(islandLODbeach, BIGBUILDINGFLAGS);
break;
- case LEVEL_SUBURBAN:
- RequestModel(islandLODindust, BIGBUILDINGFLAGS);
- RequestModel(islandLODcomSub, BIGBUILDINGFLAGS);
+ case LEVEL_BEACH:
+ if(islandLODmainland != -1)
+ RequestModel(islandLODmainland, BIGBUILDINGFLAGS);
break;
default: break;
}
+#endif
}
+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)
{
@@ -857,14 +939,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)->GetName();
+ for(int i = 0; CSnames[i][0]; i++){
+ if(strcasecmp(curname, IGnames[i]) == 0){
+ modelName = CSnames[i];
+ break;
+ }
+ }
+ }
if(!CGeneral::faststrcmp(mi->GetName(), 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->GetName());
mi->SetName(modelName);
@@ -930,13 +1041,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){
@@ -956,11 +1069,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;
@@ -969,12 +1085,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
@@ -1038,17 +1152,69 @@ CStreaming::RemoveBuildings(eLevelName level)
}
void
-CStreaming::RemoveUnusedBigBuildings(eLevelName level)
+CStreaming::RemoveBuildingsNotInArea(int32 area)
{
- 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);
+ 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)
+{
+#ifndef NO_ISLAND_LOADING
+ if(level != LEVEL_BEACH)
+ RemoveBigBuildings(LEVEL_BEACH);
+ if(level != LEVEL_MAINLAND)
+ RemoveBigBuildings(LEVEL_MAINLAND);
+#endif
RemoveIslandsNotUsed(level);
}
@@ -1068,39 +1234,29 @@ DeleteIsland(CEntity *island)
void
CStreaming::RemoveIslandsNotUsed(eLevelName level)
{
-#ifdef NO_ISLAND_LOADING
- if (CMenuManager::m_PrefsIslandLoading == CMenuManager::ISLAND_LOADING_HIGH) {
- DeleteIsland(pIslandLODindustEntity);
- DeleteIsland(pIslandLODcomIndEntity);
- DeleteIsland(pIslandLODcomSubEntity);
- DeleteIsland(pIslandLODsubIndEntity);
- DeleteIsland(pIslandLODsubComEntity);
- } else
-#endif
+#ifndef NO_ISLAND_LOADING
+ 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;
+ }
+
switch(level){
- case LEVEL_INDUSTRIAL:
- DeleteIsland(pIslandLODindustEntity);
- DeleteIsland(pIslandLODcomSubEntity);
- DeleteIsland(pIslandLODsubComEntity);
- break;
- case LEVEL_COMMERCIAL:
- DeleteIsland(pIslandLODcomIndEntity);
- DeleteIsland(pIslandLODcomSubEntity);
- DeleteIsland(pIslandLODsubIndEntity);
+ case LEVEL_MAINLAND:
+ DeleteIsland(pIslandLODmainlandEntity);
break;
- case LEVEL_SUBURBAN:
- DeleteIsland(pIslandLODsubIndEntity);
- DeleteIsland(pIslandLODsubComEntity);
- DeleteIsland(pIslandLODcomIndEntity);
- break;
- default:
- DeleteIsland(pIslandLODindustEntity);
- DeleteIsland(pIslandLODcomIndEntity);
- DeleteIsland(pIslandLODcomSubEntity);
- DeleteIsland(pIslandLODsubIndEntity);
- DeleteIsland(pIslandLODsubComEntity);
+ case LEVEL_BEACH:
+ DeleteIsland(pIslandLODbeachEntity);
+
break;
}
+#endif // !NO_ISLAND_LOADING
}
void
@@ -1134,8 +1290,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;
}
@@ -1144,31 +1299,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
@@ -1181,7 +1348,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;
@@ -1189,28 +1355,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
@@ -1241,6 +1412,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)
{
@@ -1272,8 +1471,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)
@@ -1289,13 +1488,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;
}
@@ -1307,45 +1514,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);
@@ -1382,17 +1554,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
@@ -1420,11 +1594,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);
}
@@ -1444,34 +1618,80 @@ 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) ||
+ (i != 0 && zone.carThreshold[i] != zone.carThreshold[i-1]))) {
+ 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);
@@ -1480,6 +1700,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]);
@@ -1488,63 +1709,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)->GetName());
+ if(ms_numPedsLoaded == MAXZONEPEDSLOADED){
+ SetModelIsDeletable(oldMI);
+ SetModelTxdIsDeletable(oldMI);
+ debug("Remove Ped %s\n", CModelInfo::GetModelInfo(oldMI)->GetName());
+ }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
@@ -1552,19 +1811,32 @@ 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 &&
+ CPopulation::ms_pPedGroups[ms_currentPedGrp].models[i] != MI_MALE01) {
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;
@@ -1572,6 +1844,41 @@ 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;
+ 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));
+
+ CStreaming::RequestBigBuildings(CGame::currLevel, TheCamera.GetPosition());
+ CStreaming::LoadAllRequestedModels(false);
+
+ CGame::TidyUpMemory(true, true);
+ CTimer::Resume();
+ DMAudio.SetEffectsFadeVol(127);
+}
+
// Find starting offset of the cdimage we next want to read
// Not useful at all on PC...
@@ -1618,6 +1925,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
@@ -1642,14 +1950,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){
@@ -1704,13 +2018,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
@@ -1747,7 +2066,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)
@@ -1828,10 +2148,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());
@@ -1937,6 +2257,7 @@ CStreaming::LoadAllRequestedModels(bool priority)
if(bInsideLoadAll)
return;
+ bInsideLoadAll = true;
FlushChannels();
imgOffset = GetCdImageOffset(CdStreamGetLastPosn());
@@ -2034,18 +2355,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)){
@@ -2149,7 +2478,7 @@ CStreaming::UpdateMemoryUsed(void)
#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;
@@ -2183,23 +2512,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;
@@ -2213,8 +2542,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());
@@ -2223,15 +2551,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;
@@ -2243,12 +2570,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);
}
}
}
@@ -2464,6 +2789,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
@@ -2486,9 +2816,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){
@@ -2528,6 +2855,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
@@ -2550,8 +2881,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++){
@@ -2564,6 +2896,8 @@ CStreaming::DeleteRwObjectsBehindCamera(size_t mem)
}
}
}
+
+ while(ms_memoryUsed >= mem && RemoveLeastUsedModel(0));
}
void
@@ -2589,13 +2923,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();
}
}
@@ -2610,7 +2944,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());
@@ -2631,7 +2966,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());
@@ -2651,12 +2986,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;
}
@@ -2676,17 +3011,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;
@@ -2715,9 +3077,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 ee9183a5..510da7a0 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,
@@ -90,11 +93,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;
@@ -107,6 +111,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);
@@ -115,14 +120,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);
@@ -131,29 +147,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);
+ 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);
@@ -170,9 +191,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);
@@ -183,6 +204,7 @@ public:
static bool DeleteRwObjectsNotInFrustumInSectorList(CPtrList &list, size_t mem);
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..56cea203 100644
--- a/src/core/SurfaceTable.cpp
+++ b/src/core/SurfaceTable.cpp
@@ -6,6 +6,8 @@
#include "Collision.h"
#include "SurfaceTable.h"
+//--MIAMI: file done
+
float CSurfaceTable::ms_aAdhesiveLimitTable[NUMADHESIVEGROUPS][NUMADHESIVEGROUPS];
void
@@ -74,7 +76,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 +91,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 +112,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 +136,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 +150,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..cd08c843 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,31 @@ 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_METAL_CHAIN_FENCE:
+ case SURFACE_TRANSPARENT_STONE:
+ case SURFACE_SCAFFOLD_POLE:
return true;
return false;
}
@@ -77,4 +96,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 ed5580fd..bdef6187 100644
--- a/src/core/Timer.cpp
+++ b/src/core/Timer.cpp
@@ -5,9 +5,13 @@
#include "DMAudio.h"
#include "Record.h"
#include "Timer.h"
+#include "SpecialFX.h"
+
+// --MIAMI: file done
uint32 CTimer::m_snTimeInMilliseconds;
-uint32 CTimer::m_snTimeInMillisecondsPauseMode = 1;
+PauseModeTime CTimer::m_snTimeInMillisecondsPauseMode = 1;
+
uint32 CTimer::m_snTimeInMillisecondsNonClipped;
uint32 CTimer::m_snPreviousTimeInMilliseconds;
uint32 CTimer::m_FrameCounter;
@@ -33,7 +37,7 @@ RsTimerType suspendPcTimer;
uint32 suspendDepth;
-#ifdef FIX_BUGS
+#ifdef FIX_HIGH_FPS_BUGS_ON_FRONTEND
double frameTime;
#endif
@@ -94,10 +98,10 @@ void CTimer::Update(void)
_oldPerfCounter = pc;
- float updInCyclesScaled = updInCycles * ms_fTimeScale;
+ float updInCyclesScaled = GetIsPaused() ? updInCycles : updInCycles * ms_fTimeScale;
// We need that real frame time to fix transparent menu bug.
-#ifndef FIX_BUGS
+#ifndef FIX_HIGH_FPS_BUGS_ON_FRONTEND
double
#endif
frameTime = updInCyclesScaled / (double)_nCyclesPerMS;
@@ -121,7 +125,7 @@ void CTimer::Update(void)
RsTimerType updInMs = timer - oldPcTimer;
// We need that real frame time to fix transparent menu bug.
-#ifndef FIX_BUGS
+#ifndef FIX_HIGH_FPS_BUGS_ON_FRONTEND
double
#endif
frameTime = (double)updInMs * ms_fTimeScale;
@@ -140,7 +144,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/Timer.h b/src/core/Timer.h
index 393242dd..53591c4f 100644
--- a/src/core/Timer.h
+++ b/src/core/Timer.h
@@ -1,10 +1,16 @@
#pragma once
+#ifdef FIX_HIGH_FPS_BUGS_ON_FRONTEND
+#define PauseModeTime double
+#else
+#define PauseModeTime uint32
+#endif
+
class CTimer
{
static uint32 m_snTimeInMilliseconds;
- static uint32 m_snTimeInMillisecondsPauseMode;
+ static PauseModeTime m_snTimeInMillisecondsPauseMode;
static uint32 m_snTimeInMillisecondsNonClipped;
static uint32 m_snPreviousTimeInMilliseconds;
static uint32 m_FrameCounter;
@@ -29,7 +35,7 @@ public:
static void SetTimeInMilliseconds(uint32 t) { m_snTimeInMilliseconds = t; }
static uint32 GetTimeInMillisecondsNonClipped(void) { return m_snTimeInMillisecondsNonClipped; }
static void SetTimeInMillisecondsNonClipped(uint32 t) { m_snTimeInMillisecondsNonClipped = t; }
- static uint32 GetTimeInMillisecondsPauseMode(void) { return m_snTimeInMillisecondsPauseMode; }
+ static PauseModeTime GetTimeInMillisecondsPauseMode(void) { return m_snTimeInMillisecondsPauseMode; }
static void SetTimeInMillisecondsPauseMode(uint32 t) { m_snTimeInMillisecondsPauseMode = t; }
static uint32 GetPreviousTimeInMilliseconds(void) { return m_snPreviousTimeInMilliseconds; }
static void SetPreviousTimeInMilliseconds(uint32 t) { m_snPreviousTimeInMilliseconds = t; }
@@ -64,6 +70,6 @@ public:
#endif
};
-#ifdef FIX_BUGS
+#ifdef FIX_HIGH_FPS_BUGS_ON_FRONTEND
extern double frameTime;
#endif
diff --git a/src/core/User.cpp b/src/core/User.cpp
index f906ae44..8d584b74 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"
@@ -10,6 +10,8 @@
#include "World.h"
#include "Zones.h"
+// --MIAMI: file done
+
CPlaceName CUserDisplay::PlaceName;
COnscreenTimer CUserDisplay::OnscnTimer;
CPager CUserDisplay::Pager;
@@ -32,8 +34,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 +76,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 +109,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..f5ea6e53 100644
--- a/src/core/Wanted.cpp
+++ b/src/core/Wanted.cpp
@@ -10,16 +10,21 @@
#include "CopPed.h"
#include "Wanted.h"
#include "General.h"
+#include "Stats.h"
int32 CWanted::MaximumWantedLevel = 6;
-int32 CWanted::nMaximumWantedLevel = 6400;
+int32 CWanted::nMaximumWantedLevel = 9600;
+
+// --MIAMI: File done except stats
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 +36,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 +46,12 @@ CWanted::Initialise()
}
bool
+CWanted::AreMiamiViceRequired()
+{
+ return m_nWantedLevel >= 3;
+}
+
+bool
CWanted::AreSwatRequired()
{
return m_nWantedLevel == 4 || m_bSwatRequired;
@@ -69,7 +81,7 @@ CWanted::NumOfHelisRequired()
return 1;
case 5:
case 6:
- return 2;
+ return 1;
default:
return 0;
}
@@ -87,22 +99,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 +125,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 +148,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 +183,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 +245,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 +291,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 +317,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 +401,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 +482,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 +489,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 +498,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 de36c442..057b5407 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,12 +34,14 @@ public:
public:
void Initialise();
+ bool AreMiamiViceRequired();
bool AreSwatRequired();
bool AreFbiRequired();
bool AreArmyRequired();
int32 NumOfHelisRequired();
void SetWantedLevel(int32);
void SetWantedLevelNoDrop(int32 level);
+ 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();
@@ -48,6 +53,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 b2c1696c..7d5f89b8 100644
--- a/src/core/World.cpp
+++ b/src/core/World.cpp
@@ -15,6 +15,7 @@
#include "Object.h"
#include "ParticleObject.h"
#include "Ped.h"
+#include "Pickups.h"
#include "PlayerPed.h"
#include "Population.h"
#include "ProjectileInfo.h"
@@ -28,6 +29,7 @@
#include "WaterLevel.h"
#include "World.h"
+// --MIAMI: file done
#define OBJECT_REPOSITION_OFFSET_Z 2.0f
@@ -49,13 +51,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;
@@ -64,6 +66,7 @@ CWorld::Initialise()
bIncludeDeadPeds = false;
bForceProcessControl = false;
bIncludeCarTyres = false;
+ bIncludeBikers = false;
}
void
@@ -156,6 +159,7 @@ CWorld::ClearExcitingStuffFromArea(const CVector &pos, float radius, bool bRemov
CProjectileInfo::RemoveAllProjectiles();
CShadows::TidyUpShadows();
}
+ CPickups::RemoveUnnecessaryPickups(pos, radius);
}
bool
@@ -168,7 +172,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;
@@ -187,7 +191,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
@@ -269,50 +273,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;
@@ -323,53 +332,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, dist,
- 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;
@@ -385,7 +404,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);
}
@@ -451,7 +474,7 @@ CWorld::ProcessVerticalLineSectorList(CPtrList &list, const CColLine &line, CCol
colmodel = CModelInfo::GetModelInfo(e->GetModelIndex())->GetColModel();
if(CCollision::ProcessVerticalLine(line, e->GetMatrix(), *colmodel, point, dist,
- ignoreSeeThrough, poly))
+ ignoreSeeThrough, false, poly))
entity = e;
}
}
@@ -652,7 +675,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;
}
}
@@ -699,18 +722,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();
@@ -785,13 +800,18 @@ CWorld::FindObjectsOfTypeInRange(uint32 modelId, const CVector &position, float
*nEntitiesFound = 0;
const CVector2D vecSectorStartPos(position.x - radius, position.y - radius);
const CVector2D vecSectorEndPos(position.x + radius, position.y + radius);
- const int32 nStartX = Max(CWorld::GetSectorIndexX(vecSectorStartPos.x), 0);
- const int32 nStartY = Max(CWorld::GetSectorIndexY(vecSectorStartPos.y), 0);
- const int32 nEndX = Min(CWorld::GetSectorIndexX(vecSectorEndPos.x), NUMSECTORS_X - 1);
- const int32 nEndY = Min(CWorld::GetSectorIndexY(vecSectorEndPos.y), NUMSECTORS_Y - 1);
+ 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 = CWorld::GetSector(x, y);
+ CSector *pSector = GetSector(x, y);
if(bBuildings) {
CWorld::FindObjectsOfTypeInRangeSectorList(
modelId, pSector->m_lists[ENTITYLIST_BUILDINGS], position, radius, bCheck2DOnly,
@@ -923,6 +943,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;
@@ -935,7 +956,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;
@@ -952,11 +974,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) {
@@ -1056,13 +1074,18 @@ CWorld::FindObjectsKindaColliding(const CVector &position, float radius, bool bC
*nCollidingEntities = 0;
const CVector2D vecSectorStartPos(position.x - radius, position.y - radius);
const CVector2D vecSectorEndPos(position.x + radius, position.y + radius);
- const int32 nStartX = Max(CWorld::GetSectorIndexX(vecSectorStartPos.x), 0);
- const int32 nStartY = Max(CWorld::GetSectorIndexY(vecSectorStartPos.y), 0);
- const int32 nEndX = Min(CWorld::GetSectorIndexX(vecSectorEndPos.x), NUMSECTORS_X - 1);
- const int32 nEndY = Min(CWorld::GetSectorIndexY(vecSectorEndPos.y), NUMSECTORS_Y - 1);
+ 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 = CWorld::GetSector(x, y);
+ CSector *pSector = GetSector(x, y);
if(bBuildings) {
CWorld::FindObjectsKindaCollidingSectorList(
pSector->m_lists[ENTITYLIST_BUILDINGS], position, radius, bCheck2DOnly,
@@ -1135,13 +1158,18 @@ CWorld::FindObjectsIntersectingCube(const CVector &vecStartPos, const CVector &v
{
CWorld::AdvanceCurrentScanCode();
*nIntersecting = 0;
- const int32 nStartX = Max(CWorld::GetSectorIndexX(vecStartPos.x), 0);
- const int32 nStartY = Max(CWorld::GetSectorIndexY(vecStartPos.y), 0);
- const int32 nEndX = Min(CWorld::GetSectorIndexX(vecEndPos.x), NUMSECTORS_X - 1);
- const int32 nEndY = Min(CWorld::GetSectorIndexY(vecEndPos.y), NUMSECTORS_Y - 1);
+ const int32 nStartX = Max(GetSectorIndexX(vecStartPos.x), 0);
+ const int32 nStartY = Max(GetSectorIndexY(vecStartPos.y), 0);
+#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 = CWorld::GetSector(x, y);
+ CSector *pSector = GetSector(x, y);
if(bBuildings) {
CWorld::FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_BUILDINGS],
vecStartPos, vecEndPos, nIntersecting,
@@ -1208,7 +1236,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,
@@ -1216,13 +1244,18 @@ CWorld::FindObjectsIntersectingAngledCollisionBox(const CColBox &boundingBox, co
{
CWorld::AdvanceCurrentScanCode();
*nEntitiesFound = 0;
- const int32 nStartX = Max(CWorld::GetSectorIndexX(fStartX), 0);
- const int32 nStartY = Max(CWorld::GetSectorIndexY(fStartY), 0);
- const int32 nEndX = Min(CWorld::GetSectorIndexX(fEndX), NUMSECTORS_X - 1);
- const int32 nEndY = Min(CWorld::GetSectorIndexY(fEndY), NUMSECTORS_Y - 1);
+ 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 = CWorld::GetSector(x, y);
+ CSector *pSector = GetSector(x, y);
if(bBuildings) {
CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList(
pSector->m_lists[ENTITYLIST_BUILDINGS], boundingBox, matrix, position,
@@ -1268,7 +1301,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)
@@ -1296,13 +1329,18 @@ CWorld::FindMissionEntitiesIntersectingCube(const CVector &vecStartPos, const CV
{
CWorld::AdvanceCurrentScanCode();
*nIntersecting = 0;
- const int32 nStartX = Max(CWorld::GetSectorIndexX(vecStartPos.x), 0);
- const int32 nStartY = Max(CWorld::GetSectorIndexY(vecStartPos.y), 0);
- const int32 nEndX = Min(CWorld::GetSectorIndexX(vecEndPos.x), NUMSECTORS_X - 1);
- const int32 nEndY = Min(CWorld::GetSectorIndexY(vecEndPos.y), NUMSECTORS_Y - 1);
+ 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 = CWorld::GetSector(x, y);
+ CSector *pSector = GetSector(x, y);
if(bVehicles) {
CWorld::FindMissionEntitiesIntersectingCubeSectorList(
pSector->m_lists[ENTITYLIST_VEHICLES], vecStartPos, vecEndPos, nIntersecting,
@@ -1414,13 +1452,18 @@ CWorld::CallOffChaseForArea(float x1, float y1, float x2, float y2)
float fStartY = y1 - 10.0f;
float fEndX = x2 + 10.0f;
float fEndY = y2 + 10.0f;
- const int32 nStartX = Max(CWorld::GetSectorIndexX(fStartX), 0);
- const int32 nStartY = Max(CWorld::GetSectorIndexY(fStartY), 0);
- const int32 nEndX = Min(CWorld::GetSectorIndexX(fEndX), NUMSECTORS_X - 1);
- const int32 nEndY = Min(CWorld::GetSectorIndexY(fEndY), NUMSECTORS_Y - 1);
+ 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 = CWorld::GetSector(x, y);
+ CSector *pSector = GetSector(x, y);
CWorld::CallOffChaseForAreaSectorListVehicles(pSector->m_lists[ENTITYLIST_VEHICLES], x1, y1, x2,
y2, fStartX, fStartY, fEndX, fEndY);
CWorld::CallOffChaseForAreaSectorListVehicles(pSector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], x1,
@@ -1548,7 +1591,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);
@@ -1695,9 +1738,6 @@ CWorld::ShutDown(void)
}
}
ms_listMovingEntityPtrs.Flush();
-#if GTA_VERSION <= GTA3_PS2_160
- CPools::Shutdown();
-#endif
}
void
@@ -1745,35 +1785,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 = CWorld::FindGroundZFor3DCoord(position.x, position.y,
- position.z + OBJECT_REPOSITION_OFFSET_Z, nil) -
- fBoundingBoxMinZ;
+ position.z + fHeight, nil) -
+ fBoundingBoxMinZ;
pEntity->m_matrix.UpdateRW();
pEntity->UpdateRwFrame();
- } else if(modelId == MI_BUOY) {
- float fWaterLevel = 0.0f;
+ } 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();
+
+ }
+ if(modelId == MI_BUOY) {
bool bFound = true;
const CVector &position = pEntity->GetPosition();
float fGroundZ = CWorld::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;
}
}
@@ -1792,6 +1853,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();
@@ -1843,10 +1926,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(),
- 0.02f * (csObj->IsObject()
- ? CTimer::GetTimeStepNonClipped()
- : CTimer::GetTimeStep()));
+ if (csObj->IsObject())
+ RpAnimBlendClumpUpdateAnimations(csObj->GetClump(), 0.02f * CTimer::GetTimeStepNonClipped());
+ else {
+ if (!csObj->bOffscreen)
+ csObj->bOffscreen = !csObj->GetIsOnScreen();
+ RpAnimBlendClumpUpdateAnimations(csObj->GetClump(), 0.02f * CTimer::GetTimeStep(), !csObj->bOffscreen);
+ }
}
csObj->ProcessControl();
csObj->ProcessCollision();
@@ -1859,16 +1945,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(),
- 0.02f * (movingEnt->IsObject()
- ? CTimer::GetTimeStepNonClipped()
- : CTimer::GetTimeStep()));
+ if (movingEnt->IsObject())
+ RpAnimBlendClumpUpdateAnimations(movingEnt->GetClump(), 0.02f * CTimer::GetTimeStepNonClipped());
+ else {
+ if (!movingEnt->bOffscreen)
+ movingEnt->bOffscreen = !movingEnt->GetIsOnScreen();
+ RpAnimBlendClumpUpdateAnimations(movingEnt->GetClump(), 0.02f * CTimer::GetTimeStep(), !movingEnt->bOffscreen);
+ }
}
}
for(CPtrNode *node = ms_listMovingEntityPtrs.first; node; node = node->next) {
@@ -1952,7 +2037,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();
}
@@ -1967,9 +2052,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;
@@ -1990,6 +2078,10 @@ CWorld::Process(void)
movingPed->bInVehicle = false;
movingPed->QuitEnteringCar();
}
+ } else if (movingPed->m_attachedTo) {
+ movingPed->PositionAttachedPed();
+ movingPed->GetMatrix().UpdateRW();
+ movingPed->UpdateRwFrame();
}
}
}
@@ -2010,13 +2102,13 @@ CWorld::TriggerExplosion(const CVector &position, float fRadius, float fPower, C
{
CVector2D vecStartPos(position.x - fRadius, position.y - fRadius);
CVector2D vecEndPos(position.x + fRadius, position.y + fRadius);
- const int32 nStartX = Max(CWorld::GetSectorIndexX(vecStartPos.x), 0);
- const int32 nStartY = Max(CWorld::GetSectorIndexY(vecStartPos.y), 0);
- const int32 nEndX = Min(CWorld::GetSectorIndexX(vecEndPos.x), NUMSECTORS_X - 1);
- const int32 nEndY = Min(CWorld::GetSectorIndexY(vecEndPos.y), NUMSECTORS_Y - 1);
+ 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);
for(int32 y = nStartY; y <= nEndY; y++) {
for(int32 x = nStartX; x <= nEndX; x++) {
- CSector *pSector = CWorld::GetSector(x, y);
+ CSector *pSector = GetSector(x, y);
CWorld::TriggerExplosionSectorList(pSector->m_lists[ENTITYLIST_VEHICLES], position, fRadius,
fPower, pCreator, bProcessVehicleBombTimer);
CWorld::TriggerExplosionSectorList(pSector->m_lists[ENTITYLIST_PEDS], position, fRadius, fPower,
@@ -2054,7 +2146,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();
@@ -2079,7 +2171,7 @@ CWorld::TriggerExplosionSectorList(CPtrList &list, const CVector &position, floa
if(!pEntity->GetIsStatic()) {
float fDamageMultiplier = Min((fRadius - fMagnitude) * 2.0f / fRadius, 1.0f);
CVector vecForceDir =
- vecDistance * (fPower * pEntity->m_fMass * 0.00071429f * fDamageMultiplier /
+ vecDistance * (fPower * pEntity->m_fMass / 14000.0f * fDamageMultiplier /
Max(fMagnitude, 0.01f));
vecForceDir.z = Max(vecForceDir.z, 0.0f);
if(pEntity == FindPlayerPed()) vecForceDir.z = Min(vecForceDir.z, 1.0f);
@@ -2154,4 +2246,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 9d62e79b..59bf634c 100644
--- a/src/core/World.h
+++ b/src/core/World.h
@@ -4,19 +4,19 @@
#include "Lists.h"
#include "PlayerInfo.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)
@@ -71,11 +71,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; }
@@ -90,9 +92,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);
@@ -114,8 +116,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);
@@ -125,6 +127,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); }
@@ -140,6 +144,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();
@@ -153,7 +158,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 075a13bc..69c7a796 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,25 @@
#include "ZoneCull.h"
#include "Zones.h"
-#include "Debug.h"
-#include "Renderer.h"
+//--MIAMI: done
-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 +37,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 +61,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 +159,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.0, -394.0, 18.0),
- CVector(1189.7, -414.6, 27.0),
- CVector(978.8, -391.0, 19.0),
- CVector(1199.0, -502.3, 28.0),
- CVector(1037.0, -391.9, 18.4),
- CVector(1140.0, -608.7, 16.0),
- CVector(1051.0, -26.0, 11.0),
- CVector(951.5, -345.1, 12.0),
- CVector(958.2, -394.6, 16.0),
- CVector(1036.5, -390.0, 15.2),
- CVector(960.6, -390.5, 20.9),
- CVector(1061.0, -640.6, 16.3),
- CVector(1034.5, -388.96, 14.78),
- CVector(1038.4, -13.98, 12.2),
- CVector(1047.2, -16.7, 10.6),
- CVector(1257.9, -333.3, 40.0),
- CVector(885.6, -424.9, 17.0),
- CVector(1127.5, -795.8, 17.7),
- CVector(1133.0, -716.0, 19.0),
- CVector(1125.0, -694.0, 18.5),
- CVector(1125.0, -670.0, 16.3),
- CVector(1051.6, 36.3, 17.9),
- CVector(1054.6, -11.4, 15.0),
- CVector(1058.9, -278.0, 15.0),
- CVector(1059.4, -261.0, 10.9),
- CVector(1051.5, -638.5, 16.5),
- CVector(1058.2, -643.4, 15.5),
- CVector(1058.2, -643.4, 18.0),
- CVector(826.0, -260.0, 7.0),
- CVector(826.0, -260.0, 11.0),
- CVector(833.0, -603.6, 16.4),
- CVector(833.0, -603.6, 20.0),
- CVector(1002.0, -318.5, 10.5),
- CVector(998.0, -318.0, 9.8),
- CVector(1127.0, -183.0, 18.1),
- CVector(1123.0, -331.5, 23.8),
- CVector(1123.8, -429.0, 24.0),
- CVector(1197.0, -30.0, 13.7),
- CVector(1117.5, -230.0, 17.3),
- CVector(1117.5, -230.0, 20.0),
- CVector(1120.0, -281.6, 21.5),
- CVector(1120.0, -281.6, 24.0),
- CVector(1084.5, -1022.7, 17.0),
- CVector(1071.5, 5.4, 4.6),
- CVector(1177.2, -215.7, 27.6),
- CVector(841.6, -460.0, 19.7),
- CVector(874.8, -456.6, 16.6),
- CVector(918.3, -451.8, 17.8),
- CVector(844.0, -495.7, 16.7),
- CVector(842.0, -493.4, 21.0),
- CVector(1433.5, -774.4, 16.9),
- CVector(1051.0, -205.0, 7.5),
- CVector(885.5, -425.6, 15.6),
- CVector(182.6, -470.4, 27.8),
- CVector(132.5, -930.2, 29.0),
- CVector(124.7, -904.0, 28.0),
- CVector(-50.0, -686.0, 22.0),
- CVector(-49.1, -694.5, 22.5),
- CVector(1063.8, -404.45, 16.2),
- CVector(1062.2, -405.5, 17.0)
-};
-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..8200b09a 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,6 +10,9 @@ enum eZoneAttribs
ATTRZONE_NOTCULLZONE = 0x20,
ATTRZONE_DOINEEDCOLLISION = 0x40,
ATTRZONE_SUBWAYVISIBLE = 0x80,
+ ATTRZONE_POLICEABANDONCARS = 0x100,
+ ATTRZONE_ROOMFORAUDIO = 0x200,
+ ATTRZONE_WATERFUDGE = 0x400,
};
struct CAttributeZone
@@ -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 2e3e0f6e..8abe0f1e 100644
--- a/src/core/Zones.cpp
+++ b/src/core/Zones.cpp
@@ -9,43 +9,24 @@
#include "World.h"
#include "Timer.h"
+//--MIAMI: file done
+
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)
@@ -56,66 +37,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;
}
@@ -129,7 +133,6 @@ CTheZones::Update(void)
#endif
CVector pos;
pos = FindPlayerCoors();
- m_pPlayersZone = FindSmallestZonePosition(&pos);
m_CurrLevel = GetLevelFromPosition(&pos);
}
@@ -139,8 +142,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);
@@ -149,71 +152,88 @@ 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();
}
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
CTheZones::InsertZoneIntoZoneHierarchy(CZone *zone)
{
zone->child = nil;
zone->parent = nil;
zone->next = nil;
- InsertZoneIntoZoneHierRecursive(zone, &ZoneArray[0]);
+ InsertZoneIntoZoneHierRecursive(zone, &NavigationZoneArray[0]);
}
bool
@@ -305,34 +325,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
@@ -341,35 +359,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;
}
@@ -377,7 +422,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];
@@ -388,6 +433,7 @@ CTheZones::GetZoneInfoForTimeOfDay(const CVector *pos, CZoneInfo *info)
{
CZoneInfo *day, *night;
float d, n;
+ int i;
day = GetZoneInfo(pos, 1);
night = GetZoneInfo(pos, 0);
@@ -407,109 +453,60 @@ CTheZones::GetZoneInfoForTimeOfDay(const CVector *pos, CZoneInfo *info)
n = 1.0f - d;
}
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;
}
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
@@ -520,46 +517,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];
}
+//--MIAMI: 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;
}
+//--MIAMI: 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
@@ -573,18 +579,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)
{
@@ -595,9 +589,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;
}
@@ -608,7 +603,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)
@@ -638,108 +633,140 @@ 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
- + sizeof(ZoneArray) + sizeof(ZoneInfoArray)
- + sizeof(TotalNumberOfZones) + sizeof(TotalNumberOfZoneInfos)
- + sizeof(MapZoneArray) + 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, 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++){
- 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);
- }
+ for(i = 0; i < ARRAY_SIZE(NavigationZoneArray); i++)
+ SaveOneZone(&NavigationZoneArray[i], &buffer, &length, ZONE_NAVIG);
+
+ for(i = 0; i < ARRAY_SIZE(InfoZoneArray); i++)
+ SaveOneZone(&InfoZoneArray[i], &buffer, &length, ZONE_INFO);
for(i = 0; i < ARRAY_SIZE(ZoneInfoArray); i++)
- WriteSaveBuf(buffer, ZoneInfoArray[i]);
-
- WriteSaveBuf(buffer, TotalNumberOfZones);
- WriteSaveBuf(buffer, TotalNumberOfZoneInfos);
-
- for(i = 0; i < ARRAY_SIZE(MapZoneArray); i++) {
- CZone* zone = WriteSaveBuf(buffer, MapZoneArray[i]);
-
- /*
- 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);
- zone->child = (CZone*)GetIndexForZonePointer(MapZoneArray[i].child);
- zone->parent = (CZone*)GetIndexForZonePointer(MapZoneArray[i].parent);
- zone->next = (CZone*)GetIndexForZonePointer(MapZoneArray[i].next);
- }
+ WriteSaveBuf(buffer, length, ZoneInfoArray[i]);
+
+ WriteSaveBuf(buffer, length, TotalNumberOfNavigationZones);
+ WriteSaveBuf(buffer, length, TotalNumberOfInfoZones);
+ WriteSaveBuf(buffer, length, TotalNumberOfZoneInfos);
+ WriteSaveBuf(buffer, length, (int16)0); // padding
+
+ 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)
}
void
+CTheZones::SaveOneZone(CZone *zone, uint8 **buffer, uint32 *length, eZoneType zoneType)
+{
+ 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 = GetIndexForZonePointer(zone->child);
+ WriteSaveBuf(*buffer, *length, zoneId);
+ zoneId = GetIndexForZonePointer(zone->parent);
+ WriteSaveBuf(*buffer, *length, zoneId);
+ zoneId = GetIndexForZonePointer(zone->next);
+ WriteSaveBuf(*buffer, *length, zoneId);
+}
+
+void
CTheZones::LoadAllZones(uint8 *buffer, uint32 size)
{
INITSAVEBUF
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);
- m_pPlayersZone = GetPointerForZoneIndex(ReadSaveBuf<int32>(buffer));
- m_CurrLevel = ReadSaveBuf<eLevelName>(buffer);
- FindIndex = ReadSaveBuf<int16>(buffer);
- ReadSaveBuf<int16>(buffer);
+ m_CurrLevel = ReadSaveBuf<eLevelName>(buffer, length);
+ FindIndex = ReadSaveBuf<int16>(buffer, length);
+ ReadSaveBuf<int16>(buffer, length);
- for(i = 0; i < ARRAY_SIZE(ZoneArray); i++){
- ZoneArray[i] = ReadSaveBuf<CZone>(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);
- }
+ for (i = 0; i < ARRAY_SIZE(InfoZoneArray); i++)
+ LoadOneZone(&InfoZoneArray[i], &buffer, &length, ZONE_INFO);
for(i = 0; i < ARRAY_SIZE(ZoneInfoArray); i++)
- ZoneInfoArray[i] = ReadSaveBuf<CZoneInfo>(buffer);
-
- TotalNumberOfZones = ReadSaveBuf<int16>(buffer);
- TotalNumberOfZoneInfos = ReadSaveBuf<int16>(buffer);
-
- for(i = 0; i < ARRAY_SIZE(MapZoneArray); i++){
- MapZoneArray[i] = ReadSaveBuf<CZone>(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);
- assert(MapZoneArray[i].child == nil);
- assert(MapZoneArray[i].parent == nil);
- assert(MapZoneArray[i].next == nil);
- }
+ ZoneInfoArray[i] = ReadSaveBuf<CZoneInfo>(buffer, length);
+
+ TotalNumberOfNavigationZones = ReadSaveBuf<int16>(buffer, length);
+ TotalNumberOfInfoZones = ReadSaveBuf<int16>(buffer, length);
+ TotalNumberOfZoneInfos = ReadSaveBuf<int16>(buffer, length);
+ ReadSaveBuf<int16>(buffer, length);
+
+ for(i = 0; i < ARRAY_SIZE(MapZoneArray); i++)
+ LoadOneZone(&MapZoneArray[i], &buffer, &length, ZONE_MAPZONE);
for(i = 0; i < ARRAY_SIZE(AudioZoneArray); i++)
- AudioZoneArray[i] = ReadSaveBuf<int16>(buffer);
+ AudioZoneArray[i] = ReadSaveBuf<int16>(buffer, length);
- TotalNumberOfMapZones = ReadSaveBuf<uint16>(buffer);
- NumberOfAudioZones = ReadSaveBuf<uint16>(buffer);
+ TotalNumberOfMapZones = ReadSaveBuf<uint16>(buffer, length);
+ NumberOfAudioZones = ReadSaveBuf<uint16>(buffer, length);
VALIDATESAVEBUF(size)
}
+
+void
+CTheZones::LoadOneZone(CZone *zone, uint8 **buffer, uint32 *length, eZoneType zoneType)
+{
+ *(uint32*)&zone->name[0] = ReadSaveBuf<uint32>(*buffer, *length);
+ *(uint32*)&zone->name[4] = ReadSaveBuf<uint32>(*buffer, *length);
+
+ zone->minx = ReadSaveBuf<float>(*buffer, *length);
+ zone->miny = ReadSaveBuf<float>(*buffer, *length);
+ zone->minz = ReadSaveBuf<float>(*buffer, *length);
+ zone->maxx = ReadSaveBuf<float>(*buffer, *length);
+ zone->maxy = ReadSaveBuf<float>(*buffer, *length);
+ zone->maxz = ReadSaveBuf<float>(*buffer, *length);
+
+ zone->type = ReadSaveBuf<eZoneType>(*buffer, *length);
+ zone->level = ReadSaveBuf<eLevelName>(*buffer, *length);
+ zone->zoneinfoDay = ReadSaveBuf<int16>(*buffer, *length);
+ zone->zoneinfoNight = ReadSaveBuf<int16>(*buffer, *length);
+
+ int32 zoneId;
+ zoneId = ReadSaveBuf<int32>(*buffer, *length);
+ zone->child = GetPointerForZoneIndex(zoneId);
+ zoneId = ReadSaveBuf<int32>(*buffer, *length);
+ zone->parent = GetPointerForZoneIndex(zoneId);
+ zoneId = ReadSaveBuf<int32>(*buffer, *length);
+ zone->next = GetPointerForZoneIndex(zoneId);
+} \ No newline at end of file
diff --git a/src/core/Zones.h b/src/core/Zones.h
index 6549dad5..5306d9f1 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(int32 i) { return i == -1 ? nil : &ZoneArray[i]; }
- static int32 GetIndexForZonePointer(CZone *zone) { return zone == nil ? -1 : zone - ZoneArray; }
+ static CZone *GetPointerForZoneIndex(int32 i) { return i == -1 ? nil : &NavigationZoneArray[i]; }
+ static int32 GetIndexForZonePointer(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 d5775e08..882e2fae 100644
--- a/src/core/common.h
+++ b/src/core/common.h
@@ -84,10 +84,8 @@ typedef uint16_t wchar;
#include "config.h"
-#ifdef PED_SKIN
#include <rphanim.h>
#include <rpskin.h>
-#endif
#ifdef __GNUC__
#define TYPEALIGN(n) __attribute__ ((aligned (n)))
@@ -217,12 +215,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))
@@ -417,6 +418,15 @@ inline void SkipSaveBuf(uint8 *&buf, int32 skip)
#endif
}
+inline void SkipSaveBuf(uint8*& buf, uint32 &length, int32 skip)
+{
+ buf += skip;
+ length += skip;
+#ifdef VALIDATE_SAVE_SIZE
+ _saveBufCount += skip;
+#endif
+}
+
template<typename T>
inline const T ReadSaveBuf(uint8 *&buf)
{
@@ -426,6 +436,14 @@ inline const T ReadSaveBuf(uint8 *&buf)
}
template<typename T>
+inline const T ReadSaveBuf(uint8 *&buf, uint32 &length)
+{
+ T &value = *(T*)buf;
+ SkipSaveBuf(buf, length, sizeof(T));
+ return value;
+}
+
+template<typename T>
inline T *WriteSaveBuf(uint8 *&buf, const T &value)
{
T *p = (T*)buf;
@@ -434,6 +452,15 @@ inline T *WriteSaveBuf(uint8 *&buf, const T &value)
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;
+}
+
#define SAVE_HEADER_SIZE (4*sizeof(char)+sizeof(uint32))
@@ -444,6 +471,13 @@ inline T *WriteSaveBuf(uint8 *&buf, const T &value)
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<uint32>(buf, len, size);
+
#define CheckSaveHeader(buf,a,b,c,d,size)\
assert(ReadSaveBuf<char>(buf) == a);\
assert(ReadSaveBuf<char>(buf) == b);\
@@ -451,5 +485,12 @@ inline T *WriteSaveBuf(uint8 *&buf, const T &value)
assert(ReadSaveBuf<char>(buf) == d);\
assert(ReadSaveBuf<uint32>(buf) == size);
+#define CheckSaveHeaderWithLength(buf,len,a,b,c,d,size)\
+ assert(ReadSaveBuf<char>(buf,len) == a);\
+ assert(ReadSaveBuf<char>(buf,len) == b);\
+ assert(ReadSaveBuf<char>(buf,len) == c);\
+ assert(ReadSaveBuf<char>(buf,len) == d);\
+ assert(ReadSaveBuf<uint32>(buf,len) == size);
+
void cprintf(char*, ...);
diff --git a/src/core/config.h b/src/core/config.h
index 8c9c1ccd..99f2c156 100644
--- a/src/core/config.h
+++ b/src/core/config.h
@@ -1,74 +1,77 @@
#pragma once
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
-// TXDSTORESIZE = 850,
- TXDSTORESIZE = 1024, // for Xbox map
- EXTRADIRSIZE = 128,
+ MODELINFOSIZE = 6500,
+ 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,
@@ -84,8 +87,9 @@ enum Config {
NUMMBLURSTREAKS = 4,
NUMSKIDMARKS = 32,
- NUMONSCREENTIMERENTRIES = 1,
- NUMRADARBLIPS = 32,
+ NUMONSCREENCLOCKS = 1,
+ NUMONSCREENCOUNTERS = 3,
+ NUMRADARBLIPS = 75,
NUMGENERALPICKUPS = 320,
NUMSCRIPTEDPICKUPS = 16,
NUMPICKUPS = NUMGENERALPICKUPS + NUMSCRIPTEDPICKUPS,
@@ -93,7 +97,7 @@ enum Config {
NUMPACMANPICKUPS = 256,
NUMEVENTS = 64,
- NUM_CARGENS = 160,
+ NUM_CARGENS = 185,
NUM_PATH_NODES_IN_AUTOPILOT = 8,
@@ -108,11 +112,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,
@@ -123,16 +129,21 @@ enum Config {
NUM_SOUNDS_SAMPLES_BANKS = 2,
NUM_SOUNDS_SAMPLES_SLOTS = 27,
- 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
@@ -162,14 +173,17 @@ enum Config {
#endif
// 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
// quality of life fixes that should also be in FINAL
#define NASTY_GAME // nasty game for all languages
@@ -177,19 +191,12 @@ enum Config {
// those infamous texts
#define DRAW_GAME_VERSION_TEXT
-#define DRAW_MENU_VERSION_TEXT
-
-// Memory allocation and compression
-// #define USE_CUSTOM_ALLOCATOR // use CMemoryHeap for allocation. use with care, not finished yet
-//#define COMPRESSED_COL_VECTORS // use compressed vectors for collision vertices
-//#define ANIM_COMPRESSION // only keep most recently used anims uncompressed
#if defined GTA_PS2
# define GTA_PS2_STUFF
# define RANDOMSPLASH
-# define USE_CUSTOM_ALLOCATOR
+//# define USE_CUSTOM_ALLOCATOR
# define VU_COLLISION
-# define ANIM_COMPRESSION
#elif defined GTA_PC
# ifdef GTA_PS2_STUFF
# define USE_PS2_RAND
@@ -225,20 +232,19 @@ enum Config {
# define TIMEBARS // print debug timers
#endif
-#define FIX_BUGS // fixes bugs that we've came across during reversing
-#define MORE_LANGUAGES // Add more translations to the game
+#define FIX_BUGS // fixes bugs that we've came across during reversing, TODO: use this more
+//#define MORE_LANGUAGES // Add more translations to the game
#define COMPATIBLE_SAVES // this allows changing structs while keeping saves compatible
#define LOAD_INI_SETTINGS // as the name suggests. fundamental for CUSTOM_FRONTEND_OPTIONS
+#define FIX_HIGH_FPS_BUGS_ON_FRONTEND
// 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 DEFAULT_NATIVE_RESOLUTION // Set default video mode to your native resolution (fixes Windows 10 launch)
#define USE_TXD_CDIMAGE // generate and load textures from txd.img
@@ -251,18 +257,22 @@ enum Config {
//#define EXTENDED_COLOURFILTER // more options for colour filter (replaces mblur)
//#define EXTENDED_PIPELINES // custom render pipelines (includes Neo)
//#define SCREEN_DROPLETS // neo water droplets
+//#define NEW_RENDERER // leeds-like world rendering, needs librw
#endif
#ifndef EXTENDED_COLOURFILTER
-#undef SCREEN_DROPLETS // we need the backbuffer for this effect
+#undef SCREEN_DROPLETS // we need the front- (or back-)buffer for this effect
#endif
#ifndef EXTENDED_PIPELINES
#undef SCREEN_DROPLETS // we need neo.txd
#endif
-// Particle
-//#define PC_PARTICLE
-//#define PS2_ALTERNATIVE_CARSPLASH // unused on PS2
+// Water & Particle
+// #define PC_WATER
+#define WATER_CHEATS
+
+//#define USE_CUTSCENE_SHADOW_FOR_PED
+#define DISABLE_CUTSCENE_SHADOWS
// Pad
#if !defined(RW_GL3) && defined(_WIN32)
@@ -273,37 +283,34 @@ 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 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 XBOX_SUBTITLES // the infamous outlines
#define PC_MENU
#ifndef PC_MENU
# define PS2_MENU
//# define PS2_MENU_USEALLPAGEICONS
#else
-# define MENU_MAP // VC-like menu map. Make sure you have new menu.txd
-# define SCROLLABLE_STATS_PAGE // only draggable by mouse atm
+# define MAP_ENHANCEMENTS // Adding waypoint and better mouse support
# 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 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 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 MULTISAMPLING // adds MSAA option
+# define INVERT_LOOK_FOR_PAD // enable the hidden option
# endif
#endif
@@ -311,8 +318,14 @@ 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
#endif
//#define SIMPLIER_MISSIONS // apply simplifications from mobile
#define USE_ADVANCED_SCRIPT_DEBUG_OUTPUT
@@ -328,31 +341,28 @@ enum Config {
// 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
-#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
// 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
-#ifndef AUDIO_OAL // is not working yet for openal
#define AUDIO_CACHE // cache sound lengths to speed up the cold boot
-#endif
//#define PS2_AUDIO // changes audio paths for cutscenes and radio to PS2 paths, needs vbdec to support VB with MSS
+
+#ifdef LIBRW
+// these are not supported with librw yet
+# undef MULTISAMPLING
+#endif
// IMG
#define BIG_IMG // allows to read larger img files
@@ -360,8 +370,6 @@ enum Config {
#ifdef SQUEEZE_PERFORMANCE
#undef PS2_ALPHA_TEST
#undef NO_ISLAND_LOADING
- #define PC_PARTICLE
- #define VC_PED_PORTS // To not process collisions always. But should be tested if that's really beneficial
#endif
#ifdef LIBRW
diff --git a/src/core/main.cpp b/src/core/main.cpp
index 51c48452..91ad7fc1 100644
--- a/src/core/main.cpp
+++ b/src/core/main.cpp
@@ -3,6 +3,9 @@
#include "rphanim.h"
#include "rpskin.h"
#include "rtbmp.h"
+#ifndef LIBRW
+#include "rpanisot.h"
+#endif
#include "main.h"
#include "CdStream.h"
@@ -60,14 +63,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 "frontendoption.h"
-#include "MemoryHeap.h"
+#include "screendroplets.h"
GlobalScene Scene;
@@ -92,11 +97,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];
@@ -114,7 +115,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
@@ -122,6 +123,13 @@ bool gbPrintMemoryUsage;
#define FOUND_GAME_TO_LOAD b_FoundRecentSavedGameWantToLoad
#endif
+#ifdef NEW_RENDERER
+bool gbNewRenderer;
+#define CLEARMODE (rwCAMERACLEARZ | rwCAMERACLEARSTENCIL)
+#else
+#define CLEARMODE (rwCAMERACLEARZ)
+#endif
+
void
ValidateVersion()
{
@@ -163,13 +171,10 @@ 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, rwCAMERACLEARZ);
+ RwCameraClear(Scene.camera, &TopColor.rwRGBA, CLEARMODE);
if(!RsCameraBeginUpdate(Scene.camera))
return false;
@@ -185,13 +190,10 @@ 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, rwCAMERACLEARZ);
+ RwCameraClear(Scene.camera, &gColourTop, CLEARMODE);
if(!RsCameraBeginUpdate(Scene.camera))
return false;
@@ -246,13 +248,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)
@@ -277,31 +279,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;
@@ -373,7 +355,12 @@ PluginAttach(void)
return FALSE;
}
-
+#ifndef LIBRW
+ if (!RtAnimInitialize())
+ {
+ return FALSE;
+ }
+#endif
if( !RpHAnimPluginAttach() )
{
printf("Couldn't attach RpHAnim plugin\n");
@@ -408,6 +395,9 @@ PluginAttach(void)
return FALSE;
}
+#ifndef LIBRW
+ RpAnisotPluginAttach();
+#endif
#ifdef EXTENDED_PIPELINES
CustomPipes::CustomPipeRegister();
#endif
@@ -523,6 +513,7 @@ Terminate3D(void)
CSprite2d splash;
int splashTxdId = -1;
+//--MIAMI: done
CSprite2d*
LoadSplash(const char *name)
{
@@ -568,22 +559,23 @@ DestroySplashScreen(void)
splashTxdId = -1;
}
+//--MIAMI: done
Const char*
GetRandomSplashScreen(void)
{
int index;
static int index2 = 0;
static char splashName[128];
- static int splashIndex[24] = {
- 25, 22, 4, 13,
- 1, 21, 14, 16,
- 10, 12, 5, 9,
- 11, 18, 3, 2,
- 19, 23, 7, 17,
- 15, 6, 8, 20
+ static int splashIndex[12] = {
+ 1, 2,
+ 3, 4,
+ 5, 11,
+ 6, 8,
+ 9, 10,
+ 7, 12
};
- index = splashIndex[4*index2 + CGeneral::GetRandomNumberInRange(0, 3)];
+ index = splashIndex[2*index2 + CGeneral::GetRandomNumberInRange(0, 2)];
index2++;
if(index2 == 6)
index2 = 0;
@@ -610,6 +602,7 @@ ResetLoadingScreenBar()
NumberOfChunksLoaded = 0.0f;
}
+//--MIAMI: done
void
LoadingScreen(const char *str1, const char *str2, const char *splashscreen)
{
@@ -621,10 +614,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);
@@ -645,37 +635,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
}
@@ -685,17 +689,13 @@ LoadingScreen(const char *str1, const char *str2, const char *splashscreen)
}
}
+//--MIAMI: done
void
LoadingIslandScreen(const char *levelName)
{
CSprite2d *splash;
- wchar *name;
- char str[100];
- wchar wstr[80];
- CRGBA col;
splash = LoadSplash(nil);
- name = TheText.Get(levelName);
if(!DoRWStuffStartOfFrame(0, 0, 0, 0, 0, 0, 255))
return;
@@ -703,26 +703,10 @@ LoadingIslandScreen(const char *levelName)
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();
- CFont::SetScale(1.5f, 1.5f);
- CFont::SetPropOn();
- CFont::SetRightJustifyOn();
- CFont::SetRightJustifyWrap(SCREEN_SCALE_X(150.0f));
- 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));
- CFont::SetScale(SCREEN_SCALE_X(1.2f), SCREEN_SCALE_Y(1.2f));
- CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(20.0f), SCREEN_STRETCH_FROM_BOTTOM(110.0f), TheText.Get("WELCOME"));
- TextCopy(wstr, name);
- TheText.UpperCase(wstr);
- CFont::SetColor(CRGBA(243, 237, 71, 255));
- CFont::SetScale(SCREEN_SCALE_X(1.2f), SCREEN_SCALE_Y(1.2f));
- CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(20.0f), SCREEN_STRETCH_FROM_BOTTOM(80.0f), wstr);
CFont::DrawFonts();
DoRWStuffEndOfFrame();
}
@@ -755,7 +739,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 )
@@ -769,10 +753,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;
@@ -825,22 +806,32 @@ int32 FrameSamples;
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)}
};
#ifndef MASTER
@@ -1012,12 +1003,13 @@ void
DisplayGameDebugText()
{
static bool bDisplayPosn = false;
- static bool bDisplayRate = false;
+ static bool bDisplayCheatStr = false; // custom
+
#ifndef FINAL
{
SETTWEAKPATH("GameDebugText");
TWEAKBOOL(bDisplayPosn);
- TWEAKBOOL(bDisplayRate);
+ TWEAKBOOL(bDisplayCheatStr);
}
if(gbPrintMemoryUsage)
@@ -1034,7 +1026,7 @@ DisplayGameDebugText()
CFont::SetPropOn();
CFont::SetBackgroundOff();
- CFont::SetFontStyle(FONT_BANK);
+ CFont::SetFontStyle(FONT_STANDARD);
CFont::SetScale(SCREEN_SCALE_X(0.5f), SCREEN_SCALE_Y(0.5f));
CFont::SetCentreOff();
CFont::SetRightJustifyOff();
@@ -1054,23 +1046,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
@@ -1087,50 +1064,191 @@ 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);
- // Let's not scale those numbers, they look better that way :eyes:
- CFont::SetPropOff();
+ CFont::SetPropOn();
CFont::SetBackgroundOff();
- CFont::SetScale(0.7f, 1.5f);
+ CFont::SetScale(SCREEN_SCALE_X(0.6f), SCREEN_SCALE_Y(0.8f));
CFont::SetCentreOff();
CFont::SetRightJustifyOff();
CFont::SetJustifyOff();
CFont::SetBackGroundOnlyTextOff();
CFont::SetWrapx(SCREEN_STRETCH_X(DEFAULT_SCREEN_WIDTH));
- 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));
- CFont::PrintString(42.0f, 42.0f, ustr);
+ CFont::PrintString(41.0f, 41.0f, ustr);
- CFont::SetColor(CRGBA(255, 108, 0, 255));
+ CFont::SetColor(CRGBA(205, 205, 0, 255));
CFont::PrintString(40.0f, 40.0f, ustr);
}
+
+ // 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
+
+#ifdef NEW_RENDERER
+bool gbRenderRoads = true;
+bool gbRenderEverythingBarRoads = true;
+bool gbRenderFadingInUnderwaterEntities = true;
+bool gbRenderFadingInEntities = true;
+bool gbRenderWater = true;
+bool gbRenderBoats = true;
+bool gbRenderVehicles = true;
+bool gbRenderWorld0 = true;
+bool gbRenderWorld1 = true;
+bool gbRenderWorld2 = true;
+
+void
+MattRenderScene(void)
+{
+ // this calls CMattRenderer::Render
+ /// CWorld::AdvanceCurrentScanCode();
+ // CMattRenderer::ResetRenderStates
+ /// CRenderer::ClearForFrame(); // before ConstructRenderList
+ // CClock::CalcEnvMapTimeMultiplicator
+ CWaterLevel::RenderWater(); // actually CMattRenderer::RenderWater
+ // CClock::ms_EnvMapTimeMultiplicator = 1.0f;
+ // cWorldStream::ClearDynamics
+ /// CRenderer::ConstructRenderList(); // before PreRender
+if(gbRenderWorld0)
+ CRenderer::RenderWorld(0); // roads
+ // CMattRenderer::ResetRenderStates
+ /// CRenderer::PreRender(); // has to be called before BeginUpdate because of cutscene shadows
+ CCoronas::RenderReflections();
+if(gbRenderWorld1)
+ CRenderer::RenderWorld(1); // opaque
+if(gbRenderRoads)
+ CRenderer::RenderRoads();
+
+ CRenderer::RenderPeds();
+
+ // not sure where to put these since LCS has no underwater entities
+if(gbRenderBoats)
+ CRenderer::RenderBoats();
+if(gbRenderFadingInUnderwaterEntities)
+ CRenderer::RenderFadingInUnderwaterEntities();
+if(gbRenderWater)
+ CRenderer::RenderTransparentWater();
+
+if(gbRenderEverythingBarRoads)
+ CRenderer::RenderEverythingBarRoads();
+ // get env map here?
+ // moved this:
+ // CRenderer::RenderFadingInEntities();
+}
+
+void
+RenderScene_new(void)
+{
+ CClouds::Render();
+ DoRWRenderHorizon();
+
+ MattRenderScene();
+ DefinedState();
+ // CMattRenderer::ResetRenderStates
+ // moved CRenderer::RenderBoats to before transparent water
+}
+
+// TODO
+bool FredIsInFirstPersonCam(void) { return false; }
+void
+RenderEffects_new(void)
+{
+ CShadows::RenderStaticShadows();
+ // CRenderer::GenerateEnvironmentMap
+ CShadows::RenderStoredShadows();
+ CSkidmarks::Render();
+ CRubbish::Render();
+
+ // these aren't really effects
+ DefinedState();
+ if(FredIsInFirstPersonCam()){
+ DefinedState();
+ C3dMarkers::Render(); // normally rendered in CSpecialFX::Render()
+if(gbRenderWorld2)
+ CRenderer::RenderWorld(2); // transparent
+if(gbRenderVehicles)
+ CRenderer::RenderVehicles();
+ }else{
+ // flipped these two, seems to give the best result
+if(gbRenderWorld2)
+ CRenderer::RenderWorld(2); // transparent
+if(gbRenderVehicles)
+ CRenderer::RenderVehicles();
+ }
+ // better render these after transparent world
+if(gbRenderFadingInEntities)
+ CRenderer::RenderFadingInEntities();
+
+ // actual effects here
+ 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();
+ CWeaponEffects::Render();
+ CPointLights::RenderFogEffect();
+ CMovingThings::Render();
+ CRenderer::RenderFirstPersonVehicle();
}
#endif
void
RenderScene(void)
{
+#ifdef NEW_RENDERER
+ if(gbNewRenderer){
+ RenderScene_new();
+ return;
+ }
+#endif
CClouds::Render();
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();
}
void
@@ -1149,9 +1267,16 @@ RenderDebugShit(void)
void
RenderEffects(void)
{
+#ifdef NEW_RENDERER
+ if(gbNewRenderer){
+ RenderEffects_new();
+ return;
+ }
+#endif
CGlass::Render();
CWaterCannons::Render();
CSpecialFX::Render();
+ CRopes::Render();
CShadows::RenderStaticShadows();
CShadows::RenderStoredShadows();
CSkidmarks::Render();
@@ -1196,11 +1321,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
@@ -1224,12 +1350,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();
@@ -1254,17 +1385,17 @@ Render2dStuffAfterFade(void)
DisplayGameDebugText();
#endif
+#ifdef MOBILE_IMPROVEMENTS
+ if (CDraw::FadeValue != 0)
+#endif
CHud::DrawAfterFade();
CFont::DrawFonts();
+ CCredits::Render();
}
void
Idle(void *arg)
{
-#ifdef ASPECT_RATIO_SCALE
- CDraw::SetAspectRatio(CDraw::FindAspectRatio());
-#endif
-
CTimer::Update();
tbInit();
@@ -1272,44 +1403,15 @@ 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();
tbStartTimer(0, "CGame::Process");
CGame::Process();
tbEndTimer("CGame::Process");
- POP_MEMID();
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;
@@ -1327,30 +1429,32 @@ Idle(void *arg)
if(arg == nil)
return;
- PUSH_MEMID(MEMID_RENDER);
-
- if((!FrontEndMenuManager.m_bMenuActive || FrontEndMenuManager.m_bRenderGameInMenu) &&
- TheCamera.GetScreenFadeStatus() != FADE_2)
+ if(!FrontEndMenuManager.m_bMenuActive && TheCamera.GetScreenFadeStatus() != FADE_2)
{
// This is from SA, but it's nice for windowed mode
#if defined(GTA_PC) && !defined(RW_GL3)
- if (!FrontEndMenuManager.m_bRenderGameInMenu) {
- RwV2d pos;
- pos.x = SCREEN_WIDTH / 2.0f;
- pos.y = SCREEN_HEIGHT / 2.0f;
- RsMouseSetPos(&pos);
- }
+ 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
+ CRenderer::ClearForFrame();
+ }
+#endif
CRenderer::ConstructRenderList();
tbEndTimer("CnstrRenderList");
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
@@ -1405,21 +1509,18 @@ Idle(void *arg)
Render2dStuff();
tbEndTimer("Render2dStuff");
}else{
+ CDraw::CalculateAspectRatio();
#ifdef ASPECT_RATIO_SCALE
CameraSize(Scene.camera, nil, SCREEN_VIEWWINDOW, SCREEN_ASPECT_RATIO);
#else
CameraSize(Scene.camera, nil, SCREEN_VIEWWINDOW, DEFAULT_ASPECT_RATIO);
#endif
CVisibilityPlugins::SetRenderWareCamera(Scene.camera);
- RwCameraClear(Scene.camera, &gColourTop, rwCAMERACLEARZ);
+ RwCameraClear(Scene.camera, &gColourTop, CLEARMODE);
if(!RsCameraBeginUpdate(Scene.camera))
goto popret;
}
-#ifdef PS2_SAVE_DIALOG
- if (FrontEndMenuManager.m_bMenuActive)
- DefinedState();
-#endif
tbStartTimer(0, "RenderMenus");
RenderMenus();
tbEndTimer("RenderMenus");
@@ -1436,9 +1537,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();
@@ -1457,10 +1559,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();
@@ -1471,21 +1570,20 @@ FrontendIdle(void)
if(RsGlobal.quit)
return;
-#ifdef ASPECT_RATIO_SCALE
CameraSize(Scene.camera, nil, SCREEN_VIEWWINDOW, SCREEN_ASPECT_RATIO);
-#else
- CameraSize(Scene.camera, nil, SCREEN_VIEWWINDOW, DEFAULT_ASPECT_RATIO);
-#endif
CVisibilityPlugins::SetRenderWareCamera(Scene.camera);
- RwCameraClear(Scene.camera, &gColourTop, rwCAMERACLEARZ);
+ RwCameraClear(Scene.camera, &gColourTop, CLEARMODE);
if(!RsCameraBeginUpdate(Scene.camera))
return;
DefinedState(); // seems redundant, but breaks resolution change.
RenderMenus();
+#ifdef XBOX_MESSAGE_SCREEN
+ FrontEndMenuManager.DrawOverlays();
+#endif
DoFade();
Render2dStuffAfterFade();
-// CFont::DrawFonts(); // redundant
+ CFont::DrawFonts();
DoRWStuffEndOfFrame();
}
@@ -1493,7 +1591,7 @@ void
InitialiseGame(void)
{
LoadingScreen(nil, nil, "loadsc0");
- CGame::Initialise("DATA\\GTA3.DAT");
+ CGame::Initialise("DATA\\GTA_VC.DAT");
}
RsEventStatus
@@ -1556,11 +1654,7 @@ AppEventHandler(RsEvent event, void *param)
case rsFRONTENDIDLE:
{
-#ifdef PS2_SAVE_DIALOG
- Idle((void*)1);
-#else
FrontendIdle();
-#endif
return rsEVENTPROCESSED;
}
@@ -1586,20 +1680,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();
@@ -1607,6 +1701,7 @@ TheModelViewer(void)
CAnimViewer::Render();
Render2dStuff(); // X
DoRWStuffEndOfFrame();
+ CTimer::Update();
#endif
}
#endif
@@ -1640,9 +1735,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();
}
@@ -1691,7 +1786,8 @@ void TheGame(void)
PUSH_MEMID(MEMID_RENDER);
- if (!FrontEndMenuManager.m_bMenuActive || FrontEndMenuManager.m_bRenderGameInMenu == true && TheCamera.GetScreenFadeStatus() != FADE_2 )
+ // m_bRenderGameInMenu is there in III PS2 but I don't know about VC PS2.
+ if (!FrontEndMenuManager.m_bMenuActive || /*FrontEndMenuManager.m_bRenderGameInMenu == true && */TheCamera.GetScreenFadeStatus() != FADE_2 )
{
PUSH_MEMID(MEMID_RENDERLIST);
@@ -1722,7 +1818,7 @@ void TheGame(void)
{
CameraSize(Scene.camera, NULL, SCREEN_VIEWWINDOW, SCREEN_ASPECT_RATIO);
CVisibilityPlugins::SetRenderWareCamera(Scene.camera);
- RwCameraClear(Scene.camera, &gColourTop, rwCAMERACLEARZ);
+ RwCameraClear(Scene.camera, &gColourTop, CLEARMODE);
if (!RsCameraBeginUpdate(Scene.camera))
break;
}
@@ -1875,30 +1971,30 @@ void SystemInit()
CGame::frenchGame = false;
CGame::germanGame = false;
CGame::nastyGame = true;
- CMenuManager::m_PrefsAllowNastyGame = true;
+ FrontEndMenuManager.m_PrefsAllowNastyGame = true;
#ifdef GTA_PS2
int32 lang = sceScfGetLanguage();
if ( lang == SCE_ITALIAN_LANGUAGE )
- CMenuManager::m_PrefsLanguage = LANGUAGE_ITALIAN;
+ FrontEndMenuManager.m_PrefsLanguage = LANGUAGE_ITALIAN;
else if ( lang == SCE_SPANISH_LANGUAGE )
- CMenuManager::m_PrefsLanguage = LANGUAGE_SPANISH;
+ FrontEndMenuManager.m_PrefsLanguage = LANGUAGE_SPANISH;
else if ( lang == SCE_GERMAN_LANGUAGE )
{
CGame::germanGame = true;
CGame::nastyGame = false;
- CMenuManager::m_PrefsAllowNastyGame = false;
- CMenuManager::m_PrefsLanguage = LANGUAGE_GERMAN;
+ FrontEndMenuManager.m_PrefsAllowNastyGame = false;
+ FrontEndMenuManager.m_PrefsLanguage = LANGUAGE_GERMAN;
}
else if ( lang == SCE_FRENCH_LANGUAGE )
{
CGame::frenchGame = true;
CGame::nastyGame = false;
- CMenuManager::m_PrefsAllowNastyGame = false;
- CMenuManager::m_PrefsLanguage = LANGUAGE_FRENCH;
+ FrontEndMenuManager.m_PrefsAllowNastyGame = false;
+ FrontEndMenuManager.m_PrefsLanguage = LANGUAGE_FRENCH;
}
else
- CMenuManager::m_PrefsLanguage = LANGUAGE_AMERICAN;
+ FrontEndMenuManager.m_PrefsLanguage = LANGUAGE_AMERICAN;
FrontEndMenuManager.InitialiseMenuContentsAfterLoadingGame();
#else
diff --git a/src/core/main.h b/src/core/main.h
index 149c0878..37a82fb2 100644
--- a/src/core/main.h
+++ b/src/core/main.h
@@ -48,3 +48,8 @@ void TheModelViewer(void);
void LoadINISettings();
void SaveINISettings();
#endif
+
+#ifdef NEW_RENDERER
+extern bool gbNewRenderer;
+bool FredIsInFirstPersonCam(void);
+#endif
diff --git a/src/core/re3.cpp b/src/core/re3.cpp
index 5974175a..2b3b8e6d 100644
--- a/src/core/re3.cpp
+++ b/src/core/re3.cpp
@@ -3,18 +3,20 @@
#include "common.h"
#include "crossplatform.h"
#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"
@@ -27,6 +29,7 @@
#include "WaterLevel.h"
#include "main.h"
#include "Script.h"
+#include "MBlur.h"
#include "postfx.h"
#include "custompipes.h"
#include "MemoryHeap.h"
@@ -41,6 +44,8 @@
#include <stdarg.h>
#endif
+#include <list>
+
#ifdef RWLIBS
extern "C" int vsprintf(char* const _Buffer, char const* const _Format, va_list _ArgList);
#endif
@@ -128,7 +133,7 @@ void CheckAndSaveIniFloat(const char *cat, const char *key, float val, bool &cha
void LoadINISettings()
{
- cfg.load_file("re3.ini");
+ cfg.load_file("reVC.ini");
#ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS
// Written by assuming the codes below will run after _InputInitialiseJoys().
@@ -230,16 +235,17 @@ void SaveINISettings()
#endif
if (changed)
- cfg.write_file("re3.ini");
+ cfg.write_file("reVC.ini");
}
#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();
@@ -259,7 +265,8 @@ void FastWeatherCheat();
void OnlyRenderWheelsCheat();
void ChittyChittyBangBangCheat();
void StrongGripCheat();
-void NastyLimbsCheat();
+void SpecialCarCheats();
+void PickUpChicksCheat();
DebugMenuEntry *carCol1;
DebugMenuEntry *carCol2;
@@ -282,6 +289,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);
@@ -311,13 +320,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)
{
@@ -384,20 +395,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;
@@ -455,11 +466,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);
@@ -467,19 +504,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);
@@ -496,17 +536,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);
});
@@ -516,32 +555,74 @@ 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);
+ 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);
DebugMenuAddVar("Render", "Max FPS", &RsGlobal.maxFPS, nil, 1, 1, 1000, nil);
+#ifdef NEW_RENDERER
+ DebugMenuAddVarBool8("Render", "new renderer", &gbNewRenderer, nil);
+extern bool gbRenderRoads;
+extern bool gbRenderEverythingBarRoads;
+extern bool gbRenderFadingInUnderwaterEntities;
+extern bool gbRenderFadingInEntities;
+extern bool gbRenderWater;
+extern bool gbRenderBoats;
+extern bool gbRenderVehicles;
+extern bool gbRenderWorld0;
+extern bool gbRenderWorld1;
+extern bool gbRenderWorld2;
+ DebugMenuAddVarBool8("Render", "gbRenderRoads", &gbRenderRoads, nil);
+ DebugMenuAddVarBool8("Render", "gbRenderEverythingBarRoads", &gbRenderEverythingBarRoads, nil);
+ DebugMenuAddVarBool8("Render", "gbRenderFadingInUnderwaterEntities", &gbRenderFadingInUnderwaterEntities, nil);
+ DebugMenuAddVarBool8("Render", "gbRenderFadingInEntities", &gbRenderFadingInEntities, nil);
+ DebugMenuAddVarBool8("Render", "gbRenderWater", &gbRenderWater, nil);
+ DebugMenuAddVarBool8("Render", "gbRenderBoats", &gbRenderBoats, nil);
+ DebugMenuAddVarBool8("Render", "gbRenderVehicles", &gbRenderVehicles, nil);
+ DebugMenuAddVarBool8("Render", "gbRenderWorld0", &gbRenderWorld0, nil);
+ DebugMenuAddVarBool8("Render", "gbRenderWorld1", &gbRenderWorld1, nil);
+ DebugMenuAddVarBool8("Render", "gbRenderWorld2", &gbRenderWorld2, nil);
+#endif
+
#ifdef EXTENDED_COLOURFILTER
static const char *filternames[] = { "None", "Simple", "Normal", "Mobile" };
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", &bDisplayOccDebugStuff, nil);
+#endif
#ifdef EXTENDED_PIPELINES
static const char *vehpipenames[] = { "MatFX", "Neo" };
e = DebugMenuAddVar("Render", "Vehicle Pipeline", &CustomPipes::VehiclePipeSwitch, nil,
@@ -559,8 +640,6 @@ DebugMenuPopulate(void)
DebugMenuAddVarBool8("Render", "Show Ped Paths", &gbShowPedPaths, nil);
DebugMenuAddVarBool8("Render", "Show Car Paths", &gbShowCarPaths, nil);
DebugMenuAddVarBool8("Render", "Show Car Path Links", &gbShowCarPathsLinks, nil);
- DebugMenuAddVarBool8("Render", "Show Ped Road Groups", &gbShowPedRoadGroups, nil);
- DebugMenuAddVarBool8("Render", "Show Car Road Groups", &gbShowCarRoadGroups, nil);
DebugMenuAddVarBool8("Render", "Show Collision Lines", &gbShowCollisionLines, nil);
DebugMenuAddVarBool8("Render", "Show Collision Polys", &gbShowCollisionPolys, nil);
DebugMenuAddVarBool8("Render", "Don't render Buildings", &gbDontRenderBuildings, nil);
@@ -583,7 +662,7 @@ DebugMenuPopulate(void)
#ifdef GTA_SCENE_EDIT
DebugMenuAddVarBool8("Debug", "Edit on", &CSceneEdit::m_bEditOn, nil);
#endif
-#ifdef MENU_MAP
+#ifdef MAP_ENHANCEMENTS
DebugMenuAddCmd("Debug", "Teleport to map waypoint", TeleportToWaypoint);
#endif
DebugMenuAddCmd("Debug", "Switch car collision", SwitchCarCollision);
@@ -593,16 +672,14 @@ DebugMenuPopulate(void)
DebugMenuAddCmd("Debug", "Toggle Comedy Controls", ToggleComedy);
DebugMenuAddCmd("Debug", "Place Car on Road", PlaceOnRoad);
- DebugMenuAddVarBool8("Debug", "Catalina Heli On", &CHeli::CatalinaHeliOn, nil);
- DebugMenuAddCmd("Debug", "Catalina Fly By", CHeli::StartCatalinaFlyBy);
- DebugMenuAddCmd("Debug", "Catalina Take Off", CHeli::CatalinaTakeOff);
- DebugMenuAddCmd("Debug", "Catalina Fly Away", CHeli::MakeCatalinaHeliFlyAway);
DebugMenuAddVarBool8("Debug", "Script Heli On", &CHeli::ScriptHeliOn, nil);
- DebugMenuAddVarBool8("Debug", "Toggle popping heads on headshot", &CPed::bPopHeadsOnHeadshot, nil);
DebugMenuAddCmd("Debug", "Start Credits", CCredits::Start);
DebugMenuAddCmd("Debug", "Stop Credits", CCredits::Stop);
+#ifdef RELOADABLES
+ DebugMenuAddCmd("Reload", "HUD.TXD", CHud::ReloadTXD);
+#endif
DebugMenuAddVarBool8("Debug", "Show DebugStuffInRelease", &gbDebugStuffInRelease, nil);
#ifdef TIMEBARS
DebugMenuAddVarBool8("Debug", "Show Timebars", &gbShowTimebars, nil);
@@ -610,27 +687,30 @@ DebugMenuPopulate(void)
#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("Debug", "Select mission", &nextMissionToSwitch, nil, 1, 0, 79, missions);
+ missionEntry = DebugMenuAddVar("Debug", "Select mission", &nextMissionToSwitch, nil, 1, 0, 96, missions);
DebugMenuEntrySetWrap(missionEntry, true);
DebugMenuAddCmd("Debug", "Start selected mission ", SwitchToMission);
#endif
-
extern bool PrintDebugCode;
extern int16 DebugCamMode;
DebugMenuAddVarBool8("Cam", "Use mouse Cam", &CCamera::m_bUseMouse3rdPerson, nil);
@@ -640,9 +720,6 @@ DebugMenuPopulate(void)
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");
diff --git a/src/core/templates.h b/src/core/templates.h
index 3a5b314f..19881219 100644
--- a/src/core/templates.h
+++ b/src/core/templates.h
@@ -44,17 +44,16 @@ 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 = (Flags*)new uint8[sizeof(Flags)*size];
m_size = size;
- m_allocPtr = 0;
+ m_allocPtr = -1;
for(int i = 0; i < size; i++){
m_flags[i].id = 0;
m_flags[i].free = 1;
}
}
-
~CPool() {
Flush();
}
@@ -122,21 +121,22 @@ public:
return m_flags[handle>>8].u == (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].u + (i<<8);
+ return m_flags[i].u + (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(!IsFreeSlot(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++)
@@ -167,6 +167,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/Building.cpp b/src/entities/Building.cpp
index 00bbb21e..8035cf25 100644
--- a/src/entities/Building.cpp
+++ b/src/entities/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/entities/Building.h b/src/entities/Building.h
index 3586a8dc..2c2dfb1f 100644
--- a/src/entities/Building.h
+++ b/src/entities/Building.h
@@ -17,5 +17,4 @@ public:
virtual bool GetIsATreadable(void) { return false; }
};
-VALIDATE_SIZE(CBuilding, 0x64);
-
+bool IsBuildingPointerValid(CBuilding*);
diff --git a/src/entities/Dummy.cpp b/src/entities/Dummy.cpp
index 8a4bfd5f..580245a8 100644
--- a/src/entities/Dummy.cpp
+++ b/src/entities/Dummy.cpp
@@ -4,6 +4,8 @@
#include "World.h"
#include "Dummy.h"
+// --MIAMI: file done
+
void *CDummy::operator new(size_t sz) { return CPools::GetDummyPool()->New(); }
void CDummy::operator delete(void *p, size_t sz) { CPools::GetDummyPool()->Delete((CDummy*)p); }
@@ -50,3 +52,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 3717a01c..84b1ce1a 100644
--- a/src/entities/Dummy.h
+++ b/src/entities/Dummy.h
@@ -16,5 +16,4 @@ public:
static void operator delete(void*, size_t);
};
-VALIDATE_SIZE(CDummy, 0x68);
-
+bool IsDummyPointerValid(CDummy* pDummy);
diff --git a/src/entities/Entity.cpp b/src/entities/Entity.cpp
index 476439fa..9db36bcf 100644
--- a/src/entities/Entity.cpp
+++ b/src/entities/Entity.cpp
@@ -28,8 +28,14 @@
#include "Bones.h"
#include "Debug.h"
#include "Renderer.h"
+#include "Ped.h"
+#include "Dummy.h"
+#include "WindModifiers.h"
+#include "Occlusion.h"
#include "MemoryHeap.h"
+//--MIAMI: file done
+
int gBuildings;
CEntity::CEntity(void)
@@ -53,18 +59,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;
@@ -72,13 +77,20 @@ CEntity::CEntity(void)
bDrawLast = false;
bNoBrightHeadLights = false;
bDoNotRender = false;
-
bDistanceFade = false;
+
+ m_flagE1 = false;
m_flagE2 = 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;
}
@@ -270,6 +282,21 @@ CEntity::Remove(void)
}
void
+CEntity::SetModelIndex(uint32 id)
+{
+ m_modelIndex = id;
+ bHasPreRenderEffects = HasPreRenderEffects();
+ CreateRwObject();
+}
+
+void
+CEntity::SetModelIndexNoCreate(uint32 id)
+{
+ m_modelIndex = id;
+ bHasPreRenderEffects = HasPreRenderEffects();
+}
+
+void
CEntity::CreateRwObject(void)
{
CBaseModelInfo *mi;
@@ -303,10 +330,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;
@@ -337,14 +362,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->GetName());
- }
- }
- 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->GetName());
}
CRect
@@ -368,19 +391,39 @@ CEntity::GetBoundRect(void)
return rect;
}
+bool
+CEntity::HasPreRenderEffects(void)
+{
+ return IsTreeModel(GetModelIndex()) ||
+ GetModelIndex() == MI_COLLECTABLE1 ||
+ GetModelIndex() == MI_MONEY ||
+ GetModelIndex() == MI_CARMINE ||
+ GetModelIndex() == MI_NAUTICALMINE ||
+ GetModelIndex() == MI_BRIEFCASE ||
+ GetModelIndex() == MI_GRENADE ||
+ GetModelIndex() == MI_MOLOTOV ||
+ GetModelIndex() == MI_MISSILE ||
+ GetModelIndex() == MI_BEACHBALL ||
+ IsGlass(GetModelIndex()) ||
+ IsObject() && ((CObject*)this)->bIsPickup ||
+ IsLightWithPreRenderEffects(GetModelIndex());
+}
+
void
CEntity::PreRender(void)
{
+ if (CModelInfo::GetModelInfo(GetModelIndex())->GetNum2dEffects() != 0)
+ ProcessLightsForEntity();
+
+ if(!bHasPreRenderEffects)
+ return;
+
switch(m_type){
case ENTITY_TYPE_BUILDING:
- if(GetModelIndex() == MI_RAILTRACKS){
- CShadows::StoreShadowForPole(this, 0.0f, -10.949f, 5.0f, 8.0f, 1.0f, 0);
- CShadows::StoreShadowForPole(this, 0.0f, 10.949f, 5.0f, 8.0f, 1.0f, 1);
- }else if(IsTreeModel(GetModelIndex())){
- CShadows::StoreShadowForTree(this);
+ if(IsTreeModel(GetModelIndex())){
+ float dist = (TheCamera.GetPosition() - GetPosition()).Magnitude2D();
+ CObject::fDistToNearestTree = Min(CObject::fDistToNearestTree, dist);
ModifyMatrixForTreeInWind();
- }else if(IsBannerModel(GetModelIndex())){
- ModifyMatrixForBannerInWind();
}
break;
case ENTITY_TYPE_OBJECT:
@@ -400,22 +443,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;
@@ -423,7 +450,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,
@@ -438,12 +465,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)
@@ -452,19 +511,15 @@ CEntity::PreRender(void)
CShadows::StoreShadowForPole(this, 1.143f, 0.145f, 0.0f, 16.0f, 0.4f, 0);
else if(GetModelIndex() == MI_DOUBLESTREETLIGHTS)
CShadows::StoreShadowForPole(this, 0.0f, -0.048f, 0.0f, 16.0f, 0.4f, 0);
- else if(GetModelIndex() == MI_STREETLAMP1 ||
- GetModelIndex() == MI_STREETLAMP2)
- CShadows::StoreShadowForPole(this, 0.0f, 0.0f, 0.0f, 16.0f, 0.4f, 0);
break;
}
-
- if (CModelInfo::GetModelInfo(GetModelIndex())->GetNum2dEffects() != 0)
- ProcessLightsForEntity();
}
void
CEntity::PreRenderForGlassWindow(void)
{
+ if(((CSimpleModelInfo*)CModelInfo::GetModelInfo(m_modelIndex))->m_isArtistGlass)
+ return;
CGlass::AskForObjectToBeRenderedInGlass(this);
bIsVisible = false;
}
@@ -485,8 +540,6 @@ CEntity::Render(void)
bool
CEntity::SetupLighting(void)
{
- DeActivateDirectional();
- SetAmbientColours();
return false;
}
@@ -572,13 +625,29 @@ CEntity::PruneReferences(void)
}
}
-#ifdef PED_SKIN
+// Clean up the reference from *pent -> 'this'
void
-CEntity::UpdateRpHAnim(void)
+CEntity::CleanUpOldReference(CEntity **pent)
{
- RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(GetClump());
- RpHAnimHierarchyUpdateMatrices(hier);
+ 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;
+ }
+}
+void
+CEntity::UpdateRpHAnim(void)
+{
+ if(IsClumpSkinned(GetClump())){
+ RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(GetClump());
+ RpHAnimHierarchyUpdateMatrices(hier);
#if 0
int i;
char buf[256];
@@ -607,8 +676,8 @@ CEntity::UpdateRpHAnim(void)
void RenderSkeleton(RpHAnimHierarchy *hier);
RenderSkeleton(hier);
#endif
+ }
}
-#endif
void
CEntity::AddSteamsFromGround(CVector *unused)
@@ -640,6 +709,12 @@ CEntity::AddSteamsFromGround(CVector *unused)
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;
}
}
}
@@ -664,80 +739,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;
-
- pos = GetMatrix() * effect->pos;
+ switch(effect->type){
+ case EFFECT_LIGHT:
+ pos = GetMatrix() * effect->pos;
- lightOn = false;
- lightFlickering = false;
- switch(effect->light.lightType){
- case LIGHT_ON:
- lightOn = true;
- break;
- case LIGHT_ON_NIGHT:
- if(CClock::GetHours() > 18 || CClock::GetHours() < 7)
+ lightOn = false;
+ lightFlickering = false;
+ switch(effect->light.lightType){
+ case LIGHT_ON:
lightOn = true;
- break;
- case LIGHT_FLICKER:
- if((CTimer::GetTimeInMilliseconds() ^ m_randomSeed) & 0x60)
- lightOn = true;
- else
- lightFlickering = true;
- if((CTimer::GetTimeInMilliseconds()>>11 ^ m_randomSeed) & 3)
- lightOn = true;
- break;
- case LIGHT_FLICKER_NIGHT:
- if(CClock::GetHours() > 18 || CClock::GetHours() < 7 || 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{
@@ -748,85 +809,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;
}
- 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(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;
+ }
}
- }
- // 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);
+ 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);
+ }
}
+ 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;
}
}
}
@@ -849,27 +968,31 @@ CEntity::ModifyMatrixForTreeInWind(void)
CMatrix mat(GetMatrix().m_attachment);
if(CWeather::Wind >= 0.5){
- t = m_randomSeed + 16*CTimer::GetTimeInMilliseconds();
+ t = m_randomSeed + 8*CTimer::GetTimeInMilliseconds();
f = (t & 0xFFF)/(float)0x1000;
flutter = f * WindTabel[(t>>12)+1 & 0xF] +
(1.0f - f) * WindTabel[(t>>12) & 0xF] +
1.0f;
- strength = CWeather::Wind < 0.8f ? 0.008f : 0.014f;
+ strength = -0.015f*CWeather::Wind;
}else if(CWeather::Wind >= 0.2){
t = (uintptr)this + CTimer::GetTimeInMilliseconds();
f = (t & 0xFFF)/(float)0x1000;
flutter = Sin(f * 6.28f);
- strength = 0.008f;
+ strength = -0.008f;
}else{
t = (uintptr)this + CTimer::GetTimeInMilliseconds();
f = (t & 0xFFF)/(float)0x1000;
flutter = Sin(f * 6.28f);
- strength = 0.005f;
+ strength = -0.005f;
}
mat.GetUp().x = strength * flutter;
+ if(IsPalmTreeModel(GetModelIndex()))
+ mat.GetUp().x += -0.07f*CWeather::Wind;
mat.GetUp().y = mat.GetUp().x;
+ CWindModifiers::FindWindModifier(GetPosition(), &mat.GetUp().x, &mat.GetUp().y);
+
mat.UpdateRW();
UpdateRwFrame();
}
@@ -881,6 +1004,7 @@ float BannerWindTabel[] = {
0.28f, 0.28f, 0.22f, 0.1f, 0.0f, -0.1f, -0.17f, -0.12f
};
+//--MIAMI: unused
void
CEntity::ModifyMatrixForBannerInWind(void)
{
@@ -951,32 +1075,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<uint32>(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 (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 (bDistanceFade) tmp |= BIT(8);
+ if (m_flagE1) tmp |= BIT(8);
if (m_flagE2) 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<uint32>(buf, tmp);
}
@@ -1004,30 +1133,116 @@ 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));
tmp = ReadSaveBuf<uint32>(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));
+ 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));
- bDistanceFade = !!(tmp & BIT(8));
+ m_flagE1 = !!(tmp & BIT(8));
m_flagE2 = !!(tmp & BIT(9));
+ bOffscreen = !!(tmp & BIT(10));
+ bIsStaticWaitingForCollision = !!(tmp & BIT(11));
+ bDontStream = !!(tmp & BIT(12));
+ bUnderwater = !!(tmp & BIT(13));
+ bHasPreRenderEffects = !!(tmp & BIT(14));
}
#endif
+
+bool IsEntityPointerValid(CEntity* pEntity)
+{
+ if (!pEntity)
+ return false;
+ switch (pEntity->GetType()) {
+ case ENTITY_TYPE_NOTHING: return false;
+ case ENTITY_TYPE_BUILDING: return IsBuildingPointerValid((CBuilding*)pEntity);
+ case ENTITY_TYPE_VEHICLE: return IsVehiclePointerValid((CVehicle*)pEntity);
+ case ENTITY_TYPE_PED: return IsPedPointerValid((CPed*)pEntity);
+ case ENTITY_TYPE_OBJECT: return IsObjectPointerValid((CObject*)pEntity);
+ case ENTITY_TYPE_DUMMY: return IsDummyPointerValid((CDummy*)pEntity);
+ }
+ return false;
+}
+
+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::GetModelInfo(GetModelIndex())->GetColModel()->boundingBox.min;
+ CVector max = m_matrix * CModelInfo::GetModelInfo(GetModelIndex())->GetColModel()->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;
+}
+
+/*
+0x487A10 - SetAtomicAlphaCB
+0x4879E0 - SetClumpAlphaCB
+*/
+
+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;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/entities/Entity.h b/src/entities/Entity.h
index 9372c85d..9129457c 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_flagE1 : 1;
uint32 m_flagE2 : 1;
+ 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,12 +114,12 @@ public:
#endif
CEntity(void);
- ~CEntity(void);
+ virtual ~CEntity(void);
virtual void Add(void);
virtual void Remove(void);
- virtual void SetModelIndex(uint32 id) { m_modelIndex = id; CreateRwObject(); }
- virtual void SetModelIndexNoCreate(uint32 id) { m_modelIndex = id; }
+ virtual void SetModelIndex(uint32 id);
+ virtual void SetModelIndexNoCreate(uint32 id);
virtual void CreateRwObject(void);
virtual void DeleteRwObject(void);
virtual CRect GetBoundRect(void);
@@ -150,9 +157,11 @@ public:
bool GetIsOnScreenComplex(void);
bool IsVisible(void) { return m_rwObject && bIsVisible && GetIsOnScreen(); }
bool IsVisibleComplex(void) { return m_rwObject && bIsVisible && GetIsOnScreenComplex(); }
+ 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,18 +169,18 @@ 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);
static void AddSteamsFromGround(CPtrList& list);
};
-VALIDATE_SIZE(CEntity, 0x64);
+bool IsEntityPointerValid(CEntity*);
diff --git a/src/entities/Physical.cpp b/src/entities/Physical.cpp
index 04cec96b..acf9c702 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,17 @@
#include "CarCtrl.h"
#include "DMAudio.h"
#include "Automobile.h"
+#include "Bike.h"
+#include "Pickups.h"
#include "Physical.h"
+//--MIAMI: file done
+
+#ifdef WALLCLIMB_CHEAT
+bool gGravityCheat;
+#endif
+
+
CPhysical::CPhysical(void)
{
int i;
@@ -41,6 +52,7 @@ CPhysical::CPhysical(void)
m_aCollisionRecords[i] = nil;
m_bIsVehicleBeingShifted = false;
+ bJustCheckCollision = false;
m_nDamagePieceType = 0;
m_fDamageImpulse = 0.0f;
@@ -56,21 +68,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)
@@ -225,7 +238,8 @@ CPhysical::GetBoundRect(void)
void
CPhysical::AddToMovingList(void)
{
- m_movingListNode = CWorld::GetMovingEntityList().InsertItem(this);
+ if (!bIsStaticWaitingForCollision)
+ m_movingListNode = CWorld::GetMovingEntityList().InsertItem(this);
}
void
@@ -274,17 +288,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;
}
}
@@ -417,18 +420,26 @@ CPhysical::GetSpeed(const CVector &r)
void
CPhysical::ApplyMoveSpeed(void)
{
- GetMatrix().Translate(m_vecMoveSpeed * CTimer::GetTimeStep());
+ if(bIsFrozen)
+ m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f);
+ else
+ GetMatrix().Translate(m_vecMoveSpeed * CTimer::GetTimeStep());
}
+
void
CPhysical::ApplyTurnSpeed(void)
{
- // Move the coordinate axes by their speed
- // Note that this denormalizes the matrix
- CVector turnvec = m_vecTurnSpeed*CTimer::GetTimeStep();
- GetRight() += CrossProduct(turnvec, GetRight());
- GetForward() += CrossProduct(turnvec, GetForward());
- GetUp() += CrossProduct(turnvec, GetUp());
+ if(bIsFrozen){
+ m_vecTurnSpeed = CVector(0.0f, 0.0f, 0.0f);
+ }else{
+ // Move the coordinate axes by their speed
+ // Note that this denormalizes the matrix
+ CVector turnvec = m_vecTurnSpeed*CTimer::GetTimeStep();
+ GetRight() += CrossProduct(turnvec, GetRight());
+ GetForward() += CrossProduct(turnvec, GetForward());
+ GetUp() += CrossProduct(turnvec, GetUp());
+ }
}
void
@@ -472,6 +483,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)
@@ -480,6 +508,8 @@ CPhysical::ApplySpringDampening(float damping, CVector &springDir, CVector &poin
float speedB = DotProduct(GetSpeed(point), springDir);
float step = Min(CTimer::GetTimeStep(), 3.0f);
float impulse = -damping * (speedA + speedB)/2.0f * m_fMass * step * 0.53f;
+ if(bIsHeavy)
+ impulse *= 2.0f;
// what is this?
float a = m_fTurnMass / ((point.MagnitudeSqr() + 1.0f) * 2.0f * m_fMass);
@@ -496,8 +526,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 v1(0.0f, 0.0f, 1.0f), v2(0.0f, 0.0f, 1.0f);
+ CVector prop = GetPosition() - (GetUp() + GetUp());
+ CColPoint point;
+ CEntity* entity;
+ if (CWorld::ProcessLineOfSight(GetPosition(), prop, point, entity, true, false, false, false, false, false))
+ v2 = point.normal;
+ else
+ v2 = CVector(0.0f, 0.0f, 1.0f);
+ float coef = clamp(CTimer::GetTimeStep() * 0.5f, 0.05f, 0.8f);
+ v1 = v1 * (1.0f - coef) + v2 * coef;
+ if (v1.MagnitudeSqr() < 0.1f)
+ v1 = CVector(0.0f, 0.0f, 1.0f);
+ else
+ v1.Normalise();
+ m_vecMoveSpeed -= GRAVITY * CTimer::GetTimeStep() * v1;
+ return;
+ }
+#endif
+ m_vecMoveSpeed.z -= GRAVITY * CTimer::GetTimeStep();
}
void
@@ -513,9 +564,11 @@ void
CPhysical::ApplyAirResistance(void)
{
if(m_fAirResistance > 0.1f){
- float f = Pow(m_fAirResistance, CTimer::GetTimeStep());
- m_vecMoveSpeed *= f;
- m_vecTurnSpeed *= f;
+ if(GetStatus() != STATUS_GHOST){
+ float f = Pow(m_fAirResistance, CTimer::GetTimeStep());
+ m_vecMoveSpeed *= f;
+ m_vecTurnSpeed *= f;
+ }
}else{
float f = Pow(1.0f/(m_fAirResistance*0.5f*m_vecMoveSpeed.MagnitudeSqr() + 1.0f), CTimer::GetTimeStep());
m_vecMoveSpeed *= f;
@@ -523,7 +576,6 @@ CPhysical::ApplyAirResistance(void)
}
}
-
bool
CPhysical::ApplyCollision(CPhysical *B, CColPoint &colpoint, float &impulseA, float &impulseB)
{
@@ -531,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;
@@ -546,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;
@@ -555,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){
@@ -566,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);
@@ -619,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){
+ CPickups::CreateSomeMoney(GetPosition(), CGeneral::GetRandomNumber()%100);
+ Bobj->bHasBeenDamaged = true;
}else if(B->IsObject() && !IsExplosiveThingModel(model))
Bobj->bHasBeenDamaged = true;
}else{
@@ -641,7 +705,7 @@ CPhysical::ApplyCollision(CPhysical *B, CColPoint &colpoint, float &impulseA, fl
if(B->GetIsStatic())
return false;
- if(!B->bInfiniteMass)
+ if(!B->bInfiniteMass && !B->m_phy_flagA08)
B->AddToMovingList();
}
@@ -651,19 +715,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
+ float speedB = DotProduct(B->m_vecMoveSpeed, colpoint.normal);
+
+ bool affectB = false;
+ float mA = A->m_fMass;;
+ float mB = B->m_fMass;;
+ float speedSum;
+ if(((CPed*)A)->GetPedState() == PED_FOLLOW_PATH){
+ affectB = true;
+ speedSum = (2.0f*mA*speedA + mB*speedB)/(2.0f*mA + mB);
+ }else{
+ speedSum = Max(speedB, 0.0f);
+ }
+
if(speedA < speedSum){
if(A->bHasHitWall)
eA = speedSum;
else
eA = speedSum - (speedA - speedSum) * (A->m_fElasticity+B->m_fElasticity)/2.0f;
- impulseA = (eA-speedA) * 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){
@@ -673,7 +754,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;
@@ -804,13 +889,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){
@@ -823,28 +947,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)
+ 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)
- e = -1.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
@@ -1086,13 +1243,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;
@@ -1212,6 +1369,9 @@ CPhysical::ProcessCollisionSectorList_SimpleCar(CPtrList *lists)
A = (CPhysical*)this;
+ if(!A->bUsesCollision)
+ return false;
+
radius = A->GetBoundRadius();
A->GetBoundCentre(center);
@@ -1230,6 +1390,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)){
@@ -1373,6 +1534,7 @@ CPhysical::ProcessCollisionSectorList(CPtrList *lists)
int numResponses;
int i, j;
bool skipCollision, altcollision;
+ bool ret = false;
float impulseA = -1.0f;
float impulseB = -1.0f;
@@ -1393,9 +1555,9 @@ CPhysical::ProcessCollisionSectorList(CPtrList *lists)
Bped = (CPed*)B;
bool isTouching = true;
- if(B == A ||
+ if(!B->bUsesCollision ||
B->m_scanCode == CWorld::GetCurrentScanCode() ||
- !B->bUsesCollision ||
+ B == A ||
!(isTouching = B->GetIsTouching(center, radius))){
if(!isTouching){
if(A->IsObject() && Aobj->m_pCollidingEntity == B)
@@ -1416,27 +1578,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::GetModelInfo(A->GetModelIndex())->GetColModel()->boundingBox.GetSize();
size = A->GetMatrix() * size;
@@ -1448,14 +1610,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::GetModelInfo(B->GetModelIndex())->GetColModel()->boundingBox.GetSize();
size = B->GetMatrix() * size;
@@ -1465,14 +1627,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;
@@ -1487,7 +1651,11 @@ CPhysical::ProcessCollisionSectorList(CPtrList *lists)
if(!A->bUsesCollision || skipCollision){
B->m_scanCode = CWorld::GetCurrentScanCode();
- A->ProcessEntityCollision(B, aColPoints);
+ numCollisions = A->ProcessEntityCollision(B, aColPoints);
+ if(A->bJustCheckCollision && numCollisions > 0)
+ return true;
+ if(numCollisions == 0 && A == (CEntity*)FindPlayerPed() && Aped->m_pCollidingEntity == B)
+ Aped->m_pCollidingEntity = nil;
}else if(B->IsBuilding() || B->bIsStuck || B->bInfiniteMass || altcollision){
// This is the case where B doesn't move
@@ -1499,6 +1667,7 @@ CPhysical::ProcessCollisionSectorList(CPtrList *lists)
CVector moveSpeed = { 0.0f, 0.0f, 0.0f };
CVector turnSpeed = { 0.0f, 0.0f, 0.0f };
+ float maxImpulseA = 0.0f;
numResponses = 0;
if(A->bHasContacted){
for(i = 0; i < numCollisions; i++){
@@ -1506,20 +1675,35 @@ CPhysical::ProcessCollisionSectorList(CPtrList *lists)
continue;
numResponses++;
+ if(impulseA > maxImpulseA) maxImpulseA = impulseA;
- if(impulseA > A->m_fDamageImpulse)
- A->SetDamagedPieceRecord(aColPoints[i].pieceA, impulseA, B, aColPoints[i].normal);
+ if(A->IsVehicle()){
+ if(!(((CVehicle*)A)->IsBoat() && aColPoints[i].surfaceB == SURFACE_WOOD_SOLID) &&
+ impulseA > A->m_fDamageImpulse)
+ A->SetDamagedPieceRecord(aColPoints[i].pieceA, impulseA, B, aColPoints[i].normal);
- float imp = impulseA;
- if(A->IsVehicle() && A->GetUp().z < -0.6f &&
- Abs(A->m_vecMoveSpeed.x) < 0.05f &&
- Abs(A->m_vecMoveSpeed.y) < 0.05f)
- imp *= 0.1f;
+ if(CSurfaceTable::GetAdhesionGroup(aColPoints[i].surfaceB) == ADHESIVE_SAND)
+ aColPoints[i].surfaceB = SURFACE_SAND;
- float turnSpeedDiff = A->m_vecTurnSpeed.MagnitudeSqr();
- float moveSpeedDiff = A->m_vecMoveSpeed.MagnitudeSqr();
+ float turnSpeedDiff = A->m_vecTurnSpeed.MagnitudeSqr();
+ float moveSpeedDiff = A->m_vecMoveSpeed.MagnitudeSqr();
- DMAudio.ReportCollision(A, B, aColPoints[i].surfaceA, aColPoints[i].surfaceB, imp, Max(turnSpeedDiff, moveSpeedDiff));
+ if(A->GetUp().z < -0.6f &&
+ Abs(A->m_vecMoveSpeed.x) < 0.05f &&
+ Abs(A->m_vecMoveSpeed.y) < 0.05f)
+ DMAudio.ReportCollision(A, B, aColPoints[i].surfaceA, aColPoints[i].surfaceB, 0.1f*impulseA, Max(turnSpeedDiff, moveSpeedDiff));
+ else
+ DMAudio.ReportCollision(A, B, aColPoints[i].surfaceA, aColPoints[i].surfaceB, impulseA, Max(turnSpeedDiff, moveSpeedDiff));
+
+ }else{
+ if(impulseA > A->m_fDamageImpulse)
+ A->SetDamagedPieceRecord(aColPoints[i].pieceA, impulseA, B, aColPoints[i].normal);
+
+ float turnSpeedDiff = A->m_vecTurnSpeed.MagnitudeSqr();
+ float moveSpeedDiff = A->m_vecMoveSpeed.MagnitudeSqr();
+
+ DMAudio.ReportCollision(A, B, aColPoints[i].surfaceA, aColPoints[i].surfaceB, impulseA, Max(turnSpeedDiff, moveSpeedDiff));
+ }
}
}else{
for(i = 0; i < numCollisions; i++){
@@ -1527,38 +1711,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]))
@@ -1577,7 +1775,13 @@ CPhysical::ProcessCollisionSectorList(CPtrList *lists)
A->m_vecMoveFriction.y += moveSpeed.y * -0.3f / numCollisions;
A->m_vecTurnFriction += turnSpeed * -0.3f / numCollisions;
}
- return true;
+
+ if(B->IsObject() && Bobj->m_nCollisionDamageEffect && maxImpulseA > 20.0f)
+ Bobj->ObjectDamage(maxImpulseA);
+
+ if(!CWorld::bSecondShift)
+ return true;
+ ret = true;
}
}else{
@@ -1717,9 +1921,25 @@ 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::GetModelInfo(B->GetModelIndex())->GetColModel()->boundingBox.GetSize();
+ size = B->GetMatrix() * size;
+ if(size.z < B->GetPosition().z ||
+ (Invert(A->GetMatrix(), inv) * size).z < 0.0f)
+ Bobj->ObjectDamage(50.0f);
+ }
}else if(A->IsObject() && A->bUsesCollision && B->IsVehicle()){
if(Aobj->m_nCollisionDamageEffect && maxImpulseB > 20.0f)
Aobj->ObjectDamage(maxImpulseB);
+ else if(Aobj->m_nCollisionDamageEffect >= DAMAGE_EFFECT_SMASH_COMPLETELY){
+ CMatrix inv;
+ CVector size = CModelInfo::GetModelInfo(A->GetModelIndex())->GetColModel()->boundingBox.GetSize();
+ size = A->GetMatrix() * size;
+ if(size.z < A->GetPosition().z ||
+ (Invert(B->GetMatrix(), inv) * size).z < 0.0f)
+ Aobj->ObjectDamage(50.0f);
+ }
}
if(B->GetStatus() == STATUS_SIMPLE){
@@ -1728,13 +1948,15 @@ CPhysical::ProcessCollisionSectorList(CPtrList *lists)
CCarCtrl::SwitchVehicleToRealPhysics((CVehicle*)B);
}
- return true;
+ if(!CWorld::bSecondShift)
+ return true;
+ ret = true;
}
}
}
- return false;
+ return ret;
}
bool
@@ -1763,6 +1985,8 @@ CPhysical::CheckCollision_SimpleCar(void)
return false;
}
+float PHYSICAL_SHIFT_SPEED_DAMP = 0.707f;
+
void
CPhysical::ProcessShift(void)
{
@@ -1772,6 +1996,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();
@@ -1789,11 +2020,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;
@@ -1805,6 +2044,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)
{
@@ -1836,31 +2078,78 @@ CPhysical::ProcessCollision(void)
// Save current state
CMatrix savedMatrix(GetMatrix());
+ float savedElasticity = m_fElasticity;
+ CVector savedMoveSpeed = m_vecMoveSpeed;
float savedTimeStep = CTimer::GetTimeStep();
int8 n = 1; // The number of steps we divide the time step into
float step = 0.0f; // divided time step
float distSq = m_vecMoveSpeed.MagnitudeSqr() * sq(CTimer::GetTimeStep());
- if(IsPed() && (distSq >= sq(0.2f) || ped->IsPlayer())){
- if(ped->IsPlayer())
- n = Max(NUMSTEPS(0.2f), 2.0f);
- else
- n = NUMSTEPS(0.3f);
+ if(IsPed() && (distSq >= sq(0.3f) || ped->IsPlayer())){
+ if(ped->IsPlayer()){
+ if(ped->m_pCurrentPhysSurface)
+ n = Max(NUMSTEPS(0.15f), 4.0f);
+ else
+ n = Max(NUMSTEPS(0.3f), 2.0f);
+ }else
+ n = NUMSTEPS(0.45f);
step = savedTimeStep / n;
+ if(!ped->IsPlayer())
+ ped->m_fElasticity *= HIGHSPEED_ELASTICITY_MULT_PED;
}else if(IsVehicle() && distSq >= sq(0.4f)){
if(GetStatus() == STATUS_PLAYER)
n = NUMSTEPS(0.2f);
else
n = distSq > 0.32f ? NUMSTEPS(0.3f) : NUMSTEPS(0.4f);
step = savedTimeStep / n;
- }else if(IsObject()){
+
+ CVector bbox = GetColModel()->boundingBox.GetSize();
+ float relDistX = Abs(DotProduct(m_vecMoveSpeed, GetRight())) * CTimer::GetTimeStep() / bbox.x;
+ float relDistY = Abs(DotProduct(m_vecMoveSpeed, GetForward())) * CTimer::GetTimeStep() / bbox.y;
+ float relDistZ = Abs(DotProduct(m_vecMoveSpeed, GetUp())) * CTimer::GetTimeStep() / bbox.z;
+ if(Max(relDistX, Max(relDistY, relDistZ)) < 1.0f){
+ // check if we can get away with simplified processing
+
+ ApplyMoveSpeed();
+ ApplyTurnSpeed();
+ GetMatrix().Reorthogonalise();
+ bSkipLineCol = false;
+ m_bIsVehicleBeingShifted = false;
+
+ bJustCheckCollision = true;
+ bUsesCollision = false;
+ if(!CheckCollision()){
+ bJustCheckCollision = false;
+ bUsesCollision = true;
+ if(IsVehicle())
+ ((CVehicle*)this)->bVehicleColProcessed = true;
+
+ bHitByTrain = false;
+ m_fDistanceTravelled = (GetPosition() - savedMatrix.GetPosition()).Magnitude();
+ bSkipLineCol = false;
+
+ bIsStuck = false;
+ bIsInSafePosition = true;
+ m_fElasticity = savedElasticity;
+ RemoveAndAdd();
+ return;
+ }
+ bJustCheckCollision = false;
+ bUsesCollision = true;
+ GetMatrix() = savedMatrix;
+ m_vecMoveSpeed = savedMoveSpeed;
+ if(IsVehicle() && ((CVehicle*)this)->bIsLawEnforcer)
+ m_fElasticity *= HIGHSPEED_ELASTICITY_MULT_COPCAR;
+ }
+ }else if(IsObject() && ((CObject*)this)->ObjectCreatedBy != TEMP_OBJECT){
int responsecase = ((CObject*)this)->m_nSpecialCollisionResponseCases;
if(responsecase == COLLRESPONSE_LAMPOST){
CVector speedUp = { 0.0f, 0.0f, 0.0f };
CVector speedDown = { 0.0f, 0.0f, 0.0f };
- speedUp.z = GetBoundRadius();
- speedDown.z = -speedUp.z;
+ CColModel *colModel = GetColModel();
+ speedUp.z = colModel->boundingBox.max.z;
+ speedDown.z = colModel->boundingBox.min.z;
speedUp = Multiply3x3(GetMatrix(), speedUp);
speedDown = Multiply3x3(GetMatrix(), speedDown);
speedUp = GetSpeed(speedUp);
@@ -1900,6 +2189,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 &&
@@ -1917,7 +2207,11 @@ CPhysical::ProcessCollision(void)
car->m_aSuspensionSpringRatio[2] = 1.0f;
car->m_aSuspensionSpringRatio[3] = 1.0f;
}else if(veh->m_vehType == VEHICLE_TYPE_BIKE){
- assert(0 && "TODO - but unused");
+ CBike *bike = (CBike*)this;
+ bike->m_aSuspensionSpringRatio[0] = 1.0f;
+ bike->m_aSuspensionSpringRatio[1] = 1.0f;
+ bike->m_aSuspensionSpringRatio[2] = 1.0f;
+ bike->m_aSuspensionSpringRatio[3] = 1.0f;
}
}
}
@@ -1929,15 +2223,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;
}
}
@@ -1947,5 +2241,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 f8921a5c..926b9762 100644
--- a/src/entities/Physical.h
+++ b/src/entities/Physical.h
@@ -19,7 +19,6 @@ 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
@@ -40,7 +39,6 @@ public:
int8 m_phys_unused2;
uint8 m_nStaticFrames;
uint8 m_nCollisionRecords;
- bool m_bIsVehicleBeingShifted;
CEntity *m_aCollisionRecords[PHYSICAL_MAX_COLLISIONRECORDS];
float m_fDistanceTravelled;
@@ -54,12 +52,17 @@ public:
uint8 bIsHeavy : 1;
uint8 bAffectedByGravity : 1;
uint8 bInfiniteMass : 1;
+ uint8 m_phy_flagA08 : 1;
uint8 bIsInWater : 1;
- uint8 m_phy_flagA10 : 1; // unused
uint8 m_phy_flagA20 : 1; // unused
uint8 bHitByTrain : 1;
uint8 bSkipLineCol : 1;
+ uint8 bIsFrozen : 1;
+ uint8 bDontLoadCollision : 1;
+ uint8 m_bIsVehicleBeingShifted : 1; // wrong name - also used on but never set for peds
+ uint8 bJustCheckCollision : 1; // just see if there is a collision
+
uint8 m_nSurfaceTouched;
int8 m_nZoneLevel;
@@ -116,6 +119,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;
@@ -144,11 +158,13 @@ public:
void ApplyFrictionTurnForce(const CVector &j, const CVector &p) { ApplyFrictionTurnForce(j.x, j.y, j.z, p.x, p.y, p.z); }
// springRatio: 1.0 fully extended, 0.0 fully compressed
bool ApplySpringCollision(float springConst, CVector &springDir, CVector &point, float springRatio, float bias);
+ bool ApplySpringCollisionAlt(float springConst, CVector &springDir, CVector &point, float springRatio, float bias, CVector &forceDir);
bool ApplySpringDampening(float damping, CVector &springDir, CVector &point, CVector &speed);
void ApplyGravity(void);
void ApplyFriction(void);
void ApplyAirResistance(void);
bool ApplyCollision(CPhysical *B, CColPoint &colpoint, float &impulseA, float &impulseB);
+ bool ApplyCollision(CColPoint &colpoint, float &impulse);
bool ApplyCollisionAlt(CEntity *B, CColPoint &colpoint, float &impulse, CVector &moveSpeed, CVector &turnSpeed);
bool ApplyFriction(CPhysical *B, float adhesiveLimit, CColPoint &colpoint);
bool ApplyFriction(float adhesiveLimit, CColPoint &colpoint);
@@ -159,5 +175,3 @@ public:
bool CheckCollision(void);
bool CheckCollision_SimpleCar(void);
};
-
-VALIDATE_SIZE(CPhysical, 0x128);
diff --git a/src/entities/Treadable.h b/src/entities/Treadable.h
index c3160f47..c3ab755e 100644
--- a/src/entities/Treadable.h
+++ b/src/entities/Treadable.h
@@ -8,10 +8,5 @@ public:
static void *operator new(size_t);
static void operator delete(void*, size_t);
- int16 m_nodeIndices[2][12]; // first car, then ped
-
bool GetIsATreadable(void) { return true; }
};
-
-VALIDATE_SIZE(CTreadable, 0x94);
-
diff --git a/src/extras/custompipes.cpp b/src/extras/custompipes.cpp
index bb3ebd2e..d6c8e065 100644
--- a/src/extras/custompipes.cpp
+++ b/src/extras/custompipes.cpp
@@ -337,8 +337,8 @@ ReadTweakValueTable(char *fp, InterpolatedValue &interp)
* Neo Vehicle pipe
*/
-int32 VehiclePipeSwitch = VEHICLEPIPE_MATFX;
-float VehicleShininess = 0.7f; // the default is a bit extreme
+int32 VehiclePipeSwitch = VEHICLEPIPE_NEO;
+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 b39efd47..01de3f78 100644
--- a/src/extras/custompipes_d3d9.cpp
+++ b/src/extras/custompipes_d3d9.cpp
@@ -131,6 +131,7 @@ vehicleRenderCB(rw::Atomic *atomic, rw::d3d9::InstanceDataHeader *header)
drawInst(header, inst);
inst++;
}
+
d3d::setTexture(1, nil);
SetRenderState(SRCBLEND, BLENDSRCALPHA);
@@ -182,7 +183,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)
@@ -240,7 +241,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++;
@@ -259,9 +260,9 @@ CreateWorldPipe(void)
neoWorld_VS = rw::d3d::createVertexShader(default_UV2_VS_cso);
assert(neoWorld_VS);
-#include "shaders/neoWorldIII_PS.inc"
- neoWorldIII_PS = rw::d3d::createPixelShader(neoWorldIII_PS_cso);
- assert(neoWorldIII_PS);
+#include "shaders/neoWorldVC_PS.inc"
+ neoWorldVC_PS = rw::d3d::createPixelShader(neoWorldVC_PS_cso);
+ assert(neoWorldVC_PS);
rw::d3d9::ObjPipeline *pipe = rw::d3d9::ObjPipeline::create();
@@ -276,8 +277,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();
diff --git a/src/extras/custompipes_gl.cpp b/src/extras/custompipes_gl.cpp
index 861a831e..4cd6607b 100644
--- a/src/extras/custompipes_gl.cpp
+++ b/src/extras/custompipes_gl.cpp
@@ -133,9 +133,10 @@ vehicleRenderCB(rw::Atomic *atomic, rw::gl3::InstanceDataHeader *header)
inst++;
}
- SetRenderState(SRCBLEND, BLENDSRCALPHA);
setTexture(1, nil);
+ SetRenderState(SRCBLEND, BLENDSRCALPHA);
+
#ifndef RW_GL_USE_VAOS
disableAttribPointers(header->attribDesc, header->numAttribs);
#endif
@@ -252,7 +253,6 @@ worldRenderCB(rw::Atomic *atomic, rw::gl3::InstanceDataHeader *header)
drawInst(header, inst);
inst++;
}
- setTexture(1, nil);
#ifndef RW_GL_USE_VAOS
disableAttribPointers(header->attribDesc, header->numAttribs);
#endif
@@ -270,10 +270,10 @@ CreateWorldPipe(void)
ReadTweakValueTable((char*)work_buff, WorldLightmapBlend);
{
-#include "shaders/neoWorldIII_fs_gl.inc"
+#include "shaders/neoWorldVC_fs_gl.inc"
#include "shaders/default_UV2_gl.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);
}
diff --git a/src/extras/frontendoption.cpp b/src/extras/frontendoption.cpp
index a3c4b9e3..1f154250 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* saveName)
+void FrontendOptionAddSelect(const char* gxtKey, uint16 x, uint16 y, uint8 align, const char** rightTexts, int8 numRightTexts, int8 *var, bool onlyApplyOnEnter, ChangeFunc changeFunc, const char* saveName)
{
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*));
@@ -144,12 +135,15 @@ void FrontendOptionAddSelect(const char* gxtKey, const char** rightTexts, int8 n
option.m_CFOSelect->changeFunc = changeFunc;
}
-void FrontendOptionAddDynamic(const char* gxtKey, DrawFunc drawFunc, int8 *var, ButtonPressFunc buttonPressFunc, const char* saveName)
+void FrontendOptionAddDynamic(const char* gxtKey, uint16 x, uint16 y, uint8 align, DrawFunc drawFunc, int8 *var, ButtonPressFunc buttonPressFunc, 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;
@@ -158,21 +152,15 @@ void FrontendOptionAddDynamic(const char* gxtKey, DrawFunc drawFunc, int8 *var,
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 19340b20..6670c323 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
@@ -52,8 +47,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);
@@ -83,9 +77,10 @@ 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 saveName 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* saveName = nil);
-void FrontendOptionAddDynamic(const char* gxtKey, DrawFunc rightTextDrawFunc, int8 *var, ButtonPressFunc buttonPressFunc, const char* saveName = nil);
+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* saveName = nil);
+void FrontendOptionAddDynamic(const char* gxtKey, uint16 x, uint16 y, uint8 align, DrawFunc rightTextDrawFunc, int8 *var, ButtonPressFunc buttonPressFunc, const char* saveName = 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 d3b8b8ac..2ea08141 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
@@ -142,20 +143,21 @@ CPostFX::Open(RwCamera *cam)
#ifdef RW_D3D9
-#include "shaders/colourfilterIII_PS.inc"
- colourfilterIII_PS = rw::d3d::createPixelShader(colourfilterIII_PS_cso);
+#include "shaders/colourfilterVC_PS.inc"
+ colourfilterVC_PS = rw::d3d::createPixelShader(colourfilterVC_PS_cso);
#include "shaders/contrastPS.inc"
contrast_PS = rw::d3d::createPixelShader(contrastPS_cso);
#endif
#ifdef RW_OPENGL
using namespace rw::gl3;
+
{
#include "shaders/im2d_gl.inc"
-#include "shaders/colourfilterIII_fs_gl.inc"
+#include "shaders/colourfilterVC_fs_gl.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);
}
{
@@ -182,9 +184,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);
@@ -192,9 +194,9 @@ CPostFX::Close(void)
}
#endif
#ifdef RW_OPENGL
- if(colourFilterIII){
- colourFilterIII->destroy();
- colourFilterIII = nil;
+ if(colourFilterVC){
+ colourFilterVC->destroy();
+ colourFilterVC = nil;
}
if(contrast){
contrast->destroy();
@@ -209,37 +211,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
@@ -267,12 +267,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);
@@ -288,18 +288,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);
@@ -336,9 +336,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)
@@ -355,11 +354,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;
}
@@ -374,45 +386,19 @@ 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;
- }
-
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);
@@ -428,10 +414,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){
@@ -446,10 +430,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);
@@ -467,4 +449,39 @@ CPostFX::Render(RwCamera *cam, uint32 red, uint32 green, uint32 blue, uint32 blu
bJustInitialised = true;
}
+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/Makefile b/src/extras/shaders/Makefile
index 51e009d6..5089e16a 100644
--- a/src/extras/shaders/Makefile
+++ b/src/extras/shaders/Makefile
@@ -1,7 +1,7 @@
all: im2d_gl.inc simple_fs_gl.inc default_UV2_gl.inc \
- colourfilterIII_fs_gl.inc contrast_fs_gl.inc \
+ colourfilterVC_fs_gl.inc contrast_fs_gl.inc \
neoRim_gl.inc neoRimSkin_gl.inc \
- neoWorldIII_fs_gl.inc neoGloss_vs_gl.inc neoGloss_fs_gl.inc \
+ neoWorldVC_fs_gl.inc neoGloss_vs_gl.inc neoGloss_fs_gl.inc \
neoVehicle_vs_gl.inc neoVehicle_fs_gl.inc \
im2d_UV2_gl.inc screenDroplet_fs_gl.inc
@@ -10,6 +10,10 @@ im2d_gl.inc: im2d.vert
sed 's/..*/"&\\n"/' im2d.vert;\
echo ';') >im2d_gl.inc
+colourfilterVC_fs_gl.inc: colourfilterVC.frag
+ (echo 'const char *colourfilterVC_frag_src =';\
+ sed 's/..*/"&\\n"/' colourfilterVC.frag;\
+ echo ';') >colourfilterVC_fs_gl.inc
simple_fs_gl.inc: simple.frag
(echo 'const char *simple_frag_src =';\
sed 's/..*/"&\\n"/' simple.frag;\
@@ -22,11 +26,6 @@ default_UV2_gl.inc: default_UV2.vert
-colourfilterIII_fs_gl.inc: colourfilterIII.frag
- (echo 'const char *colourfilterIII_frag_src =';\
- sed 's/..*/"&\\n"/' colourfilterIII.frag;\
- echo ';') >colourfilterIII_fs_gl.inc
-
contrast_fs_gl.inc: contrast.frag
(echo 'const char *contrast_frag_src =';\
sed 's/..*/"&\\n"/' contrast.frag;\
@@ -43,10 +42,10 @@ neoRimSkin_gl.inc: neoRimSkin.vert
sed 's/..*/"&\\n"/' neoRimSkin.vert;\
echo ';') >neoRimSkin_gl.inc
-neoWorldIII_fs_gl.inc: neoWorldIII.frag
- (echo 'const char *neoWorldIII_frag_src =';\
- sed 's/..*/"&\\n"/' neoWorldIII.frag;\
- echo ';') >neoWorldIII_fs_gl.inc
+neoWorldVC_fs_gl.inc: neoWorldVC.frag
+ (echo 'const char *neoWorldVC_frag_src =';\
+ sed 's/..*/"&\\n"/' neoWorldVC.frag;\
+ echo ';') >neoWorldVC_fs_gl.inc
neoGloss_fs_gl.inc: neoGloss.frag
(echo 'const char *neoGloss_frag_src =';\
diff --git a/src/extras/shaders/colourfilterIII_PS.cso b/src/extras/shaders/colourfilterIII_PS.cso
deleted file mode 100644
index cc41bcec..00000000
--- a/src/extras/shaders/colourfilterIII_PS.cso
+++ /dev/null
Binary files differ
diff --git a/src/extras/shaders/colourfilterIII_PS.inc b/src/extras/shaders/colourfilterIII_PS.inc
deleted file mode 100644
index db49de6c..00000000
--- a/src/extras/shaders/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/colourfilterIII.frag b/src/extras/shaders/colourfilterVC.frag
index b41cb94a..9db3950e 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/colourfilterVC_PS.cso b/src/extras/shaders/colourfilterVC_PS.cso
new file mode 100644
index 00000000..4b0e9f3f
--- /dev/null
+++ b/src/extras/shaders/colourfilterVC_PS.cso
Binary files differ
diff --git a/src/extras/shaders/colourfilterIII_PS.hlsl b/src/extras/shaders/colourfilterVC_PS.hlsl
index 27f099ef..1e62950b 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.0f;
diff --git a/src/extras/shaders/colourfilterVC_PS.inc b/src/extras/shaders/colourfilterVC_PS.inc
new file mode 100644
index 00000000..daa18360
--- /dev/null
+++ b/src/extras/shaders/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/colourfilterIII_fs_gl.inc b/src/extras/shaders/colourfilterVC_fs_gl.inc
index 6fd1935b..1f9bf6d8 100644
--- a/src/extras/shaders/colourfilterIII_fs_gl.inc
+++ b/src/extras/shaders/colourfilterVC_fs_gl.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/neoWorldIII_PS.cso b/src/extras/shaders/neoWorldIII_PS.cso
deleted file mode 100644
index 817888ef..00000000
--- a/src/extras/shaders/neoWorldIII_PS.cso
+++ /dev/null
Binary files differ
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/neoWorldVC_PS.cso b/src/extras/shaders/neoWorldVC_PS.cso
new file mode 100644
index 00000000..5e8d1696
--- /dev/null
+++ b/src/extras/shaders/neoWorldVC_PS.cso
Binary files differ
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/neoWorldIII_PS.inc b/src/extras/shaders/neoWorldVC_PS.inc
index a4631efb..eb8bf2ee 100644
--- a/src/extras/shaders/neoWorldIII_PS.inc
+++ b/src/extras/shaders/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/neoWorldIII_fs_gl.inc b/src/extras/shaders/neoWorldVC_fs_gl.inc
index afd75f57..b4385fc7 100644
--- a/src/extras/shaders/neoWorldIII_fs_gl.inc
+++ b/src/extras/shaders/neoWorldVC_fs_gl.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 2e04aed2..a35a4ecb 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 a8b1b182..3ac3e2b9 100644
--- a/src/math/Matrix.cpp
+++ b/src/math/Matrix.cpp
@@ -458,62 +458,39 @@ 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
float (*scr_fm)[4] = (float (*)[4])&src.m_matrix;
float (*dst_fm)[4] = (float (*)[4])&dst.m_matrix;
dst_fm[3][0] = dst_fm[3][1] = dst_fm[3][2] = 0.0f;
-#ifndef FIX_BUGS
- dst_fm[3][3] = scr_fm[3][3];
-#endif
dst_fm[0][0] = scr_fm[0][0];
dst_fm[0][1] = scr_fm[1][0];
dst_fm[0][2] = scr_fm[2][0];
-#ifndef FIX_BUGS
- dst_fm[0][3] = scr_fm[3][0];
-#endif
+
dst_fm[1][0] = scr_fm[0][1];
dst_fm[1][1] = scr_fm[1][1];
dst_fm[1][2] = scr_fm[2][1];
-#ifndef FIX_BUGS
- dst_fm[1][3] = scr_fm[3][1];
-#endif
+
dst_fm[2][0] = scr_fm[0][2];
dst_fm[2][1] = scr_fm[1][2];
dst_fm[2][2] = scr_fm[2][2];
-#ifndef FIX_BUGS
- dst_fm[2][3] = scr_fm[3][2];
-#endif
+
dst_fm[3][0] += dst_fm[0][0] * scr_fm[3][0];
dst_fm[3][1] += dst_fm[0][1] * scr_fm[3][0];
dst_fm[3][2] += dst_fm[0][2] * scr_fm[3][0];
-#ifndef FIX_BUGS
- dst_fm[3][3] += dst_fm[0][3] * scr_fm[3][0];
-#endif
dst_fm[3][0] += dst_fm[1][0] * scr_fm[3][1];
dst_fm[3][1] += dst_fm[1][1] * scr_fm[3][1];
dst_fm[3][2] += dst_fm[1][2] * scr_fm[3][1];
-#ifndef FIX_BUGS
- dst_fm[3][3] += dst_fm[1][3] * scr_fm[3][1];
-#endif
dst_fm[3][0] += dst_fm[2][0] * scr_fm[3][2];
dst_fm[3][1] += dst_fm[2][1] * scr_fm[3][2];
dst_fm[3][2] += dst_fm[2][2] * scr_fm[3][2];
-#ifndef FIX_BUGS
- dst_fm[3][3] += dst_fm[2][3] * scr_fm[3][2];
-#endif
dst_fm[3][0] = -dst_fm[3][0];
dst_fm[3][1] = -dst_fm[3][1];
dst_fm[3][2] = -dst_fm[3][2];
-#ifndef FIX_BUGS
- dst_fm[3][3] = scr_fm[3][3] - dst_fm[3][3];
-#endif
return dst;
}
diff --git a/src/math/Matrix.h b/src/math/Matrix.h
index d8f6388d..d32b1d93 100644
--- a/src/math/Matrix.h
+++ b/src/math/Matrix.h
@@ -25,7 +25,8 @@ public:
CMatrix &operator+=(CMatrix const &rhs);
CMatrix &operator*=(CMatrix const &rhs);
- CVector &GetPosition(void){ return *(CVector*)&m_matrix.pos; }
+ const CVector &GetPosition(void) const { return *(CVector*)&m_matrix.pos; }
+ CVector& GetPosition(void) { return *(CVector*)&m_matrix.pos; }
CVector &GetRight(void) { return *(CVector*)&m_matrix.right; }
CVector &GetForward(void) { return *(CVector*)&m_matrix.up; }
CVector &GetUp(void) { return *(CVector*)&m_matrix.at; }
@@ -44,13 +45,18 @@ public:
{
float *pFloatMatrix = (float*)&m_matrix;
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
pFloatMatrix[i * 4 + j] *= scale;
}
+ void Scale(float sx, float sy, float sz)
+ {
+ float *pFloatMatrix = (float*)&m_matrix;
+ for (int i = 0; i < 3; i++){
+ pFloatMatrix[i * 4 + 0] *= sx;
+ pFloatMatrix[i * 4 + 1] *= sy;
+ pFloatMatrix[i * 4 + 2] *= sz;
+ }
+ }
void SetRotateXOnly(float angle);
@@ -85,6 +91,15 @@ public:
void CopyOnlyMatrix(CMatrix *other);
void SetUnity(void);
void ResetOrientation(void);
+ void CopyRwMatrix(RwMatrix *matrix){
+ m_matrix = *matrix;
+ }
+
+ void CopyToRwMatrix(RwMatrix *matrix){
+ *matrix = m_matrix;
+ RwMatrixUpdate(matrix);
+ }
+
void SetTranslateOnly(float x, float y, float z) {
m_matrix.pos.x = x;
m_matrix.pos.y = 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 a2779107..f05be242 100644
--- a/src/modelinfo/BaseModelInfo.cpp
+++ b/src/modelinfo/BaseModelInfo.cpp
@@ -4,12 +4,14 @@
#include "TxdStore.h"
#include "2dEffect.h"
#include "BaseModelInfo.h"
+#include "ModelInfo.h"
+//--MIAMI: file done
CBaseModelInfo::CBaseModelInfo(ModelInfoType type)
{
m_colModel = nil;
- m_twodEffects = nil;
+ m_2dEffectsID = -1;
m_objectId = -1;
m_refCount = 0;
m_txdSlot = -1;
@@ -23,7 +25,7 @@ CBaseModelInfo::Shutdown(void)
{
DeleteCollisionModel();
DeleteRwObject();
- m_twodEffects = nil;
+ m_2dEffectsID = -1;
m_num2dEffects = 0;
m_txdSlot = -1;
}
@@ -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 ae2b6668..23ba5e66 100644
--- a/src/modelinfo/BaseModelInfo.h
+++ b/src/modelinfo/BaseModelInfo.h
@@ -2,18 +2,20 @@
#include "Collision.h"
-#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(RwMatrix *) = 0;
virtual RwObject *CreateInstance(void) = 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 *GetName(void) { return m_name; }
void SetName(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 1ae936a7..3fa9a36f 100644
--- a/src/modelinfo/ClumpModelInfo.cpp
+++ b/src/modelinfo/ClumpModelInfo.cpp
@@ -5,7 +5,9 @@
#include "NodeName.h"
#include "VisibilityPlugins.h"
#include "ModelInfo.h"
-#include "ModelIndices.h"
+#include "AnimManager.h"
+
+//--MIAMI: file done
void
CClumpModelInfo::DeleteRwObject(void)
@@ -14,17 +16,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 +34,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 +72,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 +98,27 @@ CClumpModelInfo::SetClump(RpClump *clump)
}
RpHAnimHierarchySetFlags(hier, (RpHAnimHierarchyFlag)(rpHANIMHIERARCHYUPDATEMODELLINGMATRICES|rpHANIMHIERARCHYUPDATELTMS));
}
- if(strncmp(GetName(), "playerh", 8) == 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(strncmp(GetName(), "playerh", 8) == 0){
- RpClumpForAllAtomics(clump, SetAtomicRendererCB, (void*)CVisibilityPlugins::RenderPlayerCB);
-#endif
}
void
@@ -154,6 +150,7 @@ CClumpModelInfo::FindFrameFromIdCB(RwFrame *frame, void *data)
return assoc->frame ? nil : frame;
}
+//--MIAMI: 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
deleted file mode 100644
index 7535e6c5..00000000
--- a/src/modelinfo/MloModelInfo.cpp
+++ /dev/null
@@ -1,39 +0,0 @@
-#include "common.h"
-
-#include "VisibilityPlugins.h"
-#include "ModelInfo.h"
-
-void
-CMloModelInfo::ConstructClump()
-{
- m_clump = RpClumpCreate();
- RwFrame *mainFrame = RwFrameCreate();
- RwFrameSetIdentity(mainFrame);
- RpClumpSetFrame(m_clump, mainFrame);
-
- for (int i = firstInstance; i < lastInstance; i++) {
- int modelId = CModelInfo::GetMloInstanceStore().store[i].m_modelIndex;
- RwMatrix *attMat = CModelInfo::GetMloInstanceStore().store[i].GetMatrix().m_attachment;
- CSimpleModelInfo *minfo = (CSimpleModelInfo*)CModelInfo::GetModelInfo(modelId);
-
- if (minfo->m_atomics[0] != nil) {
- RpAtomic *newAtomic = RpAtomicClone(minfo->m_atomics[0]);
- RwFrame *newFrame = RwFrameCreate();
- if (newAtomic != nil && newFrame != nil) {
- *RwFrameGetMatrix(newFrame) = *attMat;
- RpAtomicSetFrame(newAtomic, newFrame);
- RwFrameAddChild(mainFrame, newFrame);
- RpClumpAddAtomic(m_clump, newAtomic);
- } else {
- debug("Failed to allocate memory while creating template MLO.\n");
- }
- }
- }
-
- if (RpClumpGetNumAtomics(m_clump) != 0) {
- CVisibilityPlugins::SetClumpModelInfo(m_clump, this);
- } else {
- RpClumpDestroy(m_clump);
- m_clump = nil;
- }
-} \ No newline at end of file
diff --git a/src/modelinfo/MloModelInfo.h b/src/modelinfo/MloModelInfo.h
deleted file mode 100644
index d4344706..00000000
--- a/src/modelinfo/MloModelInfo.h
+++ /dev/null
@@ -1,14 +0,0 @@
-#pragma once
-
-#include "ClumpModelInfo.h"
-
-class CMloModelInfo : public CClumpModelInfo
-{
-public:
- float field_34; // draw distance?
- int firstInstance;
- int lastInstance;
-public:
- CMloModelInfo(void) : CClumpModelInfo(MITYPE_MLO) {}
- void ConstructClump();
-}; \ No newline at end of file
diff --git a/src/modelinfo/ModelIndices.h b/src/modelinfo/ModelIndices.h
index c0f01929..182a0cea 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_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 dcde0df3..9e5b0470 100644
--- a/src/modelinfo/ModelInfo.cpp
+++ b/src/modelinfo/ModelInfo.cpp
@@ -4,18 +4,17 @@
#include "TempColModels.h"
#include "ModelIndices.h"
#include "ModelInfo.h"
-#include "Frontend.h"
+
+// --MIAMI: file done
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 +23,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 +96,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 +128,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 +198,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->GetName(), name))
+ return modelinfo;
+ }
+ return nil;
+}
+
bool
CModelInfo::IsBoatModel(int32 id)
{
@@ -215,31 +227,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)
{
- 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_HELI;
+}
+
+bool
+CModelInfo::IsPlaneModel(int32 id)
+{
+ 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 65cfa4e7..1ac7b0bb 100644
--- a/src/modelinfo/ModelInfo.h
+++ b/src/modelinfo/ModelInfo.h
@@ -3,49 +3,47 @@
#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"
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 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 b77cccda..bd515391 100644
--- a/src/modelinfo/PedModelInfo.cpp
+++ b/src/modelinfo/PedModelInfo.cpp
@@ -10,36 +10,18 @@
#include "ModelInfo.h"
#include "custompipes.h"
+//--MIAMI: file done
+
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 +37,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(strncmp(GetName(), "player", 7) == 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(strncmp(GetName(), "player", 7) == 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();
- if(strncmp(GetName(), "player", 7) == 0)
+ CreateHitColModelSkinned(clump);
+ RpClumpForAllAtomics(m_clump, SetAtomicRendererCB, (void*)CVisibilityPlugins::RenderPedCB);
+ if(strcmp(GetName(), "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 +61,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)
{
@@ -334,8 +105,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;
}
@@ -370,4 +141,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 f467fe8a..86e6b74a 100644
--- a/src/modelinfo/PedModelInfo.h
+++ b/src/modelinfo/PedModelInfo.h
@@ -4,8 +4,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,
@@ -16,7 +16,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
@@ -27,40 +35,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 416bdad5..2e6e557e 100644
--- a/src/modelinfo/SimpleModelInfo.cpp
+++ b/src/modelinfo/SimpleModelInfo.cpp
@@ -3,8 +3,11 @@
#include "General.h"
#include "Camera.h"
#include "ModelInfo.h"
+#include "AnimManager.h"
#include "custompipes.h"
+//--MIAMI: file done
+
#define LOD_DISTANCE (300.0f)
void
@@ -19,6 +22,8 @@ CSimpleModelInfo::DeleteRwObject(void)
RwFrameDestroy(f);
m_atomics[i] = nil;
RemoveTexDictionaryRef();
+ if(GetAnimFileIndex() != -1)
+ CAnimManager::RemoveAnimBlockRef(GetAnimFileIndex());
}
}
@@ -56,7 +61,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;
@@ -65,6 +70,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
@@ -72,13 +81,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
}
@@ -135,12 +151,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(GetName()+3, mi->GetName()+3)){
@@ -151,24 +175,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", GetName());
+ }
+ }else
+ m_lodDistances[2] = NEAR_DRAW_DIST;
}
}
diff --git a/src/modelinfo/SimpleModelInfo.h b/src/modelinfo/SimpleModelInfo.h
index 94e55a2f..0bb5fbe6 100644
--- a/src/modelinfo/SimpleModelInfo.h
+++ b/src/modelinfo/SimpleModelInfo.h
@@ -26,15 +26,22 @@ public:
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 +51,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 +70,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 cc2a7e34..b9d6f300 100644
--- a/src/modelinfo/VehicleModelInfo.cpp
+++ b/src/modelinfo/VehicleModelInfo.cpp
@@ -21,9 +21,10 @@
#include "ModelInfo.h"
#include "custompipes.h"
+//--MIAMI: done
+
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 +84,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 +143,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 +167,8 @@ RwObjectNameIdAssocation *CVehicleModelInfo::ms_vehicleDescs[] = {
bikeIds
};
+bool gbBlackCars;
+bool gbPinkCars;
CVehicleModelInfo::CVehicleModelInfo(void)
: CClumpModelInfo(MITYPE_VEHICLE)
@@ -161,6 +180,7 @@ CVehicleModelInfo::CVehicleModelInfo(void)
m_positions[i].z = 0.0f;
}
m_numColours = 0;
+ m_animFileIndex = -1;
}
void
@@ -191,7 +211,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 +224,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 +250,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)
{
@@ -386,30 +426,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") || strncmp(name, "extra", 5) == 0){
+ 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: not done by 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 +684,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 +821,9 @@ CVehicleModelInfo::GetEditableMaterialListCB(RpAtomic *atomic, void *data)
return atomic;
}
+static int maxFirstMaterials;
+static int maxSecondMaterials;
+
void
CVehicleModelInfo::FindEditableMaterialList(void)
{
@@ -746,6 +838,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 +848,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 +876,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 +904,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;
+ }
}
+//--MIAMI: unused
RwTexture*
CreateCarColourTexture(uint8 r, uint8 g, uint8 b)
{
@@ -927,7 +1024,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 +1058,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 +1112,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 +1134,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 +1150,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 +1168,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..bd8f5cb8
--- /dev/null
+++ b/src/modelinfo/WeaponModelInfo.cpp
@@ -0,0 +1,55 @@
+#include "common.h"
+
+#include "ModelInfo.h"
+#include "AnimManager.h"
+#include "VisibilityPlugins.h"
+
+//--MIAMI: file done
+
+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 9832399c..00000000
--- a/src/modelinfo/XtraCompsModelInfo.h
+++ /dev/null
@@ -1,12 +0,0 @@
-#pragma once
-
-#include "ClumpModelInfo.h"
-
-class CXtraCompsModelInfo : public CClumpModelInfo
-{
- int field_34;
-public:
- CXtraCompsModelInfo(void) : CClumpModelInfo(MITYPE_XTRACOMPS) { field_34 = 0; }
- void SetClump(RpClump*) {};
- void Shutdown(void) {};
-}; \ No newline at end of file
diff --git a/src/objects/CutsceneHead.cpp b/src/objects/CutsceneHead.cpp
deleted file mode 100644
index 15611c29..00000000
--- a/src/objects/CutsceneHead.cpp
+++ /dev/null
@@ -1,231 +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;
- UpdateRwFrame(); // android/xbox don't call this
- }
-
- 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::GetTimeStepNonClipped()/50.0f);
-}
-
-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 5c10d37d..8d1be357 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
+ RwRenderStateSet(rwRENDERSTATECULLMODE, (void *)rwCULLMODECULLNONE);
CObject::Render();
+ RwRenderStateSet(rwRENDERSTATECULLMODE, (void *)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..8656abbb 100644
--- a/src/objects/DummyObject.cpp
+++ b/src/objects/DummyObject.cpp
@@ -3,6 +3,8 @@
#include "DummyObject.h"
#include "Pools.h"
+// --MIAMI: file done
+
CDummyObject::CDummyObject(CObject *obj)
{
SetModelIndexNoCreate(obj->GetModelIndex());
@@ -10,4 +12,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 411e245a..0605f54f 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;
void *CObject::operator new(size_t sz) { return CPools::GetObjectPool()->New(); }
void *CObject::operator new(size_t sz, int handle) { return CPools::GetObjectPool()->New(handle);};
@@ -30,11 +39,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;
@@ -43,8 +53,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)
@@ -69,22 +83,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);
@@ -98,7 +113,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;
@@ -106,11 +122,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);
m_matrix.GetPosition() = vecPos;
m_matrix.UpdateRW();
@@ -121,27 +199,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;
}
@@ -149,17 +331,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);
@@ -169,133 +354,363 @@ CObject::ObjectDamage(float amount)
bBodyCastDamageEffect = true;
amount = 0.0f;
}
+#endif
if ((amount * m_fCollisionDamageMultiplier > 150.0f || bBodyCastDamageEffect) && m_nCollisionDamageEffect) {
- const CVector& vecPos = m_matrix.GetPosition();
+ const CVector &vecPos = m_matrix.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;
+ }
+ 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;
}
- else {
+ 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;
}
- 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_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_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_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_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_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_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_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;
}
- 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.3, secondaryColor, nRotationSpeed, 0, 0, 0);
+ }
+ }
+ 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;
}
}
}
@@ -307,9 +722,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;
@@ -326,18 +741,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;
- const CVector& vecPos = m_matrix.GetPosition();
+ CEntity *outEntity = nil;
+ const CVector &vecPos = m_matrix.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
@@ -352,6 +774,8 @@ CObject::CanBeDeleted(void)
return true;
case CUTSCENE_OBJECT:
return false;
+ case CONTROLLED_SUB_OBJECT:
+ return false;
default:
return true;
}
@@ -360,9 +784,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;
@@ -370,12 +794,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;
@@ -383,8 +807,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++) {
@@ -395,3 +819,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 c9a1bba8..e34043a8 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);
static void *operator new(size_t, int);
@@ -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..04ac0b9c 100644
--- a/src/objects/ObjectData.cpp
+++ b/src/objects/ObjectData.cpp
@@ -6,6 +6,8 @@
#include "FileMgr.h"
#include "ObjectData.h"
+//--MIAMI: file done
+
CObjectInfo CObjectData::ms_aObjectInfo[NUMOBJECTINFO];
// Another ugly file reader
@@ -18,11 +20,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 +90,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 +113,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 +156,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 71f223d7..4d080d1f 100644
--- a/src/objects/ParticleObject.cpp
+++ b/src/objects/ParticleObject.cpp
@@ -53,7 +53,7 @@ CAudioHydrant::Remove(CParticleObject *particleobject)
{
DMAudio.DestroyEntity(List[i].AudioEntity);
List[i].AudioEntity = AEHANDLE_NONE;
- List[i].pParticleObject = NULL;
+ List[i].pParticleObject = nil;
}
}
}
@@ -62,8 +62,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)
{
@@ -78,20 +78,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];
@@ -127,12 +127,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);
@@ -150,7 +148,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;
@@ -165,229 +163,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;
+ ScreenDroplets::RegisterSplash(pobj);
#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;
-#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)
{
@@ -414,7 +426,7 @@ CParticleObject::UpdateAll(void)
{
CParticleObject *pobj = pCloseListHead;
CParticleObject *nextpobj;
- if ( pobj != NULL )
+ if ( pobj != nil )
{
do
{
@@ -422,7 +434,7 @@ CParticleObject::UpdateAll(void)
pobj->UpdateClose();
pobj = nextpobj;
}
- while ( nextpobj != NULL );
+ while ( nextpobj != nil );
}
}
@@ -432,7 +444,7 @@ CParticleObject::UpdateAll(void)
CParticleObject *pobj = pFarListHead;
CParticleObject *nextpobj;
- if ( pobj != NULL )
+ if ( pobj != nil )
{
do
{
@@ -448,7 +460,7 @@ CParticleObject::UpdateAll(void)
pobj = nextpobj;
}
- while ( nextpobj != NULL );
+ while ( nextpobj != nil );
}
}
}
@@ -503,7 +515,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;
@@ -534,7 +546,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++ )
@@ -553,7 +565,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;
@@ -561,7 +573,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
{
@@ -578,7 +590,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);
}
}
@@ -587,13 +599,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
{
@@ -606,7 +618,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);
}
}
@@ -628,7 +640,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));
}
@@ -637,7 +649,6 @@ void CParticleObject::UpdateClose(void)
case POBJECT_PED_WATER_SPLASH:
{
-#ifdef PC_PARTICLE
CRGBA colorsmoke(255, 255, 255, 196);
CVector pos = this->GetPosition();
@@ -655,9 +666,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);
@@ -665,9 +676,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);
@@ -675,18 +686,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);
}
@@ -706,7 +717,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);
@@ -716,7 +727,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);
@@ -726,7 +737,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);
@@ -736,72 +747,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();
@@ -825,8 +779,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);
@@ -835,8 +789,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;
@@ -844,8 +798,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;
@@ -853,8 +807,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++ )
@@ -873,88 +827,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);
- }
-#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);
+ CParticle::AddParticle(PARTICLE_CAR_SPLASH, splashpos, splashvel, nil, 0.0f, this->m_Color);
}
-#endif
+
break;
}
@@ -973,75 +869,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;
}
@@ -1062,7 +1002,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);
}
}
@@ -1070,7 +1010,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);
}
}
@@ -1114,15 +1054,15 @@ CParticleObject::UpdateFar(void)
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;
@@ -1131,7 +1071,7 @@ CParticleObject::SaveParticle(uint8 *buffer, uint32 *length)
int32 objectsLength = sizeof(CParticleObject) * (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 )
{
#if 0 // todo better
*(CParticleObject*)buffer = *p;
@@ -1141,7 +1081,7 @@ CParticleObject::SaveParticle(uint8 *buffer, uint32 *length)
buffer += sizeof(CParticleObject);
}
- for ( CParticleObject *p = pFarListHead; p != NULL; p = p->m_pNext )
+ for ( CParticleObject *p = pFarListHead; p != nil; p = p->m_pNext )
{
#if 0 // todo better
*(CParticleObject*)buffer = *p;
@@ -1159,7 +1099,7 @@ CParticleObject::SaveParticle(uint8 *buffer, uint32 *length)
bool
CParticleObject::LoadParticle(uint8 *buffer, uint32 length)
{
- ASSERT( buffer != NULL );
+ ASSERT( buffer != nil );
RemoveAllParticleObjects();
@@ -1180,7 +1120,7 @@ CParticleObject::LoadParticle(uint8 *buffer, uint32 length)
CParticleObject *src = (CParticleObject *)buffer;
buffer += sizeof(CParticleObject);
- if ( dst == NULL )
+ if ( dst == nil )
return false;
MoveToList(&pUnusedListHead, &pCloseListHead, dst);
@@ -1192,7 +1132,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;
@@ -1208,22 +1148,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];
@@ -1234,20 +1216,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;
@@ -1256,7 +1238,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/Projectile.cpp b/src/objects/Projectile.cpp
index fe8b0c68..fc4b25cf 100644
--- a/src/objects/Projectile.cpp
+++ b/src/objects/Projectile.cpp
@@ -2,6 +2,8 @@
#include "Projectile.h"
+// --MIAMI: file done
+
CProjectile::CProjectile(int32 model) : CObject()
{
m_fMass = 1.0f;
diff --git a/src/objects/Stinger.cpp b/src/objects/Stinger.cpp
new file mode 100644
index 00000000..b3660881
--- /dev/null
+++ b/src/objects/Stinger.cpp
@@ -0,0 +1,232 @@
+#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;
+ 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];
+ if (spikeSegment->m_entryInfoList.first != nil)
+ spikeSegment->bRemoveFromWorld = true;
+ else
+ delete spikeSegment;
+ }
+ bIsDeployed = false;
+}
+
+void
+CStinger::Deploy(CPed *pPed)
+{
+ if (NumOfStingerSegments < NUM_STINGER_SEGMENTS*2 && !pPed->bInVehicle && pPed->IsPedInControl()) {
+ if (!bIsDeployed && RpAnimBlendClumpGetAssociation(pPed->GetClump(), ANIM_WEAPON_THROWU) == nil) {
+ Init(pPed);
+ pPed->SetPedState(PED_DEPLOY_STINGER);
+ CAnimManager::AddAnimation(pPed->GetClump(), ASSOCGRP_STD, ANIM_WEAPON_THROWU);
+ }
+ }
+}
+
+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);
+ }
+ }
+ }
+ }
+ }
+}
+
+void
+CStinger::Process()
+{
+ switch (m_nSpikeState)
+ {
+ case STINGERSTATE_NONE:
+ if (pOwner != nil
+ && !pOwner->bInVehicle
+ && pOwner->GetPedState() == PED_DEPLOY_STINGER
+ && RpAnimBlendClumpGetAssociation(pOwner->GetClump(), ANIM_WEAPON_THROWU)->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();
+ break;
+ }
+ 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 a2f44357..079024f6 100644
--- a/src/peds/CivilianPed.cpp
+++ b/src/peds/CivilianPed.cpp
@@ -9,37 +9,43 @@
#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
+// --MIAMI: file done
+
CCivilianPed::CCivilianPed(ePedType pedtype, uint32 mi) : CPed(pedtype)
{
SetModelIndex(mi);
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 +64,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 +84,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 +117,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 +135,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 +149,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 +167,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 +203,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 +239,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,23 +256,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 (!isPhoneAvailable(m_phoneId)) {
- RestorePreviousState();
- if (crimeReporters[m_phoneId] == this)
- crimeReporters[m_phoneId] = nil;
- m_phoneId = -1;
- bRunningToPhone = false;
- } else {
- crimeReporters[m_phoneId] = this;
- m_facePhoneStart = true;
- SetPedState(PED_FACE_PHONE);
- }
-#else
} else if (bRunningToPhone) {
if (gPhoneInfo.m_aPhones[m_phoneId].m_nState != PHONE_STATE_FREE) {
RestorePreviousState();
@@ -285,9 +268,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;
@@ -295,7 +277,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();
@@ -361,6 +344,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) {
@@ -371,19 +356,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;
@@ -396,6 +385,7 @@ CCivilianPed::ProcessControl(void)
} else {
bWanderPathAfterExitingCar = true;
CWorld::Players[CWorld::PlayerInFocus].m_pHooker = nil;
+ ClearLeader();
SetObjective(OBJECTIVE_LEAVE_CAR, m_pMyVehicle);
}
}
@@ -416,6 +406,11 @@ CCivilianPed::ProcessControl(void)
if (IsPedInControl())
CivilianAI();
+ if (CharCreatedBy == RANDOM_CHAR) {
+ EnterVacantNearbyCars();
+ UseNearbyAttractors();
+ }
+
if (CTimer::GetTimeInMilliseconds() > m_timerUnused) {
m_stateUnused = 0;
m_timerUnused = 0;
@@ -425,26 +420,13 @@ CCivilianPed::ProcessControl(void)
Avoid();
}
-// It's "CPhoneInfo::ProcessNearestFreePhone" in PC IDB but that's not true, someone made it up.
+// --MIAMI: Done
bool
CPed::RunToReportCrime(eCrimeType crimeToReport)
{
-#ifdef PEDS_REPORT_CRIMES_ON_PHONE
- if (bRunningToPhone) {
- if (!isPhoneAvailable(m_phoneId)) {
- 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);
@@ -452,17 +434,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;
-#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 e518fae4..762c7f1a 100644
--- a/src/peds/CopPed.cpp
+++ b/src/peds/CopPed.cpp
@@ -16,14 +16,20 @@
#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)
+// --MIAMI: file done except TODOs
+
+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 +37,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 +54,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 +113,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 +150,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 +192,7 @@ CCopPed::ClearPursuit(void)
bNotAllowedToDuck = false;
bKindaStayInSamePlace = false;
m_bStopAndShootDisabledZone = false;
+ m_bDragsPlayerFromCar = false;
m_bZoneDisabled = false;
ClearObjective();
if (IsPedInControl()) {
@@ -197,6 +214,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 +324,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 +350,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 +413,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 +431,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_RBLOCK_CSHOOT);
- if (crouchShootAssoc)
- crouchShootAssoc->blendDelta = -1000.0f;
+ if (bIsDucking)
+ ClearDuck();
// Target is coming onto us
if (DotProduct(playerOrHisVeh->m_vecMoveSpeed, targetDist) > 0.0f) {
@@ -421,49 +460,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 +490,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 +525,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 +546,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_REACTION);
+ SetObjective(OBJECTIVE_HASSLE_CHAR, nearPed);
+ nearPed->SetObjective(OBJECTIVE_WAIT_ON_FOOT_FOR_COP, this);
+ m_nHassleTimer = CTimer::GetTimeInMilliseconds() + 100000;
+ }
+ }
+ }
+ }
}
}
}
}
}
-#endif
}
}
} else {
@@ -545,8 +580,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 +592,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 +621,7 @@ CCopPed::ProcessControl(void)
ArrestPlayer();
return;
}
- GetWeapon()->Update(m_audioEntityId);
+ GetWeapon()->Update(m_audioEntityId, nil);
if (m_moved.Magnitude() > 0.0f)
Avoid();
@@ -591,21 +637,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 +713,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 +747,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_UNK_129);
+
+ 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 9f87c12b..2eabfe04 100644
--- a/src/peds/EmergencyPed.cpp
+++ b/src/peds/EmergencyPed.cpp
@@ -9,6 +9,8 @@
#include "CarCtrl.h"
#include "Accident.h"
+// --MIAMI: file done
+
CEmergencyPed::CEmergencyPed(uint32 type) : CPed(type)
{
switch (type){
@@ -44,15 +46,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 +106,6 @@ CEmergencyPed::FiremanAI(void)
m_pAttendedFire = nearestFire;
#ifdef FIX_BUGS
bIsRunning = true;
- ++nearestFire->m_nFiremenPuttingOut;
#endif
}
break;
@@ -119,10 +117,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 +150,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 +166,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 +232,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 +245,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 +272,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 +312,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_CPR, 4.0f);
+ m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_MEDIC, ANIM_CPR, 4.0f);
bIsDucking = true;
}
SetLookTimer(2000);
@@ -380,6 +375,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 8859e61e..38e37430 100644
--- a/src/peds/Gangs.cpp
+++ b/src/peds/Gangs.cpp
@@ -2,12 +2,19 @@
#include "ModelIndices.h"
#include "Gangs.h"
+#include "General.h"
+#include "Streaming.h"
#include "Weapon.h"
+// --MIAMI: file done
+
CGangInfo CGangs::Gang[NUM_GANGS];
+bool CGangs::GangAttackWithCops[NUM_GANGS];
CGangInfo::CGangInfo() :
- m_nVehicleMI(MI_BUS),
+ m_nVehicleMI(-1),
+ m_nPedModel1MI(-1),
+ m_nPedModel2MI(-1),
m_nPedModelOverride(-1),
m_Weapon1(WEAPONTYPE_UNARMED),
m_Weapon2(WEAPONTYPE_UNARMED)
@@ -15,21 +22,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 df78902f..392ee1d4 100644
--- a/src/peds/Ped.cpp
+++ b/src/peds/Ped.cpp
@@ -30,19 +30,27 @@
#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"
+
+// --MIAMI: file done
CPed *gapTempPedList[50];
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;
@@ -51,16 +59,14 @@ void *CPed::operator new(size_t sz, int handle) { return CPools::GetPedPool()->N
void CPed::operator delete(void *p, size_t sz) { CPools::GetPedPool()->Delete((CPed*)p); }
void CPed::operator delete(void *p, int handle) { CPools::GetPedPool()->Delete((CPed*)p); }
-#ifdef DEBUGMENU
-bool CPed::bPopHeadsOnHeadshot = false;
-#endif
+float gfTommyFatness = 1.0f;
+// --MIAMI: Done
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;
@@ -70,6 +76,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
@@ -78,13 +90,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;
@@ -113,15 +129,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;
@@ -138,22 +158,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;
@@ -201,7 +236,6 @@ CPed::CPed(uint32 pedType) : m_pedIK(this)
bWanderPathAfterExitingCar = false;
bIsLeader = false;
bDontDragMeOutCar = false;
- m_ped_flagF8 = false;
bWillBeQuickJacked = false;
bCancelEnteringCar = false;
bObstacleShowedUpDuringKillObjective = false;
@@ -230,18 +264,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 = 0xFF;
+
+ 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, 1);
m_fearFlags = CPedType::GetThreats(m_nPedType);
@@ -253,15 +329,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;
@@ -270,29 +344,48 @@ 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;
}
+// --MIAMI: Done
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_vehEnterType);
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)
@@ -304,10 +397,17 @@ 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);
}
+// --MIAMI: Done
void
CPed::Initialise(void)
{
@@ -318,6 +418,7 @@ CPed::Initialise(void)
debug("CPed ready\n");
}
+// --MIAMI: Done
void
CPed::SetModelIndex(uint32 mi)
{
@@ -330,30 +431,51 @@ CPed::SetModelIndex(uint32 mi)
m_animGroup = (AssocGroupId) modelInfo->m_animGroup;
CAnimManager::AddAnimation(GetClump(), m_animGroup, ANIM_IDLE_STANCE);
+ if (!CanUseTorsoWhenLooking())
+ m_pedIK.m_flags |= CPedIK::LOOKAROUND_HEAD_ONLY;
+
// This is a mistake by R*, velocity is CVector, whereas m_vecAnimMoveDelta is CVector2D.
(*RPANIMBLENDCLUMPDATA(m_rwObject))->velocity = (CVector*) &m_vecAnimMoveDelta;
-#ifdef PED_SKIN
if(modelInfo->GetHitColModel() == nil)
modelInfo->CreateHitColModelSkinned(GetClump());
+
+ 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
}
+// --MIAMI: Done
void
CPed::SetPedStats(ePedStats pedStat)
{
m_pedStats = CPedStats::ms_apPedStats[pedStat];
}
+// --MIAMI: Done
+void
+CPed::DeleteRwObject()
+{
+ CEntity::DeleteRwObject();
+}
+
+// --MIAMI: Done
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);
@@ -364,9 +486,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++;
+ }
gapTempPedList[gnNumTempPedList] = ped;
gnNumTempPedList++;
assert(gnNumTempPedList < ARRAY_SIZE(gapTempPedList));
@@ -386,34 +513,37 @@ 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;
- }
- 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;
}
- // Above loop won't work on last slot, so we need to empty it.
- m_nearPeds[ARRAY_SIZE(m_nearPeds) - 1] = nil;
- m_numNearPeds--;
- } else
- i++;
+ } else {
+ removePed = true;
+ }
}
+ 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;
+ }
+ // Above loop won't work on last slot, so we need to empty it.
+ m_nearPeds[ARRAY_SIZE(m_nearPeds) - 1] = nil;
+ m_numNearPeds--;
+ } else
+ i++;
}
}
+// --MIAMI: Done
bool
-CPed::OurPedCanSeeThisOne(CEntity *target)
+CPed::OurPedCanSeeThisOne(CEntity *target, bool shootablesDoBlock)
{
CColPoint colpoint;
CEntity *ent;
@@ -429,11 +559,11 @@ 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);
}
+// --MIAMI: Done
// Some kind of binary sort
void
CPed::SortPeds(CPed **list, int min, int max)
@@ -471,16 +601,18 @@ CPed::SortPeds(CPed **list, int min, int max)
SortPeds(list, right, max);
}
+// --MIAMI: Done
void
CPed::SetMoveState(eMoveState state)
{
m_nMoveState = state;
}
+// --MIAMI: Done
void
CPed::SetMoveAnim(void)
{
- if (m_nStoredMoveState == m_nMoveState || !IsPedInControl())
+ if (m_nStoredMoveState == m_nMoveState || !IsPedInControl() || m_attachedTo)
return;
if (m_nMoveState == PEDMOVE_NONE) {
@@ -496,12 +628,14 @@ CPed::SetMoveAnim(void)
CAnimBlendAssociation *animAssoc = RpAnimBlendClumpGetFirstAssociation(GetClump(), ASSOC_BLOCK);
if (!animAssoc) {
- CAnimBlendAssociation *fightIdleAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_FIGHT_IDLE);
- animAssoc = fightIdleAssoc;
- if (fightIdleAssoc && m_nPedState == PED_FIGHT)
+ animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_FIGHT_IDLE);
+ if (!animAssoc)
+ animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_CROUCHRELOAD);
+
+ if (animAssoc && m_nPedState == PED_FIGHT)
return;
- if (fightIdleAssoc) {
+ if (animAssoc) {
CAnimBlendAssociation *idleAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_STANCE);
if (!idleAssoc || idleAssoc->blendDelta <= 0.0f) {
animAssoc->flags |= ASSOC_DELETEFADEDOUT;
@@ -588,6 +722,7 @@ CPed::SetMoveAnim(void)
}
}
+// --MIAMI: Done
void
CPed::StopNonPartialAnims(void)
{
@@ -599,6 +734,7 @@ CPed::StopNonPartialAnims(void)
}
}
+// --MIAMI: Done
void
CPed::RestartNonPartialAnims(void)
{
@@ -610,6 +746,7 @@ CPed::RestartNonPartialAnims(void)
}
}
+// --MIAMI: Done
void
CPed::SetStoredState(void)
{
@@ -621,20 +758,18 @@ 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;
}
}
+// --MIAMI: Done
void
CPed::RestorePreviousState(void)
{
- if(!CanSetPedState() || m_nPedState == PED_FALL)
+ if (!CanSetPedState() || m_nPedState == PED_FALL)
return;
if (m_nPedState == PED_GETUP && !bGetUpAnimStarted)
@@ -662,14 +797,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);
@@ -680,6 +816,7 @@ CPed::RestorePreviousState(void)
}
}
+// --MIAMI: Done
uint32
CPed::ScanForThreats(void)
{
@@ -692,18 +829,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);
+ }
}
}
@@ -717,32 +858,6 @@ CPed::ScanForThreats(void)
uint32 flagsOfSomePed = 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.
- flagsOfSomePed = CPedType::GetFlag(nearPed->m_nPedType);
-
- if (CPedType::GetFlag(nearPed->m_nPedType) & 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;
@@ -758,9 +873,7 @@ CPed::ScanForThreats(void)
if (flagsOfSomePed & 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) {
@@ -787,9 +900,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();
@@ -815,7 +927,7 @@ CPed::ScanForThreats(void)
}
}
}
-#endif
+
int16 lastVehicle;
CEntity* vehicles[8];
CWorld::FindObjectsInRange(ourPos, 20.0f, true, &lastVehicle, 6, vehicles, false, true, false, false, false);
@@ -829,6 +941,7 @@ CPed::ScanForThreats(void)
// BUG: Same bug as above. Fixed at the bottom of function.
flagsOfSomePed = CPedType::GetFlag(driver->m_nPedType);
if (CPedType::GetFlag(driver->m_nPedType) & fearFlags) {
+
if (driver->m_fHealth > 0.0f && OurPedCanSeeThisOne(nearVeh->pDriver)) {
// FIX: Taken from VC
#ifdef FIX_BUGS
@@ -859,26 +972,75 @@ CPed::ScanForThreats(void)
}
}
+// --MIAMI: Done
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;
+}
+
+// --MIAMI: Done
+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;
+}
+
+// --MIAMI: Done
+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;
+}
+
+// --MIAMI: Done
+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;
}
}
}
+// --MIAMI: Done
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;
@@ -886,12 +1048,13 @@ 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;
}
}
}
+// --MIAMI: Done
void
CPed::ClearLookFlag(void) {
if (bIsLooking) {
@@ -899,7 +1062,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
@@ -911,15 +1076,7 @@ CPed::ClearLookFlag(void) {
}
}
-void
-FinishFuckUCB(CAnimBlendAssociation *animAssoc, void *arg)
-{
- CPed *ped = (CPed*)arg;
-
- if (animAssoc->animId == ANIM_FUCKU && ped->GetWeapon()->m_eWeaponType == WEAPONTYPE_UNARMED)
- ped->RemoveWeaponModel(0);
-}
-
+// --MIAMI: Done
void
CPed::MoveHeadToLook(void)
{
@@ -927,38 +1084,13 @@ CPed::MoveHeadToLook(void)
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_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 {
@@ -975,53 +1107,47 @@ CPed::MoveHeadToLook(void)
if (!bShakeFist || bIsAimingGun || bIsRestoringGun)
return;
- if (m_lookTimer - CTimer::GetTimeInMilliseconds() >= 1000)
+ if (m_nPedState == PED_ANSWER_MOBILE)
return;
- bool notRocketLauncher = false;
- bool notTwoHanded = false;
- AnimationId animToPlay = NUM_ANIMS;
+ if (m_lookTimer - CTimer::GetTimeInMilliseconds() >= 1000)
+ return;
- if (!GetWeapon()->IsType2Handed())
- notTwoHanded = true;
+ bool handFreeToMove = false;
+ AnimationId animToPlay = NUM_STD_ANIMS;
- 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_FIGHT_PPUNCH;
- } else {
animToPlay = ANIM_FUCKU;
- }
- } else if (m_pedStats->m_temper > 49 || m_pLookTarget->GetModelIndex() == MI_POLICE) {
- animToPlay = ANIM_FUCKU;
+ else if(m_pedStats->m_temper < 47)
+ animToPlay = ANIM_FIGHT_PPUNCH;
+ } else {
+ if (m_pedStats->m_temper > 49 || m_pLookTarget->GetModelIndex() == MI_POLICE)
+ animToPlay = ANIM_FUCKU;
}
- } else if (notRocketLauncher && (CGeneral::GetRandomNumber() & 1)) {
+ } else if (handFreeToMove && (CGeneral::GetRandomNumber() & 1)) {
animToPlay = ANIM_FUCKU;
}
- if (animToPlay != NUM_ANIMS) {
+ if (animToPlay != NUM_STD_ANIMS) {
CAnimBlendAssociation *newAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, animToPlay, 4.0f);
if (newAssoc) {
newAssoc->flags |= ASSOC_FADEOUTWHENDONE;
newAssoc->flags |= ASSOC_DELETEFADEDOUT;
- if (newAssoc->animId == ANIM_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)
@@ -1029,14 +1155,21 @@ CPed::MoveHeadToLook(void)
}
}
+// --MIAMI: Done
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;
}
}
+// --MIAMI: Done
void
CPed::SetAimFlag(float angle)
{
@@ -1046,24 +1179,34 @@ 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)->m_bCanAimWithArm)
m_pedIK.m_flags |= CPedIK::AIMS_WITH_ARM;
else
m_pedIK.m_flags &= ~CPedIK::AIMS_WITH_ARM;
}
+// --MIAMI: Done
void
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;
}
+// --MIAMI: Done
void
CPed::ClearAimFlag(void)
{
@@ -1071,31 +1214,35 @@ 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())
((CPlayerPed*)this)->m_fFPSMoveHeading = 0.0f;
}
+// --MIAMI: Done
void
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 {
@@ -1107,6 +1254,7 @@ CPed::AimGun(void)
}
}
+// --MIAMI: Done
void
CPed::RestoreGunPosition(void)
{
@@ -1121,6 +1269,14 @@ CPed::RestoreGunPosition(void)
}
}
+// --MIAMI: Done
+bool
+CPed::CanWeRunAndFireWithWeapon(void)
+{
+ return CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bCanAimWithArm;
+}
+
+// --MIAMI: Done
void
CPed::ScanForInterestingStuff(void)
{
@@ -1191,28 +1347,6 @@ CPed::ScanForInterestingStuff(void)
}
if (m_nPedState == PED_WANDER_PATH) {
-#ifndef VC_PED_PORTS
- if (CTimer::GetTimeInMilliseconds() > m_standardTimer) {
-
- // += 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_standardTimer = CTimer::GetTimeInMilliseconds() + 30000;
- else {
- if ((GetPosition() - m_nearPeds[i]->GetPosition()).Magnitude() >= 1.8f) {
- m_standardTimer = 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_standardTimer) {
for (int i = 0; i < m_numNearPeds; i ++) {
@@ -1225,7 +1359,6 @@ CPed::ScanForInterestingStuff(void)
int time = CGeneral::GetRandomNumber() % 4000 + 10000;
SetChat(m_nearPeds[i], time);
m_nearPeds[i]->SetChat(this, time);
- return;
}
}
}
@@ -1233,53 +1366,10 @@ CPed::ScanForInterestingStuff(void)
} else {
m_standardTimer = 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;
- }
- }
- }
- }
}
}
+// --MIAMI: Done
bool
CPed::WillChat(CPed *stranger)
{
@@ -1296,11 +1386,16 @@ 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;
}
+// --MIAMI: Done
void
CPed::CalculateNewVelocity(void)
{
@@ -1315,9 +1410,6 @@ CPed::CalculateNewVelocity(void)
limitedRotDest -= 2 * PI;
}
- if (IsPlayer() && m_nPedState == PED_ATTACK)
- headAmount /= 4.0f;
-
float neededTurn = limitedRotDest - m_fRotationCur;
if (neededTurn <= headAmount) {
if (neededTurn > (-headAmount))
@@ -1341,8 +1433,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();
@@ -1362,11 +1458,13 @@ CPed::CalculateNewVelocity(void)
CAnimBlendAssociation *idleAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_STANCE);
CAnimBlendAssociation *fightAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_FIGHT_IDLE);
-#ifdef VC_PED_PORTS
+ if(!fightAssoc)
+ fightAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_TIRED);
+
+ if(!fightAssoc)
+ fightAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_CROUCHRELOAD);
+
if ((!idleAssoc || idleAssoc->blendAmount < 0.5f) && !fightAssoc && !bIsDucking) {
-#else
- if ((!idleAssoc || idleAssoc->blendAmount < 0.5f) && !fightAssoc) {
-#endif
LimbOrientation newUpperLegs;
newUpperLegs.yaw = localWalkAngle;
@@ -1377,35 +1475,19 @@ 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;
}
}
}
+// --MIAMI: Done
float
CPed::WorkOutHeadingForMovingFirstPerson(float offset)
{
@@ -1421,18 +1503,19 @@ CPed::WorkOutHeadingForMovingFirstPerson(float offset)
angle = CGeneral::GetRadianAngleBetweenPoints(0.0f, 0.0f, -leftRight, upDown);
} else {
if (leftRight < 0.0f)
- angle = 0.5f * PI;
+ angle = HALFPI;
else if (leftRight > 0.0f)
- angle = -0.5f * PI;
+ angle = -HALFPI;
}
return CGeneral::LimitRadianAngle(offset + angle);
}
+// --MIAMI: Done
void
CPed::UpdatePosition(void)
{
- if (CReplay::IsPlayingBack() || !bIsStanding)
+ if (CReplay::IsPlayingBack() || !bIsStanding || m_attachedTo)
return;
CVector2D velocityChange;
@@ -1479,7 +1562,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()) {
@@ -1496,6 +1579,7 @@ CPed::UpdatePosition(void)
m_vecMoveSpeed.y += velocityChange.y;
}
+// --MIAMI: Done
void
CPed::CalculateNewOrientation(void)
{
@@ -1505,6 +1589,7 @@ CPed::CalculateNewOrientation(void)
SetHeading(m_fRotationCur);
}
+// --MIAMI: Done
void
CPed::ClearAll(void)
{
@@ -1515,32 +1600,27 @@ 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;
}
+// --MIAMI: Done
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::GetRandomNumber() % 256 * 48.0f) + 48);
+ CRGBA color;
if (bInVehicle)
return;
@@ -1548,21 +1628,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::GetRandomNumber() % 256 * 48.0f) + 48;
bIsInWater = true;
ApplyMoveForce(buoyancyImpulse);
if (!DyingOrDead()) {
@@ -1579,119 +1660,87 @@ 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;
}
+// --MIAMI: Done?
void
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) {
@@ -1708,18 +1757,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) {
@@ -1742,6 +1789,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
@@ -1777,13 +1825,11 @@ CPed::ProcessControl(void)
if (ServiceTalkingWhenDead())
ServiceTalking();
-#ifdef VC_PED_PORTS
if (bIsInWater) {
bIsStanding = false;
bWasStanding = false;
CPhysical::ProcessControl();
}
-#endif
return;
}
@@ -1804,16 +1850,15 @@ CPed::ProcessControl(void)
++m_panicCounter;
if (m_fHealth <= 1.0f && m_nPedState <= PED_STATES_NO_AI && !bIsInTheAir && !bIsLanding)
- SetDie(ANIM_KO_SHOT_FRONT1, 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)
@@ -1821,7 +1866,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
@@ -1832,11 +1877,7 @@ CPed::ProcessControl(void)
}
*/
-#ifndef VC_PED_PORTS
- } else {
-#else
} else if (collidingEnt) {
-#endif
switch (collidingEnt->GetType())
{
case ENTITY_TYPE_BUILDING:
@@ -1871,6 +1912,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)) {
@@ -1879,6 +1927,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);
@@ -1888,6 +1939,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();
@@ -1917,10 +1971,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;
@@ -1934,9 +1988,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) {
@@ -1946,6 +2008,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,
@@ -2042,7 +2105,7 @@ CPed::ProcessControl(void)
if (collidingVeh == m_pMyVehicle)
bCollidedWithMyVehicle = true;
-#ifdef VC_PED_PORTS
+
float oldHealth = m_fHealth;
bool playerSufferSound = false;
@@ -2051,23 +2114,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;
@@ -2091,10 +2161,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 {
@@ -2200,142 +2271,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_KO_SKID_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:
@@ -2351,11 +2292,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;
}
}
@@ -2370,12 +2312,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) {
@@ -2386,11 +2323,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 {
@@ -2411,11 +2344,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();
@@ -2440,7 +2369,6 @@ CPed::ProcessControl(void)
} else {
obstacleForFlyingOtherDirZ = 501.0f;
}
-#ifdef VC_PED_PORTS
uint8 flyDir = 0;
float feetZ = GetPosition().z - FEET_OFFSET;
if ((obstacleForFlyingZ <= feetZ || obstacleForFlyingOtherDirZ >= 500.0f) && (obstacleForFlyingZ <= feetZ || obstacleForFlyingOtherDirZ <= feetZ)) {
@@ -2450,14 +2378,13 @@ CPed::ProcessControl(void)
flyDir = 1;
}
- if (flyDir != 0 && !bSomeVCflag1) {
+ if (flyDir != 0 && !bHeadStuckInCollision) {
SetPosition((flyDir == 2 ? obstacleForFlyingOtherDir.point : obstacleForFlying.point));
GetMatrix().GetPosition().z += FEET_OFFSET;
GetMatrix().UpdateRW();
SetLanding();
bIsStanding = true;
}
-#endif
if (obstacleForFlyingZ < obstacleForFlyingOtherDirZ) {
offsetToCheck *= -1.0f;
}
@@ -2478,12 +2405,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)
@@ -2500,7 +2421,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()) {
@@ -2556,17 +2476,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;
}
@@ -2587,15 +2502,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
@@ -2617,30 +2532,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)
@@ -2669,14 +2583,6 @@ CPed::ProcessControl(void)
if (m_nWaitState != WAITSTATE_FALSE)
Wait();
- if (m_nPedState != PED_IDLE) {
- CAnimBlendAssociation *idleAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_ARMED);
- if(idleAssoc) {
- idleAssoc->blendDelta = -8.0f;
- idleAssoc->flags |= ASSOC_DELETEFADEDOUT;
- }
- }
-
switch (m_nPedState) {
case PED_IDLE:
Idle();
@@ -2686,8 +2592,11 @@ 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();
@@ -2738,12 +2647,12 @@ CPed::ProcessControl(void)
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;
}
@@ -2785,6 +2694,9 @@ CPed::ProcessControl(void)
case PED_SEEK_IN_BOAT:
SeekBoatPosition();
break;
+ case PED_BUY_ICECREAM:
+ BuyIceCream();
+ break;
case PED_INVESTIGATE:
InvestigateEvent();
break;
@@ -2793,30 +2705,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) {
@@ -2825,129 +2747,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_CAR_LSIT);
-
- if (!sitAssoc || sitAssoc->blendAmount < 1.0f) {
- break;
- }
- lDriveAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DRIVE_LOW_L);
- lbAssoc = nil;
- rDriveAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DRIVE_LOW_R);
+ if (m_pMyVehicle->pDriver == this) {
+ DriveVehicle();
+ if (!m_pMyVehicle)
+ return;
} else {
- sitAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_SIT);
-
- if (!sitAssoc || sitAssoc->blendAmount < 1.0f) {
- break;
- }
-
- lDriveAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DRIVE_L);
- rDriveAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DRIVE_R);
- lbAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_LB);
-
- if (lbAssoc &&
- TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_1STPERSON
- && TheCamera.Cams[TheCamera.ActiveCam].DirectionWasLooking == LOOKING_LEFT) {
- lbAssoc->blendDelta = -1000.0f;
- }
+ LookForSexyPeds();
+ LookForSexyCars();
}
-
- CAnimBlendAssociation *driveByAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DRIVEBY_L);
-
- if (!driveByAssoc)
- driveByAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DRIVEBY_R);
-
- 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_DRIVE_LOW_R);
- else
- CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_DRIVE_R);
-
- } 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_DRIVE_LOW_L);
- else
- CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_DRIVE_L);
- }
-
- 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_CAR_LB, 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_HANDSCOWER)) {
CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_HANDSCOWER);
Say(SOUND_PED_HANDS_COWER);
@@ -2957,11 +2813,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)) {
@@ -2982,9 +2842,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) {
@@ -2992,9 +2867,11 @@ CPed::ProcessControl(void)
}
m_pCurrentPhysSurface = nil;
}
- }
+ } else
+ ServiceTalking();
}
+// --MIAMI: Done
int32
CPed::ProcessEntityCollision(CEntity *collidingEnt, CColPoint *collidingPoints)
{
@@ -3007,22 +2884,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 false;
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;
@@ -3044,16 +2915,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 {
@@ -3088,18 +2954,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) {
@@ -3122,22 +2985,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();
@@ -3146,7 +3006,7 @@ CPed::ProcessEntityCollision(CEntity *collidingEnt, CColPoint *collidingPoints)
lowerSpeedLimit *= 1.5f;
}
CAnimBlendAssociation *fallAnim = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_FALL_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);
@@ -3159,6 +3019,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)
@@ -3167,31 +3029,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_FALL_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;
}
@@ -3210,29 +3049,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)
@@ -3243,10 +3077,10 @@ CPed::ProcessEntityCollision(CEntity *collidingEnt, CColPoint *collidingPoints)
return ourCollidedSpheres;
}
+// --MIAMI: Done
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);
@@ -3255,18 +3089,9 @@ 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
}
+// --MIAMI: Done
static void
particleProduceFootDust(CPed *ped, CVector const &pos, float size, int times)
{
@@ -3276,10 +3101,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;
@@ -3288,9 +3118,18 @@ particleProduceFootDust(CPed *ped, CVector const &pos, float size, int times)
}
}
+// --MIAMI: Done
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--;
@@ -3303,10 +3142,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;
@@ -3316,96 +3151,200 @@ CPed::PlayFootSteps(void)
}
}
-#ifdef GTA_PS2_STUFF
- CAnimBlendAssociation *runStopAsoc = NULL;
-
- if ( IsPlayer() )
- {
- runStopAsoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_RUN_STOP);
-
- if ( runStopAsoc == NULL )
- runStopAsoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_RUN_STOP_R);
- }
-
- 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;
+
+ float moveStart, soundVolume, skateTime;
+ if (walkRunAssoc->animId == ANIM_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_KO_SKID_BACK, false);
+ }
+ soundVolume = 0.5f;
+ break;
+ case ADHESIVE_SAND:
+ if (CGeneral::GetRandomNumber() % 64) {
+ m_vecAnimMoveDelta *= 0.2f;
+ } else {
+ SetFall(0, ANIM_KO_SKID_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();
+
+ adjustedFootPos.z -= 0.1f;
+ adjustedFootPos += 0.2f * forward;
- 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);
+ if (bDoBloodyFootprints) {
+ CVector2D top(forward * 0.26f);
+ CVector2D right(GetRight() * (stepPart == 1 ? 0.14f : 0.1f));
- CVector forward = GetForward();
+ CShadows::AddPermanentShadow(SHADOWTYPE_DARK, gpBloodPoolTex, &adjustedFootPos,
+ top.x, top.y,
+ right.x, right.y,
+ 255, 255, 0, 0, 4.0f, 3000, 1.0f);
- footPos.z -= 0.1f;
- footPos += 0.2f * forward;
+ 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);
- if (bDoBloodyFootprints) {
- CVector2D top(forward * 0.26f);
+ 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)
@@ -3420,20 +3359,25 @@ 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);
}
}
}
+// --MIAMI: Done
// Actually GetLocalDirectionTo(Turn/Look)
int
CPed::GetLocalDirection(const CVector2D &posOffset)
@@ -3449,52 +3393,14 @@ 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);
- }
-}
-
+// --MIAMI: Done
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.
+// --MIAMI: Done
void
CPed::SetDirectionToWalkAroundObject(CEntity *obj)
{
@@ -3515,13 +3421,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);
@@ -3557,11 +3461,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)
@@ -3605,16 +3507,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;
@@ -3635,25 +3530,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_vehEnterType == CAR_DOOR_LF || m_vehEnterType == CAR_DOOR_LR)) {
- cornerToGo = tl;
- m_walkAroundType = 1;
-
- if (m_vehEnterType == 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;
@@ -3672,27 +3548,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_vehEnterType == CAR_DOOR_RF || m_vehEnterType == CAR_DOOR_RR)) {
- cornerToGo = tr;
- m_walkAroundType = 2;
-
- if (m_vehEnterType == 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;
@@ -3711,26 +3566,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_vehEnterType == CAR_DOOR_RF || m_vehEnterType == 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;
@@ -3749,26 +3584,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_vehEnterType == CAR_DOOR_LF || m_vehEnterType == 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) {
@@ -3840,7 +3704,6 @@ CPed::SetDirectionToWalkAroundObject(CEntity *obj)
m_walkAroundType = 0;
}
}
-#endif
}
m_collidingEntityWhileFleeing = obj;
m_collidingEntityWhileFleeing->RegisterReference((CEntity**) &m_collidingEntityWhileFleeing);
@@ -3850,56 +3713,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_vehEnterType : 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_vehEnterType : 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_vehEnterType : 0, goingToEnterCarAndItsVan);
-#else
if (Abs(angleDiffBtwObjCenterAndForward) < objTopRightHeading) {
if (goingToEnterCar) {
if (goingToEnterCarAndItsVan) {
@@ -4014,7 +3827,6 @@ CPed::SetDirectionToWalkAroundObject(CEntity *obj)
}
}
}
-#endif
if (objUpsideDown)
localPosToHead.x = localPosToHead.x * -1.0f;
@@ -4041,6 +3853,7 @@ CPed::SetDirectionToWalkAroundObject(CEntity *obj)
m_nPedStateTimer = CTimer::GetTimeInMilliseconds() + 280.0f * dist * checkIntervalInTime;
}
+// --MIAMI: Done
bool
CPed::IsPedInControl(void)
{
@@ -4049,12 +3862,14 @@ CPed::IsPedInControl(void)
&& m_fHealth > 0.0f;
}
+// --MIAMI: Done
bool
CPed::IsPedShootable(void)
{
return m_nPedState <= PED_STATES_NO_ST;
}
+// --MIAMI: Done
bool
CPed::UseGroundColModel(void)
{
@@ -4064,6 +3879,7 @@ CPed::UseGroundColModel(void)
m_nPedState == PED_DEAD;
}
+// --MIAMI: Done
bool
CPed::CanPedReturnToState(void)
{
@@ -4071,12 +3887,14 @@ CPed::CanPedReturnToState(void)
m_nPedState != PED_FIGHT && m_nPedState != PED_STEP_AWAY && m_nPedState != PED_SNIPER_MODE && m_nPedState != PED_LOOK_ENTITY;
}
+// --MIAMI: Done
bool
CPed::CanSetPedState(void)
{
return !DyingOrDead() && m_nPedState != PED_ARRESTED && !EnteringCar() && m_nPedState != PED_STEAL_CAR;
}
+// --MIAMI: Done
bool
CPed::CanStrafeOrMouseControl(void)
{
@@ -4085,9 +3903,19 @@ 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;
+}
+
+// --MIAMI: Done
+void
+CPed::PedSetPreviousStateCB(CAnimBlendAssociation* assoc, void* arg)
+{
+ CPed* ped = (CPed*)arg;
+ ped->RestorePreviousState();
+ ped->m_pVehicleAnim = nil;
}
+// --MIAMI: Done
void
CPed::PedGetupCB(CAnimBlendAssociation* animAssoc, void* arg)
{
@@ -4101,15 +3929,29 @@ 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;
}
+// --MIAMI: Done
void
CPed::PedLandCB(CAnimBlendAssociation* animAssoc, void* arg)
{
@@ -4122,6 +3964,7 @@ CPed::PedLandCB(CAnimBlendAssociation* animAssoc, void* arg)
ped->RestorePreviousState();
}
+// --MIAMI: Done
void
CPed::PedStaggerCB(CAnimBlendAssociation* animAssoc, void* arg)
{
@@ -4132,7 +3975,7 @@ CPed::PedStaggerCB(CAnimBlendAssociation* animAssoc, void* arg)
// nothing
*/
}
-
+// --MIAMI: Done
void
CPed::PedSetOutCarCB(CAnimBlendAssociation *animAssoc, void *arg)
{
@@ -4150,22 +3993,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_FLOOR_HIT, 4.0f, 0.5f);
}
-#endif
ped->bInVehicle = false;
- if (veh && veh->IsCar() && !veh->IsRoomForPedToLeaveCar(ped->m_vehEnterType, 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;
@@ -4213,22 +4066,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) {
@@ -4243,7 +4090,12 @@ CPed::PedSetOutCarCB(CAnimBlendAssociation *animAssoc, void *arg)
}
}
}
- veh->m_nGettingOutFlags &= ~GetCarDoorFlag(ped->m_vehEnterType);
+ if (veh && veh->IsBike())
+ // BUG?
+ veh->m_nGettingOutFlags &= ~GetBikeDoorFlag(ped->m_vehEnterType);
+ else
+ veh->m_nGettingOutFlags &= ~GetCarDoorFlag(ped->m_vehEnterType);
+
if (veh->pDriver == ped) {
veh->RemoveDriver();
veh->SetStatus(STATUS_ABANDONED);
@@ -4251,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);
}
@@ -4294,8 +4151,10 @@ CPed::PedSetOutCarCB(CAnimBlendAssociation *animAssoc, void *arg)
if (createdBy == MISSION_CHAR && !startedToRun)
ped->SetMoveState(PEDMOVE_WALK);
}
+ ped->bHeldHostageInCar = false;
}
+// --MIAMI: Done
void
CPed::PedSetDraggedOutCarCB(CAnimBlendAssociation *dragAssoc, void *arg)
{
@@ -4303,7 +4162,20 @@ CPed::PedSetDraggedOutCarCB(CAnimBlendAssociation *dragAssoc, void *arg)
CVehicle *vehicle;
CPed *ped = (CPed*)arg;
+ uint8 exitFlags = 0;
quickJackedAssoc = RpAnimBlendClumpGetAssociation(ped->GetClump(), ANIM_CAR_QJACKED);
+ if (dragAssoc && dragAssoc->animId == ANIM_BIKE_HIT && ped->m_pMyVehicle) {
+ if (ped->m_vehEnterType == CAR_DOOR_LF || ped->m_vehEnterType == CAR_DOOR_RF) {
+ CAnimManager::BlendAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_BIKE_FALL_OFF, 100.0f);
+ ped->m_pMyVehicle->m_nGettingOutFlags &= ~(CAR_DOOR_FLAG_RF | CAR_DOOR_FLAG_LF);
+ } else {
+ CAnimManager::BlendAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_BIKE_FALL_R, 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)
@@ -4314,9 +4186,15 @@ CPed::PedSetDraggedOutCarCB(CAnimBlendAssociation *dragAssoc, void *arg)
ped->m_pSeekTarget = nil;
vehicle = ped->m_pMyVehicle;
- if (vehicle) {
- vehicle->m_nGettingOutFlags &= ~GetCarDoorFlag(ped->m_vehEnterType);
+ if (vehicle && vehicle->IsBike())
+ exitFlags = GetBikeDoorFlagInclJumpInFromFront(ped->m_vehEnterType);
+ else
+ exitFlags = GetCarDoorFlag(ped->m_vehEnterType);
+ if (vehicle)
+ vehicle->m_nGettingOutFlags &= ~exitFlags;
+
+ if (vehicle) {
if (vehicle->pDriver == ped) {
vehicle->RemoveDriver();
if (vehicle->m_nDoorLock == CARLOCK_LOCKED_INITIALLY)
@@ -4332,14 +4210,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_FLOOR_HIT, 1000.0f, 0.5f);
return;
}
-#endif
if (quickJackedAssoc) {
dragAssoc->SetDeleteCallback(PedSetQuickDraggedOutCarPositionCB, ped);
@@ -4355,6 +4231,7 @@ CPed::PedSetDraggedOutCarCB(CAnimBlendAssociation *dragAssoc, void *arg)
ped->bVehExitWillBeInstant = false;
}
+// --MIAMI: Done
void
CPed::PedSetInCarCB(CAnimBlendAssociation *animAssoc, void *arg)
{
@@ -4366,7 +4243,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
@@ -4392,7 +4268,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;
@@ -4408,11 +4293,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)
@@ -4423,9 +4304,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);
@@ -4439,6 +4318,7 @@ CPed::PedSetInCarCB(CAnimBlendAssociation *animAssoc, void *arg)
ped->SetPedState(PED_DRIVING);
ped->StopNonPartialAnims();
+ ped->RemoveWeaponWhenEnteringVehicle();
return;
}
@@ -4450,7 +4330,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);
@@ -4469,27 +4349,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);
@@ -4525,14 +4390,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_vehEnterType) {
@@ -4551,17 +4426,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_vehEnterType);
+ int8 doorFlag;
+ if (veh->IsBike()) {
+ doorFlag = GetBikeDoorFlagInclJumpInFromFront(ped->m_vehEnterType);
+ } else {
+ doorFlag = GetEnterCarDoorFlag(ped->m_vehEnterType, veh->m_nNumMaxPassengers);
+ }
+
+ veh->m_nGettingInFlags &= ~doorFlag;
if (veh->bIsBus && !veh->m_nGettingInFlags)
((CAutomobile*)veh)->SetBusDoorTimer(1000, 1);
@@ -4574,24 +4458,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_CAR_LSIT, 100.0f);
- } else {
- ped->m_pVehicleAnim = CAnimManager::BlendAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_SIT, 100.0f);
- }
- } else if (veh->bLowVehicle) {
- ped->m_pVehicleAnim = CAnimManager::BlendAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_SITPLO, 100.0f);
- } else {
- ped->m_pVehicleAnim = CAnimManager::BlendAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_SITP, 100.0f);
- }
-
- ped->StopNonPartialAnims();
+ ped->AddInCarAnims(veh, veh->pDriver == ped);
if (veh->bIsBus)
ped->bRenderPedInCar = false;
@@ -4611,6 +4490,7 @@ CPed::PedSetInCarCB(CAnimBlendAssociation *animAssoc, void *arg)
ped->bChangedSeat = true;
}
+// --MIAMI: Done
bool
CPed::CanBeDeleted(void)
{
@@ -4622,32 +4502,43 @@ CPed::CanBeDeleted(void)
return true;
case MISSION_CHAR:
return false;
+ case UNK_CHAR:
+ return false;
+ default:
+ return true;
+ }
+}
+
+//--MIAMI: done
+bool
+CPed::CanBeDeletedEvenInVehicle(void)
+{
+ switch (CharCreatedBy) {
+ case RANDOM_CHAR:
+ return true;
+ case MISSION_CHAR:
+ return false;
+ case UNK_CHAR:
+ return false;
default:
return true;
}
}
+// --MIAMI: Done
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();
}
}
@@ -4662,115 +4553,238 @@ RemoveAllModelCB(RwObject *object, void *data)
return object;
}
+// --MIAMI: Done
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)
+// --MIAMI: Done
+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;
+ }
+ }
+}
+
+// --MIAMI: Done
+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;
+ }
+ }
+}
+
+// --MIAMI: Done
+int32
+CPed::GiveWeapon(eWeaponType weaponType, uint32 ammo, bool unused)
+{
+ int slot = GetWeaponSlot(weaponType);
+
+ if (m_weapons[slot].m_eWeaponType == weaponType) {
+ GetWeapon(slot).m_nAmmoTotal += ammo;
+ if (weaponType < WEAPONTYPE_TOTALWEAPONS && weaponType > WEAPONTYPE_UNARMED && CWeaponInfo::ms_aMaxAmmoForWeapon[weaponType] >= 0) {
- weapon.Reload();
+ // 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
+// --MIAMI: Done
int
CPed::GetWeaponSlot(eWeaponType weaponType)
{
- if (HasWeapon(weaponType))
- return weaponType;
- else
- return -1;
+ return CWeaponInfo::GetWeaponInfo(weaponType)->m_nWeaponSlot;
}
+// --MIAMI: Done
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);
}
}
+// --MIAMI: Done
+void
+CPed::SetCurrentWeapon(eWeaponType weaponType)
+{
+ SetCurrentWeapon(CWeaponInfo::GetWeaponInfo(weaponType)->m_nWeaponSlot);
+}
+
+// --MIAMI: Done
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;
}
+// --MIAMI: Done
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;
}
+// --MIAMI: Done
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;
+// --MIAMI: Done
+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);
+ }
+}
+// --MIAMI: Done, but enumarate weapon slots
+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) == 5) {
+ if (m_storedWeapon != WEAPONTYPE_UNIDENTIFIED) {
+ SetCurrentWeapon(m_storedWeapon);
+ m_storedWeapon = WEAPONTYPE_UNIDENTIFIED;
+ }
+ } else {
+ AddWeaponModel(CWeaponInfo::GetWeaponInfo(weaponType)->m_nModelId);
}
}
+// --MIAMI: Done
void
CPed::PreRender(void)
{
@@ -4779,20 +4793,160 @@ CPed::PreRender(void)
CTimeCycle::m_fShadowFrontX[CTimeCycle::m_CurrentStoredValue], CTimeCycle::m_fShadowFrontY[CTimeCycle::m_CurrentStoredValue],
CTimeCycle::m_fShadowSideX[CTimeCycle::m_CurrentStoredValue], CTimeCycle::m_fShadowSideY[CTimeCycle::m_CurrentStoredValue]);
-#ifdef PED_SKIN
- if(IsClumpSkinned(GetClump())){
- UpdateRpHAnim();
+ UpdateRpHAnim();
+
+ bool bIsWindModifierTurnedOn = false;
+ float fAnyDirectionShift = 1.0f;
+ bool bIsPedDrivingBikeOrOpenTopCar = false;
+ if (IsPlayer() && CWindModifiers::FindWindModifier(GetPosition(), &fAnyDirectionShift, &fAnyDirectionShift)
+ && !CCullZones::PlayerNoRain() && GetPedState() != PED_DRIVING)
+ bIsWindModifierTurnedOn = true;
- if(bBodyPartJustCameOff && m_bodyPartBleeding == PED_HEAD){
- // scale head to 0 if shot off
- RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(GetClump());
- int32 idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_HEAD));
- RwMatrix *head = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
- RwV3d zero = { 0.0f, 0.0f, 0.0f };
- RwMatrixScale(head, &zero, rwCOMBINEPRECONCAT);
+ if (GetPedState() == PED_DRIVING && m_pMyVehicle) {
+ if (m_pMyVehicle->m_vehType == VEHICLE_TYPE_BIKE
+ || (m_pMyVehicle->m_vehType == VEHICLE_TYPE_CAR && m_pMyVehicle->IsOpenTopCar()))
+ bIsPedDrivingBikeOrOpenTopCar = true;
+ }
+
+ if (bIsWindModifierTurnedOn || bIsPedDrivingBikeOrOpenTopCar) {
+ float fWindMult = 0.0f;
+ if (bIsPedDrivingBikeOrOpenTopCar) {
+ fWindMult = DotProduct(m_pMyVehicle->m_vecMoveSpeed, GetForward());
+ if (fWindMult > 0.4f) {
+ float volume = (fWindMult - 0.4f) / 0.6f;
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_SHIRT_WIND_FLAP, volume);
+ }
}
+
+ if (bIsWindModifierTurnedOn)
+ fWindMult = Min(fWindMult, Abs(fAnyDirectionShift - 1.0f));
+
+ RpHAnimHierarchy* hier = GetAnimHierarchyFromSkinClump(GetClump());
+ int32 idx;
+ RwV3d scale;
+ float fScaleOffset;
+
+ fScaleOffset = fWindMult * 0.2f;
+ scale.x = CGeneral::GetRandomNumberInRange(1.0f - fScaleOffset, 1.0f + fScaleOffset);
+ scale.y = CGeneral::GetRandomNumberInRange(1.0f - fScaleOffset, 1.0f + fScaleOffset);
+ scale.z = CGeneral::GetRandomNumberInRange(1.0f - fScaleOffset, 1.0f + fScaleOffset);
+
+ idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_NECK));
+ RwMatrix* neck = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
+ RwMatrixScale(neck, &scale, rwCOMBINEPRECONCAT);
+
+ fScaleOffset = fWindMult * 0.1f;
+ scale.x = CGeneral::GetRandomNumberInRange(1.0f - fScaleOffset, 1.0f + fScaleOffset);
+ scale.y = CGeneral::GetRandomNumberInRange(1.0f - fScaleOffset, 1.0f + fScaleOffset);
+ scale.z = CGeneral::GetRandomNumberInRange(1.0f - fScaleOffset, 1.0f + fScaleOffset);
+
+ idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_CLAVICLEL));
+ RwMatrix* clavicleL = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
+ RwMatrixScale(clavicleL, &scale, rwCOMBINEPRECONCAT);
+
+ idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_CLAVICLER));
+ RwMatrix* clavicleR = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
+ RwMatrixScale(clavicleR, &scale, rwCOMBINEPRECONCAT);
+
+ idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_MID));
+ RwMatrix* mid = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
+ RwMatrixScale(mid, &scale, rwCOMBINEPRECONCAT);
+
+ fScaleOffset = fWindMult * 0.2f;
+ scale.x = CGeneral::GetRandomNumberInRange(1.0f - fScaleOffset, 1.0f + fScaleOffset);
+ scale.y = CGeneral::GetRandomNumberInRange(1.0f - fScaleOffset, 1.0f + fScaleOffset);
+ scale.z = CGeneral::GetRandomNumberInRange(1.0f - fScaleOffset, 1.0f + fScaleOffset);
+
+ idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_UPPERARML));
+ RwMatrix* upperArmL = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
+ RwMatrixScale(upperArmL, &scale, rwCOMBINEPRECONCAT);
+
+ idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_UPPERARMR));
+ RwMatrix* upperArmR = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
+ RwMatrixScale(upperArmR, &scale, rwCOMBINEPRECONCAT);
+ }
+
+ if (bBodyPartJustCameOff && m_bodyPartBleeding == PED_HEAD) {
+ // scale head to 0 if shot off
+ RpHAnimHierarchy* hier = GetAnimHierarchyFromSkinClump(GetClump());
+ int32 idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_HEAD));
+ RwMatrix* head = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
+ RwV3d zero = { 0.0f, 0.0f, 0.0f };
+ RwMatrixScale(head, &zero, rwCOMBINEPRECONCAT);
+ }
+
+ if (IsPlayer() && gfTommyFatness != 1.0f) {
+ RpHAnimHierarchy* hier = GetAnimHierarchyFromSkinClump(GetClump());
+ int32 idx;
+ RwV3d scale;
+
+ scale.x = 1.0f;
+ scale.y = 1.0f + gfTommyFatness * 0.7f;
+ scale.z = 1.0f + gfTommyFatness * 0.7f;
+ idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_HEAD));
+ RwMatrix* head = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
+ RwMatrixScale(head, &scale, rwCOMBINEPRECONCAT);
+
+ scale.y = 1.0f + gfTommyFatness * 0.2f;
+ scale.z = 1.0f + gfTommyFatness * 0.2f;
+ idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_NECK));
+ RwMatrix* neck = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
+ RwMatrixScale(neck, &scale, rwCOMBINEPRECONCAT);
+
+ scale.y = 1.0f + gfTommyFatness * 0.5f;
+ scale.z = 1.0f + gfTommyFatness * 0.5f;
+ idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_MID));
+ RwMatrix* mid = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
+ RwMatrixScale(mid, &scale, rwCOMBINEPRECONCAT);
+
+ scale.y = 1.0f + gfTommyFatness;
+ scale.z = 1.0f + gfTommyFatness;
+ idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_UPPERLEGL));
+ RwMatrix* upperLegL = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
+ RwMatrixScale(upperLegL, &scale, rwCOMBINEPRECONCAT);
+
+ idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_UPPERLEGR));
+ RwMatrix* upperLegR = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
+ RwMatrixScale(upperLegR, &scale, rwCOMBINEPRECONCAT);
+
+ scale.y = 1.0f + gfTommyFatness * 0.5f;
+ scale.z = 1.0f + gfTommyFatness * 0.5f;
+ idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_LOWERLEGR));
+ RwMatrix* lowerLegR = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
+ RwMatrixScale(lowerLegR, &scale, rwCOMBINEPRECONCAT);
+
+ idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_LOWERLEGL));
+ RwMatrix* lowerLegL = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
+ RwMatrixScale(lowerLegL, &scale, rwCOMBINEPRECONCAT);
+
+ scale.y = 1.0f + gfTommyFatness * 0.23f;
+ scale.z = 1.0f + gfTommyFatness * 0.23f;
+ idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_FOOTL));
+ RwMatrix* footL = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
+ RwMatrixScale(footL, &scale, rwCOMBINEPRECONCAT);
+
+ idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_FOOTR));
+ RwMatrix* footR = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
+ RwMatrixScale(footR, &scale, rwCOMBINEPRECONCAT);
+
+ idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_UPPERARML));
+ RwMatrix* upperArmL = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
+ RwMatrixScale(upperArmL, &scale, rwCOMBINEPRECONCAT);
+
+ idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_UPPERARMR));
+ RwMatrix* upperArmR = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
+ RwMatrixScale(upperArmR, &scale, rwCOMBINEPRECONCAT);
+
+ scale.y = 1.0f + gfTommyFatness * 0.2f;
+ scale.z = 1.0f + gfTommyFatness * 0.2f;
+ idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_FOREARML));
+ RwMatrix* foreArmL = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
+ RwMatrixScale(foreArmL, &scale, rwCOMBINEPRECONCAT);
+
+ idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_FOREARMR));
+ RwMatrix* foreArmR = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
+ RwMatrixScale(foreArmR, &scale, rwCOMBINEPRECONCAT);
}
-#endif
if (bBodyPartJustCameOff && bIsPedDieAnimPlaying && m_bodyPartBleeding != -1 && (CTimer::GetFrameCounter() & 7) > 3) {
CVector bloodDir(0.0f, 0.0f, 0.0f);
@@ -4863,27 +5017,26 @@ CPed::PreRender(void)
}
}
+CVector vecTestTemp(-1.0f, -1.0f, -1.0f);
+
+// --MIAMI: Done
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];
@@ -4891,10 +5044,32 @@ 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
}
+// --MIAMI: Done
void
CPed::CheckAroundForPossibleCollisions(void)
{
@@ -4927,24 +5102,24 @@ CPed::CheckAroundForPossibleCollisions(void)
}
}
+// --MIAMI: Done
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);
}
}
+// --MIAMI: Done
void
CPed::Idle(void)
{
@@ -4966,48 +5141,20 @@ CPed::Idle(void)
}
}
- CAnimBlendAssociation *armedIdleAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_ARMED);
- CAnimBlendAssociation *unarmedIdleAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_STANCE);
- 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_IDLE_ARMED, 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);
}
+// --MIAMI: Done
void
CPed::ClearPause(void)
{
RestorePreviousState();
}
+// --MIAMI: Done
void
CPed::Pause(void)
{
@@ -5016,9 +5163,13 @@ CPed::Pause(void)
ClearPause();
}
+// --MIAMI: Done
void
CPed::SetFall(int extraTime, AnimationId animId, uint8 evenIfNotInControl)
{
+ if (m_attachedTo)
+ return;
+
if (!IsPedInControl() && (!evenIfNotInControl || DyingOrDead()))
return;
@@ -5026,24 +5177,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 == NUM_STD_ANIMS) {
+ if (IsPlayer()) {
+ fallAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_ROLLOUT_LHS);
+ if (!fallAssoc)
+ fallAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_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_BIKE_FALL_R)
+ 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_CAR_ROLLOUT_LHS || fallAssoc->animId == ANIM_CAR_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()
@@ -5059,25 +5229,73 @@ CPed::SetFall(int extraTime, AnimationId animId, uint8 evenIfNotInControl)
bFallenDown = true;
}
+// --MIAMI: Done
void
CPed::ClearFall(void)
{
SetGetUp();
}
+// --MIAMI: Done
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_FALL_BACK || firstPartialAssoc->animId == ANIM_FALL_FRONT))
+ fallAssoc = firstPartialAssoc;
+ else
+ fallAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_FALL_BACK);
+
+ if (!fallAssoc)
+ fallAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_FALL_FRONT);
+
+ if (!fallAssoc && firstPartialAssoc && 0.8f * firstPartialAssoc->hierarchy->totalLength < firstPartialAssoc->currentTime) {
+ if (firstPartialAssoc->flags & ASSOC_FRONTAL) {
+ CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_FALL_FRONT, 8.0f);
+ } else {
+ CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_FALL_BACK, 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_FALL_BACK);
+
+ if (!fallAssoc)
+ fallAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_FALL_FRONT);
+
+ 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;
+ }
+ }
+ }
}
+// --MIAMI: Done
bool
CPed::CheckIfInTheAir(void)
{
@@ -5099,6 +5317,7 @@ CPed::CheckIfInTheAir(void)
return !foundGround;
}
+// --MIAMI: Done
void
CPed::SetInTheAir(void)
{
@@ -5117,6 +5336,7 @@ CPed::SetInTheAir(void)
}
+// --MIAMI: Done
void
CPed::InTheAir(void)
{
@@ -5130,22 +5350,17 @@ 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_FALL_FALL)) {
- if (m_vecMoveSpeed.z < -0.1f)
- CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_FALL_FALL, 4.0f);
- }
+ } else if (m_nPedState != PED_ABSEIL && !RpAnimBlendClumpGetAssociation(GetClump(), ANIM_FALL_FALL)) {
+ if (m_vecMoveSpeed.z < -0.1f)
+ CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_FALL_FALL, 4.0f);
}
}
}
}
+// --MIAMI: Done
void
CPed::SetLanding(void)
{
@@ -5155,14 +5370,22 @@ CPed::SetLanding(void)
CAnimBlendAssociation *fallAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_FALL_FALL);
CAnimBlendAssociation *landAssoc;
+ if (fallAssoc && bIsDrowning)
+ return;
+
RpAnimBlendClumpSetBlendDeltas(GetClump(), ASSOC_PARTIAL, -1000.0f);
- if (fallAssoc) {
+ if (fallAssoc || m_nPedType == PEDTYPE_COP && bKnockedUpIntoAir) {
landAssoc = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_FALL_COLLAPSE);
DMAudio.PlayOneShot(m_audioEntityId, SOUND_FALL_COLLAPSE, 1.0f);
if (IsPlayer())
Say(SOUND_PED_LAND);
+ if (m_nPedType == PEDTYPE_COP) {
+ if (bKnockedUpIntoAir)
+ bKnockedUpIntoAir = false;
+ }
+
} else {
landAssoc = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_FALL_LAND);
DMAudio.PlayOneShot(m_audioEntityId, SOUND_FALL_LAND, 1.0f);
@@ -5173,6 +5396,7 @@ CPed::SetLanding(void)
bIsLanding = true;
}
+// --MIAMI: Done
void
CPed::SetGetUp(void)
{
@@ -5195,26 +5419,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_SPRINT);
if (animAssoc) {
if (RpAnimBlendClumpGetAssociation(GetClump(), ANIM_RUN)) {
@@ -5225,18 +5446,28 @@ 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_GETUP1, 1000.0f);
+ else
+ animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_GETUP1, 1000.0f);
+
+ } else if (RpAnimBlendClumpGetFirstAssociation(GetClump(), ASSOC_FRONTAL))
animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_GETUP_FRONT, 1000.0f);
else
animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_GETUP1, 1000.0f);
- animAssoc->SetFinishCallback(PedGetupCB,this);
+ animAssoc->SetFinishCallback(PedGetupCB, this);
} else {
m_fHealth = 0.0f;
- SetDie(NUM_ANIMS, 4.0f, 0.0f);
+ SetDie(NUM_STD_ANIMS, 4.0f, 0.0f);
}
}
+// --MIAMI: Done
void
CPed::Mug(void)
{
@@ -5258,6 +5489,30 @@ CPed::Mug(void)
}
}
+// --MIAMI: Done
+// Unused
+void
+CPed::SetLook(float direction)
+{
+ if (IsPedInControl()) {
+ SetStoredState();
+ SetPedState(PED_LOOK_HEADING);
+ SetLookFlag(direction, false);
+ }
+}
+
+// --MIAMI: Done
+void
+CPed::SetLook(CEntity* to)
+{
+ if (IsPedInControl()) {
+ SetStoredState();
+ SetPedState(PED_LOOK_ENTITY);
+ SetLookFlag(to, false);
+ }
+}
+
+// --MIAMI: Done
void
CPed::SetLookTimer(int time)
{
@@ -5266,6 +5521,7 @@ CPed::SetLookTimer(int time)
}
}
+// --MIAMI: Done
void
CPed::SetAttackTimer(uint32 time)
{
@@ -5273,6 +5529,7 @@ CPed::SetAttackTimer(uint32 time)
m_attackTimer = Max(m_shootTimer, CTimer::GetTimeInMilliseconds()) + time;
}
+// --MIAMI: Done
void
CPed::SetShootTimer(uint32 time)
{
@@ -5281,6 +5538,7 @@ CPed::SetShootTimer(uint32 time)
}
}
+// --MIAMI: Done
void
CPed::ClearLook(void)
{
@@ -5288,12 +5546,14 @@ CPed::ClearLook(void)
ClearLookFlag();
}
+// --MIAMI: Done
void
CPed::Look(void)
{
- // UNUSED: This is a perfectly empty function.
+ TurnBody();
}
+// --MIAMI: Done
bool
CPed::TurnBody(void)
{
@@ -5327,18 +5587,15 @@ CPed::TurnBody(void)
return turnDone;
}
+// --MIAMI: Done
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)->m_bCanAimWithArm) {
ClearPointGunAt();
}
@@ -5349,7 +5606,7 @@ CPed::SetSeek(CVector pos, float distanceToCountDone)
m_distanceToCountSeekDone = distanceToCountDone;
m_vecSeekPos = pos;
}
-
+// --MIAMI: Done
void
CPed::SetSeek(CEntity *seeking, float distanceToCountDone)
{
@@ -5359,7 +5616,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)
@@ -5372,6 +5629,7 @@ CPed::SetSeek(CEntity *seeking, float distanceToCountDone)
SetMoveState(PEDMOVE_STILL);
}
+// --MIAMI: Done
void
CPed::ClearSeek(void)
{
@@ -5379,6 +5637,7 @@ CPed::ClearSeek(void)
bRunningToPhone = false;
}
+// --MIAMI: Done
bool
CPed::Seek(void)
{
@@ -5391,13 +5650,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());
@@ -5413,6 +5672,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) {
@@ -5425,7 +5691,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;
@@ -5446,8 +5714,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) {
@@ -5479,14 +5749,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);
@@ -5494,7 +5771,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 {
@@ -5504,7 +5781,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);
}
@@ -5515,11 +5792,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
@@ -5528,12 +5807,10 @@ CPed::Seek(void)
bUsePedNodeSeek = true;
}
- if (SeekFollowingPath(nil))
- m_nCurPathNode++;
-
return true;
}
+// --MIAMI: Done
void
CPed::SetFlee(CVector2D const &from, int time)
{
@@ -5544,8 +5821,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;
@@ -5564,6 +5840,7 @@ CPed::SetFlee(CVector2D const &from, int time)
}
}
+// --MIAMI: Done
void
CPed::SetFlee(CEntity *fleeFrom, int time)
{
@@ -5594,6 +5871,7 @@ CPed::SetFlee(CEntity *fleeFrom, int time)
}
}
+// --MIAMI: Done
void
CPed::ClearFlee(void)
{
@@ -5603,6 +5881,7 @@ CPed::ClearFlee(void)
m_fleeTimer = 0;
}
+// --MIAMI: Done
void
CPed::Flee(void)
{
@@ -5614,11 +5893,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);
@@ -5628,6 +5910,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;
@@ -5651,7 +5938,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;
@@ -5705,22 +5992,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;
@@ -5730,7 +6001,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,
@@ -5799,11 +6069,15 @@ CPed::WanderRange(void)
}
}
+// --MIAMI: Done
bool
CPed::SetWanderPath(int8 pathStateDest)
{
uint8 nextPathState;
+ if (IsPlayer())
+ return false;
+
if (IsPedInControl()) {
if (bKindaStayInSamePlace) {
SetIdle();
@@ -5844,6 +6118,7 @@ CPed::SetWanderPath(int8 pathStateDest)
}
}
+// --MIAMI: Done
void
CPed::WanderPath(void)
{
@@ -5856,14 +6131,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
@@ -5876,6 +6151,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;
@@ -5891,7 +6168,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) {
@@ -5919,6 +6202,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;
+ }
+ }
}
}
@@ -5936,7 +6226,7 @@ CPed::WanderPath(void)
Say(SOUND_PED_WAIT_DOUBLEBACK);
}
}
-
+// --MIAMI: Done
void
CPed::Avoid(void)
{
@@ -5985,71 +6275,577 @@ CPed::Avoid(void)
}
}
-bool
-CPed::SeekFollowingPath(CVector *unused)
+// --MIAMI: Done
+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;
}
+// --MIAMI: Done
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)
+// --MIAMI: Done
+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;
+}
+
+// --MIAMI: Done
+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;
+
+ 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;
}
+ }
+
+ int lastPlaneBehindUs = -1;
+ int lastPlaneInFrontOfUs = -1;
+ CVector oldstartVecCandidate = startVecCandidate;
+ CVector oldDirToGo = targetVecCandidate - startVecCandidate;
+ oldDirToGo.Normalise();
+
- while (v4 < maxNodeIndex)
- v4++;
+ // 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;
+ }
}
-*/
- if (Seek()) {
- m_nCurPathNode++;
- if (m_nCurPathNode == m_nPathNodes)
+
+ 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;
+ }
+}
+
+// --MIAMI: Done
+void
+CPed::ClearFollowPath()
+{
+ for (int i = 0; i < ARRAY_SIZE(m_pathNodesToGo); i++) {
+ m_pathNodesToGo[i] = nil;
+ }
+ m_nNumPathNodes = 0;
+ m_nCurPathNodeId = 0;
+}
+
+// --MIAMI: Done
+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;
+ }
}
}
+// --MIAMI: Done
void
CPed::SetEvasiveStep(CEntity *reason, uint8 animType)
{
@@ -6070,7 +6866,7 @@ CPed::SetEvasiveStep(CEntity *reason, uint8 animType)
neededTurn = TWOPI - neededTurn;
CVehicle *veh = (CVehicle*)reason;
- if (reason->IsVehicle() && veh->m_vehType == VEHICLE_TYPE_CAR) {
+ if (reason->IsVehicle() && veh->IsCar()) {
if (veh->m_nCarHornTimer != 0) {
vehPressedHorn = true;
if (!IsPlayer())
@@ -6081,8 +6877,8 @@ CPed::SetEvasiveStep(CEntity *reason, uint8 animType)
SetLookFlag(veh, true);
if ((CGeneral::GetRandomNumber() & 1) && veh->GetModelIndex() != MI_RCBANDIT && animType == 0) {
stepAnim = ANIM_IDLE_TAXI;
- } else {
+ } else {
float vehDirection = CGeneral::GetRadianAngleBetweenPoints(
veh->m_vecMoveSpeed.x, veh->m_vecMoveSpeed.y,
0.0f, 0.0f);
@@ -6103,7 +6899,7 @@ CPed::SetEvasiveStep(CEntity *reason, uint8 animType)
else
angleToFace = vehDirection + HALFPI;
- stepAnim = NUM_ANIMS;
+ stepAnim = NUM_STD_ANIMS;
if (animType == 0 || animType == 1)
stepAnim = ANIM_EV_STEP;
else if (animType == 2)
@@ -6125,6 +6921,7 @@ CPed::SetEvasiveStep(CEntity *reason, uint8 animType)
}
}
+// --MIAMI: Done
void
CPed::SetEvasiveDive(CPhysical *reason, uint8 onlyRandomJump)
{
@@ -6166,7 +6963,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,
@@ -6201,6 +6998,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);
}
@@ -6235,16 +7039,9 @@ 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
}
+// --MIAMI: Done
void
CPed::PedEvadeCB(CAnimBlendAssociation* animAssoc, void* arg)
{
@@ -6254,12 +7051,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_EV_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);
}
@@ -6283,9 +7079,12 @@ CPed::PedEvadeCB(CAnimBlendAssociation* animAssoc, void* arg)
}
}
+// --MIAMI: Done
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)
@@ -6296,6 +7095,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;
@@ -6303,7 +7103,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)
@@ -6313,10 +7113,10 @@ CPed::SetDie(AnimationId animId, float delta, float speed)
}
SetPedState(PED_DIE);
- if (animId == NUM_ANIMS) {
+ if (animId == NUM_STD_ANIMS) {
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;
@@ -6330,12 +7130,20 @@ 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_FLOOR_HIT) {
+ if (dieAssoc) {
+ dieAssoc->SetCurrentTime(dieAssoc->hierarchy->totalLength - 0.01f);
+ dieAssoc->SetRun();
+ }
+ }
}
+// --MIAMI: Done
void
CPed::FinishDieAnimCB(CAnimBlendAssociation *animAssoc, void *arg)
{
@@ -6345,10 +7153,12 @@ CPed::FinishDieAnimCB(CAnimBlendAssociation *animAssoc, void *arg)
ped->bIsPedDieAnimPlaying = false;
}
+// --MIAMI: Done
void
CPed::SetDead(void)
{
- bUsesCollision = false;
+ if (!RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DROWN))
+ bUsesCollision = false;
m_fHealth = 0.0f;
if (m_nPedState == PED_DRIVING)
@@ -6364,6 +7174,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();
}
@@ -6375,28 +7186,31 @@ CPed::SetDead(void)
CEventList::RegisterEvent(EVENT_DEAD_PED, EVENT_ENTITY_PED, this, nil, 1000);
}
+// --MIAMI: Done
void
CPed::Die(void)
{
// UNUSED: This is a perfectly empty function.
}
+// --MIAMI: Done
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_standardTimer = CTimer::GetTimeInMilliseconds() + time;
m_lookTimer = CTimer::GetTimeInMilliseconds() + 3000;
}
+// --MIAMI: Done
void
CPed::Chat(void)
{
@@ -6413,6 +7227,7 @@ CPed::Chat(void)
if (partner->m_nPedState != PED_CHAT) {
ClearChat();
+ m_standardTimer = 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)
@@ -6451,6 +7266,7 @@ CPed::Chat(void)
}
}
+// --MIAMI: Done
void
CPed::ClearChat(void)
{
@@ -6462,67 +7278,31 @@ 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_IDLE_STANCE, 8.0f);
-
- if (assoc->blendAmount > 0.5f && ped) {
- CAnimManager::BlendAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_PHONE_TALK, 8.0f);
- }
-}
-
-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 (m_objective == OBJECTIVE_BUY_ICE_CREAM) {
+ bBoughtIceCream = true;
+ SetObjective(OBJECTIVE_NONE);
+ SetWanderPath(CGeneral::GetRandomNumberInRange(0, 8));
}
-
- if (assoc->blendAmount > 0.5f)
- ped->bUpdateAnimHeading = true;
-
- ped->SetWanderPath(CGeneral::GetRandomNumber() & 7);
}
-#endif
+// --MIAMI: Done
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_PHONE_IN, 4.0f);
- assoc->SetFinishCallback(ReportPhonePickUpCB, this);
- return true;
}
-
- return false;
+ return turnDone;
#else
float currentRot = RADTODEG(m_fRotationCur);
float phoneDir = CGeneral::GetRadianAngleBetweenPoints(
@@ -6553,47 +7333,113 @@ CPed::FacePhone(void)
}
#endif
}
+
+// --MIAMI: Done
bool
CPed::MakePhonecall(void)
{
-#ifdef PEDS_REPORT_CRIMES_ON_PHONE
- if (!IsPlayer() && CTimer::GetTimeInMilliseconds() > m_phoneTalkTimer - 7000 && bRunningToPhone) {
+ if (CTimer::GetTimeInMilliseconds() <= m_phoneTalkTimer)
+ return false;
- FindPlayerPed()->m_pWanted->RegisterCrime_Immediately(m_crimeToReportOnPhone, GetPosition(),
- (m_crimeToReportOnPhone == CRIME_POSSESSION_GUN ? (uintptr)m_threatEntity : (uintptr)m_victimOfPlayerCrime), false);
+ SetIdle();
+ gPhoneInfo.m_aPhones[m_phoneId].m_nState = PHONE_STATE_FREE;
+ m_phoneId = -1;
+ return true;
+}
- if (m_crimeToReportOnPhone != CRIME_POSSESSION_GUN)
- FindPlayerPed()->m_pWanted->SetWantedLevelNoDrop(1);
+// --MIAMI: Done
+void
+StartTalkingOnMobileCB(CAnimBlendAssociation* assoc, void* arg)
+{
+ CPed* ped = (CPed*)arg;
+ if (ped->m_nPedState == PED_ANSWER_MOBILE)
+ CAnimManager::BlendAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_PHONE_TALK, 4.0f);
+}
- bRunningToPhone = false;
+// --MIAMI: Done
+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;
}
-#endif
- if (CTimer::GetTimeInMilliseconds() <= m_phoneTalkTimer)
- return false;
+ ped->m_lookTimer = 0;
+}
+
+// --MIAMI: Done
+void
+CPed::SetAnswerMobile(void)
+{
+ if (m_nPedState != PED_ANSWER_MOBILE && !DyingOrDead()) {
+ SetPedState(PED_ANSWER_MOBILE);
+ RemoveWeaponAnims(GetWeapon()->m_eWeaponType, -4.0f);
+ CAnimBlendAssociation *assoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_PHONE_IN, 4.0f);
+ assoc->SetFinishCallback(StartTalkingOnMobileCB, this);
+ m_lookTimer = INT32_MAX;
+ if (m_storedWeapon == WEAPONTYPE_UNIDENTIFIED)
+ m_storedWeapon = GetWeapon()->m_eWeaponType;
-#ifdef PEDS_REPORT_CRIMES_ON_PHONE
- CAnimBlendAssociation* talkAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_PHONE_TALK);
- if (talkAssoc && talkAssoc->blendAmount > 0.5f) {
- CAnimBlendAssociation* endAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_PHONE_OUT, 8.0f);
- endAssoc->flags &= ~ASSOC_DELETEFADEDOUT;
- endAssoc->SetFinishCallback(ReportPhonePutDownCB, this);
+ RemoveWeaponModel(-1);
}
-#endif
- SetIdle();
+}
- gPhoneInfo.m_aPhones[m_phoneId].m_nState = PHONE_STATE_FREE;
-#ifndef PEDS_REPORT_CRIMES_ON_PHONE
- m_phoneId = -1;
-#endif
+// --MIAMI: Done
+void
+CPed::ClearAnswerMobile(void)
+{
+ if (m_nLastPedState == PED_ANSWER_MOBILE)
+ m_nLastPedState = PED_NONE;
- // Because SetWanderPath is now done async in ReportPhonePutDownCB
-#ifdef PEDS_REPORT_CRIMES_ON_PHONE
- return false;
-#else
- return true;
-#endif
+ if (RpAnimBlendClumpGetAssociation(GetClump(), ANIM_PHONE_TALK)) {
+ CAnimBlendAssociation *assoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_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;
+ }
+}
+
+// --MIAMI: Done
+void
+CPed::AnswerMobile(void)
+{
+ if (!IsPedInControl())
+ return;
+
+ CAnimBlendAssociation *phoneInAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_PHONE_IN);
+ CAnimBlendAssociation *phoneOutAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_PHONE_OUT);
+ CAnimBlendAssociation *phoneTalkAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_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_PHONE_TALK, 4.0f);
+ }
}
+// --MIAMI: Done
void
CPed::Teleport(CVector pos)
{
@@ -6607,16 +7453,15 @@ CPed::Teleport(CVector pos)
CWorld::Add(this);
}
+// --MIAMI: Done
void
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;
@@ -6632,6 +7477,7 @@ CPed::SetSeekCar(CVehicle *car, uint32 doorNode)
}
+// --MIAMI: Done
void
CPed::SeekCar(void)
{
@@ -6643,7 +7489,7 @@ CPed::SeekCar(void)
}
if (m_objective != OBJECTIVE_ENTER_CAR_AS_PASSENGER) {
- if (m_vehEnterType && m_objective != OBJECTIVE_ENTER_CAR_AS_DRIVER) {
+ if (!vehToSeek->IsBike() && m_vehEnterType && m_objective != OBJECTIVE_ENTER_CAR_AS_DRIVER) {
if (IsRoomToBeCarJacked()) {
dest = GetPositionToOpenCarDoor(vehToSeek, m_vehEnterType);
} else if (m_nPedType == PEDTYPE_COP) {
@@ -6714,14 +7560,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);
@@ -6738,10 +7580,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_vehEnterType);
- } else {
+ } else
+#endif
+ {
m_fRotationCur = m_fRotationDest;
if (!bVehEnterDoorIsBlocked) {
vehToSeek->SetIsStatic(false);
@@ -6757,7 +7602,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_vehEnterType == CAR_DOOR_LF || m_vehEnterType == CAR_DOOR_RF || m_vehEnterType == CAR_WINDSCREEN) && vehToSeek->pDriver ||
+ (m_vehEnterType == CAR_DOOR_LR || m_vehEnterType == CAR_DOOR_RR) && vehToSeek->pPassengers[0])) {
+ SetCarJack(vehToSeek);
+ } else {
+ SetEnterCar(vehToSeek, m_vehEnterType);
+ }
+ } else if (!vehToSeek->bIsBus && (!m_leader || m_leader != vehToSeek->pDriver) &&
(m_vehEnterType == CAR_DOOR_LF && vehToSeek->pDriver || m_vehEnterType == CAR_DOOR_RF && vehToSeek->pPassengers[0] || m_vehEnterType == CAR_DOOR_LR && vehToSeek->pPassengers[1] || m_vehEnterType == CAR_DOOR_RR && vehToSeek->pPassengers[2])) {
SetCarJack(vehToSeek);
if (m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER && m_vehEnterType != CAR_DOOR_LF)
@@ -6767,7 +7620,18 @@ CPed::SeekCar(void)
}
break;
case STATUS_ABANDONED:
- if (m_vehEnterType == CAR_DOOR_RF && vehToSeek->pPassengers[0]) {
+ if (vehToSeek->IsBike()) {
+ if ((m_vehEnterType == CAR_DOOR_LR || m_vehEnterType == CAR_DOOR_RR) && vehToSeek->pPassengers[0]) {
+ if (vehToSeek->pPassengers[0]->bDontDragMeOutCar) {
+ if (IsPlayer())
+ SetEnterCar(vehToSeek, m_vehEnterType);
+ } else {
+ SetCarJack(vehToSeek);
+ }
+ } else {
+ SetEnterCar(vehToSeek, m_vehEnterType);
+ }
+ } else if (m_vehEnterType == CAR_DOOR_RF && vehToSeek->pPassengers[0]) {
if (vehToSeek->pPassengers[0]->bDontDragMeOutCar) {
if (IsPlayer())
SetEnterCar(vehToSeek, m_vehEnterType);
@@ -6796,6 +7660,7 @@ CPed::SeekCar(void)
}
}
+// --MIAMI: Done
bool
CPed::CheckForExplosions(CVector2D &area)
{
@@ -6840,6 +7705,7 @@ CPed::CheckForExplosions(CVector2D &area)
return false;
}
+// --MIAMI: Done
CPed *
CPed::CheckForGunShots(void)
{
@@ -6855,6 +7721,7 @@ CPed::CheckForGunShots(void)
return nil;
}
+// --MIAMI: Done
CPed *
CPed::CheckForDeadPeds(void)
{
@@ -6870,19 +7737,54 @@ CPed::CheckForDeadPeds(void)
return nil;
}
+// --MIAMI: Done
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
}
+// --MIAMI: Done
bool
CPed::IsGangMember(void) const
{
return m_nPedType >= PEDTYPE_GANG1 && m_nPedType <= PEDTYPE_GANG9;
}
+// --MIAMI: Done
+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();
+}
+
+// --MIAMI: Done
+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;
+}
+
+// --MIAMI: Done
bool
CPed::IsPointerValid(void)
{
@@ -6896,27 +7798,39 @@ CPed::IsPointerValid(void)
return false;
}
+// --MIAMI: Done
void
CPed::SetPedPositionInCar(void)
{
+ bool notYet = false;
if (CReplay::IsPlayingBack())
return;
if (bChangedSeat) {
- bool notYet = false;
- if (RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_GETIN_LHS)
- || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_GETIN_LOW_LHS)
- || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_CLOSEDOOR_LHS)
- || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_CLOSEDOOR_LOW_LHS)
- || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_SHUFFLE_RHS)
- || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_LSHUFFLE_RHS)
- || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_VAN_CLOSE_L)
- || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_VAN_CLOSE)
- || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_VAN_GETIN_L)
- || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_VAN_GETIN)
- || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_COACH_IN_L)
- || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_COACH_IN_R)) {
- notYet = true;
+ if (m_pMyVehicle->IsBike()) {
+ if (RpAnimBlendClumpGetAssociation(GetClump(), ANIM_BIKE_JUMPON_R)
+ || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_BIKE_JUMPON_L)
+ || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_BIKE_KICK)) {
+ LineUpPedWithCar(LINE_UP_TO_CAR_START);
+ return;
+ }
+ bChangedSeat = false;
+ } else {
+ if (RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_GETIN_LHS)
+ || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_GETIN_LOW_LHS)
+ || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_CLOSEDOOR_LHS)
+ || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_CLOSEDOOR_LOW_LHS)
+ || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_SHUFFLE_RHS)
+ || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_LSHUFFLE_RHS)
+ || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_VAN_CLOSE_L)
+ || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_VAN_CLOSE)
+ || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_VAN_GETIN_L)
+ || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_VAN_GETIN)
+ || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_COACH_IN_L)
+ || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_COACH_IN_R)
+ || RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_JUMPIN_LHS)) {
+ notYet = true;
+ }
}
if (notYet) {
LineUpPedWithCar(LINE_UP_TO_CAR_START);
@@ -6929,14 +7843,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];
@@ -6944,6 +7860,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();
@@ -6955,6 +7875,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;
@@ -6970,6 +7891,7 @@ CPed::SetPedPositionInCar(void)
GetMatrix() = newMat;
}
+// --MIAMI: Done
void
CPed::LookForSexyPeds(void)
{
@@ -6995,6 +7917,7 @@ CPed::LookForSexyPeds(void)
m_lookTimer = CTimer::GetTimeInMilliseconds() + 10000;
}
+// --MIAMI: Done
void
CPed::LookForSexyCars(void)
{
@@ -7024,6 +7947,7 @@ CPed::LookForSexyCars(void)
}
}
+// --MIAMI: Done
bool
CPed::LookForInterestingNodes(void)
{
@@ -7165,15 +8089,160 @@ CPed::LookForInterestingNodes(void)
return true;
}
+// --MIAMI: Done
+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;
+ }
+}
+
+// --MIAMI: Done
+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_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_IDLE_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_SEAT_DOWN);
+ if (assoc)
+ assoc->blendDelta = -8.0f;
+ break;
+ case WAITSTATE_SIT_IDLE:
+ assoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_SEAT_IDLE);
+ if (assoc)
+ assoc->blendDelta = -8.0f;
+ break;
+ case WAITSTATE_SIT_UP:
+ assoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_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_KO_SKID_FRONT))
+ SetGetUp();
+
+ break;
+ case WAITSTATE_BOMBER:
+ assoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_BOMBER);
+ 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);
+ if (assoc)
+ assoc->blendDelta = -8.0f;
+ break;
+ case WAITSTATE_PLAYANIM_HANDSUP_SIMPLE:
+ assoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_HANDSUP);
+ if (assoc)
+ assoc->blendDelta = -8.0f;
+ break;
+ default:
+ break;
+ }
+ m_nWaitState = WAITSTATE_FALSE;
+}
+
+// --MIAMI: Done
void
CPed::SetWaitState(eWaitState state, void *time)
{
- AnimationId waitAnim = NUM_ANIMS;
+ AnimationId waitAnim = NUM_STD_ANIMS;
CAnimBlendAssociation *animAssoc;
if (!IsPedInControl())
return;
+ if (m_nWaitState == WAITSTATE_RIOT && state != WAITSTATE_FALSE)
+ return;
+
if (state != m_nWaitState)
FinishedWaitCB(nil, this);
@@ -7199,6 +8268,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;
@@ -7227,7 +8298,6 @@ CPed::SetWaitState(eWaitState state, void *time)
m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 5000;
animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_TURN_180, 4.0f);
animAssoc->SetFinishCallback(FinishedWaitCB, this);
- animAssoc->SetDeleteCallback(RestoreHeadingRateCB, this);
break;
case WAITSTATE_SURPRISE:
m_headingRate = 0.0f;
@@ -7245,6 +8315,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();
@@ -7265,10 +8336,10 @@ CPed::SetWaitState(eWaitState state, void *time)
case WAITSTATE_PLAYANIM_COWER:
waitAnim = ANIM_HANDSCOWER;
case WAITSTATE_PLAYANIM_HANDSUP:
- if (waitAnim == NUM_ANIMS)
+ if (waitAnim == NUM_STD_ANIMS)
waitAnim = ANIM_HANDSUP;
case WAITSTATE_PLAYANIM_HANDSCOWER:
- if (waitAnim == NUM_ANIMS)
+ if (waitAnim == NUM_STD_ANIMS)
waitAnim = ANIM_HANDSCOWER;
m_headingRate = 0.0f;
if (time)
@@ -7282,10 +8353,10 @@ CPed::SetWaitState(eWaitState state, void *time)
case WAITSTATE_PLAYANIM_DUCK:
waitAnim = ANIM_DUCK_DOWN;
case WAITSTATE_PLAYANIM_TAXI:
- if (waitAnim == NUM_ANIMS)
+ if (waitAnim == NUM_STD_ANIMS)
waitAnim = ANIM_IDLE_TAXI;
case WAITSTATE_PLAYANIM_CHAT:
- if (waitAnim == NUM_ANIMS)
+ if (waitAnim == NUM_STD_ANIMS)
waitAnim = ANIM_IDLE_CHAT;
if (time)
m_nWaitTimer = CTimer::GetTimeInMilliseconds() + *(int*)time;
@@ -7307,23 +8378,88 @@ CPed::SetWaitState(eWaitState state, void *time)
animAssoc->SetFinishCallback(RestoreHeadingRateCB, this);
#endif
break;
+ case WAITSTATE_SIT_DOWN:
+ animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_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_SEAT_UP, 4.0f);
+ animAssoc->SetFinishCallback(FinishedWaitCB, this);
+ m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 100000;
+ break;
+ case WAITSTATE_SIT_IDLE:
+ animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_SEAT_IDLE, 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_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, 4.0f);
+ animAssoc->SetDeleteCallback(DeleteSunbatheIdleAnimCB, this);
+ m_nWaitTimer = CTimer::GetTimeInMilliseconds() + CGeneral::GetRandomNumberInRange(50000, 100000);
+ break;
+ case WAITSTATE_FAST_FALL:
+ SetFall(-1, ANIM_KO_SKID_FRONT, true);
+ break;
+ case WAITSTATE_BOMBER:
+ CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_BOMBER, 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, 4.0f);
+ break;
+ case WAITSTATE_PLAYANIM_HANDSUP_SIMPLE:
+ animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_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;
}
m_nWaitState = state;
}
+// --MIAMI: Done
void
CPed::Wait(void)
{
- AnimationId mustHaveAnim = NUM_ANIMS;
+ AnimationId mustHaveAnim = NUM_STD_ANIMS;
CAnimBlendAssociation *animAssoc;
CPed *pedWeLook;
if (DyingOrDead()) {
- m_nWaitState = WAITSTATE_FALSE;
+ ClearWaitState();
RestoreHeadingRate();
return;
}
@@ -7333,7 +8469,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);
}
}
@@ -7342,7 +8478,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);
@@ -7356,7 +8492,7 @@ CPed::Wait(void)
case WAITSTATE_CROSS_ROAD_LOOK:
if (CTimer::GetTimeInMilliseconds() > m_nWaitTimer) {
- m_nWaitState = WAITSTATE_FALSE;
+ ClearWaitState();
animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_ROAD_CROSS);
if (animAssoc) {
animAssoc->blendDelta = -8.0f;
@@ -7373,7 +8509,7 @@ CPed::Wait(void)
CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_XPRESS_SCRATCH, 4.0f);
}
} else {
- m_nWaitState = WAITSTATE_FALSE;
+ ClearWaitState();
SetMoveState(PEDMOVE_WALK);
}
break;
@@ -7384,14 +8520,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();
@@ -7409,7 +8544,7 @@ CPed::Wait(void)
animAssoc->SetFinishCallback(FinishedWaitCB, this);
m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 5000;
} else {
- m_nWaitState = WAITSTATE_FALSE;
+ ClearWaitState();
}
}
break;
@@ -7438,7 +8573,7 @@ CPed::Wait(void)
if (animAssoc->animId == ANIM_TURN_180) {
m_fRotationCur = CGeneral::LimitRadianAngle(PI + m_fRotationCur);
- m_nWaitState = WAITSTATE_FALSE;
+ ClearWaitState();
SetMoveState(PEDMOVE_WALK);
m_nStoredMoveState = PEDMOVE_NONE;
m_panicCounter = 0;
@@ -7475,7 +8610,7 @@ CPed::Wait(void)
case WAITSTATE_LOOK_ABOUT:
if (CTimer::GetTimeInMilliseconds() > m_nWaitTimer) {
- m_nWaitState = WAITSTATE_FALSE;
+ ClearWaitState();
animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_HBHB);
if (animAssoc) {
animAssoc->blendDelta = -8.0f;
@@ -7488,7 +8623,7 @@ CPed::Wait(void)
mustHaveAnim = ANIM_HANDSUP;
case WAITSTATE_PLAYANIM_HANDSCOWER:
- if (mustHaveAnim == NUM_ANIMS)
+ if (mustHaveAnim == NUM_STD_ANIMS)
mustHaveAnim = ANIM_HANDSCOWER;
animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), mustHaveAnim);
@@ -7500,39 +8635,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);
@@ -7560,15 +8695,15 @@ CPed::Wait(void)
mustHaveAnim = ANIM_HANDSCOWER;
case WAITSTATE_PLAYANIM_DUCK:
- if (mustHaveAnim == NUM_ANIMS)
+ if (mustHaveAnim == NUM_STD_ANIMS)
mustHaveAnim = ANIM_DUCK_DOWN;
case WAITSTATE_PLAYANIM_TAXI:
- if (mustHaveAnim == NUM_ANIMS)
+ if (mustHaveAnim == NUM_STD_ANIMS)
mustHaveAnim = ANIM_IDLE_TAXI;
case WAITSTATE_PLAYANIM_CHAT:
- if (mustHaveAnim == NUM_ANIMS)
+ if (mustHaveAnim == NUM_STD_ANIMS)
mustHaveAnim = ANIM_IDLE_CHAT;
if (CTimer::GetTimeInMilliseconds() > m_nWaitTimer) {
@@ -7577,21 +8712,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:
@@ -7601,13 +8738,154 @@ CPed::Wait(void)
animAssoc->flags |= ASSOC_DELETEFADEDOUT;
CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_IDLE_STANCE, 4.0f);
int timer = 2000;
- m_nWaitState = WAITSTATE_FALSE;
+ ClearWaitState();
SetWaitState(WAITSTATE_CROSS_ROAD_LOOK, &timer);
}
} else {
- m_nWaitState = WAITSTATE_FALSE;
+ ClearWaitState();
}
break;
+ case WAITSTATE_SIT_DOWN:
+ if (CTimer::GetTimeInMilliseconds() > m_nWaitTimer) {
+ ClearWaitState();
+ SetWaitState(WAITSTATE_SIT_IDLE, 0);
+ }
+ break;
+ //case WAITSTATE_SIT_DOWN_RVRS:
+ case WAITSTATE_SIT_UP:
+ if (CTimer::GetTimeInMilliseconds() > m_nWaitTimer) {
+ if (m_attractor)
+ GetPedAttractorManager()->BroadcastDeparture(this, m_attractor);
+ ClearWaitState();
+ 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_FUKU - 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_149);
+ }
+ }
+ }
+ }
+ }
+ 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;
}
@@ -7616,6 +8894,26 @@ CPed::Wait(void)
RestoreHeadingRate();
}
+// --MIAMI: Done
+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();
+}
+
+// --MIAMI: Done
void
CPed::FinishedWaitCB(CAnimBlendAssociation *animAssoc, void *arg)
{
@@ -7626,18 +8924,21 @@ CPed::FinishedWaitCB(CAnimBlendAssociation *animAssoc, void *arg)
ped->Wait();
}
+// --MIAMI: Done
void
CPed::RestoreHeadingRate(void)
{
m_headingRate = m_pedStats->m_headingChangeRate;
}
+// --MIAMI: Done
void
CPed::RestoreHeadingRateCB(CAnimBlendAssociation *assoc, void *arg)
{
- ((CPed*)arg)->m_headingRate = ((CPed*)arg)->m_pedStats->m_headingChangeRate;
+ ((CPed*)arg)->RestoreHeadingRate();
}
+// --MIAMI: Done
void
CPed::FlagToDestroyWhenNextProcessed(void)
{
@@ -7661,6 +8962,7 @@ CPed::FlagToDestroyWhenNextProcessed(void)
m_pVehicleAnim = nil;
}
+// --MIAMI: Done
void
CPed::SetSolicit(uint32 time)
{
@@ -7686,11 +8988,16 @@ CPed::SetSolicit(uint32 time)
}
}
+// --MIAMI: Done
void
CPed::Solicit(void)
{
if (m_standardTimer >= CTimer::GetTimeInMilliseconds() && m_carInObjective) {
CVector doorPos = GetPositionToOpenCarDoor(m_carInObjective, m_vehEnterType, 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
@@ -7699,9 +9006,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)
@@ -7723,9 +9030,11 @@ CPed::Solicit(void)
} else {
m_pVehicleAnim = nil;
SetLeader(m_carInObjective->pDriver);
+ Say(SOUND_PED_SOLICIT);
}
}
+// --MIAMI: Done
void
CPed::SetBuyIceCream(void)
{
@@ -7735,29 +9044,29 @@ 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_standardTimer = CTimer::GetTimeInMilliseconds() + 3000;
- SetPedState(PED_BUY_ICECREAM);
+// --MIAMI: Done
+void
+CPed::BuyIceCream(void)
+{
+ if (m_carInObjective) {
+ CPed *driver = m_carInObjective->pDriver;
+ if (driver && CTimer::GetTimeInMilliseconds() > m_standardTimer) {
+ 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));
}
}
+// --MIAMI: Done
bool
CPed::PossiblyFindBetterPosToSeekCar(CVector *pos, CVehicle *veh)
{
@@ -7891,16 +9200,19 @@ CPed::PossiblyFindBetterPosToSeekCar(CVector *pos, CVehicle *veh)
return true;
}
+// --MIAMI: Done
void
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
+// --MIAMI: Done
bool
CPed::CanPedJumpThis(CEntity *unused, CVector *damageNormal)
{
@@ -7913,7 +9225,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();
@@ -7932,29 +9244,14 @@ 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
+// --MIAMI: Done
void
CPed::SetJump(void)
{
- if (!bInVehicle &&
-#if defined VC_PED_PORTS || defined FIX_BUGS
- m_nPedState != PED_JUMP && !RpAnimBlendClumpGetAssociation(GetClump(), ANIM_JUMP_LAUNCH) &&
-#endif
+ if (!bInVehicle && m_nPedState != PED_JUMP && !RpAnimBlendClumpGetAssociation(GetClump(), ANIM_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_JUMP_LAUNCH, 8.0f);
@@ -7963,6 +9260,7 @@ CPed::SetJump(void)
}
}
+// --MIAMI: Done
void
CPed::FinishLaunchCB(CAnimBlendAssociation *animAssoc, void *arg)
{
@@ -7971,8 +9269,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) {
@@ -7982,11 +9280,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_HANDSCOWER, 8.0f);
+ CAnimBlendAssociation *handsCoverAssoc = CAnimManager::BlendAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_HIT_WALL, 8.0f);
handsCoverAssoc->flags &= ~ASSOC_FADEOUTWHENDONE;
handsCoverAssoc->SetFinishCallback(FinishHitHeadCB, ped);
ped->bIsLanding = true;
@@ -8005,20 +9304,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) {
@@ -8032,12 +9323,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;
@@ -8080,6 +9370,7 @@ CPed::FinishLaunchCB(CAnimBlendAssociation *animAssoc, void *arg)
}
}
+// --MIAMI: Done
void
CPed::FinishJumpCB(CAnimBlendAssociation *animAssoc, void *arg)
{
@@ -8091,6 +9382,7 @@ CPed::FinishJumpCB(CAnimBlendAssociation *animAssoc, void *arg)
animAssoc->blendDelta = -1000.0f;
}
+// --MIAMI: Done
void
CPed::FinishHitHeadCB(CAnimBlendAssociation *animAssoc, void *arg)
{
@@ -8107,6 +9399,7 @@ CPed::FinishHitHeadCB(CAnimBlendAssociation *animAssoc, void *arg)
ped->bIsLanding = false;
}
+// --MIAMI: Done
bool
CPed::CanPedDriveOff(void)
{
@@ -8122,134 +9415,28 @@ 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;
- }
-}
-
+// --MIAMI: Done
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();
}
}
+// --MIAMI: Done
void
CPed::WarpPedIntoCar(CVehicle *car)
{
@@ -8267,6 +9454,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;
@@ -8302,137 +9493,209 @@ CPed::WarpPedIntoCar(CVehicle *car)
DMAudio.PlayOneShot(car->m_audioEntityId, SOUND_CAR_ENGINE_START, 1.0f);
}
-#ifdef VC_PED_PORTS
RpAnimBlendClumpSetBlendDeltas(GetClump(), ASSOC_PARTIAL, -1000.0f);
- // VC uses AddInCarAnims but we don't have that
- m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, car->GetDriverAnim(), 100.0f);
+ AddInCarAnims(car, car->pDriver == this);
RemoveWeaponWhenEnteringVehicle();
-#else
- if (car->IsBoat()) {
-#ifndef FIX_BUGS
- m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_DRIVE_BOAT, 100.0f);
-#else
- m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, car->GetDriverAnim(), 100.0f);
-#endif
- CWeaponInfo *ourWeapon = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType);
- RemoveWeaponModel(ourWeapon->m_nModelId);
- } else {
- // Because we can use Uzi for drive by
- RemoveWeaponWhenEnteringVehicle();
-
- if (car->bLowVehicle)
- m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_LSIT, 100.0f);
- else
- m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_SIT, 100.0f);
- }
-#endif
- StopNonPartialAnims();
if (car->bIsBus)
bRenderPedInCar = false;
bChangedSeat = true;
}
+// --MIAMI: Done
+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)
+// --MIAMI: Done
+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;
+}
+
+// --MIAMI: Done
+void
+CPed::AttachPedToEntity(CEntity *ent, CVector offset, uint16 type, float rot, eWeaponType weapon)
+{
+ if (!ent || bInVehicle)
+ return;
- for (i = 0; i < NUMEVENTS; i++) {
- if (gaEvent[i].type == EVENT_NULL || gaEvent[i].type > EVENT_CAR_SET_ON_FIRE)
- 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;
+ }
- // 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;
+ if (IsPlayer()) {
+ m_objective = OBJECTIVE_NONE;
+ m_prevObjective = OBJECTIVE_NONE;
+ }
+ SetStoredState();
+ SetPedState(PED_IDLE);
+ CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_IDLE_STANCE, 1000.0f);
- if (victim && gaEvent[i].entityRef != victimRef)
- 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);
+ }
- if (gaEvent[i].criminal != player)
- continue;
+ PositionAttachedPed();
+}
- dist = (GetPosition() - gaEvent[i].posn).Magnitude();
- if (dist < mindist) {
- mindist = dist;
- event = i;
+// --MIAMI: Done
+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_IDLE_STANCE, 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);
+// --MIAMI: Done
+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;
+// --MIAMI: Done
+void
+CPed::Undress(const char* name)
+{
+ int mi = GetModelIndex();
+ CAnimBlendAssociation* pAnim = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_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;
+// --MIAMI: Done
+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));
@@ -8446,15 +9709,13 @@ CPed::Save(uint8*& buf)
CopyToBuf(buf, GetPosition().z);
SkipSaveBuf(buf, 288);
CopyToBuf(buf, CharCreatedBy);
- SkipSaveBuf(buf, 351);
+ SkipSaveBuf(buf, 499);
CopyToBuf(buf, m_fHealth);
CopyToBuf(buf, m_fArmour);
- SkipSaveBuf(buf, 148);
- for (int i = 0; i < 13; i++) // has to be hardcoded
+ SkipSaveBuf(buf, 172);
+ for (int i = 0; i < 10; i++) // has to be hardcoded
m_weapons[i].Save(buf);
- SkipSaveBuf(buf, 5);
- CopyToBuf(buf, m_maxWeaponTypeAllowed);
- SkipSaveBuf(buf, 162);
+ SkipSaveBuf(buf, 252);
}
void
@@ -8466,15 +9727,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 d27853d6..5683c7c9 100644
--- a/src/peds/Ped.h
+++ b/src/peds/Ped.h
@@ -9,18 +9,20 @@
#include "Physical.h"
#include "Weapon.h"
#include "WeaponInfo.h"
+#include "AnimationId.h"
+#include "PathFind.h"
#define FEET_OFFSET 1.04f
#define CHECK_NEARBY_THINGS_MAX_DIST 15.0f
#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
{
@@ -30,6 +32,13 @@ struct PedAudioData
int m_nMaxRandomDelayTime;
};
+enum
+{
+ ATTACK_IN_PROGRESS,
+ CANT_ATTACK,
+ WATCH_UNTIL_HE_DISAPPEARS,
+};
+
enum eFormation
{
FORMATION_UNDEFINED,
@@ -80,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
@@ -95,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,
@@ -114,6 +130,9 @@ enum PedFightMoves
FIGHTMOVE_HITBIGSTEP,
FIGHTMOVE_HITONFLOOR,
FIGHTMOVE_HITBEHIND,
+ FIGHTMOVE_MELEE1,
+ FIGHTMOVE_MELEE2,
+ FIGHTMOVE_MELEE3,
FIGHTMOVE_IDLE2NORM,
NUM_FIGHTMOVES
};
@@ -150,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,
@@ -166,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,
@@ -187,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 {
@@ -253,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,
@@ -269,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,
@@ -284,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;
@@ -341,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;
@@ -381,21 +452,57 @@ public:
uint32 bVehExitWillBeInstant : 1;
uint32 bHasAlreadyBeenRecorded : 1;
uint32 bFallenDown : 1;
-#ifdef VC_PED_PORTS
- uint32 bSomeVCflag1 : 1;
-#endif
-#ifdef PED_SKIN
- uint32 bDontAcceptIKLookAts : 1; // TODO: find uses of this
-#endif
- uint32 m_ped_flagI40 : 1;
- uint32 m_ped_flagI80 : 1; // originally unused, KANGAROO_CHEAT define makes use of this as cheat toggle
-
+ 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;
+
+ // our own flags
+ uint32 m_ped_flagI80 : 1; // KANGAROO_CHEAT define makes use of this as cheat toggle
+
+ uint8 m_gangFlags;
uint8 CharCreatedBy;
eObjective m_objective;
eObjective m_prevObjective;
CPed *m_pedInObjective;
CVehicle *m_carInObjective;
CVector m_nextRoutePointPos;
+ float m_attractorHeading;
CPed *m_leader;
eFormation m_pedFormation;
uint32 m_fearFlags;
@@ -405,10 +512,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;
@@ -424,16 +528,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;
- int8 m_nPathDir;
-public:
- CPathNode *m_pLastPathNode;
- CPathNode *m_pNextPathNode;
+ 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;
+ char m_nPathDir;
+ 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;
@@ -453,29 +564,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;
@@ -483,9 +596,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;
@@ -501,18 +616,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;
+ uint32 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);
static void *operator new(size_t, int);
@@ -522,6 +653,7 @@ public:
CPed(uint32 pedType);
~CPed(void);
+ void DeleteRwObject();
void SetModelIndex(uint32 mi);
void ProcessControl(void);
void Teleport(CVector);
@@ -538,14 +670,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_KO_SHOT_FRONT1, 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);
@@ -554,9 +687,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);
@@ -565,7 +699,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);
@@ -579,11 +713,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);
@@ -593,9 +727,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*);
@@ -604,7 +735,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);
@@ -630,18 +763,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);
@@ -649,27 +789,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);
@@ -692,6 +830,7 @@ public:
void ReactToPointGun(CEntity*);
void SeekCar(void);
bool PositionPedOutOfCollision(void);
+ bool PositionAnyPedOutOfCollision(void);
bool RunToReportCrime(eCrimeType);
bool PlacePedOnDryLand(void);
bool PossiblyFindBetterPosToSeekCar(CVector*, CVehicle*);
@@ -702,7 +841,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);
@@ -711,6 +849,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);
@@ -738,8 +893,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);
@@ -747,13 +905,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);
@@ -768,8 +932,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);
@@ -777,29 +947,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; }
@@ -809,41 +986,103 @@ 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; }
-
- // It was inlined in III but not in VC.
- inline void
- ReplaceWeaponWhenExitingVehicle(void)
- {
- 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);
- }
+ 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
- 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);
- }
- }
+ void ReplaceWeaponWhenExitingVehicle(void);
+ void RemoveWeaponWhenEnteringVehicle(void);
bool IsNotInWreckedVehicle()
{
return m_pMyVehicle != nil && ((CEntity*)m_pMyVehicle)->GetStatus() != STATUS_WRECKED;
}
+
+ // My names. Inlined in VC
+ AnimationId GetFireAnimNotDucking(CWeaponInfo* weapon) {
+ if (m_nPedType == PEDTYPE_COP && !!weapon->m_bCop3rd)
+ return ANIM_WEAPON_FIRE_3RD;
+ else
+ return GetPrimaryFireAnim(weapon);
+ }
+
+ static AnimationId Get3rdFireAnim(CWeaponInfo* weapon) {
+ if (!!weapon->m_bCop3rd)
+ return ANIM_WEAPON_FIRE_3RD;
+ else
+ return (AnimationId)0;
+ }
+
+ static AnimationId GetFireAnimGround(CWeaponInfo* weapon, bool kickFloorIfNone = true) {
+ if (!!weapon->m_bGround2nd)
+ return ANIM_WEAPON_CROUCHFIRE;
+ else if (!!weapon->m_bGround3rd)
+ return ANIM_WEAPON_FIRE_3RD;
+ else if (kickFloorIfNone)
+ return ANIM_KICK_FLOOR;
+ else
+ return (AnimationId)0;
+ }
+
+ static AnimationId GetPrimaryFireAnim(CWeaponInfo* weapon) {
+ if (weapon->m_bAnimDetonate)
+ return ANIM_BOMBER;
+ else
+ return ANIM_WEAPON_FIRE;
+ }
+
+ static AnimationId GetCrouchReloadAnim(CWeaponInfo* weapon) {
+ if (!!weapon->m_bReload)
+ return ANIM_WEAPON_CROUCHRELOAD;
+ else
+ return (AnimationId)0;
+ }
+
+ static AnimationId GetCrouchFireAnim(CWeaponInfo* weapon) {
+ if (!!weapon->m_bCrouchFire)
+ return ANIM_WEAPON_CROUCHFIRE;
+ else
+ return (AnimationId)0;
+ }
+
+ static AnimationId GetReloadAnim(CWeaponInfo* weapon) {
+ if (!!weapon->m_bReload)
+ return ANIM_WEAPON_RELOAD;
+ else
+ return (AnimationId)0;
+ }
+
+ static AnimationId GetFightIdleWithMeleeAnim(CWeaponInfo* weapon) {
+ if (!!weapon->m_bFightMode)
+ return ANIM_MELEE_IDLE_FIGHTMODE;
+ else
+ return (AnimationId)0;
+ }
+
+ static AnimationId GetFinishingAttackAnim(CWeaponInfo* weapon) {
+ if (!!weapon->m_bFinish3rd)
+ return ANIM_MELEE_ATTACK_FINISH;
+ else
+ return (AnimationId)0;
+ }
+
+ static AnimationId GetSecondFireAnim(CWeaponInfo* weapon) {
+ if (!!weapon->m_bUse2nd)
+ return ANIM_WEAPON_FIRE_2ND; // or ANIM_MELEE_ATTACK_2ND
+ else
+ return (AnimationId)0;
+ }
+
+ static AnimationId GetMeleeStartAnim(CWeaponInfo* weapon) {
+ if (!!weapon->m_bPartialAttack)
+ return ANIM_MELEE_ATTACK_START;
+ else
+ return (AnimationId)0;
+ }
+ // --
+
// My additions, because there were many, many instances of that.
inline void SetFindPathAndFlee(CEntity *fleeFrom, int time, bool walk = false)
{
@@ -862,50 +1101,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
@@ -915,14 +1138,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);
@@ -942,18 +1161,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 a747c684..d5705a2f 100644
--- a/src/peds/PedAI.cpp
+++ b/src/peds/PedAI.cpp
@@ -24,6 +24,13 @@
#include "CarAI.h"
#include "Zones.h"
#include "Cranes.h"
+#include "PedAttractor.h"
+#include "Bike.h"
+#include "Weather.h"
+#include "GameLogic.h"
+#include "Streaming.h"
+
+//--MIAMI: file done
CVector vecPedCarDoorAnimOffset;
CVector vecPedCarDoorLoAnimOffset;
@@ -31,7 +38,13 @@ CVector vecPedVanRearDoorAnimOffset;
CVector vecPedQuickDraggedOutCarAnimOffset;
CVector vecPedDraggedOutCarAnimOffset;
CVector vecPedTrainDoorAnimOffset;
+CVector vecPedStdBikeJumpRhsAnimOffset;
+CVector vecPedVespaBikeJumpRhsAnimOffset;
+CVector vecPedHarleyBikeJumpRhsAnimOffset;
+CVector vecPedDirtBikeJumpRhsAnimOffset;
+CVector vecPedBikeKickAnimOffset;
+// --MIAMI: Done
void
CPed::SetObjectiveTimer(int time)
{
@@ -42,32 +55,42 @@ CPed::SetObjectiveTimer(int time)
}
}
+// --MIAMI: Done
void
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;
}
}
+// --MIAMI: Done
void
CPed::ForceStoredObjective(eObjective objective)
{
@@ -76,62 +99,56 @@ 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;
}
}
+// --MIAMI: Done
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;
}
+// --MIAMI: Done
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);
@@ -163,39 +180,40 @@ CPed::SetObjective(eObjective newObj)
}
}
+// --MIAMI: Done
void
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 +223,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 +260,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 +274,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 +309,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 +323,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 +357,20 @@ 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;
- }
-}
-
+// --MIAMI: Done
// 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 +382,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;
@@ -397,6 +403,7 @@ CPed::SetObjective(eObjective newObj, int16 routePoint, int16 routeType)
}
}
+// --MIAMI: Done
void
CPed::SetObjective(eObjective newObj, CVector dest)
{
@@ -406,25 +413,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 +440,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 +450,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;
@@ -478,28 +543,40 @@ CPed::SetObjective(eObjective newObj, CVector dest)
}
}
+// --MIAMI: Done
+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;
+ }
+}
+
+// --MIAMI: Done
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);
@@ -509,6 +586,7 @@ CPed::ClearObjective(void)
}
}
+// --MIAMI: Done
void
CPed::ClearLeader(void)
{
@@ -528,6 +606,7 @@ CPed::ClearLeader(void)
}
}
+// --MIAMI: Done
void
CPed::UpdateFromLeader(void)
{
@@ -544,14 +623,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 +670,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 +681,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 +710,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 +726,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 +755,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);
}
@@ -690,6 +765,7 @@ CPed::UpdateFromLeader(void)
}
}
+// --MIAMI: Done
void
CPed::RestorePreviousObjective(void)
{
@@ -697,10 +773,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) {
@@ -715,6 +788,7 @@ CPed::RestorePreviousObjective(void)
bObjectiveCompleted = false;
}
+// --MIAMI: Done
void
CPed::ProcessObjective(void)
{
@@ -752,21 +826,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 +868,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 +876,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 +895,8 @@ CPed::ProcessObjective(void)
}
}
} else {
- SetSeek(m_vecSeekPosEx, m_distanceToCountSeekDoneEx);
+ CVector seekPos = m_vecSpotToGuard;
+ SetSeek(seekPos, m_radiusToGuard);
}
break;
}
@@ -825,9 +917,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 +934,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 +950,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 +961,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 +983,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 +1019,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;
- 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_vehEnterType = 0;
- if (m_pedInObjective == vehOfTarget->pDriver || vehOfTarget->bIsBus) {
- m_vehEnterType = CAR_DOOR_LF;
- } else if (m_pedInObjective == vehOfTarget->pPassengers[0]) {
- m_vehEnterType = CAR_DOOR_RF;
- } else if (m_pedInObjective == vehOfTarget->pPassengers[1]) {
- m_vehEnterType = CAR_DOOR_LR;
- } else if (m_pedInObjective == vehOfTarget->pPassengers[2]) {
- m_vehEnterType = CAR_DOOR_RR;
- }
- // Unused
- // GetPositionToOpenCarDoor(vehOfTarget, m_vehEnterType);
- SetSeekCar(vehOfTarget, m_vehEnterType);
- SetMoveState(PEDMOVE_RUN);
- }
- }
- }
- }
- }
+ ClearLookFlag();
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_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_DUCK_DOWN);
- if (!duckAnim || duckAnim->blendDelta < 0.0f) {
- CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_DUCK_DOWN, 4.0f);
- bIsDucking = true;
- }
- break;
- } else {
- CAnimBlendAssociation* duckAnim = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_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 +1058,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 +1080,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 +1090,18 @@ CPed::ProcessObjective(void)
SetMoveState(m_pedInObjective->m_nMoveState);
else
SetMoveState(PEDMOVE_STILL);
+
+ if (m_objective == OBJECTIVE_HASSLE_CHAR) {
+ Say(SOUND_PED_COP_REACTION);
+ m_pedInObjective->Say(SOUND_PED_UNK_126);
+ 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 +1127,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 +1143,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 +1176,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_vehEnterType = 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_vehEnterType = CAR_DOOR_RR;
+ foundSeat = true;
+ }
} else {
- m_vehEnterType = CAR_DOOR_RR;
+ m_vehEnterType = CAR_DOOR_LR;
foundSeat = true;
}
} else {
- m_vehEnterType = CAR_DOOR_LR;
+ m_vehEnterType = CAR_DOOR_RF;
foundSeat = true;
}
- } else {
- m_vehEnterType = 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 +1218,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 +1238,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 +1247,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 +1277,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 +1298,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 +1330,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 +1355,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 +1392,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 +1445,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 +1510,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_hitRecoverTimer < 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 +1578,14 @@ CPed::ProcessObjective(void)
float distWithTargetScSqr = distWithTarget.MagnitudeSqr();
if (distWithTargetScSqr <= sq(10.0f)) {
if (distWithTargetScSqr <= sq(1.4f)) {
- CAnimBlendAssociation *reloadAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_AK_RELOAD);
+ CAnimBlendAssociation *reloadAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_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_FIGHT_PPUNCH, 8.0f);
punchAssoc->flags |= ASSOC_DELETEFADEDOUT;
punchAssoc->flags |= ASSOC_FADEOUTWHENDONE;
@@ -1832,7 +1597,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 +1615,7 @@ CPed::ProcessObjective(void)
if (weaponType != WEAPONTYPE_UNARMED && weaponType != WEAPONTYPE_BASEBALLBAT)
SetCurrentWeapon(WEAPONTYPE_UNARMED);
- CAnimBlendAssociation *newReloadAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_AK_RELOAD, 8.0f);
+ CAnimBlendAssociation *newReloadAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_FUCKU, 8.0f);
newReloadAssoc->flags |= ASSOC_DELETEFADEDOUT;
newReloadAssoc->flags |= ASSOC_FADEOUTWHENDONE;
}
@@ -1866,13 +1631,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 +1864,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 +1885,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.fUnkMaxVelocity;
+ 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) {
@@ -1956,18 +2060,20 @@ CPed::ProcessObjective(void)
}
}
+// --MIAMI: Done
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());
}
+// --MIAMI: Done
int
CPed::GetNextPointOnRoute(void)
{
@@ -1995,16 +2101,18 @@ CPed::GetNextPointOnRoute(void)
return nextPoint;
}
+// --MIAMI: Done
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;
}
+// --MIAMI: Done
bool
CPed::CanSeeEntity(CEntity *entity, float threshold)
{
@@ -2030,14 +2138,19 @@ CPed::CanSeeEntity(CEntity *entity, float threshold)
return neededTurn < threshold || TWOPI - threshold < neededTurn;
}
+// --MIAMI: Done
// Only used while deciding which gun ped should switch to, if no ammo left.
bool
CPed::SelectGunIfArmed(void)
{
- for (int i = 0; i < m_maxWeaponTypeAllowed; i++) {
+ for (int i = 0; i < TOTAL_WEAPON_SLOTS; i++) {
if (GetWeapon(i).m_nAmmoTotal > 0) {
eWeaponType weaponType = GetWeapon(i).m_eWeaponType;
- if (weaponType >= WEAPONTYPE_COLT45 && weaponType != WEAPONTYPE_M16 && weaponType <= WEAPONTYPE_FLAMETHROWER) {
+
+ if (weaponType == WEAPONTYPE_COLT45 || weaponType == WEAPONTYPE_PYTHON || weaponType == WEAPONTYPE_SHOTGUN ||
+ weaponType == WEAPONTYPE_SPAS12_SHOTGUN || weaponType == WEAPONTYPE_STUBBY_SHOTGUN ||
+ weaponType == WEAPONTYPE_UZI || weaponType == WEAPONTYPE_M4 || weaponType == WEAPONTYPE_MP5 ||
+ weaponType == WEAPONTYPE_ROCKETLAUNCHER || weaponType == WEAPONTYPE_FLAMETHROWER || weaponType == WEAPONTYPE_SNIPERRIFLE) {
SetCurrentWeapon(i);
return true;
}
@@ -2046,21 +2159,21 @@ CPed::SelectGunIfArmed(void)
SetCurrentWeapon(WEAPONTYPE_UNARMED);
return false;
}
-
+// --MIAMI: Done
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) {
@@ -2131,6 +2244,7 @@ CPed::ReactToPointGun(CEntity *entWithGun)
}
}
+// --MIAMI: Done
void
CPed::ReactToAttack(CEntity *attacker)
{
@@ -2140,9 +2254,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_KO_SHOT_FRONT1 + 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
@@ -2154,12 +2272,9 @@ CPed::ReactToAttack(CEntity *attacker)
m_pMyVehicle->AutoPilot.m_nCruiseSpeed = GAME_SPEED_TO_CARAI_SPEED * m_pMyVehicle->pHandling->Transmission.fUnkMaxVelocity;
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) {
@@ -2168,33 +2283,41 @@ 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);
}
}
}
}
+// --MIAMI: Done
void
CPed::PedAnimAlignCB(CAnimBlendAssociation *animAssoc, void *arg)
{
@@ -2208,24 +2331,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_vehEnterType) {
+ 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_vehEnterType) {
case CAR_DOOR_RF:
@@ -2246,37 +2370,134 @@ CPed::PedAnimAlignCB(CAnimBlendAssociation *animAssoc, void *arg)
break;
}
+ if (veh->IsBike()) {
+ CPed *pedToDragOut = nil;
+ if (veh->GetStatus() == STATUS_ABANDONED) {
+ if (ped->m_vehEnterType == 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_BIKE_PICKUP_R);
+ else
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_BIKE_PULLUP_R);
+
+ } else {
+ if (veh->GetRight().z < 0.0f)
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_BIKE_PICKUP_L);
+ else
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_BIKE_PULLUP_L);
+ }
+ 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_R : ANIM_BIKE_JUMPON_L);
+ ped->m_pVehicleAnim->SetFinishCallback(PedAnimGetInCB, ped);
+ ((CBike*)veh)->bIsBeingPickedUp = true;
+ }
+ } else if (ped->m_vehEnterType == 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_vehEnterType == CAR_DOOR_LF || ped->m_vehEnterType == CAR_DOOR_LR ? ANIM_KO_SPIN_L : ANIM_KO_SPIN_R, 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_BIKE_ELBOW_R : ANIM_BIKE_ELBOW_L);
+ 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_R : ANIM_BIKE_JUMPON_L);
+ 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_vehEnterType == CAR_DOOR_LF || ped->m_vehEnterType == CAR_DOOR_LR ? ANIM_KO_SPIN_L : ANIM_KO_SPIN_R, 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_BIKE_ELBOW_R : ANIM_BIKE_ELBOW_L);
+ 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_R : ANIM_BIKE_JUMPON_L);
+ ped->m_pVehicleAnim->SetFinishCallback(PedAnimGetInCB, ped);
+ ((CBike*)veh)->bIsBeingPickedUp = true;
+ }
+ }
+ }
+
+ if (pedToDragOut) {
+ pedToDragOut->SetBeingDraggedFromCar(veh, ped->m_vehEnterType, 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_VAN_GETIN;
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_VAN, ANIM_VAN_GETIN);
} else if (itsBus) {
- enterAnim = ANIM_COACH_IN_R;
-#ifdef FIX_BUGS
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_COACH, ANIM_COACH_IN_R);
} else if (itsLow) {
- enterAnim = ANIM_CAR_GETIN_LOW_RHS;
-#endif
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_GETIN_LOW_RHS);
} else {
- enterAnim = ANIM_CAR_GETIN_RHS;
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_GETIN_RHS);
}
} else if (itsVan) {
- enterAnim = ANIM_VAN_GETIN_L;
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_VAN, ANIM_VAN_GETIN_L);
} else if (itsBus) {
- enterAnim = ANIM_COACH_IN_L;
-#ifdef FIX_BUGS
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_COACH, ANIM_COACH_IN_L);
} else if (itsLow) {
- enterAnim = ANIM_CAR_GETIN_LOW_LHS;
-#endif
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_GETIN_LOW_LHS);
} else {
- enterAnim = ANIM_CAR_GETIN_LHS;
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_GETIN_LHS);
}
- ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, enterAnim);
ped->m_pVehicleAnim->SetFinishCallback(PedAnimGetInCB, ped);
} else if (veh->CanPedOpenLocks(ped)) {
@@ -2284,16 +2505,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_VAN_OPEN);
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_VAN, ANIM_VAN_OPEN);
} else if (itsBus) {
- ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_COACH_OPEN_R);
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_COACH, ANIM_COACH_OPEN_R);
} else {
ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_OPEN_RHS);
}
} else if (itsVan) {
- ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_VAN_OPEN_L);
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_VAN, ANIM_VAN_OPEN_L);
} else if (itsBus) {
- ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_COACH_OPEN_L);
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_COACH, ANIM_COACH_OPEN_L);
} else {
if (ped->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER && veh->pDriver) {
@@ -2304,13 +2525,28 @@ CPed::PedAnimAlignCB(CAnimBlendAssociation *animAssoc, void *arg)
ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_QJACK);
ped->m_pVehicleAnim->SetFinishCallback(PedAnimGetInCB, ped);
- veh->pDriver->SetBeingDraggedFromCar(veh, ped->m_vehEnterType, 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_vehEnterType, 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_CAR_JUMPIN_LHS);
+ ped->m_pVehicleAnim->SetFinishCallback(PedAnimGetInCB, ped);
+ return;
+ }
ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_OPEN_LHS);
}
ped->m_pVehicleAnim->SetFinishCallback(PedAnimDoorOpenCB, ped);
@@ -2326,6 +2562,7 @@ CPed::PedAnimAlignCB(CAnimBlendAssociation *animAssoc, void *arg)
}
}
+// --MIAMI: Done
void
CPed::PedAnimDoorOpenCB(CAnimBlendAssociation* animAssoc, void* arg)
{
@@ -2340,9 +2577,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;
@@ -2351,10 +2586,26 @@ CPed::PedAnimDoorOpenCB(CAnimBlendAssociation* animAssoc, void* arg)
eDoors door;
CPed *pedInSeat = nil;
switch (ped->m_vehEnterType) {
- 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);
}
@@ -2389,7 +2640,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_vehEnterType != CAR_DOOR_LF && ped->m_vehEnterType != CAR_DOOR_LR)
ped->SetFall(1000, ANIM_KO_SPIN_R, false);
@@ -2404,28 +2656,36 @@ CPed::PedAnimDoorOpenCB(CAnimBlendAssociation* animAssoc, void* arg)
isVan = false;
if (ped->m_nPedState != PED_CARJACK || isBus) {
- AnimationId animToPlay;
- if (ped->m_vehEnterType != CAR_DOOR_LF && ped->m_vehEnterType != CAR_DOOR_LR) {
- if (isVan) {
- animToPlay = ANIM_VAN_GETIN;
+ if (ped->m_vehEnterType == CAR_DOOR_LF || ped->m_vehEnterType == CAR_DOOR_LR) {
+ if (veh->IsBike()) {
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ((CBike*)veh)->m_bikeAnimType, ANIM_BIKE_JUMPON_R);
+ } else if (isVan) {
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_VAN, ANIM_VAN_GETIN_L);
} else if (isBus) {
- animToPlay = ANIM_COACH_IN_R;
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_COACH, ANIM_COACH_IN_L);
} else if (isLow) {
- animToPlay = ANIM_CAR_GETIN_LOW_RHS;
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_GETIN_LOW_LHS);
} else {
- animToPlay = ANIM_CAR_GETIN_RHS;
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_GETIN_LHS);
}
- } else if (isVan) {
- animToPlay = ANIM_VAN_GETIN_L;
- } else if (isBus) {
- animToPlay = ANIM_COACH_IN_L;
- } else if (isLow) {
- animToPlay = ANIM_CAR_GETIN_LOW_LHS;
} else {
- animToPlay = ANIM_CAR_GETIN_LHS;
+ if (veh->IsBike()) {
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ((CBike*)veh)->m_bikeAnimType, ANIM_BIKE_JUMPON_L);
+ } else if (isVan) {
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_VAN, ANIM_VAN_GETIN);
+ } else if (isBus) {
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_COACH, ANIM_COACH_IN_R);
+ } else if (isLow) {
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_GETIN_LOW_RHS);
+ } else {
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_GETIN_RHS);
+ }
+
+ if (ped->m_vehEnterType == 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;
@@ -2444,6 +2704,7 @@ CPed::PedAnimDoorOpenCB(CAnimBlendAssociation* animAssoc, void* arg)
}
if (ped->m_vehEnterType != CAR_DOOR_LF && ped->m_vehEnterType != CAR_DOOR_LR) {
+
if (pedToDragOut && !pedToDragOut->bDontDragMeOutCar) {
if (pedToDragOut->m_nPedState != PED_DRIVING) {
ped->QuitEnteringCar();
@@ -2460,58 +2721,68 @@ 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_CAR_GETIN_LOW_LHS);
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_GETIN_LOW_RHS);
else
- ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_GETIN_LHS);
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_GETIN_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_CAR_PULLOUT_LOW_LHS);
- else
- ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_PULLOUT_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_CAR_GETIN_LOW_LHS);
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_PULLOUT_LOW_LHS);
else
- ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_GETIN_LHS);
-
- ped->m_pVehicleAnim->SetFinishCallback(PedAnimGetInCB, ped);
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_PULLOUT_LHS);
+
+ ped->m_pVehicleAnim->SetFinishCallback(PedAnimPullPedOutCB, ped);
}
+ } else {
+ if (isLow)
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_GETIN_LOW_LHS);
+ else
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_GETIN_LHS);
+
+ ped->m_pVehicleAnim->SetFinishCallback(PedAnimGetInCB, ped);
}
if (pedToDragOut) {
- pedToDragOut->SetBeingDraggedFromCar(veh, ped->m_vehEnterType, 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_vehEnterType, false);
+ if (pedToDragOut->IsGangMember())
+ pedToDragOut->RegisterThreatWithGangPeds(ped);
+ }
+ }
}
return;
}
+// --MIAMI: Done
void
CPed::PedAnimPullPedOutCB(CAnimBlendAssociation* animAssoc, void* arg)
{
@@ -2573,27 +2844,31 @@ CPed::PedAnimPullPedOutCB(CAnimBlendAssociation* animAssoc, void* arg)
}
if (ped->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER) {
- AnimationId animToPlay;
- if (ped->m_vehEnterType != CAR_DOOR_LF && ped->m_vehEnterType != CAR_DOOR_LR) {
- if (isLow)
- animToPlay = ANIM_CAR_GETIN_LOW_RHS;
+ if (ped->m_vehEnterType == CAR_DOOR_LF || ped->m_vehEnterType == CAR_DOOR_LR) {
+ if (veh->IsBike())
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ((CBike*)veh)->m_bikeAnimType, ANIM_BIKE_JUMPON_R);
+ else if (isLow)
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_GETIN_LOW_LHS);
else
- animToPlay = ANIM_CAR_GETIN_RHS;
- } else if (isLow) {
- animToPlay = ANIM_CAR_GETIN_LOW_LHS;
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_GETIN_LHS);
} else {
- animToPlay = ANIM_CAR_GETIN_LHS;
+ if (veh->IsBike())
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ((CBike*)veh)->m_bikeAnimType, ANIM_BIKE_JUMPON_L);
+ else if (isLow)
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_GETIN_LOW_RHS);
+ else
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_GETIN_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();
}
}
+// --MIAMI: Done
void
CPed::PedAnimGetInCB(CAnimBlendAssociation *animAssoc, void *arg)
{
@@ -2607,13 +2882,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;
@@ -2629,13 +2903,19 @@ CPed::PedAnimGetInCB(CAnimBlendAssociation *animAssoc, void *arg)
}
if (ped->IsPlayer() && ped->m_vehEnterType == CAR_DOOR_LF
&& (Pads[0].GetAccelerate() >= 255.0f || Pads[0].GetBrake() >= 255.0f)
- && veh->IsCar()) {
+ && veh->IsCar() && !veh->pDriver) {
+
+ if (!animAssoc || animAssoc->animId != ANIM_CAR_JUMPIN_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;
@@ -2658,10 +2938,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) {
@@ -2702,38 +2987,54 @@ 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_VAN_CLOSE;
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_VAN, ANIM_VAN_CLOSE);
} else if (isLow) {
- animToPlay = ANIM_CAR_CLOSEDOOR_LOW_RHS;
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_CLOSEDOOR_LOW_RHS);
} else {
- animToPlay = ANIM_CAR_CLOSEDOOR_RHS;
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_CLOSEDOOR_RHS);
}
} else if (isVan) {
- animToPlay = ANIM_VAN_CLOSE_L;
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_VAN, ANIM_VAN_CLOSE_L);
} else if (isLow) {
- animToPlay = ANIM_CAR_CLOSEDOOR_LOW_LHS;
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_CLOSEDOOR_LOW_LHS);
} else {
- animToPlay = ANIM_CAR_CLOSEDOOR_LHS;
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_CLOSEDOOR_LHS);
}
- ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, animToPlay);
ped->m_pVehicleAnim->SetFinishCallback(PedAnimDoorCloseCB, ped);
}
}
+// --MIAMI: Done
+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_CAR_LSHUFFLE_RHS : ANIM_CAR_SHUFFLE_RHS);
+ m_objective = OBJECTIVE_ENTER_CAR_AS_DRIVER;
+ m_pMyVehicle->RemovePassenger(this);
+ bInVehicle = false;
+ m_pVehicleAnim->SetFinishCallback(PedSetInCarCB, this);
+ }
+ }
+}
+
+// --MIAMI: Done
void
CPed::PedAnimDoorCloseCB(CAnimBlendAssociation *animAssoc, void *arg)
{
@@ -2762,22 +3063,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_vehEnterType == 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;
@@ -2801,14 +3096,24 @@ 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();
}
}
+// --MIAMI: Done
+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();
+ }
+}
+
+// --MIAMI: Done
void
CPed::SetFormation(eFormation type)
{
@@ -2832,9 +3137,13 @@ CPed::SetFormation(eFormation type)
m_pedFormation = type;
}
+// --MIAMI: Done
CVector
CPed::GetFormationPosition(void)
{
+ if (!m_pedInObjective)
+ return GetPosition();
+
if (m_pedInObjective->m_nPedState == PED_DEAD) {
if (!m_pedInObjective->m_pedInObjective) {
m_pedInObjective = nil;
@@ -2844,59 +3153,67 @@ 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;
}
+// --MIAMI: Done
void
CPed::PedAnimStepOutCarCB(CAnimBlendAssociation* animAssoc, void* arg)
{
CPed* ped = (CPed*)arg;
CVehicle* veh = ped->m_pMyVehicle;
- if (animAssoc)
+ if (animAssoc) {
+ if ((animAssoc->animId == ANIM_CAR_ROLLOUT_LHS || animAssoc->animId == ANIM_CAR_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);
@@ -2964,10 +3281,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) {
@@ -3011,6 +3326,7 @@ CPed::PedAnimStepOutCarCB(CAnimBlendAssociation* animAssoc, void* arg)
return;
}
+// --MIAMI: Done
void
CPed::LineUpPedWithCar(PedLineUpPhase phase)
{
@@ -3019,28 +3335,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_CAR_SIT)) {
- SetPedPositionInCar();
- return;
- }
- if (RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_LSIT)) {
- SetPedPositionInCar();
- return;
+ if (m_pMyVehicle->IsBike()) {
+ if (RpAnimBlendClumpGetAssociation(GetClump(), ANIM_BIKE_RIDE) ||
+ RpAnimBlendClumpGetAssociation(GetClump(), ANIM_BIKE_PASSENGER)) {
+ SetPedPositionInCar();
+ return;
+ }
+ } else {
+ if (RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_SIT)) {
+ SetPedPositionInCar();
+ return;
+ }
+ if (RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_LSIT)) {
+ SetPedPositionInCar();
+ return;
+ }
+ if (RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_SITP)) {
+ SetPedPositionInCar();
+ return;
+ }
+ if (RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_SITPLO)) {
+ SetPedPositionInCar();
+ return;
+ }
}
- if (RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_SITP)) {
- SetPedPositionInCar();
- return;
+ bChangedSeat = true;
+ }
+ if (phase == LINE_UP_TO_CAR_FALL) {
+ SetPedPositionInCar();
+ autoZPos = GetPosition();
+ CPedPlacement::FindZCoorForPed(&autoZPos);
+ if (m_pVehicleAnim && (m_pVehicleAnim->animId == ANIM_CAR_ROLLOUT_LHS || m_pVehicleAnim->animId == ANIM_CAR_ROLLOUT_RHS)
+ && autoZPos.z > GetPosition().z) {
+ m_matrix.GetPosition().z = autoZPos.z;
}
- if (RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_SITPLO)) {
- 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);
@@ -3074,19 +3420,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_vehEnterType == 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;
@@ -3097,38 +3440,38 @@ CPed::LineUpPedWithCar(PedLineUpPhase phase)
case ANIM_CAR_LJACKED_LHS:
case ANIM_VAN_GETIN_L:
case ANIM_VAN_GETIN:
-#ifdef VC_PED_PORTS
multExtractedFromAnim = true;
- zBlend = Max(m_pVehicleAnim->currentTime / m_pVehicleAnim->hierarchy->totalLength - 0.3f, 0.0f) / (1.0f - 0.3f);
+ zBlend = Max(m_pVehicleAnim->GetProgress() - 0.3f, 0.0f) / (1.0f - 0.3f);
// fall through
-#endif
+
case ANIM_CAR_QJACKED:
case ANIM_CAR_GETOUT_LHS:
case ANIM_CAR_GETOUT_LOW_LHS:
case ANIM_CAR_GETOUT_RHS:
case ANIM_CAR_GETOUT_LOW_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_CAR_CRAWLOUT_RHS:
case ANIM_CAR_CRAWLOUT_RHS2:
case ANIM_VAN_GETOUT_L:
case ANIM_VAN_GETOUT:
- seatPosMult = m_pVehicleAnim->currentTime / m_pVehicleAnim->hierarchy->totalLength;
+ case ANIM_BIKE_GETOFF_RHS:
+ case ANIM_BIKE_GETOFF_LHS:
+ seatPosMult = m_pVehicleAnim->GetProgress();
break;
case ANIM_CAR_GETIN_RHS:
case ANIM_CAR_GETIN_LHS:
-#ifdef VC_PED_PORTS
if (veh && veh->IsCar() && veh->bIsBus) {
multExtractedFromAnimBus = true;
- zBlend = Min(m_pVehicleAnim->currentTime / m_pVehicleAnim->hierarchy->totalLength, 0.5f) / 0.5f;
+ zBlend = Min(m_pVehicleAnim->GetProgress(), 0.5f) / 0.5f;
}
// fall through
-#endif
+
case ANIM_CAR_QJACK:
case ANIM_CAR_GETIN_LOW_LHS:
case ANIM_CAR_GETIN_LOW_RHS:
@@ -3143,6 +3486,12 @@ CPed::LineUpPedWithCar(PedLineUpPhase phase)
case ANIM_CAR_LSHUFFLE_RHS:
seatPosMult = 0.0f;
break;
+ case ANIM_CAR_JUMPIN_LHS:
+ {
+ float animLength = m_pVehicleAnim->hierarchy->totalLength;
+ seatPosMult = Max(0.0f, 0.5f * animLength - m_pVehicleAnim->currentTime) / animLength;
+ break;
+ }
case ANIM_CAR_CLOSE_LHS:
case ANIM_CAR_CLOSE_RHS:
case ANIM_COACH_OPEN_L:
@@ -3153,8 +3502,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;
@@ -3165,7 +3531,7 @@ CPed::LineUpPedWithCar(PedLineUpPhase phase)
neededPos = GetPositionToOpenCarDoor(veh, m_vehEnterType, seatPosMult);
}
- CVector autoZPos = neededPos;
+ autoZPos = neededPos;
if (veh->bIsInWater) {
if (veh->m_vehType == VEHICLE_TYPE_BOAT && veh->IsUpsideDown())
@@ -3195,11 +3561,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_RHS && vehAnim != ANIM_BIKE_GETOFF_LHS) {
+ if (vehAnim != ANIM_BIKE_JUMPON_R && vehAnim != ANIM_BIKE_JUMPON_L) {
+ 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_VAN_GETIN_L && vehAnim != ANIM_VAN_CLOSE_L && vehAnim != ANIM_VAN_CLOSE && vehAnim != ANIM_VAN_GETIN) {
neededPos.z = autoZPos.z;
@@ -3210,20 +3589,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_CAR_GETIN_RHS || vehAnim == ANIM_CAR_GETIN_LOW_RHS || vehAnim == ANIM_CAR_GETIN_LHS || vehAnim == ANIM_CAR_GETIN_LOW_LHS
|| vehAnim == ANIM_CAR_QJACK || vehAnim == ANIM_VAN_GETIN_L || vehAnim == ANIM_VAN_GETIN)) {
@@ -3231,12 +3606,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
}
}
}
@@ -3267,18 +3640,30 @@ 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_vehEnterType, 0.0f));
- // VC couch anims are inverted, so they're fixing it here.
+
+ if (m_vehEnterType == CAR_WINDSCREEN || veh->bIsBus) {
+ CMatrix correctionMat;
+ if (veh->bIsBus && (m_vehEnterType == CAR_DOOR_LF || m_vehEnterType == CAR_DOOR_LR))
+ correctionMat.SetRotateZ(-HALFPI);
+ else if (veh->bIsBus && (m_vehEnterType == CAR_DOOR_RF || m_vehEnterType == CAR_DOOR_RR))
+ correctionMat.SetRotateZ(HALFPI);
+ else
+ correctionMat.SetRotateZ(PI);
+
+ vehDoorMat = vehDoorMat * correctionMat;
+ }
GetMatrix() = vehDoorMat;
}
}
+// --MIAMI: Done
void
CPed::SetCarJack(CVehicle* car)
{
@@ -3289,41 +3674,71 @@ CPed::SetCarJack(CVehicle* car)
if (car->IsBoat())
return;
- switch (m_vehEnterType) {
- case CAR_DOOR_RF:
- doorFlag = CAR_DOOR_FLAG_RF;
- door = DOOR_FRONT_RIGHT;
- if (car->pPassengers[0]) {
+ if (car->IsBike()) {
+ switch (m_vehEnterType) {
+ 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_vehEnterType) {
+ 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)))
@@ -3331,10 +3746,10 @@ CPed::SetCarJack(CVehicle* car)
SetCarJack_AllClear(car, m_vehEnterType, doorFlag);
}
+// --MIAMI: Done
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();
@@ -3346,24 +3761,35 @@ 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_vehEnterType);
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_vehEnterType == CAR_DOOR_LF || m_vehEnterType == CAR_DOOR_LR)
- m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, zDiff > 4.4f ? ANIM_CAR_ALIGNHI_LHS : ANIM_CAR_ALIGN_LHS, 4.0f);
- else
- m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, zDiff > 4.4f ? ANIM_CAR_ALIGNHI_RHS : ANIM_CAR_ALIGN_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_vehEnterType == CAR_DOOR_LF || m_vehEnterType == CAR_DOOR_LR)
+ m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, zDiff > 4.4f ? ANIM_CAR_ALIGNHI_LHS : ANIM_CAR_ALIGN_LHS, 4.0f);
+ else
+ m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, zDiff > 4.4f ? ANIM_CAR_ALIGNHI_RHS : ANIM_CAR_ALIGN_RHS, 4.0f);
- m_pVehicleAnim->SetFinishCallback(PedAnimAlignCB, this);
+ m_pVehicleAnim->SetFinishCallback(PedAnimAlignCB, this);
+ }
}
+// --MIAMI: Done
void
CPed::SetBeingDraggedFromCar(CVehicle *veh, uint32 vehEnterType, bool quickJack)
{
@@ -3376,7 +3802,17 @@ CPed::SetBeingDraggedFromCar(CVehicle *veh, uint32 vehEnterType, bool quickJack)
SetMoveState(PEDMOVE_STILL);
m_pSeekTarget = veh;
m_pSeekTarget->RegisterReference((CEntity **) &m_pSeekTarget);
- m_vehEnterType = vehEnterType;
+
+ if (veh->IsBike()) {
+ ((CBike*)veh)->bIsBeingPickedUp = true;
+ if (veh->pPassengers[0] != this && (vehEnterType != CAR_WINDSCREEN || veh->pPassengers[0]))
+ m_vehEnterType = CAR_DOOR_LF;
+ else
+ m_vehEnterType = CAR_DOOR_LR;
+ } else {
+ m_vehEnterType = vehEnterType;
+ }
+
if (m_vehEnterType == CAR_DOOR_LF) {
if (veh->pDriver && veh->pDriver->IsPlayer())
veh->SetStatus(STATUS_PLAYER_DISABLED);
@@ -3385,7 +3821,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;
@@ -3395,70 +3831,80 @@ CPed::SetBeingDraggedFromCar(CVehicle *veh, uint32 vehEnterType, bool quickJack)
Say(SOUND_PED_CAR_JACKED);
SetRadioStation();
- veh->m_nGettingOutFlags |= GetCarDoorFlag(m_vehEnterType);
+
+ if(veh->IsBike())
+ veh->m_nGettingOutFlags |= GetBikeDoorFlagInclJumpInFromFront(m_vehEnterType);
+ else
+ veh->m_nGettingOutFlags |= GetCarDoorFlag(m_vehEnterType);
}
+// --MIAMI: Done
void
CPed::BeingDraggedFromCar(void)
{
- CAnimBlendAssociation *animAssoc;
AnimationId enterAnim;
bool dontRunAnim = false;
- PedLineUpPhase lineUpType;
if (!m_pVehicleAnim) {
- CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_IDLE_STANCE, 100.0f);
- animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_SIT);
- if (!animAssoc) {
- animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_LSIT);
- if (!animAssoc) {
- animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_SITP);
- if (!animAssoc)
- animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_SITPLO);
- }
- }
- if (animAssoc)
- animAssoc->blendDelta = -1000.0f;
-
- if (m_vehEnterType == CAR_DOOR_LF || m_vehEnterType == CAR_DOOR_LR) {
- if (bWillBeQuickJacked) {
- enterAnim = ANIM_CAR_QJACKED;
- } else if (m_pMyVehicle->bLowVehicle) {
- enterAnim = ANIM_CAR_LJACKED_LHS;
- } else {
- enterAnim = ANIM_CAR_JACKED_LHS;
- }
- } else if (m_vehEnterType == CAR_DOOR_RF || m_vehEnterType == CAR_DOOR_RR) {
- if (m_pMyVehicle->bLowVehicle)
- enterAnim = ANIM_CAR_LJACKED_RHS;
- else
- enterAnim = ANIM_CAR_JACKED_RHS;
- } else
- dontRunAnim = true;
+ CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_IDLE_STANCE, 1000.0f);
+
+ AssocGroupId assocGroup;
+ if (m_pMyVehicle && m_pMyVehicle->IsBike()) {
+ enterAnim = ANIM_BIKE_HIT;
+ assocGroup = ((CBike*)m_pMyVehicle)->m_bikeAnimType;
+ } else {
+ if (m_vehEnterType == CAR_DOOR_LF || m_vehEnterType == CAR_DOOR_LR) {
+ if (bWillBeQuickJacked && m_vehEnterType == CAR_DOOR_LF) {
+ enterAnim = ANIM_CAR_QJACKED;
+ } else if (m_pMyVehicle->bLowVehicle) {
+ enterAnim = ANIM_CAR_LJACKED_LHS;
+ } else {
+ enterAnim = ANIM_CAR_JACKED_LHS;
+ }
+ } else if (m_vehEnterType == CAR_DOOR_RF || m_vehEnterType == CAR_DOOR_RR) {
+ if (m_pMyVehicle->bLowVehicle)
+ enterAnim = ANIM_CAR_LJACKED_RHS;
+ else
+ enterAnim = ANIM_CAR_JACKED_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_vehEnterType, NUM_ANIMS, m_pVehicleAnim->currentTime * 5.0f);
+ m_pMyVehicle->ProcessOpenDoor(m_vehEnterType, NUM_STD_ANIMS, m_pVehicleAnim->currentTime * mult);
}
}
-#endif
}
+// --MIAMI: Done
void
CPed::SetEnterCar(CVehicle *car, uint32 unused)
{
@@ -3468,26 +3914,62 @@ CPed::SetEnterCar(CVehicle *car, uint32 unused)
} else {
uint8 doorFlag;
eDoors door;
- switch (m_vehEnterType) {
- 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_vehEnterType) {
+ 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_vehEnterType) {
+ 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
@@ -3499,11 +3981,11 @@ CPed::SetEnterCar(CVehicle *car, uint32 unused)
}
}
+// --MIAMI: Done
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)
@@ -3513,7 +3995,7 @@ CPed::SetEnterCar_AllClear(CVehicle *car, uint32 doorNode, uint32 doorFlag)
m_pSeekTarget->RegisterReference((CEntity **) &m_pSeekTarget);
m_vehEnterType = doorNode;
SetPedState(PED_ENTER_CAR);
- if (m_vehEnterType == CAR_DOOR_RF && m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER && car->m_vehType != VEHICLE_TYPE_BIKE) {
+ if (m_vehEnterType == CAR_DOOR_RF && m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER && !car->IsBike()) {
car->bIsBeingCarJacked = true;
}
@@ -3529,51 +4011,35 @@ CPed::SetEnterCar_AllClear(CVehicle *car, uint32 doorNode, uint32 doorFlag)
m_vecOffsetSeek = doorOpenPos - GetPosition();
m_nPedStateTimer = CTimer::GetTimeInMilliseconds() + 600;
+
if (car->IsBoat()) {
-#ifdef VC_PED_PORTS
- // VC checks for handling flag, but we can't do that
- if(car->GetModelIndex() == MI_SPEEDER)
+ if (car->pHandling->Flags & HANDLING_SIT_IN_BOAT)
m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_SIT, 100.0f);
else
m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_DRIVE_BOAT, 100.0f);
PedSetInCarCB(nil, this);
bVehExitWillBeInstant = true;
-#else
-#ifndef FIX_BUGS
- m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_DRIVE_BOAT, 100.0f);
-#else
- m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, car->GetDriverAnim(), 100.0f);
-#endif
+ } 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_vehEnterType == CAR_DOOR_RF || m_vehEnterType == CAR_DOOR_RR)
- m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_ALIGNHI_RHS, 4.0f);
- else
- m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_ALIGNHI_LHS, 4.0f);
-
- } else {
- if (m_vehEnterType == CAR_DOOR_RF || m_vehEnterType == CAR_DOOR_RR)
- m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_ALIGN_RHS, 4.0f);
- else
- m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_ALIGN_LHS, 4.0f);
- }
+ if (m_vehEnterType == CAR_DOOR_LF || m_vehEnterType == CAR_DOOR_LR)
+ m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, zDiff > 4.4f ? ANIM_CAR_ALIGNHI_RHS : ANIM_CAR_ALIGN_RHS, 4.0f);
+ else
+ m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, zDiff > 4.4f ? ANIM_CAR_ALIGNHI_LHS : ANIM_CAR_ALIGN_LHS, 4.0f);
m_pVehicleAnim->SetFinishCallback(PedAnimAlignCB, this);
- car->AutoPilot.m_nCruiseSpeed = 0;
}
}
+// --MIAMI: Done
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_vehEnterType);
@@ -3585,12 +4051,34 @@ 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_BIKE_PICKUP_R || anim == ANIM_BIKE_PICKUP_L) && m_pVehicleAnim->currentTime > 0.4667f)
+ bike->bIsBeingPickedUp = true;
+ else if ((anim == ANIM_BIKE_PULLUP_R || anim == ANIM_BIKE_PULLUP_L) && 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_BIKE_ELBOW_R || anim == ANIM_BIKE_ELBOW_L) {
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_186, 3.0f);
+ }
+ }
+ }
+ }
} else {
QuitEnteringCar();
- SetDie(ANIM_KO_SHOT_FRONT1, 4.0f, 0.0f);
+ SetDie();
}
}
+// --MIAMI: Done
void
CPed::QuitEnteringCar(void)
{
@@ -3610,18 +4098,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_vehEnterType);
+ if (veh->IsBike()) {
+ veh->m_nGettingInFlags &= ~GetBikeDoorFlag(m_vehEnterType);
+ ((CBike*)veh)->bIsBeingPickedUp = false;
+ } else
+ veh->m_nGettingInFlags &= ~GetEnterCarDoorFlag(m_vehEnterType, veh->m_nNumMaxPassengers);
}
bUsesCollision = true;
- ReplaceWeaponWhenExitingVehicle();
-
if (DyingOrDead()) {
if (m_pVehicleAnim) {
m_pVehicleAnim->blendDelta = -4.0f;
@@ -3634,66 +4122,15 @@ 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.
+// --MIAMI: Done
void
CPed::SetExitBoat(CVehicle *boat)
{
-#ifndef VC_PED_PORTS
- SetPedState(PED_IDLE);
- CVector firstPos = GetPosition();
- CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_IDLE_STANCE, 100.0f);
- if (boat->GetModelIndex() == MI_SPEEDER && boat->IsUpsideDown()) {
- m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_CRAWLOUT_RHS, 8.0f);
- m_pVehicleAnim->SetFinishCallback(PedSetOutCarCB, this);
- m_vehEnterType = CAR_DOOR_RF;
- SetPedState(PED_EXIT_CAR);
- } else {
- m_vehEnterType = 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();
@@ -3709,49 +4146,46 @@ 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_vehEnterType = 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_vehEnterType = 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_vehEnterType = 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_vehEnterType = 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();
}
+// --MIAMI: Done
// wantedDoorNode = 0 means that func. will determine it
void
CPed::SetExitCar(CVehicle *veh, uint32 wantedDoorNode)
@@ -3759,12 +4193,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)
@@ -3774,107 +4222,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)
@@ -3903,9 +4408,20 @@ CPed::SetExitCar(CVehicle *veh, uint32 wantedDoorNode)
if (!IsPlayer() && CharCreatedBy != MISSION_CHAR)
return;
+ // needed for PositionPedOutOfCollision()
+ optedDoorNode = firstOptedDoor;
+ m_vehEnterType = firstOptedDoor;
+ PositionPedOutOfCollision();
teleportNeeded = true;
}
}
+
+ if (!teleportNeeded && veh->IsOnItsSide()) {
+ m_vehEnterType = optedDoorNode;
+ PositionPedOutOfCollision();
+ teleportNeeded = true;
+ }
+
if (m_nPedState == PED_FLEE_POS) {
m_nLastPedState = PED_FLEE_POS;
m_nPrevMoveState = PEDMOVE_RUN;
@@ -3916,7 +4432,6 @@ CPed::SetExitCar(CVehicle *veh, uint32 wantedDoorNode)
SetMoveState(PEDMOVE_STILL);
}
- ReplaceWeaponWhenExitingVehicle();
bUsesCollision = false;
m_pSeekTarget = veh;
m_pSeekTarget->RegisterReference((CEntity**) &m_pSeekTarget);
@@ -3924,61 +4439,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_IDLE_STANCE, 100.0f);
- RemoveInCarAnims();
veh->AutoPilot.m_nCruiseSpeed = 0;
+
if (teleportNeeded) {
PedSetOutCarCB(nil, this);
+ } else {
+ if (veh->GetUp().z <= -0.8f && !veh->IsBike()) {
+ if (m_vehEnterType == CAR_DOOR_RF || m_vehEnterType == CAR_DOOR_RR) {
+ m_pVehicleAnim = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_CRAWLOUT_RHS2);
+ } else if (m_vehEnterType == CAR_DOOR_LF || m_vehEnterType == CAR_DOOR_LR) {
+ m_pVehicleAnim = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_CRAWLOUT_RHS);
+ }
+ 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_vehEnterType) {
+ 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_LHS);
+ break;
+ case CAR_DOOR_LF:
+ case CAR_DOOR_LR:
+ m_pVehicleAnim = CAnimManager::AddAnimation(GetClump(), bike->m_bikeAnimType, ANIM_BIKE_GETOFF_RHS);
+ 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_vehEnterType) {
+ 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_vehEnterType == CAR_BUMP_REAR || m_vehEnterType == 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_vehEnterType) {
case CAR_DOOR_RF:
- if (veh->bIsBus) {
- m_pVehicleAnim = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_COACH_OUT_L);
+ if (canJumpOut) {
+ m_pVehicleAnim = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_ROLLOUT_RHS);
+ } else if (veh->bIsBus) {
+ m_pVehicleAnim = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_COACH, ANIM_COACH_OUT_L);
} else {
if (isLow)
m_pVehicleAnim = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_GETOUT_LOW_RHS);
else
m_pVehicleAnim = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_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_VAN_GETOUT);
+ if (canJumpOut) {
+ m_pVehicleAnim = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_ROLLOUT_RHS);
+ } else if (veh->bIsVan) {
+ m_pVehicleAnim = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_VAN, ANIM_VAN_GETOUT);
} else if (isLow) {
m_pVehicleAnim = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_GETOUT_LOW_RHS);
} else {
@@ -3986,21 +4525,22 @@ CPed::SetExitCar(CVehicle *veh, uint32 wantedDoorNode)
}
break;
case CAR_DOOR_LF:
- if (veh->bIsBus) {
- m_pVehicleAnim = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_COACH_OUT_L);
+ if (canJumpOut) {
+ m_pVehicleAnim = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_ROLLOUT_LHS);
+ } else if (veh->bIsBus) {
+ m_pVehicleAnim = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_COACH, ANIM_COACH_OUT_L);
} else {
if (isLow)
m_pVehicleAnim = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_GETOUT_LOW_LHS);
else
m_pVehicleAnim = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_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_VAN_GETOUT_L);
+ if (canJumpOut) {
+ m_pVehicleAnim = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_ROLLOUT_LHS);
+ } else if (veh->bIsVan) {
+ m_pVehicleAnim = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_VAN, ANIM_VAN_GETOUT_L);
} else if (isLow) {
m_pVehicleAnim = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_GETOUT_LOW_LHS);
} else {
@@ -4010,32 +4550,10 @@ CPed::SetExitCar(CVehicle *veh, uint32 wantedDoorNode)
default:
break;
}
- if (!bBusJacked) {
- switch (m_vehEnterType) {
- 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_vehEnterType == CAR_DOOR_RF || m_vehEnterType == CAR_DOOR_RR) {
- m_pVehicleAnim = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_CRAWLOUT_RHS2);
- } else if (m_vehEnterType == CAR_DOOR_LF || m_vehEnterType == CAR_DOOR_LR) {
- m_pVehicleAnim = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_CRAWLOUT_RHS);
+ if (!bBusJacked && !canJumpOut) {
+ veh->m_nGettingOutFlags |= GetCarDoorFlag(m_vehEnterType);
}
- m_pVehicleAnim->SetFinishCallback(PedSetOutCarCB, this);
+ m_pVehicleAnim->SetFinishCallback(canJumpOut ? RestoreHeadingRateCB : PedAnimStepOutCarCB, this);
}
}
bChangedSeat = false;
@@ -4052,81 +4570,120 @@ CPed::SetExitCar(CVehicle *veh, uint32 wantedDoorNode)
}
}
+// --MIAMI: Done
void
CPed::ExitCar(void)
{
- if (!m_pVehicleAnim)
+ if (!m_pVehicleAnim) {
+ if (InVehicle()) {
+ if (m_pMyVehicle->IsBike()) {
+ if (m_vehEnterType == CAR_BOOT || m_vehEnterType == CAR_BUMP_REAR) {
+ ((CBike*)m_pMyVehicle)->KnockOffRider(WEAPONTYPE_UNARMED, 0, this, false);
+ }
+ } else if (m_pMyVehicle->IsCar()) {
+ if (RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_ROLLOUT_LHS)) {
+ ((CAutomobile*)m_pMyVehicle)->KnockPedOutCar(WEAPONTYPE_UNIDENTIFIED, CAR_DOOR_LF, this);
+ } else if (RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_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_vehEnterType, 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_CAR_CLOSE_RHS || exitAnim == ANIM_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_CAR_ROLLOUT_LHS || exitAnim == ANIM_CAR_ROLLOUT_RHS) {
+ if (animTime > 0.07f && m_pMyVehicle && m_pMyVehicle->IsCar()) {
+ if (exitAnim == ANIM_CAR_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_vehEnterType, 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_CAR_CLOSE_RHS || exitAnim == ANIM_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 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_KO_SKID_FRONT, 1);
}
- if (foundPed && animTime > 0.4f && foundPed->IsPedInControl())
- foundPed->SetFall(1000, ANIM_KO_SKID_FRONT, 1);
}
}
-// This function was mostly duplicate of GetLocalPositionToOpenCarDoor, so I've used it.
+// --MIAMI: Done
CVector
CPed::GetPositionToOpenCarDoor(CVehicle *veh, uint32 component)
{
- CVector localPos;
- CVector vehDoorPos;
-
- localPos = GetLocalPositionToOpenCarDoor(veh, component, 1.0f);
- vehDoorPos = Multiply3x3(veh->GetMatrix(), localPos) + veh->GetPosition();
+ CVector vehDoorPos = GetPositionToOpenCarDoor(veh, component, 1.0f);
/*
- // Not used.
- CVector localVehDoorOffset;
-
- if (veh->bIsVan && (component == VEHICLE_ENTER_REAR_LEFT || component == VEHICLE_ENTER_REAR_RIGHT)) {
- localVehDoorOffset = vecPedVanRearDoorAnimOffset;
- } else {
- if (veh->bIsLow) {
- localVehDoorOffset = vecPedCarDoorLoAnimOffset;
- } else {
- localVehDoorOffset = vecPedCarDoorAnimOffset;
- }
- }
-
- vehDoorPosWithoutOffset = Multiply3x3(veh->GetMatrix(), localPos + localVehDoorOffset) + veh->GetPosition();
+ // Unused
+ vehDoorPosWithoutOffset = veh->GetMatrix() * localVehDoorPos;
*/
return vehDoorPos;
}
+// --MIAMI: Done
void
CPed::GetNearestDoor(CVehicle *veh, CVector &posToOpen)
{
CVector *enterOffset = nil;
- if (m_vehEnterType == CAR_DOOR_LF && veh->pDriver
- || m_vehEnterType == CAR_DOOR_RF && veh->pPassengers[0]
- || m_vehEnterType == CAR_DOOR_LR && veh->pPassengers[1]
- || m_vehEnterType == 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_vehEnterType ||
+ !IsPlayer() && m_nPedType != PEDTYPE_COP && m_nMoveState == PEDMOVE_RUN
+ && m_pedStats->m_temper > 65
+ && !m_vehEnterType || m_vehEnterType == CAR_WINDSCREEN)) {
+ m_vehEnterType = CAR_WINDSCREEN;
+ posToOpen = GetPositionToOpenCarDoor(veh, CAR_WINDSCREEN);
+ return;
+ }
+ }
+ }
+ } else if (m_vehEnterType == CAR_DOOR_LF && veh->pDriver && !veh->bLowVehicle && !veh->bIsBus) {
enterOffset = &vecPedQuickDraggedOutCarAnimOffset;
}
@@ -4148,7 +4705,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)) {
@@ -4166,6 +4724,7 @@ CPed::GetNearestDoor(CVehicle *veh, CVector &posToOpen)
}
}
+// --MIAMI: Done
bool
CPed::GetNearestPassengerDoor(CVehicle *veh, CVector &posToOpen)
{
@@ -4188,7 +4747,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)) {
@@ -4196,6 +4770,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)
@@ -4233,6 +4808,7 @@ CPed::GetNearestPassengerDoor(CVehicle *veh, CVector &posToOpen)
return canEnter;
}
+// --MIAMI: Done
void
CPed::GoToNearestDoor(CVehicle *veh)
{
@@ -4242,10 +4818,42 @@ CPed::GoToNearestDoor(CVehicle *veh)
SetMoveState(PEDMOVE_RUN);
}
+// --MIAMI: Done
+// 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_vehEnterType == CAR_DOOR_RR || pPed->m_vehEnterType == 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);
+}
+
+// --MIAMI: Done
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_CAR_JACKED_LHS)->hierarchy;
CAnimBlendSequence *seq = enterAssoc->sequences;
@@ -4295,7 +4903,7 @@ CPed::SetAnimOffsetForEnterOrExitVehicle(void)
}
}
- enterAssoc = CAnimManager::GetAnimAssociation(ASSOCGRP_STD, ANIM_VAN_GETIN_L)->hierarchy;
+ enterAssoc = CAnimManager::GetAnimAssociation(ASSOCGRP_VAN, ANIM_VAN_GETIN_L)->hierarchy;
seq = enterAssoc->sequences;
CAnimManager::UncompressAnimation(enterAssoc);
if (seq->numFrames > 0) {
@@ -4306,8 +4914,8 @@ CPed::SetAnimOffsetForEnterOrExitVehicle(void)
vecPedVanRearDoorAnimOffset = lastFrame->translation;
}
}
-
- enterAssoc = CAnimManager::GetAnimAssociation(ASSOCGRP_STD, ANIM_TRAIN_GETOUT)->hierarchy;
+ // I think this is leftover and ANIM_TRAIN_GETOUT
+ enterAssoc = CAnimManager::GetAnimAssociation(ASSOCGRP_STD, ANIM_IDLE_STANCE3)->hierarchy;
seq = enterAssoc->sequences;
CAnimManager::UncompressAnimation(enterAssoc);
if (seq->numFrames > 0) {
@@ -4318,8 +4926,75 @@ CPed::SetAnimOffsetForEnterOrExitVehicle(void)
vecPedTrainDoorAnimOffset = lastFrame->translation;
}
}
+
+ enterAssoc = CAnimManager::GetAnimAssociation(ASSOCGRP_BIKE_STANDARD, ANIM_BIKE_JUMPON_R)->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_R)->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_R)->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_R)->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);
}
+// --MIAMI: Done
void
CPed::PedSetQuickDraggedOutCarPositionCB(CAnimBlendAssociation *animAssoc, void *arg)
{
@@ -4386,21 +5061,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) {
@@ -4415,6 +5083,7 @@ CPed::PedSetQuickDraggedOutCarPositionCB(CAnimBlendAssociation *animAssoc, void
ped->m_nLastPedState = PED_WANDER_PATH;
}
+// --MIAMI: Done
void
CPed::PedSetDraggedOutCarPositionCB(CAnimBlendAssociation* animAssoc, void* arg)
{
@@ -4422,22 +5091,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 = vecPedDraggedOutCarAnimOffset;
+ }
if (ped->m_vehEnterType == CAR_DOOR_RF || ped->m_vehEnterType == 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_vehEnterType, &vecPedDraggedOutCarAnimOffset)) {
+ if (ped->m_pMyVehicle && !ped->m_pMyVehicle->IsBike() && !ped->m_pMyVehicle->IsRoomForPedToLeaveCar(ped->m_vehEnterType, &vecPedDraggedOutCarAnimOffset)) {
ped->PositionPedOutOfCollision();
}
@@ -4481,31 +5166,21 @@ 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();
}
+// --MIAMI: Done
uint8
CPed::GetNearestTrainDoor(CVehicle *train, CVector &doorPos)
{
@@ -4523,6 +5198,7 @@ CPed::GetNearestTrainDoor(CVehicle *train, CVector &doorPos)
return 1;
}
+// --MIAMI: Done
uint8
CPed::GetNearestTrainPedPosition(CVehicle *train, CVector &enterPos)
{
@@ -4581,6 +5257,7 @@ CPed::GetNearestTrainPedPosition(CVehicle *train, CVector &enterPos)
return 1;
}
+// --MIAMI: Done :D
void
CPed::PedSetInTrainCB(CAnimBlendAssociation* animAssoc, void* arg)
{
@@ -4597,6 +5274,7 @@ CPed::PedSetInTrainCB(CAnimBlendAssociation* animAssoc, void* arg)
veh->AddPassenger(ped);
}
+#ifdef GTA_TRAIN
void
CPed::SetEnterTrain(CVehicle *train, uint32 unused)
{
@@ -4727,29 +5405,34 @@ CPed::PedSetOutTrainCB(CAnimBlendAssociation *animAssoc, void *arg)
ped->SetHeading(ped->m_fRotationCur);
veh->RemovePassenger(ped);
}
+#endif
+// --MIAMI: Done
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);
}
}
@@ -4758,10 +5441,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;
@@ -4772,7 +5455,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.fUnkMaxVelocity * 0.8f;
@@ -4788,6 +5471,7 @@ CPed::RegisterThreatWithGangPeds(CEntity *attacker)
}
}
+// --MIAMI: Done
// Some helper function which doesn't exist in og game.
inline void
SelectClosestNodeForSeek(CPed *ped, CPathNode *node, CVector2D closeDist, CVector2D farDist, CPathNode *closeNode, CPathNode *closeNode2, int runCount = 3)
@@ -4802,12 +5486,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;
}
}
@@ -4817,13 +5501,14 @@ SelectClosestNodeForSeek(CPed *ped, CPathNode *node, CVector2D closeDist, CVecto
}
}
+// --MIAMI: Done
bool
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);
@@ -4842,12 +5527,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;
@@ -4856,6 +5542,7 @@ CPed::FindBestCoordsFromNodes(CVector unused, CVector *bestCoords)
return false;
}
+// --MIAMI: Done
bool
CPed::DuckAndCover(void)
{
@@ -4873,9 +5560,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);
@@ -4884,25 +5573,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;
@@ -4943,25 +5677,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;
}
}
@@ -4969,8 +5703,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;
@@ -4987,20 +5726,60 @@ CPed::DuckAndCover(void)
}
m_leaveCarTimer = CTimer::GetTimeInMilliseconds() + CGeneral::GetRandomNumberInRange(3000, 6000);
+ bCrouchWhenShooting = true;
+ SetDuck(CGeneral::GetRandomNumberInRange(2000, 5000), true);
return false;
}
+// --MIAMI: Done
CVector
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) {
+ return bike->GetMatrix() * (doorPos + 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;
+ }
+ 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;
}
+// --MIAMI: Done
CVector
CPed::GetLocalPositionToOpenCarDoor(CVehicle *veh, uint32 component, float seatPosMult)
{
@@ -5010,61 +5789,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;
}
+// --MIAMI: Done, but what is this parameter for?
void
-CPed::SetDuck(uint32 time)
+CPed::SetDuck(uint32 time, bool sth)
{
- if (bIsDucking || CTimer::GetTimeInMilliseconds() <= m_duckTimer)
+ 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_DUCK_LOW);
- if (!duckAssoc || duckAssoc->blendDelta < 0.0f) {
- CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_DUCK_LOW, 4.0f);
- bIsDucking = true;
- m_duckTimer = CTimer::GetTimeInMilliseconds() + time;
- }
+ CAnimBlendAssociation *duckAssoc;
+ if (bCrouchWhenShooting) {
+ duckAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_WEAPON_CROUCH, 4.0f);
+ duckAssoc->flags &= ~ASSOC_FADEOUTWHENDONE;
+ bIsDucking = true;
+ m_duckTimer = CTimer::GetTimeInMilliseconds() + time;
} else {
CAnimBlendAssociation *duckAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DUCK_DOWN);
if (!duckAssoc || duckAssoc->blendDelta < 0.0f) {
@@ -5075,38 +5891,53 @@ CPed::SetDuck(uint32 time)
}
}
+// --MIAMI: Done
void
CPed::Duck(void)
{
if (CTimer::GetTimeInMilliseconds() > m_duckTimer)
ClearDuck();
+ else if (bIsDucking && bCrouchWhenShooting) {
+ CWeaponInfo *weapon = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType);
+ CAnimBlendAssociation *attackAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_CROUCH);
+ if (!attackAssoc) {
+ if(GetCrouchFireAnim(weapon))
+ attackAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetCrouchFireAnim(weapon));
+ }
+ if (!attackAssoc) {
+ if(GetCrouchReloadAnim(weapon))
+ attackAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetCrouchReloadAnim(weapon));
+ }
+ if (!attackAssoc) {
+ bIsDucking = false;
+ }
+ }
}
+// --MIAMI: Done
void
-CPed::ClearDuck(void)
+CPed::ClearDuck(bool clearTimer)
{
CAnimBlendAssociation *animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DUCK_DOWN);
if (!animAssoc) {
animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DUCK_LOW);
-
- if (!animAssoc) {
- bIsDucking = false;
- return;
- }
+ }
+ if (!animAssoc) {
+ animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_CROUCH);
}
- 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_RBLOCK_CSHOOT);
- if (!animAssoc || animAssoc->blendDelta < 0.0f) {
- CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_RBLOCK_CSHOOT, 4.0f);
+ if (clearTimer) {
+ m_duckTimer = 0;
}
}
+// --MIAMI: Done
void
CPed::InformMyGangOfAttack(CEntity *attacker)
{
@@ -5133,8 +5964,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);
}
@@ -5142,6 +5972,7 @@ CPed::InformMyGangOfAttack(CEntity *attacker)
}
}
+// --MIAMI: Done
void
CPed::PedAnimDoorCloseRollingCB(CAnimBlendAssociation* animAssoc, void* arg)
{
@@ -5164,14 +5995,11 @@ CPed::PedAnimDoorCloseRollingCB(CAnimBlendAssociation* animAssoc, void* arg)
veh->Damage.SetDoorStatus(DOOR_FRONT_LEFT, DOOR_STATUS_OK);
}
+// --MIAMI: Done
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();
@@ -5183,6 +6011,7 @@ CPed::SetSeekBoatPosition(CVehicle *boat)
SetPedState(PED_SEEK_IN_BOAT);
}
+// --MIAMI: Done
void
CPed::SeekBoatPosition(void)
{
@@ -5204,6 +6033,7 @@ CPed::SeekBoatPosition(void)
RestorePreviousState();
}
+// --MIAMI: Done
bool
CPed::IsRoomToBeCarJacked(void)
{
@@ -5211,7 +6041,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;
@@ -5225,56 +6057,226 @@ CPed::IsRoomToBeCarJacked(void)
return false;
}
+// --MIAMI: Done
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_CAR_SIT, 100.0f);
+ } else {
+ m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_DRIVE_BOAT, 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_PASSENGER, 100.0f);
+ }
+ } else {
+ if (isDriver) {
+ if (car->bLowVehicle) {
+ m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_LSIT, 100.0f);
+ } else {
+ m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_SIT, 100.0f);
+ }
+ } else {
+ if (car->bLowVehicle) {
+ m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_SITPLO, 100.0f);
+ } else {
+ m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_SITP, 100.0f);
+ }
+ }
+ }
+ StopNonPartialAnims();
+}
+
+// --MIAMI: Done
+void
+CPed::RemoveDrivebyAnims()
+{
CAnimBlendAssociation *animAssoc;
- if (m_pMyVehicle && m_pMyVehicle->bLowVehicle) {
- animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DRIVE_LOW_L);
- if (animAssoc)
- animAssoc->blendDelta = -1000.0f;
- animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DRIVE_LOW_R);
- if (animAssoc)
- animAssoc->blendDelta = -1000.0f;
- animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DRIVEBY_L);
- if (animAssoc)
- animAssoc->blendDelta = -1000.0f;
- animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DRIVEBY_R);
- if (animAssoc)
- animAssoc->blendDelta = -1000.0f;
- } else {
- animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DRIVE_L);
- if (animAssoc)
- animAssoc->blendDelta = -1000.0f;
- animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DRIVE_R);
- if (animAssoc)
- animAssoc->blendDelta = -1000.0f;
- animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DRIVEBY_L);
- if (animAssoc)
- animAssoc->blendDelta = -1000.0f;
- animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DRIVEBY_R);
- if (animAssoc)
- animAssoc->blendDelta = -1000.0f;
- }
-
-#ifdef VC_PED_PORTS
- animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DRIVE_BOAT);
+ AnimationId LeftAnim = ANIM_DRIVEBY_L;
+ AnimationId RightAnim = ANIM_DRIVEBY_R;
+
+ if (m_pMyVehicle->pHandling->Flags & HANDLING_IS_BIKE) {
+ LeftAnim = ANIM_BIKE_DRIVEBY_LHS;
+ RightAnim = ANIM_BIKE_DRIVEBY_RHS;
+ } else if (m_pMyVehicle->bLowVehicle) {
+ LeftAnim = ANIM_DRIVEBY_LOW_L;
+ RightAnim = ANIM_DRIVEBY_LOW_R;
+ }
+
+ animAssoc = RpAnimBlendClumpGetAssociation((RpClump*)m_rwObject, ANIM_BIKE_DRIVEBY_LHS);
if (animAssoc)
animAssoc->blendDelta = -1000.0f;
-#endif
-
- animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_LB);
+ animAssoc = RpAnimBlendClumpGetAssociation((RpClump*)m_rwObject, ANIM_BIKE_DRIVEBY_RHS);
+ if (animAssoc)
+ animAssoc->blendDelta = -1000.0f;
+ animAssoc = RpAnimBlendClumpGetAssociation((RpClump*)m_rwObject, ANIM_BIKE_DRIVEBY_FT);
if (animAssoc)
animAssoc->blendDelta = -1000.0f;
}
+// --MIAMI: Done
+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;
+ }
+}
+
+// --MIAMI: Done
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_vehEnterType != 0) {
+ // Try the normal way
+ CVector pos = GetPositionToOpenCarDoor(m_pMyVehicle, m_vehEnterType);
+ 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_vehEnterType == CAR_DOOR_RF || m_vehEnterType == 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;
+}
+
+// --MIAMI: Done
+// "Any" means he shouldn't have to be in vehicle.
+bool
+CPed::PositionAnyPedOutOfCollision(void)
+{
CVehicle *veh;
CVector posNearVeh;
CVector posSomewhereClose;
@@ -5283,9 +6285,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;
@@ -5296,15 +6295,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) {
@@ -5338,6 +6329,7 @@ CPed::PositionPedOutOfCollision(void)
return true;
}
+// --MIAMI: Done
bool
CPed::WarpPedToNearLeaderOffScreen(void)
{
@@ -5351,27 +6343,27 @@ 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, &TheCamera.GetCameraMatrix())
- && 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;
}
+// --MIAMI: Done
bool
CPed::WarpPedToNearEntityOffScreen(CEntity *warpTo)
{
@@ -5385,23 +6377,559 @@ 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, &TheCamera.GetCameraMatrix())
- && 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, &TheCamera.GetCameraMatrix())
+ && 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
+}
+
+// --MIAMI: Done
+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_vehEnterType = 0;
+ if (m_pedInObjective == vehOfTarget->pDriver || vehOfTarget->bIsBus) {
+ m_vehEnterType = CAR_DOOR_LF;
+ } else if (m_pedInObjective == vehOfTarget->pPassengers[0]) {
+ m_vehEnterType = CAR_DOOR_RF;
+ } else if (m_pedInObjective == vehOfTarget->pPassengers[1]) {
+ m_vehEnterType = CAR_DOOR_LR;
+ } else if (m_pedInObjective == vehOfTarget->pPassengers[2]) {
+ m_vehEnterType = CAR_DOOR_RR;
+ }
+ // Unused
+ // GetPositionToOpenCarDoor(vehOfTarget, m_vehEnterType);
+ SetSeekCar(vehOfTarget, m_vehEnterType);
+ 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_DUCK_DOWN);
+ if (!duckAnim)
+ duckAnim = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DUCK_LOW);
+ if (!duckAnim)
+ duckAnim = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_CROUCH);
+
+ 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;
+}
+
+// --MIAMI: Done
+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_vehEnterType = 0;
+ if (m_pedInObjective == vehOfTarget->pDriver || vehOfTarget->bIsBus) {
+ m_vehEnterType = CAR_DOOR_LF;
+ } else if (m_pedInObjective == vehOfTarget->pPassengers[0]) {
+ m_vehEnterType = CAR_DOOR_RF;
+ } else if (m_pedInObjective == vehOfTarget->pPassengers[1]) {
+ m_vehEnterType = CAR_DOOR_LR;
+ } else if (m_pedInObjective == vehOfTarget->pPassengers[2]) {
+ m_vehEnterType = CAR_DOOR_RR;
+ }
+ // Unused
+ // GetPositionToOpenCarDoor(vehOfTarget, m_vehEnterType);
+ SetSeekCar(vehOfTarget, m_vehEnterType);
+ 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_FIGHT_SH_BACK, 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_DUCK_DOWN);
+ if (!duckAnim)
+ duckAnim = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DUCK_LOW);
+ if (!duckAnim)
+ duckAnim = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_CROUCH);
+
+ 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;
+ }
+}
+
+// --MIAMI: Done
+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..05e72ed3
--- /dev/null
+++ b/src/peds/PedAttractor.cpp
@@ -0,0 +1,785 @@
+#include "common.h"
+#include "PedAttractor.h"
+
+#include "General.h"
+#include "Vehicle.h"
+#include "World.h"
+
+const int gcMaxSizeOfAtmQueue = 1;
+const int gcMaxSizeOfSeatQueue = 1;
+const int gcMaxSizeOfStopQueue = 5;
+const int gcMaxSizeOfPizzaQueue = 5;
+const int gcMaxSizeOfShelterQueue = 5;
+const int gcMaxSizeOfIceCreamQueue = 1;
+
+//--MIAMI: file done
+
+std::vector<CVector> CPedShelterAttractor::ms_displacements;
+
+CPedAttractorManager* GetPedAttractorManager()
+{
+ static CPedAttractorManager manager;
+ return &manager;
+}
+
+CVehicleToEffect::CVehicleToEffect(CVehicle* pVehicle) : m_pVehicle(pVehicle)
+{
+ m_effects[1].col = CRGBA(0, 0, 0, 0);
+ m_effects[1].type = EFFECT_PED_ATTRACTOR;
+ m_effects[1].pos = CVector(2.0f, 1.0f, 0.0f);
+ m_effects[1].pedattr.useDir = CVector(-1.0f, 0.0f, 0.0f);
+ m_effects[1].pedattr.queueDir = CVector(-1.0f, 0.0f, 0.0f);
+ m_effects[1].pedattr.type = ATTRACTOR_ICECREAM;
+
+ m_effects[3].col = CRGBA(0, 0, 0, 0);
+ m_effects[3].type = EFFECT_PED_ATTRACTOR;
+ m_effects[3].pos = CVector(2.0f, -0.5f, 0.0f);
+ m_effects[3].pedattr.useDir = CVector(-1.0f, 0.0f, 0.0f);
+ m_effects[3].pedattr.queueDir = CVector(-1.0f, 0.0f, 0.0f);
+ m_effects[3].pedattr.type = ATTRACTOR_ICECREAM;
+
+ m_effects[0].col = CRGBA(0, 0, 0, 0);
+ m_effects[0].type = EFFECT_PED_ATTRACTOR;
+ m_effects[0].pos = CVector(-2.0f, 1.0f, 0.0f);
+ m_effects[0].pedattr.useDir = CVector(1.0f, 0.0f, 0.0f);
+ m_effects[0].pedattr.queueDir = CVector(1.0f, 0.0f, 0.0f);
+ m_effects[0].pedattr.type = ATTRACTOR_ICECREAM;
+
+ m_effects[2].col = CRGBA(0, 0, 0, 0);
+ m_effects[2].type = EFFECT_PED_ATTRACTOR;
+ m_effects[2].pos = CVector(-2.0f, -0.5f, 0.0f);
+ m_effects[2].pedattr.useDir = CVector(1.0f, 0.0f, 0.0f);
+ m_effects[2].pedattr.queueDir = CVector(1.0f, 0.0f, 0.0f);
+ m_effects[2].pedattr.type = ATTRACTOR_ICECREAM;
+}
+
+CVehicleToEffect& CVehicleToEffect::From(const CVehicleToEffect& other)
+{
+ m_pVehicle = other.m_pVehicle;
+ for (int i = 0; i < NUM_ATTRACTORS_FOR_ICECREAM_VAN; i++) {
+ m_effects[i].col = other.m_effects[i].col;
+ m_effects[i].type = other.m_effects[i].type;
+ m_effects[i].pos = other.m_effects[i].pos;
+ m_effects[i].pedattr = other.m_effects[i].pedattr;
+ }
+ return *this;
+}
+
+const C2dEffect* CVehicleToEffect::ChooseEffect(const CVector& pos) const
+{
+ if (!m_pVehicle)
+ return nil;
+ if (DotProduct(pos - m_pVehicle->GetPosition(), m_pVehicle->GetRight()) > 0.0f) {
+ if (DotProduct(pos - m_pVehicle->GetPosition(), m_pVehicle->GetForward()) > 0.0f)
+ return &m_effects[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.cbegin(); assoc != vVehicleToEffect.cend(); ++assoc) {
+ if (assoc->GetVehicle() == pVehicle)
+ return assoc->ChooseEffect(pos);
+ }
+ }
+ CVehicleToEffect effect(pVehicle);
+ vVehicleToEffect.push_back(effect);
+ return effect.ChooseEffect(pos);
+}
+
+CVehicle* CPedAttractorManager::GetIceCreamVanForEffect(C2dEffect* pEffect)
+{
+ if (vVehicleToEffect.empty())
+ return nil;
+ for (std::vector<CVehicleToEffect>::const_iterator assoc = vVehicleToEffect.cbegin(); assoc != vVehicleToEffect.cend(); ++assoc) {
+ if (assoc->HasThisEffect(pEffect))
+ return assoc->GetVehicle();
+ }
+ return nil;
+}
+
+const CPedAttractor* CPedAttractorManager::FindAssociatedAttractor(const C2dEffect* pEffect, std::vector<CPedAttractor*>& vecAttractors)
+{
+ if (vecAttractors.empty())
+ return nil;
+ for (std::vector<CPedAttractor*>::const_iterator attractor = vecAttractors.cbegin(); attractor != vecAttractors.cend(); ++attractor) {
+ if ((*attractor)->GetEffect() == pEffect)
+ return *attractor;
+ }
+ return nil;
+}
+
+void CPedAttractorManager::RemoveIceCreamVanEffects(C2dEffect* pEffect)
+{
+ CVehicle* pVehicle = GetIceCreamVanForEffect(pEffect);
+ if (!pVehicle)
+ return;
+ if (vVehicleToEffect.empty())
+ return;
+ for (std::vector<CVehicleToEffect>::const_iterator assoc = vVehicleToEffect.cbegin(); assoc != vVehicleToEffect.cend();) {
+ 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.cbegin(); v != ms_displacements.cend(); ++v) {
+ if ((*v - vecDisplacement).Magnitude() < 1.0f) {
+ close = true;
+ break;
+ }
+ }
+ if (!close) {
+ ms_displacements.push_back(vecDisplacement);
+ i++;
+ }
+ }
+ }
+ return ms_displacements[qid];
+}
+
+void CPedShelterAttractor::ComputeAttractPos(int32 qid, CVector& pos) const
+{
+ if (!p2dEffect)
+ return;
+ pos = vecEffectPos + GetDisplacement(qid);
+}
+
+void CPedAttractor::ComputeAttractHeading(int32 qid, float& heading) const
+{
+ heading = CGeneral::GetRadianAngleBetweenPoints(qid != 0 ? vecQueueDir.x : vecUseDir.x, qid != 0 ? vecQueueDir.y : vecUseDir.y, 0.0f, 0.0f);
+ if (qid != 0)
+ heading += ComputeDeltaHeading();
+}
+
+void CPedShelterAttractor::ComputeAttractHeading(int32 qid, float& heading) const
+{
+ heading = CGeneral::GetRandomNumberInRange(0.0f, TWOPI);
+}
+
+bool CPedAttractor::RegisterPed(CPed* pPed)
+{
+ for (std::vector<CPed*>::const_iterator pPedIt = vApproachingQueue.cbegin(); pPedIt != vApproachingQueue.cend(); ++pPedIt) {
+ if (*pPedIt == pPed) {
+ vApproachingQueue.erase(pPedIt);
+ return false;
+ }
+ }
+ if (GetNoOfRegisteredPeds() >= m_nMaxPedsInAttractor)
+ return 0;
+ vApproachingQueue.push_back(pPed);
+ CVector pos;
+ float heading;
+ float time;
+ int32 slot = ComputeFreeSlot();
+ ComputeAttractPos(slot, pos);
+ ComputeAttractHeading(slot, heading);
+ ComputeAttractTime(slot, false, time);
+ pPed->SetNewAttraction(this, pos, heading, time, slot);
+ return true;
+}
+
+static bool IsPedUsingAttractorOfThisType(int8 type, CPed* pPed)
+{
+ switch (type) {
+ case ATTRACTOR_ATM:
+ if (pPed->m_objective == OBJECTIVE_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*>::const_iterator pPedIt = vApproachingQueue.cbegin(); pPedIt != vApproachingQueue.cend(); ++pPedIt) {
+ if (*pPedIt != pPed)
+ continue;
+ pPed->m_attractor = nil;
+ pPed->m_positionInQueue = -1;
+ pPed->bHasAlreadyUsedAttractor = true;
+
+ if (IsPedUsingAttractorOfThisType(p2dEffect->pedattr.type, pPed))
+ pPed->SetObjective(OBJECTIVE_NONE);
+ else if (pPed->GetPedState() != PED_IDLE && pPed->GetPedState() != PED_NONE) {
+ vApproachingQueue.erase(pPedIt);
+ return true;
+ }
+ pPed->SetWanderPath(CGeneral::GetNodeHeadingFromVector(-vecQueueDir.x, -vecQueueDir.y));
+ vApproachingQueue.erase(pPedIt);
+ return true;
+ }
+ return BroadcastDeparture(pPed);
+}
+
+bool CPedAttractor::BroadcastArrival(CPed* pPed)
+{
+ for (std::vector<CPed*>::const_iterator pPedIt = vWaitingQueue.cbegin(); pPedIt != vWaitingQueue.cend(); ++pPedIt) {
+ if (*pPedIt == pPed)
+ return false;
+ }
+ vWaitingQueue.push_back(pPed);
+ for (std::vector<CPed*>::const_iterator pPedIt = vApproachingQueue.cbegin(); pPedIt != vApproachingQueue.cend(); ++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.cbegin() + 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.cbegin() + 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.cbegin(); pPedIt != vWaitingQueue.cend(); ++pPedIt) {
+ if (*pPedIt == pPed)
+ return true;
+ }
+ for (std::vector<CPed*>::const_iterator pPedIt = vApproachingQueue.cbegin(); pPedIt != vApproachingQueue.cend(); ++pPedIt) {
+ if (*pPedIt == pPed) {
+ return true;
+ }
+ }
+ return false;
+}
+
+bool CPedAttractor::IsInQueue(CPed* pPed) const
+{
+ for (std::vector<CPed*>::const_iterator pPedIt = vWaitingQueue.cbegin(); pPedIt != vWaitingQueue.cend(); ++pPedIt) {
+ if (*pPedIt == pPed)
+ return true;
+ }
+ return false;
+}
+
+CPedAttractor* CPedAttractorManager::RegisterPedWithAttractor(CPed* pPed, C2dEffect* pEffect, const CMatrix& matrix)
+{
+ if (pEffect->type != EFFECT_PED_ATTRACTOR)
+ return nil;
+ if (IsPedRegisteredWithEffect(pPed))
+ return nil;
+ switch (pEffect->pedattr.type) {
+ case ATTRACTOR_ATM: return RegisterPed(pPed, pEffect, matrix, vAtmAttractors);
+ case ATTRACTOR_SEAT: return RegisterPed(pPed, pEffect, matrix, vSeatAttractors);
+ case ATTRACTOR_STOP: return RegisterPed(pPed, pEffect, matrix, vStopAttractors);
+ case ATTRACTOR_PIZZA: return RegisterPed(pPed, pEffect, matrix, vPizzaAttractors);
+ case ATTRACTOR_SHELTER: return RegisterPed(pPed, pEffect, matrix, vShelterAttractors);
+ case ATTRACTOR_ICECREAM: return RegisterPed(pPed, pEffect, matrix, vIceCreamAttractors);
+ }
+ return nil;
+}
+
+bool CPedAttractorManager::DeRegisterPed(CPed* pPed, CPedAttractor* pAttractor)
+{
+ if (!pAttractor)
+ return false;
+ if (pAttractor->GetEffect()->type != EFFECT_PED_ATTRACTOR)
+ return nil;
+ if (!IsPedRegisteredWithEffect(pPed))
+ return nil;
+ switch (pAttractor->GetEffect()->pedattr.type) {
+ case ATTRACTOR_ATM: return DeRegisterPed(pPed, pAttractor, vAtmAttractors);
+ case ATTRACTOR_SEAT: return DeRegisterPed(pPed, pAttractor, vSeatAttractors);
+ case ATTRACTOR_STOP: return DeRegisterPed(pPed, pAttractor, vStopAttractors);
+ case ATTRACTOR_PIZZA: return DeRegisterPed(pPed, pAttractor, vPizzaAttractors);
+ case ATTRACTOR_SHELTER: return DeRegisterPed(pPed, pAttractor, vShelterAttractors);
+ case ATTRACTOR_ICECREAM: return DeRegisterPed(pPed, pAttractor, vIceCreamAttractors);
+ }
+ return nil;
+}
+
+bool CPedAttractorManager::BroadcastArrival(CPed* pPed, CPedAttractor* pAttractor)
+{
+ if (!pAttractor)
+ return false;
+ if (pAttractor->GetEffect()->type != EFFECT_PED_ATTRACTOR)
+ return nil;
+ if (!IsPedRegisteredWithEffect(pPed))
+ return nil;
+ switch (pAttractor->GetEffect()->pedattr.type) {
+ case ATTRACTOR_ATM: return BroadcastArrival(pPed, pAttractor, vAtmAttractors);
+ case ATTRACTOR_SEAT: return BroadcastArrival(pPed, pAttractor, vSeatAttractors);
+ case ATTRACTOR_STOP: return BroadcastArrival(pPed, pAttractor, vStopAttractors);
+ case ATTRACTOR_PIZZA: return BroadcastArrival(pPed, pAttractor, vPizzaAttractors);
+ case ATTRACTOR_SHELTER: return BroadcastArrival(pPed, pAttractor, vShelterAttractors);
+ case ATTRACTOR_ICECREAM: return BroadcastArrival(pPed, pAttractor, vIceCreamAttractors);
+ }
+ return nil;
+}
+
+bool CPedAttractorManager::BroadcastDeparture(CPed* pPed, CPedAttractor* pAttractor)
+{
+ if (!pAttractor)
+ return false;
+ if (pAttractor->GetEffect()->type != EFFECT_PED_ATTRACTOR)
+ return nil;
+ if (!IsPedRegisteredWithEffect(pPed))
+ return nil;
+ switch (pAttractor->GetEffect()->pedattr.type) {
+ case ATTRACTOR_ATM: return BroadcastDeparture(pPed, pAttractor, vAtmAttractors);
+ case ATTRACTOR_SEAT: return BroadcastDeparture(pPed, pAttractor, vSeatAttractors);
+ case ATTRACTOR_STOP: return BroadcastDeparture(pPed, pAttractor, vStopAttractors);
+ case ATTRACTOR_PIZZA: return BroadcastDeparture(pPed, pAttractor, vPizzaAttractors);
+ case ATTRACTOR_SHELTER: return BroadcastDeparture(pPed, pAttractor, vShelterAttractors);
+ case ATTRACTOR_ICECREAM: return BroadcastDeparture(pPed, pAttractor, vIceCreamAttractors);
+ }
+ return nil;
+}
+
+bool CPedAttractorManager::IsAtHeadOfQueue(CPed* pPed, CPedAttractor* pAttractor)
+{
+ if (!pAttractor)
+ return false;
+ if (pAttractor->GetEffect()->type != EFFECT_PED_ATTRACTOR)
+ return nil;
+ if (!IsPedRegisteredWithEffect(pPed))
+ return nil;
+ switch (pAttractor->GetEffect()->pedattr.type) {
+ case ATTRACTOR_ATM: return IsAtHeadOfQueue(pPed, pAttractor, vAtmAttractors);
+ case ATTRACTOR_SEAT: return IsAtHeadOfQueue(pPed, pAttractor, vSeatAttractors);
+ case ATTRACTOR_STOP: return IsAtHeadOfQueue(pPed, pAttractor, vStopAttractors);
+ case ATTRACTOR_PIZZA: return IsAtHeadOfQueue(pPed, pAttractor, vPizzaAttractors);
+ case ATTRACTOR_SHELTER: return IsAtHeadOfQueue(pPed, pAttractor, vShelterAttractors);
+ case ATTRACTOR_ICECREAM: return IsAtHeadOfQueue(pPed, pAttractor, vIceCreamAttractors);
+ }
+ return nil;
+}
+
+bool CPedAttractorManager::IsInQueue(CPed* pPed, CPedAttractor* pAttractor)
+{
+ if (!pAttractor)
+ return false;
+ if (pAttractor->GetEffect()->type != EFFECT_PED_ATTRACTOR)
+ return nil;
+ if (!IsPedRegisteredWithEffect(pPed))
+ return nil;
+ switch (pAttractor->GetEffect()->pedattr.type) {
+ case ATTRACTOR_ATM: return IsInQueue(pPed, pAttractor, vAtmAttractors);
+ case ATTRACTOR_SEAT: return IsInQueue(pPed, pAttractor, vSeatAttractors);
+ case ATTRACTOR_STOP: return IsInQueue(pPed, pAttractor, vStopAttractors);
+ case ATTRACTOR_PIZZA: return IsInQueue(pPed, pAttractor, vPizzaAttractors);
+ case ATTRACTOR_SHELTER: return IsInQueue(pPed, pAttractor, vShelterAttractors);
+ case ATTRACTOR_ICECREAM: return IsInQueue(pPed, pAttractor, vIceCreamAttractors);
+ }
+ return nil;
+}
+
+bool CPedAttractorManager::HasEmptySlot(const C2dEffect* pEffect)
+{
+ if (!pEffect)
+ return false;
+ if (pEffect->type != EFFECT_PED_ATTRACTOR)
+ return nil;
+ const CPedAttractor* pAttractor;
+ switch (pEffect->pedattr.type) {
+ case ATTRACTOR_ATM: pAttractor = FindAssociatedAttractor(pEffect, vAtmAttractors); break;
+ case ATTRACTOR_SEAT: pAttractor = FindAssociatedAttractor(pEffect, vSeatAttractors); break;
+ case ATTRACTOR_STOP: pAttractor = FindAssociatedAttractor(pEffect, vStopAttractors); break;
+ case ATTRACTOR_PIZZA: pAttractor = FindAssociatedAttractor(pEffect, vPizzaAttractors); break;
+ case ATTRACTOR_SHELTER: pAttractor = FindAssociatedAttractor(pEffect, vShelterAttractors); break;
+ case ATTRACTOR_ICECREAM: pAttractor = FindAssociatedAttractor(pEffect, vIceCreamAttractors); break;
+ default: return true;
+ }
+ if (!pAttractor)
+ return true;
+ return pAttractor->GetNoOfRegisteredPeds() < pAttractor->GetMaxPedsInAttractor();
+}
+
+bool CPedAttractorManager::IsPedRegisteredWithEffect(CPed* pPed)
+{
+ return IsPedRegistered(pPed, vAtmAttractors) ||
+ IsPedRegistered(pPed, vSeatAttractors) ||
+ IsPedRegistered(pPed, vStopAttractors) ||
+ IsPedRegistered(pPed, vPizzaAttractors) ||
+ IsPedRegistered(pPed, vShelterAttractors) ||
+ IsPedRegistered(pPed, vIceCreamAttractors);
+}
+
+void CPedAttractorManager::ComputeEffectPos(const C2dEffect* pEffect, const CMatrix& matrix, CVector& pos)
+{
+ pos = matrix.GetPosition() + Multiply3x3(matrix, pEffect->pos);
+}
+
+void CPedAttractorManager::ComputeEffectQueueDir(const C2dEffect* pEffect, const CMatrix& matrix, CVector& pos)
+{
+ pos = Multiply3x3(matrix, pEffect->pedattr.queueDir);
+}
+
+void CPedAttractorManager::ComputeEffectUseDir(const C2dEffect* pEffect, const CMatrix& matrix, CVector& pos)
+{
+ pos = Multiply3x3(matrix, pEffect->pedattr.useDir);
+}
+
+CPedAttractor* CPedAttractorManager::RegisterPed(CPed* pPed, C2dEffect* pEffect, const CMatrix& matrix, std::vector<CPedAttractor*>& vecAttractors)
+{
+ CPedAttractor* pRegisteredAttractor = nil;
+ for (std::vector<CPedAttractor*>::const_iterator pAttractorIt = vecAttractors.cbegin(); pAttractorIt != vecAttractors.cend(); ++pAttractorIt) {
+ CPedAttractor* pAttractor = *pAttractorIt;
+ CVector vEffectPos;
+ ComputeEffectPos(pAttractor->GetEffect(), matrix, vEffectPos);
+ if (pAttractor->GetEffect() == pEffect && vEffectPos == pAttractor->GetEffectPos()) {
+ if (!IsApproachable(pEffect, matrix, pAttractor->ComputeFreeSlot(), pPed))
+ return nil;
+ pRegisteredAttractor = pAttractor;
+ break;
+ }
+ }
+ if (pRegisteredAttractor || !IsApproachable(pEffect, matrix, 0, pPed)) {
+ if (pRegisteredAttractor)
+ pRegisteredAttractor->RegisterPed(pPed);
+ return pRegisteredAttractor;
+ }
+ switch (pEffect->pedattr.type) {
+ case ATTRACTOR_ATM: vecAttractors.push_back(new CPedAtmAttractor(pEffect, matrix, gcMaxSizeOfAtmQueue, 1.0f, 30000.0f, 3000.0f, 0.2f, 0.15f, 0.1f, 0.1f)); break;
+ case ATTRACTOR_SEAT: vecAttractors.push_back(new CPedSeatAttractor(pEffect, matrix, gcMaxSizeOfSeatQueue, 1.0f, 30000.0f, 3000.0f, 0.125f, 0.1f, 0.1f, 0.1f)); break;
+ case ATTRACTOR_STOP: vecAttractors.push_back(new CPedStopAttractor(pEffect, matrix, gcMaxSizeOfStopQueue, 1.0f, 30000.0f, 3000.0f, 0.2f, 0.1f, 0.1f, 0.1f)); break;
+ case ATTRACTOR_PIZZA: vecAttractors.push_back(new CPedPizzaAttractor(pEffect, matrix, gcMaxSizeOfPizzaQueue, 1.0f, 30000.0f, 3000.0f, 0.2f, 0.1f, 0.1f, 0.1f)); break;
+ case ATTRACTOR_SHELTER: vecAttractors.push_back(new CPedShelterAttractor(pEffect, matrix, gcMaxSizeOfShelterQueue, 1.0f, 30000.0f, 3000.0f, 0.5f, 6.28f, 0.1f, 0.1f)); break;
+ case ATTRACTOR_ICECREAM: vecAttractors.push_back(new CPedIceCreamAttractor(pEffect, matrix, gcMaxSizeOfIceCreamQueue, 1.0f, 30000.0f, 3000.0f, 0.2f, 0.3f, 0.1f, 0.1f)); break;
+ }
+ if (pRegisteredAttractor)
+ pRegisteredAttractor->RegisterPed(pPed);
+ return pRegisteredAttractor;
+}
+
+bool CPedAttractorManager::DeRegisterPed(CPed* pPed, CPedAttractor* pAttractor, std::vector<CPedAttractor*>& vecAttractors)
+{
+ if (!pAttractor)
+ return false;
+ CPedAttractor* pFound = nil;
+ for (std::vector<CPedAttractor*>::const_iterator pAttractorIt = vecAttractors.cbegin(); pAttractorIt != vecAttractors.cend(); ++pAttractorIt) {
+ if (*pAttractorIt == pAttractor) {
+ pFound = *pAttractorIt;
+ break;
+ }
+ }
+ if (!pFound)
+ return false;
+ pFound->DeRegisterPed(pPed);
+ if (pFound->GetNoOfRegisteredPeds() != 0)
+ return true;
+ for (std::vector<CPedAttractor*>::const_iterator pAttractorIt = vecAttractors.cbegin(); pAttractorIt != vecAttractors.cend(); ++pAttractorIt) {
+ if (*pAttractorIt == pAttractor) {
+ vecAttractors.erase(pAttractorIt);
+ break;
+ }
+ }
+ delete pAttractor;
+ return true;
+}
+
+bool CPedAttractorManager::BroadcastArrival(CPed* pPed, CPedAttractor* pAttractor, std::vector<CPedAttractor*>& vecAttractors)
+{
+ if (!pAttractor)
+ return false;
+ CPedAttractor* pFound = nil;
+ for (std::vector<CPedAttractor*>::const_iterator pAttractorIt = vecAttractors.cbegin(); pAttractorIt != vecAttractors.cend(); ++pAttractorIt) {
+ if (*pAttractorIt == pAttractor) {
+ pFound = *pAttractorIt;
+ break;
+ }
+ }
+ if (!pFound)
+ return false;
+ pFound->BroadcastArrival(pPed);
+ return true;
+}
+
+bool CPedAttractorManager::BroadcastDeparture(CPed* pPed, CPedAttractor* pAttractor, std::vector<CPedAttractor*>& vecAttractors)
+{
+ if (!pAttractor)
+ return false;
+ CPedAttractor* pFound = nil;
+ for (std::vector<CPedAttractor*>::const_iterator pAttractorIt = vecAttractors.cbegin(); pAttractorIt != vecAttractors.cend(); ++pAttractorIt) {
+ if (*pAttractorIt == pAttractor) {
+ pFound = *pAttractorIt;
+ break;
+ }
+ }
+ if (!pFound)
+ return false;
+ pFound->DeRegisterPed(pPed);
+ if (pFound->GetNoOfRegisteredPeds() != 0)
+ return true;
+ for (std::vector<CPedAttractor*>::const_iterator pAttractorIt = vecAttractors.cbegin(); pAttractorIt != vecAttractors.cend(); ++pAttractorIt) {
+ if (*pAttractorIt == pAttractor) {
+ vecAttractors.erase(pAttractorIt);
+ break;
+ }
+ }
+ delete pAttractor;
+ return true;
+}
+
+bool CPedAttractorManager::IsInQueue(CPed* pPed, CPedAttractor* pAttractor, std::vector<CPedAttractor*>& vecAttractors)
+{
+ if (!pAttractor)
+ return false;
+ for (std::vector<CPedAttractor*>::const_iterator pAttractorIt = vecAttractors.cbegin(); pAttractorIt != vecAttractors.cend(); ++pAttractorIt) {
+ if (*pAttractorIt == pAttractor) {
+ return (*pAttractorIt)->IsInQueue(pPed);
+ }
+ }
+ return false;
+}
+
+bool CPedAttractorManager::IsAtHeadOfQueue(CPed* pPed, CPedAttractor* pAttractor, std::vector<CPedAttractor*>& vecAttractors)
+{
+ if (!pAttractor)
+ return false;
+ for (std::vector<CPedAttractor*>::const_iterator pAttractorIt = vecAttractors.cbegin(); pAttractorIt != vecAttractors.cend(); ++pAttractorIt) {
+ if (*pAttractorIt == pAttractor) {
+ return (*pAttractorIt)->IsAtHeadOfQueue(pPed);
+ }
+ }
+ return false;
+}
+
+bool CPedAttractorManager::IsPedRegistered(CPed* pPed, std::vector<CPedAttractor*>& vecAttractors)
+{
+ for (std::vector<CPedAttractor*>::const_iterator pAttractorIt = vecAttractors.cbegin(); pAttractorIt != vecAttractors.cend(); ++pAttractorIt) {
+ if ((*pAttractorIt)->IsRegisteredWithPed(pPed))
+ return true;
+ }
+ return false;
+}
+
+bool CPedAttractorManager::IsApproachable(C2dEffect* pEffect, const CMatrix& matrix, int32, CPed* pPed)
+{
+ if (pEffect->pedattr.type == ATTRACTOR_SHELTER) {
+ CVector pos;
+ ComputeEffectPos(pEffect, matrix, pos);
+ return CWorld::GetIsLineOfSightClear(pPed->GetPosition(), pos, true, false, false, false, false, false);
+ }
+ CVector vecUseDir, vecEffectPos;
+ ComputeEffectUseDir(pEffect, matrix, vecUseDir);
+ ComputeEffectPos(pEffect, matrix, vecEffectPos);
+ float dp = -DotProduct(vecUseDir, vecEffectPos);
+ if (pEffect->pedattr.type == ATTRACTOR_ATM || pEffect->pedattr.type == ATTRACTOR_PIZZA || pEffect->pedattr.type == ATTRACTOR_ICECREAM) {
+ vecUseDir = -vecUseDir;
+ dp = -dp;
+ }
+ if (dp + DotProduct(vecEffectPos, pPed->GetPosition()) > 0.0f) {
+ CVector vecPedToAttractor = pPed->GetPosition() - vecEffectPos;
+ vecPedToAttractor.Normalise();
+ if (DotProduct(vecPedToAttractor, vecUseDir) > 0.25f && CWorld::IsWanderPathClear(pPed->GetPosition(), vecEffectPos, 2.0f, 0))
+ return true;
+ }
+ return false;
+}
diff --git a/src/peds/PedAttractor.h b/src/peds/PedAttractor.h
new file mode 100644
index 00000000..85b4327b
--- /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 override { return ATTRACTOR_ATM; };
+ virtual void UpdatePedStateOnDeparture(CPed* pPed) const override;
+ CPedAtmAttractor(C2dEffect* pEffect, const CMatrix& matrix, int32 maxpeds, float qdist, float waitTime, float approachTime, float distance, float headingdiff, float posdisp, float headdisp) :
+ CPedAttractor(pEffect, matrix, maxpeds, qdist, waitTime, approachTime, distance, headingdiff, posdisp, headdisp)
+ {};
+};
+
+class CPedIceCreamAttractor : public CPedAttractor
+{
+public:
+ virtual ~CPedIceCreamAttractor() override { GetPedAttractorManager()->RemoveIceCreamVanEffects(p2dEffect); }
+ virtual ePedAttractorType GetType() const override { return ATTRACTOR_ICECREAM; }
+ virtual void UpdatePedStateOnDeparture(CPed* pPed) const override {};
+ CPedIceCreamAttractor(C2dEffect* pEffect, const CMatrix& matrix, int32 maxpeds, float qdist, float waitTime, float approachTime, float distance, float headingdiff, float posdisp, float headdisp) :
+ CPedAttractor(pEffect, matrix, maxpeds, qdist, waitTime, approachTime, distance, headingdiff, posdisp, headdisp)
+ {};
+};
+
+class CPedPizzaAttractor : public CPedAttractor
+{
+public:
+ virtual float GetHeadOfQueueWaitTime() override { return 2000.0f; }
+ virtual ePedAttractorType GetType() const override { return ATTRACTOR_PIZZA; }
+ virtual void UpdatePedStateOnDeparture(CPed* pPed) const override;
+ CPedPizzaAttractor(C2dEffect* pEffect, const CMatrix& matrix, int32 maxpeds, float qdist, float waitTime, float approachTime, float distance, float headingdiff, float posdisp, float headdisp) :
+ CPedAttractor(pEffect, matrix, maxpeds, qdist, waitTime, approachTime, distance, headingdiff, posdisp, headdisp)
+ {};
+};
+
+class CPedSeatAttractor : public CPedAttractor
+{
+public:
+ virtual ePedAttractorType GetType() const override { return ATTRACTOR_SEAT; }
+ virtual void UpdatePedStateOnDeparture(CPed* pPed) const override {};
+ CPedSeatAttractor(C2dEffect* pEffect, const CMatrix& matrix, int32 maxpeds, float qdist, float waitTime, float approachTime, float distance, float headingdiff, float posdisp, float headdisp) :
+ CPedAttractor(pEffect, matrix, maxpeds, qdist, waitTime, approachTime, distance, headingdiff, posdisp, headdisp)
+ {};
+};
+
+class CPedShelterAttractor : public CPedAttractor
+{
+ static std::vector<CVector> ms_displacements;
+public:
+ virtual ePedAttractorType GetType() const override { return ATTRACTOR_SHELTER; }
+ virtual bool BroadcastDeparture(CPed*) override;
+ virtual void UpdatePedStateOnDeparture(CPed* pPed) const override {};
+ virtual bool IsAtHeadOfQueue(CPed* pPed) const override { return true; }
+ virtual void ComputeAttractPos(int qid, CVector& pos) const override;
+ virtual void ComputeAttractHeading(int qid, float& heading) const override;
+
+ CPedShelterAttractor(C2dEffect* pEffect, const CMatrix& matrix, int32 maxpeds, float qdist, float waitTime, float approachTime, float distance, float headingdiff, float posdisp, float headdisp) :
+ CPedAttractor(pEffect, matrix, maxpeds, qdist, waitTime, approachTime, distance, headingdiff, posdisp, headdisp)
+ {};
+
+
+ CVector GetDisplacement(int32 qid) const;
+};
+
+class CPedStopAttractor : public CPedAttractor
+{
+public:
+ virtual ePedAttractorType GetType() const override { return ATTRACTOR_STOP; }
+ virtual void UpdatePedStateOnDeparture(CPed* pPed) const override {};
+
+ CPedStopAttractor(C2dEffect* pEffect, const CMatrix& matrix, int32 maxpeds, float qdist, float waitTime, float approachTime, float distance, float headingdiff, float posdisp, float headdisp) :
+ CPedAttractor(pEffect, matrix, maxpeds, qdist, waitTime, approachTime, distance, headingdiff, posdisp, headdisp)
+ {};
+}; \ No newline at end of file
diff --git a/src/peds/PedChat.cpp b/src/peds/PedChat.cpp
index 81e295c6..470b7eeb 100644
--- a/src/peds/PedChat.cpp
+++ b/src/peds/PedChat.cpp
@@ -4,47 +4,66 @@
#include "General.h"
#include "Ped.h"
+// --MIAMI: file done
+
// 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 +78,7 @@ CPed::ServiceTalking(void)
if (bBodyPartJustCameOff && m_bodyPartBleeding == PED_HEAD)
return;
- if (!CGeneral::faststricmp(CModelInfo::GetModelInfo(GetModelIndex())->GetName(), "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 +92,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 +105,50 @@ CPed::ServiceTalking(void)
void
CPed::Say(uint16 audio)
{
- if (IsPlayer()) {
+ if (3.0f + TheCamera.GetPosition().z < GetPosition().z)
+ return;
+
+ if (TheCamera.m_CameraAverageSpeed > 1.65f) {
+ if (audio != SOUND_PED_DAMAGE && audio != SOUND_PED_HIT && audio != SOUND_PED_LAND)
+ return;
- // Ofc this part isn't in VC.
+ } 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..aed11357 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,7 @@ static char PersonalityTypeText[][18] = {
"Geek Girl",
"Old Girl",
"Tough Girl",
- "Tramp Male",
- "Tramp Female",
+ "Tramp",
"Tourist",
"Prostitute",
"Criminal",
@@ -142,8 +165,6 @@ static char PersonalityTypeText[][18] = {
"Psycho",
"Steward",
"Sports Fan",
- "Shopper",
- "Old Shopper"
};
static char WaitStateText[][16] = {
@@ -168,6 +189,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 +319,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 b57364d8..3e0dfb6d 100644
--- a/src/peds/PedFight.cpp
+++ b/src/peds/PedFight.cpp
@@ -22,37 +22,49 @@
#include "Automobile.h"
#include "WaterLevel.h"
#include "World.h"
+#include "Bike.h"
+#include "Glass.h"
+#include "SpecialFX.h"
+
+//--MIAMI: file done
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] = {
- {NUM_ANIMS, 0.0f, 0.0f, 0.0f, 0.0f, HITLEVEL_NULL, 0, 0},
- {ANIM_PUNCH_R, 0.2f, 8.0f / 30.0f, 0.0f, 0.3f, HITLEVEL_HIGH, 1, 0},
- {ANIM_FIGHT_IDLE, 0.0f, 0.0f, 0.0f, 0.0f, HITLEVEL_NULL, 0, 0},
- {ANIM_FIGHT_SH_F, 0.0f, 0.0f, 0.0f, 0.0f, HITLEVEL_NULL, 0, 0},
- {ANIM_FIGHT_KNEE, 4.0f / 30.0f, 0.2f, 0.0f, 0.6f, HITLEVEL_LOW, 2, 0},
- {ANIM_FIGHT_HEAD, 4.0f / 30.0f, 0.2f, 0.0f, 0.7f, HITLEVEL_HIGH, 3, 0},
- {ANIM_FIGHT_PUNCH, 4.0f / 30.0f, 7.0f / 30.0f, 10.0f / 30.0f, 0.4f, HITLEVEL_HIGH, 1, 0},
- {ANIM_FIGHT_LHOOK, 8.0f / 30.0f, 10.0f / 30.0f, 0.0f, 0.4f, HITLEVEL_HIGH, 3, 0},
- {ANIM_FIGHT_KICK, 8.0f / 30.0f, 10.0f / 30.0f, 0.0f, 0.5, HITLEVEL_MEDIUM, 2, 0},
- {ANIM_FIGHT_LONGKICK, 8.0f / 30.0f, 10.0f / 30.0f, 0.0f, 0.5, HITLEVEL_MEDIUM, 4, 0},
- {ANIM_FIGHT_ROUNDHOUSE, 8.0f / 30.0f, 10.0f / 30.0f, 0.0f, 0.6f, HITLEVEL_MEDIUM, 4, 0},
- {ANIM_FIGHT_BODYBLOW, 5.0f / 30.0f, 7.0f / 30.0f, 0.0f, 0.35f, HITLEVEL_LOW, 2, 0},
- {ANIM_KICK_FLOOR, 10.0f / 30.0f, 14.0f / 30.0f, 0.0f, 0.4f, HITLEVEL_GROUND, 1, 0},
- {ANIM_HIT_FRONT, 0.0f, 0.0f, 0.0f, 0.0f, HITLEVEL_NULL, 0, 0},
- {ANIM_HIT_BACK, 0.0f, 0.0f, 0.0f, 0.0f, HITLEVEL_NULL, 0, 0},
- {ANIM_HIT_RIGHT, 0.0f, 0.0f, 0.0f, 0.0f, HITLEVEL_NULL, 0, 0},
- {ANIM_HIT_LEFT, 0.0f, 0.0f, 0.0f, 0.0f, HITLEVEL_NULL, 0, 0},
- {ANIM_HIT_BODYBLOW, 0.0f, 0.0f, 0.0f, 0.0f, HITLEVEL_NULL, 0, 0},
- {ANIM_HIT_CHEST, 0.0f, 0.0f, 0.0f, 0.0f, HITLEVEL_NULL, 0, 0},
- {ANIM_HIT_HEAD, 0.0f, 0.0f, 0.0f, 0.0f, HITLEVEL_NULL, 0, 0},
- {ANIM_HIT_WALK, 0.0f, 0.0f, 0.0f, 0.0f, HITLEVEL_NULL, 0, 0},
- {ANIM_FLOOR_HIT, 0.0f, 0.0f, 0.0f, 0.0f, HITLEVEL_NULL, 0, 0},
- {ANIM_HIT_BEHIND, 0.0f, 0.0f, 0.0f, 0.0f, HITLEVEL_NULL, 0, 0},
- {ANIM_FIGHT2_IDLE, 0.0f, 0.0f, 0.0f, 0.0f, HITLEVEL_NULL, 0, 0},
+FightMove tFightMoves[NUM_FIGHTMOVES] =
+{
+ { NUM_STD_ANIMS, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, HITLEVEL_NULL, 0, 0 },
+ { ANIM_PUNCH_R, 0.2f, 8.f/30.f, 0.0f, 0.3f, 1.0f, HITLEVEL_HIGH, 1, 0 },
+ { ANIM_FIGHT_IDLE, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, HITLEVEL_NULL, 0, 0 },
+ { ANIM_FIGHT_SH_F, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, HITLEVEL_NULL, 0, 0 },
+ { ANIM_FIGHT_KNEE, 4.f/30.f, 0.2f, 0.0f, 0.6f, 1.0f, HITLEVEL_LOW, 2, 0 },
+ { ANIM_FIGHT_LHOOK, 8.f/30.f, 10.f/30.f, 0.0f, 0.4f, 1.0f, HITLEVEL_HIGH, 3, 0 },
+ { ANIM_FIGHT_JAB, 4.f/30.f, 0.2f, 0.0f, 0.7f, 1.0f, HITLEVEL_HIGH, 3, 0 },
+ { ANIM_FIGHT_PUNCH, 4.f/30.f, 7.f/30.f, 10.f/30.f, 0.4f, 1.0f, HITLEVEL_HIGH, 1, 0 },
+ { ANIM_FIGHT_LONGKICK, 8.f/30.f, 10.f/30.f, 0.0f, 0.5f, 1.0f, HITLEVEL_MEDIUM, 4, 0 },
+ { ANIM_FIGHT_ROUNDHOUSE, 8.f/30.f, 10.f/30.f, 0.0f, 0.6f, 1.0f, HITLEVEL_MEDIUM, 4, 0 },
+ { ANIM_FIGHT_KICK, 8.f/30.f, 10.f/30.f, 0.0f, 0.5f, 1.0f, HITLEVEL_HIGH, 2, 0 },
+ { ANIM_FIGHT_HEAD, 8.f/30.f, 10.f/30.f, 0.0f, 0.5f, 1.0f, HITLEVEL_MEDIUM, 2, 0 },
+ { ANIM_FIGHT_BKICK_L, 8.f/30.f, 10.f/30.f, 0.0f, 0.5f, 1.0f, HITLEVEL_LOW, 2, 0 },
+ { ANIM_FIGHT_BKICK_L, 8.f/30.f, 10.f/30.f, 0.0f, 0.5f, 1.0f, HITLEVEL_LOW, 2, 0 },
+ { ANIM_FIGHT_ELBOW_L, 8.f/30.f, 10.f/30.f, 0.0f, 0.5f, 1.0f, HITLEVEL_MEDIUM, 2, 0 },
+ { ANIM_FIGHT_BKICK_R, 8.f/30.f, 10.f/30.f, 0.0f, 0.5f, 1.0f, HITLEVEL_MEDIUM, 2, 0 },
+ { ANIM_FIGHT_ELBOW_R, 8.f/30.f, 10.f/30.f, 0.0f, 0.5f, 1.0f, HITLEVEL_HIGH, 2, 0 },
+ { ANIM_KICK_FLOOR, 10.f/30.f, 14.f/30.f, 0.0f, 0.4f, 1.0f, HITLEVEL_GROUND, 1, 0 },
+ { ANIM_HIT_FRONT, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, HITLEVEL_NULL, 0, 0 },
+ { ANIM_HIT_BACK, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, HITLEVEL_NULL, 0, 0 },
+ { ANIM_HIT_RIGHT, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, HITLEVEL_NULL, 0, 0 },
+ { ANIM_HIT_LEFT, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, HITLEVEL_NULL, 0, 0 },
+ { ANIM_HIT_BODYBLOW, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, HITLEVEL_NULL, 0, 0 },
+ { ANIM_HIT_CHEST, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, HITLEVEL_NULL, 0, 0 },
+ { ANIM_HIT_HEAD, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, HITLEVEL_NULL, 0, 0 },
+ { ANIM_HIT_WALK, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, HITLEVEL_NULL, 0, 0 },
+ { ANIM_FLOOR_HIT, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, HITLEVEL_NULL, 0, 0 },
+ { ANIM_HIT_BEHIND, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, HITLEVEL_NULL, 0, 0 },
+ { ANIM_WEAPON_FIRE, 4.f/30.f, 7.f/30.f, 10.f/30.f, 0.4f, 1.0f, HITLEVEL_HIGH, 1, 0 },
+ { ANIM_WEAPON_CROUCHFIRE, 4.f/30.f, 7.f/30.f, 10.f/30.f, 0.4f, 1.0f, HITLEVEL_HIGH, 1, 0 },
+ { ANIM_WEAPON_SPECIAL, 4.f / 30.f, 7.f / 30.f, 10.f / 30.f, 0.4f, 1.0f, HITLEVEL_HIGH, 1, 0 },
+ { ANIM_FIGHT2_IDLE, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, HITLEVEL_NULL, 0, 0 }
};
static PedOnGroundState
@@ -147,18 +159,18 @@ CheckForPedsOnGroundToAttack(CPed *attacker, CPed **pedOnGround)
return stateToReturn;
}
+// --MIAMI: Done
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,41 +178,51 @@ 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);
}
+// --MIAMI: Done
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->m_bCrouchFire) {
+ 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->m_bCanAimWithArm)
m_pedIK.m_flags |= CPedIK::AIMS_WITH_ARM;
else
@@ -208,6 +230,7 @@ CPed::PointGunAt(void)
}
}
+// --MIAMI: Done
void
CPed::ClearPointGunAt(void)
{
@@ -217,51 +240,39 @@ 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);
- }
- if (animAssoc) {
- animAssoc->flags |= ASSOC_DELETEFADEDOUT;
- animAssoc->blendDelta = -4.0f;
+ weaponInfo = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType);
+ animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_FIRE);
+ if (!animAssoc || animAssoc->blendDelta < 0.0f) {
+ if (!!weaponInfo->m_bCrouchFire) {
+ animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetCrouchFireAnim(weaponInfo));
}
-#ifndef VC_PED_PORTS
}
-#endif
+ if (animAssoc) {
+ animAssoc->flags |= ASSOC_DELETEFADEDOUT;
+ animAssoc->blendDelta = -4.0f;
+ }
}
+// --MIAMI: Done
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_IDLE_ARMED);
- 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_HGUN_RELOAD)) {
- bIsAttacking = false;
- return;
- }
-
- if (RpAnimBlendClumpGetAssociation(GetClump(), ANIM_AK_RELOAD)) {
+ if (curWeapon->m_bReload &&
+ (RpAnimBlendClumpGetAssociation(GetClump(), GetReloadAnim(curWeapon)) || RpAnimBlendClumpGetAssociation(GetClump(), GetCrouchReloadAnim(curWeapon)))) {
if (!IsPlayer() || m_nPedState != PED_ATTACK || ((CPlayerPed*)this)->m_bHaveTargetSelected)
bIsAttacking = false;
else
@@ -270,20 +281,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->m_bFightMode || GetWeapon()->m_eWeaponType == WEAPONTYPE_BRASSKNUCKLE) {
if (IsPlayer() ||
- (m_nPedState != PED_FIGHT && m_nMoveState != PEDMOVE_NONE && m_nMoveState != PEDMOVE_STILL && !(m_pedStats->m_flags & STAT_SHOPPING_BAGS))) {
+ (m_nPedState != PED_FIGHT && m_nMoveState != PEDMOVE_NONE && m_nMoveState != PEDMOVE_STILL
+ && !(m_pedStats->m_flags & STAT_SHOPPING_BAGS) && curWeapon->m_bPartialAttack)) {
if (m_nPedState != PED_ATTACK) {
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,33 +298,64 @@ CPed::SetAttack(CEntity *victim)
animAssoc->SetFinishCallback(FinishedAttackCB, this);
}
} else {
- StartFightAttack(CGeneral::GetRandomNumber() % 256);
+ StartFightAttack(CGeneral::GetRandomNumber());
+ }
+ return;
+ }
+
+ if (curWeapon->m_bPartialAttack &&
+ (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->m_bCanAim) {
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->m_bCanAimWithArm) {
SetAimFlag(m_fRotationCur);
-
- if (FindPlayerPed() == this && TheCamera.Cams[0].Using3rdPersonMouseCam())
- ((CPlayerPed*)this)->m_fFPSMoveHeading = TheCamera.Find3rdPersonQuickAimPitch();
}
}
if (m_nPedState == PED_ATTACK) {
@@ -325,7 +363,7 @@ CPed::SetAttack(CEntity *victim)
return;
}
- if (IsPlayer() || !victimPed || victimPed->IsPedInControl()) {
+ if (IsPlayer() || (!victimPed || victimPed->IsPedInControl())) {
if (IsPlayer())
CPad::GetPad(0)->ResetAverageWeapon();
@@ -339,7 +377,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->m_bCanAim)
@@ -350,19 +388,40 @@ CPed::SetAttack(CEntity *victim)
SetPedState(PED_ATTACK);
SetMoveState(PEDMOVE_NONE);
- if (bCrouchWhenShooting) {
- animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_RBLOCK_CSHOOT, 4.0f);
+ if (bCrouchWhenShooting && bIsDucking && !!curWeapon->m_bCrouchFire) {
+ 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->m_bThrow)
+ fireAnim = ANIM_THROWABLE_START_THROW;
+ else if (CGame::nastyGame && (curWeapon->m_bGround2nd || curWeapon->m_bGround3rd)) {
+ 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();
@@ -377,24 +436,20 @@ 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);
}
+// --MIAMI: Done
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
@@ -406,75 +461,157 @@ CPed::ClearAttack(void)
}
}
+// --MIAMI: Done
void
CPed::ClearAttackByRemovingAnim(void)
{
- if (m_nPedState != PED_ATTACK || bIsDucking)
+ if (m_nPedState != PED_ATTACK)
return;
CWeaponInfo *weapon = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType);
- CAnimBlendAssociation *weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), weapon->m_AnimToPlay);
- if (!weaponAssoc) {
- weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), weapon->m_Anim2ToPlay);
+ CAnimBlendAssociation *weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetPrimaryFireAnim(weapon));
- if (!weaponAssoc && weapon->m_bThrow)
- weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_THROWU);
-
- 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);
}
+// --MIAMI: Done
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_WEAPON_START_THROW:
- // what?!
- if ((!ped->IsPlayer() || ((CPlayerPed*)ped)->m_bHaveTargetSelected) && ped->IsPlayer()) {
- attackAssoc->blendDelta = -1000.0f;
- newAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_WEAPON_THROWU);
- } else {
- attackAssoc->blendDelta = -1000.0f;
- newAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_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_WEAPON_CROUCH, 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_WEAPON_CROUCH, 8.0f);
+ newAnim->SetCurrentTime(newAnim->hierarchy->totalLength);
+ newAnim->flags &= ~ASSOC_RUNNING;
+ }
+ }
- case ANIM_FIGHT_PPUNCH:
- attackAssoc->blendDelta = -8.0f;
- attackAssoc->flags |= ASSOC_DELETEFADEDOUT;
- ped->ClearAttack();
- return;
+ if (!ped->bIsAttacking)
+ ped->ClearAttack();
- case ANIM_WEAPON_THROW:
- case ANIM_WEAPON_THROWU:
- 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();
}
+}
+
+// --MIAMI: Done
+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->m_bCrouchFire) {
+ crouchFireAssoc = RpAnimBlendClumpGetAssociation(ped->GetClump(), GetCrouchFireAnim(weapon));
+ }
+ if (!!weapon->m_bReload && reloadAssoc) {
+ if (reloadAssoc->animId == GetCrouchReloadAnim(weapon) && !crouchFireAssoc) {
+ CAnimBlendAssociation *crouchAssoc = CAnimManager::BlendAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_WEAPON_CROUCH, 8.0f);
+ crouchAssoc->SetCurrentTime(crouchAssoc->hierarchy->totalLength);
+ crouchAssoc->flags &= ~ASSOC_RUNNING;
+ }
+ }
+ } else if (weapon->m_bReloadLoop2Start && 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));
+ }
}
+// --MIAMI: Done
uint8
CPed::CheckForPointBlankPeds(CPed *pedToVerify)
{
@@ -488,7 +625,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,
@@ -501,7 +638,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) {
@@ -516,72 +655,143 @@ CPed::CheckForPointBlankPeds(CPed *pedToVerify)
return NO_POINT_BLANK_PED;
}
+// --MIAMI: Done except commented things
void
CPed::Attack(void)
{
CAnimBlendAssociation *weaponAnimAssoc;
int32 weaponAnim;
- float animStart;
eWeaponType ourWeaponType;
float weaponAnimTime;
eWeaponFire ourWeaponFire;
float animLoopEnd;
CWeaponInfo *ourWeapon;
bool attackShouldContinue;
- AnimationId reloadAnim;
CAnimBlendAssociation *reloadAnimAssoc;
+ CAnimBlendAssociation *throwAssoc;
float delayBetweenAnimAndFire;
+ float animLoopStart;
CVector firePos;
ourWeaponType = GetWeapon()->m_eWeaponType;
ourWeapon = CWeaponInfo::GetWeaponInfo(ourWeaponType);
ourWeaponFire = ourWeapon->m_eWeaponFire;
- weaponAnimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ourWeapon->m_AnimToPlay);
+ weaponAnimAssoc = nil;
attackShouldContinue = bIsAttacking;
reloadAnimAssoc = nil;
- reloadAnim = NUM_ANIMS;
+ throwAssoc = nil;
+ animLoopStart = ourWeapon->m_fAnimLoopStart;
+ animLoopEnd = ourWeapon->m_fAnimLoopEnd;
delayBetweenAnimAndFire = ourWeapon->m_fAnimFrameFire;
weaponAnim = ourWeapon->m_AnimToPlay;
- if (weaponAnim == ANIM_WEAPON_HGUN_BODY)
- reloadAnim = ANIM_HGUN_RELOAD;
- else if (weaponAnim == ANIM_WEAPON_AK_BODY)
- reloadAnim = ANIM_AK_RELOAD;
+ if (bIsDucking) {
+ if (!!ourWeapon->m_bCrouchFire && bCrouchWhenShooting) {
+ weaponAnimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetCrouchFireAnim(ourWeapon));
+ if (weaponAnimAssoc) {
+ animLoopStart = ourWeapon->m_fAnim2LoopStart;
+ animLoopEnd = ourWeapon->m_fAnim2LoopEnd;
+ delayBetweenAnimAndFire = ourWeapon->m_fAnim2FrameFire;
+ }
+ }
+ } else {
+ AnimationId anim = GetFireAnimNotDucking(ourWeapon);
+ weaponAnimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), anim);
+ if (anim == ANIM_WEAPON_FIRE_3RD && weaponAnimAssoc) {
+ animLoopStart = 11.f/30.f;
+ animLoopEnd = 19.f/30.f;
+ delayBetweenAnimAndFire = 14.f/30.f;
+ }
+ }
- if (reloadAnim != NUM_ANIMS)
- reloadAnimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), reloadAnim);
+ if (ourWeapon->m_bReload) {
+ reloadAnimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetReloadAnim(ourWeapon));
+ }
- if (bIsDucking)
- return;
+ if (!!ourWeapon->m_bReload && !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 (!!ourWeapon->m_bThrow) {
+ throwAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_THROWABLE_START_THROW);
+ }
+
+ if ( CTimer::GetTimeInMilliseconds() < m_shootTimer )
attackShouldContinue = true;
+ bool meleeAttackStarted = false;
+ if ( !weaponAnimAssoc ) {
+ if (!!ourWeapon->m_bPartialAttack) {
+ weaponAnimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_MELEE_ATTACK_START);
+ 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->m_bThrow) {
- weaponAnimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_THROWU);
- delayBetweenAnimAndFire = 0.2f;
+ if (!!ourWeapon->m_bUse2nd) {
+ 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 (ourWeaponFire != WEAPON_FIRE_PROJECTILE || !IsPlayer() || ((CPlayerPed*)this)->m_bHaveTargetSelected) {
- if (!CGame::nastyGame || ourWeaponFire != 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 && !!ourWeapon->m_bCrouchFire) {
+ 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_bGround2nd && !ourWeapon->m_bGround3rd) ||
+ ourWeaponFire != WEAPON_FIRE_MELEE || 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);
@@ -598,75 +808,118 @@ CPed::Attack(void)
} else
FinishedAttackCB(nil, this);
- return;
+ }
+ return;
+ }
+
+ 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;
}
}
- animStart = ourWeapon->m_fAnimLoopStart;
+ float animStart = ourWeapon->m_fAnimLoopStart * 0.4f;
weaponAnimTime = weaponAnimAssoc->currentTime;
if (weaponAnimTime > animStart && weaponAnimTime - weaponAnimAssoc->timeStep <= animStart) {
- if (ourWeapon->m_bCanAimWithArm)
+ if (!bIsDucking && !(m_nPedType == PEDTYPE_COP && ourWeapon->m_bCop3rd && weaponAnimAssoc->animId == ANIM_WEAPON_FIRE_3RD) && ourWeapon->m_bCanAimWithArm)
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 (ourWeaponType != WEAPONTYPE_CHAINSAW
+ || !meleeAttackStarted && delayBetweenAnimAndFire - 0.5f >= weaponAnimAssoc->currentTime
+ || weaponAnimAssoc->currentTime - weaponAnimAssoc->timeStep > delayBetweenAnimAndFire) {
- } else {
- firePos = ourWeapon->m_vecFireOffset;
- if (ourWeaponType == WEAPONTYPE_BASEBALLBAT) {
- if (weaponAnimAssoc->animId == ourWeapon->m_Anim2ToPlay)
- firePos.z = 0.7f * ourWeapon->m_fRadius - 1.0f;
+ if (ourWeaponType == WEAPONTYPE_CHAINSAW) {
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_CHAINSAW_ATTACK, 0.0f);
+ } else if (weaponAnimTime <= delayBetweenAnimAndFire || weaponAnimTime - weaponAnimAssoc->timeStep > delayBetweenAnimAndFire || !weaponAnimAssoc->IsRunning()) {
+ if (weaponAnimAssoc->speed < 1.0f)
+ weaponAnimAssoc->speed = 1.0f;
- firePos = GetMatrix() * firePos;
- } else if (ourWeaponType != WEAPONTYPE_UNARMED) {
- TransformToNode(firePos, weaponAnimAssoc->animId == ANIM_KICK_FLOOR ? PED_FOOTR : PED_HANDR);
} else {
- firePos = GetMatrix() * firePos;
- }
-
- GetWeapon()->Fire(this, &firePos);
+ firePos = ourWeapon->m_vecFireOffset;
- if (ourWeaponType == WEAPONTYPE_MOLOTOV || ourWeaponType == WEAPONTYPE_GRENADE) {
- RemoveWeaponModel(ourWeapon->m_nModelId);
- }
- if (!GetWeapon()->m_nAmmoTotal && ourWeaponFire != WEAPON_FIRE_MELEE && FindPlayerPed() != this) {
- SelectGunIfArmed();
- }
+ if (ourWeaponType != WEAPONTYPE_KATANA && ourWeaponType != WEAPONTYPE_CHAINSAW) {
+ if (ourWeapon->m_eWeaponFire != WEAPON_FIRE_MELEE) {
+ TransformToNode(firePos, (weaponAnimAssoc->animId == ANIM_MELEE_ATTACK_2ND && ourWeapon->m_AnimToPlay == ASSOCGRP_UNARMED) ? PED_FOOTR : PED_HANDR);
+ } else {
+ firePos = GetMatrix() * firePos;
+ }
+ } else {
+ if (weaponAnimAssoc->animId == ANIM_MELEE_ATTACK_2ND)
+ firePos.z = 0.7f * ourWeapon->m_fRadius - 1.0f;
- 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 != NUM_ANIMS /* && !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_WEAPON_BAT_V || weaponAnimAssoc->animId == ANIM_WEAPON_BAT_H) {
- DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_BAT_ATTACK, 1.0f);
- } else if (weaponAnimAssoc->animId == ANIM_FIGHT_PPUNCH) {
- DMAudio.PlayOneShot(m_audioEntityId, SOUND_FIGHT_PUNCH_39, 0.0f);
+
+ GetWeapon()->Fire(this, &firePos);
+
+ if (ourWeaponType == WEAPONTYPE_MOLOTOV || ourWeaponType == WEAPONTYPE_GRENADE || ourWeaponType == WEAPONTYPE_DETONATOR_GRENADE ||
+ ourWeaponType == WEAPONTYPE_TEARGAS) {
+ RemoveWeaponModel(ourWeapon->m_nModelId);
+ }
+ if (!GetWeapon()->m_nAmmoTotal && ourWeaponFire != WEAPON_FIRE_MELEE && FindPlayerPed() != this) {
+ SelectGunIfArmed();
}
- 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 | (ourWeaponType << 8)));
+ break;
+ case ASSOCGRP_KNIFE:
+ case ASSOCGRP_BASEBALLBAT:
+ case ASSOCGRP_GOLFCLUB:
+ case ASSOCGRP_CHAINSAW:
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_BAT_ATTACK, (damagerType | (ourWeaponType << 8)));
+ break;
+ default:
+ break;
+ }
- if (bIsAttacking || CTimer::GetTimeInMilliseconds() < m_shootTimer) {
- weaponAnimAssoc->callbackType = 0;
+ 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_IDLE, 0.0f);
+ if (IsPlayer()) {
+ CPad::GetPad(0)->StartShake(240, 90);
+ }
+ }
attackShouldContinue = false;
}
- if (ourWeaponType == WEAPONTYPE_SHOTGUN) {
+ if (ourWeapon->m_eWeaponFire == WEAPON_FIRE_INSTANT_HIT && ourWeapon->m_AnimToPlay == ASSOCGRP_SHOTGUN) {
weaponAnimTime = weaponAnimAssoc->currentTime;
firePos = ourWeapon->m_vecFireOffset;
@@ -688,89 +941,124 @@ CPed::Attack(void)
GetWeapon()->AddGunshell(this, gunshellPos, gunshellRot, 0.025f);
}
}
-#ifdef VC_PED_PORTS
+
+ if (IsPlayer()) {
+ eWeaponType weaponType = GetWeapon()->m_eWeaponType;
+ if (weaponType == WEAPONTYPE_BASEBALLBAT || weaponType == WEAPONTYPE_GOLFCLUB || weaponType == 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(weaponType);
+ }
+ }
+ }
+
+ // 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 = ((ourWeaponType == WEAPONTYPE_FLAMETHROWER || ourWeaponType == WEAPONTYPE_UZI || ourWeaponType == 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 (ourWeaponFire == 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() && ourWeaponFire != WEAPON_FIRE_PROJECTILE) {
-
+ if (GetWeapon()->m_eWeaponState == WEAPONSTATE_RELOADING) {
+ if (ourWeapon->m_bReload && !reloadAnimAssoc) {
+ if (!CWorld::Players[CWorld::PlayerInFocus].m_bFastReload) {
+ CAnimBlendAssociation *newReloadAssoc;
+ if (bIsDucking) {
+ newReloadAssoc = CAnimManager::BlendAnimation(
+ GetClump(), ourWeapon->m_AnimToPlay,
+ GetCrouchReloadAnim(ourWeapon),
+ 8.0f);
+ } else {
+ newReloadAssoc = CAnimManager::BlendAnimation(
+ GetClump(), ourWeapon->m_AnimToPlay,
+ GetReloadAnim(ourWeapon),
+ 8.0f);
+ }
+ newReloadAssoc->SetFinishCallback(FinishedReloadCB, this);
+ }
+ ClearLookFlag();
+ ClearAimFlag();
+ bIsAttacking = false;
+ bIsPointingGunAt = false;
+ m_shootTimer = CTimer::GetTimeInMilliseconds();
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_AK47_BULLET_ECHO, GetWeapon()->m_eWeaponType);
+ return;
+ }
+ }
if (weaponAnimTime - 2.0f * weaponAnimAssoc->timeStep <= animLoopEnd
&& (bIsAttacking || CTimer::GetTimeInMilliseconds() < m_shootTimer)
- && GetWeapon()->m_eWeaponState != WEAPONSTATE_RELOADING) {
+ && (GetWeapon()->m_eWeaponState != WEAPONSTATE_RELOADING
+ || GetWeapon()->m_eWeaponType == WEAPONTYPE_MINIGUN)) {
+
+ PedOnGroundState pedOnGroundState;
+ if (ourWeapon->m_eWeaponFire == WEAPON_FIRE_MELEE &&
+ (CGame::nastyGame && ((pedOnGroundState = CheckForPedsOnGroundToAttack(this, nil)) > PED_IN_FRONT_OF_ATTACKER)
+ || ourWeaponType == WEAPONTYPE_BASEBALLBAT && pedOnGroundState == NO_PED && bIsStanding && m_pCurSurface && m_pCurSurface->IsVehicle())) {
- weaponAnim = weaponAnimAssoc->animId;
- if (ourWeaponFire != WEAPON_FIRE_MELEE || CheckForPedsOnGroundToAttack(this, nil) < PED_ON_THE_FLOOR) {
- if (weaponAnim != ourWeapon->m_Anim2ToPlay || weaponAnim == ANIM_RBLOCK_CSHOOT) {
- weaponAnimAssoc->Start(ourWeapon->m_fAnimLoopStart);
+ AnimationId fireAnim = GetFireAnimGround(ourWeapon, false);
+ if (weaponAnimAssoc->animId == fireAnim)
+ weaponAnimAssoc->SetCurrentTime(0.1f);
+ else {
+ if (fireAnim) {
+ weaponAnimAssoc = CAnimManager::BlendAnimation(GetClump(), ourWeapon->m_AnimToPlay, fireAnim, 8.0f);
+ } else {
+ weaponAnimAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_KICK_FLOOR, 8.0f);
+ }
+ }
+ weaponAnimAssoc->SetFinishCallback(FinishedAttackCB, this);
+ } else if (!!ourWeapon->m_bUse2nd) {
+ 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->flags &= ~ASSOC_RUNNING;
- SetPointGunAt(m_pPointGunAt);
-#endif
- } else {
- ClearAimFlag();
+ }
+ } else if (IsPlayer() && m_pPointGunAt && bIsAimingGun && GetWeapon()->m_eWeaponState != WEAPONSTATE_RELOADING) {
+ weaponAnimAssoc->SetCurrentTime(animLoopEnd);
+ weaponAnimAssoc->flags &= ~ASSOC_RUNNING;
+ SetPointGunAt(m_pPointGunAt);
+ } 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 (ourWeaponType) {
- 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;
- }
- }
+ // Echoes of bullets, at the end of the attack. (Bug: doesn't play while reloading)
+ if (weaponAnimAssoc->currentTime - weaponAnimAssoc->timeStep < animLoopEnd)
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_AK47_BULLET_ECHO, ourWeaponType);
- // Fun fact: removing this part leds to reloading flamethrower
- if (ourWeaponType == WEAPONTYPE_FLAMETHROWER && weaponAnimAssoc->IsRunning()) {
- weaponAnimAssoc->flags |= ASSOC_DELETEFADEDOUT;
- weaponAnimAssoc->flags &= ~ASSOC_RUNNING;
- weaponAnimAssoc->blendDelta = -4.0f;
- }
+ // Fun fact: removing this part leds to reloading flamethrower
+ if (ourWeaponType == WEAPONTYPE_FLAMETHROWER && weaponAnimAssoc->IsRunning()) {
+ weaponAnimAssoc->flags |= ASSOC_DELETEFADEDOUT;
+ weaponAnimAssoc->flags &= ~ASSOC_RUNNING;
+ weaponAnimAssoc->blendDelta = -4.0f;
}
}
+
if (weaponAnimAssoc->currentTime > delayBetweenAnimAndFire)
attackShouldContinue = false;
bIsAttacking = attackShouldContinue;
}
+// --MIAMI: Done
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) {
@@ -782,57 +1070,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_WALK_START);
-
- if (animAssoc) {
- animAssoc->flags |= ASSOC_DELETEFADEDOUT;
- animAssoc->blendDelta = -1000.0f;
- }
-
- animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_RUN_STOP);
+ CAnimBlendAssociation* animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_RUN_STOP);
if (!animAssoc)
animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_RUN_STOP_R);
if (animAssoc) {
- animAssoc->flags |= ASSOC_DELETEFADEDOUT;
- animAssoc->blendDelta = -1000.0f;
RestoreHeadingRate();
}
-
SetMoveState(PEDMOVE_NONE);
m_nStoredMoveState = PEDMOVE_NONE;
-
- CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_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_FIGHT_IDLE, 1000.0f);
+ }
} else {
- m_curFightMove = FIGHTMOVE_STDPUNCH;
+ fightIdleAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_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;
@@ -841,6 +1147,7 @@ CPed::StartFightAttack(uint8 buttonPressure)
nPlayerInComboMove = 0;
}
+// --MIAMI: Done
void
CPed::StartFightDefend(uint8 direction, uint8 hitLevel, uint8 unk)
{
@@ -881,13 +1188,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:
@@ -915,22 +1218,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_KO_SPIN_R, false);
- break;
- case 2:
- SetFall(500, ANIM_KO_SKID_BACK, false);
- break;
- case 3:
- SetFall(500, ANIM_KO_SPIN_L, false);
- break;
- default:
- SetFall(500, ANIM_KO_SHOT_STOM, false);
- break;
- }
-#else
bool fall = true;
AnimationId hitAnim;
switch (direction) {
@@ -973,7 +1260,6 @@ CPed::StartFightDefend(uint8 direction, uint8 hitLevel, uint8 unk)
hitAssoc->SetRun();
hitAssoc->flags |= ASSOC_FADEOUTWHENDONE;
}
-#endif
}
Say(SOUND_PED_DEFEND);
} else {
@@ -983,20 +1269,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_KO_SKID_BACK, false);
- return;
- }
-#else
if (direction == 2 && (!IsPlayer() || ((CGeneral::GetRandomNumber() & 1) && m_fHealth < 30.0f))) {
SetFall(1000, ANIM_KO_SKID_BACK, false);
+ Say(SOUND_PED_DEFEND);
return;
} else if (direction != 2 && !IsPlayer() && (CGeneral::GetRandomNumber() & 1) && m_fHealth < 30.0f) {
SetFall(1000, ANIM_KO_SHOT_STOM, false);
+ Say(SOUND_PED_DEFEND);
return;
}
-#endif
m_curFightMove = FIGHTMOVE_HITBODY;
break;
case HITLEVEL_HIGH:
@@ -1046,24 +1327,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 = 0;
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)->m_bFightMode) {
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_WALK_START);
if (walkStartAssoc) {
@@ -1080,25 +1365,51 @@ CPed::StartFightDefend(uint8 direction, uint8 hitLevel, uint8 unk)
}
SetMoveState(PEDMOVE_NONE);
m_nStoredMoveState = PEDMOVE_NONE;
- CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_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_FIGHT_IDLE);
+ }
+ } else {
+ fightIdleAssoc = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_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);
}
}
}
+// --MIAMI: Done
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->m_bFightMode && 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:
@@ -1118,6 +1429,20 @@ CPed::Fight(void)
break;
}
+ if (m_curFightMove == FIGHTMOVE_SHUFFLE_F && !currentAssoc)
+ currentAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_FIGHT_SH_BACK);
+
+ 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;
@@ -1134,272 +1459,123 @@ CPed::Fight(void)
FightMove &curMove = tFightMoves[m_curFightMove];
if (curMove.hitLevel != HITLEVEL_NULL && animTime > curMove.startFireTime && animTime <= curMove.endFireTime && m_fightState >= FIGHTSTATE_NO_MOVE) {
+ if (animTime > curMove.startFireTime && animTime - currentAssoc->timeStep < curMove.startFireTime &&
+ (IsPlayer() || weapon != WEAPONTYPE_UNARMED)) {
+
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_MELEE_ATTACK_START, weapon << 8);
+ }
+
CVector touchingNodePos(0.0f, 0.0f, 0.0f);
switch (m_curFightMove) {
- case FIGHTMOVE_STDPUNCH:
- case FIGHTMOVE_PUNCHHOOK:
- case FIGHTMOVE_BODYBLOW:
- TransformToNode(touchingNodePos, PED_HANDR);
- break;
- case FIGHTMOVE_IDLE:
- case FIGHTMOVE_SHUFFLE_F:
- break;
case FIGHTMOVE_KNEE:
TransformToNode(touchingNodePos, PED_LOWERLEGR);
break;
- case FIGHTMOVE_HEADBUTT:
- TransformToNode(touchingNodePos, PED_HEAD);
- break;
+ case FIGHTMOVE_PUNCHHOOK:
case FIGHTMOVE_PUNCHJAB:
TransformToNode(touchingNodePos, PED_HANDL);
break;
- case FIGHTMOVE_KICK:
case FIGHTMOVE_LONGKICK:
case FIGHTMOVE_ROUNDHOUSE:
+ case FIGHTMOVE_FWDLEFT:
+ case FIGHTMOVE_BACKRIGHT:
case FIGHTMOVE_GROUNDKICK:
TransformToNode(touchingNodePos, PED_FOOTR);
break;
+ case FIGHTMOVE_FWDRIGHT:
+ TransformToNode(touchingNodePos, PED_HEAD);
+ break;
+ case FIGHTMOVE_BACKKICK:
+ case FIGHTMOVE_BACKFLIP:
+ TransformToNode(touchingNodePos, PED_FOOTL);
+ break;
+ case FIGHTMOVE_BACKLEFT:
+ TransformToNode(touchingNodePos, PED_UPPERARML);
+ break;
+ default:
+ TransformToNode(touchingNodePos, PED_HANDR);
+ break;
}
- if (m_curFightMove == FIGHTMOVE_PUNCHJAB) {
- touchingNodePos += 0.1f * GetForward();
- } else if (m_curFightMove == FIGHTMOVE_PUNCHHOOK) {
- touchingNodePos += 0.22f * GetForward();
- }
- FightStrike(touchingNodePos);
+ FightStrike(touchingNodePos, fightWithWeapon);
m_fightButtonPressure = 0;
return;
}
if (curMove.hitLevel != HITLEVEL_NULL) {
- if (animTime > curMove.endFireTime) {
+ if (animTime > curMove.endFireTime && weaponInfo->m_AnimToPlay != ASSOCGRP_KNIFE) {
if (IsPlayer())
currentAssoc->speed = 1.0f;
else
currentAssoc->speed = 0.8f;
}
- if (IsPlayer() && !nPlayerInComboMove) {
+ if (IsPlayer() && !nPlayerInComboMove && !fightWithWeapon) {
if (curMove.comboFollowOnTime > 0.0f && m_fightButtonPressure != 0 && animTime > curMove.comboFollowOnTime) {
+ m_lastFightMove = m_curFightMove;
// Notice that it increases fight move index, because we're in combo!
animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, tFightMoves[++m_curFightMove].animId, 8.0f);
animAssoc->SetFinishCallback(FinishFightMoveCB, this);
animAssoc->SetCurrentTime(0.1f * animAssoc->hierarchy->totalLength);
+ animAssoc->speed = 0.8f;
m_fightButtonPressure = 0;
nPlayerInComboMove = 1;
}
}
- } else {
- if (curMove.startFireTime > 0.0f && m_curFightMove != FIGHTMOVE_SHUFFLE_F && animTime > curMove.startFireTime) {
- if (IsPlayer())
- currentAssoc->speed = 1.3f;
- else
- currentAssoc->speed = 0.8f;
- }
}
- } else if (GetWeapon()->m_eWeaponType != WEAPONTYPE_UNARMED) {
+
+ } else if (GetWeapon()->m_eWeaponType != WEAPONTYPE_UNARMED && GetWeapon()->m_eWeaponType != WEAPONTYPE_BRASSKNUCKLE && !fightWithWeapon) {
EndFight(ENDFIGHT_FAST);
} else if (m_fightButtonPressure != 0) {
- bool canAffectMultiplePeople = true;
- nextAngle = m_fRotationCur;
- bool kickGround = false;
- float angleForGroundKick = 0.0f;
- CPed *pedOnGround = nil;
-
- Say(SOUND_PED_ATTACK);
-
- if (IsPlayer()) {
- canRoundhouse = false;
- punchOnly = false;
- canKick = true;
- nextFightMove = (m_fightButtonPressure > 190 ? FIGHTMOVE_HEADBUTT : FIGHTMOVE_KNEE);
- hasShoppingBags = false;
- canKneeHead = true;
- nPlayerInComboMove = 0;
- } else {
- nextFightMove = (m_fightButtonPressure > 120 ? FIGHTMOVE_HEADBUTT : FIGHTMOVE_KNEE);
- uint16 pedFeatures = m_pedStats->m_flags;
- punchOnly = pedFeatures & STAT_PUNCH_ONLY;
- canRoundhouse = pedFeatures & STAT_CAN_ROUNDHOUSE;
- canKneeHead = pedFeatures & STAT_CAN_KNEE_HEAD;
- canKick = pedFeatures & STAT_CAN_KICK;
- hasShoppingBags = pedFeatures & STAT_SHOPPING_BAGS;
- }
-
- // Attack isn't scripted, find the victim
- if (IsPlayer() || !m_pedInObjective) {
-
- for (int i = 0; i < m_numNearPeds; i++) {
-
- CPed *nearPed = m_nearPeds[i];
- float nearPedDist = (nearPed->GetPosition() - GetPosition()).Magnitude();
- if (nearPedDist < 3.0f) {
- float angleToFace = CGeneral::GetRadianAngleBetweenPoints(
- nearPed->GetPosition().x, nearPed->GetPosition().y,
- GetPosition().x, GetPosition().y);
-
- nextAngle = CGeneral::LimitRadianAngle(angleToFace);
- m_fRotationCur = CGeneral::LimitRadianAngle(m_fRotationCur);
-
- float neededTurn = Abs(nextAngle - m_fRotationCur);
- if (neededTurn > PI)
- neededTurn = TWOPI - neededTurn;
-
- if (!nearPed->OnGroundOrGettingUp()) {
-
- if (nearPedDist < 0.8f && neededTurn < DEGTORAD(75.0f) && canKneeHead) {
- canAffectMultiplePeople = false;
- } else if (nearPedDist >= 1.3f || neededTurn >= DEGTORAD(55.0f) || hasShoppingBags) {
-
- if (nearPedDist < 1.7f
- && neededTurn < DEGTORAD(35.0f)
- && (canKick || hasShoppingBags)) {
-
- 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;
+ if (!IsPlayer())
+ Say(SOUND_PED_ATTACK);
- 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;
- }
+ if (m_curFightMove != FIGHTMOVE_IDLE)
+ m_lastFightMove = m_curFightMove;
- } else if (nearPed->m_nPedState != PED_DEAD || pedOnGround) {
- if (!nearPed->IsPedHeadAbovePos(-0.3f)) {
- canAffectMultiplePeople = false;
- nextFightMove = FIGHTMOVE_GROUNDKICK;
- }
+ m_curFightMove = IsPlayer() ? ChooseAttackPlayer(m_fightButtonPressure, fightWithWeapon) : ChooseAttackAI(m_fightButtonPressure, fightWithWeapon);
- } 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;
@@ -1409,6 +1585,7 @@ CPed::Fight(void)
#else
&& CheckForPedsOnGroundToAttack(this, nil) == PED_IN_FRONT_OF_ATTACKER) {
#endif
+ m_lastFightMove = m_curFightMove;
m_curFightMove = FIGHTMOVE_SHUFFLE_F;
animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), tFightMoves[m_curFightMove].animId);
@@ -1433,6 +1610,7 @@ CPed::Fight(void)
}
} else {
+ m_lastFightMove = m_curFightMove;
m_curFightMove = FIGHTMOVE_IDLE;
if (IsPlayer())
m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 500;
@@ -1441,6 +1619,335 @@ CPed::Fight(void)
}
}
+// --MIAMI: Done
+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->m_bGround2nd)
+ return FIGHTMOVE_MELEE2;
+ if (weaponInfo->m_bGround3rd)
+ 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;
+}
+
+// --MIAMI: Done
+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->m_bGround2nd) {
+ choosenMove = FIGHTMOVE_MELEE2;
+ } else if (fightWithWeapon && weaponInfo->m_bGround3rd) {
+ 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;
+}
+
+// --MIAMI: Done
void
CPed::EndFight(uint8 endType)
{
@@ -1450,6 +1957,9 @@ CPed::EndFight(uint8 endType)
m_curFightMove = FIGHTMOVE_NULL;
RestorePreviousState();
CAnimBlendAssociation *animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_FIGHT_IDLE);
+ if (!animAssoc)
+ animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_MELEE_IDLE_FIGHTMODE);
+
if (animAssoc)
animAssoc->flags |= ASSOC_DELETEFADEDOUT;
@@ -1472,49 +1982,67 @@ CPed::EndFight(uint8 endType)
m_nWaitTimer = 0;
}
-
+// --MIAMI: Done
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) | 3);
+ } else {
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_KNIFE_ATTACK, (weapon << 8) | 3);
+ }
+ 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];
@@ -1527,173 +2055,257 @@ CPed::PlayHitSound(CPed *hitTo)
}
if (soundId != NO_SND)
- DMAudio.PlayOneShot(m_audioEntityId, soundId, 0.0f);
+ DMAudio.PlayOneShot(m_audioEntityId, soundId, (weapon << 8) | 3);
}
+// --MIAMI: Done
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;
- if (state == FIGHTSTATE_JUST_ATTACKED)
+ CWeaponInfo *weaponInfo = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType);
+ float radius = tFightMoves[m_curFightMove].strikeRadius;
+ if (fightWithWeapon)
+ radius = weaponInfo->m_fRadius;
+
+ 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;
- 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;
+ m_vecHitLastPos = touchedNodePos;
+ return false;
+}
+
+// --MIAMI: Done
+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->m_bFightMode) {
+ 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();
}
- if (!nearPed->OnGround()) {
- float curVictimHealth = nearPed->m_fHealth;
+ CParticle::AddParticle(PARTICLE_BLOOD_SPURT, bloodPos, dir, nil, 0.0f, 0, 0, 0, 0);
+ CParticle::AddParticle(PARTICLE_BLOOD_SPURT, bloodPos, dir, nil, 0.0f, 0, 0, 0, 0);
+ if (IsPlayer()) {
+ CParticle::AddParticle(PARTICLE_BLOOD_SPURT, bloodPos, dir, nil, 0.0f, 0, 0, 0, 0);
+ CParticle::AddParticle(PARTICLE_BLOOD_SPURT, bloodPos, dir, nil, 0.0f, 0, 0, 0, 0);
+ }
+ if (!(CGeneral::GetRandomNumber() & 3)) {
+ CParticle::AddParticle(PARTICLE_TEST, bloodPos, dir, nil, 0.0f, 0, 0, 0, 0);
+ }
+ } else if (CGame::nastyGame && (tFightMoves[m_curFightMove].hitLevel > HITLEVEL_MEDIUM || fightingWithWeapon)
+ && victim->GetIsOnScreen()) {
+
+ // Just for particles. We will restore it below.
+ dir /= (10.0f * dir.Magnitude());
+ for (int i = 0; i < 4; i++) {
+ CParticle::AddParticle(PARTICLE_BLOOD, bloodPos, dir, nil, 0.0f, 0, 0, 0, 0);
+ }
+ }
+
+ 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_KO_SKID_FRONT), 0);
- if (nearPed->m_nPedState == PED_FALL)
- nearPed->bIsStanding = false;
+ victim->SetFall(0, (AnimationId)(direction + ANIM_KO_SKID_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);
+ }
}
+// --MIAMI: Done
void
CPed::FinishFightMoveCB(CAnimBlendAssociation *animAssoc, void *arg)
{
@@ -1705,10 +2317,11 @@ CPed::FinishFightMoveCB(CAnimBlendAssociation *animAssoc, void *arg)
}
}
+// --MIAMI: Done
void
CPed::LoadFightData(void)
{
- float startFireTime, endFireTime, comboFollowOnTime, strikeRadius;
+ float startFireTime, endFireTime, comboFollowOnTime, strikeRadius, extendReachMultiplier;
int damage, flags;
char line[256], moveName[32], animName[32], hitLevel;
int moveId = 0;
@@ -1737,12 +2350,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,
@@ -1755,6 +2369,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;
@@ -1778,16 +2393,19 @@ CPed::LoadFightData(void)
break;
}
- if (strncmp(animName, "null", 4) != 0) {
- animAssoc = CAnimManager::GetAnimAssociation(ASSOCGRP_STD, animName);
- tFightMoves[moveId].animId = (AnimationId)animAssoc->animId;
- } else {
- tFightMoves[moveId].animId = ANIM_WALK;
+ if (strncmp(animName, "default", 8) != 0) {
+ if (strncmp(animName, "null", 5) != 0) {
+ animAssoc = CAnimManager::GetAnimAssociation(ASSOCGRP_STD, animName);
+ tFightMoves[moveId].animId = (AnimationId)animAssoc->animId;
+ } else {
+ tFightMoves[moveId].animId = ANIM_WALK;
+ }
}
moveId++;
}
}
+// --MIAMI: Done
void
CPed::SetInvestigateEvent(eEventType event, CVector2D pos, float distanceToCountDone, uint16 time, float angle)
{
@@ -1810,6 +2428,7 @@ CPed::SetInvestigateEvent(eEventType event, CVector2D pos, float distanceToCount
}
+// --MIAMI: Done
void
CPed::InvestigateEvent(void)
{
@@ -1823,7 +2442,7 @@ CPed::InvestigateEvent(void)
if (CTimer::GetTimeInMilliseconds() > m_standardTimer) {
if (m_standardTimer) {
- if (m_eventType < EVENT_ASSAULT_NASTYWEAPON)
+ if (m_eventType < EVENT_UNK)
SetWaitState(WAITSTATE_TURN180, nil);
m_standardTimer = 0;
@@ -1883,7 +2502,8 @@ CPed::InvestigateEvent(void)
} else if (CGeneral::GetRandomNumber() & 3) {
CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_IDLE_CAM, 4.0f);
SetLookTimer(CGeneral::GetRandomNumberInRange(2500, 5000));
- Say(SOUND_PED_CHAT_EVENT);
+ if (!CGame::germanGame)
+ Say(SOUND_PED_CHAT_EVENT);
} else {
m_standardTimer = 0;
@@ -1932,7 +2552,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:
@@ -1999,17 +2620,21 @@ 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);
}
}
+// --MIAMI: Done
void
CPed::ClearInvestigateEvent(void)
{
@@ -2035,6 +2660,7 @@ CPed::ClearInvestigateEvent(void)
SetMoveState(PEDMOVE_WALK);
}
+// --MIAMI: Done
bool
CPed::InflictDamage(CEntity *damagedBy, eWeaponType method, float damage, ePedPieceTypes pedPiece, uint8 direction)
{
@@ -2046,17 +2672,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() &&
@@ -2069,8 +2707,12 @@ CPed::InflictDamage(CEntity *damagedBy, eWeaponType method, float damage, ePedPi
else
healthImpact = damage * m_pedStats->m_defendWeakness;
+ if (!IsPlayer() &&
+ (method == WEAPONTYPE_SCREWDRIVER || method == WEAPONTYPE_KNIFE || (method >= WEAPONTYPE_CLEAVER && method <= WEAPONTYPE_CHAINSAW)))
+ m_bleedCounter = 200;
+
bool detectDieAnim = true;
- if (m_nPedState == PED_FALL || m_nPedState == PED_GETUP) {
+ if (m_nPedState == PED_GETUP) {
if (!IsPedHeadAbovePos(-0.3f)) {
if (RpAnimBlendClumpGetFirstAssociation(GetClump(), ASSOC_FRONTAL))
dieAnim = ANIM_FLOOR_HIT_F;
@@ -2079,20 +2721,36 @@ CPed::InflictDamage(CEntity *damagedBy, eWeaponType method, float damage, ePedPi
dieDelta *= 2.0f;
dieSpeed = 0.5f;
detectDieAnim = false;
- } else if (m_nPedState == PED_FALL) {
- dieAnim = NUM_ANIMS;
- detectDieAnim = false;
}
+ } else if (m_nPedState == PED_FALL) {
+ CAnimBlendAssociation *fallAssoc = RpAnimBlendClumpGetFirstAssociation(GetClump(), ASSOC_PARTIAL);
+ if (!fallAssoc || fallAssoc->IsRunning()) {
+ if (fallAssoc && fallAssoc->blendDelta >= 0.0f)
+ dieAnim = NUM_STD_ANIMS;
+ else
+ dieAnim = ANIM_KO_SHOT_FRONT1;
+ } else {
+ if (fallAssoc->flags & ASSOC_FRONTAL)
+ dieAnim = ANIM_FLOOR_HIT_F;
+ else
+ dieAnim = ANIM_FLOOR_HIT;
+
+ dieDelta *= 2.0f;
+ dieSpeed = 0.5f;
+ }
+ detectDieAnim = false;
}
+
if (detectDieAnim) {
switch (method) {
case WEAPONTYPE_UNARMED:
+ case WEAPONTYPE_BRASSKNUCKLE:
if (bMeleeProof)
return false;
if (m_nPedState == PED_FALL) {
if (IsPedHeadAbovePos(-0.3f)) {
- dieAnim = NUM_ANIMS;
+ dieAnim = NUM_STD_ANIMS;
} else {
if (RpAnimBlendClumpGetFirstAssociation(GetClump(), ASSOC_FRONTAL))
dieAnim = ANIM_FLOOR_HIT_F;
@@ -2120,68 +2778,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 = NUM_ANIMS;
+ 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 = NUM_STD_ANIMS;
+ } else {
+ if (RpAnimBlendClumpGetFirstAssociation(GetClump(), ASSOC_FRONTAL))
+ dieAnim = ANIM_FLOOR_HIT_F;
+ else
+ dieAnim = ANIM_FLOOR_HIT;
+ dieDelta = dieDelta * 2.0f;
+ dieSpeed = 0.5f;
+ }
+ } else if (damagedBy != FindPlayerPed() || FindPlayerPed()->m_curFightMove != FIGHTMOVE_MELEE2) {
+ if (damagedBy != FindPlayerPed() || FindPlayerPed()->m_curFightMove != FIGHTMOVE_MELEE3) {
+ switch (direction) {
+ case 0:
+ dieAnim = ANIM_KO_SKID_FRONT;
+ break;
+ case 1:
+ dieAnim = ANIM_KO_SPIN_R;
+ break;
+ case 2:
+ dieAnim = ANIM_KO_SKID_BACK;
+ break;
+ case 3:
+ dieAnim = ANIM_KO_SPIN_L;
+ break;
+ default:
+ break;
+ }
+ } else {
+ dieAnim = ANIM_KO_SHOT_STOM;
+ }
} else {
- if (RpAnimBlendClumpGetFirstAssociation(GetClump(), ASSOC_FRONTAL))
- dieAnim = ANIM_FLOOR_HIT_F;
- else
- dieAnim = ANIM_FLOOR_HIT;
- dieDelta = dieDelta * 2.0f;
- dieSpeed = 0.5f;
+ dieAnim = ANIM_KO_SHOT_FACE;
}
} else {
- switch (direction) {
- case 0:
- dieAnim = ANIM_KO_SKID_FRONT;
- break;
- case 1:
- dieAnim = ANIM_KO_SPIN_R;
- break;
- case 2:
- dieAnim = ANIM_KO_SKID_BACK;
- break;
- case 3:
- dieAnim = ANIM_KO_SPIN_L;
- break;
- default:
- break;
- }
+ dieAnim = ANIM_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) {
@@ -2246,8 +2933,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;
@@ -2344,7 +3031,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();
@@ -2403,6 +3090,16 @@ CPed::InflictDamage(CEntity *damagedBy, eWeaponType method, float damage, ePedPi
CWorld::Players[CWorld::PlayerInFocus].m_nTimeLastHealthLoss = CTimer::GetTimeInMilliseconds();
m_lastWepDam = method;
+ m_lastDamEntity = damagedBy;
+ }
+
+ if (method == WEAPONTYPE_FALL) {
+ if (RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_ROLLOUT_LHS)) {
+ if (m_fHealth >= 1.0 && m_fHealth - healthImpact < 5.0f) {
+ m_fHealth = Min(m_fHealth, 5.0f);
+ return false;
+ }
+ }
}
if (m_fHealth - healthImpact >= 1.0f && !willLinger) {
@@ -2412,40 +3109,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);
@@ -2455,8 +3161,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;
}
@@ -2464,22 +3171,25 @@ CPed::InflictDamage(CEntity *damagedBy, eWeaponType method, float damage, ePedPi
if (player == this)
m_pMyVehicle->SetStatus(STATUS_PLAYER_DISABLED);
- SetDie(NUM_ANIMS, 4.0f, 0.0f);
+ SetDie(NUM_STD_ANIMS, 4.0f, 0.0f);
return true;
} else {
m_fHealth = 0.0f;
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;
}
@@ -2522,6 +3232,7 @@ RecurseFrameChildrenToCloneCB(RwFrame *frame, void *data)
return newFrame;
}
+// --MIAMI: Done
void
CPed::RemoveBodyPart(PedNode nodeId, int8 direction)
{
@@ -2531,25 +3242,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);
@@ -2569,90 +3263,16 @@ CPed::RemoveBodyPart(PedNode nodeId, int8 direction)
}
}
+// --MIAMI: Done
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;
}
+// --MIAMI: Done
+// III leftover and unused
void
CPed::ApplyHeadShot(eWeaponType weaponType, CVector pos, bool evenOnPlayer)
{
@@ -2667,12 +3287,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_KO_SHOT_FRONT1, 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);
@@ -2693,36 +3314,14 @@ 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
-}
-
+// --MIAMI: Done
bool
CPed::IsPedHeadAbovePos(float zOffset)
{
return zOffset + GetPosition().z < GetNodePosition(PED_HEAD).z;
}
+// --MIAMI: Done
bool
CPed::PlacePedOnDryLand(void)
{
@@ -2774,6 +3373,7 @@ CPed::PlacePedOnDryLand(void)
return true;
}
+// --MIAMI: Done
void
CPed::CollideWithPed(CPed *collideWith)
{
@@ -2786,6 +3386,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;
@@ -2793,10 +3402,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) {
@@ -2825,14 +3432,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 {
@@ -2847,20 +3495,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;
@@ -2869,11 +3511,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
@@ -2893,9 +3532,7 @@ CPed::CollideWithPed(CPed *collideWith)
TurnBody();
animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_FIGHT_PPUNCH, 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);
@@ -2905,11 +3542,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();
@@ -2939,7 +3574,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_FIGHT_46, 0.0f);
}
} else {
// We're at his right side
@@ -2962,7 +3597,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);
}
@@ -3005,6 +3640,7 @@ CPed::CollideWithPed(CPed *collideWith)
}
}
+// --MIAMI: Done
void
CPed::KillPedWithCar(CVehicle *car, float impulse)
{
@@ -3015,8 +3651,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;
}
@@ -3024,7 +3660,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;
}
@@ -3086,7 +3722,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;
@@ -3131,7 +3767,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;
@@ -3146,7 +3782,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) {
@@ -3195,9 +3831,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);
@@ -3216,7 +3850,7 @@ CPed::KillPedWithCar(CVehicle *car, float impulse)
SetFall(1000, (AnimationId)(fallDirection + ANIM_KO_SKID_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;
}
@@ -3227,15 +3861,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()
@@ -3246,5 +3876,349 @@ CPed::KillPedWithCar(CVehicle *car, float impulse)
RegisterThreatWithGangPeds(driver);
}
}
-#endif
-} \ No newline at end of file
+}
+
+// --MIAMI: Done
+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_STILL);
+ CAnimBlendAssociation *fwdAssoc, *backAssoc;
+ if (IsPlayer()) {
+ fwdAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_BIKE_FWD);
+ backAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_BIKE_BACK);
+ }
+ CAnimBlendAssociation *walkbackAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_BIKE_PUSHES);
+ CAnimBlendAssociation *drivebyAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_BIKE_DRIVEBY_RHS);
+ if (!drivebyAssoc)
+ drivebyAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_BIKE_DRIVEBY_LHS);
+ if (!drivebyAssoc)
+ drivebyAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_BIKE_DRIVEBY_FT);
+
+ 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_STILL, 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_PUSHES, 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.fUnkMaxVelocity > 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_FWD);
+ if (!backAssoc)
+ backAssoc = CAnimManager::AddAnimation(GetClump(), bike->m_bikeAnimType, ANIM_BIKE_BACK);
+
+ 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_DRIVE_BOAT);
+
+ if (!sitAssoc || sitAssoc->blendAmount < 1.0f) {
+ return;
+ }
+
+ lDriveAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DRIVE_BOAT_L);
+ rDriveAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DRIVE_BOAT_R);
+ lbAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_BOAT_LB);
+ } else if (m_pMyVehicle->bLowVehicle) {
+ sitAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_LSIT);
+
+ if (!sitAssoc || sitAssoc->blendAmount < 1.0f) {
+ return;
+ }
+
+ lDriveAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DRIVE_LOW_L);
+ lbAssoc = nil;
+ rDriveAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DRIVE_LOW_R);
+ } else {
+ sitAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_SIT);
+
+ if (!sitAssoc || sitAssoc->blendAmount < 1.0f) {
+ return;
+ }
+
+ lDriveAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DRIVE_L);
+ rDriveAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DRIVE_R);
+ lbAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_LB);
+ }
+
+ if (lbAssoc &&
+ TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_1STPERSON
+ && TheCamera.Cams[TheCamera.ActiveCam].DirectionWasLooking == LOOKING_LEFT) {
+ lbAssoc->blendDelta = -1000.0f;
+ }
+
+ CAnimBlendAssociation* driveByAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DRIVEBY_L);
+ if (!driveByAssoc)
+ driveByAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DRIVEBY_R);
+ if (!driveByAssoc)
+ driveByAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DRIVEBY_LOW_L);
+ if (!driveByAssoc)
+ driveByAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DRIVEBY_LOW_R);
+
+ if (m_pMyVehicle->bLowVehicle || m_pMyVehicle->m_fGasPedal >= 0.0f || driveByAssoc ||
+ 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_DRIVE_BOAT_R);
+ else if (m_pMyVehicle->bLowVehicle)
+ CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_DRIVE_LOW_R);
+ else
+ CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_DRIVE_R);
+
+ } 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_DRIVE_BOAT_L);
+ else if (m_pMyVehicle->bLowVehicle)
+ CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_DRIVE_LOW_L);
+ else
+ CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_DRIVE_L);
+ }
+
+ 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_BOAT_LB, 4.0f);
+ else
+ CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_LB, 4.0f);
+ }
+ }
+}
+
+// --MIAMI: Done
+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_WEAPON_CROUCHRELOAD);
+ if (weaponAssoc) {
+ weaponAssoc->flags |= ASSOC_DELETEFADEDOUT;
+ if (weaponAssoc->flags & ASSOC_PARTIAL)
+ weaponAssoc->blendDelta = animDelta;
+ else
+ CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_IDLE_STANCE, -animDelta);
+ }
+}
diff --git a/src/peds/PedIK.cpp b/src/peds/PedIK.cpp
index 8bace9a0..2925667a 100644
--- a/src/peds/PedIK.cpp
+++ b/src/peds/PedIK.cpp
@@ -7,11 +7,13 @@
#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) };
+//--MIAMI: file done
+
+LimbMovementInfo CPedIK::ms_torsoInfo = { DEGTORAD(50.0f), DEGTORAD(-50.0f), DEGTORAD(8.0f), DEGTORAD(45.0f), DEGTORAD(-45.0f), DEGTORAD(5.0f) };
+LimbMovementInfo CPedIK::ms_headInfo = { DEGTORAD(90.0f), DEGTORAD(-90.0f), DEGTORAD(15.0f), DEGTORAD(45.0f), DEGTORAD(-45.0f), DEGTORAD(8.0f) };
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 +33,6 @@ CPedIK::CPedIK(CPed *ped)
m_lowerArmOrient.pitch = 0.0f;
}
-#ifdef PED_SKIN
inline RwMatrix*
GetBoneMatrix(CPed *ped, int32 bone)
{
@@ -45,134 +46,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 +69,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 +87,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 +113,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 +176,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 +190,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 +226,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 +314,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 +359,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 +367,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 4eeef6f0..ee719fea 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..8012650a 100644
--- a/src/peds/PedPlacement.cpp
+++ b/src/peds/PedPlacement.cpp
@@ -4,7 +4,8 @@
#include "PedPlacement.h"
#include "World.h"
-void
+// --MIAMI: Done
+bool
CPedPlacement::FindZCoorForPed(CVector* pos)
{
float zForPed;
@@ -32,8 +33,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 +47,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/PedRoutes.cpp b/src/peds/PedRoutes.cpp
index 3ff080e6..2de90eae 100644
--- a/src/peds/PedRoutes.cpp
+++ b/src/peds/PedRoutes.cpp
@@ -3,6 +3,8 @@
#include "main.h"
#include "PedRoutes.h"
+// --MIAMI: file done
+
CRouteNode gaRoutes[NUMPEDROUTES];
void
diff --git a/src/peds/PedType.cpp b/src/peds/PedType.cpp
index 6e745bd7..e16fcee6 100644
--- a/src/peds/PedType.cpp
+++ b/src/peds/PedType.cpp
@@ -4,6 +4,8 @@
#include "FileMgr.h"
#include "PedType.h"
+// --MIAMI: file done
+
CPedType *CPedType::ms_apPedType[NUM_PEDTYPES];
CPedStats *CPedStats::ms_apPedStats[NUM_PEDSTATS];
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 8a6adbeb..74db3055 100644
--- a/src/peds/PlayerPed.cpp
+++ b/src/peds/PlayerPed.cpp
@@ -16,21 +16,38 @@
#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"
#define PAD_MOVE_TO_GAME_WORLD_MOVE 60.0f
+bool CPlayerPed::bDontAllowWeaponChange;
+
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;
}
+// --MIAMI: Done
CPlayerPed::CPlayerPed(void) : CPed(PEDTYPE_PLAYER1)
{
m_fMoveSpeed = 0.0f;
@@ -44,7 +61,7 @@ CPlayerPed::CPlayerPed(void) : CPed(PEDTYPE_PLAYER1)
m_pWanted->Initialise();
m_pArrestingCop = nil;
m_currentWeapon = WEAPONTYPE_UNARMED;
- m_nSelectedWepSlot = WEAPONTYPE_UNARMED;
+ m_nSelectedWepSlot = 0;
m_nSpeedTimer = 0;
m_bSpeedTimerFlag = false;
SetWeaponLockOnTarget(nil);
@@ -54,23 +71,34 @@ 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()
+// --MIAMI: Done
+void
+CPlayerPed::ClearWeaponTarget()
{
if (m_nPedType == PEDTYPE_PLAYER1) {
SetWeaponLockOnTarget(nil);
@@ -80,33 +108,33 @@ void CPlayerPed::ClearWeaponTarget()
ClearPointGunAt();
}
+// --MIAMI: Done
void
CPlayerPed::SetWantedLevel(int32 level)
{
m_pWanted->SetWantedLevel(level);
}
+// --MIAMI: Done
void
CPlayerPed::SetWantedLevelNoDrop(int32 level)
{
m_pWanted->SetWantedLevelNoDrop(level);
}
+// --MIAMI: Done
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;
}
}
}
+// --MIAMI: Done
// I don't know the actual purpose of parameter
void
CPlayerPed::AnnoyPlayerPed(bool annoyedByPassingEntity)
@@ -120,6 +148,7 @@ CPlayerPed::AnnoyPlayerPed(bool annoyedByPassingEntity)
}
}
+// --MIAMI: Done
void
CPlayerPed::ClearAdrenaline(void)
{
@@ -129,6 +158,7 @@ CPlayerPed::ClearAdrenaline(void)
}
}
+// --MIAMI: Done
CPlayerInfo *
CPlayerPed::GetPlayerInfoForThisPlayerPed()
{
@@ -138,6 +168,7 @@ CPlayerPed::GetPlayerInfoForThisPlayerPed()
return nil;
}
+// --MIAMI: Done
void
CPlayerPed::SetupPlayerPed(int32 index)
{
@@ -153,18 +184,21 @@ CPlayerPed::SetupPlayerPed(int32 index)
player->m_wepAccuracy = 100;
}
+// --MIAMI: Done
void
CPlayerPed::DeactivatePlayerPed(int32 index)
{
CWorld::Remove(CWorld::Players[index].m_pPed);
}
+// --MIAMI: Done
void
CPlayerPed::ReactivatePlayerPed(int32 index)
{
CWorld::Add(CWorld::Players[index].m_pPed);
}
+// --MIAMI: Done
void
CPlayerPed::UseSprintEnergy(void)
{
@@ -181,21 +215,24 @@ CPlayerPed::UseSprintEnergy(void)
}
}
+// --MIAMI: Done
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)->m_bCanAim))
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;
@@ -203,6 +240,15 @@ CPlayerPed::MakeChangesForNewWeapon(int8 weapon)
TheCamera.ClearPlayerWeaponMode();
}
+// --MIAMI: Done
+void
+CPlayerPed::MakeChangesForNewWeapon(int32 slot)
+{
+ if(slot != -1)
+ MakeChangesForNewWeapon(m_weapons[slot].m_eWeaponType);
+}
+
+// --MIAMI: Done
void
CPlayerPed::ReApplyMoveAnims(void)
{
@@ -222,16 +268,20 @@ CPlayerPed::ReApplyMoveAnims(void)
}
}
+// --MIAMI: Done
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 = { 0.0f, 0.0f, 0.0f };
- m_fleeFromPosX = 0.0f;
- m_fleeFromPosY = 0.0f;
+ m_vecSeekPos = CVector(0.0f, 0.0f, 0.0f);
+ m_fleeFromPos = CVector2D(0.0f, 0.0f);
m_fleeFrom = nil;
m_fleeTimer = 0;
m_objective = OBJECTIVE_NONE;
@@ -243,6 +293,7 @@ CPlayerPed::SetInitialState(void)
bRenderPedInCar = true;
if (m_pFire)
m_pFire->Extinguish();
+
RpAnimBlendClumpRemoveAllAssociations(GetClump());
SetPedState(PED_IDLE);
SetMoveState(PEDMOVE_STILL);
@@ -257,8 +308,14 @@ 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;
}
+// --MIAMI: Done
void
CPlayerPed::SetRealMoveAnim(void)
{
@@ -283,6 +340,8 @@ CPlayerPed::SetRealMoveAnim(void)
curIdleAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_TIRED);
if (!curIdleAssoc)
curIdleAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_FIGHT_IDLE);
+ if (!curIdleAssoc)
+ curIdleAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_MELEE_IDLE_FIGHTMODE);
if (!((curRunStopAssoc && curRunStopAssoc->IsRunning()) || (curRunStopRAssoc && curRunStopRAssoc->IsRunning()))) {
@@ -299,7 +358,7 @@ CPlayerPed::SetRealMoveAnim(void)
RestoreHeadingRate();
if (!curIdleAssoc) {
- if (m_fCurrentStamina < 0.0f && !CWorld::TestSphereAgainstWorld(GetPosition(), 0.0f,
+ if (m_fCurrentStamina < 0.0f && !bIsAimingGun && !CWorld::TestSphereAgainstWorld(GetPosition(), 0.0f,
nil, true, false, false, false, false, false)) {
curIdleAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_IDLE_TIRED, 8.0f);
@@ -313,7 +372,7 @@ CPlayerPed::SetRealMoveAnim(void)
} else if (m_fMoveSpeed == 0.0f && !curSprintAssoc) {
if (!curIdleAssoc) {
- if (m_fCurrentStamina < 0.0f && !CWorld::TestSphereAgainstWorld(GetPosition(), 0.0f,
+ if (m_fCurrentStamina < 0.0f && !bIsAimingGun && !CWorld::TestSphereAgainstWorld(GetPosition(), 0.0f,
nil, true, false, false, false, false, false)) {
curIdleAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_IDLE_TIRED, 4.0f);
@@ -324,11 +383,11 @@ CPlayerPed::SetRealMoveAnim(void)
m_nWaitTimer = CTimer::GetTimeInMilliseconds() + CGeneral::GetRandomNumberInRange(2500, 4000);
}
- if (m_fCurrentStamina > 0.0f && curIdleAssoc->animId == ANIM_IDLE_TIRED) {
+ if ((m_fCurrentStamina > 0.0f || bIsAimingGun) && curIdleAssoc->animId == ANIM_IDLE_TIRED) {
CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_IDLE_STANCE, 4.0f);
} else if (m_nPedState != PED_FIGHT) {
- if (m_fCurrentStamina < 0.0f && curIdleAssoc->animId != ANIM_IDLE_TIRED
+ if (m_fCurrentStamina < 0.0f && !bIsAimingGun && curIdleAssoc->animId != ANIM_IDLE_TIRED
&& !CWorld::TestSphereAgainstWorld(GetPosition(), 0.0f, nil, true, false, false, false, false, false)) {
CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_IDLE_TIRED, 4.0f);
@@ -353,7 +412,10 @@ CPlayerPed::SetRealMoveAnim(void)
delete curIdleAssoc;
delete RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_TIRED);
- delete RpAnimBlendClumpGetAssociation(GetClump(), ANIM_FIGHT_IDLE);
+ CAnimBlendAssociation *fightIdleAnim = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_FIGHT_IDLE);
+ if (!fightIdleAnim)
+ fightIdleAnim = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_MELEE_IDLE_FIGHTMODE);
+ delete fightIdleAnim;
delete curSprintAssoc;
curSprintAssoc = nil;
@@ -398,7 +460,7 @@ CPlayerPed::SetRealMoveAnim(void)
} else if (curSprintAssoc->blendDelta >= 0.0f || curSprintAssoc->blendAmount >= 0.8f) {
if (m_fMoveSpeed < 0.4f) {
AnimationId runStopAnim;
- if (curSprintAssoc->currentTime / curSprintAssoc->hierarchy->totalLength < 0.5) // double
+ if (curSprintAssoc->GetProgress() < 0.5) // double
runStopAnim = ANIM_RUN_STOP;
else
runStopAnim = ANIM_RUN_STOP_R;
@@ -461,6 +523,8 @@ CPlayerPed::SetRealMoveAnim(void)
curRunAssoc->blendAmount = 1.0f;
m_nMoveState = PEDMOVE_RUN;
}
+ curWalkAssoc->blendDelta = 0.0f;
+ curRunAssoc->blendDelta = 0.0f;
}
}
}
@@ -487,9 +551,15 @@ 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;
}
}
+// --MIAMI: Done
void
CPlayerPed::RestoreSprintEnergy(float restoreSpeed)
{
@@ -497,18 +567,57 @@ CPlayerPed::RestoreSprintEnergy(float restoreSpeed)
m_fCurrentStamina += restoreSpeed * CTimer::GetTimeStep() * 0.5f;
}
-bool
+// --MIAMI: Done
+float
CPlayerPed::DoWeaponSmoothSpray(void)
{
if (m_nPedState == PED_ATTACK && !m_pPointGunAt) {
- eWeaponType weapon = GetWeapon()->m_eWeaponType;
- 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;
+ 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)))
+ 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;
}
+// --MIAMI: Done
void
CPlayerPed::DoStuffToGoOnFire(void)
{
@@ -516,6 +625,7 @@ CPlayerPed::DoStuffToGoOnFire(void)
TheCamera.ClearPlayerWeaponMode();
}
+// --MIAMI: Done
bool
CPlayerPed::DoesTargetHaveToBeBroken(CVector target, CWeapon *weaponUsed)
{
@@ -524,17 +634,10 @@ 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;
}
+// --MIAMI: Done
// Cancels landing anim while running & jumping? I think
void
CPlayerPed::RunningLand(CPad *padUsed)
@@ -553,9 +656,13 @@ CPlayerPed::RunningLand(CPad *padUsed)
}
}
+// --MIAMI: Done
bool
-CPlayerPed::IsThisPedAttackingPlayer(CPed *suspect)
+CPlayerPed::IsThisPedAnAimingPriority(CPed *suspect)
{
+ if (!suspect->bIsPlayerFriend)
+ return true;
+
if (suspect->m_pPointGunAt == this)
return true;
@@ -569,108 +676,171 @@ CPlayerPed::IsThisPedAttackingPlayer(CPed *suspect)
default:
break;
}
- return false;
+ return suspect->m_nPedState == PED_ABSEIL;
}
+// --MIAMI: Done
void
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);
}
+// --MIAMI: Done
// 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 (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 (!m_pPointGunAt && !bDontAllowWeaponChange && GetWeapon()->m_eWeaponType != WEAPONTYPE_DETONATOR) {
+ if (padUsed->CycleWeaponRightJustDown()) {
- for (m_nSelectedWepSlot = m_currentWeapon + 1; m_nSelectedWepSlot < WEAPONTYPE_TOTAL_INVENTORY_WEAPONS; ++m_nSelectedWepSlot) {
- if (HasWeapon(m_nSelectedWepSlot) && GetWeapon(m_nSelectedWepSlot).HasWeaponAmmoToBeUsed()) {
- goto switchDetectDone;
+ 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 < 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) {
+ } 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) {
- for (m_nSelectedWepSlot = m_currentWeapon - 1; ; --m_nSelectedWepSlot) {
- if (m_nSelectedWepSlot < WEAPONTYPE_UNARMED)
- m_nSelectedWepSlot = WEAPONTYPE_DETONATOR;
+ for (m_nSelectedWepSlot = m_currentWeapon - 1; ; --m_nSelectedWepSlot) {
+ if (m_nSelectedWepSlot < 0)
+ m_nSelectedWepSlot = TOTAL_WEAPON_SLOTS - 1;
- if (HasWeapon(m_nSelectedWepSlot) && GetWeapon(m_nSelectedWepSlot).HasWeaponAmmoToBeUsed()) {
- goto switchDetectDone;
+ if (m_nSelectedWepSlot == 0)
+ break;
+
+ if (HasWeaponSlot(m_nSelectedWepSlot) && GetWeapon(m_nSelectedWepSlot).HasWeaponAmmoToBeUsed()) {
+ break;
+ }
}
}
}
- } else if (CWeaponInfo::GetWeaponInfo((eWeaponType)m_currentWeapon)->m_eWeaponFire != WEAPON_FIRE_MELEE) {
- if (GetWeapon(m_currentWeapon).m_nAmmoTotal <= 0) {
- if (TheCamera.PlayerWeaponMode.Mode != CCam::MODE_M16_1STPERSON
- && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_SNIPER
- && TheCamera.PlayerWeaponMode.Mode != CCam::MODE_ROCKETLAUNCHER) {
+ }
+
+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) {
- goto switchDetectDone;
- }
+ if (GetWeapon()->m_eWeaponType != WEAPONTYPE_DETONATOR
+ || GetWeapon(2).m_eWeaponType != WEAPONTYPE_DETONATOR_GRENADE)
+ m_nSelectedWepSlot = m_currentWeapon - 1;
+ else
+ m_nSelectedWepSlot = 2;
+
+ for (; m_nSelectedWepSlot >= 0; --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 == 1 || GetWeapon(m_nSelectedWepSlot).m_nAmmoTotal > 0 && m_nSelectedWepSlot != 2) {
+#else
+ if (m_nSelectedWepSlot == WEAPONTYPE_BASEBALLBAT && GetWeapon(WEAPONTYPE_BASEBALLBAT).m_eWeaponType == WEAPONTYPE_BASEBALLBAT
+ || GetWeapon(m_nSelectedWepSlot).m_nAmmoTotal > 0
+ && m_nSelectedWepSlot != WEAPONTYPE_MOLOTOV && m_nSelectedWepSlot != WEAPONTYPE_GRENADE && m_nSelectedWepSlot != WEAPONTYPE_TEARGAS) {
+#endif
+ goto switchDetectDone;
}
- m_nSelectedWepSlot = WEAPONTYPE_UNARMED;
}
+ m_nSelectedWepSlot = 0;
}
}
switchDetectDone:
if (m_nSelectedWepSlot != m_currentWeapon) {
if (m_nPedState != PED_ATTACK && m_nPedState != PED_AIM_GUN && m_nPedState != PED_FIGHT)
+ RemoveWeaponAnims(m_currentWeapon, -1000.0f);
MakeChangesForNewWeapon(m_nSelectedWepSlot);
}
}
+// --MIAMI: Done
void
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);
}
+// --MIAMI: Done
void
CPlayerPed::PlayerControlFighter(CPad *padUsed)
{
@@ -696,6 +866,7 @@ CPlayerPed::PlayerControlFighter(CPad *padUsed)
}
}
+// --MIAMI: Done
void
CPlayerPed::PlayerControl1stPersonRunAround(CPad *padUsed)
{
@@ -723,14 +894,21 @@ CPlayerPed::PlayerControl1stPersonRunAround(CPad *padUsed)
m_fMoveSpeed = 0.0f;
}
}
+
+ if (m_nPedState == PED_ANSWER_MOBILE) {
+ SetRealMoveAnim();
+ return;
+ }
+
if (!(CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bHeavy) && padUsed->GetSprint()) {
m_nMoveState = PEDMOVE_SPRINT;
}
if (m_nPedState != PED_FIGHT)
SetRealMoveAnim();
- if (!bIsInTheAir && !(CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bHeavy)
- && padUsed->JumpJustDown() && m_nPedState != PED_JUMP) {
+ if (!bIsInTheAir && !(CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bHeavy) &&
+ padUsed->JumpJustDown() && m_nPedState != PED_JUMP) {
+
ClearAttack();
ClearWeaponTarget();
if (m_nEvadeAmount != 0 && m_pEvadingFrom) {
@@ -741,15 +919,22 @@ 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
}
+// --MIAMI: Done
void
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);
@@ -792,18 +977,17 @@ CPlayerPed::KeepAreaAroundPlayerClear(void)
}
}
+// --MIAMI: Done
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) {
@@ -820,6 +1004,7 @@ CPlayerPed::EvaluateNeighbouringTarget(CEntity *candidate, CEntity **targetPtr,
}
}
+// --MIAMI: Done
void
CPlayerPed::EvaluateTarget(CEntity *candidate, CEntity **targetPtr, float *lastCloseness, float distLimit, float angleOffset, bool priority)
{
@@ -832,7 +1017,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) {
@@ -844,6 +1029,38 @@ 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)->m_bCanAimWithArm || Abs(angleDiff) <= HALFPI) &&
+ (CWeaponInfo::GetWeaponInfo(weapon->m_eWeaponType)->m_bCanAimWithArm || Abs(target.z - GetPosition().z) <= (target - GetPosition()).Magnitude2D());
+}
+
+void
+CPlayerPed::RotatePlayerToTrackTarget(void)
+{
+ if (CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bCanAimWithArm)
+ 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);
+ }
+}
+
+// --MIAMI: Done
+bool
CPlayerPed::FindNextWeaponLockOnTarget(CEntity *previousTarget, bool lookToLeft)
{
CEntity *nextTarget = nil;
@@ -857,29 +1074,35 @@ 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;
}
+// --MIAMI: Done
bool
CPlayerPed::FindWeaponLockOnTarget(void)
{
@@ -902,29 +1125,36 @@ 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;
}
+// --MIAMI: Done
void
CPlayerPed::ProcessAnimGroups(void)
{
@@ -937,17 +1167,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;
}
@@ -955,9 +1197,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 {
@@ -984,44 +1236,66 @@ CPlayerPed::ProcessPlayerWeapon(CPad *padUsed)
CWeaponEffects::ClearCrossHair();
ClearPointGunAt();
}
+
+ if (padUsed->DuckJustDown() && !bIsDucking && m_nMoveState != PEDMOVE_SPRINT) {
+ bCrouchWhenShooting = true;
+ SetDuck(60000, true);
+ } else if (bIsDucking && (padUsed->DuckJustDown() || m_nMoveState == PEDMOVE_SPRINT ||
+ padUsed->GetSprint() || padUsed->JumpJustDown() || padUsed->ExitVehicleJustDown())) {
+
+ ClearDuck(true);
+ bCrouchWhenShooting = false;
+ }
+
+ if(weaponInfo->m_bCanAim)
+ 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_IDLE_STANCE, 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;
@@ -1032,12 +1306,19 @@ CPlayerPed::ProcessPlayerWeapon(CPad *padUsed)
m_fAttackButtonCounter = 0.0f;
m_bHaveTargetSelected = false;
}
- SetAttack(nil);
- } else if (padUsed->WeaponJustDown()) {
- if (m_fMoveSpeed < 1.0f)
- StartFightAttack(padUsed->GetWeapon());
- else
- SetAttack(nil);
+ if (GetWeapon()->m_eWeaponType != WEAPONTYPE_UNARMED && GetWeapon()->m_eWeaponType != WEAPONTYPE_BRASSKNUCKLE &&
+ !weaponInfo->m_bFightMode) {
+
+ if (GetWeapon()->m_eWeaponType != WEAPONTYPE_DETONATOR && GetWeapon()->m_eWeaponType != WEAPONTYPE_DETONATOR_GRENADE ||
+ padUsed->WeaponJustDown())
+ SetAttack(nil);
+
+ } else if (padUsed->WeaponJustDown()) {
+ if (m_fMoveSpeed < 1.0f || m_nPedState == PED_FIGHT)
+ StartFightAttack(padUsed->GetWeapon());
+ else
+ SetAttack(nil);
+ }
}
}
} else {
@@ -1056,27 +1337,27 @@ CPlayerPed::ProcessPlayerWeapon(CPad *padUsed)
if (CCamera::m_bUseMouse3rdPerson && CCamera::bFreeCam &&
m_nSelectedWepSlot == m_currentWeapon && m_nMoveState != PEDMOVE_SPRINT) {
+#define CAN_AIM_WITH_ARM (weaponInfo->m_bCanAimWithArm && !bIsDucking && !bCrouchWhenShooting)
// Weapons except throwable and melee ones
- if (weaponInfo->m_bCanAim || weaponInfo->m_b1stPerson || weaponInfo->m_bExpands) {
- if ((padUsed->GetTarget() && weaponInfo->m_bCanAimWithArm) || 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->m_bCanAimWithArm) {
+ if (CAN_AIM_WITH_ARM) {
if (!padUsed->GetWeapon()) { // making this State != ATTACK still stops it after attack. Re-start it immediately!
- SetPointGunAt(nil);
+ SetWeaponLockOnTarget(nil);
bIsPointingGunAt = false; // to not stop after attack
}
SetLookFlag(limitedCam, true);
SetAimFlag(limitedCam);
-#ifdef VC_PED_PORTS
SetLookTimer(INT32_MAX); // removing this makes head move for real, but I experinced some bugs.
-#endif
+
} else {
m_fRotationDest = limitedCam;
changedHeadingRate = 2;
- m_headingRate = 50.0f;
+ m_headingRate = 12.5f;
// Anim. fix for shotgun, ak47 and m16 (we must finish rot. it quickly)
if (weaponInfo->m_bCanAim && padUsed->WeaponJustDown()) {
@@ -1092,9 +1373,10 @@ CPlayerPed::ProcessPlayerWeapon(CPad *padUsed)
m_fRotationCur += (limitedRotDest - m_fRotationCur) / 2;
}
}
- } else if (weaponInfo->m_bCanAimWithArm && m_nPedState != PED_ATTACK)
+ } else if (CAN_AIM_WITH_ARM && m_nPedState != PED_ATTACK)
ClearPointGunAt();
}
+#undef CAN_AIM_WITH_ARM
}
if (changedHeadingRate == 1) {
changedHeadingRate = 0;
@@ -1102,7 +1384,7 @@ CPlayerPed::ProcessPlayerWeapon(CPad *padUsed)
}
#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->m_bCanAim) {
if (m_pPointGunAt) {
// what??
if (!m_pPointGunAt
@@ -1110,15 +1392,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->m_bCanAimWithArm)) { // this line isn't on Mobile, idk why
ClearWeaponTarget();
return;
}
+
+ if (m_pPointGunAt) {
+ RotatePlayerToTrackTarget();
+ }
+
if (m_pPointGunAt) {
if (padUsed->ShiftTargetLeftJustDown())
FindNextWeaponLockOnTarget(m_pPointGunAt, true);
@@ -1127,13 +1424,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->m_bCanAim && !CCamera::m_bUseMouse3rdPerson)) {
-#else
- else if (weaponInfo->m_bCanAim && !CCamera::m_bUseMouse3rdPerson) {
-#endif
- if (padUsed->TargetJustDown())
+
+ } else if (!CCamera::m_bUseMouse3rdPerson) {
+ if (padUsed->TargetJustDown() || TheCamera.m_bJustJumpedOutOf1stPersonBecauseOfTarget)
FindWeaponLockOnTarget();
}
} else if (m_pPointGunAt) {
@@ -1141,16 +1434,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 {
@@ -1160,17 +1449,29 @@ CPlayerPed::ProcessPlayerWeapon(CPad *padUsed)
m_bHasLockOnTarget = m_pPointGunAt != nil;
}
+bool
+CPlayerPed::MovementDisabledBecauseOfTargeting(void)
+{
+ return m_pPointGunAt && !CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bCanAimWithArm;
+}
+
+// --MIAMI: Done
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 {
@@ -1180,12 +1481,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;
}
@@ -1211,9 +1508,16 @@ CPlayerPed::PlayerControlZelda(CPad *padUsed)
}
}
+ if (m_nPedState == PED_ANSWER_MOBILE) {
+ SetRealMoveAnim();
+ return;
+ }
+
if (!(CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bHeavy) && 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();
@@ -1229,34 +1533,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->m_nWantedLevel > 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_ATTACK, 0.0f);
+ }
if (m_nMoveState != PEDMOVE_RUN && m_nMoveState != PEDMOVE_SPRINT)
RestoreSprintEnergy(1.0f);
@@ -1274,27 +1712,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_CAR_ROLLDOOR);
+ 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_CAR_ROLLDOOR);
- if (m_pMyVehicle->m_nGettingOutFlags & CAR_DOOR_FLAG_LF || rollDoorAssoc || (rollDoorAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_ROLLDOOR_LOW))) {
- if (rollDoorAssoc)
- m_pMyVehicle->ProcessOpenDoor(CAR_DOOR_LF, ANIM_CAR_ROLLDOOR, rollDoorAssoc->currentTime);
-
- } 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_CAR_ROLLDOOR_LOW))) {
if (rollDoorAssoc)
m_pMyVehicle->ProcessOpenDoor(CAR_DOOR_LF, ANIM_CAR_ROLLDOOR, rollDoorAssoc->currentTime);
} else {
- m_pMyVehicle->m_nGettingOutFlags |= CAR_DOOR_FLAG_LF;
- if (m_pMyVehicle->bLowVehicle)
- rollDoorAssoc = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_ROLLDOOR_LOW);
- else
- rollDoorAssoc = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_ROLLDOOR);
+ // 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_CAR_ROLLDOOR, rollDoorAssoc->currentTime);
+
+ } else {
+ m_pMyVehicle->m_nGettingOutFlags |= CAR_DOOR_FLAG_LF;
+ if (m_pMyVehicle->bLowVehicle)
+ rollDoorAssoc = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_ROLLDOOR_LOW);
+ else
+ rollDoorAssoc = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_ROLLDOOR);
- rollDoorAssoc->SetFinishCallback(PedAnimDoorCloseRollingCB, this);
+ rollDoorAssoc->SetFinishCallback(PedAnimDoorCloseRollingCB, this);
+ }
}
}
}
@@ -1304,11 +1744,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);
@@ -1323,8 +1763,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)
+ PlayerControlFighter(padUsed);
+
+ } else if (TheCamera.Cams[0].Using3rdPersonMouseCam()
#ifdef FREE_CAM
&& !CCamera::bFreeCam
#endif
@@ -1340,7 +1785,7 @@ CPlayerPed::ProcessControl(void)
PlayerControlZelda(padUsed);
}
}
- if (IsPedInControl() && padUsed)
+ if (IsPedInControl() && m_nPedState != PED_ANSWER_MOBILE && padUsed)
ProcessPlayerWeapon(padUsed);
break;
case PED_SEEK_ENTITY:
@@ -1369,12 +1814,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:
@@ -1425,9 +1870,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) {
@@ -1437,12 +1882,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;
@@ -1473,10 +1919,285 @@ 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();
+}
+
+// --MIAMI: Done
+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_IDLE_STRETCH, ASSOCGRP_PLAYER_IDLE},
+ {ANIM_IDLE_TIME, ASSOCGRP_PLAYER_IDLE},
+ {ANIM_IDLE_SHOULDER, ASSOCGRP_PLAYER_IDLE},
+ {ANIM_IDLE_STRETCH_LEG, ASSOCGRP_PLAYER_IDLE},
+ {ANIM_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;
+ }
+ }
+ }
+}
+
+// --MIAMI: Done
+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);
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+// --MIAMI: Done
+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;
+}
+
+// --MIAMI: Done
+void
+CPlayerPed::RemovePedFromMeleeList(CPed *ped)
+{
+ int i = 0;
+ for (; m_pMeleeList[i] != ped; i++) {
+ if (i >= ARRAY_SIZE(m_pMeleeList))
+ return;
+ }
+ m_pMeleeList[i] = nil;
+ ped->m_attackTimer = 0;
+}
+
+// --MIAMI: Done
+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;
+ }
+}
+
+// --MIAMI: Done
+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
@@ -1493,7 +2214,7 @@ CPlayerPed::Save(uint8*& buf)
CopyToBuf(buf, m_nTargettableObjects[1]);
CopyToBuf(buf, m_nTargettableObjects[2]);
CopyToBuf(buf, m_nTargettableObjects[3]);
- SkipSaveBuf(buf, 116);
+ SkipSaveBuf(buf, 164);
}
void
@@ -1507,7 +2228,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..3c58f7f5 100644
--- a/src/peds/PlayerPed.h
+++ b/src/peds/PlayerPed.h
@@ -18,22 +18,34 @@ public:
int8 m_nSelectedWepSlot; // eWeaponType
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;
CPlayerPed();
~CPlayerPed();
@@ -45,7 +57,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 +66,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 +108,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 5dbde649..7314080b 100644
--- a/src/peds/Population.cpp
+++ b/src/peds/Population.cpp
@@ -22,6 +22,14 @@
#include "DummyObject.h"
#include "Script.h"
#include "Shadows.h"
+#include "SurfaceTable.h"
+#include "Weather.h"
+#include "Darkel.h"
+#include "Streaming.h"
+#include "Clock.h"
+#include "WaterLevel.h"
+
+// --MIAMI: File done
#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.
@@ -29,32 +37,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,
- CVector(790.0f, -917.0f, 39.0f), CVector(775.0f, -921.0f, 39.0f), CVector(424.0f, -942.0f, 38.0f), CVector(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 = 25;
+int32 CPopulation::MaxNumberOfPedsInUseInterior = 40;
uint32 CPopulation::ms_nNumCivMale;
uint32 CPopulation::ms_nNumCivFemale;
uint32 CPopulation::ms_nNumCop;
@@ -74,9 +63,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::RegenerationForward;
+
+uint32 CPopulation::ms_nTotalCarPassengerPeds;
+uint32 CPopulation::NumMiamiViceCops;
+
+uint32 gLastSelectedCivilianIndex;
+CEntity *gSunbatheObstacles[2];
+CEntity *gCoupleObstacles[3];
void
CPopulation::Initialise()
@@ -98,18 +91,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");
}
@@ -124,7 +118,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
@@ -319,108 +351,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::RegenerationForward = aSafeZones[safeZone].destPosA - aSafeZones[safeZone].srcPosA;
- RegenerationForward.Normalise();
- } else if (aSafeZones[safeZone].destLevel == newLevel) {
- CPopulation::RegenerationPoint_a = aSafeZones[safeZone].destPosA;
- CPopulation::RegenerationPoint_b = aSafeZones[safeZone].destPosB;
- CPopulation::RegenerationForward = aSafeZones[safeZone].srcPosA - aSafeZones[safeZone].destPosA;
- RegenerationForward.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)
@@ -432,7 +376,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),
@@ -446,13 +391,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),
@@ -460,20 +406,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()
@@ -487,7 +419,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:
@@ -498,16 +430,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);
@@ -528,12 +478,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:
@@ -575,68 +527,100 @@ 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->m_nWantedLevel > 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()) {
+ int32 model = player->m_pMyVehicle->GetModelIndex();
+ if (model == MI_TAXI || model == MI_CABBIE || model == MI_ZEBRA || model == MI_KAUFMAN)
+ 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;
@@ -649,35 +633,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;
@@ -692,7 +700,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?!
@@ -704,29 +712,81 @@ CPopulation::AddToPopulation(float minDist, float maxDist, float minDistOffScree
generatedCoors.z = Max(generatedCoors.z, groundZ);
}
- bool farEnoughToAdd = true;
- CMatrix mat(TheCamera.GetCameraMatrix());
- if (TheCamera.IsSphereVisible(generatedCoors, 2.0f, &mat)) {
+ bool surfaceAndDistIsOk = true;
+ if (TheCamera.IsSphereVisible(generatedCoors, 2.0f)) {
if (PedCreationDistMultiplier() * MIN_CREATION_DIST > (generatedCoors - playerCentreOfWorld).Magnitude2D())
- farEnoughToAdd = false;
+ surfaceAndDistIsOk = false;
}
- if (!farEnoughToAdd)
+
+ // 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 (!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 +802,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 +824,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 +838,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->GetModelIndex() == MI_TAXI || car->GetModelIndex() == MI_CABBIE || car->GetModelIndex() == MI_ZEBRA || car->GetModelIndex() == MI_KAUFMAN) {
+ 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 +870,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 +897,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 + 308h), 100.0f);
- } else */
- // FIX: Make peds comfortable while driving car/boat
-#ifdef FIX_BUGS
- {
- newPed->m_pVehicleAnim = CAnimManager::BlendAnimation(newPed->GetClump(), ASSOCGRP_STD, car->GetDriverAnim(), 100.0f);
- }
-#else
- {
- newPed->m_pVehicleAnim = CAnimManager::BlendAnimation(newPed->GetClump(), ASSOCGRP_STD, ANIM_CAR_SIT, 100.0f);
- }
-#endif
-
- newPed->StopNonPartialAnims();
+ newPed->AddInCarAnims(car, isDriver);
return newPed;
}
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() = RegenerationForward;
- ((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
@@ -969,7 +941,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);
@@ -988,7 +961,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);
@@ -1000,7 +974,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;
@@ -1075,17 +1049,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);
}
}
@@ -1096,7 +1073,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);
}
@@ -1111,7 +1088,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) {
@@ -1120,25 +1098,33 @@ CPopulation::ManagePopulation(void)
}
float dist = (ped->GetPosition() - playerPos).Magnitude2D();
-#ifdef SQUEEZE_PERFORMANCE
- if (dist > 50.f)
- ped->bUsesCollision = false;
- else
- ped->bUsesCollision = true;
-#endif
-
bool pedIsFarAway = false;
- if (PedCreationDistMultiplier() * (PED_REMOVE_DIST_SPECIAL * TheCamera.GenerationDistMultiplier) < dist
- || (!ped->bCullExtraFarAway && PedCreationDistMultiplier() * PED_REMOVE_DIST * TheCamera.GenerationDistMultiplier < dist)
- || (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))
+
+ 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;
+ } 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;
+ }
+ }
+
+ } else {
+ ped->m_nExtendedRangeTimer = ped->m_nPedType == PEDTYPE_COP ? CTimer::GetTimeInMilliseconds() + 10000 : CTimer::GetTimeInMilliseconds() + 4000;
+ }
+
if (!pedIsFarAway)
continue;
@@ -1173,3 +1159,638 @@ 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, 0)) {
+ 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, 0)) {
+ int pedIdx = 0;
+ CVector leaderPos;
+
+ 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);
+
+ if (i == 0)
+ 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 = i == 0 ? true : CWorld::GetIsLineOfSightClear(finalPos, leaderPos, true, false, false, false, false, false, false);
+
+ bool notTooCloseToLeader = i == 0 ? true : !(Abs(finalPos.z - leaderPos.z) < 1.0f);
+
+ if (!foundObstacle && memberCanSeeLeader && notTooCloseToLeader) {
+ 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);
+ }
+ // 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, 0)) {
+ 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, 0)) {
+ int pedIdx = 0;
+ CVector leaderPos;
+
+ 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);
+
+ if (i == 0)
+ 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 = i == 0 ? true : CWorld::GetIsLineOfSightClear(finalPos, leaderPos, true, false, false, false, false, false, false);
+
+ bool notTooCloseToLeader = i == 0 ? true : !(Abs(finalPos.z - leaderPos.z) < 1.0f);
+
+ if (!foundObstacle && memberCanSeeLeader && notTooCloseToLeader) {
+ 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);
+ }
+ // 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 aa8129c0..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;
- CVector destPosA;
- CVector destPosB;
- CVector srcPosA;
- CVector 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 RegenerationForward;
+
+ 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/render/2dEffect.h b/src/render/2dEffect.h
index a8013b34..8ad2b946 100644
--- a/src/render/2dEffect.h
+++ b/src/render/2dEffect.h
@@ -3,7 +3,9 @@
enum {
EFFECT_LIGHT,
EFFECT_PARTICLE,
- EFFECT_ATTRACTOR
+ EFFECT_ATTRACTOR,
+ EFFECT_PED_ATTRACTOR,
+ EFFECT_SUNGLARE
};
enum {
@@ -34,6 +36,8 @@ enum {
// same order as CPointLights flags, must start at 2
LIGHTFLAG_FOG_NORMAL = 2, // can have light and fog
LIGHTFLAG_FOG_ALWAYS = 4, // fog only
+ LIGHTFLAG_HIDE_OBJECT = 8, // hide the object instead of rendering light (???)
+ LIGHTFLAG_LONG_DIST = 16,
LIGHTFLAG_FOG = (LIGHTFLAG_FOG_NORMAL|LIGHTFLAG_FOG_ALWAYS)
};
@@ -63,6 +67,11 @@ public:
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/render/Antennas.cpp b/src/render/Antennas.cpp
index 452069a0..b9da95cb 100644
--- a/src/render/Antennas.cpp
+++ b/src/render/Antennas.cpp
@@ -2,6 +2,8 @@
#include "Antennas.h"
+//--MIAMI: file done
+
CAntenna CAntennas::aAntennas[NUMANTENNAS];
void
diff --git a/src/render/Clouds.cpp b/src/render/Clouds.cpp
index b5af6619..c7554356 100644
--- a/src/render/Clouds.cpp
+++ b/src/render/Clouds.cpp
@@ -3,6 +3,7 @@
#include "Sprite.h"
#include "Sprite2d.h"
#include "General.h"
+#include "Game.h"
#include "Coronas.h"
#include "Camera.h"
#include "TxdStore.h"
@@ -23,8 +24,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)
@@ -44,25 +47,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
@@ -70,15 +63,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 };
@@ -123,6 +116,9 @@ CClouds::Render(void)
RwV3d screenpos;
RwV3d worldpos;
+ if(!CGame::CanSeeOutSideFromCurrArea())
+ return;
+
CCoronas::SunBlockedByClouds = false;
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
@@ -132,25 +128,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);
}
@@ -199,7 +190,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;
@@ -220,10 +211,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);
@@ -235,15 +226,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,8 +269,7 @@ CClouds::Render(void)
worldpos.y = campos.x*rot_sin + campos.y*rot_cos + pos.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,
@@ -322,14 +313,17 @@ void
CClouds::RenderBackground(int16 topred, int16 topgreen, int16 topblue,
int16 botred, int16 botgreen, int16 botblue, int16 alpha)
{
- 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;
@@ -352,75 +346,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;
}
}
@@ -433,21 +426,35 @@ CClouds::RenderHorizon(void)
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;
+
+ 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);
}
diff --git a/src/render/Clouds.h b/src/render/Clouds.h
index 4d8cd2c8..ef33030b 100644
--- a/src/render/Clouds.h
+++ b/src/render/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/render/Console.cpp b/src/render/Console.cpp
index 8ea5b7a3..244bfb17 100644
--- a/src/render/Console.cpp
+++ b/src/render/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/render/Coronas.cpp b/src/render/Coronas.cpp
index 48f0f6b9..9c87e2e0 100644
--- a/src/render/Coronas.cpp
+++ b/src/render/Coronas.cpp
@@ -2,6 +2,7 @@
#include "main.h"
#include "General.h"
+#include "RenderBuffer.h"
#include "TxdStore.h"
#include "Camera.h"
#include "Sprite.h"
@@ -12,6 +13,8 @@
#include "Timecycle.h"
#include "Coronas.h"
+//--MIAMI: file done
+
struct FlareDef
{
float position;
@@ -53,7 +56,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;
@@ -129,13 +132,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;
@@ -188,15 +200,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
@@ -309,7 +325,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?
@@ -371,7 +387,7 @@ CCoronas::Render(void)
}
}
- RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDONE);
@@ -423,9 +439,7 @@ CCoronas::RenderReflections(void)
CEntity *entity;
if(CWeather::WetRoads > 0.0f){
-#ifdef FIX_BUGS
CSprite::InitSpriteBuffer();
-#endif
RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
@@ -464,7 +478,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){
@@ -506,6 +520,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)
{
@@ -522,7 +660,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(),
@@ -531,7 +669,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{
diff --git a/src/render/Coronas.h b/src/render/Coronas.h
index 46eb4315..45f027d8 100644
--- a/src/render/Coronas.h
+++ b/src/render/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/render/Credits.cpp b/src/render/Credits.cpp
index 2c8a9952..f45c0aee 100644
--- a/src/render/Credits.cpp
+++ b/src/render/Credits.cpp
@@ -7,6 +7,9 @@
#include "Camera.h"
#include "Text.h"
#include "Credits.h"
+#include "Pad.h"
+
+// --MIAMI: file done
bool CCredits::bCreditsGoing;
uint32 CCredits::CreditsStartTime;
@@ -39,13 +42,21 @@ CCredits::PrintCreditSpace(float space, uint32 &line)
void
CCredits::PrintCreditText(float scaleX, float scaleY, wchar *text, uint32 &lineoffset, float scrolloffset)
{
- float start = DEFAULT_SCREEN_HEIGHT + 50.0f;
- float y = lineoffset + start - scrolloffset;
- if(y > -50.0f && y < start){
- CFont::SetScale(SCREEN_SCALE_X(scaleX), SCREEN_SCALE_Y(scaleY));
- CFont::PrintString(SCREEN_WIDTH/2.0f, SCREEN_SCALE_Y(y), (uint16*)text);
+ 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
@@ -62,430 +73,733 @@ CCredits::Render(void)
scrolloffset = (CTimer::GetTimeInMilliseconds() - CreditsStartTime) / 24.0f;
CFont::SetJustifyOff();
CFont::SetBackgroundOff();
- CFont::SetCentreSize(SCREEN_SCALE_X(DEFAULT_SCREEN_WIDTH - 20));
+ 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();
if(TheCamera.m_WideScreenOn)
TheCamera.DrawBordersForWideScreen();
diff --git a/src/render/CutsceneShadow.cpp b/src/render/CutsceneShadow.cpp
new file mode 100644
index 00000000..8cb33896
--- /dev/null
+++ b/src/render/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/render/CutsceneShadow.h b/src/render/CutsceneShadow.h
new file mode 100644
index 00000000..a59fe78f
--- /dev/null
+++ b/src/render/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/render/Draw.cpp b/src/render/Draw.cpp
index 4e323ec2..912399c9 100644
--- a/src/render/Draw.cpp
+++ b/src/render/Draw.cpp
@@ -21,24 +21,28 @@ uint8 CDraw::FadeGreen;
uint8 CDraw::FadeBlue;
float
-CDraw::FindAspectRatio(void)
+CDraw::CalculateAspectRatio(void)
{
-#ifndef ASPECT_RATIO_SCALE
- if(FrontEndMenuManager.m_PrefsUseWideScreen)
- return 16.0f/9.0f;
- else
- return 4.0f/3.0f;
+ if (FrontEndMenuManager.m_PrefsUseWideScreen) {
+#ifdef ASPECT_RATIO_SCALE
+ if (TheCamera.m_WideScreenOn)
+ CDraw::ms_fAspectRatio = FrontEndMenuManager.m_PrefsUseWideScreen == AR_AUTO ?
+ (5.f / 3.f) * (SCREEN_WIDTH / SCREEN_HEIGHT) / (16.f / 9.f) :
+ 5.f / 3.f; // It's used on theatrical showings according to Wiki
+ else
+ CDraw::ms_fAspectRatio = FrontEndMenuManager.m_PrefsUseWideScreen == AR_AUTO ? SCREEN_WIDTH / SCREEN_HEIGHT : 16.f / 9.f;
#else
- switch (FrontEndMenuManager.m_PrefsUseWideScreen) {
- case AR_AUTO:
- return SCREEN_WIDTH / SCREEN_HEIGHT;
- default:
- case AR_4_3:
- return 4.0f / 3.0f;
- case AR_16_9:
- return 16.0f / 9.0f;
- };
+ 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;
#endif
+ } else if (TheCamera.m_WideScreenOn) {
+ CDraw::ms_fAspectRatio = 5.f/4.f;
+ } else {
+ CDraw::ms_fAspectRatio = 4.f/3.f;
+ }
+ return CDraw::ms_fAspectRatio;
}
#ifdef ASPECT_RATIO_SCALE
@@ -80,4 +84,4 @@ ScaleAndCenterX(float x)
else
return (SCREEN_WIDTH - SCREEN_SCALE_X(DEFAULT_SCREEN_WIDTH)) / 2 + SCREEN_SCALE_X(x);
}
-#endif \ No newline at end of file
+#endif \ No newline at end of file
diff --git a/src/render/Draw.h b/src/render/Draw.h
index 5c4f95b1..2976dc34 100644
--- a/src/render/Draw.h
+++ b/src/render/Draw.h
@@ -44,12 +44,10 @@ 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
};
diff --git a/src/render/Fluff.cpp b/src/render/Fluff.cpp
index c76d6109..157be0c8 100644
--- a/src/render/Fluff.cpp
+++ b/src/render/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,293 @@
#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"
+
+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 +370,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,124 +388,192 @@ 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()
{
+ 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();
+}
+
+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);
}
}
// ---------- 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;
}
}
}
@@ -252,29 +605,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()
{
@@ -285,49 +615,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;
@@ -356,263 +660,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:
+ if (m_Type == SCROLL_ARENA_STRING) {
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:
- while (previousMessage == m_pMessage)
- {
- switch (CGeneral::GetRandomNumber() % 4)
- {
- case 0:
- m_pMessage = "WELCOME TO FRANCIS INTERNATIONAL AIRPORT . . . ";
- break;
- case 1:
- m_pMessage = "PLEASE DO NOT LEAVE LUGGAGE UNATTENDED . . . ";
- break;
- case 2:
- m_pMessage = "FOLLOW 1 FOR LONG AND SHORT TERM PARKING ";
- 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 ";
+ 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 = "GTA3 OUT NOW . . . ";
+ 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 = "OUR STUFF IS CHEAP CHEAP CHEAP ";
+ 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 = "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();
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();
+ default:
break;
}
}
- break;
}
m_MessageLength = (uint32)strlen(m_pMessage);
@@ -697,172 +786,536 @@ 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;
+}
- // Prepare render states
- RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
- RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE);
+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++;
+ }
+ }
+ }
+
+ 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 = Max(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;
+
+ if (m_bIsMovingDown)
+ t = 1.0f - t;
- CSprite::FlushSpriteBuffer();
+ 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++) {
+ aArray[i] = ReadSaveBuf<CScriptPath>(buf);
+
+ for (int32 j = 0; j < 6; j++) {
+ 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;
+ }
+ }
+
+ aArray[i].m_pNode = new CPlaneNode[aArray[i].m_numNodes];
+ for (int32 j = 0; j < aArray[i].m_numNodes; j++) {
+ aArray[i].m_pNode[j] = ReadSaveBuf<CPlaneNode>(buf);
+ }
+ }
+VALIDATESAVEBUF(size)
+}
+
+void CScriptPaths::Save(uint8 *buf, uint32 *size) {
+ *size = sizeof(aArray);
+INITSAVEBUF
+ for (int32 i = 0; i < 3; i++) {
+ CScriptPath *pPath = WriteSaveBuf(buf, aArray[i]);
+
+ for (int32 j = 0; j < 6; j++) {
+ if (pPath->m_pObjects[j] != nil)
+ pPath->m_pObjects[j] = (CObject*)(CPools::GetObjectPool()->GetJustIndex_NoFreeAssert(pPath->m_pObjects[j]) + 1);
+ }
+
+ 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/render/Fluff.h b/src/render/Fluff.h
index fe3ab256..58c8410c 100644
--- a/src/render/Fluff.h
+++ b/src/render/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/render/Font.cpp b/src/render/Font.cpp
index 42ddd0fb..3f130344 100644
--- a/src/render/Font.cpp
+++ b/src/render/Font.cpp
@@ -6,6 +6,7 @@
#ifdef BUTTON_ICONS
#include "FileMgr.h"
#endif
+#include "Timer.h"
void
AsciiToUnicode(const char *src, wchar *dst)
@@ -33,67 +34,51 @@ 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;
int16 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
- {
- 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
- }
+ {
+ 12, 9, 22, 17, 19, 19, 25, 4, 33, 33, 25, 35, 11, 10, 6, 33, 18, 10, 17, 17, 17, 17, 17, 15, 12, 16, 5, 30, 30, 30, 30, 30, 12, 16, 19,
+ 16, 19, 18, 18, 17, 22, 11, 17, 18, 18, 30, 22, 19, 22, 19, 19, 20, 18, 19, 19, 29, 19, 18, 19, 19, 33, 33, 19, 19, 12, 14, 11, 11, 16, 11,
+ 12, 14, 14, 10, 13, 12, 10, 19, 18, 12, 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, 24, 18, 21, 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, 16
+ },
+ {
+ 15, 7, 31, 25, 20, 23, 21, 7, 11, 10, 26, 14, 6, 12, 6, 26, 20, 7, 20, 20, 21, 20, 20, 19, 21, 20, 8, 30, 24, 30, 24, 19, 20, 22, 22, 21, 22, 18, 18, 22,
+ 22, 9, 14, 21, 18, 27, 21, 24, 22, 22, 23, 20, 19, 23, 22, 31, 23, 23, 21, 25, 13, 30, 10, 19, 10, 17, 17, 16, 17, 17, 11, 17, 17, 7, 7, 18, 7, 25, 17,
+ 17, 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, 19, 20, 20, 20, 18, 19, 19, 21, 19, 19, 19, 19, 19, 16, 19,
+ 19, 19, 20, 19, 16, 19, 19, 9, 19, 20, 14, 29, 19, 19, 19, 19, 19, 19, 21, 19, 20, 32, 20, 19, 19, 19, 19, 19, 19, 29, 19, 19, 19, 19, 19, 9, 9, 9, 9,
+ 19, 19, 19, 19, 19, 19, 19, 19, 19, 21, 21, 10, 9, 10, 20
+ }
#ifdef MORE_LANGUAGES
},
{
@@ -227,6 +212,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;
@@ -263,16 +263,14 @@ 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);
@@ -375,7 +373,6 @@ CFont::Shutdown(void)
#endif
Sprite[0].Delete();
Sprite[1].Delete();
- Sprite[2].Delete();
#ifdef MORE_LANGUAGES
if (IsJapanese())
Sprite[3].Delete();
@@ -389,13 +386,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 = 0;
#ifdef BUTTON_ICONS
@@ -429,11 +422,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 ||
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
@@ -444,28 +441,44 @@ CFont::PrintChar(float x, float y, wchar c)
}
#endif
- if(Details.style == FONT_BANK || Details.style == FONT_HEADING){
- if(Details.dropShadowPosition != 0){
- 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 * 0.5f),
- 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(Details.bank + Details.style, // BUG: game doesn't add bank
- 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(Details.style == FONT_BANK || Details.style == FONT_STANDARD){
+ if (bDontPrint) return;
+ if (RenderState.slant == 0.0f) {
+#ifdef FIX_BUGS
+ if (c < 192) {
+#else
+ 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()) {
if (Details.dropShadowPosition != 0) {
@@ -490,16 +503,18 @@ CFont::PrintChar(float x, float y, wchar c)
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(Details.bank + Details.style, // BUG: game doesn't add bank
+ } 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);
+ }
}
#ifdef MORE_LANGUAGES
@@ -534,10 +549,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);
@@ -580,7 +599,7 @@ CFont::PrintString(float xstart, float ystart, wchar *s)
#ifdef 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;
@@ -660,7 +679,7 @@ CFont::PrintString(float xstart, float ystart, wchar *s)
lineLength = 0.0f;
}
#else
- PrintString(xleft, y, start, s, 0.0f);
+ PrintString(xleft, y, Details.anonymous_25, start, s, 0.0f);
#endif
}
}
@@ -924,58 +943,81 @@ CFont::PrintString(float x, float y, wchar *start, wchar *&end, float spwidth, f
}
#else
void
-CFont::PrintString(float x, float y, wchar *start, wchar *end, float spwidth)
+CFont::PrintString(float x, float y, uint32, wchar *start, wchar *end, float spwidth)
{
- wchar *s, c, unused;
+ wchar *s;
- 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;
+ 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
-#ifdef XBOX_SUBTITLES
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);
+ 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::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)
{
@@ -1016,7 +1058,7 @@ CFont::GetCharacterWidth(wchar c)
if (Details.proportional)
return Size[Details.style][c];
else
- return Size[Details.style][192];
+ return Size[Details.style][209];
#endif // MORE_LANGUAGES
}
@@ -1028,7 +1070,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)
{
@@ -1056,12 +1098,14 @@ CFont::GetCharacterSize(wchar c)
else if(Details.proportional)
return Size[LanguageSet][Details.style][c] * Details.scaleX;
else
- return Size[LanguageSet][Details.style][192] * Details.scaleX;
+ return Size[LanguageSet][Details.style][209] * Details.scaleX;
#else
+ 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
}
@@ -1115,8 +1159,8 @@ 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) {
@@ -1142,16 +1186,13 @@ CFont::GetStringWidth(wchar *s, bool spaces)
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;
@@ -1205,11 +1246,6 @@ CFont::GetNextSpace(wchar *s)
if(*s == '~'){
s++;
while(*s != '~') s++;
-#ifndef FIX_BUGS
- s++;
- if(*s == ' ')
- break;
-#endif
}
}
return s;
@@ -1217,7 +1253,7 @@ CFont::GetNextSpace(wchar *s)
#ifdef MORE_LANGUAGES
wchar*
-CFont::ParseToken(wchar *s, wchar* ss, bool japShit)
+CFont::ParseToken(wchar *s, bool japShit)
{
s++;
if ((Details.color.r || Details.color.g || Details.color.b) && !japShit) {
@@ -1261,33 +1297,44 @@ 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 = 1;
break;
- case 'b': SetColor(CRGBA(0x80, 0xA7, 0xF3, 0xFF)); break;
- case 'g': SetColor(CRGBA(0x5F, 0xA0, 0x6A, 0xFF)); break;
- case 'h': SetColor(CRGBA(0xE1, 0xE1, 0xE1, 0xFF)); break;
- case 'l': SetColor(CRGBA(0x00, 0x00, 0x00, 0xFF)); break;
- case 'p': SetColor(CRGBA(0xA8, 0x6E, 0xFC, 0xFF)); break;
- case 'r': SetColor(CRGBA(0x71, 0x2B, 0x49, 0xFF)); break;
- case 'w': SetColor(CRGBA(0xAF, 0xAF, 0xAF, 0xFF)); break;
- case 'y': SetColor(CRGBA(0xD2, 0xC4, 0x6A, 0xFF)); break;
+ case 'b': SetColor(CRGBA(27, 89, 130, 255)); Details.anonymous_23 = true; break;
+ case 'f':
+ Details.bFlash = !Details.bFlash;
+ if (!Details.bFlash)
+ Details.color.a = 255;
+ break;
+ case 'g': SetColor(CRGBA(255, 150, 225, 255)); Details.anonymous_23 = true; break;
+ case 'h': SetColor(CRGBA(225, 225, 225, 255)); Details.anonymous_23 = true; break;
+ case 'l': SetColor(CRGBA(0, 0, 0, 255)); Details.anonymous_23 = true; break;
+ case 'o': SetColor(CRGBA(229, 125, 126, 255)); Details.anonymous_23 = true; break;
+ case 'p': SetColor(CRGBA(168, 110, 252, 255)); Details.anonymous_23 = true; break;
+ case 'q': SetColor(CRGBA(199, 144, 203, 255)); Details.anonymous_23 = true; break;
+ case 'r': SetColor(CRGBA(255, 150, 225, 255)); Details.anonymous_23 = true; break;
+ case 't': SetColor(CRGBA(86, 212, 146, 255)); Details.anonymous_23 = true; break;
+ case 'w': SetColor(CRGBA(175, 175, 175, 255)); Details.anonymous_23 = true; break;
+#ifdef FIX_BUGS
+ case 'x': SetColor(CRGBA(0, 255, 255, 255)); Details.anonymous_23 = true; break;
+#else
+ case 'x': SetColor(CRGBA(132, 146, 197, 255)); Details.anonymous_23 = true; break;
+#endif
+ case 'y': SetColor(CRGBA(255, 227, 79, 255)); Details.anonymous_23 = true; break;
#ifdef BUTTON_ICONS
#if 0 // unused
case 'U': PS2Symbol = BUTTON_UP; break;
@@ -1308,20 +1355,210 @@ CFont::ParseToken(wchar *s, wchar*)
#endif
}
while(*s != '~') s++;
- return s+1;
+ if (*(++s) == '~')
+ s = ParseToken(s);
+ return s;
}
#endif
+wchar*
+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;
+ default:
+ break;
+ }
+ }
+ while (*s != '~')
+ ++s;
+ if (*(++s) == '~')
+ s = ParseToken(s, color, flash, bold);
+ return s;
+}
+
void
CFont::DrawFonts(void)
{
- 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
+ RenderFontBuffer();
+}
+
+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 == '~') {
+ pRenderStateBufPointer.pStr = ParseToken(pRenderStateBufPointer.pStr, color, bFlash, bBold);
+ 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;
+ }
+ textPosX += RenderState.scaleX * (RenderState.proportional ? Size[RenderState.style][c] : Size[RenderState.style][209]);
+ if (c == '\0')
+ textPosX += RenderState.fExtraSpace;
+ }
+ CSprite2d::RenderVertexBuffer();
+ FontRenderStatePointer.pRenderState = (CFontRenderState*)FontRenderStateBuf;
+}
+
+
+void
+CFont::SetFontStyle(int16 style)
+{
+ if (style == FONT_HEADING) {
+ Details.style = FONT_STANDARD;
+ Details.bFontHalfTexture = true;
+ } else {
+ Details.style = style;
+ Details.bFontHalfTexture = false;
+ }
+}
+
+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
@@ -1367,3 +1604,21 @@ CFont::SetDropColor(CRGBA col)
if (Details.alphaFade < 255.0f)
Details.dropColor.a *= Details.alphaFade / 255.0f;
}
+
+void
+CFont::FilterOutTokensFromString(wchar *str)
+{
+ 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';
+}
diff --git a/src/render/Font.h b/src/render/Font.h
index 7b67e310..d61ca6e7 100644
--- a/src/render/Font.h
+++ b/src/render/Font.h
@@ -4,6 +4,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
{
@@ -19,27 +20,54 @@ struct CFontDetails
bool background;
bool backgroundOnlyText;
bool proportional;
+ bool bIsShadow;
+ bool bFlash;
+ bool bBold;
float alphaFade;
CRGBA backgroundColor;
float wrapX;
float centreSize;
float rightJustifyWrap;
int16 style;
- int32 bank;
+ bool bFontHalfTexture;
+ uint32 bank;
int16 dropShadowPosition;
CRGBA dropColor;
+ bool bFlashState;
+ int nFlashTimer;
+ bool 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;
+ bool bIsShadow;
+ bool bFontHalfTexture;
+ bool proportional;
+ bool 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 {
@@ -95,12 +123,13 @@ class CFont
static uint8 LanguageSet;
static int32 Slot;
#else
- static int16 Size[MAX_FONTS][193];
+ static int16 Size[MAX_FONTS][210];
#endif
static int16 NewLine;
public:
static CSprite2d Sprite[MAX_FONTS];
static CFontDetails Details;
+ static CFontRenderState RenderState;
#ifdef BUTTON_ICONS
static int32 ButtonsSlot;
@@ -125,8 +154,9 @@ public:
#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);
+ 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);
@@ -135,11 +165,13 @@ public:
#endif
static uint16 *GetNextSpace(wchar *s);
#ifdef MORE_LANGUAGES
- static uint16 *ParseToken(wchar *s, wchar*, bool japShit = false);
+ static uint16 *ParseToken(wchar *s, bool japShit = false);
#else
- static uint16 *ParseToken(wchar *s, wchar*);
+ 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 CFontDetails GetDetails() { return Details; }
@@ -198,14 +230,15 @@ public:
static void SetBackGroundOnlyTextOff(void) { Details.backgroundOnlyText = false; }
static void SetPropOn(void) { Details.proportional = true; }
static void SetPropOff(void) { Details.proportional = false; }
- static void SetFontStyle(int16 style) { Details.style = style; }
+ static void SetFontStyle(int16 style);
static void SetRightJustifyWrap(float wrap) { Details.rightJustifyWrap = wrap; }
static void SetAlphaFade(float fade) { Details.alphaFade = fade; }
static void SetDropShadowPosition(int16 pos) { Details.dropShadowPosition = pos; }
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);
diff --git a/src/render/Glass.cpp b/src/render/Glass.cpp
index 0b25525e..a11495a9 100644
--- a/src/render/Glass.cpp
+++ b/src/render/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);
@@ -296,8 +311,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();
@@ -308,10 +323,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 )
@@ -342,11 +357,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();
@@ -362,7 +374,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;
@@ -375,10 +387,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;
}
@@ -386,6 +399,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;
}
}
@@ -617,42 +631,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
@@ -662,7 +682,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;
@@ -678,15 +698,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);
+ }
}
}
}
@@ -697,19 +720,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/render/Glass.h b/src/render/Glass.h
index 51c5aae9..f1c85779 100644
--- a/src/render/Glass.h
+++ b/src/render/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/render/Hud.cpp b/src/render/Hud.cpp
index 1a39e1c7..db952191 100644
--- a/src/render/Hud.cpp
+++ b/src/render/Hud.cpp
@@ -20,25 +20,33 @@
#include "TxdStore.h"
#include "User.h"
#include "World.h"
+#include "CutsceneMgr.h"
+#include "Stats.h"
+#include "main.h"
+#include "General.h"
+
+// --MIAMI: file done
// 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);
wchar CHud::m_HelpMessage[HELP_MSG_LENGTH];
@@ -48,6 +56,7 @@ uint32 CHud::m_HelpMessageTimer;
int32 CHud::m_HelpMessageFadeTimer;
wchar CHud::m_HelpMessageToPrint[HELP_MSG_LENGTH];
float CHud::m_HelpMessageDisplayTime;
+bool CHud::m_HelpMessageDisplayForever;
bool CHud::m_HelpMessageQuick;
uint32 CHud::m_ZoneState;
int32 CHud::m_ZoneFadeTimer;
@@ -67,15 +76,17 @@ 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 CHud::BigMessageInUse[6];
float CHud::BigMessageAlpha[6];
float CHud::BigMessageX[6];
float CHud::OddJob2OffTimer;
-bool CHud::CounterOnLastFrame;
+bool CHud::CounterOnLastFrame[NUMONSCREENCOUNTERS];
float CHud::OddJob2XOffset;
-uint16 CHud::CounterFlashTimer;
+uint16 CHud::CounterFlashTimer[NUMONSCREENCOUNTERS];
uint16 CHud::OddJob2Timer;
bool CHud::TimerOnLastFrame;
int16 CHud::OddJob2On;
@@ -86,6 +97,26 @@ 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;
+
CSprite2d CHud::Sprites[NUM_HUD_SPRITES];
struct
@@ -93,36 +124,89 @@ 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", "" }
};
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;
@@ -131,25 +215,32 @@ void CHud::Draw()
return;
if (m_Wants_To_Draw_Hud && !TheCamera.m_WideScreenOn) {
+ // unused statics in here
bool DrawCrossHair = false;
+ bool CrossHairHidesHud = false;
bool DrawCrossHairPC = false;
- int32 WeaponType = FindPlayerPed()->m_weapons[FindPlayerPed()->m_currentWeapon].m_eWeaponType;
+ CPlayerPed *playerPed = FindPlayerPed();
+ eWeaponType WeaponType = playerPed->GetWeapon()->m_eWeaponType;
int32 Mode = TheCamera.Cams[TheCamera.ActiveCam].Mode;
- if (Mode == CCam::MODE_SNIPER || Mode == CCam::MODE_ROCKETLAUNCHER || Mode == CCam::MODE_M16_1STPERSON || Mode == CCam::MODE_HELICANNON_1STPERSON)
+ 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;
+
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;
+ }
+ }
}
}
@@ -169,7 +260,7 @@ void CHud::Draw()
#ifdef ASPECT_RATIO_SCALE
f3rdY -= SCREEN_SCALE_Y(2.0f);
#endif
- if (FindPlayerPed() && WeaponType == WEAPONTYPE_M16) {
+ if (playerPed && (WeaponType == WEAPONTYPE_M4 || WeaponType == WEAPONTYPE_RUGER || WeaponType == WEAPONTYPE_M60)) {
rect.left = f3rdX - SCREEN_SCALE_X(32.0f * 0.6f);
rect.top = f3rdY - SCREEN_SCALE_Y(32.0f * 0.6f);
rect.right = f3rdX + SCREEN_SCALE_X(32.0f * 0.6f);
@@ -187,8 +278,7 @@ 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 {
+ } else {
if (Mode == CCam::MODE_M16_1STPERSON ||
Mode == CCam::MODE_M16_1STPERSON_RUNABOUT ||
Mode == CCam::MODE_HELICANNON_1STPERSON) {
@@ -198,7 +288,6 @@ void CHud::Draw()
rect.bottom = (SCREEN_HEIGHT / 2) + SCREEN_SCALE_Y(32.0f);
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 if (Mode == CCam::MODE_1STPERSON_RUNABOUT) {
rect.left = (SCREEN_WIDTH / 2) - SCREEN_SCALE_X(32.0f * 0.7f);
@@ -218,229 +307,393 @@ void CHud::Draw()
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(gpRocketSightTex));
CSprite::RenderOneXLUSprite(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, 1.0f, SCREEN_SCALE_X(40.0f), SCREEN_SCALE_Y(40.0f), (100.0f * fMultBright), (200.0f * fMultBright), (100.0f * fMultBright), 255, 1.0f, 255);
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
+ 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);
-
- 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));
+ 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::PrintString(SCREEN_SCALE_FROM_RIGHT(110.0f - 2.0f), SCREEN_SCALE_Y(43.0f + 2.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);
- CFont::SetColor(MONEY_COLOR);
- CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(110.0f), SCREEN_SCALE_Y(43.0f), sPrint);
+ if (FrontEndMenuManager.m_PrefsShowHud) {
+ CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(110.0f), SCREEN_SCALE_Y(43.0f), sPrint);
+ }
+ }
/*
DrawAmmo
*/
- uint32 AmmoAmount = CWeaponInfo::GetWeaponInfo(FindPlayerPed()->GetWeapon()->m_eWeaponType)->m_nAmountofAmmunition;
- uint32 AmmoInClip = FindPlayerPed()->m_weapons[FindPlayerPed()->m_currentWeapon].m_nAmmoInClip;
- uint32 TotalAmmo = FindPlayerPed()->m_weapons[FindPlayerPed()->m_currentWeapon].m_nAmmoTotal;
- uint32 Ammo, Clip;
+ 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();
+ uint32 AmmoAmount = CWeaponInfo::GetWeaponInfo((eWeaponType)WeaponType)->m_nAmountofAmmunition;
+ uint32 AmmoInClip = weapon->m_nAmmoInClip;
+ uint32 TotalAmmo = weapon->m_nAmmoTotal;
+ uint32 Ammo, Clip;
+
+ if (AmmoAmount <= 1 || AmmoAmount >= 1000)
+ sprintf(sTemp, "%d", TotalAmmo);
+ else {
+ if (WeaponType == WEAPONTYPE_FLAMETHROWER) {
+ Clip = AmmoInClip / 10;
- if (AmmoAmount <= 1 || AmmoAmount >= 1000)
- sprintf(sTemp, "%d", TotalAmmo);
- else {
- if (WeaponType == WEAPONTYPE_FLAMETHROWER) {
- Clip = AmmoInClip / 10;
+ Ammo = Min((TotalAmmo - AmmoInClip) / 10, 9999);
+ } else {
+ Clip = AmmoInClip;
- if ((TotalAmmo - AmmoInClip) / 10 <= 9999)
- Ammo = (TotalAmmo - AmmoInClip) / 10;
- else
- Ammo = 9999;
- }
- else {
- Clip = AmmoInClip;
+ Ammo = Min(TotalAmmo - AmmoInClip, 9999);
+ }
- if ((TotalAmmo - AmmoInClip) > 9999)
- Ammo = 9999;
- else
- Ammo = TotalAmmo - AmmoInClip;
+ sprintf(sTemp, "%d-%d", Ammo, Clip);
}
- sprintf(sTemp, "%d-%d", Ammo, Clip);
- }
+ 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->GetName());
+ 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
+ }
+ }
+ }
- AsciiToUnicode(sTemp, 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);
+ }
+ }
+ }
/*
- DrawWeaponIcon
+ DrawHealth
*/
- 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, 255),
- 0.015f,
- 0.015f,
- 1.0f,
- 0.0f,
- 0.015f,
- 1.0f,
- 1.0f,
- 1.0f);
+ 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;
+ }
- 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);
+ 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 (!CDarkel::FrenzyOnGoing() && WeaponType != WEAPONTYPE_UNARMED && WeaponType != WEAPONTYPE_BASEBALLBAT) {
- CFont::SetColor(AMMO_COLOR);
- CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(66.0f), SCREEN_SCALE_Y(73.0f), sPrint);
- }
+ if (m_ItemToFlash == ITEM_HEALTH && CTimer::GetFrameCounter() & 8
+ || m_ItemToFlash != ITEM_HEALTH
+ || playerPed->m_fHealth < 10
+ && CTimer::GetFrameCounter() & 8) {
+ if (playerPed->m_fHealth >= 10
+ || playerPed->m_fHealth < 10 && CTimer::GetFrameCounter() & 8) {
- /*
- 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 && CTimer::GetFrameCounter() & 8
- || m_ItemToFlash != ITEM_HEALTH
- || FindPlayerPed()->m_fHealth < 10
- && CTimer::GetFrameCounter() & 8) {
- if (FindPlayerPed()->m_fHealth >= 10
- || FindPlayerPed()->m_fHealth < 10 && CTimer::GetFrameCounter() & 8) {
-
- AsciiToUnicode("{", sPrintIcon);
+ 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);
+ AsciiToUnicode(sTemp, sPrint);
- CFont::SetColor(CRGBA(0, 0, 0, 255));
- CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(110.0f - 2.0f), SCREEN_SCALE_Y(65.0f + 2.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 || CTimer::GetFrameCounter() & 4) {
- CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(164.0f - 2.0f), SCREEN_SCALE_Y(65.0f + 2.0f), sPrintIcon);
+ if (!CWorld::Players[CWorld::PlayerInFocus].m_nTimeLastHealthLoss || CTimer::GetTimeInMilliseconds() > CWorld::Players[CWorld::PlayerInFocus].m_nTimeLastHealthLoss + 2000 || CTimer::GetFrameCounter() & 4) {
+ // CFont::SetColor(HEALTH_COLOR);
+ CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(110.0f + 54.0f), SCREEN_SCALE_Y(65.0f), sPrintIcon);
+ }
+ }
}
- CFont::SetColor(HEALTH_COLOR);
+ }
- CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(110.0f), SCREEN_SCALE_Y(65.0f), sPrint);
+ /*
+ DrawArmour
+ */
+ if (m_ItemToFlash == ITEM_ARMOUR && CTimer::GetFrameCounter() & 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(playerPed->m_fArmour + 0.5f));
+#else
+ sprintf(sTemp, "%03d", (int32)playerPed->m_fArmour);
+#endif
+ AsciiToUnicode(sTemp, sPrint);
+
+ CFont::SetColor(ARMOUR_COLOR);
+ if (FrontEndMenuManager.m_PrefsShowHud) {
- if (!CWorld::Players[CWorld::PlayerInFocus].m_nTimeLastHealthLoss || CTimer::GetTimeInMilliseconds() > CWorld::Players[CWorld::PlayerInFocus].m_nTimeLastHealthLoss + 2000 || CTimer::GetFrameCounter() & 4) {
- CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(164.0f), SCREEN_SCALE_Y(65.0f), sPrintIcon);
+ 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 || CTimer::GetFrameCounter() & 4) {
+ // CFont::SetColor(ARMOUR_COLOR);
+ CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(182.0f + 52.0f), SCREEN_SCALE_Y(65.0f), sPrintIcon);
+ }
+ }
}
}
}
/*
- DrawArmour
+ DrawWantedLevel
*/
- if (m_ItemToFlash == ITEM_ARMOUR && CTimer::GetFrameCounter() & 8 || m_ItemToFlash != ITEM_ARMOUR) {
- CFont::SetScale(SCREEN_SCALE_X(0.8f), SCREEN_SCALE_Y(1.35f));
- if (FindPlayerPed()->m_fArmour > 1.0f) {
- AsciiToUnicode("[", sPrintIcon);
-#ifdef FIX_BUGS
- sprintf(sTemp, "%03d", int32(FindPlayerPed()->m_fArmour + 0.5f));
-#else
- sprintf(sTemp, "%03d", (int32)FindPlayerPed()->m_fArmour);
-#endif
- AsciiToUnicode(sTemp, sPrint);
+ if (m_LastWanted == playerPed->m_pWanted->m_nWantedLevel) {
+ alpha = DrawFadeState(HUD_WANTED_FADING, 0);
+ } else {
+ alpha = DrawFadeState(HUD_WANTED_FADING, 1);
+ m_LastWanted = playerPed->m_pWanted->m_nWantedLevel;
+ }
+
+ 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);
- CFont::SetColor(CRGBA(0, 0, 0, 255));
- CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(182.0f - 2.0f), SCREEN_SCALE_Y(65.0f + 2.0f), sPrint);
+ AsciiToUnicode(">", sPrintIcon);
- if (!CWorld::Players[CWorld::PlayerInFocus].m_nTimeLastArmourLoss || CTimer::GetTimeInMilliseconds() > CWorld::Players[CWorld::PlayerInFocus].m_nTimeLastArmourLoss + 2000 || CTimer::GetFrameCounter() & 4) {
- CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(234.0f - 2.0f), SCREEN_SCALE_Y(65.0f + 2.0f), sPrintIcon);
- }
+ for (int i = 0; i < 6; i++) {
+ if (FrontEndMenuManager.m_PrefsShowHud) {
+ if (playerPed->m_pWanted->m_nWantedLevel > i
+ && (CTimer::GetTimeInMilliseconds() > playerPed->m_pWanted->m_nLastWantedLevelChange
+ + 2000 || CTimer::GetFrameCounter() & 4)) {
- CFont::SetColor(ARMOUR_COLOR);
+ 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);
- CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(182.0f), SCREEN_SCALE_Y(65.0f), sPrint);
+ } else if (playerPed->m_pWanted->m_nMinWantedLevel > i && CTimer::GetFrameCounter() & 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);
- if (!CWorld::Players[CWorld::PlayerInFocus].m_nTimeLastArmourLoss || CTimer::GetTimeInMilliseconds() > CWorld::Players[CWorld::PlayerInFocus].m_nTimeLastArmourLoss + 2000 || CTimer::GetFrameCounter() & 1) {
- CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(234.0f), SCREEN_SCALE_Y(65.0f), sPrintIcon);
+ } else if (playerPed->m_pWanted->m_nWantedLevel <= i) {
+ NOTWANTED_COLOR.a = alpha;
+ CFont::SetColor(NOTWANTED_COLOR);
+ CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(110.0f + 23.0f * i), SCREEN_SCALE_Y(87.0f), sPrintIcon);
+ }
}
}
}
- /*
- 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);
-
- AsciiToUnicode("]", 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));
- for (int i = 0; i < 6; i++) {
- CFont::SetColor(CRGBA(0, 0, 0, 255));
- CFont::PrintString(2.0f + SCREEN_SCALE_FROM_RIGHT(60.0f - 2.0f + 24.0f * i), SCREEN_SCALE_Y(87.0f + 2.0f), sPrintIcon);
- if (FindPlayerPed()->m_pWanted->m_nWantedLevel > i
- && (CTimer::GetTimeInMilliseconds() > FindPlayerPed()->m_pWanted->m_nLastWantedLevelChange
- + 2000 || CTimer::GetFrameCounter() & 4)) {
+ 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(SCREEN_SCALE_FROM_RIGHT(60.0f + 24.0f * i), 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);
+ }
}
}
@@ -448,7 +701,6 @@ void CHud::Draw()
DrawZoneName
*/
if (m_pZoneName) {
- float fZoneAlpha = 255.0f;
if (m_pZoneName != m_pLastZoneName) {
switch (m_ZoneState) {
@@ -457,6 +709,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:
@@ -471,19 +725,20 @@ 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;
}
@@ -491,7 +746,7 @@ void CHud::Draw()
break;
case 3:
m_ZoneFadeTimer -= CTimer::GetTimeStepInMilliseconds();
- if (m_ZoneFadeTimer < 0) {
+ if (m_ZoneFadeTimer < 0.0f) {
m_ZoneState = 0;
m_ZoneFadeTimer = 0;
}
@@ -499,7 +754,7 @@ void CHud::Draw()
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;
@@ -511,30 +766,35 @@ void CHud::Draw()
}
-#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(1.0f), SCREEN_SCALE_FROM_BOTTOM(30.0f) + SCREEN_SCALE_Y(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(30.0f), 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;
}
}
}
@@ -552,6 +812,8 @@ void CHud::Draw()
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:
@@ -605,30 +867,31 @@ void CHud::Draw()
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
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(1.0f), SCREEN_SCALE_FROM_BOTTOM(55.0f) + SCREEN_SCALE_Y(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(55.0f), 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);
}
}
}
@@ -642,25 +905,26 @@ 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);
-
- sprintf(sTemp, "%02d:%02d", CClock::GetHours(), CClock::GetMinutes());
- AsciiToUnicode(sTemp, sPrint);
-
- CFont::SetColor(CRGBA(0, 0, 0, 255));
+ 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));
- CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(111.0f) + SCREEN_SCALE_X(2.0f), SCREEN_SCALE_Y(22.0f) + SCREEN_SCALE_Y(2.0f), sPrint);
+ sprintf(sTemp, "%02d:%02d", CClock::GetHours(), CClock::GetMinutes());
+ AsciiToUnicode(sTemp, sPrint);
- CFont::SetColor(CLOCK_COLOR);
- CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(111.0f), 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
@@ -668,172 +932,137 @@ void CHud::Draw()
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;
-#ifdef FIX_BUGS
-#define TIMER_RIGHT_OFFSET 34.0f // Taken from VC frenzy timer
-#else
-#define TIMER_RIGHT_OFFSET 27.0f
-#endif
+ 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 (CTimer::GetFrameCounter() & 4 || !TimerFlashTimer) {
- AsciiToUnicode(CUserDisplay::OnscnTimer.m_sEntries[0].m_bTimerBuffer, sTimer);
+ if (CTimer::GetFrameCounter() & 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(2.0f), SCREEN_SCALE_Y(110.0f) + SCREEN_SCALE_Y(2.0f), sTimer);
- CFont::SetScale(SCREEN_SCALE_X(0.8f), SCREEN_SCALE_Y(1.35f));
+ CFont::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);
-
- if (CUserDisplay::OnscnTimer.m_sEntries[0].m_aTimerText[0]) {
- CFont::SetPropOn();
- CFont::SetColor(CRGBA(0, 0, 0, 255));
- CFont::SetScale(SCREEN_SCALE_X(0.64f), SCREEN_SCALE_Y(1.35f));
- CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(TIMER_RIGHT_OFFSET) - SCREEN_SCALE_X(80.0f) + SCREEN_SCALE_X(2.0f), SCREEN_SCALE_Y(110.0f) + SCREEN_SCALE_Y(2.0f), TheText.Get(CUserDisplay::OnscnTimer.m_sEntries[0].m_aTimerText));
+ CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(37.0f), SCREEN_SCALE_Y(110.0f), sTimer);
+ CFont::SetPropOn();
+ 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 (CTimer::GetFrameCounter() & 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(2.0f), SCREEN_SCALE_Y(132.0f) + SCREEN_SCALE_Y(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(4.0f), SCREEN_SCALE_Y(132.0f) + SCREEN_SCALE_Y(8.0f), SCREEN_SCALE_FROM_RIGHT(TIMER_RIGHT_OFFSET) + SCREEN_SCALE_X(4.0f), SCREEN_SCALE_Y(132.0f) + SCREEN_SCALE_Y(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(4.0f), SCREEN_SCALE_Y(132.0f) + SCREEN_SCALE_Y(8.0f), SCREEN_SCALE_X(counter) / 2.0f + SCREEN_SCALE_FROM_RIGHT(TIMER_RIGHT_OFFSET + 50.0f) + SCREEN_SCALE_X(4.0f), SCREEN_SCALE_Y(132.0f) + SCREEN_SCALE_Y(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_Y(2.0f), SCREEN_SCALE_Y(132.0f) + SCREEN_SCALE_Y(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 (CTimer::GetFrameCounter() & 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));
}
}
}
}
-#undef TIMER_RIGHT_OFFSET
-
- /*
- 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 - PagerXOffset), SCREEN_SCALE_Y(27.0f), SCREEN_SCALE_X(160.0 + 26.0f - PagerXOffset), SCREEN_SCALE_Y(80.0f + 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::SetJustifyOff();
- CFont::SetPropOff();
- CFont::SetFontStyle(FONT_PAGER);
- CFont::PrintString(SCREEN_SCALE_X(52.0f - PagerXOffset), SCREEN_SCALE_Y(54.0f), m_PagerMessage);
- }
/*
DrawRadar
*/
- if (m_ItemToFlash == ITEM_RADAR && CTimer::GetFrameCounter() & 8 || m_ItemToFlash != ITEM_RADAR) {
+ if (FrontEndMenuManager.m_PrefsRadarMode != 2 &&
+ !m_HideRadar && (m_ItemToFlash == ITEM_RADAR && CTimer::GetFrameCounter() & 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));
+ if (FrontEndMenuManager.m_PrefsRadarMode != 1) {
+ CRect rect(0.0f, 0.0f, SCREEN_SCALE_X(RADAR_WIDTH), SCREEN_SCALE_Y(RADAR_HEIGHT));
#ifdef FIX_BUGS
- rect.Translate(SCREEN_SCALE_X(RADAR_LEFT), SCREEN_SCALE_FROM_BOTTOM(RADAR_BOTTOM + RADAR_HEIGHT));
+ rect.Translate(SCREEN_SCALE_X(RADAR_LEFT), SCREEN_SCALE_FROM_BOTTOM(RADAR_BOTTOM + RADAR_HEIGHT));
#else
- rect.Translate(RADAR_LEFT, SCREEN_SCALE_FROM_BOTTOM(RADAR_BOTTOM + RADAR_HEIGHT));
+ rect.Translate(RADAR_LEFT, SCREEN_SCALE_FROM_BOTTOM(RADAR_BOTTOM + RADAR_HEIGHT));
#endif
- rect.Grow(4.0f);
- Sprites[HUD_RADARDISC].Draw(rect, RADARDISC_COLOR);
+
+ rect.Grow(6.0f);
+ rect.Translate(0.0f, 2.0f);
+ Sprites[HUD_RADARDISC].Draw(rect, CRGBA(0, 0, 0, 255));
+ rect.Translate(0.0f, -2.0f);
+ Sprites[HUD_RADARDISC].Draw(rect, RADARDISC_COLOR);
+ }
CRadar::DrawBlips();
}
}
@@ -922,40 +1151,166 @@ 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(0.48f), SCREEN_SCALE_Y(1.12f));
CFont::SetCentreOn();
CFont::SetPropOn();
- CFont::SetFontStyle(FONT_LOCALE(FONT_BANK));
+ CFont::SetDropShadowPosition(0);
+ CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD));
+ CFont::SetColor(CRGBA(225, 225, 225, 255));
+
+ static bool onceItWasWidescreen = false;
+
+ 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';
-#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));
+ 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));
- 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_WIDTH - SCREEN_SCALE_X(50.0f) - SCREEN_SCALE_X(8.0f) - radarBulge;
- CFont::SetCentreSize(rectWidth);
+ 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);
- const int16 shadow = 1;
- CFont::SetDropShadowPosition(shadow);
- CFont::SetDropColor(CRGBA(0, 0, 0, 255));
- CFont::SetColor(CRGBA(235, 235, 235, 255));
-
- // 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(shadow), SCREEN_SCALE_Y(4.0f) + SCREEN_SCALE_FROM_BOTTOM(68.0f) - SCREEN_SCALE_Y(shadow), m_Message);
+ CFont::PrintString(rectWidth / 2.0f + radarBulge, SCREEN_SCALE_FROM_BOTTOM(105.f + 2.0f), m_Message);
+ }
CFont::SetDropShadowPosition(0);
-#endif
}
/*
+ 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_SOUND, 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
@@ -964,10 +1319,15 @@ void CHud::Draw()
CFont::SetJustifyOff();
CFont::SetBackgroundOff();
CFont::SetBackGroundOnlyTextOff();
- CFont::SetScale(SCREEN_SCALE_X(1.8f), SCREEN_SCALE_Y(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(615.0f));
+ 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.
@@ -992,18 +1352,11 @@ void CHud::Draw()
if (BigMessageAlpha[0] > 255.0f)
BigMessageAlpha[0] = 255.0f;
}
-
- CFont::SetColor(CRGBA(0, 0, 0, BigMessageAlpha[0]));
-#ifdef FIX_BUGS
-#define Y_OFFSET 18.0f
-#else
-#define Y_OFFSET 20.0f
-#endif
- CFont::PrintString(SCREEN_WIDTH / 2 + SCREEN_SCALE_X(2.0f), (SCREEN_HEIGHT / 2) - SCREEN_SCALE_Y(Y_OFFSET) + SCREEN_SCALE_Y(2.0f), m_BigMessage[0]);
+ 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]));
CFont::PrintString(SCREEN_WIDTH / 2, (SCREEN_HEIGHT / 2) - SCREEN_SCALE_Y(18.0f), m_BigMessage[0]);
-
-#undef Y_OFFSET
}
else {
BigMessageAlpha[0] = 0.0f;
@@ -1034,15 +1387,19 @@ void CHud::Draw()
CFont::SetRightJustifyOn();
CFont::SetFontStyle(FONT_HEADING);
- CFont::SetColor(CRGBA(0, 0, 0, BigMessageAlpha[2]));
- CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(20.0f - 4.0f), SCREEN_SCALE_FROM_BOTTOM(78.0f), m_BigMessage[2]);
+ CFont::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(82.0f), 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 {
@@ -1053,108 +1410,13 @@ 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) * 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_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 * 0.001f * 225.0f;
- break;
- case 3:
- m_HelpMessageFadeTimer -= 2 * CTimer::GetTimeStepInMilliseconds();
- if (m_HelpMessageFadeTimer < 0) {
- 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;
- }
-
- 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 + 26.0f - 4.0f));
- else
-#endif
- CFont::SetWrapx(SCREEN_SCALE_X(200.0f + 26.0f - 4.0f));
- CFont::SetFontStyle(FONT_LOCALE(FONT_BANK));
- CFont::SetBackgroundOn();
- CFont::SetBackGroundOnlyTextOff();
- CFont::SetBackgroundColor(CRGBA(0, 0, 0, fAlpha * 0.9f));
- CFont::PrintString(SCREEN_SCALE_X(26.0f), SCREEN_SCALE_Y(28.0f + (150.0f - PagerXOffset) * 0.6f), CHud::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) {
@@ -1224,13 +1486,11 @@ void CHud::DrawAfterFade()
CFont::SetCentreOn();
CFont::SetPropOn();
CFont::SetCentreSize(SCREEN_SCALE_X(600.0f));
- CFont::SetFontStyle(FONT_LOCALE(FONT_BANK));
-
- CFont::SetColor(CRGBA(0, 0, 0, 255));
- CFont::PrintString((SCREEN_WIDTH / 2) + SCREEN_SCALE_X(2.0f), (SCREEN_HEIGHT / 2) - SCREEN_SCALE_Y(84.0f) + SCREEN_SCALE_Y(2.0f), m_BigMessage[3]);
-
+ CFont::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(84.0f), 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]) {
@@ -1239,14 +1499,12 @@ void CHud::DrawAfterFade()
CFont::SetScale(SCREEN_SCALE_X(1.2f), SCREEN_SCALE_Y(1.5f));
CFont::SetCentreOn();
CFont::SetPropOn();
- CFont::SetCentreSize(SCREEN_SCALE_X(620.0f));
- CFont::SetColor(CRGBA(0, 0, 0, 255));
- CFont::SetFontStyle(FONT_LOCALE(FONT_BANK));
-
- CFont::PrintString((SCREEN_WIDTH / 2) - SCREEN_SCALE_X(2.0f), (SCREEN_HEIGHT / 2) - SCREEN_SCALE_Y(84.0f) - SCREEN_SCALE_Y(2.0f), m_BigMessage[4]);
-
+ CFont::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(84.0f), m_BigMessage[4]);
+ CFont::PrintString((SCREEN_WIDTH / 2), SCREEN_SCALE_Y(140.0f), m_BigMessage[4]);
}
// Oddjob result
@@ -1296,21 +1554,12 @@ void CHud::DrawAfterFade()
CFont::SetScale(SCREEN_SCALE_X(1.0f), SCREEN_SCALE_Y(1.2f));
CFont::SetCentreOn();
CFont::SetPropOn();
- CFont::SetCentreSize(SCREEN_SCALE_X(620.0f));
- 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(2.0f) - SCREEN_SCALE_X(OddJob2XOffset), SCREEN_HEIGHT / 2 - SCREEN_SCALE_Y(20.0f) + SCREEN_SCALE_Y(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(2.0f), SCREEN_HEIGHT / 2 - SCREEN_SCALE_Y(20.0f) + SCREEN_SCALE_Y(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]);
}
}
@@ -1322,64 +1571,60 @@ 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(0.884f), SCREEN_SCALE_Y(1.36f));
else
CFont::SetScale(SCREEN_SCALE_X(1.04f), SCREEN_SCALE_Y(1.6f));
CFont::SetPropOn();
- CFont::SetRightJustifyWrap(SCREEN_SCALE_FROM_RIGHT(DEFAULT_SCREEN_WIDTH + 500.0f));
+ CFont::SetRightJustifyWrap(SCALE_AND_CENTER_X(0.0f));
CFont::SetRightJustifyOn();
- CFont::SetFontStyle(FONT_HEADING);
+ 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((CTimer::GetTimeStepInMilliseconds() * 0.3f));
- BigMessageAlpha[1] += (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(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(BigMessageX[1], SCREEN_SCALE_FROM_BOTTOM(120.0f), m_BigMessage[1]);
-#else
- CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(20.0f) + SCREEN_SCALE_X(2.0f), SCREEN_SCALE_FROM_BOTTOM(120.0f) + SCREEN_SCALE_Y(2.0f), m_BigMessage[1]);
-
- CFont::SetColor(CRGBA(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;
+ CFont::PrintString(BigMessageX[1], SCREEN_SCALE_FROM_BOTTOM(140.0f), m_BigMessage[1]);
+ } else {
+ m_ZoneFadeTimer = 0;
BigMessageX[1] = SCREEN_SCALE_FROM_RIGHT(DEFAULT_SCREEN_WIDTH + 60.0f);
BigMessageInUse[1] = 1.0f;
+ m_ZoneState = 0;
}
- }
- else {
+ } else {
BigMessageInUse[1] = 0.0f;
}
}
void CHud::GetRidOfAllHudMessages()
{
- m_ZoneState = 0;
- m_pLastZoneName = nil;
m_ZoneNameTimer = 0;
m_pZoneName = nil;
+ m_ZoneState = 0;
for (int i = 0; i < HELP_MSG_LENGTH; i++) {
m_HelpMessage[i] = 0;
@@ -1391,9 +1636,9 @@ void CHud::GetRidOfAllHudMessages()
m_HelpMessageFadeTimer = 0;
m_HelpMessageState = 0;
m_HelpMessageQuick = 0;
+ m_HelpMessageDisplayForever = false;
m_HelpMessageDisplayTime = 1.0f;
m_VehicleName = nil;
- m_pLastVehicleName = nil;
m_pVehicleNameToPrint = nil;
m_VehicleNameTimer = 0;
m_VehicleFadeTimer = 0;
@@ -1410,6 +1655,30 @@ void CHud::GetRidOfAllHudMessages()
}
}
+#ifdef RELOADABLES
+void CHud::ReloadTXD()
+{
+ for (int i = 0; i < NUM_HUD_SPRITES; ++i) {
+ Sprites[i].Delete();
+ }
+
+ int HudTXD = CTxdStore::FindTxdSlot("hud");
+ CTxdStore::RemoveTxdSlot(HudTXD);
+
+ debug("Reloading HUD.TXD...\n");
+
+ HudTXD = CTxdStore::AddTxdSlot("hud");
+ CTxdStore::LoadTxd(HudTXD, "MODELS/HUD.TXD");
+ CTxdStore::AddRef(HudTXD);
+ CTxdStore::PopCurrentTxd();
+ CTxdStore::SetCurrentTxd(HudTXD);
+
+ for (int i = 0; i < NUM_HUD_SPRITES; i++) {
+ Sprites[i].SetTexture(WeaponFilenames[i].name, WeaponFilenames[i].mask);
+ }
+}
+#endif
+
void CHud::Initialise()
{
m_Wants_To_Draw_Hud = true;
@@ -1425,20 +1694,34 @@ void CHud::Initialise()
Sprites[i].SetTexture(WeaponFilenames[i].name, WeaponFilenames[i].mask);
}
+ m_pLastZoneName = nil;
GetRidOfAllHudMessages();
+ m_pLastVehicleName = nil;
if (gpSniperSightTex == nil)
- gpSniperSightTex = RwTextureRead("sitesniper", nil);
+ gpSniperSightTex = RwTextureRead("sitesniper", nil); // unused
if (gpRocketSightTex == nil)
gpRocketSightTex = RwTextureRead("siterocket", nil);
-
- CounterOnLastFrame = false;
+ 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;
+ CounterFlashTimer[0] = 0;
+ CounterFlashTimer[1] = 0;
+ CounterFlashTimer[2] = 0;
TimerOnLastFrame = false;
TimerFlashTimer = 0;
SpriteBrightness = 0;
@@ -1447,6 +1730,32 @@ void CHud::Initialise()
PagerSoundPlayed = 0;
PagerXOffset = 150.0f;
+#ifdef HUD_AUTO_FADE
+ m_EnergyLostState = START_FADE_OUT;
+ m_WantedState = START_FADE_OUT;
+ m_DisplayScoreState = START_FADE_OUT;
+ m_WeaponState = START_FADE_OUT;
+#else
+ m_EnergyLostState = FADE_DISABLED;
+ m_WantedState = FADE_DISABLED;
+ m_DisplayScoreState = FADE_DISABLED;
+ m_WeaponState = FADE_DISABLED;
+#endif
+ m_WantedFadeTimer = 0;
+ m_WantedTimer = 0;
+ m_EnergyLostFadeTimer = 0;
+ m_EnergyLostTimer = 0;
+ m_DisplayScoreFadeTimer = 0;
+ m_DisplayScoreTimer = 0;
+ m_WeaponFadeTimer = 0;
+ m_WeaponTimer = 0;
+
+ m_HideRadar = false;
+ m_LastDisplayScore = CWorld::Players[CWorld::PlayerInFocus].m_nVisibleMoney;
+ m_LastTimeEnergyLost = CWorld::Players[CWorld::PlayerInFocus].m_nTimeLastHealthLoss;
+ m_LastWanted = 0;
+ m_LastWeapon = 0;
+
CTxdStore::PopCurrentTxd();
}
@@ -1454,15 +1763,22 @@ void CHud::ReInitialise() {
m_Wants_To_Draw_Hud = true;
m_Wants_To_Draw_3dMarkers = true;
+ m_pLastZoneName = nil;
GetRidOfAllHudMessages();
+ m_pLastVehicleName = nil;
- CounterOnLastFrame = false;
+ 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;
+ CounterFlashTimer[0] = 0;
+ CounterFlashTimer[1] = 0;
+ CounterFlashTimer[2] = 0;
TimerOnLastFrame = false;
TimerFlashTimer = 0;
SpriteBrightness = 0;
@@ -1470,6 +1786,32 @@ void CHud::ReInitialise() {
PagerTimer = 0;
PagerSoundPlayed = 0;
PagerXOffset = 150.0f;
+
+#ifdef HUD_AUTO_FADE
+ m_EnergyLostState = START_FADE_OUT;
+ m_WantedState = START_FADE_OUT;
+ m_DisplayScoreState = START_FADE_OUT;
+ m_WeaponState = START_FADE_OUT;
+#else
+ m_EnergyLostState = FADE_DISABLED;
+ m_WantedState = FADE_DISABLED;
+ m_DisplayScoreState = FADE_DISABLED;
+ m_WeaponState = FADE_DISABLED;
+#endif
+ m_WantedFadeTimer = 0;
+ m_WantedTimer = 0;
+ m_EnergyLostFadeTimer = 0;
+ m_EnergyLostTimer = 0;
+ m_DisplayScoreFadeTimer = 0;
+ m_DisplayScoreTimer = 0;
+ m_WeaponFadeTimer = 0;
+ m_WeaponTimer = 0;
+
+ m_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];
@@ -1478,6 +1820,9 @@ 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)
@@ -1502,21 +1847,50 @@ void CHud::SetBigMessage(wchar *message, uint16 style)
m_BigMessage[style][i] = 0;
}
-void CHud::SetHelpMessage(wchar *message, bool quick)
+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;
+ }
- 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;
}
- m_HelpMessageState = 0;
- m_HelpMessageQuick = quick;
}
}
+bool CHud::IsHelpMessageBeingDisplayed(void)
+{
+ return m_HelpMessageState != 0;
+}
+
void CHud::SetMessage(wchar *message)
{
int i = 0;
@@ -1563,6 +1937,127 @@ void CHud::Shutdown()
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/render/Hud.h b/src/render/Hud.h
index bef73cc2..a4b9609a 100644
--- a/src/render/Hud.h
+++ b/src/render/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,27 +14,37 @@ 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
@@ -45,6 +58,7 @@ public:
static int32 m_HelpMessageFadeTimer;
static wchar m_HelpMessageToPrint[HELP_MSG_LENGTH];
static float m_HelpMessageDisplayTime;
+ static bool m_HelpMessageDisplayForever;
static bool m_HelpMessageQuick;
static uint32 m_ZoneState;
static int32 m_ZoneFadeTimer;
@@ -64,15 +78,17 @@ public:
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;
+ static bool CounterOnLastFrame[NUMONSCREENCOUNTERS];
static float OddJob2XOffset;
- static uint16 CounterFlashTimer;
+ static uint16 CounterFlashTimer[NUMONSCREENCOUNTERS];
static uint16 OddJob2Timer;
static bool TimerOnLastFrame;
static int16 OddJob2On;
@@ -83,17 +99,41 @@ public:
static int16 PagerTimer;
static int16 PagerOn;
+ static uint32 m_WantedFadeTimer;
+ static uint32 m_WantedState;
+ static uint32 m_WantedTimer;
+ static uint32 m_EnergyLostFadeTimer;
+ static uint32 m_EnergyLostState;
+ static uint32 m_EnergyLostTimer;
+ static uint32 m_DisplayScoreFadeTimer;
+ static uint32 m_DisplayScoreState;
+ static uint32 m_DisplayScoreTimer;
+ static uint32 m_WeaponFadeTimer;
+ static uint32 m_WeaponState;
+ static uint32 m_WeaponTimer;
+
+ static uint32 m_LastDisplayScore;
+ static uint32 m_LastWanted;
+ static uint32 m_LastWeapon;
+ static uint32 m_LastTimeEnergyLost;
+
public:
static void Draw();
static void DrawAfterFade();
static void GetRidOfAllHudMessages();
+#ifdef RELOADABLES
+ static void ReloadTXD();
+#endif
static void Initialise();
static void ReInitialise();
static void SetBigMessage(wchar *message, uint16 style);
- static void SetHelpMessage(wchar *message, bool quick);
+ 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/render/MBlur.cpp b/src/render/MBlur.cpp
index de15358e..57817422 100644
--- a/src/render/MBlur.cpp
+++ b/src/render/MBlur.cpp
@@ -7,8 +7,14 @@
#include <d3d8caps.h>
#endif
+#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
@@ -214,23 +339,24 @@ 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
#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)
{
@@ -278,41 +404,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);
+ // TODO(MIAMI): 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);
@@ -321,3 +511,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*)rwBLENDINVSRCALPHA);
+ 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/render/MBlur.h b/src/render/MBlur.h
index e2e5d38c..3dc53082 100644
--- a/src/render/MBlur.h
+++ b/src/render/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/render/Occlusion.cpp b/src/render/Occlusion.cpp
new file mode 100644
index 00000000..5fef6e21
--- /dev/null
+++ b/src/render/Occlusion.cpp
@@ -0,0 +1,495 @@
+#include "common.h"
+
+#include "main.h"
+#include "Occlusion.h"
+#include "Game.h"
+#include "Camera.h"
+#include "Vector.h"
+#include "Draw.h"
+#include "Timer.h"
+#include "RwHelper.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 bDisplayOccDebugStuff;
+#endif
+
+void
+COcclusion::Init(void)
+{
+ NumOccludersOnMap = 0;
+ FarAwayList = -1;
+ NearbyList = -1;
+ ListWalkThroughFA = -1;
+ PreviousListWalkThroughFA = -1;
+#ifndef MASTER
+ bDisplayOccDebugStuff = false;
+#endif
+}
+
+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 (!bDisplayOccDebugStuff || !(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
diff --git a/src/render/Occlusion.h b/src/render/Occlusion.h
new file mode 100644
index 00000000..8a444525
--- /dev/null
+++ b/src/render/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 bDisplayOccDebugStuff;
+#endif \ No newline at end of file
diff --git a/src/render/Particle.cpp b/src/render/Particle.cpp
index f175c264..7012f956 100644
--- a/src/render/Particle.cpp
+++ b/src/render/Particle.cpp
@@ -5,23 +5,27 @@
#include "TxdStore.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"
-#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)
@@ -36,16 +40,16 @@
#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)
+
const char SmokeFiles[][6+1] =
{
"smoke1",
@@ -56,15 +60,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",
@@ -108,14 +103,6 @@ const char GunFlashFiles[][9+1] =
"gunflash4"
};
-const char RaindropFiles[][9+1] =
-{
- "raindrop1",
- "raindrop2",
- "raindrop3",
- "raindrop4"
-};
-
const char RainSplashupFiles[][10+1] =
{
"splash_up1",
@@ -130,6 +117,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",
@@ -149,7 +148,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];
@@ -157,26 +156,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 *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];
@@ -184,45 +184,62 @@ 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 *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 *gpLetterTex;
+RwRaster *gpLetterRaster;
+
+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);
@@ -230,6 +247,8 @@ TWEAKFLOAT(fParticleScaleLimit, 0.0f, 1.0f, 0.1f);
TWEAKFUNC(CParticle::ReloadConfig);
#endif
+
+
void CParticle::ReloadConfig()
{
debug("Initialising CParticleMgr...");
@@ -317,11 +336,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++ )
{
@@ -349,15 +365,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++ )
{
@@ -367,10 +381,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);
@@ -383,7 +403,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);
@@ -402,6 +425,9 @@ void CParticle::Initialise()
gpLeafTex = RwTextureRead("gameleaf01_64", nil);
gpLeafRaster = RwTextureGetRaster(gpLeafTex);
+
+ gpLetterTex = RwTextureRead("letter", nil);
+ gpLetterRaster = RwTextureGetRaster(gpLetterTex);
gpCloudTex1 = RwTextureRead("cloud3", nil);
gpCloudRaster1 = RwTextureGetRaster(gpCloudTex1);
@@ -424,12 +450,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++ )
@@ -438,145 +491,180 @@ 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;
}
}
@@ -590,168 +678,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(gpLetterTex);
+ gpLetterTex = 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;
@@ -761,6 +826,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);
@@ -770,9 +869,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
@@ -785,8 +883,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 )
@@ -807,7 +907,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;
@@ -816,14 +928,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;
@@ -831,7 +958,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;
@@ -839,7 +966,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),
@@ -856,13 +983,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
@@ -871,8 +992,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];
@@ -891,7 +1010,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 )
@@ -1015,6 +1134,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++ )
{
@@ -1028,9 +1166,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 )
{
@@ -1057,7 +1395,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 )
@@ -1070,16 +1408,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:
@@ -1199,7 +1562,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,
@@ -1207,7 +1570,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,
@@ -1225,12 +1588,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;
@@ -1317,16 +1680,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;
}
}
@@ -1335,37 +1698,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 )
@@ -1409,31 +1756,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;
}
}
}
@@ -1457,13 +1801,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
@@ -1477,7 +1818,6 @@ void CParticle::Render()
{
particleBanned = true;
}
-#endif
if ( particle )
{
@@ -1519,11 +1859,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];
@@ -1537,28 +1876,153 @@ void CParticle::Render()
if ( canDraw && psystem->Flags & DRAWTOP2D )
{
- if ( particle->m_nRotation != 0 )
+ float screenZ = (particle->m_vecPosition.z - CDraw::GetNearClipZ())
+ * (CSprite::GetFarScreenZ() - CSprite::GetNearScreenZ())
+ * CDraw::GetFarClipZ()
+ / ( (CDraw::GetFarClipZ() - CDraw::GetNearClipZ()) * particle->m_vecPosition.z )
+ + CSprite::GetNearScreenZ();
+
+ 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;
+ }
+
+
+ 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;
+ }
+
+ 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;
@@ -1572,174 +2036,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));
}
- 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;
+ 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));
+ }
+
+ 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();
+ float fRotation;
+ float fTrailLength;
- fTrailLength = fDist;
-
- 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);
}
}
}
@@ -1769,6 +2293,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
@@ -1857,3 +2384,89 @@ 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;
+ }
+ }
+ }
+ }
+
+}
diff --git a/src/render/Particle.h b/src/render/Particle.h
index 7f02e318..5542dc02 100644
--- a/src/render/Particle.h
+++ b/src/render/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/render/ParticleMgr.cpp b/src/render/ParticleMgr.cpp
index 3387d471..f6919435 100644
--- a/src/render/ParticleMgr.cpp
+++ b/src/render/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/render/ParticleMgr.h b/src/render/ParticleMgr.h
index 0100bb65..f4afc018 100644
--- a/src/render/ParticleMgr.h
+++ b/src/render/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/render/ParticleType.h b/src/render/ParticleType.h
index 8d352c44..0af9a1e1 100644
--- a/src/render/ParticleType.h
+++ b/src/render/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,9 +77,14 @@ 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,
diff --git a/src/render/PlayerSkin.cpp b/src/render/PlayerSkin.cpp
index f0fae45a..b385a62c 100644
--- a/src/render/PlayerSkin.cpp
+++ b/src/render/PlayerSkin.cpp
@@ -16,6 +16,8 @@
#include "Lights.h"
#include "MemoryMgr.h"
+//--MIAMI: file done
+
RpClump *gpPlayerClump;
float gOldFov;
@@ -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/render/PointLights.cpp b/src/render/PointLights.cpp
index 6f0b4d46..c8f21d21 100644
--- a/src/render/PointLights.cpp
+++ b/src/render/PointLights.cpp
@@ -1,6 +1,7 @@
#include "common.h"
#include "main.h"
+#include "CutsceneMgr.h"
#include "Lights.h"
#include "Camera.h"
#include "Weather.h"
@@ -10,8 +11,23 @@
#include "Timer.h"
#include "PointLights.h"
+//--MIAMI: file done
+
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,12 +158,17 @@ CPointLights::RenderFogEffect(void)
CVector spriteCoors;
float spritew, spriteh;
+ if(CCutsceneMgr::IsRunning())
+ return;
+
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDONE);
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;
@@ -218,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);
@@ -233,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;
@@ -266,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);
@@ -282,4 +302,27 @@ CPointLights::RenderFogEffect(void)
}
}
}
+
+ CSprite::FlushSpriteBuffer();
+}
+
+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/render/PointLights.h b/src/render/PointLights.h
index 9e94328f..827200b9 100644
--- a/src/render/PointLights.h
+++ b/src/render/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/render/RenderBuffer.cpp b/src/render/RenderBuffer.cpp
index 6120dfe2..687cc76b 100644
--- a/src/render/RenderBuffer.cpp
+++ b/src/render/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/render/RenderBuffer.h b/src/render/RenderBuffer.h
index 485d24e3..a0f3e7b9 100644
--- a/src/render/RenderBuffer.h
+++ b/src/render/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/render/Renderer.cpp b/src/render/Renderer.cpp
index d47cac31..4e94e75d 100644
--- a/src/render/Renderer.cpp
+++ b/src/render/Renderer.cpp
@@ -1,3 +1,4 @@
+#define WITH_D3D
#include "common.h"
#include "main.h"
@@ -6,7 +7,9 @@
#include "Treadable.h"
#include "Ped.h"
#include "Vehicle.h"
+#include "Boat.h"
#include "Heli.h"
+#include "Bike.h"
#include "Object.h"
#include "PathFind.h"
#include "Collision.h"
@@ -18,11 +21,13 @@
#include "Streaming.h"
#include "Shadows.h"
#include "PointLights.h"
+#include "Occlusion.h"
#include "Renderer.h"
-#include "Frontend.h"
#include "custompipes.h"
#include "Debug.h"
+//--MIAMI: file done
+
bool gbShowPedRoadGroups;
bool gbShowCarRoadGroups;
bool gbShowCollisionPolys;
@@ -68,24 +73,22 @@ int32 CRenderer::ms_nNoOfVisibleEntities;
CEntity *CRenderer::ms_aVisibleEntityPtrs[NUMVISIBLEENTITIES];
CEntity *CRenderer::ms_aInVisibleEntityPtrs[NUMINVISIBLEENTITIES];
int32 CRenderer::ms_nNoOfInVisibleEntities;
+#ifdef NEW_RENDERER
+int32 CRenderer::ms_nNoOfVisibleVehicles;
+CEntity *CRenderer::ms_aVisibleVehiclePtrs[NUMVISIBLEENTITIES];
+int32 CRenderer::ms_nNoOfVisibleBuildings;
+CEntity *CRenderer::ms_aVisibleBuildingPtrs[NUMVISIBLEENTITIES];
+#endif
CVector CRenderer::ms_vecCameraPosition;
CVehicle *CRenderer::m_pFirstPersonVehicle;
bool CRenderer::m_loadingPriority;
float CRenderer::ms_lodDistScale = 1.2f;
-#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
-
// unused
BlockedRange CRenderer::aBlockedRanges[16];
-BlockedRange *CRenderer::pFullBlockedRanges;
-BlockedRange *CRenderer::pEmptyBlockedRanges;
+BlockedRange* CRenderer::pFullBlockedRanges;
+BlockedRange* CRenderer::pEmptyBlockedRanges;
void
CRenderer::Init(void)
@@ -109,6 +112,20 @@ CRenderer::PreRender(void)
for(i = 0; i < ms_nNoOfVisibleEntities; i++)
ms_aVisibleEntityPtrs[i]->PreRender();
+#ifdef NEW_RENDERER
+ if(gbNewRenderer){
+ 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(node = CVisibilityPlugins::m_alphaBuildingList.head.next;
+ node != &CVisibilityPlugins::m_alphaBuildingList.tail;
+ node = node->next)
+ ((CEntity*)node->item.entity)->PreRender();
+ }
+#endif
+
for (i = 0; i < ms_nNoOfInVisibleEntities; i++) {
#ifdef SQUEEZE_PERFORMANCE
if (ms_aInVisibleEntityPtrs[i]->IsVehicle() && ((CVehicle*)ms_aInVisibleEntityPtrs[i])->IsHeli())
@@ -132,19 +149,8 @@ CRenderer::RenderOneRoad(CEntity *e)
return;
if(gbShowCollisionPolys)
CCollision::DrawColModel_Coloured(e->GetMatrix(), *CModelInfo::GetModelInfo(e->GetModelIndex())->GetColModel(), e->GetModelIndex());
- else{
-#ifdef EXTENDED_PIPELINES
- CustomPipes::AttachGlossPipe(e->GetAtomic());
-#endif
-#ifdef EXTRA_MODEL_FLAGS
- if(!e->IsBuilding() || CModelInfo::GetModelInfo(e->GetModelIndex())->RenderDoubleSided()){
- BACKFACE_CULLING_OFF;
- e->Render();
- BACKFACE_CULLING_ON;
- }else
-#endif
+ else
e->Render();
- }
}
void
@@ -193,8 +199,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()){
@@ -204,23 +213,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);
@@ -241,54 +242,56 @@ CRenderer::RenderFirstPersonVehicle(void)
RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE);
}
+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;
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(t->IsBuilding() && t->GetIsATreadable()){
-#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);
}
}
+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;
- BACKFACE_CULLING_ON;
+ RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
+ SetCullMode(rwCULLMODECULLBACK);
gSortedVehiclesAndPeds.Clear();
for(i = 0; i < ms_nNoOfVisibleEntities; i++){
e = ms_aVisibleEntityPtrs[i];
- if(e->IsBuilding() && ((CBuilding*)e)->GetIsATreadable())
+ if(IsRoad(e))
continue;
#ifdef EXTENDED_PIPELINES
@@ -298,14 +301,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);
}
@@ -316,50 +317,604 @@ CRenderer::RenderEverythingBarRoads(void)
}
void
-CRenderer::RenderVehiclesButNotBoats(void)
+CRenderer::RenderBoats(void)
{
- // This function doesn't do anything
- // because only boats are inserted into the list
CLink<EntityInfo> *node;
+ 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);
+ }
+}
+
+#ifdef NEW_RENDERER
+#ifndef LIBRW
+#error "Need librw for EXTENDED_PIPELINES"
+#endif
+#include "WaterLevel.h"
+
+enum {
+ // blend passes
+ PASS_NOZ, // no z-write
+ PASS_ADD, // additive
+ PASS_BLEND // normal blend
+};
+
+static RwRGBAReal black;
+
+static void
+SetStencilState(int state)
+{
+ switch(state){
+ // disable stencil
+ case 0:
+ rw::SetRenderState(rw::STENCILENABLE, FALSE);
+ break;
+ // test against stencil
+ case 1:
+ rw::SetRenderState(rw::STENCILENABLE, TRUE);
+ rw::SetRenderState(rw::STENCILFUNCTION, rw::STENCILNOTEQUAL);
+ rw::SetRenderState(rw::STENCILPASS, rw::STENCILKEEP);
+ rw::SetRenderState(rw::STENCILFAIL, rw::STENCILKEEP);
+ rw::SetRenderState(rw::STENCILZFAIL, rw::STENCILKEEP);
+ rw::SetRenderState(rw::STENCILFUNCTIONMASK, 0xFF);
+ rw::SetRenderState(rw::STENCILFUNCTIONREF, 0xFF);
+ break;
+ // write to stencil
+ case 2:
+ rw::SetRenderState(rw::STENCILENABLE, TRUE);
+ rw::SetRenderState(rw::STENCILFUNCTION, rw::STENCILALWAYS);
+ rw::SetRenderState(rw::STENCILPASS, rw::STENCILREPLACE);
+ rw::SetRenderState(rw::STENCILFUNCTIONREF, 0xFF);
+ break;
+ }
+}
+
+#ifdef RW_D3D9
+struct BuildingInst
+{
+ rw::RawMatrix combinedMat;
+ rw::d3d9::InstanceDataHeader *instHeader;
+ uint8 fadeAlpha;
+ bool lighting;
+};
+static BuildingInst blendInsts[3][2000];
+static int numBlendInsts[3];
+
+static void
+SetMatrix(BuildingInst *building, rw::Matrix *worldMat)
+{
+ using namespace rw;
+ RawMatrix world, worldview;
+ Camera *cam = engine->currentCamera;
+ convMatrix(&world, worldMat);
+ RawMatrix::mult(&worldview, &world, &cam->devView);
+ RawMatrix::mult(&building->combinedMat, &worldview, &cam->devProj);
+}
+
+static bool
+IsTextureTransparent(RwTexture *tex)
+{
+ if(tex == nil || tex->raster == nil)
+ return false;
+ return PLUGINOFFSET(rw::d3d::D3dRaster, tex->raster, rw::d3d::nativeRasterOffset)->hasAlpha;
+}
+
+// Render all opaque meshes and put atomics that needs blending
+// into the deferred list.
+static void
+AtomicFirstPass(RpAtomic *atomic, int pass)
+{
+ using namespace rw;
+ using namespace rw::d3d;
+ using namespace rw::d3d9;
+
+ BuildingInst *building = &blendInsts[pass][numBlendInsts[pass]];
+
+ atomic->getPipeline()->instance(atomic);
+ building->instHeader = (d3d9::InstanceDataHeader*)atomic->geometry->instData;
+ assert(building->instHeader != nil);
+ assert(building->instHeader->platform == PLATFORM_D3D9);
+ building->fadeAlpha = 255;
+ building->lighting = !!(atomic->geometry->flags & rw::Geometry::LIGHT);
+
+ bool setupDone = false;
+ bool defer = false;
+ SetMatrix(building, atomic->getFrame()->getLTM());
+
+ InstanceData *inst = building->instHeader->inst;
+ for(rw::uint32 i = 0; i < building->instHeader->numMeshes; i++, inst++){
+ Material *m = inst->material;
+
+ if(inst->vertexAlpha || m->color.alpha != 255 ||
+ IsTextureTransparent(m->texture)){
+ defer = true;
+ continue;
+ }
+
+ // alright we're rendering this atomic
+ if(!setupDone){
+ setStreamSource(0, building->instHeader->vertexStream[0].vertexBuffer, 0, building->instHeader->vertexStream[0].stride);
+ setIndices(building->instHeader->indexBuffer);
+ setVertexDeclaration(building->instHeader->vertexDeclaration);
+ setVertexShader(default_amb_VS);
+ d3ddevice->SetVertexShaderConstantF(VSLOC_combined, (float*)&building->combinedMat, 4);
+ if(building->lighting)
+ setAmbient(pAmbient->color);
+ else
+ setAmbient(black);
+ setupDone = true;
+ }
+
+ setMaterial(m->color, m->surfaceProps);
+
+ if(m->texture){
+ d3d::setTexture(0, m->texture);
+ setPixelShader(default_tex_PS);
+ }else
+ setPixelShader(default_PS);
+
+ drawInst(building->instHeader, inst);
+ }
+ if(defer)
+ numBlendInsts[pass]++;
+}
+
+static void
+AtomicFullyTransparent(RpAtomic *atomic, int pass, int fadeAlpha)
+{
+ using namespace rw;
+ using namespace rw::d3d;
+ using namespace rw::d3d9;
+
+ BuildingInst *building = &blendInsts[pass][numBlendInsts[pass]];
+
+ atomic->getPipeline()->instance(atomic);
+ building->instHeader = (d3d9::InstanceDataHeader*)atomic->geometry->instData;
+ assert(building->instHeader != nil);
+ assert(building->instHeader->platform == PLATFORM_D3D9);
+ building->fadeAlpha = fadeAlpha;
+ building->lighting = !!(atomic->geometry->flags & rw::Geometry::LIGHT);
+ SetMatrix(building, atomic->getFrame()->getLTM());
+ numBlendInsts[pass]++;
+}
+
+static void
+RenderBlendPass(int pass)
+{
+ using namespace rw;
+ using namespace rw::d3d;
+ using namespace rw::d3d9;
+
+ setVertexShader(default_amb_VS);
+
+ int i;
+ for(i = 0; i < numBlendInsts[pass]; i++){
+ BuildingInst *building = &blendInsts[pass][i];
+
+ setStreamSource(0, building->instHeader->vertexStream[0].vertexBuffer, 0, building->instHeader->vertexStream[0].stride);
+ setIndices(building->instHeader->indexBuffer);
+ setVertexDeclaration(building->instHeader->vertexDeclaration);
+ d3ddevice->SetVertexShaderConstantF(VSLOC_combined, (float*)&building->combinedMat, 4);
+ if(building->lighting)
+ setAmbient(pAmbient->color);
+ else
+ setAmbient(black);
+
+ InstanceData *inst = building->instHeader->inst;
+ for(rw::uint32 j = 0; j < building->instHeader->numMeshes; j++, inst++){
+ Material *m = inst->material;
+ if(!inst->vertexAlpha && m->color.alpha == 255 && !IsTextureTransparent(m->texture) && building->fadeAlpha == 255)
+ continue; // already done this one
+
+ rw::RGBA color = m->color;
+ color.alpha = (color.alpha * building->fadeAlpha)/255;
+ setMaterial(color, m->surfaceProps);
+
+ if(m->texture){
+ d3d::setTexture(0, m->texture);
+ setPixelShader(default_tex_PS);
+ }else
+ setPixelShader(default_PS);
+
+ drawInst(building->instHeader, inst);
+ }
+ }
+}
+#endif
+#ifdef RW_GL3
+struct BuildingInst
+{
+ rw::Matrix matrix;
+ rw::gl3::InstanceDataHeader *instHeader;
+ uint8 fadeAlpha;
+ bool lighting;
+};
+static BuildingInst blendInsts[3][2000];
+static int numBlendInsts[3];
+
+static bool
+IsTextureTransparent(RwTexture *tex)
+{
+ if(tex == nil || tex->raster == nil)
+ return false;
+ return PLUGINOFFSET(rw::gl3::Gl3Raster, tex->raster, rw::gl3::nativeRasterOffset)->hasAlpha;
+}
+
+// Render all opaque meshes and put atomics that needs blending
+// into the deferred list.
+static void
+AtomicFirstPass(RpAtomic *atomic, int pass)
+{
+ using namespace rw;
+ using namespace rw::gl3;
+
+ BuildingInst *building = &blendInsts[pass][numBlendInsts[pass]];
+
+ atomic->getPipeline()->instance(atomic);
+ building->instHeader = (gl3::InstanceDataHeader*)atomic->geometry->instData;
+ assert(building->instHeader != nil);
+ assert(building->instHeader->platform == PLATFORM_GL3);
+ building->fadeAlpha = 255;
+ building->lighting = !!(atomic->geometry->flags & rw::Geometry::LIGHT);
+
+ WorldLights lights;
+ lights.numAmbients = 1;
+ lights.numDirectionals = 0;
+ lights.numLocals = 0;
+ if(building->lighting)
+ lights.ambient = pAmbient->color;
+ else
+ lights.ambient = black;
+
+ bool setupDone = false;
+ bool defer = false;
+ building->matrix = *atomic->getFrame()->getLTM();
+
+ InstanceData *inst = building->instHeader->inst;
+ for(rw::uint32 i = 0; i < building->instHeader->numMeshes; i++, inst++){
+ Material *m = inst->material;
+
+ if(inst->vertexAlpha || m->color.alpha != 255 ||
+ IsTextureTransparent(m->texture)){
+ defer = true;
+ continue;
+ }
+
+ // alright we're rendering this atomic
+ if(!setupDone){
+ defaultShader->use();
+ setWorldMatrix(&building->matrix);
+#ifdef RW_GL_USE_VAOS
+ glBindVertexArray(building->instHeader->vao);
+#else
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, building->instHeader->ibo);
+ glBindBuffer(GL_ARRAY_BUFFER, building->instHeader->vbo);
+ setAttribPointers(building->instHeader->attribDesc, building->instHeader->numAttribs);
+#endif
+ setLights(&lights);
+ setupDone = true;
+ }
+
+ setMaterial(m->color, m->surfaceProps);
+
+ setTexture(0, m->texture);
+
+ drawInst(building->instHeader, inst);
}
+#ifndef RW_GL_USE_VAOS
+ disableAttribPointers(building->instHeader->attribDesc, building->instHeader->numAttribs);
+#endif
+ if(defer)
+ numBlendInsts[pass]++;
+}
+
+static void
+AtomicFullyTransparent(RpAtomic *atomic, int pass, int fadeAlpha)
+{
+ using namespace rw;
+ using namespace rw::gl3;
+
+ BuildingInst *building = &blendInsts[pass][numBlendInsts[pass]];
+
+ atomic->getPipeline()->instance(atomic);
+ building->instHeader = (gl3::InstanceDataHeader*)atomic->geometry->instData;
+ assert(building->instHeader != nil);
+ assert(building->instHeader->platform == PLATFORM_GL3);
+ building->fadeAlpha = fadeAlpha;
+ building->lighting = !!(atomic->geometry->flags & rw::Geometry::LIGHT);
+ building->matrix = *atomic->getFrame()->getLTM();
+ numBlendInsts[pass]++;
}
+static void
+RenderBlendPass(int pass)
+{
+ using namespace rw;
+ using namespace rw::gl3;
+
+ defaultShader->use();
+ WorldLights lights;
+ lights.numAmbients = 1;
+ lights.numDirectionals = 0;
+ lights.numLocals = 0;
+
+ int i;
+ for(i = 0; i < numBlendInsts[pass]; i++){
+ BuildingInst *building = &blendInsts[pass][i];
+
+#ifdef RW_GL_USE_VAOS
+ glBindVertexArray(building->instHeader->vao);
+#else
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, building->instHeader->ibo);
+ glBindBuffer(GL_ARRAY_BUFFER, building->instHeader->vbo);
+ setAttribPointers(building->instHeader->attribDesc, building->instHeader->numAttribs);
+#endif
+ setWorldMatrix(&building->matrix);
+ if(building->lighting)
+ lights.ambient = pAmbient->color;
+ else
+ lights.ambient = black;
+ setLights(&lights);
+
+ InstanceData *inst = building->instHeader->inst;
+ for(rw::uint32 j = 0; j < building->instHeader->numMeshes; j++, inst++){
+ Material *m = inst->material;
+ if(!inst->vertexAlpha && m->color.alpha == 255 && !IsTextureTransparent(m->texture) && building->fadeAlpha == 255)
+ continue; // already done this one
+
+ rw::RGBA color = m->color;
+ color.alpha = (color.alpha * building->fadeAlpha)/255;
+ setMaterial(color, m->surfaceProps);
+
+ setTexture(0, m->texture);
+
+ drawInst(building->instHeader, inst);
+ }
+#ifndef RW_GL_USE_VAOS
+ disableAttribPointers(building->instHeader->attribDesc, building->instHeader->numAttribs);
+#endif
+ }
+}
+#endif
+
void
-CRenderer::RenderBoats(void)
+CRenderer::RenderOneBuilding(CEntity *ent, float camdist)
+{
+ if(ent->m_rwObject == nil)
+ return;
+
+ ent->bImBeingRendered = true; // TODO: this seems wrong, but do we even need it?
+
+ assert(RwObjectGetType(ent->m_rwObject) == rpATOMIC);
+ RpAtomic *atomic = (RpAtomic*)ent->m_rwObject;
+ CSimpleModelInfo *mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(ent->GetModelIndex());
+
+ int pass = PASS_BLEND;
+ if(mi->m_additive) // very questionable
+ pass = PASS_ADD;
+ if(mi->m_noZwrite)
+ pass = PASS_NOZ;
+
+ if(ent->bDistanceFade){
+ RpAtomic *lodatm;
+ float fadefactor;
+ uint32 alpha;
+
+ lodatm = mi->GetAtomicFromDistance(camdist - FADE_DISTANCE);
+ fadefactor = (mi->GetLargestLodDistance() - (camdist - FADE_DISTANCE))/FADE_DISTANCE;
+ if(fadefactor > 1.0f)
+ fadefactor = 1.0f;
+ alpha = mi->m_alpha * fadefactor;
+
+ if(alpha == 255)
+ AtomicFirstPass(atomic, pass);
+ else{
+ // not quite sure what this is about, do we have to do that?
+ RpGeometry *geo = RpAtomicGetGeometry(lodatm);
+ if(geo != RpAtomicGetGeometry(atomic))
+ RpAtomicSetGeometry(atomic, geo, rpATOMICSAMEBOUNDINGSPHERE);
+ AtomicFullyTransparent(atomic, pass, alpha);
+ }
+ }else
+ AtomicFirstPass(atomic, pass);
+
+ ent->bImBeingRendered = false; // TODO: this seems wrong, but do we even need it?
+}
+
+void
+CRenderer::RenderWorld(int pass)
+{
+ int i;
+ CEntity *e;
+ CLink<CVisibilityPlugins::AlphaObjectInfo> *node;
+
+ RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)TRUE);
+ SetCullMode(rwCULLMODECULLBACK);
+ DeActivateDirectional();
+ SetAmbientColours();
+
+ // Temporary...have to figure out sorting better
+ switch(pass){
+ case 0:
+ // Roads
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
+ for(i = 0; i < ms_nNoOfVisibleBuildings; i++){
+ e = ms_aVisibleBuildingPtrs[i];
+ if(e->bIsBIGBuilding || IsRoad(e))
+ RenderOneBuilding(e);
+ }
+ for(node = CVisibilityPlugins::m_alphaBuildingList.tail.prev;
+ node != &CVisibilityPlugins::m_alphaBuildingList.head;
+ node = node->prev){
+ e = node->item.entity;
+ if(e->bIsBIGBuilding || IsRoad(e))
+ RenderOneBuilding(e, node->item.sort);
+ }
+ break;
+ case 1:
+ // Opaque
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
+ for(i = 0; i < ms_nNoOfVisibleBuildings; i++){
+ e = ms_aVisibleBuildingPtrs[i];
+ if(!(e->bIsBIGBuilding || IsRoad(e)))
+ RenderOneBuilding(e);
+ }
+ for(node = CVisibilityPlugins::m_alphaBuildingList.tail.prev;
+ node != &CVisibilityPlugins::m_alphaBuildingList.head;
+ node = node->prev){
+ e = node->item.entity;
+ if(!(e->bIsBIGBuilding || IsRoad(e)))
+ RenderOneBuilding(e, node->item.sort);
+ }
+ // Now we have iterated through all visible buildings (unsorted and sorted)
+ // and the transparency list is done.
+
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, FALSE);
+ RenderBlendPass(PASS_NOZ);
+ RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
+ break;
+ case 2:
+ // Transparent
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE);
+ RenderBlendPass(PASS_ADD);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
+ RenderBlendPass(PASS_BLEND);
+ break;
+ }
+}
+
+void
+CRenderer::RenderPeds(void)
+{
+ int i;
+ CEntity *e;
+
+ for(i = 0; i < ms_nNoOfVisibleVehicles; i++){
+ e = ms_aVisibleVehiclePtrs[i];
+ if(e->IsPed())
+ RenderOneNonRoad(e);
+ }
+}
+
+void
+CRenderer::RenderVehicles(void)
{
+ int i;
+ CEntity *e;
+ EntityInfo ei;
CLink<EntityInfo> *node;
- BACKFACE_CULLING_ON;
+ // not the real thing
+ for(i = 0; i < ms_nNoOfVisibleVehicles; i++){
+ e = ms_aVisibleVehiclePtrs[i];
+ if(!e->IsVehicle())
+ continue;
+ if(PutIntoSortedVehicleList((CVehicle*)e))
+ continue; // boats handled elsewhere
+ ei.ent = e;
+ ei.sort = (ms_vecCameraPosition - e->GetPosition()).MagnitudeSqr();
+ gSortedVehiclesAndPeds.InsertSorted(ei);
+ }
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);
+ node = node->prev)
+ RenderOneNonRoad(node->item.ent);
+}
+
+void
+CRenderer::RenderTransparentWater(void)
+{
+ int i;
+ CEntity *e;
+
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, nil);
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE);
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDZERO);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE);
+ RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
+ SetStencilState(2);
+
+ for(i = 0; i < ms_nNoOfVisibleVehicles; i++){
+ e = ms_aVisibleVehiclePtrs[i];
+ if(e->IsVehicle() && ((CVehicle*)e)->IsBoat())
+ ((CBoat*)e)->RenderWaterOutPolys();
}
+
+ RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
+ SetStencilState(1);
+
+ CWaterLevel::RenderTransparentWater();
+
+ SetStencilState(0);
}
void
+CRenderer::ClearForFrame(void)
+{
+ ms_nNoOfVisibleEntities = 0;
+ ms_nNoOfVisibleVehicles = 0;
+ ms_nNoOfVisibleBuildings = 0;
+ ms_nNoOfInVisibleEntities = 0;
+ gSortedVehiclesAndPeds.Clear();
+
+ numBlendInsts[PASS_NOZ] = 0;
+ numBlendInsts[PASS_ADD] = 0;
+ numBlendInsts[PASS_BLEND] = 0;
+}
+#endif
+
+void
CRenderer::RenderFadingInEntities(void)
{
RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)TRUE);
- BACKFACE_CULLING_ON;
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
+ SetCullMode(rwCULLMODECULLBACK);
DeActivateDirectional();
SetAmbientColours();
CVisibilityPlugins::RenderFadingEntities();
}
void
+CRenderer::RenderFadingInUnderwaterEntities(void)
+{
+ DeActivateDirectional();
+ SetAmbientColours();
+ CVisibilityPlugins::RenderFadingUnderwaterEntities();
+}
+
+void
CRenderer::RenderCollisionLines(void)
{
int i;
@@ -407,7 +962,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())){
@@ -423,25 +978,35 @@ CRenderer::SetupEntityVisibility(CEntity *ent)
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();
@@ -451,22 +1016,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;
@@ -486,7 +1067,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;
}
@@ -498,9 +1079,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;
}
@@ -536,7 +1118,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{
@@ -549,19 +1131,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();
@@ -570,7 +1165,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)
@@ -578,7 +1173,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())
@@ -586,7 +1181,7 @@ CRenderer::SetupBigBuildingVisibility(CEntity *ent)
}
}
- RpAtomic *a = mi->GetAtomicFromDistance(dist);
+ RpAtomic *a = mi->GetFirstAtomicFromDistance(dist);
if(a){
if(ent->m_rwObject == nil)
ent->CreateRwObject();
@@ -597,8 +1192,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;
@@ -614,10 +1219,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...
@@ -627,16 +1236,27 @@ 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
+{
ms_nNoOfVisibleEntities = 0;
ms_nNoOfInVisibleEntities = 0;
+}
ms_vecCameraPosition = TheCamera.GetPosition();
// unused
@@ -726,6 +1346,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;
@@ -771,6 +1400,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);
@@ -780,7 +1410,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);
@@ -808,19 +1440,8 @@ 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));
- } else
-#endif
- {
- #ifdef FIX_BUGS
- if (CCollision::ms_collisionInMemory != LEVEL_GENERIC)
- #endif
- ScanBigBuildingList(CWorld::GetBigBuildingList(CCollision::ms_collisionInMemory));
- }
+
+ ScanBigBuildingList(CWorld::GetBigBuildingList(CGame::currLevel));
ScanBigBuildingList(CWorld::GetBigBuildingList(LEVEL_GENERIC));
}
}
@@ -865,6 +1486,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
@@ -920,6 +1542,7 @@ CRenderer::RequestObjectsInFrustum(void)
}
}
+// --MIAMI: Done
bool
CPed::SetupLighting(void)
{
@@ -937,7 +1560,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;
}
@@ -945,10 +1568,17 @@ CPed::SetupLighting(void)
return false;
}
+// --MIAMI: Done
void
CPed::RemoveLighting(bool reset)
{
- CRenderer::RemoveVehiclePedLights(this, reset);
+ if (!bRenderScorched) {
+ CRenderer::RemoveVehiclePedLights(this, reset);
+ if (reset)
+ ReSetAmbientAndDirectionalColours();
+ }
+ SetAmbientColours();
+ DeActivateDirectional();
}
float
@@ -1110,26 +1740,43 @@ CRenderer::ScanSectorPoly(RwV2d *poly, int32 numVertices, void (*scanfunc)(CPtrL
}
void
+CRenderer::InsertEntityIntoList(CEntity *ent)
+{
+#ifdef NEW_RENDERER
+ // TODO: there are more flags being checked here
+ if(gbNewRenderer && (ent->IsVehicle() || ent->IsPed()))
+ ms_aVisibleVehiclePtrs[ms_nNoOfVisibleVehicles++] = ent;
+ else if(gbNewRenderer && ent->IsBuilding())
+ ms_aVisibleBuildingPtrs[ms_nNoOfVisibleBuildings++] = ent;
+ else
+#endif
+ ms_aVisibleEntityPtrs[ms_nNoOfVisibleEntities++] = ent;
+}
+
+void
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){
- if(SetupBigBuildingVisibility(ent) == VIS_VISIBLE)
- ms_aVisibleEntityPtrs[ms_nNoOfVisibleEntities++] = 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;
}
}
}
@@ -1150,61 +1797,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:
- ms_aVisibleEntityPtrs[ms_nNoOfVisibleEntities++] = 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(ent->IsBuilding() && ((CBuilding*)ent)->GetIsATreadable() && !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;
}
}
}
@@ -1226,69 +1842,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:
- ms_aVisibleEntityPtrs[ms_nNoOfVisibleEntities++] = 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(ent->IsBuilding() && ((CBuilding*)ent)->GetIsATreadable() && !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)
{
@@ -1305,15 +1890,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:
- ms_aVisibleEntityPtrs[ms_nNoOfVisibleEntities++] = ent;
+ 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;
@@ -1321,6 +1908,7 @@ CRenderer::ScanSectorList_Subway(CPtrList *lists)
}
}
}
+#endif
void
CRenderer::ScanSectorList_RequestModels(CPtrList *lists)
@@ -1337,8 +1925,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);
}
}
@@ -1373,95 +1960,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/render/Renderer.h b/src/render/Renderer.h
index e14f73b1..8b68d4ee 100644
--- a/src/render/Renderer.h
+++ b/src/render/Renderer.h
@@ -40,6 +40,13 @@ class CRenderer
static CEntity *ms_aVisibleEntityPtrs[NUMVISIBLEENTITIES];
static int32 ms_nNoOfInVisibleEntities;
static CEntity *ms_aInVisibleEntityPtrs[NUMINVISIBLEENTITIES];
+#ifdef NEW_RENDERER
+ static int32 ms_nNoOfVisibleVehicles;
+ static CEntity *ms_aVisibleVehiclePtrs[NUMVISIBLEENTITIES];
+ // for cWorldStream emulation
+ static int32 ms_nNoOfVisibleBuildings;
+ static CEntity *ms_aVisibleBuildingPtrs[NUMVISIBLEENTITIES];
+#endif
static CVector ms_vecCameraPosition;
static CVehicle *m_pFirstPersonVehicle;
@@ -58,8 +65,8 @@ 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 *);
@@ -85,9 +92,18 @@ 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);
+
+
+#ifdef NEW_RENDERER
+ static void ClearForFrame(void);
+ static void RenderPeds(void);
+ 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 RenderTransparentWater(void); // keep-out polys and transparent water
+#endif
+ static void InsertEntityIntoList(CEntity *ent);
};
diff --git a/src/render/Rubbish.cpp b/src/render/Rubbish.cpp
index 18a20bc7..dada2439 100644
--- a/src/render/Rubbish.cpp
+++ b/src/render/Rubbish.cpp
@@ -8,17 +8,18 @@
#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)
+//--MIAMI: file done
+
+#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,12 +53,16 @@ CRubbish::Render(void)
{
int type;
+ if(RubbishVisibility == 0)
+ return;
+
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
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;
@@ -69,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;
@@ -82,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);
}
}
@@ -92,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);
@@ -373,24 +388,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;
@@ -414,19 +411,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/render/Rubbish.h b/src/render/Rubbish.h
index 37f895f3..5a4e479b 100644
--- a/src/render/Rubbish.h
+++ b/src/render/Rubbish.h
@@ -53,3 +53,5 @@ public:
static void Init(void);
static void Shutdown(void);
};
+
+extern RwTexture *gpRubbishTexture[4];
diff --git a/src/render/ShadowCamera.cpp b/src/render/ShadowCamera.cpp
new file mode 100644
index 00000000..f69c234f
--- /dev/null
+++ b/src/render/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/render/ShadowCamera.h b/src/render/ShadowCamera.h
new file mode 100644
index 00000000..a2149db7
--- /dev/null
+++ b/src/render/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/render/Shadows.cpp b/src/render/Shadows.cpp
index 8c892be3..e8be23bd 100644
--- a/src/render/Shadows.cpp
+++ b/src/render/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,12 @@
#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"
#ifdef DEBUGMENU
SETTWEAKPATH("Shadows");
@@ -30,6 +36,8 @@ RwImVertexIndex ShadowIndexList[24];
RwTexture *gpShadowCarTex;
RwTexture *gpShadowPedTex;
RwTexture *gpShadowHeliTex;
+RwTexture *gpShadowBikeTex;
+RwTexture *gpShadowBaronTex;
RwTexture *gpShadowExplosionTex;
RwTexture *gpShadowHeadLightsTex;
RwTexture *gpOutline1Tex;
@@ -37,7 +45,6 @@ RwTexture *gpOutline2Tex;
RwTexture *gpOutline3Tex;
RwTexture *gpBloodPoolTex;
RwTexture *gpReflectionTex;
-RwTexture *gpGoalMarkerTex;
RwTexture *gpWalkDontTex;
RwTexture *gpCrackedGlassTex;
RwTexture *gpPostShadowTex;
@@ -59,37 +66,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 +137,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 +145,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];
}
@@ -150,24 +159,27 @@ CShadows::Init(void)
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 +187,6 @@ CShadows::Shutdown(void)
RwTextureDestroy(gpOutline3Tex);
RwTextureDestroy(gpBloodPoolTex);
RwTextureDestroy(gpReflectionTex);
- RwTextureDestroy(gpGoalMarkerTex);
RwTextureDestroy(gpWalkDontTex);
RwTextureDestroy(gpCrackedGlassTex);
RwTextureDestroy(gpPostShadowTex);
@@ -187,8 +198,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 +226,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 +277,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 +300,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 +326,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 +357,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 +371,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 +385,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 +395,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 +405,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 +415,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 +425,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 +434,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 +448,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 +490,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 +513,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 +748,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 +880,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 +889,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 +912,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 +993,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 +1056,7 @@ CShadows::SetRenderModeForShadowType(uint8 ShadowType)
}
}
+
void
CShadows::RenderStoredShadows(void)
{
@@ -692,17 +1065,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));
@@ -734,39 +1110,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);
+ }
}
}
@@ -776,16 +1225,17 @@ CShadows::RenderStoredShadows(void)
RenderBuffer::RenderStuffInBuffer();
}
-
}
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void *)FALSE);
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void *)TRUE);
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void *)TRUE);
+ RwRenderStateSet(rwRENDERSTATETEXTUREADDRESS, (void *)rwTEXTUREADDRESSWRAP);
ShadowsStoredToBeRendered = 0;
}
+
void
CShadows::RenderStaticShadows(void)
{
@@ -811,19 +1261,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++ )
{
@@ -857,6 +1307,7 @@ CShadows::RenderStaticShadows(void)
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void *)TRUE);
}
+
void
CShadows::GeneratePolysForStaticShadow(int16 nStaticShadowID)
{
@@ -883,7 +1334,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,
@@ -914,50 +1365,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->m_flagE2 )
{
- 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);
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+
+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;
- Bound = pEntity->GetBoundRect();
+ ASSERT( pEntity != nil );
- if ( fStartX < Bound.right
- && fEndX > Bound.left
- && fStartY < Bound.bottom
- && fEndY > Bound.top )
+ 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);
+ }
}
}
}
@@ -965,21 +1475,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 )
@@ -1025,14 +1588,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;
@@ -1432,12 +1995,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;
@@ -1462,8 +2025,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++ )
@@ -1487,12 +2050,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();
@@ -1515,13 +2288,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,
@@ -1538,7 +2312,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,
@@ -1553,6 +2327,9 @@ CShadows::UpdatePermanentShadows(void)
aPermanentShadows[i].m_fZDistance,
1.0f, 40.0f, false, 0.0f);
}
+
+ if ( !bOk )
+ aPermanentShadows[i].m_nType = SHADOWTYPE_NONE;
}
}
}
@@ -1561,19 +2338,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;
}
@@ -1617,6 +2394,7 @@ CShadows::CalcPedShadowValues(CVector vecLightDir,
}
+
void
CShadows::RenderExtraPlayerShadows(void)
{
@@ -1627,64 +2405,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++ )
{
@@ -1737,7 +2464,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
{
@@ -1747,7 +2474,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);
}
}
}
@@ -1769,9 +2496,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/render/Shadows.h b/src/render/Shadows.h
index 8c909df3..937ff4eb 100644
--- a/src/render/Shadows.h
+++ b/src/render/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/render/Skidmarks.cpp b/src/render/Skidmarks.cpp
index 9e509b52..0251878a 100644
--- a/src/render/Skidmarks.cpp
+++ b/src/render/Skidmarks.cpp
@@ -6,13 +6,13 @@
#include "Replay.h"
#include "Skidmarks.h"
+//--MIAMI: file done
+
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 +22,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 +39,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,32 +97,23 @@ void
CSkidmarks::Render(void)
{
int i, j;
- RwTexture *lastTex = nil;
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)FALSE);
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;
@@ -156,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();
@@ -177,7 +157,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);
@@ -193,7 +186,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;
@@ -225,13 +218,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
@@ -247,12 +243,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/render/Skidmarks.h b/src/render/Skidmarks.h
index c061782d..28082f08 100644
--- a/src/render/Skidmarks.h
+++ b/src/render/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/render/SpecialFX.cpp b/src/render/SpecialFX.cpp
index 34423d83..665a41ab 100644
--- a/src/render/SpecialFX.cpp
+++ b/src/render/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
@@ -141,9 +169,86 @@ CSpecialFX::Render(void)
CBrightLights::Render();
CShinyTexts::Render();
CMoneyMessages::Render();
+#ifdef NEW_RENDERER
+ if(!(gbNewRenderer && FredIsInFirstPersonCam()))
+#endif
C3dMarkers::Render();
}
+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));
+ 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));
+ FONT_LOCALE(FONT_STANDARD);
+ 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(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
@@ -212,6 +317,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
@@ -224,10 +330,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;
@@ -276,20 +384,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)
@@ -298,31 +489,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();
@@ -343,23 +634,8 @@ void CBulletTraces::Update(void)
void CBulletTrace::Update(void)
{
- if (m_framesInUse == 0) {
- m_framesInUse++;
- return;
- }
- if (m_framesInUse > 60) {
- 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
+ if (CTimer::GetTimeInMilliseconds() - m_nCreationTime >= m_nLifeTime)
m_bInUse = false;
- if (--m_lifeTime == 0)
- m_bInUse = false;
- m_framesInUse++;
}
RpAtomic *
@@ -369,6 +645,8 @@ MarkerAtomicCB(RpAtomic *atomic, void *data)
return atomic;
}
+// --MIAMI: C3dMarker and C3dMarkers done
+
bool
C3dMarker::AddMarker(uint32 identifier, uint16 type, float fSize, uint8 r, uint8 g, uint8 b, uint8 a, uint16 pulsePeriod, float pulseFraction, int16 rotateRate)
{
@@ -413,6 +691,7 @@ C3dMarker::DeleteMarkerObject()
m_nIdentifier = 0;
m_nStartTime = 0;
m_bIsUsed = false;
+ m_bFindZOnNextPlacement = false;
m_nType = MARKERTYPE_INVALID;
frame = RpAtomicGetFrame(m_pAtomic);
@@ -456,6 +735,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;
@@ -501,8 +781,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) {
@@ -515,9 +802,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;
@@ -562,7 +849,7 @@ C3dMarkers::PlaceMarker(uint32 identifier, uint16 type, CVector &pos, float size
} else {
pMarker->m_fStdSize = size;
}
- } else if (type == MARKERTYPE_CYLINDER) {
+ } else {
if (dist < size + 12.0f) {
if (dist > size + 1.0f)
pMarker->m_Color.alpha = (1.0f - (size + 12.0f - dist) * 0.7f / 11.0f) * (float)a;
@@ -575,21 +862,24 @@ C3dMarkers::PlaceMarker(uint32 identifier, uint16 type, CVector &pos, float size
float someSin = Sin(TWOPI * (float)((pMarker->m_nPulsePeriod - 1) & (CTimer::GetTimeInMilliseconds() - pMarker->m_nStartTime)) / (float)pMarker->m_nPulsePeriod);
pMarker->m_fSize = pMarker->m_fStdSize - pulseFraction * pMarker->m_fStdSize * someSin;
- if (type == MARKERTYPE_ARROW) {
+ if (type == MARKERTYPE_ARROW)
pos.z += 0.25f * pMarker->m_fStdSize * someSin;
- } else if (type == MARKERTYPE_0) {
- if (someSin > 0.0f)
- pMarker->m_Color.alpha = (float)a * 0.7f * someSin + a;
- else
- pMarker->m_Color.alpha = (float)a * 0.4f * someSin + a;
- }
- if (pMarker->m_nRotateRate) {
+ if (pMarker->m_nRotateRate != 0) {
RwV3d pos = pMarker->m_Matrix.m_matrix.pos;
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;
}
@@ -598,16 +888,17 @@ C3dMarkers::PlaceMarker(uint32 identifier, uint16 type, CVector &pos, float size
pMarker->DeleteMarkerObject();
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 (type == MARKERTYPE_CYLINDER) {
+ 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) {
- pMarker->m_Matrix.RotateX(PI);
- pMarker->m_Matrix.GetPosition() = pos;
- }
pMarker->m_Matrix.UpdateRW();
if (type == MARKERTYPE_ARROW) {
if (dist < 25.0f) {
@@ -618,7 +909,7 @@ C3dMarkers::PlaceMarker(uint32 identifier, uint16 type, CVector &pos, float size
} else {
pMarker->m_fStdSize = size;
}
- } else if (type == MARKERTYPE_CYLINDER) {
+ } else {
if (dist < size + 12.0f) {
if (dist > size + 1.0f)
pMarker->m_Color.alpha = (1.0f - (size + 12.0f - dist) * 0.7f / 11.0f) * (float)a;
@@ -722,6 +1013,9 @@ CBrightLights::Render(void)
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, nil);
+ TempBufferVerticesStored = 0;
+ TempBufferIndicesStored = 0;
+
for(i = 0; i < NumBrightLights; i++){
if(TempBufferIndicesStored > TEMPBUFFERINDEXSIZE-40 || TempBufferVerticesStored > TEMPBUFFERVERTSIZE-40)
RenderOutGeometryBuffer();
@@ -758,6 +1052,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)
@@ -824,18 +1122,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:
@@ -1042,8 +1340,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;
@@ -1052,17 +1351,15 @@ CMoneyMessage::Render()
fDistY *= (0.7 * fLifeTime + 2.0) * m_fSize;
CFont::SetPropOn();
CFont::SetBackgroundOff();
-
float fScaleY = Min(fDistY / 100.0f, MAX_SCALE);
float fScaleX = Min(fDistX / 100.0f, MAX_SCALE);
-
CFont::SetScale(fScaleX, fScaleY); // maybe use SCREEN_SCALE_X and SCREEN_SCALE_Y here?
CFont::SetCentreOn();
CFont::SetCentreSize(SCREEN_WIDTH);
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/render/SpecialFX.h b/src/render/SpecialFX.h
index 2d9f18b1..f163d8ca 100644
--- a/src/render/SpecialFX.h
+++ b/src/render/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/render/Sprite.cpp b/src/render/Sprite.cpp
index 9ec7b002..401eebd0 100644
--- a/src/render/Sprite.cpp
+++ b/src/render/Sprite.cpp
@@ -148,10 +148,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;
@@ -263,8 +263,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];
@@ -576,8 +576,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/render/Sprite.h b/src/render/Sprite.h
index ec4c1d1b..fae6684e 100644
--- a/src/render/Sprite.h
+++ b/src/render/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/render/Sprite2d.cpp b/src/render/Sprite2d.cpp
index 98bb6eb2..0cd0e8bb 100644
--- a/src/render/Sprite2d.cpp
+++ b/src/render/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);
RwIm2DVertexSetIntRGBA(&maVertices[i], 255, 255, 255, 255); // 0, 0, 0, 0 on PC
}
}
@@ -366,72 +285,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);
@@ -446,7 +340,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);
@@ -459,7 +353,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);
@@ -471,6 +365,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);
@@ -484,3 +394,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/render/Sprite2d.h b/src/render/Sprite2d.h
index 0e12d441..5abd8d71 100644
--- a/src/render/Sprite2d.h
+++ b/src/render/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/render/Timecycle.cpp b/src/render/Timecycle.cpp
index 0d94dbd6..b20a2443 100644
--- a/src/render/Timecycle.cpp
+++ b/src/render/Timecycle.cpp
@@ -10,50 +10,74 @@
#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];
+//--MIAMI: done
+
+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 +98,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 +114,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 +136,6 @@ float CTimeCycle::m_fShadowSideY[16];
float CTimeCycle::m_fShadowDisplacementX[16];
float CTimeCycle::m_fShadowDisplacementY[16];
-
void
CTimeCycle::Initialise(void)
{
@@ -115,18 +144,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");
@@ -144,31 +177,49 @@ CTimeCycle::Initialise(void)
bi++;
bi++;
}
- while(work_buff[bi] != '\n')
+ while(work_buff[bi] != '\n'
+#ifdef FIX_BUGS
+ && work_buff[bi] != '\0'
+#endif
+ )
line[li++] = work_buff[bi++];
line[li] = '\0';
bi++;
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 +235,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 +256,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 +267,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 +319,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 +339,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 +364,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 +389,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/render/Timecycle.h b/src/render/Timecycle.h
index d5d7b67a..da911b75 100644
--- a/src/render/Timecycle.h
+++ b/src/render/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/render/WaterCannon.cpp b/src/render/WaterCannon.cpp
index f54b31b9..91304be3 100644
--- a/src/render/WaterCannon.cpp
+++ b/src/render/WaterCannon.cpp
@@ -11,6 +11,9 @@
#include "Fire.h"
#include "WaterLevel.h"
#include "Camera.h"
+#include "Particle.h"
+
+// --MIAMI: file done
#define WATERCANNONVERTS 4
#define WATERCANNONINDEXES 12
@@ -77,9 +80,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 +238,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_KO_SKID_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_KO_SKID_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/render/WaterCreatures.cpp b/src/render/WaterCreatures.cpp
new file mode 100644
index 00000000..d3bd2701
--- /dev/null
+++ b/src/render/WaterCreatures.cpp
@@ -0,0 +1,274 @@
+#include "WaterCreatures.h"
+#include "ModelIndices.h"
+#include "World.h"
+#include "WaterLevel.h"
+#include "Camera.h"
+#include "PlayerPed.h"
+#include "config.h"
+#include "General.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/render/WaterCreatures.h b/src/render/WaterCreatures.h
new file mode 100644
index 00000000..9ef8198c
--- /dev/null
+++ b/src/render/WaterCreatures.h
@@ -0,0 +1,48 @@
+#pragma once
+#include "Object.h"
+
+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/render/WaterLevel.cpp b/src/render/WaterLevel.cpp
index a0c7ae31..b698a5b2 100644
--- a/src/render/WaterLevel.cpp
+++ b/src/render/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" Dont 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 = 0.5f;
-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)
+WaterLevelInitialise(Const char *pWaterDat)
{
- ms_nNoOfWaterLevels = 0;
-
+ CWaterLevel::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_aWaterRects, sizeof(ms_aWaterRects));
- CFileMgr::Read(hFile, (char *)aWaterBlockList, sizeof(aWaterBlockList));
- CFileMgr::Read(hFile, (char *)aWaterFineBlockList, sizeof(aWaterFineBlockList));
-
+ CFileMgr::Read(hFile, (char *)&CWaterLevel::ms_nNoOfWaterLevels, sizeof(CWaterLevel::ms_nNoOfWaterLevels));
+ CFileMgr::Read(hFile, (char *)CWaterLevel::ms_aWaterZs, sizeof(CWaterLevel::ms_aWaterZs));
+ CFileMgr::Read(hFile, (char *)CWaterLevel::ms_aWaterRects, sizeof(CWaterLevel::ms_aWaterRects));
+ CFileMgr::Read(hFile, (char *)CWaterLevel::aWaterBlockList, sizeof(CWaterLevel::aWaterBlockList));
+ CFileMgr::Read(hFile, (char *)CWaterLevel::aWaterFineBlockList, sizeof(CWaterLevel::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,15 +153,11 @@ 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);
- AddWaterLevel(l, b, r, t, z);
+ CWaterLevel::AddWaterLevel(l, b, r, t, z);
}
}
@@ -111,32 +167,28 @@ CWaterLevel::Initialise(Const char *pWaterDat)
{
for (int32 y = 0; y < MAX_SMALL_SECTORS; y++)
{
- aWaterFineBlockList[x][y] = NO_WATER;
+ CWaterLevel::aWaterFineBlockList[x][y] = NO_WATER;
}
}
// rasterize water rects read from file
- for (int32 i = 0; i < ms_nNoOfWaterLevels; i++)
+ for (int32 i = 0; i < CWaterLevel::ms_nNoOfWaterLevels; i++)
{
- int32 l = WATER_HUGE_X(ms_aWaterRects[i].left);
- int32 r = WATER_HUGE_X(ms_aWaterRects[i].right) + 1.0f;
- int32 t = WATER_HUGE_Y(ms_aWaterRects[i].top);
- int32 b = WATER_HUGE_Y(ms_aWaterRects[i].bottom) + 1.0f;
+ int32 l = WATER_HUGE_X(CWaterLevel::ms_aWaterRects[i].left + WATER_X_OFFSET);
+ int32 r = WATER_HUGE_X(CWaterLevel::ms_aWaterRects[i].right + WATER_X_OFFSET) + 1.0f;
+ int32 t = WATER_HUGE_Y(CWaterLevel::ms_aWaterRects[i].top);
+ int32 b = WATER_HUGE_Y(CWaterLevel::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++)
{
for (int32 y = t; y <= b; y++)
{
- aWaterFineBlockList[x][y] = i;
+ CWaterLevel::aWaterFineBlockList[x][y] = i;
}
}
}
@@ -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;
@@ -157,10 +209,10 @@ CWaterLevel::Initialise(Const char *pWaterDat)
{
for (int32 j = 0; j <= 8; j++)
{
- CVector worldPos = CVector(worldX + i * (SMALL_SECTOR_SIZE / 8), worldY + j * (SMALL_SECTOR_SIZE / 8), ms_aWaterZs[aWaterFineBlockList[x][y]]);
+ CVector worldPos = CVector(worldX + i * (SMALL_SECTOR_SIZE / 8), worldY + j * (SMALL_SECTOR_SIZE / 8), CWaterLevel::ms_aWaterZs[CWaterLevel::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)))
+ (!CWaterLevel::WaterLevelAccordingToRectangles(worldPos.x, worldPos.y) || CWaterLevel::TestVisibilityForFineWaterBlocks(worldPos)))
continue;
// at least one point in the tile wasn't blocked, so don't remove water
@@ -170,37 +222,37 @@ CWaterLevel::Initialise(Const char *pWaterDat)
}
if (i < 1000)
- aWaterFineBlockList[x][y] = NO_WATER;
+ CWaterLevel::aWaterFineBlockList[x][y] = NO_WATER;
}
}
}
- RemoveIsolatedWater();
+ CWaterLevel::RemoveIsolatedWater();
// calculate coarse tiles from fine tiles
for (int32 x = 0; x < MAX_LARGE_SECTORS; x++)
{
for (int32 y = 0; y < MAX_LARGE_SECTORS; y++)
{
- if (aWaterFineBlockList[x * 2][y * 2] >= 0)
+ if (CWaterLevel::aWaterFineBlockList[x * 2][y * 2] >= 0)
{
- aWaterBlockList[x][y] = aWaterFineBlockList[x * 2][y * 2];
+ CWaterLevel::aWaterBlockList[x][y] = CWaterLevel::aWaterFineBlockList[x * 2][y * 2];
}
- else if (aWaterFineBlockList[x * 2 + 1][y * 2] >= 0)
+ else if (CWaterLevel::aWaterFineBlockList[x * 2 + 1][y * 2] >= 0)
{
- aWaterBlockList[x][y] = aWaterFineBlockList[x * 2 + 1][y * 2];
+ CWaterLevel::aWaterBlockList[x][y] = CWaterLevel::aWaterFineBlockList[x * 2 + 1][y * 2];
}
- else if (aWaterFineBlockList[x * 2][y * 2 + 1] >= 0)
+ else if (CWaterLevel::aWaterFineBlockList[x * 2][y * 2 + 1] >= 0)
{
- aWaterBlockList[x][y] = aWaterFineBlockList[x * 2][y * 2 + 1];
+ CWaterLevel::aWaterBlockList[x][y] = CWaterLevel::aWaterFineBlockList[x * 2][y * 2 + 1];
}
- else if (aWaterFineBlockList[x * 2 + 1][y * 2 + 1] >= 0)
+ else if (CWaterLevel::aWaterFineBlockList[x * 2 + 1][y * 2 + 1] >= 0)
{
- aWaterBlockList[x][y] = aWaterFineBlockList[x * 2 + 1][y * 2 + 1];
+ CWaterLevel::aWaterBlockList[x][y] = CWaterLevel::aWaterFineBlockList[x * 2 + 1][y * 2 + 1];
}
else
{
- aWaterBlockList[x][y] = NO_WATER;
+ CWaterLevel::aWaterBlockList[x][y] = NO_WATER;
}
}
}
@@ -209,14 +261,17 @@ 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_aWaterRects, sizeof(ms_aWaterRects));
- CFileMgr::Write(hFile, (char *)aWaterBlockList, sizeof(aWaterBlockList));
- CFileMgr::Write(hFile, (char *)aWaterFineBlockList, sizeof(aWaterFineBlockList));
+ CFileMgr::Write(hFile, (char *)&CWaterLevel::ms_nNoOfWaterLevels, sizeof(CWaterLevel::ms_nNoOfWaterLevels));
+ CFileMgr::Write(hFile, (char *)CWaterLevel::ms_aWaterZs, sizeof(CWaterLevel::ms_aWaterZs));
+ CFileMgr::Write(hFile, (char *)CWaterLevel::ms_aWaterRects, sizeof(CWaterLevel::ms_aWaterRects));
+ CFileMgr::Write(hFile, (char *)CWaterLevel::aWaterBlockList, sizeof(CWaterLevel::aWaterBlockList));
+ CFileMgr::Write(hFile, (char *)CWaterLevel::aWaterFineBlockList, sizeof(CWaterLevel::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();
+ CWaterLevel::CreateWavyAtomic();
printf("Done Initing waterlevels\n");
}
@@ -240,92 +308,153 @@ 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(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,
+ wavytlist, (RwInt16)base, (RwInt16)(base+1), (RwInt16)(base+16+2));
+
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+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 +463,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 +689,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,15 +706,17 @@ 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];
+ uint8 nBlock = aWaterFineBlockList[x][y];
- if ( nBlock == NO_WATER )
+ if ( nBlock == 0x80 )
return false;
ASSERT( pfOutLevel != nil );
@@ -546,12 +726,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,15 +748,17 @@ 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];
+ uint8 nBlock = aWaterFineBlockList[x][y];
- if ( nBlock == NO_WATER )
+ if ( nBlock == 0x80 )
return false;
ASSERT( pfOutLevel != nil );
@@ -584,18 +767,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;
+
+ 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;
+}
- // if z greater then 60.0f return 2000.0f;
- if ( TheCamera.GetPosition().z > 60.0f )
- return 2000.0f;
- 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 +843,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)
{
@@ -649,64 +906,85 @@ CWaterLevel::RenderWater()
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 )
@@ -726,7 +1004,274 @@ 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), &TheCamera.GetCameraMatrix()) )
+ {
+#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 - 400.0f;
+ 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), &TheCamera.GetCameraMatrix()) )
+ {
+ 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), &TheCamera.GetCameraMatrix()) )
+ {
+ 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), &TheCamera.GetCameraMatrix()) )
+ {
+ 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), &TheCamera.GetCameraMatrix()) )
+ {
+ 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;
+
+ 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
@@ -736,29 +1281,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),
- &TheCamera.GetCameraMatrix()) )
+ if ( TheCamera.IsSphereVisible(CVector(vecHugeSectorCentre.x, vecHugeSectorCentre.y, 0.0f), SectorRadius(HUGE_SECTOR_SIZE), &TheCamera.GetCameraMatrix()) )
{
- 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,21 +1299,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,
- &TheCamera.GetCameraMatrix()) )
+ if ( TheCamera.IsSphereVisible(CVector(vecLargeSectorCentre.x, vecLargeSectorCentre.y, 0.0f), SectorRadius(LARGE_SECTOR_SIZE), &TheCamera.GetCameraMatrix()) )
{
// Render four small(32x32) sectors, or one large(64x64).
@@ -795,9 +1321,13 @@ CWaterLevel::RenderWater()
// ---------
// [S]
//
-
- if ( fLargeSectorDistToCamSqr < SQR(176.0f) )
- {
+
+ float fLargeSectorDrawDistSqr = SQR((fWaterDrawDistLarge + 16.0f));
+
+ if ( fLargeSectorDistToCamSqr < fLargeSectorDrawDistSqr )
+ {
+ _bSeaLife = true;
+
float fZ;
// WS
@@ -806,19 +1336,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
@@ -827,19 +1353,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
@@ -848,19 +1370,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
@@ -869,19 +1387,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
@@ -892,13 +1406,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++ )
- //
-
+ }
+ }
+ }
+ }
+ }
}
}
}
@@ -906,195 +1418,100 @@ 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),
- &TheCamera.GetCameraMatrix()) )
- {
- 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),
- &TheCamera.GetCameraMatrix()) )
- {
- 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),
- &TheCamera.GetCameraMatrix()) )
- {
- 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 + 400.0f) + 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) - 400.0f;
+ float fSectorY = WATER_FROM_SMALL_SECTOR_Y(BlockY);
+
+ RenderWavyMask(fMaskX, fMaskY, fWaterZ,
+ fSectorX, fSectorY,
+ signX, signY, colorTrans);
}
}
}
-
+
DefinedState();
+#endif
}
-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;
@@ -1118,25 +1535,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;
@@ -1159,27 +1576,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;
@@ -1202,27 +1625,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;
@@ -1239,172 +1668,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(geometry);
}
- static CBoat *apBoatList[4] = { nil };
+ 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);
+ }
+ }
+#endif
+}
+
+#ifdef PC_WATER
+void
+CWaterLevel::PreCalcWaterGeometry(void)
+{
+ if ( !RequireWavySector )
+ {
+ WavesCalculatedThisFrame = false;
+ MaskCalculatedThisFrame = false;
+ return;
+ }
+
+ RequireWavySector = false;
+ WavesCalculatedThisFrame = true;
+
+ 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;
@@ -1421,7 +2896,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
@@ -1456,101 +2931,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;
+}
- PUSH_MEMID(MEMID_STREAM);
+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;
+}
- ASSERT(ms_pWavyAtomic != nil );
+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);
+}
+
+bool
+CWaterLevel::GetWaterDepth(CVector const &vecPosn, float *pfDepth, float *pfLevelNoWaves, float *pfGroundLevel)
+{
+ float fLevelNoWaves;
+ float fGroundLevel;
- RpGeometry *wavyGeometry = RpAtomicGetGeometry(ms_pWavyAtomic);
- ASSERT(wavyGeometry != nil );
- RpMorphTarget *wavyMorphTarget = RpGeometryGetMorphTarget(wavyGeometry, 0);
- RpMaterial *wavyMaterial = RpGeometryGetMaterial(wavyGeometry, 0);
+ if ( !GetWaterLevelNoWaves(vecPosn.x, vecPosn.y, vecPosn.z, &fLevelNoWaves) )
+ return false;
+
+ if ( !GetGroundLevel(vecPosn, &fGroundLevel, nil, 30.0f) )
+ fGroundLevel = -100.0;
+
+ if ( pfDepth != nil )
+ *pfDepth = fLevelNoWaves - fGroundLevel;
+
+ if ( pfLevelNoWaves != nil )
+ *pfLevelNoWaves = fLevelNoWaves;
- ASSERT(wavyMorphTarget != nil );
- ASSERT(wavyMaterial != nil );
+ if ( pfGroundLevel != nil )
+ *pfGroundLevel = fGroundLevel;
+
+ return true;
+}
- for ( int32 geom = 0; geom < MAX_BOAT_WAKES; geom++ )
+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);
- RpTriangle *geomTriangles = RpGeometryGetTriangles(apGeomArray[geom]);
+ 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);
+ }
+ }
+ }
+}
+
+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;
+
+ float fAngle = CGeneral::GetRandomNumberInRange(450.0f, 750.0f);
- ASSERT( geomTriangles != nil );
+ 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, &TheCamera.GetCameraMatrix()) )
+ {
+ 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, &TheCamera.GetCameraMatrix()) )
+ {
+ 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/render/WaterLevel.h b/src/render/WaterLevel.h
index cf3537ae..5a497ddf 100644
--- a/src/render/WaterLevel.h
+++ b/src/render/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,116 @@
#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 void Initialise(Const char *pWaterDat);
+ 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 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);
};
+
+extern void WaterLevelInitialise(Const char *datFile); \ No newline at end of file
diff --git a/src/render/Weather.cpp b/src/render/Weather.cpp
index e765f306..3f242362 100644
--- a/src/render/Weather.cpp
+++ b/src/render/Weather.cpp
@@ -8,6 +8,7 @@
#include "DMAudio.h"
#include "General.h"
#include "Pad.h"
+#include "PlayerPed.h"
#include "Particle.h"
#include "RenderBuffer.h"
#include "Stats.h"
@@ -17,6 +18,10 @@
#include "Vehicle.h"
#include "World.h"
#include "ZoneCull.h"
+#include "SpecialFX.h"
+#include "Replay.h"
+
+//--MIAMI: file done
int32 CWeather::SoundHandle = -1;
@@ -31,7 +36,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 +46,60 @@ float CWeather::Rain;
float CWeather::InterpolationValue;
float CWeather::WetRoads;
float CWeather::Rainbow;
+float CWeather::SunGlare;
+float CWeather::WindClipped;
+float CWeather::TrafficLightBrightness;
bool CWeather::bScriptsForceRain;
-bool CWeather::Stored_StateStored;
-
-float CWeather::Stored_InterpolationValue;
-int16 CWeather::Stored_OldWeatherType;
-int16 CWeather::Stored_NewWeatherType;
-float CWeather::Stored_Rain;
tRainStreak Streaks[NUM_RAIN_STREAKS];
const int16 WeatherTypesList[] = {
+ WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY,
+ WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY,
+ WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_EXTRA_SUNNY,
+ WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY,
+ WEATHER_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY,
+ WEATHER_EXTRA_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_EXTRA_SUNNY,
+ WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY,
+ WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY,
+ WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY,
WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY,
- WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY,
- WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY,
- WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY,
- WEATHER_CLOUDY, WEATHER_CLOUDY, WEATHER_RAINY, WEATHER_RAINY,
+ WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_CLOUDY,
+ WEATHER_RAINY, WEATHER_RAINY, WEATHER_RAINY, WEATHER_RAINY,
WEATHER_CLOUDY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY,
- WEATHER_CLOUDY, WEATHER_FOGGY, WEATHER_FOGGY, WEATHER_CLOUDY,
- WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_CLOUDY, WEATHER_CLOUDY,
- WEATHER_SUNNY, WEATHER_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
+};
+
+const int16 WeatherTypesList_WithHurricanes[] = {
+ WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY,
+ WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY,
+ WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_EXTRA_SUNNY,
+ WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY,
+ WEATHER_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_CLOUDY,
+ WEATHER_HURRICANE, WEATHER_HURRICANE, WEATHER_CLOUDY, WEATHER_SUNNY,
+ WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY,
+ WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY,
+ WEATHER_EXTRA_SUNNY, WEATHER_EXTRA_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY,
WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY,
WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY, WEATHER_SUNNY,
- WEATHER_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 +130,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 +144,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,14 +210,14 @@ void CWeather::Update(void)
}
// Wet roads
- if (OldWeatherType == WEATHER_RAINY) {
- if (NewWeatherType == WEATHER_RAINY)
+ if (OldWeatherType == WEATHER_RAINY || OldWeatherType == WEATHER_HURRICANE) {
+ if (NewWeatherType == WEATHER_RAINY || NewWeatherType == WEATHER_HURRICANE)
WetRoads = 1.0f;
else
WetRoads = 1.0f - InterpolationValue;
}
else {
- if (NewWeatherType == WEATHER_RAINY)
+ if (NewWeatherType == WEATHER_RAINY || NewWeatherType == WEATHER_HURRICANE)
WetRoads = InterpolationValue;
else
WetRoads = 0.0f;
@@ -203,10 +225,10 @@ void CWeather::Update(void)
// Rain
float fNewRain;
- if (NewWeatherType == WEATHER_RAINY) {
+ if (NewWeatherType == WEATHER_RAINY || NewWeatherType == WEATHER_HURRICANE) {
// if raining for >1 hour, values: 0, 0.33, 0.66, 0.99, switching every ~16.5s
fNewRain = ((uint16)CTimer::GetTimeInMilliseconds() >> 14) * 0.33f;
- if (OldWeatherType != WEATHER_RAINY) {
+ if (OldWeatherType != WEATHER_RAINY && OldWeatherType != WEATHER_HURRICANE) {
if (InterpolationValue < 0.4f)
// if rain has just started (<24 minutes), always 0.5
fNewRain = 0.5f;
@@ -214,22 +236,18 @@ void CWeather::Update(void)
// 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;
}
+ fNewRain = Max(fNewRain, 0.5f);
}
else
fNewRain = 0.0f;
- if (Rain != fNewRain) { // ok to use comparasion
- if (Rain < fNewRain)
- Rain = Min(fNewRain, Rain + RAIN_CHANGE_SPEED * CTimer::GetTimeStep());
- else
- Rain = Max(fNewRain, Rain - RAIN_CHANGE_SPEED * CTimer::GetTimeStep());
- }
+ Rain = fNewRain;
// Clouds
- if (OldWeatherType != WEATHER_SUNNY)
+ if (OldWeatherType != WEATHER_SUNNY && OldWeatherType != WEATHER_EXTRA_SUNNY)
CloudCoverage = 1.0f - InterpolationValue;
else
CloudCoverage = 0.0f;
- if (NewWeatherType != WEATHER_SUNNY)
+ if (NewWeatherType != WEATHER_SUNNY && OldWeatherType != WEATHER_EXTRA_SUNNY)
CloudCoverage += InterpolationValue;
// Fog
@@ -239,12 +257,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)
@@ -264,6 +370,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())
@@ -275,104 +437,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);
+ }
}
}
}
@@ -420,9 +555,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);
@@ -445,6 +580,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++) {
@@ -455,11 +592,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;
@@ -473,7 +610,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;
@@ -481,8 +618,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();
}
}
@@ -494,7 +631,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);
@@ -510,23 +647,3 @@ void CWeather::RenderRainStreaks(void)
TempBufferVerticesStored = 0;
TempBufferIndicesStored = 0;
}
-
-void CWeather::StoreWeatherState()
-{
- Stored_StateStored = true;
- Stored_InterpolationValue = InterpolationValue;
- Stored_Rain = Rain;
- Stored_NewWeatherType = NewWeatherType;
- Stored_OldWeatherType = OldWeatherType;
-}
-
-void CWeather::RestoreWeatherState()
-{
-#ifdef FIX_BUGS // it's not used anyway though
- Stored_StateStored = false;
-#endif
- InterpolationValue = Stored_InterpolationValue;
- Rain = Stored_Rain;
- NewWeatherType = Stored_NewWeatherType;
- OldWeatherType = Stored_OldWeatherType;
-}
diff --git a/src/render/Weather.h b/src/render/Weather.h
index 9c670317..ef62ebb6 100644
--- a/src/render/Weather.h
+++ b/src/render/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,11 @@ 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();
};
enum {
@@ -68,4 +68,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/render/WindModifiers.cpp b/src/render/WindModifiers.cpp
new file mode 100644
index 00000000..3bd6ac9c
--- /dev/null
+++ b/src/render/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/render/WindModifiers.h b/src/render/WindModifiers.h
new file mode 100644
index 00000000..7c2e57bd
--- /dev/null
+++ b/src/render/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..b8d72d23 100644
--- a/src/rw/ClumpRead.cpp
+++ b/src/rw/ClumpRead.cpp
@@ -1,5 +1,6 @@
#include "common.h"
+//--MIAMI: done
struct rpGeometryList
{
diff --git a/src/rw/Lights.cpp b/src/rw/Lights.cpp
index b3cef6d4..e0dff850 100644
--- a/src/rw/Lights.cpp
+++ b/src/rw/Lights.cpp
@@ -9,6 +9,9 @@
#include "Weather.h"
#include "ZoneCull.h"
#include "Frontend.h"
+#include "MBlur.h"
+
+//--MIAMI: done
RpLight *pAmbient;
RpLight *pDirect;
@@ -23,6 +26,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 +40,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 +95,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 +351,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..45dd1fc2 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); } }
diff --git a/src/rw/MemoryHeap.h b/src/rw/MemoryHeap.h
index 23163c1c..38a8ba2b 100644
--- a/src/rw/MemoryHeap.h
+++ b/src/rw/MemoryHeap.h
@@ -18,7 +18,6 @@
enum {
MEMID_FREE,
// IDs from LCS:
-/*
MEMID_GAME = 1, // "Game"
MEMID_WORLD = 2, // "World"
MEMID_ANIMATION = 3, // "Animation"
@@ -38,25 +37,6 @@ enum {
MEMID_CARS = 17, // "Cars"
MEMID_RENDER = 18, // "Render"
MEMID_PED_ATTR = 19, // "Ped Attr"
-*/
- // III:
- MEMID_GAME = 1, // "Game"
- MEMID_WORLD = 2, // "World"
- MEMID_ANIMATION = 3, // "Animation"
- 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, // ?
-
NUM_MEMIDS,
NUM_FIXED_MEMBLOCKS = 6
diff --git a/src/rw/RwHelper.cpp b/src/rw/RwHelper.cpp
index e0133985..8e41cdc9 100644
--- a/src/rw/RwHelper.cpp
+++ b/src/rw/RwHelper.cpp
@@ -3,7 +3,6 @@
#endif
#include "common.h"
-#include "RwHelper.h"
#include "Timecycle.h"
#include "skeleton.h"
#include "Debug.h"
@@ -19,7 +18,7 @@ bool gPS2alphaTest = true;
#else
bool gPS2alphaTest = false;
#endif
-bool gBackfaceCulling = true;
+bool gBackfaceCulling;
#if !defined(FINAL) || defined(DEBUGMENU)
static bool charsetOpen;
@@ -76,7 +75,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,
@@ -86,22 +85,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
}
@@ -182,24 +172,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*
@@ -237,17 +214,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)
{
@@ -263,8 +229,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);
@@ -335,9 +300,9 @@ 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
}
@@ -370,7 +335,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,
@@ -483,7 +566,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
@@ -618,16 +701,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
@@ -637,7 +710,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 1a5f64b1..9352d1fd 100644
--- a/src/rw/RwHelper.h
+++ b/src/rw/RwHelper.h
@@ -1,6 +1,7 @@
#pragma once
extern bool gPS2alphaTest;
+extern bool gBackfaceCulling;
void OpenCharsetSafe();
void CreateDebugFont();
@@ -8,23 +9,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);
@@ -32,6 +32,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 7403ae1d..c5252f77 100644
--- a/src/rw/TexRead.cpp
+++ b/src/rw/TexRead.cpp
@@ -1,7 +1,13 @@
#pragma warning( push )
#pragma warning( disable : 4005)
#pragma warning( pop )
+#ifndef LIBRW
+#define WITHD3D
+#endif
#include "common.h"
+#ifndef LIBRW
+#include "rpanisot.h"
+#endif
#include "crossplatform.h"
#include "platform.h"
@@ -48,6 +54,15 @@ RwTextureGtaStreamRead(RwStream *stream)
texLoadTime = (texNumLoaded * texLoadTime + (float)CTimer::GetCurrentTimeInCycles() / (float)CTimer::GetCyclesPerMillisecond() - preloadTime) / (float)(texNumLoaded+1);
texNumLoaded++;
}
+
+ if(tex == nil)
+ return nil;
+
+#ifndef LIBRW
+ if(RpAnisotTextureGetMaxAnisotropy(tex) > 1)
+ RpAnisotTextureSetMaxAnisotropy(tex, RpAnisotTextureGetMaxAnisotropy(tex));
+#endif
+
return tex;
}
@@ -223,8 +238,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)
{
@@ -273,6 +290,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)
{
@@ -297,11 +329,12 @@ ConvertingTexturesScreen(uint32 num, uint32 count, const char *text)
CFont::SetBackgroundOff();
CFont::SetPropOn();
CFont::SetScale(SCREEN_SCALE_X(0.45f), SCREEN_SCALE_Y(0.7f));
+ CFont::SetCentreOff();
CFont::SetWrapx(SCREEN_SCALE_FROM_RIGHT(170.0f));
CFont::SetJustifyOff();
CFont::SetColor(CRGBA(255, 217, 106, 255));
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();
@@ -362,10 +395,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;
@@ -423,8 +456,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 21e00725..aa4bdcc0 100644
--- a/src/rw/VisibilityPlugins.cpp
+++ b/src/rw/VisibilityPlugins.cpp
@@ -2,9 +2,11 @@
#include "RwHelper.h"
#include "templates.h"
+#include "main.h"
#include "Entity.h"
#include "ModelInfo.h"
#include "Lights.h"
+#include "RwHelper.h"
#include "Renderer.h"
#include "Camera.h"
#include "VisibilityPlugins.h"
@@ -12,8 +14,15 @@
#include "custompipes.h"
#include "MemoryHeap.h"
+//--MIAMI: file done
+
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
int32 CVisibilityPlugins::ms_atomicPluginOffset = -1;
int32 CVisibilityPlugins::ms_framePluginOffset = -1;
@@ -27,122 +36,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)
@@ -150,6 +47,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 if not enough for bigger FOVs
m_alphaEntityList.Init(NUMALPHAENTITYLIST * 3);
@@ -158,19 +60,39 @@ CVisibilityPlugins::Initialise(void)
#endif // ASPECT_RATIO_SCALE
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;
+ m_alphaBuildingList.tail.item.sort = 100000000.0f;
+#endif
}
void
CVisibilityPlugins::Shutdown(void)
{
m_alphaList.Shutdown();
+ m_alphaBoatAtomicList.Shutdown();
m_alphaEntityList.Shutdown();
+ m_alphaUnderwaterEntityList.Shutdown();
+#ifdef NEW_RENDERER
+ m_alphaBuildingList.Shutdown();
+#endif
}
void
CVisibilityPlugins::InitAlphaEntityList(void)
{
m_alphaEntityList.Clear();
+ m_alphaBoatAtomicList.Clear();
+ m_alphaUnderwaterEntityList.Clear();
+#ifdef NEW_RENDERER
+ m_alphaBuildingList.Clear();
+#endif
}
bool
@@ -179,10 +101,13 @@ CVisibilityPlugins::InsertEntityIntoSortedList(CEntity *e, float dist)
AlphaObjectInfo item;
item.entity = e;
item.sort = dist;
- bool ret = !!m_alphaEntityList.InsertSorted(item);
-// if(!ret)
-// printf("list full %d\n", m_alphaEntityList.Count());
- return ret;
+#ifdef NEW_RENDERER
+ if(gbNewRenderer && e->IsBuilding())
+ return !!m_alphaBuildingList.InsertSorted(item);
+#endif
+ if(e->bUnderwater && m_alphaUnderwaterEntityList.InsertSorted(item))
+ return true;
+ return !!m_alphaEntityList.InsertSorted(item);
}
void
@@ -197,10 +122,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...
@@ -219,14 +150,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*
@@ -244,23 +189,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;
@@ -269,16 +224,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);
-#endif
if(e->bDistanceFade){
DeActivateDirectional();
@@ -289,38 +236,34 @@ CVisibilityPlugins::RenderFadingEntities(void)
}else
CRenderer::RenderOneNonRoad(e);
-#ifdef EXTRA_MODEL_FLAGS
- if(mi->m_bIsTree)
- SetAlphaRef(2);
-#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);
@@ -362,6 +305,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;
@@ -371,29 +332,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;
}
@@ -403,17 +365,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);
@@ -425,25 +386,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);
}
}
@@ -454,14 +414,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)
@@ -476,20 +435,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;
@@ -498,29 +456,36 @@ 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_bigVehicleLod1Dist)
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::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)
@@ -535,21 +500,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;
@@ -559,12 +523,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);
@@ -578,12 +540,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;
}
@@ -592,17 +549,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);
@@ -614,25 +570,24 @@ 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){
// 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);
}
}
@@ -640,54 +595,49 @@ 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)
{
- RpClump *clump;
- float dist;
- int32 alpha;
-
- clump = RpAtomicGetClump(atomic);
- dist = GetDistanceSquaredFromCamera(RpClumpGetFrame(clump));
- if(dist < ms_pedLod0Dist){
- alpha = GetClumpAlpha(clump);
- if(alpha == 255)
- RENDERCALLBACK(atomic);
- else
- RenderAlphaAtomic(atomic, alpha);
- }
+ if(CWorld::Players[0].m_pSkinTexture)
+ RpGeometryForAllMaterials(RpAtomicGetGeometry(atomic), SetTextureCB, CWorld::Players[0].m_pSkinTexture);
+ RENDERCALLBACK(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)
{
@@ -706,6 +656,14 @@ CVisibilityPlugins::RenderPedCB(RpAtomic *atomic)
}
float
+CVisibilityPlugins::GetDistanceSquaredFromCamera(RwV3d *pos)
+{
+ RwV3d dist;
+ RwV3dSub(&dist, pos, ms_pCameraPosn);
+ return RwV3dDotProduct(&dist, &dist);
+}
+
+float
CVisibilityPlugins::GetDistanceSquaredFromCamera(RwFrame *frame)
{
RwMatrix *m;
@@ -762,16 +720,6 @@ CVisibilityPlugins::DefaultVisibilityCB(RpClump *clump)
}
bool
-CVisibilityPlugins::MloVisibilityCB(RpClump *clump)
-{
- RwFrame *frame = RpClumpGetFrame(clump);
- CMloModelInfo *modelInfo = (CMloModelInfo*)GetFrameHierarchyId(frame);
- if (sq(modelInfo->field_34) < GetDistanceSquaredFromCamera(frame))
- return false;
- return CVisibilityPlugins::FrustumSphereCB(clump);
-}
-
-bool
CVisibilityPlugins::FrustumSphereCB(RpClump *clump)
{
RwSphere sphere;
@@ -828,11 +776,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;
}
@@ -870,13 +813,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*
@@ -907,7 +843,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 dd02f2e1..03833c9c 100644
--- a/src/rw/VisibilityPlugins.h
+++ b/src/rw/VisibilityPlugins.h
@@ -21,7 +21,12 @@ 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
static RwCamera *ms_pCamera;
static RwV3d *ms_pCameraPosn;
static float ms_cullCompsDist;
@@ -30,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;
@@ -40,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);
@@ -53,28 +60,33 @@ 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 *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);
static bool FrustumSphereCB(RpClump *clump);
- static bool MloVisibilityCB(RpClump *clump);
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 a7cafec8..82f66308 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,13 @@
#include "Weather.h"
#include "World.h"
#include "Zones.h"
+#include "Timecycle.h"
+#include "Fluff.h"
-#define BLOCK_COUNT 20
-#define SIZE_OF_SIMPLEVARS 0xBC
+// --MIAMI: file done
+
+#define BLOCK_COUNT 22
+#define SIZE_OF_SIMPLEVARS 0xE4
const uint32 SIZE_OF_ONE_GAME_IN_BYTES = 201729;
@@ -56,8 +61,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 +69,28 @@ bool StillToFadeOut;
uint32 TimeStartedCountingForFade;
uint32 TimeToStayFadedBeforeFadeOut = 1750;
+uint32 RadioStationPosition[NUM_RADIOS];
+
+void
+InitRadioStationPositionList()
+{
+ for (int i = 0; i < NUM_RADIOS; i++)
+ RadioStationPosition[i] = 0;
+}
+
+uint32
+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 +113,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 +147,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 +195,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 +207,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 +222,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 +230,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");
// Write padding
for (int i = 0; i < 4; i++) {
@@ -241,7 +274,8 @@ GenericSave(int file)
return false;
}
-
+
+ CPad::FixPadsAfterSave();
return true;
}
@@ -293,12 +327,6 @@ GenericLoad()
ReadDataFromBufferPointer(buf, CWeather::NewWeatherType);
ReadDataFromBufferPointer(buf, CWeather::ForcedWeatherType);
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
@@ -312,6 +340,13 @@ GenericLoad()
ReadDataFromBufferPointer(buf, TheCamera.CarZoomIndicator);
ReadDataFromBufferPointer(buf, TheCamera.PedZoomIndicator);
#endif
+ ReadDataFromBufferPointer(buf, CGame::currArea);
+ ReadDataFromBufferPointer(buf, CVehicle::bAllTaxisHaveNitro);
+ ReadDataFromBufferPointer(buf, CPad::bInvertLook4Pad);
+ 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;
@@ -326,6 +361,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();
@@ -355,16 +392,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;
@@ -419,8 +460,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, 0);
CTheScripts::Process();
}
@@ -563,19 +609,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 {
diff --git a/src/save/GenericGameStorage.h b/src/save/GenericGameStorage.h
index ee8a52a1..07aa23ca 100644
--- a/src/save/GenericGameStorage.h
+++ b/src/save/GenericGameStorage.h
@@ -1,9 +1,13 @@
#pragma once
+#include "Game.h"
#include "PCSave.h"
#define SLOT_COUNT (8)
+void InitRadioStationPositionList();
+uint32 GetSavedRadioStationPosition(int32 station);
+void PopulateRadioStationPositionList();
bool GenericSave(int file);
bool GenericLoad();
bool ReadInSizeofSaveFileBuffer(int32 &file, uint32 &size);
@@ -21,8 +25,6 @@ bool CheckDataNotCorrupt(int32 slot, char *name);
bool RestoreForStartLoad();
int align4bytes(int32 size);
-extern class CDate CompileDateAndTime;
-
extern char DefaultPCSaveFileName[260];
extern char ValidSaveName[260];
extern char LoadFileName[256];
@@ -30,7 +32,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 d8ede0d3..dd0926cf 100644
--- a/src/save/PCSave.cpp
+++ b/src/save/PCSave.cpp
@@ -12,6 +12,8 @@
#include "PCSave.h"
#include "Text.h"
+// --MIAMI: file done
+
const char* _psGetUserFilesFolder();
C_PcSave PcSaveHelper;
@@ -19,7 +21,7 @@ C_PcSave PcSaveHelper;
void
C_PcSave::SetSaveDirectory(const char *path)
{
- sprintf(DefaultPCSaveFileName, "%s\\%s", path, "GTA3sf");
+ sprintf(DefaultPCSaveFileName, "%s\\%s", path, "GTAVCsf");
}
bool
@@ -34,7 +36,7 @@ C_PcSave::DeleteSlot(int32 slot)
return true;
}
-bool
+int8
C_PcSave::SaveSlot(int32 slot)
{
MakeValidSaveName(slot);
@@ -49,10 +51,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;
@@ -89,7 +91,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';
}
@@ -109,14 +111,14 @@ 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)) {
SYSTEMTIME st;
memcpy(&st, &header.SaveDateTime, sizeof(SYSTEMTIME));
@@ -148,7 +150,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 4a2d9a66..2e85867a 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 a2, uint8 *data, uint32 size);
static void SetSaveDirectory(const char *path);
};
diff --git a/src/skel/crossplatform.cpp b/src/skel/crossplatform.cpp
index f2f9d5ee..37c94cb4 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 strtok doesn't return NULL for last delimiter
- if (extension - folder == strlen(pathname))
- extension = nil;
+ // because strtok doesn't return NULL for last delimiter
+ if (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))
@@ -256,3 +256,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 d8807f2b..bfc03913 100644
--- a/src/skel/crossplatform.h
+++ b/src/skel/crossplatform.h
@@ -12,6 +12,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/events.cpp b/src/skel/events.cpp
index 3e1e95b3..6589ab71 100644
--- a/src/skel/events.cpp
+++ b/src/skel/events.cpp
@@ -9,6 +9,8 @@
#include "events.h"
+// --MIAMI: file done
+
/*
*****************************************************************************
*/
diff --git a/src/skel/glfw/glfw.cpp b/src/skel/glfw/glfw.cpp
index 93bfde5a..f039819c 100644
--- a/src/skel/glfw/glfw.cpp
+++ b/src/skel/glfw/glfw.cpp
@@ -44,6 +44,7 @@
#define MAX_SUBSYSTEMS (16)
+// --MIAMI: file done
rw::EngineOpenParams openParams;
@@ -150,7 +151,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;
}
@@ -190,7 +191,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);
@@ -386,10 +391,6 @@ psInitialize(void)
InitialiseLanguage();
-#if GTA_VERSION < GTA3_PC_11
- FrontEndMenuManager.LoadSettings();
-#endif
-
#endif
gGameState = GS_START_UP;
@@ -439,13 +440,9 @@ psInitialize(void)
#ifndef PS2_MENU
-
-#if GTA_VERSION >= GTA3_PC_11
FrontEndMenuManager.LoadSettings();
#endif
-#endif
-
#ifdef _WIN32
MEMORYSTATUS memstats;
@@ -469,11 +466,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();
@@ -918,12 +931,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;
@@ -937,7 +971,7 @@ void psPostRWinit(void)
glfwSetJoystickCallback(joysChangeCB);
_InputInitialiseJoys();
- _InputInitialiseMouse();
+ _InputInitialiseMouse(false);
if(!(vm.flags & rwVIDEOMODEEXCLUSIVE))
glfwSetWindowSize(PSGLOBAL(window), RsGlobal.maximumWidth, RsGlobal.maximumHeight);
@@ -1116,7 +1150,7 @@ void InitialiseLanguage()
|| primLayout == LANG_GERMAN )
{
CGame::nastyGame = false;
- CMenuManager::m_PrefsAllowNastyGame = false;
+ FrontEndMenuManager.m_PrefsAllowNastyGame = false;
CGame::germanGame = true;
}
@@ -1125,7 +1159,7 @@ void InitialiseLanguage()
|| primLayout == LANG_FRENCH )
{
CGame::nastyGame = false;
- CMenuManager::m_PrefsAllowNastyGame = false;
+ FrontEndMenuManager.m_PrefsAllowNastyGame = false;
CGame::frenchGame = true;
}
@@ -1136,7 +1170,7 @@ void InitialiseLanguage()
#ifdef NASTY_GAME
CGame::nastyGame = true;
- CMenuManager::m_PrefsAllowNastyGame = true;
+ FrontEndMenuManager.m_PrefsAllowNastyGame = true;
CGame::noProstitutes = false;
#endif
@@ -1171,33 +1205,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;
}
}
@@ -1610,7 +1644,7 @@ main(int argc, char *argv[])
{
CFileMgr::SetDirMyDocuments();
- int32 gta3set = CFileMgr::OpenFile("gta3.set", "r");
+ int32 gta3set = CFileMgr::OpenFile("gta_vc.set", "r");
if ( gta3set )
{
@@ -1661,7 +1695,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();
@@ -1687,7 +1721,7 @@ main(int argc, char *argv[])
glfwPollEvents();
#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
@@ -1786,6 +1820,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;
@@ -1798,15 +1833,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 )
{
@@ -1889,7 +1924,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;
@@ -1992,7 +2027,6 @@ main(int argc, char *argv[])
#endif
}
-
#ifndef MASTER
if ( gbModelViewer )
CAnimViewer::Shutdown();
@@ -2148,5 +2182,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 98fc9843..0d70f27d 100644
--- a/src/skel/skeleton.cpp
+++ b/src/skel/skeleton.cpp
@@ -13,7 +13,7 @@
#include "main.h"
#include "MemoryHeap.h"
-
+// --MIAMI: file done
static RwBool DefaultVideoMode = TRUE;
@@ -373,8 +373,8 @@ RsRwInitialize(void *displayID)
psNativeTextureSupport();
+ RwTextureSetAutoMipmapping(TRUE);
RwTextureSetMipmapping(FALSE);
- RwTextureSetAutoMipmapping(FALSE);
POP_MEMID();
@@ -403,7 +403,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 2017c811..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..d253ff2c
--- /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 388090fc..1fd959f2 100644
--- a/src/skel/win/win.cpp
+++ b/src/skel/win/win.cpp
@@ -53,6 +53,7 @@
#define MAX_SUBSYSTEMS (16)
+// --MIAMI: file done
static RwBool ForegroundApp = TRUE;
@@ -190,7 +191,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;
}
@@ -230,7 +231,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);
@@ -651,10 +656,6 @@ psInitialize(void)
C_PcSave::SetSaveDirectory(_psGetUserFilesFolder());
InitialiseLanguage();
-#if GTA_VERSION >= GTA3_PC_11
- FrontEndMenuManager.LoadSettings();
-#endif
-
#endif
gGameState = GS_START_UP;
@@ -702,13 +703,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);
@@ -946,8 +943,7 @@ void HandleGraphEvent(void)
/*
*****************************************************************************
- */
-
+ */
LRESULT CALLBACK
MainWndProc(HWND window, UINT message, WPARAM wParam, LPARAM lParam)
{
@@ -1293,6 +1289,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;
+ }
+
}
/*
@@ -1301,7 +1307,6 @@ MainWndProc(HWND window, UINT message, WPARAM wParam, LPARAM lParam)
return DefWindowProc(window, message, wParam, lParam);
}
-
/*
*****************************************************************************
*/
@@ -1320,7 +1325,7 @@ InitApplication(HANDLE instance)
windowClass.cbClsExtra = 0;
windowClass.cbWndExtra = 0;
windowClass.hInstance = (HINSTANCE)instance;
- windowClass.hIcon = nil;
+ windowClass.hIcon = LoadIcon((HINSTANCE)instance, (LPCSTR)IDI_MAIN_ICON);
windowClass.hCursor = LoadCursor(nil, IDC_ARROW);
windowClass.hbrBackground = nil;
windowClass.lpszMenuName = NULL;
@@ -1376,10 +1381,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;
}
@@ -1388,10 +1390,7 @@ UINT GetBestRefreshRate(UINT width, UINT height, UINT depth)
}
}
- // From VC
-#ifdef FIX_BUGS
d3d->Release();
-#endif
if ( refreshRate == -1 )
return -1;
@@ -1662,7 +1661,6 @@ RwBool _psSetVideoMode(RwInt32 subSystem, RwInt32 videoMode)
return TRUE;
}
-
/*
*****************************************************************************
*/
@@ -1773,7 +1771,7 @@ void InitialiseLanguage()
|| primLayout == LANG_GERMAN )
{
CGame::nastyGame = false;
- CMenuManager::m_PrefsAllowNastyGame = false;
+ FrontEndMenuManager.m_PrefsAllowNastyGame = false;
CGame::germanGame = true;
}
@@ -1782,7 +1780,7 @@ void InitialiseLanguage()
|| primLayout == LANG_FRENCH )
{
CGame::nastyGame = false;
- CMenuManager::m_PrefsAllowNastyGame = false;
+ FrontEndMenuManager.m_PrefsAllowNastyGame = false;
CGame::frenchGame = true;
}
@@ -1793,7 +1791,7 @@ void InitialiseLanguage()
#ifdef NASTY_GAME
CGame::nastyGame = true;
- CMenuManager::m_PrefsAllowNastyGame = true;
+ FrontEndMenuManager.m_PrefsAllowNastyGame = true;
CGame::noProstitutes = false;
#endif
@@ -1828,33 +1826,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;
}
}
@@ -2074,7 +2072,7 @@ WinMain(HINSTANCE instance,
if ( _InputInitialise() == S_OK )
{
- _InputInitialiseMouse();
+ _InputInitialiseMouse(false);
_InputInitialiseJoys();
}
@@ -2148,7 +2146,7 @@ WinMain(HINSTANCE instance,
{
CFileMgr::SetDirMyDocuments();
- int32 gta3set = CFileMgr::OpenFile("gta3.set", "r");
+ int32 gta3set = CFileMgr::OpenFile("gta_vc.set", "r");
if ( gta3set )
{
@@ -2180,7 +2178,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();
@@ -2269,6 +2267,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() )
@@ -2290,7 +2290,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");
@@ -2306,6 +2306,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() )
@@ -2342,6 +2344,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;
@@ -2359,10 +2362,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 )
{
@@ -2447,7 +2451,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;
@@ -2616,7 +2620,7 @@ HRESULT _InputInitialise()
return S_OK;
}
-HRESULT _InputInitialiseMouse()
+HRESULT _InputInitialiseMouse(bool exclusive)
{
HRESULT hr;
@@ -2634,7 +2638,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
@@ -2922,6 +2926,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;
@@ -3391,5 +3417,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..db0865ae 100644
--- a/src/text/Messages.cpp
+++ b/src/text/Messages.cpp
@@ -11,6 +11,8 @@
#include "Font.h"
+// --MIAMI: file done
+
tMessage CMessages::BriefMessages[NUMBRIEFMESSAGES];
tPreviousBrief CMessages::PreviousBriefs[NUMPREVIOUSBRIEFS];
tBigMessage CMessages::BIGMessages[NUMBIGMESSAGES];
@@ -290,6 +292,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 +323,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 +422,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 f3324fd7..e23369fb 100644
--- a/src/text/Text.cpp
+++ b/src/text/Text.cpp
@@ -7,6 +7,9 @@
#include "Frontend.h"
#include "Messages.h"
#include "Text.h"
+#include "Timer.h"
+
+//--MIAMI: file done
static wchar WideErrorString[25];
@@ -15,22 +18,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];
- intptr_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 +68,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;
+#ifdef FIX_BUGS
+ wchar *outstr = keyArray.Search(key, data.chars, &result);
+#else
+ wchar *outstr = keyArray.Search(key, &result);
+#endif
+
+ if (!result && bHasMissionTextOffsets && bIsMissionTextLoaded)
#ifdef FIX_BUGS
- return keyArray.Search(key, data.chars);
+ outstr = mission_keyArray.Search(key, mission_data.chars, &result);
#else
- return keyArray.Search(key);
+ outstr = mission_keyArray.Search(key, &result);
#endif
+ return outstr;
}
wchar UpperCaseTable[128] = {
@@ -174,20 +196,137 @@ CText::UpperCase(wchar *s)
}
}
+void
+CText::GetNameOfLoadedMissionText(char *outName)
+{
+ strcpy(outName, szMissionTableName);
+}
void
-CKeyArray::Load(size_t length, uint8 *data, intptr_t *offset)
+CText::ReadChunkHeader(ChunkHeader *buf, int32 file, size_t *offset)
{
- size_t i;
- uint8 *rawbytes;
+#if 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 LANGUAGE_POLISH:
+ sprintf(filename, "POLISH.GXT");
+ break;
+ case LANGUAGE_RUSSIAN:
+ sprintf(filename, "RUSSIAN.GXT");
+ break;
+ case LANGUAGE_JAPANESE:
+ sprintf(filename, "JAPANESE.GXT");
+ break;
+#endif
+ }
+ CTimer::Suspend();
+ int file = CFileMgr::OpenFile(filename, "rb");
+ CFileMgr::Seek(file, MissionTextOffsets.data[missionTableId].offset, SEEK_SET);
+
+ char TableCheck[8];
+ CFileMgr::Read(file, TableCheck, 8);
+ if (strncmp(TableCheck, MissionTableName, 8) != 0)
+ printf("CText::LoadMissionText - expected to find %s in the text file", MissionTableName);
+
+ bool tkey_loaded = false, tdat_loaded = false;
+ ChunkHeader m_ChunkHeader;
+ while (!tkey_loaded || !tdat_loaded) {
+ 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)++];
+#if DUMB
+ 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 +369,9 @@ CKeyArray::BinarySearch(const char *key, CKeyEntry *entries, int16 low, int16 hi
wchar*
#ifdef FIX_BUGS
-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 +380,47 @@ CKeyArray::Search(const char *key)
#ifdef FIX_BUGS
found = BinarySearch(key, entries, 0, numEntries-1);
- if(found)
+ if (found) {
+ *result = true;
return (wchar*)((uint8*)data + found->valueOffset);
+ }
#else
found = BinarySearch(key, entries, 0, numEntries-1);
- if(found)
+ 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, intptr_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)++];
+#if DUMB
+ 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 +431,33 @@ CData::Unload(void)
numChars = 0;
}
+void
+CMissionTextOffsets::Load(size_t table_size, int file, size_t *offset, int)
+{
+#if DUMB
+ 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 +470,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 52c17e27..33dc313e 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, intptr_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);
#ifdef FIX_BUGS
- 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, intptr_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 79d3f6af..d20f1177 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,8 +48,11 @@
#include "PlayerPed.h"
#include "Object.h"
#include "Automobile.h"
+#include "Bike.h"
-bool bAllCarCheat; // unused
+//--MIAMI: file done
+
+bool bAllCarCheat;
RwObject *GetCurrentAtomicObjectCB(RwObject *object, void *data);
@@ -53,7 +60,7 @@ bool CAutomobile::m_sAllTaxiLights;
const uint32 CAutomobile::nSaveStructSize =
#ifdef COMPATIBLE_SAVES
- 1448;
+ 1500;
#else
sizeof(CAutomobile);
#endif
@@ -67,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;
@@ -75,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;
@@ -129,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;
@@ -139,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;
@@ -150,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;
}
@@ -159,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){
@@ -173,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;
@@ -184,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;
@@ -194,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);
@@ -205,7 +237,6 @@ CAutomobile::CAutomobile(int32 id, uint8 CreatedBy)
}
}
-
void
CAutomobile::SetModelIndex(uint32 id)
{
@@ -213,6 +244,11 @@ 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);
@@ -227,12 +263,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;
+
+ bool carHasNitro = bAllTaxisHaveNitro && GetStatus() == STATUS_PLAYER && IsTaxi();
- // skip if the collision isn't for the current level
- if(colModel->level > LEVEL_GENERIC && colModel->level != CCollision::ms_collisionInMemory)
+ 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;
@@ -247,7 +296,8 @@ CAutomobile::ProcessControl(void)
else if((GetPosition() - FindPlayerCoors()).Magnitude() > 50.0f)
strongGrip2 = true;
}
- }
+ }else if(GetModelIndex() == MI_RCBANDIT && GetStatus() != STATUS_PLAYER_REMOTE)
+ strongGrip1 = true;
if(bIsBus)
ProcessAutoBusDoors();
@@ -258,7 +308,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:
@@ -268,25 +318,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()){
@@ -300,18 +340,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;
@@ -322,24 +351,33 @@ 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
bool playerRemote = false;
switch(GetStatus()){
case STATUS_PLAYER_REMOTE:
- if(CPad::GetPad(0)->WeaponJustDown()){
+ if(CPad::GetPad(0)->WeaponJustDown() && !bDisableRemoteDetonation){
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());
}
@@ -350,7 +388,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);
@@ -359,7 +397,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)->WeaponJustDown())
+ ActivateBomb();
break;
case STATUS_SIMPLE:
@@ -380,6 +470,7 @@ CAutomobile::ProcessControl(void)
PlayHornIfNecessary();
ReduceHornCounter();
bVehicleColProcessed = false;
+ bAudioChangingGear = false;
// that's all we do for simple vehicles
return;
@@ -387,15 +478,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:
@@ -404,26 +524,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)){
@@ -451,7 +577,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++;
@@ -467,15 +594,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
@@ -487,12 +626,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
@@ -531,12 +669,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;
+
float brake;
if(skipPhysics){
bHasContacted = false;
@@ -546,11 +689,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
@@ -603,6 +748,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
@@ -620,13 +773,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);
}
@@ -643,6 +803,8 @@ 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
@@ -661,7 +823,6 @@ CAutomobile::ProcessControl(void)
}
}
-
bool gripCheat = true;
fwdSpeed = DotProduct(m_vecMoveSpeed, GetForward());
if(!strongGrip1 && !CVehicle::bCheat3)
@@ -669,14 +830,25 @@ 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 if(m_nBusDoorTimerEnd > CTimer::GetTimeStepInMilliseconds())
+ m_nBusDoorTimerEnd -= CTimer::GetTimeStepInMilliseconds();
+ }
+
+ 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 tractionBiasFront = neutralHandling ? 1.0f : 2.0f*pHandling->fTractionBias;
@@ -722,21 +894,7 @@ CAutomobile::ProcessControl(void)
if(CVehicle::bCheat3)
traction *= 4.0f;
- if(FindPlayerVehicle() && FindPlayerVehicle() == this){
- if(CPad::GetPad(0)->WeaponJustDown()){
- if(m_bombType == CARBOMB_TIMED){
- m_bombType = CARBOMB_TIMEDACTIVE;
- m_nBombTimer = 7000;
- m_pBlowUpEntity = FindPlayerPed();
- CGarages::TriggerMessage("GA_12", -1, 3000, -1);
- DMAudio.PlayOneShot(m_audioEntityId, SOUND_BOMB_TIMED_ACTIVATED, 1.0f);
- }else if(m_bombType == CARBOMB_ONIGNITION){
- m_bombType = CARBOMB_ONIGNITIONACTIVE;
- CGarages::TriggerMessage("GA_12", -1, 3000, -1);
- DMAudio.PlayOneShot(m_audioEntityId, SOUND_BOMB_ONIGNITION_ACTIVATED, 1.0f);
- }
- }
- }else if(strongGrip1 || CVehicle::bCheat3){
+ if(FindPlayerVehicle() != this && (strongGrip1 || CVehicle::bCheat3)){
traction *= 1.2f;
acceleration *= 1.4f;
if(strongGrip2 || CVehicle::bCheat3){
@@ -748,13 +906,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.HasRearWheelDrive(pHandling->nIdentifier))
@@ -762,6 +923,15 @@ CAutomobile::ProcessControl(void)
else
fThrust = acceleration;
+ 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)
@@ -796,6 +966,15 @@ CAutomobile::ProcessControl(void)
else
fThrust = acceleration;
+ 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)
@@ -827,33 +1006,36 @@ CAutomobile::ProcessControl(void)
// Process front wheels off ground
- if(m_aWheelTimer[CARWHEEL_FRONT_LEFT] <= 0.0f){
- if(mod_HandlingManager.HasRearWheelDrive(pHandling->nIdentifier) || acceleration == 0.0f)
- m_aWheelSpeed[CARWHEEL_FRONT_LEFT] *= 0.95f;
- else{
- 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;
+ if(!IsRealHeli()){
+ if(m_aWheelTimer[CARWHEEL_FRONT_LEFT] <= 0.0f){
+ if(mod_HandlingManager.HasRearWheelDrive(pHandling->nIdentifier) || acceleration == 0.0f)
+ m_aWheelSpeed[CARWHEEL_FRONT_LEFT] *= 0.95f;
+ else{
+ 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;
+ }
}
+ 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.HasRearWheelDrive(pHandling->nIdentifier) || acceleration == 0.0f)
- m_aWheelSpeed[CARWHEEL_FRONT_RIGHT] *= 0.95f;
- else{
- 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;
+ if(m_aWheelTimer[CARWHEEL_FRONT_RIGHT] <= 0.0f){
+ if(mod_HandlingManager.HasRearWheelDrive(pHandling->nIdentifier) || acceleration == 0.0f)
+ m_aWheelSpeed[CARWHEEL_FRONT_RIGHT] *= 0.95f;
+ else{
+ 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;
+ }
}
+ m_aWheelRotation[CARWHEEL_FRONT_RIGHT] += m_aWheelSpeed[CARWHEEL_FRONT_RIGHT];
}
- m_aWheelRotation[CARWHEEL_FRONT_RIGHT] += m_aWheelSpeed[CARWHEEL_FRONT_RIGHT];
+ }
}
// Process rear wheels
@@ -862,14 +1044,28 @@ CAutomobile::ProcessControl(void)
CVector wheelFwd = GetForward();
CVector wheelRight = GetRight();
+ 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.HasFrontWheelDrive(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.HasFrontWheelDrive(pHandling->nIdentifier))
@@ -877,8 +1073,14 @@ CAutomobile::ProcessControl(void)
else
fThrust = acceleration;
+ wheelFwd = GetForward();
+ 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];
@@ -887,7 +1089,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],
@@ -897,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,
CARWHEEL_REAR_LEFT,
&m_aWheelSpeed[CARWHEEL_REAR_LEFT],
@@ -905,14 +1107,26 @@ CAutomobile::ProcessControl(void)
WHEEL_STATUS_OK);
}
+#ifdef FIX_BUGS
+ // Shouldn't we reset these after the left wheel?
+ wheelFwd = GetForward();
+ wheelRight = GetRight();
+#endif
+
if(m_aWheelTimer[CARWHEEL_REAR_RIGHT] > 0.0f){
if(mod_HandlingManager.HasFrontWheelDrive(pHandling->nIdentifier))
fThrust = 0.0f;
else
fThrust = acceleration;
+ wheelFwd = GetForward();
+ 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];
@@ -921,7 +1135,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],
@@ -931,7 +1145,7 @@ CAutomobile::ProcessControl(void)
ProcessWheel(wheelFwd, wheelRight,
contactSpeeds[CARWHEEL_REAR_RIGHT], contactPoints[CARWHEEL_REAR_RIGHT],
m_nWheelsOnGround, fThrust,
- brake*brakeBiasRear,
+ rearBrake*brakeBiasRear,
adhesion*tractionBiasRear,
CARWHEEL_REAR_RIGHT,
&m_aWheelSpeed[CARWHEEL_REAR_RIGHT],
@@ -940,58 +1154,203 @@ CAutomobile::ProcessControl(void)
}
}
+ if(m_doingBurnout && !mod_HandlingManager.HasFrontWheelDrive(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.HasFrontWheelDrive(pHandling->nIdentifier) || acceleration == 0.0f)
- m_aWheelSpeed[CARWHEEL_REAR_LEFT] *= 0.95f;
- else{
- 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;
+ if(!IsRealHeli()){
+ if(m_aWheelTimer[CARWHEEL_REAR_LEFT] <= 0.0f){
+ if(mod_HandlingManager.HasFrontWheelDrive(pHandling->nIdentifier) || acceleration == 0.0f)
+ m_aWheelSpeed[CARWHEEL_REAR_LEFT] *= 0.95f;
+ else{
+ 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;
+ }
}
+ m_aWheelRotation[CARWHEEL_REAR_LEFT] += m_aWheelSpeed[CARWHEEL_REAR_LEFT];
}
- m_aWheelRotation[CARWHEEL_REAR_LEFT] += m_aWheelSpeed[CARWHEEL_REAR_LEFT];
- }
- if(m_aWheelTimer[CARWHEEL_REAR_RIGHT] <= 0.0f){
- if(mod_HandlingManager.HasFrontWheelDrive(pHandling->nIdentifier) || acceleration == 0.0f)
- m_aWheelSpeed[CARWHEEL_REAR_RIGHT] *= 0.95f;
- else{
- 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;
+ if(m_aWheelTimer[CARWHEEL_REAR_RIGHT] <= 0.0f){
+ if(mod_HandlingManager.HasFrontWheelDrive(pHandling->nIdentifier) || acceleration == 0.0f)
+ m_aWheelSpeed[CARWHEEL_REAR_RIGHT] *= 0.95f;
+ else{
+ 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;
+ }
+ }
+ m_aWheelRotation[CARWHEEL_REAR_RIGHT] += m_aWheelSpeed[CARWHEEL_REAR_RIGHT];
+ }
+ }
+
+ // Process front wheels on ground - second try
+
+ if(rearWheelsFirst){
+ if(m_aWheelTimer[CARWHEEL_FRONT_LEFT] > 0.0f || m_aWheelTimer[CARWHEEL_FRONT_RIGHT] > 0.0f){
+ float s = Sin(m_fSteerAngle);
+ float c = Cos(m_fSteerAngle);
+
+ CVector wheelFwd, wheelRight, tmp;
+
+ if(m_aWheelTimer[CARWHEEL_FRONT_LEFT] > 0.0f){
+ if(mod_HandlingManager.HasRearWheelDrive(pHandling->nIdentifier))
+ fThrust = 0.0f;
+ else
+ fThrust = acceleration;
+
+ 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.HasRearWheelDrive(pHandling->nIdentifier))
+ fThrust = 0.0f;
+ else
+ fThrust = acceleration;
+
+ 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.HasRearWheelDrive(pHandling->nIdentifier) || acceleration == 0.0f)
+ m_aWheelSpeed[CARWHEEL_FRONT_LEFT] *= 0.95f;
+ else{
+ 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;
+ }
}
+ m_aWheelRotation[CARWHEEL_FRONT_LEFT] += m_aWheelSpeed[CARWHEEL_FRONT_LEFT];
}
- m_aWheelRotation[CARWHEEL_REAR_RIGHT] += m_aWheelSpeed[CARWHEEL_REAR_RIGHT];
+ if(m_aWheelTimer[CARWHEEL_FRONT_RIGHT] <= 0.0f){
+ if(mod_HandlingManager.HasRearWheelDrive(pHandling->nIdentifier) || acceleration == 0.0f)
+ m_aWheelSpeed[CARWHEEL_FRONT_RIGHT] *= 0.95f;
+ else{
+ 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;
+ }
+ }
+ m_aWheelRotation[CARWHEEL_FRONT_RIGHT] += m_aWheelSpeed[CARWHEEL_FRONT_RIGHT];
+ }
+ }
}
for(i = 0; i < 4; i++){
float wheelPos = colModel->lines[i].p0.z;
if(m_aSuspensionSpringRatio[i] > 0.0f)
wheelPos -= m_aSuspensionSpringRatio[i]*m_aSuspensionSpringLength[i];
- m_aWheelPosition[i] += (wheelPos - m_aWheelPosition[i])*0.75f;
+ if(GetModelIndex() == MI_VOODOO && bUsingSpecialColModel)
+ m_aWheelPosition[i] = wheelPos;
+ else
+ m_aWheelPosition[i] += (wheelPos - m_aWheelPosition[i])*0.75f;
}
for(i = 0; i < 4; i++)
m_aWheelState[i] = WheelState[i];
+ if(m_fGasPedal < 0.0f){
+ if(m_aWheelState[CARWHEEL_REAR_LEFT] == WHEEL_STATE_SPINNING)
+ m_aWheelState[CARWHEEL_REAR_LEFT] = WHEEL_STATE_NORMAL;
+ if(m_aWheelState[CARWHEEL_REAR_RIGHT] == WHEEL_STATE_SPINNING)
+ m_aWheelState[CARWHEEL_REAR_RIGHT] = WHEEL_STATE_NORMAL;
+ }
// Process horn
if(GetStatus() != STATUS_PLAYER){
- ReduceHornCounter();
+ if(!IsAlarmOn())
+ ReduceHornCounter();
}else{
- if(GetModelIndex() == MI_MRWHOOP){
- if(Pads[0].bHornHistory[Pads[0].iCurrHornHistory] &&
- !Pads[0].bHornHistory[(Pads[0].iCurrHornHistory+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])
@@ -1004,42 +1363,141 @@ 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 || CPad::GetPad(0)->GetCarGunUpDown() > 1.0f ||
+ 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];
+ }
}
}
}
@@ -1082,7 +1540,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),
@@ -1094,10 +1552,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;
@@ -1109,7 +1565,7 @@ CAutomobile::ProcessControl(void)
if(m_bSirenOrAlarm && (CTimer::GetFrameCounter()&7) == 5 &&
- UsesSiren(GetModelIndex()) && GetModelIndex() != MI_MRWHOOP)
+ UsesSiren() && GetModelIndex() != MI_MRWHOOP)
CCarAI::MakeWayForCarWithSiren(this);
@@ -1117,10 +1573,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;
}
@@ -1129,7 +1589,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){
@@ -1137,13 +1597,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);
@@ -1158,8 +1622,9 @@ CAutomobile::ProcessControl(void)
}
bVehicleColProcessed = false;
+ bAudioChangingGear = false;
- if(!bWarnedPeds)
+ if(!bWarnedPeds && GetVehicleAppearance() != VEHICLE_APPEARANCE_HELI && GetVehicleAppearance() != VEHICLE_APPEARANCE_PLANE)
CCarCtrl::ScanForPedDanger(this);
@@ -1167,20 +1632,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();
@@ -1188,7 +1653,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();
@@ -1207,11 +1672,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;
+ }
+ }
}
void
@@ -1235,6 +1720,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);
@@ -1245,7 +1741,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++){
@@ -1300,6 +1796,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)){
@@ -1319,46 +1816,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);
+ }
+ }
}
}
}
@@ -1381,7 +1911,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;
}
@@ -1399,7 +1929,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;
}
@@ -1434,21 +1964,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;
@@ -1458,17 +1989,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);
}
}
@@ -1540,8 +2116,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,
@@ -1579,17 +2155,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);
}
@@ -1597,7 +2182,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,
@@ -1614,7 +2200,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
@@ -1653,7 +2240,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
@@ -1668,7 +2254,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;
@@ -1758,7 +2345,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;
@@ -1832,7 +2419,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);
@@ -1924,26 +2511,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
@@ -1951,7 +2555,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)
@@ -1962,75 +2566,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]));
@@ -2039,8 +2730,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]){
@@ -2070,59 +2759,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);
@@ -2130,11 +2898,104 @@ CAutomobile::Render(void)
ProcessSwingingDoor(CAR_DOOR_RR, DOOR_REAR_RIGHT);
ProcessSwingingDoor(CAR_BONNET, DOOR_BONNET);
ProcessSwingingDoor(CAR_BOOT, DOOR_BOOT);
+ }
+
+ if((GetModelIndex() == MI_PHEONIX || GetModelIndex() == MI_BFINJECT) &&
+ GetStatus() == STATUS_PLAYER && m_aCarNodes[CAR_WING_LR]){
+ float rotation = 0.0f;
+
+ if(GetModelIndex() == MI_BFINJECT)
+ if(m_fPropellerRotation > TWOPI) m_fPropellerRotation -= TWOPI;
+
+ 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();
+ }
+}
- mi->SetVehicleColour(m_currentColour1, m_currentColour2);
+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)
+ 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();
}
@@ -2157,6 +3018,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,
@@ -2165,12 +3030,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++;
@@ -2182,30 +3042,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);
@@ -2231,10 +3075,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_CAR_ROLLOUT_LHS ||
+ pDriver->m_pVehicleAnim->animId == ANIM_CAR_ROLLOUT_RHS))
bIsHandbrakeOn = !!CPad::GetPad(pad)->GetHandBrake();
+ else
+ bIsHandbrakeOn = true;
// Steer left/right
if(CCamera::m_bUseMouse3rdPerson && !CVehicle::m_bDisableMouseSteering){
@@ -2262,8 +3108,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
@@ -2312,17 +3164,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:
@@ -2342,14 +3183,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;
@@ -2367,7 +3210,7 @@ void
CAutomobile::FireTruckControl(void)
{
if(this == FindPlayerVehicle()){
- if(!CPad::GetPad(0)->GetWeapon())
+ if(!CPad::GetPad(0)->GetCarGunFired())
return;
#ifdef FREE_CAM
if (!CCamera::bFreeCam)
@@ -2524,22 +3367,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)
@@ -2647,8 +3478,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{
@@ -2722,7 +3551,6 @@ CAutomobile::HydraulicControl(void)
}
setPrevRatio = true;
- m_aWheelPosition[i] -= 0.05f;
}
DMAudio.PlayOneShot(m_audioEntityId, SOUND_CAR_HYDRAULIC_2, 0.0f);
}
@@ -2753,7 +3581,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;
@@ -2773,15 +3600,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;
@@ -2847,19 +3670,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;
@@ -2874,49 +3725,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);
@@ -2957,6 +3794,7 @@ CAutomobile::ProcessBuoyancy(void)
}
}else{
bIsInWater = false;
+ bIsDrowning = false;
bTouchingWater = false;
static RwRGBA splashCol = {155, 155, 185, 196};
@@ -2967,13 +3805,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);
@@ -2993,35 +3825,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
}
}
}
@@ -3030,16 +3833,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())
@@ -3051,37 +3859,42 @@ CAutomobile::DoDriveByShootings(void)
lookingRight = true;
}
+ AnimationId rightAnim = ANIM_DRIVEBY_R;
+ AnimationId leftAnim = ANIM_DRIVEBY_L;
+ if (pDriver->m_pMyVehicle->bLowVehicle) {
+ rightAnim = ANIM_DRIVEBY_LOW_R;
+ leftAnim = ANIM_DRIVEBY_LOW_L;
+ }
+
if(lookingLeft || lookingRight){
if(lookingLeft){
- anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_DRIVEBY_R);
+ anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), rightAnim);
if(anim)
anim->blendDelta = -1000.0f;
- anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_DRIVEBY_L);
+ anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), leftAnim);
if(anim == nil || anim->blendDelta < 0.0f)
- CAnimManager::AddAnimation(pDriver->GetClump(), ASSOCGRP_STD, ANIM_DRIVEBY_L);
- else
- anim->SetRun();
+ anim = CAnimManager::AddAnimation(pDriver->GetClump(), ASSOCGRP_STD, leftAnim);
}else if(pDriver->m_pMyVehicle->pPassengers[0] == nil || TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_1STPERSON){
- anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_DRIVEBY_L);
+ anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), leftAnim);
if(anim)
anim->blendDelta = -1000.0f;
- anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_DRIVEBY_R);
+ anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), rightAnim);
if(anim == nil || anim->blendDelta < 0.0f)
- CAnimManager::AddAnimation(pDriver->GetClump(), ASSOCGRP_STD, ANIM_DRIVEBY_R);
- else
- anim->SetRun();
+ anim = CAnimManager::AddAnimation(pDriver->GetClump(), ASSOCGRP_STD, rightAnim);
}
- if(CPad::GetPad(0)->GetCarGunFired() && CTimer::GetTimeInMilliseconds() > weapon->m_nTimer){
- weapon->FireFromCar(this, lookingLeft);
- weapon->m_nTimer = CTimer::GetTimeInMilliseconds() + 70;
+ if (!anim || !anim->IsRunning()) {
+ if (CPad::GetPad(0)->GetCarGunFired() && CTimer::GetTimeInMilliseconds() > weapon->m_nTimer) {
+ weapon->FireFromCar(this, lookingLeft, true);
+ weapon->m_nTimer = CTimer::GetTimeInMilliseconds() + 70;
+ }
}
}else{
weapon->Reload();
- anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_DRIVEBY_L);
+ anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), leftAnim);
if(anim)
anim->blendDelta = -1000.0f;
- anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_DRIVEBY_R);
+ anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), rightAnim);
if(anim)
anim->blendDelta = -1000.0f;
}
@@ -3089,11 +3902,49 @@ CAutomobile::DoDriveByShootings(void)
// TODO: what is this?
if(!lookingLeft && m_weaponDoorTimerLeft > 0.0f){
m_weaponDoorTimerLeft = Max(m_weaponDoorTimerLeft - CTimer::GetTimeStep()*0.1f, 0.0f);
- ProcessOpenDoor(CAR_DOOR_LF, NUM_ANIMS, m_weaponDoorTimerLeft);
+ ProcessOpenDoor(CAR_DOOR_LF, NUM_STD_ANIMS, m_weaponDoorTimerLeft);
}
if(!lookingRight && m_weaponDoorTimerRight > 0.0f){
m_weaponDoorTimerRight = Max(m_weaponDoorTimerRight - CTimer::GetTimeStep()*0.1f, 0.0f);
- ProcessOpenDoor(CAR_DOOR_RF, NUM_ANIMS, m_weaponDoorTimerRight);
+ ProcessOpenDoor(CAR_DOOR_RF, NUM_STD_ANIMS, m_weaponDoorTimerRight);
+ }
+}
+
+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;
+ }
}
}
@@ -3136,7 +3987,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 &&
@@ -3210,8 +4062,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;
@@ -3219,19 +4070,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 &&
@@ -3244,12 +4106,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;
@@ -3269,109 +4136,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:
@@ -3385,37 +4224,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;
}
@@ -3490,15 +4334,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)){
@@ -3516,26 +4361,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);
}
}
@@ -3547,9 +4438,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){
@@ -3568,7 +4461,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:
@@ -3580,30 +4473,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;
}
}
@@ -3714,6 +4607,7 @@ inline void ProcessDoorOpenCloseAnimation(CAutomobile *car, uint32 component, eD
car->OpenDoor(component, door, 0.0f);
}
}
+
void
CAutomobile::ProcessOpenDoor(uint32 component, uint32 anim, float time)
{
@@ -3734,13 +4628,13 @@ CAutomobile::ProcessOpenDoor(uint32 component, uint32 anim, float time)
case ANIM_CAR_QJACK:
case ANIM_CAR_OPEN_LHS:
case ANIM_CAR_OPEN_RHS:
- ProcessDoorOpenAnimation(this, component, door, time, 0.66f, 0.8f);
+ ProcessDoorOpenAnimation(this, component, door, time, 0.41f, 0.89f);
break;
case ANIM_CAR_CLOSEDOOR_LHS:
case ANIM_CAR_CLOSEDOOR_LOW_LHS:
case ANIM_CAR_CLOSEDOOR_RHS:
case ANIM_CAR_CLOSEDOOR_LOW_RHS:
- ProcessDoorCloseAnimation(this, component, door, time, 0.2f, 0.63f);
+ ProcessDoorCloseAnimation(this, component, door, time, 0.2f, 0.45f);
break;
case ANIM_CAR_ROLLDOOR:
case ANIM_CAR_ROLLDOOR_LOW:
@@ -3779,7 +4673,7 @@ CAutomobile::ProcessOpenDoor(uint32 component, uint32 anim, float time)
case ANIM_VAN_GETOUT:
ProcessDoorOpenAnimation(this, component, door, time, 0.5f, 0.6f);
break;
- case NUM_ANIMS:
+ case NUM_STD_ANIMS:
OpenDoor(component, door, time);
break;
}
@@ -3819,6 +4713,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)
{
@@ -3831,12 +4760,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);
@@ -3866,27 +4800,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_KO_SHOT_FRONT1, 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_KO_SHOT_FRONT1, 4.0f, 0.0f);
- }
- }
+ KillPedsInVehicle();
bEngineOn = false;
bLightsOn = false;
@@ -3916,24 +4830,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;
@@ -3941,10 +4859,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;
@@ -3955,14 +4875,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());
+ }
}
}
@@ -4008,7 +4932,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);
@@ -4039,10 +4963,16 @@ CAutomobile::PlayCarHorn(void)
{
int 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){
@@ -4064,7 +4994,6 @@ CAutomobile::PlayHornIfNecessary(void)
PlayCarHorn();
}
-
void
CAutomobile::ResetSuspension(void)
{
@@ -4107,8 +5036,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;
@@ -4142,13 +5071,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
@@ -4182,6 +5114,7 @@ CAutomobile::HasCarStoppedBecauseOfLight(void)
return false;
}
+// --MIAMI: Done
void
CPed::DeadPedMakesTyresBloody(void)
{
@@ -4205,27 +5138,33 @@ CPed::DeadPedMakesTyresBloody(void)
}
}
+// --MIAMI: Done
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;
@@ -4240,24 +5179,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) {
+
+ 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;
+ }
- if (veh == FindPlayerVehicle()) {
- CPad::GetPad(0)->StartShake(300, 70);
+ // 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);
+ }
+ }
}
}
}
@@ -4328,6 +5308,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 };
@@ -4337,6 +5320,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
@@ -4363,6 +5367,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
@@ -4404,8 +5421,6 @@ GetCurrentAtomicObjectCB(RwObject *object, void *data)
return object;
}
-static CColPoint aTempPedColPts[MAX_COLLISION_POINTS];
-
CObject*
CAutomobile::SpawnFlyingComponent(int32 component, uint32 type)
{
@@ -4438,6 +5453,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);
@@ -4464,6 +5480,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;
@@ -4522,9 +5539,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)
@@ -4562,11 +5586,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);
}
@@ -4602,6 +5629,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;
@@ -4698,13 +5730,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_fAngle = -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_KO_SHOT_FRONT1;
+ if(ped == nil)
+ return;
+
+ ped->m_vehEnterType = door;
+ ped->SetPedState(PED_IDLE);
+ CAnimManager::BlendAnimation(ped->GetClump(), ped->m_animGroup, ANIM_IDLE_STANCE, 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 = NUM_STD_ANIMS;
+ break;
+
+ case WEAPONTYPE_BASEBALLBAT:
+ case WEAPONTYPE_RAMMEDBYCAR:
+ case WEAPONTYPE_FALL:
+ ped->m_vecMoveSpeed = m_vecMoveSpeed;
+ anim = ANIM_KD_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<CDamageManager>(buf, Damage);
- SkipSaveBuf(buf, 800 - sizeof(CDamageManager));
+ SkipSaveBuf(buf, 1500 - 672 - sizeof(CDamageManager));
}
void
@@ -4712,7 +5861,7 @@ CAutomobile::Load(uint8*& buf)
{
CVehicle::Load(buf);
Damage = ReadSaveBuf<CDamageManager>(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..06cca57e
--- /dev/null
+++ b/src/vehicles/Bike.cpp
@@ -0,0 +1,2949 @@
+#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"
+
+//--MIAMI: file done
+
+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;
+
+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_FWD);
+ 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_STILL);
+ 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){
+ if(m_wheelStatus[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;
+ }
+ }
+
+ 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());
+ }
+ }
+ }
+}
+
+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 = -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_LHS);
+ if(anim)
+ anim->blendDelta = -1000.0f;
+ anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_BIKE_DRIVEBY_FT);
+ 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 if(lookingRight){
+ anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_BIKE_DRIVEBY_RHS);
+ if(anim)
+ anim->blendDelta = -1000.0f;
+ anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_BIKE_DRIVEBY_FT);
+ 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{
+ 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_FT);
+ if(anim == nil || anim->blendDelta < 0.0f)
+ anim = CAnimManager::AddAnimation(pDriver->GetClump(), m_bikeAnimType, ANIM_BIKE_DRIVEBY_FT);
+ }
+
+ 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_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_FT);
+ 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)
+{
+ int 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_KO_SHOT_FRONT1;
+ 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_IDLE_STANCE, 100.0f);
+ ped->m_vehEnterType = 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 = NUM_STD_ANIMS;
+ break;
+
+ case WEAPONTYPE_BASEBALLBAT:
+ default:
+ switch(direction){
+ case 0:
+ anim = ANIM_BIKE_FALL_R;
+ 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_KO_SPIN_R;
+ ped->m_vecMoveSpeed = 0.3f*m_vecMoveSpeed;
+ ped->ApplyMoveForce(5.0f*GetUp() + 6.0f*GetRight());
+ }else{
+ anim = ANIM_KD_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_KO_SPIN_L;
+ ped->m_vecMoveSpeed = 0.3f*m_vecMoveSpeed;
+ ped->ApplyMoveForce(5.0f*GetUp() - 6.0f*GetRight());
+ }else{
+ anim = ANIM_KD_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_FALL_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_KO_SKID_BACK; break;
+ case 1: anim = ANIM_KD_RIGHT; break;
+ case 2: anim = ANIM_KO_SKID_FRONT; break;
+ case 3: anim = ANIM_KD_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_KO_SKID_BACK; break;
+ case 1: anim = ANIM_KD_RIGHT; break;
+ case 2: anim = ANIM_KO_SKID_FRONT; break;
+ case 3: anim = ANIM_KD_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_FALL_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);
+ SkipSaveBuf(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 4e7e5a0e..3fcf66a2 100644
--- a/src/vehicles/Bike.h
+++ b/src/vehicles/Bike.h
@@ -1,6 +1,7 @@
#pragma once
-// some miami bike leftovers
+#include "Vehicle.h"
+#include "Skidmarks.h"
enum eBikeNodes {
BIKE_NODE_NONE,
@@ -12,4 +13,159 @@ enum eBikeNodes {
BIKE_MUDGUARD,
BIKE_HANDLEBARS,
BIKE_NUM_NODES
-}; \ No newline at end of file
+};
+
+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];
+ 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];
+ float m_aSuspensionSpringRatioPrev[4];
+ float m_aWheelTimer[4];
+ float m_bike_unused1;
+ eSkidmarkType m_aWheelSkidmarkType[2];
+ bool m_aWheelSkidmarkBloody[2];
+ bool m_aWheelSkidmarkUnk[2];
+ float m_aWheelRotation[2];
+ float m_aWheelSpeed[2];
+ float m_aWheelPosition[2];
+ float m_aWheelBasePosition[2];
+ float m_aSuspensionSpringLength[4];
+ float m_aSuspensionLineLength[4];
+ float m_fHeightAboveRoad;
+ float m_fTraction;
+ 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 aba48bad..695d380f 100644
--- a/src/vehicles/Boat.cpp
+++ b/src/vehicles/Boat.cpp
@@ -1,8 +1,11 @@
-#include "common.h"
+#include "common.h"
+#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"
@@ -12,29 +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"
+
+//--MIAMI: file done
#define INVALID_ORIENTATION (-9999.99f)
float fShapeLength = 0.4f;
float fShapeTime = 0.05f;
-float fRangeMult = 0.75f; //0.6f; // 0.75f gta 3
+float fRangeMult = 0.6f;
float fTimeMult;
-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;
CBoat *CBoat::apFrameWakeGeneratingBoats[4];
const uint32 CBoat::nSaveStructSize =
#ifdef COMPATIBLE_SAVES
- 1156;
+ 1216;
#else
sizeof(CBoat);
#endif
@@ -48,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;
@@ -63,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;
@@ -79,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;
@@ -91,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();
}
@@ -109,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->m_nWantedLevel > 0 && GetModelIndex() == MI_PREDATOR){
+#else
+ if(FindPlayerPed()->m_pWanted->m_nWantedLevel > 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()){
@@ -151,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;
@@ -163,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:
@@ -174,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;
@@ -185,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();
@@ -237,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);
@@ -254,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;
@@ -315,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)
@@ -330,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;
-
- 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;
+ // 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, 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;
@@ -547,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);
@@ -557,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;
@@ -616,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;
@@ -656,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;
@@ -695,30 +926,193 @@ 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;
+ 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);
+#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 VC
+}
+
+void
+CBoat::RenderWaterOutPolys(void)
+{
+ if(GetModelIndex() == MI_SKIMMER)
+ return;
KeepWaterOutIndices[0] = 0;
KeepWaterOutIndices[1] = 2;
KeepWaterOutIndices[2] = 1;
@@ -730,6 +1124,18 @@ CBoat::Render()
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);
@@ -743,12 +1149,37 @@ CBoat::Render()
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;
@@ -758,19 +1189,51 @@ CBoat::Render()
KeepWaterOutVertices[2].v = 1.0f;
KeepWaterOutVertices[3].u = 1.0f;
KeepWaterOutVertices[3].v = 1.0f;
+#ifdef NEW_RENDERER
+ if(!gbNewRenderer)
+#endif
+{
RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpWaterRaster);
RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDZERO);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE);
+}
if (!CVehicle::bWheelsOnlyCheat && RwIm3DTransform(KeepWaterOutVertices, 4, GetMatrix().m_attachment, rwIM3D_VERTEXUV)) {
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
+{
RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)TRUE);
RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
}
+}
void
CBoat::Teleport(CVector v)
@@ -783,6 +1246,7 @@ CBoat::Teleport(CVector v)
CWorld::Add(this);
}
+//--MIAMI: unused
bool
CBoat::IsSectorAffectedByWake(CVector2D sector, float fSize, CBoat **apBoats)
{
@@ -814,6 +1278,7 @@ CBoat::IsSectorAffectedByWake(CVector2D sector, float fSize, CBoat **apBoats)
return numVerts != 0;
}
+//--MIAMI: unused
float
CBoat::IsVertexAffectedByWake(CVector vecVertex, CBoat *pBoat)
{
@@ -850,22 +1315,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;
@@ -897,35 +1375,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_DRIVEBY_R);
+ if(anim)
+ anim->blendDelta = -1000.0f;
+ anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_DRIVEBY_L);
+ if(anim == nil || anim->blendDelta < 0.0f)
+ anim = CAnimManager::AddAnimation(pDriver->GetClump(), ASSOCGRP_STD, ANIM_DRIVEBY_L);
+ }else if(pDriver->m_pMyVehicle->pPassengers[0] == nil || TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_1STPERSON){
+ anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_DRIVEBY_L);
+ if(anim)
+ anim->blendDelta = -1000.0f;
+ anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_DRIVEBY_R);
+ if(anim == nil || anim->blendDelta < 0.0f)
+ anim = CAnimManager::AddAnimation(pDriver->GetClump(), ASSOCGRP_STD, ANIM_DRIVEBY_R);
+ }
+
+ if (!anim || !anim->IsRunning()) {
+ if (CPad::GetPad(0)->GetCarGunFired() && CTimer::GetTimeInMilliseconds() > weapon->m_nTimer) {
+ weapon->FireFromCar(this, lookingLeft, true);
+ weapon->m_nTimer = CTimer::GetTimeInMilliseconds() + 70;
+ }
+ }
+ }else{
+ weapon->Reload();
+ anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_DRIVEBY_L);
+ if(anim)
+ anim->blendDelta = -1000.0f;
+ anim = RpAnimBlendClumpGetAssociation(pDriver->GetClump(), ANIM_DRIVEBY_R);
+ if(anim)
+ anim->blendDelta = -1000.0f;
+ }
+}
+
#ifdef COMPATIBLE_SAVES
void
CBoat::Save(uint8*& buf)
{
CVehicle::Save(buf);
- SkipSaveBuf(buf, 1156 - 648);
+ SkipSaveBuf(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 56aff264..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,22 +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];
@@ -71,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 7524444b..77d66cbf 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,12 @@
#include "Streaming.h"
#include "Timer.h"
#include "Vehicle.h"
+#include "VisibilityPlugins.h"
#include "World.h"
+#include "Zones.h"
+#include "Occlusion.h"
+
+// --MIAMI: file done
uint8 CTheCarGenerators::ProcessCounter;
uint32 CTheCarGenerators::NumOfCarGenerators;
@@ -45,42 +51,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{
@@ -94,33 +108,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;
@@ -137,7 +161,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;
@@ -152,6 +176,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)
@@ -171,25 +197,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;
@@ -198,7 +232,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;
}
@@ -217,8 +251,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()
@@ -250,6 +285,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 564f493d..8433a0ba 100644
--- a/src/vehicles/Cranes.cpp
+++ b/src/vehicles/Cranes.cpp
@@ -12,6 +12,8 @@
#include "Object.h"
#include "World.h"
+// --MIAMI: file done
+
#define MAX_DISTANCE_TO_FIND_CRANE (10.0f)
#define CRANE_UPDATE_RADIUS (300.0f)
#define CRANE_MOVEMENT_PROCESSING_RADIUS (150.0f)
@@ -52,16 +54,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);
}
}
@@ -83,23 +91,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, 1);
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++;
}
@@ -268,7 +261,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);
}
}
}
@@ -448,8 +440,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 &&
@@ -460,7 +450,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;
@@ -474,7 +464,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);
@@ -489,7 +479,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;
@@ -666,11 +656,6 @@ void CCranes::Load(uint8* buf, uint32 size)
if (pCrane->m_pVehiclePickedUp != nil)
pCrane->m_pVehiclePickedUp = CPools::GetVehiclePool()->GetSlot((uintptr)pCrane->m_pVehiclePickedUp - 1);
}
- 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, 1);
- }
VALIDATESAVEBUF(size);
}
diff --git a/src/vehicles/Cranes.h b/src/vehicles/Cranes.h
index 0e134310..162f9af9 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..92e3d80e 100644
--- a/src/vehicles/Floater.cpp
+++ b/src/vehicles/Floater.cpp
@@ -7,6 +7,8 @@
#include "Vehicle.h"
#include "Floater.h"
+//--MIAMI: done
+
cBuoyancy mod_Buoyancy;
float fVolMultiplier = 1.0f;
@@ -16,9 +18,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 +59,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 +140,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;
+ m_dimMax.z += 0.25f;
+ m_dimMin.z -= 0.2f;
+ break;
+ case MI_SQUALO:
m_dimMax.y *= 0.9f;
m_dimMin.y *= 0.9f;
- }else if(phys->GetModelIndex() == MI_SPEEDER){
+ 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 +222,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 +254,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 +294,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 18a2481e..f96835d3 100644
--- a/src/vehicles/HandlingMgr.cpp
+++ b/src/vehicles/HandlingMgr.cpp
@@ -4,6 +4,8 @@
#include "FileMgr.h"
#include "HandlingMgr.h"
+//--MIAMI: done
+
cHandlingDataMgr mod_HandlingManager;
const char *HandlingFilename = "HANDLING.CFG";
@@ -21,7 +23,6 @@ const char VehicleNames[NUMHANDLINGS][14] = {
"STRETCH",
"MANANA",
"INFERNUS",
- "BLISTA",
"PONY",
"MULE",
"CHEETAH",
@@ -38,7 +39,6 @@ const char VehicleNames[NUMHANDLINGS][14] = {
"ENFORCER",
"SECURICA",
"BANSHEE",
- "PREDATOR",
"BUS",
"RHINO",
"BARRACKS",
@@ -50,22 +50,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)
@@ -94,6 +145,9 @@ cHandlingDataMgr::LoadHandlingData(void)
int field, handlingId;
int keepGoing;
tHandlingData *handling;
+ tFlyingHandlingData *flyingHandling;
+ tBoatHandlingData *boatHandling;
+ tBikeHandlingData *bikeHandling;
CFileMgr::SetDir("DATA");
CFileMgr::LoadFile(HandlingFilename, work_buff, sizeof(work_buff), "r");
@@ -102,6 +156,9 @@ cHandlingDataMgr::LoadHandlingData(void)
start = (char*)work_buff;
end = start+1;
handling = nil;
+ flyingHandling = nil;
+ boatHandling = nil;
+ bikeHandling = nil;
keepGoing = 1;
while(keepGoing){
@@ -118,55 +175,157 @@ cHandlingDataMgr::LoadHandlingData(void)
if(strncmp(line, ";the end", 9) == 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.4f; break;
- case 15: handling->Transmission.nDriveType = word[0]; break;
- case 16: handling->Transmission.nEngineType = word[0]; break;
- case 17: handling->fBrakeDeceleration = strtod(word, nil); break;
- case 18: handling->fBrakeBias = strtod(word, nil); break;
- case 19: handling->bABS = !!atoi(word); break;
- case 20: handling->fSteeringLock = strtod(word, nil); break;
- case 21: handling->fSuspensionForceLevel = strtod(word, nil); break;
- case 22: handling->fSuspensionDampingLevel = strtod(word, nil); break;
- case 23: handling->fSeatOffsetDistance = strtod(word, nil); break;
- case 24: handling->fCollisionDamageMultiplier = strtod(word, nil); break;
- case 25: handling->nMonetaryValue = atoi(word); break;
- case 26: handling->fSuspensionUpperLimit = strtod(word, nil); break;
- case 27: handling->fSuspensionLowerLimit = strtod(word, nil); break;
- case 28: handling->fSuspensionBias = strtod(word, nil); break;
- case 29:
- 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.4f; break;
+ case 15: handling->Transmission.nDriveType = word[0]; break;
+ case 16: handling->Transmission.nEngineType = word[0]; break;
+ case 17: handling->fBrakeDeceleration = atof(word); break;
+ case 18: handling->fBrakeBias = atof(word); break;
+ case 19: handling->bABS = !!atoi(word); break;
+ case 20: handling->fSteeringLock = atof(word); break;
+ case 21: handling->fSuspensionForceLevel = atof(word); break;
+ case 22: handling->fSuspensionDampingLevel = atof(word); break;
+ case 23: handling->fSeatOffsetDistance = atof(word); break;
+ case 24: handling->fCollisionDamageMultiplier = atof(word); break;
+ case 25: handling->nMonetaryValue = atoi(word); break;
+ case 26: handling->fSuspensionUpperLimit = atof(word); break;
+ case 27: handling->fSuspensionLowerLimit = atof(word); break;
+ case 28: handling->fSuspensionBias = atof(word); break;
+ case 29: handling->fSuspensionAntidiveMultiplier = atof(word); break;
+ case 30:
+ sscanf(word, "%x", &handling->Flags);
+ handling->Transmission.Flags = handling->Flags;
+ break;
+ case 31: handling->FrontLights = atoi(word); break;
+ case 32: handling->RearLights = atoi(word); break;
+ }
+ field++;
+ }
+ ConvertDataToGameUnits(handling);
}
- ConvertDataToGameUnits(handling);
}
}
}
@@ -199,6 +358,7 @@ cHandlingDataMgr::ConvertDataToGameUnits(tHandlingData *handling)
if(handling->fTurnMass < 10.0f)
handling->fTurnMass *= 5.0f;
handling->fInvMass = 1.0f/handling->fMass;
+ handling->fCollisionDamageMultiplier *= 2000.0f/handling->fMass;
handling->fBuoyancy = 100.0f/handling->nPercentSubmerged * 0.008f*handling->fMass;
// What the hell is going on here?
@@ -214,11 +374,16 @@ cHandlingDataMgr::ConvertDataToGameUnits(tHandlingData *handling)
if(handling->nIdentifier == HANDLING_RCBANDIT){
handling->Transmission.fUnkMaxVelocity = handling->Transmission.fMaxVelocity;
+ handling->Transmission.fMaxReverseVelocity = -handling->Transmission.fMaxVelocity;
+ }else if(handling->nIdentifier >= HANDLING_BIKE && handling->nIdentifier <= HANDLING_FREEWAY){
+ handling->Transmission.fUnkMaxVelocity = velocity;
+ handling->Transmission.fMaxVelocity = velocity * 1.2f;
+ handling->Transmission.fMaxReverseVelocity = -0.05f;
}else{
handling->Transmission.fUnkMaxVelocity = velocity;
handling->Transmission.fMaxVelocity = velocity * 1.2f;
+ handling->Transmission.fMaxReverseVelocity = -0.2f;
}
- handling->Transmission.fMaxReverseVelocity = -0.2f;
if(handling->Transmission.nDriveType == '4')
handling->Transmission.fEngineAcceleration /= 4.0f;
@@ -228,6 +393,15 @@ cHandlingDataMgr::ConvertDataToGameUnits(tHandlingData *handling)
handling->Transmission.InitGearRatios();
}
+void
+cHandlingDataMgr::ConvertBikeDataToGameUnits(tBikeHandlingData *handling)
+{
+ handling->fMaxLean = Sin(DEGTORAD(handling->fMaxLean));
+ handling->fFullAnimLean = DEGTORAD(handling->fFullAnimLean);
+ handling->fWheelieAng = Sin(DEGTORAD(handling->fWheelieAng));
+ handling->fStoppieAng = Sin(DEGTORAD(handling->fStoppieAng));
+}
+
int32
cHandlingDataMgr::GetHandlingId(const char *name)
{
@@ -238,26 +412,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 23bd9681..038ff80c 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 == 'R'; }
bool HasFrontWheelDrive(tVehicleType id) { return HandlingData[id].Transmission.nDriveType == 'F'; }
};
-VALIDATE_SIZE(cHandlingDataMgr, 0x3030);
extern cHandlingDataMgr mod_HandlingManager;
diff --git a/src/vehicles/Heli.cpp b/src/vehicles/Heli.cpp
index 7008818b..644fdde8 100644
--- a/src/vehicles/Heli.cpp
+++ b/src/vehicles/Heli.cpp
@@ -14,20 +14,26 @@
#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"
#endif
+//--MIAMI: done
+
enum
{
HELI_STATUS_HOVER,
@@ -40,7 +46,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 +72,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 +90,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 +130,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 +278,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 +291,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 +361,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 +532,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 +555,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 +593,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 +662,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 +708,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_ABSEIL, 4.0f);
+ return true;
+ }
+ return false;
+}
void
@@ -772,16 +753,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 +768,8 @@ 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 +780,7 @@ 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 +821,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 +851,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 +871,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 +891,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 +909,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 +928,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 +1004,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 cf3f791f..1f372e42 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,12 +79,15 @@ public:
void PreRenderAlways(void);
CObject *SpawnFlyingComponent(int32 component);
+ CVector FindSwatPositionRelativeToHeli(int n);
+ bool SendDownSwat(void);
static void InitHelis(void);
static void UpdateHelis(void);
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);
static void RemoveCatalinaHeli(void);
@@ -95,6 +98,3 @@ public:
static void ActivateHeli(bool activate);
};
-
-VALIDATE_SIZE(CHeli, 0x33C);
-
diff --git a/src/vehicles/Plane.cpp b/src/vehicles/Plane.cpp
index 532be938..5b5536fd 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,11 +13,15 @@
#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"
+//--MIAMI: file done
+
CPlaneNode *pPathNodes;
CPlaneNode *pPath2Nodes;
CPlaneNode *pPath3Nodes;
@@ -40,12 +45,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 +66,6 @@ int32 DropOffCesnaMissionStatus;
int32 DropOffCesnaMissionStartTime;
CPlane *pDropOffCesna;
-
CPlane::CPlane(int32 id, uint8 CreatedBy)
: CVehicle(CreatedBy)
{
@@ -81,13 +83,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 +104,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 +143,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 +412,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 +425,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 +651,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 +698,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 +727,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 +736,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 +755,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 +778,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 +798,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 +829,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 +850,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 +896,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 +1004,7 @@ CPlane::TestRocketCollision(CVector *rocketPos)
return false;
}
+//--MIAMI: unused
// BUG: not in CPlane in the game
void
CPlane::CreateIncomingCesna(void)
@@ -946,6 +1028,7 @@ CPlane::CreateIncomingCesna(void)
printf("CPlane::CreateIncomingCesna(void)\n");
}
+//--MIAMI: unused
void
CPlane::CreateDropOffCesna(void)
{
@@ -968,8 +1051,21 @@ CPlane::CreateDropOffCesna(void)
printf("CPlane::CreateDropOffCesna(void)\n");
}
+//--MIAMI: 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 4250f6f4..1a4af307 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_vehEnterType;
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 5287055d..cc994ac6 100644
--- a/src/vehicles/Transmission.cpp
+++ b/src/vehicles/Transmission.cpp
@@ -4,6 +4,8 @@
#include "HandlingMgr.h"
#include "Transmission.h"
+//--MIAMI: done
+
void
cTransmission::InitGearRatios(void)
{
@@ -80,59 +82,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 = fEngineAcceleration*accelMul * (targetVelocity - fVelocity)/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 = fEngineAcceleration*accelMul * (targetVelocity - fVelocity)/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 9adcf148..56de3562 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,20 +16,38 @@
#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"
+
+//--MIAMI: done
bool CVehicle::bWheelsOnlyCheat;
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;
void *CVehicle::operator new(size_t sz) { return CPools::GetVehiclePool()->New(); }
void *CVehicle::operator new(size_t sz, int handle) { return CPools::GetVehiclePool()->New(handle); }
@@ -55,6 +75,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;
@@ -102,6 +123,26 @@ 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;
@@ -109,7 +150,26 @@ CVehicle::CVehicle(uint8 CreatedBy)
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() % USERTRACK;
+ 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() % USERTRACK;
+ break;
+ }
m_pCurGroundEntity = nil;
m_bRainAudioCounter = 0;
m_bRainSamplesCounter = 0;
@@ -121,6 +181,7 @@ CVehicle::CVehicle(uint8 CreatedBy)
AutoPilot.m_nTimeToStartMission = CTimer::GetTimeInMilliseconds();
AutoPilot.m_bStayInCurrentLevel = false;
AutoPilot.m_bIgnorePathfinding = false;
+ AutoPilot.m_nSwitchDistance = 20;
}
CVehicle::~CVehicle()
@@ -170,7 +231,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;
}
@@ -185,57 +246,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:
{
@@ -276,6 +310,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);
@@ -288,38 +324,65 @@ 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());
+ 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;
@@ -327,125 +390,145 @@ 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;
+ if(Abs(CPad::GetPad(0)->GetCarGunLeftRight()) > 1.0f)
+ fYaw = CPad::GetPad(0)->GetCarGunLeftRight() / 128.0f;
}
+ if(Abs(CPad::GetPad(0)->GetCarGunUpDown()) > 1.0f)
+ fPitch = -CPad::GetPad(0)->GetCarGunUpDown() / 128.0f;
if (CPad::GetPad(0)->GetHorn()) {
fYaw = 0.0f;
- fPitch = clamp(10.0f * DotProduct(m_vecMoveSpeed, 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;
@@ -457,8 +540,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,
@@ -530,7 +833,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 = 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;
@@ -570,23 +877,197 @@ 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);
}
}
+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
+ right *= CTimer::GetTimeStepFix();
+#endif
+
+ if(wheelStatus == WHEEL_STATUS_BURST){
+ float fwdspeed = Min(contactSpeedFwd, fBurstBikeSpeedMax);
+ right += fwdspeed * CGeneral::GetRandomNumberInRange(-fBurstBikeTyreMod, fBurstBikeTyreMod);
+ }
+ }
+
+ if(bDriving){
+ fwd = thrust;
+
+ // limit sideways force (why?)
+ if(right > 0.0f){
+ if(right > adhesion)
+ right = adhesion;
+ }else{
+ if(right < -adhesion)
+ right = -adhesion;
+ }
+ }else if(contactSpeedFwd != 0.0f){
+ fwd = -contactSpeedFwd/wheelsOnGround;
+#ifdef FIX_BUGS
+ // contactSpeedFwd is independent of framerate but fwd has timestep as a factor
+ // so we probably have to fix this
+ fwd *= CTimer::GetTimeStepFix();
+#endif
+
+ if(!bBraking){
+ if(m_fGasPedal < 0.01f){
+ if(IsBike())
+ brake = 0.6f * mod_HandlingManager.fWheelFriction / (pHandling->fMass + 200.0f);
+ else if(pHandling->fMass < 500.0f)
+ brake = mod_HandlingManager.fWheelFriction / m_fMass;
+ else if(GetModelIndex() == MI_RCBANDIT)
+ brake = 0.2f * mod_HandlingManager.fWheelFriction / m_fMass;
+ else
+ brake = mod_HandlingManager.fWheelFriction / m_fMass;
+#ifdef FIX_BUGS
+ brake *= CTimer::GetTimeStepFix();
+#endif
+ }
+ }
+
+ if(brake > adhesion){
+ if(Abs(contactSpeedFwd) > 0.005f)
+ *wheelState = WHEEL_STATE_FIXED;
+ }else {
+ if(fwd > 0.0f){
+ if(fwd > brake)
+ fwd = brake;
+ }else{
+ if(fwd < -brake)
+ fwd = -brake;
+ }
+ }
+ }
+
+ float speedSq = sq(right) + sq(fwd);
+ if(sq(adhesion) < speedSq){
+ if(*wheelState != WHEEL_STATE_FIXED){
+ if(bDriving && contactSpeedFwd < 0.2f)
+ *wheelState = WHEEL_STATE_SPINNING;
+ else
+ *wheelState = WHEEL_STATE_SKIDDING;
+ }
+
+ float l = Sqrt(speedSq);
+ float tractionLoss = bAlreadySkidding ? 1.0f : pHandling->fTractionLoss;
+ right *= adhesion * tractionLoss / l;
+ fwd *= adhesion * tractionLoss / l;
+
+ if(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
@@ -607,35 +1088,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;
@@ -652,6 +1179,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) &&
@@ -664,24 +1237,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;
@@ -723,56 +1313,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()){
@@ -843,6 +1475,69 @@ 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->m_nWantedLevel > 0 &&
+ ped2->m_pedInObjective == ped1){
+ player = (CPlayerPed*)ped1;
+ cop = (CCopPed*)ped2;
+ return;
+ }
+
+ bool ped1IsDriver = ped1 == pDriver;
+
+ // Just what the hell is this weird code?
+ CPed *peds[9];
+ CPed *peds2[9];
+ int numPeds = 0;
+ int numPeds2 = 0;
+ for(i = 0; i < m_nNumMaxPassengers; i++){
+ CPed *p = pPassengers[i];
+ if(p && p != ped1 && !p->bStayInCarOnJack){
+ peds[numPeds++] = p;
+ // uhh what?
+ if(i < 1 && !ped1IsDriver)
+ continue;
+ peds2[numPeds2++] = p;
+ }
+ }
+
+ // So we're copying this array for no reason...
+ CPed *peds3[9];
+ int numPeds3 = 0;
+ for(i = 0; i < numPeds; i++){
+ if(peds[i]->IsPlayer() && ped2->m_nPedType == PEDTYPE_COP &&
+ ((CPlayerPed*)peds[i])->m_pWanted->m_nWantedLevel > 0 &&
+ ped2->m_pedInObjective == peds[i]){
+ player = (CPlayerPed*)peds[i];
+ cop = (CCopPed*)ped2;
+ return;
+ }
+ peds3[numPeds3++] = peds[i];
+ }
+
+ int time = 1800;
+ for(i = 0; i < numPeds3; i++){
+ peds3[i]->m_leaveCarTimer = CTimer::GetTimeInMilliseconds() + time;
+ peds3[i]->SetObjective(OBJECTIVE_LEAVE_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,8 +1556,6 @@ CVehicle::ProcessDelayedExplosion(void)
if (m_nBombTimer != 0)
return;
- if(FindPlayerVehicle() != this && m_pBlowUpEntity == FindPlayerPed())
- CWorld::Players[CWorld::PlayerInFocus].AwardMoneyForExplosion(this);
BlowUpCar(m_pBlowUpEntity);
}
@@ -870,12 +1563,13 @@ bool
CVehicle::IsLawEnforcementVehicle(void)
{
switch(GetModelIndex()){
- case MI_FBICAR:
case MI_POLICE:
case MI_ENFORCER:
case MI_PREDATOR:
case MI_RHINO:
case MI_BARRACKS:
+ case MI_FBIRANCH:
+ case MI_VICECHEE:
return true;
default:
return false;
@@ -883,9 +1577,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:
@@ -893,6 +1587,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;
@@ -904,24 +1600,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
@@ -929,9 +1608,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
@@ -998,7 +1676,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_SKIP_SHUT_DOORS)
return false;
if(ped->IsPlayer() && m_nDoorLock == CARLOCK_LOCKOUT_PLAYER_ONLY)
return false;
@@ -1006,10 +1685,18 @@ CVehicle::CanPedOpenLocks(CPed *ped)
}
bool
+CVehicle::CanDoorsBeDamaged(void)
+{
+ return m_nDoorLock == CARLOCK_NOT_USED ||
+ m_nDoorLock == CARLOCK_UNLOCKED ||
+ m_nDoorLock == CARLOCK_SKIP_SHUT_DOORS;
+}
+
+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;
@@ -1021,16 +1708,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 ||
@@ -1053,6 +1738,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)
{
@@ -1077,7 +1779,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;
@@ -1090,15 +1792,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];
@@ -1111,23 +1829,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
@@ -1135,10 +1872,13 @@ CVehicle::AddPassenger(CPed *passenger)
{
int i;
- ApplyTurnForce(0.0f, 0.0f, -0.2f*passenger->m_fMass,
- passenger->GetPosition().x - GetPosition().x,
- passenger->GetPosition().y - GetPosition().y,
- 0.0f);
+ if(IsBike())
+ ApplyTurnForce(-0.2f*passenger->m_fMass * GetUp(), -0.1f*GetForward());
+ else
+ ApplyTurnForce(0.0f, 0.0f, -0.2f*passenger->m_fMass,
+ passenger->GetPosition().x - GetPosition().x,
+ passenger->GetPosition().y - GetPosition().y,
+ 0.0f);
for(i = 0; i < m_nNumMaxPassengers; i++)
if(pPassengers[i] == nil){
@@ -1155,10 +1895,13 @@ CVehicle::AddPassenger(CPed *passenger, uint8 n)
if(bIsBus)
return AddPassenger(passenger);
- ApplyTurnForce(0.0f, 0.0f, -0.2f*passenger->m_fMass,
- passenger->GetPosition().x - GetPosition().x,
- passenger->GetPosition().y - GetPosition().y,
- 0.0f);
+ if(IsBike())
+ ApplyTurnForce(-0.2f*passenger->m_fMass * GetUp(), -0.1f*GetForward());
+ else
+ ApplyTurnForce(0.0f, 0.0f, -0.2f*passenger->m_fMass,
+ passenger->GetPosition().x - GetPosition().x,
+ passenger->GetPosition().y - GetPosition().y,
+ 0.0f);
if(n < m_nNumMaxPassengers && pPassengers[n] == nil){
pPassengers[n] = passenger;
@@ -1172,6 +1915,22 @@ void
CVehicle::RemoveDriver(void)
{
SetStatus(STATUS_ABANDONED);
+ if(pDriver == FindPlayerPed()){
+ if(GetModelIndex() == MI_POLICE && CStreaming::HasModelLoaded(MI_SHOTGUN)){
+ if(bFreebies){
+ if(((CPlayerPed*)pDriver)->DoesPlayerWantNewWeapon(WEAPONTYPE_SHOTGUN, true))
+ pDriver->GiveWeapon(WEAPONTYPE_SHOTGUN, 5, true);
+ else
+ pDriver->GrantAmmo(WEAPONTYPE_SHOTGUN, 5);
+ bFreebies = false;
+ }
+ CStreaming::SetModelIsDeletable(MI_SHOTGUN);
+ }else if(GetModelIndex() == MI_CADDY && CStreaming::HasModelLoaded(MI_GOLFCLUB)){
+ if(((CPlayerPed*)pDriver)->DoesPlayerWantNewWeapon(WEAPONTYPE_GOLFCLUB, true))
+ pDriver->GiveWeapon(WEAPONTYPE_GOLFCLUB, 1, true);
+ CStreaming::SetModelIsDeletable(MI_GOLFCLUB);
+ }
+ }
pDriver = nil;
}
@@ -1197,6 +1956,57 @@ CVehicle::RemovePassenger(CPed *p)
}
}
+bool
+CVehicle::IsDriver(CPed *ped)
+{
+ if(ped == nil)
+ return false;
+ return ped == pDriver;
+}
+
+bool
+CVehicle::IsDriver(int32 model)
+{
+ return pDriver && pDriver->GetModelIndex() == model;
+}
+
+bool
+CVehicle::IsPassenger(CPed *ped)
+{
+ int i;
+ if(ped == nil)
+ return false;
+ for(i = 0; i < 8; i++)
+ if(pPassengers[i] == ped)
+ return true;
+ return false;
+}
+
+bool
+CVehicle::IsPassenger(int32 model)
+{
+ int i;
+ for(i = 0; i < 8; i++)
+ if(pPassengers[i] && pPassengers[i]->GetModelIndex() == model)
+ return true;
+ return false;
+}
+
+void
+CVehicle::UpdatePassengerList(void)
+{
+ int i;
+ bool hasPassenger = false;
+ if(m_nNumPassengers)
+ for(i = 0; i < 8; i++)
+ if(pPassengers[i]){
+ hasPassenger = true;
+ break;
+ }
+ if(!hasPassenger)
+ m_nNumPassengers = 0;
+}
+
void
CVehicle::ProcessCarAlarm(void)
{
@@ -1206,9 +2016,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;
}
@@ -1236,6 +2047,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)
{
@@ -1275,15 +2367,15 @@ CVehicle::Save(uint8*& buf)
WriteSaveBuf<float>(buf, GetPosition().z);
SkipSaveBuf(buf, 16);
SaveEntityFlags(buf);
- SkipSaveBuf(buf, 212);
+ SkipSaveBuf(buf, 208);
AutoPilot.Save(buf);
WriteSaveBuf<int8>(buf, m_currentColour1);
WriteSaveBuf<int8>(buf, m_currentColour2);
SkipSaveBuf(buf, 2);
WriteSaveBuf<int16>(buf, m_nAlarmState);
- SkipSaveBuf(buf, 43);
+ SkipSaveBuf(buf, 42);
WriteSaveBuf<uint8>(buf, m_nNumMaxPassengers);
- SkipSaveBuf(buf, 2);
+ SkipSaveBuf(buf, 3);
WriteSaveBuf<float>(buf, field_1D0[0]);
WriteSaveBuf<float>(buf, field_1D0[1]);
WriteSaveBuf<float>(buf, field_1D0[2]);
@@ -1306,13 +2398,13 @@ CVehicle::Save(uint8*& buf)
WriteSaveBuf<uint8>(buf, m_nCurrentGear);
SkipSaveBuf(buf, 3);
WriteSaveBuf<float>(buf, m_fChangeGearTime);
- SkipSaveBuf(buf, 4);
+ SkipSaveBuf(buf, 12);
WriteSaveBuf<uint32>(buf, m_nTimeOfDeath);
SkipSaveBuf(buf, 2);
WriteSaveBuf<int16>(buf, m_nBombTimer);
SkipSaveBuf(buf, 12);
WriteSaveBuf<int8>(buf, m_nDoorLock);
- SkipSaveBuf(buf, 99);
+ SkipSaveBuf(buf, 111);
}
void
@@ -1338,15 +2430,15 @@ CVehicle::Load(uint8*& buf)
m_matrix = tmp;
SkipSaveBuf(buf, 16);
LoadEntityFlags(buf);
- SkipSaveBuf(buf, 212);
+ SkipSaveBuf(buf, 208);
AutoPilot.Load(buf);
m_currentColour1 = ReadSaveBuf<int8>(buf);
m_currentColour2 = ReadSaveBuf<int8>(buf);
SkipSaveBuf(buf, 2);
m_nAlarmState = ReadSaveBuf<int16>(buf);
- SkipSaveBuf(buf, 43);
+ SkipSaveBuf(buf, 42);
m_nNumMaxPassengers = ReadSaveBuf<int8>(buf);
- SkipSaveBuf(buf, 2);
+ SkipSaveBuf(buf, 3);
field_1D0[0] = ReadSaveBuf<float>(buf);
field_1D0[1] = ReadSaveBuf<float>(buf);
field_1D0[2] = ReadSaveBuf<float>(buf);
@@ -1368,12 +2460,44 @@ CVehicle::Load(uint8*& buf)
m_nCurrentGear = ReadSaveBuf<uint8>(buf);
SkipSaveBuf(buf, 3);
m_fChangeGearTime = ReadSaveBuf<float>(buf);
- SkipSaveBuf(buf, 4);
+ SkipSaveBuf(buf, 12);
m_nTimeOfDeath = ReadSaveBuf<uint32>(buf);
SkipSaveBuf(buf, 2);
m_nBombTimer = ReadSaveBuf<int16>(buf);
SkipSaveBuf(buf, 12);
m_nDoorLock = (eCarLock)ReadSaveBuf<int8>(buf);
- SkipSaveBuf(buf, 99);
+ SkipSaveBuf(buf, 111);
}
#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 7066a0ea..a42106cc 100644
--- a/src/vehicles/Vehicle.h
+++ b/src/vehicles/Vehicle.h
@@ -5,8 +5,11 @@
#include "ModelIndices.h"
#include "AnimManager.h"
#include "Weapon.h"
+#include "HandlingMgr.h"
class CPed;
+class CPlayerPed;
+class CCopPed;
class CFire;
struct tHandlingData;
@@ -17,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,
@@ -28,6 +63,16 @@ enum eCarLock {
CARLOCK_SKIP_SHUT_DOORS
};
+enum eBombType
+{
+ CARBOMB_NONE,
+ CARBOMB_TIMED,
+ CARBOMB_ONIGNITION,
+ CARBOMB_REMOTE,
+ CARBOMB_TIMEDACTIVE,
+ CARBOMB_ONIGNITIONACTIVE,
+};
+
enum eDoors
{
DOOR_BONNET = 0,
@@ -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,16 +265,18 @@ public:
float m_fMapObjectHeightBehind; // rear Z?
eCarLock m_nDoorLock;
int8 m_nLastWeaponDamage; // see eWeaponType, -1 if no damage
+ CEntity *m_pLastDamageEntity;
int8 m_nRadioStation;
uint8 m_bRainAudioCounter;
uint8 m_bRainSamplesCounter;
- uint8 m_nCarHornTimer;
- uint8 m_nCarHornPattern; // last horn?
+ uint32 m_nCarHornTimer;
+ uint8 m_nCarHornPattern;
bool m_bSirenOrAlarm;
+ uint8 m_nCarHornDelay;
int8 m_comedyControlState;
CStoredCollPoly m_aCollPolys[2]; // poly which is under front/rear part of car
float m_fSteerInput;
- eVehicleType m_vehType;
+ uint8 m_vehType;
static void *operator new(size_t);
static void *operator new(size_t sz, int slot);
@@ -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,89 @@ 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_CAR_LSIT : (IsBoat() && GetModelIndex() != MI_SPEEDER ? ANIM_DRIVE_BOAT : ANIM_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;
};
-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 e87a7407..13032300 100644
--- a/src/weapons/BulletInfo.cpp
+++ b/src/weapons/BulletInfo.cpp
@@ -23,6 +23,9 @@
#include "WeaponInfo.h"
#include "World.h"
#include "SurfaceTable.h"
+#include "Heli.h"
+
+// --MIAMI: file done
#ifdef SQUEEZE_PERFORMANCE
uint32 bulletInfoInUse;
@@ -32,9 +35,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 +99,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 +114,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_SHOT_FRONT_PARTIAL);
- 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_SHOT_FRONT_PARTIAL);
+ 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 +171,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 +197,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 +229,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 +286,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 d0a68279..38ce6e53 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,15 @@ CExplosion::GetExplosionPosition(uint8 id)
}
bool
-CExplosion::AddExplosion(CEntity *explodingEntity, CEntity *culprit, eExplosionType type, const CVector &pos, uint32 lifetime)
+CExplosion::AddExplosion(CEntity *explodingEntity, CEntity *culprit, eExplosionType type, const CVector &pos, uint32 lifetime, bool makeSound)
{
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
@@ -123,6 +140,7 @@ 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)
{
@@ -134,8 +152,12 @@ CExplosion::AddExplosion(CEntity *explodingEntity, CEntity *culprit, eExplosionT
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:
{
@@ -145,18 +167,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:
@@ -170,6 +191,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;
@@ -179,59 +201,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);
}
@@ -254,13 +288,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;
@@ -292,7 +323,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;
@@ -301,8 +336,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;
}
@@ -328,6 +367,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) {
@@ -346,8 +386,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++) {
@@ -356,8 +398,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));
}
@@ -365,9 +405,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;
@@ -378,16 +419,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) {
@@ -414,13 +453,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..7aa02b63 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,25 @@ 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);
+ static bool AddExplosion(CEntity *explodingEntity, CEntity *culprit, eExplosionType type, const CVector &pos, uint32 lifetime, bool makeSound = true); //done(new parametr in android ver is fix for one mission)
+ 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 b56e3a29..754da5f7 100644
--- a/src/weapons/ProjectileInfo.cpp
+++ b/src/weapons/ProjectileInfo.cpp
@@ -17,9 +17,16 @@
uint32 projectileInUse;
#endif
+// --MIAMI: file done except TODOs
+
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 +73,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;
@@ -135,18 +166,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)
@@ -170,13 +203,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
@@ -189,18 +237,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;
}
}
@@ -212,6 +259,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;
@@ -227,21 +276,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];
@@ -250,15 +324,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();
@@ -271,7 +355,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;
@@ -292,6 +376,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 c0ab9ac1..ae7b9d2d 100644
--- a/src/weapons/ShotInfo.cpp
+++ b/src/weapons/ShotInfo.cpp
@@ -10,6 +10,8 @@
#include "Ped.h"
#include "Fire.h"
+// --MIAMI: file done
+
CShotInfo gaShotInfo[NUMSHOTINFOS];
float CShotInfo::ms_afRandTable[20];
@@ -146,4 +148,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 a987a4c7..2435d544 100644
--- a/src/weapons/Weapon.cpp
+++ b/src/weapons/Weapon.cpp
@@ -30,24 +30,19 @@
#include "WaterLevel.h"
#include "WeaponInfo.h"
#include "World.h"
+#include "SurfaceTable.h"
+#include "Bike.h"
+#include "Glass.h"
+#include "Sprite.h"
+#include "Pickups.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;
CWeaponInfo *
CWeapon::GetInfo()
@@ -57,6 +52,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)
{
@@ -65,6 +71,7 @@ CWeapon::InitialiseWeapons(void)
CExplosion::Initialise();
CProjectileInfo::Initialise();
CBulletInfo::Initialise();
+ bPhotographHasBeenTaken = false;
}
void
@@ -86,18 +93,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
@@ -107,19 +137,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());
@@ -132,44 +161,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;
}
@@ -192,12 +237,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 )
{
@@ -209,6 +254,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;
}
@@ -228,16 +278,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;
}
@@ -256,17 +300,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);
@@ -275,8 +367,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;
@@ -290,9 +386,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
@@ -301,9 +398,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 )
@@ -313,7 +415,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);
@@ -323,12 +425,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;
@@ -344,8 +449,6 @@ CWeapon::FireFromCar(CAutomobile *shooter, bool left)
}
m_nTimer = CTimer::GetTimeInMilliseconds() + 1000;
- if ( shooter == FindPlayerVehicle() )
- CStats::RoundsFiredByPlayer++;
}
return true;
@@ -359,27 +462,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->m_bFightMode))
+ continue;
float victimPedRadius = victimPed->GetBoundRadius() + info->m_fRadius;
if ( victimPed->bUsesCollision || victimPed->Dead() || victimPed->Driving() )
@@ -388,12 +509,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() )
{
@@ -414,65 +551,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_KO_SKID_FRONT + localDir), false);
else
victimPed->SetFall(1500, AnimationId(ANIM_KO_SKID_FRONT + localDir), false);
@@ -485,21 +684,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;
}
@@ -541,9 +870,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() )
{
@@ -554,19 +880,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;
+ CWorld::ProcessLineOfSight(*fireSource, target, point, victim, true, true, true, true, true, false, false, true);
CWorld::bIncludeDeadPeds = false;
+ CWorld::bIncludeBikers = false;
}
else
{
@@ -576,24 +923,32 @@ 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;
+ CWorld::ProcessLineOfSight(*fireSource, target, point, victim, true, true, true, true, true, false, false, true);
+ CWorld::bIncludeBikers = false;
}
}
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);
+ CWorld::bIncludeBikers = true;
CWorld::bIncludeDeadPeds = true;
- ProcessLineOfSight(src, trgt,point, victim, m_eWeaponType, shooter, true, true, true, true, true, true, false);
+ CWorld::bIncludeCarTyres = true;
+ CWorld::ProcessLineOfSight(source, target, point, victim, true, true, true, true, true, false, false, true);
+ 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);
@@ -601,140 +956,113 @@ 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;
+ CWorld::ProcessLineOfSight(*fireSource, target, point, victim, true, true, true, true, true, false, false, true);
+ 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->m_bCanAim))
+ {
+ CWeapon::DoDoomAiming(shooter, fireSource, &target);
+ }
+
+ CWorld::bIncludeBikers = true;
+ CWorld::ProcessLineOfSight(*fireSource, target, point, victim, true, true, true, true, true, false, false, true);
+ 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));
+ AddGunFlashBigGuns(*fireSource, *fireSource + target);
CVector gunshellPos = *fireSource;
gunshellPos -= CVector(0.65f*ahead.x, 0.65f*ahead.y, 0.0f);
@@ -747,6 +1075,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,
@@ -785,6 +1116,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,
@@ -823,6 +1157,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);
@@ -851,6 +1250,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)
@@ -864,72 +1264,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_KO_SKID_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 )
- {
- posOffset.Normalise();
- victimPed->bIsStanding = false;
-
- victimPed->ApplyMoveForce(posOffset.x*-5.0f, posOffset.y*-5.0f, 5.0f);
- victimPed->SetFall(1500, AnimationId(ANIM_KO_SKID_FRONT + localDir), false);
-
- victimPed->InflictDamage(shooter, m_eWeaponType, info->m_nDamage, (ePedPieceTypes)point->pieceB, localDir);
- }
- else
+ if ( victimPed->IsPlayer() )
{
- 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_SHOT_FRONT_PARTIAL + 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();
@@ -938,31 +1365,53 @@ CWeapon::DoBulletImpact(CEntity *shooter, CEntity *victim,
asoc->blendAmount = 0.0f;
asoc->blendDelta = 8.0f;
+
+ if ( m_eWeaponType == WEAPONTYPE_M4 )
+ victimPlayer->m_nHitAnimDelayTimer = CTimer::GetTimeInMilliseconds() + 2500;
+ else
+ victimPlayer->m_nHitAnimDelayTimer = CTimer::GetTimeInMilliseconds() + 1000;
}
+ }
+ else
+ {
+ victimPed->ClearAttackByRemovingAnim();
+
+ CAnimBlendAssociation *asoc = CAnimManager::AddAnimation(victimPed->GetClump(), ASSOCGRP_STD, AnimationId(ANIM_SHOT_FRONT_PARTIAL + localDir));
+ ASSERT(asoc!=nil);
- victimPed->InflictDamage(shooter, m_eWeaponType, info->m_nDamage, (ePedPieceTypes)point->pieceB, localDir);
+ asoc->blendAmount = 0.0f;
+ asoc->blendDelta = 8.0f;
}
+
+ victimPed->InflictDamage(shooter, m_eWeaponType, info->m_nDamage, (ePedPieceTypes)point->pieceB, localDir);
}
+ }
- if ( victimPed->m_nPedType == PEDTYPE_COP )
- CEventList::RegisterEvent(EVENT_SHOOT_COP, EVENT_ENTITY_PED, victim, (CPed*)shooter, 10000);
- else
- CEventList::RegisterEvent(EVENT_SHOOT_PED, EVENT_ENTITY_PED, victim, (CPed*)shooter, 10000);
+ if ( victimPed->m_nPedType == PEDTYPE_COP )
+ CEventList::RegisterEvent(EVENT_SHOOT_COP, EVENT_ENTITY_PED, victim, (CPed*)shooter, 10000);
+ else
+ CEventList::RegisterEvent(EVENT_SHOOT_PED, EVENT_ENTITY_PED, victim, (CPed*)shooter, 10000);
- if ( CGame::nastyGame )
- {
- uint8 bloodAmount = 8;
- if ( m_eWeaponType == WEAPONTYPE_SHOTGUN || m_eWeaponType == WEAPONTYPE_HELICANNON )
- bloodAmount = 32;
+ if ( CGame::nastyGame )
+ {
+ uint8 bloodAmount = 8;
+ if ( IsShotgun(m_eWeaponType) || m_eWeaponType == WEAPONTYPE_HELICANNON )
+ bloodAmount = 32;
- CVector dir = (point->point - victim->GetPosition()) * 0.01f;
- dir.z = 0.01f;
+ CVector dir = (point->point - victim->GetPosition()) * 0.01f;
+ dir.z = 0.01f;
- if ( victimPed->GetIsOnScreen() )
- {
- for ( uint8 i = 0; i < bloodAmount; i++ )
- CParticle::AddParticle(PARTICLE_BLOOD_SMALL, point->point, dir);
- }
+ if ( victimPed->GetIsOnScreen() )
+ {
+ for ( uint8 i = 0; i < bloodAmount; i++ )
+ CParticle::AddParticle(PARTICLE_BLOOD_SMALL, point->point, dir);
+ }
+
+ if (m_eWeaponType == WEAPONTYPE_MINIGUN)
+ {
+ CParticle::AddParticle(PARTICLE_TEST, point->point, CVector(0.f, 0.f, 0.f), nil, 0.f, 0, 0, 0, 0);
+ CParticle::AddParticle(PARTICLE_TEST, point->point + CVector(0.2f, -0.2f, 0.f), CVector(0.f, 0.f, 0.f), nil, 0.f, 0, 0, 0, 0);
+ CParticle::AddParticle(PARTICLE_TEST, point->point + CVector(-0.2f, 0.2f, 0.f), CVector(0.f, 0.f, 0.f), nil, 0.f, 0, 0, 0, 0);
}
}
}
@@ -1007,9 +1456,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
@@ -1024,20 +1473,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() )
{
@@ -1062,19 +1521,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;
@@ -1092,17 +1555,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;
}
@@ -1115,7 +1581,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);
@@ -1123,6 +1589,7 @@ CWeapon::DoBulletImpact(CEntity *shooter, CEntity *victim,
BlowUpExplosiveThings(victim);
}
+
bool
CWeapon::FireShotgun(CEntity *shooter, CVector *fireSource)
{
@@ -1168,10 +1635,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();
@@ -1184,12 +1676,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;
+ CWorld::ProcessLineOfSight(source, target, point, victim, true, true, true, true, true, false, false, true);
+ CWorld::bIncludeDeadPeds = false;
+ CWorld::bIncludeCarTyres = false;
}
else
{
@@ -1205,24 +1701,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;
+ CWorld::ProcessLineOfSight(*fireSource, target, point, victim, true, true, true, true, true, false, false, true);
+ 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;
@@ -1235,7 +1791,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 )
@@ -1260,7 +1817,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;
@@ -1272,6 +1829,36 @@ CWeapon::FireShotgun(CEntity *shooter, CVector *fireSource)
CParticle::AddParticle(PARTICLE_BLOOD_SMALL, point.point, dir);
}
}
+ } else {
+ if (CGame::nastyGame)
+ {
+ CVector dir = (point.point - victim->GetPosition()) * 0.01f;
+ dir.z = 0.01f;
+
+ if (victimPed->GetIsOnScreen())
+ {
+ for (uint8 i = 0; i < 8; i++)
+ CParticle::AddParticle(PARTICLE_BLOOD_SMALL, point.point + CVector(0.0f, 0.0f, 0.15f), dir);
+ }
+ if (victimPed->Dead())
+ {
+ CAnimBlendAssociation *hitAssoc;
+ if (RpAnimBlendClumpGetFirstAssociation(victimPed->GetClump(), ASSOC_FRONTAL))
+ {
+ hitAssoc = CAnimManager::BlendAnimation(victimPed->GetClump(), ASSOCGRP_STD, ANIM_FLOOR_HIT_F, 8.0f);
+ }
+ else
+ {
+ hitAssoc = CAnimManager::BlendAnimation(victimPed->GetClump(), ASSOCGRP_STD, ANIM_FLOOR_HIT, 8.0f);
+ }
+ if (hitAssoc)
+ {
+ hitAssoc->SetCurrentTime(0.0f);
+ hitAssoc->SetRun();
+ hitAssoc->flags &= ~ASSOC_DELETEFADEDOUT;
+ }
+ }
+ }
}
}
else
@@ -1280,21 +1867,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;
}
@@ -1324,13 +1919,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);
@@ -1353,17 +1950,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;
}
@@ -1379,7 +1988,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);
}
}
@@ -1396,10 +2005,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() )
{
@@ -1441,7 +2052,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() )
@@ -1450,14 +2061,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;
}
@@ -1510,24 +2129,76 @@ 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;
+ }
}
#ifndef FIX_BUGS
@@ -1541,7 +2212,7 @@ 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;
@@ -1549,22 +2220,80 @@ CWeapon::FireSniper(CEntity *shooter)
CBulletInfo::AddBullet(shooter, m_eWeaponType, source, dir);
if ( shooter == FindPlayerPed() )
- CStats::InstantHitsFiredByPlayer++;
-
- if ( shooter == FindPlayerPed() )
{
CPad::GetPad(0)->StartShake_Distance(240, 128,
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);
@@ -1573,6 +2302,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
@@ -1584,10 +2314,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;
@@ -1597,9 +2329,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 (CWorld::ProcessLineOfSight(source, target, point, victim, true, true, true, true, true, false, false, true)) {
+ 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);
@@ -1608,7 +2343,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));
@@ -1616,77 +2352,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);
@@ -1695,7 +2491,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);
@@ -1703,7 +2504,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() )
{
@@ -1790,7 +2591,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() )
@@ -1811,8 +2612,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];
@@ -1831,7 +2630,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);
@@ -1850,7 +2650,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);
@@ -1939,10 +2742,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);
@@ -1950,27 +2754,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)
{
@@ -1979,14 +2792,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;
}
}
@@ -2006,8 +2829,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:
@@ -2018,18 +2843,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;
}
@@ -2038,11 +2864,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 )
@@ -2129,17 +2993,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;
}
@@ -2165,13 +3032,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
@@ -2252,14 +3121,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;
@@ -2278,19 +3147,26 @@ 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;
}
+// --MIAMI: Done
bool
CPed::IsPedDoingDriveByShooting(void)
{
+#ifdef FIX_BUGS
+ if (FindPlayerPed() == this && CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_nWeaponSlot == 5) {
+#else
if (FindPlayerPed() == this && GetWeapon()->m_eWeaponType == WEAPONTYPE_UZI) {
+#endif
if (TheCamera.Cams[TheCamera.ActiveCam].LookingLeft || TheCamera.Cams[TheCamera.ActiveCam].LookingRight)
return true;
}
@@ -2303,6 +3179,81 @@ CWeapon::ProcessLineOfSight(CVector const &point1, CVector const &point2, CColPo
return CWorld::ProcessLineOfSight(point1, point2, point, entity, checkBuildings, checkVehicles, checkPeds, checkObjects, checkDummies, ignoreSeeThrough, ignoreSomeObjects);
}
+
+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
#define CopyFromBuf(buf, data) memcpy(&data, buf, sizeof(data)); SkipSaveBuf(buf, sizeof(data));
#define CopyToBuf(buf, data) memcpy(buf, &data, sizeof(data)); SkipSaveBuf(buf, sizeof(data));
diff --git a/src/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 214ae9c7..b0df610f 100644
--- a/src/weapons/WeaponEffects.cpp
+++ b/src/weapons/WeaponEffects.cpp
@@ -3,9 +3,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;
@@ -24,10 +26,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;
@@ -36,8 +38,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();
}
@@ -46,9 +47,7 @@ void
CWeaponEffects::Shutdown(void)
{
RwTextureDestroy(gpCrossHairTex);
-#if GTA_VERSION >= GTA3_PC_11
gpCrossHairTex = nil;
-#endif
}
void
@@ -56,10 +55,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;
}
@@ -72,28 +67,62 @@ 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;
if ( CSprite::CalcScreenCoors(gCrossHair.m_vecPos, &pos, &w, &h, true) )
{
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;
}
-
+
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 284a0c20..b911805d 100644
--- a/src/weapons/WeaponInfo.cpp
+++ b/src/weapons/WeaponInfo.cpp
@@ -6,70 +6,160 @@
#include "AnimManager.h"
#include "AnimBlendAssociation.h"
#include "Weapon.h"
+#include "ModelInfo.h"
+#include "ModelIndices.h"
-CWeaponInfo CWeaponInfo::ms_apWeaponInfos[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
+};
-static char ms_aWeaponNames[][32] = {
+// 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
+};
+
+CWeaponInfo CWeaponInfo::ms_apWeaponInfos[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) {
- return &CWeaponInfo::ms_apWeaponInfos[weaponType];
+CWeaponInfo::GetWeaponInfo(eWeaponType weaponType)
+{
+ return &ms_apWeaponInfos[weaponType];
}
+// --MIAMI: done except WEAPONTYPE_TOTALWEAPONS value
void
CWeaponInfo::Initialise(void)
{
debug("Initialising CWeaponInfo...\n");
for (int i = 0; i < WEAPONTYPE_TOTALWEAPONS; i++) {
ms_apWeaponInfos[i].m_eWeaponFire = WEAPON_FIRE_INSTANT_HIT;
- ms_apWeaponInfos[i].m_AnimToPlay = ANIM_PUNCH_R;
- ms_apWeaponInfos[i].m_Anim2ToPlay = NUM_ANIMS;
+ ms_apWeaponInfos[i].m_fRange = 0.0f;
+ ms_apWeaponInfos[i].m_nFiringRate = 0;
+ ms_apWeaponInfos[i].m_nReload = 0;
+ ms_apWeaponInfos[i].m_nAmountofAmmunition = 0;
+ ms_apWeaponInfos[i].m_nDamage = 0;
+ ms_apWeaponInfos[i].m_fSpeed = 0.0f;
+ ms_apWeaponInfos[i].m_fRadius = 0.0f;
+ ms_apWeaponInfos[i].m_fLifespan = 0.0f;
+ ms_apWeaponInfos[i].m_fSpread = 0.0f;
+ ms_apWeaponInfos[i].m_vecFireOffset = CVector(0.0f, 0.0f, 0.0f);
+ ms_apWeaponInfos[i].m_AnimToPlay = ASSOCGRP_UNARMED;
+ ms_apWeaponInfos[i].m_fAnimLoopStart = 0.0f;
+ ms_apWeaponInfos[i].m_fAnimLoopEnd = 0.0f;
+ ms_apWeaponInfos[i].m_fAnimFrameFire = 0.0f;
+ ms_apWeaponInfos[i].m_fAnim2LoopStart = 0.0f;
+ ms_apWeaponInfos[i].m_fAnim2LoopEnd = 0.0f;
+ ms_apWeaponInfos[i].m_fAnim2FrameFire = 0.0f;
+ ms_apWeaponInfos[i].m_fAnimBreakout = 0.0f;
ms_apWeaponInfos[i].m_bUseGravity = 1;
ms_apWeaponInfos[i].m_bSlowsDown = 1;
ms_apWeaponInfos[i].m_bRandSpeed = 1;
ms_apWeaponInfos[i].m_bExpands = 1;
ms_apWeaponInfos[i].m_bExplodes = 1;
+ ms_apWeaponInfos[i].m_nWeaponSlot = 0;
}
debug("Loading weapon data...\n");
LoadWeaponData();
debug("CWeaponInfo ready\n");
}
+// --MIAMI: Done, commented parts wait for weapons port
void
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
@@ -101,10 +191,9 @@ CWeaponInfo::LoadWeaponData(void)
fireType[0] = '\0';
fireOffsetY = 0.0f;
fireOffsetZ = 0.0f;
- animId = ANIM_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,
@@ -120,27 +209,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 (strncmp(anim2ToPlay, "null", 4) != 0) {
- animAssoc = CAnimManager::GetAnimAssociation(ASSOCGRP_STD, anim2ToPlay);
- ms_apWeaponInfos[weaponType].m_Anim2ToPlay = (AnimationId) animAssoc->animId;
- }
-
CVector vecFireOffset(fireOffsetX, fireOffsetY, fireOffsetZ);
ms_apWeaponInfos[weaponType].m_eWeaponFire = FindWeaponFireType(fireType);
@@ -154,12 +239,16 @@ CWeaponInfo::LoadWeaponData(void)
ms_apWeaponInfos[weaponType].m_fLifespan = lifeSpan;
ms_apWeaponInfos[weaponType].m_fSpread = spread;
ms_apWeaponInfos[weaponType].m_vecFireOffset = vecFireOffset;
- ms_apWeaponInfos[weaponType].m_AnimToPlay = animId;
ms_apWeaponInfos[weaponType].m_fAnimLoopStart = animLoopStart / 30.0f;
ms_apWeaponInfos[weaponType].m_fAnimLoopEnd = animLoopEnd / 30.0f;
+ ms_apWeaponInfos[weaponType].m_fAnim2LoopStart = anim2LoopStart / 30.0f;
+ ms_apWeaponInfos[weaponType].m_fAnim2LoopEnd = anim2LoopEnd / 30.0f;
ms_apWeaponInfos[weaponType].m_fAnimFrameFire = delayBetweenAnimAndFire / 30.0f;
ms_apWeaponInfos[weaponType].m_fAnim2FrameFire = delayBetweenAnim2AndFire / 30.0f;
+ ms_apWeaponInfos[weaponType].m_fAnimBreakout = animBreakout / 30.0f;
ms_apWeaponInfos[weaponType].m_nModelId = modelId;
+ ms_apWeaponInfos[weaponType].m_nModel2Id = modelId2;
+
ms_apWeaponInfos[weaponType].m_bUseGravity = flags & 1;
ms_apWeaponInfos[weaponType].m_bSlowsDown = (flags >> 1) & 1;
ms_apWeaponInfos[weaponType].m_bDissipates = (flags >> 2) & 1;
@@ -171,6 +260,37 @@ CWeaponInfo::LoadWeaponData(void)
ms_apWeaponInfos[weaponType].m_b1stPerson = (flags >> 8) & 1;
ms_apWeaponInfos[weaponType].m_bHeavy = (flags >> 9) & 1;
ms_apWeaponInfos[weaponType].m_bThrow = (flags >> 10) & 1;
+ ms_apWeaponInfos[weaponType].m_bReloadLoop2Start = (flags >> 11) & 1;
+ ms_apWeaponInfos[weaponType].m_bUse2nd = (flags >> 12) & 1;
+ ms_apWeaponInfos[weaponType].m_bGround2nd = (flags >> 13) & 1;
+ ms_apWeaponInfos[weaponType].m_bFinish3rd = (flags >> 14) & 1;
+ ms_apWeaponInfos[weaponType].m_bReload = (flags >> 15) & 1;
+ ms_apWeaponInfos[weaponType].m_bFightMode = (flags >> 16) & 1;
+ ms_apWeaponInfos[weaponType].m_bCrouchFire = (flags >> 17) & 1;
+ ms_apWeaponInfos[weaponType].m_bCop3rd = (flags >> 18) & 1;
+ ms_apWeaponInfos[weaponType].m_bGround3rd = (flags >> 19) & 1;
+ ms_apWeaponInfos[weaponType].m_bPartialAttack = (flags >> 20) & 1;
+ ms_apWeaponInfos[weaponType].m_bAnimDetonate = (flags >> 21) & 1;
+
+ ms_apWeaponInfos[weaponType].m_nWeaponSlot = weaponSlot;
+
+ if (animLoopEnd < 98.0f && weaponType != WEAPONTYPE_FLAMETHROWER && !CWeapon::IsShotgun(weaponType))
+ ms_apWeaponInfos[weaponType].m_nFiringRate = ((ms_apWeaponInfos[weaponType].m_fAnimLoopEnd - ms_apWeaponInfos[weaponType].m_fAnimLoopStart) * 900.0f);
+
+ if (weaponType == WEAPONTYPE_DETONATOR || weaponType == WEAPONTYPE_HELICANNON)
+ 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))) {
+ ms_apWeaponInfos[weaponType].m_AnimToPlay = (AssocGroupId)i;
+ break;
+ }
+ }
}
}
@@ -192,6 +312,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 c89dd482..6e09e9f2 100644
--- a/src/weapons/WeaponInfo.h
+++ b/src/weapons/WeaponInfo.h
@@ -1,12 +1,18 @@
#pragma once
+#include "AnimManager.h"
#include "AnimationId.h"
#include "WeaponType.h"
+enum AssocGroupId;
+
class CWeaponInfo {
-// static CWeaponInfo(&ms_apWeaponInfos)[14];
- static CWeaponInfo ms_apWeaponInfos[WEAPONTYPE_LAST_WEAPONTYPE];
+ static CWeaponInfo ms_apWeaponInfos[WEAPONTYPE_TOTALWEAPONS];
+ 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;
@@ -18,13 +24,16 @@ 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;
// flags
uint8 m_bUseGravity : 1;
uint8 m_bSlowsDown : 1;
@@ -34,9 +43,24 @@ public:
uint8 m_bExplodes : 1;
uint8 m_bCanAim : 1;
uint8 m_bCanAimWithArm : 1;
+
uint8 m_b1stPerson : 1;
uint8 m_bHeavy : 1;
uint8 m_bThrow : 1;
+ uint8 m_bReloadLoop2Start : 1;
+ uint8 m_bUse2nd : 1;
+ uint8 m_bGround2nd : 1;
+ uint8 m_bFinish3rd : 1;
+ uint8 m_bReload : 1;
+
+ uint8 m_bFightMode : 1;
+ uint8 m_bCrouchFire : 1;
+ uint8 m_bCop3rd : 1;
+ uint8 m_bGround3rd : 1;
+ uint8 m_bPartialAttack : 1;
+ uint8 m_bAnimDetonate : 1;
+
+ uint32 m_nWeaponSlot;
static void Initialise(void);
static void LoadWeaponData(void);
@@ -44,6 +68,7 @@ public:
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; }
};
-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 cdee16f9..bb1f44e9 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,4896 +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
-
-[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
+[R_TIME]
+RACE TIME:
-[HOOD]
-HOOD MISSIONS
+[PROP_1]
+You don't have enough cash for this property
-[CITYZON]
-Liberty City
+[PROP_2]
+You cannot buy property whilst on a mission
[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
+Vice City Beach
[COM_ZON]
-Staunton Island
+Vice City Mainland
-[STADIUM]
-Aspatria
+[BEACH1]
+Ocean Beach
-[HOSPI_2]
-Rockford
+[BEACH2]
+Washington Beach
-[UNIVERS]
-Liberty Campus
+[BEACH3]
+Vice Point
-[CONSTRU]
-Fort Staunton
+[GOLFC]
+Leaf Links
-[PARK]
-Belleville Park
+[STARI]
+Starfish Island
-[COM_EAS]
-Newport
+[DOCKS]
+Viceport
-[SHOPING]
-Bedford Point
+[HAVANA]
+Little Havana
-[YAKUSA]
-Torrington
+[HAITI]
+Little Haiti
-[SUB_ZON]
-Shoreside Vale
+[PORNI]
+Prawn Island
-[AIRPORT]
-Francis Intl. Airport
+[DTOWN]
+Downtown
-[PROJECT]
-Wichita Gardens
+[VICE_C]
+Vice City
-[SUB_IND]
-Pike Creek
+[A_PORT]
+Escobar International
-[SWANKS]
-Cedar Grove
+[JUNKY]
+Junk Yard
-[BIG_DAM]
-Cochrane Dam
+[PISTOL]
+Pistol
-[SUB_ZO2]
-Shoreside Vale
+[PYTHON]
+.357
-[SUB_ZO3]
-Shoreside Vale
+[UZI]
+Uz-1
-[CAR_1]
-Ambulance
+[TEC9]
+Tec 9
-[CAR_2]
-Firetruck
-
-[CAR_3]
-Police
-
-[CAR_4]
-Enforcer
-
-[CAR_5]
-Barracks
-
-[CAR_6]
-Rhino
+[M4]
+M4
-[CAR_7]
-FBIcar
+[INGRAM]
+Mac
-[CAR_8]
-Securicar
+[MP5]
+MP
-[CAR_9]
-Moonbeam
+[RUGER]
+Kruger
-[CAR_10]
-Coach
+[SNIPE]
+Sniper rifle
-[CAR_11]
-Flatbed
+[GRENADE]
+Grenades
-[CAR_12]
-Linerunner
+[SHOTGN1]
+Shotgun
-[CAR_13]
-Trashmaster
+[SHOTGN2]
+S.P.A.S. 12
-[CAR_14]
-Patriot
+[SHOTGN3]
+Stubby shotgun
-[CAR_15]
-Mr Whoopee
+[ARMOUR]
+Body Armor
-[CAR_16]
-Mule
+[LASER]
+.308 Sniper
-[CAR_17]
-Yankee
+[BASEBAT]
+Baseball bat
-[CAR_18]
-Pony
+[HAMMER]
+Hammer
-[CAR_19]
-Bobcat
+[SCREWD]
+Screwdriver
-[CAR_20]
-Rumpo
+[CLEVER]
+Meat Cleaver
-[CAR_21]
-Blista
+[MACHETE]
+Machete
-[CAR_22]
-Dodo
+[KNIFE]
+Knife
-[CAR_23]
-Bus
+[KATANA]
+Katana
-[CAR_24]
-Sentinel
+[CHAINSA]
+Chainsaw
-[CAR_25]
-Cheetah
+[G_COST]
+Cost: $~1~
-[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_1]
+Ambulance
-[CAR_36]
-Stallion
+[MALIBU]
+The Malibu Club
-[CAR_37]
-Taxi
+[MANSION]
+Diaz's Mansion
-[CAR_38]
-Cabbie
+[TMANS]
+Vercetti Estate
-[CAR_39]
-Buggy
+[STRIP]
+The 'Pole Position Club'
-[LUIGIS]
-Luigi's Place
+[MALL1]
+North Point Mall
-[GOAWAY]
-~g~You are already on a mission!
+[BANKINT]
+El Banco Corrupto Grande
-[LUIGGO]
-~g~Luigi's interviewing some new girls -Come back later!
+[RANGE]
+Rifle Range
-[JOEYGO]
-~g~Joey's out on the town with Misty -Drop by later!
+[POL_HQ]
+VCPD HQ
-[TONIGO]
-~g~Toni's taken his Momma to the opera -Call in some other time!
+[INT_B]
+An Old Friend
-[KEMUGO]
-~g~Maria and Kemuri are all tied up at the moment -Drop by later!
+[INTB_1]
+~g~Go to the Lawyer's office.
-[KENJGO]
-~g~Kenji is attending a Yakuza meeting -Call by some other time!
+[LAW_1]
+The Party
-[RAYGO]
-~g~Ray has other toilets to hang around -Try again later!
+[LAW_2]
+Back Alley Brawl
-[LOVEGO]
-~g~Donald Love has other business to attend to -Make an appointment later!
+[LAW_3]
+Jury Fury
-[KENSGO]
-~g~Kenji is busy! -Call by later!
+[LAW_4]
+Riot
-[HOODGO]
-~g~The Hoods are not available at this time!
+[COL_1]
+Treacherous Swine
-[WRONGT1]
-~g~Come back between 05:00 and 21:00 for a job
+[COL_2]
+Mall Shootout
-[WRONGT2]
-~g~Come back between 06:00 and 14:00 for a job
+[COL_3]
+Guardian Angels
-[WRONGT3]
-~g~Come back between 15:00 and 00:00 for a job
+[COL_4]
+Sir, Yes Sir!
-[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.
+[COL_5]
+All Hands On Deck!
-[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...
+[COK_1]
+The Chase
-[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...
+[COK_2]
+Phnom Penh '86
-[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...
+[COK_3]
+The Fastest Boat
-[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.
+[COK_4]
+Supply & Demand
-[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.
+[KENT_1]
+Death Row
-[GUN_4A]
-While holding the ~h~~k~~PED_LOCK_TARGET~ button~w~ you can walk or run while remaining locked onto a target.
+[ASS_1]
+Rub Out
-[GUN_4B]
-While holding the ~h~~k~~PED_LOCK_TARGET~ button~w~ you can walk or run while remaining locked onto a target.
+[BUD_1]
+Shakedown
-[GUN_5]
-You can practice targeting and shooting on these paper targets. When you are finished resume the mission.
+[BUD_2]
+Bar Brawl
-[TAXI1]
-~g~Look for a fare.
+[BUD_3]
+Cop Land
-[FARE1]
-~g~Destination ~w~'Meeouch Sex Kitten Club' ~g~in Redlight.
+[CAP_1]
+Cap the Collector
-[FARE2]
-~g~Destination ~w~'Supa Save' ~g~in Portland View.
+[FIN_1]
+Keep your Friends Close...
-[FARE3]
-~g~Destination ~w~'old school hall' ~g~in Chinatown.
+[BANK_1]
+No Escape?
-[FARE4]
-~g~Destination ~w~'Greasy Joe's Cafe' ~g~in Callahan Point.
+[BANK_2]
+The Shootist
-[FARE5]
-~g~Destination ~w~'AmmuNation' ~g~in Redlight.
+[BANK_3]
+The Driver
-[FARE6]
-~g~Destination ~w~'Easy Credit Autos' ~g~in Saint Mark's.
+[BANK_4]
+The Job
-[FARE7]
-~g~Destination ~w~'Woody's topless bar' ~g~in Redlight.
+[CNT_1]
+Spilling the Beans
-[FARE8]
-~g~Destination ~w~'Marcos Bistro' ~g~in Saint Mark's.
+[CNT_2]
+Hit the Courier
-[FARE9]
-~g~Destination ~w~'import export garage' ~g~in Portland Harbor.
+[PORN_1]
+Recruitment Drive
-[FARE10]
-~g~Destination ~w~'Punk Noodles' ~g~in Chinatown.
+[PORN_2]
+Dildo Dodo
-[FARE12]
-~g~Destination ~w~'Football Stadium' ~g~in Aspatria.
+[PORN_3]
+Martha's Mug Shot
-[FARE13]
-~g~Destination ~w~'The Church' ~g~in Bedford Point
+[PORN_4]
+G-spotlight
-[FARE14]
-~g~Destination ~w~'The Casino' ~g~in Torrington
+[TAX_1]
+Kaufman Cabs
-[FARE15]
-~g~Destination ~w~'Liberty University' ~g~in Liberty Campus
+[TAXI_1]
+V.I.P.
-[FARE16]
-~g~Destination ~w~'Shopping Mall' ~g~in Belleville Park Area
+[TAXI_2]
+Friendly Rivalry
-[FARE17]
-~g~Destination ~w~'Museum' ~g~in Newport
+[TAXI_3]
+Cabmaggedon
-[FARE18]
-~g~Destination ~w~'AmCo Building' ~g~in Torrington
+[ICE_1]
+Distribution
-[FARE19]
-~g~Destination ~w~'Bolt Burgers' ~g~in Bedford Point
+[TEX_1]
+Four Iron
-[FARE20]
-~g~Destination ~w~'The Park' ~g~in Belleville
+[TEX_2]
+Two Bit Hit
-[FARE21]
-~g~Destination ~w~'Francis intl. Airport'
+[TEX_3]
+Demolition Man
-[FARE22]
-~g~Destination ~w~'Cochrane Dam'
+[PHIL_1]
+Gun Runner
-[FARE24]
-~g~Destination ~w~'The hospital' ~g~in Pike Creek
+[PHIL_2]
+Boomshine Saigon
-[FARE25]
-~g~Destination ~w~'The Park' ~g~in Shoreside Vale
+[BIKE_1]
+Alloy Wheels of Steel
-[FARE26]
-~g~Destination ~w~'North West Towers' ~g~in Wichita Gardens
+[BIKE_2]
+Messing with the Man
-[NEW_TAX]
-BIGGER! FASTER! HARDER! new Borgnine taxis open for business in Harwood. Call 555-BORGNINE today!
+[BIKE_3]
+Hog Tied
-[TSCORE2]
-$~1~
+[ROCK_1]
+Love Juice
-[IN_ROW]
-~1~ IN A ROW bonus! $~1~
+[ROCK_2]
+Psycho Killer
-[TTUTOR]
-Press the ~h~~k~~TOGGLE_SUBMISSIONS~ button~w~ to toggle taxi missions on or off.
+[ROCK_3]
+Publicity Tour
-[TTUTOR2]
-Press the ~h~~k~~TOGGLE_SUBMISSIONS~ button~w~ to toggle taxi missions on or off.
+[ROCK_4]
+Love Fist!!
-[A_TIME]
-+~1~ seconds
+[HAT_1]
+Juju Scramble
-[A_FULL]
-~r~Ambulance full!!
+[HAT_2]
+Bombs Away!
-[A_RANGE]
-~g~The ambulance radio is out of range, get closer to a hospital!
+[HAT_3]
+Dirty Lickin's
-[FTUTOR]
-Press the ~h~~k~~TOGGLE_SUBMISSIONS~ button~w~ to toggle fire truck missions on or off.
+[CUB_1]
+Stunt Boat Challenge
-[FTUTOR2]
-Press the ~h~~k~~TOGGLE_SUBMISSIONS~ button~w~ to toggle fire truck missions on or off.
+[CUB_2]
+Cannon Fodder
-[F_PASS1]
-Fire extinguished!
+[CUB_3]
+Naval Engagement
-[F_RANGE]
-~g~The fire truck radio is out of range, get closer to a fire station!
+[CUB_4]
+Trojan Voodoo
-[C_BREIF]
-~g~Suspect last seen in the ~a~ area.
+[JOB_1]
+Road Kill
-[C_RANGE]
-~g~The police radio is out of range, get closer to a police station!
+[JOB_2]
+Waste the Wife
-[DODO_FT]
-You flew for ~1~ seconds!
+[JOB_3]
+Autocide
-[EBAL_A]
-I know a place on the edge of the Red Light District where we can lay low,
+[JOB_4]
+Check Out at the Check In
-[EBAL_A1]
-but my hands are all messed up so you better drive, brother.
+[JOB_5]
+Loose Ends
-[EBAL_1]
-Press the~h~ ~k~~VEHICLE_ENTER_EXIT~ button~w~ to ~h~enter ~w~or ~h~exit~w~ a vehicle.
+[ANSWER]
+Press the ~h~~k~~PED_ANSWER_PHONE~~w~ to answer your cell phone.
-[EBAL_1B]
-Press the~h~ ~k~~VEHICLE_ENTER_EXIT~ button~w~ to ~h~enter ~w~or ~h~exit~w~ a vehicle.
+[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.
-[EBAL_2]
-~g~Get back into the car!
+[MOB_01B]
+I'm enjoying a little R&R at the Club Malibu.
-[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_01C]
+Reckon you're gonna owe me a favor or two after this, sunshine. I'll see you later.
-[EBAL_D]
-I know a guy, he's connected, his name's Luigi.
+[MOB_02A]
+Ssssnniiiiffffff Hey! Hello, Tommy? Tommy!
-[EBAL_D1]
-Me an' him go back so I could probably get you some work. C'mon lets head over there.
+[MOB_02B]
+We got a situation over at the Print Works. You better go and check it out.
-[EBAL_E]
-C'mon, lets drop by and I'll introduce you.
+[MOB_02C]
+Some kind of mess or other. Things are messed up. I gotta go.
-[EBAL_I]
-The boss will be out to see you shortly...
+[MOB_03A]
+Mr. Vercetti? I have here a signed piece of crap stating
-[EBAL_J]
-8-Ball's got some business up stairs.
+[MOB_03B]
+that you have taken on all of BJ's Auto's debts.
-[EBAL_K]
-Maybe you can do me a favor.
+[MOB_03C]
+With BJ's sudden disappearance I have no choice
-[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_03D]
+but to hold you responsible for his financial insecurities.
-[EBAL_N]
-So keep your hands on the wheel!
+[MOB_03E]
+Until this account is settled in full
-[EBAL_4]
-~r~8-Ball's dead!
+[MOB_03F]
+you should consider Vice City's streets to be very unfriendly.
-[EBAL_5]
-~g~Get a vehicle!
+[MOB_04A]
+How you doin' mate? It's Paulo again.
-[EBAL_6]
-~g~Pick up Misty!
+[MOB_04B]
+Look Tommy, I forgot to mention we're going to need some extra muscle for the concert. A bit of security.
-[LM1]
-'LUIGI'S GIRLS'
+[MOB_04C]
+There's a biker gang led by Mitch Baker, it would be great publicity. Very rock and roll, baby.
-[LM2]
-'DON'T SPANK MA BITCH UP'
+[MOB_04D]
+Sort this out for me and I'll get you some back stage passes for the gig, awright?
-[LM3]
-'DRIVE MISTY FOR ME'
+[MOB_05A]
+Hey, it's Mitch. You did good Tommy, it's good to have the old girl back.
-[LM5]
-'THE FUZZ BALL'
+[MOB_05B]
+You tell Kent Paul he'll get his security for the gig.
-[LM1_2]
-~g~Take Misty to Luigi's Club.
+[MOB_05C]
+You have my word on that.
-[LM1_3]
-~g~Press the horn to get the girl into the car.
+[MOB_05D]
+Now keep yourself out of trouble.
-[LM1_6]
-~g~Get back into the car!
+[MOB_06A]
+Tommy, 'nuf dead man been chattin' about you, my dear.
-[LM1_7]
-Stop the vehicle next to Misty and allow her to enter it.
+[MOB_06B]
+Thought you might need something to make you feel better. So Auntie Poulet make you some stew, aye?
-[LM1_8]
-You can go and see Luigi for more work or check out Liberty City.
+[MOB_06C]
+Come by me kitchen some time, ok Tommy?
-[LM2_A]
-There's a new high on the street goes by the name of SPANK.
+[MOB_08A]
+Hey Tommy, I thought you might need some business advice.
-[LM2_E]
-Some wiseguy's been introducing this trash to my girls down Portland Harbor.
+[MOB_08B]
+Once you got an operation up and running, you'll need to drop by and take the week's cash.
-[LM2_B]
-Go and introduce a bat to his face!
+[MOB_08C]
+Let the guys think they got the run of the place and they'll try shaving the profits - ok?
-[LM2_G]
-I want compensation for this insult!
+[MOB_08D]
+Hey, I know how to handle business, Ken, ok?
-[LM2_1]
-~g~Take his car and get it resprayed.
+[MOB_08E]
+Ok, ok. I know, you know. I know. I was,
-[LM2_2A]
-Use the~h~ ~k~~PED_FIREWEAPON~ button~w~ to ~h~punch ~w~and ~h~kick~w~ or ~h~swing ~w~the bat!
+[MOB_08F]
+I was just, you know, telling you I know, that you know, that I know.
-[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~!
+[MOB_08G]
+Just keeping it sharp baby!
-[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~!
+[MOB_08H]
+Whatever, Ken, whatever...
-[LM2_3]
-~g~Stash the car in Luigi's lockup!
+[MOB_09A]
+Hey Leo! I got some work for you!
-[LM2_4]
-~g~Respray the car!
+[MOB_09B]
+This ain't Leo.
-[LM3_A]
-Hey I've gotta talk to you... All right Mick I'll talk to yah later.
+[MOB_09C]
+Hey, if Leo knows you got his phone, he gonna kill you!
-[LM3_B]
-How yah doing kid?
+[MOB_09E]
+You killed Leo? You must have big cojones - wanna work for me?!
-[LM3_C]
-The Don's son, Joey Leone, he wants some action from his regular girl Misty.
+[MOB_09F]
+Drop by my father's cafe in Little Havana and we'll talk mano a mano.
-[LM3_D]
-Go pick her up at Hepburn Heights...
+[MOB_10A]
+Tommy! Look, I gotta ask you a favor.
-[LM3_E]
-but watch yourself that's Diablo turf.
+[MOB_10B]
+Steve! How's filming going!
-[LM3_F]
-Then run her over to his garage in Trenton and make it quick,
+[MOB_10C]
+Fine, fine. I, heh, WE need a car chase scene, but our budget can't stretch to it.
-[LM3_H]
-so keep your eyes on the road and off Misty!
+[MOB_10D]
+I've left some wheels around town. You'll know what to do.
-[LM3_2]
-~g~Take Misty to Joey's.
+[MOB_10E]
+Ok Steve, I'll keep an eye out. Catch you later.
-[LM3_4]
-~g~Go pick up Misty!
+[MOB_11A]
+Howdy son, just thought I'd ring you up and give you some advice.
-[LM3_5]
-You working regular for Luigi now huh? It's about time he got a driver we can trust!
+[MOB_11B]
+Hey, Avery. What's eating you?
-[LM3_7]
-I'll be with you in a minute spark plug.
+[MOB_11C]
+There's a lot of opportunity in this town if you own the right real estate, you catch my drift?
-[LM3_10]
-~g~Get a vehicle!
+[MOB_11D]
+I reckon so...
-[LM4_B]
-Go and take care of things for me.
+[MOB_11E]
+All I'm saying is keep your eyes open and you might find the perfect business opportunity. I'll catch y'later.
-[LM4_C]
-If you need a piece go around the back of AmmuNation opposite the subway.
+[MOB_11F]
+Later, Avery.
-[LM5_A]
-The Policeman's Ball is being held at the old school hall near the Callahan Bridge
+[MOB12_A]
+Hey Tommy, it's Avery! Now listen, I got me all tied up at the moment
-[LM5_B]
-and they'll be looking for some 'old school' action.
+[MOB12_B]
+and I have a representative of mine needs chaperoning out to the Gator Keys.
-[LM5_C]
-Now I got girls all over town walking the streets.
+[MOB12_C]
+I'm after some land out that way, so I'm sending someone out to sweeten the deal.
-[LM5_D]
-Get'em to the ball they'll make a bundle.
+[MOB12_D]
+Could you do me a favor and make sure he gets there ok?
-[LM5_1]
-~g~You pack these ladies too tight, they gonna bruise! ~g~Drop these girls off first, then come back for more.
+[MOB12_E]
+Yeah, sure thing Avery. Where'd you want me to pick him up?
-[LM5_2]
-~r~One of Luigi's girls is bodybag meat!
+[MOB12_F]
+He's just finishing some business at the building site. I said you'd pick him up from there.
-[LM5_3]
-~g~You need a car!
+[MOB12_G]
+No problem. See you later, Avery.
-[LM5_4]
-~g~Pick up the girls working St. Marks.
+[MOB13_A]
+Vercetti? VERCETTI!! Damn you man, you've got to help me!
-[LM5_5]
-~g~Take the girls to the Fuzz Ball!
+[MOB13_B]
+Mr. Moffat? How's family life?
-[LM5_8]
-~g~Girls working the Ball: ~1~
+[MOB13_C]
+Damn you to hell, HELL, do hear me?!
-[JM2]
-'FAREWELL 'CHUNKY' LEE CHONG'
+[MOB13_D]
+Well it was nice chatting...
-[JM4]
-'CIPRIANI'S CHAUFFEUR'
+[MOB13_E]
+WAIT! Wait, Vercetti - Tommy, can I call you Tommy?
-[JM5]
-'DEAD SKUNK IN THE TRUNK'
+[MOB13_F]
+We're both businessmen, yeah? You know a good deal when you hear one, ok?
-[JM1_1]
-~g~Take Forelli's car to 8-Ball's garage North of here, behind 'Easy Credit Autos'.
+[MOB13_G]
+I don't have time to chat, get to the point.
-[JM1_2]
-~g~Park the car back at Marco's Bistro.
+[MOB13_H]
+MONEY. Money is the goddamned point.
-[JM1_3]
-~g~Activate the car bomb then get out of there!
+[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!
-[JM1_4]
-~g~You're trashing the vehicle! Get it repaired!
+[MOB13_J]
+I'm at a pay phone somewhere in this god forsaken shit hole.
-[JM1_5]
-~g~The car bomb's not set!
+[MOB13_K]
+Get me out of here before they take me back and...and..oh go-o-od...
-[JM1_6]
-~g~Put the car back in the correct position.
+[MOB13_L]
+Well, I'm busy for the next -
-[JM1_8A]
-~y~Hey, it's my main man!
+[MOB13_M]
+No! Don't shit with me here, have a heart! No man should have to do such, such things.
-[JM1_8B]
-~y~The bomb shop's automated. Just drive in, stop your car and the shop will do the rest.
+[MOB13_N]
+I'm on my knees here Tommy, in the dirt begging you please...
-[JM1_8C]
-~y~Here, your first can be free, but after that it'll cost.
+[MOB13_O]
+I guess I could swing by that way, see if I can spot you...
-[JM2_A]
-Chunky Lee Chong is pushing spank for some new gang from Colombia... or Colorado... or something....
+[MOB13_P]
+Oh god, they're coming. For the love of Christ hurry, hurry!
-[JM2_B]
-I'm not really sure. Who needs details anyway.
+[MOB_14A]
+Hey there Tommy, you're gonna love me mate.
-[JM2_D]
-That rat has sold his last stir fry.
+[MOB_14B]
+A little birdy told me that Vice City SWAT Division has a deposit box at a certain rather large banking establishment,
-[JM2_E]
-I want you to take him out!
+[MOB_14C]
+where they keep all the bribes they've taken over the years,
-[JM2_G]
-Sort yourself with a nine, you know where it is, right?
+[MOB_14D]
+like some kind of old boys' retirement fund.
-[JM2_H]
-Well remember, just watch your back in China Town, it's Triad territory.
+[MOB_14E]
+Of course, if this information should ever help you acquire any of that cash,
-[JM3_A]
-Alright, we're gonna hit the pay role van.
+[MOB_14F]
+I guess you'd feel obliged to push some of it my way?
-[JM3_B]
-It leaves the edge of China Town everyday.
+[MOB_14G]
+I'll bear that in mind, thanks Kent.
-[JM3_C]
-Bullets won't even dent the van's armor, so get a car and ram it off the road.
+[MOB_14H]
+It's Paul. I'm from Kent, near London, you prat.
-[JM3_D]
-Now hit it hard and the punk ass security guards should bail.
+[MOB_14I]
+My provincial English geography ain't what it was.
-[JM3_E]
-Then take it to the warehouse at the docks and my guys are gonna take over from there.
+[MOB15_A]
+Tommy, mate, it's Paul, from Kent,
-[JM3_F]
-Now it won't be doin' it's rounds all day, so don't hang around.
+[MOB15_B]
+a couple of proper sorts have your name written all over them, down at the Malibu.
-[JM3_1]
-~g~Take the van to the lock up.
+[MOB15_C]
+What are you talking about?
-[JM3_2]
-~g~Ram the van until its damage is below 70 percent.
+[MOB15_D]
+Sorts. Birds. You know. Girls. Tastey ones, don't think they're brasses or nothing.
-[JM4_B]
-Oh! Here's the guy I was telling you about!
+[MOB15_E]
+You gotta come check them out.
-[JM4_C]
-Alright Listen. This guy ain't Italian and he's no mechanic but he can get things fixed.
+[MOB16_A]
+Tommy, Paulo here, que pasa amigo?
-[JM4_D]
-This is Pops Capo, Toni Cipriani.
+[MOB16_B]
+What do you want Paul. I don't want any fake label clothes.
-[JM4_E]
-Yeah, I'm Toni Cipriani
+[MOB16_C]
+Very funny, mate, but you know I don't touch bent gear.
-[JM4_F]
-Take him to Momma's restaurant at St Marks, alright.
+[MOB16_D]
+Nah, I was just calling to see if I get a part in one your movies,
-[JM4_G]
-Now listen to me, I'm planning a job that needs a good driver so drop by sometime later Ok?
+[MOB16_E]
+back in England I did a lot of blue stuff, mate.
-[JM4_2]
-Wait here! Keep the engine running. This ain't a social call.
+[MOB16_F]
+I'm packing more heat than you, my son.
-[JM4_3]
-It's a Triad ambush! Get us out of here kid!
+[MOB16_G]
+Paul, thanks for the offer, I'll bear it in mind.
-[JM4_4]
-The Triads think they can mess with me, the triads, with ME!
+[MOB16_H]
+Seriously, don't forget about me, after all I done for you.
-[JM4_6]
-Hey watch the car! I said no fancy crap.
+[MOB16_I]
+That's what I'm trying to forget about.
-[JM4_7]
-~g~Take Toni to his momma's restaurant.
+[MOB19_A]
+Tommy V, It's KP here. Kent Paul. Word on the street is people want to rip you off.
-[JM4_8]
-~r~Toni's been wasted!
+[MOB19_B]
+Keep your eye's peeled, my son. And remember, I didn't say nothing to you about this.
-[JM5_A]
-Beautiful! Just beautiful.
+[MOB_20A]
+Alright, Tommy, it's Paul. I just heard from a mush that you've been a real naughty boy.
-[JM5_B]
-Alright, Just the guy I need to talk to!
+[MOB_20B]
+Somebody has taken offense to you acting like the big guy all of a sudden, giving it the big shot thing.
-[JM5_D]
-One of the Forellis thought he was a wise guy, so he got what he had coming to him.
+[MOB_20C]
+Well, don't say I never warned you or nothing. Boasting is a mug's game, son.
-[JM5_E]
-Take the corpse to the crusher in Harwood, alright?
+[MOB_20D]
+Anyway, I heard there's some price been put on your head and someone's going to have a crack at you,
-[JM5_1]
-~g~Take it to the crusher!
+[MOB_20E]
+so watch yourself, and remember me, mate.
-[JM5_2]
-~g~It's the Forelli brothers!
+[MOB21_A]
+Tommy, Thomas, it's Cortez. Que pasa?
-[JM6_A]
-What a ride she's gonna be, huh?
+[MOB21_B]
+Things are interesting. How are you, my friend?
-[JM6_B]
-Alright, listen. Get some wheels to the safehouse at St. Marks and pick up a few friends of mine.
+[MOB21_G]
+I wanted to ask you about Mercedes.
-[JM6_C]
-They're hittin' a bank and they need a driver.
+[MOB21_H]
+Ok, what about her?
-[JM6_D]
-I gave my word that you were the man, so don't screw this up.
+[MOB21_I]
+Oh Tommy, Tommy. I, I hear these stories, all these stories - I don't know what to think.
-[JM6_E]
-Get them to the bank before five o'clock, not a minute after.
+[MOB21_K]
+Maybe she thinks she can do what she likes, but Tommy, tell me, is it true?
-[JM6_2]
-Keep the engine running we'll be in and out in no time.
+[MOB21_M]
+Is what true?
-[JM6_3]
-Get us out of here!!
+[MOB21_N]
+These stories I hear. Is she really going to be a lawyer?
-[JM6_4]
-Shake the cops and get us to the safehouse!!
+[MOB21_O]
+Oh Tommy, the shame, the shame! You know, we Cortez's are a proud family.
-[JM6_6]
-~g~Go and get a vehicle less conspicuous!
+[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.
-[JM6_7]
-~g~You need all 3 to rob the bank!
+[MOB21_Q]
+Oh Colonel, I can assure you Mercedes is never going to become a lawyer. Don't worry about it.
-[TM1]
-'TAKING OUT THE LAUNDRY'
+[MOB21_R]
+Oh thank you, Tommy. Tommy, thank you. The shame would be unbearable. She is a lady, not a parasite, you know.
-[TM2]
-'THE PICK-UP'
+[MOB21_S]
+I know, colonel.
-[TM3]
-'SALVATORE'S CALLED A MEETING'
+[MOB21_T]
+Anyway, Tommy, you must excuse me, the new minister of the interior has arrived.
-[TM4]
-'TRIADS AND TRIBULATIONS'
+[MOB21_U]
+Many years ago, I killed his father in a failed coup so I must be polite. Good day, amigo.
-[TM5]
-'BLOW FISH'
+[MOB21_C]
+Tommy, it is always a struggle here. Excuse the poor line, we have just had another failed coup.
-[TONI_P]
-I've got some urgent work for you! -Toni
+[MOB21_D]
+The people are the most demanding mistress of all.
-[TM1_A]
-~w~Take a seat kid, take a god damned seat.
+[MOB21_E]
+So far, we have had three revolutions and four coups since I return from Vice City.
-[TM1_B]
-~w~So the laundry won't pay any protection eh?
+[MOB21_F]
+Luckily, I have been promoted each time.
-[TM1_C]
-~w~The Triads think they can mess with me?
+[MOB21_J]
+Maybe everyone is humiliating me.
-[TM1_D]
-~w~Let's teach these would be tough guys what it means to be a tough guy.
+[MOB21_L]
+but tell me Tommy, is it true?
-[TM1_E]
-~w~Yeah, teach 'em some respect. No son of mine gets it from some Triads.
+[MOB22_A]
+Tommy, you are proving very useful, my friend.
-[TM1_F]
-~w~Your father, god rest his soul, took no crap from no Triads back in Sicily.
+[MOB22_B]
+Thanks, Cortez. What about my deal?
-[TM1_G]
-~w~Sorry Ma. Yes Ma.
+[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,
-[TM1_H]
-~w~I want you to destroy their laundry vans
+[MOB22_D]
+you have my word on that, but in the meantime,
-[TM1_I]
-~w~and mangle any triad gimp that gets in your way.
+[MOB22_E]
+please accept the esteemed thanks of my people for your work on our behalf.
-[TM1_J]
-~w~8-Ball can supply you with what you're gonna need.
+[MOB_25A]
+Tommy, Thomas it's Cortez. Look, the French are giving me all kinds of trouble, amigo.
-[TM2_A]
-~w~TONI's off making people bleed or trying to.
+[MOB_25B]
+Damn hypocrites. They spend a hundred years stealing from poor countries and they call me a thief!
-[TM2_AA]
-~w~He'll never be as tough as his Pop, but he left you a note on the table.
+[MOB_25C]
+I am going to need your help as soon as possible, amigo.
-[TM2_B]
-~w~The laundry has agreed to pay - you did real good kid!
+[MOB_25D]
+So please hurry, Tommy, I need you, all right? I hate the damn French.
-[TM2_C]
-~w~Go collect the cash and bring it back here. Watch out for the Triads.
+[MOB_26A]
+Hello, Tommy?
-[TM2_D]
-~w~They may be shoving a firecracker up your ass, but don't take no crap.
+[MOB_26B]
+Yeah?
-[TM2_E]
-~w~Nobody I mean nobody, messes with TONI CIPRIANI!
+[MOB_26C]
+It's Baker. I just wanted to say I really enjoyed the show.
-[TM2_1]
-~g~Get the cash back to Toni's!!
+[MOB_26D]
+Me and the boys want to thank you, and remind you,
-[TM2_2]
-~g~You iced them all!
+[MOB_26E]
+you got our respect. Good day. Keep riding hard, son.
-[TM3_MA]
-~w~I don't know where he is!
+[MOB_29A]
+Hello, is this Mr. Tommy Vercetti?
-[TM3_MB]
-~w~I swear that boy of mine don't know himself sometimes.
+[MOB_29B]
+Yes.
-[TM3_MC]
-~w~Now his father, he was different. Always on top, in charge, manful...
+[MOB_29C]
+Well, I hear through the vine of grapes you the man when someone got a vermin infestation.
-[TM3_A]
-~w~Don Salvatore has called a meeting.
+[MOB_29D]
+Maybe...
-[TM3_B]
-~w~I need you to collect the limo and his boy, Joey, from the garage.
+[MOB_29E]
+Well, I got a real vermin infestation. Haitians everywhere.
-[TM3_C]
-~w~Then get Luigi from his club, come back here and pick me up,
+[MOB_29F]
+My name is Umberto Robina and I want you to meet me at the Cafe Robina as soon as you can,
-[TM3_D]
-~w~then we'll all drive over to the boss's place together.
+[MOB_29G]
+'cause I tell you, these damn Haitians gone too far this time.
-[TM3_E]
-~w~Those Triads, they don't know when to stop.
+[MOB_29H]
+Test
-[TM3_F]
-~w~They want a war. They got a war.
+[MOB_30A]
+Tommy, is Umberto Robina
-[TM3_G]
-~w~Now get going.
+[MOB_30B]
+Hey, how's the cafe?
-[TM3_1]
-~g~Pick up the Stretch from Joey's.
+[MOB_30C]
+Oh, wonderful. Incredible. Tommy, incredible. No wimps, Tommy, just real men, and the beautiful women!
-[TM3_2]
-~g~Now go pick up Luigi.
+[MOB_30D]
+Anyway, I wanted to tell you, me and Papi, to us, you Cuban.
-[TM3_3]
-~g~Now go pick up Toni.
+[MOB_30E]
+You have proved yourself, man. You got big cojones.
-[TM3_4]
-~g~Drive the goodfellas to Salvatore's place.
+[MOB_30F]
+Well thank you, Umberto. Nobody's said that to me since I left jail. I'll see you around.
-[TM3_5]
-~y~It's a triad ambush!!
+[MOB_33A]
+Tommy, it's Phil, now cut out all the reminiscing crap and listen to me, you hear?
-[TM4_B]
-~w~We're at WAR! The Triads have a fish factory as a front.
+[MOB_33B]
+Good. I got me some extra strength boomshine nearing fermentation time and I was wondering if you'd fancy having a shot.
-[TM4_C]
-~w~Most of their business goes down at the fish market in Chinatown.
+[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.
-[TM4_D]
-~w~That laundry still owes us protection.
+[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.
-[TM4_E]
-~w~They reckon the Triads are protecting them now, so I say we exact a fitting punishment.
+[MOB_34A]
+Tommy, I really enjoyed working with you. Ain't had so much fun since the ridge in Nam, pal.
-[TM4_F]
-~w~Take these boys over and whack the Triad Warlords!
+[MOB_34B]
+Anyhows, you need anything, you call on me, you hear?
-[TM4_G]
-~w~Hell, if you get a chance, pop some of their soldiers too.
+[MOB_34C]
+I always remember those I served with,
-[TM4_GAT]
-~g~You need a 'Triad fish van' to enter.
+[MOB_34D]
+and I am sure I can help you out, you hear?
-[TM5_B]
-~w~OK, I've had enough of this shit.
+[MOB_35A]
+Tommy, the wound is healing well. Funny thing is,
-[TM5_C]
-~w~We're gonna finish the Triads in Liberty once and for all!
+[MOB_35B]
+I have fought in 6 battle zones and always walked away without a scratch, and now this!
-[TM5_D]
-8-Ball's rigged a dustcart with a bomb.
+[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.
-[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_35D]
+Any way son, cut out the sentimental crap and go buy yourself a drink, you hear!
-[TM5_F]
-~w~Careful, 8-Ball says it's real sensitive and the slightest bump could set that thing off!
+[MOB_36A]
+Tommy, it's Phil, I want to thank you for helping me out back there son,
-[TM5_G]
-~w~Their fish factory will open its gates for a dustcart, so you can drive right in.
+[MOB_36B]
+Damn Charlie, he'll always ambush you somewhere or other,
-[TM5_H]
-~w~Park up between the gas canisters and get the hell out of there!
+[MOB_36C]
+Anyway the wound is healing well, and it means I'll no longer be defrauding the government on my disability check.
-[TM5_I]
-~w~I want it to rain mackerel.
+[MOB_40A]
+Hey Tommy, it's Sonny. How's the sun tan?
-[TM5_J]
-~w~We're talking real biblical here, nothing low budget.
+[MOB_40B]
+I ain't got no sun tan.
-[FM2]
-'CUTTING THE GRASS'
+[MOB_40C]
+Well, you ain't got my money, either, so I'm wondering to myself,
-[FM4]
-'LAST REQUESTS'
+[MOB_40D]
+what are you doing? So, tell me, Tommy, what are you doing?
-[FM1_A]
-~w~Me an' the fellas need to talk business
+[MOB_40E]
+I'm looking for the money, Sonny. Don't worry.
-[FM1_B]
-~w~so you're gonna look after my girl for the evening.
+[MOB_40F]
+I am worrying, Tommy, that's my style,
-[FM1_C]
-~w~HEY MARIA! MOVE YOUR BUTT!
+[MOB_40G]
+because I seem to have this problem in my life with unreliable people.
-[FM1_D]
-~w~Dumb broad does this every time.
+[MOB_40H]
+Don't be an unreliable person, Tommy, please.
-[FM1_E]
-~w~And here she is, the one and only Queen of Sheba!
+[MOB_40I]
+Do us both a favor. I'm looking forward to hearing from you.
-[FM1_F]
-~w~What were you doing up there?
+[MOB_41A]
+Tommy, remember me?
-[FM1_G]
-~w~Whatever it was, I bet it cost me money.
+[MOB_41B]
+Hello Sonny.
-[FM1_H]
-~w~Well, you don't think I hang around for the conversation, do you?
+[MOB_41C]
+That's right, Sonny. We're old friends,
-[FM1_I]
-~w~Get in that car and keep your big mouth shut.
+[MOB_41D]
+You never write me, you never call. Don't you want to be friends no more?
-[FM1_J]
-~w~Take the limo but bring it back in one piece, y'hear me?
+[MOB_41E]
+I've been busy trying to sort things out. You didn't give me a lot of support down here, Sonny.
-[FM1_K]
-~w~And watch her, she can be trouble.
+[MOB_41F]
+Oh, my fault is it? We'll I've heard you been busy all right.
-[FM1_L]
-~w~Yeah, yeah, yeah! I'm sure your new lap dog has everything covered,
+[MOB_41G]
+Busy killing drugs barons. Busy taking over.
-[FM1_M]
-~w~and isn't he big and strong?
+[MOB_41H]
+Don't forget about us, Tommy, 'cause I can assure you, I ain't forgotten about you.
-[FM1_N]
-~w~Hey Fido, Let's go visit Chico and get some party treats!
+[MOB_42A]
+Tommy.
-[FM1_P]
-~g~That's Chico over there, pull up next to him.
+[MOB_42B]
+Sonny.
-[FM1_S]
-~w~Here you go lady.
+[MOB_42C]
+Obviously you are suffering from hearing problems, so I'll try again.
-[FM1_TT]
-~w~IT'S A POLICE RAID!
+[MOB_42D]
+Where's the goddamned money, where's the goddamned stuff, and where's my cut of your new action?
-[FM1_1]
-~g~Get back into the Stretch!
+[MOB_42E]
+You are making an idiot out of me, Tommy, and I'm not laughing yet.
-[FM1_2]
-~g~Get into the Stretch!
+[MOB_43A]
+Tommy, Tommy, Tommy, I had Sonny on the phone, ok, are you with me?.
-[FM1_3]
-~r~Leave Maria and Salvatore will have you whacked, go back and pick her up.
+[MOB_43B]
+I don't know about you, but there's something about a man threatening to murder my family
-[FM1_4]
-~g~You've dumped the Don's woman! Get back to the warehouse and wait for Maria!
+[MOB_43C]
+which really scares the crap out of me. What are you going to do?
-[FM1_5]
-~g~Get Maria safely back to Salvatore's!
+[MOB_43D]
+Ken, take it easy.
-[FM1_6]
-~g~Chico won't be there forever, get Maria to the waterfront!
+[MOB_43E]
+I AM calm, calm as a man can be when he's fearing for his life!
-[FM1_7]
-~r~Maria's dead! Salvatore won't be too pleased...
+[MOB_43F]
+Stay off the idiot fuel and look after yourself.
-[FM1_8]
-~r~You wasted Maria's supplier!
+[MOB_43G]
+No one's gonna take us out. I'll see you later.
-[FM2_J]
-Leave us alone for a minute.
+[MOB_43H]
+I am calm. Don't I sound calm? Must be impending death that is doing this to my voice.
-[FM2_A]
-The Colombian Cartel is making SPANK somewhere in Liberty.
+[MOB45_A]
+Tommy We gotta talk about stuff.
-[FM2_K]
-but we don't know where, and they seem to know everything we're doin' before we do.
+[MOB45_B]
+What's the problem Lance?
-[FM2_L]
-There is a guy named Curly Bob works the bar at Luigi's.
+[MOB45_C]
+It's you, my friend, I feel you're not giving me a fair slice.
-[FM2_M]
-He's been throwing more money around than he's earning.
+[MOB45_D]
+And more than that, you been embarrassing me in front of the boys. I can't have that.
-[FM2_N]
-He usually gets a taxi home after work. So follow him.
+[MOB45_E]
+Lance, it ain't like that. You've been making mistakes.
-[FM2_O]
-And if he's rattin' us out... kill him.
+[MOB45_F]
+Tommy, I'm not your message boy. I'm not your running boy.
-[FM2_F]
-Here comes our little friend. Mr big mouth himself.
+[MOB45_G]
+Lance, don't screw up, and we won't have any problems. I screw up, you can lay into me any time.
-[FM2_G]
-Were you followed? You know what goes on here is our little secret.
+[MOB45_H]
+Tommy, I've done everything for you, you treat me like a fool. Don't do that.
-[FM2_H]
-No..no, I wasn't followed. You got my stuff?
+[MOB45_I]
+Lance, I won't rip you off or stab you in the back, okay?
-[FM2_I]
-Here's your SPANK, squealer, now talk.
+[MOB45_J]
+Just take it easy. This is tough enough without you getting all emotional on me.
-[FM2_P]
-OK, so the Leone's are fighting wars on two fronts.
+[MOB45_K]
+Trust me. Do you hear me, do you hear me?
-[FM2_Q]
-They're in a turf war with the Triads with no sign of either side giving up.
+[MOB45_L]
+I hear you, Tommy, but I can't take this much more.
-[FM2_R]
-Meanwhile Joey Leone has stirred up some bad blood with the Forellis.
+[MOB45_M]
+Lance, don't be like this. Now I'm warning you.
-[FM2_S]
-Every day they're losing men and influence in the city.
+[MOB45_N]
+Do you hear me? Just relax, take a few days off. Okay? I'll talk to you.
-[FM2_T]
-Salvatore is becoming dangerous and paranoid. He suspects everybody and everything.
+[MOB46_A]
+Yo, Tommy! It's Lance.
-[FM2_U]
-With loyalty like yours, what has he possibly got to worry about.
+[MOB46_B]
+Yeah?
-[FM2_1]
-~g~There's Curly Bob!
+[MOB46_C]
+Oh, nice to hear from you, Lance. Come on, man, be cool, be cool.
-[FM2_2]
-~g~Curly's left the club, tail him!
+[MOB46_D]
+I'm in the middle of something. What do you want?
-[FM2_5]
-~g~Take him to Portland Harbor.
+[MOB46_E]
+Nothing. Just to say, you know. Look Tommy, we can do this thing.
-[FM2_6]
-~r~Curly won't get into a smashed-up taxi!
+[MOB46_F]
+You and me, no problem. You know what I mean?
-[FM2_7]
-~r~Curly's spooked! The meeting's off!
+[MOB46_G]
+We're going to have to do it, 'cause otherwise, we're going to be dead, Lance.
-[FM2_8]
-~g~Whack Curly Bob!
+[MOB46_H]
+We're in too far now. But thanks for the call. I'll speak to you later.
-[FM2_9]
-~r~Curly Bob's dead!
+[MOB_47A]
+Tommy, Lance, we got big problems. Come down here. Right away.
-[FM2_10]
-~r~Curly got away!
+[MOB52_A]
+Hey Leo, I think we got a buyer for Diaz's merchandise.
-[FM2_11]
-~g~Park out the front of Luigi's Club, Curly Bob will be leaving shortly.
+[MOB52_B]
+You gotta give him a ring, man, set up the deal, you know?
-[FM2_12]
-~r~He gave you the slip!
+[MOB52_C]
+Where are you now?
-[FM3_A]
-~w~We should take these Colombian bastards out,
+[MOB52_D]
+You ok Leo? You sound kinda different.
-[FM3_B]
-~w~but while we're at war with the Triads we ain't strong enough.
+[MOB52_E]
+Just tell me where you are.
-[FM3_C]
-~w~The Cartel has got bottomless funds from pushing that SPANK crap.
+[MOB52_F]
+Who the hell is this? Put Leo on, man!
-[FM3_D]
-~w~If we make an open attack on them, they'll wipe the floor with us.
+[MOB52_G]
+Leo's gone away for a while, he left me in charge.
-[FM3_E]
-~w~They must be making SPANK on that big boat that Curly lead you to.
+[MOB52_H]
+Screw you, man!
-[FM3_F]
-~w~So we gotta use our heads, or rather one head. Your head.
+[MOB54_A]
+Hiya Tommy!
-[FM3_G]
-~w~I'm asking you to destroy that SPANK factory as a personal favor to me, Salvatore Leone.
+[MOB54_B]
+Hi Mercedes, howyadoin'?
-[FM3_H]
-~w~If you do this for me, you will be a made man, anything you want.
+[MOB54_C]
+I got a new apartment up in Vice Point
-[FM3_I]
-~w~Go and see 8-Ball, you'll need his expertise to blow-up that boat.
+[MOB54_D]
+- thought you might want to drop by sometime.
-[FM3_8A]
-~w~Yo my man! Salvatore phoned ahead,
+[MOB54_E]
+I'd love to. I'll catch you later.
-[FM3_8B]
-~w~but a job like this is gonna need a lot of fireworks.
+[MOB55_A]
+Tommy, it's me.
-[FM3_8D]
-~w~but you know with me you get a lot of bang for your buck.
+[MOB55_B]
+Hi Mercedes.
-[FM3_8E]
-~w~Okay, let's do this thing!
+[MOB55_C]
+Tommy, I so bored, when we going to have some fun?
-[FM3_8F]
-~w~I can set this baby to detonate, but I still can't use a piece with these hands.
+[MOB55_D]
+What do you mean?
-[FM3_8G]
-~w~Here, this rifle should help you pop some heads!
+[MOB55_E]
+Well, I know you're busy fighting and killing and corrupting people,
-[FM3_4]
-~g~Stop the vehicle and let 8-Ball out!
+[MOB55_F]
+but I just want to have some fun. So don't forget about me, you hear?
-[FM3_7]
-~r~8-Ball's been iced!
+[MOB56_A]
+Tommy, I hear you kill Ricardo Diaz.
-[FM3_8]
-~r~The guards have been alerted!
+[MOB56_B]
+there was an unfortunate fire at his mansion.
-[FM4_A]
-~w~It's my favorite cleaner.
+[MOB56_C]
+I think he burnt to death in an acrylic shirt.
-[FM4_B]
-~w~I'm proud of you my boy, you kicked the shit out of those grease balls.
+[MOB56_D]
+Tommy, I so proud of you. I knew you were a real man.
-[FM4_C]
-~w~I've got just one little job for you before we can all celebrate.
+[MOB56_E]
+He awful trouser stain of a man, you make me so proud to be your friend.
-[FM4_D]
-~w~There's a car around the block from Luigi's club.
+[MOB56_F]
+No, I know you going to be busy trying to take over this town,
-[FM4_E]
-~w~The inside is covered in brains.
+[MOB56_G]
+but don't forget about me, you hear?
-[FM4_F]
-~w~We had to help some guy make up his mind and it proved a little messy.
+[MOB57_A]
+It's merceedes. I no longer love you Tommy.
-[FM4_H]
-~w~Take it to the crusher before the cops find it.
+[MOB57_B]
+I no longer do. Honest. 'cause you no longer nice to Mercedes.
-[AM3]
-'PAPARAZZI PURGE'
+[MOB57_C]
+You no longer treat her like a lady. You ignore me and I hate you.
-[AM4]
-'PAYDAY FOR RAY'
+[MOB57_D]
+I insist you come to see me right away!
-[AM5]
-'TWO-FACED TANNER'
+[MOB58_A]
+Tommy.
-[AM1_A]
-We have certain issues to clear up before we can continue any form of relationship,
+[MOB58_B]
+Hey Mercedes.
-[AM1_B]
-business or otherwise. Lets lay our cards on the table.
+[MOB58_C]
+Hey indeed Mr. Tough Guy. I real angry with you Tommy.
-[AM1_C]
-I am Yakuza and I know you worked for Salvatore Leone's family.
+[MOB58_D]
+Never make me hang out with Jezz Torrent again.
-[AM1_D]
-I can give you work with our organization,
+[MOB58_E]
+He is pathetic. Half way through he starts crying about his doggie
-[AM1_E]
-But first you must prove to me that your ties with the Mafia are truly broken.
+[MOB58_F]
+that died when he was 7 years old and that his mommy never loved him.
-[AM1_G]
-Make sure he doesn't reach his club alive.
+[MOB58_G]
+And Tommy. He wear a wig and a bra in private.
-[AM1_H]
-Meanwhile Maria and I will catch up on old times.
+[MOB58_H]
+I not very happy with you!
-[AM1_I]
-Oh..Asuka, you've got a massager.
+[MOB59_A]
+Ooh Tommy, its Mercedes.
-[AM1_J]
-That's not a massager.
+[MOB59_B]
+I just want to say, I have so much fun on that film set.
-[AM1_1]
-~g~Salvatore is now leaving Luigi's!
+[MOB59_C]
+Anything else you have like that, you let me know.
-[AM1_2]
-~r~You have been spotted!
+[MOB59_D]
+I really mean that. I always wanted to be an actress.
-[AM1_3]
-~r~You've missed Salvatore!
+[MOB59_E]
+I think I learn a lot about the dramatic process.
-[AM1_4]
-~r~Nice going, you scared off the target! Call yourself a hitman?
+[MOB59_F]
+It so enlightening! Thank you. Thank you. I see you real soon. Adios.
-[AM1_5]
-~g~Get to the Red Light District and wait for Salvatore to leave the club.
+[MOB_99]
+Get to the payphone at location.
-[AM1_7]
-~r~Salvatore's home, safe and sipping a cocktail. Ain't no one gonna call you the 'Jackal'!
+[MOB_98]
+Get to the payphone at location.
-[AM1_8]
-~g~Salvatore will be leaving Luigi's at about ~1~:~1~
+[MOB_97]
+Get to the payphone at location.
-[AM2_4]
-~g~They seen you coming like a dayglow elephant!
+[MOB_96]
+Get to the payphone at location.
-[AM3_A]
-A reporter has been nosing around.
+[MOB_95]
+Get to the payphone at location.
-[AM3_B]
-Maria and I have taken a little holiday together until you can get rid of this perverted voyeur.
+[A_TIME]
++~1~ seconds
-[AM4_A]
-It's my handsome handyman!
+[DODO_FT]
+You flew for ~1~ seconds!
-[AM4_B]
-Maria's all tied up at the moment but I'll tell her you called.
+[GA_8]
+Use the detonator to activate the bomb.
-[AM4_C]
-Who's that? Asuka? I know I've been a naughty girl but I really need to pee! OK?
+[GA_10]
+Nice one. Here's your $~1~
-[AM4_D]
-It's time you met our man inside the LPD.
+[GA_11]
+We got these wheels already. It's worthless to us!
-[AM4_E]
-Here's his payment for the last little job he did for us.
+[GA_12]
+Bomb armed
-[AM4_F]
-He is understandably cautious.
+[GA_13]
+Delivered like a pro. Complete the list and there'll be a bonus for you.
-[AM4_G]
-Get to the pay phone in Torrington as quick as you can and await his instructions.
+[GA_14]
+All the cars. NICE! Here's a little something.
-[AM5_A]
-Maria and I have gone shopping.
+[GA_15]
+Hope you like the new color.
-[AM5_B]
-Our source in the police has informed us that one of our drivers is a strangely animated undercover cop!
+[GA_16]
+Respray is complementary.
-[AM5_C]
-He's more or less useless out of his car, so we've tagged it with a tracer.
+[GA_19]
+We're not interested in that model.
-[AM5_D]
-Make him bleed!
+[GA_20]
+We got more of these than we can shift. Sorry man, no deal.
-[AM5_1]
-Tanner's on to you!
+[CHASE]
+Highest media attention
-[AS1]
-'BAIT'
+[CHASE1]
+Ignored
-[AS2]
-'ESPRESSO-2-GO!'
+[CHASE2]
+Boring
-[AS4]
-'RANSOM'
+[CHASE3]
+Vaguely interesting
-[AS1_A]
-~w~Miguel seems to think I'm mistreating him.
+[CHASE4]
+Local paper Page 7
-[AS1_B]
-~w~Still, he's revealed the extent to which Catalina fears your quest for revenge.
+[CHASE5]
+Front page of local paper
-[AS2_A]
-~w~We underestimated Catalina's plans for SPANK.
+[CHASE6]
+Vice Courier Page 2
-[AS2_B]
-~w~It reaches far beyond the Yardies selling it on the street corners.
+[CHASE7]
+Vice Courier Front page
-[AS2_D]
-~w~They've been selling SPANK through the street stalls.
+[CHASE8]
+Local TV 3am
-[AS2_1]
-~g~All espresso stalls in Portland wrecked!!
+[CHASE9]
+Local TV news
-[AS2_2]
-~g~All espresso stalls in Staunton Island wrecked!!
+[CHASE10]
+Local TV Live coverage
-[AS2_3]
-~g~All espresso stalls in Shoreside Vale wrecked!!
+[CHASE11]
+UFA Today page 12
-[AS2_4]
-~r~The Cartel have warned their pushers!!
+[CHASE12]
+UFA Today page 4
-[AS2_5]
-~g~There are still espresso stalls in Shoreside Vale and on Staunton Island!
+[CHASE13]
+Picture in UFA Today
-[AS2_6]
-~g~There are still espresso stalls in Shoreside Vale!
+[CHASE14]
+National TV 4am
-[AS2_7]
-~g~There are still espresso stalls on Staunton Island!
+[CHASE15]
+National TV news
-[AS2_8]
-~g~There are still espresso stalls in Portland!
+[CHASE16]
+National TV live coverage
-[AS2_9]
-~g~There are still espresso stalls in Portland and Shoreside Vale!
+[CHASE17]
+International news
-[AS2_10]
-~g~There are still espresso stalls in Portland and on Staunton Island
+[CHASE18]
+National crisis
-[AS2_12]
-~g~Cruise Liberty's districts to find ~b~Espresso-2-Go stalls!
+[CHASE19]
+International crisis
-[AS3_A]
-~W~Do we tighten it some more now, or just wait for it to turn black and fall off?
+[CHASE20]
+World event
-[AS3_B]
-~w~Give it a quick prod...
+[CHASE21]
+Stuff of legends
-[AS3_D]
-~w~My Handyman!
+[CR_1]
+Crane cannot lift this vehicle.
-[AS3_E]
-~w~I was bored so I came over to keep Asuka company.
+[PU_MONY]
+You don't have enough cash.
-[AS3_1]
-~g~Find the ~r~boat~g~ and get to the ~b~marker buoy!
+[CO_ALL]
+You got all of them. Here's a little something...
-[AS3_3]
-~g~Wait for the ~y~plane~g~ to start its approach!
+[FEM_ON]
+ON
-[AS3_5]
-~g~Collect the cargo!
+[FEM_OFF]
+OFF
-[AS3_4]
-~g~Use a rocket launcher to shoot the ~y~plane~g~ down!!
+[FEM_YES]
+Yes
-[AS3_2]
-~b~Get to the runway marker buoys! ~y~The plane is on its final approach!!
+[FEM_NO]
+No
-[AS3_6]
-~g~~1~ OF 8
+[FEC_NA]
+NA
-[KM1]
-'KANBU BUST-OUT'
+[FEC_CWL]
+Cycle Weapon left
-[KM3]
-'DEAL STEAL'
+[FEC_CWR]
+Cycle Weapon right
-[KM4]
-'SHIMA'
+[FEC_LOF]
+Look forward
-[KM5]
-'SMACK DOWN'
+[FEC_TAR]
+Target
-[KM1_A]
-My sister speaks highly of you,
+[FEC_MOV]
+Movement
-[KM1_E]
-though I am yet to be convinced that a gaijin can offer anything but disappointment.
+[FEC_CAM]
+Camera modes
-[KM1_B]
-Perhaps you could help deal with a situation that has me at a disadvantage.
+[FEC_PAU]
+Pause
-[KM1_F]
-Of course failure has its own disgrace.
+[FEC_ENV]
+Enter vehicle
-[KM1_C]
-A Yakuza Kanbu is in custody awaiting transfer for trial.
+[FEC_JUM]
+Jump
-[KM1_G]
-He is a valued member of the family.
+[FEC_ATT]
+Attack or Fire weapon
-[KM1_H]
-Break him out of custody and get him to the dojo at Bedford Point.
+[FEC_RUN]
+Run
-[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_FPC]
+First person camera
-[KM1_1]
-~g~Steal a cop car!
+[FEC_LL]
+Look left
-[KM1_2]
-~g~Rig the car with a bomb!
+[FEC_LB]
+Look behind
-[KM1_3]
-~g~Now get him to the Yakuza dojo.
+[FEC_LR]
+Look right
-[KM1_5]
-~g~Okay now go to the police station.
+[FEC_HOR]
+Horn
-[KM1_6]
-~g~Fit the car with a bomb!
+[FEC_VES]
+Vehicle control
-[KM1_7]
-~g~Authorised police vehicles only!
+[FEC_BRA]
+Brake or Reverse
-[KM1_9]
-~r~You did not use a car bomb to destroy the wall
+[FEC_HAB]
+Hand brake
-[KM1_10]
-~r~The Yakuza Kanbu is dead -along with your honor!
+[FEC_CAW]
+Car weapon
-[KM1_11]
-~r~You brought the heat down on yourself!
+[FEC_ACC]
+Accelerate
-[KM2_A]
-It is impossible to over-estimate the importance of etiquette in this line of work.
+[FEC_CCF]
+Configuration
-[KM2_B]
-To my eternal shame, a man once did me a favor and I have never had the opportunity to repay his kindness.
+[FEC_CF1]
+Setup 1
-[KM2_C]
-The man's weakness is motor cars and he has requested that we acquire him certain models for his collection.
+[FEC_CF2]
+Setup 2
-[KM2_F]
-My honor demands it.
+[FEC_CF3]
+Setup 3
-[KM2_2]
-~g~Car delivered.
+[FEC_CF4]
+Setup 4
-[KM3_A]
-When trouble looms, the fool turns his back, while the wise man faces it down.
+[FEC_CDP]
+Controller Display
-[KM3_B]
-The Colombian Cartel have ignored repeated requests to leave our interests in Liberty well alone.
+[FEC_ONF]
+On foot
-[KM3_C]
-Now they are negotiating terms with the Jamaicans in order to humiliate us further.
+[FEC_INC]
+In car
-[KM3_D]
-They are finalizing a deal across town.
+[FEC_VIB]
+Vibration
-[KM3_F]
-Take one of my men, steal a Yardie car, and go and pay your respects to the Colombians.
+[FEL_ENG]
+English
-[KM3_E]
-Our Honor demands that you leave no one alive.
+[FEL_FRE]
+French
-[KM3_2]
-~g~Go and pick up your contact.
+[FEL_GER]
+German
-[KM3_3]
-~g~The meeting is being held in the hospital parking lot in Rockford!
+[FEL_ITA]
+Italian
-[KM3_4]
-~r~They got away!
+[FEL_SPA]
+Spanish
-[KM3_6]
-~g~Kill them, kill them all!
+[FED_DBG]
+Menu Debug
-[KM3_8]
-~g~You need a Yardie car to get on with the job!
+[FED_RID]
+Reload IDE
-[KM3_9]
-~r~One of the Colombians is dead, the deal's off.
+[FED_RIP]
+Reload IPL
-[KM3_10]
-~r~The contact is dead!
+[FED_PAH]
+Parse Heap
-[KM4_A]
-To be truly strong, it is important that you never show weakness.
+[FED_DFL]
+CTheScripts::DbgFlag
-[KM4_C]
-Go and collect the money immediately, so we can enter it into the casino accounts.
+[FED_DLS]
+Big White Debug Light Switched
-[KM4_1]
-I can't pay you and I wouldn't pay you if I could!
+[FED_SPR]
+Show Ped Road Groups
-[KM4_9]
-Some young gang just jacked out the place! They took everything!
+[FED_SCR]
+Show Car Road Grups
-[KM4_2]
-You guys are useless.
+[FED_SCZ]
+Show Cull Zones
-[KM4_10]
-What kind of Yakuza are YOU anyway...?
+[FED_DSR]
+Debug Streaming Requests
-[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
+[FED_SCP]
+gbShowCollisionPolys
-[KM4_4]
-~g~Punish the gang responsible and retrieve the ~b~protection money~g~!
+[PL_STAT]
+Player stats
-[KM4_7]
-~r~The shopkeeper's breathed his last!
+[PE_WAST]
+People you've wasted
-[KM4_5]
-Donald Love wishes you to drop by his tea garden so you and he can talk.
+[PE_WSOT]
+People wasted by others
-[KM4_6]
-There's the money its all there!
+[TM_BUST]
+Times busted
-[KM4_8]
-~g~Briefcase collected!
+[GNG_WST]
+Gang members wasted
-[KM5_A]
-YOU! How fitting you should choose this moment to show your worthless face!
+[DED_CRI]
+Criminals wasted
-[KM5_B]
-It would appear your attempts to dissuade the Jamaicans
+[PER_COM]
+Percentage completed
-[KM5_B1]
-from becoming bed fellows with the Cartel were wholly inadequate!
+[KGS_EXP]
+Kgs of explosives used
-[KM5_C]
-Yardie pushers line Liberty's streets selling packets of SPANK like they were selling hotdogs!
+[ACCURA]
+Accuracy
-[KM5_D]
-Those Cartel pigs are laughing at us, at me!
+[ST_WEAP]
+Weapon Budget
-[KM5_E]
-I will give you one last chance to prove my sister's faith in you to be well founded!
+[ST_PROP]
+Property Budget
-[KM5_F]
-Run these scumbags into the ground and wash your shame in rivers of our enemies' blood!!!
+[ST_AUTO]
+Auto Repair and Painting Budget
-[KM5_3]
-~r~You failed to kill at least ~1~ yardies.
+[ST_PHOT]
+Photographs Taken
-[KM5_4]
-~g~Congratulations you killed ~1~ Yardies.
+[ST_LOAN]
+Visits From Loan Sharks
-[KM5_5]
-~g~Congratulations you killed ~1~ Yardies. BONUS $~1~
+[ST_STOR]
+Stores Knocked Off
-[RM1]
-'SILENCE THE SNEAK'
+[ST_MOVI]
+Movie Stunts
-[RM3]
-'EVIDENCE DASH'
+[ST_PIZZ]
+Pizza's Delivered
-[RM4]
-'GONE FISHING'
+[ST_GARB]
+Garbage Pickups Made
-[RM5]
-'PLASTER BLASTER'
+[TOP_SHO]
+Top Shooting Range Score
-[RM1_D]
-He's under armed protection in WitSec property down in Newport, some apartment behind the car park.
+[SHO_RAN]
+Shooting Range Rank
-[RM1_E]
-Torch that place, that should flush 'em out, and you'll hunt 'em down, make sure he never talks to nobody.
+[SEAGULL]
+Seagulls Sniped
-[RM1_1]
-~g~Check out the witness protection house.
+[PROPOWN]
+Property Owned
-[RM1_2]
-~g~Take out McAffrey!
+[ST_TIME]
+Playing Time
-[RM2_A1]
-Hey kid over here!
+[ST_FTIM]
+Flight hours
-[RM2_A]
-An old army buddy of mine runs a business in Rockford.
+[ST_PRAN]
+Pilot Ranking
-[RM2_D]
-He's gonna need some back-up and in return he'll give you knock-down rates on any hardware you buy.
+[ST_RAN0]
+Learner
-[RM2_E]
-Ray phoned ahead....but I thought there'd be more of you.
+[ST_RAN1]
+Navigator
-[RM2_F]
-Well, three arms are better than one, so grab whatever you need.
+[ST_RAN2]
+Co Pilot
-[RM2_G]
-~g~Go and check on Phil!
+[ST_RAN3]
+Junior
-[RM2_H]
-~r~Phil has been killed!!
+[ST_RAN4]
+Competent
-[RM2_L]
-Heh-hey! If I'd teamed up with you in Nicaragua maybe I'd still have my arm!
+[ST_RAN5]
+Senior
-[RM2_N]
-Leave the cash behind. Now get out of here, I'll handle the cops.
+[ST_RAN6]
+Ace
-[RM3_D]
-The evidence is being driven across town.
+[ST_RAN7]
+Red baron
-[RM3_E]
-You are going to have to ram that car and collect each little bit of evidence as it falls out.
+[ST_DRWN]
+Fishes Fed
-[RM3_F]
-When you've got it all, leave it in the car and torch it.
+[ST_FASH]
+Fashion Budget
-[RM3_G]
-We're both gonna do pretty well outta this kid.
+[ST_DAMA]
+Property Destroyed
-[RM3_1]
-~g~Leave the evidence in a car then torch the car.
+[TM_DED]
+Hospital visits
-[RM3_4]
-~g~The Prosecution has dropped the evidence!
+[DAYSPS]
+Days passed in game
-[RM3_6]
-~r~The photos will be washed up all over Liberty!
+[NUMSHV]
+Safehouse visits
-[RM3_7]
-~g~Now torch the car!
+[MXCARD]
+Max. INSANE Jump dist. (ft)
-[RM4_A]
-I think my partner's a rat.
+[MXCARJ]
+Max. INSANE Jump height (ft)
-[RM4_C]
-He goes fishing out of his boat near the lighthouse on Portland Rock most nights.
+[MXCARDM]
+Max. INSANE Jump dist. (m)
-[RM4_D]
-Steal a police boat and make sure his back stabbing plans are sunk!
+[MXCARJM]
+Max. INSANE Jump height (m)
-[RM4_1]
-~g~Go and steal a police boat.
+[MXFLIP]
+Max. INSANE Jump flips
-[RM4_2]
-~g~Get to the lighthouse and 'rub out' Ray's partner!
+[MXJUMP]
+Max. INSANE Jump rotation
-[RM5_A]
-You useless bastard!
+[BUL_FIR]
+Bullets fired
-[RM5_A1]
-You totally messed up! My ass is on the line and you can't even kill a god damned fly.
+[BUL_HIT]
+Bullets that hit
-[RM5_B]
-I paid you good money to kill that witness and he ain't dead!
+[SPRAYIN]
+Sprayings
-[RM5_B1]
-And today he's gonna make a Federal Deposition!
+[BSTSTU]
+Best INSANE stunt so far
-[RM5_C]
-He's being moved any second now from the Carson General Hospital up in Rockford.
+[INSTUN]
+Insane stunt
-[RM5_D]
-If he squeals, I squeal....
+[PRINST]
+Perfect insane stunt
-[RM5_E]
-so go do the job you were paid for!
+[DBINST]
+Double insane stunt
-[RM5_1]
-~g~Intercept the ambulance.
+[DBPINS]
+Perfect double insane stunt
-[RM5_2]
-~g~You've been spotted!!
+[TRINST]
+Triple insane stunt
-[RM5_3]
-~g~It was a decoy!
+[PRTRST]
+Perfect triple insane stunt
-[RM5_4]
-~g~Bullets won't get through that armored bodycast!!
+[QUINST]
+Quadruple insane stunt
-[RM5_5]
-~g~That armored bodycast is flame retardant!!
+[PQUINS]
+Perfect quadruple insane stunt
-[RM5_7]
-~r~Witness has been delivered!!
+[NOSTUC]
+No INSANE stunts completed
-[RM5_8]
-~g~Witness has drowned!!
+[NOUNIF]
+Unique Jumps completed
-[LOVE2]
-'WAKA-GASHIRA WIPEOUT!'
+[NMISON]
+Mission attempts
-[LOVE3]
-'A DROP IN THE OCEAN'
+[PASDRO]
+Passengers dropped off
-[LOVE1_A]
-First of all, let me thank you for dealing with that personal matter.
+[MONTAX]
+Cash made in taxi
-[LOVE1_F]
-People will read something into anything these days.
+[DAYPLC]
+Daily police spending
-[LOVE1_D]
-They're trying to extort additional funds from me but I don't believe in re-negotiation.
+[CRIMRA]
+Criminal rating:
-[LOVE1_E]
-A deal is a deal, so they'll not see a penny from me.
+[STPR_1]
+The Malibu
-[LOVE1_G]
-Go and rescue my friend, do whatever it takes.
+[STPR_2]
+Print Works
-[LOVE1_2]
-~g~Rescue the Old Oriental Gentleman.
+[STPR_3]
+Film Studio
-[LOVE1_3]
-~g~Take the Old Oriental Gentleman back to Donald Love's building.
+[STPR_4]
+Ice Cream Factory
-[LOVE1_4]
-~g~The Old Oriental Gentleman must be in one of the garages....
+[STPR_5]
+Car Showroom
-[LOVE1_6]
-~r~The Old Oriental Gentleman's guts are all over the street!
+[STPR_6]
+Taxi Company
-[LOVE1_7]
-~g~The gate will only open for a Colombian Gang-car.
+[STPR_7]
+Boatyard
-[LOVE2_A]
-Nothing drives down real estate prices like a good old fashioned gang war,
+[SET1EN]
+SetUp 1. Enabled
-[LOVE2_B]
-apart from an outbreak of plague......but that might be going too far in this case.
+[GMSAVE]
+Save Game
-[LOVE2_C]
-I've noticed the Yakuza and the Colombians are far from friends.
+[FEDS_TB]
+Back
-[LOVE2_D]
-Let's capitalise on this business opportunity.
+[FEST_OO]
+out of
-[LOVE2_E]
-I want you to kill the Yakuza Waka-gashira, Kenji Kasen.
+[FEC_TUC]
+Turret control
-[LOVE2_F]
-Kenji is attending a meeting at the top of the multi-story carpark in Newport.
+[FEC_RS3]
+Radio station cycle (L3 button)
-[LOVE2_G]
-Get a Cartel gangcar and eliminate him!
+[FEC_HO3]
+Horn (L3 button)
-[LOVE2_H]
-The Yakuza must blame the Cartel for this declaration of war.
+[C_FAIL]
+Vigilante mission ended!
-[LOVE2_1]
-~g~Go to Fort Staunton and steal a Colombian gangcar!
+[C_ESCP]
+~r~The suspect has escaped!
-[LOVE2_2]
-~g~Now get to the ~p~multi-storey in Newport~g~ and whack Kenji!
+[C_VIGIL]
+VIGILANTE BONUS!!
-[LOVE2_3]
-~r~If you proceed without a Cartel car you will be identified!!
+[HEAL_A]
+Your ~h~health~w~ is displayed in orange in the top right of the screen.
-[LOVE2_4]
-~r~The Yakuza have identified you!!
+[WRONGCD]
+Incorrect disc. Please insert correct disc.
-[LOVE2_6]
-~r~You've killed all the witnesses!!
+[NOCD]
+The disc tray is empty. Please insert disc.
-[LOVE3_A]
-In these days of moral hypocrisy certain valuable commodities can be hard to import.
+[OPENCD]
+The disc tray is open. Please close the disc tray.
-[LOVE3_C]
-It will drop several packages into the water.
+[CDERROR]
+Error reading the Grand Theft Auto: Vice City DVD
-[LOVE3_D]
-Make sure you pick them up before anyone else does.
+[RESTART]
+Starting new game
-[LOVE3_1]
-~g~Get a ~r~boat~g~ and follow the ~y~plane~g~!
+[GA_3]
+No more freebies. $100 to respray!
-[LOVE4]
-'GRAND THEFT AERO'
+[GA_1]
+Whoa! I don't touch nothing THAT hot!
-[LOVE5]
-'ESCORT SERVICE'
+[GA_1A]
+Come back when you're not so busy...
-[LOVE4_A]
-Thank you for retrieving those packages, but they were only a decoy.
+[HELP9_C]
+Press the~h~ ~k~~PED_FIREWEAPON~ ~w~button to ~h~fire~w~ the sniper rifle.
-[LOVE4_B]
-Sorry about that, but that's sometimes the way in business.
+[TAXI2]
+~r~You're out of time!
-[LOVE4_C]
-My real objective was hidden on the plane all along.
+[PAGEB13]
+Health delivered to hideout
-[LOVE4_F]
-I've paid off the officials.
+[PAGEB14]
+Adrenaline delivered to hideout
-[LOVE4_1]
-~r~The Colombian Cartel is here!!
+[FESZ_CA]
+Cancel
-[LOVE4_2]
-~g~The package is gone! Track down the Colombians and retrieve it.
+[FES_NGA]
+New Game
-[LOVE4_3]
-~g~Panlantic Construction...?
+[FES_CAN]
+Cancel
-[LOVE4_5]
-~g~The package should be in the plane....
+[FESZ_QL]
+All unsaved progress in your current game will be lost. Proceed with loading?
-[LOVE4_6]
-~g~Take the lift up the tower!
+[FESZ_QD]
+Proceed with deleting this save game?
-[LOVE5_B]
-My Oriental friend will need an escort while he takes my latest acquisition to be authenticated.
+[FESZ_QO]
+Proceed with overwriting this save game?
-[LOVE5_1]
-~g~Lets go!
+[T4X4_1]
+'PCJ Playground'
-[LOVE5_2]
-~g~You'll need a car!
+[BMX_1]
+'Trial by Dirt'
-[LOVE5_3]
-~g~Go ahead and scout the exit of the tunnel!
+[BMX_2]
+'Test Track'
-[LOVE5_4]
-~r~Protect the truck!
+[BMXFAIL]
+~r~You failed to set a new record!
-[RM6]
-'MARKED MAN'
+[BMX_REC]
+~g~New Record Set:~1~ !!
-[RM6_A]
-You weren't followed? Good.
+[T4X4_3]
+'GRIPPED!'
-[RM6_B]
-This is it, I'm way over my head and I'm starting to drown here!
+[MM_1]
+'CONE CRAZY'
-[RM6_D]
-I'm a marked man, so I'm getting out of here.
+[T4X4_F]
+~r~You bailed! Too tough for you?!
-[RM6_E]
-Get me to my flight at the airport and I'll make it worth your while!
+[LANDSTK]
+Landstalker
-[RM6_666]
-Take care of my bullet proof Patriot. See you in Miami, Ray
+[IDAHO]
+Idaho
-[CAT1]
-'RANSOM'
+[STINGER]
+Stinger
-[CAT2]
-'THE EXCHANGE'
+[LINERUN]
+Linerunner
-[CAT1_A]
-I've got your precious Maria. If you don't want her face to look like she fell out with the butcher.
+[PEREN]
+Perennial
-[CAT2_F]
-I broke a nail, and my hair's ruined. Can you believe it? This one cost me fifty dollars!
+[SENTINL]
+Sentinel
-[CAT2_G]
-I was so scared, but then I thought to myself, you're a big girl now.
+[RIO]
+Rio
-[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,
+[PATRIOT]
+Patriot
-[CAT2_I]
-because her husband's playing around again and..
+[FIRETRK]
+Firetruck
-[CAT1_E]
-XXXX
+[TRASHM]
+Trashmaster
-[CAT1_F]
-Get to Catalina before the time runs out!
+[STRETCH]
+Stretch
-[CAT_MON]
-~g~You don't have enough money yet. You need $500,000.
+[MANANA]
+Manana
-[BITCH_D]
-~g~Maria's dead!
+[INFERNS]
+Infernus
-[WEATHER]
-FORCE WEATHER
+[VOODOO]
+Voodoo
-[WEATHE2]
-WEATHER NORMAL
+[PONY]
+Pony
-[8001]
-You failed miserably!!
+[MULE]
+Mule
-[1000]
-YOU ARE DEAD
+[CHEETAH]
+Cheetah
-[1001]
-YOU ARE DEAD
+[AMBULAN]
+Ambulance
-[1002]
-YOU ARE DEAD
+[FBICAR]
+FBI Washington
-[1003]
-YOU ARE DEAD
+[MOONBM]
+Moonbeam
-[1004]
-YOU ARE DEAD
+[ESPERAN]
+Esperanto
-[1005]
-BUSTED
+[TAXI]
+Taxi
-[1006]
-BUSTED
+[WASHING]
+Washington
-[1007]
-BUSTED
+[BOBCAT]
+Bobcat
-[1008]
-BUSTED
+[WHOOPEE]
+Mr. Whoopee
-[1009]
-BUSTED
+[BFINJC]
+BF Injection
-[GA_4]
-Car bombs are $1000 each
+[HUNTER]
+Hunter
-[GA_5]
-Your car is already fitted with a bomb.
+[POLICAR]
+Police
-[GA_6]
-Park it, prime it by pressing the ~h~~k~~PED_FIREWEAPON~ button~w~ and LEG IT!
+[ENFORCR]
+Enforcer
-[GA_7]
-Arm with ~h~~k~~PED_FIREWEAPON~ button~w~. Bomb will go off when engine is started.
+[SECURI]
+Securicar
-[GA_8]
-Use the detonator to activate the bomb.
+[BANSHEE]
+Banshee
-[GA_9]
-You collected ~1~ out of 10 special cars
+[PREDATR]
+Predator
-[GA_10]
-Nice one. Here's your $~1~
+[BUS]
+Bus
-[GA_11]
-We got these wheels already. It's worthless to us!
+[RHINO]
+Rhino
-[GA_12]
-Bomb armed
+[BARRCKS]
+Barracks OL
-[GA_13]
-Delivered like a pro. Complete the list and there'll be a bonus for you.
+[CUBAN]
+Cuban Hermes
-[GA_14]
-All the cars. NICE! Here's a little something.
+[HELI]
+Helicopter
-[GA_15]
-Hope you like the new color.
+[DODO]
+Dodo
-[GA_16]
-Respray is complementary.
+[COACH]
+Coach
-[GA_19]
-We're not interested in that model.
+[CABBIE]
+Cabbie
-[GA_20]
-We got more of these than we can shift. Sorry man, no deal.
+[STALION]
+Stallion
-[CR_1]
-Crane cannot lift this vehicle.
+[RUMPO]
+Rumpo
-[PU_MONY]
-You don't have enough cash.
+[RCBANDT]
+RC Bandit
-[CO_ALL]
-You got all of them. Here's a little something...
+[ROMERO]
+Romero's Hearse
-[PAUSED]
-GAME PAUSED
+[PACKER]
+Packer
-[HEALTH1]
-Get outta here! You're perfectly healthy.
+[ADMIRAL]
+Admiral
-[HEALTH2]
-Healthcare costs.
+[SQUALO]
+Squalo
-[HEALTH3]
-I'll just fix you up.
+[SEASPAR]
+Sea Sparrow
-[HEALTH4]
-That will be $250.
+[PIZZABO]
+Pizza Boy
-[FEB_STA]
-Stats
+[GANGBUR]
+Gang Burrito
-[FEB_BRI]
-Briefs
+[TROPIC]
+Tropic
-[FEB_CON]
-Controls
+[SPEEDER]
+Speeder
-[FEB_AUD]
-Audio
+[REEFER]
+Reefer
-[FEB_DIS]
-Display
+[FLATBED]
+Flatbed
-[FEB_LAN]
-Language
+[YANKEE]
+Yankee
-[FEP_STA]
-STATS
+[CADDY]
+Caddy
-[FEP_BRI]
-BRIEFS
+[ZEBRA]
+Zebra Cab
-[FEP_CON]
-CONTROLS
+[TOPFUN]
+Top Fun
-[FEP_AUD]
-AUDIO
+[SKIMMER]
+Skimmer
-[FEP_DIS]
-DISPLAY
+[PCJ600]
+PCJ 600
-[FEP_LAN]
-LANGUAGE
+[PHOENIX]
+Phoenix
-[FEF_ST1]
-Who's the bad man?
+[FAGGIO]
+Faggio
-[FEF_ST2]
-How much havoc have you caused
+[FREEWAY]
+Freeway
-[FEF_BR1]
-Lost the plot?
+[RCBARON]
+RC Baron
-[FEF_CO1]
-Need more control, freak?
+[RCRAIDE]
+RC Raider
-[FEF_CO2]
-Choose the best contoller set-up for your playing style
+[GLENDAL]
+Glendale
-[FEF_SA1]
-Keep your place in the pile!
+[OCEANIC]
+Oceanic
-[FEF_SA2]
-Save and load your games
+[SANCHEZ]
+Sanchez
-[FEF_AU1]
-Pump up the volume!
+[SPARROW]
+Sparrow
-[FEF_AU2]
-Select a radio station and sound effect
+[LOVEFIS]
+Love Fist
-[FEF_DI1]
-Change the game!
+[COASTG]
+Coast Guard
-[FEF_DI2]
-Customize the game for your TV
+[DINGHY]
+Dinghy
-[FEF_LA1]
-What you talking about willis?
+[HERMES]
+Hermes
-[FEF_LA2]
-Choose your preferred parlance
+[SABRE]
+Sabre
-[FEB_PMB]
-Previous Mission Briefs:
+[SABRETU]
+Sabre Turbo
-[FEC_NA]
-NA
+[WALTON]
+Walton
-[FEC_CWL]
-Cycle Weapon left
+[REGINA]
+Regina
-[FEC_CWR]
-Cycle Weapon right
+[COMET]
+Comet
-[FEC_LOF]
-Look forward
+[DELUXO]
+Deluxo
-[FEC_TAR]
-Target
+[BURRITO]
+Burrito
-[FEC_MOV]
-Movement
+[SPAND]
+Spand Express
-[FEC_CAM]
-Camera modes
+[MARQUIS]
+Marquis
-[FEC_PAU]
-Pause
+[BAGGAGE]
+Baggage Handler
-[FEC_ENV]
-Enter vehicle
+[KAUFMAN]
+Kaufman Cab
-[FEC_JUM]
-Jump
+[COASTMA]
+Coastguard Maverick
-[FEC_ATT]
-Attack or Fire weapon
+[MAVERIC]
+Maverick
-[FEC_RUN]
-Run
+[RANCHER]
+Rancher
-[FEC_FPC]
-First person camera
+[FBIRANC]
+FBI Rancher
-[FEC_LL]
-Look left
+[VIRGO]
+Virgo
-[FEC_LB1]
-Look
+[GREENWO]
+Greenwood
-[FEC_LB2]
-behind
+[HOTRING]
+Hotring Racer
-[FEC_LB]
-Look behind
+[BLISTAC]
+Blista Compact
-[FEC_LR]
-Look right
+[FEST_DF]
+Dist. traveled on foot (miles)
-[FEC_HOR]
-Horn
+[FEST_DC]
+Dist. traveled by car (miles)
-[FEC_VES]
-Vehicle control
+[FESTDFM]
+Distance traveled on foot (m)
-[FEC_RSC]
-Radio station cycle
+[FESTDCM]
+Distance traveled by car (m)
-[FEC_BRA]
-Brake or Reverse
+[TOT_DIS]
+Total distance traveled (miles)
-[FEC_HAB]
-Hand brake
+[TOTDISM]
+Total distance traveled (m)
-[FEC_CAW]
-Car weapon
+[DISTHEL]
+Dist. traveled by helicopter (miles)
-[FEC_ACC]
-Accelerate
+[DISTHEM]
+Distance traveled by helicopter (m)
-[FEC_SMT]
-Special mission trigger
+[DISTBOA]
+Dist. traveled by boat (miles)
-[FEC_CCF]
-Configuration:
+[DISTBOM]
+Distance traveled by boat (m)
-[FEC_CF1]
-Setup1
+[FEST_LS]
+People saved in an Ambulance
-[FEC_CF2]
-Setup2
+[FEST_CC]
+Criminals killed on Vigilante Mission
-[FEC_CF3]
-Setup3
+[FEST_FE]
+Total fires extinguished
-[FEC_CF4]
-Setup4
+[FEST_RP]
+Rampages passed
-[FEC_CDP]
-Controller Display:
+[FEST_MP]
+Missions passed
-[FEC_ONF]
-On Foot
+[FEST_BB]
+Bling-bling Scramble:
-[FEC_INC]
-In Car
+[FEST_H0]
+Most checkpoints
-[FEC_VIB]
-Vibration:
+[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]
+Press the ~h~~k~~PED_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
-[DIAB1_3]
-~r~You couldn't win a raffle, LOSER!
+[RACE3]
+~g~2
-[DIAB1_2]
-~g~Congratulations you won, with an incredible time of ~1~ seconds.
+[RACE4]
+~g~1
+
+[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.
+~b~4th
-[DIAB2_2]
-~g~Find an icecream van.
+[RACETM]
+~b~RACE TIME: ~1~:~1~
-[DIAB2_3]
-~g~Park the icecream van down at Atlantic Quays.
+[RACETM2]
+~b~RACE TIME: ~1~:0~1~
-[DIAB2_4]
-~g~Press the ~w~~k~~VEHICLE_HORN~ button ~g~to activate the Icecream jingle.
+[RACEFA]
+~r~You failed to win the race!
-[DIAB2_6]
-~g~Press the ~w~~k~~VEHICLE_HORN~ button ~g~to activate the Icecream jingle.
+[TEX1_5]
+~r~He got away!
-[DIAB2_7]
-~g~Press the ~w~~k~~VEHICLE_HORN~ button ~g~to activate the Icecream jingle.
+[SEG3_2]
+~g~Get to the van that contains the RC Raider and remote timed bombs.
-[DIAB2_5]
-~g~Exit the van then use the remote to detonate the Icecream van.
+[SEG3_3]
+~g~You must use the RC RAIDER to transport 4 bombs to 4 target zones on the building site.
-[YD1]
-'BLING-BLING SCRAMBLE'
+[SERG3_5]
+~g~You can only carry one bomb at a time and cannot pick up successfully planted bombs.
-[YD2]
-'UZI RIDER'
+[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.
-[YD3]
-'GANGCAR ROUND-UP'
+[SEG3_8]
+~g~All 4 bombs must be located at the 4 target zones to pass the mission and demolish the building.
-[YD4]
-'KINGDOM COME'
+[SEG3_9]
+~g~You hit the target! 3 more to go.
-[YD_P]
-King Courtney would like a word. Get to the payphone in Aspatria!!
+[SEG3_10]
+~g~You hit the target! 2 more to go.
-[YD1_A]
-~w~This is King Courtney.
+[SEG3_11]
+~g~You hit the target! Just 1 more to go!
-[YD1_A1]
-~w~My Yardie posse could do with a driver and you've got a reputation for hot moves.
+[SEG3_12]
+~r~You missed the target! Go get a bomb!
-[YD1_B]
-~w~Get to the waste ground opposite the stadium in a car and wait for the other hopefuls.
+[SEG3_13]
+~g~Drop the bomb at a target zone.
-[YD1_C]
-~w~I've got men watching checkpoints all over Staunton.
+[SEG3_14]
+~r~You ran out of time and failed to demolish the building.
-[YD1_D]
-~w~First driver to a checkpoint gets a Grand, then it's on to the next stop.
+[SEG3_15]
+~r~Your RC Raider has been destroyed! How you gonna transport the bombs now?
-[YD1_D1]
-~w~If you get more checkpoints than any other driver, I could have some work for you.
+[AVERY]
+AVERY MISSIONS
-[YD1_E]
-~g~Prepare to race!
+[ASM]
+ASSASSIN MISSIONS
-[YD1_F]
-~g~You jumped the start -I like your style!!
+[ASM_1]
+ASSASSIN MISSION 1
-[YD1_G]
-~r~This is a CAR RACE. You need a CAR 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.
-[YD1GO]
-~g~GO!!
+[ASM1_2]
+~g~Get to the payphone outside the Mall in Washington.
-[YD1_1]
-~r~1
+[ASM1_3]
+~g~Carl Pearson, Pizza Delivery Man. He must not complete his deliveries.
-[YD1_2]
-~r~2
+[ASM1_4]
+~g~Kill the Pizza Delivery Man before he completes his deliveries.
-[YD1_3]
-~r~3
+[ASM_2]
+ASSASSIN MISSION 2
-[YD1_BON]
-$1000!!
+[ASM_3]
+ASSASSIN MISSION 3
-[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!
+[ASM3_A]
+TEXT NO LONGER NEEDED
-[Y1_3RD]
-~r~3rd with ~1~ successful checkpoints. ~r~I thought you said you were good!
+[ASM3_B]
+TEXT NO LONGER NEEDED
-[Y1_LAST]
-~r~You were last! ~r~You wasted my time FOOL!
+[ASM3_1]
+~g~Go and get the weapon Mr. Black has left for you.
-[Y1_J1ST]
-~y~Joint 1st with ~1~ successful checkpoints. ~y~Good, but you gotta be the best to drive for Queen Lizzy!
+[ASM3_2]
+~g~Don't get too close to the target or he may spot you!
-[Y1_J2ND]
-~r~Joint 2nd with ~1~ successful checkpoints. You drive like a crazed monkey!
+[ASM3_3]
+~g~For a quick safe kill find a secluded spot nearby with a clear view of your target.
-[Y1JLAST]
-~r~Joint last! You talk like a driver, but you drive like a talker!
+[ASM3_4]
+~g~He's seen you! Better waste him any way you can!
-[Y1_TEST]
-CAR IN WATER!!
+[ASM3_5]
+~g~Marcus Hammond is working on an advertising board in Washington.
-[YD2_A]
-~w~I need to see if you're capable of doing my dirty work.
+[ASM3_6]
+~g~Franco Carter is working for DBP Security off Ocean Drive.
-[YD2_A1]
-~w~See if you can be trusted.
+[ASM3_7]
+~g~Dick Tanner is situated near the Jewelry shop in Vice Point.
-[YD2_B]
-~w~Two of my boys will be there any second to take you for a ride,
+[ASM3_8]
+~g~Nick Kong is situated near Washington Beach.
-[YD2_B1]
-~w~see if you are who you say you are.
+[ASM3_9]
+~g~Stuntman Driver is situated in Washington.
-[YD2_C]
-~w~We're going for a little ride into Hepburn Heights, whack us some filthy Diablos been dissing Queen Lizzy.
+[ASM3_10]
+~r~You failed to kill them all.
-[YD2_CC]
-~w~Here, you'll need a 'piece'.
+[ASM_4]
+ASSASSIN MISSION 4
-[YD2_D]
-~w~You do the driving and shooting. We'll make sure you don't get cold feet.
+[ASM4_1]
+~g~Go get the rifle left for you in the foliage outside the airport terminal.
-[YD2_E]
-~w~Let's drive!!
+[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.
-[YD2_F]
-~r~He's bailed out on us, cap his yellow ass!!!
+[ASM4_3]
+~g~Watch the woman on the balcony above the check-in desks inside the airport terminal. DO NOT KILL HER.
-[YD2_G1]
-~w~Hepburn Heights..Let's kill me some filthy Diablos...
+[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.
-[YD2_G2]
-~w~But remember, ~r~You don't leave this car!!
+[ASM4_5]
+~g~Get the briefcase!
-[YD2_H]
-~w~OK, Get us back to Yardie turf! GO GO GO!!
+[ASM4_6]
+~g~Take the briefcase to Ammu-Nation in Downtown.
-[YD2_L]
-~w~You did good, Reaperman!
+[ASM4_7]
+~r~You killed the woman, you fool!
-[YD2_M]
-~r~He's wrecked my car! Waste him!
+[ASM4_8]
+~r~The target heard you firing your weapon! The deal is off!
-[YD2_N]
-~w~Get your ass back in this car!
+[ASM4_9]
+~r~The target has boarded his flight!
-[YD3_A]
-I want you to boost some gang cars
+[ASM4_11]
+~r~The target has seen you! The deal is off!
-[YD3_A1]
-so we can do hits on our enemies' turf.
+[ASM4_13]
+~g~He's spotted you and is making a run for it, nail him and get the briefcase!
-[YD3_B]
-I need a Mafia Sentinel,
+[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_B1]
-a Yakuza Stinger and a
+[ASM_5]
+ASSASSIN MISSION 5
-[YD3_B2]
-Diablo Stallion so we can hit any gang in Liberty.
+[KICK]
+KICKSTART
-[YD3_C]
-Drop them off at the garage in Newport and remember,
+[KICK1_3]
+~g~Number of times foot put down: ~1~
-[YD3_C1]
-they're no use to us wrecked!!
+[KICK1_4]
+~g~Time penalty: ~1~ seconds
-[YD3_D]
-Spare text label
+[BANK]
+BANKJOB MISSIONS
-[YD3_E]
-~r~You've already boosted a diablo gangcar!
+[BANK1]
+BANKJOB MISSION 1
-[YD3_F]
-~r~You've already boosted a Mafia gangcar!
+[BANK2]
+BANKJOB MISSION 2
-[YD3_G]
-~r~You've already boosted a Yakuza gangcar!
+[BJM2_21]
+~g~Hit as many targets as you can while your ammo lasts.
-[YD3_H]
-~g~Diablo gangcar boosted!
+[BANK3]
+BANKJOB MISSION 3
-[YD3_I]
-~g~Mafia gangcar boosted!
+[BJM3_1]
+~g~Get a fast car and get to the starting grid.
-[YD3_J]
-~g~Yakuza gangcar boosted!
+[BNK4_2A]
+Boys at the car lot did a great job on this baby.
-[YD3_K]
-~r~The car's nearly wrecked! Get it repaired!
+[BNK4_3G]
+Oh crap, now the cops are onto us!
-[YD3_L]
-~g~Take it to the ~p~garage!
+[BNK4_3H]
+- and we're not even there yet.
-[YD3_M]
-~r~You've flipped it! Get another one!
+[BNK4_3K]
+We'll have to lose the cops first...
-[YD4_A]
-Listen up!
+[BNK4_3L]
+Christ Tommy, you trying to kill us all!?
-[YD4_A1]
-Get over to Bedford Point.
+[BNK4_3N]
+Everything I care about gets trashed!
-[YD4_A2]
-There's a stash in an old car I need pronto!
+[BNK4_26]
+Hot damn! Here they come!
-[YD4_B]
-LETTER: I hear you've been a busy boy. Well I've been a busy girl.
+[BNK4_32]
+Use explosives to open the deposit boxes!
-[YD4_C]
-I think it's time you witnessed the real power of 'SPANK'! Besos y fuderes, Catalina, xxx.
+[BNK4_36]
+Where's Cam?
-[YD4_D]
-PS: DIE PEEG DOG, DIE!!
+[BNK4_37]
+History...
-[YD4_1]
-~g~SPANKED-up madmen!
+[BNK4_38]
+That's the last of them. GO! GO! GO!
-[YD4_2]
-~g~Destroy the madmens' vans!!
+[BNK_39]
+Shit! Where's Hilary?
-[HM_1]
-'UZI MONEY'
+[BK4_40A]
+I'll give him abandonment issues!
-[HM_2]
-'TOYMINATOR'
+[BNK4_42]
+Hey guys! Get in! I got you covered!
-[HM_3]
-'RIGGED TO BLOW'
+[BNK4_43]
+I've got our asses covered, DRIVE!
-[HM_5]
-'RUMBLE'
+[BNK4_44]
+We made it! We're rich! RICH!
-[HOOD1_A]
-Get to the payphone in Wichita Gardens and we'll talk business.
+[BNK4_45]
+Shame Cam didn't make it, he was a good guy!
-[HM1_A]
-Yo! This is D-Ice of the Red Jacks!
+[BNK4_46]
+Yeah. Still... more for us!
-[HM1_C]
-These young punks, they come onto the streets and they got nothing but guns and SPANK on their minds.
+[BNK4_47]
+Damned straight! YEEEEHAAAH!
-[HM1_3]
-~g~The 'Nines' walk their turf in Wichita Gardens.
+[BNK4_48]
+Tommy, would you like a massage?
-[HM2_3]
-If you hit a vehicle's wheels the RC buggy will detonate!
+[BNK4_49]
+Well, Hi there, Mercedes! Yeah, I'm a little tense...
-[HM2_4]
-If it goes out of range the RC buggy will detonate!
+[BNK450A]
+What'd I tell you Tommy? What'd I tell you? Bent SWAT better watch out when Kent Paul is in town.
-[HM2_5]
-~r~Out of range!
+[BNK450B]
+Come on, gimme a bigger slice, mate, c'mon. I gotta get some new threads.
-[HM3_1]
-~g~Get to the garage but watch out if the car takes too much damage it will blow!
+[BNK4_51]
+You look fine to me.
-[HM3_2]
-~g~Take the car back it has to be in perfect condition - no damage!
+[KENT]
+KENT PAULS MISSIONS
-[HM3_3]
-~g~Get the car repaired!
+[KENT1]
+KENT PAUL MISSION1
-[HM4_D]
-~g~Get a vehicle!
+[COUNT]
+COUNTERFEITING MISSIONS
-[HM4_E]
-TEXT NO LONGER REQUIRED
+[COUNT1]
+COUNTERFEITING MISSION 1
-[HM4_1]
-~g~Head to the location where the cargo is scattered, you need to collect 30 pieces of bullion.
+[COUNT2]
+COUNTERFEITING MISSION 2
-[HM4_2]
-~g~Remember when the vehicle becomes too heavy and slow goto the garage and drop off the cargo.
+[BIKE]
+THE BIKER GANG MISSIONS
-[HM5_3]
-~r~You were told to use a baseball bat only!
+[BIKE1]
+BIKER MISSION 1
-[HM5_4]
-~r~Your contact's dead!
+[BIKE2]
+BIKER MISSION 2
-[MEA1]
-'THE CROOK'
+[BIKE3]
+BIKER MISSION 3
-[MEA2]
-'THE THIEVES'
+[GOAWAY1]
+~g~Come back when you have finished the Haitian gang missions.
-[MEA3]
-'THE WIFE'
+[HAIT]
+THE HAITIAN GANG MISSIONS
-[MEA4]
-'HER LOVER'
+[HAIT1]
+HAITIAN MISSION 1
-[MEAT1_A]
-A friend said you could fix some problems I got. Get to the payphone in Trenton if you think you can help.
+[HAIT2]
+HAITIAN MISSION 2
-[MEA1_B3]
-~g~Go and meet the Bank Manager.
+[HAIT3]
+HAITIAN MISSION 3
-[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.
+[HAM3_6]
+~g~Use the sniper rifle I have left to accomplish your task.
-[MEA1_1]
-~r~The Bank Manager's dead!
+[ROCK]
+THE ROCKBAND GANG MISSIONS
-[MEA1_2]
-~r~You were told to crush the vehicle!
+[ROK1_4]
+~g~Ok, I think this is what you were after...
-[MEA1_3]
-~g~Get out of the car!
+[ROK1_1E]
+~g~It'll cost more than you've got!
-[MEA1_4]
-~r~You have left the Bank Manager behind!
+[ROK1_1F]
+~g~Come back when you got the money.
-[MEA2_B3]
-~g~Go and meet the thieves.
+[RBM2_6]
+~g~Wow! She's a bloke, stop him!
-[MEA2_B4]
-~g~Take them to the Bitch'n' Dog Food Factory
+[ROCK3]
+ROCKBAND MISSION 3
-[MEA2_B6]
-~g~Get the car resprayed to get rid of any evidence.
+[RBM3_5]
+~g~Take Love Fist to the venue.
-[MEA2_1]
-~r~You were told to crush the vehicle!
+[CUBANM]
+THE CUBAN GANG MISSIONS
-[MEA2_2]
-~r~A thief's dead!
+[CUBAN1]
+CUBAN MISSION 1
-[MEA2_4]
-~r~You have left a thief behind!
+[CUBAN2]
+CUBAN MISSION 2
-[MEA3_B3]
-~g~Go and collect Mrs. Chonks
+[CUB2_10]
+~r~You are supposed to be killing Haitians, not Cubans.
-[MEA3_B6]
-~g~Take the car and dump it into the sea, this will get rid of any evidence.
+[CUBAN3]
+CUBAN MISSION 3
-[MEA3_1]
-~r~The wife's dead!
+[CUBAN4]
+CUBAN MISSION 4
-[MEA3_2]
-~r~You were supposed to dump the vehicle in the water!
+[PROT]
+PROTECTION MISSIONS
-[MEA3_3]
-~r~You have left his wife behind!
+[PORN]
+PORN MISSIONS
-[MEA4_B3]
-~g~Pick up his wife's lover
+[PORN1]
+PORN MISSION 1
-[MEA4_B6]
-It's far too late for that Marty. You had your chance, but now I'm taking over the business...
+[POR1_03]
+~r~Candy is dead!
-[MEA4_1]
-~r~Carlos is dead!
+[PORN2]
+PORN MISSION 2
-[MEA4_3]
-~r~You have left Carlos the loan shark behind!
+[PORN3]
+PORN MISSION 3
-[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~.
+[PORN4]
+PORN MISSION 4
-[LOVE6_1]
-~g~Now lead the cops away from the warehouse!
+[PHIL]
+PHIL MISSIONS
-[LOVE6_2]
-~r~You failed to lead the police far enough away!
+[PHIL1]
+PHIL MISSION 1
-[RM4_3]
-~r~Ray's partner has escaped!
+[PHIL2]
+PHIL MISSION 2
-[RM6_C]
-The CIA seem to have a vested interest in SPANK
+[PIZ1_A]
+PIZZA BOY MISSION
-[RM6_C1]
-and they don't like us screwing with the Cartel.
+[CNTBUY1]
+Printworks purchased: $~1~
-[C_PASS]
-THREAT ELIMINATED!
+[CARBUY]
+Car Showroom purchased: $~1~
-[CTUTOR]
-Press the ~h~~k~~TOGGLE_SUBMISSIONS~ button~w~ to toggle Vigilante missions on or off.
+[PORNBUY]
+Film Studio purchased: $~1~
-[CTUTOR2]
-Press the ~h~~k~~TOGGLE_SUBMISSIONS~ button~w~ to toggle Vigilante missions on or off.
+[ICEBUY]
+Ice Cream Factory purchased: $~1~
-[COPCART]
-~g~You have ~1~ seconds to return to a police vehicle before the mission ends.
+[TAXIBUY]
+Taxi Firm purchased: $~1~
-[C_FAIL]
-Vigilante mission ended!
+[BANKBUY]
+The Malibu purchased: $~1~
-[C_CANC]
-~r~Vigilante mission cancelled!
+[BOATBUY]
+Boatyard purchased: $~1~
-[C_ESCP]
-~r~The suspect has escaped!
+[PRNT_NO]
+You cannot buy the Print Works at this time, come back later.
-[C_TIME]
-~r~Your time as a law enforcer is over!
+[CAR_NO]
+You cannot buy the Car Showroom at this time, come back later.
-[C_VIGIL]
-VIGILANTE BONUS!!
+[PORN_NO]
+You cannot buy the Film Studio at this time, come back later.
-[A_FAIL2]
-~r~Your lack of urgency has been fatal to the patient!
+[ICE_NO]
+You cannot buy the Ice Cream Factory at this time, come back later.
-[A_FAIL3]
-~r~The patient is dead!!
+[TAXI_NO]
+You cannot buy the Taxi Company at this time, come back later.
-[A_PASS]
-Rescued!
+[BANK_NO]
+You cannot buy The Malibu at this time, come back later.
-[F_FAIL2]
-~r~You're too late!
+[BOAT_NO]
+You cannot buy the Boatyard at this time, come back later.
-[A_COMP2]
-You will never get tired!
+[COL2_6]
+Freeze, imperialist American pig!
-[RM2_M]
-If you need any firepower just drop by and take what you need from the lockers.
+[COL2_6B]
+Zat iz propertay of ze government Francais.
-[HEAL_A]
-Your ~h~health~w~ is displayed in orange in the top right of the screen.
+[COL2_6C]
+'And eet over!
-[YD1_CNT]
-~1~ of 15!
+[COL3_A]
+Thomas I appreciate you coming
-[FM1_9]
-~g~Thats the party up ahead, drop Maria off out front.
+[COL3_B]
+Forgive me for getting straight to business,
-[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.
+[COL3_C]
+Diaz has asked me to oversee a minor business transaction.
-[FM1_AA]
-~w~Oh, I'd better go. I'll see you around I hope.
+[COL3_D]
+Let's hope it goes better than last time.
-[NOCONTE]
-Please re-insert the analog controller (DUALSHOCK@) or analog controller (DUALSHOCK@2) in controller port 1 to continue
+[COL3_E]
+Which is why I thought of you, my friend.
-[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).
+[COL3_F]
+I've dropped some protection at the multistory carpark.
-[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).
+[COL3_G]
+Pick it up then go and watch over Diaz's men at the drop off.
-[WRONGCD]
-Incorrect disc. Please insert correct disc.
+[COL4_2]
+Don't know Sir!
-[NOCD]
-The disc tray is empty. Please insert disc.
+[COL4_5]
+Sir, Yes Sir!
-[OPENCD]
-The disc tray is open. Please close the disc tray.
+[COL4_10]
+Lets go eat some doughnuts.
-[CDERROR]
-Error reading the Grand Theft Auto III DVD
+[COL4_16]
+Sir! Moving vehicle Sir!
-[RESTART]
-Starting new game
+[COL4_25]
+Vehicle self destruct initiated!
-[GA_3]
-No more freebies. $1000 to respray!
+[COL5_6]
+Mercedes, that girl will be the death of me.
-[GA_1]
-Whoa! I don't touch nothing THAT hot!
+[COL5_8]
+Damn cockroach!
-[GA_1A]
-Come back when you're not so busy...
+[COL5_5]
+Die French peegs!
-[S_PROM2]
-The garage next door can store one vehicle when you save your game.
+[CNT2_1]
+Kill him.
-[STOCK]
-out of stock
+[CNT2_2]
+Get the Plates!
-[FM1_O]
-~w~He's at the rail station at the Chinatown waterfront I think.
+[CNT2_3]
+Protect the courier!
-[EBAL_B]
-This is the place right here, let's get off the street and find a change of clothes!
+[FINKILL]
+Ok boys, kill him!
-[EBAL_G]
-This is Luigi's club. Let's go round the back and use the service door.
+[FIN_1A]
+Come here you double-crossing piece of shit!
-[AM4_3]
-You must be Asuka's new errand boy!
+[FIN_1B]
+You're going down, you back stabbing prick!
-[AM4_4]
-You got the money? Is it all here?
+[FIN_1C]
+This is the last dance for lance vance!
-[AM4_5]
-I know what you're thinking, another bent cop.
+[FIN_2B]
+Oh you think so!
-[AM4_6]
-Well, it's a bent world.
+[FIN_2C]
+I said I had enough of that at school!
-[AM4_7]
-Just 'cause I lost a few partners, those suckers from internal affairs have started sniffing around.
+[FIN_3]
+No one to cover your ass now, eh Tommy?
-[AM4_8]
-Reckon they can smell me.
+[FIN_4]
+You're history, Tommy, history
-[AM4_9]
-Well, this city is just one big open sewer.
+[FIN_5]
+You picked the wrong side, Lance...
-[AM4_10]
-But I'm gonna need some non-union help.
+[FIN_6]
+Sonny's up with the safe and MY money...
-[AM4_11]
-And if you're interested you'll know where to find me.
+[FIN_10]
+Sonny? SONNY! I'm coming for ya!
-[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.
+[FIN_11A]
+You took fifteen years from me Sonny...
-[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.
+[FIN_11B]
+And now I'm gonna make you pay!
-[KM2_1]
-~g~Repair the car, it's gotta be mint.
+[FIN_12A]
+You still don't get it do you!
-[LM3_6]
-Joey...
+[FIN_12B]
+I OWN you, Tommy.
-[LM3_6A]
-Am I goin' to play with your big end again?
+[FIN_12C]
+Those fifteen years were mine to spend!
-[LM3_9A]
-there might be some work for you.
+[FIN_13]
+Get him boys, he never understood a thing.
-[LM3_9B]
-Alright?
+[RACES_4]
+3
-[AWAY2]
-~r~They got away.
+[RACES_5]
+2
-[AWAY]
-~r~He's clean out of here!
+[RACES_6]
+1
-[JM6_1]
-Get to the bank on the main drag.
+[RACES_7]
+GO!
-[GA_6B]
-Park it, prime it by pressing the ~h~~k~~PED_FIREWEAPON~ button~w~ and LEG IT!
+[RACES_9]
+Time: ~1~:~1~
-[GA_7B]
-Arm with ~h~~k~~PED_FIREWEAPON~ button~w~. Bomb will go off when engine is started.
+[RACES]
+TIME:
-[BAT1]
-~g~Pick up the bat!
+[RACES17]
+New best time: ~1~:~1~
-[EBAL_O]
-If you don't mess this up, maybe there be more work for you. Now get outta here!
+[RACES18]
+YOU HAVE WON: $~1~
-[HELP9_B]
-Press the~h~ ~k~~PED_FIREWEAPON~ button ~w~to ~h~fire~w~ the sniper rifle.
+[RACES20]
+New best time: ~1~:0~1~
-[HELP9_C]
-Press the~h~ ~k~~PED_FIREWEAPON~ button ~w~to ~h~fire~w~ the sniper rifle.
+[RACES21]
+Time: ~1~:0~1~
-[JM6_8]
-~r~You've lost all the robbers!
+[RCH1_1]
+NO LONGER NEEDED NO LONGER NEEDED NO LONGER NEEDED NO LONGER NEEDED NO LONGER NEEDED
-[COLT_IN]
-The Pistol is now in stock at Ammunation!
+[RCH1_2]
+~g~The CHECKPOINTS are scattered throughout the airport.
-[TAXI2]
-~r~You're out of time!
+[RCH1_3]
+NO LONGER NEEDED NO LONGER NEEDED NO LONGER NEEDED NO LONGER NEEDED NO LONGER NEEDED
-[TAXI3]
-~r~Your passenger fled in terror!
+[RCH1_5]
+Time:
-[TAXI7]
-~r~Your car is trashed, get it repaired.
+[RCRC1_2]
+~g~Get to the starting grid now!
-[TAXI4]
-Fare complete!
+[RCRC1_4]
+~g~3
-[TAXI5]
-SPEED BONUS!!
+[RCRC1_5]
+~g~2
-[TAXI6]
-Taxi mission over
+[RCRC1_6]
+~g~1
-[FRANGO]
-~g~Salvatore wants you to help Toni deal with the Triads first!
+[RCRC1_7]
+~g~GO!
-[PAGEB12]
-Police Bribe delivered to hideout
+[RCRC1_8]
+~g~Race time: ~1~ seconds
-[PAGEB13]
-Health delivered to hideout
+[RCPL1_1]
+~g~Compete in a CHECKPOINT RACE with 3 other RC Baron's
-[PAGEB14]
-Adrenaline delivered to hideout
+[RCPL1_2]
+~g~You must go through the ~o~CENTRE CORONA ~g~to successfully pass a checkpoint.
-[KM1_4]
-~g~You need a cop car to do the job!
+[RCPL1_3]
+~g~Get to the starting grid now!
-[CAT1_B]
-bring $500,000 to the Villa at Cedar Grove.
+[ICC1_O]
+What is wrong with you??
-[JM2_C]
-He's got a noodle stand down in China Town.
+[FEA_2SP]
+2 Speakers
-[RM6_1]
-Here's a key to a lock-up.
+[FEA_4SP]
+More than 2 speakers
-[RM6_2]
-You'll find some cash and some 'supplies' I'd stashed in case things got tight.
+[FEA_EAR]
+Headphones
-[RM6_3]
-See y'around.
+[FEA_NAH]
+NO AUDIO HARDWARE
-[FE_INIP]
-Initialising and loading Pause Menu... Please wait.
+[FET_APP]
+APPLY
-[FESZ_CA]
-Cancel
+[FES_SKN]
+SKIN NAME
-[FESZ_QU]
-Quit
+[FES_DAT]
+DATE
-[FESZ_L1]
-Game saved successfully!
+[FES_SET]
+Use Skin
-[FESZ_L2]
-Your saved filename is:
+[FET_DEF]
+Restore Defaults
-[FESZ_OK]
-OK
+[FESZ_QZ]
+Are you sure you want to save this game?
-[FES_LGA]
-Load Game
+[FES_SCG]
+Save the current game?
-[FES_NGA]
-New Game
+[FES_LCG]
+Load the game and continue playing?
-[FES_CAN]
-Cancel
+[FEC_FIR]
+Fire
-[FESZ_QL]
-All unsaved progress in your current game will be lost. Proceed with loading?
+[FEC_NWE]
+Next weapon
-[FESZ_QD]
-Proceed with deleting this saved game?
+[FEC_PWE]
+Previous weapon
-[FESZ_QO]
-Proceed with overwriting this saved game?
+[FEC_FOR]
+Forward
-[FESZ_QR]
-Are you sure you want to start a new game? All progress since the last save game will be lost. Proceed?
+[FEC_BAC]
+Backwards
-[FESZ_QS]
-PROCEED WITH SAVE ?
+[FEC_LEF]
+Left
-[T4X4_1]
-'PATRIOT PLAYGROUND'
+[FEC_RIG]
+Right
-[T4X4_2]
-'A RIDE IN THE PARK'
+[FEC_ZIN]
+Zoom in
-[T4X4_3]
-'GRIPPED!'
+[FEC_ZOT]
+Zoom out
-[MM_1]
-'MULTISTOREY MAYHEM'
+[FEC_EEX]
+Enter+exit
-[T4X4_1A]
-~g~You have ~y~5 minutes~g~ to collect ~y~15~g~ checkpoints. ~g~You may collect them in ~y~ANY ORDER.
+[FEC_RAD]
+Radio
-[T4X4_1B]
-~1~ of 15!
+[FEC_SUB]
+Sub-mission
-[T4X4_1C]
-~y~PASS THROUGH~g~ the first checkpoint to start the timer. ~g~Each checkpoint will credit you with ~y~20 SECONDS~g~.
+[FEC_CMR]
+Change camera
-[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_JMP]
+Jump
-[T4X4_2B]
-~1~ of 12!
+[FEC_SPN]
+Sprint
-[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_HND]
+Handbrake
-[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_LOL]
+Look left
-[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_LOR]
+Look right
-[T4X4_3C]
-~1~ of 20!
+[FEC_NTR]
+Next target
-[T4X4_F]
-~r~You bailed! Too tough for you?!
+[FEC_PTT]
+Previous target
-[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_LBA]
+Look behind
-[MM_1_B]
-~1~ of 20!
+[FEC_CEN]
+Center camera
-[MM_1_C]
-~g~That's 20 seconds, plus ~y~5 SECONDS~g~ for each checkpoint. ~g~The timer will start ~y~IMMEDIATELY.
+[FET_CFT]
+ON FOOT
-[FM2_14]
-~r~You got too close and spooked Curly!
+[FET_CCR]
+IN CAR
-[FM2_15]
-~g~Don't get too close or Curly will suspect something!
+[FET_CAC]
+ACTION
-[UPSIDE]
-~r~You flipped your wheels!
+[FEC_IBT]
+-
-[FM2_16]
-SPOOKOMETER:
+[FEC_MXO]
+MXB1
-[LM3_11]
-~g~Misty won't ride in a bus get another vehicle!
+[FEC_MXT]
+MXB2
-[LANDSTK]
-Landstalker
+[FEC_UNB]
+UNBOUND
-[IDAHO]
-Idaho
+[FEC_TFL]
+Look left+Turret L
-[STINGER]
-Stinger
+[FEC_TFR]
+Look right+Turret R
-[LINERUN]
-Linerunner
+[FEC_MWF]
+MS WHEEL UP
-[PEREN]
-Perennial
+[FEC_MWB]
+MS WHEEL DN
-[SENTINL]
-Sentinel
+[FEC_ORR]
+or
-[PATRIOT]
-Patriot
+[FEC_NUS]
+NOT USED
-[FIRETRK]
-Firetruck
+[FEC_LUD]
+Look Up
-[TRASHM]
-Trashmaster
+[FEC_LDU]
+Look Down
-[STRETCH]
-Stretch
+[FEC_CMP]
+COMBO: LOOK L+R
-[MANANA]
-Manana
+[LAW_1A]
+law_1a
-[INFERNS]
-Infernus
+[LAW_1B]
+law_1b
-[BLISTA]
-Blista
+[LAW_2A]
+law_2a
-[PONY]
-Pony
+[LAW_2B]
+law_2b
-[MULE]
-Mule
+[FEH_STA]
+STATS
-[CHEETAH]
-Cheetah
+[FEH_LOA]
+LOAD
-[AMBULAN]
-Ambulance
+[FEH_CON]
+CONTROLS
-[FBICAR]
-Fbi Car
+[FEH_AUD]
+AUDIO
-[MOONBM]
-Moonbeam
+[FEH_LAN]
+LANGUAGE
-[ESPERAN]
-Esperanto
+[FEH_SGA]
+START NEW GAME
-[TAXI]
-Taxi
+[FEO_CON]
+Controller Setup
-[KURUMA]
-Kuruma
+[FEO_AUD]
+Audio Setup
-[BOBCAT]
-Bobcat
+[FEO_DIS]
+Display Setup
-[WHOOPEE]
-Mr Whoopee
+[FEO_LAN]
+Language Setup
-[BFINJC]
-BF Injection
+[FEO_PLA]
+Player Setup
-[POLICAR]
-Police
-
-[ENFORCR]
-Enforcer
+[FEA_OUT]
+Output
-[SECURI]
-Securicar
+[FEA_ST]
+Stereo
-[BANSHEE]
-Banshee
+[FEA_DTS]
+DTS
-[PREDATR]
-Predator
+[FEA_RSS]
+Radio station
-[BUS]
-Bus
+[FEA_NON]
+RADIO OFF
-[RHINO]
-Rhino
+[FEA_FM0]
+WILDSTYLE
-[BARRCKS]
-Barracks OL
+[FEA_FM1]
+FLASH FM
-[TRAIN]
-Train
+[FEA_FM2]
+KCHAT
-[HELI]
-Helicopter
+[FEA_FM3]
+FEVER 105
-[DODO]
-Dodo
+[FEA_FM4]
+VROCK
-[COACH]
-Coach
+[FEA_FM5]
+VCPR
-[CABBIE]
-Cabbie
+[FEA_FM7]
+EMOTION 98.3
-[STALION]
-Stallion
+[FEA_FM8]
+WAVE 103
-[RUMPO]
-Rumpo
+[FED_BRI]
+Brightness
-[RCBANDT]
-RC Bandit
+[FED_TRA]
+Trails
-[BELLYUP]
-Triad Fish Van
+[FED_SUB]
+Subtitles
-[MRWONGS]
-Mr Wongs
+[FED_WIS]
+Wide Screen
-[MAFIACR]
-Mafia Sentinel
+[FED_POS]
+Screen Position
-[YARDICR]
-Yardie Lobo
+[FEP_RES]
+Resume
-[YAKUZCR]
-Yakuza Stinger
+[FEP_STG]
+Start Game
-[DIABLCR]
-Diablo Stallion
+[FEP_STA]
+Stats
-[COLOMCR]
-Cartel Cruiser
+[FEP_BRI]
+Briefs
-[HOODSCR]
-Hoods Rumpo XL
+[FEP_OPT]
+Options
-[AEROPL]
-Aeroplane
+[FEP_QUI]
+Quit Game
-[SPEEDER]
-Speeder
+[FES_LOA]
+Load game
-[REEFER]
-Reefer
+[FES_DEL]
+Delete game
-[PANLANT]
-Panlantic
+[FEC_CSU]
+Controller Setup
-[FLATBED]
-Flatbed
+[FEC_RED]
+Redefine Controls
-[YANKEE]
-Yankee
+[FEC_MOU]
+Mouse Settings
-[BORGNIN]
-Borgnine
+[DISTGOL]
+Dist. traveled by golf cart (miles)
-[TOYZ]
-TOYZ
+[DISTGOM]
+Distance traveled by golf cart (m)
-[FEST_DF]
-Dist. travelled on foot (miles)
+[ST_FAVR]
+Favorite radio station
-[FEST_DC]
-Dist. travelled by car (miles)
+[ST_WSTR]
+least favorite radio station
-[FESTDFM]
-Distance travelled on foot (m)
+[ST_FAVV]
+Favorite vehicle
-[FESTDCM]
-Distance travelled by car (m)
+[ST_STAR]
+Total number of wanted stars attained
-[FEST_R1]
-Patriot Playground in secs
+[ST_HEAD]
+Number of headshots
-[FEST_R2]
-A Ride In The Park in secs
+[ST_GANG]
+Least favorite gang
-[FEST_R3]
-Gripped! in secs
+[ST_STGN]
+Total number of wanted stars evaded
-[FEST_RM]
-Multistorey Mayhem in secs
+[TYREPOP]
+Tires popped with gunfire
-[FEST_LS]
-People saved in an Ambulance
+[TYRESLA]
+Tires slashed with a blade
-[FEST_CC]
-Criminals killed on Vigilante Mission
+[ST_BRK]
+Number of bloodring kills
-[FEST_FE]
-Total fires extinguished
+[ST_LTBR]
+Longest time in bloodring (secs)
-[FEST_LF]
-Longest flight in Dodo
+[ST_GNG1]
+Cubans
-[FEST_BD]
-Best time for bomb defusal
+[ST_GNG2]
+Haitians
-[FEST_RP]
-Rampages passed
+[ST_GNG3]
+Streetwannabe's
-[FEST_MP]
-Missions passed
+[ST_GNG4]
+Diaz's gang
-[FEST_BB]
-Bling-bling Scramble:
+[ST_GNG5]
+Security guards
-[FEST_H0]
-Most checkpoints
+[ST_GNG6]
+Biker gang
-[FEST_GC]
-Gang Cars Totalled:
+[ST_GNG7]
+Vercetti gang
-[FEST_H1]
-Diablo destruction
+[ST_GNG8]
+Golfers
-[FEST_H2]
-Mafia Massacre
+[FEA_FM6]
+ESPANTOSO
-[FEST_H3]
-Casino Calamity
+[ST_ASSI]
+Assassination Contracts Completed
-[FEST_H4]
-Rumpo Wrecker
+[DISTBIK]
+Dist. traveled by bike (miles)
-[USJI1]
-TEXT NO LONGER REQUIRED
+[DISTBIM]
+Distance traveled by bike (m)
-[USJI2]
-TEXT NO LONGER REQUIRED
+[HOTEL]
+Ocean View
-[USJI3]
-TEXT NO LONGER REQUIRED
+[KICK1_9]
+CHECKPOINTS:
-[USJ]
-UNIQUE STUNT BONUS!
+[FIN_B6]
+You do not have enough money to start this mission.
-[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.
+[TEX3_9]
+~g~Pickup a bomb by maneuvering the RC helicopter next to it.
-[HM1_1]
-~g~Ice 20 Purple Nines in 2 minutes 30 seconds.
+[HELP22]
+Go to the green house blip on the radar.
-[KM1_8A]
-Press the~h~ ~k~~PED_FIREWEAPON~ button~w~ to ~h~activate the bomb,~w~ remember to get out of the way.
+[FES_FMS]
+Format Successful. Select OK to continue.
-[KM1_8D]
-Press the~h~ ~k~~PED_FIREWEAPON~ button~w~ to ~h~activate the bomb,~w~ remember to get out of the way.
+[FES_SSC]
+Save Successful. Select OK to continue.
-[KM1_12]
-~g~Get him to the dojo but get rid of the cops first!
+[FES_DSC]
+Delete Successful. Select OK to continue.
-[RATNG1]
-Pickpocket
+[FESZ_QC]
+Proceed with overwriting this corrupted save game?
-[RATNG2]
-Bully
+[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.
-[RATNG3]
-Thug
+[FET_SG]
+SAVE GAME
-[RATNG4]
-Hustler
+[FEH_BRI]
+BRIEF
-[RATNG5]
-Goon
+[FEH_DIS]
+DISPLAY
-[RATNG6]
-Wheelman
+[FEH_MAP]
+MAP
-[RATNG7]
-Hired muscle
+[FEM_OK]
+OK
-[RATNG8]
-Fixer
+[FEC_CRO]
+Crouch
-[RATNG9]
-Associate
+[FEC_CR3]
+Crouch (L3 button)
-[RATNG10]
-Cleaner
+[FEC_SMT]
+Sub-mission
-[RATNG11]
-Assassin
+[FEC_SM3]
+Sub-mission (R3 button)
-[RATNG12]
-Right-hand man
+[FEC_RSC]
+Radio stations
-[RATNG13]
-Executioner
+[ST_PR01]
+Flyboy
-[RATNG14]
-Capo
+[ST_PR02]
+Aircraftman
-[RATNG15]
-Boss
+[ST_PR03]
+Pilot Officer
-[1010]
-~r~Your vehicle is upside down
+[ST_PR04]
+Corporal
-[1011]
-~r~Your vehicle is upside down
+[ST_PR05]
+Lieutenant
-[1012]
-~r~Your vehicle is upside down
+[ST_PR06]
+Sergeant
-[1013]
-~r~Your vehicle is upside down
+[ST_PR07]
+Captain
-[1014]
-~r~Your vehicle is upside down
+[ST_PR08]
+Biggs
-[JM4_10]
-OK, Kid. Drive me to the laundry in Chinatown first, I got a bit of business to take care of.
+[ST_PR09]
+Wedge
-[JM4_11]
-Those washer women aint been payin' their protection money.
+[ST_PR10]
+Red Baron
-[JM4_12]
-And watch the car, Joey just fixed this junk heap.
+[ST_PR11]
+Goose
-[JM4_13]
-So no fancy crap, OK?
+[ST_PR12]
+Viper
-[KM4_11]
-~g~Take the money back to the casino!
+[ST_PR13]
+Jester
-[FEF_BR2]
-Find it again by reading any mission briefs collected to date.
+[ST_PR14]
+Chappy
-[TRAIN_1]
-Kurowski Station
+[ST_PR15]
+Iceman
-[TRAIN_2]
-Rothwell Station
+[ST_PR16]
+Maverick
-[TRAIN_3]
-Baillie Station
+[ST_PR17]
+Noops
-[SUBWAY1]
-Portland Station
+[ST_PR18]
+Air Chief Marshal
-[SUBWAY2]
-Rockford Station
+[ST_PR19]
+Ace
-[SUBWAY3]
-Staunton South Station
+[FET_LG]
+LOAD GAME
-[SUBWAY4]
-Shoreside Terminal
+[CAR_EXP]
+Road Vehicles destroyed
-[MEA4_2]
-~r~Marty Chonks is dead!
+[BOA_EXP]
+Boats destroyed
-[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.
+[HEL_DST]
+Planes & Helicopters destroyed
-[JM4_A]
-Yeah, I know Toni, I've tuned her real sweet. She purrs, you know what I mean?
+[STFT_01]
+Fastest time on 'Alloy Wheels Of Steel'
-[JM4_5]
-Drop by later and we'll give them something to launder, their own blood stained clothes!
+[STFT_02]
+Fastest time on 'The Driver'
-[AMMU_A]
-Luigi said you'd need a piece...
+[STFT_03]
+Fastest time in Dirt Ring
-[AMMU_B]
-Joey told me to tool you up...
+[STFT_04]
+Fastest time on RC Plane Race
-[AMMU_C]
-So go around back of the shop. I left you a nine in the yard.
+[STFT_05]
+Fastest time on RC Car Race
-[AMMU_D]
-I got all your home defence needs.
+[STFT_06]
+Fastest time on RC helicopter Pickup
-[AMMU_E]
-You want a license too?
+[STFT_07]
+Fastest time on 'Terminal Velocity'
-[AMMU_F]
-I don't need to see any I.D. you look trustworthy.
+[STFT_08]
+Fastest time on 'Ocean Drive'
-[DETON]
-DETONATION:
+[STFT_09]
+Fastest time on 'Border Run'
-[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.
+[STFT_10]
+Fastest time on 'Capital Cruise'
-[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.
+[STFT_11]
+Fastest time on 'Tour!'
-[RECORD]
-~g~NEW RECORD!!
+[STFT_12]
+Fastest time on 'V.C. Endurance'
-[NRECORD]
-~r~NO NEW RECORD!
+[STHC_01]
+Highest score for Shooter
-[RCHELP]
-Press ~k~~PED_FIREWEAPON~, or drive the RC car into a vehicle's wheels to detonate.
+[STHC_02]
+Best Percentage of hits for Shooter
-[RCHELPA]
-Press the ~k~~PED_FIREWEAPON~ button, or drive the RC car into a vehicle's wheels to detonate.
+[STHC_03]
+Number of drug deals made
-[RC_1]
-You have 2 minutes to blow up as many Diablo Gang Cars as possible!
+[HELP24]
+You can now take jobs from the Colonel.
-[RC_2]
-You have 2 minutes to blow up as many Mafia Gang Cars as possible!
+[HELP25]
+You can now take jobs from Avery Carrington.
-[RC_3]
-You have 2 minutes to blow up as many Yakuza Gang Cars as possible!
+[HELP29]
+You can visit the clothes store when you're not on a mission.
-[RC_4]
-You have 2 minutes to blow up as many Yardie Gang Cars as possible!
+[HELP30]
+When you buy new clothes your wanted level will be set to zero.
-[RC_5]
-You have 2 minutes to blow up as many Hood Gang Cars as possible!
+[ASM4_24]
+distance:
-[RC_6]
-You have 2 minutes to blow up as many Cartel Gang Cars as possible!
+[RBM1_6]
+~g~Take Mercedes and the 'Love Juice' to the band at the recording studio.
-[RAMPAGE]
-RAMPAGE!!
+[RBM1_3]
+NO LONGER NEEDED
-[RAMP_P]
-RAMPAGE COMPLETE!
+[HAM1_5]
+NO LONGER NEEDED
-[RAMP_F]
-RAMPAGE FAILED
+[RBM1_11]
+NO LONGER NEEDED
-[PAGE_00]
-.
+[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_01]
-Murder ~1~ Diablos in 120 seconds!
+[HELP34]
+You must have a sub machine gun to perform a drive-by.
-[PAGE_02]
-Destroy ~1~ vehicles in 120 seconds!
+[STRIP_1]
+~r~Not enough cash, you cheap sleazebag.
-[PAGE_03]
-Kill ~1~ Mafia in 120 seconds!
+[EXIT_1]
+Press the ~h~~k~~PED_SPRINT~ ~w~button to exit.
-[PAGE_04]
-Kill ~1~ Triads in 120 seconds!
+[ASM1_B]
+Your next job is taped under the phone.
-[PAGE_05]
-Kill ~1~ Triads in 120 seconds!
+[ASM1_C]
+I have more work for you with a more 'hands-on' approach.
-[PAGE_06]
-Destroy ~1~ vehicles in 120 seconds!
+[SCARF]
+Apartment 3c
-[PAGE_07]
-Pop ~1~ Yardie heads in 120 seconds!
+[LAW4_10]
+Rich management suck!
-[PAGE_08]
-Burn ~1~ Yakuza in 120 seconds!
+[RCH1_6]
+~g~Use the RC Helicopter to collect checkpoints scattered throughout the airport.
-[PAGE_09]
-Destroy ~1~ vehicles in 120 seconds!
+[RCH1_9]
+~b~TOTAL TIME: ~1~:~1~
-[PAGE_10]
-Destroy ~1~ vehicles in 120 seconds!
+[RCH1_10]
+~b~TOTAL TIME: ~1~:0~1~
-[PAGE_11]
-Annihialate ~1~ Yardies in 120 seconds!
+[WHEEL01]
+TWO WHEELS DOUBLE BONUS: $ ~1~ Distance: ~1~.~1~m Time: ~1~ seconds
-[PAGE_12]
-Torch ~1~ Yakuza in 120 seconds!
+[WHEEL02]
+TWO WHEELS DOUBLE BONUS: $ ~1~ Distance: ~1~ feet Time: ~1~ seconds
-[PAGE_13]
-Explode ~1~ Yardies in 120 seconds!
+[WHEEL03]
+TWO WHEELS BONUS: $ ~1~ Time: ~1~ seconds
-[PAGE_14]
-Fry ~1~ Colombians in 120 seconds!
+[WHEEL04]
+TWO WHEELS BONUS: $ ~1~ Distance: ~1~.~1~m
-[PAGE_15]
-Splatter ~1~ Hoods in 120 seconds!
+[WHEEL05]
+TWO WHEELS BONUS: $ ~1~ Distance: ~1~ feet
-[PAGE_16]
-Destroy ~1~ vehicles in 120 seconds!
+[WHEEL06]
+WHEELIE BONUS: $ ~1~ Distance: ~1~.~1~m Time: ~1~ seconds
-[PAGE_17]
-Splatter ~1~ Colombians with a car in 120 seconds!
+[WHEEL07]
+WHEELIE BONUS: $ ~1~ Distance: ~1~ feet Time: ~1~ seconds
-[PAGE_18]
-Driveby and Destroy ~1~ vehicles in 120 seconds!
+[WHEEL08]
+WHEELIE BONUS: $ ~1~ Time: ~1~ seconds
-[PAGE_19]
-Remove ~1~ Colombian heads in 120 seconds!
+[WHEEL09]
+WHEELIE BONUS: $ ~1~ Distance: ~1~.~1~m
-[PAGE_20]
-Behead ~1~ Hoods in 120 seconds!
+[WHEEL10]
+WHEELIE BONUS: $ ~1~ Distance: ~1~ feet
-[JM1_A]
-Hey, I'm bored when you gonna drill me?
+[WHEEL11]
+STOPPIE BONUS: $ ~1~ Distance: ~1~.~1~m Time: ~1~ seconds
-[JM1_B]
-In a moment sweet heart, I got a little business to take care of.
+[WHEEL12]
+STOPPIE BONUS: $ ~1~ Distance: ~1~ feet Time: ~1~ seconds
-[JM1_C]
-I got a little job for you pal.
+[WHEEL13]
+STOPPIE BONUS: $ ~1~ Time: ~1~ seconds
-[JM1_D]
-The Forelli brothers have owed me money for too long
+[WHEEL14]
+STOPPIE BONUS: $ ~1~ Distance: ~1~.~1~m
-[JM1_E]
-and they need to be taught some respect.
+[WHEEL15]
+STOPPIE BONUS: $ ~1~ Distance: ~1~ feet
-[JM1_F]
-Lips Forelli is stuffing his fat face in St Marks Bistro,
+[ROK3_72]
+Love Fist!
-[JM1_G]
-so steal his car and take it to 8-Ball's bomb shop up in Harwood.
+[POR1_19]
+Hey!
-[JM1_H]
-You know 8-Ball right?
+[DESPERA]
+Desperado
-[JM1_I]
-Once he's fitted it with a bomb, go park the car where you found it.
+[MOB_99A]
+Get to the payphone next to the mall in Washington.
-[JM1_J]
-Then sit back and watch the whole show.
+[MOB_98A]
+Get to the pay phone in Vice Point.
-[JM1_K]
-But hurry up, he won't be eating forever.
+[MOB_96A]
+Get to the payphone at the airport terminal.
-[CAT2_A1]
-Come on you dumb bitch!
+[MOB_95A]
+Get to the payphone in Little Havana.
-[CAT2_A]
-The real question is, did you turn up to rescue Maria or to get me back?
+[BNK1_1]
+Can I help you, sir?
-[CAT2_B]
-Well I got news for you,
+[BNK1_2]
+There's an imposter!
-[CAT2_B2]
-shooting you will be a pleasure but dating you was only business.
+[BNK1_3]
+He's gone insane!
-[CAT2_C]
-You are muy peccinno amigo!
+[BNK1_4]
+Who the hell are you?
-[CAT2_D]
-Throw over the cash.
+[BNK1_5]
+Where's your badge?
-[CAT2_E]
-You have been a busy boy!
+[BNK1_6]
+There they are! Shoot to kill!
-[CAT2_E2]
-But you haven't learned, I'm not to be trusted.
+[MOB_24A]
+Hola, is this Mr. Vercetti?
-[CAT2_E3]
-Kill the idiot.
+[MOB_24B]
+Yeah.
-[CAT2_J]
-Get this thing airborne!!
+[MOB_24C]
+This is Cortez. You were at my party.
-[HM5_1]
-Yo, Ice said was comin'. There rules. Bats only. No guns, no cars.
+[MOB_24D]
+Yeah. I remember.
-[HM5_5]
-This is a battle for respect, you cool?
+[MOB_24E]
+Mr. Vercetti, it was a most unfortunate incident that happened with your business deal.
-[HELP14]
-To collect weapons walk through them. These cannot be collected while in a vehicle.
+[MOB_24F]
+I know.
-[CRUSH]
-Park in the marked area and exit your vehicle. The vehicle will then be crushed.
+[MOB_24G]
+I want you to know me and my people are doing their utmost to get to the bottom of it.
-[DIAB2_B]
-A gang of no-goods has threatened to remove my starring member if I don't pay them a cut.
+[MOB_24H]
+If you'd like to talk to me more privately, you can find me at the boat, eh? Okay? Good day, senor.
-[DIAB2_C]
-They threaten the wrong man, amigo.
+[BNK2_6]
+This guy's a lunatic!
-[DIAB2_D]
-They have a weakness for the icecream.
+[ANGEL]
+Angel
-[DIAB2_E]
-Pick up the bomb I've hidden in Harwood,
+[CUBJET]
+Cuban Jetmax
-[DIAB2_F]
-hijack the regular icecream van on its rounds.
+[SANDKIN]
+Sandking
-[DIAB2_G]
-and lure these fools to their doom with the jeengle-jeengle.
+[POLMAV]
+Police Maverick
-[DIAB2_H]
-They hide in a warehouse on Atlantic Quay.
+[BOXVILL]
+Boxville
-[DIAB3_A]
-Some insolent Triads stole my beautiful car last night,
+[BENSON]
+Benson
-[DIAB3_B]
-wrecked it and left it burning.
+[HOTRINA]
+Hotring Racer
-[DIAB3_C]
-Some of my most precious donkey memorabilia was in the trunk -
+[HOTRINB]
+Hotring Racer
-[DIAB3_D]
-real collectibles that are irreplaceable my friend.
+[BLOODRA]
+Bloodring Banger
-[DIAB3_E]
-I've hidden a throbbing weapon on the edge of Chinatown.
+[BLOODRB]
+Bloodring Banger
-[DIAB3_F]
-Take it and teach these Triad vandals to fear El Burro's well-endowed wrath.
+[MAFIACR]
+Mafia Cruiser
-[DIAB3_1]
-KILL 25 TRIADS
+[COP_M2]
+'VICE SQUAD'
-[DIAB4_A]
-A thieving opportunist has stolen a van of my latest publication hot off the press!
+[COP_M3]
+'BROWN THUNDER'
-[DIAB4_B]
-But that SPANKED-up idiot has left the rear doors open
+[BNK3_2]
+I'm not driving for you, no way, I'm sharing this at group.
-[DIAB4_C]
-and now my beautifully produced,
+[FEM_SL1]
+Save File 1 Not Present
-[DIAB4_D]
-tastefully photographed adult literature is being dropped all over Liberty!
+[FEM_SL2]
+Save File 2 Not Present
-[DIAB4_E]
-Take the van and follow that trail of Donkey Does Dallas volumes 1, 2 and 3
+[FEM_SL3]
+Save File 3 Not Present
-[DIAB4_F]
-collecting it as you go.
+[FEM_SL4]
+Save File 4 Not Present
-[DIAB4_G]
-When you've followed the trail to that thieving SPANK-head, waste him!
+[FEM_SL5]
+Save File 5 Not Present
-[DIAB4_H]
-Then deliver my donkey derby to XXX Mags in the Red Light District.
+[FEM_SL6]
+Save File 6 Not Present
-[DIAB4_1]
-~g~Take the van to the back of XXX Magazines.
+[FEM_SL7]
+Save File 7 Not Present
-[HM1_E]
-I want you to show these punk ass bitches how a real drive-by works.
+[FEM_SL8]
+Save File 8 Not Present
-[HM1_H]
-Take these nines off of here!!
+[FEA_CHA]
+Changing audio output to STEREO. Please wait...
-[HM2_A]
-Those Nines are pressing me.
+[FEA_CHD]
+Warning! You are changing from STEREO output to DTS. Please wait...
-[HM2_B]
-These Bitches got armored cars and now they're running SPANK...
+[FEI_SEL]
+Select
-[HM2_C]
-and slinging it to brothers with no fear.
+[FEI_BAC]
+Back
-[HM2_D]
-There's a car parked up the way.
+[FEI_RES]
+Resume
-[HM2_E]
-There's some stuff in there to put these sissys on blass...
+[FEI_NAV]
+Navigate
-[HM3_A]
-Some effa has wired my wheels to blow.
+[FEI_BTX]
+/ button -
-[HM3_B]
-If I lose those wheels, my rep on the street will be dead.
+[FEI_BTT]
+" button -
-[HM3_C]
-Pick up my car and take it over to the garage on St. Marks, a'right yo.
+[FEI_STA]
+START button -
-[HM3_D]
-Let them diffuse that, let them take care of that bomb.
+[FEI_BTD]
+; = > < -
-[HM3_E]
-The clocks ticking and the wiring is messed up.
+[FEI_STO]
+Stop
-[HM3_F]
-One pot hole too many and that thing could blow.
+[ST_ICEC]
+'Ice Cream' Sold
-[HM3_G]
-Now move it!
+[MOB_68A]
+Tommy son, have I got a surprise for you
-[HM4_A]
-Yo, a Federal Reserve flight just smashed down at Francis International.
+[MOB_68B]
+I'm down at the recording studios with some major artists
-[HM4_B]
-There's platinum all over the strip.
+[MOB_68C]
+Why don't you pay us a visit?
-[HM4_C]
-Get a car and snatch up as much as you can.
+[MOB_68D]
+You know it makes sense, dontcha? See ya later.
-[HM4_F]
-You can drop the bling off at one of my garages.
+[OUTFT1]
+Street
-[HM4_G]
-This platinum is mad heavy and it will slow your wheels down some.
+[OUTFT2]
+Soiree
-[HM4_H]
-So make regular drop off's at the garage.
+[OUTFT3]
+Coveralls
-[HM5_A]
-Them Nines are down to a few scabby herds...
+[OUTFT4]
+Country Club
-[HM5_B]
-but they still wanna bring it.
+[OUTFT5]
+Havana
-[HM5_C]
-They agreed to go toe to toe.
+[OUTFT6]
+Cop
-[HM5_D]
-A gang of them against two of us, or rather...
+[OUTFT7]
+Bank Job
-[HM5_E]
-two of yaw
+[OUTFT8]
+Casual
-[HM5_F]
-I'd join you but...
+[OUTFT9]
+Mr Vercetti
-[HM5_G]
-I ain't due my parole hearing for another three months now,
+[OUTFT10]
+Tracksuit
-[HM5_H]
-y'know what I mean?
+[OUTFT13]
+MC Tommy
-[HM5_I]
-Go and meet my baby brother,
+[CAR_AS1]
+CAR SHOWROOM ASSET COMPLETED
-[HM5_J]
-He'll show you where they are fighting a'right son.
+[CAR_AS2]
+~g~Sunshine Auto's will now generate revenue up to a maximum of $~1~. Make sure you collect it regularly.
-[MEA1_B]
-The name's Chonks, Marty Chonks.
+[BUYSAVE]
+~g~You can now save your game here when not on a mission.
-[MEA1_C]
-I run the Bitchin' Dog Food factory around the corner.
+[BUYGARG]
+~g~You can also store vehicles in this garage.
-[MEA1_D]
-I got money troubles, but hey, who doesn't right?
+[STRPBUY]
+Pole Position Club purchased: $~1~
-[MEA1_E]
-I'm meeting my bank manager later.
+[GA_4]
+Car bombs are $500 each
-[MEA1_F]
-He's a crooked bastard that keeps bumping up the loan repayments so he can cut a slice.
+[GA_5]
+Your car is already fitted with a bomb.
-[MEA1_G]
-Take my car, pick him up and bring him back here.
+[GA_6]
+Park it, prime it by pressing the ~h~~k~~PED_FIREWEAPON~ ~w~button and LEG IT!
-[MEA1_H]
-I've got a little surprise for that blood sucking leech!!
+[GA_7]
+Arm with the ~h~~k~~PED_FIREWEAPON~ ~w~button. Bomb will go off when engine is started.
-[MEA2_A]
-I hired some thieves to break into my apartment...
+[GA_6B]
+Park it, prime it by pressing the ~h~~k~~PED_FIREWEAPON~ ~w~button and LEG IT!
-[MEA2_C]
-The thieving bastards are threatening to tell the insurance company,
+[GA_7B]
+Arm with the ~h~~k~~PED_FIREWEAPON~ ~w~button. Bomb will go off when engine is started.
-[MEA2_D]
-if I don't give them a cut.
+[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.
-[MEA2_E]
-Can you believe it?
+[MOB_70B]
+You can find me at the boat.
-[MEA2_F]
-I've left a car inside the factory gates.
+[PICK2]
+.357 delivered to Ocean View Hotel!
-[MEA2_G]
-Use it to go and pick them up from their turf in the Red Light district.
+[PICK3]
+Chainsaw delivered to Ocean View Hotel!
-[MEA2_H]
-Then bring 'em back to the factory so I can make 'em see Marty's point of view.
+[PICK4]
+Flame Thrower delivered to Ocean View Hotel!
-[MEA3_A]
-The business is going to go under unless I get hold of some serious cash soon.
+[PICK5]
+.308 Sniper delivered to Ocean View Hotel!
-[MEA3_B]
-My wife has an insurance policy and all she's ever been to me is a hole in my pocket.
+[PICK6]
+Minigun delivered to Ocean View Hotel!
-[MEA3_C]
-I've left a car in the usual place.
+[PICK7]
+Rocket Launcher delivered to Ocean View Hotel!
-[MEA3_D]
-Go and pick up my wife from Classic Nails and bring her back to the factory.
+[PICK8]
+Sea Sparrow now available from the Mansion on Starfish Island!
-[MEA4_A]
-Damn, I'm in trouble!
+[PICK9]
+Tank now available from the Army Barracks!
-[MEA4_B]
-Turns out my wife was seeing some guy I owe money to.
+[PICK10]
+Hunter now available from the Army Barracks!
-[MEA4_C]
-He's got real angry and he's looking for payback!
+[CLOTH1]
+Soiree outfit delivered to Rafael's on Ocean Beach.
-[MEA4_E]
-he thinks I'm gonna pay him off...
+[CLOTH2]
+Street outfit delivered to Safehouses.
-[MEA4_F]
-but my guess is...
+[CLOTH3]
+Coveralls outfit delivered to Tooled Up in The North Point Mall.
-[MEA4_G]
-Liberty's dogs are gonna get yet another flavor this month!
+[CLOTH4]
+Country Club outfit delivered to The Golf Club in Leaf Links.
-[WELCOME]
-WELCOME TO
+[CLOTH5]
+Havana outfit delivered to Little Havana Streetwear in Little Havana.
-[HM1_2]
-~g~Get a vehicle, remember only Uzi drive by kills count!
+[CLOTH6]
+Cop outfit delivered to Police Station on Washington Beach.
-[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.
+[CLOTH7]
+Casual outfit delivered to Gash in The North Point Mall.
-[LRQC_1]
-Asuka and I are gonna have to talk, uh,
+[CLOTH8]
+Mr Vercetti outfit delivered to Collar & Cuffs on Ocean Beach.
-[LRQC_2]
-Why don't you go cruise around?
+[CLOTH9]
+Tracksuit outfit delivered to Jocksport in Downtown.
-[LRQC_3]
-You'll need a place to lie low.
+[CLOTH10]
+Bank Job outfit delivered to Malibu Club in Vice Point.
-[LRQC_4]
-There's a warehouse at the edge of Belleville that should suit your needs.
+[MOB_62A]
+Tommy, is Ricardo Diaz, I want to thank you for looking out for me my man.
-[LRQC_5]
-Come back here to my Condo when you are ready,
+[MOB_62B]
+I ask that prick Cortez, he say you the real deal, my friend, why you not come see me.
-[LRQC_6]
-and we can have a little chat.
+[MOB_62C]
+I need a guy like you. All I have now is dickheads,
-[JM6_5]
-~g~You need a getaway vehicle, Idiot!
+[MOB_62D]
+dickheads everywhere, yo. I make you real rich.
-[JM2_F]
-If you need a piece go around back of AmmuNation opposite the subway.
+[GOAWAY2]
+~g~Come back when you have finished the Biker gang missions.
-[LOVE4_7]
-~g~There's a construction yard in Staunton Island, maybe they took the package there.
+[COL2_9]
+You American idiot! They followed you here!
-[LOVE4_8]
-~g~You'll need a car to open the garage.
+[LOADCOL]
+Loading...
-[TSCORE]
-EARNINGS: $~1~
+[STFT_17]
+Fastest time on 'PCJ Playground'
-[AM1_9]
-~r~Salvatore has escaped back into Luigi's Club!
+[STFT_18]
+Fastest time on 'Trial By Dirt'
-[AM1_6]
-~g~If you hang around Luigi's club, the Mafia will spot you!
+[STFT_19]
+Fastest time on 'Test Track'
-[TM2_3]
-~g~It's a trap! Waste them all!!
+[NEW_REC]
+~g~New Record Set!! ~w~~1~ minutes ~g~and ~w~~1~ seconds.
-[FM4_1]
-This is Maria. The car's a trap! Meet me at the slip south of Callahan Bridge.
+[BMX_HOW]
+~g~Do two laps of the dirt track, ~y~passing through ~g~the ~y~CHECKPOINTS ~g~as you go!
-[JM1_7]
-~g~Close the car door! He'll notice!
+[BMXREW1]
+~g~Each time you beat your previous record for the two laps
-[KM5_1]
-~g~DEALER MINCED!!.
+[BMXREW2]
+~g~a larger ~y~REWARD ~g~will be awarded!
-[KM5_6]
-~g~You must murder at least 8 Yardie dealers.
+[BMXRAIN]
+~g~Looks like rain...
-[KM5_7]
-~g~Kill them quickly! Once they've pushed their SPANK they're off the streets.
+[ITBEG]
+In the beginning...
-[RM3_8]
-~r~That car is a decoy!!
+[NBMNBUY]
+El Swanko Casa purchased: $~1~
-[LM3_8]
-Hey, I'm Joey.
+[LNKVBUY]
+Links View Apartment purchased: $~1~
-[LM3_9]
-Luigi said you were reliable so come back later,
+[HYCOBUY]
+Hyman Condo purchased: $~1~
-[KM3_5]
-~g~Press the horn to get the deal going.
+[BUYGARS]
+~g~You can also store vehicles in these garages.
-[LOVE7]
-LOVE'S DISAPPEARANCE
+[OCHEBUY]
+Ocean Heights Apartment purchased: $~1~
-[LOVE2_5]
-~g~Kenji is fender meat! Get out of Newport and dump the car!
+[WASHBUY]
+1102 Washington Street purchased: $~1~
-[AS2_11]
-~g~~1~ OF 9!
+[VCPTBUY]
+3321 Vice Point purchased: $~1~
-[GARAGE1]
-~g~Get out of the vehicle and walk outside.
+[HELP6_C]
+Press the ~h~~k~~VEHICLE_HANDBRAKE~ ~w~button to apply the vehicle's handbrake.
-[KM3_11]
-~g~The Cartel have been attacked and the briefcase has not been recovered.
+[HELP2_A]
+Press the ~h~~k~~PED_SPRINT~ ~w~button when running to ~h~sprint
-[KM3_12]
-~g~Kill all of the Colombians, destory the vehicles and recover the briefcase.
+[HELP4_A]
+Press the ~h~~k~~VEHICLE_ACCELERATE~ ~w~button to accelerate.
-[KM3_13]
-~g~Take the briefcase back to the casino.
+[HELP5_A]
+Press the ~h~~k~~VEHICLE_BRAKE~ ~w~button to brake, or to reverse if the vehicle has stopped.
-[RM5_6]
-~g~He's bailed out!! Smash his bodycast with a vehicle or an explosion!!
+[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.
[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.
+Press the ~h~~k~~PED_FIREWEAPON~ ~w~button to fire the boat cannons.
-[HM2_2]
-~r~You failed to destroy all the armored cars!
+[SEG3_4]
+~g~You can pick up bombs by simply piloting your RC Raider adjacent to each one, to drop a bomb press the ~h~~k~~PED_FIREWEAPON~ ~g~button.
-[HM2_6]
-~g~Armored Car destroyed!
+[RCR1_3]
+~g~If you wish to quit this mission press the ~h~~k~~PED_FIREWEAPON~ ~g~button to detonate your RC car.
-[RM3_A]
-I know a real important man in town, a soft touch,
+[HELP32]
+Then fire using the ~h~~k~~PED_FIREWEAPON~ ~w~button.
-[RM3_H]
-with shall we say, exotic tastes and the money to indulge them.
+[HELP33]
+Then fire using the ~h~~k~~PED_FIREWEAPON~ ~w~button.
-[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.
+[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]
+Press the ~h~~k~~VEHICLE_ENTER_EXIT~ ~w~button to replace current weapon in this slot.
-[MEA2_3]
-~g~Bring the car back to the factory.
+[PU_CF4]
+Press the ~h~~k~~VEHICLE_ENTER_EXIT~ ~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
@@ -5192,7 +4889,7 @@ ART DIRECTOR
AARON GARBUT
[CRED006]
-TECHNICAL DIRECTION
+TECHNICAL DIRECTORS
[CRED007]
OBBE VERMEIJ
@@ -5200,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
@@ -5228,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
@@ -5297,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
@@ -5315,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
@@ -5372,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
@@ -5389,6 +5176,12 @@ ASSOCIATE PRODUCER
[CRED070]
JEREMY POPE
+[CRD071A]
+DIRECTOR OF QUALITY ASSURANCE
+
+[CRD072A]
+JEFF ROSA
+
[CRED071]
MUSIC SUPERVISOR
@@ -5396,7 +5189,7 @@ MUSIC SUPERVISOR
TERRY DONOVAN
[CRED073]
-ROCKSTAR PRODUCTION TEAM
+PRODUCTION TEAM
[CRED074]
TERRY DONOVAN
@@ -5414,10 +5207,10 @@ LAURA PATERSON
JEFF CASTANEDA
[CRED079]
-CHRIS CARRO
+JERONIMO BARRERA
[CRED080]
-ADAM TEDMAN
+CARLY SLATER
[CRED081]
JUNG KWAK
@@ -5426,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
@@ -5455,6 +5287,12 @@ LEAD ANALYST
[CRED092]
ADAM DAVIDSON
+[CRD092A]
+JOE HOWELL
+
+[CRD092B]
+MARC FERNANDEZ
+
[CRED093]
GAME ANALYST
@@ -5462,7 +5300,7 @@ GAME ANALYST
RICHARD HUIE
[CRED095]
-TEST TEAM
+ROCKSTAR TEST TEAM
[CRED096]
LANCE WILLIAMS
@@ -5473,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
@@ -5498,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
@@ -5588,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
@@ -5858,10 +5762,10 @@ SARA SEWELL
RADIO STATIONS AND MUSIC
[CRED218]
-PRODUCERS FOR ROCKSTAR UK
+MUSIC CONSULTANCY
[CRD218A]
-CRAIG CONNER
+HEINZ HENN
[CRD218B]
STUART ROSS
@@ -5876,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
@@ -5891,1033 +5795,1069 @@ 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]
-Use the ~h~~k~~PED_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]
-Use the ~h~~k~~PED_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]
+Use the ~h~~k~~VEHICLE_ACCELERATE~~w~ button to accelerate, 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.
-[RM3_5]
-~g~You have ~1~ of 6 evidence packages.
+[LG_38]
+Target
-[LOVE3_2]
-~g~You have all the packages! Take them back to Donald Love.
+[ASSET_C]
+POLE POSITION ASSET COMPLETED!
-[LOVE4_4]
-~g~Take the package 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!
-[FEB_SAV]
-Load
+[ST_WHEE]
+Longest Wheelie time (secs)
-[FEP_SAV]
-LOAD GAME
+[ST_STOP]
+Longest Stoppie time (secs)
-[AS2_12A]
-~g~After you trash the first stall, you will have 8 minutes before the Cartel warn their pushers!
+[ST_2WHE]
+Longest 2 wheels time (secs)
-[AS3_1A]
-~g~Now get to the ~b~marker buoy!
+[ST_WHED]
+Longest Wheelie distance (m)
-[NOCONT]
-Please reconnect an analog controller (DUALSHOCK@) or analog controller (DUALSHOCK@2). to controller port 1 to continue
+[ST_STOD]
+Longest Stoppie distance (m)
+
+[ST_2WHD]
+Longest 2 wheels distance (m)
+
+[OUTFT11]
+Tracksuit
+
+[OUTFT12]
+Frankie
+
+[RELOAD]
+~g~You have won the fast reload ability!
+
+[APACHE]
+Hunter delivered to helipad in Ocean Beach.
+
+[CRED369]
+JOHN MCCARDLE
+
+[CRED370]
+DAVID MURDOCH
-[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!
+[CRED371]
+CHRIS BROWN
-[END_A]
-Residents in Cedar Grove have been coming to terms
+[CRED372]
+PAUL GREEN
-[END_B]
-with the emotional aftermath of a full blown war
+[CRED373]
+KYLE MILNE
-[END_C]
-that hit the area yesterday.
+[CRED374]
+KEVIN YUN
-[END_D]
-Local resident, Clive Denver described to police
+[CRED375]
+ERICK COBBS
-[END_E]
-a single gunman that he saw fleeing the scene, with a dark haired woman.
+[CRED376]
+RANDY BLAKE
-[END_F]
-Oh, you know, we're gonna have such fun, 'cos you know, you know,
+[CRED377]
+BRANDON LIM
-[END_G]
-I love you, I, I, I, I really do, 'cos you're such a big strong man
+[CRED378]
+BRANDON FENOL
-[END_H]
-and that's just what I need.
+[CRED379]
+MICHAEL MANOLE
-[END_I]
-Anyway, what was I saying?
+[CRED380]
+ALETHEIA SIMONSON
-[END_J]
-Oh, you know, I forget. But you know what it's like, don't you?
+[CRED381]
+JOHN JANSEN
-[END_K]
-The sound of explosions shook nearby homes as people ran for cover.
+[CUNTY]
+New clothes delivered to the Vercetti Estate!
-[END_L]
-Several citizens were injured in the panic as ground fire was exchanged
+[GOODBOY]
+$50 Good Citizen Bonus!
-[END_M]
-between ground forces and a helicopter circling the dam.
+[NEWCONT]
+New ~h~Contact Point ~w~opened at the marina in Ocean Beach!!
-[END_N]
-Yeah, we got a good view from down here in the gardens.
+[FIRELVL]
+Fire Truck Mission level ~1~
-[END_O]
-When the 'copter finally got taken out,
+[FEM_RET]
+RETRY
-[END_P]
-better than the fireworks on the 4th of July.
+[FESZ_QR]
+Are you sure you want to start a new game? All progress will be lost. Proceed?
-[END_Q]
-With the death toll already over twenty,
+[SEG3_1]
+TIME:
-[END_R]
-police are still finding bodies.
+[HELP56]
+Press the ~h~~k~~CAMERA_CHANGE_VIEW_ALL_SITUATIONS~~w~ button to change camera modes.
-[END_S]
-There have been no official denials concerning rumours
+[HELP57]
+Press the ~h~~k~~CAMERA_CHANGE_VIEW_ALL_SITUATIONS~~w~ button to change camera modes.
-[END_T]
-that the dead were members of the Colombian Cartel,
+[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.
-[END_U]
-and still no leads as to the cause of the massacre.
+[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.
-[END_V]
-I broke a nail and my hair is ruined, I mean can you believe it?
+[HELP60]
+If you press the ~w~~k~~PED_SPRINT~ ~w~button while car jacking, you will not enter that vehicle.
-[END_W]
-This one cost me fifty dollars...
+[HELP61]
+You now have limitless ammo and double health on all vehicles.
-[PAPER1]
-*
+[FEC_LB1]
+Look
-[PAPER2]
-*
+[FEC_LB2]
+behind
-[PAPER3]
-*
+[FEC_LB3]
+Look behind
-[FEB_CPC]
-Control Configuration
+[FEC_R3]
+(R3 button)
[FEC_PED]
Controls On Foot
@@ -6932,7 +6872,7 @@ Controls For First Person
Common Controls
[FEC_PWL]
-GO Left
+Go Left
[FEC_PWR]
Go Right
@@ -7042,84 +6982,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
@@ -7171,781 +7033,7249 @@ 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
+
+[REPLAY]
+REPLAY
-[FEG_PLY]
-PLAYERS
+[FEC_ANS]
+Action
-[FEG_TYP]
-TYPE
+[CVT_MSG]
+Converting textures to optimal format for your video card
-[FEG_PNG]
-PING
+[FEC_SFT]
+SHIFT
-[FET_FG]
-FIND GAME
+[FEH_VMP]
+VIEW MAP
-[FET_SP]
-SINGLE PLAYER
+[FES_DEE]
+Delete Failed! Please try again.
-[FET_MP]
-MULTIPLAYER
+[FES_CMP]
+Save failed! Please try again.
-[FET_HG]
-HOST GAME
+[FESZ_WR]
+Saving current game. Please wait...
+
+[FELD_WR]
+Loading game. Please wait...
+
+[FEDL_WR]
+Deleting saved game. Please wait...
+
+[PCRESRT]
+Starting new game. Please wait...
+
+[FET_STI]
+Standard Controls
+
+[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_GFX]
-GFX SETUP
+[FEA_MP3]
+MP3 PLAYER
-[FET_DIS]
-DISPLAY SETUP
+[NO_PCCD]
+Please insert your GTA Vice City CD, or press ESC to cancel
-[FET_LAN]
-LANGUAGE SETUP
+[FEH_SSA]
+CURSORS TO MOVE - S TO SAVE TO FILE
-[FET_LG]
-LOAD GAME
+[FES_CMI]
+LAST MISSION PASSED
-[FET_DG]
-DELETE GAME
+[FET_STS]
+STATS SAVED TO 'STATS.HTML' + 'STATS.TXT'
-[FET_NG]
-NEW GAME
+[WIN_VDM]
+Grand Theft Auto VC cannot find enough available video memory
-[FET_SG]
-SAVE GAME
+[FEC_ERI]
+Error! One or more control actions are not bound to a key or button. Please check all control actions are set
-[FET_MAP]
-SELECT MAP
+[FEC_TFU]
+Turret + Lean Up
-[FET_GT]
-GAME TYPE
+[FEC_TFD]
+Turret + Lean Down
-[FET_CTL]
-CONTROLLER SETUP
+[FET_RIG]
+SELECT A NEW CONTROL FOR THIS ACTION
-[FET_OPT]
-OPTIONS
+[FEA_NM3]
+NO MP3 FILES FOUND
-[FET_QG]
-QUIT GAME
+[FEA_MPB]
+MP3 VOLUME BOOST
-[FET_STA]
-STATISTICS
+[FEA_MUS]
+MUSIC VOLUME
-[FET_BRE]
-BRIEFS
+[FEA_SFX]
+SFX VOLUME
-[FEC_WAR]
-Warning
+[CVT_ERR]
+You have run out of disk space. Please make some space on your harddisk before continuing. Press ESC to cancel.
-[FEC_OKK]
-O.K.
+[FEA_ADP]
+AUTO-DETECT HARDWARE
-[FED_CON]
-Delete File Confirmation
+{=================================== MISSION TABLE AMBULAE ===================================}
-[FES_SSC]
-Game successfully saved.
+[ATUTOR2:AMBULAE]
+~g~Drive the patients to Hospital CAREFULLY. Each bump reduces their chances of survival.
-[DEL_FNM]
-File Successfully Deleted.
+[A_FULL:AMBULAE]
+~r~Ambulance full!!
-[PCLOAD]
-Loading File Data
+[A_FAIL2:AMBULAE]
+~r~Your lack of urgency has been fatal to the patient!
-[PCRESRT]
-Restarting Grand Theft Auto III
+[A_FAIL3:AMBULAE]
+~r~The patient is dead!!
-[FEC_DLF]
-Delete Failed.
+[A_PASS:AMBULAE]
+Rescued!
-[FEC_SVU]
-Save Unsuccessful.
+[A_COMP2:AMBULAE]
+You will never get tired!
-[FEC_LUN]
-Load Unsuccessful. File Corrupted, Please delete.
+[A_CANC:AMBULAE]
+~r~Paramedic mission cancelled!
-[FEN_PLA]
-Number of players:
+[A_COMP3:AMBULAE]
+Paramedic missions complete! You will never get tired when running!
-[FET_NON]
-NO GAMES AVAILABLE
+[ALEVEL:AMBULAE]
+Paramedic Mission Level ~1~
-[FET_SFG]
-SEARCHING FOR GAMES...
+[A_FAIL1:AMBULAE]
+Paramedic mission ended.
-[FET_SRT]
-SORTING GAMES...
+[A_SAVES:AMBULAE]
+PEOPLE SAVED: ~1~
-[FEF_LAN]
-LAN
+[A_COMP1:AMBULAE]
+Paramedic missions complete: $~1~
-[FEF_INT]
-INTERNET
+{=================================== MISSION TABLE ASSIN1 ===================================}
-[FET_REF]
-Refresh
+[ASM1_5:ASSIN1]
+~r~Your target completed his deliveries!
-[FET_FIL]
-Filter
+[ASM1_6:ASSIN1]
+Deliveries left:
-[FET_JG]
-Join
+[ASM1_7:ASSIN1]
+~g~Carl Pearson, Pizza Delivery Man. Kill him before he completes his deliveries.
-[FEC_NTW]
-Talk To Network
+[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_ESR]
-Escape key is Restricted
+[ASM1_D:ASSIN1]
+Mr. Teal, your help in eradicating those out-of-towners was invaluable to business.
-[FEC_GSL]
-Show head bob:
+{=================================== MISSION TABLE ASSIN2 ===================================}
-[FIL_FLT]
-FILTER GAMES LIST
+[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.
-[FET_SAN]
-START NEW GAME
+[ASM2_3:ASSIN2]
+~g~She's gonna blow! Get out of there!
-[FIL_MAP]
-Map:
+[ASM2_4:ASSIN2]
+~r~You smashed up her car when she wasn't in it! She won't touch it now!
-[FIL_SRV]
-Server:
+[ASM2_5:ASSIN2]
+~r~She got away!
-[FIL_TYP]
-Game type:
+[ASM2_6:ASSIN2]
+~r~You were too near the scene of the 'accident'!
-[FIL_SPC]
-Games with Space available?
+[ASM2_7:ASSIN2]
+~r~It's supposed to look like an accident! Try ramming her off the road instead!
-[FIL_PNG]
-Ping:
+[ASM2_8:ASSIN2]
+~g~You must make Mrs. Dawson's death look like an accident. Do not use any weapons.
-[FEN_UKH]
-Unknown host
+[ASM2_9:ASSIN2]
+~g~You need some wheels for this job!
-[FEN_UKM]
-Map not found
+[ASM2_10:ASSIN2]
+~g~When her car bursts into flames make your self scarce!
-[FEN_UKT]
-Game type not found
+[ASM2_11:ASSIN2]
+Help me!
-[FEN_NCI]
-NOT CONNECTED TO THE INTERNET
+[ASM2_12:ASSIN2]
+Somebody help me!
-[FET_PAU]
-PAUSE MENU
+[ASM2_13:ASSIN2]
+Oh my god!
-[FET_SGA]
-START GAME
+[ASM2_A:ASSIN2]
+My compliments on a job well done Mr. Teal. My client was very pleased.
-[FEC_SGJ]
-Set Game Joystick
+[ASM2_2:ASSIN2]
+health:
-[FEC_PAD]
-Gamepad
+{=================================== MISSION TABLE ASSIN3 ===================================}
-[FEC_JOY]
-Joystick
+[ASM3_11:ASSIN3]
+TIME:
-[FEC_WHL]
-Steering wheel
+[ASM3_C:ASSIN3]
+A European gang plans to hit a bank in Vice City. My employers would rather this didn't happen.
-[FEC_CNT]
-Controller type:
+[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_CSA]
-Select a skin from the list below:
+[ASM3_E:ASSIN3]
+Each target and their likely whereabouts are taped under the phone.
-[FES_SKN]
-SKIN NAME
+[ASM3_14:ASSIN3]
+~g~Dick Tanner is working for DBP Security in Ocean Drive.
-[FES_DAT]
-DATE
+[ASM3_15:ASSIN3]
+~g~Marcus Hammond and Franco Carter are located near the Jewelry shop in Vice Point.
-[FES_NON]
-NO SKINS AVAILABLE
+[ASM3_16:ASSIN3]
+~g~Nick Kong is cruising off Washington Beach.
-[FEA_FM9]
-MP3 PLAYER
+[ASM3_18:ASSIN3]
+~g~Don't get too close to the target or he may spot you!
-[FESZ_QZ]
-Are you sure you want to save this game?
+[ASM3_19:ASSIN3]
+~g~He's seen you! Waste him!
-[FES_CGA]
-Current game slots available:
+[ASM3_20:ASSIN3]
+~g~They have seen you! Make sure you waste them both!
-[FES_SCG]
-Save the current game?
+[ASM3_21:ASSIN3]
+~r~You did not kill all the gang members in time!
-[FES_LCG]
-Load the game and continue playing?
+[ASM3_22:ASSIN3]
+~g~Don't get too close to the targets or they may spot you!
-[FEC_FIR]
-Fire
+[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_NWE]
-Next weapon
+[ASM3_13:ASSIN3]
+~g~Mike Griffin is working on an advertising board in Washington.
-[FEC_PWE]
-Previous weapon
+[ASM3_17:ASSIN3]
+~g~Charlie Dilson is riding in Washington.
-[FEC_FOR]
-Forward
+{=================================== MISSION TABLE ASSIN4 ===================================}
-[FEC_BAC]
-Backwards
+[ASM4_10:ASSIN4]
+~g~Looks like you're not the only one after the briefcase! Get it to Ammu-Nation, quick time!
-[FEC_LEF]
-Left
+[ASM4_12:ASSIN4]
+Distance:
-[FEC_RIG]
-Right
+[ASM4_15:ASSIN4]
+~g~Get the sniper rifle to your right.
-[FEC_ZIN]
-Zoom in
+[ASM4_16:ASSIN4]
+~g~Watch the woman on the balcony, she will walk down the escalators and ask someone the time.
-[FEC_ZOT]
-Zoom out
+[ASM4_17:ASSIN4]
+~g~Once the conversation has finished kill the person she spoke to, but do not kill her.
-[FEC_EEX]
-Enter /exit
+[ASM4_18:ASSIN4]
+~g~Once the target is dead retrieve his briefcase and take it to Ammu-Nation in Downtown.
-[FEC_RAD]
-Radio
+[ASM4_19:ASSIN4]
+~g~Keep your distance from the target! Use the distance bar in the upper right corner of the screen.
-[FEC_SUB]
-Sub-mission
+[ASM4_20:ASSIN4]
+~g~If it gets full he will see you.
-[FEC_CMR]
-Change camera
+[ASM4_21:ASSIN4]
+~g~Get the briefcase!
-[FEC_JMP]
-Jump
+[ASM4_22:ASSIN4]
+~g~Take the briefcase to Ammu-Nation in Downtown.
-[FEC_SPN]
-Sprint
+[ASM4_23:ASSIN4]
+~g~He has spotted you! Nail him and get the briefcase!
-[FEC_HND]
-Handbrake
+[ASM4_25:ASSIN4]
+~r~You killed the woman you fool!
-[FEC_TUL]
-Turret left
+[ASM4_26:ASSIN4]
+~r~The target has boarded his flight!
-[FEC_TUR]
-Turret right
+[ASM4_27:ASSIN4]
+~r~The target has seen you! You should have kept your distance!
-[FEC_LOL]
-Look left
+[ASM4_28:ASSIN4]
+~r~The target heard you firing your weapon!
-[FEC_LOR]
-Look right
+[ASM4_29:ASSIN4]
+~r~Itchy trigger finger? You killed him too soon!
-[FEC_NTR]
-Next target
+[ASM4_A:ASSIN4]
+Time to fry bigger fish, Mr. Teal. There's a rifle in the foliage to your right.
-[FEC_PTT]
-Previous target
+[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_LBA]
-Look behind
+[ASM4_C:ASSIN4]
+You must kill that person, retrieve his case and take it to the location taped under the phone.
-[FEC_CEN]
-Center camera
+{=================================== MISSION TABLE ASSIN5 ===================================}
-[FEC_UND]
-(NO)
+[ASM5_A:ASSIN5]
+There is a valuable exchange taking place on the roof of the Cherry Popper Ice Cream Company.
-[FET_CFT]
-ON FOOT
+[ASM5_B:ASSIN5]
+Kill everyone involved, steal the merchandise and take it to the helipad at the airport.
-[FET_CCR]
-IN CAR
+[ASM5_C:ASSIN5]
+There is a gate to your left that leads to the back of the factory.
-[CVT_MSG]
-Converting textures to optimal format for your video card
+[ASM5_1:ASSIN5]
+~g~Enter the compound behind the Cherry Popper Ice Cream Company The deal is taking place on the roof.
-[FET_CAC]
-ACTION
+[ASM5_2:ASSIN5]
+~g~Get the merchandise and take it to the helipad at the airport!
-[FEC_IBT]
--
+[ASM5_3:ASSIN5]
+~g~Take the merchandise to the helipad at the airport!
-[FEC_SPC]
-SPC
+{=================================== MISSION TABLE BANKJ1 ===================================}
-[FEC_MXO]
-MXB1
+[WANTED1:BANKJ1]
+~g~Shake the cops and lose your wanted level!
-[FEC_MXT]
-MXB2
+[BJM1_A:BANKJ1]
+Tommy! Hey, Tommy, look at this, this is great! I've got us this minibar installed!
-[FEC_UNB]
-UNBOUND
+[BJM1_B:BANKJ1]
+We got a whole bar downstairs, Ken.
-[FET_CME]
-CONTROL METHOD
+[BJM1_C:BANKJ1]
+Yeah, yeah, whatever. Well, I got the chalkboard you asked for.
-[FET_RDK]
-REDEFINE CONTROLS
+[BJM1_D:BANKJ1]
+Ah, that's the benefit of a law school education: the ability to follow instructions.
-[FET_AMS]
-MOUSE SETTINGS
+[BJM1_E:BANKJ1]
+Now, I need a safe man.
-[FET_STI]
-STANDARD 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_CTI]
-CLASSIC CONTROL CONFIGURATION
+[BJM1_G:BANKJ1]
+Ahh, nah, that schmuck. He's on the inside.
-[FET_MTI]
-MOUSE CONTROL CONFIGURATION
+[BJM1_H:BANKJ1]
+Where inside?
-[FET_DAM]
-DYNAMIC ACOUSTIC MODELING
+[BJM1_I:BANKJ1]
+In a police headquarter cell awaiting transfer.
-[FEC_TFL]
-Turret Left
+[BJM1_J:BANKJ1]
+I think he's about to get paroled....
-[FEC_TFR]
-Turret Right
+[BJM1_1:BANKJ1]
+~g~Break Cam Jones out of police custody!
-[FEC_MWF]
-WHEEL UP
+[BJM1_3:BANKJ1]
+~g~You will find something useful in the station's locker room.
-[FEC_MWB]
-WHEEL DN
+[BJM1_21:BANKJ1]
+~g~The key card to the cells can be found upstairs in the station.
-[FEC_ORR]
-or
+[BNK1_7:BANKJ1]
+Cam Jones?
-[FEC_NUS]
-NOT USED
+[BNK1_8:BANKJ1]
+I'm busting you out!
-[FEC_LUD]
-Look Up
+[BNK1_10:BANKJ1]
+Yeah, that's me..
-[FEC_LDU]
-Look Down
+[BNK1_11:BANKJ1]
+Whatever you say!
-[FEC_CMP]
-COMBO: LOOK L+R
+[BNK1_13:BANKJ1]
+I'm gonna be doing a job and you're my safe cracker.
-[FEC_NTT]
-No Text Yet For This Key
+[BNK1_14:BANKJ1]
+Beats losing my ass in a cell!
-[FEC_FNC]
-F~1~
+[BJM1_22:BANKJ1]
+~g~Get Cam back to his house!
-[FEC_IRT]
-INS
+[BJM1_23:BANKJ1]
+~g~You need to get the key card first!
-[FEC_DLL]
-DEL
+[BNK1_12:BANKJ1]
+Lose the heat and get me back to my place!
-[FEC_HME]
-HOME
+[BJM1_20:BANKJ1]
+Put the weapon away or face the consequences!
-[FEC_END]
-END
+[BJM1_5:BANKJ1]
+Only authorized personnel beyond this point!
-[FEC_PGU]
-PGUP
+[BJM1_2:BANKJ1]
+~r~You were supposed to bust Cam out, not get him killed!
-[FEC_PGD]
-PGDN
+[BJM1_4:BANKJ1]
+He's armed! Kill him!
-[FEC_UPA]
-UP
+{=================================== MISSION TABLE BANKJ2 ===================================}
-[FEC_DWA]
-DOWN
+[BJM2_A:BANKJ2]
+We need a stick up man. You know one?
-[FEC_LFA]
-LEFT
+[BJM2_B:BANKJ2]
+Hey, Tommy, Tommy, Tommy, this stuff keeps you sharp, man.
-[FEC_RFA]
-RIGHT
+[BJM2_C:BANKJ2]
+WoooOOOooo!
-[FEC_NUM]
-NUM
+[BJM2_D:BANKJ2]
+I could be your stick up man! Stick 'em up! Stick 'em up!
-[FEC_NMN]
-NUM~1~
+[BJM2_E:BANKJ2]
+You ain't a stick up man, you're an idiot.
-[FEC_FWS]
-NUM /
+[BJM2_F:BANKJ2]
+Now get yourself a drink and shut up.
-[FEC_PLS]
-NUM +
+[BJM2_G:BANKJ2]
+Hey, get outta my way! Yeh yeh yeh - ow ow ow!
-[FEC_MIN]
-NUM -
+[BJM2_H:BANKJ2]
+Cam, what do you think?
-[FEC_DOT]
-NUM .
+[BJM2_I:BANKJ2]
+Well, the best shooter in this town is a guy named Cassidy.
-[FEC_NLK]
-NUMLOCK
+[BJM2_J:BANKJ2]
+Is that so?
-[FEC_ETR]
-ENT
+[BJM2_K:BANKJ2]
+Yeah. A military guy, or he thinks he is.
-[FEC_SLK]
-SCROLL LOCK
+[BJM2_L:BANKJ2]
+I doubt he was ever in the army, but he certainly knows how to get a hold of guns.
-[FEC_PSB]
-BREAK
+[BJM2_M:BANKJ2]
+He'll be down at the shooting range.
-[FEC_BSP]
-BSPACE
+[BJM2_2A:BANKJ2]
+You Phil Cassidy?
-[FEC_TAB]
-TAB
+[BJM2_2B:BANKJ2]
+Why?
-[FEC_CLK]
-CAPSLOCK
+[BJM2_2C:BANKJ2]
+I'm looking for a man who can handle a gun. From this setup, I'm not too convinced.
-[FEC_RTN]
-RET
+[BJM2_2D:BANKJ2]
+Son, I could shoot a fly off your head at 80 feet.
-[FEC_LSF]
-LSHIFT
+[BJM2_2E:BANKJ2]
+Oh really?
-[FEC_RSF]
-RSHIFT
+[BJM2_2F:BANKJ2]
+Yeah. I learnt in the army.
-[FEC_LCT]
-LCTRL
+[BJM2_2G:BANKJ2]
+Fly shooting real popular in the army? Glad I don't pay tax.
-[FEC_RCT]
-RCTRL
+[BJM2_2H:BANKJ2]
+You tryin' to be funny kid?
-[FEC_LAL]
-LALT
+[BJM2_2I:BANKJ2]
+Ha ha ha ha ha!
-[FEC_RAL]
-RALT
+[BJM2_2J:BANKJ2]
+Let's shoot.
-[FEC_LWD]
-LWIN
+[BJM2_1:BANKJ2]
+~g~Go to Ammu-Nation in Downtown and talk to Phil Cassidy.
-[FEC_RWD]
-RWIN
+[BJM2_3:BANKJ2]
+HIT RATE: ~1~%
-[FEC_WRC]
-WINCLICK
+[BJM2_4:BANKJ2]
+SCORE ROUND ONE: ~1~
-[WIN_TTL]
-Grand Theft Auto III
+[BJM2_6:BANKJ2]
+SCORE ROUND TWO: ~1~
-[WIN_95]
-Grand Theft Auto III cannot run on Windows 95
+[BJM2_7:BANKJ2]
+TOTAL SCORE FOR SHOOT: ~1~
-[WIN_DX]
-Grand Theft Auto III requires at least DirectX version 8.1
+[BJM2_9:BANKJ2]
+~g~Get to round two's starting point.
-[WIN_VDM]
-Grand Theft Auto III requires at least 12MB of available video memory
+[BJM2_11:BANKJ2]
+~r~Phil's dead!
-[DIAB3_G]
-Arriba!
+[BJM2_12:BANKJ2]
+~r~One of the shooters is dead!
-[FEM_RES]
-RESUME GAME
+[BJM2_14:BANKJ2]
+~g~Move on to the next area!
-[FES_SNG]
-START NEW GAME
+[BJM2_15:BANKJ2]
+SCORE:
-[FEM_SP]
-SINGLE PLAYER
+[BJM2_17:BANKJ2]
+~g~Go and talk to Phil.
-[FEM_MP]
-MULTIPLAYER
+[BJM2_18:BANKJ2]
+SCORE TO BEAT:
-[FEM_QT]
-QUIT GAME
+[BJM2_19:BANKJ2]
+~g~Hit as many targets as you can in the time limit!
-[FES_SG]
-START NEW GAME
+[BJM2_22:BANKJ2]
+~r~You have left the shooting range!
-[FES_LG]
-LOAD GAME
+[BJM2_23:BANKJ2]
+~g~If you leave the shooting range during the competition, you will fail the mission.
-[FEM_HST]
-HOST GAME
+[BJM2_24:BANKJ2]
+~g~The closest target is worth one point.
-[FEM_OPT]
-OPTIONS
+[BJM2_25:BANKJ2]
+~g~The middle target is worth two points.
-[FEM_DBG]
-DEBUG
+[BJM2_27:BANKJ2]
+~g~All targets this round are worth one point.
-[FET_PSU]
-PLAYER SETUP
+[BNK2_2:BANKJ2]
+AIM 3-2-1 FIRE!
-[FET_DEF]
-RESTORE DEFAULTS
+[BNK2_3:BANKJ2]
+AREA CLEAR!
-[FED_BRI]
-BRIGHTNESS
+[BNK2_4:BANKJ2]
+Hoooeee!
-[FED_TRA]
-TRAILS
+[BNK2_5:BANKJ2]
+Couldn't hit a barn door!
-[FEM_LOD]
-DRAW DISTANCE
+[BNK2_7:BANKJ2]
+So you wanna do me a favor, and help me put together a job?
-[FEM_VSC]
-FRAME SYNC
+[BNK2_8:BANKJ2]
+Son, after shooting like that, if you asked me to be your wife, I'd say yes.
-[FEM_FRM]
-FRAME LIMITER
+[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_RES]
-SCREEN RESOLUTION
+[BNK2_9B:BANKJ2]
+You can't shoot nothin'.
-[FED_WIS]
-WIDE SCREEN
+[BJM2_28:BANKJ2]
+SCORE ROUND THREE: ~1~
-[FEDS_TB]
-BACK
+[BJM2_20:BANKJ2]
+~g~When you run out of ~w~time ~g~or ~w~ammunition ~g~the round is over!
-[FEA_MUS]
-MUSIC VOLUME
+[BJM2_26:BANKJ2]
+~g~The far target is worth three points.
-[FEA_SFX]
-SFX VOLUME
+[BNK2_1:BANKJ2]
+LIVE AMMUNITION
-[FEA_RSS]
-RADIO STATION
+[RANGE_1:BANKJ2]
+SCORE FOR SHOOT: ~1~
-[FEL_ENG]
-ENGLISH
+[BJM2_2:BANKJ2]
+~g~To exit the round press the ~h~~k~~PED_JUMPING~ ~g~button.
-[FEL_FRE]
-FRENCH
+[BJM2_N:BANKJ2]
+Relax
-[FEL_GER]
-GERMAN
+{=================================== MISSION TABLE BANKJ3 ===================================}
-[FEL_ITA]
-ITALIAN
+[BJM3_A:BANKJ3]
+Things are starting to come together nicely here.
-[FEL_SPA]
-SPANISH
+[BJM3_B:BANKJ3]
+What's the plan, Tommy? Que pasa, amigo?
-[FEA_3DH]
-AUDIO HARDWARE
+[BJM3_C:BANKJ3]
+The plan is you keep doing that like a moron. Anyhow, we need a driver.
-[FEA_SPK]
-SPEAKERS CONFIGURATION
+[BJM3_D:BANKJ3]
+Tommy, I'll do it. I can drive.
-[FEA_2SP]
-2 SPEAKERS
+[BJM3_E:BANKJ3]
+You want Hilary, mister. Not some smart-talking law school chump.
-[FEA_4SP]
-MORE THAN 2 SPEAKERS
+[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_EAR]
-HEADPHONES
+[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?
-[FEA_NAH]
-NO AUDIO HARDWARE
+[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.
-[FET_SNG]
-START NEW GAME
+[BJM3_I:BANKJ3]
+For a bit of action. Okay, I understand.
-[FEN_STA]
-START GAME
+[BJM3_J:BANKJ3]
+What'd he say?
-[GMLOAD]
-LOAD GAME
+[BJM3_K:BANKJ3]
+Well, he'll do it, no problem. Well, there might be a little problem - see, he has abandonment issues.
-[GMSAVE]
-SAVE GAME
+[BJM3_L:BANKJ3]
+Seems he won't work for anyone who can't beat him. Something to do with his momma.
-[FES_DGA]
-DELETE GAME
+[BJM3_M:BANKJ3]
+Anyway, he wants to race you first, said he'd meet you outside..
-[FEM_NON]
-NONE
+[BJM3_2A:BANKJ3]
+You Tommy? Of course you're Tommy, I mean,
-[FEC_IVV]
-INVERT MOUSE VERTICALLY
+[BJM3_2B:BANKJ3]
+Why else would anyone want to speak to me?
-[FEC_MSH]
-MOUSE SENSITIVITY
+[BJM3_2C:BANKJ3]
+OK. Consider it this way -
-[FET_CCN]
-CONTROLS: CLASSIC
+[BJM3_2D:BANKJ3]
+I'll drive for you IF, and only IF, you can drive properly.
-[FET_SCN]
-CONTROLS: STANDARD
+[BJM3_2E:BANKJ3]
+Leave me alone - and I'll never forgive you.
-[FES_SET]
-USE SKIN
+[BJM3_2:BANKJ3]
+~r~Hilary is dead!
-[GHOST]
-Ghost
+[BJM3_4:BANKJ3]
+~g~You need a car to take part!
-[WIN_RSZ]
-Failed to select new screen resolution
+[BNK3_1:BANKJ3]
+Ok. I'll drive for you, but please, treat me bad.
-[FEC_TFU]
-Turret /Dodo up
+[BNK3_3A:BANKJ3]
+Illegal street race in progress at Vice Point.
-[FEC_TFD]
-Turret /Dodo down
+[BNK3_3B:BANKJ3]
+Calling all officers.
-[FET_APL]
-APPLY
+[BNK3_3C:BANKJ3]
+Street racers, this is illegal and forbidden!
-[FET_APP]
-LMB,RETURN TO APPLY THE NEW SETTING
+{=================================== MISSION TABLE BANKJ4 ===================================}
-[FET_HRD]
-DEFAULT SETTINGS RESTORED
+[BNK4_A:BANKJ4]
+~w~As you can see, gentlemen, this is going to be the easiest buck we ever made.
-[FET_MST]
-MOUSE CONTROLLED STEERING
+[BNK4_B:BANKJ4]
+~w~Tommy, seriously, you gotta consider going into law.
-[FEC_STR]
-NUM STAR
+[BNK4_C:BANKJ4]
+~w~What the hell are you smoking, man? This ain't no simple plan!
-[FET_MIG]
-LEFT,RIGHT,MOUSEWHEEL TO ADJUST
+[BNK4_D:BANKJ4]
+~w~Well, who needs a simple plan anyway?
-[FET_CIG]
-BACKSPACE TO CLEAR - LMB,RETURN TO CHANGE
+[BNK4_E:BANKJ4]
+~w~Take communism, now that was a simple plan. Didn't do Russia any favors, huh?
-[FET_RIG]
-SELECT A NEW CONTROL FOR THIS ACTION OR ESC TO CANCEL
+[BNK4_F:BANKJ4]
+~w~Calm down, all right? With a team like this it's going to be no problem.
-[FET_EIG]
-CANNOT SET A CONTROL FOR THIS ACTION
+[BNK4_G:BANKJ4]
+~w~We got Cam on safe. Phil? You and me will handle security, and Hilary'll drive the getaway car.
-[NO_PCCD]
-Please insert Grand Theft Auto III - disc 2 into the drive or 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...
-[CVT_ERR]
-You have run out of disk space. Please make some space on your harddisk before continuing. Press ESC to cancel.
+[BNK4_I:BANKJ4]
+~w~Ken... Ken, that's right. Ken here, he washes the money for us and he keeps the drinks on ice.
-[FED_SUB]
-SUBTITLES
+[BNK4_J:BANKJ4]
+~w~I don't understand what I am supposed to be doing here.
-[FET_DSN]
-Default Player Skin.bmp
+[BNK4_K:BANKJ4]
+~w~Look, it's easy. Haven't you ever seen a movie?
-[JM3]
-'VAN HEIST'
+[BNK4_L:BANKJ4]
+~w~We walk into the bank, we wave the gun around, and leave very rich men.
-[ATUTOR2]
-~g~Drive the patients to Hospital CAREFULLY. Each bump reduces their chances of survival.
+[P_DEAD:BANKJ4]
+~r~Phil's dead!!
-[EBAL]
-'GIVE ME LIBERTY'
+[C_DEAD:BANKJ4]
+~r~Cam's dead!!
-[LM4]
-'PUMP-ACTION PIMP'
+[H_DEAD:BANKJ4]
+~r~Hilary's dead!!
-[REPLAY]
-REPLAY
+[P_HIND:BANKJ4]
+~r~You've lost Phil!
-[FEC_SFT]
-SHIFT
+[C_HIND:BANKJ4]
+~r~Cam's been left behind!
-[CRED254]
-STUDIO MANAGER
+[H_HIND:BANKJ4]
+~r~Hilary's been abandoned!
-[CVT_CRT]
-Cannot convert textures for your video card. You must login to an Administrator account to do this. Press ESC to quit.
+[GETCAR:BANKJ4]
+~g~Get in the getaway car to do the bank job!
-[FEM_ON]
-ON
+[TRASHED:BANKJ4]
+~r~YOU TRASHED THE GETAWAY CAR!!
-[FEM_OFF]
-OFF
+[BNK4_1:BANKJ4]
+I'll drive.
-[FEM_YES]
-YES
+[BNK4_2:BANKJ4]
+Great. A passenger. Wait 'til I tell the group about this.
-[FEM_NO]
-NO
+[BNK4_3A:BANKJ4]
+Hey, watch the wheels, Tommy!
-[FES_WAR]
-Saving, please wait...
+[BNK4_3B:BANKJ4]
+Tommy, Hilary's taking up too much room!
-[FED_DLW]
-Deleting, please wait...
+[BNK4_3C:BANKJ4]
+I am not!
-[FED_LDW]
-Loading, please wait...
+[BNK4_3D:BANKJ4]
+Are too!
-[FEC_SLC]
-Slot is corrupted
+[BNK4_3E:BANKJ4]
+Hey, shut up you two, or you can get out and walk.
-[FED_LFL]
-Loading save game has failed. The game will restart now.
+[BNK4_3F:BANKJ4]
+Yeah - HILARY.
-[FET_RSO]
-ORIGINAL SETTING RESTORED
+[BNK4_3I:BANKJ4]
+For god's sake, Phil, stop waving that thing around!
-[FET_RSC]
-HARDWARE NOT AVAILABLE - ORIGINAL SETTING RESTORED
+[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]
+Use the ~h~~k~~PED_FIREWEAPON~ ~w~button to fire the water cannon. Aim using ~h~~k~~VEHICLE_TURRETLEFT~~w~ and ~h~~k~~VEHICLE_TURRETRIGHT~~w~.
+
+[SPRAY_1:FIRETRK]
+Use the ~h~~k~~PED_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]
+To ~h~shoot straight ahead ~w~on a ~h~motorbike ~w~press the ~h~~k~~PED_FIREWEAPON~ ~w~button.
+
+[GEN3_41:GENERA3]
+To ~h~shoot straight ahead ~w~on a ~h~motorbike ~w~press the ~h~~k~~PED_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]
+To shoot forwards while on a bike press the ~h~~k~~PED_FIREWEAPON~~w~ button.
+
+[GEN3_65:GENERA3]
+To shoot forwards while on a bike press the ~h~~k~~PED_FIREWEAPON~~w~ button.
+
+[GEN3_66:GENERA3]
+To shoot forwards while on a bike press the ~h~~k~~PED_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]
+Press the ~h~~k~~PED_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,
-{ re3 updates }
+[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.
+
+[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]
+~g~If you wish to quit this mission press the ~h~~k~~PED_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]
+~g~If you wish to quit this mission press the ~h~~k~~PED_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]
+~g~To drop a bomb press the~h~ ~k~~PED_FIREWEAPON~ ~g~button.
+
+[TEX3_29:SERG3]
+To drop a bomb press the~h~ ~k~~PED_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]
+Pressing the ~h~~k~~VEHICLE_ACCELERATE~ ~w~button 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
@@ -8065,7 +14395,6 @@ XBOX
INVERT PAD VERTICALLY
{ 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 17eb7983..7327497f 100644
--- a/utils/gxt/build.bat
+++ b/utils/gxt/build.bat
@@ -1,7 +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" \ No newline at end of file
+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 32a6f18f..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 a6bbc0fd..a7d011c3 100644
--- a/utils/gxt/french.txt
+++ b/utils/gxt/french.txt
@@ -1,7178 +1,7058 @@
-[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
-
-[SWANKS]
-Bosquet Cedar
+Partie centrale de Vice City
-[BIG_DAM]
-Ecluse Cochrane
+[BEACH1]
+Ocean Beach
-[SUB_ZO2]
-Vallée Shoreside
+[BEACH2]
+Washington Beach
-[SUB_ZO3]
-Vallée Shoreside
+[BEACH3]
+Vice Point
-[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
+[GOLFC]
+Leaf Links
-[CAR_14]
-Patriot
+[STARI]
+Starfish Island
-[CAR_15]
-M. Whoopee
+[DOCKS]
+Port de Vice
-[CAR_16]
-Mule
-
-[CAR_17]
-Yankee
-
-[CAR_18]
-Pony
+[HAVANA]
+Little Havana
-[CAR_19]
-Bobcat
-
-[CAR_20]
-Rumpo
+[HAITI]
+Little Haiti
-[CAR_21]
-Blista
-
-[CAR_22]
-Dodo
-
-[CAR_23]
-Bus
-
-[CAR_24]
-Sentinelle
-
-[CAR_25]
-Guépard
-
-[CAR_26]
-Banshee
-
-[CAR_27]
-Stinger
+[PORNI]
+Prawn Island
-[CAR_28]
-Infernus
+[DTOWN]
+Centre
-[CAR_29]
-Esperanto
+[VICE_C]
+Vice City
-[CAR_30]
-Kuruma
+[A_PORT]
+Aéroport Escobar
-[CAR_31]
-Stretch
+[JUNKY]
+Décharge
-[CAR_32]
-Perennial
+[PISTOL]
+Pistolet
-[CAR_33]
-Tout-terrain
+[PYTHON]
+.357
-[CAR_34]
-Manana
+[UZI]
+Uz-1
-[CAR_35]
-Idaho
+[TEC9]
+Tec 9
-[CAR_36]
-Etalon
+[M4]
+M4
-[CAR_37]
-Taxi
+[INGRAM]
+Mac
-[CAR_38]
-Tacot
+[MP5]
+MP
-[CAR_39]
-Buggy
+[RUGER]
+Kruger
-[LUIGIS]
-Chez Luigi
+[SNIPE]
+Fusil à lunette
-[GOAWAY]
-~g~T'es déjà en mission, imbécile!
+[GRENADE]
+Grenades
-[LUIGGO]
-~g~Luigi fait passer un entretien à de nouvelles filles. Reviens plus tard!
+[SHOTGN1]
+Fusil à pompe
-[JOEYGO]
-~g~Joey est en ville avec Misty. Repasse plus tard!
+[SHOTGN2]
+S.P.A.S. 12
-[TONIGO]
-~g~Toni a emmené sa mère à l'opéra. Rappelle plus tard!
+[SHOTGN3]
+Fusil à pompe Stubby
-[KEMUGO]
-~g~Maria et Kenuri sont occupés. Reviens un peu plus tard!
+[ARMOUR]
+Gilet pare-balles
-[KENJGO]
-~g~Kenji est à un congrès de Yakuzas. Repasse plus tard.
+[LASER]
+.308 Lunette
-[RAYGO]
-Ray a autre chose à faire que de voir ta tronche. Va faire un tour!
+[BASEBAT]
+Batte de baseball
-[LOVEGO]
-~g~Donald Love a d'autres chats à fouetter. Prends rendez-vous la prochaine fois!
+[HAMMER]
+Marteau
-[KENSGO]
-~g~Kenji est occupé. Repasse à un autre moment.
+[SCREWD]
+Tournevis
-[ASUSGO]
-~g~Asuka n'est pas dispo pour l'instant.
+[CLEVER]
+Couperet
-[HOODGO]
-~g~Les Hoods ne sont pas là pour le moment.
+[MACHETE]
+Machette
-[WRONGT1]
-~g~Repasse entre 05:00 et 21:00 pour du boulot.
+[KNIFE]
+Couteau
-[WRONGT2]
-~g~Repasse entre 06:00 et 14:00 pour du taf.
+[KATANA]
+Katana
-[WRONGT3]
-~g~Ramène ta fraise entre 15:00 et 00:00 pour bosser.
+[CHAINSA]
+Tronçonneuse
-[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.
+[G_COST]
+$~1~
-[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...
+[CAR_1]
+Ambulance
-[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...
+[MALIBU]
+Malibu Club
-[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...
+[MANSION]
+La résidence de Diaz
-[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.
+[TMANS]
+Chez Tommy
-[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.
+[STRIP]
+'Pole Position Club'
-[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.
+[MALL1]
+Centre commercial de North Point
-[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.
+[BANKINT]
+El Banco Corrupto Grande
-[GUN_5]
-Tu peux t'entraîner à cibler et tirer sur ces cibles en papier. Quand tu as finis, reprends ta mission.
+[RANGE]
+Champ de tir
-[TAXI1]
-~g~Cherche une course.
+[POL_HQ]
+QG de Vice City Police
-[FARE1]
-~g~Destination : ~w~Le 'Club Sex Meeouch'~g~ dans Le Quartier Rouge.
+[INT_B]
+Un vieil ami
-[FARE2]
-~g~Destination : ~w~'Pribas'~g~ au Belvédère de Portland.
+[INTB_1]
+~g~Va au bureau de l'avocat.
-[FARE3]
-~g~Destination : ~w~la 'Vieille Ecole'~g~ à Chinatown.
+[LAW_1]
+La Fête
-[FARE4]
-~g~Destination : ~w~le 'Cafe greasy Joes' ~g~au Point Callahan.
+[LAW_2]
+Baston de Rue
-[FARE5]
-~g~Destination : ~w~'AmmuNation'~g~ dans Le Quartier Rouge.
+[LAW_3]
+Jury sous pression
-[FARE6]
-~g~Destination : ~w~'Caisses à crédit'~g~ à Saint Mark's.
+[LAW_4]
+Emeute
-[FARE7]
-~g~Destination : ~w~le 'Woody's topless bar' ~g~ dans le Quartier Rouge.
+[COL_1]
+Salaud de traître
-[FARE8]
-~g~Destination : ~w~le 'Bistro de Marco'~g~ à Saint Mark's.
+[COL_2]
+Fusillade
-[FARE9]
-~g~Destination : ~w~le 'Garage import export' ~g~au Port de Portland.
+[COL_3]
+Anges gardiens
-[FARE10]
-~g~Destination : ~w~'Têtes de Punk' ~g~ à Chinatown.
+[COL_4]
+Chef, oui, chef !
-[FARE12]
-~g~Destination : ~w~le 'Stade de Football'~g~ à Aspatria.
+[COL_5]
+Sur le Pont
-[FARE13]
-~g~Destination : ~w~'L'église'~g~ au Point Bedford.
+[COK_1]
+Course poursuite
-[FARE14]
-~g~Destination : ~w~'Le Casino'~g~ à Torrington.
+[COK_2]
+Phnom Penh '86
-[FARE15]
-~g~Destination : ~w~'Université de Liberty'~g~ au Campus Liberty.
+[COK_3]
+Speedboat
-[FARE16]
-~g~Destination : ~w~le 'Centre commercial~g~ dans le coin du Parc Belleville.
+[COK_4]
+Offre & demande
-[FARE17]
-~g~Destination : ~w~le 'Musée'~g~ de Newport
+[KENT_1]
+Couloir de la mort
-[FARE18]
-~g~Destination : ~w~le 'Bâtiment Am'~g~ de Torrington.
+[ASS_1]
+Liquidation
-[FARE19]
-~g~Destination : ~w~'Burgers bourgeois'~g~ à Point Bedford.
+[BUD_1]
+EXTORSION
-[FARE20]
-~g~Destination : ~w~'Le parc'~g~ à Belleville.
+[BUD_2]
+Rixe de Bar
-[FARE21]
-~g~Destination : ~w~'Aéroport internationnal Francis'~g~.
+[BUD_3]
+CopLand
-[FARE22]
-~g~Destination : ~w~'l'écluse de Cochrane'~g~.
+[CAP_1]
+L'encaisseur
-[FARE24]
-~g~Destination : ~w~'L'hôpital'~g~ de la Crique Pike.
+[FIN_1]
+Amis proches
-[FARE25]
-~g~Destination : ~w~le 'Parc'~g~ à la vallée Shoreside.
+[BANK_1]
+Sans Issue
-[FARE26]
-~g~Destination : ~w~les 'Tours North West'~g~ des jardins Wichita.
+[BANK_2]
+Le Flingueur
-[NEW_TAX]
-PLUS GROS! PLUS RAPIDES! PLUS SOLIDES! Les taxis Borgnine s'installent à Harwood. Contactez-les dès aujourd'hui au 555-Borgnine!
+[BANK_3]
+Le Chauffeur
-[TSCORE2]
-~1~$
+[BANK_4]
+Hold-up
-[IN_ROW]
-~1~ DE SUITE! Bonus : ~1~$
+[CNT_1]
+La Mèche est vendue
-[TTUTOR]
-Appuie sur la ~h~touche ~k~~TOGGLE_SUBMISSIONS~~w~ pour activer ou désactiver l'affichage des missions taxi.
+[CNT_2]
+Halte au Messager
-[TTUTOR2]
-Appuie sur la ~h~touche ~k~~TOGGLE_SUBMISSIONS~~w~ pour activer ou désactiver l'affichage des missions taxi.
+[PORN_1]
+Bout d'essai
-[ATUTOR2]
-~g~Conduis les patients à l'hôpital. DOUCEMENT. Chaque secousse réduit leurs chances de survie.
+[PORN_2]
+Dodo Vibro
-[A_TIME]
-+~1~ secondes.
+[PORN_3]
+Martha
-[A_FULL]
-~r~Ambulance pleine!
+[PORN_4]
+Projecteur-G
-[A_RANGE]
-~g~La radio de l'ambulance ne capte plus rien. Rapproche-toi d'un hôpital!
+[TAX_1]
+Taxis Kaufman
-[FTUTOR]
-Appuie sur la ~h~touche ~k~~TOGGLE_SUBMISSIONS~~w~ pour activer ou désactiver les missions camion de pompier.
+[TAXI_1]
+V.I.P.
-[FTUTOR2]
-Appuie sur la ~h~touche ~k~~TOGGLE_SUBMISSIONS~~w~ pour activer ou désactiver les missions camion de pompier.
+[TAXI_2]
+Concurrence Amicale
-[F_PASS1]
-Feu éteint!
+[TAXI_3]
+Cabmaggedon
-[F_RANGE]
-~g~La radio du camion de pompier ne capte plus rien. Rapproche-toi d'une caserne de pompiers!
+[ICE_1]
+Distribution
-[C_BREIF]
-~g~Suspect aperçu pour la dernière fois dans le secteur : ~a~.
+[TEX_1]
+Quatre fers
-[C_RANGE]
-~g~La radio de la voiture de police ne capte plus rien. Rapproche-toi d'un poste de police!
+[TEX_2]
+Funérailles
-[DODO_FT]
-Tu as 'volé' pendant ~1~ secondes!
+[TEX_3]
+Demolition Man
-[EBAL_A]
-Je connais un coin dans Le Quartier Rouge où on pourra se planquer,
+[PHIL_1]
+Trafiquant d'armes
-[EBAL_A1]
-faut que tu prennes le volant, mes mains tremblent trop.
+[PHIL_2]
+Boomshine Saigon
-[EBAL_1]
-Appuie sur la ~h~touche ~k~~VEHICLE_ENTER_EXIT~~w~ pour ~h~monter~w~ ou ~h~sortir~w~ d'un véhicule.
+[BIKE_1]
+Alliage d'Acier
-[EBAL_1B]
-Appuie sur la ~h~touche ~k~~VEHICLE_ENTER_EXIT~~w~ pour ~h~monter~w~ ou ~h~sortir~w~ d'un véhicule.
+[BIKE_2]
+Colère
-[EBAL_2]
-~g~Remonte dans la bagnole!
+[BIKE_3]
+Bécane
-[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!
+[ROCK_1]
+Love Juice
-[EBAL_D]
-Je connais un mec qu'a des relations. Il s'appelle Luigi.
+[ROCK_2]
+Psychopathe
-[EBAL_D1]
-On est pote, alors il pourra certainement te trouver du boulot. Viens, on y va.
+[ROCK_3]
+Promo
-[EBAL_E]
-Allez, viens, on va y faire un tour, histoire de te présenter.
+[ROCK_4]
+Les Love Fist!
-[EBAL_I]
-Le patron viendra bientôt vous voir...
+[HAT_1]
+Juju
-[EBAL_J]
-8-Ball a des trucs à faire en haut.
+[HAT_2]
+Bombes!
-[EBAL_K]
-Tu peux peut-être me rendre un service.
+[HAT_3]
+Raclée
-[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.
+[CUB_1]
+Cascades aquatiques
-[EBAL_N]
-Et garde bien tes mains sur le volant, compris ?
+[CUB_2]
+Chair à Canon
-[EBAL_4]
-~r~8-Ball est mort!
+[CUB_3]
+Bataille Navale
-[EBAL_5]
-~g~Prenez une caisse!
+[CUB_4]
+Vaudou
-[EBAL_6]
-~g~Va chercher Misty!
+[JOB_1]
+Accident de la route
-[LM1]
-'LES FILLES DE LUIGI'
+[JOB_2]
+Bute la femme!
-[LM2]
-'PAS DE SPANK POUR LA PEPEE'
+[JOB_3]
+Autocide
-[LM3]
-'LA MYSTERIEUSE MISTY'
+[JOB_4]
+Enregistrement
-[LM5]
-'LE BAL A BALLES'
+[JOB_5]
+Détails
-[LM1_2]
-~g~Emmène Misty au club de Luigi.
+[ANSWER]
+Appuie sur la ~h~~k~~PED_ANSWER_PHONE~~w~ pour répondre au téléphone.
-[LM1_3]
-~g~Klaxonne pour faire monter la fille.
+[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.
-[LM1_6]
-~g~Rentre dans la caisse!
+[MOB_01B]
+Je suis en train de me la couler douce au Malibu.
-[LM1_7]
-Arrête la bagnole près de Misty et laisse-la monter à bord.
+[MOB_01C]
+Tu me devras un ou deux petits services en échange, mon mignon. A tout à l'heure...
-[LM1_8]
-Tu peux retourner voir Luigi pour le boulot, ou visiter Liberty City.
+[MOB_02A]
+Sniiiiiiiiiiiif! Hé, salut, Tommy! Tommy?
-[LM2_A]
-Y'a une nouvelle saloperie sur le marché. Ca s'appelle la SPANK.
+[MOB_02B]
+On a un problème à l'imprimerie. Tu ferais mieux d'aller y jeter un coup d'oeil.
-[LM2_E]
-Un petit malin fourgue cette merde à mes filles du Port de Portland.
+[MOB_02C]
+Quelque chose a merdé. C'est le bordel. Faut que j'te laisse.
-[LM2_B]
-Va lui foutre une raclée!
+[MOB_03A]
+Mr Vercetti? J'ai ici un document signé qui établit formellement
-[LM2_G]
-Je me vengerai!
+[MOB_03B]
+que vous avez racheté toutes les dettes de BJ's Auto.
-[LM2_1]
-~g~Pique sa caisse et fais-la repeindre.
+[MOB_03C]
+La disparition soudaine de BJ ne me laisse pas d'autre choix
-[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_03D]
+que de vous tenir pour responsable du passif de cette société.
-[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_03E]
+Jusqu'à ce que ce compte soit complètement soldé
-[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_03F]
+vous devriez considérer les rues de Vice City comme très dangereuses.
-[LM2_3]
-~g~Planque la bagnole dans le garage de Luigi!
+[MOB_04A]
+Comment va, vieille branche?
-[LM2_4]
-~g~Repeins la bagnole!
+[MOB_04B]
+Ecoute, Tommy, j'avais oublié de te dire qu'on va avoir besoin de balaises en plus pour le concert.
-[LM3_A]
-Hé, faut que je te cause... OK, Mick, je te parle plus tard.
+[MOB_04C]
+Y'a un gang de motards dirigé par Mitch Baker, ça nous ferai une super publicité. Vraiment Rock'n'roll, Baby.
-[LM3_B]
-Comment ça va, gamin ?
+[MOB_04D]
+Règle ça pour moi et je te laisserai accéder aux coulisses du concert, d'accord?
-[LM3_C]
-Le fils du Don, Joey Leone, il veut voir sa régulière, Misty.
+[MOB_05A]
+Bien joué, Tommy, j'suis content d'avoir récupéré ma bécane.
-[LM3_D]
-Va la chercher à Hauteurs de Hepburn...
+[MOB_05B]
+Dis à Mr Kent Paul que la sécurité sera assurée pour le concert.
-[LM3_E]
-Mais fais gaffe, c'est le territoire de Diablo.
+[MOB_05C]
+Tu as ma parole.
-[LM3_F]
-Amène-la ensuite au garage de joey, à Trenton et vite!
+[MOB_05D]
+Bon, maintenant, évite de t'attirer des emmerdes.
-[LM3_H]
-Donc tes yeux, ils regardent la route et pas Misty, ok ?
+[MOB_06A]
+Tommy! Ceux d'en bas, ils parlent de toi, mon petit...
-[LM3_1D]
-Appuie sur la ~h~touche L3~w~ pour ~h~klaxonner~w~ et indiquer à Misty que tu es là.
+[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?
-[LM3_2]
-~g~Emmène Misty chez Joey!
+[MOB_06C]
+Fais un saut par ma cuisine un de ces jours, hein, Tommy?
-[LM3_4]
-~g~Va chercher Misty!
+[MOB_08A]
+Salut, Tommy, je me disais que t'aurais peut-être besoin d'un conseil en affaires...
-[LM3_5]
-Tu bosses pour Luigi, hein ? Il était temps qu'il se trouve un chauffeur digne de confiance.
+[MOB_08B]
+Dès que tu as une opération en route, il faut que tu passes prendre le fric de la semaine.
-[LM3_7]
-Je suis à toi dans une minute, poupée.
+[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_10]
-~g~Trouve une caisse!
+[MOB_08D]
+Ca va, Ken, je connais le business...
-[LM4_B]
-Va t'occuper de cette affaire pour moi.
+[MOB_08E]
+Ok, ok, je sais que tu sais. Je sais. C'était...
-[LM4_C]
-Si t'as besoin d'un calibre, va derrière Ammu-Nation en face du métro.
+[MOB_08F]
+C'était juste pour te dire que je sais que tu sais que je sais...
-[LM5_A]
-Le Bal de la police a lieu dans la vieille école près du Pont de Callahan.
+[MOB_08G]
+Ouvre simplement l'oeil!
-[LM5_B]
-Alors les flics auront besoin d'action à l'ancienne!
+[MOB_08H]
+T'inquiète, Ken, t'inquiète...
-[LM5_C]
-J'ai des filles partout dans les rues.
+[MOB_09A]
+Salut, Léo! J'ai du boulot pour toi!
-[LM5_D]
-Emmène-les au bal, histoire de faire d'une pierre deux coups : profit et détente!
+[MOB_09B]
+C'est pas Léo.
-[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_09C]
+Si Léo apprend que t'as son téléphone, il va te buter aussi sec!
-[LM5_2]
-~r~L'une des filles de Luigi est bonne pour la morgue!
+[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?
-[LM5_3]
-~g~T'as besoin d'un véhicule!
+[MOB_09E]
+T'as buté Léo? Alors, c'est que t'en as dans le froc! Tu veux bosser pour moi?
-[LM5_4]
-~g~Va ramasser les filles qui tapinent à St. Mark's.
+[MOB_09F]
+Passe au café de mon père dans Little Havana et on pourra causer entre hommes.
-[LM5_5]
-~g~Emmène les filles au bal!
+[MOB_10A]
+Tommy! Ecoute, j'ai un service à te demander!
-[LM5_8]
-~g~Filles au bal : ~1~
+[MOB_10B]
+Steve! Comment ça marche, le cinoche?
-[JM2]
-'AU REVOIR LEE'
+[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.
-[JM4]
-'LE CHAUFFEUR DE MONSIEUR'
+[MOB_10D]
+J'ai laissé des bagnoles dans les environs. Tu sauras quoi faire.
-[JM5]
-'TRANSPORT DE MARCHANDISES AVARIEES'
+[MOB_10E]
+OK, Steve, je vais voir ce que je peux faire. A plus tard.
-[JM1_1]
-~g~Amène la voiture de Forelli au garage de 8-Ball, au nord, derrière 'Caisses à crédit'.
+[MOB_11A]
+Salut petit, je me suis dit que j'allais te passer un coup de fil pour te donner un bon conseil.
-[JM1_2]
-~g~Ramène la bagnole au Bistro de Marco.
+[MOB_11B]
+Salut Avery, qu'est-ce que tu voulais me dire?
-[JM1_3]
-~g~Arme la bombe et CASSE-TOI EN VITESSE!
+[MOB_11C]
+Les perspectives ne manquent pas dans cette ville, si tu possèdes le bon business... Tu vois ce que je veux dire?
-[JM1_4]
-~g~T'as bousillé la caisse! Fais-la réparer!
+[MOB_11D]
+Je pense que oui...
-[JM1_5]
-~g~T'as pas armé la bombe!
+[MOB_11E]
+Je te conseille d'ouvrir l'oeil, et le bon, si tu veux dégotter un bon business. A plus tard.
-[JM1_6]
-~g~Gare la bagnole correctement!
+[MOB_11F]
+Ciao, Avery.
-[JM1_8A]
-~y~Hé, c'est mon gars préféré!
+[MOB12_A]
+Tommy! C'est Avery! Ecoute, je suis débordé de boulot pour le moment,
-[JM1_8B]
-~y~Chez l'artifier, tout est automatique. T'amènes la voiture, tu la gares, et le reste se fait tout seul!
+[MOB12_B]
+et j'ai un de mes réprésentants qui a besoin d'être chaperonné jusqu'aux Gator Keys.
-[JM1_8C]
-~y~Viens, le premier est gratuit, mais juste le premier, compris ?
+[MOB12_C]
+Je suis sur l'achat d'un terrain là-bas, alors j'envoie un mec graisser quelques pattes.
-[JM2_A]
-Chunky Lee Chong fout la merde avec la Spank pour un nouveau gang de Colombie... ou du Colorado... un coin comme ça...
+[MOB12_D]
+J'ai besoin que tu t'assures qu'il arrive bien là-bas. OK?
-[JM2_B]
-J'en sais rien. On s'en fout, après tout.
+[MOB12_E]
+OK, pas de problème, Avery! Mais où c'est que je le trouve, ce mec?
-[JM2_D]
-Il a dépassé les bornes!
+[MOB12_F]
+Il boucle une affaire au chantier. Je lui ai dit que tu le prendrais là-bas.
-[JM2_E]
-Il faut lui régler son compte!
+[MOB12_G]
+Ok, Avery. J'y vais. A plus tard.
-[JM2_G]
-Débrouille-toi avec un 9 mm, tu sais où il se trouve, non ?
+[MOB13_A]
+Vercetti? VERCETTI! Putain, mec, faut que tu me files un coup de main!
-[JM2_H]
-Et souviens-toi : fais gaffe à Chinatown, c'est le territoire de la Triade.
+[MOB13_B]
+Mr Moffat? Comment va la famille?
-[JM3_A]
-Bon, on va s'attaquer à un fourgon blindé.
+[MOB13_C]
+Merde, mais quel con! Tu m'entends?
-[JM3_B]
-Il part de Chinatown tous les jours.
+[MOB13_D]
+Ca m'a fait plaisir d'avoir des nouvelles...
-[JM3_C]
-Les balles traverseront pas son blindage, alors vole une caisse et rentre-lui dedans.
+[MOB13_E]
+Attends! Attends! Vercetti, euh... Tommy. Je peux t'appeler Tommy?
-[JM3_D]
-Cogne bien fort et les larbins de sécurité devraient pas demander leur reste!
+[MOB13_F]
+On est tous les deux dans les affaires, pas vrai? Et tu sais renifler les bonnes, hein?
-[JM3_E]
-Ensuite, t'emmènes le fourgon à l'entrepôt des docks et mes gars prennent le relais.
+[MOB13_G]
+J'ai pas le temps de causer, viens-en au fait!
-[JM3_F]
-Mais bon, ils vont pas faire leur ronde toute la journée, alors traîne pas en route!
+[MOB13_H]
+Du FRIC! Voilà le putain de fait!
-[JM3_1]
-~g~Emmène le fourgon à la planque.
+[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!
-[JM3_2]
-~g~Fonce dans le fourgon jusqu'à ce que ses dégâts soient inférieurs à 70%.
+[MOB13_J]
+Je t'appelle d'une cabine quelque part dans le trou du cul du monde!
-[JM4_B]
-Hé! C'est le gars dont je te parlais!
+[MOB13_K]
+Sors-moi de là avant qu'ils me chopent encore et... et... ah... meeeerde...
-[JM4_C]
-Ok. Ce gars, c'est pas un Italien, c'est pas un mécano, mais il peut réparer les choses.
+[MOB13_L]
+Eh bien, c'est que je suis très occupé pour les prochaines-
-[JM4_D]
-C'est Pops Capo, Toni Cipriani.
+[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!
-[JM4_E]
-Ouais, je suis Toni Cipriani.
+[MOB13_N]
+Je suis à genoux, Tommy! Et c'est les rotules dans la poussière que je te supplie...
-[JM4_F]
-Emmène-le au resto de la Mamma, à St Mark's, ok ?
+[MOB13_O]
+J'imagine que je pourrais passer dans le coin et voir si je te trouve...
-[JM4_G]
-Maintenant, écoute. Je prépare un truc et j'ai besoin d'un bon conducteur. Alors, passe me voir, ok ?
+[MOB13_P]
+Oh, merde, les voilà! Putain, magne-toi, Tommy! Vite!
-[JM4_2]
-Attends-moi ici. Et laisse tourner le moulin. C'est pas une visite de courtoisie.
+[MOB_14A]
+Salut, Tommy, on va bien s'entendre, toi et moi.
-[JM4_3]
-Une embuscade de la Triade! Sors-nous d'ici, gamin!
+[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,
-[JM4_4]
-La Triade pense qu'elle peut s'attaquer à moi! Hum! Tu te rends compte, A MOI!
+[MOB_14C]
+et ils y gardent les pots-de-vin de toutes ces dernières années.
-[JM4_6]
-Hé, fais gaffe à la bagnole! J'ai dit pas de lézards!
+[MOB_14D]
+C'est une sorte de caisse de retraite pour vieux garçons.
-[JM4_7]
-~g~Emmène Toni au restaurant de la Mamma.
+[MOB_14E]
+Evidemment, si cette info pouvait t'aider à ramasser un peu de ce pognon,
-[JM4_8]
-~r~Toni sert d'engrais aux chrisantèmes!
+[MOB_14F]
+j'imagine que tu te sentirais obligé de m'en refiler un peu, pas vrai, Tommy?
-[JM5_A]
-Magnifique! Réellement magnifique!
+[MOB_14G]
+Je vais garder ça à l'esprit, merci, Kent.
-[JM5_B]
-Très bien, c'est l'homme qu'il me fallait!
+[MOB_14H]
+Je m'appelle Paul, abruti! Et je suis du Kent, près de Londres.
-[JM5_D]
-Un des Forelli s'est cru un peu trop malin et il en a pris pour son grade!
+[MOB_14I]
+Pour ce que j'en ai à foutre de la campagne anglaise, depuis l'école...
-[JM5_E]
-Emmène le corps au broyeur de Harwood, ok ?
+[MOB15_A]
+Tommy, mon vieux, c'est Paul, du Kent.
-[JM5_1]
-~g~Emmène-le au broyeur!
+[MOB15_B]
+Il y a une ou deux authentiques dames qui ont ton nom plein la bouche, au Malibu.
-[JM5_2]
-~g~C'est les frères Forelli!
+[MOB15_C]
+De quoi tu parles?!
-[JM6_A]
-Joli morceau, hein?
+[MOB15_D]
+De gonzesses, de poulettes, de filles, quoi! Et bien élevées, pas le genre à causer pognon.
-[JM6_B]
-Ok, écoute : choisis une caisse dans l'entrepôt de Saint Mark's et va chercher quelques potes à moi.
+[MOB15_E]
+Faut que tu viennes voir ça.
-[JM6_C]
-Il font un retrait à la banque et ils ont besoin d'un taxi.
+[MOB16_A]
+Tommy, c'est Paulo, que pasa amigo?
-[JM6_D]
-J'ai dit que tu ferais parfaitement l'affaire, alors me déçois pas!
+[MOB16_B]
+Qu'est-ce que tu m'veux, Paul? J'ai pas besoin de fausses fringues de marque.
-[JM6_E]
-Amène-les à la banque avant 5 heures, et sois pas en retard!
+[MOB16_C]
+Très drôle, mon vieux, mais je fais pas dans la fringue de tapette, moi.
-[JM6_2]
-Laisse le moulin tourner, y'en a pas pour longtemps!
+[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.
-[JM6_3]
-Sors-nous de là!
+[MOB16_E]
+J'ai fait pas mal de pornos en Angleterre, mon vieux.
-[JM6_4]
-Débarrasse-toi des poulets et amène-nous à l'entrepôt!
+[MOB16_F]
+Au plumard, je suis une mitrailleuse lourde.
-[JM6_6]
-~g~Va voler une caisse moins voyante!
+[MOB16_G]
+Merci de me proposer tes services, Paul, j'y réfléchirai.
-[JM6_7]
-~g~Faut que tu prennes les 3 pour voler la banque!
+[MOB16_H]
+Sérieusement, pense à moi, après tout ce que j'ai fait pour toi...
-[TM1]
-'LINGE SALE'
+[MOB16_I]
+Justement, j'essaie de l'oublier.
-[TM2]
-'LA LIVRAISON'
+[MOB17_A]
+Tommy Vercetti, comment ça va, big boss?
-[TM3]
-'LA RENCONTRE'
+[MOB17_B]
+J'ai entendu tous ces trucs sur toi. Un flambeur en ville maintenant...
-[TM4]
-'LE TRIANGLE DES TRIADES'
+[MOB17_C]
+Paul, t'es bourré.
-[TM5]
-'LA HUITIEME PLAIE'
+[MOB17_D]
+Naan! Pauvre abruti! J'suis pas saoul!
-[TONI_P]
-J'ai un boulot urgent pour toi!
+[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!
-[TM1_A]
-~w~Assieds-toi, gamin. Prends une de ces putains de chaises.
+[MOB17_F]
+De toute façon, ne me traite pas comme ça.
-[TM1_B]
-~w~Alors, la laverie veut pas payer pour sa protection, hein ?
+[MOB17_G]
+Je suis pas une poire. Qui c'est qui t'a lancé dans cette ville? Hein, qui? Moi!
-[TM1_C]
-~w~La Triade pense qu'elle peut se mêler de mes affaires ?
+[MOB17_H]
+Ah ouais?
-[TM1_D]
-~w~On va apprendre à ces faux durs ce que c'est que des vrais hommes!
+[MOB17_I]
+Ouais!
-[TM1_E]
-~w~Ouais, on va leur apprendre à nous respecter! Aucun de mes gars ne se laisse intimider par une Triade minable!
+[MOB17_J]
+Paul, t'énerve pas. J'étais occupé, sois pas stupide.
-[TM1_F]
-~w~Ton père, qu'il repose en paix, se laissait pas faire par les Triades, à l'époque, en Sicile!
+[MOB17_K]
+Je suis pas stupide, connard! Ils me l'ont dit en maison de redressement!
-[TM1_G]
-~w~Pardon Ma. Oui Ma.
+[MOB17_L]
+Si tu cherches les emmerdes, mon pote, tu vas les trouver!
-[TM1_H]
-~w~Je veux que tu détruises les camionnettes de la laverie.
+[MOB17_M]
+Tommy, s'il te plaît! T'étais mon grand espoir! Te fous pas de moi!
-[TM1_I]
-~w~Et roule sur tous les gars de la Triade que tu croiseras.
+[MOB17_N]
+Paul, va roupiller un bon coup, sérieusement.
-[TM1_J]
-~w~8-Ball te donnera ce dont tu as besoin.
+[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.
-[TM2_A]
-~w~Toni est parti en faire saigner plus d'un, ou du moins, il essaie.
+[MOB18_B]
+Ah, mon pote, tu croiras jamais l'incroyable petit lot que je viens de lever...
-[TM2_AA]
-Il ne sera jamais aussi fort que son papa. Il t'a laissé un mot sur la table.
+[MOB18_C]
+Elle se promenait juste en bas dans Little Havana, mon pote.
-[TM2_B]
-~w~La laverie a accepté de payer. C'est du bon boulot!
+[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!
-[TM2_C]
-~w~Va chercher la thune et ramène-la ici. Et fais gaffe à la Triade.
+[MOB18_E]
+Elle ferait bander un eunuque! Elle m'a dit que j'étais le meilleur coup de sa vie et tout et tout!
-[TM2_D]
-~w~C'est comme les roquets : ça aboie, mais ça mord pas!
+[MOB18_F]
+Vas-y, trouve-la. A plus tard.
-[TM2_E]
-~w~Personne, je dis bien PERSONNE, ne se mêle des affaires de TONY CIPRIANI!
+[MOB19_A]
+Tommy V, c'est KP! Kent Paul. Le bruit court que des mecs veulent te faire la peau.
-[TM2_1]
-~g~Apporte le flouze à Toni!
+[MOB19_B]
+Ouvre l'oeil, mon pote. Et oublie pas... Je t'ai rien dit.
-[TM2_2]
-~g~Tu les as tous refroidis!
+[MOB_20A]
+Salut, Tommy, c'est Paul. Je viens juste d'entendre dire que t'avais été un vilain garçon.
-[TM3_MA]
-~w~Je ne sais pas où il est!
+[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...
-[TM3_MB]
-~w~Ce gamin, des fois, il sait même pas où il se trouve!
+[MOB_20C]
+Bon, dis à personne que je t'ai rencardé. Les grandes gueules finissent toujours par l'avoir dans l'os.
-[TM3_MC]
-~w~Son père, c'est sûr, c'était différent. Toujours au top, sûr de lui, viril...
+[MOB_20D]
+Enfin, j'ai entendu dire que ta tête a été mise à prix et que quelqu'un va essayer de t'avoir,
-[TM3_A]
-~w~Don Salvatore a convoqué une assemblée.
+[MOB_20E]
+alors fais gaffe, et m'oublie pas, mon pote.
-[TM3_B]
-~w~J'ai besoin de toi pour aller chercher la Stretch et Joey, son fils, au garage.
+[MOB71_A]
+Tommy, Thomas, c'est Cortez. Que pasa?
-[TM3_C]
-~w~Alors va chercher Luigi à son club et reviens ensuite me chercher.
+[MOB71_B]
+Les affaires tournent... Et toi, comment ça va?
-[TM3_D]
-~w~On ira tous ensemble chez le don.
+[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é.
-[TM3_E]
-~w~Ces Triades, elles savent jamais quand s'arrêter.
+[MOB71_D]
+Le peuple est la plus exigeante des maîtresses.
-[TM3_F]
-~w~Elles veulent la guerre, elles auront la guerre.
+[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_G]
-~w~Maintenant, faut y aller.
+[MOB71_F]
+Heureusement, à chaque fois, j'ai pris du galon.
-[TM3_1]
-~g~Prends la Stretch chez Joey.
+[MOB71_G]
+Je voulais vous demander quelque chose à propos de Mercedes...
-[TM3_2]
-~g~Va chercher Luigi.
+[MOB71_H]
+Ouais? Quoi?
-[TM3_3]
-~g~Va chercher Toni.
+[MOB71_I]
+Voilà, Tommy, Tommy, j'ai entendu toutes ces histoires et je sais pas quoi penser...
-[TM3_4]
-~g~Conduis tout le monde chez Salvatore.
+[MOB71_J]
+Peut-être que tout le monde essaye de m'humilier...
-[TM3_5]
-~y~Une embuscade de la Triade!
+[MOB71_K]
+Peut-être qu'elle se croit tout permis, mais dites-moi juste la vérité, Tommy, c'est vrai?
-[TM4_B]
-~w~Nous sommes en GUERRE! La Triade se sert d'une conserverie de poisson comme façade!
+[MOB71_L]
+Mais dites-moi juste la vérité, Tommy, c'est vrai?
-[TM4_C]
-~w~Ils règlent la majeure partie de leurs affaires au marché aux poissons de Chinatown.
+[MOB71_M]
+Qu'est-ce qui est vrai?
-[TM4_D]
-~w~Cette laverie doit toujours payer son assurance...
+[MOB71_N]
+Ces bruits qui courent... Elle va vraiment devenir avocate?
-[TM4_E]
-~w~Ils pensent que la Triade les protège, donc il faut leur montrer que ce n'est pas le cas.
+[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.
-[TM4_F]
-~w~Prends les garçons avec toi pour éliminer les chefs de la Triade!
+[MOB71_P]
+Je vous en prie, dites-moi que ce n'est pas vrai, je ne crois pas que je pourrais le supporter.
-[TM4_G]
-~w~Et puis, si t'en as l'occasion, descends quelques-uns de leurs porte-flingues.
+[MOB71_Q]
+Colonel, je peux vous assurer que Mercedes ne deviendra jamais avocate. Ne vous inquiètez pas.
-[TM4_GAT]
-~g~Tu as besoin d'un 'Camion de poisson de la Triade' pour entrer.
+[MOB71_R]
+Merci, Tommy, cette honte me serait insupportable. C'est une femme, pas un parasite, vous comprenez.
-[TM5_A]
-TEXT NO LONGER REQUIRED
+[MOB71_S]
+Je le sais, colonel.
-[TM5_B]
-~w~Ok, j'en ai marre de toutes ces conneries.
+[MOB71_T]
+Bon, vous allez devoir m'excuser, Tommy, mais le nouveau ministre de l'intérieur vient d'arriver...
-[TM5_C]
-~w~On va en finir une bonne fois pour toute avec la Triade de Liberty!.
+[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.
-[TM5_D]
-8-Ball a installé une bombe sur une benne à ordures.
+[MOB22_A]
+Tommy, vous vous révèlez très utile, amigo.
-[TM5_E]
-~w~Il y a un minuteur donc, si tu te chies dessus, y'aura pas de preuves. Va chercher la benne.
+[MOB22_B]
+Merci, Cortez. Et mon affaire?
-[TM5_F]
-~w~Fais gaffe, 8-Ball dit que c'est super-sensible et que la moindre secousse peut tout faire sauter.
+[MOB22_C]
+Tommy, je travaille inlassablement en ce sens pour aller au fond des choses et de la vérité dans cette terrible histoire.
-[TM5_G]
-~w~La conserverie de poisson laissera entrer la benne, après ce sera à toi de jouer.
+[MOB22_D]
+Vous avez ma parole, mais en attendant,
-[TM5_H]
-~w~Gare-toi entre les bonbonnes de gaz et casse-toi en vitesse!
+[MOB22_E]
+acceptez, je vous en prie, les sincères remerciements de mon peuple pour vos actions bénéfiques.
-[TM5_I]
-~w~Je veux qu'il pleuve des maquereaux!
+[MOB_25A]
+Tommy, c'est Cortez. Les Français me font beaucoup d'ennuis...
-[TM5_J]
-~w~C'est du Cecil B. DeMille que je veux, pas de la série Z!
+[MOB_25B]
+Les sales hypocrites! Ils passent des siècles à piller les pays pauvres et ils osent me traiter de voleur!
-[FM2]
-'LA FILLE DU MOGHOL'
+[MOB_25C]
+Je vais avoir besoin de votre aide aussi vite que possible.
-[FM4]
-'DERNIERES VOLONTES'
+[MOB_25D]
+Vite, Tommy, j'ai vraiment besoin de vous. Je hais ces maudits Français!
-[FM1_A]
-~w~Moi et les gars, on a besoin de causer affaires.
+[MOB_26A]
+Allo, Tommy?
-[FM1_B]
-~w~Alors tu vas veiller sur ma fille pendant la soirée.
+[MOB_26B]
+Ouais?
-[FM1_C]
-~w~MARIA! RAMENE TES FESSES PAR ICI!
+[MOB_26C]
+C'est moi, Baker. Je voulais juste te dire que j'ai beaucoup apprécié le spectacle.
-[FM1_D]
-~w~Cette petite conne fait toujours ça.
+[MOB_26D]
+Moi et mes gars, on veut te remercier, et te rappeler
-[FM1_E]
-~w~Et la voilà, la seule et unique reine de Saba!
+[MOB_26E]
+que tu as tout notre respect. Bon, salut. Et continue comme ça, mon pote.
-[FM1_F]
-~w~Qu'est-ce que tu faisais là-bas ?
+[MOB_29A]
+Allo? Vous êtes bien M. Tommy Vercetti?
-[FM1_G]
-~w~Enfin, peu importe, je parie que ça m'a coûté de l'argent!
+[MOB_29B]
+Ouais.
-[FM1_H]
-~w~Bon, tu crois quand même pas que je suis dans le coin pour te faire la conversation ?
+[MOB_29C]
+Bien. J'ai entendu dire que vous êtes l'homme à appeler quand on est victime d'une invasion de vermine.
-[FM1_I]
-~w~Monte dans cette bagnole et ferme ta grande gueule!
+[MOB_29D]
+Ca se peut...
-[FM1_J]
-~w~Prends la Stretch, mais tu la ramènes en un seul morceau, compris?
+[MOB_29E]
+Eh bien, là je suis vraiment envahi par la vermine. Les haïtiens sont partout...
-[FM1_K]
-~w~Et surveille-la, elle peut foutre la merde!
+[MOB_29F]
+Je m'appelle Umberto Robina et je vous propose une rencontre au Café Robina aussitôt que vous pourrez.
-[FM1_L]
-~w~Ouais, ouais, ouais, je suis sûr que le neurone de ton nouveau larbin a tout enregistré!
+[MOB_29G]
+Moi j'vous le dis, ces maudits haïtiens sont allés trop loin, cette fois...
-[FM1_M]
-~w~Et pis il est taillé comme une armoire normande, alors y'a pas de risque!
+[MOB_29H]
+Test
-[FM1_N]
-~w~Allez, Fido. On va chez Chico s'éclater un peu!
+[MOB_30A]
+Tommy, c'est Umberto Robina.
-[FM1_P]
-~g~C'est Chico, là! Arrête-moi à côté!
+[MOB_30B]
+Quoi de neuf au café?
-[FM1_S]
-~w~Bonsoir, jolie dame.
+[MOB_30C]
+Oh, merveilleux, Tommy, vraiment incroyable! Ici, plus de mauviettes, Tommy. Juste de vrais hommes et des belles filles!
-[FM1_TT]
-~w~22, V'LA LES FLICS!
+[MOB_30D]
+Je voulais te dire que moi et papa, maintenant, on te considère comme cubain.
-[FM1_1]
-~g~Retourne dans la Stretch!
+[MOB_30E]
+T'as fait tes preuves, mon frère et t'en as une sacrée paire dans l'pantalon!
-[FM1_2]
-~g~Monte dans la Stretch!
+[MOB_30F]
+Euh, merci, Umberto. Personne ne m'a dit ça depuis que je suis sorti de taule. Bon, salut.
-[FM1_3]
-~r~Si tu laisses Maria, Salvatore va l'avoir mauvaise, alors retourne la chercher!
+[MOB_33A]
+Tommy, c'est Phil! Bon, arrête tes conneries et écoute-moi, tu veux?
-[FM1_4]
-~g~Tu viens de larguer la femme du Don! Retourne à l'entrepôt et attends Maria!
+[MOB_33B]
+Bon. J'ai du whisky extra fort, presque fermenté, et je me demandais si tu voulais pas venir boire un coup...
-[FM1_5]
-~g~Ramène Maria chez Salvatore!
+[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_6]
-~g~Chico ne restera pas là tout le temps, alors emmène Maria voir la mer.
+[MOB_33D]
+Ca me fait cet effet, même si je vois plus rien d'un oeil. Je t'attends, t'entends?
-[FM1_7]
-~r~Maria est morte! Salvatore va être furax...
+[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_8]
-~r~T'as trucidé le fournisseur de Maria!
+[MOB_34B]
+Bon, si t'as besoin de quelque chose, tu m'appelles, t'entends?
-[FM2_J]
-Laisse-nous seuls un moment.
+[MOB_34C]
+Je n'oublie jamais ceux avec qui j'ai servi
-[FM2_A]
-Le Cartel colombien fabrique de la SPANK quelque part à Liberty.
+[MOB_34D]
+et je suis sûr que je peux t'aider, t'entends?
-[FM2_K]
-Mais on sait pas où, et on dirait qu'ils sont au courant de nos moindres faits et gestes.
+[MOB_35A]
+Tommy, la blessure cicatrise bien. Le truc drôle, c'est que
-[FM2_L]
-Y'a un gars, Bob le frisé, qui bosse au bar chaz Luigi.
+[MOB_35B]
+j'ai combattu dans six batailles et que je m'en suis toujours sorti sans une égratignure, et voilà!
-[FM2_M]
-Il dépense plus qu'il ne gagne...
+[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?
-[FM2_N]
-Il prend souvent un taxi pour rentrer chez lui après le boulot. Alors, suis-le.
+[MOB_35D]
+Aller, mon pote, laisse tomber les conneries sentimentales et va te boire un verre, t'entends?
-[FM2_O]
-Et si c'est lui la balance, descends-le...
+[MOB_36A]
+Tommy, c'est Phil. Je voulais te remercier pour le coup de main, mon pote.
-[FM2_F]
-Voilà notre copain. Monsieur grande gueule en personne.
+[MOB_36B]
+Salopard de Charlie, toujours à tendre des embuscades ici ou là,
-[FM2_G]
-T'as été suivi ? Tu sais que ce qui se passe ici, c'est notre petit secret...
+[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_H]
-Non, non, j'ai pas été suivi. T'as la came ?
+[MOB_40A]
+Salut, Tommy, c'est Sonny. Alors ce bronzage?
-[FM2_I]
-Voilà ta SPANK, alors crache le morceau.
+[MOB_40B]
+J'suis pas bronzé.
-[FM2_P]
-Ok, alors ce qui se passe, c'est que les Leone mènent la guerre sur deux fronts à la fois.
+[MOB_40C]
+Ouais et t'as pas non plus mon pognon, alors je m'interrogeais...
-[FM2_Q]
-Y'a une guerre de territoire avec la Triade qu'est pas prête de finir
+[MOB_40D]
+Je me disais : 'Qu'est-ce qu'il fout?' Alors, je te le demande, Tommy, qu'est-ce que tu fous?
-[FM2_R]
-et Joey Leone a foutu la merde avec les Forelli.
+[MOB_40E]
+Je cherche le pognon, Sonny, t'inquéte pas!
-[FM2_S]
-Ils perdent du terrain et des hommes tous les jours.
+[MOB_40F]
+Je m'inquiéte, Tommy, c'est mon genre,
-[FM2_T]
-Salvatore devient de plus en plus irascible et parano chaque jour. Il soupçonne tout le monde.
+[MOB_40G]
+parce que j'ai ce problème récurrent dans la vie de tomber sur des gens indignes de confiance...
-[FM2_U]
-Ben, quand je te vois, je me dis qu'il a pas forcément tort...
+[MOB_40H]
+Ne sois pas indigne de ma confiance, Tommy, s'il te plaît...
-[FM2_1]
-~g~Voilà Bob le frisé!
+[MOB_40I]
+Rends-nous à tous deux ce service. J'attends de tes nouvelles...
-[FM2_2]
-~g~Bob a quitté le club, suis-le!
+[MOB_41A]
+Tommy, tu te souviens de moi?
-[FM2_5]
-~g~Amène-le au port de Portland.
+[MOB_41B]
+Salut, Sonny.
-[FM2_6]
-~r~Bob montera jamais dans un taxi bousillé!
+[MOB_41C]
+Ouais, exactement, Sonny, on est de vieux amis,
-[FM2_7]
-~r~Bob le frisé s'est dégonflé. Le rendez-vous est annulé.
+[MOB_41D]
+mais tu ne m'écris jamais, tu ne m'appelles jamais. Tu ne veux plus qu'on soit amis?
-[FM2_8]
-~g~Cogne Bob le frisé!
+[MOB_41E]
+J'ai été très occupé à régler des trucs ici et là. Tu ne m'aides pas beaucoup, ici.
-[FM2_9]
-~r~Bob le frisé est mort!
+[MOB_41F]
+Oh, c'est ma faute? Bon, j'ai entendu que tu étais très occupé, d'accord,
-[FM2_10]
-~r~Bob le frisé s'est fait la malle!
+[MOB_41G]
+occupé à liquider des barons de la drogue, occupé à prendre le pouvoir.
-[FM2_11]
-~g~Gare-toi devant le club de Luigi, Bob le frisé devrait pas tarder à sortir.
+[MOB_41H]
+Alors je te préviens simplement de ne pas m'oublier, Tommy, parce que moi, je ne t'oublie pas...
-[FM2_12]
-~r~Il t'a faussé compagnie!
+[MOB_42A]
+Tommy.
-[FM3_A]
-~w~On devrait régler leur compte à ces bâtards de Colombiens.
+[MOB_42B]
+Sonny.
-[FM3_B]
-~w~Mais tant qu'on est en guerre avec les Triades, on n'est pas assez fort.
+[MOB_42C]
+Faut croire que t'es à moitié sourd, alors je vais me répéter :
-[FM3_C]
-~w~Les fonds du Cartel sont illimités, avec tout l'argent qu'ils se font sur la SPANK.
+[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?
-[FM3_D]
-~w~Si on les attaquait de front, ils nous lamineraient!
+[MOB_42E]
+Tu te fous vraiment d'ma gueule, Tommy, et ça me fait pas rire!
-[FM3_E]
-~w~Ils doivent fabriquer la SPANK sur le bateau vers lequel Le frisé t'a conduit.
+[MOB_43A]
+Tommy! Tommy! J'ai eu Sonny au téléphone. Tu m'écoutes?
-[FM3_F]
-~w~Va falloir utiliser nos cerveaux, ou plutôt un. Le tien!
+[MOB_43B]
+Je ne sais pas pour toi, mais il y a un mec qui menace de buter toute ma famille,
-[FM3_G]
-~w~Je te demande de détruire cette usine de SPANK comme une faveur, pour moi, Salvatore Leone.
+[MOB_43C]
+et ça me fout vraiment les jetons. Qu'est-ce que tu comptes faire?
-[FM3_H]
-~w~Si tu y arrives, ton avenir est assuré, tu auras tout ce que tu veux!
+[MOB_43D]
+Reste calme, Ken, tout va bien se passer.
-[FM3_I]
-~w~Va voir 8-Ball, il te dira comment faire, c'est un expert en explosifs.
+[MOB_43E]
+Je suis calme! Calme comme un homme qui craint pour sa propre vie!
-[FM3_8A]
-~w~Salut mon gars! Salvatore m'a téléphoné.
+[MOB_43F]
+Ken, j'ai d'autres choses en tête pour l'instant,
-[FM3_8B]
-~w~Pour un boulot comme ça, il va te falloir un sacré paquet de feux d'artifices!
+[MOB_43G]
+on s'occupera de Forelli quand l'heure sera venue.
-[FM3_8D]
-~w~Mais tu sais que tu en as toujours pour ton pognon avec moi!
+[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_8E]
-~w~Ok, au boulot!
+[MOB45_A]
+Tommy, faut qu'on cause sérieusement.
-[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_B]
+C'est quoi le problème, Lance?
-[FM3_8G]
-~w~Tiens, cette pétoire devrait te servir à faire sauter quelques têtes.
+[MOB45_C]
+C'est toi le problème, mon pote, j'ai l'impression que tu m'files pas une part équitable...
-[FM3_4]
-~g~Arrête la bagnole et laisse 8-Ball sortir.
+[MOB45_D]
+Mais le pire, c'est que tu m'as foutu la honte devant les mecs. Je supporte pas ça.
-[FM3_7]
-~r~8-Ball s'est fait refroidir!
+[MOB45_E]
+Lance, c'est pas ça du tout. T'as fait des bourdes, c'est tout.
-[FM3_8]
-~r~Les gardes ont été prévenus!
+[MOB45_F]
+Tommy, je suis pas ton petit messager et encore moins ton garçon de courses.
-[FM4_A]
-~w~Ah, voilà mon nettoyeur favori!
+[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.
-[FM4_B]
-~w~Je suis fier de toi, mon garçon, tu leur en as mis plein la gueule!
+[MOB45_H]
+Tommy, j'ai tout fait pour toi et tu me traites comme un con. Fais pas ça.
-[FM4_C]
-~w~J'ai juste un autre petit travail à te confier avant de pouvoir sabrer le champagne.
+[MOB45_I]
+Lance, je ne vais pas t'arnaquer ou te planter un couteau dans le dos, ok?
-[FM4_D]
-~w~Il y a une voiture devant le club de Luigi.
+[MOB45_J]
+T'énerve pas. C'est déjà assez dur comme ça, sans que tu perdes les pédales.
-[FM4_E]
-~w~L'intérieur est tapissé de cervelle!
+[MOB45_K]
+Fais-moi confiance. Tu m'entends? Tu m'entends?
-[FM4_F]
-~w~On a aidé un gars à se faire une idée, et y'a eu quelques salissures.
+[MOB45_L]
+Je t'entends, Tommy, mais je peux pas supporter ça plus longtemps.
-[FM4_H]
-~w~Emmène-le au broyeur avant que les flics ne le trouvent.
+[MOB45_M]
+Lance, arrête de déconner. Maintenant, je te préviens.
-[AM3]
-'PURGE DE PAPARAZZI'
+[MOB45_N]
+Tu m'entends? Relax! Prends quelques jours de repos et on en reparle, ok?
-[AM4]
-'JOUR DE PAYE'
+[MOB46_A]
+Tommy, c'est Lance.
-[AM5]
-'TANNER L'AGENT DOUBLE'
+[MOB46_B]
+Ouais?
-[AM1_A]
-Nous devons éclaircir certains points avant de poursuivre nos relations,
+[MOB46_C]
+Même pas un 'ça fait plaisir d'avoir des tes nouvelles'? Allez, mec, sois sympa!
-[AM1_B]
-affaires ou autres. Mettons cartes sur table.
+[MOB46_D]
+Je suis occupé. Qu'est-ce que tu veux?
-[AM1_C]
-Moi, je suis Yakuza et je sais que tu travailles pour la famille de Salvatore Leone.
+[MOB46_E]
+Rien. C'était juste pour te dire... Tu sais, Tommy, on peut faire ce truc.
-[AM1_D]
-Nous pouvons te donner du travail,
+[MOB46_F]
+Toi et moi, sans problème. Tu vois ce que je veux dire?
-[AM1_E]
-mais il faut d'abord nous prouver que t'as plus aucun lien avec la mafia.
+[MOB46_G]
+Va bien falloir qu'on le fasse, parce que sinon, on est morts, Lance.
-[AM1_G]
-Débrouille-toi pour qu'il n'arrive pas vivant à son club.
+[MOB46_H]
+On peut plus reculer, maintenant, mais merci de ton appel. On se reparle plus tard.
-[AM1_H]
-Pendant ce temps-là, Maria et moi, nous nous remémorerons le bon vieux temps.
+[MOB_47A]
+Tommy, c'est Lance, on a de gros problèmes. Amène-toi ici en vitesse.
-[AM1_I]
-Oh... Asuka, tu t'es trouvé un messager.
+[MOB52_A]
+Salut, Léo, je crois qu'on a un acheteur pour la marchandise de Diaz.
-[AM1_J]
-Ce n'est pas un simple messager.
+[MOB52_B]
+Il faut que tu l'appelles, mec, pour organiser le deal, tu comprends?
-[AM1_1]
-~g~Salvatore part de chez Luigi!
+[MOB52_C]
+T'es où, là?
-[AM1_2]
-~r~Tu t'es fait repérer!
+[MOB52_D]
+T'es sûr que ça va, Léo? T'as une voix bizarre...
-[AM1_3]
-~r~Tu as raté Salvatore!
+[MOB52_E]
+Dis-moi juste où t'es.
-[AM1_4]
-~r~Bravo, t'as effrayé la cible! Et t'es censé être un tireur d'élite, c'est ça ?
+[MOB52_F]
+Qui c'est qui cause? Je veux parler à Léo!
-[AM1_5]
-~g~Va au Le Quartier Rouge et attends que Salvatore sorte du club.
+[MOB52_G]
+Léo est parti pour un moment, je le remplace.
-[AM1_7]
-~r~Salvatore est chez lui, à siroter un whisky. T'es vraiment pas une flèche, toi!
+[MOB52_H]
+Va te faire foutre, connard!
-[AM1_8]
-~g~Salvatore va sortir de chez Luigi à environ ~1~:~1~.
+[MOB54_A]
+Salut, Tommy!
-[AM2_4]
-~g~Ils t'ont vu venir aussi nettement que si t'étais un éléphant rose!
+[MOB54_B]
+Salut, Mercedes, quoi de neuf?
-[AM3_A]
-Y'a un journaliste qui nous tourne autour.
+[MOB54_C]
+J'ai un nouvel appartement dans Vice Point.
-[AM3_B]
-Maria et moi, on part en vacances, histoire de te laisser le temps de te débarrasser de ce voyeur pervers.
+[MOB54_D]
+J'ai pensé que tu voudrais peut-être passer un de ces quatre...
-[AM4_A]
-Ah, mon meilleur homme!
+[MOB54_E]
+J'adorerai. A plus tard.
-[AM4_B]
-Maria est très occupée, mais je lui dirai que t'es passé.
+[MOB55_A]
+Tommy, c'est moi.
-[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 ?
+[MOB55_B]
+Salut, Mercedes.
-[AM4_D]
-Il est temps que tu rencontres notre homme au LPD.
+[MOB55_C]
+Tommy, je m'ennuie tellement! Quand est-ce qu'on va s'amuser?
-[AM4_E]
-Voilà sa paye pour le dernier service qu'il nous a rendu.
+[MOB55_D]
+Comment ça?
-[AM4_F]
-Il est terriblement prudent.
+[MOB55_E]
+Bon, je sais que t'es très occupé à te battre, à tuer des gens ou à les corrompre,
-[AM4_G]
-Va à la cabine de téléphone de Torrington aussi vite que tu peux et attends ses instructions.
+[MOB55_F]
+mais moi, j'ai envie de m'amuser un peu! Alors, ne m'oublie pas, Tommy!
-[AM5_A]
-Maria et moi, on est allé faire des courses.
+[MOB56_A]
+Tommy, j'ai entendu dire que tu avais tué Ricardo Diaz!
-[AM5_B]
-Notre informateur dans la police nous a dit qu'un de nos conducteurs est un flic sous couverture!
+[MOB56_B]
+Un feu accidentel s'est déclenché dans sa résidence...
-[AM5_C]
-Il ne vaut pas grand chose hors de sa voiture, alors on y a installé un capteur.
+[MOB56_C]
+Je pense qu'il a cramé dans sa chemise en acrylique.
-[AM5_D]
-Je veux qu'il souffre!
+[MOB56_D]
+Tommy, je suis si fière de toi! Je savais que tu étais un vrai macho!
-[AM5_1]
-Tanner est à tes trousses!
+[MOB56_E]
+Ah, mon dur de dur, je suis si fière d'être ton amie!
-[AS1]
-'L'APPAT'
+[MOB56_F]
+Je sais que tu vas être très occupé à essayer de t'emparer de cette ville,
-[AS2]
-'CAFE RAPIDO'
+[MOB56_G]
+mais ne m'oublie pas, d'accord?
-[AS4]
-'LA RANCON'
+[MOB57_A]
+C'est Mercedes. Je ne t'aime plus, Tommy!
-[AS1_A]
-~w~Miguel semble croire que je l'ai maltraité.
+[MOB57_B]
+C'est fini! C'est vrai! Parce que tu n'es plus gentil avec moi!
-[AS1_B]
-Il nous a néanmoins révélé à quel point Catalina s'inquiète de ta soif de vengeance.
+[MOB57_C]
+Tu ne me traites plus comme une dame! Tu m'ignores et je te déteste!
-[AS2_A]
-~w~On a sous-estimé les ambitions de Catalina avec la SPANK.
+[MOB57_D]
+Je veux que tu viennes me voir tout de suite! "
-[AS2_B]
-~w~Cela va plus loin qu'une vente à la sauvette dans les rues.
+[MOB58_A]
+Tommy.
-[AS2_D]
-~w~Il fourgue sa came sur des étals.
+[MOB58_B]
+Salut, Mercedes.
-[AS2_1]
-~g~Tous les étals des vendeurs de café de Portland ont été renversés!
+[MOB58_C]
+Bonjour monsieur le vrai dur! Je suis très en colère contre toi, Tommy!
-[AS2_2]
-~g~Tous les étals des vendeurs de café de l'île de Staunton ont été renversés!
+[MOB58_D]
+Ne m'oblige plus jamais à supporter Jezz Torrent!
-[AS2_3]
-~g~Tous les étals des vendeurs de café la vallée Shoreside ont été renversés!
+[MOB58_E]
+Il est pathétique! En plein milieu il a commencé à pleurer à cause de son toutou
-[AS2_4]
-~r~Le Cartel a mis en garde ses revendeurs!
+[MOB58_F]
+qui est mort quand il avait 7 ans et parce que sa mère ne l'a jamais aimé...
-[AS2_5]
-~g~Il y a toujours des stands de café à la vallée Shoreside et sur l'île Staunton!
+[MOB58_G]
+En plus, Tommy, il porte une perruque et un soutien-gorge dans l'intimité!
-[AS2_6]
-~g~Il y a toujours des stands de café à la vallée Shoreside!
+[MOB58_H]
+Je t'en veux vraiment!
-[AS2_7]
-~g~Il y a toujours des stands de café sur l'île Staunton!
+[MOB59_A]
+Ooh Tommy, c'est Mercedes.
-[AS2_8]
-~g~Il y a encore des étals de vendeurs de café à Portland!
+[MOB59_B]
+Je voulais juste te dire que je m'étais éclatée sur le tournage!
-[AS2_9]
-~g~Il y a toujours des stands de café dans Portland et la vallée Shoreside!
+[MOB59_C]
+Si tu as quelque chose d'autre de ce genre, pense à moi!
-[AS2_10]
-~g~Il y a toujours des stands de café dans Portland et sur l'île Staunton!
+[MOB59_D]
+Je suis sincère! J'ai toujours voulu être actrice!
-[AS2_12]
-~g~Parcours les districts de Liberty pour trouver ~b~les étals de Café Rapido!
+[MOB59_E]
+Je crois que j'ai beaucoup appris sur l'art dramatique!
-[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?
+[MOB59_F]
+C'est tellement révélateur! Merci beaucoup! On se voit très bientôt, adios!
-[AS3_B]
-~w~Allez, encore un peu...
+[MOB_99]
+Rends-toi à la cabine indiquée.
-[AS3_D]
-~w~Mon homme à tout faire!
+[MOB_98]
+Rends-toi à la cabine indiquée.
-[AS3_E]
-~w~Je m'ennuyais alors je suis venue tenir compagnie à Asuka.
+[MOB_97]
+Rends-toi à la cabine indiquée.
-[AS3_1]
-~g~Trouve un ~r~bateau~g~ et rejoins la ~b~bouée repère!
+[MOB_96]
+Rends-toi à la cabine indiquée.
-[AS3_3]
-~g~Attends que l'~y~avion~g~ s'approche!
+[MOB_95]
+Rends-toi à la cabine indiquée.
-[AS3_5]
-~g~Récupère la marchandise!
+[A_TIME]
++~1~ secondes
-[AS3_4]
-~g~Sers-toi d'un lance-roquettes pour descendre l'~y~avion~g~!
+[F_RANGE]
+La radio du camion de pompiers ne capte plus rien. Rapproche-toi d'une caserne!
-[AS3_2]
-~b~Va vers les bouées repères! ~y~L'avion est en phase d'approche!
+[DODO_FT]
+Tu as 'volé' pendant ~1~ secondes!
-[AS3_6]
-~g~~1~ SUR 8
+[GA_8]
+Utilise le détonateur pour armer la bombe.
-[KM1]
-'LA GRANDE EVASION'
+[GA_10]
+Bravo. Voilà tes ~1~$.
-[KM3]
-'NEGOCIATION'
+[GA_11]
+On en a déjà des comme ça. Ca nous sert à rien!
-[KM4]
-'SHIMA'
+[GA_12]
+Bombe armée
-[KM5]
-'LES RIVIERES POURPRES'
+[GA_13]
+Comme un pro! Finis la liste et t'auras un bonus!
-[KM1_A]
-Ma soeur m'a parlé de toi en des termes élogieux,
+[GA_14]
+Toutes les voitures! PARFAIT! Tiens, voilà un petit quelque chose!
-[KM1_E]
-même si je suis toujours pas convaincu qu'un gaijin à autre chose à offrir que des déceptions.
+[GA_15]
+J'espère que t'aimes la nouvelle couleur.
-[KM1_B]
-Quoique, tu pourrais peut-être m'aider à régler un petit problème.
+[GA_16]
+La peinture est en option!
-[KM1_F]
-Bien sûr, un échec te serait fatal.
+[GA_19]
+Ce modèle ne nous intéresse pas!
-[KM1_C]
-Un kanbu Yakuza est en garde à vue, en attente d'un transfert au palais de justice.
+[GA_20]
+On en a trop des comme ça! Désolé, mec.
-[KM1_G]
-C'est un membre apprécié de notre famille.
+[CHASE]
+Attention maximale des médias
-[KM1_H]
-Libère-le et amène-le au dojo de Bedford Point.
+[CHASE1]
+Ignoré
-[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.
+[CHASE2]
+Ennuyeux
-[KM1_1]
-~g~Vole une bagnole de flics!
+[CHASE3]
+Plus ou moins intéressant
-[KM1_2]
-~g~Equipe-la d'une bombe!
+[CHASE4]
+Journal local page 7
-[KM1_3]
-~g~Maintenant, emmène-la au dojo des Yakuzas!
+[CHASE5]
+Journal local La une
-[KM1_5]
-~g~Bien, maintenant, va au poste de police.
+[CHASE6]
+Vice Courier Rubrique 1
-[KM1_6]
-~g~Equipe la voiture d'une bombe!
+[CHASE7]
+Vice Courier La une
-[KM1_7]
-~g~Réservé aux véhicules de police!
+[CHASE8]
+Télé locale 3h du mat'
-[KM1_9]
-~r~Tu n'as pas utilisé de voiture piégée pour détruire le mur.
+[CHASE9]
+Télé locale Infos
-[KM1_10]
-~r~Le Yakuza Kanbu est mort, tout comme ton honneur!
+[CHASE10]
+Télé locale Direct
-[KM1_11]
-~r~Tu t'es fouré tout seul dans le pétrin!
+[CHASE11]
+UFA Today page 12
-[KM2_A]
-Dans ce milieu, l'étiquette ne doit jamais être sous-estimée. Au contraire!
+[CHASE12]
+UFA Today page 4
-[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.
+[CHASE13]
+Photo dans UFA Today
-[KM2_C]
-Cet homme est un passionné de voitures et il a demandé que nous lui fournissions certains modèles pour sa collection.
+[CHASE14]
+Télé nationale 4h du mat'
-[KM2_F]
-Mon honneur m'interdit de refuser.
+[CHASE15]
+Télé nationale Infos
-[KM2_2]
-~g~Voiture livrée.
+[CHASE16]
+Télé nationale Direct
-[KM3_A]
-Face au danger, l'inconscient tourne le dos alors que le sage fait front.
+[CHASE17]
+Infos internationales
-[KM3_B]
-Nous avons prévenu à plusieurs reprises le Cartel colombien qu'il fallait laisser nos intérêts à Liberty tranquilles.
+[CHASE18]
+Crise nationale
-[KM3_C]
-En ce moment même, ils négocient avec les Jamaïcains pour se moquer encore plus de nous.
+[CHASE19]
+Crise internationale
-[KM3_D]
-Ils sont en train de passer un accord pour l'ensemble de la ville.
+[CHASE20]
+Evénement mondial
-[KM3_F]
-Prends un de mes hommes, vole une bagnole de Yardie et va présenter nos respects aux Colombiens.
+[CHASE21]
+Truc de légendes
-[KM3_E]
-Pour notre honneur, ils doivent tous mourir!
+[CR_1]
+La grue ne peut pas soulever ce véhicule.
-[KM3_2]
-~g~Va prendre ton contact.
+[PU_MONY]
+T'as pas assez de liquide.
-[KM3_3]
-~g~La réunion a lieu sur le parking de l'hôpital de Rockford!
+[CO_ALL]
+Tu les as toutes eues. Tiens, voilà pour toi...
-[KM3_4]
-~r~Ils ont filé!
+[FEM_ON]
+Activé
-[KM3_6]
-~g~Supprime-les, tue-les tous!
+[FEM_OFF]
+Désactivé
-[KM3_8]
-~g~Il te faut une bagnole de Yardie pour ce boulot!
+[FEM_YES]
+Oui
-[KM3_9]
-~r~L'un des Colombiens est mort, l'accord est caduc.
+[FEM_NO]
+Non
-[KM3_10]
-~r~Le contact est mort!
+[FEM_RET]
+Réessayer
-[KM4_A]
-La seule vraie force consiste à ne jamais montrer ses faiblesses.
+[FEC_NA]
+NA
-[KM4_C]
-Va récupérer l'argent immédiatement pour qu'on puisse le placer sur les comptes du casino.
+[FEC_CWL]
+Faire défiler les armes vers la gauche
-[KM4_1]
-Je peux pas vous payer et même si je pouvais, je le ferais pas!
+[FEC_CWR]
+Faire défiler les armes vers la droite
-[KM4_9]
-Un gang de jeunes vient de dévaliser cet endroit! Ils ont tout pris!
+[FEC_LOF]
+Regarder devant
-[KM4_2]
-Vous ne servez à rien!
+[FEC_TAR]
+Viser
-[KM4_10]
-Quel genre de Yakuza êtes-vous? hein?
+[FEC_MOV]
+Déplacement
-[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_CAM]
+Modes caméra
-[KM4_4]
-~g~Réglez son compte au gang et récupérez ~b~l'argent de la protection~g~!
+[FEC_PAU]
+Pause
-[KM4_7]
-~r~Le commerçant est mort!
+[FEC_ENV]
+Monter dans un véhicule
-[KM4_5]
-Donald Love aimerait que vous passiez prendre le thé chez lui afin d'avoir une conversation avec vous.
+[FEC_JUM]
+Sauter
-[KM4_6]
-Tout l'argent est là!
+[FEC_ATT]
+Attaquer ou tirer
-[KM4_8]
-~g~Malette récupérée!
+[FEC_RUN]
+Courir
-[KM5_A]
-TOI! Et c'est maintenant que tu te décides à te montrer!
+[FEC_FPC]
+Vue subjective
-[KM5_B]
-Il semblerait que ta tentative pour empêcher les Jamaïcains
+[FEC_LL]
+Rergarder à gauche
-[KM5_B1]
-de s'allier aux Colombiens ait complètement raté!
+[FEC_LB]
+Regarder derrière
-[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_LR]
+Regarder à droite
-[KM5_D]
-Les membres du Cartel se foutent de nous et de moi surtout!
+[FEC_HOR]
+Klaxon
-[KM5_E]
-Je te donne une dernière chance de me prouver que ma soeur avait raison de te faire confiance!
+[FEC_VES]
+Commandes du véhicule
-[KM5_F]
-Débarrasse-moi de tous ces rats et rachète-toi avec leur sang!
+[FEC_BRA]
+Freiner ou marche arrière
-[KM5_3]
-~r~Tu n'as pas réussi à tuer au moins ~1~ Yardies.
+[FEC_HAB]
+Frein à main
-[KM5_4]
-~g~Bravo, tu as tué ~1~ Yardies.
+[FEC_CAW]
+Arme du véhicule
-[KM5_5]
-~g~Bravo! Tu as tué ~1~ Yardies. Bonus : ~1~$
+[FEC_ACC]
+Accélérateur
-[RM1]
-'EQUILIBRER LA BALANCE'
+[FEC_CCF]
+Configuration :
-[RM3]
-'PREUVES A PROUVER'
+[FEC_CF1]
+Config. 1
-[RM4]
-'PECHE AU GROS'
+[FEC_CF2]
+Config. 2
-[RM5]
-'LE MARTEAU ET L'ENCLUME'
+[FEC_CF3]
+Config. 3
-[RM1_D]
-Il est sous protection dans une propriété de WitSec à Newport, des appartements à l'arrière du parking.
+[FEC_CF4]
+Config. 4
-[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.
+[FEC_CDP]
+Affichage manette :
-[RM1_1]
-~g~Vérifie la maison du programme de protection des témoins.
+[FEC_ONF]
+à pied
-[RM1_2]
-~g~Chope McAffrey!
+[FEC_INC]
+En voiture
-[RM2_A1]
-Hé, gamin, par là!
+[FEC_VIB]
+Vibrations :
-[RM2_A]
-Un vieux pote à moi de l'armée a une affaire à Rockford.
+[FEL_ENG]
+Anglais
-[RM2_D]
-Il a besoin d'un coup de main et, en échange, il te fera des prix d'enfer sur son matos.
+[FEL_FRE]
+Français
-[RM2_E]
-Ray a téléphoné... mais je pensais que vous seriez plusieurs...
+[FEL_GER]
+Allemand
-[RM2_F]
-Bon, trois bras valent mieux qu'un, alors prends ce qu'il te faut.
+[FEL_ITA]
+Italien
-[RM2_G]
-~g~Va voir Phil!
+[FEL_SPA]
+Espagnol
-[RM2_H]
-~r~Phil a été tué!
+[FED_DBG]
+Menu Debug
-[RM2_L]
-Héhé! Si je t'avais eu comme partenaire au Nicaragua, j'aurais peut-être encore mes deux bras!
+[FED_RID]
+Recharger IDE
-[RM2_N]
-Laisse le fric. Maintenant, dégage, je m'occupe des poulets.
+[FED_RIP]
+Recharger IPL
-[RM3_D]
-La pièce à conviction est en train de rouler dans la ville.
+[FED_PAH]
+Analyser Saut
-[RM3_E]
-Va falloir que tu tamponnes cette caisse et que tu récupères les preuves au fur et à mesure qu'elles tombent!
+[FED_DFL]
+CTheScripts::DbgFlag
-[RM3_F]
-Quand t'auras tout, laisse-les dans la voiture et brûle-la.
+[FED_DLS]
+Lumière blanche de debug allumée
-[RM3_G]
-C'est une bonne affaire pour tous les deux, tu sais, gamin.
+[FED_SPR]
+Affiche les groupes de pietons
-[RM3_1]
-~g~Laisse les preuves dans la voiture et brûle-la.
+[FED_SCR]
+Affiche les groupes en voiture
-[RM3_4]
-~g~L'accusation n'a pas tenu compte des pièces à conviction!
+[FED_SCZ]
+Affiche les zones de massacre
-[RM3_6]
-~r~Ces photos seront dans tout Liberty!
+[FED_DSR]
+Debug les demandes de répartition par niveaux
-[RM3_7]
-~g~Brûle la voiture!
+[FED_SCP]
+gb Indique les polys de collision
-[RM4_A]
-Mon partenaire est un rat.
+[PL_STAT]
+Stats du joueur
-[RM4_C]
-Il va souvent pêcher en bateau près du phare de Portland Rock, la nuit.
+[PE_WAST]
+Personnes tuées par toi
-[RM4_D]
-Vole une vedette de la police et assure-toi que ses sales plans de traître tombent à l'eau!
+[PE_WSOT]
+Personnes tuées par d'autres
-[RM4_1]
-~g~Vole une vedette de la police.
+[TM_BUST]
+Nb de fois capturé
-[RM4_2]
-~g~Va jusqu'au phare et 'occupe-toi' du partenaire de Ray!
+[GNG_WST]
+Gangsters tués
-[RM5_A]
-Espèce de bon à rien!
+[DED_CRI]
+Criminels tué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!
+[PER_COM]
+Pourcentage accompli
-[RM5_B]
-Je t'ai filé de la thune pour buter ce témoin et il est encore en vie!
+[KGS_EXP]
+Kilos d'explosifs utilisés
-[RM5_B1]
-Et il va faire une déposition devant les fédéraux aujourd'hui!
+[ACCURA]
+Précision
-[RM5_C]
-Ils vont le transférer d'un moment à l'autre de l'Hôpital Général Carson à Rockford!
+[ST_WEAP]
+Budget arsenal
-[RM5_D]
-S'il crache le morceau, je vais cracher mes dents, et plus encore...
+[ST_PROP]
+Budget propriété
-[RM5_E]
-Alors fais ce putain de boulot pour lequel je t'ai payé!
+[ST_AUTO]
+Budget réparation et peinture voiture
-[RM5_1]
-~g~Intercepte l'ambulance.
+[ST_PHOT]
+Photos prises
-[RM5_2]
-~g~Tu t'es fait repérer!
+[ST_LOAN]
+Visites des usuriers
-[RM5_3]
-~g~C'était un piège à cons!
+[ST_STOR]
+Magasins liquidés
-[RM5_4]
-~g~Les balles ne peuvent pas traverser cette armure!
+[ST_MOVI]
+Cascades de films
-[RM5_5]
-~g~Cette armure est recouverte d'amiante!
+[ST_PIZZ]
+Pizza livrées
-[RM5_7]
-~r~Le témoin est arrivé à bon port!
+[ST_GARB]
+Collectes de détritus effectuées
-[RM5_8]
-~g~Le témoin s'est noyé!
+[ST_ICEC]
+Crèmes glacées vendues
-[LOVE2]
-'HARA-KIRI WAKA-SHIRA'
+[TOP_SHO]
+Meilleur score au champ de tir
-[LOVE3]
-'RIEN QU'UNE GOUTTE DANS L'OCEAN'
+[SHO_RAN]
+Position au champ de tir
-[LOVE1_A]
-Tout d'abord, je tiens à te remercier pour m'avoir aidé à régler cette affaire privée.
+[SEAGULL]
+Mouettes descendues
-[LOVE1_F]
-Les gens croient tout ce qu'on leur raconte de nos jours!
+[PROPOWN]
+Propriété possédée
-[LOVE1_D]
-Ils essaient de m'extorquer plus d'argent, mais j'aime pas renégocier mes accords!
+[ST_TIME]
+Temps de jeu
-[LOVE1_E]
-Un accord est un accord et il n'auront rien de plus de moi!
+[ST_FTIM]
+Heures de vol
-[LOVE1_G]
-Va aider mon ami, tu as carte blanche.
+[ST_PRAN]
+Classement pilote
-[LOVE1_2]
-~g~Sauve le vieux bridé.
+[ST_RAN0]
+Apprenti
-[LOVE1_3]
-~g~Amène le vieux bridé à l'appartement de Donald Love.
+[ST_RAN1]
+Navigateur
-[LOVE1_4]
-~g~Le vieux bridé doit se trouver dans un de ces garages...
+[ST_RAN2]
+Copilote
-[LOVE1_6]
-~r~Les tripes du vieux bridé sont étalées sur le trottoir. Attention, ça glisse!
+[ST_RAN3]
+Junior
-[LOVE1_7]
-~g~Les portes ne s'ouvriront que pour laisser passer une voiture du gang des Colombiens.
+[ST_RAN4]
+Compétent
-[LOVE2_A]
-Rien de mieux qu'une bonne vieille guerre des gangs pour faire marcher l'immobilier,
+[ST_RAN5]
+Senior
-[LOVE2_B]
-en dehors d'une bonne épidémie... mais ça serait peut-être un peu trop.
+[ST_RAN6]
+As
-[LOVE2_C]
-J'ai remarqué que les Yakuzas et les Colombiens n'étaient pas très copains.
+[ST_RAN7]
+Baron rouge
-[LOVE2_D]
-C'est une opportunité que nous devons saisir!
+[ST_DRWN]
+Poissons nourris
-[LOVE2_E]
-Je veux que tu tues le waka-gashira des Yakuzas, Kenji Kasen.
+[ST_FASH]
+Budget fringues
-[LOVE2_F]
-Kenji est à une réunion au sommet du parking à plusieurs étages de Newport.
+[ST_DAMA]
+Propriété détruite
-[LOVE2_G]
-Procure-toi une voiture du Cartel et tue-le!
+[TM_DED]
+Visites à l'hôpital
-[LOVE2_H]
-Les Yakuzas doivent accuser le Cartel de leur déclarer la guerre.
+[DAYSPS]
+Jours passés dans le jeu
-[LOVE2_1]
-~g~Va à Fort Staunton et vole une voiture du gang des Colombiens.
+[NUMSHV]
+Visites dans l'entrepôt
-[LOVE2_2]
-~g~Maintenant, rends-toi au ~p~parking de Newport~g~ et élimine Kenji.
+[MXCARD]
+Dist. max. de saut de Cascade dangereuse (ft)
-[LOVE2_3]
-~r~Si tu n'as pas de voiture du Cartel, tu seras démasqué!
+[MXCARJ]
+Hauteur max. de saut de Cascade dangereuse(ft)
-[LOVE2_4]
-~r~Les Yakuzas t'ont reconnu!
+[MXCARDM]
+Dist. max. de saut de Cascade dangereuse (m)
-[LOVE2_6]
-~r~Tu as tué tous les témoins!
+[MXCARJM]
+Hauteur max. de saut de Cascade dangereuse (m)
-[LOVE3_A]
-De nos jours, certaines marchandises de valeur sont difficiles à importer.
+[MXFLIP]
+Saltos max. de saut de Cascade dangereuse
-[LOVE3_C]
-Plusieurs paquets vont être jetés à l'eau.
+[MXJUMP]
+Rotation max. de saut de Cascade dangereuse
-[LOVE3_D]
-Récupère-les avant tout le monde.
+[BUL_FIR]
+Balles tirées
-[LOVE3_1]
-~g~Procure-toi un ~r~bateau~g~ et suis l'~y~avion~g~!
+[BUL_HIT]
+Balles ayant atteint la cible
-[LOVE4]
-'VOL AU VENT'
+[SPRAYIN]
+Peintures
-[LOVE5]
-'ACCORTE ESCORTE!'
+[BSTSTU]
+Meilleure cacade jusqu'à maintenant
-[LOVE4_A]
-Merci beaucoup pour ces paquets, mais ils n'étaient qu'un leurre!
+[INSTUN]
+Cascade dangereuse
-[LOVE4_B]
-Je suis désolé pour ça, mais c'est quelque fois comme ça dans les affaires.
+[PRINST]
+Cascade dangereuse parfaite
-[LOVE4_C]
-Mon réel objectif se trouvait depuis le début caché à bord de l'avion.
+[DBINST]
+Double cascade dangereuse
-[LOVE4_F]
-J'avais graissé la patte aux autorités.
+[DBPINS]
+Double cascade dangereuse parfaite
-[LOVE4_1]
-~r~Les Colombiens sont là!
+[TRINST]
+Triple cascade dangereuse
-[LOVE4_2]
-~g~Le paquet est parti! Suis les Colombiens et récupère-le!
+[PRTRST]
+Triple cascade dangereuse parfaite
-[LOVE4_3]
-~g~Panlantic construction ?
+[QUINST]
+Quadruple cascade dangereuse
-[LOVE4_5]
-~g~Le paquet devrait être à bord de l'avion...
+[PQUINS]
+Quadruple cascade dangereuse parfaite
-[LOVE4_6]
-~g~Prends l'ascenseur pour accéder au sommet de la tour!
+[NOSTUC]
+Aucune cascade dangereuse réalisée
-[LOVE5_B]
-Mon ami oriental a besoin d'une escorte pour l'accompagner pendant l'authentification de ma dernière acquisition.
+[NOUNIF]
+Sauts uniques accomplis
-[LOVE5_1]
-~g~Vas-y!
+[NMISON]
+Tentatives de mission
-[LOVE5_2]
-~g~Tu vas avoir besoin d'une caisse!
+[PASDRO]
+Passagers perdus
-[LOVE5_3]
-~g~Passe devant et contrôle la sortie du tunnel!
+[MONTAX]
+Total des courses en taxi
-[LOVE5_4]
-~r~Protège le camion!
+[DAYPLC]
+Dépenses quotidiennes de police
-[RM6]
-'L'HOMME A ABATTRE!'
+[CRIMRA]
+Taux de criminalité :
-[RM6_A]
-T'as pas été suivi ? Parfait!
+[STPR_1]
+Le Malibu
-[RM6_B]
-Ca y est! Je suis cuit, déjà mort, en quelque sorte!
+[STPR_2]
+Imprimerie
-[RM6_D]
-J'ai un contrat sur ma tête, alors je me casse!
+[STPR_3]
+Studio de cinéma
-[RM6_E]
-Amène-moi à l'aéroport et t'auras un bon pourboire!
+[STPR_4]
+Usine de crème glacée
-[RM6_666]
-Prends soin de ma Patriot blindée. On se verra à Miami, Ray!
+[STPR_5]
+Concession automobile
-[CAT1]
-'LA RANCON'
+[STPR_6]
+Compagnie de taxis
-[CAT2]
-'L'ECHANGE'
+[STPR_7]
+Chantier naval
-[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 ?
+[SET1EN]
+Config. 1. Activée
-[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!
+[GMSAVE]
+Sauvegarder partie
-[CAT2_G]
-J'étais complètement flippée, mais, je me suis dit, Maria, t'es une grande fille maintenant.
+[FEDS_TB]
+Retour
-[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.
+[FEST_OO]
+sur
-[CAT2_I]
-Son mec a recommencé à aller voir ailleurs et...
+[FEC_TUC]
+Commandes tourelle
-[CAT1_F]
-Rattrape Catalina avant la fin du temps imparti!
+[FEC_RS3]
+Faire défiler les stations de radio (touche L3)
-[CAT_MON]
-~g~T'as pas encore assez d'argent. T'as besoin de 500 000$.
+[FEC_HO3]
+Klaxonner (touche L3)
-[BITCH_D]
-~g~Maria est morte!
+[C_FAIL]
+Mission d'autodéfense terminée!
-[WEATHER]
-METEO AGITEE
+[C_ESCP]
+~r~Le suspect s'est échappé!
-[WEATHE2]
-METEO NORMALE
+[C_VIGIL]
+BONUS AUTODEFENSE!
-[8001]
-Tu as échoué lamentablement!
+[HEAL_A]
+Ton niveau de ~h~santé~w~ s'affiche en orange en haut à droite de l'écran.
-[1000]
-TU ES MORT
+[WRONGCD]
+Disque invalide. Insère le bon disque.
-[1001]
-TU ES MORT
+[NOCD]
+Le compartiment à disque est vide. Insère un disque.
-[1002]
-TU ES MORT
+[OPENCD]
+Le compartiment à disque est ouvert. Referme-le.
-[1003]
-TU ES MORT
+[CDERROR]
+Erreur au cours de la lecture du DVD de Grand Theft Auto: Vice City
-[1004]
-TU ES MORT
+[RESTART]
+Démarrage d'une nouvelle partie
-[1005]
-CAPTURE!
+[GA_3]
+Plus de cadeaux. 100$ pour repeindre!
-[1006]
-CAPTURE!
+[GA_1]
+Oula! Je ne touche à rien d'aussi chaud, moi!
-[1007]
-CAPTURE!
+[GA_1A]
+Reviens quand tu seras moins occupé...
-[1008]
-CAPTURE!
+[HELP9_C]
+Appuie sur la~h~ ~k~~PED_FIREWEAPON~ ~w~pour ~h~tirer~w~ avec le fusil à lunette.
-[1009]
-CAPTURE!
+[TAXI2]
+~r~Tu n'as plus le temps!
-[GA_4]
-Une voiture piégée coûte 1000$ pièce!
+[PAGEB13]
+Santé livrée à la planque
-[GA_5]
-Ta voiture est déjà équipée d'une bombe.
+[PAGEB14]
+Adrénaline livrée à la planque
-[GA_6]
-Gare-la, arme la bombe avec la ~h~touche ~k~~PED_FIREWEAPON~~w~ et CASSE-TOI!
+[FESZ_CA]
+Annuler
-[GA_7]
-Arme la bombe avec la ~h~touche ~k~~PED_FIREWEAPON~~w~. Elle explose au démarrage.
+[FES_NGA]
+Nouvelle partie
-[GA_8]
-Utilise le détonateur pour armer la bombe.
+[FES_CAN]
+Annuler
-[GA_9]
-Tu as récupéré ~1~ des 10 voitures spéciales.
+[FESZ_QL]
+Toutes les étapes non sauvegardées de cette partie seront perdues. Charger la partie?
-[GA_10]
-Beau morceau. Voilà tes ~1~$.
+[FESZ_QD]
+Effacer cette sauvegarde?
-[GA_11]
-On en a déjà des comme ça. Ca nous sert à rien!
+[FESZ_QO]
+Ecraser cette sauvegarde?
-[GA_12]
-Bombe armée.
+[FESZ_QR]
+Veux-tu vraiment commencer une autre partie? Toutes les données depuis la dernière partie sauvegardée seront perdues. Continuer?
-[GA_13]
-Comme un pro! Finis la liste et t'auras un bonus!
+[T4X4_1]
+'Terrain de jeu PCJ'
-[GA_14]
-Toutes les voitures! Parfait! Tiens, voilà un petit quelque chose!
+[BMX_1]
+'Sélection par la boue'
-[GA_15]
-J'espère que t'aimes la nouvelle couleur!
+[BMX_2]
+'Piste d'essai'
-[GA_16]
-La peinture est en option!
+[BMXFAIL]
+~r~Tu n'as pas réussi à établir un nouveau record!
-[GA_19]
-Ce modèle, ça nous intéresse pas!
+[T4X4_3]
+'DANS LA POCHE!'
-[GA_20]
-On en a trop des comme ça! Désolé, mec.
+[MM_1]
+'Cônes en folie'
-[CR_1]
-La grue ne peut pas soulever ce véhicule.
+[T4X4_F]
+~r~Tu t'es barré! Trop dur pour toi?
-[PU_MONY]
-T'as pas assez d'argent.
+[LANDSTK]
+Landstalker
-[CO_ALL]
-Tu les as toutes eues. Tiens, voilà pour toi...
+[IDAHO]
+Idaho
-[PAUSED]
-PAUSE
+[STINGER]
+Stinger
-[HEALTH1]
-Sors de là! T'es en pleine forme!
+[LINERUN]
+Linerunner
-[HEALTH2]
-Coût des soins
+[PEREN]
+Perennial
-[HEALTH3]
-Je vais vous remettre sur pied!
+[SENTINL]
+Sentinelle
-[HEALTH4]
-Ca fera 250$.
+[RIO]
+Rio
-[FEB_STA]
-Statistiques
+[PATRIOT]
+Patriote
-[FEB_BRI]
-Briefings
+[FIRETRK]
+Camion de pompier
-[FEB_CON]
-Commandes
+[TRASHM]
+Trashmaster
-[FEB_AUD]
-Son
+[STRETCH]
+Stretch
-[FEB_DIS]
-Affichage
+[MANANA]
+Manana
-[FEB_LAN]
-Langue
+[INFERNS]
+Infernus
-[FEP_STA]
-STATISTIQUES
+[VOODOO]
+Voodoo
-[FEP_BRI]
-BRIEFINGS
+[PONY]
+Pony
-[FEP_CON]
-COMMANDES
+[MULE]
+Mule
-[FEP_AUD]
-SON
+[CHEETAH]
+Cheetah
-[FEP_DIS]
-AFFICHAGE
+[AMBULAN]
+Ambulance
-[FEP_LAN]
-LANGUE
+[FBICAR]
+FBI Washington
-[FEF_ST1]
-C'est qui, le méchant ?
+[MOONBM]
+Moonbeam
-[FEF_ST2]
-T'as foutu un sacré merdier!
+[ESPERAN]
+Esperanto
-[FEF_BR1]
-T'as perdu le fil de l'histoire ?
+[TAXI]
+Taxi
-[FEF_CO1]
-Tu veux prendre les commandes, c'est ça ?
+[WASHING]
+Washington
-[FEF_CO2]
-Choisis la configuration qui correspond le mieux à ta façon de jouer.
+[BOBCAT]
+Bobcat
-[FEF_SA1]
-Fais la queue!
+[WHOOPEE]
+Mr Whoopee
-[FEF_SA2]
-Sauvegarde et charge tes parties
+[BFINJC]
+BF Injection
-[FEF_AU1]
-Fais péter la sono!
+[HUNTER]
+Hunter
-[FEF_AU2]
-Sélectionne une station de radio et des effets sonores
+[POLICAR]
+Police
-[FEF_DI1]
-Change de partie!
+[ENFORCR]
+Enforcer
-[FEF_DI2]
-Configure le jeu pour ta télé pourrie!
+[SECURI]
+Securicar
-[FEF_LA1]
-Mais qu'est-ce que tu racontes ?
+[BANSHEE]
+Banshee
-[FEF_LA2]
-Do tu hablar Deutsh ?
+[PREDATR]
+Predator
-[FEB_PMB]
-Briefings de mission précédents:
+[BUS]
+Bus
-[FEC_NA]
-Oups!
+[RHINO]
+Rhino
-[FEC_CWL]
-Montrer les armes à gauche
+[BARRCKS]
+Barracks OL
-[FEC_CWR]
-Montrer les armes à droite
+[CUBAN]
+Cuban Hermes
-[FEC_LOF]
-Regarder devant
+[HELI]
+Hélicoptère
-[FEC_TAR]
-Cible
+[DODO]
+Dodo
-[FEC_MOV]
-Déplacement
+[COACH]
+Coach
-[FEC_CAM]
-Modes caméra
+[CABBIE]
+Cabbie
-[FEC_PAU]
-Pause
+[STALION]
+Stallion
-[FEC_ENV]
-Monter dans un véhicule
+[RUMPO]
+Rumpo
-[FEC_JUM]
-Sauter
+[RCBANDT]
+RC Bandit
-[FEC_ATT]
-Attaquer ou tirer
+[ROMERO]
+Corbillard de Romero
-[FEC_RUN]
-Courir
+[PACKER]
+Packer
-[FEC_FPC]
-Vue subjective
+[ADMIRAL]
+Amiral
-[FEC_LL]
-Regarder à gauche
+[SQUALO]
+Squalo
-[FEC_LB1]
-Regarder
+[SEASPAR]
+Sea Sparrow
-[FEC_LB2]
-derrière
+[PIZZABO]
+Pizza Boy
-[FEC_LB]
-Regarder derrière
+[GANGBUR]
+Gang Burrito
-[FEC_LR]
-Regarder à droite
+[TROPIC]
+Tropic
-[FEC_HOR]
-Klaxon
+[SPEEDER]
+Speeder
-[FEC_VES]
-Commandes du véhicule
+[REEFER]
+Reefer
-[FEC_RSC]
-Chang. les stations de radio
+[FLATBED]
+Flatbed
-[FEC_BRA]
-Frein ou marche arrière
+[YANKEE]
+Yankee
-[FEC_HAB]
-Frein à main
+[CADDY]
+Caddy
-[FEC_CAW]
-Arme du véhicule
+[ZEBRA]
+Taxi Zebra
-[FEC_ACC]
-Accélérateur
+[TOPFUN]
+Top Fun
-[FEC_SMT]
-Déclencheur de mission spéciale
+[SKIMMER]
+Skimmer
-[FEC_CCF]
-Configuration:
+[PCJ600]
+PCJ 600
-[FEC_CF1]
-Config1
+[PHOENIX]
+Phoenix
-[FEC_CF2]
-Config2
+[FAGGIO]
+Faggio
-[FEC_CF3]
-Config3
+[FREEWAY]
+Freeway
-[FEC_CF4]
-Config4
+[RCBARON]
+RC Baron
-[FEC_CDP]
-Affichage de la manette:
+[RCRAIDE]
+RC Raider
-[FEC_ONF]
-A pied
+[GLENDAL]
+Glendale
-[FEC_INC]
-Dans un véhicule
+[OCEANIC]
+Oceanic
-[FEC_VIB]
-Vibrations:
+[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]
+Appuie sur la ~h~~k~~PED_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]
-Tu la gares, tu l'amorces en appuyant sur la ~h~touche ~k~~PED_FIREWEAPON~~w~ et tu te barres!
+[CRED151]
+DAN SCHNEIDER, DAN TOYAMA, DAVID DEAN CHALTFIELD, JR., DAVID HARRISON, DAVID WILEY,
-[GA_7B]
-Pour armer la bombe, appuie sur la ~h~touche ~k~~PED_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]
-Appuie sur la ~h~touche ~k~~PED_FIREWEAPON~~w~ pour ~h~activer la bombe~w~, n'oublie pas de t'éloigner.
+[CRED292]
+DJ : PEPE-TONY CHILRODES
-[KM1_8D]
-Appuie sur la ~h~touche ~k~~PED_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]
-Selectionne un Uzi quand tu montes dans la voiture, regarde à gauche ou à droite et appuie sur la ~h~touche ~k~~PED_FIREWEAPON~~w~ pour tirer.
+[CRED339]
+JOHN MAUCERI, JOSH CLARK, JULIE WEMYSS, KEVIN STRALEY, KIM GURNEY, LANCE
-[DRIVE_B]
-Selectionne un Uzi quand tu montes dans la voiture, regarde à gauche ou à droite et appuie sur la ~h~touche ~k~~PED_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]
-Appuie sur la ~h~touche ~k~~PED_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]
-Appuie sur la ~h~touche ~k~~PED_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]
-Appuie sur la ~h~touche ~k~~PED_FIREWEAPON~~w~ pour tirer avec les canons du bateau.
+[RACEFA]
+~r~Tu n'as pas gagné la course!
-[PBOAT_2]
-Appuie sur la ~h~touche ~k~~PED_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]
-Utilise les buggies télécommandés pour détruire les voitures blindées. Appuie sur la ~h~touche ~k~~PED_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]
-Utilise les buggies télécommandés pour détruire les voitures blindées. Appuie sur la ~h~touche ~k~~PED_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]
+Gare-toi, amorce-la en appuyant sur la ~h~~k~~PED_FIREWEAPON~~w~ et BARRE-TOI vite!
-[N_IQA8]
-EDWIN SMITH
+[GA_7]
+Amorce la bombe en appuyant sur la ~h~~k~~PED_FIREWEAPON~~w~. Elle explosera au démarrage.
-[N_IQA9]
-MARK FLETT
+[GA_6B]
+Gare-toi, amorce-la en appuyant sur la ~h~~k~~PED_FIREWEAPON~~w~ et BARRE-TOI vite!
-[N_IQ10]
-MICHAEL SUTHERLAND
+[GA_7B]
+Amorce la bombe en appuyant sur la ~h~~k~~PED_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]
+Appuie sur la~h~ ~k~~PED_FIREWEAPON~~w~ pour tirer avec les canons du bateau.
-[AS3_C]
-~w~Oulala! C'est quoi ce truc jaune ?
+[SEG3_4]
+~g~Tu peux ramasser des bombes en pilotant ton avion radiocommandé à côté. Appuie sur la ~o~touche |.
-[AS3_C1]
-~w~Salut ma poule.
+[RCR1_3]
+~g~Si tu veux quitter cette mission, appuie sur la ~h~~k~~PED_FIREWEAPON~~g~ pour faire exploser ta voiture radiocommandée.
-[AS3_F]
-~w~Elle se classe tout de suite dans les meilleures, cette nana.
+[HELP32]
+Appuie ensuite sur la ~h~~k~~PED_FIREWEAPON~~w~ pour tirer.
-[AS3_F1]
-~w~Elle s'est arrangée pour dérober ce joli petit bijou à notre invité.
+[HELP33]
+Appuie ensuite sur la ~h~~k~~PED_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]
+Appuie sur la ~h~~k~~VEHICLE_ENTER_EXIT~~w~ pour remplacer l'arme actuelle dans cet emplacement.
-[LOVE2_8]
-~g~Dégage de Newport!
+[PU_CF4]
+Appuie sur la ~h~~k~~VEHICLE_ENTER_EXIT~~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]
-Utilise la ~h~touche ~k~~PED_FIREWEAPON~~w~ pour tirer à l'aide du canon à eau.
+[STFT_13]
+Meilleur tps point de passage hélico du centre
-[SPRAY_1]
-Utilise la ~h~touche ~k~~PED_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]
+Utilise la touche ~h~~k~~VEHICLE_ACCELERATE~~w~ pour accélérer. 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
@@ -7241,7 +7121,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
@@ -7297,84 +7177,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
@@ -7426,41 +7228,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
-[FEM_QTW]
-Quitter
+[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
+
+[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 ?
@@ -7468,743 +7438,7124 @@ 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_GFX]
-CONFIG. EFFETS SPECIAUX
+[FELD_WR]
+Chargement en cours. Un instant...
-[FET_DIS]
-CONFIG. AFFICHAGE
+[FEDL_WR]
+Suppression en cours. Un instant...
-[FET_LAN]
-CHOIX LANGUE
+[PCRESRT]
+Lancement d'une nouvelle partie. Un instant...
-[FET_LG]
-CHARGER PARTIE
+[FET_STI]
+Commandes standard
-[FET_DG]
-SUPPRIMER PARTIE
+[FET_CTI]
+Commandes classiques
-[FET_NG]
-NOUVELLE PARTIE
+[FEH_NA]
+OPTION NON DISPONIBLE
-[FET_SG]
-SAUVEGARDER PARTIE
+[FEH_MPH]
+SOURIS, CURSEURS POUR SE DEPLACER - PAGE HAUT, PAGE BAS, MOLETTE POUR ZOOMER, L - LEGENDE
-[FET_MAP]
-CHOISIR CARTE
+[FEA_MP3]
+LECTEUR MP3
-[FET_GT]
-TYPE DE PARTIE
+[NO_PCCD]
+Insérer le disque de GTA Vice City ou appuyer sur ECHAP pour annuler
-[FET_CTL]
-CONFIG. PERIPHERIQUE
+[FEH_SSA]
+CURSEURS POUR SE DEPLACER - S POUR SAUVEGARDER LE FICHIER
-[FET_OPT]
-OPTIONS
+[FES_CMI]
+DERNIERE MISSION REUSSIE
-[FET_QG]
-QUITTER PARTIE
+[FET_STS]
+STATS SAUVEGARDEES DANS 'STATS.HTML' + 'STATS.TXT'
-[FET_STA]
-STATISTIQUES
+[WIN_VDM]
+Grand Theft Auto VC ne dispose pas de suffisamment de mémoire graphique.
-[FET_BRE]
-BRIEFINGS
+[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_WAR]
-Avertissement
+[FEC_TFU]
+Tourelle + Orienter haut
-[FEC_OKK]
-O.K.
+[FEC_TFD]
+Tourelle + Orienter bas
-[FED_CON]
-Confirmation de suppression de fichier
+[FET_RIG]
+CHOISIR UNE AUTRE COMMANDE POUR CETTE ACTION
-[FES_SSC]
-Sauvegarde de la partie effectuée
+[FEA_NM3]
+AUCUN FICHIER MP3 TROUVE
-[DEL_FNM]
-Suppression du fichier effectuée
+[FEA_MPB]
+VOLUME MP3 A FOND
-[PCLOAD]
-Chargement des données du fichier
+[FEA_MUS]
+VOLUME MUSIQUE
-[PCRESRT]
-Redémarrage de Grand Theft Auto III
+[FEA_SFX]
+VOLUME EFFETS SONORES
-[FEC_DLF]
-Erreur lors de suppression
+[CVT_ERR]
+Espace disque épuisé. Libérez de la mémoire sur votre disque dur pour continuer. Appuyez sur ECHAP pour annuler.
-[FEC_SVU]
-Erreur lors de la sauvegarde
+[FEA_ADP]
+AUTODETECT MATERIEL
-[FEC_LUN]
-Erreur lors du chargement. Fichier corrompu, veuillez le supprimer.
+{=================================== MISSION TABLE AMBULAE ===================================}
-[FEN_PLA]
-Nombre de joueurs :
+[ATUTOR2:AMBULAE]
+~g~Conduis les patients à l'hôpital. DOUCEMENT. Chaque secousse réduit leurs chances de survie.
-[FET_NON]
-AUCUNE PARTIE DISPONIBLE
+[A_FULL:AMBULAE]
+~r~Ambulance pleine!
-[FET_SFG]
-RECHERCHE DE PARTIES...
+[A_FAIL2:AMBULAE]
+~r~Ton manque de rapidité a été fatal pour le patient!
-[FET_SRT]
-TRI DES PARTIES...
+[A_FAIL3:AMBULAE]
+~r~Le patient est mort!!
-[FEF_LAN]
-RESEAU
+[A_PASS:AMBULAE]
+Sauvé!
-[FEF_INT]
-INTERNET
+[A_COMP2:AMBULAE]
+Tu ne seras plus jamais essoufflé!
-[FET_REF]
-Rafraîchir
+[A_COMP1:AMBULAE]
+Missions Ambulance réussies : $~1~
-[FET_FIL]
-Filtre
+[A_CANC:AMBULAE]
+~r~Mission ambulance annulée!
-[FET_JG]
-Rejoindre
+[A_COMP3:AMBULAE]
+Missions ambulance accomplies! Maintenant, tu peux sprinter indéfiniment!
-[FEC_NTW]
-Talk To Network
+[ALEVEL:AMBULAE]
+Mission ambulance, niveau ~1~
-[FEC_ESR]
-Utilisation restreinte de la touche Echap
+[A_FAIL1:AMBULAE]
+Mission ambulance achevée.
-[FEC_GSL]
-Show head bob:
+[A_SAVES:AMBULAE]
+PERSONNES SAUVEES : ~1~
-[FIL_FLT]
-FILTRER LISTE DES PARTIES
+{=================================== MISSION TABLE ASSIN1 ===================================}
-[FET_SAN]
-NOUVELLE PARTIE
+[ASM1_5:ASSIN1]
+~r~Il a livré toutes ses pizzas!
-[FIL_MAP]
-Carte :
+[ASM1_6:ASSIN1]
+Livraisons restantes :
-[FIL_SRV]
-Serveur :
+[ASM1_7:ASSIN1]
+~g~Carl Pearson, livreur de pizzas. Tue-le avant qu'il ne termine ses livraisons.
-[FIL_TYP]
-Type de partie :
+[ASM1_D:ASSIN1]
+Ton aide dans l'éradication de ces indésirables fut une excellente affaire.
-[FIL_SPC]
-Parties avec espace disponible ?
+{=================================== MISSION TABLE ASSIN2 ===================================}
-[FIL_PNG]
-Ping :
+[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_UKH]
-Hôte inconnu
+[ASM2_3:ASSIN2]
+~g~Ca va sauter, écarte toi!
-[FEN_UKM]
-Carte non trouvée
+[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_UKT]
-Type de partie non trouvé
+[ASM2_5:ASSIN2]
+~r~Elle s'est enfuie!
-[FEN_NCI]
-VOUS N'ETES PAS CONNECTE A INTERNET
+[ASM2_6:ASSIN2]
+~r~Tu étais trop près de l'accident!
-[FET_PAU]
-MENU PAUSE
+[ASM2_7:ASSIN2]
+~g~N'utilise pas d'armes! Il faut que ça ressemble à un accident! Sors-la plutôt de la route!
-[FET_SGA]
-COMMENCER PARTIE
+[ASM2_8:ASSIN2]
+~g~La mort de madame Dawson doit avoir l'air d'un accident. N'utilise pas d'armes.
-[FEC_SGJ]
-Régler joystick
+[ASM2_9:ASSIN2]
+~g~Il te faut une voiture pour ce boulot!
-[FEC_PAD]
-Manette
+[ASM2_10:ASSIN2]
+~g~Quand sa bagnole prendra feu, éloigne-toi le plus possible du lieu de l'accident.
-[FEC_JOY]
-Joystick
+[ASM2_11:ASSIN2]
+A l'aide!
-[FEC_WHL]
-Volant
+[ASM2_12:ASSIN2]
+Que quelqu'un m'aide!
-[FEC_CNT]
-Type de périphérique :
+[ASM2_13:ASSIN2]
+Oh non!
-[FET_APL]
-APPLIQUER
+[ASM2_A:ASSIN2]
+Mes félicitations pour ce travail bien fait, Mr. Teal. Mon client était ravi.
-[FES_CSA]
-Sélectionnez une apparence dans la liste suivante :
+[ASM2_2:ASSIN2]
+Santé :
-[FES_SKN]
-NOM DE L'APPARENCE
+{=================================== MISSION TABLE ASSIN3 ===================================}
-[FES_DAT]
-DATE
+[ASM3_11:ASSIN3]
+TEMPS :
-[FES_NON]
-AUCUNE APPARENCE DISPONIBLE
+[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.
-[FEA_FM9]
-LECTEUR MP3
+[ASM3_D:ASSIN3]
+Chaque membre du gang dispose d'une couverture à Vice City. Certains ont des petits boulots, d'autres jouent les touristes.
-[FESZ_QZ]
-Etes-vous sûr de vouloir sauvegarder cette partie ?
+[ASM3_E:ASSIN3]
+Chaque cible et leur position probable sont indiqués sous le téléphone.
-[FES_CGA]
-Emplacements disponibles :
+[ASM3_14:ASSIN3]
+~g~Dick Tanner est à côté de DBP Security sur Ocean Drive.
-[FES_SCG]
-Sauvegarder la partie actuelle ?
+[ASM3_15:ASSIN3]
+~g~Marcus Hammond et Franco Carter sont près de la bijouterie de Vice Point.
-[FES_LCG]
-Charger la partie et continuer à jouer ?
+[ASM3_16:ASSIN3]
+~g~Nick Kong est à côté de Washington Beach.
-[FEC_FIR]
-Tirer
+[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_NWE]
-Arme suivante
+[ASM3_19:ASSIN3]
+~g~Il t'a repéré! Bute-le!
-[FEC_PWE]
-Arme précédente
+[ASM3_20:ASSIN3]
+~g~Ils t'ont repéré! Tue-les vite tous les deux!
-[FEC_FOR]
-Avant
+[ASM3_21:ASSIN3]
+~r~Tu n'as pas tué tous les membres du gang à temps!
-[FEC_BAC]
-Arrière
+[ASM3_22:ASSIN3]
+~g~Ne t'approche pas trop des cibles ou elles risquent de te repérer et d'essayer de filer.
-[FEC_LEF]
-Gauche
+[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_RIG]
-Droite
+[ASM3_13:ASSIN3]
+~g~Mike Griffin travaille sur un panneau publicitaire à Washington.
-[FEC_ZIN]
-Zoom avant
+[ASM3_17:ASSIN3]
+~g~Charlie Dilson est à moto sur Washington.
-[FEC_ZOT]
-Zoom arrière
+{=================================== MISSION TABLE ASSIN4 ===================================}
-[FEC_EEX]
-Entrer+sortir
+[ASM4_12:ASSIN4]
+Distance :
-[FEC_RAD]
-Radio
+[ASM4_15:ASSIN4]
+~g~Prends le fusil à lunette sur ta droite.
-[FEC_SUB]
-Sous-mission
+[ASM4_16:ASSIN4]
+~g~Observe la femme au balcon. Elle va descendre l'escalator et demander l'heure à quelqu'un.
-[FEC_CMR]
-Changer caméra
+[ASM4_17:ASSIN4]
+~g~Lorsque la conversation est terminée, liquide son interlocuteur sans faire de mal à la femme.
-[FEC_JMP]
-Sauter
+[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_SPN]
-Sprint
+[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_HND]
-Frein à main
+[ASM4_20:ASSIN4]
+~g~Ne la laisse pas devenir pleine ou tu seras repéré.
-[FEC_TUL]
-Tourelle gauche
+[ASM4_21:ASSIN4]
+~g~Récupère la serviette!
-[FEC_TUR]
-Tourelle droite
+[ASM4_22:ASSIN4]
+~g~Ramène la serviette à Ammu-Nation dans le centre.
-[FEC_LOL]
-Regarder à gauche
+[ASM4_23:ASSIN4]
+~g~Il t'a repéré et s'enfuit. Rattrape-le et récupère la serviette!
-[FEC_LOR]
-Regarder à droite
+[ASM4_25:ASSIN4]
+~r~T'as buté la femme, imbécile!
-[FEC_NTR]
-Cible suivante
+[ASM4_26:ASSIN4]
+~r~La cible a embarqué pour son vol!
-[FEC_PTT]
-Cible précédente
+[ASM4_27:ASSIN4]
+~r~La cible t'a repéré! Tu devais garder tes distances!
-[FEC_LBA]
-Regarder en arrière
+[ASM4_28:ASSIN4]
+~r~La cible t'a repéré! Elle t'a entendu tirer!
-[FEC_CEN]
-Centrer caméra
+[ASM4_29:ASSIN4]
+~r~Ne le tue qu'après qu'il ait parlé à la femme!
-[FEC_UND]
-(NON)
+[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_CFT]
-A PIED
+[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.
-[FET_CCR]
-EN VOITURE
+[ASM4_C:ASSIN4]
+Vous devez tuer son interlocuteur, récupérer la mallette et l'apporter à l'emplacement indiqué sous le téléphone.
-[CVT_MSG]
-Conversion des textures vers un format optimal pour votre carte graphique
+{=================================== MISSION TABLE ASSIN5 ===================================}
-[FET_CAC]
-ACTION
+[ASM5_A:ASSIN5]
+Un deal important se déroule sur le toit de l'usine de crème glacée Cherry Popper.
-[FEC_IBT]
--
+[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_SPC]
-ESP
+[ASM5_C:ASSIN5]
+Il y a une porte sur votre gauche qui mène à l'arrière de l'usine.
-[FEC_MXO]
-MXB1
+[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_MXT]
-MXB2
+[ASM5_2:ASSIN5]
+~g~Récupère la marchandise et amène-la à la piste pour hélicos de l'aéroport.
-[FEC_UNB]
-NON UTILISE
+[ASM5_3:ASSIN5]
+~g~Emmène la marchandise à la piste pour hélicos de l'aéroport!
-[FET_CME]
-TYPE DE COMMANDES
+{=================================== MISSION TABLE BANKJ1 ===================================}
-[FET_RDK]
-REDEFINIR COMMANDES
+[WANTED1:BANKJ1]
+~g~Largue les flics et perds ton indice de recherche!
-[FET_AMS]
-PARAMETRES SOURIS
+[BJM1_A:BANKJ1]
+Tommy! Hé, regarde-ça, c'est génial! J'ai fait installer un minibar!
-[FET_STI]
-CONFIG. COMMANDES STANDARD
+[BJM1_B:BANKJ1]
+Y'a déjà un vrai bar en bas, Ken.
-[FET_CTI]
-CONFIG. COMMANDES NORMALES
+[BJM1_C:BANKJ1]
+Ouais, je sais, et alors? Bon, j'ai le tableau noir que tu m'as demandé.
-[FET_MTI]
-CONFIG. SOURIS
+[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.
-[FET_DAM]
-MODELAGE ACCOUST. DYNAMIQUE
+[BJM1_E:BANKJ1]
+Bon, il me faut un mec sûr.
-[FEC_TFL]
-Tourelle Gauche
+[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_TFR]
-Tourelle Droite
+[BJM1_G:BANKJ1]
+Aaah, non, merde, ce con est au trou.
-[FEC_TFU]
-Tourelle /Dodo Haut
+[BJM1_H:BANKJ1]
+Comment ça au trou?
-[FEC_TFD]
-Tourelle /Dodo Bas
+[BJM1_I:BANKJ1]
+Dans un poste de police. Il attend son transfert.
-[FEC_MWF]
-MOLETTE HAUT
+[BJM1_J:BANKJ1]
+Je crois qu'il va être remis en liberté sur parole...
-[FEC_MWB]
-MOLETTE BAS
+[BJM1_1:BANKJ1]
+~g~Sors Cam Jones de chez les flics!
-[FEC_ORR]
-ou
+[BJM1_3:BANKJ1]
+~g~Tu trouveras quelque chose d'utile dans la salle des casiers.
-[FEC_NUS]
-NON UTILISE
+[BJM1_21:BANKJ1]
+~g~La carte d'accès aux cellules se trouve à l'étage.
-[FEC_LUD]
-Regarder Haut
+[BNK1_7:BANKJ1]
+Cam Jones?
-[FEC_LDU]
-Regarder Bas
+[BNK1_8:BANKJ1]
+Je viens t'aider à mettre les bouts!
-[FEC_CMP]
-COMBO : REGARDER G+D
+[BNK1_10:BANKJ1]
+Ouais, c'est moi...
-[FEC_NTT]
-No Text Yet For This Key
+[BNK1_11:BANKJ1]
+Ca me va!
-[FEC_FNC]
-F~1~
+[BNK1_13:BANKJ1]
+J'ai un boulot à faire et t'es mon perceur de coffre.
-[FEC_IRT]
-INSER
+[BNK1_14:BANKJ1]
+Marre de perdre mon temps dans une cellule.
-[FEC_DLL]
-SUPPR
+[BJM1_22:BANKJ1]
+~g~Ramène Cam chez lui!
-[FEC_HME]
-ORIG
+[BJM1_23:BANKJ1]
+~g~Tu dois d'abord trouver la carte d'accès!
-[FEC_END]
-FIN
+[BNK1_12:BANKJ1]
+Sème les flics et ramène-moi chez moi!
-[FEC_PGU]
-PAGE HAUT
+[BJM1_20:BANKJ1]
+Jette ton flingue ou tu vas en subir les conséquences!
-[FEC_PGD]
-PAGE BAS
+[BJM1_5:BANKJ1]
+Accès réservé au personnel autorisé!
-[FEC_UPA]
-HAUT
+[BJM1_2:BANKJ1]
+~r~T'étais supposé faire sortir Cam, pas le faire tuer!
-[FEC_DWA]
-BAS
+[BJM1_4:BANKJ1]
+Il est armé! Descendez-le!
-[FEC_LFA]
-GAUCHE
+{=================================== MISSION TABLE BANKJ2 ===================================}
-[FEC_RFA]
-DROITE
+[BJM2_A:BANKJ2]
+Il nous faut un braqueur. T'en connais un?
-[FEC_NUM]
-PAV.NUM
+[BJM2_B:BANKJ2]
+Hé, Tommy, Tommy, ce truc ça permet d'rester dans l'coup, mec!
-[FEC_NMN]
-PAV.NUM~1~
+[BJM2_C:BANKJ2]
+WoooOOOooo!
-[FEC_FWS]
-PAV.NUM /
+[BJM2_D:BANKJ2]
+J'pourrais être ton braqueur! Haut les mains! Haut les mains!
-[FEC_PLS]
-PAV.NUM +
+[BJM2_E:BANKJ2]
+T'es pas un braqueur, t'es un idiot.
-[FEC_MIN]
-PAV.NUM -
+[BJM2_F:BANKJ2]
+Va boire un verre et ferme-la.
-[FEC_DOT]
-PAV.NUM .
+[BJM2_G:BANKJ2]
+Hé, tire-toi de mon chemin! Ye ye ye ow ow!
-[FEC_NLK]
-VERR NUM
+[BJM2_H:BANKJ2]
+Cam, qu'est-ce que t'en penses?
-[FEC_ETR]
-ENTR
+[BJM2_I:BANKJ2]
+Ben, le meilleur tireur de cette ville, c'est un mec qui s'appelle Cassidy.
-[FEC_SLK]
-ARRET DEFIL
+[BJM2_J:BANKJ2]
+Ah ouais?
-[FEC_PSB]
-PAUSE
+[BJM2_K:BANKJ2]
+Ouais. Un militaire ou en tout cas c'est ce qu'il croit.
-[FEC_BSP]
-RET. ARR.
+[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_TAB]
-TAB
+[BJM2_M:BANKJ2]
+Il devrait être au champ de tir.
-[FEC_CLK]
-VERR MAJ
+[BJM2_2A:BANKJ2]
+C'est toi, Phil Cassidy?
-[FEC_RTN]
-RETOUR
+[BJM2_2B:BANKJ2]
+Pourquoi?
-[FEC_LSF]
-MAJ. G
+[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_RSF]
-MAJ. D
+[BJM2_2D:BANKJ2]
+Mon pote, je peux dégomme une mouche sur ta tête à 25 mètres!
-[FEC_LCT]
-CTRL G
+[BJM2_2E:BANKJ2]
+Vraiment?
-[FEC_RCT]
-CTRL D
+[BJM2_2F:BANKJ2]
+Ouais. J'ai appris ça à l'armée.
-[FEC_LAL]
-ALT G
+[BJM2_2G:BANKJ2]
+Ils s'amusent souvent à descendre des mouches à l'armée? Heureusement que je paye pas d'impôts!
-[FEC_RAL]
-ALT D
+[BJM2_2H:BANKJ2]
+Tu t'crois marrant peut-être, minus?
-[FEC_LWD]
-WIN G
+[BJM2_2I:BANKJ2]
+Ha ha ha ha ha!
-[FEC_RWD]
-WIN D
+[BJM2_2J:BANKJ2]
+Tirons quelques coups.
-[FEC_WRC]
-CLIC WIN
+[BJM2_1:BANKJ2]
+~g~Va à Ammu-Nation dans le centre et parle à Phil Cassidy.
-[WIN_TTL]
-Grand Theft Auto III
+[BJM2_4:BANKJ2]
+SCORE MANCHE 1 : ~1~
-[WIN_95]
-Grand Theft Auto III n'est pas compatible WINDOWS 95
+[BJM2_6:BANKJ2]
+SCORE MANCHE 2 : ~1~
-[WIN_DX]
-Grand Theft Auto III requiert la version 8.1 de DirectX minimum.
+[BJM2_7:BANKJ2]
+SCORE TOTAL : ~1~
-[WIN_VDM]
-Grand Theft Auto III requiert au moins 12 Mo de mémoire vidéo libre.
+[BJM2_9:BANKJ2]
+~g~Va au point de départ de la deuxième manche.
-[DIAB3_G]
-Arriba !
+[BJM2_11:BANKJ2]
+~r~Phil est mort!
-[FEM_RES]
-REPRENDRE PARTIE
+[BJM2_12:BANKJ2]
+~r~Un des tireurs est mort!
-[FES_SNG]
-NOUVELLE PARTIE
+[BJM2_14:BANKJ2]
+~g~Continue jusqu'au prochain secteur!
-[FEM_SP]
-MODE SOLO
+[BJM2_17:BANKJ2]
+~g~Va parler à Phil.
-[FEM_MP]
-MODE MULTIJOUEUR
+[BJM2_24:BANKJ2]
+~g~La cible la plus proche rapporte un point.
-[FEM_QT]
-QUITTER
+[BJM2_25:BANKJ2]
+~g~La cible intermédiaire rapporte deux points.
-[FES_SG]
-NOUVELLE PARTIE
+[BJM2_27:BANKJ2]
+~g~Toutes les cibles de cette manche rapportent un point.
-[FES_LG]
-CHARGER PARTIE
+[BNK2_4:BANKJ2]
+Waou!
-[FEM_HST]
-HEBERGER PARTIE
+[BNK2_5:BANKJ2]
+Il raterait une vache dans un couloir!
-[FEM_OPT]
-OPTIONS
+[BNK2_7:BANKJ2]
+Bon, tu veux bien me rendre un service et m'assister sur un boulot?
-[FEM_DBG]
-DEBUG
+[BNK2_8:BANKJ2]
+Mon gars, vu comment tu tires, si tu me demandes en mariage, j'accepte.
-[FET_PSU]
-PARAMETRES JOUEUR
+[BNK2_9A:BANKJ2]
+Mon gars, tu ferais mieux de remballer ton baratin et tes grands projets. T'es trop mauvais tireur.
-[FET_DEF]
-PAR DEFAUT
+[BNK2_9B:BANKJ2]
+T'es trop mauvais tireur.
-[FED_BRI]
-LUMINOSITE
+[BJM2_28:BANKJ2]
+SCORE MANCHE TROIS : ~1~
-[FED_TRA]
-TRAINEES
+[BJM2_26:BANKJ2]
+~g~La cible éloignée rapporte trois points.
-[FEM_LOD]
-DISTANCE MODELES
+[BNK2_1:BANKJ2]
+BALLES REELLES
-[FEM_VSC]
-SYNCHRO VIDEO
+[RANGE_1:BANKJ2]
+SCORE POUR LE TIR : ~1~
-[FEM_FRM]
-RESTRICTION VIDEO
+[BJM2_2:BANKJ2]
+~g~Pour quitter la manche, appuie sur la ~h~~k~~PED_JUMPING~.
-[FED_RES]
-RESOLUTION ECRAN
+[BJM2_N:BANKJ2]
+Du calme...
-[FED_WIS]
-PLEIN ECRAN
+{=================================== MISSION TABLE BANKJ3 ===================================}
-[FEDS_TB]
-RETOUR
+[BJM3_A:BANKJ3]
+Les choses commencent à se mettre tranquillement en place, ici.
-[FEA_MUS]
-MUSIQUE
+[BJM3_B:BANKJ3]
+C'est quoi le plan, Tommy? Que pasa, amigo?
-[FEA_SFX]
-EFFETS SPECIAUX
+[BJM3_C:BANKJ3]
+Le plan, c'est que toi, tu restes ici à glander. Bon, on a besoin d'un chauffeur.
-[FEA_RSS]
-STATION RADIO
+[BJM3_D:BANKJ3]
+Tommy, je m'en charge! Je peux conduire.
-[FEL_ENG]
-ANGLAIS
+[BJM3_E:BANKJ3]
+C'est Hilary que tu veux, mec! Pas un stupide vantard d'école de droit.
-[FEL_FRE]
-FRANCAIS
+[BJM3_F:BANKJ3]
+Hilary, c'est le meilleur. T'as jamais vu quelqu'un conduire aussi vite. Je vais l'appeler.
-[FEL_GER]
-ALLEMAND
+[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_ITA]
-ITALIEN
+[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.
-[FEL_SPA]
-ESPAGNOL
+[BJM3_I:BANKJ3]
+Pour un peu d'adrénaline. Ok, compris.
-[FEA_3DH]
-CONFIG. CARTE-SON
+[BJM3_J:BANKJ3]
+Qu'est-ce qu'il a dit?
-[FEA_SPK]
-CONFIG. 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_2SP]
-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_4SP]
-PLUS DE 2 HAUT-PARLEURS
+[BJM3_M:BANKJ3]
+Quoi qu'il en soit, il veut t'affronter d'abord et il a dit qu'il te retrouvait dehors...
-[FEA_EAR]
-CASQUE
+[BJM3_2A:BANKJ3]
+C'est toi Tommy? Evidemment que c'est toi Tommy, enfin, je veux dire,
-[FEA_NAH]
-PAS DE CARTE-SON
+[BJM3_2B:BANKJ3]
+pourquoi est-ce que quelqu'un d'autre parlerait avec moi?
-[FET_SNG]
-NOUVELLE PARTIE
+[BJM3_2C:BANKJ3]
+Bon. Ecoute-moi.
-[FEN_STA]
-COMMENCER PARTIE
+[BJM3_2D:BANKJ3]
+Je conduis pour toi que SI, et seulement SI, tu peux conduire convenablement.
-[GMLOAD]
-CHARGER PARTIE
+[BJM3_2E:BANKJ3]
+Abandonne et je ne te pardonnerai jamais.
-[GMSAVE]
-SAUVEGARDER PARTIE
+[BJM3_2:BANKJ3]
+~r~Hilary est mort!
-[FES_DGA]
-EFFACER PARTIE
+[BJM3_4:BANKJ3]
+~g~T'as besoin d'une voiture!
-[FEM_NON]
-AUCUN
+[BNK3_1:BANKJ3]
+Ok, je piloterai pour toi, mais s'il te plaît, traite-moi mal.
-[FEC_IVV]
-INVERSER SOURIS VERTIC.
+[BNK3_3A:BANKJ3]
+Course de rue illégale dans Vice Point!
-[FEC_MSH]
-SENSIBILITE SOURIS
+[BNK3_3B:BANKJ3]
+Appel à tous les officiers.
-[FET_CCN]
-COMMANDES : NORMALES
+[BNK3_3C:BANKJ3]
+Les courses de rue sont formellement interdites!
-[FET_SCN]
-COMMANDES : STANDARD
+{=================================== MISSION TABLE BANKJ4 ===================================}
-[FES_SET]
-UTILISER MODELE
+[BNK4_A:BANKJ4]
+~w~Comme vous pouvez voir, les mecs, ça va être le fric le plus facile qu'on se soit jamais fait!
-[GHOST]
-Fantôme
+[BNK4_B:BANKJ4]
+~w~Tommy, sérieusement, va falloir que tu considères la question judiciaire.
-[WIN_RSZ]
-Impossible de choisir la nouvelle résolution.
+[BNK4_C:BANKJ4]
+~w~Merde! Qu'est-ce que tu fumes, mon pote? J'appelle pas ça un plan!
-[FET_APP]
-BGS, RETOUR POUR APPLIQUER LE NOUV. PARAMETRE
+[BNK4_D:BANKJ4]
+~w~Bon, de toute manière, on a pas besoin de plan!
-[FET_HRD]
-PARAMETRES PAR DEFAUT RETABLIS
+[BNK4_E:BANKJ4]
+~w~Prenez le communisme, ça c'était un plan! Et regarde où en est la Russie, maintenant!
-[FET_MST]
-DIRECTION CONTROLEE PAR LA SOURIS
+[BNK4_F:BANKJ4]
+~w~Du calme, Ok? Avec une équipe comme ça, il n'y aura pas le moindre problème!
-[FEC_STR]
-ETOILE PAV.NUM.
+[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_MIG]
-GAUCHE, DROITE, MOLETTE SOURIS POUR REGLER
+[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_CIG]
-RETOUR ARRIERE POUR EFFACER - BGS, RETOUR POUR CHANGER
+[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_RIG]
-SELECTIONNEZ NOUV. TOUCHE POUR CETTE ACTION OU ECHAP POUR ANNULER
+[BNK4_J:BANKJ4]
+~w~Je comprends pas ce que je suis supposé faire ici.
-[FET_EIG]
-IMPOSSIBLE DE PARAMETRER UNE TOUCHE POUR CETTE ACTION
+[BNK4_K:BANKJ4]
+~w~Ecoute, c'est dans la poche. T'as jamais vu de film?
-[NO_PCCD]
-Insérez le disque 2 de Grand Theft Auto III dans le lecteur ou appuyez sur ECHAP pour annuler.
+[BNK4_L:BANKJ4]
+~w~On entre dans la banque, on sort nos flingues et on ressort plein aux as!
-[CVT_ERR]
-Espace disque épuisé. Libérez de la mémoire sur votre disque dur pour continuer. Appuyez sur ECHAP pour annuler.
+[P_DEAD:BANKJ4]
+~r~Phil est mort!
-[FED_SUB]
-SOUS-TITRES
+[C_DEAD:BANKJ4]
+~r~Cam est mort!
-[FET_DSN]
-Skin joueur par défaut.bmp
+[H_DEAD:BANKJ4]
+~r~Hilary est mort!
-[JM3]
-'HAUT LES MAINS'
+[P_HIND:BANKJ4]
+~r~T'as perdu Phil!
-[EBAL]
-'A MOI LIBERTY'
+[C_HIND:BANKJ4]
+~r~T'as oublié Cam!
-[LM4]
-'MAQUEREAU EN BOITE'
+[H_HIND:BANKJ4]
+~r~Hilary est resté derrière!
-[REPLAY]
-RALENTI
+[GETCAR:BANKJ4]
+~g~Monte dans la bagnole pour terminer le boulot!
-[FEC_SFT]
-MAJ
+[TRASHED:BANKJ4]
+~r~T'as détruit la bagnole pour s'enfuir!
-[CRED254]
-RESPONSABLE STUDIO
+[BNK4_1:BANKJ4]
+Je vais conduire.
-[CVT_CRT]
-Pour convertir les textures pour votre carte graphique, connectez-vous à un compte Administrateur. Pour quitter, appuyez sur ECHAP.
+[BNK4_2:BANKJ4]
+Super. Un passager. Attends que j'en parle à la réunion!
-[FEM_ON]
-AVEC
+[BNK4_3A:BANKJ4]
+Hé, fais gaffe à la caisse, Tommy!
-[FEM_OFF]
-SANS
+[BNK4_3B:BANKJ4]
+Tommy, Hilary prend trop de place!
-[FEM_YES]
-OUI
+[BNK4_3C:BANKJ4]
+C'est pas vrai!
-[FEM_NO]
-NON
+[BNK4_3D:BANKJ4]
+Toi aussi!
-[FES_WAR]
-Sauvegarde en cours...
+[BNK4_3E:BANKJ4]
+Hé, fermez-la tous les deux ou vous rentrez à pied!
-[FED_DLW]
-Suppression en cours...
+[BNK4_3F:BANKJ4]
+Ouais, Hilary.
-[FED_LDW]
-Chargement en cours...
+[BNK4_3I:BANKJ4]
+Putain, Phil! Arrête d'agiter ce truc devant moi!
-[FEC_SLC]
-Emplacement corrompu
+[BNK4_3J:BANKJ4]
+Ouais, tu vas éborgner quelqu'un!
-[FED_LFL]
-Echec du chargement de la sauvegarde. La partie va être relancée.
+[BNK4_3M:BANKJ4]
+Mon bébé! Elle est foutue!
-[FET_RSO]
-PARAMETRE D'ORIGINE RETABLI
+[BNK4_3O:BANKJ4]
+Tu t'accroches à l'illusion de la permanence!
-[FET_RSC]
-MATERIEL INDISPONIBLE - PARAMETRE D'ORIGINE RETABLI
+[BNK4_3P:BANKJ4]
+Quoi?!
-[CRED270]
-MIKE HONG
+[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]
+Utilise la touche ~h~~k~~PED_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]
+Utilise la touche ~h~~k~~PED_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]
+Pour ~h~tirer droit devant ~w~lorsque tu es en ~h~moto~w~, appuie sur la ~h~~k~~PED_FIREWEAPON~.
+
+[GEN3_41:GENERA3]
+Pour ~h~tirer droit devant ~w~lorsque tu es en ~h~moto~w~, appuie sur la ~h~~k~~PED_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]
+Appuie sur la touche ~h~~k~~PED_FIREWEAPON~~w~ pour tirer droit devant toi sur une moto.
+
+[GEN3_65:GENERA3]
+Appuie sur la touche ~h~~k~~PED_FIREWEAPON~~w~ pour tirer droit devant toi sur une moto.
+
+[GEN3_66:GENERA3]
+Appuie sur la touche ~h~~k~~PED_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]
+Appuie sur la touche ~h~~k~~PED_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...
+
+[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]
+~g~Si tu veux quitter cette mission, appuie sur la ~h~~k~~PED_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]
+~g~Si tu veux quitter cette mission, appuie sur la ~h~~k~~PED_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]
+~g~Pour larguer une bombe, appuie sur la~h~ ~k~~PED_FIREWEAPON~~w~.
+
+[TEX3_29:SERG3]
+Pour larguer une bombe, appuie sur la~h~ ~k~~PED_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]
+Pousse le ~h~~k~~VEHICLE_ACCELERATE~ ~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!
[DUMMY]
THIS LABEL NEEDS TO BE HERE !!!
diff --git a/utils/gxt/german.txt b/utils/gxt/german.txt
index c48d7757..965db366 100644
--- a/utils/gxt/german.txt
+++ b/utils/gxt/german.txt
@@ -1,86 +1,254 @@
-[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.
@@ -94,78 +262,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)
@@ -184,44 +322,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.
@@ -265,6746 +370,6641 @@ 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
-
-[TONI]
-TONI MISSIONEN
-
-[JOEY]
-JOEY MISSIONEN
-
-[FRANK]
-SALVATORE MISSIONEN
-
-[DIABLO]
-DIABLO MISSIONEN
-
-[ASUKA]
-ASUKA MISSIONEN
-
-[B_SITE]
-ASUKA VORSTADT-MISSIONEN
+Betritt den Ammu-Nation, um eine Waffe zu kaufen.
-[KENJI]
-KENJI MISSIONEN
-
-[RAY]
-RAY MISSIONEN
-
-[LOVE]
-LOVE MISSIONEN
-
-[YARDIE]
-YARDIE MISSIONEN
+[R_TIME]
+ZEIT:
-[HOOD]
-HOOD MISSIONEN
+[PROP_1]
+Du hast nicht genug Cash für dieses Objekt.
-[CITYZON]
-Liberty City
+[PROP_2]
+Wãhrend einer Mission kannst du keine Objekte kaufen.
[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]
-Rotlichtbezirk
-
-[TOWERS]
-Hepburn Heights
-
-[HARWOOD]
-Harwood
-
-[ROADBR1]
-Callahan Bridge
-
-[ROADBR2]
-Callahan Bridge
-
-[TUNNELP]
-Porter Tunnel
-
-[BOMB1]
-8-Balls Werkstatt
+Vice City Beach
[COM_ZON]
-Staunton Island
+Vice City Mainland
-[STADIUM]
-Aspatria
+[BEACH1]
+Ocean Beach
-[HOSPI_2]
-Rockford
+[BEACH2]
+Washington Beach
-[UNIVERS]
-Liberty Campus
+[BEACH3]
+Vice Point
-[CONSTRU]
-Fort Staunton
+[GOLFC]
+Leaf Links Golfclub
-[PARK]
-Belleville Park
+[STARI]
+Starfish Island
-[COM_EAS]
-Newport
+[DOCKS]
+Viceport
-[SHOPING]
-Bedford Point
+[HAVANA]
+Little Havana
-[YAKUSA]
-Torrington
+[HAITI]
+Little Haiti
-[SUB_ZON]
-Shoreside Vale
+[PORNI]
+Prawn Island
-[AIRPORT]
-Francis Int. Airport
+[DTOWN]
+Downtown
-[PROJECT]
-Wichita Gardens
+[VICE_C]
+Vice City
-[SUB_IND]
-Pike Creek
+[A_PORT]
+Escobar Inter. Airport
-[SWANKS]
-Cedar Grove
+[JUNKY]
+Schrottplatz
-[BIG_DAM]
-Cochrane Dam
+[PISTOL]
+Pistole
-[SUB_ZO2]
-Shoreside Vale
+[PYTHON]
+.357
-[SUB_ZO3]
-Shoreside Vale
+[UZI]
+Uz-1
-[CAR_1]
-Krankenwagen
+[TEC9]
+Tec 9
-[CAR_2]
-Feuerwehrwagen
+[M4]
+M4
-[CAR_3]
-Polizei
+[INGRAM]
+Mac
-[CAR_4]
-Enforcer
+[MP5]
+MP
-[CAR_5]
-Barracks
+[RUGER]
+Kruger
-[CAR_6]
-Rhino
+[SNIPE]
+Prãzisionsgewehr
-[CAR_7]
-FBI-Wagen
+[GRENADE]
+Granaten
-[CAR_8]
-Securicar
+[SHOTGN1]
+Schrotflinte
-[CAR_9]
-Moonbeam
+[SHOTGN2]
+S.P.A.S. 12
-[CAR_10]
-Kleinbus
+[SHOTGN3]
+Abgesãgte Schrotflinte
-[CAR_11]
-Lkw
+[ARMOUR]
+Kugelsichere Weste
-[CAR_12]
-Linerunner
+[LASER]
+.308 Prãzisionsgewehr
-[CAR_13]
-Trashmaster
+[BASEBAT]
+Baseballschlãger
-[CAR_14]
-Patriot
+[HAMMER]
+Hammer
-[CAR_15]
-Mr Whoopee
+[SCREWD]
+Schraubenzieher
-[CAR_16]
-Mule
+[CLEVER]
+Fleischerbeil
-[CAR_17]
-Yankee
+[MACHETE]
+Machete
-[CAR_18]
-Pony
+[KNIFE]
+Messer
-[CAR_19]
-Bobcat
+[KATANA]
+Katana
-[CAR_20]
-Rumpo
+[CHAINSA]
+Kettensãge
-[CAR_21]
-Blista
+[G_COST]
+$~1~
-[CAR_22]
-Dodo
+[CAR_1]
+Krankenwagen
-[CAR_23]
-Bus
+[MALIBU]
+Malibu Club
-[CAR_24]
-Sentinel
+[MANSION]
+Diaz' Haus
-[CAR_25]
-Cheetah
+[TMANS]
+Vercetti Estate
-[CAR_26]
-Banshee
+[STRIP]
+Pole Position Club
-[CAR_27]
-Stinger
+[MALL1]
+North Point Einkaufszentrum
-[CAR_28]
-Infernus
+[BANKINT]
+El Banco Corrupto Grande
-[CAR_29]
-Esperanto
+[RANGE]
+Schießstand
-[CAR_30]
-Kuruma
+[POL_HQ]
+Vice City Polizeihauptquartier
-[CAR_31]
-Stretch Limo
+[INT_B]
+Ein alter Freund
-[CAR_32]
-Perennial
+[INTB_1]
+~g~Begib dich in die Anwaltskanzlei.
-[CAR_33]
-Landstalker
+[LAW_1]
+Die Party
-[CAR_34]
-Manana
+[LAW_2]
+Dunkle Gassen
-[CAR_35]
-Idaho
+[LAW_3]
+Die Geschworenen
-[CAR_36]
-Stallion
+[LAW_4]
+Aufruhr
-[CAR_37]
-Taxi
+[COL_1]
+Der Verrãter
-[CAR_38]
-Cabbie
+[COL_2]
+Kugelhagel im Einkaufszentrum
-[CAR_39]
-Buggy
+[COL_3]
+Die Schutzengel
-[LUIGIS]
-Luigis Club
+[COL_4]
+Zu Befehl, Sir!
-[GOAWAY]
-~g~Du bist bereits auf einer Mission!
+[COL_5]
+Alle Mann an Deck!
-[LUIGGO]
-~g~Luigi checkt gerade ein paar neue Girls aus. Komm spãter wieder!
+[COK_1]
+Die Jagd
-[JOEYGO]
-~g~Joey ist mit Misty in der Stadt unterwegs. Komm spãter wieder!
+[COK_2]
+Phnom Penh '86
-[TONIGO]
-~g~Toni ist mit seiner Mamma in der Oper. Probier's ein andermal!
+[COK_3]
+Das schnellste Boot
-[KEMUGO]
-~g~Maria und Kemuri sind gerade beschãftigt. Versuch's spãter nochmal!
+[COK_4]
+Angebot & Nachfrage
-[KENJGO]
-~g~Kenji ist bei einem Yakuza-Treffen. Schau ein andermal wieder vorbei.
+[KENT_1]
+Die Befreiungsaktion
-[RAYGO]
-~g~Ray hãngt gerade auf irgend einem anderen Klo rum. Komm spãter wieder!
+[ASS_1]
+Pizza Mortale
-[LOVEGO]
-~g~Donald Love hat anderes zu tun. Vielleicht hat er spãter Zeit!
+[BUD_1]
+Fette Beute
-[KENSGO]
-~g~Kenji hat zu tun! Komm spãter wieder!
+[BUD_2]
+Zoff in der Bar
-[ASUSGO]
-~g~Asuka hat gerade überhaupt keine Zeit!
+[BUD_3]
+Cop-Land
-[HOODGO]
-~g~Die Hoods haben gerade keine Zeit!
+[CAP_1]
+Der Eintreiber
-[WRONGT1]
-~g~Komm zwischen 05:00 und 21:00 wieder. Dann gibt's einen Job.
+[FIN_1]
+Freunde und andere Feinde
-[WRONGT2]
-~g~Komm zwischen 06:00 und 14:00 wieder. Dann gibt's einen Job.
+[BANK_1]
+Kein Entkommen?
-[WRONGT3]
-~g~Komm zwischen 15:00 und 00:00 wieder. Dann gibt's einen Job.
+[BANK_2]
+Der Scharfschütze
-[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.
+[BANK_3]
+Der Fahrer
-[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...
+[BANK_4]
+Der Coup
-[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...
+[CNT_1]
+Der Singvogel
-[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...
+[CNT_2]
+Der Kurier
-[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.
+[PORN_1]
+Alle meine Pferdchen
-[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.
+[PORN_2]
+Der Dildo-Jet
-[GUN_4A]
-Mit gedrückter ~h~~k~~PED_LOCK_TARGET~-Taste~w~ kannst du gehen oder laufen und behãltst dein Ziel im Visier.
+[PORN_3]
+Ein Mann namens Martha
-[GUN_4B]
-Mit gedrückter ~h~~k~~PED_LOCK_TARGET~-Taste~w~ kannst du gehen oder laufen und behãltst dein Ziel im Visier.
+[PORN_4]
+Heiße Lightshow
-[GUN_5]
-An diesen Pappkameraden kannst du zielen und schießen üben. Wenn du fertig bist, widme dich wieder deiner Mission.
+[TAX_1]
+Kaufman-Taxis
-[TAXI1]
-~g~Besorg dir einen Passagier.
+[TAXI_1]
+V.I.P
-[FARE1]
-~g~Fahrziel: ~w~'Meeouch Sex Kitten Club' ~g~im Rotlichtbezirk.
+[TAXI_2]
+Konkurrentenjagd
-[FARE2]
-~g~Fahrtziel: ~w~'Supa Save' ~g~in Portland View.
+[TAXI_3]
+Das Taxi-Inferno
-[FARE3]
-~g~Fahrtziel: ~w~'Alte Schulhalle' ~g~in Chinatown.
+[ICE_1]
+Eiscreme und andere Leckereien
-[FARE4]
-~g~Fahrtziel: ~w~'Greasy Joe's Cafe' ~g~in Callahan Point.
+[TEX_1]
+Schlagende Argumente
-[FARE5]
-~g~Fahrtziel: ~w~'AmmuNation' ~g~im Rotlichtbezirk.
+[TEX_2]
+Das Begrãbnis
-[FARE6]
-~g~Fahrtziel: ~w~'Easy Credit Autos' ~g~in Saint Mark's.
+[TEX_3]
+Schutt und Asche
-[FARE7]
-~g~Fahrtziel: ~w~'Woody's Topless Bar' ~g~im Rotlichtbezirk.
+[PHIL_1]
+Der Waffenschieber
-[FARE8]
-~g~Fahrtziel: ~w~'Marcos Bistro' ~g~in Saint Mark's.
+[PHIL_2]
+TNT-Whiskey
-[FARE9]
-~g~Fahrtziel: ~w~'Import-Export Garage' ~g~in Portland Harbour.
+[BIKE_1]
+Wheels of Steel
-[FARE10]
-~g~Fahrtziel: ~w~'Punk Noodles' ~g~in Chinatown.
+[BIKE_2]
+Chaos-City
-[FARE12]
-~g~Fahrtziel: ~w~'Football Stadion' ~g~in Aspatria.
+[BIKE_3]
+Big Bakers Bike
-[FARE13]
-~g~Fahrtziel: ~w~'Die Kirche' ~g~in Bedford Point.
+[ROCK_1]
+Love Juice
-[FARE14]
-~g~Fahrtziel: ~w~'Das Casino' ~g~in Torrington.
+[ROCK_2]
+Der Psychokiller
-[FARE15]
-~g~Fahrtziel: ~w~'Liberty University' ~g~in Liberty Campus.
+[ROCK_3]
+Die PR-Tour
-[FARE16]
-~g~Fahrtziel: ~w~'Einkaufszentrum' ~g~in der Belleville Park Area.
+[ROCK_4]
+Love Fist!
-[FARE17]
-~g~Fahrtziel: ~w~'Museum' ~g~in Newport.
+[HAT_1]
+Mysteriöses Pulver
-[FARE18]
-~g~Fahrtziel: ~w~'AmCo Gebãude' ~g~in Torrington.
+[HAT_2]
+Fliegende Bomben
-[FARE19]
-~g~Fahrtziel: ~w~'Bolt Burgers' ~g~in Bedford Point.
+[HAT_3]
+Schmutzige Methoden
-[FARE20]
-~g~Fahrtziel: ~w~'Der Park' ~g~in Belleville.
+[CUB_1]
+Stunt-Boot-Action
-[FARE21]
-~g~Fahrtziel: ~w~'Francis Int. Airport'.
+[CUB_2]
+Kanonenfutter
-[FARE22]
-~g~Fahrtziel: ~w~'Cochrane Dam'.
+[CUB_3]
+Die Seeschlacht
-[FARE24]
-~g~Fahrtziel: ~w~'Die Klinik' ~g~in Pike Creek.
+[CUB_4]
+Trojanisches Voodoo
-[FARE25]
-~g~Fahrtziel: ~w~'Der Park' ~g~in Shoreside Vale.
+[JOB_1]
+Der Pizza-Lieferant
-[FARE26]
-~g~Fahrtziel: ~w~'North West Towers' ~g~in Wichita Gardens.
+[JOB_2]
+Ein bedauerlicher Unfall
-[NEW_TAX]
-GRÖSSER! SCHNELLER! HÃRTER! Neu! Borgnine Taxis jetzt in Harwood! Rufen Sie 555-BORGNINE! Heute noch!
+[JOB_3]
+Die rasende Schrottfabrik
-[TSCORE2]
-$~1~
+[JOB_4]
+Trouble am Check-In
-[IN_ROW]
-~1~ SERIEN-Bonus! $~1~
+[JOB_5]
+Gefeuert!
-[TTUTOR]
-Drücke die ~h~~k~~TOGGLE_SUBMISSIONS~-Taste~w~, um Taxi-Missionen an- oder abzuschalten.
+[ANSWER]
+Drücke die ~h~~k~~PED_ANSWER_PHONE~~w~, um den Anruf auf deinem Handy entgegenzunehmen.
-[TTUTOR2]
-Drücke die ~h~~k~~TOGGLE_SUBMISSIONS~-Taste~w~, um Taxi-Missionen an- oder abzuschalten.
+[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.
-[ATUTOR2]
-~g~Fahre die Patienten VORSICHTIG in die Klinik.
+[MOB_01B]
+Ich bin im Malibu und lass es mir gutgehen.
-[A_TIME]
-+~1~ Sekunden
+[MOB_01C]
+Ich denke, ich hab einen gut bei dir, wenn du das hörst, Kumpel. Bis gleich.
-[A_FULL]
-~r~Krankenwagen voll!!
+[MOB_02A]
+Hey! Hallo, Tommy? Tommy!
-[A_RANGE]
-~g~Du bist außer Reichweite des Notarztfunks. Fahr nãher an die Klinik heran!
+[MOB_02B]
+In der Druckerei ist irgendwas im Busch. Fahr mal rüber und kümmere dich darum.
-[FTUTOR]
-Drücke die ~h~~k~~TOGGLE_SUBMISSIONS~-Taste~w~, um Feuerwehr Missionen an- oder abzuschalten.
+[MOB_02C]
+Es scheint ziemlichen Ãrger zu geben. Ich muss Schluss machen.
-[FTUTOR2]
-Drücke die ~h~~k~~TOGGLE_SUBMISSIONS~-Taste~w~, um Feuerwehr Missionen an- oder abzuschalten.
+[MOB_03A]
+Mr. Vercetti? Ich habe hier einen unterschriebenen Wisch,
-[F_PASS1]
-Feuer gelöscht!
+[MOB_03B]
+der besagt, dass Sie alle Schulden von 'BJ's Autos' übernehmen.
-[F_RANGE]
-~g~Du bist außer Reichweite des Feuerwehrfunks. Fahr nãher an eine Feuerwache heran!
+[MOB_03C]
+Nach BJ's plötzlichem Verschwinden hab ich keine andere Wahl,
-[C_BREIF]
-~g~Verdãchtiger wurde zuletzt in der Gegend von ~a~ gesichtet.
+[MOB_03D]
+als Sie für seine Verbindlichkeiten zur Rechenschaft zu ziehen.
-[C_RANGE]
-~g~Du bist außer Reichweite des Polizeifunks. Fahr nãher an ein Polizeirevier heran!
+[MOB_03E]
+Bis Sie die volle Summe beglichen haben,
-[DODO_FT]
-Du bist ~1~ Sekunden geflogen!
+[MOB_03F]
+sollte Ihnen klar sein, dass Vice City ein heißes Pflaster für Sie ist.
-[EBAL_A]
-Ich kenn ein Plãtzchen im Rotlichtbezirk, wo wir untertauchen können.
+[MOB_04A]
+Wie geht's, mein Alter?
-[EBAL_A1]
-Aber meine Hãnde sind im Eimer. Also, fahr du.
+[MOB_04B]
+Ich hab vergessen, dir zu sagen, dass wir für das Konzert noch ein paar Ordner brauchen.
-[EBAL_1]
-Drücke die~h~ ~k~~VEHICLE_ENTER_EXIT~-Taste~w~, um in ein Fahrzeug ~h~ein- oder auszusteigen~w~.
+[MOB_04C]
+Da gibt's so 'ne Biker-Gang, die wãr super für die Publicity.
-[EBAL_1B]
-Drücke die~h~ ~k~~VEHICLE_ENTER_EXIT~-Taste~w~, um in ein Fahrzeug ~h~ein- oder auszusteigen~w~.
+[MOB_04D]
+Wenn du mir das arrangierst, besorg ich dir 'n VIP-Pass für den Abend. Ok?
-[EBAL_2]
-~g~Steig wieder in den Wagen!
+[MOB_05A]
+Gut gemacht, Tommy. Schön, den Ofen wiederzuhaben.
-[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!
+[MOB_05B]
+Sag Mr. Kent Paul, dass er seine Ordner für das Konzert kriegt.
-[EBAL_D]
-Ich kenn einen, der hat Beziehungen zur Mafia. Er heißt Luigi.
+[MOB_05C]
+Du hast mein Wort darauf.
-[EBAL_D1]
-Wir sind alte Bekannte. Vielleicht kann ich dir 'nen Job bei ihm verschaffen. Komm, hier rüber.
+[MOB_05D]
+Halt die Ohren steif.
-[EBAL_E]
-Komm, wir gehen zu ihm. Ich stell dich vor.
+[MOB_06A]
+Tommy, man hört so allerlei über dich, mein Junge.
-[EBAL_I]
-Der Boss kommt gleich zu dir raus...
+[MOB_06B]
+Wenn du willst, kocht Tante Poulet dir ein leckeres Süppchen, dann kannst du mal abschalten, hm?
-[EBAL_J]
-8-Ball hat oben was zu erledigen.
+[MOB_06C]
+Komm doch die Tage mal bei mir vorbei, ok, Tommy?
-[EBAL_K]
-Du könntest mir einen Gefallen tun.
+[MOB_08A]
+Tommy, ich dachte mir, du könntest meinen Rat als Geschãftsmann brauchen.
-[EBAL_L]
-Eines meiner Girls braucht 'nen Fahrer. Schnapp dir ein Auto, hol Misty von der Klinik ab und bring sie her.
+[MOB_08B]
+Wenn du ein Unternehmen am Laufen hast, musst du einmal pro Woche die Einnahmen kassieren gehen.
-[EBAL_N]
-Also lass die Hãnde am Lenkrad!
+[MOB_08C]
+Sonst werden deine Leute übermütig und versuchen, in die eigene Tasche zu wirtschaften. Ok?
-[EBAL_4]
-~r~8-Ball ist tot!
+[MOB_08D]
+Hey, ich weiß selbst, wie man so was macht, Ken, ok?
-[EBAL_5]
-~g~Besorg dir ein Fahrzeug!
+[MOB_08E]
+Ok, ok. Ich weiß ja, dass du Bescheid weißt.
-[EBAL_6]
-~g~Hol Misty ab!
+[MOB_08F]
+Ich meinte ja nur, damit du weißt, dass ich im Zweifelsfall auch Bescheid weiß.
-[LM1]
-'LUIGIS GIRLS'
+[MOB_08G]
+Nur für alle Fãlle, mein Alter!
-[LM2]
-'KEIN SPANK FÜR DIE LADIES'
+[MOB_08H]
+Wenn du meinst, Ken...
-[LM3]
-'MISTY UND DER MAFIOSO'
+[MOB_09A]
+Hey, Leo! Ich hab Arbeit für dich!
-[LM5]
-'DER BULLEN-BALL'
+[MOB_09B]
+Hier ist nicht Leo.
-[LM1_2]
-~g~Bring Misty zu Luigis Club.
+[MOB_09C]
+Hey, wenn Leo erfãhrt, dass du mit seinem Handy telefonierst, bist du fãllig.
-[LM1_3]
-~g~Drück auf die Hupe, damit die Kleine einsteigt.
+[MOB_09E]
+Du hast Leo erledigt? Du musst Mumm haben - willst du für mich arbeiten?
-[LM1_6]
-~g~Steig wieder in den Wagen!
+[MOB_09F]
+Komm ins Café von meinem Vater in Little Havana, dann können wir reden.
-[LM1_7]
-Halte neben Misty an und lass sie einsteigen.
+[MOB_10A]
+Tommy! Du musst mir einen Gefallen tun.
-[LM1_8]
-Du kannst dir bei Luigi den nãchsten Job abholen oder Liberty City erkunden.
+[MOB_10B]
+Steve! Was machen die Dreharbeiten?
-[LM2_A]
-Da ist eine neue Droge in Umlauf, sie heißt SPANK.
+[MOB_10C]
+Gut. Ich- ãh, WIR brauchen noch eine Autoverfolgungsjagd, aber unser Budget ist knapp.
-[LM2_E]
-Irgendein Kerl hat diesen Müll meinen Girls in Portland Harbour verabreicht.
+[MOB_10D]
+Ich hab in der Stadt verteilt ein paar Karren stehen. Du weißt, was zu tun ist.
-[LM2_B]
-Fahr hin und verabreich ihm ein paar mit 'nem Baseballschlãger!
+[MOB_10E]
+Ok, Steve, ich halt die Augen offen. Bis dann.
-[LM2_G]
-Der Typ soll bezahlen für diese Beleidigung!
+[MOB_11A]
+Hallo, Söhnchen. Ich wollte dir kurz 'nen kleinen Tipp geben.
-[LM2_1]
-~g~Nimm sein Auto und spritz es um.
+[MOB_11B]
+Hi, Avery. Worum geht's denn?
-[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~!
+[MOB_11C]
+Man kann in dieser Stadt viel Geld machen, wenn man die richtigen Immobilien hat. Klingelt's?
-[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~!
+[MOB_11D]
+Ich denke schon.
-[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~!
+[MOB_11E]
+Also, halt die Augen offen, dann könnte sich dir die ideale Gelegenheit bieten. Bis bald.
-[LM2_3]
-~g~Stell das Auto in Luigis Garage ab!
+[MOB_11F]
+Ciao, Avery.
-[LM2_4]
-~g~Lackiere das Auto um!
+[MOB12_A]
+Hey, Tommy. Avery hier. Hör mal, ich hab gerade alle Hãnde voll zu tun,
-[LM3_A]
-He, ich muss mit dir reden... Okay, Mick, wir reden spãter.
+[MOB12_B]
+und ein Bevollmãchtigter von mir müsste zu den Gator Keys eskortiert werden.
-[LM3_B]
-Na? Alles klar, mein Junge?
+[MOB12_C]
+Ich will da ein Stück Land kaufen und schick ihn hin, um den Deal abzuschließen.
-[LM3_C]
-Der Sohn des Don, Joey Leone, will seine kleine Misty sehen.
+[MOB12_D]
+Könntest du dafür sorgen, dass er gut dort ankommt?
-[LM3_D]
-Hol sie in Hepburn Heights ab.
+[MOB12_E]
+Mach ich doch glatt, Avery. Wo soll ich ihn abholen?
-[LM3_E]
-Aber Vorsicht, das ist Diablo-Gebiet.
+[MOB12_F]
+Er hat gerade noch an der Baustelle zu tun. Hol ihn doch am besten dort ab.
-[LM3_F]
-Dann bringst du sie rüber zu seiner Werkstatt in Trenton. Aber dalli.
+[MOB12_G]
+Kein Problem. Bis dann, Avery.
-[LM3_H]
-Also, Augen auf die Straße und nicht auf Misty!
+[MOB13_A]
+Vercetti? VERCETTI!! Verdammt, Mann, Sie müssen mir helfen!
-[LM3_1D]
-Drücke die~h~ L3-Taste~w~, um zu ~h~hupen~w~. So weiß Misty, dass du da bist.
+[MOB13_B]
+Mr. Moffat? Wie geht's der Familie?
-[LM3_2]
-~g~Fahr Misty zu Joey.
+[MOB13_C]
+Zur Hölle mit Ihnen, hören Sie!
-[LM3_4]
-~g~Hol Misty ab!
+[MOB13_D]
+Tja, war nett, mit Ihnen zu plaudern...
-[LM3_5]
-Du arbeitest jetzt fest für Luigi? War auch Zeit, dass er 'nen verlãsslichen Fahrer anbringt.
+[MOB13_E]
+WARTEN SIE! Vercetti - Tommy, kann ich Tommy zu Ihnen sagen?
-[LM3_7]
-Ich bin gleich bei dir, Süße.
+[MOB13_F]
+Wir sind beide Geschãftsleute. Sie erkennen doch ein gutes Geschãft sofort, oder?
-[LM3_10]
-~g~Besorg dir ein Auto!
+[MOB13_G]
+Ich hab keine Zeit für Palaver. Kommen Sie zum Punkt.
-[LM4_B]
-Fahr hin und regle das für mich.
+[MOB13_H]
+GELD. Geld ist der Punkt, verdammt!
-[LM4_C]
-Wenn du 'ne Knarre brauchst, geh zum Hintereingang von AmmuNation, gegenüber der U-Bahn.
+[MOB13_I]
+Ich bin den Kerlen nochmal entwischt, aber sie sitzen mir im Nacken. Die machen sich einen Spaß daraus!
-[LM5_A]
-Der Polizeiball findet in der alten Schulhalle nahe der Callahan Bridge statt,
+[MOB13_J]
+Ich bin in einer Telefonzelle, irgendwo in diesem verdammten Loch.
-[LM5_B]
-und bei solchen Bãllen möchten auch Cops ein wenig 'Action' haben.
+[MOB13_K]
+Holen Sie mich hier raus, bevor sie mich schnappen und-... oh Gott...
-[LM5_C]
-Ich hab Girls in der ganzen Stadt stehen.
+[MOB13_L]
+Ich bin leider ausgebucht bis-...
-[LM5_D]
-Bring sie zu dem Ball. Das bringt 'nen Haufen Kohle.
+[MOB13_M]
+Nein! Verarschen Sie mich nicht, haben Sie Erbarmen! Kein Mensch hat das verdient!
-[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.
+[MOB13_N]
+Ich flehe Sie an, Tommy, auf den Knien flehe ich Sie an! Bitte...
-[LM5_2]
-~r~Eins von Luigis Girls ist hinüber!
+[MOB13_O]
+Naja, ich könnte 'nen kurzen Abstecher machen. Vielleicht finde ich Sie...
-[LM5_3]
-~g~Du brauchst ein Auto!
+[MOB13_P]
+Oh Gott, sie kommen! Um Himmels Willen, beeilen Sie sich!
-[LM5_4]
-~g~Hol die Girls, die in St. Mark's arbeiten.
+[MOB_14A]
+Hey, Tommy, hör zu, das wird dir gefallen.
-[LM5_5]
-~g~Bring die Girls zum Polizeiball!
+[MOB_14B]
+Ein Vögelchen hat mir gesteckt, dass das Vice City-Spezialkommando in einem renommierten Finanzinstitut ein Schließfach hat.
-[LM5_8]
-~g~Girls auf dem Ball: ~1~
+[MOB_14C]
+Da sind die Schmiergelder drin, die sie über die Jahre kassiert haben.
-[JM2]
-'ADIEU, 'CHUNKY' LEE CHONG'
+[MOB_14D]
+So 'ne Art Altersversorgung für die ganze Mannschaft.
-[JM3]
-' DER GELDTRANSPORTER'
+[MOB_14E]
+Sollte dir diese Info je helfen, dir was von dem Kuchen anzueignen,
-[JM4]
-'CIPRIANIS CHAUFFEUR'
+[MOB_14F]
+würdest du dich sicher verpflichtet fühlen, mir 'n Stück davon abzugeben?
-[JM5]
-'DER TOTE PASSAGIER'
+[MOB_14G]
+Ich werd dich nicht vergessen. Danke, Kent.
-[JM1_1]
-~g~Bring Forellis Wagen zu 8-Balls Werkstatt nördlich von hier, hinter 'Easy Credit Autos'.
+[MOB_14H]
+'Paul'heiße ich, Scherzkeks. Ich KOMME aus Kent, Nãhe London.
-[JM1_2]
-~g~Park den Wagen wieder vor Marcos Bistro.
+[MOB_14I]
+Mein geographisches Wissen über England ist eben nicht mehr, was es war.
-[JM1_3]
-~g~Aktiviere die Autobombe und dann nichts wie weg!
+[MOB15_A]
+Tommy, Alter. Hier ist Paul aus Kent.
-[JM1_4]
-~g~Du schrottest das Auto! Repariere es!
+[MOB15_B]
+Unten im Malibu, da sind ein paar Keulen, die haben ein Auge auf dich geworfen.
-[JM1_5]
-~g~Die Autobombe ist nicht aktiviert!
+[MOB15_C]
+Ich verstehe nur Bahnhof.
-[JM1_6]
-~g~Stell den Wagen wieder an den richtigen Platz.
+[MOB15_D]
+Hasen. Miezen. Na, Puppen, eben. Coole Babes, keine Professionellen, oder so.
-[JM1_8A]
-~y~Hey, mein alter Freund!
+[MOB15_E]
+Du solltest mal kommen und sie dir ansehen.
-[JM1_8B]
-~y~Die Bombenwerkstatt ist automatisiert. Einfach reinfahren und anhalten, der Rest passiert von selbst.
+[MOB16_A]
+Tommy, hier Paul. Wie geht's, mein Freund?
-[JM1_8C]
-~y~Hier, die erste ist umsonst, jede weitere kostet aber.
+[MOB16_B]
+Was willst du, Paul? Ich brauch keine getürkten Designer-Klamotten.
-[JM2_A]
-Chunky Lee Chong verhökert Spank für irgend so eine neue Gang aus Kolumbien oder Colorado oder so...
+[MOB16_C]
+Sehr witzig. Du weißt, dass ich mit getürkter Ware nichts am Hut habe.
-[JM2_B]
-Ich weiß nicht genau. Aber wen interessieren schon die Details?
+[MOB16_D]
+Wollte nur hören, ob ich nicht 'ne Rolle in einem von deinen Filmen kriegen könnte.
-[JM2_D]
-Diese Ratte hat seine letzte Frühlingsrolle verkauft.
+[MOB16_E]
+In England habe ich viel einschlãgiges Zeug gedreht.
-[JM2_E]
-Ich möchte, dass du ihn erledigst.
+[MOB16_F]
+Ich hab mehr zu bieten als du, mein Alter.
-[JM2_G]
-Besorg dir 'ne 9mm. Du weißt ja, wo du sie findest, oder?
+[MOB16_G]
+Paul, danke für das Angebot. Ich komm auf dich zurück.
-[JM2_H]
-Und sei vorsichtig in Chinatown. Das ist Triaden-Gebiet.
+[MOB16_H]
+Lass mich nicht hãngen. Denk dran, was ich alles für dich getan habe.
-[JM3_A]
-Also, wir überfallen den Transporter mit den Lohngeldern.
+[MOB16_I]
+Das versuch ich ja grade zu vergessen.
-[JM3_B]
-Er startet jeden Tag an der Grenze zu Chinatown.
+[MOB17_A]
+Tommy Vercetti. Wie geht's, großer Meister?
-[JM3_C]
-Kugeln können der Karre nichts anhaben. Also besorg dir einen Wagen und ramm ihn von der Straße.
+[MOB17_B]
+Man hört so einiges über dich. Bist jetzt 'ne große Nummer in der Stadt, hã?
-[JM3_D]
-Fahr ihm voll rein, dann dürften die Wachmãnner schnell abhauen.
+[MOB17_C]
+Paul, du bist betrunken.
-[JM3_E]
-Fahr den Transporter dann zum Lagerhaus bei den Docks, von da an übernehmen meine Leute.
+[MOB17_D]
+Nein, du Trottel, ich bin nicht betrunken.
-[JM3_F]
-Der Transporter ist nicht ewig unterwegs, also beeil dich.
+[MOB17_E]
+Hab mir nur ein paar Ladungen Stoff gegeben, war seit ein paar Tagen nicht im Bett.
-[JM3_1]
-~g~Fahr den Transporter zu der Garage.
+[MOB17_F]
+Und du brauchst mich nicht dumm anzureden.
-[JM3_2]
-~g~Ramm den Wagen, bis der Schadenswert unter 70 Prozent liegt.
+[MOB17_G]
+Ich bin nicht irgendwer. Wer hat dir denn in dieser Stadt den Weg geebnet? Ich!
-[JM4_B]
-Oh! Da ist der Typ, von dem ich dir erzãhlt habe!
+[MOB17_H]
+Tatsãchlich?
-[JM4_C]
-Okay, hör zu. Der Typ ist kein Italiener und kein Mechaniker, aber er kann alles 'richten'.
+[MOB17_I]
+Tatsãchlich!
-[JM4_D]
-Das ist Paps' Capo, Toni Cipriani.
+[MOB17_J]
+Paul, reg dich ab. Ich hatte viel zu tun. Sei kein Idiot.
-[JM4_E]
-Ja, ich bin Toni Cipriani.
+[MOB17_K]
+Ich bin kein Idiot. Das haben sie schon im Jugendknast gesagt.
-[JM4_F]
-Bring ihn zu Mammas Restaurant in St. Mark's.
+[MOB17_L]
+Wenn du Ãrger haben willst, Freundchen, den kannst du haben!
-[JM4_G]
-Hör zu, ich plane eine Sache, da brauche ich einen guten Fahrer. Also komm spãter wieder, okay?
+[MOB17_M]
+Tommy, bitte! Du warst meine große Hoffnung. Bitte, mach dich nicht lustig über mich!
-[JM4_2]
-Warte hier. Lass den Motor laufen. Das ist kein Freundschaftsbesuch.
+[MOB17_N]
+Paul, schlaf mal 'ne Runde. Im Ernst.
-[JM4_3]
-Ein Hinterhalt der Triaden! Bring uns hier raus!
+[MOB18_A]
+Tommy, hier Paul. Wie geht's, Alter? Hey, ich dachte mir, das musst du hören...
-[JM4_4]
-Die Triaden denken wohl, sie können mich fertigmachen. Die! MICH!
+[MOB18_B]
+Echt der Hammer. Du glaubst nicht, was mir für 'ne Puppe über den Weg gelaufen ist.
-[JM4_6]
-Hey, Vorsicht! Ich sagte, keine künstlerischen Einlagen!
+[MOB18_C]
+'ne Bordsteinschwalbe, oder sowas. Unten in Little Havana.
-[JM4_7]
-~g~Fahr Toni zu Mammas Restaurant.
+[MOB18_D]
+Sagt, sie heißt Mercedes oder so ãhnlich. Wahnsinn, Alter. Die Puppe musst du dir geben.
-[JM4_8]
-~r~Toni ist tot!
+[MOB18_E]
+Da würde 'nen Toter Hormonkoller kriegen. Sie sagt, ich wãr der beste, den sie je hatte.
-[JM5_A]
-Großartig! Einfach großartig!
+[MOB18_F]
+Halt die Augen nach ihr offen. Bis dann.
-[JM5_B]
-Na also. Genau der, mit dem ich jetzt reden muss!
+[MOB19_A]
+Tommy, hier KP - Kent Paul. Ich hab lãuten hören, dass jemand dich leimen will.
-[JM5_D]
-Einer der Forellis meinte, er weiß zu viel, also hat er gekriegt, was er verdiente.
+[MOB19_B]
+Also, sei wachsam, mein Freund. Und kein Sterbenswörtchen, dass du das von mir weißt.
-[JM5_E]
-Schaff die Leiche zu der Schrottpresse in Harwood, okay?
+[MOB_20A]
+Hallo, Tommy. Hier Paul. Ich höre, dass du ein paar Leuten auf den Schlips getreten bist.
-[JM5_1]
-~g~Bring ihn zu der Schrottpresse!
+[MOB_20B]
+Irgendjemand sieht es anscheinend nicht gern, dass du auf einmal den großen Zampano spielst.
-[JM5_2]
-~g~Die Forelli Brüder!
+[MOB_20C]
+Also, sag nicht, ich hãtte dich nicht gewarnt. Es rãcht sich, wenn man's übertreibt.
-[JM6_A]
-Nicht schlecht, das Ding, was?
+[MOB_20D]
+Jedenfalls ist angeblich ein Kopfgeld auf dich ausgesetzt und es ist schon jemand hinter dir her.
-[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.
+[MOB_20E]
+Also pass auf dich auf. Und vergiss mich nicht ganz.
-[JM6_C]
-Die überfallen eine Bank und brauchen einen Fahrer.
+[MOB71_A]
+Tommy, Thomas, hier Cortez. Wie geht's?
-[JM6_D]
-Ich hab ihnen gesagt, du bist der richtige. Also, vermassle es nicht.
+[MOB71_B]
+Es bleibt spannend. Und selbst?
-[JM6_E]
-Bring sie vor 5 Uhr zu der Bank, keine Minute spãter.
+[MOB71_C]
+Ein ewiger Kampf, Tommy. Entschuldigen Sie die schlechte Verbindung, wir hatten wieder einen Putschversuch.
-[JM6_2]
-Lass den Motor laufen. Wir sind gleich wieder da.
+[MOB71_D]
+Es gibt keine anspruchsvollere Geliebte als das Volk.
-[JM6_3]
-Bring uns hier weg!!
+[MOB71_E]
+Seit ich aus Vice City zurück bin, gab's drei Revolutionen und vier Staatsstreiche.
-[JM6_4]
-Hãng die Cops ab und bring uns in die sichere Wohnung!
+[MOB71_F]
+Zum Glück bin ich jedesmal befördert worden.
-[JM6_6]
-~g~Los, besorge ein weniger verdãchtiges Fahrzeug!
+[MOB71_G]
+Ich wollte Sie wegen Mercedes etwas fragen.
-[JM6_7]
-~g~Du brauchst alle 3 für den Überfall!
+[MOB71_H]
+OK. Was ist mit ihr?
-[TM1]
-'SCHMUTZIGE WÃSCHE'
+[MOB71_I]
+Ich hör Geschichten über sie und weiß nicht, was ich davon halten soll.
-[TM2]
-'DER GELDBOTE'
+[MOB71_J]
+Vielleicht wollen mich alle demütigen.
-[TM3]
-'DAS TREFFEN BEI SALVATORE'
+[MOB71_K]
+Vielleicht wird sie übermütig, seit ich weg musste, sagen Sie mir nur eins, Tommy. Ist das wahr?.
-[TM4]
-'TRIADEN UND ANDERE KLEINE FISCHE'
+[MOB71_L]
+sagen Sie mir nur eins, Tommy. Ist das wahr?
-[TM5]
-'EXPLODIERENDE FISCHE'
+[MOB71_M]
+Ist was wahr?
-[TONI_P]
-Ich habe einen dringenden Job für dich! -Toni
+[MOB71_N]
+Die Geschichten, die ich höre? Will sie wirklich Anwãltin werden?
-[TM1_A]
-~w~Setz dich, Junge. Los, mach's dir bequem.
+[MOB71_O]
+Welche Schande, Tommy. Wir Cortez sind eine stolze Familie und würden nie einer Tochter erlauben, Anwãltin zu werden.
-[TM1_B]
-~w~Die Wãscherei will also kein Schutzgeld zahlen, was?
+[MOB71_P]
+Sagen Sie mir, dass es nicht wahr ist. Das ertrage ich nicht.
-[TM1_C]
-~w~Denken die Triaden, sie können mich verscheißern?
+[MOB71_Q]
+Colonel, ich versichere Ihnen, dass Mercedes niemals Anwãltin wird. Keine Angst.
-[TM1_D]
-~w~Diesen Möchtegern-Gangstern werden wir eine Lektion erteilen.
+[MOB71_R]
+Danke, Tommy - das wãre zu viel der Schande. Sie ist eine Dame, keine Schmarotzerin.
-[TM1_E]
-~w~Ja, ich werde denen Respekt beibringen. Die rühren keinen meiner Söhne ungestraft an.
+[MOB71_S]
+Ich weiß, Colonel
-[TM1_F]
-~w~Dein Vater - Gott hab ihn selig - hat sich von den Triaden nie etwas gefallen lassen.
+[MOB71_T]
+Tommy, Sie müssen jetzt entschuldigen, gerade kommt der neue Innenminister.
-[TM1_G]
-~w~Sorry, Ma. Ja, Ma.
+[MOB71_U]
+Ich hab seinen Vater vor Jahren bei einem Putschversuch erledigt. Ich muss mich gut mit ihm stellen. Wiederhören.
-[TM1_H]
-~w~Ich will, dass du ihre Wãscherei-Transporter zerstörst
+[MOB22_A]
+Tommy, Sie erweisen sich als sehr nützlich, mein Freund.
-[TM1_I]
-~w~und jeden Triaden-Tölpel niedermachst, der dir in die Quere kommt.
+[MOB22_B]
+Danke, Cortez. Was ist mit meinem Deal?
-[TM1_J]
-~w~8-Ball liefert dir alles, was du dazu brauchst.
+[MOB22_C]
+Tommy, ich mühe mich ohne Unterlass, um diesem Sumpf von elenden Lügen und Intrigen auf den Grund zu gehen.
-[TM2_A]
-~w~TONI ist unterwegs, um jemanden zu erledigen - oder er versucht es jedenfalls.
+[MOB22_D]
+Sie haben mein Wort darauf. Einstweilen möchte ich
-[TM2_AA]
-Er wird nie so sein wie sein Papa. Auf dem Tisch hat er dir eine Nachricht hinterlassen.
+[MOB22_E]
+Ihnen den Dank meines Volkes aussprechen, für das Sie so viel getan haben.
-[TM2_B]
-~w~Die Wãscherei will jetzt bezahlen. Gute Arbeit, mein Junge!
+[MOB_25A]
+Tommy, hier Cortez. Die Franzosen machen mir Ãrger. Und wie.
-[TM2_C]
-~w~Hol das Geld ab und bring es hierher. Pass auf die Triaden auf.
+[MOB_25B]
+Verdammte Heuchler! Jahrhundertelang beuten sie arme Lãnder aus und mich schimpfen sie einen Dieb!
-[TM2_D]
-~w~Die wollen dich wahrscheinlich zu Chop Suey verarbeiten, aber lass dir nichts gefallen.
+[MOB_25C]
+Ich brauche dingend Ihre Hilfe.
-[TM2_E]
-~w~Niemand, wirklich niemand, macht TONI CIPRIANI fertig!
+[MOB_25D]
+Beeilen Sie sich. Ich brauche Sie. Ich hasse die Franzosen.
-[TM2_1]
-~g~Bring das Geld zu Toni!!
+[MOB_26A]
+Hallo, Tommy?
-[TM2_2]
-~g~Du hast sie alle erledigt!
+[MOB_26B]
+Ja?
-[TM3_MA]
-~w~Ich weiß nicht, wo er ist!
+[MOB_26C]
+Baker hier. Wollte dir nur sagen, der Gig hat Spaß gemacht.
-[TM3_MB]
-~w~Ach, mein Sohn weiß manchmal selbst nicht, wer er ist.
+[MOB_26D]
+Danke, auch im Namen der Gang. Eins sollst du wissen:
-[TM3_MC]
-~w~Ja, sein Vater, der war da ganz anders. Immer auf Draht, top, ein echter Mann...
+[MOB_26E]
+Du hast unsern Respekt. Halt die Nase im Wind, Junge.
-[TM3_A]
-~w~Don Salvatore hat ein Treffen angesetzt.
+[MOB_29A]
+Hallo? Spreche ich mit Mr. Tommy Vercetti?
-[TM3_B]
-~w~Du musst erst die Limo und seinen Sohn Joey aus der Werkstatt abholen.
+[MOB_29B]
+Ja.
-[TM3_C]
-~w~Dann holst du Luigi aus seinem Club ab und dann kommst du wieder her und holst mich ab.
+[MOB_29C]
+Ich hab mir sagen lassen, du wãrst der richtige Mann, wenn man Kroppzeug am Hals hat.
-[TM3_D]
-~w~Dann fahren wir alle gemeinsam zum Boss.
+[MOB_29D]
+Vielleicht...
-[TM3_E]
-~w~Diese Triaden wissen einfach nicht, wann Schluss ist.
+[MOB_29E]
+Tja, ich hab 'ne regelrechte Plage am Hals. Haitianer, überall.
-[TM3_F]
-~w~Wenn sie Krieg wollen, sollen sie Krieg haben.
+[MOB_29F]
+Mein Name ist Umberto Robina und es wãr mir recht, wenn du baldmöglichst ins Café Robina kãmst.
-[TM3_G]
-~w~Also, los jetzt.
+[MOB_29G]
+Diesmal haben's die Haitianer nãmlich zu weit getrieben.
-[TM3_1]
-~g~Hol die Limousine bei Joey ab.
+[MOB_29H]
+Test
-[TM3_2]
-~g~Jetzt hol Luigi ab.
+[MOB_30A]
+Tommy, hier Umberto Robina.
-[TM3_3]
-~g~Jetzt hol Toni ab.
+[MOB_30B]
+Wie lãuft das Café?
-[TM3_4]
-~g~Jetzt fahr die Mãnner zu Salvatore.
+[MOB_30C]
+Oh, bestens. Sagenhaft, Tommy, sagenhaft. Keine Memmen, Tommy, nur echte Mãnner. Und wunderschöne Frauen!
-[TM3_5]
-~y~Ein Hinterhalt der Triaden!!
+[MOB_30D]
+Ich wollte nur sagen, für mich und Paps bist du jetzt einer von uns. Ein Kubaner.
-[TM4_B]
-~w~Es herrscht KRIEG! Die Triaden betreiben zur Tarnung einen Fischmarkt in Chinatown.
+[MOB_30E]
+Du bist ein ganzer Kerl. Du hast Mumm in den Knochen.
-[TM4_C]
-~w~Die meisten ihrer Geschãfte werden auf diesem Fischmarkt durchgezogen.
+[MOB_30F]
+Danke, Umberto. Seit ich aus dem Knast raus bin, hat das keiner zu mir gesagt. Bis dann.
-[TM4_D]
-~w~Diese Wãscherei schuldet uns immer noch Geld.
+[MOB_33A]
+Tommy, Phil hier. Spar dir die sentimentalen Worte, hör mir einfach zu, ok?
-[TM4_E]
-~w~Die denken, die Triaden beschützen sie jetzt. Ich schlage vor, wir führen eine Strafaktion durch.
+[MOB_33B]
+Also, ich brau hier 'nen extra starken TNT-Whiskey und ich wollte fragen, ob du mal 'nen Schluck probieren willst.
-[TM4_F]
-~w~Nimm dir diese Jungs und knöpf dir die Köpfe der Triaden vor!
+[MOB_33C]
+Im Ernst, Tommy, wenn du 'nen Drink willst, oder 'ne Wand abbeizen musst - das Zeug macht einen Mann aus dir.
-[TM4_G]
-~w~Und wenn es geht, macht auch ein paar von deren Soldaten fertig.
+[MOB_33D]
+Bei mir hat's jedenfalls gewirkt, auch wenn ich jetzt auf einem Auge nichts mehr sehe. Ich warte auf dich.
-[TM4_GAT]
-~g~Du brauchst einen 'Triaden-Packwagon', um da reinzukommen.
+[MOB_34A]
+Tommy, war ein Vergnügen, mit dir zu arbeiten. So einen Spaß hatte ich seit Vietnam nicht mehr.
-[TM5_A]
-TEXT NO LONGER REQUIRED
+[MOB_34B]
+Also, falls du je irgendwas brauchst, ruf mich an, ok?
-[TM5_B]
-~w~Okay, jetzt hab ich aber die Schnauze voll.
+[MOB_34C]
+Ich vergesse keinen, mit dem ich in der Schlacht war.
-[TM5_C]
-~w~Wir machen die Triaden ein für alle Mal fertig.
+[MOB_34D]
+Und ich kann dir bestimmt irgendwann helfen, ok?
-[TM5_D]
-8-Ball hat einen Müllkarren mit einer Bombe prãpariert.
+[MOB_35A]
+Tommy, die Wunde verheilt gut. Ist nur komisch:
-[TM5_E]
-~w~Sie hat einen Zeitzünder. Wenn du's vermasselst, hinterlassen wir keine Spuren. Hol den Müllkarren ab.
+[MOB_35B]
+da hab ich auf 6 Schlachtfeldern gekãmpft und nie 'n Kratzer abgekriegt und dann das!
-[TM5_F]
-~w~Fahr vorsichtig. 8-Ball sagt, die Bombe ist extrem empfindlich, das kleinste Schlagloch und sie geht hoch.
+[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.
-[TM5_G]
-~w~In ihrer Fischfabrik werden sie dich reinlassen mit dem Müllkarren.
+[MOB_35D]
+Also hör auf mit der sentimentalen Scheiße und hol dir 'nen Drink, ok!
-[TM5_H]
-~w~Stell das Ding zwischen den Benzinkanistern ab und dann nichts wie weg.
+[MOB_36A]
+Tommy, hier Phil. Wollte mich bedanken, dass du mich da rausgehauen hast.
-[TM5_I]
-~w~Es soll rummsen, dass es Fische vom Himmel regnet.
+[MOB_36B]
+Verdammte Vietnamesen. Wo du hinschaust ein Hinterhalt.
-[TM5_J]
-~w~Ne biblische Apokalypse will ich haben, nichts popeliges.
+[MOB_36C]
+Die Wunde heilt gut. Und jetzt kassiere ich meine Versehrtenrente endlich völlig zurecht. Danke, Kumpel.
-[FM2]
-'CURLYS GEHEIMKONTAKTE'
+[MOB_40A]
+Hey, Tommy, hier Sonny. Was macht die Sonnenbrãune?
-[FM4]
-'DER LETZTE WUNSCH'
+[MOB_40B]
+Ich hab keine Sonnenbrãune.
-[FM1_A]
-~w~Die Jungs und ich haben einiges zu besprechen,
+[MOB_40C]
+Naja, mein Geld hast du jedenfalls auch nicht. Daher frag ich mich,
-[FM1_B]
-~w~du wirst dich heute abend um meine Kleine kümmern.
+[MOB_40D]
+was treibst du eigentlich die ganze Zeit, Tommy? Sag doch mal?
-[FM1_C]
-~w~HEY, MARIA! WO BLEIBST DU?
+[MOB_40E]
+Ich bin auf der Suche nach deinem Geld, Sonny. Keine Sorge.
-[FM1_D]
-~w~Dãmliche Ziege. Jedes Mal dasselbe.
+[MOB_40F]
+Ich mach mir aber Sorgen, Tommy, ich kann nicht anders.
-[FM1_E]
-~w~Und hier ist sie, die Königin der Nacht höchstpersönlich!
+[MOB_40G]
+Ich hab nãmlich anscheinend mit zu viel unzuverlãssigen Menschen zu tun.
-[FM1_F]
-~w~Was hast du denn da oben getrieben?
+[MOB_40H]
+Sei du bitte kein unzuverlãssiger Mensch, Tommy.
-[FM1_G]
-~w~Was es auch war, jede Wette, es hat mich Geld gekostet.
+[MOB_40I]
+Tu dir und mir einen Gefallen. Ich freu mich, von dir zu hören.
-[FM1_H]
-~w~Du glaubst doch nicht, ich bin zum Palavern hier, oder?
+[MOB_41A]
+Tommy, kennst du mich noch?
-[FM1_I]
-~w~Halt die Klappe und steig in den Wagen.
+[MOB_41B]
+Hey, Sonny.
-[FM1_J]
-~w~Nimm die Limo, aber bring sie mir heil wieder, hörst du?
+[MOB_41C]
+Ja genau, Sonny. Wir sind doch alte Freunde,
-[FM1_K]
-~w~Und pass auf sie auf, sie kann eine Menge Ãrger machen.
+[MOB_41D]
+aber du schreibst nie, rufst nie an. Willst du denn nicht mehr mein Freund sein?
-[FM1_L]
-~w~Ja, ja, ja! Dein neues Schoßhündchen wird schon alles im Griff haben.
+[MOB_41E]
+Ich hab alle Hãnde voll zu tun, die Sache zu regeln. Und du bist auch keine große Hilfe.
-[FM1_M]
-~w~Er ist ja auch so groß und stark.
+[MOB_41F]
+Ach, ich bin also schuld? Ja, ich hab gehört, dass du zu tun hast...
-[FM1_N]
-~w~Hey, Fiffi, los, wir besuchen Chico und besorgen uns was zum 'Naschen'!
+[MOB_41G]
+Musst Drogenbarone erledigen, ihre Geschãfte übernehmen.
-[FM1_P]
-~g~Da ist Chico. Halt neben ihm an.
+[MOB_41H]
+Vergiss mich nicht, Tommy. Ich verspreche dir nãmlich, dass ich dich nicht vergesse...
-[FM1_S]
-~w~Bitte sehr, die Dame.
+[MOB_42A]
+Tommy.
-[FM1_TT]
-~w~EINE POLIZEI-RAZZIA!
+[MOB_42B]
+Sonny.
-[FM1_1]
-~g~Zurück in die Limo!
+[MOB_42C]
+Anscheinend hörst du neuerdings schlecht, deshalb frag ich dich jetzt nochmal:
-[FM1_2]
-~g~Steig in die Limo!
+[MOB_42D]
+Tommy, wo ist die verdammte Kohle? Wo ist der verdammte Stoff und wo ist mein Anteil an deinem neuen Geschãft?
-[FM1_3]
-~r~Wenn du Maria im Stich lãsst, bringt Salvatore dich um. Kehr um und hol sie!
+[MOB_42E]
+Du hãltst mich zum Narren, Tommy, ich find's bloß nicht zum Lachen.
-[FM1_4]
-~g~Du hast die Frau des Don im Stich gelassen! Los, zurück zur Lagerhalle! Warte dort auf Maria!
+[MOB_43A]
+Tommy, Tommy, Tommy, Sonny hat gerade angerufen, dãmmert dir was?
-[FM1_5]
-~g~Bring Maria wohlbehalten zu Salvatore zurück!
+[MOB_43B]
+Ich weiß nicht, wie das mit dir ist, aber wenn mir jemand droht, dass er meine Familie umbringt,
-[FM1_6]
-~g~Chico ist nicht ewig dort. Bring Maria zu diesem Ufer!
+[MOB_43C]
+dann macht mir das eine Scheißangst. Was gedenkst du zu unternehmen?
-[FM1_7]
-~r~Maria ist tot! Das wird Salvatore nicht gefallen...
+[MOB_43D]
+Nur die Ruhe, Ken, alles wird cool.
-[FM1_8]
-~r~Du hast Marias Lieferanten erledigt!
+[MOB_43E]
+Ich BIN ruhig. So ruhig wie man sein kann, wenn man um sein Leben fürchtet!
-[FM2_J]
-Lasst uns eine Minute alleine.
+[MOB_43F]
+Ken, ich muss mich gerade auf was anderes konzentrieren.
-[FM2_A]
-Das kolumbianische Kartell stellt irgendwo in Liberty SPANK her.
+[MOB_43G]
+Wir kümmern uns zu gegebener Zeit um Forelli.
-[FM2_K]
-Aber wir wissen nicht wo. Und die scheinen jeden unserer Schritte im Voraus zu kennen.
+[MOB_43H]
+Ich bin ruhig. Hör ich mich nicht ruhig an? Muss die Todesangst sein, die auf die Stimme schlãgt.
-[FM2_L]
-Es gibt da einen Typ namens Curly Bob. Er arbeitet in Luigis Bar.
+[MOB45_A]
+Tommy, wir müssen miteinander reden.
-[FM2_M]
-Der verpulvert schon dauernd mehr Geld als er verdient.
+[MOB45_B]
+Wo liegt das Problem, Lance?
-[FM2_N]
-Normalerweise fãhrt er nach der Arbeit mit dem Taxi nach Hause. Folge ihm.
+[MOB45_C]
+Bei dir, mein Freund: Ich finde, du gibst mir keinen fairen Anteil.
-[FM2_O]
-Und wenn er der Verrãter ist, mach ihn fertig.
+[MOB45_D]
+Noch dazu hast du mich vor den Jungs blamiert. Das kann ich nicht auf mir sitzen lassen.
-[FM2_F]
-Da kommt ja unser kleiner, gesprãchiger Freund.
+[MOB45_E]
+Lance, das siehst du falsch. Du hast Fehler gemacht.
-[FM2_G]
-Ist man dir gefolgt? Du weißt, was hier lãuft, muss unter uns bleiben.
+[MOB45_F]
+Tommy, ich bin nicht dein Laufbursche. Nicht dein Lakai.
-[FM2_H]
-Nein, nein, niemand ist mir gefolgt. Hast du meinen Stoff?
+[MOB45_G]
+Lance, alles ist ok, solange du keinen Mist baust. Und sollte ICH Mist bauen, steh ich dafür gerade.
-[FM2_I]
-Hier ist dein SPANK, du Ratte, und jetzt rede.
+[MOB45_H]
+Tommy, ich hab alles für dich getan und du trittst mich mit Füßen. Mach das doch nicht.
-[FM2_P]
-Okay. Die Leones führen einen Zwei-Fronten-Krieg.
+[MOB45_I]
+Lance, ich betrüg dich nicht und falle dir nicht in den Rücken, ok?
-[FM2_Q]
-Sie kãmpfen mit den Triaden um ein Territorium, und keiner der beiden gibt nach.
+[MOB45_J]
+Reiß dich zusammen. Es ist schwer genug, ohne dass du mir die Ohren vollheulst.
-[FM2_R]
-Gleichzeitig hat Joey Leone Streit mit den Forellis angefangen.
+[MOB45_K]
+Vertrau mir, hörst du. Hörst du?
-[FM2_S]
-Jeden Tag verlieren sie Leute und Einfluss in der Stadt.
+[MOB45_L]
+Ja, Tommy, aber ich halt das nicht mehr lange aus.
-[FM2_T]
-Salvatore wird gefãhrlich und paranoid. Er verdãchtigt alles und jeden.
+[MOB45_M]
+Lance, komm mir bloß nicht so, ich warne dich.
-[FM2_U]
-Bei treuen Gefolgsleuten wie dir, wie kann er sich da nur Sorgen machen?
+[MOB45_N]
+Reg dich ab, mach ein paar Tage frei, dann unterhalten wir uns, ok?
-[FM2_1]
-~g~Da ist Curly Bob!
+[MOB46_A]
+Tommy - Lance.
-[FM2_2]
-~g~Curly hat den Club verlassen. Folge ihm!
+[MOB46_B]
+Ja?
-[FM2_5]
-~g~Bring ihn nach Portland Harbour.
+[MOB46_C]
+Kein 'Schön, dass du anrufst, Lance!' Kein freundliches Wort? Was soll das?
-[FM2_6]
-~r~Curly steigt in kein geschrottetes Taxi!
+[MOB46_D]
+Ich habe gerade zu tun, Lance. Was willst du?
-[FM2_7]
-~r~Curly hat Angst! Das Treffen ist abgeblasen!
+[MOB46_E]
+Nichts. Ich wollte dir nur sagen, wir kriegen das hin.
-[FM2_8]
-~g~Knöpf dir Curly Bob vor!
+[MOB46_F]
+Du und ich, ohne Probleme. Du verstehst mich?
-[FM2_9]
-~r~Curly Bob ist tot!
+[MOB46_G]
+Wir müssen es hinkriegen. Sonst sind wir erledigt, Lance.
-[FM2_10]
-~r~Curly ist entwischt!
+[MOB46_H]
+Wir stecken schon viel zu tief drin. Aber danke für den Anruf. Du hörst von mir.
-[FM2_11]
-~g~Parke vor Luigis Club, Curly Bob kommt gleich heraus.
+[MOB_47A]
+Tommy - Lance. Wir stecken in der Patsche. Du musst sofort kommen.
-[FM2_12]
-~r~Er ist dir entwischt!
+[MOB52_A]
+Hey, Leo, ich glaube, wir haben einen Kãufer für Diaz' Ware.
-[FM3_A]
-~w~Wir sollten diese kolumbianischen Mistkerle fertigmachen,
+[MOB52_B]
+Du musst ihn anrufen und den Deal in die Wege leiten, ok?
-[FM3_B]
-~w~aber durch den Krieg mit den Triaden sind wir dazu zu geschwãcht.
+[MOB52_C]
+Wo bist du gerade?
-[FM3_C]
-~w~Das Kartell hat unendlich Geld aus dem Handel mit diesem Mistzeug SPANK.
+[MOB52_D]
+Ist irgendwas, Leo? Du hörst dich so komisch an.
-[FM3_D]
-~w~Wenn wir sie offen angreifen, putzen sie uns weg.
+[MOB52_E]
+Sag mir, wo du bist.
-[FM3_E]
-~w~Die müssen das SPANK auf diesem großen Schiff machen, zu dem dich Curly geführt hat.
+[MOB52_F]
+Verdammt, wer ist da dran? Gib mir Leo!
-[FM3_F]
-~w~Wir müssen also mit Köpfchen vorgehen. Genauer gesagt, mit DEINEM Köpfchen.
+[MOB52_G]
+Leo ist 'ne Weile verreist, ich vertrete ihn.
-[FM3_G]
-~w~Ich bitte dich, mir, Salvatore Leone zuliebe, dieses SPANK Labor zu zerstören.
+[MOB52_H]
+Zum Teufel mit dir!
-[FM3_H]
-~w~Wenn du das für mich tust, bist du ein gemachter Mann. Du kriegst alles, was du willst.
+[MOB54_A]
+Hi, Tommy!
-[FM3_I]
-~w~Geh zu 8-Ball. Du brauchst einen Fachmann, um dieses Schiff hochzujagen.
+[MOB54_B]
+Hi, Mercedes. Wie geht's?
-[FM3_8A]
-~w~Hi, Kumpel! Salvatore hat schon angerufen,
+[MOB54_C]
+Ich hab 'ne neue Wohnung in Vice Point.
-[FM3_8B]
-~w~aber für so einen Job brauchst du eine Menge Chinaböller.
+[MOB54_D]
+Vielleicht kommst du mich ja mal besuchen.
-[FM3_8D]
-~w~Aber du kennst mich. Dafür scheppert's dann auch gewaltig.
+[MOB54_E]
+Klar, gern. Also, bis spãter.
-[FM3_8E]
-~w~Okay, dann wollen wir mal!
+[MOB55_A]
+Tommy, ich bin's.
-[FM3_8F]
-~w~Ich kann das Baby scharf machen, aber eine Knarre kann ich mit diesen Hãnden immer noch nicht halten.
+[MOB55_B]
+Hi, Mercedes.
-[FM3_8G]
-~w~Hier, das Gewehr hier wirst du sicher brauchen.
+[MOB55_C]
+Tommy, mir ist so langweilig. Wann hast du denn mal Zeit für mich?
-[FM3_4]
-~g~Halt an und lass 8-Ball aussteigen!
+[MOB55_D]
+Was soll denn das heißen?
-[FM3_7]
-~r~8-Ball hat's erwischt!
+[MOB55_E]
+Ich weiß, du hast so viel zu tun, musst Leute beseitigen und bestechen.
-[FM3_8]
-~r~Die Wachmãnner wurden alarmiert!
+[MOB55_F]
+Aber ich will mal wieder Spaß haben. Also vergiss mich nicht, hörst du?
-[FM4_A]
-~w~Ah, sieh an! Mein bester Troubleshooter.
+[MOB56_A]
+Tommy, es heißt, du hast Ricardo Diaz erledigt.
-[FM4_B]
-~w~Ich bin stolz auf dich, meine Junge. Du hast es diesen Mistkerlen gezeigt.
+[MOB56_B]
+In seinem Haus ist ein Feuer ausgebrochen.
-[FM4_C]
-~w~Ich hab nur noch einen kleinen Job für dich, bevor wir alle feiern können.
+[MOB56_C]
+Ich glaube, er hatte ein Acrylhemd an und ist verbrannt.
-[FM4_D]
-~w~Um die Ecke von Luigis Club steht ein Wagen.
+[MOB56_D]
+Tommy, ich bin so stolz auf dich. Ich wusste, du bist ein echter Mann.
-[FM4_E]
-~w~Innen drin sieht's ziemlich aus.
+[MOB56_E]
+Und er war ein Mistkerl. Ich bin so stolz, dass du mein Freund bist.
-[FM4_F]
-~w~Wir haben so einem Typ versehentlich ein Loch in den Kopf gemacht.
+[MOB56_F]
+Ich weiß, du hast zu tun, du musst schließlich die Stadt erobern.
-[FM4_H]
-~w~Bring den Wagen zur Schrottpresse, bevor die Cops ihn finden.
+[MOB56_G]
+Aber vergiss mich nicht, hörst du?
-[AM3]
-'DER PAPARAZZO'
+[MOB57_A]
+Ich bin's, Mercedes. Ich liebe dich nicht mehr, Tommy.
-[AM4]
-'ZAHLTAG FÜR RAY'
+[MOB57_B]
+Wirklich nicht mehr. Du bist nicht mehr nett zu Mercedes.
-[AM5]
-'V-MANN TANNER'
+[MOB57_C]
+Du behandelst mich nicht mehr wie eine Dame. Du ignorierst mich und ich hasse dich.
-[AM1_A]
-Wir müssen ein paar Dinge klãren, bevor wir unsere Beziehungen fortsetzen,
+[MOB57_D]
+Ich bestehe darauf, dass du sofort zu mir kommst!
-[AM1_B]
-geschãftlich oder sonstwie. Legen wir also die Karten auf den Tisch.
+[MOB58_A]
+Tommy.
-[AM1_C]
-Ich bin eine Yakuza und ich weiß, dass du für Salvatore Leones Familie gearbeitet hast.
+[MOB58_B]
+Hey, Mercedes.
-[AM1_D]
-Ich kann dir einen Job in unserer Organisation verschaffen,
+[MOB58_C]
+Selber hey, du toller Hecht. Ich bin sauer auf dich, Tommy.
-[AM1_E]
-aber zuerst musst du mir beweisen, dass du dich wirklich von der Mafia losgesagt hast.
+[MOB58_D]
+Schick mich nie mehr zu diesem Jezz Torrent.
-[AM1_G]
-Sorge dafür, dass er seinen Club nicht lebend erreicht.
+[MOB58_E]
+So ein Jammerlappen. Mittendrin fãngt er an zu weinen wegen seinem Hündchen,
-[AM1_H]
-Maria und ich reden inzwischen ein bisschen über die alten Zeiten.
+[MOB58_F]
+das gestorben ist, als er 7 war, und dass seine Mama ihn nie lieb hatte.
-[AM1_I]
-Oh, Asuka, du hast einen Massagestab.
+[MOB58_G]
+Und Tommy - privat lãuft er in Perücke und BH rum.
-[AM1_J]
-Das ist kein Massagestab.
+[MOB58_H]
+Ich bin nicht gut auf dich zu sprechen!
-[AM1_1]
-~g~Salvatore verlãsst jetzt Luigis Club!
+[MOB59_A]
+Oh, Tommy. Ich bin's, Mercedes.
-[AM1_2]
-~r~Man hat dich entdeckt!
+[MOB59_B]
+Ich wollte dir nur sagen, es ist ganz toll beim Film.
-[AM1_3]
-~r~Du hast Salvatore verpasst!
+[MOB59_C]
+Wenn du nochmal etwas für mich hast, sag Bescheid.
-[AM1_4]
-~r~Na, prima! Du hast dein Opfer verscheucht. Und du willst ein Profi sein?
+[MOB59_D]
+Wirklich. Ich wollte immer Schauspielerin werden.
-[AM1_5]
-~g~Begib dich in den Rotlichtbezirk und warte, bis Salvatore den Club verlãsst.
+[MOB59_E]
+Ich denke, ich lerne viel über die Dramaturgie.
-[AM1_7]
-~r~Salvatore sitzt bequem zu Hause und schlürft einen Cocktail. 'Der Schakal' bist du nicht gerade!
+[MOB59_F]
+Es ist so lehrreich! Vielen, vielen Dank. Bis bald. Adios.
-[AM1_8]
-~g~Salvatore wird Luigis Club um zirka ~1~:~1~ verlassen.
+[MOB_99]
+Geh zu der Telefonzelle vor Ort.
-[AM2_4]
-~g~Du bist für die so unsichtbar wie ein Hochhaus!
+[MOB_98]
+Geh zu der Telefonzelle vor Ort.
-[AM3_A]
-Ein Reporter hat rumgeschnüffelt.
+[MOB_97]
+Geh zu der Telefonzelle vor Ort.
-[AM3_B]
-Maria und ich sind ein bisschen ins Grüne gefahren, bis du diesen miesen Voyeur beseitigt hast.
+[MOB_96]
+Geh zu der Telefonzelle vor Ort.
-[AM4_A]
-Ah, mein hübsches Helferlein!
+[MOB_95]
+Geh zu der Telefonzelle vor Ort.
-[AM4_B]
-Maria ist gerade beschãftigt, aber ich richte ihr aus, dass du hier warst.
+[A_TIME]
++~1~ Sekunden
-[AM4_C]
-Wer ist da? Asuka? Ich weiß, ich war ein böses Mãdchen, aber ich muss dringend pinkeln!
+[F_RANGE]
+~g~Du bist außer Reichweite des Feuerwehrfunks. Fahr nãher an eine Feuerwache heran!
-[AM4_D]
-Wird Zeit dass du unseren Mann bei der Polizei kennenlernst.
+[DODO_FT]
+Du bist ~1~ Sekunden geflogen!
-[AM4_E]
-Das ist seine Bezahlung für den letzten Job, den er für uns erledigt hat.
+[GA_8]
+Benutze den Zünder, um die Bombe hochgehen zu lassen.
-[AM4_F]
-Verstãndlicherweise ist er vorsichtig.
+[GA_10]
+Hübsche Karre. Hier sind deine $~1~.
-[AM4_G]
-Begib dich so schnell wie möglich zu dem öffentlichen Fernsprecher in Torrington und warte auf seine Anweisungen.
+[GA_11]
+So eine Karre haben wir schon. Die können wir nicht gebrauchen.
-[AM5_A]
-Maria und ich sind shoppen gegangen.
+[GA_12]
+Bombe ist scharf.
-[AM5_B]
-Unser Spitzel hat uns informiert, dass einer unserer Fahrer ein übereifriger Undercover Cop ist!
+[GA_13]
+Auf dich ist Verlass. Wenn du alle, die auf der Liste stehen, abgeliefert hast, kriegst du einen Bonus.
-[AM5_C]
-Ohne sein Auto ist er praktisch ein Nichts. Wir haben seinen Wagen mit einem Sender versehen.
+[GA_14]
+Du hast alle georderten Karren geliefert. Sehr gut. Hier, für dich.
-[AM5_D]
-Knöpf ihn dir vor!
+[GA_15]
+Hoffentlich gefãllt dir die neue Farbe.
-[AM5_1]
-Tanner hat dich bemerkt!
+[GA_16]
+Das Umspritzen ist gratis.
-[AS1]
-'DER KÖDER'
+[GA_19]
+An dem Modell haben wir kein Interesse.
-[AS2]
-'ESPRESSO-2-GO!'
+[GA_20]
+Von der Sorte haben wir schon mehr als genug. Sorry, da kommen wir nicht ins Geschãft.
-[AS4]
-'DAS LÖSEGELD'
+[CHASE]
+Größtes Medieninteresse bisher
-[AS1_A]
-~w~Miguel findet anscheinend, dass ich ihn schlecht behandle.
+[CHASE1]
+Null
-[AS1_B]
-~w~Trotzdem hat er uns mitgeteilt, wie sehr Catalina deine Rache fürchtet.
+[CHASE2]
+Minimal
-[AS2_A]
-~w~Wir haben Catalinas Plãne mit dem SPANK unterschãtzt.
+[CHASE3]
+Vages Interesse
-[AS2_B]
-~w~Das beschrãnkt sich bei weitem nicht darauf, dass die Yardies es an der Straßenecke verkaufen.
+[CHASE4]
+Lokalblatt Seite 7
-[AS2_D]
-~w~Die verkaufen SPANK über Kaffeestãnde.
+[CHASE5]
+Lokalblatt Titelseite
-[AS2_1]
-~g~Alle Espressostãnde in Portland zerstört!!
+[CHASE6]
+Vice Courier einspaltig
-[AS2_2]
-~g~Alle Espressostãnde auf Staunton Island zerstört!!
+[CHASE7]
+Vice Courier Titelseite
-[AS2_3]
-~g~Alle Espressostãnde in Shoreside Vale zerstört!!
+[CHASE8]
+Lokalsender 3-Uhr-Nachrichten
-[AS2_4]
-~r~Das Kartell hat seine Dealer gewarnt!!
+[CHASE9]
+Lokalsender 20-Uhr-Nachrichten
-[AS2_5]
-~g~Da sind noch Espressostãnde in Shoreside Vale und auf Staunton Island!
+[CHASE10]
+Lokalsender Live-Berichterstattung
-[AS2_6]
-~g~Da sind noch Espressostãnde in Shoreside Vale!
+[CHASE11]
+UFA Today Seite 12
-[AS2_7]
-~g~Da sind noch Espressostãnde auf Staunton Island!
+[CHASE12]
+UFA Today Seite 4
-[AS2_8]
-~g~Da sind noch Espressostãnde in Portland!
+[CHASE13]
+Foto in UFA Today
-[AS2_9]
-~g~Da sind noch Espressostãnde in Portland und Shoreside Vale!
+[CHASE14]
+Landesweites TV 4-Uhr-News
-[AS2_10]
-~g~Da sind noch Espressostãnde in Portland und auf Staunton Island!
+[CHASE15]
+Landesweites TV 20-Uhr-News
-[AS2_12]
-~g~Suche in den Sadtteilen von Liberty City nach ~b~Espresso-2-Go-Stãnden!
+[CHASE16]
+Landesweite Live-Berichterstattung
-[AS3_A]
-~W~Drücken wir noch fester zu oder warten wir, bis es von selbst abfãllt?
+[CHASE17]
+Internationale Berichterstattung
-[AS3_B]
-~w~Hau einfach drauf...
+[CHASE18]
+Nationale Krise
-[AS3_D]
-~w~Mein Helferlein!
+[CHASE19]
+Internationale Krise
-[AS3_E]
-~w~Mir war langweilig, da dachte ich mir, ich leiste Asuka Gesellschaft.
+[CHASE20]
+Weltereignis
-[AS3_1]
-~g~Such dir ein ~r~Boot~g~ und fahre zu der ~b~Markierungsboje!
+[CHASE21]
+Stoff aus dem Legenden sind
-[AS3_3]
-~g~Warte, bis die ~y~Maschine~g~ zur Landung ansetzt!
+[CR_1]
+Kran kann dieses Fahrzeug nicht anheben.
-[AS3_5]
-~g~Sammle die Ladung ein!
+[PU_MONY]
+Du hast nicht genug Geld.
-[AS3_4]
-~g~Benutze einen Raketenwerfer, um das ~y~Flugzeug~g~ abzuschießen!!
+[CO_ALL]
+Du hast sie alle geliefert. Hier, für dich.
-[AS3_2]
-~b~Fahr zu der Markierungsboje! ~y~Das Flugzeug landet gleich!!
+[FEM_ON]
+AN
-[AS3_6]
-~g~~1~ VON 8
+[FEM_OFF]
+AUS
-[KM1]
-'DIE BEFREIUNG DES KANBU'
+[FEM_YES]
+Ja
-[KM3]
-'DER JAMAICA DEAL'
+[FEM_NO]
+Nein
-[KM4]
-'DIE GANG'
+[FEM_RET]
+Wiederholen
-[KM5]
-'DIE ABRECHNUNG'
+[FEC_NA]
+Nicht verfügbar
-[KM1_A]
-Meine Schwester hãlt große Stücke auf dich,
+[FEC_CWL]
+Eine Waffe nach links
-[KM1_E]
-aber ich bin noch nicht überzeugt, dass ein Gajin wie du was auf dem Kasten hat.
+[FEC_CWR]
+Eine Waffe nach rechts
-[KM1_B]
-Vielleicht kannst du mir bei einer etwas kniffligen Sache helfen.
+[FEC_LOF]
+Nach vorne sehen
-[KM1_F]
-Ein Fehlschlag wãre natürlich unverzeihlich.
+[FEC_TAR]
+Zielen
-[KM1_C]
-Ein Yakuza Kanbu sitzt in Haft und wartet auf seine Überführung zum Prozess.
+[FEC_MOV]
+Bewegung
-[KM1_G]
-Er ist ein geschãtztes Mitglied der Familie.
+[FEC_CAM]
+Blickwinkel
-[KM1_H]
-Befreie ihn aus der Haft und bring ihn in das Dojo beim Bedford Point.
+[FEC_PAU]
+Pause
-[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_ENV]
+In Fahrzeug einsteigen
-[KM1_1]
-~g~Klau ein Polizeiauto!
+[FEC_JUM]
+Springen
-[KM1_2]
-~g~Bau eine Bombe in den Wagen ein!
+[FEC_ATT]
+Angreifen oder Waffe abfeuern
-[KM1_3]
-~g~Jetzt bring ihn zu dem Yakuza Dojo.
+[FEC_RUN]
+Rennen
-[KM1_5]
-~g~Okay, jetzt fahr zum Polizeirevier.
+[FEC_FPC]
+Subjektive Kamera
-[KM1_6]
-~g~Bau eine Bombe in das Auto ein!
+[FEC_LL]
+Nach links sehen
-[KM1_7]
-~g~Nur autorisierte Polizeifahrzeuge!
+[FEC_LB]
+Nach hinten sehen
-[KM1_9]
-~r~Du hast keine Autobombe benutzt, um die Wand zu sprengen.
+[FEC_LR]
+Nach rechts sehen
-[KM1_10]
-~r~Der Yakuza Kanbu ist tot - genau wie deine Ehre!
+[FEC_HOR]
+Hupe
-[KM1_11]
-~r~Du hast dich selbst in Schwierigkeiten gebracht!
+[FEC_VES]
+Fahrzeugsteuerung
-[KM2_A]
-Gewisse Umgangsformen sind in diesem Beruf von nicht zu unterschãtzender Wichtigkeit.
+[FEC_BRA]
+Bremsen oder rückwãrts fahren
-[KM2_B]
-Es ist eine Schande. Jemand hat mir einmal einen Gefallen getan, und ich konnte mich nie dafür erkenntlich zeigen.
+[FEC_HAB]
+Handbremse
-[KM2_C]
-Der Mann ist ein Autonarr, und er hat gebeten, dass wir ihm bestimmte Modelle für seine Sammlung besorgen.
+[FEC_CAW]
+Fahrzeugwaffe
-[KM2_F]
-Mein Ehrgefühl verlangt das von mir.
+[FEC_ACC]
+Beschleunigen
-[KM2_2]
-~g~Auto abgeliefert.
+[FEC_CCF]
+Konfiguration :
-[KM3_A]
-Wenn Ungemach droht, wendet der Narr sich ab, wãhrend der Weise sich ihm stellt.
+[FEC_CF1]
+Konfig. 1
-[KM3_B]
-Das kolumbianische Kartell hat unsere wiederholten Bitten ignoriert, unsere Interessen in Liberty zu berücksichtigen.
+[FEC_CF2]
+Konfig. 2
-[KM3_C]
-Jetzt verhandeln die mit den Jamaikanern, um uns weiter zu demütigen.
+[FEC_CF3]
+Konfig. 3
-[KM3_D]
-Sie wollen den Deal am anderen Ende der Stadt besiegeln.
+[FEC_CF4]
+Konfig. 4
-[KM3_F]
-Nimm einen meiner Mãnner, klau einen Yardie-Wagen und statte den Kolumbianern einen Besuch ab.
+[FEC_CDP]
+Controller-Anzeige :
-[KM3_E]
-Unser Ehrgefühl verlangt es, dass niemand am Leben bleibt.
+[FEC_ONF]
+Zu Fuß
-[KM3_2]
-~g~Hole deinen Kontaktmann ab.
+[FEC_INC]
+Im Auto
-[KM3_3]
-~g~Das Treffen findet auf dem Krankenhaus-Parkplatz in Rockford statt!
+[FEC_VIB]
+Vibration :
-[KM3_4]
-~r~Sie sind entkommen!
+[FEL_ENG]
+Englisch
-[KM3_6]
-~g~Knöpf sie dir vor! Mach sie fertig!
+[FEL_FRE]
+Französisch
-[KM3_8]
-~g~Du brauchst einen Yardie-Wagen für diesen Job!
+[FEL_GER]
+Deutsch
-[KM3_9]
-~r~Einer der Kolumbianer ist tot. Der Deal ist geplatzt.
+[FEL_ITA]
+Italienisch
-[KM3_10]
-~r~Der Kontaktmann ist tot!
+[FEL_SPA]
+Spanisch
-[KM4_A]
-Um wahrhaft stark zu sein, darfst du niemals Schwãche zeigen.
+[FED_DBG]
+Menu Debug
-[KM4_C]
-Sammle die Gelder umgehend ein, damit wir sie in unsere Casinos stecken können.
+[FED_RID]
+Reload IDE
-[KM4_1]
-Ich kann euch nicht bezahlen, und selbst wenn ich könnte, würde ich es nicht tun.
+[FED_RIP]
+Reload IPL
-[KM4_9]
-Eine Jugendbande hat mich gerade überfallen! Sie haben mir alles genommen!
+[FED_PAH]
+Parse Heap
-[KM4_2]
-Ihr seid zu nichts nutze.
+[FED_DFL]
+CTheScripts::DbgFlag
-[KM4_10]
-Was sind SIE denn eigentlich für ein Yakuza..?
+[FED_DLS]
+Big White Debug Light Switched
-[KM4_3]
-Dafür bezahle ich euch Gangster nicht. Diese Art von Schutz kann ich auch von der verdammten Polizei bekommen!
+[FED_SPR]
+Show Ped Road Groups
-[KM4_4]
-~g~Bestrafe die verantwortliche Gang und stelle das ~b~Schutzgeld~g~ sicher!
+[FED_SCR]
+Show Car Road Grups
-[KM4_7]
-~r~Der Ladenbesitzer hat sein Leben verröchelt.
+[FED_SCZ]
+Show Cull Zones
-[KM4_5]
-Donald Love möchte dich in seinem Teegarten sehen, um mit dir zu reden.
+[FED_DSR]
+Debug Streaming Requests
-[KM4_6]
-Da ist das Geld. Es ist alles da!
+[FED_SCP]
+gbShowCollisionPolys
-[KM4_8]
-~g~Tasche aufgesammelt!
+[PL_STAT]
+Spielerstatistiken
-[KM5_A]
-DU! Wie passend, dass du ausgerechnet jetzt dein ehrloses Gesicht zeigst!
+[PE_WAST]
+Von dir abservierte Personen
-[KM5_B]
-Es scheint, deine Versuche, die Jamaikaner davon abzuhalten,
+[PE_WSOT]
+Von anderen abservierte Personen
-[KM5_B1]
-sich mit dem Kartell einzulassen, sind komplett fehlgeschlagen!
+[TM_BUST]
+Zahl deiner Verhaftungen
-[KM5_C]
-Yardie-Pusher verdealen pãckchenweise SPANK in den Straßen von Liberty, als würden sie Hotdogs verkaufen!
+[GNG_WST]
+Gang-Mitglieder
-[KM5_D]
-Die Mistkerle vom Kartell lachen uns aus, lachen MICH aus!
+[DED_CRI]
+Kriminelle
-[KM5_E]
-Ich gebe dir eine letzte Chance das Vertrauen zu rechtfertigen, das meine Schwester in dich setzt!
+[PER_COM]
+Absolviert (in Prozent)
-[KM5_F]
-Mach diese Dreckskerle fertig und wasch deine befleckte Ehre im Blut unserer Feinde rein!!!
+[KGS_EXP]
+Sprengstoffverbrauch in kg
-[KM5_3]
-~r~Du hast mindestens ~1~ der Yardies nicht erwischt.
+[ACCURA]
+Treffsicherheit
-[KM5_4]
-~g~Du hast ~1~ der Yardies erwischt.
+[ST_WEAP]
+Waffen-Budget
-[KM5_5]
-~g~Du hast ~1~ der Yardies erwischt. BONUS $~1~
+[ST_PROP]
+Budget für Objekte
-[RM1]
-'DAS SCHWEIGEN DES VERRÃTERS'
+[ST_AUTO]
+Budget für Autoreparaturen und Lackierung
-[RM3]
-'BRENNENDE BEWEISE'
+[ST_PHOT]
+Von dir gemachte Fotos
-[RM4]
-'TÖDLICHE BOOTSFAHRT'
+[ST_LOAN]
+Besuche von Kredithaien
-[RM5]
-'DER GEPANZERTE ZEUGE'
+[ST_STOR]
+Geknackte Lãden
-[RM1_D]
-Er steht unter Zeugenschutz und sitzt mit bewaffneten Leibwãchtern in einer Wohnung in Newport, irgendwo hinter dem Parkplatz.
+[ST_MOVI]
+Film-Stunts
-[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_PIZZ]
+Gelieferte Pizzas
-[RM1_1]
-~g~Check das Zeugenschutz-Haus aus.
+[ST_GARB]
+Getãtigte Müllfuhren
-[RM1_2]
-~g~Knöpf dir McAffrey vor!
+[ST_ICEC]
+Verkaufte Eiscreme
-[RM2_A1]
-Hey, Junge! Hier rüber!
+[TOP_SHO]
+Beste Schießstand-Punktzahl
-[RM2_A]
-Ein alter Kumpel aus der Army macht Geschãfte in Rockford.
+[SHO_RAN]
+Schießstand-Rangliste
-[RM2_D]
-Er braucht Hilfe. Zum Dank will er dir Superpreise machen für alles, was du bei ihm kaufst.
+[SEAGULL]
+Abgeschossene Möwen
-[RM2_E]
-Ray hat schon angerufen... Aber ich dachte, er schickt mehr Leute.
+[PROPOWN]
+Objekte in deinem Besitz
-[RM2_F]
-Na ja, drei Arme sind besser als einer, also nimm dir, was du brauchst.
+[ST_TIME]
+Gespielte Zeit
-[RM2_G]
-~g~Sieh nach Phil!
+[ST_FTIM]
+Flugstunden
-[RM2_H]
-~r~Phil hat's erwischt!!
+[ST_PRAN]
+Piloten-Rating
-[RM2_L]
-Heh-hey! Wãre ich mit DIR in Nicaragua gewesen, hãtte ich vielleicht meinen Arm noch!
+[ST_RAN0]
+Anfãnger
-[RM2_N]
-Lass das Geld da. Und jetzt verschwinde. Ich regle das mit den Cops.
+[ST_RAN1]
+Navigator
-[RM3_D]
-Das Beweismaterial wird gerade quer durch die Stadt transportiert.
+[ST_RAN2]
+Co-Pilot
-[RM3_E]
-Du wirst diesen Wagen rammen und jedes kleine Beweisstück einsammeln, wenn es rausfãllt.
+[ST_RAN3]
+Halb-Profi
-[RM3_F]
-Wenn du alles hast, lass das Zeug im Wagen und zünde ihn an.
+[ST_RAN4]
+Könner
-[RM3_G]
-Das bringt uns beiden eine Stange Geld ein, mein Junge.
+[ST_RAN5]
+Profi
-[RM3_1]
-~g~Lass das Beweismaterial in einem Auto und zünde das Auto dann an.
+[ST_RAN6]
+Ass
-[RM3_4]
-~g~Der Staatsanwalt hat die Beweisfotos verloren!
+[ST_RAN7]
+Roter Baron
-[RM3_6]
-~r~Die Fotos werden sich über ganz Liberty verteilen!
+[ST_DRWN]
+Gefütterte Fische
-[RM3_7]
-~g~Steck jetzt das Auto in Brand!
+[ST_FASH]
+Kleidungsbudget
-[RM4_A]
-Ich glaube, mein Partner ist ein Verrãter.
+[ST_DAMA]
+Zerstörte Objekte
-[RM4_C]
-Meistens fãhrt er abends mit seinem Boot fischen, nahe dem Leuchtturm auf dem Portland Rock.
+[TM_DED]
+Krankenhausbesuche
-[RM4_D]
-Klau ein Polizeiboot und mach seinen miesen Machenschaften ein Ende!
+[DAYSPS]
+Im Spiel verstrichene Tage
-[RM4_1]
-~g~Klau ein Polizeiboot.
+[NUMSHV]
+Besuche in Versteck
-[RM4_2]
-~g~Fahr zum Leuchtturm und nimm dir Rays Partner vor!
+[MXCARD]
+Weitester IRRSINNS-Sprung (in Fuß)
-[RM5_A]
-Du unfãhiger Idiot!
+[MXCARJ]
+Höchster IRRSINNS-Sprung (in Fuß)
-[RM5_A1]
-Du hast alles vermasselt! Es geht um mein Leben, und du kannst nicht mal eine Fliege totschlagen!
+[MXCARDM]
+Weitester IRRSINNS-Sprung (m)
-[RM5_B]
-Ich hab dir viel Geld gezahlt, dafür, dass du diesen Zeugen beseitigst, aber er lebt!
+[MXCARJM]
+Höchster IRRSINNS-Sprung (m)
-[RM5_B1]
-Und heute wird er vor dem FBI aussagen!
+[MXFLIP]
+Max. Anzahl Salti
-[RM5_C]
-Er muss jeden Moment aus dem Carson General Hospital in Rockford rausgebracht werden.
+[MXJUMP]
+Max. Drehungen im Sprung
-[RM5_D]
-Wenn er singt, singe ich auch...
+[BUL_FIR]
+Verschossene Kugeln
-[RM5_E]
-Also los, erledige den Job, für den ich dich bezahlt habe!
+[BUL_HIT]
+Kugeln, die trafen
-[RM5_1]
-~g~Fang den Krankenwagen ab.
+[SPRAYIN]
+Anzahl Lackierungen
-[RM5_2]
-~g~Man hat dich bemerkt!!
+[BSTSTU]
+Bester IRRSINNS-Stunt bisher
-[RM5_3]
-~g~Das war ein Ablenkungsmanöver!
+[INSTUN]
+Irrsinns-Stunt
-[RM5_4]
-~g~Kugel können den Panzer nicht durchschlagen!!
+[PRINST]
+Super Irrsinns-Stunt
-[RM5_5]
-~g~Der Panzer ist feuersicher!!
+[DBINST]
+Doppelter Irrsinns-Stunt
-[RM5_7]
-~r~Zeuge wurde abgeliefert!!
+[DBPINS]
+Super-Doppel-Irrsinns-Stunt
-[RM5_8]
-~g~Zeuge ist ertrunken!!
+[TRINST]
+Dreifacher Irrsinns-Stunt
-[LOVE2]
-'DAS KENJI-KOMPLOTT'
+[PRTRST]
+Super-Dreifach-Irrsinns-Stunt
-[LOVE3]
-'NÃCHTLICHER FISCHZUG'
+[QUINST]
+Vierfacher Irrsinns-Stunt
-[LOVE1_A]
-Zunãchst möchte ich dir danken, dass du diese Sache für mich geregelt hast.
+[PQUINS]
+Super-Vierfach-Irrsinns-Stunt
-[LOVE1_F]
-Die Leute interpretieren heute in alles etwas hinein.
+[NOSTUC]
+Bisher keine Irrsinns-Stunts geschafft
-[LOVE1_D]
-Sie versuchen, mir immer noch mehr Geld abzupressen, aber ich halte nichts von Verhandlungen.
+[NOUNIF]
+Monster-Stunts geschafft
-[LOVE1_E]
-Deal ist Deal, die sehen keinen Penny von mir.
+[NMISON]
+Begonnene Missionen
-[LOVE1_G]
-Befreie meinen Freund, egal wie.
+[PASDRO]
+Ans Ziel beförderte Fahrgãste
-[LOVE1_2]
-~g~Rette den alten asiatischen Gentleman.
+[MONTAX]
+Mit Taxi verdientes Geld
-[LOVE1_3]
-~g~Bring den alten Asiaten zu Love.
+[DAYPLC]
+Tagesetat für Polizei
-[LOVE1_4]
-~g~Der alte Asiate muss in einer der Garagen sein...
+[CRIMRA]
+Rang:
-[LOVE1_6]
-~r~Der alte Asiate ist von uns gegangen!
+[STPR_1]
+Malibu Club
-[LOVE1_7]
-~g~Das Tor öffnet sich nur für Autos der kolumbianischen Gang.
+[STPR_2]
+Druckerei
-[LOVE2_A]
-Nichts lãsst die Grundstückspreise so tief purzeln wie ein guter alter Bandenkrieg,
+[STPR_3]
+Filmstudio
-[LOVE2_B]
-außer vielleicht eine Pestepidemie... Aber das ginge hier wohl zu weit.
+[STPR_4]
+Eiscremefabrik
-[LOVE2_C]
-Wie ich bemerkt habe, sind die Yakuza und die Kolumbianer nicht eben Busenfreunde.
+[STPR_5]
+Autohaus
-[LOVE2_D]
-Daraus sollte man Kapital schlagen.
+[STPR_6]
+Taxiunternehmen
-[LOVE2_E]
-Ich möchte, dass du dir den Yakuza WAKA-Gashira Kenji Kasen vornimmst.
+[STPR_7]
+Bootswerft
-[LOVE2_F]
-Kenji ist bei einem Treffen auf dem Dach der Parkgarage in Newport.
+[SET1EN]
+Konfig. 1 aktiviert
-[LOVE2_G]
-Besorg dir einen Wagen des Kartells und nimm ihn dir vor.
+[GMSAVE]
+Spiel speichern
-[LOVE2_H]
-Die Yakuza werden das als Kriegserklãrung des Kartells auffassen.
+[FEDS_TB]
+Zurück
-[LOVE2_1]
-~g~Klau in Fort Staunton einen Wagen der kolumbianischen Gang!
+[FEST_OO]
+von
-[LOVE2_2]
-~g~Fahre jetzt zu dem ~p~Parkhaus in Newport~g~ und zieh Kenji aus dem Verkehr!
+[FEC_TUC]
+Geschützsteuerung
-[LOVE2_3]
-~r~Wenn du nicht mit einem Auto des Kartells aufkreuzt, wird man dich erkennen!
+[FEC_RS3]
+Radiosender auswãhlen (L3-Taste)
-[LOVE2_4]
-~r~Die Yakuza haben dich erkannt!
+[FEC_HO3]
+Hupe (L3-Taste)
-[LOVE2_6]
-~r~ Du hast alle Zeugen aus dem Weg gerãumt!!
+[C_FAIL]
+Bürgerwehr-Mission beendet!
-[LOVE3_A]
-In scheinheiligen Zeiten wie diesen sind bestimmte wertvolle Waren schwer zu importieren.
+[C_ESCP]
+~r~Der Verdãchtige ist entwischt!
-[LOVE3_C]
-Es wird einige kleine Pãckchen ins Wasser abwerfen.
+[C_VIGIL]
+BÜRGERWEHR BONUS!!
-[LOVE3_D]
-Sammle sie ein, bevor es ein anderer tut.
+[HEAL_A]
+Dein ~h~Gesundheitszustand~w~ wird rechts oben auf dem Bildschirm in Orange angezeigt.
-[LOVE3_1]
-~g~Besorg dir ein ~r~Boot~g~ und folge dem ~y~Flugzeug~g~!
+[WRONGCD]
+Falsche DVD. Bitte legen Sie die richtige DVD ein.
-[LOVE4]
-'DER FLUGHAFEN-COUP'
+[NOCD]
+Die DVD-Lade ist leer. Bitte DVD einlegen.
-[LOVE5]
-'BODYGUARD ACTION'
+[OPENCD]
+Die DVD-Lade ist offen. Bitte schließen.
-[LOVE4_A]
-Danke, dass du die Pãckchen geholt hast. Aber die sollten nur als Köder dienen.
+[CDERROR]
+Fehler beim Lesen der 'Grand Theft Auto: Vice City' DVD.
-[LOVE4_B]
-Sorry, aber so lãuft das manchmal in dem Geschãft.
+[RESTART]
+Neues Spiel wird gestartet
-[LOVE4_C]
-Die Ware, um die es mir wirklich geht, ist noch in dem Flugzeug versteckt.
+[GA_3]
+Keine Gratisjobs mehr. Umspritzen kostet $100!
-[LOVE4_F]
-Ich habe die Beamten bestochen.
+[GA_1]
+Hey, so was heißes rühre ich nicht an!
-[LOVE4_1]
-~r~Das kolumbianische Kartell ist da!!
+[GA_1A]
+Komm wieder, wenn du nicht so viel zu tun hast...
-[LOVE4_2]
-~g~Das Pãckchen ist weg! Du musst die Kolumbianer finden und es ihnen abjagen.
+[HELP9_C]
+Drücke die~h~ ~k~~PED_FIREWEAPON~~w~, um das Prãzisionsgewehr ~h~abzufeuern~w~.
-[LOVE4_3]
-~g~Bauunternehmen Panlantic...?
+[TAXI2]
+~r~Die Zeit ist um!
-[LOVE4_5]
-~g~Das Pãckchen müsste im Flugzeug sein...
+[PAGEB13]
+Gesundheits-Powerups in Versteck angeliefert.
-[LOVE4_6]
-~g~Nimm den Lift nach oben in den Tower!
+[PAGEB14]
+Adrenalin in Versteck vorrãtig.
-[LOVE5_B]
-Mein asiatischer Freund braucht einen Bodyguard. Er lãsst meine neue Lieferung auf Qualitãt überprüfen.
+[FESZ_CA]
+Abbrechen
-[LOVE5_1]
-~g~Los!
+[FES_NGA]
+Neues Spiel
-[LOVE5_2]
-~g~Du wirst ein Auto brauchen!
+[FES_CAN]
+Abbrechen
-[LOVE5_3]
-~g~Los, sieh nach, ob am Tunnelende die Luft rein ist.
+[FESZ_QL]
+Alle nicht gespeicherten Daten des aktuellen Spiels werden verloren gehen. Ladevorgang fortsetzen?
-[LOVE5_4]
-~r~Dem Truck darf nichts passieren!
+[FESZ_QD]
+Dieses gespeicherte Spiel wirklich löschen?
-[RM6]
-'IM FADENKREUZ'
+[FESZ_QO]
+Dieses gespeicherte Spiel wirklich überschreiben?
-[RM6_A]
-Dir ist niemand gefolgt? Gut.
+[FESZ_QR]
+Wirklich ein neues Spiel beginnen? Alle Daten seit dem letzten Speichern werden verloren gehen. Weiter?
-[RM6_B]
-Es wird langsam brenzlig, ich stecke bis zum Hals in der Scheiße!
+[T4X4_1]
+'PCJ Rallye'
-[RM6_D]
-Die haben mich im Visier, ich muss mich absetzen.
+[BMX_1]
+'Krasses Gelãnde'
-[RM6_E]
-Wenn du mich rechtzeitig zum Flughafen bringst, lass ich ordentlich was springen.
+[BMX_2]
+'Teststrecke'
-[RM6_666]
-Pass gut auf meinen kugelsicheren Patriot auf, Ray. Wir sehen uns in Miami.
+[BMXFAIL]
+~r~Du hast es nicht geschafft, einen neuen Rekord aufzustellen!
-[CAT1]
-'LÖSEGELD'
+[BMX_REC]
+~g~Neuer Rekord:~1~ !!
-[CAT2]
-'DIE ÜBERGABE'
+[T4X4_3]
+'CHECKPOINT FIEBER'
-[CAT1_A]
-Ich habe deine Maria. Wenn ihr Gesicht nicht aussehen soll, als wãr's in einen Fleischwolf geraten,
+[MM_1]
+'PYLONEN-RALLYE'
-[CAT2_F]
-Ich hab mir 'nen Fingernagel abgebrochen und meine Frisur ist hin! Fünfzig Dollar im Eimer!
+[T4X4_F]
+~r~Du hast gekniffen! Schon überfordert?
-[CAT2_G]
-Mann, hatte ich Angst. Aber dann dachte ich mir, du bist doch kein kleines Mãdchen mehr.
+[LANDSTK]
+Landstalker
-[CAT2_H]
-Du, das wird lustig, weißt du, meine Schwester will nãmlich mit ihren zwei Kindern eine zeitlang bei uns wohnen,
+[IDAHO]
+Idaho
-[CAT2_I]
-weil ihr Mann gerade mal wieder fremdgeht und...
+[STINGER]
+Stinger
-[CAT1_C]
-XXXX
+[LINERUN]
+Linerunner
-[CAT1_D]
-XXXX
+[PEREN]
+Perennial
-[CAT1_E]
-XXXX
+[SENTINL]
+Sentinel
-[CAT1_F]
-Du musst rechtzeitig bei Catalina sein!
+[RIO]
+Rio
-[CAT1_G]
-XXXX
+[PATRIOT]
+Patriot
-[CAT1_H]
-XXXX
+[FIRETRK]
+Feuerwehrwagen
-[CAT1_I]
-XXXX
+[TRASHM]
+Trashmaster
-[CAT1_J]
-XXXX
+[STRETCH]
+Stretch Limo
-[CAT1_K]
-XXXX
+[MANANA]
+Manana
-[CAT1_L]
-XXXX
+[INFERNS]
+Infernus
-[AS4_1]
-XXXX
+[VOODOO]
+Voodoo
-[CAT_MON]
-~g~Du hast noch nicht genug Geld. Du brauchst $500.000.
+[PONY]
+Pony
-[BITCH_D]
-~g~Maria ist tot!
+[MULE]
+Mule
-[WEATHER]
-WETTER ÃNDERN
+[CHEETAH]
+Cheetah
-[WEATHE2]
-WETTER NORMAL
+[AMBULAN]
+Krankenwagen
-[8001]
-Du hast komplett versagt!
+[FBICAR]
+FBI Washington
-[1000]
-DU BIST TOT
+[MOONBM]
+Moonbeam
-[1001]
-DU BIST TOT
+[ESPERAN]
+Esperanto
-[1002]
-DU BIST TOT
+[TAXI]
+Taxi
-[1003]
-DU BIST TOT
+[WASHING]
+Washington
-[1004]
-DU BIST TOT
+[BOBCAT]
+Bobcat
-[1005]
-VERHAFTET
+[WHOOPEE]
+Mr Whoopee
-[1006]
-VERHAFTET
+[BFINJC]
+BF Injection
-[1007]
-VERHAFTET
+[HUNTER]
+Hunter
-[1008]
-VERHAFTET
+[POLICAR]
+Polizei
-[1009]
-VERHAFTET
+[ENFORCR]
+Enforcer
-[GA_4]
-Autobomben kosten $1000 pro Stück.
+[SECURI]
+Securicar
-[GA_5]
-In deinem Wagen ist schon eine Autobombe.
+[BANSHEE]
+Banshee
-[GA_6]
-Park die Karre, mach sie durch Drücken der ~h~~k~~PED_FIREWEAPON~-Taste~w~ scharf, und dann nichts wie weg!
+[PREDATR]
+Predator
-[GA_7]
-Mach die Bombe mit der ~h~~k~~PED_FIREWEAPON~-Taste~w~ scharf. Dann geht sie hoch, wenn der Wagen angelassen wird.
+[BUS]
+Bus
-[GA_8]
-Benutze den Zünder, um die Bombe hochgehen zu lassen.
+[RHINO]
+Rhino
-[GA_9]
-Du hast ~1~ von zehn Spezialautos beschafft.
+[BARRCKS]
+Barracks OL
-[GA_10]
-Hübsche Karre. Hier sind deine $~1~.
+[CUBAN]
+Kubanischer Hermes
-[GA_11]
-So eine Karre haben wir schon. Die können wir nicht gebrauchen.
+[HELI]
+Helikopter
-[GA_12]
-Bombe ist scharf.
+[DODO]
+Dodo
-[GA_13]
-Auf dich ist Verlass. Wenn du alle, die auf der Liste stehen, abgeliefert hast, kriegst du einen Bonus.
+[COACH]
+Coach
-[GA_14]
-Du hast alle georderten Karren geliefert. Sehr gut. Hier, für dich.
+[CABBIE]
+Cabbie
-[GA_15]
-Hoffentlich gefãllt dir die neue Farbe.
+[STALION]
+Stallion
-[GA_16]
-Das Umspritzen ist gratis.
+[RUMPO]
+Rumpo
-[GA_19]
-An dem Modell haben wir kein Interesse.
+[RCBANDT]
+RC Bandit
-[GA_20]
-Von der Sorte haben wir schon mehr als genug. Sorry, da kommen wir nicht ins Geschãft.
+[ROMERO]
+Romeros Leichenwagen
-[CR_1]
-Kran kann dieses Fahrzeug nicht anheben.
+[PACKER]
+Packer
-[PU_MONY]
-Du hast nicht genug Geld.
+[ADMIRAL]
+Admiral
-[CO_ALL]
-Du hast sie alle geliefert. Hier, für dich.
+[SQUALO]
+Squalo
-[PAUSED]
-PAUSE
+[SEASPAR]
+Sea Sparrow
-[HEALTH1]
-Stell dich nicht so an! Dir fehlt doch überhaupt nichts.
+[PIZZABO]
+Pizza Boy
-[HEALTH2]
-Medizinische Versorgung ist teuer.
+[GANGBUR]
+Gang Burrito
-[HEALTH3]
-Ich flick dich wieder zusammen.
+[TROPIC]
+Tropic
-[HEALTH4]
-Das macht $250.
+[SPEEDER]
+Speeder
-[FEB_STA]
-Statistik
+[REEFER]
+Reefer
-[FEB_BRI]
-Mission
+[FLATBED]
+Flatbed
-[FEB_CON]
-Steuerung
+[YANKEE]
+Yankee
-[FEB_AUD]
-Audio
+[CADDY]
+Caddy
-[FEB_DIS]
-Anzeige
+[ZEBRA]
+Zebra Cab
-[FEB_LAN]
-Sprache
+[TOPFUN]
+Top Fun
-[FEP_STA]
-STATISTIKEN
+[SKIMMER]
+Skimmer
-[FEP_BRI]
-MISSIONSINFOS
+[PCJ600]
+PCJ 600
-[FEP_CON]
-STEUERUNG
+[PHOENIX]
+Phoenix
-[FEP_AUD]
-AUDIO
+[FAGGIO]
+Faggio
-[FEP_DIS]
-ANZEIGE
+[FREEWAY]
+Freeway
-[FEP_LAN]
-SPRACHE
+[RCBARON]
+RC Baron
-[FEF_ST1]
-Wer ist der Schurke?
+[RCRAIDE]
+RC Raider
-[FEF_ST2]
-Wie viel Chaos hast du angerichtet?
+[GLENDAL]
+Glendale
-[FEF_BR1]
-Du blickst bei der Story nicht mehr durch?
+[OCEANIC]
+Oceanic
-[FEF_CO1]
-Taste dich ran, Mann!
+[SANCHEZ]
+Sanchez
-[FEF_CO2]
-Wãhle das Controller-Setup, das zu deinem Spielstil am besten passt
+[SPARROW]
+Sparrow
-[FEF_SA1]
-Bring deine Daten in Sicherheit!
+[LOVEFIS]
+Love Fist
-[FEF_SA2]
-Spiele laden und speichern
+[COASTG]
+Küstenwache
-[FEF_AU1]
-Volle Dröhnung gefãllig?
+[DINGHY]
+Dinghy
-[FEF_AU2]
-Radiosender und Soundeffekt auswãhlen
+[HERMES]
+Hermes
-[FEF_DI1]
-Andere Optik?
+[SABRE]
+Sabre
-[FEF_DI2]
-Spiel für deinen Fernseher optimieren
+[SABRETU]
+Sabre Turbo
-[FEF_LA1]
-Was für ein Gefasel!
+[WALTON]
+Walton
-[FEF_LA2]
-Sprache auswãhlen
+[REGINA]
+Regina
-[FEB_PMB]
-Vorherige Missionsinfos:
+[COMET]
+Comet
-[FEC_NA]
-Nicht verfügbar
+[DELUXO]
+Deluxo
-[FEC_CWL]
-Eine Waffe nach links
+[BURRITO]
+Burrito
-[FEC_CWR]
-Eine Waffe nach rechts
+[SPAND]
+Spandex Express
-[FEC_LOF]
-Nach vorne schauen
+[MARQUIS]
+Marquis
-[FEC_TAR]
-Zielen
+[BAGGAGE]
+Baggage Handler
-[FEC_MOV]
-Bewegung
+[KAUFMAN]
+Kaufman-Taxi
-[FEC_CAM]
-Blickwinkel
+[COASTMA]
+Küstenwachen-Maverick
-[FEC_PAU]
-Pause
+[MAVERIC]
+Maverick
-[FEC_ENV]
-In Fahrzeug einsteigen
+[RANCHER]
+Rancher
-[FEC_JUM]
-Springen
+[FBIRANC]
+FBI Rancher
-[FEC_ATT]
-Angreifen\Waffe abfeuern
+[VIRGO]
+Virgo
-[FEC_RUN]
-Rennen
+[GREENWO]
+Greenwood
-[FEC_FPC]
-Subjektive Kamera
+[HOTRING]
+Hotring Racer
-[FEC_LB1]
-Schau
+[BLISTAC]
+Blista Compact
-[FEC_LL]
-Nach links schauen
+[FEST_DF]
+Zu Fuß zurückgel. Strecke (Meilen)
-[FEC_LB2]
-nach hinten
+[FEST_DC]
+Mit Auto gefahrene Strecke (Meilen)
-[FEC_LB]
-Nach hinten schauen
+[FESTDFM]
+Zu Fuß zurückgelegte Strecke (Meter)
-[FEC_LR]
-Nach rechts schauen
+[FESTDCM]
+Mit Auto gefahrene Strecke (Meter)
-[FEC_HOR]
-Hupe
+[TOT_DIS]
+Insgesamt zurückgel. Strecke (Meilen)
-[FEC_VES]
-Fahrzeug steuern
+[TOTDISM]
+Insgesamt zurückgel. Strecke (Meter)
-[FEC_RSC]
-Radiosender auswãhlen
+[DISTHEL]
+Mit Helikopter geflogene Strecke (Meilen)
-[FEC_BRA]
-Bremsen\rückwãrts fahren
+[DISTHEM]
+Mit Helikopter geflogene Strecke (Meter)
-[FEC_HAB]
-Handbremse
+[DISTBOA]
+Mit Boot zurückgel. Strecke (Meilen)
-[FEC_CAW]
-Fahrzeugwaffe
+[DISTBOM]
+Mit Boot zurückgel. Strecke (Meter)
-[FEC_ACC]
-Beschleunigen
+[FEST_LS]
+Mit Krankenwagen gerettete Menschen
-[FEC_SMT]
-Spezialmission aktivieren
+[FEST_CC]
+Kriminelle bei Bürgerwehr-Mission
-[FEC_CCF]
-Konfiguration:
+[FEST_FE]
+Gelöschte Feuer gesamt
-[FEC_CF1]
-Konfig1
+[FEST_RP]
+Bestandene Amokfahrten
-[FEC_CF2]
-Konfig2
+[FEST_MP]
+Erledigte Missionen
-[FEC_CF3]
-Konfig3
+[FEST_BB]
+Schnelle Autos, Schnelles Geld:
-[FEC_CF4]
-Konfig4
+[FEST_H0]
+Meiste Checkpoints
-[FEC_CDP]
-Controller-Anzeige:
+[FEST_GC]
+Geschrottete Gang-Autos:
-[FEC_ONF]
-Zu Fuß
+[FEST_H1]
+Im Dschungel der Diablos
-[FEC_INC]
-Im Auto
+[FEST_H2]
+Mafia-Massaker
-[FEC_VIB]
-Vibration:
+[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]
+Drücke die ~h~~k~~PED_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]
-Park die Karre, mach sie durch Drücken der ~h~~k~~PED_FIREWEAPON~-Taste~w~ scharf, und dann HAU AB!
+[CRED230]
+SPECIAL THANKS TO
-[GA_7B]
-Mach die Bombe mit der ~h~~k~~PED_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]
-Drücke die~h~ ~k~~PED_FIREWEAPON~-Taste~w~ zum ~h~Zünden der Bombe~w~. Aber geh vorher in Deckung!
+[CHEAT6]
+Geld-Cheat
-[KM1_8D]
-Drücke die~h~ ~k~~PED_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]
-Halt eine Uzi im Anschlag, wenn du in ein Fahrzeug steigst. Schau dann nach links oder rechts und drücke die ~h~~k~~PED_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]
-Halt eine Uzi im Anschlag, wenn du in ein Fahrzeug steigst. Schau dann nach links oder rechts und drücke die ~h~~k~~PED_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]
-Drücke die ~k~~PED_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]
-Drücke die ~k~~PED_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]
-Drücke die ~h~~k~~PED_FIREWEAPON~-Taste~w~, um die Bordkanonen abzufeuern.
+[RBM2_6]
+~g~Wow! Die ist 'n Kerl! Halt ihn auf!
-[PBOAT_2]
-Drücke die ~h~~k~~PED_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]
-Zerstöre die gepanzerten Fahrzeuge mit den Buggies. Zur Zündung drücke die ~h~~k~~PED_FIREWEAPON~-Taste~w~.
+[CUBAN1]
+KUBA-MISSION 1
-[HM2_1A]
-Zerstöre die gepanzerten Fahrzeuge mit den Buggies. Zur Zündung drücke die ~h~~k~~PED_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]
+Park die Karre, mach sie durch Drücken der ~h~~k~~PED_FIREWEAPON~~w~ scharf und dann HAU AB!
-[CRED230]
-SPECIAL THANKS TO
+[GA_7]
+Mach die Bombe mit der ~h~~k~~PED_FIREWEAPON~~w~ scharf. Dann geht sie hoch, wenn der Wagen angelassen wird.
-[CRED231]
-ADAM TEDMAN
+[GA_6B]
+Park die Karre, mach sie durch Drücken der ~h~~k~~PED_FIREWEAPON~~w~ scharf und dann HAU AB!
-[CRED232]
-ALEX MASON
+[GA_7B]
+Mach die Bombe mit der ~h~~k~~PED_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]
+Drücke die~h~ ~k~~PED_FIREWEAPON~~w~, um die Bordkanonen abzufeuern.
-[RM6_6]
-~r~Ray ist tot!
+[SEG3_4]
+~g~Um Bomben aufzunehmen, steuere den RC Raider einfach nahe an sie heran. Um eine abzuwerfen, drücke die ~o~|-Taste.
-[RM6_7]
-~r~Ray hat seinen Flug verpasst.
+[RCR1_3]
+~g~Wenn du diese Mission abbrechen willst, drücke die ~h~~k~~PED_FIREWEAPON~~g~, um dein Auto zu sprengen.
-[RM6_8]
-~g~Du hast Ray zurückgelassen. Kehr um und hol ihn.
+[HELP32]
+Dann feuere mit der ~h~~k~~PED_FIREWEAPON~.
-[FM1_10]
-~g~Du hast Maria zurückgelassen. Kehr um und hol sie.
+[HELP33]
+Dann feuere mit der ~h~~k~~PED_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]
+Drück die ~h~~k~~VEHICLE_ENTER_EXIT~~w~, um die augenblickliche Waffe in diesem Slot auszutauschen.
-[MEA4_D]
-Ich habe ein Treffen mit ihm vereinbart...
+[PU_CF4]
+Drück die ~h~~k~~VEHICLE_ENTER_EXIT~~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]
-~h~~k~~PED_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]
-~h~~k~~PED_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]
+Benutze die ~h~~k~~VEHICLE_ACCELERATE~~w~-Taste, um zu beschleunigen. 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ß
@@ -7129,81 +7129,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ü
@@ -7249,41 +7174,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
-[FEM_QTW]
-Beenden
+[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
+
+[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?
@@ -7291,737 +7384,7178 @@ 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
+
+[REPLAY]
+WIEDERHOLUNG
+
+[FET_PAU]
+PAUSENMENÜ
+
+[FEC_ANS]
+Aktion
+
+[CVT_MSG]
+Texturen werden in optimales Format für Ihre Grafikkarte konvertiert
+
+[FEC_SFT]
+UMSCHALT
+
+[CVT_ERR]
+Kein Platz mehr auf der Festplatte. Bitte schaffen Sie Speicherplatz, bevor Sie fortfahren. ESC zum Abbrechen.
+
+[FEH_VMP]
+KARTE ANSEHEN
+
+[FES_DEE]
+Löschen fehlgeschlagen! Bitte noch einmal versuchen.
-[FEG_PLY]
-SPIELER
+[FES_CMP]
+Speichern fehlgeschlagen! Bitte noch einmal versuchen.
-[FEG_TYP]
-TYP
+[FESZ_WR]
+Spiel wird gespeichert. Bitte warten...
-[FEG_PNG]
-PING
+[FELD_WR]
+Spiel wird geladen. Bitte warten...
-[FET_FG]
-SPIEL SUCHEN
+[FEDL_WR]
+Gespeichertes Spiel wird gelöscht. Bitte warten...
-[FET_SP]
-SINGLEPLAYER
+[PCRESRT]
+Neues Spiel wird gestartet. Bitte warten...
-[FET_MP]
-MULTIPLAYER
+[FET_STI]
+Standard-Steuerung
-[FET_HG]
-SPIEL HOSTEN
+[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_GFX]
-GRAFIK-SETUP
+[FEA_MP3]
+MP3 PLAYER
-[FET_DIS]
-ANZEIGEN-SETUP
+[NO_PCCD]
+Bitte legen Sie die GTA Vice City Disk ein, oder drücken Sie ESC zum Abbrechen
-[FET_LAN]
-SPRACHEN-SETUP
+[FEH_SSA]
+CURSOR ZUM BEWEGEN - S UM ZU SPEICHERN
-[FET_LG]
-SPIEL LADEN
+[FES_CMI]
+LETZTE ERFÜLLTE MISSION
-[FET_DG]
-SPIEL LÖSCHEN
+[FET_STS]
+STATISTIKEN GESPEICHERT IN 'STATS.HTML' + 'STATS.TXT'
-[FET_NG]
-NEUES SPIEL
+[WIN_VDM]
+Nicht genug verfügbarer Grafikspeicher für GTA Vice City vorhanden
-[FET_SG]
-SPIEL SPEICHERN
+[FEC_ERI]
+Fehler! Eine oder mehrere Aktionen haben keine Tastenbelegungen. Bitte alle Aktionen belegen.
-[FET_MAP]
-KARTE AUSWÃHLEN
+[FEC_TFU]
+Geschütz + nach hinten neigen
-[FET_GT]
-SPIEL-TYP
+[FEC_TFD]
+Geschütz + nach vorne neigen
-[FET_CTL]
-CONTROLLER-SETUP
+[FET_RIG]
+WÃHLEN SIE EINE NEUE TASTENBELEGUNG FÜR DIESE AKTION
-[FET_OPT]
-OPTIONEN
+[FEA_NM3]
+KEINE MP3-DATEIEN GEFUNDEN
-[FET_QG]
-SPIEL BEENDEN
+[FEA_MPB]
+MP3 LAUTSTÃRKE-BOOST
-[FET_STA]
-STATISTIK
+[FEA_MUS]
+LAUTSTÃRKE MUSIK
-[FET_BRE]
-MISSIONSINFOS
+[FEA_SFX]
+LAUTSTÃRKE SFX
-[FEC_WAR]
-Achtung!
+[FEA_ADP]
+AUTOMATISCHE HARDWARE ERKENNUNG
-[FEC_OKK]
-OK
+{=================================== MISSION TABLE AMBULAE ===================================}
-[FED_CON]
-Löschen bestãtigen
+[A_COMP1:AMBULAE]
+Krankenwagen-Missionen abgeschlossen: $ ~1~
-[FES_SSC]
-Spiel wurde gespeichert.
+[ATUTOR2:AMBULAE]
+~g~Fahre die Patienten VORSICHTIG in die Klinik. Jede Erschütterung verringert ihre Überlebenschancen.
-[DEL_FNM]
-Datei wurde gelöscht.
+[A_FULL:AMBULAE]
+~r~Krankenwagen voll!!
-[PCLOAD]
-Datei wird geladen
+[A_FAIL2:AMBULAE]
+~r~Deine Bummelei war tödlich für den Patienten!
-[PCRESRT]
-GTA 3 wird neu gestartet
+[A_FAIL3:AMBULAE]
+~r~Der Patient ist tot!!
-[FEC_DLF]
-Löschen fehlgeschlagen.
+[A_PASS:AMBULAE]
+Gerettet!
-[FEC_SVU]
-Speichern fehlgeschlagen.
+[A_COMP2:AMBULAE]
+Du ermüdest nie!
-[FEC_LUN]
-Laden fehlgeschlagen. Datei beschãdigt. Bitte löschen.
+[A_CANC:AMBULAE]
+~r~Krankenwagen-Mission abgebrochen!
-[FEN_PLA]
-Anzahl der Spieler:
+[A_COMP3:AMBULAE]
+Krankenwagen-Missionen abgeschlossen! Du wirst beim Rennen nie ermüden!
-[FET_NON]
-KEINE SPIELE VERFÜGBAR
+[ALEVEL:AMBULAE]
+Krankenwagen-Mission Level ~1~
-[FET_SFG]
-SPIELE WERDEN GESUCHT...
+[A_FAIL1:AMBULAE]
+Krankenwagen-Mission beendet.
-[FET_SRT]
-SPIELE WERDEN SORTIERT...
+[A_SAVES:AMBULAE]
+GERETTETE MENSCHEN: ~1~
-[FEF_LAN]
-LAN
+{=================================== MISSION TABLE ASSIN1 ===================================}
-[FEF_INT]
-INTERNET
+[ASM1_5:ASSIN1]
+~r~Er hat seine Lieferungen abgeschlossen!
-[FET_REF]
-Aktualisieren
+[ASM1_6:ASSIN1]
+Weitere Lieferungen:
-[FET_FIL]
-Filter
+[ASM1_7:ASSIN1]
+~g~Carl Pearson, Pizza-Lieferant. Schalte ihn aus, bevor er seine Lieferungen abschließt.
-[FET_JG]
-Beitreten
+[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_NTW]
-Talk To Network
+[ASM1_D:ASSIN1]
+Mr. Teal, Ihre Hilfe bei der Beseitigung der Landeier war ãußerst wertvoll.
-[FEC_ESR]
-Esc-Taste nicht zugelassen
+{=================================== MISSION TABLE ASSIN2 ===================================}
-[FEC_GSL]
-Show head bob:
+[ASM2_1:ASSIN2]
+~g~Mrs. Dawson verlãsst bald den Juwelier in Vice Point. Schalte sie aus. Es muss wie ein Autounfall aussehen.
-[FIL_FLT]
-SPIELE-LISTE FILTERN
+[ASM2_3:ASSIN2]
+~g~Das Fahrzeug wird explodieren! Hau ab!
-[FET_SAN]
-NEUES SPIEL STARTEN
+[ASM2_4:ASSIN2]
+~r~Du hast ihr Auto beschãdigt, obwohl sie nicht drin saß! Jetzt wird sie nicht einsteigen!
-[FIL_MAP]
-Karte:
+[ASM2_5:ASSIN2]
+~r~Sie ist entwischt!
-[FIL_SRV]
-Server:
+[ASM2_6:ASSIN2]
+~r~Du warst zu nah am Unfallort!
-[FIL_TYP]
-Spiel-Typ
+[ASM2_7:ASSIN2]
+~g~Keine Waffen! Es soll wie ein Unfall aussehen! Drãnge sie stattdessen von der Fahrbahn!
-[FIL_SPC]
-Offene Spiele?
+[ASM2_8:ASSIN2]
+~g~Das ganze muss wie ein Unfall aussehen. Benutze keine Waffen.
-[FIL_PNG]
-Ping:
+[ASM2_9:ASSIN2]
+Du brauchst einen fahrbaren Untersatz für diesen Job.
-[FEN_UKH]
-Unbekannter Host
+[ASM2_10:ASSIN2]
+~g~Wenn ihr Auto in Flammen aufgeht, entferne dich so weit wie möglich von der Unfallstelle.
-[FEN_UKM]
-Map nicht gefunden
+[ASM2_11:ASSIN2]
+Hilfe!
-[FEN_UKT]
-Spiel-Typ nicht gefunden
+[ASM2_12:ASSIN2]
+Hilf mir doch jemand!
-[FEN_NCI]
-KEINE INTERNET-VERBINDUNG
+[ASM2_13:ASSIN2]
+Oh Gott!
-[FET_PAU]
-PAUSENMENÜ
+[ASM2_A:ASSIN2]
+Mein Kompliment für die gute Arbeit, Mr. Teal. Mein Kunde war sehr zufrieden.
-[FET_SGA]
-SPIEL STARTEN
+[ASM2_2:ASSIN2]
+Health:
-[FEC_PAD]
-Gamepad
+{=================================== MISSION TABLE ASSIN3 ===================================}
-[FEC_JOY]
-Joystick
+[ASM3_11:ASSIN3]
+ZEIT:
-[FEC_WHL]
-Lenkrad
+[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.
-[FEC_CNT]
-Controller-Typ:
+[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.
-[FET_APL]
-ÜBERNEHMEN
+[ASM3_E:ASSIN3]
+Infos über alle Zielpersonen und ihre wahrscheinlichen Aufenthaltsorte kleben unter dem Telefon.
-[FES_CSA]
-Wãhlen Sie eine Skin aus der Liste aus:
+[ASM3_14:ASSIN3]
+~g~Dick Tanner hãlt sich bei DBP Security am Ocean Drive auf.
-[FES_SKN]
-SKIN-NAME
+[ASM3_15:ASSIN3]
+~g~Marc Hammond und Franco Carter halten sich in der Nãhe des Juwelierladens in Vice Point auf.
-[FES_DAT]
-DATUM
+[ASM3_16:ASSIN3]
+~g~Nick Kong hãlt sich in der Nãhe von Washington Beach auf.
-[FES_NON]
-KEINE SKINS VERFÜGBAR
+[ASM3_18:ASSIN3]
+~g~Geh nicht zu nahe an deine Zielperson heran, sonst entdeckt sie dich und du musst hinter ihr herjagen.
-[FEA_FM9]
-SPIELER MP3
+[ASM3_19:ASSIN3]
+~g~Er hat dich gesehen! Schalte ihn aus!
-[FESZ_QZ]
-Dieses Spiel wirklich speichern?
+[ASM3_20:ASSIN3]
+~g~Sie haben dich gesehen! Schalte alle beide aus!
-[FES_CGA]
-Momentan verfügbare Speicherplãtze:
+[ASM3_21:ASSIN3]
+~r~Du hast nicht alle Mitglieder der Gang rechtzeitig erledigt!
-[FES_SCG]
-Laufendes Spiel speichern?
+[ASM3_22:ASSIN3]
+~g~Geh nicht zu nahe an deine Zielpersonen heran, sonst entdecken sie dich und versuchen zu fliehen.
-[FES_LCG]
-Spiel laden und weiterspielen?
+[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_FIR]
-Feuern
+[ASM3_13:ASSIN3]
+~g~Mike Griffin arbeitet an einer Plakatwand in Washington.
-[FEC_NWE]
-Nãchste Waffe
+[ASM3_17:ASSIN3]
+~g~Charlie Dilson fãhrt mit dem Motorrad in Washington herum.
-[FEC_PWE]
-Vorherige Waffe
+{=================================== MISSION TABLE ASSIN4 ===================================}
-[FEC_FOR]
-Vorwãrts
+[ASM4_10:ASSIN4]
+~g~Du warst anscheinend nicht der einzige, der hinter dem Aktenkoffer her war. Bring ihn schnell ins Ammu-Nation!
-[FEC_BAC]
-Rückwãrts
+[ASM4_12:ASSIN4]
+Distanz:
-[FEC_LEF]
-Links
+[ASM4_15:ASSIN4]
+~g~Nimm das Prãzisionsgewehr zu deiner Rechten.
-[FEC_RIG]
-Rechts
+[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_ZIN]
-Heranzoomen
+[ASM4_17:ASSIN4]
+~g~Schalte die Zielperson aus, NACHDEM die Frau mit ihr gesprochen hat. Aber erledige nicht die Frau.
-[FEC_ZOT]
-Herauszoomen
+[ASM4_18:ASSIN4]
+~g~Wenn die Zielperson ausgeschaltet ist, nimm ihren Aktenkoffer und bringe ihn zum Ammu-Nation in Downtown.
-[FEC_EEX]
-Ein-/Aussteigen
+[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_RAD]
-Radio
+[ASM4_20:ASSIN4]
+~g~Lass den Anzeigebalken nicht an den Anschlag geraten, sonst sieht dich die Zielperson.
-[FEC_SUB]
-Spezialmission
+[ASM4_21:ASSIN4]
+~g~Schnapp dir den Aktenkoffer!
-[FEC_CMR]
-Blickwinkel ãndern
+[ASM4_22:ASSIN4]
+~g~Bring den Aktenkoffer zum Ammu-Nation in Downtown.
-[FEC_JMP]
-Springen
+[ASM4_23:ASSIN4]
+~g~Er hat dich entdeckt und versucht zu fliehen. Erledige ihn und schnapp dir den Aktenkoffer!
-[FEC_SPN]
-Sprinten
+[ASM4_25:ASSIN4]
+~r~Du hast die Frau ausgeschaltet, du Idiot!
-[FEC_HND]
-Handbremse
+[ASM4_26:ASSIN4]
+~r~Die Zielperson hat das Flugzeug bestiegen!
-[FEC_TUL]
-Geschütz links
+[ASM4_27:ASSIN4]
+~r~Die Zielperson hat dich gesehen! Du hãttest Abstand halten sollen!
-[FEC_TUR]
-Geschütz rechts
+[ASM4_28:ASSIN4]
+~r~Die Zielperson hat dich gesehen! Er hat gehört, wie du geschossen hast!
-[FEC_LOL]
-Nach links schauen
+[ASM4_29:ASSIN4]
+~r~Schalte ihn erst aus, wenn er mit der Frau gesprochen hat!
-[FEC_LOR]
-Nach rechts schauen
+[ASM4_A:ASSIN4]
+Es wird Zeit für dickere Brocken, Mr. Teal. Unter dem Busch zu Ihrer Rechten ist ein Gewehr.
-[FEC_NTR]
-Nãchstes 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_PTT]
-Vorheriges Ziel
+[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_LBA]
-Nach hinten schauen
+{=================================== MISSION TABLE ASSIN5 ===================================}
-[FEC_CEN]
-Kamera zentrieren
+[ASM5_A:ASSIN5]
+Auf dem Dach der Cherry Popper-Eiscremefabrik findet eine Übergabe von wertvoller Ware statt.
-[FEC_UND]
-(NEIN)
+[ASM5_B:ASSIN5]
+Erledigen Sie alle Beteiligten, klauen Sie die Ware und bringen Sie sie zum Heliport am Flughafen.
-[FET_CFT]
-ZU FUSS
+[ASM5_C:ASSIN5]
+Links von Ihnen ist ein Tor, das zur Rückseite der Fabrik führt.
-[FET_CCR]
-IN FAHRZEUG
+[ASM5_1:ASSIN5]
+~g~Geh auf das Gelãnde hinter der Cherry Popper-Eiscremefabrik und dann auf das Dach, wo der Deal abgewickelt wird.
-[CVT_MSG]
-Texturen werden in optimales Format für Ihre Grafikkarte konvertiert
+[ASM5_2:ASSIN5]
+~g~Schnapp dir die Ware und bring sie zum Heliport am Flughafen.
-[FET_CAC]
-AKTION
+[ASM5_3:ASSIN5]
+~g~Bring die Ware zum Heliport am Flughafen!
-[FEC_IBT]
--
+{=================================== MISSION TABLE BANKJ1 ===================================}
-[FEC_SPC]
-LEERT.
+[WANTED1:BANKJ1]
+~g~Schüttle die Cops ab. Verringere deinen Fahndungslevel.
-[FEC_MXO]
-MXB1
+[BJM1_A:BANKJ1]
+Tommy! Hey, Tommy, sieh mal, das ist super! Ich hab eine Minibar einbauen lassen!
-[FEC_MXT]
-MXB2
+[BJM1_B:BANKJ1]
+Wir haben unten eine ausgewachsene Bar, Ken.
-[FEC_UNB]
-NICHT BEL.
+[BJM1_C:BANKJ1]
+Ja, ja, wie auch immer. Tja, ich hab die Tafel besorgt, die du haben wolltest.
-[FET_CME]
-STEUERUNGSART
+[BJM1_D:BANKJ1]
+Ah, das ist der Lohn des Jurastudiums: Die Fãhigkeit, Anweisungen auszuführen.
-[FET_RDK]
-STEUERUNG ÃNDERN
+[BJM1_E:BANKJ1]
+Also, ich brauche einen Safeknacker.
-[FET_AMS]
-MAUS-EINSTELLG.
+[BJM1_F:BANKJ1]
+Oh, ok, mal nachdenken...Safeknacker, Safeknacker...Ich hab's! Du wirst begeistert sein!
-[FET_STI]
-STANDARD STEURUNGSKONFIG.
+[BJM1_G:BANKJ1]
+Aah, nicht dieser Schwachkopf. Der sitzt doch.
-[FET_CTI]
-CLASSIC STEURUNGSKONFIG.
+[BJM1_H:BANKJ1]
+Wo sitzt er denn?
-[FET_MTI]
-MAUS STEURUNGSKONFIG.
+[BJM1_I:BANKJ1]
+In einer Zelle in einem Polizeirevier. Er wartet auf seine Verlegung.
-[FET_DAM]
-DYNAMISCHE AKUSTIK
+[BJM1_J:BANKJ1]
+Ich glaube fast, er kommt auf Bewãhrung raus...
-[FEC_TFL]
-Geschütz Links
+[BJM1_1:BANKJ1]
+~g~Befreie Cam Jones aus der Haft!
-[FEC_TFR]
-Geschütz Rechts
+[BJM1_3:BANKJ1]
+~g~In der Umkleide des Reviers findest du etwas Nützliches.
-[FEC_TFU]
-Geschütz /Dodo aufwãrts
+[BJM1_21:BANKJ1]
+~g~Die Key Card zu den Zellen findet sich im Obergeschoss des Reviers.
-[FEC_TFD]
-Geschütz /Dodo abwãrts
+[BNK1_7:BANKJ1]
+Cam Jones?
-[FEC_MWF]
-RAD AUFW.
+[BNK1_8:BANKJ1]
+Ich hol dich hier raus.
-[FEC_MWB]
-RAD ABW.
+[BNK1_10:BANKJ1]
+Ja, der bin ich...
-[FEC_ORR]
-oder
+[BNK1_11:BANKJ1]
+Ganz wie du meinst!
-[FEC_NUS]
-NICHT VERWENDET
+[BNK1_13:BANKJ1]
+Ich ziehe einen Job durch, und du bist mein Safeknacker.
-[FEC_LUD]
-Aufw. Sehen
+[BNK1_14:BANKJ1]
+Besser als in 'ner Zelle zu verrotten!
-[FEC_LDU]
-Abw. Sehen
+[BJM1_22:BANKJ1]
+~g~Bring Cam nach Hause!
-[FEC_CMP]
-COMBO: L+R SEHEN
+[BJM1_23:BANKJ1]
+~g~Du brauchst zunãchst die Magnetkarte für die Tür!
-[FEC_NTT]
-Noch kein Text für diese Taste
+[BNK1_12:BANKJ1]
+Hãng die Bullen ab und bring mich nach Hause!
-[FEC_FNC]
-F~1~
+[BJM1_20:BANKJ1]
+Die Waffe weg oder es passiert was!
-[FEC_IRT]
-EINFG
+[BJM1_5:BANKJ1]
+Zutritt ab hier nur für befugtes Personal.
-[FEC_DLL]
-ENTF
+[BJM1_2:BANKJ1]
+~r~Du solltest Cam die Freiheit bringen, nicht den Tod!
-[FEC_HME]
-POS1
+[BJM1_4:BANKJ1]
+Er ist bewaffnet! Erledigt ihn!
-[FEC_END]
-ENDE
+{=================================== MISSION TABLE BANKJ2 ===================================}
-[FEC_PGU]
-BILD AUF
+[BJM2_A:BANKJ2]
+Wir brauchen einen Überfall-Experten. Kennt ihr einen?
-[FEC_PGD]
-BILD AB
+[BJM2_B:BANKJ2]
+Hey, Tommy, Tommy, Tommy, das Zeug bringt dich nach vorn, Mann.
-[FEC_UPA]
-AUF
+[BJM2_C:BANKJ2]
+WoooOOOooo!
-[FEC_DWA]
-AB
+[BJM2_D:BANKJ2]
+Ich könnte dein Experte sein! Überfall! Überfall!
-[FEC_LFA]
-LINKS
+[BJM2_E:BANKJ2]
+Du bist kein Experte, du bist ein Idiot.
-[FEC_RFA]
-RECHTS
+[BJM2_F:BANKJ2]
+Mach dir 'nen Drink und halt die Klappe.
-[FEC_NUM]
-NUM
+[BJM2_G:BANKJ2]
+Hey, aus dem Weg!
-[FEC_NMN]
-NUM~1~
+[BJM2_H:BANKJ2]
+Cam, was meinst du?
-[FEC_FWS]
-NUM /
+[BJM2_I:BANKJ2]
+Tja, der beste Schütze in der Stadt ist ein Kerl namens Cassidy.
-[FEC_PLS]
-NUM +
+[BJM2_J:BANKJ2]
+Ach ja?
-[FEC_MIN]
-NUM -
+[BJM2_K:BANKJ2]
+Ja. Soldat, oder wenigstens hãlt er sich dafür.
-[FEC_DOT]
-NUM ,
+[BJM2_L:BANKJ2]
+Ich bezweifle, dass er je bei der Army war, aber er kann mit der Knarre umgehen.
-[FEC_NLK]
-NUMLOCK
+[BJM2_M:BANKJ2]
+Wahrscheinlich ist er in der Schießanlage.
-[FEC_ETR]
-ENT
+[BJM2_2A:BANKJ2]
+Bist du Phil Cassidy?
-[FEC_SLK]
-ROLLEN
+[BJM2_2B:BANKJ2]
+Wieso?
-[FEC_PSB]
-UNTBR
+[BJM2_2C:BANKJ2]
+Ich suche einen, der mit der Kanone umgehen kann. Was ich hier so sehe, überzeugt mich nicht.
-[FEC_BSP]
-RÜCKT.
+[BJM2_2D:BANKJ2]
+Jungchen, ich schieße dir auf 25 Meter eine Fliege vom Kopf.
-[FEC_TAB]
-TAB
+[BJM2_2E:BANKJ2]
+Ach wirklich?
-[FEC_CLK]
-CAPSLOCK
+[BJM2_2F:BANKJ2]
+Ja. Hab ich bei der Army gelernt.
-[FEC_RTN]
-RET
+[BJM2_2G:BANKJ2]
+Ist Fliegen-Schießen so beliebt in der Army? Gut, dass ich keine Steuern zahle.
-[FEC_LSF]
-LUMSCHALT
+[BJM2_2H:BANKJ2]
+Sollte das witzig sein, Jungchen?
-[FEC_RSF]
-RUMSCHALT
+[BJM2_2I:BANKJ2]
+Ha ha ha ha ha!
-[FEC_LCT]
-LSTRG
+[BJM2_2J:BANKJ2]
+Lass uns schießen.
-[FEC_RCT]
-RSTRG
+[BJM2_1:BANKJ2]
+~g~Begib dich nach Downtown ins Ammu-Nation und sprich mit Phil Cassidy.
-[FEC_LAL]
-LALT
+[BJM2_3:BANKJ2]
+TREFFERQUOTE: ~1~%
-[FEC_RAL]
-RALT
+[BJM2_4:BANKJ2]
+PUNKTE RUNDE EINS: ~1~
-[FEC_LWD]
-LWIN
+[BJM2_6:BANKJ2]
+PUNKTE RUNDE ZWEI: ~1~
-[FEC_RWD]
-RWIN
+[BJM2_7:BANKJ2]
+GESAMTPUNKTZAHL FÜR DAS SCHIESSEN: ~1~
-[FEC_WRC]
-WINKLICK
+[BJM2_9:BANKJ2]
+~g~Begib dich zum Startpunkt für Runde Zwei.
-[WIN_TTL]
-GTA 3
+[BJM2_11:BANKJ2]
+~r~Phil ist erledigt!
-[WIN_95]
-GTA 3 lãuft nicht unter Windows 95
+[BJM2_12:BANKJ2]
+~r~Einer der Schützen ist erledigt!
-[WIN_DX]
-GTA 3 benötigt mind. DirectX Version 8.1
+[BJM2_14:BANKJ2]
+~g~Begib dich zum nãchsten Areal!
-[WIN_VDM]
-GTA 3 benötigt mind. 12MB freien Grafikspeicher
+[BJM2_15:BANKJ2]
+PUNKTE:
-[DIAB3_G]
-Arriba!
+[BJM2_17:BANKJ2]
+~g~Sprich mit Phil.
-[FEM_RES]
-SPIEL FORTSETZEN
+[BJM2_18:BANKJ2]
+ZU SCHLAGEN:
-[FES_SNG]
-NEUES SPIEL STARTEN
+[BJM2_19:BANKJ2]
+~g~Triff innerhalb des Zeitlimits so viele Ziele wie du kannst!
-[FEM_SP]
-SINGLEPLAYER
+[BJM2_22:BANKJ2]
+~r~Du hast den Schießstand verlassen!
-[FEM_MP]
-MULTIPLAYER
+[BJM2_23:BANKJ2]
+~g~Wenn du den Schießstand wãhrend des Wettbewerbs verlãsst, ist die Mission gescheitert.
-[FEM_QT]
-SPIEL BEENDEN
+[BJM2_24:BANKJ2]
+~g~Das nahegelegenste Ziel bringt 1 Punkt.
-[FES_SG]
-NEUES SPIEL STARTEN
+[BJM2_25:BANKJ2]
+~g~Das mittlere Ziel bringt 2 Punkte.
-[FES_LG]
-SPIEL LADEN
+[BJM2_27:BANKJ2]
+~g~Alle Ziele dieser Runde bringen 1 Punkt.
-[FEM_HST]
-SPIEL HOSTEN
+[BNK2_2:BANKJ2]
+ZIELEN 3-2-1 FEUER!
-[FEM_OPT]
-OPTIONEN
+[BNK2_3:BANKJ2]
+AREAL KLAR!
-[FEM_DBG]
-DEBUG
+[BNK2_4:BANKJ2]
+Huuuiii!
-[FET_PSU]
-SPIELER SETUP
+[BNK2_5:BANKJ2]
+Der trãfe nicht mal ein Scheunentor.
-[FET_DEF]
-STANDARD WIEDERHERST.
+[BNK2_7:BANKJ2]
+Also, was ist jetzt, hilfst du mir bei dem Job?
-[FED_BRI]
-HELLIGKEIT
+[BNK2_8:BANKJ2]
+Jungchen, so wie du schießt, würde ich dich sogar heiraten.
-[FED_TRA]
-UNSCHÃRFE-FX
+[BNK2_9A:BANKJ2]
+Junge, deine Sprüche und deine Hirngespinste kannst du dir sonst wohin stecken. Du bist ein lausiger Schütze.
-[FEM_LOD]
-DISTANZ-DARSTELLG.
+[BNK2_9B:BANKJ2]
+Du bist ein lausiger Schütze.
-[FEM_VSC]
-FRAME SYNC
+[BJM2_28:BANKJ2]
+PUNKTE RUNDE DREI: ~1~
-[FEM_FRM]
-FRAME LIMITER
+[BJM2_20:BANKJ2]
+~g~Geht dir die ~w~Zeit ~g~oder die ~w~Munition ~g~aus, ist die Runde beendet!
-[FED_RES]
-BILDSCHIRMAUFLSG.
+[BJM2_26:BANKJ2]
+~g~Das am weitesten entfernte Ziel bringt 3 Punkte.
-[FED_WIS]
-BREITBILD
+[BNK2_1:BANKJ2]
+SCHARFE MUNITION
-[FEDS_TB]
-ZURÜCK
+[RANGE_1:BANKJ2]
+PUNKTZAHL SCHIESS-RUNDE:~1~
-[FEA_MUS]
-MUSIK VOLUME
+[BJM2_2:BANKJ2]
+~g~Um die Runde zu beenden, drücke die ~h~~k~~PED_JUMPING~.
-[FEA_SFX]
-SFX VOLUME
+[BJM2_N:BANKJ2]
+Nur die Ruhe.
-[FEA_RSS]
-RADIOSENDER
+{=================================== MISSION TABLE BANKJ3 ===================================}
-[FEL_ENG]
-ENGLISCH
+[BJM3_A:BANKJ3]
+Langsam fügt sich alles sehr schön zusammen hier.
-[FEL_FRE]
-FRANZ.
+[BJM3_B:BANKJ3]
+Was ist der Plan, Tommy? Was geht ab, Amigo?
-[FEL_GER]
-DEUTSCH
+[BJM3_C:BANKJ3]
+Der Plan ist, dass du dich wie ein Vollidiot benimmst. Wir brauchen einen Fahrer.
-[FEL_ITA]
-ITALIEN.
+[BJM3_D:BANKJ3]
+Tommy, ich mach's. Ich kann fahren.
-[FEL_SPA]
-SPANISCH
+[BJM3_E:BANKJ3]
+Nimm Hilary, Boss, nicht diesen Labersack von einem Rechtverdreher.
-[FEA_3DH]
-AUDIO HARDWARE
+[BJM3_F:BANKJ3]
+Hilary ist der beste. So schnell wie den hast noch keinen fahren sehen. Ich rufe ihn mal an.
-[FEA_SPK]
-BOXEN KONFIGURATION
+[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_2SP]
-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_4SP]
-MEHR ALS 2 BOXEN
+[BJM3_I:BANKJ3]
+Für einen Job. Ok, verstehe.
-[FEA_EAR]
-KOPFHÖRER
+[BJM3_J:BANKJ3]
+Was hat er gesagt?
-[FEA_NAH]
-KEINE AUDIO HARDWARE
+[BJM3_K:BANKJ3]
+Er macht's. Kein Problem. Na ja, ein kleines vielleicht: Er leidet unter Verlustãngsten.
-[FET_SNG]
-NEUES 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.
-[FEN_STA]
-SPIEL STARTEN
+[BJM3_M:BANKJ3]
+Jedenfalls will er erst ein Rennen gegen dich fahren. Er wartet draußen auf dich.
-[GMLOAD]
-SPIEL LADEN
+[BJM3_2A:BANKJ3]
+Bist du Tommy? Klar bist du Tommy, ich meine,
-[GMSAVE]
-SPIEL SPEICHERN
+[BJM3_2B:BANKJ3]
+wieso sollte sonst einer mit mir reden wollen?
-[FES_DGA]
-SPIEL LÖSCHEN
+[BJM3_2C:BANKJ3]
+Ok. Das ganze lãuft so ab:
-[FEM_NON]
-KEIN
+[BJM3_2D:BANKJ3]
+Ich fahre für dich, WENN und NUR WENN du selbst anstãndig fãhrst.
-[FEC_IVV]
-MAUS VERTIKAL INVERTIEREN
+[BJM3_2E:BANKJ3]
+Verlierst du mich, verzeihe ich dir das nie.
-[FEC_MSH]
-MAUSEMPFINDLICHKEIT
+[BJM3_2:BANKJ3]
+Hilary ist erledigt!
-[FET_CCN]
-STEUERUNG: CLASSIC
+[BJM3_4:BANKJ3]
+~g~Du brauchst ein Auto, um mitzumachen.
-[FET_SCN]
-STEUERUNG: STANDARD
+[BNK3_1:BANKJ3]
+Ok, ich fahre für dich. Aber bitte, behandle mich schlecht.
-[FES_SET]
-SKIN VERWENDEN
+[BNK3_3A:BANKJ3]
+Illegales Straßenrennen bei Vice Point.
-[GHOST]
-Ghost
+[BNK3_3B:BANKJ3]
+An alle Einsatzkrãfte.
-[WIN_RSZ]
-Neue Auflösung konnte nicht aktiviert werden
+[BNK3_3C:BANKJ3]
+Straßenrennen sind verboten und illegal!
-[FET_APP]
-LMT,RETURN,UM NEUE EINSTLLG. ZU SPEICHERN
+{=================================== MISSION TABLE BANKJ4 ===================================}
-[FET_HRD]
-STANDARDEINSTLLG. WIEDERHERGESTELLT
+[BNK4_A:BANKJ4]
+~w~Ihr seht Gentlemen, das wird leicht verdientes Geld für uns.
-[FET_MST]
-MAUSSTEUERUNG
+[BNK4_B:BANKJ4]
+~w~Ernsthaft, Tommy, du solltest dir überlegen, Anwalt zu werden.
-[FEC_STR]
-NUM STERN
+[BNK4_C:BANKJ4]
+~w~Was zum Geier rauchst du eigentlich, Mann? Das ist kein simpler Plan.
-[FET_MIG]
-LINKS,RECHTS,MAUSRAD ZUR EINSTLLG.
+[BNK4_D:BANKJ4]
+~w~Ach, wer braucht schon simple Plãne?
-[FET_CIG]
-RÜCKT. ZUM LÖSCHEN - LMT,RETURN ZUM ÃNDERN
+[BNK4_E:BANKJ4]
+~w~Der Kommunismus, das war ein simpler Plan. Hat Russland aber nicht viel genützt, hah?
-[FET_RIG]
-NEUE STEUERUNG FÜR DIESE AKTION WÃHLEN ODER ESC FÜR ABBRUCH
+[BNK4_F:BANKJ4]
+~w~Ganz ruhig. Mit einem Team wie diesem ist das alles kein Problem.
-[FET_EIG]
-KANN DIESER AKTION KEINE STEUERUNG ZUWEISEN
+[BNK4_G:BANKJ4]
+~w~Cam übernimmt den Safe. Phil? Wir beide kümmern uns um die Sicherheit, und Hilary fãhrt den Fluchtwagen.
-[NO_PCCD]
-Bitte legen Sie die GTA 3 Disk 2 ein oder drücken Sie 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...?
-[CVT_ERR]
-Kein Platz mehr auf der Festplatte. Bitte schaffen Sie Speicherplatz, bevor Sie fortfahren. ESC zum Abbrechen.
+[BNK4_I:BANKJ4]
+~w~Ken...Ken, richtig. Ken wãscht das Geld für uns und stellt schon mal die Drinks kalt.
-[FED_SUB]
-UNTERTITEL
+[BNK4_J:BANKJ4]
+~w~Ich verstehe nicht, was ich hier soll.
-[FET_DSN]
-Standard-Player Skin.bmp
+[BNK4_K:BANKJ4]
+~w~Ist doch ganz einfach. Warst du noch nie im Kino?
-[EBAL]
-'GIB MIR LIBERTY'
+[BNK4_L:BANKJ4]
+~w~Wir latschen in die Bank rein, fuchteln mit den Knarren rum und gehen stinkreich wieder raus.
-[LM4]
-'PUMP-ACTION-THRILLER'
+[P_DEAD:BANKJ4]
+~r~Phil ist erledigt!!
-[REPLAY]
-WIEDERHOLUNG
+[C_DEAD:BANKJ4]
+~r~Cam ist erledigt!!
-[FEC_SFT]
-UMSCHALT
+[H_DEAD:BANKJ4]
+~r~Hilary ist erledigt!!
-[CRED254]
-STUDIO MANAGER
+[P_HIND:BANKJ4]
+~r~Du hast Phil verloren!
-[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.
+[C_HIND:BANKJ4]
+~r~Cam wurde abgehãngt!
-[FEM_ON]
-AN
+[H_HIND:BANKJ4]
+~r~Hilary wurde im Stich gelassen!
-[FEM_OFF]
-AUS
+[GETCAR:BANKJ4]
+Steig in den Fluchtwagen und führe den Plan aus!
-[FEM_YES]
-JA
+[TRASHED:BANKJ4]
+~r~DU HAST DEN FLUCHTWAGEN GESCHROTTET!!
-[FEM_NO]
-NEIN
+[BNK4_1:BANKJ4]
+Ich fahre.
-[FES_WAR]
-Speichere Daten, bitte warten...
+[BNK4_2:BANKJ4]
+Na prima. Beifahrer. Wenn ich das in der Therapie erzãhle.
-[FED_DLW]
-Lösche Daten, bitte warten...
+[BNK4_3A:BANKJ4]
+Hey, pass auf, wo du hinfãhrst, Tommy!
-[FED_LDW]
-Lade Daten, bitte warten...
+[BNK4_3B:BANKJ4]
+Tommy, Hilary macht sich so breit!
-[FEC_SLC]
-Slot ist beschãdigt
+[BNK4_3C:BANKJ4]
+Stimmt gar nicht!
-[FED_LFL]
-Spiel konnte nicht geladen werden. Das Spiel wird neu gestartet.
+[BNK4_3D:BANKJ4]
+Doch!
-[FET_RSO]
-ORIGINAL-EINSTELLG. WIEDERHERGESTELLT
+[BNK4_3E:BANKJ4]
+Hey, Klappe, ihr zwei, oder ihr könnt zu Fuß gehen.
-[FET_RSC]
-HARDWARE NICHT VERFÜGBAR - ORIGINAL-EINSTELLG. WIEDERHERGESTELLT
+[BNK4_3F:BANKJ4]
+Ja, Hilary.
-[CRED270]
-MIKE HONG
+[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]
+Benutze die ~h~~k~~PED_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]
+Benutze die ~h~~k~~PED_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]
+Um auf einem ~h~Motorrad ~w~sitzend ~h~geradeaus zu feuern~w~, drücke die ~h~~k~~PED_FIREWEAPON~.
+
+[GEN3_41:GENERA3]
+Um auf einem ~h~Motorrad ~w~sitzend ~h~geradeaus zu feuern~w~, drücke die ~h~~k~~PED_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]
+Um auf einem Motorrad sitzend geradeaus zu feuern, drücke die ~o~|~w~-Taste.
+
+[GEN3_65:GENERA3]
+Um auf einem Motorrad sitzend geradeaus zu feuern, drücke die ~x~/~w~-Taste.
+
+[GEN3_66:GENERA3]
+Um auf einem Motorrad sitzend geradeaus zu feuern, drücke die ~h~R1~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]
+Um eine Bombe abzuwerfen, drück die ~h~~k~~PED_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.
+
+[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]
+~g~Wenn du diese Mission abbrechen willst, drücke die ~h~~k~~PED_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]
+~g~Wenn du diese Mission abbrechen willst, drücke die ~h~~k~~PED_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]
+~g~Um eine Bombe abzuwerfen, drücke die~h~ ~k~~PED_FIREWEAPON~~w~.
+
+[TEX3_29:SERG3]
+Um eine Bombe abzuwerfen, drücke die~h~ ~k~~PED_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]
+Drück den ~h~ ~k~~VEHICLE_ACCELERATE~~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!
[DUMMY]
THIS LABEL NEEDS TO BE HERE !!!
diff --git a/utils/gxt/italian.txt b/utils/gxt/italian.txt
index 822a30b8..7b02017f 100644
--- a/utils/gxt/italian.txt
+++ b/utils/gxt/italian.txt
@@ -1,152 +1,50 @@
-[LETTER1]
-abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789"$,.'-?!!SDBFàèéìòùÀÈÉÌÒÙ
-
-[DEFNAM]
-Claude----------------------
-
-[IN_VEH]
+[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!
@@ -154,15 +52,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)
@@ -170,10 +80,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
@@ -181,47 +91,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.
@@ -245,7 +122,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.
@@ -262,6746 +139,6926 @@ 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]
-Parcheggiala, attivala premendo il ~h~tasto ~k~~PED_FIREWEAPON~~w~ e DATTELA A GAMBE!
+[RCRAIDE]
+Raider radiocomandato
-[GA_7]
-Arma la bomba con il ~h~tasto ~k~~PED_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
-[FEC_CCF]
-Configurazione:
+[RATNG23]
+Scagnozzo
-[FEC_CF1]
-Config1
+[RATNG24]
+Tirapiedi
-[FEC_CF2]
-Config2
+[RATNG25]
+Avanzo di galera
-[FEC_CF3]
-Config3
+[RATNG26]
+Ex galeotto
-[FEC_CF4]
-Config4
+[RATNG27]
+Criminale
-[FEC_CDP]
-Schermata controller:
+[RATNG28]
+Picchiatore
-[FEC_ONF]
-A piedi
+[RATNG29]
+Saggio
-[FEC_INC]
-In macchina
+[RATNG30]
+Autista
-[FEC_VIB]
-Vibrazione:
+[RATNG31]
+Guardia del corpo
-[FEA_OUT]
-Uscita:
+[RATNG32]
+Attaccabrighe
-[FEA_ST]
-Stereo
+[RATNG33]
+Cacciatore di taglie
-[FEA_MNO]
-Mono
+[RATNG34]
+Vigilante
-[FEA_NON]
-Nessuna
+[RATNG35]
+Ronin
-[FEA_FM0]
-HEAD RADIO
+[RATNG36]
+Riparatore
-[FEA_FM1]
-DOUBLE CLEFF FM
+[RATNG37]
+Sicario
-[FEA_FM2]
-JAH RADIO
+[RATNG38]
+Socio
-[FEA_FM3]
-RISE FM
+[RATNG39]
+Macellaio
-[FEA_FM4]
-LIPS 106
+[RATNG40]
+Pulitore
-[FEA_FM5]
-GAME FM
+[RATNG41]
+Assassino
-[FEA_FM6]
-MSX FM
+[RATNG42]
+Consigliere
-[FEA_FM7]
-FLASHBACK 95.6
+[RATNG43]
+Consulente
-[FEA_FM8]
-CHATTERBOX 109
+[RATNG44]
+Braccio destro
-[FED_DBG]
-Menu Debug
+[RATNG45]
+Esecutore
-[FED_RID]
-Reload IDE
+[RATNG46]
+Tenente
-[FED_RIP]
-Reload IPL
+[RATNG47]
+Aiutante del boss
-[FED_PAH]
-Parse Heap
+[RATNG48]
+Capo
-[FED_RCD]
-CCullZones::RecalculateCullZoneData
+[RATNG49]
+Boss
-[FED_DFL]
-CTheScripts::DbgFlag
+[RATNG50]
+Intoccabile
-[FED_DLS]
-Big White Debug Light Switched
+[RATNG51]
+Don
-[FED_SPR]
-Show Ped Road Groups
+[RATNG52]
+Re della fottuta città
-[FED_SCR]
-Show Car Road Grups
+[PAGE_00]
+.
-[FED_SCZ]
-Show Cull Zones
+[WELCOME]
+BENVENUTO A
-[FED_DSR]
-Debug Streaming Requests
+[TSCORE]
+GUADAGNI: ~1~$
-[FED_SCP]
-gbShowCollisionPolys
+[PBOAT_2]
+Premi il ~h~~k~~PED_FIREWEAPON~~w~ per sparare con i cannoni della barca.
-[FEM_MCM]
-Memory Card Menu
+[HJSTAT]
+Distanza: ~1~.~1~m Altezza: ~1~.~1~m Ribaltamenti: ~1~ Rotazioni: ~1~_
-[FEM_RMC]
-Registra MEMORY CARD uno
+[HJSTATW]
+Distanza: ~1~.~1~m Altezza: ~1~.~1~m Ribaltamenti: ~1~ Rotazioni: ~1~_ E che grande atterraggio!
-[FEM_TFM]
-Test Format MemCard One
+[ATUTOR]
+Premi il ~h~~k~~TOGGLE_SUBMISSIONS~~w~ per attivare o disattivare le missioni Infermiere.
-[FEM_TUM]
-Test UnFormat MemCard One
+[FEST_HA]
+Livello massimo della missione Infermiere
-[FEM_CRD]
-Create Root Dir
+[C_KILLS]
+CRIMINALI UCCISI: ~1~
-[FEM_CLI]
-Crea e carica icone
+[HJSTATF]
+Distanza: ~1~ piedi Altezza: ~1~ piedi Ribaltamenti: ~1~ Rotazioni: ~1~_
-[FEM_FFF]
-Riempi il primo file con fuffa
+[HJSTAWF]
+Distanza: ~1~ piedi Altezza: ~1~ piedi Ribaltamenti: ~1~ Rotazioni: ~1~_ E che grande atterraggio!
-[FEM_SOG]
-Salva solo la partita
+[CRED001]
+ROCKSTAR NORTH
-[FEM_CES]
-Verifica ogni salvataggio 0kB4
+[CRD001A]
+DIRETTORE DELLO STUDIO
-[FEM_STG]
-Salva la partita
+[CRD001B]
+ANDREW SEMPLE
-[FEM_STS]
-Salva la partita con il nome GTA3
+[CRED002]
+PRODUTTORE
-[FEM_CPD]
-Crea una cartella mag protetta
+[CRD002A]
+DIRETTORE DI SVILUPPO
-[FEM_MC2]
-Memory Card Menu 2
+[CRED003]
+LESLIE BENZIES
-[FEM_TS]
-Prova salvataggio:
+[CRED004]
+DIRETTORE ARTISTICO
-[FEM_TL]
-Prova caricamento:
+[CRED005]
+AARON GARBUT
-[FEM_TD]
-Prova eliminazione:
+[CRED006]
+DIRETTORI TECNICI
-[PL_STAT]
-Statistiche giocatore
+[CRED007]
+OBBE VERMEIJ
-[PE_WAST]
-Persone massacrate
+[CRED008]
+ADAM FOWLER
-[PE_WSOT]
-Persone massacrate da altri
+[CRED010]
+ANDREW DUTHIE
-[CAR_EXP]
-Macchine esplose
+[CRED011]
+CRAIG FILSHIE
-[TM_BUST]
-Tempi battuti
+[CRED012]
+WILLIAM MILLS
-[M_WASTE]
-Uomini civili massacrati
+[CRED013]
+CHRIS ROTHWELL
-[F_WASTE]
-Donne civili massacrate
+[CRD013A]
+IMRAN SARWAR
-[PIG_WST]
-Poliziotti massacrati
+[CRD013B]
+JAMES WORRALL
-[GNG_WST]
-Membri delle gang massacrati
+[CRD013C]
+JOHN HAIME
-[MED_WST]
-Medici massacrati
+[CRED014]
+SCRITTO DA
-[FIRE_WS]
-Pompieri massacrati
+[CRED015]
+JAMES WORRALL
-[DED_CRI]
-Criminali massacrati
+[CRED016]
+PAUL KUROWSKI
-[DED_DED]
-Scrocconi massacrati
+[CRED017]
+DAN HOUSER
-[DED_HOK]
-Prostitute massacrate
+[CRED018]
+PROGETTAZIONE PERSONAGGI PRINCIPALI
-[HEL_DST]
-Elicotteri distrutti
+[CRD018A]
+PROGETTAZIONE PERSONAGGI
-[PER_COM]
-Percentuale completata
+[CRED019]
+IAN MCQUE
-[KGS_EXP]
-Kg di esplosivi utilizzati
+[CRD019A]
+TOKS SOLARIN
-[ACCURA]
-Accuratezza
+[CRD019B]
+ALAN DAVIDSON
-[ELBURRO]
-Miglior tempo di corsa in sec
+[CRED020]
+ANIMATORE CAPO
-[CAR_CRU]
-Macchine distrutte
+[CRED021]
+ALEX HORTON
-[HED_EX]
-Teste esplose
+[CRD022A]
+ANIMATORI
-[TM_DED]
-Visite in ospedale
+[CRED022]
+LEE MONTGOMERY
-[DAYSPS]
-Giorni trascorsi nel gioco
+[CRD022B]
+DUNCAN SHIELDS
-[MMRAIN]
-Pioggia caduta in mm
+[CRD022C]
+GUS BRAID
-[MXCARD]
-Distanza max salto FOLLE (ft)
+[CRED023]
+PROGETTAZIONE VEICOLI
-[MXCARJ]
-Altezza max salto FOLLE (ft)
+[CRD023A]
+JOLYON ORME
-[MXCARDM]
-Distanza max salto FOLLE (m)
+[CRD023B]
+ALAN DUNCAN
-[MXCARJM]
-Altezza max salto FOLLE (m)
+[CRD024A]
+CAPO PROGETTAZIONE VEICOLI
-[MXFLIP]
-Numero max ribaltamenti FOLLI in aria
+[CRED024]
+PAUL KUROWSKI
-[MXJUMP]
-Numero max rotazioni FOLLI in aria
+[CRED025]
+PROGETTAZIONE MAPPA
-[BSTSTU]
-Migliore acrobazia FOLLE:
+[CRED026]
+ADAM COCHRANE
-[INSTUN]
-Acrobazia folle
+[CRED027]
+NIK TAYLOR
-[PRINST]
-Acrobazia folle perfetta
+[CRED028]
+GARY MCADAM
-[DBINST]
-Doppia acrobazia folle
+[CRED029]
+KEIRAN BAILLIE
-[DBPINS]
-Doppia acrobazia folle perfetta
+[CRED030]
+ALISDAIR WOOD
-[TRINST]
-Tripla acrobazia folle
+[CRED031]
+ANDREW SOOSAY
-[PRTRST]
-Tripla acrobazia folle perfetta
+[CRD031A]
+STEVEN MULHOLLAND
-[QUINST]
-Quadrupla acrobazia folle
+[CRD031B]
+WAYLAND STANDING
-[PQUINS]
-Quadrupla acrobazia folle perfetta
+[CRD031C]
+CAMPBELL J. DICK
-[NOSTUC]
-Nessuna acrobazia FOLLE effettuata
+[CRD031D]
+PROGETTAZIONE GRAFICA
-[NOUNIF]
-Acrobazie uniche effettuate
+[CRD031E]
+STUART PETRI
-[NOUNGM]
-Acrobazie uniche complessive
+[CRED032]
+PROGRAMMATORE CAPO
-[NMISON]
-Missioni provate
+[CRD032A]
+PROGRAMMATORI
-[NMMISP]
-Missioni superate
+[CRED033]
+ALEXANDER ROGER
-[PASDRO]
-Passeggeri scaricati
+[CRED034]
+GRAEME WILLIAMSON
-[MONTAX]
-Soldi guadagnati in taxi
+[CRED035]
+BARANE CHAN
-[DAYPLC]
-Spesa giornaliera polizia
+[CRED036]
+DEREK PAYNE
-[CRIMRA]
-Livello criminalità:
+[CRED037]
+GORDON YEOMAN
-[GMSTOR]
-Negozio dei giochi
+[CRD037A]
+ALAN CAMPBELL
-[PREBRF]
-Briefing precedenti
+[CRD037B]
+MARK HANLON
-[CNTLS]
-Comandi
+[CRD037C]
+ANDRZEJ MADAJCZYK
-[MUSMEN]
-Musica-FX
+[CRED038]
+CAPO PRODUZIONE MUSICA
-[GAMSET]
-Impostazioni
+[CRED039]
+CRAIG CONNER
-[LANGUA]
-Lingua
+[CRED040]
+STUART ROSS
-[DSPLAY]
-Video
+[CRED041]
+CAPO INGEGNERE AUDIO
-[DEBUGM]
-Menu di debug
+[CRED042]
+ALLAN WALKER
-[QUITOP]
-Esci dalle opzioni
+[CRD041A]
+INGEGNERE AUDIO
-[CONTRL]
-Configurazione comandi
+[CRD041B]
+AUDIO
-[SET1EN]
-Configurazione 1. Abilitata.
+[CRD042A]
+WILL MORTON
-[SET1]
-Configurazione 1
+[CRED043]
+PROGRAMMATORE AUDIO
-[SET2EN]
-Configurazione 2. Abilitata.
+[CRED044]
+RAYMOND USHER
-[SET2]
-Configurazione 2
+[CRED045]
+RESPONSABILE TESTING
-[SET3EN]
-Configurazione 3. Abilitata.
+[CRED046]
+CRAIG ARBUTHNOTT
-[SET3]
-Configurazione 3
+[CRED047]
+CAPO CQ
-[SET4EN]
-Configurazione 4. Abilitata.
+[CRED048]
+NEIL CORBETT
-[SET4]
-Configurazione 4
+[CRED049]
+KEVIN WONG
-[GOBACK]
-Indietro
+[CRED050]
+CQ
-[SOUND]
-SONORO
+[CRED051]
+DAVID BEDDOES
-[MUSVOL]
-Volume musica
+[CRED052]
+DAVID WATSON
-[SFXVOL]
-Volume FX
+[CRED053]
+BARRY CLARK
-[SCROPT]
-OPZIONI SCHERMO
+[CRED054]
+ROSS SPARROW
-[CTRSCR]
-Centra schermo
+[CRED055]
+JAMES ALLAN
-[SCRFOR]
-Formato schermo
+[CRED056]
+NEIL MEIKLE
-[GMSVLQ]
-SALVA-CARICA-ESCI
+[CRD056A]
+GEORGE WILLIAMSON
-[GMREST]
-Ricomincia partita
+[CRD056B]
+MATT JONES
-[NOGMSV]
-Puoi salvare solo al tuo nascondiglio.
+[CRD056C]
+ROB HARBOUR
-[DLFILE]
-Elimina i file di Grand Theft Auto III
+[CRD056D]
+TOM WHITTAKER
-[CHFILE]
-SCEGLI IL FILE DA CARICARE
+[CRED057]
+CAPO SUPPORTO TECNICO
-[CHCDLD]
-Choose Card to Load From
+[CRED058]
+LORRAINE ROY
-[CDUNFR]
-Card is unformatted.
+[CRD057A]
+SUPPORTO TECNICO
-[CHFIDL]
-SCEGLI IL FILE DA CANCELLARE
+[CRED059]
+CHRISTINE CHALMERS
-[SVCONF]
-SALVA CONFERMA
+[CRD060A]
+SUPPORTO UFFICIO
-[SVFNAM]
-Il nome del tuo salvataggio è
+[CRD060B]
+KIM GURNEY
-[SAVEDN]
-Errore. Salvataggio non completato.
+[CRD060C]
+CASSIE OLIVER
-[LANGSL]
-SCELTA LINGUA
+[CRED060]
+ROCKSTAR NEW YORK
-[ENGLIS]
-Inglese
+[CRED061]
+PRODUTTORE ESECUTIVO
-[GERMAN]
-Tedesco
+[CRED062]
+SAM HOUSER
-[ITALIA]
-Italiano
+[CRED063]
+PRODUTTORE
-[FRENCH]
-Francese
+[CRED064]
+DAN HOUSER
-[SPAIN]
-Spagnolo
+[CRED065]
+VP DI SVILUPPO
-[RELIDE]
-ReLoadIde
+[CRED066]
+JAMIE KING
-[RELIPE]
-ReLoadIpl
+[CRED067]
+CAPO RESPONSABILE TECNOLOGICO
-[PARSHP]
-Parse Heap
+[CRED068]
+GARY J. FOREMAN
-[DBGFON]
-CTheScripts::DbgFlag On
+[CRED069]
+PRODUTTORE ASSOCIATO
-[DBFOFF]
-CTheScripts::DbgFlag Off
+[CRED070]
+JEREMY POPE
-[BGWHON]
-Big White Debug Light Switched On
+[CRD071A]
+DIRETTORE DEL CQ
-[BGWOFF]
-Big White Debug Light Switched Off
+[CRD072A]
+JEFF ROSA
-[DSTRON]
-Debug Streaming Requests On
+[CRED071]
+SUPERVISORE MUSICA
-[DSTROFF]
-Debug Streaming Requests Off
+[CRED072]
+TERRY DONOVAN
-[PDRGON]
-ShowPedRoadGroups On
+[CRED073]
+SQUADRA DI PRODUZIONE
-[PRGOFF]
-ShowPedRoadGroups Off
+[CRED074]
+TERRY DONOVAN
-[CRRGON]
-ShowCarRoadGroups On
+[CRED075]
+JENNIFER KOLBE
-[CRGOFF]
-ShowCarRoadGroups Off
+[CRED076]
+JENEFER GROSS
-[CLZOON]
-Show Cull Zones On
+[CRED077]
+LAURA PATERSON
-[CLZOOF]
-Show Cull Zones Off
+[CRED078]
+JEFF CASTANEDA
-[SHPLON]
-gbShowCollisionPolys On
+[CRED079]
+JERONIMO BARRERA
-[SHPLOF]
-gbShowCollisionPolys Off
+[CRED080]
+CARLY SLATER
-[CULREC]
-CCullZones::RecalculateCullZoneData()
+[CRED081]
+JUNG KWAK
-[FORMM1]
-FormatMemCard 1 (teststuff)
+[CRED082]
+BRIAN WOOD
-[UNFRM1]
-UnFormatMemCard 1 (teststuff)
+[CRED083]
+RENAUD SEBANNE
-[GORLEV]
-Livello violenza
+[CRED084]
+RICHARD KRUGER
-[SICASS]
-Stupro
+[CRD084A]
+DANIEL EINZIG
-[SICSIC]
-Stupratore
+[CRD084B]
+JACEN BURROWS
-[SCASSL]
-Stupro selezionato
+[CRD084C]
+LINN PR
-[SCSCSL]
-Stupratore selezionato
+[CRD084D]
+GRAFICA DI COPERTINA
-[PRVMEN]
-Briefing di missione precedente
+[CRD084E]
+STEPHEN BLISS
-[DOSVGM]
-Vuoi salvare la partita?
+[CRED085]
+KENT PAUL'S 80 NOSTALGIA ZONE
-[FORMEN]
-Format Menu
+[CRED086]
+COMPOSTA DA DAN HOUSER
-[MEMTST]
-MemoryCardTest screen
+[CRD086A]
+PRODOTTA DA ADAM TEDMAN
-[REGCAR]
-Register MemoryCard One
+[CRED087]
+WWW.KENTPAUL.COM E WWW.VICECITY.COM
-[TEFONE]
-Test Format MemCard One
+[CRED088]
+CREATO DA
-[TEUFON]
-Test UnFormat MemCard One
+[CRD088A]
+ADAM TEDMAN
-[CRROOT]
-CreaDirRoot
+[CRD088B]
+DAVID YU
-[CRLDIC]
-Crea e carica icone
+[CRD088C]
+JERRY LUNA
-[FLFSGF]
-Riempi il primo file con fuffa
+[CRD088D]
+STUART PETRI
-[PUSAVE]
-Salva solo il gioco
+[CRD088E]
+MICHAEL CARNEVALE
-[CHEVOK]
-VerificaOgniSalvataggioOKB4
+[CRD088F]
+GREG LAU
-[SVGMON]
-SalvaIlGioco
+[CRD088G]
+FUTABA HAYASHI
-[CNTSAV]
-Impossibile salvare il gioco, sei in missione.
+[CRED089]
+RESPONSABILE CQ
-[CNCSAV]
-Impossibile salvare il gioco, sei in macchina.
+[CRED090]
+CRAIG ARBUTHNOTT
-[CRMGSV]
-Crea cartella magazine protetta
+[CRED091]
+CAPO ANALISTA
-[MGSVCN]
-Cartella Magazine creata
+[CRED092]
+ADAM DAVIDSON
-[MGSVNC]
-Cartella Magazine non creata
+[CRD092A]
+JOE HOWELL
-[YES]
-Sì
+[CRD092B]
+MARC FERNANDEZ
-[NO]
-No
+[CRED093]
+ANALISTA DI GIOCO
-[X]
-x
+[CRED094]
+RICHARD HUIE
-[LAST]
-Ultimo messaggio.
+[CRED095]
+SQUADRA TESTING ROCKSTAR
-[FEDS_XB]
-Selezione
+[CRED096]
+LANCE WILLIAMS
-[FEDS_ST]
-Tasto START - RIPRENDI
+[CRED097]
+JOE GREENE
-[FEST_OO]
-su
+[CRED098]
+BRIAN PLANER
-[FEC_TUC]
-Torretta di controllo
+[CRD098A]
+ELIZABETH SATTERWHITE
-[FEC_SM3]
-Attivazione missione speciale (tasto R3)
+[CRD098B]
+JAMEEL VEGA
-[FEC_RS3]
-Stazioni radio (tasto L3)
+[CRD098C]
+MIKE HONG
-[FEC_HO3]
-Clacson (tasto L3)
+[CRED099]
+LEE CUMMINGS
-[DIAB1]
-'TURISMO'
+[CRED100]
+SCENEGGIATURA
-[DIAB2]
-'IO GRIDO, TU GRIDI'
+[CRED101]
+JAMES WORRALL
-[DIAB3]
-'BATTESIMO DEL FUOCO'
+[CRED102]
+DAN HOUSER
-[DIAB4]
-'GROSSO E ARTERIOSO'
+[CRED103]
+ADAM TEDMAN
-[DIAB1_A]
-El Burro ti vuole offrire un'opportunità. Vai alla cabina telefonica di Hepburn Heights se vuoi saperne di più.
+[CRED104]
+PAUL YEATES
-[DIAB1_C]
-Sei un pilota provetto. Ripassa per la cabina telefonica, 'El Burro' potrebbe avere altro lavoro per te.
+[CRED105]
+JENEFER GROSS
-[DIAB1_1]
-~g~3..2..1.. VIA VIA VIA!
+[CRED106]
+LAURA PATERSON
-[DIAB1_4]
-~g~Procurati un'auto veloce e vai alla griglia di partenza.
+[CRED107]
+SEQUENZE ANIMATE
-[DIAB1_3]
-~r~Non riusciresti a vincere neanche una lotteria, FALLITO!
+[CRED108]
+SCRITTE DA DAN HOUSER E JAMES WORRALL
-[DIAB1_2]
-~g~Congratulazioni, hai vinto con l'incredibile tempo di ~1~ secondi.
+[CRED109]
+DIREZIONE AUDIO DI DAN HOUSER E NAVID KHONSARI
-[FIRST]
-~g~Primo
+[CRED110]
+PRODOTTE DA JAMIE KING
-[SECOND]
-~g~Secondo
+[CRD110A]
+RICERCA TALENTI: JAMIE KING, SEAN MACALUSO
-[THIRD]
-~g~Terzo
+[CRED111]
+CAST
-[FOURTH]
-~g~Quarto
+[CRD111A]
+PERSONAGGI PRINCIPALI
-[DIAB2_1]
-~g~Prendi la valigia ad Harwood.
+[CRED112]
+TOMMY VERCETTI - RAY LIOTTA
-[DIAB2_2]
-~g~Trova un furgone dei gelati.
+[CRED113]
+KEN ROSENBERG - WILLIAN FICHTNER
-[DIAB2_3]
-~g~Parcheggia il furgone dei gelati al molo atlantico.
+[CRED114]
+SONNY FORELLI - TOM SIZEMORE
-[DIAB2_4]
-~g~Premi il ~w~tasto ~k~~VEHICLE_HORN~ ~g~per attivare il campanello.
+[CRED115]
+STEVE SCOTT - DENNIS HOPPER
-[DIAB2_6]
-~g~Premi il ~w~tasto ~k~~VEHICLE_HORN~ ~g~per attivare il campanello.
+[CRED116]
+AVERY CARRINGTON - BURT REYNOLDS
-[DIAB2_7]
-~g~Premi il ~w~tasto ~k~~VEHICLE_HORN~ ~g~per attivare il campanello.
+[CRED117]
+RICARDO DIAZ - LUIS GUZMAN
-[DIAB2_5]
-~g~Esci dal furgone dei gelati e usa il telecomando per farlo esplodere.
+[CRED118]
+LANCE VANCE - PHILIP MICHAEL THOMAS
-[YD1]
-'BLING-BLING SCRAMBLE'
+[CRED119]
+COLONNELLO JUAN CORTEZ - ROBERT DAVI
-[YD2]
-'UZI RIDER'
+[CRED120]
+UMBERTO ROBINA - DANNY TREJO
-[YD3]
-'CORSA TRA GANGSTER'
+[CRED121]
+PHIL CASSIDY - GARY BUSEY
-[YD4]
-'VENGA IL TUO REGNO'
+[CRED122]
+MITCH BAKER - LEE MAJORS
-[YD_P]
-King Courtney vuole parlarti. Vai alla cabina telefonica ad Aspatria!
+[CRED123]
+MERCEDES CORTEZ - FAIRUZA BALK
-[YD1_A]
-~w~Sono King Courtney.
+[CRED124]
+KENT PAUL - DANNY DYER
-[YD1_A1]
-~w~Alla mia cricca Yardie servirebbe un buon autista e tu hai un'ottima reputazione.
+[CRED125]
+JEZZ TORRENT - KEVIN MCKIDD
-[YD1_B]
-~w~Vai in macchina alla discarica dalla parte opposta dello stadio e aspetta gli altri aspiranti.
+[CRED126]
+CENTRALINISTA TAXI - DEBORAH HARRY
-[YD1_C]
-~w~Ho uomini di guardia in postazioni sparse per tutta Staunton.
+[CRED127]
+CANDY SUXX - JENNA JAMESON
-[YD1_D]
-~w~Il primo pilota che raggiunge una postazione prende $1000, e cosi via fino alla tappa successiva.
+[CRED128]
+BJ SMITH - LAWRENCE TAYLOR
-[YD1_D1]
-~w~Se raggiungi per primo più postazioni degli altri piloti, potrei avere del lavoro per te.
+[CRED129]
+AUNTIE POULET - YOUREE CLEOMILI HARRIS
-[YD1_E]
-~g~Preparati alla gara!
+[CRED130]
+SPACCIATORE - ARMANDO RIESCO
-[YD1_F]
-~g~Hai anticipato la partenza; mi piace il tuo stile!
+[CRED131]
+COUGAR - BLAYNE PERRY
-[YD1_G]
-~r~È una GARA AUTOMOBILISTICA. Ti serve un'AUTO, idiota!
+[CRED132]
+HILARY - CHARLES TUCKER
-[YD1GO]
-~g~VIA!
+[CRED133]
+DEPUTATO ALEX SHRUB - CHRIS LUCAS
-[YD1_1]
-~r~1
+[CRED134]
+VECCHIO KELLY - GEORGE DICENZO
-[YD1_2]
-~r~2
+[CRD134A]
+CAM JONES - GREG SIMS
-[YD1_3]
-~r~3
+[CRD134B]
+PSICOPATICO - HUNTER PLATIN
-[YD1_BON]
-$1000!
+[CRD134C]
+MAUDE, LA SIGNORA DEI GELATI - JANE GENNARO
-[Y1_1ST]
-~g~Sei arrivato primo con ~1~ postazioni!
+[CRD134D]
+JETHRO - JOHN ZURHELLEN
-[Y1_2ND]
-~y~Sei arrivato secondo con ~1~ postazioni. ~y~Non male, ma non sei il migliore!
+[CRD134E]
+GONZALES - JORGE PUPO
-[Y1_3RD]
-~r~Sei arrivato terzo con ~1~ postazioni. ~r~Credevo avessi detto di essere in gamba!
+[CRD134F]
+DWAYNE - NAVID KHONSARI
-[Y1_LAST]
-~r~Sei arrivato ultimo! ~r~Mi hai fatto perdere tempo, IDIOTA!
+[CRD134G]
+DICK - PETER MCKAY
-[Y1_J1ST]
-~y~Primo a pari merito con ~1~ postazioni. ~y~Bravo, ma devi essere il migliore per guidare per Queen Lizzy!
+[CRD134H]
+MIKE & PORNOSTAR - ROBERT CIHRA
-[Y1_J2ND]
-~r~Secondo a pari merito con ~1~ postazioni. Guidi come una scimmia impazzita!
+[CRD134I]
+PERCY - RUSSELL FOREMAN
-[Y1JLAST]
-~r~Ultimo a pari merito! Sei più veloce con la lingua che con l'auto!
+[CRED135]
+MOTION CAPTURE
-[Y1_TEST]
-AUTO IN ACQUA!
+[CRED136]
+ANIMATO DA
-[YD2_A]
-~w~Devo vedere se sei in grado di eseguire certi lavoretti per me.
+[CRD136A]
+DIREZIONE TECNICA DI ALEX HORTON
-[YD2_A1]
-~w~Vediamo se ci si può fidare di te.
+[CRED137]
+DIRETTO DA
-[YD2_B]
-~w~Due dei miei ragazzi saranno lì a momenti per accompagnarti in un giro:
+[CRD137A]
+DIRETTO DA NAVID KHONSARI
-[YD2_B1]
-~w~vedremo se sei davvero chi dici di essere.
+[CRED138]
+PRODOTTO DA
-[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.
+[CRD138A]
+PRODOTTO DA JAMIE KING
-[YD2_CC]
-~w~Prendi, ti serviranno 'i ferri del mestiere'.
+[CRD138B]
+RENAUD SEBBANE
-[YD2_D]
-~w~Dovrai guidare e sparare. Noi faremo in modo che tu non finisca al creatore.
+[CRED139]
+REGISTRATO PRESSO PERSPECTIVE STUDIOS, BROOKLYN
-[YD2_E]
-~w~Comincia a guidare!
+[CRED140]
+ATTORI MOTION CAPTURE
-[YD2_F]
-~r~Ci è scappato! Facciamo secco quel bastardo muso giallo!!!
+[CRD140A]
+BLAYNE PERRY
-[YD2_G1]
-~w~Hepburn Heights... Facciamo fuori qualche lurido Diablo...
+[CRD140B]
+JONATHON SALE
-[YD2_G2]
-~w~Ma ricorda: ~r~non pensare di uscire da quest'auto!
+[CRD140C]
+CHARLES TUCKER
-[YD2_H]
-~w~OK, riportaci nel territorio di Yardie! VIA VIA VIA!!!
+[CRD140D]
+EDDIE MARRERO
-[YD2_L]
-~w~Bel lavoro, Cecchino!
+[CRD140E]
+WILLIAM MCCALL
-[YD2_M]
-~r~Ha distrutto la mia auto! Fallo secco!
+[CRD140F]
+JORGE PUPO
-[YD2_N]
-~w~Rimetti il culo in macchina!
+[CRD140G]
+ROBERT JACKSON
-[YD3_A]
-Devi rubare alcune auto delle gang avversarie
+[CRD140H]
+TARA RADCLIFFE
-[YD3_A1]
-per poter colpire nel loro territorio.
+[CRD140I]
+JENIFER GAMBETESE
-[YD3_B]
-Mi serve una Sentinel della Mafia,
+[CRD140J]
+KRIS ACHEVARRIA
-[YD3_B1]
-una Stinger della Yakuza e uno
+[CRD140K]
+ALI ORDOUBADI
-[YD3_B2]
-Stallion dei Diablo per poter attaccare qualunque gang di Liberty.
+[CRD140L]
+KAHLEEM POOLE
-[YD3_C]
-Parcheggiale nel garage a Newport e ricorda,
+[CRED141]
+DIALOGHI PEDONI
-[YD3_C1]
-se le distruggi sono inutilizzabili!
+[CRD141A]
+SCRITTI DA DAN HOUSER, MARC FERNANDEZ, GILLIAN TELLING E NAVID KHONSARI
-[YD3_D]
-Etichetta testo aggiuntiva
+[CRD141B]
+CON L'AIUTO DI JEREMY POPE, LANCE WILLIAMS E JENNY JEMISON
-[YD3_E]
-~r~Hai già rubato un'auto dei Diablo!
+[CRED142]
+SCRITTI DA
-[YD3_F]
-~r~Hai già rubato un'auto della Mafia!
+[CRD142A]
+DAN HOUSER E JAMES WORRALL
-[YD3_G]
-~r~Hai già rubato un'auto della Yakuza!
+[CRED143]
+DIRETTI DA DAN HOUSER, CRAIG CONNER, MARC FERNANDEZ E ALLAN WALKER
-[YD3_H]
-~g~Auto dei Diablo rubata!
+[CRED144]
+PRODOTTI DA RENAUD SEBANNE
-[YD3_I]
-~g~Auto della Mafia rubata!
+[CRED145]
+PEDONI
-[YD3_J]
-~g~Auto della Yakuza rubata!
+[CRED146]
+ADAM DAVIDSON, ADAM WATKINS, ALEJANDRO K. BROWN, ALEX ANTHONY SIOUKAS, ALEX GARCIA,
-[YD3_K]
-~r~L'auto è quasi un rottame! Falla riparare!
+[CRED147]
+ALICE SALTZMAN, ALISON CIHRA, AMY SALIMA, AMY SALZMAN, ANDREA VIDELA, ANTHONY ATTI,
-[YD3_L]
-~g~Portala al ~p~garage!
+[CRED148]
+ANTHONY RIVERA, BIJAN SHAMS, BLAYNE PERRY, BRETT BISOGNO, BREYE MATA, BRIAN PANEN,
-[YD3_M]
-~r~Hai cappottato l'auto! Procuratene un'altra!
+[CRED149]
+BROCK VODER, CAREY BERTINI, CHARISSE LAMBERT, CHRIS DIFAT, CHRIS REISENBERGER,
-[YD4_A]
-Stammi a sentire!
+[CRED150]
+CHRISTOPHER BRODAY, CHRISTOPHER CARRO, CYNTHIA GREENE, DAMARIES LOPEZ, DAN LEE,
-[YD4_A1]
-Arriva fino a Bedford Point.
+[CRED151]
+DAN SCHNEIDER, DAN TOYAMA, DAVID DEAN CHALTFIELD, JR., DAVID HARRISON, DAVID WILEY,
-[YD4_A2]
-C'è della roba nascosta in una vecchia automobile che mi serve subito!
+[CRED152]
+DEBORAH COLLINS, DEBRANDA CHANEY-GILES, DEMETRA KOUKOULAS, DENISE ROSADO,
-[YD4_B]
-LETTERA: Ho saputo che ti sei dato da fare. Beh mi sono data da fare anch'io.
+[CRED153]
+DEVIN BENNETT, DEVIN WINTERBOTTOM, DORIS WOO, DOUGLAS HARRISON, DUNCAN COUTTS,
-[YD4_C]
-Credo sia ora che tu provi il vero potere dello 'SPANK'! Baci e abbracci, Catalina, con amore.
+[CRED154]
+DUPE AJAYI, EDWIN AVELLANEDA, ELIZABETH HOWELL, ELIZABETH SATTERWHITE, ERIC NAGLE,
-[YD4_D]
-PS: MUORI CANE BASTARDO, MUORI!
+[CRED155]
+ESTEBAN KARPLUS, F. FONT, FUTABA HAYASHI, GENE HILGREEN, GERALD COSGROVE,
-[YD4_1]
-Pazzi strafatti di SPANK!
+[CRED156]
+GERARD LUNA, GILLIAN TELLING, GREGG CARLUCCI, GREGORY CLERVOIX, GREGORY SCHWEIZER,
-[YD4_2]
-Distruggi i camion di SPANK!
+[CRED157]
+HADLEY TOMICKI, J. ROSSETT, JAMEEL VEGA, JASON JONES, JEFF ROSA, JENNIFER JEMISON,
-[HM_1]
-'SOLDI E UZI'
+[CRED158]
+JEREMY TAGGERT, JESSICA RIDER, JOSEPH GREENE,JOSEPH HOWELL, KATE DUKICH,
-[HM_2]
-'STERMINATOR'
+[CRED159]
+KEL O'NEILL, KEVIN HOPKINS, LADAWN JAMES, LANCE WILLIAMS, LAURA BUBBLES,
-[HM_3]
-'PRONTO A ESPLODERE'
+[CRED160]
+LAURA PATTERSON, LEE CUMMINGS, LETICIA L. YOUNG, LINDSAY KENNEDY, LISA ORITZ,
-[HM_5]
-'RISSA'
+[CRED161]
+LORNA JORDAN, LUCIO AMADIO, MARCO FERNANDEZ, MARIKO TANAKA, MARLON MATTHEWS,
-[HOOD1_A]
-Raggiungi il telefono pubblico dei giardini Wichita se vuoi parlare d'affari.
+[CRED162]
+MARY TELLING, MASAYOSHI MITSUYAMA, MATTHEW CHUNG, MAX ALLSTADT, MAX BOGDANOV,
-[HM1_A]
-Ehi, sono D-Ice dei Red Jack!
+[CRED163]
+MELISSA ALVAREZ, MICHAEL MAY, MICHAEL ROTHSTEIN, MIGUEL VIDAL, MIKE FEDERLINE,
-[HM1_C]
-Questi stronzetti scorrazzano per le strade con nient'altro che armi e SPANK nella testa.
+[CRED164]
+NATALIE DESCALZO, N'GAI MEMBERS, NICOLAS MALLO, NOELLE SADLER, NORBERT MORIVAN,
-[HM1_3]
-~g~I 'Nine' controllano il territorio dei giardini Wichita.
+[CRED165]
+OSWALD GREENE, JR., PETER MCKAY, PETER APPEL, PRESTON SAVARESE, RAFAEL GONZALES,
-[HM2_3]
-Se colpisci i pneumatici, il maggiolino radiocomandato esploderà!
+[CRED166]
+RANDY JOHNSON, REY CONCEPCION, RICHARD KROGER, ROB TIBBS, ROBERT JACKSON,
-[HM2_4]
-Se supera la portata massima, il maggiolino radiocomandato esploderà!
+[CRED167]
+ROBERT SCHULER, ROSS A. MCINTYRE, RUSSELL FOREMAN, RUTH NUNEZ, SALVADORE SUAZO,
-[HM2_5]
-~r~Fuori dalla portata massima!
+[CRED168]
+SAM WHITE, SANTOS GONZALES, SCOTT SMITH, SEYMOUR FRAILMAN, SPELMAN BRAUMAN,
-[HM3_1]
-~g~Vai al garage, ma stai attento: se l'auto viene danneggiata troppo, salterà in aria!
+[CRED169]
+STEPHANIE TELLING, STEVE KNEZEVICH, STEVE ROBERT, SUMIKO YASUDA, SUSAN LEWIS,
-[HM3_2]
-~g~Riporta l'auto in ottime condizioni: nessun danno!
+[CRED170]
+SYLVIA COLACIOS, TOMOKO MIYAZAKI, TRON, VERDEL HALE, YVES MONDESIR, ZENO LEINFELDER,
-[HM3_3]
-~g~Fai riparare l'auto!
+[CRED171]
+DAVID BEDDOES, CHRISTINE CHALMERS, BARRY CLARK, NEIL CORBETT, KIM GURNEY, NEIL MEIKLE,
-[HM4_D]
-~g~Prendi un veicolo!
+[CRED172]
+CASSIE OLIVER, LORRAINE ROY, DAVID WATSON, KEVIN WONG, WILL MORTON
-[HM4_E]
-TESTO NON PIÙ NECESSARIO
+[CRED175]
+ADAM DAVIDSON
-[HM4_1]
-~g~Dirigiti nel posto dove il carico s'è rovesciato: dovrai raccogliere almeno 30 lingotti.
+[CRED176]
+LANCE WILLIAMS
-[HM4_2]
-~g~Ricorda di raggiungere il garage e depositare il carico quando il veicolo diventa troppo pesante e lento.
+[CRED177]
+NEIL MCCAFFREY
-[HM5_3]
-~r~Dovevi usare solo una mazza da baseball!
+[CRED178]
+LAURA PATERSON
-[HM5_4]
-~r~Il tuo intermediario è morto!
+[CRED179]
+REY CONCEPCION
-[MEA1]
-'L'IMBROGLIONE'
+[CRED180]
+CHARLES HEROLD
-[MEA2]
-'I LADRI'
+[CRED181]
+ANDREW GREENWALD
-[MEA3]
-'LA MOGLIE'
+[CRED182]
+JAMES MIELKE
-[MEA4]
-'L'AMANTE'
+[CRED183]
+PETER SUCIU
-[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.
+[CRED184]
+ALEX ODULIO
-[MEA1_B3]
-~g~Devi incontrare il direttore della banca.
+[CRED185]
+DON NKRUMAH
-[MEA1_B6]
-~g~Porta l'auto dal rottamatore per distruggere le prove: esci dall'auto e la gru la raccoglierà.
+[CRED186]
+KENDALL PITTMAN
-[MEA1_1]
-~r~Il direttore della banca è morto!
+[CRED187]
+SAL SUAZO
-[MEA1_2]
-~r~Ti era stato detto di rottamare il veicolo!
+[CRED188]
+EREK MATEO
-[MEA1_3]
-~g~Esci dalla macchina!
+[CRED189]
+CHRIS DIFATE
-[MEA1_4]
-~r~Ti sei dimenticato del direttore della banca!
+[CRED190]
+LEILA MILTON
-[MEA2_B3]
-~g~Vai a incontrare i ladri.
+[CRED191]
+DARREN ZOLTOWSKI
-[MEA2_B4]
-~g~Accompagnali alla fabbrica di cibo per cani Bitch'n' Dog.
+[CRED192]
+VIRGINIA SMITH
-[MEA2_B6]
-~g~Fai riverniciare l'auto per eliminare ogni prova.
+[CRED193]
+KEVIN CASSIN
-[MEA2_1]
-~r~Ti era stato detto di far rottamare il veicolo!
+[CRED194]
+JASON SHIGEMORI
-[MEA2_2]
-~r~Un ladro è morto!
+[CRED195]
+KELLY KINSELLA
-[MEA2_4]
-~r~Ti sei dimenticato un ladro!
+[CRED196]
+MOLLIE STICKNEY
-[MEA3_B3]
-~g~Vai a prelevare la signora Chonks.
+[CRED197]
+STANTON SARJEANT
-[MEA3_B6]
-~g~Prendi l'auto e scaricala in mare: questo cancellerà ogni prova.
+[CRED198]
+LAURA WALSH
-[MEA3_1]
-~r~La moglie è morta!
+[CRED199]
+MARK GARONE
-[MEA3_2]
-~r~Dovevi scaricare il veicolo in mare!
+[CRED200]
+JOANNA SLY
-[MEA3_3]
-~r~Ti sei dimenticato di della moglie!
+[CRED201]
+ELIZABETH HOWELL
-[MEA4_B3]
-~g~Vai a prendere l'amante della moglie.
+[CRED202]
+ANA HERCULES
-[MEA4_B6]
-È davvero troppo tardi per farlo, Marty. Ti ho dato una chance, ma adesso prenderò io il controllo del tuo business...
+[CRED203]
+SHIRLEY IRICK
-[MEA4_1]
-~r~Carlos è morto!
+[CRED204]
+KASHONA FIELDS
-[MEA4_3]
-~r~Ti sei dimenticato di Carlos lo strozzino!
+[CRED205]
+JOEL M. LILJE
-[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~.
+[CRED206]
+JOHN DIBENEDETTO
-[LOVE6_1]
-~g~Adesso attira gli sbirri lontano dai magazzini!
+[CRED207]
+NANCY GILES
-[LOVE6_2]
-~r~Non sei riuscito ad attirare gli sbirri abbastanza lontano!
+[CRED208]
+RYAN CROY
-[RM4_3]
-~r~Il socio di Ray è fuggito!
+[CRED209]
+JENNIFER KOLBE
-[RM6_C]
-La CIA sembra interessata allo SPANK
+[CRED210]
+LIAM BURKE
-[RM6_C1]
-e non vogliono che interferiamo con il Cartello.
+[CRED211]
+SIGRID PREISSL
-[C_PASS]
-MINACCIA ELIMINATA!
+[CRED212]
+ANITA FITZSIMONS
-[CTUTOR]
-Premi il ~h~tasto ~k~~TOGGLE_SUBMISSIONS~~w~ per attivare o disattivare le missioni Vigilante.
+[CRED213]
+PHILIPPA RASELLI
-[CTUTOR2]
-Premi il ~h~tasto ~k~~TOGGLE_SUBMISSIONS~~w~ per attivare o disattivare le missioni Vigilante.
+[CRED214]
+WIL QUESNEL
-[COPCART]
-~g~Hai ~1~ secondi per tornare a un mezzo della polizia prima che termini la missione.
+[CRED215]
+FALKO BURKERT
-[C_FAIL]
-Missione Vigilante terminata!
+[CRED216]
+SARA SEWELL
-[C_CANC]
-~r~Missione Vigilante annullata!
+[CRED217]
+STAZIONI RADIO E MUSICA
-[C_ESCP]
-~r~Il sospetto è fuggito!
+[CRED218]
+CONSULENZA MUSICALE
-[C_TIME]
-~r~È scaduto il tuo tempo come tutore della legge!
+[CRD218A]
+HEINZ HENN
-[C_VIGIL]
-BONUS VIGILANTE!
+[CRD218B]
+STUART ROSS
-[A_FAIL2]
-~r~La tua scarsa sollecitudine è stata fatale al paziente!
+[CRED219]
+COORDINATORE TRACCE AUDIO
-[A_FAIL3]
-~r~Il paziente è morto!
+[CRED220]
+TERRY DONOVAN
-[A_PASS]
-Salvato!
+[CRED221]
+PRODUTTORI ROCKSTAR GAMES
-[F_FAIL2]
-~r~Sei arrivato tardi!
+[CRED222]
+DAN HOUSER E LAZLOW
-[A_COMP2]
-Non ti stancherai mai!
+[CRED223]
+PRODUTTORE ROCKSTAR NORTH
-[RM2_M]
-Se ti servono armi da fuoco, passa di qui e prendi ciò che ti serve dagli armadietti.
+[CRED224]
+CRAIG CONNER
-[HEAL_A]
-La tua ~h~salute~w~ è indicata in color arancione in alto a destra sullo schermo.
+[CRED225]
+ALLAN WALKER
-[YD1_CNT]
-~1~ su 15!
+[CRED226]
+LAZLOW
-[FM1_9]
-~g~Lì davanti c'è il party: fai scendere Maria all'ingresso.
+[CRED227]
+DJ BANTER E IMAGING
-[FM1_Y]
-~w~Sai, non mi divertivo così tanto da una vita, e mi hai trattato proprio bene. Con molto rispetto.
+[CRED228]
+SCRITTO DA DAN HOUSER E LAZLOW
-[FM1_AA]
-~w~Oh, devo andare. Spero di rivederti.
+[CRED229]
+FLASH FM
-[NOCONTE]
-Ricollega il controller analogico (DUALSHOCK#) o controller analogico (DUALSHOCK#2) all'ingresso controller 1 per continuare.
+[CRD229A]
+TONI-MARIA CHAMBERS
-[WRCONT]
-Il controller collegato all'ingresso controller 1 non è supportato. Grand Theft Auto III richiede un controller analogico (DUALSHOCK#) o (DUALSHOCK#2).
+[CRD229B]
+VOCE E PRODUZIONE IMAGING - JEFF BERLIN
-[WRCONTE]
-Il controller collegato all'ingresso controller 1 non è supportato. Grand Theft Auto III richiede un controller analogico (DUALSHOCK#) o controller analogico (DUALSHOCK#2).
+[CRED230]
+UN RINGRAZIAMENTO SPECIALE A
-[WRONGCD]
-Disco errato. Inserisci il disco corretto.
+[CRED231]
+TOMMY MOTTOLA,
-[NOCD]
-Il vano cassetto del disco è vuoto. Inserisci il disco.
+[CRED232]
+MICHELLE ANTHONY,
-[OPENCD]
-Il vano cassetto del disco è aperto. Chiudi il vano.
+[CRED233]
+STEVE BARNETT,
-[CDERROR]
-Errore di lettura del DVD Grand Theft Auto III.
+[CRED234]
+CHUCK FLECKENSTEIN,
-[RESTART]
-Avvio di una nuova partita
+[CRED235]
+RITA LIBERATOR
-[GA_3]
-Niente più sconti. $1000 per la riverniciatura!
+[CRED236]
+MARTIN & CLAIRE LOGAN
-[GA_1]
-Wow! Non tocco niente di COSÌ caldo!
+[CRED237]
+SANDRA HUTTON
-[GA_1A]
-Torna quando non sarai così occupato...
+[CRED238]
+CHRISTINE DAVIDSON
-[S_PROM2]
-Nel garage qua accanto puoi parcheggiare un veicolo quando salvi la partita.
+[CRED239]
+ALAN, RED & BIGFOOT
-[STOCK]
-scorte esaurite
+[CRED240]
+LE T
-[FM1_O]
-~w~Credo si trovi alla stazione vicino al porto di Chinatown.
+[CRED241]
+COLIN DONALD
-[EBAL_B]
-Siamo arrivati, togliamoci dalla strada e cerchiamo di cambiarci d'abito!
+[CRED242]
+KERRY STALLWOOD
-[EBAL_G]
-Questo è il club Luigi's. Passiamo dal retro attraverso la porta di servizio.
+[CRED243]
+ALAN MCGREGOR
-[AM4_3]
-Tu devi essere il nuovo tuttofare di Asuka!
+[CRED244]
+CHRIS MORTON
-[AM4_4]
-Hai i soldi? Tutto qui?
+[CRED245]
+EMIL BUSSE
-[AM4_5]
-So cosa pensi, un altro sbirro corrotto.
+[CRED246]
+EMILY BAILLIE
-[AM4_6]
-Beh, il mondo è corrotto.
+[CRED247]
+KEVIN ARCHIBALD
-[AM4_7]
-Solo perché ho perso dei partner, quegli idioti degli Affari Interni hanno cominciato a curiosare.
+[CRED248]
+MORAG KERR
-[AM4_8]
-Immagino che sentano puzza di bruciato.
+[CRED249]
+CATH WALKER
-[AM4_9]
-Beh, questa città è una grande fogna.
+[CRED250]
+ISO BAR
-[AM4_10]
-Mi servirà aiuto anche fuori dai sindacati.
+[CRED251]
+WATERLINE
-[AM4_11]
-Se sei interessato, sai dove trovarmi.
+[CRED252]
+NEWS CAFE
-[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.
+[CRD251A]
+THE POND
-[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.
+[CRD252A]
+PIVO
-[KM2_1]
-~g~Ripara l'auto, sarà come nuova.
+[CRED253]
+BUDGET VIDEO RENTALS
-[LM3_6]
-Joey...
+[CRED254]
+LORNA'S SCOOTER
-[LM3_6A]
-Mi farai giocare ancora col tuo pistone?
+[CRED255]
+GARETH MURFIN
-[LM3_9A]
-Potrebbe esserci del lavoro per te.
+[CRED256]
+GRAFICA ADDIZIONALE
-[LM3_9B]
-OK?
+[CRED257]
+TONY PORTER
-[AWAY2]
-~r~Sono scappati.
+[CRED258]
+CRAIG MOORE
-[AWAY]
-~r~È scomparso nel nulla!
+[CRED259]
+SINCRONIZZAZIONE LABIALE SEQUENZE
-[JM6_1]
-Raggiungi la banca sulla strada principale.
+[CRED260]
+COSGROVE HALL FILMS
-[GA_6B]
-Parcheggiala, innesca la bomba schiacciando il ~h~tasto ~k~~PED_FIREWEAPON~~w~ e BATTITELA!
+[CRED261]
+PRODUTTORE - OWEN BALLHATCHET
-[GA_7B]
-Innescala col ~h~tasto ~k~~PED_FIREWEAPON~~w~. La bomba esploderà quando si tenterà di avviare il motore.
+[CRED262]
+ANIMATORE SENIOR- JON TURNER
-[BAT1]
-~g~Prendi la mazza!
+[CRED263]
+ANIMATORI - RICHARD DRUMM
-[EBAL_O]
-Se andrà tutto liscio, forse potrei darti altro lavoro. Adesso fuori di qui!
+[CRED264]
+DAVE BROWN
-[HELP9_B]
-Premere il ~h~tasto ~k~~PED_FIREWEAPON~~w~ per ~h~sparare~w~ col fucile di precisione.
+[CRED265]
+MAIR THOMAS
-[HELP9_C]
-Premere il ~h~tasto ~k~~PED_FIREWEAPON~~w~ per ~h~sparare~w~ col fucile di precisione.
+[CRED266]
+PRASHANT PATEL
-[JM6_8]
-~r~Hai perso tutti i rapinatori!
+[CRED267]
+CONSULENTE TECNOLOGICO AUDIO
-[COLT_IN]
-La pistola è adesso disponibile da AmmuNation!
+[CRED268]
+RIK EDE DI GAMESOUND LTD.
-[TAXI2]
-~r~Tempo scaduto!
+[CRED269]
+SUPPORTO INTEGRAZIONE DTS
-[TAXI3]
-~r~Il passeggero è fuggito terrorizzato!
+[CRED270]
+TED LAVERTY DI DTS
-[TAXI7]
-~r~La tua auto è distrutta, falla riparare.
+[CRED271]
+CHRIS GREER DI DTS
-[TAXI4]
-Tariffa completa!
+[CRED272]
+JASON PAGE DI DTS
-[TAXI5]
-BONUS VELOCITÀ!
+[CRED273]
+RICERCA E ANALISI
-[TAXI6]
-Missione taxi terminata
+[CRED274]
+VROCK
-[FRANGO]
-~g~Salvatore vuole che tu aiuti prima Toni ad affrontare le Triadi!
+[CRED275]
+DJ: LAZLOW COME SE STESSO
-[PAGEB12]
-Tangente per la Polizia consegnata al nascondiglio
+[CRED276]
+VOCE IMAGING - JOE KELLY
-[PAGEB13]
-Salute consegnata al nascondiglio
+[CRED277]
+PRODUZIONE IMAGING - JONATHAN HANST
-[PAGEB14]
-Adrenalina consegnata al nascondiglio
+[CRED278]
+WAVE 103
-[KM1_4]
-~g~Ti serve un'auto della polizia per svolgere il lavoro!
+[CRED279]
+DJ: ADAM FIRST - JAMIE CANFIELD
-[CAT1_B]
-Porta 500.000$ alla Villa a Cedar Grove.
+[CRED280]
+VOCE IMAGING - JEN SWEENEY
-[JM2_C]
-Ha un chiosco di spaghetti cinesi a China Town.
+[CRED281]
+PRODUZIONE IMAGING - JONATHAN HANST
-[RM6_1]
-Eccoti la chiave di un deposito.
+[CRED282]
+FEVER 105
-[RM6_2]
-Troverai del denaro e alcune 'dotazioni' da utilizzare nei momenti difficili.
+[CRED283]
+DJ: OLIVER 'LADYKILLER' BISCUIT - JULIUS DYSON
-[RM6_3]
-Ci vediamo.
+[CRED284]
+VOCE IMAGING MASCHILE - ED MCMANN
-[FE_INIP]
-Inizializzazione e caricamento menu pausa... Un momento.
+[CRED285]
+VOCE IMAGING FEMMINILE - SHAWNEE SMITH
-[FESZ_CA]
-Annulla
+[CRED286]
+PRODUZIONE IMAGING - LISTEN KITCHEN
-[FESZ_QU]
-Esci
+[CRED287]
+EMOTION 98.3
-[FESZ_L1]
-Partita salvata con successo!
+[CRED288]
+DJ: FERNANDO - FRANK CHAVEZ
-[FESZ_L2]
-Il nome del file salvato è:
+[CRED289]
+VOCE IMAGING - JEN SWEENEY
-[FESZ_OK]
-OK
+[CRED290]
+PRODUZIONE IMAGING - JONATHAN HANST
-[FES_LGA]
-Carica partita
+[CRED291]
+RADIO ESPANTOSO
-[FES_NGA]
-Nuova partita
+[CRED292]
+DJ: PEPE - TONY CHILRODES
-[FES_CAN]
-Annulla
+[CRED293]
+WILDSTYLE
-[FESZ_QL]
-Tutti i progressi della partita attuale non ancora salvati andranno perduti. Vuoi procedere con il caricamento?
+[CRED294]
+DJ: MISTER MAGIC COME SE STESSO
-[FESZ_QD]
-Vuoi eliminare questa partita salvata?
+[CRED295]
+VOCE IMAGING - FRANK SILVESTRO
-[FESZ_QO]
-Vuoi procedere con la sovrascrittura di questa partita salvata?
+[CRED296]
+PRODUZIONE IMAGING - LAZLOW
-[FESZ_QR]
-Sei sicuro di voler iniziare una nuova partita? Tutti i progressi fatti fino all'ultimo salvataggio andranno perduti. Vuoi procedere?
+[CRED297]
+KCHAT
-[FESZ_QS]
-VUOI PROCEDERE CON IL SALVATAGGIO?
+[CRED298]
+SCRITTA DA DAN HOUSER E LAZLOW
-[SLONFP]
-Ingresso 1. File protetto.
+[CRED299]
+PRODOTTA E MIXATA DA LAZLOW
-[T4X4_1]
-'CAMPO DEL PATRIOTA'
+[CRED300]
+DJ AMY SHECKENHAUSEN - LEYNA WEBER
-[T4X4_2]
-'UN GIRO NEL PARCO'
+[CRED301]
+JEZ TORRENT - KEVIN MCKIDD
-[T4X4_3]
-'AFFERRATO'
+[CRED302]
+MANDY - COLLEEN CORBETT
-[MM_1]
-'MASSACRO NEL PALAZZO'
+[CRED303]
+MICHELLE CARAPADIS - MARY BIRDSONG
-[T4X4_1A]
-~g~Hai ~y~5 minuti~g~ per attraversare ~y~15~g~ punti di controllo. ~g~Puoi attraversarli in ~y~QUALSIASI ORDINE~g~.
+[CRED304]
+MR.ZOO - CARL DOWLING
-[T4X4_1B]
-~1~ su 15!
+[CRED305]
+GETHSEMANEE - LYNN LIPTON
-[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.
+[CRED306]
+CLAUDE MAGINOT - JOHN MAUCERI
-[T4X4_2A]
-~g~Hai ~y~2 minuti~g~ per attraversare ~y~12~g~ punti di controllo!!! ~g~Puoi attraversarli in ~y~QUALSIASI ORDINE~g~.
+[CRED307]
+BJ SMITH - LAWRENCE TAYLOR
-[T4X4_2B]
-~1~ su 12!
+[CRED308]
+THOR - FRANK FAVA
-[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.
+[CRED309]
+VOCI PUBBLICITÀ
-[T4X4_3A]
-~g~Hai ~y~5 minuti~g~ per attraversare ~y~20~g~ punti di controllo!!! ~g~Puoi attraversarli in ~y~QUALSIASI ORDINE~g~.
+[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_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.
+[CRED311]
+LEWIS, GILLIAN TELLING, TOM MURRAY, MIKE FERRANTE SR., EMMANUEL GOLDSTEIN,
-[T4X4_3C]
-~1~ su 20!
+[CRED312]
+DAN HOUSER, NICK MANDELOS, GERRY COSGROVE, MIKE PALERMO, PORKCHOP,
-[T4X4_F]
-~r~Sei scappato! Troppo difficile per te?
+[CRED313]
+KEITH BROADAS
-[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~.
+[CRED314]
+VCPR
-[MM_1_B]
-~1~ su 20!
+[CRED315]
+SCRITTO DA DAN HOUSER E LAZLOW
-[MM_1_C]
-~g~Sono 20 secondi più ~y~5 secondi~g~ per ogni punto di controllo. ~g~Il timer partirà ~y~IMMEDIATAMENTE~g~.
+[CRED316]
+PRODOTTO DA LAZLOW
-[FM2_14]
-~r~Ti sei avvicinato troppo e hai spaventato Ricciolino!
+[CRED317]
+MAURICE CHAVEZ - PHILLIP ANTHONY RODRIGUEZ
-[FM2_15]
-~g~Non ti avvicinare troppo o Ricciolino si insospettirà!
+[CRED318]
+JONATHAN FREELOADER - PATRICK OLSEN
-[UPSIDE]
-~r~Hai cappottato la macchina!
+[CRED319]
+MICHELLE MONTANIUS - KELLY GUEST
-[FM2_16]
-PAURIMETRO:
+[CRED320]
+DEP. ALEX SHRUB - CHRIS LUCAS
-[LM3_11]
-~g~Misty non sale su un autobus, prendi un altro veicolo!
+[CRED321]
+CALLUM CRAYSHAW - SEAN MODICA
-[LANDSTK]
-Landstalker
+[CRED322]
+JOHN F. HICKORY - LJ GANSEN
-[IDAHO]
-Idaho
+[CRED323]
+PASTOR RICHARDS - DAVID GREEN
-[STINGER]
-Stinger
+[CRED324]
+JAN BROWN - MAUREEN SILLIMAN
-[LINERUN]
-Linerunner
+[CRED325]
+BARRY STARK - RENAUD SEBBANE
-[PEREN]
-Perennial
+[CRED326]
+JENNY LOUISE CRAB - MARY BIRDSONG
-[SENTINL]
-Sentinel
+[CRED327]
+KONSTANTINOS SMITH - KONSTANTINOS.COM
-[PATRIOT]
-Patriot
+[CRED328]
+JEREMY ROBARD - PETER SILVESTRO
-[FIRETRK]
-Camion dei pompieri
+[CRED329]
+PUBBLICITÀ RADIO
-[TRASHM]
-Trashmaster
+[CRED330]
+SCRITTE DA DAN HOUSER E LAZLOW
-[STRETCH]
-Stretch
+[CRED331]
+PRODOTTE DA LAZLOW
-[MANANA]
-Manana
+[CRED332]
+JINGLE AGGIUNTIVI PRODOTTI DA CRAIG CONNER
-[INFERNS]
-Infernus
+[CRED333]
+VOCI PUBBLICITÀ
-[BLISTA]
-Blista
+[CRED334]
+ADAM DAVIDSON, ALEX ANTHONY, ALICE SALTZMAN, AMY SALZMAN, KATE DUKICH,
-[PONY]
-Pony
+[CRED335]
+ARAN RONICLE, BARB JONES, BEN KRECH, BRIAN THOMAS, BROCK YODER, CHRIS
-[MULE]
-Mulo
+[CRED336]
+FERRANTE, CRAIG CONNER, DAVE RYAN, DAVID GREEN, DORIS WOO, DOUGLAS
-[CHEETAH]
-Cheetah
+[CRED337]
+HARRISON, ED MCMANN, FRANK CHAVEZ, FRANK FAVA, GENE HILGREEN, GREG
-[AMBULAN]
-Ambulanza
+[CRED338]
+SCHWEIZER, HUNTER PLATIN, JAMES FERRANTE, JEFF BERLIN, JEFF ROSA, JOE KELLY,
-[FBICAR]
-F.B.I.
+[CRED339]
+JOHN MAUCERI, JOSH CLARK, JULIE WEMYSS, KEVIN STRALEY, KIM GURNEY, LANCE
-[MOONBM]
-Moonbeam
+[CRED340]
+WILLIAMS, LAURA PATERSON, LAZLOW, LISA ORTIZ, LORNA JORDAN, LUCIEN JONES,
-[ESPERAN]
-Esperanto
+[CRED341]
+MAUREEN SILLIMAN, MIKE FERRANTE JR., PETE GUSTIN, PETER SILVESTRO, RAFF
-[TAXI]
-Taxi
+[CRED342]
+CROLLA, RANDY JOHNSON, RICHARD KRUGER, RON REEVE, SHELLEY MILLER, SKY, TJ ALLARD
-[KURUMA]
-Kuruma
+[CRD344A]
+AUDIO REGISTRATO PRESSO DIGITAL ARTS STUDIOS,
-[BOBCAT]
-Bobcat
+[CRED344]
+NYC, TRACK 9 STUDIOS, NYC,
-[WHOOPEE]
-Mr Whoopee
+[CRED345]
+WEDDINGTON MULTIMEDIA, LOS ANGELES,
-[BFINJC]
-BF Injection
+[CRD345A]
+SYNC SOUND, NYC E RADIO LAZLOW, LONG ISLAND.
-[POLICAR]
-Polizia
+[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
-[ENFORCR]
-Cellulare
+[CRED347]
+MARK LLOYD
-[SECURI]
-Securicar
+[CRED348]
+TIM BATES
-[BANSHEE]
-Banshee
+[CRED349]
+KIT BROWN
-[PREDATR]
-Predator
+[CRED350]
+ANDY MASON
-[BUS]
-Bus
+[CRED351]
+PHIL DEANE
-[RHINO]
-Rhino
+[CRED352]
+PHIL ALEXANDER
-[BARRCKS]
-Caserma OL
+[CRED353]
+MATT HEWITT
-[TRAIN]
-Treno
+[CRED354]
+DENBY GRACE
-[HELI]
-Elicottero
+[CRED355]
+ANTOINE CABROL
-[DODO]
-Dodo
+[CRED356]
+JONOTHAN STONES
-[COACH]
-Coach
+[CRED357]
+MIKE BLACKBURN
-[CABBIE]
-Cabbie
+[CRED358]
+TIM MCGAFF
-[STALION]
-Stallion
+[CINCAM]
+Camera mobile
-[RUMPO]
-Rumpo
+[RC4]
+'LA FURIA DI RUMPO'
-[RCBANDT]
-Bandito RC
+[LEGAL]
+~g~Elimina la minaccia criminale!
-[BELLYUP]
-Triad
+[GA_2]
+Motore nuovo e carrozzeria riverniciata. Gli sbirri non ti riconosceranno!
-[MRWONGS]
-Mr Wongs
+[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~.
-[MAFIACR]
-Mafia
+[FEC_LB4]
+Guarda indietro (tasto R3)
-[YARDICR]
-Yardie
+[PERPIC]
+Pacchetti speciali recuperati
-[YAKUZCR]
-Yakuza
+[CO_ONE]
+Pacchetto speciale ~1~ su ~1~
-[DIABLCR]
-Diablo
+[GA_21]
+Non puoi parcheggiare altri veicoli in questo garage.
-[COLOMCR]
-Cartel
+[CHEAT1]
+Trucco attivato
-[HOODSCR]
-Hoods
+[CHEAT2]
+Trucco armi
-[AEROPL]
-Aeroplano
+[CHEAT3]
+Trucco salute
-[SPEEDER]
-Speeder
+[CHEAT4]
+Trucco armatura
-[REEFER]
-Reefer
+[CHEAT5]
+Trucco livello di sospetto
-[PANLANT]
-Panlantic
+[CHEAT6]
+Trucco soldi
-[FLATBED]
-Flatbed
+[CHEAT7]
+Trucco tempo atmosferico
-[YANKEE]
-Yankee
+[USJ_ALL]
+TUTTE LE ACROBAZIE UNICHE COMPLETATE
-[BORGNIN]
-Borgnine
+[JAN]
+Gen
-[TOYZ]
-TOYZ
+[FEB]
+Feb
-[FEST_DF]
-Distanza percorsa a piedi (miglia)
+[MAR]
+Mar
-[FEST_DC]
-Distanza percorsa in auto (miglia)
+[APR]
+Apr
-[FESTDFM]
-Distanza percorsa a piedi (m)
+[MAY]
+Mag
-[FESTDCM]
-Distanza percorsa in auto (m)
+[JUN]
+Giu
-[FEST_R1]
-Campo del Patriota (secondi)
+[JUL]
+Lug
-[FEST_R2]
-un Giro nel Parco (secondi)
+[AUG]
+Ago
-[FEST_R3]
-Afferrato! (secondi)
+[SEP]
+Set
-[FEST_RM]
-Massacro Multi-livello (secondi)
+[OCT]
+Ott
-[FEST_LS]
-Persone salvate in ambulanza
+[NOV]
+Nov
-[FEST_CC]
-Missione Vigilante - Criminali uccisi
+[DEC]
+Dic
-[FEST_FE]
-Totale incendi spenti
+[DEFDT]
+--:---:---- --:--:--
-[FEST_LF]
-Volo più lungo nel Dodo
+[BONUS]
+~g~BONUS ~1~$
-[FEST_BD]
-Disinnesco bomba - Miglior tempo
+[HORN1]
+Premi il ~h~~k~~VEHICLE_HORN~~w~ per attivare il ~h~clacson~w~.
-[FEST_RP]
-Violenze eseguite
+[HORN2]
+Premi il ~h~~k~~VEHICLE_HORN~~w~ per attivare il ~h~clacson~w~.
-[FEST_MP]
-Missioni eseguite
+[HORN3]
+Premi il ~h~~k~~VEHICLE_HORN~~w~ per attivare il ~h~clacson~w~.
-[FEST_BB]
-Bling-bling Scramble:
+[FEC_EXV]
+Esci dal veicolo
-[FEST_H0]
-Maggior numero di checkpoints
+[TAXI_M]
+'TAXI DRIVER'
-[FEST_GC]
-Auto delle gang distrutte:
+[COP_M]
+'VIGILANTE'
-[FEST_H1]
-Distruzione Diablo
+[FIRE_M]
+'POMPIERE'
-[FEST_H2]
-Massacro Mafioso
+[AMBUL_M]
+'INFERMIERE'
-[FEST_H3]
-Calamità al Casinò
+[HJ_IS]
+BONUS ACROBAZIA FOLLE: ~1~$
-[FEST_H4]
-Demolizioni Rumpo
+[HJ_PIS]
+BONUS ACROBAZIA FOLLE PERFETTA: ~1~$
-[USJI1]
-TESTO NON PIÙ RICHIESTO
+[HJ_DIS]
+BONUS DOPPIA ACROBAZIA FOLLE: ~1~$
-[USJI2]
-TESTO NON PIÙ RICHIESTO
+[HJ_PDIS]
+BONUS DOPPIA ACROBAZIA FOLLE PERFETTA: ~1~$
-[USJI3]
-TESTO NON PIÙ RICHIESTO
+[HJ_TIS]
+BONUS TRIPLA ACROBAZIA FOLLE: ~1~$
-[USJ]
-BONUS PER ACROBAZIA UNICA!
+[HJ_PTIS]
+BONUS TRIPLA ACROBAZIA FOLLE PERFETTA: ~1~$
-[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~.
+[HJ_QIS]
+BONUS QUADRUPLA ACROBAZIA FOLLE: ~1~$
-[HM1_1]
-~g~Fredda 20 Purple Nine in 2 minuti e 30 secondi.
+[HJ_PQIS]
+BONUS QUADRUPLA ACROBAZIA FOLLE PERFETTA: ~1~$
-[KM1_8A]
-Premi il ~h~tasto ~k~~PED_FIREWEAPON~~w~ per ~h~attivare la bomba~w~: ricorda di toglierti di mezzo!
+[FESZ_LS]
+Caricamento completato.
-[KM1_8D]
-Premi il ~h~tasto ~k~~PED_FIREWEAPON~~w~ per ~h~attivare la bomba~w~: e ricorda di toglierti di mezzo!
+[HELI_1A]
+Prova le tue abilità con lo Sparrow: scopri quanto velocemente riesci a completare il percorso.
-[KM1_12]
-~g~Portalo nel dojo, ma prima sbarazzati degli sbirri!
+[HELI_1B]
+Percorso completato!
-[RATNG1]
-Borsaiolo
+[HELIODD]
+Strani incarichi con l'elicottero
-[RATNG2]
-Prepotente
+[INT2_M]
+Hanno una fattoria in Panama.
-[RATNG3]
-Teppista
+[INT2_N]
+OK, va bene, ascoltate:
-[RATNG4]
-Attaccabrighe
+[INT2_O]
+quando arriviamo volete che resti in macchina
-[RATNG5]
-Gorilla
+[INT2_P]
+o preferite che venga con voi altri?
-[RATNG6]
-Autista
+[INT2_Q]
+No, resta in macchina.
-[RATNG7]
-Aiutante
+[INT2_R]
+Lo sapete, ci ho pensato su.
-[RATNG8]
-Riparatore
+[INT2_S]
+Penso proprio che resterò in macchina.
-[RATNG9]
-Socio
+[INT4_A]
+Fottuti! Siamo fottuti!
-[RATNG10]
-Uomo delle pulizie
+[INT4_B]
+È sempre la stessa storia,
-[RATNG11]
-Assassino
+[INT4_C]
+metto fuori la testa per un maledetto secondo,
-[RATNG12]
-Braccio destro
+[INT4_D]
+e il fato mi tira palate di merda in faccia!
-[RATNG13]
-Boia
+[INT4_E]
+Bene, vaffanculo!
-[RATNG14]
-Capo
+[INT4_F]
+Smettila di fare casino e di lamentarti. Siamo vivi, non è vero?
-[RATNG15]
-Boss
+[INT4_G]
+Fammi scendere qua.
-[1010]
-~r~Il tuo veicolo si è ribaltato
+[INT4_H]
+Fai scomparire la macchina e fatti una bella dormita.
-[1011]
-~r~Il tuo veicolo si è ribaltato
+[INT4_I]
+Passerò domani a trovarti in ufficio e troveremo un modo per risolvere questo casino.
-[1012]
-~r~Il tuo veicolo si è ribaltato
+[INT4_J]
+OK, mi sembra un'ottima idea, andrò a dormire.
-[1013]
-~r~Il tuo veicolo si è ribaltato
+[INT4_K]
+Che cosa intendi fare?
-[1014]
-~r~Il tuo veicolo si è ribaltato
+[INT4_L]
+Tornare nella mia stanza,
-[JM4_10]
-OK, ragazzo. Accompagnami prima alla lavanderia di Chinatown, devo occuparmi di alcuni affari.
+[INT4_M]
+schiarirmi le idee e risolvere questo casino.
-[JM4_11]
-La donna della lavanderia non mi ha pagato i soldi del pizzo.
+[INT4_N]
+OK.
-[JM4_12]
-E bada all'auto: Joey ha appena riparato questo rottame.
+[LAW]
+MISSIONI DELL'AVVOCATO
-[JM4_13]
-Quindi, niente colpi di testa, OK?
+[LAW1_1]
+~g~Vai a prendere degli abiti nuovi dal negozio di vestiti Rafael's.
-[KM4_11]
-~g~Riporta i soldi al Casinò!
+[LAW4_6]
+Brucia l'amministrazione!
-[FEF_BR2]
-Ritrovalo leggendo i sommari di missione che hai già ricevuto.
+[LAW4_7]
+Uccidi i responsabili!
-[TRAIN_1]
-Stazione Kurowski
+[LAW4_8]
+Combattere, combattere, combattere, combattere,.
-[TRAIN_2]
-Stazione Rothwell
+[LAW4_9]
+Più ferie, meno lavoro!
-[TRAIN_3]
-Stazione Baillie
+[LAW4_11]
+Combattere, combattere, combattere, combattere,.
-[SUBWAY1]
-Stazione Portland
+[LAW4_12]
+Viva la rivoluzione.
-[SUBWAY2]
-Stazione Rockford
+[GENERAL]
+MISSIONI DEL COLONNELLO
-[SUBWAY3]
-Stazione Sud Staunton
+[GEN3_4]
+Tommy Vercetti. Andiamo...
-[SUBWAY4]
-Capolinea Shoreside
+[GEN3_13]
+Che cosa diavolo ti prende? Vai sul tetto dall'altra parte del cortile prima che arrivino!
-[MEA4_2]
-~r~Marty Chonks è morto!
+[GEN3_17]
+Meeerda! Stai cercando di ammazzarmi?
-[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.
+[GEN3_21]
+~g~Ha preso i soldi di Diaz! Inseguilo e riprendili!
-[JM4_A]
-Sì, lo so Toni, l'ho sistemata per bene. Il motore fa le fusa, non so se mi spiego.
+[GEN3_24]
+~r~Diaz è morto! Non sei riuscito a proteggerlo!
-[JM4_5]
-Ripassa più tardi e darò loro qualcosa da lavare... i panni macchiati del loro sangue!
+[GEN3_26]
+~r~Hai ucciso Diaz!
-[AMMU_A]
-Luigi dice che ti serve 'un ferro del mestiere'...
+[GEN3_27]
+~r~Hai ucciso una guardia di Diaz!
-[AMMU_B]
-Joey mi ha detto di equipaggiarti...
+[GEN3_31]
+~g~Vai all'appuntamento e proteggi Diaz.
-[AMMU_C]
-Vai sul retro del negozio. Ti ho lasciato una calibro nove in cortile.
+[GEN3_32]
+~g~Raggiungi il tetto nell'edificio di fronte a Lance e appostati.
-[AMMU_D]
-Ho tutto quello che ti serve per la tua auto-difesa.
+[COKE]
+MISSIONI DEL BARONE DELLA COCA
-[AMMU_E]
-Vuoi anche una licenza?
+[COK1_3]
+Spero tu cada e ti rompa l'osso del collo!
-[AMMU_F]
-Non mi serve che mi mostri i documenti, hai una faccia fidata.
+[COK1_6]
+Sono stanco di tutto questo.
-[DETON]
-DETONAZIONE:
+[COK2_7]
+Vedi quei segnali, ragazzo? Cerca di colpire le luci!
-[DRIVE_A]
-Seleziona un Uzi quando entri in un veicolo, poi guarda a destra o a sinistra e premi il ~h~tasto ~k~~PED_FIREWEAPON~~w~ per sparare.
+[COK2_10]
+Di certo sei più bravo a sparare che a parlare.
-[DRIVE_B]
-Seleziona un Uzi quando entri in un veicolo, poi guarda a destra o a sinistra e premi il ~h~tasto ~k~~PED_FIREWEAPON~~w~ per sparare.
+[COK2_11]
+Grazie. Anche tu hai una bella parlantina.
-[RECORD]
-~g~NUOVO RECORD!!!
+[COK2_12]
+Lo so, Tommy.
-[NRECORD]
-~r~NESSUN NUOVO RECORD!
+[COK2_18]
+Ti diverti con Kenny Loggins.
-[RCHELP]
-Premi il tasto ~k~~PED_FIREWEAPON~ o dirigi l'auto radiocomandata contro i pneumatici di un veicolo per provocarne la detonazione.
+[COK2_19]
+Cielo, adoro questo album!
-[RCHELPA]
-Premi il tasto ~k~~PED_FIREWEAPON~ o dirigi l'auto radiocomandata contro i pneumatici di un veicolo per provocarne la detonazione.
+[COK2_26]
+~r~Hai ucciso Lance!
-[RC_1]
-Hai 2 minuti per far esplodere quante più auto dei Diablo possibile!
+[COK3_1]
+Non sparare, amico!
-[RC_2]
-Hai 2 minuti per far esplodere quante più auto Mafiose possibile!
+[COK3_2]
+Che cosa sta succedendo?
-[RC_3]
-Hai 2 minuti per far esplodere quante più auto della Yakuza possibile!
+[COK3_3]
+Sta prendendo la barca. Farabutto!
-[RC_4]
-Hai 2 minuti per far esplodere quante più auto degli Yardie possibile!
+[COK3_4]
+Aiuto! Un idiota sta rubando la barca!
-[RC_5]
-Hai 2 minuti per far esplodere quante più auto degli Hood possibile!
+[COK4_W]
+Uugghh! Questo è l'ultimo.
-[RC_6]
-Hai 2 minuti per far esplodere quante più auto del Cartello possibile!
+[COK4_X]
+Vado ad accendere...
-[RAMPAGE]
-VIOLENZA!!
+[COK4_Y]
+A quanto sembra abbiamo dei nuovi amici.
-[RAMP_P]
-VIOLENZA COMPIUTA!
+[COK4_2]
+Sì.
-[RAMP_F]
-VIOLENZA FALLITA
+[COK4_6]
+Sai dove stiamo andando?
-[PAGE_00]
-.
+[COK4_7]
+Ci siamo persi?
-[PAGE_01]
-Uccidi ~1~ Diablo in 120 secondi!
+[COK4_8]
+Abbiamo un po' di competizione!
-[PAGE_02]
-Distruggi ~1~ veicoli in 120 secondi!
+[COK4_9]
+Falli fuori!
-[PAGE_03]
-Uccidi ~1~ Mafiosi in 120 secondi!
+[COK4_9A]
+È giunta l'ora di un po' di Lance Vance Dance!
-[PAGE_04]
-Uccidi ~1~ elementi della Triade in 120 secondi!
+[COK4_10]
+Sono pronti per il macero! E per sfamare i pesci.
-[PAGE_05]
-Uccidi ~1~ elementi della Triade in 120 secondi!
+[COK4_11]
+Ce l'abbiamo fatta! Le altre imbarcazioni non sono della nostra classe.
-[PAGE_06]
-Distruggi ~1~ veicoli in 120 secondi!
+[COK4_17]
+Stanno iniziando a pregare!
-[PAGE_07]
-Fai saltare la testa a ~1~ Yardie in 120 secondi!
+[COK4_18]
+I miei piedi sono bagnati! STIAMO IMBARCANDO ACQUA!
-[PAGE_08]
-Brucia ~1~ elementi della Yakuza in 120 secondi!
+[COK4_21]
+Ponte in arrivo!
-[PAGE_09]
-Distruggi ~1~ veicoli in 120 secondi!
+[COK4_22]
+Lanciati, sta per esplodere!
-[PAGE_10]
-Distruggi ~1~ veicoli in 120 secondi!
+[COK4_23]
+Bel colpo!
-[PAGE_11]
-Annienta ~1~ Yardie in 120 secondi!
+[COK4_29]
+~r~Hai ucciso Lance!
-[PAGE_12]
-Carbonizza ~1~ elementi della Yakuza in 120 secondi!
+[ASS1_6]
+Vai Tommy, andrà tutto bene!
-[PAGE_13]
-Fai esplodere ~1~ Yardie in 120 secondi!
+[ASS1_7]
+Beccatevi questo, maledetti assassini!
-[PAGE_14]
-Fai fuori ~1~ ColombianI in 120 secondi!
+[ASS1_8]
+Sono bloccato!
-[PAGE_15]
-Polverizza ~1~ Hood in 120 secondi!
+[ASS1_9]
+Ti copro io Tommy!
-[PAGE_16]
-Distruggi ~1~ veicoli in 120 secondi!
+[ASS1_10]
+Ehi, questo sì che è un bel confine alberato.
-[PAGE_17]
-Investi in macchina ~1~ Colombiani in 120 secondi!
+[ASS1_11]
+Ehi Tommy, posso avere la stanza con la vista sulla baia?
-[PAGE_18]
-Distruggi guidando ~1~ veicoli in 120 secondi!
+[ASS1_12]
+Che bel soffitto alto che c'è qui...
-[PAGE_19]
-Stacca la testa a ~1~ Colombiani in 120 secondi!
+[ASS1_3]
+Lance! Ho bisogno di copertura!
-[PAGE_20]
-Decapita ~1~ Hood in 120 secondi!
+[ASS1_5]
+Lance!
-[JOEY_1]
-TESTO NON PIÙ RICHIESTO
+[ASS1_15]
+~g~Distruggi la dimora e uccidi Diaz!
-[JM1_A]
-Ehi, sono stufa, quand'è che si passa ai fatti?
+[ASS1_17]
+~g~Sono disponibili più strade all'interno della villa.
-[JM1_B]
-Tra un minuto, cocca, ho una cosetta da sbrigare.
+[TAXWAR]
+MISSIONI GUERRA DEI TAXI
-[JM1_C]
-Ho un lavoretto per te, amico.
+[NOTAXI]
+~g~Hai bisogno di un taxi Kaufman per attivare questa missione.
-[JM1_D]
-I fratelli Forelli mi devono soldi da troppo tempo
+[TAXW1_5]
+~g~Devi avere un taxi Kaufman!
-[JM1_E]
-e occorre insegnargli un po' di rispetto.
+[TAX2_4]
+Forza, Tommy.
-[JM1_F]
-'Labbra' Forelli si sta ingozzando come un porco al St Mark's Bistro,
+[TAX2_5]
+Riempilo di botte!
-[JM1_G]
-quindi rubagli l'auto e portala nell'armeria di 8-Ball ad Harwood.
+[TAX2_6]
+Non ha neppure il permesso.
-[JM1_H]
-Conosci 8-Ball, vero?
+[TAX2_7]
+Maledetti servizi di limousine.
-[JM1_I]
-Dopo che sarà stata installata una bomba, parcheggia l'auto dove l'hai trovata.
+[TAXW3_1]
+~g~Vai a prendere Mercedes.
-[JM1_J]
-Poi rilassati e goditi lo spettacolo.
+[RACE1]
+~g~3..2..1.. VIA VIA VIA!
-[JM1_K]
-Ma fai in fretta, non starà a pranzo una vita.
+[RACE2]
+~g~3
-[CAT2_A1]
-Forza, brutta deficiente!
+[RACE3]
+~g~2
-[CAT2_A]
-La domanda è: sei venuto a salvare Maria o a riportarmi indietro?
+[RACE4]
+~g~1
-[CAT2_B]
-Beh, stammi a sentire,
+[RACE5]
+~g~VIA!
-[CAT2_B2]
-spararti sarà un piacere, ma uscire con te è stato solo lavoro.
+[FIRST]
+~b~PRIMO
-[CAT2_C]
-Sei il mio peccinno amigo!
+[SECOND]
+~b~SECONDO
-[CAT2_D]
-Butta qui la grana.
+[THIRD]
+~b~TERZO
-[CAT2_E]
-Ti sei dato molto da fare!
+[FOURTH]
+~b~QUARTO
-[CAT2_E2]
-Ma non hai imparato che non devi fidarti di me.
+[RACETM]
+~b~TEMPO DI GARA: ~1~:~1~
-[CAT2_E3]
-Ammazzate quell'idiota.
+[RACETM2]
+~b~TEMPO DI GARA: ~1~:0~1~
-[CAT2_J]
-Fai decollare questo affare!
+[RACEFA]
+~r~Non sei riuscito a vincere la gara!
-[HM5_1]
-Ehi, Ice mi ha detto che saresti arrivato. Ecco le regole. Solo mazze. Niente pistole, niente auto.
+[TEX1_5]
+~r~È riuscito a fuggire!
-[HM5_5]
-È una battaglia per il rispetto, chiaro?.
+[SEG3_1]
+TEMPO:
-[HELP14]
-Per raccogliere le armi, passaci sopra a piedi. Non puoi raccoglierle mentre sei in un veicolo.
+[SEG3_2]
+~g~Raggiungi il van che contiene il Raider radiocomandato e le bombe a tempo.
-[CRUSH]
-Parcheggia nell'area contrassegnata ed esci dal veicolo. Il veicolo verrà rottamato.
+[SEG3_3]
+~g~Devi utilizzare il RAIDER RADIOCOMANDATO per trasportare le 4 bombe nelle 4 aree bersaglio all'interno del cantiere.
-[DIAB2_B]
-Un gruppo di gentaglia mi ha minacciato di asportare il mio attributo di tutto rispetto se non gli sgancio dei soldi.
+[SERG3_5]
+~g~Puoi trasportare solo una bomba alla volta e non puoi raccogliere dell'esplosivo correttamente posizionato.
-[DIAB2_C]
-Hanno minacciato l'uomo sbagliato, amigo.
+[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.
-[DIAB2_D]
-Hanno un debole per il gelato.
+[SEG3_8]
+~g~Le 4 bombe devono essere tutte posizionate su ognuno dei bersagli per passare la missione e demolire l'edificio.
-[DIAB2_E]
-Prendi la bomba che ho nascosto ad Harwood,
+[SEG3_9]
+~g~Bomba piazzata! Ancora 3.
-[DIAB2_F]
-dirotta il furgone dei gelati durante i suoi spostamenti
+[SEG3_10]
+~g~Bomba piazzata! Ancora 2.
-[DIAB2_G]
-e attira quegli idioti verso il loro destino con il campanello.
+[SEG3_11]
+~g~Bomba piazzata! Ne manca una sola.
-[DIAB2_H]
-Si nascondono in un magazzino ad Atlantic Quay.
+[SEG3_12]
+~g~Bomba NON piazzata! Recupera l'esplosivo!
-[DIAB3_A]
-Qualche insolente della Triade ha rubato la mia stupenda macchina ieri notte,
+[SEG3_13]
+~g~Piazza la bomba nella zona bersaglio.
-[DIAB3_B]
-l'ha distrutta e carbonizzata.
+[SEG3_14]
+~r~Tempo esaurito: hai fallito nel demolire l'edificio.
-[DIAB3_C]
-Uno dei miei più cari escrementi asinini si trovava nel bagagliaio
+[SEG3_15]
+~r~Il Raider radiocomandato è stato distrutto! Come farai adesso a trasportare le bombe?
-[DIAB3_D]
-veri oggetti da collezione, insostituibili amico mio.
+[AVERY]
+MISSIONI DI AVERY
-[DIAB3_E]
-Ho nascosto un'arma lancinante alla periferia di Chinatown.
+[ASM]
+MISSIONI DA SICARIO
-[DIAB3_F]
-Prendila e insegna ai vandali della Triade a temere l'ira super-dotata di El Burro!
+[ASM_1]
+MISSIONE DA SICARIO 1
-[DIAB3_1]
-UCCIDI 25 ELEMENTI DELLA TRIADE
+[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.
-[DIAB4_A]
-Un ladruncolo approfittatore ha rubato un furgone carico di copie delle mie ultime pubblicazioni!
+[ASM1_2]
+~g~Raggiungi il telefono pubblico presso il Mall in Washington Beach.
-[DIAB4_B]
-Ma quell'idiota fatto di SPANK ha lasciato lo sportello posteriore aperto,
+[ASM1_3]
+~g~Carl Pearson, fattorino di una pizzeria. Non deve completare le sue consegne.
-[DIAB4_C]
-per cui tutto quello splendido capolavoro patinato
+[ASM1_4]
+~g~Uccidi il fattorino prima che possa completare le sue consegne.
-[DIAB4_D]
-con intriganti foto pornografiche è stato sparso per tutta Liberty!
+[ASM_2]
+MISSIONE DA SICARIO 2
-[DIAB4_E]
-Prendi il furgone e segui la scia di copie di Un Asino si fa Dallas volume 1, 2 e 3
+[ASM_3]
+MISSIONE DA SICARIO 3
-[DIAB4_F]
-raccogliendole lungo la 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.
-[DIAB4_G]
-Quando raggiungi quel ladruncolo imbottito di SPANK, fallo fuori!
+[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.
-[DIAB4_H]
-Poi consegna il mio materiale asinino a Riviste XXX nel quartiere a luci rosse.
+[ASM3_1]
+~g~Recupera le armi che Mr. Black ha lasciato per te.
-[DIAB4_1]
-~g~Porta il furgone nel retro di Riviste XXX.
+[ASM3_2]
+~g~Non avvicinarti troppo, se no il bersaglio potrebbe vederti.
-[HM1_E]
-Devi far vedere a queste depravate come si fa una vera sparatoria.
+[ASM3_3]
+~g~Per un'eliminazione più rapida, colpisci da una locazione vicino alle loro postazioni ed evita di farti vedere.
-[HM1_H]
-Togli di torno questi Nine!
+[ASM3_4]
+~g~Ti ha visto! Fallo fuori il prima possibile!
-[HM2_A]
-Questi Nine mi stanno causando problemi.
+[ASM3_5]
+~g~Marcus Hammond si trova presso dei cartelli pubblicitari in Washington.
-[HM2_B]
-Queste stronze hanno auto blindate e adesso stanno spacciando SPANK...
+[ASM3_6]
+~g~Franco Carter si trova presso la DBP Security vicino a Ocean Drive.
-[HM2_C]
-e lo smerciano senza paura ai miei fratelli.
+[ASM3_7]
+~g~Dick Tanner si trova presso la gioielleria in Vice Point.
-[HM2_D]
-C'è un'auto parcheggiata in strada.
+[ASM3_8]
+~g~Nick Kong si trova presso Washington Beach.
-[HM2_E]
-Dentro c'è della roba che metterà le sorelline fuori combattimento...
+[ASM3_9]
+~g~Stuntman Driver si trova presso Washington Beach.
-[HM3_A]
-Qualche bastardo ha messo una bomba nella mia auto.
+[ASM3_10]
+~r~Non sei riuscito a eliminarli tutti quanti.
-[HM3_B]
-Se perdo l'auto, la mia reputazione nel giro sarà finita.
+[ASM_4]
+MISSIONE DA SICARIO 4
-[HM3_C]
-Prendi la mia macchina e portala al garage a St. Marks, chiaro?
+[ASM4_1]
+~g~Recupera il fucile che ti abbiamo lasciato tra le foglie presso il terminal dell'aeroporto.
-[HM3_D]
-Fagli disinnescare la bomba, lascia che se ne occupino loro.
+[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.
-[HM3_E]
-Il tempo corre e l'ordigno è tutto incasinato.
+[ASM4_3]
+~g~Osserva la donna sul balcone sopra ai banconi del check-in dentro il terminal. NON UCCIDERLA.
-[HM3_F]
-Se becchi una buca potrebbe saltare tutto in aria.
+[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.
-[HM3_G]
-Adesso muoviti!
+[ASM4_5]
+~g~Recupera la valigetta!
-[HM4_A]
-Ehi, un aereo federale portavalute si è appena schiantato all'aeroporto Francis.
+[ASM4_6]
+~g~Porta la valigetta ad Ammu-Nation in Downtown
-[HM4_B]
-C'è del platino sparso per tutta la pista.
+[ASM4_7]
+~r~Hai ucciso la donna, idiota!
-[HM4_C]
-Prendi un'auto e raccogline quanto ne puoi!
+[ASM4_8]
+~r~Il bersaglio ha sentito il colpo d'arma da fuoco! L'accordo è saltato!
-[HM4_F]
-Puoi scaricare il malloppo in uno dei miei garage.
+[ASM4_9]
+~r~Il bersaglio è salito a bordo del volo!
-[HM4_G]
-Il platino è molto pesante e rallenterà un po' l'automobile.
+[ASM4_10]
+~g~Sembra tu non sia l'unico interessato alla valigetta! Portala in fretta ad Ammu-Nation!
-[HM4_H]
-Quindi fai diverse consegne nel garage.
+[ASM4_11]
+~r~Il bersaglio ti ha visto! L'accordo è saltato!
-[HM5_A]
-Quei Nine sono rimasti in una manciata di rognosi...
+[ASM4_13]
+~g~Ti ha visto e sta scappando! Uccidilo e recupera la valigetta!
-[HM5_B]
-ma insistono ancora.
+[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.
-[HM5_C]
-Ci siamo accordati per uno scontro.
+[ASM_5]
+MISSIONE DA SICARIO 5
-[HM5_D]
-Un gruppo dei loro contro due di noi, anzi...
+[KICK]
+KICKSTART
-[HM5_E]
-due di te.
+[KICK1_3]
+~g~Numero di volte che hai appoggiato i piedi: ~1~
-[HM5_F]
-Ti accompagnerei, ma...
+[KICK1_4]
+~g~Penalità: ~1~ secondi
-[HM5_G]
-non sarò in libertà vigilata per altri tre mesi.
+[BANK]
+MISSIONI RAPINA
-[HM5_H]
-Tu mi capisci, vero?
+[BANK1]
+MISSIONE RAPINA 1
-[HM5_I]
-Vai a trovare il mio fratellino,
+[BANK2]
+MISSIONE RAPINA 2
-[HM5_J]
-Ti accompagnerà sul luogo della rissa, amico.
+[BJM2_3]
+PERCENTUALE DI CENTRI: ~1~%
-[MEA1_B]
-Mi chiamo Chonks, Marty Chonks.
+[BJM2_15]
+PUNTEGGIO:
-[MEA1_C]
-Gestisco la fabbrica di cibo per cani Bitch'n'Dog qui vicino.
+[BJM2_18]
+PUNTEGGIO DA BATTERE:
-[MEA1_D]
-Ho dei problemi finanziari, ma in fondo chi non ne ha?
+[BJM2_19]
+~g~Colpisci il maggior numero di bersagli entro il tempo limite!
-[MEA1_E]
-Più tardi mi incontrerò col direttore della mia banca.
+[BJM2_21]
+~g~Colpisci il maggior numero di bersagli finché hai ancora colpi.
-[MEA1_F]
-È un imbroglione schifoso che continua a far crescere gli interessi di un prestito per arricchirsi.
+[BANK3]
+MISSIONE RAPINA 3
-[MEA1_G]
-Usa la mia auto, vallo a prendere e portalo qui.
+[BJM3_1]
+~g~Trova una macchina da corsa e posizionati sulla griglia di partenza.
-[MEA1_H]
-Ho una sorpresina per quella maledetta sanguisuga!
+[BNK4_2A]
+I ragazzi dell'officina hanno fatto un ottimo lavoro su questa piccola.
-[MEA2_A]
-Ho assunto dei ladri per entrare nel mio appartamento...
+[BNK4_3G]
+Ommerda, abbiamo la polizia alle calcagna!
-[MEA2_C]
-Quei ladruncoli bastardi minacciano di dire tutto all'assicurazione,
+[BNK4_3H]
+...e non siamo ancora neanche arrivati.
-[MEA2_D]
-se non do loro una percentuale.
+[BNK4_3K]
+Dobbiamo seminare prima la polizia...
-[MEA2_E]
-Roba da non credere!
+[BNK4_3L]
+Cristo Tommy, stai cercando di farci fuori?
-[MEA2_F]
-Ho parcheggiato un'auto dietro i cancelli della fabbrica.
+[BNK4_3N]
+Tutto ciò che amo finisce a pezzi!
-[MEA2_G]
-Usala e valli a prelevare nel loro territorio nel quartiere a luci rosse.
+[BNK422A]
+Cam, quanto tempo?
-[MEA2_H]
-Poi portali qui in fabbrica così che comprendano il mio punto di vista.
+[BK4_23A]
+Mi bastano 3 minuti!
-[MEA3_A]
-L'azienda farà bancarotta se non riesco a procurarmi in fretta parecchi contanti.
+[BNK4_26]
+Maledizione! Ecco che arrivano!
-[MEA3_B]
-Mia moglie ha un'assicurazione e l'unica cosa che sa fare è sperperare i miei soldi.
+[BNK4_32]
+Usa l'esplosivo per aprire le cassette di sicurezza!
-[MEA3_C]
-Ho lasciato un'auto al solito posto.
+[BNK4_43]
+Vi copro io il culo, PARTI!
-[MEA3_D]
-Vai a prendere mia moglie al salone di bellezza Classic Nails e accompagnala alla fabbrica.
+[BNK4_51]
+A me sembri a posto.
-[MEA4_A]
-Maledizione, sono nei guai!
+[KENT]
+MISSIONI DI KENT PAUL
-[MEA4_B]
-Sembra che mia moglie avesse una storia con un tipo a cui devo dei soldi.
+[KENT1]
+MISSIONE DI KENT PAUL 1
-[MEA4_C]
-È molto arrabiato e vuole vendetta!
+[COUNT]
+MISSIONI DI FALSIFICAZIONE
-[MEA4_E]
-Lui si aspetta che cercherò di patteggiare...
+[COUNT1]
+MISSIONE DI FALSIFICAZIONE 1
-[MEA4_F]
-ma io credo che...
+[COUNT2]
+MISSIONE DI FALSIFICAZIONE 2
-[MEA4_G]
-i cani di Liberty assaggeranno dei bocconcini extra questo mese!
+[BIKE]
+MISSIONI DEI MOTOCICLISTI
-[WELCOME]
-BENVENUTI A
+[BIKE1]
+MISSIONE DEI MOTOCICLISTI 1
-[HM1_2]
-~g~Prendi un veicolo e ricorda: contano solo le uccisioni fatte con l'Uzi mentre guidi!
+[BIKE2]
+MISSIONE DEI MOTOCICLISTI 2
-[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~.
+[BIKE3]
+MISSIONE DEI MOTOCICLISTI 3
-[LRQC_1]
-Asuka e io dobbiamo parlare, OK?
+[GOAWAY1]
+Ritorna quando avrai completato le missioni per la gang di Haiti.
-[LRQC_2]
-Perché non ti fai un giro?
+[HAIT]
+MISSIONI DEGLI HAITIANI
-[LRQC_3]
-Ti servira un posto dove nasconderti.
+[HAIT1]
+MISSIONE DEGLI HAITIANI 1
-[LRQC_4]
-C'è un magazzino al confine di Bellville che farà al caso tuo.
+[HAIT2]
+MISSIONE DEGLI HAITIANI 2
-[LRQC_5]
-Ritorna qui nel mio appartamento quando sei pronto,
+[HAIT3]
+MISSIONE DEGLI HAITIANI 3
-[LRQC_6]
-Così possiamo chiacchierare un po'.
+[HAM3_6]
+~g~Utilizza il fucile di precisione che ti ho lasciato per completare la missione.
-[JM6_5]
-~g~Ti serve un veicolo per la fuga, idiota!
+[ROCK]
+MISSIONI DELLA BAND
-[JM2_F]
-Se ti serve un'arma, vai sul retro di AmmuNation dal lato opposto della metropolitana.
+[ROK1_4]
+~g~OK, credo tu stessi cercando questo...
-[LOVE4_7]
-~g~C'è un cantiere edile a Staunton Island, forse hanno portato lì il pacco.
+[ROK1_1E]
+~g~Ti costerà di più di quanto hai!
-[LOVE4_8]
-~g~Ti servirà un'auto per accedere al garage.
+[ROK1_1F]
+~g~Ritorna quando avrai i soldi.
-[TSCORE]
-GUADAGNI: ~1~$
+[RBM2_6]
+~g~Wow! È un uomo, bloccalo!
-[AM1_9]
-~r~Salvatore è fuggito di nuovo dentro il club Luigi's!
+[ROCK3]
+MISSIONE DELLA BAND 3
-[AM1_6]
-~g~Se ti aggiri attorno al club Luigi's, la Mafia ti avvisterà!
+[ROK3_6D]
+~r~insieme alle vostre GROSSE TESTE DA CAPELLONI!
-[TM2_3]
-~g~È una trappola! Falli fuori tutti!!!
+[ROK3_40]
+Vicino al fottuto minibar?
-[FM4_1]
-Sono Maria. L'auto è una trappola! Incontriamoci alla rampa a sud del ponte Callahan.
+[RBM3_5]
+~g~Porta i Love Fist allo spettacolo.
-[JM1_7]
-~g~Chiudi la portiera! Lo noterà!
+[CUBANM]
+MISSIONI DEI CUBANI
-[KM5_1]
-~g~TRITATO DI SPACCIATORE!
+[CUBAN1]
+MISSIONE DEI CUBANI 1
-[KM5_6]
-~g~Devi uccidere almeno 8 spacciatori Yardie.
+[CUBAN2]
+MISSIONE DEI CUBANI 2
-[KM5_7]
-~g~Uccidili in fretta! Dopo aver venduto lo SPANK spariscono dalla circolazione.
+[CUB2_10]
+~r~Dovresti uccidere gli Haitiani, non i Cubani.
-[RM3_8]
-~r~Quell'auto è un tranello!!!
+[CUBAN3]
+MISSIONE DEI CUBANI 3
-[LM3_8]
-Ehi, sono Joey.
+[CUBAN4]
+MISSIONE DEI CUBANI 4
-[LM3_9]
-Luigi mi ha detto che sei affidabile, quindi torna più tardi,
+[CUB4_05]
+~r~Ti avevo detto di restare in macchina! Adesso non riusciremo mai a entrare!
-[KM3_5]
-~g~Suona il clacson per avviare l'affare.
+[CUB4_25]
+OK, andiamo.
-[LOVE7]
-LA SCOMPARSA DI LOVE
+[PROT]
+MISSIONI DI PROTEZIONE
-[LOVE2_5]
-~g~Kenji è un tritato di carne! Allontanati da Newport e abbandona l'auto!
+[PRO1_H]
+Perché non ti calmi per un secondo, sto finalmente cominciando a capire come funzionano le cose da queste parti.
-[AS2_11]
-~g~~1~ SU 9!
+[PRO1_02]
+~g~Esci dal Mall.
-[GARAGE1]
-~g~Esci dal veicolo ed esci fuori.
+[PRO3_06]
+~g~Fai perdere le tracce.
-[KM3_11]
-~g~Il Cartello è stato attaccato e la valigia non è stata recuperata.
+[PORN]
+MISSIONI PORNOGRAFIA
-[KM3_12]
-~g~Uccidi tutti i Colombiani, distruggi i veicoli e recupera la valigia.
+[PORN1]
+MISSIONE PORNOGRAFIA 1
-[KM3_13]
-~g~Riconsegna la valigia al Casinò.
+[POR1_03]
+~r~Candy è morta!
-[RM5_6]
-~g~Ci è scappato! Spaccagli la corazza con un veicolo o con una bella esplosione!
+[PORN2]
+MISSIONE PORNOGRAFIA 2
-[PBOAT_1]
-Premi il ~h~tasto ~k~~PED_FIREWEAPON~~w~ per sparare con i cannoni della barca.
+[PORN3]
+MISSIONE PORNOGRAFIA 3
-[PBOAT_2]
-Premi il ~h~tasto ~k~~PED_FIREWEAPON~~w~ per sparare con i cannoni della barca.
+[POR3_18]
+Sei stato visto!
-[DIAB1_B]
-Sono El Burro dei Diablo.
+[PORN4]
+MISSIONE PORNOGRAFIA 4
-[DIAB1_D]
-Sei da poco a Liberty, ma ti sei già guadagnato una reputazione in città.
+[POR4_04]
+~g~Gli uffici sono dall'altra parte di questo cancello.
-[DIAB1_E]
-C'e una corsa d'auto con inizio alla vecchia scuola vicino al ponte Callahan.
+[PHIL]
+MISSIONI DI PHIL
-[DIAB1_F]
-Procurati un mezzo, il primo che attraversa tutti i posti di blocco vince il premio.
+[PHIL1]
+MISSIONE DI PHIL 1
-[HM2_1]
-Usa i maggiolini radiocomandati per distruggere le auto blindate. Premi il ~h~tasto ~k~~PED_FIREWEAPON~~w~ per farli esplodere.
+[PHI1_06]
+Ma che combini, come diavolo guidi?
-[HM2_1A]
-Usa i maggiolini radiocomandati per distruggere le auto blindate. Premi il ~h~tasto ~k~~PED_FIREWEAPON~~w~ per farli esplodere.
+[PHI1_07]
+Ehi!
-[HM2_2]
-~r~Non sei riuscito a distruggere tutte le auto blindate!
+[PHIL2]
+MISSIONE DI PHIL 2
-[HM2_6]
-~g~Auto blindata distrutta!
+[PIZ1_A]
+MISSIONE RECAPITO PIZZE
-[RM3_A]
-Conosco un uomo molto importante in città, di manica larga,
+[PIZ1_03]
+~g~Ritorna alla pizzeria e prendi le nuove ordinazioni.
-[RM3_H]
-con gusti, diciamo, esotici e i soldi per permetterseli.
+[PIZ1_04]
+~g~Ecco le nuove ordinazioni.
-[RM3_B]
-È coinvolto in un processo e l'accusa ha delle sue foto piuttosto imbarazzanti
+[PIZ1_10]
+Premi il ~h~tasto R3~w~ per annullare la missione.
-[RM3_C]
-in cui appare in un party all'obitorio.
+[CNTBUY1]
+Tipografia acquistata: ~1~$
-[LOVE6_A]
-Una lezione d'affari, amico.
+[CARBUY]
+Concessionario acquistato: ~1~$
-[LOVE6_E]
-Se possiedi qualcosa di unico, il mondo intero cercherà di strappartelo dalle mani...
+[PORNBUY]
+Studio cinematografico acquistato: ~1~$
-[LOVE6_C]
-Squadre speciali di polizia hanno circondato la zona attorno al mio socio e al pacco.
+[ICEBUY]
+Fabbrica di gelato acquistata: ~1~$
-[LOVE6_D]
-Vai li, prendi il furgone e fuggi per attirarli dietro di te.
+[TAXIBUY]
+Compagnia di taxi acquistata: ~1~$
-[LOVE6_F]
-Tienili occupati, così che lui possa sfuggire!
+[BANKBUY]
+Malibu acquistato: ~1~$
-[AM3_C]
-Probabilmente quando lo leggerai questo sarà in alto mare! Ruba un'imbarcazione della polizia e mandalo a picco!
+[BOATBUY]
+Cantiere navale acquistato: ~1~$
-[FESZ_UC]
-ANNULLA
+[PRNT_NO]
+Non puoi ancora comprare la tipografia, prova più tardi.
-[FEDS_SM]
-L1,R1-CAMBIA MENU
+[CAR_NO]
+Non puoi ancora comprare il concessionario, prova più tardi.
-[FEDS_AS]
-;=-CAMBIA SELEZIONE
+[PORN_NO]
+Non puoi ancora comprare lo studio cinematografico, prova più tardi.
-[FEDSAS2]
-<>-CAMBIA SELEZIONE
+[ICE_NO]
+Non puoi ancora comprare la fabbrica di gelato, prova più tardi.
-[FEDS_SS]
-L1,R1-CAMBIA SELEZIONE
+[TAXI_NO]
+Non puoi ancora comprare la compagnia di taxi, prova più tardi.
-[FEDSSC1]
-;-SCORRIMENTO RAPIDO
+[BANK_NO]
+Non puoi ancora comprare il Malibu, prova più tardi.
-[FEDSSC2]
-=-FERMA SCORRIMENTO
+[BOAT_NO]
+Non puoi ancora comprare il cantiere navale, prova più tardi.
-[MEA2_3]
-~g~Riporta l'auto alla fabbrica.
+[PRNT_R3]
+Premi il tasto R3 per acquistare la tipografia per ~1~$
-[RM1_3]
-~r~McAffrey è scappato!
+[CAR_R3]
+Premi il tasto R3 per acquistare il concessionario per ~1~$
-[RM1_4]
-~g~Hai usato tutte le granate! Procuratene altre da AmmuNation!
+[PORN_R3]
+Premi il tasto R3 per acquistare lo studio cinematografico per ~1~$
-[RM1_5]
-~g~Torna indietro e incendia il rifugio!
+[ICE_R3]
+Premi il tasto R3 per acquistare la fabbrica di gelato per ~1~$
-[RM6_4]
-~g~Vai al nascondiglio e preleva la roba di Ray.
+[TAXI_R3]
+Premi il tasto R3 per acquistare la compagnia di taxi per ~1~$
-[RM6_5]
-~g~La CIA ha messo il ponte sotto sorveglianza, trova un altro punto d'accesso.
+[BANK_R3]
+Premi il tasto R3 per acquistare il Malibu per ~1~$
-[HM2_F]
-e distruggi tutte le loro attrezzature blindate.
+[BOAT_R3]
+Premi il tasto R3 per acquistare il cantiere navale per ~1~$
-[HM_4]
-'CORSA AL LINGOTTO'
+[COL2_6]
+Fermo, brutto maiale imperialista americano!
-[MEA2_B5]
-TESTO NON PIÙ NECESSARIO
+[COL2_6B]
+Questa è proprietà del governo francese.
-[MEA1_B5]
-TESTO NON PIÙ NECESSARIO
+[COL2_6C]
+È finita!
-[MEA3_B5]
-TESTO NON PIÙ NECESSARIO
+[COL3_A]
+Thomas, grazie per essere venuto.
-[MEA4_B7]
-ma se entri un attimo nel mio ufficio...
+[COL3_B]
+Scusami se giungo subito al punto.
-[MEA3_B4]
-Marty vuole vedermi? È meglio che si sbrighi perché devo acconciarmi i capelli.
+[COL3_C]
+Diaz mi ha chiesto di sovrintendere una piccola transizione di lavoro.
-[KM3_7]
-È un esperto in trappole della Yakuza!
+[COL3_D]
+Speriamo vada meglio dell'ultima...
-[FES_LOF]
-Caricamento fallito.
+[COL3_E]
+Ed è per questo che ho pensato a te, amico.
-[P1INSA]
-Ingresso 1. memory card (PS2) inserita. ~1~ K di spazio disponibile per salvare. ~1~ K necessari.
+[COL3_F]
+Ho lasciato un po' di supporto al parcheggio multipiano.
-[P1INSN]
-Ingresso 1. memory card (PS2). Spazio disponibile insufficiente. Elimina alcuni file.
+[COL3_G]
+Raccogli il materiale, poi raggiungi e sorveglia gli uomini di Diaz all'incontro.
-[FES_SLO]
-SALVA FILE
+[COL4_2]
+Non so signore!
-[FES_ISC]
-CORROTTO
+[COL4_5]
+Signorsì, signore!
-[FESZ_TI]
-SALVA Z1
+[COL4_10]
+Andiamo a prendere delle ciambelle.
-[FESZ_SA]
-Salva partita
+[COL4_16]
+Signore! Sposto il veicolo, signore!
-[P1NOIN]
-Ingresso 1. memory card (PS2) non inserita
+[COL4_25]
+Autodistruzione del veicolo attivata!
-[P1INSE]
-Ingresso 1. memory card (PS2) inserita.
+[COL5_6]
+Mercedes, quella ragazza sarà la mia rovina.
-[MC_LDFL]
-Caricamento fallito!
+[COL5_8]
+Maledetti scarafaggi!
-[MC_NWRE]
-Partita in fase di riavvio.
+[COL5_5]
+Morite, maiali Francesi!
-[LOVE6_3]
-~g~Hai ~1~ secondi per tornare alla Securicar prima di fallire la missione.
+[CNT2_1]
+Uccidetelo
-[LOVE6_4]
-~r~Hai distrutto la Securicar da depistaggio!
+[CNT2_2]
+Recuperate le matrici!
-[HELP1]
-Fermati nel centro del segnale blu.
+[CNT2_3]
+Proteggete il corriere.
-[HELP12]
-Cammina nel centro del segnale blu per attivare una missione.
+[FINKILL]
+OK ragazzi, uccidetelo!
-[HJSTAT]
-Distanza: ~1~.~1~m Altezza: ~1~.~1~m Ribaltamenti: ~1~ Rotazioni: ~1~_
+[FIN_6]
+Sonny è interessato alla mia cassaforte e ai miei soldi...
-[HJSTATW]
-Distanza: ~1~.~1~m Altezza: ~1~.~1~m Ribaltamenti: ~1~ Rotazioni: ~1~_ E che grande atterraggio!
+[FIN_10]
+Sonny? SONNY! Sto venendo a prenderti!
-[DIAB1_5]
-TEMPO DI GARA:
+[RACES_4]
+3
-[LOVE3_4]
-~r~Hai distrutto l'aereo!!!
+[RACES_5]
+2
-[F_FAIL1]
-Missione Camion dei pompieri terminata.
+[RACES_6]
+1
-[F_CANC]
-~r~Missione Pompieri annullata!
+[RACES_7]
+VIA!
-[F_EXTIN]
-INCENDI:
+[RACES_9]
+Tempo: ~1~:~1~
-[A_COMP1]
-Missioni Infermieri completate!
+[RACES]
+TEMPO:
-[A_CANC]
-~r~Missione Infermieri annullata!
+[RACES17]
+Nuovo miglior tempo: ~1~:~1~
-[A_COMP3]
-Missioni Infermieri completate! Ora non ti stancherai mai mentre corri!
+[RACES20]
+Nuovo miglior tempo: ~1~:0~1~
-[ATUTOR]
-Premi il ~h~tasto ~k~~TOGGLE_SUBMISSIONS~~w~ per attivare o disattivare le missioni Infermieri.
+[RACES21]
+Tempo: ~1~:0~1~
-[ATUTOR3]
-Premi il ~h~tasto ~k~~TOGGLE_SUBMISSIONS~~w~ per attivare o disattivare le missioni Infermieri.
+[RCH1_1]
+~g~Usa l'elicottero radiocomandato, il Raider, per PASSARE ATTRAVERSO i punti di controllo.
-[ALEVEL]
-Missione Infermieri Livello ~1~
+[RCH1_2]
+~g~I punti di controllo sono sparsi per tutto l'aeroporto.
-[A_FAIL1]
-Missione Infermieri terminata.
+[RCH1_3]
+~g~Hai ~c~8 MINUTI~g~ per attraversarli tutti e ~c~20~g~!
-[FEST_HA]
-Missione Infermieri - Livello Max.
+[RCH1_5]
+Tempo
-[A_SAVES]
-PERSONE SALVATE: ~1~
+[RCRC1_1]
+~g~Sfida nella GARA A TAPPE altri 3 Bandit radiocomandati su 2 GIRI.
-[C_KILLS]
-CRIMINALI UCCISI: ~1~
+[RCRC1_2]
+~g~Raggiungi subito la griglia di partenza!
-[HM1_B]
-Ho un problema. Stanno cercando di farsi gioco di me.
+[RCRC1_3]
+~g~Giro finale!
-[AM2_A]
-La morte di Salvatore è un'ottima notizia,
+[RCRC1_4]
+~g~3
-[AM2_A2]
-sei un killer efficiente. Mi piace come qualità in un uomo.
+[RCRC1_5]
+~g~2
-[AM2_B]
-Lui è mio fratello Kenji.
+[RCRC1_6]
+~g~1
-[AM2_C]
-Asuka ha un lavoretto per te: quando hai finito, passa al Casinò così parliamo.
+[RCRC1_7]
+~g~VIA!
-[AM2_D]
-Proprio come Kenji, che cerca sempre di usare i miei giocattoli.
+[RCRC1_8]
+~g~Tempo di gara: ~1~ secondi
-[AM2_E]
-La mia fonte alla polizia mi ha informato che la Mafia sta studiando le nostre operazioni nella città
+[RCPL1_1]
+~g~Sfida nella GARA A TAPPE altri 3 Baron radiocomandati.
-[AM2_E2]
-nel tentativo di scovarti.
+[RCPL1_2]
+~g~Devi attraversare la ~o~CORONA CENTRALE~g~ per passare con successo un punto di controllo.
-[AM2_F]
-Non possiamo continuare le nostre operazioni fino a quando il problema non verrà risolto.
+[RCPL1_3]
+~g~Raggiungi subito la griglia di partenza!
-[AM2_G]
-Elimina questi insulsi spioni e termina questa vendetta una volta per tutte.
+[FEA_2SP]
+2 altoparlanti
-[F_START]
-~g~Veicolo in fiamme avvistato nell'area ~a~. Vai a spegnere il fuoco.
+[FEA_4SP]
+Più di 2 altoparlanti
-[AM4_1A]
-Vai al telefono al parco Belleville ovest.
+[FEA_EAR]
+Cuffie
-[AM4_1B]
-Vai al telefono nel campus Liberty.
+[FEA_NAH]
+NESSUNA PERIFERICA AUDIO
-[AM4_1C]
-Vai al telefono al parco Belleville sud.
+[FET_APP]
+APPLICA
-[AM4_1D]
-Incontriamoci nei bagni pubblici nel parco.
+[FES_SKN]
+NOME SKIN
-[HJSTATF]
-Distanza: ~1~ piedi Altezza: ~1~ piedi Ribaltamenti: ~1~ Rotazioni: ~1~_
+[FES_DAT]
+DATA
-[HJSTAWF]
-Distanza: ~1~ piedi Altezza: ~1~ piedi Ribaltamenti: ~1~ Rotazioni: ~1~_ E che grande atterraggio!
+[FES_SET]
+Usa skin
-[HM1_F]
-Stai in guardia, però. Ci saranno dei Jack in giro che penseranno che vuoi far fuori anche loro!
+[FET_DEF]
+Ripristina predefiniti
-[HM1_D]
-'Nine' è il loro nome e la loro bandiera è porpora e ogni giorno che portano i loro colori...
+[FESZ_QZ]
+Sei sicuro di voler salvare la partita?
-[HM1_G]
-è un giorno in cui i 'Jack' appaiono rammolliti.
+[FES_SCG]
+Salvare la partita?
-[MEA2_B]
-e ruba qualcosa così che io possa incassare l'assicurazione come fai tu.
+[FES_LCG]
+Vuoi caricare e continuare la partita?
-[TM3_H]
-~w~Hai fatto un bel lavoro laggiù, molto bravo.
+[FEC_FIR]
+Fuoco
-[TM3_I]
-~w~Forza, adesso ti presento al Don.
+[FEC_NWE]
+Arma successiva
-[TM3_J]
-~w~Eehi!!! Luigi!
+[FEC_PWE]
+Arma precedente
-[TM3_K]
-~w~Oh, le mie ragazze hanno sentito la sua mancanza, Don Salvatore, è mancato per molto tempo.
+[FEC_FOR]
+Avanti
-[TM3_L]
-~w~Dì loro che una volta risolta questa situazione spiacevole,
+[FEC_BAC]
+Indietro
-[TM3_M]
-~w~andremo tutti al club a festeggiare, OK?
+[FEC_LEF]
+Sinistra
-[TM3_N]
-~w~Ecco il mio ragazzo!
+[FEC_RIG]
+Destra
-[TM3_N2]
-~w~Come va, papà?
+[FEC_ZIN]
+Ingrandisci
-[TM3_O]
-~w~Ti sei trovato una brava mogliettina?
+[FEC_ZOT]
+Riduci
-[TM3_P]
-~w~Ehi, tua madre, pace all'anima sua, si rivolterebbe nella tomba
+[FEC_EEX]
+Entra o esci
-[TM3_Q]
-~w~vedendoti ancora senza moglie.
+[FEC_RAD]
+Radio
-[TM3_R]
-~w~Lo so, papà, ci sto pensando su.
+[FEC_SUB]
+Sottomissione
-[TM3_S]
-~w~TONI! Come sta tua madre?
+[FEC_CMR]
+Cambia visuale
-[TM3_T]
-~w~È una donna eccezionale. Forte.
+[FEC_JMP]
+Salto
-[TM3_U]
-~w~Sta bene... tutto OK.
+[FEC_SPN]
+Scatto
-[TM3_V]
-~w~Bene, bene. Voi ragazzi entrate pure, mentre io chiacchiero col nostro nuovo amico.
+[FEC_HND]
+Freno a mano
-[TM3_W]
-~w~Vedo un futuro roseo per te, figghiu miu...
+[FEC_LOL]
+Sguardo a sinistra
-[RM1_A]
-Quell'infame di McAffrey, si prende più bustarelle di chiunque.
+[FEC_LOR]
+Sguardo a destra
-[RM1_B]
-Pensa di venir assolto dignitosamente presentando delle prove inequivocabili.
+[FEC_NTR]
+Bersaglio successivo
-[RM1_C]
-Ha appena cantato!
+[FEC_PTT]
+Bersaglio precedente
-[RM4_B]
-Dobbiamo metterlo a tacere, per sempre.
+[FEC_LBA]
+Sguardo indietro
-[RM4_E]
-Voglio che dorma con i pesci, in senso letterale.
+[FEC_CEN]
+Centra visuale
-[LOVE3_B]
-Avvicinandosi all'aeroporto stasera, un piccolo aereo sorvolerà la baia.
+[FET_CCN]
+Classico
-[LOVE4_D]
-Sfortunatamente le autorità aeroportuali avevano già iniziato a smantellare l'aereo
+[FET_SCN]
+Predefinito
-[LOVE4_H]
-finché non sono intervenuto sborsando una fortuna.
+[FET_CFT]
+A PIEDI
-[LOVE4_E]
-Attraversa il ponte per Shoreside Vale e vai all'aeroporto internazionale Francis.
+[FET_CCR]
+IN MACCHINA
-[GTAB_A]
-Ehi, portiamo questo fuori di qui. Dio solo sa cos'è
+[FET_CAC]
+AZIONE
-[GTAB_B]
-ma sembra che lui lo voglia davvero, quindi dovrà pur valere qualcosa.
+[FEC_IBT]
+-
-[GTAB_C]
-Chi diavolo è!
+[FEC_MXO]
+MXB1
-[GTAB_D]
-TU!
+[FEC_MXT]
+MXB2
-[GTAB_E]
-Ehi, in gamba amigo, stai calmo, amigo! Di niente, di niente!
+[FEC_UNB]
+NON ASSEGNATO
-[GTAB_F]
-Ti ho lasciato sfogare!
+[FEC_TFL]
+Sguardo+Torretta a SX
-[GTAB_G]
-Non sparare amigo. Nessun problema. Siamo tutti amici. Ecco, prendi questo.
+[FEC_TFR]
+Sguardo+Torretta a DX
-[GTAB_H]
-Non fare la femminuccia!
+[FEC_MWF]
+VOLANTE SU
-[GTAB_I]
-Non abbiamo scelta, baby!
+[FEC_MWB]
+VOLANTE GIÙ
-[GTAB_J]
-C'è sempre una scelta, stupido bastardo!
+[FEC_ORR]
+o
-[GTAB_K]
-Mi spiace per quella cretina, amigo, sono tutte uguali... por favor?
+[FEC_NUS]
+NON USATO
-[GTAB_L]
-Allora la puttana è scappata.
+[FEC_LUD]
+Sguardo su
-[GTAB_M]
-Ma mi hai fatto un favore,
+[FEC_LDU]
+Sguardo giù
-[GTAB_N]
-non sei il solo che ha un conto in sospeso col Cartello,
+[FEC_CMP]
+COMBO: SGUARDO SX+DX
-[GTAB_O]
-questo verme ha ucciso mio fratello!
+[LAW_1A]
+law_1a
-[GTAB_P]
-Non ho mai ucciso nessun Yakuza!
+[LAW_1B]
+law_1b
-[GTAB_Q]
-BUGIARDO! Abbiamo visto tutti l'assassino del Cartello.
+[LAW_2A]
+law_2a
-[GTAB_R]
-Daremo la caccia ed elimineremo tutti voi cani Colombiani!
+[LAW_2B]
+law_2b
-[GTAB_S]
-Farò un'operazione al nostro amichetto per strappargli qualche informazione e per divertirmi.
+[FEH_STA]
+STATISTICHE
-[GTAB_T]
-Tu, passa più tardi, sono certo che avrò bisogno del tuo aiuto.
+[FEH_LOA]
+CARICA
-[GTAB_U]
-Ti prego, amigo, non lasciarmi con lei, è tutta matta! Amigo? Ehi Amiiigooo!!! Aieeeeeeaaaaahh!!!
+[FEH_CON]
+COMANDI
-[LOVE5_A]
-Ti stai dimostrando un buon investimento, cosa rara in questi giorni.
+[FEH_AUD]
+AUDIO
-[KM3_1]
-~g~Il Cartello aspetta una gang di Yardie. Vai a rubare una loro auto! Dirigiti a nord, ne troverai una a Newport.
+[FEH_DIS]
+VIDEO
-[LOVE1_1]
-~g~Procurati un'auto dei gangster Colombiani per infiltrarti nel loro nascondiglio: dirigiti a nord, ne troverai una a Fort Staunton.
+[FEH_LAN]
+LINGUA
-[FM1_Q1]
-~w~Ti va di divertirti? Un po' di... hmmm? Un po' di SPANK?
+[FEH_SGA]
+NUOVA PARTITA
-[FM1_R]
-~w~Ciao Chico. No, il solito.
+[FEO_CON]
+Impostazioni controller
-[FM1_T]
-~w~Grazie Chico, a presto.
+[FEO_AUD]
+Impostazioni audio
-[FM1_W]
-~w~OK, Fido, aspetta qui e tieni d'occhio l'auto mentre io vado a sculettare un po'.
+[FEO_DIS]
+Impostazioni video
-[FM1_X]
-~w~OK, Fido, andiamocene via di qui. Uuuhhh!
+[FEO_LAN]
+Impostazioni lingua
-[FM1_Q]
-~w~Ehi, Maria! La mia ragazza preferita!
+[FEO_PLA]
+Impostazioni giocatore
-[FM1_S1]
-~w~Ehi, forse dovresti dare un'occhiata al party nei magazzini sulla costa est del molo atlantico.
+[FEA_OUT]
+Uscita
-[FM1_U]
-~w~Gracias e buon divertimento. È roba buona.
+[FEA_ST]
+Stereo
-[FM1_V]
-~w~Forza, Fido, facciamo un salto a questo party!
+[FEA_DTS]
+DTS
-[FM1_SS]
-~r~SCANNER: ~g~4-5 a tutte le unità: rinforzi per l'operazione antinarcotici al molo atlantico...
+[FEA_RSS]
+Stazione radio
-[LOVE6_B]
-Anche se hanno scarsa comprensione del suo autentico valore.
+[FEA_NON]
+NO RADIO
-[TM3_A1]
-~r~Joey è spacciato!
+[FEA_FM0]
+WILDSTYLE
-[TM3_A2]
-~r~Joey e Luigi sono stati cremati!
+[FEA_FM1]
+FLASH FM
-[TM3_A3]
-~r~Joey, Luigi e Toni sono fritti!
+[FEA_FM2]
+KCHAT
-[FM4_2]
-Ascolta, Salvatore pensa che vogliamo tradirlo,
+[FEA_FM3]
+FEVER 105
-[FM4_3]
-per cui ti stava per consegnare al Cartello per raggiungere un accordo.
+[FEA_FM4]
+VROCK
-[FM4_4]
-Non potevo lasciarglielo fare, e poi la cosa peggiore è che
+[FEA_FM5]
+VCPR
-[FM4_4B]
-è tutta colpa mia... perché gli ho detto che stavamo insieme.
+[FEA_FM7]
+EMOTION 98.3
-[FM4_5]
-Non chiedermi il perché. Non lo so.
+[FEA_FM8]
+WAVE 103
-[FM4_6]
-Senti, sei un uomo spacciato in territorio mafioso, e anch'io devo svignarmela.
+[FED_BRI]
+Luminosità
-[FM4_6B]
-Ho visto troppi omicidi. Troppo sangue!
+[FED_TRA]
+Tracce :
-[FM4_7]
-Questa è una mia vecchia amica, OK, di vecchia data. È Asuka, ed è una tipa fidata.
+[FED_SUB]
+Sottotitoli
-[FM4_8]
-Forza, basta con i discorsi.
+[FED_WIS]
+Panoramico
-[FM4_9]
-Dovremmo andarcene prima che arrivino altri italiani isterici poco propensi a una discussione amichevole.
+[FED_POS]
+Posizione schermo
-[CRED001]
-ROCKSTAR STUDIOS
+[FEP_RES]
+Riprendi
-[CRED002]
-PRODUTTORE
+[FEP_STG]
+Avvia partita
-[CRED003]
-LESLIE BENZIES
+[FEP_STA]
+Statistiche
-[CRED004]
-DIREZIONE ARTISTICA
+[FEP_BRI]
+Briefing
-[CRED005]
-AARON GARBUT
+[FEP_OPT]
+Opzioni
-[CRED006]
-DIREZIONE TECNICA
+[FEP_QUI]
+Esci
-[CRED007]
-OBBE VERMEIJ
+[FES_LOA]
+Carica partita
-[CRED008]
-ADAM FOWLER
+[FES_DEL]
+Elimina partita
-[CRED009]
-DESIGN
+[FEC_CSU]
+Impostazioni controller
-[CRED010]
-CRAIG FILSHIE
+[FEC_RED]
+Ridefinisci comandi
-[CRED011]
-WILLIAM MILLS
+[FEC_MOU]
+Impostazioni mouse
-[CRED012]
-CHRIS ROTHWELL
+[DISTGOL]
+Distanza percorsa su cart da golf (miglia)
-[CRED013]
-JAMES WORRALL
+[DISTGOM]
+Distanza percorsa su cart da golf (metri)
-[CRED014]
-SCRITTO DA
+[ST_FAVR]
+Stazione radio preferita
-[CRED015]
-JAMES WORRALL
+[ST_WSTR]
+Stazione radio meno amata
-[CRED016]
-PAUL KUROWSKI
+[ST_FAVV]
+Veicolo preferito
-[CRED017]
-DAN HOUSER
+[ST_STAR]
+Totale stelle di sospetto
-[CRED018]
-PERSONAGGI
+[ST_HEAD]
+Colpi alla testa
-[CRED019]
-IAN MCQUE
+[ST_GANG]
+Gang meno amata
-[CRED020]
-ANIMAZIONE E REGIA
+[ST_STGN]
+Totale stelle di sospetto evase
-[CRED021]
-ALEX HORTON
+[TYREPOP]
+Pneumatici esplosi con proiettili
-[CRED022]
-LEE MONTGOMERY
+[TYRESLA]
+Pneumatici tagliati con una lama
-[CRED023]
-DESIGN AUTOMOBILI
+[ST_BRK]
+Numero di uccisioni nel Bloodring
-[CRED024]
-PAUL KUROWSKI
+[ST_LTBR]
+Permanenza massima nel Bloodring (sec)
-[CRED025]
-GRAFICI
+[ST_GNG1]
+Cubani
-[CRED026]
-KEIRAN BAILLIE
+[ST_GNG2]
+Haitiani
-[CRED027]
-ADAM COCHRANE
+[ST_GNG3]
+Teppistelli
-[CRED028]
-GARY MCADAM
+[ST_GNG4]
+Gang di Diaz
-[CRED029]
-MICHAEL PIRSO
+[ST_GNG5]
+Sorveglianza
-[CRED030]
-ANDREW SOOSAY
+[ST_GNG6]
+Gang di motociclisti
-[CRED031]
-ALISDAIR WOOD
+[ST_GNG7]
+Gang di Vercetti
-[CRED032]
-CODIFICATORI
+[ST_GNG8]
+Giocatori di golf
-[CRED033]
-ALAN CAMPBELL
+[FEA_FM6]
+ESPANTOSO
-[CRED034]
-MARK HANLON
+[ST_ASSI]
+Contratti da sicario completati
-[CRED035]
-ANDRZEJ MADAJCZYK
+[DISTBIK]
+Distanza percorsa in moto (miglia)
-[CRED036]
-ALEXANDER ROGER
+[DISTBIM]
+Distanza percorsa in moto (metri)
-[CRED037]
-GRAEME WILLIAMSON
+[HOTEL]
+Hotel Ocean View
-[CRED038]
-MUSICHE
+[ICC1_1]
+~g~Utilizza il camioncino dei gelati per distribuire droga in Vice City.
-[CRED039]
-CRAIG CONNER
+[ICC1_2]
+~g~Parcheggia il camioncino e premi ~h~~k~~VEHICLE_HORN~~w~ per attivare il campanello e attrarre i clienti.
-[CRED040]
-STUART ROSS
+[ICC1_3]
+~g~Riceverai soldi per ogni transizione, ma più ne esegui, maggiori saranno le probabilità di attirare l'attenzione della polizia.
-[CRED041]
-DESIGN AUDIO E MASTERIZZAZIONE
+[KICK1_9]
+PUNTI DI CONTROLLO RIMANENTI:
-[CRED042]
-ALLAN WALKER
+[FIN_B6]
+Non hai abbastanza soldi per avviare questa missione.
-[CRED043]
-PROGRAMMAZIONE AUDIO
+[TEX3_3]
+~g~Per raccogliere una bomba, avvicinati con l'elicottero: la bomba verrà automaticamente raccolta.
-[CRED044]
-RAYMOND USHER
+[TEX3_9]
+~g~Raccogli una bomba avvicinandole l'elicottero.
-[CRED045]
-DIRETTORE TESTING
+[HELP22]
+Raggiungi la casa verde sul radar.
-[CRED046]
-CRAIG ARBUTHNOTT
+[FES_FMS]
+Formattazione completata. Seleziona OK per continuare.
-[CRED047]
-TESTER PRINCIPALI
+[FES_SSC]
+Salvataggio completato. Seleziona OK per continuare.
-[CRED048]
-ANDY DUTHIE
+[FES_DSC]
+Eliminazione completata. Seleziona OK per continuare.
-[CRED049]
-JOHN HAIME
+[FESZ_QC]
+Vuoi sovrascrivere il salvataggio corrotto?
-[CRED050]
-NEIL CORBETT
+[FES_CHE]
+Attenzione! Uno o più trucchi sono stati attivati: ciò influenzerà il salvataggio. Si consiglia di non salvare questa partita.
-[CRD050A]
-TESTER
+[FET_SG]
+SALVA PARTITA
-[CRED051]
-GRAEME JENNINGS
+[FEH_BRI]
+BRIEFING
-[CRED052]
-DAVID MURDOCH
+[FEH_MAP]
+MAPPA
-[CRED053]
-DAVID BEDDOES
+[FEM_OK]
+OK
-[CRED054]
-EDWIN SMITH
+[FEC_CRO]
+Abbassarsi
-[CRED055]
-MARK FLETT
+[FEC_CR3]
+Abbassarsi (tasto L3)
-[CRED056]
-MICHAEL SUTHERLAND
+[FEC_SMT]
+Sottomissione
-[CRED057]
-SUPPORTO TECNICO
+[FEC_SM3]
+Sottomissione (tasto R3)
-[CRED058]
-LORRAINE ROY
+[FEC_RSC]
+Stazioni radio
-[CRED059]
-CHRISTINE CHALMERS
+[ST_PR01]
+Apprendista
-[CRED060]
-ROCKSTAR
+[ST_PR02]
+Aviere
-[CRED061]
-PRODUTTORE ESECUTIVO
+[ST_PR03]
+Ufficiale
-[CRED062]
-SAM HOUSER
+[ST_PR04]
+Caporale
-[CRED063]
-PRODUTTORE
+[ST_PR05]
+Tenente
-[CRED064]
-DAN HOUSER
+[ST_PR06]
+Sergente
-[CRED065]
-DIRETTORE DI SVILUPPO
+[ST_PR07]
+Capitano
-[CRED066]
-JAMIE KING
+[ST_PR08]
+Biggs
-[CRED067]
-PRODUTTORE TECNICO
+[ST_PR09]
+Wedge
-[CRED068]
-GARY J. FOREMAN
+[ST_PR10]
+Barone rosso
-[CRED069]
-PRODUTTORE ASSOCIATO
+[ST_PR11]
+Goose
-[CRED070]
-JEREMY POPE
+[ST_PR12]
+Viper
-[CRED071]
-SUPERVISORE MUSICHE
+[ST_PR13]
+Jester
-[CRED072]
-TERRY DONOVAN
+[ST_PR14]
+Chappy
-[CRED073]
-ROCKSTAR PRODUCTION TEAM
+[ST_PR15]
+Iceman
-[CRED074]
-TERRY DONOVAN
+[ST_PR16]
+Maverick
-[CRED075]
-JENNIFER KOLBE
+[ST_PR17]
+Noops
-[CRED076]
-JENEFER GROSS
+[ST_PR18]
+Maresciallo
-[CRED077]
-LAURA PATERSON
+[ST_PR19]
+Asso
-[CRED078]
-JEFF CASTANEDA
+[FET_LG]
+CARICA PARTITA
-[CRED079]
-CHRIS CARRO
+[CAR_EXP]
+Veicoli distrutti
-[CRED080]
-ADAM TEDMAN
+[BOA_EXP]
+Imbarcazioni distrutte
-[CRED081]
-JUNG KWAK
+[HEL_DST]
+Velivoli distrutti
-[CRED082]
-BRIAN WOOD
+[STFT_01]
+Tempo migliore in 'Due ruote d'acciaio'
-[CRED083]
-PAUL YEATES
+[STFT_02]
+Tempo migliore in 'L'autista'
-[CRED084]
-STANTON SARJEANT
+[STFT_03]
+Tempo migliore nella prova del fango
-[CRED085]
-VICEPRESIDENTE MARKETING
+[STFT_04]
+Tempo migliore con gli aerei radiocomandati
-[CRED086]
-TERRY DONOVAN
+[STFT_05]
+Tempo migliore con le macchine radiocomandate
-[CRED087]
-COORDINATORE TECNICO
+[STFT_06]
+Tempo migliore di raccolta con l'elicottero
-[CRED088]
-BRANDON ROSE
+[STFT_07]
+Tempo migliore in 'Terminal Velocity'
-[CRED089]
-RESPONSABILE CONTROLLO QUALITÀ
+[STFT_08]
+Tempo migliore in 'Ocean Drive'
-[CRED090]
-JEFF ROSA
+[STFT_09]
+Tempo migliore in 'Border Run'
-[CRED091]
-LEAD ANALYST
+[STFT_10]
+Tempo migliore in 'Capital Cruise'
-[CRED092]
-ADAM DAVIDSON
+[STFT_11]
+Tempo migliore in 'Tour!'
-[CRED093]
-ANALISTA DEL GIOCO
+[STFT_12]
+Tempo migliore in 'V.C. Endurance'
-[CRED094]
-RICHARD HUIE
+[STHC_01]
+Punteggio migliore al poligono
-[CRED095]
-SQUADRA TESTING
+[STHC_02]
+Miglior percentuale di colpi al poligono
-[CRED096]
-LANCE WILLIAMS
+[STHC_03]
+Numero di traffici di droga
-[CRED097]
-JOE GREENE
+[HELP24]
+Adesso puoi accettare le missioni del Colonnello.
-[CRED098]
-BRIAN PLANER
+[HELP25]
+Adesso puoi accettare le missioni di Avery Carrington.
-[CRED099]
-OSWALD GREENE
+[HELP29]
+Puoi far visita al negozio di abbigliamento quando non sei in missione.
-[CRED100]
-PIANTA DI LIBERTY
+[HELP30]
+Quando compri nuovi abiti, il tuo livello di sospetto scenderà a zero.
-[CRED101]
-JAMES WORRALL
+[BJM2_22]
+~r~Sei uscito dal poligono di tiro!
-[CRED102]
-DAN HOUSER
+[BJM2_23]
+~g~Se esci dal poligono di tiro durante la competizione, fallirai la missione.
-[CRED103]
-ADAM TEDMAN
+[ASM4_24]
+Distanza:
-[CRED104]
-PAUL YEATES
+[RBM1_6]
+~g~Porta Mercedes e la 'Love Juice' al gruppo nello studio di registrazione.
-[CRED105]
-JENEFER GROSS
+[RBM1_3]
+NON NECESSARIO
-[CRED106]
-LAURA PATERSON
+[HAM1_5]
+NON NECESSARIO
-[CRED107]
-SEQUENZE ANIMATE
+[RBM1_11]
+NON NECESSARIO
-[CRED108]
-COPIONE SCRITTO DA DAN HOUSER E JAMES WORRALL
+[HELP31]
+Per eseguire un assalto in macchina, guarda a destra o a sinistra premendo il tasto L2 o il tasto R2.
-[CRED109]
-REGISTRAZIONE AUDIO DIRETTA DA DAN HOUSER
+[HELP34]
+Hai bisogno di una mitragliatrice per eseguire un assalto in macchina.
-[CRED110]
-AUDIO PRODOTTO DA RENAUD SEBBANE
+[STRIP_1]
+~r~Soldi insufficienti, brutto idiota.
-[CRED111]
-CASTING
+[EXIT_1]
+Premi ~k~~PED_SPRINT~ per uscire.
-[CRED112]
-FRANK VINCENT NEL RUOLO DI SALVATORE LEONE
+[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'.
-[CRED113]
-JOE PANTOLIANO NEL RUOLO DI LUIGI GOTERELLI
+[ASM1_B]
+I dettagli per il prossimo colpo sono stati attaccati sotto al telefono.
-[CRED114]
-MICHAEL MADSEN NEL RUOLO DI TONI CIPRIANI
+[ASM1_C]
+Ho un altro compito con un contatto più 'diretto'.
-[CRED115]
-MICHAEL RAPAPORT NEL RUOLO DI JOEY LEONE
+[SCARF]
+Appartamento 3c
-[CRED116]
-DEBBI MAZAR NEL RUOLO DI MARIA
+[LAW4_10]
+La ricca amministrazione ci ha rotto!
-[CRED117]
-KYLE MACLACHLAN NEL RUOLO DI DONALD LOVE
+[GEN1_04]
+~g~Attraversa la porta per accedere alla piattaforma sul tetto di Gonzalez.
-[CRED118]
-ROBERT LOGGIA NEL RUOLO DI RAY MACHOWSKI
+[GEN1_17]
+~g~Gonzalez sta fuggendo! Seguilo attraverso le porte e finiscilo!
-[CRED119]
-GURU NEL RUOLO DI 8-BALL
+[RCH1_9]
+~b~TEMPO TOTALE: ~1~:~1~
-[CRED120]
-SONDRA JAMES NEL RUOLO DI MOMMA
+[RCH1_10]
+~b~TEMPO TOTALE: ~1~:0~1~
-[CRED121]
-LIANA PAI NEL RUOLO DI ASUKA
+[WHEEL01]
+BONUS DOPPIO SU DUE RUOTE: ~1~$ Distanza: ~1~.~1~ m Tempo: ~1~ secondi
-[CRED122]
-LES MAU NEL RUOLO DI KENJI
+[WHEEL02]
+BONUS DOPPIO SU DUE RUOTE: ~1~$ Distanza: ~1~ piedi Tempo: ~1~ secondi
-[CRED123]
-CYNTHIA FARRELL NEL RUOLO DI CATALINA
+[WHEEL03]
+BONUS SU DUE RUOTE: ~1~$ Tempo: ~1~ secondi
-[CRED124]
-AL ESPINOSA NEL RUOLO DI MIGUEL
+[WHEEL04]
+BONUS SU DUE RUOTE: ~1~$ Distanza: ~1~.~1~ m
-[CRED125]
-CHRIS PHILLIPS NEL RUOLO DI EL BURRO
+[WHEEL05]
+BONUS SU DUE RUOTE: ~1~$ Distanza: ~1~ piedi
-[CRED126]
-HUNTER PLATIN NEL RUOLO DI CHICO
+[WHEEL06]
+BONUS IMPENNATA: ~1~$ Distanza: ~1~.~1~ m Tempo: ~1~ secondi
-[CRED127]
-WALTER MUDU NEL RUOLO DI D-ICE
+[WHEEL07]
+BONUS IMPENNATA: ~1~$ Distanza: ~1~ piedi Tempo: ~1~ secondi
-[CRED128]
-CURTIS MCCLARIN NEL RUOLO DI CURTLY
+[WHEEL08]
+BONUS IMPENNATA: ~1~$ Tempo: ~1~ secondi
-[CRED129]
-BILL FIORE NEL RUOLO DI DARKEL
+[WHEEL09]
+BONUS IMPENNATA: ~1~$ Distanza: ~1~.~1~ m
-[CRED130]
-CHRIS PHILLIPS NEL RUOLO DI MARTY CHONKS
+[WHEEL10]
+BONUS IMPENNATA: ~1~$ Distanza: ~1~ piedi
-[CRED131]
-HUNTER PLATIN NEL RUOLO DI RICCIOLINO BOB
+[WHEEL11]
+BONUS FRENATA IN PUNTA: ~1~$ Distanza: ~1~.~1~ m Tempo: ~1~ secondi
-[CRED132]
-WALTER MUDU NEL RUOLO DI KING COURTNEY
+[WHEEL12]
+BONUS FRENATA IN PUNTA: ~1~$ Distanza: ~1~ piedi Tempo: ~1~ secondi
-[CRED133]
-HUNTER PLATIN NEL RUOLO DI ONE-ARMED PHIL
+[WHEEL13]
+BONUS FRENATA IN PUNTA: ~1~$ Tempo: ~1~ secondi
-[CRED134]
-KIM GURNEY NEL RUOLO DI MISTY
+[WHEEL14]
+BONUS FRENATA IN PUNTA: ~1~$ Distanza: ~1~.~1~ m
-[CRED135]
-MOTION CAPTURE
+[WHEEL15]
+BONUS FRENATA IN PUNTA: ~1~$ Distanza: ~1~ piedi
-[CRED136]
-ANIMATO DA
+[ROK3_72]
+Love Fist!
-[CRD136A]
-ALEX HORTON
+[POR1_19]
+Ehi!
-[CRED137]
-DIRETTO DA
+[DESPERA]
+Desperado
-[CRD137A]
-NAVID KHONSARI
+[MOB_99A]
+Raggiungi il telefono pubblico vicino al Mall in Washington.
-[CRED138]
-PRODOTTO DA
+[MOB_98A]
+Raggiungi il telefono pubblico in Vice Point.
-[CRD138A]
-JAMIE KING
+[MOB_96A]
+Raggiungi il telefono pubblico al terminal dell'aeroporto.
-[CRD138B]
-RENAUD SEBBANE
+[MOB_95A]
+Raggiungi il telefono pubblico in Little Havana.
-[CRED139]
-REGISTRATO PRESSO GLI STUDI MODERN UPRISING, BROOKLYN
+[BNK1_1]
+La posso aiutare, signore?
-[CRED140]
-ATTORI
+[BNK1_2]
+Un impostore!
-[CRD140A]
-RENAUD SEBBANE
+[BNK1_3]
+È impazzito!
-[CRD140B]
-GISELLE JONES
+[BNK1_4]
+Ma chi diavolo sei?
-[CRD140C]
-STEPHEN DANIELS
+[BNK1_5]
+Dov'è il tuo distintivo?
-[CRD140D]
-ROBERT STIO
+[BNK1_6]
+Eccoli là! Sparate per uccidere!
-[CRD140E]
-JENNY GROSS
+[MOB_24A]
+Salve: Mr Vercetti?
-[CRED141]
-DIALOGO DEI PEDONI
+[MOB_24B]
+Sì.
-[CRED142]
-SCRITTO DA DAN HOUSER, NAVID KHONSARI & JAMES WORRALL
+[MOB_24C]
+Sono Cortez. Eri invitato al mio party.
-[CRED143]
-DIRETTO DA CRAIG CONNER, DAN HOUSER E LAZLOW
+[MOB_24D]
+Sì, ricordo.
-[CRED144]
-PRODOTTO DA RENAUD SEBBANE
+[MOB_24E]
+Mr. Vercetti, è stato davvero uno sfortunato incidente quello avvenuto al tuo accordo.
-[CRED145]
-CAST
+[MOB_24F]
+Lo so.
-[CRED146]
-HUNTER PLATIN
+[MOB_24G]
+Sappi che io e la mia gente stiamo facendo il massimo per scoprire cosa è successo.
-[CRED147]
-DAN HOUSER
+[MOB_24H]
+Se vuoi parlarne in prima persona, mi troverai sulla mia barca. Buona giornata, senor.
-[CRED148]
-RENAUD SEBBANE
+[BNK2_2]
+MIRARE 3-2-1 FUOCO!
-[CRED149]
-MARIA CHAMBERS
+[BNK2_3]
+AREA RIPULITA!
-[CRED150]
-JEFF STANTON
+[BNK2_6]
+Questo tipo è pazzo!
-[CRED151]
-RYAN CROY
+[ANGEL]
+Angel
-[CRED152]
-DEENA BERMAN
+[CUBJET]
+Jetmax Cubano
-[CRED153]
-MARIA CHAMBERS
+[SANDKIN]
+Sandking
-[CRED154]
-ALICE B. SALTZMAN
+[POLMAV]
+Maverick della polizia
-[CRED155]
-ALEX ANTHONY SIOUKAS
+[BOXVILL]
+Boxville
-[CRED156]
-SEAN R. LYNCH
+[BENSON]
+Benson
-[CRED157]
-AMY SALZMAN
+[HOTRINA]
+Hotring Racer
-[CRED158]
-COLIN MCSHANE
+[HOTRINB]
+Hotring Racer
-[CRED159]
-COREY WADE
+[BLOODRA]
+Bloodring Banger
-[CRED160]
-GERALD COSGROVE
+[BLOODRB]
+Bloodring Banger
-[CRED161]
-STEPHANIE ROY
+[MAFIACR]
+Cruiser della Mafia
-[CRED162]
-DORIS WOO
+[COP_M2]
+'VICE SQUAD'
-[CRED163]
-JOSEPH GREENE
+[COP_M3]
+'BROWN THUNDER'
-[CRED164]
-LAZLOW JONES
+[BJM2_20]
+~g~Quando finisci il ~w~tempo~g~ o i ~w~colpi~g~, il turno è finito!
-[CRED165]
-HSIANG LIN
+[BNK3_2]
+Non intendo guidare per te, per niente, e lo dirò ai miei compagni di terapia.
-[CRED166]
-STEVE MICHAEL ROBERT
+[FEM_SL1]
+Salvataggio 1 non trovato
-[CRED167]
-MATHEW MURRAY
+[FEM_SL2]
+Salvataggio 2 non trovato
-[CRED168]
-RICHARD HUIE
+[FEM_SL3]
+Salvataggio 3 non trovato
-[CRED169]
-GARVIN ATWELL
+[FEM_SL4]
+Salvataggio 4 non trovato
-[CRED170]
-STEVE KNEZEVICH
+[FEM_SL5]
+Salvataggio 5 non trovato
-[CRED171]
-YUKIMURA SATO
+[FEM_SL6]
+Salvataggio 6 non trovato
-[CRED172]
-FRANK CHAVEZ
+[FEM_SL7]
+Salvataggio 7 non trovato
-[CRED173]
-LIEZL JACINTO
+[FEM_SL8]
+Salvataggio 8 non trovato
-[CRED174]
-CANAAN MCKOY
+[FEA_CHA]
+Modifica uscita audio in STEREO. Attendere...
-[CRED175]
-ADAM DAVIDSON
+[FEA_CHD]
+Attenzione! Modifica uscita audio da STEREO a DTS. Attendere...
-[CRED176]
-LANCE WILLIAMS
+[FEI_SEL]
+Seleziona
-[CRED177]
-NEIL MCCAFFREY
+[FEI_BAC]
+Indietro
-[CRED178]
-LAURA PATERSON
+[FEI_RES]
+Riprendi
-[CRED179]
-REY CONCEPCION
+[FEI_NAV]
+Naviga
-[CRED180]
-CHARLES HEROLD
+[FEI_BTX]
+Tasto / -
-[CRED181]
-ANDREW GREENWALD
+[FEI_BTT]
+Tasto " -
-[CRED182]
-JAMES MIELKE
+[FEI_STA]
+Tasto START -
-[CRED183]
-PETER SUCIU
+[FEI_BTD]
+; = > < -
-[CRED184]
-ALEX ODULIO
+[FEI_STO]
+Stop
-[CRED185]
-DON NKRUMAH
+[MOB_68A]
+Ehi Tommy, ho una sorpresa per te.
-[CRED186]
-KENDALL PITTMAN
+[MOB_68B]
+Sono allo studio cinematografico con dei grandi artisti.
-[CRED187]
-SAL SUAZO
+[MOB_68C]
+Perché non vieni a farci visita?
-[CRED188]
-EREK MATEO
+[MOB_68D]
+Lo sai che è una buona idea, vero? Ci vediamo.
-[CRED189]
-CHRIS DIFATE
+[OUTFT1]
+Da strada
-[CRED190]
-LEILA MILTON
+[OUTFT2]
+Eleganti
-[CRED191]
-DARREN ZOLTOWSKI
+[OUTFT3]
+Tuta
-[CRED192]
-VIRGINIA SMITH
+[OUTFT4]
+Sportivo
-[CRED193]
-KEVIN CASSIN
+[OUTFT5]
+Havana
-[CRED194]
-JASON SHIGEMORI
+[OUTFT6]
+Da poliziotto
-[CRED195]
-KELLY KINSELLA
+[OUTFT7]
+Da rapina
-[CRED196]
-MOLLIE STICKNEY
+[OUTFT8]
+Casual
-[CRED197]
-STANTON SARJEANT
+[OUTFT9]
+Mr. Vercetti
-[CRED198]
-LAURA WALSH
+[OUTFT10]
+Da corsa
-[CRED199]
-MARK GARONE
+[OUTFT13]
+MC Tommy
-[CRED200]
-JOANNA SLY
+[HOTR_07]
+Nuovo miglior tempo: ~1~:0~1~
-[CRED201]
-ELIZABETH HOWELL
+[HOTR_08]
+Tempo: ~1~:~1~
-[CRED202]
-ANA HERCULES
+[GEN3_45]
+Arriveranno fra pochi minuti: troviamo un buon punto dove appostarci...
-[CRED203]
-SHIRLEY IRICK
+[CAR_AS1]
+BENI CONCESSIONARIA ACQUISITI
-[CRED204]
-KASHONA FIELDS
+[CAR_AS2]
+~g~La concessionaria d'ora in poi genererà introiti per un massimo di ~1~$. Ricordati di recuperarli regolarmente.
-[CRED205]
-JOEL M. LILJE
+[BUYSAVE]
+~g~Se non sei in missione, potrai ora salvare la partita da qui gratuitamente.
-[CRED206]
-JOHN DIBENEDETTO
+[BUYGARG]
+~g~Potrai anche depositare i mezzi in questo garage.
-[CRED207]
-NANCY GILES
+[STRPBUY]
+Club Pole Position acquistato: ~1~$
-[CRED208]
-RYAN CROY
+[STRP_R3]
+Premi il tasto R3 per acquistare il club Pole Position per ~1~$
-[CRED209]
-JENNIFER KOLBE
+[NBMN_R3]
+Premi il tasto R3 per acquistare Elswanko Casa per ~1~$
-[CRED210]
-LIAM BURKE
+[GA_4]
+Le bombe per le macchine costano 1000$
-[CRED211]
-SIGRID PREISSL
+[GA_5]
+La tua macchina ha già una bomba installata.
-[CRED212]
-ANITA FITZSIMONS
+[GA_6]
+Parcheggiala, attivala premendo il ~h~~k~~PED_FIREWEAPON~~w~ e DATTELA A GAMBE!
-[CRED213]
-PHILIPPA RASELLI
+[GA_7]
+Arma la bomba con il ~h~~k~~PED_FIREWEAPON~~w~: esploderà non appena qualcuno cercherà di avviarla.
-[CRED214]
-WIL QUESNEL
+[GA_6B]
+Parcheggiala, attivala premendo il ~h~~k~~PED_FIREWEAPON~~w~ e DATTELA A GAMBE!
-[CRED215]
-FALKO BURKERT
+[GA_7B]
+Arma la bomba con il ~h~~k~~PED_FIREWEAPON~~w~: esploderà non appena qualcuno cercherà di avviarla.
-[CRED216]
-SARA SEWELL
+[MOB_70A]
+Tommy, sono io, il Colonnello Cortez. Ascolta senor, credo tu sia una persona capace di risolvere i problemi.
-[CRED217]
-STAZIONI RADIO E MUSICA
+[MOB_70B]
+Mi troverai sulla mia barca.
-[CRED218]
-PRODUTTORI PER ROCKSTAR UK
+[PICK1]
+Giubbotto antiproiettile consegnato all'hotel Ocean View!
-[CRD218A]
-CRAIG CONNER
+[PICK2]
+.357 consegnato al nascondiglio!
-[CRD218B]
-STUART ROSS
+[PICK3]
+Motosega consegnata al nascondiglio!
-[CRED219]
-COORDINATORE COLONNA SONORA
+[PICK4]
+Lanciafiamme consegnato al nascondiglio!
-[CRED220]
-TERRY DONOVAN
+[PICK5]
+.308 Fucile di precisione consegnato al nascondiglio!
-[CRED221]
-PRODUTTORE PER ROCKSTAR GAMES
+[PICK6]
+Mitragliatore consegnato al nascondiglio!
-[CRED222]
-DAN HOUSER
+[PICK7]
+Lanciamissili consegnato al nascondiglio!
-[CRED223]
-POST-PRODOTTA DA
+[PICK8]
+Sea Sparrow adesso disponibile alla villa!
-[CRED224]
-CRAIG CONNER
+[PICK9]
+Carro armato adesso disponibile alle caserme!
-[CRED225]
-ALLAN WALKER
+[PICK10]
+Hunter adesso disponibile alle caserme!
-[CRED226]
-LAZLOW
+[HELP41]
+o puoi speronarli con il tuo mezzo
-[CRED227]
-DJ BANTER E IMAGING SCRITTE DA
+[ICC1_6]
+~g~Utilizza il Mr. Whopee per distribuire i prodotti Cherry Poppers per Vice City.
-[CRED228]
-DAN HOUSER
+[ICC1_12]
+PROPRIETÀ ACQUISTATA!
-[CRED229]
-LAZLOW
+[CLOTH1]
+Abiti eleganti consegnati a Rafaels in Ocean Beach.
-[CRED230]
-RINGRAZIAMENTI SPECIALI A
+[CLOTH2]
+Abiti da strada consegnati al nascondiglio.
-[CRED231]
-ADAM TEDMAN
+[CLOTH3]
+Tuta consegnata a Tooled Up nel Mall North Point.
-[CRED232]
-ALEX MASON
+[CLOTH4]
+Abiti sportivi consegnati al club di Golf in Leafs Links.
-[CRED233]
-JUDY HENDERSON CASTING
+[CLOTH5]
+Abiti havana consegnati a Little Havana Streetwear in Little Havana.
-[CRED234]
-HAMISH BROWN
+[CLOTH6]
+Abiti da poliziotto consegnati alla stazione di polizia in Washington Beach.
-[CRED235]
-CHRISSY HOBAN
+[CLOTH7]
+Abiti casual consegnati a Gash nel Mall North Point.
-[CRED236]
-INNES RICARD
+[CLOTH8]
+Abiti Mr. Vercetti consegnati a Collar & Cuffs in Ocean Beach.
-[CRED237]
-LILION BROZSKA
+[CLOTH9]
+Abiti da corsa consegnati a Jocksport in Downtown.
-[CRED238]
-BOB HILLARY
+[CLOTH10]
+Abiti da rapina consegnati al club Malibu in Vice Point.
-[CRED239]
-EMILY ANDERSON
+[RBM1_9]
+~g~Recupera della Love Juice dallo spacciatore per i Love Fist!
-[CRED240]
-RICHIE HENDERSON
+[MOB_62A]
+Tommy, sono Ricardo Diaz. Ti volevo ringraziare per l'aiuto ai miei uomini.
-[CRED241]
-CHRSTIAN CANTAMESSA
+[MOB_62B]
+Ho chiesto a quel coglione di Cortez e mi ha detto che il vero affare sei tu. Amico, vienimi a trovare.
-[CRED242]
-JERONIMO BARRERA
+[MOB_62C]
+Ho bisogno di un tipo come te. Sono circondato da coglioni,
-[CRED243]
-ALEXANDER ILLES
+[MOB_62D]
+coglioni dappertutto, davvero. Ti farò diventare ricco.
-[CRED244]
-BARANE CHAN
+[GOAWAY2]
+~g~Ritorna quando avrai completato le missioni dei motociclisti.
-[CRED245]
-DUNCAN SHIELDS
+[COL2_9]
+Idiota di un americano! Ti sei fatto seguire!
-[CRED246]
-BARANE CHAN
+[LOADCOL]
+Caricamento...
-[CRED247]
-DEREK PAYNE
+[STFT_17]
+Tempo migliore in 'Parco divertimenti PCJ'
-[CRED248]
-KEVIN WONG
+[STFT_18]
+Tempo migliore in 'Prova del fango'
-[CRED249]
-ROSS ELLIOTT
+[STFT_19]
+Tempo migliore in 'Tracciato di prova'
-[CRED250]
-ROSS BEAZLEY
+[NEW_REC]
+Nuovo record!!! ~1~ minuti e ~1~ secondi.
-[CRED251]
-ALEX BAZLINTON
+[BMX_HOW]
+~g~Fai due giri sul tracciato sterrato, ~y~passando attraverso~g~ i ~y~PUNTI DI CONTROLLO~g~!
-[CRED252]
-DAVE WATSON
+[BMXREW1]
+~g~Ogni volta che batti il tuo record precedente per i due giri,
-[CRED253]
-MALCOLM SMITH
+[BMXREW2]
+~g~otterrai una ~y~RICOMPENSA~g~ più cospicua!
-[CRED255]
-ANDREW SEMPLE
+[BMXRAIN]
+~g~È come se piovesse...
-[CRED256]
-ARTIST
+[ITBEG]
+All'inizio...
-[CRED257]
-STUART PETRI
+[NBMNBUY]
+El Swanko Casa acquistata: ~1~$
-[CRED258]
-JERONIMO BARRERA
+[LNKVBUY]
+Appartamento Links View acquistato: ~1~$
-[CRED259]
-CARLY SLATER
+[HYCOBUY]
+Condominio Hyman acquistato: ~1~$
-[CRED260]
-GREG LAU
+[BUYGARS]
+~g~Puoi parcheggiare altri veicoli in questi garage.
-[CRED261]
-STEVE KNEZEVICH
+[OCHEBUY]
+Appartamento Ocean Heights acquistato: ~1~$
-[CRED262]
-DEVIN WINTERBOTTOM
+[WASHBUY]
+1102 Washington Street acquistata: ~1~$
-[CRED263]
-JAMEEL VEGA
+[VCPTBUY]
+3321 Vice Point acquistata: ~1~$
-[CRED264]
-LEE CUMMINGS
+[SKUMBUY]
+Skumole Shack acquistato: ~1~$
-[CRED265]
-DEVIN BENNET
+[HELP6_C]
+Premi il ~h~~k~~VEHICLE_HANDBRAKE~~w~ per tirare il freno a mano.
-[CRED266]
-ELIZABETH SATTERWHITE
+[HELP2_A]
+Premi il ~h~~k~~PED_SPRINT~~w~ mentre corri per effettuare uno ~h~scatto~w~.
-[CRED267]
-AARON RIGBY
+[HELP4_A]
+Premi il ~h~~k~~VEHICLE_ACCELERATE~~w~ per ~h~accelerare~w~.
-[CRED268]
-STEVE K.
+[HELP5_A]
+Premi il ~h~~k~~VEHICLE_BRAKE~~w~ per frenare o, se il veicolo è fermo, per inserire la retromarcia.
-[CRED269]
-GREG LAU
+[HELP8_A]
+Premi il ~h~~k~~PED_SNIPER_ZOOM_IN~~w~ per zoomare col fucile e il ~x~tasto /~w~ per allargare il campo.
-[CRED270]
-MIKE HONG
+[PBOAT_1]
+Premi il ~h~~k~~PED_FIREWEAPON~~w~ per sparare con i cannoni della barca.
-[CINCAM]
-Camera mobile
+[SEG3_4]
+~g~Puoi raccogliere una bomba avvicinando il Raider telecomandato. Per posizionare la bomba, premi il ~o~tasto |~g~.
-[KM1_13]
-Entra in auto dentro il garage!
+[RCR1_3]
+~g~Se desideri interrompere la missione, premi il ~h~~k~~PED_FIREWEAPON~~g~ per far esplodere la macchina.
-[KM3_14]
-~r~Sei stato scoperto, l'affare è saltato!
+[HELP32]
+Poi spara con il ~h~~k~~PED_FIREWEAPON~~w~.
-[EBAL_H]
-Aspetta qui mentre entro a parlare con Luigi.
+[HELP33]
+Poi spara con il ~h~~k~~PED_FIREWEAPON~~w~.
-[EBAL_M]
-Ricorda, niente casini con le mie ragazze!
+[TTUTOR]
+Premi il ~h~~k~~TOGGLE_SUBMISSIONS~~w~ per attivare o disattivare le missioni Taxi.
-[LM2_F]
-Poi prendi la sua macchina, riverniciala.
+[TTUTOR2]
+Premi il ~h~~k~~TOGGLE_SUBMISSIONS~~w~ per attivare o disattivare le missioni Taxi.
-[LM2_D]
-tieni, prendi.
+[FTUTOR]
+Premi il ~h~~k~~TOGGLE_SUBMISSIONS~~w~ per attivare o disattivare le missioni Camion dei pompieri.
-[LM1_9]
-Ciao, sono Misty.
+[FTUTOR2]
+Premi il ~h~~k~~TOGGLE_SUBMISSIONS~~w~ per attivare o disattivare le missioni Camion dei pompieri.
-[LM4_A]
-I papponi dei Diablo hanno messo a battere le loro mignotte nella mia zona.
+[CTUTOR]
+Premi il ~h~~k~~TOGGLE_SUBMISSIONS~~w~ per attivare o disattivare le missioni Vigilante.
-[FM2_B]
-C'è di mezzo una spia.
+[CTUTOR2]
+Premi il ~h~~k~~TOGGLE_SUBMISSIONS~~w~ per attivare o disattivare le missioni Vigilante.
-[FM2_C]
-Non è ne un pusher ne un pappone, quindi dev'essere una spia.
+[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.
-[FM3_CC]
-~w~Fratello, torna quando avrai i soldi.
+[ATUTOR3]
+Premi il ~h~~k~~TOGGLE_SUBMISSIONS~~w~ per attivare o disattivare le missioni Infermiere.
-[LOVE5_5]
-~r~Non sei riuscito a proteggere il camion!
+[GUN_H1]
+~w~Premi il ~h~~k~~PED_SPRINT~~w~ per comprare. ~w~Premi il ~h~~k~~VEHICLE_ENTER_EXIT~~w~ per uscire.
-[RM6_6]
-~r~Ray è morto!
+[PU_CF3]
+Premi il ~h~~k~~VEHICLE_ENTER_EXIT~~w~ per sostituire l'arma attuale con quella presente in questo slot.
-[RM6_7]
-~r~Ray ha perso il volo.
+[PU_CF4]
+Premi il ~h~~k~~VEHICLE_ENTER_EXIT~~w~ per sostituire l'arma attuale con quella presente in questo slot.
-[RM6_8]
-~g~Ti sei dimenticato Ray, torna a prenderlo.
+[HELP9_B]
+Premi il ~h~~k~~PED_FIREWEAPON~~w~ per sparare con il fucile di precisione.
-[FM1_10]
-~g~Ti sei dimenticato Maria, torna a prenderla.
+[HELP37]
+Se non vuoi entrare in un veicolo mentre stai assalendo un guidatore, premi il ~h~~k~~PED_SPRINT~~w~.
-[LOVE4_9]
-~r~L'aereo è stato distrutto!
+[HELP6_A]
+Premi il ~h~~k~~VEHICLE_HANDBRAKE~~w~ per tirare il freno a mano.
-[LOV4_10]
-~r~Il solo indizio che indicasse dov'è finito il pacco è stato distrutto!
+[HELP6_D]
+Premi il ~h~~k~~VEHICLE_HANDBRAKE~~w~ per tirare il freno a mano.
-[KM2_D]
-Non occorre dire che dobbiamo donargli le auto, per ripagare il debito che gli è dovuto.
+[HELP26]
+Premi il ~h~~k~~VEHICLE_ENTER_EXIT~~w~ per entrare o uscire da un veicolo.
-[KM4_B]
-Le imprese che godono della nostra protezione oggi salderanno i conti.
+[HELP27]
+Premi il ~h~~k~~VEHICLE_TURRETUP~~w~ o ~h~~k~~VEHICLE_TURRETDOWN~~w~ per spostare il peso sulla moto.
-[KM2_E]
-Devi procurarti le auto nella lista e consegnarle nel garage dietro il parcheggio a Newport.
+[HELP28]
+Premi il ~h~~k~~VEHICLE_TURRETUP~~w~ o ~h~~k~~VEHICLE_TURRETDOWN~~w~ per spostare il peso sulla moto.
-[FM3_8I]
-~w~Scegli una postazione vantaggiosa, poi io entrerò dopo che hai sparato il primo colpo.
+[HELP35]
+Premi il ~h~~k~~GO_LEFT~~w~ o la ~h~~k~~GO_RIGHT~~w~ per sterzare.
-[LOVE1_B]
-L'esperienza mi ha insegnato che un uomo come te sa essere molto leale se ben pagato,
+[HELP36]
+Premi il ~h~~k~~GO_LEFT~~w~ o la ~h~~k~~GO_RIGHT~~w~ per sterzare.
-[LOVE1_H]
-ma gruppi di uomini diventano avidi.
+[HELP42]
+Segui il ~q~segnalino rosa~w~ per trovare l'hotel.
-[LOVE1_C]
-Un personaggio chiave, un vecchietto orientale che conosco,
+[HELP19]
+Cammina sul ~q~segnalino rosa~w~ per continuare.
-[LOVE1_I]
-è ostaggio di alcuni sud-americani in Aspatria.
+[HELP1]
+Fermati al centro del ~q~segnalino rosa~w~.
-[MEA4_D]
-Ho preso accordi per vederlo...
+[HELP12]
+Cammina nel centro del ~q~segnalino rosa~w~ per attivare una missione.
-[MEA4_B4]
-Ti manda Marty, eh? OK, mostrerò a quello schifoso il significato della parola affari.
+[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.
-[MEA4_B5]
-Carl, ciao! Mi, uh, mi serve più tempo per pagarti.
+[S_PROMP]
+Quando non sei in missione, puoi salvare la partita raccogliendo il bonus ~h~audiocassetta~w~.
-[MEA1_B4]
-Ah, ti manda il signor Chonk, vero? Andiamo a fargli un visita.
+[HELP16]
+Passa attraverso la porta principale dell'hotel ~h~Ocean View~w~ per entrare nell'edificio.
-[HM5_6]
-Andiamo a spaccare qualche cranio...
+[HELP43]
+~g~Raggiungi l'hotel ~h~Ocean View~g~ in Ocean Drive.
-[LOVE1_5]
-~g~Non perdere altro tempo, procurati un'auto dei Colombiani e salva il socio di Love.
+[HELI_F1]
+~r~Gara a tappe con l'elicottero annullata!
-[AS1_D]
-~w~Agisci da esca e fatti inseguire dai plotoni d'esecuzione fino a Pike Creek
+[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.
-[AS1_E]
-~w~dove i miei uomini li aspetteranno.
+[HELI_1]
+Tappa elicottero Downtown
-[AS2_C]
-~w~Il Cartello ha un negozio di copertura, la compagnia Kappa Coffee House.
+[HELI_2]
+Tappa elicottero Ocean Beach
-[AS2_E]
-~w~Non abbiamo scelta, dobbiamo mettere questi spacciatori ambulanti fuori combattimento.
+[HELI_3]
+Tappa elicottero Vice Point
-[AS2_F]
-~w~Riducili in poltiglia!!
+[HELI_4]
+Tappa elicottero Little Haiti
-[AS2_A1]
-~w~Miguel ha di certo un po' di quella famosa prestanza latina.
+[FST_MFR]
+Stazione radio preferita
-[AS2_A2]
-~w~Io non ce la faccio più.
+[FST_LFR]
+Stazione radio meno amata
-[SIREN_3]
-Per attivare la sirena di questo veicolo premi il ~h~tasto ~k~~VEHICLE_HORN~~w~.
+[FEI_HOL]
+Trattieni
-[SIREN_4]
-Per attivare la sirena di questo veicolo premi il ~h~tasto ~k~~VEHICLE_HORN~~w~.
+[FEI_ZOO]
+Zoom
-[AS3_C]
-~w~Eeeeyooo! Cos'è quella roba gialla e collosa?
+[FEI_BTR]
+> < -
-[AS3_C1]
-~w~Oh, ciao pupa.
+[FEI_NA]
+N\D
-[AS3_F]
-~w~Ha un talento naturale questa ragazza.
+[MESA]
+Mesa Grande
-[AS3_F1]
-~w~È riuscita a strappare questa perla al nostro ospite.
+[STRP_NO]
+Non puoi ancora comprare il club a luci rosse, prova più tardi.
-[AS3_G]
-~w~C'è un aereo in arrivo all'aeroporto internazionale Francis in 2 ore.
+[CHSE]
+INSEGUI
-[AS3_G1]
-~w~È pieno del veleno di Catalina.
+[NBMN_L]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare El Swanko Casa per ~1~$
-[AS3_H]
-~w~Puoi evitare la sicurezza dell'aeroporto andando in barca vicino alle boe di segnalazione della pista di atterraggio
+[NBMN_T]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare El Swanko Casa per ~1~$
-[AS3_H1]
-e abbattendo l'aereo quando si avvicina.
+[NBMN_C]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare El Swanko Casa per ~1~$
-[AS3_I]
-~w~Raccogli il carico dalle macerie!
+[LNKV_L]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare l'appartamento Links View per ~1~$
-[AS3_J]
-~w~Oh, adesso fa attenzione, OK baby?
+[LNKV_T]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare l'appartamento Links View per ~1~$
-[AS3_K]
-~w~Adesso prova l'olio di chili...
+[LNKV_C]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare l'appartamento Links View per ~1~$
-[RM2_F1]
-Quei Colombiani dovrebbero essere qui a momenti!
+[HYCO_L]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare il condominio Hyman per ~1~$
-[RM2_K]
-Maledizione, sono arrivati!!! CARICA LE ARMI!!!
+[HYCO_T]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare il condominio Hyman per ~1~$
-[LOVE2_7]
-~g~Adesso abbandona l'auto!
+[HYCO_C]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare il condominio Hyman per ~1~$
-[LOVE2_8]
-~g~Ora allontanati da Newport!
+[OCHE_L]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare l'appartamento Ocean Heights per ~1~$
-[AM1_F]
-Salvatore Leone lascerà Luigi's all'incirca alle ~1~:~1~.
+[OCHE_T]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare l'appartamento Ocean Heights per ~1~$
-[LOVE5_C]
-Voglio che tu lo segua che ti accerti che lui e il mio pacco giungano a Pine Creex illesi.
+[OCHE_C]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare l'appartamento Ocean Heights per ~1~$
-[FESZ_SR]
-Salvataggio fallito! Controlla la memory card (PS2) nell'ingresso MEMORY CARD 1 e riprova.
+[WASH_L]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare 1102 Washington Street per ~1~$
-[FESZ_FO]
-Vuoi formattare 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~$
-[FELZ_FO]
-La memory card (PS2) nell'ingresso MEMORY CARD 1 non è formattata.
+[WASH_C]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare 1102 Washington Street per ~1~$
-[FES_NOC]
-Nessuna memory card (PS2) nell'ingresso MEMORY CARD 1.
+[VCPT_L]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare 3321 Vice Point per ~1~$
-[FES_LOE]
-Caricamento fallito! Controlla la memory card (PS2) nell'ingresso MEMORY CARD 1 e riprova.
+[VCPT_T]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare 3321 Vice Point per ~1~$
-[FES_DEE]
-Eliminazione fallita! Controlla la memory card (PS2) nell'ingresso MEMORY CARD 1 e riprova.
+[VCPT_C]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare 3321 Vice Point per ~1~$
-[FORSUC]
-Formattazione della memory card (PS2) nell'ingresso MEMORY CARD 1 completata.
+[SKUM_L]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare lo Skumole Shack per ~1~$
-[ERFOUN]
-Formattazione della memory card (PS2) nell'ingresso MEMORY CARD 1 fallita.
+[SKUM_T]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare lo Skumole Shack per ~1~$
-[ERMCNP]
-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~$
-[SVMEM1]
-Salva sulla memory card (PS2) nell'ingresso MEMORY CARD 1.
+[PRNT_L]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare la tipografia per ~1~$
-[FORSLO]
-Formatta 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~$
-[SLONFM]
-Errore di formattazione della memory card (PS2) nell'ingresso MEMORY CARD 1.
+[PRNT_C]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare la tipografia per ~1~$
-[SLONDR]
-Spazio insufficiente. Inserire una memory card (PS2) con almeno 500KB di spazio libero nell'ingresso MEMORY CARD 1.
+[CAR_L]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare il concessionario per ~1~$
-[SLNSP]
-Spazio insufficiente. Inserire una memory card (PS2) con almeno 200KB di spazio libero nell'ingresso MEMORY CARD 1.
+[CAR_T]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare il concessionario 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.
+[CAR_C]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare il concessionario per ~1~$
-[FES_ISF]
-NON PRESENTE
+[PORN_L]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare lo studio cinematografico per ~1~$
-[FES_SAG]
-PRESENTE
+[PORN_T]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare lo studio cinematografico per ~1~$
-[SLONNO]
-Nessuna memory card (PS2) nell'ingresso MEMORY CARD 1.
+[PORN_C]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare lo studio cinematografico per ~1~$
-[SLONNF]
-Memory card (PS2) nell'ingresso MEMORY CARD 1 non formattata.
+[ICE_L]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare la fabbrica di gelato 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?
+[ICE_T]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare la fabbrica di gelato per ~1~$
-[FESZ_FF]
-Formattazione fallita! Controlla la memory card (PS2) nell'ingresso MEMORY CARD 1 e riprova.
+[ICE_C]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare la fabbrica di gelato 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)
+[TAXI_L]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare la compagnia di taxi 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)
+[TAXI_T]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare la compagnia di taxi per ~1~$
-[FESZ_WR]
-Salvataggio dati. Non rimuovere la memory card (PS2) dall'ingresso MEMORY CARD 1, riavviare o spegnere la console.
+[TAXI_C]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare la compagnia di taxi per ~1~$
-[FESZ_OW]
-Sovrascrittura dati. Non rimuovere la memory card (PS2) dall'ingresso MEMORY CARD 1, riavviare o spegnere la console.
+[BANK_L]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare il Malibu per ~1~$
-[FELD_WR]
-Caricamento dati. Non rimuovere la memory card (PS2) dall'ingresso MEMORY CARD 1, riavviare o spegnere la console.
+[BANK_T]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare il Malibu per ~1~$
-[FEDL_WR]
-Eliminazione dati. Non rimuovere la memory card (PS2) dall'ingresso MEMORY CARD 1, riavviare o spegnere la console.
+[BANK_C]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare il Malibu per ~1~$
-[LM2_C]
-Luigi dice di, di darti questo, quindi...
+[BOAT_L]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare il cantiere navale per ~1~$
-[LM3_G]
-Joey non è tipo da aspettare: ricorda, questa è la tua grande occasione...
+[BOAT_T]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare il cantiere navale per ~1~$
-[LM5_E]
-Portane più che puoi prima che gli sbirri si bevano tutto lo stipendio.
+[BOAT_C]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare il cantiere navale per ~1~$
-[JM5_C]
-OK, c'è un'auto con ripieno di cadavere al bar vicino Callahan Point.
+[STRP_L]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare il club Pole Position per ~1~$
-[RM2_B]
-Abbiamo visto i casini in Nicaragua, ai tempi in cui la nazione aveva ancora un senso.
+[STRP_T]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare il club Pole Position per ~1~$
-[RM2_C]
-Qualche bastardo del Cartello l'ha maltrattato ieri e ha detto che ritornerà oggi per la sua merce.
+[STRP_C]
+Premi il ~h~~k~~PED_ANSWER_PHONE~~w~ per acquistare il club Pole Position per ~1~$
-[RM2_D1]
-Andrei io, ma la mia vecchia sciatica si fa sentire -cough cough- quindi, uhh, in bocca al lupo.
+[STOCK]
+~r~scorte esaurite
-[CATINF1]
-~g~Prendi Catalina!
+[HELP14]
+Per trovare l'ufficio dell'avvocato, segui la ~h~L~w~ sul radar.
-[CATINF2]
-~g~Segui l'elicottero per trovare Catalina.
+[RAMPAGE]
+VIOLENZA!
-[BOATIN1]
-Salta su una barca e premi il ~h~tasto ~k~~VEHICLE_ENTER_EXIT~~w~ per entrare.
+[RAMP_F]
+VIOLENZA FALLITA!
-[BOATIN2]
-Se sei vicino a una barca, puoi premere il ~h~tasto ~k~~VEHICLE_ENTER_EXIT~~w~ per tirarla verso di te.
+[RAMP_P]
+VIOLENZA COMPIUTA!
-[BOATIN3]
-Salta su una barca e premi il ~h~tasto ~k~~VEHICLE_ENTER_EXIT~~w~ per entrare.
+[RAMP_A]
+TUTTE LE VIOLENZE COMPIUTE!
-[BOATIN4]
-Se sei vicino a una barca, puoi premere il ~h~tasto ~k~~VEHICLE_ENTER_EXIT~~w~ per tirarla verso di te.
+[PAGE_01]
+Uccidi ~1~ membri della gang in 2 minuti!
-[JM6]
-'LA PARTENZA'
+[PAGE_02]
+Distruggi ~1~ veicoli in 2 minuti!
-[FM1]
-L'AUTISTA
+[PAGE_03]
+Uccidi sparando in corsa ~1~ membri della gang in 2 minuti!
-[JM1]
-'L'ULTIMA CENA DI MIKE 'LABBRA''
+[PAGE_04]
+Travolgi ~1~ membri della gang in 2 minuti!
-[FM21]
-'BOMBARDA LA BASE: ATTO PRIMO'
+[PAGE_05]
+Fai saltare la testa a ~1~ membri della gang in 2 minuti!
-[FM3]
-'BOMBARDA LA BASE: ATTO SECONDO'
+[SENTXS]
+Sentinel XS
-[AM1]
-'SAYONARA SALVATORE'
+[MAP_LEG]
+Legenda
-[AM2]
-'SOTTO SORVEGLIANZA'
+[VCNMAV]
+VCN Maverick
-[KM2]
-'GRAND THEFT AUTO'
+[LG_01]
+Posizione giocatore
-[AS3]
-'S.A.M.'
+[LG_02]
+Avery Carrington
-[RM2]
-'A CORTO D'ARMI'
+[LG_03]
+Contatto motociclisti
-[LOVE6]
-'TRANELLO'
+[LG_04]
+Colonnello Cortez
-[LOVE1]
-'LIBERATORE'
+[LG_05]
+Ricardo Diaz
-[RC1]
-'DISTRUZIONE DEI DIABLO'
+[LG_06]
+Kent Paul
-[RC2]
-'MASSACRO MAFIOSO'
+[LG_07]
+Avvocato
-[RC3]
-'CALAMITÀ AL CASINÒ'
+[LG_08]
+Phil Cassidy
-[RC4]
-'LA FURIA DI RUMPO'
+[LG_09]
+Cantiere navale
-[RM2_E1]
-Non posso credere che quei bastardi musi gialli se ne siano andati lasciandomi di nuovo senza copertura!
+[LG_10]
+Club Malibu
-[GREN_1]
-Quanto più a lungo tieni premuto il ~h~tasto ~k~~PED_FIREWEAPON~~w~, tanto più lontano lancerai la granata.
+[LG_11]
+Cubani
-[GREN_2]
-Quanto più a lungo tieni premuto il ~h~tasto ~k~~PED_FIREWEAPON~~w~, tanto più lontano lancerai la granata.
+[LG_12]
+Studio cinematografico
-[GREN_3]
-Quanto più a lungo tieni premuto il ~h~tasto ~k~~PED_FIREWEAPON~~w~, tanto più lontano lancerai la granata.
+[LG_13]
+AmmuNation
-[LOVE4_G]
-Le mie proprietà ti aspettano all'interno dell'aereo nell'hangar doganale.
+[LG_14]
+Haitiani
-[KABOOM]
-KABOOOM!
+[LG_15]
+Ferramenta
-[SPLAT]
-SPIACCICATO!
+[LG_16]
+Nascondiglio
-[PANCAK]
-SCHIACCIATO!
+[LG_17]
+Fabbrica di gelato
-[SOAKED]
-ANNEGATO!
+[LG_18]
+Taxi Kaufman
-[HEAD]
-Head Radio
+[LG_19]
+Love Fist
-[DBL_CLF]
-Double Clef FM
+[LG_20]
+Tipografia
-[FLASHB]
-Flashback FM
+[LG_21]
+Proprietà
-[RISE]
-Rise FM
+[LG_22]
+Pay 'n' Spray
-[LIPS]
-Lips 106
+[LG_23]
+Negozio di vestiario
-[CHAT]
-Chatterbox FM
+[LG_24]
+Dimora di Tommy
-[K_JAH]
-K-Jah Radio
+[LG_25]
+Telefono
-[GAM_FM]
-Game Radio FM
+[LG_26]
+Stazione radio Wildstyle
-[MSX_FM]
-MSX FM
+[LG_27]
+Stazione radio Flash FM
-[TUBE1]
-Quando aprirà la metropolitana potrai prendere un treno verso Staunton Island.
+[LG_28]
+Stazione radio KChat
-[TUBE2]
-Quando aprirà Shoreside Vale potrai uscire dallo Shoreside terminal verso l'aeroporto internazionale Francis.
+[LG_29]
+Stazione radio Fever 105
-[TUBE_2]
-Per salire sulla metropolitana, premi il ~h~tasto 'entra nel veicolo'~w~.
+[LG_30]
+Stazione radio VROck
-[LEGAL]
-~g~Elimina la minaccia criminale!
+[LG_31]
+Stazione radio VCPR
-[GA_2]
-Motore nuovo e carrozzeria riverniciata. Gli sbirri non ti riconosceranno!
+[LG_32]
+Stazione radio Espantoso
-[LM1_8A]
-Per guadagnare qualche soldo extra, perché non 'prendere in prestito' un taxi...
+[LG_33]
+Stazione radio Emotion 98.3
-[TAXIH1]
-Fermati vicino a un pedone evidenziato per farlo salire a bordo e portarlo a destinazione prima che scada il tempo.
+[LG_34]
+Stazione radio Wave 103
-[LM5_7]
-~g~Se ci sono meno di quattro ragazze alla ~p~festa degli sbirri~g~, Luigi sarà nero!
+[LG_36]
+Sun Yard
-[KM2_3]
-~g~Ricorda, le ~r~macchine~g~ devono essere in condizioni eccellenti per essere accolte nel ~p~garage~g~.
+[LG_37]
+Club a luci rosse
-[KM5_2]
-~g~Uno Yardie è in giro per strada.
+[MAP_YAH]
+TU SEI QUI
-[BETRA_A]
-Scusa baby.
+[TAXSHRT]
+~g~Puoi utilizzare questo taxi Kaufman per arrivare a destinazione invece di guidare. Ti costerà 9$.
-[BETRA_B]
-Sono una ragazza ambiziosa e tu,
+[FE_MLG]
+LEGENDA MAPPA
-[BETRA_C]
-sei una mezza calzetta.
+[FED_RDR]
+RADAR
-[JAILB_C]
-Nessun dettaglio è stato fornito riguardo i prigionieri che venivano trasferiti dalla scorta,
+[FED_HUD]
+INTERFACCIA
-[JAILB_E]
-La scorta aveva lasciato la centrale di polizia questa mattina presto...
+[FED_RDL]
+GRANDE
-[JAILB_F]
-per un trasferimento ordinario verso il penitenziario di Liberty.
+[FED_RDB]
+SOLO SEGNALI
-[JAILB_G]
-L'attacco è avvenuto sul ponte Callahan,
+[FED_HUF]
+DISSOLVENZA
-[JAILB_I]
-Alcuni dei detenuti sembrerebbero essere deceduti a seguito dell'esplosione...
+[FEST_HV]
+Massimo livello missione Vigilante
-[JAILB_P]
-questo disastro lascia Portland isolata dal resto della città.
+[BRIBE1]
+Hai appena raccolto una bustarella della polizia: il tuo livello di sospetto è sceso di una stella.
-[JAILB_Q]
-Forza!
+[CLOHELP]
+Abiti puliti!
-[JAILB_R]
-Signor stronzo!
+[SUNSHIN]
+Sunshine Autos
-[JAILB_S]
-Non è un problema ucciderti.
+[CHERRYP]
+Gelateria Cherry Popper
-[JAILB_T]
-Te ne pentirai.
+[KAUFCAB]
+Taxi Kaufman
-[JAILB_U]
-Va bene, va bene. Sparisci.
+[BOATYAR]
+Cantiere navale
-[HELP15]
-Quando sei a piedi, premi il ~h~tasto ~k~~PED_LOOKBEHIND~~w~ per ~h~guardare indietro~w~.
+[WANT_L]
+Il tuo livello di sospetto è sospeso: se commetterai un crimine mentre le stelle lampeggiano, il tuo livello di sospetto verrà ripristinato.
-[FEC_LB3]
-Guarda indietro
+[HOTRNG]
+HOTRING
-[FEC_R3]
-(tasto R3)
+[BLODRNG]
+BLOODRING
-[FES_AFO]
-Questa memory card (PS2) è già formattata.
+[DIRTRNG]
+DIRTRING
-[FEA_UP]
-;
+[FEC_ABR]
+Accelera, frena o inverti marcia
-[FEA_DO]
-=
+[FEI_BTU]
+; = -
-[FEA_LE]
-<
+[FEI_SCR]
+Scorri
-[FEA_RI]
->
+[LG_35]
+Destinazione
-[FEDSAS3]
-- CAMBIA SELEZIONE
+[BOAT_AS]
+~g~Il cantiere navale d'ora in poi genererà introiti per un massimo di ~1~$. Ricordati di recuperarli regolarmente.
-[FEDSAS4]
-;=<> - CAMBIA SELEZIONE
+[BOAT_A2]
+CANTIERE NAVALE COMPLETATO
-[SPRAY_4]
-Usa il ~h~tasto ~k~~PED_FIREWEAPON~~w~ per sparare col cannone ad acqua.
+[BOAT_N]
+Tappa Charlie
-[SPRAY_1]
-Usa il ~h~tasto ~k~~PED_FIREWEAPON~~w~ per sparare col cannone ad acqua.
+[BOAT_P]
+~g~Raccogli i pacchi prima dello scadere del tempo.
-[LITTLE]
-LITTLE T
+[FEI_R1B]
+Tasto R1 \ R2 -
-[NICK]
-NICK LOVE
+[HELP9_A]
+Premi il tasto ~h~~k~~PED_FIREWEAPON~~w~ per sparare con il fucile di precisione.
-[AM1_10]
-Salvatore uscirà da Luigi's attorno alle 0~1~:~1~.
+[HELP21]
+Premi il tasto ~h~~k~~VEHICLE_ENTER_EXIT~~w~ per entrare o uscire da un veicolo.
-[JAILB_V]
-La città di Liberty è sotto shock.
+[CREAM]
+Distribuzione
-[JAILB_A]
-Mentre la polizia e i servizi di emergenza affrontano le conseguenze...
+[UMBERTO]
+Cafe Robina
-[JAILB_B]
-di un devastante attacco alla scorta avvenuto questa mattina.
+[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.
-[JAILB_W]
-Rivelazioni sulla professionalità dell'attacco hanno sconvolto le forze dell'ordine,
+[FED_RDM]
+MAPPA E INDICATORI
-[JAILB_K]
-Inoltre, l'identificazione dei detenuti scomparsi è stata ulteriormente ostacolata...
+[FEC_ILU]
+Sguardo invertito in prima persona :
-[JAILB_L]
-da un attacco informatico al computer principale della centrale di Polizia.
+[NITRO]
+Tutti i taxi adesso hanno il super salto! Premi il pulsante del clacson.
-[JAILB_M]
-Il Sindaco O'Donovan ha dichiarato che la polizia considera l'attentato...
+[RATNG53]
+Inaffidabile
-[JAILB_N]
-*
+[RATNG54]
+Imbarazzante
-[JAILB_O]
-Considerato il ritardo nella costruzione del sottopassaggio Porter,
+[RATNG55]
+Hacker
-[JAILB_X]
-In un'affermazione resa nota ieri,
+[RATNG56]
+Baro
-[FEDS_SE]
-Tasto / - SELEZIONA
+[RATNG57]
+Bugiardo assoluto
-[FEDS_SB]
-Tasto / - SELEZIONA Tasto " - INDIETRO
+[STHC_04]
+Miglior punteggio con la palla sulla spiaggia
-[TM4_A]
-~w~Oh, sei te. TONI non è qua.
+[STHC_05]
+Miglior risultato Hotring
-[TM4_A2]
-~w~Ma ha lasciato una delle sue dolci lettere per te.
+[STFT_13]
+Tempo migliore corsa in elicottero a Downtown
-[DIAB2_A]
-Ho iniziato a lavorare nel business dell'intrattenimento solo grazie al voluminoso contenuto dei miei pantaloni di pelle!
+[STFT_14]
+Tempo migliore corsa in elicottero a Ocean Beach
-[LM5_9]
-RAGAZZE:
+[STFT_15]
+Tempo migliore corsa in elicottero a Vice Point
-[PERPIC]
-Pacchetti speciali recuperati
+[STFT_16]
+Tempo migliore corsa in elicottero a Little Haiti
-[CO_ONE]
-Pacchetto speciale ~1~ su ~1~
+[STFT_21]
+Tempo migliore nell'Hotring
-[LOVE3_3]
-~g~L'aeroplano ha fatto cadere ~1~ dei 6 pacchi.
+[STFT_22]
+Giro migliore nell'Hotring
-[FARE11]
-~g~Destinazione: ~w~'il cantiere costruzioni'~g~ a Fort Staunton.
+[STFT_20]
+Tempo migliore in 'Cone Crazy'
-[GA_21]
-Non puoi parcheggiare altri veicoli in questo garage.
+[HELP44]
+Fermati nel ~q~ segnalino rosa.
-[CHEAT1]
-Trucco attivato
+[HELP45]
+Premi il ~h~~k~~PED_DUCK~~w~ per abbassarti. In questo modo migliorerai la precisione con le armi da fuoco.
-[CHEAT2]
-Trucco armi
+[RCR1_5]
+Corsa Bandit radiocomandati
-[CHEAT3]
-Trucco salute
+[RCPL1_7]
+Corsa Baron radiocomandati
-[CHEAT4]
-Trucco armatura
+[RCH1_11]
+Raccolta Raider radiocomandato
-[CHEAT5]
-Trucco livello di sospetto
+[FEA_CTD]
+Attenzione! Questa caratteristica richiede delle periferiche compatibili DTS. Vuoi procedere?
-[CHEAT6]
-Trucco soldi
+[FEM_STE]
+USA STEREO
-[CHEAT7]
-Trucco tempo atmosferico
+[FEM_UDY]
+USA DTS
-[AS1_H]
-~r~Hai fallito nel far cadere la squadra della morte nella trappola della Yakuza!!!
+[GREET]
+Saluti da...
-[FEDS_BA]
-Tasto " - INDIETRO
+[LANCE_1]
+Ehi bello, guida con più prudenza!
-[RAMP_A]
-TUTTE LE VIOLENZE COMPLETATE!
+[LANCE_2]
+Ehi, guarda cosa hai combinato!
-[USJ_ALL]
-TUTTE LE ACROBAZIE UNICHE COMPLETATE
+[LANCE_3]
+Ehi, ma dove stai andando adesso?
-[FARE23]
-~g~Destinazione: ~w~'Garage importazioni-esportazioni' ~g~nel distretto della diga Cochrane.
+[LANCE_4]
+Cosa diavolo stai facendo?
-[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.
+[LAW4_15]
+Più soldi!
-[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.
+[MERC_5]
+Bella machina, Mr. Vercetti.
-[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.
+[MERC_26]
+PIÙ VELOCE, PIÙ VELOCE, PIÙ VELOCE!
-[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.
+[MERC_27]
+Attento Tommy, mi hanno rifatto il naso il mese scorso.
-[AS1_C]
-~w~Ha tre squadre della morte in giro per Liberty il cui unico scopo è beccarti.
+[MERC_28]
+Tommy, guida con attenzione.
-[AS1_G]
-~r~Tutti i membri della Yakuza sono morti!!!
+[MERC_29]
+Tommy, vai più piano!
-[JAN]
-Gen
+[MERC_30]
+Tommy per favore, fai fuori qualcun altro!
-[FEB]
-Feb
+[MERC_31]
+Tommy, baby, non farmi fuori!
-[MAR]
-Mar
+[MERC_32]
+Tommy, sono felice che hai rubato questa macchina!
-[APR]
-Apr
+[MERC_40]
+Mi sono davvero divertita.
-[MAY]
-Mag
+[MERC_43]
+Adios, angioletto.
-[JUN]
-Giu
+[MERC_44]
+Continua a lavorarci, capito?
-[JUL]
-Lug
+[MERC_45]
+Ciao, bellezza.
-[AUG]
-Ago
+[COL5_17]
+Oddio, hanno un elicottero!
-[SEP]
-Set
+[COL5_18]
+Abbatti l'elicottero!
-[OCT]
-Ott
+[COL5_19]
+Tommy, abbatti quell'elicottero!
-[NOV]
-Nov
+[COL5_20]
+Sta tornando! Distruggi l'elicottero!
-[DEC]
-Dic
+[COL5_21]
+Ma guarda quanto è grosso!
-[DEFDT]
-Nessun salvataggio valido
+[COL5_22]
+Sta tornando di nuovo!
-[BUGGY]
-MAGGIOLINI RIMASTI:
+[FEA_DSM]
+Attenzione! Questo salvataggio utilizza il DTS e richiede periferiche compatibili. Scegli se vuoi procedere utilizzando l'uscita DTS o quella STEREO.
-[BONUS]
-~g~BONUS $~1~$
+[STFT_23]
+Tempo migliore per la tappa Charlie
-[HORN1]
-Premi il ~h~tasto L3~w~ per suonare il ~h~clacson~w~.
+[HELP50]
+Premi il tasto ~h~~k~~PED_ANSWER_PHONE~~w~ per posizionare la visuale da dietro.
-[HORN2]
-Premi il ~h~tasto L1~w~ per suonare il ~h~clacson~w~.
+[HELP51]
+Premi il tasto ~h~~k~~PED_ANSWER_PHONE~~w ~ per posizionare la visuale da dietro.
-[HORN3]
-Premi il ~h~tasto R1~w~ per suonare il ~h~clacson~w~.
+[HELP52]
+Premi il tasto ~h~~k~~PED_ANSWER_PHONE~~w ~ per posizionare la visuale da dietro.
-[LM3_1A]
-Premi il ~h~tasto ~k~~VEHICLE_HORN~~w~ per suonare il ~h~clacson~w~ e avvertire Misty che sei arrivato.
+[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.
-[LM3_1B]
-Premi il ~h~tasto ~k~~VEHICLE_HORN~~w~ per suonare il ~h~clacson~w~ e avvertire Misty che sei arrivato.
+[HELP46]
+Sono disponibili otto diversi tipi di arma.
-[LM3_1C]
-Premi il ~h~tasto ~k~~VEHICLE_HORN~~w~ per suonare il ~h~clacson~w~ e avvertire Misty che sei arrivato.
+[HELP47]
+Puoi trasportare una sola arma per tipo alla volta: un tipo di pistola, un tipo di fucile a pompa...
-[RADIO_A]
-Premi il ~h~tasto ~k~~VEHICLE_CHANGE_RADIO_STATION~~w~ per passare in rassegna le ~h~stazioni radio~w~.
+[HELP54]
+~w~Costo: ~1~$ ~r~Comprando quest'arma sostituirai quella in uso.
-[RADIO_B]
-Premi il ~h~tasto ~k~~VEHICLE_CHANGE_RADIO_STATION~~w~ per passare in rassegna le ~h~stazioni radio~w~.
+[HELP2A2]
+Premi il tasto ~h~~k~~PED_SPRINT~~w~ mentre corri per effettuare uno ~h~scatto~w~.
-[RADIO_C]
-Premi il ~h~tasto ~k~~VEHICLE_CHANGE_RADIO_STATION~~w~ per passare in rassegna le ~h~stazioni radio~w~.
+[HLPSN_A]
+Il fucile di precisione ti permette di ingrandire l'immagine e colpire i bersagli con precisione dalla distanza.
-[RADIO_D]
-Premi il ~h~tasto ~k~~VEHICLE_CHANGE_RADIO_STATION~~w~ per passare in rassegna le ~h~stazioni radio~w~.
+[HLPSN_B]
+Tieni premuto il tasto ~h~~k~~PED_LOCK_TARGET~~w~ per ~h~mirare~w~ col fucile di precisione.
-[FEC_EXV]
-Entra o esci dal veicolo
+[HLPSN_C]
+Tieni premuto il tasto ~h~L1~w~ per ~h~mirare~w~ col fucile di precisione.
-[TAXI_M]
-'TAXISTA'
+[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~.
-[COP_M]
-'VIGILANTE'
+[HLPSN_E]
+Premi il tasto ~h~~k~~PED_FIREWEAPON~~w~ per ~h~sparare~w~ col fucile di precisione.
-[FIRE_M]
-'POMPIERE'
+[HLPSN_F]
+Premi il tasto ~h~~k~~PED_FIREWEAPON~~w~ per ~h~sparare~w~ col fucile di precisione.
-[AMBUL_M]
-'PARAMEDICO'
+[HLPSN_G]
+Premi il tasto ~h~~k~~PED_FIREWEAPON~~w~ per ~h~sparare~w~ col fucile di precisione.
-[HJ_IS]
-BONUS ACROBAZIA FOLLE: ~1~$
+[PLANE_H]
+Usa il tasto ~h~~k~~VEHICLE_ACCELERATE~~w~ per accelerare e a sinistra e a destra per curvare.
-[HJ_PIS]
-BONUS ACROBAZIA FOLLE PERFETTA: $~1~
+[PLANE_4]
+Usa il tasto ~h~~k~~VEHICLE_ACCELERATE~~w~ per accelerare e a sinistra e a destra per curvare.
-[HJ_DIS]
-BONUS DOPPIA ACROBAZIA FOLLE: $~1~
+[HELP55]
+Premi il tasto ~h~~k~~PED_FIREWEAPON~~w~ per attaccare lo chef.
-[HJ_PDIS]
-BONUS DOPPIA ACROBAZIA FOLLE PERFETTA: $~1~
+[STPR_8]
+Club Pole Position
-[HJ_TIS]
-BONUS TRIPLA ACROBAZIA FOLLE: $~1~
+[STPR_9]
+3321 Vice Point
-[HJ_PTIS]
-BONUS TRIPLA ACROBAZIA FOLLE PERFETTA: $~1~
+[STPR_10]
+Appartamento Links View
-[HJ_QIS]
-BONUS QUADRUPLA ACROBAZIA FOLLE: $~1~
+[STPR_11]
+El Swanko Casa
-[HJ_PQIS]
-BONUS QUADRUPLA ACROBAZIA FOLLE PERFETTA: $~1~
+[STPR_12]
+1102 Washington Street
-[AM1_K]
-Salvatore Leone uscirà da Luigi's fra circa tre ore. (0~1~:~1~)
+[STPR_13]
+Appartamento Ocean Heights
-[IMPEXPP]
-Garage importazioni-esportazioni, porto di Portland. Abbiamo richieste per vari mezzi: consulta la bacheca per le saperne di più.
+[STPR_14]
+Skumole Shack
-[VANHSTP]
-Hai scassinato altre Securicar? Portale al nostro garage al porto di Portland.
+[STPR_15]
+Condominio Hyman
-[EMVHPUP]
-Ottimi prezzi per veicoli di soccorso nuovi o usati. Portali vicino alla gru a nord est del porto di Portland.
+[RCCANX]
+~r~Aereo radiocomandato annullato.
-[STANDS]
-CHIOSCHI DISTRUTTI:
+[CLT_HL2]
+Quando viene raccolto un bonus vestiti, vengono rimosse una o due stelle del livello di sospetto.
-[STASH]
-~g~Nascondi lo SPANK nel ~p~cantiere edile~g~!
+[CRED009]
+PROGETTAZIONE MISSIONI
-[MCSTNS]
-Nessuna memory card (PS2) nell'ingresso MEMORY CARD 1. Vuoi procedere comunque? (SÌ o NO)
+[CRED359]
+LEE JOHNSON
-[LOVE3_5]
-~g~L'aeroplano è a tiro.
+[CRED360]
+HENDRIK LESSER
-[LOVE3_6]
-~r~La polizia è arrivata ai pacchi per prima!
+[CRED361]
+PASQUALE STACCHIOTTI
-[SIREN_1]
-Per accendere le sirene di questo veicolo, premi il ~h~tasto ~k~~VEHICLE_HORN~~w~.
+[CRED362]
+ENRIQUE FERNANDEZ
-[SIREN_2]
-Per accendere le sirene di questo veicolo, premi il ~h~tasto ~k~~VEHICLE_HORN~~w~.
+[CRED363]
+PAUL BYERS
-[FM3_8C]
-~w~Avrò bisogno di 100.000$ per coprire le spese,
+[CRED364]
+MIKE EMENY
-[MCLOAD]
-Caricamento dati. Non rimuovere la memory card (PS2) dall'ingresso MEMORY CARD 1, riavviare o spegnere la console.
+[CRED365]
+ROB DUNKIN
-[FES_GME]
-Errore di lettura della memory card (PS2) nell'ingresso MEMORY CARD 1! Controlla la memory card (PS2) e riprova.
+[CRED366]
+CHARLIE KINLOCH
-[FESZ_QF]
-Sei sicuro di voler formattare la memory card (PS2) nell'ingresso MEMORY CARD 1?
+[CRED367]
+KEVIN HOBSON
-[FESZ_LS]
-Caricamento riuscito.
+[CRED368]
+JIM CREE
-[RM3_5]
-~g~Hai raccolto ~1~ su 6 prove.
+[MOB_66A]
+Tommy, Tommy, Tommy, perché sei tornato qua?
-[LOVE3_2]
-~g~Hai tutti i pacchi! Riportali subito a Donald Love.
+[MOB_66B]
+Te l'avevo detto che non vi volevamo più vedere.
-[LOVE4_4]
-~g~Riporta il pacco a Donald Love.
+[MOB_67A]
+Tommy, credo che dovresti andartene, capito?
-[FEDS_AM]
-<>-CAMBIA MENU
+[MOB_67B]
+I ragazzi Haitiani non sono molto felici di te.
-[FEB_SAV]
-Carica
+[MOB_18A]
+Tommy, sono Paulo, come stai? Bene amico, ascolta: volevo farti una chiamata.
-[FEP_SAV]
-CARICA PARTITA
+[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.
-[AS2_12A]
-~g~Dopo aver distrutto il primo chiosco, avrai 8 minuti prima che il Cartello informi i propri spacciatori!
+[MOB_18G]
+Dovresti farci un giro. Ci vediamo!
-[AS3_1A]
-~g~Adesso raggiungi la ~b~boa segnalatrice~g~!
+[MOB_72A]
+Tommy, sono io, Lance. Tieni la bocca chiusa Tommy, perché non ho tempo da perdere.
-[NOCONT]
-Ricollega il controller analogico (DUALSHOCK#) o controller analogico (DUALSHOCK#2) all'ingresso controller 1 per continuare.
+[MOB_72B]
+Non mi importa cos'hai da dire. Perché dovrei? Non te ne frega niente di me, non è vero?
-[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_72C]
+Dovresti fare più attenzione a me. Dovresti darmi la fetta che merito. Lo sai...
-[END_A]
-I residenti in Cedar Grove si sono finalmente ripresi
+[MOB_72D]
+Tommy... senti amico, mi dispiace. È solo che...
-[END_B]
-dallo spavento per i violenti scontri
+[MOB_72E]
+La gente mi ha sempre trattato con accondiscenda, come se fossi un bambino.
-[END_C]
-avvenuti ieri nell'area.
+[MOB_72F]
+Mio fratello lo farebbe. Per favore, amico, tu non farlo.
-[END_D]
-Un abitante della zona, Clive Denver, ha dichiarato alla polizia
+[MOB_72G]
+Devo andare.
-[END_E]
-di aver visto un uomo armato che sia allontanava dalla scena del crimine con una donna dai capelli neri.
+[MOB_63A]
+Tommy, sono Earnest. Earnest Kelly.
-[END_F]
-Oh, lo sai, vedrai che ci divertiremo, perché lo sai, cioè,
+[MOB_63B]
+Come stai?
-[END_G]
-io ti amo, io... io ti amo davvero perché sei un vero uomo
+[MOB_63C]
+Non male. Avrò bisogno di un bastone per camminare, ma dovrei tornare al lavoro ben presto.
-[END_H]
-ed è ciò di cui ho bisogno.
+[MOB_63D]
+Bene.
-[END_I]
-Comunque, cosa stavo dicendo?
+[MOB_63E]
+Ho sentito di Lance. Che brutto storno, eh?
-[END_J]
-Oh, lo sai, me lo sono dimenticato. Sai com'è che succede, vero?
+[MOB_63F]
+Sì.
-[END_K]
-Il suono delle esplosioni ha fatto tremare le case mentre la gente correva al riparo.
+[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.
-[END_L]
-Molti cittadini sono rimasti feriti per il panico mentre venivano sparati colpi
+[MOB_63H]
+Credo di sì. Non credevo fosse quel genere di persona...
-[END_M]
-tra le forze terrestri e l'elicottero che sorvolava la diga.
+[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.
-[END_N]
-Sì, c'è proprio una bella vista da qui in giardino.
+[MOB_63J]
+Fai con calma, Earnest. Abbi cura di te.
-[END_O]
-Quando hanno fatto saltare l'elicottero
+[MOB_16A]
+Tommy, sono Paulo, que pasa amigo?
-[END_P]
-è stato meglio dei fuochi d'artificio del 4 luglio.
+[MOB_16B]
+Che cosa vuoi Paul: non sono interessato a vestiti di marca taroccati.
-[END_Q]
-Il numero di cadaveri recuperati ha già superato la ventina,
+[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.
-[END_R]
-ma la polizia continua a trovare nuovi corpi.
+[MOB_16D]
+Quando ero in Inghilterra ho fatto un sacco di cose, sai? Ho attributi più forniti di te, amico.
-[END_S]
-Non sono state smentite le voci secondo cui
+[MOB_16E]
+Paul, grazie per l'offerta, lo terrò presente.
-[END_T]
-i morti appartenessero al Cartello Colombiano,
+[MOB_16F]
+Davvero, non scordarti di me dopo tutto quello che ho fatto per te.
-[END_U]
-ciò nonostante, non ci sono indizi sulle ragioni di questa strage.
+[MOB_16G]
+È proprio ciò che sto cercando di dimenticare...
-[END_V]
-Mi sono rotta un'unghia e i miei capelli sono un disastro. Ma ci puoi credere?
+[MOB_17A]
+Tommy Vercetti: come va, Mr. Pezzo Grosso? Ho saputo le tue novità: un vero giocatore in città, eh...
-[END_W]
-Mi è costato 50 dollari...
+[MOB_17B]
+Paul, sei ubriaco.
-[PAPER1]
-CRIMINALE FERITO DALLA FIDANZATA COMPLICE. LA CORTE GIUDICA IL RAPINATORE COLPEVOLE CON VERDETTO UNANIME.
+[MOB_17C]
+No, idiota. Non sono ubriaco. Solo un paio di bicchierini e qualche pillola: non dormo da un paio di giorni, sai...
-[PAPER2]
-DIECI ANNI PER L'AMORE!
+[MOB_17D]
+Comunque, niente prediche. Non sono uno stupido. Chi ti ha portato in questa città? Chi? Io, ecco chi.
-[JAILB_J]
-che è seguita all'attacco iniziale.
+[MOB_17F]
+Davvero?
-[JAILB_D]
-E nessun gruppo ha rivendicato l'attentato.
+[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.
-[JAILB_H]
-lasciando pochi testimoni e il ponte stesso seriamente danneggiato.
+[MOB_17H]
+Mi ignori. Non mi aiuti a entrare dopo tutto ciò che ho fatto per te! Cosa credi che sia? Un idiota?
-[FEB_CPC]
-Configurazione comandi
+[MOB_17I]
+Paul, sta' buono. Sono stato occupato, non fare l'idiota.
+
+[MOB_17J]
+Non sono un idiota, chiaro? Questo è ciò che hanno detto in riformatorio. Stai forse cercando guai, amico? Beh, stai per trovarli!
+
+[MOB_17K]
+Tommy, amico. Per favore. Sei la mia più grande speranza! Per favore, non ridere di me.
+
+[MOB_17L]
+Paul, cerca di dormire, davvero.
+
+[MOB_73A]
+Tommy, sono Steve.
+
+[MOB_73B]
+Ehi Steve.
+
+[MOB_73C]
+Ehi, ciao genio. Sei uno spettacolo! Anch'io sono uno spettacolo! Ci adorano. Stiamo battendo tutti i record, amico.
+
+[MOB_73D]
+Stiamo ottenendo dei grandi riconoscimenti. Finalmente posso comprare una casa al mio vecchio così se ne starà zitto.
+
+[MOB_73E]
+Eeer, mi sembra perfetto, Steve.
+
+[MOB_73F]
+Perfetto? È meraviglioso! Meraviglioso, MERAVIGLIOSO! Non ha mai creduto in me. Non pensava fossi un artista, ma adesso ce l'ho fatta.
+
+[MOB_73G]
+Sono il miglior direttore sadomaso di tutti i tempi, amico. Volevo solo dirti che è stato un piacere averti incontrato.
+
+[MOB_73H]
+Grazie Steve.
+
+[MOB_73I]
+Ti voglio bene, amico. Non cambiare, capito?
+
+[MOB_73J]
+Capito. Ci sentiamo Steve.
+
+[BOLLOX]
+Premi il tasto ~o~R1~w~ per sganciare una bomba. Premi il tasto ~t~"~w~ per annullare.
+
+[BRID_OP]
+Pericolo uragano terminato: tutti i ponti per la terra ferma sono nuovamente aperti.
+
+[BRID_CL]
+Pericolo uragano: tutti i ponti per la terra ferma sono chiusi.
+
+[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!
+
+[GOODBOY]
+$50 Come Bonus Buon Cittadino!
+
+[NEWCONT]
+Nuovo ~h~Punto di Contatto~w~ disponibile alla Marina di Ocean Beach!!
+
+[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
+
+[FEC_LB3]
+Guarda indietro
+
+[FEC_R3]
+(tasto R3)
[FEC_PED]
Comandi a piedi
@@ -7126,84 +7183,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
@@ -7255,41 +7234,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?
@@ -7297,743 +7444,7127 @@ 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
+
+[REPLAY]
+REPLAY
+
+[FEC_ANS]
+Azione
+
+[CVT_MSG]
+Conversione texture per prestazioni ottimali con la tua scheda video
+
+[FEC_SFT]
+MAIUSC
-[FEG_PLY]
-GIOCATORI
+[FEH_VMP]
+VEDI MAPPA
-[FEG_TYP]
-MODALITÀ
+[FES_DEE]
+Eliminazione fallita! Prova nuovamente.
+
+[FES_CMP]
+Salvataggio fallito! Prova nuovamente.
-[FEG_PNG]
-PING
+[FESZ_WR]
+Salvataggio partita. Un momento...
+
+[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_GFX]
-IMPOSTAZIONI GRAFICA
+[FEA_MP3]
+RIPRODUTTORE MP3
-[FET_DIS]
-IMPOSTAZIONI VIDEO
+[NO_PCCD]
+Inserisci il CD di GTA Vice City o premi Esc per annullare
-[FET_LAN]
-IMPOSTAZIONI LINGUA
+[FEH_SSA]
+FRECCE PER MUOVERSI - S PER SALVARE
-[FET_LG]
-CARICA PARTITA
+[FES_CMI]
+ULTIMA MISSIONE COMPLETATA
-[FET_DG]
-ELIMINA PARTITA
+[FET_STS]
+STATISTICHE SALVATE NEL FILE 'STATS.HTML' + 'STATS.TXT'
-[FET_NG]
-NUOVA PARTITA
+[WIN_VDM]
+Memoria video insufficiente per eseguire Grand Theft Auto VC
-[FET_SG]
-SALVA PARTITA
+[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_MAP]
-SELEZIONA MAPPA
+[FEC_TFU]
+Torretta + Inclina in su
-[FET_GT]
-MODALITÀ DI GIOCO
+[FEC_TFD]
+Torretta + Inclina in giù
-[FET_CTL]
-IMPOSTAZIONI DEI COMANDI
+[FET_RIG]
+SELEZIONA IL NUOVO COMANDO PER QUESTA AZIONE
-[FET_OPT]
-OPZIONI
+[FEA_NM3]
+NESSUN FILE MP3 TROVATO
-[FET_QG]
-ESCI DAL GIOCO
+[FEA_MPB]
+INCREMENTO VOLUME MP3
-[FET_STA]
-STATISTICHE
+[FEA_MUS]
+VOLUME MUSICA
-[FET_BRE]
-MISSIONI
+[FEA_SFX]
+VOLUME EFFETTI
-[FEC_WAR]
-Attenzione
+[CVT_ERR]
+Spazio su disco esaurito; è necessario liberare dello spazio prima di poter procedere. Premi ESC per annullare.
-[FEC_OKK]
-OK
+[FEA_ADP]
+RILEVAMENTO AUTOMATICO
-[FED_CON]
-Conferma eliminazione file
+{=================================== MISSION TABLE AMBULAE ===================================}
-[FES_SSC]
-Partita salvata con successo
+[ATUTOR2:AMBULAE]
+~g~Conduci i pazienti all'ospedale guidando CON PRUDENZA! Qualsiasi scossone può ucciderli.
-[DEL_FNM]
-File eliminato con successo.
+[A_FULL:AMBULAE]
+~r~Ambulanza piena!
-[PCLOAD]
-Caricamento dati in corso
+[A_FAIL2:AMBULAE]
+~r~La tua scarsa sollecitudine è stata fatale al paziente!
-[PCRESRT]
-Riavvio di Grand Theft Auto III
+[A_FAIL3:AMBULAE]
+~r~Il paziente è morto!
-[FEC_DLF]
-Eliminazione fallita.
+[A_PASS:AMBULAE]
+Salvato!
-[FEC_SVU]
-Salvataggio fallito.
+[A_COMP2:AMBULAE]
+Non ti stancherai mai!
-[FEC_LUN]
-Caricamento fallito. File corrotto: è necessario eliminarlo.
+[A_COMP1:AMBULAE]
+Missioni Infermiere completate: ~1~$
-[FEN_PLA]
-Numero di giocatori:
+[A_CANC:AMBULAE]
+~r~Missione Infermiere annullata!
-[FET_NON]
-NESSUNA PARTITA DISPONIBILE
+[A_COMP3:AMBULAE]
+Missione Infermiere completata! Non ti stancherai mentre corri!
-[FET_SFG]
-RICERCA DI PARTITE...
+[ALEVEL:AMBULAE]
+Missione Infermiere livello ~1~
-[FET_SRT]
-CLASSIFICAZIONE PARTITE...
+[A_FAIL1:AMBULAE]
+Missione Infermiere terminata.
-[FEF_LAN]
-LAN
+[A_SAVES:AMBULAE]
+PERSONE SALVATE: ~1~
-[FEF_INT]
-INTERNET
+{=================================== MISSION TABLE ASSIN1 ===================================}
-[FET_REF]
-Aggiorna
+[ASM1_5:ASSIN1]
+~r~Ha completato le sue consegne!
-[FET_FIL]
-Filtra
+[ASM1_6:ASSIN1]
+Consegne rimanenti:
-[FET_JG]
-Partecipa
+[ASM1_7:ASSIN1]
+~g~Carl Pearson, fattorino di una pizzeria. Uccidilo prima che completi le sue consegne.
-[FEC_NTW]
-Talk To Network
+[ASM1_D:ASSIN1]
+Mr. Teal, il tuo aiuto nello sradicare gli stranieri è stato inestimabile per il nostro lavoro.
-[FEC_ESR]
-Il tasto ESC è riservato
+{=================================== MISSION TABLE ASSIN2 ===================================}
-[FEC_GSL]
-Show head bob:
+[ASM2_1:ASSIN2]
+~g~Mrs. Dawson lascerà presto la gioielleria in Vice Point. Devi ucciderla. Deve sembrare un incidente d'auto.
-[FIL_FLT]
-FILTRA ELENCO PARTITE
+[ASM2_3:ASSIN2]
+~g~Sta per esplodere! Allontanati!
-[FET_SAN]
-NUOVA PARTITA
+[ASM2_4:ASSIN2]
+~r~Hai danneggiato la sua auto, ma lei non è sopra! Adesso non ci entrerà di sicuro!
-[FIL_MAP]
-Mappa:
+[ASM2_5:ASSIN2]
+~r~È riuscita a scappare!
-[FIL_SRV]
-Server:
+[ASM2_6:ASSIN2]
+~r~Sei stato visto troppo vicino alla scena dell'incidente!
-[FIL_TYP]
-Modalità:
+[ASM2_7:ASSIN2]
+~g~Non utilizzare armi! Deve sembrare un incidente! Spingila fuori strada!
-[FIL_SPC]
-Partite non piene?
+[ASM2_8:ASSIN2]
+~g~La morte di Mrs. Dawson deve sembrare un incidente. Non utilizzare armi.
-[FIL_PNG]
-Ping:
+[ASM2_9:ASSIN2]
+~g~Avrai bisogno di una vettura per questo lavoro!
-[FEN_UKH]
-Host sconosciuto
+[ASM2_10:ASSIN2]
+~g~Quando la sua macchina prende fuoco, allontanati il più possibile dal luogo dell'incidente.
-[FEN_UKM]
-Mappa non trovata
+[ASM2_11:ASSIN2]
+Aiuto!
-[FEN_UKT]
-Modalità non trovata
+[ASM2_12:ASSIN2]
+Qualcuno mi aiuti!
-[FEN_NCI]
-NON CONNESSO A INTERNET
+[ASM2_13:ASSIN2]
+Oddio!
-[FET_PAU]
-MENU PAUSA
+[ASM2_A:ASSIN2]
+Complimenti per l'ottimo lavoro, Mr. Teal. Il mio cliente è molto soddisfatto.
-[FET_SGA]
-AVVIA PARTITA
+[ASM2_2:ASSIN2]
+Salute:
-[FEC_SGJ]
-Imposta joystick
+{=================================== MISSION TABLE ASSIN3 ===================================}
-[FEC_PAD]
-Gamepad
+[ASM3_11:ASSIN3]
+TEMPO:
-[FEC_JOY]
-Joystick
+[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_WHL]
-Volante
+[ASM3_D:ASSIN3]
+Ogni membro della gang ha un nascondiglio nella città: alcuni hanno dei lavori di copertura, altri sono in vacanza.
-[FEC_CNT]
-Periferica di controllo:
+[ASM3_E:ASSIN3]
+Dettagli e posizione più probabile di ogni bersaglio sono riportati nel nastro sotto al telefono.
-[FET_APL]
-APPLICA
+[ASM3_14:ASSIN3]
+~g~Dick Tanner si trova presso la DBP Security in Ocean Drive.
-[FES_CSA]
-Seleziona una skin dalla seguente lista:
+[ASM3_15:ASSIN3]
+~g~Marcus Hammond e Franco Carter si trovano presso la gioielleria in Vice Point.
-[FES_SKN]
-NOME SKIN
+[ASM3_16:ASSIN3]
+~g~Nick Kong si trova presso Washington Beach.
-[FES_DAT]
-DATA
+[ASM3_18:ASSIN3]
+~g~Non avvicinarti troppo, se no il bersaglio potrebbe vederti e sarai costretto a inseguirlo!
-[FES_NON]
-NESSUNA SKIN DISPONIBILE
+[ASM3_19:ASSIN3]
+~g~Ti ha visto! Fallo fuori!
-[FEA_FM9]
-RIPRODUTTORE MP3
+[ASM3_20:ASSIN3]
+~g~Ti hanno visto! Falli fuori entrambi!
-[FESZ_QZ]
-Sei sicuro di voler salvare la partita?
+[ASM3_21:ASSIN3]
+~r~Non hai ucciso tutti i membri della gang in tempo!
-[FES_CGA]
-Blocchi di gioco disponibili:
+[ASM3_22:ASSIN3]
+~g~Non avvicinarti troppo, se no i bersagli potrebbero vederti e cercare di scappare!
-[FES_SCG]
-Vuoi salvare la partita attuale?
+[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.
-[FES_LCG]
-Vuoi caricare e continuare la partita?
+[ASM3_13:ASSIN3]
+~g~Mike Griffin lavora su un cartello pubblicitario in Washington.
-[FEC_FIR]
-Fuoco
+[ASM3_17:ASSIN3]
+~g~Charlie Dilson è in macchina in Washington.
-[FEC_NWE]
-Arma successiva
+{=================================== MISSION TABLE ASSIN4 ===================================}
-[FEC_PWE]
-Arma precedente
+[ASM4_12:ASSIN4]
+Distanza:
-[FEC_FOR]
-Avanti
+[ASM4_15:ASSIN4]
+~g~Recupera il fucile di precisione alla tua destra.
-[FEC_BAC]
-Indietro
+[ASM4_16:ASSIN4]
+~g~Osserva la donna sul balcone: scenderà per le scale e chiederà l'ora a un uomo.
-[FEC_LEF]
-Sinistra
+[ASM4_17:ASSIN4]
+~g~Solo quando la conversazione avrà termine, dovrai uccidere l'uomo con cui ha parlato ma NON la donna.
-[FEC_RIG]
-Destra
+[ASM4_18:ASSIN4]
+~g~Una volta eliminato il bersaglio, recupera la sua valigetta e portala ad Ammu-Nation in Downtown.
-[FEC_ZIN]
-Ingrandimento
+[ASM4_19:ASSIN4]
+~g~Tieni la distanza dal bersaglio: la barra nella parte superiore destra dello schermo indica quanto gli sei vicino.
-[FEC_ZOT]
-Riduzione
+[ASM4_20:ASSIN4]
+~g~Se si riempirà, verrai avvistato.
-[FEC_EEX]
-Entra/Esci
+[ASM4_21:ASSIN4]
+~g~Recupera la valigetta!
-[FEC_RAD]
-Radio
+[ASM4_22:ASSIN4]
+~g~Porta la valigetta ad Ammu-Nation in Downtown.
-[FEC_SUB]
-Sottomissioni
+[ASM4_23:ASSIN4]
+~g~Ti ha visto e sta fuggendo! Uccidilo e recupera la valigetta!
-[FEC_CMR]
-Cambia visuale
+[ASM4_25:ASSIN4]
+~r~Hai ucciso la donna, idiota!
-[FEC_JMP]
-Salto
+[ASM4_26:ASSIN4]
+~r~Il bersaglio è salito a bordo del volo!
-[FEC_SPN]
-Scatto
+[ASM4_27:ASSIN4]
+~r~Il bersaglio ti ha visto! Avresti dovuto tenerti a distanza!
-[FEC_HND]
-Freno a mano
+[ASM4_28:ASSIN4]
+~r~Il bersaglio ti ha visto! Ti ha sentito sparare!
-[FEC_TUL]
-Torretta a sx
+[ASM4_29:ASSIN4]
+~r~Dovevi ucciderlo solo dopo che aveva parlato con la donna!
-[FEC_TUR]
-Torretta a dx
+[ASM4_A:ASSIN4]
+È giunta l'ora di occuparsi di pesci più grossi, Mr Teal. Troverai un fucile tra le foglie alla tua destra.
-[FEC_LOL]
-Guarda a sinistra
+[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_LOR]
-Guarda a destra
+[ASM4_C:ASSIN4]
+Dovrai uccidere questa persona, recuperare la sua valigetta e portarla nella locazione riportata sotto al telefono.
-[FEC_NTR]
-Bersaglio successivo
+{=================================== MISSION TABLE ASSIN5 ===================================}
-[FEC_PTT]
-Bersaglio precedente
+[ASM5_A:ASSIN5]
+C'è uno scambio di beni sopra il tetto della fabbrica di gelato Cherry Popper.
-[FEC_LBA]
-Guarda indietro
+[ASM5_B:ASSIN5]
+Uccidi tutti gli elementi coinvolti, recupera la merce e portala all'eliporto presso l'aeroporto.
-[FEC_CEN]
-Centra visuale
+[ASM5_C:ASSIN5]
+Alla tua sinistra troverai un cancello che porta al retro della fabbrica.
-[FEC_UND]
-(NO)
+[ASM5_1:ASSIN5]
+~g~Entra nel cortile dietro alla fabbrica di gelato Cherry Popper e apriti la strada fino al luogo dello scambio.
-[FET_CFT]
-A PIEDI
+[ASM5_2:ASSIN5]
+~g~Recupera la merce e portala all'eliporto presso l'aeroporto.
-[FET_CCR]
-IN MACCHINA
+[ASM5_3:ASSIN5]
+~g~Porta la merce all'eliporto presso l'aeroporto!
-[CVT_MSG]
-Conversione texture per prestazioni ottimali con la tua scheda video
+{=================================== MISSION TABLE BANKJ1 ===================================}
-[FET_CAC]
-AZIONE
+[WANTED1:BANKJ1]
+~g~Semina i poliziotti per perdere il tuo livello di sospetto.
-[FEC_IBT]
--
+[BJM1_A:BANKJ1]
+Tommy! Ehi Tommy, guarda qua, è grandioso! Ho fatto installare un minibar!
-[FEC_SPC]
-BARRA
+[BJM1_B:BANKJ1]
+Abbiamo un intero bar al piano di sotto, Ken.
-[FEC_MXO]
-P1MX
+[BJM1_C:BANKJ1]
+Sì, sì, certo. Beh, ho portato quella lavagna che mi avevi richiesto.
-[FEC_MXT]
-P2MX
+[BJM1_D:BANKJ1]
+Ah, questi sono i benefici della scuola dell'obbligo: l'abilità di seguire le istruzioni.
-[FEC_UNB]
-NESSUNO
+[BJM1_E:BANKJ1]
+Adesso mi serve uno scassinatore.
-[FET_CME]
-METODO DI CONTROLLO
+[BJM1_F:BANKJ1]
+Oh, va bene, beh, fammi pensare... scassinatore, scassinatore, scassinatore... Trovato! Questo tipo ti farà impazzire!
-[FET_RDK]
-RIDEFINISCI COMANDI
+[BJM1_G:BANKJ1]
+Ahh, nah, quello schmuck. È dentro.
-[FET_AMS]
-IMPOSTAZIONI MOUSE
+[BJM1_H:BANKJ1]
+Dentro dove?
-[FET_STI]
-CONFIGURAZIONE PREDEFINITA
+[BJM1_I:BANKJ1]
+In una cella nel quartier generale della polizia in attesa di trasferimento.
-[FET_CTI]
-CONFIGURAZIONE CLASSICA
+[BJM1_J:BANKJ1]
+Credo stia per essere rilasciato sulla parola...
-[FET_MTI]
-CONFIGURAZIONE COL MOUSE
+[BJM1_1:BANKJ1]
+~g~Fai fuggire Cam Jones dalla custodia della polizia!
-[FET_DAM]
-MODELLAZIONE ACUSTICA DINAMICA
+[BJM1_3:BANKJ1]
+~g~Troverai ciò che ti serve nello spogliatoio della stazione.
-[FEC_TFL]
-Torretta a sinistra
+[BJM1_21:BANKJ1]
+~g~La tessera per le celle si trova nel piano superiore della stazione.
-[FEC_TFR]
-Torretta a destra
+[BNK1_7:BANKJ1]
+Cam Jones?
-[FEC_TFU]
-Torretta /Aereo su
+[BNK1_8:BANKJ1]
+Ti sto facendo scappare!
-[FEC_TFD]
-Torretta /Aereo giù
+[BNK1_10:BANKJ1]
+Sì, sono io...
-[FEC_MWF]
-VOLANTE SU
+[BNK1_11:BANKJ1]
+Come vuoi!
-[FEC_MWB]
-VOLANTE GIÙ
+[BNK1_13:BANKJ1]
+Devo fare un lavoro e tu sarai il mio scassinatore.
-[FEC_ORR]
-o
+[BNK1_14:BANKJ1]
+Sempre meglio che restare col culo in galera!
-[FEC_NUS]
-NON USATO
+[BJM1_22:BANKJ1]
+~g~Riporta Cam a casa sua!
-[FEC_LUD]
-Sguardo su
+[BJM1_23:BANKJ1]
+~g~Prima devi recuperare la tessera!
-[FEC_LDU]
-Sguardo giù
+[BNK1_12:BANKJ1]
+Fai perdere le tracce e riportami a casa!
-[FEC_CMP]
-COMBO: SGUARDO S+D
+[BJM1_20:BANKJ1]
+Metti via l'arma o ne pagherai le conseguenze!
-[FEC_NTT]
-Nessun testo assegnato a questo tasto
+[BJM1_5:BANKJ1]
+Solo personale autorizzato oltre a questo punto!
-[FEC_FNC]
-F~1~
+[BJM1_2:BANKJ1]
+~r~Dovevi far fuggire Cam, non farlo morire!
-[FEC_IRT]
-INS
+[BJM1_4:BANKJ1]
+È armato! Uccidetelo!
-[FEC_DLL]
-CANC
+{=================================== MISSION TABLE BANKJ2 ===================================}
-[FEC_HME]
-HOME
+[BJM2_A:BANKJ2]
+Abbiamo bisogno di un tiratore. Ne conosci uno?
-[FEC_END]
-FINE
+[BJM2_B:BANKJ2]
+Ehi Tommy, Tommy, Tommy, questa roba ti tiene in forma, amico.
-[FEC_PGU]
-PAG SU
+[BJM2_C:BANKJ2]
+WoooOOOooo!
-[FEC_PGD]
-PAG GIÙ
+[BJM2_D:BANKJ2]
+Potrei essere io il tuo tiratore! Spara! Spara!
-[FEC_UPA]
-SU
+[BJM2_E:BANKJ2]
+Non sei un tiratore, sei un idiota.
-[FEC_DWA]
-GIÙ
+[BJM2_F:BANKJ2]
+Fatti un drink e sta zitto.
-[FEC_LFA]
-SINISTRA
+[BJM2_G:BANKJ2]
+Ehi, via dai miei piedi! Ye ye ye ow ow.
-[FEC_RFA]
-DESTRA
+[BJM2_H:BANKJ2]
+Cam, cosa mi dici?
-[FEC_NUM]
-NUM
+[BJM2_I:BANKJ2]
+Beh, il miglior tiratore in città è un tipo chiamato Cassidy.
-[FEC_NMN]
-NUM~1~
+[BJM2_J:BANKJ2]
+Davvero?
-[FEC_FWS]
-NUM /
+[BJM2_K:BANKJ2]
+Sì. Un militare, o per lo meno crede di esserlo.
-[FEC_PLS]
-NUM +
+[BJM2_L:BANKJ2]
+Non credo sia mai stato nell'esercito, ma sicuramente sa come tenere in mano un'arma.
-[FEC_MIN]
-NUM -
+[BJM2_M:BANKJ2]
+Lo troverai di sicuro al poligono di tiro.
-[FEC_DOT]
-NUM .
+[BJM2_2A:BANKJ2]
+Sei Phil Cassidy?
-[FEC_NLK]
-BLOC NUM
+[BJM2_2B:BANKJ2]
+Perché?
-[FEC_ETR]
-INVIO
+[BJM2_2C:BANKJ2]
+Sto cercando un uomo che sappia come sparare. Da quello che vedo, non sono molto convinto...
-[FEC_SLK]
-BLOC SCORR
+[BJM2_2D:BANKJ2]
+Figliolo, potrei colpire una mosca sulla tua testa a 30 metri di distanza.
-[FEC_PSB]
-PAUSA
+[BJM2_2E:BANKJ2]
+Davvero?
-[FEC_BSP]
-INDIETRO
+[BJM2_2F:BANKJ2]
+Certo. Ho fatto pratica nell'esercito.
-[FEC_TAB]
-TAB
+[BJM2_2G:BANKJ2]
+Lo sparo alla mosca è così popolare nell'esercito? Per fortuna non pago le tasse.
-[FEC_CLK]
-BLOC MAIUSC
+[BJM2_2H:BANKJ2]
+Stai cercando di fare lo spiritoso?
-[FEC_RTN]
-RET
+[BJM2_2I:BANKJ2]
+Ah ah ah ah ah!
-[FEC_LSF]
-MAIUSC SX
+[BJM2_2J:BANKJ2]
+Spariamo.
-[FEC_RSF]
-MAIUSC DX
+[BJM2_1:BANKJ2]
+~g~Raggiungi Ammu-Nation in Downtown e parla con Phil Cassidy.
-[FEC_LCT]
-CTRL SX
+[BJM2_4:BANKJ2]
+PUNTEGGIO PRIMO TURNO: ~1~
-[FEC_RCT]
-CTRL DX
+[BJM2_6:BANKJ2]
+PUNTEGGIO SECONDO TURNO: ~1~
-[FEC_LAL]
-ALT SX
+[BJM2_7:BANKJ2]
+PUNTEGGIO TOTALE: ~1~
-[FEC_RAL]
-ALT DX
+[BJM2_9:BANKJ2]
+~G~Raggiungi il punto di partenza del secondo turno.
-[FEC_LWD]
-WIN SX
+[BJM2_11:BANKJ2]
+~r~Phil è morto!
-[FEC_RWD]
-WIN DX
+[BJM2_12:BANKJ2]
+~r~Uno dei tiratori è morto!
-[FEC_WRC]
-CLIC WIN
+[BJM2_14:BANKJ2]
+~g~Raggiungi la prossima area!
-[WIN_TTL]
-Grand Theft Auto III
+[BJM2_17:BANKJ2]
+~g~Vai a parlare con Phil.
-[WIN_95]
-Grand Theft Auto III non è supportato da Windows 95
+[BJM2_24:BANKJ2]
+~g~Il bersaglio più vicino vale un punto.
-[WIN_DX]
-Grand Theft Auto III richiede DirectX versione 8.1 o superiore
+[BJM2_25:BANKJ2]
+~g~Il bersaglio centrale vale due punti.
-[WIN_VDM]
-Grand Theft Auto III richiede almeno 12 MB di memoria video disponibile
+[BJM2_27:BANKJ2]
+~g~In questo turno, tutti i bersagli valgono un punto.
-[DIAB3_G]
-Arriba!
+[BNK2_4:BANKJ2]
+Hoooeee!
-[FEM_RES]
-RIPRENDI PARTITA
+[BNK2_5:BANKJ2]
+Non riusciresti a colpire neanche un elefante!
-[FES_SNG]
-NUOVA PARTITA
+[BNK2_7:BANKJ2]
+Fammi un favore, aiutami a mettere a segno un colpo.
-[FEM_SP]
-GIOCATORE SINGOLO
+[BNK2_8:BANKJ2]
+Figliolo, da come hai sparato, se mi chiedessi di sposarti direi di sì.
-[FEM_MP]
-MULTIGIOCATORE
+[BNK2_9A:BANKJ2]
+Figliolo, ficcati la tua parlata e le tue grandi idee là dove non batte il sole. Non sai sparare per niente.
-[FEM_QT]
-ESCI DAL GIOCO
+[BNK2_9B:BANKJ2]
+Non sai sparare per niente.
-[FES_SG]
-NUOVA PARTITA
+[BJM2_28:BANKJ2]
+PUNTEGGIO TERZO TURNO: ~1~
-[FES_LG]
-CARICA PARTITA
+[BJM2_26:BANKJ2]
+~g~Il bersaglio più lontano vale tre punti.
-[FEM_HST]
-OSPITA PARTITA
+[BNK2_1:BANKJ2]
+MUNIZIONI VERE
-[FEM_OPT]
-OPZIONI
+[RANGE_1:BANKJ2]
+PUNTEGGIO PER COLPO: ~1~
-[FEM_DBG]
-DEBUG
+[BJM2_2:BANKJ2]
+~g~Per interrompere il turno, premi il ~h~~k~~PED_JUMPING~~g~.
-[FET_PSU]
-IMPOSTAZIONI GIOCATORE
+[BJM2_N:BANKJ2]
+Rilassati.
-[FET_DEF]
-RIPRISTINA PREDEFINITI
+{=================================== MISSION TABLE BANKJ3 ===================================}
-[FED_BRI]
-LUMINOSITÀ
+[BJM3_A:BANKJ3]
+Le cose stanno iniziando a prendere forma.
-[FED_TRA]
-TRACCE
+[BJM3_B:BANKJ3]
+Qual è il piano Tommy? Que pasa, amigo?
-[FEM_LOD]
-DISTANZA VISUALE
+[BJM3_C:BANKJ3]
+La tua parte consiste nel continuare a fare l'idiota. Comunque, adesso abbiamo bisogno di un pilota.
-[FEM_VSC]
-SINCRONIA FRAME
+[BJM3_D:BANKJ3]
+Tommy, lo farò io. Io so guidare bene.
-[FEM_FRM]
-LIMITATORE FRAME
+[BJM3_E:BANKJ3]
+Ti serve Hilary, capo. Di certo non un sapientone avvocato del cazzo.
-[FED_RES]
-RISOLUZIONE
+[BJM3_F:BANKJ3]
+Hilary è la persona giusta. Non troverai nessuno capace di guidare così veloce. Gli posso fare una chiamata.
-[FED_WIS]
-SCHERMO 16:9
+[BJM3_G:BANKJ3]
+Ehi Hil, sono Phil. Come butta? No, lascia stare, ne parliamo un'altra volta. Mi faresti un favore?
-[FEDS_TB]
-INDIETRO
+[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_MUS]
-VOLUME MUSICA
+[BJM3_I:BANKJ3]
+Per un po' di azione. OK, capisco.
-[FEA_SFX]
-VOLUME EFFETTI
+[BJM3_J:BANKJ3]
+Che cosa ha detto?
-[FEA_RSS]
-STAZIONE RADIO
+[BJM3_K:BANKJ3]
+Beh, ci sta, nessun problema. Beh, un piccolo problema c'è: ha subito uno shock da abbandono.
-[FEL_ENG]
-INGLESE
+[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_FRE]
-FRANCESE
+[BJM3_M:BANKJ3]
+Comunque, vuole prima sfidarti in una corsa, ha detto che ci aspettava fuori...
-[FEL_GER]
-TEDESCO
+[BJM3_2A:BANKJ3]
+Sei Tommy? Beh, certo che sei Tommy, cioè...
-[FEL_ITA]
-ITALIANO
+[BJM3_2B:BANKJ3]
+Per quale altro motivo qualcuno vorrebbe parlare con me?
-[FEL_SPA]
-SPAGNOLO
+[BJM3_2C:BANKJ3]
+OK, vedila in questo modo...
-[FEA_3DH]
-HARDWARE AUDIO
+[BJM3_2D:BANKJ3]
+Io guiderò SE, e solo SE, tu sai guidare come si deve.
-[FEA_SPK]
-CONFIGURAZIONE ALTOPARLANTI
+[BJM3_2E:BANKJ3]
+Lasciami solo... e non te lo perdonerò mai.
-[FEA_2SP]
-DUE CASSE
+[BJM3_2:BANKJ3]
+~r~Hilary è morto!
-[FEA_4SP]
-PIÙ DI DUE CASSE
+[BJM3_4:BANKJ3]
+~g~Hai bisogno di una vettura per partecipare!
-[FEA_EAR]
-CUFFIE
+[BNK3_1:BANKJ3]
+OK. Guiderò per te, ma per favore trattami male!
-[FEA_NAH]
-NESSUN HARDWARE AUDIO
+[BNK3_3A:BANKJ3]
+Corsa illegale in corso presso Vice Point.
-[FET_SNG]
-NUOVA PARTITA
+[BNK3_3B:BANKJ3]
+A tutte le pattuglie.
-[FEN_STA]
-AVVIA LA PARTITA
+[BNK3_3C:BANKJ3]
+Queste corse sono illegali e vietate!
-[GMLOAD]
-CARICA PARTITA
+{=================================== MISSION TABLE BANKJ4 ===================================}
-[GMSAVE]
-SALVA PARTITA
+[BNK4_A:BANKJ4]
+~w~Come potete vedere, signori, questi saranno i soldi più facili della storia.
-[FES_DGA]
-ELIMINA PARTITA
+[BNK4_B:BANKJ4]
+~w~Tommy, seriamente, dovresti pensare di fare l'avvocato.
-[FEM_NON]
-NESSUNO
+[BNK4_C:BANKJ4]
+~w~Ma che cosa ti fumi, amico? Non è per niente un piano semplice!
-[FEC_IVV]
-INVERTI MOUSE VERTICALMENTE
+[BNK4_D:BANKJ4]
+~w~Beh, chi ha bisogno di un piano semplice?
-[FEC_MSH]
-SENSIBILITÀ MOUSE
+[BNK4_E:BANKJ4]
+~w~Prendi il comunismo, beh, quello era un piano semplice. Non ha fatto così bene alla Russia, no?
-[FET_CCN]
-COMANDI: CLASSICO
+[BNK4_F:BANKJ4]
+~w~Rilassatevi, OK? Con una squadra come la nostra, non ci saranno problemi.
-[FET_SCN]
-COMANDI: PREDEFINITO
+[BNK4_G:BANKJ4]
+~w~Abbiamo Cam per la cassaforte. Phil? Noi ci occuperemo della sorveglianza, mentre Hilary guiderà l'auto per la fuga.
-[FES_SET]
-USA SKIN
+[BNK4_H:BANKJ4]
+~w~Uh, eh eh, non ti stai dimenticando qualcuno? Qualcuno che ti ha costantemente aiutato in questa città? Qualcuno...?
-[GHOST]
-Fantasma
+[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.
-[WIN_RSZ]
-Impossibile impostare la nuova risoluzione
+[BNK4_J:BANKJ4]
+~w~Non ho ancora capito cosa ci sto a fare io qua.
-[FET_APP]
-PULSANTE SX, INVIO PER APPLICARE LE NUOVE IMPOSTAZIONI
+[BNK4_K:BANKJ4]
+~w~Beh, è semplice: non hai mai visto un film d'azione?
-[FET_HRD]
-IMPOSTAZIONI PREDEFINITE RIPRISTINATE
+[BNK4_L:BANKJ4]
+~w~Entriamo nella banca, sventoliamo in giro l'arma e usciamo molto ricchi.
-[FET_MST]
-STERZO VIA MOUSE
+[P_DEAD:BANKJ4]
+~r~Phil è morto!
-[FEC_STR]
-NUM ASTERISCO
+[C_DEAD:BANKJ4]
+~r~Cam è morto!
-[FET_MIG]
-SINISTRA, DESTRA, ROTELLA PER MODIFICARE
+[H_DEAD:BANKJ4]
+~r~Hilary è morto!
-[FET_CIG]
-INDIETRO PER AZZERARE - PULSANTE SX, INVIO PER MODIFICARE
+[P_HIND:BANKJ4]
+~r~Hai perso Phil!
-[FET_RIG]
-SELEZIONA UN NUOVO COMANDO PER QUESTA AZIONE O PREMI ESC PER ANNULLARE
+[C_HIND:BANKJ4]
+~r~Cam è restato indietro!
-[FET_EIG]
-IMPOSSIBILE ASSEGNARE UN COMANDO A QUESTA AZIONE
+[H_HIND:BANKJ4]
+~r~Hai abbandonato Hilary!
-[NO_PCCD]
-Inserisci il disco 2 di Grand Theft Auto III nel lettore o premi ESC per annullare
+[GETCAR:BANKJ4]
+~g~Entra nell'auto e preparati alla rapina!
-[CVT_ERR]
-Spazio su disco esaurito; è necessario liberare dello spazio prima di poter procedere. Premi ESC per annullare.
+[TRASHED:BANKJ4]
+~r~HAI DISTRUTTO L'AUTO PER LA FUGA!!!
-[FED_SUB]
-SOTTOTITOLI
+[BNK4_1:BANKJ4]
+Guido io.
-[FET_DSN]
-Skin predefinita.bmp
+[BNK4_2:BANKJ4]
+Ottimo. Un passeggero. Aspetta che lo dica al resto del gruppo.
-[JM3]
-'RAPINA AL FURGONE'
+[BNK4_3A:BANKJ4]
+Ehi, fai attenzione alla macchina, Tommy!
-[EBAL]
-'GIVE ME LIBERTY'
+[BNK4_3B:BANKJ4]
+Tommy, Hilary occupa troppo spazio!
-[LM4]
-'ARMI PRONTE ALL'AZIONE'
+[BNK4_3C:BANKJ4]
+Non è vero!
-[ATUTOR2]
-~g~Porta i pazienti all'ospedale! Qualsiasi scossone ridurrà le probabilità che arrivino vivi.
+[BNK4_3D:BANKJ4]
+Invece sì!
-[REPLAY]
-REPLAY
+[BNK4_3E:BANKJ4]
+Ehi, state entrambi zitti o ve ne andate a piedi.
-[FEC_SFT]
-MAIUSC
+[BNK4_3F:BANKJ4]
+Sì Hilary.
-[CRED254]
-RESPONSABILE STUDIO
+[BNK4_3I:BANKJ4]
+Perdio, Phil, smettila di sventolare quell'affare in giro!
-[CVT_CRT]
-Impossibile convertire le texture per la scheda video. Deve collegarti come Amministratore per poterlo fare. Premi ESC per uscire.
+[BNK4_3J:BANKJ4]
+Sì, finirai col cavare un occhio a qualcuno!
-[FEM_ON]
-ON
+[BNK4_3M:BANKJ4]
+La mia bambina! È a pezzi!
-[FEM_OFF]
-OFF
+[BNK4_3O:BANKJ4]
+Sei accecato dall'illusione di permanenza.
-[FEM_YES]
-SÌ
+[BNK4_3P:BANKJ4]
+Cosa?
-[FEM_NO]
-NO
+[BNK4_3Q:BANKJ4]
+Pensi che tutto duri per sempre.
-[FES_WAR]
-Salvataggio, attendere...
+[BNK4_3R:BANKJ4]
+La giovinezza, le persone care, la pizza...
-[FED_DLW]
-Eliminazione, attendere...
+[BNK4_3S:BANKJ4]
+Ma tutto passa e finisce e tu lo devi accettare.
-[FED_LDW]
-Caricamento, attendere...
+[BNK4_3T:BANKJ4]
+Ehi, hai ragione. Grazie Cam.
-[FEC_SLC]
-Slot non valido
+[BNK4_3U:BANKJ4]
+È un piacere.
-[FED_LFL]
-Caricamento posizione salvata fallito. Il gioco verrà riavviato.
+[BNK4_3V:BANKJ4]
+Ehi Tommy, perché ci siamo fermati?
-[FET_RSO]
-RIPRISTINATE IMPOSTAZIONI ORIGINALI
+[BNK4_4A:BANKJ4]
+~w~Hilary, continua a guidare attorno al quartiere.
-[FET_RSC]
-HARDWARE NON DISPONIBILE - RIPRISTINATE IMPOSTAZIONI ORIGINALI
+[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]
+Premi il tasto ~h~~k~~PED_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]
+Premi il tasto ~h~~k~~PED_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]
+Per ~h~sparare davanti~w~ su una ~h~moto~w~ premi il ~h~~k~~PED_FIREWEAPON~~w~.
+
+[GEN3_41:GENERA3]
+Per ~h~sparare davanti~w~ su una ~h~moto~w~ premi il ~h~~k~~PED_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]
+Per sparare in avanti quando sei su una moto, premi il tasto ~h~~k~~PED_FIREWEAPON~~w~.
+
+[GEN3_65:GENERA3]
+Per sparare in avanti quando sei su una moto, premi il tasto ~h~~k~~PED_FIREWEAPON~~w~.
+
+[GEN3_66:GENERA3]
+Per sparare in avanti quando sei su una moto, premi il tasto ~h~~k~~PED_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]
+Premi il ~h~~k~~PED_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]
+~g~Se desideri interrompere la missione, premi il ~h~~k~~PED_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]
+~g~Se desideri interrompere la missione, premi il ~h~~k~~PED_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]
+~g~Per sganciare una bomba, premi il ~h~~k~~PED_FIREWEAPON~~g~.
+
+[TEX3_29:SERG3]
+Per sganciare una bomba, premi il ~h~~k~~PED_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]
+Sposta ~h~~k~~VEHICLE_ACCELERATE~~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!
[DUMMY]
THIS LABEL NEEDS TO BE HERE !!!
diff --git a/utils/gxt/russian.txt b/utils/gxt/russian.txt
deleted file mode 100644
index 4598dad5..00000000
--- a/utils/gxt/russian.txt
+++ /dev/null
@@ -1,7979 +0,0 @@
-[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]
-Садясь в машину, возьми в руки Узи. Посмотри вправо или влево и нажми ~h~~k~~PED_FIREWEAPON~~w~ для выстрела.
-
-[DRIVE_B]
-Садясь в машину, возьми в руки Узи. Посмотри вправо или влево и нажми ~h~~k~~PED_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_CCF]
-Конфигурация:
-
-[FEC_CCM]
-Поставить камеру сзади игрока.
-
-[FEC_CDP]
-Показ контроллера:
-
-[FEC_CEN]
-Центровка камеры
-
-[FEC_CF1]
-Setup1
-
-[FEC_CF2]
-Setup2
-
-[FEC_CF3]
-Setup3
-
-[FEC_CF4]
-Setup4
-
-[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_INC]
-В машине
-
-[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_ONF]
-Пешком
-
-[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_VIB]
-Vibration:
-
-[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_GFX]
-НАСТРОЙКА ГРАФИКИ
-
-[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]
-Припаркуй тачку на место, нажми ~h~~k~~PED_FIREWEAPON~~w~ и ДЕЛАЙ НОГИ!
-
-[GA_6B]
-Припаркуй тачку на место, нажми ~h~~k~~PED_FIREWEAPON~~w~ и ДЕЛАЙ НОГИ!
-
-[GA_7]
-Включи бомбу, нажав на ~h~~k~~PED_FIREWEAPON~~w~. Бомба взорвется как только заведется мотор.
-
-[GA_7B]
-Включи бомбу, нажав на ~h~~k~~PED_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]
-Используй радоуправляемые машинки, чтобы подорвать броневики. Взрыв бомбы - ~h~~k~~PED_FIREWEAPON~~w~.
-
-[HM2_1A]
-Используй радоуправляемые машинки, чтобы подорвать броневики. Взрыв бомбы - ~h~~k~~PED_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]
-Чтобы ~h~подорвать бомбу~w~, нажми ~h~~k~~PED_FIREWEAPON~~w~, но не забудь отойти подальше от машины.
-
-[KM1_8D]
-Чтобы ~h~подорвать бомбу~w~, нажми ~h~~k~~PED_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]
-Чтобы выстрелить из орудия катера нажми ~h~~k~~PED_FIREWEAPON~~w~.
-
-[PBOAT_2]
-Чтобы выстрелить из орудия катера нажми ~h~~k~~PED_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]
-Чтобы подорвать машинку, нажми ~k~~PED_FIREWEAPON~, или врежься в колесо жертвы.
-
-[RCHELPA]
-Чтобы подорвать машинку, нажми ~k~~PED_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]
-Чтобы включить брандспойт, нажми на ~h~~k~~PED_FIREWEAPON~~w~.
-
-[SPRAY_4]
-Чтобы включить брандспойт, нажми на ~h~~k~~PED_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 }
-[FED_MIP]
-МИП-МАППИНГ
-
-[FED_AAS]
-СГЛАЖИВАНИЕ
-
-[FED_FIL]
-ТЕКСТУРНАЯ ФИЛЬТРАЦИЯ
-
-[FED_BIL]
-БИЛИНЕЙНАЯ
-
-[FED_TRL]
-ТРИЛИНЕЙНАЯ
-
-{ 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 425899e4..335c5d2c 100644
--- a/utils/gxt/spanish.txt
+++ b/utils/gxt/spanish.txt
@@ -1,144 +1,47 @@
-{ 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!
@@ -146,92 +49,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...
@@ -240,6744 +116,6744 @@ 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.
-
-[DAM]
-DAÑO:
-
-[KILLS]
-MUERTES:
+Encontrarás modos de curarte o de protegerte cuanto más juegues al juego.
-[FARES]
-CARRERAS:
+[BRIBE1]
+Acabas de recoger un soborno de la policía, esto disminuirá en una estrella tu nivel de se busca.
-[BULL]
-LINGOTES:
+[SAVE1]
+Entra al corona para ~h~guardar la partida~w~. No puedes guardar durante una misión.
-[EVID]
-PRUEBAS:
+[SAVE2]
+Cualquier vehículo que quede en este garaje será almacenado cuando se guarde la partida.
-[HEALTH]
-ESTADO DEL COCHE:
+[AMMU]
+Ve dentro de Ammu-Nation para comprar un arma.
-[COLLECT]
-RECOGIDOS:
+[R_TIME]
+TIEMPO DE CARRERA:
-[BOMB]
-Mete tu vehículo en la tienda de ~h~bombas~w~ para poner una. Coste: ~h~1.000 $~w~.
+[PROP_1]
+No tienes suficiente dinero para adquirir esta propiedad
-[SAVE1]
-Pasa por la puerta para ~h~guardar la partida~w~. No podrás guardar durante una misión.
+[PROP_2]
+No puedes comprar propiedades mientras estás en una misión.
-[SAVE2]
-Cualquier vehículo que dejes en este garaje se conservará al guardar la partida.
+[IND_ZON]
+Vice City Beach
-[AMMU]
-Entra en la tienda Ammu-Nation para comprar armas.
+[COM_ZON]
+Península de Vice City
-[BRIDGE1]
-Podrás conducir hasta Staunton Island cuando el puente Callahan esté reparado.
+[BEACH1]
+Ocean Beach
-[TUNNEL]
-Podrás conducir hasta Staunton Island cuando el túnel Porter esté abierto.
+[BEACH2]
+Washington Beach
-[LUIGI]
-MISIONES DE LUIGI
+[BEACH3]
+Vice Point
-[TONI]
-MISIONES DE TONI
+[GOLFC]
+Leaf Links
-[JOEY]
-MISIONES DE JOEY
+[STARI]
+Starfish Island
-[FRANK]
-MISIONES DE SALVATORE
+[DOCKS]
+Viceport
-[DIABLO]
-MISIONES DE DIABLO
+[HAVANA]
+Little Havana
-[ASUKA]
-MISIONES DE ASUKA
+[HAITI]
+Little Haiti
-[B_SITE]
-MISIONES SUBURBANAS DE ASUKA
+[PORNI]
+Prawn Island
-[KENJI]
-MISIONES DE KENJI
+[DTOWN]
+Centro de la ciudad
-[RAY]
-MISIONES DE RAY
+[VICE_C]
+Vice City
-[LOVE]
-MISIONES DE LOVE
+[A_PORT]
+Escobar International
-[YARDIE]
-MISIONES DE JAMAICANOS
+[JUNKY]
+Vertedero
-[HOOD]
-MISIONES DE HOOD
+[PISTOL]
+Pistola
-[CITYZON]
-Liberty City
+[PYTHON]
+.357
-[IND_ZON]
-Portland
+[UZI]
+Uz-1
-[PORT_W]
-Callahan Point
+[TEC9]
+Tec 9
-[PORT_S]
-Muelle Atlantic
+[M4]
+M4
-[PORT_E]
-Puerto de Portland
+[INGRAM]
+Mac
-[PORT_I]
-Trenton
+[MP5]
+MP
-[S_VIEW]
-Portland View
+[RUGER]
+Kruger
-[CHINA]
-Chinatown
+[SNIPE]
+Rifle de francotirador
-[EASTBAY]
-Playa de Portland
+[GRENADE]
+Granadas
-[LITTLEI]
-Saint Mark's
+[SHOTGN1]
+Escopeta
-[REDLIGH]
-Barrio rojo
+[SHOTGN2]
+S.P.A.S. 12
-[TOWERS]
-Cerros de Hepburn
+[SHOTGN3]
+Escopeta de cañones recortados
-[HARWOOD]
-Harwood
+[ARMOUR]
+Chaleco antibalas
-[ROADBR1]
-Puente Callahan
+[LASER]
+.308 Rifle de francotirador
-[ROADBR2]
-Puente Callahan
+[BASEBAT]
+Bate de béisbol
-[TUNNELP]
-Túnel Porter
+[HAMMER]
+Martillo
-[BOMB1]
-Taller de 8-Ball
+[SCREWD]
+Destornillador
-[COM_ZON]
-Staunton Island
+[CLEVER]
+Cuchillo de carnicero
-[STADIUM]
-Aspatria
+[MACHETE]
+Machete
-[HOSPI_2]
-Rockford
+[KNIFE]
+Cuchillo
-[UNIVERS]
-Campus de Liberty
+[KATANA]
+Katana
-[CONSTRU]
-Fort Staunton
+[CHAINSA]
+Sierra eléctrica
-[PARK]
-Parque Belleville
+[G_COST]
+~1~ $
-[COM_EAS]
-Newport
+[CAR_1]
+Ambulancia
-[SHOPING]
-Bedford Point
+[MALIBU]
+El Club Malibú
-[YAKUSA]
-Torrington
+[MANSION]
+Mansión de Díaz
-[SUB_ZON]
-Shoreside Vale
+[TMANS]
+Finca de Vercetti
-[AIRPORT]
-Aeropuerto Int. Francis
+[STRIP]
+El Club Pole Position
-[PROJECT]
-Wichita Gardens
+[MALL1]
+Centro comercial North Point
-[SUB_IND]
-Pike Creek
+[BANKINT]
+El Banco Corrupto Grande
-[SWANKS]
-Cedar Grove
+[RANGE]
+Campo de tiro con rifle
-[BIG_DAM]
-Presa Cochrane
+[POL_HQ]
+Cuartel general de VCPD
-[SUB_ZO2]
-Shoreside Vale
+[INT_B]
+Un viejo amigo
-[SUB_ZO3]
-Shoreside Vale
+[INTB_1]
+~g~Ve a la oficina del Abogado.
-[CAR_1]
-Ambulancia
+[LAW_1]
+La fiesta
-[CAR_2]
-Camión de bomberos
+[LAW_2]
+Pelea en el callejón trasero
-[CAR_3]
-Coche patrulla
+[LAW_3]
+Furia en el jurado
-[CAR_4]
-Enforcer
+[LAW_4]
+Disturbios
-[CAR_5]
-Barracks
+[COL_1]
+Cerdo traidor
-[CAR_6]
-Rhino
+[COL_2]
+Tiros en el centro comercial
-[CAR_7]
-Coche del FBI
+[COL_3]
+Ángeles guardianes
-[CAR_8]
-Securicar
+[COL_4]
+¡Señor, sí, señor!
-[CAR_9]
-Moonbeam
+[COL_5]
+¡Todos con las manos arriba!
-[CAR_10]
-Coach
+[COK_1]
+La caza
-[CAR_11]
-Flatbed
+[COK_2]
+Phnom Penh '86
-[CAR_12]
-Linerunner
+[COK_3]
+El barco más rápido
-[CAR_13]
-Trashmaster
+[COK_4]
+Oferta y demanda
-[CAR_14]
-Patriot
+[KENT_1]
+El corredor de la muerte
-[CAR_15]
-Mr. Whoopee
+[ASS_1]
+Borrar
-[CAR_16]
-Mule
+[BUD_1]
+Extorsión
-[CAR_17]
-Yankee
+[BUD_2]
+Pelea en el bar
-[CAR_18]
-Pony
+[BUD_3]
+Tierra de polis
-[CAR_19]
-Bobcat
+[CAP_1]
+Liquida al cobrador
-[CAR_20]
-Rumpo
+[FIN_1]
+Mantén cerca a tus amigos...
-[CAR_21]
-Blista
+[BANK_1]
+¿Sin escapatoria?
-[CAR_22]
-Dodo
+[BANK_2]
+El tirador
-[CAR_23]
-Autobús
+[BANK_3]
+El conductor
-[CAR_24]
-Sentinel
+[BANK_4]
+El atraco
-[CAR_25]
-Cheetah
+[CNT_1]
+Descubriendo el pastel
-[CAR_26]
-Banshee
+[CNT_2]
+Ataca al mensajero
-[CAR_27]
-Stinger
+[PORN_1]
+Campaña de reclutamiento
-[CAR_28]
-Infernus
+[PORN_2]
+Consolador Dodo
-[CAR_29]
-Esperanto
+[PORN_3]
+La foto policial de Marta
-[CAR_30]
-Kuruma
+[PORN_4]
+Punto G
-[CAR_31]
-Stretch
+[TAX_1]
+Taxis Kaufman
-[CAR_32]
-Perennial
+[TAXI_1]
+V.I.P.
-[CAR_33]
-Landstalker
+[TAXI_2]
+Rivalidad amistosa
-[CAR_34]
-Mañana
+[TAXI_3]
+Taxigedón
-[CAR_35]
-Idaho
+[ICE_1]
+Distribución
-[CAR_36]
-Stallion
+[TEX_1]
+Hierro número cuatro
-[CAR_37]
-Taxi
+[TEX_2]
+Dos leves impactos
-[CAR_38]
-Cabbie
+[TEX_3]
+Demoledor
-[CAR_39]
-Buggy
+[PHIL_1]
+Traficante de armas
-[LUIGIS]
-Club de Luigi
+[PHIL_2]
+Boomshine Saigon
-[GOAWAY]
-~g~¡Ya estás en una misión!
+[BIKE_1]
+Moto con llantas de aleación
-[LUIGGO]
-~g~Luigi está entrevistando a unas chicas nuevas... ¡Vuelve más tarde!
+[BIKE_2]
+Incitando al macho
-[JOEYGO]
-~g~Joey ha salido con Misty. ¡Pásate más tarde!
+[BIKE_3]
+Moto robada
-[TONIGO]
-~g~Toni ha llevado a su mamá a la ópera... ¡Vente en otro momento!
+[ROCK_1]
+Love Juice
-[KEMUGO]
-~g~María y Kemuri están muy liadas... ¡Pásate más tarde!
+[ROCK_2]
+Asesino psicópata
-[KENJGO]
-~g~Kenji está reunido con la yakuza, ¡ven en otro momento!
+[ROCK_3]
+Gira publicitaria
-[RAYGO]
-~g~Ray tiene otros baños por los que rondar, ¡ven en otro momento!
+[ROCK_4]
+¡Love Fist!
-[LOVEGO]
-~g~Donald Love tiene otros asuntos que atender. ¡Pide una cita más tarde!
+[HAT_1]
+Poción mágica
-[KENSGO]
-~g~¡Kenji está ocupado! ¡Llama más tarde!
+[HAT_2]
+¡Bombas fuera!
-[ASUSGO]
-~g~¡Asuka no está disponible en este momento!
+[HAT_3]
+Juego sucio
-[HOODGO]
-~g~¡Los Hoods no pueden atenderte en este momento!
+[CUB_1]
+El desafío del barco trucado
-[WRONGT1]
-~g~Vuelve entre las 05:00 y las 21:00 para buscar trabajo.
+[CUB_2]
+Carne de cañón
-[WRONGT2]
-~g~Vuelve entre las 06:00 y las 14:00 para buscar trabajo.
+[CUB_3]
+Encuentro naval
-[WRONGT3]
-~g~Vuelve entre las 15:00 y las 00:00 para buscar trabajo.
+[CUB_4]
+Vudú troyano
-[GUN_1A]
-Pulsa ~h~~k~~PED_CYCLE_WEAPON_RIGHT~~w~ y ~h~~k~~PED_CYCLE_WEAPON_LEFT~ ~w~para cambiar de arma.
+[JOB_1]
+Muerte en la carretera
-[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_2]
+Elimina a la esposa
-[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_3]
+Autocidio
-[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...
+[JOB_4]
+Comprobar el registro
-[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.
+[JOB_5]
+Cabos sueltos
-[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.
+[ANSWER]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para responder a una llamada a tu teléfono móvil.
-[GUN_4A]
-Mientras mantienes pulsado ~h~~k~~PED_LOCK_TARGET~~w~, puedes moverte mientras sigues apuntando a tu 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_4B]
-Mientras mantienes pulsado ~h~~k~~PED_LOCK_TARGET~~w~, puedes moverte mientras sigues apuntando a tu objetivo.
+[MOB_01B]
+Estoy de relax en el Malibu.
-[GUN_5]
-Puedes practicar disparando a estas dianas. Vuelve a la misión cuando hayas terminado.
+[MOB_01C]
+Creo que después de esto me vas a deber un favor o dos, guapo. Hasta luego.
-[TAXI1]
-~g~Busca un cliente.
+[MOB_02A]
+Ssssnniiiiffffff... ¡Eh! Hola, ¿Tommy? ¡Tommy!
-[FARE1]
-~g~Ve al ~w~club Sex Kitten Meeouch ~g~en el barrio rojo.
+[MOB_02B]
+Tenemos un problema en la imprenta. Mejor que vayas y lo compruebes.
-[FARE2]
-~g~Ve a ~w~Supa Save ~g~en Portland View.
+[MOB_02C]
+Algún tipo de lío. Las cosas andan revueltas. Tengo que irme.
-[FARE3]
-~g~Ve a ~w~la sala Clásica ~g~en Chinatown.
+[MOB_03A]
+¿Sr. Vercetti? Tengo un trozo de mierda firmada que dice
-[FARE4]
-~g~Ve a la ~w~cafetería Greasy Joe ~g~en Callahan Point.
+[MOB_03B]
+que usted ha asumido todas las deudas de BJ's Auto.
-[FARE5]
-~g~Ve a la ~w~tienda de armas Ammu-Nation ~g~en el barrio rojo.
+[MOB_03C]
+Con la repentina desaparición de BJ no tengo más remedio
-[FARE6]
-~g~Ve a ~w~Easy Credit Autos ~g~en Saint Mark's.
+[MOB_03D]
+que hacerle responsable de su inestabilidad financiera
-[FARE7]
-~g~Ve al ~w~bar de topless de Woody ~g~en el barrio rojo.
+[MOB_03E]
+Hasta que esta cuenta quede completamente saldada
-[FARE8]
-~g~Ve al ~w~restaurante Marcos ~g~en Saint Mark's.
+[MOB_03F]
+debería considerar que las calles de Vice City son poco seguras.
-[FARE9]
-~g~Ve al ~w~taller de importación y exportación ~g~en el puerto de Portland.
+[MOB_04A]
+¿Cómo estás, tío? Soy Paulo.
-[FARE10]
-~g~Ve a ~w~Punk Noodles ~g~en Chinatown.
+[MOB_04B]
+Mira, Tommy, me olvidé de mencionar que vamos a necesitar más seguridad para el concierto.
-[FARE12]
-~g~Ve al ~w~estadio de fútbol ~g~en Aspatria.
+[MOB_04C]
+Hay una banda de moteros liderada por Mitch Baker que serían la publicidad ideal.
-[FARE13]
-~g~Ve a la ~w~iglesia ~g~de Bedford Point.
+[MOB_04D]
+Solucióname esto y te conseguiré un pase para la actuación, ¿vale?
-[FARE14]
-~g~Ve al ~w~casino ~g~de Torrington.
+[MOB_05A]
+Soy Mitch. Hiciste un buen trabajo, Tommy. Es bueno volver a tener a mi pequeña en casa.
-[FARE15]
-~g~Ve a la ~w~universidad ~g~en el Campus de Liberty.
+[MOB_05B]
+Dile al Sr. Kent Paul que dispondrá de seguridad para la actuación.
-[FARE16]
-~g~Ve al ~w~centro comercial ~g~en la zona del parque Belleville.
+[MOB_05C]
+Tiene mi palabra de ello.
-[FARE17]
-~g~Ve al ~w~museo ~g~de Newport.
+[MOB_05D]
+Intenta no meterte en problemas.
-[FARE18]
-~g~Ve al ~w~edificio de AmCo ~g~en Torrington.
+[MOB_06A]
+Tommy, esos de abajo han estado rajando sobre ti, chico.
-[FARE19]
-~g~Ve a ~w~Bolt Burgers ~g~en Bedford Point.
+[MOB_06B]
+Pensé que podrías necesitar consuelo casero así que la tía Poulet te preparará una sopa, ¿hmmm?
-[FARE20]
-~g~Ve al ~w~parque ~g~de Belleville.
+[MOB_06C]
+Pásate por mi cocina alguna vez, ¿de acuerdo Tommy?
-[FARE21]
-~g~Ve al ~w~Aeropuerto Internacional Francis.
+[MOB_08A]
+Eh Tommy, pensé que podrías necesitar algún asesoramiento financiero.
-[FARE22]
-~g~Ve a la ~w~presa Cochrane~g~.
+[MOB_08B]
+Una vez que tengas la operación en marcha, tendrás que pasarte a recoger la recaudación de la semana.
-[FARE24]
-~g~Ve al ~w~hospital ~g~de Pike Creek.
+[MOB_08C]
+Deja que esos tipos crean que son los amos del lugar e intentarán cepillarse los beneficios... ¿vale?
-[FARE25]
-~g~Ve al ~w~parque ~g~de Shoreside Vale.
+[MOB_08D]
+Eh, sé como llevar el negocio, Ken.
-[FARE26]
-~g~Ve a las ~w~Torres del Noroeste ~g~de Wichita Gardens.
+[MOB_08E]
+Vale, vale. Lo sé, ya sabes. Lo sé. Estaba,
-[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_08F]
+Sólo estaba, ya sabes, diciéndote que sé, que tú sabes que yo lo sé.
-[TSCORE2]
-~1~ $
+[MOB_08G]
+¡Solo manteniéndolo a punto, nene!
-[IN_ROW]
-¡Racha de ~1~ clientes! Premio de ~1~ $.
+[MOB_08H]
+Lo que sea, Ken, lo que sea...
-[TTUTOR]
-Pulsa ~h~~k~~TOGGLE_SUBMISSIONS~~w~ para activar o desactivar las misiones de taxi.
+[MOB_09A]
+¡Eh, Leo! ¡Tengo trabajo para ti!
-[TTUTOR2]
-Pulsa ~h~~k~~TOGGLE_SUBMISSIONS~~w~ para activar o desactivar las misiones de taxi.
+[MOB_09B]
+No soy Leo.
-[ATUTOR2]
-~g~Lleva a los pacientes al hospital CON CUIDADO. Cada golpe reducirá sus posibilidades de supervivencia.
+[MOB_09C]
+¡Eh, como Leo sepa que tienes su teléfono, te va a liquidar!
-[A_TIME]
-+~1~ segundos
+[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?
-[A_FULL]
-~r~¡Ambulancia llena!
+[MOB_09E]
+¿Mataste a Leo? Debes tener unas pelotas muy grandes... ¿quieres trabajar para mí?
-[A_RANGE]
-~g~La radio de la ambulancia está fuera de cobertura, ¡acércate a un hospital!
+[MOB_09F]
+Pásate por el café de mi padre en Little Havana y podremos hablar de tú a tú.
-[FTUTOR]
-Pulsa ~h~~k~~TOGGLE_SUBMISSIONS~~w~ para activar o desactivar las misiones del camión de bomberos.
+[MOB_10A]
+¡Tommy! Mira, tengo que pedirte un favor.
-[FTUTOR2]
-Pulsa ~h~~k~~TOGGLE_SUBMISSIONS~~w~ para activar o desactivar las misiones del camión de bomberos.
+[MOB_10B]
+¡Steve! ¿Cómo van con el rodaje?
-[F_PASS1]
-¡Fuego apagado!
+[MOB_10C]
+Bien, bien. Yo, je, NOSOTROS necesitamos una escena con una persecución de coches, pero nuestro presupuesto no da para más.
-[F_RANGE]
-~g~La radio del camión de bomberos está fuera de cobertura, ¡acércate a una estación de bomberos!
+[MOB_10D]
+Me han dejado un coche en la ciudad. Tú sabrás qué hacer.
-[C_BREIF]
-~g~Sospechoso visto por última vez en: ~a~.
+[MOB_10E]
+De acuerdo, Steve, estaré al tanto. Te veo luego.
-[C_RANGE]
-~g~La radio de la policía está fuera de cobertura, ¡acércate a una comisaría!
+[MOB_11A]
+¿Qué hay, hijo? Pensé sólo en llamarte para darte algún consejo.
-[DODO_FT]
-¡Has volado durante ~1~ segundos!
+[MOB_11B]
+Hola, Avery. ¿Qué te preocupa?
-[EBAL_A]
-Conozco un lugar en las afueras del barrio rojo donde podemos escondernos,
+[MOB_11C]
+Hay muchas oportunidades en esta ciudad si dispones de las propiedades adecuadas, ¿entiendes lo que quiero decir?
-[EBAL_A1]
-pero mis manos están destrozadas, así que conduce tú, hermano.
+[MOB_11D]
+Creo que sí...
-[EBAL_1]
-Pulsa ~h~~k~~VEHICLE_ENTER_EXIT~~w~ para ~h~entrar ~w~o ~h~salir~w~ de un vehículo.
+[MOB_11E]
+Lo que digo es que mantengas los ojos abiertos y podrás encontrar la oportunidad de negocio perfecta. Te veré luego.
-[EBAL_1B]
-Pulsa ~h~~k~~VEHICLE_ENTER_EXIT~~w~ para ~h~entrar ~w~o ~h~salir~w~ de un vehículo.
+[MOB_11F]
+Nos vemos, Avery.
-[EBAL_2]
-~g~¡Vuelve al coche!
+[MOB12_A]
+¡Eh, Tommy, soy Avery! Ahora escucha, estoy muy liado en este momento
-[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_B]
+y uno de mis representantes necesita carabina para ir a Gator Keys.
-[EBAL_D]
-Conozco a un tipo con contactos, se llama Luigi.
+[MOB12_C]
+Estoy detrás de unas tierras por allí, así que voy a enviar alguien a que ablande el trato.
-[EBAL_D1]
-Somos viejos amigos, así que podremos buscarte curro. Vamos a verlo.
+[MOB12_D]
+Podrías hacerme un favor y asegurarte de que llega allí, ¿entendido?
-[EBAL_E]
-Venga, vamos a pasarnos por allí y te presentaré.
+[MOB12_E]
+Sí, eso está hecho, Avery. ¿Dónde te gustaría que le recogiese?
-{ UNUSED }
+[MOB12_F]
+Está terminando algunos negocios en la obra. Le dije que le recogerías allí.
-[EBAL_I]
-El jefe os recibirá enseguida...
+[MOB12_G]
+Ningún problema. Nos vemos, Avery.
-[EBAL_J]
-8-Ball tiene cosas que hacer arriba.
+[MOB13_A]
+¿Vercetti? ¡VERCETTI! ¡Maldito seas, tío, tienes que ayudarme!
-[EBAL_K]
-Quizá puedas hacerme un favor.
+[MOB13_B]
+¿Sr. Moffat? ¿Cómo le va la vida en familia?
-[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_C]
+Maldito seas, DEMONIOS, ¿me oyes?
-[EBAL_N]
-¡Así que no quites las manos del volante!
+[MOB13_D]
+Bueno, fue agradable charlar...
-[EBAL_4]
-~r~¡8-Ball ha muerto!
+[MOB13_E]
+¡ESPERA! Espera, Vercetti Tommy, ¿Puedo llamarte Tommy?
-[EBAL_5]
-~g~¡Consigue un vehículo!
+[MOB13_F]
+Los dos somos hombres de negocios, ¿verdad? Reconoces un buen negocio cuando lo ves.
-[EBAL_6]
-~g~¡Recoge a Misty!
+[MOB13_G]
+No tengo tiempo para charlar, vaya al grano.
-[LM1]
-'LAS CHICAS DE LUIGI'
+[MOB13_H]
+DINERO. El dinero es el maldito asunto.
-[LM2]
-'NO DROGUES A MI ZORRA'
+[MOB13_I]
+Me escapado de la trena otra vez, pero nunca tardan mucho en encontrarme... ¡creen que es un maldito juego!
-[LM3]
-'LLEVA A MISTY POR MÍ'
+[MOB13_J]
+Estoy en un teléfono público en alguna parte de este agujero de mierda olvidado de la mano de Dios.
-[LM5]
-'EL BAILE DE LA POLICÍA'
+[MOB13_K]
+Sácame de aquí antes de que me lleven de vuelta y... oh... Dios...
-[LM1_2]
-~g~Lleva a Misty al club de Luigi.
+[MOB13_L]
+Bueno, estoy ocupado durante las próximas...
-[LM1_3]
-~g~Toca el claxon para que la chica entre en el coche.
+[MOB13_M]
+¡No! ¡No me jodas, ten piedad! Ningún hombre debería tener que hacer esas, esas cosas.
-[LM1_6]
-~g~¡Vuelve al coche!
+[MOB13_N]
+Estoy de rodillas, Tommy, en el fango, rogándote, por favor...
-[LM1_7]
-Para el vehículo junto a Misty y déjala que suba.
+[MOB13_O]
+Supongo que podría desviarme hacia allí, veré si puedo localizarte...
-[LM1_8]
-Puedes ir a ver a Luigi para que te dé más trabajo o explorar Liberty City.
+[MOB13_P]
+Oh, Dios, ya vienen. Por el amor de Dios, date prisa, ¡date prisa!
-[LM2_A]
-Hay una nueva droga en la ciudad llamada SPANK.
+[MOB_14A]
+Hola, Tommy, me vas a adorar, amigo.
-[LM2_E]
-Algún listillo ha pasado esta basura a mis chicas en el puerto de Portland.
+[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_B]
-¡Ve y repásale la cara con un bate de béisbol!
+[MOB_14C]
+donde guardan todos los sobornos que han recibido durante estos años,
-[LM2_G]
-¡Quiero una compensación por este insulto!
+[MOB_14D]
+¡como una especie de fondo de retiro para los veteranos!
-[LM2_1]
-~g~Llévate su coche y repíntalo.
+[MOB_14E]
+Por supuesto, si esta información te ayudase a adquirir parte de ese dinero,
-[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_14F]
+¿Supongo que te sentirías obligado a mandarme algo?
-[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_14G]
+Lo tendré en mente, gracias Kent.
-[LM2_2D]
-¡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_3]
-~g~¡Mete el coche en el garaje de Luigi!
+[MOB_14I]
+Mi conocimiento de la geografía provincial inglesa ya no es lo que era.
-[LM2_4]
-~g~¡Vuelve a pintar el coche!
+[MOB15_A]
+Tommy, colega, soy Paul, de Kent,
-[LM3_A]
-Hola, tengo que hablar contigo... Bueno, Mick, ya hablaremos.
+[MOB15_B]
+un par de titis han escrito tu nombre por todas partes, en el Malibú.
-[LM3_B]
-¿Cómo te va, chico?
+[MOB15_C]
+¿De qué estás hablando?
-[LM3_C]
-El hijo del Don, Joey Leone, quiere fiesta con su chica de siempre, Misty.
+[MOB15_D]
+Tías. Palomitas. Ya sabes. Chicas. De las buenas, no creas que son furcias ni nada por el estilo.
-[LM3_D]
-Recógela en los cerros de Hepburn,
+[MOB15_E]
+Tienes que venir a echarles un vistazo.
-[LM3_E]
-pero cuidado, ese es territorio de los Diablos.
+[MOB16_A]
+Tommy, aquí Paulo, ¿qué pasa amigo?
-[LM3_F]
-Luego llévala rapidito hasta su taller en Trenton,
+[MOB16_B]
+¿Qué quieres Paul? No quiero ropa de imitación.
-[LM3_H]
-¡así que fíjate en el camino y no en Misty!
+[MOB16_C]
+Muy divertido, colega, pero yo no toco la ropa falsificada.
-[LM3_1D]
-Pulsa ~h~~k~~VEHICLE_HORN~~w~ para tocar el ~h~claxon~w~ y avisar a Misty.
+[MOB16_D]
+Nada, sólo llamaba para ver si consigo un papel en una de tus películas,
-[LM3_2]
-~g~Lleva a Misty al local de Joey.
+[MOB16_E]
+en Inglaterra hice un montón de porno, colega.
-[LM3_4]
-~g~¡Recoge a Misty!
+[MOB16_F]
+Guardo más fuego que tu, hijo mío.
-[LM3_5]
-Ahora trabajas para Luigi, ¿no? ¡Ya era hora de que tuviese un conductor de confianza!
+[MOB16_G]
+Paul, gracias por la oferta, lo tendré en mente.
-[LM3_7]
-Estaré contigo en un momento, bujía mía.
+[MOB16_H]
+En serio, no te olvides de mí, después de todo lo que he hecho por ti.
-[LM3_10]
-~g~¡Consigue un vehículo!
+[MOB16_I]
+Eso es lo que estoy intentando olvidar.
-[LM4_B]
-Resuelve esto por mí.
+[MOB19_A]
+Tommy V, aquí KP. Kent Paul. En las calles se dice que hay gente que te quiere despellejar.
-[LM4_C]
-Si necesitas un arma, ve a la parte de atrás del Ammu-Nation que está enfrente del metro.
+[MOB19_B]
+Mantén los ojos abiertos. Y recuerda, yo no te he dicho nada de esto.
-[LM5_A]
-El baile de la policía se está celebrando en la sala Clásica, cerca del puente,
+[MOB_20A]
+De acuerdo, Tommy, soy Paul. Me ha dicho un pajarito que has sido un chico muy malo.
-[LM5_B]
-y parece que tienen ganas de una fiesta más ''clásica''.
+[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_C]
-Tengo chicas haciendo la calle.
+[MOB_20C]
+Bueno, no digas que nunca te advertí. Presumir es un juego de tontos, hijo.
-[LM5_D]
-Llévalas al baile, sacarán una buena tajada.
+[MOB_20D]
+En cualquier caso, oí que se ha puesto un precio a tu cabeza y que alguien te la va a partir,
-[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.
+[MOB_20E]
+así que ten cuidado, y acuérdate de mí, colega.
-[LM5_2]
-~r~¡Una chica de Luigi la ha espichado!
+[MOB21_A]
+Tommy, Thomas, soy Cortez. ¿Qué pasa?
-[LM5_3]
-~g~¡Necesitas un coche!
+[MOB21_B]
+Las cosas van bien. ¿Cómo estás?
-[LM5_4]
-~g~Recoge a las chicas que trabajan en Saint Mark's.
+[MOB21_G]
+De todos modos, Tommy, quisiera preguntarte algo sobre Mercedes.
-[LM5_5]
-~g~¡Lleva a las chicas al baile de la policía!
+[MOB21_H]
+¿Sí? ¿Qué pasa con ella?
-[LM5_8]
-~g~Chicas trabajando en el baile: ~1~
+[MOB21_I]
+Oh Tommy, Tommy, oigo todas esas historias y no sé qué pensar.
-[JM2]
-'DESPEDIDA A LEE CHONG ''EL GORDO'''
+[MOB21_K]
+Quizás ella piense que puede hacer lo que quiera ahora que pero dime, Tommy, ¿es verdad?
-[JM4]
-'EL CHÓFER DE CIPRIANI'
+[MOB21_M]
+¿El qué es verdad?
-[JM5]
-'FIAMBRE EN EL MALETERO'
+[MOB21_N]
+Las historias que he oído. ¿De verdad va a ser abogada?
-[JM1_1]
-~g~Lleva el coche de Forelli al taller que tiene 8-Ball al norte, tras Easy Credit Autos.
+[MOB21_O]
+Oh Tommy, la vergüenza. Los Cortez somos una familia orgullosa
-[JM1_2]
-~g~Vuelve a aparcar el coche frente al restaurante de Marco.
+[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_3]
-~g~¡Activa la bomba del coche y luego sal de ahí!
+[MOB21_Q]
+Coronel, puedo asegurarle que Mercedes nunca será abogada. No tema.
-[JM1_4]
-~g~¡Te estás cargando el coche! ¡Repáralo!
+[MOB21_R]
+Gracias, Tommy, gracias. La vergüenza sería insoportable.
-[JM1_5]
-~g~¡La bomba del coche no está activada!
+[MOB21_S]
+Lo sé, coronel.
-[JM1_6]
-~g~Vuelve a aparcar el coche en el sitio correcto.
+[MOB21_T]
+Bueno, Tommy, debes perdonarme, ha llegado el nuevo ministro de interior.
-[JM1_8A]
-~y~¡Ey, pero si es mi colega!
+[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_8B]
-~y~El taller de bombas está automatizado. Sólo tienes que meter el coche, pararlo y el taller hará el resto.
+[MOB21_C]
+Tommy, aquí siempre es una lucha. Siento el ruido, acabamos de tener otro golpe fallido.
-[JM1_8C]
-~y~Ten, tu primer coche es gratis, pero los siguientes te los cobraré.
+[MOB21_D]
+La gente es la señora más exigente de todas.
-[JM2_A]
-Lee Chong ''el Gordo'' está traficando SPANK para una nueva banda de Colombia, o Colorado... O como se llame.
+[MOB21_E]
+Desde que he vuelto de Vice City y hasta ahora, hemos tenido tres revoluciones y cuatro golpes.
-[JM2_B]
-No me acuerdo. El caso es que no importa.
+[MOB21_F]
+Afortunadamente, me han ascendido cada vez.
-[JM2_D]
-Ese cabrito ha vendido su último fideo.
+[MOB21_J]
+Quizás todo el mundo me está humillando.
-[JM2_E]
-¡Lo quiero muerto!
+[MOB21_L]
+pero dime, Tommy, ¿es verdad?
-[JM2_G]
-Búscate un nueve, queda claro, ¿no?
+[MOB22_A]
+Tommy, estás demostrando ser muy útil, amigo mío.
-[JM2_H]
-Y recuerda, ve con ojo en Chinatown: es territorio de las Tríadas.
+[MOB22_B]
+Gracias, Cortez. ¿Qué hay de mi asunto?
-[JM3_A]
-Vamos a robar un furgón blindado.
+[MOB22_C]
+Tommy, estoy trabajando infatigablemente en tu nombre para conseguir llegar al fondo de esta zanja de apestosas mentiras y engaños,
-[JM3_B]
-Sale de Chinatown todos los días.
+[MOB22_D]
+tienes mi palabra al respecto, pero mientras tanto,
-[JM3_C]
-Las balas ni siquiera abollarán el furgón, así que coge un coche y échalo de la carretera.
+[MOB22_E]
+por favor, acepta el estimable agradecimiento de mi gente por tu trabajo para nosotros.
-[JM3_D]
-Si lo zurras bien, los imbéciles de los guardias se achantarán.
+[MOB_25A]
+Tommy, soy Cortez. Los franceses me están causando todo tipo de problemas.
-[JM3_E]
-Luego llévalo al almacén de los muelles y mis chicos se encargarán del resto.
+[MOB_25B]
+Malditos hipócritas. ¡Se pasan cien años robando a países pobres y me llaman ladrón a mí!
-[JM3_F]
-El furgón no estará fuera todo el día, así que no pierdas el tiempo.
+[MOB_25C]
+Voy a necesitar tu ayuda tan pronto como sea posible.
-[JM3_1]
-~g~Lleva el furgón al almacén.
+[MOB_25D]
+Por favor, Tommy, date prisa, te necesito, ¿de acuerdo? Odio a esos malditos franceses.
-[JM3_2]
-~g~Carga contra el furgón hasta que su daño esté por debajo del 70 por ciento.
+[MOB_26A]
+Hola, ¿Tommy?
-[JM4_B]
-¡Ah, aquí está el tío que te decía!
+[MOB_26B]
+¿Sí?
-[JM4_C]
-Bueno, éste no es italiano ni tampoco mecánico, pero sabe arreglar cosas.
+[MOB_26C]
+Soy Baker. Sólo quería decirte que verdaderamente disfruté con el espectáculo.
-[JM4_D]
-Él es el capo de papá, Toni Cipriani.
+[MOB_26D]
+Los chicos y yo queremos darte las gracias, y recordarte,
-[JM4_E]
-Sí, soy Toni Cipriani.
+[MOB_26E]
+que te tienes nuestro respeto. Buenos días. Sigue cabalgando duro, chico.
-[JM4_F]
-Llévale al restaurante de Mamma en Saint Mark's, ¿va?
+[MOB_29A]
+Hola, ¿hablo con el Sr. Tommy Vercetti?
-[JM4_G]
-Oye, estoy planeando un curro que necesita un buen conductor, pásate por aquí más tarde, ¿estamos?
+[MOB_29B]
+Sí.
-[JM4_2]
-¡Espera aquí! Deja el motor en marcha. Ésta no es una visita social.
+[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_3]
-¡Es una emboscada de las Tríadas! ¡Sácanos de aquí, chico!
+[MOB_29D]
+Puede...
-[JM4_4]
-Las Tríadas creen que pueden meterse conmigo. ¡Las Tríadas, CONMIGO!
+[MOB_29E]
+Bueno, yo tengo una plaga de bichos de verdad. Haitianos, por todas partes.
-[JM4_6]
-¡Mi coche! Dije que fueras con cuidado.
+[MOB_29F]
+Mi nombre es Umberto Robina y quiero que nos reunamos en el Café Robina lo antes posible,
-[JM4_7]
-~g~Lleva a Toni al restaurante de Mamma.
+[MOB_29G]
+porque, como le digo, estos malditos haitianos se han pasado de la raya esta vez.
-[JM4_8]
-~r~¡Toni la ha palmado!
+[MOB_29H]
+Prueba
-[JM5_A]
-Guapo, muy guapo...
+[MOB_30A]
+Tommy, soy Umberto Robina.
-[JM5_B]
-¡Justo te estaba buscando!
+[MOB_30B]
+¿Cómo está el café?
-[JM5_D]
-Uno de los Forelli se las daba de mafioso y se llevó su merecido.
+[MOB_30C]
+Oh, maravilloso. Increíble. Tommy, increíble. Sin blandengues, Tommy, sólo hombres de verdad, ya sabes, ¡y las mujeres hermosas!
-[JM5_E]
-Lleva el cuerpo a la trituradora en Harwood, ¿vale?
+[MOB_30D]
+De todos modos, quería decirte que para papá y para mí, para nosotros, ahora eres un cubano.
-[JM5_1]
-~g~¡Llévalo a la trituradora!
+[MOB_30E]
+Has demostrado que tienes unas pelotas de cojones, tío.
-[JM5_2]
-~g~¡Son los hermanos Forelli!
+[MOB_30F]
+Gracias, Umberto. Nadie me había dicho eso desde que salí de la cárcel. Nos vemos.
-[JM6_A]
-Vaya cochazo, ¿eh?
+[MOB_33A]
+Tommy, soy Phil, olvida toda esa mierda del pasado y escúchame, ¿me oyes?
-[JM6_B]
-Bueno, escucha. Lleva un coche a la casa franca de Saint Mark's y recoge a unos colegas.
+[MOB_33B]
+Bien. Tengo un pelotazo extra a punto de fermentar y me preguntaba si te apetecería probarlo.
-[JM6_C]
-Van a atracar un banco y necesitan un conductor.
+[MOB_33C]
+En serio, Tommy, si quieres una copa, o si necesitas ponerte a tono, este material hará de ti un hombre.
-[JM6_D]
-Di mi palabra de que eras su hombre, así que no la cagues.
+[MOB_33D]
+A mí me pasó aunque todavía no puedo ver por un ojo. Te estaré esperando, lo que oyes.
-[JM6_E]
-Llévalos al banco antes de las cinco en punto, ni un minuto después.
+[MOB_34A]
+Tommy, de verdad que he disfrutado trabajando contigo. No me había divertido tanto desde la loma en Vietnam, colega.
-[JM6_2]
-Mantén el motor en marcha, entraremos y saldremos enseguida.
+[MOB_34B]
+De todas formas, si necesitas algo, llámame, ¿me oyes?
-[JM6_3]
-¡Sácanos de aquí!
+[MOB_34C]
+Siempre me acuerdo de aquellos con los que he servido,
-[JM6_4]
-¡Líbrate de la poli y llévanos a la casa franca!
+[MOB_34D]
+y estoy seguro de que puedo ayudarte, ¿me oyes?
-[JM6_6]
-~g~¡Busca un vehículo menos llamativo!
+[MOB_35A]
+Tommy, la herida está cicatrizando bien. Lo gracioso es
-[JM6_7]
-~g~¡Necesitas a los 3 para robar el banco!
+[MOB_35B]
+que he luchado en 6 zonas de combate y siempre he salido sin un rasguño, ¡y ahora esto!
-[TM1]
-'SACANDO LA COLADA'
+[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.
-[TM2]
-'LA ENTREGA'
+[MOB_35D]
+Venga, hijo, corta con esa mierda sentimental y pídete una copa, ¡me oyes!
-[TM3]
-'SALVATORE HA CONVOCADO UNA REUNIÓN'
+[MOB_36A]
+Tommy, soy Phil, quiero darte las gracias por ayudarme allí, hijo,
-[TM4]
-'TRÍADAS Y TRIBULACIONES'
+[MOB_36B]
+maldito Charlie, siempre te tenderá una emboscada de un modo o de otro.
-[TM5]
-'LLUVIA DE PECES'
+[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.
-[TONI_P]
-¡Tengo un trabajo urgente para ti! -Toni
+[MOB_40A]
+Eh, Tommy, soy Sonny. ¿Qué tal el bronceado?
-[TM1_A]
-Siéntate, chico, siéntate de una vez.
+[MOB_40B]
+No tengo bronceado.
-[TM1_B]
-La lavandería no quiere pagar la protección, ¿eh?
+[MOB_40C]
+Bueno, tampoco tienes mi dinero, así que me estoy preguntando,
-[TM1_C]
-¿Las Tríadas creen que pueden meterse conmigo?
+[MOB_40D]
+¿qué estás haciendo? Así que, dime Tommy ¿qué estás haciendo?
-[TM1_D]
-¡Se van a enterar esos aspirantes a tipos duros de lo que es ser un tipo duro!
+[MOB_40E]
+Estoy buscando el dinero, Sonny. No te preocupes.
-[TM1_E]
-¡Eso, enséñales respeto! ¡Las Tríadas no se ríen de ninguno de mis hijos!
+[MOB_40F]
+Me estoy preocupando, Tommy, ese es mi estilo,
-[TM1_F]
-Tu padre, Dios acoja su alma, no toleraba ni media a las Tríadas en Sicilia.
+[MOB_40G]
+porque parece que en mi vida tengo este problema con gente que no es de confianza.
-[TM1_G]
-Lo siento, mamá. Sí, mamá.
+[MOB_40H]
+No seas una persona poco fiable, Tommy, por favor.
-[TM1_H]
-Quiero que te cargues sus furgonetas de lavandería
+[MOB_40I]
+Haznos un favor. Tengo muchas ganas de tener noticias tuyas.
-[TM1_I]
-y a cualquiera de las Tríadas que se cruce en tu camino.
+[MOB_41A]
+Tommy, ¿te acuerdas de mí?
-[TM1_J]
-8-Ball te dará lo que necesites.
+[MOB_41B]
+Hola, Sonny.
-[TM2_A]
-Toni ha salido a partir cabezas, o a intentarlo...
+[MOB_41C]
+Sí, está bien, Sonny. Somos viejos amigos,
-[TM2_AA]
-Nunca será tan duro como su padre. Te dejó una nota en la mesa.
+[MOB_41D]
+y nunca me escribes, nunca llamas. ¿No quieres que sigamos siendo amigos?
-[TM2_B]
-La lavandería ya quiere pagar. ¡Buen trabajo, chico!
+[MOB_41E]
+He estado muy ocupado intentando arreglar las cosas. No me diste mucho apoyo.
-[TM2_C]
-Ve a por el dinero y tráelo aquí. Cuidado con las Tríadas.
+[MOB_41F]
+Oh, y es culpa mía, ¿verdad? Bueno, he oído que has estado muy ocupado.
-[TM2_D]
-Puede que intenten metértela doblada, pero no te dejes.
+[MOB_41G]
+Ocupado matando a capos. Ocupado tomando el poder.
-[TM2_E]
-¡Nadie, quiero decir nadie, se mete con Toni Cipriani!
+[MOB_41H]
+No te olvides de nosotros, Tommy, porque puedo asegurarte que yo no me he olvidado de ti.
-[TM2_1]
-~g~¡Lleva el dinero a Toni!
+[MOB_42A]
+Tommy.
-[TM2_2]
-~g~¡Los dejaste tiesos a todos!
+[MOB_42B]
+Sonny.
-[TM3_MA]
-¡No sé dónde está!
+[MOB_42C]
+Obviamente tienes un problema a la hora de escuchar a los demás, de modo que lo intentaré de nuevo.
-[TM3_MB]
-Te juro que mi hijo a veces no sabe lo que hace.
+[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_MC]
-Ahora bien, su padre era diferente. Siempre en la cumbre, pendiente de todo, valiente...
+[MOB_42E]
+Me estás haciendo quedar como un idiota, Tommy, y no me hace gracia.
-[TM3_A]
-Don Salvatore ha convocado una reunión.
+[MOB_43A]
+Tommy, Tommy, Tommy, tenía a Sonny al teléfono, de acuerdo, ¿me sigues?
-[TM3_B]
-Necesito que vayas a por la limusina y su hijo, Joey, a su taller.
+[MOB_43B]
+No sé tú, pero hay algo sobre un hombre que amenaza con asesinar a mi familia
-[TM3_C]
-Luego recoge a Luigi en su club, ven a buscarme,
+[MOB_43C]
+que realmente me pone enfermo. ¿Qué vas a hacer?
-[TM3_D]
-y nos iremos todos juntos a la casa del jefe.
+[MOB_43D]
+Ten calma, Ken, todo irá bien.
-[TM3_E]
-Los de las Tríadas no saben cuándo parar...
+[MOB_43E]
+¡ESTOY calmado, todo lo calmado que puede estar un hombre cuando teme por su vida!
-[TM3_F]
-Si quieren guerra, la tendrán.
+[MOB_43F]
+Ken, ahora mismo tengo otras cosas en la cabeza,
-[TM3_G]
-Ponte en marcha.
+[MOB_43G]
+nos ocuparemos de Forelli cuando llegue el momento.
-[TM3_1]
-~g~Ve al taller de Joey a por la limusina.
+[MOB_43H]
+Estoy calmado. ¿No te lo parece? Debe ser la muerte inminente la que le hace esto a mi voz.
-[TM3_2]
-~g~Recoge a Luigi.
+[MOB45_A]
+Tommy, tenemos cosas de las que hablar.
-[TM3_3]
-~g~Ahora recoge a Toni.
+[MOB45_B]
+¿Cuál es el problema, Lance?
-[TM3_4]
-~g~Lleva a los mafiosos a la casa de Salvatore.
+[MOB45_C]
+Eres tú, amigo, creo que no me estás dando una tajada justa.
-[TM3_5]
-~y~¡Es una emboscada de las Tríadas!
+[MOB45_D]
+Y lo que es más, me estás avergonzando delante de los chicos. No puedo permitirlo.
-[TM4_B]
-¡Esto es la guerra! Las Tríadas tienen una piscifactoría como tapadera.
+[MOB45_E]
+Lance, las cosas no son así. Has estado cometiendo errores.
-[TM4_C]
-Casi todos sus negocios pasan por la lonja de Chinatown.
+[MOB45_F]
+Tommy, no soy tu chico de los recados. No soy tu emisario.
-[TM4_D]
-La lavandería todavía no ha pagado la protección.
+[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_E]
-Creen que está protegida por las Tríadas, así que creo que se merecen un castigo.
+[MOB45_H]
+Tommy, he hecho de todo por ti, pero me tratas como si fuese estúpido. No hagas eso.
-[TM4_F]
-¡Llévate a estos chicos y elimina a los líderes de las Tríadas!
+[MOB45_I]
+Lance no te voy a timar ni a apuñalarte por la espalda, de acuerdo.
-[TM4_G]
-Qué narices, si ves la oportunidad, cárgate también a unos cuántos de sus soldados.
+[MOB45_J]
+Tómatelo con calma. Esto ya es lo suficientemente duro sin que te me pongas sentimental.
-[TM4_GAT]
-~g~Necesitas un camión de pescado de las Tríadas para entrar.
+[MOB45_K]
+Confía en mí. ¿Me oyes, me oyes?
-[TM5_B]
-Vale, ya me he hartado de esta mierda.
+[MOB45_L]
+Te oigo, pero Tommy, no puedo aguantar esto por más tiempo.
-[TM5_C]
-¡Vamos a acabar con las Tríadas en Liberty de una vez por todas!
+[MOB45_M]
+Lance, no seas así. Ahora te estoy dando un aviso.
-[TM5_D]
-8-Ball ha instalado una bomba en un camión de la basura.
+[MOB45_N]
+¿Me oyes? Relájate, tómate unos días libres, y luego hablaremos, ¿vale?
-[TM5_E]
-Lleva un temporizador, así que si te despistas, no quedará nada de ti. Ve a por el camión.
+[MOB46_A]
+¡Eh, Tommy! Soy Lance.
-[TM5_F]
-¡Cuidado, 8-Ball dice que es muy sensible y que cualquier golpe puede hacerlo estallar!
+[MOB46_B]
+¿Sí?
-[TM5_G]
-Su piscifactoría abrirá sus puertas a uno de sus camiones, así que podrás entrar sin más.
+[MOB46_C]
+Me alegro tanto de tener noticias tuyas, Lance. Venga, tío, enróllate, enróllate.
-[TM5_H]
-¡Aparca entre los tanques de gas y lárgate de ahí!
+[MOB46_D]
+Estoy ocupado. ¿Qué quieres?
-[TM5_I]
-Quiero que llueva pescado.
+[MOB46_E]
+Nada. Solo llamo para decirte, ya sabes. Mira Tommy, podemos hacer esto.
-[TM5_J]
-En plan bíblico, nada de bajo presupuesto.
+[MOB46_F]
+Tú y yo, sin ningún problema. ¿Sabes lo que quiero decir?
-[FM2]
-'CORTANDO LA HIERBA'
+[MOB46_G]
+Vamos a tener que hacerlo, porque de otro modo, estaremos muertos, Lance.
-[FM4]
-'ÚLTIMA VOLUNTAD'
+[MOB46_H]
+Ya hemos ido demasiado lejos. Pero gracias por llamar. Hablaré contigo más tarde.
-[FM1_A]
-Mis chicos y yo queremos hablar de negocios,
+[MOB_47A]
+Tommy, Lance, tenemos problemas serios. Ven aquí. Enseguida.
-[FM1_B]
-así que esta tarde vas a cuidar de mi chica.
+[MOB52_A]
+Eh, Leo, creo que tengo un comprador para la mercancía de Díaz.
-[FM1_C]
-¡OYE, MARÍA! ¡MUEVE ESE CULO!
+[MOB52_B]
+Tienes que llamarle, tío, montar el trato, ¿sabes?
-[FM1_D]
-La muy idiota siempre hace lo mismo.
+[MOB52_C]
+¿Dónde estás?
-[FM1_E]
-Y aquí está, ¡la primera y única reina de Saba!
+[MOB52_D]
+¿Estás bien, Leo? Te noto un tanto diferente.
-[FM1_F]
-¿Qué hacías arriba?
+[MOB52_E]
+Simplemente dime dónde estás.
-[FM1_G]
-Fuera lo que fuera, seguro que me cuesta dinero.
+[MOB52_F]
+¿Quién demonios eres? ¡Que se ponga Leo!
-[FM1_H]
-Bueno, no pensarás que estoy aquí para conversar, ¿o sí?
+[MOB52_G]
+Leo se ha ido de viaje unos días, me dejó al cargo de todo.
-[FM1_I]
-Métete en el coche y cierra el pico.
+[MOB52_H]
+¡Que te jodan, tío!
-[FM1_J]
-Llévate la limusina, pero devuélvela de una pieza, ¿me has oído?
+[MOB54_A]
+¡Hola, Tommy!
-[FM1_K]
-Y cuidado con ella, es una lianta.
+[MOB54_B]
+Hola, Mercedes, ¿cómo te va?
-[FM1_L]
-¡Sí, sí, sí! Seguro que tu nuevo perrito faldero está pendiente de todo.
+[MOB54_C]
+Tengo un apartamento nuevo en Vice Point,
-[FM1_M]
-¿No es fuerte y grande?
+[MOB54_D]
+pensé que quizás querrías pasarte en algún momento.
-[FM1_N]
-¡Oye, tú, vamos a ver a Chico para que nos dé unas pirulas!
+[MOB54_E]
+Me encantaría. Te veo luego.
-[FM1_P]
-~g~Ése de ahí es Chico, párate cerca.
+[MOB55_A]
+Tommy, soy yo.
-[FM1_S]
-Aquí tienes, señorita.
+[MOB55_B]
+Hola, Mercedes.
-[FM1_TT]
-¡UNA REDADA!
+[MOB55_C]
+Tommy, estoy tan aburrida, ¿cuándo vamos a divertirnos un poco?
-[FM1_1]
-~g~¡Vuelve al Stretch!
+[MOB55_D]
+¿Qué quieres decir?
-[FM1_2]
-~g~¡Entra en el Stretch!
+[MOB55_E]
+Bueno, sé que estás ocupado luchando y matando y sobornando a gente,
-[FM1_3]
-~r~Si abandonas a María, Salvatore hará que te maten. Vuelve a por ella.
+[MOB55_F]
+pero yo sólo quiero divertirme un poco. Así que no te olvides de mí, ¿me oyes?
-[FM1_4]
-~g~¡Has dejado a la chica del Don tirada! ¡Vuelve al almacén y espera a María!
+[MOB56_A]
+Tommy, oí que te cargaste a Ricardo Díaz.
-[FM1_5]
-~g~¡Lleva a María sana y salva con Salvatore!
+[MOB56_B]
+Hubo un desafortunado tiroteo en su mansión.
-[FM1_6]
-~g~¡Chico no estará esperando todo el día, lleva a María al muelle!
+[MOB56_C]
+Creo que se quemó hasta morir en su camisa acrílica.
-[FM1_7]
-~r~¡María está muerta! A Salvatore le va a sentar muy mal...
+[MOB56_D]
+Tommy, estoy tan orgullosa de ti. Sabía que eras un hombre de verdad.
-[FM1_8]
-~r~¡Te cargaste al camello de María!
+[MOB56_E]
+Era un marrano en pantalones, me haces sentir muy orgullosa de ser tu amiga.
-[FM2_J]
-Déjanos a solas un momento.
+[MOB56_F]
+No, sé que vas a estar ocupado intentando tomar las riendas de esta ciudad,
-[FM2_A]
-El cártel colombiano fabrica SPANK en Liberty,
+[MOB56_G]
+pero no te olvides de mí, ¿me oyes?
-[FM2_K]
-pero no sabemos dónde y parece como si supieran qué vamos a hacer antes de que lo pensemos.
+[MOB57_A]
+Soy Mercedes. Ya no te amo, Tommy.
-[FM2_L]
-Hay un tipo llamado Curly Bob que trabaja en el bar de Luigi.
+[MOB57_B]
+Ya no lo hago. De verdad. Porque ya no eres amable con Mercedes.
-[FM2_M]
-Ha estado gastando más dinero del que gana.
+[MOB57_C]
+Ya no la tratas como una dama. Me ignoras y te odio.
-[FM2_N]
-Suele ir del trabajo a casa en taxi, así que síguelo.
+[MOB57_D]
+¡Insisto en que vengas a verme enseguida!
-[FM2_O]
-Y si nos está vendiendo..., mátalo.
+[MOB58_A]
+Tommy.
-[FM2_F]
-Aquí viene nuestro amiguito. El señor Bocón en persona.
+[MOB58_B]
+Hola, Mercedes.
-[FM2_G]
-¿Te han seguido? Ya sabes que esto es nuestro secretito.
+[MOB58_C]
+Hola, tipo duro. Estoy muy enfadada contigo, Tommy.
-[FM2_H]
-No, no, no me han seguido. ¿Tienes lo mío?
+[MOB58_D]
+No me hagas ir nunca más por ahí con Jezz Torrent otra vez.
-[FM2_I]
-Toma tu SPANK, soplón, ahora habla.
+[MOB58_E]
+Es patético. A mitad de camino, empieza a llorar por su perrito
-[FM2_P]
-Vale, los Leone libran una guerra en dos frentes.
+[MOB58_F]
+que murió cuando él tenía siete años y que si su madre nunca le había querido.
-[FM2_Q]
-Tienen una guerra territorial con las Tríadas y no parece que ninguno se vaya a rendir.
+[MOB58_G]
+Y Tommy. En privado lleva peluca y sostén.
-[FM2_R]
-Mientras tanto, Joey Leone ha cabreado a los Forelli.
+[MOB58_H]
+¡No estoy muy contenta contigo!
-[FM2_S]
-Cada día pierden más hombres e influencia.
+[MOB59_A]
+Ooh Tommy, soy Mercedes.
-[FM2_T]
-Salvatore se está volviendo peligroso y paranoico. Sospecha de todos y de todo.
+[MOB59_B]
+Sólo quería decirte que me divertí mucho en el plató de rodaje.
-[FM2_U]
-Con lo leales que son algunos, ¿de qué tendría que preocuparse?
+[MOB59_C]
+Cualquier otra cosa que tengas así, me lo dices.
-[FM2_1]
-~g~¡Ahí está Curly Bob!
+[MOB59_D]
+Lo digo de verdad. Siempre quise ser actriz.
-[FM2_2]
-~g~¡Curly ha salido del club, síguelo!
+[MOB59_E]
+Creo que aprendí mucho sobre el proceso dramático.
-[FM2_5]
-~g~Llévale al puerto de Portland.
+[MOB59_F]
+¡Es tan instructivo! Gracias. Gracias. Hasta muy, muy pronto. Adiós.
-[FM2_6]
-~r~¡Curly no se meterá en un taxi cascado!
+[MOB_99]
+Ve al teléfono público del lugar.
-[FM2_7]
-~r~¡Curly se ha asustado! ¡Han cancelado la reunión!
+[MOB_98]
+Ve al teléfono público del lugar.
-[FM2_8]
-~g~¡Elimina a Curly Bob!
+[MOB_97]
+Ve al teléfono público del lugar.
-[FM2_9]
-~r~¡Curly Bob la ha espichado!
+[MOB_96]
+Ve al teléfono público del lugar.
-[FM2_10]
-~r~¡Curly se ha largado!
+[MOB_95]
+Ve al teléfono público del lugar.
-[FM2_11]
-~g~Aparca enfrente del club de Luigi;Curly Bob saldrá pronto.
+[A_TIME]
++~1~ segundos
-[FM2_12]
-~r~¡Te ha dado esquinazo!
+[DODO_FT]
+¡Volaste durante ~1~ segundos!
-[FM3_A]
-Tenemos que despachar a esos puñeteros colombianos,
+[GA_8]
+Utiliza el detonador para activar la bomba.
-[FM3_B]
-pero mientras estemos en guerra con las Tríadas, no tendremos la fuerza necesaria.
+[GA_10]
+Muy bien. Aquí están tus ~1~ $.
-[FM3_C]
-El cártel tiene fondos ilimitados gracias a esa mierda del SPANK.
+[GA_11]
+Ya tenemos ese coche. ¡No nos sirve!
-[FM3_D]
-Si les atacamos abiertamente, nos harán picadillo.
+[GA_12]
+Bomba activada.
-[FM3_E]
-Estarán fabricando el SPANK en ese barco grande al que te llevó Curly.
+[GA_13]
+Entregado como un profesional. Completa la lista y habrá una bonificación para ti.
-[FM3_F]
-Así que tenemos que actuar con cuidado, o mejor dicho, tú tienes que hacerlo.
+[GA_14]
+Todos los coches. ¡ESTUPENDO! Aquí tienes una cosilla.
-[FM3_G]
-Te estoy pidiendo que destruyas esa fábrica de SPANK como un favor personal para mí, Salvatore Leone.
+[GA_15]
+Espero que te guste el nuevo color.
-[FM3_H]
-Si lo haces, entrarás en la familia. Tendrás todo lo que quieras.
+[GA_16]
+Volver a pintarlo es gratis.
-[FM3_I]
-Ve a ver a 8-Ball, necesitarás su ayuda para volar ese barco.
+[GA_19]
+No estamos interesados en este modelo.
-[FM3_8A]
-¡Hombre, colega! Salvatore me avisó,
+[GA_20]
+Tenemos más de eso de los que podemos colocar. Lo siento, tío, no hay trato.
-[FM3_8B]
-pero este trabajo va a necesitar muchos fuegos artificiales.
+[CHASE]
+Atención de la prensa
-[FM3_8D]
-pero ya sabes que conmigo valdrá la pena.
+[CHASE1]
+Ignorado
-[FM3_8E]
-Venga, ¡vamos allá!
+[CHASE2]
+Aburrido
-[FM3_8F]
-Puedo reventar el barco, pero aún no puedo usar una pipa con estas manos.
+[CHASE3]
+Algo interesante
-[FM3_8G]
-¡Toma, con este fusil podrás reventar unas cuantas cabezas!
+[CHASE4]
+Página 7 del periódico local
-[FM3_4]
-~g~¡Para el coche y deja que 8-Ball salga!
+[CHASE5]
+Portada del periódico local
-[FM3_7]
-~r~¡8-Ball ha pasado a mejor vida!
+[CHASE6]
+Página 2 del Vice Courier
-[FM3_8]
-~r~¡Los guardias han sido alertados!
+[CHASE7]
+Portada del Vice Courier
-[FM4_A]
-¡Mi socio favorito!
+[CHASE8]
+TV Local a las 3 de la mañana
-[FM4_B]
-Estoy orgulloso, hijo, pusiste finos a esos sudacas.
+[CHASE9]
+Noticias locales en TV
-[FM4_C]
-Tengo un trabajito más para ti antes de que podamos celebrarlo.
+[CHASE10]
+Cobertura en directo de la TV Local
-[FM4_D]
-Hay un coche a la vuelta del edificio del club de Luigi.
+[CHASE11]
+Página 12 del UFA Today
-[FM4_E]
-El interior está pringado de sesos.
+[CHASE12]
+Página 4 del UFA Today
-[FM4_F]
-Tuvimos que ayudar a un tipo a que se decidiera y fue un poco... sucio.
+[CHASE13]
+Imagen en UFA Today
-[FM4_H]
-Llévalo a la trituradora antes de que lo encuentre la pasma.
+[CHASE14]
+TV Nacional a las 4 de la mañana
-[AM3]
-'PURGA DEL PAPARAZZI'
+[CHASE15]
+Noticias de la TV Nacional
-[AM4]
-'LA PAGA DE RAY'
+[CHASE16]
+Cobertura en directo de la TV Nacional
-[AM5]
-'TANNER EL TRAIDOR'
+[CHASE17]
+Noticias internacionales
-[AM1_A]
-Tenemos que aclarar ciertos temas antes de seguir con cualquier clase de relación,
+[CHASE18]
+Crisis nacional
-[AM1_B]
-sea de negocios u otra. Pongamos las cartas sobre la mesa.
+[CHASE19]
+Crisis internacional
-[AM1_C]
-Soy yakuza y sé que trabajaste para la familia de Salvatore Leone.
+[CHASE20]
+Acontecimiento mundial
-[AM1_D]
-Puedo darte trabajo en nuestra organización,
+[CHASE21]
+Leyenda
-[AM1_E]
-pero primero debes demostrarme que has cortado todos tus lazos con la mafia.
+[CR_1]
+La grúa no puede levantar este vehículo
-[AM1_G]
-Asegúrate de que no salga con vida.
+[PU_MONY]
+No tienes suficiente dinero.
-[AM1_H]
-Mientras tanto, María y yo nos pondremos al día.
+[CO_ALL]
+Los tienes todos. Aquí tienes una cosilla...
-[AM1_I]
-Uy, Asuka, tienes un masajeador...
+[FEM_ON]
+SÍ
-[AM1_J]
-Eso no es un masajeador.
+[FEM_OFF]
+NO
-[AM1_1]
-~g~¡Salvatore está saliendo del club de Luigi!
+[FEM_YES]
+Sí
-[AM1_2]
-~r~¡Te han descubierto!
+[FEM_NO]
+No
-[AM1_3]
-~r~¡Has perdido a Salvatore!
+[FEM_RET]
+REINTENTAR
-[AM1_4]
-~r~Muy bonito, ¡has asustado al objetivo! ¿Y te consideras un asesino?
+[FEC_NA]
+NO DISPONIBLE
-[AM1_5]
-~g~Ve al barrio rojo y espera a que Salvatore salga del club.
+[FEC_CWL]
+Escoger arma hacia la izquierda
-[AM1_7]
-~r~Salvatore está en su casita, sano y salvo, tomándose un cóctel. ¡Nadie te va a llamar ''Chacal''!
+[FEC_CWR]
+Escoger arma hacia la derecha
-[AM1_8]
-~g~Salvatore saldrá del club de Luigi sobre las ~1~:~1~.
+[FEC_LOF]
+Mirar hacia adelante
-[AM2_4]
-~g~¡Has irrumpido como un elefante en una cacharrería!
+[FEC_TAR]
+Objetivo
-[AM3_A]
-Un periodista ha estado husmeando por aquí.
+[FEC_MOV]
+Movimiento
-[AM3_B]
-María y yo nos hemos ido de vacaciones hasta que puedas librarte de ese mirón pervertido.
+[FEC_CAM]
+Modos de cámara
-[AM4_A]
-¡Si es mi guapo manitas!
+[FEC_PAU]
+Pausa
-[AM4_B]
-María está un poquito liada, pero le diré que has venido.
+[FEC_ENV]
+Entrar en el vehículo
-[AM4_C]
-¿Quién es, Asuka? Sé que he sido muy traviesa, ¡pero necesito mear! ¿Vale?
+[FEC_JUM]
+Saltar
-[AM4_D]
-Es hora de que conozcas a nuestro espía en la policía.
+[FEC_ATT]
+Atacar o disparar arma
-[AM4_E]
-Aquí está su pago por el último trabajito que hizo para nosotros.
+[FEC_RUN]
+Correr
-[AM4_F]
-Él es comprensiblemente cauteloso.
+[FEC_FPC]
+Cámara en primera persona
-[AM4_G]
-Ve a la cabina en Torrington tan rápido como puedas y espera sus instrucciones.
+[FEC_LL]
+Mirar a la izquierda
-[AM5_A]
-María y yo hemos ido de compras.
+[FEC_LB]
+Retrovisor
-[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_LR]
+Mirar a la derecha
-[AM5_C]
-Sin un coche es prácticamente un inútil, así que le hemos puesto un localizador.
+[FEC_ABR]
+Acelerar, frenar o dar marcha atrás
-[AM5_D]
-¡Haz que sufra!
+[FEC_HOR]
+Bocina
-[AM5_1]
-¡Tanner te ha pillado!
+[FEC_VES]
+Control del vehículo
-[AS1]
-'CEBO'
+[FEC_BRA]
+Freno o marcha atrás
-[AS2]
-'CAFÉ PARA LLEVAR'
+[FEC_HAB]
+Freno de mano
-[AS4]
-'RESCATE'
+[FEC_CAW]
+Arma del vehículo
-[AS1_A]
-Parece que Miguel piensa que le maltrato.
+[FEC_ACC]
+Acelerar
-[AS1_B]
-Pero ha revelado cuánto teme Catalina tu búsqueda de venganza.
+[FEC_CCF]
+Configuración:
-[AS2_A]
-Subestimamos los planes que tiene Catalina para el SPANK.
+[FEC_CF1]
+Configuración 1
-[AS2_B]
-Va mucho más allá de hacer que los jamaicanos lo vendan en las esquinas.
+[FEC_CF2]
+Configuración 2
-[AS2_D]
-Vende SPANK en puestos callejeros.
+[FEC_CF3]
+Configuración 3
-[AS2_1]
-~g~¡Todos los puestos de café en Portland han sido destruidos!
+[FEC_CF4]
+Configuración 4
-[AS2_2]
-~g~¡Todos los puestos de café en Staunton Island han sido destruidos!
+[FEC_CDP]
+Pantalla del mando
-[AS2_3]
-~g~¡Todos los puestos de café en Shoreside Vale han sido destruidos!
+[FEC_ONF]
+A pie
-[AS2_4]
-~r~¡El cártel ha avisado a sus camellos!
+[FEC_INC]
+En coche
-[AS2_5]
-~g~¡Todavía hay puestos de café en Shoreside Vale y en Staunton Island!
+[FEC_VIB]
+Vibración :
-[AS2_6]
-~g~¡Todavía hay puestos de café en Shoreside Vale!
+[FEL_ENG]
+Inglés
-[AS2_7]
-~g~¡Todavía hay puestos de café en Staunton Island!
+[FEL_FRE]
+Francés
-[AS2_8]
-~g~¡Todavía hay puestos de café en Portland!
+[FEL_GER]
+Alemán
-[AS2_9]
-~g~¡Todavía hay puestos de café en Portland y en Shoreside Vale!
+[FEL_ITA]
+Italiano
-[AS2_10]
-~g~¡Todavía hay puestos de café en Portland y en Staunton Island!
+[FEL_SPA]
+Español
-[AS2_12]
-~g~¡Recorre los distritos de Liberty y busca puestos de café ~b~Espresso-2-Go~g~!
+[FED_DBG]
+Menú de soluciones técnicas
-[AS3_A]
-¿Lo apretamos un poco más o esperamos a que se vuelva negro y se caiga?
+[FED_RID]
+Recargar IDE
-[AS3_B]
-Dale un toque rápido...
+[FED_RIP]
+Recargar IPL
-[AS3_D]
-¡Mi manitas!
+[FED_PAH]
+Parse Heap
-[AS3_E]
-Me aburría, así que vine a hacer compañía a Asuka.
+[FED_DFL]
+CLos guiones::DbgBandera
-[AS3_1]
-~g~¡Busca una ~r~lancha~g~ y ve a la ~b~boya señalada~g~!
+[FED_DLS]
+Gran luz blanca de solución técnica encendida
-[AS3_3]
-~g~¡Espera a que la ~y~avioneta~g~ comience a acercarse!
+[FED_SPR]
+Mostrar grupos de aceras
-[AS3_5]
-~g~¡Recupera el cargamento!
+[FED_SCR]
+Mostrar grupos de carreteras
-[AS3_4]
-~g~¡Usa un lanzacohetes para derribar ~y~la avioneta~g~!
+[FED_SCZ]
+Mostrar zonas de desechos
-[AS3_2]
-~b~¡Ve a la boya del aeropuerto señalada! ~y~¡El avión se está acercando!
+[FED_DSR]
+Solicitud de solución técnica del streaming
-[AS3_6]
-~g~~1~ DE 8
+[FED_SCP]
+gbMostrarcolisiónPolys
-[KM1]
-'LA FUGA DEL KANBU'
+[PL_STAT]
+Estadísticas del jugador
-[KM3]
-'UN MAL TRATO'
+[PE_WAST]
+Gente que te has cargado
-[KM4]
-'SHIMA'
+[PE_WSOT]
+Gente eliminada por otros
-[KM5]
-'CONTRINCANTES TRAFICANTES'
+[TM_BUST]
+Veces detenido
-[KM1_A]
-Mi hermana te tiene en gran estima,
+[GNG_WST]
+Miembros de la banda liquidados
-[KM1_E]
-pero yo no estoy convencido de que un gaijin pueda ofrecerme algo más que desilusiones.
+[DED_CRI]
+Criminales liquidados
-[KM1_B]
-Tal vez puedas ayudar con una situación que me perjudica.
+[PER_COM]
+Porcentaje completado
-[KM1_F]
-Por supuesto, el fracaso conllevará una desgracia.
+[KGS_EXP]
+Kilogramos de explosivos empleados
-[KM1_C]
-Un kanbu, o jefe de la yakuza, está bajo custodia a la espera de juicio.
+[ACCURA]
+Precisión
-[KM1_G]
-Es un miembro importante de la familia.
+[ST_WEAP]
+Presupuesto armamentístico
-[KM1_H]
-Libéralo y llévalo al dojo de Bedford Point.
+[ST_PROP]
+Presupuesto de propiedades
-[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_AUTO]
+Presupuesto para reparación de coches y pintura
-[KM1_1]
-~g~¡Roba un coche de la policía!
+[ST_PHOT]
+Fotografías tomadas
-[KM1_2]
-~g~¡Instala una bomba en el coche!
+[ST_LOAN]
+Visitas de usureros prestamistas
-[KM1_3]
-~g~Ahora llévalo al dojo de la yakuza.
+[ST_STOR]
+Almacenes desvalijados
-[KM1_5]
-~g~Ahora ve a la comisaría.
+[ST_MOVI]
+Escenas de especialista
-[KM1_6]
-~g~¡Pon una bomba en el coche!
+[ST_PIZZ]
+Pizzas entregadas
-[KM1_7]
-~g~¡Sólo pueden entrar vehículos de policía autorizados!
+[ST_GARB]
+Recogidas de basura efectuadas
-[KM1_9]
-~r~No destruiste la pared con un coche bomba.
+[ST_ICEC]
+''Helado'' vendido
-[KM1_10]
-~r~El kanbu está muerto, ¡y tu honor también!
+[TOP_SHO]
+Puntuación máxima en el campo de tiro
-[KM1_11]
-~r~¡La policía te ha seguido!
+[SHO_RAN]
+Clasificación del campo de tiro
-[KM2_A]
-Es imposible sobreestimar la importancia del protocolo en este trabajo.
+[SEAGULL]
+Gaviotas disparadas
-[KM2_B]
-Para mi vergüenza eterna, un hombre me hizo una vez un favor y nunca pude corresponder su amabilidad.
+[PROPOWN]
+Propiedad en posesión
-[KM2_C]
-Su debilidad son los coches y nos ha pedido que adquiramos ciertos modelos para su colección.
+[ST_TIME]
+Tiempo de juego
-[KM2_F]
-Mi honor lo exige.
+[ST_FTIM]
+Horas de vuelo
-[KM2_2]
-~g~Coche entregado.
+[ST_PRAN]
+Clasificación de los pilotos
-[KM3_A]
-Cuando los problemas acechan, el tonto les da la espalda, mientras que el sabio los enfrenta.
+[ST_RAN0]
+Aprendiz
-[KM3_B]
-El cártel colombiano ha ignorado nuestras repetidas peticiones de que dejen en paz nuestros intereses en Liberty.
+[ST_RAN1]
+Navegante
-[KM3_C]
-Ahora están negociando con los jamaicanos para humillarnos aún más.
+[ST_RAN2]
+Copiloto
-[KM3_D]
-Están cerrando un trato en la ciudad.
+[ST_RAN3]
+Junior
-[KM3_F]
-Llévate a uno de mis hombres, roba un coche de los jamaicanos y presenta tus respetos a los colombianos.
+[ST_RAN4]
+Competente
-[KM3_E]
-¡Nuestro honor exige que no dejes a nadie vivo!
+[ST_RAN5]
+Senior
-[KM3_2]
-~g~Recoge a tu contacto.
+[ST_RAN6]
+As
-[KM3_3]
-~g~¡La reunión está teniendo lugar en el aparcamiento del hospital de Rockford!
+[ST_RAN7]
+Barón rojo
-[KM3_4]
-~r~¡Han escapado!
+[ST_DRWN]
+Peces alimentados
-[KM3_6]
-~g~¡Mátalos, mátalos a todos!
+[ST_FASH]
+Presupuesto para moda
-[KM3_8]
-~g~¡Necesitas un coche de los jamaicanos para este trabajo!
+[ST_DAMA]
+Coste de propiedades destruidas
-[KM3_9]
-~r~Uno de los colombianos ha muerto, se ha cancelado el trato.
+[TM_DED]
+Visitas al hospital
-[KM3_10]
-~r~¡El contacto está muerto!
+[DAYSPS]
+Días transcurridos en el juego
-[KM4_A]
-Para ser verdaderamente fuerte, es importante no mostrar debilidad.
+[NUMSHV]
+Visitas a pisos francos
-[KM4_C]
-Hazte con el dinero inmediatamente para que podamos ingresarlo en las cuentas del casino.
+[MXCARD]
+Max. Distancia de salto LOCO (pies)
-[KM4_1]
-¡Ni puedo pagarte, ni lo haría aunque pudiera!
+[MXCARJ]
+Max. Altura de salto LOCO (pies)
-[KM4_9]
-¡Una banda de chavales acaba de arrasar el local! ¡Se han llevado todo!
+[MXCARDM]
+Máxima distancia de salto LOCO (m)
-[KM4_2]
-¡Sois inútiles!
+[MXCARJM]
+Máxima altura de salto LOCO (m)
-[KM4_10]
-Además, ¿qué clase de yakuza eres tú?
+[MXFLIP]
+Máximas vueltas de salto LOCO
-{ Unused string? }
+[MXJUMP]
+Máxima rotación de salto LOCO
-[KM4_3]
-No pago a matones como vosotros para esto. Si quisiera esta clase de protección, llamaría a la policía, demonios.
+[BUL_FIR]
+Balas disparadas
-[KM4_4]
-~g~¡Castiga a la banda responsable y recupera el ~b~dinero de la protección~g~!
+[BUL_HIT]
+Aciertos
-[KM4_7]
-~r~¡El tendero la acaba de palmar!
+[SPRAYIN]
+Pintura
-[KM4_5]
-Donald Love desea que te pases por su terraza para tener una charla.
+[BSTSTU]
+Mejor maniobra LOCA hasta ahora
-[KM4_6]
-¡Aquí está todo el dinero!
+[INSTUN]
+Maniobra loca
-[KM4_8]
-~g~¡Maletín conseguido!
+[PRINST]
+Maniobra loca perfecta
-[KM5_A]
-¡Tú! ¡Qué oportuno por tu parte que muestres ahora tu despreciable cara!
+[DBINST]
+Maniobra loca doble
-[KM5_B]
-¡Parece que tu ataque para disuadir a los jamaicanos
+[DBPINS]
+Maniobra loca doble perfecta
-[KM5_B1]
-de convertirse en aliados del cártel ha sido completamente inútil!
+[TRINST]
+Maniobra loca triple
-[KM5_C]
-¡Los traficantes jamaicanos están vendiendo SPANK por las calles de Liberty como si fueran perritos calientes!
+[PRTRST]
+Maniobra loca triple perfecta
-[KM5_D]
-Estos cerdos del cártel se están riendo de nosotros, ¡de mí!
+[QUINST]
+Maniobra loca cuádruple
-[KM5_E]
-¡Te daré una última oportunidad para demostrar que la fe que tiene mi hermana en ti está justificada!
+[PQUINS]
+Maniobra loca cuádruple perfecta
-[KM5_F]
-¡Aplasta a estos canallas y lava tu vergüenza en el río de la sangre de nuestros enemigos!
+[NOSTUC]
+No se ha completado ninguna
-[KM5_3]
-~r~No has matado a ~1~ jamaicanos.
+[NOUNIF]
+Saltos únicos completados
-[KM5_4]
-~g~Enhorabuena, has matado a ~1~ jamaicanos.
+[NMISON]
+Intentos de misión
-[KM5_5]
-~g~Enhorabuena, has matado a ~1~ jamaicanos. PREMIO DE ~1~ $
+[PASDRO]
+Pasajeros en destino
-[RM1]
-'SILENCIA AL SOPLÓN'
+[MONTAX]
+Dinero conseguido con el taxi
-[RM3]
-'FALTA DE PRUEBAS'
+[DAYPLC]
+Gastos diarios provocados a la policía
-[RM4]
-'DE PESCA'
+[CRIMRA]
+Tasa criminal:
-[RM5]
-'DESESCAYOLADOR'
+[STPR_1]
+El Malibú
-[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_2]
+Imprenta
-[RM1_E]
-Quema el lugar, así saldrán y podrás cazarlos. Asegúrate de que no hable con nadie.
+[STPR_3]
+Estudio de cine
-[RM1_1]
-~g~Ve a la casa de protección de testigos.
+[STPR_4]
+Fábrica de helados
-[RM1_2]
-~g~¡Cárgate a McAffrey!
+[STPR_5]
+Salón de coches
-[RM2_A1]
-¡Chico, estoy aquí!
+[STPR_6]
+Compañía de taxis
-[RM2_A]
-Un viejo colega del ejército tiene un negocio en Rockford.
+[STPR_7]
+Astillero
-[RM2_D]
-Necesitará refuerzos y a cambio te venderá todo su material a precios de ganga.
+[SET1EN]
+Configuración 1. Activada
-[RM2_E]
-Ray me avisó... Pero pensé que vendría más gente.
+[GMSAVE]
+Guardar partida
-[RM2_F]
-Bueno, tres brazos son mejor que uno, así que sírvete.
+[FEDS_TB]
+Volver
-[RM2_G]
-~g~¡Ve a ver a Phil!
+[FEST_OO]
+de
-[RM2_H]
-~r~¡Phil ha muerto!
+[FEC_TUC]
+Control de la torreta
-[RM2_L]
-¡Caray! ¡Si hubieras estado a mi lado en Nicaragua, a lo mejor conservaría el brazo!
+[FEC_RS3]
+Cambiar emisora de radio (Botón L3)
-[RM2_N]
-Deja el dinero en el suelo. Ahora vete, ya me ocupo yo de la poli.
+[FEC_HO3]
+Bocina (Botón L3)
-[RM3_D]
-Están transportando las pruebas por la ciudad.
+[C_FAIL]
+¡Misión de justiciero terminada!
-[RM3_E]
-Tendrás que embestir al coche y recoger hasta la última prueba que se le caiga.
+[C_ESCP]
+~r~¡El sospechoso ha escapado!
-[RM3_F]
-En cuanto tengas todas, déjalas en tu coche y préndele fuego.
+[C_VIGIL]
+¡BONIFICACIÓN DE JUSTICIERO!
-[RM3_G]
-Cuando acabes, nos irá mucho mejor, chico.
+[HEAL_A]
+Tu ~h~salud~w~ aparece en naranja en la parte superior derecha de la pantalla.
-[RM3_1]
-~g~Deja las pruebas en un coche y después préndele fuego.
+[WRONGCD]
+Disco incorrecto. Introduce el disco correcto.
-[RM3_4]
-~g~¡Al fiscal se le ha caído una prueba!
+[NOCD]
+La bandeja del disco está vacía. Por favor, inserta el disco.
-[RM3_6]
-~r~¡Las fotos circularán por toda la ciudad!
+[OPENCD]
+La bandeja del disco está abierta. Por favor, cierra la bandeja de disco.
-[RM3_7]
-~g~¡Ahora préndele fuego al coche!
+[CDERROR]
+Error al leer el DVD de Grand Theft Auto: Vice City
-[RM4_A]
-Creo que mi socio es un soplón.
+[RESTART]
+Iniciando nueva partida
-[RM4_C]
-Casi todas las noches sale a pescar con su lancha cerca del faro que hay en Portland Rock.
+[GA_3]
+No hay más regalitos. ¡100 $ para volver a pintar!
-[RM4_D]
-¡Roba una lancha de la policía y húndele las ganas de dar puñaladas traperas!
+[GA_1]
+¡Hala! ¡Demasiado peligroso para mi gusto!
-[RM4_1]
-~g~Roba una lancha de la policía.
+[GA_1A]
+Vuelve cuando no estés tan ocupado...
-[RM4_2]
-~g~¡Ve al faro y despacha al socio de Ray!
+[HELP9_C]
+Pulsa ~h~~k~~k~~PED_FIREWEAPON~~w~para ~h~disparar~w~ el fusil de francotirador.
-[RM5_A]
-¡Inútil de mierda!
+[TAXI2]
+~r~¡Te has quedado sin tiempo!
-[RM5_A1]
-¡La has cagado! Me la estoy jugando y ni siquiera eres capaz de matar a una maldita mosca.
+[PAGEB13]
+Salud entregada en el escondite
-[RM5_B]
-¡Te pagué una pasta para matar al testigo y aún sigue vivo!
+[PAGEB14]
+Adrenalina entregada en el escondite
-[RM5_B1]
-¡Y hoy va a declarar ante los federales!
+[FESZ_CA]
+Cancelar
-[RM5_C]
-Está a punto de ser trasladado del hospital general Carson, en Rockford.
+[FES_NGA]
+Nueva partida
-[RM5_D]
-¡Si él canta, yo canto!
+[FES_CAN]
+Cancelar
-[RM5_E]
-¡Así que termina el trabajo por el que te pagué!
+[FESZ_QL]
+Todo el progreso no guardado de tu partida actual se perderá. ¿Continuar cargando?
-[RM5_1]
-~g~Intercepta la ambulancia.
+[FESZ_QD]
+¿Proceder a borrar esta partida guardada?
-[RM5_2]
-~g~¡Te han descubierto!
+[FESZ_QO]
+¿Proceder para sobrescribir esta partida guardada?
-[RM5_3]
-~g~¡Era un señuelo!
+[FESZ_QR]
+¿Seguro que quieres empezar una nueva partida? Todo el progreso desde la última partida guardada se perderá. ¿Continuar?
-[RM5_4]
-~g~¡Las balas no atraviesan esa escayola de cuerpo entero!
+[T4X4_1]
+Prueba de PCJ
-[RM5_5]
-~g~¡Esa escayola de cuerpo entero es ignífugo!
+[BMX_1]
+Trial de tierra
-[RM5_7]
-~r~¡El testigo está a salvo!
+[BMX_2]
+Pista de pruebas
-[RM5_8]
-~g~¡El testigo se ha ahogado!
+[BMXFAIL]
+~r~¡No has conseguido un nuevo récord!
-[LOVE2]
-'¡EXTERMINA AL WAKA-GASHIRA!'
+[BMX_REC]
+~g~¡Nuevo récord establecido: ~1~!
-[LOVE3]
-'UNA GOTA EN EL OCÉANO'
+[T4X4_3]
+¡AGARRADO!
-[LOVE1_A]
-Antes que nada, permíteme agradecerte que te hayas ocupado de ese asunto personal.
+[MM_1]
+CONOCIRCUITO
-[LOVE1_F]
-Últimamente la gente tiende a malinterpretar las cosas.
+[T4X4_F]
+~r~¡Te rajaste! ¿Demasiado duro para ti?
-[LOVE1_D]
-Pretenden exigirme más de lo pactado, pero no me gusta renegociar.
+[LANDSTK]
+Landstalker
-[LOVE1_E]
-Un trato es un trato, así que no van a ver ni un dólar mío.
+[IDAHO]
+Idaho
-[LOVE1_G]
-Rescata a mi amigo cueste lo que cueste.
+[STINGER]
+Stinger
-[LOVE1_2]
-~g~Rescata al anciano oriental.
+[LINERUN]
+Linerunner
-[LOVE1_3]
-~g~Lleva al anciano oriental de vuelta al edificio de Donald Love.
+[PEREN]
+Perennial
-[LOVE1_4]
-~g~El anciano oriental debe estar detrás de alguna de estas puertas...
+[SENTINL]
+Sentinel
-[LOVE1_6]
-~r~¡Las tripas del anciano oriental están desparramadas por las calles!
+[RIO]
+Río
-[LOVE1_7]
-~g~La puerta sólo se abrirá ante un coche de los colombianos.
+[PATRIOT]
+Patriot
-[LOVE2_A]
-No hay nada como una clásica guerra de bandas para hacer que bajen los precios de los bienes inmuebles,
+[FIRETRK]
+Camión de bomberos
-[LOVE2_B]
-excepto una plaga... pero eso sería excesivo en este caso.
+[TRASHM]
+Trashmaster
-[LOVE2_C]
-He observado que la yakuza y los colombianos no son precisamente buenos amigos.
+[STRETCH]
+Limusina
-[LOVE2_D]
-Vamos a aprovechar esta oportunidad de negocio.
+[MANANA]
+Mañana
-[LOVE2_E]
-Quiero que mates a Kenji Kasen, el waka-gashira (segundo al mando) de la yakuza.
+[INFERNS]
+Infernus
-[LOVE2_F]
-Kenji está asistiendo a una reunión en lo alto del aparcamiento de Newport.
+[VOODOO]
+Voodoo
-[LOVE2_G]
-¡Hazte con un coche de la banda del cártel y elimínalo!
+[PONY]
+Pony
-[LOVE2_H]
-La yakuza debe culpar al cártel de esta declaración de guerra.
+[MULE]
+Mule
-[LOVE2_1]
-~g~¡Ve a Fort Staunton y roba un coche de la banda de los colombianos!
+[CHEETAH]
+Cheetah
-[LOVE2_2]
-~g~¡Ahora ve al ~p~aparcamiento de Newport~g~ y cárgate a Kenji!
+[AMBULAN]
+Ambulancia
-[LOVE2_3]
-~r~¡Si no llevas un coche del cártel, te descubrirán!
+[FBICAR]
+FBI Washington
-[LOVE2_4]
-~r~¡La yakuza te ha reconocido!
+[MOONBM]
+Moonbeam
-[LOVE2_6]
-~r~¡Has matado a todos los testigos!
+[ESPERAN]
+Esperanto
-[LOVE3_A]
-En estos días de hipocresía moral, ciertos artículos pueden resultar difíciles de importar.
+[TAXI]
+Taxi
-[LOVE3_C]
-Echará varios paquetes al agua.
+[WASHING]
+Washington
-[LOVE3_D]
-Asegúrate de los consigues antes que nadie.
+[BOBCAT]
+Bobcat
-[LOVE3_1]
-~g~¡Consigue una ~r~lancha~g~ y sigue a la ~y~avioneta~g~!
+[WHOOPEE]
+Mr Whoopee
-[LOVE4]
-'ROBO DE ALTOS VUELOS'
+[BFINJC]
+BF Injection
-[LOVE5]
-'SERVICIO DE ESCOLTA'
+[HUNTER]
+Hunter
-[LOVE4_A]
-Gracias por conseguir esos paquetes, pero sólo eran un señuelo.
+[POLICAR]
+Policía
-[LOVE4_B]
-Lo siento, pero a veces los negocios son así.
+[ENFORCR]
+Enforcer
-[LOVE4_C]
-Mi verdadero objetivo se ocultaba en la avioneta.
+[SECURI]
+Securicar
-[LOVE4_F]
-He sobornado a los funcionarios.
+[BANSHEE]
+Banshee
-[LOVE4_1]
-~r~¡El cártel colombiano está aquí!
+[PREDATR]
+Predator
-[LOVE4_2]
-~g~¡El paquete ha desparecido! Síguele la pista a los colombianos y recupéralo.
+[BUS]
+Autobús
-[LOVE4_3]
-~g~¿''Panlantic Construction''...?
+[RHINO]
+Rhino
-[LOVE4_5]
-~g~El paquete debería estar en la avioneta...
+[BARRCKS]
+Barracks OL
-[LOVE4_6]
-~g~¡Usa el ascensor!
+[CUBAN]
+Cuban Hermes
-[LOVE5_B]
-Mi amigo oriental necesita que le escolten mientras comprueba la autenticidad de mi última adquisición.
+[HELI]
+Helicóptero
-[LOVE5_1]
-~g~¡En marcha!
+[DODO]
+Dodo
-[LOVE5_2]
-~g~¡Necesitas un coche!
+[COACH]
+Autocar
-[LOVE5_3]
-~g~¡Comprueba la salida del túnel!
+[CABBIE]
+Taxi clásico
-[LOVE5_4]
-~r~¡Protege el camión!
+[STALION]
+Stallion
-[RM6]
-'HOMBRE MUERTO'
+[RUMPO]
+Rumpo
-[RM6_A]
-¿No te han seguido? Bien.
+[RCBANDT]
+Bandit RC
-[RM6_B]
-Se acabó, ¡esto se me va de las manos y estoy con la soga al cuello!
+[ROMERO]
+Romero's Hearse
-[RM6_D]
-Soy hombre muerto, así que tengo que largarme.
+[PACKER]
+Packer
-[RM6_E]
-¡Consigue que no pierda mi vuelo en el aeropuerto y haré que tu trabajo haya merecido la pena!
+[ADMIRAL]
+Admiral
-[RM6_666]
-Cuida mi Patriot a prueba de balas. Nos vemos en Miami, Ray
+[SQUALO]
+Squalo
-[CAT1]
-'RESCATE'
+[SEASPAR]
+Sea Sparrow
-[CAT2]
-'EL INTERCAMBIO'
+[PIZZABO]
+Pizza Boy
-[CAT1_A]
-Tengo a tu linda María. Si no quieres que parezca que un carnicero se ensañó con ella,
+[GANGBUR]
+Gang Burrito
-{ UNUSED DUPLICATE }
+[TROPIC]
+Tropic
-[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!
+[SPEEDER]
+Speeder
-{ UNUSED DUPLICATE }
+[REEFER]
+Reefer
-[CAT2_G]
-Estaba muerta de miedo, pero luego me dije a mí misma: ''Ya eres mayorcita''.
+[FLATBED]
+Flatbed
-{ UNUSED DUPLICATE }
+[YANKEE]
+Yankee
-[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,
+[CADDY]
+Caddy
-{ UNUSED DUPLICATE }
+[ZEBRA]
+Taxi cebra
-[CAT2_I]
-porque su marido a vuelto a enredar por ahí y...
+[TOPFUN]
+Top Fun
-[CAT1_F]
-¡Ve a donde está Catalina antes de que se acabe el tiempo!
+[SKIMMER]
+Skimmer
-[CAT_MON]
-~g~Todavía te falta dinero. Necesitas 500.000 dólares.
+[PCJ600]
+PCJ 600
-[BITCH_D]
-~g~¡María está muerta!
+[PHOENIX]
+Phoenix
-[WEATHER]
-FORZAR EL CLIMA
+[FAGGIO]
+Faggio
-[WEATHE2]
-CLIMA NORMAL
+[FREEWAY]
+Freeway
-[8001]
-¡Has fallado miserablemente!
+[RCBARON]
+Barón RC
-[1000]
-HAS MUERTO
+[RCRAIDE]
+Raider RC
-[1001]
-HAS MUERTO
+[GLENDAL]
+Glendale
-[1002]
-HAS MUERTO
+[OCEANIC]
+Oceanic
-[1003]
-HAS MUERTO
+[SANCHEZ]
+Sanchez
-[1004]
-HAS MUERTO
+[SPARROW]
+Sparrow
-[1005]
-TRINCADO
+[LOVEFIS]
+Love Fist
-[1006]
-TRINCADO
+[COASTG]
+Guardacostas
-[1007]
-TRINCADO
+[DINGHY]
+Dinghy
-[1008]
-TRINCADO
+[HERMES]
+Hermes
-[1009]
-TRINCADO
+[SABRE]
+Sabre
-[GA_4]
-Una bomba de coche vale 1.000 dólares.
+[SABRETU]
+Sabre Turbo
-[GA_5]
-Tu coche ya tiene una bomba instalada.
+[WALTON]
+Walton
-[GA_6]
-¡Apárcalo, actívala pulsando ~h~~k~~PED_FIREWEAPON~~w~ y SAL PITANDO!
+[REGINA]
+Regina
-[GA_7]
-Activa la bomba pulsando ~h~~k~~PED_FIREWEAPON~~w~. Estallará cuando se arranque el motor.
+[COMET]
+Comet
-[GA_8]
-Utiliza el detonador para activar la bomba.
+[DELUXO]
+Deluxo
-[GA_9]
-Ha conseguido ~1~ de los 10 coches especiales.
+[BURRITO]
+Burrito
-[GA_10]
-Buen trabajo. Aquí tienes tus ~1~ dólares.
+[SPAND]
+Spand Express
-[GA_11]
-Ya tenemos este modelo. ¡No nos sirve para nada!
+[MARQUIS]
+Marquis
-[GA_12]
-Bomba armada
+[BAGGAGE]
+Mozo de equipaje
-[GA_13]
-Eres todo un profesional. Completa la lista y conseguirás una recompensa.
+[KAUFMAN]
+Taxi Kaufman
-[GA_14]
-Ya están todos los coches. ¡Estupendo! Toma un detallito.
+[COASTMA]
+Guardacostas Maverick
-[GA_15]
-Espero que te guste el nuevo color.
+[MAVERIC]
+Maverick
-[GA_16]
-Esta mano de pintura es gratuita.
+[RANCHER]
+Rancher
-[GA_19]
-No nos interesa ese modelo.
+[FBIRANC]
+FBI Rancher
-[GA_20]
-Tenemos de esos más de los que necesitamos. Lo siento, tío, no hay trato.
+[VIRGO]
+Virgo
-[CR_1]
-La grúa no puede levantar este vehículo.
+[GREENWO]
+Greenwood
-[PU_MONY]
-No tienes suficiente dinero.
+[HOTRING]
+Hotring Racer
-[CO_ALL]
-Te has hecho con todos. Toma un detallito...
+[BLISTAC]
+Blista Compact
-[PAUSED]
-PARTIDA EN PAUSA
+[FEST_DF]
+Dist. recorrida a pie (millas)
-[HEALTH1]
-¡Largo! Estás completamente sano.
+[FEST_DC]
+Dist. recorrida en coche (millas)
-[HEALTH2]
-La sanidad cuesta dinero.
+[FESTDFM]
+Distancia recorrida a pie (m)
-[HEALTH3]
-Te pondré como nuevo.
+[FESTDCM]
+Distancia recorrida en coche (m)
-[HEALTH4]
-Te va a costar 250 $.
+[TOT_DIS]
+Distancia total recorrida (millas)
-[FEB_STA]
-Estadísticas
+[TOTDISM]
+Distancia total recorrida (m)
-[FEB_BRI]
-Resumen
+[DISTHEL]
+Dist. recorrida en helicóptero (millas)
-[FEB_CON]
-Controles
+[DISTHEM]
+Distancia recorrida en helicóptero (m)
-[FEB_AUD]
-Sonido
+[DISTBOA]
+Dist. recorrida en barco (millas)
-[FEB_DIS]
-Pantalla
+[DISTBOM]
+Distancia recorrida en barco (m)
-[FEB_LAN]
-Idioma
+[FEST_LS]
+Gente salvada en una ambulancia
-[FEP_STA]
-ESTADÍSTICAS
+[FEST_CC]
+Criminales asesinados en misión Vigilante
-[FEP_BRI]
-RESUMEN
+[FEST_FE]
+Total de fuegos extinguidos
-[FEP_CON]
-CONTROLES
+[FEST_RP]
+Masacres superadas
-[FEP_AUD]
-SONIDO
+[FEST_MP]
+Misiones superadas
-[FEP_DIS]
-PANTALLA
+[FEST_BB]
+Bling-bling Scramble:
-[FEP_LAN]
-IDIOMA
+[FEST_H0]
+Mayoría de puntos de control
-[FEF_ST1]
-¿Quién es el malo?
+[FEST_GC]
+Total de coches de bandas:
-[FEF_ST2]
-Cuánta destrucción has producido
+[FEST_H1]
+Destrucción del diablo
-[FEF_BR1]
-¿Has perdido el hilo?
+[FEST_H2]
+Masacre de la mafia
-[FEF_CO1]
-¿Necesitas más control?
+[FEST_H3]
+Casino Calamity
-[FEF_CO2]
-Elige la mejor configuración del mando para tu estilo de juego
+[FEST_H4]
+Rumpo Wrecker
-[FEF_SA1]
-¡Mantén tu sitio en el bloque!
+[USJ]
+¡BONIFICACIÓN POR MANIOBRA ÚNICA!
-[FEF_SA2]
-Guarda y carga tus partidas
+[USJ_DUN]
+MANIOBRA YA COMPLETADA
-[FEF_AU1]
-¡Dale candela al volumen!
+[RATNG1]
+Ciudadano honrado
-[FEF_AU2]
-Elige una emisora de radio y un efecto de sonido
+[RATNG2]
+Nadie en especial
-[FEF_DI1]
-¡Cambia el juego!
+[RATNG3]
+Basurero
-[FEF_DI2]
-Personaliza el juego para tu televisión
+[RATNG4]
+Cleptómano
-[FEF_LA1]
-¿Qué dices de los Willis?
+[RATNG5]
+Vándalo
-[FEF_LA2]
-Elige tu idioma preferido
+[RATNG6]
+Chico de los recados
-[FEB_PMB]
-Resumen de la última misión:
+[RATNG7]
+Carterista
-[FEC_NA]
-No disponible
+[RATNG8]
+Cleptómano
-[FEC_CWL]
-Siguiente arma
+[RATNG9]
+Chivato
-[FEC_CWR]
-Arma anterior
+[RATNG10]
+Rata
-[FEC_LOF]
-Mirar hacia delante
+[RATNG11]
+Lince
-{ !!!!!!!!!!!!!!!!!! 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
+[RATNG12]
+Estafador
-[FEC_MOV]
-Movimiento
+[RATNG13]
+Timador
-[FEC_CAM]
-Cambiar cámara
+[RATNG14]
+Corredor de apuestas
-[FEC_PAU]
-Pausa
+[RATNG15]
+Buscavidas
-[FEC_ENV]
-Entrar en vehículo
+[RATNG16]
+Matón
-[FEC_JUM]
-Saltar
+[RATNG17]
+Chusma
-[FEC_ATT]
-Atacar o disparar
+[RATNG18]
+Bribón
-[FEC_RUN]
-Correr
+[RATNG19]
+Rufián
-[FEC_FPC]
-Cámara en primera persona
+[RATNG20]
+Proscrito
-[FEC_LL]
-Mirar a la izquierda
+[RATNG21]
+Malhechor
-[FEC_LB1]
-Mirar
+[RATNG22]
+Asesino
-[FEC_LB2]
-atrás
+[RATNG23]
+Super matón
-[FEC_LB]
-Mirar atrás
+[RATNG24]
+Matón
-[FEC_LR]
-Mirar a la derecha
+[RATNG25]
+Presidiario
-[FEC_HOR]
-Claxon
+[RATNG26]
+Exconvicto
-[FEC_VES]
-Controlar vehículo
+[RATNG27]
+Criminal
-[FEC_RSC]
-Cambiar emisora de radio
+[RATNG28]
+Saqueador
-[FEC_BRA]
-Freno o marcha atrás
+[RATNG29]
+Mafioso
-[FEC_HAB]
-Freno de mano
+[RATNG30]
+Conductor
-[FEC_CAW]
-Arma del vehículo
+[RATNG31]
+Gorila
-[FEC_ACC]
-Acelerar
+[RATNG32]
+Asesino profesional
-[FEC_SMT]
-Activar misión especial
+[RATNG33]
+Asuntos internos
-[FEC_CCF]
-Configuración:
+[RATNG34]
+Agente
-[FEC_CF1]
-Ajuste1
+[RATNG35]
+Ronin
-[FEC_CF2]
-Ajuste2
+[RATNG36]
+Manitas
-[FEC_CF3]
-Ajuste3
+[RATNG37]
+Asesino a sueldo
-[FEC_CF4]
-Ajuste4
+[RATNG38]
+Asociado
-[FEC_CDP]
-Controles a mostrar:
+[RATNG39]
+Carnicero
-[FEC_ONF]
-A pie
+[RATNG40]
+Encargado de la limpieza
-[FEC_INC]
-En vehículos
+[RATNG41]
+Asesino
-[FEC_VIB]
-Vibración:
+[RATNG42]
+Consigliere
-[FEA_OUT]
-Salida:
+[RATNG43]
+Maleante
-[FEA_ST]
-Estéreo
+[RATNG44]
+Mano derecha
-[FEA_MNO]
-Mono
+[RATNG45]
+Ejecutor
-[FEA_NON]
-Ninguna
+[RATNG46]
+Teniente
-[FEA_FM0]
-HEAD RADIO
+[RATNG47]
+Subjefe
-[FEA_FM1]
-DOUBLE CLEF FM
+[RATNG48]
+Capo
-[FEA_FM2]
-K-JAH RADIO
+[RATNG49]
+Jefe
-[FEA_FM3]
-RISE FM
+[RATNG50]
+Negado
-[FEA_FM4]
-LIPS 106
+[RATNG51]
+Don
-[FEA_FM5]
-GAME FM
+[RATNG52]
+Rey de la Jodida Ciudad
-[FEA_FM6]
-MSX FM
+[PAGE_00]
+.
-[FEA_FM7]
-FLASHBACK 95.6
+[WELCOME]
+BIENVENIDO A
-[FEA_FM8]
-CHATTERBOX FM
+[TSCORE]
+GANANCIAS: ~1~ $
-[FED_DBG]
-Menú de depuración
+[PBOAT_2]
+Pulsa ~h~~k~~PED_FIREWEAPON~~w~ para disparar los cañones del barco.
-[FED_RID]
-Recargar IDE
+[HJSTAT]
+Distancia: ~1~.~1~m Altura: ~1~.~1~m Vueltas: ~1~ Rotación: ~1~_
-[FED_RIP]
-Recargar IPL
+[HJSTATW]
+Distancia: ~1~.~1~m Altura: ~1~.~1~m Vueltas: ~1~ Rotación: ~1~_ ¡qué gran aterrizaje!
-[FED_PAH]
-Analizar pila
+[ATUTOR]
+Pulsa ~h~~k~~TOGGLE_SUBMISSIONS~~w~ para activar o desactivar las misiones de ATS.
-[FED_RCD]
-CCullZones::RecalculateCullZoneData
+[FEST_HA]
+Nivel más alto de misión de ATS
-[FED_DFL]
-CTheScripts::DbgFlag
+[C_KILLS]
+CRIMINALES ASESINADOS: ~1~
-[FED_DLS]
-Cambiar luz blanca grande de depuración
+[HJSTATF]
+Distancia: ~1~ pies Altura: ~1~ pies Vueltas: ~1~ Rotación: ~1~_
-[FED_SPR]
-Mostrar grupos de peatones en carretera
+[HJSTAWF]
+Distancia: ~1~ pies Altura: ~1~ pies Vueltas: ~1~ Rotación: ~1~_, ¡y qué gran aterrizaje!
-[FED_SCR]
-Mostrar grupos de vehículos en carretera
+[CRED001]
+ROCKSTAR NORTH
-[FED_SCZ]
-Mostrar zonas de máscara selectiva
+[CRD001A]
+DIRECTOR DEL ESTUDIO
-[FED_DSR]
-Solicitudes de depuración de streaming
+[CRD001B]
+ANDREW SEMPLE
-[FED_SCP]
-gbShowCollisionPolys
+[CRED002]
+PRODUCTOR
-[FEM_MCM]
-Menú de Memory Card
+[CRD002A]
+DIRECTOR DE DESARROLLO
-[FEM_RMC]
-Registrar MemCard uno
+[CRED003]
+LESLIE BENZIES
-[FEM_TFM]
-Probar MemCard uno formateada
+[CRED004]
+DIRECTOR DE ARTE
-[FEM_TUM]
-Probar Memcard uno sin formato
+[CRED005]
+AARON GARBUT
-[FEM_CRD]
-Crear directorio raíz
+[CRED006]
+DIRECTORES TÉCNICOS
-[FEM_CLI]
-Crear y cargar iconos
+[CRED007]
+OBBE VERMEIJ
-[FEM_FFF]
-Llenar primer archivo con basura
+[CRED008]
+ADAM FOWLER
-[FEM_SOG]
-Guardar sólo partida
+[CRED010]
+ANDREW DUTHIE
-[FEM_CES]
-Comprobar cada guardado de 0kB4
+[CRED011]
+CRAIG FILSHIE
-[FEM_STG]
-Guardar partida
+[CRED012]
+WILLIAM MILLS
-[FEM_STS]
-Guardar partida bajo el nombre GTA3
+[CRED013]
+CHRIS ROTHWELL
-[FEM_CPD]
-Crear copia protegida del directorio mag
+[CRD013A]
+IMRAN SARWAR
-[FEM_MC2]
-Menú de Memory Card 2
+[CRD013B]
+JAMES WORRALL
-[FEM_TS]
-Prueba de guardado:
+[CRD013C]
+JOHN HAIME
-[FEM_TL]
-Prueba de carga:
+[CRED014]
+ESCRITO POR
-[FEM_TD]
-Prueba de borrado:
+[CRED015]
+JAMES WORRALL
-[PL_STAT]
-Estadísticas de jugador
+[CRED016]
+PAUL KUROWSKI
-[PE_WAST]
-Personas asesinadas
+[CRED017]
+DAN HOUSER
-[PE_WSOT]
-Personas asesinadas por otros
+[CRED018]
+DISEÑO DEL PERSONAJE PRINCIPAL
-[CAR_EXP]
-Coches reventados
+[CRD018A]
+DISEÑO DE PERSONAJES
-[TM_BUST]
-Veces arrestado
+[CRED019]
+IAN MCQUE
-[M_WASTE]
-Hombres civiles asesinados
+[CRD019A]
+TOKS SOLARIN
-[F_WASTE]
-Mujeres civiles asesinadas
+[CRD019B]
+ALAN DAVIDSON
-[PIG_WST]
-Polis asesinados
+[CRED020]
+ANIMACIÓN PRINCIPAL
-[GNG_WST]
-Miembros de bandas asesinados
+[CRED021]
+ALEX HORTON
-[MED_WST]
-Médicos asesinados
+[CRD022A]
+ANIMACIÓN
-[FIRE_WS]
-Bomberos asesinados
+[CRED022]
+LEE MONTGOMERY
-[DED_CRI]
-Criminales asesinados
+[CRD022B]
+DUNCAN SHIELDS
-[DED_DED]
-Vagabundos asesinados
+[CRD022C]
+GUS BRAID
-[DED_HOK]
-Prostitutas asesinadas
+[CRED023]
+DISEÑO DE VEHÍCULOS
-[HEL_DST]
-Helicópteros destruidos
+[CRD023A]
+JOLYON ORME
-[PER_COM]
-Porcentaje completado
+[CRD023B]
+ALAN DUNCAN
-[KGS_EXP]
-Kgs de explosivos empleados
+[CRD024A]
+DISEÑO DEL VEHÍCULO PRINCIPAL
-[ACCURA]
-Precisión de tiro
+[CRED024]
+PAUL KUROWSKI
-[ELBURRO]
-Mejor tiempo de ''Turismo'' en segundos
+[CRED025]
+DISEÑO DE MAPAS
-[CAR_CRU]
-Coches destrozados
+[CRED026]
+ADAM COCHRANE
-[HED_EX]
-Cabezas explotadas
+[CRED027]
+NIK TAYLOR
-[TM_DED]
-Visitas al hospital
+[CRED028]
+GARY MCADAM
-[DAYSPS]
-Días de juego transcurridos
+[CRED029]
+KEIRAN BAILLIE
-[MMRAIN]
-mm de lluvia caídos
+[CRED030]
+ALISDAIR WOOD
-[MXCARD]
-Dist. máx. de salto demencial (pies)
+[CRED031]
+ANDREW SOOSAY
-[MXCARJ]
-Altura máx. de salto demencial (pies)
+[CRD031A]
+STEVEN MULHOLLAND
-[MXCARDM]
-Dist. máx. de salto demencial (metros)
+[CRD031B]
+WAYLAND STANDING
-[MXCARJM]
-Altura máx. de salto demencial (metros)
+[CRD031C]
+CAMPBELL J. DICK
-[MXFLIP]
-Vueltas máximas en salto demencial
+[CRD031D]
+DISEÑO GRÁFICO
-[MXJUMP]
-Rotación máxima en salto demencial
+[CRD031E]
+STUART PETRI
-[BSTSTU]
-Mayor acrobacia demencial:
+[CRED032]
+PROGRAMADOR JEFE
-[INSTUN]
-Acrobacia demencial
+[CRD032A]
+PROGRAMADORES
-[PRINST]
-Acrobacia demencial perfecta
+[CRED033]
+ALEXANDER ROGER
-[DBINST]
-Acrobacia demencial doble
+[CRED034]
+GRAEME WILLIAMSON
-[DBPINS]
-Acrobacia demencial doble perfecta
+[CRED035]
+BARANE CHAN
-[TRINST]
-Acrobacia demencial triple
+[CRED036]
+DEREK PAYNE
-[PRTRST]
-Acrobacia demencial triple perfecta
+[CRED037]
+GORDON YEOMAN
-[QUINST]
-Acrobacia demencial cuádruple
+[CRD037A]
+ALAN CAMPBELL
-[PQUINS]
-Acrobacia demencial cuádruple perfecta
+[CRD037B]
+MARK HANLON
-[NOSTUC]
-No se han hecho acrobacias
+[CRD037C]
+ANDRZEJ MADAJCZYK
-[NOUNIF]
-Saltos únicos completados
+[CRED038]
+PRODUCTOR JEFE MUSICAL
-[NOUNGM]
-Saltos únicos
+[CRED039]
+CRAIG CONNER
-[NMISON]
-Intentos de misión
+[CRED040]
+STUART ROSS
-[NMMISP]
-Misiones superadas
+[CRED041]
+INGENIERO JEFE DE AUDIO
-[PASDRO]
-Pasajeros transportados
+[CRED042]
+ALLAN WALKER
-[MONTAX]
-Dinero conseguido en taxi
+[CRD041A]
+INGENIERO DE AUDIO
-[DAYPLC]
-Gastos diarios provocados a la policía
+[CRD041B]
+AUDIO
-[CRIMRA]
-Rango de criminal:
+[CRD042A]
+WILL MORTON
-[GMSTOR]
-Almacenar partida
+[CRED043]
+PROGRAMADOR DE AUDIO
-[PREBRF]
-Resúmenes anteriores
+[CRED044]
+RAYMOND USHER
-[CNTLS]
-Controles
+[CRED045]
+JEFE DE PRUEBAS
-[MUSMEN]
-Música/Efectos
+[CRED046]
+CRAIG ARBUTHNOTT
-[GAMSET]
-Ajustes del juego
+[CRED047]
+CONTROL DE CALIDAD PRINCIPAL
-[LANGUA]
-Idioma
+[CRED048]
+NEIL CORBETT
-[DSPLAY]
-Pantalla
+[CRED049]
+KEVIN WONG
-[DEBUGM]
-Menú de depuración
+[CRED050]
+CONTROL DE CALIDAD
-[QUITOP]
-Salir de las opciones
+[CRED051]
+DAVID BEDDOES
-[CONTRL]
-Configuración de controles
+[CRED052]
+DAVID WATSON
-[SET1EN]
-Ajuste 1. Activado
+[CRED053]
+BARRY CLARK
-[SET1]
-Ajuste 1.
+[CRED054]
+ROSS SPARROW
-[SET2EN]
-Ajuste 2. Activado
+[CRED055]
+JAMES ALLAN
-[SET2]
-Ajuste 2
+[CRED056]
+NEIL MEIKLE
-[SET3EN]
-Ajuste 3. Activado
+[CRD056A]
+GEORGE WILLIAMSON
-[SET3]
-Ajuste 3
+[CRD056B]
+MATT JONES
-[SET4EN]
-Ajuste 4. Activado
+[CRD056C]
+ROB HARBOUR
-[SET4]
-Ajuste 4
+[CRD056D]
+TOM WHITTAKER
-[GOBACK]
-Volver
+[CRED057]
+SOPORTE TÉCNICO PRINCIPAL
-[SOUND]
-SONIDO
+[CRED058]
+LORRAINE ROY
-[MUSVOL]
-Volumen de la música
+[CRD057A]
+SOPORTE TÉCNICO
-[SFXVOL]
-Volumen de los efectos
+[CRED059]
+CHRISTINE CHALMERS
-[SCROPT]
-OPCIONES DE PANTALLA
+[CRD060A]
+SOPORTE DE OFICINA
-[CTRSCR]
-Centrar pantalla
+[CRD060B]
+KIM GURNEY
-[SCRFOR]
-Formato de imagen
+[CRD060C]
+CASSIE OLIVER
-[GMSVLQ]
-GUARDAR-CARGAR-SALIR
+[CRED060]
+ROCKSTAR NUEVA YORK
-[GMREST]
-Reiniciar partida
+[CRED061]
+GABINETE DE APOYO
-[GMLOAD]
-CARGAR PARTIDA
+[CRED062]
+SAM HOUSER
-[NOGMSV]
-Sólo puedes guardar desde tu escondite.
+[CRED063]
+PRODUCTOR
-[DLFILE]
-Borrar archivos de Grand Theft Auto III
+[CRED064]
+DAN HOUSER
-[CHFILE]
-ELEGIR ARCHIVO A CARGAR
+[CRED065]
+VICEPRESIDENTE DE DESARROLLO
-[CHCDLD]
-ELEGIR MEMORY CARD A USAR
+[CRED066]
+JAMIE KING
-[CDUNFR]
-Memory Card sin formato.
+[CRED067]
+OFICIAL JEFE DE TECNOLOGÍA
-[CHFIDL]
-ELEGIR ARCHIVO A BORRAR
+[CRED068]
+GARY J. FOREMAN
-[SVCONF]
-CONFIRMACIÓN
+[CRED069]
+PRODUCTOR ASOCIADO
-[SVFNAM]
-El nombre de tu archivo guardado es
+[CRED070]
+JEREMY POPE
-[SAVEDN]
-Error. Fallo al guardar.
+[CRD071A]
+DIRECTOR DE CONTROL DE CALIDAD
-[LANGSL]
-SELECCIÓN DE IDIOMA
+[CRD072A]
+JEFF ROSA
-[ENGLIS]
-Inglés
+[CRED071]
+SUPERVISOR MUSICAL
-[GERMAN]
-Alemán
+[CRED072]
+TERRY DONOVAN
-[ITALIA]
-Italiano
+[CRED073]
+EQUIPO DE PRODUCCIÓN
-[FRENCH]
-Francés
+[CRED074]
+TERRY DONOVAN
-[SPAIN]
-Español
+[CRED075]
+JENNIFER KOLBE
-[RELIDE]
-ReLoadIde
+[CRED076]
+JENEFER GROSS
-[RELIPE]
-ReLoadIpl
+[CRED077]
+LAURA PATERSON
-[PARSHP]
-Analizar pila
+[CRED078]
+JEFF CASTANEDA
-[DBGFON]
-CTheScripts::DbgFlag activado
+[CRED079]
+JERONIMO BARRERA
-[DBFOFF]
-CTheScripts::DbgFlag desactivado
+[CRED080]
+CARLY SLATER
-[BGWHON]
-Luz blanca grande de depuración activada
+[CRED081]
+JUNG KWAK
-[BGWOFF]
-Luz blanca grande de depuración desactivada
+[CRED082]
+BRIAN WOOD
-[DSTRON]
-Solicitudes de depuración de streaming activadas
+[CRED083]
+RENAUD SEBANNE
-[DSTROFF]
-Solicitudes de depuración de streaming desactivadas
+[CRED084]
+RICHARD KRUGER
-[PDRGON]
-ShowPedRoadGroups activado
+[CRD084A]
+DANIEL EINZIG
-[PRGOFF]
-ShowPedRoadGroups desactivado
+[CRD084B]
+JACEN BURROWS
-[CRRGON]
-ShowCarRoadGroups activado
+[CRD084C]
+LINN PR
-[CRGOFF]
-ShowCarRoadGroups desactivado
+[CRD084D]
+DISEÑO DE PORTADA
-[CLZOON]
-Zonas de máscara selectiva mostradas
+[CRD084E]
+STEPHEN BLISS
-[CLZOOF]
-Zonas de máscara selectiva ocultadas
+[CRED085]
+KENT PAUL'S 80 NOSTALGIA ZONE
-[SHPLON]
-gbShowCollisionPolys activado
+[CRED086]
+ESCRITO POR DAN HOUSER
-[SHPLOF]
-gbShowCollisionPolys desactivado
+[CRD086A]
+PRODUCIDO POR ADAM TEDMAN
-[CULREC]
-CCullZones::RecalculateCullZoneData()
+[CRED087]
+WWW.KENTPAUL.COM AND WWW.VICECITY.COM
-[FORMM1]
-FormatMemCard 1 (prueba)
+[CRED088]
+CREADO POR
-[UNFRM1]
-UnFormatMemCard 1 (prueba)
+[CRD088A]
+ADAM TEDMAN
-[GORLEV]
-Nivel de violencia
+[CRD088B]
+DAVID YU
-[SICASS]
-Puta locura
+[CRD088C]
+JERRY LUNA
-[SICSIC]
-Puto manicomio
+[CRD088D]
+STUART PETRI
-[SCASSL]
-Seleccionado Puta locura
+[CRD088E]
+MICHAEL CARNEVALE
-[SCSCSL]
-Seleccionado Puto manicomio
+[CRD088F]
+GREG LAU
-[PRVMEN]
-Resúmenes de misiones anteriores
+[CRD088G]
+FUTABA HAYASHI
-[DOSVGM]
-¿Deseas guardar la partida?
+[CRED089]
+JEFE DE CONTROL DE CALIDAD
-[FORMEN]
-Menú de formato
+[CRED090]
+CRAIG ARBUTHNOTT
-[MEMTST]
-Pantalla MemoryCardTest
+[CRED091]
+ANALISTA JEFE
-[REGCAR]
-Registrar MemoryCard uno
+[CRED092]
+ADAM DAVIDSON
-[TEFONE]
-Probar MemCard uno con formato
+[CRD092A]
+JOE HOWELL
-[TEUFON]
-Probar MemCard uno sin formato
+[CRD092B]
+MARC FERNANDEZ
-[CRROOT]
-CreateRootDir
+[CRED093]
+ANALISTA DEL JUEGO
-[CRLDIC]
-Crear y cargar iconos
+[CRED094]
+RICHARD HUIE
-[FLFSGF]
-Llenar el primer archivo con basura
+[CRED095]
+EQUIPO DE PRUEBAS DE ROCKSTAR
-[PUSAVE]
-Guardar sólo la partida
+[CRED096]
+LANCE WILLIAMS
-[CHEVOK]
-CheckEveryOkB4Save
+[CRED097]
+JOE GREENE
-[SVGMON]
-SaveTheGame
+[CRED098]
+BRIAN PLANER
-[CNTSAV]
-No se puede guardar la partida en una misión.
+[CRD098A]
+ELIZABETH SATTERWHITE
-[CNCSAV]
-No se puede guardar la partida dentro de un vehículo.
+[CRD098B]
+JAMEEL VEGA
-[CRMGSV]
-Crear directorio de cargador con protección de copia
+[CRD098C]
+MIKE HONG
-[MGSVNC]
-MagazineDirectory no creado
+[CRED099]
+LEE CUMMINGS
-[MGSVCN]
-MagazineDirectory creado
+[CRED100]
+HISTORIA
-[YES]
-Sí
+[CRED101]
+JAMES WORRALL
-[NO]
-No
+[CRED102]
+DAN HOUSER
-[X]
-x
+[CRED103]
+ADAM TEDMAN
-[LAST]
-Último mensaje
+[CRED104]
+PAUL YEATES
-[FEDS_XB]
-Seleccionar
+[CRED105]
+JENEFER GROSS
-[FEDS_ST]
-Botón START - CONTINUAR
+[CRED106]
+LAURA PATERSON
-[FEST_OO]
-de
+[CRED107]
+SECUENCIAS
-[FEC_TUC]
-Controlar torreta
+[CRED108]
+ESCRITAS POR DAN HOUSER Y JAMES WORRALL
-[FEC_SM3]
-Activar misión secundaria (botón R3)
+[CRED109]
+DIRECCIÓN DE AUDIO DE DAN HOUSER Y NAVID KHONSARI
-[FEC_RS3]
-Cambiar emisora de radio (botón L3)
+[CRED110]
+PRODUCIDAS POR JAMIE KING
-[FEC_HO3]
-Claxon (botón L3)
+[CRD110A]
+SELECCIÓN DE ACTORES: JAMIE KING, SEAN MACALUSO
-[DIAB1]
-'TURISMO'
+[CRED111]
+REPARTO
-[DIAB2]
-'IRA HELADA'
+[CRD111A]
+PERSONAJES DE REPARTO
-[DIAB3]
-'A LA HOGUERA'
+[CRED112]
+TOMMY VERCETTI - RAY LIOTTA
-[DIAB4]
-'GRANDE Y VENOSA'
+[CRED113]
+KEN ROSENBERG - WILLIAN FICHTNER
-[DIAB1_A]
-El Burro quiere ofrecerte una oportunidad. Ve al teléfono público de los cerros de Hepburn si te interesa.
+[CRED114]
+SONNY FORELLI - TOM SIZEMORE
-[DIAB1_C]
-Se te da bien correr. Pásate por el teléfono público y puede que El Burro tenga trabajo para ti.
+[CRED115]
+STEVE SCOTT - DENNIS HOPPER
-[DIAB1_1]
-~g~3... 2... 1... ¡ADELANTE!
+[CRED116]
+AVERY CARRINGTON - BURT REYNOLDS
-[DIAB1_4]
-~g~Hazte con un coche rápido y ve a la parrilla de salida.
+[CRED117]
+RICARDO DÍAZ - LUIS GUZMÁN
-[DIAB1_3]
-~r~No sabes ganar ni una rifa, ¡FRACASADO!
+[CRED118]
+LANCE VANCE - PHILIP MICHAEL THOMAS
-[DIAB1_2]
-~g~Felicidades, has ganado con un tiempo increíble de ~1~ segundos.
+[CRED119]
+CORONEL JUAN CORTEZ - ROBERT DAVI
-[FIRST]
-~g~1
+[CRED120]
+UMBERTO ROBINA - DANNY TREJO
-[SECOND]
-~g~2
+[CRED121]
+PHIL CASSIDY - GARY BUSEY
-[THIRD]
-~g~3
+[CRED122]
+MITCH BAKER - LEE MAJORS
-[FOURTH]
-~g~4
+[CRED123]
+MERCEDES CORTEZ - FAIRUZA BALK
-[DIAB2_1]
-~g~Recoge el maletín en Harwood.
+[CRED124]
+KENT PAUL - DANNY DYER
-[DIAB2_2]
-~g~Encuentra un camión de helados.
+[CRED125]
+JEZZ TORRENT - KEVIN MCKIDD
-[DIAB2_3]
-~g~Aparca el camión de helados en el muelle Atlantic.
+[CRED126]
+SUPERVISOR TAXIS - DEBORAH HARRY
-[DIAB2_4]
-~g~Pulsa ~w~~k~~VEHICLE_HORN~~g~ para activar la melodía del camión de helados.
+[CRED127]
+CANDY SUXX - JENNA JAMESON
-[DIAB2_6]
-~g~Pulsa ~w~~k~~VEHICLE_HORN~~g~ para activar la melodía del camión de helados.
+[CRED128]
+BJ SMITH - LAWRENCE TAYLOR
-[DIAB2_7]
-~g~Pulsa ~w~~k~~VEHICLE_HORN~~g~ para activar la melodía del camión de helados.
+[CRED129]
+TÍA POULET - YOUREE CLEOMILI HARRIS
-[DIAB2_5]
-~g~Sal del camión y luego usa el mando a distancia para detonarlo.
+[CRED130]
+PROVEEDOR - ARMANDO RIESCO
-[YD1]
-'CORRE A POR LA PASTA'
+[CRED131]
+COUGAR - BLAYNE PERRY
-[YD2]
-'JINETE CON UZI'
+[CRED132]
+HILARY - CHARLES TUCKER
-[YD3]
-'COLECCIONANDO COCHES DE BANDAS'
+[CRED133]
+CONGRESISTA ALEX SHRUB - CHRIS LUCAS
-[YD4]
-'POR LOS AIRES'
+[CRED134]
+VIEJO KELLY - GEORGE DICENZO
-[YD_P]
-El Rey Courtney quiere hablarte. ¡Ve al teléfono público de Aspatria!
+[CRD134A]
+CAM JONES - GREG SIMS
-[YD1_A]
-Habla el rey Courtney.
+[CRD134B]
+PSICÓPATA - HUNTER PLATIN
-[YD1_A1]
-Mi banda jamaicana necesita un conductor y tú tienes buena reputación.
+[CRD134C]
+MAUDE LA VENDEDORA DE HELADOS - JANE GENNARO
-[YD1_B]
-Ve en un coche al vertedero que hay detrás del estadio y espera a los otros candidatos.
+[CRD134D]
+JETHRO - JOHN ZURHELLEN
-[YD1_C]
-Tengo hombres vigilando puntos de control por toda Staunton.
+[CRD134E]
+GONZÁLEZ - JORGE PUPO
-[YD1_D]
-El primer conductor que llegue a un punto de control se lleva mil pavos, y así de punto a punto.
+[CRD134F]
+DWAYNE - NAVID KHONSARI
-[YD1_D1]
-Si ganas más puntos de control que los demás, podría tener trabajo para ti.
+[CRD134G]
+DICK - PETER MCKAY
-[YD1_E]
-~g~¡Prepárate!
+[CRD134H]
+MIKE EL MATÓN & CHICO PORNO - ROBERT CIHRA
-[YD1_F]
-~g~Te has saltado la salida. ¡Me gusta tu estilo!
+[CRD134I]
+PERCY - RUSSELL FOREMAN
-[YD1_G]
-~r~Esto es una carrera DE COCHES. ¡Necesitas un COCHE, idiota!
+[CRED135]
+CAPTURA DE MOVIMIENTOS
-[YD1GO]
-~g~¡VAMOS!
+[CRED136]
+ANIMACIÓN DE
-[YD1_1]
-~r~1
+[CRD136A]
+DIRECCIÓN TÉCNICA DE ALEX HORTON
-[YD1_2]
-~r~2
+[CRED137]
+DIRIGIDO POR
-[YD1_3]
-~r~3
+[CRD137A]
+DIRIGIDO POR NAVID KHONSARI
-[YD1_BON]
-¡1.000 $!
+[CRED138]
+PRODUCIDO POR
-[Y1_1ST]
-~G~¡Has quedado primero con ~1~ puntos de control!
+[CRD138A]
+PRODUCIDO POR JAMIE KING
-[Y1_2ND]
-~y~Eres el segundo con ~1~ puntos de control. ~y~¡Casi, pero no!
+[CRD138B]
+RENAUD SEBBANE
-[Y1_3RD]
-~r~Eres el tercero con ~1~ puntos de control. ~r~¿No decías que eras bueno?
+[CRED139]
+GRABADO EN PERSPECTIVE STUDIOS, BROOKLYN
-[Y1_LAST]
-~r~¡Has quedado el último! ~r~¡Me has hecho perder el tiempo, IDIOTA!
+[CRED140]
+ACTORES DE CAPTURA DE MOVIMIENTOS
-[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!
+[CRD140A]
+BLAYNE PERRY
-[Y1_J2ND]
-~r~Has empatado el segundo con ~1~ puntos de control. ¡Conduces como un mono loco!
+[CRD140B]
+JONATHON SALE
-[Y1JLAST]
-~r~¡Has empatado el último! ¡Hablas como un conductor, pero conduces como un hablador!
+[CRD140C]
+CHARLES TUCKER
-[Y1_TEST]
-¡COCHE AL AGUA!
+[CRD140D]
+EDDIE MARRERO
-[YD2_A]
-Necesito ver si eres capaz de hacer mi trabajo sucio,
+[CRD140E]
+WILLIAM MCCALL
-[YD2_A1]
-si se puede confiar en ti.
+[CRD140F]
+JORGE PUPO
-[YD2_B]
-Dos de mis chicos llegarán allí enseguida para llevarte de paseo,
+[CRD140G]
+ROBERT JACKSON
-[YD2_B1]
-a ver si eres quien dices que eres.
+[CRD140H]
+TARA RADCLIFFE
-[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.
+[CRD140I]
+JENIFER GAMBETESE
-[YD2_CC]
-Toma, necesitarás una pipa.
+[CRD140J]
+KRIS ACHEVARRIA
-[YD2_D]
-Tú te ocupas de conducir y disparar. Nosotros nos aseguraremos de que no te eches atrás.
+[CRD140K]
+ALI ORDOUBADI
-[YD2_E]
-¡Conduce!
+[CRD140L]
+KAHLEEM POOLE
-[YD2_F]
-~r~Se quiere escapar, ¡cárgatelo!
+[CRED141]
+DIÁLOGOS DE LOS PEATONES
-[YD2_G1]
-Los cerros de Hepburn... Vamos a matar a algunos asquerosos Diablos...
+[CRD141A]
+ESCRITOS POR DAN HOUSER, MARC FERNÁNDEZ, GILLIAN TELLING Y NAVID KHONSARI
-[YD2_G2]
-Pero recuerda, ~r~¡no salgas de este coche!
+[CRD141B]
+CON LA AYUDA DE JEREMY POPE, LANCE WILLIAMS, Y JENNY JEMISON
-[YD2_H]
-¡Vale, ya está! ¡Llévanos de vuelta a territorio jamaicano! ¡Vamos, vamos, vamos!
+[CRED142]
+ESCRITO POR
-[YD2_L]
-¡Eres la Muerte personificada!
+[CRD142A]
+DAN HOUSER Y JAMES WORRALL
-[YD2_M]
-~r~¡Ha destrozado mi coche! ¡Liquídalo!
+[CRED143]
+DIRIGIDO POR DAN HOUSER, CRAIG CONNER, MARC FERNÁNDEZ, Y ALLAN WALKER
-[YD2_N]
-¡Vuelve al coche!
+[CRED144]
+PRODUCIDO POR RENAUD SEBANNE
-[YD3_A]
-Quiero que robes coches de otras bandas
+[CRED145]
+PEATONES
-[YD3_A1]
-para que podamos atacar sus territorios.
+[CRED146]
+ADAM DAVIDSON, ADAM WATKINS, ALEJANDRO K. BROWN, ALEX ANTHONY SIOUKAS, ALEX GARCÍA,
-[YD3_B]
-Necesito un Mafia Sentinel,
+[CRED147]
+ALICE SALTZMAN, ALISON CIHRA, AMY SALIMA, AMY SALZMAN, ANDREA VIDELA, ANTHONY ATTI,
-[YD3_B1]
-un Yakuza Stinger y un
+[CRED148]
+ANTHONY RIVERA, BIJAN SHAMS, BLAYNE PERRY, BRETT BISOGNO, BREYE MATA, BRIAN PANEN,
-[YD3_B2]
-Diablo Stallion para que podamos ir a por cualquier banda de Liberty.
+[CRED149]
+BROCK VODER, CAREY BERTINI, CHARISSE LAMBERT, CHRIS DIFAT, CHRIS REISENBERGER,
-[YD3_C]
-Déjalos en el garaje de Newport y recuerda,
+[CRED150]
+CHRISTOPHER BRODAY, CHRISTOPHER CARRO, CYNTHIA GREENE, DAMARIES LÓPEZ, DAN LEE,
-[YD3_C1]
-¡dañados no nos sirven de nada!
+[CRED151]
+DAN SCHNEIDER, DAN TOYAMA, DAVID DEAN CHALTFIELD, JR., DAVID HARRISON, DAVID WILEY,
-[YD3_D]
-UNUSED
+[CRED152]
+DEBORAH COLLINS, DEBRANDA CHANEY-GILES, DEMETRA KOUKOULAS, DENISE ROSADO,
-[YD3_E]
-~r~¡Ya has entregado un coche de los Diablos!
+[CRED153]
+DEVIN BENNETT, DEVIN WINTERBOTTOM, DORIS WOO, DOUGLAS HARRISON, DUNCAN COUTTS,
-[YD3_F]
-~r~¡Ya has entregado un coche de la mafia!
+[CRED154]
+DUPE AJAYI, EDWIN AVELLANEDA, ELIZABETH HOWELL, ELIZABETH SATTERWHITE, ERIC NAGLE,
-[YD3_G]
-~r~¡Ya has entregado un coche de la yakuza!
+[CRED155]
+ESTEBAN KARPLUS, F. FONT, FUTABA HAYASHI, GENE HILGREEN, GERALD COSGROVE,
-[YD3_H]
-~g~¡Coche de los Diablos entregado!
+[CRED156]
+GERARD LUNA, GILLIAN TELLING, GREGG CARLUCCI, GREGORY CLERVOIX, GREGORY SCHWEIZER,
-[YD3_I]
-~g~¡Coche de la mafia entregado!
+[CRED157]
+HADLEY TOMICKI, J. ROSSETT, JAMEEL VEGA, JASON JONES, JEFF ROSA, JENNIFER JEMISON,
-[YD3_J]
-~g~¡Coche de la yakuza entregado!
+[CRED158]
+JEREMY TAGGERT, JESSICA RIDER, JOSEPH GREENE,JOSEPH HOWELL, KATE DUKICH,
-[YD3_K]
-~r~¡El coche está casi destrozado! ¡Haz que lo reparen!
+[CRED159]
+KEL O'NEILL, KEVIN HOPKINS, LADAWN JAMES, LANCE WILLIAMS, LAURA BUBBLES,
-[YD3_L]
-~g~¡Llévalo al ~p~garaje~g~!
+[CRED160]
+LAURA PATTERSON, LEE CUMMINGS, LETICIA L. YOUNG, LINDSAY KENNEDY, LISA ORITZ,
-[YD3_M]
-~r~¡Has volcado el vehículo! ¡Consigue otro!
+[CRED161]
+LORNA JORDAN, LUCIO AMADIO, MARCO FERNÁNDEZ, MARIKO TANAKA, MARLON MATTHEWS,
-[YD4_A]
-¡Escucha!
+[CRED162]
+MARY TELLING, MASAYOSHI MITSUYAMA, MATTHEW CHUNG, MAX ALLSTADT, MAX BOGDANOV,
-[YD4_A1]
-Mueve el culo a Bedford Point.
+[CRED163]
+MELISSA ÁLVAREZ, MICHAEL MAY, MICHAEL ROTHSTEIN, MIGUEL VIDAL, MIKE FEDERLINE,
-[YD4_A2]
-¡Hay un cargamento en una tartana que necesito pronto!
+[CRED164]
+NATALIE DESCALZO, N'GAI MEMBERS, NICOLAS MALLO, NOELLE SADLER, NORBERT MORIVAN,
-[YD4_B]
-CARTA: Dicen que estuviste entretenido. Igual que yo.
+[CRED165]
+OSWALD GREENE, JR., PETER MCKAY, PETER APPEL, PRESTON SAVARESE, RAFAEL GONZÁLEZ,
-[YD4_C]
-¡Es hora de que seas testigo del verdadero poder del SPANK! Con mucho amor, Catalina.
+[CRED166]
+RANDY JOHNSON, REY CONCEPCIÓN, RICHARD KROGER, ROB TIBBS, ROBERT JACKSON,
-[YD4_D]
-P.D. ¡MUERE, BASURA, MUERE!
+[CRED167]
+ROBERT SCHULER, ROSS A. MCINTYRE, RUSSELL FOREMAN, RUTH NÚÑEZ, SALVADORE SUAZO,
-[YD4_1]
-~g~¡Son psicópatas adictos al SPANK!
+[CRED168]
+SAM WHITE, SANTOS GONZÁLEZ, SCOTT SMITH, SEYMOUR FRAILMAN, SPELMAN BRAUMAN,
-[YD4_2]
-~g~¡Destruye las furgonetas de SPANK!
+[CRED169]
+STEPHANIE TELLING, STEVE KNEZEVICH, STEVE ROBERT, SUMIKO YASUDA, SUSAN LEWIS,
-[HM_1]
-'PASADA AMETRALLADA'
+[CRED170]
+SYLVIA COLACIOS, TOMOKO MIYAZAKI, TRON, VERDEL HALE, YVES MONDESIR, ZENO LEINFELDER,
-[HM_2]
-'BOMBINATOR'
+[CRED171]
+DAVID BEDDOES, CHRISTINE CHALMERS, BARRY CLARK, NEIL CORBETT, KIM GURNEY, NEIL MEIKLE,
-[HM_3]
-'PREPARADO PARA ESTALLAR'
+[CRED172]
+CASSIE OLIVER, LORRAINE ROY, DAVID WATSON, KEVIN WONG, WILL MORTON
-[HM_5]
-'ENFRENTAMIENTO'
+[CRED175]
+ADAM DAVIDSON
-[HOOD1_A]
-Ve al teléfono público de Wichita Gardens y hablaremos de negocios.
+[CRED176]
+LANCE WILLIAMS
-[HM1_A]
-¡Ey! ¡Soy D-Ice, de los Red Jacks!
+[CRED177]
+NEIL MCCAFFREY
-[HM1_C]
-Hay unos macarrillas en la calle que no piensan más que en pistolas y en SPANK.
+[CRED178]
+LAURA PATERSON
-[HM1_3]
-~g~Los Nines tienen su territorio en Wichita Gardens.
+[CRED179]
+REY CONCEPCIÓN
-[HM2_3]
-¡Si golpeas las ruedas de un vehículo, el coche teledirigido estallará!
+[CRED180]
+CHARLES HEROLD
-[HM2_4]
-¡Si el coche teledirigido sale fuera de cobertura, estallará solo!
+[CRED181]
+ANDREW GREENWALD
-[HM2_5]
-~r~¡Te has ido de cobertura!
+[CRED182]
+JAMES MIELKE
-[HM3_1]
-~g~¡Ve al garaje, pero pon atención, porque el coche explotará si se daña demasiado!
+[CRED183]
+PETER SUCIU
-[HM3_2]
-~g~Lleva el coche de vuelta. ¡Tiene que estar inmaculado!
+[CRED184]
+ALEX ODULIO
-[HM3_3]
-~g~¡Haz que reparen el vehículo!
+[CRED185]
+DON NKRUMAH
-[HM4_D]
-~g~¡Hazte con un vehículo!
+[CRED186]
+KENDALL PITTMAN
-[HM4_1]
-~g~Dirígete al lugar donde está el cargamento. Necesitas conseguir 30 lingotes.
+[CRED187]
+SAL SUAZO
-[HM4_2]
-~g~Recuerda: cuando el vehículo esté pesado y vaya más despacio, ve al garaje y deja el cargamento.
+[CRED188]
+EREK MATEO
-[HM5_3]
-~r~¡Te han dicho que uses sólo un bate de béisbol!
+[CRED189]
+CHRIS DIFATE
-[HM5_4]
-~r~¡Tu contacto está muerto!
+[CRED190]
+LEILA MILTON
-[MEA1]
-'EL CRIMINAL'
+[CRED191]
+DARREN ZOLTOWSKI
-[MEA2]
-'LOS LADRONES'
+[CRED192]
+VIRGINIA SMITH
-[MEA3]
-'LA MUJER'
+[CRED193]
+KEVIN CASSIN
-[MEA4]
-'SU AMANTE'
+[CRED194]
+JASON SHIGEMORI
-[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.
+[CRED195]
+KELLY KINSELLA
-[MEA1_B3]
-~g~Reúnete con el director del banco.
+[CRED196]
+MOLLIE STICKNEY
-[MEA1_B6]
-~g~Lleva el coche a la trituradora para eliminar las pruebas, allí sal del coche y la grúa lo recogerá.
+[CRED197]
+STANTON SARJEANT
-[MEA1_1]
-~r~¡El director del banco está muerto!
+[CRED198]
+LAURA WALSH
-[MEA1_2]
-~r~¡Te dijeron que trituraras el coche!
+[CRED199]
+MARK GARONE
-[MEA1_3]
-~g~¡Sal del coche!
+[CRED200]
+JOANNA SLY
-[MEA1_4]
-~r~¡Has abandonado al director del banco!
+[CRED201]
+ELIZABETH HOWELL
-[MEA2_B3]
-~g~Reúnete con los ladrones.
+[CRED202]
+ANA HÉRCULES
-[MEA2_B4]
-~g~Llévalos a la fábrica de comestibles Bitch'n' Dog.
+[CRED203]
+SHIRLEY IRICK
-[MEA2_B6]
-~g~Haz que repinten el coche para borrar las pruebas.
+[CRED204]
+KASHONA FIELDS
-[MEA2_1]
-~r~¡Te dijeron que trituraras el vehículo!
+[CRED205]
+JOEL M. LILJE
-[MEA2_2]
-~r~¡Un ladrón ha muerto!
+[CRED206]
+JOHN DIBENEDETTO
-[MEA2_4]
-~r~¡Has abandonado a un ladrón!
+[CRED207]
+NANCY GILES
-[MEA3_B3]
-~g~Recoge a la Sra. Chonks.
+[CRED208]
+RYAN CROY
-[MEA3_B6]
-~g~Llévate el coche y tíralo al mar para eliminar las pruebas.
+[CRED209]
+JENNIFER KOLBE
-[MEA3_1]
-~r~¡La mujer ha muerto!
+[CRED210]
+LIAM BURKE
-[MEA3_2]
-~r~¡Se suponía que debías tirar el coche al agua!
+[CRED211]
+SIGRID PREISSL
-[MEA3_3]
-~r~¡Has abandonado a su mujer!
+[CRED212]
+ANITA FITZSIMONS
-[MEA4_B3]
-~g~Recoge al amante de su mujer.
+[CRED213]
+PHILIPPA RASELLI
-[MEA4_B6]
-Ya es muy tarde, Marty. Tuviste tu oportunidad, pero ahora yo me ocuparé de tu negocio...
+[CRED214]
+WIL QUESNEL
-[MEA4_1]
-~r~¡Carlos está muerto!
+[CRED215]
+FALKO BURKERT
-[MEA4_3]
-~r~¡Has abandonado a Carlos, el usurero!
+[CRED216]
+SARA SEWELL
-[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~.
+[CRED217]
+EMISORAS DE RADIO Y MÚSICA
-[LOVE6_1]
-~g~¡Ahora aleja a los policías del almacén!
+[CRED218]
+ASESOR MUSICAL
-[LOVE6_2]
-~r~¡No has distraído a la policía!
+[CRD218A]
+HEINZ HENN
-[RM4_3]
-~r~¡El socio de Ray ha escapado!
+[CRD218B]
+STUART ROSS
-[RM6_C]
-La CIA parece tener intereses con el SPANK
+[CRED219]
+COORDINADOR DE LA BANDA SONORA
-[RM6_C1]
-y no les gusta que incordiemos al cártel.
+[CRED220]
+TERRY DONOVAN
-[C_PASS]
-¡AMENAZA ELIMINADA!
+[CRED221]
+PRODUCTOR DE ROCKSTAR GAMES
-[CTUTOR]
-Pulsa ~h~~k~~TOGGLE_SUBMISSIONS~~w~ para activar o desactivar las misiones de justiciero.
+[CRED222]
+DAN HOUSER Y LAZLOW
-[CTUTOR2]
-Pulsa ~h~~k~~TOGGLE_SUBMISSIONS~~w~ para activar o desactivar las misiones de justiciero.
+[CRED223]
+PRODUCTOR DE ROCKSTAR NORTH
-[COPCART]
-~g~Tienes ~1~ segundos para volver a un vehículo de la policía antes de que termine la misión.
+[CRED224]
+CRAIG CONNER
-[C_FAIL]
-¡Misión de justiciero terminada!
+[CRED225]
+ALLAN WALKER
-[C_CANC]
-~r~¡Misión de justiciero cancelada!
+[CRED226]
+LAZLOW
-[C_ESCP]
-~r~¡El sospechoso ha escapado!
+[CRED227]
+DJ BANTER E IMÁGENES
-[C_TIME]
-~r~¡Tu trabajo como defensor de la ley ha terminado!
+[CRED228]
+ESCRITO POR DAN HOUSER Y LAZLOW
-[C_VIGIL]
-¡PREMIO POR JUSTICIERO!
+[CRED229]
+FLASH FM
-[A_FAIL2]
-~r~¡Tu falta de rapidez ha sido fatal para el paciente!
+[CRD229A]
+TONI-MARIA CHAMBERS
-[A_FAIL3]
-~r~¡El paciente está muerto!
+[CRD229B]
+VOCES FICTICIAS Y PRODUCCIÓN-JEFF BERLIN
-[A_PASS]
-¡Paciente a salvo!
+[CRED230]
+GRACIAS ESPECIALES A
-[F_FAIL2]
-~r~¡Llegas demasiado tarde!
+[CRED231]
+TOMMY MOTTOLA,
-[A_COMP2]
-¡Nunca te cansarás!
+[CRED232]
+MICHELLE ANTHONY,
-[RM2_M]
-Si necesitas armas nuevas, pasa por aquí y coge lo que necesites de las taquillas.
+[CRED233]
+STEVE BARNETT,
-[HEAL_A]
-Tu ~h~salud ~w~está indicada en naranja en la parte superior derecha de la pantalla.
+[CRED234]
+CHUCK FLECKENSTEIN,
-[YD1_CNT]
-¡~1~ de 15!
+[CRED235]
+RITA LIBERATOR
-[FM1_9]
-~g~La fiesta es allí. Deja a María enfrente.
+[CRED236]
+MARTIN & CLAIRE LOGAN
-[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.
+[CRED237]
+SANDRA HUTTON
-[FM1_AA]
-Bueno, será mejor que me vaya. Espero que nos veamos pronto.
+[CRED238]
+CHRISTINE DAVIDSON
-[NOCONTE]
-Vuelve a conectar un mando analógico (DUALSHOCK#) o mando analógico (DUALSHOCK#2) en el puerto de mando 1 para continuar.
+[CRED239]
+ALAN, RED & BIGFOOT
-[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).
+[CRED240]
+LE T
-[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).
+[CRED241]
+COLIN DONALD
-[WRONGCD]
-Disco incorrecto. Introduce el disco correcto.
+[CRED242]
+KERRY STALLWOOD
-[NOCD]
-La bandeja del disco está vacía. Introduce un disco.
+[CRED243]
+ALAN MCGREGOR
-[OPENCD]
-La bandeja del disco está abierta. Cierra la bandeja de disco.
+[CRED244]
+CHRIS MORTON
-[CDERROR]
-Error al leer el DVD de Grand Theft Auto III
+[CRED245]
+EMIL BUSSE
-[RESTART]
-Empezando una nueva partida
+[CRED246]
+EMILY BAILLIE
-[GA_3]
-¡Ya no es gratis! ¡La mano de pintura son 1.000 dólares!
+[CRED247]
+KEVIN ARCHIBALD
-[GA_1]
-¡Hala! ¡Demasiado peligroso para mi gusto!
+[CRED248]
+MORAG KERR
-[GA_1A]
-Vuelve cuando no estés tan ocupado...
+[CRED249]
+CATH WALKER
-[S_PROM2]
-Puedes alojar un vehículo en el garaje de al lado al guardar tu partida.
+[CRED250]
+ISO BAR
-[STOCK]
-Mercancía agotada
+[CRED251]
+WATERLINE
-[FM1_O]
-Creo que está en la estación de ferrocarril del muelle de Chinatown.
+[CRED252]
+NEWS CAFE
-[EBAL_B]
-Es aquí, ¡entremos y cambiémonos de ropa!
+[CRD251A]
+THE POND
-[EBAL_G]
-Éste es el club de Luigi. Vamos a la parte de atrás, a la puerta de servicio.
+[CRD252A]
+PIVO
-[AM4_3]
-¡Tú debes de ser el nuevo recadero de Asuka!
+[CRED253]
+BUDGET VIDEO RENTALS
-[AM4_4]
-¿Tienes el dinero? ¿Está todo?
+[CRED254]
+LORNA'S SCOOTER
-[AM4_5]
-Sé lo que estás pensando: ''otro poli corrupto''.
+[CRED255]
+GARETH MURFIN
-[AM4_6]
-Pues éste es un mundo corrupto.
+[CRED256]
+ARTE ADICIONAL
-[AM4_7]
-He perdido a un par de socios y esos papanatas de Asuntos Internos ya se han puesto a husmear.
+[CRED257]
+TONY PORTER
-[AM4_8]
-¡Y seguro que les llega mi olor!
+[CRED258]
+CRAIG MOORE
-[AM4_9]
-¡Pues esta ciudad es una gran alcantarilla!
+[CRED259]
+ANIMACIÓN DE SINCRONIZACIÓN LABIAL DE LAS SECUENCIAS
-[AM4_10]
-Pero voy a necesitar un ayudita ajena al cuerpo.
+[CRED260]
+COSGROVE HALL FILMS
-[AM4_11]
-Si estás interesado, ya sabes dónde encontrarme.
+[CRED261]
+PRODUCTOR - OWEN BALLHATCHET
-[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.
+[CRED262]
+ANIMADOR SENIOR - JON TURNER
-[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.
+[CRED263]
+ANIMADORES - RICHARD DRUMM
-[KM2_1]
-~g~Repara el coche, tiene que estar en perfecto estado.
+[CRED264]
+DAVE BROWN
-[LM3_6]
-¡Joey...!
+[CRED265]
+MAIR THOMAS
-[LM3_6A]
-¿Voy a jugar con tu paquetín otra vez?
+[CRED266]
+PRASHANT PATEL
-[LM3_9A]
-que tendré trabajo para ti.
+[CRED267]
+ASESOR TECNOLOGÍA DE AUDIO
-[LM3_9B]
-¿De acuerdo?
+[CRED268]
+RIK EDE PARA GAMESOUND LTD.
-[AWAY2]
-~r~Se ha escapado.
+[CRED269]
+SOPORTE DTS INTEGRATION
-[AWAY]
-~r~¡Se ha pirado!
+[CRED270]
+TED LAVERTY DE DTS
-[JM6_1]
-Llévanos al banco de la avenida principal.
+[CRED271]
+CHRIS GREER DE DTS
-[GA_6B]
-¡Apárcalo, actívala pulsando ~h~~k~~PED_FIREWEAPON~~w~ y SAL PITANDO!
+[CRED272]
+JASON PAGE DE SCEE
-[GA_7B]
-Activa la bomba pulsando ~h~~k~~PED_FIREWEAPON~~w~. Estallará cuando se arranque el motor.
+[CRED273]
+INVESTIGACIÓN Y ANÁLISIS
-[BAT1]
-~g~¡Coge el bate!
+[CRED274]
+VROCK
-[EBAL_O]
-Si no la cagas, puede que haya más trabajo para ti. ¡Ahora largo!
+[CRED275]
+DJ: LAZLOW COMO ÉL MISMO
-[HELP9_B]
-Pulsa ~h~~k~~PED_FIREWEAPON~~w~ para ~h~disparar ~w~el fusil de francotirador.
+[CRED276]
+VOZ-JOE KELLY
-[HELP9_C]
-Pulsa ~h~~k~~PED_FIREWEAPON~~w~ para ~h~disparar ~w~el fusil de francotirador.
+[CRED277]
+PRODUCCIÓN-JONATHAN HANST
-[JM6_8]
-~r~¡Has perdido a todos los ladrones!
+[CRED278]
+WAVE 103
-[COLT_IN]
-¡La pistola ya está disponible en la tienda Ammu-Nation!
+[CRED279]
+DJ: ADAM FIRST-JAMIE CANFIELD
-[TAXI2]
-~r~¡Se te acabó el tiempo!
+[CRED280]
+VOZ-JEN SWEENEY
-[TAXI3]
-~r~¡Tu cliente ha salido por patas!
+[CRED281]
+PRODUCCIÓN-JONATHAN HANST
-[TAXI7]
-~r~Tu coche está destrozado, repáralo.
+[CRED282]
+FEVER 105
-[TAXI4]
-¡Carrera terminada!
+[CRED283]
+DJ: OLIVER 'LADYKILLER' BISCUIT-JULIUS DYSON
-[TAXI5]
-¡VIAJE RÁPIDO!
+[CRED284]
+VOZ MASCULINA-ED MCMANN
-[TAXI6]
-Misión de taxista cancelada
+[CRED285]
+VOZ FEMENINA-SHAWNEE SMITH
-[FRANGO]
-~g~¡Salvatore quiere que ayudes primero a Toni a ocuparse de las Tríadas!
+[CRED286]
+PRODUCCIÓN- LISTEN KITCHEN
-[PAGEB12]
-Soborno policial entregado en tu guarida.
+[CRED287]
+EMOTION 98.3
-[PAGEB13]
-Salud entregada en tu guarida.
+[CRED288]
+DJ: FERNANDO- FRANK CHAVEZ
-[PAGEB14]
-Adrenalina entregada en tu guarida.
+[CRED289]
+VOZ-JEN SWEENEY
-[KM1_4]
-~g~¡Necesitas un coche de policía para hacer el trabajo!
+[CRED290]
+PRODUCCIÓN-JONATHAN HANST
-[CAT1_B]
-lleva 500.000 dólares a la mansión de Cedar Grove.
+[CRED291]
+RADIO ESPANTOSO
-[JM2_C]
-Tiene un puesto de fideos en Chinatown.
+[CRED292]
+DJ: PEPE-TONY CHILRODES
-[RM6_1]
-Esta llave es de un almacén.
+[CRED293]
+WILDSTYLE
-[RM6_2]
-Encontrarás dinero en metálico y ''suministros'' que guardé por si las cosas se ponían feas.
+[CRED294]
+DJ: MISTER MAGIC AS HIMSELF
-[RM6_3]
-Hasta la vista.
+[CRED295]
+VOZ-FRANK SILVESTRO
-[FE_INIP]
-Iniciando y cargando el menú de pausa... Espera, por favor.
+[CRED296]
+PRODUCCIÓN-LAZLOW
-[FESZ_CA]
-Cancelar
+[CRED297]
+KCHAT
-[FESZ_QU]
-Abandonar
+[CRED298]
+ESCRITO POR DAN HOUSER Y LAZLOW
-[FESZ_L1]
-¡La partida se ha guardado!
+[CRED299]
+PRODUCIDO Y EDITADO POR LAZLOW
-[FESZ_L2]
-El nombre guardado es:
+[CRED300]
+DJ AMY SHECKENHAUSEN -LEYNA WEBER
-[FESZ_OK]
-ACEPTAR
+[CRED301]
+JEZ TORRENT-KEVIN MCKIDD
-[FES_NGA]
-Nueva partida
+[CRED302]
+MANDY -COLLEEN CORBETT
-[FES_CAN]
-Cancelar
+[CRED303]
+MICHELLE CARAPADIS-MARY BIRDSONG
-[FESZ_QL]
-Perderás todo el progreso en tu partida actual. ¿Quieres continuar con la carga?
+[CRED304]
+MR.ZOO-CARL DOWLING
-[FESZ_QD]
-¿Quieres borrar esta partida guardada?
+[CRED305]
+GETHSEMANEE-LYNN LIPTON
-[FESZ_QO]
-¿Quieres sobreescribir esta partida guardada?
+[CRED306]
+CLAUDE MAGINOT-JOHN MAUCERI
-[FESZ_QR]
-¿Seguro que quieres empezar una nueva partida? Perderás todo el progreso desde la última partida guardada.
+[CRED307]
+BJ SMITH-LAWRENCE TAYLOR
-[FESZ_QS]
-¿QUIERES GUARDAR?
+[CRED308]
+THOR-FRANK FAVA
-[SLONFP]
-Puerto 1. Archivo protegido.
+[CRED309]
+PERSONAS LLAMANDO A LA RADIO
-[T4X4_1]
-'PATIO DE RECREO DEL PATRIOT'
+[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_2]
-'UN PASEO POR EL PARQUE'
+[CRED311]
+LEWIS, GILLIAN TELLING, TOM MURRAY, MIKE FERRANTE SR., EMMANUEL GOLDSTEIN,
-[T4X4_3]
-'¡AGARRADO!'
+[CRED312]
+DAN HOUSER, NICK MANDELOS, GERRY COSGROVE, MIKE PALERMO, PORKCHOP,
-[MM_1]
-'CAOS EN EL APARCAMIENTO'
+[CRED313]
+KEITH BROADAS
-[T4X4_1A]
-~g~Tienes ~y~5 minutos~g~ para pasar por ~y~15~g~ puntos de control. ~g~Puedes atravesarlos en ~y~CUALQUIER ORDEN.
+[CRED314]
+VCPR
-[T4X4_1B]
-¡~1~ de 15!
+[CRED315]
+ESCRITO POR DAN HOUSER Y LAZLOW
-[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.
+[CRED316]
+PRODUCIDO POR LAZLOW
-[T4X4_2A]
-~g~¡Tienes ~y~2 minutos~g~ para pasar por ~y~12~g~ puntos de control! ~g~Puedes atravesarlos en ~y~CUALQUIER ORDEN.
+[CRED317]
+MAURICE CHAVEZ-PHILLIP ANTHONY RODRIGUEZ
-[T4X4_2B]
-¡~1~ de 12!
+[CRED318]
+JONATHAN FREELOADER- PATRICK OLSEN
-[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.
+[CRED319]
+MICHELLE MONTANIUS-KELLY GUEST
-[T4X4_3A]
-~g~Tienes ~y~5 minutos~g~ para pasar por ~y~20~g~ puntos de control. ~g~Puedes atravesarlos en ~y~CUALQUIER ORDEN.
+[CRED320]
+REP. ALEX SHRUB- CHRIS LUCAS
-[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.
+[CRED321]
+CALLUM CRAYSHAW- SEAN MODICA
-[T4X4_3C]
-¡~1~ de 20!
+[CRED322]
+JOHN F. HICKORY- LJ GANSEN
-[T4X4_F]
-~r~¡Te has escapado! ¿Demasiado difícil para ti?
+[CRED323]
+PASTOR RICHARDS- DAVID GREEN
-[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.
+[CRED324]
+JAN BROWN- MAUREEN SILLIMAN
-[MM_1_B]
-¡~1~ de 20!
+[CRED325]
+BARRY STARK- RENAUD SEBBANE
-[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.
+[CRED326]
+JENNY LOUISE CRAB- MARY BIRDSONG
-[FM2_14]
-~r~¡Te acercaste demasiado y asustaste a Curly!
+[CRED327]
+KONSTANTINOS SMITH- KONSTANTINOS.COM
-[FM2_15]
-~g~No te acerques mucho, ¡o Curly sospechará!
+[CRED328]
+JEREMY ROBARD-PETER SILVESTRO
-[UPSIDE]
-~r~¡Has volcado!
+[CRED329]
+ANUNCIOS DE RADIO
-[FM2_16]
-ASUSTÓMETRO:
+[CRED330]
+ESCRITOS POR DAN HOUSER Y LAZLOW
-[LM3_11]
-~g~Misty no irá en un autobús, ¡hazte con otro vehículo!
+[CRED331]
+PRODUCIDOS POR LAZLOW
-[LANDSTK]
-Landstalker
+[CRED332]
+JINGLES ADICIONALES PRODUCIDOS POR CRAIG CONNER
-[IDAHO]
-Idaho
+[CRED333]
+VOCES EN LOS ANUNCIOS:
-[STINGER]
-Stinger
+[CRED334]
+ADAM DAVIDSON, ALEX ANTHONY, ALICE SALTZMAN, AMY SALZMAN, KATE DUKICH,
-[LINERUN]
-Linerunner
+[CRED335]
+ARAN RONICLE, BARB JONES, BEN KRECH, BRIAN THOMAS, BROCK YODER, CHRIS
-[PEREN]
-Perennial
+[CRED336]
+FERRANTE, CRAIG CONNER, DAVE RYAN, DAVID GREEN, DORIS WOO, DOUGLAS
-[SENTINL]
-Sentinel
+[CRED337]
+HARRISON, ED MCMANN, FRANK CHÁVEZ, FRANK FAVA, GENE HILGREEN, GREG
-[PATRIOT]
-Patriot
+[CRED338]
+SCHWEIZER, HUNTER PLATIN, JAMES FERRANTE, JEFF BERLIN, JEFF ROSA, JOE KELLY,
-[FIRETRK]
-Camión de bomberos
+[CRED339]
+JOHN MAUCERI, JOSH CLARK, JULIE WEMYSS, KEVIN STRALEY, KIM GURNEY, LANCE
-[TRASHM]
-Trashmaster
+[CRED340]
+WILLIAMS, LAURA PATERSON, LAZLOW, LISA ORTIZ, LORNA JORDAN, LUCIEN JONES,
-[STRETCH]
-Stretch
+[CRED341]
+MAUREEN SILLIMAN, MIKE FERRANTE JR., PETE GUSTIN, PETER SILVESTRO, RAFF
-[MANANA]
-Mañana
+[CRED342]
+CROLLA, RANDY JOHNSON, RICHARD KRUGER, RON REEVE, SHELLEY MILLER, SKY, TJ ALLARD
-[INFERNS]
-Infernus
+[CRD344A]
+AUDIO GRABADO EN DIGITAL ARTS STUDIOS,
-[BLISTA]
-Blista
+[CRED344]
+NYC, TRACK 9 STUDIOS, NYC,
-[PONY]
-Pony
+[CRED345]
+WEDDINGTON MULTIMEDIA, LOS ANGELES,
-[MULE]
-Mule
+[CRD345A]
+SYNC SOUND, NYC Y RADIO LAZLOW, LONG ISLAND.
-[CHEETAH]
-Cheetah
+[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
-[AMBULAN]
-Ambulancia
+[CRED347]
+MARK LLOYD
-[FBICAR]
-Coche del FBI
+[CRED348]
+TIM BATES
-[MOONBM]
-Moonbeam
+[CRED349]
+KIT BROWN
-[ESPERAN]
-Esperanto
+[CRED350]
+ANDY MASON
-[TAXI]
-Taxi
+[CRED351]
+PHIL DEANE
-[KURUMA]
-Kuruma
+[CRED352]
+PHIL ALEXANDER
-[BOBCAT]
-Bobcat
+[CRED353]
+MATT HEWITT
-[WHOOPEE]
-Mr. Whoopee
+[CRED354]
+DENBY GRACE
-[BFINJC]
-BF Injection
+[CRED355]
+ANTOINE CABROL
-[POLICAR]
-Coche patrulla
+[CRED356]
+JONOTHAN STONES
-[ENFORCR]
-Enforcer
+[CRED357]
+MIKE BLACKBURN
-[SECURI]
-Securicar
+[CRED358]
+TIM MCGAFF
-[BANSHEE]
-Banshee
+[CINCAM]
+Cámara cinemática
-[PREDATR]
-Predator
+[RC4]
+MASACRES RUMPO
-[BUS]
-Autobús
+[LEGAL]
+~g~¡Elimina la amenaza criminal!
-[RHINO]
-Rhino
+[GA_2]
+Nuevo motor y trabajo de pintura. ¡Los policías no te reconocerán!
-[BARRCKS]
-Barracks OL
+[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~.
-[TRAIN]
-Tren
+[FEC_LB4]
+Mirar detrás (botón R3)
-[HELI]
-Helicóptero
+[PERPIC]
+Objetos ocultos encontrados
-[DODO]
-Dodo
+[CO_ONE]
+Objeto oculto ~1~ de ~1~
-[COACH]
-Coach
+[GA_21]
+No puedes almacenar más coches en este garaje.
-[CABBIE]
-Cabbie
+[CHEAT1]
+Truco activado
-[STALION]
-Stallion
+[CHEAT2]
+Truco de arma
-[RUMPO]
-Rumpo
+[CHEAT3]
+Truco de salud
-[RCBANDT]
-Bandit RC
+[CHEAT4]
+Truco de blindaje
-[BELLYUP]
-Furgoneta de las Tríadas
+[CHEAT5]
+Truco de nivel de se busca
-[MRWONGS]
-Mr Wongs
+[CHEAT6]
+Truco de dinero
-[MAFIACR]
-Sentinel de la mafia
+[CHEAT7]
+Truco de tiempo
-[YARDICR]
-Lobo jamaicano
+[USJ_ALL]
+¡TODAS LAS MANIOBRAS ÚNICAS COMPLETADAS!
-[YAKUZCR]
-Stinger de la yakuza
+[JAN]
+Ene
-[DIABLCR]
-Stallion de los Diablos
+[FEB]
+Feb
-[COLOMCR]
-Cruiser del cártel
+[MAR]
+Mar
-[HOODSCR]
-Rumpo XL de los hood
+[APR]
+Abr
-[AEROPL]
-Avioneta
+[MAY]
+May
-[SPEEDER]
-Speeder
+[JUN]
+Jun
-[REEFER]
-Reefer
+[JUL]
+Jul
-[PANLANT]
-Panlantic
+[AUG]
+Ago
-[FLATBED]
-Flatbed
+[SEP]
+Sep
-[YANKEE]
-Yankee
+[OCT]
+Oct
-[BORGNIN]
-Borgnine
+[NOV]
+Nov
-[TOYZ]
-TOYZ
+[DEC]
+Dic
-[FEST_DF]
-Distancia recorrida a pie (millas)
+[DEFDT]
+--:---:---- --:--:--
-[FEST_DC]
-Distancia recorrida en coche (millas)
+[BONUS]
+~g~BONIFICACIÓN ~1~ $
-[FESTDFM]
-Distancia recorrida a pie (metros)
+[HORN1]
+Pulsa ~h~~k~~VEHICLE_HORN~~w~para tocar el ~h~claxon.
-[FESTDCM]
-Distancia recorrida en coche (metros)
+[HORN2]
+Pulsa ~h~~k~~VEHICLE_HORN~~w~para tocar el ~h~claxon.
-[FEST_R1]
-''Patio de recreo del Patriot'' en segundos
+[HORN3]
+Pulsa ~h~~k~~VEHICLE_HORN~~w~para tocar el ~h~claxon.
-[FEST_R2]
-''Un paseo por el parque'' en segundos
+[FEC_EXV]
+Entrar y salir de vehículo
-[FEST_R3]
-''¡Agarrado!'' en segundos
+[TAXI_M]
+'TAXISTA'
-[FEST_RM]
-''Caos en el aparcamiento'' en segundos
+[COP_M]
+'JUSTICIERO'
-[FEST_LS]
-Gente salvada con una ambulancia
+[FIRE_M]
+'BOMBERO'
-[FEST_CC]
-Criminales asesinados en misiones de justiciero
+[AMBUL_M]
+'ATS'
-[FEST_FE]
-Incendios extinguidos
+[HJ_IS]
+BONIFICACIÓN POR ACROBACIA: ~1~ $
-[FEST_LF]
-Vuelo más largo en Dodo
+[HJ_PIS]
+BONIFICACIÓN POR ACROBACIA PERFECTA: ~1~ $
-[FEST_BD]
-Mejor tiempo al desactivar la bomba
+[HJ_DIS]
+BONIFICACIÓN POR ACROBACIA DOBLE: ~1~ $
-[FEST_RP]
-Masacres superadas
+[HJ_PDIS]
+BONIFICACIÓN POR ACROBACIA DOBLE PERFECTA: ~1~ $
-[FEST_MP]
-Misiones superadas
+[HJ_TIS]
+BONIFICACIÓN POR ACROBACIA TRIPLE: ~1~ $
-[FEST_BB]
-''Corre a por la pasta'':
+[HJ_PTIS]
+BONIFICACIÓN POR ACROBACIA TRIPLE PERFECTA: ~1~ $
-[FEST_H0]
-Máximo de puntos de control
+[HJ_QIS]
+BONIFICACIÓN POR ACROBACIA CUÁDRUPLE: ~1~ $
-[FEST_GC]
-Coches de bandas destruidos:
+[HJ_PQIS]
+BONIFICACIÓN POR ACROBACIA CUÁDRUPLE PERFECTA: ~1~ $
-[FEST_H1]
-Destrucción de los Diablos
+[FESZ_LS]
+Carga completada con éxito.
-[FEST_H2]
-La masacre de la mafia
+[HELI_1A]
+Prueba tus habilidades con el Sparrow, comprueba lo rápido que puedes completar el circuito.
-[FEST_H3]
-Calamidad en el casino
+[HELI_1B]
+¡Circuito completado! ~1~ $
-[FEST_H4]
-Exterminio de Rumpos
+[HELIODD]
+Trabajos esporádicos del helicóptero
-[USJ]
-¡PREMIO POR ACROBACIA ÚNICA!
+[LAW]
+LAS MISIONES DEL ABOGADO
-[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~.
+[LAW1_1]
+~g~Consigue unos trapos nuevos en la tienda de ropa de Rafael.
-[HM1_1]
-~g~Cepíllate a 20 Purple Nines en 2 minutos y 30 segundos.
+[LAW4_6]
+¡Quemad la dirección!
-[KM1_8A]
-Pulsa ~h~~k~~PED_FIREWEAPON~~w~ para ~h~activar la bomba~w~. Acuérdate de alejarte de ella.
+[LAW4_7]
+¡Matad a los jefes!
-[KM1_8D]
-Pulsa ~h~~k~~PED_FIREWEAPON~~w~ para ~h~activar la bomba~w~. Acuérdate de alejarte de ella.
+[LAW4_8]
+Luchad, luchad, luchad, luchad.
-[KM1_12]
-~g~¡Llévalo al dojo, pero deshazte primero de la policía!
+[LAW4_9]
+¡Más vacaciones, menos trabajo!
-[RATNG1]
-Carterista
+[LAW4_11]
+¡Luchad! ¡Luchad! ¡Luchad! ¡Luchad!
-[RATNG2]
-Abusón
+[LAW4_12]
+¡Viva la revolución!
-[RATNG3]
-Chorizo
+[GENERAL]
+LAS MISIONES DEL CORONEL
-[RATNG4]
-Granuja
+[GEN3_4]
+Tommy Vercetti. Vamos...
-[RATNG5]
-Secuaz
+[GEN3_13]
+¿Cuál es tu problema, tío? ¡Sube al tejado al otro lado del patio antes de que aparezcan!
-[RATNG6]
-Conductor
+[GEN3_17]
+¡Mierda! ¿Intentas matarme?
-[RATNG7]
-Guardaespaldas
+[GEN3_21]
+~g~¡Tiene el dinero de Díaz! ¡Ve tras él y recupéralo!
-[RATNG8]
-Negociador
+[GEN3_24]
+~r~¡Díaz murió! ¡Has fracasado al protegerle!
-[RATNG9]
-Socio
+[GEN3_26]
+~r~¡Le pegaste un tiro a Díaz!
-[RATNG10]
-Sicario
+[GEN3_27]
+~r~¡Disparaste a los guardaespaldas de Díaz!
-[RATNG11]
-Asesino
+[GEN3_31]
+~g~Ahora ve al punto de entrega y cuida de Díaz.
-[RATNG12]
-Mano derecha
+[GEN3_32]
+~g~Ve a tu posición elevada en el tejado del edificio opuesto a donde está Lance.
-[RATNG13]
-Verdugo
+[COKE]
+LAS MISIONES DEL BARÓN DE LA NIEVE
-[RATNG14]
-Capo
+[COK1_3]
+¡Espero que te caigas y te rompas el cuello!
-[RATNG15]
-Jefe
+[COK1_6]
+Estoy cansado de estos mamones.
-[1010]
-~r~Tu vehículo ha volcado
+[COK2_7]
+¿Veis esos marcadores chicos? ¡Probad a dar a las luces!
-[1011]
-~r~Tu vehículo ha volcado
+[COK2_10]
+Desde luego eres mejor disparando que charlando.
-[1012]
-~r~Tu vehículo ha volcado
+[COK2_11]
+Gracias. Eres un verdadero encanto.
-[1013]
-~r~Tu vehículo ha volcado
+[COK2_12]
+Lo sé, Tommy.
-[1014]
-~r~Tu vehículo ha volcado
+[COK2_18]
+¿Te gusta Kenny Loggins?
-[JM4_10]
-Vale, chaval, llévame primero a la lavandería de Chinatown, tengo un asunto del que ocuparme.
+[COK2_19]
+Dios, ¡me encanta este disco!
-[JM4_11]
-Las lavanderas no están pagando por su protección.
+[COK2_26]
+~r~¡Mataste a Lance!
-[JM4_12]
-Y ojo con el coche, Joey acaba de arreglar esta chatarra.
+[COK3_1]
+¡No dispares tío!
-[JM4_13]
-Así que ve con cuidado, ¿vale?
+[COK3_2]
+¿Qué hay ahí?
-[KM4_11]
-~g~¡Lleva el dinero de vuelta al casino!
+[COK3_3]
+Se está llevando el barco. Gorrón.
-[FEF_BR2]
-Encuéntralo de nuevo leyendo los resúmenes de las misiones jugadas hasta la fecha.
+[COK3_4]
+¡Ayuda! ¡Un tipo me está robando el barco, tío!
-[TRAIN_1]
-Estación Kurowski
+[COK4_W]
+¡Uugghh! Ése era el último.
-[TRAIN_2]
-Estación Rothwell
+[COK4_X]
+Voy a arrancarlo
-[TRAIN_3]
-Estación Baillie
+[COK4_Y]
+Creo que tenemos algunos amigos nuevos.
-[SUBWAY1]
-Estación Portland
+[COK4_2]
+Sí.
-[SUBWAY2]
-Estación Rockford
+[COK4_6]
+¿A dónde crees que vamos?
-[SUBWAY3]
-Estación Staunton sur
+[COK4_7]
+¿Nos hemos perdido?
-[SUBWAY4]
-Terminal Shoreside
+[COK4_8]
+¡Tenemos competencia!
-[MEA4_2]
-~r~¡Marty Chonks ha muerto!
+[COK4_9]
+¡Elimínales!
-[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_9A]
+¡Es hora del baile de Lance Vance!
-[JM4_A]
-Sí, Toni, ya está a punto. Ahora es una delicia, ¿sabes?
+[COK4_10]
+¡Ya son astillas! Y comida para los peces.
-[JM4_5]
-Pasa más tarde y les daremos algo que lavar... ¡Su propia ropa manchada de sangre!
+[COK4_11]
+¡Lo conseguimos! Esos otros barcos no son de la clase VIP.
-[AMMU_A]
-Luigi dijo que necesitabas una pipa...
+[COK4_17]
+¡Se están desesperando!
-[AMMU_B]
-Joey me pidió que te armara...
+[COK4_18]
+¡Mis malditos pies están mojados! ¡NOS ESTÁ ENTRANDO AGUA!
-[AMMU_C]
-Ve a la parte de atrás. Te dejé un nueve en el patio.
+[COK4_21]
+¡Subiendo el puente!
-[AMMU_D]
-Tengo todo lo necesario para defender tu casa.
+[COK4_22]
+¡Salta, está apunto de estallar!
-[AMMU_E]
-¿También quieres una licencia?
+[COK4_23]
+Buen disparo.
-[AMMU_F]
-No necesito tu documentación, pareces de fiar.
+[COK4_29]
+~r~¡Mataste a Lance!
-[DETON]
-DETONACIÓN:
+[ASS1_6]
+¡Adelante Tommy, yo estaré bien!
-[DRIVE_A]
-Ten una Uzi seleccionada cuando entres en un vehículo, luego mira a la izquierda o a la derecha y pulsa ~h~~k~~PED_FIREWEAPON~~w~ para disparar.
+[ASS1_7]
+¡Comeos esto, asesinos hijos de puta!
-[DRIVE_B]
-Ten una Uzi seleccionada cuando entres en un vehículo, luego mira a la izquierda o a la derecha y pulsa ~h~~k~~PED_FIREWEAPON~~w~ para disparar.
+[ASS1_8]
+¡Me han dado!
-[RECORD]
-~g~¡NUEVO RÉCORD!
+[ASS1_9]
+¡Te tengo cubierto, Tommy!
-[NRECORD]
-~r~¡NO HAY UN NUEVO RÉCORD!
+[ASS1_10]
+Eh, este seto es precioso.
-[RCHELP]
-Pulsa ~k~~PED_FIREWEAPON~ o lleva el coche teledirigido hasta las ruedas de otro coche para detonarlo.
+[ASS1_11]
+Tommy, ¿puedo tener una habitación con vistas a la bahía?
-[RCHELPA]
-Pulsa ~k~~PED_FIREWEAPON~ o lleva el coche teledirigido hasta las ruedas de otro coche para detonarlo.
+[ASS1_12]
+Unos techos altos muy bonitos...
-[RC_1]
-¡Tienes 2 minutos para destruir todos los coches de los Diablos que puedas!
+[ASS1_3]
+¡Lance! ¡Necesito que me cubras!
-[RC_2]
-¡Tienes 2 minutos para destruir todos los coches de la mafia que puedas!
+[ASS1_4]
+¡Díaz debe de estar dentro!
-[RC_3]
-¡Tienes 2 minutos para destruir todos los coches de la yakuza que puedas!
+[ASS1_5]
+¡Lance!
-[RC_4]
-¡Tienes 2 minutos para destruir todos los coches de los jamaicanos que puedas!
+[TAXWAR]
+MISIONES DE LA GUERRA DE TAXIS
-[RC_5]
-¡Tienes 2 minutos para destruir todos los coches de los Hood que puedas!
+[NOTAXI]
+~g~Necesitas un Taxi Kaufman para activar esta misión.
-[RC_6]
-¡Tienes 2 minutos para destruir todos los coches del cártel que puedas!
+[TAXW1_5]
+~g~¡Necesitas estar en un taxi Kaufman!
-[RAMPAGE]
-¡MASACRE!
+[TAX2_4]
+Adelante, Tommy.
-[RAMP_P]
-¡MASACRE COMPLETADA!
+[TAX2_5]
+Dale una buena paliza.
-[RAMP_F]
-MASACRE FALLIDA
+[TAX2_6]
+Ni siquiera tiene licencia.
-[PAGE_00]
-.
+[TAX2_7]
+Malditos servicios de limusina.
-[PAGE_01]
-¡Liquida a ~1~ Diablos en 120 segundos!
+[TAXW3_1]
+~g~Ve y recoge a Mercedes.
-[PAGE_02]
-¡Destruye ~1~ vehículos en 120 segundos!
+[RACE1]
+~g~3..2..1.. ¡VAMOS VAMOS VAMOS!
-[PAGE_03]
-¡Mata a ~1~ mafiosos en 120 segundos!
+[RACE2]
+~g~3
-[PAGE_04]
-¡Mata a ~1~ Tríadas en 120 segundos!
+[RACE3]
+~g~2
-[PAGE_05]
-¡Mata a ~1~ Tríadas en 120 segundos!
+[RACE4]
+~g~1
-[PAGE_06]
-¡Destruye ~1~ vehículos en 120 segundos!
+[RACE5]
+~g~¡ADELANTE!
-[PAGE_07]
-¡Revienta ~1~ cabezas jamaicanas en 120 segundos!
+[FIRST]
+~b~1
-[PAGE_08]
-¡Quema a ~1~ yakuzas en 120 segundos!
+[SECOND]
+~b~2
-[PAGE_09]
-¡Destruye ~1~ vehículos en 120 segundos!
+[THIRD]
+~b~3
-[PAGE_10]
-¡Destruye ~1~ vehículos en 120 segundos!
+[FOURTH]
+~b~4
-[PAGE_11]
-¡Aniquila a ~1~ jamaicanos en 120 segundos!
+[RACETM]
+~b~TIEMPO DE CARRERA: ~1~:~1~
-[PAGE_12]
-¡Quema a ~1~ yakuzas en 120 segundos!
+[RACETM2]
+~b~TIEMPO DE CARRERA: ~1~:0~1~
-[PAGE_13]
-¡Vuela a ~1~ jamaicanos en 120 segundos!
+[RACEFA]
+~r~¡Has fracasado en ganar la carrera!
-[PAGE_14]
-¡Fríe a ~1~ colombianos en 120 segundos!
+[HOTRNG]
+HOTRING
-[PAGE_15]
-¡Machaca a ~1~ Hoods en 120 segundos!
+[BLODRNG]
+BLOODRING
-[PAGE_16]
-¡Destruye ~1~ vehículos en 120 segundos!
+[DIRTRNG]
+DIRTRING
-[PAGE_17]
-¡Arrolla a ~1~ colombianos con un coche en 120 segundos!
+[TEX1_5]
+~r~¡Se escapó!
-[PAGE_18]
-¡Destruye ~1~ vehículos disparando desde otro en 120 segundos!
+[SEG3_1]
+TIEMPO:
-[PAGE_19]
-¡Revienta ~1~ cabezas colombianas en 120 segundos!
+[SEG3_2]
+~g~Ve a la camioneta que contiene el Helicótero RC y las bombas por control remoto con temporizador.
-[PAGE_20]
-¡Decapita a ~1~ Hoods en 120 segundos!
+[SEG3_3]
+~g~Debes emplear el Helicótero RC para transportar 4 bombas hasta 4 objetivos en lugar del edificio.
-[JM1_A]
-Jo, me aburro, ¿cuándo me la vas a meter?
+[SERG3_5]
+~g~Sólo puedes llevar una bomba en cada ocasión y no puedes recoger bombas colocadas con éxito.
-[JM1_B]
-Dame un momento, cariño, que tengo un asuntillo que tratar.
+[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_C]
-Tengo un trabajito para ti, colega.
+[SEG3_8]
+~g~Las 4 bombas deben estar colocadas en las 4 zonas objetivo para superar la misión y demoler el edificio.
-[JM1_D]
-Los hermanos Forelli me deben dinero desde hace mucho tiempo
+[SEG3_9]
+~g~¡Alcanzaste el objetivo! Quedan 3.
-[JM1_E]
-y hay que enseñarles modales.
+[SEG3_10]
+~g~¡Alcanzaste el objetivo! Quedan 2.
-[JM1_F]
-''Labios'' Forelli está atiborrándose en el restaurante de Saint Mark's,
+[SEG3_11]
+~g~¡Alcanzaste el objetivo! ¡Sólo queda 1!
-[JM1_G]
-así que róbale el coche y llévalo al taller de bombas de 8-Ball en Harwood.
+[SEG3_12]
+~r~¡Fallaste el blanco! ¡Ve a por una bomba!
-[JM1_H]
-Conoces a 8-Ball, ¿verdad?
+[SEG3_13]
+~g~Deja caer la bomba en una zona del objetivo.
-[JM1_I]
-En cuanto le ponga una bomba, aparca el coche donde lo encontraste.
+[SEG3_14]
+~r~Te quedaste sin tiempo y fracasaste en demoler el edificio.
-[JM1_J]
-Luego salte y disfruta del espectáculo.
+[SEG3_15]
+~r~¡Tu Helicótero RC ha sido destruido! ¿Cómo vas a transportar las bombas ahora?
-[JM1_K]
-Pero cuidado, no va a estar comiendo toda la vida.
+[AVERY]
+MISIONES DE AVERY
-[CAT2_A1]
-¡Vamos, perra!
+[ASM]
+MISIONES DE ASESINO
-[CAT2_A]
-La verdadera pregunta es: ¿vienes buscando a María o buscándome a mí?
+[ASM_1]
+MISIÓN DE ASESINO 1
-[CAT2_B]
-Tengo una noticia para ti:
+[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_B2]
-matarte será un placer, pero salir contigo sólo fue un negocio.
+[ASM1_2]
+~g~Ve a la cabina telefónica que hay frente al centro comercial de Washington.
-[CAT2_C]
-¡Eres muy pequeñito, amigo!
+[ASM1_3]
+~g~Carl Pearson, un repartidor de pizza. No debe finalizar sus entregas.
-[CAT2_D]
-Dame el dinero.
+[ASM1_4]
+~g~Elimina al repartidor de pizza antes de que complete sus entregas.
-[CAT2_E]
-¡Has estado muy ocupado!
+[ASM_2]
+MISIÓN DE ASESINO 2
-[CAT2_E2]
-Pero no has aprendido que yo no soy de fiar.
+[ASM_3]
+MISIÓN DE ASESINO 3
-[CAT2_E3]
-¡Mata al idiota!
+[ASM3_1]
+~g~Ve a coger el arma que el Sr. Black ha dejado para ti.
-[CAT2_J]
-¡Despega de una vez!
+[ASM3_2]
+~g~No te acerques demasiado al objetivo o podría verte.
-[HM5_1]
-Hola, Ice dijo que vendrías. Las reglas son sólo bates. Cero armas, cero coches.
+[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.
-[HM5_5]
-Es una batalla por respeto, ¿vale?
+[ASM3_4]
+~g~¡Te ha visto! ¡Mejor elimínale de cualquier modo que puedas!
-[HELP14]
-Para conseguir un arma, pasa sobre ella. No podrás recogerlas estando dentro de un vehículo.
+[ASM3_5]
+~g~Marcus Hammond está situado cerca de los anuncios de Washington.
-[CRUSH]
-Aparca en la zona señalada y sal de tu vehículo para que sea triturado.
+[ASM3_6]
+~g~Franco Carter está situado en el DBP de Seguridad, cerca de Ocean Drive.
-[DIAB2_B]
-Una banda de roñosos amenazó con quitarme a mi protagonista si no les pago.
+[ASM3_7]
+~g~Dick Tanner está cerca de la joyería de Vice Point.
-[DIAB2_C]
-Amenazaron al hombre equivocado, amigo.
+[ASM3_8]
+~g~Nick Kong está colocado cerca de Washington Beach.
-[DIAB2_D]
-Su debilidad son los helados.
+[ASM3_9]
+~g~El conductor está situado en Washington.
-[DIAB2_E]
-Hazte con la bomba que dejé en Harwood,
+[ASM3_10]
+~r~Fallaste en matarles a todos.
-[DIAB2_F]
-secuestra la camioneta del heladero mientras hace su ronda
+[ASM_4]
+MISIÓN DE ASESINO 4
-[DIAB2_G]
-y engaña a esos idiotas con esa musiquita.
+[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.
-[DIAB2_H]
-Se esconden en un almacén del muelle Atlantic.
+[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_A]
-¡Unas Tríadas insolentes robaron mi lindo carro anoche,
+[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.
-[DIAB3_B]
-lo destrozaron y lo quemaron!
+[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.
-[DIAB3_C]
-En el baúl había algunas de mis más preciadas posesiones sobre burros...
+[ASM4_5]
+~g~¡Consigue el maletín!
-[DIAB3_D]
-Objetos de coleccionista irremplazables, amigo.
+[ASM4_6]
+~g~Lleva al maletín a Ammu-Nation en el centro de la ciudad.
-[DIAB3_E]
-Escondí un arma caliente en el borde de Chinatown.
+[ASM4_7]
+~r~¡Estúpido, has matado a la mujer!
-[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_8]
+~r~¡El blanco te oyó disparar el arma! ¡El trato queda anulado!
-[DIAB3_1]
-MATA A 25 TRÍADAS
+[ASM4_9]
+~r~¡El blanco ha embarcado en su vuelo!
-[DIAB4_A]
-¡Un ladrón oportunista robó una camioneta con mi última publicación!
+[ASM4_11]
+~r~¡El blanco te ha visto! ¡El trato queda anulado!
-[DIAB4_B]
-Pero ese idiota drogado de SPANK dejó las puertas de atrás abiertas,
+[ASM4_13]
+~g~Te ha visto y está huyendo, ¡atrápale y consigue el maletín!
-[DIAB4_C]
-¡y ahora mi literatura para adultos
+[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á.
-[DIAB4_D]
-tan bellamente producida, tan gustosamente fotografiada, está siendo esparcida por toda Liberty!
+[ASM_5]
+MISIÓN DE ASESINO 5
-[DIAB4_E]
-Monta en la camioneta y sigue el rastro de los volúmenes 1, 2 y 3 de Donkey Does Dallas,
+[KICK]
+ARRANQUE
-[DIAB4_F]
-tomándolos por el camino.
+[KICK1_3]
+~g~Número de veces que pusiste el pie: ~1~
-[DIAB4_G]
-¡Cuando alcances a ese bandido espaciado con SPANK, chíngatelo!
+[KICK1_4]
+~g~Tiempo de penalización: ~1~ segundos
-[DIAB4_H]
-Luego reparte mis revistas XXX por el barrio rojo.
+[BANK]
+MISIONES DEL ATRACO AL BANCO
-[DIAB4_1]
-~g~Lleva la furgoneta a la parte de atrás de Revistas XXX.
+[BANK1]
+MISIÓN DE ATRACO AL BANCO 1
-[HM1_E]
-Quiero que esos mierdecillas sepan lo que es un verdadero tiroteo desde un vehículo.
+[BANK2]
+MISIÓN DE ATRACO AL BANCO 2
-[HM1_H]
-¡Haz que esos Nines se larguen!
+[BJM2_21]
+~g~Acierta a tantos blancos como puedas mientras te quede munición.
-[HM2_A]
-Los Nines me están presionando.
+[BANK3]
+MISIÓN DE ATRACO AL BANCO 3
-[HM2_B]
-Tienen coches blindados y ahora están pasando SPANK
+[BJM3_1]
+~g~Consigue un coche rápido y ve a la parrilla de salida.
-[HM2_C]
-a los hermanos sin ningún pudor.
+[BNK4_2A]
+Los chicos hicieron un trabajo genial con este pequeño.
-[HM2_D]
-Hay un coche aparcado en la calle.
+[BNK4_3G]
+¡Oh, mierda, ahora los polis andan tras nosotros!
-[HM2_E]
-Dentro lleva algo que te servirá para poner a esos gallinas en su sitio
+[BNK4_3H]
+Y ni siquiera hemos llegado.
-[HM3_A]
-Algún cazurro me ha puesto una bomba en el coche.
+[BNK4_3K]
+Primero tendremos que despistar a los polis...
-[HM3_B]
-Si lo pierdo, mi reputación en la calle se irá a la porra.
+[BNK4_3L]
+Joder, Tommy, ¿intentas matarnos a todos?
-[HM3_C]
-Coge mi coche y llévalo al taller de Saint Mark's, ¿valiendo?
+[BNK4_3N]
+¡Todo lo que me importa acaba destrozado!
-[HM3_D]
-Que se encarguen ellos de desarmar la bomba.
+[BNK4_26]
+¡Maldición! ¡Aquí vienen!
-[HM3_E]
-El tiempo corre y ese trasto es un peligro.
+[BNK4_32]
+¡Usa los explosivos para abrir las cajas de depósito!
-[HM3_F]
-Un golpe más de la cuenta y podría saltar por los aires.
+[BNK4_36]
+¿Dónde está Cam?
-[HM3_G]
-¡Tira!
+[BNK4_37]
+Es historia...
-[HM4_A]
-Tío, un vuelo de la Reserva Federal se la acaba de pegar en el Aeropuerto Francis.
+[BNK4_38]
+Ése era el último. ¡Vamos! ¡Vamos! ¡Vamos!
-[HM4_B]
-Hay platino por toda la pista.
+[BNK_39]
+¡Mierda! ¿Dónde está Hilary?
-[HM4_C]
-Consigue un coche y agarra todo lo que puedas.
+[BK4_40A]
+¡Ya le daré yo miedo al abandono!
-[HM4_F]
-Puedes dejar la mercancía en uno de mis garajes.
+[BNK4_42]
+¡Eh, tíos! ¡Subid! ¡Yo os cubro!
-[HM4_G]
-El platino pesa un huevo y hará que tu buga vaya a paso de tortuga,
+[BNK4_43]
+¡Ya cubro yo nuestros culos, tú conduce!
-[HM4_H]
-así que ve dejándolo de vez en cuando en el garaje.
+[BNK4_44]
+¡Lo conseguimos! ¡Somos ricos! ¡Ricos!
-[HM5_A]
-Ya sólo quedan unos pocos Nines,
+[BNK4_45]
+Es una pena que Cam no lo consiguiese, ¡era un buen tipo!
-[HM5_B]
-pero todavía quieren guerra.
+[BNK4_46]
+Sí. Pero aún así... ¡más tajada para nosotros!
-[HM5_C]
-Han aceptado un mano a mano.
+[BNK4_47]
+¡Claro que sí! ¡Sí!
-[HM5_D]
-Un puñado de los suyos contra dos de los nuestros,
+[BNK4_48]
+Tommy, ¿te gustaría un masaje?
-[HM5_E]
-o más bien, tú y uno más.
+[BNK4_49]
+¡Hola, Mercedes! Sí, estoy un poco tenso...
-[HM5_F]
-Os ayudaría, pero...
+[BNK450A]
+¿Qué te dije, Tommy? ¿Qué te dije? Maldito SWAT, será mejor que tengas cuidado cuando Kent Paul esté en la ciudad.
-[HM5_G]
-No quiero jugarme mi libertad condicional,
+[BNK450B]
+Vamos, dame una tajada más grande, colega, venga. Tengo que comprarme ropa nueva.
-[HM5_H]
-¿me captas?
+[BNK4_51]
+Yo creo que tienes buen aspecto.
-[HM5_I]
-Reúnete con mi hermano pequeño,
+[KENT]
+MISIONES DE KENT PAUL
-[HM5_J]
-él te enseñará dónde será la pelea.
+[KENT1]
+MISIÓN DE KENT PAUL 1
-[MEA1_B]
-Me llamo Chonks, Marty Chonks.
+[COUNT]
+MISIONES DE FALSIFICACIÓN
-[MEA1_C]
-Soy el dueño de la fábrica de comestibles Bitch'n' Dog que está a la vuelta de la esquina.
+[COUNT1]
+MISIÓN DE FALSIFICACIÓN 1
-[MEA1_D]
-Tengo problemas económicos, ¿pero y quién no?
+[COUNT2]
+MISIÓN DE FALSIFICACIÓN 2
-[MEA1_E]
-He quedado con el director de mi banco.
+[BIKE]
+LAS MISIONES DE LA PANDILLA DE MOTEROS
-[MEA1_F]
-Es un chorizo que no para de inflar los intereses del préstamo para sacarme una buena tajada.
+[BIKE1]
+MISIÓN DE MOTORISTA 1
-[MEA1_G]
-Coge mi coche, búscale y tráelo aquí.
+[BIKE2]
+MISIÓN DE MOTORISTA 2
-[MEA1_H]
-¡Tengo una sorpresita para ese parásito chupasangre!
+[BIKE3]
+MISIÓN DE MOTORISTA 3
-[MEA2_A]
-Contraté a unos ladrones para que entraran en mi piso
+[GOAWAY1]
+Vuelve cuando hayas terminado con las misiones de la banda haitiana.
-[MEA2_C]
-Ahora los muy cabritos me han amenazado con delatarme
+[HAIT]
+LAS MISIONES DE LA BANDA HAITIANA
-[MEA2_D]
-si no les doy una parte.
+[HAIT1]
+MISIÓN HAITIANA 1
-[MEA2_E]
-¿Te lo puedes creer?
+[HAIT2]
+MISIÓN HAITIANA 2
-[MEA2_F]
-He dejado un coche dentro de la fábrica.
+[HAIT3]
+MISIÓN HAITIANA 3
-[MEA2_G]
-Ve a recogerles con él en su territorio, en el barrio rojo.
+[HAM3_6]
+~g~Utiliza el rifle de francotirador que te he dejado para cumplir tu tarea.
-[MEA2_H]
-Luego tráelos a la fábrica para que conozcan la opinión de Marty.
+[ROCK]
+LAS MISIONES DE LA BANDA DE ROCK
-[MEA3_A]
-El negocio se irá a pique si no consigo un pastizal muy pronto.
+[ROK1_4]
+~g~De acuerdo, creo que esto es lo que andabais buscando...
-[MEA3_B]
-Mi esposa tiene un seguro de vida y ella no ha hecho más que vaciarme los bolsillos.
+[ROK1_1E]
+~g~¡Costará más de lo que tienes!
-[MEA3_C]
-He dejado un coche donde siempre.
+[ROK1_1F]
+~g~Vuelve cuando tengas el dinero.
-[MEA3_D]
-Ve a por a mi esposa a Classic Nails y tráela a la fábrica.
+[RBM2_6]
+~g~¡Guau! ¡Ella es un tío, detenle!
-[MEA4_A]
-Mierda, ¡la he liado!
+[ROCK3]
+MISIONES DE LA BANDA DE ROCK 3
-[MEA4_B]
-Resulta que mi esposa salía con uno al que debo dinero.
+[RBM3_5]
+~g~Lleva a los Love Fist al escenario.
-[MEA4_C]
-¡Se ha cabreado y ahora quiere vengarse!
+[CUBANM]
+LAS MISIONES DE LA BANDA CUBANA
-[MEA4_E]
-y piensa que voy a devolverle el dinero.
+[CUBAN1]
+MISIÓN CUBANA 1
-[MEA4_F]
-Pero creo...
+[CUBAN2]
+MISIÓN CUBANA 2
-[MEA4_G]
-¡que los perros de Liberty van a disfrutar de un sabor nuevo este mes!
+[CUB2_10]
+~r~¡Se supone que debes matar a haitianos, no a cubanos!
-[WELCOME]
-BIENVENIDO A
+[CUBAN3]
+MISIÓN CUBANA 3
-[HM1_2]
-~g~Hazte con un vehículo y recuerda que sólo cuentan las muertes a tiros desde el coche.
+[CUBAN4]
+MISIÓN CUBANA 4
-[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~.
+[PROT]
+MISIONES DE PROTECCIÓN
-[LRQC_1]
-Asuka y yo tenemos que hablar...
+[PORN]
+MISIONES PORNO
-[LRQC_2]
-¿Por qué no te das una vuelta?
+[PORN1]
+MISIÓN PORNO 1
-[LRQC_3]
-Necesitarás un escondite.
+[POR1_03]
+~r~¡Candy está muerta!
-[LRQC_4]
-Hay un almacén en la orilla de Belleville que podría servirte.
+[PORN2]
+MISIÓN PORNO 2
-[LRQC_5]
-Regresa a mi apartamento cuando estés listo
+[PORN3]
+MISIÓN PORNO 3
-[LRQC_6]
-y podremos tener una charla.
+[PORN4]
+MISIÓN PORNO 4
-[JM6_5]
-~g~Necesitas un vehículo de fuga, ¡idiota!
+[PHIL]
+MISIONES DE PHIL
-[JM2_F]
-Si necesitas una pipa, ve a la parte de atrás del Ammu-Nation que está enfrente del metro.
+[PHIL1]
+MISIÓN DE PHIL 1
-[LOVE4_7]
-~g~Hay un edificio en construcción en Staunton Island, puede que hayan llevado el paquete allí.
+[PHIL2]
+MISIÓN DE PHIL 2
-[LOVE4_8]
-~g~Necesitarás un coche para abrir el garaje.
+[PIZ1_A]
+MISIÓN DEL REPARTIDOR DE PIZZAS
-[TSCORE]
-GANANCIAS: ~1~ $
+[CNTBUY1]
+Compra de la imprenta: ~1~ $
-[AM1_9]
-~r~¡Salvatore ha vuelto a meterse en el club de Luigi!
+[CARBUY]
+Compra del salón de coches: ~1~ $
-[AM1_6]
-~g~Si te dejas ver por el club de Luigi, ¡la mafia te descubrirá!
+[PORNBUY]
+Compra del estudio cinematográfico: ~1~ $
-[TM2_3]
-~g~¡Es una trampa! ¡Liquidadlos a todos!
+[ICEBUY]
+Compra de la fábrica de helados: ~1~ $
-[FM4_1]
-Soy María. ¡El coche es una trampa! Estoy en el lado sur del puente Callahan.
+[TAXIBUY]
+Compra de la empresa de taxis: ~1~ $
-[JM1_7]
-~g~¡Cierra la puerta del coche o se dará cuenta!
+[BANKBUY]
+Compra del Malibú: ~1~ $
-[KM5_1]
-~g~¡TRAFICANTE LIQUIDADO!
+[BOATBUY]
+Compra del astillero: ~1~ $
-[KM5_6]
-~g~Debes matar a al menos 8 traficantes jamaicanos.
+[PRNT_NO]
+No puedes comprar la imprenta en este momento, vuelve más tarde.
-[KM5_7]
-~g~¡Mátalos rápido! En cuanto vendan el SPANK se retirarán de las calles.
+[CAR_NO]
+No puedes comprar el salón de coches en este momento, vuelve más tarde.
-[RM3_8]
-~r~¡El coche es un señuelo!
+[PORN_NO]
+No puedes comprar el estudio cinematográfico en este momento, vuelve más tarde.
-[LM3_8]
-Hola, soy Joey.
+[ICE_NO]
+No puedes comprar la fábrica de helados en este momento, vuelve más tarde.
-[LM3_9]
-Luigi dijo que eras de fiar, así que vuelve más tarde,
+[TAXI_NO]
+No puedes comprar la compañía de taxis en este momento, vuelve más tarde.
-[KM3_5]
-~g~Toca el claxon para empezar con el trato.
+[BANK_NO]
+No puedes comprar el Malibú en este momento, vuelve más tarde.
-[LOVE7]
-'LA DESAPARICIÓN DE LOVE'
+[BOAT_NO]
+No puedes comprar el astillero en este momento, vuelve más tarde.
-[LOVE2_5]
-~g~¡Kenji ha palmado! ¡Sal de Newport y deshazte del coche!
+[COL2_6]
+¡Alto, cerdo imperialista americano!
-[AS2_11]
-~g~¡~1~ DE 9!
+[COL2_6B]
+Eso es propiedad del gobierno francés.
-[GARAGE1]
-~g~Sal del vehículo y aléjate caminando.
+[COL2_6C]
+¡y se acabó!
-[KM3_11]
-~g~El cártel ha sido atacado y el maletín no ha sido recuperado.
+[COL3_A]
+Thomas, aprecio que vinieses.
-[KM3_12]
-~g~Mata a todos los colombianos, destruye los vehículos y recupera el maletín.
+[COL3_B]
+Perdóname por ir directamente al asunto.
-[KM3_13]
-~g~Lleva el maletín de vuelta al casino.
+[COL3_C]
+Diaz me ha pedido que supervise una transacción de un negocio menor.
-[RM5_6]
-~g~¡Ha salido de la ambulancia! ¡Cárgate su escayola con un vehículo o una explosión!
+[COL3_D]
+Esperemos que vaya mejor que la última vez.
-[PBOAT_1]
-Pulsa ~h~~k~~PED_FIREWEAPON~~w~ para disparar los cañones de la lancha.
+[COL3_E]
+Por eso es por lo que pensé en ti, amigo mío.
-[PBOAT_2]
-Pulsa ~h~~k~~PED_FIREWEAPON~~w~ para disparar los cañones de la lancha.
+[COL3_F]
+He dejado algo de protección en el aparcamiento.
-[DIAB1_B]
-Al habla El Burro, de los Diablos.
+[COL3_G]
+Recógele y luego id a ver a los hombres de Diaz en el punto de entrega.
-[DIAB1_D]
-Eres nuevo en Liberty, pero ya te estás ganando una reputación en las calles.
+[COL4_2]
+¡No lo sé, señor!
-[DIAB1_E]
-Hay una carrera que empezará junto a la sala Clásica, cerca del puente Callahan.
+[COL4_5]
+¡Señor, sí, señor!
-[DIAB1_F]
-Consíguete un buen carro y el primero que pase por todos los puntos de control se llevará el premio.
+[COL4_10]
+Vamos a comer unos donuts.
-[HM2_1]
-Usa los coches teledirigidos para destruir los furgones blindados. Pulsa ~h~~k~~PED_FIREWEAPON~ ~w~para detonarlos.
+[COL4_16]
+¡Señor! ¡Moviendo el vehículo, señor!
-[HM2_1A]
-Usa los coches teledirigidos para destruir los furgones blindados. Pulsa ~h~~k~~PED_FIREWEAPON~ ~w~para detonarlos.
+[COL4_25]
+¡Iniciada autodestrucción del vehículo!
-[HM2_2]
-~r~¡No has destruido todos los furgones blindados!
+[COL5_6]
+Mercedes, esa chica me matará.
-[HM2_6]
-~g~¡Te has cargado un furgón blindado!
+[COL5_8]
+¡Maldita cucaracha!
-[RM3_A]
-Conozco a un pez gordo de la ciudad, un tipo muy cándido,
+[COL5_5]
+¡Morid, cerdos franceses!
-[RM3_H]
-con, digamos... gustos exóticos y el dinero para pagárselos.
+[CNT2_1]
+Matadle.
-[RM3_B]
-Está involucrado en un asunto legal y la fiscalía tiene fotos de él muy comprometedoras
+[CNT2_2]
+¡Conseguid las planchas!
-[RM3_C]
-en una fiesta en la morgue o algo así.
+[CNT2_3]
+¡Proteged al mensajero!
-[LOVE6_A]
-Una lección sobre negocios, amigo mío:
+[FINKILL]
+¡De acuerdo, chicos, matadle!
-[LOVE6_E]
-Si tienes una mercancía única, todo el mundo tratará de arrebatártela,
+[FIN_1A]
+¡Ven aquí, traidor, pedazo de mierda!
-[LOVE6_C]
-Unos SWAT han acordonado la zona donde se encuentran mi socio y el paquete.
+[FIN_1B]
+¡Vas a caer, mamón traicionero!
-[LOVE6_D]
-Ve allí, recoge la furgoneta y haz de señuelo.
+[FIN_1C]
+¡Éste es el último baile para Lance Vance!
-[LOVE6_F]
-Mantenlos ocupados para que él pueda escapar.
+[FIN_2B]
+¡Oh, eso crees tú!
-[AM3_C]
-Ahora mismo estará en la bahía. ¡Roba una lancha de la policía y hunde su carrera!
+[FIN_2C]
+¡Ya tuve suficiente de eso en la escuela!
-[FESZ_UC]
-CANCELAR
+[FIN_3]
+Ahora no hay nadie para cubrirte el trasero, ¿eh, Tommy?
-[FEDS_SM]
-L1, R1 - CAMBIAR MENÚ
+[FIN_4]
+Eres historia, Tommy, historia.
-[FEDS_AS]
-;= - CAMBIAR SELECCIÓN
+[FIN_5]
+Escogiste el lado equivocado, Lance...
-[FEDSAS2]
-<> - CAMBIAR SELECCIÓN
+[FIN_6]
+Sonny está arriba con la caja fuerte y mi dinero...
-[FEDS_SS]
-L1,R1 - CAMBIAR SELECCIÓN
+[FIN_10]
+¿Sonny? ¡Sonny! ¡Voy por ti!
-[FEDSSC1]
-; - ACELERAR
+[FIN_11A]
+Me arrebataste quince años, Sonny...
-[FEDSSC2]
-= - RALENTIZAR
+[FIN_11B]
+¡Y ahora voy a hacértelo pagar!
-[MEA2_3]
-~g~Lleva el coche de vuelta a la fábrica.
+[FIN_12A]
+Todavía no lo captas, ¿verdad?
-[RM1_3]
-~r~¡McAffrey se ha escapado!
+[FIN_12B]
+Eres de mi propiedad, Tommy.
-[RM1_4]
-~g~¡Has usado todas las granadas! ¡Consigue más en la tienda Ammu-Nation!
+[FIN_12C]
+¡Esos quince años eran míos para gastarlos!
-[RM1_5]
-~g~¡Vuelve y quema la casa franca!
+[FIN_13]
+Atrapadle chicos, nunca comprendió nada.
-[RM6_4]
-~g~Ve al almacén a por el cargamento de Ray.
+[RACES_4]
+3
-[RM6_5]
-~g~La CIA vigila el puente, busca otro camino.
+[RACES_5]
+2
-[HM2_F]
-y cargarte sus blindados.
+[RACES_6]
+1
-[HM_4]
-'FIEBRE DEL PLATINO'
+[RACES_7]
+¡ADELANTE!
-[MEA4_B7]
-Pero si pasas por mi oficina...
+[RACES_9]
+Tiempo: ~1~:~1~
-[MEA3_B4]
-¿Marty quiere verme? Bueno, pues que sea rápido, porque tengo que ir a la peluquería.
+[RACES]
+TIEMPO:
-[KM3_7]
-¡Es una trampa de la yakuza, man!
+[RACES17]
+Nuevo mejor tiempo: ~1~:~1~
-[FES_LOF]
-Fallo al cargar.
+[RACES18]
+HAS GANADO: ~1~ $
-[P1INSA]
-La Memory Card (PS2) insertada en la ranura para MEMORY CARD 1 tiene ~1~ KB de espacio disponible. Necesitas ~1~ KB para guardar.
+[RACES20]
+Nuevo mejor tiempo: ~1~:0~1~
-[P1INSN]
-La Memory Card (PS2) insertada en la ranura para MEMORY CARD 1 no tiene espacio suficiente. Por favor, borra algunos archivos.
+[RACES21]
+Tiempo: ~1~:0~1~
-[FES_SLO]
-ARCHIVO
-[FES_ISC]
-ESTÁ DAÑADO
+[RCH1_2]
+~g~Los CONTROLES están esparcidos a lo largo del aeropuerto.
-[FESZ_TI]
-ARCHIVO Z1
+[RCH1_5]
+Tiempo:
-[FESZ_SA]
-Guardar partida
+[RCRC1_2]
+~g~¡Ve a la parrilla de salida!
-[P1NOIN]
-No hay una Memory Card (PS2) insertada en la ranura para MEMORY CARD 1.
+[RCRC1_4]
+~g~3
-[P1INSE]
-Memory Card (PS2) insertada en la ranura para MEMORY CARD 1.
+[RCRC1_5]
+~g~2
-[MC_LDFL]
-¡Fallo al cargar!
+[RCRC1_6]
+~g~1
-[MC_NWRE]
-Reiniciando partida.
+[RCRC1_7]
+~g~¡ADELANTE!
-[LOVE6_3]
-~g~Tienes ~1~ segundos para volver al Securicar antes de fracasar la misión.
+[RCRC1_8]
+~g~Tiempo de carrera: ~1~ segundos
-[LOVE6_4]
-~r~¡Has abandonado el Securicar señuelo!
+[RCPL1_1]
+~g~Compite en una CARRERA DE PUNTOS DE CONTROL con otros tres Barón RC.
-[HELP1]
-Detente en el centro del marcador azul.
+[RCPL1_2]
+~g~Debes atravesar la ~o~CORONA DEL CENTRO ~g~para pasar con éxito un punto de control.
-[HELP12]
-Entra en el marcador azul para comenzar una misión.
+[RCPL1_3]
+~g~¡Ve ahora a la parrilla de salida!
-[HJSTAT]
-Distancia: ~1~,~1~ m. Altura: ~1~,~1~ m. Vueltas: ~1~. Rotación: ~1~_.
+[ICC1_O]
+¿Qué pasa contigo?
-[HJSTATW]
-Distancia: ~1~,~1~ m. Altura: ~1~,~1~ m. Vueltas: ~1~. Rotación: ~1~_. ¡Y qué buen aterrizaje!
+[FEA_2SP]
+2 altavoces
-[DIAB1_5]
-TIEMPO DE CARRERA:
+[FEA_4SP]
+Más de 2 altavoces
-[LOVE3_4]
-~r~¡Has destruido la avioneta!
+[FEA_EAR]
+Auriculares
-[F_FAIL1]
-¡Misión del camión de bomberos terminada!
+[FEA_NAH]
+NO HAY HARDWARE DE AUDIO
-[F_CANC]
-~r~¡Misión del camión de bomberos cancelada!
+[FET_APP]
+APLICAR
-[F_EXTIN]
-INCENDIOS:
+[FES_SKN]
+NOMBRE DE APARIENCIA
-[A_COMP1]
-¡Misiones de conductor de ambulancia completadas!
+[FES_DAT]
+FECHA
-[A_CANC]
-~r~¡Misión de conductor de ambulancia cancelada!
+[FES_SET]
+Utilizar apariencia
-[A_COMP3]
-¡Misiones de conductor de ambulancia completadas! ¡Ahora no te cansarás al esprintar!
+[FET_DEF]
+Restaurar valores por defecto
-[ATUTOR]
-Pulsa ~h~~k~~TOGGLE_SUBMISSIONS~~w~ para activar o desactivar las misiones de conductor de ambulancia.
+[FESZ_QZ]
+¿Seguro de que quieres guardar esta partida?
-[ATUTOR3]
-Pulsa ~h~~k~~TOGGLE_SUBMISSIONS~~w~ para activar o desactivar las misiones de conductor de ambulancia.
+[FES_SCG]
+¿Guardar la partida actual?
-[ALEVEL]
-Nivel de misión de conductor de ambulancia: ~1~
+[FES_LCG]
+¿Cargar la partida y continuar jugando?
-[A_FAIL1]
-Misión de conductor de ambulancia terminada.
+[FEC_FIR]
+Disparar
-[FEST_HA]
-Mayor nivel de misión de cond. de ambulancia
+[FEC_NWE]
+Siguiente arma
-[A_SAVES]
-PERSONAS SALVADAS: ~1~
+[FEC_PWE]
+Arma anterior
-[C_KILLS]
-CRIMINALES ABATIDOS: ~1~
+[FEC_FOR]
+Avanzar
-[HM1_B]
-Tengo un problema, me la están liando.
+[FEC_BAC]
+Retroceder
-[AM2_A]
-La muerte de Salvatore es una placentera noticia,
+[FEC_LEF]
+Izquierda
-[AM2_A2]
-eres un asesino eficaz. Eso me gusta en un hombre.
+[FEC_RIG]
+Derecha
-[AM2_B]
-Éste es mi hermano Kenji.
+[FEC_ZIN]
+Acercar zoom
-[AM2_C]
-Asuka tiene un trabajito para ti, pero cuando acabes, pásate por mi casino y podremos hablar.
+[FEC_ZOT]
+Alejar zoom
-[AM2_D]
-Típico de Kenji, siempre está detrás de mis juguetes.
+[FEC_EEX]
+Entrar y salir
-{ The voiced dialogue doesn't match the English subtitle for the next string }
+[FEC_RAD]
+Radio
-[AM2_E]
-Mi contacto en la policía me dice que el FBI ha montado un operativo de vigilancia
+[FEC_SUB]
+Misión secundaria
-{ The voiced dialogue doesn't match the English subtitle for the next string }
+[FEC_CMR]
+Cambiar cámara
-[AM2_E2]
-en varios puntos de la ciudad.
+[FEC_JMP]
+Saltar
-{ The voiced dialogue doesn't match the English subtitle for the next string }
+[FEC_SPN]
+Esprintar
-[AM2_F]
-No tenemos tiempo para contactar con nadie y evitar que nos incriminen.
+[FEC_HND]
+Freno de mano
-{ The voiced dialogue doesn't match the English subtitle for the next string }
+[FEC_LOL]
+Mirar hacia la izquierda
-[AM2_G]
-Liquida a esos polis espías, pero cuidado: tendrán apoyo.
+[FEC_LOR]
+Mirar hacia la derecha
-[F_START]
-~g~Se ha avistado un vehículo en llamas en: ~a~. Ve y extingue el fuego.
+[FEC_NTR]
+Siguiente objetivo
-[AM4_1A]
-Ve a la cabina al oeste del parque Belleville.
+[FEC_PTT]
+Objetivo anterior
-[AM4_1B]
-Ve a la cabina del campus de Liberty.
+[FEC_LBA]
+Mirar detrás
-[AM4_1C]
-Ve a la cabina al sur del parque Belleville.
+[FEC_CEN]
+Centrar cámara
-[AM4_1D]
-Ven a verme a los baños públicos del parque.
+[FET_CFT]
+A PIE
-[HJSTATF]
-Distancia: ~1~ pies. Altura: ~1~ pies. Vueltas: ~1~. Rotación: ~1~_.
+[FET_CCR]
+EN COCHE
-[HJSTAWF]
-Distancia: ~1~ pies. Altura: ~1~ pies. Vueltas: ~1~. Rotación: ~1~_. ¡Y qué buen aterrizaje!
+[FET_CAC]
+ACCIÓN
-[HM1_F]
-Pero ojo, también habrá Jacks que se creerán que vas a por ellos.
+[FEC_IBT]
+-
-[HM1_D]
-Se llaman ''Nines'', van de púrpura, y cada día en el que se hacen notar
+[FEC_MXO]
+MXB1
-[HM1_G]
-es otro día más que los Jacks parecemos blandos.
+[FEC_MXT]
+MXB2
-[MEA2_B]
-y robaran cuanto pillaran para que yo pudiera reclamar a la aseguradora.
+[FEC_UNB]
+ILIMITADO
-[TM3_H]
-Buen trabajo, chaval, muy bueno.
+[FEC_TFL]
+Mirar a izquierd+Torreta L
-[TM3_I]
-Vente, te presentaré al Don.
+[FEC_TFR]
+Mirar a derecha+Torreta R
-[TM3_J]
-¡Hola! ¡Luigi!
+[FEC_MWF]
+RUEDA DEL RATÓN ARRIBA
-[TM3_K]
-Mis chicas te han echado de menos, Salvatore. Hace bastante que no te vemos.
+[FEC_MWB]
+RUEDA DEL RATÓN ABAJO
-[TM3_L]
-Diles que en cuanto resolvamos este desafortunado incidente
+[FEC_ORR]
+o
-[TM3_M]
-iremos todos al club para celebrarlo, ¿vale?
+[FEC_NUS]
+NO UTILIZADO
-[TM3_N]
-¡Mi niño!
+[FEC_LUD]
+Mirar arriba
-[TM3_N2]
-¿Cómo estás, papá?
+[FEC_LDU]
+Mirar abajo
-[TM3_O]
-¿Has encontrado ya una buena mujer?
+[FEC_CMP]
+COMBO: MIRAR I+d
-[TM3_P]
-Tu madre, que en paz descanse, se retorcería en la tumba
+[LAW_1A]
+law_1a
-[TM3_Q]
-si te viera sin una mujer.
+[LAW_1B]
+law_1b
-[TM3_R]
-Lo sé, papá, estoy en ello.
+[LAW_2A]
+law_2a
-[TM3_S]
-¡Toni! ¿Cómo está tu madre?
+[LAW_2B]
+law_2b
-[TM3_T]
-Es una gran mujer, ¿sabes? Fuerte, ''firenze''.
+[FEH_STA]
+ESTADÍSTICAS
-[TM3_U]
-Está bien, estupendamente.
+[FEH_LOA]
+CARGAR
-[TM3_V]
-Fantástico, fantástico. Bien, muchachos, entrad mientras yo hablo con nuestro nuevo amigo.
+[FEH_CON]
+CONTROLES
-[TM3_W]
-Tienes un gran futuro por delante, hijo mío...
+[FEH_AUD]
+SONIDO
-[RM1_A]
-¡Ese canalla de McAffrey...! ¡Aceptó más sobornos que nadie,
+[FEH_DIS]
+PANTALLA
-[RM1_B]
-se piensa que le darán la pensión completa si se convierte en un testigo de cargo!
+[FEH_LAN]
+IDIOMA
-[RM1_C]
-¡Y ha cantado!
+[FEH_SGA]
+INICIAR NUEVA PARTIDA
-[RM4_B]
-Tenemos que cerrarle la boca para siempre.
+[FEO_CON]
+Configuración del mando
-[RM4_E]
-¡Quiero que deje de comer peces y se vaya a dormir con ellos!
+[FEO_AUD]
+Configuración de sonido
-[LOVE3_B]
-Esta noche, durante su aproximación al aeropuerto, una avioneta sobrevolará la bahía.
+[FEO_DIS]
+Configuración de pantalla
-[LOVE4_D]
-Desgraciadamente, las autoridades aduaneras incautaron la avioneta y la comenzaron a desmontar
+[FEO_LAN]
+Configuración de idioma
-[LOVE4_H]
-hasta que yo intervine a través de mi fortuna.
+[FEO_PLA]
+Configuración del jugador
-[LOVE4_E]
-Cruza el puente hacia Shoreside Vale y ve al Aeropuerto Internacional Francis.
+[FET_PS]
+CONFIGURACIÓN DE APARIENCIA
-[GTAB_A]
-Oye, saquemos esto de aquí. Dios sabrá lo que será,
+[FEA_OUT]
+Salida
-[GTAB_B]
-pero él lo quiere a toda costa, así que tendrá algún valor.
+[FEA_ST]
+Estéreo
-[GTAB_C]
-¡¿Qué diablos?!
+[FEA_DTS]
+DTS
-[GTAB_D]
-¡TÚ!
+[FEA_RSS]
+Emisora de radio
-[GTAB_E]
-¡Tranquilo, amigo! ¡No es nada! ¡No es nada!
+[FEA_NON]
+RADIO APAGADA
-[GTAB_F]
-¡Te dejé desangrándote entre la basura!
+[FEA_FM0]
+WILDSTYLE
-[GTAB_G]
-No dispares, amigo. No hay problema. Somos amigos. Mira, coge esto.
+[FEA_FM1]
+FLASH FM
-[GTAB_H]
-¡No seas cagón!
+[FEA_FM2]
+KCHAT
-[GTAB_I]
-¡No tenemos elección, nena!
+[FEA_FM3]
+FEVER 105
-[GTAB_J]
-¡Siempre la hay, imbécil!
+[FEA_FM4]
+VROCK
-[GTAB_K]
-¡Siento mucho lo de esa perra enloquecida, todas son iguales...! ¿Por favor?
+[FEA_FM5]
+VCPR
-[GTAB_L]
-Así que la zorra se fue.
+[FEA_FM7]
+EMOTION 98.3
-[GTAB_M]
-Pero me has hecho un favor,
+[FEA_FM8]
+WAVE 103
-[GTAB_N]
-no eres el único que tiene una cuenta pendiente con el cártel...
+[FED_BRI]
+Brillo
-[GTAB_O]
-¡Este gusano mató a mi hermano!
+[FED_TRA]
+Estelas
-[GTAB_P]
-¡Nunca maté a ningún yakuza!
+[FED_SUB]
+Subtítulos
-[GTAB_Q]
-¡Mientes! Todos vimos al asesino del cártel.
+[FED_WIS]
+Formato 16:9
-[GTAB_R]
-¡Vamos a cazaros y a mataros a todos, perros colombianos!
+[FED_POS]
+Posición de la pantalla
-[GTAB_S]
-Me trabajaré a nuestro querido amigo para extraerle información y un poco de placer.
+[FED_RDR]
+RADAR
-[GTAB_T]
-Tú, ven más tarde, estoy segura de que voy a necesitar tus servicios.
+[FED_HUD]
+MODO HUD
-[GTAB_U]
-¡Por favor, amigo! ¡No me dejes con ella, esa chica está loca! ¿Amigo? ¡Oye, amigo! ¡Amigo...!
+[FED_RDB]
+SOLO ICONOS
-[LOVE5_A]
-Estás demostrando ser una inversión segura, algo muy raro en estos días.
+[FE_MLG]
+LEYENDA DEL MAPA
-[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.
+[FEI_SCR]
+Desplazarse
-[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.
+[FEP_RES]
+Continuar
-[FM1_Q1]
-¿Quieres un poco de diversión? ¿Un poco de... hmmm, de SPANK?
+[FEP_STG]
+Iniciar partida
-[FM1_R]
-Hola, Chico. No, sólo lo de siempre.
+[FEP_STA]
+Estadísticas
-[FM1_T]
-Gracias, Chico, nos vemos.
+[FEP_BRI]
+Resumen
-[FM1_W]
-Oye, tú, espera aquí y quédate pendiente del coche mientras yo voy a menear el esqueleto, ¿vale?
+[FEP_OPT]
+Opciones
-[FM1_X]
-¡Vale, tú, salgamos de aquí! ¡Uaaah!
+[FEP_QUI]
+Salir del juego
-[FM1_Q]
-¡Ay, mira, es mi chica favorita!
+[FES_LOA]
+Cargar partida
-[FM1_S1]
-Ey, deberías echar un vistazo a la fiesta del almacén en el lado este del muelle Atlantic.
+[FES_DEL]
+Borrar partida
-[FM1_U]
-Gracias y disfruta. Es buen material.
+[FEC_CSU]
+Configuración del controlador
-[FM1_V]
-¡Venga, tú, vamos a ver esa fiesta!
+[FEC_RED]
+Redefinir controles
-[FM1_SS]
-~r~ESCÁNER: ~g~Cuatro-cinco a todas las unidades: asistan redada de narcóticos en el muelle Atlantic.
+[FEC_MOU]
+Configuración del ratón
-[LOVE6_B]
-aun sin conocer su verdadera valía.
+[DISTGOL]
+Distancia recorrida en carro de golf (millas)
-[TM3_A1]
-~r~¡Joey está frito!
+[DISTGOM]
+Distancia recorrida en carro de golf (m)
-[TM3_A2]
-~r~¡Joey y Luigi han sido incinerados!
+[ST_FAVR]
+Estación de radio favorita
-[TM3_A3]
-~r~¡Joey, Luigi y Toni están calcinados!
+[ST_WSTR]
+estación de radio que menos te gusta
-[FM4_2]
-Mira, Salvatore cree que se la estamos jugando,
+[ST_FAVV]
+Vehículo favorito
-[FM4_3]
-así que te vendió al cártel para llegar a un trato.
+[ST_STAR]
+Número total de estrellas se busca conseguidas
-[FM4_4]
-No podía permitírselo, o sea, lo peor es...
+[ST_HEAD]
+Número de disparos a la cabeza
-[FM4_4B]
-que yo tengo la culpa, porque le dije que somos pareja.
+[ST_GANG]
+Banda que menos te gusta
-[FM4_5]
-¡No me preguntes por qué, no lo sé!
+[ST_STGN]
+Número total de estrellas se busca evadidas
-[FM4_6]
-Mira, la mafia te quiere muerto y yo también tengo que salir de aquí.
+[TYREPOP]
+Neumáticos reventados por disparos
-[FM4_6B]
-¡He visto demasiados asesinatos, demasiada sangre!
+[TYRESLA]
+Neumáticos rajados con una navaja
-[FM4_7]
-Es una amiga mía, ¿vale?, una vieja amiga... Es Asuka, es de fiar.
+[ST_BRK]
+Número de muertes en el anillo sangriento
-[FM4_8]
-Venga, dejémonos de discursos.
+[ST_LTBR]
+Mayor tiempo en el anillo sangriento (segs.)
-[FM4_9]
-Mejor nos vamos antes de que lleguen más italianos histéricos con intenciones menos amistosas.
+[ST_GNG1]
+Cubanos
-[CRED001]
-ROCKSTAR STUDIOS
+[ST_GNG2]
+Haitianos
-[CRED002]
-PRODUCTOR
+[ST_GNG3]
+Aspirantes callejeros
-[CRED003]
-LESLIE BENZIES
+[ST_GNG4]
+Pandilleros de Díaz
-[CRED004]
-DIRECTOR DE ARTE
+[ST_GNG5]
+Guardias de seguridad
-[CRED005]
-AARON GARBUT
+[ST_GNG6]
+Banda de motoristas
-[CRED006]
-DIRECCIÓN TÉCNICA
+[ST_GNG7]
+Banda de Vercetti
-[CRED007]
-OBBE VERMEIJ
+[ST_GNG8]
+Golfistas
-[CRED008]
-ADAM FOWLER
+[FEA_FM6]
+ESPANTOSO
-[CRED009]
-DISEÑO
+[ST_ASSI]
+Contratos de asesinato completados
-[CRED010]
-CRAIG FILSHIE
+[DISTBIK]
+Dist. Recorrida en moto (millas)
-[CRED011]
-WILLIAM MILLS
+[DISTBIM]
+Distancia recorrida en moto (m)
-[CRED012]
-CHRIS ROTHWELL
+[HOTEL]
+Ocean View
-[CRED013]
-JAMES WORRALL
+[KICK1_9]
+PUNTOS DE CONTROL:
-[CRED014]
-GUIÓN
+[FIN_B6]
+No tienes suficiente dinero para empezar esta misión.
-[CRED015]
-JAMES WORRALL
+[TEX3_9]
+~g~Recoge una bomba pasando con el helicóptero RC cerca de ella.
-[CRED016]
-PAUL KUROWSKI
+[HELP22]
+Ve a la señal de la casa verde que hay en el radar.
-[CRED017]
-DAN HOUSER
+[FES_FMS]
+Éxito al formatear. Selecciona Aceptar para continuar.
-[CRED018]
-PERSONAJES
+[FES_SSC]
+Éxito al guardar. Selecciona Aceptar para continuar.
-[CRED019]
-IAN MCQUE
+[FES_DSC]
+Éxito al borrar. Selecciona Aceptar para continuar.
-[CRED020]
-ANIMACIÓN Y DIRECCIÓN
+[FESZ_QC]
+¿Deseas sobreescribir esta partida guardada dañada?
-[CRED021]
-ALEX HORTON
+[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.
-[CRED022]
-LEE MONTGOMERY
+[FET_SG]
+GUARDAR PARTIDA
-[CRED023]
-DISEÑO DE VEHÍCULOS
+[FEH_BRI]
+INFORME
-[CRED024]
-PAUL KUROWSKI
+[FEH_MAP]
+MAPA
-[CRED025]
-ARTISTAS
+[FEM_OK]
+Aceptar
-[CRED026]
-KEIRAN BAILLIE
+[FEC_CRO]
+Agacharse
-[CRED027]
-ADAM COCHRANE
+[FEC_CR3]
+Agacharse (Botón L3)
-[CRED028]
-GARY MCADAM
+[FEC_SMT]
+Sub-misión
-[CRED029]
-MICHAEL PIRSO
+[FEC_SM3]
+Sub-misión (Botón R3)
-[CRED030]
-ANDREW SOOSAY
+[FEC_RSC]
+Emisoras de radio
-[CRED031]
-ALISDAIR WOOD
+[ST_PR01]
+Aviador
-[CRED032]
-PROGRAMADORES
+[ST_PR02]
+Piloto del ejército
-[CRED033]
-ALAN CAMPBELL
+[ST_PR03]
+Oficial piloto
-[CRED034]
-MARK HANLON
+[ST_PR04]
+Cabo
-[CRED035]
-ANDRZEJ MADAJCZYK
+[ST_PR05]
+Teniente
-[CRED036]
-ALEXANDER ROGER
+[ST_PR06]
+Sargento
-[CRED037]
-GRAEME WILLIAMSON
+[ST_PR07]
+Capitán
-[CRED038]
-MÚSICA
+[ST_PR08]
+Biggs
-[CRED039]
-CRAIG CONNER
+[ST_PR09]
+Wedge
-[CRED040]
-STUART ROSS
+[ST_PR10]
+Barón Rojo
-[CRED041]
-DISEÑO DE SONIDO Y MÁSTER
+[ST_PR11]
+Ganso
-[CRED042]
-ALLAN WALKER
+[ST_PR12]
+Víbora
-[CRED043]
-PROGRAM. DE AUDIO
+[ST_PR13]
+Jester
-[CRED044]
-RAYMOND USHER
+[ST_PR14]
+Chappy
-[CRED045]
-DIRECTOR DE PRUEBAS
+[ST_PR15]
+Iceman
-[CRED046]
-CRAIG ARBUTHNOTT
+[ST_PR16]
+Maverick
-[CRED047]
-JEFES DE PRUEBAS
+[ST_PR17]
+Negado
-[CRED048]
-ANDY DUTHIE
+[ST_PR18]
+General de la Armada aérea
-[CRED049]
-JOHN HAIME
+[ST_PR19]
+As
-[CRED050]
-NEIL CORBETT
+[FET_LG]
+CARGAR JUEGO
-[CRD050A]
-PROBADORES
+[CAR_EXP]
+Vehículos destruidos
-[CRED051]
-GRAEME JENNINGS
+[BOA_EXP]
+Barcos destruidos
-[CRED052]
-DAVID MURDOCH
+[HEL_DST]
+Aviones y helicópteros destruidos
-[CRED053]
-DAVID BEDDOES
+[STFT_01]
+Tiempo más rápido de ''Moto con llantas de aleación''
-[CRED054]
-EDWIN SMITH
+[STFT_02]
+Tiempo más rápido de ''El conductor''
-[CRED055]
-MARK FLETT
+[STFT_03]
+Tiempo más rápido en el Circuito de Tierra
-[CRED056]
-MICHAEL SUTHERLAND
+[STFT_04]
+Tiempo más rápido en la Carrera de Aviones RC
-[CRED057]
-SOPORTE TÉCNICO
+[STFT_05]
+Tiempo más rápido en la Carrera de Coches RC
-[CRED058]
-LORRAINE ROY
+[STFT_06]
+Tiempo más rápido Control del Helicóptero RC
-[CRED059]
-CHRISTINE CHALMERS
+[STFT_07]
+Tiempo más rápido en ''Velocidad terminal''
-[CRED060]
-ROCKSTAR
+[STFT_08]
+Tiempo más rápido en ''Ocean Drive''
-[CRED061]
-PRODUCTOR EJECUTIVO
+[STFT_09]
+Tiempo más rápido en ''Carrera por el borde''
-[CRED062]
-SAM HOUSER
+[STFT_10]
+Tiempo más rápido en ''Capital Cruise''
-[CRED063]
-PRODUCTOR
+[STFT_11]
+Tiempo más rápido en ''¡Tour!''
-[CRED064]
-DAN HOUSER
+[STFT_12]
+Tiempo más rápido en ''Aguante en V.C.''
-[CRED065]
-DIRECTOR DE DESARROLLO
+[STHC_01]
+Puntuación más alta en el campo de tiro
-[CRED066]
-JAMIE KING
+[STHC_02]
+Mejor porcentaje de impactos en el campo de tiro
-[CRED067]
-PRODUCTOR TÉCNICO
+[STHC_03]
+Ventas de droga realizadas
-[CRED068]
-GARY J. FOREMAN
+[HELP24]
+Ahora puedes aceptar trabajos del Coronel.
-[CRED069]
-PRODUCTOR ASOCIADO
+[HELP25]
+Ahora puedes aceptar trabajos de Avery Carrington.
-[CRED070]
-JEREMY POPE
+[HELP29]
+Puedes visitar la tienda de ropa cuando no estés en una misión.
-[CRED071]
-SUPERVISOR MUSICAL
+[HELP30]
+Cuando compres ropa nueva, tu nivel de se busca se establecerá en cero.
-[CRED072]
-TERRY DONOVAN
+[ASM4_24]
+distancia:
-[CRED073]
-EQUIPO DE PRODUCCIÓN DE ROCKSTAR
+[RBM1_6]
+~g~Lleva a Mercedes y el ''love juice'' a la banda en el estudio de grabación.
-[CRED074]
-TERRY DONOVAN
+[HELP31]
+Para hacer una pasada, mira primero a izquierda o derecha con ~k~~VEHICLE_LOOKLEFT~ o ~k~~VEHICLE_LOOKRIGHT~.
-[CRED075]
-JENNIFER KOLBE
+[HELP34]
+Para realizar una pasada deberás tener un subfusil.
-[CRED076]
-JENEFER GROSS
+[STRIP_1]
+~r~No tienes dinero suficiente, tacaño miserable.
-[CRED077]
-LAURA PATERSON
+[EXIT_1]
+Pulsa ~k~~PED_SPRINT~ para salir.
-[CRED078]
-JEFF CASTANEDA
+[ASM1_B]
+Encontrará su siguiente trabajo pegado con cinta adhesiva bajo el teléfono.
-[CRED079]
-CHRIS CARRO
+[ASM1_C]
+Tengo más trabajo para usted que requerirá tomar ''el volante'' de la situación.
-[CRED080]
-ADAM TEDMAN
+[SCARF]
+Apartamento 3c
-[CRED081]
-JUNG KWAK
+[LAW4_10]
+¡Mamones de directores!
-[CRED082]
-BRIAN WOOD
+[RCH1_6]
+~g~Utiliza el helicóptero RC para pasar por los puntos de control dispersados por el aeropuerto.
-[CRED083]
-PAUL YEATES
+[RCH1_9]
+~b~TIEMPO TOTAL: ~1~:~1~
-[CRED084]
-STANTON SARJEANT
+[RCH1_10]
+~b~TIEMPO TOTAL: ~1~:0~1~
-[CRED085]
-V.P. DE MÁRKETING
+[WHEEL01]
+DOBLE BONIFICACIÓN EN DOS RUEDAS: ~1~ $ Distancia: ~1~,~1~m Tiempo: ~1~ segundos
-[CRED086]
-TERRY DONOVAN
+[WHEEL02]
+DOBLE BONIFICACIÓN EN DOS RUEDAS: ~1~ $ Distancia: ~1~ pies Tiempo: ~1~ segundos
-[CRED087]
-COORDINADOR TÉCNICO
+[WHEEL03]
+BONIFICACIÓN EN DOS RUEDAS: ~1~ $ Tiempo: ~1~ segundos
-[CRED088]
-BRANDON ROSE
+[WHEEL04]
+BONIFICACIÓN EN DOS RUEDAS: ~1~ $ Distancia: ~1~,~1~m
-[CRED089]
-DIRECTOR DE CONTROL DE CALIDAD
+[WHEEL05]
+BONIFICACIÓN EN DOS RUEDAS: ~1~ $ Distancia: ~1~ pies
-[CRED090]
-JEFF ROSA
+[WHEEL06]
+BONIFICACIÓN EN CABALLITO: ~1~ $ Distancia: ~1~,~1~m Tiempo: ~1~ segundos
-[CRED091]
-JEFE DE ANÁLISIS
+[WHEEL07]
+BONIFICACIÓN EN CABALLITO: ~1~ $ Distancia: ~1~ pies Tiempo: ~1~ segundos
-[CRED092]
-ADAM DAVIDSON
+[WHEEL08]
+BONIFICACIÓN EN CABALLITO: ~1~ $ Tiempo: ~1~ segundos
-[CRED093]
-ANALISTA DEL JUEGO
+[WHEEL09]
+BONIFICACIÓN EN CABALLITO: ~1~ $ Distancia: ~1~,~1~m
-[CRED094]
-RICHARD HUIE
+[WHEEL10]
+BONIFICACIÓN EN CABALLITO: ~1~ $ Distancia: ~1~ pies
-[CRED095]
-EQUIPO DE PRUEBAS
+[WHEEL11]
+BONIFICACIÓN EN PARADA MÁS LARGA: ~1~ $ Distancia: ~1~,~1~m Tiempo: ~1~ segundos
-[CRED096]
-LANCE WILLIAMS
+[WHEEL12]
+BONIFICACIÓN EN PARADA MÁS LARGA: ~1~ $ Distancia: ~1~ pies Tiempo: ~1~ segundos
-[CRED097]
-JOE GREENE
+[WHEEL13]
+BONIFICACIÓN EN PARADA MÁS LARGA: ~1~ $ Tiempo: ~1~ segundos
-[CRED098]
-BRIAN PLANER
+[WHEEL14]
+BONIFICACIÓN EN PARADA MÁS LARGA: ~1~ $ Distancia: ~1~,~1~m
-[CRED099]
-OSWALD GREENE
+[WHEEL15]
+BONIFICACIÓN EN PARADA MÁS LARGA: ~1~ $ Distancia: ~1~ pies
-[CRED100]
-EDITORIAL DEL LIBERTY TREE
+[ROK3_72]
+¡Love Fist!
-[CRED101]
-JAMES WORRALL
+[POR1_19]
+¡Eh!
-[CRED102]
-DAN HOUSER
+[DESPERA]
+Desesperado
-[CRED103]
-ADAM TEDMAN
+[MOB_99A]
+Ve hasta el teléfono público junto al centro comercial en Washington.
-[CRED104]
-PAUL YEATES
+[MOB_98A]
+Ve hasta el teléfono público en Vice Point.
-[CRED105]
-JENEFER GROSS
+[MOB_96A]
+Ve hasta el teléfono público en la terminal del aeropuerto.
-[CRED106]
-LAURA PATERSON
+[MOB_95A]
+Ve hasta el teléfono público en Little Havana.
-[CRED107]
-CINEMÁTICAS
+[BNK1_1]
+¿Le puedo ayudar, señor?
-[CRED108]
-GUIÓN DE DAN HOUSER Y JAMES WORRALL
+[BNK1_2]
+¡Hay un impostor!
-[CRED109]
-AUDIO DIRIGIDO POR DAN HOUSER
+[BNK1_3]
+¡Se ha vuelto loco!
-[CRED110]
-AUDIO PRODUCIDO POR RENAUD SEBBANE
+[BNK1_4]
+¿Quién demonios eres?
-[CRED111]
-REPARTO
+[BNK1_5]
+¿Dónde está tu placa?
-[CRED112]
-FRANK VINCENT - SALVATORE LEONE
+[BNK1_6]
+¡Ahí están! ¡Dispara a matar!
-[CRED113]
-JOE PANTOLIANO - LUIGI GOTERELLI
+[MOB_24A]
+Hola, ¿Sr. Vercetti?
-[CRED114]
-MICHAEL MADSEN - TONI CIPRIANI
+[MOB_24B]
+Sí.
-[CRED115]
-MICHAEL RAPAPORT - JOEY LEONE
+[MOB_24C]
+Soy Cortez. Usted estuvo en mi fiesta.
-[CRED116]
-DEBBI MAZAR - MARÍA
+[MOB_24D]
+Sí, lo recuerdo.
-[CRED117]
-KYLE MACLACHAN - DONALD LOVE
+[MOB_24E]
+Sr. Vercetti, ha sido un desgraciado incidente lo que ocurrió con su operación de negocios.
-[CRED118]
-ROBERT LOGGIA - RAY MACHOWSKI
+[MOB_24F]
+Lo sé.
-[CRED119]
-GURU - 8-BALL
+[MOB_24G]
+Quiero que sepa que tanto yo como mi gente estamos haciendo todo lo que podemos para llegar al fondo de este tema.
-[CRED120]
-SONDRA JAMES - MAMMA
+[MOB_24H]
+Si desea hablar conmigo de manera más privada, me podrá encontrar en el barco. Buenos días, señor.
-[CRED121]
-LIANA PAI - ASUKA
+[BNK2_6]
+¡Este tío está chalado!
-[CRED122]
-LES MAU - KENJI
+[ANGEL]
+Ángel
-[CRED123]
-CYNTHIA FARRELL - CATALINA
+[CUBJET]
+Jetmax Cubano
-[CRED124]
-AL ESPINOSA - MIGUEL
+[SANDKIN]
+Sandking
-[CRED125]
-CHRIS PHILLIPS - EL BURRO
+[POLMAV]
+Maverick de la policía
-[CRED126]
-HUNTER PLATIN - CHICO
+[BOXVILL]
+Boxville
-[CRED127]
-WALTER MUDU - D-ICE
+[BENSON]
+Benson
-[CRED128]
-CURTIS MCCLARIN - CURTLY
+[HOTRINA]
+Corredor de Hotring
-[CRED129]
-BILL FIORE - DARKEL
+[HOTRINB]
+Corredor de Hotring
-[CRED130]
-CHRIS PHILLIPS - MARTY CHONKS
+[BLOODRA]
+Coche de Bloodring
-[CRED131]
-HUNTER PLATIN - CURLY BOB
+[BLOODRB]
+Coche de Bloodring
-[CRED132]
-WALTER MUDU - REY COURTNEY
+[MAFIACR]
+Yate de la Mafia
-[CRED133]
-HUNTER PLATIN - PHIL EL MANCO
+[COP_M2]
+ANTI VICIO
-[CRED134]
-KIM GURNEY - MISTY
+[COP_M3]
+TRUENO MARRÓN
-[CRED135]
-CAPTURA DE MOVIM.
+[BNK3_2]
+No voy a conducir por ti, ni soñando, voy a compartir esto con el grupo.
-[CRED136]
-ANIMACIÓN
+[FEM_SL1]
+No hay archivo 1 guardado
-[CRD136A]
-ALEX HORTON
+[FEM_SL2]
+No hay archivo 2 guardado
-[CRED137]
-DIRECCIÓN
+[FEM_SL3]
+No hay archivo 3 guardado
-[CRD137A]
-NAVID KHONSARI
+[FEM_SL4]
+No hay archivo 4 guardado
-[CRED138]
-PRODUCCIÓN
+[FEM_SL5]
+No hay archivo 5 guardado
-[CRD138A]
-JAMIE KING
+[FEM_SL6]
+No hay archivo 6 guardado
-[CRD138B]
-RENAUD SEBBANE
+[FEM_SL7]
+No hay archivo 7 guardado
-[CRED139]
-GRABADA EN MODERN UPRISING STUDIOS, BROOKLYN
+[FEM_SL8]
+No hay archivo 8 guardado
-[CRED140]
-ACTORES
+[FEA_CHA]
+Cambiando la salida de audio a ESTÉREO. Espera...
-[CRD140A]
-RENAUD SEBBANE
+[FEA_CHD]
+¡Aviso! Estás cambiando la salida de ESTÉREO a DTS. Espera...
-[CRD140B]
-GISELLE JONES
+[FEI_SEL]
+Selec.
-[CRD140C]
-STEPHEN DANIELS
+[FEI_BAC]
+Atrás
-[CRD140D]
-ROBERT STIO
+[FEI_RES]
+Reanudar
-[CRD140E]
-JENNY GROSS
+[FEI_NAV]
+Navegar
-[CRED141]
-DIÁLOGO DE PEATONES
+[FEI_BTX]
+botón / -
-[CRED142]
-ESCRITO POR DAN HOUSER, NAVID KHONSARI Y JAMES WORRALL
+[FEI_BTT]
+botón " -
-[CRED143]
-DIRIGIDO POR CRAIG CONNER, DAN HOUSER Y LAZLOW
+[FEI_STA]
+Botón START -
-[CRED144]
-PRODUCIDO POR RENAUD SEBBANE
+[FEI_BTD]
+; = > < -
-[CRED145]
-REPARTO
+[FEI_STO]
+Parar
-[CRED146]
-HUNTER PLATIN
+[MOB_68A]
+Tommy, tío, tengo una sorpresa para ti.
-[CRED147]
-DAN HOUSER
+[MOB_68B]
+Me encuentro en el estudio de grabación con unos artistas importantes.
-[CRED148]
-RENAUD SEBBANE
+[MOB_68C]
+¿Por qué no te vienes por aquí?
-[CRED149]
-MARIA CHAMBERS
+[MOB_68D]
+Sabes que esto tiene sentido, ¿a que sí? Hasta dentro de un rato.
-[CRED150]
-JEFF STANTON
+[OUTFT1]
+Calle
-[CRED151]
-RYAN CROY
+[OUTFT2]
+Etiqueta
-[CRED152]
-DEENA BERMAN
+[OUTFT3]
+Mono de trabajo
-[CRED153]
-MARIA CHAMBERS
+[OUTFT4]
+Club de campo
-[CRED154]
-ALICE B. SALTZMAN
+[OUTFT5]
+Habana
-[CRED155]
-ALEX ANTHONY SIOUKAS
+[OUTFT6]
+Policía
-[CRED156]
-SEAN R. LYNCH
+[OUTFT7]
+Atraco al banco
-[CRED157]
-AMY SALZMAN
+[OUTFT8]
+Informal
-[CRED158]
-COLIN MCSHANE
+[OUTFT9]
+Sr. Vercetti
-[CRED159]
-COREY WADE
+[OUTFT10]
+Chándal
-[CRED160]
-GERALD COSGROVE
+[OUTFT13]
+MC Tommy
-[CRED161]
-STEPHANIE ROY
+[CAR_AS1]
+CONCESIONARIO DE COCHES CONSOLIDADO
-[CRED162]
-DORIS WOO
+[CAR_AS2]
+~g~El Concesionario de coches Sunshine generará ahora unos ingresos de hasta ~1~ $ máximo. Asegúrate de recaudarlos regularmente.
-[CRED163]
-JOSEPH GREENE
+[BUYSAVE]
+~g~A partir de ahora, podrás guardar tu partida aquí cuando no estés en una misión.
-[CRED164]
-LAZLOW JONES
+[BUYGARG]
+~g~También puedes almacenar vehículos en este garaje.
-[CRED165]
-HSIANG LIN
+[STRPBUY]
+Adquirido el club Pole Position: ~1~ $
-[CRED166]
-STEVE MICHAEL ROBERT
+[GA_4]
+Las bombas de coche son 500 $ cada una.
-[CRED167]
-MATHEW MURRAY
+[GA_5]
+Tu coche ya está equipado con una bomba.
-[CRED168]
-RICHARD HUIE
+[GA_6]
+¡Apárcalo, actívala pulsando ~h~~k~~PED_FIREWEAPON~~w~ y SAL PITANDO!
-[CRED169]
-GARVIN ATWELL
+[GA_7]
+¡Ármalo pulsando ~h~~k~~PED_FIREWEAPON~~w~. La bomba explotará cuando se arranque el motor.
-[CRED170]
-STEVE KNEZEVICH
+[GA_6B]
+¡Apárcalo, actívala pulsando ~h~~k~~PED_FIREWEAPON~~w~ y SAL PITANDO!
-[CRED171]
-YUKIMURA SATO
+[GA_7B]
+¡Ármalo pulsando ~h~~k~~PED_FIREWEAPON~~w~. La bomba explotará cuando se arranque el motor.
-[CRED172]
-FRANK CHAVEZ
+[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.
-[CRED173]
-LIEZL JACINTO
+[MOB_70B]
+Me podrás encontrar en el barco.
-[CRED174]
-CANAAN MCKOY
+[PICK1]
+¡El chaleco antibalas ha sido entregado en el hotel Ocean View!
-[CRED175]
-ADAM DAVIDSON
+[PICK2]
+¡La .357 ha sido entregada en el hotel Ocean View!
-[CRED176]
-LANCE WILLIAMS
+[PICK3]
+¡La sierra mecánica ha sido entregada en el hotel Ocean View!
-[CRED177]
-NEIL MCCAFFREY
+[PICK4]
+¡El lanzallamas ha sido entregado en el hotel Ocean View!
-[CRED178]
-LAURA PATERSON
+[PICK5]
+¡El rifle de francotirador .308 ha sido entregado en el hotel Ocean View!
-[CRED179]
-REY CONCEPCION
+[PICK6]
+¡La Ametralladora Pesada ha sido entregada en el hotel Ocean View!
-[CRED180]
-CHARLES HEROLD
+[PICK7]
+¡El lanzacohetes ha sido entregado en el hotel Ocean View!
-[CRED181]
-ANDREW GREENWALD
+[PICK8]
+¡El Sea Sparrow está ahora disponible en la mansión de Starfish Island!
-[CRED182]
-JAMES MIELKE
+[PICK9]
+¡El tanque está ahora disponible en los cuarteles del ejército!
-[CRED183]
-PETER SUCIU
+[PICK10]
+¡El Hunter está ahora disponible en los cuarteles del ejército!
-[CRED184]
-ALEX ODULIO
+[CLOTH1]
+El traje de etiqueta ha sido entregado en Rafaels en Ocean Beach.
-[CRED185]
-DON NKRUMAH
+[CLOTH2]
+El traje de calle ha sido entregado en los pisos francos.
-[CRED186]
-KENDALL PITTMAN
+[CLOTH3]
+El mono de trabajo ha sido entregado en Tooled Up en el centro comercial de North Point.
-[CRED187]
-SAL SUAZO
+[CLOTH4]
+El traje del club de campo ha sido entregado en el club de golf de Leaf Links.
-[CRED188]
-EREK MATEO
+[CLOTH5]
+El traje Havana ha sido entregado en la tienda de ropa de Little Havana.
-[CRED189]
-CHRIS DIFATE
+[CLOTH6]
+El traje de policía ha sido entregado en la jefatura de policía de Washington Beach.
-[CRED190]
-LEILA MILTON
+[CLOTH7]
+El traje informal ha sido entregado en Gash del centro comercial de North Point.
-[CRED191]
-DARREN ZOLTOWSKI
+[CLOTH8]
+El traje del Sr. Vercetti ha sido entregado en Collar & Cuffs de Ocean Beach.
-[CRED192]
-VIRGINIA SMITH
+[CLOTH9]
+El chándal ha sido entregado en Jocksport del centro de la ciudad.
-[CRED193]
-KEVIN CASSIN
+[CLOTH10]
+El traje para el atraco al banco ha sido entregado en el Club Malibu de Vice Point.
-[CRED194]
-JASON SHIGEMORI
+[MOB_62A]
+Tommy, soy Ricardo Díaz, quiero darte las gracias por cuidar de mí, tío.
-[CRED195]
-KELLY KINSELLA
+[MOB_62B]
+He preguntado al gilipollas de Cortez, y me ha dicho que eres bueno, amigo, ¿por qué no vienes a verme?
-[CRED196]
-MOLLIE STICKNEY
+[MOB_62C]
+Necesito un tío como tú. Todos los que tengo son gilipollas perdidos,
-[CRED197]
-STANTON SARJEANT
+[MOB_62D]
+gilipollas por todas partes, tío. Yo te puedo hacer muy rico.
-[CRED198]
-LAURA WALSH
+[GOAWAY2]
+~g~Regresa cuando hayas terminado las misiones de la banda de moteros.
-[CRED199]
-MARK GARONE
+[COL2_9]
+¡Estúpido americano! ¡Te han seguido hasta aquí!
-[CRED200]
-JOANNA SLY
+[LOADCOL]
+Cargando...
-[CRED201]
-ELIZABETH HOWELL
+[STFT_17]
+Tiempo más rápido en la ''Prueba PCJ''
-[CRED202]
-ANA HERCULES
+[STFT_18]
+Tiempo más rápido en el ''Trial de tierra''
-[CRED203]
-SHIRLEY IRICK
+[STFT_19]
+Tiempo más rápido en la ''Pista de Pruebas''
-[CRED204]
-KASHONA FIELDS
+[NEW_REC]
+¡Nuevo récord establecido! ~w~~1~ minutos ~g~y ~w~~1~ segundos.
-[CRED205]
-JOEL M. LILJE
+[BMX_HOW]
+~g~¡Da dos vueltas a la pista de tierra, ~y~pasando por ~g~los ~y~PUNTOS DE CONTROL ~g~por el camino!
-[CRED206]
-JOHN DIBENEDETTO
+[BMXREW1]
+~g~¡Cada vez que batas tu récord anterior de las dos vueltas
-[CRED207]
-NANCY GILES
+[BMXREW2]
+~g~conseguirás una ~y~RECOMPENSA ~g~mejor!
-[CRED208]
-RYAN CROY
+[BMXRAIN]
+~g~Parece lluvia...
-[CRED209]
-JENNIFER KOLBE
+[ITBEG]
+Al principio...
-[CRED210]
-LIAM BURKE
+[NBMNBUY]
+Casa Swanko adquirida: ~1~ $
-[CRED211]
-SIGRID PREISSL
+[LNKVBUY]
+Apartamento en Links View adquirido: ~1~ $
-[CRED212]
-ANITA FITZSIMONS
+[HYCOBUY]
+Piso de Hyman adquirido: ~1~ $
-[CRED213]
-PHILIPPA RASELLI
+[BUYGARS]
+~g~Puedes guardar vehículos en estos garajes.
-[CRED214]
-WIL QUESNEL
+[OCHEBUY]
+Apartamento de Ocean Heights adquirido: ~1~ $
-[CRED215]
-FALKO BURKERT
+[WASHBUY]
+1102 de la calle Washington adquirido: ~1~ $
-[CRED216]
-SARA SEWELL
+[VCPTBUY]
+3321 de Vice Point adquirido: ~1~ $
-[CRED217]
-EMISORAS DE RADIO Y MÚSICA
+[SKUMBUY]
+Chabola Skumole adquirida: ~1~ $
-[CRED218]
-PRODUCTORES DE ROCKSTAR REINO UNIDO
+[HELP6_C]
+Pulsa ~h~~k~~VEHICLE_HANDBRAKE~~w~ para usar el freno de mano del vehículo.
-[CRD218A]
-CRAIG CONNER
+[HELP2_A]
+Pulsa ~h~~k~~PED_SPRINT~~w~~w~ cuando estés corriendo para ~h~esprintar.
-[CRD218B]
-STUART ROSS
+[HELP4_A]
+Pulsa ~h~~k~~VEHICLE_ACCELERATE~~w~ para acelerar.
-[CRED219]
-COORDINADOR DE BANDA SONORA
+[HELP5_A]
+Pulsa ~h~~k~~VEHICLE_BRAKE~~w~ para frenar o para dar marcha atrás si el vehículo se ha detenido.
-[CRED220]
-TERRY DONOVAN
+[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.
-[CRED221]
-PRODUCTOR DE ROCKSTAR GAMES
+[PBOAT_1]
+Pulsa ~h~ ~k~~PED_FIREWEAPON~~w~ para disparar los cañones del barco.
-[CRED222]
-DAN HOUSER
+[SEG3_4]
+~g~Puedes recoger bombas simplemente pilotando tu Helicóptero RC cerca de cada una de ellas, para soltar una bomba pulsa ~h~~k~~PED_FIREWEAPON~~g~.
-[CRED223]
-EDICIÓN
+[RCR1_3]
+~g~Si quieres abandonar esta misión, pulsa ~h~~k~~PED_FIREWEAPON~~g~ para detonar tu coche RC.
-[CRED224]
-CRAIG CONNER
+[HELP32]
+A continuación dispara pulsando ~h~~k~~PED_FIREWEAPON~.
-[CRED225]
-ALLAN WALKER
+[HELP33]
+A continuación dispara pulsando ~h~~k~~PED_FIREWEAPON~.
-[CRED226]
-LAZLOW
+[TTUTOR]
+Pulsa ~h~~k~~TOGGLE_SUBMISSIONS~~w~ para comenzar o cancelar las misiones de taxista.
-[CRED227]
-GUIÓN DE LOCUTORES Y ANUNCIOS
+[TTUTOR2]
+Pulsa ~h~~k~~TOGGLE_SUBMISSIONS~~w~ para comenzar o cancelar las misiones de taxista.
-[CRED228]
-DAN HOUSER
+[FTUTOR]
+Pulsa ~h~~k~~TOGGLE_SUBMISSIONS~~w~ para comenzar o cancelar las misiones del camión de bomberos.
-[CRED229]
-LAZLOW
+[FTUTOR2]
+Pulsa ~h~~k~~TOGGLE_SUBMISSIONS~~w~ para comenzar o cancelar las misiones del camión de bomberos.
-[CRED230]
-AGRADECIMIENTOS
+[CTUTOR]
+Pulsa ~h~~k~~TOGGLE_SUBMISSIONS~~w~ para comenzar o cancelar las misiones de justiciero.
-[CRED231]
-ADAM TEDMAN
+[CTUTOR2]
+Pulsa ~h~~k~~TOGGLE_SUBMISSIONS~~w~ para comenzar o cancelar las misiones de justiciero.
-[CRED232]
-ALEX MASON
+[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.
-[CRED233]
-JUDY HENDERSON CASTING
+[ATUTOR3]
+Pulsa ~h~~k~~TOGGLE_SUBMISSIONS~~w~ para comenzar o cancelar las misiones de ATS.
-[CRED234]
-HAMISH BROWN
+[GUN_H1]
+~w~Pulsa ~h~~k~~PED_SPRINT~~w~ para comprar. ~w~Pulsa ~h~~k~~VEHICLE_ENTER_EXIT~~w~ para salir.
-[CRED235]
-CHRISSY HOBAN
+[PU_CF3]
+Pulsa ~h~~k~~VEHICLE_ENTER_EXIT~~w~ para reemplazar tu arma actual en esta ranura.
-[CRED236]
-INNES RICARD
+[PU_CF4]
+Pulsa ~h~~k~~VEHICLE_ENTER_EXIT~~w~ para reemplazar tu arma actual en esta ranura.
-[CRED237]
-LILION BROZSKA
+[HELP9_B]
+Pulsa ~h~~k~~PED_FIREWEAPON~ ~w~para ~h~disparar~w~ el rifle de francotirador.
-[CRED238]
-BOB HILLARY
+[HELP37]
+Si no quieres subir al coche mientras se lo estás robando a alguien, pulsa ~h~~k~~PED_SPRINT~.
-[CRED239]
-EMILY ANDERSON
+[HELP6_A]
+Pulsa ~h~~k~~VEHICLE_HANDBRAKE~~w~ para usar el freno de mano del vehículo.
-[CRED240]
-RICHIE HENDERSON
+[HELP6_D]
+Pulsa ~h~~k~~VEHICLE_HANDBRAKE~~w~ para usar el freno de mano del vehículo.
-[CRED241]
-CHRISTIAN CANTAMESSA
+[HELP26]
+Pulsa ~h~~k~~VEHICLE_ENTER_EXIT~~w~ para subir o bajar de un vehículo.
-[CRED242]
-JERONIMO BARRERA
+[HELP27]
+Pulsa ~h~~k~~VEHICLE_TURRETUP~~w~ o ~h~~k~~VEHICLE_TURRETDOWN~~w~ para equilibrar tu peso en la moto.
-[CRED243]
-ALEXANDER ILLES
+[HELP28]
+Pulsa ~h~~k~~VEHICLE_TURRETUP~~w~ o ~h~~k~~VEHICLE_TURRETDOWN~~w~ para equilibrar tu peso en la moto.
-[CRED244]
-BARANE CHAN
+[HELP35]
+Pulsa ~h~~k~~GO_LEFT~~w~ o ~h~~k~~GO_RIGHT~~w~ para conducir el vehículo.
-[CRED245]
-DUNCAN SHIELDS
+[HELP36]
+Pulsa ~h~~k~~GO_LEFT~~w~ o ~h~~k~~GO_RIGHT~~w~ para conducir el vehículo.
-[CRED246]
-BARANE CHAN
+[HELP42]
+Ve al ~q~icono rosa~w~ para encontrar el hotel.
-[CRED247]
-DEREK PAYNE
+[HELP19]
+Camina hasta el ~q~marcador rosa~w~ para continuar.
-[CRED248]
-KEVIN WONG
+[HELP1]
+Párate en el centro del ~q~marcador rosa.
-[CRED249]
-ROSS ELLIOTT
+[HELP12]
+Camina hasta el centro del ~q~marcador rosa~w~ para activar una misión.
-[CRED250]
-ROSS BEAZLEY
+[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.
-[CRED251]
-ALEX BAZLINTON
+[S_PROMP]
+Cuando no estés en una misión podrás guardar tu progreso recogiendo las ~h~cintas de cassette~w~.
-[CRED252]
-DAVE WATSON
+[HELP16]
+Cruza la puerta principal del hotel ~h~Ocean View~w~ para entrar en el edificio.
-[CRED253]
-MALCOLM SMITH
+[HELP43]
+~g~Ve al hotel ~h~Ocean View~g~ en Ocean Drive.
-[CRED255]
-ANDREW SEMPLE
+[HELI_F1]
+~r~¡Misión de puntos de control cancelada!
-[CRED256]
-ARTISTAS
+[AMMUHLP]
+Si necesitas armas pásate por ~h~Ammu-Nation~w~. Está indicado en el radar como una ~h~pistola~w~ azul.
-[CRED257]
-STUART PETRI
+[HELI_1]
+Control del Helicóptero de Centro de la ciudad
-[CRED258]
-JERONIMO BARRERA
+[HELI_2]
+Control del Helicóptero de Ocean Beach
-[CRED259]
-CARLY SLATER
+[HELI_3]
+Control del Helicóptero de Vice Point
-[CRED260]
-GREG LAU
+[HELI_4]
+Control del Helicóptero de Little Haiti
-[CRED261]
-STEVE KNEZEVICH
+[FST_MFR]
+Emisora de radio preferida
-[CRED262]
-DEVIN WINTERBOTTOM
+[FST_LFR]
+Emisora de radio menos escuchada
-[CRED263]
-JAMEEL VEGA
+[FEI_HOL]
+Mantener
-[CRED264]
-LEE CUMMINGS
+[FEI_ZOO]
+Zoom
-[CRED265]
-DEVIN BENNET
+[FEI_BTR]
+> < -
-[CRED266]
-ELIZABETH SATTERWHITE
+[FEI_NA]
+N\A
-[CRED267]
-AARON RIGBY
+[MESA]
+Mesa Grande
-[CRED268]
-STEVE K.
+[STRP_NO]
+No puedes comprar el club de striptease en este momento, vuelve luego.
-[CRED269]
-GREG LAU
+[CHSE]
+PERSECUCIÓN
-[CINCAM]
-Vista cinematográfica
+[NBMN_L]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar la casa Swanko por ~1~ $.
-[KM1_13]
-¡Mete el vehículo en el garaje!
+[NBMN_T]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar la casa Swanko por ~1~ $.
-[KM3_14]
-~r~¡Te han descubierto, han cancelado el trato!
+[NBMN_C]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar la casa Swanko por ~1~ $.
-[EBAL_H]
-Espera, tío, que voy a hablar con Luigi.
+[LNKV_L]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar el apartamento de Links View por ~1~ $.
-[EBAL_M]
-¡Recuerda: nadie se mete con mis chicas!
+[LNKV_T]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar el apartamento de Linsk View por ~1~ $.
-[LM2_F]
-Luego coge su coche y repíntalo.
+[LNKV_C]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar el apartamento de Links View por ~1~ $.
-[LM2_D]
-Toma, toma, para ti.
+[HYCO_L]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar el piso de Hyman por ~1~ $.
-[LM1_9]
-Hola, soy Misty.
+[HYCO_T]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar el piso de Hyman por ~1~ $.
-[LM4_A]
-Algún Diablo de las narices ha estado vendiendo a sus putitas en mi territorio.
+[HYCO_C]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar el piso de Hyman por ~1~ $.
-[FM2_B]
-¡Tenemos a un chivato!
+[OCHE_L]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar el apartamento de Ocean Heights por ~1~ $.
-[FM2_C]
-No está ni chuleando ni traficando, así que estará cantando.
+[OCHE_T]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar el apartamento de Ocean Heights por ~1~ $.
-[FM3_CC]
-Regresa cuando tengas el dinero.
+[OCHE_C]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar el apartamento de Ocean Heights por ~1~ $.
-[FEDS_AM]
-<> - CAMBIAR MENÚ
+[WASH_L]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar el 1102 de la calle Washington por ~1~ $.
-[LOVE5_5]
-~r~¡No has protegido al camión!
+[WASH_T]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar el 1102 de la calle Washington por ~1~ $.
-[RM6_6]
-~r~¡Ray ha muerto!
+[WASH_C]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar el 1102 de la calle Washington por ~1~ $.
-[RM6_7]
-~r~¡Ray ha perdido su avión!
+[VCPT_L]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar el 3321 de Vice Point por ~1~ $.
-[RM6_8]
-~g~Has abandonado a Ray, vuelve a por él.
+[VCPT_T]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar el 3321 de Vice Point por ~1~ $.
-[FM1_10]
-~g~Has abandonado a María, vuelve a por ella.
+[VCPT_C]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar el 3321 de Vice Point por ~1~ $.
-[LOVE4_9]
-~r~¡El avión ha sido destruido!
+[SKUM_L]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar la chabola Skumole por ~1~ $.
-[LOV4_10]
-~r~¡La única pista sobre dónde se encuentra el paquete ha sido destruida!
+[SKUM_T]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~para comprar la chabola Skumole por ~1~ $.
-[KM2_D]
-No hace falta decir que debemos darle los coches como un regalo para pagar mi deuda con él.
+[SKUM_C]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~ ~w~ para comprar la chabola Skumole por ~1~ $.
-[KM4_B]
-El negocio es lo bastante afortunado como para permitir que nuestra protección salde sus cuentas hoy mismo.
+[PRNT_L]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar la imprenta por ~1~ $.
-[KM2_E]
-Debes obtener los coches de la lista y llevarlos a un garaje que hay tras el aparcamiento de Newport.
+[PRNT_T]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar la imprenta por ~1~ $.
-[FM3_8I]
-Encuentra una posición elevada. Entraré cuando dispares el primer tiro.
+[PRNT_C]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar la imprenta por ~1~ $.
-[LOVE1_B]
-La experiencia me ha enseñado que un hombre como tú puede ser muy leal por el precio correcto,
+[CAR_L]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar el concesionario de coches por ~1~ $.
-[LOVE1_H]
-pero los grupos de hombres se vuelven codiciosos.
+[CAR_T]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar el concesionario de coches por ~1~ $.
-[LOVE1_C]
-Un activo valioso, un anciano oriental que conozco,
+[CAR_C]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar el concesionario de coches por ~1~ $.
-[LOVE1_I]
-está siendo retenido por unos sudamericanos en Aspatria.
+[PORN_L]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar los estudios de cine por ~1~ $.
-[MEA4_D]
-He quedado con él,
+[PORN_T]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar los estudios de cine por ~1~ $.
-[MEA4_B4]
-¿Te envía Marty? Vale, le voy a enseñar a ese sinvergüenza el significado de la palabra negocio.
+[PORN_C]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar los estudios de cine por ~1~ $.
-[MEA4_B5]
-¡Carl, hola! Ehhh... Necesito más tiempo para conseguir tu dinero.
+[ICE_L]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar la fábrica de helados por ~1~ $.
-[MEA1_B4]
-Ah, te envió el Sr. Chonks, ¿verdad? Vayamos a visitarlo.
+[ICE_T]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar la fábrica de helados por ~1~ $.
-[HM5_6]
-Vamos a partir cabezas...
+[ICE_C]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar la fábrica de helados por ~1~ $.
-[LOVE1_5]
-~g~Deja de perder el tiempo, hazte con un coche de los colombianos y rescata al socio de Love.
+[TAXI_L]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar la compañía de taxis por ~1~ $.
-[AS1_D]
-Haz de cebo y consigue que los escuadrones te sigan hasta Pike Creek,
+[TAXI_T]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar la compañía de taxis por ~1~ $.
-[AS1_E]
-donde estarán esperando algunos de mis hombres.
+[TAXI_C]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar la compañía de taxis por ~1~ $.
-[AS2_C]
-El cártel tiene una tapadera, el Kappa Coffee House.
+[BANK_L]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar el Malibú por ~1~ $.
-[AS2_E]
-No tenemos otra opción más que sabotear esos puntos de venta.
+[BANK_T]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar el Malibú por ~1~ $.
-[AS2_F]
-¡Redúcelos a cenizas!
+[BANK_C]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar el Malibú por ~1~ $.
-[AS2_A1]
-¡Está claro que Miguel tiene esa famosa resistencia latina!
+[BOAT_L]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar el astillero por ~1~ $.
-[AS2_A2]
-Estoy agotada.
+[BOAT_T]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar el astillero por ~1~ $.
-[SIREN_3]
-Para activar la sirena de este vehículo, pulsa ~h~~k~~VEHICLE_HORN~~w~.
+[BOAT_C]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar el astillero por ~1~ $.
-[SIREN_4]
-Para activar la sirena de este vehículo, pulsa ~h~~k~~VEHICLE_HORN~~w~.
+[STRP_L]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar el club Pole Position por ~1~ $.
-[AS3_C]
-¡Buaj! ¿Qué es esa cosa amarilla pegajosa?
+[STRP_T]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar el club Pole Position por ~1~ $.
-[AS3_C1]
-¡Hola, guapo!
+[STRP_C]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para comprar el club Pole Position por ~1~ $.
-[AS3_F]
-Esta chica tiene un talento nato para la tortura.
+[STOCK]
+~r~Agotado
-[AS3_F1]
-Se las ha arreglado para extraerle esta joyita a nuestro invitado.
+[HELP14]
+Para encontrar el bufete del abogado, ve hacia la ~h~señal de la L~w~ que hay en el radar.
-[AS3_G]
-Hay una avioneta que llegará al Aeropuerto Francis en dos horas.
+[RAMPAGE]
+¡MASACRE!
-[AS3_G1]
-Está llena del veneno de Catalina.
+[RAMP_F]
+¡MASACRE FALLIDA!
-[AS3_H]
-Podrás evitar la seguridad del aeropuerto si conduces una lancha hasta las boyas luminosas,
+[RAMP_P]
+¡MASACRE COMPLETADA!
-[AS3_H1]
-así podrás disparar a la avioneta al aterrizar.
+[RAMP_A]
+¡TODAS LAS MASACRES COMPLETADAS!
-[AS3_I]
-¡Recoge el cargamento de entre los escombros y tráelo!
+[PAGE_01]
+¡Liquida a ~1~ criminales en 2 minutos!
-[AS3_J]
-Ten cuidado, guapo, ¿vale?
+[PAGE_02]
+¡Destruye ~1~ vehículos en 2 minutos!
-[AS3_K]
-Ahora prueba con el aceite picante...
+[PAGE_03]
+¡Pasa en el coche y cárgate a ~1~ criminales en 2 minutos!
-[RM2_F1]
-¡Los colombianos llegarán en cualquier momento!
+[PAGE_04]
+¡Atropella y mata a ~1~ criminales en 2 minutos!
-[RM2_K]
-Maldita sea, ¡están aquí! ¡FUEGO A DISCRECIÓN!
+[PAGE_05]
+¡Abate a tiros a ~1~ criminales en 2 minutos!
-[LOVE2_7]
-~g~¡Ahora deshazte del coche!
+[SENTXS]
+Sentinel XS
-[LOVE2_8]
-~g~¡Sal de Newport!
+[MAP_LEG]
+Leyenda
-[AM1_F]
-Salvatore Leone saldrá del club de Luigi dentro de unas tres horas. (~1~:~1~)
+[VCNMAV]
+VCN Maverick
-[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.
+[LG_01]
+Posición del jugador
-[FESZ_SR]
-¡Error al guardar! Comprueba la Memory Card (PS2) de la ranura de MEMORY CARD 1 e inténtalo de nuevo.
+[LG_02]
+Avery Carrington
-[FESZ_FO]
-¿Deseas formatear la Memory Card (PS2) en la ranura de MEMORY CARD 1?
+[LG_03]
+Contacto del motero
-[FELZ_FO]
-La Memory Card (PS2) de la ranura de MEMORY CARD 1 no tiene formato.
+[LG_04]
+Coronel Cortez
-[FES_NOC]
-No hay una Memory Card (PS2) insertada en la ranura para MEMORY CARD 1.
+[LG_05]
+Ricardo Díaz
-[FES_LOE]
-¡Fallo al cargar! Comprueba la Memory Card (PS2) de la ranura de MEMORY CARD 1 e inténtalo de nuevo.
+[LG_06]
+Kent Paul
-[FES_DEE]
-¡Fallo al borrar! Comprueba la Memory Card (PS2) de la ranura de MEMORY CARD 1 e inténtalo de nuevo.
+[LG_07]
+Abogado
-[FORSUC]
-Memory Card (PS2) de la ranura de MEMORY CARD 1 formateada con éxito.
+[LG_08]
+Phil Cassidy
-[ERFOUN]
-¡Error al formatear la Memory Card (PS2)!
+[LG_09]
+Astillero
-[ERMCNP]
-No hay Memory Card (PS2) en la ranura de MEMORY CARD 1.
+[LG_10]
+Club Malibú
-[SVMEM1]
-Guardando en la Memory Card (PS2) de la ranura de MEMORY CARD 1.
+[LG_11]
+Cubanos
-[FORSLO]
-Formateando Memory Card (PS2) de la ranura de MEMORY CARD 1.
+[LG_12]
+Estudio Cinematográfico
-[SLONFM]
-¡Error al formatear la Memory Card (PS2)!
+[LG_13]
+Ammu-Nation
-[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_14]
+Haitianos
-[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_15]
+Ferretería
-[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_16]
+Piso franco
-[FES_ISF]
-NO PRESENTE
+[LG_17]
+Helado
-[FES_SAG]
-PRESENTE
+[LG_18]
+Taxis Kaufman
-[SLONNO]
-No hay una Memory Card (PS2) en la ranura de MEMORY CARD 1.
+[LG_19]
+Love Fist
-[SLONNF]
-La Memory Card (PS2) de la ranura de MEMORY CARD 1 no tiene formato.
+[LG_20]
+Imprenta
-[FESZ_FM]
-La Memory Card (PS2) de la ranura de MEMORY CARD 1 no tiene formato. ¿Deseas formatear la Memory Card (PS2)?
+[LG_21]
+Propiedad
-[FESZ_FF]
-¡Fallo al formatear! Comprueba la Memory Card (PS2) de la ranura de MEMORY CARD 1 e inténtalo de nuevo.
+[LG_22]
+Taller de Pintura
-[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_23]
+Tienda de ropa
-[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_24]
+Mansión de Tommy
-[FESZ_WR]
-Guardando datos. No extraigas la Memory Card (PS2) de la ranura de MEMORY CARD 1, ni reinicies o apagues la consola.
+[LG_25]
+Teléfono
-[FESZ_OW]
-Sobrescribiendo datos. No extraigas la Memory Card (PS2) de la ranura de MEMORY CARD 1, ni reinicies o apagues la consola.
+[LG_26]
+Emisora de radio Wildstyle
-[FELD_WR]
-Cargando datos. No extraigas la Memory Card (PS2) de la ranura de MEMORY CARD 1, ni reinicies o apagues la consola.
+[LG_27]
+Emisora de radio Flash FM
-[FEDL_WR]
-Borrando datos. No extraigas la Memory Card (PS2) de la ranura de MEMORY CARD 1, ni reinicies o apagues la consola.
+[LG_28]
+Emisora de radio Kchat
-[LM2_C]
-Luigi dijo que... que te diera esto...
+[LG_29]
+Emisora de radio Fever 105
-[LM3_G]
-que a Joey no le gusta esperar. Recuerda, tienes un pie dentro...
+[LG_30]
+Emisora de radio VRock
-[LM5_E]
-Saca todo el dinero que puedas a los polis antes de que se lo beban.
+[LG_31]
+Emisora de radio VCPR
-[JM5_C]
-Vale, hay un coche cargado con un fiambre en el bar cercano a Callahan Point.
+[LG_32]
+Emisora de radio Espantoso
-[RM2_B]
-Combatimos juntos en Nicaragua, cuando el país sabía lo que hacía.
+[LG_33]
+Emisora de radio Emotion 98.3
-[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_34]
+Emisora de radio Wave 103
-[RM2_D1]
-Iría yo mismo, pero la ciática ya está en sus trece... ¡Cof, cof! Así que... buena suerte.
+[LG_35]
+Destino
-[CATINF1]
-~g~¡Liquida a Catalina!
+[LG_36]
+Solarium
-[CATINF2]
-~g~Sigue al helicóptero para dar con Catalina.
+[LG_37]
+Club de Striptease
-[BOATIN1]
-Sube a una lancha y pulsa ~h~~k~~VEHICLE_ENTER_EXIT~~w~ para ponerte a los mandos.
+[LG_38]
+Objetivo
-[BOATIN2]
-Puedes pulsar ~h~~k~~VEHICLE_ENTER_EXIT~~w~ si estás cerca de una lancha para abordarla.
+[MAP_YAH]
+ESTÁS AQUÍ
-[BOATIN3]
-Sube a una lancha y pulsa ~h~~k~~VEHICLE_ENTER_EXIT~~w~ para ponerte a los mandos.
+[TAXSHRT]
+~g~Puedes coger este taxi Kaufman para ir a tu destino sin conducir. Te costará 9 $.
-[BOATIN4]
-Puedes pulsar ~h~~k~~VEHICLE_ENTER_EXIT~~w~ si estás cerca de una lancha para abordarla.
+[FEST_HV]
+Nivel más alto de misión de justiciero
-[JM6]
-'LA HUIDA'
+[CLOHELP]
+¡Ropa limpia!
-[FM1]
-'CARABINA'
+[SUNSHIN]
+Coches Sunshine
-[JM1]
-'EL ÚLTIMO ALMUERZO DE MIKE ''LABIOS'' '
+[CHERRYP]
+Helados Cherry Popper
-[FM21]
-'BASE FUERA: ACTO I'
+[KAUFCAB]
+Taxis Kaufman
-[FM3]
-'BASE FUERA: ACTO II'
+[BOATYAR]
+El Astillero
-[AM1]
-'SAYONARA, SALVATORE'
+[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á.
-[AM2]
-'BAJO VIGILANCIA'
+[FEI_BTU]
+; = -
-[KM2]
-'ROBO DE VEHÍCULOS'
+[BOAT_AS]
+~g~El astillero generará ahora unos ingresos hasta un máximo de ~1~ $. Asegúrate de recaudarlos de manera regular.
-[AS3]
-'TIERRA-AIRE'
+[BOAT_A2]
+ASTILLERO COMPLETADO
-[RM2]
-'ESCASEZ DE MANOS'
+[BOAT_N]
+Punto de control Charlie
-[LOVE6]
-'SEÑUELO'
+[BOAT_P]
+~g~Recoge los paquetes antes de que se acabe el tiempo.
-[LOVE1]
-'EL LIBERADOR'
+[FEI_R1B]
+Botón R1 \ R2 -
-[RC1]
-'DESTRUCCIÓN DE LOS DIABLOS'
+[HELP9_A]
+Pulsa ~h~~k~~PED_FIREWEAPON~ ~w~para disparar el rifle de francotirador.
-[RC2]
-'LA MASACRE DE LA MAFIA'
+[HELP21]
+Pulsa ~h~~k~~VEHICLE_ENTER_EXIT~ ~w~para subir o bajar de un vehículo.
-[RC3]
-'CALAMIDAD EN EL CASINO'
+[CREAM]
+Distribución
-[RC4]
-'EXTERMINIO DE RUMPOS'
+[UMBERTO]
+Café Robina
-[RM2_E1]
-¡No puedo creer que esos mamones amarillos me hayan vuelto a dejar con el culo al aire!
+[PU_CF1]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~ ~w~para recoger esta arma. Reemplazará cualquier arma del mismo tipo que tengas.
-[GREN_1]
-Cuanto más tiempo mantengas pulsado ~h~~k~~PED_FIREWEAPON~~w~, más lejos lanzarás la granada.
+[FED_RDM]
+MAPA E ICONOS
-[GREN_2]
-Cuanto más tiempo mantengas pulsado ~h~~k~~PED_FIREWEAPON~~w~, más lejos lanzarás la granada.
+[FEC_ILU]
+Invertir vista en primera persona
-[GREN_3]
-Cuanto más tiempo mantengas pulsado ~h~~k~~PED_FIREWEAPON~~w~, más lejos lanzarás la granada.
+[NITRO]
+¡Ahora todos los taxis disponen de un impulsor de salto! Simplemente toca el claxon.
-[LOVE4_G]
-Mis pertenencias estarán esperándote en el hangar de aduanas, dentro de la avioneta.
+[RATNG53]
+Informal
-[KABOOM]
-¡BUUUM!
+[RATNG54]
+Vergüenza
-[SPLAT]
-¡PLOF!
+[RATNG55]
+Hacker
-[PANCAK]
-¡APLASTADO!
+[RATNG56]
+Liante
-[SOAKED]
-¡AHOGADO!
+[RATNG57]
+Mentiroso compulsivo
-[HEAD]
-Head Radio
+[STHC_04]
+Puntuación más alta por mantener la pelota en el aire en la playa
-[DBL_CLF]
-Double Clef FM
+[STHC_05]
+Mejor resultado de Hotring
-[FLASHB]
-Flashback FM
+[STFT_13]
+Mejor tiempo en el Control del Helicóptero del centro
-[RISE]
-Rise FM
+[STFT_14]
+Mejor tiempo en el Control del Helicóptero de Ocean Beach
-[LIPS]
-Lips 106
+[STFT_15]
+Mejor tiempo en el Control del Helicóptero de Vice Point
-[CHAT]
-Chatterbox FM
+[STFT_16]
+Mejor tiempo en el Control del Helicóptero de Little Haití
-[K_JAH]
-K-Jah Radio
+[STFT_21]
+Tiempo más rápido en Hotring
-[GAM_FM]
-Game Radio FM
+[STFT_22]
+Vuelta más rápida en Hotring
-[MSX_FM]
-MSX FM
+[STFT_20]
+Tiempo más rápido en el ''Conocircuito''
-[TUBE1]
-Cuando abra el metro, podrás usarlo para ir a Staunton Island.
+[HELP44]
+Detente en el ~q~marcador rosa.
-[TUBE2]
-Cuando abra Shoreside Vale, podrás salir por la terminal Shoreside al Aeropuerto Internacional Francis.
+[HELP45]
+Pulsa ~h~~k~~PED_DUCK~~w~ para agacharte. Esto aumentará tu puntería con las armas que llevas.
-[TUBE_2]
-Para subirte a un vagón, pulsa el ~h~botón Entrar al vehículo~w~.
+[RCR1_5]
+Carrera Bandit RC
-[LEGAL]
-~g~¡Elimina la amenaza criminal!
+[RCPL1_7]
+Carrera Barón RC
-[GA_2]
-He cambiado el motor y la mano de pintura. ¡La poli no te reconocerá!
+[RCH1_11]
+Recogidas del Raider RC
-[LM1_8A]
-Si quieres ganar un dinerillo extra, siempre puedes ''coger prestado'' un taxi...
+[FEA_CTD]
+¡Aviso! Esta característica requiere que el dispositivo compatible DTS esté conectado. ¿Continuar?
-[TAXIH1]
-Para cerca de un peatón señalado para recogerlo y llevarlo a su destino antes de que se acabe el tiempo.
+[FEM_STE]
+UTILIZAR ESTÉREO
-[LM5_7]
-~g~¡Luigi no estará contento si hay menos de cuatro chicas trabajando en el ~p~baile de la policía~g~!
+[GREET]
+Saludos desde...
-[KM2_3]
-~g~Recuerda que los ~r~coches ~g~tienen que estar en perfecto estado para ser aceptados en el ~p~garaje~g~.
+[LANCE_1]
+¡Venga, tío, conduce con más cuidado!
-[KM5_2]
-~g~Uno de los jamaicanos se ha ido.
+[LANCE_2]
+¡Eh, mira lo que haces!
-[BETRA_A]
-Lo siento, cariño.
+[LANCE_3]
+¿Eh, dónde vamos ahora?
-[BETRA_B]
-Soy una chica ambiciosa, ¿pero tú?
+[LANCE_4]
+¿Qué estamos haciendo ahora?
-[BETRA_C]
-Eres un pez pequeñito.
+[LAW4_15]
+¡Más dinero!
-[JAILB_Q]
-¡Ándele!
+[MERC_5]
+Bonito coche, Mr. Vercetti.
-[JAILB_R]
-¡Señor malparido!
+[MERC_26]
+¡DEPRISA, DEPRISA, DEPRISA!
-[JAILB_S]
-No nos importará matarte.
+[MERC_27]
+Con cuidado Tommy, me arreglaron la nariz el mes pasado.
-[JAILB_T]
-Os vais a arrepentir.
+[MERC_28]
+Conduce con cuidado Tommy.
-[JAILB_U]
-Bien, bien, piérdete.
+[MERC_29]
+Ve más despacio Tommy.
-[HELP15]
-Cuando vayas a pie, mantén pulsado ~h~~k~~PED_LOOKBEHIND~~w~ para~h~ mirar atrás~w~.
+[MERC_30]
+Tommy, si no te importa mata a quien quieras menos a mí.
-[FEC_LB3]
-Mirar atrás
+[MERC_31]
+¡Tommy, cielo, no me mates!
-[FEC_R3]
-(botón R3)
+[MERC_32]
+¡Tommy, me alegro que robaras este coche!
-[FES_AFO]
-Esta Memory Card (PS2) ya está formateada.
+[MERC_40]
+Me he divertido tanto.
-[FEA_UP]
-;
+[MERC_43]
+Adiós, mi ángel.
-[FEA_DO]
-=
+[MERC_44]
+Ahora sigue machacándote, me oyes.
-[FEA_LE]
-<
+[MERC_45]
+Ciao, guapetón.
-[FEA_RI]
->
+[COL5_17]
+¡Oh, Dios mío, tienen un helicóptero!
-[FEDSAS3]
-- CAMBIAR SELECCIÓN
+[COL5_18]
+¡Dispara al helicóptero!
-[FEDSAS4]
-;=<> - CAMBIAR SELECCIÓN
+[COL5_19]
+Tommy, ¡hazte con ese helicóptero!
-[SPRAY_4]
-Pulsa ~h~~k~~PED_FIREWEAPON~~w~ para disparar el cañón de agua.
+[COL5_20]
+¡Ahí viene otra vez! ¡Derriba a ese helicóptero!
-[SPRAY_1]
-Pulsa ~h~~k~~PED_FIREWEAPON~~w~ para disparar el cañón de agua.
+[COL5_21]
+¡Mira el tamaño de ese helicóptero!
-[LITTLE]
-LITTLE T
+[COL5_22]
+¡Ahí viene de nuevo!
-[NICK]
-NICK LOVE
+[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.
-[AM1_10]
-~g~Salvatore saldrá del club de Luigi sobre las 0~1~:~1~.
+[STFT_23]
+Tiempo más rápido en Punto de control Charlie
-[JAILB_V]
-Hoy, Liberty City se ha visto conmocionada.
+[HELP50]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para colocar la cámara detrás de ti.
-[JAILB_A]
-La policía y los servicios de emergencia lidian con las consecuencias
+[HELP51]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para colocar la cámara detrás de ti.
-[JAILB_B]
-de un devastador ataque a un convoy policial ocurrido esta mañana.
+[HELP52]
+Pulsa ~h~~k~~PED_ANSWER_PHONE~~w~ para colocar la cámara detrás de ti.
-[JAILB_C]
-No se ha informado de quiénes eran los prisioneros trasladados en el convoy
+[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_D]
-y ningún grupo ha reconocido la autoría.
+[HELP46]
+Hay ocho categorías de armas diferentes.
-[JAILB_E]
-El convoy abandonó las oficinas de la policía esta mañana
+[HELP47]
+Puedes llevar una arma de cada categoría al mismo tiempo: un tipo de pistola, un tipo de rifle.
-[JAILB_F]
-para hacer una transferencia de reos a la penitenciaría de Liberty.
+[HELP54]
+~w~Cuesta: ~1~ $. ~r~Si compras esta arma reemplazarás la actual.
-[JAILB_G]
-El ataque se produjo en el puente Callahan,
+[HELP2A2]
+Pulsa ~h~~k~~PED_SPRINT~~w~ cuando corras para ~h~esprintar.
-[JAILB_H]
-dejando pocos testigos y al puente seriamente dañado.
+[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_I]
-Se cree que algunos de los convictos han perecido en la explosión
+[HLPSN_B]
+Mantén pulsado ~h~~k~~PED_LOCK_TARGET~ ~w~para ~h~apuntar~w~ con el rifle de francotirador.
-[JAILB_J]
-posterior al ataque inicial.
+[HLPSN_C]
+Mantén pulsado ~h~~k~~PED_LOCK_TARGET~ ~w~para ~h~apuntar~w~ con el rifle de francotirador.
-[JAILB_W]
-Pasadas las horas se hizo evidente que el ataque era obra de profesionales,
+[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_K]
-ya que la identificación de los prófugos se complicó
+[HLPSN_E]
+Pulsa ~h~~k~~PED_FIREWEAPON~~w~ para ~h~disparar~w~ el rifle de francotirador.
-[JAILB_L]
-cuando piratas informáticos atacaron las bases de datos de la policía.
+[HLPSN_F]
+Pulsa ~h~~k~~PED_FIREWEAPON~~w~ para ~h~disparar~w~ el rifle de francotirador.
-[JAILB_O]
-Con el retraso del proyecto del túnel Porter,
+[HLPSN_G]
+Pulsa ~h~~k~~PED_FIREWEAPON~~w~ para ~h~disparar~w~ el rifle de francotirador.
-[JAILB_P]
-este desastre deja a Portland aislada del resto de la ciudad.
+[PLANE_H]
+Mueve ~h~~k~~VEHICLE_ACCELERATE~~w~ hacia delante para acelerar y a izquierda o derecha para girar.
-[JAILB_M]
-*
+[PLANE_4]
+Mueve ~h~~k~~VEHICLE_ACCELERATE~~w~ hacia delante para acelerar y a izquierda o derecha para girar.
-[JAILB_N]
-*
+[HELP55]
+Pulsa ~h~~k~~PED_FIREWEAPON~~w~ para atacar al chef.
-[JAILB_X]
-UNUSED
+[STPR_8]
+Club Pole Position
-[FEDS_SE]
-Botón / - ELEGIR
+[STPR_9]
+3321 de Vice Point
-[FEDS_SB]
-Botón / - ELEGIR Botón " - VOLVER
+[STPR_10]
+Apartamento de Links View
-[TM4_A]
-Ah, eres tú. Toni no está.
+[STPR_11]
+Casa Swanko
-[TM4_A2]
-Pero te ha dejado una de sus cartitas de amor.
+[STPR_12]
+1102 de Washington Street
-[DIAB2_A]
-¡Empecé mi negocio de entretenimiento exótico sin nada más que lo que cabía en mis pantalones de cuero!
+[STPR_13]
+Apartamento de Ocean Heights
-[LM5_9]
-CHICAS:
+[STPR_14]
+Chabola Skumole
-[PERPIC]
-Paquetes ocultos encontrados
+[STPR_15]
+Piso de Hyman
-[CO_ONE]
-Paquete oculto ~1~ de ~1~
+[RCCANX]
+~r~Misión de avión RC cancelada.
-[LOVE3_3]
-~g~La avioneta ha tirado ~1~ de los 6 paquetes.
+[CLT_HL2]
+Cuando recojas ropa, te librarás de una o dos estrellas del nivel de se busca.
-[FARE11]
-~g~Ve al ~w~edificio en construcción ~g~de Fort Staunton.
+[CRED009]
+DISEÑO DE MISIONES
-[GA_21]
-No puedes guardar más coches en este garaje.
+[CRED359]
+LEE JOHNSON
-[CHEAT1]
-Trucos activados
+[CRED360]
+HENDRIK LESSER
-[CHEAT2]
-Arma trucada
+[CRED361]
+PASQUALE STACCHIOTTI
-[CHEAT3]
-Salud trucada
+[CRED362]
+ENRIQUE FERNÁNDEZ
-[CHEAT4]
-Armadura trucada
+[CRED363]
+PAUL BYERS
-[CHEAT5]
-Busca y captura trucado
+[CRED364]
+MIKE EMENY
-[CHEAT6]
-Dinero trucado
+[CRED365]
+ROB DUNKIN
-[CHEAT7]
-Clima trucado
+[CRED366]
+CHARLIE KINLOCH
-[AS1_H]
-~r~¡No has llevado al escuadrón de la muerte hasta la trampa de la yakuza!
+[CRED367]
+KEVIN HOBSON
-[FEDS_BA]
-Botón " - VOLVER
+[CRED368]
+JIM CREE
-[RAMP_A]
-¡TODAS LAS MASACRES COMPLETADAS!
+[MOB_66A]
+Tommy, Tommy, ¿para qué has vuelto?
-[USJ_ALL]
-¡TODAS LAS ACROBACIAS COMPLETADAS!
+[MOB_66B]
+Ya te he dicho que no queremos verte más.
-[FARE23]
-~g~Ve al ~w~taller de importación/exportación~g~ en el distrito de la presa Cochrane.
+[MOB_67A]
+Tommy, creo que no deberías acercarte, ¿me oyes?
-[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.
+[MOB_67B]
+Los chicos haitianos no están muy contentos contigo.
-[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_18A]
+Tommy, soy Paulo, ¿cómo estás? Vale hombre, bueno pensé que tenía que mandarte una nota.
-[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_18B]
+Oh Dios misericordioso, hijo mío, no te vas a creer la categoría de la furcia que acabo de conocer.
-[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_18C]
+Prostituta callejera o algo parecido, cerca de Little Havana, tío.
-[AS1_C]
-Ella cuenta con tres escuadrones de la muerte que patrullan por Liberty con el único fin de darte caza.
+[MOB_18D]
+Me dijo que se llamaba Mercedes o algo así.
-[AS1_G]
-~r~¡Todos los yakuza están muertos!
+[MOB_18E]
+Oh Dios, tío, tienes que probar a esa palomita.
-[JAN]
-Ene
+[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.
-[FEB]
-Feb
+[MOB_18G]
+Estate al tanto por si la ves. Hasta luego.
-[MAR]
-Mar
+[MOB_72A]
+Tommy, soy yo, Lance. Mantén la boca cerrada Tommy porque no tengo ganas de hablar.
-[APR]
-Abr
+[MOB_72B]
+No estoy interesado en lo que tengas que decir. ¿Por qué debería estarlo? ¿Te preocupas tú por mí?
-[MAY]
-May
+[MOB_72C]
+Tienes que cuidarme un poco mejor. Darme una buena tajada, ya sabes...
-[JUN]
-Jun
+[MOB_72D]
+Tommy... oh, mira, tío, Lo siento. Es solo que...
-[JUL]
-Jul
+[MOB_72E]
+La gente me ha estado sobreprotegiendo toda mi vida, tratándome como a un niño.
-[AUG]
-Ago
+[MOB_72F]
+Mi hermano haría eso. Por favor, tío, no lo hagas.
-[SEP]
-Sept
+[MOB_72G]
+Tengo que irme.
-[OCT]
-Oct
+[MOB_63A]
+Tommy, soy Earnest. Earnest Kelly.
-[NOV]
-Nov
+[MOB_63B]
+¿Cómo estás?
-[DEC]
-Dic
+[MOB_63C]
+Estoy bien. Necesitaré un bastón para andar pero muy pronto volveré al trabajo.
-[DEFDT]
---:---:---- --:--:--
+[MOB_63D]
+Bien.
-[BUGGY]
-COCHES RESTANTES:
+[MOB_63E]
+Me enteré de lo de Lance. Vaya cabroncete, ¿eh?
-[BONUS]
-~g~PRIMA DE ~1~ $
+[MOB_63F]
+Sí.
-[HORN1]
-Pulsa el ~h~botón L3~w~ para tocar el ~h~claxon.
+[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.
-[HORN2]
-Pulsa el ~h~botón L1~w~ para tocar el ~h~claxon.
+[MOB_63H]
+Creo que sí. Lo que pasa es que yo no creí que...
-[HORN3]
-Pulsa el ~h~botón R1~w~ para tocar el ~h~claxon.
+[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.
-[LM3_1A]
-Pulsa ~h~~k~~VEHICLE_HORN~~w~ para tocar el ~h~claxon~w~ y avisar a Misty.
+[MOB_63J]
+Tómate tu tiempo, Earnest. Cuídate.
-[LM3_1B]
-Pulsa ~h~~k~~VEHICLE_HORN~~w~ para tocar el ~h~claxon~w~ y avisar a Misty.
+[MOB_16A]
+Tommy, soy Paulo, ¿qué pasa amigo?
-[LM3_1C]
-Pulsa ~h~~k~~VEHICLE_HORN~~w~ para tocar el ~h~claxon~w~ y avisar a Misty.
+[MOB_16B]
+Qué quieres Paul. No necesito ropa de marca de imitación.
-[RADIO_A]
-Pulsa ~h~~k~~VEHICLE_CHANGE_RADIO_STATION~~w~ para cambiar de ~h~emisora de radio.
+[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.
-[RADIO_B]
-Pulsa ~h~~k~~VEHICLE_CHANGE_RADIO_STATION~~w~ para cambiar de ~h~emisora de radio.
+[MOB_16D]
+Allí en Inglaterra hice un montón de porno, colega. Soy bastante más ardiente que tú, pequeño.
-[RADIO_C]
-Pulsa ~h~~k~~VEHICLE_CHANGE_RADIO_STATION~~w~ para cambiar de ~h~emisora de radio.
+[MOB_16E]
+Paul, gracias por la oferta, lo tendré en cuenta.
-[RADIO_D]
-Pulsa ~h~~k~~VEHICLE_CHANGE_RADIO_STATION~~w~ para cambiar de ~h~emisora de radio.
+[MOB_16F]
+En serio, después de todo lo que he hecho por ti, no te olvides de mí.
-[FEC_EXV]
-Entrar/salir de vehículo
+[MOB_16G]
+Eso es lo que intento olvidar.
-[TAXI_M]
-'TAXISTA'
+[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...
-[COP_M]
-'JUSTICIERO'
+[MOB_17B]
+Paul, estás borracho.
-[FIRE_M]
-'BOMBERO'
+[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.
-[AMBUL_M]
-'CONDUCTOR DE AMBULANCIA'
+[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_IS]
-PREMIO POR ACROBACIA DEMENCIAL: ~1~ $
+[MOB_17F]
+¿De verdad?
-[HJ_PIS]
-PREMIO POR ACROBACIA DEMENCIAL 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_DIS]
-PREMIO POR ACROBACIA DEMENCIAL DOBLE: ~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_PDIS]
-PREMIO POR ACROBACIA DEMENCIAL DOBLE PERFECTA: ~1~ $
+[MOB_17I]
+Paul, tranquilízate. He estado muy ocupado, no te comportes como un idiota..
-[HJ_TIS]
-PREMIO POR ACROBACIA DEMENCIAL TRIPLE: ~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!
-[HJ_PTIS]
-PREMIO POR ACROBACIA DEMENCIAL TRIPLE PERFECTA: ~1~ $
+[MOB_17K]
+Tommy, colega. Por favor. ¡Tú eras mi gran esperanza! Por favor, ¡no te rías de mí!
-[HJ_QIS]
-PREMIO POR ACROBACIA DEMENCIAL CUÁDRUPLE: ~1~ $
+[MOB_17L]
+Paul, vete a dormir un poco, de verdad.
-[HJ_PQIS]
-PREMIO POR ACROBACIA DEMENCIAL CUÁDRUPLE PERFECTA: ~1~ $
+[MOB_73A]
+Tommy, soy Steve.
-[AM1_K]
-Salvatore Leone saldrá del club de Luigi dentro de unas tres horas. (0~1~:~1~)
+[MOB_73B]
+Eh, Steve.
-[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_73C]
+¡Eres un portento! ¡Soy un portento! La gente está loca por nosotros. Vamos a entrar en la historia, amigo.
-[VANHSTP]
-¿Quieres abrir algún Securicar? Llévalo a nuestro garaje en el puerto de Portland.
+[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.
-[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_73E]
+Eso está bien, Steve.
-[STANDS]
-PUESTOS DESTROZADOS:
+[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.
-[STASH]
-~g~¡Lleva el SPANK de vuelta al ~p~edificio en construcción~g~!
+[MOB_73G]
+Soy el mejor director de cine porno de todos los tiempos, amigo. Solo quería decirte que ha sido un placer conocerte.
-[MCSTNS]
-No hay una Memory Card (PS2) insertada en la ranura para MEMORY CARD 1. ¿Quieres empezar? (SÍ o NO)
+[MOB_73H]
+Gracias Steve.
-[LOVE3_5]
-~g~La avioneta ha llegado a la zona.
+[MOB_73I]
+Te quiero tío, No cambies, me oyes.
-[LOVE3_6]
-~r~¡La bofia ha llegado a los paquetes antes que tú!
+[MOB_73J]
+Te oigo. Adiós Steve.
-[SIREN_1]
-Para activar la sirena de este vehículo, pulsa ~h~~k~~VEHICLE_HORN~~w~.
+[BOLLOX]
+Pulsa ~h~~k~~VEHICLE_HANDBRAKE~ ~w~para soltar una bomba. Pulsa ~h~~k~~VEHICLE_ENTER_EXIT~ ~w~para cancelar.
-[SIREN_2]
-Para activar la sirena de este vehículo, pulsa ~h~~k~~VEHICLE_HORN~~w~.
+[BRID_OP]
+El temporal ha pasado, todos los puentes hacia la península están ahora abiertos.
-[FM3_8C]
-Necesitaré 100.000 dólares para cubrir gastos,
+[BRID_CL]
+Alerta de temporal: Cerrados todos los puentes hacia la península.
-[MCLOAD]
-Cargando datos. No extraigas la Memory Card (PS2) de la ranura de MEMORY CARD 1, ni reinicies o apagues la consola.
+[ASSET_C]
+¡CLUB POLE POSITION CONSOLIDADO!
-[FES_GME]
-Fallo al leer la Memory Card (PS2) de la ranura de MEMORY CARD 1. Compruébala e inténtalo de nuevo.
+[ASSET_D]
+El club Pole Position generará ahora unos ingresos máximos de hasta ~1~ $ al día. ¡Asegúrate de recaudarlos regularmente!
-[FESZ_QF]
-¿Seguro que quieres formatear la Memory Card (PS2) de la ranura de MEMORY CARD 1?
+[ST_WHEE]
+Mayor tiempo en caballito (seg)
-[FESZ_LS]
-Carga completada.
+[ST_STOP]
+Mayor tiempo en parada (seg)
-[RM3_5]
-~g~Tienes ~1~ de 6 paquetes de pruebas.
+[ST_2WHE]
+Mayor tiempo en dos ruedas (seg)
-[LOVE3_2]
-~g~¡Tienes todos los paquetes! Llévaselos a Donald Love.
+[ST_WHED]
+Mayor distancia en caballito (m)
-[LOVE4_4]
-~g~¡Lleva el paquete a Donald Love!
+[ST_STOD]
+Mayor distancia en parada (m)
-[FEB_SAV]
-Cargar
+[ST_2WHD]
+Mayor distancia en dos ruedas (m)
-[FEP_SAV]
-CARGAR PARTIDA
+[OUTFT11]
+Chándal
-[AS2_12A]
-~g~Cuando destruyas el primer puesto, ¡tendrás 8 mintutos antes que el cártel avise a sus camellos!
+[OUTFT12]
+Frankie
-[AS3_1A]
-~g~¡Ahora ve a la ~b~boya señalada~g~!
+[RELOAD]
+~g~¡Has conseguido la habilidad de recargar rápidamente!
-[NOCONT]
-Vuelve a conectar un mando analógico (DUALSHOCK#) o mando analógico (DUALSHOCK#2) en el puerto de mando 1 para continuar.
+[APACHE]
+Hunter entregado en el helipuerto de Ocean Beach.
-{ Possibly unused }
+[CRED369]
+JOHN MCCARDLE
-[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!
+[CRED370]
+DAVID MURDOCH
-[END_A]
-Los residentes de Cedar Grove todavía están asumiendo
+[CRED371]
+CHRIS BROWN
-[END_B]
-las consecuencias emocionales provocadas
+[CRED372]
+PAUL GREEN
-[END_C]
-por la guerra que estalló ayer en la zona.
+[CRED373]
+KYLE MILNE
-[END_D]
-Un residente local, Clive Denver, dijo a la policía
+[CRED374]
+KEVIN YUN
-[END_E]
-que vio a un hombre armado huyendo de la escena, acompañado de una mujer de pelo negro.
+[CRED375]
+ERICK COBBS
-[END_F]
-¿Sabes? Vamos a pasar un buen rato, porque, como sabes...
+[CRED376]
+RANDY BLAKE
-[END_G]
-¡Te amo! Yo, yo, yo realmente te amo, porque eres superfuerte,
+[CRED377]
+BRANDON LIM
-[END_H]
-y eso es todo lo que necesito.
+[CRED378]
+BRANDON FENOL
-[END_I]
-Bueno, ¿qué estaba diciendo?
+[CRED379]
+MICHAEL MANOLE
-[END_J]
-Lo he olvidado. Pero me entiendes, ¿verdad?
+[CRED380]
+ALETHEIA SIMONSON
-[END_K]
-Las explosiones sacudieron las casas más próximas mientra sus residentes buscaban refugio.
+[CRED381]
+JOHN JANSEN
-[END_L]
-Varios ciudadanos resultaron heridos entre el caos debido al tiroteo
+[CUNTY]
+¡Ropa nueva entregada en la finca de Vercetti!
-[END_M]
-entre las fuerzas terrestres y un helicóptero que rodeaba a la presa.
+[GOODBOY]
+¡Prima de 50 $ por comportamiento ejemplar!
-[END_N]
-Sí, en estos jardines tuvimos una vista excelente.
+[NEWCONT]
+¡Nuevo ~h~punto de contacto ~w~disponible en el puerto deportivo en Ocean Beach!
-[END_O]
-El momento en el que derribaron el helicóptero
+[FIRELVL]
+Misión de camión de bomberos nivel ~1~
-[END_P]
-fue mejor que los fuegos artificiales del 4 de julio.
-[END_Q]
-El número de víctimas asciende a las veinte
+[HELP56]
+Pulsa ~h~~k~~CAMERA_CHANGE_VIEW_ALL_SITUATIONS~~w~ para ajustar la cámara.
-[END_R]
-mientras la policía sigue encontrando cuerpos.
+[HELP57]
+Pulsa ~h~~k~~CAMERA_CHANGE_VIEW_ALL_SITUATIONS~~w~ para ajustar la cámara.
-[END_S]
-No se han negado oficialmente los rumores
+[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_T]
-de que las víctimas eran miembros del cártel colombiano,
+[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_U]
-y aún no hay pistas que aclaren las causas de la masacre.
+[HELP60]
+Si pulsas ~h~~k~~PED_SPRINT~ ~w~ mientras estás robando un coche, no te subirás en él.
-[END_V]
-Me he roto una uña y me pelo está hecho un asco, ¿puedes creerlo?
+[HELP61]
+Ahora dispones de munición ilimitada y el doble de robustez en todos los vehículos.
-[PAPER1]
-CRIMINAL HERIDO DE BALA POR SU NOVIA Y CÓMPLICE; EL TRIBUNAL ENCUENTRA CULPABLE AL ATRACADOR CON UN VEREDICTO UNÁNIME.
+[FEC_LB1]
+Mirar
-[PAPER2]
-¡DIEZ AÑOS POR AMOR!
+[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
@@ -6998,43 +6874,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
@@ -7076,7 +6952,7 @@ Misiones secundarias
Cambiar emisora de radio
[FEC_ENT]
-Entrar /salir de vehículo
+Entrar/salir de vehículo
[FEC_WPN]
Disparar arma
@@ -7085,105 +6961,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]
-Barrio rojo
-
-[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
@@ -7198,28 +6994,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.
@@ -7227,783 +7023,7231 @@ 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
-[FEG_PLY]
-JUGADORES
+[FEC_DLL]
+SUPR
-[FEG_TYP]
-TIPO
+[FEC_HME]
+INICIO
-[FEG_PNG]
-PING
+[FEC_END]
+FIN
-[FET_FG]
-ENCONTRAR PARTIDA
+[FEC_PGU]
+RE PÁG
-[FET_SP]
-UN JUGADOR
+[FEC_PGD]
+AV PÁG
-[FET_MP]
-MULTIJUGADOR
+[FEC_UPA]
+ARRIBA
-[FET_HG]
-CREAR PARTIDA
+[FEC_DWA]
+ABAJO
-[FET_PS]
-AJUSTES DE JUGADOR
+[FEC_LFA]
+IZDA
-[FET_CON]
-CONEXIÓN
+[FEC_RFA]
+DCHA
-[FET_AUD]
-AJUSTES DE AUDIO
+[FEC_NUM]
+NUM.
-[FET_GFX]
-AJUSTES GRÁFICOS
+[FEC_NMN]
+NUM. ~1~
-[FET_DIS]
-AJUSTES DE PANTALLA
+[FEC_FWS]
+NUM. /
-[FET_LAN]
-AJUSTES DE IDIOMA
+[FEC_PLS]
+NUM. +
-[FET_LG]
-CARGAR PARTIDA
+[FEC_MIN]
+NUM. -
-[FET_DG]
-BORRAR PARTIDA
+[FEC_DOT]
+NUM. .
-[FET_NG]
-NUEVA PARTIDA
+[FEC_NLK]
+BLOQ NUM
-[FET_SG]
-GUARDAR PARTIDA
+[FEC_ETR]
+INTRO
-[FET_MAP]
-ELEGIR MAPA
+[FEC_SLK]
+BLOQ DESPL
-[FET_GT]
-TIPO DE JUEGO
+[FEC_PSB]
+PAUSA INTER
-[FET_CTL]
-AJUSTES DEL MANDO
+[FEC_BSP]
+RETROCESO
-[FET_OPT]
-OPCIONES
+[FEC_TAB]
+TAB
+
+[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
-[FED_CON]
-Confirmación de borrado
+[CVT_MSG]
+Convertir texturas a un formato óptimo para tu tarjeta de vídeo
-[FES_SSC]
-Partida guardada.
+[FEC_SFT]
+MAYÚS
+
+[FEH_VMP]
+VER MAPA
+
+[FES_DEE]
+¡Error al eliminar! Por favor, inténtalo de nuevo.
-[DEL_FNM]
-Partida eliminada.
+[FES_CMP]
+¡Error al guardar! Por favor, inténtalo de nuevo.
-[PCLOAD]
-Cargando datos de la partida
+[FESZ_WR]
+Guardando partida actual. Por favor, espera...
+
+[FELD_WR]
+Cargando el juego. Por favor, espera...
+
+[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 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]
-SINCRONÍA DE 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]
+Pulsa ~h~~k~~PED_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]
+Pulsa ~h~~k~~PED_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]
+Para ~h~disparar hacia el frente ~w~sobre una ~h~moto ~w~pulsa ~h~~k~~PED_FIREWEAPON~~w~.
+
+[GEN3_41:GENERA3]
+Para ~h~disparar hacia el frente ~w~sobre una ~h~moto ~w~pulsa ~h~~k~~PED_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]
+Para ~h~disparar hacia el frente ~w~sobre una ~h~moto ~w~pulsa ~h~~k~~PED_FIREWEAPON~~w~.
+
+[GEN3_65:GENERA3]
+Para ~h~disparar hacia el frente ~w~sobre una ~h~moto ~w~pulsa ~h~~k~~PED_FIREWEAPON~~w~.
+
+[GEN3_66:GENERA3]
+Para ~h~disparar hacia el frente ~w~sobre una ~h~moto ~w~pulsa ~h~~k~~PED_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]
+Pulsa ~h~~k~~PED_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.
-{ re3 updates }
+[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?
+
+[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]
+~g~Si deseas abandonar esta misión, pulsa ~h~~k~~PED_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]
+~g~Si deseas abandonar esta misión, pulsa ~h~~k~~PED_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]
+~g~Para soltar una bomba pulsa ~h~~k~~PED_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]
+~g~Para soltar una bomba pulsa ~h~~k~~PED_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]
+Pulsa ~h~~k~~VEHICLE_ACCELERATE~~w~ para aumentar la velocidad del rotor y así ~h~ascender~w~.
+
+[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
@@ -8016,7 +14260,7 @@ RUSO
{ new display menus }
[FET_GRA]
-AJUSTES GRÁFICOS
+CONFIGURACIÓN DE GRÁFICOS
[FED_MIP]
MIPMAPPING
@@ -8123,7 +14367,6 @@ XBOX
INVERTIR VERTICALIDAD MANDO
{ end of file }
-
[DUMMY]
THIS LABEL NEEDS TO BE HERE !!!
AS THE LAST LABEL DOES NOT GET COMPILED \ No newline at end of file