summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorNikolay Korolev <nickvnuk@gmail.com>2021-01-01 11:21:42 +0100
committerNikolay Korolev <nickvnuk@gmail.com>2021-01-01 11:21:42 +0100
commit575845772fc3f5385eab56044cf97ef0ce930e17 (patch)
tree1b51da6e1759bac72bec1392435c453eaee60158 /src
parentlcs car ctrl 2 (diff)
parentMerge branch 'miami' of github.com:GTAmodding/re3 into miami (diff)
downloadre3-575845772fc3f5385eab56044cf97ef0ce930e17.tar
re3-575845772fc3f5385eab56044cf97ef0ce930e17.tar.gz
re3-575845772fc3f5385eab56044cf97ef0ce930e17.tar.bz2
re3-575845772fc3f5385eab56044cf97ef0ce930e17.tar.lz
re3-575845772fc3f5385eab56044cf97ef0ce930e17.tar.xz
re3-575845772fc3f5385eab56044cf97ef0ce930e17.tar.zst
re3-575845772fc3f5385eab56044cf97ef0ce930e17.zip
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt113
-rw-r--r--src/animation/AnimBlendAssociation.cpp10
-rw-r--r--src/animation/AnimBlendClumpData.cpp2
-rw-r--r--src/animation/AnimBlendClumpData.h12
-rw-r--r--src/animation/AnimBlendHierarchy.cpp30
-rw-r--r--src/animation/AnimBlendHierarchy.h9
-rw-r--r--src/animation/AnimBlendNode.cpp127
-rw-r--r--src/animation/AnimBlendNode.h4
-rw-r--r--src/animation/AnimBlendSequence.cpp137
-rw-r--r--src/animation/AnimBlendSequence.h63
-rw-r--r--src/animation/AnimManager.cpp148
-rw-r--r--src/animation/AnimManager.h4
-rw-r--r--src/animation/CutsceneMgr.cpp21
-rw-r--r--src/animation/FrameUpdate.cpp222
-rw-r--r--src/animation/RpAnimBlend.cpp14
-rw-r--r--src/animation/RpAnimBlend.h3
-rw-r--r--src/audio/AudioCollision.cpp34
-rw-r--r--src/audio/AudioLogic.cpp1748
-rw-r--r--src/audio/AudioManager.cpp15
-rw-r--r--src/audio/AudioManager.h191
-rw-r--r--src/audio/AudioSamples.h3
-rw-r--r--src/audio/MusicManager.cpp10
-rw-r--r--src/audio/PoliceRadio.cpp2
-rw-r--r--src/audio/audio_enums.h2
-rw-r--r--src/audio/oal/oal_utils.cpp11
-rw-r--r--src/audio/oal/oal_utils.h7
-rw-r--r--src/audio/oal/stream.cpp6
-rw-r--r--src/audio/sampman_miles.cpp4
-rw-r--r--src/audio/soundlist.h6
-rw-r--r--src/buildings/Building.cpp (renamed from src/entities/Building.cpp)4
-rw-r--r--src/buildings/Building.h (renamed from src/entities/Building.h)0
-rw-r--r--src/buildings/Solid.h (renamed from src/entities/Solid.h)0
-rw-r--r--src/buildings/Treadable.cpp (renamed from src/entities/Treadable.cpp)0
-rw-r--r--src/buildings/Treadable.h (renamed from src/entities/Treadable.h)0
-rw-r--r--src/collision/ColModel.cpp8
-rw-r--r--src/collision/ColStore.cpp (renamed from src/core/ColStore.cpp)2
-rw-r--r--src/collision/ColStore.h (renamed from src/core/ColStore.h)0
-rw-r--r--src/collision/Collision.cpp14
-rw-r--r--src/collision/TempColModels.cpp2
-rw-r--r--src/control/AutoPilot.cpp6
-rw-r--r--src/control/AutoPilot.h12
-rw-r--r--src/control/CarAI.cpp4
-rw-r--r--src/control/CarAI.h4
-rw-r--r--src/control/CarCtrl.cpp36
-rw-r--r--src/control/Darkel.cpp9
-rw-r--r--src/control/GameLogic.cpp10
-rw-r--r--src/control/Garages.cpp395
-rw-r--r--src/control/Garages.h32
-rw-r--r--src/control/NameGrid.cpp87
-rw-r--r--src/control/NameGrid.h53
-rw-r--r--src/control/PathFind.cpp10
-rw-r--r--src/control/Phones.cpp8
-rw-r--r--src/control/Pickups.cpp128
-rw-r--r--src/control/Pickups.h4
-rw-r--r--src/control/Record.h2
-rw-r--r--src/control/Replay.cpp49
-rw-r--r--src/control/Replay.h35
-rw-r--r--src/control/Restart.cpp4
-rw-r--r--src/control/RoadBlocks.cpp6
-rw-r--r--src/control/SceneEdit.cpp3
-rw-r--r--src/control/SceneEdit.h3
-rw-r--r--src/control/Script.cpp11560
-rw-r--r--src/control/Script.h56
-rw-r--r--src/control/Script2.cpp1558
-rw-r--r--src/control/Script3.cpp2134
-rw-r--r--src/control/Script4.cpp2334
-rw-r--r--src/control/Script5.cpp2072
-rw-r--r--src/control/Script6.cpp1803
-rw-r--r--src/control/Script7.cpp1402
-rw-r--r--src/control/Script8.cpp613
-rw-r--r--src/control/ScriptCommands.h33
-rw-r--r--src/control/SetPieces.cpp2
-rw-r--r--src/control/SetPieces.h4
-rw-r--r--src/core/AnimViewer.cpp60
-rw-r--r--src/core/Cam.cpp145
-rw-r--r--src/core/Camera.cpp72
-rw-r--r--src/core/Camera.h2
-rw-r--r--src/core/CdStream.cpp14
-rw-r--r--src/core/CdStreamPosix.cpp4
-rw-r--r--src/core/ControllerConfig.cpp244
-rw-r--r--src/core/EventList.cpp5
-rw-r--r--src/core/EventList.h2
-rw-r--r--src/core/FileLoader.cpp118
-rw-r--r--src/core/FileMgr.cpp14
-rw-r--r--src/core/FileMgr.h6
-rw-r--r--src/core/Fire.cpp38
-rw-r--r--src/core/Frontend.cpp2285
-rw-r--r--src/core/Frontend.h213
-rw-r--r--src/core/Frontend_PS2.cpp4
-rw-r--r--src/core/Game.cpp578
-rw-r--r--src/core/General.h9
-rw-r--r--src/core/MenuScreens.cpp75
-rw-r--r--src/core/MenuScreensCustom.cpp716
-rw-r--r--src/core/Pad.cpp44
-rw-r--r--src/core/PlayerInfo.cpp630
-rw-r--r--src/core/PlayerInfo.h25
-rw-r--r--src/core/Pools.cpp21
-rw-r--r--src/core/References.cpp77
-rw-r--r--src/core/Stats.cpp723
-rw-r--r--src/core/Stats.h6
-rw-r--r--src/core/Streaming.cpp212
-rw-r--r--src/core/Streaming.h8
-rw-r--r--src/core/World.cpp333
-rw-r--r--src/core/World.h14
-rw-r--r--src/core/ZoneCull.h12
-rw-r--r--src/core/Zones.cpp6
-rw-r--r--src/core/common.h19
-rw-r--r--src/core/config.h93
-rw-r--r--src/core/main.cpp875
-rw-r--r--src/core/main.h10
-rw-r--r--src/core/re3.cpp210
-rw-r--r--src/core/templates.h79
-rw-r--r--src/entities/Dummy.cpp2
-rw-r--r--src/entities/Entity.cpp1020
-rw-r--r--src/entities/Entity.h28
-rw-r--r--src/extras/custompipes.cpp10
-rw-r--r--src/extras/custompipes.h1
-rw-r--r--src/extras/custompipes_d3d9.cpp18
-rw-r--r--src/extras/custompipes_gl.cpp54
-rw-r--r--src/extras/debugmenu.cpp2
-rw-r--r--src/extras/debugmenu.h2
-rw-r--r--src/extras/frontendoption.cpp167
-rw-r--r--src/extras/frontendoption.h86
-rw-r--r--src/extras/postfx.cpp33
-rw-r--r--src/extras/postfx.h1
-rw-r--r--src/extras/re3_inttypes.h (renamed from src/extras/inttypes.h)0
-rw-r--r--src/extras/screendroplets.cpp817
-rw-r--r--src/extras/screendroplets.h78
-rw-r--r--src/extras/shaders/Makefile69
-rw-r--r--src/extras/shaders/colourfilterVC.frag13
-rw-r--r--src/extras/shaders/colourfilterVC_fs_gl.inc (renamed from src/extras/shaders/colourfilterVC_fs_gl3.inc)13
-rw-r--r--src/extras/shaders/contrast.frag11
-rw-r--r--src/extras/shaders/contrast_fs_gl.inc (renamed from src/extras/shaders/contrast_fs_gl3.inc)11
-rw-r--r--src/extras/shaders/default_UV2.vert14
-rw-r--r--src/extras/shaders/default_UV2_gl.inc (renamed from src/extras/shaders/default_UV2_gl3.inc)14
-rw-r--r--src/extras/shaders/im2d.vert10
-rw-r--r--src/extras/shaders/im2d_UV2.vert21
-rw-r--r--src/extras/shaders/im2d_UV2_gl.inc23
-rw-r--r--src/extras/shaders/im2d_gl.inc (renamed from src/extras/shaders/im2d_gl3.inc)10
-rw-r--r--src/extras/shaders/neoGloss.frag14
-rw-r--r--src/extras/shaders/neoGloss.vert14
-rw-r--r--src/extras/shaders/neoGloss_fs_gl.inc (renamed from src/extras/shaders/neoGloss_fs_gl3.inc)14
-rw-r--r--src/extras/shaders/neoGloss_vs_gl.inc (renamed from src/extras/shaders/neoGloss_vs_gl3.inc)14
-rw-r--r--src/extras/shaders/neoRim.vert13
-rw-r--r--src/extras/shaders/neoRimSkin.vert15
-rw-r--r--src/extras/shaders/neoRimSkin_gl.inc (renamed from src/extras/shaders/neoRimSkin_gl3.inc)15
-rw-r--r--src/extras/shaders/neoRim_gl.inc (renamed from src/extras/shaders/neoRim_gl3.inc)13
-rw-r--r--src/extras/shaders/neoVehicle.frag15
-rw-r--r--src/extras/shaders/neoVehicle.vert17
-rw-r--r--src/extras/shaders/neoVehicle_fs_gl.inc (renamed from src/extras/shaders/neoVehicle_fs_gl3.inc)15
-rw-r--r--src/extras/shaders/neoVehicle_vs_gl.inc (renamed from src/extras/shaders/neoVehicle_vs_gl3.inc)17
-rw-r--r--src/extras/shaders/neoWorldVC.frag15
-rw-r--r--src/extras/shaders/neoWorldVC_fs_gl.inc (renamed from src/extras/shaders/neoWorldVC_fs_gl3.inc)15
-rw-r--r--src/extras/shaders/screenDroplet.frag18
-rw-r--r--src/extras/shaders/screenDroplet_PS.csobin0 -> 324 bytes
-rw-r--r--src/extras/shaders/screenDroplet_PS.hlsl17
-rw-r--r--src/extras/shaders/screenDroplet_PS.inc29
-rw-r--r--src/extras/shaders/screenDroplet_fs_gl.inc20
-rw-r--r--src/extras/shaders/simple.frag11
-rw-r--r--src/extras/shaders/simple_fs_gl.inc (renamed from src/extras/shaders/simple_fs_gl3.inc)11
-rw-r--r--src/fakerw/fake.cpp60
-rw-r--r--src/fakerw/rwcore.h2
-rw-r--r--src/fakerw/rwplcore.h6
-rw-r--r--src/math/Matrix.h9
-rw-r--r--src/math/Quaternion.h5
-rw-r--r--src/math/Vector.h29
-rw-r--r--src/math/VuVector.h13
-rw-r--r--src/modelinfo/BaseModelInfo.cpp4
-rw-r--r--src/modelinfo/BaseModelInfo.h11
-rw-r--r--src/modelinfo/ModelIndices.cpp2
-rw-r--r--src/modelinfo/ModelInfo.cpp42
-rw-r--r--src/modelinfo/PedModelInfo.h1
-rw-r--r--src/modelinfo/TimeModelInfo.cpp3
-rw-r--r--src/modelinfo/VehicleModelInfo.cpp20
-rw-r--r--src/modelinfo/VehicleModelInfo.h2
-rw-r--r--src/objects/Object.cpp586
-rw-r--r--src/objects/Object.h14
-rw-r--r--src/objects/ParticleObject.cpp6
-rw-r--r--src/objects/ParticleObject.h2
-rw-r--r--src/objects/Projectile.h2
-rw-r--r--src/peds/CivilianPed.cpp32
-rw-r--r--src/peds/CivilianPed.h4
-rw-r--r--src/peds/CopPed.cpp17
-rw-r--r--src/peds/CopPed.h4
-rw-r--r--src/peds/EmergencyPed.cpp16
-rw-r--r--src/peds/EmergencyPed.h4
-rw-r--r--src/peds/Ped.cpp22511
-rw-r--r--src/peds/Ped.h97
-rw-r--r--src/peds/PedAI.cpp6939
-rw-r--r--src/peds/PedAttractor.cpp19
-rw-r--r--src/peds/PedChat.cpp9
-rw-r--r--src/peds/PedFight.cpp4217
-rw-r--r--src/peds/PedIK.h1
-rw-r--r--src/peds/PedStats.cpp120
-rw-r--r--src/peds/PedStats.h85
-rw-r--r--src/peds/PedType.cpp125
-rw-r--r--src/peds/PedType.h84
-rw-r--r--src/peds/PlayerPed.cpp747
-rw-r--r--src/peds/PlayerPed.h24
-rw-r--r--src/render/Clouds.cpp2
-rw-r--r--src/render/Coronas.cpp242
-rw-r--r--src/render/Fluff.cpp8
-rw-r--r--src/render/Font.cpp201
-rw-r--r--src/render/Font.h39
-rw-r--r--src/render/Glass.cpp8
-rw-r--r--src/render/Hud.cpp15
-rw-r--r--src/render/MBlur.cpp365
-rw-r--r--src/render/MBlur.h23
-rw-r--r--src/render/Occlusion.cpp39
-rw-r--r--src/render/Particle.cpp110
-rw-r--r--src/render/Particle.h5
-rw-r--r--src/render/PlayerSkin.cpp3
-rw-r--r--src/render/PointLights.cpp4
-rw-r--r--src/render/Renderer.cpp183
-rw-r--r--src/render/Renderer.h21
-rw-r--r--src/render/Shadows.cpp4
-rw-r--r--src/render/SpecialFX.cpp32
-rw-r--r--src/render/WaterLevel.cpp370
-rw-r--r--src/render/WaterLevel.h41
-rw-r--r--src/render/Weather.cpp2
-rw-r--r--src/rw/Lights.cpp41
-rw-r--r--src/rw/Lights.h2
-rw-r--r--src/rw/MemoryHeap.cpp499
-rw-r--r--src/rw/MemoryHeap.h204
-rw-r--r--src/rw/MemoryMgr.cpp130
-rw-r--r--src/rw/MemoryMgr.h12
-rw-r--r--src/rw/RwHelper.cpp68
-rw-r--r--src/rw/RwHelper.h5
-rw-r--r--src/rw/TexRead.cpp109
-rw-r--r--src/rw/TexturePools.cpp221
-rw-r--r--src/rw/TexturePools.h42
-rw-r--r--src/rw/VisibilityPlugins.cpp87
-rw-r--r--src/rw/VisibilityPlugins.h6
-rw-r--r--src/save/MemoryCard.cpp1
-rw-r--r--src/skel/crossplatform.cpp14
-rw-r--r--src/skel/crossplatform.h7
-rw-r--r--src/skel/glfw/glfw.cpp165
-rw-r--r--src/skel/skeleton.cpp6
-rw-r--r--src/skel/skeleton.h3
-rw-r--r--src/skel/win/win.cpp73
-rw-r--r--src/text/Text.cpp8
-rw-r--r--src/vehicles/Automobile.cpp194
-rw-r--r--src/vehicles/Automobile.h8
-rw-r--r--src/vehicles/Bike.cpp24
-rw-r--r--src/vehicles/Boat.cpp15
-rw-r--r--src/vehicles/Cranes.cpp6
-rw-r--r--src/vehicles/Cranes.h8
-rw-r--r--src/vehicles/HandlingMgr.cpp21
-rw-r--r--src/vehicles/HandlingMgr.h26
-rw-r--r--src/vehicles/Heli.cpp2
-rw-r--r--src/vehicles/Plane.cpp7
-rw-r--r--src/vehicles/Train.cpp2
-rw-r--r--src/vehicles/Vehicle.cpp2
-rw-r--r--src/vehicles/Vehicle.h15
-rw-r--r--src/weapons/Explosion.cpp7
-rw-r--r--src/weapons/ProjectileInfo.cpp6
-rw-r--r--src/weapons/ShotInfo.cpp6
-rw-r--r--src/weapons/Weapon.cpp60
-rw-r--r--src/weapons/WeaponEffects.cpp4
-rw-r--r--src/weapons/WeaponInfo.cpp40
-rw-r--r--src/weapons/WeaponInfo.h54
261 files changed, 43843 insertions, 34258 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
new file mode 100644
index 00000000..e87878a8
--- /dev/null
+++ b/src/CMakeLists.txt
@@ -0,0 +1,113 @@
+set(THREADS_PREFER_PTHREAD_FLAG ON)
+find_package(Threads REQUIRED)
+
+if(${REVC_AUDIO} STREQUAL "OAL")
+ find_package(OpenAL REQUIRED)
+ find_package(MPG123 REQUIRED)
+ find_package(SndFile REQUIRED)
+endif()
+
+file(GLOB_RECURSE Sources "*.cpp" "*.h")
+
+MACRO(HEADER_DIRECTORIES return_list)
+ FILE(GLOB_RECURSE new_list *.cpp)
+ SET(dir_list "animation"
+ "audio"
+ "collision"
+ "control"
+ "core"
+ "entities"
+ "extras"
+ "fakerw"
+ "math"
+ "modelinfo"
+ "objects"
+ "peds"
+ "render"
+ "rw"
+ "save"
+ "skel"
+ "text"
+ "vehicles"
+ "weapons")
+ FOREACH(file_path ${new_list})
+ GET_FILENAME_COMPONENT(dir_path ${file_path} PATH)
+ SET(dir_list ${dir_list} ${dir_path})
+ ENDFOREACH()
+ LIST(REMOVE_DUPLICATES dir_list)
+ SET(${return_list} ${dir_list})
+ENDMACRO()
+
+HEADER_DIRECTORIES(header_list)
+include_directories(${header_list})
+
+
+add_executable(reVC ${Sources})
+target_link_libraries(reVC librw)
+target_link_libraries(reVC Threads::Threads)
+
+if(${REVC_AUDIO} STREQUAL "OAL")
+ target_link_libraries(reVC ${OPENAL_LIBRARY})
+ target_link_libraries(reVC ${MPG123_LIBRARIES})
+ target_link_libraries(reVC ${SNDFILE_LIBRARIES})
+endif()
+
+target_include_directories(reVC
+ INTERFACE
+ $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}>
+ )
+
+target_compile_definitions(reVC
+ PRIVATE
+ "$<IF:$<CONFIG:DEBUG>,DEBUG,NDEBUG>"
+ PUBLIC
+ "RW_${REVC_PLATFORM}"
+ )
+
+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(reVC
+ PRIVATE
+ "-Wall"
+ )
+ if (NOT REVC_PLATFORM_PS2)
+ target_compile_options(reVC
+ PRIVATE
+ "-Wextra"
+ "-Wdouble-promotion"
+ "-Wpedantic"
+ )
+ endif()
+elseif(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
+ target_compile_options(reVC
+ PUBLIC
+ /wd4996 /wd4244
+ )
+endif()
+
+set_target_properties(reVC
+ PROPERTIES
+ C_STANDARD 11
+ C_EXTENSIONS OFF
+ C_STANDARD_REQUIRED ON
+ CXX_STANDARD 11
+ CXX_EXTENSIONS OFF
+ CXX_STANDARD_REQUIRED ON
+ PREFIX ""
+ )
+
+if(REVC_INSTALL)
+ target_include_directories(reVC
+ INTERFACE
+ $<INSTALL_INTERFACE:${REVC_INSTALL_INCLUDEDIR}>
+ )
+
+ install(
+ TARGETS reVC
+ EXPORT reVC-targets
+ RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}"
+ LIBRARY DESTINATION "${CMAKE_INSTALL_LIBDIR}"
+ ARCHIVE DESTINATION "${CMAKE_INSTALL_LIBDIR}"
+ )
+endif()
diff --git a/src/animation/AnimBlendAssociation.cpp b/src/animation/AnimBlendAssociation.cpp
index a6c679eb..b91b35ee 100644
--- a/src/animation/AnimBlendAssociation.cpp
+++ b/src/animation/AnimBlendAssociation.cpp
@@ -5,7 +5,7 @@
#include "RpAnimBlend.h"
#include "AnimManager.h"
#include "AnimBlendAssociation.h"
-#include "RwHelper.h"
+#include "MemoryMgr.h"
//--MIAMI: file done
@@ -139,11 +139,15 @@ CAnimBlendAssociation::SetCurrentTime(float time)
}
CAnimManager::UncompressAnimation(hierarchy);
- if(hierarchy->compressed2){
+#ifdef ANIM_COMPRESSION
+ // strangely PC has this but android doesn't
+ if(hierarchy->keepCompressed){
for(i = 0; i < numNodes; i++)
if(nodes[i].sequence)
nodes[i].SetupKeyFrameCompressed();
- }else{
+ }else
+#endif
+ {
for(i = 0; i < numNodes; i++)
if(nodes[i].sequence)
nodes[i].FindKeyFrame(currentTime);
diff --git a/src/animation/AnimBlendClumpData.cpp b/src/animation/AnimBlendClumpData.cpp
index 5f7491fe..4e8f3153 100644
--- a/src/animation/AnimBlendClumpData.cpp
+++ b/src/animation/AnimBlendClumpData.cpp
@@ -1,7 +1,7 @@
#include "common.h"
#include "AnimBlendClumpData.h"
-#include "RwHelper.h"
+#include "MemoryMgr.h"
//--MIAMI: file done
diff --git a/src/animation/AnimBlendClumpData.h b/src/animation/AnimBlendClumpData.h
index af7e5df5..633fc7b9 100644
--- a/src/animation/AnimBlendClumpData.h
+++ b/src/animation/AnimBlendClumpData.h
@@ -12,24 +12,18 @@ struct AnimBlendFrameData
VELOCITY_EXTRACTION = 8,
VELOCITY_EXTRACTION_3D = 0x10,
UPDATE_KEYFRAMES = 0x20,
- UNK_COMPRESSED = 0x40,
+ 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
@@ -44,8 +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);
};
diff --git a/src/animation/AnimBlendHierarchy.cpp b/src/animation/AnimBlendHierarchy.cpp
index d3d6287a..cc7c7de8 100644
--- a/src/animation/AnimBlendHierarchy.cpp
+++ b/src/animation/AnimBlendHierarchy.cpp
@@ -65,10 +65,10 @@ CAnimBlendHierarchy::CalcTotalTimeCompressed(void)
continue;
#endif
- totalLength = Max(totalLength, sequences[i].GetKeyFrameCompressed(sequences[i].numFrames-1)->deltaTime/60.0f);
+ totalLength = Max(totalLength, sequences[i].GetKeyFrameCompressed(sequences[i].numFrames-1)->GetDeltaTime());
for(j = sequences[i].numFrames-1; j >= 1; j--){
- KeyFrame *kf1 = sequences[i].GetKeyFrameCompressed(j);
- KeyFrame *kf2 = sequences[i].GetKeyFrameCompressed(j-1);
+ KeyFrameCompressed *kf1 = sequences[i].GetKeyFrameCompressed(j);
+ KeyFrameCompressed *kf2 = sequences[i].GetKeyFrameCompressed(j-1);
kf1->deltaTime -= kf2->deltaTime;
}
}
@@ -94,6 +94,12 @@ CAnimBlendHierarchy::RemoveAnimSequences(void)
void
CAnimBlendHierarchy::Uncompress(void)
{
+#ifdef ANIM_COMPRESSION
+ int i;
+ assert(compressed);
+ for(i = 0; i < numSequences; i++)
+ sequences[i].Uncompress();
+#endif
compressed = 0;
if(totalLength == 0.0f){
RemoveQuaternionFlips();
@@ -104,6 +110,22 @@ CAnimBlendHierarchy::Uncompress(void)
void
CAnimBlendHierarchy::RemoveUncompressedData(void)
{
- // useless
+#ifdef ANIM_COMPRESSION
+ int i;
+ assert(!compressed);
+ for(i = 0; i < numSequences; i++)
+ sequences[i].RemoveUncompressedData();
+#endif
compressed = 1;
}
+
+#ifdef USE_CUSTOM_ALLOCATOR
+void
+CAnimBlendHierarchy::MoveMemory(bool onlyone)
+{
+ int i;
+ for(i = 0; i < numSequences; i++)
+ if(sequences[i].MoveMemory() && onlyone)
+ return;
+}
+#endif
diff --git a/src/animation/AnimBlendHierarchy.h b/src/animation/AnimBlendHierarchy.h
index b34ae210..4838c4f8 100644
--- a/src/animation/AnimBlendHierarchy.h
+++ b/src/animation/AnimBlendHierarchy.h
@@ -2,6 +2,10 @@
#include "templates.h"
+#ifdef MoveMemory
+#undef MoveMemory // windows shit
+#endif
+
class CAnimBlendSequence;
// A collection of sequences
@@ -11,8 +15,8 @@ public:
char name[24];
CAnimBlendSequence *sequences;
int16 numSequences;
- bool compressed; // not really used
- bool compressed2; // not really used
+ bool compressed;
+ bool keepCompressed;
float totalLength;
CLink<CAnimBlendHierarchy*> *linkPtr;
@@ -25,6 +29,7 @@ public:
void RemoveAnimSequences(void);
void Uncompress(void);
void RemoveUncompressedData(void);
+ void MoveMemory(bool onlyone = false);
bool IsCompressed() { return !!compressed; };
};
diff --git a/src/animation/AnimBlendNode.cpp b/src/animation/AnimBlendNode.cpp
index ac1328eb..d2a8dd41 100644
--- a/src/animation/AnimBlendNode.cpp
+++ b/src/animation/AnimBlendNode.cpp
@@ -48,6 +48,44 @@ CAnimBlendNode::Update(CVector &trans, CQuaternion &rot, float weight)
}
bool
+CAnimBlendNode::UpdateCompressed(CVector &trans, CQuaternion &rot, float weight)
+{
+ bool looped = false;
+
+ trans = CVector(0.0f, 0.0f, 0.0f);
+ rot = CQuaternion(0.0f, 0.0f, 0.0f, 0.0f);
+
+ if(association->IsRunning()){
+ remainingTime -= association->timeStep;
+ if(remainingTime <= 0.0f)
+ looped = NextKeyFrameCompressed();
+ }
+
+ float blend = association->GetBlendAmount(weight);
+ if(blend > 0.0f){
+ KeyFrameTransCompressed *kfA = (KeyFrameTransCompressed*)sequence->GetKeyFrameCompressed(frameA);
+ KeyFrameTransCompressed *kfB = (KeyFrameTransCompressed*)sequence->GetKeyFrameCompressed(frameB);
+ float t = kfA->deltaTime == 0 ? 0.0f : (kfA->GetDeltaTime() - remainingTime)/kfA->GetDeltaTime();
+ if(sequence->type & CAnimBlendSequence::KF_TRANS){
+ CVector transA, transB;
+ kfA->GetTranslation(&transA);
+ kfB->GetTranslation(&transB);
+ trans = transB + t*(transA - transB);
+ trans *= blend;
+ }
+ if(sequence->type & CAnimBlendSequence::KF_ROT){
+ CQuaternion rotA, rotB;
+ kfA->GetRotation(&rotA);
+ kfB->GetRotation(&rotB);
+ rot.Slerp(rotB, rotA, theta, invSin, t);
+ rot *= blend;
+ }
+ }
+
+ return looped;
+}
+
+bool
CAnimBlendNode::NextKeyFrame(void)
{
bool looped;
@@ -84,6 +122,43 @@ CAnimBlendNode::NextKeyFrame(void)
return looped;
}
+bool
+CAnimBlendNode::NextKeyFrameCompressed(void)
+{
+ bool looped;
+
+ if(sequence->numFrames <= 1)
+ return false;
+
+ looped = false;
+ frameB = frameA;
+
+ // Advance as long as we have to
+ while(remainingTime <= 0.0f){
+ frameA++;
+
+ if(frameA >= sequence->numFrames){
+ // reached end of animation
+ if(!association->IsRepeating()){
+ frameA--;
+ remainingTime = 0.0f;
+ return false;
+ }
+ looped = true;
+ frameA = 0;
+ }
+
+ remainingTime += sequence->GetKeyFrameCompressed(frameA)->GetDeltaTime();
+ }
+
+ frameB = frameA - 1;
+ if(frameB < 0)
+ frameB += sequence->numFrames;
+
+ CalcDeltasCompressed();
+ return looped;
+}
+
// Set animation to time t
bool
CAnimBlendNode::FindKeyFrame(float t)
@@ -132,7 +207,7 @@ CAnimBlendNode::SetupKeyFrameCompressed(void)
frameA = 0;
remainingTime = 0.0f;
}else
- remainingTime = sequence->GetKeyFrameCompressed(frameA)->deltaTime/60.0f;
+ remainingTime = sequence->GetKeyFrameCompressed(frameA)->GetDeltaTime();
CalcDeltasCompressed();
return true;
@@ -157,9 +232,17 @@ 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);
+ KeyFrameCompressed *kfA = sequence->GetKeyFrameCompressed(frameA);
+ KeyFrameCompressed *kfB = sequence->GetKeyFrameCompressed(frameB);
+ CQuaternion rotA, rotB;
+ kfA->GetRotation(&rotA);
+ kfB->GetRotation(&rotB);
+ float cos = DotProduct(rotA, rotB);
+ if(cos < 0.0f){
+ rotB *= -1.0f;
+ kfB->SetRotation(rotB);
+ }
+ cos = DotProduct(rotA, rotB);
if(cos > 1.0f)
cos = 1.0f;
theta = Acos(cos);
@@ -184,6 +267,26 @@ CAnimBlendNode::GetCurrentTranslation(CVector &trans, float weight)
}
void
+CAnimBlendNode::GetCurrentTranslationCompressed(CVector &trans, float weight)
+{
+ trans = CVector(0.0f, 0.0f, 0.0f);
+
+ float blend = association->GetBlendAmount(weight);
+ if(blend > 0.0f){
+ KeyFrameTransCompressed *kfA = (KeyFrameTransCompressed*)sequence->GetKeyFrameCompressed(frameA);
+ KeyFrameTransCompressed *kfB = (KeyFrameTransCompressed*)sequence->GetKeyFrameCompressed(frameB);
+ float t = kfA->deltaTime == 0 ? 0.0f : (kfA->GetDeltaTime() - remainingTime)/kfA->GetDeltaTime();
+ if(sequence->type & CAnimBlendSequence::KF_TRANS){
+ CVector transA, transB;
+ kfA->GetTranslation(&transA);
+ kfB->GetTranslation(&transB);
+ trans = transB + t*(transA - transB);
+ trans *= blend;
+ }
+ }
+}
+
+void
CAnimBlendNode::GetEndTranslation(CVector &trans, float weight)
{
trans = CVector(0.0f, 0.0f, 0.0f);
@@ -195,3 +298,19 @@ CAnimBlendNode::GetEndTranslation(CVector &trans, float weight)
trans = kf->translation * blend;
}
}
+
+void
+CAnimBlendNode::GetEndTranslationCompressed(CVector &trans, float weight)
+{
+ trans = CVector(0.0f, 0.0f, 0.0f);
+
+ float blend = association->GetBlendAmount(weight);
+ if(blend > 0.0f){
+ KeyFrameTransCompressed *kf = (KeyFrameTransCompressed*)sequence->GetKeyFrameCompressed(sequence->numFrames-1);
+ if(sequence->type & CAnimBlendSequence::KF_TRANS){
+ CVector pos;
+ kf->GetTranslation(&pos);
+ trans = pos * blend;
+ }
+ }
+}
diff --git a/src/animation/AnimBlendNode.h b/src/animation/AnimBlendNode.h
index 9446e1ae..99a657ac 100644
--- a/src/animation/AnimBlendNode.h
+++ b/src/animation/AnimBlendNode.h
@@ -20,13 +20,17 @@ public:
void Init(void);
bool Update(CVector &trans, CQuaternion &rot, float weight);
+ bool UpdateCompressed(CVector &trans, CQuaternion &rot, float weight);
bool NextKeyFrame(void);
+ bool NextKeyFrameCompressed(void);
bool FindKeyFrame(float t);
bool SetupKeyFrameCompressed(void);
void CalcDeltas(void);
void CalcDeltasCompressed(void);
void GetCurrentTranslation(CVector &trans, float weight);
+ void GetCurrentTranslationCompressed(CVector &trans, float weight);
void GetEndTranslation(CVector &trans, float weight);
+ void GetEndTranslationCompressed(CVector &trans, float weight);
};
diff --git a/src/animation/AnimBlendSequence.cpp b/src/animation/AnimBlendSequence.cpp
index b04d6b41..93cce91d 100644
--- a/src/animation/AnimBlendSequence.cpp
+++ b/src/animation/AnimBlendSequence.cpp
@@ -1,6 +1,7 @@
#include "common.h"
#include "AnimBlendSequence.h"
+#include "MemoryHeap.h"
//--MIAMI: file done
@@ -10,9 +11,7 @@ CAnimBlendSequence::CAnimBlendSequence(void)
numFrames = 0;
keyFrames = nil;
keyFramesCompressed = nil;
-#ifdef PED_SKIN
boneTag = -1;
-#endif
}
CAnimBlendSequence::~CAnimBlendSequence(void)
@@ -67,3 +66,137 @@ CAnimBlendSequence::RemoveQuaternionFlips(void)
last = frame->rotation;
}
}
+
+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/1024.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 = 1024.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)
+{
+ if(keyFrames){
+ void *newaddr = gMainHeap.MoveMemory(keyFrames);
+ if(newaddr != keyFrames){
+ keyFrames = newaddr;
+ return true;
+ }
+ }else if(keyFramesCompressed){
+ void *newaddr = gMainHeap.MoveMemory(keyFramesCompressed);
+ if(newaddr != keyFramesCompressed){
+ keyFramesCompressed = newaddr;
+ return true;
+ }
+ }
+ return false;
+}
+#endif
diff --git a/src/animation/AnimBlendSequence.h b/src/animation/AnimBlendSequence.h
index 6d8c98aa..67118b2f 100644
--- a/src/animation/AnimBlendSequence.h
+++ b/src/animation/AnimBlendSequence.h
@@ -2,6 +2,10 @@
#include "Quaternion.h"
+#ifdef MoveMemory
+#undef MoveMemory // windows shit
+#endif
+
// TODO: put them somewhere else?
struct KeyFrame {
CQuaternion rotation;
@@ -12,6 +16,43 @@ struct KeyFrameTrans : KeyFrame {
CVector translation;
};
+struct KeyFrameCompressed {
+ int16 rot[4]; // 4096
+ int16 deltaTime; // 60
+
+ void GetRotation(CQuaternion *quat){
+ float scale = 1.0f/4096.0f;
+ quat->x = rot[0]*scale;
+ quat->y = rot[1]*scale;
+ quat->z = rot[2]*scale;
+ quat->w = rot[3]*scale;
+ }
+ void SetRotation(const CQuaternion &quat){
+ rot[0] = quat.x * 4096.0f;
+ rot[1] = quat.y * 4096.0f;
+ rot[2] = quat.z * 4096.0f;
+ rot[3] = quat.w * 4096.0f;
+ }
+ float GetDeltaTime(void) { return deltaTime/60.0f; }
+ void SetTime(float t) { deltaTime = t*60.0f + 0.5f; }
+};
+
+struct KeyFrameTransCompressed : KeyFrameCompressed {
+ int16 trans[3]; // 1024
+
+ void GetTranslation(CVector *vec) {
+ float scale = 1.0f/1024.0f;
+ vec->x = trans[0]*scale;
+ vec->y = trans[1]*scale;
+ vec->z = trans[2]*scale;
+ }
+ void SetTranslation(const CVector &vec){
+ trans[0] = vec.x*1024.0f;
+ trans[1] = vec.y*1024.0f;
+ trans[2] = vec.z*1024.0f;
+ }
+};
+
// The sequence of key frames of one animated node
class CAnimBlendSequence
@@ -24,9 +65,7 @@ public:
int32 type;
char name[24];
int32 numFrames;
-#ifdef PED_SKIN
int16 boneTag;
-#endif
void *keyFrames;
void *keyFramesCompressed;
@@ -40,21 +79,17 @@ public:
&((KeyFrameTrans*)keyFrames)[n] :
&((KeyFrame*)keyFrames)[n];
}
- KeyFrame *GetKeyFrameCompressed(int n) {
+ KeyFrameCompressed *GetKeyFrameCompressed(int n) {
return type & KF_TRANS ?
- &((KeyFrameTrans*)keyFramesCompressed)[n] :
- &((KeyFrame*)keyFramesCompressed)[n];
+ &((KeyFrameTransCompressed*)keyFramesCompressed)[n] :
+ &((KeyFrameCompressed*)keyFramesCompressed)[n];
}
bool HasTranslation(void) { return !!(type & KF_TRANS); }
- // TODO? these are unused
-// void Uncompress(void);
-// void CompressKeyframes(void);
-// void RemoveUncompressedData(void);
+ 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 a85149e6..9fc54654 100644
--- a/src/animation/AnimManager.cpp
+++ b/src/animation/AnimManager.cpp
@@ -287,6 +287,7 @@ AnimAssocDesc aStripAnimDescs[] = {
{ ANIM_STRIP_F, ASSOC_REPEAT | ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
{ ANIM_STRIP_G, ASSOC_FADEOUTWHENDONE | ASSOC_PARTIAL },
};
+#ifdef PC_PLAYER_CONTROLS
AnimAssocDesc aStdAnimDescsSide[] = {
{ 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 },
@@ -294,7 +295,7 @@ AnimAssocDesc aStdAnimDescsSide[] = {
{ ANIM_IDLE_STANCE, ASSOC_REPEAT },
{ ANIM_WALK_START, ASSOC_HAS_TRANSLATION | ASSOC_HAS_X_TRANSLATION },
};
-
+#endif
char const* aStdAnimations[] = {
"walk_civi",
"run_civi",
@@ -834,6 +835,7 @@ char const* aSkateAnimations[] = {
"skate_sprint",
"skate_idle",
};
+#ifdef PC_PLAYER_CONTROLS
char const* aPlayerStrafeBackAnimations[] = {
"walk_back",
"run_back",
@@ -897,7 +899,7 @@ char const* aChainsawStrafeRightAnimations[] = {
"idle_csaw",
"walkst_csaw_right",
};
-
+#endif
#define awc(a) ARRAY_SIZE(a), a
const AnimAssocDefinition CAnimManager::ms_aAnimAssocDefinitions[NUM_ANIM_ASSOC_GROUPS] = {
@@ -953,6 +955,7 @@ const AnimAssocDefinition CAnimManager::ms_aAnimAssocDefinitions[NUM_ANIM_ASSOC_
{ "jogwoman", "ped", MI_COP, awc(aJoggerWomanAnimations), aStdAnimDescs },
{ "panicchunky", "ped", MI_COP, awc(aPanicChunkyAnimations), aStdAnimDescs },
{ "skate", "skate", MI_COP, awc(aSkateAnimations), aStdAnimDescs },
+#ifdef PC_PLAYER_CONTROLS
{ "playerback", "ped", MI_COP, awc(aPlayerStrafeBackAnimations), aStdAnimDescs },
{ "playerleft", "ped", MI_COP, awc(aPlayerStrafeLeftAnimations), aStdAnimDescsSide },
{ "playerright", "ped", MI_COP, awc(aPlayerStrafeRightAnimations), aStdAnimDescsSide },
@@ -962,6 +965,7 @@ const AnimAssocDefinition CAnimManager::ms_aAnimAssocDefinitions[NUM_ANIM_ASSOC_
{ "csawback", "ped", MI_COP, awc(aChainsawStrafeBackAnimations), aStdAnimDescs },
{ "csawleft", "ped", MI_COP, awc(aChainsawStrafeLeftAnimations), aStdAnimDescsSide },
{ "csawright", "ped", MI_COP, awc(aChainsawStrafeRightAnimations), aStdAnimDescsSide },
+#endif
};
#undef awc
@@ -992,7 +996,7 @@ CAnimManager::Shutdown(void)
void
CAnimManager::UncompressAnimation(CAnimBlendHierarchy *hier)
{
- if(hier->compressed2){
+ if(hier->keepCompressed){
if(hier->totalLength == 0.0f)
hier->CalcTotalTimeCompressed();
}else{
@@ -1255,13 +1259,10 @@ CAnimManager::CreateAnimAssocGroups(void)
group->firstAnimId = def->animDescs[0].animId;
group->CreateAssociations(def->blockName, clump, def->animNames, def->numAnims);
for(j = 0; j < group->numAssociations; j++)
-
// 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;
-#ifdef PED_SKIN
if(IsClumpSkinned(clump))
RpClumpForAllAtomics(clump, AtomicRemoveAnimFromSkinCB, nil);
-#endif
RpClumpDestroy(clump);
}
}
@@ -1278,7 +1279,7 @@ CAnimManager::LoadAnimFile(const char *filename)
//--MIAMI: done
void
-CAnimManager::LoadAnimFile(RwStream *stream, bool compress, char (*somename)[32])
+CAnimManager::LoadAnimFile(RwStream *stream, bool compress, char (*uncompressedAnims)[32])
{
#define ROUNDSIZE(x) if((x) & 3) (x) += 4 - ((x)&3)
struct IfpHeader {
@@ -1323,16 +1324,22 @@ CAnimManager::LoadAnimFile(RwStream *stream, bool compress, char (*somename)[32]
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))
+#ifdef ANIM_COMPRESSION
+ bool compressHier = compress;
+#else
+ bool compressHier = false;
+#endif
+ if (uncompressedAnims) {
+ for (int i = 0; uncompressedAnims[i][0]; i++) {
+ if (!CGeneral::faststricmp(uncompressedAnims[i], hier->name)){
debug("Loading %s uncompressed\n", hier->name);
+ compressHier = false;
+ }
}
}
- hier->compressed = false;
- hier->compressed2 = false;
+ hier->compressed = compressHier;
+ hier->keepCompressed = false;
// DG info has number of nodes/sequences
RwStreamRead(stream, (char*)&dgan, sizeof(IfpHeader));
@@ -1352,69 +1359,86 @@ CAnimManager::LoadAnimFile(RwStream *stream, bool compress, char (*somename)[32]
ROUNDSIZE(anim.size);
RwStreamRead(stream, buf, anim.size);
int numFrames = *(int*)(buf+28);
-#ifdef PED_SKIN
+ seq->SetName(buf);
if(anim.size == 44)
seq->SetBoneTag(*(int*)(buf+40));
-#endif
- seq->SetName(buf);
if(numFrames == 0)
continue;
+ bool hasScale = false;
+ bool hasTranslation = false;
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
- }
+ if(strncmp(info.ident, "KRTS", 4) == 0){
+ hasScale = true;
+ seq->SetNumFrames(numFrames, true, compressHier);
}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);
+ hasTranslation = true;
+ seq->SetNumFrames(numFrames, true, compressHier);
+ }else if(strncmp(info.ident, "KR00", 4) == 0){
+ seq->SetNumFrames(numFrames, false, compressHier);
+ }
+ if(strstr(seq->name, "L Toe"))
+ debug("anim %s has toe keyframes\n", hier->name); // BUG: seq->name
+
+ for(l = 0; l < numFrames; l++){
+ if(hasScale){
+ RwStreamRead(stream, buf, 0x2C);
+ CQuaternion rot(fbuf[0], fbuf[1], fbuf[2], fbuf[3]);
+ rot.Invert();
+ CVector trans(fbuf[4], fbuf[5], fbuf[6]);
- for(l = 0; l < numFrames; l++, kf++){
+ if(compressHier){
+ KeyFrameTransCompressed *kf = (KeyFrameTransCompressed*)seq->GetKeyFrameCompressed(l);
+ kf->SetRotation(rot);
+ kf->SetTranslation(trans);
+ // scaling ignored
+ kf->SetTime(fbuf[10]); // absolute time here
+ }else{
+ KeyFrameTrans *kf = (KeyFrameTrans*)seq->GetKeyFrame(l);
+ kf->rotation = rot;
+ kf->translation = trans;
+ // scaling ignored
+ kf->deltaTime = fbuf[10]; // absolute time here
+ }
+ }else if(hasTranslation){
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);
+ CQuaternion rot(fbuf[0], fbuf[1], fbuf[2], fbuf[3]);
+ rot.Invert();
+ CVector trans(fbuf[4], fbuf[5], fbuf[6]);
- 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
+ if(compressHier){
+ KeyFrameTransCompressed *kf = (KeyFrameTransCompressed*)seq->GetKeyFrameCompressed(l);
+ kf->SetRotation(rot);
+ kf->SetTranslation(trans);
+ kf->SetTime(fbuf[7]); // absolute time here
+ }else{
+ KeyFrameTrans *kf = (KeyFrameTrans*)seq->GetKeyFrame(l);
+ kf->rotation = rot;
+ kf->translation = trans;
+ kf->deltaTime = fbuf[7]; // absolute time here
+ }
+ }else{
+ RwStreamRead(stream, buf, 0x14);
+ CQuaternion rot(fbuf[0], fbuf[1], fbuf[2], fbuf[3]);
+ rot.Invert();
+
+ if(compressHier){
+ KeyFrameCompressed *kf = (KeyFrameCompressed*)seq->GetKeyFrameCompressed(l);
+ kf->SetRotation(rot);
+ kf->SetTime(fbuf[4]); // absolute time here
+ }else{
+ KeyFrame *kf = (KeyFrame*)seq->GetKeyFrame(l);
+ kf->rotation = rot;
+ kf->deltaTime = fbuf[4]; // absolute time here
+ }
}
}
}
- hier->RemoveQuaternionFlips();
- hier->CalcTotalTime();
+ if(!compressHier){
+ hier->RemoveQuaternionFlips();
+ hier->CalcTotalTime();
+ }
}
if(animIndex > ms_numAnimations)
ms_numAnimations = animIndex;
diff --git a/src/animation/AnimManager.h b/src/animation/AnimManager.h
index a55577b1..213326b6 100644
--- a/src/animation/AnimManager.h
+++ b/src/animation/AnimManager.h
@@ -57,6 +57,7 @@ enum AssocGroupId
ASSOCGRP_JOGWOMAN,
ASSOCGRP_PANICCHUNKY,
ASSOCGRP_SKATE,
+#ifdef PC_PLAYER_CONTROLS
ASSOCGRP_PLAYERBACK,
ASSOCGRP_PLAYERLEFT,
ASSOCGRP_PLAYERRIGHT,
@@ -66,6 +67,7 @@ enum AssocGroupId
ASSOCGRP_CHAINSAWBACK,
ASSOCGRP_CHAINSAWLEFT,
ASSOCGRP_CHAINSAWRIGHT,
+#endif
NUM_ANIM_ASSOC_GROUPS
};
@@ -136,7 +138,7 @@ 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(RwStream *stream, bool compress, char (*somename)[32] = nil);
+ static void LoadAnimFile(RwStream *stream, bool compress, char (*uncompressedAnims)[32] = nil);
static void CreateAnimAssocGroups(void);
static void RemoveLastAnimFile(void);
static CAnimBlendAssocGroup* GetAnimAssocGroups(void) { return ms_aAnimAssocGroups; }
diff --git a/src/animation/CutsceneMgr.cpp b/src/animation/CutsceneMgr.cpp
index 64951a87..b312236b 100644
--- a/src/animation/CutsceneMgr.cpp
+++ b/src/animation/CutsceneMgr.cpp
@@ -291,12 +291,15 @@ CCutsceneMgr::SetupCutsceneToStart(void)
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);
+ if (pAnimBlendAssoc->hierarchy->IsCompressed()){
+ KeyFrameTransCompressed *keyFrames = ((KeyFrameTransCompressed*)pAnimBlendAssoc->hierarchy->sequences[0].GetKeyFrameCompressed(0));
+ CVector trans;
+ keyFrames->GetTranslation(&trans);
+ ms_pCutsceneObjects[i]->SetPosition(ms_cutsceneOffset + trans);
+ }else{
+ KeyFrameTrans *keyFrames = ((KeyFrameTrans*)pAnimBlendAssoc->hierarchy->sequences[0].GetKeyFrame(0));
+ ms_pCutsceneObjects[i]->SetPosition(ms_cutsceneOffset + keyFrames->translation);
+ }
}
pAnimBlendAssoc->SetRun();
} else {
@@ -331,7 +334,7 @@ CCutsceneMgr::SetCutsceneAnim(const char *animName, CObject *pObject)
}
if (pNewAnim->hierarchy->IsCompressed())
- pNewAnim->hierarchy->compressed2 = true;
+ pNewAnim->hierarchy->keepCompressed = true;
CStreaming::ImGonnaUseStreamingMemory();
pNewAnim = ms_cutsceneAssociations.CopyAnimation(animName);
@@ -344,8 +347,8 @@ CCutsceneMgr::SetCutsceneAnim(const char *animName, CObject *pObject)
pAnimBlendClumpData = *RPANIMBLENDCLUMPDATA(pObject->m_rwObject);
pAnimBlendClumpData->link.Prepend(&pNewAnim->link);
- if (pNewAnim->hierarchy->compressed2)
- pAnimBlendClumpData->frames->flag |= AnimBlendFrameData::UNK_COMPRESSED;
+ if (pNewAnim->hierarchy->keepCompressed)
+ pAnimBlendClumpData->frames->flag |= AnimBlendFrameData::COMPRESSED;
}
void
diff --git a/src/animation/FrameUpdate.cpp b/src/animation/FrameUpdate.cpp
index faeea709..a085fd4b 100644
--- a/src/animation/FrameUpdate.cpp
+++ b/src/animation/FrameUpdate.cpp
@@ -19,6 +19,9 @@ void FrameUpdateCallBackSkinned(AnimBlendFrameData *frame, void *arg);
void FrameUpdateCallBackWithVelocityExtractionSkinned(AnimBlendFrameData *frame, void *arg);
void FrameUpdateCallBackWith3dVelocityExtractionSkinned(AnimBlendFrameData *frame, void *arg);
+void FrameUpdateCallBackNonSkinnedCompressed(AnimBlendFrameData *frame, void *arg);
+void FrameUpdateCallBackSkinnedCompressed(AnimBlendFrameData *frame, void *arg);
+
void
FrameUpdateCallBackNonSkinned(AnimBlendFrameData *frame, void *arg)
{
@@ -446,3 +449,222 @@ FrameUpdateCallBackOffscreen(AnimBlendFrameData *frame, void *arg)
if(frame->flag & AnimBlendFrameData::VELOCITY_EXTRACTION && gpAnimBlendClump->velocity)
FrameUpdateCallBackWithVelocityExtractionSkinned(frame, arg);
}
+
+
+void
+FrameUpdateCallBackNonSkinnedCompressed(AnimBlendFrameData *frame, void *arg)
+{
+ CVector vec, pos(0.0f, 0.0f, 0.0f);
+ CQuaternion q, rot(0.0f, 0.0f, 0.0f, 0.0f);
+ float totalBlendAmount = 0.0f;
+ CVector trans(0.0f, 0.0f, 0.0f);
+ CVector cur(0.0f, 0.0f, 0.0f);
+ CVector end(0.0f, 0.0f, 0.0f);
+ bool looped = false;
+ RwMatrix *mat = RwFrameGetMatrix(frame->frame);
+ CAnimBlendNode **node;
+ AnimBlendFrameUpdateData *updateData = (AnimBlendFrameUpdateData*)arg;
+
+ if(frame->flag & AnimBlendFrameData::VELOCITY_EXTRACTION &&
+ gpAnimBlendClump->velocity){
+ if(updateData->foobar)
+ for(node = updateData->nodes; *node; node++)
+ if((*node)->sequence && (*node)->association->IsPartial())
+ totalBlendAmount += (*node)->association->blendAmount;
+
+ for(node = updateData->nodes; *node; node++)
+ if((*node)->sequence && (*node)->sequence->HasTranslation()){
+ if((*node)->association->HasTranslation()){
+ (*node)->GetCurrentTranslationCompressed(vec, 1.0f-totalBlendAmount);
+ cur += vec;
+ }
+ }
+
+ for(node = updateData->nodes; *node; node++){
+ if((*node)->sequence){
+ bool nodelooped = (*node)->UpdateCompressed(vec, q, 1.0f-totalBlendAmount);
+#ifdef FIX_BUGS
+ if(DotProduct(rot, q) < 0.0f)
+ rot -= q;
+ else
+#endif
+ rot += q;
+ if((*node)->sequence->HasTranslation()){
+ pos += vec;
+ if((*node)->association->HasTranslation()){
+ trans += vec;
+ looped |= nodelooped;
+ if(nodelooped){
+ (*node)->GetEndTranslationCompressed(vec, 1.0f-totalBlendAmount);
+ end += vec;
+ }
+ }
+ }
+ }
+ ++*node;
+ }
+
+ if((frame->flag & AnimBlendFrameData::IGNORE_ROTATION) == 0){
+ RwMatrixSetIdentity(mat);
+ rot.Normalise();
+ rot.Get(mat);
+ }
+
+ if((frame->flag & AnimBlendFrameData::IGNORE_TRANSLATION) == 0){
+ *gpAnimBlendClump->velocity = trans - cur;
+ if(looped)
+ *gpAnimBlendClump->velocity += end;
+ mat->pos.x = (pos - trans).x + frame->resetPos.x;
+ mat->pos.y = (pos - trans).y + frame->resetPos.y;
+ mat->pos.z = (pos - trans).z + frame->resetPos.z;
+ }
+ RwMatrixUpdate(mat);
+ }else{
+ if(updateData->foobar)
+ for(node = updateData->nodes; *node; node++)
+ if((*node)->sequence && (*node)->association->IsPartial())
+ totalBlendAmount += (*node)->association->blendAmount;
+
+ for(node = updateData->nodes; *node; node++){
+ if((*node)->sequence){
+ (*node)->UpdateCompressed(vec, q, 1.0f-totalBlendAmount);
+ if((*node)->sequence->HasTranslation())
+ pos += vec;
+#ifdef FIX_BUGS
+ if(DotProduct(rot, q) < 0.0f)
+ rot -= q;
+ else
+#endif
+ rot += q;
+ }
+ ++*node;
+ }
+
+ if((frame->flag & AnimBlendFrameData::IGNORE_ROTATION) == 0){
+ RwMatrixSetIdentity(mat);
+ rot.Normalise();
+ rot.Get(mat);
+ }
+
+ if((frame->flag & AnimBlendFrameData::IGNORE_TRANSLATION) == 0){
+ mat->pos.x = pos.x;
+ mat->pos.y = pos.y;
+ mat->pos.z = pos.z;
+ mat->pos.x += frame->resetPos.x;
+ mat->pos.y += frame->resetPos.y;
+ mat->pos.z += frame->resetPos.z;
+ }
+ RwMatrixUpdate(mat);
+ }
+}
+
+void
+FrameUpdateCallBackSkinnedCompressed(AnimBlendFrameData *frame, void *arg)
+{
+ CVector vec, pos(0.0f, 0.0f, 0.0f);
+ CQuaternion q, rot(0.0f, 0.0f, 0.0f, 0.0f);
+ float totalBlendAmount = 0.0f;
+ CVector trans(0.0f, 0.0f, 0.0f);
+ CVector cur(0.0f, 0.0f, 0.0f);
+ CVector end(0.0f, 0.0f, 0.0f);
+ bool looped = false;
+ RpHAnimStdInterpFrame *xform = frame->hanimFrame;
+ CAnimBlendNode **node;
+ AnimBlendFrameUpdateData *updateData = (AnimBlendFrameUpdateData*)arg;
+
+ if(frame->flag & AnimBlendFrameData::VELOCITY_EXTRACTION &&
+ gpAnimBlendClump->velocity){
+ if(updateData->foobar)
+ for(node = updateData->nodes; *node; node++)
+ if((*node)->sequence && (*node)->association->IsPartial())
+ totalBlendAmount += (*node)->association->blendAmount;
+
+ for(node = updateData->nodes; *node; node++)
+ if((*node)->sequence && (*node)->sequence->HasTranslation()){
+ if((*node)->association->HasTranslation()){
+ (*node)->GetCurrentTranslationCompressed(vec, 1.0f-totalBlendAmount);
+ cur += vec;
+ }
+ }
+
+ for(node = updateData->nodes; *node; node++){
+ if((*node)->sequence){
+ bool nodelooped = (*node)->UpdateCompressed(vec, q, 1.0f-totalBlendAmount);
+#ifdef FIX_BUGS
+ if(DotProduct(rot, q) < 0.0f)
+ rot -= q;
+ else
+#endif
+ rot += q;
+ if((*node)->sequence->HasTranslation()){
+ pos += vec;
+ if((*node)->association->HasTranslation()){
+ trans += vec;
+ looped |= nodelooped;
+ if(nodelooped){
+ (*node)->GetEndTranslationCompressed(vec, 1.0f-totalBlendAmount);
+ end += vec;
+ }
+ }
+ }
+ }
+ ++*node;
+ }
+
+ if((frame->flag & AnimBlendFrameData::IGNORE_ROTATION) == 0){
+ rot.Normalise();
+ xform->q.imag.x = rot.x;
+ xform->q.imag.y = rot.y;
+ xform->q.imag.z = rot.z;
+ xform->q.real = rot.w;
+ }
+
+ if((frame->flag & AnimBlendFrameData::IGNORE_TRANSLATION) == 0){
+ *gpAnimBlendClump->velocity = trans - cur;
+ if(looped)
+ *gpAnimBlendClump->velocity += end;
+ xform->t.x = (pos - trans).x + frame->resetPos.x;
+ xform->t.y = (pos - trans).y + frame->resetPos.y;
+ xform->t.z = (pos - trans).z + frame->resetPos.z;
+ }
+ }else{
+ float transBlendAmount = 0.0f;
+
+ if(updateData->foobar)
+ for(node = updateData->nodes; *node; node++)
+ if((*node)->sequence && (*node)->association->IsPartial())
+ totalBlendAmount += (*node)->association->blendAmount;
+
+ for(node = updateData->nodes; *node; node++){
+ if((*node)->sequence){
+ (*node)->UpdateCompressed(vec, q, 1.0f-totalBlendAmount);
+ if((*node)->sequence->HasTranslation()){
+ pos += vec;
+ transBlendAmount += (*node)->association->blendAmount;
+ }
+ if(DotProduct(rot, q) < 0.0f)
+ rot -= q;
+ else
+ rot += q;
+ }
+ ++*node;
+ }
+
+ if((frame->flag & AnimBlendFrameData::IGNORE_ROTATION) == 0){
+ rot.Normalise();
+ xform->q.imag.x = rot.x;
+ xform->q.imag.y = rot.y;
+ xform->q.imag.z = rot.z;
+ xform->q.real = rot.w;
+ }
+
+ if((frame->flag & AnimBlendFrameData::IGNORE_TRANSLATION) == 0){
+ xform->t.x = transBlendAmount*pos.x;
+ xform->t.y = transBlendAmount*pos.y;
+ xform->t.z = transBlendAmount*pos.z;
+ xform->t.x += (1.0f-transBlendAmount)*frame->resetPos.x;
+ xform->t.y += (1.0f-transBlendAmount)*frame->resetPos.y;
+ xform->t.z += (1.0f-transBlendAmount)*frame->resetPos.z;
+ }
+ }
+}
diff --git a/src/animation/RpAnimBlend.cpp b/src/animation/RpAnimBlend.cpp
index e93615b7..c4103dbf 100644
--- a/src/animation/RpAnimBlend.cpp
+++ b/src/animation/RpAnimBlend.cpp
@@ -8,6 +8,7 @@
#include "AnimBlendClumpData.h"
#include "AnimBlendHierarchy.h"
#include "AnimBlendAssociation.h"
+#include "AnimManager.h"
#include "RpAnimBlend.h"
#include "PedModelInfo.h"
@@ -443,6 +444,9 @@ RpAnimBlendNodeUpdateKeyframes(AnimBlendFrameData *frames, AnimBlendFrameUpdateD
}
}
+// TODO:
+// CAnimBlendClumpData::LoadFramesIntoSPR
+// CAnimBlendClumpData::ForAllFramesInSPR
void
RpAnimBlendClumpUpdateAnimations(RpClump *clump, float timeDelta, bool doRender)
{
@@ -466,7 +470,7 @@ RpAnimBlendClumpUpdateAnimations(RpClump *clump, float timeDelta, bool doRender)
assoc = CAnimBlendAssociation::FromLink(link);
if(assoc->UpdateBlend(timeDelta)){
if(assoc->hierarchy->sequences){
- //CAnimManager::UncompressAnimation(v6->hierarchy)
+ CAnimManager::UncompressAnimation(assoc->hierarchy);
if(i < 11)
updateData.nodes[i++] = assoc->GetNode(0);
if(assoc->flags & ASSOC_MOVEMENT){
@@ -486,6 +490,14 @@ RpAnimBlendClumpUpdateAnimations(RpClump *clump, float timeDelta, bool doRender)
updateData.nodes[i] = nil;
+#ifdef ANIM_COMPRESSION
+ if(clumpData->frames[0].flag & AnimBlendFrameData::COMPRESSED){
+ if(IsClumpSkinned(clump))
+ clumpData->ForAllFrames(FrameUpdateCallBackSkinnedCompressed, &updateData);
+ else
+ clumpData->ForAllFrames(FrameUpdateCallBackNonSkinnedCompressed, &updateData);
+ }else
+#endif
if(doRender){
if(clumpData->frames[0].flag & AnimBlendFrameData::UPDATE_KEYFRAMES)
RpAnimBlendNodeUpdateKeyframes(clumpData->frames, &updateData, clumpData->numFrames);
diff --git a/src/animation/RpAnimBlend.h b/src/animation/RpAnimBlend.h
index d0f7a114..6e9e0f0f 100644
--- a/src/animation/RpAnimBlend.h
+++ b/src/animation/RpAnimBlend.h
@@ -43,3 +43,6 @@ extern CAnimBlendClumpData *gpAnimBlendClump;
void FrameUpdateCallBackNonSkinned(AnimBlendFrameData *frame, void *arg);
void FrameUpdateCallBackSkinned(AnimBlendFrameData *frame, void *arg);
void FrameUpdateCallBackOffscreen(AnimBlendFrameData *frame, void *arg);
+
+void FrameUpdateCallBackNonSkinnedCompressed(AnimBlendFrameData *frame, void *arg);
+void FrameUpdateCallBackSkinnedCompressed(AnimBlendFrameData *frame, void *arg);
diff --git a/src/audio/AudioCollision.cpp b/src/audio/AudioCollision.cpp
index 6ce7bbac..c5aa170c 100644
--- a/src/audio/AudioCollision.cpp
+++ b/src/audio/AudioCollision.cpp
@@ -71,31 +71,33 @@ cAudioManager::GetCollisionOneShotRatio(int32 a, float b) const
case SURFACE_TARMAC:
case SURFACE_PAVEMENT:
case SURFACE_STEEP_CLIFF:
- case SURFACE_TRANSPARENT_STONE: result = GetCollisionRatio(b, 10.f, 60.f, 50.f); break;
+ case SURFACE_TRANSPARENT_STONE:
+ case SURFACE_CONCRETE_BEACH: result = GetCollisionRatio(b, 10.f, 60.f, 50.f); break;
case SURFACE_GRASS:
+ case SURFACE_GRAVEL:
+ case SURFACE_MUD_DRY:
case SURFACE_CARDBOARDBOX: result = GetCollisionRatio(b, 0.f, 2.f, 2.f); break;
- case SURFACE_GRAVEL: result = GetCollisionRatio(b, 0.f, 2.f, 2.f); break;
- case SURFACE_MUD_DRY: result = GetCollisionRatio(b, 0.f, 2.f, 2.f); break;
case SURFACE_CAR: result = GetCollisionRatio(b, 6.f, 50.f, 44.f); break;
- case SURFACE_GLASS: result = GetCollisionRatio(b, 0.1f, 10.f, 9.9f); break;
+ case SURFACE_GLASS:
+ case SURFACE_METAL_CHAIN_FENCE: result = GetCollisionRatio(b, 0.1f, 10.f, 9.9f); break;
case SURFACE_TRANSPARENT_CLOTH:
case SURFACE_THICK_METAL_PLATE: result = GetCollisionRatio(b, 30.f, 130.f, 100.f); break;
case SURFACE_GARAGE_DOOR: result = GetCollisionRatio(b, 20.f, 100.f, 80.f); break;
case SURFACE_CAR_PANEL: result = GetCollisionRatio(b, 0.f, 4.f, 4.f); break;
case SURFACE_SCAFFOLD_POLE:
- case SURFACE_METAL_GATE: result = GetCollisionRatio(b, 1.f, 10.f, 9.f); break;
+ case SURFACE_METAL_GATE:
case SURFACE_LAMP_POST: result = GetCollisionRatio(b, 1.f, 10.f, 9.f); break;
case SURFACE_FIRE_HYDRANT: result = GetCollisionRatio(b, 1.f, 15.f, 14.f); break;
case SURFACE_GIRDER: result = GetCollisionRatio(b, 8.f, 50.f, 42.f); break;
- case SURFACE_METAL_CHAIN_FENCE: result = GetCollisionRatio(b, 0.1f, 10.f, 9.9f); break;
case SURFACE_PED: result = GetCollisionRatio(b, 0.f, 20.f, 20.f); break;
- case SURFACE_SAND: result = GetCollisionRatio(b, 0.f, 10.f, 10.f); break;
- case SURFACE_WATER: result = GetCollisionRatio(b, 0.f, 10.f, 10.f); break;
+ case SURFACE_SAND:
+ case SURFACE_WATER:
+ case SURFACE_RUBBER:
+ case SURFACE_WHEELBASE:
+ case SURFACE_SAND_BEACH: result = GetCollisionRatio(b, 0.f, 10.f, 10.f); break;
case SURFACE_WOOD_CRATES: result = GetCollisionRatio(b, 1.f, 4.f, 3.f); break;
case SURFACE_WOOD_BENCH: result = GetCollisionRatio(b, 0.1f, 5.f, 4.9f); break;
case SURFACE_WOOD_SOLID: result = GetCollisionRatio(b, 0.1f, 40.f, 39.9f); break;
- case SURFACE_RUBBER:
- case SURFACE_WHEELBASE: result = GetCollisionRatio(b, 0.f, 10.f, 10.f); break;
case SURFACE_PLASTIC: result = GetCollisionRatio(b, 0.1f, 4.f, 3.9f); break;
case SURFACE_HEDGE: result = GetCollisionRatio(b, 0.f, 0.5f, 0.5f); break;
case SURFACE_CONTAINER: result = GetCollisionRatio(b, 4.f, 40.f, 36.f); break;
@@ -135,8 +137,8 @@ cAudioManager::SetLoopingCollisionRequestedSfxFreqAndGetVol(const cAudioCollisio
m_sQueueSample.m_nSampleIndex = SFX_BOAT_WATER_LOOP;
m_sQueueSample.m_nFrequency = 6050.f * ratio + 16000;
vol = 30.f * ratio;
- } else if(surface1 == SURFACE_GRAVEL || surface2 == SURFACE_GRAVEL || surface1 == SURFACE_MUD_DRY ||
- surface2 == SURFACE_MUD_DRY || surface1 == SURFACE_SAND || surface2 == SURFACE_SAND) {
+ } else if(surface1 == SURFACE_GRAVEL || surface2 == SURFACE_GRAVEL || surface1 == SURFACE_MUD_DRY || surface2 == SURFACE_MUD_DRY ||
+ surface1 == SURFACE_SAND || surface2 == SURFACE_SAND || surface1 == SURFACE_SAND_BEACH || surface2 == SURFACE_SAND_BEACH) {
ratio = GetCollisionRatio(audioCollision.m_fIntensity2, 0.0001f, 0.09f, 0.0899f);
m_sQueueSample.m_nSampleIndex = SFX_GRAVEL_SKID;
m_sQueueSample.m_nFrequency = 6000.f * ratio + 10000;
@@ -156,12 +158,12 @@ cAudioManager::SetLoopingCollisionRequestedSfxFreqAndGetVol(const cAudioCollisio
void
cAudioManager::SetUpLoopingCollisionSound(const cAudioCollision &col, uint8 counter)
{
+ bool distCalculated = false;
if(col.m_fIntensity2 > 0.0016f) {
uint8 emittingVol = SetLoopingCollisionRequestedSfxFreqAndGetVol(col);
if(emittingVol) {
- m_sQueueSample.m_fDistance = Sqrt(col.m_fDistance);
- m_sQueueSample.m_nVolume =
- ComputeVolume(emittingVol, CollisionSoundIntensity, m_sQueueSample.m_fDistance);
+ CalculateDistance(distCalculated, m_sQueueSample.m_fDistance);
+ m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, CollisionSoundIntensity, m_sQueueSample.m_fDistance);
if(m_sQueueSample.m_nVolume) {
m_sQueueSample.m_nCounter = counter;
m_sQueueSample.m_vecPos = col.m_vecPosition;
@@ -266,7 +268,7 @@ cAudioManager::SetUpOneShotCollisionSound(const cAudioCollision &col)
m_sQueueSample.m_nSampleIndex += m_anRandomTable[3] % 4;
break;
case SFX_COL_PED_1:
- m_sQueueSample.m_nSampleIndex += m_anRandomTable[4] % 5;
+ m_sQueueSample.m_nSampleIndex += m_anRandomTable[4] % 2;
break;
case SFX_COL_WOOD_CRATES_1:
m_sQueueSample.m_nSampleIndex += m_anRandomTable[4] % 4;
diff --git a/src/audio/AudioLogic.cpp b/src/audio/AudioLogic.cpp
index a7d33938..8f03d66a 100644
--- a/src/audio/AudioLogic.cpp
+++ b/src/audio/AudioLogic.cpp
@@ -47,8 +47,8 @@ const int channels = ARRAY_SIZE(cAudioManager::m_asActiveSamples);
const int policeChannel = channels + 1;
const int allChannels = channels + 2;
-enum PLAY_STATUS : uint8 { PLAY_STATUS_STOPPED = 0, PLAY_STATUS_PLAYING, PLAY_STATUS_FINISHED };
-enum LOADING_STATUS : uint8 { LOADING_STATUS_NOT_LOADED = 0, LOADING_STATUS_LOADED, LOADING_STATUS_FAILED };
+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 };
void
cAudioManager::PreInitialiseGameSpecificSetup() const
@@ -123,39 +123,39 @@ cAudioManager::PostInitialiseGameSpecificSetup()
{
m_nFireAudioEntity = CreateEntity(AUDIOTYPE_FIRE, &gFireManager);
if (m_nFireAudioEntity >= 0)
- SetEntityStatus(m_nFireAudioEntity, 1);
+ SetEntityStatus(m_nFireAudioEntity, true);
m_nCollisionEntity = CreateEntity(AUDIOTYPE_COLLISION, (void *)1);
if (m_nCollisionEntity >= 0)
- SetEntityStatus(m_nCollisionEntity, 1);
+ SetEntityStatus(m_nCollisionEntity, true);
m_nFrontEndEntity = CreateEntity(AUDIOTYPE_FRONTEND, (void *)1);
if (m_nFrontEndEntity >= 0)
- SetEntityStatus(m_nFrontEndEntity, 1);
+ SetEntityStatus(m_nFrontEndEntity, true);
m_nProjectileEntity = CreateEntity(AUDIOTYPE_PROJECTILE, (void *)1);
if (m_nProjectileEntity >= 0)
- SetEntityStatus(m_nProjectileEntity, 1);
+ SetEntityStatus(m_nProjectileEntity, true);
m_nWaterCannonEntity = CreateEntity(AUDIOTYPE_WATERCANNON, (void *)1);
if (m_nWaterCannonEntity >= 0)
- SetEntityStatus(m_nWaterCannonEntity, 1);
+ SetEntityStatus(m_nWaterCannonEntity, true);
m_nPoliceChannelEntity = CreateEntity(AUDIOTYPE_POLICERADIO, (void *)1);
if (m_nPoliceChannelEntity >= 0)
- SetEntityStatus(m_nPoliceChannelEntity, 1);
+ SetEntityStatus(m_nPoliceChannelEntity, true);
#ifdef GTA_BRIDGE
m_nBridgeEntity = CreateEntity(AUDIOTYPE_BRIDGE, (void*)1);
if (m_nBridgeEntity >= 0)
- SetEntityStatus(m_nBridgeEntity, 1);
+ SetEntityStatus(m_nBridgeEntity, true);
#endif // GTA_BRIDGE
m_nEscalatorEntity = CreateEntity(AUDIOTYPE_ESCALATOR, (void*)1);
if (m_nEscalatorEntity >= 0)
- SetEntityStatus(m_nEscalatorEntity, 1);
+ SetEntityStatus(m_nEscalatorEntity, true);
m_nExtraSoundsEntity = CreateEntity(AUDIOTYPE_EXTRA_SOUNDS, (void*)1);
if (m_nExtraSoundsEntity >= 0)
- SetEntityStatus(m_nExtraSoundsEntity, 1);
+ SetEntityStatus(m_nExtraSoundsEntity, true);
m_sMissionAudio.m_nSampleIndex[0] = NO_SAMPLE;
@@ -261,7 +261,7 @@ cAudioManager::ProcessReverb() const
if (SampleManager.UpdateReverb() && m_bDynamicAcousticModelingStatus) {
for (uint32 i = 0; i < numChannels; i++) {
if (m_asActiveSamples[i].m_bReverbFlag)
- SampleManager.SetChannelReverbFlag(i, 1);
+ SampleManager.SetChannelReverbFlag(i, true);
}
}
}
@@ -277,10 +277,7 @@ void
cAudioManager::CalculateDistance(bool &distCalculated, float dist)
{
if (!distCalculated) {
- if (dist > 0.0f)
- m_sQueueSample.m_fDistance = Sqrt(dist);
- else
- m_sQueueSample.m_fDistance = 0.0f;
+ m_sQueueSample.m_fDistance = Sqrt(dist);
distCalculated = true;
}
}
@@ -317,7 +314,6 @@ cAudioManager::ProcessPlayerMood()
return;
}
- //lastMissionPassedTime = CTheScripts::GetLastMissionPassedTime();
if (lastMissionPassedTime != -1) {
if (curTime < lastMissionPassedTime) {
lastMissionPassedTime = curTime;
@@ -350,7 +346,7 @@ cAudioManager::ProcessSpecial()
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)
+ if(!playerPed->bInVehicle && CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle == nil)
SampleManager.StopChannel(m_nActiveSamples);
}
}
@@ -361,7 +357,7 @@ cAudioManager::ProcessSpecial()
void
cAudioManager::ProcessEntity(int32 id)
{
- if (m_asAudioEntities[id].m_nStatus != STATUS_PLAYER) {
+ if (m_asAudioEntities[id].m_bStatus) {
m_sQueueSample.m_nEntityIndex = id;
switch (m_asAudioEntities[id].m_nType) {
case AUDIOTYPE_PHYSICAL:
@@ -1403,7 +1399,7 @@ cAudioManager::ProcessVehicleEngine(cVehicleParams& params)
} else if (params.m_fVelocityChange == 0.0f) {
traction = 0.9f;
}
- if (transmission->fMaxVelocity <= 0.0) {
+ if (transmission->fMaxVelocity <= 0.0f) {
relativeChange = 0.0f;
modificator = 0.0f;
} else {
@@ -1421,7 +1417,7 @@ cAudioManager::ProcessVehicleEngine(cVehicleParams& params)
}
modificator = relativeChange;
} else {
- modificator = Min(1.0, Abs(params.m_fVelocityChange / transmission->fMaxVelocity > 1.0f));
+ modificator = Min(1.0f, Abs(params.m_fVelocityChange / transmission->fMaxVelocity > 1.0f));
}
}
} else {
@@ -1506,14 +1502,10 @@ cAudioManager::UpdateGasPedalAudio(CVehicle* veh, int vehType)
float gasPedal = Abs(veh->m_fGasPedal);
float* gasPealAudioPtr;
- switch (vehType) {
- case VEHICLE_TYPE_CAR:
- gasPealAudioPtr = &((CAutomobile*)veh)->m_fGasPedalAudio;
- case VEHICLE_TYPE_BIKE:
- gasPealAudioPtr = &((CBike*)veh)->m_fGasPedalAudio;
- default:
- return;
- break;
+ switch(vehType) {
+ case VEHICLE_TYPE_CAR: gasPealAudioPtr = &((CAutomobile *)veh)->m_fGasPedalAudio; break;
+ case VEHICLE_TYPE_BIKE: gasPealAudioPtr = &((CBike *)veh)->m_fGasPedalAudio; break;
+ default: return;
}
if (*gasPealAudioPtr < gasPedal)
*gasPealAudioPtr = Min(*gasPealAudioPtr + 0.09f, gasPedal);
@@ -1568,29 +1560,12 @@ cAudioManager::AddPlayerCarSample(uint8 emittingVolume, int32 freq, uint32 sampl
}
void
-cAudioManager::ProcessCesna(cVehicleParams& params)
+cAudioManager::ProcessCesna(cVehicleParams &params)
{
- static uint8 nAccel = 0;
-
- //((CAutomobile *)params.m_pVehicle)->Damage.GetEngineStatus();
-
- if (FindPlayerVehicle() == params.m_pVehicle) {
- if (params.m_nIndex == DODO) {
- if (Pads[0].GetAccelerate() <= 0) {
- if (nAccel != 0)
- --nAccel;
- } else if (nAccel < 60) {
- ++nAccel;
- }
- AddPlayerCarSample(85 * (60 - nAccel) / 60 + 20, 8500 * nAccel / 60 + 17000, SFX_CESNA_IDLE, SFX_BANK_0, 52, true);
- AddPlayerCarSample(85 * nAccel / 60 + 20, 8500 * nAccel / 60 + 17000, SFX_CESNA_REV, SFX_BANK_0, 2, true);
- }
- } else if (params.m_nIndex == DODO) {
- AddPlayerCarSample(105, 17000, SFX_CESNA_IDLE, SFX_BANK_0, 52, true);
- } else if (params.m_fDistance < SQR(200)) {
+ if(params.m_fDistance < SQR(200)) {
CalculateDistance(params.m_bDistanceCalculated, params.m_fDistance);
m_sQueueSample.m_nVolume = ComputeVolume(80, 200.f, m_sQueueSample.m_fDistance);
- if (m_sQueueSample.m_nVolume != 0) {
+ if(m_sQueueSample.m_nVolume != 0) {
m_sQueueSample.m_nCounter = 52;
m_sQueueSample.m_nSampleIndex = SFX_CESNA_IDLE;
m_sQueueSample.m_nBankIndex = SFX_BANK_0;
@@ -1602,28 +1577,28 @@ cAudioManager::ProcessCesna(cVehicleParams& params)
m_sQueueSample.m_nEmittingVolume = 80;
m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_fSpeedMultiplier = 8.0f;
+ m_sQueueSample.m_fSpeedMultiplier = 4.0f;
m_sQueueSample.m_fSoundIntensity = 200.0f;
m_sQueueSample.m_bReleasingSoundFlag = false;
m_sQueueSample.m_bReverbFlag = true;
m_sQueueSample.m_bRequireReflection = false;
AddSampleToRequestedQueue();
}
- if (params.m_fDistance < SQR(90)) {
+ if(params.m_fDistance < SQR(90)) {
m_sQueueSample.m_nVolume = ComputeVolume(80, 90.f, m_sQueueSample.m_fDistance);
- if (m_sQueueSample.m_nVolume != 0) {
+ if(m_sQueueSample.m_nVolume != 0) {
m_sQueueSample.m_nCounter = 2;
m_sQueueSample.m_nSampleIndex = SFX_CESNA_REV;
m_sQueueSample.m_nBankIndex = SFX_BANK_0;
m_sQueueSample.m_bIs2D = false;
- m_sQueueSample.m_nReleasingVolumeModificator = 0;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
m_sQueueSample.m_nFrequency = 25000;
m_sQueueSample.m_nLoopCount = 0;
m_sQueueSample.m_nReleasingVolumeDivider = 4;
m_sQueueSample.m_nEmittingVolume = 80;
m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_fSpeedMultiplier = 8.0f;
+ m_sQueueSample.m_fSpeedMultiplier = 4.0f;
m_sQueueSample.m_fSoundIntensity = 90.0f;
m_sQueueSample.m_bReleasingSoundFlag = false;
m_sQueueSample.m_bReverbFlag = true;
@@ -2002,27 +1977,11 @@ cAudioManager::ProcessPlayersVehicleEngine(cVehicleParams& params, CVehicle* veh
}
} 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;
- }
+ goto PlayCruising;
}
}
} else {
+PlayCruising:
bAccelSampleStopped = true;
SampleManager.StopChannel(m_nActiveSamples);
if (isMoped || accelerateState >= 150 && wheelsOnGround && brakeState <= 0 && !params.m_pVehicle->bIsHandbrakeOn
@@ -2036,7 +1995,7 @@ cAudioManager::ProcessPlayersVehicleEngine(cVehicleParams& params, CVehicle* veh
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);
+ AddPlayerCarSample(120, freq, soundOffset + SFX_CAR_AFTER_ACCEL_1, engineSoundType, 64, true);
} else {
nCruising = 0;
}
@@ -2232,7 +2191,6 @@ cAudioManager::ProcessVehicleHorn(cVehicleParams& params)
if (veh->m_modelIndex == MI_MRWHOOP)
return true;
- veh->m_nAlarmState;
if (veh->IsAlarmOn())
return true;
@@ -2614,12 +2572,8 @@ cAudioManager::ProcessVehicleOneShots(cVehicleParams& params)
bool noReflections;
bool isHeli;
float maxDist;
- cPedParams pedParams;
static uint8 GunIndex = 53;
- 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 = false;
isHeli = false;
@@ -3010,21 +2964,58 @@ cAudioManager::ProcessVehicleOneShots(cVehicleParams& params)
isHeli = true;
break;
default:
+ {
maxDist = SQR(SOUND_INTENSITY);
+#ifdef FIX_BUGS
+ int32 sampleIndex;
+ int32 frequency;
+ CPed *pPed = params.m_pVehicle->pDriver;
+ if(!pPed->HasWeaponSlot(WEAPONSLOT_SUBMACHINEGUN)) {
+ sampleIndex = SFX_UZI_LEFT;
+ frequency = SampleManager.GetSampleBaseFrequency(sampleIndex);
+ frequency += RandomDisplacement(frequency / 32);
+ } else
+ switch(pPed->GetWeapon(WEAPONSLOT_SUBMACHINEGUN).m_eWeaponType) {
+ case WEAPONTYPE_TEC9:
+ sampleIndex = SFX_TEC_LEFT;
+ frequency = RandomDisplacement(500) + 17000;
+ break;
+ case WEAPONTYPE_SILENCED_INGRAM:
+ sampleIndex = SFX_TEC_LEFT;
+ frequency = RandomDisplacement(1000) + 34000;
+ break;
+ case WEAPONTYPE_MP5:
+ sampleIndex = SFX_MP5_LEFT;
+ frequency = SampleManager.GetSampleBaseFrequency(sampleIndex);
+ frequency += RandomDisplacement(frequency / 32);
+ break;
+ default:
+ sampleIndex = SFX_UZI_LEFT;
+ frequency = SampleManager.GetSampleBaseFrequency(sampleIndex);
+ frequency += RandomDisplacement(frequency / 32);
+ break;
+ }
+ m_sQueueSample.m_nSampleIndex = sampleIndex;
+#else
m_sQueueSample.m_nSampleIndex = SFX_UZI_LEFT;
+#endif
m_sQueueSample.m_nBankIndex = SFX_BANK_0;
m_sQueueSample.m_nCounter = GunIndex++;
emittingVol = m_anRandomTable[2] % 15 + 65;
- if (GunIndex > 58)
- GunIndex = 53;
+ if(GunIndex > 58) GunIndex = 53;
+#ifdef FIX_BUGS
+ m_sQueueSample.m_nFrequency = frequency;
+#else
m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_UZI_LEFT);
m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 16);
+#endif
m_sQueueSample.m_nReleasingVolumeModificator = 3;
m_sQueueSample.m_fSpeedMultiplier = 0.0f;
m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY;
m_sQueueSample.m_bRequireReflection = true;
break;
}
+ }
break;
}
case SOUND_WEAPON_HIT_VEHICLE: {
@@ -3059,9 +3050,10 @@ cAudioManager::ProcessVehicleOneShots(cVehicleParams& params)
break;
}
case SOUND_PED_HELI_PLAYER_FOUND: {
+ cPedParams pedParams;
pedParams.m_bDistanceCalculated = params.m_bDistanceCalculated;
pedParams.m_fDistance = params.m_fDistance;
- SetupPedComments(&pedParams, SOUND_PED_HELI_PLAYER_FOUND);
+ SetupPedComments(pedParams, SOUND_PED_HELI_PLAYER_FOUND);
continue;
}
/* case SOUND_PED_BODYCAST_HIT:
@@ -3073,9 +3065,11 @@ cAudioManager::ProcessVehicleOneShots(cVehicleParams& params)
SetupPedComments(&pedParams, SOUND_PED_BODYCAST_HIT);
continue; */
case SOUND_PED_VCPA_PLAYER_FOUND: {
+ cPedParams pedParams;
pedParams.m_bDistanceCalculated = params.m_bDistanceCalculated;
pedParams.m_fDistance = params.m_fDistance;
- SetupPedComments(&pedParams, SOUND_PED_VCPA_PLAYER_FOUND);
+ SetupPedComments(pedParams, SOUND_PED_VCPA_PLAYER_FOUND);
+ continue;
}
case SOUND_WATER_FALL: {
const float SOUND_INTENSITY = 40.0f;
@@ -3161,7 +3155,7 @@ cAudioManager::ProcessVehicleOneShots(cVehicleParams& params)
m_sQueueSample.m_nCounter = GunIndex++;
if (GunIndex > 58)
GunIndex = 53;
- m_sQueueSample.m_bRequireReflection = 0;
+ m_sQueueSample.m_bRequireReflection = false;
AddSampleToRequestedQueue();
continue;
#endif
@@ -3193,7 +3187,7 @@ AddSample:
#ifdef GTA_TRAIN
bool
-cAudioManager::ProcessTrainNoise(cVehicleParams *params)
+cAudioManager::ProcessTrainNoise(cVehicleParams& params)
{
const float SOUND_INTENSITY = 300.0f;
@@ -3201,12 +3195,12 @@ cAudioManager::ProcessTrainNoise(cVehicleParams *params)
uint8 emittingVol;
float speedMultipler;
- if (params->m_fDistance >= SQR(SOUND_INTENSITY))
+ if (params.m_fDistance >= SQR(SOUND_INTENSITY))
return false;
- if (params->m_fVelocityChange > 0.0f) {
- CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance);
- train = (CTrain *)params->m_pVehicle;
+ if (params.m_fVelocityChange > 0.0f) {
+ CalculateDistance(params.m_bDistanceCalculated, params.m_fDistance);
+ train = (CTrain *)params.m_pVehicle;
speedMultipler = Min(1.0f, train->m_fSpeed * 250.f / 51.f);
emittingVol = (75.f * speedMultipler);
if (train->m_fWagonPosition == 0.0f) {
@@ -3232,7 +3226,7 @@ cAudioManager::ProcessTrainNoise(cVehicleParams *params)
}
}
const float SOUND_INTENSITY = 70.0f;
- if (params->m_fDistance < SQR(SOUND_INTENSITY)) {
+ if (params.m_fDistance < SQR(SOUND_INTENSITY)) {
m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, SOUND_INTENSITY, m_sQueueSample.m_fDistance);
if (m_sQueueSample.m_nVolume != 0) {
m_sQueueSample.m_nCounter = 33;
@@ -3263,25 +3257,128 @@ cAudioManager::ProcessBoatEngine(cVehicleParams& params)
{
CBoat *boat;
float padRelativeAccerate;
- float gasPedal;
- int32 padAccelerate;
- uint8 emittingVol;
- float oneShotVol;
- static uint16 LastAccel = 0;
- static uint8 LastVol = 0;
+ bool isV12 = false;
+ static int32 LastFreq = 2000;
+ static int8 LastVol = 0;
- static const int intensity = 50;
+ static const float intensity = 90.0f;
if (params.m_fDistance < SQR(intensity)) {
boat = (CBoat *)params.m_pVehicle;
- if (params.m_nIndex == REEFER) {
+ if(boat->GetStatus() == STATUS_WRECKED)
+ return true;
+
+ float freqModificator;
+ float volModificator;
+ int BaseVol;
+ int BaseFreq;
+
+ switch(boat->GetModelIndex()) {
+ case MI_RIO:
+ freqModificator = 490.0f;
+ volModificator = 60.0f;
+ BaseVol = 20;
+ BaseFreq = 1888;
+ break;
+ case MI_PREDATOR:
+ case MI_SQUALO:
+ case MI_SPEEDER:
+ case MI_COASTG:
+ case MI_DINGHY:
+ case MI_JETMAX:
+ freqModificator = 6000.0f;
+ volModificator = 60.0f;
+ isV12 = true;
+ BaseFreq = 9000;
+ BaseVol = 20;
+ break;
+ case MI_REEFER:
+ freqModificator = 715.0f;
+ volModificator = 80.0f;
+ BaseVol = 0;
+ BaseFreq = 3775;
+ break;
+ case MI_TROPIC:
+ case MI_MARQUIS:
+ freqModificator = 463.0f;
+ volModificator = 60.0f;
+ BaseVol = 20;
+ BaseFreq = 1782;
+ break;
+ default:
+ return true;
+ }
+
+ bool bIsPlayerVeh;
+
+ if(FindPlayerVehicle() == params.m_pVehicle) {
+ float padAccelerate = Max(Pads[0].GetAccelerate(), Pads[0].GetBrake());
+ padRelativeAccerate = padAccelerate / 255.0f;
+ bIsPlayerVeh = true;
+ } else {
+ padRelativeAccerate = Max(params.m_pVehicle->m_fGasPedal, params.m_pVehicle->m_fBrakePedal);
+ bIsPlayerVeh = false;
+ }
+
+ int Freq = BaseFreq + (padRelativeAccerate * freqModificator);
+ int Vol = BaseVol + (padRelativeAccerate * volModificator);
+
+ if(!boat->bPropellerInWater)
+ Freq = (9 * Freq) / 8;
+
+ if(bIsPlayerVeh) {
+ if(Freq > LastFreq) {
+ if(isV12)
+ Freq = Min(Freq, LastFreq + 100);
+ else
+ Freq = Min(Freq, LastFreq + 15);
+ } else {
+ if(isV12)
+ Freq = Max(Freq, LastFreq - 100);
+ else
+ Freq = Max(Freq, LastFreq - 15);
+ }
+ if(Vol > LastVol)
+ Vol = Min(Vol, LastVol + 3);
+ else
+ Vol = Max(Vol, LastVol - 3);
+ }
+
+ if (Vol > 0) {
CalculateDistance(params.m_bDistanceCalculated, params.m_fDistance);
- m_sQueueSample.m_nVolume = ComputeVolume(80, 50.f, m_sQueueSample.m_fDistance);
+ m_sQueueSample.m_nVolume = ComputeVolume(Vol, intensity, m_sQueueSample.m_fDistance);
if (m_sQueueSample.m_nVolume != 0) {
+ m_sQueueSample.m_nFrequency = Freq;
+ m_sQueueSample.m_nCounter = 40;
+ if (isV12)
+ m_sQueueSample.m_nSampleIndex = SFX_BOAT_V12_LOOP;
+ else
+ m_sQueueSample.m_nSampleIndex = SFX_BOAT_CRUISER_LOOP;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_nLoopCount = 0;
+ m_sQueueSample.m_nEmittingVolume = Vol;
+ m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_fSpeedMultiplier = 2.0f;
+ m_sQueueSample.m_fSoundIntensity = intensity;
+ m_sQueueSample.m_bReleasingSoundFlag = false;
+ m_sQueueSample.m_nReleasingVolumeDivider = 7;
+ m_sQueueSample.m_bReverbFlag = true;
+ m_sQueueSample.m_bRequireReflection = false;
+ AddSampleToRequestedQueue();
+ }
+ }
+
+ if(boat->GetModelIndex() == MI_REEFER) {
+ CalculateDistance(params.m_bDistanceCalculated, params.m_fDistance);
+ m_sQueueSample.m_nVolume = ComputeVolume(80, intensity, m_sQueueSample.m_fDistance);
+ if (m_sQueueSample.m_nVolume != 0) {
+ m_sQueueSample.m_nFrequency = 6000;
m_sQueueSample.m_nCounter = 39;
m_sQueueSample.m_nSampleIndex = SFX_FISHING_BOAT_IDLE;
- m_sQueueSample.m_nFrequency = 10386;
m_sQueueSample.m_nFrequency += (m_sQueueSample.m_nEntityIndex * 65536) % 1000;
m_sQueueSample.m_nBankIndex = SFX_BANK_0;
m_sQueueSample.m_bIs2D = false;
@@ -3298,102 +3395,11 @@ cAudioManager::ProcessBoatEngine(cVehicleParams& params)
m_sQueueSample.m_bRequireReflection = false;
AddSampleToRequestedQueue();
}
- if (FindPlayerVehicle() == params.m_pVehicle) {
- padAccelerate = Max(Pads[0].GetAccelerate(), Pads[0].GetBrake());
- padRelativeAccerate = padAccelerate / 255;
- emittingVol = (100.f * padRelativeAccerate) + 15;
- m_sQueueSample.m_nFrequency = (3000.f * padRelativeAccerate) + 6000;
- if (!boat->m_bIsAnchored)
- m_sQueueSample.m_nFrequency = 11 * m_sQueueSample.m_nFrequency / 10;
- } else {
- gasPedal = Abs(boat->m_fGasPedal);
- if (gasPedal > 0.0f) {
- m_sQueueSample.m_nFrequency = 6000;
- emittingVol = 15;
- } else {
- emittingVol = (100.f * gasPedal) + 15;
- m_sQueueSample.m_nFrequency = (3000.f * gasPedal) + 6000;
- if (!boat->m_bIsAnchored)
- m_sQueueSample.m_nFrequency = 11 * m_sQueueSample.m_nFrequency / 10;
- }
- }
- m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, 50.f, m_sQueueSample.m_fDistance);
- if (!m_sQueueSample.m_nVolume)
- return true;
- m_sQueueSample.m_nCounter = 40;
- m_sQueueSample.m_nSampleIndex = SFX_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;
- m_sQueueSample.m_nReleasingVolumeModificator = 3;
- m_sQueueSample.m_nLoopCount = 0;
- m_sQueueSample.m_nEmittingVolume = emittingVol;
- m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_fSpeedMultiplier = 2.0f;
- m_sQueueSample.m_fSoundIntensity = intensity;
- m_sQueueSample.m_bReleasingSoundFlag = false;
- m_sQueueSample.m_nReleasingVolumeDivider = 7;
- m_sQueueSample.m_bReverbFlag = true;
- m_sQueueSample.m_bRequireReflection = false;
- } else {
- if (FindPlayerVehicle() == params.m_pVehicle) {
- padAccelerate = Max(Pads[0].GetAccelerate(), Pads[0].GetBrake());
- if (padAccelerate <= 20) {
- emittingVol = 45 - 45 * padAccelerate / 40;
- m_sQueueSample.m_nFrequency = 100 * padAccelerate + 11025;
- m_sQueueSample.m_nCounter = 39;
- m_sQueueSample.m_nSampleIndex = SFX_FISHING_BOAT_IDLE;
- if (LastAccel > 20) {
- oneShotVol = LastVol;
- PlayOneShot(m_sQueueSample.m_nEntityIndex, SOUND_BOAT_SLOWDOWN, oneShotVol);
- }
- } else {
- emittingVol = 105 * padAccelerate / 255 + 15;
- m_sQueueSample.m_nFrequency = 4000 * padAccelerate / 255 + 8000;
- if (!boat->m_bIsAnchored)
- m_sQueueSample.m_nFrequency = 11 * m_sQueueSample.m_nFrequency / 10;
- m_sQueueSample.m_nCounter = 40;
- m_sQueueSample.m_nSampleIndex = SFX_FISHING_BOAT_IDLE;
- }
- LastVol = emittingVol;
- LastAccel = padAccelerate;
- } else {
- gasPedal = Abs(boat->m_fGasPedal);
- if (gasPedal > 0.0f) {
- m_sQueueSample.m_nFrequency = 11025;
- emittingVol = 45;
- m_sQueueSample.m_nCounter = 39;
- m_sQueueSample.m_nSampleIndex = SFX_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_FISHING_BOAT_IDLE;
- }
- }
- CalculateDistance(params.m_bDistanceCalculated, params.m_fDistance);
- m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, 50.f, m_sQueueSample.m_fDistance);
- if (!m_sQueueSample.m_nVolume)
- return true;
- m_sQueueSample.m_nFrequency += (m_sQueueSample.m_nEntityIndex * 65536) % 1000;
- m_sQueueSample.m_nBankIndex = SFX_BANK_0;
- m_sQueueSample.m_bIs2D = false;
- m_sQueueSample.m_nReleasingVolumeModificator = 3;
- m_sQueueSample.m_nLoopCount = 0;
- m_sQueueSample.m_nEmittingVolume = emittingVol;
- m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_fSpeedMultiplier = 2.0f;
- m_sQueueSample.m_fSoundIntensity = intensity;
- m_sQueueSample.m_bReleasingSoundFlag = false;
- m_sQueueSample.m_nReleasingVolumeDivider = 7;
- m_sQueueSample.m_bReverbFlag = true;
- m_sQueueSample.m_bRequireReflection = false;
}
- AddSampleToRequestedQueue();
+ if(bIsPlayerVeh) {
+ LastFreq = Freq;
+ LastVol = Vol;
+ }
return true;
}
return false;
@@ -3432,7 +3438,7 @@ cAudioManager::ProcessBoatMovingOverWater(cVehicleParams& params)
m_sQueueSample.m_fSpeedMultiplier = 2.0f;
m_sQueueSample.m_fSoundIntensity = 50.0f;
m_sQueueSample.m_bReleasingSoundFlag = false;
- m_sQueueSample.m_nReleasingVolumeDivider = 3;
+ m_sQueueSample.m_nReleasingVolumeDivider = 6;
m_sQueueSample.m_bReverbFlag = true;
m_sQueueSample.m_bRequireReflection = false;
AddSampleToRequestedQueue();
@@ -3630,7 +3636,7 @@ cAudioManager::ProcessCarHeli(cVehicleParams& params)
//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);
+ m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, 140.0f, m_sQueueSample.m_fDistance);
if (m_sQueueSample.m_nVolume != 0) {
m_sQueueSample.m_nCounter = 1;
if (hunterBool) {
@@ -3677,7 +3683,7 @@ cAudioManager::ProcessCarHeli(cVehicleParams& params)
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);
+ m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, 30.0f, m_sQueueSample.m_fDistance);
if (m_sQueueSample.m_nVolume) {
if (hunterBool) {
m_sQueueSample.m_nSampleIndex = SFX_HELI_APACHE_4;
@@ -3718,7 +3724,7 @@ cAudioManager::ProcessCarHeli(cVehicleParams& params)
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)
+ if (propellerSpeed < 1.0f)
m_sQueueSample.m_nFrequency = (propellerSpeed + 1) * (m_sQueueSample.m_nFrequency / 2.0f);
m_sQueueSample.m_nFrequency = clamp2(m_sQueueSample.m_nFrequency, freqSkimmerPrev, 197);
freqSkimmerPrev = m_sQueueSample.m_nFrequency;
@@ -3761,7 +3767,7 @@ cAudioManager::ProcessCarHeli(cVehicleParams& params)
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_bIs2D = false;
m_sQueueSample.m_nReleasingVolumeModificator = 1;
m_sQueueSample.m_nFrequency = (volumeModifier + 1.0f) * 16000;
m_sQueueSample.m_nLoopCount = 0;
@@ -3880,8 +3886,8 @@ cAudioManager::ProcessJumbo(cVehicleParams& params)
CPlane *plane;
float position;
- //if (params.m_fDistance >= SQR(440))
- // return;
+ if (params.m_fDistance >= SQR(440))
+ return;
CalculateDistance(params.m_bDistanceCalculated, params.m_fDistance);
plane = (CPlane*)params.m_pVehicle;
@@ -4083,27 +4089,26 @@ bool
cAudioManager::SetupJumboFlySound(uint8 emittingVol)
{
const float SOUND_INTENSITY = 440.0f;
- if (m_sQueueSample.m_fDistance >= SOUND_INTENSITY)
- return false;
+ if(m_sQueueSample.m_fDistance >= SOUND_INTENSITY) return false;
int32 vol = ComputeVolume(emittingVol, SOUND_INTENSITY, m_sQueueSample.m_fDistance);
m_sQueueSample.m_nVolume = vol;
- if (m_sQueueSample.m_nVolume != 0) {
- m_sQueueSample.m_nSampleIndex = SFX_JUMBO_DIST_FLY;
+ if(m_sQueueSample.m_nVolume != 0) {
m_sQueueSample.m_nCounter = 0;
+ m_sQueueSample.m_nSampleIndex = SFX_JUMBO_DIST_FLY;
m_sQueueSample.m_nBankIndex = SFX_BANK_0;
m_sQueueSample.m_bIs2D = false;
m_sQueueSample.m_nReleasingVolumeModificator = 1;
- m_sQueueSample.m_nEmittingVolume = emittingVol;
- m_sQueueSample.m_nLoopCount = 0;
m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_JUMBO_DIST_FLY);
+ m_sQueueSample.m_nLoopCount = 0;
+ m_sQueueSample.m_nEmittingVolume = emittingVol;
m_sQueueSample.m_nLoopStart = SampleManager.GetSampleLoopStartOffset(m_sQueueSample.m_nSampleIndex);
- m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY;
- m_sQueueSample.m_bReleasingSoundFlag = false;
+ m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
m_sQueueSample.m_fSpeedMultiplier = 4.0f;
- m_sQueueSample.m_bReverbFlag = true;
+ m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY;
m_sQueueSample.m_nReleasingVolumeDivider = 5;
- m_sQueueSample.m_nLoopEnd = SampleManager.GetSampleLoopEndOffset(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_bReverbFlag = true;
+ m_sQueueSample.m_bRequireReflection = false; // todo port fix to re3
AddSampleToRequestedQueue();
}
return true;
@@ -4149,7 +4154,7 @@ cAudioManager::SetupJumboRumbleSound(uint8 emittingVol)
int32
cAudioManager::GetJumboTaxiFreq() const
{
- return (60.833f * m_sQueueSample.m_fDistance) + 22050;
+ return (1.f / 180 * 10950 * m_sQueueSample.m_fDistance) + 22050; // todo port fix to re3
}
#pragma endregion Some jumbo crap
@@ -4162,49 +4167,46 @@ cAudioManager::ProcessPed(CPhysical *ped)
{
cPedParams params;
- params.m_pPed = nil;
- params.m_bDistanceCalculated = false;
- params.m_fDistance = 0.0f;
-
m_sQueueSample.m_vecPos = ped->GetPosition();
- //params.m_bDistanceCalculated = false;
+ params.m_bDistanceCalculated = false;
params.m_pPed = (CPed *)ped;
params.m_fDistance = GetDistanceSquared(m_sQueueSample.m_vecPos);
- ProcessPedOneShots(&params);
+ ProcessPedOneShots(params);
}
void
-cAudioManager::ProcessPedOneShots(cPedParams *params)
+cAudioManager::ProcessPedOneShots(cPedParams &params)
{
uint8 emittingVol;
int32 sampleIndex;
- CPed *ped = params->m_pPed;
+ CPed *ped = params.m_pPed;
- bool stereo;
+ bool narrowSoundRange;
int16 sound;
- bool noReflection;
+ bool stereo;
CWeapon *weapon;
float maxDist = 0.f; // uninitialized variable
static uint8 iSound = 21;
+ static uint32 iSplashFrame = 0;
- weapon = params->m_pPed->GetWeapon();
+ weapon = params.m_pPed->GetWeapon();
for (uint32 i = 0; i < m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_AudioEvents; i++) {
- noReflection = false;
stereo = false;
+ narrowSoundRange = false;
m_sQueueSample.m_bRequireReflection = false;
sound = m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_awAudioEvent[i];
switch (sound) {
case SOUND_STEP_START:
case SOUND_STEP_END:
- if (!params->m_pPed->bIsLooking) {
+ if (!params.m_pPed->bIsLooking) {
emittingVol = m_anRandomTable[3] % 15 + 45;
if (FindPlayerPed() != m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_pEntity)
emittingVol /= 2;
maxDist = 400.f;
- switch (params->m_pPed->m_nSurfaceTouched) {
+ switch (params.m_pPed->m_nSurfaceTouched) {
case SURFACE_GRASS:
sampleIndex = m_anRandomTable[1] % 5 + SFX_FOOTSTEP_GRASS_1;
break;
@@ -4245,10 +4247,10 @@ 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) {
+ switch (params.m_pPed->m_nMoveState) {
case PEDMOVE_WALK:
emittingVol /= 4;
m_sQueueSample.m_nFrequency = 9 * m_sQueueSample.m_nFrequency / 10;
@@ -4306,229 +4308,83 @@ cAudioManager::ProcessPedOneShots(cPedParams *params)
case SOUND_FIGHT_37:
m_sQueueSample.m_nSampleIndex = SFX_FIGHT_1;
m_sQueueSample.m_nFrequency = 18000;
- m_sQueueSample.m_nBankIndex = SFX_BANK_0;
- m_sQueueSample.m_nCounter = iSound;
- stereo = true;
- ++iSound;
- m_sQueueSample.m_nReleasingVolumeModificator = 3;
- m_sQueueSample.m_fSpeedMultiplier = 0.0f;
- m_sQueueSample.m_fSoundIntensity = 30.0f;
- maxDist = SQR(30);
- m_sQueueSample.m_nLoopCount = 1;
- m_sQueueSample.m_nLoopStart = 0;
- emittingVol = m_anRandomTable[3] % 26 + 100;
- m_sQueueSample.m_nLoopEnd = -1;
- m_sQueueSample.m_nEmittingVolume = emittingVol;
- m_sQueueSample.m_bIs2D = false;
- m_sQueueSample.m_bReleasingSoundFlag = true;
- m_sQueueSample.m_bRequireReflection = true;
- break;
+ goto AddFightSound;
case SOUND_FIGHT_38:
m_sQueueSample.m_nSampleIndex = SFX_FIGHT_1;
m_sQueueSample.m_nFrequency = 16500;
- m_sQueueSample.m_nBankIndex = SFX_BANK_0;
- m_sQueueSample.m_nCounter = iSound;
- stereo = true;
- ++iSound;
- m_sQueueSample.m_nReleasingVolumeModificator = 3;
- m_sQueueSample.m_fSpeedMultiplier = 0.0f;
- m_sQueueSample.m_fSoundIntensity = 30.0f;
- maxDist = SQR(30);
- m_sQueueSample.m_nLoopCount = 1;
- m_sQueueSample.m_nLoopStart = 0;
- emittingVol = m_anRandomTable[3] % 26 + 100;
- m_sQueueSample.m_nLoopEnd = -1;
- m_sQueueSample.m_nEmittingVolume = emittingVol;
- m_sQueueSample.m_bIs2D = false;
- m_sQueueSample.m_bReleasingSoundFlag = true;
- m_sQueueSample.m_bRequireReflection = true;
- break;
+ goto AddFightSound;
case SOUND_FIGHT_39:
m_sQueueSample.m_nSampleIndex = SFX_FIGHT_1;
m_sQueueSample.m_nFrequency = 20000;
- m_sQueueSample.m_nBankIndex = SFX_BANK_0;
- m_sQueueSample.m_nCounter = iSound;
- stereo = true;
- ++iSound;
- m_sQueueSample.m_nReleasingVolumeModificator = 3;
- m_sQueueSample.m_fSpeedMultiplier = 0.0f;
- m_sQueueSample.m_fSoundIntensity = 30.0f;
- maxDist = SQR(30);
- m_sQueueSample.m_nLoopCount = 1;
- m_sQueueSample.m_nLoopStart = 0;
- emittingVol = m_anRandomTable[3] % 26 + 100;
- m_sQueueSample.m_nLoopEnd = -1;
- m_sQueueSample.m_nEmittingVolume = emittingVol;
- m_sQueueSample.m_bIs2D = false;
- m_sQueueSample.m_bReleasingSoundFlag = true;
- m_sQueueSample.m_bRequireReflection = true;
- break;
+ goto AddFightSound;
case SOUND_FIGHT_40:
m_sQueueSample.m_nSampleIndex = SFX_FIGHT_2;
m_sQueueSample.m_nFrequency = 18000;
- m_sQueueSample.m_nBankIndex = SFX_BANK_0;
- m_sQueueSample.m_nCounter = iSound;
- stereo = true;
- ++iSound;
- m_sQueueSample.m_nReleasingVolumeModificator = 3;
- m_sQueueSample.m_fSpeedMultiplier = 0.0f;
- m_sQueueSample.m_fSoundIntensity = 30.0f;
- maxDist = SQR(30);
- m_sQueueSample.m_nLoopCount = 1;
- m_sQueueSample.m_nLoopStart = 0;
- emittingVol = m_anRandomTable[3] % 26 + 100;
- m_sQueueSample.m_nLoopEnd = -1;
- m_sQueueSample.m_nEmittingVolume = emittingVol;
- m_sQueueSample.m_bIs2D = false;
- m_sQueueSample.m_bReleasingSoundFlag = true;
- m_sQueueSample.m_bRequireReflection = true;
- break;
+ goto AddFightSound;
case SOUND_FIGHT_41:
m_sQueueSample.m_nSampleIndex = SFX_FIGHT_2;
m_sQueueSample.m_nFrequency = 16500;
- m_sQueueSample.m_nBankIndex = SFX_BANK_0;
- m_sQueueSample.m_nCounter = iSound;
- stereo = true;
- ++iSound;
- m_sQueueSample.m_nReleasingVolumeModificator = 3;
- m_sQueueSample.m_fSpeedMultiplier = 0.0f;
- m_sQueueSample.m_fSoundIntensity = 30.0f;
- maxDist = SQR(30);
- m_sQueueSample.m_nLoopCount = 1;
- m_sQueueSample.m_nLoopStart = 0;
- emittingVol = m_anRandomTable[3] % 26 + 100;
- m_sQueueSample.m_nLoopEnd = -1;
- m_sQueueSample.m_nEmittingVolume = emittingVol;
- m_sQueueSample.m_bIs2D = false;
- m_sQueueSample.m_bReleasingSoundFlag = true;
- m_sQueueSample.m_bRequireReflection = true;
- break;
+ goto AddFightSound;
case SOUND_FIGHT_42:
m_sQueueSample.m_nSampleIndex = SFX_FIGHT_2;
m_sQueueSample.m_nFrequency = 20000;
- m_sQueueSample.m_nBankIndex = SFX_BANK_0;
- m_sQueueSample.m_nCounter = iSound;
- stereo = true;
- ++iSound;
- m_sQueueSample.m_nReleasingVolumeModificator = 3;
- m_sQueueSample.m_fSpeedMultiplier = 0.0f;
- m_sQueueSample.m_fSoundIntensity = 30.0f;
- maxDist = SQR(30);
- m_sQueueSample.m_nLoopCount = 1;
- m_sQueueSample.m_nLoopStart = 0;
- emittingVol = m_anRandomTable[3] % 26 + 100;
- m_sQueueSample.m_nLoopEnd = -1;
- m_sQueueSample.m_nEmittingVolume = emittingVol;
- m_sQueueSample.m_bIs2D = false;
- m_sQueueSample.m_bReleasingSoundFlag = true;
- m_sQueueSample.m_bRequireReflection = true;
- break;
+ goto AddFightSound;
case SOUND_FIGHT_43:
m_sQueueSample.m_nSampleIndex = SFX_FIGHT_4;
m_sQueueSample.m_nFrequency = 18000;
- m_sQueueSample.m_nBankIndex = SFX_BANK_0;
- m_sQueueSample.m_nCounter = iSound;
- stereo = true;
- ++iSound;
- m_sQueueSample.m_nReleasingVolumeModificator = 3;
- m_sQueueSample.m_fSpeedMultiplier = 0.0f;
- m_sQueueSample.m_fSoundIntensity = 30.0f;
- maxDist = SQR(30);
- m_sQueueSample.m_nLoopCount = 1;
- m_sQueueSample.m_nLoopStart = 0;
- emittingVol = m_anRandomTable[3] % 26 + 100;
- m_sQueueSample.m_nLoopEnd = -1;
- m_sQueueSample.m_nEmittingVolume = emittingVol;
- m_sQueueSample.m_bIs2D = false;
- m_sQueueSample.m_bReleasingSoundFlag = true;
- m_sQueueSample.m_bRequireReflection = true;
- break;
+ goto AddFightSound;
case SOUND_FIGHT_44:
m_sQueueSample.m_nSampleIndex = SFX_FIGHT_4;
m_sQueueSample.m_nFrequency = 16500;
- m_sQueueSample.m_nBankIndex = SFX_BANK_0;
- m_sQueueSample.m_nCounter = iSound;
- stereo = true;
- ++iSound;
- m_sQueueSample.m_nReleasingVolumeModificator = 3;
- m_sQueueSample.m_fSpeedMultiplier = 0.0f;
- m_sQueueSample.m_fSoundIntensity = 30.0f;
- maxDist = SQR(30);
- m_sQueueSample.m_nLoopCount = 1;
- m_sQueueSample.m_nLoopStart = 0;
- emittingVol = m_anRandomTable[3] % 26 + 100;
- m_sQueueSample.m_nLoopEnd = -1;
- m_sQueueSample.m_nEmittingVolume = emittingVol;
- m_sQueueSample.m_bIs2D = false;
- m_sQueueSample.m_bReleasingSoundFlag = true;
- m_sQueueSample.m_bRequireReflection = true;
- break;
+ goto AddFightSound;
case SOUND_FIGHT_45:
m_sQueueSample.m_nSampleIndex = SFX_FIGHT_4;
m_sQueueSample.m_nFrequency = 20000;
- m_sQueueSample.m_nBankIndex = SFX_BANK_0;
- m_sQueueSample.m_nCounter = iSound;
- stereo = true;
- ++iSound;
- m_sQueueSample.m_nReleasingVolumeModificator = 3;
- m_sQueueSample.m_fSpeedMultiplier = 0.0f;
- m_sQueueSample.m_fSoundIntensity = 30.0f;
- maxDist = SQR(30);
- m_sQueueSample.m_nLoopCount = 1;
- m_sQueueSample.m_nLoopStart = 0;
- emittingVol = m_anRandomTable[3] % 26 + 100;
- m_sQueueSample.m_nLoopEnd = -1;
- m_sQueueSample.m_nEmittingVolume = emittingVol;
- m_sQueueSample.m_bIs2D = false;
- m_sQueueSample.m_bReleasingSoundFlag = true;
- m_sQueueSample.m_bRequireReflection = true;
- break;
+ goto AddFightSound;
case SOUND_FIGHT_46:
m_sQueueSample.m_nSampleIndex = SFX_FIGHT_5;
m_sQueueSample.m_nFrequency = 18000;
- m_sQueueSample.m_nBankIndex = SFX_BANK_0;
- m_sQueueSample.m_nCounter = iSound;
- stereo = true;
- ++iSound;
- m_sQueueSample.m_nReleasingVolumeModificator = 3;
- m_sQueueSample.m_fSpeedMultiplier = 0.0f;
- m_sQueueSample.m_fSoundIntensity = 30.0f;
- maxDist = SQR(30);
- m_sQueueSample.m_nLoopCount = 1;
- m_sQueueSample.m_nLoopStart = 0;
- emittingVol = m_anRandomTable[3] % 26 + 100;
- m_sQueueSample.m_nLoopEnd = -1;
- m_sQueueSample.m_nEmittingVolume = emittingVol;
- m_sQueueSample.m_bIs2D = false;
- m_sQueueSample.m_bReleasingSoundFlag = true;
- m_sQueueSample.m_bRequireReflection = true;
- break;
+ goto AddFightSound;
case SOUND_FIGHT_47:
m_sQueueSample.m_nSampleIndex = SFX_FIGHT_5;
m_sQueueSample.m_nFrequency = 16500;
- m_sQueueSample.m_nBankIndex = SFX_BANK_0;
- m_sQueueSample.m_nCounter = iSound;
- stereo = true;
- ++iSound;
- m_sQueueSample.m_nReleasingVolumeModificator = 3;
- m_sQueueSample.m_fSpeedMultiplier = 0.0f;
- m_sQueueSample.m_fSoundIntensity = 30.0f;
- maxDist = SQR(30);
- m_sQueueSample.m_nLoopCount = 1;
- m_sQueueSample.m_nLoopStart = 0;
- emittingVol = m_anRandomTable[3] % 26 + 100;
- m_sQueueSample.m_nLoopEnd = -1;
- m_sQueueSample.m_nEmittingVolume = emittingVol;
- m_sQueueSample.m_bIs2D = false;
- m_sQueueSample.m_bReleasingSoundFlag = true;
- m_sQueueSample.m_bRequireReflection = true;
- break;
+ goto AddFightSound;
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;
- stereo = true;
+ narrowSoundRange = true;
++iSound;
m_sQueueSample.m_nReleasingVolumeModificator = 3;
m_sQueueSample.m_fSpeedMultiplier = 0.0f;
@@ -4544,11 +4400,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++;
- stereo = true;
- m_sQueueSample.m_nFrequency = RandomDisplacement(2000) + 22000;
+ narrowSoundRange = true;
m_sQueueSample.m_nReleasingVolumeModificator = 3;
m_sQueueSample.m_fSpeedMultiplier = 0.0f;
m_sQueueSample.m_fSoundIntensity = 30.0f;
@@ -4560,25 +4453,109 @@ 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
- noReflection = true;
+ m_sQueueSample.m_bRequireReflection = true;
+ break;
+ }
+ 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.GetSampleLoopEndOffset(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.GetSampleLoopEndOffset(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;
m_sQueueSample.m_nCounter = iSound++;
- stereo = true;
+ narrowSoundRange = true;
m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_COLT45_LEFT);
m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32);
m_sQueueSample.m_nReleasingVolumeModificator = 3;
m_sQueueSample.m_fSpeedMultiplier = 0.0f;
- m_sQueueSample.m_fSoundIntensity = 50.0f;
- maxDist = SQR(50);
+ m_sQueueSample.m_fSoundIntensity = 120.0f;
+ maxDist = SQR(120);
m_sQueueSample.m_nLoopCount = 1;
m_sQueueSample.m_nLoopStart = 0;
m_sQueueSample.m_nLoopEnd = -1;
@@ -4586,41 +4563,42 @@ 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
- noReflection = 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++;
- stereo = true;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_UZI_LEFT);
+ narrowSoundRange = true;
+ 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++;
- stereo = true;
+ narrowSoundRange = true;
m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_SHOTGUN_LEFT);
m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32);
m_sQueueSample.m_nReleasingVolumeModificator = 3;
m_sQueueSample.m_fSpeedMultiplier = 0.0f;
- m_sQueueSample.m_fSoundIntensity = 60.0f;
- maxDist = SQR(60);
+ m_sQueueSample.m_fSoundIntensity = 120.0f;
+ maxDist = SQR(120);
m_sQueueSample.m_nLoopCount = 1;
m_sQueueSample.m_nLoopStart = 0;
m_sQueueSample.m_nLoopEnd = -1;
@@ -4628,94 +4606,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
- noReflection = true;
+ m_sQueueSample.m_bRequireReflection = true;
+ stereo = true;
break;
- case WEAPONTYPE_RUGER:
- 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++;
- stereo = true;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_AK47_LEFT);
+ narrowSoundRange = true;
+ 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;
- emittingVol = m_anRandomTable[1] % 15 + 70;
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_M4:
- m_sQueueSample.m_nSampleIndex = SFX_M60_LEFT;
+ case WEAPONTYPE_TEC9:
+ m_sQueueSample.m_nSampleIndex = SFX_TEC_LEFT;
m_sQueueSample.m_nBankIndex = SFX_BANK_0;
m_sQueueSample.m_nCounter = iSound++;
+ narrowSoundRange = true;
+ m_sQueueSample.m_nFrequency = 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[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;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_M60_LEFT);
+ break;
+ case WEAPONTYPE_UZI:
+ case WEAPONTYPE_MINIGUN:
+ m_sQueueSample.m_nSampleIndex = SFX_UZI_LEFT;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;
+ m_sQueueSample.m_nCounter = iSound++;
+ narrowSoundRange = true;
+ m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_UZI_LEFT);
m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32);
m_sQueueSample.m_nReleasingVolumeModificator = 3;
m_sQueueSample.m_fSpeedMultiplier = 0.0f;
- m_sQueueSample.m_fSoundIntensity = 80.0f;
- maxDist = SQR(80);
+ m_sQueueSample.m_fSoundIntensity = 120.0f;
+ maxDist = SQR(120);
m_sQueueSample.m_nLoopCount = 1;
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 = 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;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_SNIPER_LEFT);
+ 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
- noReflection = 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 = 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;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_ROCKET_LEFT);
+ 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
- noReflection = 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;
@@ -4734,53 +4790,73 @@ 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
- noReflection = 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_AK47_RELOAD;
- m_sQueueSample.m_nFrequency = 39243;
- break;
case WEAPONTYPE_SHOTGUN:
- m_sQueueSample.m_nSampleIndex = SFX_AK47_RELOAD;
- m_sQueueSample.m_nFrequency = 30290;
- break;
+ case WEAPONTYPE_SPAS12_SHOTGUN:
+ case WEAPONTYPE_STUBBY_SHOTGUN:
case WEAPONTYPE_RUGER:
m_sQueueSample.m_nSampleIndex = SFX_AK47_RELOAD;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_AK47_RELOAD);
+ m_sQueueSample.m_nFrequency = 30290;
break;
+ 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);
+ 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;
}
emittingVol = 75;
m_sQueueSample.m_nCounter = iSound++;
- stereo = true;
+ narrowSoundRange = true;
m_sQueueSample.m_nFrequency += RandomDisplacement(300);
m_sQueueSample.m_nBankIndex = SFX_BANK_0;
m_sQueueSample.m_nReleasingVolumeModificator = 5;
@@ -4796,28 +4872,71 @@ cAudioManager::ProcessPedOneShots(cPedParams *params)
m_sQueueSample.m_bRequireReflection = true;
break;
case SOUND_WEAPON_AK47_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++;
- stereo = true;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_UZI_END_LEFT);
+ narrowSoundRange = true;
+ 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
- noReflection = 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;
@@ -4840,7 +4959,7 @@ cAudioManager::ProcessPedOneShots(cPedParams *params)
m_sQueueSample.m_nSampleIndex = SFX_BULLET_PED;
m_sQueueSample.m_nBankIndex = SFX_BANK_0;
m_sQueueSample.m_nCounter = iSound++;
- stereo = true;
+ narrowSoundRange = true;
m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_BULLET_PED);
m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 8);
m_sQueueSample.m_nReleasingVolumeModificator = 7;
@@ -4856,10 +4975,13 @@ 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++;
- stereo = true;
+ narrowSoundRange = true;
m_sQueueSample.m_nFrequency = RandomDisplacement(1400) + 20000;
m_sQueueSample.m_nReleasingVolumeModificator = 1;
m_sQueueSample.m_fSpeedMultiplier = 0.0f;
@@ -4874,28 +4996,192 @@ 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 = SFX_BANK_0;
+ m_sQueueSample.m_nCounter = iSound;
+ stereo = true;
+ ++iSound;
+ m_sQueueSample.m_nFrequency = m_anRandomTable[1] % 1000 + 17000;
+ if (param2 == 0)
+ m_sQueueSample.m_nFrequency = (3 * m_sQueueSample.m_nFrequency) / 4;
+ m_sQueueSample.m_nReleasingVolumeModificator = 6;
+ m_sQueueSample.m_fSpeedMultiplier = 3.0f;
+ m_sQueueSample.m_fSoundIntensity = 20.0f;
+ maxDist = SQR(20);
+ m_sQueueSample.m_nLoopCount = 1;
+ 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() && params.m_pPed->m_pMyVehicle) {
+ if (m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i] > 0.0f) {
+ if (m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i] > 1.0f)
+ m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i] = 1.0f;
+
+ emittingVol = 90.0f * m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_afVolume[i];
+
+ switch (params.m_pPed->m_pMyVehicle->GetModelIndex())
+ {
+ case MI_ANGEL:
+ case MI_FREEWAY:
+ m_sQueueSample.m_nSampleIndex = SFX_CAR_WIND_17;
+ break;
+ case MI_PIZZABOY:
+ case MI_FAGGIO:
+ m_sQueueSample.m_nSampleIndex = SFX_CAR_WIND_18;
+ break;
+ case MI_PCJ600:
+ m_sQueueSample.m_nSampleIndex = SFX_CAR_WIND_20;
+ break;
+ case MI_SANCHEZ:
+ m_sQueueSample.m_nSampleIndex = SFX_CAR_WIND_19;
+ break;
+ default:
+ continue;
+ };
+
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;
+ m_sQueueSample.m_nCounter = 71;
+ m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_fSpeedMultiplier = 3.0f;
+ m_sQueueSample.m_fSoundIntensity = 15.0f;
+ maxDist = SQR(15);
+ m_sQueueSample.m_nLoopCount = 0;
+ 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;
}
- if (stereo && iSound > 60)
+ if (narrowSoundRange && iSound > 60)
iSound = 21;
- if (params->m_fDistance < maxDist) {
- CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance);
+ if (params.m_fDistance < maxDist) {
+ CalculateDistance(params.m_bDistanceCalculated, params.m_fDistance);
m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance);
if (m_sQueueSample.m_nVolume != 0) {
- if (noReflection) {
+ if (stereo) {
if (m_sQueueSample.m_fDistance < 0.2f * m_sQueueSample.m_fSoundIntensity) {
m_sQueueSample.m_bIs2D = true;
m_sQueueSample.m_nOffset = 0;
} else {
- noReflection = false;
+ stereo = false;
}
}
m_sQueueSample.m_bReverbFlag = true;
AddSampleToRequestedQueue();
- if (noReflection) {
+ if (stereo) {
m_sQueueSample.m_nOffset = 127;
++m_sQueueSample.m_nSampleIndex;
if (m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_awAudioEvent[i] != SOUND_WEAPON_SHOT_FIRED ||
@@ -4933,9 +5219,9 @@ cAudioManager::SetPlayersMood(uint8 mood, uint32 time)
}
void
-cAudioManager::SetupPedComments(cPedParams *params, uint32 sound)
+cAudioManager::SetupPedComments(cPedParams &params, uint16 sound)
{
- CPed *ped = params->m_pPed;
+ CPed *ped = params.m_pPed;
uint8 emittingVol;
float soundIntensity;
tPedComment pedComment;
@@ -4974,8 +5260,8 @@ cAudioManager::SetupPedComments(cPedParams *params, uint32 sound)
}
}
- if(params->m_fDistance < SQR(soundIntensity)) {
- CalculateDistance(params->m_bDistanceCalculated, params->m_fDistance);
+ if(params.m_fDistance < SQR(soundIntensity)) {
+ CalculateDistance(params.m_bDistanceCalculated, params.m_fDistance);
if(CWorld::GetIsLineOfSightClear(TheCamera.GetPosition(), m_sQueueSample.m_vecPos, true, false, false, false, false, false))
emittingVol = MAX_VOLUME;
else
@@ -5161,7 +5447,7 @@ cAudioManager::GetPlayerTalkSfx(CPed *ped, int16 sound)
{
uint32 sfx;
- if(this->m_bIsPlayerShutUp) return NO_SAMPLE;
+ if(m_bIsPlayerShutUp) return NO_SAMPLE;
switch(sound) {
case SOUND_PED_DEATH: return 9796;
case SOUND_PED_DAMAGE:
@@ -7672,7 +7958,7 @@ cAudioManager::ProcessExplosions(int32 explosion)
m_sQueueSample.m_vecPos = *CExplosion::GetExplosionPosition(i);
distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos);
if (distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) {
- m_sQueueSample.m_fDistance = distSquared <= 0.0f ? 0.0f : Sqrt(distSquared);
+ m_sQueueSample.m_fDistance = Sqrt(distSquared);
m_sQueueSample.m_nVolume = ComputeVolume(MAX_VOLUME, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance);
if (m_sQueueSample.m_nVolume != 0) {
m_sQueueSample.m_nCounter = i;
@@ -7737,7 +8023,7 @@ cAudioManager::ProcessFires(int32)
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 = distSquared < 0.0f ? 0.0f : Sqrt(distSquared);
+ m_sQueueSample.m_fDistance = Sqrt(distSquared);
m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance);
if (m_sQueueSample.m_nVolume != 0) {
m_sQueueSample.m_nCounter = i;
@@ -7793,7 +8079,7 @@ 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 = distSquared <= 0.0f ? 0.0f : Sqrt(distSquared);
+ m_sQueueSample.m_fDistance = Sqrt(distSquared);
m_sQueueSample.m_nVolume = ComputeVolume(50, SOUND_INTENSITY, m_sQueueSample.m_fDistance);
if (m_sQueueSample.m_nVolume != 0) {
m_sQueueSample.m_fSoundIntensity = SOUND_INTENSITY;
@@ -7834,10 +8120,7 @@ cAudioManager::ProcessExtraSounds()
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_fDistance = Sqrt(distance);
m_sQueueSample.m_nVolume = ComputeVolume(EMITTING_VOLUME, SOUND_INTENSITY, m_sQueueSample.m_fDistance);
if (m_sQueueSample.m_nVolume != 0) {
m_sQueueSample.m_nCounter = i;
@@ -7876,10 +8159,7 @@ cAudioManager::ProcessEscalators()
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_fDistance = Sqrt(distance);
m_sQueueSample.m_nVolume = ComputeVolume(EMITTING_VOLUME, SOUND_INTENSITY, m_sQueueSample.m_fDistance);
if (m_sQueueSample.m_nVolume != 0) {
m_sQueueSample.m_nSampleIndex = SFX_BOAT_V12_LOOP;
@@ -7930,41 +8210,34 @@ cAudioManager::ProcessOneShotScriptObject(uint8 sound)
uint8 emittingVolume;
float distSquared;
- cPedParams male;
- cPedParams female;
-
static uint8 iSound = 0;
switch (sound) {
- /*case SCRIPT_SOUND_INJURED_PED_MALE_OUCH_S:
- case SCRIPT_SOUND_INJURED_PED_MALE_OUCH_L:
- male.m_pPed = nil;
- male.m_bDistanceCalculated = false;
- male.m_fDistance = GetDistanceSquared(m_sQueueSample.m_vecPos);
- SetupPedComments(&male, SOUND_INJURED_PED_MALE_OUCH);
- return;
- case SCRIPT_SOUND_INJURED_PED_FEMALE_OUCH_S:
- case SCRIPT_SOUND_INJURED_PED_FEMALE_OUCH_L:
- female.m_pPed = nil;
- female.m_bDistanceCalculated = false;
- female.m_fDistance = GetDistanceSquared(m_sQueueSample.m_vecPos);
- SetupPedComments(&female, SOUND_INJURED_PED_FEMALE);
- return;
- case SCRIPT_SOUND_GATE_START_CLUNK:
- case SCRIPT_SOUND_GATE_STOP_CLUNK:
+ case SCRIPT_SOUND_POLICE_CELL_DOOR_CLUNK:
m_sQueueSample.m_fSoundIntensity = 40.0f;
m_sQueueSample.m_nSampleIndex = SFX_COL_GATE;
m_sQueueSample.m_nBankIndex = SFX_BANK_0;
- if (sound == SCRIPT_SOUND_GATE_START_CLUNK)
- m_sQueueSample.m_nFrequency = 10600;
- else
- m_sQueueSample.m_nFrequency = 9000;
- m_sQueueSample.m_nReleasingVolumeModificator = 1;
+ m_sQueueSample.m_nFrequency = 10600;
+ m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32);
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ emittingVolume = 60;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_bRequireReflection = true;
+ break;
+ case SCRIPT_SOUND_GARAGE_DOOR_CLUNK:
+ m_sQueueSample.m_fSoundIntensity = 80.0f;
+ m_sQueueSample.m_nSampleIndex = SFX_COL_CAR_PANEL_2; // huh?
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;
+ m_sQueueSample.m_nFrequency = 22000;
+ m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 32);
+ m_sQueueSample.m_nReleasingVolumeModificator = 4;
+ emittingVolume = 60;
m_sQueueSample.m_fSpeedMultiplier = 0.0f;
m_sQueueSample.m_bIs2D = false;
m_sQueueSample.m_bRequireReflection = true;
- emittingVolume = RandomDisplacement(10) + 50;
- break;*/
+ break;
+ case SCRIPT_SOUND_SHOOTING_RANGE_TARGET_HIT:
case SCRIPT_SOUND_BULLET_HIT_GROUND_1:
case SCRIPT_SOUND_BULLET_HIT_GROUND_2:
case SCRIPT_SOUND_BULLET_HIT_GROUND_3:
@@ -7978,20 +8251,42 @@ 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(SAMPLEBANK_TRAIN))
- return;
- m_sQueueSample.m_fSoundIntensity = 80.0f;
- m_sQueueSample.m_nSampleIndex = SFX_TRAIN_STATION_ANNOUNCE;
- 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;
+ case SCRIPT_SOUND_WILLIE_CARD_SWIPE:
+ emittingVolume = 70;
+ m_sQueueSample.m_fSoundIntensity = 40.0f;
+ m_sQueueSample.m_nSampleIndex = SFX_BOMB_BEEP;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;
+ m_sQueueSample.m_nFrequency = 20159;
+ m_sQueueSample.m_nReleasingVolumeModificator = 1;
+ m_sQueueSample.m_fSpeedMultiplier = 1.0f;
m_sQueueSample.m_bIs2D = false;
- break;*/
+ m_sQueueSample.m_bRequireReflection = false;
+ break;
+ case SCRIPT_SOUND_MALE_AMBULANCE_OUCH:
+ {
+ cPedParams pedParams;
+ pedParams.m_fDistance = GetDistanceSquared(m_sQueueSample.m_vecPos);
+ SetupPedComments(pedParams, SOUND_INJURED_PED_MALE_OUCH);
+ return;
+ }
+ case SCRIPT_SOUND_FEMALE_AMBULANCE_OUCH:
+ {
+ cPedParams pedParams;
+ pedParams.m_fDistance = GetDistanceSquared(m_sQueueSample.m_vecPos);
+ SetupPedComments(pedParams, SOUND_INJURED_PED_FEMALE);
+ return;
+ }
+ case SCRIPT_SOUND_SEAPLANE_LOW_FUEL:
+ m_sQueueSample.m_fSoundIntensity = 1000.0f;
+ m_sQueueSample.m_nSampleIndex = SFX_SEAPLANE_LOW;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;
+ emittingVolume = 100;
+ m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CAR_HORN_JEEP); // BUG?
+ m_sQueueSample.m_nReleasingVolumeModificator = 1;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
+ m_sQueueSample.m_bIs2D = true;
+ m_sQueueSample.m_bRequireReflection = false;
+ break;
case SCRIPT_SOUND_PAYPHONE_RINGING:
m_sQueueSample.m_fSoundIntensity = 80.0f;
m_sQueueSample.m_nSampleIndex = SFX_PHONE_RING;
@@ -8090,6 +8385,18 @@ cAudioManager::ProcessOneShotScriptObject(uint8 sound)
m_sQueueSample.m_bRequireReflection = true;
emittingVolume = m_anRandomTable[2] % 30 + 60;
break;
+ case SCRIPT_SOUND_HIT_BALL:
+ m_sQueueSample.m_fSoundIntensity = 60.0f;
+ m_sQueueSample.m_nSampleIndex = SFX_HIT_BALL;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;
+ m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nFrequency += RandomDisplacement(m_sQueueSample.m_nFrequency / 16);
+ m_sQueueSample.m_nReleasingVolumeModificator = 5;
+ m_sQueueSample.m_fSpeedMultiplier = 0.0f;
+ m_sQueueSample.m_bIs2D = false;
+ m_sQueueSample.m_bRequireReflection = true;
+ emittingVolume = m_anRandomTable[2] % 30 + 60;
+ break;
case SCRIPT_SOUND_GUNSHELL_DROP:
playerPed = FindPlayerPed();
if (playerPed) {
@@ -8102,39 +8409,24 @@ cAudioManager::ProcessOneShotScriptObject(uint8 sound)
case SURFACE_SAND:
case SURFACE_RUBBER:
case SURFACE_HEDGE:
+ case SURFACE_SAND_BEACH:
m_sQueueSample.m_nSampleIndex = SFX_BULLET_SHELL_HIT_GROUND_2;
- m_sQueueSample.m_nFrequency = RandomDisplacement(500) + 11000;
+ m_sQueueSample.m_nFrequency = RandomDisplacement(600) + 10600;
m_sQueueSample.m_nReleasingVolumeModificator = 18;
- m_sQueueSample.m_fSoundIntensity = 20.0f;
- m_sQueueSample.m_nBankIndex = SFX_BANK_0;
- m_sQueueSample.m_fSpeedMultiplier = 0.0f;
- m_sQueueSample.m_bIs2D = false;
- emittingVolume = m_anRandomTable[2] % 20 + 30;
- distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos);
- if (distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) {
- m_sQueueSample.m_fDistance = Sqrt(distSquared);
- m_sQueueSample.m_nVolume = ComputeVolume(emittingVolume, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance);
- if (m_sQueueSample.m_nVolume != 0) {
- m_sQueueSample.m_nCounter = iSound++;
- m_sQueueSample.m_nLoopCount = 1;
- m_sQueueSample.m_bReleasingSoundFlag = true;
- m_sQueueSample.m_nEmittingVolume = emittingVolume;
- m_sQueueSample.m_nLoopStart = 0;
- m_sQueueSample.m_nLoopEnd = -1;
- m_sQueueSample.m_bReverbFlag = true;
- AddSampleToRequestedQueue();
- }
- }
- return;
+ break;
case SURFACE_WATER:
return;
default:
+ m_sQueueSample.m_nSampleIndex = SFX_BULLET_SHELL_HIT_GROUND_1;
+ m_sQueueSample.m_nFrequency = RandomDisplacement(1500) + 30000;
+ m_sQueueSample.m_nReleasingVolumeModificator = 15;
break;
}
+ } else {
+ m_sQueueSample.m_nSampleIndex = SFX_BULLET_SHELL_HIT_GROUND_1;
+ m_sQueueSample.m_nFrequency = RandomDisplacement(1500) + 30000;
+ m_sQueueSample.m_nReleasingVolumeModificator = 15;
}
- m_sQueueSample.m_nSampleIndex = SFX_BULLET_SHELL_HIT_GROUND_1;
- m_sQueueSample.m_nFrequency = RandomDisplacement(750) + 18000;
- m_sQueueSample.m_nReleasingVolumeModificator = 15;
m_sQueueSample.m_fSoundIntensity = 20.0f;
m_sQueueSample.m_nBankIndex = SFX_BANK_0;
m_sQueueSample.m_fSpeedMultiplier = 0.0f;
@@ -8178,116 +8470,204 @@ cAudioManager::ProcessLoopingScriptObject(uint8 sound)
uint8 emittingVolume;
float distSquared;
- switch (sound) {
- /*case SCRIPT_SOUND_PARTY_1_LOOP_S:
- m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_S;
- m_sQueueSample.m_nSampleIndex = SFX_CLUB_1;
- m_sQueueSample.m_nBankIndex = SFX_BANK_0;//SAMPLEBANK_BUILDING_CLUB_1;
- emittingVolume = MAX_VOLUME;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_1);
- m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ switch(sound) {
+ case SCRIPT_SOUND_BANK_ALARM_LOOP:
+ m_sQueueSample.m_fSoundIntensity = 80.0f;
+ m_sQueueSample.m_nSampleIndex = SFX_BUILDINGS_BANK_ALARM;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_BANK_ALARM;
+ emittingVolume = 90;
+ m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_BUILDINGS_BANK_ALARM);
+ m_sQueueSample.m_nReleasingVolumeModificator = 2;
m_sQueueSample.m_nReleasingVolumeDivider = 3;
m_sQueueSample.m_fSpeedMultiplier = 2.0f;
+ m_sQueueSample.m_bIs2D = false;
break;
- case SCRIPT_SOUND_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_0;//SAMPLEBANK_BUILDING_CLUB_1;
- emittingVolume = MAX_VOLUME;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_1);
+ case SCRIPT_SOUND_POLICE_CELL_DOOR_SLIDING_LOOP:
+ case SCRIPT_SOUND_GARAGE_DOOR_SLIDING_LOOP:
+ m_sQueueSample.m_fSoundIntensity = 80.0f;
+ m_sQueueSample.m_nSampleIndex = SFX_GARAGE_DOOR_LOOP;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;
+ emittingVolume = 90;
+ m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_GARAGE_DOOR_LOOP);
m_sQueueSample.m_nReleasingVolumeModificator = 3;
m_sQueueSample.m_nReleasingVolumeDivider = 3;
m_sQueueSample.m_fSpeedMultiplier = 2.0f;
+ m_sQueueSample.m_bIs2D = false;
break;
- case SCRIPT_SOUND_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_0;//SAMPLEBANK_BUILDING_CLUB_2;
- emittingVolume = MAX_VOLUME;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_2);
- m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ case SCRIPT_SOUND_SNORING_LOOP:
+ m_sQueueSample.m_fSoundIntensity = 6.0f;
+ m_sQueueSample.m_nSampleIndex = SFX_BUILDING_SNORE;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_SNORING;
+ emittingVolume = 25;
+ m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_BUILDING_SNORE);
+ m_sQueueSample.m_nReleasingVolumeModificator = 6;
m_sQueueSample.m_nReleasingVolumeDivider = 3;
- m_sQueueSample.m_fSpeedMultiplier = 2.0f;
+ m_sQueueSample.m_fSpeedMultiplier = 3.0f;
+ m_sQueueSample.m_bIs2D = false;
break;
- case SCRIPT_SOUND_PARTY_2_LOOP_L:
- m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_L;
- m_sQueueSample.m_nSampleIndex = SFX_CLUB_2;
- m_sQueueSample.m_nBankIndex = SFX_BANK_0;//SAMPLEBANK_BUILDING_CLUB_2;
- emittingVolume = MAX_VOLUME;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_2);
- m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ case SCRIPT_SOUND_SHOOTING_RANGE_TARGET_MOVING_LOOP:
+ m_sQueueSample.m_fSoundIntensity = 40.0f;
+ m_sQueueSample.m_nSampleIndex = SFX_TANK_TURRET;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_0;
+ emittingVolume = 60;
+ m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_TANK_TURRET);
+ m_sQueueSample.m_nReleasingVolumeModificator = 4;
m_sQueueSample.m_nReleasingVolumeDivider = 3;
m_sQueueSample.m_fSpeedMultiplier = 2.0f;
+ m_sQueueSample.m_bIs2D = false;
break;
- case SCRIPT_SOUND_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_0;//SAMPLEBANK_BUILDING_CLUB_3;
- emittingVolume = MAX_VOLUME;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_3);
+ case SCRIPT_SOUND_NEW_BUILDING_BAR_1:
+ m_sQueueSample.m_nSampleIndex = SFX_BUILDING_BAR_1;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_BAR_1;
+ m_sQueueSample.m_fSoundIntensity = 80.0f;
+ emittingVolume = 127;
+ m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex);
m_sQueueSample.m_nReleasingVolumeModificator = 3;
- m_sQueueSample.m_nReleasingVolumeDivider = 3;
- m_sQueueSample.m_fSpeedMultiplier = 2.0f;
+ m_sQueueSample.m_nReleasingVolumeDivider = 15;
+ m_sQueueSample.m_fSpeedMultiplier = 4.0f;
+ m_sQueueSample.m_bIs2D = false;
break;
- case SCRIPT_SOUND_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_0;//SAMPLEBANK_BUILDING_CLUB_3;
- emittingVolume = MAX_VOLUME;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_3);
+ case SCRIPT_SOUND_NEW_BUILDING_BAR_2:
+ m_sQueueSample.m_nSampleIndex = SFX_BUILDING_BAR_2;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_BAR_2;
+ m_sQueueSample.m_fSoundIntensity = 80.0f;
+ emittingVolume = 127;
+ m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex);
m_sQueueSample.m_nReleasingVolumeModificator = 3;
- m_sQueueSample.m_nReleasingVolumeDivider = 3;
- m_sQueueSample.m_fSpeedMultiplier = 2.0f;
+ m_sQueueSample.m_nReleasingVolumeDivider = 15;
+ m_sQueueSample.m_fSpeedMultiplier = 4.0f;
+ m_sQueueSample.m_bIs2D = false;
break;
- case SCRIPT_SOUND_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_0;//SAMPLEBANK_BUILDING_CLUB_4;
- emittingVolume = MAX_VOLUME;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_4);
+ case SCRIPT_SOUND_NEW_BUILDING_BAR_3:
+ m_sQueueSample.m_nSampleIndex = SFX_BUILDING_BAR_3;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_BAR_3;
+ m_sQueueSample.m_fSoundIntensity = 80.0f;
+ emittingVolume = 127;
+ m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex);
m_sQueueSample.m_nReleasingVolumeModificator = 3;
- m_sQueueSample.m_nReleasingVolumeDivider = 3;
- m_sQueueSample.m_fSpeedMultiplier = 2.0f;
+ m_sQueueSample.m_nReleasingVolumeDivider = 15;
+ m_sQueueSample.m_fSpeedMultiplier = 4.0f;
+ m_sQueueSample.m_bIs2D = false;
break;
- case SCRIPT_SOUND_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_0;//SAMPLEBANK_BUILDING_CLUB_4;
- emittingVolume = MAX_VOLUME;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_4);
+ case SCRIPT_SOUND_NEW_BUILDING_BAR_4:
+ m_sQueueSample.m_nSampleIndex = SFX_BUILDING_BAR_4;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_BAR_4;
+ m_sQueueSample.m_fSoundIntensity = 80.0f;
+ emittingVolume = 127;
+ m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex);
m_sQueueSample.m_nReleasingVolumeModificator = 3;
- m_sQueueSample.m_nReleasingVolumeDivider = 3;
- m_sQueueSample.m_fSpeedMultiplier = 2.0f;
+ m_sQueueSample.m_nReleasingVolumeDivider = 15;
+ m_sQueueSample.m_fSpeedMultiplier = 4.0f;
+ m_sQueueSample.m_bIs2D = false;
break;
- case SCRIPT_SOUND_PARTY_1_LOOP:
- m_sQueueSample.m_fSoundIntensity = SCRIPT_OBJECT_INTENSITY_L;
- m_sQueueSample.m_nSampleIndex = SFX_CLUB_1;
- m_sQueueSample.m_nBankIndex = SFX_BANK_0;//SAMPLEBANK_BUILDING_CLUB_1;
- emittingVolume = MAX_VOLUME;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CLUB_1);
+ case SCRIPT_SOUND_NEW_BUILDING_MALIBU_1:
+ if(MusicManager.m_nPlayingTrack == STREAMED_SOUND_MALIBU_AMBIENT) return;
+ m_sQueueSample.m_nSampleIndex = SFX_BUILDING_MAL1;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_MALIBU_1;
+ MusicManager.SetMalibuClubTrackPos(SCRIPT_SOUND_NEW_BUILDING_MALIBU_1);
+ m_sQueueSample.m_fSoundIntensity = 80.0f;
+ emittingVolume = 127;
+ m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex);
m_sQueueSample.m_nReleasingVolumeModificator = 3;
- m_sQueueSample.m_nReleasingVolumeDivider = 3;
- m_sQueueSample.m_fSpeedMultiplier = 2.0f;
+ m_sQueueSample.m_nReleasingVolumeDivider = 15;
+ m_sQueueSample.m_fSpeedMultiplier = 4.0f;
+ m_sQueueSample.m_bIs2D = false;
break;
- case SCRIPT_SOUND_PRETEND_FIRE_LOOP:
- m_sQueueSample.m_fSoundIntensity = 50.0f;
- m_sQueueSample.m_nSampleIndex = SFX_CAR_ON_FIRE;
+ case SCRIPT_SOUND_NEW_BUILDING_MALIBU_2:
+ if(MusicManager.m_nPlayingTrack == STREAMED_SOUND_MALIBU_AMBIENT) return;
+ m_sQueueSample.m_nSampleIndex = SFX_BUILDING_MAL2;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_MALIBU_2;
+ MusicManager.SetMalibuClubTrackPos(SCRIPT_SOUND_NEW_BUILDING_MALIBU_2);
+ m_sQueueSample.m_fSoundIntensity = 80.0f;
+ emittingVolume = 127;
+ m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_nReleasingVolumeDivider = 15;
+ m_sQueueSample.m_fSpeedMultiplier = 4.0f;
+ m_sQueueSample.m_bIs2D = false;
+ break;
+ case SCRIPT_SOUND_NEW_BUILDING_MALIBU_3:
+ if(MusicManager.m_nPlayingTrack == STREAMED_SOUND_MALIBU_AMBIENT) return;
+ m_sQueueSample.m_nSampleIndex = SFX_BUILDING_MAL3;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_MALIBU_3;
+ MusicManager.SetMalibuClubTrackPos(SCRIPT_SOUND_NEW_BUILDING_MALIBU_3);
+ m_sQueueSample.m_fSoundIntensity = 80.0f;
+ emittingVolume = 127;
+ m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_nReleasingVolumeDivider = 15;
+ m_sQueueSample.m_fSpeedMultiplier = 4.0f;
+ m_sQueueSample.m_bIs2D = false;
+ break;
+ case SCRIPT_SOUND_NEW_BUILDING_STRIP_1:
+ if(MusicManager.m_nPlayingTrack == STREAMED_SOUND_STRIPCLUB_AMBIENT) return;
+ m_sQueueSample.m_nSampleIndex = SFX_BUILDING_STR1;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_STRIP_1;
+ MusicManager.SetStripClubTrackPos(SCRIPT_SOUND_NEW_BUILDING_STRIP_1);
+ m_sQueueSample.m_fSoundIntensity = 80.0f;
+ emittingVolume = 127;
+ m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_nReleasingVolumeDivider = 15;
+ m_sQueueSample.m_fSpeedMultiplier = 4.0f;
+ m_sQueueSample.m_bIs2D = false;
+ break;
+ case SCRIPT_SOUND_NEW_BUILDING_STRIP_2:
+ if(MusicManager.m_nPlayingTrack == STREAMED_SOUND_STRIPCLUB_AMBIENT) return;
+ m_sQueueSample.m_nSampleIndex = SFX_BUILDING_STR2;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_STRIP_2;
+ MusicManager.SetStripClubTrackPos(SCRIPT_SOUND_NEW_BUILDING_STRIP_2);
+ m_sQueueSample.m_fSoundIntensity = 80.0f;
+ emittingVolume = 127;
+ m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_nReleasingVolumeDivider = 15;
+ m_sQueueSample.m_fSpeedMultiplier = 4.0f;
+ m_sQueueSample.m_bIs2D = false;
+ break;
+ case SCRIPT_SOUND_NEW_BUILDING_STRIP_3:
+ if(MusicManager.m_nPlayingTrack == STREAMED_SOUND_STRIPCLUB_AMBIENT) return;
+ m_sQueueSample.m_nSampleIndex = SFX_BUILDING_STR3;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_STRIP_3;
+ MusicManager.SetStripClubTrackPos(SCRIPT_SOUND_NEW_BUILDING_STRIP_3);
+ m_sQueueSample.m_fSoundIntensity = 80.0f;
+ emittingVolume = 127;
+ m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_nReleasingVolumeDivider = 15;
+ m_sQueueSample.m_fSpeedMultiplier = 4.0f;
+ m_sQueueSample.m_bIs2D = false;
+ break;
+ case SCRIPT_SOUND_NEW_BUILDING_CHURCH:
+ m_sQueueSample.m_nSampleIndex = SFX_BUILDING_CHURCH;
+ m_sQueueSample.m_nBankIndex = SFX_BANK_BUILDING_CHURCH;
+ m_sQueueSample.m_fSoundIntensity = 80.0f;
+ emittingVolume = 127;
+ m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(m_sQueueSample.m_nSampleIndex);
+ m_sQueueSample.m_nReleasingVolumeModificator = 3;
+ m_sQueueSample.m_nReleasingVolumeDivider = 15;
+ m_sQueueSample.m_fSpeedMultiplier = 4.0f;
+ m_sQueueSample.m_bIs2D = false;
+ break;
+ case SCRIPT_SOUND_NEW_WATERFALL:
+ emittingVolume = 30;
+ m_sQueueSample.m_fSoundIntensity = 80.0f;
+ m_sQueueSample.m_nSampleIndex = SFX_BOAT_WATER_LOOP;
m_sQueueSample.m_nBankIndex = SFX_BANK_0;
- emittingVolume = 80;
- m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_CAR_ON_FIRE);
- m_sQueueSample.m_nReleasingVolumeModificator = 8;
- m_sQueueSample.m_nReleasingVolumeDivider = 10;
+ m_sQueueSample.m_nFrequency = 20812;
+ m_sQueueSample.m_nReleasingVolumeModificator = 4;
+ m_sQueueSample.m_nReleasingVolumeDivider = 9;
m_sQueueSample.m_fSpeedMultiplier = 2.0f;
- break;*/
- default:
- return;
+ m_sQueueSample.m_bIs2D = false;
+ break;
+ default: return;
}
distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos);
- if (distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) {
+ if(distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) {
m_sQueueSample.m_fDistance = Sqrt(distSquared);
m_sQueueSample.m_nVolume = ComputeVolume(emittingVolume, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance);
- if (m_sQueueSample.m_nVolume != 0) {
+ if(m_sQueueSample.m_nVolume != 0) {
m_sQueueSample.m_nCounter = 0;
m_sQueueSample.m_bIs2D = false;
m_sQueueSample.m_nLoopCount = 0;
@@ -8369,7 +8749,7 @@ cAudioManager::ProcessWeather(int32 id)
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) {
+ if (wind > 0.0f && CObject::fDistToNearestTree < 75.0f) {
m_sQueueSample.m_nSampleIndex = SFX_PALM_TREE_LO;
m_sQueueSample.m_nFrequency = SampleManager.GetSampleBaseFrequency(SFX_PALM_TREE_LO);
m_sQueueSample.m_nVolume = (m_anRandomTable[1] % 10 + 45.0f) * (75.0f - CObject::fDistToNearestTree) * (4.0f / 300.0f) * wind;
@@ -8440,6 +8820,8 @@ cAudioManager::ProcessFrontEnd()
case SOUND_GARAGE_BOMB1_SET:
case SOUND_GARAGE_BOMB2_SET:
case SOUND_GARAGE_BOMB3_SET:
+ case SOUND_PICKUP_WEAPON_BOUGHT:
+ case SOUND_PICKUP_WEAPON:
center = true;
processedPickup = true;
m_sQueueSample.m_nSampleIndex = SFX_WEAPON_LEFT;
@@ -8707,7 +9089,7 @@ cAudioManager::ProcessProjectiles()
m_sQueueSample.m_vecPos = CProjectileInfo::ms_apProjectile[i]->GetPosition();
distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos);
if (distSquared < SQR(m_sQueueSample.m_fSoundIntensity)) {
- m_sQueueSample.m_fDistance = distSquared <= 0.0f ? 0.0f : Sqrt(distSquared);
+ m_sQueueSample.m_fDistance = Sqrt(distSquared);
m_sQueueSample.m_nVolume = ComputeVolume(emittingVol, m_sQueueSample.m_fSoundIntensity, m_sQueueSample.m_fDistance);
if (m_sQueueSample.m_nVolume != 0) {
m_sQueueSample.m_nCounter = i;
@@ -8732,7 +9114,7 @@ cAudioManager::ProcessGarages()
const float SOUND_INTENSITY = 80.0f;
CEntity *entity;
- eGarageState state;
+ uint8 state;
uint32 sampleIndex;
uint8 j;
float distSquared;
@@ -8856,7 +9238,7 @@ cAudioManager::ProcessFireHydrant()
const float SOUND_INTENSITY = 35;
float distSquared;
- bool distCalculated = 0;
+ bool distCalculated = false;
m_sQueueSample.m_vecPos = ((CEntity *)m_asAudioEntities[m_sQueueSample.m_nEntityIndex].m_pEntity)->GetPosition();
distSquared = GetDistanceSquared(m_sQueueSample.m_vecPos);
@@ -9653,7 +10035,7 @@ cAudioManager::ProcessMissionAudioSlot(uint8 slot)
}
break;
case LOADING_STATUS_FAILED:
- if (++nFramesUntilFailedLoad[slot] >= 90) {
+ if (++nFramesUntilFailedLoad[slot] >= 120) {
nFramesForPretendPlaying[slot] = 0;
g_bMissionAudioLoadFailed[slot] = true;
nFramesUntilFailedLoad[slot] = 0;
diff --git a/src/audio/AudioManager.cpp b/src/audio/AudioManager.cpp
index c9bd6c17..d441b750 100644
--- a/src/audio/AudioManager.cpp
+++ b/src/audio/AudioManager.cpp
@@ -20,7 +20,7 @@ const int allChannels = channels + 2;
cAudioManager::cAudioManager()
{
m_bIsInitialised = false;
- field_1 = 1;
+ m_bReverb = true;
m_fSpeedOfSound = 6.86f;
m_nTimeSpent = 50;
m_nActiveSamples = NUM_SOUNDS_SAMPLES_SLOTS;
@@ -128,7 +128,7 @@ cAudioManager::CreateEntity(eAudioType type, void *entity)
for (uint32 i = 0; i < ARRAY_SIZE(m_asAudioEntities); i++) {
if (!m_asAudioEntities[i].m_bIsUsed) {
m_asAudioEntities[i].m_bIsUsed = true;
- m_asAudioEntities[i].m_nStatus = 0;
+ m_asAudioEntities[i].m_bStatus = false;
m_asAudioEntities[i].m_nType = type;
m_asAudioEntities[i].m_pEntity = entity;
m_asAudioEntities[i].m_awAudioEvent[0] = SOUND_NO_SOUND;
@@ -163,11 +163,11 @@ void
cAudioManager::SetEntityStatus(int32 id, uint8 status)
{
if (m_bIsInitialised && id >= 0 && id < NUM_AUDIOENTITIES && m_asAudioEntities[id].m_bIsUsed)
- m_asAudioEntities[id].m_nStatus = status;
+ m_asAudioEntities[id].m_bStatus = status;
}
void
-cAudioManager::PlayOneShot(int32 index, int16 sound, float vol)
+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, 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,
@@ -426,7 +426,8 @@ cAudioManager::CheckForAnAudioFileOnCD() const
uint8
cAudioManager::GetCDAudioDriveLetter() const
{
- return SampleManager.GetCDAudioDriveLetter();
+ if(m_bIsInitialised) return SampleManager.GetCDAudioDriveLetter();
+ return 0;
}
bool
@@ -456,7 +457,7 @@ cAudioManager::ServiceSoundEffects()
ClearActiveSamples();
}
m_nActiveSampleQueue = m_nActiveSampleQueue == 1 ? 0 : 1;
- ProcessReverb();
+ if(m_bReverb) ProcessReverb();
ProcessSpecial();
ClearRequestedQueue();
InterrogateAudioEntities();
@@ -802,7 +803,7 @@ cAudioManager::AddReleasingSounds()
if (sample.m_nReleasingVolumeModificator < 20)
++sample.m_nReleasingVolumeModificator;
}
- sample.m_bReleasingSoundFlag = 0;
+ sample.m_bReleasingSoundFlag = false;
}
memcpy(&m_sQueueSample, &sample, sizeof(tSound));
AddSampleToRequestedQueue();
diff --git a/src/audio/AudioManager.h b/src/audio/AudioManager.h
index 35bb877c..376a7f60 100644
--- a/src/audio/AudioManager.h
+++ b/src/audio/AudioManager.h
@@ -49,7 +49,7 @@ public:
eAudioType m_nType;
void *m_pEntity;
bool m_bIsUsed;
- uint8 m_nStatus;
+ uint8 m_bStatus;
int16 m_awAudioEvent[NUM_AUDIOENTITY_EVENTS];
float m_afVolume[NUM_AUDIOENTITY_EVENTS];
uint8 m_AudioEvents;
@@ -144,21 +144,39 @@ public:
bool m_bDistanceCalculated;
float m_fDistance;
CPed *m_pPed;
+
+ cPedParams()
+ {
+ m_bDistanceCalculated = false;
+ m_fDistance = 0.0f;
+ m_pPed = nil;
+ }
};
class cVehicleParams
{
public:
- eVehicleType m_VehicleType;
+ int32 m_VehicleType;
bool m_bDistanceCalculated;
float m_fDistance;
CVehicle *m_pVehicle;
cTransmission *m_pTransmission;
int32 m_nIndex;
float m_fVelocityChange;
+
+ cVehicleParams()
+ {
+ m_VehicleType = -1;
+ m_bDistanceCalculated = false;
+ m_fDistance = 0.0f;
+ m_pVehicle = nil;
+ m_pTransmission = nil;
+ m_nIndex = 0;
+ m_fVelocityChange = 0.0f;
+ }
};
-VALIDATE_SIZE(cVehicleParams, 0x18);
+VALIDATE_SIZE(cVehicleParams, 0x1C);
enum {
REFLECTION_NORTH = 0,
@@ -176,7 +194,7 @@ class cAudioManager
{
public:
bool m_bIsInitialised;
- uint8 field_1; // unused
+ uint8 m_bReverb; // unused
bool m_bFifthFrameFlag;
uint8 m_nActiveSamples;
uint8 field_4; // unused
@@ -256,8 +274,8 @@ public:
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 DestroyAllGameCreatedEntities(); // done
+ void DestroyEntity(int32 id); // done (inlined in vc)
void DoPoliceRadioCrackle(); // done
// functions returning talk sfx,
@@ -359,38 +377,39 @@ public:
uint32 GetGenericFemaleTalkSfx(CPed *ped, int16 sound); // todo names (inlined in vc)
// end of functions returning talk sfx
- 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; // done (inlined in vc)
- int32 GetJumboTaxiFreq() const;
- uint8 GetMissionAudioLoadingStatus(uint8 slot) const; // done
- int8 GetMissionScriptPoliceAudioPlayingStatus() const;
- uint8 GetNum3DProvidersAvailable() const; // done
- uint32 GetPedCommentSfx(CPed *ped, int32 sound);
- void GetPhrase(uint32 &phrase, uint32 &prevPhrase, uint32 sample, uint32 maxOffset) const;
- float GetVehicleDriveWheelSkidValue(CVehicle* veh, tWheelState wheelState, float gasPedalAudio, cTransmission* transmission, float velocityChange); // done
- float GetVehicleNonDriveWheelSkidValue(CVehicle* veh, tWheelState wheelState, cTransmission* transmission, float velocityChange); // done
+ void GenerateIntegerRandomNumberTable(); // done
+ char *Get3DProviderName(uint8 id) const; // done
+ uint8 GetCDAudioDriveLetter() const; // done
+ int8 GetCurrent3DProviderIndex() const; // done
+ int8 AutoDetect3DProviders() const; // done
+ float GetCollisionLoopingRatio(uint32 a, uint32 b, float c) const; // not used
+ float GetCollisionOneShotRatio(int32 a, float b) const; // done
+ float GetCollisionRatio(float a, float b, float c, float d) const; // done (inlined in vc)
+ float GetDistanceSquared(const CVector &v) const; // done (inlined in vc)
+ int32 GetJumboTaxiFreq() const; // done (inlined in vc)
+ uint8 GetMissionAudioLoadingStatus(uint8 slot) const; // done
+ int8 GetMissionScriptPoliceAudioPlayingStatus() const; // done
+ uint8 GetNum3DProvidersAvailable() const; // done
+ uint32 GetPedCommentSfx(CPed *ped, int32 sound); // done
+ void GetPhrase(uint32 &phrase, uint32 &prevPhrase, uint32 sample, uint32 maxOffset) const; // done
+ 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
+ void Initialise(); // done
+ void InitialisePoliceRadio(); // done
+ void InitialisePoliceRadioZones(); // done
+ void InterrogateAudioEntities(); // done (inlined)
+ bool IsAudioInitialised() const; // done
bool IsMissionAudioSampleFinished(uint8 slot); // done
- bool IsMP3RadioChannelAvailable() const; // done
+ bool IsMP3RadioChannelAvailable() const; // done
bool MissionScriptAudioUsesPoliceChannel(int32 soundMission) const; //done
void PlayLoadedMissionAudio(uint8 slot); // done
- void PlayOneShot(int32 index, int16 sound, float vol); // 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
@@ -403,7 +422,7 @@ public:
void ProcessActiveQueues(); // done
bool ProcessAirBrakes(cVehicleParams& params); // done
bool ProcessBoatEngine(cVehicleParams& params);
- bool ProcessBoatMovingOverWater(cVehicleParams& params);
+ bool ProcessBoatMovingOverWater(cVehicleParams& params); //done
#ifdef GTA_BRIDGE
void ProcessBridge(); // done(bcs not exists in VC)
void ProcessBridgeMotor(); // done(bcs not exists in VC)
@@ -412,7 +431,7 @@ public:
#endif
bool ProcessCarBombTick(cVehicleParams& params); // done
void ProcessCarHeli(cVehicleParams& params); // done
- void ProcessCesna(cVehicleParams& params); //
+ void ProcessCesna(cVehicleParams& params); // done
//void ProcessCrane(); // done(bcs not exists in VC)
bool ProcessEngineDamage(cVehicleParams& params); // done
void ProcessEntity(int32 sound); // done
@@ -420,7 +439,7 @@ public:
void ProcessFireHydrant(); // done
void ProcessFires(int32 entity); // done
void ProcessFrontEnd(); // done
- void ProcessGarages(); //
+ void ProcessGarages(); // done
void ProcessJumbo(cVehicleParams& params); // done
void ProcessJumboAccel(CPlane *plane); // done
void ProcessJumboDecel(CPlane *plane); // done
@@ -428,14 +447,14 @@ public:
void ProcessJumboLanding(CPlane *plane); // done
void ProcessJumboTakeOff(CPlane *plane); // done
void ProcessJumboTaxi(); // done
- void ProcessLoopingScriptObject(uint8 sound); //
- void ProcessMissionAudio(); //
- void ProcessMissionAudioSlot(uint8 slot); //
+ void ProcessLoopingScriptObject(uint8 sound); // done
+ void ProcessMissionAudio(); // done
+ void ProcessMissionAudioSlot(uint8 slot); // done
void ProcessModelHeliVehicle(cVehicleParams& params); // done
void ProcessModelVehicle(cVehicleParams& params); // done
void ProcessOneShotScriptObject(uint8 sound); //
void ProcessPed(CPhysical *ped); // done
- void ProcessPedOneShots(cPedParams *params); //
+ void ProcessPedOneShots(cPedParams &params); //
void ProcessPhysical(int32 id); // done
void ProcessPlane(cVehicleParams& params); // done
void ProcessPlayerMood(); // done
@@ -450,15 +469,15 @@ public:
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
+ 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
@@ -474,52 +493,54 @@ public:
void ResetPoliceRadio(); // done
void ResetTimers(uint32 time); // done
- void Service(); //done
- void ServiceCollisions(); //done
- void ServicePoliceRadio();
- void ServicePoliceRadioChannel(uint8 wantedLevel);
- void ServiceSoundEffects();
- int8 SetCurrent3DProvider(uint8 which);
- void SetDynamicAcousticModelingStatus(uint8 status);
- void SetEffectsFadeVol(uint8 volume) const;
- void SetEffectsMasterVolume(uint8 volume) const;
- void SetMP3BoostVolume(uint8 volume) const;
- void SetEntityStatus(int32 id, uint8 status); //done
- uint32 SetLoopingCollisionRequestedSfxFreqAndGetVol(const cAudioCollision &audioCollision);
- void SetMissionAudioLocation(uint8 slot, float x, float y, float z);
- void SetMissionScriptPoliceAudio(int32 sfx) const;
- void SetMonoMode(uint8 mono);
- void SetMusicFadeVol(uint8 volume) const;
- void SetMusicMasterVolume(uint8 volume) const;
- void SetSpeakerConfig(int32 conf) const;
- void SetUpLoopingCollisionSound(const cAudioCollision &col, uint8 counter);
- void SetUpOneShotCollisionSound(const cAudioCollision &col);
- bool SetupCrimeReport();
- bool SetupJumboEngineSound(uint8 vol, uint32 freq);
- bool SetupJumboFlySound(uint8 emittingVol);
- bool SetupJumboRumbleSound(uint8 emittingVol);
- bool SetupJumboTaxiSound(uint8 vol);
- bool SetupJumboWhineSound(uint8 emittingVol, uint32 freq);
- void SetupPedComments(cPedParams *params, uint32 sound); // done
+ void Service(); // done
+ void ServiceCollisions(); // done
+ void ServicePoliceRadio(); // done
+ void ServicePoliceRadioChannel(uint8 wantedLevel); // done
+ void ServiceSoundEffects(); // done
+ int8 SetCurrent3DProvider(uint8 which); // done
+ void SetDynamicAcousticModelingStatus(uint8 status); // done
+ void SetEffectsFadeVol(uint8 volume) const; // done
+ void SetEffectsMasterVolume(uint8 volume) const; // done
+ void SetMP3BoostVolume(uint8 volume) const; // done
+ void SetEntityStatus(int32 id, uint8 status); // done
+ uint32 SetLoopingCollisionRequestedSfxFreqAndGetVol(const cAudioCollision &audioCollision); // done
+ void SetMissionAudioLocation(uint8 slot, float x, float y, float z); // done
+ void SetMissionScriptPoliceAudio(int32 sfx) const; // inlined and optimized
+ void SetMonoMode(uint8 mono); // done
+ void SetMusicFadeVol(uint8 volume) const; // done
+ void SetMusicMasterVolume(uint8 volume) const; // done
+ void SetSpeakerConfig(int32 conf) const; // done
+ void SetUpLoopingCollisionSound(const cAudioCollision &col, uint8 counter); // done
+ void SetUpOneShotCollisionSound(const cAudioCollision &col); // done
+ bool SetupCrimeReport(); // done
+ bool SetupJumboEngineSound(uint8 vol, uint32 freq); // done
+ bool SetupJumboFlySound(uint8 emittingVol); // done
+ bool SetupJumboRumbleSound(uint8 emittingVol); // done
+ bool SetupJumboTaxiSound(uint8 vol); // done
+ bool SetupJumboWhineSound(uint8 emittingVol, uint32 freq); // done
+ void SetupPedComments(cPedParams &params, uint16 sound); // done
void SetupSuspectLastSeenReport();
- void Terminate(); //done
- void TranslateEntity(Const CVector *v1, CVector *v2) const; //done
+ 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(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
+ CVehicle *FindVehicleOfPlayer(); // done
+ void SetPedTalkingStatus(CPed *ped, uint8 status); // done
+ void SetPlayersMood(uint8 mood, uint32 time); // done
- CVehicle *FindVehicleOfPlayer(); //done
- void SetPedTalkingStatus(CPed *ped, uint8 status);
- void SetPlayersMood(uint8 mood, uint32 time);
+ float Sqrt(float v) const { return v <= 0.0f ? 0.0f : ::Sqrt(v); }
#ifdef GTA_PC
// only used in pc
- void AdjustSamplesVolume();
- uint8 ComputeEmittingVolume(uint8 emittingVolume, float intensity, float dist);
+ void AdjustSamplesVolume(); // done (inlined)
+ uint8 ComputeEmittingVolume(uint8 emittingVolume, float intensity, float dist); // done (inlined)
#endif
};
diff --git a/src/audio/AudioSamples.h b/src/audio/AudioSamples.h
index 703431a5..a68cf768 100644
--- a/src/audio/AudioSamples.h
+++ b/src/audio/AudioSamples.h
@@ -2,7 +2,8 @@
#include "common.h"
-enum eSfxSample : uint32 {
+enum eSfxSample
+{
SFX_CAR_HORN_JEEP = 0,
SFX_CAR_HORN_BMW328,
SFX_CAR_HORN_BUS,
diff --git a/src/audio/MusicManager.cpp b/src/audio/MusicManager.cpp
index 8aedf306..c4abf351 100644
--- a/src/audio/MusicManager.cpp
+++ b/src/audio/MusicManager.cpp
@@ -223,8 +223,8 @@ void
cMusicManager::SetRadioChannelByScript(uint32 station, int32 pos)
{
if (m_bIsInitialised) {
- if (station == USERTRACK)
- station = RADIO_OFF;
+ if (station == STREAMED_SOUND_RADIO_MP3_PLAYER)
+ station = STREAMED_SOUND_CITY_AMBIENT;
if (station <= STREAMED_SOUND_RADIO_POLICE) {
m_bRadioSetByScript = true;
m_nRadioStation = station;
@@ -512,7 +512,7 @@ cMusicManager::ServiceGameMode()
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) {
+ if(!ped->DyingOrDead()) {
#ifdef GTA_PC
if (SampleManager.IsMP3RadioChannelAvailable()
&& vehicle->m_nRadioStation < USERTRACK
@@ -564,8 +564,8 @@ cMusicManager::ServiceGameMode()
gRetuneCounter = 0;
return;
}
- if (m_nAnnouncement == NO_TRACK)
- {
+ if(m_nAnnouncement == NO_TRACK) {
+ m_nStreamedTrack = NO_TRACK;
m_nFrontendTrack = GetCarTuning();
field_2 = false;
gRetuneCounter = 0;
diff --git a/src/audio/PoliceRadio.cpp b/src/audio/PoliceRadio.cpp
index 781040d6..30fcbde0 100644
--- a/src/audio/PoliceRadio.cpp
+++ b/src/audio/PoliceRadio.cpp
@@ -67,7 +67,7 @@ cAudioManager::InitialisePoliceRadio()
for (int32 i = 0; i < ARRAY_SIZE(m_sPoliceRadioQueue.crimes); i++)
m_sPoliceRadioQueue.crimes[i].type = CRIME_NONE;
- SampleManager.SetChannelReverbFlag(policeChannel, 0);
+ SampleManager.SetChannelReverbFlag(policeChannel, false);
gSpecialSuspectLastSeenReport = false;
for (int32 i = 0; i < ARRAY_SIZE(gMinTimeToNextReport); i++)
gMinTimeToNextReport[i] = m_FrameCounter;
diff --git a/src/audio/audio_enums.h b/src/audio/audio_enums.h
index 65094555..91fcec49 100644
--- a/src/audio/audio_enums.h
+++ b/src/audio/audio_enums.h
@@ -1274,7 +1274,7 @@ enum AudioEntityHandle {
AEHANDLE_ERROR_BADAUDIOTYPE = -1,
};
-enum eAudioType : int32
+enum eAudioType
{
AUDIOTYPE_PHYSICAL = 0,
AUDIOTYPE_EXPLOSION,
diff --git a/src/audio/oal/oal_utils.cpp b/src/audio/oal/oal_utils.cpp
index e16de572..e4cb0b77 100644
--- a/src/audio/oal/oal_utils.cpp
+++ b/src/audio/oal/oal_utils.cpp
@@ -3,6 +3,14 @@
#ifdef AUDIO_OAL
+/*
+ * When linking to a static openal-soft library,
+ * the extension function inside the openal library conflict with the variables here.
+ * Therefore declare these re3 owned symbols in a private namespace.
+ */
+
+namespace re3_openal {
+
LPALGENEFFECTS alGenEffects;
LPALDELETEEFFECTS alDeleteEffects;
LPALISEFFECT alIsEffect;
@@ -37,6 +45,9 @@ LPALGETFILTERIV alGetFilteriv;
LPALGETFILTERF alGetFilterf;
LPALGETFILTERFV alGetFilterfv;
+}
+
+using namespace re3_openal;
void EFXInit()
{
diff --git a/src/audio/oal/oal_utils.h b/src/audio/oal/oal_utils.h
index b89ccf36..f0fa090a 100644
--- a/src/audio/oal/oal_utils.h
+++ b/src/audio/oal/oal_utils.h
@@ -11,6 +11,8 @@ void EFX_Set(ALuint effect, const EAXLISTENERPROPERTIES *props);
void EAX3_SetReverbMix(ALuint filter, float mix);
void SetEffectsLevel(ALuint uiFilter, float level);
+namespace re3_openal {
+
extern LPALGENEFFECTS alGenEffects;
extern LPALDELETEEFFECTS alDeleteEffects;
extern LPALISEFFECT alIsEffect;
@@ -44,4 +46,9 @@ extern LPALGETFILTERI alGetFilteri;
extern LPALGETFILTERIV alGetFilteriv;
extern LPALGETFILTERF alGetFilterf;
extern LPALGETFILTERFV alGetFilterfv;
+
+}
+
+using namespace re3_openal;
+
#endif
diff --git a/src/audio/oal/stream.cpp b/src/audio/oal/stream.cpp
index 06a38c29..3a1f748f 100644
--- a/src/audio/oal/stream.cpp
+++ b/src/audio/oal/stream.cpp
@@ -10,13 +10,15 @@
#ifdef _WIN32
#pragma comment( lib, "libsndfile-1.lib" )
#pragma comment( lib, "libmpg123-0.lib" )
-#else
-#include "crossplatform.h"
#endif
#include <sndfile.h>
#include <mpg123.h>
#endif
+#ifndef _WIN32
+#include "crossplatform.h"
+#endif
+
#ifndef AUDIO_OPUS
class CSndFile : public IDecoder
{
diff --git a/src/audio/sampman_miles.cpp b/src/audio/sampman_miles.cpp
index f7c4d7a6..2a4286eb 100644
--- a/src/audio/sampman_miles.cpp
+++ b/src/audio/sampman_miles.cpp
@@ -1380,7 +1380,7 @@ cSampleManager::Terminate(void)
bool
cSampleManager::CheckForAnAudioFileOnCD(void)
{
-#if !defined(GTA3_STEAM_PATCH) && !defined(NO_CDCHECK)
+#if !defined(NO_CDCHECK) // TODO: check steam, probably GTAVC_STEAM_PATCH needs to be added
char filepath[MAX_PATH];
strcpy(filepath, m_MiscomPath);
@@ -1406,7 +1406,7 @@ cSampleManager::CheckForAnAudioFileOnCD(void)
#else
return true;
-#endif // #if !defined(GTA3_STEAM_PATCH) && !defined(NO_CDCHECK)
+#endif // #if !defined(NO_CDCHECK)
}
char
diff --git a/src/audio/soundlist.h b/src/audio/soundlist.h
index ba2c8bec..98982f61 100644
--- a/src/audio/soundlist.h
+++ b/src/audio/soundlist.h
@@ -1,6 +1,6 @@
#pragma once
-enum eSound : uint16
+enum eSound
{
SOUND_CAR_DOOR_CLOSE_BONNET = 0,
SOUND_CAR_DOOR_CLOSE_BUMPER,
@@ -201,14 +201,14 @@ enum eSound : uint16
SOUND_FRONTEND_AUDIO_TEST,
SOUND_INJURED_PED_MALE_OUCH,
SOUND_INJURED_PED_FEMALE,
- SOUND_SET_202,
+ SOUND_SHIRT_WIND_FLAP,
SOUND_SET_203,
SOUND_TOTAL_SOUNDS = 204,
SOUND_NO_SOUND = 205,
};
-enum eScriptSounds : uint16 {
+enum eScriptSounds {
SCRIPT_SOUND_BANK_ALARM_LOOP = 0,
SCRIPT_SOUND_PART_MISSION_COMPLETE,
SCRIPT_SOUND_POLICE_CELL_DOOR_SLIDING_LOOP,
diff --git a/src/entities/Building.cpp b/src/buildings/Building.cpp
index 921055ce..8035cf25 100644
--- a/src/entities/Building.cpp
+++ b/src/buildings/Building.cpp
@@ -27,14 +27,14 @@ IsBuildingPointerValid(CBuilding* pBuilding)
if (!pBuilding)
return false;
if (pBuilding->GetIsATreadable()) {
- int index = CPools::GetTreadablePool()->GetJustIndex((CTreadable*)pBuilding);
+ 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(pBuilding);
+ int index = CPools::GetBuildingPool()->GetJustIndex_NoFreeAssert(pBuilding);
#ifdef FIX_BUGS
return index >= 0 && index < CPools::GetBuildingPool()->GetSize();
#else
diff --git a/src/entities/Building.h b/src/buildings/Building.h
index 2c2dfb1f..2c2dfb1f 100644
--- a/src/entities/Building.h
+++ b/src/buildings/Building.h
diff --git a/src/entities/Solid.h b/src/buildings/Solid.h
index 4ca800c2..4ca800c2 100644
--- a/src/entities/Solid.h
+++ b/src/buildings/Solid.h
diff --git a/src/entities/Treadable.cpp b/src/buildings/Treadable.cpp
index 00abbe13..00abbe13 100644
--- a/src/entities/Treadable.cpp
+++ b/src/buildings/Treadable.cpp
diff --git a/src/entities/Treadable.h b/src/buildings/Treadable.h
index c3ab755e..c3ab755e 100644
--- a/src/entities/Treadable.h
+++ b/src/buildings/Treadable.h
diff --git a/src/collision/ColModel.cpp b/src/collision/ColModel.cpp
index ba33c134..d2e01f50 100644
--- a/src/collision/ColModel.cpp
+++ b/src/collision/ColModel.cpp
@@ -2,6 +2,7 @@
#include "ColModel.h"
#include "Collision.h"
#include "Game.h"
+#include "MemoryHeap.h"
#include "Pools.h"
CColModel::CColModel(void)
@@ -65,10 +66,15 @@ CColModel::RemoveCollisionVolumes(void)
void
CColModel::CalculateTrianglePlanes(void)
{
+ PUSH_MEMID(MEMID_COLLISION);
+
// HACK: allocate space for one more element to stuff the link pointer into
trianglePlanes = (CColTrianglePlane*)RwMalloc(sizeof(CColTrianglePlane) * (numTriangles+1));
+ REGISTER_MEMPTR(&trianglePlanes);
for(int i = 0; i < numTriangles; i++)
trianglePlanes[i].Set(vertices, triangles[i]);
+
+ POP_MEMID();
}
void
@@ -198,4 +204,4 @@ CColModel::operator=(const CColModel &other)
vertices = nil;
}
return *this;
-} \ No newline at end of file
+}
diff --git a/src/core/ColStore.cpp b/src/collision/ColStore.cpp
index bca1e9b7..192c373d 100644
--- a/src/core/ColStore.cpp
+++ b/src/collision/ColStore.cpp
@@ -173,7 +173,7 @@ CColStore::LoadCollision(const CVector2D &pos)
if(GetBoundingBox(i).IsPointInside(pos) ||
bLoadAtSecondPosition && GetBoundingBox(i).IsPointInside(secondPosition, -119.0f) ||
- CGeneral::faststrcmp(GetColName(i), "yacht") == 0){
+ strcmp(GetColName(i), "yacht") == 0){
wantThisOne = true;
}else{
for (int j = 0; j < MAX_CLEANUP; j++) {
diff --git a/src/core/ColStore.h b/src/collision/ColStore.h
index 8e2a3a70..8e2a3a70 100644
--- a/src/core/ColStore.h
+++ b/src/collision/ColStore.h
diff --git a/src/collision/Collision.cpp b/src/collision/Collision.cpp
index 20778345..c90390c4 100644
--- a/src/collision/Collision.cpp
+++ b/src/collision/Collision.cpp
@@ -499,7 +499,7 @@ CCollision::TestLineOfSight(const CColLine &line, const CMatrix &matrix, CColMod
// transform line to model space
Invert(matrix, matTransform);
CVuVector newline[2];
- TransformPoints(newline, 2, matTransform, (RwV3d*)&line.p0, sizeof(CColLine)/2);
+ TransformPoints(newline, 2, matTransform, &line.p0, sizeof(CColLine)/2);
// If we don't intersect with the bounding box, no chance on the rest
if(!TestLineBox(*(CColLine*)newline, model.boundingBox))
@@ -1321,7 +1321,7 @@ CCollision::ProcessLineOfSight(const CColLine &line,
// transform line to model space
Invert(matrix, matTransform);
CVuVector newline[2];
- TransformPoints(newline, 2, matTransform, (RwV3d*)&line.p0, sizeof(CColLine)/2);
+ TransformPoints(newline, 2, matTransform, &line.p0, sizeof(CColLine)/2);
if(mindist < 1.0f)
newline[1] = newline[0] + (newline[1] - newline[0])*mindist;
@@ -1456,7 +1456,7 @@ CCollision::ProcessVerticalLine(const CColLine &line,
// transform line to model space
Invert(matrix, matTransform);
CVuVector newline[2];
- TransformPoints(newline, 2, matTransform, (RwV3d*)&line.p0, sizeof(CColLine)/2);
+ TransformPoints(newline, 2, matTransform, &line.p0, sizeof(CColLine)/2);
if(mindist < 1.0f)
newline[1] = newline[0] + (newline[1] - newline[0])*mindist;
@@ -1655,16 +1655,16 @@ CCollision::ProcessColModels(const CMatrix &matrixA, CColModel &modelA,
matAB *= matrixA;
CVuVector bsphereAB; // bounding sphere of A in B space
- TransformPoint(bsphereAB, matAB, *(RwV3d*)modelA.boundingSphere.center); // inlined
+ TransformPoint(bsphereAB, matAB, modelA.boundingSphere.center); // inlined
bsphereAB.w = modelA.boundingSphere.radius;
if(!TestSphereBox(*(CColSphere*)&bsphereAB, modelB.boundingBox))
return 0;
// transform modelA's spheres and lines to B space
- TransformPoints(aSpheresA, modelA.numSpheres, matAB, (RwV3d*)&modelA.spheres->center, sizeof(CColSphere));
+ TransformPoints(aSpheresA, modelA.numSpheres, matAB, &modelA.spheres->center, sizeof(CColSphere));
for(i = 0; i < modelA.numSpheres; i++)
aSpheresA[i].w = modelA.spheres[i].radius;
- TransformPoints(aLinesA, modelA.numLines*2, matAB, (RwV3d*)&modelA.lines->p0, sizeof(CColLine)/2);
+ TransformPoints(aLinesA, modelA.numLines*2, matAB, &modelA.lines->p0, sizeof(CColLine)/2);
// Test them against model B's bounding volumes
int numSpheresA = 0;
@@ -1681,7 +1681,7 @@ CCollision::ProcessColModels(const CMatrix &matrixA, CColModel &modelA,
matBA *= matrixB;
// transform modelB's spheres to A space
- TransformPoints(aSpheresB, modelB.numSpheres, matBA, (RwV3d*)&modelB.spheres->center, sizeof(CColSphere));
+ TransformPoints(aSpheresB, modelB.numSpheres, matBA, &modelB.spheres->center, sizeof(CColSphere));
for(i = 0; i < modelB.numSpheres; i++)
aSpheresB[i].w = modelB.spheres[i].radius;
diff --git a/src/collision/TempColModels.cpp b/src/collision/TempColModels.cpp
index e7ba54f1..f8b26450 100644
--- a/src/collision/TempColModels.cpp
+++ b/src/collision/TempColModels.cpp
@@ -41,7 +41,7 @@ CTempColModels::Initialise(void)
colmodel.numSpheres = ARRAY_SIZE(sphrs);\
colmodel.spheres = sphrs;\
colmodel.level = LEVEL_GENERIC;\
- colmodel.ownsCollisionVolumes = false;\
+ colmodel.ownsCollisionVolumes = false;
int i;
diff --git a/src/control/AutoPilot.cpp b/src/control/AutoPilot.cpp
index 1b14e3d7..a899518b 100644
--- a/src/control/AutoPilot.cpp
+++ b/src/control/AutoPilot.cpp
@@ -109,9 +109,9 @@ void CAutoPilot::Load(uint8*& buf)
m_nNextDirection = ReadSaveBuf<int8>(buf);
m_nCurrentLane = ReadSaveBuf<int8>(buf);
m_nNextLane = ReadSaveBuf<int8>(buf);
- m_nDrivingStyle = (eCarDrivingStyle)ReadSaveBuf<uint8>(buf);
- m_nCarMission = (eCarMission)ReadSaveBuf<uint8>(buf);
- m_nTempAction = (eCarTempAction)ReadSaveBuf<uint8>(buf);
+ m_nDrivingStyle = ReadSaveBuf<uint8>(buf);
+ m_nCarMission = ReadSaveBuf<uint8>(buf);
+ m_nTempAction = ReadSaveBuf<uint8>(buf);
m_nTimeTempAction = ReadSaveBuf<uint32>(buf);
m_fMaxTrafficSpeed = ReadSaveBuf<float>(buf);
m_nCruiseSpeed = ReadSaveBuf<uint8>(buf);
diff --git a/src/control/AutoPilot.h b/src/control/AutoPilot.h
index 25feb72d..aa14ccdd 100644
--- a/src/control/AutoPilot.h
+++ b/src/control/AutoPilot.h
@@ -4,7 +4,7 @@
class CVehicle;
struct CPathNode;
-enum eCarMission : uint8
+enum eCarMission
{
MISSION_NONE,
MISSION_CRUISE,
@@ -35,7 +35,7 @@ enum eCarMission : uint8
MISSION_BLOCKPLAYER_FORWARDANDBACK
};
-enum eCarTempAction : uint8
+enum eCarTempAction
{
TEMPACT_NONE,
TEMPACT_WAIT,
@@ -50,7 +50,7 @@ enum eCarTempAction : uint8
TEMPACT_SWERVERIGHT
};
-enum eCarDrivingStyle : uint8
+enum eCarDrivingStyle
{
DRIVINGSTYLE_STOP_FOR_CARS,
DRIVINGSTYLE_SLOW_DOWN_FOR_CARS,
@@ -76,9 +76,9 @@ public:
int8 m_nNextDirection;
int8 m_nCurrentLane;
int8 m_nNextLane;
- eCarDrivingStyle m_nDrivingStyle;
- eCarMission m_nCarMission;
- eCarTempAction m_nTempAction;
+ uint8 m_nDrivingStyle;
+ uint8 m_nCarMission;
+ uint8 m_nTempAction;
uint32 m_nTimeTempAction;
float m_fMaxTrafficSpeed;
uint8 m_nCruiseSpeed;
diff --git a/src/control/CarAI.cpp b/src/control/CarAI.cpp
index c8e80c32..ed7f432e 100644
--- a/src/control/CarAI.cpp
+++ b/src/control/CarAI.cpp
@@ -647,7 +647,7 @@ void CCarAI::TellCarToBlockOtherCar(CVehicle* pVehicle, CVehicle* pTarget)
pVehicle->AutoPilot.m_nCruiseSpeed = Max(6, pVehicle->AutoPilot.m_nCruiseSpeed);
}
-eCarMission CCarAI::FindPoliceCarMissionForWantedLevel()
+uint8 CCarAI::FindPoliceCarMissionForWantedLevel()
{
switch (CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_pWanted->m_nWantedLevel){
case 0:
@@ -661,7 +661,7 @@ eCarMission CCarAI::FindPoliceCarMissionForWantedLevel()
}
}
-eCarMission CCarAI::FindPoliceBoatMissionForWantedLevel()
+uint8 CCarAI::FindPoliceBoatMissionForWantedLevel()
{
switch (CWorld::Players[CWorld::PlayerInFocus].m_pPed->m_pWanted->m_nWantedLevel) {
case 0:
diff --git a/src/control/CarAI.h b/src/control/CarAI.h
index d4af1806..dcd76d78 100644
--- a/src/control/CarAI.h
+++ b/src/control/CarAI.h
@@ -22,8 +22,8 @@ public:
static void TellOccupantsToFleeCar(CVehicle*);
static void TellCarToRamOtherCar(CVehicle*, CVehicle*);
static void TellCarToBlockOtherCar(CVehicle*, CVehicle*);
- static eCarMission FindPoliceCarMissionForWantedLevel();
- static eCarMission FindPoliceBoatMissionForWantedLevel();
+ static uint8 FindPoliceCarMissionForWantedLevel();
+ static uint8 FindPoliceBoatMissionForWantedLevel();
static int32 FindPoliceCarSpeedForWantedLevel(CVehicle*);
static void MellowOutChaseSpeed(CVehicle*);
static void MellowOutChaseSpeedBoat(CVehicle*);
diff --git a/src/control/CarCtrl.cpp b/src/control/CarCtrl.cpp
index a6ddf24f..056c7713 100644
--- a/src/control/CarCtrl.cpp
+++ b/src/control/CarCtrl.cpp
@@ -464,6 +464,11 @@ CCarCtrl::GenerateOneRandomCar()
pVehicle->GetRight() = CVector(forwardY, -forwardX, 0.0f);
pVehicle->GetUp() = CVector(0.0f, 0.0f, 1.0f);
+ float currentPathLinkForwardX = pVehicle->AutoPilot.m_nCurrentDirection * ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nCurrentPathNodeInfo].GetDirX();
+ float currentPathLinkForwardY = pVehicle->AutoPilot.m_nCurrentDirection * ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nCurrentPathNodeInfo].GetDirY();
+ float nextPathLinkForwardX = pVehicle->AutoPilot.m_nNextDirection * ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nNextPathNodeInfo].GetDirX();
+ float nextPathLinkForwardY = pVehicle->AutoPilot.m_nNextDirection * ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nNextPathNodeInfo].GetDirY();
+
#ifdef FIX_BUGS
CCarPathLink* pCurrentLink;
CCarPathLink* pNextLink;
@@ -474,11 +479,6 @@ CCarCtrl::GenerateOneRandomCar()
float directionNextLinkX;
float directionNextLinkY;
if (positionBetweenNodes < 0.5f) {
- float currentPathLinkForwardX = pVehicle->AutoPilot.m_nCurrentDirection * ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nCurrentPathNodeInfo].GetDirX();
- float currentPathLinkForwardY = pVehicle->AutoPilot.m_nCurrentDirection * ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nCurrentPathNodeInfo].GetDirY();
- float nextPathLinkForwardX = pVehicle->AutoPilot.m_nNextDirection * ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nNextPathNodeInfo].GetDirX();
- float nextPathLinkForwardY = pVehicle->AutoPilot.m_nNextDirection * ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nNextPathNodeInfo].GetDirY();
-
pCurrentLink = &ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nCurrentPathNodeInfo];
pNextLink = &ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nNextPathNodeInfo];
positionOnCurrentLinkIncludingLane = CVector(
@@ -508,11 +508,6 @@ CCarCtrl::GenerateOneRandomCar()
pVehicle->AutoPilot.m_nTimeEnteredCurve = CTimer::GetTimeInMilliseconds() -
(uint32)((positionBetweenNodes - 0.5f) * pVehicle->AutoPilot.m_nTimeToSpendOnCurrentCurve);
- float currentPathLinkForwardX = pVehicle->AutoPilot.m_nCurrentDirection * ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nCurrentPathNodeInfo].GetDirX();
- float currentPathLinkForwardY = pVehicle->AutoPilot.m_nCurrentDirection * ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nCurrentPathNodeInfo].GetDirY();
- float nextPathLinkForwardX = pVehicle->AutoPilot.m_nNextDirection * ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nNextPathNodeInfo].GetDirX();
- float nextPathLinkForwardY = pVehicle->AutoPilot.m_nNextDirection * ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nNextPathNodeInfo].GetDirY();
-
pCurrentLink = &ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nCurrentPathNodeInfo];
pNextLink = &ThePaths.m_carPathLinks[pVehicle->AutoPilot.m_nNextPathNodeInfo];
positionOnCurrentLinkIncludingLane = CVector(
@@ -1917,7 +1912,6 @@ void CCarCtrl::PickNextNodeRandomly(CVehicle* pVehicle)
}
if (pVehicle->AutoPilot.m_bStayInFastLane)
pVehicle->AutoPilot.m_nNextLane = 0;
-#ifdef FIX_BUGS
CVector positionOnCurrentLinkIncludingLane(
pCurLink->GetX() + ((pVehicle->AutoPilot.m_nCurrentLane + pCurLink->OneWayLaneOffset()) * LANE_WIDTH)
#ifdef FIX_BUGS
@@ -1932,16 +1926,6 @@ void CCarCtrl::PickNextNodeRandomly(CVehicle* pVehicle)
#endif
,pNextLink->GetY() - ((pVehicle->AutoPilot.m_nNextLane + pNextLink->OneWayLaneOffset()) * LANE_WIDTH) * nextPathLinkForwardX,
0.0f);
-#else
- CVector positionOnCurrentLinkIncludingLane(
- pCurLink->GetX() + ((pVehicle->AutoPilot.m_nCurrentLane + pCurLink->OneWayLaneOffset()) * LANE_WIDTH),
- pCurLink->GetY() - ((pVehicle->AutoPilot.m_nCurrentLane + pCurLink->OneWayLaneOffset()) * LANE_WIDTH) * currentPathLinkForwardX,
- 0.0f);
- CVector positionOnNextLinkIncludingLane(
- pNextLink->GetX() + ((pVehicle->AutoPilot.m_nNextLane + pNextLink->OneWayLaneOffset()) * LANE_WIDTH) * nextPathLinkForwardY,
- pNextLink->GetY() - ((pVehicle->AutoPilot.m_nNextLane + pNextLink->OneWayLaneOffset()) * LANE_WIDTH) * nextPathLinkForwardX,
- 0.0f);
-#endif
float directionCurrentLinkX = pCurLink->GetDirX() * pVehicle->AutoPilot.m_nCurrentDirection;
float directionCurrentLinkY = pCurLink->GetDirY() * pVehicle->AutoPilot.m_nCurrentDirection;
float directionNextLinkX = pNextLink->GetDirX() * pVehicle->AutoPilot.m_nNextDirection;
@@ -2898,7 +2882,13 @@ void CCarCtrl::SteerAICarWithPhysicsFollowPath(CVehicle* pVehicle, float* pSwerv
case DRIVINGSTYLE_STOP_FOR_CARS:
case DRIVINGSTYLE_SLOW_DOWN_FOR_CARS:
case DRIVINGSTYLE_STOP_FOR_CARS_IGNORE_LIGHTS:
- speedStyleMultiplier = FindMaximumSpeedForThisCarInTraffic(pVehicle) / pVehicle->AutoPilot.m_nCruiseSpeed;
+ speedStyleMultiplier = FindMaximumSpeedForThisCarInTraffic(pVehicle);
+#ifdef FIX_BUGS
+ if (pVehicle->AutoPilot.GetCruiseSpeed() != 0)
+ speedStyleMultiplier /= pVehicle->AutoPilot.GetCruiseSpeed();
+#else
+ speedStyleMultiplier /= pVehicle->AutoPilot.m_nCruiseSpeed;
+#endif
break;
default:
speedStyleMultiplier = 1.0f;
@@ -3242,7 +3232,7 @@ void CCarCtrl::GenerateEmergencyServicesCar(void)
float distance = 30.0f;
CFire* pNearestFire = gFireManager.FindNearestFire(FindPlayerCoors(), &distance);
if (pNearestFire) {
- if (CountCarsOfType(MI_FIRETRUCK) < 2 && CTimer::GetTimeInMilliseconds() > LastTimeFireTruckCreated + 30000){
+ if (CountCarsOfType(MI_FIRETRUCK) < 2 && CTimer::GetTimeInMilliseconds() > LastTimeFireTruckCreated + 35000){
CStreaming::RequestModel(MI_FIRETRUCK, STREAMFLAGS_DEPENDENCY);
CStreaming::RequestModel(MI_FIREMAN, STREAMFLAGS_DONT_REMOVE);
if (CStreaming::HasModelLoaded(MI_FIRETRUCK) && CStreaming::HasModelLoaded(MI_FIREMAN)){
diff --git a/src/control/Darkel.cpp b/src/control/Darkel.cpp
index 1356638f..722ebbcd 100644
--- a/src/control/Darkel.cpp
+++ b/src/control/Darkel.cpp
@@ -16,7 +16,7 @@
#include "Vehicle.h"
#include "GameLogic.h"
-//--MIAMI: file done except TODO
+//--MIAMI: file done
#define FRENZY_ANY_PED -1
#define FRENZY_ANY_CAR -2
@@ -295,11 +295,16 @@ CDarkel::StartFrenzy(eWeaponType weaponType, int32 time, uint16 kill, int32 mode
CPlayerPed *player = FindPlayerPed();
if (fixedWeapon < WEAPONTYPE_TOTALWEAPONS) {
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->SetCurrentWeapon(fixedWeapon);
player->MakeChangesForNewWeapon(player->m_nSelectedWepSlot);
@@ -403,6 +408,6 @@ CDarkel::DealWithWeaponChangeAtEndOfFrenzy()
FindPlayerPed()->m_nSelectedWepSlot = WEAPONSLOT_UNARMED;
player->SetCurrentWeapon(FindPlayerPed()->m_nSelectedWepSlot);
player->MakeChangesForNewWeapon(player->m_currentWeapon);
- //player->RemoveDriveByAnims(); // TODO(MIAMI)
+ player->RemoveDrivebyAnims();
}
}
diff --git a/src/control/GameLogic.cpp b/src/control/GameLogic.cpp
index 98209c85..e7f7d525 100644
--- a/src/control/GameLogic.cpp
+++ b/src/control/GameLogic.cpp
@@ -29,6 +29,7 @@
#include "ColStore.h"
#include "Automobile.h"
#include "MBlur.h"
+#include "screendroplets.h"
uint8 CGameLogic::ActivePlayers;
uint8 CGameLogic::ShortCutState;
@@ -153,6 +154,9 @@ CGameLogic::Update()
}
}
CEventList::Initialise();
+#ifdef SCREEN_DROPLETS
+ ScreenDroplets::Initialise();
+#endif
CMessages::ClearMessages();
CCarCtrl::ClearInterestingVehicleList();
CWorld::ClearExcitingStuffFromArea(pPlayerInfo.GetPos(), 4000.0f, 1);
@@ -259,6 +263,9 @@ CGameLogic::Update()
}
}
CEventList::Initialise();
+#ifdef SCREEN_DROPLETS
+ ScreenDroplets::Initialise();
+#endif
CMessages::ClearMessages();
CCarCtrl::ClearInterestingVehicleList();
CWorld::ClearExcitingStuffFromArea(pPlayerInfo.GetPos(), 4000.0f, 1);
@@ -311,6 +318,9 @@ CGameLogic::Update()
}
}
CEventList::Initialise();
+#ifdef SCREEN_DROPLETS
+ ScreenDroplets::Initialise();
+#endif
CMessages::ClearMessages();
CCarCtrl::ClearInterestingVehicleList();
CWorld::ClearExcitingStuffFromArea(pPlayerInfo.GetPos(), 4000.0f, 1);
diff --git a/src/control/Garages.cpp b/src/control/Garages.cpp
index b27b3c20..53cebeea 100644
--- a/src/control/Garages.cpp
+++ b/src/control/Garages.cpp
@@ -4,9 +4,7 @@
#include "main.h"
#include "Bike.h"
-#ifdef FIX_BUGS
#include "Boat.h"
-#endif
#include "DMAudio.h"
#include "General.h"
#include "Font.h"
@@ -47,7 +45,7 @@
// 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)
@@ -126,8 +124,8 @@ uint32 CGarages::MessageEndTime;
uint32 CGarages::NumGarages;
bool CGarages::PlayerInGarage;
int32 CGarages::PoliceCarsCollected;
-CStoredCar CGarages::aCarsInSafeHouses[TOTAL_HIDEOUT_GARAGES][CGarages::MAX_NUM_CARS_IN_HIDEOUT_GARAGE];
-int32 CGarages::AudioEntity = AEHANDLE_NONE;
+CStoredCar CGarages::aCarsInSafeHouses[TOTAL_HIDEOUT_GARAGES][NUM_GARAGE_STORED_CARS];
+int32 hGarages = AEHANDLE_NONE;
CGarage CGarages::aGarages[NUM_GARAGES];
bool CGarages::bCamShouldBeOutisde;
@@ -148,41 +146,47 @@ void CGarages::Init(void)
for (int i = 0; i < TOTAL_COLLECTCARS_GARAGES; i++)
CarTypesCollected[i] = 0;
LastTimeHelpMessage = 0;
- for (int i = 0; i < TOTAL_HIDEOUT_GARAGES; i++) {
- for (int j = 0; j < MAX_NUM_CARS_IN_HIDEOUT_GARAGE; j++)
- aCarsInSafeHouses[i][j].Init();
+ for (int i = 0; i < NUM_GARAGE_STORED_CARS; i++) {
+ for (int j = 0; j < TOTAL_HIDEOUT_GARAGES; j++)
+ aCarsInSafeHouses[j][i].Init();
}
- AudioEntity = DMAudio.CreateEntity(AUDIOTYPE_GARAGE, (void*)1);
- if (AudioEntity >= 0)
- DMAudio.SetEntityStatus(AudioEntity, 1);
+ hGarages = DMAudio.CreateEntity(AUDIOTYPE_GARAGE, (void*)1);
+ if (hGarages >= 0)
+ DMAudio.SetEntityStatus(hGarages, true);
}
void CGarages::Shutdown(void)
{
NumGarages = 0;
- if (AudioEntity < 0)
+ if (hGarages < 0)
return;
- DMAudio.DestroyEntity(AudioEntity);
- AudioEntity = AEHANDLE_NONE;
+ DMAudio.DestroyEntity(hGarages);
+ hGarages = AEHANDLE_NONE;
}
void CGarages::Update(void)
{
- static int GarageToBeTidied = 0;
-#ifndef PS2
+ static uint32 GarageToBeTidied = 0;
if (CReplay::IsPlayingBack())
return;
-#endif
bCamShouldBeOutisde = false;
TheCamera.pToGarageWeAreIn = nil;
TheCamera.pToGarageWeAreInForHackAvoidFirstPerson = nil;
+#ifdef FIX_BUGS
+ for (uint32 i = 0; i < NumGarages; i++) {
+#else
for (int i = 0; i < NUM_GARAGES; i++) {
+#endif
if (aGarages[i].IsUsed())
aGarages[i].Update();
}
if ((CTimer::GetFrameCounter() & 0xF) != 0xC)
return;
+#ifdef FIX_BUGS
+ if (++GarageToBeTidied >= NumGarages)
+#else
if (++GarageToBeTidied >= NUM_GARAGES)
+#endif
GarageToBeTidied = 0;
if (!aGarages[GarageToBeTidied].IsUsed())
return;
@@ -192,7 +196,7 @@ void CGarages::Update(void)
aGarages[GarageToBeTidied].TidyUpGarage();
}
-int16 CGarages::AddOne(float X1, float Y1, float Z1, float X2, float Y2, float X3, float Y3, float Z2, eGarageType 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);
@@ -293,7 +297,7 @@ int16 CGarages::AddOne(float X1, float Y1, float Z1, float X2, float Y2, float X
return NumGarages++;
}
-void CGarages::ChangeGarageType(int16 garage, eGarageType type, int32 mi)
+void CGarages::ChangeGarageType(int16 garage, uint8 type, int32 mi)
{
CGarage* pGarage = &aGarages[garage];
pGarage->m_eGarageType = type;
@@ -339,6 +343,43 @@ 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) {
@@ -378,7 +419,7 @@ void CGarage::Update()
if (m_fDoorPos == 0.0f) {
m_eGarageState = GS_FULLYCLOSED;
m_nTimeToStartAction = CTimer::GetTimeInMilliseconds() + TIME_TO_RESPRAY;
- DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
+ DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
CStats::CheckPointReachedSuccessfully();
}
UpdateDoorsHeight();
@@ -482,7 +523,7 @@ void CGarage::Update()
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_OPENEDCONTAINSCAR;
- DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f);
+ DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_OPENED, 1.0f);
}
UpdateDoorsHeight();
break;
@@ -526,7 +567,7 @@ void CGarage::Update()
if (m_fDoorPos == 0.0f) {
m_eGarageState = GS_FULLYCLOSED;
m_nTimeToStartAction = CTimer::GetTimeInMilliseconds() + TIME_TO_SETUP_BOMB;
- DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
+ DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
}
UpdateDoorsHeight();
if (m_eGarageType == GARAGE_BOMBSHOP3)
@@ -539,14 +580,18 @@ void CGarage::Update()
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() || 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;
@@ -584,7 +629,6 @@ void CGarage::Update()
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;
@@ -598,7 +642,7 @@ void CGarage::Update()
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_OPENEDCONTAINSCAR;
- DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f);
+ DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_OPENED, 1.0f);
}
UpdateDoorsHeight();
break;
@@ -616,13 +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)) {
+ IsEntityEntirelyOutside(FindPlayerVehicle() ? (CEntity*)FindPlayerVehicle() : (CEntity*)FindPlayerPed(), 2.0f)) {
CPad::GetPad(0)->SetDisablePlayerControls(PLAYERCONTROL_GARAGE);
FindPlayerPed()->m_pWanted->m_bIgnoredByCops = true;
m_eGarageState = GS_CLOSING;
@@ -634,7 +682,7 @@ void CGarage::Update()
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(CGarages::AudioEntity, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
+ DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
if (m_bClosingWithoutTargetCar)
m_eGarageState = GS_FULLYCLOSED;
else {
@@ -664,7 +712,7 @@ void CGarage::Update()
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(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f);
+ DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_OPENED, 1.0f);
}
UpdateDoorsHeight();
break;
@@ -717,7 +765,7 @@ void CGarage::Update()
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(CGarages::AudioEntity, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
+ DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
if (m_pTarget) {
MarkThisCarAsCollectedForCraig(m_pTarget->GetModelIndex());
DestroyVehicleAndDriverAndPassengers(m_pTarget);
@@ -757,7 +805,7 @@ void CGarage::Update()
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(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f);
+ DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_OPENED, 1.0f);
}
UpdateDoorsHeight();
break;
@@ -778,7 +826,7 @@ void CGarage::Update()
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(CGarages::AudioEntity, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
+ DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
}
if (!IsGarageEmpty())
m_eGarageState = GS_OPENING;
@@ -789,7 +837,7 @@ void CGarage::Update()
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(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f);
+ DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_OPENED, 1.0f);
}
UpdateDoorsHeight();
break;
@@ -823,7 +871,7 @@ void CGarage::Update()
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(CGarages::AudioEntity, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
+ DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
if (m_bClosingWithoutTargetCar)
m_eGarageState = GS_FULLYCLOSED;
else {
@@ -852,7 +900,7 @@ void CGarage::Update()
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(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f);
+ DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_OPENED, 1.0f);
}
UpdateDoorsHeight();
break;
@@ -872,7 +920,7 @@ void CGarage::Update()
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(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f);
+ DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_OPENED, 1.0f);
}
UpdateDoorsHeight();
break;
@@ -892,7 +940,7 @@ void CGarage::Update()
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(CGarages::AudioEntity, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
+ DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
}
UpdateDoorsHeight();
break;
@@ -900,7 +948,7 @@ void CGarage::Update()
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(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f);
+ DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_OPENED, 1.0f);
}
UpdateDoorsHeight();
break;
@@ -932,8 +980,8 @@ void CGarage::Update()
// Close car doors either if player is far, or if he is in vehicle and garage is full,
// or if player is very very far so that we can remove whatever is blocking garage door without him noticing
if ((distance > SQR(DISTANCE_TO_CLOSE_HIDEOUT_GARAGE_IN_CAR) ||
- !FindPlayerVehicle() && distance > SQR(DISTANCE_TO_CLOSE_HIDEOUT_GARAGE_ON_FOOT) &&
- !IsAnyCarBlockingDoor()))
+ !FindPlayerVehicle() && distance > SQR(DISTANCE_TO_CLOSE_HIDEOUT_GARAGE_ON_FOOT)) &&
+ !IsAnyCarBlockingDoor())
m_eGarageState = GS_CLOSING;
else if (FindPlayerVehicle() &&
CountCarsWithCenterPointWithinGarage(FindPlayerVehicle()) >=
@@ -951,7 +999,7 @@ void CGarage::Update()
if (!IsPlayerOutsideGarage())
m_eGarageState = GS_OPENING;
else if (m_fDoorPos == 0.0f) {
- DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
+ DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
m_eGarageState = GS_FULLYCLOSED;
StoreAndRemoveCarsForThisHideout(CGarages::aCarsInSafeHouses[CGarages::FindSafeHouseIndexForGarageType(m_eGarageType)], NUM_GARAGE_STORED_CARS);
}
@@ -982,7 +1030,7 @@ void CGarage::Update()
m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + HIDEOUT_DOOR_SPEED_COEFFICIENT * (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == m_fDoorHeight) {
m_eGarageState = GS_OPENED;
- DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f);
+ DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_OPENED, 1.0f);
}
UpdateDoorsHeight();
break;
@@ -1009,7 +1057,7 @@ void CGarage::Update()
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(CGarages::AudioEntity, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
+ DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
}
UpdateDoorsHeight();
break;
@@ -1025,7 +1073,7 @@ void CGarage::Update()
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(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f);
+ DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_OPENED, 1.0f);
}
UpdateDoorsHeight();
break;
@@ -1036,8 +1084,8 @@ 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:
@@ -1046,20 +1094,23 @@ void CGarage::Update()
m_eGarageState = GS_CLOSING;
m_bClosingWithoutTargetCar = false;
}
+ break;
case GS_CLOSING:
m_fDoorPos = Max(0.0f, m_fDoorPos - (m_bRotatedDoor ? ROTATED_DOOR_CLOSE_SPEED : DEFAULT_DOOR_CLOSE_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == 0.0f) {
m_eGarageState = GS_FULLYCLOSED;
- DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
+ DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_CLOSED, 1.0f);
CPad::GetPad(0)->SetEnablePlayerControls(PLAYERCONTROL_GARAGE);
}
+ UpdateDoorsHeight();
+ break;
case GS_FULLYCLOSED:
break;
case GS_OPENING:
m_fDoorPos = Min(m_fDoorHeight, m_fDoorPos + (m_bRotatedDoor ? ROTATED_DOOR_OPEN_SPEED : DEFAULT_DOOR_OPEN_SPEED) * CTimer::GetTimeStep());
if (m_fDoorPos == m_fDoorHeight) {
m_eGarageState = GS_OPENED;
- DMAudio.PlayOneShot(CGarages::AudioEntity, SOUND_GARAGE_DOOR_OPENED, 1.0f);
+ DMAudio.PlayOneShot(hGarages, SOUND_GARAGE_DOOR_OPENED, 1.0f);
}
UpdateDoorsHeight();
break;
@@ -1074,28 +1125,6 @@ void CGarage::Update()
}
}
-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::IsStaticPlayerCarEntirelyInside()
{
if (!FindPlayerVehicle())
@@ -1160,7 +1189,7 @@ bool CGarage::IsPointInsideGarage(CVector pos, float m_fMargin)
return true;
}
-bool CGarage::IsEntityEntirelyInside3D(CEntity * pEntity, float fMargin)
+bool CGarage::IsEntityEntirelyInside3D(CEntity* pEntity, float fMargin)
{
if (pEntity->GetPosition().x < m_fInfX - fMargin || pEntity->GetPosition().x > m_fSupX + fMargin ||
pEntity->GetPosition().y < m_fInfY - fMargin || pEntity->GetPosition().y > m_fSupY + fMargin ||
@@ -1212,12 +1241,12 @@ bool CGarage::IsPlayerOutsideGarage()
return IsEntityEntirelyOutside(FindPlayerPed(), 0.0f);
}
-bool CGarage::IsEntityTouching3D(CEntity * pEntity)
+bool CGarage::IsEntityTouching3D(CEntity* pEntity)
{
float radius = pEntity->GetBoundRadius();
- if (pEntity->GetPosition().x - radius < m_fInfX || pEntity->GetPosition().x + radius > m_fSupX ||
- pEntity->GetPosition().y - radius < m_fInfY || pEntity->GetPosition().y + radius > m_fSupY ||
- pEntity->GetPosition().z - radius < m_fInfZ || pEntity->GetPosition().z + radius > m_fSupZ)
+ 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++) {
@@ -1261,6 +1290,28 @@ bool CGarage::IsAnyOtherCarTouchingGarage(CVehicle * pException)
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();
@@ -1328,7 +1379,9 @@ void CGarage::RemoveCarsBlockingDoorNotInside()
if (!pVehicle->bIsLocked && pVehicle->CanBeDeleted()) {
CWorld::Remove(pVehicle);
delete pVehicle;
- return; // WHY?
+#ifndef FIX_BUGS
+ return;
+#endif
}
}
}
@@ -1337,43 +1390,34 @@ 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_STANDARD));
- CFont::SetColor(CRGBA(0, 0, 0, 255));
+ CFont::SetColor(CRGBA(27, 89, 130, 255));
+ CFont::SetDropShadowPosition(2);
+ CFont::SetDropColor(CRGBA(0, 0, 0, 255));
-#if defined(PS2) || defined (FIX_BUGS)
- float y_offset = SCREEN_HEIGHT / 3; // THIS is PS2 calculation
+#if defined(GTA_PS2) || defined (FIX_BUGS)
+ 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) {
- if (MessageNumberInString < 0) {
- CFont::PrintString(SCREEN_WIDTH / 2 - SCREEN_SCALE_X(2.0f), y_offset - SCREEN_SCALE_Y(2.0f), TheText.Get(MessageIDString));
-
- CFont::SetColor(CRGBA(27, 89, 130, 255));
- CFont::PrintString(SCREEN_WIDTH / 2, y_offset, TheText.Get(MessageIDString));
- }
- else {
- 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(27, 89, 130, 255));
- CFont::PrintString(SCREEN_WIDTH / 2, y_offset - SCREEN_SCALE_Y(40.0f), gUString);
- }
+ if (MessageNumberInString2 >= 0) {
+ CMessages::InsertNumberInString(TheText.Get(MessageIDString), MessageNumberInString, MessageNumberInString2, -1, -1, -1, -1, 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, y_offset - SCREEN_SCALE_Y(30.0f), gUString);
}
else {
- 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(27, 89, 130, 255));
- CFont::PrintString(SCREEN_WIDTH / 2, y_offset - SCREEN_SCALE_Y(40.0f), gUString);
+ CFont::PrintString(SCREEN_WIDTH / 2, y_offset, TheText.Get(MessageIDString));
}
}
}
@@ -1390,7 +1434,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;
@@ -1462,41 +1508,54 @@ void CGarage::UpdateCrusherShake(float X, float Y)
m_pDoor2->GetMatrix().GetPosition().y -= Y;
}
-// This is dumb but there is no way to avoid goto. What was there originally even?
-static bool DoINeedToRefreshPointer(CEntity * pDoor, bool bIsDummy, uint8 nIndex)
+void CGarage::RefreshDoorPointers(bool bCreate)
{
- bool bNeedToFindDoorEntities = false;
- if (pDoor) {
- if (bIsDummy) {
- if (CPools::GetDummyPool()->IsFreeSlot(CPools::GetDummyPool()->GetJustIndex((CDummy*)pDoor)))
- return true;
- if (nIndex != (CPools::GetDummyPool()->GetIndex((CDummy*)pDoor) & 0x7F))
+ bool bNeedToFindDoorEntities = bCreate || m_bRecreateDoorOnNextRefresh;
+ m_bRecreateDoorOnNextRefresh = false;
+ if (m_pDoor1) {
+ if (m_bDoor1IsDummy) {
+ if (CPools::GetDummyPool()->IsFreeSlot(CPools::GetDummyPool()->GetJustIndex_NoFreeAssert((CDummy*)m_pDoor1)))
bNeedToFindDoorEntities = true;
- if (!CGarages::IsModelIndexADoor(pDoor->GetModelIndex()))
- return true;
+ else {
+ if (m_bDoor1PoolIndex != (CPools::GetDummyPool()->GetIndex((CDummy*)m_pDoor1) & 0x7F))
+ bNeedToFindDoorEntities = true;
+ if (!CGarages::IsModelIndexADoor(m_pDoor1->GetModelIndex()))
+ bNeedToFindDoorEntities = true;
+ }
}
else {
- if (CPools::GetObjectPool()->IsFreeSlot(CPools::GetObjectPool()->GetJustIndex((CObject*)pDoor)))
- return true;
- if (nIndex != (CPools::GetObjectPool()->GetIndex((CObject*)pDoor) & 0x7F))
+ if (CPools::GetObjectPool()->IsFreeSlot(CPools::GetObjectPool()->GetJustIndex_NoFreeAssert((CObject*)m_pDoor1)))
bNeedToFindDoorEntities = true;
- if (!CGarages::IsModelIndexADoor(pDoor->GetModelIndex()))
- return true;
+ else {
+ if (m_bDoor1PoolIndex != (CPools::GetObjectPool()->GetIndex((CObject*)m_pDoor1) & 0x7F))
+ bNeedToFindDoorEntities = true;
+ if (!CGarages::IsModelIndexADoor(m_pDoor1->GetModelIndex()))
+ bNeedToFindDoorEntities = true;
+ }
+ }
+ }
+ if (m_pDoor2) {
+ if (m_bDoor2IsDummy) {
+ if (CPools::GetDummyPool()->IsFreeSlot(CPools::GetDummyPool()->GetJustIndex_NoFreeAssert((CDummy*)m_pDoor2)))
+ bNeedToFindDoorEntities = true;
+ else {
+ if (m_bDoor2PoolIndex != (CPools::GetDummyPool()->GetIndex((CDummy*)m_pDoor2) & 0x7F))
+ bNeedToFindDoorEntities = true;
+ if (!CGarages::IsModelIndexADoor(m_pDoor2->GetModelIndex()))
+ bNeedToFindDoorEntities = true;
+ }
+ }
+ else {
+ if (CPools::GetObjectPool()->IsFreeSlot(CPools::GetObjectPool()->GetJustIndex_NoFreeAssert((CObject*)m_pDoor2)))
+ bNeedToFindDoorEntities = true;
+ else {
+ if (m_bDoor2PoolIndex != (CPools::GetObjectPool()->GetIndex((CObject*)m_pDoor2) & 0x7F))
+ bNeedToFindDoorEntities = true;
+ if (!CGarages::IsModelIndexADoor(m_pDoor2->GetModelIndex()))
+ bNeedToFindDoorEntities = true;
+ }
}
}
- return bNeedToFindDoorEntities;
-}
-
-void CGarage::RefreshDoorPointers(bool bCreate)
-{
- bool bNeedToFindDoorEntities = true;
- if (!bCreate && !m_bRecreateDoorOnNextRefresh)
- bNeedToFindDoorEntities = false;
- m_bRecreateDoorOnNextRefresh = false;
- if (DoINeedToRefreshPointer(m_pDoor1, m_bDoor1IsDummy, m_bDoor1PoolIndex))
- bNeedToFindDoorEntities = true;
- if (DoINeedToRefreshPointer(m_pDoor2, m_bDoor2IsDummy, m_bDoor2PoolIndex))
- bNeedToFindDoorEntities = true;
if (bNeedToFindDoorEntities)
FindDoorsEntities();
}
@@ -1520,7 +1579,7 @@ 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) {
@@ -1663,10 +1722,10 @@ void CGarage::FindDoorsEntities()
{
m_pDoor1 = nil;
m_pDoor2 = nil;
- int xstart = Max(0, CWorld::GetSectorIndexX(m_fInfX));
- int xend = Min(NUMSECTORS_X - 1, CWorld::GetSectorIndexX(m_fSupX));
- int ystart = Max(0, CWorld::GetSectorIndexY(m_fInfY));
- int yend = Min(NUMSECTORS_Y - 1, CWorld::GetSectorIndexY(m_fSupY));
+ int xstart = Max(0, CWorld::GetSectorIndexX(GetGarageCenterX() - 100.0f));
+ int xend = Min(NUMSECTORS_X - 1, CWorld::GetSectorIndexX(GetGarageCenterX() + 100.0f));
+ int ystart = Max(0, CWorld::GetSectorIndexY(GetGarageCenterY() - 100.0f));
+ int yend = Min(NUMSECTORS_Y - 1, CWorld::GetSectorIndexY(GetGarageCenterY() + 100.0f));
assert(xstart <= xend);
assert(ystart <= yend);
@@ -1779,8 +1838,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()
@@ -1817,9 +1876,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
@@ -1882,7 +1939,11 @@ 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;
@@ -1909,8 +1970,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)
@@ -1923,12 +1989,12 @@ void CGarage::TidyUpGarage()
uint32 i = CPools::GetVehiclePool()->GetSize();
while (i--) {
CVehicle* pVehicle = CPools::GetVehiclePool()->GetSlot(i);
- if (!pVehicle || !pVehicle->IsCar())
- continue;
- if (IsPointInsideGarage(pVehicle->GetPosition())) {
- 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;
+ }
}
}
}
@@ -1939,9 +2005,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) {
@@ -1966,7 +2032,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();
}
@@ -2061,20 +2131,24 @@ void CGarage::CenterCarInGarage(CVehicle* pVehicle)
void CGarages::CloseHideOutGaragesBeforeSave()
{
+#ifdef FIX_BUGS
+ for (uint32 i = 0; i < NumGarages; i++) {
+#else
for (int i = 0; i < NUM_GARAGES; i++) {
+#endif
if (!IsThisGarageTypeSafehouse(aGarages[i].m_eGarageType))
continue;
if (aGarages[i].m_eGarageState != GS_FULLYCLOSED) {
aGarages[i].m_eGarageState = GS_FULLYCLOSED;
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();
}
}
-int32 CGarages::CountCarsInHideoutGarage(eGarageType type)
+int32 CGarages::CountCarsInHideoutGarage(uint8 type)
{
int32 total = 0;
for (int i = 0; i < NUM_GARAGE_STORED_CARS; i++) {
@@ -2085,11 +2159,24 @@ int32 CGarages::CountCarsInHideoutGarage(eGarageType type)
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:
+ 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;
@@ -2100,7 +2187,11 @@ 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;
@@ -2114,7 +2205,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;
diff --git a/src/control/Garages.h b/src/control/Garages.h
index 04c01719..46ae1542 100644
--- a/src/control/Garages.h
+++ b/src/control/Garages.h
@@ -7,7 +7,7 @@
class CVehicle;
class CCamera;
-enum eGarageState : int8
+enum eGarageState
{
GS_FULLYCLOSED,
GS_OPENED,
@@ -18,7 +18,7 @@ enum eGarageState : int8
GS_AFTERDROPOFF,
};
-enum eGarageType : int8
+enum eGarageType
{
GARAGE_NONE,
GARAGE_MISSION,
@@ -93,8 +93,8 @@ VALIDATE_SIZE(CStoredCar, 0x28);
class CGarage
{
- eGarageType m_eGarageType;
- eGarageState m_eGarageState;
+ uint8 m_eGarageType;
+ uint8 m_eGarageState;
uint8 m_nMaxStoredCars;
bool field_2; // unused
bool m_bClosingWithoutTargetCar;
@@ -148,8 +148,8 @@ class CGarage
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();
@@ -187,7 +187,7 @@ class CGarage
bool IsPointInsideGarage(CVector, float);
void ThrowCarsNearDoorOutOfGarage(CVehicle*);
- int32 FindMaxNumStoredCarsForGarage() { return Max(NUM_GARAGE_STORED_CARS, m_nMaxStoredCars); }
+ int32 FindMaxNumStoredCarsForGarage() { return Min(NUM_GARAGE_STORED_CARS, m_nMaxStoredCars); }
friend class CGarages;
friend class cAudioManager;
@@ -198,7 +198,6 @@ class CGarages
{
enum {
MESSAGE_LENGTH = 8,
- MAX_NUM_CARS_IN_HIDEOUT_GARAGE = 4
};
static int32 BankVansCollected;
static bool BombsAreFree;
@@ -216,8 +215,7 @@ class CGarages
static bool PlayerInGarage;
static int32 PoliceCarsCollected;
static CGarage aGarages[NUM_GARAGES];
- static CStoredCar aCarsInSafeHouses[TOTAL_HIDEOUT_GARAGES][MAX_NUM_CARS_IN_HIDEOUT_GARAGE];
- static int32 AudioEntity;
+ static CStoredCar aCarsInSafeHouses[TOTAL_HIDEOUT_GARAGES][NUM_GARAGE_STORED_CARS];
static bool bCamShouldBeOutisde;
public:
@@ -227,8 +225,8 @@ public:
#endif
static void Update(void);
- static int16 AddOne(float X1, float Y1, float Z1, float X2, float Y2, float X3, float Y3, float Z2, eGarageType type, int32 targetId);
- static void ChangeGarageType(int16, eGarageType, int32);
+ 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);
static void SetTargetCarForMissonGarage(int16, CVehicle*);
@@ -265,9 +263,9 @@ private:
static bool IsCarSprayable(CVehicle*);
static float FindDoorHeightForMI(int32);
static void CloseHideOutGaragesBeforeSave(void);
- static int32 CountCarsInHideoutGarage(eGarageType);
- static int32 GetBombTypeForGarageType(eGarageType type) { return type - GARAGE_BOMBSHOP1 + 1; }
- static int32 GetCarsCollectedIndexForGarageType(eGarageType type)
+ static int32 CountCarsInHideoutGarage(uint8);
+ static int32 GetBombTypeForGarageType(uint8 type) { return type - GARAGE_BOMBSHOP1 + 1; }
+ static int32 GetCarsCollectedIndexForGarageType(uint8 type)
{
switch (type) {
case GARAGE_COLLECTCARS_1: return 0;
@@ -278,7 +276,7 @@ private:
}
return 0;
}
- static int32 FindSafeHouseIndexForGarageType(eGarageType type)
+ static int32 FindSafeHouseIndexForGarageType(uint8 type)
{
switch (type) {
case GARAGE_HIDEOUT_ONE: return 0;
@@ -296,7 +294,7 @@ private:
}
return -1;
}
- static bool IsThisGarageTypeSafehouse(eGarageType type) { return FindSafeHouseIndexForGarageType(type) >= 0; }
+ static bool IsThisGarageTypeSafehouse(uint8 type) { return FindSafeHouseIndexForGarageType(type) >= 0; }
friend class cAudioManager;
friend class CReplay;
diff --git a/src/control/NameGrid.cpp b/src/control/NameGrid.cpp
new file mode 100644
index 00000000..204e8b9c
--- /dev/null
+++ b/src/control/NameGrid.cpp
@@ -0,0 +1,87 @@
+#include "common.h"
+#include "NameGrid.h"
+
+// TODO: reverse mobile code
+
+CPlayerName::CPlayerName()
+{
+ // TODO
+}
+
+void
+CPlayerName::DisplayName(int)
+{
+ // TODO
+}
+
+CRow::CRow()
+{
+ // TODO
+}
+
+void
+CRow::SetLetter(int, wchar *)
+{
+ // TODO
+}
+
+CGrid::CGrid()
+{
+ // TODO
+}
+
+void
+CGrid::ProcessAnyLeftJustDown()
+{
+ unk_int2--;
+}
+
+void
+CGrid::ProcessAnyRightJustDown()
+{
+ unk_int2++;
+}
+
+void
+CGrid::ProcessAnyUpJustDown()
+{
+ unk_int1--;
+}
+
+void
+CGrid::ProcessAnyDownJustDown()
+{
+ unk_int1++;
+}
+
+void
+CGrid::AllDoneMakePlayerName()
+{
+ // TODO
+}
+
+void
+CGrid::ProcessDPadCrossJustDown()
+{
+ // TODO
+}
+
+void
+CGrid::DisplayGrid()
+{
+ // TODO
+}
+
+void
+CGrid::ProcessControllerInput()
+{
+ // TODO
+}
+
+void
+CGrid::Process()
+{
+ ProcessControllerInput();
+ DisplayGrid();
+ playerName.DisplayName(2 * playerName.unk_4c);
+} \ No newline at end of file
diff --git a/src/control/NameGrid.h b/src/control/NameGrid.h
new file mode 100644
index 00000000..d52cec73
--- /dev/null
+++ b/src/control/NameGrid.h
@@ -0,0 +1,53 @@
+#pragma once
+
+// TODO: reverse mobile code
+
+class CPlayerName
+{
+ friend class CGrid;
+
+ float x;
+ float y;
+ wchar unk_8[34];
+ int unk_4c;
+public:
+ CPlayerName();
+ void DisplayName(int);
+};
+
+class CRow
+{
+ friend class CGrid;
+
+ int unk_0;
+ int unk_4;
+ wchar unk_8[20];
+ int unk_30;
+public:
+ CRow();
+ void SetLetter(int, wchar *);
+};
+
+class CGrid
+{
+ CRow rows[5];
+ int unk_int1;
+ int unk_int2;
+ int unk_int3;
+ float unk_float1;
+ float unk_float2;
+ CPlayerName playerName;
+ char unk2[4];
+ char unk3[4];
+public:
+ CGrid();
+ void ProcessAnyLeftJustDown();
+ void ProcessAnyRightJustDown();
+ void ProcessAnyUpJustDown();
+ void ProcessAnyDownJustDown();
+ void AllDoneMakePlayerName();
+ void ProcessDPadCrossJustDown();
+ void DisplayGrid();
+ void ProcessControllerInput();
+ void Process();
+}; \ No newline at end of file
diff --git a/src/control/PathFind.cpp b/src/control/PathFind.cpp
index 41dc735f..aa453701 100644
--- a/src/control/PathFind.cpp
+++ b/src/control/PathFind.cpp
@@ -286,6 +286,8 @@ CPathFind::AllocatePathFindInfoMem(int16 numPathGroups)
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;
@@ -1766,10 +1768,18 @@ CPathFind::TestCoorsCloseness(CVector target, uint8 type, CVector start)
DoPathSearch(type, start, -1, target, pNodeList, &DummyResult, 32, nil, &dist, 999999.88f, -1);
else
DoPathSearch(type, start, -1, target, nil, &DummyResult2, 0, nil, &dist, 50.0f, -1);
+#ifdef FIX_BUGS
+ // dist has GenerationDistMultiplier as a factor, so our reference dist should have it too
+ if(type == PATH_CAR)
+ return dist < 150.0f*TheCamera.GenerationDistMultiplier;
+ else
+ return dist < 100.0f*TheCamera.GenerationDistMultiplier;
+#else
if(type == PATH_CAR)
return dist < 150.0f;
else
return dist < 100.0f;
+#endif
}
void
diff --git a/src/control/Phones.cpp b/src/control/Phones.cpp
index 7f8677ec..cc80360d 100644
--- a/src/control/Phones.cpp
+++ b/src/control/Phones.cpp
@@ -58,7 +58,7 @@ CPhoneInfo::Update(void)
} else {
CPad::GetPad(0)->SetEnablePlayerControls(PLAYERCONTROL_PHONE);
if (player->m_nPedState == PED_MAKE_CALL)
- player->m_nPedState = PED_IDLE;
+ player->SetPedState(PED_IDLE);
}
}
bool notInCar;
@@ -105,7 +105,7 @@ CPhoneInfo::Update(void)
player->m_fRotationCur = angleToFace;
player->m_fRotationDest = angleToFace;
player->SetHeading(angleToFace);
- player->m_nPedState = PED_MAKE_CALL;
+ player->SetPedState(PED_MAKE_CALL);
CPad::GetPad(0)->SetDisablePlayerControls(PLAYERCONTROL_PHONE);
TheCamera.SetWideScreenOn();
playerInfo->MakePlayerSafe(true);
@@ -308,7 +308,7 @@ INITSAVEBUF
// Convert entity pointer to building pool index while saving
if (phone->m_pEntity) {
- phone->m_pEntity = (CEntity*) (CPools::GetBuildingPool()->GetJustIndex((CBuilding*)phone->m_pEntity) + 1);
+ phone->m_pEntity = (CEntity*) (CPools::GetBuildingPool()->GetJustIndex_NoFreeAssert((CBuilding*)phone->m_pEntity) + 1);
}
}
VALIDATESAVEBUF(*size)
@@ -333,7 +333,7 @@ PhonePutDownCB(CAnimBlendAssociation *assoc, void *arg)
ped->bUpdateAnimHeading = true;
if (ped->m_nPedState == PED_MAKE_CALL)
- ped->m_nPedState = PED_IDLE;
+ ped->SetPedState(PED_IDLE);
}
void
diff --git a/src/control/Pickups.cpp b/src/control/Pickups.cpp
index e53f1ecb..23b5d9ff 100644
--- a/src/control/Pickups.cpp
+++ b/src/control/Pickups.cpp
@@ -140,18 +140,12 @@ ModifyStringLabelForControlSetting(char *str)
}
}
-inline bool
-IsWeaponSlotAmmoMergeable(uint32 slot)
-{
- return slot == WEAPONSLOT_SHOTGUN || slot == WEAPONSLOT_SUBMACHINEGUN || slot == WEAPONSLOT_RIFLE;
-}
-
void
CPickup::ExtractAmmoFromPickup(CPlayerPed *player)
{
eWeaponType weaponType = CPickups::WeaponForModel(m_pObject->GetModelIndex());
- if (m_eType == PICKUP_IN_SHOP || !IsWeaponSlotAmmoMergeable(CWeaponInfo::GetWeaponInfo(weaponType)->m_nWeaponSlot))
+ if (m_eType == PICKUP_IN_SHOP || !CWeaponInfo::IsWeaponSlotAmmoMergeable(CWeaponInfo::GetWeaponInfo(weaponType)->m_nWeaponSlot))
return;
uint32 ammo = m_nQuantity;
@@ -374,14 +368,14 @@ CPickup::Update(CPlayerPed *player, CVehicle *vehicle, int playerId)
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 && !IsWeaponSlotAmmoMergeable(slot))) {
+ 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 (IsWeaponSlotAmmoMergeable(slot)) {
+ 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();
@@ -602,7 +596,10 @@ CPickup::Update(CPlayerPed *player, CVehicle *vehicle, int playerId)
bool explode = false;
if (CTimer::GetTimeInMilliseconds() > m_nTimer)
explode = true;
- else {// added else here since vehicle lookup is useless
+#ifdef FIX_BUGS
+ else// added else here since vehicle lookup is useless
+#endif
+ {
for (int32 i = CPools::GetVehiclePool()->GetSize()-1; i >= 0; i--) {
CVehicle *vehicle = CPools::GetVehiclePool()->GetSlot(i);
if (vehicle != nil && vehicle->IsSphereTouchingVehicle(m_pObject->GetPosition().x, m_pObject->GetPosition().y, m_pObject->GetPosition().z, 1.5f)) {
@@ -625,11 +622,11 @@ CPickup::Update(CPlayerPed *player, CVehicle *vehicle, int playerId)
m_pObject->GetMatrix().UpdateRW();
m_pObject->UpdateRwFrame();
- if (CWaterLevel::GetWaterLevel(m_pObject->GetPosition().x, m_pObject->GetPosition().y, m_pObject->GetPosition().z + 5.0f, &waterLevel, 0) && waterLevel >= m_pObject->GetPosition().z)
+ if (CWaterLevel::GetWaterLevel(m_pObject->GetPosition().x, m_pObject->GetPosition().y, m_pObject->GetPosition().z + 5.0f, &waterLevel, false) && waterLevel >= m_pObject->GetPosition().z)
m_eType = PICKUP_FLOATINGPACKAGE_FLOATING;
break;
case PICKUP_FLOATINGPACKAGE_FLOATING:
- if (CWaterLevel::GetWaterLevel(m_pObject->GetPosition().x, m_pObject->GetPosition().y, m_pObject->GetPosition().z + 5.0f, &waterLevel, 0))
+ if (CWaterLevel::GetWaterLevel(m_pObject->GetPosition().x, m_pObject->GetPosition().y, m_pObject->GetPosition().z + 5.0f, &waterLevel, false))
m_pObject->GetMatrix().GetPosition().z = waterLevel;
m_pObject->GetMatrix().UpdateRW();
@@ -858,7 +855,7 @@ CPickups::GenerateNewOne(CVector pos, uint32 modelIndex, uint8 type, uint32 quan
if (slot >= NUMPICKUPS) return -1;
- aPickUps[slot].m_eType = (ePickupType)type;
+ aPickUps[slot].m_eType = type;
aPickUps[slot].m_bRemoved = false;
aPickUps[slot].m_nQuantity = quantity;
aPickUps[slot].m_nMoneySpeed = rate;
@@ -1384,7 +1381,7 @@ void
CPickups::RemoveAllPickupsOfACertainWeaponGroupWithNoAmmo(eWeaponType weaponType)
{
uint32 weaponSlot = CWeaponInfo::GetWeaponInfo(weaponType)->m_nWeaponSlot;
- if (IsWeaponSlotAmmoMergeable(weaponSlot)) {
+ 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) {
@@ -1464,9 +1461,9 @@ INITSAVEBUF
CPickup *buf_pickup = WriteSaveBuf(buf, aPickUps[i]);
if (buf_pickup->m_eType != PICKUP_NONE) {
if (buf_pickup->m_pObject != nil)
- buf_pickup->m_pObject = (CObject*)(CPools::GetObjectPool()->GetJustIndex(buf_pickup->m_pObject) + 1);
+ 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(buf_pickup->m_pExtraObject) + 1);
+ buf_pickup->m_pExtraObject = (CObject*)(CPools::GetObjectPool()->GetJustIndex_NoFreeAssert(buf_pickup->m_pExtraObject) + 1);
}
}
@@ -1578,3 +1575,102 @@ void
CPacManPickups::ResetPowerPillsCarriedByPlayer()
{
}
+
+// --MIAMI: Done
+void
+CPed::CreateDeadPedMoney(void)
+{
+ if (!CGame::nastyGame)
+ return;
+
+ int mi = GetModelIndex();
+
+ if ((mi >= MI_COP && mi <= MI_FIREMAN) || (CharCreatedBy == MISSION_CHAR && !bMoneyHasBeenGivenByScript) || bInVehicle)
+ return;
+
+ int money = m_nPedMoney;
+ if (money < 10)
+ return;
+
+ CVector pickupPos = GetPosition();
+ CPickups::CreateSomeMoney(pickupPos, money);
+ m_nPedMoney = 0;
+}
+
+// --MIAMI: Done
+void
+CPed::CreateDeadPedWeaponPickups(void)
+{
+ CVector pickupPos;
+
+ if (bInVehicle)
+ return;
+
+ 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 && !GetWeapon(i).IsTypeMelee()))
+ continue;
+
+ 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((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;
+
+ CVector pedToPickup = pickupPos - pedPos;
+ float distance = pedToPickup.Magnitude();
+
+ // outer edge of pickup
+ distance = (distance + 0.4f) / distance;
+ CVector pickupPos2 = pedPos;
+ pickupPos2 += distance * pedToPickup;
+
+ if ((pickupPos - FindPlayerCoors()).Magnitude2D() > 2.0f || i > NUMBER_OF_ATTEMPTS / 2) {
+
+ if (i > NUMBER_OF_ATTEMPTS / 2 || !CPickups::TestForPickupsInBubble(pickupPos, 1.3f)) {
+
+ if (CWorld::GetIsLineOfSightClear(pickupPos2, pedPos,
+ true, i < NUMBER_OF_ATTEMPTS / 2, false, i < NUMBER_OF_ATTEMPTS / 2, false, false, false)) {
+
+ if (i > NUMBER_OF_ATTEMPTS / 2 || !CWorld::TestSphereAgainstWorld(pickupPos, 1.2f, nil, false, true, false, false, false, false)) {
+ *x = pickupPos.x;
+ *y = pickupPos.y;
+ *z = pickupPos.z;
+ return;
+ }
+ }
+ }
+ }
+ }
+ *x = GetPosition().x;
+ *y = GetPosition().y;
+ *z = GetPosition().z + 0.4f;
+#undef NUMBER_OF_ATTEMPTS
+} \ No newline at end of file
diff --git a/src/control/Pickups.h b/src/control/Pickups.h
index 36179f66..af9503e0 100644
--- a/src/control/Pickups.h
+++ b/src/control/Pickups.h
@@ -1,7 +1,7 @@
#pragma once
#include "Weapon.h"
-enum ePickupType : uint8
+enum ePickupType
{
PICKUP_NONE = 0,
PICKUP_IN_SHOP,
@@ -43,7 +43,7 @@ public:
int16 m_eModelIndex;
uint16 m_nIndex;
char m_sTextKey[8];
- ePickupType m_eType;
+ uint8 m_eType;
bool m_bRemoved;
uint8 m_bWasAmmoCollected:1;
uint8 m_bWasControlMessageShown:1;
diff --git a/src/control/Record.h b/src/control/Record.h
index 8b55b1f4..6a94c408 100644
--- a/src/control/Record.h
+++ b/src/control/Record.h
@@ -57,9 +57,7 @@ public:
static void RestoreInfoForMatrix(CMatrix&, CCarStateEachFrame*);
static void RestoreInfoForCar(CAutomobile*, CCarStateEachFrame*, bool);
static void ProcessControlCars(void);
-#if (defined(GTA_PS2) || defined(FIX_BUGS))
static bool ShouldThisPadBeLeftAlone(uint8 pad);
-#endif
static void GiveUsACar(int32, CVector, float, CAutomobile**, uint8, uint8);
static void StartChaseScene(float);
static void CleanUpChaseScene(void);
diff --git a/src/control/Replay.cpp b/src/control/Replay.cpp
index e28bbf35..d3de987e 100644
--- a/src/control/Replay.cpp
+++ b/src/control/Replay.cpp
@@ -1,5 +1,5 @@
#include "common.h"
-
+#ifdef GTA_REPLAY
#include "AnimBlendAssocGroup.h"
#include "AnimBlendAssociation.h"
#include "Bike.h"
@@ -794,10 +794,19 @@ void CReplay::StoreBikeUpdate(CVehicle* vehicle, int id)
vp->matrix.CompressFromFullMatrix(vehicle->GetMatrix());
vp->health = vehicle->m_fHealth / 4.0f; /* Not anticipated that health can be > 1000. */
vp->acceleration = vehicle->m_fGasPedal * 100.0f;
+#ifdef FIX_BUGS // originally it's undefined behaviour - different fields are copied on PC and mobile
+ for (int i = 0; i < 2; i++)
+ vp->wheel_rotation[i] = 128.0f / PI * bike->m_aWheelRotation[i];
+ for (int i = 0; i < 2; i++)
+ vp->wheel_rotation[i + 2] = 128.0f / PI * bike->m_aWheelSpeed[i];
+ for (int i = 0; i < 4; i++)
+ vp->wheel_susp_dist[i] = 50.0f * bike->m_aSuspensionSpringRatio[i];
+#else
for (int i = 0; i < 4; i++) {
vp->wheel_susp_dist[i] = 50.0f * bike->m_aSuspensionSpringRatio[i];
vp->wheel_rotation[i] = 128.0f / PI * bike->m_aWheelRotation[i];
}
+#endif
vp->velocityX = 8000.0f * Max(-4.0f, Min(4.0f, vehicle->GetMoveSpeed().x)); /* 8000!? */
vp->velocityY = 8000.0f * Max(-4.0f, Min(4.0f, vehicle->GetMoveSpeed().y));
vp->velocityZ = 8000.0f * Max(-4.0f, Min(4.0f, vehicle->GetMoveSpeed().z));
@@ -902,12 +911,19 @@ void CReplay::ProcessBikeUpdate(CVehicle* vehicle, float interpolation, CAddress
vehicle->m_vecMoveSpeed = CVector(vp->velocityX / 8000.0f, vp->velocityY / 8000.0f, vp->velocityZ / 8000.0f);
vehicle->m_fSteerAngle = vp->wheel_state / 50.0f;
vehicle->bEngineOn = true;
+#ifdef FIX_BUGS
+ for (int i = 0; i < 2; i++)
+ bike->m_aWheelRotation[i] = vp->wheel_rotation[i] / (128.0f / PI);
+ for (int i = 0; i < 2; i++)
+ bike->m_aWheelSpeed[i] = vp->wheel_rotation[i + 2] / (128.0f / PI);
+ for (int i = 0; i < 4; i++)
+ bike->m_aSuspensionSpringRatio[i] = vp->wheel_susp_dist[i] / 50.0f;
+#else
for (int i = 0; i < 4; i++) {
bike->m_aSuspensionSpringRatio[i] = vp->wheel_susp_dist[i] / 50.0f;
bike->m_aWheelRotation[i] = vp->wheel_rotation[i] / (128.0f / PI);
- // 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
}
+#endif
bike->m_fLeanLRAngle = vp->lean_angle / 50.0f;
bike->m_fWheelAngle = vp->wheel_angle / 50.0f;
bike->bLeanMatrixClean = false;
@@ -1218,10 +1234,10 @@ void CReplay::ProcessReplayCamera(void)
TheCamera.GetUp() = CVector(0.0f, 1.0f, 0.0f);
TheCamera.GetRight() = CVector(1.0f, 0.0f, 0.0f);
RwMatrix* pm = RwFrameGetMatrix(RwCameraGetFrame(TheCamera.m_pRwCamera));
- pm->pos = *(RwV3d*)&TheCamera.GetPosition();
- pm->at = *(RwV3d*)&TheCamera.GetForward();
- pm->up = *(RwV3d*)&TheCamera.GetUp();
- pm->right = *(RwV3d*)&TheCamera.GetRight();
+ pm->pos = TheCamera.GetPosition();
+ pm->at = TheCamera.GetForward();
+ pm->up = TheCamera.GetUp();
+ pm->right = TheCamera.GetRight();
break;
}
case REPLAYCAMMODE_FIXED:
@@ -1237,10 +1253,10 @@ void CReplay::ProcessReplayCamera(void)
TheCamera.GetMatrix().GetUp() = up;
TheCamera.GetMatrix().GetRight() = right;
RwMatrix* pm = RwFrameGetMatrix(RwCameraGetFrame(TheCamera.m_pRwCamera));
- pm->pos = *(RwV3d*)&TheCamera.GetMatrix().GetPosition();
- pm->at = *(RwV3d*)&TheCamera.GetMatrix().GetForward();
- pm->up = *(RwV3d*)&TheCamera.GetMatrix().GetUp();
- pm->right = *(RwV3d*)&TheCamera.GetMatrix().GetRight();
+ pm->pos = TheCamera.GetMatrix().GetPosition();
+ pm->at = TheCamera.GetMatrix().GetForward();
+ pm->up = TheCamera.GetMatrix().GetUp();
+ pm->right = TheCamera.GetMatrix().GetRight();
break;
}
default:
@@ -1447,7 +1463,7 @@ void CReplay::RestoreStuffFromMem(void)
ped->m_rwObject = nil;
ped->m_modelIndex = -1;
ped->SetModelIndex(mi);
- ped->m_pVehicleAnim = 0;
+ ped->m_pVehicleAnim = nil;
ped->m_audioEntityId = DMAudio.CreateEntity(AUDIOTYPE_PHYSICAL, ped);
DMAudio.SetEntityStatus(ped->m_audioEntityId, true);
CPopulation::UpdatePedCount((ePedType)ped->m_nPedType, false);
@@ -1840,10 +1856,10 @@ void CReplay::ProcessLookAroundCam(void)
TheCamera.GetRight() = right;
TheCamera.SetPosition(camera_pt);
RwMatrix* pm = RwFrameGetMatrix(RwCameraGetFrame(TheCamera.m_pRwCamera));
- pm->pos = *(RwV3d*)&TheCamera.GetPosition();
- pm->at = *(RwV3d*)&TheCamera.GetForward();
- pm->up = *(RwV3d*)&TheCamera.GetUp();
- pm->right = *(RwV3d*)&TheCamera.GetRight();
+ pm->pos = TheCamera.GetPosition();
+ pm->at = TheCamera.GetForward();
+ pm->up = TheCamera.GetUp();
+ pm->right = TheCamera.GetRight();
TheCamera.CalculateDerivedValues();
RwMatrixUpdate(RwFrameGetMatrix(RwCameraGetFrame(TheCamera.m_pRwCamera)));
RwFrameUpdateObjects(RwCameraGetFrame(TheCamera.m_pRwCamera));
@@ -1887,3 +1903,4 @@ void CReplay::Display()
if (Mode == MODE_PLAYBACK)
CFont::PrintString(SCREEN_SCALE_X(63.5f), SCREEN_SCALE_Y(30.0f), TheText.Get("REPLAY"));
}
+#endif
diff --git a/src/control/Replay.h b/src/control/Replay.h
index 319d8bd4..84a6bef0 100644
--- a/src/control/Replay.h
+++ b/src/control/Replay.h
@@ -66,6 +66,12 @@ struct CStoredDetailedAnimationState
void PlayReplayFromHD(void);
+#ifdef GTA_REPLAY
+#define REPLAY_STUB
+#else
+#define REPLAY_STUB {}
+#endif
+
class CReplay
{
enum {
@@ -362,21 +368,25 @@ private:
#endif
public:
- static void Init(void);
- static void DisableReplays(void);
- static void EnableReplays(void);
- static void Update(void);
- static void FinishPlayback(void);
- static void EmptyReplayBuffer(void);
- static void Display(void);
- static void TriggerPlayback(uint8 cam_mode, float cam_x, float cam_y, float cam_z, bool load_scene);
- static void StreamAllNecessaryCarsAndPeds(void);
+ static void Init(void) REPLAY_STUB;
+ static void DisableReplays(void) REPLAY_STUB;
+ static void EnableReplays(void) REPLAY_STUB;
+ static void Update(void) REPLAY_STUB;
+ static void FinishPlayback(void) REPLAY_STUB;
+ static void EmptyReplayBuffer(void) REPLAY_STUB;
+ 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; }
+ static bool IsPlayingBack() { return false; }
+ static bool IsPlayingBackFromFile() { return false; }
+#else
static bool ShouldStandardCameraBeProcessed(void);
-
static bool IsPlayingBack() { return Mode == MODE_PLAYBACK; }
static bool IsPlayingBackFromFile() { return bPlayingBackFromFile; }
-
- static void RecordParticle(tParticleType type, CVector const& vecPos, CVector const& vecDir, float fSize, RwRGBA const& color);
private:
static void RecordThisFrame(void);
static void StorePedUpdate(CPed *ped, int id);
@@ -407,4 +417,5 @@ private:
/* Absolute nonsense, but how could this function end up being outside of class? */
friend void PlayReplayFromHD(void);
+#endif
};
diff --git a/src/control/Restart.cpp b/src/control/Restart.cpp
index 052e6b61..f63d2c07 100644
--- a/src/control/Restart.cpp
+++ b/src/control/Restart.cpp
@@ -83,7 +83,7 @@ CRestart::FindClosestHospitalRestartPoint(const CVector &pos, CVector *outPos, f
}
eLevelName curlevel = CTheZones::GetLevelFromPosition(&pos);
- float fMinDist = 16000000.0f;
+ float fMinDist = SQR(4000.0f);
int closestPoint = NUM_RESTART_POINTS;
// find closest point on this level
@@ -130,7 +130,7 @@ CRestart::FindClosestPoliceRestartPoint(const CVector &pos, CVector *outPos, flo
}
eLevelName curlevel = CTheZones::GetLevelFromPosition(&pos);
- float fMinDist = 16000000.0f;
+ float fMinDist = SQR(4000.0f);
int closestPoint = NUM_RESTART_POINTS;
// find closest point on this level
diff --git a/src/control/RoadBlocks.cpp b/src/control/RoadBlocks.cpp
index dee2cbe3..260978b3 100644
--- a/src/control/RoadBlocks.cpp
+++ b/src/control/RoadBlocks.cpp
@@ -97,11 +97,7 @@ CRoadBlocks::GenerateRoadBlockCopsForCar(CVehicle* pVehicle, int32 roadBlockType
pCopPed->m_nRoadblockVeh->RegisterReference((CEntity**)&pCopPed->m_nRoadblockVeh);
pCopPed->bCrouchWhenShooting = roadBlockType == 2 ? false : true;
if (pEntityToAttack) {
- if (pCopPed->m_pPointGunAt)
- pCopPed->m_pPointGunAt->CleanUpOldReference(&pCopPed->m_pPointGunAt);
- pCopPed->m_pPointGunAt = pEntityToAttack;
- if (pEntityToAttack)
- pEntityToAttack->RegisterReference(&pCopPed->m_pPointGunAt);
+ pCopPed->SetWeaponLockOnTarget(pEntityToAttack);
pCopPed->SetAttack(pEntityToAttack);
}
pCopPed->m_pMyVehicle = pVehicle;
diff --git a/src/control/SceneEdit.cpp b/src/control/SceneEdit.cpp
index 21512290..582f7a12 100644
--- a/src/control/SceneEdit.cpp
+++ b/src/control/SceneEdit.cpp
@@ -1,7 +1,7 @@
#include "common.h"
#include "SceneEdit.h"
-
+#ifdef GTA_SCENE_EDIT
#include "Automobile.h"
#include "Camera.h"
#include "CarCtrl.h"
@@ -1098,3 +1098,4 @@ bool CSceneEdit::SelectWeapon(void)
}
return false;
}
+#endif
diff --git a/src/control/SceneEdit.h b/src/control/SceneEdit.h
index 6dcefa31..7c8fb98a 100644
--- a/src/control/SceneEdit.h
+++ b/src/control/SceneEdit.h
@@ -1,5 +1,5 @@
#pragma once
-
+#ifdef GTA_SCENE_EDIT
class CPed;
class CVehicle;
@@ -93,3 +93,4 @@ public:
static void SelectVehicle(void);
static bool SelectWeapon(void);
};
+#endif
diff --git a/src/control/Script.cpp b/src/control/Script.cpp
index 3466a52e..9d5e347b 100644
--- a/src/control/Script.cpp
+++ b/src/control/Script.cpp
@@ -4,34 +4,19 @@
#include "ScriptCommands.h"
#include "AnimBlendAssociation.h"
-#include "Bike.h"
+#include "AudioManager.h"
#include "Boat.h"
-#include "BulletInfo.h"
#include "Camera.h"
-#include "CarAI.h"
#include "CarCtrl.h"
-#include "CarGen.h"
#include "CivilianPed.h"
#include "Clock.h"
-#include "ColStore.h"
#include "CopPed.h"
-#include "Coronas.h"
-#include "Cranes.h"
-#include "Credits.h"
-#include "CutsceneMgr.h"
#include "Debug.h"
#include "DMAudio.h"
-#include "Darkel.h"
#include "EmergencyPed.h"
-#include "Explosion.h"
#include "FileMgr.h"
-#include "Fire.h"
#include "Frontend.h"
-#include "Gangs.h"
-#include "GameLogic.h"
-#include "Garages.h"
#include "General.h"
-#include "Glass.h"
#ifdef MISSION_REPLAY
#include "GenericGameStorage.h"
#endif
@@ -40,68 +25,36 @@
#include "Hud.h"
#include "Lines.h"
#include "Messages.h"
-#include "ModelIndices.h"
#include "Pad.h"
-#include "Particle.h"
-#include "ParticleObject.h"
-#include "PedAttractor.h"
-#include "PedRoutes.h"
-#include "Phones.h"
#include "Pickups.h"
-#include "Plane.h"
-#include "PlayerInfo.h"
-#include "PlayerPed.h"
-#include "PointLights.h"
#include "Pools.h"
#include "Population.h"
-#include "PowerPoints.h"
-#include "ProjectileInfo.h"
-#include "Radar.h"
-#include "Record.h"
#include "Remote.h"
#include "Replay.h"
-#include "Restart.h"
-#include "RoadBlocks.h"
-#include "RpAnimBlend.h"
-#include "Rubbish.h"
-#include "SimpleModelInfo.h"
-#include "SetPieces.h"
-#include "Shadows.h"
-#include "SpecialFX.h"
-#include "Sprite.h"
#include "Stats.h"
#include "Streaming.h"
-#include "Text.h"
-#include "Timecycle.h"
-#include "TxdStore.h"
#include "User.h"
-#include "VisibilityPlugins.h"
-#include "WaterLevel.h"
+#include "Wanted.h"
#include "Weather.h"
-#include "World.h"
#include "Zones.h"
#include "main.h"
#include "Ropes.h"
-#include "MBlur.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
-#define PICKUP_PLACEMENT_OFFSET 0.5f
-#define PED_FIND_Z_OFFSET 5.0f
-#define COP_PED_FIND_Z_OFFSET 10.0f
-
-#ifdef USE_PRECISE_MEASUREMENT_CONVERTION
-#define METERS_IN_FOOT 0.3048f
-#define FEET_IN_METER 3.28084f
-#else
-#define METERS_IN_FOOT 0.3f
-#define FEET_IN_METER 3.33f
-#endif
-
uint8 CTheScripts::ScriptSpace[SIZE_SCRIPT_SPACE];
CRunningScript CTheScripts::ScriptsArray[MAX_NUM_SCRIPTS];
intro_text_line CTheScripts::IntroTextLines[MAX_NUM_INTRO_TEXT_LINES];
@@ -143,6 +96,10 @@ 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
@@ -173,6 +130,9 @@ float oldTargetX;
float oldTargetY;
int missionRetryScriptIndex;
bool doingMissionRetry;
+bool gbTryingPorn4Again;
+int IsInAmmunation;
+int MissionSkipLevel;
#endif
@@ -302,12 +262,12 @@ const tScriptCommandData commands[] = {
REGISTER_COMMAND(COMMAND_DIV_FLOAT_VAR_BY_FLOAT_LVAR, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, 0, " /="),
REGISTER_COMMAND(COMMAND_DIV_INT_LVAR_BY_INT_VAR, INPUT_ARGUMENTS(ARGTYPE_INT, ARGTYPE_INT,), OUTPUT_ARGUMENTS(), false, 0, " /="),
REGISTER_COMMAND(COMMAND_DIV_FLOAT_LVAR_BY_FLOAT_VAR, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, 0, " /="),
- REGISTER_COMMAND(COMMAND_ADD_TIMED_VAL_TO_FLOAT_VAR, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, 0, " -=@"),
- REGISTER_COMMAND(COMMAND_ADD_TIMED_VAL_TO_FLOAT_LVAR, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, 0, " -=@"),
- REGISTER_COMMAND(COMMAND_ADD_TIMED_FLOAT_VAR_TO_FLOAT_VAR, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, 0, " -=@"),
- REGISTER_COMMAND(COMMAND_ADD_TIMED_FLOAT_LVAR_TO_FLOAT_LVAR, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, 0, " -=@"),
- REGISTER_COMMAND(COMMAND_ADD_TIMED_FLOAT_LVAR_TO_FLOAT_VAR, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, 0, " -=@"),
- REGISTER_COMMAND(COMMAND_ADD_TIMED_FLOAT_VAR_TO_FLOAT_LVAR, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, 0, " -=@"),
+ REGISTER_COMMAND(COMMAND_ADD_TIMED_VAL_TO_FLOAT_VAR, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, 0, " +=@"),
+ REGISTER_COMMAND(COMMAND_ADD_TIMED_VAL_TO_FLOAT_LVAR, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, 0, " +=@"),
+ REGISTER_COMMAND(COMMAND_ADD_TIMED_FLOAT_VAR_TO_FLOAT_VAR, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, 0, " +=@"),
+ REGISTER_COMMAND(COMMAND_ADD_TIMED_FLOAT_LVAR_TO_FLOAT_LVAR, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, 0, " +=@"),
+ REGISTER_COMMAND(COMMAND_ADD_TIMED_FLOAT_LVAR_TO_FLOAT_VAR, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, 0, " +=@"),
+ REGISTER_COMMAND(COMMAND_ADD_TIMED_FLOAT_VAR_TO_FLOAT_LVAR, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, 0, " +=@"),
REGISTER_COMMAND(COMMAND_SUB_TIMED_VAL_FROM_FLOAT_VAR, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, 0, " -=@"),
REGISTER_COMMAND(COMMAND_SUB_TIMED_VAL_FROM_FLOAT_LVAR, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, 0, " -=@"),
REGISTER_COMMAND(COMMAND_SUB_TIMED_FLOAT_VAR_FROM_FLOAT_VAR, INPUT_ARGUMENTS(ARGTYPE_FLOAT, ARGTYPE_FLOAT,), OUTPUT_ARGUMENTS(), false, 0, " -=@"),
@@ -1618,6 +1578,39 @@ const tScriptCommandData commands[] = {
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
#undef INPUT_ARGUMENTS
@@ -1649,7 +1642,7 @@ static void PrintToLog(const char* format, ...)
#endif
-static void FlushLog()
+void FlushLog()
{
#ifdef USE_ADVANCED_SCRIPT_DEBUG_OUTPUT
#if SCRIPT_LOG_FILE_LEVEL == 1 || SCRIPT_LOG_FILE_LEVEL == 2
@@ -1659,7 +1652,6 @@ static void FlushLog()
#endif
}
-#define script_assert(_Expression) FlushLog(); assert(_Expression);
const uint32 CRunningScript::nSaveStructSize =
#ifdef COMPATIBLE_SAVES
136;
@@ -2340,6 +2332,7 @@ CRunningScript* CTheScripts::StartNewScript(uint32 ip)
pNew->Init();
pNew->SetIP(ip);
pNew->AddScriptToList(&pActiveScripts);
+ pNew->m_bIsActive = true;
return pNew;
}
@@ -2424,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
@@ -3076,8 +3071,10 @@ int8 CRunningScript::ProcessCommands0To99(int32 command)
#ifdef MISSION_REPLAY
if (m_bMissionFlag) {
CPlayerInfo* pPlayerInfo = &CWorld::Players[CWorld::PlayerInFocus];
+#if 0 // makeing autosave is pointless and is a bit buggy
if (pPlayerInfo->m_pPed->GetPedState() != PED_DEAD && pPlayerInfo->m_WBState == WBSTATE_PLAYING && !m_bDeatharrestExecuted)
SaveGameForPause(1);
+#endif
oldTargetX = oldTargetY = 0.0f;
if (AllowMissionReplay == 1)
AllowMissionReplay = 2;
@@ -4046,7 +4043,7 @@ int8 CRunningScript::ProcessCommands100To199(int32 command)
CollectParameters(&m_nIp, 2);
CVehicle* car = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
script_assert(car);
- car->AutoPilot.m_nDrivingStyle = (eCarDrivingStyle)ScriptParams[1];
+ car->AutoPilot.m_nDrivingStyle = (uint8)ScriptParams[1];
return 0;
}
case COMMAND_SET_CAR_MISSION:
@@ -4054,7 +4051,7 @@ int8 CRunningScript::ProcessCommands100To199(int32 command)
CollectParameters(&m_nIp, 2);
CVehicle* car = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
script_assert(car);
- car->AutoPilot.m_nCarMission = (eCarMission)ScriptParams[1];
+ car->AutoPilot.m_nCarMission = (uint8)ScriptParams[1];
car->AutoPilot.m_nAntiReverseTimer = CTimer::GetTimeInMilliseconds();
car->bEngineOn = true;
return 0;
@@ -4750,11427 +4747,6 @@ int8 CRunningScript::ProcessCommands200To299(int32 command)
return -1;
}
-int8 CRunningScript::ProcessCommands300To399(int32 command)
-{
- switch (command) {
- //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;
- */
- //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);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle);
- pVehicle->m_nDoorLock = (eCarLock)ScriptParams[1];
- return 0;
- }
- case COMMAND_SHAKE_CAM_WITH_POINT:
- CollectParameters(&m_nIp, 4);
- TheCamera.CamShake(ScriptParams[0] / 1000.0f,
- *(float*)&ScriptParams[1],
- *(float*)&ScriptParams[2],
- *(float*)&ScriptParams[3]);
- return 0;
- */
- case COMMAND_IS_CAR_MODEL:
- {
- CollectParameters(&m_nIp, 2);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle);
- UpdateCompareFlag(pVehicle->GetModelIndex() == ScriptParams[1]);
- return 0;
- }
- //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);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle);
- float x1 = *(float*)&ScriptParams[1];
- float y1 = *(float*)&ScriptParams[2];
- float x2 = *(float*)&ScriptParams[3];
- float y2 = *(float*)&ScriptParams[4];
- UpdateCompareFlag(pVehicle->GetStatus() == STATUS_WRECKED &&
- pVehicle->IsWithinArea(x1, y1, x2, y2));
- if (ScriptParams[5])
- CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, x1, y1, x2, y2, MAP_Z_LOW_LIMIT);
- if (CTheScripts::DbgFlag)
- CTheScripts::DrawDebugSquare(x1, y1, x2, y2);
- return 0;
- }
- case COMMAND_IS_CAR_DEAD_IN_AREA_3D:
- {
- CollectParameters(&m_nIp, 8);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle);
- float x1 = *(float*)&ScriptParams[1];
- float y1 = *(float*)&ScriptParams[2];
- float z1 = *(float*)&ScriptParams[3];
- float x2 = *(float*)&ScriptParams[4];
- float y2 = *(float*)&ScriptParams[5];
- float z2 = *(float*)&ScriptParams[6];
- UpdateCompareFlag(pVehicle->GetStatus() == STATUS_WRECKED &&
- pVehicle->IsWithinArea(x1, y1, z1, x2, y2, z2));
- if (ScriptParams[7])
- CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, x1, y1, x2, y2, (z1 + z2) / 2);
- if (CTheScripts::DbgFlag)
- CTheScripts::DrawDebugCube(x1, y1, z1, x2, y2, z2);
- return 0;
- }
- */
- //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;
- */
- //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(
- 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);
- CCarGenerator* pCarGen = &CTheCarGenerators::CarGeneratorArray[ScriptParams[0]];
- if (ScriptParams[1] == 0){
- pCarGen->SwitchOff();
- }else if (ScriptParams[1] <= 100){
- pCarGen->SwitchOn();
- pCarGen->SetUsesRemaining(ScriptParams[1]);
- }else{
- pCarGen->SwitchOn();
- }
- return 0;
- }
- /*
- case COMMAND_ADD_PAGER_MESSAGE:
- {
- wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- CollectParameters(&m_nIp, 3);
- 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++;
- 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:
- {
- script_assert(CTheScripts::ScriptSpace[m_nIp] == ARGUMENT_GLOBALVAR);
- m_nIp++;
- CUserDisplay::OnscnTimer.ClearClock((uint16)CTheScripts::Read2BytesFromScript(&m_nIp));
- return 0;
- }
- case COMMAND_DISPLAY_ONSCREEN_COUNTER:
- {
- script_assert(CTheScripts::ScriptSpace[m_nIp] == ARGUMENT_GLOBALVAR);
- m_nIp++;
- int16 counter = CTheScripts::Read2BytesFromScript(&m_nIp);
- CollectParameters(&m_nIp, 1);
- CUserDisplay::OnscnTimer.AddCounter(counter, ScriptParams[0], nil, 0);
- return 0;
- }
- case COMMAND_CLEAR_ONSCREEN_COUNTER:
- {
- script_assert(CTheScripts::ScriptSpace[m_nIp] == ARGUMENT_GLOBALVAR);
- m_nIp++;
- CUserDisplay::OnscnTimer.ClearCounter((uint16)CTheScripts::Read2BytesFromScript(&m_nIp));
- return 0;
- }
- 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, 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;
- }
- while (zone >= 0) {
- CTheZones::SetZoneCarInfo(zone, ScriptParams[0], ScriptParams[1], ScriptParams[11], gangDensities);
- zone = CTheZones::FindNextZoneByLabelAndReturnIndex(label, ZONE_INFO);
- }
- return 0;
- }
- //case COMMAND_IS_CHAR_IN_GANG_ZONE:
- case COMMAND_IS_CHAR_IN_ZONE:
- {
- CollectParameters(&m_nIp, 1);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- char label[12];
- CTheScripts::ReadTextLabelFromScript(&m_nIp, 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::GetNavigationZone(zone)));
- return 0;
- }
- //case COMMAND_SET_CAR_DENSITY:
- //case COMMAND_SET_PED_DENSITY:
- case COMMAND_POINT_CAMERA_AT_PLAYER:
- {
- CollectParameters(&m_nIp, 3);
- // ScriptParams[0] is unused.
- TheCamera.TakeControl(nil, ScriptParams[1], ScriptParams[2], CAMCONTROL_SCRIPT);
- return 0;
- }
- case COMMAND_POINT_CAMERA_AT_CAR:
- {
- CollectParameters(&m_nIp, 3);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- 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]);
- 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, 12);
- int16 zone = CTheZones::FindZoneByLabelAndReturnIndex(label, ZONE_INFO);
- if (zone < 0) {
- debug("Couldn't find zone - %s\n", label);
- return 0;
- }
- 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);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle && pVehicle->IsCar());
- CAutomobile* pCar = (CAutomobile*)pVehicle;
- UpdateCompareFlag(pCar->GetAllWheelsOffGround());
- return 0;
- }
- */
- case COMMAND_SET_FIXED_CAMERA_POSITION:
- {
- CollectParameters(&m_nIp, 6);
- TheCamera.SetCamPositionForFixedMode(
- CVector(*(float*)&ScriptParams[0], *(float*)&ScriptParams[1], *(float*)&ScriptParams[2]),
- CVector(*(float*)&ScriptParams[3], *(float*)&ScriptParams[4], *(float*)&ScriptParams[5]));
- return 0;
- }
- case COMMAND_POINT_CAMERA_AT_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);
- TheCamera.TakeControlNoEntity(pos, ScriptParams[3], CAMCONTROL_SCRIPT);
- return 0;
- }
- case COMMAND_ADD_BLIP_FOR_CAR_OLD:
- {
- CollectParameters(&m_nIp, 3);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle);
- CRadar::GetActualBlipArrayIndex(CollectNextParameterWithoutIncreasingPC(m_nIp));
- ScriptParams[0] = CRadar::SetEntityBlip(BLIP_CAR, ScriptParams[0], ScriptParams[1], (eBlipDisplay)ScriptParams[2]);
- StoreParameters(&m_nIp, 1);
- return 0;
- }
- case COMMAND_ADD_BLIP_FOR_CHAR_OLD:
- {
- CollectParameters(&m_nIp, 3);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- 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);
- 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]);
- return 0;
- case COMMAND_CHANGE_BLIP_COLOUR:
- CollectParameters(&m_nIp, 2);
- CRadar::ChangeBlipColour(ScriptParams[0], ScriptParams[1]);
- return 0;
- case COMMAND_DIM_BLIP:
- CollectParameters(&m_nIp, 2);
- CRadar::ChangeBlipBrightness(ScriptParams[0], ScriptParams[1]);
- return 0;
- case COMMAND_ADD_BLIP_FOR_COORD_OLD:
- {
- CollectParameters(&m_nIp, 5);
- 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));
- ScriptParams[0] = CRadar::SetCoordBlip(BLIP_COORD, pos, ScriptParams[3], (eBlipDisplay)ScriptParams[4]);
- StoreParameters(&m_nIp, 1);
- return 0;
- }
- case COMMAND_CHANGE_BLIP_SCALE:
- CollectParameters(&m_nIp, 2);
- CRadar::ChangeBlipScale(ScriptParams[0], ScriptParams[1]);
- return 0;
- case COMMAND_SET_FADING_COLOUR:
- CollectParameters(&m_nIp, 3);
- TheCamera.SetFadeColour(ScriptParams[0], ScriptParams[1], ScriptParams[2]);
- return 0;
- case COMMAND_DO_FADE:
- CollectParameters(&m_nIp, 2);
- TheCamera.Fade(ScriptParams[0] / 1000.0f, ScriptParams[1]);
- return 0;
- case COMMAND_GET_FADING_STATUS:
- UpdateCompareFlag(TheCamera.GetFading());
- return 0;
- case COMMAND_ADD_HOSPITAL_RESTART:
- {
- CollectParameters(&m_nIp, 4);
- CVector pos = *(CVector*)&ScriptParams[0];
- float angle = *(float*)&ScriptParams[3];
- if (pos.z <= MAP_Z_LOW_LIMIT)
- pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
- CRestart::AddHospitalRestartPoint(pos, angle);
- return 0;
- }
- case COMMAND_ADD_POLICE_RESTART:
- {
- CollectParameters(&m_nIp, 4);
- CVector pos = *(CVector*)&ScriptParams[0];
- float angle = *(float*)&ScriptParams[3];
- if (pos.z <= MAP_Z_LOW_LIMIT)
- pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
- CRestart::AddPoliceRestartPoint(pos, angle);
- return 0;
- }
- case COMMAND_OVERRIDE_NEXT_RESTART:
- {
- CollectParameters(&m_nIp, 4);
- CVector pos = *(CVector*)&ScriptParams[0];
- float angle = *(float*)&ScriptParams[3];
- if (pos.z <= MAP_Z_LOW_LIMIT)
- pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
- CRestart::OverrideNextRestart(pos, angle);
- return 0;
- }
- /*
- case COMMAND_DRAW_SHADOW:
- {
- CollectParameters(&m_nIp, 10);
- CVector pos = *(CVector*)&ScriptParams[1];
- float angle = *(float*)&ScriptParams[4];
- float length = *(float*)&ScriptParams[5];
- float x, y;
- if (angle != 0.0f){
- y = cos(angle) * length;
- x = sin(angle) * length;
- }else{
- y = length;
- x = 0.0f;
- }
- float frontX = -x;
- float frontY = y;
- float sideX = y;
- float sideY = x;
- 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();
- 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;
- }
- case COMMAND_SET_PLAYER_HEADING:
- {
- CollectParameters(&m_nIp, 2);
- CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
- 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;
- }
- case COMMAND_GET_CHAR_HEADING:
- {
- CollectParameters(&m_nIp, 1);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- float angle = pPed->bInVehicle ? pPed->m_pMyVehicle->GetForward().Heading() : pPed->GetForward().Heading();
- 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;
- }
- case COMMAND_SET_CHAR_HEADING:
- {
- CollectParameters(&m_nIp, 2);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- 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;
- }
- case COMMAND_GET_CAR_HEADING:
- {
- CollectParameters(&m_nIp, 1);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle);
- float angle = pVehicle->GetForward().Heading();
- 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;
- }
- case COMMAND_SET_CAR_HEADING:
- {
- CollectParameters(&m_nIp, 2);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle);
- pVehicle->SetHeading(DEGTORAD(*(float*)&ScriptParams[1]));
- return 0;
- }
- case COMMAND_GET_OBJECT_HEADING:
- {
- CollectParameters(&m_nIp, 1);
- CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
- script_assert(pObject);
- float angle = pObject->GetForward().Heading();
- 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;
- }
- case COMMAND_SET_OBJECT_HEADING:
- {
- CollectParameters(&m_nIp, 2);
- CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
- script_assert(pObject);
- CWorld::Remove(pObject);
- pObject->SetHeading(DEGTORAD(*(float*)&ScriptParams[1]));
- pObject->GetMatrix().UpdateRW();
- pObject->UpdateRwFrame();
- CWorld::Add(pObject);
- return 0;
- }
- /*
- case COMMAND_IS_PLAYER_TOUCHING_OBJECT:
- {
- CollectParameters(&m_nIp, 2);
- CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
- CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[1]);
- script_assert(pObject);
- CPhysical* pEntityToTest = pPed->bInVehicle ? (CPhysical*)pPed->m_pMyVehicle : pPed;
- UpdateCompareFlag(pEntityToTest->GetHasCollidedWith(pObject));
- return 0;
- }
- case COMMAND_IS_CHAR_TOUCHING_OBJECT:
- {
- CollectParameters(&m_nIp, 2);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[1]);
- script_assert(pObject);
- CPhysical* pEntityToTest = pPed->bInVehicle ? (CPhysical*)pPed->m_pMyVehicle : pPed;
- 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);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- pPed->SetAmmo((eWeaponType)ScriptParams[1], ScriptParams[2]);
- return 0;
- }
- */
- //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:
- return 0;
- //case COMMAND_DECLARE_BASE_BRIEF_ID_FOR_CONTACT:
- case COMMAND_IS_PLAYER_HEALTH_GREATER:
- {
- CollectParameters(&m_nIp, 2);
- CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
- UpdateCompareFlag(pPed->m_fHealth > ScriptParams[1]);
- return 0;
- }
- case COMMAND_IS_CHAR_HEALTH_GREATER:
- {
- CollectParameters(&m_nIp, 2);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- UpdateCompareFlag(pPed->m_fHealth > ScriptParams[1]);
- return 0;
- }
- case COMMAND_IS_CAR_HEALTH_GREATER:
- {
- CollectParameters(&m_nIp, 2);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle);
- UpdateCompareFlag(pVehicle->m_fHealth > ScriptParams[1]);
- return 0;
- }
- case COMMAND_ADD_BLIP_FOR_CAR:
- {
- CollectParameters(&m_nIp, 1);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle);
- CRadar::GetActualBlipArrayIndex(CollectNextParameterWithoutIncreasingPC(m_nIp));
- int handle = CRadar::SetEntityBlip(BLIP_CAR, ScriptParams[0], 0, BLIP_DISPLAY_BOTH);
- CRadar::ChangeBlipScale(handle, 3);
- ScriptParams[0] = handle;
- StoreParameters(&m_nIp, 1);
- return 0;
- }
- case COMMAND_ADD_BLIP_FOR_CHAR:
- {
- CollectParameters(&m_nIp, 1);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- CRadar::GetActualBlipArrayIndex(CollectNextParameterWithoutIncreasingPC(m_nIp));
- int handle = CRadar::SetEntityBlip(BLIP_CHAR, ScriptParams[0], 1, BLIP_DISPLAY_BOTH);
- CRadar::ChangeBlipScale(handle, 3);
- ScriptParams[0] = handle;
- StoreParameters(&m_nIp, 1);
- return 0;
- }
- case COMMAND_ADD_BLIP_FOR_OBJECT:
- {
- CollectParameters(&m_nIp, 1);
- CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
- script_assert(pObject);
- CRadar::GetActualBlipArrayIndex(CollectNextParameterWithoutIncreasingPC(m_nIp));
- int handle = CRadar::SetEntityBlip(BLIP_OBJECT, ScriptParams[0], 6, BLIP_DISPLAY_BOTH);
- CRadar::ChangeBlipScale(handle, 3);
- ScriptParams[0] = handle;
- StoreParameters(&m_nIp, 1);
- return 0;
- }
- case COMMAND_ADD_BLIP_FOR_CONTACT_POINT:
- {
- CollectParameters(&m_nIp, 3);
- 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 handle = CRadar::SetCoordBlip(BLIP_CONTACT_POINT, pos, 2, BLIP_DISPLAY_BOTH);
- CRadar::ChangeBlipScale(handle, 3);
- ScriptParams[0] = handle;
- StoreParameters(&m_nIp, 1);
- return 0;
- }
- case COMMAND_ADD_BLIP_FOR_COORD:
- {
- CollectParameters(&m_nIp, 3);
- 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 handle = CRadar::SetCoordBlip(BLIP_COORD, pos, 5, BLIP_DISPLAY_BOTH);
- CRadar::ChangeBlipScale(handle, 3);
- ScriptParams[0] = handle;
- StoreParameters(&m_nIp, 1);
- return 0;
- }
- case COMMAND_CHANGE_BLIP_DISPLAY:
- CollectParameters(&m_nIp, 2);
- CRadar::ChangeBlipDisplay(ScriptParams[0], (eBlipDisplay)ScriptParams[1]);
- return 0;
- case COMMAND_ADD_ONE_OFF_SOUND:
- {
- CollectParameters(&m_nIp, 4);
- switch (ScriptParams[3]) {
- case SCRIPT_SOUND_PART_MISSION_COMPLETE:
- DMAudio.PlayFrontEndSound(SOUND_PART_MISSION_COMPLETE, 0);
- return 0;
- case SCRIPT_SOUND_RACE_START_3:
- DMAudio.PlayFrontEndSound(SOUND_RACE_START_3, 0);
- return 0;
- case SCRIPT_SOUND_RACE_START_2:
- DMAudio.PlayFrontEndSound(SOUND_RACE_START_2, 0);
- return 0;
- case SCRIPT_SOUND_RACE_START_1:
- DMAudio.PlayFrontEndSound(SOUND_RACE_START_1, 0);
- return 0;
- 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;
- }
- if (!DMAudio.IsAudioInitialised())
- return 0;
- cAudioScriptObject* obj = new cAudioScriptObject();
- obj->Posn = *(CVector*)&ScriptParams[0];
- obj->AudioId = ScriptParams[3];
- obj->AudioEntity = AEHANDLE_NONE;
- DMAudio.CreateOneShotScriptObject(obj);
- return 0;
- }
- case COMMAND_ADD_CONTINUOUS_SOUND:
- {
- CollectParameters(&m_nIp, 4);
- 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;
- }
- case COMMAND_REMOVE_SOUND:
- {
- CollectParameters(&m_nIp, 1);
- cAudioScriptObject* obj = CPools::GetAudioScriptObjectPool()->GetAt(ScriptParams[0]);
- if (!obj){
- debug("REMOVE_SOUND - Sound doesn't exist\n");
- return 0;
- }
- DMAudio.DestroyLoopingScriptObject(obj->AudioEntity);
- delete obj;
- return 0;
- }
- case COMMAND_IS_CAR_STUCK_ON_ROOF:
- {
- CollectParameters(&m_nIp, 1);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle);
- UpdateCompareFlag(CTheScripts::UpsideDownCars.HasCarBeenUpsideDownForAWhile(ScriptParams[0]));
- return 0;
- }
- default:
- script_assert(0);
- }
- return -1;
-}
-
-int8 CRunningScript::ProcessCommands400To499(int32 command)
-{
- switch (command) {
- case COMMAND_ADD_UPSIDEDOWN_CAR_CHECK:
- {
- CollectParameters(&m_nIp, 1);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle);
- CTheScripts::UpsideDownCars.AddCarToCheck(ScriptParams[0]);
- return 0;
- }
- case COMMAND_REMOVE_UPSIDEDOWN_CAR_CHECK:
- {
- CollectParameters(&m_nIp, 1);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- CTheScripts::UpsideDownCars.RemoveCarFromCheck(ScriptParams[0]);
- return 0;
- }
- case COMMAND_SET_CHAR_OBJ_WAIT_ON_FOOT:
- {
- CollectParameters(&m_nIp, 1);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- pPed->bScriptObjectiveCompleted = false;
- pPed->SetObjective(OBJECTIVE_WAIT_ON_FOOT);
- return 0;
- }
- case COMMAND_SET_CHAR_OBJ_FLEE_ON_FOOT_TILL_SAFE:
- {
- CollectParameters(&m_nIp, 1);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- pPed->bScriptObjectiveCompleted = false;
- pPed->SetObjective(OBJECTIVE_FLEE_CHAR_ON_FOOT_TILL_SAFE);
- return 0;
- }
- case COMMAND_SET_CHAR_OBJ_GUARD_SPOT:
- {
- CollectParameters(&m_nIp, 4);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- CVector pos = *(CVector*)&ScriptParams[1];
- if (pos.z <= MAP_Z_LOW_LIMIT)
- pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
- pPed->bScriptObjectiveCompleted = false;
- pPed->SetObjective(OBJECTIVE_GUARD_SPOT, pos);
- return 0;
- }
- /*
- case COMMAND_SET_CHAR_OBJ_GUARD_AREA:
- {
- CollectParameters(&m_nIp, 5);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- float infX = *(float*)&ScriptParams[1];
- float infY = *(float*)&ScriptParams[2];
- float supX = *(float*)&ScriptParams[3];
- float supY = *(float*)&ScriptParams[4];
- if (infX > supX){
- infX = *(float*)&ScriptParams[3];
- supX = *(float*)&ScriptParams[1];
- }
- if (infY > supY) {
- infY = *(float*)&ScriptParams[4];
- supY = *(float*)&ScriptParams[2];
- }
- CVector pos;
- pos.x = (infX + supX) / 2;
- pos.y = (infY + supY) / 2;
- pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
- float radius = Max(pos.x - infX, pos.y - infY);
- pPed->bScriptObjectiveCompleted = false;
- pPed->SetObjective(OBJECTIVE_GUARD_SPOT, pos, radius);
- return 0;
- }
- case COMMAND_SET_CHAR_OBJ_WAIT_IN_CAR:
- {
- CollectParameters(&m_nIp, 1);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- pPed->bScriptObjectiveCompleted = false;
- 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:
- case COMMAND_IS_PLAYER_STOPPED_IN_AREA_ON_FOOT_2D:
- case COMMAND_IS_PLAYER_STOPPED_IN_AREA_IN_CAR_2D:
- case COMMAND_IS_PLAYER_IN_AREA_ON_FOOT_3D:
- case COMMAND_IS_PLAYER_IN_AREA_IN_CAR_3D:
- case COMMAND_IS_PLAYER_STOPPED_IN_AREA_3D:
- case COMMAND_IS_PLAYER_STOPPED_IN_AREA_ON_FOOT_3D:
- case COMMAND_IS_PLAYER_STOPPED_IN_AREA_IN_CAR_3D:
- PlayerInAreaCheckCommand(command, &m_nIp);
- return 0;
- case COMMAND_IS_CHAR_IN_AREA_ON_FOOT_2D:
- case COMMAND_IS_CHAR_IN_AREA_IN_CAR_2D:
- case COMMAND_IS_CHAR_STOPPED_IN_AREA_2D:
- case COMMAND_IS_CHAR_STOPPED_IN_AREA_ON_FOOT_2D:
- case COMMAND_IS_CHAR_STOPPED_IN_AREA_IN_CAR_2D:
- case COMMAND_IS_CHAR_IN_AREA_ON_FOOT_3D:
- case COMMAND_IS_CHAR_IN_AREA_IN_CAR_3D:
- case COMMAND_IS_CHAR_STOPPED_IN_AREA_3D:
- case COMMAND_IS_CHAR_STOPPED_IN_AREA_ON_FOOT_3D:
- case COMMAND_IS_CHAR_STOPPED_IN_AREA_IN_CAR_3D:
- CharInAreaCheckCommand(command, &m_nIp);
- return 0;
- case COMMAND_IS_CAR_STOPPED_IN_AREA_2D:
- case COMMAND_IS_CAR_STOPPED_IN_AREA_3D:
- CarInAreaCheckCommand(command, &m_nIp);
- return 0;
- case COMMAND_LOCATE_CAR_2D:
- case COMMAND_LOCATE_STOPPED_CAR_2D:
- case COMMAND_LOCATE_CAR_3D:
- case COMMAND_LOCATE_STOPPED_CAR_3D:
- LocateCarCommand(command, &m_nIp);
- return 0;
- case COMMAND_GIVE_WEAPON_TO_PLAYER:
- {
- CollectParameters(&m_nIp, 3);
- CPlayerPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
- script_assert(pPed);
- pPed->m_nSelectedWepSlot = pPed->GiveWeapon((eWeaponType)ScriptParams[1], ScriptParams[2]);
- return 0;
- }
- case COMMAND_GIVE_WEAPON_TO_CHAR:
- {
- CollectParameters(&m_nIp, 3);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- pPed->SetCurrentWeapon(pPed->GiveWeapon((eWeaponType)ScriptParams[1], ScriptParams[2]));
- if (pPed->bInVehicle && pPed->m_pMyVehicle)
- pPed->RemoveWeaponModel(CWeaponInfo::GetWeaponInfo(pPed->m_weapons[pPed->m_currentWeapon].m_eWeaponType)->m_nModelId);
- return 0;
- }
- //case COMMAND_GIVE_WEAPON_TO_CAR:
- case COMMAND_SET_PLAYER_CONTROL:
- {
- CollectParameters(&m_nIp, 2);
- CPlayerInfo* pPlayer = &CWorld::Players[ScriptParams[0]];
- if (ScriptParams[1]){
- pPlayer->MakePlayerSafe(false);
- if (strcmp(m_abScriptName, "serg1") == 0) // Four Iron
- pPlayer->m_pPed->ClearFollowPath();
- }else{
- pPlayer->MakePlayerSafe(true);
- }
- return 0;
- }
- case COMMAND_FORCE_WEATHER:
- CollectParameters(&m_nIp, 1);
- CWeather::ForceWeather(ScriptParams[0]);
- return 0;
- case COMMAND_FORCE_WEATHER_NOW:
- CollectParameters(&m_nIp, 1);
- CWeather::ForceWeatherNow(ScriptParams[0]);
- return 0;
- case COMMAND_RELEASE_WEATHER:
- CWeather::ReleaseWeather();
- return 0;
- case COMMAND_SET_CURRENT_PLAYER_WEAPON:
- {
- CollectParameters(&m_nIp, 2);
- CPlayerPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
- for (int i = 0; i < TOTAL_WEAPON_SLOTS; i++){
- if (pPed->m_weapons[i].m_eWeaponType == ScriptParams[1])
- pPed->m_nSelectedWepSlot = i;
- }
- return 0;
- }
- case COMMAND_SET_CURRENT_CHAR_WEAPON:
- {
- CollectParameters(&m_nIp, 2);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- for (int i = 0; i < TOTAL_WEAPON_SLOTS; i++) {
- if (pPed->m_weapons[i].m_eWeaponType == ScriptParams[1])
- pPed->SetCurrentWeapon(i);
- }
- return 0;
- }
- //case COMMAND_SET_CURRENT_CAR_WEAPON:
- case COMMAND_GET_OBJECT_COORDINATES:
- {
- CollectParameters(&m_nIp, 1);
- CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
- script_assert(pObject);
- *(CVector*)&ScriptParams[0] = pObject->GetPosition();
- StoreParameters(&m_nIp, 3);
- return 0;
- }
- case COMMAND_SET_OBJECT_COORDINATES:
- {
- CollectParameters(&m_nIp, 4);
- CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
- script_assert(pObject);
- CVector pos = *(CVector*)&ScriptParams[1];
- if (pos.z <= MAP_Z_LOW_LIMIT)
- pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
- pObject->Teleport(pos);
- CTheScripts::ClearSpaceForMissionEntity(pos, pObject);
- return 0;
- }
- case COMMAND_GET_GAME_TIMER:
- ScriptParams[0] = CTimer::GetTimeInMilliseconds();
- StoreParameters(&m_nIp, 1);
- return 0;
- case COMMAND_TURN_CHAR_TO_FACE_COORD:
- {
- CollectParameters(&m_nIp, 4);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- CVehicle* pVehicle;
- CVector pos;
- if (pPed->bInVehicle)
- pVehicle = pPed->m_pMyVehicle;
- else
- pVehicle = nil;
- if (pVehicle)
- pos = pVehicle->GetPosition();
- else
- pos = pPed->GetPosition();
- float heading = CGeneral::GetATanOfXY(pos.x - *(float*)&ScriptParams[1], pos.y - *(float*)&ScriptParams[2]);
- heading += HALFPI;
- if (heading > TWOPI)
- heading -= TWOPI;
- if (!pVehicle){
- pPed->m_fRotationCur = heading;
- pPed->m_fRotationDest = heading;
- pPed->SetHeading(heading);
- }
- return 0;
- }
- case COMMAND_TURN_PLAYER_TO_FACE_COORD:
- {
- CollectParameters(&m_nIp, 4);
- CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
- script_assert(pPed);
- CVehicle* pVehicle;
- CVector pos;
- if (pPed->bInVehicle)
- pVehicle = pPed->m_pMyVehicle;
- else
- pVehicle = nil;
- if (pVehicle)
- pos = pVehicle->GetPosition();
- else
- pos = pPed->GetPosition();
- float heading = CGeneral::GetATanOfXY(pos.x - *(float*)&ScriptParams[1], pos.y - *(float*)&ScriptParams[2]);
- heading += HALFPI;
- if (heading > TWOPI)
- heading -= TWOPI;
- if (!pVehicle) {
- pPed->m_fRotationCur = heading;
- pPed->m_fRotationDest = heading;
- pPed->SetHeading(heading);
- }
- return 0;
- }
- case COMMAND_STORE_WANTED_LEVEL:
- {
- CollectParameters(&m_nIp, 1);
- CPlayerPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
- script_assert(pPed);
- ScriptParams[0] = pPed->m_pWanted->m_nWantedLevel;
- StoreParameters(&m_nIp, 1);
- return 0;
- }
- case COMMAND_IS_CAR_STOPPED:
- {
- CollectParameters(&m_nIp, 1);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle);
- UpdateCompareFlag(CTheScripts::IsVehicleStopped(pVehicle));
- return 0;
- }
- case COMMAND_MARK_CHAR_AS_NO_LONGER_NEEDED:
- {
- CollectParameters(&m_nIp, 1);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- CTheScripts::CleanUpThisPed(pPed);
- if (m_bIsMissionScript)
- CTheScripts::MissionCleanup.RemoveEntityFromList(ScriptParams[0], CLEANUP_CHAR);
- return 0;
- }
- case COMMAND_MARK_CAR_AS_NO_LONGER_NEEDED:
- {
- CollectParameters(&m_nIp, 1);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- CTheScripts::CleanUpThisVehicle(pVehicle);
- if (m_bIsMissionScript)
- CTheScripts::MissionCleanup.RemoveEntityFromList(ScriptParams[0], CLEANUP_CAR);
- return 0;
- }
- case COMMAND_MARK_OBJECT_AS_NO_LONGER_NEEDED:
- {
- CollectParameters(&m_nIp, 1);
- CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
- CTheScripts::CleanUpThisObject(pObject);
- if (m_bIsMissionScript)
- CTheScripts::MissionCleanup.RemoveEntityFromList(ScriptParams[0], CLEANUP_OBJECT);
- return 0;
- }
- case COMMAND_DONT_REMOVE_CHAR:
- {
- CollectParameters(&m_nIp, 1);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- CTheScripts::MissionCleanup.RemoveEntityFromList(ScriptParams[0], CLEANUP_CHAR);
- return 0;
- }
- case COMMAND_DONT_REMOVE_CAR:
- {
- CollectParameters(&m_nIp, 1);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle);
- CTheScripts::MissionCleanup.RemoveEntityFromList(ScriptParams[0], CLEANUP_CAR);
- return 0;
- }
- case COMMAND_DONT_REMOVE_OBJECT:
- {
- CollectParameters(&m_nIp, 1);
- CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
- script_assert(pObject);
- CTheScripts::MissionCleanup.RemoveEntityFromList(ScriptParams[0], CLEANUP_OBJECT);
- return 0;
- }
- case COMMAND_CREATE_CHAR_AS_PASSENGER:
- {
- CollectParameters(&m_nIp, 4);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle);
- switch (ScriptParams[2]) {
- case MI_COP:
- if (ScriptParams[1] == PEDTYPE_COP)
- ScriptParams[2] = COP_STREET;
- break;
- case MI_SWAT:
- if (ScriptParams[1] == PEDTYPE_COP)
- ScriptParams[2] = COP_SWAT;
- break;
- case MI_FBI:
- if (ScriptParams[1] == PEDTYPE_COP)
- ScriptParams[2] = COP_FBI;
- break;
- case MI_ARMY:
- if (ScriptParams[1] == PEDTYPE_COP)
- ScriptParams[2] = COP_ARMY;
- break;
- case MI_MEDIC:
- if (ScriptParams[1] == PEDTYPE_EMERGENCY)
- ScriptParams[2] = PEDTYPE_EMERGENCY;
- break;
- case MI_FIREMAN:
- if (ScriptParams[1] == PEDTYPE_FIREMAN)
- ScriptParams[2] = PEDTYPE_FIREMAN;
- break;
- default:
- break;
- }
- CPed* pPed;
- if (ScriptParams[1] == PEDTYPE_COP)
- pPed = new CCopPed((eCopType)ScriptParams[2]);
- else if (ScriptParams[1] == PEDTYPE_EMERGENCY || ScriptParams[1] == PEDTYPE_FIREMAN)
- pPed = new CEmergencyPed(ScriptParams[2]);
- else
- pPed = new CCivilianPed((ePedType)ScriptParams[1], ScriptParams[2]);
- 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++;
- if (ScriptParams[3] >= 0)
- pVehicle->AddPassenger(pPed, ScriptParams[3]);
- else
- pVehicle->AddPassenger(pPed);
- pPed->m_pMyVehicle = pVehicle;
- pPed->m_pMyVehicle->RegisterReference((CEntity**)&pPed->m_pMyVehicle);
- pPed->bInVehicle = true;
- pVehicle->SetStatus(STATUS_PHYSICS);
- pPed->SetPedState(PED_DRIVING);
- pPed->bUsesCollision = false;
- pPed->AddInCarAnims(pVehicle, false);
- pPed->m_nZoneLevel = CTheZones::GetLevelFromPosition(&pPed->GetPosition());
- CWorld::Add(pPed);
- ScriptParams[0] = CPools::GetPedPool()->GetIndex(pPed);
- StoreParameters(&m_nIp, 1);
- if (m_bIsMissionScript)
- CTheScripts::MissionCleanup.AddEntityToList(ScriptParams[0], CLEANUP_CHAR);
- return 0;
- }
- case COMMAND_SET_CHAR_OBJ_KILL_CHAR_ON_FOOT:
- {
- CollectParameters(&m_nIp, 2);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- CPed* pTarget = CPools::GetPedPool()->GetAt(ScriptParams[1]);
- pPed->bScriptObjectiveCompleted = false;
- pPed->SetObjective(OBJECTIVE_KILL_CHAR_ON_FOOT, pTarget);
- return 0;
- }
- case COMMAND_SET_CHAR_OBJ_KILL_PLAYER_ON_FOOT:
- {
- CollectParameters(&m_nIp, 2);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- CPed* pTarget = CWorld::Players[ScriptParams[1]].m_pPed;
- pPed->bScriptObjectiveCompleted = false;
- pPed->SetObjective(OBJECTIVE_KILL_CHAR_ON_FOOT, pTarget);
- return 0;
- }
- case COMMAND_SET_CHAR_OBJ_KILL_CHAR_ANY_MEANS:
- {
- CollectParameters(&m_nIp, 2);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- CPed* pTarget = CPools::GetPedPool()->GetAt(ScriptParams[1]);
- pPed->bScriptObjectiveCompleted = false;
- pPed->SetObjective(OBJECTIVE_KILL_CHAR_ANY_MEANS, pTarget);
- return 0;
- }
- case COMMAND_SET_CHAR_OBJ_KILL_PLAYER_ANY_MEANS:
- {
- CollectParameters(&m_nIp, 2);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- CPed* pTarget = CWorld::Players[ScriptParams[1]].m_pPed;
- pPed->bScriptObjectiveCompleted = false;
- 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);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- CPed* pTarget = CPools::GetPedPool()->GetAt(ScriptParams[1]);
- pPed->bScriptObjectiveCompleted = false;
- 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);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- CPed* pTarget = CWorld::Players[ScriptParams[1]].m_pPed;
- pPed->bScriptObjectiveCompleted = false;
- pPed->SetObjective(OBJECTIVE_FLEE_CHAR_ON_FOOT_TILL_SAFE, pTarget);
- return 0;
- }
- case COMMAND_SET_CHAR_OBJ_FLEE_CHAR_ON_FOOT_ALWAYS:
- {
- CollectParameters(&m_nIp, 2);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- CPed* pTarget = CPools::GetPedPool()->GetAt(ScriptParams[1]);
- pPed->bScriptObjectiveCompleted = false;
- pPed->SetObjective(OBJECTIVE_FLEE_CHAR_ON_FOOT_ALWAYS, pTarget);
- return 0;
- }
- case COMMAND_SET_CHAR_OBJ_FLEE_PLAYER_ON_FOOT_ALWAYS:
- {
- CollectParameters(&m_nIp, 2);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- CPed* pTarget = CWorld::Players[ScriptParams[1]].m_pPed;
- pPed->bScriptObjectiveCompleted = false;
- pPed->SetObjective(OBJECTIVE_FLEE_CHAR_ON_FOOT_ALWAYS, pTarget);
- return 0;
- }
- case COMMAND_SET_CHAR_OBJ_GOTO_CHAR_ON_FOOT:
- {
- CollectParameters(&m_nIp, 2);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- CPed* pTarget = CPools::GetPedPool()->GetAt(ScriptParams[1]);
- pPed->bScriptObjectiveCompleted = false;
- pPed->SetObjective(OBJECTIVE_GOTO_CHAR_ON_FOOT, pTarget);
- return 0;
- }
- case COMMAND_SET_CHAR_OBJ_GOTO_PLAYER_ON_FOOT:
- {
- CollectParameters(&m_nIp, 2);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- CPed* pTarget = CWorld::Players[ScriptParams[1]].m_pPed;
- pPed->bScriptObjectiveCompleted = false;
- pPed->SetObjective(OBJECTIVE_GOTO_CHAR_ON_FOOT, pTarget);
- return 0;
- }
- case COMMAND_SET_CHAR_OBJ_LEAVE_CAR:
- {
- 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_LEAVE_CAR, pVehicle);
- return 0;
- }
- case COMMAND_SET_CHAR_OBJ_ENTER_CAR_AS_PASSENGER:
- {
- 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_ENTER_CAR_AS_PASSENGER, pVehicle);
- return 0;
- }
- case COMMAND_SET_CHAR_OBJ_ENTER_CAR_AS_DRIVER:
- {
- 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_ENTER_CAR_AS_DRIVER, pVehicle);
- return 0;
- }
- //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);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[1]);
- pPed->bScriptObjectiveCompleted = false;
- pPed->SetObjective(OBJECTIVE_DESTROY_CAR, pVehicle);
- return 0;
- }
- /*
- case COMMAND_SET_CHAR_OBJ_GOTO_AREA_ON_FOOT:
- {
- CollectParameters(&m_nIp, 5);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- float infX = *(float*)&ScriptParams[1];
- float infY = *(float*)&ScriptParams[2];
- float supX = *(float*)&ScriptParams[3];
- float supY = *(float*)&ScriptParams[4];
- if (infX > supX) {
- infX = *(float*)&ScriptParams[3];
- supX = *(float*)&ScriptParams[1];
- }
- if (infY > supY) {
- infY = *(float*)&ScriptParams[4];
- supY = *(float*)&ScriptParams[2];
- }
- CVector pos;
- pos.x = (infX + supX) / 2;
- pos.y = (infY + supY) / 2;
- pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
- float radius = Max(pos.x - infX, pos.y - infY);
- pPed->bScriptObjectiveCompleted = false;
- pPed->SetObjective(OBJECTIVE_GOTO_AREA_ON_FOOT, pos, radius);
- return 0;
- }
- */
- //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);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- CPed* pTarget = CPools::GetPedPool()->GetAt(ScriptParams[1]);
- pPed->SetObjective(OBJECTIVE_SET_LEADER, pTarget);
- return 0;
- }
- case COMMAND_SET_PLAYER_AS_LEADER:
- {
- CollectParameters(&m_nIp, 2);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- CPed* pTarget = CWorld::Players[ScriptParams[1]].m_pPed;
- pPed->SetObjective(OBJECTIVE_SET_LEADER, pTarget);
- return 0;
- }
- case COMMAND_LEAVE_GROUP:
- {
- CollectParameters(&m_nIp, 1);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- pPed->ClearLeader();
- return 0;
- }
- case COMMAND_SET_CHAR_OBJ_FOLLOW_ROUTE:
- {
- CollectParameters(&m_nIp, 3);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- pPed->bScriptObjectiveCompleted = false;
- pPed->SetObjective(OBJECTIVE_FOLLOW_ROUTE, ScriptParams[1], ScriptParams[2]);
- return 0;
- }
- case COMMAND_ADD_ROUTE_POINT:
- {
- CollectParameters(&m_nIp, 4);
- CRouteNode::AddRoutePoint(ScriptParams[0], *(CVector*)&ScriptParams[1]);
- return 0;
- }
- case COMMAND_PRINT_WITH_NUMBER_BIG:
- {
- wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- CollectParameters(&m_nIp, 3);
- CMessages::AddBigMessageWithNumber(text, ScriptParams[1], ScriptParams[2] - 1, ScriptParams[0], -1, -1, -1, -1, -1);
- return 0;
- }
- case COMMAND_PRINT_WITH_NUMBER:
- {
- wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- CollectParameters(&m_nIp, 3);
- CMessages::AddMessageWithNumber(text, ScriptParams[1], ScriptParams[2], ScriptParams[0], -1, -1, -1, -1, -1);
- return 0;
- }
- case COMMAND_PRINT_WITH_NUMBER_NOW:
- {
- wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- CollectParameters(&m_nIp, 3);
- CMessages::AddMessageJumpQWithNumber(text, ScriptParams[1], ScriptParams[2], ScriptParams[0], -1, -1, -1, -1, -1);
- return 0;
- }
- //case COMMAND_PRINT_WITH_NUMBER_SOON:
- case COMMAND_SWITCH_ROADS_ON:
- {
- CollectParameters(&m_nIp, 6);
- 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];
- }
- ThePaths.SwitchRoadsOffInArea(infX, supX, infY, supY, infZ, supZ, false);
- return 0;
- }
- case COMMAND_SWITCH_ROADS_OFF:
- {
- CollectParameters(&m_nIp, 6);
- 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];
- }
- ThePaths.SwitchRoadsOffInArea(infX, supX, infY, supY, infZ, supZ, true);
- return 0;
- }
- case COMMAND_GET_NUMBER_OF_PASSENGERS:
- {
- CollectParameters(&m_nIp, 1);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle);
- ScriptParams[0] = pVehicle->m_nNumPassengers;
- StoreParameters(&m_nIp, 1);
- return 0;
- }
- case COMMAND_GET_MAXIMUM_NUMBER_OF_PASSENGERS:
- {
- CollectParameters(&m_nIp, 1);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle);
- ScriptParams[0] = pVehicle->m_nNumMaxPassengers;
- StoreParameters(&m_nIp, 1);
- return 0;
- }
- case COMMAND_SET_CAR_DENSITY_MULTIPLIER:
- {
- CollectParameters(&m_nIp, 1);
- CCarCtrl::CarDensityMultiplier = *(float*)&ScriptParams[0];
- return 0;
- }
- case COMMAND_SET_CAR_HEAVY:
- {
- CollectParameters(&m_nIp, 2);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle);
- 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:
- {
- CollectParameters(&m_nIp, 1);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- pPed->m_fearFlags = 0;
- return 0;
- }
- /*
- case COMMAND_ACTIVATE_CRANE:
- {
- CollectParameters(&m_nIp, 10);
- float infX = *(float*)&ScriptParams[2];
- float infY = *(float*)&ScriptParams[3];
- float supX = *(float*)&ScriptParams[4];
- float supY = *(float*)&ScriptParams[5];
- if (infX > supX) {
- infX = *(float*)&ScriptParams[4];
- supX = *(float*)&ScriptParams[2];
- }
- if (infY > supY) {
- infY = *(float*)&ScriptParams[5];
- supY = *(float*)&ScriptParams[3];
- }
- CCranes::ActivateCrane(infX, supX, infY, supY,
- *(float*)&ScriptParams[6], *(float*)&ScriptParams[7], *(float*)&ScriptParams[8],
- DEGTORAD(*(float*)&ScriptParams[9]), false, false,
- *(float*)&ScriptParams[0], *(float*)&ScriptParams[1]);
- return 0;
- }
- case COMMAND_DEACTIVATE_CRANE:
- {
- CollectParameters(&m_nIp, 2);
- 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;
- }
- //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);
- UpdateCompareFlag(pVehicle->m_nCollisionRecords == 0);
- return 0;
- }
- default:
- script_assert(0);
- }
- return -1;
-}
-
-int8 CRunningScript::ProcessCommands500To599(int32 command)
-{
- switch (command) {
- case COMMAND_IS_CAR_UPSIDEDOWN:
- {
- CollectParameters(&m_nIp, 1);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle);
- UpdateCompareFlag(pVehicle->GetUp().z <= -0.97f);
- return 0;
- }
- case COMMAND_GET_PLAYER_CHAR:
- {
- CollectParameters(&m_nIp, 1);
- CPlayerPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
- script_assert(pPed);
- ScriptParams[0] = CPools::GetPedPool()->GetIndex(pPed);
- StoreParameters(&m_nIp, 1);
- return 0;
- }
- case COMMAND_CANCEL_OVERRIDE_RESTART:
- CRestart::CancelOverrideRestart();
- return 0;
- case COMMAND_SET_POLICE_IGNORE_PLAYER:
- {
- CollectParameters(&m_nIp, 2);
- CPlayerPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
- script_assert(pPed);
- if (ScriptParams[1]) {
- pPed->m_pWanted->m_bIgnoredByCops = true;
- CWorld::StopAllLawEnforcersInTheirTracks();
- }
- else {
- pPed->m_pWanted->m_bIgnoredByCops = false;
- }
- return 0;
- }
- /*
- case COMMAND_ADD_PAGER_MESSAGE_WITH_NUMBER:
- {
- wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- CollectParameters(&m_nIp, 4);
- CUserDisplay::Pager.AddMessageWithNumber(text, ScriptParams[0], -1, -1, -1, -1, -1,
- ScriptParams[1], ScriptParams[2], ScriptParams[3]);
- return 0;
- }
- */
- case COMMAND_START_KILL_FRENZY:
- {
- wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- CollectParameters(&m_nIp, 8);
- CDarkel::StartFrenzy((eWeaponType)ScriptParams[0], ScriptParams[1], ScriptParams[2],
- ScriptParams[3], text, ScriptParams[4], ScriptParams[5],
- ScriptParams[6], ScriptParams[7] != 0, false);
- return 0;
- }
- case COMMAND_READ_KILL_FRENZY_STATUS:
- {
- ScriptParams[0] = CDarkel::ReadStatus();
- StoreParameters(&m_nIp, 1);
- return 0;
- }
- case COMMAND_SQRT:
- {
- CollectParameters(&m_nIp, 1);
- *(float*)&ScriptParams[0] = Sqrt(*(float*)&ScriptParams[0]);
- StoreParameters(&m_nIp, 1);
- return 0;
- }
- case COMMAND_LOCATE_PLAYER_ANY_MEANS_CAR_2D:
- case COMMAND_LOCATE_PLAYER_ON_FOOT_CAR_2D:
- case COMMAND_LOCATE_PLAYER_IN_CAR_CAR_2D:
- case COMMAND_LOCATE_PLAYER_ANY_MEANS_CAR_3D:
- case COMMAND_LOCATE_PLAYER_ON_FOOT_CAR_3D:
- case COMMAND_LOCATE_PLAYER_IN_CAR_CAR_3D:
- LocatePlayerCarCommand(command, &m_nIp);
- return 0;
- case COMMAND_LOCATE_CHAR_ANY_MEANS_CAR_2D:
- case COMMAND_LOCATE_CHAR_ON_FOOT_CAR_2D:
- case COMMAND_LOCATE_CHAR_IN_CAR_CAR_2D:
- case COMMAND_LOCATE_CHAR_ANY_MEANS_CAR_3D:
- case COMMAND_LOCATE_CHAR_ON_FOOT_CAR_3D:
- case COMMAND_LOCATE_CHAR_IN_CAR_CAR_3D:
- LocateCharCarCommand(command, &m_nIp);
- return 0;
- case COMMAND_GENERATE_RANDOM_FLOAT_IN_RANGE:
- CollectParameters(&m_nIp, 2);
- *(float*)&ScriptParams[0] = CGeneral::GetRandomNumberInRange(*(float*)&ScriptParams[0], *(float*)&ScriptParams[1]);
- StoreParameters(&m_nIp, 1);
- return 0;
- case COMMAND_GENERATE_RANDOM_INT_IN_RANGE:
- CollectParameters(&m_nIp, 2);
- ScriptParams[0] = CGeneral::GetRandomNumberInRange(ScriptParams[0], ScriptParams[1]);
- StoreParameters(&m_nIp, 1);
- return 0;
- case COMMAND_LOCK_CAR_DOORS:
- {
- CollectParameters(&m_nIp, 2);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle);
- pVehicle->m_nDoorLock = (eCarLock)ScriptParams[1];
- return 0;
- }
- case COMMAND_EXPLODE_CAR:
- {
- CollectParameters(&m_nIp, 1);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle);
- pVehicle->BlowUpCar(nil);
- return 0;
- }
- case COMMAND_ADD_EXPLOSION:
- CollectParameters(&m_nIp, 4);
- CExplosion::AddExplosion(nil, nil, (eExplosionType)ScriptParams[3], *(CVector*)&ScriptParams[0], 0, true);
- return 0;
-
- case COMMAND_IS_CAR_UPRIGHT:
- {
- CollectParameters(&m_nIp, 1);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle);
- UpdateCompareFlag(pVehicle->GetUp().z >= 0.0f);
- return 0;
- }
- case COMMAND_TURN_CHAR_TO_FACE_CHAR:
- {
- CollectParameters(&m_nIp, 2);
- CPed* pSourcePed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- CPed* pTargetPed = CPools::GetPedPool()->GetAt(ScriptParams[1]);
- CVehicle* pVehicle = pSourcePed->bInVehicle ? pSourcePed->m_pMyVehicle : nil;
- CVector2D sourcePos = pSourcePed->bInVehicle ? pVehicle->GetPosition() : pSourcePed->GetPosition();
- CVector2D targetPos = pTargetPed->bInVehicle ? pTargetPed->m_pMyVehicle->GetPosition() : pTargetPed->GetPosition();
- float angle = CGeneral::GetATanOfXY(sourcePos.x - targetPos.x, sourcePos.y - targetPos.y) + HALFPI;
- if (angle > TWOPI)
- angle -= TWOPI;
- if (!pVehicle) {
- pSourcePed->m_fRotationCur = angle;
- pSourcePed->m_fRotationDest = angle;
- pSourcePed->SetHeading(angle);
- }
- return 0;
- }
- case COMMAND_TURN_CHAR_TO_FACE_PLAYER:
- {
- CollectParameters(&m_nIp, 2);
- CPed* pSourcePed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- CPed* pTargetPed = CWorld::Players[ScriptParams[1]].m_pPed;
- CVehicle* pVehicle = pSourcePed->bInVehicle ? pSourcePed->m_pMyVehicle : nil;
- CVector2D sourcePos = pSourcePed->bInVehicle ? pVehicle->GetPosition() : pSourcePed->GetPosition();
- CVector2D targetPos = pTargetPed->bInVehicle ? pTargetPed->m_pMyVehicle->GetPosition() : pTargetPed->GetPosition();
- float angle = CGeneral::GetATanOfXY(sourcePos.x - targetPos.x, sourcePos.y - targetPos.y) + HALFPI;
- if (angle > TWOPI)
- angle -= TWOPI;
- if (!pVehicle) {
- pSourcePed->m_fRotationCur = angle;
- pSourcePed->m_fRotationDest = angle;
- pSourcePed->SetHeading(angle);
- }
- return 0;
- }
- case COMMAND_TURN_PLAYER_TO_FACE_CHAR:
- {
- CollectParameters(&m_nIp, 2);
- CPed* pSourcePed = CWorld::Players[ScriptParams[0]].m_pPed;
- CPed* pTargetPed = CPools::GetPedPool()->GetAt(ScriptParams[1]);
- CVehicle* pVehicle = pSourcePed->bInVehicle ? pSourcePed->m_pMyVehicle : nil;
- CVector2D sourcePos = pSourcePed->bInVehicle ? pVehicle->GetPosition() : pSourcePed->GetPosition();
- CVector2D targetPos = pTargetPed->bInVehicle ? pTargetPed->m_pMyVehicle->GetPosition() : pTargetPed->GetPosition();
- float angle = CGeneral::GetATanOfXY(sourcePos.x - targetPos.x, sourcePos.y - targetPos.y) + HALFPI;
- if (angle > TWOPI)
- angle -= TWOPI;
- if (!pVehicle) {
- pSourcePed->m_fRotationCur = angle;
- pSourcePed->m_fRotationDest = angle;
- pSourcePed->SetHeading(angle);
- }
- return 0;
- }
- case COMMAND_SET_CHAR_OBJ_GOTO_COORD_ON_FOOT:
- {
- CollectParameters(&m_nIp, 3);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- CVector target;
- target.x = *(float*)&ScriptParams[1];
- target.y = *(float*)&ScriptParams[2];
- target.z = CWorld::FindGroundZForCoord(target.x, target.y);
- pPed->bScriptObjectiveCompleted = false;
- pPed->SetObjective(OBJECTIVE_GOTO_AREA_ON_FOOT, target);
- return 0;
- }
- //case COMMAND_SET_CHAR_OBJ_GOTO_COORD_IN_CAR:
- case COMMAND_CREATE_PICKUP:
- {
- CollectParameters(&m_nIp, 5);
- int16 model = ScriptParams[0];
- if (model < 0)
- model = CTheScripts::UsedObjectArray[-model].index;
- CVector pos = *(CVector*)&ScriptParams[2];
- 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, model, ScriptParams[1], 0);
- StoreParameters(&m_nIp, 1);
- return 0;
- }
- case COMMAND_HAS_PICKUP_BEEN_COLLECTED:
- CollectParameters(&m_nIp, 1);
- UpdateCompareFlag(CPickups::IsPickUpPickedUp(ScriptParams[0]) != 0);
- return 0;
- case COMMAND_REMOVE_PICKUP:
- CollectParameters(&m_nIp, 1);
- CPickups::RemovePickUp(ScriptParams[0]);
- return 0;
- case COMMAND_SET_TAXI_LIGHTS:
- {
- CollectParameters(&m_nIp, 2);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle);
- script_assert(pVehicle->m_vehType == VEHICLE_TYPE_CAR);
- ((CAutomobile*)pVehicle)->SetTaxiLight(ScriptParams[1] != 0);
- return 0;
- }
- case COMMAND_PRINT_BIG_Q:
- {
- wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- CollectParameters(&m_nIp, 2);
- CMessages::AddBigMessageQ(text, ScriptParams[0], ScriptParams[1] - 1);
- return 0;
- }
- /*
- case COMMAND_PRINT_WITH_NUMBER_BIG_Q:
- {
- wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- CollectParameters(&m_nIp, 3);
- CMessages::AddBigMessageWithNumberQ(text, ScriptParams[1], ScriptParams[2] - 1,
- ScriptParams[0], -1, -1, -1, -1, -1);
- return 0;
- }
- */
- case COMMAND_SET_GARAGE:
- {
- CollectParameters(&m_nIp, 9);
- float infX = *(float*)&ScriptParams[0];
- float infY = *(float*)&ScriptParams[1];
- float infZ = *(float*)&ScriptParams[2];
- 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, (eGarageType)ScriptParams[8], 0);
- StoreParameters(&m_nIp, 1);
- return 0;
- }
- /*
- case COMMAND_SET_GARAGE_WITH_CAR_MODEL:
- {
- CollectParameters(&m_nIp, 10);
- float infX = *(float*)&ScriptParams[0];
- float infY = *(float*)&ScriptParams[1];
- float infZ = *(float*)&ScriptParams[2];
- 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, (eGarageType)ScriptParams[8], ScriptParams[9]);
- StoreParameters(&m_nIp, 1);
- return 0;
- }
- */
- case COMMAND_SET_TARGET_CAR_FOR_MISSION_GARAGE:
- {
- CollectParameters(&m_nIp, 2);
- CVehicle* pTarget;
- if (ScriptParams[1] >= 0) {
- pTarget = CPools::GetVehiclePool()->GetAt(ScriptParams[1]);
- script_assert(pTarget);
- }
- else {
- pTarget = nil;
- }
- CGarages::SetTargetCarForMissonGarage(ScriptParams[0], pTarget);
- return 0;
- }
- case COMMAND_IS_CAR_IN_MISSION_GARAGE:
- CollectParameters(&m_nIp, 1);
- UpdateCompareFlag(CGarages::HasCarBeenDroppedOffYet(ScriptParams[0]));
- return 0;
- case COMMAND_SET_FREE_BOMBS:
- CollectParameters(&m_nIp, 1);
- CGarages::SetFreeBombs(ScriptParams[0] != 0);
- return 0;
-#ifdef GTA_PS2
- case COMMAND_SET_POWERPOINT:
- {
- CollectParameters(&m_nIp, 7);
- float f1 = *(float*)&ScriptParams[0];
- float f2 = *(float*)&ScriptParams[1];
- float f3 = *(float*)&ScriptParams[2];
- float f4 = *(float*)&ScriptParams[3];
- float f5 = *(float*)&ScriptParams[4];
- float f6 = *(float*)&ScriptParams[5];
- float temp;
-
- if (f1 > f4) {
- temp = f1;
- f1 = f4;
- f4 = temp;
- }
-
- if (f2 > f5) {
- temp = f2;
- f2 = f5;
- f5 = temp;
- }
-
- if (f3 > f6) {
- temp = f3;
- f3 = f6;
- f6 = temp;
- }
-
- CPowerPoints::GenerateNewOne(f1, f2, f3, f4, f5, f6, *(uint8*)&ScriptParams[6]);
-
- return 0;
- }
-#endif // GTA_PS2
- /*
- case COMMAND_SET_ALL_TAXI_LIGHTS:
- CollectParameters(&m_nIp, 1);
- CAutomobile::SetAllTaxiLights(ScriptParams[0] != 0);
- return 0;
- case COMMAND_IS_CAR_ARMED_WITH_ANY_BOMB:
- {
- CollectParameters(&m_nIp, 1);
- CAutomobile* pCar = (CAutomobile*)CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pCar);
- script_assert(pCar->m_vehType == VEHICLE_TYPE_CAR);
- 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);
- return 0;
- case COMMAND_SET_PLAYER_HEALTH:
- {
- CollectParameters(&m_nIp, 2);
- CPlayerPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
- script_assert(pPed);
- pPed->m_fHealth = Min(ScriptParams[1], CWorld::Players[ScriptParams[0]].m_nMaxHealth);
- return 0;
- }
- case COMMAND_SET_CHAR_HEALTH:
- {
- CollectParameters(&m_nIp, 2);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- if (ScriptParams[1]) {
- pPed->m_fHealth = ScriptParams[1];
- }
- else if (pPed->bInVehicle) {
- pPed->SetDead();
- if (!pPed->IsPlayer())
- pPed->FlagToDestroyWhenNextProcessed();
- }
- else {
- pPed->SetDie();
- }
- return 0;
- }
- case COMMAND_SET_CAR_HEALTH:
- {
- CollectParameters(&m_nIp, 2);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle);
- pVehicle->m_fHealth = ScriptParams[1];
- return 0;
- }
- case COMMAND_GET_PLAYER_HEALTH:
- {
- CollectParameters(&m_nIp, 1);
- CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
- script_assert(pPed);
- ScriptParams[0] = pPed->m_fHealth;
- StoreParameters(&m_nIp, 1);
- return 0;
- }
- case COMMAND_GET_CHAR_HEALTH:
- {
- CollectParameters(&m_nIp, 1);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- ScriptParams[0] = pPed->m_fHealth;
- StoreParameters(&m_nIp, 1);
- return 0;
- }
- case COMMAND_GET_CAR_HEALTH:
- {
- CollectParameters(&m_nIp, 1);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle);
- 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]);
- return 0;
- }
- */
- case COMMAND_CHANGE_CAR_COLOUR:
- {
- CollectParameters(&m_nIp, 3);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- if (ScriptParams[1] >= 256 || ScriptParams[2] >= 256)
- debug("CHANGE_CAR_COLOUR - Colours must be less than %d", 256);
- pVehicle->m_currentColour1 = ScriptParams[1];
- pVehicle->m_currentColour2 = ScriptParams[2];
- return 0;
- }
- case COMMAND_SWITCH_PED_ROADS_ON:
- {
- CollectParameters(&m_nIp, 6);
- 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];
- }
- ThePaths.SwitchPedRoadsOffInArea(infX, supX, infY, supY, infZ, supZ, false);
- return 0;
- }
- case COMMAND_SWITCH_PED_ROADS_OFF:
- {
- CollectParameters(&m_nIp, 6);
- 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];
- }
- ThePaths.SwitchPedRoadsOffInArea(infX, supX, infY, supY, infZ, supZ, true);
- return 0;
- }
- case COMMAND_CHAR_LOOK_AT_CHAR_ALWAYS:
- {
- CollectParameters(&m_nIp, 2);
- CPed* pSourcePed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pSourcePed);
- CPed* pTargetPed = CPools::GetPedPool()->GetAt(ScriptParams[1]);
- script_assert(pTargetPed);
- pSourcePed->SetLookFlag(pTargetPed, true);
- pSourcePed->SetLookTimer(60000);
- return 0;
- }
- case COMMAND_CHAR_LOOK_AT_PLAYER_ALWAYS:
- {
- CollectParameters(&m_nIp, 2);
- CPed* pSourcePed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pSourcePed);
- CPed* pTargetPed = CWorld::Players[ScriptParams[1]].m_pPed;
- script_assert(pTargetPed);
- pSourcePed->SetLookFlag(pTargetPed, true);
- pSourcePed->SetLookTimer(60000);
- return 0;
- }
- case COMMAND_PLAYER_LOOK_AT_CHAR_ALWAYS:
- {
- CollectParameters(&m_nIp, 2);
- CPed* pSourcePed = CWorld::Players[ScriptParams[0]].m_pPed;
- script_assert(pSourcePed);
- CPed* pTargetPed = CPools::GetPedPool()->GetAt(ScriptParams[1]);
- script_assert(pTargetPed);
- pSourcePed->SetLookFlag(pTargetPed, true);
- pSourcePed->SetLookTimer(60000);
- return 0;
- }
- case COMMAND_STOP_CHAR_LOOKING:
- {
- CollectParameters(&m_nIp, 1);
- CPed* pSourcePed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pSourcePed);
- pSourcePed->ClearLookFlag();
- pSourcePed->bKeepTryingToLook = false;
- if (pSourcePed->GetPedState() == PED_LOOK_HEADING || pSourcePed->GetPedState() == PED_LOOK_ENTITY)
- pSourcePed->RestorePreviousState();
- return 0;
- }
- case COMMAND_STOP_PLAYER_LOOKING:
- {
- CollectParameters(&m_nIp, 1);
- CPed* pSourcePed = CWorld::Players[ScriptParams[0]].m_pPed;
- script_assert(pSourcePed);
- pSourcePed->ClearLookFlag();
- pSourcePed->bKeepTryingToLook = false;
- if (pSourcePed->GetPedState() == PED_LOOK_HEADING || pSourcePed->GetPedState() == PED_LOOK_ENTITY)
- 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:
- 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]);
- return 0;
- case COMMAND_SET_GANG_WEAPONS:
- 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);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- float infX = *(float*)&ScriptParams[1];
- float infY = *(float*)&ScriptParams[2];
- float supX = *(float*)&ScriptParams[3];
- float supY = *(float*)&ScriptParams[4];
- if (infX > supX) {
- infX = *(float*)&ScriptParams[3];
- supX = *(float*)&ScriptParams[1];
- }
- if (infY > supY) {
- infY = *(float*)&ScriptParams[4];
- supY = *(float*)&ScriptParams[2];
- }
- CVector pos;
- pos.x = (infX + supX) / 2;
- pos.y = (infY + supY) / 2;
- pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
- float radius = Max(pos.x - infX, pos.y - infY);
- pPed->bScriptObjectiveCompleted = false;
- pPed->SetObjective(OBJECTIVE_RUN_TO_AREA, pos, radius);
- return 0;
- }
- */
- case COMMAND_SET_CHAR_OBJ_RUN_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_RUN_TO_AREA, pos);
- return 0;
- }
- /*
- case COMMAND_IS_PLAYER_TOUCHING_OBJECT_ON_FOOT:
- {
- CollectParameters(&m_nIp, 2);
- CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
- script_assert(pPed);
- CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[1]);
- bool isTouching = false;
- if (pPed->bInVehicle)
- isTouching = false;
- else if (pPed->GetHasCollidedWith(pObject))
- isTouching = true;
- UpdateCompareFlag(isTouching);
- return 0;
- }
- case COMMAND_IS_CHAR_TOUCHING_OBJECT_ON_FOOT:
- {
- CollectParameters(&m_nIp, 2);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[1]);
- bool isTouching = false;
- if (pPed->InVehicle())
- isTouching = false;
- else if (pPed->GetHasCollidedWith(pObject))
- isTouching = true;
- UpdateCompareFlag(isTouching);
- return 0;
- }
- */
- case COMMAND_LOAD_SPECIAL_CHARACTER:
- {
- CollectParameters(&m_nIp, 1);
- char name[16];
- strncpy(name, (char*)&CTheScripts::ScriptSpace[m_nIp], KEY_LENGTH_IN_SCRIPT);
- for (int i = 0; i < KEY_LENGTH_IN_SCRIPT; i++)
- name[i] = tolower(name[i]);
- CStreaming::RequestSpecialChar(ScriptParams[0] - 1, name, STREAMFLAGS_DEPENDENCY | STREAMFLAGS_SCRIPTOWNED);
- m_nIp += KEY_LENGTH_IN_SCRIPT;
- return 0;
- }
- case COMMAND_HAS_SPECIAL_CHARACTER_LOADED:
- {
- CollectParameters(&m_nIp, 1);
- UpdateCompareFlag(CStreaming::HasSpecialCharLoaded(ScriptParams[0] - 1));
- return 0;
- }
- /*
- case COMMAND_FLASH_CAR:
- {
- CollectParameters(&m_nIp, 2);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle);
- pVehicle->bHasBlip = (ScriptParams[1] != 0);
- return 0;
- }
- case COMMAND_FLASH_CHAR:
- {
- CollectParameters(&m_nIp, 2);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- pPed->bHasBlip = (ScriptParams[1] != 0);
- return 0;
- }
- case COMMAND_FLASH_OBJECT:
- {
- CollectParameters(&m_nIp, 2);
- CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
- script_assert(pObject);
- 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);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle);
- script_assert(pVehicle->m_vehType == VEHICLE_TYPE_CAR);
- ((CAutomobile*)pVehicle)->m_bombType = ScriptParams[1];
- ((CAutomobile*)pVehicle)->m_pBombRigger = FindPlayerPed();
- return 0;
- }
- */
- case COMMAND_SET_CHAR_PERSONALITY:
- {
- CollectParameters(&m_nIp, 2);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- pPed->SetPedStats((ePedStats)ScriptParams[1]);
- return 0;
- }
- case COMMAND_SET_CUTSCENE_OFFSET:
- CollectParameters(&m_nIp, 3);
- CCutsceneMgr::SetCutsceneOffset(*(CVector*)&ScriptParams[0]);
- return 0;
- case COMMAND_SET_ANIM_GROUP_FOR_CHAR:
- {
- CollectParameters(&m_nIp, 2);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- pPed->m_animGroup = (AssocGroupId)ScriptParams[1];
- return 0;
- }
- /*
- case COMMAND_SET_ANIM_GROUP_FOR_PLAYER:
- {
- CollectParameters(&m_nIp, 2);
- CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
- script_assert(pPed);
- pPed->m_animGroup = (AssocGroupId)ScriptParams[1];
- return 0;
- }
- */
- case COMMAND_REQUEST_MODEL:
- {
- CollectParameters(&m_nIp, 1);
- int model = ScriptParams[0];
- if (model < 0)
- model = CTheScripts::UsedObjectArray[-model].index;
- CStreaming::RequestModel(model, STREAMFLAGS_DEPENDENCY | STREAMFLAGS_NOFADE | STREAMFLAGS_SCRIPTOWNED);
- return 0;
- }
- case COMMAND_HAS_MODEL_LOADED:
- {
- CollectParameters(&m_nIp, 1);
- int model = ScriptParams[0];
- if (model < 0)
- model = CTheScripts::UsedObjectArray[-model].index;
- UpdateCompareFlag(CStreaming::HasModelLoaded(model));
- return 0;
- }
- case COMMAND_MARK_MODEL_AS_NO_LONGER_NEEDED:
- {
- CollectParameters(&m_nIp, 1);
- int model = ScriptParams[0];
- if (model < 0)
- model = CTheScripts::UsedObjectArray[-model].index;
- CStreaming::SetMissionDoesntRequireModel(model);
- return 0;
- }
- case COMMAND_GRAB_PHONE:
- {
- CollectParameters(&m_nIp, 2);
- ScriptParams[0] = gPhoneInfo.GrabPhone(*(float*)&ScriptParams[0], *(float*)&ScriptParams[1]);
- StoreParameters(&m_nIp, 1);
- return 0;
- }
- /*
- case COMMAND_SET_REPEATED_PHONE_MESSAGE:
- {
- CollectParameters(&m_nIp, 1);
- wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- gPhoneInfo.SetPhoneMessage_Repeatedly(ScriptParams[0], text, nil, nil, nil, nil, nil);
- return 0;
- }
- case COMMAND_SET_PHONE_MESSAGE:
- {
- CollectParameters(&m_nIp, 1);
- wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- gPhoneInfo.SetPhoneMessage_JustOnce(ScriptParams[0], text, nil, nil, nil, nil, nil);
- return 0;
- }
- case COMMAND_HAS_PHONE_DISPLAYED_MESSAGE:
- {
- CollectParameters(&m_nIp, 1);
- UpdateCompareFlag(gPhoneInfo.HasMessageBeenDisplayed(ScriptParams[0]));
- return 0;
- }
- */
- case COMMAND_TURN_PHONE_OFF:
- {
- CollectParameters(&m_nIp, 1);
- gPhoneInfo.SetPhoneMessage_JustOnce(ScriptParams[0], nil, nil, nil, nil, nil, nil);
- return 0;
- }
- case COMMAND_DRAW_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);
- return 0;
- }
- case COMMAND_DRAW_LIGHT:
- {
- CollectParameters(&m_nIp, 6);
- CVector pos = *(CVector*)&ScriptParams[0];
- CVector unused(0.0f, 0.0f, 0.0f);
- CPointLights::AddLight(0, *(CVector*)&ScriptParams[0], CVector(0.0f, 0.0f, 0.0f), 12.0f,
- ScriptParams[3] / 255.0f, ScriptParams[4] / 255.0f, ScriptParams[5] / 255.0f, 0, true);
- 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);
- CVector pos = *(CVector*)&ScriptParams[0];
- if (pos.z <= MAP_Z_LOW_LIMIT)
- pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
- CRestart::OverrideNextRestart(pos, *(float*)&ScriptParams[3]);
- if (CWorld::Players[CWorld::PlayerInFocus].m_WBState != WBSTATE_PLAYING)
- printf("RESTART_CRITICAL_MISSION - Player state is not PLAYING\n");
- CWorld::Players[CWorld::PlayerInFocus].PlayerFailedCriticalMission();
- return 0;
- }
- */
- case COMMAND_IS_PLAYER_PLAYING:
- {
- CollectParameters(&m_nIp, 1);
- UpdateCompareFlag(CWorld::Players[ScriptParams[0]].m_WBState == WBSTATE_PLAYING);
- return 0;
- }
- //case COMMAND_SET_COLL_OBJ_NO_OBJ:
- default:
- script_assert(0);
- }
- return -1;
-}
-
-int8 CRunningScript::ProcessCommands600To699(int32 command)
-{
- switch (command){
- /* Collective commands are not implemented until LCS.
- case COMMAND_SET_COLL_OBJ_WAIT_ON_FOOT:
- case COMMAND_SET_COLL_OBJ_FLEE_ON_FOOT_TILL_SAFE:
- case COMMAND_SET_COLL_OBJ_GUARD_SPOT:
- case COMMAND_SET_COLL_OBJ_GUARD_AREA:
- case COMMAND_SET_COLL_OBJ_WAIT_IN_CAR:
- case COMMAND_SET_COLL_OBJ_KILL_CHAR_ON_FOOT:
- case COMMAND_SET_COLL_OBJ_KILL_PLAYER_ON_FOOT:
- case COMMAND_SET_COLL_OBJ_KILL_CHAR_ANY_MEANS:
- case COMMAND_SET_COLL_OBJ_KILL_PLAYER_ANY_MEANS:
- case COMMAND_SET_COLL_OBJ_FLEE_CHAR_ON_FOOT_TILL_SAFE:
- case COMMAND_SET_COLL_OBJ_FLEE_PLAYER_ON_FOOT_TILL_SAFE:
- case COMMAND_SET_COLL_OBJ_FLEE_CHAR_ON_FOOT_ALWAYS:
- case COMMAND_SET_COLL_OBJ_FLEE_PLAYER_ON_FOOT_ALWAYS:
- case COMMAND_SET_COLL_OBJ_GOTO_CHAR_ON_FOOT:
- case COMMAND_SET_COLL_OBJ_GOTO_PLAYER_ON_FOOT:
- case COMMAND_SET_COLL_OBJ_LEAVE_CAR:
- case COMMAND_SET_COLL_OBJ_ENTER_CAR_AS_PASSENGER:
- case COMMAND_SET_COLL_OBJ_ENTER_CAR_AS_DRIVER:
- case COMMAND_SET_COLL_OBJ_FOLLOW_CAR_IN_CAR:
- case COMMAND_SET_COLL_OBJ_FIRE_AT_OBJECT_FROM_VEHICLE:
- case COMMAND_SET_COLL_OBJ_DESTROY_OBJECT:
- case COMMAND_SET_COLL_OBJ_DESTROY_CAR:
- case COMMAND_SET_COLL_OBJ_GOTO_AREA_ON_FOOT:
- case COMMAND_SET_COLL_OBJ_GOTO_AREA_IN_CAR:
- case COMMAND_SET_COLL_OBJ_FOLLOW_CAR_ON_FOOT_WITH_OFFSET:
- case COMMAND_SET_COLL_OBJ_GUARD_ATTACK:
- case COMMAND_SET_COLL_OBJ_FOLLOW_ROUTE:
- case COMMAND_SET_COLL_OBJ_GOTO_COORD_ON_FOOT:
- case COMMAND_SET_COLL_OBJ_GOTO_COORD_IN_CAR:
- case COMMAND_SET_COLL_OBJ_RUN_TO_AREA:
- case COMMAND_SET_COLL_OBJ_RUN_TO_COORD:
- case COMMAND_ADD_PEDS_IN_AREA_TO_COLL:
- case COMMAND_ADD_PEDS_IN_VEHICLE_TO_COLL:
- case COMMAND_CLEAR_COLL:
- case COMMAND_IS_COLL_IN_CARS:
- case COMMAND_LOCATE_COLL_ANY_MEANS_2D:
- case COMMAND_LOCATE_COLL_ON_FOOT_2D:
- case COMMAND_LOCATE_COLL_IN_CAR_2D:
- case COMMAND_LOCATE_STOPPED_COLL_ANY_MEANS_2D:
- case COMMAND_LOCATE_STOPPED_COLL_ON_FOOT_2D:
- case COMMAND_LOCATE_STOPPED_COLL_IN_CAR_2D:
- case COMMAND_LOCATE_COLL_ANY_MEANS_CHAR_2D:
- case COMMAND_LOCATE_COLL_ON_FOOT_CHAR_2D:
- case COMMAND_LOCATE_COLL_IN_CAR_CHAR_2D:
- case COMMAND_LOCATE_COLL_ANY_MEANS_CAR_2D:
- case COMMAND_LOCATE_COLL_ON_FOOT_CAR_2D:
- case COMMAND_LOCATE_COLL_IN_CAR_CAR_2D:
- case COMMAND_LOCATE_COLL_ANY_MEANS_PLAYER_2D:
- case COMMAND_LOCATE_COLL_ON_FOOT_PLAYER_2D:
- case COMMAND_LOCATE_COLL_IN_CAR_PLAYER_2D:
- case COMMAND_IS_COLL_IN_AREA_2D:
- case COMMAND_IS_COLL_IN_AREA_ON_FOOT_2D:
- case COMMAND_IS_COLL_IN_AREA_IN_CAR_2D:
- case COMMAND_IS_COLL_STOPPED_IN_AREA_2D:
- case COMMAND_IS_COLL_STOPPED_IN_AREA_ON_FOOT_2D:
- case COMMAND_IS_COLL_STOPPED_IN_AREA_IN_CAR_2D:
- case COMMAND_GET_NUMBER_OF_PEDS_IN_COLL:
- */
- case COMMAND_SET_CHAR_HEED_THREATS:
- {
- CollectParameters(&m_nIp, 2);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- pPed->bRespondsToThreats = (ScriptParams[1] != 0);
- return 0;
- }
- case COMMAND_SET_PLAYER_HEED_THREATS:
- {
- CollectParameters(&m_nIp, 2);
- CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
- script_assert(pPed);
- pPed->bRespondsToThreats = (ScriptParams[1] != 0);
- return 0;
- }
- case COMMAND_GET_CONTROLLER_MODE:
-#if defined(GTA_PC) && !defined(DETECT_PAD_INPUT_SWITCH)
- ScriptParams[0] = 0;
-#else
- ScriptParams[0] = CPad::IsAffectedByController ? CPad::GetPad(0)->Mode : 0;
-#endif
- StoreParameters(&m_nIp, 1);
- return 0;
- case COMMAND_SET_CAN_RESPRAY_CAR:
- {
- CollectParameters(&m_nIp, 2);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle);
- //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);
- UpdateCompareFlag(pVehicle->IsTaxi());
- return 0;
- }
- */
- case COMMAND_UNLOAD_SPECIAL_CHARACTER:
- CollectParameters(&m_nIp, 1);
- CStreaming::SetMissionDoesntRequireSpecialChar(ScriptParams[0] - 1);
- return 0;
- case COMMAND_RESET_NUM_OF_MODELS_KILLED_BY_PLAYER:
- CDarkel::ResetModelsKilledByPlayer();
- return 0;
- case COMMAND_GET_NUM_OF_MODELS_KILLED_BY_PLAYER:
- CollectParameters(&m_nIp, 1);
- ScriptParams[0] = CDarkel::QueryModelsKilledByPlayer(ScriptParams[0]);
- StoreParameters(&m_nIp, 1);
- return 0;
- /*
- case COMMAND_ACTIVATE_GARAGE:
- CollectParameters(&m_nIp, 1);
- CGarages::ActivateGarage(ScriptParams[0]);
- return 0;
- case COMMAND_SWITCH_TAXI_TIMER:
- {
- CollectParameters(&m_nIp, 1);
- if (ScriptParams[0] != 0){
- CWorld::Players[CWorld::PlayerInFocus].m_nUnusedTaxiTimer = CTimer::GetTimeInMilliseconds();
- CWorld::Players[CWorld::PlayerInFocus].m_bUnusedTaxiThing = true;
- }else{
- CWorld::Players[CWorld::PlayerInFocus].m_bUnusedTaxiThing = false;
- }
- 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;
- CVector pos = *(CVector*)&ScriptParams[1];
- if (pos.z <= MAP_Z_LOW_LIMIT)
- pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
- pObj->SetPosition(pos);
- 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);
- StoreParameters(&m_nIp, 1);
- if (m_bIsMissionScript)
- CTheScripts::MissionCleanup.AddEntityToList(ScriptParams[0], CLEANUP_OBJECT);
- return 0;
- }
- /*
- case COMMAND_IS_BOAT:
- {
- CollectParameters(&m_nIp, 1);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle);
- UpdateCompareFlag(pVehicle->m_vehType == VEHICLE_TYPE_BOAT);
- return 0;
- }
- case COMMAND_SET_CHAR_OBJ_GOTO_AREA_ANY_MEANS:
- {
- CollectParameters(&m_nIp, 5);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- float infX = *(float*)&ScriptParams[1];
- float infY = *(float*)&ScriptParams[2];
- float supX = *(float*)&ScriptParams[3];
- float supY = *(float*)&ScriptParams[4];
- if (infX > supX) {
- infX = *(float*)&ScriptParams[3];
- supX = *(float*)&ScriptParams[1];
- }
- if (infY > supY) {
- infY = *(float*)&ScriptParams[4];
- supY = *(float*)&ScriptParams[2];
- }
- CVector pos;
- pos.x = (infX + supX) / 2;
- pos.y = (infY + supY) / 2;
- pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
- float radius = Max(pos.x - infX, pos.y - infY);
- pPed->bScriptObjectiveCompleted = false;
- 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:
- {
- CollectParameters(&m_nIp, 1);
- CPlayerInfo* pPlayer = &CWorld::Players[ScriptParams[0]];
- UpdateCompareFlag(CTheScripts::IsPlayerStopped(pPlayer));
- return 0;
-
- }
- /*
- case COMMAND_IS_CHAR_STOPPED:
- {
- CollectParameters(&m_nIp, 1);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- UpdateCompareFlag(CTheScripts::IsPedStopped(pPed));
- return 0;
- }
- case COMMAND_MESSAGE_WAIT:
- CollectParameters(&m_nIp, 2);
- m_nWakeTime = CTimer::GetTimeInMilliseconds() + ScriptParams[0];
- if (ScriptParams[1] != 0)
- m_bSkipWakeTime = true;
- return 1;
- case COMMAND_ADD_PARTICLE_EFFECT:
- {
- CollectParameters(&m_nIp, 5);
- CVector pos = *(CVector*)&ScriptParams[1];
- if (pos.z <= MAP_Z_LOW_LIMIT)
- pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
- CParticleObject::AddObject(ScriptParams[0], pos, ScriptParams[4] != 0);
- return 0;
- }
- */
- case COMMAND_SWITCH_WIDESCREEN:
- CollectParameters(&m_nIp, 1);
- if (ScriptParams[0] != 0)
- TheCamera.SetWideScreenOn();
- else
- TheCamera.SetWideScreenOff();
- return 0;
- /*
- case COMMAND_ADD_SPRITE_BLIP_FOR_CAR:
- {
- CollectParameters(&m_nIp, 2);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle);
- CRadar::GetActualBlipArrayIndex(CollectNextParameterWithoutIncreasingPC(m_nIp));
- int id = CRadar::SetEntityBlip(BLIP_CAR, ScriptParams[0], 0, BLIP_DISPLAY_BOTH);
- CRadar::SetBlipSprite(id, ScriptParams[1]);
- ScriptParams[0] = id;
- StoreParameters(&m_nIp, 1);
- return 0;
- }
- case COMMAND_ADD_SPRITE_BLIP_FOR_CHAR:
- {
- CollectParameters(&m_nIp, 2);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- CRadar::GetActualBlipArrayIndex(CollectNextParameterWithoutIncreasingPC(m_nIp));
- int id = CRadar::SetEntityBlip(BLIP_CHAR, ScriptParams[0], 1, BLIP_DISPLAY_BOTH);
- CRadar::SetBlipSprite(id, ScriptParams[1]);
- ScriptParams[0] = id;
- StoreParameters(&m_nIp, 1);
- return 0;
- }
- case COMMAND_ADD_SPRITE_BLIP_FOR_OBJECT:
- {
- CollectParameters(&m_nIp, 2);
- CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
- script_assert(pObject);
- CRadar::GetActualBlipArrayIndex(CollectNextParameterWithoutIncreasingPC(m_nIp));
- int id = CRadar::SetEntityBlip(BLIP_OBJECT, ScriptParams[0], 6, BLIP_DISPLAY_BOTH);
- CRadar::SetBlipSprite(id, ScriptParams[1]);
- ScriptParams[0] = id;
- StoreParameters(&m_nIp, 1);
- return 0;
- }
- */
- case COMMAND_ADD_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::SetCoordBlip(BLIP_CONTACT_POINT, pos, 2, BLIP_DISPLAY_BOTH);
- CRadar::SetBlipSprite(id, ScriptParams[3]);
- ScriptParams[0] = id;
- StoreParameters(&m_nIp, 1);
- return 0;
- }
- case COMMAND_ADD_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::SetCoordBlip(BLIP_COORD, pos, 5, BLIP_DISPLAY_BOTH);
- CRadar::SetBlipSprite(id, ScriptParams[3]);
- ScriptParams[0] = id;
- StoreParameters(&m_nIp, 1);
- return 0;
- }
- case COMMAND_SET_CHAR_ONLY_DAMAGED_BY_PLAYER:
- {
- CollectParameters(&m_nIp, 2);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- pPed->bOnlyDamagedByPlayer = (ScriptParams[1] != 0);
- return 0;
- }
- case COMMAND_SET_CAR_ONLY_DAMAGED_BY_PLAYER:
- {
- CollectParameters(&m_nIp, 2);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle);
- pVehicle->bOnlyDamagedByPlayer = (ScriptParams[1] != 0);
- return 0;
- }
- case COMMAND_SET_CHAR_PROOFS:
- {
- CollectParameters(&m_nIp, 6);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- pPed->bBulletProof = (ScriptParams[1] != 0);
- pPed->bFireProof = (ScriptParams[2] != 0);
- pPed->bExplosionProof = (ScriptParams[3] != 0);
- pPed->bCollisionProof = (ScriptParams[4] != 0);
- pPed->bMeleeProof = (ScriptParams[5] != 0);
- return 0;
- }
- case COMMAND_SET_CAR_PROOFS:
- {
- CollectParameters(&m_nIp, 6);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle);
- pVehicle->bBulletProof = (ScriptParams[1] != 0);
- pVehicle->bFireProof = (ScriptParams[2] != 0);
- pVehicle->bExplosionProof = (ScriptParams[3] != 0);
- pVehicle->bCollisionProof = (ScriptParams[4] != 0);
- pVehicle->bMeleeProof = (ScriptParams[5] != 0);
- return 0;
- }
- case COMMAND_IS_PLAYER_IN_ANGLED_AREA_2D:
- case COMMAND_IS_PLAYER_IN_ANGLED_AREA_ON_FOOT_2D:
- case COMMAND_IS_PLAYER_IN_ANGLED_AREA_IN_CAR_2D:
- case COMMAND_IS_PLAYER_STOPPED_IN_ANGLED_AREA_2D:
- case COMMAND_IS_PLAYER_STOPPED_IN_ANGLED_AREA_ON_FOOT_2D:
- case COMMAND_IS_PLAYER_STOPPED_IN_ANGLED_AREA_IN_CAR_2D:
- case COMMAND_IS_PLAYER_IN_ANGLED_AREA_3D:
- case COMMAND_IS_PLAYER_IN_ANGLED_AREA_ON_FOOT_3D:
- case COMMAND_IS_PLAYER_IN_ANGLED_AREA_IN_CAR_3D:
- case COMMAND_IS_PLAYER_STOPPED_IN_ANGLED_AREA_3D:
- case COMMAND_IS_PLAYER_STOPPED_IN_ANGLED_AREA_ON_FOOT_3D:
- 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]);
- return 0;
- case COMMAND_GET_NUMBER_OF_CARS_COLLECTED_BY_GARAGE:
- CollectParameters(&m_nIp, 1);
- ScriptParams[0] = CGarages::QueryCarsCollected(ScriptParams[0]);
- StoreParameters(&m_nIp, 1);
- return 0;
- case COMMAND_HAS_CAR_BEEN_TAKEN_TO_GARAGE:
- CollectParameters(&m_nIp, 2);
- UpdateCompareFlag(CGarages::HasThisCarBeenCollected(ScriptParams[0], ScriptParams[1] - 1));
- return 0;
- */
- default:
- script_assert(0);
- }
- return -1;
-}
-
-int8 CRunningScript::ProcessCommands700To799(int32 command)
-{
- switch (command){
- /*
- case COMMAND_SET_SWAT_REQUIRED:
- CollectParameters(&m_nIp, 1);
- FindPlayerPed()->m_pWanted->m_bSwatRequired = (ScriptParams[0] != 0);
- return 0;
- case COMMAND_SET_FBI_REQUIRED:
- CollectParameters(&m_nIp, 1);
- FindPlayerPed()->m_pWanted->m_bFbiRequired = (ScriptParams[0] != 0);
- return 0;
- case COMMAND_SET_ARMY_REQUIRED:
- CollectParameters(&m_nIp, 1);
- FindPlayerPed()->m_pWanted->m_bArmyRequired = (ScriptParams[0] != 0);
- return 0;
- */
- case COMMAND_IS_CAR_IN_WATER:
- {
- CollectParameters(&m_nIp, 1);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- UpdateCompareFlag(pVehicle && pVehicle->bIsInWater);
- return 0;
- }
- case COMMAND_GET_CLOSEST_CHAR_NODE:
- {
- CollectParameters(&m_nIp, 3);
- 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, true)];
- *(CVector*)&ScriptParams[0] = pNode->GetPosition();
- StoreParameters(&m_nIp, 3);
- return 0;
- }
- case COMMAND_GET_CLOSEST_CAR_NODE:
- {
- CollectParameters(&m_nIp, 3);
- 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.FindNodeClosestToCoors(pos, 0, 999999.9f, true, true));
- StoreParameters(&m_nIp, 3);
- return 0;
- }
- case COMMAND_CAR_GOTO_COORDINATES_ACCURATE:
- {
- CollectParameters(&m_nIp, 4);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle);
- CVector pos = *(CVector*)&ScriptParams[1];
- if (pos.z <= MAP_Z_LOW_LIMIT)
- pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
- pos.z += pVehicle->GetDistanceFromCentreOfMassToBaseOfModel();
- if (CCarCtrl::JoinCarWithRoadSystemGotoCoors(pVehicle, pos, false))
- pVehicle->AutoPilot.m_nCarMission = MISSION_GOTO_COORDS_STRAIGHT_ACCURATE;
- else
- pVehicle->AutoPilot.m_nCarMission = MISSION_GOTOCOORDS_ACCURATE;
- pVehicle->SetStatus(STATUS_PHYSICS);
- pVehicle->bEngineOn = true;
- 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]);
- return 0;
- case COMMAND_START_PACMAN_RECORD:
- CPacManPickups::StartPacManRecord();
- return 0;
- case COMMAND_GET_NUMBER_OF_POWER_PILLS_EATEN:
- ScriptParams[0] = CPacManPickups::QueryPowerPillsEatenInRace();
- StoreParameters(&m_nIp, 1);
- return 0;
- case COMMAND_CLEAR_PACMAN:
- CPacManPickups::CleanUpPacManStuff();
- return 0;
- case COMMAND_START_PACMAN_SCRAMBLE:
- {
- CollectParameters(&m_nIp, 5);
- CVector pos = *(CVector*)&ScriptParams[0];
- if (pos.z <= MAP_Z_LOW_LIMIT)
- pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
- CPacManPickups::StartPacManScramble(pos, *(float*)&ScriptParams[3], ScriptParams[4]);
- return 0;
- }
- case COMMAND_GET_NUMBER_OF_POWER_PILLS_CARRIED:
- ScriptParams[0] = CPacManPickups::QueryPowerPillsCarriedByPlayer();
- StoreParameters(&m_nIp, 1);
- return 0;
- case COMMAND_CLEAR_NUMBER_OF_POWER_PILLS_CARRIED:
- CPacManPickups::ResetPowerPillsCarriedByPlayer();
- return 0;
- */
- case COMMAND_IS_CAR_ON_SCREEN:
- {
- CollectParameters(&m_nIp, 1);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle);
- UpdateCompareFlag(TheCamera.IsSphereVisible(pVehicle->GetBoundCentre(), pVehicle->GetBoundRadius()));
- return 0;
- }
- case COMMAND_IS_CHAR_ON_SCREEN:
- {
- CollectParameters(&m_nIp, 1);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- UpdateCompareFlag(TheCamera.IsSphereVisible(pPed->GetBoundCentre(), pPed->GetBoundRadius()));
- return 0;
- }
- case COMMAND_IS_OBJECT_ON_SCREEN:
- {
- CollectParameters(&m_nIp, 1);
- CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
- script_assert(pObject);
- UpdateCompareFlag(TheCamera.IsSphereVisible(pObject->GetBoundCentre(), pObject->GetBoundRadius()));
- return 0;
- }
- /*
- case COMMAND_GOSUB_FILE:
- {
- CollectParameters(&m_nIp, 2);
- script_assert(m_nStackPointer < MAX_STACK_DEPTH);
- m_anStack[m_nStackPointer++] = m_nIp;
- SetIP(ScriptParams[0]);
- // ScriptParams[1] == filename
- return 0;
- }
- */
- case COMMAND_GET_GROUND_Z_FOR_3D_COORD:
- {
- CollectParameters(&m_nIp, 3);
- CVector pos = *(CVector*)&ScriptParams[0];
- bool success;
- *(float*)&ScriptParams[0] = CWorld::FindGroundZFor3DCoord(pos.x, pos.y, pos.z, &success);
- StoreParameters(&m_nIp, 1);
- return 0;
- }
- case COMMAND_START_SCRIPT_FIRE:
- {
- CollectParameters(&m_nIp, 3);
- CVector pos = *(CVector*)&ScriptParams[0];
- if (pos.z <= MAP_Z_LOW_LIMIT)
- pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
- ScriptParams[0] = gFireManager.StartScriptFire(pos, nil, 0.8f, 1);
- StoreParameters(&m_nIp, 1);
- return 0;
- }
- case COMMAND_IS_SCRIPT_FIRE_EXTINGUISHED:
- CollectParameters(&m_nIp, 1);
- UpdateCompareFlag(gFireManager.IsScriptFireExtinguish(ScriptParams[0]));
- return 0;
- case COMMAND_REMOVE_SCRIPT_FIRE:
- CollectParameters(&m_nIp, 1);
- gFireManager.RemoveScriptFire(ScriptParams[0]);
- return 0;
- /*
- case COMMAND_SET_COMEDY_CONTROLS:
- {
- CollectParameters(&m_nIp, 2);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle);
- pVehicle->bComedyControls = (ScriptParams[1] != 0);
- return 0;
- }
- */
- case COMMAND_BOAT_GOTO_COORDS:
- {
- CollectParameters(&m_nIp, 4);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle);
- script_assert(pVehicle->m_vehType == VEHICLE_TYPE_BOAT);
- CBoat* pBoat = (CBoat*)pVehicle;
- CVector pos = *(CVector*)&ScriptParams[1];
- if (pos.z <= MAP_Z_LOW_LIMIT)
- CWaterLevel::GetWaterLevel(pos.x, pos.y, pos.z, &pos.z, false);
- pBoat->AutoPilot.m_nCarMission = MISSION_GOTOCOORDS_ASTHECROWSWIMS;
- pBoat->AutoPilot.m_vecDestinationCoors = pos;
- pBoat->SetStatus(STATUS_PHYSICS);
- pBoat->AutoPilot.m_nCruiseSpeed = Max(1, pBoat->AutoPilot.m_nCruiseSpeed);
- pBoat->AutoPilot.m_nAntiReverseTimer = CTimer::GetTimeInMilliseconds();
- return 0;
- }
- case COMMAND_BOAT_STOP:
- {
- CollectParameters(&m_nIp, 1);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle);
- script_assert(pVehicle->m_vehType == VEHICLE_TYPE_BOAT);
- CBoat* pBoat = (CBoat*)pVehicle;
- pBoat->AutoPilot.m_nCarMission = MISSION_NONE;
- pBoat->SetStatus(STATUS_PHYSICS);
- pBoat->bEngineOn = false;
- pBoat->AutoPilot.m_nCruiseSpeed = 0;
- return 0;
- }
- case COMMAND_IS_PLAYER_SHOOTING_IN_AREA:
- {
- CollectParameters(&m_nIp, 6);
- CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
- script_assert(pPed);
- float x1 = *(float*)&ScriptParams[1];
- float y1 = *(float*)&ScriptParams[2];
- float x2 = *(float*)&ScriptParams[3];
- float y2 = *(float*)&ScriptParams[4];
- UpdateCompareFlag(pPed->bIsShooting && pPed->IsWithinArea(x1, y1, x2, y2));
- if (ScriptParams[5])
- CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, x1, y1, x2, y2, MAP_Z_LOW_LIMIT);
- if (CTheScripts::DbgFlag)
- CTheScripts::DrawDebugSquare(x1, y1, x2, y2);
- return 0;
- }
- case COMMAND_IS_CHAR_SHOOTING_IN_AREA:
- {
- CollectParameters(&m_nIp, 6);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- float x1 = *(float*)&ScriptParams[1];
- float y1 = *(float*)&ScriptParams[2];
- float x2 = *(float*)&ScriptParams[3];
- float y2 = *(float*)&ScriptParams[4];
- UpdateCompareFlag(pPed->bIsShooting && pPed->IsWithinArea(x1, y1, x2, y2));
- if (ScriptParams[5])
- CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, x1, y1, x2, y2, MAP_Z_LOW_LIMIT);
- if (CTheScripts::DbgFlag)
- CTheScripts::DrawDebugSquare(x1, y1, x2, y2);
- return 0;
- }
- case COMMAND_IS_CURRENT_PLAYER_WEAPON:
- {
- CollectParameters(&m_nIp, 2);
- CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
- script_assert(pPed);
- UpdateCompareFlag(ScriptParams[1] == pPed->GetWeapon()->m_eWeaponType);
- return 0;
- }
- case COMMAND_IS_CURRENT_CHAR_WEAPON:
- {
- CollectParameters(&m_nIp, 2);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- UpdateCompareFlag(ScriptParams[1] == pPed->GetWeapon()->m_eWeaponType);
- return 0;
- }
- /*
- case COMMAND_CLEAR_NUMBER_OF_POWER_PILLS_EATEN:
- CPacManPickups::ResetPowerPillsEatenInRace();
- return 0;
- case COMMAND_ADD_POWER_PILL:
- {
- CollectParameters(&m_nIp, 3);
- CVector pos = *(CVector*)&ScriptParams[0];
- if (pos.z <= MAP_Z_LOW_LIMIT)
- pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
- CPacManPickups::GenerateOnePMPickUp(pos);
- return 0;
- }
- */
- case COMMAND_SET_BOAT_CRUISE_SPEED:
- {
- CollectParameters(&m_nIp, 2);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle);
- script_assert(pVehicle->m_vehType == VEHICLE_TYPE_BOAT);
- CBoat* pBoat = (CBoat*)pVehicle;
- pBoat->AutoPilot.m_nCruiseSpeed = *(float*)&ScriptParams[1];
- return 0;
- }
- /*
- case COMMAND_GET_RANDOM_CHAR_IN_AREA:
- {
- CollectParameters(&m_nIp, 4);
- 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->GetModelIndex() == MI_SCUM_WOM || pPed->GetModelIndex() == MI_SCUM_MAN)
-// continue;
- if (!ThisIsAValidRandomPed(pPed->m_nPedType))
- 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_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, ZONE_DEFAULT);
- if (nZone != -1)
- m_nIp += KEY_LENGTH_IN_SCRIPT;
- CZone* pZone = CTheZones::GetNavigationZone(nZone);
- CollectParameters(&m_nIp, 3);
- int ped_handle = -1;
- CVector pos = FindPlayerCoors();
- int i = CPools::GetPedPool()->GetSize();
- 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 (!ThisIsAValidRandomPed(pPed->m_nPedType, ScriptParams[0], ScriptParams[1], ScriptParams[2]))
- continue;
- if (pPed->bIsLeader || pPed->m_leader)
- continue;
- if (!CTheZones::PointLiesWithinZone(&pPed->GetPosition(), pZone))
- continue;
- if (pos.z - PED_FIND_Z_OFFSET > pPed->GetPosition().z)
- 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;
- 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_IS_PLAYER_IN_TAXI:
- {
- CollectParameters(&m_nIp, 1);
- CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
- script_assert(pPed);
- UpdateCompareFlag(pPed->bInVehicle && pPed->m_pMyVehicle->IsTaxi());
- return 0;
- }
- case COMMAND_IS_PLAYER_SHOOTING:
- {
- CollectParameters(&m_nIp, 1);
- CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
- script_assert(pPed);
- UpdateCompareFlag(pPed->bIsShooting);
- return 0;
- }
- case COMMAND_IS_CHAR_SHOOTING:
- {
- CollectParameters(&m_nIp, 1);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- UpdateCompareFlag(pPed->bIsShooting);
- return 0;
- }
- case COMMAND_CREATE_MONEY_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_MONEY, PICKUP_MONEY, ScriptParams[3]);
- StoreParameters(&m_nIp, 1);
- return 0;
- }
- case COMMAND_SET_CHAR_ACCURACY:
- {
- CollectParameters(&m_nIp, 2);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- pPed->m_wepAccuracy = ScriptParams[1];
- return 0;
- }
- case COMMAND_GET_CAR_SPEED:
- {
- CollectParameters(&m_nIp, 1);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle);
- *(float*)&ScriptParams[0] = pVehicle->GetSpeed().Magnitude() * GAME_SPEED_TO_METERS_PER_SECOND;
- StoreParameters(&m_nIp, 1);
- return 0;
- }
- case COMMAND_LOAD_CUTSCENE:
- {
- char name[KEY_LENGTH_IN_SCRIPT];
- strncpy(name, (const char*)&CTheScripts::ScriptSpace[m_nIp], KEY_LENGTH_IN_SCRIPT);
- m_nIp += KEY_LENGTH_IN_SCRIPT;
- CCutsceneMgr::LoadCutsceneData(name);
- return 0;
- }
- case COMMAND_CREATE_CUTSCENE_OBJECT:
- {
- CollectParameters(&m_nIp, 1);
- CCutsceneObject* pCutObj = CCutsceneMgr::CreateCutsceneObject(ScriptParams[0]);
- ScriptParams[0] = CPools::GetObjectPool()->GetIndex(pCutObj);
- StoreParameters(&m_nIp, 1);
- return 0;
- }
- case COMMAND_SET_CUTSCENE_ANIM:
- {
- CollectParameters(&m_nIp, 1);
- char name[KEY_LENGTH_IN_SCRIPT];
- CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
- script_assert(pObject);
- strncpy(name, (const char*)&CTheScripts::ScriptSpace[m_nIp], KEY_LENGTH_IN_SCRIPT);
- m_nIp += KEY_LENGTH_IN_SCRIPT;
- CCutsceneMgr::SetCutsceneAnim(name, pObject);
- return 0;
- }
- case COMMAND_START_CUTSCENE:
- CCutsceneMgr::ms_cutsceneLoadStatus = 1;
- return 0;
- case COMMAND_GET_CUTSCENE_TIME:
- ScriptParams[0] = CCutsceneMgr::GetCutsceneTimeInMilleseconds();
- StoreParameters(&m_nIp, 1);
- return 0;
- case COMMAND_HAS_CUTSCENE_FINISHED:
- UpdateCompareFlag(CCutsceneMgr::HasCutsceneFinished());
- return 0;
- case COMMAND_CLEAR_CUTSCENE:
- CCutsceneMgr::DeleteCutsceneData();
- return 0;
- case COMMAND_RESTORE_CAMERA_JUMPCUT:
- TheCamera.RestoreWithJumpCut();
- return 0;
- case COMMAND_CREATE_COLLECTABLE1:
- {
- 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;
- CPickups::GenerateNewOne(pos, MI_COLLECTABLE1, PICKUP_COLLECTABLE1, 0);
- return 0;
- }
- case COMMAND_SET_COLLECTABLE1_TOTAL:
- CollectParameters(&m_nIp, 1);
- CWorld::Players[CWorld::PlayerInFocus].m_nTotalPackages = ScriptParams[0];
- return 0;
- /*
- case COMMAND_IS_PROJECTILE_IN_AREA:
- {
- CollectParameters(&m_nIp, 6);
- 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];
- }
- UpdateCompareFlag(CProjectileInfo::IsProjectileInRange(infX, supX, infY, supY, infZ, supZ, false));
- if (CTheScripts::DbgFlag)
- CTheScripts::DrawDebugCube(infX, infY, infZ, supX, supY, supZ);
- return 0;
- }
- case COMMAND_DESTROY_PROJECTILES_IN_AREA:
- {
- CollectParameters(&m_nIp, 6);
- 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];
- }
- UpdateCompareFlag(CProjectileInfo::IsProjectileInRange(infX, supX, infY, supY, infZ, supZ, true));
- if (CTheScripts::DbgFlag)
- CTheScripts::DrawDebugCube(infX, infY, infZ, supX, supY, supZ);
- return 0;
- }
- case COMMAND_DROP_MINE:
- {
- 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;
- CPickups::GenerateNewOne(pos, MI_CARMINE, PICKUP_MINE_INACTIVE, 0);
- return 0;
- }
- case COMMAND_DROP_NAUTICAL_MINE:
- {
- 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;
- CPickups::GenerateNewOne(pos, MI_NAUTICALMINE, PICKUP_MINE_INACTIVE, 0);
- return 0;
- }
- */
- case COMMAND_IS_CHAR_MODEL:
- {
- CollectParameters(&m_nIp, 2);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- UpdateCompareFlag(ScriptParams[1] == pPed->GetModelIndex());
- return 0;
- }
- case COMMAND_LOAD_SPECIAL_MODEL:
- {
- CollectParameters(&m_nIp, 1);
- char name[KEY_LENGTH_IN_SCRIPT];
- strncpy(name, (const char*)&CTheScripts::ScriptSpace[m_nIp], KEY_LENGTH_IN_SCRIPT);
- for (int i = 0; i < KEY_LENGTH_IN_SCRIPT; i++)
- name[i] = tolower(name[i]);
- CStreaming::RequestSpecialModel(ScriptParams[0], name, STREAMFLAGS_DEPENDENCY | STREAMFLAGS_SCRIPTOWNED);
- m_nIp += KEY_LENGTH_IN_SCRIPT;
- 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]));
- StoreParameters(&m_nIp, 1);
- return 0;
- case COMMAND_COS:
- CollectParameters(&m_nIp, 1);
- *(float*)&ScriptParams[0] = Cos(DEGTORAD(*(float*)&ScriptParams[0]));
- StoreParameters(&m_nIp, 1);
- return 0;
- case COMMAND_GET_CAR_FORWARD_X:
- {
- CollectParameters(&m_nIp, 1);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- float forwardX = pVehicle->GetForward().x / pVehicle->GetForward().Magnitude2D();
- *(float*)&ScriptParams[0] = forwardX;
- StoreParameters(&m_nIp, 1);
- return 0;
- }
- case COMMAND_GET_CAR_FORWARD_Y:
- {
- CollectParameters(&m_nIp, 1);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- float forwardY = pVehicle->GetForward().y / pVehicle->GetForward().Magnitude2D();
- *(float*)&ScriptParams[0] = forwardY;
- StoreParameters(&m_nIp, 1);
- return 0;
- }
- case COMMAND_CHANGE_GARAGE_TYPE:
- CollectParameters(&m_nIp, 2);
- CGarages::ChangeGarageType(ScriptParams[0], (eGarageType)ScriptParams[1], 0);
- return 0;
- /*
- case COMMAND_ACTIVATE_CRUSHER_CRANE:
- {
- CollectParameters(&m_nIp, 10);
- float infX = *(float*)&ScriptParams[2];
- float infY = *(float*)&ScriptParams[3];
- float supX = *(float*)&ScriptParams[4];
- float supY = *(float*)&ScriptParams[5];
- if (infX > supX) {
- infX = *(float*)&ScriptParams[4];
- supX = *(float*)&ScriptParams[2];
- }
- if (infY > supY) {
- infY = *(float*)&ScriptParams[5];
- supY = *(float*)&ScriptParams[3];
- }
- CCranes::ActivateCrane(infX, supX, infY, supY,
- *(float*)&ScriptParams[6], *(float*)&ScriptParams[7], *(float*)&ScriptParams[8],
- DEGTORAD(*(float*)&ScriptParams[9]), true, false,
- *(float*)&ScriptParams[0], *(float*)&ScriptParams[1]);
- return 0;
- }
- case COMMAND_PRINT_WITH_2_NUMBERS:
- {
- wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- CollectParameters(&m_nIp, 4);
- 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);
- CollectParameters(&m_nIp, 4);
- 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);
- CollectParameters(&m_nIp, 4);
- 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);
- CollectParameters(&m_nIp, 5);
- 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);
- CollectParameters(&m_nIp, 5);
- CMessages::AddMessageJumpQWithNumber(text, ScriptParams[3], ScriptParams[4], ScriptParams[0], ScriptParams[1], ScriptParams[2], -1, -1, -1);
- return 0;
- }
- case COMMAND_PRINT_WITH_3_NUMBERS_SOON:
- {
- wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- CollectParameters(&m_nIp, 5);
- 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);
- CollectParameters(&m_nIp, 6);
- 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);
- CollectParameters(&m_nIp, 6);
- CMessages::AddMessageJumpQWithNumber(text, ScriptParams[4], ScriptParams[5], ScriptParams[0], ScriptParams[1], ScriptParams[2], ScriptParams[3], -1, -1);
- return 0;
- }
- case COMMAND_PRINT_WITH_4_NUMBERS_SOON:
- {
- wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- CollectParameters(&m_nIp, 6);
- CMessages::AddMessageSoonWithNumber(text, ScriptParams[4], ScriptParams[5], ScriptParams[0], ScriptParams[1], ScriptParams[2], ScriptParams[3], -1, -1);
- return 0;
- }
- case COMMAND_PRINT_WITH_5_NUMBERS:
- {
- wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- CollectParameters(&m_nIp, 7);
- CMessages::AddMessageWithNumber(text, ScriptParams[5], ScriptParams[6], ScriptParams[0], ScriptParams[1], ScriptParams[2], ScriptParams[3], ScriptParams[4], -1);
- return 0;
- }
- case COMMAND_PRINT_WITH_5_NUMBERS_NOW:
- {
- wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- CollectParameters(&m_nIp, 7);
- CMessages::AddMessageJumpQWithNumber(text, ScriptParams[5], ScriptParams[6], ScriptParams[0], ScriptParams[1], ScriptParams[2], ScriptParams[3], ScriptParams[4], -1);
- return 0;
- }
- case COMMAND_PRINT_WITH_5_NUMBERS_SOON:
- {
- wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- CollectParameters(&m_nIp, 7);
- 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);
- CollectParameters(&m_nIp, 8);
- 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);
- CollectParameters(&m_nIp, 8);
- CMessages::AddMessageJumpQWithNumber(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_SOON:
- {
- wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- CollectParameters(&m_nIp, 8);
- CMessages::AddMessageSoonWithNumber(text, ScriptParams[6], ScriptParams[7], ScriptParams[0], ScriptParams[1], ScriptParams[2], ScriptParams[3], ScriptParams[4], ScriptParams[5]);
- return 0;
- }
- case COMMAND_SET_CHAR_OBJ_FOLLOW_CHAR_IN_FORMATION:
- {
- CollectParameters(&m_nIp, 3);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- CPed* pTargetPed = CPools::GetPedPool()->GetAt(ScriptParams[1]);
- pPed->bScriptObjectiveCompleted = false;
- pPed->SetObjective(OBJECTIVE_FOLLOW_CHAR_IN_FORMATION, pTargetPed);
- pPed->SetFormation((eFormation)ScriptParams[2]);
- return 0;
- }
- */
- case COMMAND_PLAYER_MADE_PROGRESS:
- CollectParameters(&m_nIp, 1);
- CStats::ProgressMade += ScriptParams[0];
- return 0;
- 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);
- CStats::MaximumJumpDistance = Max(CStats::MaximumJumpDistance, *(float*)&ScriptParams[0]);
- return 0;
- case COMMAND_REGISTER_JUMP_HEIGHT:
- CollectParameters(&m_nIp, 1);
- CStats::MaximumJumpHeight = Max(CStats::MaximumJumpHeight, *(float*)&ScriptParams[0]);
- return 0;
- case COMMAND_REGISTER_JUMP_FLIPS:
- CollectParameters(&m_nIp, 1);
- CStats::MaximumJumpFlips = Max(CStats::MaximumJumpFlips, ScriptParams[0]);
- return 0;
- case COMMAND_REGISTER_JUMP_SPINS:
- CollectParameters(&m_nIp, 1);
- CStats::MaximumJumpSpins = Max(CStats::MaximumJumpSpins, ScriptParams[0]);
- return 0;
- case COMMAND_REGISTER_JUMP_STUNT:
- CollectParameters(&m_nIp, 1);
- CStats::BestStuntJump = Max(CStats::BestStuntJump, ScriptParams[0]);
- return 0;
- case COMMAND_REGISTER_UNIQUE_JUMP_FOUND:
- ++CStats::NumberOfUniqueJumpsFound;
- return 0;
- case COMMAND_SET_UNIQUE_JUMPS_TOTAL:
- CollectParameters(&m_nIp, 1);
- CStats::TotalNumberOfUniqueJumps = ScriptParams[0];
- return 0;
- case COMMAND_REGISTER_PASSENGER_DROPPED_OFF_TAXI:
- ++CStats::PassengersDroppedOffWithTaxi;
- return 0;
- case COMMAND_REGISTER_MONEY_MADE_TAXI:
- CollectParameters(&m_nIp, 1);
- CStats::MoneyMadeWithTaxi += ScriptParams[0];
- return 0;
- case COMMAND_REGISTER_MISSION_GIVEN:
- ++CStats::MissionsGiven;
- return 0;
- case COMMAND_REGISTER_MISSION_PASSED:
- {
- char name[KEY_LENGTH_IN_SCRIPT];
- strncpy(name, (const char*)&CTheScripts::ScriptSpace[m_nIp], KEY_LENGTH_IN_SCRIPT);
- m_nIp += KEY_LENGTH_IN_SCRIPT;
- 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:
- {
- CollectParameters(&m_nIp, 2);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- pPed->bIsRunning = (ScriptParams[1] != 0);
- return 0;
- }
- case COMMAND_REMOVE_ALL_SCRIPT_FIRES:
- gFireManager.RemoveAllScriptFires();
- return 0;
- /*
- case COMMAND_IS_FIRST_CAR_COLOUR:
- {
- CollectParameters(&m_nIp, 2);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle);
- UpdateCompareFlag(pVehicle->m_currentColour1 == ScriptParams[1]);
- return 0;
- }
- case COMMAND_IS_SECOND_CAR_COLOUR:
- {
- CollectParameters(&m_nIp, 2);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle);
- 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");
- 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");
- 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:
- {
- CollectParameters(&m_nIp, 2);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- CPed* pLeader = CPools::GetPedPool()->GetAt(ScriptParams[1]);
- script_assert(pPed);
- script_assert(pLeader);
- UpdateCompareFlag(pPed->m_leader == pLeader);
- return 0;
- }
- default:
- script_assert(0);
- }
- return -1;
-}
-int8 CRunningScript::ProcessCommands800To899(int32 command)
-{
- CMatrix tmp_matrix;
- switch (command) {
- case COMMAND_IS_CHAR_IN_PLAYERS_GROUP:
- {
- CollectParameters(&m_nIp, 2);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- CPed* pLeader = CWorld::Players[ScriptParams[1]].m_pPed;
- script_assert(pPed);
- script_assert(pLeader);
- UpdateCompareFlag(pPed->m_leader == pLeader);
- return 0;
- }
- case COMMAND_EXPLODE_CHAR_HEAD:
- {
- CollectParameters(&m_nIp, 1);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- pPed->InflictDamage(nil, WEAPONTYPE_SNIPERRIFLE, 1000.0f, PEDPIECE_HEAD, 0);
- return 0;
- }
- case COMMAND_EXPLODE_PLAYER_HEAD:
- {
- CollectParameters(&m_nIp, 1);
- CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
- script_assert(pPed);
- pPed->InflictDamage(nil, WEAPONTYPE_SNIPERRIFLE, 1000.0f, PEDPIECE_HEAD, 0);
- return 0;
- }
- case COMMAND_ANCHOR_BOAT:
- {
- 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);
- return 0;
- }
- case COMMAND_SET_ZONE_GROUP:
- {
- char zone[KEY_LENGTH_IN_SCRIPT];
- CTheScripts::ReadTextLabelFromScript(&m_nIp, zone);
- m_nIp += KEY_LENGTH_IN_SCRIPT;
- CollectParameters(&m_nIp, 2);
- int zone_id = CTheZones::FindZoneByLabelAndReturnIndex(zone, ZONE_INFO);
- if (zone_id < 0) {
- printf("Couldn't find zone - %s\n", zone);
- return 0;
- }
- CTheZones::SetPedGroup(zone_id, ScriptParams[0], ScriptParams[1]);
- return 0;
- }
- case COMMAND_START_CAR_FIRE:
- {
- CollectParameters(&m_nIp, 1);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle);
- ScriptParams[0] = gFireManager.StartScriptFire(pVehicle->GetPosition(), pVehicle, 0.8f, 1);
- StoreParameters(&m_nIp, 1);
- return 0;
- }
- case COMMAND_START_CHAR_FIRE:
- {
- CollectParameters(&m_nIp, 1);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- ScriptParams[0] = gFireManager.StartScriptFire(pPed->GetPosition(), pPed, 0.8f, 1);
- StoreParameters(&m_nIp, 1);
- return 0;
- }
- case COMMAND_GET_RANDOM_CAR_OF_TYPE_IN_AREA:
- {
- 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 (!pVehicle->bUsesCollision)
- 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);
- pVehicle->VehicleCreatedBy = MISSION_VEHICLE;
- ++CCarCtrl::NumMissionCars;
- --CCarCtrl::NumRandomCars;
- if (m_bIsMissionScript)
- CTheScripts::MissionCleanup.AddEntityToList(handle, CLEANUP_CAR);
- }
- ScriptParams[0] = handle;
- 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, ZONE_DEFAULT);
- if (zone_id != -1)
- m_nIp += KEY_LENGTH_IN_SCRIPT;
- CZone* pZone = CTheZones::GetNavigationZone(zone_id);
- CollectParameters(&m_nIp, 1);
- int handle = -1;
- uint32 i = CPools::GetVehiclePool()->GetSize();
- while (i--) {
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetSlot(i);
- if (!pVehicle)
- continue;
- if (ScriptParams[0] != pVehicle->GetModelIndex() && ScriptParams[0] >= 0)
- continue;
- if (pVehicle->VehicleCreatedBy != RANDOM_VEHICLE)
- continue;
- if (!CTheZones::PointLiesWithinZone(&pVehicle->GetPosition(), pZone))
- continue;
- handle = CPools::GetVehiclePool()->GetIndex(pVehicle);
- pVehicle->VehicleCreatedBy = MISSION_VEHICLE;
- ++CCarCtrl::NumMissionCars;
- --CCarCtrl::NumRandomCars;
- if (m_bIsMissionScript)
- CTheScripts::MissionCleanup.AddEntityToList(handle, CLEANUP_CAR);
- }
- ScriptParams[0] = handle;
- StoreParameters(&m_nIp, 1);
- return 0;
- }
- */
- case COMMAND_HAS_RESPRAY_HAPPENED:
- {
- CollectParameters(&m_nIp, 1);
- UpdateCompareFlag(CGarages::HasResprayHappened(ScriptParams[0]));
- return 0;
- }
- case COMMAND_SET_CAMERA_ZOOM:
- {
- CollectParameters(&m_nIp, 1);
- if (TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_FOLLOWPED)
- TheCamera.SetZoomValueFollowPedScript(ScriptParams[0]);
- else if (TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_CAM_ON_A_STRING)
- TheCamera.SetZoomValueCamStringScript(ScriptParams[0]);
- return 0;
- }
- case COMMAND_CREATE_PICKUP_WITH_AMMO:
- {
- CollectParameters(&m_nIp, 6);
- int16 model = ScriptParams[0];
- if (model < 0)
- model = CTheScripts::UsedObjectArray[-model].index;
- CVector pos = *(CVector*)&ScriptParams[3];
- 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, model, ScriptParams[1], ScriptParams[2]);
- StoreParameters(&m_nIp, 1);
- return 0;
- }
- case COMMAND_SET_CAR_RAM_CAR:
- {
- CollectParameters(&m_nIp, 2);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle);
- CVehicle* pTarget = CPools::GetVehiclePool()->GetAt(ScriptParams[1]);
- script_assert(pTarget);
- CCarAI::TellCarToRamOtherCar(pVehicle, pTarget);
- return 0;
- }
- /*
- case COMMAND_SET_CAR_BLOCK_CAR:
- {
- CollectParameters(&m_nIp, 2);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle);
- CVehicle* pTarget = CPools::GetVehiclePool()->GetAt(ScriptParams[1]);
- script_assert(pTarget);
- CCarAI::TellCarToBlockOtherCar(pVehicle, pTarget);
- return 0;
- }
- case COMMAND_SET_CHAR_OBJ_CATCH_TRAIN:
- {
- CollectParameters(&m_nIp, 1);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- pPed->bScriptObjectiveCompleted = false;
- pPed->SetObjective(OBJECTIVE_CATCH_TRAIN);
- return 0;
- }
- */
- //case COMMAND_SET_COLL_OBJ_CATCH_TRAIN:
- case COMMAND_SET_PLAYER_NEVER_GETS_TIRED:
- {
- CollectParameters(&m_nIp, 2);
- CPlayerInfo* pPlayer = &CWorld::Players[ScriptParams[0]];
- pPlayer->m_bInfiniteSprint = (ScriptParams[1] != 0);
- return 0;
- }
- case COMMAND_SET_PLAYER_FAST_RELOAD:
- {
- CollectParameters(&m_nIp, 2);
- CPlayerInfo* pPlayer = &CWorld::Players[ScriptParams[0]];
- pPlayer->m_bFastReload = (ScriptParams[1] != 0);
- return 0;
- }
- case COMMAND_SET_CHAR_BLEEDING:
- {
- CollectParameters(&m_nIp, 2);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- pPed->bPedIsBleeding = (ScriptParams[1] != 0);
- return 0;
- }
- /*
- case COMMAND_SET_CAR_FUNNY_SUSPENSION:
- {
- CollectParameters(&m_nIp, 2);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle);
- // no action
- return 0;
- }
- case COMMAND_SET_CAR_BIG_WHEELS:
- {
- 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->bBigWheels = (ScriptParams[1] != 0);
- return 0;
- }
- */
- case COMMAND_SET_FREE_RESPRAYS:
- CollectParameters(&m_nIp, 1);
- CGarages::SetFreeResprays(ScriptParams[0] != 0);
- return 0;
- case COMMAND_SET_PLAYER_VISIBLE:
- {
- CollectParameters(&m_nIp, 2);
- CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
- script_assert(pPed);
- pPed->bIsVisible = (ScriptParams[1] != 0);
- return 0;
- }
- case COMMAND_SET_CHAR_VISIBLE:
- {
- CollectParameters(&m_nIp, 2);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- pPed->bIsVisible = (ScriptParams[1] != 0);
- return 0;
- }
- /*
- case COMMAND_SET_CAR_VISIBLE:
- {
- CollectParameters(&m_nIp, 2);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle);
- pVehicle->bIsVisible = (ScriptParams[1] != 0);
- return 0;
- }
- */
- case COMMAND_IS_AREA_OCCUPIED:
- {
- CollectParameters(&m_nIp, 11);
- 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];
- }
- int16 total;
- CWorld::FindObjectsIntersectingCube(CVector(infX, infY, infZ), CVector(supX, supY, supZ), &total, 2, nil,
- !!ScriptParams[6], !!ScriptParams[7], !!ScriptParams[8], !!ScriptParams[9], !!ScriptParams[10]);
- UpdateCompareFlag(total > 0);
- return 0;
- }
- /*
- case COMMAND_START_DRUG_RUN:
- CPlane::CreateIncomingCesna();
- return 0;
- case COMMAND_HAS_DRUG_RUN_BEEN_COMPLETED:
- UpdateCompareFlag(CPlane::HasCesnaLanded());
- return 0;
- case COMMAND_HAS_DRUG_PLANE_BEEN_SHOT_DOWN:
- UpdateCompareFlag(CPlane::HasCesnaBeenDestroyed());
- return 0;
- case COMMAND_SAVE_PLAYER_FROM_FIRES:
- CollectParameters(&m_nIp, 1);
- gFireManager.ExtinguishPoint(CWorld::Players[ScriptParams[0]].GetPos(), 3.0f);
- return 0;
- */
- case COMMAND_DISPLAY_TEXT:
- {
- CollectParameters(&m_nIp, 2);
- wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- CTheScripts::IntroTextLines[CTheScripts::NumberOfIntroTextLinesThisFrame].m_fAtX = *(float*)&ScriptParams[0];
- CTheScripts::IntroTextLines[CTheScripts::NumberOfIntroTextLinesThisFrame].m_fAtY = *(float*)&ScriptParams[1];
- uint16 len = CMessages::GetWideStringLength(text);
- for (uint16 i = 0; i < len; i++)
- CTheScripts::IntroTextLines[CTheScripts::NumberOfIntroTextLinesThisFrame].m_Text[i] = text[i];
- for (uint16 i = len; i < SCRIPT_TEXT_MAX_LENGTH; i++)
- CTheScripts::IntroTextLines[CTheScripts::NumberOfIntroTextLinesThisFrame].m_Text[i] = 0;
- ++CTheScripts::NumberOfIntroTextLinesThisFrame;
- return 0;
- }
- case COMMAND_SET_TEXT_SCALE:
- {
- CollectParameters(&m_nIp, 2);
- CTheScripts::IntroTextLines[CTheScripts::NumberOfIntroTextLinesThisFrame].m_fScaleX = *(float*)&ScriptParams[0];
- CTheScripts::IntroTextLines[CTheScripts::NumberOfIntroTextLinesThisFrame].m_fScaleY = *(float*)&ScriptParams[1];
- return 0;
- }
- case COMMAND_SET_TEXT_COLOUR:
- {
- CollectParameters(&m_nIp, 4);
- CTheScripts::IntroTextLines[CTheScripts::NumberOfIntroTextLinesThisFrame].m_sColor =
- CRGBA(ScriptParams[0], ScriptParams[1], ScriptParams[2], ScriptParams[3]);
- return 0;
- }
- case COMMAND_SET_TEXT_JUSTIFY:
- {
- CollectParameters(&m_nIp, 1);
- CTheScripts::IntroTextLines[CTheScripts::NumberOfIntroTextLinesThisFrame].m_bJustify = (ScriptParams[0] != 0);
- return 0;
- }
- case COMMAND_SET_TEXT_CENTRE:
- {
- CollectParameters(&m_nIp, 1);
- CTheScripts::IntroTextLines[CTheScripts::NumberOfIntroTextLinesThisFrame].m_bCentered = (ScriptParams[0] != 0);
- return 0;
- }
- case COMMAND_SET_TEXT_WRAPX:
- {
- CollectParameters(&m_nIp, 1);
- 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);
- CTheScripts::IntroTextLines[CTheScripts::NumberOfIntroTextLinesThisFrame].m_sBackgroundColor =
- CRGBA(ScriptParams[0], ScriptParams[1], ScriptParams[2], ScriptParams[3]);
- return 0;
- }
- case COMMAND_SET_TEXT_BACKGROUND_ONLY_TEXT:
- {
- CollectParameters(&m_nIp, 1);
- 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);
- CTheScripts::IntroTextLines[CTheScripts::NumberOfIntroTextLinesThisFrame].m_nFont = ScriptParams[0];
- return 0;
- }
- case COMMAND_INDUSTRIAL_PASSED:
- CStats::IndustrialPassed = true;
- DMAudio.PlayRadioAnnouncement(STREAMED_SOUND_ANNOUNCE_COMMERCIAL_OPEN);
- return 0;
- case COMMAND_COMMERCIAL_PASSED:
- CStats::CommercialPassed = true;
- DMAudio.PlayRadioAnnouncement(STREAMED_SOUND_ANNOUNCE_SUBURBAN_OPEN);
- return 0;
- case COMMAND_SUBURBAN_PASSED:
- CStats::SuburbanPassed = true;
- return 0;
- */
- case COMMAND_ROTATE_OBJECT:
- {
- CollectParameters(&m_nIp, 4);
- CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
- script_assert(pObject);
- float heading = LimitAngleOnCircle(
- RADTODEG(Atan2(-pObject->GetForward().x, pObject->GetForward().y)));
- float headingTarget = *(float*)&ScriptParams[1];
-#ifdef FIX_BUGS
- float rotateBy = *(float*)&ScriptParams[2] * CTimer::GetTimeStepFix();
-#else
- float rotateBy = *(float*)&ScriptParams[2];
-#endif
- if (headingTarget == heading) { // using direct comparasion here is fine
- UpdateCompareFlag(true);
- return 0;
- }
- float angleClockwise = LimitAngleOnCircle(headingTarget - heading);
- float angleCounterclockwise = LimitAngleOnCircle(heading - headingTarget);
- float newHeading;
- if (angleClockwise < angleCounterclockwise)
- newHeading = rotateBy < angleClockwise ? heading + rotateBy : headingTarget;
- else
- newHeading = rotateBy < angleCounterclockwise ? heading - rotateBy : headingTarget;
- bool obstacleInPath = false;
- if (ScriptParams[3]) {
- CVector pos = pObject->GetPosition();
- tmp_matrix.SetRotateZ(DEGTORAD(newHeading));
- tmp_matrix.GetPosition() += pos;
- CColModel* pColModel = pObject->GetColModel();
- CVector cp1 = tmp_matrix * pColModel->boundingBox.min;
- CVector cp2 = tmp_matrix * CVector(pColModel->boundingBox.max.x, pColModel->boundingBox.min.y, pColModel->boundingBox.min.z);
- CVector cp3 = tmp_matrix * CVector(pColModel->boundingBox.min.x, pColModel->boundingBox.max.y, pColModel->boundingBox.min.z);
- CVector cp4 = tmp_matrix * CVector(pColModel->boundingBox.min.x, pColModel->boundingBox.min.y, pColModel->boundingBox.max.z);
- int16 collisions;
- CWorld::FindObjectsIntersectingAngledCollisionBox(pColModel->boundingBox, tmp_matrix, pos,
- Min(cp1.x, Min(cp2.x, Min(cp3.x, cp4.x))),
- Min(cp1.y, Min(cp2.y, Min(cp3.y, cp4.y))),
- Max(cp1.x, Max(cp2.x, Max(cp3.x, cp4.x))),
- Max(cp1.y, Max(cp2.y, Max(cp3.y, cp4.y))),
- &collisions, 2, nil, false, true, true, false, false);
- if (collisions > 0)
- obstacleInPath = true;
- }
- if (obstacleInPath) {
- UpdateCompareFlag(true);
- return 0;
- }
- pObject->SetHeading(DEGTORAD(newHeading));
- pObject->GetMatrix().UpdateRW();
- pObject->UpdateRwFrame();
- UpdateCompareFlag(newHeading == headingTarget); // using direct comparasion here is fine
- return 0;
- }
- case COMMAND_SLIDE_OBJECT:
- {
- CollectParameters(&m_nIp, 8);
- CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
- 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];
-#endif
- if (posTarget == pos) { // using direct comparasion here is fine
- UpdateCompareFlag(true);
- return 0;
- }
- CVector posDiff = pos - posTarget;
- CVector newPosition;
- if (posDiff.x < 0)
- newPosition.x = -posDiff.x < slideBy.x ? posTarget.x : pos.x + slideBy.x;
- else
- newPosition.x = posDiff.x < slideBy.x ? posTarget.x : pos.x - slideBy.x;
- if (posDiff.y < 0)
- newPosition.y = -posDiff.y < slideBy.y ? posTarget.y : pos.y + slideBy.y;
- else
- newPosition.y = posDiff.y < slideBy.y ? posTarget.y : pos.y - slideBy.y;
- if (posDiff.z < 0)
- newPosition.z = -posDiff.z < slideBy.z ? posTarget.z : pos.z + slideBy.z;
- else
- newPosition.z = posDiff.z < slideBy.z ? posTarget.z : pos.z - slideBy.z;
- bool obstacleInPath = false;
- if (ScriptParams[7]) {
- tmp_matrix = pObject->GetMatrix();
- tmp_matrix.GetPosition() = newPosition;
- CColModel* pColModel = pObject->GetColModel();
- CVector cp1 = tmp_matrix * pColModel->boundingBox.min;
- CVector cp2 = tmp_matrix * CVector(pColModel->boundingBox.max.x, pColModel->boundingBox.min.y, pColModel->boundingBox.min.z);
- CVector cp3 = tmp_matrix * CVector(pColModel->boundingBox.min.x, pColModel->boundingBox.max.y, pColModel->boundingBox.min.z);
- CVector cp4 = tmp_matrix * CVector(pColModel->boundingBox.min.x, pColModel->boundingBox.min.y, pColModel->boundingBox.max.z);
- int16 collisions;
- CWorld::FindObjectsIntersectingAngledCollisionBox(pColModel->boundingBox, tmp_matrix, newPosition,
- Min(cp1.x, Min(cp2.x, Min(cp3.x, cp4.x))),
- Min(cp1.y, Min(cp2.y, Min(cp3.y, cp4.y))),
- Max(cp1.x, Max(cp2.x, Max(cp3.x, cp4.x))),
- Max(cp1.y, Max(cp2.y, Max(cp3.y, cp4.y))),
- &collisions, 2, nil, false, true, true, false, false);
- if (collisions > 0)
- obstacleInPath = true;
- }
- if (obstacleInPath) {
- UpdateCompareFlag(true);
- return 0;
- }
- pObject->Teleport(newPosition);
- UpdateCompareFlag(newPosition == posTarget); // using direct comparasion here is fine
- return 0;
- }
- case COMMAND_REMOVE_CHAR_ELEGANTLY:
- {
- CollectParameters(&m_nIp, 1);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- if (pPed && pPed->CharCreatedBy == MISSION_CHAR){
- CWorld::RemoveReferencesToDeletedObject(pPed);
- 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)
- CTheScripts::MissionCleanup.RemoveEntityFromList(ScriptParams[0], CLEANUP_CHAR);
- return 0;
- }
- case COMMAND_SET_CHAR_STAY_IN_SAME_PLACE:
- {
- CollectParameters(&m_nIp, 2);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- 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);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- char name[KEY_LENGTH_IN_SCRIPT];
- CTheScripts::ReadTextLabelFromScript(&m_nIp, name);
- for (int i = 0; i < KEY_LENGTH_IN_SCRIPT; i++)
- name[i] = tolower(name[i]);
- m_nIp += KEY_LENGTH_IN_SCRIPT;
- pPed->Undress(name);
- return 0;
- }
- case COMMAND_DRESS_CHAR:
- {
- CollectParameters(&m_nIp, 1);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- pPed->Dress();
- return 0;
- }
- /*
- case COMMAND_START_CHASE_SCENE:
- CollectParameters(&m_nIp, 1);
- CTimer::Suspend();
- CStreaming::DeleteAllRwObjects();
- CRecordDataForChase::StartChaseScene(*(float*)&ScriptParams[0]);
- CTimer::Resume();
- return 0;
- case COMMAND_STOP_CHASE_SCENE:
- CRecordDataForChase::CleanUpChaseScene();
- return 0;
- case COMMAND_IS_EXPLOSION_IN_AREA:
- {
- CollectParameters(&m_nIp, 7);
- float infX = *(float*)&ScriptParams[1];
- float infY = *(float*)&ScriptParams[2];
- float infZ = *(float*)&ScriptParams[3];
- float supX = *(float*)&ScriptParams[4];
- float supY = *(float*)&ScriptParams[5];
- float supZ = *(float*)&ScriptParams[6];
- if (infX > supX) {
- infX = *(float*)&ScriptParams[4];
- supX = *(float*)&ScriptParams[1];
- }
- if (infY > supY) {
- infY = *(float*)&ScriptParams[5];
- supY = *(float*)&ScriptParams[2];
- }
- if (infZ > supZ) {
- infZ = *(float*)&ScriptParams[6];
- supZ = *(float*)&ScriptParams[3];
- }
- UpdateCompareFlag(CExplosion::TestForExplosionInArea((eExplosionType)ScriptParams[0],
- infX, supX, infY, supY, infZ, supZ));
- return 0;
- }
- case COMMAND_IS_EXPLOSION_IN_ZONE:
- {
- CollectParameters(&m_nIp, 1);
- char zone[KEY_LENGTH_IN_SCRIPT];
- CTheScripts::ReadTextLabelFromScript(&m_nIp, zone);
- int zone_id = CTheZones::FindZoneByLabelAndReturnIndex(zone, ZONE_DEFAULT);
- if (zone_id != -1)
- m_nIp += KEY_LENGTH_IN_SCRIPT;
- 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;
- }
- case COMMAND_START_DRUG_DROP_OFF:
- CPlane::CreateDropOffCesna();
- return 0;
- case COMMAND_HAS_DROP_OFF_PLANE_BEEN_SHOT_DOWN:
- UpdateCompareFlag(CPlane::HasDropOffCesnaBeenShotDown());
- return 0;
- case COMMAND_FIND_DROP_OFF_PLANE_COORDINATES:
- {
- CVector pos = CPlane::FindDropOffCesnaCoordinates();
- *(CVector*)&ScriptParams[0] = pos;
- StoreParameters(&m_nIp, 3);
- return 0;
- }
- case COMMAND_CREATE_FLOATING_PACKAGE:
- {
- 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;
- ScriptParams[0] = CPickups::GenerateNewOne(pos, MI_FLOATPACKAGE1, PICKUP_FLOATINGPACKAGE, 0);
- StoreParameters(&m_nIp, 1);
- return 0;
- }
- */
- case COMMAND_PLACE_OBJECT_RELATIVE_TO_CAR:
- {
- CollectParameters(&m_nIp, 5);
- CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
- script_assert(pObject);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[1]);
- script_assert(pVehicle);
- CVector offset = *(CVector*)&ScriptParams[2];
- CPhysical::PlacePhysicalRelativeToOtherPhysical(pVehicle, pObject, offset);
- return 0;
- }
- case COMMAND_MAKE_OBJECT_TARGETTABLE:
- {
- CollectParameters(&m_nIp, 1);
- CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
- script_assert(pObject);
- CPlayerPed* pPlayerPed = CWorld::Players[CWorld::PlayerInFocus].m_pPed;
- script_assert(pPlayerPed);
- pPlayerPed->MakeObjectTargettable(ScriptParams[0]);
- return 0;
- }
- case COMMAND_ADD_ARMOUR_TO_PLAYER:
- {
- 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, CWorld::Players[ScriptParams[0]].m_nMaxArmour);
- return 0;
- }
- case COMMAND_ADD_ARMOUR_TO_CHAR:
- {
- CollectParameters(&m_nIp, 2);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- pPed->m_fArmour = clamp(pPed->m_fArmour + ScriptParams[1], 0.0f, 100.0f);
- return 0;
- }
- case COMMAND_OPEN_GARAGE:
- {
- CollectParameters(&m_nIp, 1);
- CGarages::OpenGarage(ScriptParams[0]);
- return 0;
- }
- case COMMAND_CLOSE_GARAGE:
- {
- CollectParameters(&m_nIp, 1);
- CGarages::CloseGarage(ScriptParams[0]);
- return 0;
- }
- case COMMAND_WARP_CHAR_FROM_CAR_TO_COORD:
- {
- CollectParameters(&m_nIp, 4);
- CPed *pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- CVector pos = *(CVector*)&ScriptParams[1];
- if (pos.z <= MAP_Z_LOW_LIMIT)
- pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
- if (pPed->bInVehicle){
- if (pPed->m_pMyVehicle->bIsBus)
- pPed->bRenderPedInCar = true;
- if (pPed->m_pMyVehicle->pDriver == pPed){
- pPed->m_pMyVehicle->RemoveDriver();
- 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);
- }
- 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->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, 1000.0f);
- pos.z += pPed->GetDistanceFromCentreOfMassToBaseOfModel();
- pPed->Teleport(pos);
- CTheScripts::ClearSpaceForMissionEntity(pos, pPed);
- return 0;
- }
- case COMMAND_SET_VISIBILITY_OF_CLOSEST_OBJECT_OF_TYPE:
- {
- CollectParameters(&m_nIp, 6);
- CVector pos = *(CVector*)&ScriptParams[0];
- if (pos.z <= MAP_Z_LOW_LIMIT)
- pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
- float range = *(float*)&ScriptParams[3];
- int mi = ScriptParams[4] < 0 ? CTheScripts::UsedObjectArray[-ScriptParams[4]].index : ScriptParams[4];
- int16 total;
- CEntity* apEntities[16];
- CWorld::FindObjectsOfTypeInRange(mi, pos, range, true, &total, 16, apEntities, true, false, false, true, true);
- 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::GetLevelFromPosition(&pos)), pos, range, true, &total, 16, apEntities);
- CEntity* pClosestEntity = nil;
- float min_dist = 2.0f * range;
- for (int i = 0; i < total; i++) {
- float dist = (apEntities[i]->GetPosition() - pos).Magnitude();
- if (dist < min_dist) {
- min_dist = dist;
- pClosestEntity = apEntities[i];
- }
- }
- if (pClosestEntity) {
- pClosestEntity->bIsVisible = (ScriptParams[5] != 0);
- CTheScripts::AddToInvisibilitySwapArray(pClosestEntity, ScriptParams[5] != 0);
- }
- return 0;
- }
- /*
- case COMMAND_HAS_CHAR_SPOTTED_CHAR:
- {
- CollectParameters(&m_nIp, 2);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- CPed* pTarget = CPools::GetPedPool()->GetAt(ScriptParams[1]);
- script_assert(pTarget);
- UpdateCompareFlag(pPed->OurPedCanSeeThisOne(pTarget));
- return 0;
- }
- */
- case COMMAND_SET_CHAR_OBJ_HAIL_TAXI:
- {
- CollectParameters(&m_nIp, 1);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- pPed->bScriptObjectiveCompleted = false;
- pPed->SetObjective(OBJECTIVE_HAIL_TAXI);
- return 0;
- }
- case COMMAND_HAS_OBJECT_BEEN_DAMAGED:
- {
- CollectParameters(&m_nIp, 1);
- CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
- script_assert(pObject);
- UpdateCompareFlag(pObject->bRenderDamaged || !pObject->bIsVisible);
- return 0;
- }
- /*
- case COMMAND_START_KILL_FRENZY_HEADSHOT:
- {
- wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- CollectParameters(&m_nIp, 8);
- CDarkel::StartFrenzy((eWeaponType)ScriptParams[0], ScriptParams[1], ScriptParams[2],
- ScriptParams[3], text, ScriptParams[4], ScriptParams[5],
- ScriptParams[6], ScriptParams[7] != 0, true);
- return 0;
- }
- case COMMAND_ACTIVATE_MILITARY_CRANE:
- {
- CollectParameters(&m_nIp, 10);
- float infX = *(float*)&ScriptParams[2];
- float infY = *(float*)&ScriptParams[3];
- float supX = *(float*)&ScriptParams[4];
- float supY = *(float*)&ScriptParams[5];
- if (infX > supX) {
- infX = *(float*)&ScriptParams[4];
- supX = *(float*)&ScriptParams[2];
- }
- if (infY > supY) {
- infY = *(float*)&ScriptParams[5];
- supY = *(float*)&ScriptParams[3];
- }
- CCranes::ActivateCrane(infX, supX, infY, supY,
- *(float*)&ScriptParams[6], *(float*)&ScriptParams[7], *(float*)&ScriptParams[8],
- DEGTORAD(*(float*)&ScriptParams[9]), false, true,
- *(float*)&ScriptParams[0], *(float*)&ScriptParams[1]);
- return 0;
- }
- */
- case COMMAND_WARP_PLAYER_INTO_CAR:
- {
- CollectParameters(&m_nIp, 2);
- CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
- script_assert(pPed);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[1]);
- script_assert(pVehicle);
- pPed->SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, pVehicle);
- pPed->WarpPedIntoCar(pVehicle);
- return 0;
- }
- case COMMAND_WARP_CHAR_INTO_CAR:
- {
- CollectParameters(&m_nIp, 2);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[1]);
- script_assert(pVehicle);
- pPed->SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, pVehicle);
- pPed->WarpPedIntoCar(pVehicle);
- return 0;
- }
- //case COMMAND_SWITCH_CAR_RADIO:
- //case COMMAND_SET_AUDIO_STREAM:
- case COMMAND_PRINT_WITH_2_NUMBERS_BIG:
- {
- wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- CollectParameters(&m_nIp, 4);
- 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);
- CollectParameters(&m_nIp, 5);
- CMessages::AddBigMessageWithNumber(text, ScriptParams[3], ScriptParams[4] - 1, ScriptParams[0], ScriptParams[1], ScriptParams[2], -1, -1, -1);
- return 0;
- }
- case COMMAND_PRINT_WITH_4_NUMBERS_BIG:
- {
- wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- CollectParameters(&m_nIp, 6);
- CMessages::AddBigMessageWithNumber(text, ScriptParams[4], ScriptParams[5] - 1, ScriptParams[0], ScriptParams[1], ScriptParams[2], ScriptParams[3], -1, -1);
- return 0;
- }
- case COMMAND_PRINT_WITH_5_NUMBERS_BIG:
- {
- wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- CollectParameters(&m_nIp, 7);
- CMessages::AddBigMessageWithNumber(text, ScriptParams[5], ScriptParams[6] - 1, ScriptParams[0], ScriptParams[1], ScriptParams[2], ScriptParams[3], ScriptParams[4], -1);
- return 0;
- }
- case COMMAND_PRINT_WITH_6_NUMBERS_BIG:
- {
- wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- CollectParameters(&m_nIp, 8);
- 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);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- pPed->SetWaitState((eWaitState)ScriptParams[1], ScriptParams[2] >= 0 ? &ScriptParams[2] : nil);
- return 0;
- }
- 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]);
- return 0;
- case COMMAND_PRINT_STRING_IN_STRING:
- {
- wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- wchar* string = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- CollectParameters(&m_nIp, 2);
- CMessages::AddMessageWithString(text, ScriptParams[0], ScriptParams[1], string);
- return 0;
- }
- */
- case COMMAND_CREATE_RANDOM_CHAR:
- {
- CollectParameters(&m_nIp, 3);
- CZoneInfo zoneinfo;
- CTheZones::GetZoneInfoForTimeOfDay(&CWorld::Players[CWorld::PlayerInFocus].GetPos(), &zoneinfo);
- int mi;
- ePedType pedtype = PEDTYPE_COP;
- int attempt = 0;
- while (pedtype != PEDTYPE_CIVMALE && pedtype != PEDTYPE_CIVFEMALE && attempt < 5) {
- mi = CPopulation::ChooseCivilianOccupation(zoneinfo.pedGroup);
- if (CModelInfo::GetModelInfo(mi)->GetRwObject())
- pedtype = ((CPedModelInfo*)(CModelInfo::GetModelInfo(mi)))->m_pedType;
- attempt++;
- }
- if (!CModelInfo::GetModelInfo(mi)->GetRwObject()) {
- mi = MI_MALE01;
- pedtype = ((CPedModelInfo*)(CModelInfo::GetModelInfo(mi)))->m_pedType;
- }
- CPed* ped = new CCivilianPed(pedtype, mi);
- 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);
- pos.z += 1.0f;
- 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++;
- ScriptParams[0] = CPools::GetPedPool()->GetIndex(ped);
- StoreParameters(&m_nIp, 1);
- if (m_bIsMissionScript)
- CTheScripts::MissionCleanup.AddEntityToList(ScriptParams[0], CLEANUP_CHAR);
- return 0;
- }
- case COMMAND_SET_CHAR_OBJ_STEAL_ANY_CAR:
- {
- CollectParameters(&m_nIp, 1);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- pPed->bScriptObjectiveCompleted = false;
- pPed->SetObjective(OBJECTIVE_STEAL_ANY_CAR);
- return 0;
- }
- /*
- case COMMAND_SET_2_REPEATED_PHONE_MESSAGES:
- {
- CollectParameters(&m_nIp, 1);
- wchar* text1 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- wchar* text2 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- gPhoneInfo.SetPhoneMessage_Repeatedly(ScriptParams[0], text1, text2, nil, nil, nil, nil);
- return 0;
- }
- case COMMAND_SET_2_PHONE_MESSAGES:
- {
- CollectParameters(&m_nIp, 1);
- wchar* text1 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- wchar* text2 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- gPhoneInfo.SetPhoneMessage_JustOnce(ScriptParams[0], text1, text2, nil, nil, nil, nil);
- return 0;
- }
- case COMMAND_SET_3_REPEATED_PHONE_MESSAGES:
- {
- CollectParameters(&m_nIp, 1);
- wchar* text1 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- wchar* text2 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- wchar* text3 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- gPhoneInfo.SetPhoneMessage_Repeatedly(ScriptParams[0], text1, text2, text3, nil, nil, nil);
- return 0;
- }
- case COMMAND_SET_3_PHONE_MESSAGES:
- {
- CollectParameters(&m_nIp, 1);
- wchar* text1 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- wchar* text2 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- wchar* text3 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- gPhoneInfo.SetPhoneMessage_JustOnce(ScriptParams[0], text1, text2, text3, nil, nil, nil);
- return 0;
- }
- case COMMAND_SET_4_REPEATED_PHONE_MESSAGES:
- {
- CollectParameters(&m_nIp, 1);
- wchar* text1 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- wchar* text2 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- wchar* text3 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- wchar* text4 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- gPhoneInfo.SetPhoneMessage_Repeatedly(ScriptParams[0], text1, text2, text3, text4, nil, nil);
- return 0;
- }
- case COMMAND_SET_4_PHONE_MESSAGES:
- {
- CollectParameters(&m_nIp, 1);
- wchar* text1 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- wchar* text2 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- wchar* text3 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- wchar* text4 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- gPhoneInfo.SetPhoneMessage_JustOnce(ScriptParams[0], text1, text2, text3, text4, nil, nil);
- return 0;
- }
- */
- case COMMAND_IS_SNIPER_BULLET_IN_AREA:
- {
- CollectParameters(&m_nIp, 6);
- 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];
- }
- 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:
- {
- CollectParameters(&m_nIp, 4);
- CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
- script_assert(pObject);
- pObject->SetMoveSpeed(*(CVector*)&ScriptParams[1] * METERS_PER_SECOND_TO_GAME_SPEED);
- return 0;
- }
- case COMMAND_SET_OBJECT_COLLISION:
- {
- CollectParameters(&m_nIp, 2);
- CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
- script_assert(pObject);
- pObject->bUsesCollision = (ScriptParams[1] != 0);
- return 0;
- }
- case COMMAND_IS_ICECREAM_JINGLE_ON:
- {
- CollectParameters(&m_nIp, 1);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle);
- // Adding this check to correspond to command name.
- // All original game scripts always assume that the vehicle is actually Mr. Whoopee,
- // but maybe there are mods that use it as "is alarm activated"?
- script_assert(pVehicle->GetModelIndex() == MI_MRWHOOP);
- UpdateCompareFlag(pVehicle->m_bSirenOrAlarm);
- return 0;
- }
- default:
- script_assert(0);
- }
- return -1;
-}
-
-int8 CRunningScript::ProcessCommands900To999(int32 command)
-{
- char str[52];
- char onscreen_str[KEY_LENGTH_IN_SCRIPT];
- switch (command) {
- case COMMAND_PRINT_STRING_IN_STRING_NOW:
- {
- wchar* source = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- wchar* pstr = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- CollectParameters(&m_nIp, 2);
- CMessages::AddMessageJumpQWithString(source, ScriptParams[0], ScriptParams[1], pstr);
- return 0;
- }
- //case COMMAND_PRINT_STRING_IN_STRING_SOON:
- /*
- case COMMAND_SET_5_REPEATED_PHONE_MESSAGES:
- {
- CollectParameters(&m_nIp, 1);
- wchar* text1 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- wchar* text2 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- wchar* text3 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- wchar* text4 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- wchar* text5 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- gPhoneInfo.SetPhoneMessage_Repeatedly(ScriptParams[0], text1, text2, text3, text4, text5, nil);
- return 0;
- }
- case COMMAND_SET_5_PHONE_MESSAGES:
- {
- CollectParameters(&m_nIp, 1);
- wchar* text1 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- wchar* text2 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- wchar* text3 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- wchar* text4 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- wchar* text5 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- gPhoneInfo.SetPhoneMessage_JustOnce(ScriptParams[0], text1, text2, text3, text4, text5, nil);
- return 0;
- }
- case COMMAND_SET_6_REPEATED_PHONE_MESSAGES:
- {
- CollectParameters(&m_nIp, 1);
- wchar* text1 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- wchar* text2 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- wchar* text3 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- wchar* text4 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- wchar* text5 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- wchar* text6 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- gPhoneInfo.SetPhoneMessage_Repeatedly(ScriptParams[0], text1, text2, text3, text4, text5, text6);
- return 0;
- }
- case COMMAND_SET_6_PHONE_MESSAGES:
- {
- CollectParameters(&m_nIp, 1);
- wchar* text1 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- wchar* text2 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- wchar* text3 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- wchar* text4 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- wchar* text5 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- wchar* text6 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- 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);
- float infX = *(float*)&ScriptParams[0] - *(float*)&ScriptParams[3];
- float supX = *(float*)&ScriptParams[0] + *(float*)&ScriptParams[3];
- float infY = *(float*)&ScriptParams[1] - *(float*)&ScriptParams[4];
- float supY = *(float*)&ScriptParams[1] + *(float*)&ScriptParams[4];
- float infZ = *(float*)&ScriptParams[2] - *(float*)&ScriptParams[5];
- float supZ = *(float*)&ScriptParams[2] + *(float*)&ScriptParams[5];
- if (infX > supX) {
- float tmp = infX;
- infX = supX;
- supX = tmp;
- }
- if (infY > supY) {
- float tmp = infY;
- infY = supY;
- supY = tmp;
- }
- if (infZ > supZ) {
- float tmp = infZ;
- infZ = supZ;
- supZ = tmp;
- }
- int16 total;
- CWorld::FindMissionEntitiesIntersectingCube(CVector(infX, infY, infZ), CVector(supX, supY, supZ), &total, 2, nil, true, true, true);
- UpdateCompareFlag(total > 0);
- 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->AddToMoveSpeed(*(CVector*)&ScriptParams[1] * METERS_PER_SECOND_TO_GAME_SPEED);
- return 0;
- }
- case COMMAND_DRAW_SPRITE:
- {
- CollectParameters(&m_nIp, 9);
- CTheScripts::IntroRectangles[CTheScripts::NumberOfIntroRectanglesThisFrame].m_bIsUsed = true;
- CTheScripts::IntroRectangles[CTheScripts::NumberOfIntroRectanglesThisFrame].m_nTextureId = ScriptParams[0] - 1;
- CTheScripts::IntroRectangles[CTheScripts::NumberOfIntroRectanglesThisFrame].m_sRect = CRect(
- *(float*)&ScriptParams[1], *(float*)&ScriptParams[2], *(float*)&ScriptParams[1] + *(float*)&ScriptParams[3], *(float*)&ScriptParams[2] + *(float*)&ScriptParams[4]);
- CTheScripts::IntroRectangles[CTheScripts::NumberOfIntroRectanglesThisFrame].m_sColor = CRGBA(ScriptParams[5], ScriptParams[6], ScriptParams[7], ScriptParams[8]);
- CTheScripts::NumberOfIntroRectanglesThisFrame++;
- return 0;
- }
- case COMMAND_DRAW_RECT:
- {
- CollectParameters(&m_nIp, 8);
- CTheScripts::IntroRectangles[CTheScripts::NumberOfIntroRectanglesThisFrame].m_bIsUsed = true;
- CTheScripts::IntroRectangles[CTheScripts::NumberOfIntroRectanglesThisFrame].m_nTextureId = -1;
- CTheScripts::IntroRectangles[CTheScripts::NumberOfIntroRectanglesThisFrame].m_sRect = CRect(
- *(float*)&ScriptParams[0], *(float*)&ScriptParams[1], *(float*)&ScriptParams[0] + *(float*)&ScriptParams[2], *(float*)&ScriptParams[1] + *(float*)&ScriptParams[3]);
- CTheScripts::IntroRectangles[CTheScripts::NumberOfIntroRectanglesThisFrame].m_sColor = CRGBA(ScriptParams[4], ScriptParams[5], ScriptParams[6], ScriptParams[7]);
- CTheScripts::NumberOfIntroRectanglesThisFrame++;
- return 0;
- }
- case COMMAND_LOAD_SPRITE:
- {
- 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;
- int slot = CTxdStore::FindTxdSlot("script");
- CTxdStore::PushCurrentTxd();
- CTxdStore::SetCurrentTxd(slot);
- CTheScripts::ScriptSprites[ScriptParams[0] - 1].SetTexture(str);
- CTxdStore::PopCurrentTxd();
- return 0;
- }
- case COMMAND_LOAD_TEXTURE_DICTIONARY:
- {
- strcpy(str, "models\\");
- strncpy(str + sizeof("models\\"), (char*)&CTheScripts::ScriptSpace[m_nIp], KEY_LENGTH_IN_SCRIPT);
- strcat(str, ".txd");
- m_nIp += KEY_LENGTH_IN_SCRIPT;
- int slot = CTxdStore::FindTxdSlot("script");
- if (slot == -1)
- slot = CTxdStore::AddTxdSlot("script");
- CTxdStore::LoadTxd(slot, str);
- CTxdStore::AddRef(slot);
- return 0;
- }
- case COMMAND_REMOVE_TEXTURE_DICTIONARY:
- {
- CTheScripts::RemoveScriptTextureDictionary();
- return 0;
- }
- case COMMAND_SET_OBJECT_DYNAMIC:
- {
- CollectParameters(&m_nIp, 2);
- CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
- script_assert(pObject);
- if (ScriptParams[1]) {
- if (pObject->bIsStatic) {
- pObject->SetIsStatic(false);
- pObject->AddToMovingList();
- }
- }
- else {
- if (!pObject->bIsStatic) {
- pObject->SetIsStatic(true);
- pObject->RemoveFromMovingList();
- }
- }
- return 0;
- }
- /*
- case COMMAND_SET_CHAR_ANIM_SPEED:
- {
- CollectParameters(&m_nIp, 2);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- CAnimBlendAssociation* pAssoc = RpAnimBlendClumpGetFirstAssociation(pPed->GetClump());
- if (pAssoc)
- pAssoc->speed = *(float*)&ScriptParams[1];
- return 0;
- }
- */
- case COMMAND_PLAY_MISSION_PASSED_TUNE:
- {
- CollectParameters(&m_nIp, 1);
- DMAudio.ChangeMusicMode(MUSICMODE_FRONTEND);
- DMAudio.PlayFrontEndTrack(ScriptParams[0] + STREAMED_SOUND_MISSION_COMPLETED - 1, 0);
- return 0;
- }
- case COMMAND_CLEAR_AREA:
- {
- CollectParameters(&m_nIp, 5);
- CVector pos = *(CVector*)&ScriptParams[0];
- if (pos.z <= MAP_Z_LOW_LIMIT)
- pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
- CWorld::ClearExcitingStuffFromArea(pos, *(float*)&ScriptParams[3], ScriptParams[4]);
- return 0;
- }
- case COMMAND_FREEZE_ONSCREEN_TIMER:
- CollectParameters(&m_nIp, 1);
- CUserDisplay::OnscnTimer.m_bDisabled = ScriptParams[0] != 0;
- return 0;
- case COMMAND_SWITCH_CAR_SIREN:
- {
- CollectParameters(&m_nIp, 2);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle);
- pVehicle->m_bSirenOrAlarm = ScriptParams[1] != 0;
- return 0;
- }
- /*
- case COMMAND_SWITCH_PED_ROADS_ON_ANGLED:
- {
- CollectParameters(&m_nIp, 7);
- ThePaths.SwitchRoadsInAngledArea(*(float*)&ScriptParams[0], *(float*)&ScriptParams[1], *(float*)&ScriptParams[2],
- *(float*)&ScriptParams[3], *(float*)&ScriptParams[4], *(float*)&ScriptParams[5], *(float*)&ScriptParams[6], 0, 1);
- return 0;
- }
- case COMMAND_SWITCH_PED_ROADS_OFF_ANGLED:
- CollectParameters(&m_nIp, 7);
- ThePaths.SwitchRoadsInAngledArea(*(float*)&ScriptParams[0], *(float*)&ScriptParams[1], *(float*)&ScriptParams[2],
- *(float*)&ScriptParams[3], *(float*)&ScriptParams[4], *(float*)&ScriptParams[5], *(float*)&ScriptParams[6], 0, 0);
- return 0;
- case COMMAND_SWITCH_ROADS_ON_ANGLED:
- CollectParameters(&m_nIp, 7);
- ThePaths.SwitchRoadsInAngledArea(*(float*)&ScriptParams[0], *(float*)&ScriptParams[1], *(float*)&ScriptParams[2],
- *(float*)&ScriptParams[3], *(float*)&ScriptParams[4], *(float*)&ScriptParams[5], *(float*)&ScriptParams[6], 1, 1);
- return 0;
- case COMMAND_SWITCH_ROADS_OFF_ANGLED:
- CollectParameters(&m_nIp, 7);
- 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);
- 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:
- {
- CollectParameters(&m_nIp, 12);
- CVector pos = *(CVector*)&ScriptParams[1];
- if (pos.z <= MAP_Z_LOW_LIMIT)
- pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
- float size = Max(0.0f, *(float*)&ScriptParams[7]);
- eParticleObjectType type = (eParticleObjectType)ScriptParams[0];
- RwRGBA color;
- if (type == POBJECT_SMOKE_TRAIL){
- color.alpha = -1;
- color.red = ScriptParams[8];
- color.green = ScriptParams[9];
- color.blue = ScriptParams[10];
- }else{
- color.alpha = color.red = color.blue = color.green = 0;
- }
- CVector target = *(CVector*)&ScriptParams[4];
- CParticleObject::AddObject(type, pos, target, size, ScriptParams[11], color, 1);
- return 0;
- }
- case COMMAND_SET_CHAR_CANT_BE_DRAGGED_OUT:
- {
- CollectParameters(&m_nIp, 2);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- pPed->bDontDragMeOutCar = ScriptParams[1] != 0;
- return 0;
- }
- case COMMAND_TURN_CAR_TO_FACE_COORD:
- {
- CollectParameters(&m_nIp, 3);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle);
- const CVector& pos = pVehicle->GetPosition();
- float heading = CGeneral::GetATanOfXY(pos.y - *(float*)&ScriptParams[2], pos.x - *(float*)&ScriptParams[1]) + HALFPI;
- if (heading > TWOPI)
- heading -= TWOPI;
- pVehicle->SetHeading(heading);
- return 0;
- }
- /*
- case COMMAND_IS_CRANE_LIFTING_CAR:
- {
- CollectParameters(&m_nIp, 3);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[2]);
- UpdateCompareFlag(CCranes::IsThisCarPickedUp(*(float*)&ScriptParams[0], *(float*)&ScriptParams[1], pVehicle));
- return 0;
- }
- */
- case COMMAND_DRAW_SPHERE:
- {
- CollectParameters(&m_nIp, 4);
- CVector pos = *(CVector*)&ScriptParams[0];
- if (pos.z <= MAP_Z_LOW_LIMIT)
- pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
- C3dMarkers::PlaceMarkerSet((uintptr)this + m_nIp, MARKERTYPE_CYLINDER, pos, *(float*)&ScriptParams[3],
- SPHERE_MARKER_R, SPHERE_MARKER_G, SPHERE_MARKER_B, SPHERE_MARKER_A,
- SPHERE_MARKER_PULSE_PERIOD, SPHERE_MARKER_PULSE_FRACTION, 0);
- return 0;
- }
- case COMMAND_SET_CAR_STATUS:
- {
- CollectParameters(&m_nIp, 2);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle);
- pVehicle->SetStatus((eEntityStatus)ScriptParams[1]);
- return 0;
- }
- case COMMAND_IS_CHAR_MALE:
- {
- CollectParameters(&m_nIp, 1);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- UpdateCompareFlag(pPed->m_nPedType != PEDTYPE_CIVFEMALE && pPed->m_nPedType != PEDTYPE_PROSTITUTE);
- return 0;
- }
- case COMMAND_SCRIPT_NAME:
- {
- 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;
- strncpy(m_abScriptName, str, KEY_LENGTH_IN_SCRIPT);
- return 0;
- }
- /*
- case COMMAND_CHANGE_GARAGE_TYPE_WITH_CAR_MODEL:
- {
- CollectParameters(&m_nIp, 3);
- CGarages::ChangeGarageType(ScriptParams[0], (eGarageType)ScriptParams[1], ScriptParams[2]);
- return 0;
- }
- case COMMAND_FIND_DRUG_PLANE_COORDINATES:
- *(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);
- return 0;
- case COMMAND_SAVE_FLOAT_TO_DEBUG_FILE:
- CollectParameters(&m_nIp, 1);
- return 0;
- case COMMAND_SAVE_NEWLINE_TO_DEBUG_FILE:
- return 0;
- case COMMAND_POLICE_RADIO_MESSAGE:
- CollectParameters(&m_nIp, 3);
- DMAudio.PlaySuspectLastSeen(*(float*)&ScriptParams[0], *(float*)&ScriptParams[1], *(float*)&ScriptParams[2]);
- return 0;
- case COMMAND_SET_CAR_STRONG:
- {
- CollectParameters(&m_nIp, 2);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle);
- pVehicle->bTakeLessDamage = ScriptParams[1] != 0;
- return 0;
- }
- case COMMAND_REMOVE_ROUTE:
- CollectParameters(&m_nIp, 1);
- CRouteNode::RemoveRoute(ScriptParams[0]);
- return 0;
- case COMMAND_SWITCH_RUBBISH:
- CollectParameters(&m_nIp, 1);
- CRubbish::SetVisibility(ScriptParams[0] != 0);
- return 0;
- case COMMAND_REMOVE_PARTICLE_EFFECTS_IN_AREA:
- {
- CollectParameters(&m_nIp, 6);
- float x1 = *(float*)&ScriptParams[0];
- float y1 = *(float*)&ScriptParams[1];
- float z1 = *(float*)&ScriptParams[2];
- float x2 = *(float*)&ScriptParams[3];
- float y2 = *(float*)&ScriptParams[4];
- float z2 = *(float*)&ScriptParams[5];
- CParticleObject* tmp = CParticleObject::pCloseListHead;
- while (tmp) {
- CParticleObject* next = tmp->m_pNext;
- if (tmp->IsWithinArea(x1, y1, z1, x2, y2, z2))
- tmp->RemoveObject();
- tmp = next;
- }
- tmp = CParticleObject::pFarListHead;
- while (tmp) {
- CParticleObject* next = tmp->m_pNext;
- if (tmp->IsWithinArea(x1, y1, z1, x2, y2, z2))
- tmp->RemoveObject();
- tmp = next;
- }
- return 0;
- }
- case COMMAND_SWITCH_STREAMING:
- CollectParameters(&m_nIp, 1);
- CStreaming::ms_disableStreaming = ScriptParams[0] == 0;
- return 0;
- case COMMAND_IS_GARAGE_OPEN:
- CollectParameters(&m_nIp, 1);
- UpdateCompareFlag(CGarages::IsGarageOpen(ScriptParams[0]));
- return 0;
- case COMMAND_IS_GARAGE_CLOSED:
- CollectParameters(&m_nIp, 1);
- UpdateCompareFlag(CGarages::IsGarageClosed(ScriptParams[0]));
- return 0;
- /*
- case COMMAND_START_CATALINA_HELI:
- CHeli::StartCatalinaFlyBy();
- return 0;
- case COMMAND_CATALINA_HELI_TAKE_OFF:
- CHeli::CatalinaTakeOff();
- return 0;
- case COMMAND_REMOVE_CATALINA_HELI:
- CHeli::RemoveCatalinaHeli();
- return 0;
- case COMMAND_HAS_CATALINA_HELI_BEEN_SHOT_DOWN:
- UpdateCompareFlag(CHeli::HasCatalinaBeenShotDown());
- return 0;
- */
- case COMMAND_SWAP_NEAREST_BUILDING_MODEL:
- {
- CollectParameters(&m_nIp, 6);
- CVector pos = *(CVector*)&ScriptParams[0];
- if (pos.z <= MAP_Z_LOW_LIMIT)
- pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
- float radius = *(float*)&ScriptParams[3];
- int mi1 = ScriptParams[4] >= 0 ? ScriptParams[4] : CTheScripts::UsedObjectArray[-ScriptParams[4]].index;
- int mi2 = ScriptParams[5] >= 0 ? ScriptParams[5] : CTheScripts::UsedObjectArray[-ScriptParams[5]].index;
- int16 total;
- CEntity* apEntities[16];
- CWorld::FindObjectsOfTypeInRange(mi1, pos, radius, true, &total, 16, apEntities, true, false, false, false, false);
- 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::GetLevelFromPosition(&pos)), pos, radius, true, &total, 16, apEntities);
- CEntity* pClosestEntity = nil;
- float min_dist = 2.0f * radius;
- for (int i = 0; i < total; i++) {
- float dist = (apEntities[i]->GetPosition() - pos).Magnitude();
- if (dist < min_dist) {
- min_dist = dist;
- pClosestEntity = apEntities[i];
- }
- }
- if (!pClosestEntity) {
- printf("Failed to find building\n");
- return 0;
- }
- CBuilding* pReplacedBuilding = ((CBuilding*)pClosestEntity);
- pReplacedBuilding->ReplaceWithNewModel(mi2);
- CTheScripts::AddToBuildingSwapArray(pReplacedBuilding, mi1, mi2);
- return 0;
- }
- case COMMAND_SWITCH_WORLD_PROCESSING:
- CollectParameters(&m_nIp, 1);
- CWorld::bProcessCutsceneOnly = ScriptParams[0] == 0;
- return 0;
- case COMMAND_REMOVE_ALL_PLAYER_WEAPONS:
- {
- CollectParameters(&m_nIp, 1);
- CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
- script_assert(pPed);
- pPed->ClearWeapons();
- return 0;
- }
- /*
- case COMMAND_GRAB_CATALINA_HELI:
- {
- CHeli* pHeli = CHeli::FindPointerToCatalinasHeli();
- ScriptParams[0] = pHeli ? CPools::GetVehiclePool()->GetIndex(pHeli) : -1;
- StoreParameters(&m_nIp, 1);
- return 0;
- }
- */
- case COMMAND_CLEAR_AREA_OF_CARS:
- {
- CollectParameters(&m_nIp, 6);
- 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];
- }
- CWorld::ClearCarsFromArea(infX, infY, infZ, supX, supY, supZ);
- return 0;
- }
- case COMMAND_SET_ROTATING_GARAGE_DOOR:
- CollectParameters(&m_nIp, 1);
- CGarages::SetGarageDoorToRotate(ScriptParams[0]);
- return 0;
- case COMMAND_ADD_SPHERE:
- {
- CollectParameters(&m_nIp, 4);
- CVector pos = *(CVector*)&ScriptParams[0];
- if (pos.z <= MAP_Z_LOW_LIMIT)
- pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
- float radius = *(float*)&ScriptParams[3];
- CTheScripts::GetActualScriptSphereIndex(CollectNextParameterWithoutIncreasingPC(m_nIp));
- ScriptParams[0] = CTheScripts::AddScriptSphere((uintptr)this + m_nIp, pos, radius);
- StoreParameters(&m_nIp, 1);
- return 0;
- }
- case COMMAND_REMOVE_SPHERE:
- 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);
- CPlayerPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
- script_assert(pPed);
- if (ScriptParams[1]) {
- pPed->m_pWanted->m_bIgnoredByEveryone = true;
- CWorld::StopAllLawEnforcersInTheirTracks();
- }
- else {
- pPed->m_pWanted->m_bIgnoredByEveryone = false;
- }
- return 0;
- }
- case COMMAND_STORE_CAR_CHAR_IS_IN_NO_SAVE:
- {
- CollectParameters(&m_nIp, 1);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- CVehicle* pVehicle = pPed->bInVehicle ? pPed->m_pMyVehicle : nil;
- ScriptParams[0] = CPools::GetVehiclePool()->GetIndex(pVehicle);
- StoreParameters(&m_nIp, 1);
- return 0;
- }
- case COMMAND_STORE_CAR_PLAYER_IS_IN_NO_SAVE:
- {
- CollectParameters(&m_nIp, 1);
- CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
- script_assert(pPed);
- CVehicle* pVehicle = pPed->bInVehicle ? pPed->m_pMyVehicle : nil;
- ScriptParams[0] = CPools::GetVehiclePool()->GetIndex(pVehicle);
- 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, ScriptParams[0] != 0);
- return 0;
- }
- case COMMAND_DISPLAY_ONSCREEN_COUNTER_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.AddCounter(var, ScriptParams[0], onscreen_str, 0);
- return 0;
- }
- case COMMAND_CREATE_RANDOM_CAR_FOR_CAR_PARK:
- {
- CollectParameters(&m_nIp, 4);
- if (CCarCtrl::NumRandomCars >= 30)
- return 0;
- int attempts;
- int model = -1;
- int index = CGeneral::GetRandomNumberInRange(0, 50);
- for (attempts = 0; attempts < 50; attempts++) {
- if (model != -1)
- break;
- model = CStreaming::ms_vehiclesLoaded[index];
- if (model == -1)
- continue;
- 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_HUNTER:
- case MI_POLICE:
- case MI_ENFORCER:
- case MI_SECURICA:
- case MI_PREDATOR:
- case MI_BUS:
- case MI_RHINO:
- case MI_BARRACKS:
- case MI_CUBAN:
- case MI_CHOPPER:
- case MI_ANGEL:
- case MI_COACH:
- case MI_RCBANDIT:
- 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_TROPIC:
- case MI_FLATBED:
- case MI_YANKEE:
- 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_MANANA:
- case MI_INFERNUS:
- case MI_PONY:
- case MI_CHEETAH:
- case MI_MOONBEAM:
- case MI_ESPERANT:
- case MI_TAXI:
- case MI_WASHING:
- case MI_BOBCAT:
- case MI_BANSHEE:
- case MI_CABBIE:
- case MI_STALLION:
- case MI_RUMPO:
- 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]);
- model = -1;
- break;
- }
- }
- else
- model = -1;
- if (++index >= 50)
- index = 0;
- }
- if (model == -1)
- return 0;
- CVehicle* car;
- 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();
- car->SetPosition(pos);
- car->SetHeading(DEGTORAD(*(float*)&ScriptParams[3]));
- CTheScripts::ClearSpaceForMissionEntity(pos, car);
- car->SetStatus(STATUS_ABANDONED);
- car->bIsLocked = false;
- car->bIsCarParkVehicle = true;
- CCarCtrl::JoinCarWithRoadSystem(car);
- car->AutoPilot.m_nCarMission = MISSION_NONE;
- 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);
- 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];
- return 0;
- case COMMAND_SET_CAMERA_IN_FRONT_OF_PLAYER:
- TheCamera.SetCameraDirectlyInFrontForFollowPed_CamOnAString();
- return 0;
- /*
- case COMMAND_IS_CAR_VISIBLY_DAMAGED:
- {
- CollectParameters(&m_nIp, 1);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle);
- UpdateCompareFlag(pVehicle->bIsDamaged);
- return 0;
- }
- */
- case COMMAND_DOES_OBJECT_EXIST:
- CollectParameters(&m_nIp, 1);
- UpdateCompareFlag(CPools::GetObjectPool()->GetAt(ScriptParams[0]));
- return 0;
- case COMMAND_LOAD_SCENE:
- {
- 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:
- {
- CollectParameters(&m_nIp, 3);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle);
- CTheScripts::StuckCars.AddCarToCheck(ScriptParams[0], *(float*)&ScriptParams[1], ScriptParams[2]);
- return 0;
- }
- case COMMAND_REMOVE_STUCK_CAR_CHECK:
- {
- CollectParameters(&m_nIp, 1);
- CTheScripts::StuckCars.RemoveCarFromCheck(ScriptParams[0]);
- return 0;
- }
- case COMMAND_IS_CAR_STUCK:
- CollectParameters(&m_nIp, 1);
- 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(ScriptParams[0] - 1, str);
- return 0;
- }
- case COMMAND_HAS_MISSION_AUDIO_LOADED:
- {
- CollectParameters(&m_nIp, 1);
- UpdateCompareFlag(DMAudio.GetMissionAudioLoadingStatus(ScriptParams[0] - 1) == 1);
- return 0;
- }
- case COMMAND_PLAY_MISSION_AUDIO:
- CollectParameters(&m_nIp, 1);
- DMAudio.PlayLoadedMissionAudio(ScriptParams[0] - 1);
- return 0;
- case COMMAND_HAS_MISSION_AUDIO_FINISHED:
- {
- CollectParameters(&m_nIp, 1);
- UpdateCompareFlag(DMAudio.IsMissionAudioSampleFinished(ScriptParams[0] - 1));
- return 0;
- }
- case COMMAND_GET_CLOSEST_CAR_NODE_WITH_HEADING:
- {
- CollectParameters(&m_nIp, 3);
- CVector pos = *(CVector*)&ScriptParams[0];
- 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.FindNodeCoorsForScript(node);
- *(float*)&ScriptParams[3] = ThePaths.FindNodeOrientationForCarPlacement(node);
- StoreParameters(&m_nIp, 4);
- return 0;
- }
- case COMMAND_HAS_IMPORT_GARAGE_SLOT_BEEN_FILLED:
- {
- CollectParameters(&m_nIp, 2);
- UpdateCompareFlag(CGarages::HasImportExportGarageCollectedThisCar(ScriptParams[0], ScriptParams[1] - 1));
- return 0;
- }
- case COMMAND_CLEAR_THIS_PRINT:
- {
- wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- CMessages::ClearThisPrint(text);
- return 0;
- }
- case COMMAND_CLEAR_THIS_BIG_PRINT:
- {
- wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- CMessages::ClearThisBigPrint(text);
- return 0;
- }
- case COMMAND_SET_MISSION_AUDIO_POSITION:
- {
- 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:
- {
- 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 && !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);
- CObject* pObject = CPickups::aPickUps[CPickups::GetActualPickupIndex(ScriptParams[0])].m_pObject;
- CRadar::GetActualBlipArrayIndex(CollectNextParameterWithoutIncreasingPC(m_nIp));
- ScriptParams[0] = CRadar::SetEntityBlip(BLIP_OBJECT, CPools::GetObjectPool()->GetIndex(pObject), ScriptParams[1], (eBlipDisplay)ScriptParams[2]);
- StoreParameters(&m_nIp, 1);
- return 0;
- }
- */
- case COMMAND_ADD_BLIP_FOR_PICKUP:
- {
- CollectParameters(&m_nIp, 1);
- CObject* pObject = CPickups::aPickUps[CPickups::GetActualPickupIndex(ScriptParams[0])].m_pObject;
- CRadar::GetActualBlipArrayIndex(CollectNextParameterWithoutIncreasingPC(m_nIp));
- int handle = CRadar::SetEntityBlip(BLIP_OBJECT, CPools::GetObjectPool()->GetIndex(pObject), 6, BLIP_DISPLAY_BOTH);
- CRadar::ChangeBlipScale(handle, 3);
- ScriptParams[0] = handle;
- StoreParameters(&m_nIp, 1);
- return 0;
- }
- /*
- case COMMAND_ADD_SPRITE_BLIP_FOR_PICKUP:
- {
- CollectParameters(&m_nIp, 2);
- CObject* pObject = CPickups::aPickUps[CPickups::GetActualPickupIndex(ScriptParams[0])].m_pObject;
- CRadar::GetActualBlipArrayIndex(CollectNextParameterWithoutIncreasingPC(m_nIp));
- int handle = CRadar::SetEntityBlip(BLIP_OBJECT, CPools::GetObjectPool()->GetIndex(pObject), 6, BLIP_DISPLAY_BOTH);
- CRadar::SetBlipSprite(handle, ScriptParams[1]);
- ScriptParams[0] = handle;
- StoreParameters(&m_nIp, 1);
- return 0;
- }
- */
- case COMMAND_SET_PED_DENSITY_MULTIPLIER:
- CollectParameters(&m_nIp, 1);
- CPopulation::PedDensityMultiplier = *(float*)&ScriptParams[0];
- return 0;
- case COMMAND_FORCE_RANDOM_PED_TYPE:
- 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_SET_CHAR_OBJ_LEAVE_ANY_CAR:
- {
- CollectParameters(&m_nIp, 1);
- 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;
- return 0;
- case COMMAND_SET_TEXT_RIGHT_JUSTIFY:
- CollectParameters(&m_nIp, 1);
- CTheScripts::IntroTextLines[CTheScripts::NumberOfIntroTextLinesThisFrame].m_bRightJustify = ScriptParams[0] != 0;
- return 0;
- case COMMAND_PRINT_HELP:
- {
- 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_2C", 7) == 0 ||
- strncmp((char*)&CTheScripts::ScriptSpace[m_nIp], "GUN_2D", 7) == 0)) {
- m_nIp += KEY_LENGTH_IN_SCRIPT;
- return 0;
- }
- wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- CHud::SetHelpMessage(text, false);
- return 0;
- }
- case COMMAND_CLEAR_HELP:
- CHud::SetHelpMessage(nil, false);
- return 0;
- case COMMAND_FLASH_HUD_OBJECT:
- CollectParameters(&m_nIp, 1);
- CHud::m_ItemToFlash = ScriptParams[0];
- return 0;
- default:
- script_assert(0);
- }
- return -1;
-}
-
-int8 CRunningScript::ProcessCommands1000To1099(int32 command)
-{
- switch (command) {
- //case COMMAND_FLASH_RADAR_BLIP:
- /*
- case COMMAND_IS_CHAR_IN_CONTROL:
- {
- CollectParameters(&m_nIp, 1);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- UpdateCompareFlag(pPed->IsPedInControl());
- return 0;
- }
- */
- case COMMAND_SET_GENERATE_CARS_AROUND_CAMERA:
- CollectParameters(&m_nIp, 1);
- CCarCtrl::bCarsGeneratedAroundCamera = (ScriptParams[0] != 0);
- return 0;
- 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);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle);
- script_assert(pVehicle->m_vehType == VEHICLE_TYPE_CAR);
- CAutomobile* pCar = (CAutomobile*)pVehicle;
- pCar->bNotDamagedUpsideDown = (ScriptParams[1] != 0);
- return 0;
- }
- case COMMAND_CAN_PLAYER_START_MISSION:
- {
- CollectParameters(&m_nIp, 1);
- CPlayerPed* pPlayerPed = CWorld::Players[ScriptParams[0]].m_pPed;
- script_assert(pPlayerPed);
- UpdateCompareFlag(pPlayerPed->IsPedInControl() || pPlayerPed->m_nPedState == PED_DRIVING);
- return 0;
- }
- case COMMAND_MAKE_PLAYER_SAFE_FOR_CUTSCENE:
- {
- CollectParameters(&m_nIp, 1);
-#ifdef MISSION_REPLAY
- AllowMissionReplay = 0;
- SaveGameForPause(3);
-#endif
- CPlayerInfo* pPlayerInfo = &CWorld::Players[ScriptParams[0]];
- CPad::GetPad(ScriptParams[0])->SetDisablePlayerControls(PLAYERCONTROL_CUTSCENE);
- pPlayerInfo->MakePlayerSafe(true);
- CCutsceneMgr::StartCutsceneProcessing();
- return 0;
- }
- case COMMAND_USE_TEXT_COMMANDS:
- CollectParameters(&m_nIp, 1);
- CTheScripts::UseTextCommands = (ScriptParams[0] != 0) ? 2 : 1;
- return 0;
- case COMMAND_SET_THREAT_FOR_PED_TYPE:
- CollectParameters(&m_nIp, 2);
- CPedType::AddThreat(ScriptParams[0], ScriptParams[1]);
- return 0;
- case COMMAND_CLEAR_THREAT_FOR_PED_TYPE:
- CollectParameters(&m_nIp, 2);
- CPedType::RemoveThreat(ScriptParams[0], ScriptParams[1]);
- return 0;
- case COMMAND_GET_CAR_COLOURS:
- {
- CollectParameters(&m_nIp, 1);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle);
- ScriptParams[0] = pVehicle->m_currentColour1;
- ScriptParams[1] = pVehicle->m_currentColour2;
- StoreParameters(&m_nIp, 2);
- return 0;
- }
- case COMMAND_SET_ALL_CARS_CAN_BE_DAMAGED:
- CollectParameters(&m_nIp, 1);
- CWorld::SetAllCarsCanBeDamaged(ScriptParams[0] != 0);
- if (!ScriptParams[0])
- CWorld::ExtinguishAllCarFiresInArea(FindPlayerCoors(), 4000.0f);
- return 0;
- case COMMAND_SET_CAR_CAN_BE_DAMAGED:
- {
- CollectParameters(&m_nIp, 2);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- pVehicle->bCanBeDamaged = ScriptParams[1] != 0;
- if (!ScriptParams[1])
- pVehicle->ExtinguishCarFire();
- return 0;
- }
- //case COMMAND_MAKE_PLAYER_UNSAFE:
- /*
- case COMMAND_LOAD_COLLISION:
- {
- CollectParameters(&m_nIp, 1);
- CTimer::Stop();
- CGame::currLevel = (eLevelName)ScriptParams[0];
- ISLAND_LOADING_IS(LOW)
- {
- CStreaming::RemoveUnusedBigBuildings(CGame::currLevel);
- CStreaming::RemoveUnusedBuildings(CGame::currLevel);
- }
- CCollision::SortOutCollisionAfterLoad();
- ISLAND_LOADING_ISNT(HIGH)
- {
- CStreaming::RequestIslands(CGame::currLevel);
- CStreaming::LoadAllRequestedModels(true);
- }
- CTimer::Update();
- return 0;
- }
- case COMMAND_GET_BODY_CAST_HEALTH:
- // ScriptParams[0] = CObject::nBodyCastHealth;
- // StoreParameters(&m_nIp, 1);
- return 0;
- */
- case COMMAND_SET_CHARS_CHATTING:
- {
- CollectParameters(&m_nIp, 3);
- CPed* pPed1 = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- CPed* pPed2 = CPools::GetPedPool()->GetAt(ScriptParams[1]);
- script_assert(pPed1 && pPed2);
- pPed1->SetChat(pPed2, ScriptParams[2]);
- pPed2->SetChat(pPed1, ScriptParams[2]);
- return 0;
- }
- //case COMMAND_MAKE_PLAYER_SAFE:
- /*
- case COMMAND_SET_CAR_STAYS_IN_CURRENT_LEVEL:
- {
- CollectParameters(&m_nIp, 2);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle);
- if (ScriptParams[1])
- pVehicle->m_nZoneLevel = CTheZones::GetLevelFromPosition(&pVehicle->GetPosition());
- else
- pVehicle->m_nZoneLevel = LEVEL_GENERIC;
- return 0;
- }
- case COMMAND_SET_CHAR_STAYS_IN_CURRENT_LEVEL:
- {
- CollectParameters(&m_nIp, 2);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- if (ScriptParams[1])
- pPed->m_nZoneLevel = CTheZones::GetLevelFromPosition(&pPed->GetPosition());
- else
- pPed->m_nZoneLevel = LEVEL_GENERIC;
- return 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_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_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;
- case COMMAND_REGISTER_CRIMINAL_CAUGHT:
- CStats::AnotherCriminalCaught();
- return 0;
- case COMMAND_REGISTER_AMBULANCE_LEVEL:
- CollectParameters(&m_nIp, 1);
- CStats::RegisterLevelAmbulanceMission(ScriptParams[0]);
- return 0;
- case COMMAND_REGISTER_FIRE_EXTINGUISHED:
- CStats::AnotherFireExtinguished();
- return 0;
- case COMMAND_TURN_PHONE_ON:
- CollectParameters(&m_nIp, 1);
- gPhoneInfo.m_aPhones[ScriptParams[0]].m_nState = PHONE_STATE_9;
- return 0;
- /*
- case COMMAND_REGISTER_LONGEST_DODO_FLIGHT:
- CollectParameters(&m_nIp, 1);
- CStats::RegisterLongestFlightInDodo(ScriptParams[0]);
- return 0;
- */
- case COMMAND_GET_OFFSET_FROM_CAR_IN_WORLD_COORDS:
- {
- 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(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;
- case COMMAND_IS_GERMAN_GAME:
- UpdateCompareFlag(CGame::germanGame);
- return 0;
- case COMMAND_CLEAR_MISSION_AUDIO:
- 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];
- return 0;
- case COMMAND_SET_FADE_IN_AFTER_NEXT_DEATH:
- CollectParameters(&m_nIp, 1);
- CRestart::bFadeInAfterNextDeath = !!ScriptParams[0];
- return 0;
- case COMMAND_SET_GANG_PED_MODEL_PREFERENCE:
- CollectParameters(&m_nIp, 2);
- CGangs::SetGangPedModelOverride(ScriptParams[0], ScriptParams[1]);
- return 0;
- */
- case COMMAND_SET_CHAR_USE_PEDNODE_SEEK:
- {
- CollectParameters(&m_nIp, 2);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- if (ScriptParams[1])
- pPed->m_pNextPathNode = nil;
- pPed->bUsePedNodeSeek = !!ScriptParams[1];
- return 0;
- }
- /*
- case COMMAND_SWITCH_VEHICLE_WEAPONS:
- {
- CollectParameters(&m_nIp, 2);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle);
- pVehicle->bGunSwitchedOff = !ScriptParams[1];
- return 0;
- }
- case COMMAND_SET_GET_OUT_OF_JAIL_FREE:
- 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);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle);
- 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)
- CStats::LastMissionPassedName[0] = '\0';
-#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);
- CRunningScript* pMissionScript = CTheScripts::StartNewScript(SIZE_MAIN_SCRIPT);
- CTimer::Resume();
- pMissionScript->m_bIsMissionScript = true;
- pMissionScript->m_bMissionFlag = true;
- CTheScripts::bAlreadyRunningAMissionScript = true;
- CGameLogic::ClearShortCut();
- return 0;
- }
- case COMMAND_SET_OBJECT_DRAW_LAST:
- {
- CollectParameters(&m_nIp, 2);
- CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
- script_assert(pObject);
- pObject->bDrawLast = !!ScriptParams[1];
- return 0;
- }
- case COMMAND_GET_AMMO_IN_PLAYER_WEAPON:
- {
- CollectParameters(&m_nIp, 2);
- CPlayerPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
- script_assert(pPed);
- 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);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- 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;
- StoreParameters(&m_nIp, 1);
- return 0;
- }
- case COMMAND_REGISTER_KILL_FRENZY_PASSED:
- CStats::AnotherKillFrenzyPassed();
- return 0;
- case COMMAND_SET_CHAR_SAY:
- {
- CollectParameters(&m_nIp, 2);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- switch (ScriptParams[1]) {
- case SCRIPT_SOUND_CHUNKY_RUN_SHOUT:
- pPed->Say(SOUND_PED_FLEE_RUN);
- break;
- case SCRIPT_SOUND_SECURITY_GUARD_AWAY_SHOUT:
- pPed->Say(SOUND_PED_FLEE_RUN);
- break;
- case SCRIPT_SOUND_SWAT_PED_SHOUT:
- pPed->Say(SOUND_PED_PURSUIT_SWAT);
- break;
- case SCRIPT_SOUND_AMMUNATION_CHAT_1:
- pPed->Say(SOUND_AMMUNATION_WELCOME_1);
- break;
- case SCRIPT_SOUND_AMMUNATION_CHAT_2:
- pPed->Say(SOUND_AMMUNATION_WELCOME_2);
- break;
- case SCRIPT_SOUND_AMMUNATION_CHAT_3:
- pPed->Say(SOUND_AMMUNATION_WELCOME_3);
- break;
- default:
- break;
- }
- return 0;
- }
- */
- case COMMAND_SET_NEAR_CLIP:
- CollectParameters(&m_nIp, 1);
- TheCamera.SetNearClipScript(*(float*)&ScriptParams[0]);
- return 0;
- case COMMAND_SET_RADIO_CHANNEL:
- 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];
- return 0;
- case COMMAND_OVERRIDE_POLICE_STATION_LEVEL:
- CollectParameters(&m_nIp, 1);
- CRestart::OverridePoliceStationLevel = ScriptParams[0];
- return 0;
- case COMMAND_FORCE_RAIN:
- CollectParameters(&m_nIp, 1);
- CWeather::bScriptsForceRain = !!ScriptParams[0];
- return 0;
- case COMMAND_DOES_GARAGE_CONTAIN_CAR:
- {
- CollectParameters(&m_nIp, 2);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[1]);
- script_assert(pVehicle);
- UpdateCompareFlag(CGarages::IsThisCarWithinGarageArea(ScriptParams[0], pVehicle));
- return 0;
- }
- */
- case COMMAND_SET_CAR_TRACTION:
- {
- CollectParameters(&m_nIp, 2);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- float fTraction = *(float*)&ScriptParams[1];
- script_assert(pVehicle->m_vehType == VEHICLE_TYPE_CAR || pVehicle->m_vehType == VEHICLE_TYPE_BIKE);
- if (pVehicle->m_vehType == VEHICLE_TYPE_CAR)
- ((CAutomobile*)pVehicle)->m_fTraction = fTraction;
- else
- ((CBike*)pVehicle)->m_fTraction = fTraction;
- return 0;
- }
- case COMMAND_ARE_MEASUREMENTS_IN_METRES:
-#ifdef USE_MEASUREMENTS_IN_METERS
- UpdateCompareFlag(true);
-#else
- UpdateCompareFlag(false);
-#endif
- return 0;
- case COMMAND_CONVERT_METRES_TO_FEET:
- {
- CollectParameters(&m_nIp, 1);
- float fMeterValue = *(float*)&ScriptParams[0];
- float fFeetValue = fMeterValue / METERS_IN_FOOT;
- *(float*)&ScriptParams[0] = fFeetValue;
- StoreParameters(&m_nIp, 1);
- return 0;
- }
- /*
- case COMMAND_MARK_ROADS_BETWEEN_LEVELS:
- {
- CollectParameters(&m_nIp, 6);
- 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];
- }
- ThePaths.MarkRoadsBetweenLevelsInArea(infX, supX, infY, supY, infZ, supZ);
- return 0;
- }
- case COMMAND_MARK_PED_ROADS_BETWEEN_LEVELS:
- {
- CollectParameters(&m_nIp, 6);
- 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];
- }
- ThePaths.PedMarkRoadsBetweenLevelsInArea(infX, supX, infY, supY, infZ, supZ);
- return 0;
- }
- */
- case COMMAND_SET_CAR_AVOID_LEVEL_TRANSITIONS:
- {
- CollectParameters(&m_nIp, 2);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle);
- pVehicle->AutoPilot.m_bStayInCurrentLevel = !!ScriptParams[1];
- return 0;
- }
- /*
- case COMMAND_SET_CHAR_AVOID_LEVEL_TRANSITIONS:
- {
- CollectParameters(&m_nIp, 2);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[1]);
- script_assert(pPed);
- // not implemented
- return 0;
- }
- case COMMAND_IS_THREAT_FOR_PED_TYPE:
- CollectParameters(&m_nIp, 2);
- UpdateCompareFlag(CPedType::IsThreat(ScriptParams[0], ScriptParams[1]));
- return 0;
- */
- case COMMAND_CLEAR_AREA_OF_CHARS:
- {
- CollectParameters(&m_nIp, 6);
- 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];
- }
- CWorld::ClearPedsFromArea(infX, infY, infZ, supX, supY, supZ);
- return 0;
- }
- case COMMAND_SET_TOTAL_NUMBER_OF_MISSIONS:
- CollectParameters(&m_nIp, 1);
- CStats::SetTotalNumberMissions(CGame::germanGame ? ScriptParams[0] - 2 : ScriptParams[0]);
- return 0;
- case COMMAND_CONVERT_METRES_TO_FEET_INT:
- CollectParameters(&m_nIp, 1);
- ScriptParams[0] *= FEET_IN_METER;
- StoreParameters(&m_nIp, 1);
- return 0;
- case COMMAND_REGISTER_FASTEST_TIME:
- CollectParameters(&m_nIp, 2);
- CStats::RegisterFastestTime(ScriptParams[0], ScriptParams[1]);
- return 0;
- case COMMAND_REGISTER_HIGHEST_SCORE:
- CollectParameters(&m_nIp, 2);
- CStats::RegisterHighestScore(ScriptParams[0], ScriptParams[1]);
- return 0;
- //case COMMAND_WARP_CHAR_INTO_CAR_AS_PASSENGER:
- case COMMAND_IS_CAR_PASSENGER_SEAT_FREE:
- {
- CollectParameters(&m_nIp, 2);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle);
- UpdateCompareFlag(ScriptParams[1] < pVehicle->m_nNumMaxPassengers && pVehicle->pPassengers[ScriptParams[1]] == nil);
- return 0;
- }
- /*
- case COMMAND_GET_CHAR_IN_CAR_PASSENGER_SEAT:
- {
- CollectParameters(&m_nIp, 2);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle);
- script_assert(ScriptParams[1] >= 0 && ScriptParams[1] < ARRAY_SIZE(pVehicle->pPassengers));
- CPed* pPassenger = pVehicle->pPassengers[ScriptParams[1]];
- ScriptParams[0] = CPools::GetPedPool()->GetIndex(pPassenger);
- StoreParameters(&m_nIp, 1);
- return 0;
- }
- */
- case COMMAND_SET_CHAR_IS_CHRIS_CRIMINAL:
- {
- CollectParameters(&m_nIp, 2);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- pPed->bChrisCriminal = !!ScriptParams[1];
- return 0;
- }
- case COMMAND_START_CREDITS:
- CCredits::Start();
- return 0;
- case COMMAND_STOP_CREDITS:
- CCredits::Stop();
- return 0;
- case COMMAND_ARE_CREDITS_FINISHED:
- UpdateCompareFlag(CCredits::AreCreditsDone());
- return 0;
- case COMMAND_CREATE_SINGLE_PARTICLE:
- CollectParameters(&m_nIp, 8);
- 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);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- if (ScriptParams[1])
- pPed->m_nZoneLevel = LEVEL_IGNORE;
- else
- pPed->m_nZoneLevel = CTheZones::GetLevelFromPosition(&pPed->GetPosition());
- return 0;
- }
- case COMMAND_GET_CHASE_CAR:
- {
- CollectParameters(&m_nIp, 1);
- CVehicle* pVehicle = CRecordDataForChase::TurnChaseCarIntoScriptCar(ScriptParams[0]);
- ScriptParams[0] = CPools::GetVehiclePool()->GetIndex(pVehicle);
- StoreParameters(&m_nIp, 1);
- if (m_bIsMissionScript)
- CTheScripts::MissionCleanup.AddEntityToList(ScriptParams[0], CLEANUP_CAR);
- return 0;
- }
- case COMMAND_START_BOAT_FOAM_ANIMATION:
- CSpecialParticleStuff::StartBoatFoamAnimation();
- return 0;
- case COMMAND_UPDATE_BOAT_FOAM_ANIMATION:
- {
- CollectParameters(&m_nIp, 1);
- CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
- script_assert(pObject);
- 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]) {
- CGame::playingIntro = true;
- CStreaming::RemoveCurrentZonesModels();
- } else {
- CGame::playingIntro = false;
- DMAudio.ChangeMusicMode(MUSICMODE_GAME);
- int mi;
- CModelInfo::GetModelInfo("bridgefukb", &mi);
- CStreaming::RequestModel(mi, STREAMFLAGS_DEPENDENCY);
- CStreaming::LoadAllRequestedModels(false);
- }
- return 0;
- */
- case COMMAND_SET_PLAYER_HOOKER:
- {
- CollectParameters(&m_nIp, 2);
- CPlayerInfo* pPlayerInfo = &CWorld::Players[ScriptParams[0]];
- if (ScriptParams[1] < 0) {
- pPlayerInfo->m_pHooker = nil;
- pPlayerInfo->m_nNextSexFrequencyUpdateTime = 0;
- pPlayerInfo->m_nNextSexMoneyUpdateTime = 0;
- } else {
- 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;
- }
- return 0;
- }
- case COMMAND_PLAY_END_OF_GAME_TUNE:
- DMAudio.PlayPreloadedCutSceneMusic();
- return 0;
- case COMMAND_STOP_END_OF_GAME_TUNE:
- DMAudio.StopCutSceneMusic();
- DMAudio.ChangeMusicMode(MUSICMODE_GAME);
- return 0;
- case COMMAND_GET_CAR_MODEL:
- {
- CollectParameters(&m_nIp, 1);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle);
- ScriptParams[0] = pVehicle->GetModelIndex();
- StoreParameters(&m_nIp, 1);
- return 0;
- }
- case COMMAND_IS_PLAYER_SITTING_IN_CAR:
- {
- CollectParameters(&m_nIp, 2);
- CPlayerPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
- script_assert(pPed);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[1]);
- 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:
- {
- CollectParameters(&m_nIp, 1);
- CPlayerPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
- script_assert(pPed);
- 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 || 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[1] == 0);
- return 0;
- }
- /*
- case COMMAND_IS_PLAYER_LIFTING_A_PHONE:
- {
- CollectParameters(&m_nIp, 1);
- CPlayerPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
- script_assert(pPed);
- UpdateCompareFlag(pPed->GetPedState() == PED_MAKE_CALL);
- return 0;
- }
- */
- case COMMAND_IS_CHAR_SITTING_IN_CAR:
- {
- CollectParameters(&m_nIp, 2);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[1]);
- script_assert(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:
- {
- CollectParameters(&m_nIp, 1);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- UpdateCompareFlag(pPed->GetPedState() == PED_DRIVING && pPed->m_objective != OBJECTIVE_LEAVE_CAR);
- return 0;
- }
- case COMMAND_IS_PLAYER_ON_FOOT:
- {
- CollectParameters(&m_nIp, 1);
- CPlayerPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
- script_assert(pPed);
- UpdateCompareFlag(!pPed->bInVehicle && pPed->m_objective != OBJECTIVE_ENTER_CAR_AS_PASSENGER &&
- pPed->m_objective != OBJECTIVE_ENTER_CAR_AS_DRIVER);
- return 0;
- }
- case COMMAND_IS_CHAR_ON_FOOT:
- {
- CollectParameters(&m_nIp, 1);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- UpdateCompareFlag(!pPed->bInVehicle && pPed->m_objective != OBJECTIVE_ENTER_CAR_AS_PASSENGER &&
- pPed->m_objective != OBJECTIVE_ENTER_CAR_AS_DRIVER);
- return 0;
- }
- default:
- script_assert(0);
- }
- return -1;
-}
-
-int8 CRunningScript::ProcessCommands1100To1199(int32 command)
-{
- char tmp[48];
- switch (command) {
- /*
- case COMMAND_LOAD_COLLISION_WITH_SCREEN:
- CollectParameters(&m_nIp, 1);
- CTimer::Stop();
- CGame::currLevel = (eLevelName)ScriptParams[0];
- if (CGame::currLevel != CCollision::ms_collisionInMemory) {
- ISLAND_LOADING_IS(LOW)
- {
- DMAudio.SetEffectsFadeVol(0);
- CPad::StopPadsShaking();
- CCollision::LoadCollisionScreen(CGame::currLevel);
- DMAudio.Service();
- }
- CPopulation::DealWithZoneChange(CCollision::ms_collisionInMemory, CGame::currLevel, false);
-
- ISLAND_LOADING_IS(LOW)
- {
- CStreaming::RemoveUnusedBigBuildings(CGame::currLevel);
- CStreaming::RemoveUnusedBuildings(CGame::currLevel);
- }
- CCollision::SortOutCollisionAfterLoad();
-
- ISLAND_LOADING_ISNT(HIGH)
- CStreaming::RequestIslands(CGame::currLevel);
-
- ISLAND_LOADING_IS(LOW)
- CStreaming::RequestBigBuildings(CGame::currLevel);
-
- ISLAND_LOADING_ISNT(HIGH)
- CStreaming::LoadAllRequestedModels(true);
-
- ISLAND_LOADING_IS(LOW)
- DMAudio.SetEffectsFadeVol(127);
- }
- CTimer::Update();
- return 0;
- */
- case COMMAND_LOAD_SPLASH_SCREEN:
- CTheScripts::ReadTextLabelFromScript(&m_nIp, tmp);
- for (int i = 0; i < KEY_LENGTH_IN_SCRIPT; i++)
- tmp[i] = tolower(tmp[i]);
- m_nIp += 8;
- LoadSplash(tmp);
- return 0;
- /*
- case COMMAND_SET_CAR_IGNORE_LEVEL_TRANSITIONS:
- {
- CollectParameters(&m_nIp, 2);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle);
- if (ScriptParams[1])
- pVehicle->m_nZoneLevel = LEVEL_IGNORE;
- else
- pVehicle->m_nZoneLevel = CTheZones::GetLevelFromPosition(&pVehicle->GetPosition());
- return 0;
- }
- case COMMAND_MAKE_CRAIGS_CAR_A_BIT_STRONGER:
- {
- 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->bMoreResistantToDamage = ScriptParams[1];
- return 0;
- }
- */
- case COMMAND_SET_JAMES_CAR_ON_PATH_TO_PLAYER:
- {
- CollectParameters(&m_nIp, 1);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle);
- CCarCtrl::JoinCarWithRoadSystemGotoCoors(pVehicle, FindPlayerCoors(), false);
- return 0;
- }
- case COMMAND_LOAD_END_OF_GAME_TUNE:
- DMAudio.ChangeMusicMode(MUSICMODE_CUTSCENE);
- printf("Start preload end of game audio\n");
- 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;
- */
- case COMMAND_SET_OBJECT_ROTATION:
- {
- CollectParameters(&m_nIp, 4);
- CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
- script_assert(pObject);
- CWorld::Remove(pObject);
- pObject->SetOrientation(
- DEGTORAD(*(float*)&ScriptParams[1]),
- DEGTORAD(*(float*)&ScriptParams[2]),
- DEGTORAD(*(float*)&ScriptParams[3]));
- pObject->GetMatrix().UpdateRW();
- pObject->UpdateRwFrame();
- CWorld::Add(pObject);
- return 0;
- }
- case COMMAND_GET_DEBUG_CAMERA_COORDINATES:
- *(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);
- return 0;
- case COMMAND_IS_PLAYER_TARGETTING_ANY_CHAR:
- {
- CollectParameters(&m_nIp, 1);
- CPlayerPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
- script_assert(pPed);
- CEntity* pTarget = pPed->m_pPointGunAt;
- UpdateCompareFlag(pTarget && pTarget->IsPed());
- return 0;
- }
- */
- case COMMAND_IS_PLAYER_TARGETTING_CHAR:
- {
- CollectParameters(&m_nIp, 2);
- CPlayerPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
- script_assert(pPed);
- CPed* pTestedPed = CPools::GetPedPool()->GetAt(ScriptParams[1]);
- script_assert(pTestedPed);
- CEntity* pTarget = pPed->m_pPointGunAt;
- 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);
- CPlayerPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
- script_assert(pPed);
- CObject* pTestedObject = CPools::GetObjectPool()->GetAt(ScriptParams[1]);
- script_assert(pTestedObject);
- CEntity* pTarget = pPed->m_pPointGunAt;
- UpdateCompareFlag(pTarget && pTarget->IsObject() && pTarget == pTestedObject);
- return 0;
- }
- */
- case COMMAND_TERMINATE_ALL_SCRIPTS_WITH_THIS_NAME:
- {
- CTheScripts::ReadTextLabelFromScript(&m_nIp, tmp);
- for (int i = 0; i < KEY_LENGTH_IN_SCRIPT; i++)
- tmp[i] = tolower(tmp[i]);
- m_nIp += 8;
- CRunningScript* pScript = CTheScripts::pActiveScripts;
- while (pScript) {
- CRunningScript* pNext = pScript->next;
- if (strcmp(pScript->m_abScriptName, tmp) == 0) {
- pScript->RemoveScriptFromList(&CTheScripts::pActiveScripts);
- pScript->AddScriptToList(&CTheScripts::pIdleScripts);
- }
- pScript = pNext;
- }
- return 0;
- }
- case COMMAND_DISPLAY_TEXT_WITH_NUMBER:
- {
- CollectParameters(&m_nIp, 2);
- wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- CTheScripts::IntroTextLines[CTheScripts::NumberOfIntroTextLinesThisFrame].m_fAtX = *(float*)&ScriptParams[0];
- CTheScripts::IntroTextLines[CTheScripts::NumberOfIntroTextLinesThisFrame].m_fAtY = *(float*)&ScriptParams[1];
- CollectParameters(&m_nIp, 1);
- CMessages::InsertNumberInString(text, ScriptParams[0], -1, -1, -1, -1, -1,
- CTheScripts::IntroTextLines[CTheScripts::NumberOfIntroTextLinesThisFrame++].m_Text);
- return 0;
- }
- case COMMAND_DISPLAY_TEXT_WITH_2_NUMBERS:
- {
- CollectParameters(&m_nIp, 2);
- wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
- CTheScripts::IntroTextLines[CTheScripts::NumberOfIntroTextLinesThisFrame].m_fAtX = *(float*)&ScriptParams[0];
- CTheScripts::IntroTextLines[CTheScripts::NumberOfIntroTextLinesThisFrame].m_fAtY = *(float*)&ScriptParams[1];
- CollectParameters(&m_nIp, 2);
- CMessages::InsertNumberInString(text, ScriptParams[0], ScriptParams[1], -1, -1, -1, -1,
- CTheScripts::IntroTextLines[CTheScripts::NumberOfIntroTextLinesThisFrame++].m_Text);
- return 0;
- }
- case COMMAND_FAIL_CURRENT_MISSION:
- CTheScripts::FailCurrentMission = 2;
- 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)
- pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
- float range = *(float*)&ScriptParams[3];
- int mi = ScriptParams[4] < 0 ? CTheScripts::UsedObjectArray[-ScriptParams[4]].index : ScriptParams[4];
- int16 total;
- CEntity* apEntities[16];
- CWorld::FindObjectsOfTypeInRange(mi, pos, range, true, &total, 16, apEntities, false, false, false, true, true);
- CEntity* pClosestEntity = nil;
- float min_dist = 2.0f * range;
- for (int i = 0; i < total; i++) {
- float dist = (apEntities[i]->GetPosition() - pos).Magnitude();
- if (dist < min_dist) {
- min_dist = dist;
- pClosestEntity = apEntities[i];
- }
- }
- if (pClosestEntity && pClosestEntity->IsDummy()) {
- CPopulation::ConvertToRealObject((CDummyObject*)pClosestEntity);
- CWorld::FindObjectsOfTypeInRange(mi, pos, range, true, &total, 16, apEntities, false, false, false, true, true);
- pClosestEntity = nil;
- float min_dist = 2.0f * range;
- for (int i = 0; i < total; i++) {
- float dist = (apEntities[i]->GetPosition() - pos).Magnitude();
- if (dist < min_dist) {
- min_dist = dist;
- pClosestEntity = apEntities[i];
- }
- }
- if (pClosestEntity->IsDummy())
- pClosestEntity = nil;
- }
- if (pClosestEntity) {
- script_assert(pClosestEntity->IsObject());
- CObject* pObject = (CObject*)pClosestEntity;
- pObject->ObjectCreatedBy = MISSION_OBJECT;
- ScriptParams[0] = CPools::GetObjectPool()->GetIndex(pObject);
- } else {
- ScriptParams[0] = -1;
- }
- StoreParameters(&m_nIp, 1);
- return 0;
-*/
- }
- /*
- case COMMAND_PLACE_OBJECT_RELATIVE_TO_OBJECT:
- {
- CollectParameters(&m_nIp, 5);
- CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
- script_assert(pObject);
- CObject* pTarget = CPools::GetObjectPool()->GetAt(ScriptParams[1]);
- script_assert(pTarget);
- CVector offset = *(CVector*)&ScriptParams[2];
- 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);
- CCarAI::TellOccupantsToLeaveCar(pVehicle);
- return 0;
- }
- case COMMAND_SET_INTERPOLATION_PARAMETERS:
- CollectParameters(&m_nIp, 2);
- 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);
- CVector pos = *(CVector*)&ScriptParams[0];
- if (pos.z <= MAP_Z_LOW_LIMIT)
- pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
- float destX = *(float*)&ScriptParams[3];
- float destY = *(float*)&ScriptParams[4];
- int32 nid = ThePaths.FindNodeClosestToCoors(pos, 0, 999999.9f, true, true);
- CPathNode* pNode = &ThePaths.m_pathNodes[nid];
- *(CVector*)&ScriptParams[0] = pNode->GetPosition();
- *(float*)&ScriptParams[3] = ThePaths.FindNodeOrientationForCarPlacementFacingDestination(nid, destX, destY, true);
- StoreParameters(&m_nIp, 4);
- return 0;
- }
- case COMMAND_GET_CLOSEST_CAR_NODE_WITH_HEADING_AWAY_POINT:
- {
- CollectParameters(&m_nIp, 5);
- CVector pos = *(CVector*)&ScriptParams[0];
- if (pos.z <= MAP_Z_LOW_LIMIT)
- pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
- float destX = *(float*)&ScriptParams[3];
- float destY = *(float*)&ScriptParams[4];
- int32 nid = ThePaths.FindNodeClosestToCoors(pos, 0, 999999.9f, true, true);
- CPathNode* pNode = &ThePaths.m_pathNodes[nid];
- *(CVector*)&ScriptParams[0] = pNode->GetPosition();
- *(float*)&ScriptParams[3] = ThePaths.FindNodeOrientationForCarPlacementFacingDestination(nid, destX, destY, false);
- 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:
- {
- 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:
- {
- 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);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle);
- pVehicle->AutoPilot.m_bStayInFastLane = !ScriptParams[1];
- return 0;
- }
- case COMMAND_CLEAR_CHAR_LAST_WEAPON_DAMAGE:
- {
- CollectParameters(&m_nIp, 1);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- 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]);
- 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, 9);
- 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->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 && pPed->GetPedState() != PED_ABSEIL)
- continue;
- if (pPed->bRemoveFromWorld)
- continue;
- if (pPed->bFadeOut)
- continue;
- if (pPed->bIsLeader || pPed->m_leader)
- continue;
- if (!pPed->IsWithinArea(x1, y1, x2, y2))
- continue;
- if (pos.z - COP_PED_FIND_Z_OFFSET > pPed->GetPosition().z)
- continue;
- if (pos.z + COP_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_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, ZONE_DEFAULT);
- if (nZone != -1)
- m_nIp += KEY_LENGTH_IN_SCRIPT;
- CZone* pZone = CTheZones::GetNavigationZone(nZone);
- int ped_handle = -1;
- CVector pos = FindPlayerCoors();
- 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->m_nPedType != PEDTYPE_COP)
- continue;
- if (pPed->CharCreatedBy != RANDOM_CHAR)
- continue;
- if (!pPed->IsPedInControl() && pPed->GetPedState() != PED_DRIVING)
- continue;
- if (pPed->bRemoveFromWorld)
- continue;
- if (pPed->bFadeOut)
- continue;
- if (pPed->bIsLeader || pPed->m_leader)
- continue;
- if (!CTheZones::PointLiesWithinZone(&pPed->GetPosition(), pZone))
- continue;
- if (pos.z - COP_PED_FIND_Z_OFFSET > pPed->GetPosition().z)
- continue;
- if (pos.z + COP_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_SET_CHAR_OBJ_FLEE_CAR:
- {
- CollectParameters(&m_nIp, 2);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[1]);
- script_assert(pVehicle);
- pPed->bScriptObjectiveCompleted = false;
- pPed->SetObjective(OBJECTIVE_FLEE_CAR, pVehicle);
- return 0;
- }
- case COMMAND_GET_DRIVER_OF_CAR:
- {
- CollectParameters(&m_nIp, 1);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle);
- CPed* pDriver = pVehicle->pDriver;
- if (pDriver)
- ScriptParams[0] = CPools::GetPedPool()->GetIndex(pDriver);
- else
- ScriptParams[0] = -1;
- StoreParameters(&m_nIp, 1);
- return 0;
- }
- case COMMAND_GET_NUMBER_OF_FOLLOWERS:
- {
- CollectParameters(&m_nIp, 1);
- CPed* pLeader = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pLeader);
- int total = 0;
- int i = CPools::GetPedPool()->GetSize();
- while (--i) {
- CPed* pPed = CPools::GetPedPool()->GetSlot(i);
- if (!pPed)
- continue;
- if (pPed->m_leader == pLeader)
- total++;
- }
- ScriptParams[0] = total;
- StoreParameters(&m_nIp, 1);
- return 0;
- }
- case COMMAND_GIVE_REMOTE_CONTROLLED_MODEL_TO_PLAYER:
- {
- CollectParameters(&m_nIp, 6);
- CVector pos = *(CVector*)&ScriptParams[1];
- if (pos.z <= MAP_Z_LOW_LIMIT)
- pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
- CRemote::GivePlayerRemoteControlledCar(pos.x, pos.y, pos.z, DEGTORAD(*(float*)&ScriptParams[4]), ScriptParams[5]);
- return 0;
- }
- case COMMAND_GET_CURRENT_PLAYER_WEAPON:
- {
- CollectParameters(&m_nIp, 1);
- CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
- script_assert(pPed);
- ScriptParams[0] = pPed->GetWeapon()->m_eWeaponType;
- StoreParameters(&m_nIp, 1);
- return 0;
- }
- case COMMAND_GET_CURRENT_CHAR_WEAPON:
- {
- CollectParameters(&m_nIp, 1);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- ScriptParams[0] = pPed->GetWeapon()->m_eWeaponType;
- StoreParameters(&m_nIp, 1);
- return 0;
- }
- case COMMAND_LOCATE_CHAR_ANY_MEANS_OBJECT_2D:
- case COMMAND_LOCATE_CHAR_ON_FOOT_OBJECT_2D:
- case COMMAND_LOCATE_CHAR_IN_CAR_OBJECT_2D:
- case COMMAND_LOCATE_CHAR_ANY_MEANS_OBJECT_3D:
- case COMMAND_LOCATE_CHAR_ON_FOOT_OBJECT_3D:
- case COMMAND_LOCATE_CHAR_IN_CAR_OBJECT_3D:
- LocateCharObjectCommand(command, &m_nIp);
- return 0;
- case COMMAND_SET_CAR_TEMP_ACTION:
- {
- CollectParameters(&m_nIp, 3);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle);
- pVehicle->AutoPilot.m_nTempAction = (eCarTempAction)ScriptParams[1];
- pVehicle->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + ScriptParams[2];
- return 0;
- }
- /*
- case COMMAND_SET_CAR_HANDBRAKE_TURN_RIGHT:
- {
- CollectParameters(&m_nIp, 2);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle);
- pVehicle->AutoPilot.m_nTempAction = TEMPACT_HANDBRAKETURNRIGHT;
- pVehicle->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + ScriptParams[1];
- return 0;
- }
- case COMMAND_SET_CAR_HANDBRAKE_STOP:
- {
- CollectParameters(&m_nIp, 2);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle);
- pVehicle->AutoPilot.m_nTempAction = TEMPACT_HANDBRAKESTRAIGHT;
- 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->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;
- StoreParameters(&m_nIp, 1);
- return 0;
- case COMMAND_IS_PLAYER_ON_ANY_BIKE:
- {
- CollectParameters(&m_nIp, 1);
- CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
- script_assert(pPed);
- UpdateCompareFlag(pPed->bInVehicle && pPed->m_pMyVehicle->GetVehicleAppearance() == VEHICLE_APPEARANCE_BIKE);
- return 0;
- }
- /*
- case COMMAND_IS_CHAR_LYING_DOWN:
- {
- CollectParameters(&m_nIp, 1);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- UpdateCompareFlag(pPed->bFallenDown);
- return 0;
- }
- */
- case COMMAND_CAN_CHAR_SEE_DEAD_CHAR:
- {
- CollectParameters(&m_nIp, 2);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- int pedtype = ScriptParams[1];
- bool can = false;
- for (int i = 0; i < pPed->m_numNearPeds; i++) {
- CPed* pTestPed = pPed->m_nearPeds[i];
- if (pTestPed->m_fHealth <= 0.0f && pTestPed->m_nPedType == pedtype && pPed->OurPedCanSeeThisOne(pTestPed))
- can = true;
- }
- UpdateCompareFlag(can);
- return 0;
- }
- case COMMAND_SET_ENTER_CAR_RANGE_MULTIPLIER:
- CollectParameters(&m_nIp, 1);
- CPed::nEnterCarRangeMultiplier = *(float*)&ScriptParams[0];
- return 0;
- case COMMAND_SET_THREAT_REACTION_RANGE_MULTIPLIER:
- CollectParameters(&m_nIp, 1);
- CPed::nThreatReactionRangeMultiplier = *(float*)&ScriptParams[0];
- return 0;
- case COMMAND_SET_CHAR_CEASE_ATTACK_TIMER:
- {
- CollectParameters(&m_nIp, 2);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- 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);
- }
- return -1;
-}
-
-
-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;
-}
-
-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]);
- break;
- 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;
- }
- default:
- script_assert(0);
- }
- return -1;
-}
-
-bool CRunningScript::CheckDamagedWeaponType(int32 actual, int32 type)
-{
- if (actual == -1)
- return false;
-
- if (type == WEAPONTYPE_ANYMELEE) {
- if (actual <= WEAPONTYPE_CHAINSAW)
- return true;
- if (actual - WEAPONTYPE_GRENADE <= WEAPONTYPE_MINIGUN)
- return false;
- return false;
- }
-
- if (type != WEAPONTYPE_ANYWEAPON)
- return false;
-
- switch (actual) {
- case WEAPONTYPE_UNARMED:
- case WEAPONTYPE_BRASSKNUCKLE:
- case WEAPONTYPE_SCREWDRIVER:
- case WEAPONTYPE_GOLFCLUB:
- case WEAPONTYPE_NIGHTSTICK:
- case WEAPONTYPE_KNIFE:
- case WEAPONTYPE_BASEBALLBAT:
- case WEAPONTYPE_HAMMER:
- case WEAPONTYPE_CLEAVER:
- case WEAPONTYPE_MACHETE:
- case WEAPONTYPE_KATANA:
- case WEAPONTYPE_CHAINSAW:
- case WEAPONTYPE_GRENADE:
- case WEAPONTYPE_DETONATOR_GRENADE:
- case WEAPONTYPE_TEARGAS:
- case WEAPONTYPE_MOLOTOV:
- case WEAPONTYPE_ROCKET:
- case WEAPONTYPE_COLT45:
- case WEAPONTYPE_PYTHON:
- case WEAPONTYPE_SHOTGUN:
- case WEAPONTYPE_SPAS12_SHOTGUN:
- case WEAPONTYPE_STUBBY_SHOTGUN:
- case WEAPONTYPE_TEC9:
- case WEAPONTYPE_UZI:
- case WEAPONTYPE_SILENCED_INGRAM:
- case WEAPONTYPE_MP5:
- case WEAPONTYPE_M4:
- case WEAPONTYPE_RUGER:
- case WEAPONTYPE_SNIPERRIFLE:
- case WEAPONTYPE_LASERSCOPE:
- case WEAPONTYPE_ROCKETLAUNCHER:
- case WEAPONTYPE_FLAMETHROWER:
- case WEAPONTYPE_M60:
- case WEAPONTYPE_MINIGUN:
- case WEAPONTYPE_DETONATOR:
- case WEAPONTYPE_HELICANNON:
- case WEAPONTYPE_CAMERA:
- case WEAPONTYPE_EXPLOSION:
- case WEAPONTYPE_UZI_DRIVEBY:
- return true;
- case WEAPONTYPE_HEALTH:
- case WEAPONTYPE_ARMOUR:
- case WEAPONTYPE_RAMMEDBYCAR:
- case WEAPONTYPE_RUNOVERBYCAR:
- case WEAPONTYPE_DROWNING:
- case WEAPONTYPE_FALL:
- case WEAPONTYPE_UNIDENTIFIED:
- return false;
- }
-
- return false;
-}
-
-bool CRunningScript::ThisIsAValidRandomCop(int32 mi, bool cop, bool swat, bool fbi, bool army, bool miami)
-{
- switch (mi)
- {
- case MI_COP: if (cop) return true;
- case MI_SWAT: if (swat) return true;
- case MI_FBI: if (fbi) return true;
- case MI_ARMY: if (army) return true;
- default:
- return miami && (mi >= MI_VICE1 && mi <= MI_VICE8);
- }
-}
-
-void CTheScripts::RemoveThisPed(CPed* pPed)
-{
- if (pPed) {
- bool bWasMissionPed = pPed->CharCreatedBy == MISSION_CHAR;
- if (pPed->InVehicle() && pPed->m_pMyVehicle) {
- if (pPed->m_pMyVehicle->pDriver == pPed) {
- pPed->m_pMyVehicle->RemoveDriver();
- pPed->m_pMyVehicle->SetStatus(STATUS_ABANDONED);
- if (pPed->m_pMyVehicle->m_nDoorLock == CARLOCK_LOCKED_INITIALLY)
- pPed->m_pMyVehicle->m_nDoorLock = CARLOCK_UNLOCKED;
- if (pPed->m_nPedType == PEDTYPE_COP && pPed->m_pMyVehicle->IsLawEnforcementVehicle())
- pPed->m_pMyVehicle->ChangeLawEnforcerState(0);
- }
- else {
- pPed->m_pMyVehicle->RemovePassenger(pPed);
- }
- }
- CWorld::RemoveReferencesToDeletedObject(pPed);
- delete pPed;
- if (bWasMissionPed)
- --CPopulation::ms_nTotalMissionPeds;
- }
-}
-
-int32 CTheScripts::GetNewUniqueScriptSphereIndex(int32 index)
-{
- if (ScriptSphereArray[index].m_Index >= UINT16_MAX - 1)
- ScriptSphereArray[index].m_Index = 1;
- else
- ScriptSphereArray[index].m_Index++;
- return (uint16)index | ScriptSphereArray[index].m_Index << 16;
-}
-
-int32 CTheScripts::GetActualScriptSphereIndex(int32 index)
-{
- if (index == -1)
- return -1;
- uint16 check = (uint32)index >> 16;
- uint16 array_idx = index & (0xFFFF);
- script_assert(array_idx < ARRAY_SIZE(ScriptSphereArray));
- if (check != ScriptSphereArray[array_idx].m_Index)
- return -1;
- return array_idx;
-}
-
-void CTheScripts::DrawScriptSpheres()
-{
- for (int i = 0; i < MAX_NUM_SCRIPT_SPHERES; i++) {
- if (ScriptSphereArray[i].m_bInUse)
- C3dMarkers::PlaceMarkerSet(ScriptSphereArray[i].m_Id, MARKERTYPE_CYLINDER, ScriptSphereArray[i].m_vecCenter, ScriptSphereArray[i].m_fRadius,
- SPHERE_MARKER_R, SPHERE_MARKER_G, SPHERE_MARKER_B, SPHERE_MARKER_A, SPHERE_MARKER_PULSE_PERIOD, SPHERE_MARKER_PULSE_FRACTION, 0);
- }
-}
-
-int32 CTheScripts::AddScriptSphere(int32 id, CVector pos, float radius)
-{
- int16 i = 0;
- for (i = 0; i < MAX_NUM_SCRIPT_SPHERES; i++) {
- if (!ScriptSphereArray[i].m_bInUse)
- break;
- }
-#ifdef FIX_BUGS
- if (i == MAX_NUM_SCRIPT_SPHERES)
- return -1;
-#endif
- ScriptSphereArray[i].m_bInUse = true;
- ScriptSphereArray[i].m_Id = id;
- ScriptSphereArray[i].m_vecCenter = pos;
- ScriptSphereArray[i].m_fRadius = radius;
- return GetNewUniqueScriptSphereIndex(i);
-}
-
-void CTheScripts::RemoveScriptSphere(int32 index)
-{
- index = GetActualScriptSphereIndex(index);
- if (index == -1)
- return;
- ScriptSphereArray[index].m_bInUse = false;
- ScriptSphereArray[index].m_Id = 0;
-}
-
-void CTheScripts::AddToBuildingSwapArray(CBuilding* pBuilding, int32 old_model, int32 new_model)
-{
- int i = 0;
- bool found = false;
- while (i < MAX_NUM_BUILDING_SWAPS && !found) {
- if (BuildingSwapArray[i].m_pBuilding == pBuilding)
- found = true;
- else
- i++;
- }
- if (found) {
- if (BuildingSwapArray[i].m_nOldModel == new_model) {
- BuildingSwapArray[i].m_pBuilding = nil;
- BuildingSwapArray[i].m_nOldModel = BuildingSwapArray[i].m_nNewModel = -1;
- }
- else {
- BuildingSwapArray[i].m_nNewModel = new_model;
- }
- }
- else {
- i = 0;
- while (i < MAX_NUM_BUILDING_SWAPS && !found) {
- if (BuildingSwapArray[i].m_pBuilding == nil)
- found = true;
- else
- i++;
- }
- if (found) {
- BuildingSwapArray[i].m_pBuilding = pBuilding;
- BuildingSwapArray[i].m_nNewModel = new_model;
- BuildingSwapArray[i].m_nOldModel = old_model;
- }
- }
-}
-
-void CTheScripts::AddToInvisibilitySwapArray(CEntity* pEntity, bool remove)
-{
- int i = 0;
- bool found = false;
- while (i < MAX_NUM_INVISIBILITY_SETTINGS && !found) {
- if (InvisibilitySettingArray[i] == pEntity)
- found = true;
- else
- i++;
- }
- if (found) {
- if (remove)
- InvisibilitySettingArray[i] = nil;
- }
- else if (!remove) {
- i = 0;
- while (i < MAX_NUM_INVISIBILITY_SETTINGS && !found) {
- if (InvisibilitySettingArray[i] == nil)
- found = true;
- else
- i++;
- }
- if (found)
- InvisibilitySettingArray[i] = pEntity;
- }
-}
-
-void CTheScripts::UndoBuildingSwaps()
-{
- for (int i = 0; i < MAX_NUM_BUILDING_SWAPS; i++) {
- if (BuildingSwapArray[i].m_pBuilding) {
- BuildingSwapArray[i].m_pBuilding->ReplaceWithNewModel(BuildingSwapArray[i].m_nOldModel);
- BuildingSwapArray[i].m_pBuilding = nil;
- BuildingSwapArray[i].m_nOldModel = BuildingSwapArray[i].m_nNewModel = -1;
- }
- }
-}
-
-void CTheScripts::UndoEntityInvisibilitySettings()
-{
- for (int i = 0; i < MAX_NUM_INVISIBILITY_SETTINGS; i++) {
- if (InvisibilitySettingArray[i]) {
- InvisibilitySettingArray[i]->bIsVisible = true;
- InvisibilitySettingArray[i] = nil;
- }
- }
-}
-
-void CRunningScript::UpdateCompareFlag(bool flag)
-{
- if (m_bNotFlag)
- flag = !flag;
- if (m_nAndOrState == ANDOR_NONE) {
- m_bCondResult = flag;
- return;
- }
- if (m_nAndOrState >= ANDS_1 && m_nAndOrState <= ANDS_8) {
- m_bCondResult &= flag;
- if (m_nAndOrState == ANDS_1) {
- m_nAndOrState = ANDOR_NONE;
- return;
- }
- }
- else if (m_nAndOrState >= ORS_1 && m_nAndOrState <= ORS_8) {
- m_bCondResult |= flag;
- if (m_nAndOrState == ORS_1) {
- m_nAndOrState = ANDOR_NONE;
- return;
- }
- }
- else {
- return;
- }
- m_nAndOrState--;
-}
-
-void CRunningScript::LocatePlayerCommand(int32 command, uint32* pIp)
-{
- bool b3D, result, debug, decided = false;
- float X, Y, Z, dX, dY, dZ;
- switch (command) {
- case COMMAND_LOCATE_PLAYER_ANY_MEANS_3D:
- case COMMAND_LOCATE_PLAYER_ON_FOOT_3D:
- case COMMAND_LOCATE_PLAYER_IN_CAR_3D:
- case COMMAND_LOCATE_STOPPED_PLAYER_ANY_MEANS_3D:
- case COMMAND_LOCATE_STOPPED_PLAYER_ON_FOOT_3D:
- case COMMAND_LOCATE_STOPPED_PLAYER_IN_CAR_3D:
- b3D = true;
- break;
- default:
- b3D = false;
- break;
- }
- CollectParameters(pIp, b3D ? 8 : 6);
- CPlayerInfo* pPlayerInfo = &CWorld::Players[ScriptParams[0]];
- switch (command) {
- case COMMAND_LOCATE_STOPPED_PLAYER_ANY_MEANS_2D:
- case COMMAND_LOCATE_STOPPED_PLAYER_ANY_MEANS_3D:
- case COMMAND_LOCATE_STOPPED_PLAYER_IN_CAR_2D:
- case COMMAND_LOCATE_STOPPED_PLAYER_IN_CAR_3D:
- case COMMAND_LOCATE_STOPPED_PLAYER_ON_FOOT_2D:
- case COMMAND_LOCATE_STOPPED_PLAYER_ON_FOOT_3D:
- if (!CTheScripts::IsPlayerStopped(pPlayerInfo)) {
- result = false;
- decided = true;
- }
- break;
- default:
- break;
- }
- 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];
- }
- if (!decided) {
- CVector pos = pPlayerInfo->GetPos();
- 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;
- }
- if (in_area) {
- switch (command) {
- case COMMAND_LOCATE_PLAYER_ANY_MEANS_2D:
- case COMMAND_LOCATE_PLAYER_ANY_MEANS_3D:
- case COMMAND_LOCATE_STOPPED_PLAYER_ANY_MEANS_2D:
- case COMMAND_LOCATE_STOPPED_PLAYER_ANY_MEANS_3D:
- result = true;
- break;
- case COMMAND_LOCATE_PLAYER_ON_FOOT_2D:
- case COMMAND_LOCATE_PLAYER_ON_FOOT_3D:
- case COMMAND_LOCATE_STOPPED_PLAYER_ON_FOOT_2D:
- case COMMAND_LOCATE_STOPPED_PLAYER_ON_FOOT_3D:
- result = !pPlayerInfo->m_pPed->bInVehicle;
- break;
- case COMMAND_LOCATE_PLAYER_IN_CAR_2D:
- case COMMAND_LOCATE_PLAYER_IN_CAR_3D:
- case COMMAND_LOCATE_STOPPED_PLAYER_IN_CAR_2D:
- case COMMAND_LOCATE_STOPPED_PLAYER_IN_CAR_3D:
- result = pPlayerInfo->m_pPed->bInVehicle;
- break;
- default:
- script_assert(false);
- break;
- }
- }
- }
- 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::LocatePlayerCharCommand(int32 command, uint32* pIp)
-{
- bool b3D, result, debug;
- float X, Y, Z, dX, dY, dZ;
- switch (command) {
- case COMMAND_LOCATE_PLAYER_ANY_MEANS_CHAR_3D:
- case COMMAND_LOCATE_PLAYER_ON_FOOT_CHAR_3D:
- case COMMAND_LOCATE_PLAYER_IN_CAR_CHAR_3D:
- b3D = true;
- break;
- default:
- b3D = false;
- break;
- }
- CollectParameters(pIp, b3D ? 6 : 5);
- CPlayerInfo* pPlayerInfo = &CWorld::Players[ScriptParams[0]];
- CPed* pTarget = CPools::GetPedPool()->GetAt(ScriptParams[1]);
- script_assert(pTarget);
- CVector pos = pPlayerInfo->GetPos();
- if (pTarget->bInVehicle) {
- X = pTarget->m_pMyVehicle->GetPosition().x;
- Y = pTarget->m_pMyVehicle->GetPosition().y;
- Z = pTarget->m_pMyVehicle->GetPosition().z;
- } else {
- X = pTarget->GetPosition().x;
- Y = pTarget->GetPosition().y;
- Z = pTarget->GetPosition().z;
- }
- dX = *(float*)&ScriptParams[2];
- dY = *(float*)&ScriptParams[3];
- if (b3D) {
- dZ = *(float*)&ScriptParams[4];
- debug = ScriptParams[5];
- }
- else {
- debug = ScriptParams[4];
- }
- 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;
- }
- if (in_area) {
- switch (command) {
- case COMMAND_LOCATE_PLAYER_ANY_MEANS_CHAR_2D:
- case COMMAND_LOCATE_PLAYER_ANY_MEANS_CHAR_3D:
- result = true;
- break;
- case COMMAND_LOCATE_PLAYER_ON_FOOT_CHAR_2D:
- case COMMAND_LOCATE_PLAYER_ON_FOOT_CHAR_3D:
- result = !pPlayerInfo->m_pPed->bInVehicle;
- break;
- case COMMAND_LOCATE_PLAYER_IN_CAR_CHAR_2D:
- case COMMAND_LOCATE_PLAYER_IN_CAR_CHAR_3D:
- result = pPlayerInfo->m_pPed->bInVehicle;
- break;
- default:
- script_assert(false);
- break;
- }
- }
- UpdateCompareFlag(result);
- if (debug)
-#ifdef FIX_BUGS
- CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, X - dX, Y - dY, X + dX, Y + dY, b3D ? Z : MAP_Z_LOW_LIMIT);
-#else
- CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, X - dX, Y - dY, X + dX, Y + dX, b3D ? Z : MAP_Z_LOW_LIMIT);
-#endif
- 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::LocatePlayerCarCommand(int32 command, uint32* pIp)
-{
- bool b3D, result, debug;
- float X, Y, Z, dX, dY, dZ;
- switch (command) {
- case COMMAND_LOCATE_PLAYER_ANY_MEANS_CAR_3D:
- case COMMAND_LOCATE_PLAYER_ON_FOOT_CAR_3D:
- case COMMAND_LOCATE_PLAYER_IN_CAR_CAR_3D:
- b3D = true;
- break;
- default:
- b3D = false;
- break;
- }
- CollectParameters(pIp, b3D ? 6 : 5);
- CPlayerInfo* pPlayerInfo = &CWorld::Players[ScriptParams[0]];
- CVehicle* pTarget = CPools::GetVehiclePool()->GetAt(ScriptParams[1]);
- script_assert(pTarget);
- CVector pos = pPlayerInfo->GetPos();
- X = pTarget->GetPosition().x;
- Y = pTarget->GetPosition().y;
- Z = pTarget->GetPosition().z;
- dX = *(float*)&ScriptParams[2];
- dY = *(float*)&ScriptParams[3];
- if (b3D) {
- dZ = *(float*)&ScriptParams[4];
- debug = ScriptParams[5];
- }
- else {
- debug = ScriptParams[4];
- }
- 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;
- }
- if (in_area) {
- switch (command) {
- case COMMAND_LOCATE_PLAYER_ANY_MEANS_CAR_2D:
- case COMMAND_LOCATE_PLAYER_ANY_MEANS_CAR_3D:
- result = true;
- break;
- case COMMAND_LOCATE_PLAYER_ON_FOOT_CAR_2D:
- case COMMAND_LOCATE_PLAYER_ON_FOOT_CAR_3D:
- result = !pPlayerInfo->m_pPed->bInVehicle;
- break;
- case COMMAND_LOCATE_PLAYER_IN_CAR_CAR_2D:
- case COMMAND_LOCATE_PLAYER_IN_CAR_CAR_3D:
- result = pPlayerInfo->m_pPed->bInVehicle;
- break;
- default:
- script_assert(false);
- break;
- }
- }
- 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::LocateCharCommand(int32 command, uint32* pIp)
-{
- bool b3D, result, debug, decided = false;
- float X, Y, Z, dX, dY, dZ;
- switch (command) {
- case COMMAND_LOCATE_CHAR_ANY_MEANS_3D:
- case COMMAND_LOCATE_CHAR_ON_FOOT_3D:
- case COMMAND_LOCATE_CHAR_IN_CAR_3D:
- case COMMAND_LOCATE_STOPPED_CHAR_ANY_MEANS_3D:
- case COMMAND_LOCATE_STOPPED_CHAR_ON_FOOT_3D:
- case COMMAND_LOCATE_STOPPED_CHAR_IN_CAR_3D:
- b3D = true;
- break;
- default:
- b3D = false;
- break;
- }
- CollectParameters(pIp, b3D ? 8 : 6);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- 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:
- case COMMAND_LOCATE_STOPPED_CHAR_IN_CAR_2D:
- case COMMAND_LOCATE_STOPPED_CHAR_IN_CAR_3D:
- case COMMAND_LOCATE_STOPPED_CHAR_ON_FOOT_2D:
- case COMMAND_LOCATE_STOPPED_CHAR_ON_FOOT_3D:
- if (!CTheScripts::IsPedStopped(pPed)) {
- result = false;
- decided = true;
- }
- break;
- default:
- break;
- }
- 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];
- }
- if (!decided) {
- 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;
- }
- if (in_area) {
- switch (command) {
- case COMMAND_LOCATE_CHAR_ANY_MEANS_2D:
- case COMMAND_LOCATE_CHAR_ANY_MEANS_3D:
- case COMMAND_LOCATE_STOPPED_CHAR_ANY_MEANS_2D:
- case COMMAND_LOCATE_STOPPED_CHAR_ANY_MEANS_3D:
- result = true;
- break;
- case COMMAND_LOCATE_CHAR_ON_FOOT_2D:
- case COMMAND_LOCATE_CHAR_ON_FOOT_3D:
- case COMMAND_LOCATE_STOPPED_CHAR_ON_FOOT_2D:
- case COMMAND_LOCATE_STOPPED_CHAR_ON_FOOT_3D:
- result = !pPed->bInVehicle;
- break;
- case COMMAND_LOCATE_CHAR_IN_CAR_2D:
- case COMMAND_LOCATE_CHAR_IN_CAR_3D:
- case COMMAND_LOCATE_STOPPED_CHAR_IN_CAR_2D:
- case COMMAND_LOCATE_STOPPED_CHAR_IN_CAR_3D:
- result = pPed->bInVehicle;
- break;
- default:
- script_assert(false);
- break;
- }
- }
- }
- 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::LocateCharCharCommand(int32 command, uint32* pIp)
-{
- bool b3D, result, debug;
- float X, Y, Z, dX, dY, dZ;
- switch (command) {
- case COMMAND_LOCATE_CHAR_ANY_MEANS_CHAR_3D:
- case COMMAND_LOCATE_CHAR_ON_FOOT_CHAR_3D:
- case COMMAND_LOCATE_CHAR_IN_CAR_CHAR_3D:
- b3D = true;
- break;
- default:
- b3D = false;
- break;
- }
- CollectParameters(pIp, b3D ? 6 : 5);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- CPed* pTarget = CPools::GetPedPool()->GetAt(ScriptParams[1]);
- script_assert(pTarget);
- CVector pos = pPed->bInVehicle ? pPed->m_pMyVehicle->GetPosition() : pPed->GetPosition();
- if (pTarget->bInVehicle) {
- X = pTarget->m_pMyVehicle->GetPosition().x;
- Y = pTarget->m_pMyVehicle->GetPosition().y;
- Z = pTarget->m_pMyVehicle->GetPosition().z;
- }
- else {
- X = pTarget->GetPosition().x;
- Y = pTarget->GetPosition().y;
- Z = pTarget->GetPosition().z;
- }
- dX = *(float*)&ScriptParams[2];
- dY = *(float*)&ScriptParams[3];
- if (b3D) {
- dZ = *(float*)&ScriptParams[4];
- debug = ScriptParams[5];
- }
- else {
- debug = ScriptParams[4];
- }
- 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;
- }
- if (in_area) {
- switch (command) {
- case COMMAND_LOCATE_CHAR_ANY_MEANS_CHAR_2D:
- case COMMAND_LOCATE_CHAR_ANY_MEANS_CHAR_3D:
- result = true;
- break;
- case COMMAND_LOCATE_CHAR_ON_FOOT_CHAR_2D:
- case COMMAND_LOCATE_CHAR_ON_FOOT_CHAR_3D:
- result = !pPed->bInVehicle;
- break;
- case COMMAND_LOCATE_CHAR_IN_CAR_CHAR_2D:
- case COMMAND_LOCATE_CHAR_IN_CAR_CHAR_3D:
- result = pPed->bInVehicle;
- break;
- default:
- script_assert(false);
- break;
- }
- }
- UpdateCompareFlag(result);
- if (debug)
-#ifdef FIX_BUGS
- CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, X - dX, Y - dY, X + dX, Y + dY, b3D ? Z : MAP_Z_LOW_LIMIT);
-#else
- CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, X - dX, Y - dY, X + dX, Y + dX, b3D ? Z : MAP_Z_LOW_LIMIT);
-#endif
- 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::LocateCharCarCommand(int32 command, uint32* pIp)
-{
- bool b3D, result, debug;
- float X, Y, Z, dX, dY, dZ;
- switch (command) {
- case COMMAND_LOCATE_CHAR_ANY_MEANS_CAR_3D:
- case COMMAND_LOCATE_CHAR_ON_FOOT_CAR_3D:
- case COMMAND_LOCATE_CHAR_IN_CAR_CAR_3D:
- b3D = true;
- break;
- default:
- b3D = false;
- break;
- }
- CollectParameters(pIp, b3D ? 6 : 5);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- CVehicle* pTarget = CPools::GetVehiclePool()->GetAt(ScriptParams[1]);
- script_assert(pTarget);
- CVector pos = pPed->bInVehicle ? pPed->m_pMyVehicle->GetPosition() : pPed->GetPosition();
- X = pTarget->GetPosition().x;
- Y = pTarget->GetPosition().y;
- Z = pTarget->GetPosition().z;
- dX = *(float*)&ScriptParams[2];
- dY = *(float*)&ScriptParams[3];
- if (b3D) {
- dZ = *(float*)&ScriptParams[4];
- debug = ScriptParams[5];
- }
- else {
- debug = ScriptParams[4];
- }
- 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;
- }
- if (in_area) {
- switch (command) {
- case COMMAND_LOCATE_CHAR_ANY_MEANS_CAR_2D:
- case COMMAND_LOCATE_CHAR_ANY_MEANS_CAR_3D:
- result = true;
- break;
- case COMMAND_LOCATE_CHAR_ON_FOOT_CAR_2D:
- case COMMAND_LOCATE_CHAR_ON_FOOT_CAR_3D:
- result = !pPed->bInVehicle;
- break;
- case COMMAND_LOCATE_CHAR_IN_CAR_CAR_2D:
- case COMMAND_LOCATE_CHAR_IN_CAR_CAR_3D:
- result = pPed->bInVehicle;
- break;
- default:
- script_assert(false);
- break;
- }
- }
- 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::LocateCharObjectCommand(int32 command, uint32* pIp)
-{
- bool b3D, result, debug;
- float X, Y, Z, dX, dY, dZ;
- switch (command) {
- case COMMAND_LOCATE_CHAR_ANY_MEANS_OBJECT_3D:
- case COMMAND_LOCATE_CHAR_ON_FOOT_OBJECT_3D:
- case COMMAND_LOCATE_CHAR_IN_CAR_OBJECT_3D:
- b3D = true;
- break;
- default:
- b3D = false;
- break;
- }
- CollectParameters(pIp, b3D ? 6 : 5);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- CObject* pTarget = CPools::GetObjectPool()->GetAt(ScriptParams[1]);
- script_assert(pTarget);
- CVector pos = pPed->bInVehicle ? pPed->m_pMyVehicle->GetPosition() : pPed->GetPosition();
- X = pTarget->GetPosition().x;
- Y = pTarget->GetPosition().y;
- Z = pTarget->GetPosition().z;
- dX = *(float*)&ScriptParams[2];
- dY = *(float*)&ScriptParams[3];
- if (b3D) {
- dZ = *(float*)&ScriptParams[4];
- debug = ScriptParams[5];
- }
- else {
- debug = ScriptParams[4];
- }
- 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;
- }
- if (in_area) {
- switch (command) {
- case COMMAND_LOCATE_CHAR_ANY_MEANS_OBJECT_2D:
- case COMMAND_LOCATE_CHAR_ANY_MEANS_OBJECT_3D:
- result = true;
- break;
- case COMMAND_LOCATE_CHAR_ON_FOOT_OBJECT_2D:
- case COMMAND_LOCATE_CHAR_ON_FOOT_OBJECT_3D:
- result = !pPed->bInVehicle;
- break;
- case COMMAND_LOCATE_CHAR_IN_CAR_OBJECT_2D:
- case COMMAND_LOCATE_CHAR_IN_CAR_OBJECT_3D:
- result = pPed->bInVehicle;
- break;
- default:
- script_assert(false);
- break;
- }
- }
- 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::LocateCarCommand(int32 command, uint32* pIp)
-{
- bool b3D, result, debug, decided = false;
- float X, Y, Z, dX, dY, dZ;
- switch (command) {
- case COMMAND_LOCATE_CAR_3D:
- case COMMAND_LOCATE_STOPPED_CAR_3D:
- b3D = true;
- break;
- default:
- b3D = false;
- break;
- }
- CollectParameters(pIp, b3D ? 8 : 6);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle);
- CVector pos = pVehicle->GetPosition();
- switch (command) {
- case COMMAND_LOCATE_STOPPED_CAR_2D:
- case COMMAND_LOCATE_STOPPED_CAR_3D:
- if (!CTheScripts::IsVehicleStopped(pVehicle)) {
- result = false;
- decided = true;
- }
- break;
- default:
- break;
- }
- 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];
- }
- if (!decided) {
- 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::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;
- float X, Y, Z, dX, dY, dZ;
- switch (command) {
- case COMMAND_LOCATE_SNIPER_BULLET_3D:
- b3D = true;
- break;
- default:
- b3D = false;
- break;
- }
- CollectParameters(pIp, b3D ? 7 : 5);
- X = *(float*)&ScriptParams[0];
- Y = *(float*)&ScriptParams[1];
- if (b3D) {
- Z = *(float*)&ScriptParams[2];
- dX = *(float*)&ScriptParams[3];
- dY = *(float*)&ScriptParams[4];
- dZ = *(float*)&ScriptParams[5];
- debug = ScriptParams[6];
- }
- else {
- dX = *(float*)&ScriptParams[2];
- dY = *(float*)&ScriptParams[3];
- debug = ScriptParams[4];
- }
- result = CBulletInfo::TestForSniperBullet(X - dX, X + dX, Y - dY, Y + dY, b3D ? Z - dZ : -1000.0f, b3D ? Z + dZ : 1000.0f);
- 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::PlayerInAreaCheckCommand(int32 command, uint32* pIp)
-{
- bool b3D, result, debug, decided = false;
- float infX, infY, infZ, supX, supY, supZ;
- switch (command) {
- case COMMAND_IS_PLAYER_IN_AREA_3D:
- case COMMAND_IS_PLAYER_IN_AREA_ON_FOOT_3D:
- case COMMAND_IS_PLAYER_IN_AREA_IN_CAR_3D:
- case COMMAND_IS_PLAYER_STOPPED_IN_AREA_3D:
- case COMMAND_IS_PLAYER_STOPPED_IN_AREA_ON_FOOT_3D:
- case COMMAND_IS_PLAYER_STOPPED_IN_AREA_IN_CAR_3D:
- b3D = true;
- break;
- default:
- b3D = false;
- break;
- }
- CollectParameters(pIp, b3D ? 8 : 6);
- CPlayerInfo* pPlayerInfo = &CWorld::Players[ScriptParams[0]];
- switch (command) {
- case COMMAND_IS_PLAYER_STOPPED_IN_AREA_3D:
- case COMMAND_IS_PLAYER_STOPPED_IN_AREA_ON_FOOT_3D:
- case COMMAND_IS_PLAYER_STOPPED_IN_AREA_IN_CAR_3D:
- case COMMAND_IS_PLAYER_STOPPED_IN_AREA_2D:
- case COMMAND_IS_PLAYER_STOPPED_IN_AREA_ON_FOOT_2D:
- case COMMAND_IS_PLAYER_STOPPED_IN_AREA_IN_CAR_2D:
- if (!CTheScripts::IsPlayerStopped(pPlayerInfo)) {
- result = false;
- decided = true;
- }
- break;
- default:
- break;
- }
- 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;
- }
- if (!decided) {
- CVector pos = pPlayerInfo->GetPos();
- 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_PLAYER_IN_AREA_2D:
- case COMMAND_IS_PLAYER_IN_AREA_3D:
- case COMMAND_IS_PLAYER_STOPPED_IN_AREA_2D:
- case COMMAND_IS_PLAYER_STOPPED_IN_AREA_3D:
- result = true;
- break;
- case COMMAND_IS_PLAYER_IN_AREA_ON_FOOT_2D:
- case COMMAND_IS_PLAYER_IN_AREA_ON_FOOT_3D:
- case COMMAND_IS_PLAYER_STOPPED_IN_AREA_ON_FOOT_2D:
- case COMMAND_IS_PLAYER_STOPPED_IN_AREA_ON_FOOT_3D:
- result = !pPlayerInfo->m_pPed->bInVehicle;
- break;
- case COMMAND_IS_PLAYER_IN_AREA_IN_CAR_2D:
- case COMMAND_IS_PLAYER_IN_AREA_IN_CAR_3D:
- case COMMAND_IS_PLAYER_STOPPED_IN_AREA_IN_CAR_2D:
- case COMMAND_IS_PLAYER_STOPPED_IN_AREA_IN_CAR_3D:
- result = pPlayerInfo->m_pPed->bInVehicle;
- 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::PlayerInAngledAreaCheckCommand(int32 command, uint32* pIp)
-{
- bool b3D, result, debug, decided = false;
- float infX, infY, infZ, supX, supY, supZ, side2length;
- switch (command) {
- case COMMAND_IS_PLAYER_IN_ANGLED_AREA_3D:
- case COMMAND_IS_PLAYER_IN_ANGLED_AREA_ON_FOOT_3D:
- case COMMAND_IS_PLAYER_IN_ANGLED_AREA_IN_CAR_3D:
- case COMMAND_IS_PLAYER_STOPPED_IN_ANGLED_AREA_3D:
- case COMMAND_IS_PLAYER_STOPPED_IN_ANGLED_AREA_ON_FOOT_3D:
- case COMMAND_IS_PLAYER_STOPPED_IN_ANGLED_AREA_IN_CAR_3D:
- b3D = true;
- break;
- default:
- b3D = false;
- break;
- }
- CollectParameters(pIp, b3D ? 9 : 7);
- CPlayerInfo* pPlayerInfo = &CWorld::Players[ScriptParams[0]];
- switch (command) {
- case COMMAND_IS_PLAYER_STOPPED_IN_ANGLED_AREA_3D:
- case COMMAND_IS_PLAYER_STOPPED_IN_ANGLED_AREA_ON_FOOT_3D:
- case COMMAND_IS_PLAYER_STOPPED_IN_ANGLED_AREA_IN_CAR_3D:
- case COMMAND_IS_PLAYER_STOPPED_IN_ANGLED_AREA_2D:
- case COMMAND_IS_PLAYER_STOPPED_IN_ANGLED_AREA_ON_FOOT_2D:
- case COMMAND_IS_PLAYER_STOPPED_IN_ANGLED_AREA_IN_CAR_2D:
- if (!CTheScripts::IsPlayerStopped(pPlayerInfo)) {
- result = false;
- decided = true;
- }
- break;
- default:
- break;
- }
- 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];
- }
- side2length = *(float*)&ScriptParams[7];
- debug = ScriptParams[8];
- }
- else {
- supX = *(float*)&ScriptParams[3];
- supY = *(float*)&ScriptParams[4];
- side2length = *(float*)&ScriptParams[5];
- debug = ScriptParams[6];
- }
- float initAngle = CGeneral::GetRadianAngleBetweenPoints(infX, infY, supX, supY) + HALFPI;
- while (initAngle < 0.0f)
- initAngle += TWOPI;
- while (initAngle > TWOPI)
- initAngle -= TWOPI;
- // it looks like the idea is to use a rectangle using the diagonal of the rectangle as
- // the side of new rectangle, with "length" being the length of second side
- float rotatedSupX = supX + side2length * sin(initAngle);
- float rotatedSupY = supY - side2length * cos(initAngle);
- float rotatedInfX = infX + side2length * sin(initAngle);
- float rotatedInfY = infY - side2length * cos(initAngle);
- float side1X = supX - infX;
- float side1Y = supY - infY;
- float side1Length = CVector2D(side1X, side1Y).Magnitude();
- float side2X = rotatedInfX - infX;
- float side2Y = rotatedInfY - infY;
- float side2Length = CVector2D(side2X, side2Y).Magnitude(); // == side2length?
- if (!decided) {
- CVector pos = pPlayerInfo->GetPos();
- result = false;
- float X = pos.x - infX;
- float Y = pos.y - infY;
- float positionAlongSide1 = X * side1X / side1Length + Y * side1Y / side1Length;
- bool in_area = false;
- if (positionAlongSide1 >= 0.0f && positionAlongSide1 <= side1Length) {
- float positionAlongSide2 = X * side2X / side2Length + Y * side2Y / side2Length;
- if (positionAlongSide2 >= 0.0f && positionAlongSide2 <= side2Length) {
- in_area = !b3D || pos.z >= infZ && pos.z <= supZ;
- }
- }
-
- if (in_area) {
- switch (command) {
- case COMMAND_IS_PLAYER_IN_ANGLED_AREA_2D:
- case COMMAND_IS_PLAYER_IN_ANGLED_AREA_3D:
- case COMMAND_IS_PLAYER_STOPPED_IN_ANGLED_AREA_2D:
- case COMMAND_IS_PLAYER_STOPPED_IN_ANGLED_AREA_3D:
- result = true;
- break;
- case COMMAND_IS_PLAYER_IN_ANGLED_AREA_ON_FOOT_2D:
- case COMMAND_IS_PLAYER_IN_ANGLED_AREA_ON_FOOT_3D:
- case COMMAND_IS_PLAYER_STOPPED_IN_ANGLED_AREA_ON_FOOT_2D:
- case COMMAND_IS_PLAYER_STOPPED_IN_ANGLED_AREA_ON_FOOT_3D:
- result = !pPlayerInfo->m_pPed->bInVehicle;
- break;
- case COMMAND_IS_PLAYER_IN_ANGLED_AREA_IN_CAR_2D:
- case COMMAND_IS_PLAYER_IN_ANGLED_AREA_IN_CAR_3D:
- case COMMAND_IS_PLAYER_STOPPED_IN_ANGLED_AREA_IN_CAR_2D:
- case COMMAND_IS_PLAYER_STOPPED_IN_ANGLED_AREA_IN_CAR_3D:
- result = pPlayerInfo->m_pPed->bInVehicle;
- break;
- default:
- script_assert(false);
- break;
- }
- }
- }
- UpdateCompareFlag(result);
- if (debug)
- CTheScripts::HighlightImportantAngledArea((uintptr)this + m_nIp, infX, infY, supX, supY,
- rotatedSupX, rotatedSupY, rotatedInfX, rotatedInfY, b3D ? (infZ + supZ) / 2 : MAP_Z_LOW_LIMIT);
- if (CTheScripts::DbgFlag) {
- if (b3D)
- CTheScripts::DrawDebugAngledCube(infX, infY, infZ, supX, supY, supZ,
- rotatedSupX, rotatedSupY, rotatedInfX, rotatedInfY);
- else
- CTheScripts::DrawDebugAngledSquare(infX, infY, supX, supY,
- rotatedSupX, rotatedSupY, rotatedInfX, rotatedInfY);
- }
-}
-
-void CRunningScript::CharInAreaCheckCommand(int32 command, uint32* pIp)
-{
- bool b3D, result, debug, decided = false;
- float infX, infY, infZ, supX, supY, supZ;
- switch (command) {
- case COMMAND_IS_CHAR_IN_AREA_3D:
- case COMMAND_IS_CHAR_IN_AREA_ON_FOOT_3D:
- case COMMAND_IS_CHAR_IN_AREA_IN_CAR_3D:
- case COMMAND_IS_CHAR_STOPPED_IN_AREA_3D:
- case COMMAND_IS_CHAR_STOPPED_IN_AREA_ON_FOOT_3D:
- case COMMAND_IS_CHAR_STOPPED_IN_AREA_IN_CAR_3D:
- b3D = true;
- break;
- default:
- b3D = false;
- break;
- }
- CollectParameters(pIp, b3D ? 8 : 6);
- CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
- script_assert(pPed);
- 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:
- case COMMAND_IS_CHAR_STOPPED_IN_AREA_IN_CAR_3D:
- case COMMAND_IS_CHAR_STOPPED_IN_AREA_2D:
- case COMMAND_IS_CHAR_STOPPED_IN_AREA_ON_FOOT_2D:
- case COMMAND_IS_CHAR_STOPPED_IN_AREA_IN_CAR_2D:
- if (!CTheScripts::IsPedStopped(pPed)) {
- result = false;
- decided = true;
- }
- break;
- default:
- break;
- }
- 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;
- }
- if (!decided) {
- 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_CHAR_IN_AREA_2D:
- case COMMAND_IS_CHAR_IN_AREA_3D:
- case COMMAND_IS_CHAR_STOPPED_IN_AREA_2D:
- case COMMAND_IS_CHAR_STOPPED_IN_AREA_3D:
- result = true;
- break;
- case COMMAND_IS_CHAR_IN_AREA_ON_FOOT_2D:
- case COMMAND_IS_CHAR_IN_AREA_ON_FOOT_3D:
- case COMMAND_IS_CHAR_STOPPED_IN_AREA_ON_FOOT_2D:
- case COMMAND_IS_CHAR_STOPPED_IN_AREA_ON_FOOT_3D:
- result = !pPed->bInVehicle;
- break;
- case COMMAND_IS_CHAR_IN_AREA_IN_CAR_2D:
- case COMMAND_IS_CHAR_IN_AREA_IN_CAR_3D:
- case COMMAND_IS_CHAR_STOPPED_IN_AREA_IN_CAR_2D:
- case COMMAND_IS_CHAR_STOPPED_IN_AREA_IN_CAR_3D:
- result = pPed->bInVehicle;
- 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::CarInAreaCheckCommand(int32 command, uint32* pIp)
-{
- bool b3D, result, debug, decided = false;
- float infX, infY, infZ, supX, supY, supZ;
- switch (command) {
- case COMMAND_IS_CAR_IN_AREA_3D:
- case COMMAND_IS_CAR_STOPPED_IN_AREA_3D:
- b3D = true;
- break;
- default:
- b3D = false;
- break;
- }
- CollectParameters(pIp, b3D ? 8 : 6);
- CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
- script_assert(pVehicle);
- CVector pos = pVehicle->GetPosition();
- switch (command) {
- case COMMAND_IS_CAR_STOPPED_IN_AREA_3D:
- case COMMAND_IS_CAR_STOPPED_IN_AREA_2D:
- if (!CTheScripts::IsVehicleStopped(pVehicle)) {
- result = false;
- decided = true;
- }
- break;
- default:
- break;
- }
- 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;
- }
- if (!decided) {
- 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_CAR_IN_AREA_2D:
- case COMMAND_IS_CAR_IN_AREA_3D:
- case COMMAND_IS_CAR_STOPPED_IN_AREA_2D:
- case COMMAND_IS_CAR_STOPPED_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::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)
- return;
- if (!CTheScripts::IsPlayerOnAMission())
- return;
- CPlayerInfo* pPlayer = &CWorld::Players[CWorld::PlayerInFocus];
- if (!pPlayer->IsRestartingAfterDeath() && !pPlayer->IsRestartingAfterArrest())
- return;
-#ifdef MISSION_REPLAY
- if (AllowMissionReplay != 0)
- return;
- if (CanAllowMissionReplay())
- AllowMissionReplay = 1;
-#endif
- script_assert(m_nStackPointer > 0);
- while (m_nStackPointer > 1)
- --m_nStackPointer;
- m_nIp = m_anStack[--m_nStackPointer];
- CMessages::ClearSmallMessagesOnly();
- *(int32*)&CTheScripts::ScriptSpace[CTheScripts::OnAMissionFlag] = 0;
- m_bDeatharrestExecuted = true;
- m_nWakeTime = 0;
-}
-
-int16 CRunningScript::GetPadState(uint16 pad, uint16 button)
-{
- CPad* pPad = CPad::GetPad(pad);
- switch (button) {
- case 0: return pPad->NewState.LeftStickX;
- case 1: return pPad->NewState.LeftStickY;
- case 2: return pPad->NewState.RightStickX;
- case 3: return pPad->NewState.RightStickY;
- case 4: return pPad->NewState.LeftShoulder1;
- case 5: return pPad->NewState.LeftShoulder2;
- case 6: return pPad->NewState.RightShoulder1;
- case 7: return pPad->NewState.RightShoulder2;
- case 8: return pPad->NewState.DPadUp;
- case 9: return pPad->NewState.DPadDown;
- case 10: return pPad->NewState.DPadLeft;
- case 11: return pPad->NewState.DPadRight;
- case 12: return pPad->NewState.Start;
- case 13: return pPad->NewState.Select;
- case 14: return pPad->NewState.Square;
- case 15: return pPad->NewState.Triangle;
- case 16: return pPad->NewState.Cross;
- case 17: return pPad->NewState.Circle;
- case 18: return pPad->NewState.LeftShock;
- case 19: return pPad->NewState.RightShock;
- default: break;
- }
- return 0;
-}
-
-void CTheScripts::PrintListSizes()
-{
- int active = 0;
- int idle = 0;
-
- for (CRunningScript* pScript = pActiveScripts; pScript; pScript = pScript->GetNext())
- active++;
- for (CRunningScript* pScript = pIdleScripts; pScript; pScript = pScript->GetNext())
- idle++;
-
- debug("active: %d, idle: %d", active, idle);
-}
-
-uint32 DbgLineColour = 0x0000FFFF; // r = 0, g = 0, b = 255, a = 255
-
-void CTheScripts::DrawDebugSquare(float infX, float infY, float supX, float supY)
-{
- CColPoint tmpCP;
- CEntity* tmpEP;
- CVector p1, p2, p3, p4;
- p1 = CVector(infX, infY, -1000.0f);
- CWorld::ProcessVerticalLine(p1, 1000.0f, tmpCP, tmpEP, true, false, false, false, true, false, nil);
- p1.z = 2.0f + tmpCP.point.z;
- p2 = CVector(supX, supY, -1000.0f);
- CWorld::ProcessVerticalLine(p2, 1000.0f, tmpCP, tmpEP, true, false, false, false, true, false, nil);
- p2.z = 2.0f + tmpCP.point.z;
- p3 = CVector(infX, supY, -1000.0f);
- CWorld::ProcessVerticalLine(p3, 1000.0f, tmpCP, tmpEP, true, false, false, false, true, false, nil);
- p3.z = 2.0f + tmpCP.point.z;
- p4 = CVector(supX, infY, -1000.0f);
- CWorld::ProcessVerticalLine(p4, 1000.0f, tmpCP, tmpEP, true, false, false, false, true, false, nil);
- p4.z = 2.0f + tmpCP.point.z;
- CTheScripts::ScriptDebugLine3D(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z, DbgLineColour, DbgLineColour);
- CTheScripts::ScriptDebugLine3D(p2.x, p2.y, p2.z, p3.x, p3.y, p3.z, DbgLineColour, DbgLineColour);
- CTheScripts::ScriptDebugLine3D(p3.x, p3.y, p3.z, p4.x, p4.y, p4.z, DbgLineColour, DbgLineColour);
- CTheScripts::ScriptDebugLine3D(p4.x, p4.y, p4.z, p1.x, p1.y, p1.z, DbgLineColour, DbgLineColour);
-}
-
-void CTheScripts::DrawDebugAngledSquare(float infX, float infY, float supX, float supY, float rotSupX, float rotSupY, float rotInfX, float rotInfY)
-{
- CColPoint tmpCP;
- CEntity* tmpEP;
- CVector p1, p2, p3, p4;
- p1 = CVector(infX, infY, -1000.0f);
- CWorld::ProcessVerticalLine(p1, 1000.0f, tmpCP, tmpEP, true, false, false, false, true, false, nil);
- p1.z = 2.0f + tmpCP.point.z;
- p2 = CVector(supX, supY, -1000.0f);
- CWorld::ProcessVerticalLine(p2, 1000.0f, tmpCP, tmpEP, true, false, false, false, true, false, nil);
- p2.z = 2.0f + tmpCP.point.z;
- p3 = CVector(rotSupX, rotSupY, -1000.0f);
- CWorld::ProcessVerticalLine(p3, 1000.0f, tmpCP, tmpEP, true, false, false, false, true, false, nil);
- p3.z = 2.0f + tmpCP.point.z;
- p4 = CVector(rotInfX, rotInfY, -1000.0f);
- CWorld::ProcessVerticalLine(p4, 1000.0f, tmpCP, tmpEP, true, false, false, false, true, false, nil);
- p4.z = 2.0f + tmpCP.point.z;
- CTheScripts::ScriptDebugLine3D(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z, DbgLineColour, DbgLineColour);
- CTheScripts::ScriptDebugLine3D(p2.x, p2.y, p2.z, p3.x, p3.y, p3.z, DbgLineColour, DbgLineColour);
- CTheScripts::ScriptDebugLine3D(p3.x, p3.y, p3.z, p4.x, p4.y, p4.z, DbgLineColour, DbgLineColour);
- CTheScripts::ScriptDebugLine3D(p4.x, p4.y, p4.z, p1.x, p1.y, p1.z, DbgLineColour, DbgLineColour);
-}
-
-void CTheScripts::DrawDebugCube(float infX, float infY, float infZ, float supX, float supY, float supZ)
-{
- CTheScripts::ScriptDebugLine3D(infX, infY, infZ, supX, infY, infZ, DbgLineColour, DbgLineColour);
- CTheScripts::ScriptDebugLine3D(supX, infY, infZ, supX, supY, infZ, DbgLineColour, DbgLineColour);
- CTheScripts::ScriptDebugLine3D(supX, supY, infZ, infX, supY, infZ, DbgLineColour, DbgLineColour);
- CTheScripts::ScriptDebugLine3D(infX, supY, infZ, infX, infY, infZ, DbgLineColour, DbgLineColour);
- CTheScripts::ScriptDebugLine3D(infX, infY, supZ, supX, infY, supZ, DbgLineColour, DbgLineColour);
- CTheScripts::ScriptDebugLine3D(supX, infY, supZ, supX, supY, supZ, DbgLineColour, DbgLineColour);
- CTheScripts::ScriptDebugLine3D(supX, supY, supZ, infX, supY, supZ, DbgLineColour, DbgLineColour);
- CTheScripts::ScriptDebugLine3D(infX, supY, supZ, infX, infY, supZ, DbgLineColour, DbgLineColour);
- CTheScripts::ScriptDebugLine3D(infX, infY, supZ, infX, infY, infZ, DbgLineColour, DbgLineColour);
- CTheScripts::ScriptDebugLine3D(supX, infY, supZ, supX, infY, infZ, DbgLineColour, DbgLineColour);
- CTheScripts::ScriptDebugLine3D(supX, supY, supZ, supX, supY, infZ, DbgLineColour, DbgLineColour);
- CTheScripts::ScriptDebugLine3D(infX, supY, supZ, infX, supY, infZ, DbgLineColour, DbgLineColour);
-}
-
-void CTheScripts::DrawDebugAngledCube(float infX, float infY, float infZ, float supX, float supY, float supZ, float rotSupX, float rotSupY, float rotInfX, float rotInfY)
-{
- CTheScripts::ScriptDebugLine3D(infX, infY, infZ, supX, infY, infZ, DbgLineColour, DbgLineColour);
- CTheScripts::ScriptDebugLine3D(supX, infY, infZ, rotSupX, rotSupY, infZ, DbgLineColour, DbgLineColour);
- CTheScripts::ScriptDebugLine3D(rotSupX, rotSupY, infZ, rotInfX, rotInfY, infZ, DbgLineColour, DbgLineColour);
- CTheScripts::ScriptDebugLine3D(rotInfX, rotInfY, infZ, infX, infY, infZ, DbgLineColour, DbgLineColour);
- CTheScripts::ScriptDebugLine3D(infX, infY, supZ, supX, infY, supZ, DbgLineColour, DbgLineColour);
- CTheScripts::ScriptDebugLine3D(supX, infY, supZ, rotSupX, rotSupY, supZ, DbgLineColour, DbgLineColour);
- CTheScripts::ScriptDebugLine3D(rotSupX, rotSupY, rotInfX, rotInfY, supY, supZ, DbgLineColour, DbgLineColour);
- CTheScripts::ScriptDebugLine3D(rotInfX, rotInfY, supZ, infX, infY, supZ, DbgLineColour, DbgLineColour);
- CTheScripts::ScriptDebugLine3D(infX, infY, supZ, infX, infY, infZ, DbgLineColour, DbgLineColour);
- CTheScripts::ScriptDebugLine3D(supX, infY, supZ, supX, infY, infZ, DbgLineColour, DbgLineColour);
- CTheScripts::ScriptDebugLine3D(rotSupX, rotSupY, supZ, rotSupX, rotSupY, infZ, DbgLineColour, DbgLineColour);
- CTheScripts::ScriptDebugLine3D(rotInfX, rotInfY, supZ, rotInfX, rotInfY, infZ, DbgLineColour, DbgLineColour);
-}
-
-void CTheScripts::ScriptDebugLine3D(float x1, float y1, float z1, float x2, float y2, float z2, uint32 col, uint32 col2)
-{
- if (NumScriptDebugLines >= MAX_NUM_STORED_LINES)
- return;
- aStoredLines[NumScriptDebugLines].vecInf = CVector(x1, y1, z1);
- aStoredLines[NumScriptDebugLines].vecSup = CVector(x2, y2, z2);
- aStoredLines[NumScriptDebugLines].color1 = col;
- aStoredLines[NumScriptDebugLines++].color2 = col2;
-}
-
-void CTheScripts::RenderTheScriptDebugLines()
-{
- RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)1);
- RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)1);
- for (int i = 0; i < NumScriptDebugLines; i++) {
- CLines::RenderLineWithClipping(
- aStoredLines[i].vecInf.x,
- aStoredLines[i].vecInf.y,
- aStoredLines[i].vecInf.z,
- aStoredLines[i].vecSup.x,
- aStoredLines[i].vecSup.y,
- aStoredLines[i].vecSup.z,
- aStoredLines[i].color1,
- aStoredLines[i].color2);
- }
- NumScriptDebugLines = 0;
- RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)0);
-}
-
-#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)
-{
-INITSAVEBUF
- uint32 varSpace = GetSizeOfVariableSpace();
- uint32 runningScripts = 0;
- for (CRunningScript* pScript = pActiveScripts; pScript; pScript = pScript->GetNext())
- runningScripts++;
- *size = CRunningScript::nSaveStructSize * runningScripts + varSpace + SCRIPT_DATA_SIZE + SAVE_HEADER_SIZE + 3 * sizeof(uint32);
- WriteSaveHeader(buf, 'S', 'C', 'R', '\0', *size - SAVE_HEADER_SIZE);
- WriteSaveBuf(buf, varSpace);
- for (uint32 i = 0; i < varSpace; i++)
- WriteSaveBuf(buf, ScriptSpace[i]);
-#ifdef CHECK_STRUCT_SIZES
- static_assert(SCRIPT_DATA_SIZE == 968, "CTheScripts::SaveAllScripts");
-#endif
- uint32 script_data_size = SCRIPT_DATA_SIZE;
- WriteSaveBuf(buf, script_data_size);
- WriteSaveBuf(buf, OnAMissionFlag);
- WriteSaveBuf(buf, LastMissionPassedTime);
- for (uint32 i = 0; i < MAX_NUM_BUILDING_SWAPS; i++) {
- CBuilding* pBuilding = BuildingSwapArray[i].m_pBuilding;
- uint32 type, handle;
- if (!pBuilding) {
- type = 0;
- handle = 0;
- } else if (pBuilding->GetIsATreadable()) {
- type = 1;
- handle = CPools::GetTreadablePool()->GetJustIndex((CTreadable*)pBuilding) + 1;
- } else {
- type = 2;
- handle = CPools::GetBuildingPool()->GetJustIndex(pBuilding) + 1;
- }
- WriteSaveBuf(buf, type);
- WriteSaveBuf(buf, handle);
- WriteSaveBuf(buf, BuildingSwapArray[i].m_nNewModel);
- WriteSaveBuf(buf, BuildingSwapArray[i].m_nOldModel);
- }
- for (uint32 i = 0; i < MAX_NUM_INVISIBILITY_SETTINGS; i++) {
- CEntity* pEntity = InvisibilitySettingArray[i];
- uint32 type, handle;
- if (!pEntity) {
- type = 0;
- handle = 0;
- } else {
- switch (pEntity->GetType()) {
- case ENTITY_TYPE_BUILDING:
- if (((CBuilding*)pEntity)->GetIsATreadable()) {
- type = 1;
- handle = CPools::GetTreadablePool()->GetJustIndex((CTreadable*)pEntity) + 1;
- } else {
- type = 2;
- handle = CPools::GetBuildingPool()->GetJustIndex((CBuilding*)pEntity) + 1;
- }
- break;
- case ENTITY_TYPE_OBJECT:
- type = 3;
- handle = CPools::GetObjectPool()->GetJustIndex((CObject*)pEntity) + 1;
- break;
- case ENTITY_TYPE_DUMMY:
- type = 4;
- handle = CPools::GetDummyPool()->GetJustIndex((CDummy*)pEntity) + 1;
- default: break;
- }
- }
- WriteSaveBuf(buf, type);
- WriteSaveBuf(buf, handle);
- }
- WriteSaveBuf(buf, bUsingAMultiScriptFile);
- WriteSaveBuf(buf, bPlayerHasMetDebbieHarry);
- WriteSaveBuf(buf, (uint16)0);
- WriteSaveBuf(buf, MainScriptSize);
- WriteSaveBuf(buf, LargestMissionScriptSize);
- WriteSaveBuf(buf, NumberOfMissionScripts);
- WriteSaveBuf(buf, NumberOfExclusiveMissionScripts);
- WriteSaveBuf(buf, runningScripts);
- for (CRunningScript* pScript = pActiveScripts; pScript; pScript = pScript->GetNext())
- pScript->Save(buf);
-VALIDATESAVEBUF(*size)
-}
-
-void CTheScripts::LoadAllScripts(uint8* buf, uint32 size)
-{
- Init();
-INITSAVEBUF
- CheckSaveHeader(buf, 'S', 'C', 'R', '\0', size - SAVE_HEADER_SIZE);
- uint32 varSpace = ReadSaveBuf<uint32>(buf);
- for (uint32 i = 0; i < varSpace; i++)
- ScriptSpace[i] = ReadSaveBuf<uint8>(buf);
- script_assert(ReadSaveBuf<uint32>(buf) == SCRIPT_DATA_SIZE);
- OnAMissionFlag = 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);
- switch (type) {
- case 0:
- BuildingSwapArray[i].m_pBuilding = nil;
- break;
- case 1:
- BuildingSwapArray[i].m_pBuilding = CPools::GetTreadablePool()->GetSlot(handle - 1);
- break;
- case 2:
- BuildingSwapArray[i].m_pBuilding = CPools::GetBuildingPool()->GetSlot(handle - 1);
- break;
- default:
- script_assert(false);
- }
- BuildingSwapArray[i].m_nNewModel = ReadSaveBuf<uint32>(buf);
- BuildingSwapArray[i].m_nOldModel = ReadSaveBuf<uint32>(buf);
- if (BuildingSwapArray[i].m_pBuilding)
- BuildingSwapArray[i].m_pBuilding->ReplaceWithNewModel(BuildingSwapArray[i].m_nNewModel);
- }
- for (uint32 i = 0; i < MAX_NUM_INVISIBILITY_SETTINGS; i++) {
- uint32 type = ReadSaveBuf<uint32>(buf);
- uint32 handle = ReadSaveBuf<uint32>(buf);
- switch (type) {
- case 0:
- InvisibilitySettingArray[i] = nil;
- break;
- case 1:
- InvisibilitySettingArray[i] = CPools::GetTreadablePool()->GetSlot(handle - 1);
- break;
- case 2:
- InvisibilitySettingArray[i] = CPools::GetBuildingPool()->GetSlot(handle - 1);
- break;
- case 3:
- InvisibilitySettingArray[i] = CPools::GetObjectPool()->GetSlot(handle - 1);
- break;
- case 4:
- InvisibilitySettingArray[i] = CPools::GetDummyPool()->GetSlot(handle - 1);
- break;
- default:
- script_assert(false);
- }
- if (InvisibilitySettingArray[i])
- InvisibilitySettingArray[i]->bIsVisible = false;
- }
- script_assert(ReadSaveBuf<bool>(buf) == bUsingAMultiScriptFile);
- 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);
- script_assert(ReadSaveBuf<uint16>(buf) == NumberOfExclusiveMissionScripts);
- uint32 runningScripts = ReadSaveBuf<uint32>(buf);
- for (uint32 i = 0; i < runningScripts; i++)
- StartNewScript(0)->Load(buf);
-VALIDATESAVEBUF(size)
-}
-
-#undef SCRIPT_DATA_SIZE
-
-void CTheScripts::ClearSpaceForMissionEntity(const CVector& pos, CEntity* pEntity)
-{
- static CColPoint aTempColPoints[MAX_COLLISION_POINTS];
- int16 entities = 0;
- CEntity* aEntities[16];
- CWorld::FindObjectsKindaColliding(pos, pEntity->GetBoundRadius(), false, &entities, 16, aEntities, false, true, true, false, false);
- if (entities <= 0)
- return;
- for (uint16 i = 0; i < entities; i++) {
- if (aEntities[i] != pEntity && aEntities[i]->IsPed() && ((CPed*)aEntities[i])->bInVehicle)
- aEntities[i] = nil;
- }
- for (uint16 i = 0; i < entities; i++) {
- if (aEntities[i] == pEntity || !aEntities[i])
- continue;
- CEntity* pFound = aEntities[i];
- int cols;
- if (pEntity->GetColModel()->numLines <= 0)
- cols = CCollision::ProcessColModels(pEntity->GetMatrix(), *pEntity->GetColModel(),
- pFound->GetMatrix(), *pFound->GetColModel(), aTempColPoints, nil, nil);
- else {
- float lines[4];
- lines[0] = lines[1] = lines[2] = lines[3] = 1.0f;
- CColPoint tmp[4];
- cols = CCollision::ProcessColModels(pEntity->GetMatrix(), *pEntity->GetColModel(),
- pFound->GetMatrix(), *pFound->GetColModel(), aTempColPoints,tmp, lines);
- }
- if (cols <= 0)
- continue;
- switch (pFound->GetType()) {
- case ENTITY_TYPE_VEHICLE:
- {
- printf("Will try to delete a vehicle where a mission entity should be\n");
- CVehicle* pVehicle = (CVehicle*)pFound;
- if (pVehicle->bIsLocked || !pVehicle->CanBeDeleted())
- break;
- if (pVehicle->pDriver) {
- CPopulation::RemovePed(pVehicle->pDriver);
- pVehicle->pDriver = nil;
- }
- for (int i = 0; i < pVehicle->m_nNumMaxPassengers; i++) {
- if (pVehicle->pPassengers[i]) {
- CPopulation::RemovePed(pVehicle->pPassengers[i]);
- pVehicle->pPassengers[i] = 0;
- pVehicle->m_nNumPassengers--;
- }
- }
- CCarCtrl::RemoveFromInterestingVehicleList(pVehicle);
- CWorld::Remove(pVehicle);
- delete pVehicle;
- break;
- }
- case ENTITY_TYPE_PED:
- {
- CPed* pPed = (CPed*)pFound;
- if (pPed->IsPlayer() || !pPed->CanBeDeleted())
- break;
- CPopulation::RemovePed(pPed);
- printf("Deleted a ped where a mission entity should be\n");
- break;
- }
- default: break;
- }
- }
-}
-
-void CTheScripts::HighlightImportantArea(uint32 id, float x1, float y1, float x2, float y2, float z)
-{
- float infX, infY, supX, supY;
- if (x1 < x2) {
- infX = x1;
- supX = x2;
- } else {
- infX = x2;
- supX = x1;
- }
- if (y1 < y2) {
- infY = y1;
- supY = y2;
- }
- else {
- infY = y2;
- supY = y1;
- }
- CVector center;
- center.x = (infX + supX) / 2;
- center.y = (infY + supY) / 2;
- center.z = (z <= MAP_Z_LOW_LIMIT) ? CWorld::FindGroundZForCoord(center.x, center.y) : z;
- CShadows::RenderIndicatorShadow(id, 2, gpGoalTex, &center, supX - center.x, 0.0f, 0.0f, center.y - supY, 0);
-}
-
-void CTheScripts::HighlightImportantAngledArea(uint32 id, float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4, float z)
-{
- float infX, infY, supX, supY, X, Y;
- X = (x1 + x2) / 2;
- Y = (y1 + y2) / 2;
- supX = infX = X;
- supY = infY = Y;
- X = (x2 + x3) / 2;
- Y = (y2 + y3) / 2;
- infX = Min(infX, X);
- supX = Max(supX, X);
- infY = Min(infY, Y);
- supY = Max(supY, Y);
- X = (x3 + x4) / 2;
- Y = (y3 + y4) / 2;
- infX = Min(infX, X);
- supX = Max(supX, X);
- infY = Min(infY, Y);
- supY = Max(supY, Y);
- X = (x4 + x1) / 2;
- Y = (y4 + y1) / 2;
- infX = Min(infX, X);
- supX = Max(supX, X);
- infY = Min(infY, Y);
- supY = Max(supY, Y);
- CVector center;
- center.x = (infX + supX) / 2;
- center.y = (infY + supY) / 2;
- center.z = (z <= MAP_Z_LOW_LIMIT) ? CWorld::FindGroundZForCoord(center.x, center.y) : z;
- CShadows::RenderIndicatorShadow(id, 2, gpGoalTex, &center, supX - center.x, 0.0f, 0.0f, center.y - supY, 0);
-}
-
-bool CTheScripts::IsPedStopped(CPed* pPed)
-{
- if (pPed->InVehicle())
- return IsVehicleStopped(pPed->m_pMyVehicle);
- 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->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) &&
- !pPed->bIsInTheAir && !pPed->bIsLanding && pPed->bIsStanding && pPed->m_vecAnimMoveDelta.x == 0.0f && pPed->m_vecAnimMoveDelta.y == 0.0f;
-}
-
-bool CTheScripts::IsVehicleStopped(CVehicle* pVehicle)
-{
- return 0.01f * CTimer::GetTimeStep() >= pVehicle->m_fDistanceTravelled;
-}
-
-void CTheScripts::CleanUpThisPed(CPed* pPed)
-{
- if (!pPed)
- return;
- if (pPed->CharCreatedBy != MISSION_CHAR)
- return;
- pPed->CharCreatedBy = RANDOM_CHAR;
- if (pPed->m_nPedType == PEDTYPE_PROSTITUTE)
- pPed->m_objectiveTimer = CTimer::GetTimeInMilliseconds() + 30000;
- if (pPed->InVehicle()) {
- if (pPed->m_pMyVehicle->pDriver == pPed) {
- if (pPed->m_pMyVehicle->m_vehType == VEHICLE_TYPE_CAR) {
- CCarCtrl::JoinCarWithRoadSystem(pPed->m_pMyVehicle);
- pPed->m_pMyVehicle->AutoPilot.m_nCarMission = MISSION_CRUISE;
- }
- }
- else {
- if (pPed->m_pMyVehicle->m_vehType == VEHICLE_TYPE_CAR) {
- pPed->SetObjective(OBJECTIVE_LEAVE_CAR, pPed->m_pMyVehicle);
- pPed->bWanderPathAfterExitingCar = true;
- }
- }
- }
- bool flees = false;
- PedState state;
- eMoveState ms;
- if (pPed->m_nPedState == PED_FLEE_ENTITY || pPed->m_nPedState == PED_FLEE_POS) {
- ms = pPed->m_nMoveState;
- state = pPed->m_nPedState;
- flees = true;
- }
- pPed->ClearObjective();
- pPed->bRespondsToThreats = true;
- pPed->bScriptObjectiveCompleted = false;
- pPed->bKindaStayInSamePlace = false;
- pPed->ClearLeader();
- if (pPed->IsPedInControl())
- pPed->SetWanderPath(CGeneral::GetRandomNumber() & 7);
- if (flees) {
- if (pPed->m_nPedState == PED_FOLLOW_PATH && state != PED_FOLLOW_PATH)
- pPed->ClearFollowPath();
-
- pPed->m_nPedState = state;
- pPed->SetMoveState(ms);
- }
- --CPopulation::ms_nTotalMissionPeds;
-}
-
-void CTheScripts::CleanUpThisVehicle(CVehicle* pVehicle)
-{
- if (!pVehicle)
- return;
- if (pVehicle->VehicleCreatedBy != MISSION_VEHICLE)
- return;
- pVehicle->bIsLocked = false;
- CCarCtrl::RemoveFromInterestingVehicleList(pVehicle);
- pVehicle->VehicleCreatedBy = RANDOM_VEHICLE;
- ++CCarCtrl::NumRandomCars;
- --CCarCtrl::NumMissionCars;
-}
-
-void CTheScripts::CleanUpThisObject(CObject* pObject)
-{
- if (!pObject)
- return;
- if (pObject->ObjectCreatedBy != MISSION_OBJECT)
- return;
- pObject->ObjectCreatedBy = TEMP_OBJECT;
- pObject->m_nEndOfLifeTime = CTimer::GetTimeInMilliseconds() + 20000000;
- pObject->m_nRefModelIndex = -1;
- pObject->bUseVehicleColours = false;
- ++CObject::nNoTempObjects;
-}
-
-void CTheScripts::ReadObjectNamesFromScript()
-{
- int32 varSpace = GetSizeOfVariableSpace();
- uint32 ip = varSpace + 8;
- NumberOfUsedObjects = Read2BytesFromScript(&ip);
- ip += 2;
- for (uint16 i = 0; i < NumberOfUsedObjects; i++) {
- for (int j = 0; j < USED_OBJECT_NAME_LENGTH; j++)
- UsedObjectArray[i].name[j] = ScriptSpace[ip++];
- UsedObjectArray[i].index = 0;
- }
-}
-
-void CTheScripts::UpdateObjectIndices()
-{
- char name[USED_OBJECT_NAME_LENGTH];
- char error[112];
- for (int i = 1; i < NumberOfUsedObjects; i++) {
- bool found = false;
- for (int j = 0; j < MODELINFOSIZE && !found; j++) {
- CBaseModelInfo* pModel = CModelInfo::GetModelInfo(j);
- if (!pModel)
- continue;
- strcpy(name, pModel->GetName());
-#ifdef FIX_BUGS
- for (int k = 0; k < USED_OBJECT_NAME_LENGTH && name[k]; k++)
-#else
- for (int k = 0; k < USED_OBJECT_NAME_LENGTH; k++)
-#endif
- name[k] = toupper(name[k]);
- if (strcmp(name, UsedObjectArray[i].name) == 0) {
- found = true;
- UsedObjectArray[i].index = j;
- }
- }
- if (!found) {
- sprintf(error, "CTheScripts::UpdateObjectIndices - Couldn't find %s", UsedObjectArray[i].name);
- debug("%s\n", error);
- }
- }
-}
-
-void CTheScripts::ReadMultiScriptFileOffsetsFromScript()
-{
- int32 varSpace = GetSizeOfVariableSpace();
- uint32 ip = varSpace + 3;
- int32 objectSize = Read4BytesFromScript(&ip);
- ip = objectSize + 8;
- MainScriptSize = Read4BytesFromScript(&ip);
- LargestMissionScriptSize = Read4BytesFromScript(&ip);
- NumberOfMissionScripts = Read2BytesFromScript(&ip);
- NumberOfExclusiveMissionScripts = Read2BytesFromScript(&ip);
- for (int i = 0; i < NumberOfMissionScripts; i++) {
- MultiScriptArray[i] = Read4BytesFromScript(&ip);
- }
-}
void CRunningScript::Save(uint8*& buf)
{
@@ -16191,10 +4767,10 @@ void CRunningScript::Save(uint8*& buf)
#endif
for (int i = 0; i < NUM_LOCAL_VARS + NUM_TIMERS; i++)
WriteSaveBuf<int32>(buf, m_anLocalVariables[i]);
+ WriteSaveBuf<bool>(buf, m_bIsActive);
WriteSaveBuf<bool>(buf, m_bCondResult);
WriteSaveBuf<bool>(buf, m_bIsMissionScript);
WriteSaveBuf<bool>(buf, m_bSkipWakeTime);
- SkipSaveBuf(buf, 1);
WriteSaveBuf<uint32>(buf, m_nWakeTime);
WriteSaveBuf<uint16>(buf, m_nAndOrState);
WriteSaveBuf<bool>(buf, m_bNotFlag);
@@ -16226,10 +4802,10 @@ void CRunningScript::Load(uint8*& buf)
#endif
for (int i = 0; i < NUM_LOCAL_VARS + NUM_TIMERS; i++)
m_anLocalVariables[i] = ReadSaveBuf<int32>(buf);
+ m_bIsActive = ReadSaveBuf<bool>(buf);
m_bCondResult = ReadSaveBuf<bool>(buf);
m_bIsMissionScript = ReadSaveBuf<bool>(buf);
m_bSkipWakeTime = ReadSaveBuf<bool>(buf);
- SkipSaveBuf(buf, 1);
m_nWakeTime = ReadSaveBuf<uint32>(buf);
m_nAndOrState = ReadSaveBuf<uint16>(buf);
m_bNotFlag = ReadSaveBuf<bool>(buf);
@@ -16274,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) {
diff --git a/src/control/Script.h b/src/control/Script.h
index c6ece50f..983cf6e5 100644
--- a/src/control/Script.h
+++ b/src/control/Script.h
@@ -14,7 +14,15 @@ class CPlayerInfo;
class CRunningScript;
-#define KEY_LENGTH_IN_SCRIPT 8
+extern int32 ScriptParams[32];
+
+void FlushLog();
+#define script_assert(_Expression) FlushLog(); assert(_Expression);
+
+#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 252
#define SPHERE_MARKER_G 138
#define SPHERE_MARKER_B 242
@@ -22,6 +30,16 @@ class CRunningScript;
#define SPHERE_MARKER_PULSE_PERIOD 2048
#define SPHERE_MARKER_PULSE_FRACTION 0.1f
+#ifdef USE_PRECISE_MEASUREMENT_CONVERTION
+#define METERS_IN_FOOT 0.3048f
+#define FEET_IN_METER 3.28084f
+#else
+#define METERS_IN_FOOT 0.3f
+#define FEET_IN_METER 3.33f
+#endif
+
+#define KEY_LENGTH_IN_SCRIPT 8
+
struct intro_script_rectangle
{
bool m_bIsUsed;
@@ -288,6 +306,15 @@ class CTheScripts
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;
@@ -516,28 +543,7 @@ private:
float LimitAngleOnCircle(float angle) { return angle < 0.0f ? angle + 360.0f : angle; }
- bool ThisIsAValidRandomPed(uint32 pedtype, int civ, int gang, int criminal) {
- switch (pedtype) {
- case PEDTYPE_CIVMALE:
- case PEDTYPE_CIVFEMALE:
- return civ;
- case PEDTYPE_GANG1:
- case PEDTYPE_GANG2:
- case PEDTYPE_GANG3:
- 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 ThisIsAValidRandomPed(uint32 pedtype, int civ, int gang, int criminal);
bool CheckDamagedWeaponType(int32 actual, int32 type);
@@ -550,12 +556,16 @@ private:
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);
diff --git a/src/control/Script2.cpp b/src/control/Script2.cpp
new file mode 100644
index 00000000..93098dac
--- /dev/null
+++ b/src/control/Script2.cpp
@@ -0,0 +1,1558 @@
+#include "common.h"
+
+#include "Script.h"
+#include "ScriptCommands.h"
+
+#include "Camera.h"
+#include "CarCtrl.h"
+#include "CarGen.h"
+#include "CivilianPed.h"
+#include "CopPed.h"
+#include "Cranes.h"
+#include "DMAudio.h"
+#include "EmergencyPed.h"
+#include "Garages.h"
+#include "General.h"
+#include "Messages.h"
+#include "Pad.h"
+#include "PedRoutes.h"
+#include "Pools.h"
+#include "Population.h"
+#include "Radar.h"
+#include "Restart.h"
+#include "Shadows.h"
+#include "User.h"
+#include "Wanted.h"
+#include "WaterLevel.h"
+#include "Weather.h"
+#include "World.h"
+#include "Zones.h"
+
+int8 CRunningScript::ProcessCommands300To399(int32 command)
+{
+ switch (command) {
+ //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;
+ */
+ //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);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ pVehicle->m_nDoorLock = (eCarLock)ScriptParams[1];
+ return 0;
+ }
+ case COMMAND_SHAKE_CAM_WITH_POINT:
+ CollectParameters(&m_nIp, 4);
+ TheCamera.CamShake(ScriptParams[0] / 1000.0f,
+ *(float*)&ScriptParams[1],
+ *(float*)&ScriptParams[2],
+ *(float*)&ScriptParams[3]);
+ return 0;
+ */
+ case COMMAND_IS_CAR_MODEL:
+ {
+ CollectParameters(&m_nIp, 2);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ UpdateCompareFlag(pVehicle->GetModelIndex() == ScriptParams[1]);
+ return 0;
+ }
+ //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);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ float x1 = *(float*)&ScriptParams[1];
+ float y1 = *(float*)&ScriptParams[2];
+ float x2 = *(float*)&ScriptParams[3];
+ float y2 = *(float*)&ScriptParams[4];
+ UpdateCompareFlag(pVehicle->GetStatus() == STATUS_WRECKED &&
+ pVehicle->IsWithinArea(x1, y1, x2, y2));
+ if (ScriptParams[5])
+ CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, x1, y1, x2, y2, MAP_Z_LOW_LIMIT);
+ if (CTheScripts::DbgFlag)
+ CTheScripts::DrawDebugSquare(x1, y1, x2, y2);
+ return 0;
+ }
+ case COMMAND_IS_CAR_DEAD_IN_AREA_3D:
+ {
+ CollectParameters(&m_nIp, 8);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ float x1 = *(float*)&ScriptParams[1];
+ float y1 = *(float*)&ScriptParams[2];
+ float z1 = *(float*)&ScriptParams[3];
+ float x2 = *(float*)&ScriptParams[4];
+ float y2 = *(float*)&ScriptParams[5];
+ float z2 = *(float*)&ScriptParams[6];
+ UpdateCompareFlag(pVehicle->GetStatus() == STATUS_WRECKED &&
+ pVehicle->IsWithinArea(x1, y1, z1, x2, y2, z2));
+ if (ScriptParams[7])
+ CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, x1, y1, x2, y2, (z1 + z2) / 2);
+ if (CTheScripts::DbgFlag)
+ CTheScripts::DrawDebugCube(x1, y1, z1, x2, y2, z2);
+ return 0;
+ }
+ */
+ //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;
+ */
+ //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(
+ 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);
+ CCarGenerator* pCarGen = &CTheCarGenerators::CarGeneratorArray[ScriptParams[0]];
+ if (ScriptParams[1] == 0){
+ pCarGen->SwitchOff();
+ }else if (ScriptParams[1] <= 100){
+ pCarGen->SwitchOn();
+ pCarGen->SetUsesRemaining(ScriptParams[1]);
+ }else{
+ pCarGen->SwitchOn();
+ }
+ return 0;
+ }
+ /*
+ case COMMAND_ADD_PAGER_MESSAGE:
+ {
+ wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ CollectParameters(&m_nIp, 3);
+ 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++;
+ 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:
+ {
+ script_assert(CTheScripts::ScriptSpace[m_nIp] == ARGUMENT_GLOBALVAR);
+ m_nIp++;
+ CUserDisplay::OnscnTimer.ClearClock((uint16)CTheScripts::Read2BytesFromScript(&m_nIp));
+ return 0;
+ }
+ case COMMAND_DISPLAY_ONSCREEN_COUNTER:
+ {
+ script_assert(CTheScripts::ScriptSpace[m_nIp] == ARGUMENT_GLOBALVAR);
+ m_nIp++;
+ int16 counter = CTheScripts::Read2BytesFromScript(&m_nIp);
+ CollectParameters(&m_nIp, 1);
+ CUserDisplay::OnscnTimer.AddCounter(counter, ScriptParams[0], nil, 0);
+ return 0;
+ }
+ case COMMAND_CLEAR_ONSCREEN_COUNTER:
+ {
+ script_assert(CTheScripts::ScriptSpace[m_nIp] == ARGUMENT_GLOBALVAR);
+ m_nIp++;
+ CUserDisplay::OnscnTimer.ClearCounter((uint16)CTheScripts::Read2BytesFromScript(&m_nIp));
+ return 0;
+ }
+ 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, 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;
+ }
+ while (zone >= 0) {
+ CTheZones::SetZoneCarInfo(zone, ScriptParams[0], ScriptParams[1], ScriptParams[11], gangDensities);
+ zone = CTheZones::FindNextZoneByLabelAndReturnIndex(label, ZONE_INFO);
+ }
+ return 0;
+ }
+ //case COMMAND_IS_CHAR_IN_GANG_ZONE:
+ case COMMAND_IS_CHAR_IN_ZONE:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ char label[12];
+ CTheScripts::ReadTextLabelFromScript(&m_nIp, 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::GetNavigationZone(zone)));
+ return 0;
+ }
+ //case COMMAND_SET_CAR_DENSITY:
+ //case COMMAND_SET_PED_DENSITY:
+ case COMMAND_POINT_CAMERA_AT_PLAYER:
+ {
+ CollectParameters(&m_nIp, 3);
+ // ScriptParams[0] is unused.
+ TheCamera.TakeControl(nil, ScriptParams[1], ScriptParams[2], CAMCONTROL_SCRIPT);
+ return 0;
+ }
+ case COMMAND_POINT_CAMERA_AT_CAR:
+ {
+ CollectParameters(&m_nIp, 3);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ 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]);
+ 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, 12);
+ int16 zone = CTheZones::FindZoneByLabelAndReturnIndex(label, ZONE_INFO);
+ if (zone < 0) {
+ debug("Couldn't find zone - %s\n", label);
+ return 0;
+ }
+ 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);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle && pVehicle->IsCar());
+ CAutomobile* pCar = (CAutomobile*)pVehicle;
+ UpdateCompareFlag(pCar->GetAllWheelsOffGround());
+ return 0;
+ }
+ */
+ case COMMAND_SET_FIXED_CAMERA_POSITION:
+ {
+ CollectParameters(&m_nIp, 6);
+ TheCamera.SetCamPositionForFixedMode(
+ CVector(*(float*)&ScriptParams[0], *(float*)&ScriptParams[1], *(float*)&ScriptParams[2]),
+ CVector(*(float*)&ScriptParams[3], *(float*)&ScriptParams[4], *(float*)&ScriptParams[5]));
+ return 0;
+ }
+ case COMMAND_POINT_CAMERA_AT_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);
+ TheCamera.TakeControlNoEntity(pos, ScriptParams[3], CAMCONTROL_SCRIPT);
+ return 0;
+ }
+ case COMMAND_ADD_BLIP_FOR_CAR_OLD:
+ {
+ CollectParameters(&m_nIp, 3);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ CRadar::GetActualBlipArrayIndex(CollectNextParameterWithoutIncreasingPC(m_nIp));
+ ScriptParams[0] = CRadar::SetEntityBlip(BLIP_CAR, ScriptParams[0], ScriptParams[1], (eBlipDisplay)ScriptParams[2]);
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ }
+ case COMMAND_ADD_BLIP_FOR_CHAR_OLD:
+ {
+ CollectParameters(&m_nIp, 3);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ 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);
+ 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]);
+ return 0;
+ case COMMAND_CHANGE_BLIP_COLOUR:
+ CollectParameters(&m_nIp, 2);
+ CRadar::ChangeBlipColour(ScriptParams[0], ScriptParams[1]);
+ return 0;
+ case COMMAND_DIM_BLIP:
+ CollectParameters(&m_nIp, 2);
+ CRadar::ChangeBlipBrightness(ScriptParams[0], ScriptParams[1]);
+ return 0;
+ case COMMAND_ADD_BLIP_FOR_COORD_OLD:
+ {
+ CollectParameters(&m_nIp, 5);
+ 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));
+ ScriptParams[0] = CRadar::SetCoordBlip(BLIP_COORD, pos, ScriptParams[3], (eBlipDisplay)ScriptParams[4]);
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ }
+ case COMMAND_CHANGE_BLIP_SCALE:
+ CollectParameters(&m_nIp, 2);
+ CRadar::ChangeBlipScale(ScriptParams[0], ScriptParams[1]);
+ return 0;
+ case COMMAND_SET_FADING_COLOUR:
+ CollectParameters(&m_nIp, 3);
+ TheCamera.SetFadeColour(ScriptParams[0], ScriptParams[1], ScriptParams[2]);
+ return 0;
+ case COMMAND_DO_FADE:
+ CollectParameters(&m_nIp, 2);
+ TheCamera.Fade(ScriptParams[0] / 1000.0f, ScriptParams[1]);
+ return 0;
+ case COMMAND_GET_FADING_STATUS:
+ UpdateCompareFlag(TheCamera.GetFading());
+ return 0;
+ case COMMAND_ADD_HOSPITAL_RESTART:
+ {
+ CollectParameters(&m_nIp, 4);
+ CVector pos = *(CVector*)&ScriptParams[0];
+ float angle = *(float*)&ScriptParams[3];
+ if (pos.z <= MAP_Z_LOW_LIMIT)
+ pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
+ CRestart::AddHospitalRestartPoint(pos, angle);
+ return 0;
+ }
+ case COMMAND_ADD_POLICE_RESTART:
+ {
+ CollectParameters(&m_nIp, 4);
+ CVector pos = *(CVector*)&ScriptParams[0];
+ float angle = *(float*)&ScriptParams[3];
+ if (pos.z <= MAP_Z_LOW_LIMIT)
+ pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
+ CRestart::AddPoliceRestartPoint(pos, angle);
+ return 0;
+ }
+ case COMMAND_OVERRIDE_NEXT_RESTART:
+ {
+ CollectParameters(&m_nIp, 4);
+ CVector pos = *(CVector*)&ScriptParams[0];
+ float angle = *(float*)&ScriptParams[3];
+ if (pos.z <= MAP_Z_LOW_LIMIT)
+ pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
+ CRestart::OverrideNextRestart(pos, angle);
+ return 0;
+ }
+ /*
+ case COMMAND_DRAW_SHADOW:
+ {
+ CollectParameters(&m_nIp, 10);
+ CVector pos = *(CVector*)&ScriptParams[1];
+ float angle = *(float*)&ScriptParams[4];
+ float length = *(float*)&ScriptParams[5];
+ float x, y;
+ if (angle != 0.0f){
+ y = cos(angle) * length;
+ x = sin(angle) * length;
+ }else{
+ y = length;
+ x = 0.0f;
+ }
+ float frontX = -x;
+ float frontY = y;
+ float sideX = y;
+ float sideY = x;
+ 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();
+ 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;
+ }
+ case COMMAND_SET_PLAYER_HEADING:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
+ 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;
+ }
+ case COMMAND_GET_CHAR_HEADING:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ float angle = pPed->bInVehicle ? pPed->m_pMyVehicle->GetForward().Heading() : pPed->GetForward().Heading();
+ 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;
+ }
+ case COMMAND_SET_CHAR_HEADING:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ 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;
+ }
+ case COMMAND_GET_CAR_HEADING:
+ {
+ CollectParameters(&m_nIp, 1);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ float angle = pVehicle->GetForward().Heading();
+ 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;
+ }
+ case COMMAND_SET_CAR_HEADING:
+ {
+ CollectParameters(&m_nIp, 2);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ pVehicle->SetHeading(DEGTORAD(*(float*)&ScriptParams[1]));
+ return 0;
+ }
+ case COMMAND_GET_OBJECT_HEADING:
+ {
+ CollectParameters(&m_nIp, 1);
+ CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
+ script_assert(pObject);
+ float angle = pObject->GetForward().Heading();
+ 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;
+ }
+ case COMMAND_SET_OBJECT_HEADING:
+ {
+ CollectParameters(&m_nIp, 2);
+ CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
+ script_assert(pObject);
+ CWorld::Remove(pObject);
+ pObject->SetHeading(DEGTORAD(*(float*)&ScriptParams[1]));
+ pObject->GetMatrix().UpdateRW();
+ pObject->UpdateRwFrame();
+ CWorld::Add(pObject);
+ return 0;
+ }
+ /*
+ case COMMAND_IS_PLAYER_TOUCHING_OBJECT:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
+ CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[1]);
+ script_assert(pObject);
+ CPhysical* pEntityToTest = pPed->bInVehicle ? (CPhysical*)pPed->m_pMyVehicle : pPed;
+ UpdateCompareFlag(pEntityToTest->GetHasCollidedWith(pObject));
+ return 0;
+ }
+ case COMMAND_IS_CHAR_TOUCHING_OBJECT:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[1]);
+ script_assert(pObject);
+ CPhysical* pEntityToTest = pPed->bInVehicle ? (CPhysical*)pPed->m_pMyVehicle : pPed;
+ 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);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ pPed->SetAmmo((eWeaponType)ScriptParams[1], ScriptParams[2]);
+ return 0;
+ }
+ */
+ //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:
+ return 0;
+ //case COMMAND_DECLARE_BASE_BRIEF_ID_FOR_CONTACT:
+ case COMMAND_IS_PLAYER_HEALTH_GREATER:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
+ UpdateCompareFlag(pPed->m_fHealth > ScriptParams[1]);
+ return 0;
+ }
+ case COMMAND_IS_CHAR_HEALTH_GREATER:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ UpdateCompareFlag(pPed->m_fHealth > ScriptParams[1]);
+ return 0;
+ }
+ case COMMAND_IS_CAR_HEALTH_GREATER:
+ {
+ CollectParameters(&m_nIp, 2);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ UpdateCompareFlag(pVehicle->m_fHealth > ScriptParams[1]);
+ return 0;
+ }
+ case COMMAND_ADD_BLIP_FOR_CAR:
+ {
+ CollectParameters(&m_nIp, 1);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ CRadar::GetActualBlipArrayIndex(CollectNextParameterWithoutIncreasingPC(m_nIp));
+ int handle = CRadar::SetEntityBlip(BLIP_CAR, ScriptParams[0], 0, BLIP_DISPLAY_BOTH);
+ CRadar::ChangeBlipScale(handle, 3);
+ ScriptParams[0] = handle;
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ }
+ case COMMAND_ADD_BLIP_FOR_CHAR:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ CRadar::GetActualBlipArrayIndex(CollectNextParameterWithoutIncreasingPC(m_nIp));
+ int handle = CRadar::SetEntityBlip(BLIP_CHAR, ScriptParams[0], 1, BLIP_DISPLAY_BOTH);
+ CRadar::ChangeBlipScale(handle, 3);
+ ScriptParams[0] = handle;
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ }
+ case COMMAND_ADD_BLIP_FOR_OBJECT:
+ {
+ CollectParameters(&m_nIp, 1);
+ CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
+ script_assert(pObject);
+ CRadar::GetActualBlipArrayIndex(CollectNextParameterWithoutIncreasingPC(m_nIp));
+ int handle = CRadar::SetEntityBlip(BLIP_OBJECT, ScriptParams[0], 6, BLIP_DISPLAY_BOTH);
+ CRadar::ChangeBlipScale(handle, 3);
+ ScriptParams[0] = handle;
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ }
+ case COMMAND_ADD_BLIP_FOR_CONTACT_POINT:
+ {
+ CollectParameters(&m_nIp, 3);
+ 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 handle = CRadar::SetCoordBlip(BLIP_CONTACT_POINT, pos, 2, BLIP_DISPLAY_BOTH);
+ CRadar::ChangeBlipScale(handle, 3);
+ ScriptParams[0] = handle;
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ }
+ case COMMAND_ADD_BLIP_FOR_COORD:
+ {
+ CollectParameters(&m_nIp, 3);
+ 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 handle = CRadar::SetCoordBlip(BLIP_COORD, pos, 5, BLIP_DISPLAY_BOTH);
+ CRadar::ChangeBlipScale(handle, 3);
+ ScriptParams[0] = handle;
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ }
+ case COMMAND_CHANGE_BLIP_DISPLAY:
+ CollectParameters(&m_nIp, 2);
+ CRadar::ChangeBlipDisplay(ScriptParams[0], (eBlipDisplay)ScriptParams[1]);
+ return 0;
+ case COMMAND_ADD_ONE_OFF_SOUND:
+ {
+ CollectParameters(&m_nIp, 4);
+ switch (ScriptParams[3]) {
+ case SCRIPT_SOUND_PART_MISSION_COMPLETE:
+ DMAudio.PlayFrontEndSound(SOUND_PART_MISSION_COMPLETE, 0);
+ return 0;
+ case SCRIPT_SOUND_RACE_START_3:
+ DMAudio.PlayFrontEndSound(SOUND_RACE_START_3, 0);
+ return 0;
+ case SCRIPT_SOUND_RACE_START_2:
+ DMAudio.PlayFrontEndSound(SOUND_RACE_START_2, 0);
+ return 0;
+ case SCRIPT_SOUND_RACE_START_1:
+ DMAudio.PlayFrontEndSound(SOUND_RACE_START_1, 0);
+ return 0;
+ 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;
+ }
+ if (!DMAudio.IsAudioInitialised())
+ return 0;
+ cAudioScriptObject* obj = new cAudioScriptObject();
+ obj->Posn = *(CVector*)&ScriptParams[0];
+ obj->AudioId = ScriptParams[3];
+ obj->AudioEntity = AEHANDLE_NONE;
+ DMAudio.CreateOneShotScriptObject(obj);
+ return 0;
+ }
+ case COMMAND_ADD_CONTINUOUS_SOUND:
+ {
+ CollectParameters(&m_nIp, 4);
+ 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;
+ }
+ case COMMAND_REMOVE_SOUND:
+ {
+ CollectParameters(&m_nIp, 1);
+ cAudioScriptObject* obj = CPools::GetAudioScriptObjectPool()->GetAt(ScriptParams[0]);
+ if (!obj){
+ debug("REMOVE_SOUND - Sound doesn't exist\n");
+ return 0;
+ }
+ DMAudio.DestroyLoopingScriptObject(obj->AudioEntity);
+ delete obj;
+ return 0;
+ }
+ case COMMAND_IS_CAR_STUCK_ON_ROOF:
+ {
+ CollectParameters(&m_nIp, 1);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ UpdateCompareFlag(CTheScripts::UpsideDownCars.HasCarBeenUpsideDownForAWhile(ScriptParams[0]));
+ return 0;
+ }
+ default:
+ script_assert(0);
+ }
+ return -1;
+}
+
+int8 CRunningScript::ProcessCommands400To499(int32 command)
+{
+ switch (command) {
+ case COMMAND_ADD_UPSIDEDOWN_CAR_CHECK:
+ {
+ CollectParameters(&m_nIp, 1);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ CTheScripts::UpsideDownCars.AddCarToCheck(ScriptParams[0]);
+ return 0;
+ }
+ case COMMAND_REMOVE_UPSIDEDOWN_CAR_CHECK:
+ {
+ CollectParameters(&m_nIp, 1);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ CTheScripts::UpsideDownCars.RemoveCarFromCheck(ScriptParams[0]);
+ return 0;
+ }
+ case COMMAND_SET_CHAR_OBJ_WAIT_ON_FOOT:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ pPed->bScriptObjectiveCompleted = false;
+ pPed->SetObjective(OBJECTIVE_WAIT_ON_FOOT);
+ return 0;
+ }
+ case COMMAND_SET_CHAR_OBJ_FLEE_ON_FOOT_TILL_SAFE:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ pPed->bScriptObjectiveCompleted = false;
+ pPed->SetObjective(OBJECTIVE_FLEE_CHAR_ON_FOOT_TILL_SAFE);
+ return 0;
+ }
+ case COMMAND_SET_CHAR_OBJ_GUARD_SPOT:
+ {
+ CollectParameters(&m_nIp, 4);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ CVector pos = *(CVector*)&ScriptParams[1];
+ if (pos.z <= MAP_Z_LOW_LIMIT)
+ pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
+ pPed->bScriptObjectiveCompleted = false;
+ pPed->SetObjective(OBJECTIVE_GUARD_SPOT, pos);
+ return 0;
+ }
+ /*
+ case COMMAND_SET_CHAR_OBJ_GUARD_AREA:
+ {
+ CollectParameters(&m_nIp, 5);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ float infX = *(float*)&ScriptParams[1];
+ float infY = *(float*)&ScriptParams[2];
+ float supX = *(float*)&ScriptParams[3];
+ float supY = *(float*)&ScriptParams[4];
+ if (infX > supX){
+ infX = *(float*)&ScriptParams[3];
+ supX = *(float*)&ScriptParams[1];
+ }
+ if (infY > supY) {
+ infY = *(float*)&ScriptParams[4];
+ supY = *(float*)&ScriptParams[2];
+ }
+ CVector pos;
+ pos.x = (infX + supX) / 2;
+ pos.y = (infY + supY) / 2;
+ pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
+ float radius = Max(pos.x - infX, pos.y - infY);
+ pPed->bScriptObjectiveCompleted = false;
+ pPed->SetObjective(OBJECTIVE_GUARD_SPOT, pos, radius);
+ return 0;
+ }
+ case COMMAND_SET_CHAR_OBJ_WAIT_IN_CAR:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ pPed->bScriptObjectiveCompleted = false;
+ 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:
+ case COMMAND_IS_PLAYER_STOPPED_IN_AREA_ON_FOOT_2D:
+ case COMMAND_IS_PLAYER_STOPPED_IN_AREA_IN_CAR_2D:
+ case COMMAND_IS_PLAYER_IN_AREA_ON_FOOT_3D:
+ case COMMAND_IS_PLAYER_IN_AREA_IN_CAR_3D:
+ case COMMAND_IS_PLAYER_STOPPED_IN_AREA_3D:
+ case COMMAND_IS_PLAYER_STOPPED_IN_AREA_ON_FOOT_3D:
+ case COMMAND_IS_PLAYER_STOPPED_IN_AREA_IN_CAR_3D:
+ PlayerInAreaCheckCommand(command, &m_nIp);
+ return 0;
+ case COMMAND_IS_CHAR_IN_AREA_ON_FOOT_2D:
+ case COMMAND_IS_CHAR_IN_AREA_IN_CAR_2D:
+ case COMMAND_IS_CHAR_STOPPED_IN_AREA_2D:
+ case COMMAND_IS_CHAR_STOPPED_IN_AREA_ON_FOOT_2D:
+ case COMMAND_IS_CHAR_STOPPED_IN_AREA_IN_CAR_2D:
+ case COMMAND_IS_CHAR_IN_AREA_ON_FOOT_3D:
+ case COMMAND_IS_CHAR_IN_AREA_IN_CAR_3D:
+ case COMMAND_IS_CHAR_STOPPED_IN_AREA_3D:
+ case COMMAND_IS_CHAR_STOPPED_IN_AREA_ON_FOOT_3D:
+ case COMMAND_IS_CHAR_STOPPED_IN_AREA_IN_CAR_3D:
+ CharInAreaCheckCommand(command, &m_nIp);
+ return 0;
+ case COMMAND_IS_CAR_STOPPED_IN_AREA_2D:
+ case COMMAND_IS_CAR_STOPPED_IN_AREA_3D:
+ CarInAreaCheckCommand(command, &m_nIp);
+ return 0;
+ case COMMAND_LOCATE_CAR_2D:
+ case COMMAND_LOCATE_STOPPED_CAR_2D:
+ case COMMAND_LOCATE_CAR_3D:
+ case COMMAND_LOCATE_STOPPED_CAR_3D:
+ LocateCarCommand(command, &m_nIp);
+ return 0;
+ case COMMAND_GIVE_WEAPON_TO_PLAYER:
+ {
+ CollectParameters(&m_nIp, 3);
+ CPlayerPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
+ script_assert(pPed);
+ pPed->m_nSelectedWepSlot = pPed->GiveWeapon((eWeaponType)ScriptParams[1], ScriptParams[2]);
+ return 0;
+ }
+ case COMMAND_GIVE_WEAPON_TO_CHAR:
+ {
+ CollectParameters(&m_nIp, 3);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ pPed->SetCurrentWeapon(pPed->GiveWeapon((eWeaponType)ScriptParams[1], ScriptParams[2]));
+ if (pPed->bInVehicle && pPed->m_pMyVehicle)
+ pPed->RemoveWeaponModel(CWeaponInfo::GetWeaponInfo(pPed->m_weapons[pPed->m_currentWeapon].m_eWeaponType)->m_nModelId);
+ return 0;
+ }
+ //case COMMAND_GIVE_WEAPON_TO_CAR:
+ case COMMAND_SET_PLAYER_CONTROL:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPlayerInfo* pPlayer = &CWorld::Players[ScriptParams[0]];
+ if (ScriptParams[1]){
+ pPlayer->MakePlayerSafe(false);
+ if (strcmp(m_abScriptName, "serg1") == 0) // Four Iron
+ pPlayer->m_pPed->ClearFollowPath();
+ }else{
+ pPlayer->MakePlayerSafe(true);
+ }
+ return 0;
+ }
+ case COMMAND_FORCE_WEATHER:
+ CollectParameters(&m_nIp, 1);
+ CWeather::ForceWeather(ScriptParams[0]);
+ return 0;
+ case COMMAND_FORCE_WEATHER_NOW:
+ CollectParameters(&m_nIp, 1);
+ CWeather::ForceWeatherNow(ScriptParams[0]);
+ return 0;
+ case COMMAND_RELEASE_WEATHER:
+ CWeather::ReleaseWeather();
+ return 0;
+ case COMMAND_SET_CURRENT_PLAYER_WEAPON:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPlayerPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
+ for (int i = 0; i < TOTAL_WEAPON_SLOTS; i++){
+ if (pPed->m_weapons[i].m_eWeaponType == ScriptParams[1])
+ pPed->m_nSelectedWepSlot = i;
+ }
+ return 0;
+ }
+ case COMMAND_SET_CURRENT_CHAR_WEAPON:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ for (int i = 0; i < TOTAL_WEAPON_SLOTS; i++) {
+ if (pPed->m_weapons[i].m_eWeaponType == ScriptParams[1])
+ pPed->SetCurrentWeapon(i);
+ }
+ return 0;
+ }
+ //case COMMAND_SET_CURRENT_CAR_WEAPON:
+ case COMMAND_GET_OBJECT_COORDINATES:
+ {
+ CollectParameters(&m_nIp, 1);
+ CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
+ script_assert(pObject);
+ *(CVector*)&ScriptParams[0] = pObject->GetPosition();
+ StoreParameters(&m_nIp, 3);
+ return 0;
+ }
+ case COMMAND_SET_OBJECT_COORDINATES:
+ {
+ CollectParameters(&m_nIp, 4);
+ CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
+ script_assert(pObject);
+ CVector pos = *(CVector*)&ScriptParams[1];
+ if (pos.z <= MAP_Z_LOW_LIMIT)
+ pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
+ pObject->Teleport(pos);
+ CTheScripts::ClearSpaceForMissionEntity(pos, pObject);
+ return 0;
+ }
+ case COMMAND_GET_GAME_TIMER:
+ ScriptParams[0] = CTimer::GetTimeInMilliseconds();
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ case COMMAND_TURN_CHAR_TO_FACE_COORD:
+ {
+ CollectParameters(&m_nIp, 4);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ CVehicle* pVehicle;
+ CVector pos;
+ if (pPed->bInVehicle)
+ pVehicle = pPed->m_pMyVehicle;
+ else
+ pVehicle = nil;
+ if (pVehicle)
+ pos = pVehicle->GetPosition();
+ else
+ pos = pPed->GetPosition();
+ float heading = CGeneral::GetATanOfXY(pos.x - *(float*)&ScriptParams[1], pos.y - *(float*)&ScriptParams[2]);
+ heading += HALFPI;
+ if (heading > TWOPI)
+ heading -= TWOPI;
+ if (!pVehicle){
+ pPed->m_fRotationCur = heading;
+ pPed->m_fRotationDest = heading;
+ pPed->SetHeading(heading);
+ }
+ return 0;
+ }
+ case COMMAND_TURN_PLAYER_TO_FACE_COORD:
+ {
+ CollectParameters(&m_nIp, 4);
+ CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
+ script_assert(pPed);
+ CVehicle* pVehicle;
+ CVector pos;
+ if (pPed->bInVehicle)
+ pVehicle = pPed->m_pMyVehicle;
+ else
+ pVehicle = nil;
+ if (pVehicle)
+ pos = pVehicle->GetPosition();
+ else
+ pos = pPed->GetPosition();
+ float heading = CGeneral::GetATanOfXY(pos.x - *(float*)&ScriptParams[1], pos.y - *(float*)&ScriptParams[2]);
+ heading += HALFPI;
+ if (heading > TWOPI)
+ heading -= TWOPI;
+ if (!pVehicle) {
+ pPed->m_fRotationCur = heading;
+ pPed->m_fRotationDest = heading;
+ pPed->SetHeading(heading);
+ }
+ return 0;
+ }
+ case COMMAND_STORE_WANTED_LEVEL:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPlayerPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
+ script_assert(pPed);
+ ScriptParams[0] = pPed->m_pWanted->m_nWantedLevel;
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ }
+ case COMMAND_IS_CAR_STOPPED:
+ {
+ CollectParameters(&m_nIp, 1);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ UpdateCompareFlag(CTheScripts::IsVehicleStopped(pVehicle));
+ return 0;
+ }
+ case COMMAND_MARK_CHAR_AS_NO_LONGER_NEEDED:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ CTheScripts::CleanUpThisPed(pPed);
+ if (m_bIsMissionScript)
+ CTheScripts::MissionCleanup.RemoveEntityFromList(ScriptParams[0], CLEANUP_CHAR);
+ return 0;
+ }
+ case COMMAND_MARK_CAR_AS_NO_LONGER_NEEDED:
+ {
+ CollectParameters(&m_nIp, 1);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ CTheScripts::CleanUpThisVehicle(pVehicle);
+ if (m_bIsMissionScript)
+ CTheScripts::MissionCleanup.RemoveEntityFromList(ScriptParams[0], CLEANUP_CAR);
+ return 0;
+ }
+ case COMMAND_MARK_OBJECT_AS_NO_LONGER_NEEDED:
+ {
+ CollectParameters(&m_nIp, 1);
+ CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
+ CTheScripts::CleanUpThisObject(pObject);
+ if (m_bIsMissionScript)
+ CTheScripts::MissionCleanup.RemoveEntityFromList(ScriptParams[0], CLEANUP_OBJECT);
+ return 0;
+ }
+ case COMMAND_DONT_REMOVE_CHAR:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ CTheScripts::MissionCleanup.RemoveEntityFromList(ScriptParams[0], CLEANUP_CHAR);
+ return 0;
+ }
+ case COMMAND_DONT_REMOVE_CAR:
+ {
+ CollectParameters(&m_nIp, 1);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ CTheScripts::MissionCleanup.RemoveEntityFromList(ScriptParams[0], CLEANUP_CAR);
+ return 0;
+ }
+ case COMMAND_DONT_REMOVE_OBJECT:
+ {
+ CollectParameters(&m_nIp, 1);
+ CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
+ script_assert(pObject);
+ CTheScripts::MissionCleanup.RemoveEntityFromList(ScriptParams[0], CLEANUP_OBJECT);
+ return 0;
+ }
+ case COMMAND_CREATE_CHAR_AS_PASSENGER:
+ {
+ CollectParameters(&m_nIp, 4);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ switch (ScriptParams[2]) {
+ case MI_COP:
+ if (ScriptParams[1] == PEDTYPE_COP)
+ ScriptParams[2] = COP_STREET;
+ break;
+ case MI_SWAT:
+ if (ScriptParams[1] == PEDTYPE_COP)
+ ScriptParams[2] = COP_SWAT;
+ break;
+ case MI_FBI:
+ if (ScriptParams[1] == PEDTYPE_COP)
+ ScriptParams[2] = COP_FBI;
+ break;
+ case MI_ARMY:
+ if (ScriptParams[1] == PEDTYPE_COP)
+ ScriptParams[2] = COP_ARMY;
+ break;
+ case MI_MEDIC:
+ if (ScriptParams[1] == PEDTYPE_EMERGENCY)
+ ScriptParams[2] = PEDTYPE_EMERGENCY;
+ break;
+ case MI_FIREMAN:
+ if (ScriptParams[1] == PEDTYPE_FIREMAN)
+ ScriptParams[2] = PEDTYPE_FIREMAN;
+ break;
+ default:
+ break;
+ }
+ CPed* pPed;
+ if (ScriptParams[1] == PEDTYPE_COP)
+ pPed = new CCopPed((eCopType)ScriptParams[2]);
+ else if (ScriptParams[1] == PEDTYPE_EMERGENCY || ScriptParams[1] == PEDTYPE_FIREMAN)
+ pPed = new CEmergencyPed(ScriptParams[2]);
+ else
+ pPed = new CCivilianPed((ePedType)ScriptParams[1], ScriptParams[2]);
+ 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++;
+ if (ScriptParams[3] >= 0)
+ pVehicle->AddPassenger(pPed, ScriptParams[3]);
+ else
+ pVehicle->AddPassenger(pPed);
+ pPed->m_pMyVehicle = pVehicle;
+ pPed->m_pMyVehicle->RegisterReference((CEntity**)&pPed->m_pMyVehicle);
+ pPed->bInVehicle = true;
+ pVehicle->SetStatus(STATUS_PHYSICS);
+ pPed->SetPedState(PED_DRIVING);
+ pPed->bUsesCollision = false;
+ pPed->AddInCarAnims(pVehicle, false);
+ pPed->m_nZoneLevel = CTheZones::GetLevelFromPosition(&pPed->GetPosition());
+ CWorld::Add(pPed);
+ ScriptParams[0] = CPools::GetPedPool()->GetIndex(pPed);
+ StoreParameters(&m_nIp, 1);
+ if (m_bIsMissionScript)
+ CTheScripts::MissionCleanup.AddEntityToList(ScriptParams[0], CLEANUP_CHAR);
+ return 0;
+ }
+ case COMMAND_SET_CHAR_OBJ_KILL_CHAR_ON_FOOT:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ CPed* pTarget = CPools::GetPedPool()->GetAt(ScriptParams[1]);
+ pPed->bScriptObjectiveCompleted = false;
+ pPed->SetObjective(OBJECTIVE_KILL_CHAR_ON_FOOT, pTarget);
+ return 0;
+ }
+ case COMMAND_SET_CHAR_OBJ_KILL_PLAYER_ON_FOOT:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ CPed* pTarget = CWorld::Players[ScriptParams[1]].m_pPed;
+ pPed->bScriptObjectiveCompleted = false;
+ pPed->SetObjective(OBJECTIVE_KILL_CHAR_ON_FOOT, pTarget);
+ return 0;
+ }
+ case COMMAND_SET_CHAR_OBJ_KILL_CHAR_ANY_MEANS:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ CPed* pTarget = CPools::GetPedPool()->GetAt(ScriptParams[1]);
+ pPed->bScriptObjectiveCompleted = false;
+ pPed->SetObjective(OBJECTIVE_KILL_CHAR_ANY_MEANS, pTarget);
+ return 0;
+ }
+ case COMMAND_SET_CHAR_OBJ_KILL_PLAYER_ANY_MEANS:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ CPed* pTarget = CWorld::Players[ScriptParams[1]].m_pPed;
+ pPed->bScriptObjectiveCompleted = false;
+ 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);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ CPed* pTarget = CPools::GetPedPool()->GetAt(ScriptParams[1]);
+ pPed->bScriptObjectiveCompleted = false;
+ 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);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ CPed* pTarget = CWorld::Players[ScriptParams[1]].m_pPed;
+ pPed->bScriptObjectiveCompleted = false;
+ pPed->SetObjective(OBJECTIVE_FLEE_CHAR_ON_FOOT_TILL_SAFE, pTarget);
+ return 0;
+ }
+ case COMMAND_SET_CHAR_OBJ_FLEE_CHAR_ON_FOOT_ALWAYS:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ CPed* pTarget = CPools::GetPedPool()->GetAt(ScriptParams[1]);
+ pPed->bScriptObjectiveCompleted = false;
+ pPed->SetObjective(OBJECTIVE_FLEE_CHAR_ON_FOOT_ALWAYS, pTarget);
+ return 0;
+ }
+ case COMMAND_SET_CHAR_OBJ_FLEE_PLAYER_ON_FOOT_ALWAYS:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ CPed* pTarget = CWorld::Players[ScriptParams[1]].m_pPed;
+ pPed->bScriptObjectiveCompleted = false;
+ pPed->SetObjective(OBJECTIVE_FLEE_CHAR_ON_FOOT_ALWAYS, pTarget);
+ return 0;
+ }
+ case COMMAND_SET_CHAR_OBJ_GOTO_CHAR_ON_FOOT:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ CPed* pTarget = CPools::GetPedPool()->GetAt(ScriptParams[1]);
+ pPed->bScriptObjectiveCompleted = false;
+ pPed->SetObjective(OBJECTIVE_GOTO_CHAR_ON_FOOT, pTarget);
+ return 0;
+ }
+ case COMMAND_SET_CHAR_OBJ_GOTO_PLAYER_ON_FOOT:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ CPed* pTarget = CWorld::Players[ScriptParams[1]].m_pPed;
+ pPed->bScriptObjectiveCompleted = false;
+ pPed->SetObjective(OBJECTIVE_GOTO_CHAR_ON_FOOT, pTarget);
+ return 0;
+ }
+ case COMMAND_SET_CHAR_OBJ_LEAVE_CAR:
+ {
+ 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_LEAVE_CAR, pVehicle);
+ return 0;
+ }
+ case COMMAND_SET_CHAR_OBJ_ENTER_CAR_AS_PASSENGER:
+ {
+ 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_ENTER_CAR_AS_PASSENGER, pVehicle);
+ return 0;
+ }
+ case COMMAND_SET_CHAR_OBJ_ENTER_CAR_AS_DRIVER:
+ {
+ 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_ENTER_CAR_AS_DRIVER, pVehicle);
+ return 0;
+ }
+ //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);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[1]);
+ pPed->bScriptObjectiveCompleted = false;
+ pPed->SetObjective(OBJECTIVE_DESTROY_CAR, pVehicle);
+ return 0;
+ }
+ /*
+ case COMMAND_SET_CHAR_OBJ_GOTO_AREA_ON_FOOT:
+ {
+ CollectParameters(&m_nIp, 5);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ float infX = *(float*)&ScriptParams[1];
+ float infY = *(float*)&ScriptParams[2];
+ float supX = *(float*)&ScriptParams[3];
+ float supY = *(float*)&ScriptParams[4];
+ if (infX > supX) {
+ infX = *(float*)&ScriptParams[3];
+ supX = *(float*)&ScriptParams[1];
+ }
+ if (infY > supY) {
+ infY = *(float*)&ScriptParams[4];
+ supY = *(float*)&ScriptParams[2];
+ }
+ CVector pos;
+ pos.x = (infX + supX) / 2;
+ pos.y = (infY + supY) / 2;
+ pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
+ float radius = Max(pos.x - infX, pos.y - infY);
+ pPed->bScriptObjectiveCompleted = false;
+ pPed->SetObjective(OBJECTIVE_GOTO_AREA_ON_FOOT, pos, radius);
+ return 0;
+ }
+ */
+ //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);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ CPed* pTarget = CPools::GetPedPool()->GetAt(ScriptParams[1]);
+ pPed->SetObjective(OBJECTIVE_SET_LEADER, pTarget);
+ return 0;
+ }
+ case COMMAND_SET_PLAYER_AS_LEADER:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ CPed* pTarget = CWorld::Players[ScriptParams[1]].m_pPed;
+ pPed->SetObjective(OBJECTIVE_SET_LEADER, pTarget);
+ return 0;
+ }
+ case COMMAND_LEAVE_GROUP:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ pPed->ClearLeader();
+ return 0;
+ }
+ case COMMAND_SET_CHAR_OBJ_FOLLOW_ROUTE:
+ {
+ CollectParameters(&m_nIp, 3);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ pPed->bScriptObjectiveCompleted = false;
+ pPed->SetObjective(OBJECTIVE_FOLLOW_ROUTE, ScriptParams[1], ScriptParams[2]);
+ return 0;
+ }
+ case COMMAND_ADD_ROUTE_POINT:
+ {
+ CollectParameters(&m_nIp, 4);
+ CRouteNode::AddRoutePoint(ScriptParams[0], *(CVector*)&ScriptParams[1]);
+ return 0;
+ }
+ case COMMAND_PRINT_WITH_NUMBER_BIG:
+ {
+ wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ CollectParameters(&m_nIp, 3);
+ CMessages::AddBigMessageWithNumber(text, ScriptParams[1], ScriptParams[2] - 1, ScriptParams[0], -1, -1, -1, -1, -1);
+ return 0;
+ }
+ case COMMAND_PRINT_WITH_NUMBER:
+ {
+ wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ CollectParameters(&m_nIp, 3);
+ CMessages::AddMessageWithNumber(text, ScriptParams[1], ScriptParams[2], ScriptParams[0], -1, -1, -1, -1, -1);
+ return 0;
+ }
+ case COMMAND_PRINT_WITH_NUMBER_NOW:
+ {
+ wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ CollectParameters(&m_nIp, 3);
+ CMessages::AddMessageJumpQWithNumber(text, ScriptParams[1], ScriptParams[2], ScriptParams[0], -1, -1, -1, -1, -1);
+ return 0;
+ }
+ //case COMMAND_PRINT_WITH_NUMBER_SOON:
+ case COMMAND_SWITCH_ROADS_ON:
+ {
+ CollectParameters(&m_nIp, 6);
+ 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];
+ }
+ ThePaths.SwitchRoadsOffInArea(infX, supX, infY, supY, infZ, supZ, false);
+ return 0;
+ }
+ case COMMAND_SWITCH_ROADS_OFF:
+ {
+ CollectParameters(&m_nIp, 6);
+ 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];
+ }
+ ThePaths.SwitchRoadsOffInArea(infX, supX, infY, supY, infZ, supZ, true);
+ return 0;
+ }
+ case COMMAND_GET_NUMBER_OF_PASSENGERS:
+ {
+ CollectParameters(&m_nIp, 1);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ ScriptParams[0] = pVehicle->m_nNumPassengers;
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ }
+ case COMMAND_GET_MAXIMUM_NUMBER_OF_PASSENGERS:
+ {
+ CollectParameters(&m_nIp, 1);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ ScriptParams[0] = pVehicle->m_nNumMaxPassengers;
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ }
+ case COMMAND_SET_CAR_DENSITY_MULTIPLIER:
+ {
+ CollectParameters(&m_nIp, 1);
+ CCarCtrl::CarDensityMultiplier = *(float*)&ScriptParams[0];
+ return 0;
+ }
+ case COMMAND_SET_CAR_HEAVY:
+ {
+ CollectParameters(&m_nIp, 2);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ 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:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ pPed->m_fearFlags = 0;
+ return 0;
+ }
+ /*
+ case COMMAND_ACTIVATE_CRANE:
+ {
+ CollectParameters(&m_nIp, 10);
+ float infX = *(float*)&ScriptParams[2];
+ float infY = *(float*)&ScriptParams[3];
+ float supX = *(float*)&ScriptParams[4];
+ float supY = *(float*)&ScriptParams[5];
+ if (infX > supX) {
+ infX = *(float*)&ScriptParams[4];
+ supX = *(float*)&ScriptParams[2];
+ }
+ if (infY > supY) {
+ infY = *(float*)&ScriptParams[5];
+ supY = *(float*)&ScriptParams[3];
+ }
+ CCranes::ActivateCrane(infX, supX, infY, supY,
+ *(float*)&ScriptParams[6], *(float*)&ScriptParams[7], *(float*)&ScriptParams[8],
+ DEGTORAD(*(float*)&ScriptParams[9]), false, false,
+ *(float*)&ScriptParams[0], *(float*)&ScriptParams[1]);
+ return 0;
+ }
+ case COMMAND_DEACTIVATE_CRANE:
+ {
+ CollectParameters(&m_nIp, 2);
+ 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;
+ }
+ //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);
+ UpdateCompareFlag(pVehicle->m_nCollisionRecords == 0);
+ return 0;
+ }
+ default:
+ script_assert(0);
+ }
+ return -1;
+}
diff --git a/src/control/Script3.cpp b/src/control/Script3.cpp
new file mode 100644
index 00000000..2fe8b41f
--- /dev/null
+++ b/src/control/Script3.cpp
@@ -0,0 +1,2134 @@
+#include "common.h"
+
+#include "Script.h"
+#include "ScriptCommands.h"
+
+#include "Boat.h"
+#include "CarCtrl.h"
+#include "Clock.h"
+#include "Coronas.h"
+#include "Cranes.h"
+#include "CutsceneMgr.h"
+#include "Darkel.h"
+#include "Explosion.h"
+#include "Fire.h"
+#include "General.h"
+#include "Garages.h"
+#include "Heli.h"
+#include "Messages.h"
+#include "Pad.h"
+#include "ParticleObject.h"
+#include "Phones.h"
+#include "Pickups.h"
+#include "PointLights.h"
+#include "Population.h"
+#include "Pools.h"
+#include "ProjectileInfo.h"
+#include "Radar.h"
+#include "Restart.h"
+#include "Stats.h"
+#include "Streaming.h"
+#include "User.h"
+#include "WaterLevel.h"
+#include "Weather.h"
+#include "Zones.h"
+#include "GameLogic.h"
+#include "Bike.h"
+
+int8 CRunningScript::ProcessCommands500To599(int32 command)
+{
+ switch (command) {
+ case COMMAND_IS_CAR_UPSIDEDOWN:
+ {
+ CollectParameters(&m_nIp, 1);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ UpdateCompareFlag(pVehicle->GetUp().z <= -0.97f);
+ return 0;
+ }
+ case COMMAND_GET_PLAYER_CHAR:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPlayerPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
+ script_assert(pPed);
+ ScriptParams[0] = CPools::GetPedPool()->GetIndex(pPed);
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ }
+ case COMMAND_CANCEL_OVERRIDE_RESTART:
+ CRestart::CancelOverrideRestart();
+ return 0;
+ case COMMAND_SET_POLICE_IGNORE_PLAYER:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPlayerPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
+ script_assert(pPed);
+ if (ScriptParams[1]) {
+ pPed->m_pWanted->m_bIgnoredByCops = true;
+ CWorld::StopAllLawEnforcersInTheirTracks();
+ }
+ else {
+ pPed->m_pWanted->m_bIgnoredByCops = false;
+ }
+ return 0;
+ }
+ /*
+ case COMMAND_ADD_PAGER_MESSAGE_WITH_NUMBER:
+ {
+ wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ CollectParameters(&m_nIp, 4);
+ CUserDisplay::Pager.AddMessageWithNumber(text, ScriptParams[0], -1, -1, -1, -1, -1,
+ ScriptParams[1], ScriptParams[2], ScriptParams[3]);
+ return 0;
+ }
+ */
+ case COMMAND_START_KILL_FRENZY:
+ {
+ wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ CollectParameters(&m_nIp, 8);
+ CDarkel::StartFrenzy((eWeaponType)ScriptParams[0], ScriptParams[1], ScriptParams[2],
+ ScriptParams[3], text, ScriptParams[4], ScriptParams[5],
+ ScriptParams[6], ScriptParams[7] != 0, false);
+ return 0;
+ }
+ case COMMAND_READ_KILL_FRENZY_STATUS:
+ {
+ ScriptParams[0] = CDarkel::ReadStatus();
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ }
+ case COMMAND_SQRT:
+ {
+ CollectParameters(&m_nIp, 1);
+ *(float*)&ScriptParams[0] = Sqrt(*(float*)&ScriptParams[0]);
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ }
+ case COMMAND_LOCATE_PLAYER_ANY_MEANS_CAR_2D:
+ case COMMAND_LOCATE_PLAYER_ON_FOOT_CAR_2D:
+ case COMMAND_LOCATE_PLAYER_IN_CAR_CAR_2D:
+ case COMMAND_LOCATE_PLAYER_ANY_MEANS_CAR_3D:
+ case COMMAND_LOCATE_PLAYER_ON_FOOT_CAR_3D:
+ case COMMAND_LOCATE_PLAYER_IN_CAR_CAR_3D:
+ LocatePlayerCarCommand(command, &m_nIp);
+ return 0;
+ case COMMAND_LOCATE_CHAR_ANY_MEANS_CAR_2D:
+ case COMMAND_LOCATE_CHAR_ON_FOOT_CAR_2D:
+ case COMMAND_LOCATE_CHAR_IN_CAR_CAR_2D:
+ case COMMAND_LOCATE_CHAR_ANY_MEANS_CAR_3D:
+ case COMMAND_LOCATE_CHAR_ON_FOOT_CAR_3D:
+ case COMMAND_LOCATE_CHAR_IN_CAR_CAR_3D:
+ LocateCharCarCommand(command, &m_nIp);
+ return 0;
+ case COMMAND_GENERATE_RANDOM_FLOAT_IN_RANGE:
+ CollectParameters(&m_nIp, 2);
+ *(float*)&ScriptParams[0] = CGeneral::GetRandomNumberInRange(*(float*)&ScriptParams[0], *(float*)&ScriptParams[1]);
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ case COMMAND_GENERATE_RANDOM_INT_IN_RANGE:
+ CollectParameters(&m_nIp, 2);
+ ScriptParams[0] = CGeneral::GetRandomNumberInRange(ScriptParams[0], ScriptParams[1]);
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ case COMMAND_LOCK_CAR_DOORS:
+ {
+ CollectParameters(&m_nIp, 2);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ pVehicle->m_nDoorLock = (eCarLock)ScriptParams[1];
+ return 0;
+ }
+ case COMMAND_EXPLODE_CAR:
+ {
+ CollectParameters(&m_nIp, 1);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ pVehicle->BlowUpCar(nil);
+ return 0;
+ }
+ case COMMAND_ADD_EXPLOSION:
+ CollectParameters(&m_nIp, 4);
+ CExplosion::AddExplosion(nil, nil, (eExplosionType)ScriptParams[3], *(CVector*)&ScriptParams[0], 0, true);
+ return 0;
+
+ case COMMAND_IS_CAR_UPRIGHT:
+ {
+ CollectParameters(&m_nIp, 1);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ UpdateCompareFlag(pVehicle->GetUp().z >= 0.0f);
+ return 0;
+ }
+ case COMMAND_TURN_CHAR_TO_FACE_CHAR:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pSourcePed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ CPed* pTargetPed = CPools::GetPedPool()->GetAt(ScriptParams[1]);
+ CVehicle* pVehicle = pSourcePed->bInVehicle ? pSourcePed->m_pMyVehicle : nil;
+ CVector2D sourcePos = pSourcePed->bInVehicle ? pVehicle->GetPosition() : pSourcePed->GetPosition();
+ CVector2D targetPos = pTargetPed->bInVehicle ? pTargetPed->m_pMyVehicle->GetPosition() : pTargetPed->GetPosition();
+ float angle = CGeneral::GetATanOfXY(sourcePos.x - targetPos.x, sourcePos.y - targetPos.y) + HALFPI;
+ if (angle > TWOPI)
+ angle -= TWOPI;
+ if (!pVehicle) {
+ pSourcePed->m_fRotationCur = angle;
+ pSourcePed->m_fRotationDest = angle;
+ pSourcePed->SetHeading(angle);
+ }
+ return 0;
+ }
+ case COMMAND_TURN_CHAR_TO_FACE_PLAYER:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pSourcePed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ CPed* pTargetPed = CWorld::Players[ScriptParams[1]].m_pPed;
+ CVehicle* pVehicle = pSourcePed->bInVehicle ? pSourcePed->m_pMyVehicle : nil;
+ CVector2D sourcePos = pSourcePed->bInVehicle ? pVehicle->GetPosition() : pSourcePed->GetPosition();
+ CVector2D targetPos = pTargetPed->bInVehicle ? pTargetPed->m_pMyVehicle->GetPosition() : pTargetPed->GetPosition();
+ float angle = CGeneral::GetATanOfXY(sourcePos.x - targetPos.x, sourcePos.y - targetPos.y) + HALFPI;
+ if (angle > TWOPI)
+ angle -= TWOPI;
+ if (!pVehicle) {
+ pSourcePed->m_fRotationCur = angle;
+ pSourcePed->m_fRotationDest = angle;
+ pSourcePed->SetHeading(angle);
+ }
+ return 0;
+ }
+ case COMMAND_TURN_PLAYER_TO_FACE_CHAR:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pSourcePed = CWorld::Players[ScriptParams[0]].m_pPed;
+ CPed* pTargetPed = CPools::GetPedPool()->GetAt(ScriptParams[1]);
+ CVehicle* pVehicle = pSourcePed->bInVehicle ? pSourcePed->m_pMyVehicle : nil;
+ CVector2D sourcePos = pSourcePed->bInVehicle ? pVehicle->GetPosition() : pSourcePed->GetPosition();
+ CVector2D targetPos = pTargetPed->bInVehicle ? pTargetPed->m_pMyVehicle->GetPosition() : pTargetPed->GetPosition();
+ float angle = CGeneral::GetATanOfXY(sourcePos.x - targetPos.x, sourcePos.y - targetPos.y) + HALFPI;
+ if (angle > TWOPI)
+ angle -= TWOPI;
+ if (!pVehicle) {
+ pSourcePed->m_fRotationCur = angle;
+ pSourcePed->m_fRotationDest = angle;
+ pSourcePed->SetHeading(angle);
+ }
+ return 0;
+ }
+ case COMMAND_SET_CHAR_OBJ_GOTO_COORD_ON_FOOT:
+ {
+ CollectParameters(&m_nIp, 3);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ CVector target;
+ target.x = *(float*)&ScriptParams[1];
+ target.y = *(float*)&ScriptParams[2];
+ target.z = CWorld::FindGroundZForCoord(target.x, target.y);
+ pPed->bScriptObjectiveCompleted = false;
+ pPed->SetObjective(OBJECTIVE_GOTO_AREA_ON_FOOT, target);
+ return 0;
+ }
+ //case COMMAND_SET_CHAR_OBJ_GOTO_COORD_IN_CAR:
+ case COMMAND_CREATE_PICKUP:
+ {
+ CollectParameters(&m_nIp, 5);
+ int16 model = ScriptParams[0];
+ if (model < 0)
+ model = CTheScripts::UsedObjectArray[-model].index;
+ CVector pos = *(CVector*)&ScriptParams[2];
+ 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, model, ScriptParams[1], 0);
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ }
+ case COMMAND_HAS_PICKUP_BEEN_COLLECTED:
+ CollectParameters(&m_nIp, 1);
+ UpdateCompareFlag(CPickups::IsPickUpPickedUp(ScriptParams[0]) != 0);
+ return 0;
+ case COMMAND_REMOVE_PICKUP:
+ CollectParameters(&m_nIp, 1);
+ CPickups::RemovePickUp(ScriptParams[0]);
+ return 0;
+ case COMMAND_SET_TAXI_LIGHTS:
+ {
+ CollectParameters(&m_nIp, 2);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ script_assert(pVehicle->m_vehType == VEHICLE_TYPE_CAR);
+ ((CAutomobile*)pVehicle)->SetTaxiLight(ScriptParams[1] != 0);
+ return 0;
+ }
+ case COMMAND_PRINT_BIG_Q:
+ {
+ wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ CollectParameters(&m_nIp, 2);
+ CMessages::AddBigMessageQ(text, ScriptParams[0], ScriptParams[1] - 1);
+ return 0;
+ }
+ /*
+ case COMMAND_PRINT_WITH_NUMBER_BIG_Q:
+ {
+ wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ CollectParameters(&m_nIp, 3);
+ CMessages::AddBigMessageWithNumberQ(text, ScriptParams[1], ScriptParams[2] - 1,
+ ScriptParams[0], -1, -1, -1, -1, -1);
+ return 0;
+ }
+ */
+ case COMMAND_SET_GARAGE:
+ {
+ CollectParameters(&m_nIp, 9);
+ float infX = *(float*)&ScriptParams[0];
+ float infY = *(float*)&ScriptParams[1];
+ float infZ = *(float*)&ScriptParams[2];
+ 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, 10);
+ float infX = *(float*)&ScriptParams[0];
+ float infY = *(float*)&ScriptParams[1];
+ float infZ = *(float*)&ScriptParams[2];
+ 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);
+ CVehicle* pTarget;
+ if (ScriptParams[1] >= 0) {
+ pTarget = CPools::GetVehiclePool()->GetAt(ScriptParams[1]);
+ script_assert(pTarget);
+ }
+ else {
+ pTarget = nil;
+ }
+ CGarages::SetTargetCarForMissonGarage(ScriptParams[0], pTarget);
+ return 0;
+ }
+ case COMMAND_IS_CAR_IN_MISSION_GARAGE:
+ CollectParameters(&m_nIp, 1);
+ UpdateCompareFlag(CGarages::HasCarBeenDroppedOffYet(ScriptParams[0]));
+ return 0;
+ case COMMAND_SET_FREE_BOMBS:
+ CollectParameters(&m_nIp, 1);
+ CGarages::SetFreeBombs(ScriptParams[0] != 0);
+ return 0;
+#ifdef GTA_PS2
+ case COMMAND_SET_POWERPOINT:
+ {
+ CollectParameters(&m_nIp, 7);
+ float f1 = *(float*)&ScriptParams[0];
+ float f2 = *(float*)&ScriptParams[1];
+ float f3 = *(float*)&ScriptParams[2];
+ float f4 = *(float*)&ScriptParams[3];
+ float f5 = *(float*)&ScriptParams[4];
+ float f6 = *(float*)&ScriptParams[5];
+ float temp;
+
+ if (f1 > f4) {
+ temp = f1;
+ f1 = f4;
+ f4 = temp;
+ }
+
+ if (f2 > f5) {
+ temp = f2;
+ f2 = f5;
+ f5 = temp;
+ }
+
+ if (f3 > f6) {
+ temp = f3;
+ f3 = f6;
+ f6 = temp;
+ }
+
+ CPowerPoints::GenerateNewOne(f1, f2, f3, f4, f5, f6, *(uint8*)&ScriptParams[6]);
+
+ return 0;
+ }
+#endif // GTA_PS2
+ /*
+ case COMMAND_SET_ALL_TAXI_LIGHTS:
+ CollectParameters(&m_nIp, 1);
+ CAutomobile::SetAllTaxiLights(ScriptParams[0] != 0);
+ return 0;
+ case COMMAND_IS_CAR_ARMED_WITH_ANY_BOMB:
+ {
+ CollectParameters(&m_nIp, 1);
+ CAutomobile* pCar = (CAutomobile*)CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pCar);
+ script_assert(pCar->m_vehType == VEHICLE_TYPE_CAR);
+ 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);
+ return 0;
+ case COMMAND_SET_PLAYER_HEALTH:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPlayerPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
+ script_assert(pPed);
+ pPed->m_fHealth = Min(ScriptParams[1], CWorld::Players[ScriptParams[0]].m_nMaxHealth);
+ return 0;
+ }
+ case COMMAND_SET_CHAR_HEALTH:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ if (ScriptParams[1]) {
+ pPed->m_fHealth = ScriptParams[1];
+ }
+ else if (pPed->bInVehicle) {
+ pPed->SetDead();
+ if (!pPed->IsPlayer())
+ pPed->FlagToDestroyWhenNextProcessed();
+ }
+ else {
+ pPed->SetDie();
+ }
+ return 0;
+ }
+ case COMMAND_SET_CAR_HEALTH:
+ {
+ CollectParameters(&m_nIp, 2);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ pVehicle->m_fHealth = ScriptParams[1];
+ return 0;
+ }
+ case COMMAND_GET_PLAYER_HEALTH:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
+ script_assert(pPed);
+ ScriptParams[0] = pPed->m_fHealth;
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ }
+ case COMMAND_GET_CHAR_HEALTH:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ ScriptParams[0] = pPed->m_fHealth;
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ }
+ case COMMAND_GET_CAR_HEALTH:
+ {
+ CollectParameters(&m_nIp, 1);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ 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]);
+ return 0;
+ }
+ */
+ case COMMAND_CHANGE_CAR_COLOUR:
+ {
+ CollectParameters(&m_nIp, 3);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ if (ScriptParams[1] >= 256 || ScriptParams[2] >= 256)
+ debug("CHANGE_CAR_COLOUR - Colours must be less than %d", 256);
+ pVehicle->m_currentColour1 = ScriptParams[1];
+ pVehicle->m_currentColour2 = ScriptParams[2];
+ return 0;
+ }
+ case COMMAND_SWITCH_PED_ROADS_ON:
+ {
+ CollectParameters(&m_nIp, 6);
+ 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];
+ }
+ ThePaths.SwitchPedRoadsOffInArea(infX, supX, infY, supY, infZ, supZ, false);
+ return 0;
+ }
+ case COMMAND_SWITCH_PED_ROADS_OFF:
+ {
+ CollectParameters(&m_nIp, 6);
+ 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];
+ }
+ ThePaths.SwitchPedRoadsOffInArea(infX, supX, infY, supY, infZ, supZ, true);
+ return 0;
+ }
+ case COMMAND_CHAR_LOOK_AT_CHAR_ALWAYS:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pSourcePed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pSourcePed);
+ CPed* pTargetPed = CPools::GetPedPool()->GetAt(ScriptParams[1]);
+ script_assert(pTargetPed);
+ pSourcePed->SetLookFlag(pTargetPed, true);
+ pSourcePed->SetLookTimer(60000);
+ return 0;
+ }
+ case COMMAND_CHAR_LOOK_AT_PLAYER_ALWAYS:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pSourcePed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pSourcePed);
+ CPed* pTargetPed = CWorld::Players[ScriptParams[1]].m_pPed;
+ script_assert(pTargetPed);
+ pSourcePed->SetLookFlag(pTargetPed, true);
+ pSourcePed->SetLookTimer(60000);
+ return 0;
+ }
+ case COMMAND_PLAYER_LOOK_AT_CHAR_ALWAYS:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pSourcePed = CWorld::Players[ScriptParams[0]].m_pPed;
+ script_assert(pSourcePed);
+ CPed* pTargetPed = CPools::GetPedPool()->GetAt(ScriptParams[1]);
+ script_assert(pTargetPed);
+ pSourcePed->SetLookFlag(pTargetPed, true);
+ pSourcePed->SetLookTimer(60000);
+ return 0;
+ }
+ case COMMAND_STOP_CHAR_LOOKING:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPed* pSourcePed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pSourcePed);
+ pSourcePed->ClearLookFlag();
+ pSourcePed->bKeepTryingToLook = false;
+ if (pSourcePed->GetPedState() == PED_LOOK_HEADING || pSourcePed->GetPedState() == PED_LOOK_ENTITY)
+ pSourcePed->RestorePreviousState();
+ return 0;
+ }
+ case COMMAND_STOP_PLAYER_LOOKING:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPed* pSourcePed = CWorld::Players[ScriptParams[0]].m_pPed;
+ script_assert(pSourcePed);
+ pSourcePed->ClearLookFlag();
+ pSourcePed->bKeepTryingToLook = false;
+ if (pSourcePed->GetPedState() == PED_LOOK_HEADING || pSourcePed->GetPedState() == PED_LOOK_ENTITY)
+ 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:
+ 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]);
+ return 0;
+ case COMMAND_SET_GANG_WEAPONS:
+ 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);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ float infX = *(float*)&ScriptParams[1];
+ float infY = *(float*)&ScriptParams[2];
+ float supX = *(float*)&ScriptParams[3];
+ float supY = *(float*)&ScriptParams[4];
+ if (infX > supX) {
+ infX = *(float*)&ScriptParams[3];
+ supX = *(float*)&ScriptParams[1];
+ }
+ if (infY > supY) {
+ infY = *(float*)&ScriptParams[4];
+ supY = *(float*)&ScriptParams[2];
+ }
+ CVector pos;
+ pos.x = (infX + supX) / 2;
+ pos.y = (infY + supY) / 2;
+ pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
+ float radius = Max(pos.x - infX, pos.y - infY);
+ pPed->bScriptObjectiveCompleted = false;
+ pPed->SetObjective(OBJECTIVE_RUN_TO_AREA, pos, radius);
+ return 0;
+ }
+ */
+ case COMMAND_SET_CHAR_OBJ_RUN_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_RUN_TO_AREA, pos);
+ return 0;
+ }
+ /*
+ case COMMAND_IS_PLAYER_TOUCHING_OBJECT_ON_FOOT:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
+ script_assert(pPed);
+ CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[1]);
+ bool isTouching = false;
+ if (pPed->bInVehicle)
+ isTouching = false;
+ else if (pPed->GetHasCollidedWith(pObject))
+ isTouching = true;
+ UpdateCompareFlag(isTouching);
+ return 0;
+ }
+ case COMMAND_IS_CHAR_TOUCHING_OBJECT_ON_FOOT:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[1]);
+ bool isTouching = false;
+ if (pPed->InVehicle())
+ isTouching = false;
+ else if (pPed->GetHasCollidedWith(pObject))
+ isTouching = true;
+ UpdateCompareFlag(isTouching);
+ return 0;
+ }
+ */
+ case COMMAND_LOAD_SPECIAL_CHARACTER:
+ {
+ CollectParameters(&m_nIp, 1);
+ char name[16];
+ strncpy(name, (char*)&CTheScripts::ScriptSpace[m_nIp], KEY_LENGTH_IN_SCRIPT);
+ for (int i = 0; i < KEY_LENGTH_IN_SCRIPT; i++)
+ name[i] = tolower(name[i]);
+ CStreaming::RequestSpecialChar(ScriptParams[0] - 1, name, STREAMFLAGS_DEPENDENCY | STREAMFLAGS_SCRIPTOWNED);
+ m_nIp += KEY_LENGTH_IN_SCRIPT;
+ return 0;
+ }
+ case COMMAND_HAS_SPECIAL_CHARACTER_LOADED:
+ {
+ CollectParameters(&m_nIp, 1);
+ UpdateCompareFlag(CStreaming::HasSpecialCharLoaded(ScriptParams[0] - 1));
+ return 0;
+ }
+ /*
+ case COMMAND_FLASH_CAR:
+ {
+ CollectParameters(&m_nIp, 2);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ pVehicle->bHasBlip = (ScriptParams[1] != 0);
+ return 0;
+ }
+ case COMMAND_FLASH_CHAR:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ pPed->bHasBlip = (ScriptParams[1] != 0);
+ return 0;
+ }
+ case COMMAND_FLASH_OBJECT:
+ {
+ CollectParameters(&m_nIp, 2);
+ CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
+ script_assert(pObject);
+ 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);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ script_assert(pVehicle->m_vehType == VEHICLE_TYPE_CAR);
+ ((CAutomobile*)pVehicle)->m_bombType = ScriptParams[1];
+ ((CAutomobile*)pVehicle)->m_pBombRigger = FindPlayerPed();
+ return 0;
+ }
+ */
+ case COMMAND_SET_CHAR_PERSONALITY:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ pPed->SetPedStats((ePedStats)ScriptParams[1]);
+ return 0;
+ }
+ case COMMAND_SET_CUTSCENE_OFFSET:
+ CollectParameters(&m_nIp, 3);
+ CCutsceneMgr::SetCutsceneOffset(*(CVector*)&ScriptParams[0]);
+ return 0;
+ case COMMAND_SET_ANIM_GROUP_FOR_CHAR:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ pPed->m_animGroup = (AssocGroupId)ScriptParams[1];
+ return 0;
+ }
+ /*
+ case COMMAND_SET_ANIM_GROUP_FOR_PLAYER:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
+ script_assert(pPed);
+ pPed->m_animGroup = (AssocGroupId)ScriptParams[1];
+ return 0;
+ }
+ */
+ case COMMAND_REQUEST_MODEL:
+ {
+ CollectParameters(&m_nIp, 1);
+ int model = ScriptParams[0];
+ if (model < 0)
+ model = CTheScripts::UsedObjectArray[-model].index;
+ CStreaming::RequestModel(model, STREAMFLAGS_DEPENDENCY | STREAMFLAGS_NOFADE | STREAMFLAGS_SCRIPTOWNED);
+ return 0;
+ }
+ case COMMAND_HAS_MODEL_LOADED:
+ {
+ CollectParameters(&m_nIp, 1);
+ int model = ScriptParams[0];
+ if (model < 0)
+ model = CTheScripts::UsedObjectArray[-model].index;
+ UpdateCompareFlag(CStreaming::HasModelLoaded(model));
+ return 0;
+ }
+ case COMMAND_MARK_MODEL_AS_NO_LONGER_NEEDED:
+ {
+ CollectParameters(&m_nIp, 1);
+ int model = ScriptParams[0];
+ if (model < 0)
+ model = CTheScripts::UsedObjectArray[-model].index;
+ CStreaming::SetMissionDoesntRequireModel(model);
+ return 0;
+ }
+ case COMMAND_GRAB_PHONE:
+ {
+ CollectParameters(&m_nIp, 2);
+ ScriptParams[0] = gPhoneInfo.GrabPhone(*(float*)&ScriptParams[0], *(float*)&ScriptParams[1]);
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ }
+ /*
+ case COMMAND_SET_REPEATED_PHONE_MESSAGE:
+ {
+ CollectParameters(&m_nIp, 1);
+ wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ gPhoneInfo.SetPhoneMessage_Repeatedly(ScriptParams[0], text, nil, nil, nil, nil, nil);
+ return 0;
+ }
+ case COMMAND_SET_PHONE_MESSAGE:
+ {
+ CollectParameters(&m_nIp, 1);
+ wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ gPhoneInfo.SetPhoneMessage_JustOnce(ScriptParams[0], text, nil, nil, nil, nil, nil);
+ return 0;
+ }
+ case COMMAND_HAS_PHONE_DISPLAYED_MESSAGE:
+ {
+ CollectParameters(&m_nIp, 1);
+ UpdateCompareFlag(gPhoneInfo.HasMessageBeenDisplayed(ScriptParams[0]));
+ return 0;
+ }
+ */
+ case COMMAND_TURN_PHONE_OFF:
+ {
+ CollectParameters(&m_nIp, 1);
+ gPhoneInfo.SetPhoneMessage_JustOnce(ScriptParams[0], nil, nil, nil, nil, nil, nil);
+ return 0;
+ }
+ case COMMAND_DRAW_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);
+ return 0;
+ }
+ case COMMAND_DRAW_LIGHT:
+ {
+ CollectParameters(&m_nIp, 6);
+ CVector pos = *(CVector*)&ScriptParams[0];
+ CVector unused(0.0f, 0.0f, 0.0f);
+ CPointLights::AddLight(0, *(CVector*)&ScriptParams[0], CVector(0.0f, 0.0f, 0.0f), 12.0f,
+ ScriptParams[3] / 255.0f, ScriptParams[4] / 255.0f, ScriptParams[5] / 255.0f, 0, true);
+ 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);
+ CVector pos = *(CVector*)&ScriptParams[0];
+ if (pos.z <= MAP_Z_LOW_LIMIT)
+ pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
+ CRestart::OverrideNextRestart(pos, *(float*)&ScriptParams[3]);
+ if (CWorld::Players[CWorld::PlayerInFocus].m_WBState != WBSTATE_PLAYING)
+ printf("RESTART_CRITICAL_MISSION - Player state is not PLAYING\n");
+ CWorld::Players[CWorld::PlayerInFocus].PlayerFailedCriticalMission();
+ return 0;
+ }
+ */
+ case COMMAND_IS_PLAYER_PLAYING:
+ {
+ CollectParameters(&m_nIp, 1);
+ UpdateCompareFlag(CWorld::Players[ScriptParams[0]].m_WBState == WBSTATE_PLAYING);
+ return 0;
+ }
+ //case COMMAND_SET_COLL_OBJ_NO_OBJ:
+ default:
+ script_assert(0);
+ }
+ return -1;
+}
+
+int8 CRunningScript::ProcessCommands600To699(int32 command)
+{
+ switch (command){
+ /* Collective commands are not implemented until LCS.
+ case COMMAND_SET_COLL_OBJ_WAIT_ON_FOOT:
+ case COMMAND_SET_COLL_OBJ_FLEE_ON_FOOT_TILL_SAFE:
+ case COMMAND_SET_COLL_OBJ_GUARD_SPOT:
+ case COMMAND_SET_COLL_OBJ_GUARD_AREA:
+ case COMMAND_SET_COLL_OBJ_WAIT_IN_CAR:
+ case COMMAND_SET_COLL_OBJ_KILL_CHAR_ON_FOOT:
+ case COMMAND_SET_COLL_OBJ_KILL_PLAYER_ON_FOOT:
+ case COMMAND_SET_COLL_OBJ_KILL_CHAR_ANY_MEANS:
+ case COMMAND_SET_COLL_OBJ_KILL_PLAYER_ANY_MEANS:
+ case COMMAND_SET_COLL_OBJ_FLEE_CHAR_ON_FOOT_TILL_SAFE:
+ case COMMAND_SET_COLL_OBJ_FLEE_PLAYER_ON_FOOT_TILL_SAFE:
+ case COMMAND_SET_COLL_OBJ_FLEE_CHAR_ON_FOOT_ALWAYS:
+ case COMMAND_SET_COLL_OBJ_FLEE_PLAYER_ON_FOOT_ALWAYS:
+ case COMMAND_SET_COLL_OBJ_GOTO_CHAR_ON_FOOT:
+ case COMMAND_SET_COLL_OBJ_GOTO_PLAYER_ON_FOOT:
+ case COMMAND_SET_COLL_OBJ_LEAVE_CAR:
+ case COMMAND_SET_COLL_OBJ_ENTER_CAR_AS_PASSENGER:
+ case COMMAND_SET_COLL_OBJ_ENTER_CAR_AS_DRIVER:
+ case COMMAND_SET_COLL_OBJ_FOLLOW_CAR_IN_CAR:
+ case COMMAND_SET_COLL_OBJ_FIRE_AT_OBJECT_FROM_VEHICLE:
+ case COMMAND_SET_COLL_OBJ_DESTROY_OBJECT:
+ case COMMAND_SET_COLL_OBJ_DESTROY_CAR:
+ case COMMAND_SET_COLL_OBJ_GOTO_AREA_ON_FOOT:
+ case COMMAND_SET_COLL_OBJ_GOTO_AREA_IN_CAR:
+ case COMMAND_SET_COLL_OBJ_FOLLOW_CAR_ON_FOOT_WITH_OFFSET:
+ case COMMAND_SET_COLL_OBJ_GUARD_ATTACK:
+ case COMMAND_SET_COLL_OBJ_FOLLOW_ROUTE:
+ case COMMAND_SET_COLL_OBJ_GOTO_COORD_ON_FOOT:
+ case COMMAND_SET_COLL_OBJ_GOTO_COORD_IN_CAR:
+ case COMMAND_SET_COLL_OBJ_RUN_TO_AREA:
+ case COMMAND_SET_COLL_OBJ_RUN_TO_COORD:
+ case COMMAND_ADD_PEDS_IN_AREA_TO_COLL:
+ case COMMAND_ADD_PEDS_IN_VEHICLE_TO_COLL:
+ case COMMAND_CLEAR_COLL:
+ case COMMAND_IS_COLL_IN_CARS:
+ case COMMAND_LOCATE_COLL_ANY_MEANS_2D:
+ case COMMAND_LOCATE_COLL_ON_FOOT_2D:
+ case COMMAND_LOCATE_COLL_IN_CAR_2D:
+ case COMMAND_LOCATE_STOPPED_COLL_ANY_MEANS_2D:
+ case COMMAND_LOCATE_STOPPED_COLL_ON_FOOT_2D:
+ case COMMAND_LOCATE_STOPPED_COLL_IN_CAR_2D:
+ case COMMAND_LOCATE_COLL_ANY_MEANS_CHAR_2D:
+ case COMMAND_LOCATE_COLL_ON_FOOT_CHAR_2D:
+ case COMMAND_LOCATE_COLL_IN_CAR_CHAR_2D:
+ case COMMAND_LOCATE_COLL_ANY_MEANS_CAR_2D:
+ case COMMAND_LOCATE_COLL_ON_FOOT_CAR_2D:
+ case COMMAND_LOCATE_COLL_IN_CAR_CAR_2D:
+ case COMMAND_LOCATE_COLL_ANY_MEANS_PLAYER_2D:
+ case COMMAND_LOCATE_COLL_ON_FOOT_PLAYER_2D:
+ case COMMAND_LOCATE_COLL_IN_CAR_PLAYER_2D:
+ case COMMAND_IS_COLL_IN_AREA_2D:
+ case COMMAND_IS_COLL_IN_AREA_ON_FOOT_2D:
+ case COMMAND_IS_COLL_IN_AREA_IN_CAR_2D:
+ case COMMAND_IS_COLL_STOPPED_IN_AREA_2D:
+ case COMMAND_IS_COLL_STOPPED_IN_AREA_ON_FOOT_2D:
+ case COMMAND_IS_COLL_STOPPED_IN_AREA_IN_CAR_2D:
+ case COMMAND_GET_NUMBER_OF_PEDS_IN_COLL:
+ */
+ case COMMAND_SET_CHAR_HEED_THREATS:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ pPed->bRespondsToThreats = (ScriptParams[1] != 0);
+ return 0;
+ }
+ case COMMAND_SET_PLAYER_HEED_THREATS:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
+ script_assert(pPed);
+ pPed->bRespondsToThreats = (ScriptParams[1] != 0);
+ return 0;
+ }
+ case COMMAND_GET_CONTROLLER_MODE:
+#if defined(GTA_PC) && !defined(DETECT_PAD_INPUT_SWITCH)
+ ScriptParams[0] = 0;
+#else
+ ScriptParams[0] = CPad::IsAffectedByController ? CPad::GetPad(0)->Mode : 0;
+#endif
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ case COMMAND_SET_CAN_RESPRAY_CAR:
+ {
+ CollectParameters(&m_nIp, 2);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ //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);
+ UpdateCompareFlag(pVehicle->IsTaxi());
+ return 0;
+ }
+ */
+ case COMMAND_UNLOAD_SPECIAL_CHARACTER:
+ CollectParameters(&m_nIp, 1);
+ CStreaming::SetMissionDoesntRequireSpecialChar(ScriptParams[0] - 1);
+ return 0;
+ case COMMAND_RESET_NUM_OF_MODELS_KILLED_BY_PLAYER:
+ CDarkel::ResetModelsKilledByPlayer();
+ return 0;
+ case COMMAND_GET_NUM_OF_MODELS_KILLED_BY_PLAYER:
+ CollectParameters(&m_nIp, 1);
+ ScriptParams[0] = CDarkel::QueryModelsKilledByPlayer(ScriptParams[0]);
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ /*
+ case COMMAND_ACTIVATE_GARAGE:
+ CollectParameters(&m_nIp, 1);
+ CGarages::ActivateGarage(ScriptParams[0]);
+ return 0;
+ case COMMAND_SWITCH_TAXI_TIMER:
+ {
+ CollectParameters(&m_nIp, 1);
+ if (ScriptParams[0] != 0){
+ CWorld::Players[CWorld::PlayerInFocus].m_nUnusedTaxiTimer = CTimer::GetTimeInMilliseconds();
+ CWorld::Players[CWorld::PlayerInFocus].m_bUnusedTaxiThing = true;
+ }else{
+ CWorld::Players[CWorld::PlayerInFocus].m_bUnusedTaxiThing = false;
+ }
+ 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;
+ CVector pos = *(CVector*)&ScriptParams[1];
+ if (pos.z <= MAP_Z_LOW_LIMIT)
+ pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
+ pObj->SetPosition(pos);
+ 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);
+ StoreParameters(&m_nIp, 1);
+ if (m_bIsMissionScript)
+ CTheScripts::MissionCleanup.AddEntityToList(ScriptParams[0], CLEANUP_OBJECT);
+ return 0;
+ }
+ /*
+ case COMMAND_IS_BOAT:
+ {
+ CollectParameters(&m_nIp, 1);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ UpdateCompareFlag(pVehicle->m_vehType == VEHICLE_TYPE_BOAT);
+ return 0;
+ }
+ case COMMAND_SET_CHAR_OBJ_GOTO_AREA_ANY_MEANS:
+ {
+ CollectParameters(&m_nIp, 5);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ float infX = *(float*)&ScriptParams[1];
+ float infY = *(float*)&ScriptParams[2];
+ float supX = *(float*)&ScriptParams[3];
+ float supY = *(float*)&ScriptParams[4];
+ if (infX > supX) {
+ infX = *(float*)&ScriptParams[3];
+ supX = *(float*)&ScriptParams[1];
+ }
+ if (infY > supY) {
+ infY = *(float*)&ScriptParams[4];
+ supY = *(float*)&ScriptParams[2];
+ }
+ CVector pos;
+ pos.x = (infX + supX) / 2;
+ pos.y = (infY + supY) / 2;
+ pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
+ float radius = Max(pos.x - infX, pos.y - infY);
+ pPed->bScriptObjectiveCompleted = false;
+ 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:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPlayerInfo* pPlayer = &CWorld::Players[ScriptParams[0]];
+ UpdateCompareFlag(CTheScripts::IsPlayerStopped(pPlayer));
+ return 0;
+
+ }
+ /*
+ case COMMAND_IS_CHAR_STOPPED:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ UpdateCompareFlag(CTheScripts::IsPedStopped(pPed));
+ return 0;
+ }
+ case COMMAND_MESSAGE_WAIT:
+ CollectParameters(&m_nIp, 2);
+ m_nWakeTime = CTimer::GetTimeInMilliseconds() + ScriptParams[0];
+ if (ScriptParams[1] != 0)
+ m_bSkipWakeTime = true;
+ return 1;
+ case COMMAND_ADD_PARTICLE_EFFECT:
+ {
+ CollectParameters(&m_nIp, 5);
+ CVector pos = *(CVector*)&ScriptParams[1];
+ if (pos.z <= MAP_Z_LOW_LIMIT)
+ pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
+ CParticleObject::AddObject(ScriptParams[0], pos, ScriptParams[4] != 0);
+ return 0;
+ }
+ */
+ case COMMAND_SWITCH_WIDESCREEN:
+ CollectParameters(&m_nIp, 1);
+ if (ScriptParams[0] != 0)
+ TheCamera.SetWideScreenOn();
+ else
+ TheCamera.SetWideScreenOff();
+ return 0;
+ /*
+ case COMMAND_ADD_SPRITE_BLIP_FOR_CAR:
+ {
+ CollectParameters(&m_nIp, 2);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ CRadar::GetActualBlipArrayIndex(CollectNextParameterWithoutIncreasingPC(m_nIp));
+ int id = CRadar::SetEntityBlip(BLIP_CAR, ScriptParams[0], 0, BLIP_DISPLAY_BOTH);
+ CRadar::SetBlipSprite(id, ScriptParams[1]);
+ ScriptParams[0] = id;
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ }
+ case COMMAND_ADD_SPRITE_BLIP_FOR_CHAR:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ CRadar::GetActualBlipArrayIndex(CollectNextParameterWithoutIncreasingPC(m_nIp));
+ int id = CRadar::SetEntityBlip(BLIP_CHAR, ScriptParams[0], 1, BLIP_DISPLAY_BOTH);
+ CRadar::SetBlipSprite(id, ScriptParams[1]);
+ ScriptParams[0] = id;
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ }
+ case COMMAND_ADD_SPRITE_BLIP_FOR_OBJECT:
+ {
+ CollectParameters(&m_nIp, 2);
+ CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
+ script_assert(pObject);
+ CRadar::GetActualBlipArrayIndex(CollectNextParameterWithoutIncreasingPC(m_nIp));
+ int id = CRadar::SetEntityBlip(BLIP_OBJECT, ScriptParams[0], 6, BLIP_DISPLAY_BOTH);
+ CRadar::SetBlipSprite(id, ScriptParams[1]);
+ ScriptParams[0] = id;
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ }
+ */
+ case COMMAND_ADD_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::SetCoordBlip(BLIP_CONTACT_POINT, pos, 2, BLIP_DISPLAY_BOTH);
+ CRadar::SetBlipSprite(id, ScriptParams[3]);
+ ScriptParams[0] = id;
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ }
+ case COMMAND_ADD_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::SetCoordBlip(BLIP_COORD, pos, 5, BLIP_DISPLAY_BOTH);
+ CRadar::SetBlipSprite(id, ScriptParams[3]);
+ ScriptParams[0] = id;
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ }
+ case COMMAND_SET_CHAR_ONLY_DAMAGED_BY_PLAYER:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ pPed->bOnlyDamagedByPlayer = (ScriptParams[1] != 0);
+ return 0;
+ }
+ case COMMAND_SET_CAR_ONLY_DAMAGED_BY_PLAYER:
+ {
+ CollectParameters(&m_nIp, 2);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ pVehicle->bOnlyDamagedByPlayer = (ScriptParams[1] != 0);
+ return 0;
+ }
+ case COMMAND_SET_CHAR_PROOFS:
+ {
+ CollectParameters(&m_nIp, 6);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ pPed->bBulletProof = (ScriptParams[1] != 0);
+ pPed->bFireProof = (ScriptParams[2] != 0);
+ pPed->bExplosionProof = (ScriptParams[3] != 0);
+ pPed->bCollisionProof = (ScriptParams[4] != 0);
+ pPed->bMeleeProof = (ScriptParams[5] != 0);
+ return 0;
+ }
+ case COMMAND_SET_CAR_PROOFS:
+ {
+ CollectParameters(&m_nIp, 6);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ pVehicle->bBulletProof = (ScriptParams[1] != 0);
+ pVehicle->bFireProof = (ScriptParams[2] != 0);
+ pVehicle->bExplosionProof = (ScriptParams[3] != 0);
+ pVehicle->bCollisionProof = (ScriptParams[4] != 0);
+ pVehicle->bMeleeProof = (ScriptParams[5] != 0);
+ return 0;
+ }
+ case COMMAND_IS_PLAYER_IN_ANGLED_AREA_2D:
+ case COMMAND_IS_PLAYER_IN_ANGLED_AREA_ON_FOOT_2D:
+ case COMMAND_IS_PLAYER_IN_ANGLED_AREA_IN_CAR_2D:
+ case COMMAND_IS_PLAYER_STOPPED_IN_ANGLED_AREA_2D:
+ case COMMAND_IS_PLAYER_STOPPED_IN_ANGLED_AREA_ON_FOOT_2D:
+ case COMMAND_IS_PLAYER_STOPPED_IN_ANGLED_AREA_IN_CAR_2D:
+ case COMMAND_IS_PLAYER_IN_ANGLED_AREA_3D:
+ case COMMAND_IS_PLAYER_IN_ANGLED_AREA_ON_FOOT_3D:
+ case COMMAND_IS_PLAYER_IN_ANGLED_AREA_IN_CAR_3D:
+ case COMMAND_IS_PLAYER_STOPPED_IN_ANGLED_AREA_3D:
+ case COMMAND_IS_PLAYER_STOPPED_IN_ANGLED_AREA_ON_FOOT_3D:
+ 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]);
+ return 0;
+ case COMMAND_GET_NUMBER_OF_CARS_COLLECTED_BY_GARAGE:
+ CollectParameters(&m_nIp, 1);
+ ScriptParams[0] = CGarages::QueryCarsCollected(ScriptParams[0]);
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ case COMMAND_HAS_CAR_BEEN_TAKEN_TO_GARAGE:
+ CollectParameters(&m_nIp, 2);
+ UpdateCompareFlag(CGarages::HasThisCarBeenCollected(ScriptParams[0], ScriptParams[1] - 1));
+ return 0;
+ */
+ default:
+ script_assert(0);
+ }
+ return -1;
+}
+
+int8 CRunningScript::ProcessCommands700To799(int32 command)
+{
+ switch (command){
+ /*
+ case COMMAND_SET_SWAT_REQUIRED:
+ CollectParameters(&m_nIp, 1);
+ FindPlayerPed()->m_pWanted->m_bSwatRequired = (ScriptParams[0] != 0);
+ return 0;
+ case COMMAND_SET_FBI_REQUIRED:
+ CollectParameters(&m_nIp, 1);
+ FindPlayerPed()->m_pWanted->m_bFbiRequired = (ScriptParams[0] != 0);
+ return 0;
+ case COMMAND_SET_ARMY_REQUIRED:
+ CollectParameters(&m_nIp, 1);
+ FindPlayerPed()->m_pWanted->m_bArmyRequired = (ScriptParams[0] != 0);
+ return 0;
+ */
+ case COMMAND_IS_CAR_IN_WATER:
+ {
+ CollectParameters(&m_nIp, 1);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ UpdateCompareFlag(pVehicle && pVehicle->bIsInWater);
+ return 0;
+ }
+ case COMMAND_GET_CLOSEST_CHAR_NODE:
+ {
+ CollectParameters(&m_nIp, 3);
+ 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, true)];
+ *(CVector*)&ScriptParams[0] = pNode->GetPosition();
+ StoreParameters(&m_nIp, 3);
+ return 0;
+ }
+ case COMMAND_GET_CLOSEST_CAR_NODE:
+ {
+ CollectParameters(&m_nIp, 3);
+ 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.FindNodeClosestToCoors(pos, 0, 999999.9f, true, true));
+ StoreParameters(&m_nIp, 3);
+ return 0;
+ }
+ case COMMAND_CAR_GOTO_COORDINATES_ACCURATE:
+ {
+ CollectParameters(&m_nIp, 4);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ CVector pos = *(CVector*)&ScriptParams[1];
+ if (pos.z <= MAP_Z_LOW_LIMIT)
+ pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
+ pos.z += pVehicle->GetDistanceFromCentreOfMassToBaseOfModel();
+ if (CCarCtrl::JoinCarWithRoadSystemGotoCoors(pVehicle, pos, false))
+ pVehicle->AutoPilot.m_nCarMission = MISSION_GOTO_COORDS_STRAIGHT_ACCURATE;
+ else
+ pVehicle->AutoPilot.m_nCarMission = MISSION_GOTOCOORDS_ACCURATE;
+ pVehicle->SetStatus(STATUS_PHYSICS);
+ pVehicle->bEngineOn = true;
+ 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]);
+ return 0;
+ case COMMAND_START_PACMAN_RECORD:
+ CPacManPickups::StartPacManRecord();
+ return 0;
+ case COMMAND_GET_NUMBER_OF_POWER_PILLS_EATEN:
+ ScriptParams[0] = CPacManPickups::QueryPowerPillsEatenInRace();
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ case COMMAND_CLEAR_PACMAN:
+ CPacManPickups::CleanUpPacManStuff();
+ return 0;
+ case COMMAND_START_PACMAN_SCRAMBLE:
+ {
+ CollectParameters(&m_nIp, 5);
+ CVector pos = *(CVector*)&ScriptParams[0];
+ if (pos.z <= MAP_Z_LOW_LIMIT)
+ pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
+ CPacManPickups::StartPacManScramble(pos, *(float*)&ScriptParams[3], ScriptParams[4]);
+ return 0;
+ }
+ case COMMAND_GET_NUMBER_OF_POWER_PILLS_CARRIED:
+ ScriptParams[0] = CPacManPickups::QueryPowerPillsCarriedByPlayer();
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ case COMMAND_CLEAR_NUMBER_OF_POWER_PILLS_CARRIED:
+ CPacManPickups::ResetPowerPillsCarriedByPlayer();
+ return 0;
+ */
+ case COMMAND_IS_CAR_ON_SCREEN:
+ {
+ CollectParameters(&m_nIp, 1);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ UpdateCompareFlag(TheCamera.IsSphereVisible(pVehicle->GetBoundCentre(), pVehicle->GetBoundRadius()));
+ return 0;
+ }
+ case COMMAND_IS_CHAR_ON_SCREEN:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ UpdateCompareFlag(TheCamera.IsSphereVisible(pPed->GetBoundCentre(), pPed->GetBoundRadius()));
+ return 0;
+ }
+ case COMMAND_IS_OBJECT_ON_SCREEN:
+ {
+ CollectParameters(&m_nIp, 1);
+ CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
+ script_assert(pObject);
+ UpdateCompareFlag(TheCamera.IsSphereVisible(pObject->GetBoundCentre(), pObject->GetBoundRadius()));
+ return 0;
+ }
+ /*
+ case COMMAND_GOSUB_FILE:
+ {
+ CollectParameters(&m_nIp, 2);
+ script_assert(m_nStackPointer < MAX_STACK_DEPTH);
+ m_anStack[m_nStackPointer++] = m_nIp;
+ SetIP(ScriptParams[0]);
+ // ScriptParams[1] == filename
+ return 0;
+ }
+ */
+ case COMMAND_GET_GROUND_Z_FOR_3D_COORD:
+ {
+ CollectParameters(&m_nIp, 3);
+ CVector pos = *(CVector*)&ScriptParams[0];
+ bool success;
+ *(float*)&ScriptParams[0] = CWorld::FindGroundZFor3DCoord(pos.x, pos.y, pos.z, &success);
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ }
+ case COMMAND_START_SCRIPT_FIRE:
+ {
+ CollectParameters(&m_nIp, 3);
+ CVector pos = *(CVector*)&ScriptParams[0];
+ if (pos.z <= MAP_Z_LOW_LIMIT)
+ pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
+ ScriptParams[0] = gFireManager.StartScriptFire(pos, nil, 0.8f, 1);
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ }
+ case COMMAND_IS_SCRIPT_FIRE_EXTINGUISHED:
+ CollectParameters(&m_nIp, 1);
+ UpdateCompareFlag(gFireManager.IsScriptFireExtinguish(ScriptParams[0]));
+ return 0;
+ case COMMAND_REMOVE_SCRIPT_FIRE:
+ CollectParameters(&m_nIp, 1);
+ gFireManager.RemoveScriptFire(ScriptParams[0]);
+ return 0;
+ /*
+ case COMMAND_SET_COMEDY_CONTROLS:
+ {
+ CollectParameters(&m_nIp, 2);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ pVehicle->bComedyControls = (ScriptParams[1] != 0);
+ return 0;
+ }
+ */
+ case COMMAND_BOAT_GOTO_COORDS:
+ {
+ CollectParameters(&m_nIp, 4);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ script_assert(pVehicle->m_vehType == VEHICLE_TYPE_BOAT);
+ CBoat* pBoat = (CBoat*)pVehicle;
+ CVector pos = *(CVector*)&ScriptParams[1];
+ if (pos.z <= MAP_Z_LOW_LIMIT)
+ CWaterLevel::GetWaterLevel(pos.x, pos.y, pos.z, &pos.z, false);
+ pBoat->AutoPilot.m_nCarMission = MISSION_GOTOCOORDS_ASTHECROWSWIMS;
+ pBoat->AutoPilot.m_vecDestinationCoors = pos;
+ pBoat->SetStatus(STATUS_PHYSICS);
+ pBoat->AutoPilot.m_nCruiseSpeed = Max(1, pBoat->AutoPilot.m_nCruiseSpeed);
+ pBoat->AutoPilot.m_nAntiReverseTimer = CTimer::GetTimeInMilliseconds();
+ return 0;
+ }
+ case COMMAND_BOAT_STOP:
+ {
+ CollectParameters(&m_nIp, 1);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ script_assert(pVehicle->m_vehType == VEHICLE_TYPE_BOAT);
+ CBoat* pBoat = (CBoat*)pVehicle;
+ pBoat->AutoPilot.m_nCarMission = MISSION_NONE;
+ pBoat->SetStatus(STATUS_PHYSICS);
+ pBoat->bEngineOn = false;
+ pBoat->AutoPilot.m_nCruiseSpeed = 0;
+ return 0;
+ }
+ case COMMAND_IS_PLAYER_SHOOTING_IN_AREA:
+ {
+ CollectParameters(&m_nIp, 6);
+ CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
+ script_assert(pPed);
+ float x1 = *(float*)&ScriptParams[1];
+ float y1 = *(float*)&ScriptParams[2];
+ float x2 = *(float*)&ScriptParams[3];
+ float y2 = *(float*)&ScriptParams[4];
+ UpdateCompareFlag(pPed->bIsShooting && pPed->IsWithinArea(x1, y1, x2, y2));
+ if (ScriptParams[5])
+ CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, x1, y1, x2, y2, MAP_Z_LOW_LIMIT);
+ if (CTheScripts::DbgFlag)
+ CTheScripts::DrawDebugSquare(x1, y1, x2, y2);
+ return 0;
+ }
+ case COMMAND_IS_CHAR_SHOOTING_IN_AREA:
+ {
+ CollectParameters(&m_nIp, 6);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ float x1 = *(float*)&ScriptParams[1];
+ float y1 = *(float*)&ScriptParams[2];
+ float x2 = *(float*)&ScriptParams[3];
+ float y2 = *(float*)&ScriptParams[4];
+ UpdateCompareFlag(pPed->bIsShooting && pPed->IsWithinArea(x1, y1, x2, y2));
+ if (ScriptParams[5])
+ CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, x1, y1, x2, y2, MAP_Z_LOW_LIMIT);
+ if (CTheScripts::DbgFlag)
+ CTheScripts::DrawDebugSquare(x1, y1, x2, y2);
+ return 0;
+ }
+ case COMMAND_IS_CURRENT_PLAYER_WEAPON:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
+ script_assert(pPed);
+ UpdateCompareFlag(ScriptParams[1] == pPed->GetWeapon()->m_eWeaponType);
+ return 0;
+ }
+ case COMMAND_IS_CURRENT_CHAR_WEAPON:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ UpdateCompareFlag(ScriptParams[1] == pPed->GetWeapon()->m_eWeaponType);
+ return 0;
+ }
+ /*
+ case COMMAND_CLEAR_NUMBER_OF_POWER_PILLS_EATEN:
+ CPacManPickups::ResetPowerPillsEatenInRace();
+ return 0;
+ case COMMAND_ADD_POWER_PILL:
+ {
+ CollectParameters(&m_nIp, 3);
+ CVector pos = *(CVector*)&ScriptParams[0];
+ if (pos.z <= MAP_Z_LOW_LIMIT)
+ pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
+ CPacManPickups::GenerateOnePMPickUp(pos);
+ return 0;
+ }
+ */
+ case COMMAND_SET_BOAT_CRUISE_SPEED:
+ {
+ CollectParameters(&m_nIp, 2);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ script_assert(pVehicle->m_vehType == VEHICLE_TYPE_BOAT);
+ CBoat* pBoat = (CBoat*)pVehicle;
+ pBoat->AutoPilot.m_nCruiseSpeed = *(float*)&ScriptParams[1];
+ return 0;
+ }
+ /*
+ case COMMAND_GET_RANDOM_CHAR_IN_AREA:
+ {
+ CollectParameters(&m_nIp, 4);
+ 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->GetModelIndex() == MI_SCUM_WOM || pPed->GetModelIndex() == MI_SCUM_MAN)
+// continue;
+ if (!ThisIsAValidRandomPed(pPed->m_nPedType))
+ 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_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, ZONE_DEFAULT);
+ if (nZone != -1)
+ m_nIp += KEY_LENGTH_IN_SCRIPT;
+ CZone* pZone = CTheZones::GetNavigationZone(nZone);
+ CollectParameters(&m_nIp, 3);
+ int ped_handle = -1;
+ CVector pos = FindPlayerCoors();
+ int i = CPools::GetPedPool()->GetSize();
+ 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 (!ThisIsAValidRandomPed(pPed->m_nPedType, ScriptParams[0], ScriptParams[1], ScriptParams[2]))
+ continue;
+ if (pPed->bIsLeader || pPed->m_leader)
+ continue;
+ if (!CTheZones::PointLiesWithinZone(&pPed->GetPosition(), pZone))
+ continue;
+ if (pos.z - PED_FIND_Z_OFFSET > pPed->GetPosition().z)
+ 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;
+ 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_IS_PLAYER_IN_TAXI:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
+ script_assert(pPed);
+ UpdateCompareFlag(pPed->bInVehicle && pPed->m_pMyVehicle->IsTaxi());
+ return 0;
+ }
+ case COMMAND_IS_PLAYER_SHOOTING:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
+ script_assert(pPed);
+ UpdateCompareFlag(pPed->bIsShooting);
+ return 0;
+ }
+ case COMMAND_IS_CHAR_SHOOTING:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ UpdateCompareFlag(pPed->bIsShooting);
+ return 0;
+ }
+ case COMMAND_CREATE_MONEY_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_MONEY, PICKUP_MONEY, ScriptParams[3]);
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ }
+ case COMMAND_SET_CHAR_ACCURACY:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ pPed->m_wepAccuracy = ScriptParams[1];
+ return 0;
+ }
+ case COMMAND_GET_CAR_SPEED:
+ {
+ CollectParameters(&m_nIp, 1);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ *(float*)&ScriptParams[0] = pVehicle->GetSpeed().Magnitude() * GAME_SPEED_TO_METERS_PER_SECOND;
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ }
+ case COMMAND_LOAD_CUTSCENE:
+ {
+ char name[KEY_LENGTH_IN_SCRIPT];
+ strncpy(name, (const char*)&CTheScripts::ScriptSpace[m_nIp], KEY_LENGTH_IN_SCRIPT);
+ m_nIp += KEY_LENGTH_IN_SCRIPT;
+ CCutsceneMgr::LoadCutsceneData(name);
+ return 0;
+ }
+ case COMMAND_CREATE_CUTSCENE_OBJECT:
+ {
+ CollectParameters(&m_nIp, 1);
+ CCutsceneObject* pCutObj = CCutsceneMgr::CreateCutsceneObject(ScriptParams[0]);
+ ScriptParams[0] = CPools::GetObjectPool()->GetIndex(pCutObj);
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ }
+ case COMMAND_SET_CUTSCENE_ANIM:
+ {
+ CollectParameters(&m_nIp, 1);
+ char name[KEY_LENGTH_IN_SCRIPT];
+ CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
+ script_assert(pObject);
+ strncpy(name, (const char*)&CTheScripts::ScriptSpace[m_nIp], KEY_LENGTH_IN_SCRIPT);
+ m_nIp += KEY_LENGTH_IN_SCRIPT;
+ CCutsceneMgr::SetCutsceneAnim(name, pObject);
+ return 0;
+ }
+ case COMMAND_START_CUTSCENE:
+ CCutsceneMgr::ms_cutsceneLoadStatus = 1;
+ return 0;
+ case COMMAND_GET_CUTSCENE_TIME:
+ ScriptParams[0] = CCutsceneMgr::GetCutsceneTimeInMilleseconds();
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ case COMMAND_HAS_CUTSCENE_FINISHED:
+ UpdateCompareFlag(CCutsceneMgr::HasCutsceneFinished());
+ return 0;
+ case COMMAND_CLEAR_CUTSCENE:
+ CCutsceneMgr::DeleteCutsceneData();
+ return 0;
+ case COMMAND_RESTORE_CAMERA_JUMPCUT:
+ TheCamera.RestoreWithJumpCut();
+ return 0;
+ case COMMAND_CREATE_COLLECTABLE1:
+ {
+ 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;
+ CPickups::GenerateNewOne(pos, MI_COLLECTABLE1, PICKUP_COLLECTABLE1, 0);
+ return 0;
+ }
+ case COMMAND_SET_COLLECTABLE1_TOTAL:
+ CollectParameters(&m_nIp, 1);
+ CWorld::Players[CWorld::PlayerInFocus].m_nTotalPackages = ScriptParams[0];
+ return 0;
+ /*
+ case COMMAND_IS_PROJECTILE_IN_AREA:
+ {
+ CollectParameters(&m_nIp, 6);
+ 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];
+ }
+ UpdateCompareFlag(CProjectileInfo::IsProjectileInRange(infX, supX, infY, supY, infZ, supZ, false));
+ if (CTheScripts::DbgFlag)
+ CTheScripts::DrawDebugCube(infX, infY, infZ, supX, supY, supZ);
+ return 0;
+ }
+ case COMMAND_DESTROY_PROJECTILES_IN_AREA:
+ {
+ CollectParameters(&m_nIp, 6);
+ 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];
+ }
+ UpdateCompareFlag(CProjectileInfo::IsProjectileInRange(infX, supX, infY, supY, infZ, supZ, true));
+ if (CTheScripts::DbgFlag)
+ CTheScripts::DrawDebugCube(infX, infY, infZ, supX, supY, supZ);
+ return 0;
+ }
+ case COMMAND_DROP_MINE:
+ {
+ 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;
+ CPickups::GenerateNewOne(pos, MI_CARMINE, PICKUP_MINE_INACTIVE, 0);
+ return 0;
+ }
+ case COMMAND_DROP_NAUTICAL_MINE:
+ {
+ 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;
+ CPickups::GenerateNewOne(pos, MI_NAUTICALMINE, PICKUP_MINE_INACTIVE, 0);
+ return 0;
+ }
+ */
+ case COMMAND_IS_CHAR_MODEL:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ UpdateCompareFlag(ScriptParams[1] == pPed->GetModelIndex());
+ return 0;
+ }
+ case COMMAND_LOAD_SPECIAL_MODEL:
+ {
+ CollectParameters(&m_nIp, 1);
+ char name[KEY_LENGTH_IN_SCRIPT];
+ strncpy(name, (const char*)&CTheScripts::ScriptSpace[m_nIp], KEY_LENGTH_IN_SCRIPT);
+ for (int i = 0; i < KEY_LENGTH_IN_SCRIPT; i++)
+ name[i] = tolower(name[i]);
+ CStreaming::RequestSpecialModel(ScriptParams[0], name, STREAMFLAGS_DEPENDENCY | STREAMFLAGS_SCRIPTOWNED);
+ m_nIp += KEY_LENGTH_IN_SCRIPT;
+ 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]));
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ case COMMAND_COS:
+ CollectParameters(&m_nIp, 1);
+ *(float*)&ScriptParams[0] = Cos(DEGTORAD(*(float*)&ScriptParams[0]));
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ case COMMAND_GET_CAR_FORWARD_X:
+ {
+ CollectParameters(&m_nIp, 1);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ float forwardX = pVehicle->GetForward().x / pVehicle->GetForward().Magnitude2D();
+ *(float*)&ScriptParams[0] = forwardX;
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ }
+ case COMMAND_GET_CAR_FORWARD_Y:
+ {
+ CollectParameters(&m_nIp, 1);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ float forwardY = pVehicle->GetForward().y / pVehicle->GetForward().Magnitude2D();
+ *(float*)&ScriptParams[0] = forwardY;
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ }
+ case COMMAND_CHANGE_GARAGE_TYPE:
+ CollectParameters(&m_nIp, 2);
+ CGarages::ChangeGarageType(ScriptParams[0], ScriptParams[1], 0);
+ return 0;
+ /*
+ case COMMAND_ACTIVATE_CRUSHER_CRANE:
+ {
+ CollectParameters(&m_nIp, 10);
+ float infX = *(float*)&ScriptParams[2];
+ float infY = *(float*)&ScriptParams[3];
+ float supX = *(float*)&ScriptParams[4];
+ float supY = *(float*)&ScriptParams[5];
+ if (infX > supX) {
+ infX = *(float*)&ScriptParams[4];
+ supX = *(float*)&ScriptParams[2];
+ }
+ if (infY > supY) {
+ infY = *(float*)&ScriptParams[5];
+ supY = *(float*)&ScriptParams[3];
+ }
+ CCranes::ActivateCrane(infX, supX, infY, supY,
+ *(float*)&ScriptParams[6], *(float*)&ScriptParams[7], *(float*)&ScriptParams[8],
+ DEGTORAD(*(float*)&ScriptParams[9]), true, false,
+ *(float*)&ScriptParams[0], *(float*)&ScriptParams[1]);
+ return 0;
+ }
+ case COMMAND_PRINT_WITH_2_NUMBERS:
+ {
+ wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ CollectParameters(&m_nIp, 4);
+ 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);
+ CollectParameters(&m_nIp, 4);
+ 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);
+ CollectParameters(&m_nIp, 4);
+ 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);
+ CollectParameters(&m_nIp, 5);
+ 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);
+ CollectParameters(&m_nIp, 5);
+ CMessages::AddMessageJumpQWithNumber(text, ScriptParams[3], ScriptParams[4], ScriptParams[0], ScriptParams[1], ScriptParams[2], -1, -1, -1);
+ return 0;
+ }
+ case COMMAND_PRINT_WITH_3_NUMBERS_SOON:
+ {
+ wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ CollectParameters(&m_nIp, 5);
+ 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);
+ CollectParameters(&m_nIp, 6);
+ 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);
+ CollectParameters(&m_nIp, 6);
+ CMessages::AddMessageJumpQWithNumber(text, ScriptParams[4], ScriptParams[5], ScriptParams[0], ScriptParams[1], ScriptParams[2], ScriptParams[3], -1, -1);
+ return 0;
+ }
+ case COMMAND_PRINT_WITH_4_NUMBERS_SOON:
+ {
+ wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ CollectParameters(&m_nIp, 6);
+ CMessages::AddMessageSoonWithNumber(text, ScriptParams[4], ScriptParams[5], ScriptParams[0], ScriptParams[1], ScriptParams[2], ScriptParams[3], -1, -1);
+ return 0;
+ }
+ case COMMAND_PRINT_WITH_5_NUMBERS:
+ {
+ wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ CollectParameters(&m_nIp, 7);
+ CMessages::AddMessageWithNumber(text, ScriptParams[5], ScriptParams[6], ScriptParams[0], ScriptParams[1], ScriptParams[2], ScriptParams[3], ScriptParams[4], -1);
+ return 0;
+ }
+ case COMMAND_PRINT_WITH_5_NUMBERS_NOW:
+ {
+ wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ CollectParameters(&m_nIp, 7);
+ CMessages::AddMessageJumpQWithNumber(text, ScriptParams[5], ScriptParams[6], ScriptParams[0], ScriptParams[1], ScriptParams[2], ScriptParams[3], ScriptParams[4], -1);
+ return 0;
+ }
+ case COMMAND_PRINT_WITH_5_NUMBERS_SOON:
+ {
+ wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ CollectParameters(&m_nIp, 7);
+ 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);
+ CollectParameters(&m_nIp, 8);
+ 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);
+ CollectParameters(&m_nIp, 8);
+ CMessages::AddMessageJumpQWithNumber(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_SOON:
+ {
+ wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ CollectParameters(&m_nIp, 8);
+ CMessages::AddMessageSoonWithNumber(text, ScriptParams[6], ScriptParams[7], ScriptParams[0], ScriptParams[1], ScriptParams[2], ScriptParams[3], ScriptParams[4], ScriptParams[5]);
+ return 0;
+ }
+ case COMMAND_SET_CHAR_OBJ_FOLLOW_CHAR_IN_FORMATION:
+ {
+ CollectParameters(&m_nIp, 3);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ CPed* pTargetPed = CPools::GetPedPool()->GetAt(ScriptParams[1]);
+ pPed->bScriptObjectiveCompleted = false;
+ pPed->SetObjective(OBJECTIVE_FOLLOW_CHAR_IN_FORMATION, pTargetPed);
+ pPed->SetFormation((eFormation)ScriptParams[2]);
+ return 0;
+ }
+ */
+ case COMMAND_PLAYER_MADE_PROGRESS:
+ CollectParameters(&m_nIp, 1);
+ CStats::ProgressMade += ScriptParams[0];
+ return 0;
+ 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);
+ CStats::MaximumJumpDistance = Max(CStats::MaximumJumpDistance, *(float*)&ScriptParams[0]);
+ return 0;
+ case COMMAND_REGISTER_JUMP_HEIGHT:
+ CollectParameters(&m_nIp, 1);
+ CStats::MaximumJumpHeight = Max(CStats::MaximumJumpHeight, *(float*)&ScriptParams[0]);
+ return 0;
+ case COMMAND_REGISTER_JUMP_FLIPS:
+ CollectParameters(&m_nIp, 1);
+ CStats::MaximumJumpFlips = Max(CStats::MaximumJumpFlips, ScriptParams[0]);
+ return 0;
+ case COMMAND_REGISTER_JUMP_SPINS:
+ CollectParameters(&m_nIp, 1);
+ CStats::MaximumJumpSpins = Max(CStats::MaximumJumpSpins, ScriptParams[0]);
+ return 0;
+ case COMMAND_REGISTER_JUMP_STUNT:
+ CollectParameters(&m_nIp, 1);
+ CStats::BestStuntJump = Max(CStats::BestStuntJump, ScriptParams[0]);
+ return 0;
+ case COMMAND_REGISTER_UNIQUE_JUMP_FOUND:
+ ++CStats::NumberOfUniqueJumpsFound;
+ return 0;
+ case COMMAND_SET_UNIQUE_JUMPS_TOTAL:
+ CollectParameters(&m_nIp, 1);
+ CStats::TotalNumberOfUniqueJumps = ScriptParams[0];
+ return 0;
+ case COMMAND_REGISTER_PASSENGER_DROPPED_OFF_TAXI:
+ ++CStats::PassengersDroppedOffWithTaxi;
+ return 0;
+ case COMMAND_REGISTER_MONEY_MADE_TAXI:
+ CollectParameters(&m_nIp, 1);
+ CStats::MoneyMadeWithTaxi += ScriptParams[0];
+ return 0;
+ case COMMAND_REGISTER_MISSION_GIVEN:
+ ++CStats::MissionsGiven;
+ return 0;
+ case COMMAND_REGISTER_MISSION_PASSED:
+ {
+ char name[KEY_LENGTH_IN_SCRIPT];
+ strncpy(name, (const char*)&CTheScripts::ScriptSpace[m_nIp], KEY_LENGTH_IN_SCRIPT);
+ m_nIp += KEY_LENGTH_IN_SCRIPT;
+ 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:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ pPed->bIsRunning = (ScriptParams[1] != 0);
+ return 0;
+ }
+ case COMMAND_REMOVE_ALL_SCRIPT_FIRES:
+ gFireManager.RemoveAllScriptFires();
+ return 0;
+ /*
+ case COMMAND_IS_FIRST_CAR_COLOUR:
+ {
+ CollectParameters(&m_nIp, 2);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ UpdateCompareFlag(pVehicle->m_currentColour1 == ScriptParams[1]);
+ return 0;
+ }
+ case COMMAND_IS_SECOND_CAR_COLOUR:
+ {
+ CollectParameters(&m_nIp, 2);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ 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");
+ 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");
+ 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:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ CPed* pLeader = CPools::GetPedPool()->GetAt(ScriptParams[1]);
+ script_assert(pPed);
+ script_assert(pLeader);
+ UpdateCompareFlag(pPed->m_leader == pLeader);
+ return 0;
+ }
+ default:
+ script_assert(0);
+ }
+ return -1;
+}
diff --git a/src/control/Script4.cpp b/src/control/Script4.cpp
new file mode 100644
index 00000000..ba481b52
--- /dev/null
+++ b/src/control/Script4.cpp
@@ -0,0 +1,2334 @@
+#include "common.h"
+
+#include "Script.h"
+#include "ScriptCommands.h"
+
+#include "AnimBlendAssociation.h"
+#include "BulletInfo.h"
+#include "CarAI.h"
+#include "CarCtrl.h"
+#include "CivilianPed.h"
+#include "Cranes.h"
+#include "DMAudio.h"
+#include "Darkel.h"
+#include "Explosion.h"
+#include "Fire.h"
+#include "Frontend.h"
+#include "Garages.h"
+#include "General.h"
+#include "Heli.h"
+#include "Hud.h"
+#include "Messages.h"
+#include "ParticleObject.h"
+#include "PedRoutes.h"
+#include "Phones.h"
+#include "Pickups.h"
+#include "Plane.h"
+#include "Pools.h"
+#include "Population.h"
+#include "Radar.h"
+#include "Record.h"
+#include "RpAnimBlend.h"
+#include "Rubbish.h"
+#include "SpecialFX.h"
+#include "Stats.h"
+#include "Streaming.h"
+#include "TxdStore.h"
+#include "User.h"
+#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)
+{
+ CMatrix tmp_matrix;
+ switch (command) {
+ case COMMAND_IS_CHAR_IN_PLAYERS_GROUP:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ CPed* pLeader = CWorld::Players[ScriptParams[1]].m_pPed;
+ script_assert(pPed);
+ script_assert(pLeader);
+ UpdateCompareFlag(pPed->m_leader == pLeader);
+ return 0;
+ }
+ case COMMAND_EXPLODE_CHAR_HEAD:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ pPed->InflictDamage(nil, WEAPONTYPE_SNIPERRIFLE, 1000.0f, PEDPIECE_HEAD, 0);
+ return 0;
+ }
+ case COMMAND_EXPLODE_PLAYER_HEAD:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
+ script_assert(pPed);
+ pPed->InflictDamage(nil, WEAPONTYPE_SNIPERRIFLE, 1000.0f, PEDPIECE_HEAD, 0);
+ return 0;
+ }
+ case COMMAND_ANCHOR_BOAT:
+ {
+ 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);
+ return 0;
+ }
+ case COMMAND_SET_ZONE_GROUP:
+ {
+ char zone[KEY_LENGTH_IN_SCRIPT];
+ CTheScripts::ReadTextLabelFromScript(&m_nIp, zone);
+ m_nIp += KEY_LENGTH_IN_SCRIPT;
+ CollectParameters(&m_nIp, 2);
+ int zone_id = CTheZones::FindZoneByLabelAndReturnIndex(zone, ZONE_INFO);
+ if (zone_id < 0) {
+ printf("Couldn't find zone - %s\n", zone);
+ return 0;
+ }
+ CTheZones::SetPedGroup(zone_id, ScriptParams[0], ScriptParams[1]);
+ return 0;
+ }
+ case COMMAND_START_CAR_FIRE:
+ {
+ CollectParameters(&m_nIp, 1);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ ScriptParams[0] = gFireManager.StartScriptFire(pVehicle->GetPosition(), pVehicle, 0.8f, 1);
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ }
+ case COMMAND_START_CHAR_FIRE:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ ScriptParams[0] = gFireManager.StartScriptFire(pPed->GetPosition(), pPed, 0.8f, 1);
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ }
+ case COMMAND_GET_RANDOM_CAR_OF_TYPE_IN_AREA:
+ {
+ 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 (!pVehicle->bUsesCollision)
+ 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);
+ pVehicle->VehicleCreatedBy = MISSION_VEHICLE;
+ ++CCarCtrl::NumMissionCars;
+ --CCarCtrl::NumRandomCars;
+ if (m_bIsMissionScript)
+ CTheScripts::MissionCleanup.AddEntityToList(handle, CLEANUP_CAR);
+ }
+ ScriptParams[0] = handle;
+ 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, ZONE_DEFAULT);
+ if (zone_id != -1)
+ m_nIp += KEY_LENGTH_IN_SCRIPT;
+ CZone* pZone = CTheZones::GetNavigationZone(zone_id);
+ CollectParameters(&m_nIp, 1);
+ int handle = -1;
+ uint32 i = CPools::GetVehiclePool()->GetSize();
+ while (i--) {
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetSlot(i);
+ if (!pVehicle)
+ continue;
+ if (ScriptParams[0] != pVehicle->GetModelIndex() && ScriptParams[0] >= 0)
+ continue;
+ if (pVehicle->VehicleCreatedBy != RANDOM_VEHICLE)
+ continue;
+ if (!CTheZones::PointLiesWithinZone(&pVehicle->GetPosition(), pZone))
+ continue;
+ handle = CPools::GetVehiclePool()->GetIndex(pVehicle);
+ pVehicle->VehicleCreatedBy = MISSION_VEHICLE;
+ ++CCarCtrl::NumMissionCars;
+ --CCarCtrl::NumRandomCars;
+ if (m_bIsMissionScript)
+ CTheScripts::MissionCleanup.AddEntityToList(handle, CLEANUP_CAR);
+ }
+ ScriptParams[0] = handle;
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ }
+ */
+ case COMMAND_HAS_RESPRAY_HAPPENED:
+ {
+ CollectParameters(&m_nIp, 1);
+ UpdateCompareFlag(CGarages::HasResprayHappened(ScriptParams[0]));
+ return 0;
+ }
+ case COMMAND_SET_CAMERA_ZOOM:
+ {
+ CollectParameters(&m_nIp, 1);
+ if (TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_FOLLOWPED)
+ TheCamera.SetZoomValueFollowPedScript(ScriptParams[0]);
+ else if (TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_CAM_ON_A_STRING)
+ TheCamera.SetZoomValueCamStringScript(ScriptParams[0]);
+ return 0;
+ }
+ case COMMAND_CREATE_PICKUP_WITH_AMMO:
+ {
+ CollectParameters(&m_nIp, 6);
+ int16 model = ScriptParams[0];
+ if (model < 0)
+ model = CTheScripts::UsedObjectArray[-model].index;
+ CVector pos = *(CVector*)&ScriptParams[3];
+ 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, model, ScriptParams[1], ScriptParams[2]);
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ }
+ case COMMAND_SET_CAR_RAM_CAR:
+ {
+ CollectParameters(&m_nIp, 2);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ CVehicle* pTarget = CPools::GetVehiclePool()->GetAt(ScriptParams[1]);
+ script_assert(pTarget);
+ CCarAI::TellCarToRamOtherCar(pVehicle, pTarget);
+ return 0;
+ }
+ /*
+ case COMMAND_SET_CAR_BLOCK_CAR:
+ {
+ CollectParameters(&m_nIp, 2);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ CVehicle* pTarget = CPools::GetVehiclePool()->GetAt(ScriptParams[1]);
+ script_assert(pTarget);
+ CCarAI::TellCarToBlockOtherCar(pVehicle, pTarget);
+ return 0;
+ }
+ case COMMAND_SET_CHAR_OBJ_CATCH_TRAIN:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ pPed->bScriptObjectiveCompleted = false;
+ pPed->SetObjective(OBJECTIVE_CATCH_TRAIN);
+ return 0;
+ }
+ */
+ //case COMMAND_SET_COLL_OBJ_CATCH_TRAIN:
+ case COMMAND_SET_PLAYER_NEVER_GETS_TIRED:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPlayerInfo* pPlayer = &CWorld::Players[ScriptParams[0]];
+ pPlayer->m_bInfiniteSprint = (ScriptParams[1] != 0);
+ return 0;
+ }
+ case COMMAND_SET_PLAYER_FAST_RELOAD:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPlayerInfo* pPlayer = &CWorld::Players[ScriptParams[0]];
+ pPlayer->m_bFastReload = (ScriptParams[1] != 0);
+ return 0;
+ }
+ case COMMAND_SET_CHAR_BLEEDING:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ pPed->bPedIsBleeding = (ScriptParams[1] != 0);
+ return 0;
+ }
+ /*
+ case COMMAND_SET_CAR_FUNNY_SUSPENSION:
+ {
+ CollectParameters(&m_nIp, 2);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ // no action
+ return 0;
+ }
+ case COMMAND_SET_CAR_BIG_WHEELS:
+ {
+ 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->bBigWheels = (ScriptParams[1] != 0);
+ return 0;
+ }
+ */
+ case COMMAND_SET_FREE_RESPRAYS:
+ CollectParameters(&m_nIp, 1);
+ CGarages::SetFreeResprays(ScriptParams[0] != 0);
+ return 0;
+ case COMMAND_SET_PLAYER_VISIBLE:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
+ script_assert(pPed);
+ pPed->bIsVisible = (ScriptParams[1] != 0);
+ return 0;
+ }
+ case COMMAND_SET_CHAR_VISIBLE:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ pPed->bIsVisible = (ScriptParams[1] != 0);
+ return 0;
+ }
+ /*
+ case COMMAND_SET_CAR_VISIBLE:
+ {
+ CollectParameters(&m_nIp, 2);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ pVehicle->bIsVisible = (ScriptParams[1] != 0);
+ return 0;
+ }
+ */
+ case COMMAND_IS_AREA_OCCUPIED:
+ {
+ CollectParameters(&m_nIp, 11);
+ 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];
+ }
+ int16 total;
+ CWorld::FindObjectsIntersectingCube(CVector(infX, infY, infZ), CVector(supX, supY, supZ), &total, 2, nil,
+ !!ScriptParams[6], !!ScriptParams[7], !!ScriptParams[8], !!ScriptParams[9], !!ScriptParams[10]);
+ UpdateCompareFlag(total > 0);
+ return 0;
+ }
+ /*
+ case COMMAND_START_DRUG_RUN:
+ CPlane::CreateIncomingCesna();
+ return 0;
+ case COMMAND_HAS_DRUG_RUN_BEEN_COMPLETED:
+ UpdateCompareFlag(CPlane::HasCesnaLanded());
+ return 0;
+ case COMMAND_HAS_DRUG_PLANE_BEEN_SHOT_DOWN:
+ UpdateCompareFlag(CPlane::HasCesnaBeenDestroyed());
+ return 0;
+ case COMMAND_SAVE_PLAYER_FROM_FIRES:
+ CollectParameters(&m_nIp, 1);
+ gFireManager.ExtinguishPoint(CWorld::Players[ScriptParams[0]].GetPos(), 3.0f);
+ return 0;
+ */
+ case COMMAND_DISPLAY_TEXT:
+ {
+ CollectParameters(&m_nIp, 2);
+ wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ CTheScripts::IntroTextLines[CTheScripts::NumberOfIntroTextLinesThisFrame].m_fAtX = *(float*)&ScriptParams[0];
+ CTheScripts::IntroTextLines[CTheScripts::NumberOfIntroTextLinesThisFrame].m_fAtY = *(float*)&ScriptParams[1];
+ uint16 len = CMessages::GetWideStringLength(text);
+ for (uint16 i = 0; i < len; i++)
+ CTheScripts::IntroTextLines[CTheScripts::NumberOfIntroTextLinesThisFrame].m_Text[i] = text[i];
+ for (uint16 i = len; i < SCRIPT_TEXT_MAX_LENGTH; i++)
+ CTheScripts::IntroTextLines[CTheScripts::NumberOfIntroTextLinesThisFrame].m_Text[i] = 0;
+ ++CTheScripts::NumberOfIntroTextLinesThisFrame;
+ return 0;
+ }
+ case COMMAND_SET_TEXT_SCALE:
+ {
+ CollectParameters(&m_nIp, 2);
+ CTheScripts::IntroTextLines[CTheScripts::NumberOfIntroTextLinesThisFrame].m_fScaleX = *(float*)&ScriptParams[0];
+ CTheScripts::IntroTextLines[CTheScripts::NumberOfIntroTextLinesThisFrame].m_fScaleY = *(float*)&ScriptParams[1];
+ return 0;
+ }
+ case COMMAND_SET_TEXT_COLOUR:
+ {
+ CollectParameters(&m_nIp, 4);
+ CTheScripts::IntroTextLines[CTheScripts::NumberOfIntroTextLinesThisFrame].m_sColor =
+ CRGBA(ScriptParams[0], ScriptParams[1], ScriptParams[2], ScriptParams[3]);
+ return 0;
+ }
+ case COMMAND_SET_TEXT_JUSTIFY:
+ {
+ CollectParameters(&m_nIp, 1);
+ CTheScripts::IntroTextLines[CTheScripts::NumberOfIntroTextLinesThisFrame].m_bJustify = (ScriptParams[0] != 0);
+ return 0;
+ }
+ case COMMAND_SET_TEXT_CENTRE:
+ {
+ CollectParameters(&m_nIp, 1);
+ CTheScripts::IntroTextLines[CTheScripts::NumberOfIntroTextLinesThisFrame].m_bCentered = (ScriptParams[0] != 0);
+ return 0;
+ }
+ case COMMAND_SET_TEXT_WRAPX:
+ {
+ CollectParameters(&m_nIp, 1);
+ 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);
+ CTheScripts::IntroTextLines[CTheScripts::NumberOfIntroTextLinesThisFrame].m_sBackgroundColor =
+ CRGBA(ScriptParams[0], ScriptParams[1], ScriptParams[2], ScriptParams[3]);
+ return 0;
+ }
+ case COMMAND_SET_TEXT_BACKGROUND_ONLY_TEXT:
+ {
+ CollectParameters(&m_nIp, 1);
+ 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);
+ CTheScripts::IntroTextLines[CTheScripts::NumberOfIntroTextLinesThisFrame].m_nFont = ScriptParams[0];
+ return 0;
+ }
+ case COMMAND_INDUSTRIAL_PASSED:
+ CStats::IndustrialPassed = true;
+ DMAudio.PlayRadioAnnouncement(STREAMED_SOUND_ANNOUNCE_COMMERCIAL_OPEN);
+ return 0;
+ case COMMAND_COMMERCIAL_PASSED:
+ CStats::CommercialPassed = true;
+ DMAudio.PlayRadioAnnouncement(STREAMED_SOUND_ANNOUNCE_SUBURBAN_OPEN);
+ return 0;
+ case COMMAND_SUBURBAN_PASSED:
+ CStats::SuburbanPassed = true;
+ return 0;
+ */
+ case COMMAND_ROTATE_OBJECT:
+ {
+ CollectParameters(&m_nIp, 4);
+ CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
+ script_assert(pObject);
+ float heading = LimitAngleOnCircle(
+ RADTODEG(Atan2(-pObject->GetForward().x, pObject->GetForward().y)));
+ float headingTarget = *(float*)&ScriptParams[1];
+#ifdef FIX_BUGS
+ float rotateBy = *(float*)&ScriptParams[2] * CTimer::GetTimeStepFix();
+#else
+ float rotateBy = *(float*)&ScriptParams[2];
+#endif
+ if (headingTarget == heading) { // using direct comparasion here is fine
+ UpdateCompareFlag(true);
+ return 0;
+ }
+ float angleClockwise = LimitAngleOnCircle(headingTarget - heading);
+ float angleCounterclockwise = LimitAngleOnCircle(heading - headingTarget);
+ float newHeading;
+ if (angleClockwise < angleCounterclockwise)
+ newHeading = rotateBy < angleClockwise ? heading + rotateBy : headingTarget;
+ else
+ newHeading = rotateBy < angleCounterclockwise ? heading - rotateBy : headingTarget;
+ bool obstacleInPath = false;
+ if (ScriptParams[3]) {
+ CVector pos = pObject->GetPosition();
+ tmp_matrix.SetRotateZ(DEGTORAD(newHeading));
+ tmp_matrix.GetPosition() += pos;
+ CColModel* pColModel = pObject->GetColModel();
+ CVector cp1 = tmp_matrix * pColModel->boundingBox.min;
+ CVector cp2 = tmp_matrix * CVector(pColModel->boundingBox.max.x, pColModel->boundingBox.min.y, pColModel->boundingBox.min.z);
+ CVector cp3 = tmp_matrix * CVector(pColModel->boundingBox.min.x, pColModel->boundingBox.max.y, pColModel->boundingBox.min.z);
+ CVector cp4 = tmp_matrix * CVector(pColModel->boundingBox.min.x, pColModel->boundingBox.min.y, pColModel->boundingBox.max.z);
+ int16 collisions;
+ CWorld::FindObjectsIntersectingAngledCollisionBox(pColModel->boundingBox, tmp_matrix, pos,
+ Min(cp1.x, Min(cp2.x, Min(cp3.x, cp4.x))),
+ Min(cp1.y, Min(cp2.y, Min(cp3.y, cp4.y))),
+ Max(cp1.x, Max(cp2.x, Max(cp3.x, cp4.x))),
+ Max(cp1.y, Max(cp2.y, Max(cp3.y, cp4.y))),
+ &collisions, 2, nil, false, true, true, false, false);
+ if (collisions > 0)
+ obstacleInPath = true;
+ }
+ if (obstacleInPath) {
+ UpdateCompareFlag(true);
+ return 0;
+ }
+ pObject->SetHeading(DEGTORAD(newHeading));
+ pObject->GetMatrix().UpdateRW();
+ pObject->UpdateRwFrame();
+ UpdateCompareFlag(newHeading == headingTarget); // using direct comparasion here is fine
+ return 0;
+ }
+ case COMMAND_SLIDE_OBJECT:
+ {
+ CollectParameters(&m_nIp, 8);
+ CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
+ script_assert(pObject);
+ CVector pos = pObject->GetPosition();
+ CVector posTarget = *(CVector*)&ScriptParams[1];
+ 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);
+ return 0;
+ }
+ CVector posDiff = pos - posTarget;
+ CVector newPosition;
+ if (posDiff.x < 0)
+ newPosition.x = -posDiff.x < slideBy.x ? posTarget.x : pos.x + slideBy.x;
+ else
+ newPosition.x = posDiff.x < slideBy.x ? posTarget.x : pos.x - slideBy.x;
+ if (posDiff.y < 0)
+ newPosition.y = -posDiff.y < slideBy.y ? posTarget.y : pos.y + slideBy.y;
+ else
+ newPosition.y = posDiff.y < slideBy.y ? posTarget.y : pos.y - slideBy.y;
+ if (posDiff.z < 0)
+ newPosition.z = -posDiff.z < slideBy.z ? posTarget.z : pos.z + slideBy.z;
+ else
+ newPosition.z = posDiff.z < slideBy.z ? posTarget.z : pos.z - slideBy.z;
+ bool obstacleInPath = false;
+ if (ScriptParams[7]) {
+ tmp_matrix = pObject->GetMatrix();
+ tmp_matrix.GetPosition() = newPosition;
+ CColModel* pColModel = pObject->GetColModel();
+ CVector cp1 = tmp_matrix * pColModel->boundingBox.min;
+ CVector cp2 = tmp_matrix * CVector(pColModel->boundingBox.max.x, pColModel->boundingBox.min.y, pColModel->boundingBox.min.z);
+ CVector cp3 = tmp_matrix * CVector(pColModel->boundingBox.min.x, pColModel->boundingBox.max.y, pColModel->boundingBox.min.z);
+ CVector cp4 = tmp_matrix * CVector(pColModel->boundingBox.min.x, pColModel->boundingBox.min.y, pColModel->boundingBox.max.z);
+ int16 collisions;
+ CWorld::FindObjectsIntersectingAngledCollisionBox(pColModel->boundingBox, tmp_matrix, newPosition,
+ Min(cp1.x, Min(cp2.x, Min(cp3.x, cp4.x))),
+ Min(cp1.y, Min(cp2.y, Min(cp3.y, cp4.y))),
+ Max(cp1.x, Max(cp2.x, Max(cp3.x, cp4.x))),
+ Max(cp1.y, Max(cp2.y, Max(cp3.y, cp4.y))),
+ &collisions, 2, nil, false, true, true, false, false);
+ if (collisions > 0)
+ obstacleInPath = true;
+ }
+ if (obstacleInPath) {
+ UpdateCompareFlag(true);
+ return 0;
+ }
+ pObject->Teleport(newPosition);
+ UpdateCompareFlag(newPosition == posTarget); // using direct comparasion here is fine
+ return 0;
+ }
+ case COMMAND_REMOVE_CHAR_ELEGANTLY:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ if (pPed && pPed->CharCreatedBy == MISSION_CHAR){
+ CWorld::RemoveReferencesToDeletedObject(pPed);
+ 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)
+ CTheScripts::MissionCleanup.RemoveEntityFromList(ScriptParams[0], CLEANUP_CHAR);
+ return 0;
+ }
+ case COMMAND_SET_CHAR_STAY_IN_SAME_PLACE:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ 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);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ char name[KEY_LENGTH_IN_SCRIPT];
+ CTheScripts::ReadTextLabelFromScript(&m_nIp, name);
+ for (int i = 0; i < KEY_LENGTH_IN_SCRIPT; i++)
+ name[i] = tolower(name[i]);
+ m_nIp += KEY_LENGTH_IN_SCRIPT;
+ pPed->Undress(name);
+ return 0;
+ }
+ case COMMAND_DRESS_CHAR:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ pPed->Dress();
+ return 0;
+ }
+ /*
+ case COMMAND_START_CHASE_SCENE:
+ CollectParameters(&m_nIp, 1);
+ CTimer::Suspend();
+ CStreaming::DeleteAllRwObjects();
+ CRecordDataForChase::StartChaseScene(*(float*)&ScriptParams[0]);
+ CTimer::Resume();
+ return 0;
+ case COMMAND_STOP_CHASE_SCENE:
+ CRecordDataForChase::CleanUpChaseScene();
+ return 0;
+ case COMMAND_IS_EXPLOSION_IN_AREA:
+ {
+ CollectParameters(&m_nIp, 7);
+ float infX = *(float*)&ScriptParams[1];
+ float infY = *(float*)&ScriptParams[2];
+ float infZ = *(float*)&ScriptParams[3];
+ float supX = *(float*)&ScriptParams[4];
+ float supY = *(float*)&ScriptParams[5];
+ float supZ = *(float*)&ScriptParams[6];
+ if (infX > supX) {
+ infX = *(float*)&ScriptParams[4];
+ supX = *(float*)&ScriptParams[1];
+ }
+ if (infY > supY) {
+ infY = *(float*)&ScriptParams[5];
+ supY = *(float*)&ScriptParams[2];
+ }
+ if (infZ > supZ) {
+ infZ = *(float*)&ScriptParams[6];
+ supZ = *(float*)&ScriptParams[3];
+ }
+ UpdateCompareFlag(CExplosion::TestForExplosionInArea((eExplosionType)ScriptParams[0],
+ infX, supX, infY, supY, infZ, supZ));
+ return 0;
+ }
+ case COMMAND_IS_EXPLOSION_IN_ZONE:
+ {
+ CollectParameters(&m_nIp, 1);
+ char zone[KEY_LENGTH_IN_SCRIPT];
+ CTheScripts::ReadTextLabelFromScript(&m_nIp, zone);
+ int zone_id = CTheZones::FindZoneByLabelAndReturnIndex(zone, ZONE_DEFAULT);
+ if (zone_id != -1)
+ m_nIp += KEY_LENGTH_IN_SCRIPT;
+ 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;
+ }
+ case COMMAND_START_DRUG_DROP_OFF:
+ CPlane::CreateDropOffCesna();
+ return 0;
+ case COMMAND_HAS_DROP_OFF_PLANE_BEEN_SHOT_DOWN:
+ UpdateCompareFlag(CPlane::HasDropOffCesnaBeenShotDown());
+ return 0;
+ case COMMAND_FIND_DROP_OFF_PLANE_COORDINATES:
+ {
+ CVector pos = CPlane::FindDropOffCesnaCoordinates();
+ *(CVector*)&ScriptParams[0] = pos;
+ StoreParameters(&m_nIp, 3);
+ return 0;
+ }
+ case COMMAND_CREATE_FLOATING_PACKAGE:
+ {
+ 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;
+ ScriptParams[0] = CPickups::GenerateNewOne(pos, MI_FLOATPACKAGE1, PICKUP_FLOATINGPACKAGE, 0);
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ }
+ */
+ case COMMAND_PLACE_OBJECT_RELATIVE_TO_CAR:
+ {
+ CollectParameters(&m_nIp, 5);
+ CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
+ script_assert(pObject);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[1]);
+ script_assert(pVehicle);
+ CVector offset = *(CVector*)&ScriptParams[2];
+ CPhysical::PlacePhysicalRelativeToOtherPhysical(pVehicle, pObject, offset);
+ return 0;
+ }
+ case COMMAND_MAKE_OBJECT_TARGETTABLE:
+ {
+ CollectParameters(&m_nIp, 1);
+ CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
+ script_assert(pObject);
+ CPlayerPed* pPlayerPed = CWorld::Players[CWorld::PlayerInFocus].m_pPed;
+ script_assert(pPlayerPed);
+ pPlayerPed->MakeObjectTargettable(ScriptParams[0]);
+ return 0;
+ }
+ case COMMAND_ADD_ARMOUR_TO_PLAYER:
+ {
+ 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, CWorld::Players[ScriptParams[0]].m_nMaxArmour);
+ return 0;
+ }
+ case COMMAND_ADD_ARMOUR_TO_CHAR:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ pPed->m_fArmour = clamp(pPed->m_fArmour + ScriptParams[1], 0.0f, 100.0f);
+ return 0;
+ }
+ case COMMAND_OPEN_GARAGE:
+ {
+ CollectParameters(&m_nIp, 1);
+ CGarages::OpenGarage(ScriptParams[0]);
+ return 0;
+ }
+ case COMMAND_CLOSE_GARAGE:
+ {
+ CollectParameters(&m_nIp, 1);
+ CGarages::CloseGarage(ScriptParams[0]);
+ return 0;
+ }
+ case COMMAND_WARP_CHAR_FROM_CAR_TO_COORD:
+ {
+ CollectParameters(&m_nIp, 4);
+ CPed *pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ CVector pos = *(CVector*)&ScriptParams[1];
+ if (pos.z <= MAP_Z_LOW_LIMIT)
+ pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
+ if (pPed->bInVehicle){
+ if (pPed->m_pMyVehicle->bIsBus)
+ pPed->bRenderPedInCar = true;
+ if (pPed->m_pMyVehicle->pDriver == pPed){
+ pPed->m_pMyVehicle->RemoveDriver();
+ 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);
+ }
+ 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->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, 1000.0f);
+ pos.z += pPed->GetDistanceFromCentreOfMassToBaseOfModel();
+ pPed->Teleport(pos);
+ CTheScripts::ClearSpaceForMissionEntity(pos, pPed);
+ return 0;
+ }
+ case COMMAND_SET_VISIBILITY_OF_CLOSEST_OBJECT_OF_TYPE:
+ {
+ CollectParameters(&m_nIp, 6);
+ CVector pos = *(CVector*)&ScriptParams[0];
+ if (pos.z <= MAP_Z_LOW_LIMIT)
+ pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
+ float range = *(float*)&ScriptParams[3];
+ int mi = ScriptParams[4] < 0 ? CTheScripts::UsedObjectArray[-ScriptParams[4]].index : ScriptParams[4];
+ int16 total;
+ CEntity* apEntities[16];
+ CWorld::FindObjectsOfTypeInRange(mi, pos, range, true, &total, 16, apEntities, true, false, false, true, true);
+ 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::GetLevelFromPosition(&pos)), pos, range, true, &total, 16, apEntities);
+ CEntity* pClosestEntity = nil;
+ float min_dist = 2.0f * range;
+ for (int i = 0; i < total; i++) {
+ float dist = (apEntities[i]->GetPosition() - pos).Magnitude();
+ if (dist < min_dist) {
+ min_dist = dist;
+ pClosestEntity = apEntities[i];
+ }
+ }
+ if (pClosestEntity) {
+ pClosestEntity->bIsVisible = (ScriptParams[5] != 0);
+ CTheScripts::AddToInvisibilitySwapArray(pClosestEntity, ScriptParams[5] != 0);
+ }
+ return 0;
+ }
+ /*
+ case COMMAND_HAS_CHAR_SPOTTED_CHAR:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ CPed* pTarget = CPools::GetPedPool()->GetAt(ScriptParams[1]);
+ script_assert(pTarget);
+ UpdateCompareFlag(pPed->OurPedCanSeeThisOne(pTarget));
+ return 0;
+ }
+ */
+ case COMMAND_SET_CHAR_OBJ_HAIL_TAXI:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ pPed->bScriptObjectiveCompleted = false;
+ pPed->SetObjective(OBJECTIVE_HAIL_TAXI);
+ return 0;
+ }
+ case COMMAND_HAS_OBJECT_BEEN_DAMAGED:
+ {
+ CollectParameters(&m_nIp, 1);
+ CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
+ script_assert(pObject);
+ UpdateCompareFlag(pObject->bRenderDamaged || !pObject->bIsVisible);
+ return 0;
+ }
+ /*
+ case COMMAND_START_KILL_FRENZY_HEADSHOT:
+ {
+ wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ CollectParameters(&m_nIp, 8);
+ CDarkel::StartFrenzy((eWeaponType)ScriptParams[0], ScriptParams[1], ScriptParams[2],
+ ScriptParams[3], text, ScriptParams[4], ScriptParams[5],
+ ScriptParams[6], ScriptParams[7] != 0, true);
+ return 0;
+ }
+ case COMMAND_ACTIVATE_MILITARY_CRANE:
+ {
+ CollectParameters(&m_nIp, 10);
+ float infX = *(float*)&ScriptParams[2];
+ float infY = *(float*)&ScriptParams[3];
+ float supX = *(float*)&ScriptParams[4];
+ float supY = *(float*)&ScriptParams[5];
+ if (infX > supX) {
+ infX = *(float*)&ScriptParams[4];
+ supX = *(float*)&ScriptParams[2];
+ }
+ if (infY > supY) {
+ infY = *(float*)&ScriptParams[5];
+ supY = *(float*)&ScriptParams[3];
+ }
+ CCranes::ActivateCrane(infX, supX, infY, supY,
+ *(float*)&ScriptParams[6], *(float*)&ScriptParams[7], *(float*)&ScriptParams[8],
+ DEGTORAD(*(float*)&ScriptParams[9]), false, true,
+ *(float*)&ScriptParams[0], *(float*)&ScriptParams[1]);
+ return 0;
+ }
+ */
+ case COMMAND_WARP_PLAYER_INTO_CAR:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
+ script_assert(pPed);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[1]);
+ script_assert(pVehicle);
+ pPed->SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, pVehicle);
+ pPed->WarpPedIntoCar(pVehicle);
+ return 0;
+ }
+ case COMMAND_WARP_CHAR_INTO_CAR:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[1]);
+ script_assert(pVehicle);
+ pPed->SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, pVehicle);
+ pPed->WarpPedIntoCar(pVehicle);
+ return 0;
+ }
+ //case COMMAND_SWITCH_CAR_RADIO:
+ //case COMMAND_SET_AUDIO_STREAM:
+ case COMMAND_PRINT_WITH_2_NUMBERS_BIG:
+ {
+ wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ CollectParameters(&m_nIp, 4);
+ 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);
+ CollectParameters(&m_nIp, 5);
+ CMessages::AddBigMessageWithNumber(text, ScriptParams[3], ScriptParams[4] - 1, ScriptParams[0], ScriptParams[1], ScriptParams[2], -1, -1, -1);
+ return 0;
+ }
+ case COMMAND_PRINT_WITH_4_NUMBERS_BIG:
+ {
+ wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ CollectParameters(&m_nIp, 6);
+ CMessages::AddBigMessageWithNumber(text, ScriptParams[4], ScriptParams[5] - 1, ScriptParams[0], ScriptParams[1], ScriptParams[2], ScriptParams[3], -1, -1);
+ return 0;
+ }
+ case COMMAND_PRINT_WITH_5_NUMBERS_BIG:
+ {
+ wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ CollectParameters(&m_nIp, 7);
+ CMessages::AddBigMessageWithNumber(text, ScriptParams[5], ScriptParams[6] - 1, ScriptParams[0], ScriptParams[1], ScriptParams[2], ScriptParams[3], ScriptParams[4], -1);
+ return 0;
+ }
+ case COMMAND_PRINT_WITH_6_NUMBERS_BIG:
+ {
+ wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ CollectParameters(&m_nIp, 8);
+ 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);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ pPed->SetWaitState((eWaitState)ScriptParams[1], ScriptParams[2] >= 0 ? &ScriptParams[2] : nil);
+ return 0;
+ }
+ 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]);
+ return 0;
+ case COMMAND_PRINT_STRING_IN_STRING:
+ {
+ wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ wchar* string = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ CollectParameters(&m_nIp, 2);
+ CMessages::AddMessageWithString(text, ScriptParams[0], ScriptParams[1], string);
+ return 0;
+ }
+ */
+ case COMMAND_CREATE_RANDOM_CHAR:
+ {
+ CollectParameters(&m_nIp, 3);
+ CZoneInfo zoneinfo;
+ CTheZones::GetZoneInfoForTimeOfDay(&CWorld::Players[CWorld::PlayerInFocus].GetPos(), &zoneinfo);
+ int mi;
+ ePedType pedtype = PEDTYPE_COP;
+ int attempt = 0;
+ while (pedtype != PEDTYPE_CIVMALE && pedtype != PEDTYPE_CIVFEMALE && attempt < 5) {
+ mi = CPopulation::ChooseCivilianOccupation(zoneinfo.pedGroup);
+ if (CModelInfo::GetModelInfo(mi)->GetRwObject())
+ pedtype = ((CPedModelInfo*)(CModelInfo::GetModelInfo(mi)))->m_pedType;
+ attempt++;
+ }
+ if (!CModelInfo::GetModelInfo(mi)->GetRwObject()) {
+ mi = MI_MALE01;
+ pedtype = ((CPedModelInfo*)(CModelInfo::GetModelInfo(mi)))->m_pedType;
+ }
+ CPed* ped = new CCivilianPed(pedtype, mi);
+ 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);
+ pos.z += 1.0f;
+ 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++;
+ ScriptParams[0] = CPools::GetPedPool()->GetIndex(ped);
+ StoreParameters(&m_nIp, 1);
+ if (m_bIsMissionScript)
+ CTheScripts::MissionCleanup.AddEntityToList(ScriptParams[0], CLEANUP_CHAR);
+ return 0;
+ }
+ case COMMAND_SET_CHAR_OBJ_STEAL_ANY_CAR:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ pPed->bScriptObjectiveCompleted = false;
+ pPed->SetObjective(OBJECTIVE_STEAL_ANY_CAR);
+ return 0;
+ }
+ /*
+ case COMMAND_SET_2_REPEATED_PHONE_MESSAGES:
+ {
+ CollectParameters(&m_nIp, 1);
+ wchar* text1 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ wchar* text2 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ gPhoneInfo.SetPhoneMessage_Repeatedly(ScriptParams[0], text1, text2, nil, nil, nil, nil);
+ return 0;
+ }
+ case COMMAND_SET_2_PHONE_MESSAGES:
+ {
+ CollectParameters(&m_nIp, 1);
+ wchar* text1 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ wchar* text2 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ gPhoneInfo.SetPhoneMessage_JustOnce(ScriptParams[0], text1, text2, nil, nil, nil, nil);
+ return 0;
+ }
+ case COMMAND_SET_3_REPEATED_PHONE_MESSAGES:
+ {
+ CollectParameters(&m_nIp, 1);
+ wchar* text1 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ wchar* text2 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ wchar* text3 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ gPhoneInfo.SetPhoneMessage_Repeatedly(ScriptParams[0], text1, text2, text3, nil, nil, nil);
+ return 0;
+ }
+ case COMMAND_SET_3_PHONE_MESSAGES:
+ {
+ CollectParameters(&m_nIp, 1);
+ wchar* text1 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ wchar* text2 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ wchar* text3 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ gPhoneInfo.SetPhoneMessage_JustOnce(ScriptParams[0], text1, text2, text3, nil, nil, nil);
+ return 0;
+ }
+ case COMMAND_SET_4_REPEATED_PHONE_MESSAGES:
+ {
+ CollectParameters(&m_nIp, 1);
+ wchar* text1 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ wchar* text2 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ wchar* text3 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ wchar* text4 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ gPhoneInfo.SetPhoneMessage_Repeatedly(ScriptParams[0], text1, text2, text3, text4, nil, nil);
+ return 0;
+ }
+ case COMMAND_SET_4_PHONE_MESSAGES:
+ {
+ CollectParameters(&m_nIp, 1);
+ wchar* text1 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ wchar* text2 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ wchar* text3 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ wchar* text4 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ gPhoneInfo.SetPhoneMessage_JustOnce(ScriptParams[0], text1, text2, text3, text4, nil, nil);
+ return 0;
+ }
+ */
+ case COMMAND_IS_SNIPER_BULLET_IN_AREA:
+ {
+ CollectParameters(&m_nIp, 6);
+ 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];
+ }
+ 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:
+ {
+ CollectParameters(&m_nIp, 4);
+ CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
+ script_assert(pObject);
+ pObject->SetMoveSpeed(*(CVector*)&ScriptParams[1] * METERS_PER_SECOND_TO_GAME_SPEED);
+ return 0;
+ }
+ case COMMAND_SET_OBJECT_COLLISION:
+ {
+ CollectParameters(&m_nIp, 2);
+ CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
+ script_assert(pObject);
+ pObject->bUsesCollision = (ScriptParams[1] != 0);
+ return 0;
+ }
+ case COMMAND_IS_ICECREAM_JINGLE_ON:
+ {
+ CollectParameters(&m_nIp, 1);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ // Adding this check to correspond to command name.
+ // All original game scripts always assume that the vehicle is actually Mr. Whoopee,
+ // but maybe there are mods that use it as "is alarm activated"?
+ script_assert(pVehicle->GetModelIndex() == MI_MRWHOOP);
+ UpdateCompareFlag(pVehicle->m_bSirenOrAlarm);
+ return 0;
+ }
+ default:
+ script_assert(0);
+ }
+ return -1;
+}
+
+int8 CRunningScript::ProcessCommands900To999(int32 command)
+{
+ char str[52];
+ char onscreen_str[KEY_LENGTH_IN_SCRIPT];
+ switch (command) {
+ case COMMAND_PRINT_STRING_IN_STRING_NOW:
+ {
+ wchar* source = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ wchar* pstr = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ CollectParameters(&m_nIp, 2);
+ CMessages::AddMessageJumpQWithString(source, ScriptParams[0], ScriptParams[1], pstr);
+ return 0;
+ }
+ //case COMMAND_PRINT_STRING_IN_STRING_SOON:
+ /*
+ case COMMAND_SET_5_REPEATED_PHONE_MESSAGES:
+ {
+ CollectParameters(&m_nIp, 1);
+ wchar* text1 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ wchar* text2 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ wchar* text3 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ wchar* text4 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ wchar* text5 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ gPhoneInfo.SetPhoneMessage_Repeatedly(ScriptParams[0], text1, text2, text3, text4, text5, nil);
+ return 0;
+ }
+ case COMMAND_SET_5_PHONE_MESSAGES:
+ {
+ CollectParameters(&m_nIp, 1);
+ wchar* text1 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ wchar* text2 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ wchar* text3 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ wchar* text4 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ wchar* text5 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ gPhoneInfo.SetPhoneMessage_JustOnce(ScriptParams[0], text1, text2, text3, text4, text5, nil);
+ return 0;
+ }
+ case COMMAND_SET_6_REPEATED_PHONE_MESSAGES:
+ {
+ CollectParameters(&m_nIp, 1);
+ wchar* text1 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ wchar* text2 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ wchar* text3 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ wchar* text4 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ wchar* text5 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ wchar* text6 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ gPhoneInfo.SetPhoneMessage_Repeatedly(ScriptParams[0], text1, text2, text3, text4, text5, text6);
+ return 0;
+ }
+ case COMMAND_SET_6_PHONE_MESSAGES:
+ {
+ CollectParameters(&m_nIp, 1);
+ wchar* text1 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ wchar* text2 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ wchar* text3 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ wchar* text4 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ wchar* text5 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ wchar* text6 = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ 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);
+ float infX = *(float*)&ScriptParams[0] - *(float*)&ScriptParams[3];
+ float supX = *(float*)&ScriptParams[0] + *(float*)&ScriptParams[3];
+ float infY = *(float*)&ScriptParams[1] - *(float*)&ScriptParams[4];
+ float supY = *(float*)&ScriptParams[1] + *(float*)&ScriptParams[4];
+ float infZ = *(float*)&ScriptParams[2] - *(float*)&ScriptParams[5];
+ float supZ = *(float*)&ScriptParams[2] + *(float*)&ScriptParams[5];
+ if (infX > supX) {
+ float tmp = infX;
+ infX = supX;
+ supX = tmp;
+ }
+ if (infY > supY) {
+ float tmp = infY;
+ infY = supY;
+ supY = tmp;
+ }
+ if (infZ > supZ) {
+ float tmp = infZ;
+ infZ = supZ;
+ supZ = tmp;
+ }
+ int16 total;
+ CWorld::FindMissionEntitiesIntersectingCube(CVector(infX, infY, infZ), CVector(supX, supY, supZ), &total, 2, nil, true, true, true);
+ UpdateCompareFlag(total > 0);
+ 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->AddToMoveSpeed(*(CVector*)&ScriptParams[1] * METERS_PER_SECOND_TO_GAME_SPEED);
+ return 0;
+ }
+ case COMMAND_DRAW_SPRITE:
+ {
+ CollectParameters(&m_nIp, 9);
+ CTheScripts::IntroRectangles[CTheScripts::NumberOfIntroRectanglesThisFrame].m_bIsUsed = true;
+ CTheScripts::IntroRectangles[CTheScripts::NumberOfIntroRectanglesThisFrame].m_nTextureId = ScriptParams[0] - 1;
+ CTheScripts::IntroRectangles[CTheScripts::NumberOfIntroRectanglesThisFrame].m_sRect = CRect(
+ *(float*)&ScriptParams[1], *(float*)&ScriptParams[2], *(float*)&ScriptParams[1] + *(float*)&ScriptParams[3], *(float*)&ScriptParams[2] + *(float*)&ScriptParams[4]);
+ CTheScripts::IntroRectangles[CTheScripts::NumberOfIntroRectanglesThisFrame].m_sColor = CRGBA(ScriptParams[5], ScriptParams[6], ScriptParams[7], ScriptParams[8]);
+ CTheScripts::NumberOfIntroRectanglesThisFrame++;
+ return 0;
+ }
+ case COMMAND_DRAW_RECT:
+ {
+ CollectParameters(&m_nIp, 8);
+ CTheScripts::IntroRectangles[CTheScripts::NumberOfIntroRectanglesThisFrame].m_bIsUsed = true;
+ CTheScripts::IntroRectangles[CTheScripts::NumberOfIntroRectanglesThisFrame].m_nTextureId = -1;
+ CTheScripts::IntroRectangles[CTheScripts::NumberOfIntroRectanglesThisFrame].m_sRect = CRect(
+ *(float*)&ScriptParams[0], *(float*)&ScriptParams[1], *(float*)&ScriptParams[0] + *(float*)&ScriptParams[2], *(float*)&ScriptParams[1] + *(float*)&ScriptParams[3]);
+ CTheScripts::IntroRectangles[CTheScripts::NumberOfIntroRectanglesThisFrame].m_sColor = CRGBA(ScriptParams[4], ScriptParams[5], ScriptParams[6], ScriptParams[7]);
+ CTheScripts::NumberOfIntroRectanglesThisFrame++;
+ return 0;
+ }
+ case COMMAND_LOAD_SPRITE:
+ {
+ 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;
+ int slot = CTxdStore::FindTxdSlot("script");
+ CTxdStore::PushCurrentTxd();
+ CTxdStore::SetCurrentTxd(slot);
+ CTheScripts::ScriptSprites[ScriptParams[0] - 1].SetTexture(str);
+ CTxdStore::PopCurrentTxd();
+ return 0;
+ }
+ case COMMAND_LOAD_TEXTURE_DICTIONARY:
+ {
+ strcpy(str, "models\\");
+ strncpy(str + sizeof("models\\"), (char*)&CTheScripts::ScriptSpace[m_nIp], KEY_LENGTH_IN_SCRIPT);
+ strcat(str, ".txd");
+ m_nIp += KEY_LENGTH_IN_SCRIPT;
+ int slot = CTxdStore::FindTxdSlot("script");
+ if (slot == -1)
+ slot = CTxdStore::AddTxdSlot("script");
+ CTxdStore::LoadTxd(slot, str);
+ CTxdStore::AddRef(slot);
+ return 0;
+ }
+ case COMMAND_REMOVE_TEXTURE_DICTIONARY:
+ {
+ CTheScripts::RemoveScriptTextureDictionary();
+ return 0;
+ }
+ case COMMAND_SET_OBJECT_DYNAMIC:
+ {
+ CollectParameters(&m_nIp, 2);
+ CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
+ script_assert(pObject);
+ if (ScriptParams[1]) {
+ if (pObject->bIsStatic) {
+ pObject->SetIsStatic(false);
+ pObject->AddToMovingList();
+ }
+ }
+ else {
+ if (!pObject->bIsStatic) {
+ pObject->SetIsStatic(true);
+ pObject->RemoveFromMovingList();
+ }
+ }
+ return 0;
+ }
+ /*
+ case COMMAND_SET_CHAR_ANIM_SPEED:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ CAnimBlendAssociation* pAssoc = RpAnimBlendClumpGetFirstAssociation(pPed->GetClump());
+ if (pAssoc)
+ pAssoc->speed = *(float*)&ScriptParams[1];
+ return 0;
+ }
+ */
+ case COMMAND_PLAY_MISSION_PASSED_TUNE:
+ {
+ CollectParameters(&m_nIp, 1);
+ DMAudio.ChangeMusicMode(MUSICMODE_FRONTEND);
+ DMAudio.PlayFrontEndTrack(ScriptParams[0] + STREAMED_SOUND_MISSION_COMPLETED - 1, 0);
+ return 0;
+ }
+ case COMMAND_CLEAR_AREA:
+ {
+ CollectParameters(&m_nIp, 5);
+ CVector pos = *(CVector*)&ScriptParams[0];
+ if (pos.z <= MAP_Z_LOW_LIMIT)
+ pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
+ CWorld::ClearExcitingStuffFromArea(pos, *(float*)&ScriptParams[3], ScriptParams[4]);
+ return 0;
+ }
+ case COMMAND_FREEZE_ONSCREEN_TIMER:
+ CollectParameters(&m_nIp, 1);
+ CUserDisplay::OnscnTimer.m_bDisabled = ScriptParams[0] != 0;
+ return 0;
+ case COMMAND_SWITCH_CAR_SIREN:
+ {
+ CollectParameters(&m_nIp, 2);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ pVehicle->m_bSirenOrAlarm = ScriptParams[1] != 0;
+ return 0;
+ }
+ /*
+ case COMMAND_SWITCH_PED_ROADS_ON_ANGLED:
+ {
+ CollectParameters(&m_nIp, 7);
+ ThePaths.SwitchRoadsInAngledArea(*(float*)&ScriptParams[0], *(float*)&ScriptParams[1], *(float*)&ScriptParams[2],
+ *(float*)&ScriptParams[3], *(float*)&ScriptParams[4], *(float*)&ScriptParams[5], *(float*)&ScriptParams[6], 0, 1);
+ return 0;
+ }
+ case COMMAND_SWITCH_PED_ROADS_OFF_ANGLED:
+ CollectParameters(&m_nIp, 7);
+ ThePaths.SwitchRoadsInAngledArea(*(float*)&ScriptParams[0], *(float*)&ScriptParams[1], *(float*)&ScriptParams[2],
+ *(float*)&ScriptParams[3], *(float*)&ScriptParams[4], *(float*)&ScriptParams[5], *(float*)&ScriptParams[6], 0, 0);
+ return 0;
+ case COMMAND_SWITCH_ROADS_ON_ANGLED:
+ CollectParameters(&m_nIp, 7);
+ ThePaths.SwitchRoadsInAngledArea(*(float*)&ScriptParams[0], *(float*)&ScriptParams[1], *(float*)&ScriptParams[2],
+ *(float*)&ScriptParams[3], *(float*)&ScriptParams[4], *(float*)&ScriptParams[5], *(float*)&ScriptParams[6], 1, 1);
+ return 0;
+ case COMMAND_SWITCH_ROADS_OFF_ANGLED:
+ CollectParameters(&m_nIp, 7);
+ 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);
+ 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:
+ {
+ CollectParameters(&m_nIp, 12);
+ CVector pos = *(CVector*)&ScriptParams[1];
+ if (pos.z <= MAP_Z_LOW_LIMIT)
+ pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
+ float size = Max(0.0f, *(float*)&ScriptParams[7]);
+ eParticleObjectType type = (eParticleObjectType)ScriptParams[0];
+ RwRGBA color;
+ if (type == POBJECT_SMOKE_TRAIL){
+ color.alpha = -1;
+ color.red = ScriptParams[8];
+ color.green = ScriptParams[9];
+ color.blue = ScriptParams[10];
+ }else{
+ color.alpha = color.red = color.blue = color.green = 0;
+ }
+ CVector target = *(CVector*)&ScriptParams[4];
+ CParticleObject::AddObject(type, pos, target, size, ScriptParams[11], color, 1);
+ return 0;
+ }
+ case COMMAND_SET_CHAR_CANT_BE_DRAGGED_OUT:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ pPed->bDontDragMeOutCar = ScriptParams[1] != 0;
+ return 0;
+ }
+ case COMMAND_TURN_CAR_TO_FACE_COORD:
+ {
+ CollectParameters(&m_nIp, 3);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ const CVector& pos = pVehicle->GetPosition();
+ float heading = CGeneral::GetATanOfXY(pos.y - *(float*)&ScriptParams[2], pos.x - *(float*)&ScriptParams[1]) + HALFPI;
+ if (heading > TWOPI)
+ heading -= TWOPI;
+ pVehicle->SetHeading(heading);
+ return 0;
+ }
+ /*
+ case COMMAND_IS_CRANE_LIFTING_CAR:
+ {
+ CollectParameters(&m_nIp, 3);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[2]);
+ UpdateCompareFlag(CCranes::IsThisCarPickedUp(*(float*)&ScriptParams[0], *(float*)&ScriptParams[1], pVehicle));
+ return 0;
+ }
+ */
+ case COMMAND_DRAW_SPHERE:
+ {
+ CollectParameters(&m_nIp, 4);
+ CVector pos = *(CVector*)&ScriptParams[0];
+ if (pos.z <= MAP_Z_LOW_LIMIT)
+ pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
+ C3dMarkers::PlaceMarkerSet((uintptr)this + m_nIp, MARKERTYPE_CYLINDER, pos, *(float*)&ScriptParams[3],
+ SPHERE_MARKER_R, SPHERE_MARKER_G, SPHERE_MARKER_B, SPHERE_MARKER_A,
+ SPHERE_MARKER_PULSE_PERIOD, SPHERE_MARKER_PULSE_FRACTION, 0);
+ return 0;
+ }
+ case COMMAND_SET_CAR_STATUS:
+ {
+ CollectParameters(&m_nIp, 2);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ pVehicle->SetStatus(ScriptParams[1]);
+ return 0;
+ }
+ case COMMAND_IS_CHAR_MALE:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ UpdateCompareFlag(pPed->m_nPedType != PEDTYPE_CIVFEMALE && pPed->m_nPedType != PEDTYPE_PROSTITUTE);
+ return 0;
+ }
+ case COMMAND_SCRIPT_NAME:
+ {
+ 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;
+ strncpy(m_abScriptName, str, KEY_LENGTH_IN_SCRIPT);
+ return 0;
+ }
+ /*
+ case COMMAND_CHANGE_GARAGE_TYPE_WITH_CAR_MODEL:
+ {
+ CollectParameters(&m_nIp, 3);
+ CGarages::ChangeGarageType(ScriptParams[0], ScriptParams[1], ScriptParams[2]);
+ return 0;
+ }
+ case COMMAND_FIND_DRUG_PLANE_COORDINATES:
+ *(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);
+ return 0;
+ case COMMAND_SAVE_FLOAT_TO_DEBUG_FILE:
+ CollectParameters(&m_nIp, 1);
+ return 0;
+ case COMMAND_SAVE_NEWLINE_TO_DEBUG_FILE:
+ return 0;
+ case COMMAND_POLICE_RADIO_MESSAGE:
+ CollectParameters(&m_nIp, 3);
+ DMAudio.PlaySuspectLastSeen(*(float*)&ScriptParams[0], *(float*)&ScriptParams[1], *(float*)&ScriptParams[2]);
+ return 0;
+ case COMMAND_SET_CAR_STRONG:
+ {
+ CollectParameters(&m_nIp, 2);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ pVehicle->bTakeLessDamage = ScriptParams[1] != 0;
+ return 0;
+ }
+ case COMMAND_REMOVE_ROUTE:
+ CollectParameters(&m_nIp, 1);
+ CRouteNode::RemoveRoute(ScriptParams[0]);
+ return 0;
+ case COMMAND_SWITCH_RUBBISH:
+ CollectParameters(&m_nIp, 1);
+ CRubbish::SetVisibility(ScriptParams[0] != 0);
+ return 0;
+ case COMMAND_REMOVE_PARTICLE_EFFECTS_IN_AREA:
+ {
+ CollectParameters(&m_nIp, 6);
+ float x1 = *(float*)&ScriptParams[0];
+ float y1 = *(float*)&ScriptParams[1];
+ float z1 = *(float*)&ScriptParams[2];
+ float x2 = *(float*)&ScriptParams[3];
+ float y2 = *(float*)&ScriptParams[4];
+ float z2 = *(float*)&ScriptParams[5];
+ CParticleObject* tmp = CParticleObject::pCloseListHead;
+ while (tmp) {
+ CParticleObject* next = tmp->m_pNext;
+ if (tmp->IsWithinArea(x1, y1, z1, x2, y2, z2))
+ tmp->RemoveObject();
+ tmp = next;
+ }
+ tmp = CParticleObject::pFarListHead;
+ while (tmp) {
+ CParticleObject* next = tmp->m_pNext;
+ if (tmp->IsWithinArea(x1, y1, z1, x2, y2, z2))
+ tmp->RemoveObject();
+ tmp = next;
+ }
+ return 0;
+ }
+ case COMMAND_SWITCH_STREAMING:
+ CollectParameters(&m_nIp, 1);
+ CStreaming::ms_disableStreaming = ScriptParams[0] == 0;
+ return 0;
+ case COMMAND_IS_GARAGE_OPEN:
+ CollectParameters(&m_nIp, 1);
+ UpdateCompareFlag(CGarages::IsGarageOpen(ScriptParams[0]));
+ return 0;
+ case COMMAND_IS_GARAGE_CLOSED:
+ CollectParameters(&m_nIp, 1);
+ UpdateCompareFlag(CGarages::IsGarageClosed(ScriptParams[0]));
+ return 0;
+ /*
+ case COMMAND_START_CATALINA_HELI:
+ CHeli::StartCatalinaFlyBy();
+ return 0;
+ case COMMAND_CATALINA_HELI_TAKE_OFF:
+ CHeli::CatalinaTakeOff();
+ return 0;
+ case COMMAND_REMOVE_CATALINA_HELI:
+ CHeli::RemoveCatalinaHeli();
+ return 0;
+ case COMMAND_HAS_CATALINA_HELI_BEEN_SHOT_DOWN:
+ UpdateCompareFlag(CHeli::HasCatalinaBeenShotDown());
+ return 0;
+ */
+ case COMMAND_SWAP_NEAREST_BUILDING_MODEL:
+ {
+ CollectParameters(&m_nIp, 6);
+ CVector pos = *(CVector*)&ScriptParams[0];
+ if (pos.z <= MAP_Z_LOW_LIMIT)
+ pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
+ float radius = *(float*)&ScriptParams[3];
+ int mi1 = ScriptParams[4] >= 0 ? ScriptParams[4] : CTheScripts::UsedObjectArray[-ScriptParams[4]].index;
+ int mi2 = ScriptParams[5] >= 0 ? ScriptParams[5] : CTheScripts::UsedObjectArray[-ScriptParams[5]].index;
+ int16 total;
+ CEntity* apEntities[16];
+ CWorld::FindObjectsOfTypeInRange(mi1, pos, radius, true, &total, 16, apEntities, true, false, false, false, false);
+ 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::GetLevelFromPosition(&pos)), pos, radius, true, &total, 16, apEntities);
+ CEntity* pClosestEntity = nil;
+ float min_dist = 2.0f * radius;
+ for (int i = 0; i < total; i++) {
+ float dist = (apEntities[i]->GetPosition() - pos).Magnitude();
+ if (dist < min_dist) {
+ min_dist = dist;
+ pClosestEntity = apEntities[i];
+ }
+ }
+ if (!pClosestEntity) {
+ printf("Failed to find building\n");
+ return 0;
+ }
+ CBuilding* pReplacedBuilding = ((CBuilding*)pClosestEntity);
+ pReplacedBuilding->ReplaceWithNewModel(mi2);
+ CTheScripts::AddToBuildingSwapArray(pReplacedBuilding, mi1, mi2);
+ return 0;
+ }
+ case COMMAND_SWITCH_WORLD_PROCESSING:
+ CollectParameters(&m_nIp, 1);
+ CWorld::bProcessCutsceneOnly = ScriptParams[0] == 0;
+ return 0;
+ case COMMAND_REMOVE_ALL_PLAYER_WEAPONS:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
+ script_assert(pPed);
+ pPed->ClearWeapons();
+ return 0;
+ }
+ /*
+ case COMMAND_GRAB_CATALINA_HELI:
+ {
+ CHeli* pHeli = CHeli::FindPointerToCatalinasHeli();
+ ScriptParams[0] = pHeli ? CPools::GetVehiclePool()->GetIndex(pHeli) : -1;
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ }
+ */
+ case COMMAND_CLEAR_AREA_OF_CARS:
+ {
+ CollectParameters(&m_nIp, 6);
+ 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];
+ }
+ CWorld::ClearCarsFromArea(infX, infY, infZ, supX, supY, supZ);
+ return 0;
+ }
+ case COMMAND_SET_ROTATING_GARAGE_DOOR:
+ CollectParameters(&m_nIp, 1);
+ CGarages::SetGarageDoorToRotate(ScriptParams[0]);
+ return 0;
+ case COMMAND_ADD_SPHERE:
+ {
+ CollectParameters(&m_nIp, 4);
+ CVector pos = *(CVector*)&ScriptParams[0];
+ if (pos.z <= MAP_Z_LOW_LIMIT)
+ pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
+ float radius = *(float*)&ScriptParams[3];
+ CTheScripts::GetActualScriptSphereIndex(CollectNextParameterWithoutIncreasingPC(m_nIp));
+ ScriptParams[0] = CTheScripts::AddScriptSphere((uintptr)this + m_nIp, pos, radius);
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ }
+ case COMMAND_REMOVE_SPHERE:
+ 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);
+ CPlayerPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
+ script_assert(pPed);
+ if (ScriptParams[1]) {
+ pPed->m_pWanted->m_bIgnoredByEveryone = true;
+ CWorld::StopAllLawEnforcersInTheirTracks();
+ }
+ else {
+ pPed->m_pWanted->m_bIgnoredByEveryone = false;
+ }
+ return 0;
+ }
+ case COMMAND_STORE_CAR_CHAR_IS_IN_NO_SAVE:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ CVehicle* pVehicle = pPed->bInVehicle ? pPed->m_pMyVehicle : nil;
+ ScriptParams[0] = CPools::GetVehiclePool()->GetIndex(pVehicle);
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ }
+ case COMMAND_STORE_CAR_PLAYER_IS_IN_NO_SAVE:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
+ script_assert(pPed);
+ CVehicle* pVehicle = pPed->bInVehicle ? pPed->m_pMyVehicle : nil;
+ ScriptParams[0] = CPools::GetVehiclePool()->GetIndex(pVehicle);
+ 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, ScriptParams[0] != 0);
+ return 0;
+ }
+ case COMMAND_DISPLAY_ONSCREEN_COUNTER_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.AddCounter(var, ScriptParams[0], onscreen_str, 0);
+ return 0;
+ }
+ case COMMAND_CREATE_RANDOM_CAR_FOR_CAR_PARK:
+ {
+ CollectParameters(&m_nIp, 4);
+ if (CCarCtrl::NumRandomCars >= 30)
+ return 0;
+ int attempts;
+ int model = -1;
+ int index = CGeneral::GetRandomNumberInRange(0, 50);
+ for (attempts = 0; attempts < 50; attempts++) {
+ if (model != -1)
+ break;
+ model = CStreaming::ms_vehiclesLoaded[index];
+ if (model == -1)
+ continue;
+ 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_HUNTER:
+ case MI_POLICE:
+ case MI_ENFORCER:
+ case MI_SECURICA:
+ case MI_PREDATOR:
+ case MI_BUS:
+ case MI_RHINO:
+ case MI_BARRACKS:
+ case MI_CUBAN:
+ case MI_CHOPPER:
+ case MI_ANGEL:
+ case MI_COACH:
+ case MI_RCBANDIT:
+ 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_TROPIC:
+ case MI_FLATBED:
+ case MI_YANKEE:
+ 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_MANANA:
+ case MI_INFERNUS:
+ case MI_PONY:
+ case MI_CHEETAH:
+ case MI_MOONBEAM:
+ case MI_ESPERANT:
+ case MI_TAXI:
+ case MI_WASHING:
+ case MI_BOBCAT:
+ case MI_BANSHEE:
+ case MI_CABBIE:
+ case MI_STALLION:
+ case MI_RUMPO:
+ 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]);
+ model = -1;
+ break;
+ }
+ }
+ else
+ model = -1;
+ if (++index >= 50)
+ index = 0;
+ }
+ if (model == -1)
+ return 0;
+ CVehicle* car;
+ 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();
+ car->SetPosition(pos);
+ car->SetHeading(DEGTORAD(*(float*)&ScriptParams[3]));
+ CTheScripts::ClearSpaceForMissionEntity(pos, car);
+ car->SetStatus(STATUS_ABANDONED);
+ car->bIsLocked = false;
+ car->bIsCarParkVehicle = true;
+ CCarCtrl::JoinCarWithRoadSystem(car);
+ car->AutoPilot.m_nCarMission = MISSION_NONE;
+ 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);
+ 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];
+ return 0;
+ case COMMAND_SET_CAMERA_IN_FRONT_OF_PLAYER:
+ TheCamera.SetCameraDirectlyInFrontForFollowPed_CamOnAString();
+ return 0;
+ /*
+ case COMMAND_IS_CAR_VISIBLY_DAMAGED:
+ {
+ CollectParameters(&m_nIp, 1);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ UpdateCompareFlag(pVehicle->bIsDamaged);
+ return 0;
+ }
+ */
+ case COMMAND_DOES_OBJECT_EXIST:
+ CollectParameters(&m_nIp, 1);
+ UpdateCompareFlag(CPools::GetObjectPool()->GetAt(ScriptParams[0]));
+ return 0;
+ case COMMAND_LOAD_SCENE:
+ {
+ 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:
+ {
+ CollectParameters(&m_nIp, 3);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ CTheScripts::StuckCars.AddCarToCheck(ScriptParams[0], *(float*)&ScriptParams[1], ScriptParams[2]);
+ return 0;
+ }
+ case COMMAND_REMOVE_STUCK_CAR_CHECK:
+ {
+ CollectParameters(&m_nIp, 1);
+ CTheScripts::StuckCars.RemoveCarFromCheck(ScriptParams[0]);
+ return 0;
+ }
+ case COMMAND_IS_CAR_STUCK:
+ CollectParameters(&m_nIp, 1);
+ 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(ScriptParams[0] - 1, str);
+ return 0;
+ }
+ case COMMAND_HAS_MISSION_AUDIO_LOADED:
+ {
+ CollectParameters(&m_nIp, 1);
+ UpdateCompareFlag(DMAudio.GetMissionAudioLoadingStatus(ScriptParams[0] - 1) == 1);
+ return 0;
+ }
+ case COMMAND_PLAY_MISSION_AUDIO:
+ CollectParameters(&m_nIp, 1);
+ DMAudio.PlayLoadedMissionAudio(ScriptParams[0] - 1);
+ return 0;
+ case COMMAND_HAS_MISSION_AUDIO_FINISHED:
+ {
+ CollectParameters(&m_nIp, 1);
+ UpdateCompareFlag(DMAudio.IsMissionAudioSampleFinished(ScriptParams[0] - 1));
+ return 0;
+ }
+ case COMMAND_GET_CLOSEST_CAR_NODE_WITH_HEADING:
+ {
+ CollectParameters(&m_nIp, 3);
+ CVector pos = *(CVector*)&ScriptParams[0];
+ 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.FindNodeCoorsForScript(node);
+ *(float*)&ScriptParams[3] = ThePaths.FindNodeOrientationForCarPlacement(node);
+ StoreParameters(&m_nIp, 4);
+ return 0;
+ }
+ case COMMAND_HAS_IMPORT_GARAGE_SLOT_BEEN_FILLED:
+ {
+ CollectParameters(&m_nIp, 2);
+ UpdateCompareFlag(CGarages::HasImportExportGarageCollectedThisCar(ScriptParams[0], ScriptParams[1] - 1));
+ return 0;
+ }
+ case COMMAND_CLEAR_THIS_PRINT:
+ {
+ wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ CMessages::ClearThisPrint(text);
+ return 0;
+ }
+ case COMMAND_CLEAR_THIS_BIG_PRINT:
+ {
+ wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ CMessages::ClearThisBigPrint(text);
+ return 0;
+ }
+ case COMMAND_SET_MISSION_AUDIO_POSITION:
+ {
+ 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:
+ {
+ 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 && !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);
+ CObject* pObject = CPickups::aPickUps[CPickups::GetActualPickupIndex(ScriptParams[0])].m_pObject;
+ CRadar::GetActualBlipArrayIndex(CollectNextParameterWithoutIncreasingPC(m_nIp));
+ ScriptParams[0] = CRadar::SetEntityBlip(BLIP_OBJECT, CPools::GetObjectPool()->GetIndex(pObject), ScriptParams[1], (eBlipDisplay)ScriptParams[2]);
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ }
+ */
+ case COMMAND_ADD_BLIP_FOR_PICKUP:
+ {
+ CollectParameters(&m_nIp, 1);
+ CObject* pObject = CPickups::aPickUps[CPickups::GetActualPickupIndex(ScriptParams[0])].m_pObject;
+ CRadar::GetActualBlipArrayIndex(CollectNextParameterWithoutIncreasingPC(m_nIp));
+ int handle = CRadar::SetEntityBlip(BLIP_OBJECT, CPools::GetObjectPool()->GetIndex(pObject), 6, BLIP_DISPLAY_BOTH);
+ CRadar::ChangeBlipScale(handle, 3);
+ ScriptParams[0] = handle;
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ }
+ /*
+ case COMMAND_ADD_SPRITE_BLIP_FOR_PICKUP:
+ {
+ CollectParameters(&m_nIp, 2);
+ CObject* pObject = CPickups::aPickUps[CPickups::GetActualPickupIndex(ScriptParams[0])].m_pObject;
+ CRadar::GetActualBlipArrayIndex(CollectNextParameterWithoutIncreasingPC(m_nIp));
+ int handle = CRadar::SetEntityBlip(BLIP_OBJECT, CPools::GetObjectPool()->GetIndex(pObject), 6, BLIP_DISPLAY_BOTH);
+ CRadar::SetBlipSprite(handle, ScriptParams[1]);
+ ScriptParams[0] = handle;
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ }
+ */
+ case COMMAND_SET_PED_DENSITY_MULTIPLIER:
+ CollectParameters(&m_nIp, 1);
+ CPopulation::PedDensityMultiplier = *(float*)&ScriptParams[0];
+ return 0;
+ case COMMAND_FORCE_RANDOM_PED_TYPE:
+ 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_SET_CHAR_OBJ_LEAVE_ANY_CAR:
+ {
+ CollectParameters(&m_nIp, 1);
+ 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;
+ return 0;
+ case COMMAND_SET_TEXT_RIGHT_JUSTIFY:
+ CollectParameters(&m_nIp, 1);
+ CTheScripts::IntroTextLines[CTheScripts::NumberOfIntroTextLinesThisFrame].m_bRightJustify = ScriptParams[0] != 0;
+ return 0;
+ case COMMAND_PRINT_HELP:
+ {
+ if (CCamera::m_bUseMouse3rdPerson && (
+ strcmp((char*)&CTheScripts::ScriptSpace[m_nIp], "HELP15") == 0 ||
+ strcmp((char*)&CTheScripts::ScriptSpace[m_nIp], "GUN_2A") == 0 ||
+ strcmp((char*)&CTheScripts::ScriptSpace[m_nIp], "GUN_2C") == 0 ||
+ strcmp((char*)&CTheScripts::ScriptSpace[m_nIp], "GUN_2D") == 0)) {
+ m_nIp += KEY_LENGTH_IN_SCRIPT;
+ return 0;
+ }
+ wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ CHud::SetHelpMessage(text, false);
+ return 0;
+ }
+ case COMMAND_CLEAR_HELP:
+ CHud::SetHelpMessage(nil, false);
+ return 0;
+ case COMMAND_FLASH_HUD_OBJECT:
+ CollectParameters(&m_nIp, 1);
+ CHud::m_ItemToFlash = ScriptParams[0];
+ return 0;
+ default:
+ script_assert(0);
+ }
+ return -1;
+}
+
+int32 CTheScripts::GetNewUniqueScriptSphereIndex(int32 index)
+{
+ if (ScriptSphereArray[index].m_Index >= UINT16_MAX - 1)
+ ScriptSphereArray[index].m_Index = 1;
+ else
+ ScriptSphereArray[index].m_Index++;
+ return (uint16)index | ScriptSphereArray[index].m_Index << 16;
+}
+
+int32 CTheScripts::GetActualScriptSphereIndex(int32 index)
+{
+ if (index == -1)
+ return -1;
+ uint16 check = (uint32)index >> 16;
+ uint16 array_idx = index & (0xFFFF);
+ script_assert(array_idx < ARRAY_SIZE(ScriptSphereArray));
+ if (check != ScriptSphereArray[array_idx].m_Index)
+ return -1;
+ return array_idx;
+}
+
+void CTheScripts::DrawScriptSpheres()
+{
+ for (int i = 0; i < MAX_NUM_SCRIPT_SPHERES; i++) {
+ if (ScriptSphereArray[i].m_bInUse)
+ C3dMarkers::PlaceMarkerSet(ScriptSphereArray[i].m_Id, MARKERTYPE_CYLINDER, ScriptSphereArray[i].m_vecCenter, ScriptSphereArray[i].m_fRadius,
+ SPHERE_MARKER_R, SPHERE_MARKER_G, SPHERE_MARKER_B, SPHERE_MARKER_A, SPHERE_MARKER_PULSE_PERIOD, SPHERE_MARKER_PULSE_FRACTION, 0);
+ }
+}
+
+int32 CTheScripts::AddScriptSphere(int32 id, CVector pos, float radius)
+{
+ int16 i = 0;
+ for (i = 0; i < MAX_NUM_SCRIPT_SPHERES; i++) {
+ if (!ScriptSphereArray[i].m_bInUse)
+ break;
+ }
+#ifdef FIX_BUGS
+ if (i == MAX_NUM_SCRIPT_SPHERES)
+ return -1;
+#endif
+ ScriptSphereArray[i].m_bInUse = true;
+ ScriptSphereArray[i].m_Id = id;
+ ScriptSphereArray[i].m_vecCenter = pos;
+ ScriptSphereArray[i].m_fRadius = radius;
+ return GetNewUniqueScriptSphereIndex(i);
+}
+
+void CTheScripts::RemoveScriptSphere(int32 index)
+{
+ index = GetActualScriptSphereIndex(index);
+ if (index == -1)
+ return;
+ ScriptSphereArray[index].m_bInUse = false;
+ ScriptSphereArray[index].m_Id = 0;
+}
+
+void CTheScripts::AddToBuildingSwapArray(CBuilding* pBuilding, int32 old_model, int32 new_model)
+{
+ int i = 0;
+ bool found = false;
+ while (i < MAX_NUM_BUILDING_SWAPS && !found) {
+ if (BuildingSwapArray[i].m_pBuilding == pBuilding)
+ found = true;
+ else
+ i++;
+ }
+ if (found) {
+ if (BuildingSwapArray[i].m_nOldModel == new_model) {
+ BuildingSwapArray[i].m_pBuilding = nil;
+ BuildingSwapArray[i].m_nOldModel = BuildingSwapArray[i].m_nNewModel = -1;
+ }
+ else {
+ BuildingSwapArray[i].m_nNewModel = new_model;
+ }
+ }
+ else {
+ i = 0;
+ while (i < MAX_NUM_BUILDING_SWAPS && !found) {
+ if (BuildingSwapArray[i].m_pBuilding == nil)
+ found = true;
+ else
+ i++;
+ }
+ if (found) {
+ BuildingSwapArray[i].m_pBuilding = pBuilding;
+ BuildingSwapArray[i].m_nNewModel = new_model;
+ BuildingSwapArray[i].m_nOldModel = old_model;
+ }
+ }
+}
+
+void CTheScripts::AddToInvisibilitySwapArray(CEntity* pEntity, bool remove)
+{
+ int i = 0;
+ bool found = false;
+ while (i < MAX_NUM_INVISIBILITY_SETTINGS && !found) {
+ if (InvisibilitySettingArray[i] == pEntity)
+ found = true;
+ else
+ i++;
+ }
+ if (found) {
+ if (remove)
+ InvisibilitySettingArray[i] = nil;
+ }
+ else if (!remove) {
+ i = 0;
+ while (i < MAX_NUM_INVISIBILITY_SETTINGS && !found) {
+ if (InvisibilitySettingArray[i] == nil)
+ found = true;
+ else
+ i++;
+ }
+ if (found)
+ InvisibilitySettingArray[i] = pEntity;
+ }
+}
+
+void CTheScripts::UndoBuildingSwaps()
+{
+ for (int i = 0; i < MAX_NUM_BUILDING_SWAPS; i++) {
+ if (BuildingSwapArray[i].m_pBuilding) {
+ BuildingSwapArray[i].m_pBuilding->ReplaceWithNewModel(BuildingSwapArray[i].m_nOldModel);
+ BuildingSwapArray[i].m_pBuilding = nil;
+ BuildingSwapArray[i].m_nOldModel = BuildingSwapArray[i].m_nNewModel = -1;
+ }
+ }
+}
+
+void CTheScripts::UndoEntityInvisibilitySettings()
+{
+ for (int i = 0; i < MAX_NUM_INVISIBILITY_SETTINGS; i++) {
+ if (InvisibilitySettingArray[i]) {
+ InvisibilitySettingArray[i]->bIsVisible = true;
+ InvisibilitySettingArray[i] = nil;
+ }
+ }
+}
diff --git a/src/control/Script5.cpp b/src/control/Script5.cpp
new file mode 100644
index 00000000..5b7b34c5
--- /dev/null
+++ b/src/control/Script5.cpp
@@ -0,0 +1,2072 @@
+#include "common.h"
+
+#include "Script.h"
+#include "ScriptCommands.h"
+
+#include "CarCtrl.h"
+#include "BulletInfo.h"
+#include "General.h"
+#include "Lines.h"
+#include "Messages.h"
+#include "Pad.h"
+#include "Pools.h"
+#include "Population.h"
+#include "RpAnimBlend.h"
+#include "Shadows.h"
+#include "SpecialFX.h"
+#include "World.h"
+#include "main.h"
+
+void CRunningScript::UpdateCompareFlag(bool flag)
+{
+ if (m_bNotFlag)
+ flag = !flag;
+ if (m_nAndOrState == ANDOR_NONE) {
+ m_bCondResult = flag;
+ return;
+ }
+ if (m_nAndOrState >= ANDS_1 && m_nAndOrState <= ANDS_8) {
+ m_bCondResult &= flag;
+ if (m_nAndOrState == ANDS_1) {
+ m_nAndOrState = ANDOR_NONE;
+ return;
+ }
+ }
+ else if (m_nAndOrState >= ORS_1 && m_nAndOrState <= ORS_8) {
+ m_bCondResult |= flag;
+ if (m_nAndOrState == ORS_1) {
+ m_nAndOrState = ANDOR_NONE;
+ return;
+ }
+ }
+ else {
+ return;
+ }
+ m_nAndOrState--;
+}
+
+void CRunningScript::LocatePlayerCommand(int32 command, uint32* pIp)
+{
+ bool b3D, result, debug, decided = false;
+ float X, Y, Z, dX, dY, dZ;
+ switch (command) {
+ case COMMAND_LOCATE_PLAYER_ANY_MEANS_3D:
+ case COMMAND_LOCATE_PLAYER_ON_FOOT_3D:
+ case COMMAND_LOCATE_PLAYER_IN_CAR_3D:
+ case COMMAND_LOCATE_STOPPED_PLAYER_ANY_MEANS_3D:
+ case COMMAND_LOCATE_STOPPED_PLAYER_ON_FOOT_3D:
+ case COMMAND_LOCATE_STOPPED_PLAYER_IN_CAR_3D:
+ b3D = true;
+ break;
+ default:
+ b3D = false;
+ break;
+ }
+ CollectParameters(pIp, b3D ? 8 : 6);
+ CPlayerInfo* pPlayerInfo = &CWorld::Players[ScriptParams[0]];
+ switch (command) {
+ case COMMAND_LOCATE_STOPPED_PLAYER_ANY_MEANS_2D:
+ case COMMAND_LOCATE_STOPPED_PLAYER_ANY_MEANS_3D:
+ case COMMAND_LOCATE_STOPPED_PLAYER_IN_CAR_2D:
+ case COMMAND_LOCATE_STOPPED_PLAYER_IN_CAR_3D:
+ case COMMAND_LOCATE_STOPPED_PLAYER_ON_FOOT_2D:
+ case COMMAND_LOCATE_STOPPED_PLAYER_ON_FOOT_3D:
+ if (!CTheScripts::IsPlayerStopped(pPlayerInfo)) {
+ result = false;
+ decided = true;
+ }
+ break;
+ default:
+ break;
+ }
+ 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];
+ }
+ if (!decided) {
+ CVector pos = pPlayerInfo->GetPos();
+ 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;
+ }
+ if (in_area) {
+ switch (command) {
+ case COMMAND_LOCATE_PLAYER_ANY_MEANS_2D:
+ case COMMAND_LOCATE_PLAYER_ANY_MEANS_3D:
+ case COMMAND_LOCATE_STOPPED_PLAYER_ANY_MEANS_2D:
+ case COMMAND_LOCATE_STOPPED_PLAYER_ANY_MEANS_3D:
+ result = true;
+ break;
+ case COMMAND_LOCATE_PLAYER_ON_FOOT_2D:
+ case COMMAND_LOCATE_PLAYER_ON_FOOT_3D:
+ case COMMAND_LOCATE_STOPPED_PLAYER_ON_FOOT_2D:
+ case COMMAND_LOCATE_STOPPED_PLAYER_ON_FOOT_3D:
+ result = !pPlayerInfo->m_pPed->bInVehicle;
+ break;
+ case COMMAND_LOCATE_PLAYER_IN_CAR_2D:
+ case COMMAND_LOCATE_PLAYER_IN_CAR_3D:
+ case COMMAND_LOCATE_STOPPED_PLAYER_IN_CAR_2D:
+ case COMMAND_LOCATE_STOPPED_PLAYER_IN_CAR_3D:
+ result = pPlayerInfo->m_pPed->bInVehicle;
+ break;
+ default:
+ script_assert(false);
+ break;
+ }
+ }
+ }
+ 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::LocatePlayerCharCommand(int32 command, uint32* pIp)
+{
+ bool b3D, result, debug;
+ float X, Y, Z, dX, dY, dZ;
+ switch (command) {
+ case COMMAND_LOCATE_PLAYER_ANY_MEANS_CHAR_3D:
+ case COMMAND_LOCATE_PLAYER_ON_FOOT_CHAR_3D:
+ case COMMAND_LOCATE_PLAYER_IN_CAR_CHAR_3D:
+ b3D = true;
+ break;
+ default:
+ b3D = false;
+ break;
+ }
+ CollectParameters(pIp, b3D ? 6 : 5);
+ CPlayerInfo* pPlayerInfo = &CWorld::Players[ScriptParams[0]];
+ CPed* pTarget = CPools::GetPedPool()->GetAt(ScriptParams[1]);
+ script_assert(pTarget);
+ CVector pos = pPlayerInfo->GetPos();
+ if (pTarget->bInVehicle) {
+ X = pTarget->m_pMyVehicle->GetPosition().x;
+ Y = pTarget->m_pMyVehicle->GetPosition().y;
+ Z = pTarget->m_pMyVehicle->GetPosition().z;
+ } else {
+ X = pTarget->GetPosition().x;
+ Y = pTarget->GetPosition().y;
+ Z = pTarget->GetPosition().z;
+ }
+ dX = *(float*)&ScriptParams[2];
+ dY = *(float*)&ScriptParams[3];
+ if (b3D) {
+ dZ = *(float*)&ScriptParams[4];
+ debug = ScriptParams[5];
+ }
+ else {
+ debug = ScriptParams[4];
+ }
+ 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;
+ }
+ if (in_area) {
+ switch (command) {
+ case COMMAND_LOCATE_PLAYER_ANY_MEANS_CHAR_2D:
+ case COMMAND_LOCATE_PLAYER_ANY_MEANS_CHAR_3D:
+ result = true;
+ break;
+ case COMMAND_LOCATE_PLAYER_ON_FOOT_CHAR_2D:
+ case COMMAND_LOCATE_PLAYER_ON_FOOT_CHAR_3D:
+ result = !pPlayerInfo->m_pPed->bInVehicle;
+ break;
+ case COMMAND_LOCATE_PLAYER_IN_CAR_CHAR_2D:
+ case COMMAND_LOCATE_PLAYER_IN_CAR_CHAR_3D:
+ result = pPlayerInfo->m_pPed->bInVehicle;
+ break;
+ default:
+ script_assert(false);
+ break;
+ }
+ }
+ UpdateCompareFlag(result);
+ if (debug)
+#ifdef FIX_BUGS
+ CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, X - dX, Y - dY, X + dX, Y + dY, b3D ? Z : MAP_Z_LOW_LIMIT);
+#else
+ CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, X - dX, Y - dY, X + dX, Y + dX, b3D ? Z : MAP_Z_LOW_LIMIT);
+#endif
+ 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::LocatePlayerCarCommand(int32 command, uint32* pIp)
+{
+ bool b3D, result, debug;
+ float X, Y, Z, dX, dY, dZ;
+ switch (command) {
+ case COMMAND_LOCATE_PLAYER_ANY_MEANS_CAR_3D:
+ case COMMAND_LOCATE_PLAYER_ON_FOOT_CAR_3D:
+ case COMMAND_LOCATE_PLAYER_IN_CAR_CAR_3D:
+ b3D = true;
+ break;
+ default:
+ b3D = false;
+ break;
+ }
+ CollectParameters(pIp, b3D ? 6 : 5);
+ CPlayerInfo* pPlayerInfo = &CWorld::Players[ScriptParams[0]];
+ CVehicle* pTarget = CPools::GetVehiclePool()->GetAt(ScriptParams[1]);
+ script_assert(pTarget);
+ CVector pos = pPlayerInfo->GetPos();
+ X = pTarget->GetPosition().x;
+ Y = pTarget->GetPosition().y;
+ Z = pTarget->GetPosition().z;
+ dX = *(float*)&ScriptParams[2];
+ dY = *(float*)&ScriptParams[3];
+ if (b3D) {
+ dZ = *(float*)&ScriptParams[4];
+ debug = ScriptParams[5];
+ }
+ else {
+ debug = ScriptParams[4];
+ }
+ 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;
+ }
+ if (in_area) {
+ switch (command) {
+ case COMMAND_LOCATE_PLAYER_ANY_MEANS_CAR_2D:
+ case COMMAND_LOCATE_PLAYER_ANY_MEANS_CAR_3D:
+ result = true;
+ break;
+ case COMMAND_LOCATE_PLAYER_ON_FOOT_CAR_2D:
+ case COMMAND_LOCATE_PLAYER_ON_FOOT_CAR_3D:
+ result = !pPlayerInfo->m_pPed->bInVehicle;
+ break;
+ case COMMAND_LOCATE_PLAYER_IN_CAR_CAR_2D:
+ case COMMAND_LOCATE_PLAYER_IN_CAR_CAR_3D:
+ result = pPlayerInfo->m_pPed->bInVehicle;
+ break;
+ default:
+ script_assert(false);
+ break;
+ }
+ }
+ 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::LocateCharCommand(int32 command, uint32* pIp)
+{
+ bool b3D, result, debug, decided = false;
+ float X, Y, Z, dX, dY, dZ;
+ switch (command) {
+ case COMMAND_LOCATE_CHAR_ANY_MEANS_3D:
+ case COMMAND_LOCATE_CHAR_ON_FOOT_3D:
+ case COMMAND_LOCATE_CHAR_IN_CAR_3D:
+ case COMMAND_LOCATE_STOPPED_CHAR_ANY_MEANS_3D:
+ case COMMAND_LOCATE_STOPPED_CHAR_ON_FOOT_3D:
+ case COMMAND_LOCATE_STOPPED_CHAR_IN_CAR_3D:
+ b3D = true;
+ break;
+ default:
+ b3D = false;
+ break;
+ }
+ CollectParameters(pIp, b3D ? 8 : 6);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ 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:
+ case COMMAND_LOCATE_STOPPED_CHAR_IN_CAR_2D:
+ case COMMAND_LOCATE_STOPPED_CHAR_IN_CAR_3D:
+ case COMMAND_LOCATE_STOPPED_CHAR_ON_FOOT_2D:
+ case COMMAND_LOCATE_STOPPED_CHAR_ON_FOOT_3D:
+ if (!CTheScripts::IsPedStopped(pPed)) {
+ result = false;
+ decided = true;
+ }
+ break;
+ default:
+ break;
+ }
+ 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];
+ }
+ if (!decided) {
+ 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;
+ }
+ if (in_area) {
+ switch (command) {
+ case COMMAND_LOCATE_CHAR_ANY_MEANS_2D:
+ case COMMAND_LOCATE_CHAR_ANY_MEANS_3D:
+ case COMMAND_LOCATE_STOPPED_CHAR_ANY_MEANS_2D:
+ case COMMAND_LOCATE_STOPPED_CHAR_ANY_MEANS_3D:
+ result = true;
+ break;
+ case COMMAND_LOCATE_CHAR_ON_FOOT_2D:
+ case COMMAND_LOCATE_CHAR_ON_FOOT_3D:
+ case COMMAND_LOCATE_STOPPED_CHAR_ON_FOOT_2D:
+ case COMMAND_LOCATE_STOPPED_CHAR_ON_FOOT_3D:
+ result = !pPed->bInVehicle;
+ break;
+ case COMMAND_LOCATE_CHAR_IN_CAR_2D:
+ case COMMAND_LOCATE_CHAR_IN_CAR_3D:
+ case COMMAND_LOCATE_STOPPED_CHAR_IN_CAR_2D:
+ case COMMAND_LOCATE_STOPPED_CHAR_IN_CAR_3D:
+ result = pPed->bInVehicle;
+ break;
+ default:
+ script_assert(false);
+ break;
+ }
+ }
+ }
+ 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::LocateCharCharCommand(int32 command, uint32* pIp)
+{
+ bool b3D, result, debug;
+ float X, Y, Z, dX, dY, dZ;
+ switch (command) {
+ case COMMAND_LOCATE_CHAR_ANY_MEANS_CHAR_3D:
+ case COMMAND_LOCATE_CHAR_ON_FOOT_CHAR_3D:
+ case COMMAND_LOCATE_CHAR_IN_CAR_CHAR_3D:
+ b3D = true;
+ break;
+ default:
+ b3D = false;
+ break;
+ }
+ CollectParameters(pIp, b3D ? 6 : 5);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ CPed* pTarget = CPools::GetPedPool()->GetAt(ScriptParams[1]);
+ script_assert(pTarget);
+ CVector pos = pPed->bInVehicle ? pPed->m_pMyVehicle->GetPosition() : pPed->GetPosition();
+ if (pTarget->bInVehicle) {
+ X = pTarget->m_pMyVehicle->GetPosition().x;
+ Y = pTarget->m_pMyVehicle->GetPosition().y;
+ Z = pTarget->m_pMyVehicle->GetPosition().z;
+ }
+ else {
+ X = pTarget->GetPosition().x;
+ Y = pTarget->GetPosition().y;
+ Z = pTarget->GetPosition().z;
+ }
+ dX = *(float*)&ScriptParams[2];
+ dY = *(float*)&ScriptParams[3];
+ if (b3D) {
+ dZ = *(float*)&ScriptParams[4];
+ debug = ScriptParams[5];
+ }
+ else {
+ debug = ScriptParams[4];
+ }
+ 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;
+ }
+ if (in_area) {
+ switch (command) {
+ case COMMAND_LOCATE_CHAR_ANY_MEANS_CHAR_2D:
+ case COMMAND_LOCATE_CHAR_ANY_MEANS_CHAR_3D:
+ result = true;
+ break;
+ case COMMAND_LOCATE_CHAR_ON_FOOT_CHAR_2D:
+ case COMMAND_LOCATE_CHAR_ON_FOOT_CHAR_3D:
+ result = !pPed->bInVehicle;
+ break;
+ case COMMAND_LOCATE_CHAR_IN_CAR_CHAR_2D:
+ case COMMAND_LOCATE_CHAR_IN_CAR_CHAR_3D:
+ result = pPed->bInVehicle;
+ break;
+ default:
+ script_assert(false);
+ break;
+ }
+ }
+ UpdateCompareFlag(result);
+ if (debug)
+#ifdef FIX_BUGS
+ CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, X - dX, Y - dY, X + dX, Y + dY, b3D ? Z : MAP_Z_LOW_LIMIT);
+#else
+ CTheScripts::HighlightImportantArea((uintptr)this + m_nIp, X - dX, Y - dY, X + dX, Y + dX, b3D ? Z : MAP_Z_LOW_LIMIT);
+#endif
+ 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::LocateCharCarCommand(int32 command, uint32* pIp)
+{
+ bool b3D, result, debug;
+ float X, Y, Z, dX, dY, dZ;
+ switch (command) {
+ case COMMAND_LOCATE_CHAR_ANY_MEANS_CAR_3D:
+ case COMMAND_LOCATE_CHAR_ON_FOOT_CAR_3D:
+ case COMMAND_LOCATE_CHAR_IN_CAR_CAR_3D:
+ b3D = true;
+ break;
+ default:
+ b3D = false;
+ break;
+ }
+ CollectParameters(pIp, b3D ? 6 : 5);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ CVehicle* pTarget = CPools::GetVehiclePool()->GetAt(ScriptParams[1]);
+ script_assert(pTarget);
+ CVector pos = pPed->bInVehicle ? pPed->m_pMyVehicle->GetPosition() : pPed->GetPosition();
+ X = pTarget->GetPosition().x;
+ Y = pTarget->GetPosition().y;
+ Z = pTarget->GetPosition().z;
+ dX = *(float*)&ScriptParams[2];
+ dY = *(float*)&ScriptParams[3];
+ if (b3D) {
+ dZ = *(float*)&ScriptParams[4];
+ debug = ScriptParams[5];
+ }
+ else {
+ debug = ScriptParams[4];
+ }
+ 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;
+ }
+ if (in_area) {
+ switch (command) {
+ case COMMAND_LOCATE_CHAR_ANY_MEANS_CAR_2D:
+ case COMMAND_LOCATE_CHAR_ANY_MEANS_CAR_3D:
+ result = true;
+ break;
+ case COMMAND_LOCATE_CHAR_ON_FOOT_CAR_2D:
+ case COMMAND_LOCATE_CHAR_ON_FOOT_CAR_3D:
+ result = !pPed->bInVehicle;
+ break;
+ case COMMAND_LOCATE_CHAR_IN_CAR_CAR_2D:
+ case COMMAND_LOCATE_CHAR_IN_CAR_CAR_3D:
+ result = pPed->bInVehicle;
+ break;
+ default:
+ script_assert(false);
+ break;
+ }
+ }
+ 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::LocateCharObjectCommand(int32 command, uint32* pIp)
+{
+ bool b3D, result, debug;
+ float X, Y, Z, dX, dY, dZ;
+ switch (command) {
+ case COMMAND_LOCATE_CHAR_ANY_MEANS_OBJECT_3D:
+ case COMMAND_LOCATE_CHAR_ON_FOOT_OBJECT_3D:
+ case COMMAND_LOCATE_CHAR_IN_CAR_OBJECT_3D:
+ b3D = true;
+ break;
+ default:
+ b3D = false;
+ break;
+ }
+ CollectParameters(pIp, b3D ? 6 : 5);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ CObject* pTarget = CPools::GetObjectPool()->GetAt(ScriptParams[1]);
+ script_assert(pTarget);
+ CVector pos = pPed->bInVehicle ? pPed->m_pMyVehicle->GetPosition() : pPed->GetPosition();
+ X = pTarget->GetPosition().x;
+ Y = pTarget->GetPosition().y;
+ Z = pTarget->GetPosition().z;
+ dX = *(float*)&ScriptParams[2];
+ dY = *(float*)&ScriptParams[3];
+ if (b3D) {
+ dZ = *(float*)&ScriptParams[4];
+ debug = ScriptParams[5];
+ }
+ else {
+ debug = ScriptParams[4];
+ }
+ 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;
+ }
+ if (in_area) {
+ switch (command) {
+ case COMMAND_LOCATE_CHAR_ANY_MEANS_OBJECT_2D:
+ case COMMAND_LOCATE_CHAR_ANY_MEANS_OBJECT_3D:
+ result = true;
+ break;
+ case COMMAND_LOCATE_CHAR_ON_FOOT_OBJECT_2D:
+ case COMMAND_LOCATE_CHAR_ON_FOOT_OBJECT_3D:
+ result = !pPed->bInVehicle;
+ break;
+ case COMMAND_LOCATE_CHAR_IN_CAR_OBJECT_2D:
+ case COMMAND_LOCATE_CHAR_IN_CAR_OBJECT_3D:
+ result = pPed->bInVehicle;
+ break;
+ default:
+ script_assert(false);
+ break;
+ }
+ }
+ 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::LocateCarCommand(int32 command, uint32* pIp)
+{
+ bool b3D, result, debug, decided = false;
+ float X, Y, Z, dX, dY, dZ;
+ switch (command) {
+ case COMMAND_LOCATE_CAR_3D:
+ case COMMAND_LOCATE_STOPPED_CAR_3D:
+ b3D = true;
+ break;
+ default:
+ b3D = false;
+ break;
+ }
+ CollectParameters(pIp, b3D ? 8 : 6);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ CVector pos = pVehicle->GetPosition();
+ switch (command) {
+ case COMMAND_LOCATE_STOPPED_CAR_2D:
+ case COMMAND_LOCATE_STOPPED_CAR_3D:
+ if (!CTheScripts::IsVehicleStopped(pVehicle)) {
+ result = false;
+ decided = true;
+ }
+ break;
+ default:
+ break;
+ }
+ 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];
+ }
+ if (!decided) {
+ 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::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;
+ float X, Y, Z, dX, dY, dZ;
+ switch (command) {
+ case COMMAND_LOCATE_SNIPER_BULLET_3D:
+ b3D = true;
+ break;
+ default:
+ b3D = false;
+ break;
+ }
+ CollectParameters(pIp, b3D ? 7 : 5);
+ X = *(float*)&ScriptParams[0];
+ Y = *(float*)&ScriptParams[1];
+ if (b3D) {
+ Z = *(float*)&ScriptParams[2];
+ dX = *(float*)&ScriptParams[3];
+ dY = *(float*)&ScriptParams[4];
+ dZ = *(float*)&ScriptParams[5];
+ debug = ScriptParams[6];
+ }
+ else {
+ dX = *(float*)&ScriptParams[2];
+ dY = *(float*)&ScriptParams[3];
+ debug = ScriptParams[4];
+ }
+ result = CBulletInfo::TestForSniperBullet(X - dX, X + dX, Y - dY, Y + dY, b3D ? Z - dZ : -1000.0f, b3D ? Z + dZ : 1000.0f);
+ 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::PlayerInAreaCheckCommand(int32 command, uint32* pIp)
+{
+ bool b3D, result, debug, decided = false;
+ float infX, infY, infZ, supX, supY, supZ;
+ switch (command) {
+ case COMMAND_IS_PLAYER_IN_AREA_3D:
+ case COMMAND_IS_PLAYER_IN_AREA_ON_FOOT_3D:
+ case COMMAND_IS_PLAYER_IN_AREA_IN_CAR_3D:
+ case COMMAND_IS_PLAYER_STOPPED_IN_AREA_3D:
+ case COMMAND_IS_PLAYER_STOPPED_IN_AREA_ON_FOOT_3D:
+ case COMMAND_IS_PLAYER_STOPPED_IN_AREA_IN_CAR_3D:
+ b3D = true;
+ break;
+ default:
+ b3D = false;
+ break;
+ }
+ CollectParameters(pIp, b3D ? 8 : 6);
+ CPlayerInfo* pPlayerInfo = &CWorld::Players[ScriptParams[0]];
+ switch (command) {
+ case COMMAND_IS_PLAYER_STOPPED_IN_AREA_3D:
+ case COMMAND_IS_PLAYER_STOPPED_IN_AREA_ON_FOOT_3D:
+ case COMMAND_IS_PLAYER_STOPPED_IN_AREA_IN_CAR_3D:
+ case COMMAND_IS_PLAYER_STOPPED_IN_AREA_2D:
+ case COMMAND_IS_PLAYER_STOPPED_IN_AREA_ON_FOOT_2D:
+ case COMMAND_IS_PLAYER_STOPPED_IN_AREA_IN_CAR_2D:
+ if (!CTheScripts::IsPlayerStopped(pPlayerInfo)) {
+ result = false;
+ decided = true;
+ }
+ break;
+ default:
+ break;
+ }
+ 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;
+ }
+ if (!decided) {
+ CVector pos = pPlayerInfo->GetPos();
+ 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_PLAYER_IN_AREA_2D:
+ case COMMAND_IS_PLAYER_IN_AREA_3D:
+ case COMMAND_IS_PLAYER_STOPPED_IN_AREA_2D:
+ case COMMAND_IS_PLAYER_STOPPED_IN_AREA_3D:
+ result = true;
+ break;
+ case COMMAND_IS_PLAYER_IN_AREA_ON_FOOT_2D:
+ case COMMAND_IS_PLAYER_IN_AREA_ON_FOOT_3D:
+ case COMMAND_IS_PLAYER_STOPPED_IN_AREA_ON_FOOT_2D:
+ case COMMAND_IS_PLAYER_STOPPED_IN_AREA_ON_FOOT_3D:
+ result = !pPlayerInfo->m_pPed->bInVehicle;
+ break;
+ case COMMAND_IS_PLAYER_IN_AREA_IN_CAR_2D:
+ case COMMAND_IS_PLAYER_IN_AREA_IN_CAR_3D:
+ case COMMAND_IS_PLAYER_STOPPED_IN_AREA_IN_CAR_2D:
+ case COMMAND_IS_PLAYER_STOPPED_IN_AREA_IN_CAR_3D:
+ result = pPlayerInfo->m_pPed->bInVehicle;
+ 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::PlayerInAngledAreaCheckCommand(int32 command, uint32* pIp)
+{
+ bool b3D, result, debug, decided = false;
+ float infX, infY, infZ, supX, supY, supZ, side2length;
+ switch (command) {
+ case COMMAND_IS_PLAYER_IN_ANGLED_AREA_3D:
+ case COMMAND_IS_PLAYER_IN_ANGLED_AREA_ON_FOOT_3D:
+ case COMMAND_IS_PLAYER_IN_ANGLED_AREA_IN_CAR_3D:
+ case COMMAND_IS_PLAYER_STOPPED_IN_ANGLED_AREA_3D:
+ case COMMAND_IS_PLAYER_STOPPED_IN_ANGLED_AREA_ON_FOOT_3D:
+ case COMMAND_IS_PLAYER_STOPPED_IN_ANGLED_AREA_IN_CAR_3D:
+ b3D = true;
+ break;
+ default:
+ b3D = false;
+ break;
+ }
+ CollectParameters(pIp, b3D ? 9 : 7);
+ CPlayerInfo* pPlayerInfo = &CWorld::Players[ScriptParams[0]];
+ switch (command) {
+ case COMMAND_IS_PLAYER_STOPPED_IN_ANGLED_AREA_3D:
+ case COMMAND_IS_PLAYER_STOPPED_IN_ANGLED_AREA_ON_FOOT_3D:
+ case COMMAND_IS_PLAYER_STOPPED_IN_ANGLED_AREA_IN_CAR_3D:
+ case COMMAND_IS_PLAYER_STOPPED_IN_ANGLED_AREA_2D:
+ case COMMAND_IS_PLAYER_STOPPED_IN_ANGLED_AREA_ON_FOOT_2D:
+ case COMMAND_IS_PLAYER_STOPPED_IN_ANGLED_AREA_IN_CAR_2D:
+ if (!CTheScripts::IsPlayerStopped(pPlayerInfo)) {
+ result = false;
+ decided = true;
+ }
+ break;
+ default:
+ break;
+ }
+ 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];
+ }
+ side2length = *(float*)&ScriptParams[7];
+ debug = ScriptParams[8];
+ }
+ else {
+ supX = *(float*)&ScriptParams[3];
+ supY = *(float*)&ScriptParams[4];
+ side2length = *(float*)&ScriptParams[5];
+ debug = ScriptParams[6];
+ }
+ float initAngle = CGeneral::GetRadianAngleBetweenPoints(infX, infY, supX, supY) + HALFPI;
+ while (initAngle < 0.0f)
+ initAngle += TWOPI;
+ while (initAngle > TWOPI)
+ initAngle -= TWOPI;
+ // it looks like the idea is to use a rectangle using the diagonal of the rectangle as
+ // the side of new rectangle, with "length" being the length of second side
+ float rotatedSupX = supX + side2length * sin(initAngle);
+ float rotatedSupY = supY - side2length * cos(initAngle);
+ float rotatedInfX = infX + side2length * sin(initAngle);
+ float rotatedInfY = infY - side2length * cos(initAngle);
+ float side1X = supX - infX;
+ float side1Y = supY - infY;
+ float side1Length = CVector2D(side1X, side1Y).Magnitude();
+ float side2X = rotatedInfX - infX;
+ float side2Y = rotatedInfY - infY;
+ float side2Length = CVector2D(side2X, side2Y).Magnitude(); // == side2length?
+ if (!decided) {
+ CVector pos = pPlayerInfo->GetPos();
+ result = false;
+ float X = pos.x - infX;
+ float Y = pos.y - infY;
+ float positionAlongSide1 = X * side1X / side1Length + Y * side1Y / side1Length;
+ bool in_area = false;
+ if (positionAlongSide1 >= 0.0f && positionAlongSide1 <= side1Length) {
+ float positionAlongSide2 = X * side2X / side2Length + Y * side2Y / side2Length;
+ if (positionAlongSide2 >= 0.0f && positionAlongSide2 <= side2Length) {
+ in_area = !b3D || pos.z >= infZ && pos.z <= supZ;
+ }
+ }
+
+ if (in_area) {
+ switch (command) {
+ case COMMAND_IS_PLAYER_IN_ANGLED_AREA_2D:
+ case COMMAND_IS_PLAYER_IN_ANGLED_AREA_3D:
+ case COMMAND_IS_PLAYER_STOPPED_IN_ANGLED_AREA_2D:
+ case COMMAND_IS_PLAYER_STOPPED_IN_ANGLED_AREA_3D:
+ result = true;
+ break;
+ case COMMAND_IS_PLAYER_IN_ANGLED_AREA_ON_FOOT_2D:
+ case COMMAND_IS_PLAYER_IN_ANGLED_AREA_ON_FOOT_3D:
+ case COMMAND_IS_PLAYER_STOPPED_IN_ANGLED_AREA_ON_FOOT_2D:
+ case COMMAND_IS_PLAYER_STOPPED_IN_ANGLED_AREA_ON_FOOT_3D:
+ result = !pPlayerInfo->m_pPed->bInVehicle;
+ break;
+ case COMMAND_IS_PLAYER_IN_ANGLED_AREA_IN_CAR_2D:
+ case COMMAND_IS_PLAYER_IN_ANGLED_AREA_IN_CAR_3D:
+ case COMMAND_IS_PLAYER_STOPPED_IN_ANGLED_AREA_IN_CAR_2D:
+ case COMMAND_IS_PLAYER_STOPPED_IN_ANGLED_AREA_IN_CAR_3D:
+ result = pPlayerInfo->m_pPed->bInVehicle;
+ break;
+ default:
+ script_assert(false);
+ break;
+ }
+ }
+ }
+ UpdateCompareFlag(result);
+ if (debug)
+ CTheScripts::HighlightImportantAngledArea((uintptr)this + m_nIp, infX, infY, supX, supY,
+ rotatedSupX, rotatedSupY, rotatedInfX, rotatedInfY, b3D ? (infZ + supZ) / 2 : MAP_Z_LOW_LIMIT);
+ if (CTheScripts::DbgFlag) {
+ if (b3D)
+ CTheScripts::DrawDebugAngledCube(infX, infY, infZ, supX, supY, supZ,
+ rotatedSupX, rotatedSupY, rotatedInfX, rotatedInfY);
+ else
+ CTheScripts::DrawDebugAngledSquare(infX, infY, supX, supY,
+ rotatedSupX, rotatedSupY, rotatedInfX, rotatedInfY);
+ }
+}
+
+void CRunningScript::CharInAreaCheckCommand(int32 command, uint32* pIp)
+{
+ bool b3D, result, debug, decided = false;
+ float infX, infY, infZ, supX, supY, supZ;
+ switch (command) {
+ case COMMAND_IS_CHAR_IN_AREA_3D:
+ case COMMAND_IS_CHAR_IN_AREA_ON_FOOT_3D:
+ case COMMAND_IS_CHAR_IN_AREA_IN_CAR_3D:
+ case COMMAND_IS_CHAR_STOPPED_IN_AREA_3D:
+ case COMMAND_IS_CHAR_STOPPED_IN_AREA_ON_FOOT_3D:
+ case COMMAND_IS_CHAR_STOPPED_IN_AREA_IN_CAR_3D:
+ b3D = true;
+ break;
+ default:
+ b3D = false;
+ break;
+ }
+ CollectParameters(pIp, b3D ? 8 : 6);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ 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:
+ case COMMAND_IS_CHAR_STOPPED_IN_AREA_IN_CAR_3D:
+ case COMMAND_IS_CHAR_STOPPED_IN_AREA_2D:
+ case COMMAND_IS_CHAR_STOPPED_IN_AREA_ON_FOOT_2D:
+ case COMMAND_IS_CHAR_STOPPED_IN_AREA_IN_CAR_2D:
+ if (!CTheScripts::IsPedStopped(pPed)) {
+ result = false;
+ decided = true;
+ }
+ break;
+ default:
+ break;
+ }
+ 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;
+ }
+ if (!decided) {
+ 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_CHAR_IN_AREA_2D:
+ case COMMAND_IS_CHAR_IN_AREA_3D:
+ case COMMAND_IS_CHAR_STOPPED_IN_AREA_2D:
+ case COMMAND_IS_CHAR_STOPPED_IN_AREA_3D:
+ result = true;
+ break;
+ case COMMAND_IS_CHAR_IN_AREA_ON_FOOT_2D:
+ case COMMAND_IS_CHAR_IN_AREA_ON_FOOT_3D:
+ case COMMAND_IS_CHAR_STOPPED_IN_AREA_ON_FOOT_2D:
+ case COMMAND_IS_CHAR_STOPPED_IN_AREA_ON_FOOT_3D:
+ result = !pPed->bInVehicle;
+ break;
+ case COMMAND_IS_CHAR_IN_AREA_IN_CAR_2D:
+ case COMMAND_IS_CHAR_IN_AREA_IN_CAR_3D:
+ case COMMAND_IS_CHAR_STOPPED_IN_AREA_IN_CAR_2D:
+ case COMMAND_IS_CHAR_STOPPED_IN_AREA_IN_CAR_3D:
+ result = pPed->bInVehicle;
+ 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::CarInAreaCheckCommand(int32 command, uint32* pIp)
+{
+ bool b3D, result, debug, decided = false;
+ float infX, infY, infZ, supX, supY, supZ;
+ switch (command) {
+ case COMMAND_IS_CAR_IN_AREA_3D:
+ case COMMAND_IS_CAR_STOPPED_IN_AREA_3D:
+ b3D = true;
+ break;
+ default:
+ b3D = false;
+ break;
+ }
+ CollectParameters(pIp, b3D ? 8 : 6);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ CVector pos = pVehicle->GetPosition();
+ switch (command) {
+ case COMMAND_IS_CAR_STOPPED_IN_AREA_3D:
+ case COMMAND_IS_CAR_STOPPED_IN_AREA_2D:
+ if (!CTheScripts::IsVehicleStopped(pVehicle)) {
+ result = false;
+ decided = true;
+ }
+ break;
+ default:
+ break;
+ }
+ 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;
+ }
+ if (!decided) {
+ 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_CAR_IN_AREA_2D:
+ case COMMAND_IS_CAR_IN_AREA_3D:
+ case COMMAND_IS_CAR_STOPPED_IN_AREA_2D:
+ case COMMAND_IS_CAR_STOPPED_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::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)
+ return;
+ if (!CTheScripts::IsPlayerOnAMission())
+ return;
+ CPlayerInfo* pPlayer = &CWorld::Players[CWorld::PlayerInFocus];
+ if (!pPlayer->IsRestartingAfterDeath() && !pPlayer->IsRestartingAfterArrest())
+ return;
+#ifdef MISSION_REPLAY
+ if (AllowMissionReplay != 0)
+ return;
+ if (CanAllowMissionReplay())
+ AllowMissionReplay = 1;
+#endif
+ script_assert(m_nStackPointer > 0);
+ while (m_nStackPointer > 1)
+ --m_nStackPointer;
+ m_nIp = m_anStack[--m_nStackPointer];
+ CMessages::ClearSmallMessagesOnly();
+ *(int32*)&CTheScripts::ScriptSpace[CTheScripts::OnAMissionFlag] = 0;
+ m_bDeatharrestExecuted = true;
+ m_nWakeTime = 0;
+}
+
+int16 CRunningScript::GetPadState(uint16 pad, uint16 button)
+{
+ CPad* pPad = CPad::GetPad(pad);
+ switch (button) {
+ case 0: return pPad->NewState.LeftStickX;
+ case 1: return pPad->NewState.LeftStickY;
+ case 2: return pPad->NewState.RightStickX;
+ case 3: return pPad->NewState.RightStickY;
+ case 4: return pPad->NewState.LeftShoulder1;
+ case 5: return pPad->NewState.LeftShoulder2;
+ case 6: return pPad->NewState.RightShoulder1;
+ case 7: return pPad->NewState.RightShoulder2;
+ case 8: return pPad->NewState.DPadUp;
+ case 9: return pPad->NewState.DPadDown;
+ case 10: return pPad->NewState.DPadLeft;
+ case 11: return pPad->NewState.DPadRight;
+ case 12: return pPad->NewState.Start;
+ case 13: return pPad->NewState.Select;
+ case 14: return pPad->NewState.Square;
+ case 15: return pPad->NewState.Triangle;
+ case 16: return pPad->NewState.Cross;
+ case 17: return pPad->NewState.Circle;
+ case 18: return pPad->NewState.LeftShock;
+ case 19: return pPad->NewState.RightShock;
+ default: break;
+ }
+ 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()
+{
+ int active = 0;
+ int idle = 0;
+
+ for (CRunningScript* pScript = pActiveScripts; pScript; pScript = pScript->GetNext())
+ active++;
+ for (CRunningScript* pScript = pIdleScripts; pScript; pScript = pScript->GetNext())
+ idle++;
+
+ debug("active: %d, idle: %d", active, idle);
+}
+
+uint32 DbgLineColour = 0x0000FFFF; // r = 0, g = 0, b = 255, a = 255
+
+void CTheScripts::DrawDebugSquare(float infX, float infY, float supX, float supY)
+{
+ CColPoint tmpCP;
+ CEntity* tmpEP;
+ CVector p1, p2, p3, p4;
+ p1 = CVector(infX, infY, -1000.0f);
+ CWorld::ProcessVerticalLine(p1, 1000.0f, tmpCP, tmpEP, true, false, false, false, true, false, nil);
+ p1.z = 2.0f + tmpCP.point.z;
+ p2 = CVector(supX, supY, -1000.0f);
+ CWorld::ProcessVerticalLine(p2, 1000.0f, tmpCP, tmpEP, true, false, false, false, true, false, nil);
+ p2.z = 2.0f + tmpCP.point.z;
+ p3 = CVector(infX, supY, -1000.0f);
+ CWorld::ProcessVerticalLine(p3, 1000.0f, tmpCP, tmpEP, true, false, false, false, true, false, nil);
+ p3.z = 2.0f + tmpCP.point.z;
+ p4 = CVector(supX, infY, -1000.0f);
+ CWorld::ProcessVerticalLine(p4, 1000.0f, tmpCP, tmpEP, true, false, false, false, true, false, nil);
+ p4.z = 2.0f + tmpCP.point.z;
+ CTheScripts::ScriptDebugLine3D(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z, DbgLineColour, DbgLineColour);
+ CTheScripts::ScriptDebugLine3D(p2.x, p2.y, p2.z, p3.x, p3.y, p3.z, DbgLineColour, DbgLineColour);
+ CTheScripts::ScriptDebugLine3D(p3.x, p3.y, p3.z, p4.x, p4.y, p4.z, DbgLineColour, DbgLineColour);
+ CTheScripts::ScriptDebugLine3D(p4.x, p4.y, p4.z, p1.x, p1.y, p1.z, DbgLineColour, DbgLineColour);
+}
+
+void CTheScripts::DrawDebugAngledSquare(float infX, float infY, float supX, float supY, float rotSupX, float rotSupY, float rotInfX, float rotInfY)
+{
+ CColPoint tmpCP;
+ CEntity* tmpEP;
+ CVector p1, p2, p3, p4;
+ p1 = CVector(infX, infY, -1000.0f);
+ CWorld::ProcessVerticalLine(p1, 1000.0f, tmpCP, tmpEP, true, false, false, false, true, false, nil);
+ p1.z = 2.0f + tmpCP.point.z;
+ p2 = CVector(supX, supY, -1000.0f);
+ CWorld::ProcessVerticalLine(p2, 1000.0f, tmpCP, tmpEP, true, false, false, false, true, false, nil);
+ p2.z = 2.0f + tmpCP.point.z;
+ p3 = CVector(rotSupX, rotSupY, -1000.0f);
+ CWorld::ProcessVerticalLine(p3, 1000.0f, tmpCP, tmpEP, true, false, false, false, true, false, nil);
+ p3.z = 2.0f + tmpCP.point.z;
+ p4 = CVector(rotInfX, rotInfY, -1000.0f);
+ CWorld::ProcessVerticalLine(p4, 1000.0f, tmpCP, tmpEP, true, false, false, false, true, false, nil);
+ p4.z = 2.0f + tmpCP.point.z;
+ CTheScripts::ScriptDebugLine3D(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z, DbgLineColour, DbgLineColour);
+ CTheScripts::ScriptDebugLine3D(p2.x, p2.y, p2.z, p3.x, p3.y, p3.z, DbgLineColour, DbgLineColour);
+ CTheScripts::ScriptDebugLine3D(p3.x, p3.y, p3.z, p4.x, p4.y, p4.z, DbgLineColour, DbgLineColour);
+ CTheScripts::ScriptDebugLine3D(p4.x, p4.y, p4.z, p1.x, p1.y, p1.z, DbgLineColour, DbgLineColour);
+}
+
+void CTheScripts::DrawDebugCube(float infX, float infY, float infZ, float supX, float supY, float supZ)
+{
+ CTheScripts::ScriptDebugLine3D(infX, infY, infZ, supX, infY, infZ, DbgLineColour, DbgLineColour);
+ CTheScripts::ScriptDebugLine3D(supX, infY, infZ, supX, supY, infZ, DbgLineColour, DbgLineColour);
+ CTheScripts::ScriptDebugLine3D(supX, supY, infZ, infX, supY, infZ, DbgLineColour, DbgLineColour);
+ CTheScripts::ScriptDebugLine3D(infX, supY, infZ, infX, infY, infZ, DbgLineColour, DbgLineColour);
+ CTheScripts::ScriptDebugLine3D(infX, infY, supZ, supX, infY, supZ, DbgLineColour, DbgLineColour);
+ CTheScripts::ScriptDebugLine3D(supX, infY, supZ, supX, supY, supZ, DbgLineColour, DbgLineColour);
+ CTheScripts::ScriptDebugLine3D(supX, supY, supZ, infX, supY, supZ, DbgLineColour, DbgLineColour);
+ CTheScripts::ScriptDebugLine3D(infX, supY, supZ, infX, infY, supZ, DbgLineColour, DbgLineColour);
+ CTheScripts::ScriptDebugLine3D(infX, infY, supZ, infX, infY, infZ, DbgLineColour, DbgLineColour);
+ CTheScripts::ScriptDebugLine3D(supX, infY, supZ, supX, infY, infZ, DbgLineColour, DbgLineColour);
+ CTheScripts::ScriptDebugLine3D(supX, supY, supZ, supX, supY, infZ, DbgLineColour, DbgLineColour);
+ CTheScripts::ScriptDebugLine3D(infX, supY, supZ, infX, supY, infZ, DbgLineColour, DbgLineColour);
+}
+
+void CTheScripts::DrawDebugAngledCube(float infX, float infY, float infZ, float supX, float supY, float supZ, float rotSupX, float rotSupY, float rotInfX, float rotInfY)
+{
+ CTheScripts::ScriptDebugLine3D(infX, infY, infZ, supX, infY, infZ, DbgLineColour, DbgLineColour);
+ CTheScripts::ScriptDebugLine3D(supX, infY, infZ, rotSupX, rotSupY, infZ, DbgLineColour, DbgLineColour);
+ CTheScripts::ScriptDebugLine3D(rotSupX, rotSupY, infZ, rotInfX, rotInfY, infZ, DbgLineColour, DbgLineColour);
+ CTheScripts::ScriptDebugLine3D(rotInfX, rotInfY, infZ, infX, infY, infZ, DbgLineColour, DbgLineColour);
+ CTheScripts::ScriptDebugLine3D(infX, infY, supZ, supX, infY, supZ, DbgLineColour, DbgLineColour);
+ CTheScripts::ScriptDebugLine3D(supX, infY, supZ, rotSupX, rotSupY, supZ, DbgLineColour, DbgLineColour);
+ CTheScripts::ScriptDebugLine3D(rotSupX, rotSupY, rotInfX, rotInfY, supY, supZ, DbgLineColour, DbgLineColour);
+ CTheScripts::ScriptDebugLine3D(rotInfX, rotInfY, supZ, infX, infY, supZ, DbgLineColour, DbgLineColour);
+ CTheScripts::ScriptDebugLine3D(infX, infY, supZ, infX, infY, infZ, DbgLineColour, DbgLineColour);
+ CTheScripts::ScriptDebugLine3D(supX, infY, supZ, supX, infY, infZ, DbgLineColour, DbgLineColour);
+ CTheScripts::ScriptDebugLine3D(rotSupX, rotSupY, supZ, rotSupX, rotSupY, infZ, DbgLineColour, DbgLineColour);
+ CTheScripts::ScriptDebugLine3D(rotInfX, rotInfY, supZ, rotInfX, rotInfY, infZ, DbgLineColour, DbgLineColour);
+}
+
+void CTheScripts::ScriptDebugLine3D(float x1, float y1, float z1, float x2, float y2, float z2, uint32 col, uint32 col2)
+{
+ if (NumScriptDebugLines >= MAX_NUM_STORED_LINES)
+ return;
+ aStoredLines[NumScriptDebugLines].vecInf = CVector(x1, y1, z1);
+ aStoredLines[NumScriptDebugLines].vecSup = CVector(x2, y2, z2);
+ aStoredLines[NumScriptDebugLines].color1 = col;
+ aStoredLines[NumScriptDebugLines++].color2 = col2;
+}
+
+void CTheScripts::RenderTheScriptDebugLines()
+{
+ RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)1);
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)1);
+ for (int i = 0; i < NumScriptDebugLines; i++) {
+ CLines::RenderLineWithClipping(
+ aStoredLines[i].vecInf.x,
+ aStoredLines[i].vecInf.y,
+ aStoredLines[i].vecInf.z,
+ aStoredLines[i].vecSup.x,
+ aStoredLines[i].vecSup.y,
+ aStoredLines[i].vecSup.z,
+ aStoredLines[i].color1,
+ aStoredLines[i].color2);
+ }
+ NumScriptDebugLines = 0;
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)0);
+}
+
+#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)
+{
+INITSAVEBUF
+ uint32 varSpace = GetSizeOfVariableSpace();
+ uint32 runningScripts = 0;
+ for (CRunningScript* pScript = pActiveScripts; pScript; pScript = pScript->GetNext())
+ runningScripts++;
+ *size = CRunningScript::nSaveStructSize * runningScripts + varSpace + SCRIPT_DATA_SIZE + SAVE_HEADER_SIZE + 3 * sizeof(uint32);
+ WriteSaveHeader(buf, 'S', 'C', 'R', '\0', *size - SAVE_HEADER_SIZE);
+ WriteSaveBuf(buf, varSpace);
+ for (uint32 i = 0; i < varSpace; i++)
+ WriteSaveBuf(buf, ScriptSpace[i]);
+#ifdef CHECK_STRUCT_SIZES
+ static_assert(SCRIPT_DATA_SIZE == 968, "CTheScripts::SaveAllScripts");
+#endif
+ uint32 script_data_size = SCRIPT_DATA_SIZE;
+ WriteSaveBuf(buf, script_data_size);
+ WriteSaveBuf(buf, OnAMissionFlag);
+ WriteSaveBuf(buf, LastMissionPassedTime);
+ for (uint32 i = 0; i < MAX_NUM_BUILDING_SWAPS; i++) {
+ CBuilding* pBuilding = BuildingSwapArray[i].m_pBuilding;
+ uint32 type, handle;
+ if (!pBuilding) {
+ type = 0;
+ handle = 0;
+ } else if (pBuilding->GetIsATreadable()) {
+ type = 1;
+ handle = CPools::GetTreadablePool()->GetJustIndex_NoFreeAssert((CTreadable*)pBuilding) + 1;
+ } else {
+ type = 2;
+ handle = CPools::GetBuildingPool()->GetJustIndex_NoFreeAssert(pBuilding) + 1;
+ }
+ WriteSaveBuf(buf, type);
+ WriteSaveBuf(buf, handle);
+ WriteSaveBuf(buf, BuildingSwapArray[i].m_nNewModel);
+ WriteSaveBuf(buf, BuildingSwapArray[i].m_nOldModel);
+ }
+ for (uint32 i = 0; i < MAX_NUM_INVISIBILITY_SETTINGS; i++) {
+ CEntity* pEntity = InvisibilitySettingArray[i];
+ uint32 type, handle;
+ if (!pEntity) {
+ type = 0;
+ handle = 0;
+ } else {
+ switch (pEntity->GetType()) {
+ case ENTITY_TYPE_BUILDING:
+ if (((CBuilding*)pEntity)->GetIsATreadable()) {
+ type = 1;
+ handle = CPools::GetTreadablePool()->GetJustIndex_NoFreeAssert((CTreadable*)pEntity) + 1;
+ } else {
+ type = 2;
+ handle = CPools::GetBuildingPool()->GetJustIndex_NoFreeAssert((CBuilding*)pEntity) + 1;
+ }
+ break;
+ case ENTITY_TYPE_OBJECT:
+ type = 3;
+ handle = CPools::GetObjectPool()->GetJustIndex_NoFreeAssert((CObject*)pEntity) + 1;
+ break;
+ case ENTITY_TYPE_DUMMY:
+ type = 4;
+ handle = CPools::GetDummyPool()->GetJustIndex_NoFreeAssert((CDummy*)pEntity) + 1;
+ default: break;
+ }
+ }
+ WriteSaveBuf(buf, type);
+ WriteSaveBuf(buf, handle);
+ }
+ WriteSaveBuf(buf, bUsingAMultiScriptFile);
+ WriteSaveBuf(buf, bPlayerHasMetDebbieHarry);
+ WriteSaveBuf(buf, (uint16)0);
+ WriteSaveBuf(buf, MainScriptSize);
+ WriteSaveBuf(buf, LargestMissionScriptSize);
+ WriteSaveBuf(buf, NumberOfMissionScripts);
+ WriteSaveBuf(buf, NumberOfExclusiveMissionScripts);
+ WriteSaveBuf(buf, runningScripts);
+ for (CRunningScript* pScript = pActiveScripts; pScript; pScript = pScript->GetNext())
+ pScript->Save(buf);
+VALIDATESAVEBUF(*size)
+}
+
+void CTheScripts::LoadAllScripts(uint8* buf, uint32 size)
+{
+ Init();
+INITSAVEBUF
+ CheckSaveHeader(buf, 'S', 'C', 'R', '\0', size - SAVE_HEADER_SIZE);
+ uint32 varSpace = ReadSaveBuf<uint32>(buf);
+ for (uint32 i = 0; i < varSpace; i++)
+ ScriptSpace[i] = ReadSaveBuf<uint8>(buf);
+ script_assert(ReadSaveBuf<uint32>(buf) == SCRIPT_DATA_SIZE);
+ OnAMissionFlag = 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);
+ switch (type) {
+ case 0:
+ BuildingSwapArray[i].m_pBuilding = nil;
+ break;
+ case 1:
+ BuildingSwapArray[i].m_pBuilding = CPools::GetTreadablePool()->GetSlot(handle - 1);
+ break;
+ case 2:
+ BuildingSwapArray[i].m_pBuilding = CPools::GetBuildingPool()->GetSlot(handle - 1);
+ break;
+ default:
+ script_assert(false);
+ }
+ BuildingSwapArray[i].m_nNewModel = ReadSaveBuf<uint32>(buf);
+ BuildingSwapArray[i].m_nOldModel = ReadSaveBuf<uint32>(buf);
+ if (BuildingSwapArray[i].m_pBuilding)
+ BuildingSwapArray[i].m_pBuilding->ReplaceWithNewModel(BuildingSwapArray[i].m_nNewModel);
+ }
+ for (uint32 i = 0; i < MAX_NUM_INVISIBILITY_SETTINGS; i++) {
+ uint32 type = ReadSaveBuf<uint32>(buf);
+ uint32 handle = ReadSaveBuf<uint32>(buf);
+ switch (type) {
+ case 0:
+ InvisibilitySettingArray[i] = nil;
+ break;
+ case 1:
+ InvisibilitySettingArray[i] = CPools::GetTreadablePool()->GetSlot(handle - 1);
+ break;
+ case 2:
+ InvisibilitySettingArray[i] = CPools::GetBuildingPool()->GetSlot(handle - 1);
+ break;
+ case 3:
+ InvisibilitySettingArray[i] = CPools::GetObjectPool()->GetSlot(handle - 1);
+ break;
+ case 4:
+ InvisibilitySettingArray[i] = CPools::GetDummyPool()->GetSlot(handle - 1);
+ break;
+ default:
+ script_assert(false);
+ }
+ if (InvisibilitySettingArray[i])
+ InvisibilitySettingArray[i]->bIsVisible = false;
+ }
+ script_assert(ReadSaveBuf<bool>(buf) == bUsingAMultiScriptFile);
+ 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);
+ script_assert(ReadSaveBuf<uint16>(buf) == NumberOfExclusiveMissionScripts);
+ uint32 runningScripts = ReadSaveBuf<uint32>(buf);
+ for (uint32 i = 0; i < runningScripts; i++)
+ StartNewScript(0)->Load(buf);
+VALIDATESAVEBUF(size)
+}
+
+#undef SCRIPT_DATA_SIZE
+
+void CTheScripts::ClearSpaceForMissionEntity(const CVector& pos, CEntity* pEntity)
+{
+ static CColPoint aTempColPoints[MAX_COLLISION_POINTS];
+ int16 entities = 0;
+ CEntity* aEntities[16];
+ CWorld::FindObjectsKindaColliding(pos, pEntity->GetBoundRadius(), false, &entities, 16, aEntities, false, true, true, false, false);
+ if (entities <= 0)
+ return;
+ for (uint16 i = 0; i < entities; i++) {
+ if (aEntities[i] != pEntity && aEntities[i]->IsPed() && ((CPed*)aEntities[i])->bInVehicle)
+ aEntities[i] = nil;
+ }
+ for (uint16 i = 0; i < entities; i++) {
+ if (aEntities[i] == pEntity || !aEntities[i])
+ continue;
+ CEntity* pFound = aEntities[i];
+ int cols;
+ if (pEntity->GetColModel()->numLines <= 0)
+ cols = CCollision::ProcessColModels(pEntity->GetMatrix(), *pEntity->GetColModel(),
+ pFound->GetMatrix(), *pFound->GetColModel(), aTempColPoints, nil, nil);
+ else {
+ float lines[4];
+ lines[0] = lines[1] = lines[2] = lines[3] = 1.0f;
+ CColPoint tmp[4];
+ cols = CCollision::ProcessColModels(pEntity->GetMatrix(), *pEntity->GetColModel(),
+ pFound->GetMatrix(), *pFound->GetColModel(), aTempColPoints,tmp, lines);
+ }
+ if (cols <= 0)
+ continue;
+ switch (pFound->GetType()) {
+ case ENTITY_TYPE_VEHICLE:
+ {
+ printf("Will try to delete a vehicle where a mission entity should be\n");
+ CVehicle* pVehicle = (CVehicle*)pFound;
+ if (pVehicle->bIsLocked || !pVehicle->CanBeDeleted())
+ break;
+ if (pVehicle->pDriver) {
+ CPopulation::RemovePed(pVehicle->pDriver);
+ pVehicle->pDriver = nil;
+ }
+ for (int i = 0; i < pVehicle->m_nNumMaxPassengers; i++) {
+ if (pVehicle->pPassengers[i]) {
+ CPopulation::RemovePed(pVehicle->pPassengers[i]);
+ pVehicle->pPassengers[i] = 0;
+ pVehicle->m_nNumPassengers--;
+ }
+ }
+ CCarCtrl::RemoveFromInterestingVehicleList(pVehicle);
+ CWorld::Remove(pVehicle);
+ delete pVehicle;
+ break;
+ }
+ case ENTITY_TYPE_PED:
+ {
+ CPed* pPed = (CPed*)pFound;
+ if (pPed->IsPlayer() || !pPed->CanBeDeleted())
+ break;
+ CPopulation::RemovePed(pPed);
+ printf("Deleted a ped where a mission entity should be\n");
+ break;
+ }
+ default: break;
+ }
+ }
+}
+
+void CTheScripts::HighlightImportantArea(uint32 id, float x1, float y1, float x2, float y2, float z)
+{
+ float infX, infY, supX, supY;
+ if (x1 < x2) {
+ infX = x1;
+ supX = x2;
+ } else {
+ infX = x2;
+ supX = x1;
+ }
+ if (y1 < y2) {
+ infY = y1;
+ supY = y2;
+ }
+ else {
+ infY = y2;
+ supY = y1;
+ }
+ CVector center;
+ center.x = (infX + supX) / 2;
+ center.y = (infY + supY) / 2;
+ center.z = (z <= MAP_Z_LOW_LIMIT) ? CWorld::FindGroundZForCoord(center.x, center.y) : z;
+ CShadows::RenderIndicatorShadow(id, 2, gpGoalTex, &center, supX - center.x, 0.0f, 0.0f, center.y - supY, 0);
+}
+
+void CTheScripts::HighlightImportantAngledArea(uint32 id, float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4, float z)
+{
+ float infX, infY, supX, supY, X, Y;
+ X = (x1 + x2) / 2;
+ Y = (y1 + y2) / 2;
+ supX = infX = X;
+ supY = infY = Y;
+ X = (x2 + x3) / 2;
+ Y = (y2 + y3) / 2;
+ infX = Min(infX, X);
+ supX = Max(supX, X);
+ infY = Min(infY, Y);
+ supY = Max(supY, Y);
+ X = (x3 + x4) / 2;
+ Y = (y3 + y4) / 2;
+ infX = Min(infX, X);
+ supX = Max(supX, X);
+ infY = Min(infY, Y);
+ supY = Max(supY, Y);
+ X = (x4 + x1) / 2;
+ Y = (y4 + y1) / 2;
+ infX = Min(infX, X);
+ supX = Max(supX, X);
+ infY = Min(infY, Y);
+ supY = Max(supY, Y);
+ CVector center;
+ center.x = (infX + supX) / 2;
+ center.y = (infY + supY) / 2;
+ center.z = (z <= MAP_Z_LOW_LIMIT) ? CWorld::FindGroundZForCoord(center.x, center.y) : z;
+ CShadows::RenderIndicatorShadow(id, 2, gpGoalTex, &center, supX - center.x, 0.0f, 0.0f, center.y - supY, 0);
+}
+
+bool CTheScripts::IsPedStopped(CPed* pPed)
+{
+ if (pPed->InVehicle())
+ return IsVehicleStopped(pPed->m_pMyVehicle);
+ 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->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) &&
+ !pPed->bIsInTheAir && !pPed->bIsLanding && pPed->bIsStanding && pPed->m_vecAnimMoveDelta.x == 0.0f && pPed->m_vecAnimMoveDelta.y == 0.0f;
+}
+
+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)
+ return;
+ if (pPed->CharCreatedBy != MISSION_CHAR)
+ return;
+ pPed->CharCreatedBy = RANDOM_CHAR;
+ if (pPed->m_nPedType == PEDTYPE_PROSTITUTE)
+ pPed->m_objectiveTimer = CTimer::GetTimeInMilliseconds() + 30000;
+ if (pPed->InVehicle()) {
+ if (pPed->m_pMyVehicle->pDriver == pPed) {
+ if (pPed->m_pMyVehicle->m_vehType == VEHICLE_TYPE_CAR) {
+ CCarCtrl::JoinCarWithRoadSystem(pPed->m_pMyVehicle);
+ pPed->m_pMyVehicle->AutoPilot.m_nCarMission = MISSION_CRUISE;
+ }
+ }
+ else {
+ if (pPed->m_pMyVehicle->m_vehType == VEHICLE_TYPE_CAR) {
+ pPed->SetObjective(OBJECTIVE_LEAVE_CAR, pPed->m_pMyVehicle);
+ pPed->bWanderPathAfterExitingCar = true;
+ }
+ }
+ }
+ bool flees = false;
+ PedState state;
+ eMoveState ms;
+ if (pPed->m_nPedState == PED_FLEE_ENTITY || pPed->m_nPedState == PED_FLEE_POS) {
+ ms = pPed->m_nMoveState;
+ state = pPed->m_nPedState;
+ flees = true;
+ }
+ pPed->ClearObjective();
+ pPed->bRespondsToThreats = true;
+ pPed->bScriptObjectiveCompleted = false;
+ pPed->bKindaStayInSamePlace = false;
+ pPed->ClearLeader();
+ if (pPed->IsPedInControl())
+ pPed->SetWanderPath(CGeneral::GetRandomNumber() & 7);
+ if (flees) {
+ pPed->SetPedState(state);
+ pPed->SetMoveState(ms);
+ }
+ --CPopulation::ms_nTotalMissionPeds;
+}
+
+void CTheScripts::CleanUpThisVehicle(CVehicle* pVehicle)
+{
+ if (!pVehicle)
+ return;
+ if (pVehicle->VehicleCreatedBy != MISSION_VEHICLE)
+ return;
+ pVehicle->bIsLocked = false;
+ CCarCtrl::RemoveFromInterestingVehicleList(pVehicle);
+ pVehicle->VehicleCreatedBy = RANDOM_VEHICLE;
+ ++CCarCtrl::NumRandomCars;
+ --CCarCtrl::NumMissionCars;
+}
+
+void CTheScripts::CleanUpThisObject(CObject* pObject)
+{
+ if (!pObject)
+ return;
+ if (pObject->ObjectCreatedBy != MISSION_OBJECT)
+ return;
+ pObject->ObjectCreatedBy = TEMP_OBJECT;
+ pObject->m_nEndOfLifeTime = CTimer::GetTimeInMilliseconds() + 20000000;
+ pObject->m_nRefModelIndex = -1;
+ pObject->bUseVehicleColours = false;
+ ++CObject::nNoTempObjects;
+}
+
+void CTheScripts::ReadObjectNamesFromScript()
+{
+ int32 varSpace = GetSizeOfVariableSpace();
+ uint32 ip = varSpace + 8;
+ NumberOfUsedObjects = Read2BytesFromScript(&ip);
+ ip += 2;
+ for (uint16 i = 0; i < NumberOfUsedObjects; i++) {
+ for (int j = 0; j < USED_OBJECT_NAME_LENGTH; j++)
+ UsedObjectArray[i].name[j] = ScriptSpace[ip++];
+ UsedObjectArray[i].index = 0;
+ }
+}
+
+void CTheScripts::UpdateObjectIndices()
+{
+ char name[USED_OBJECT_NAME_LENGTH];
+ char error[112];
+ for (int i = 1; i < NumberOfUsedObjects; i++) {
+ bool found = false;
+ for (int j = 0; j < MODELINFOSIZE && !found; j++) {
+ CBaseModelInfo* pModel = CModelInfo::GetModelInfo(j);
+ if (!pModel)
+ continue;
+ strcpy(name, pModel->GetName());
+#ifdef FIX_BUGS
+ for (int k = 0; k < USED_OBJECT_NAME_LENGTH && name[k]; k++)
+#else
+ for (int k = 0; k < USED_OBJECT_NAME_LENGTH; k++)
+#endif
+ name[k] = toupper(name[k]);
+ if (strcmp(name, UsedObjectArray[i].name) == 0) {
+ found = true;
+ UsedObjectArray[i].index = j;
+ }
+ }
+ if (!found) {
+ sprintf(error, "CTheScripts::UpdateObjectIndices - Couldn't find %s", UsedObjectArray[i].name);
+ debug("%s\n", error);
+ }
+ }
+}
+
+void CTheScripts::ReadMultiScriptFileOffsetsFromScript()
+{
+ int32 varSpace = GetSizeOfVariableSpace();
+ uint32 ip = varSpace + 3;
+ int32 objectSize = Read4BytesFromScript(&ip);
+ ip = objectSize + 8;
+ MainScriptSize = Read4BytesFromScript(&ip);
+ LargestMissionScriptSize = Read4BytesFromScript(&ip);
+ NumberOfMissionScripts = Read2BytesFromScript(&ip);
+ 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
new file mode 100644
index 00000000..272ecd4b
--- /dev/null
+++ b/src/control/Script6.cpp
@@ -0,0 +1,1803 @@
+#include "common.h"
+
+#include "Script.h"
+#include "ScriptCommands.h"
+
+#include "CarCtrl.h"
+#include "Cranes.h"
+#include "Credits.h"
+#include "CutsceneMgr.h"
+#include "DMAudio.h"
+#include "FileMgr.h"
+#include "Fire.h"
+#include "Frontend.h"
+#include "Garages.h"
+#include "General.h"
+#ifdef MISSION_REPLAY
+#include "GenericGameStorage.h"
+#endif
+#include "Messages.h"
+#include "Pad.h"
+#include "Particle.h"
+#include "Phones.h"
+#include "Population.h"
+#include "Pools.h"
+#include "Record.h"
+#include "Remote.h"
+#include "Restart.h"
+#include "SpecialFX.h"
+#include "Stats.h"
+#include "Streaming.h"
+#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)
+{
+ switch (command) {
+ //case COMMAND_FLASH_RADAR_BLIP:
+ /*
+ case COMMAND_IS_CHAR_IN_CONTROL:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ UpdateCompareFlag(pPed->IsPedInControl());
+ return 0;
+ }
+ */
+ case COMMAND_SET_GENERATE_CARS_AROUND_CAMERA:
+ CollectParameters(&m_nIp, 1);
+ CCarCtrl::bCarsGeneratedAroundCamera = (ScriptParams[0] != 0);
+ return 0;
+ 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);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ script_assert(pVehicle->m_vehType == VEHICLE_TYPE_CAR);
+ CAutomobile* pCar = (CAutomobile*)pVehicle;
+ pCar->bNotDamagedUpsideDown = (ScriptParams[1] != 0);
+ return 0;
+ }
+ case COMMAND_CAN_PLAYER_START_MISSION:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPlayerPed* pPlayerPed = CWorld::Players[ScriptParams[0]].m_pPed;
+ script_assert(pPlayerPed);
+ UpdateCompareFlag(pPlayerPed->IsPedInControl() || pPlayerPed->m_nPedState == PED_DRIVING);
+ return 0;
+ }
+ case COMMAND_MAKE_PLAYER_SAFE_FOR_CUTSCENE:
+ {
+ CollectParameters(&m_nIp, 1);
+#ifdef MISSION_REPLAY
+ AllowMissionReplay = 0;
+ SaveGameForPause(3);
+#endif
+ CPlayerInfo* pPlayerInfo = &CWorld::Players[ScriptParams[0]];
+ CPad::GetPad(ScriptParams[0])->SetDisablePlayerControls(PLAYERCONTROL_CUTSCENE);
+ pPlayerInfo->MakePlayerSafe(true);
+ CCutsceneMgr::StartCutsceneProcessing();
+ return 0;
+ }
+ case COMMAND_USE_TEXT_COMMANDS:
+ CollectParameters(&m_nIp, 1);
+ CTheScripts::UseTextCommands = (ScriptParams[0] != 0) ? 2 : 1;
+ return 0;
+ case COMMAND_SET_THREAT_FOR_PED_TYPE:
+ CollectParameters(&m_nIp, 2);
+ CPedType::AddThreat(ScriptParams[0], ScriptParams[1]);
+ return 0;
+ case COMMAND_CLEAR_THREAT_FOR_PED_TYPE:
+ CollectParameters(&m_nIp, 2);
+ CPedType::RemoveThreat(ScriptParams[0], ScriptParams[1]);
+ return 0;
+ case COMMAND_GET_CAR_COLOURS:
+ {
+ CollectParameters(&m_nIp, 1);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ ScriptParams[0] = pVehicle->m_currentColour1;
+ ScriptParams[1] = pVehicle->m_currentColour2;
+ StoreParameters(&m_nIp, 2);
+ return 0;
+ }
+ case COMMAND_SET_ALL_CARS_CAN_BE_DAMAGED:
+ CollectParameters(&m_nIp, 1);
+ CWorld::SetAllCarsCanBeDamaged(ScriptParams[0] != 0);
+ if (!ScriptParams[0])
+ CWorld::ExtinguishAllCarFiresInArea(FindPlayerCoors(), 4000.0f);
+ return 0;
+ case COMMAND_SET_CAR_CAN_BE_DAMAGED:
+ {
+ CollectParameters(&m_nIp, 2);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ pVehicle->bCanBeDamaged = ScriptParams[1] != 0;
+ if (!ScriptParams[1])
+ pVehicle->ExtinguishCarFire();
+ return 0;
+ }
+ //case COMMAND_MAKE_PLAYER_UNSAFE:
+ /*
+ case COMMAND_LOAD_COLLISION:
+ {
+ CollectParameters(&m_nIp, 1);
+ CTimer::Stop();
+ CGame::currLevel = (eLevelName)ScriptParams[0];
+ ISLAND_LOADING_IS(LOW)
+ {
+ CStreaming::RemoveUnusedBigBuildings(CGame::currLevel);
+ CStreaming::RemoveUnusedBuildings(CGame::currLevel);
+ }
+ CCollision::SortOutCollisionAfterLoad();
+ ISLAND_LOADING_ISNT(HIGH)
+ {
+ CStreaming::RequestIslands(CGame::currLevel);
+ CStreaming::LoadAllRequestedModels(true);
+ }
+ CTimer::Update();
+ return 0;
+ }
+ case COMMAND_GET_BODY_CAST_HEALTH:
+ // ScriptParams[0] = CObject::nBodyCastHealth;
+ // StoreParameters(&m_nIp, 1);
+ return 0;
+ */
+ case COMMAND_SET_CHARS_CHATTING:
+ {
+ CollectParameters(&m_nIp, 3);
+ CPed* pPed1 = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ CPed* pPed2 = CPools::GetPedPool()->GetAt(ScriptParams[1]);
+ script_assert(pPed1 && pPed2);
+ pPed1->SetChat(pPed2, ScriptParams[2]);
+ pPed2->SetChat(pPed1, ScriptParams[2]);
+ return 0;
+ }
+ //case COMMAND_MAKE_PLAYER_SAFE:
+ /*
+ case COMMAND_SET_CAR_STAYS_IN_CURRENT_LEVEL:
+ {
+ CollectParameters(&m_nIp, 2);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ if (ScriptParams[1])
+ pVehicle->m_nZoneLevel = CTheZones::GetLevelFromPosition(&pVehicle->GetPosition());
+ else
+ pVehicle->m_nZoneLevel = LEVEL_GENERIC;
+ return 0;
+ }
+ case COMMAND_SET_CHAR_STAYS_IN_CURRENT_LEVEL:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ if (ScriptParams[1])
+ pPed->m_nZoneLevel = CTheZones::GetLevelFromPosition(&pPed->GetPosition());
+ else
+ pPed->m_nZoneLevel = LEVEL_GENERIC;
+ return 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_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_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;
+ case COMMAND_REGISTER_CRIMINAL_CAUGHT:
+ CStats::AnotherCriminalCaught();
+ return 0;
+ case COMMAND_REGISTER_AMBULANCE_LEVEL:
+ CollectParameters(&m_nIp, 1);
+ CStats::RegisterLevelAmbulanceMission(ScriptParams[0]);
+ return 0;
+ case COMMAND_REGISTER_FIRE_EXTINGUISHED:
+ CStats::AnotherFireExtinguished();
+ return 0;
+ case COMMAND_TURN_PHONE_ON:
+ CollectParameters(&m_nIp, 1);
+ gPhoneInfo.m_aPhones[ScriptParams[0]].m_nState = PHONE_STATE_9;
+ return 0;
+ /*
+ case COMMAND_REGISTER_LONGEST_DODO_FLIGHT:
+ CollectParameters(&m_nIp, 1);
+ CStats::RegisterLongestFlightInDodo(ScriptParams[0]);
+ return 0;
+ */
+ case COMMAND_GET_OFFSET_FROM_CAR_IN_WORLD_COORDS:
+ {
+ 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(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;
+ case COMMAND_IS_GERMAN_GAME:
+ UpdateCompareFlag(CGame::germanGame);
+ return 0;
+ case COMMAND_CLEAR_MISSION_AUDIO:
+ 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];
+ return 0;
+ case COMMAND_SET_FADE_IN_AFTER_NEXT_DEATH:
+ CollectParameters(&m_nIp, 1);
+ CRestart::bFadeInAfterNextDeath = !!ScriptParams[0];
+ return 0;
+ case COMMAND_SET_GANG_PED_MODEL_PREFERENCE:
+ CollectParameters(&m_nIp, 2);
+ CGangs::SetGangPedModelOverride(ScriptParams[0], ScriptParams[1]);
+ return 0;
+ */
+ case COMMAND_SET_CHAR_USE_PEDNODE_SEEK:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ if (ScriptParams[1])
+ pPed->m_pNextPathNode = nil;
+ pPed->bUsePedNodeSeek = !!ScriptParams[1];
+ return 0;
+ }
+ /*
+ case COMMAND_SWITCH_VEHICLE_WEAPONS:
+ {
+ CollectParameters(&m_nIp, 2);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ pVehicle->bGunSwitchedOff = !ScriptParams[1];
+ return 0;
+ }
+ case COMMAND_SET_GET_OUT_OF_JAIL_FREE:
+ 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);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ 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)
+ CStats::LastMissionPassedName[0] = '\0';
+#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);
+ CRunningScript* pMissionScript = CTheScripts::StartNewScript(SIZE_MAIN_SCRIPT);
+ CTimer::Resume();
+ pMissionScript->m_bIsMissionScript = true;
+ pMissionScript->m_bMissionFlag = true;
+ CTheScripts::bAlreadyRunningAMissionScript = true;
+ CGameLogic::ClearShortCut();
+ return 0;
+ }
+ case COMMAND_SET_OBJECT_DRAW_LAST:
+ {
+ CollectParameters(&m_nIp, 2);
+ CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
+ script_assert(pObject);
+ pObject->bDrawLast = !!ScriptParams[1];
+ return 0;
+ }
+ case COMMAND_GET_AMMO_IN_PLAYER_WEAPON:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPlayerPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
+ script_assert(pPed);
+ 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);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ 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;
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ }
+ case COMMAND_REGISTER_KILL_FRENZY_PASSED:
+ CStats::AnotherKillFrenzyPassed();
+ return 0;
+ case COMMAND_SET_CHAR_SAY:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ switch (ScriptParams[1]) {
+ case SCRIPT_SOUND_CHUNKY_RUN_SHOUT:
+ pPed->Say(SOUND_PED_FLEE_RUN);
+ break;
+ case SCRIPT_SOUND_SECURITY_GUARD_AWAY_SHOUT:
+ pPed->Say(SOUND_PED_FLEE_RUN);
+ break;
+ case SCRIPT_SOUND_SWAT_PED_SHOUT:
+ pPed->Say(SOUND_PED_PURSUIT_SWAT);
+ break;
+ case SCRIPT_SOUND_AMMUNATION_CHAT_1:
+ pPed->Say(SOUND_AMMUNATION_WELCOME_1);
+ break;
+ case SCRIPT_SOUND_AMMUNATION_CHAT_2:
+ pPed->Say(SOUND_AMMUNATION_WELCOME_2);
+ break;
+ case SCRIPT_SOUND_AMMUNATION_CHAT_3:
+ pPed->Say(SOUND_AMMUNATION_WELCOME_3);
+ break;
+ default:
+ break;
+ }
+ return 0;
+ }
+ */
+ case COMMAND_SET_NEAR_CLIP:
+ CollectParameters(&m_nIp, 1);
+ TheCamera.SetNearClipScript(*(float*)&ScriptParams[0]);
+ return 0;
+ case COMMAND_SET_RADIO_CHANNEL:
+ 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];
+ return 0;
+ case COMMAND_OVERRIDE_POLICE_STATION_LEVEL:
+ CollectParameters(&m_nIp, 1);
+ CRestart::OverridePoliceStationLevel = ScriptParams[0];
+ return 0;
+ case COMMAND_FORCE_RAIN:
+ CollectParameters(&m_nIp, 1);
+ CWeather::bScriptsForceRain = !!ScriptParams[0];
+ return 0;
+ case COMMAND_DOES_GARAGE_CONTAIN_CAR:
+ {
+ CollectParameters(&m_nIp, 2);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[1]);
+ script_assert(pVehicle);
+ UpdateCompareFlag(CGarages::IsThisCarWithinGarageArea(ScriptParams[0], pVehicle));
+ return 0;
+ }
+ */
+ case COMMAND_SET_CAR_TRACTION:
+ {
+ CollectParameters(&m_nIp, 2);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ float fTraction = *(float*)&ScriptParams[1];
+ script_assert(pVehicle->m_vehType == VEHICLE_TYPE_CAR || pVehicle->m_vehType == VEHICLE_TYPE_BIKE);
+ if (pVehicle->m_vehType == VEHICLE_TYPE_CAR)
+ ((CAutomobile*)pVehicle)->m_fTraction = fTraction;
+ else
+ ((CBike*)pVehicle)->m_fTraction = fTraction;
+ return 0;
+ }
+ case COMMAND_ARE_MEASUREMENTS_IN_METRES:
+#ifdef USE_MEASUREMENTS_IN_METERS
+ UpdateCompareFlag(true);
+#else
+ UpdateCompareFlag(false);
+#endif
+ return 0;
+ case COMMAND_CONVERT_METRES_TO_FEET:
+ {
+ CollectParameters(&m_nIp, 1);
+ float fMeterValue = *(float*)&ScriptParams[0];
+ float fFeetValue = fMeterValue / METERS_IN_FOOT;
+ *(float*)&ScriptParams[0] = fFeetValue;
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ }
+ /*
+ case COMMAND_MARK_ROADS_BETWEEN_LEVELS:
+ {
+ CollectParameters(&m_nIp, 6);
+ 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];
+ }
+ ThePaths.MarkRoadsBetweenLevelsInArea(infX, supX, infY, supY, infZ, supZ);
+ return 0;
+ }
+ case COMMAND_MARK_PED_ROADS_BETWEEN_LEVELS:
+ {
+ CollectParameters(&m_nIp, 6);
+ 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];
+ }
+ ThePaths.PedMarkRoadsBetweenLevelsInArea(infX, supX, infY, supY, infZ, supZ);
+ return 0;
+ }
+ */
+ case COMMAND_SET_CAR_AVOID_LEVEL_TRANSITIONS:
+ {
+ CollectParameters(&m_nIp, 2);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ pVehicle->AutoPilot.m_bStayInCurrentLevel = !!ScriptParams[1];
+ return 0;
+ }
+ /*
+ case COMMAND_SET_CHAR_AVOID_LEVEL_TRANSITIONS:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[1]);
+ script_assert(pPed);
+ // not implemented
+ return 0;
+ }
+ case COMMAND_IS_THREAT_FOR_PED_TYPE:
+ CollectParameters(&m_nIp, 2);
+ UpdateCompareFlag(CPedType::IsThreat(ScriptParams[0], ScriptParams[1]));
+ return 0;
+ */
+ case COMMAND_CLEAR_AREA_OF_CHARS:
+ {
+ CollectParameters(&m_nIp, 6);
+ 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];
+ }
+ CWorld::ClearPedsFromArea(infX, infY, infZ, supX, supY, supZ);
+ return 0;
+ }
+ case COMMAND_SET_TOTAL_NUMBER_OF_MISSIONS:
+ CollectParameters(&m_nIp, 1);
+ CStats::SetTotalNumberMissions(CGame::germanGame ? ScriptParams[0] - 2 : ScriptParams[0]);
+ return 0;
+ case COMMAND_CONVERT_METRES_TO_FEET_INT:
+ CollectParameters(&m_nIp, 1);
+ ScriptParams[0] *= FEET_IN_METER;
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ case COMMAND_REGISTER_FASTEST_TIME:
+ CollectParameters(&m_nIp, 2);
+ CStats::RegisterFastestTime(ScriptParams[0], ScriptParams[1]);
+ return 0;
+ case COMMAND_REGISTER_HIGHEST_SCORE:
+ CollectParameters(&m_nIp, 2);
+ CStats::RegisterHighestScore(ScriptParams[0], ScriptParams[1]);
+ return 0;
+ //case COMMAND_WARP_CHAR_INTO_CAR_AS_PASSENGER:
+ case COMMAND_IS_CAR_PASSENGER_SEAT_FREE:
+ {
+ CollectParameters(&m_nIp, 2);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ UpdateCompareFlag(ScriptParams[1] < pVehicle->m_nNumMaxPassengers && pVehicle->pPassengers[ScriptParams[1]] == nil);
+ return 0;
+ }
+ /*
+ case COMMAND_GET_CHAR_IN_CAR_PASSENGER_SEAT:
+ {
+ CollectParameters(&m_nIp, 2);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ script_assert(ScriptParams[1] >= 0 && ScriptParams[1] < ARRAY_SIZE(pVehicle->pPassengers));
+ CPed* pPassenger = pVehicle->pPassengers[ScriptParams[1]];
+ ScriptParams[0] = CPools::GetPedPool()->GetIndex(pPassenger);
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ }
+ */
+ case COMMAND_SET_CHAR_IS_CHRIS_CRIMINAL:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ pPed->bChrisCriminal = !!ScriptParams[1];
+ return 0;
+ }
+ case COMMAND_START_CREDITS:
+ CCredits::Start();
+ return 0;
+ case COMMAND_STOP_CREDITS:
+ CCredits::Stop();
+ return 0;
+ case COMMAND_ARE_CREDITS_FINISHED:
+ UpdateCompareFlag(CCredits::AreCreditsDone());
+ return 0;
+ case COMMAND_CREATE_SINGLE_PARTICLE:
+ CollectParameters(&m_nIp, 8);
+ 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);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ if (ScriptParams[1])
+ pPed->m_nZoneLevel = LEVEL_IGNORE;
+ else
+ pPed->m_nZoneLevel = CTheZones::GetLevelFromPosition(&pPed->GetPosition());
+ return 0;
+ }
+ case COMMAND_GET_CHASE_CAR:
+ {
+ CollectParameters(&m_nIp, 1);
+ CVehicle* pVehicle = CRecordDataForChase::TurnChaseCarIntoScriptCar(ScriptParams[0]);
+ ScriptParams[0] = CPools::GetVehiclePool()->GetIndex(pVehicle);
+ StoreParameters(&m_nIp, 1);
+ if (m_bIsMissionScript)
+ CTheScripts::MissionCleanup.AddEntityToList(ScriptParams[0], CLEANUP_CAR);
+ return 0;
+ }
+ case COMMAND_START_BOAT_FOAM_ANIMATION:
+ CSpecialParticleStuff::StartBoatFoamAnimation();
+ return 0;
+ case COMMAND_UPDATE_BOAT_FOAM_ANIMATION:
+ {
+ CollectParameters(&m_nIp, 1);
+ CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
+ script_assert(pObject);
+ 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]) {
+ CGame::playingIntro = true;
+ CStreaming::RemoveCurrentZonesModels();
+ } else {
+ CGame::playingIntro = false;
+ DMAudio.ChangeMusicMode(MUSICMODE_GAME);
+ int mi;
+ CModelInfo::GetModelInfo("bridgefukb", &mi);
+ CStreaming::RequestModel(mi, STREAMFLAGS_DEPENDENCY);
+ CStreaming::LoadAllRequestedModels(false);
+ }
+ return 0;
+ */
+ case COMMAND_SET_PLAYER_HOOKER:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPlayerInfo* pPlayerInfo = &CWorld::Players[ScriptParams[0]];
+ if (ScriptParams[1] < 0) {
+ pPlayerInfo->m_pHooker = nil;
+ pPlayerInfo->m_nNextSexFrequencyUpdateTime = 0;
+ pPlayerInfo->m_nNextSexMoneyUpdateTime = 0;
+ } else {
+ 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;
+ }
+ return 0;
+ }
+ case COMMAND_PLAY_END_OF_GAME_TUNE:
+ DMAudio.PlayPreloadedCutSceneMusic();
+ return 0;
+ case COMMAND_STOP_END_OF_GAME_TUNE:
+ DMAudio.StopCutSceneMusic();
+ DMAudio.ChangeMusicMode(MUSICMODE_GAME);
+ return 0;
+ case COMMAND_GET_CAR_MODEL:
+ {
+ CollectParameters(&m_nIp, 1);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ ScriptParams[0] = pVehicle->GetModelIndex();
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ }
+ case COMMAND_IS_PLAYER_SITTING_IN_CAR:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPlayerPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
+ script_assert(pPed);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[1]);
+ 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:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPlayerPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
+ script_assert(pPed);
+ 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 || 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[1] == 0);
+ return 0;
+ }
+ /*
+ case COMMAND_IS_PLAYER_LIFTING_A_PHONE:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPlayerPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
+ script_assert(pPed);
+ UpdateCompareFlag(pPed->GetPedState() == PED_MAKE_CALL);
+ return 0;
+ }
+ */
+ case COMMAND_IS_CHAR_SITTING_IN_CAR:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[1]);
+ script_assert(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:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ UpdateCompareFlag(pPed->GetPedState() == PED_DRIVING && pPed->m_objective != OBJECTIVE_LEAVE_CAR);
+ return 0;
+ }
+ case COMMAND_IS_PLAYER_ON_FOOT:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPlayerPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
+ script_assert(pPed);
+ UpdateCompareFlag(!pPed->bInVehicle && pPed->m_objective != OBJECTIVE_ENTER_CAR_AS_PASSENGER &&
+ pPed->m_objective != OBJECTIVE_ENTER_CAR_AS_DRIVER);
+ return 0;
+ }
+ case COMMAND_IS_CHAR_ON_FOOT:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ UpdateCompareFlag(!pPed->bInVehicle && pPed->m_objective != OBJECTIVE_ENTER_CAR_AS_PASSENGER &&
+ pPed->m_objective != OBJECTIVE_ENTER_CAR_AS_DRIVER);
+ return 0;
+ }
+ default:
+ script_assert(0);
+ }
+ return -1;
+}
+
+int8 CRunningScript::ProcessCommands1100To1199(int32 command)
+{
+ char tmp[48];
+ switch (command) {
+ /*
+ case COMMAND_LOAD_COLLISION_WITH_SCREEN:
+ CollectParameters(&m_nIp, 1);
+ CTimer::Stop();
+ CGame::currLevel = (eLevelName)ScriptParams[0];
+ if (CGame::currLevel != CCollision::ms_collisionInMemory) {
+ ISLAND_LOADING_IS(LOW)
+ {
+ DMAudio.SetEffectsFadeVol(0);
+ CPad::StopPadsShaking();
+ CCollision::LoadCollisionScreen(CGame::currLevel);
+ DMAudio.Service();
+ }
+ CPopulation::DealWithZoneChange(CCollision::ms_collisionInMemory, CGame::currLevel, false);
+
+ ISLAND_LOADING_IS(LOW)
+ {
+ CStreaming::RemoveUnusedBigBuildings(CGame::currLevel);
+ CStreaming::RemoveUnusedBuildings(CGame::currLevel);
+ }
+ CCollision::SortOutCollisionAfterLoad();
+
+ ISLAND_LOADING_ISNT(HIGH)
+ CStreaming::RequestIslands(CGame::currLevel);
+
+ ISLAND_LOADING_IS(LOW)
+ CStreaming::RequestBigBuildings(CGame::currLevel);
+
+ ISLAND_LOADING_ISNT(HIGH)
+ CStreaming::LoadAllRequestedModels(true);
+
+ ISLAND_LOADING_IS(LOW)
+ DMAudio.SetEffectsFadeVol(127);
+ }
+ CTimer::Update();
+ return 0;
+ */
+ case COMMAND_LOAD_SPLASH_SCREEN:
+ CTheScripts::ReadTextLabelFromScript(&m_nIp, tmp);
+ for (int i = 0; i < KEY_LENGTH_IN_SCRIPT; i++)
+ tmp[i] = tolower(tmp[i]);
+ m_nIp += 8;
+ LoadSplash(tmp);
+ return 0;
+ /*
+ case COMMAND_SET_CAR_IGNORE_LEVEL_TRANSITIONS:
+ {
+ CollectParameters(&m_nIp, 2);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ if (ScriptParams[1])
+ pVehicle->m_nZoneLevel = LEVEL_IGNORE;
+ else
+ pVehicle->m_nZoneLevel = CTheZones::GetLevelFromPosition(&pVehicle->GetPosition());
+ return 0;
+ }
+ case COMMAND_MAKE_CRAIGS_CAR_A_BIT_STRONGER:
+ {
+ 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->bMoreResistantToDamage = ScriptParams[1];
+ return 0;
+ }
+ */
+ case COMMAND_SET_JAMES_CAR_ON_PATH_TO_PLAYER:
+ {
+ CollectParameters(&m_nIp, 1);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ CCarCtrl::JoinCarWithRoadSystemGotoCoors(pVehicle, FindPlayerCoors(), false);
+ return 0;
+ }
+ case COMMAND_LOAD_END_OF_GAME_TUNE:
+ DMAudio.ChangeMusicMode(MUSICMODE_CUTSCENE);
+ printf("Start preload end of game audio\n");
+ 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;
+ */
+ case COMMAND_SET_OBJECT_ROTATION:
+ {
+ CollectParameters(&m_nIp, 4);
+ CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
+ script_assert(pObject);
+ CWorld::Remove(pObject);
+ pObject->SetOrientation(
+ DEGTORAD(*(float*)&ScriptParams[1]),
+ DEGTORAD(*(float*)&ScriptParams[2]),
+ DEGTORAD(*(float*)&ScriptParams[3]));
+ pObject->GetMatrix().UpdateRW();
+ pObject->UpdateRwFrame();
+ CWorld::Add(pObject);
+ return 0;
+ }
+ case COMMAND_GET_DEBUG_CAMERA_COORDINATES:
+ *(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);
+ return 0;
+ case COMMAND_IS_PLAYER_TARGETTING_ANY_CHAR:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPlayerPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
+ script_assert(pPed);
+ CEntity* pTarget = pPed->m_pPointGunAt;
+ UpdateCompareFlag(pTarget && pTarget->IsPed());
+ return 0;
+ }
+ */
+ case COMMAND_IS_PLAYER_TARGETTING_CHAR:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPlayerPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
+ script_assert(pPed);
+ CPed* pTestedPed = CPools::GetPedPool()->GetAt(ScriptParams[1]);
+ script_assert(pTestedPed);
+ CEntity* pTarget = pPed->m_pPointGunAt;
+ 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);
+ CPlayerPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
+ script_assert(pPed);
+ CObject* pTestedObject = CPools::GetObjectPool()->GetAt(ScriptParams[1]);
+ script_assert(pTestedObject);
+ CEntity* pTarget = pPed->m_pPointGunAt;
+ UpdateCompareFlag(pTarget && pTarget->IsObject() && pTarget == pTestedObject);
+ return 0;
+ }
+ */
+ case COMMAND_TERMINATE_ALL_SCRIPTS_WITH_THIS_NAME:
+ {
+ CTheScripts::ReadTextLabelFromScript(&m_nIp, tmp);
+ for (int i = 0; i < KEY_LENGTH_IN_SCRIPT; i++)
+ tmp[i] = tolower(tmp[i]);
+ m_nIp += 8;
+ CRunningScript* pScript = CTheScripts::pActiveScripts;
+ while (pScript) {
+ CRunningScript* pNext = pScript->next;
+ if (strcmp(pScript->m_abScriptName, tmp) == 0) {
+ pScript->RemoveScriptFromList(&CTheScripts::pActiveScripts);
+ pScript->AddScriptToList(&CTheScripts::pIdleScripts);
+ }
+ pScript = pNext;
+ }
+ return 0;
+ }
+ case COMMAND_DISPLAY_TEXT_WITH_NUMBER:
+ {
+ CollectParameters(&m_nIp, 2);
+ wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ CTheScripts::IntroTextLines[CTheScripts::NumberOfIntroTextLinesThisFrame].m_fAtX = *(float*)&ScriptParams[0];
+ CTheScripts::IntroTextLines[CTheScripts::NumberOfIntroTextLinesThisFrame].m_fAtY = *(float*)&ScriptParams[1];
+ CollectParameters(&m_nIp, 1);
+ CMessages::InsertNumberInString(text, ScriptParams[0], -1, -1, -1, -1, -1,
+ CTheScripts::IntroTextLines[CTheScripts::NumberOfIntroTextLinesThisFrame++].m_Text);
+ return 0;
+ }
+ case COMMAND_DISPLAY_TEXT_WITH_2_NUMBERS:
+ {
+ CollectParameters(&m_nIp, 2);
+ wchar* text = CTheScripts::GetTextByKeyFromScript(&m_nIp);
+ CTheScripts::IntroTextLines[CTheScripts::NumberOfIntroTextLinesThisFrame].m_fAtX = *(float*)&ScriptParams[0];
+ CTheScripts::IntroTextLines[CTheScripts::NumberOfIntroTextLinesThisFrame].m_fAtY = *(float*)&ScriptParams[1];
+ CollectParameters(&m_nIp, 2);
+ CMessages::InsertNumberInString(text, ScriptParams[0], ScriptParams[1], -1, -1, -1, -1,
+ CTheScripts::IntroTextLines[CTheScripts::NumberOfIntroTextLinesThisFrame++].m_Text);
+ return 0;
+ }
+ case COMMAND_FAIL_CURRENT_MISSION:
+ CTheScripts::FailCurrentMission = 2;
+ 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)
+ pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
+ float range = *(float*)&ScriptParams[3];
+ int mi = ScriptParams[4] < 0 ? CTheScripts::UsedObjectArray[-ScriptParams[4]].index : ScriptParams[4];
+ int16 total;
+ CEntity* apEntities[16];
+ CWorld::FindObjectsOfTypeInRange(mi, pos, range, true, &total, 16, apEntities, false, false, false, true, true);
+ CEntity* pClosestEntity = nil;
+ float min_dist = 2.0f * range;
+ for (int i = 0; i < total; i++) {
+ float dist = (apEntities[i]->GetPosition() - pos).Magnitude();
+ if (dist < min_dist) {
+ min_dist = dist;
+ pClosestEntity = apEntities[i];
+ }
+ }
+ if (pClosestEntity && pClosestEntity->IsDummy()) {
+ CPopulation::ConvertToRealObject((CDummyObject*)pClosestEntity);
+ CWorld::FindObjectsOfTypeInRange(mi, pos, range, true, &total, 16, apEntities, false, false, false, true, true);
+ pClosestEntity = nil;
+ float min_dist = 2.0f * range;
+ for (int i = 0; i < total; i++) {
+ float dist = (apEntities[i]->GetPosition() - pos).Magnitude();
+ if (dist < min_dist) {
+ min_dist = dist;
+ pClosestEntity = apEntities[i];
+ }
+ }
+ if (pClosestEntity->IsDummy())
+ pClosestEntity = nil;
+ }
+ if (pClosestEntity) {
+ script_assert(pClosestEntity->IsObject());
+ CObject* pObject = (CObject*)pClosestEntity;
+ pObject->ObjectCreatedBy = MISSION_OBJECT;
+ ScriptParams[0] = CPools::GetObjectPool()->GetIndex(pObject);
+ } else {
+ ScriptParams[0] = -1;
+ }
+ StoreParameters(&m_nIp, 1);
+ return 0;
+*/
+ }
+ /*
+ case COMMAND_PLACE_OBJECT_RELATIVE_TO_OBJECT:
+ {
+ CollectParameters(&m_nIp, 5);
+ CObject* pObject = CPools::GetObjectPool()->GetAt(ScriptParams[0]);
+ script_assert(pObject);
+ CObject* pTarget = CPools::GetObjectPool()->GetAt(ScriptParams[1]);
+ script_assert(pTarget);
+ CVector offset = *(CVector*)&ScriptParams[2];
+ 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);
+ CCarAI::TellOccupantsToLeaveCar(pVehicle);
+ return 0;
+ }
+ case COMMAND_SET_INTERPOLATION_PARAMETERS:
+ CollectParameters(&m_nIp, 2);
+ 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);
+ CVector pos = *(CVector*)&ScriptParams[0];
+ if (pos.z <= MAP_Z_LOW_LIMIT)
+ pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
+ float destX = *(float*)&ScriptParams[3];
+ float destY = *(float*)&ScriptParams[4];
+ int32 nid = ThePaths.FindNodeClosestToCoors(pos, 0, 999999.9f, true, true);
+ CPathNode* pNode = &ThePaths.m_pathNodes[nid];
+ *(CVector*)&ScriptParams[0] = pNode->GetPosition();
+ *(float*)&ScriptParams[3] = ThePaths.FindNodeOrientationForCarPlacementFacingDestination(nid, destX, destY, true);
+ StoreParameters(&m_nIp, 4);
+ return 0;
+ }
+ case COMMAND_GET_CLOSEST_CAR_NODE_WITH_HEADING_AWAY_POINT:
+ {
+ CollectParameters(&m_nIp, 5);
+ CVector pos = *(CVector*)&ScriptParams[0];
+ if (pos.z <= MAP_Z_LOW_LIMIT)
+ pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
+ float destX = *(float*)&ScriptParams[3];
+ float destY = *(float*)&ScriptParams[4];
+ int32 nid = ThePaths.FindNodeClosestToCoors(pos, 0, 999999.9f, true, true);
+ CPathNode* pNode = &ThePaths.m_pathNodes[nid];
+ *(CVector*)&ScriptParams[0] = pNode->GetPosition();
+ *(float*)&ScriptParams[3] = ThePaths.FindNodeOrientationForCarPlacementFacingDestination(nid, destX, destY, false);
+ 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:
+ {
+ 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:
+ {
+ 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);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ pVehicle->AutoPilot.m_bStayInFastLane = !ScriptParams[1];
+ return 0;
+ }
+ case COMMAND_CLEAR_CHAR_LAST_WEAPON_DAMAGE:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ 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]);
+ 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, 9);
+ 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->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 && pPed->GetPedState() != PED_ABSEIL)
+ continue;
+ if (pPed->bRemoveFromWorld)
+ continue;
+ if (pPed->bFadeOut)
+ continue;
+ if (pPed->bIsLeader || pPed->m_leader)
+ continue;
+ if (!pPed->IsWithinArea(x1, y1, x2, y2))
+ continue;
+ if (pos.z - COP_PED_FIND_Z_OFFSET > pPed->GetPosition().z)
+ continue;
+ if (pos.z + COP_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_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, ZONE_DEFAULT);
+ if (nZone != -1)
+ m_nIp += KEY_LENGTH_IN_SCRIPT;
+ CZone* pZone = CTheZones::GetNavigationZone(nZone);
+ int ped_handle = -1;
+ CVector pos = FindPlayerCoors();
+ 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->m_nPedType != PEDTYPE_COP)
+ continue;
+ if (pPed->CharCreatedBy != RANDOM_CHAR)
+ continue;
+ if (!pPed->IsPedInControl() && pPed->GetPedState() != PED_DRIVING)
+ continue;
+ if (pPed->bRemoveFromWorld)
+ continue;
+ if (pPed->bFadeOut)
+ continue;
+ if (pPed->bIsLeader || pPed->m_leader)
+ continue;
+ if (!CTheZones::PointLiesWithinZone(&pPed->GetPosition(), pZone))
+ continue;
+ if (pos.z - COP_PED_FIND_Z_OFFSET > pPed->GetPosition().z)
+ continue;
+ if (pos.z + COP_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_SET_CHAR_OBJ_FLEE_CAR:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[1]);
+ script_assert(pVehicle);
+ pPed->bScriptObjectiveCompleted = false;
+ pPed->SetObjective(OBJECTIVE_FLEE_CAR, pVehicle);
+ return 0;
+ }
+ case COMMAND_GET_DRIVER_OF_CAR:
+ {
+ CollectParameters(&m_nIp, 1);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ CPed* pDriver = pVehicle->pDriver;
+ if (pDriver)
+ ScriptParams[0] = CPools::GetPedPool()->GetIndex(pDriver);
+ else
+ ScriptParams[0] = -1;
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ }
+ case COMMAND_GET_NUMBER_OF_FOLLOWERS:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPed* pLeader = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pLeader);
+ int total = 0;
+ int i = CPools::GetPedPool()->GetSize();
+ while (--i) {
+ CPed* pPed = CPools::GetPedPool()->GetSlot(i);
+ if (!pPed)
+ continue;
+ if (pPed->m_leader == pLeader)
+ total++;
+ }
+ ScriptParams[0] = total;
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ }
+ case COMMAND_GIVE_REMOTE_CONTROLLED_MODEL_TO_PLAYER:
+ {
+ CollectParameters(&m_nIp, 6);
+ CVector pos = *(CVector*)&ScriptParams[1];
+ if (pos.z <= MAP_Z_LOW_LIMIT)
+ pos.z = CWorld::FindGroundZForCoord(pos.x, pos.y);
+ CRemote::GivePlayerRemoteControlledCar(pos.x, pos.y, pos.z, DEGTORAD(*(float*)&ScriptParams[4]), ScriptParams[5]);
+ return 0;
+ }
+ case COMMAND_GET_CURRENT_PLAYER_WEAPON:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
+ script_assert(pPed);
+ ScriptParams[0] = pPed->GetWeapon()->m_eWeaponType;
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ }
+ case COMMAND_GET_CURRENT_CHAR_WEAPON:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ ScriptParams[0] = pPed->GetWeapon()->m_eWeaponType;
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ }
+ case COMMAND_LOCATE_CHAR_ANY_MEANS_OBJECT_2D:
+ case COMMAND_LOCATE_CHAR_ON_FOOT_OBJECT_2D:
+ case COMMAND_LOCATE_CHAR_IN_CAR_OBJECT_2D:
+ case COMMAND_LOCATE_CHAR_ANY_MEANS_OBJECT_3D:
+ case COMMAND_LOCATE_CHAR_ON_FOOT_OBJECT_3D:
+ case COMMAND_LOCATE_CHAR_IN_CAR_OBJECT_3D:
+ LocateCharObjectCommand(command, &m_nIp);
+ return 0;
+ case COMMAND_SET_CAR_TEMP_ACTION:
+ {
+ CollectParameters(&m_nIp, 3);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ 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);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ pVehicle->AutoPilot.m_nTempAction = TEMPACT_HANDBRAKETURNRIGHT;
+ pVehicle->AutoPilot.m_nTimeTempAction = CTimer::GetTimeInMilliseconds() + ScriptParams[1];
+ return 0;
+ }
+ case COMMAND_SET_CAR_HANDBRAKE_STOP:
+ {
+ CollectParameters(&m_nIp, 2);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ pVehicle->AutoPilot.m_nTempAction = TEMPACT_HANDBRAKESTRAIGHT;
+ 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->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;
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ case COMMAND_IS_PLAYER_ON_ANY_BIKE:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
+ script_assert(pPed);
+ UpdateCompareFlag(pPed->bInVehicle && pPed->m_pMyVehicle->GetVehicleAppearance() == VEHICLE_APPEARANCE_BIKE);
+ return 0;
+ }
+ /*
+ case COMMAND_IS_CHAR_LYING_DOWN:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ UpdateCompareFlag(pPed->bFallenDown);
+ return 0;
+ }
+ */
+ case COMMAND_CAN_CHAR_SEE_DEAD_CHAR:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ int pedtype = ScriptParams[1];
+ bool can = false;
+ for (int i = 0; i < pPed->m_numNearPeds; i++) {
+ CPed* pTestPed = pPed->m_nearPeds[i];
+ if (pTestPed->m_fHealth <= 0.0f && pTestPed->m_nPedType == pedtype && pPed->OurPedCanSeeThisOne(pTestPed))
+ can = true;
+ }
+ UpdateCompareFlag(can);
+ return 0;
+ }
+ case COMMAND_SET_ENTER_CAR_RANGE_MULTIPLIER:
+ CollectParameters(&m_nIp, 1);
+ CPed::nEnterCarRangeMultiplier = *(float*)&ScriptParams[0];
+ return 0;
+ case COMMAND_SET_THREAT_REACTION_RANGE_MULTIPLIER:
+ CollectParameters(&m_nIp, 1);
+ CPed::nThreatReactionRangeMultiplier = *(float*)&ScriptParams[0];
+ return 0;
+ case COMMAND_SET_CHAR_CEASE_ATTACK_TIMER:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ 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);
+ }
+ return -1;
+}
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..a75692a0
--- /dev/null
+++ b/src/control/Script8.cpp
@@ -0,0 +1,613 @@
+#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];
+ memset(key, 0, KEY_LENGTH_IN_SCRIPT);
+ CTheScripts::ReadTextLabelFromScript(&m_nIp, key);
+ m_nIp += KEY_LENGTH_IN_SCRIPT;
+ CVector pos = pPlayerInfo->GetPos();
+ CZone *infoZone = CTheZones::FindInformationZoneForPosition(&pos);
+ UpdateCompareFlag(strncmp(key, infoZone->name, 8) == 0); // original code doesn't seem to be using strncmp in here and compare 2 ints instead
+ return 0;
+ }
+ case COMMAND_CLEAR_CHAR_ICE_CREAM_PURCHASE:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ if (pPed->m_attractor)
+ GetPedAttractorManager()->DeRegisterPed(pPed, pPed->m_attractor);
+ return 0;
+ }
+ case COMMAND_IS_IN_CAR_FIRE_BUTTON_PRESSED:
+ UpdateCompareFlag(CPad::GetPad(0)->GetCarGunFired());
+ return 0;
+ case COMMAND_HAS_CHAR_ATTEMPTED_ATTRACTOR:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ UpdateCompareFlag(pPed->bHasAlreadyUsedAttractor);
+ return 0;
+ }
+ case COMMAND_SET_LOAD_COLLISION_FOR_CAR_FLAG:
+ {
+ CollectParameters(&m_nIp, 2);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ if (ScriptParams[1]) {
+ pVehicle->bDontLoadCollision = false;
+ if (m_bMissionFlag) {
+ CWorld::Remove(pVehicle);
+ pVehicle->bIsStaticWaitingForCollision = true;
+ CWorld::Add(pVehicle);
+ }
+ }
+ else {
+ pVehicle->bDontLoadCollision = true;
+ if (pVehicle->bIsStaticWaitingForCollision) {
+ pVehicle->bIsStaticWaitingForCollision = false;
+ if (!pVehicle->GetIsStatic())
+ pVehicle->AddToMovingList();
+ }
+ }
+ return 0;
+ }
+ case COMMAND_SET_LOAD_COLLISION_FOR_CHAR_FLAG:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ if (ScriptParams[1]) {
+ pPed->bDontLoadCollision = false;
+ if (m_bMissionFlag) {
+ CWorld::Remove(pPed);
+ pPed->bIsStaticWaitingForCollision = true;
+ CWorld::Add(pPed);
+ }
+ }
+ else {
+ pPed->bDontLoadCollision = true;
+ if (pPed->bIsStaticWaitingForCollision) {
+ pPed->bIsStaticWaitingForCollision = false;
+ if (!pPed->GetIsStatic())
+ pPed->AddToMovingList();
+ }
+ }
+ return 0;
+ }
+ //case COMMAND_SET_LOAD_COLLISION_FOR_OBJECT_FLAG:
+ case COMMAND_ADD_BIG_GUN_FLASH:
+ {
+ CollectParameters(&m_nIp, 6);
+ CWeapon::AddGunFlashBigGuns(*(CVector*)&ScriptParams[0], *(CVector*)&ScriptParams[3]);
+ return 0;
+ }
+ case COMMAND_HAS_CHAR_BOUGHT_ICE_CREAM:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ UpdateCompareFlag(pPed->bBoughtIceCream);
+ return 0;
+ }
+ case COMMAND_GET_PROGRESS_PERCENTAGE:
+ *(float*)&ScriptParams[0] = CStats::GetPercentageProgress();
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ case COMMAND_SET_SHORTCUT_PICKUP_POINT:
+ {
+ CollectParameters(&m_nIp, 4);
+ CGameLogic::AddShortCutPointAfterDeath(*(CVector*)&ScriptParams[0], *(float*)&ScriptParams[3]);
+ return 0;
+ }
+ case COMMAND_SET_SHORTCUT_DROPOFF_POINT_FOR_MISSION:
+ {
+ CollectParameters(&m_nIp, 4);
+ CGameLogic::AddShortCutDropOffPointForMission(*(CVector*)&ScriptParams[0], *(float*)&ScriptParams[3]);
+ return 0;
+ }
+ case COMMAND_GET_RANDOM_ICE_CREAM_CUSTOMER_IN_AREA:
+ {
+ CollectParameters(&m_nIp, 7);
+ int ped_handle = -1;
+ CVector pos = FindPlayerCoors();
+ float x1 = *(float*)&ScriptParams[0];
+ float y1 = *(float*)&ScriptParams[1];
+ float x2 = *(float*)&ScriptParams[2];
+ float y2 = *(float*)&ScriptParams[3];
+ int i = CPools::GetPedPool()->GetSize();
+ while (--i && ped_handle == -1) {
+ CPed* pPed = CPools::GetPedPool()->GetSlot(i);
+ if (!pPed)
+ continue;
+ if (CTheScripts::LastRandomPedId == CPools::GetPedPool()->GetIndex(pPed))
+ continue;
+ if (pPed->CharCreatedBy != RANDOM_CHAR)
+ continue;
+ if (!pPed->IsPedInControl())
+ continue;
+ if (pPed->bRemoveFromWorld)
+ continue;
+ if (pPed->bFadeOut)
+ continue;
+ if (pPed->m_nWaitState != WAITSTATE_FALSE)
+ continue;
+ if (pPed->bHasAlreadyUsedAttractor)
+ continue;
+ if (pPed->m_attractor)
+ continue;
+ if (!ThisIsAValidRandomPed(pPed->m_nPedType, ScriptParams[4], ScriptParams[5], ScriptParams[6]))
+ continue;
+ if (pPed->bIsLeader || pPed->m_leader)
+ continue;
+ if (!pPed->IsWithinArea(x1, y1, x2, y2))
+ continue;
+ if (pos.z - PED_FIND_Z_OFFSET > pPed->GetPosition().z)
+ continue;
+ if (pos.z + PED_FIND_Z_OFFSET < pPed->GetPosition().z)
+ continue;
+ ped_handle = CPools::GetPedPool()->GetIndex(pPed);
+ CTheScripts::LastRandomPedId = ped_handle;
+ pPed->CharCreatedBy = MISSION_CHAR;
+ pPed->bRespondsToThreats = false;
+ ++CPopulation::ms_nTotalMissionPeds;
+ if (m_bIsMissionScript)
+ CTheScripts::MissionCleanup.AddEntityToList(ped_handle, CLEANUP_CHAR);
+ }
+ ScriptParams[0] = ped_handle;
+ StoreParameters(&m_nIp, 1);
+ return 0;
+ }
+ //case COMMAND_GET_RANDOM_ICE_CREAM_CUSTOMER_IN_ZONE:
+ case COMMAND_UNLOCK_ALL_CAR_DOORS_IN_AREA:
+ {
+ CollectParameters(&m_nIp, 4);
+ uint32 i = CPools::GetVehiclePool()->GetSize();
+ float infX = *(float*)&ScriptParams[0];
+ float infY = *(float*)&ScriptParams[1];
+ float supX = *(float*)&ScriptParams[2];
+ float supY = *(float*)&ScriptParams[3];
+ while (i--) {
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetSlot(i);
+ if (!pVehicle)
+ continue;
+ if (pVehicle->IsWithinArea(infX, infY, supX, supY))
+ pVehicle->m_nDoorLock = CARLOCK_UNLOCKED;
+ }
+ return 0;
+ }
+ case COMMAND_SET_GANG_ATTACK_PLAYER_WITH_COPS:
+ CollectParameters(&m_nIp, 2);
+ CGangs::SetWillAttackPlayerWithCops((ePedType)((int)PEDTYPE_GANG1 + ScriptParams[0]), !!ScriptParams[1]);
+ return 0;
+ case COMMAND_SET_CHAR_FRIGHTENED_IN_JACKED_CAR:
+ {
+ CollectParameters(&m_nIp, 2);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ pPed->bHeldHostageInCar = ScriptParams[1];
+ return 0;
+ }
+ case COMMAND_SET_VEHICLE_TO_FADE_IN:
+ {
+ CollectParameters(&m_nIp, 2);
+ CVehicle* pVehicle = CPools::GetVehiclePool()->GetAt(ScriptParams[0]);
+ script_assert(pVehicle);
+ CVisibilityPlugins::SetClumpAlpha(pVehicle->GetClump(), ScriptParams[1]);
+ return 0;
+ }
+ case COMMAND_REGISTER_ODDJOB_MISSION_PASSED:
+ ++CStats::MissionsPassed;
+ CStats::CheckPointReachedSuccessfully();
+ CTheScripts::LastMissionPassedTime = CTimer::GetTimeInMilliseconds();
+ CGameLogic::RemoveShortCutDropOffPointForMission();
+ return 0;
+ case COMMAND_IS_PLAYER_IN_SHORTCUT_TAXI:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPed* pPed = CWorld::Players[ScriptParams[0]].m_pPed;
+ script_assert(pPed);
+ UpdateCompareFlag(pPed->bInVehicle && pPed->m_pMyVehicle && pPed->m_pMyVehicle == CGameLogic::pShortCutTaxi);
+ return 0;
+ }
+ case COMMAND_IS_CHAR_DUCKING:
+ {
+ CollectParameters(&m_nIp, 1);
+ CPed* pPed = CPools::GetPedPool()->GetAt(ScriptParams[0]);
+ script_assert(pPed);
+ UpdateCompareFlag(RpAnimBlendClumpGetAssociation(pPed->GetClump(), ANIM_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 18fc9575..9863e852 100644
--- a/src/control/ScriptCommands.h
+++ b/src/control/ScriptCommands.h
@@ -1437,6 +1437,39 @@ enum {
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
diff --git a/src/control/SetPieces.cpp b/src/control/SetPieces.cpp
index 9b4e0075..c5142a0a 100644
--- a/src/control/SetPieces.cpp
+++ b/src/control/SetPieces.cpp
@@ -29,7 +29,7 @@ void CSetPieces::AddOne(uint8 type, CVector2D vTriggerInf, CVector2D vTriggerSup
{
if (NumSetPieces >= NUM_SETPIECES)
return;
- aSetPieces[NumSetPieces].m_nType = (eSetPieceType)type;
+ 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);
diff --git a/src/control/SetPieces.h b/src/control/SetPieces.h
index 5776d35a..5c228d4c 100644
--- a/src/control/SetPieces.h
+++ b/src/control/SetPieces.h
@@ -5,7 +5,7 @@
class CVehicle;
class CCopPed;
-enum eSetPieceType : uint8
+enum eSetPieceType
{
SETPIECE_NONE = 0,
SETPIECE_TWOCOPCARSINALLEY,
@@ -20,7 +20,7 @@ enum eSetPieceType : uint8
class CSetPiece
{
public:
- eSetPieceType m_nType;
+ uint8 m_nType;
uint32 m_nLastTimeCreated;
CVector2D m_vTriggerInf;
CVector2D m_vTriggerSup;
diff --git a/src/core/AnimViewer.cpp b/src/core/AnimViewer.cpp
index d39be754..854ec7d4 100644
--- a/src/core/AnimViewer.cpp
+++ b/src/core/AnimViewer.cpp
@@ -18,6 +18,7 @@
#include "World.h"
#include "Renderer.h"
#include "AnimManager.h"
+#include "AnimBlendAssocGroup.h"
#include "AnimViewer.h"
#include "PlayerPed.h"
#include "Pools.h"
@@ -46,7 +47,6 @@ CEntity *CAnimViewer::pTarget = nil;
void
CAnimViewer::Render(void) {
if (pTarget) {
-// pTarget->GetPosition() = CVector(0.0f, 0.0f, 0.0f);
if (pTarget) {
#ifdef FIX_BUGS
if(pTarget->IsPed())
@@ -60,11 +60,14 @@ CAnimViewer::Render(void) {
void
CAnimViewer::Initialise(void) {
- LoadingScreen("Loading the ModelViewer", "", GetRandomSplashScreen());
- animTxdSlot = CTxdStore::AddTxdSlot("generic");
- CTxdStore::Create(animTxdSlot);
+
+ // 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 particleSlot = CTxdStore::AddTxdSlot("particle");
CTxdStore::LoadTxd(particleSlot, "MODELS/PARTICLE.TXD");
CTxdStore::SetCurrentTxd(animTxdSlot);
@@ -73,10 +76,6 @@ CAnimViewer::Initialise(void) {
TheCamera.Init();
TheCamera.SetRwCamera(Scene.camera);
TheCamera.Cams[TheCamera.ActiveCam].Distance = 5.0f;
-
- gbModelViewer = true;
- CHud::m_Wants_To_Draw_Hud = false;
-
ThePaths.Init();
ThePaths.AllocatePathFindInfoMem(4500);
CCollision::Init();
@@ -101,6 +100,9 @@ CAnimViewer::Initialise(void) {
CStreaming::LoadAllRequestedModels(false);
CRenderer::Init();
CVehicleModelInfo::LoadVehicleColours();
+#ifdef FIX_BUGS
+ CVehicleModelInfo::LoadEnvironmentMaps();
+#endif
CAnimManager::LoadAnimFiles();
CWorld::PlayerInFocus = 0;
CWeapon::InitialiseWeapons();
@@ -110,7 +112,7 @@ CAnimViewer::Initialise(void) {
CTimeCycle::Initialise();
CCarCtrl::Init();
CPlayerPed *player = new CPlayerPed();
- player->SetPosition(0.0f, 0.0f, 0.0f);
+ player->SetPosition(1000.0f, 1000.0f, 1000.0f);
CWorld::Players[0].m_pPed = player;
CDraw::SetFOV(120.0f);
CDraw::ms_fLODDistance = 500.0f;
@@ -138,6 +140,25 @@ CAnimViewer::Initialise(void) {
} else {
// 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
@@ -215,8 +236,7 @@ CAnimViewer::Update(void)
{
static int modelId = 0;
static int animId = 0;
- // Please don't make this bool, static bool's are problematic on my side.
- static int reloadIFP = 0;
+ static bool reloadIFP = false;
AssocGroupId animGroup = ASSOCGRP_STD;
int nextModelId = modelId;
@@ -241,7 +261,7 @@ CAnimViewer::Update(void)
CAnimManager::Initialise();
CAnimManager::LoadAnimFiles();
- reloadIFP = 0;
+ reloadIFP = false;
}
} else {
animGroup = ASSOCGRP_STD;
@@ -292,14 +312,19 @@ CAnimViewer::Update(void)
if (pTarget->IsVehicle() || pTarget->IsPed() || pTarget->IsObject()) {
((CPhysical*)pTarget)->m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f);
}
+#ifdef FIX_BUGS
+ // so we don't end up in the water
+ pTarget->GetMatrix().GetPosition().z = 10.0f;
+#else
pTarget->GetMatrix().GetPosition().z = 0.0f;
+#endif
if (modelInfo->GetModelType() == MITYPE_PED) {
((CPed*)pTarget)->bKindaStayInSamePlace = true;
// Triangle in mobile
if (pad->GetSquareJustDown()) {
- reloadIFP = 1;
+ reloadIFP = true;
AsciiToUnicode("IFP reloaded", gUString);
CMessages::AddMessage(gUString, 1000, 0);
@@ -316,7 +341,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);
@@ -325,7 +350,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);
@@ -344,6 +369,11 @@ CAnimViewer::Update(void)
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 7560a86e..2cf1748c 100644
--- a/src/core/Cam.cpp
+++ b/src/core/Cam.cpp
@@ -180,9 +180,11 @@ CCam::Process(void)
Process_BehindCar(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar);
break;
case MODE_FOLLOWPED:
+#ifdef PC_PLAYER_CONTROLS
if(CCamera::m_bUseMouse3rdPerson)
Process_FollowPedWithMouse(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar);
else
+#endif
#ifdef FREE_CAM
if(CCamera::bFreeCam)
Process_FollowPed_Rotation(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar);
@@ -287,9 +289,11 @@ CCam::Process(void)
case MODE_FIGHT_CAM_RUNABOUT:
Process_1rstPersonPedOnPC(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar);
break;
+#ifdef GTA_SCENE_EDIT
case MODE_EDITOR:
Process_Editor(CameraTarget, TargetOrientation, SpeedVar, TargetSpeedVar);
break;
+#endif
default:
Source = CVector(0.0f, 0.0f, 0.0f);
Front = CVector(0.0f, 1.0f, 0.0f);
@@ -2703,7 +2707,7 @@ CCam::Process_1rstPersonPedOnPC(const CVector&, float TargetOrientation, float,
RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(CamTargetEntity->GetClump());
int32 idx = RpHAnimIDGetIndex(hier, ConvertPedNode2BoneTag(PED_HEAD));
RwMatrix *mats = RpHAnimHierarchyGetMatrixArray(hier);
- RwV3dTransformPoints((RwV3d*)&HeadPos, (RwV3d*)&HeadPos, 1, &mats[idx]);
+ RwV3dTransformPoints(&HeadPos, &HeadPos, 1, &mats[idx]);
RwV3d scl = { 0.0f, 0.0f, 0.0f };
RwMatrixScale(&mats[idx], &scl, rwCOMBINEPRECONCAT);
@@ -2744,7 +2748,7 @@ CCam::Process_1rstPersonPedOnPC(const CVector&, float TargetOrientation, float,
Source = HeadPos;
// unused:
- // ((CPed*)CamTargetEntity)->m_pedIK.GetComponentPosition(&MidPos, PED_MID);
+ // ((CPed*)CamTargetEntity)->m_pedIK.GetComponentPosition(MidPos, PED_MID);
// Source - MidPos;
// Look around
@@ -2920,8 +2924,7 @@ CCam::Process_Sniper(const CVector &CameraTarget, float TargetOrientation, float
UseMouse = false;
int ZoomInButton = ControlsManager.GetMouseButtonAssociatedWithAction(PED_SNIPER_ZOOM_IN);
int ZoomOutButton = ControlsManager.GetMouseButtonAssociatedWithAction(PED_SNIPER_ZOOM_OUT);
- // TODO: enum? this should be mouse wheel up and down
- if(ZoomInButton == 4 || ZoomInButton == 5 || ZoomOutButton == 4 || ZoomOutButton == 5){
+ if(ZoomInButton == rsMOUSEWHEELUPBUTTON || ZoomInButton == rsMOUSEWHEELDOWNBUTTON || ZoomOutButton == rsMOUSEWHEELUPBUTTON || ZoomOutButton == rsMOUSEWHEELDOWNBUTTON){
if(CPad::GetPad(0)->GetMouseWheelUp() || CPad::GetPad(0)->GetMouseWheelDown()){
if(CPad::GetPad(0)->SniperZoomIn()){
TargetFOV = FOV - 10.0f;
@@ -3734,6 +3737,7 @@ CCam::Process_Fixed(const CVector &CameraTarget, float, float, float)
}
}
+#ifdef PC_PLAYER_CONTROLS
if(FrontEndMenuManager.m_ControlMethod == CONTROL_STANDARD && Using3rdPersonMouseCam()){
CPed *player = FindPlayerPed();
if(player && player->CanStrafeOrMouseControl()){
@@ -3744,6 +3748,7 @@ CCam::Process_Fixed(const CVector &CameraTarget, float, float, float)
TheCamera.pTargetEntity->GetMatrix().UpdateRW();
}
}
+#endif
}
void
@@ -4034,6 +4039,7 @@ CCam::Process_Debug(const CVector&, float, float, float)
}
#endif
+#ifdef GTA_SCENE_EDIT
void
CCam::Process_Editor(const CVector&, float, float, float)
{
@@ -4112,6 +4118,7 @@ CCam::Process_Editor(const CVector&, float, float, float)
sprintf(str, "Look@: %f, Look@: %f, Look@: %f ", Front.x + Source.x, Front.y + Source.y, Front.z + Source.z);
}
}
+#endif
void
CCam::Process_ModelView(const CVector &CameraTarget, float, float, float)
@@ -4125,6 +4132,12 @@ CCam::Process_ModelView(const CVector &CameraTarget, float, float, float)
Distance += CPad::GetPad(0)->GetLeftStickY()/1000.0f;
else
Distance += CPad::GetPad(0)->GetLeftStickY() * ((Distance - 10.0f)/20.0f + 1.0f) / 1000.0f;
+#ifdef IMPROVED_CAMERA
+ if(CPad::GetPad(0)->GetLeftMouse()){
+ Distance += DEGTORAD(CPad::GetPad(0)->GetMouseY()/2.0f);
+ Angle += DEGTORAD(CPad::GetPad(0)->GetMouseX()/2.0f);
+ }
+#endif
if(Distance < 1.5f)
Distance = 1.5f;
@@ -4903,13 +4916,9 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
if (FOV > DefaultFOV)
// 0.98f: CAR_FOV_FADE_MULT
- FOV = pow(0.98f, CTimer::GetTimeStep()) * (FOV - DefaultFOV) + DefaultFOV;
+ FOV = Pow(0.98f, CTimer::GetTimeStep()) * (FOV - DefaultFOV) + DefaultFOV;
- if (FOV <= DefaultFOV + 30.0f) {
- if (FOV < DefaultFOV)
- FOV = DefaultFOV;
- } else
- FOV = DefaultFOV + 30.0f;
+ FOV = clamp(FOV, DefaultFOV, DefaultFOV + 30.0f);
}
// WORKAROUND: I still don't know how looking behind works (m_bCamDirectlyInFront is unused in III, they seem to use m_bUseTransitionBeta)
@@ -5036,7 +5045,7 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
targetAlpha = maxAlphaAllowed;
}
float maxAlphaBlendAmount = CTimer::GetTimeStep() * CARCAM_SET[camSetArrPos][6];
- float targetAlphaBlendAmount = (1.0f - pow(CARCAM_SET[camSetArrPos][5], CTimer::GetTimeStep())) * (targetAlpha - Alpha);
+ float targetAlphaBlendAmount = (1.0f - Pow(CARCAM_SET[camSetArrPos][5], CTimer::GetTimeStep())) * (targetAlpha - Alpha);
if (targetAlphaBlendAmount <= maxAlphaBlendAmount) {
if (targetAlphaBlendAmount < -maxAlphaBlendAmount)
targetAlphaBlendAmount = -maxAlphaBlendAmount;
@@ -5048,7 +5057,6 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
float stickX = -(pad->GetCarGunLeftRight());
float stickY = pad->GetCarGunUpDown();
- // In SA this checks for m_bUseMouse3rdPerson so num2/num8 do not move camera when Keyboard & Mouse controls are used.
if (CCamera::m_bUseMouse3rdPerson)
stickY = 0.0f;
@@ -5128,7 +5136,7 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
float betaSpeedFromStickX = xMovement * CARCAM_SET[camSetArrPos][12];
float newAngleSpeedMaxBlendAmount = CARCAM_SET[camSetArrPos][9];
- float angleChangeStep = pow(CARCAM_SET[camSetArrPos][8], CTimer::GetTimeStep());
+ float angleChangeStep = Pow(CARCAM_SET[camSetArrPos][8], CTimer::GetTimeStep());
float targetBetaWithStickBlendAmount = betaSpeedFromStickX + (targetBeta - Beta) / Max(CTimer::GetTimeStep(), 1.0f);
if (targetBetaWithStickBlendAmount < -newAngleSpeedMaxBlendAmount)
@@ -5240,69 +5248,78 @@ CCam::Process_FollowCar_SA(const CVector& CameraTarget, float TargetOrientation,
// SA calls SetColVarsVehicle in here
if (nextDirectionIsForward) {
- // This is new in LCS!
+ // LCS uses exactly the same collision code as FollowPedWithMouse, so we will do so.
+
+ // This is only in LCS!
float timestepFactor = Pow(0.99f, CTimer::GetTimeStep());
dontCollideWithCars = (timestepFactor * dontCollideWithCars) + ((1.0f - timestepFactor) * car->m_vecMoveSpeed.Magnitude());
- // Move cam if on collision
- CColPoint foundCol;
- CEntity* foundEnt;
+ // Our addition
+#define IS_TRAFFIC_LIGHT(ent) (ent->IsObject() && IsLightObject(ent->GetModelIndex()))
+
+ // Clip Source and fix near clip
+ CColPoint colPoint;
+ CEntity* entity;
CWorld::pIgnoreEntity = CamTargetEntity;
- if (CWorld::ProcessLineOfSight(TargetCoors, Source, foundCol, foundEnt, true, dontCollideWithCars < 0.1f, false, false, false, true, false)) {
- float obstacleTargetDist = (TargetCoors - foundCol.point).Magnitude();
- float obstacleCamDist = newDistance - obstacleTargetDist;
- if (!foundEnt->IsPed() || obstacleCamDist <= 1.0f) {
- Source = foundCol.point;
- if (obstacleTargetDist < 1.2f) {
- RwCameraSetNearClipPlane(Scene.camera, Max(0.05f, obstacleTargetDist - 0.3f));
- }
- } else {
- if (!CWorld::ProcessLineOfSight(foundCol.point, Source, foundCol, foundEnt, true, dontCollideWithCars < 0.1f, false, false, false, true, false)) {
- float lessClip = obstacleCamDist - 0.35f;
- if (lessClip <= DEFAULT_NEAR)
- RwCameraSetNearClipPlane(Scene.camera, lessClip);
- else
- RwCameraSetNearClipPlane(Scene.camera, DEFAULT_NEAR);
- } else {
- obstacleTargetDist = (TargetCoors - foundCol.point).Magnitude();
- Source = foundCol.point;
- if (obstacleTargetDist < 1.2f) {
- float lessClip = obstacleTargetDist - 0.3f;
- if (lessClip >= 0.05f)
- RwCameraSetNearClipPlane(Scene.camera, lessClip);
- else
- RwCameraSetNearClipPlane(Scene.camera, 0.05f);
- }
+ if(CWorld::ProcessLineOfSight(TargetCoors, Source, colPoint, entity, true, dontCollideWithCars < 0.1f, false, true, false, true, true) && !IS_TRAFFIC_LIGHT(entity)){
+ float PedColDist = (TargetCoors - colPoint.point).Magnitude();
+ float ColCamDist = newDistance - PedColDist;
+ if(entity->IsPed() && ColCamDist > DEFAULT_NEAR + 0.1f){
+ // Ped in the way but not clipping through
+ if(CWorld::ProcessLineOfSight(colPoint.point, Source, colPoint, entity, true, dontCollideWithCars < 0.1f, false, true, false, true, true) || IS_TRAFFIC_LIGHT(entity)){
+ PedColDist = (TargetCoors - colPoint.point).Magnitude();
+ Source = colPoint.point;
+ if(PedColDist < DEFAULT_NEAR + 0.3f)
+ RwCameraSetNearClipPlane(Scene.camera, Max(PedColDist-0.3f, 0.05f));
+ }else{
+ RwCameraSetNearClipPlane(Scene.camera, Min(ColCamDist-0.35f, DEFAULT_NEAR));
}
+ }else{
+ Source = colPoint.point;
+ if(PedColDist < DEFAULT_NEAR + 0.3f)
+ RwCameraSetNearClipPlane(Scene.camera, Max(PedColDist-0.3f, 0.05f));
}
}
+
CWorld::pIgnoreEntity = nil;
- float nearClip = RwCameraGetNearClipPlane(Scene.camera);
- float radius = Tan(DEGTORAD(FOV * 0.5f)) * CDraw::GetAspectRatio() * 1.1f;
// If we're seeing blue hell due to camera intersects some surface, fix it.
// SA and LCS have this unrolled.
- for (int i = 0;
- i <= 5 && CWorld::TestSphereAgainstWorld((nearClip * Front) + Source, radius * nearClip, nil, true, true, false, true, false, false);
- i++) {
-
- CVector surfaceCamDist = gaTempSphereColPoints->point - Source;
- CVector frontButInvertedIfTouchesSurface = DotProduct(surfaceCamDist, Front) * Front;
- float newNearClip = (surfaceCamDist - frontButInvertedIfTouchesSurface).Magnitude() / radius;
-
- if (newNearClip > nearClip)
- newNearClip = nearClip;
- if (newNearClip < 0.1f)
- newNearClip = 0.1f;
- if (nearClip > newNearClip)
- RwCameraSetNearClipPlane(Scene.camera, newNearClip);
-
- if (newNearClip == 0.1f)
- Source += (TargetCoors - Source) * 0.3f;
-
- nearClip = RwCameraGetNearClipPlane(Scene.camera);
- radius = Tan(DEGTORAD(FOV * 0.5f)) * CDraw::GetAspectRatio() * 1.1f;
+
+ float ViewPlaneHeight = Tan(DEGTORAD(FOV) / 2.0f);
+ 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);
+ int i = 0;
+ while(entity){
+
+ if (IS_TRAFFIC_LIGHT(entity))
+ break;
+
+ CVector CamToCol = gaTempSphereColPoints[0].point - Source;
+ float frontDist = DotProduct(CamToCol, Front);
+ float dist = (CamToCol - Front*frontDist).Magnitude() / ViewPlaneWidth;
+
+ // Try to decrease near clip
+ dist = Max(Min(Near, dist), 0.1f);
+ if(dist < Near)
+ RwCameraSetNearClipPlane(Scene.camera, dist);
+
+ // Move forward a bit
+ if(dist == 0.1f)
+ Source += (TargetCoors - Source)*0.3f;
+
+ // Keep testing
+ Near = RwCameraGetNearClipPlane(Scene.camera);
+ radius = ViewPlaneWidth*Near;
+ entity = CWorld::TestSphereAgainstWorld(Source + Front*Near, radius, nil, true, true, false, true, false, true);
+
+ i++;
+ if(i > 5)
+ entity = nil;
}
+#undef IS_TRAFFIC_LIGHT
}
TheCamera.m_bCamDirectlyBehind = false;
TheCamera.m_bCamDirectlyInFront = false;
diff --git a/src/core/Camera.cpp b/src/core/Camera.cpp
index 2fa81d24..d245bb5a 100644
--- a/src/core/Camera.cpp
+++ b/src/core/Camera.cpp
@@ -69,7 +69,11 @@ enum
// NB: removed explicit TheCamera from all functions
CCamera TheCamera;
+#ifdef PC_PLAYER_CONTROLS
bool CCamera::m_bUseMouse3rdPerson = true;
+#else
+bool CCamera::m_bUseMouse3rdPerson = false;
+#endif
bool bDidWeProcessAnyCinemaCam;
static bool bSwitchedToObbeCam;
float CCamera::m_fMouseAccelHorzntl;
@@ -612,7 +616,7 @@ CCamera::Process(void)
// LOD dist
if(!CCutsceneMgr::IsRunning() || CCutsceneMgr::UseLodMultiplier()){
- LODDistMultiplier = 70.0f/CDraw::GetFOV() * CDraw::GetAspectRatio()/(4.0f/3.0f);
+ LODDistMultiplier = 70.0f/CDraw::GetFOV();
if(GetPosition().z > 55.0f && FindPlayerVehicle() && FindPlayerVehicle()->pHandling->Flags & (HANDLING_IS_HELI|HANDLING_IS_PLANE) ||
FindPlayerPed()->m_attachedTo){
@@ -1008,22 +1012,26 @@ CCamera::CamControl(void)
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){
m_bFirstPersonBeingUsed = false;
+ }else if(CPad::GetPad(0)->TargetJustDown()){
+ m_bFirstPersonBeingUsed = false;
m_bJustJumpedOutOf1stPersonBecauseOfTarget = true;
}
}
@@ -1129,27 +1137,31 @@ 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(stairsZone){ // always true
+ garageCenter = CVector((stairsZone->minx+stairsZone->maxx)/2, (stairsZone->miny+stairsZone->maxy)/2, 0.0f);
+ if(pTargetEntity->GetPosition().x > 376.0f && pTargetEntity->GetPosition().x < 383.0f &&
+ pTargetEntity->GetPosition().y > -496.0f && pTargetEntity->GetPosition().y < -489.0f &&
+ pTargetEntity->GetPosition().z > 11.6f && pTargetEntity->GetPosition().z < 13.6f){
+ garageDoorPos1 = CVector(382.6f, -489.6f, 13.1f);
+ }else{
+ bool bClearViewOutside = true;
+ CVector dirOutside = pTargetEntity->GetPosition() - garageCenter;
+ dirOutside.z = 0.0f;
+ dirOutside.Normalise();
+ float zoneDim = stairsZone->maxx - stairsZone->minx;
+ if(zoneDim < stairsZone->maxy - stairsZone->miny)
+ zoneDim = stairsZone->maxy - stairsZone->miny;
+ zoneDim *= 2.0f;
+ CVector posOutside = pTargetEntity->GetPosition() + zoneDim*dirOutside;
+ if(!CWorld::GetIsLineOfSightClear(pTargetEntity->GetPosition(), posOutside, true, false, false, false, false, false, true)){
+ posOutside = pTargetEntity->GetPosition() - zoneDim*dirOutside;
+ if(!CWorld::GetIsLineOfSightClear(pTargetEntity->GetPosition(), posOutside, true, false, false, false, false, false, true))
+ bClearViewOutside = false;
+ }
+ if(bClearViewOutside)
+ garageDoorPos1 = posOutside;
}
- if(bClearViewOutside)
- garageDoorPos1 = posOutside;
}
}
@@ -1159,7 +1171,7 @@ CCamera::CamControl(void)
garageCenter.z = 0.0f;
}else{
garageDoorPos1.z = 0.0f;
- if(stairs == nil) // how can this be true?
+ if(!stairs) // how can this be true?
garageCenter = CVector(pTargetEntity->GetPosition().x, pTargetEntity->GetPosition().y, 0.0f);
}
if(whichDoor == 1)
@@ -1598,8 +1610,10 @@ CCamera::CamControl(void)
switchByJumpCut = true;
}
}
+#ifdef GTA_SCENE_EDIT
if(CSceneEdit::m_bEditOn)
ReqMode = CCam::MODE_EDITOR;
+#endif
if((m_uiTransitionState == 0 || switchByJumpCut) && ReqMode != Cams[ActiveCam].Mode){
if(switchByJumpCut){
@@ -1698,7 +1712,7 @@ 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;
if(m_bEnable1rstPersonCamCntrlsScript && ReqMode == CCam::MODE_1STPERSON)
@@ -3385,12 +3399,12 @@ CCamera::LoadTrainCamNodes(char const *name)
char token[16] = { 0 };
char filename[16] = { 0 };
uint8 *buf;
- size_t bufpos = 0;
+ ssize_t bufpos = 0;
int field = 0;
int tokpos = 0;
char c;
int i;
- size_t len;
+ ssize_t len;
strcpy(filename, name);
len = (int)strlen(filename);
@@ -3617,6 +3631,8 @@ CCamera::LoadPathSplines(int file)
m_arrPathArray[i].m_arr_PathData[j] = atof(token);
i++;
j = 0;
+ if (i == MAX_NUM_OF_SPLINETYPES)
+ reading = false;
memset(token, 0, 32);
n = 0;
}
diff --git a/src/core/Camera.h b/src/core/Camera.h
index ff74931c..4da7b499 100644
--- a/src/core/Camera.h
+++ b/src/core/Camera.h
@@ -209,7 +209,9 @@ public:
void PrintMode(void);
void Process_Debug(const CVector&, float, float, float);
+#ifdef GTA_SCENE_EDIT
void Process_Editor(const CVector&, float, float, float);
+#endif
void Process_ModelView(const CVector &CameraTarget, float, float, float);
void Process_FollowPed(const CVector &CameraTarget, float TargetOrientation, float, float);
void Process_FollowPedWithMouse(const CVector &CameraTarget, float TargetOrientation, float, float);
diff --git a/src/core/CdStream.cpp b/src/core/CdStream.cpp
index c11fb72a..4bb31ea4 100644
--- a/src/core/CdStream.cpp
+++ b/src/core/CdStream.cpp
@@ -5,6 +5,7 @@
#include "CdStream.h"
#include "rwcore.h"
#include "RwHelper.h"
+#include "MemoryMgr.h"
#define CDDEBUG(f, ...) debug ("%s: " f "\n", "cdvd_stream", ## __VA_ARGS__)
#define CDTRACE(f, ...) printf("%s: " f "\n", "cdvd_stream", ## __VA_ARGS__)
@@ -72,7 +73,11 @@ CdStreamInitThread(void)
gChannelRequestQ.size = gNumChannels + 1;
ASSERT(gChannelRequestQ.items != nil );
+#ifdef FIX_BUGS
+ gCdStreamSema = CreateSemaphore(nil, 0, 5, nil);
+#else
gCdStreamSema = CreateSemaphore(nil, 0, 5, "CdStream");
+#endif
if ( gCdStreamSema == nil )
{
@@ -242,8 +247,15 @@ CdStreamRead(int32 channel, void *buffer, uint32 offset, uint32 size)
else
return STREAM_SUCCESS;
}
-
+
+#ifdef BIG_IMG
+ LARGE_INTEGER liDistanceToMove;
+ liDistanceToMove.QuadPart = _GET_OFFSET(offset);
+ liDistanceToMove.QuadPart *= CDSTREAM_SECTOR_SIZE;
+ SetFilePointerEx(hImage, liDistanceToMove, nil, FILE_BEGIN);
+#else
SetFilePointer(hImage, _GET_OFFSET(offset) * CDSTREAM_SECTOR_SIZE, nil, FILE_BEGIN);
+#endif
DWORD NumberOfBytesRead;
diff --git a/src/core/CdStreamPosix.cpp b/src/core/CdStreamPosix.cpp
index 5c8d1b16..0854d850 100644
--- a/src/core/CdStreamPosix.cpp
+++ b/src/core/CdStreamPosix.cpp
@@ -16,7 +16,7 @@
#include "CdStream.h"
#include "rwcore.h"
-#include "RwHelper.h"
+#include "MemoryMgr.h"
#define CDDEBUG(f, ...) debug ("%s: " f "\n", "cdvd_stream", ## __VA_ARGS__)
#define CDTRACE(f, ...) printf("%s: " f "\n", "cdvd_stream", ## __VA_ARGS__)
@@ -429,7 +429,7 @@ void *CdStreamThread(void *param)
ASSERT(pChannel->hFile >= 0);
ASSERT(pChannel->pBuffer != nil );
- lseek(pChannel->hFile, pChannel->nSectorOffset * CDSTREAM_SECTOR_SIZE, SEEK_SET);
+ lseek(pChannel->hFile, (size_t)pChannel->nSectorOffset * (size_t)CDSTREAM_SECTOR_SIZE, SEEK_SET);
if (read(pChannel->hFile, pChannel->pBuffer, pChannel->nSectorsToRead * CDSTREAM_SECTOR_SIZE) == -1) {
// pChannel->nSectorsToRead == 0 at this point means we wanted to flush channel
// STREAM_WAITING is a little hack to make CStreaming not process this data
diff --git a/src/core/ControllerConfig.cpp b/src/core/ControllerConfig.cpp
index 51e942d0..fe865865 100644
--- a/src/core/ControllerConfig.cpp
+++ b/src/core/ControllerConfig.cpp
@@ -2348,8 +2348,252 @@ int32 CControllerConfigManager::GetNumOfSettingsForAction(e_ControllerAction act
return num;
}
+#ifdef BIND_VEHICLE_FIREWEAPON
+#define VFB(b) b,
+#else
+#define VFB(b)
+#endif
+
+#define CONTROLLER_BUTTONS(T, O, X, Q, L1, L2, L3, R1, R2, R3, SELECT) \
+ {{ \
+ O, /* PED_FIREWEAPON */ \
+ R2, /* PED_CYCLE_WEAPON_RIGHT */ \
+ L2, /* PED_CYCLE_WEAPON_LEFT */ \
+ nil, /* GO_FORWARD */ \
+ nil, /* GO_BACK */ \
+ nil, /* GO_LEFT */ \
+ nil, /* GO_RIGHT */ \
+ Q, /* PED_SNIPER_ZOOM_IN */ \
+ X, /* PED_SNIPER_ZOOM_OUT */ \
+ T, /* VEHICLE_ENTER_EXIT */ \
+ SELECT, /* CAMERA_CHANGE_VIEW_ALL_SITUATIONS */ \
+ Q, /* PED_JUMPING */ \
+ X, /* PED_SPRINT */ \
+ R3, /* PED_LOOKBEHIND */ \
+ VFB(O) /* VEHICLE_FIREWEAPON */ \
+ X, /* VEHICLE_ACCELERATE */ \
+ Q, /* VEHICLE_BRAKE */ \
+ L1, /* VEHICLE_CHANGE_RADIO_STATION */ \
+ L3, /* VEHICLE_HORN */ \
+ R3, /* TOGGLE_SUBMISSIONS */ \
+ R1, /* VEHICLE_HANDBRAKE */ \
+ nil, /* PED_1RST_PERSON_LOOK_LEFT */ \
+ nil, /* PED_1RST_PERSON_LOOK_RIGHT */ \
+ L2, /* VEHICLE_LOOKLEFT */ \
+ R2, /* VEHICLE_LOOKRIGHT */ \
+ nil, /* VEHICLE_LOOKBEHIND */ \
+ nil, /* VEHICLE_TURRETLEFT */ \
+ nil, /* VEHICLE_TURRETRIGHT */ \
+ nil, /* VEHICLE_TURRETUP */ \
+ nil, /* VEHICLE_TURRETDOWN */ \
+ L2, /* PED_CYCLE_TARGET_LEFT */ \
+ R2, /* PED_CYCLE_TARGET_RIGHT */ \
+ L1, /* PED_CENTER_CAMERA_BEHIND_PLAYER */ \
+ R1, /* PED_LOCK_TARGET */ \
+ nil, /* NETWORK_TALK */ \
+ nil, /* PED_1RST_PERSON_LOOK_UP */ \
+ nil, /* PED_1RST_PERSON_LOOK_DOWN */ \
+ nil, /* _CONTROLLERACTION_36 */ \
+ nil, /* TOGGLE_DPAD */ \
+ nil, /* SWITCH_DEBUG_CAM_ON */ \
+ nil, /* TAKE_SCREEN_SHOT */ \
+ nil, /* SHOW_MOUSE_POINTER_TOGGLE */ \
+ }, \
+ { \
+ O, /* PED_FIREWEAPON */ \
+ R2, /* PED_CYCLE_WEAPON_RIGHT */ \
+ L2, /* PED_CYCLE_WEAPON_LEFT */ \
+ nil, /* GO_FORWARD */ \
+ nil, /* GO_BACK */ \
+ nil, /* GO_LEFT */ \
+ nil, /* GO_RIGHT */ \
+ Q, /* PED_SNIPER_ZOOM_IN */ \
+ X, /* PED_SNIPER_ZOOM_OUT */ \
+ T, /* VEHICLE_ENTER_EXIT */ \
+ SELECT, /* CAMERA_CHANGE_VIEW_ALL_SITUATIONS */ \
+ Q, /* PED_JUMPING */ \
+ X, /* PED_SPRINT */ \
+ R3, /* PED_LOOKBEHIND */ \
+ VFB(O) /* VEHICLE_FIREWEAPON */ \
+ X, /* VEHICLE_ACCELERATE */ \
+ Q, /* VEHICLE_BRAKE */ \
+ SELECT, /* VEHICLE_CHANGE_RADIO_STATION */ \
+ L1, /* VEHICLE_HORN */ \
+ R3, /* TOGGLE_SUBMISSIONS */ \
+ R1, /* VEHICLE_HANDBRAKE */ \
+ nil, /* PED_1RST_PERSON_LOOK_LEFT */ \
+ nil, /* PED_1RST_PERSON_LOOK_RIGHT */ \
+ L2, /* VEHICLE_LOOKLEFT */ \
+ R2, /* VEHICLE_LOOKRIGHT */ \
+ nil, /* VEHICLE_LOOKBEHIND */ \
+ nil, /* VEHICLE_TURRETLEFT */ \
+ nil, /* VEHICLE_TURRETRIGHT */ \
+ nil, /* VEHICLE_TURRETUP */ \
+ nil, /* VEHICLE_TURRETDOWN */ \
+ L2, /* PED_CYCLE_TARGET_LEFT */ \
+ R2, /* PED_CYCLE_TARGET_RIGHT */ \
+ L1, /* PED_CENTER_CAMERA_BEHIND_PLAYER */ \
+ R1, /* PED_LOCK_TARGET */ \
+ nil, /* NETWORK_TALK */ \
+ nil, /* PED_1RST_PERSON_LOOK_UP */ \
+ nil, /* PED_1RST_PERSON_LOOK_DOWN */ \
+ nil, /* _CONTROLLERACTION_36 */ \
+ nil, /* TOGGLE_DPAD */ \
+ nil, /* SWITCH_DEBUG_CAM_ON */ \
+ nil, /* TAKE_SCREEN_SHOT */ \
+ nil, /* SHOW_MOUSE_POINTER_TOGGLE */ \
+ }, \
+ { \
+ X, /* PED_FIREWEAPON */ \
+ R2, /* PED_CYCLE_WEAPON_RIGHT */ \
+ L2, /* PED_CYCLE_WEAPON_LEFT */ \
+ nil, /* GO_FORWARD */ \
+ nil, /* GO_BACK */ \
+ nil, /* GO_LEFT */ \
+ nil, /* GO_RIGHT */ \
+ T, /* PED_SNIPER_ZOOM_IN */ \
+ Q, /* PED_SNIPER_ZOOM_OUT */ \
+ L1, /* VEHICLE_ENTER_EXIT */ \
+ SELECT, /* CAMERA_CHANGE_VIEW_ALL_SITUATIONS */ \
+ Q, /* PED_JUMPING */ \
+ O, /* PED_SPRINT */ \
+ R3, /* PED_LOOKBEHIND */ \
+ VFB(O) /* VEHICLE_FIREWEAPON */ \
+ X, /* VEHICLE_ACCELERATE */ \
+ Q, /* VEHICLE_BRAKE */ \
+ L3, /* VEHICLE_CHANGE_RADIO_STATION */ \
+ R1, /* VEHICLE_HORN */ \
+ R3, /* TOGGLE_SUBMISSIONS */ \
+ T, /* VEHICLE_HANDBRAKE */ \
+ nil, /* PED_1RST_PERSON_LOOK_LEFT */ \
+ nil, /* PED_1RST_PERSON_LOOK_RIGHT */ \
+ L2, /* VEHICLE_LOOKLEFT */ \
+ R2, /* VEHICLE_LOOKRIGHT */ \
+ nil, /* VEHICLE_LOOKBEHIND */ \
+ nil, /* VEHICLE_TURRETLEFT */ \
+ nil, /* VEHICLE_TURRETRIGHT */ \
+ nil, /* VEHICLE_TURRETUP */ \
+ nil, /* VEHICLE_TURRETDOWN */ \
+ L2, /* PED_CYCLE_TARGET_LEFT */ \
+ R2, /* PED_CYCLE_TARGET_RIGHT */ \
+ T, /* PED_CENTER_CAMERA_BEHIND_PLAYER */ \
+ R1, /* PED_LOCK_TARGET */ \
+ nil, /* NETWORK_TALK */ \
+ nil, /* PED_1RST_PERSON_LOOK_UP */ \
+ nil, /* PED_1RST_PERSON_LOOK_DOWN */ \
+ nil, /* _CONTROLLERACTION_36 */ \
+ nil, /* TOGGLE_DPAD */ \
+ nil, /* SWITCH_DEBUG_CAM_ON */ \
+ nil, /* TAKE_SCREEN_SHOT */ \
+ nil, /* SHOW_MOUSE_POINTER_TOGGLE */ \
+ }, \
+ { \
+ R1, /* PED_FIREWEAPON */ \
+ R2, /* PED_CYCLE_WEAPON_RIGHT */ \
+ L2, /* PED_CYCLE_WEAPON_LEFT */ \
+ nil, /* GO_FORWARD */ \
+ nil, /* GO_BACK */ \
+ nil, /* GO_LEFT */ \
+ nil, /* GO_RIGHT */ \
+ Q, /* PED_SNIPER_ZOOM_IN */ \
+ X, /* PED_SNIPER_ZOOM_OUT */ \
+ T, /* VEHICLE_ENTER_EXIT */ \
+ SELECT, /* CAMERA_CHANGE_VIEW_ALL_SITUATIONS */ \
+ Q, /* PED_JUMPING */ \
+ X, /* PED_SPRINT */ \
+ R3, /* PED_LOOKBEHIND */ \
+ VFB(R1) /* VEHICLE_FIREWEAPON */ \
+ nil, /* VEHICLE_ACCELERATE */ \
+ nil, /* VEHICLE_BRAKE */ \
+ O, /* VEHICLE_CHANGE_RADIO_STATION */ \
+ L3, /* VEHICLE_HORN */ \
+ Q, /* TOGGLE_SUBMISSIONS */ \
+ L1, /* VEHICLE_HANDBRAKE */ \
+ nil, /* PED_1RST_PERSON_LOOK_LEFT */ \
+ nil, /* PED_1RST_PERSON_LOOK_RIGHT */ \
+ L2, /* VEHICLE_LOOKLEFT */ \
+ R2, /* VEHICLE_LOOKRIGHT */ \
+ nil, /* VEHICLE_LOOKBEHIND */ \
+ nil, /* VEHICLE_TURRETLEFT */ \
+ nil, /* VEHICLE_TURRETRIGHT */ \
+ nil, /* VEHICLE_TURRETUP */ \
+ nil, /* VEHICLE_TURRETDOWN */ \
+ L2, /* PED_CYCLE_TARGET_LEFT */ \
+ R2, /* PED_CYCLE_TARGET_RIGHT */ \
+ O, /* PED_CENTER_CAMERA_BEHIND_PLAYER */ \
+ L1, /* PED_LOCK_TARGET */ \
+ nil, /* NETWORK_TALK */ \
+ nil, /* PED_1RST_PERSON_LOOK_UP */ \
+ nil, /* PED_1RST_PERSON_LOOK_DOWN */ \
+ nil, /* _CONTROLLERACTION_36 */ \
+ nil, /* TOGGLE_DPAD */ \
+ nil, /* SWITCH_DEBUG_CAM_ON */ \
+ nil, /* TAKE_SCREEN_SHOT */ \
+ nil, /* SHOW_MOUSE_POINTER_TOGGLE */ \
+ }}
+
+
+const char *XboxButtons_noIcons[][MAX_CONTROLLERACTIONS] = CONTROLLER_BUTTONS("Y", "B", "A", "X", "LB", "LT", "LS", "RB", "RT", "RS", "BACK");
+
+#ifdef BUTTON_ICONS
+const char *XboxButtons[][MAX_CONTROLLERACTIONS] = CONTROLLER_BUTTONS("~T~", "~O~", "~X~", "~Q~", "~K~", "~M~", "~A~", "~J~", "~V~", "~C~", "BACK");
+#endif
+
+
+#if 0 // set 1 for ps2 fonts
+#define PS2_TRIANGLE "\""
+#define PS2_CIRCLE "|"
+#define PS2_CROSS "/"
+#define PS2_SQUARE "^"
+#elif defined(BUTTON_ICONS)
+#define PS2_TRIANGLE "~T~"
+#define PS2_CIRCLE "~O~"
+#define PS2_CROSS "~X~"
+#define PS2_SQUARE "~Q~"
+#else
+#define PS2_TRIANGLE "TRIANGLE"
+#define PS2_CIRCLE "CIRCLE"
+#define PS2_CROSS "CROSS"
+#define PS2_SQUARE "SQUARE"
+#endif
+
+const char *PlayStationButtons_noIcons[][MAX_CONTROLLERACTIONS] =
+ CONTROLLER_BUTTONS(PS2_TRIANGLE, PS2_CIRCLE, PS2_CROSS, PS2_SQUARE, "L1", "L2", "L3", "R1", "R2", "R3", "SELECT");
+
+#ifdef BUTTON_ICONS
+const char *PlayStationButtons[][MAX_CONTROLLERACTIONS] =
+ CONTROLLER_BUTTONS(PS2_TRIANGLE, PS2_CIRCLE, PS2_CROSS, PS2_SQUARE, "~K~", "~M~", "~A~", "~J~", "~V~", "~C~", "SELECT");
+#endif
+
+#undef PS2_TRIANGLE
+#undef PS2_CIRCLE
+#undef PS2_CROSS
+#undef PS2_SQUARE
+
+#undef CONTROLLER_BUTTONS
+#undef VFB
+
void CControllerConfigManager::GetWideStringOfCommandKeys(uint16 action, wchar *text, uint16 leight)
{
+#ifdef DETECT_PAD_INPUT_SWITCH
+ if (CPad::GetPad(0)->IsAffectedByController) {
+ wchar wstr[16];
+
+ // TODO: INI and/or menu setting for Xbox/PS switch
+#ifdef BUTTON_ICONS
+ const char *(*Buttons)[MAX_CONTROLLERACTIONS] = CFont::ButtonsSlot != -1 ? XboxButtons : XboxButtons_noIcons;
+#else
+ const char *(*Buttons)[MAX_CONTROLLERACTIONS] = XboxButtons_noIcons;
+#endif
+
+ assert(Buttons[CPad::GetPad(0)->Mode][action] != nil); // we cannot use these
+ AsciiToUnicode(Buttons[CPad::GetPad(0)->Mode][action], wstr);
+
+ CMessages::WideStringCopy(text, wstr, leight);
+ return;
+ }
+#endif
+
int32 nums = GetNumOfSettingsForAction((e_ControllerAction)action);
int32 sets = 0;
diff --git a/src/core/EventList.cpp b/src/core/EventList.cpp
index b22ddcb2..8e639656 100644
--- a/src/core/EventList.cpp
+++ b/src/core/EventList.cpp
@@ -59,7 +59,6 @@ CEventList::Update(void)
}
}
-// ok
void
CEventList::RegisterEvent(eEventType type, eEventEntity entityType, CEntity *ent, CPed *criminal, int32 timeout)
{
@@ -121,7 +120,7 @@ CEventList::RegisterEvent(eEventType type, eEventEntity entityType, CEntity *ent
}
if(criminal == FindPlayerPed())
- ReportCrimeForEvent(type, (uintptr)ent, copsDontCare);
+ ReportCrimeForEvent(type, (intptr)ent, copsDontCare);
}
void
@@ -199,7 +198,7 @@ CEventList::FindClosestEvent(eEventType type, CVector posn, int32 *event)
}
void
-CEventList::ReportCrimeForEvent(eEventType type, size_t crimeId, bool copsDontCare)
+CEventList::ReportCrimeForEvent(eEventType type, intptr crimeId, bool copsDontCare)
{
eCrimeType crime;
switch(type){
diff --git a/src/core/EventList.h b/src/core/EventList.h
index dcca1270..3e9d8fd4 100644
--- a/src/core/EventList.h
+++ b/src/core/EventList.h
@@ -62,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, size_t, bool);
+ static void ReportCrimeForEvent(eEventType type, intptr, bool);
};
extern CEvent gaEvent[NUMEVENTS]; \ No newline at end of file
diff --git a/src/core/FileLoader.cpp b/src/core/FileLoader.cpp
index 1c9b4036..9aaba611 100644
--- a/src/core/FileLoader.cpp
+++ b/src/core/FileLoader.cpp
@@ -2,6 +2,7 @@
#include <ctype.h>
#include "main.h"
+#include "General.h"
#include "Quaternion.h"
#include "ModelInfo.h"
#include "ModelIndices.h"
@@ -11,7 +12,6 @@
#include "HandlingMgr.h"
#include "CarCtrl.h"
#include "PedType.h"
-#include "PedStats.h"
#include "AnimManager.h"
#include "Game.h"
#include "RwHelper.h"
@@ -25,6 +25,7 @@
#include "ZoneCull.h"
#include "CdStream.h"
#include "FileLoader.h"
+#include "MemoryHeap.h"
#include "Streaming.h"
#include "ColStore.h"
#include "Occlusion.h"
@@ -69,17 +70,19 @@ CFileLoader::LoadLevel(const char *filename)
if(*line == '#')
continue;
- if(strncmp(line, "EXIT", 9) == 0) // BUG: 9?
+ if(strncmp(line, "EXIT", 4) == 0)
break;
if(strncmp(line, "IMAGEPATH", 9) == 0){
RwImageSetPath(line + 10);
}else if(strncmp(line, "TEXDICTION", 10) == 0){
+ PUSH_MEMID(MEMID_TEXTURES);
strcpy(txdname, line+11);
LoadingScreenLoadingFile(txdname);
RwTexDictionary *txd = LoadTexDictionary(txdname);
AddTexDictionaries(savedTxd, txd);
RwTexDictionaryDestroy(txd);
+ POP_MEMID();
}else if(strncmp(line, "COLFILE", 7) == 0){
LoadingScreenLoadingFile(line+10);
LoadCollisionFile(line+10, 0);
@@ -95,22 +98,30 @@ CFileLoader::LoadLevel(const char *filename)
}else if(strncmp(line, "IPL", 3) == 0){
if(!objectsLoaded){
LoadingScreenLoadingFile("Collision");
+ PUSH_MEMID(MEMID_WORLD);
CObjectData::Initialise("DATA\\OBJECT.DAT");
CStreaming::Init();
+ POP_MEMID();
+ PUSH_MEMID(MEMID_COLLISION);
CColStore::LoadAllCollision();
+ POP_MEMID();
for(int i = 0; i < MODELINFOSIZE; i++)
if(CModelInfo::GetModelInfo(i))
CModelInfo::GetModelInfo(i)->ConvertAnimFileIndex();
objectsLoaded = true;
}
+ PUSH_MEMID(MEMID_WORLD);
LoadingScreenLoadingFile(line + 4);
LoadScene(line + 4);
+ POP_MEMID();
}else if(strncmp(line, "SPLASH", 6) == 0){
#ifndef DISABLE_LOADING_SCREEN
LoadSplash(GetRandomSplashScreen());
#endif
+#ifndef GTA_PS2
}else if(strncmp(line, "CDIMAGE", 7) == 0){
CdStreamAddImage(line + 8);
+#endif
}
}
@@ -161,7 +172,7 @@ CFileLoader::LoadTexDictionary(const char *filename)
struct ColHeader
{
- char ident[4];
+ uint32 ident;
uint32 size;
};
@@ -173,12 +184,14 @@ CFileLoader::LoadCollisionFile(const char *filename, uint8 colSlot)
CBaseModelInfo *mi;
ColHeader header;
+ PUSH_MEMID(MEMID_COLLISION);
+
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);
+ assert(header.ident == 'LLOC');
CFileMgr::Read(fd, (char*)work_buff, header.size);
memcpy(modelname, work_buff, 24);
@@ -198,6 +211,8 @@ CFileLoader::LoadCollisionFile(const char *filename, uint8 colSlot)
}
CFileMgr::CloseFile(fd);
+
+ POP_MEMID();
}
@@ -213,7 +228,7 @@ CFileLoader::LoadCollisionFileFirstTime(uint8 *buffer, uint32 size, uint8 colSlo
while(size > 8){
header = (ColHeader*)buffer;
modelsize = header->size;
- if(strncmp(header->ident, "COLL", 4) != 0)
+ if(header->ident != 'LLOC')
return size-8 < CDSTREAM_SECTOR_SIZE;
memcpy(modelname, buffer+8, 24);
memcpy(work_buff, buffer+32, modelsize-24);
@@ -247,7 +262,7 @@ CFileLoader::LoadCollisionFile(uint8 *buffer, uint32 size, uint8 colSlot)
while(size > 8){
header = (ColHeader*)buffer;
modelsize = header->size;
- if(strncmp(header->ident, "COLL", 4) != 0)
+ if(header->ident != 'LLOC')
return size-8 < CDSTREAM_SECTOR_SIZE;
memcpy(modelname, buffer+8, 24);
memcpy(work_buff, buffer+32, modelsize-24);
@@ -292,6 +307,7 @@ CFileLoader::LoadCollisionModel(uint8 *buf, CColModel &model, char *modelname)
buf += 44;
if(model.numSpheres > 0){
model.spheres = (CColSphere*)RwMalloc(model.numSpheres*sizeof(CColSphere));
+ REGISTER_MEMPTR(&model.spheres);
for(i = 0; i < model.numSpheres; i++){
model.spheres[i].Set(*(float*)buf, *(CVector*)(buf+4), buf[16], buf[17]);
buf += 20;
@@ -316,6 +332,7 @@ CFileLoader::LoadCollisionModel(uint8 *buf, CColModel &model, char *modelname)
buf += 4;
if(model.numBoxes > 0){
model.boxes = (CColBox*)RwMalloc(model.numBoxes*sizeof(CColBox));
+ REGISTER_MEMPTR(&model.boxes);
for(i = 0; i < model.numBoxes; i++){
model.boxes[i].Set(*(CVector*)buf, *(CVector*)(buf+12), buf[24], buf[25]);
buf += 28;
@@ -327,6 +344,7 @@ CFileLoader::LoadCollisionModel(uint8 *buf, CColModel &model, char *modelname)
buf += 4;
if(numVertices > 0){
model.vertices = (CompressedVector*)RwMalloc(numVertices*sizeof(CompressedVector));
+ REGISTER_MEMPTR(&model.vertices);
for(i = 0; i < numVertices; i++){
model.vertices[i].Set(*(float*)buf, *(float*)(buf+4), *(float*)(buf+8));
#if 0
@@ -344,6 +362,7 @@ CFileLoader::LoadCollisionModel(uint8 *buf, CColModel &model, char *modelname)
buf += 4;
if(model.numTriangles > 0){
model.triangles = (CColTriangle*)RwMalloc(model.numTriangles*sizeof(CColTriangle));
+ REGISTER_MEMPTR(&model.triangles);
for(i = 0; i < model.numTriangles; i++){
model.triangles[i].Set(*(int32*)buf, *(int32*)(buf+4), *(int32*)(buf+8), buf[12]);
buf += 16;
@@ -567,6 +586,9 @@ CFileLoader::AddTexDictionaries(RwTexDictionary *dst, RwTexDictionary *src)
RwTexDictionaryForAllTextures(src, MoveTexturesCB, dst);
}
+#define isLine3(l, a, b, c) ((l[0] == a) && (l[1] == b) && (l[2] == c))
+#define isLine4(l, a, b, c, d) ((l[0] == a) && (l[1] == b) && (l[2] == c) && (l[3] == d))
+
void
CFileLoader::LoadObjectTypes(const char *filename)
{
@@ -602,15 +624,15 @@ CFileLoader::LoadObjectTypes(const char *filename)
continue;
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){
+ if(isLine4(line, 'o','b','j','s')) section = OBJS;
+ else if(isLine4(line, 't','o','b','j')) section = TOBJ;
+ else if(isLine4(line, 'w','e','a','p')) section = WEAP;
+ else if(isLine4(line, 'h','i','e','r')) section = HIER;
+ else if(isLine4(line, 'c','a','r','s')) section = CARS;
+ else if(isLine4(line, 'p','e','d','s')) section = PEDS;
+ else if(isLine4(line, 'p','a','t','h')) section = PATH;
+ else if(isLine4(line, '2','d','f','x')) section = TWODFX;
+ }else if(isLine3(line, 'e','n','d')){
section = NONE;
}else switch(section){
case OBJS:
@@ -843,21 +865,21 @@ CFileLoader::LoadVehicleObject(const char *line)
mi->m_level = level;
mi->m_compRules = comprules;
- if(strncmp(type, "car", 4) == 0){
+ if(strcmp(type, "car") == 0){
mi->m_wheelId = misc;
mi->m_wheelScale = wheelScale;
mi->m_vehicleType = VEHICLE_TYPE_CAR;
- }else if(strncmp(type, "boat", 5) == 0){
+ }else if(strcmp(type, "boat") == 0){
mi->m_vehicleType = VEHICLE_TYPE_BOAT;
- }else if(strncmp(type, "train", 6) == 0){
+ }else if(strcmp(type, "train") == 0){
mi->m_vehicleType = VEHICLE_TYPE_TRAIN;
- }else if(strncmp(type, "heli", 5) == 0){
+ }else if(strcmp(type, "heli") == 0){
mi->m_vehicleType = VEHICLE_TYPE_HELI;
- }else if(strncmp(type, "plane", 6) == 0){
+ }else if(strcmp(type, "plane") == 0){
mi->m_planeLodId = misc;
mi->m_wheelScale = 1.0f;
mi->m_vehicleType = VEHICLE_TYPE_PLANE;
- }else if(strncmp(type, "bike", 5) == 0){
+ }else if(strcmp(type, "bike") == 0){
mi->m_bikeSteerAngle = misc;
mi->m_wheelScale = wheelScale;
mi->m_vehicleType = VEHICLE_TYPE_BIKE;
@@ -866,29 +888,29 @@ CFileLoader::LoadVehicleObject(const char *line)
mi->m_handlingId = mod_HandlingManager.GetHandlingId(handlingId);
- if(strncmp(vehclass, "normal", 7) == 0)
+ if(strcmp(vehclass, "normal") == 0)
mi->m_vehicleClass = CCarCtrl::NORMAL;
- else if(strncmp(vehclass, "poorfamily", 11) == 0)
+ else if(strcmp(vehclass, "poorfamily") == 0)
mi->m_vehicleClass = CCarCtrl::POOR;
- else if(strncmp(vehclass, "richfamily", 11) == 0)
+ else if(strcmp(vehclass, "richfamily") == 0)
mi->m_vehicleClass = CCarCtrl::RICH;
- else if(strncmp(vehclass, "executive", 10) == 0)
+ else if(strcmp(vehclass, "executive") == 0)
mi->m_vehicleClass = CCarCtrl::EXEC;
- else if(strncmp(vehclass, "worker", 7) == 0)
+ else if(strcmp(vehclass, "worker") == 0)
mi->m_vehicleClass = CCarCtrl::WORKER;
- else if(strncmp(vehclass, "big", 4) == 0)
+ else if(strcmp(vehclass, "big") == 0)
mi->m_vehicleClass = CCarCtrl::BIG;
- else if(strncmp(vehclass, "taxi", 5) == 0)
+ else if(strcmp(vehclass, "taxi") == 0)
mi->m_vehicleClass = CCarCtrl::TAXI;
- else if(strncmp(vehclass, "moped", 6) == 0)
+ else if(strcmp(vehclass, "moped") == 0)
mi->m_vehicleClass = CCarCtrl::MOPED;
- else if(strncmp(vehclass, "motorbike", 10) == 0)
+ else if(strcmp(vehclass, "motorbike") == 0)
mi->m_vehicleClass = CCarCtrl::MOTORBIKE;
- else if(strncmp(vehclass, "leisureboat", 12) == 0)
+ else if(strcmp(vehclass, "leisureboat") == 0)
mi->m_vehicleClass = CCarCtrl::LEISUREBOAT;
- else if(strncmp(vehclass, "workerboat", 11) == 0)
+ else if(strcmp(vehclass, "workerboat") == 0)
mi->m_vehicleClass = CCarCtrl::WORKERBOAT;
- else if(strncmp(vehclass, "ignore", 11) == 0){
+ else if(strcmp(vehclass, "ignore") == 0) {
mi->m_vehicleClass = -1;
return;
}
@@ -995,7 +1017,7 @@ CFileLoader::Load2dEffect(const char *line)
CTxdStore::SetCurrentTxd(CTxdStore::FindTxdSlot("particle"));
mi = CModelInfo::GetModelInfo(id);
- effect = CModelInfo::Get2dEffectStore().alloc();
+ effect = CModelInfo::Get2dEffectStore().Alloc();
mi->Add2dEffect(effect);
effect->pos = CVector(x, y, z);
effect->col = CRGBA(r, g, b, a);
@@ -1103,13 +1125,13 @@ CFileLoader::LoadScene(const char *filename)
continue;
if(section == NONE){
- if(strncmp(line, "inst", 4) == 0) section = INST;
- else if(strncmp(line, "zone", 4) == 0) section = ZONE;
- 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){
+ if(isLine4(line, 'i','n','s','t')) section = INST;
+ else if(isLine4(line, 'z','o','n','e')) section = ZONE;
+ else if(isLine4(line, 'c','u','l','l')) section = CULL;
+ else if(isLine4(line, 'p','i','c','k')) section = PICK;
+ else if(isLine4(line, 'p','a','t','h')) section = PATH;
+ else if(isLine4(line, 'o','c','c','l')) section = OCCL;
+ }else if(isLine3(line, 'e','n','d')){
section = NONE;
}else switch(section){
case INST:
@@ -1307,11 +1329,11 @@ CFileLoader::ReloadPaths(const char *filename)
continue;
if (section == NONE) {
- if (strncmp(line, "path", 4) == 0) {
+ if (isLine4(line, 'p','a','t','h')) {
section = PATH;
ThePaths.AllocatePathFindInfoMem(4500);
}
- } else if (strncmp(line, "end", 3) == 0) {
+ } else if (isLine3(line, 'e','n','d')) {
section = NONE;
} else {
switch (section) {
@@ -1362,10 +1384,10 @@ CFileLoader::ReloadObjectTypes(const char *filename)
continue;
if (section == NONE) {
- if (strncmp(line, "objs", 4) == 0) section = OBJS;
- else if (strncmp(line, "tobj", 4) == 0) section = TOBJ;
- else if (strncmp(line, "2dfx", 4) == 0) section = TWODFX;
- } else if (strncmp(line, "end", 3) == 0) {
+ if (isLine4(line, 'o','b','j','s')) section = OBJS;
+ else if (isLine4(line, 't','o','b','j')) section = TOBJ;
+ else if (isLine4(line, '2','d','f','x')) section = TWODFX;
+ } else if (isLine3(line, 'e','n','d')) {
section = NONE;
} else {
switch (section) {
@@ -1438,7 +1460,7 @@ CFileLoader::ReLoadScene(const char *filename)
if (*line == '#')
continue;
- if (strncmp(line, "EXIT", 9) == 0) // BUG: 9?
+ if (strncmp(line, "EXIT", 4) == 0)
break;
if (strncmp(line, "IDE", 3) == 0) {
diff --git a/src/core/FileMgr.cpp b/src/core/FileMgr.cpp
index d3695cb4..99923ddf 100644
--- a/src/core/FileMgr.cpp
+++ b/src/core/FileMgr.cpp
@@ -240,20 +240,22 @@ CFileMgr::SetDirMyDocuments(void)
mychdir(_psGetUserFilesFolder());
}
-size_t
+ssize_t
CFileMgr::LoadFile(const char *file, uint8 *buf, int unused, const char *mode)
{
int fd;
- size_t n, len;
+ ssize_t n, len;
fd = myfopen(file, mode);
if(fd == 0)
- return 0;
+ return -1;
len = 0;
do{
n = myfread(buf + len, 1, 0x4000, fd);
- if(n < 0)
+#ifndef FIX_BUGS
+ if (n < 0)
return -1;
+#endif
len += n;
}while(n == 0x4000);
buf[len] = 0;
@@ -274,13 +276,13 @@ CFileMgr::OpenFileForWriting(const char *file)
}
size_t
-CFileMgr::Read(int fd, const char *buf, size_t len)
+CFileMgr::Read(int fd, const char *buf, ssize_t len)
{
return myfread((void*)buf, 1, len, fd);
}
size_t
-CFileMgr::Write(int fd, const char *buf, size_t len)
+CFileMgr::Write(int fd, const char *buf, ssize_t len)
{
return myfwrite((void*)buf, 1, len, fd);
}
diff --git a/src/core/FileMgr.h b/src/core/FileMgr.h
index 8278953b..98a78360 100644
--- a/src/core/FileMgr.h
+++ b/src/core/FileMgr.h
@@ -9,12 +9,12 @@ public:
static void ChangeDir(const char *dir);
static void SetDir(const char *dir);
static void SetDirMyDocuments(void);
- static size_t LoadFile(const char *file, uint8 *buf, int unused, const char *mode);
+ static ssize_t LoadFile(const char *file, uint8 *buf, int unused, const char *mode);
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, size_t len);
- static size_t Write(int fd, const char *buf, size_t len);
+ static size_t Read(int fd, const char *buf, ssize_t len);
+ static size_t Write(int fd, const char *buf, ssize_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 a47ca3cf..c4c39b1f 100644
--- a/src/core/Fire.cpp
+++ b/src/core/Fire.cpp
@@ -46,7 +46,7 @@ CFire::ProcessFire(void)
float fDamagePlayer;
float fDamagePeds;
float fDamageVehicle;
- int8 nRandNumber;
+ int16 nRandNumber;
float fGreen;
float fRed;
CVector lightpos;
@@ -107,7 +107,11 @@ CFire::ProcessFire(void)
}
}
}
- if (!FindPlayerVehicle() && !FindPlayerPed()->m_pFire && !(FindPlayerPed()->bFireProof)
+ if (!FindPlayerVehicle() &&
+#ifdef FIX_BUGS
+ FindPlayerPed() &&
+#endif
+ !FindPlayerPed()->m_pFire && !(FindPlayerPed()->bFireProof)
&& ((FindPlayerPed()->GetPosition() - m_vecPos).MagnitudeSqr() < 2.0f)) {
FindPlayerPed()->DoStuffToGoOnFire();
gFireManager.StartFire(FindPlayerPed(), m_pSource, 0.8f, 1);
@@ -148,11 +152,10 @@ CFire::ProcessFire(void)
CShadows::StoreStaticShadow((uintptr)this, SHADOWTYPE_ADDITIVE, gpShadowExplosionTex, &lightpos, 7.0f, 0.0f, 0.0f, -7.0f, 0, nRandNumber / 2,
nRandNumber / 2, 0, 10.0f, 1.0f, 40.0f, 0, 0.0f);
}
- fGreen = nRandNumber / 128;
- fRed = nRandNumber / 128;
+ fGreen = nRandNumber / 128.f;
+ fRed = nRandNumber / 128.f;
- CPointLights::AddLight(0, m_vecPos, CVector(0.0f, 0.0f, 0.0f),
- 12.0f, fRed, fGreen, 0, 0, 0);
+ CPointLights::AddLight(CPointLights::LIGHT_POINT, m_vecPos, CVector(0.0f, 0.0f, 0.0f), 12.0f, fRed, fGreen, 0.0f, 0, 0);
} else {
Extinguish();
}
@@ -391,19 +394,16 @@ 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];
+ int i;
+ for (i = 0; i < NUM_FIRES;) {
+ if (m_aFires[i].m_bIsOngoing && (point - m_aFires[i].m_vecPos).MagnitudeSqr() < sq(range)) {
+ break;
+ }
+ if (++i >= NUM_FIRES)
+ return false;
+ }
+
+ CFire *fireToExtinguish = &m_aFires[i];
fireToExtinguish->m_fWaterExtinguishCountdown -= 0.012f * CTimer::GetTimeStep();
CVector steamPos = fireToExtinguish->m_vecPos +
CVector((CGeneral::GetRandomNumber() - 128) * 3.1f / 200.f,
diff --git a/src/core/Frontend.cpp b/src/core/Frontend.cpp
index a52b9bfc..db5da918 100644
--- a/src/core/Frontend.cpp
+++ b/src/core/Frontend.cpp
@@ -39,32 +39,61 @@
#include "User.h"
#include "sampman.h"
-// TODO(Miami): Remove that!! That was my map implementation for III, instead use MAP_ENHACEMENTS on some places
-#define CUSTOM_MAP
+// --MIAMI: file done
// Similar story to Hud.cpp:
// Game has colors inlined in code.
// For easier modification we collect them here:
-CRGBA LABEL_COLOR(255, 150, 225, 255);
-CRGBA SELECTIONBORDER_COLOR(25, 130, 70, 255);
-CRGBA MENUOPTION_COLOR(255, 150, 225, 255);
-CRGBA SELECTEDMENUOPTION_COLOR(255, 150, 225, 255);
-CRGBA HEADER_COLOR(255, 150, 255, 255);
-CRGBA DARKMENUOPTION_COLOR(195, 90, 165, 255);
-CRGBA SLIDERON_COLOR(97, 194, 247, 255);
-CRGBA SLIDEROFF_COLOR(27, 89, 130, 255);
-CRGBA LIST_BACKGROUND_COLOR(49, 101, 148, 255);
-
-#define TIDY_UP_PBP // ProcessUserInput
+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 = 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 RADIO_SELECTOR_COLOR = SLIDEROFF_COLOR;
+const CRGBA INACTIVE_RADIO_COLOR(100, 100, 255, 100);
+const CRGBA SCROLLBAR_COLOR = LABEL_COLOR;
+
+#define MAP_MIN_SIZE 162.f
+#define MAP_SIZE_TO_ALLOW_X_MOVE 297.f
+
#define MAX_VISIBLE_LIST_ROW 30
#define SCROLLBAR_MAX_HEIGHT 263.0f // not in end result
+#define SCROLLABLE_PAGES
+
+#define hasNativeList(screen) (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)
+#define SCREEN_HAS_AUTO_SCROLLBAR (m_nTotalListRow > MAX_VISIBLE_OPTION && !hasNativeList(m_nCurrScreen))
+
+int GetOptionCount(int screen)
+{
+ int i = 0;
+ for (; i < NUM_MENUROWS && aScreens[screen].m_aEntries[i].m_Action != MENUACTION_NOTHING; i++);
+ return i;
+}
-#ifdef USE_PRECISE_MEASUREMENT_CONVERTION
-#define MILES_IN_METER 0.000621371192f
-#define FEET_IN_METER 3.28084f
+#define SETUP_SCROLLING(screen) \
+ if (!hasNativeList(screen)) { \
+ m_nTotalListRow = GetOptionCount(screen); \
+ if (m_nTotalListRow > MAX_VISIBLE_OPTION) { \
+ m_nSelectedListRow = 0; \
+ m_nFirstVisibleRowOnList = 0; \
+ m_nScrollbarTopMargin = 0; \
+ } \
+ }
+
+#define MINUS_SCROLL_OFFSET - scrollOffset
#else
-#define MILES_IN_METER 0.00059880241f
-#define FEET_IN_METER 3.33f
+#define MAX_VISIBLE_OPTION_ON_SCREEN MAX_VISIBLE_LIST_ROW
+#define SETUP_SCROLLING(screen)
+#define MINUS_SCROLL_OFFSET
#endif
#ifdef TRIANGLE_BACK_BUTTON
@@ -78,15 +107,14 @@ CRGBA LIST_BACKGROUND_COLOR(49, 101, 148, 255);
#define GetBackJustDown GetSquareJustDown
#endif
+#ifdef MAP_ENHANCEMENTS
+CVector2D mapCrosshair;
+#endif
+
#ifdef CUTSCENE_BORDERS_SWITCH
bool CMenuManager::m_PrefsCutsceneBorders = true;
#endif
-const CRGBA TEXT_COLOR = CRGBA(150, 110, 30, 255); // TODO(Miami): is this still here?
-
-float MENU_TEXT_SIZE_X = SMALLTEXT_X_SCALE;
-float MENU_TEXT_SIZE_Y = SMALLTEXT_Y_SCALE;
-
bool holdingScrollBar; // *(bool*)0x7039B9; // not original name
CMenuManager FrontEndMenuManager;
@@ -97,17 +125,11 @@ MenuTrapezoid menuBg(CGeneral::GetRandomNumber() % 40 + 65, CGeneral::GetRandomN
MenuTrapezoid menuOptionHighlight(0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f);
-#ifdef CUSTOM_MAP
-bool bMapLoaded = false;
-bool bMapMouseShownOnce = false;
-#endif
-
#ifndef MASTER
bool CMenuManager::m_PrefsMarketing = false;
bool CMenuManager::m_PrefsDisableTutorials = false;
#endif // !MASTER
-// 0x68C144
const char* FrontendFilenames[][2] = {
{"background", ""},
{"vc_logo", "vc_logom"},
@@ -150,37 +172,59 @@ const char* FrontendFilenames[][2] = {
#define MENU_Y(y) StretchY(y)
#endif
-#define PREPARE_MENU_HEADER \
+#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
+
+#define SET_FONT_FOR_MENU_HEADER \
CFont::SetRightJustifyOn(); \
CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING)); \
CFont::SetScale(MENU_X(MENUHEADER_WIDTH), MENU_Y(MENUHEADER_HEIGHT)); \
CFont::SetDropShadowPosition(0);
-#define ProcessSlider(value, y, increaseAction, decreaseAction, hoverStartX, hoverEndX) \
+#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(); \
+ CFont::SetScale(MENU_X(MENUACTION_SCALE_MULT), MENU_Y(MENUACTION_SCALE_MULT)); \
+ CFont::SetPropOn(); \
+ CFont::SetCentreOff(); \
+ CFont::SetJustifyOn(); \
+ CFont::SetRightJustifyOff(); \
+ CFont::SetBackGroundOnlyTextOn(); \
+ CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENU_X_MARGIN)); \
+ CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(MENU_X_MARGIN));
+
+#define ProcessSlider(value, origY, increaseAction, decreaseAction, hoverEndX, onlyWhenHoveringRow) \
do { \
+ 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(3.0f), MENU_Y(y), MENU_Y(MENUSLIDER_BIGGEST_BAR + y))) \
+ if (CheckHover(0, lastActiveBarX - MENU_X(3.0f), MENU_Y(y), MENU_Y(MENUSLIDER_BIGGEST_BAR + y))) { \
m_nHoverOption = decreaseAction; \
- \
- if (!CheckHover(MENU_X(3.0f) + lastActiveBarX, hoverEndX, MENU_Y(y), MENU_Y(MENUSLIDER_BIGGEST_BAR + y))) \
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_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)
-// TODO: this is COMPLETELY different in VC
-#define ProcessRadioIcon(sprite, x, y, radioId, hoverOpt) \
- do { \
- sprite.Draw(x, y, MENU_X(MENURADIO_ICON_SCALE), MENU_Y(MENURADIO_ICON_SCALE), radioId == m_PrefsRadioStation ? CRGBA(255, 255, 255, 255) : CRGBA(255, 255, 255, 100)); \
- if (CheckHover(x, x + MENU_X(MENURADIO_ICON_SCALE), y, y + MENU_Y(MENURADIO_ICON_SCALE))) \
- m_nHoverOption = hoverOpt; \
- } while (0)
-
// --- Functions not in the game/inlined starts
inline void
@@ -200,8 +244,8 @@ CMenuManager::ScrollUpListByOne()
inline void
CMenuManager::ScrollDownListByOne()
{
- if (m_nSelectedListRow == m_nFirstVisibleRowOnList + MAX_VISIBLE_LIST_ROW - 1) {
- if (m_nFirstVisibleRowOnList < m_nTotalListRow - MAX_VISIBLE_LIST_ROW) {
+ if (m_nSelectedListRow == m_nFirstVisibleRowOnList + MAX_VISIBLE_OPTION_ON_SCREEN - 1) {
+ if (m_nFirstVisibleRowOnList < m_nTotalListRow - MAX_VISIBLE_OPTION_ON_SCREEN) {
m_nSelectedListRow++;
m_nFirstVisibleRowOnList++;
m_nScrollbarTopMargin += SCROLLBAR_MAX_HEIGHT / m_nTotalListRow;
@@ -216,13 +260,13 @@ CMenuManager::ScrollDownListByOne()
inline void
CMenuManager::PageUpList(bool playSoundOnSuccess)
{
- if (m_nTotalListRow > MAX_VISIBLE_LIST_ROW) {
+ if (m_nTotalListRow > MAX_VISIBLE_OPTION_ON_SCREEN) {
if (m_nFirstVisibleRowOnList > 0) {
if(playSoundOnSuccess)
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_HIGHLIGHT_OPTION, 0);
- m_nFirstVisibleRowOnList = Max(0, m_nFirstVisibleRowOnList - MAX_VISIBLE_LIST_ROW);
- m_nSelectedListRow = Min(m_nSelectedListRow, m_nFirstVisibleRowOnList + MAX_VISIBLE_LIST_ROW - 1);
+ m_nFirstVisibleRowOnList = Max(0, m_nFirstVisibleRowOnList - MAX_VISIBLE_OPTION_ON_SCREEN);
+ m_nSelectedListRow = Min(m_nSelectedListRow, m_nFirstVisibleRowOnList + MAX_VISIBLE_OPTION_ON_SCREEN - 1);
} else {
m_nFirstVisibleRowOnList = 0;
m_nSelectedListRow = 0;
@@ -234,58 +278,144 @@ CMenuManager::PageUpList(bool playSoundOnSuccess)
inline void
CMenuManager::PageDownList(bool playSoundOnSuccess)
{
- if (m_nTotalListRow > MAX_VISIBLE_LIST_ROW) {
- if (m_nFirstVisibleRowOnList < m_nTotalListRow - MAX_VISIBLE_LIST_ROW) {
+ if (m_nTotalListRow > MAX_VISIBLE_OPTION_ON_SCREEN) {
+ if (m_nFirstVisibleRowOnList < m_nTotalListRow - MAX_VISIBLE_OPTION_ON_SCREEN) {
if(playSoundOnSuccess)
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_HIGHLIGHT_OPTION, 0);
- m_nFirstVisibleRowOnList = Min(m_nFirstVisibleRowOnList + MAX_VISIBLE_LIST_ROW, m_nTotalListRow - MAX_VISIBLE_LIST_ROW);
+ m_nFirstVisibleRowOnList = Min(m_nFirstVisibleRowOnList + MAX_VISIBLE_OPTION_ON_SCREEN, m_nTotalListRow - MAX_VISIBLE_OPTION_ON_SCREEN);
m_nSelectedListRow = Max(m_nSelectedListRow, m_nFirstVisibleRowOnList);
} else {
- m_nFirstVisibleRowOnList = m_nTotalListRow - MAX_VISIBLE_LIST_ROW;
+ m_nFirstVisibleRowOnList = m_nTotalListRow - MAX_VISIBLE_OPTION_ON_SCREEN;
m_nSelectedListRow = m_nTotalListRow - 1;
}
m_nScrollbarTopMargin = (SCROLLBAR_MAX_HEIGHT / m_nTotalListRow) * m_nFirstVisibleRowOnList;
}
}
+#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++) {
+ if (strcmp(gxtKey, aScreens[screen].m_aEntries[i].m_EntryName) == 0)
+ return true;
+ }
+ return false;
+}
+
inline void
CMenuManager::ThingsToDoBeforeLeavingPage()
{
if ((m_nCurrScreen == MENUPAGE_SKIN_SELECT) && strcmp(m_aSkinName, m_PrefsSkinFile) != 0) {
CWorld::Players[0].SetPlayerSkin(m_PrefsSkinFile);
+
} else if (m_nCurrScreen == MENUPAGE_SOUND_SETTINGS) {
if (m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER)
m_nPrefsAudio3DProviderIndex = DMAudio.GetCurrent3DProviderIndex();
-#ifdef TIDY_UP_PBP
+
DMAudio.StopFrontEndTrack();
OutputDebugString("FRONTEND AUDIO TRACK STOPPED");
-#endif
- } else if (m_nCurrScreen == MENUPAGE_DISPLAY_SETTINGS) {
+
+ } else if (ScreenHasOption(m_nCurrScreen, "FED_RES")) {
m_nDisplayVideoMode = m_nPrefsVideoMode;
-#ifdef IMPROVED_VIDEOMODE
- m_nSelectedScreenMode = m_nPrefsWindowed;
-#endif
}
if (m_nCurrScreen == MENUPAGE_SKIN_SELECT) {
CPlayerSkin::EndFrontendSkinEdit();
}
+
+#ifdef SCROLLABLE_PAGES
+ if (SCREEN_HAS_AUTO_SCROLLBAR) {
+ m_nSelectedListRow = 0;
+ m_nFirstVisibleRowOnList = 0;
+ m_nScrollbarTopMargin = 0;
+ }
+#endif
+
+ CMenuScreenCustom::CMenuEntry &option = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption];
+
+ if (option.m_Action == MENUACTION_CFO_DYNAMIC)
+ if(option.m_CFODynamic->buttonPressFunc)
+ option.m_CFODynamic->buttonPressFunc(FEOPTION_ACTION_FOCUSLOSS);
+
+ if (option.m_Action == MENUACTION_CFO_SELECT && option.m_CFOSelect->onlyApplyOnEnter && option.m_CFOSelect->lastSavedValue != option.m_CFOSelect->displayedValue)
+ option.m_CFOSelect->displayedValue = *option.m_CFO->value = option.m_CFOSelect->lastSavedValue;
+
+ if (aScreens[m_nCurrScreen].returnPrevPageFunc) {
+ aScreens[m_nCurrScreen].returnPrevPageFunc();
+ }
}
-int8
+inline int8
+CMenuManager::GetPreviousPageOption()
+{
+ 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;
+
+ prevPage = prevPage == MENUPAGE_NONE ? (!m_bGameNotLoaded ? MENUPAGE_PAUSE_MENU : MENUPAGE_START_MENU) : prevPage;
+
+ for (int i = 0; i < NUM_MENUROWS; i++) {
+ if (aScreens[prevPage].m_aEntries[i].m_Action >= MENUACTION_NOTHING) { // CFO check
+ if (aScreens[prevPage].m_aEntries[i].m_TargetMenu == m_nCurrScreen) {
+ return i;
+ }
+ }
+ }
+
+ // This shouldn't happen
+ return 0;
+}
+
+#else
+#define PLUS_LINE_HEIGHT_ON_SCREEN + MENU_DEFAULT_LINE_HEIGHT
+inline void
+CMenuManager::ThingsToDoBeforeLeavingPage()
+{
+ 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;
+ }
+
+#ifdef SCROLLABLE_PAGES
+ if (SCREEN_HAS_AUTO_SCROLLBAR) {
+ m_nSelectedListRow = 0;
+ m_nFirstVisibleRowOnList = 0;
+ m_nScrollbarTopMargin = 0;
+ }
+#endif
+}
+
+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
// ------ Functions not in the game/inlined ends
bool DoRWStuffStartOfFrame(int16 TopRed, int16 TopGreen, int16 TopBlue, int16 BottomRed, int16 BottomGreen, int16 BottomBlue, int16 Alpha);
void DoRWStuffEndOfFrame(void);
-// --MIAMI: Done
void
CMenuManager::SwitchToNewScreen(int8 screen)
{
@@ -315,8 +445,9 @@ CMenuManager::SwitchToNewScreen(int8 screen)
m_nCurrOption = 0;
m_nCurrScreen = screen;
}
-
- if (m_nPrevScreen == MENUPAGE_SKIN_SELECT || m_nPrevScreen == MENUPAGE_KEYBOARD_CONTROLS)
+ SETUP_SCROLLING(m_nCurrScreen)
+
+ if (hasNativeList(m_nPrevScreen))
m_nTotalListRow = 0;
if (m_nCurrScreen == MENUPAGE_CHOOSE_SAVE_SLOT)
@@ -341,7 +472,11 @@ CMenuManager::CMenuManager()
m_PrefsMP3BoostVolume = 0;
m_PrefsShowSubtitles = 0;
m_PrefsShowLegends = 1;
+#ifdef ASPECT_RATIO_SCALE
+ m_PrefsUseWideScreen = AR_AUTO;
+#else
m_PrefsUseWideScreen = 0;
+#endif
m_PrefsVsync = 0;
m_PrefsVsyncDisp = 1;
m_PrefsFrameLimiter = 1;
@@ -362,7 +497,11 @@ CMenuManager::CMenuManager()
m_PrefsDMA = 1;
OS_Language = LANG_ENGLISH;
m_ControlMethod = CONTROL_STANDARD;
+#ifdef PC_PLAYER_CONTROLS
CCamera::m_bUseMouse3rdPerson = true;
+#else
+ CCamera::m_bUseMouse3rdPerson = false;
+#endif
m_lastWorking3DAudioProvider = 0;
m_nFirstVisibleRowOnList = 0;
m_nScrollbarTopMargin = 0.0f;
@@ -383,11 +522,15 @@ CMenuManager::CMenuManager()
m_bWantToLoad = false;
m_nMenuFadeAlpha = 0;
m_OnlySaveMenu = false;
- m_fMapSize = 162.0f;
- m_fMapCenterX = 320.0f;
- m_fMapCenterY = 225.0f;
+ 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);
+
+#ifdef NO_ISLAND_LOADING
+ m_PrefsIslandLoading = ISLAND_LOADING_LOW;
+#endif
}
void
@@ -408,15 +551,15 @@ CMenuManager::Initialise(void)
DoRWStuffStartOfFrame(0, 0, 0, 0, 0, 0, 255);
DoRWStuffEndOfFrame();
m_AllowNavigation = false;
- m_menuTransitionProgress = -50; // to start from black
+ m_firstStartCounter = -50; // to start from black
m_nMenuFadeAlpha = 0;
m_nCurrOption = 0;
m_nOptionHighlightTransitionBlend = 0;
CentreMousePointer();
m_bShowMouse = true;
- m_fMapSize = 162.0f;
- m_fMapCenterX = 320.0f;
- m_fMapCenterY = 225.0f;
+ 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;
@@ -440,37 +583,6 @@ CMenuManager::Initialise(void)
}
void
-CMenuManager::BuildStatLine(Const char *text, void *stat, bool itsFloat, void *stat2)
-{
- if (!text)
- return;
-
-#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';
-
- UnicodeStrcpy(gUString, TheText.Get(text));
- AsciiToUnicode(gString2, gUString2);
-}
-
-void
CMenuManager::CentreMousePointer()
{
if (SCREEN_WIDTH * 0.5f != 0.0f && 0.0f != SCREEN_HEIGHT * 0.5f) {
@@ -489,7 +601,6 @@ CMenuManager::CentreMousePointer()
}
}
-// --MIAMI: Done
void
CMenuManager::CheckCodesForControls(int typeOfControl)
{
@@ -558,7 +669,6 @@ CMenuManager::CheckHover(int x1, int x2, int y1, int y2)
m_nMousePosY > y1 && m_nMousePosY < y2;
}
-// --MIAMI: Done
void
CMenuManager::CheckSliderMovement(int value)
{
@@ -601,6 +711,9 @@ CMenuManager::CheckSliderMovement(int value)
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);
+#ifdef FIX_BUGS
+ TheCamera.m_fMouseAccelVertical = TheCamera.m_fMouseAccelHorzntl + 0.0005f;
+#endif
break;
default:
return;
@@ -608,7 +721,6 @@ CMenuManager::CheckSliderMovement(int value)
SaveSettings();
}
-// --MIAMI: Done
void
CMenuManager::DisplayHelperText(char *text)
{
@@ -624,9 +736,10 @@ CMenuManager::DisplayHelperText(char *text)
CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD));
CFont::SetDropShadowPosition(0);
+ // 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(10.f), SCREEN_SCALE_FROM_BOTTOM(18.f), TheText.Get(text));
+ CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(HELPER_TEXT_RIGHT_MARGIN), SCREEN_SCALE_FROM_BOTTOM(HELPER_TEXT_BOTTOM_MARGIN), TheText.Get(text));
return;
}
@@ -646,19 +759,19 @@ CMenuManager::DisplayHelperText(char *text)
// TODO: name this cases?
switch (m_nHelperTextMsgId) {
case 1:
- CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(10.f), SCREEN_SCALE_FROM_BOTTOM(18.f), 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::PrintString(SCREEN_STRETCH_FROM_RIGHT(10.f), SCREEN_SCALE_FROM_BOTTOM(18.f), 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::PrintString(SCREEN_STRETCH_FROM_RIGHT(10.f), SCREEN_SCALE_FROM_BOTTOM(18.f), 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::PrintString(SCREEN_STRETCH_FROM_RIGHT(10.f), SCREEN_SCALE_FROM_BOTTOM(18.f), TheText.Get("FET_STS"));
+ 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(10.f), SCREEN_SCALE_FROM_BOTTOM(18.f), 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_RSC"));
break;
default:
if (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action == MENUACTION_NO)
@@ -667,7 +780,7 @@ CMenuManager::DisplayHelperText(char *text)
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(10.f), SCREEN_SCALE_FROM_BOTTOM(18.f),
+ 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;
}
@@ -676,7 +789,7 @@ CMenuManager::DisplayHelperText(char *text)
return;
if (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action == MENUACTION_SCREENRES) {
- CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(10.f), SCREEN_SCALE_FROM_BOTTOM(18.f),
+ 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;
}
@@ -684,7 +797,7 @@ CMenuManager::DisplayHelperText(char *text)
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(10.f), SCREEN_SCALE_FROM_BOTTOM(18.f),
+ 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;
}
@@ -693,19 +806,18 @@ CMenuManager::DisplayHelperText(char *text)
return;
if (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action == MENUACTION_MP3VOLUMEBOOST) {
- CFont::PrintString(SCREEN_STRETCH_FROM_RIGHT(10.f), SCREEN_SCALE_FROM_BOTTOM(18.f),
+ 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(10.f), SCREEN_SCALE_FROM_BOTTOM(18.f),
+ 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;
}
}
-// --MIAMI: Done
int
CMenuManager::DisplaySlider(float x, float y, float mostLeftBarSize, float mostRightBarSize, float rectSize, float progress, float spacing)
{
@@ -737,7 +849,6 @@ CMenuManager::DisplaySlider(float x, float y, float mostLeftBarSize, float mostR
return lastActiveBarX;
}
-// TODO(Miami)
void
CMenuManager::DoSettingsBeforeStartingAGame()
{
@@ -751,6 +862,9 @@ CMenuManager::DoSettingsBeforeStartingAGame()
m_bWantToRestart = true;
DMAudio.SetEffectsFadeVol(0);
DMAudio.SetMusicFadeVol(0);
+ for (int i = 0; i < NUM_RADIOS; i++)
+ CStats::FavoriteRadioStationList[i] = 0.0f;
+
SwitchMenuOnAndOff();
DMAudio.ResetTimers(CTimer::GetTimeInMilliseconds());
}
@@ -766,9 +880,19 @@ CMenuManager::DrawStandardMenus(bool activeScreen)
CFont::SetJustifyOn();
CFont::SetBackGroundOnlyTextOff();
- CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENU_UNK_X_MARGIN));
- CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(MENU_UNK_X_MARGIN));
+#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
switch (m_nCurrScreen) {
case MENUPAGE_CHOOSE_LOAD_SLOT:
@@ -777,14 +901,11 @@ CMenuManager::DrawStandardMenus(bool activeScreen)
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(130)));
+ 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;
- /*
- // TODO(Miami)
case MENUPAGE_SOUND_SETTINGS:
- PrintSoundSettings();
+ PrintRadioSelector();
break;
- */
case MENUPAGE_STATS:
PrintStats();
break;
@@ -796,7 +917,7 @@ CMenuManager::DrawStandardMenus(bool activeScreen)
// Page name
if (aScreens[m_nCurrScreen].m_ScreenName[0] != '\0') {
- PREPARE_MENU_HEADER
+ 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(aScreens[m_nCurrScreen].m_ScreenName));
@@ -812,7 +933,6 @@ CMenuManager::DrawStandardMenus(bool activeScreen)
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)));
@@ -847,8 +967,8 @@ CMenuManager::DrawStandardMenus(bool activeScreen)
}
CFont::PrintString(MENU_X_LEFT_ALIGNED(100.0f), MENU_Y(97.0f), str);
- CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENU_UNK_X_MARGIN));
- CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(MENU_UNK_X_MARGIN));
+ CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(xMargin));
+ CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(xMargin));
}
if (m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS) {
@@ -858,7 +978,6 @@ CMenuManager::DrawStandardMenus(bool activeScreen)
DrawControllerScreenExtraText(-8.0f, MENU_X_LEFT_ALIGNED(350), MENU_DEFAULT_LINE_HEIGHT);
}
- bool foundTheHoveringItem = false;
wchar unicodeTemp[64];
char asciiTemp[32];
@@ -866,8 +985,15 @@ CMenuManager::DrawStandardMenus(bool activeScreen)
uint8 section = 0; // 0: highlight trapezoid 1: texts
while (section < 2) {
+#endif
+#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 i = firstOption; i < firstOption + MAX_VISIBLE_OPTION && i < NUM_MENUROWS; ++i) {
+#else
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) {
@@ -892,16 +1018,26 @@ CMenuManager::DrawStandardMenus(bool activeScreen)
CFont::SetRightJustifyOff();
CFont::SetCentreOn();
}
- if (!aScreens[m_nCurrScreen].m_aEntries[i].m_X && !aScreens[m_nCurrScreen].m_aEntries[i].m_Y) {
+ 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
+ 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
} 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 + MENU_DEFAULT_LINE_HEIGHT;
+ 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') {
@@ -923,7 +1059,7 @@ CMenuManager::DrawStandardMenus(bool activeScreen)
}
if (m_nPrefsAudio3DProviderIndex == NO_AUDIO_PROVIDER) {
- if (strncmp(aScreens[m_nCurrScreen].m_aEntries[i].m_EntryName, "FEO_AUD", 8) == 0) {
+ if (strcmp(aScreens[m_nCurrScreen].m_aEntries[i].m_EntryName, "FEO_AUD") == 0) {
CFont::SetColor(CRGBA(DARKMENUOPTION_COLOR.r, DARKMENUOPTION_COLOR.g, DARKMENUOPTION_COLOR.b, FadeIn(255)));
}
}
@@ -1000,11 +1136,38 @@ CMenuManager::DrawStandardMenus(bool activeScreen)
break;
case MENUACTION_RADIO:
- if (m_PrefsRadioStation > USERTRACK)
- break;
-
- sprintf(gString, "FEA_FM%d", m_PrefsRadioStation);
- rightText = TheText.Get(gString);
+ 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");
@@ -1050,17 +1213,6 @@ CMenuManager::DrawStandardMenus(bool activeScreen)
CFont::SetColor(CRGBA(DARKMENUOPTION_COLOR.r, DARKMENUOPTION_COLOR.g, DARKMENUOPTION_COLOR.b, FadeIn(255)));
}
break;
-#ifdef IMPROVED_VIDEOMODE
- case MENUACTION_SCREENFORMAT:
- if (m_nSelectedScreenMode == 0)
- sprintf(asciiTemp, "FULLSCREEN");
- else
- sprintf(asciiTemp, "WINDOWED");
-
- AsciiToUnicode(asciiTemp, unicodeTemp);
- rightText = unicodeTemp;
- break;
-#endif
case MENUACTION_AUDIOHW:
if (m_nPrefsAudio3DProviderIndex == NO_AUDIO_PROVIDER)
rightText = TheText.Get("FEA_NAH");
@@ -1123,6 +1275,30 @@ CMenuManager::DrawStandardMenus(bool activeScreen)
rightText = TheText.Get("FEA_NM3");
}
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) {
+ // 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->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]);
+
+ } 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
}
// Highlight trapezoid
@@ -1130,7 +1306,8 @@ CMenuManager::DrawStandardMenus(bool activeScreen)
int leftXMax, rightXMin;
- // FIX: Let's don't scale those so GetStringWidth will give unscaled width, which will be handy to other calculations below that's done without scaling in mind.
+ // 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);
@@ -1140,9 +1317,11 @@ CMenuManager::DrawStandardMenus(bool activeScreen)
if (CFont::Details.centre) {
leftXMax = Max(0, aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_X - curOptionWidth / 2.f);
rightXMin = Min(DEFAULT_SCREEN_WIDTH, curOptionWidth / 2.f + aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_X);
+
} else if (!CFont::Details.rightJustify) {
leftXMax = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_X;
rightXMin = Min(DEFAULT_SCREEN_WIDTH, curOptionWidth + aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_X);
+
} else {
leftXMax = Max(0, aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_X - curOptionWidth);
rightXMin = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_X;
@@ -1158,16 +1337,15 @@ CMenuManager::DrawStandardMenus(bool activeScreen)
leftXMax = 40;
}
- int y = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Y;
+ int y = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Y MINUS_SCROLL_OFFSET;
int topYMax = y;
- uint32 bottomYMin = y + 22;
- int transition = m_nOptionHighlightTransitionBlend;
+ uint32 bottomYMin = y + MENU_DEFAULT_LINE_HEIGHT - 7; // Decreasing is not recommended. Because this actually is dependent to font scale, not line height.
// 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.
- if (transition == 0) {
- if (m_menuTransitionProgress == 255 && m_nMenuFadeAlpha == 255 && !bMenuChangeOngoing) {
+ 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),
@@ -1184,9 +1362,10 @@ CMenuManager::DrawStandardMenus(bool activeScreen)
menuOptionHighlight.bottomRight_y = bottomYMin + CGeneral::GetRandomNumber() % 7;
menuOptionHighlight.UpdateMultipliers();
menuOptionHighlight.Translate(m_nOptionHighlightTransitionBlend);
- } else if (transition < 255) {
+
+ } else if (m_nOptionHighlightTransitionBlend < 255) {
menuOptionHighlight.Translate(m_nOptionHighlightTransitionBlend);
- if (m_menuTransitionProgress == 255 && m_nMenuFadeAlpha == 255 && !bMenuChangeOngoing) {
+ 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),
@@ -1195,7 +1374,7 @@ CMenuManager::DrawStandardMenus(bool activeScreen)
} else {
m_nOptionHighlightTransitionBlend = 255;
menuOptionHighlight.Translate(m_nOptionHighlightTransitionBlend);
- if (m_menuTransitionProgress == 255 && m_nMenuFadeAlpha == 255 && !bMenuChangeOngoing) {
+ 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),
@@ -1219,10 +1398,9 @@ CMenuManager::DrawStandardMenus(bool activeScreen)
}
}
- if (section != 0) {
-
+ 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), 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);
}
if (rightText) {
@@ -1235,7 +1413,7 @@ CMenuManager::DrawStandardMenus(bool activeScreen)
CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING));
CFont::SetScale(MENU_X(BIGTEXT_X_SCALE), MENU_Y(BIGTEXT_Y_SCALE));
}
- CFont::PrintString(MENU_X_LEFT_ALIGNED(600.0f), MENU_Y(aScreens[m_nCurrScreen].m_aEntries[i].m_Y), rightText);
+ 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()) {
@@ -1256,7 +1434,12 @@ CMenuManager::DrawStandardMenus(bool activeScreen)
}
if (m_nPrefsAudio3DProviderIndex != DMAudio.GetCurrent3DProviderIndex()) {
if (strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FEA_3DH") != 0
- && m_nCurrScreen == MENUPAGE_SOUND_SETTINGS && m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER) {
+#ifdef CUSTOM_FRONTEND_OPTIONS
+ && ScreenHasOption(m_nCurrScreen, "FEA_3DH")
+#else
+ && m_nCurrScreen == MENUPAGE_SOUND_SETTINGS
+#endif
+ && m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER) {
m_nPrefsAudio3DProviderIndex = DMAudio.GetCurrent3DProviderIndex();
SetHelperText(3);
@@ -1264,41 +1447,40 @@ CMenuManager::DrawStandardMenus(bool activeScreen)
}
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")) {
+#else
&& m_nCurrScreen == MENUPAGE_DISPLAY_SETTINGS) {
+#endif
m_nDisplayVideoMode = m_nPrefsVideoMode;
SetHelperText(3);
}
}
-#ifdef IMPROVED_VIDEOMODE
- if (m_nSelectedScreenMode != m_nPrefsWindowed) {
- if (strcmp(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_EntryName, "FED_POS") != 0
- && m_nCurrScreen == MENUPAGE_DISPLAY_SETTINGS) {
- m_nSelectedScreenMode = m_nPrefsWindowed;
- }
- }
-#endif
- // TODO(Miami): check
// 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, MENU_X_LEFT_ALIGNED(170.0f), SCREEN_WIDTH);
- break;
- case MENUACTION_DRAWDIST:
- ProcessSlider((m_PrefsLOD - 0.925f) / 0.875f, 99.0f, HOVEROPTION_INCREASE_DRAWDIST, HOVEROPTION_DECREASE_DRAWDIST, MENU_X_LEFT_ALIGNED(170.0f), SCREEN_WIDTH);
- break;
- case MENUACTION_MUSICVOLUME:
- if(m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER)
- ProcessSlider(m_PrefsMusicVolume / 64.0f, 70.0f, HOVEROPTION_INCREASE_MUSICVOLUME, HOVEROPTION_DECREASE_MUSICVOLUME, MENU_X_LEFT_ALIGNED(170.0f), SCREEN_WIDTH);
- break;
- case MENUACTION_SFXVOLUME:
- if (m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER)
- ProcessSlider(m_PrefsSfxVolume / 64.0f, 99.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, 170.0f, HOVEROPTION_INCREASE_MOUSESENS, HOVEROPTION_DECREASE_MOUSESENS, MENU_X_LEFT_ALIGNED(200.0f), SCREEN_WIDTH);
- break;
+ 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.
@@ -1306,25 +1488,8 @@ CMenuManager::DrawStandardMenus(bool activeScreen)
nextYToUse += MENU_DEFAULT_LINE_HEIGHT * CFont::GetNumberLines(MENU_X_LEFT_ALIGNED(60.0f), MENU_Y(nextYToUse), leftText);
#endif
- nextYToUse = 300.0f; // TODO(Miami): temp
- // Radio icons
if (aScreens[m_nCurrScreen].m_aEntries[i].m_Action == MENUACTION_RADIO) {
-
- // TODO(Miami): Remove those after audio page is done
- ProcessRadioIcon(m_aFrontEndSprites[MENUSPRITE_WILDSTYLE], MENU_X_LEFT_ALIGNED(30.0f), MENU_Y(nextYToUse), 0, HOVEROPTION_RADIO_0);
- ProcessRadioIcon(m_aFrontEndSprites[MENUSPRITE_FLASH], MENU_X_LEFT_ALIGNED(90.0f), MENU_Y(nextYToUse), 1, HOVEROPTION_RADIO_1);
- ProcessRadioIcon(m_aFrontEndSprites[MENUSPRITE_KCHAT], MENU_X_LEFT_ALIGNED(150.0f), MENU_Y(nextYToUse), 2, HOVEROPTION_RADIO_2);
- ProcessRadioIcon(m_aFrontEndSprites[MENUSPRITE_FEVER], MENU_X_LEFT_ALIGNED(210.0f), MENU_Y(nextYToUse), 3, HOVEROPTION_RADIO_3);
- ProcessRadioIcon(m_aFrontEndSprites[MENUSPRITE_VROCK], MENU_X_LEFT_ALIGNED(270.0f), MENU_Y(nextYToUse), 4, HOVEROPTION_RADIO_4);
- ProcessRadioIcon(m_aFrontEndSprites[MENUSPRITE_VCPR], MENU_X_LEFT_ALIGNED(320.0f), MENU_Y(nextYToUse), 5, HOVEROPTION_RADIO_5);
- ProcessRadioIcon(m_aFrontEndSprites[MENUSPRITE_ESPANTOSO], MENU_X_LEFT_ALIGNED(360.0f), MENU_Y(nextYToUse), 6, HOVEROPTION_RADIO_6);
- ProcessRadioIcon(m_aFrontEndSprites[MENUSPRITE_EMOTION], MENU_X_LEFT_ALIGNED(420.0f), MENU_Y(nextYToUse), 7, HOVEROPTION_RADIO_7);
- ProcessRadioIcon(m_aFrontEndSprites[MENUSPRITE_WAVE], MENU_X_LEFT_ALIGNED(480.0f), MENU_Y(nextYToUse), 8, HOVEROPTION_RADIO_8);
-
- if (DMAudio.IsMP3RadioChannelAvailable())
- ProcessRadioIcon(m_aFrontEndSprites[MENUSPRITE_MP3], MENU_X_LEFT_ALIGNED(540.0f), MENU_Y(nextYToUse), 9, HOVEROPTION_RADIO_9);
-
- nextYToUse += 70.0f;
+ nextYToUse += MENURADIO_SELECTOR_HEIGHT + 5.f; // unused
}
}
}
@@ -1332,6 +1497,35 @@ CMenuManager::DrawStandardMenus(bool activeScreen)
section++;
}
+#ifdef SCROLLABLE_PAGES
+ #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 84
+
+ 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(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 - 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)),
+ CRGBA(50, 50, 50, FadeIn(255)));
+
+ // Scrollbar
+ CSprite2d::DrawRect(CRect(MENU_X_RIGHT_ALIGNED(SCROLLBAR_RIGHT_X - 4), scrollbarTop,
+ MENU_X_RIGHT_ALIGNED(SCROLLBAR_RIGHT_X - SCROLLBAR_WIDTH), scrollbarBottom),
+ CRGBA(SCROLLBAR_COLOR.r, SCROLLBAR_COLOR.g, SCROLLBAR_COLOR.b, FadeIn(255)));
+
+ }
+#endif
+
switch (m_nCurrScreen) {
case MENUPAGE_STATS:
case MENUPAGE_CONTROLLER_PC:
@@ -1344,16 +1538,27 @@ CMenuManager::DrawStandardMenus(bool activeScreen)
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(nil);
+ }
+ }
+ break;
+#endif
}
if (m_nCurrScreen == MENUPAGE_DELETING_IN_PROGRESS) {
SmallMessageScreen("FEDL_WR");
- } else if (m_nCurrScreen == MENUPAGE_SAVING_IN_PROGRESS) {
+ }
+#ifndef XBOX_MESSAGE_SCREEN
+ else if (m_nCurrScreen == MENUPAGE_SAVING_IN_PROGRESS) {
SmallMessageScreen("FESZ_WR");
}
+#endif
}
-// --MIAMI: Done
int
CMenuManager::GetNumOptionsCntrlConfigScreens(void)
{
@@ -1387,6 +1592,7 @@ CMenuManager::DrawControllerBound(int32 yStart, int32 xStart, int32 unused, int8
int controllerAction = PED_FIREWEAPON;
// GetStartOptionsCntrlConfigScreens();
int numOptions = GetNumOptionsCntrlConfigScreens();
+ int nextY = MENU_Y(yStart);
int bindingMargin = MENU_X(3.0f);
float rowHeight;
switch (m_ControlMethod) {
@@ -1400,11 +1606,11 @@ CMenuManager::DrawControllerBound(int32 yStart, int32 xStart, int32 unused, int8
break;
}
- // MENU_Y(rowHeight * 0.0f + yStart);
- for (int optionIdx = 0, nextY = MENU_Y(yStart); optionIdx < numOptions; nextY = MENU_Y(++optionIdx * rowHeight + yStart)) {
+ for (int optionIdx = 0; optionIdx < numOptions; nextY = MENU_Y(++optionIdx * rowHeight + yStart)) {
int nextX = xStart;
int bindingsForThisOpt = 0;
- CFont::SetColor(CRGBA(155, 155, 155, FadeIn(255)));
+ int contSetOrder = SETORDER_1;
+ CFont::SetColor(CRGBA(255, 255, 255, FadeIn(255)));
if (column == CONTSETUP_PED_COLUMN) {
switch (optionIdx) {
@@ -1442,10 +1648,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:
@@ -1460,34 +1666,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:
@@ -1509,11 +1721,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:
@@ -1546,32 +1760,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) {
@@ -1580,58 +1793,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(235, 170, 50, FadeIn(150)));
- } else {
- CSprite2d::DrawRect(CRect(nextX, MENU_Y(bgY), nextX + MENU_X(CONTSETUP_BOUND_COLUMN_WIDTH),
- MENU_Y(bgY + CONTSETUP_BOUND_HIGHLIGHT_HEIGHT)), CRGBA(255, 217, 106, FadeIn(210)));
- }
+ 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(235, 170, 50, FadeIn(150)));
- } 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(255, 217, 106, FadeIn(210)));
- }
+ 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(235, 170, 50, FadeIn(150)));
- } else {
- CSprite2d::DrawRect(CRect(nextX, MENU_Y(bgY), nextX + MENU_X(CONTSETUP_BOUND_COLUMN_WIDTH),
- MENU_Y(bgY + CONTSETUP_BOUND_HIGHLIGHT_HEIGHT)), CRGBA(255, 217, 106, FadeIn(210)));
- }
+ 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(235, 170, 50, FadeIn(150)));
- } else {
- CSprite2d::DrawRect(CRect(MENU_X_LEFT_ALIGNED(410.0f), MENU_Y(bgY), MENU_X_LEFT_ALIGNED(600.0f), MENU_Y(bgY + 10)), CRGBA(255, 217, 106, FadeIn(210)));
- }
+ 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(0.6f));
- for (int contSetOrder = SETORDER_1; contSetOrder < MAX_SETORDERS && controllerAction != -1; contSetOrder++) {
+ 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);
@@ -1644,23 +1837,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
}
@@ -1684,51 +1881,32 @@ CMenuManager::DrawControllerBound(int32 yStart, int32 xStart, int32 unused, int8
lastWaitingTextFlash = CTimer::GetTimeInMillisecondsPauseMode();
}
if (showWaitingText) {
- CFont::SetColor(CRGBA(55, 55, 55, FadeIn(255)));
+ CFont::SetColor(CRGBA(255, 255, 255, FadeIn(255)));
CFont::PrintString(nextX, nextY, TheText.Get("FEC_QUE")); // "???"
}
- CFont::SetCentreOn();
- CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE), MENU_Y(SMALLESTTEXT_Y_SCALE));
- CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING));
- 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
- }
-
- CFont::SetRightJustifyOff();
- CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE), MENU_Y(SMALLESTTEXT_Y_SCALE));
- CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD));
+ if (m_bKeyChangeNotProcessed)
+ DisplayHelperText("FET_CIG");
+ else
+ DisplayHelperText("FET_RIG");
+
+ SET_FONT_FOR_LIST_ITEM
m_bKeyIsOK = true;
} else {
- CFont::SetCentreOn();
- CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE), MENU_Y(SMALLESTTEXT_Y_SCALE));
- CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING));
- 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
- CFont::SetRightJustifyOff();
- CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE), MENU_Y(SMALLESTTEXT_Y_SCALE));
- CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD));
+ DisplayHelperText("FET_CIG");
+ SET_FONT_FOR_LIST_ITEM
+
m_bKeyIsOK = false;
m_bKeyChangeNotProcessed = false;
}
} else if (optionIdx == m_nSelectedListRow) {
- CFont::SetCentreOn();
- CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE), MENU_Y(SMALLESTTEXT_Y_SCALE));
- CFont::SetFontStyle(FONT_LOCALE(FONT_HEADING));
- 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
- CFont::SetRightJustifyOff();
- CFont::SetScale(MENU_X(SMALLESTTEXT_X_SCALE), MENU_Y(SMALLESTTEXT_Y_SCALE));
- CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD));
+ DisplayHelperText("FET_EIG");
+ SET_FONT_FOR_LIST_ITEM
}
}
}
}
-// --MIAMI: Done
void
CMenuManager::DrawControllerScreenExtraText(int yStart, int xStart, int lineHeight)
{
@@ -1799,39 +1977,25 @@ CMenuManager::DrawControllerSetupScreen()
default:
break;
}
- CFont::SetBackgroundOff();
- CFont::SetScale(MENU_X(MENUACTION_SCALE_MULT), MENU_Y(MENUACTION_SCALE_MULT));
- CFont::SetPropOn();
- CFont::SetCentreOff();
- CFont::SetJustifyOn();
- CFont::SetRightJustifyOff();
- CFont::SetBackGroundOnlyTextOn();
- CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENU_UNK_X_MARGIN));
- CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(MENU_UNK_X_MARGIN));
- PREPARE_MENU_HEADER
+ RESET_FONT_FOR_NEW_PAGE
+ SET_FONT_FOR_MENU_HEADER
- switch (m_ControlMethod) {
- case CONTROL_STANDARD:
- 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_STI"));
+ // Shadow
+ CFont::SetColor(CRGBA(30, 30, 30, FadeIn(255)));
- 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_STI"));
- break;
- case CONTROL_CLASSIC:
- 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_CTI"));
+ 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"));
- 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_CTI"));
- break;
- default:
- break;
- }
wchar *actionTexts[33];
actionTexts[0] = TheText.Get("FEC_FIR");
actionTexts[1] = TheText.Get("FEC_NWE");
@@ -1878,43 +2042,44 @@ CMenuManager::DrawControllerSetupScreen()
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(200, 200, 50, FadeIn(50)));
+ CRGBA(LIST_BACKGROUND_COLOR.r, LIST_BACKGROUND_COLOR.g, LIST_BACKGROUND_COLOR.b, FadeIn(LIST_BACKGROUND_COLOR.a)));
if (m_nCurrExLayer == HOVEROPTION_LIST)
- CFont::SetColor(CRGBA(255, 217, 106, FadeIn(255)));
+ CFont::SetColor(CRGBA(SELECTEDMENUOPTION_COLOR.r, SELECTEDMENUOPTION_COLOR.g, SELECTEDMENUOPTION_COLOR.b, FadeIn(255)));
else
- CFont::SetColor(CRGBA(235, 170, 50, FadeIn(255)));
+ CFont::SetColor(CRGBA(MENUOPTION_COLOR.r, MENUOPTION_COLOR.g, MENUOPTION_COLOR.b, FadeIn(255)));
// List header
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::SetRightJustifyOff();
- CFont::SetScale(MENU_X_LEFT_ALIGNED(SMALLESTTEXT_X_SCALE), MENU_Y(SMALLESTTEXT_Y_SCALE));
- CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD));
+ CFont::SetDropShadowPosition(0);
+ SET_FONT_FOR_LIST_ITEM
+
int yStart;
if (m_ControlMethod == CONTROL_CLASSIC)
- yStart = CONTSETUP_LIST_HEADER_HEIGHT + 29;
+ yStart = CONTSETUP_LIST_TOP + 18;
else
- yStart = CONTSETUP_LIST_HEADER_HEIGHT + 34;
+ yStart = CONTSETUP_LIST_TOP + 21;
+ float optionYBottom = yStart + rowHeight;
for (int i = 0; i < ARRAY_SIZE(actionTexts); ++i) {
wchar *actionText = actionTexts[i];
if (!actionText)
break;
if (!m_bWaitingForNewKeyBind) {
- if (m_nMousePosX > MENU_X_LEFT_ALIGNED(CONTSETUP_LIST_LEFT + 2.0f) &&
+ 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)) {
- float curOptY = i * rowHeight + yStart;
- if (m_nMousePosY > MENU_Y(curOptY) && m_nMousePosY < MENU_Y(rowHeight + curOptY)) {
+ 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;
@@ -1954,10 +2119,10 @@ 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(SMALLESTTEXT_X_SCALE), 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(0.32f), 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);
}
@@ -1965,15 +2130,15 @@ CMenuManager::DrawControllerSetupScreen()
DrawControllerBound(yStart, MENU_X_LEFT_ALIGNED(CONTSETUP_COLUMN_3_X), rowHeight, CONTSETUP_VEHICLE_COLUMN);
if (!m_bWaitingForNewKeyBind) {
- 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));
if ((m_nMousePosX > MENU_X_RIGHT_ALIGNED(CONTSETUP_BACK_RIGHT) - CFont::GetStringWidth(TheText.Get("FEDS_TB"), true)
&& m_nMousePosX < MENU_X_RIGHT_ALIGNED(CONTSETUP_BACK_RIGHT) && m_nMousePosY > SCREEN_SCALE_FROM_BOTTOM(CONTSETUP_BACK_BOTTOM)
&& m_nMousePosY < SCREEN_SCALE_FROM_BOTTOM(CONTSETUP_BACK_BOTTOM - CONTSETUP_BACK_HEIGHT)) || m_nCurrExLayer == HOVEROPTION_BACK) {
m_nHoverOption = HOVEROPTION_BACK;
- } else if (m_nMousePosX > MENU_X_LEFT_ALIGNED(CONTSETUP_LIST_LEFT + 2.0f) && m_nMousePosX < MENU_X_LEFT_ALIGNED(CONTSETUP_COLUMN_3_X + CONTSETUP_BOUND_COLUMN_WIDTH)
- && m_nMousePosY > MENU_Y(CONTSETUP_LIST_TOP + CONTSETUP_LIST_HEADER_HEIGHT) && m_nMousePosY < SCREEN_SCALE_FROM_BOTTOM(CONTSETUP_LIST_BOTTOM + 5.0f)) {
+ } 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 {
@@ -1983,18 +2148,12 @@ CMenuManager::DrawControllerSetupScreen()
// 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(255, 217, 106, FadeIn(255)));
- else
- CFont::SetColor(CRGBA(235, 170, 50, 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
@@ -2012,18 +2171,18 @@ CMenuManager::DrawFrontEnd()
} else {
m_nCurrScreen = MENUPAGE_PAUSE_MENU;
}
+ SETUP_SCROLLING(m_nCurrScreen)
}
if (m_nCurrOption == 0 && aScreens[m_nCurrScreen].m_aEntries[0].m_Action == MENUACTION_LABEL)
m_nCurrOption = 1;
- if (m_menuTransitionProgress == 255 && m_nMenuFadeAlpha == 255)
+ if (m_firstStartCounter == 255 && m_nMenuFadeAlpha == 255)
bMenuChangeOngoing = false;
DrawBackground(false);
}
-// --MIAMI: Done except commented things
void
CMenuManager::DrawBackground(bool transitionCall)
{
@@ -2032,7 +2191,7 @@ CMenuManager::DrawBackground(bool transitionCall)
SetFrontEndRenderStates();
- if (m_menuTransitionProgress < 255) {
+ if (m_firstStartCounter < 255) {
CSprite2d::DrawRect(CRect(0.0f, 0.0f, SCREEN_WIDTH, SCREEN_HEIGHT), CRGBA(0, 0, 0, 255));
}
@@ -2063,7 +2222,7 @@ CMenuManager::DrawBackground(bool transitionCall)
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_menuTransitionProgress = 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();
@@ -2135,6 +2294,20 @@ CMenuManager::DrawBackground(bool transitionCall)
menuBg.bottomRight_y = 398.0f;
break;
default:
+#ifdef CUSTOM_FRONTEND_OPTIONS
+ 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;
+ }
+#endif
menuBg.topLeft_x = CGeneral::GetRandomNumber() % 40 + 65;
menuBg.topLeft_y = CGeneral::GetRandomNumber() % 40 + 21;
menuBg.topRight_x = CGeneral::GetRandomNumber() % 40 + 568;
@@ -2147,30 +2320,30 @@ CMenuManager::DrawBackground(bool transitionCall)
}
menuBg.UpdateMultipliers();
- if (m_menuTransitionProgress == 255)
+ if (m_firstStartCounter == 255)
m_nOptionHighlightTransitionBlend = 0;
}
static PauseModeTime LastFade = 0;
- static uint8 forceFadeInCounter = 0;
- if (m_nMenuFadeAlpha >= 255) {
- if (m_nMenuFadeAlpha > 255)
- m_nMenuFadeAlpha = 255;
- } else {
+ 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;
- m_menuTransitionProgress = Min(m_menuTransitionProgress + 20, 255);
+ if (m_firstStartCounter < 255) {
+ m_firstStartCounter = Min(m_firstStartCounter + 20, 255);
+ }
LastFade = CTimer::GetTimeInMillisecondsPauseMode();
}
forceFadeInCounter++;
- }
+ } else if (m_nMenuFadeAlpha > 255)
+ m_nMenuFadeAlpha = 255;
- if (!transitionCall && m_menuTransitionProgress == 255) {
+ if (!transitionCall && m_firstStartCounter == 255) {
int actualAlpha = m_nMenuFadeAlpha;
if (actualAlpha < 255) {
int actualScreen = m_nCurrScreen;
@@ -2204,7 +2377,7 @@ CMenuManager::DrawBackground(bool transitionCall)
DrawControllerSetupScreen();
break;
case MENUPAGE_OUTRO:
- CMenuManager::DrawQuitGameScreen();
+ DrawQuitGameScreen();
break;
default:
DrawStandardMenus(true);
@@ -2215,7 +2388,7 @@ CMenuManager::DrawBackground(bool transitionCall)
SetFrontEndRenderStates();
if (m_nCurrScreen != MENUPAGE_OUTRO)
- if (m_menuTransitionProgress == 255) {
+ 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)));
@@ -2237,8 +2410,8 @@ CMenuManager::DrawBackground(bool transitionCall)
}
if (m_bShowMouse) {
- CRect mouse(0.0f, 0.0f, MENU_X(40.0f), MENU_Y(40.0f));
- CRect shad(MENU_X(10.0f), MENU_Y(3.0f), MENU_X(55.0f), MENU_Y(43.0f));
+ 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);
@@ -2247,19 +2420,10 @@ CMenuManager::DrawBackground(bool transitionCall)
}
}
-// --MIAMI: Done
void
CMenuManager::DrawPlayerSetupScreen(bool activeScreen)
{
- CFont::SetBackgroundOff();
- CFont::SetScale(MENU_X(MENUACTION_SCALE_MULT), MENU_Y(MENUACTION_SCALE_MULT));
- CFont::SetPropOn();
- CFont::SetCentreOff();
- CFont::SetJustifyOn();
- CFont::SetRightJustifyOff();
- CFont::SetBackGroundOnlyTextOn();
- CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENU_UNK_X_MARGIN));
- CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(MENU_UNK_X_MARGIN));
+ RESET_FONT_FOR_NEW_PAGE
// lstrcpy's changed with strcpy
if (!m_bSkinsEnumerated) {
@@ -2278,7 +2442,7 @@ CMenuManager::DrawPlayerSetupScreen(bool activeScreen)
SYSTEMTIME SystemTime;
HANDLE handle = FindFirstFile("skins\\*.bmp", &FindFileData);
for (int i = 1; handle != INVALID_HANDLE_VALUE && i; i = FindNextFile(handle, &FindFileData)) {
- if (strncmp(FindFileData.cFileName, DEFAULT_SKIN_NAME, 5) != 0) {
+ if (strcmp(FindFileData.cFileName, DEFAULT_SKIN_NAME) != 0) {
m_pSelectedSkin->nextSkin = new tSkinInfo;
m_pSelectedSkin = m_pSelectedSkin->nextSkin;
m_pSelectedSkin->skinId = nextSkinId;
@@ -2325,7 +2489,7 @@ CMenuManager::DrawPlayerSetupScreen(bool activeScreen)
strncpy(&m_pSelectedSkin->skinNameDisplayed[k], "(", 1);
if (!strncmp(&m_pSelectedSkin->skinNameDisplayed[k], "}", 1))
strncpy(&m_pSelectedSkin->skinNameDisplayed[k], ")", 1);
- if (!strncmp(&m_pSelectedSkin->skinNameDisplayed[k], "�", 1))
+ if (!strncmp(&m_pSelectedSkin->skinNameDisplayed[k], "£", 1))
strncpy(&m_pSelectedSkin->skinNameDisplayed[k], "$", 1);
}
@@ -2344,9 +2508,9 @@ CMenuManager::DrawPlayerSetupScreen(bool activeScreen)
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(49, 101, 148, FadeIn(130)));
+ 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)));
- PREPARE_MENU_HEADER
+ 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"));
@@ -2378,9 +2542,7 @@ CMenuManager::DrawPlayerSetupScreen(bool activeScreen)
CFont::SetDropShadowPosition(0);
// Skin list
- CFont::SetRightJustifyOff();
- CFont::SetScale(MENU_X(PLAYERSETUP_ROW_TEXT_X_SCALE), MENU_Y(PLAYERSETUP_ROW_TEXT_Y_SCALE));
- CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD));
+ SET_FONT_FOR_LIST_ITEM
if (m_nSkinsTotal > 0) {
for (m_pSelectedSkin = m_pSkinListHead.nextSkin; m_pSelectedSkin->skinId != m_nFirstVisibleRowOnList;
m_pSelectedSkin = m_pSelectedSkin->nextSkin);
@@ -2427,7 +2589,7 @@ CMenuManager::DrawPlayerSetupScreen(bool activeScreen)
} else if (!strcmp(m_PrefsSkinFile, m_pSelectedSkin->skinNameOriginal)) {
CFont::SetColor(CRGBA(255, 255, 155, FadeIn(255)));
} else {
- CFont::SetColor(CRGBA(155, 155, 155, FadeIn(255)));
+ CFont::SetColor(CRGBA(LIST_OPTION_COLOR.r, LIST_OPTION_COLOR.g, LIST_OPTION_COLOR.b, FadeIn(LIST_OPTION_COLOR.a)));
}
wchar unicodeTemp[80];
AsciiToUnicode(m_pSelectedSkin->skinNameDisplayed, unicodeTemp);
@@ -2449,18 +2611,17 @@ CMenuManager::DrawPlayerSetupScreen(bool activeScreen)
++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)));
- // Scrollbar
- float scrollbarHeight = SCROLLBAR_MAX_HEIGHT / m_nSkinsTotal * (float) MAX_VISIBLE_LIST_ROW;
+ float scrollbarHeight = SCROLLBAR_MAX_HEIGHT / (m_nSkinsTotal / (float) MAX_VISIBLE_LIST_ROW);
float scrollbarBottom, scrollbarTop;
if (m_nSkinsTotal <= MAX_VISIBLE_LIST_ROW) {
scrollbarBottom = SCREEN_SCALE_FROM_BOTTOM(PLAYERSETUP_LIST_BOTTOM + PLAYERSETUP_SCROLLBUTTON_HEIGHT + 4.0f);
scrollbarTop = MENU_Y(PLAYERSETUP_LIST_BODY_TOP);
- // Shadow
+ // Scrollbar shadow
CSprite2d::DrawRect(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 4), scrollbarTop,
MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 1 - PLAYERSETUP_SCROLLBAR_WIDTH), scrollbarBottom + MENU_Y(1.0f)), CRGBA(50, 50, 50, FadeIn(255)));
} else {
@@ -2471,15 +2632,16 @@ CMenuManager::DrawPlayerSetupScreen(bool activeScreen)
scrollbarBottom = MENU_Y(PLAYERSETUP_LIST_BODY_TOP - 4 + m_nScrollbarTopMargin + scrollbarHeight - SCROLLBAR_MAX_HEIGHT / m_nSkinsTotal);
scrollbarTop = MENU_Y(SCROLLBAR_MAX_HEIGHT / m_nSkinsTotal + PLAYERSETUP_LIST_BODY_TOP - 3 + m_nScrollbarTopMargin);
#endif
- // Shadow
+ // Scrollbar shadow
CSprite2d::DrawRect(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 4), scrollbarTop,
MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 1 - PLAYERSETUP_SCROLLBAR_WIDTH), scrollbarBottom + MENU_Y(1.0f)),
CRGBA(50, 50, 50, FadeIn(255)));
}
+ // Scrollbar
CSprite2d::DrawRect(CRect(MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - 4), scrollbarTop,
MENU_X_RIGHT_ALIGNED(PLAYERSETUP_LIST_RIGHT - PLAYERSETUP_SCROLLBAR_WIDTH), scrollbarBottom),
- CRGBA(255, 150, 225, FadeIn(255)));
+ CRGBA(SCROLLBAR_COLOR.r, SCROLLBAR_COLOR.g, SCROLLBAR_COLOR.b, FadeIn(255)));
// FIX: Scroll button dimensions are buggy, because:
// 1 - stretches the original image
@@ -2647,32 +2809,12 @@ CMenuManager::DrawPlayerSetupScreen(bool activeScreen)
CFont::SetDropShadowPosition(0);
}
-// --MIAMI: Done
int
CMenuManager::FadeIn(int alpha)
{
return Min(m_nMenuFadeAlpha, alpha);
}
-void
-CMenuManager::FilterOutColorMarkersFromString(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';
-}
-
-// --MIAMI: Done
int
CMenuManager::GetStartOptionsCntrlConfigScreens()
{
@@ -2753,7 +2895,8 @@ CMenuManager::LoadAllTextures()
if (m_bSpritesLoaded)
return;
- field_F0 = SCREEN_STRETCH_X(178.0f); // TODO(Miami)
+ // 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
@@ -2806,7 +2949,6 @@ CMenuManager::LoadAllTextures()
CTimer::Update();
}
-// --MIAMI: Done
void
CMenuManager::LoadSettings()
{
@@ -2855,12 +2997,7 @@ CMenuManager::LoadSettings()
CFileMgr::Read(fileHandle, gString, 20);
CFileMgr::Read(fileHandle, gString, 4);
CFileMgr::Read(fileHandle, gString, 4);
-#ifdef FREE_CAM
- CFileMgr::Read(fileHandle, (char*)&TheCamera.bFreeCam, 1);
-#else
CFileMgr::Read(fileHandle, gString, 1);
-#endif
-
#ifdef LEGACY_MENU_OPTIONS
CFileMgr::Read(fileHandle, (char*)&m_PrefsVsyncDisp, 1);
CFileMgr::Read(fileHandle, (char*)&CMBlur::BlurOn, 1);
@@ -2891,16 +3028,18 @@ CMenuManager::LoadSettings()
CFileMgr::Read(fileHandle, (char*)&m_PrefsShowHud, 1);
CFileMgr::Read(fileHandle, (char*)&m_PrefsRadarMode, 1);
CFileMgr::Read(fileHandle, (char*)&m_PrefsShowLegends, 1);
-#ifdef CUTSCENE_BORDERS_SWITCH
- CFileMgr::Read(fileHandle, (char *)&CMenuManager::m_PrefsCutsceneBorders, 1);
-#endif
}
}
CFileMgr::CloseFile(fileHandle);
CFileMgr::SetDir("");
+#ifdef FIX_BUGS
+ TheCamera.m_fMouseAccelVertical = TheCamera.m_fMouseAccelHorzntl + 0.0005f;
+#endif
+#ifdef PC_PLAYER_CONTROLS
CCamera::m_bUseMouse3rdPerson = m_ControlMethod == CONTROL_STANDARD;
+#endif
#ifdef LEGACY_MENU_OPTIONS
m_PrefsVsync = m_PrefsVsyncDisp;
#endif
@@ -2940,9 +3079,12 @@ CMenuManager::LoadSettings()
strcpy(m_PrefsSkinFile, DEFAULT_SKIN_NAME);
strcpy(m_aSkinName, DEFAULT_SKIN_NAME);
}
+
+#ifdef LOAD_INI_SETTINGS
+ LoadINISettings(); // needs frontend options to be loaded
+#endif
}
-// --MIAMI: Done
void
CMenuManager::SaveSettings()
{
@@ -2967,12 +3109,7 @@ CMenuManager::SaveSettings()
CFileMgr::Write(fileHandle, RubbishString, 20);
CFileMgr::Write(fileHandle, RubbishString, 4);
CFileMgr::Write(fileHandle, RubbishString, 4);
-#ifdef FREE_CAM
- CFileMgr::Write(fileHandle, (char*)&TheCamera.bFreeCam, 1);
-#else
CFileMgr::Write(fileHandle, RubbishString, 1);
-#endif
-
#ifdef LEGACY_MENU_OPTIONS
CFileMgr::Write(fileHandle, (char*)&m_PrefsVsyncDisp, 1);
CFileMgr::Write(fileHandle, (char*)&CMBlur::BlurOn, 1);
@@ -3003,14 +3140,15 @@ CMenuManager::SaveSettings()
CFileMgr::Write(fileHandle, (char*)&m_PrefsShowHud, 1);
CFileMgr::Write(fileHandle, (char*)&m_PrefsRadarMode, 1);
CFileMgr::Write(fileHandle, (char*)&m_PrefsShowLegends, 1);
-#ifdef CUTSCENE_BORDERS_SWITCH
- CFileMgr::Write(fileHandle, (char *)&CMenuManager::m_PrefsCutsceneBorders, 1);
-#endif
}
m_lastWorking3DAudioProvider = m_nPrefsAudio3DProviderIndex;
CFileMgr::CloseFile(fileHandle);
CFileMgr::SetDir("");
+
+#ifdef LOAD_INI_SETTINGS
+ SaveINISettings();
+#endif
}
void
@@ -3035,7 +3173,6 @@ CMenuManager::MessageScreen(const char *text, bool blackBg)
DoRWStuffEndOfFrame();
}
-// --MIAMI: Done
void
CMenuManager::SmallMessageScreen(const char* text)
{
@@ -3062,7 +3199,6 @@ CMenuManager::SmallMessageScreen(const char* text)
CFont::PrintString(SCREEN_WIDTH / 2.f, y, TheText.Get(text));
}
-// --MIAMI: Done, but FilterOutColorMarkersFromString is actually in CFont
void
CMenuManager::PrintBriefs()
{
@@ -3086,7 +3222,7 @@ CMenuManager::PrintBriefs()
brief.m_nNumber[4], brief.m_nNumber[5], gUString);
CMessages::InsertStringInString(gUString, brief.m_pString);
CMessages::InsertPlayerControlKeysInString(gUString);
- FilterOutColorMarkersFromString(gUString);
+ CFont::FilterOutTokensFromString(gUString);
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);
@@ -3094,18 +3230,17 @@ CMenuManager::PrintBriefs()
}
}
-// --MIAMI: Done
void
CMenuManager::PrintStats()
{
static uint8 pirateCheck = 0;
static float scrollY = 0;
- int rowNum = ConstructStatLine(99999);
+ 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(130)));
+ 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();
@@ -3155,7 +3290,7 @@ CMenuManager::PrintStats()
// If it's still on screen
if (y > MENU_Y(STATS_VISIBLE_START_Y) && y < MENU_Y(STATS_VISIBLE_END_Y)) {
- ConstructStatLine(row);
+ CStats::ConstructStatLine(row);
// But about to dim from bottom
if (y < MENU_Y(STATS_BOTTOM_Y)) {
@@ -3200,17 +3335,24 @@ CMenuManager::PrintStats()
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);
}
-// --MIAMI: Done
void
CMenuManager::Process(void)
{
+#ifdef XBOX_MESSAGE_SCREEN
+ ProcessDialogTimer();
+#endif
+
if (TheCamera.GetScreenFadeStatus() != FADE_0)
return;
@@ -3228,6 +3370,535 @@ CMenuManager::Process(void)
SwitchMenuOnAndOff();
}
+#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)
+
+#endif
+
+// Handles Map, Audio and Stats
+void
+CMenuManager::AdditionalOptionInput(bool &goBack)
+{
+ switch (m_nCurrScreen) {
+ case MENUPAGE_MAP:
+ {
+ static PauseModeTime lastMapTick = 0;
+
+ // FIX: All those macros were hardcoded values originally.
+
+#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 (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
+
+ {
+ // 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
+
+ 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;
+
+ 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 (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;
+ }
+ }
+}
+
+// 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)));
+
+ 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 {
+ m_aFrontEndSprites[m_PrefsRadioStation + MENUSPRITE_WILDSTYLE - 1].Draw(m_LeftMostRadioX + MENU_X(MENURADIO_ICON_SIZE), MENU_Y(MENURADIO_ICON_Y), MENU_X(MENURADIO_ICON_SIZE),
+ MENU_Y(MENURADIO_ICON_SIZE), CRGBA(INACTIVE_RADIO_COLOR.r, INACTIVE_RADIO_COLOR.g, INACTIVE_RADIO_COLOR.b, FadeIn(INACTIVE_RADIO_COLOR.a)));
+ }
+
+ // Third (middle)
+ int prevStation = m_PrefsRadioStation - 1;
+ if (prevStation == rightMostStation) {
+ m_aFrontEndSprites[MENUSPRITE_WILDSTYLE + 1].Draw(m_LeftMostRadioX + MENU_X(MENURADIO_ICON_SIZE * 3), MENU_Y(MENURADIO_ICON_Y), MENU_X(MENURADIO_ICON_SIZE), MENU_Y(MENURADIO_ICON_SIZE),
+ CRGBA(INACTIVE_RADIO_COLOR.r, INACTIVE_RADIO_COLOR.g, INACTIVE_RADIO_COLOR.b, FadeIn(INACTIVE_RADIO_COLOR.a)));
+ } else if ( prevStation == rightMostStation - 1) {
+ m_aFrontEndSprites[MENUSPRITE_WILDSTYLE].Draw(m_LeftMostRadioX + MENU_X(MENURADIO_ICON_SIZE * 3), MENU_Y(MENURADIO_ICON_Y), MENU_X(MENURADIO_ICON_SIZE), MENU_Y(MENURADIO_ICON_SIZE),
+ CRGBA(INACTIVE_RADIO_COLOR.r, INACTIVE_RADIO_COLOR.g, INACTIVE_RADIO_COLOR.b, FadeIn(INACTIVE_RADIO_COLOR.a)));
+ } else {
+ m_aFrontEndSprites[m_PrefsRadioStation + MENUSPRITE_WILDSTYLE + 1].Draw(m_LeftMostRadioX + MENU_X(MENURADIO_ICON_SIZE * 3), MENU_Y(MENURADIO_ICON_Y), MENU_X(MENURADIO_ICON_SIZE), MENU_Y(MENURADIO_ICON_SIZE),
+ CRGBA(INACTIVE_RADIO_COLOR.r, INACTIVE_RADIO_COLOR.g, INACTIVE_RADIO_COLOR.b, FadeIn(INACTIVE_RADIO_COLOR.a)));
+ }
+
+ // Fifth
+ if (m_ScrollRadioBy == -1) {
+ int prevStation = m_PrefsRadioStation - 1;
+ if (prevStation == rightMostStation) {
+ m_aFrontEndSprites[MENUSPRITE_WILDSTYLE + 4].Draw(m_LeftMostRadioX + MENU_X(MENURADIO_ICON_SIZE * 4), MENU_Y(MENURADIO_ICON_Y), MENU_X(MENURADIO_ICON_SIZE), MENU_Y(MENURADIO_ICON_SIZE),
+ CRGBA(INACTIVE_RADIO_COLOR.r, INACTIVE_RADIO_COLOR.g, INACTIVE_RADIO_COLOR.b, FadeIn(INACTIVE_RADIO_COLOR.a)));
+ } else if (prevStation == rightMostStation - 1) {
+ m_aFrontEndSprites[MENUSPRITE_WILDSTYLE + 1].Draw(m_LeftMostRadioX + MENU_X(MENURADIO_ICON_SIZE * 4), MENU_Y(MENURADIO_ICON_Y), MENU_X(MENURADIO_ICON_SIZE), MENU_Y(MENURADIO_ICON_SIZE),
+ CRGBA(INACTIVE_RADIO_COLOR.r, INACTIVE_RADIO_COLOR.g, INACTIVE_RADIO_COLOR.b, FadeIn(INACTIVE_RADIO_COLOR.a)));
+ } else if ( prevStation == rightMostStation - 2) {
+ m_aFrontEndSprites[MENUSPRITE_WILDSTYLE].Draw(m_LeftMostRadioX + MENU_X(MENURADIO_ICON_SIZE * 4), MENU_Y(MENURADIO_ICON_Y), MENU_X(MENURADIO_ICON_SIZE), MENU_Y(MENURADIO_ICON_SIZE),
+ CRGBA(INACTIVE_RADIO_COLOR.r, INACTIVE_RADIO_COLOR.g, INACTIVE_RADIO_COLOR.b, FadeIn(INACTIVE_RADIO_COLOR.a)));
+ } else {
+ m_aFrontEndSprites[m_PrefsRadioStation + MENUSPRITE_WILDSTYLE + 2].Draw(m_LeftMostRadioX + MENU_X(MENURADIO_ICON_SIZE * 4), MENU_Y(MENURADIO_ICON_Y), MENU_X(MENURADIO_ICON_SIZE), MENU_Y(MENURADIO_ICON_SIZE),
+ CRGBA(INACTIVE_RADIO_COLOR.r, INACTIVE_RADIO_COLOR.g, INACTIVE_RADIO_COLOR.b, FadeIn(INACTIVE_RADIO_COLOR.a)));
+ }
+ }
+
+ // Fourth
+ if (m_ScrollRadioBy == 0) {
+ m_aFrontEndSprites[m_PrefsRadioStation + MENUSPRITE_WILDSTYLE].Draw(m_LeftMostRadioX + MENU_X(MENURADIO_ICON_SIZE * 2 - 10.f), MENU_Y(MENURADIO_ICON_Y - 10.f), MENU_X(MENURADIO_ICON_SIZE) + MENU_X(20.f), MENU_Y(MENURADIO_ICON_SIZE) + MENU_Y(20.f),
+ CRGBA(255, 255, 255, FadeIn(255)));
+ } else {
+ if (m_PrefsRadioStation - 1 == rightMostStation) {
+ m_aFrontEndSprites[MENUSPRITE_WILDSTYLE].Draw(m_LeftMostRadioX + MENU_X(MENURADIO_ICON_SIZE * 2), MENU_Y(MENURADIO_ICON_Y), MENU_X(MENURADIO_ICON_SIZE), MENU_Y(MENURADIO_ICON_SIZE),
+ CRGBA(INACTIVE_RADIO_COLOR.r, INACTIVE_RADIO_COLOR.g, INACTIVE_RADIO_COLOR.b, FadeIn(INACTIVE_RADIO_COLOR.a)));
+ } else {
+ m_aFrontEndSprites[m_PrefsRadioStation + MENUSPRITE_WILDSTYLE].Draw(m_LeftMostRadioX + MENU_X(MENURADIO_ICON_SIZE * 2), MENU_Y(MENURADIO_ICON_Y), MENU_X(MENURADIO_ICON_SIZE), MENU_Y(MENURADIO_ICON_SIZE),
+ CRGBA(INACTIVE_RADIO_COLOR.r, INACTIVE_RADIO_COLOR.g, INACTIVE_RADIO_COLOR.b, FadeIn(INACTIVE_RADIO_COLOR.a)));
+ }
+ }
+#else
+ int first = ((m_PrefsRadioStation - 2) + rightMostStation + 1) % (rightMostStation + 1);
+ int second = ((m_PrefsRadioStation - 1) + rightMostStation + 1) % (rightMostStation + 1);
+ int third = ((m_PrefsRadioStation) + rightMostStation + 1) % (rightMostStation + 1);
+ int fourth = ((m_PrefsRadioStation + 1) + rightMostStation + 1) % (rightMostStation + 1);
+ int fifth = ((m_PrefsRadioStation + 2) + rightMostStation + 1) % (rightMostStation + 1);
+
+ // First one is only drawn on transition to next
+ if (m_ScrollRadioBy == 1) {
+ m_aFrontEndSprites[first + MENUSPRITE_WILDSTYLE].Draw(m_LeftMostRadioX, MENU_Y(MENURADIO_ICON_Y), MENU_X(MENURADIO_ICON_SIZE), MENU_Y(MENURADIO_ICON_SIZE),
+ CRGBA(INACTIVE_RADIO_COLOR.r, INACTIVE_RADIO_COLOR.g, INACTIVE_RADIO_COLOR.b, FadeIn(INACTIVE_RADIO_COLOR.a)));
+ }
+
+ // Second
+ m_aFrontEndSprites[second + MENUSPRITE_WILDSTYLE].Draw(m_LeftMostRadioX + MENU_X(MENURADIO_ICON_SIZE), MENU_Y(MENURADIO_ICON_Y), MENU_X(MENURADIO_ICON_SIZE), MENU_Y(MENURADIO_ICON_SIZE),
+ CRGBA(INACTIVE_RADIO_COLOR.r, INACTIVE_RADIO_COLOR.g, INACTIVE_RADIO_COLOR.b, FadeIn(INACTIVE_RADIO_COLOR.a)));
+
+ // Fourth
+ m_aFrontEndSprites[fourth + MENUSPRITE_WILDSTYLE].Draw(m_LeftMostRadioX + MENU_X(MENURADIO_ICON_SIZE * 3), MENU_Y(MENURADIO_ICON_Y), MENU_X(MENURADIO_ICON_SIZE), MENU_Y(MENURADIO_ICON_SIZE),
+ CRGBA(INACTIVE_RADIO_COLOR.r, INACTIVE_RADIO_COLOR.g, INACTIVE_RADIO_COLOR.b, FadeIn(INACTIVE_RADIO_COLOR.a)));
+
+ // Fifth one is only drawn on transition to prev.
+ if (m_ScrollRadioBy == -1) {
+ m_aFrontEndSprites[fifth + MENUSPRITE_WILDSTYLE].Draw(m_LeftMostRadioX + MENU_X(MENURADIO_ICON_SIZE * 4), MENU_Y(MENURADIO_ICON_Y), MENU_X(MENURADIO_ICON_SIZE), MENU_Y(MENURADIO_ICON_SIZE),
+ CRGBA(INACTIVE_RADIO_COLOR.r, INACTIVE_RADIO_COLOR.g, INACTIVE_RADIO_COLOR.b, FadeIn(INACTIVE_RADIO_COLOR.a)));
+ }
+
+ // 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::ProcessList(bool &optionSelected, bool &goBack)
@@ -3239,7 +3910,8 @@ CMenuManager::ProcessList(bool &optionSelected, bool &goBack)
m_nTotalListRow = m_nSkinsTotal;
}
if (m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS) {
- m_nTotalListRow = m_ControlMethod == CONTROL_CLASSIC ? 30 : 25;
+ // 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;
}
@@ -3366,7 +4038,7 @@ CMenuManager::ProcessList(bool &optionSelected, bool &goBack)
m_nCurrExLayer = HOVEROPTION_LIST;
m_bShowMouse = false;
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_HIGHLIGHT_OPTION, 0);
- if (m_nTotalListRow >= MAX_VISIBLE_LIST_ROW) {
+ if (m_nTotalListRow >= MAX_VISIBLE_OPTION_ON_SCREEN) {
m_nFirstVisibleRowOnList = 0;
}
m_nSelectedListRow = 0;
@@ -3376,8 +4048,8 @@ CMenuManager::ProcessList(bool &optionSelected, bool &goBack)
m_nCurrExLayer = HOVEROPTION_LIST;
m_bShowMouse = false;
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_HIGHLIGHT_OPTION, 0);
- if (m_nTotalListRow >= MAX_VISIBLE_LIST_ROW) {
- m_nFirstVisibleRowOnList = m_nTotalListRow - MAX_VISIBLE_LIST_ROW;
+ 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;
@@ -3467,7 +4139,7 @@ CMenuManager::UserInput(void)
bool goDown = false;
int8 changeValueBy;
- if (!m_AllowNavigation && m_menuTransitionProgress == 255)
+ 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;
@@ -3475,17 +4147,22 @@ CMenuManager::UserInput(void)
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;
- int extraOffset = 0;
- if (aScreens[m_nCurrScreen].m_aEntries[rowToCheck].m_Action == MENUACTION_RADIO)
- extraOffset = MENURADIO_ICON_SCALE;
+ // 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) &&
- m_nMousePosY < MENU_Y(aScreens[m_nCurrScreen].m_aEntries[rowToCheck].m_Y + MENU_DEFAULT_LINE_HEIGHT)) {
+ 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;
@@ -3529,11 +4206,10 @@ CMenuManager::UserInput(void)
if (m_nMousePosY > SCREEN_HEIGHT) m_nMousePosY = SCREEN_HEIGHT;
changeValueBy = 0;
- if (m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS || m_nCurrScreen == MENUPAGE_SKIN_SELECT) {
+ if (hasNativeList(m_nCurrScreen)) {
ProcessList(optionSelected, goBack);
} else {
- // TODO(Miami): Seperate that code into a new function from ProcessUserInput
- // ProcessScrollingExceptLists(goBack);
+ AdditionalOptionInput(goBack);
if (m_AllowNavigation &&
(CPad::GetPad(0)->GetDownJustDown() || CPad::GetPad(0)->GetAnaloguePadDown() || CPad::GetPad(0)->GetDPadDownJustDown())) {
@@ -3541,8 +4217,7 @@ CMenuManager::UserInput(void)
goDown = true;
m_nOptionHighlightTransitionBlend = 0;
- }
- else if (m_AllowNavigation &&
+ } else if (m_AllowNavigation &&
(CPad::GetPad(0)->GetUpJustDown() || CPad::GetPad(0)->GetAnaloguePadUp() || CPad::GetPad(0)->GetDPadUpJustDown())) {
m_bShowMouse = false;
goUp = true;
@@ -3554,8 +4229,7 @@ CMenuManager::UserInput(void)
m_bShowMouse = false;
optionSelected = true;
}
- }
- else {
+ } else {
if (CPad::GetPad(0)->GetEnterJustDown() || CPad::GetPad(0)->GetCrossJustDown()) {
m_bShowMouse = false;
optionSelected = true;
@@ -3563,16 +4237,12 @@ CMenuManager::UserInput(void)
}
if (CPad::GetPad(0)->GetLeftMouseJustUp() && m_nCurrScreen != MENUPAGE_MAP) {
- // TODO(Miami): New radio selector
- if (m_nHoverOption == HOVEROPTION_RANDOM_ITEM) {
+ if (m_nHoverOption == HOVEROPTION_RANDOM_ITEM)
optionSelected = true;
- }
- }
- // TODO(Miami): This part is old radio selector, remove when new is reversed!!
- else if (CPad::GetPad(0)->GetLeftMouseJustDown()) {
- if (m_nHoverOption >= HOVEROPTION_RADIO_0 && m_nHoverOption <= HOVEROPTION_RADIO_9) {
- ChangeRadioStation(m_nHoverOption - HOVEROPTION_RADIO_0 - m_PrefsRadioStation);
- }
+ else if (m_nHoverOption == HOVEROPTION_NEXT_RADIO)
+ ChangeRadioStation(1);
+ else if (m_nHoverOption == HOVEROPTION_PREV_RADIO)
+ ChangeRadioStation(-1);
}
if (CPad::GetPad(0)->GetLeftMouse()) {
@@ -3596,6 +4266,27 @@ CMenuManager::UserInput(void)
}
}
+#ifdef SCROLLABLE_PAGES
+ if (m_nTotalListRow > MAX_VISIBLE_OPTION) {
+ bool temp = false;
+
+ m_nSelectedListRow = m_nCurrOption;
+
+ // ignore detected back/select states, it's our screen's job
+ ProcessList(temp, temp);
+
+ // and ignore our screen's goUp/Down, now it's ProcessList's job
+ 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()
@@ -3605,7 +4296,7 @@ CMenuManager::UserInput(void)
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_ENTER_OR_ADJUST, 0);
else if (option == MENUACTION_SFXVOLUME)
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_AUDIO_TEST, 0);
- else if (option == MENUACTION_DRAWDIST || option == MENUACTION_MOUSESTEER)
+ else if (option == MENUACTION_DRAWDIST || option == MENUACTION_MOUSESENS)
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_ENTER_OR_ADJUST, 0);
}
@@ -3649,10 +4340,15 @@ CMenuManager::UserInput(void)
}
}
- if (CPad::GetPad(0)->GetMouseWheelUpJustDown()) {
- changeValueBy = 1;
- } else if (CPad::GetPad(0)->GetMouseWheelDownJustDown()) {
- changeValueBy = -1;
+#ifdef SCROLLABLE_PAGES
+ if (!SCREEN_HAS_AUTO_SCROLLBAR)
+#endif
+ {
+ if (CPad::GetPad(0)->GetMouseWheelUpJustDown()) {
+ changeValueBy = 1;
+ } else if (CPad::GetPad(0)->GetMouseWheelDownJustDown()) {
+ changeValueBy = -1;
+ }
}
if (m_AllowNavigation) {
@@ -3685,9 +4381,30 @@ CMenuManager::UserInput(void)
}
}
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
}
-// --MIAMI: Done except TODOs
void
CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, uint8 goBack, int8 changeAmount)
{
@@ -3798,7 +4515,7 @@ CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, u
if (optionSelected && m_nMenuFadeAlpha == 255) {
if (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_TargetMenu == MENUPAGE_NEW_GAME_RELOAD && m_bGameNotLoaded) {
DoSettingsBeforeStartingAGame();
- } else if ((m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS) || (m_nCurrScreen == MENUPAGE_SKIN_SELECT)) {
+ } else if (hasNativeList(m_nCurrScreen)) {
switch (m_nCurrExLayer) {
case HOVEROPTION_LIST:
if (m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS) {
@@ -3835,16 +4552,14 @@ CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, u
}
int option = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_Action;
+#ifdef FIX_BUGS
+ int currScreen = m_nCurrScreen;
+ int currOption = m_nCurrOption;
+#endif
switch (option) {
case MENUACTION_CHANGEMENU:
case MENUACTION_YES:
case MENUACTION_NO:
-#ifdef CUSTOM_MAP
- if (aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_TargetMenu == MENUPAGE_MAP) {
- bMapLoaded = false;
- }
-
-#endif
SwitchToNewScreen(aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_TargetMenu);
break;
case MENUACTION_RADIO:
@@ -3884,8 +4599,8 @@ CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, u
{
int saveSlot = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_SaveSlot;
- if (saveSlot >= 2 && saveSlot <= 9) {
- m_nCurrSaveSlot = saveSlot - 2;
+ if (saveSlot >= SAVESLOT_1 && saveSlot <= SAVESLOT_8) {
+ m_nCurrSaveSlot = saveSlot - SAVESLOT_1;
if (Slots[m_nCurrSaveSlot] != SLOT_EMPTY && Slots[m_nCurrSaveSlot] != SLOT_CORRUPTED) {
if (m_nCurrScreen == MENUPAGE_CHOOSE_LOAD_SLOT) {
SwitchToNewScreen(MENUPAGE_LOAD_SLOT_CONFIRM);
@@ -3972,15 +4687,6 @@ CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, u
SaveSettings();
}
break;
-#ifdef IMPROVED_VIDEOMODE
- case MENUACTION_SCREENFORMAT:
- if (m_nSelectedScreenMode != m_nPrefsWindowed) {
- m_nPrefsWindowed = m_nSelectedScreenMode;
- _psSelectScreenVM(m_nPrefsVideoMode); // apply same resolution
- SaveSettings();
- }
- break;
-#endif
case MENUACTION_AUDIOHW:
{
int selectedProvider = m_nPrefsAudio3DProviderIndex;
@@ -4034,7 +4740,11 @@ CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, u
#endif
CRenderer::ms_lodDistScale = m_PrefsLOD;
m_PrefsShowSubtitles = false;
+#ifdef ASPECT_RATIO_SCALE
+ m_PrefsUseWideScreen = AR_AUTO;
+#else
m_PrefsUseWideScreen = false;
+#endif
m_PrefsShowLegends = true;
m_PrefsVsyncDisp = true;
m_PrefsFrameLimiter = true;
@@ -4042,6 +4752,13 @@ CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, u
m_PrefsShowHud = true;
m_nDisplayVideoMode = m_nPrefsVideoMode;
CMBlur::BlurOn = false;
+#ifdef CUSTOM_FRONTEND_OPTIONS
+ extern void RestoreDefGraphics(int8);
+ extern void RestoreDefDisplay(int8);
+
+ RestoreDefGraphics(FEOPTION_ACTION_SELECT);
+ RestoreDefDisplay(FEOPTION_ACTION_SELECT);
+#endif
SaveSettings();
} else if (m_nCurrScreen == MENUPAGE_CONTROLLER_PC) {
ControlsManager.MakeControllerActionsBlank();
@@ -4063,6 +4780,9 @@ CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, u
#endif
MousePointerStateHelper.bInvertVertically = true;
TheCamera.m_bHeadBob = false;
+#ifdef FIX_BUGS
+ TheCamera.m_fMouseAccelVertical = 0.003f;
+#endif
TheCamera.m_fMouseAccelHorzntl = 0.0025f;
CVehicle::m_bDisableMouseSteering = true;
m_ControlMethod = CONTROL_STANDARD;
@@ -4081,12 +4801,43 @@ CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, u
}
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();
+
+ if (option.m_CFOSelect->displayedValue != oldValue && option.m_CFOSelect->changeFunc)
+ option.m_CFOSelect->changeFunc(oldValue, option.m_CFOSelect->displayedValue);
+
+ } else if (option.m_Action == MENUACTION_CFO_DYNAMIC) {
+ if (option.m_CFODynamic->buttonPressFunc)
+ option.m_CFODynamic->buttonPressFunc(FEOPTION_ACTION_SELECT);
+ }
+
+ break;
+#endif
}
ProcessOnOffMenuOptions();
if (!goBack) {
+#ifdef FIX_BUGS
+ int saveSlot = aScreens[currScreen].m_aEntries[currOption].m_SaveSlot;
+ if (saveSlot >= SAVESLOT_1 && saveSlot <= SAVESLOT_8 && Slots[currOption] != SLOT_OK)
+#else
int saveSlot = aScreens[m_nCurrScreen].m_aEntries[m_nCurrOption].m_SaveSlot;
-
- if (saveSlot >= 2 && saveSlot <= 9 && Slots[m_nCurrOption] != SLOT_OK)
+ if (saveSlot >= SAVESLOT_1 && saveSlot <= SAVESLOT_8 && Slots[m_nCurrOption] != SLOT_OK)
+#endif
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_FAIL, 0);
else
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_ENTER_OR_ADJUST, 0);
@@ -4097,7 +4848,7 @@ CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, u
if (m_NoEmptyBinding) {
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_BACK, 0);
SwitchToNewScreen(-2);
- if ((m_nCurrScreen == MENUPAGE_SKIN_SELECT) || (m_nCurrScreen == MENUPAGE_KEYBOARD_CONTROLS)) {
+ if (hasNativeList(m_nCurrScreen)) {
m_nTotalListRow = 0;
}
} else {
@@ -4152,11 +4903,6 @@ CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, u
}
}
break;
-#ifdef IMPROVED_VIDEOMODE
- case MENUACTION_SCREENFORMAT:
- m_nSelectedScreenMode = !m_nSelectedScreenMode;
- break;
-#endif
case MENUACTION_AUDIOHW:
if (m_nPrefsAudio3DProviderIndex != NO_AUDIO_PROVIDER) {
m_nPrefsAudio3DProviderIndex += changeAmount;
@@ -4203,6 +4949,36 @@ CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, u
CCamera::m_bUseMouse3rdPerson = !m_ControlMethod;
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 (changeAmount > 0) {
+ option.m_CFOSelect->displayedValue++;
+ if (option.m_CFOSelect->displayedValue >= option.m_CFOSelect->numRightTexts)
+ option.m_CFOSelect->displayedValue = 0;
+ } else {
+ option.m_CFOSelect->displayedValue--;
+ if (option.m_CFOSelect->displayedValue < 0)
+ option.m_CFOSelect->displayedValue = option.m_CFOSelect->numRightTexts - 1;
+ }
+ if (!option.m_CFOSelect->onlyApplyOnEnter) {
+ int8 oldValue = *option.m_CFO->value;
+
+ *option.m_CFO->value = option.m_CFOSelect->lastSavedValue = option.m_CFOSelect->displayedValue;
+
+ if (option.m_CFOSelect->save)
+ SaveSettings();
+
+ if (option.m_CFOSelect->displayedValue != oldValue && option.m_CFOSelect->changeFunc)
+ 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(changeAmount > 0 ? FEOPTION_ACTION_RIGHT : FEOPTION_ACTION_LEFT);
+ }
+ break;
+#endif
}
CheckSliderMovement(changeAmount);
ProcessOnOffMenuOptions();
@@ -4216,7 +4992,6 @@ CMenuManager::ProcessUserInput(uint8 goDown, uint8 goUp, uint8 optionSelected, u
}
}
-// --MIAMI: Done
void
CMenuManager::ProcessOnOffMenuOptions()
{
@@ -4345,6 +5120,129 @@ float CMenuManager::StretchY(float y)
return SCREEN_STRETCH_Y(y);
}
+#ifdef XBOX_MESSAGE_SCREEN
+void
+CMenuManager::CloseDialog(void)
+{
+ // We don't have this on PC GXT :shrug:
+ static wchar* gameSaved = AllocUnicode("Game saved successfully!");
+
+ if (m_bSaveWasSuccessful && DialogTextCmp("FESZ_WR")) {
+ m_bSaveWasSuccessful = false; // i don't know where XBOX resets that
+ m_pDialogText = gameSaved;
+ SetDialogTimer(1000);
+ ProcessDialogTimer();
+ } else {
+ ToggleDialog(false);
+ }
+
+}
+
+void
+CMenuManager::ProcessDialogTimer(void)
+{
+ if (!m_bDialogOpen || m_nDialogHideTimer == 0)
+ return;
+
+ // Also XBOX has unified time source for in-game/menu, but we don't have that
+ if (m_bMenuActive && CTimer::GetTimeInMilliseconds() > m_nDialogHideTimer || !m_bMenuActive && CTimer::GetTimeInMillisecondsPauseMode() > m_nDialogHideTimerPauseMode) {
+
+ // This is originally activePage.funcs->closePage()
+ CloseDialog();
+ }
+}
+
+void
+CMenuManager::SetDialogTimer(uint32 timer)
+{
+ // XBOX iterates some page list(actives?) and then sets timer variable of specified page to specified value. We only have dialog right now.
+ // Also XBOX has unified time source for in-game/menu, but we don't have that, thus 2 timer variables...
+
+ m_nDialogHideTimer = CTimer::GetTimeInMilliseconds() + timer;
+ m_nDialogHideTimerPauseMode = CTimer::GetTimeInMillisecondsPauseMode() + timer;
+}
+
+void
+CMenuManager::SetDialogText(const char* key)
+{
+ // There are many things going around here, idk why
+ m_pDialogText = TheText.Get(key);
+}
+
+bool
+CMenuManager::DialogTextCmp(const char* key)
+{
+ wchar *value = TheText.Get(key);
+ wchar *i = m_pDialogText;
+ for (; *i != '\0' && *value != '\0'; i++, value++) {
+ if (*i != *value)
+ return false;
+ }
+ return *i == '\0' && *value == '\0';
+}
+
+void
+CMenuManager::ToggleDialog(bool toggle)
+{
+ // This originally calls some mysterious function on enable and close CB on disable, along with decreasing some counter. Which is no use for dialog
+
+ // XBOX doesn't do that
+ if (toggle)
+ m_nDialogHideTimer = 0;
+
+ m_bDialogOpen = toggle;
+}
+
+void
+DrawDialogBg(float offset, uint8 alpha)
+{
+ CSprite2d::Draw2DPolygon(SCALE_AND_CENTER_X(84.f + offset), MENU_Y(126.f + offset),
+ SCALE_AND_CENTER_X(512.f + offset), MENU_Y(109.f + offset),
+ SCALE_AND_CENTER_X(100.f + offset), MENU_Y(303.f + offset),
+ SCALE_AND_CENTER_X(474.f + offset), MENU_Y(311.f + offset), CRGBA(107, 193, 236, alpha));
+ CSprite2d::Draw2DPolygon(SCALE_AND_CENTER_X(523.f + offset), MENU_Y(108.f + offset),
+ SCALE_AND_CENTER_X(542.f + offset), MENU_Y(107.f + offset),
+ SCALE_AND_CENTER_X(485.f + offset), MENU_Y(310.f + offset),
+ SCALE_AND_CENTER_X(516.f + offset), MENU_Y(311.f + offset), CRGBA(107, 193, 236, alpha));
+}
+
+void
+CMenuManager::DrawOverlays(void)
+{
+ // This is stripped to show only Dialog box, XBOX does much more in here.
+
+ if (!m_bDialogOpen)
+ return;
+
+ DefinedState();
+
+ CSprite2d::DrawRect(CRect(0, SCREEN_HEIGHT, SCREEN_WIDTH, 0), CRGBA(0, 0, 0, 160));
+
+ // Ofc this is not hardcoded like that on Xbox, it should be a texture
+ DrawDialogBg(20.f, 160); // shadow
+ DrawDialogBg(0.f, 255);
+
+ CFont::SetBackgroundOff();
+ CFont::SetPropOn();
+ CFont::SetJustifyOn();
+ CFont::SetBackGroundOnlyTextOn();
+ CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD));
+ CFont::SetCentreSize(SCREEN_SCALE_X(380.0f));
+ CFont::SetCentreOn();
+ CFont::SetColor(CRGBA(LABEL_COLOR.r, LABEL_COLOR.g, LABEL_COLOR.b, 255));
+ CFont::SetDropShadowPosition(2);
+ CFont::SetDropColor(CRGBA(0, 0, 0, 255));
+ // Both of those are 0.9 on Xbox, which is ofcouse wrong...
+ CFont::SetScale(SCREEN_SCALE_X(BIGTEXT_X_SCALE), SCREEN_SCALE_Y(BIGTEXT_Y_SCALE));
+
+ int x = SCREEN_WIDTH / 2.f - SCREEN_SCALE_X(30.0f);
+ int y = SCREEN_HEIGHT / 2.f - SCREEN_SCALE_Y(30.0f);
+ int numOfLines = CFont::GetNumberLines(x, y, m_pDialogText);
+ CFont::PrintString(x, y - SCREEN_SCALE_Y(numOfLines / 2.f), m_pDialogText);
+ CFont::DrawFonts();
+}
+#endif
+
void
CMenuManager::ProcessFileActions()
{
@@ -4354,9 +5252,14 @@ CMenuManager::ProcessFileActions()
#ifdef USE_DEBUG_SCRIPT_LOADER
scriptToLoad = 0;
#endif
+
+#ifdef XBOX_MESSAGE_SCREEN
+ SetDialogText("FELD_WR");
+ ToggleDialog(true);
+#else
if (!m_bGameNotLoaded)
MessageScreen("FELD_WR", true);
-
+#endif
DoSettingsBeforeStartingAGame();
m_bWantToLoad = true;
} else
@@ -4389,6 +5292,41 @@ CMenuManager::ProcessFileActions()
}
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
+
+ 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) {
@@ -4404,13 +5342,12 @@ CMenuManager::ProcessFileActions()
waitedForScreen = false;
} else if (m_nMenuFadeAlpha >= 255)
waitedForScreen = true;
-
+#endif
break;
}
}
}
-// --MIAMI: Done
void
CMenuManager::SwitchMenuOnAndOff()
{
@@ -4419,9 +5356,17 @@ CMenuManager::SwitchMenuOnAndOff()
// 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) {
+ || m_bShutDownFrontEndRequested || m_bStartUpFrontEndRequested
+#ifdef REGISTER_START_BUTTON
+ || CPad::GetPad(0)->GetStartJustDown() && !m_bGameNotLoaded
+#endif
+ ) {
- if (m_nCurrScreen != MENUPAGE_LOADING_IN_PROGRESS) {
+ 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);
@@ -4443,6 +5388,10 @@ CMenuManager::SwitchMenuOnAndOff()
Initialise();
LoadAllTextures();
} else {
+#ifdef EXTENDED_COLOURFILTER
+ // we always expect CPostFX to be open
+ CMBlur::BlurOn = true;
+#endif
if (CMBlur::BlurOn)
CMBlur::MotionBlurOpen(Scene.camera);
else
@@ -4457,6 +5406,9 @@ CMenuManager::SwitchMenuOnAndOff()
}
m_StatsScrollSpeed = 150.0f;
+#ifdef FIX_BUGS
+ ThingsToDoBeforeLeavingPage();
+#endif
SaveSettings();
pControlEdit = nil;
pEditString = nil;
@@ -4546,7 +5498,6 @@ CMenuManager::UnloadTextures()
CUserDisplay::PlaceName.ProcessAfterFrontEndShutDown();
}
-// --MIAMI: Done
void
CMenuManager::WaitForUserCD()
{
@@ -4605,56 +5556,14 @@ CMenuManager::DrawQuitGameScreen(void)
m_AllowNavigation = false;
}
-#ifdef CUSTOM_MAP
-
-#define ZOOM(x, y, in) \
- do { \
- if(m_fMapSize > SCREEN_HEIGHT * 3.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 < SCREEN_HEIGHT / 2 && !in) \
- break; \
- \
- m_fMapSize *= z2; \
- } while(0)
-
-#endif
-
void
CMenuManager::PrintMap(void)
{
m_bMenuMapActive = true;
CRadar::InitFrontEndMap();
-#ifdef CUSTOM_MAP
- // Just entered to map
- if (!bMapLoaded) {
- m_fMapSize = SCREEN_HEIGHT * 2.0f;
- m_fMapCenterX = 0.0f;
- m_fMapCenterY = 0.0f;
- CVector2D radarSpacePlayer;
- CVector2D screenSpacePlayer;
- CRadar::TransformRealWorldPointToRadarSpace(radarSpacePlayer, CVector2D(FindPlayerCoors()));
- CRadar::TransformRadarPointToScreenSpace(screenSpacePlayer, radarSpacePlayer);
-
- m_fMapCenterX = (-screenSpacePlayer.x) + SCREEN_WIDTH / 2;
- m_fMapCenterY = (-screenSpacePlayer.y) + SCREEN_HEIGHT / 2;
- bMapMouseShownOnce = false;
- bMapLoaded = true;
-
- // Let's wait for a frame to not toggle the waypoint
- if (CPad::GetPad(0)->NewState.Cross) {
- m_bMenuMapActive = false;
- return;
- }
- }
-#endif
-
- // Because m_fMapSize is half of the map length, and map consists of 3x3 tiles.
- float halfTile = m_fMapSize / 3.0f;
+ // 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);
@@ -4752,266 +5661,45 @@ CMenuManager::PrintMap(void)
}
}
-#ifdef CUSTOM_MAP
- CVector2D mapPoint;
- mapPoint.x = m_nMousePosX;
- mapPoint.y = m_nMousePosY;
-
- if (m_bShowMouse) {
- bMapMouseShownOnce = true;
- } else if (!bMapMouseShownOnce) {
- mapPoint.x = SCREEN_WIDTH / 2;
- mapPoint.y = SCREEN_HEIGHT / 2;
+#ifdef MAP_ENHANCEMENTS
+ if (m_nMenuFadeAlpha != 255 && !m_bShowMouse) {
+ mapCrosshair.x = SCREEN_WIDTH / 2;
+ mapCrosshair.y = SCREEN_HEIGHT / 2;
+ } else if (m_bShowMouse) {
+ mapCrosshair.x = m_nMousePosX;
+ mapCrosshair.y = m_nMousePosY;
}
- CSprite2d::DrawRect(CRect(mapPoint.x - MENU_X(1.0f), 0.0f,
- mapPoint.x + MENU_X(1.0f), SCREEN_HEIGHT),
+ CSprite2d::DrawRect(CRect(mapCrosshair.x - MENU_X(1.0f), 0.0f,
+ mapCrosshair.x + MENU_X(1.0f), SCREEN_HEIGHT),
CRGBA(0, 0, 0, 150));
- CSprite2d::DrawRect(CRect(0.0f, mapPoint.y + MENU_X(1.0f),
- SCREEN_WIDTH, mapPoint.y - MENU_X(1.0f)),
+ CSprite2d::DrawRect(CRect(0.0f, mapCrosshair.y + MENU_X(1.0f),
+ SCREEN_WIDTH, mapCrosshair.y - MENU_X(1.0f)),
CRGBA(0, 0, 0, 150));
- if (CPad::GetPad(0)->GetRightMouseJustDown() || CPad::GetPad(0)->GetCrossJustDown()) {
- if (mapPoint.y > m_fMapCenterY - m_fMapSize && mapPoint.y < m_fMapCenterY + m_fMapSize &&
- mapPoint.x > m_fMapCenterX - m_fMapSize && mapPoint.x < m_fMapCenterX + m_fMapSize) {
-
- // Don't ask me the meanings, I don't know. Found them by trying
- float diffX = m_fMapCenterX - m_fMapSize, diffY = m_fMapCenterY - m_fMapSize;
- float x = ((mapPoint.x - diffX) / (m_fMapSize * 2)) * (WORLD_SIZE_X / MENU_MAP_WIDTH_SCALE) - (WORLD_SIZE_X / 2 + MENU_MAP_LEFT_OFFSET * MENU_MAP_LENGTH_UNIT);
- float y = (WORLD_SIZE_Y / 2 - MENU_MAP_TOP_OFFSET * MENU_MAP_LENGTH_UNIT) - ((mapPoint.y - diffY) / (m_fMapSize * 2)) * (WORLD_SIZE_Y / MENU_MAP_HEIGHT_SCALE);
- CRadar::ToggleTargetMarker(x, y);
- DMAudio.PlayFrontEndSound(SOUND_FRONTEND_BACK, 0);
- }
- }
-
- if (CPad::GetPad(0)->GetLeftMouse()) {
- m_fMapCenterX += m_nMousePosX - m_nMouseOldPosX;
- m_fMapCenterY += m_nMousePosY - m_nMouseOldPosY;
- } else if (CPad::GetPad(0)->GetLeft() || CPad::GetPad(0)->GetDPadLeft()) {
- m_fMapCenterX += 15.0f;
- } else if (CPad::GetPad(0)->GetRight() || CPad::GetPad(0)->GetDPadRight()) {
- m_fMapCenterX -= 15.0f;
- } else if (CPad::GetPad(0)->GetLeftStickX()) {
- m_fMapCenterX -= CPad::GetPad(0)->GetLeftStickX() / 128.0f * 20.0f;
- }
-
- if (CPad::GetPad(0)->GetUp() || CPad::GetPad(0)->GetDPadUp()) {
- m_fMapCenterY += 15.0f;
- } else if (CPad::GetPad(0)->GetDown() || CPad::GetPad(0)->GetDPadDown()) {
- m_fMapCenterY -= 15.0f;
- } else if (CPad::GetPad(0)->GetLeftStickY()) {
- m_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(mapPoint.x, mapPoint.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(mapPoint.x, mapPoint.y, true);
- else
- ZOOM(SCREEN_WIDTH / 2, SCREEN_HEIGHT / 2, true);
- }
-
- if (m_fMapCenterX - m_fMapSize > SCREEN_WIDTH / 2)
- m_fMapCenterX = m_fMapSize + SCREEN_WIDTH / 2;
-
- if (m_fMapCenterX + m_fMapSize < SCREEN_WIDTH / 2)
- m_fMapCenterX = SCREEN_WIDTH / 2 - m_fMapSize;
-
- if (m_fMapCenterY + m_fMapSize < SCREEN_HEIGHT - MENU_Y(60.0f))
- m_fMapCenterY = SCREEN_HEIGHT - MENU_Y(60.0f) - m_fMapSize;
-
- if (m_fMapCenterY - m_fMapSize > SCREEN_HEIGHT / 2)
- m_fMapCenterY = SCREEN_HEIGHT / 2 + m_fMapSize;
#endif
m_bMenuMapActive = false;
- CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENU_UNK_X_MARGIN));
- CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(MENU_UNK_X_MARGIN));
+ CFont::SetWrapx(MENU_X_RIGHT_ALIGNED(MENU_X_MARGIN));
+ CFont::SetRightJustifyWrap(MENU_X_LEFT_ALIGNED(MENU_X_MARGIN));
DisplayHelperText("FEH_MPH");
}
-#ifdef CUSTOM_MAP
-#undef ZOOM
-#endif
-
-// rowIdx 99999 returns total numbers of rows. otherwise it returns 0.
-int
-CMenuManager::ConstructStatLine(int rowIdx)
-{
-#define STAT_LINE(str, left, isFloat, right) \
- do { \
- if(counter == rowIdx){ \
- BuildStatLine(str, left, isFloat, right); \
- return 0; \
- } counter++; \
- } while(0)
-
- int counter = 0, nTemp;
-
- STAT_LINE("PL_STAT", nil, false, nil);
-
- int percentCompleted = CStats::GetPercentageProgress();
-
- STAT_LINE("PER_COM", &percentCompleted, false, nil);
- STAT_LINE("NMISON", &CStats::MissionsGiven, false, nil);
- STAT_LINE("FEST_MP", &CStats::MissionsPassed, false, &CStats::TotalNumberMissions);
- if (CGame::nastyGame) {
- STAT_LINE("FEST_RP", &CStats::NumberKillFrenziesPassed, false, &CStats::TotalNumberKillFrenzies);
- }
-
- CPlayerInfo &player = CWorld::Players[CWorld::PlayerInFocus];
- float packagesPercent = 0.0f;
- if (player.m_nTotalPackages != 0)
- packagesPercent = player.m_nCollectedPackages * 100.0f / player.m_nTotalPackages;
-
- int nPackagesPercent = packagesPercent;
- STAT_LINE("PERPIC", &nPackagesPercent, false, &(nTemp = 100));
- STAT_LINE("NOUNIF", &CStats::NumberOfUniqueJumpsFound, false, &CStats::TotalNumberOfUniqueJumps);
- STAT_LINE("DAYSPS", &CStats::DaysPassed, false, nil);
- if (CGame::nastyGame) {
- STAT_LINE("PE_WAST", &CStats::PeopleKilledByPlayer, false, nil);
- STAT_LINE("PE_WSOT", &CStats::PeopleKilledByOthers, false, nil);
- }
- STAT_LINE("CAR_EXP", &CStats::CarsExploded, false, nil);
- STAT_LINE("TM_BUST", &CStats::TimesArrested, false, nil);
- STAT_LINE("TM_DED", &CStats::TimesDied, false, nil);
- STAT_LINE("GNG_WST", &(nTemp = 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]), false, nil);
- STAT_LINE("DED_CRI", &(nTemp = CStats::PedsKilledOfThisType[PEDTYPE_CRIMINAL]), false, nil);
- STAT_LINE("HEL_DST", &CStats::HelisDestroyed, false, nil);
- STAT_LINE("KGS_EXP", &CStats::KgsOfExplosivesUsed, false, nil);
-
- if (CStats::HighestScores[0] > 0) {
- STAT_LINE("FEST_BB", nil, false, nil);
- STAT_LINE("FEST_H0", &CStats::HighestScores[0], false, nil);
- }
- if (CStats::HighestScores[4] + CStats::HighestScores[3] + CStats::HighestScores[2] + CStats::HighestScores[1] > 0) {
- STAT_LINE("FEST_GC", nil, false, nil);
- }
- if (CStats::HighestScores[1] > 0) {
- STAT_LINE("FEST_H1", &CStats::HighestScores[1], false, nil);
- }
- if (CStats::HighestScores[2] > 0) {
- STAT_LINE("FEST_H2", &CStats::HighestScores[2], false, nil);
- }
- if (CStats::HighestScores[3] > 0) {
- STAT_LINE("FEST_H3", &CStats::HighestScores[3], false, nil);
- }
- if (CStats::HighestScores[4] > 0) {
- STAT_LINE("FEST_H4", &CStats::HighestScores[4], false, nil);
- }
-
- switch (m_PrefsLanguage) {
- case LANGUAGE_AMERICAN:
-#ifndef USE_MEASUREMENTS_IN_METERS
- float fTemp;
- STAT_LINE("FEST_DF", &(fTemp = CStats::DistanceTravelledOnFoot * MILES_IN_METER), true, nil);
- STAT_LINE("FEST_DC", &(fTemp = CStats::DistanceTravelledByCar * MILES_IN_METER), true, nil);
- STAT_LINE("DISTBIK", &(fTemp = CStats::DistanceTravelledByBike * MILES_IN_METER), true, nil);
- STAT_LINE("DISTBOA", &(fTemp = CStats::DistanceTravelledByBoat * MILES_IN_METER), true, nil);
- STAT_LINE("DISTGOL", &(fTemp = CStats::DistanceTravelledByGolfCart * MILES_IN_METER), true, nil);
- STAT_LINE("DISTHEL", &(fTemp = CStats::DistanceTravelledByHelicoptor * MILES_IN_METER), true, nil);
- STAT_LINE("MXCARD", &(fTemp = CStats::MaximumJumpDistance * FEET_IN_METER), true, nil);
- STAT_LINE("MXCARJ", &(fTemp = CStats::MaximumJumpHeight * FEET_IN_METER), true, nil);
- 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("FESTDFM", &CStats::DistanceTravelledOnFoot, true, nil);
- STAT_LINE("FESTDCM", &CStats::DistanceTravelledByCar, true, nil);
- STAT_LINE("DISTBIM", &CStats::DistanceTravelledByBike, true, nil);
- STAT_LINE("DISTBOM", &CStats::DistanceTravelledByBoat, true, nil);
- STAT_LINE("DISTGOM", &CStats::DistanceTravelledByGolfCart, true, nil);
- STAT_LINE("DISTHEM", &CStats::DistanceTravelledByHelicoptor, true, nil);
- STAT_LINE("MXCARDM", &CStats::MaximumJumpDistance, true, nil);
- STAT_LINE("MXCARJM", &CStats::MaximumJumpHeight, true, nil);
- break;
- default:
- break;
- }
-
- STAT_LINE("MXFLIP", &CStats::MaximumJumpFlips, false, nil);
- STAT_LINE("MXJUMP", &CStats::MaximumJumpSpins, false, nil);
- STAT_LINE("BSTSTU", nil, false, nil);
-
- if (counter == rowIdx) {
- gUString[0] = '\0';
- switch (CStats::BestStuntJump) {
- case 1:
- UnicodeStrcpy(gUString2, TheText.Get("INSTUN"));
- return 0;
- case 2:
- UnicodeStrcpy(gUString2, TheText.Get("PRINST"));
- return 0;
- case 3:
- UnicodeStrcpy(gUString2, TheText.Get("DBINST"));
- return 0;
- case 4:
- UnicodeStrcpy(gUString2, TheText.Get("DBPINS"));
- return 0;
- case 5:
- UnicodeStrcpy(gUString2, TheText.Get("TRINST"));
- return 0;
- case 6:
- UnicodeStrcpy(gUString2, TheText.Get("PRTRST"));
- return 0;
- case 7:
- UnicodeStrcpy(gUString2, TheText.Get("QUINST"));
- return 0;
- case 8:
- UnicodeStrcpy(gUString2, TheText.Get("PQUINS"));
- return 0;
- default:
- UnicodeStrcpy(gUString2, TheText.Get("NOSTUC"));
- return 0;
- }
- }
- counter++;
- STAT_LINE("PASDRO", &CStats::PassengersDroppedOffWithTaxi, false, nil);
- STAT_LINE("MONTAX", &CStats::MoneyMadeWithTaxi, false, nil);
- STAT_LINE("FEST_LS", &CStats::LivesSavedWithAmbulance, false, nil);
- STAT_LINE("FEST_HA", &CStats::HighestLevelAmbulanceMission, false, nil);
- STAT_LINE("FEST_CC", &CStats::CriminalsCaught, false, nil);
- STAT_LINE("FEST_FE", &CStats::FiresExtinguished, false, nil);
- STAT_LINE("DAYPLC", &(nTemp = CTimer::GetTimeInMilliseconds() + 100), false, nil);
- //TODO(MIAMI): move this function to the CStats and add reading of Stat lines tied with "MEDIA" for the "CHASESTAT" cheatcode
- return counter;
-
-#undef STAT_LINE
-}
-
-// TODO(Miami): These #if 0's are here because we still use III radio selector. Remove them when new one reversed
void
-CMenuManager::ChangeRadioStation(uint8 increaseBy)
+CMenuManager::ChangeRadioStation(int8 increaseBy)
{
if (m_ScrollRadioBy != 0)
return;
m_PrefsRadioStation += increaseBy;
-#if 0
m_ScrollRadioBy = increaseBy;
if (m_ScrollRadioBy == 1) {
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_ENTER_OR_ADJUST, 0);
- field_F0 = 238.0f;
+ m_LeftMostRadioX = MENU_X_LEFT_ALIGNED(MENURADIO_ICON_FIRST_X);
} else {
DMAudio.PlayFrontEndSound(SOUND_FRONTEND_ENTER_OR_ADJUST, 0);
- field_F0 = 118.0f;
+ m_LeftMostRadioX = MENU_X_LEFT_ALIGNED(MENURADIO_ICON_FIRST_X - (2 * MENURADIO_ICON_SIZE));
}
-#endif
if (DMAudio.IsMP3RadioChannelAvailable()) {
if (m_PrefsRadioStation < WILDSTYLE)
@@ -5024,15 +5712,8 @@ CMenuManager::ChangeRadioStation(uint8 increaseBy)
if (m_PrefsRadioStation > WAVE)
m_PrefsRadioStation = WILDSTYLE;
}
-#if 0
DMAudio.StopFrontEndTrack();
DMAudio.PlayFrontEndSound(SOUND_RADIO_CHANGE, 0);
-#else
- SaveSettings();
- DMAudio.SetRadioInCar(m_PrefsRadioStation);
- DMAudio.PlayFrontEndTrack(m_PrefsRadioStation, 1);
- OutputDebugString("FRONTEND RADIO STATION CHANGED");
-#endif
}
#if 0
@@ -5051,5 +5732,3 @@ uint8 CMenuManager::GetNumberOfMenuOptions()
#undef GetBackJustUp
#undef GetBackJustDown
-
-#endif
diff --git a/src/core/Frontend.h b/src/core/Frontend.h
index d2091a52..5e18c29a 100644
--- a/src/core/Frontend.h
+++ b/src/core/Frontend.h
@@ -4,13 +4,14 @@
#else
#include "Sprite2d.h"
+#include "Timer.h"
#define MENUHEADER_POS_X 10.0f
#define MENUHEADER_POS_Y 10.0f
#define MENUHEADER_HEIGHT 2.0f
#define MENUHEADER_WIDTH 1.0f
-#define MENU_UNK_X_MARGIN 10.0f
+#define MENU_X_MARGIN 10.0f
#define MENUACTION_SCALE_MULT 0.9f
@@ -22,24 +23,36 @@
#define MENU_DEFAULT_CONTENT_Y 100
#define MENU_DEFAULT_LINE_HEIGHT 29
-#define MENURADIO_ICON_SCALE 60.0f
+#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
+#define BIGTEXT2_X_SCALE 0.6f // For FONT_STANDARD
#define BIGTEXT2_Y_SCALE 1.2f
-#define BIGTEXT_X_SCALE 0.6f
+#define BIGTEXT_X_SCALE 0.6f // For FONT_HEADING
#define BIGTEXT_Y_SCALE 1.0f
-#define MEDIUMTEXT_X_SCALE 0.48f
+#define MEDIUMTEXT_X_SCALE 0.48f // For FONT_STANDARD
#define MEDIUMTEXT_Y_SCALE 1.0f
-#define SMALLTEXT_X_SCALE 0.42f
+#define SMALLTEXT_X_SCALE 0.42f // For FONT_STANDARD
#define SMALLTEXT_Y_SCALE 0.9f
-#define SMALLESTTEXT_X_SCALE 0.3f
+#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
@@ -51,8 +64,6 @@
#endif
#define PLAYERSETUP_SCROLLBUTTON_HEIGHT 17.0f
#define PLAYERSETUP_SCROLLBUTTON_TXD_DIMENSION 64
-#define PLAYERSETUP_ROW_TEXT_X_SCALE 0.4f
-#define PLAYERSETUP_ROW_TEXT_Y_SCALE 0.6f
#define PLAYERSETUP_SKIN_COLUMN_LEFT 220.0f
#define PLAYERSETUP_DATE_COLUMN_RIGHT 56.0f
#define PLAYERSETUP_LIST_BODY_TOP 77
@@ -80,16 +91,15 @@
#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
@@ -182,7 +192,6 @@ enum eMenuScreen
MENUPAGE_MOUSE_CONTROLS = 31,
MENUPAGE_PAUSE_MENU = 32,
MENUPAGE_NONE = 33, // Then chooses main menu or pause menu
- MENUPAGE_OUTRO = 34,
#ifdef LEGACY_MENU_OPTIONS
MENUPAGE_CONTROLLER_SETTINGS,
MENUPAGE_DEBUG_MENU,
@@ -192,14 +201,26 @@ enum eMenuScreen
MENUPAGE_CONTROLLER_PC_OLD4,
MENUPAGE_CONTROLLER_DEBUG,
#endif
+#ifdef CUSTOM_FRONTEND_OPTIONS
+
#ifdef GRAPHICS_MENU_OPTIONS
MENUPAGE_GRAPHICS_SETTINGS,
#endif
+#ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS
+ MENUPAGE_DETECT_JOYSTICK,
+#endif
+
+#endif
+ MENUPAGE_OUTRO, // Originally 34, but CFO needs last screen to be empty to count number of menu pages
MENUPAGES
};
enum eMenuAction
{
+#ifdef CUSTOM_FRONTEND_OPTIONS
+ MENUACTION_CFO_SELECT = -2,
+ MENUACTION_CFO_DYNAMIC = -1,
+#endif
MENUACTION_NOTHING,
MENUACTION_LABEL,
MENUACTION_YES,
@@ -254,29 +275,10 @@ enum eMenuAction
MENUACTION_DRAWDIST,
MENUACTION_MOUSESENS,
MENUACTION_MP3VOLUMEBOOST,
-#ifdef IMPROVED_VIDEOMODE
- MENUACTION_SCREENFORMAT,
-#endif
#ifdef LEGACY_MENU_OPTIONS
MENUACTION_CTRLVIBRATION,
MENUACTION_CTRLCONFIG,
#endif
-#ifdef ANISOTROPIC_FILTERING
- MENUACTION_MIPMAPS,
- MENUACTION_TEXTURE_FILTERING,
-#endif
-#ifdef MULTISAMPLING
- MENUACTION_MULTISAMPLING,
-#endif
-#ifdef NO_ISLAND_LOADING
- MENUACTION_ISLANDLOADING,
-#endif
-#ifdef PS2_ALPHA_TEST
- MENUACTION_PS2_ALPHA_TEST,
-#endif
-#ifdef CUTSCENE_BORDERS_SWITCH
- MENUACTION_CUTSCENEBORDERS,
-#endif
};
enum eCheckHover
@@ -303,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,
@@ -330,8 +324,8 @@ enum eCheckHover
enum
{
-#ifdef LEGACY_MENU_OPTIONS
- NUM_MENUROWS = 14,
+#if defined LEGACY_MENU_OPTIONS || defined CUSTOM_FRONTEND_OPTIONS
+ NUM_MENUROWS = 18,
#else
NUM_MENUROWS = 12,
#endif
@@ -347,7 +341,7 @@ enum eControlMethod
enum ControllerSetupColumn
{
CONTSETUP_PED_COLUMN = 0,
- CONTSETUP_VEHICLE_COLUMN = 14,
+ CONTSETUP_VEHICLE_COLUMN = 16,
};
struct tSkinInfo
@@ -365,6 +359,7 @@ struct BottomBarOption
int32 screenId;
};
+#ifndef CUSTOM_FRONTEND_OPTIONS
struct CMenuScreen
{
char m_ScreenName[8];
@@ -382,6 +377,88 @@ struct CMenuScreen
uint8 m_Align;
} m_aEntries[NUM_MENUROWS];
};
+extern CMenuScreen aScreens[MENUPAGES];
+#else
+#include "frontendoption.h"
+struct CCustomScreenLayout {
+ 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;
+ bool noInvasiveBorders; // not needed on pages already handled by game
+ int xMargin; // useful for two part texts - 0/empty = MENU_X_MARGIN
+};
+
+struct CCFO
+{
+ int8 *value;
+ const char *save;
+};
+
+struct CCFOSelect : CCFO
+{
+ char** rightTexts;
+ int8 numRightTexts;
+ bool onlyApplyOnEnter;
+ int8 displayedValue; // only if onlyApplyOnEnter enabled for now
+ int8 lastSavedValue; // only if onlyApplyOnEnter enabled
+ ChangeFunc changeFunc;
+
+ CCFOSelect() {};
+ CCFOSelect(int8* value, const char* save, const char** rightTexts, int8 numRightTexts, bool onlyApplyOnEnter, ChangeFunc changeFunc){
+ this->value = value;
+ if (value)
+ this->lastSavedValue = this->displayedValue = *value;
+
+ this->save = save;
+ this->rightTexts = (char**)rightTexts;
+ this->numRightTexts = numRightTexts;
+ this->onlyApplyOnEnter = onlyApplyOnEnter;
+ this->changeFunc = changeFunc;
+ }
+};
+
+struct CCFODynamic : CCFO
+{
+ DrawFunc drawFunc;
+ ButtonPressFunc buttonPressFunc;
+
+ CCFODynamic() {};
+ CCFODynamic(int8* value, const char* save, DrawFunc drawFunc, ButtonPressFunc buttonPressFunc){
+ this->value = value;
+ this->save = save;
+ this->drawFunc = drawFunc;
+ this->buttonPressFunc = buttonPressFunc;
+ }
+};
+
+struct CMenuScreenCustom
+{
+ char m_ScreenName[8];
+ int32 m_PreviousPage; // eMenuScreen
+ CCustomScreenLayout *layout;
+ ReturnPrevPageFunc returnPrevPageFunc;
+
+ struct CMenuEntry
+ {
+ int32 m_Action; // eMenuAction - below zero is CFO
+ char m_EntryName[8];
+ struct {
+ union {
+ CCFO *m_CFO; // for initializing
+ CCFOSelect *m_CFOSelect;
+ CCFODynamic *m_CFODynamic;
+ };
+ 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
{
@@ -473,7 +550,7 @@ public:
int8 m_PrefsShowSubtitles;
int8 m_PrefsShowLegends;
int8 m_PrefsUseWideScreen;
- int8 m_PrefsVsync; // TODO(Miami): Are we sure?
+ int8 m_PrefsVsync;
int8 m_PrefsVsyncDisp;
int8 m_PrefsFrameLimiter;
int8 m_nPrefsAudio3DProviderIndex;
@@ -481,7 +558,7 @@ public:
int8 m_PrefsDMA;
int8 m_PrefsSfxVolume;
int8 m_PrefsMusicVolume;
- uint8 m_PrefsRadioStation;
+ int8 m_PrefsRadioStation;
uint8 m_PrefsStereoMono; // unused except restore settings
int32 m_nCurrOption;
bool m_bQuitGameNoCD;
@@ -501,7 +578,7 @@ public:
int32 field_54;
int8 m_bLanguageLoaded;
uint8 m_PrefsAllowNastyGame;
- uint8 m_PrefsMP3BoostVolume;
+ int8 m_PrefsMP3BoostVolume;
uint8 m_ControlMethod;
int32 m_nPrefsVideoMode;
int32 m_nDisplayVideoMode;
@@ -514,10 +591,10 @@ public:
uint8 field_74[4];
int32 *pControlEdit;
bool m_OnlySaveMenu;
- int32 m_menuTransitionProgress;
+ int32 m_firstStartCounter;
CSprite2d m_aFrontEndSprites[NUM_MENU_SPRITES];
bool m_bSpritesLoaded;
- int32 field_F0;
+ int32 m_LeftMostRadioX;
int32 m_ScrollRadioBy;
int32 m_nCurrScreen;
int32 m_nPrevScreen;
@@ -621,20 +698,34 @@ public:
ISLAND_LOADING_HIGH
};
- static int8 m_DisplayIslandLoading;
- static int8 m_PrefsIslandLoading;
+ int8 m_PrefsIslandLoading;
- #define ISLAND_LOADING_IS(p) if (CMenuManager::m_PrefsIslandLoading == CMenuManager::ISLAND_LOADING_##p)
- #define ISLAND_LOADING_ISNT(p) if (CMenuManager::m_PrefsIslandLoading != CMenuManager::ISLAND_LOADING_##p)
+ #define ISLAND_LOADING_IS(p) if (FrontEndMenuManager.m_PrefsIslandLoading == CMenuManager::ISLAND_LOADING_##p)
+ #define ISLAND_LOADING_ISNT(p) if (FrontEndMenuManager.m_PrefsIslandLoading != CMenuManager::ISLAND_LOADING_##p)
#else
#define ISLAND_LOADING_IS(p)
#define ISLAND_LOADING_ISNT(p)
#endif
+#ifdef 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 BuildStatLine(Const char *text, void *stat, bool itsFloat, void *stat2);
static void CentreMousePointer();
void CheckCodesForControls(int);
bool CheckHover(int x1, int x2, int y1, int y2);
@@ -651,7 +742,6 @@ public:
void DrawBackground(bool transitionCall);
void DrawPlayerSetupScreen(bool);
int FadeIn(int alpha);
- void FilterOutColorMarkersFromString(wchar*);
int GetStartOptionsCntrlConfigScreens();
void InitialiseChangedLanguageSettings();
void LoadAllTextures();
@@ -665,7 +755,7 @@ public:
void ProcessList(bool &optionSelected, bool &goBack);
void UserInput();
void ProcessUserInput(uint8, uint8, uint8, uint8, int8);
- void ChangeRadioStation(uint8);
+ void ChangeRadioStation(int8);
void ProcessFileActions();
void ProcessOnOffMenuOptions();
void RequestFrontEndShutDown();
@@ -679,8 +769,10 @@ public:
void UnloadTextures();
void WaitForUserCD();
int GetNumOptionsCntrlConfigScreens();
- int ConstructStatLine(int);
void SwitchToNewScreen(int8);
+ void AdditionalOptionInput(bool &goBack);
+ void ExportStats(void);
+ void PrintRadioSelector(void);
// New (not in function or inlined in the game)
void ThingsToDoBeforeLeavingPage();
@@ -698,6 +790,5 @@ VALIDATE_SIZE(CMenuManager, 0x688);
#endif
extern CMenuManager FrontEndMenuManager;
-extern CMenuScreen aScreens[];
#endif
diff --git a/src/core/Frontend_PS2.cpp b/src/core/Frontend_PS2.cpp
index c9264f7d..1ccb658b 100644
--- a/src/core/Frontend_PS2.cpp
+++ b/src/core/Frontend_PS2.cpp
@@ -22,7 +22,7 @@
#include "Game.h"
#include "World.h"
#include "PlayerInfo.h"
-#include "FrontendControls.h"
+#include "FrontEndControls.h"
#include "MemoryCard.h"
#define CRect_SZ(x, y, w, h) CRect(x, y, x+w, y+h)
@@ -3017,4 +3017,4 @@ CMenuManager::FilterOutColorMarkersFromString(wchar *string, CRGBA &color)
*dst = '\0';
}
-#endif \ No newline at end of file
+#endif
diff --git a/src/core/Game.cpp b/src/core/Game.cpp
index 4034c4b6..348ac26d 100644
--- a/src/core/Game.cpp
+++ b/src/core/Game.cpp
@@ -32,6 +32,7 @@
#include "Fluff.h"
#include "Font.h"
#include "Frontend.h"
+#include "frontendoption.h"
#include "GameLogic.h"
#include "Garages.h"
#include "GenericGameStorage.h"
@@ -44,6 +45,7 @@
#include "MBlur.h"
#include "Messages.h"
#include "MemoryCard.h"
+#include "MemoryHeap.h"
#include "Pad.h"
#include "Particle.h"
#include "ParticleObject.h"
@@ -93,6 +95,10 @@
#include "WaterCreatures.h"
#include "postfx.h"
#include "custompipes.h"
+#include "screendroplets.h"
+#ifdef USE_TEXTURE_POOL
+#include "TexturePools.h"
+#endif
eLevelName CGame::currLevel;
int32 CGame::currArea;
@@ -163,6 +169,11 @@ CGame::InitialiseOnceBeforeRW(void)
#ifdef EXTENDED_COLOURFILTER
CPostFX::InitOnce();
#endif
+#ifdef CUSTOM_FRONTEND_OPTIONS
+ // Not needed here but may be needed in future
+ // if (numCustomFrontendOptions == 0 && numCustomFrontendScreens == 0)
+ CustomFrontendOptionsPopulate();
+#endif
return true;
}
@@ -182,12 +193,22 @@ CGame::InitialiseRenderWare(void)
#ifdef USE_TEXTURE_POOL
_TexturePoolsInitialise();
#endif
-
+
CTxdStore::Initialise();
CVisibilityPlugins::Initialise();
-
+
+#ifdef GTA_PS2
+ RpSkySelectTrueTSClipper(TRUE);
+ RpSkySelectTrueTLClipper(TRUE);
+
+ // PS2ManagerApplyDirectionalLightingCB() uploads the GTA lights
+ // directly without going through RpWorld and all that
+ SetupPS2ManagerDefaultLightingCallback();
+ PreAllocateRwObjects();
+#endif
+
/* Create camera */
- Scene.camera = CameraCreate(RsGlobal.width, RsGlobal.height, TRUE);
+ Scene.camera = CameraCreate(SCREEN_WIDTH, SCREEN_HEIGHT, TRUE);
ASSERT(Scene.camera != nil);
if (!Scene.camera)
{
@@ -217,7 +238,7 @@ CGame::InitialiseRenderWare(void)
/* Add the camera to the world */
RpWorldAddCamera(Scene.world, Scene.camera);
LightsCreate(Scene.world);
-
+
CreateDebugFont();
#ifdef LIBRW
@@ -234,23 +255,39 @@ CGame::InitialiseRenderWare(void)
ReplaceAtomicPipeCallback();
#endif // PS2_ALPHA_TEST
#endif // LIBRW
-
+
+ PUSH_MEMID(MEMID_TEXTURES);
CFont::Initialise();
CHud::Initialise();
CPlayerSkin::Initialise();
-
+ POP_MEMID();
+
+#ifdef EXTENDED_PIPELINES
+ CustomPipes::CustomPipeInit(); // need Scene.world for this
+#endif
+#ifdef SCREEN_DROPLETS
+ ScreenDroplets::InitDraw();
+#endif
+
return (true);
}
void CGame::ShutdownRenderWare(void)
{
+#ifdef SCREEN_DROPLETS
+ ScreenDroplets::Shutdown();
+#endif
+#ifdef EXTENDED_PIPELINES
+ CustomPipes::CustomPipeShutdown();
+#endif
+
DestroySplashScreen();
CHud::Shutdown();
CFont::Shutdown();
for ( int32 i = 0; i < NUMPLAYERS; i++ )
CWorld::Players[i].DeletePlayerSkin();
-
+
CPlayerSkin::Shutdown();
DestroyDebugFont();
@@ -282,7 +319,12 @@ bool CGame::InitialiseOnceAfterRW(void)
CSurfaceTable::Initialise("DATA\\SURFACE.DAT");
CPedStats::Initialise();
CTimeCycle::Initialise();
+#ifdef GTA_PS2
+ LoadingScreen("Loading the Game", "Initialising audio", GetRandomSplashScreen());
+#endif
DMAudio.Initialise();
+
+#ifndef GTA_PS2
if ( DMAudio.GetNum3DProvidersAvailable() == 0 )
FrontEndMenuManager.m_nPrefsAudio3DProviderIndex = NO_AUDIO_PROVIDER;
@@ -299,6 +341,7 @@ bool CGame::InitialiseOnceAfterRW(void)
DMAudio.SetEffectsMasterVolume(FrontEndMenuManager.m_PrefsSfxVolume);
DMAudio.SetEffectsFadeVol(127);
DMAudio.SetMusicFadeVol(127);
+#endif
return true;
}
@@ -314,23 +357,40 @@ bool CGame::Initialise(const char* datFile)
{
ResetLoadingScreenBar();
strcpy(aDatFile, datFile);
+
+#ifdef GTA_PS2
+ // TODO: upload VU0 collision code here
+#endif
+
CPools::Initialise();
+
+#ifndef GTA_PS2
CIniFile::LoadIniFile();
+#endif
#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());
gameTxdSlot = CTxdStore::AddTxdSlot("generic");
CTxdStore::Create(gameTxdSlot);
CTxdStore::AddRef(gameTxdSlot);
+
LoadingScreen("Loading the Game", "Loading particles", nil);
int particleTxdSlot = CTxdStore::AddTxdSlot("particle");
CTxdStore::LoadTxd(particleTxdSlot, "MODELS/PARTICLE.TXD");
CTxdStore::AddRef(particleTxdSlot);
CTxdStore::SetCurrentTxd(gameTxdSlot);
LoadingScreen("Loading the Game", "Setup game variables", nil);
+ POP_MEMID();
+
+#ifdef GTA_PS2
+ CDma::SyncChannel(0, true);
+#endif
+
CGameLogic::InitAtStartOfGame();
CReferences::Init();
TheCamera.Init();
@@ -350,21 +410,32 @@ bool CGame::Initialise(const char* datFile)
CMessages::ClearAllMessagesDisplayedByGame();
CRecordDataForGame::Init();
CRestart::Initialise();
+
+ PUSH_MEMID(MEMID_WORLD);
CWorld::Initialise();
+ POP_MEMID();
+
+ PUSH_MEMID(MEMID_TEXTURES);
CParticle::Initialise();
-#ifdef PS2
- gStartX = -180.0f;
- gStartY = 180.0f;
- gStartZ = 14.0f;
-#endif
+ POP_MEMID();
+
+ PUSH_MEMID(MEMID_ANIMATION);
CAnimManager::Initialise();
CCutsceneMgr::Initialise();
+ POP_MEMID();
+
+ PUSH_MEMID(MEMID_CARS);
CCarCtrl::Init();
+ POP_MEMID();
+
+ PUSH_MEMID(MEMID_DEF_MODELS);
InitModelIndices();
CModelInfo::Initialise();
CPickups::Init();
CTheCarGenerators::Init();
+
CdStreamAddImage("MODELS\\GTA3.IMG");
+
CFileLoader::LoadLevel("DATA\\DEFAULT.DAT");
CFileLoader::LoadLevel(datFile);
#ifdef EXTENDED_PIPELINES
@@ -376,17 +447,21 @@ bool CGame::Initialise(const char* datFile)
CVehicleModelInfo::LoadVehicleColours();
CVehicleModelInfo::LoadEnvironmentMaps();
CTheZones::PostZoneCreation();
+ POP_MEMID();
+
LoadingScreen("Loading the Game", "Setup paths", nil);
ThePaths.PreparePathData();
for (int i = 0; i < NUMPLAYERS; i++)
CWorld::Players[i].Clear();
CWorld::Players[0].LoadPlayerSkin();
TestModelIndices();
+
LoadingScreen("Loading the Game", "Setup water", nil);
WaterLevelInitialise("DATA\\WATER.DAT");
TheConsole.Init();
CDraw::SetFOV(120.0f);
CDraw::ms_fLODDistance = 500.0f;
+
LoadingScreen("Loading the Game", "Setup streaming", nil);
CStreaming::LoadInitialVehicles();
CStreaming::LoadInitialPeds();
@@ -394,22 +469,32 @@ bool CGame::Initialise(const char* datFile)
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();
+#ifdef SCREEN_DROPLETS
+ ScreenDroplets::Initialise();
+#endif
LoadingScreen("Loading the Game", "Find big buildings", nil);
CRenderer::Init();
+
LoadingScreen("Loading the Game", "Setup game variables", nil);
CRadar::Initialise();
CRadar::LoadTextures();
CWeapon::InitialiseWeapons();
+
LoadingScreen("Loading the Game", "Setup traffic lights", nil);
CTrafficLights::ScanForLightsOnMap();
CRoadBlocks::Init();
+
LoadingScreen("Loading the Game", "Setup game variables", nil);
CPopulation::Initialise();
CWorld::PlayerInFocus = 0;
@@ -420,10 +505,16 @@ bool CGame::Initialise(const char* datFile)
CAntennas::Init();
CGlass::Init();
gPhoneInfo.Initialise();
+#ifdef GTA_SCENE_EDIT
CSceneEdit::Initialise();
+#endif
+
LoadingScreen("Loading the Game", "Load scripts", nil);
+ PUSH_MEMID(MEMID_SCRIPT);
CTheScripts::Init();
CGangs::Initialise();
+ POP_MEMID();
+
LoadingScreen("Loading the Game", "Setup game variables", nil);
CClock::Initialise(1000);
CHeli::InitHelis();
@@ -439,24 +530,26 @@ bool CGame::Initialise(const char* datFile)
CWaterCannons::Init();
CBridge::Init();
CGarages::Init();
+
LoadingScreen("Loading the Game", "Position dynamic objects", nil);
LoadingScreen("Loading the Game", "Initialise vehicle paths", nil);
+
CTrain::InitTrains();
CPlane::InitPlanes();
CCredits::Init();
CRecordDataForChase::Init();
CReplay::Init();
+
+ LoadingScreen("Loading the Game", "Start script", nil);
#ifdef PS2_MENU
if ( !TheMemoryCard.m_bWantToLoad )
- {
#endif
- LoadingScreen("Loading the Game", "Start script", nil);
- CTheScripts::StartTestScript();
- CTheScripts::Process();
- TheCamera.Process();
-#ifdef PS2_MENU
+ {
+ CTheScripts::StartTestScript();
+ CTheScripts::Process();
+ TheCamera.Process();
}
-#endif
+
LoadingScreen("Loading the Game", "Load scene", nil);
CCollision::ms_collisionInMemory = currLevel;
for (int i = 0; i < MAX_PADS; i++)
@@ -481,9 +574,7 @@ bool CGame::ShutDown(void)
CScriptPaths::Shutdown();
CWaterCreatures::RemoveAll();
CSpecialFX::Shutdown();
-#ifndef PS2
CGarages::Shutdown();
-#endif
CMovingThings::Shutdown();
gPhoneInfo.Shutdown();
CWeapon::ShutdownWeapons();
@@ -537,13 +628,11 @@ void CGame::ReInitGameObjectVariables(void)
CGameLogic::InitAtStartOfGame();
#ifdef PS2_MENU
if ( !TheMemoryCard.m_bWantToLoad )
- {
#endif
- TheCamera.Init();
- TheCamera.SetRwCamera(Scene.camera);
-#ifdef PS2_MENU
+ {
+ TheCamera.Init();
+ TheCamera.SetRwCamera(Scene.camera);
}
-#endif
CDebug::DebugInitTextBuffer();
CWeather::Init();
CUserDisplay::Init();
@@ -552,11 +641,6 @@ void CGame::ReInitGameObjectVariables(void)
CWorld::bDoingCarCollisions = false;
CHud::ReInitialise();
CRadar::Initialise();
-#ifdef PS2
- gStartX = -180.0f;
- gStartY = 180.0f;
- gStartZ = 14.0f;
-#endif
CCarCtrl::ReInit();
CTimeCycle::Initialise();
CDraw::SetFOV(120.0f);
@@ -568,6 +652,9 @@ void CGame::ReInitGameObjectVariables(void)
currArea = AREA_MAIN_MAP;
CPed::Initialise();
CEventList::Initialise();
+#ifdef SCREEN_DROPLETS
+ ScreenDroplets::Initialise();
+#endif
CWeapon::InitialiseWeapons();
CPopulation::Initialise();
@@ -575,15 +662,15 @@ void CGame::ReInitGameObjectVariables(void)
CWorld::Players[i].Clear();
CWorld::PlayerInFocus = 0;
-#ifdef PS2
- CWeaponEffects::Init();
- CSkidmarks::Init();
-#endif
CAntennas::Init();
CGlass::Init();
gPhoneInfo.Initialise();
+
+ PUSH_MEMID(MEMID_SCRIPT);
CTheScripts::Init();
CGangs::Initialise();
+ POP_MEMID();
+
CTimer::Initialise();
CClock::Initialise(1000);
CTheCarGenerators::Init();
@@ -594,10 +681,6 @@ void CGame::ReInitGameObjectVariables(void)
CPickups::Init();
CPacManPickups::Init();
CGarages::Init();
-#ifdef PS2
- CClouds::Init();
- CRemote::Init();
-#endif
CSpecialFX::Init();
CRopes::Init();
CWaterCannons::Init();
@@ -667,8 +750,10 @@ void CGame::InitialiseWhenRestarting(void)
if (b_FoundRecentSavedGameWantToLoad || FrontEndMenuManager.m_bWantToLoad)
{
LoadSplash("splash1");
+#ifndef XBOX_MESSAGE_SCREEN
if (FrontEndMenuManager.m_bWantToLoad)
FrontEndMenuManager.MessageScreen("FELD_WR", true);
+#endif
}
b_FoundRecentSavedGameWantToLoad = false;
@@ -677,6 +762,14 @@ void CGame::InitialiseWhenRestarting(void)
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();
}
@@ -685,8 +778,7 @@ void CGame::InitialiseWhenRestarting(void)
if ( FrontEndMenuManager.m_bWantToLoad == true )
{
FrontEndMenuManager.m_bWantToLoad = false;
- // TODO(Miami)
- //InitRadioStationPositionList();
+ InitRadioStationPositionList();
if ( GenericLoad() == true )
{
DMAudio.ResetTimers(CTimer::GetTimeInMilliseconds());
@@ -710,6 +802,9 @@ void CGame::InitialiseWhenRestarting(void)
currLevel = LEVEL_GENERIC;
CCollision::SortOutCollisionAfterLoad();
}
+#ifdef XBOX_MESSAGE_SCREEN
+ FrontEndMenuManager.ProcessDialogTimer();
+#endif
}
CTimer::Update();
@@ -723,15 +818,17 @@ void CGame::InitialiseWhenRestarting(void)
void CGame::Process(void)
{
CPad::UpdatePads();
-#ifdef GTA_PS2
+#ifdef USE_CUSTOM_ALLOCATOR
ProcessTidyUpMemory();
#endif
#ifdef DEBUGMENU
DebugMenuProcess();
#endif
CCutsceneMgr::Update();
+
if (!CCutsceneMgr::IsCutsceneProcessing() && !CTimer::GetIsCodePaused())
FrontEndMenuManager.Process();
+
CTheZones::Update();
// DRM call in here
uint32 startTime = CTimer::GetCurrentTimeInCycles() / CTimer::GetCyclesPerMillisecond();
@@ -748,7 +845,11 @@ void CGame::Process(void)
CPad::DoCheats();
CClock::Update();
CWeather::Update();
+
+ PUSH_MEMID(MEMID_SCRIPT);
CTheScripts::Process();
+ POP_MEMID();
+
CCollision::Update();
CScriptPaths::Update();
CTrain::UpdateTrains();
@@ -758,7 +859,9 @@ void CGame::Process(void)
CSkidmarks::Update();
CAntennas::Update();
CGlass::Update();
+#ifdef GTA_SCENE_EDIT
CSceneEdit::Update();
+#endif
CSetPieces::Update();
CEventList::Update();
CParticle::Update();
@@ -780,7 +883,11 @@ void CGame::Process(void)
CWaterCannons::Update();
CUserDisplay::Process();
CReplay::Update();
+
+ PUSH_MEMID(MEMID_WORLD);
CWorld::Process();
+ POP_MEMID();
+
gAccidentManager.Update();
CPacManPickups::Update();
CPickups::Update();
@@ -802,62 +909,399 @@ void CGame::Process(void)
gPhoneInfo.Update();
if (!CReplay::IsPlayingBack())
{
+ PUSH_MEMID(MEMID_CARS);
if (processTime < 2)
CCarCtrl::GenerateRandomCars();
CRoadBlocks::GenerateRoadBlocks();
CCarCtrl::RemoveDistantCars();
CCarCtrl::RemoveCarsIfThePoolGetsFull();
+ POP_MEMID();
}
}
+#ifdef GTA_PS2
+ CMemCheck::DoTest();
+#endif
}
-void
-CGame::InitAfterFocusLoss()
+#ifdef USE_CUSTOM_ALLOCATOR
+
+// TODO(MIAMI)
+
+int32 gNumMemMoved;
+
+bool
+MoveMem(void** ptr)
{
- FrontEndMenuManager.m_nPrefsAudio3DProviderIndex = FrontEndMenuManager.m_lastWorking3DAudioProvider;
- DMAudio.SetCurrent3DProvider(FrontEndMenuManager.m_lastWorking3DAudioProvider);
+ if (*ptr) {
+ gNumMemMoved++;
+ void* newPtr = gMainHeap.MoveMemory(*ptr);
+ if (*ptr != newPtr) {
+ *ptr = newPtr;
+ return true;
+ }
+ }
+ return false;
+}
- if (!FrontEndMenuManager.m_bGameNotLoaded && !FrontEndMenuManager.m_bMenuActive)
- FrontEndMenuManager.m_bStartUpFrontEndRequested = true;
+// Some convenience structs
+struct SkyDataPrefix
+{
+ uint32 pktSize1;
+ uint32 data; // pointer to data as read from TXD
+ uint32 pktSize2;
+ uint32 unused;
+};
+
+struct DMAGIFUpload
+{
+ uint32 tag1_qwc, tag1_addr; // dmaref
+ uint32 nop1, vif_direct1;
+
+ uint32 giftag[4];
+ uint32 gs_bitbltbuf[4];
+
+ uint32 tag2_qwc, tag2_addr; // dmaref
+ uint32 nop2, vif_direct2;
+};
+
+// This is very scary. it depends on the exact memory layout of the DMA chains and whatnot
+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)
+ return texture;
+
+ // this is the allocated pointer we will move
+ 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,
+ // and the palette if there is one.
+ // NB: this code does NOT support mipmaps!
+ // so we assume two uploads (pixels and palette)
+ //
+ // each upload looks like this:
+ // (DMAcnt; NOP; VIF DIRECT(2))
+ // giftag (1, A+D)
+ // GS_BITBLTBUF
+ // (DMAref->pixel data; NOP; VIF DIRECT(5))
+ // the DMArefs are what we have to adjust
+ uintptr dataDiff, upload1Diff, upload2Diff, pixelDiff, paletteDiff;
+ dataDiff = prefix->data - (uintptr)raster->originalPixels;
+ upload1Diff = uploads[0].tag2_addr - (uintptr)raster->originalPixels;
+ if (raster->palette)
+ upload2Diff = uploads[1].tag2_addr - (uintptr)raster->originalPixels;
+ pixelDiff = (uintptr)raster->cpPixels - (uintptr)raster->originalPixels;
+ if (raster->palette)
+ paletteDiff = (uintptr)raster->palette - (uintptr)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)
+ uploads[1].tag2_addr = (uintptr)newptr + upload2Diff;
+ raster->originalPixels = newptr;
+ raster->cpPixels = newptr + pixelDiff;
+ if (raster->palette)
+ raster->palette = newptr + paletteDiff;
+
+ if (pRet) {
+ *pRet = true;
+ return nil;
+ }
+ }
+#else
+ // nothing to do here really, everything should be in videomemory
+#endif
+ return texture;
}
bool
-CGame::CanSeeWaterFromCurrArea(void)
+MoveAtomicMemory(RpAtomic* atomic, bool onlyOne)
{
- return currArea == AREA_MAIN_MAP || currArea == AREA_MANSION
- || currArea == AREA_HOTEL;
+ RpGeometry* geo = RpAtomicGetGeometry(atomic);
+
+#if THIS_IS_COMPATIBLE_WITH_GTA3_RW31
+ if (MoveMem((void**)&geo->triangles) && onlyOne)
+ return true;
+ if (MoveMem((void**)&geo->matList.materials) && onlyOne)
+ return true;
+ if (MoveMem((void**)&geo->preLitLum) && onlyOne)
+ return true;
+ if (MoveMem((void**)&geo->texCoords[0]) && onlyOne)
+ return true;
+ if (MoveMem((void**)&geo->texCoords[1]) && onlyOne)
+ return true;
+
+ // verts and normals of morph target are allocated together
+ int vertDiff;
+ if (geo->morphTarget->normals)
+ vertDiff = geo->morphTarget->normals - geo->morphTarget->verts;
+ if (MoveMem((void**)&geo->morphTarget->verts)) {
+ if (geo->morphTarget->normals)
+ geo->morphTarget->normals = geo->morphTarget->verts + vertDiff;
+ if (onlyOne)
+ return true;
+ }
+
+ 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);
+ uintptr reloc = (uintptr)geo->mesh - (uintptr)oldmesh;
+ for (int i = 0; i < geo->mesh->numMeshes; i++)
+ mesh[i].indices = (RxVertexIndex*)((uintptr)mesh[i].indices + reloc);
+ if (onlyOne)
+ return true;
+ }
+#else
+ // we could do something in librw here
+#endif
+ return false;
}
bool
-CGame::CanSeeOutSideFromCurrArea(void)
+MoveColModelMemory(CColModel& colModel, bool onlyOne)
{
- return currArea == AREA_MAIN_MAP || currArea == AREA_MALL ||
- currArea == AREA_MANSION || currArea == AREA_HOTEL;
+#if GTA_VERSION >= GTA3_PS2_160
+ // hm...should probably only do this if ownsCollisionVolumes
+ // but it doesn't exist on PS2...
+ if (!colModel.ownsCollisionVolumes)
+ return false;
+#endif
+
+ if (MoveMem((void**)&colModel.spheres) && onlyOne)
+ return true;
+ if (MoveMem((void**)&colModel.lines) && onlyOne)
+ return true;
+ if (MoveMem((void**)&colModel.boxes) && onlyOne)
+ return true;
+ if (MoveMem((void**)&colModel.vertices) && onlyOne)
+ return true;
+ if (MoveMem((void**)&colModel.triangles) && onlyOne)
+ return true;
+ if (MoveMem((void**)&colModel.trianglePlanes) && onlyOne)
+ return true;
+ return false;
}
-void CGame::DrasticTidyUpMemory(bool)
+RpAtomic*
+MoveAtomicMemoryCB(RpAtomic* atomic, void* pData)
{
-#ifdef USE_TEXTURE_POOL
- // TODO
+ bool* pRet = (bool*)pData;
+ if (pRet == nil)
+ MoveAtomicMemory(atomic, false);
+ else if (MoveAtomicMemory(atomic, true)) {
+ *pRet = true;
+ return nil;
+ }
+ return atomic;
+}
+
+bool
+TidyUpModelInfo(CBaseModelInfo* modelInfo, bool 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))
+ return true;
+ if (RwObjectGetType(rwobj) == rpCLUMP) {
+ bool ret = false;
+ if (onlyone)
+ RpClumpForAllAtomics((RpClump*)rwobj, MoveAtomicMemoryCB, &ret);
+ else
+ RpClumpForAllAtomics((RpClump*)rwobj, MoveAtomicMemoryCB, nil);
+ if (ret)
+ return true;
+ }
+
+ if (modelInfo->GetModelType() == MITYPE_PED && ((CPedModelInfo*)modelInfo)->m_hitColModel)
+ if (MoveColModelMemory(*((CPedModelInfo*)modelInfo)->m_hitColModel, onlyone))
+ return true;
+
+ return false;
+}
#endif
-#ifdef PS2
- // meow
+
+
+void CGame::DrasticTidyUpMemory(bool flushDraw)
+{
+#ifdef USE_CUSTOM_ALLOCATOR
+ bool removedCol = false;
+
+ TidyUpMemory(true, flushDraw);
+
+ 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) {
+ CModelInfo::RemoveColModelsFromOtherLevels(LEVEL_GENERIC);
+ TidyUpMemory(true, flushDraw);
+ removedCol = true;
+ }
+
+ if (gMainHeap.GetLargestFreeBlock() < 200000 && !playingIntro) {
+ CStreaming::RemoveBigBuildings(LEVEL_INDUSTRIAL);
+ CStreaming::RemoveBigBuildings(LEVEL_COMMERCIAL);
+ CStreaming::RemoveBigBuildings(LEVEL_SUBURBAN);
+ TidyUpMemory(true, flushDraw);
+ }
+
+ if (removedCol) {
+ // different on PS2
+ CFileLoader::LoadCollisionFromDatFile(CCollision::ms_collisionInMemory);
+ }
+
+ if (!playingIntro)
+ CStreaming::RequestBigBuildings(currLevel);
+
+ CStreaming::LoadAllRequestedModels(true);
#endif
}
-void CGame::TidyUpMemory(bool unk1, bool unk2)
+void CGame::TidyUpMemory(bool moveTextures, bool flushDraw)
{
-#ifdef PS2
- // meow
+#ifdef USE_CUSTOM_ALLOCATOR
+ printf("Largest free block before tidy %d\n", gMainHeap.GetLargestFreeBlock());
+
+ if (moveTextures) {
+ if (flushDraw) {
+#ifdef GTA_PS2
+ for (int i = 0; i < sweMaxFlips + 1; i++) {
+#else
+ 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)
+ continue;
+ 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)
+ continue; // cannot happen
+ anim->MoveMemory();
+ }
+
+ // model info
+ 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
- if (unk2) {
- DrasticTidyUpMemory(true); // parameter is unknown too
}
-}
void CGame::ProcessTidyUpMemory(void)
{
-#ifdef PS2
- // meow
+#ifdef USE_CUSTOM_ALLOCATOR
+ static int32 modelIndex = 0;
+ static int32 animIndex = 0;
+ static int32 txdIndex = 0;
+ bool txdReturn = false;
+ RwTexDictionary* txd = nil;
+ gNumMemMoved = 0;
+
+ // model infos
+ for (int numCleanedUp = 0; numCleanedUp < 10; numCleanedUp++) {
+ CBaseModelInfo* mi;
+ do {
+ mi = CModelInfo::GetModelInfo(modelIndex);
+ modelIndex++;
+ if (modelIndex >= MODELINFOSIZE)
+ modelIndex = 0;
+ } while (mi == nil);
+
+ if (TidyUpModelInfo(mi, true))
+ return;
+ }
+
+ // tex dicts
+ for (int numCleanedUp = 0; numCleanedUp < 3; numCleanedUp++) {
+ if (gNumMemMoved > 80)
+ break;
+
+ do {
+#ifdef FIX_BUGS
+ txd = nil;
#endif
+ if (CTxdStore::GetSlot(txdIndex))
+ txd = CTxdStore::GetSlot(txdIndex)->texDict;
+ txdIndex++;
+ if (txdIndex >= TXDSTORESIZE)
+ txdIndex = 0;
+ } while (txd == nil);
+
+ RwTexDictionaryForAllTextures(txd, MoveTextureMemoryCB, &txdReturn);
+ if (txdReturn)
+ return;
+ }
+
+ // animations
+ CAnimBlendHierarchy* anim;
+ do {
+ anim = CAnimManager::GetAnimation(animIndex);
+ animIndex++;
+ if (animIndex >= NUMANIMATIONS)
+ animIndex = 0;
+ } 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/General.h b/src/core/General.h
index 7e06b96e..69492fb8 100644
--- a/src/core/General.h
+++ b/src/core/General.h
@@ -123,6 +123,15 @@ public:
return *str2 != '\0';
}
+ static bool faststrncmp(const char *str1, const char *str2, uint32 count)
+ {
+ for(uint32 i = 0; *str1 && i < count; str1++, str2++, i++) {
+ if (*str1 != *str2)
+ return true;
+ }
+ return false;
+ }
+
static bool faststricmp(const char *str1, const char *str2)
{
for (; *str1; str1++, str2++) {
diff --git a/src/core/MenuScreens.cpp b/src/core/MenuScreens.cpp
index 11cd3078..173de805 100644
--- a/src/core/MenuScreens.cpp
+++ b/src/core/MenuScreens.cpp
@@ -2,44 +2,10 @@
#include "Frontend.h"
#ifdef PC_MENU
-#ifdef CUTSCENE_BORDERS_SWITCH
-#define MENU_CUTSCENE_BORDERS_SWITCH(screen) MENUACTION_CUTSCENEBORDERS, "FEM_CSB", SAVESLOT_NONE, screen,
-#else
-#define MENU_CUTSCENE_BORDERS_SWITCH(screen)
-#endif
-
-#ifdef IMPROVED_VIDEOMODE
-#define MENU_IMPROVED_VIDEOMODE(screen) MENUACTION_SCREENFORMAT, "FEM_SCF", SAVESLOT_NONE, screen,
-#else
-#define MENU_IMPROVED_VIDEOMODE(screen)
-#endif
-
-#ifdef ANISOTROPIC_FILTERING
-#define MENU_MIPMAPS(screen) MENUACTION_MIPMAPS, "FED_MIP", SAVESLOT_NONE, screen,
-#define MENU_TEXTURE_FILTERING(screen) MENUACTION_TEXTURE_FILTERING, "FED_FIL", SAVESLOT_NONE, screen,
-#else
-#define MENU_MIPMAPS(screen)
-#define MENU_TEXTURE_FILTERING(screen)
-#endif
-
-#ifdef MULTISAMPLING
-#define MENU_MULTISAMPLING(screen) MENUACTION_MULTISAMPLING, "FED_AAS", SAVESLOT_NONE, screen,
-#else
-#define MENU_MULTISAMPLING(screen)
-#endif
-
-#ifdef NO_ISLAND_LOADING
-#define MENU_ISLAND_LOADING(screen) MENUACTION_ISLANDLOADING, "FEM_ISL", SAVESLOT_NONE, screen,
-#else
-#define MENU_ISLAND_LOADING(screen)
-#endif
-
-#ifdef PS2_ALPHA_TEST
-#define MENU_PS2_ALPHA_TEST(screen) MENUACTION_PS2_ALPHA_TEST, "FEM_2PR", SAVESLOT_NONE, screen,
-#else
-#define MENU_PS2_ALPHA_TEST(screen)
-#endif
+// Please don't touch this file, except for bug fixing or ports.
+// Check MenuScreensCustom.cpp
+#ifndef CUSTOM_FRONTEND_OPTIONS
CMenuScreen aScreens[] = {
// MENUPAGE_STATS = 0
{ "FEH_STA", MENUPAGE_NONE, 3,
@@ -72,7 +38,7 @@ CMenuScreen aScreens[] = {
MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, MENUALIGN_CENTER,
},
- // MENUPAGE_GRAPHICS_SETTINGS = 4
+ // MENUPAGE_DISPLAY_SETTINGS = 4
#ifdef LEGACY_MENU_OPTIONS
#define Y_OFFSET 50
#else
@@ -95,14 +61,8 @@ CMenuScreen aScreens[] = {
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,
-#ifdef IMPROVED_VIDEOMODE
- MENUACTION_SCREENFORMAT,"FED_POS", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS, 40, 303 + Y_OFFSET, MENUALIGN_LEFT,
- MENUACTION_RESTOREDEF, "FET_DEF", SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS, 320, 328 + Y_OFFSET, MENUALIGN_CENTER,
- MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 320, 353 + Y_OFFSET, MENUALIGN_CENTER,
-#else
- MENUACTION_RESTOREDEF, "FET_DEF", SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS, 320, 303 + Y_OFFSET, MENUALIGN_CENTER,
+ 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,
-#endif
},
#undef Y_OFFSET
@@ -255,7 +215,9 @@ CMenuScreen aScreens[] = {
// MENUPAGE_CONTROLLER_PC = 26
{ "FET_CTL", MENUPAGE_OPTIONS, 0,
+#ifdef PC_PLAYER_CONTROLS
MENUACTION_CTRLMETHOD, "FET_STI", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC, 320, 150, MENUALIGN_CENTER,
+#endif
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,
@@ -286,10 +248,8 @@ CMenuScreen aScreens[] = {
MENUACTION_CHANGEMENU, "FEP_QUI", SAVESLOT_NONE, MENUPAGE_EXIT, 0, 0, MENUALIGN_CENTER,
},
- // TODO(Miami)
// MENUPAGE_KEYBOARD_CONTROLS = 30
{ "FET_STI", MENUPAGE_CONTROLLER_PC, 1,
- MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC, 0, 0, 0,
},
// MENUPAGE_MOUSE_CONTROLS = 31
@@ -314,18 +274,15 @@ CMenuScreen aScreens[] = {
// MENUPAGE_NONE = 33
{ "", 0, 0, },
- // MENUPAGE_OUTRO = 34
- { "", 0, 0, },
-
#ifdef LEGACY_MENU_OPTIONS
- // MENUPAGE_CONTROLLER_SETTINGS = 4
+ // 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_DEBUG_MENU = 18
+ // 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,
@@ -334,7 +291,7 @@ CMenuScreen aScreens[] = {
MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, 0,
},
- // MENUPAGE_CONTROLLER_PC_OLD1 = 36
+ // 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,
@@ -348,12 +305,12 @@ CMenuScreen aScreens[] = {
MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, 0,
},
- // MENUPAGE_CONTROLLER_PC_OLD2 = 37
+ // MENUPAGE_CONTROLLER_PC_OLD2
{ "FET_CTL", MENUPAGE_CONTROLLER_PC, 1,
},
- // MENUPAGE_CONTROLLER_PC_OLD3 = 38
+ // 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,
@@ -362,12 +319,12 @@ CMenuScreen aScreens[] = {
MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, 0,
},
- // MENUPAGE_CONTROLLER_PC_OLD4 = 39
+ // MENUPAGE_CONTROLLER_PC_OLD4
{ "FET_CTL", MENUPAGE_CONTROLLER_PC, 3,
},
- // MENUPAGE_CONTROLLER_DEBUG = 40
+ // 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,
@@ -376,6 +333,10 @@ CMenuScreen aScreens[] = {
MENUACTION_GOBACK, "FEDS_TB", SAVESLOT_NONE, MENUPAGE_NONE, 0, 0, 0,
},
#endif
+
+ // MENUPAGE_OUTRO - Originally 34
+ { "", 0, 0, },
};
#endif
+#endif
diff --git a/src/core/MenuScreensCustom.cpp b/src/core/MenuScreensCustom.cpp
new file mode 100644
index 00000000..96e3be07
--- /dev/null
+++ b/src/core/MenuScreensCustom.cpp
@@ -0,0 +1,716 @@
+#include "common.h"
+#include "platform.h"
+#include "crossplatform.h"
+#include "Renderer.h"
+#include "Frontend.h"
+#include "Font.h"
+#include "Camera.h"
+#include "main.h"
+#include "MBlur.h"
+#include "postfx.h"
+#include "custompipes.h"
+#include "RwHelper.h"
+#include "Text.h"
+#include "Streaming.h"
+#include "FileLoader.h"
+#include "Collision.h"
+#include "ModelInfo.h"
+#include "Pad.h"
+
+// Menu screens array is at the bottom of the file.
+
+#ifdef PC_MENU
+
+#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) }, 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) }, 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 *)&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) }, 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) }, 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*)&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) }, 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 INVERT_LOOK_FOR_PAD
+ #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
+
+const char *filterNames[] = { "FEM_NON", "FEM_SIM", "FEM_NRM", "FEM_MOB" };
+const char *off_on[] = { "FEM_OFF", "FEM_ON" };
+
+void RestoreDefGraphics(int8 action) {
+ if (action != FEOPTION_ACTION_SELECT)
+ return;
+
+ #ifdef PS2_ALPHA_TEST
+ gPS2alphaTest = false;
+ #endif
+ #ifdef MULTISAMPLING
+ FrontEndMenuManager.m_nPrefsMSAALevel = FrontEndMenuManager.m_nDisplayMSAALevel = 0;
+ #endif
+ #ifdef NO_ISLAND_LOADING
+ if (!FrontEndMenuManager.m_bGameNotLoaded) {
+ FrontEndMenuManager.m_PrefsIslandLoading = FrontEndMenuManager.ISLAND_LOADING_LOW;
+ CStreaming::RemoveUnusedBigBuildings(CGame::currLevel);
+ CStreaming::RemoveUnusedBuildings(CGame::currLevel);
+ CStreaming::RequestIslands(CGame::currLevel);
+ CStreaming::LoadAllRequestedModels(true);
+ } else
+ FrontEndMenuManager.m_PrefsIslandLoading = FrontEndMenuManager.ISLAND_LOADING_LOW;
+ #endif
+ #ifdef GRAPHICS_MENU_OPTIONS // otherwise Frontend will handle those
+ 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
+}
+
+void RestoreDefDisplay(int8 action) {
+ if (action != FEOPTION_ACTION_SELECT)
+ return;
+
+ #ifdef CUTSCENE_BORDERS_SWITCH
+ FrontEndMenuManager.m_PrefsCutsceneBorders = true;
+ #endif
+ #ifdef FREE_CAM
+ TheCamera.bFreeCam = false;
+ #endif
+ #ifdef GRAPHICS_MENU_OPTIONS // otherwise Frontend will handle those
+ FrontEndMenuManager.m_PrefsBrightness = 256;
+ FrontEndMenuManager.m_PrefsLOD = 1.2f;
+ CRenderer::ms_lodDistScale = 1.2f;
+ FrontEndMenuManager.m_PrefsShowSubtitles = false;
+ FrontEndMenuManager.m_PrefsShowLegends = true;
+ FrontEndMenuManager.m_PrefsRadarMode = 0;
+ FrontEndMenuManager.m_PrefsShowHud = true;
+ FrontEndMenuManager.SaveSettings();
+ #endif
+}
+
+#ifdef NO_ISLAND_LOADING
+const char *islandLoadingOpts[] = { "FEM_LOW", "FEM_MED", "FEM_HIG" };
+void IslandLoadingAfterChange(int8 before, int8 after) {
+ if (!FrontEndMenuManager.m_bGameNotLoaded) {
+ if (after > FrontEndMenuManager.ISLAND_LOADING_LOW) {
+ FrontEndMenuManager.m_PrefsIslandLoading = before; // calls below needs previous mode :shrug:
+
+ if (after == FrontEndMenuManager.ISLAND_LOADING_HIGH) {
+ CStreaming::RemoveIslandsNotUsed(LEVEL_BEACH);
+ CStreaming::RemoveIslandsNotUsed(LEVEL_MAINLAND);
+ }
+ if (before == FrontEndMenuManager.ISLAND_LOADING_LOW) {
+ FrontEndMenuManager.m_PrefsIslandLoading = after;
+ CStreaming::RequestBigBuildings(CGame::currLevel);
+
+ } else if (before == FrontEndMenuManager.ISLAND_LOADING_HIGH) {
+ FrontEndMenuManager.m_PrefsIslandLoading = after;
+ CStreaming::RequestIslands(CGame::currLevel);
+ } else
+ FrontEndMenuManager.m_PrefsIslandLoading = after;
+
+ } else { // low
+ CStreaming::RemoveUnusedBigBuildings(CGame::currLevel);
+ CStreaming::RemoveUnusedBuildings(CGame::currLevel);
+ CStreaming::RequestIslands(CGame::currLevel);
+ }
+
+ CStreaming::LoadAllRequestedModels(true);
+ }
+
+ FrontEndMenuManager.SetHelperText(0);
+}
+#endif
+
+#ifdef MORE_LANGUAGES
+void LangPolSelect(int8 action)
+{
+ if (action == FEOPTION_ACTION_SELECT) {
+ FrontEndMenuManager.m_PrefsLanguage = CMenuManager::LANGUAGE_POLISH;
+ FrontEndMenuManager.m_bFrontEnd_ReloadObrTxtGxt = true;
+ FrontEndMenuManager.InitialiseChangedLanguageSettings();
+ FrontEndMenuManager.SaveSettings();
+ }
+}
+
+void LangRusSelect(int8 action)
+{
+ if (action == FEOPTION_ACTION_SELECT) {
+ FrontEndMenuManager.m_PrefsLanguage = CMenuManager::LANGUAGE_RUSSIAN;
+ FrontEndMenuManager.m_bFrontEnd_ReloadObrTxtGxt = true;
+ FrontEndMenuManager.InitialiseChangedLanguageSettings();
+ FrontEndMenuManager.SaveSettings();
+ }
+}
+
+void LangJapSelect(int8 action)
+{
+ if (action == FEOPTION_ACTION_SELECT) {
+ FrontEndMenuManager.m_PrefsLanguage = CMenuManager::LANGUAGE_JAPANESE;
+ FrontEndMenuManager.m_bFrontEnd_ReloadObrTxtGxt = true;
+ FrontEndMenuManager.InitialiseChangedLanguageSettings();
+ FrontEndMenuManager.SaveSettings();
+ }
+}
+#endif
+
+#ifndef MULTISAMPLING
+void GraphicsGoBack() {
+}
+#else
+void GraphicsGoBack() {
+ FrontEndMenuManager.m_nDisplayMSAALevel = FrontEndMenuManager.m_nPrefsMSAALevel;
+}
+
+void MultiSamplingButtonPress(int8 action) {
+ if (action == FEOPTION_ACTION_SELECT) {
+ if (FrontEndMenuManager.m_nDisplayMSAALevel != FrontEndMenuManager.m_nPrefsMSAALevel) {
+ FrontEndMenuManager.m_nPrefsMSAALevel = FrontEndMenuManager.m_nDisplayMSAALevel;
+ _psSelectScreenVM(FrontEndMenuManager.m_nPrefsVideoMode);
+ FrontEndMenuManager.SetHelperText(0);
+ FrontEndMenuManager.SaveSettings();
+ }
+ } else if (action == FEOPTION_ACTION_LEFT || action == FEOPTION_ACTION_RIGHT) {
+ if (FrontEndMenuManager.m_bGameNotLoaded) {
+ FrontEndMenuManager.m_nDisplayMSAALevel += (action == FEOPTION_ACTION_RIGHT ? 1 : -1);
+
+ int i = 0;
+ int maxAA = RwD3D8EngineGetMaxMultiSamplingLevels();
+ while (maxAA != 1) {
+ i++;
+ maxAA >>= 1;
+ }
+
+ if (FrontEndMenuManager.m_nDisplayMSAALevel < 0)
+ FrontEndMenuManager.m_nDisplayMSAALevel = i;
+ else if (FrontEndMenuManager.m_nDisplayMSAALevel > i)
+ FrontEndMenuManager.m_nDisplayMSAALevel = 0;
+ }
+ } else if (action == FEOPTION_ACTION_FOCUSLOSS) {
+ if (FrontEndMenuManager.m_nDisplayMSAALevel != FrontEndMenuManager.m_nPrefsMSAALevel) {
+ FrontEndMenuManager.m_nDisplayMSAALevel = FrontEndMenuManager.m_nPrefsMSAALevel;
+ FrontEndMenuManager.SetHelperText(3);
+ }
+ }
+}
+
+wchar* MultiSamplingDraw(bool *disabled, bool userHovering) {
+ static wchar unicodeTemp[64];
+ if (userHovering) {
+ if (FrontEndMenuManager.m_nDisplayMSAALevel == FrontEndMenuManager.m_nPrefsMSAALevel) {
+ if (FrontEndMenuManager.m_nHelperTextMsgId == 1) // Press enter to apply
+ FrontEndMenuManager.ResetHelperText();
+ } else {
+ FrontEndMenuManager.SetHelperText(1);
+ }
+ } else {
+ if (FrontEndMenuManager.m_nDisplayMSAALevel != FrontEndMenuManager.m_nPrefsMSAALevel) {
+ FrontEndMenuManager.m_nDisplayMSAALevel = FrontEndMenuManager.m_nPrefsMSAALevel;
+ }
+ }
+
+ if (!FrontEndMenuManager.m_bGameNotLoaded)
+ *disabled = true;
+
+ switch (FrontEndMenuManager.m_nDisplayMSAALevel) {
+ case 0:
+ return TheText.Get("FEM_OFF");
+ default:
+ sprintf(gString, "%iX", 1 << (FrontEndMenuManager.m_nDisplayMSAALevel));
+ AsciiToUnicode(gString, unicodeTemp);
+ return unicodeTemp;
+ }
+}
+#endif
+
+#ifdef IMPROVED_VIDEOMODE
+const char* screenModes[] = { "FED_FLS", "FED_WND" };
+void ScreenModeAfterChange(int8 before, int8 after)
+{
+ _psSelectScreenVM(FrontEndMenuManager.m_nPrefsVideoMode); // apply same resolution
+ FrontEndMenuManager.SetHelperText(0);
+}
+
+#endif
+
+#ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS
+wchar selectedJoystickUnicode[128];
+
+wchar* DetectJoystickDraw(bool* disabled, bool userHovering) {
+ int numButtons;
+ int found = -1;
+ const char *joyname;
+ if (userHovering) {
+ for (int i = 0; i <= GLFW_JOYSTICK_LAST; i++) {
+ if ((joyname = glfwGetJoystickName(i))) {
+ const uint8* buttons = glfwGetJoystickButtons(i, &numButtons);
+ for (int j = 0; j < numButtons; j++) {
+ if (buttons[j]) {
+ found = i;
+ break;
+ }
+ }
+ if (found != -1)
+ break;
+ }
+ }
+
+ if (found != -1 && PSGLOBAL(joy1id) != found) {
+ if (PSGLOBAL(joy1id) != -1 && PSGLOBAL(joy1id) != found)
+ PSGLOBAL(joy2id) = PSGLOBAL(joy1id);
+ else
+ PSGLOBAL(joy2id) = -1;
+
+ strcpy(gSelectedJoystickName, joyname);
+ PSGLOBAL(joy1id) = found;
+ }
+ }
+ if (PSGLOBAL(joy1id) == -1)
+ AsciiToUnicode("Not found", selectedJoystickUnicode);
+ else
+ AsciiToUnicode(gSelectedJoystickName, selectedJoystickUnicode);
+
+ return selectedJoystickUnicode;
+}
+#endif
+
+CMenuScreenCustom aScreens[] = {
+ // MENUPAGE_STATS = 0
+ { "FEH_STA", MENUPAGE_NONE, nil, nil,
+ MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 190, 320, MENUALIGN_RIGHT,
+ },
+
+ // MENUPAGE_NEW_GAME = 1
+ { "FEP_STG", MENUPAGE_NONE, nil, nil,
+ MENUACTION_CHANGEMENU, "FES_NGA", {nil, SAVESLOT_NONE, MENUPAGE_NEW_GAME_RELOAD}, 320, 155, MENUALIGN_CENTER,
+ MENUACTION_CHANGEMENU, "FES_LOA", {nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_LOAD_SLOT}, 0, 0, MENUALIGN_CENTER,
+ MENUACTION_CHANGEMENU, "FES_DEL", {nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_DELETE_SLOT}, 0, 0, MENUALIGN_CENTER,
+ MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, 0}, 0, 0, MENUALIGN_CENTER,
+ },
+
+ // MENUPAGE_BRIEFS = 2
+ { "FEH_BRI", MENUPAGE_NONE, nil, nil,
+ MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 190, 320, MENUALIGN_RIGHT,
+ },
+
+ // 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
+ { "FEH_DIS", MENUPAGE_OPTIONS, new CCustomScreenLayout({40, 78, 25, true}), nil,
+ MENUACTION_BRIGHTNESS, "FED_BRI", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_DRAWDIST, "FEM_LOD", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT,
+#ifdef LEGACY_MENU_OPTIONS
+ MENUACTION_FRAMESYNC, "FEM_VSC", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT,
+#endif
+ MENUACTION_FRAMELIMIT, "FEM_FRM", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT,
+#if defined LEGACY_MENU_OPTIONS && !defined EXTENDED_COLOURFILTER
+ MENUACTION_TRAILS, "FED_TRA", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT,
+#endif
+ MENUACTION_SUBTITLES, "FED_SUB", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_WIDESCREEN, "FED_WIS", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_LEGENDS, "MAP_LEG", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_RADARMODE, "FED_RDR", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_HUD, "FED_HUD", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_SCREENRES, "FED_RES", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 0, 0, MENUALIGN_LEFT,
+ VIDEOMODE_SELECTOR
+ MULTISAMPLING_SELECTOR
+ ISLAND_LOADING_SELECTOR
+ DUALPASS_SELECTOR
+ CUTSCENE_BORDERS_TOGGLE
+ FREE_CAM_TOGGLE
+ POSTFX_SELECTORS
+ // re3.cpp inserts here pipeline selectors if neo/neo.txd exists and EXTENDED_PIPELINES defined
+ MENUACTION_RESTOREDEF, "FET_DEF", {nil, SAVESLOT_NONE, MENUPAGE_DISPLAY_SETTINGS}, 320, 0, MENUALIGN_CENTER,
+ MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 320, 0, MENUALIGN_CENTER,
+ },
+#else
+ { "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_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 = 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) }, 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_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 0, 0, MENUALIGN_CENTER,
+ },
+
+ // MENUPAGE_MAP = 6
+ { "FEH_MAP", MENUPAGE_NONE, nil, nil,
+ MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_NONE}, 70, 380, MENUALIGN_CENTER,
+ },
+
+ // 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_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_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_LOAD_SLOT_CONFIRM = 10
+ { "FET_LG", MENUPAGE_CHOOSE_LOAD_SLOT, nil, nil,
+ MENUACTION_LABEL, "FESZ_QL", {nil, SAVESLOT_NONE, 0}, 0, 0, 0,
+ MENUACTION_NO, "FEM_NO", {nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_LOAD_SLOT}, 320, 200, MENUALIGN_CENTER,
+ MENUACTION_YES, "FEM_YES", {nil, SAVESLOT_NONE, MENUPAGE_LOADING_IN_PROGRESS}, 320, 225, MENUALIGN_CENTER,
+ },
+
+ // MENUPAGE_DELETE_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_LOADING_IN_PROGRESS = 12
+ { "FET_LG", MENUPAGE_CHOOSE_LOAD_SLOT, nil, nil,
+ },
+
+ // MENUPAGE_DELETING_IN_PROGRESS = 13
+ { "FES_DEL", MENUPAGE_CHOOSE_DELETE_SLOT, nil, nil,
+ },
+
+ // MENUPAGE_DELETE_SUCCESSFUL = 14
+ { "FES_DEL", MENUPAGE_NEW_GAME, nil, nil,
+ MENUACTION_LABEL, "FES_DSC", {nil, SAVESLOT_NONE, 0}, 0, 0, 0,
+ MENUACTION_CHANGEMENU, "FEM_OK", {nil, SAVESLOT_NONE, MENUPAGE_NEW_GAME}, 320, 225, MENUALIGN_CENTER,
+ },
+
+ // MENUPAGE_CHOOSE_SAVE_SLOT = 15
+ { "FET_SG", MENUPAGE_DISABLED, nil, nil,
+ MENUACTION_SAVEGAME, "FEM_SL1", {nil, SAVESLOT_1, MENUPAGE_SAVE_OVERWRITE_CONFIRM}, 40, 90, MENUALIGN_LEFT,
+ MENUACTION_SAVEGAME, "FEM_SL2", {nil, SAVESLOT_2, MENUPAGE_SAVE_OVERWRITE_CONFIRM}, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_SAVEGAME, "FEM_SL3", {nil, SAVESLOT_3, MENUPAGE_SAVE_OVERWRITE_CONFIRM}, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_SAVEGAME, "FEM_SL4", {nil, SAVESLOT_4, MENUPAGE_SAVE_OVERWRITE_CONFIRM}, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_SAVEGAME, "FEM_SL5", {nil, SAVESLOT_5, MENUPAGE_SAVE_OVERWRITE_CONFIRM}, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_SAVEGAME, "FEM_SL6", {nil, SAVESLOT_6, MENUPAGE_SAVE_OVERWRITE_CONFIRM}, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_SAVEGAME, "FEM_SL7", {nil, SAVESLOT_7, MENUPAGE_SAVE_OVERWRITE_CONFIRM}, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_SAVEGAME, "FEM_SL8", {nil, SAVESLOT_8, MENUPAGE_SAVE_OVERWRITE_CONFIRM}, 0, 0, MENUALIGN_LEFT,
+ MENUACTION_RESUME_FROM_SAVEZONE,"FESZ_CA", {nil, SAVESLOT_NONE, 0}, 320, 345, MENUALIGN_CENTER,
+ },
+
+ // MENUPAGE_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_SAVING_IN_PROGRESS = 17
+ { "FET_SG", MENUPAGE_CHOOSE_SAVE_SLOT, nil, nil,
+ },
+
+ // MENUPAGE_SAVE_SUCCESSFUL = 18
+ { "FET_SG", MENUPAGE_CHOOSE_SAVE_SLOT, nil, nil,
+ MENUACTION_LABEL, "FES_SSC", {nil, SAVESLOT_LABEL, MENUPAGE_NONE}, 0, 0, 0,
+ MENUACTION_RESUME_FROM_SAVEZONE, "FEM_OK", {nil, SAVESLOT_NONE, MENUPAGE_CHOOSE_SAVE_SLOT}, 320, 225, MENUALIGN_CENTER,
+ },
+
+ // MENUPAGE_SAVE_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_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_SKIN_SELECT = 21
+ { "FET_PS", MENUPAGE_OPTIONS, nil, nil,
+ MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, MENUPAGE_OPTIONS}, 0, 0, 0,
+ },
+
+ // 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_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_SAVE_FAILED_2 = 24
+ { "FET_LG", MENUPAGE_CHOOSE_SAVE_SLOT, nil, nil,
+ MENUACTION_LABEL, "FEC_SVU", {nil, SAVESLOT_NONE, 0}, 0, 0, 0,
+ },
+
+ // 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 = 26
+ { "FET_CTL", MENUPAGE_OPTIONS, new CCustomScreenLayout({0, 0, MENU_DEFAULT_LINE_HEIGHT, false, false, 150}), nil,
+#ifdef PC_PLAYER_CONTROLS
+ MENUACTION_CTRLMETHOD, "FET_STI", {nil, SAVESLOT_NONE, MENUPAGE_CONTROLLER_PC}, 320, 150, MENUALIGN_CENTER,
+#endif
+ 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}, 0, 0, MENUALIGN_CENTER,
+#endif
+ 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_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}, 0, 0, MENUALIGN_CENTER,
+#endif
+ MENUACTION_CHANGEMENU, "FEO_LAN", {nil, SAVESLOT_NONE, MENUPAGE_LANGUAGE_SETTINGS}, 0, 0, MENUALIGN_CENTER,
+ MENUACTION_PLAYERSETUP, "FET_PS", {nil, SAVESLOT_NONE, MENUPAGE_SKIN_SELECT}, 0, 0, MENUALIGN_CENTER,
+ MENUACTION_GOBACK, "FEDS_TB", {nil, SAVESLOT_NONE, 0}, 0, 0, MENUALIGN_CENTER,
+ },
+
+ // MENUPAGE_EXIT = 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_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_KEYBOARD_CONTROLS = 30
+ { "FET_STI", MENUPAGE_CONTROLLER_PC, nil, nil,
+ },
+
+ // 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_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_NONE = 33
+ { "", 0, 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_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_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_CONTROLLER_PC_OLD2 = 37
+ { "FET_CTL", MENUPAGE_CONTROLLER_PC, nil, nil,
+
+ },
+
+ // 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_CONTROLLER_PC_OLD4 = 39
+ { "FET_CTL", MENUPAGE_CONTROLLER_PC, nil, nil,
+
+ },
+
+ // 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, new CCustomScreenLayout({40, 78, 25, true, true}), GraphicsGoBack,
+
+ 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
+#ifdef LEGACY_MENU_OPTIONS
+ MENUACTION_FRAMESYNC, "FEM_VSC", {nil, SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS}, 0, 0, MENUALIGN_LEFT,
+#endif
+ MENUACTION_FRAMELIMIT, "FEM_FRM", { nil, SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS }, 0, 0, MENUALIGN_LEFT,
+ MULTISAMPLING_SELECTOR
+ ISLAND_LOADING_SELECTOR
+ DUALPASS_SELECTOR
+#ifdef EXTENDED_COLOURFILTER
+ POSTFX_SELECTORS
+#elif defined LEGACY_MENU_OPTIONS
+ MENUACTION_TRAILS, "FED_TRA", { nil, SAVESLOT_NONE, MENUPAGE_GRAPHICS_SETTINGS }, 0, 0, MENUALIGN_LEFT,
+#endif
+ // re3.cpp inserts here pipeline selectors if neo/neo.txd exists and EXTENDED_PIPELINES defined
+ MENUACTION_CFO_DYNAMIC, "FET_DEF", { new CCFODynamic(nil, nil, nil, 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, new CCustomScreenLayout({0, 0, 0, false, false, 30}), nil,
+
+ 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_OUTRO = 34
+ { "", 0, nil, nil, },
+};
+
+#endif
+#endif
diff --git a/src/core/Pad.cpp b/src/core/Pad.cpp
index 91e2d704..7d53009d 100644
--- a/src/core/Pad.cpp
+++ b/src/core/Pad.cpp
@@ -1213,14 +1213,46 @@ void CPad::AddToCheatString(char c)
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;
- }
+#define ccmp(n) if((uint8)sourceStr[i] != (uint8)origCheatStr[i] - n) return 1;
+ int i = 0;
+ while(origCheatStr[i])
+ {
+ switch(i)
+ {
+ case 0: ccmp(3); break;
+ case 1: ccmp(5); break;
+ case 2: ccmp(7); break;
+ case 3: ccmp(1); break;
+ case 4: ccmp(13); break;
+ case 5: ccmp(27); break;
+ case 6: ccmp(3); break;
+ case 7: ccmp(7); break;
+ case 8: ccmp(1); break;
+ case 9: ccmp(11); break;
+ case 10: ccmp(13); break;
+ case 11: ccmp(8); break;
+ case 12: ccmp(7); break;
+ case 13: ccmp(32); break;
+ case 14: ccmp(13); break;
+ case 15: ccmp(6); break;
+ case 16: ccmp(28); break;
+ case 17: ccmp(19); break;
+ case 18: ccmp(10); break;
+ case 19: ccmp(3); break;
+ case 20: ccmp(3); break;
+ case 21: ccmp(5); break;
+ case 22: ccmp(7); break;
+ case 23: ccmp(1); break;
+ case 24: ccmp(13); break;
+ case 25: ccmp(27); break;
+ case 26: ccmp(3); break;
+ case 27: ccmp(7); break;
+ default: return 1;
+ }
+ i++;
}
return 0;
+#undef ccmp
}
// TODO(Miami): Mobile has changed some of the cheats to include debugging things
diff --git a/src/core/PlayerInfo.cpp b/src/core/PlayerInfo.cpp
index 61e2f67a..77ddfdb1 100644
--- a/src/core/PlayerInfo.cpp
+++ b/src/core/PlayerInfo.cpp
@@ -3,6 +3,7 @@
#include "Automobile.h"
#include "Bridge.h"
#include "Camera.h"
+#include "CarCtrl.h"
#include "Cranes.h"
#include "Darkel.h"
#include "Explosion.h"
@@ -34,93 +35,10 @@
#include "Automobile.h"
#include "GameLogic.h"
-CVector lastPlayerPos;
-
-// --MIAMI: Done
-void
-CPlayerInfo::SetPlayerSkin(char *skin)
-{
- strncpy(m_aSkinName, skin, 32);
- LoadPlayerSkin();
-}
-
-// --MIAMI: Done
-const CVector &
-CPlayerInfo::GetPos()
-{
-#ifdef FIX_BUGS
- if (!m_pPed)
- return TheCamera.GetPosition();
-#endif
- if (m_pPed->InVehicle())
- return m_pPed->m_pMyVehicle->GetPosition();
- return m_pPed->GetPosition();
-}
-
-// --MIAMI: Done
-void
-CPlayerInfo::LoadPlayerSkin()
-{
- DeletePlayerSkin();
-
- m_pSkinTexture = CPlayerSkin::GetSkinTexture(m_aSkinName);
-}
-
-// --MIAMI: Done
-void
-CPlayerInfo::DeletePlayerSkin()
-{
- if (m_pSkinTexture) {
- RwTextureDestroy(m_pSkinTexture);
- m_pSkinTexture = nil;
- }
-}
-
-// --MIAMI: Done
-void
-CPlayerInfo::KillPlayer()
-{
- if (m_WBState != WBSTATE_PLAYING) return;
-
- m_WBState = WBSTATE_WASTED;
- m_nWBTime = CTimer::GetTimeInMilliseconds();
- CDarkel::ResetOnPlayerDeath();
- CMessages::AddBigMessage(TheText.Get("DEAD"), 4000, 2);
- CStats::TimesDied++;
-}
-
-// --MIAMI: Done
-void
-CPlayerInfo::ArrestPlayer()
-{
- if (m_WBState != WBSTATE_PLAYING) return;
+// --MIAMI: File done
- m_WBState = WBSTATE_BUSTED;
- m_nWBTime = CTimer::GetTimeInMilliseconds();
- m_nBustedAudioStatus = BUSTEDAUDIO_NONE;
- CDarkel::ResetOnPlayerDeath();
- CMessages::AddBigMessage(TheText.Get("BUSTED"), 5000, 2);
- CStats::TimesArrested++;
-}
-
-// --MIAMI: Done
-bool
-CPlayerInfo::IsPlayerInRemoteMode()
-{
- return m_pRemoteVehicle || m_bInRemoteMode;
-}
-
-void
-CPlayerInfo::PlayerFailedCriticalMission()
-{
- if (m_WBState != WBSTATE_PLAYING)
- return;
- m_WBState = WBSTATE_FAILED_CRITICAL_MISSION;
- m_nWBTime = CTimer::GetTimeInMilliseconds();
- CDarkel::ResetOnPlayerDeath();
-}
+CVector lastPlayerPos;
-// --MIAMI: Done
void
CPlayerInfo::Clear(void)
{
@@ -181,192 +99,6 @@ CPlayerInfo::Clear(void)
m_nBustedAudioStatus = BUSTEDAUDIO_NONE;
}
-// --MIAMI: Done
-void
-CPlayerInfo::BlowUpRCBuggy(bool actually)
-{
- if (!m_pRemoteVehicle || m_pRemoteVehicle->bRemoveFromWorld)
- return;
-
- CRemote::TakeRemoteControlledCarFromPlayer(actually);
- if (actually)
- m_pRemoteVehicle->BlowUpCar(FindPlayerPed());
-}
-
-// --MIAMI: Done
-void
-CPlayerInfo::CancelPlayerEnteringCars(CVehicle *car)
-{
- if (!car || car == m_pPed->m_pMyVehicle) {
- if (m_pPed->EnteringCar())
- m_pPed->QuitEnteringCar();
- }
- if (m_pPed->m_objective == OBJECTIVE_ENTER_CAR_AS_PASSENGER || m_pPed->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER)
- m_pPed->ClearObjective();
-}
-
-// --MIAMI: Done
-void
-CPlayerInfo::MakePlayerSafe(bool toggle)
-{
- if (toggle) {
- m_pPed->m_pWanted->m_bIgnoredByEveryone = true;
- CWorld::StopAllLawEnforcersInTheirTracks();
- CPad::GetPad(0)->SetDisablePlayerControls(PLAYERCONTROL_PLAYERINFO);
- CPad::StopPadsShaking();
- m_pPed->bBulletProof = true;
- m_pPed->bFireProof = true;
- m_pPed->bCollisionProof = true;
- m_pPed->bMeleeProof = true;
- m_pPed->bOnlyDamagedByPlayer = true;
- m_pPed->bExplosionProof = true;
- m_pPed->m_bCanBeDamaged = false;
- ((CPlayerPed*)m_pPed)->ClearAdrenaline();
- CancelPlayerEnteringCars(nil);
- gFireManager.ExtinguishPoint(GetPos(), 4000.0f);
- CExplosion::RemoveAllExplosionsInArea(GetPos(), 4000.0f);
- CProjectileInfo::RemoveAllProjectiles();
- CWorld::SetAllCarsCanBeDamaged(false);
- CWorld::ExtinguishAllCarFiresInArea(GetPos(), 4000.0f);
- CReplay::DisableReplays();
-
- } else {
- m_pPed->m_pWanted->m_bIgnoredByEveryone = false;
- CPad::GetPad(0)->SetEnablePlayerControls(PLAYERCONTROL_PLAYERINFO);
- m_pPed->bBulletProof = false;
- m_pPed->bFireProof = false;
- m_pPed->bCollisionProof = false;
- m_pPed->bMeleeProof = false;
- m_pPed->bOnlyDamagedByPlayer = false;
- m_pPed->bExplosionProof = false;
- m_pPed->m_bCanBeDamaged = true;
- CWorld::SetAllCarsCanBeDamaged(true);
- CReplay::EnableReplays();
- }
-}
-
-// --MIAMI: Done
-bool
-CPlayerInfo::IsRestartingAfterDeath()
-{
- return m_WBState == WBSTATE_WASTED;
-}
-
-// --MIAMI: Done
-bool
-CPlayerInfo::IsRestartingAfterArrest()
-{
- return m_WBState == WBSTATE_BUSTED;
-}
-
-// --MIAMI: Done
-// lastCloseness is passed to other calls of this function
-void
-CPlayerInfo::EvaluateCarPosition(CEntity *carToTest, CPed *player, float carBoundCentrePedDist, float *lastCloseness, CVehicle **closestCarOutput)
-{
- // This dist used for determining the angle to face
- CVector2D dist(carToTest->GetPosition() - player->GetPosition());
- float neededTurn = CGeneral::GetATanOfXY(player->GetForward().x, player->GetForward().y) - CGeneral::GetATanOfXY(dist.x, dist.y);
- while (neededTurn >= PI) {
- neededTurn -= 2 * PI;
- }
-
- while (neededTurn < -PI) {
- neededTurn += 2 * PI;
- }
-
- // This dist used for evaluating cars' distances, weird...
- // Accounts inverted needed turn (or needed turn in long way) and car dist.
- float closeness = (1.0f - Abs(neededTurn) / TWOPI) * (10.0f - carBoundCentrePedDist);
- if (closeness > *lastCloseness) {
- *lastCloseness = closeness;
- *closestCarOutput = (CVehicle*)carToTest;
- }
-}
-
-// --MIAMI: Done
-void
-CPlayerInfo::SavePlayerInfo(uint8 *buf, uint32 *size)
-{
- // Interesting
- *size = sizeof(CPlayerInfo);
-
-#define CopyToBuf(buf, data) memcpy(buf, &data, sizeof(data)); buf += sizeof(data);
- CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nMoney);
- CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_WBState);
- CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nWBTime);
- CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nTrafficMultiplier);
- CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_fRoadDensity);
- CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nVisibleMoney);
- CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nCollectedPackages);
- 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
-}
-
-// --MIAMI: Done
-void
-CPlayerInfo::LoadPlayerInfo(uint8 *buf, uint32 size)
-{
-#define CopyFromBuf(buf, data) memcpy(&data, buf, sizeof(data)); buf += sizeof(data);
- CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nMoney);
- CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_WBState);
- CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nWBTime);
- CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nTrafficMultiplier);
- CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_fRoadDensity);
- CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nVisibleMoney);
- CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nCollectedPackages);
- 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_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
-}
-
-// --MIAMI: Done
-void
-CPlayerInfo::FindClosestCarSectorList(CPtrList& carList, CPed* ped, float unk1, float unk2, float unk3, float unk4, float* lastCloseness, CVehicle** closestCarOutput)
-{
- for (CPtrNode* node = carList.first; node; node = node->next) {
- CVehicle *car = (CVehicle*)node->item;
- if(car->m_scanCode != CWorld::GetCurrentScanCode()) {
- if (!car->bUsesCollision || !car->IsVehicle())
- continue;
-
- car->m_scanCode = CWorld::GetCurrentScanCode();
- if (car->GetStatus() != STATUS_WRECKED && car->GetStatus() != STATUS_TRAIN_MOVING
- && (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 || 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);
- }
- }
- }
- }
- }
-}
-
void
CPlayerInfo::Process(void)
{
@@ -673,13 +405,13 @@ CPlayerInfo::Process(void)
uint32 timeWithoutRemoteCar = CTimer::GetTimeInMilliseconds() - m_nTimeLostRemoteCar;
if (CTimer::GetPreviousTimeInMilliseconds() - m_nTimeLostRemoteCar < 1000 && timeWithoutRemoteCar >= 1000 && m_WBState == WBSTATE_PLAYING && field_D6) {
TheCamera.SetFadeColour(0, 0, 0);
- TheCamera.Fade(1.0f, 0);
+ TheCamera.Fade(1.0f, FADE_OUT);
}
if (timeWithoutRemoteCar > 2000) {
if (m_WBState == WBSTATE_PLAYING && field_D6) {
TheCamera.RestoreWithJumpCut();
TheCamera.SetFadeColour(0, 0, 0);
- TheCamera.Fade(1.0f, 1);
+ TheCamera.Fade(1.0f, FADE_IN);
TheCamera.Process();
CTimer::Stop();
CCullZones::ForceCullZoneCoors(TheCamera.GetPosition());
@@ -796,3 +528,355 @@ CPlayerInfo::Process(void)
m_nMoney = Min(999999999, m_nMoney);
m_nVisibleMoney = Min(999999999, m_nVisibleMoney);
}
+
+bool
+CPlayerInfo::IsPlayerInRemoteMode()
+{
+ return m_pRemoteVehicle || m_bInRemoteMode;
+}
+
+void
+CPlayerInfo::SavePlayerInfo(uint8 *buf, uint32 *size)
+{
+ // Interesting
+ *size = sizeof(CPlayerInfo);
+
+#define CopyToBuf(buf, data) memcpy(buf, &data, sizeof(data)); buf += sizeof(data);
+ CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nMoney);
+ CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_WBState);
+ CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nWBTime);
+ CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nTrafficMultiplier);
+ CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_fRoadDensity);
+ CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nVisibleMoney);
+ CopyToBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nCollectedPackages);
+ 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
+}
+
+void
+CPlayerInfo::LoadPlayerInfo(uint8 *buf, uint32 size)
+{
+#define CopyFromBuf(buf, data) memcpy(&data, buf, sizeof(data)); buf += sizeof(data);
+ CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nMoney);
+ CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_WBState);
+ CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nWBTime);
+ CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nTrafficMultiplier);
+ CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_fRoadDensity);
+ CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nVisibleMoney);
+ CopyFromBuf(buf, CWorld::Players[CWorld::PlayerInFocus].m_nCollectedPackages);
+ 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_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
+}
+
+void
+CPlayerInfo::FindClosestCarSectorList(CPtrList& carList, CPed* ped, float unk1, float unk2, float unk3, float unk4, float* lastCloseness, CVehicle** closestCarOutput)
+{
+ for (CPtrNode* node = carList.first; node; node = node->next) {
+ CVehicle *car = (CVehicle*)node->item;
+ if(car->m_scanCode != CWorld::GetCurrentScanCode()) {
+ if (!car->bUsesCollision || !car->IsVehicle())
+ continue;
+
+ car->m_scanCode = CWorld::GetCurrentScanCode();
+ if (car->GetStatus() != STATUS_WRECKED && car->GetStatus() != STATUS_TRAIN_MOVING
+ && (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 || 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);
+ }
+ }
+ }
+ }
+ }
+}
+
+// lastCloseness is passed to other calls of this function
+void
+CPlayerInfo::EvaluateCarPosition(CEntity *carToTest, CPed *player, float carBoundCentrePedDist, float *lastCloseness, CVehicle **closestCarOutput)
+{
+ // This dist used for determining the angle to face
+ CVector2D dist(carToTest->GetPosition() - player->GetPosition());
+ float neededTurn = CGeneral::GetATanOfXY(player->GetForward().x, player->GetForward().y) - CGeneral::GetATanOfXY(dist.x, dist.y);
+ while (neededTurn >= PI) {
+ neededTurn -= 2 * PI;
+ }
+
+ while (neededTurn < -PI) {
+ neededTurn += 2 * PI;
+ }
+
+ // This dist used for evaluating cars' distances, weird...
+ // Accounts inverted needed turn (or needed turn in long way) and car dist.
+ float closeness = (1.0f - Abs(neededTurn) / TWOPI) * (10.0f - carBoundCentrePedDist);
+ if (closeness > *lastCloseness) {
+ *lastCloseness = closeness;
+ *closestCarOutput = (CVehicle*)carToTest;
+ }
+}
+
+const CVector &
+CPlayerInfo::GetPos()
+{
+#ifdef FIX_BUGS
+ if (!m_pPed)
+ return TheCamera.GetPosition();
+#endif
+ if (m_pPed->InVehicle())
+ return m_pPed->m_pMyVehicle->GetPosition();
+ return m_pPed->GetPosition();
+}
+
+CVector
+FindPlayerCoors(void)
+{
+#ifdef FIX_BUGS
+ if (CReplay::IsPlayingBack())
+ return TheCamera.GetPosition();
+#endif
+ CPlayerPed *ped = FindPlayerPed();
+ if(ped->InVehicle())
+ return ped->m_pMyVehicle->GetPosition();
+ else
+ return ped->GetPosition();
+}
+
+const CVector &
+FindPlayerSpeed(void)
+{
+#ifdef FIX_BUGS
+ static CVector vecTmpVector(0.0f, 0.0f, 0.0f);
+ if (CReplay::IsPlayingBack())
+ return vecTmpVector;
+#endif
+ CPlayerPed *ped = FindPlayerPed();
+ if(ped->InVehicle())
+ return ped->m_pMyVehicle->m_vecMoveSpeed;
+ else
+ return ped->m_vecMoveSpeed;
+}
+
+CVehicle *
+FindPlayerVehicle(void)
+{
+ CPlayerPed *ped = FindPlayerPed();
+ if(ped && ped->InVehicle()) return ped->m_pMyVehicle;
+ return nil;
+}
+
+CEntity *
+FindPlayerEntity(void)
+{
+ CPlayerPed *ped = FindPlayerPed();
+ if(ped->InVehicle())
+ return ped->m_pMyVehicle;
+ else
+ return ped;
+}
+
+CVehicle *
+FindPlayerTrain(void)
+{
+ if(FindPlayerVehicle() && FindPlayerVehicle()->IsTrain())
+ return FindPlayerVehicle();
+ else
+ return nil;
+}
+
+CPlayerPed *
+FindPlayerPed(void)
+{
+ return CWorld::Players[CWorld::PlayerInFocus].m_pPed;
+}
+
+const CVector &
+FindPlayerCentreOfWorld(int32 player)
+{
+#ifdef FIX_BUGS
+ if(CReplay::IsPlayingBack()) return TheCamera.GetPosition();
+#endif
+ if(CCarCtrl::bCarsGeneratedAroundCamera) return TheCamera.GetPosition();
+ if(CWorld::Players[player].m_pRemoteVehicle) return CWorld::Players[player].m_pRemoteVehicle->GetPosition();
+ if(FindPlayerVehicle()) return FindPlayerVehicle()->GetPosition();
+ return CWorld::Players[player].m_pPed->GetPosition();
+}
+
+const CVector &
+FindPlayerCentreOfWorld_NoSniperShift(void)
+{
+#ifdef FIX_BUGS
+ if (CReplay::IsPlayingBack()) return TheCamera.GetPosition();
+#endif
+ if(CCarCtrl::bCarsGeneratedAroundCamera) return TheCamera.GetPosition();
+ if(CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle)
+ return CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle->GetPosition();
+ if(FindPlayerVehicle()) return FindPlayerVehicle()->GetPosition();
+ return FindPlayerPed()->GetPosition();
+}
+
+float
+FindPlayerHeading(void)
+{
+ if(CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle)
+ return CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle->GetForward().Heading();
+ if(FindPlayerVehicle()) return FindPlayerVehicle()->GetForward().Heading();
+ return FindPlayerPed()->GetForward().Heading();
+}
+
+bool
+CPlayerInfo::IsRestartingAfterDeath()
+{
+ return m_WBState == WBSTATE_WASTED;
+}
+
+bool
+CPlayerInfo::IsRestartingAfterArrest()
+{
+ return m_WBState == WBSTATE_BUSTED;
+}
+
+void
+CPlayerInfo::KillPlayer()
+{
+ if (m_WBState != WBSTATE_PLAYING) return;
+
+ m_WBState = WBSTATE_WASTED;
+ m_nWBTime = CTimer::GetTimeInMilliseconds();
+ CDarkel::ResetOnPlayerDeath();
+ CMessages::AddBigMessage(TheText.Get("DEAD"), 4000, 2);
+ CStats::TimesDied++;
+}
+
+void
+CPlayerInfo::ArrestPlayer()
+{
+ if (m_WBState != WBSTATE_PLAYING) return;
+
+ m_WBState = WBSTATE_BUSTED;
+ m_nWBTime = CTimer::GetTimeInMilliseconds();
+ m_nBustedAudioStatus = BUSTEDAUDIO_NONE;
+ CDarkel::ResetOnPlayerDeath();
+ CMessages::AddBigMessage(TheText.Get("BUSTED"), 5000, 2);
+ CStats::TimesArrested++;
+}
+
+void
+CPlayerInfo::PlayerFailedCriticalMission()
+{
+ if (m_WBState != WBSTATE_PLAYING)
+ return;
+ m_WBState = WBSTATE_FAILED_CRITICAL_MISSION;
+ m_nWBTime = CTimer::GetTimeInMilliseconds();
+ CDarkel::ResetOnPlayerDeath();
+}
+
+void
+CPlayerInfo::CancelPlayerEnteringCars(CVehicle *car)
+{
+ if (!car || car == m_pPed->m_pMyVehicle) {
+ if (m_pPed->EnteringCar())
+ m_pPed->QuitEnteringCar();
+ }
+ if (m_pPed->m_objective == OBJECTIVE_ENTER_CAR_AS_PASSENGER || m_pPed->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER)
+ m_pPed->ClearObjective();
+}
+
+void
+CPlayerInfo::MakePlayerSafe(bool toggle)
+{
+ if (toggle) {
+ m_pPed->m_pWanted->m_bIgnoredByEveryone = true;
+ CWorld::StopAllLawEnforcersInTheirTracks();
+ CPad::GetPad(0)->SetDisablePlayerControls(PLAYERCONTROL_PLAYERINFO);
+ CPad::StopPadsShaking();
+ m_pPed->bBulletProof = true;
+ m_pPed->bFireProof = true;
+ m_pPed->bCollisionProof = true;
+ m_pPed->bMeleeProof = true;
+ m_pPed->bOnlyDamagedByPlayer = true;
+ m_pPed->bExplosionProof = true;
+ m_pPed->m_bCanBeDamaged = false;
+ ((CPlayerPed*)m_pPed)->ClearAdrenaline();
+ CancelPlayerEnteringCars(nil);
+ gFireManager.ExtinguishPoint(GetPos(), 4000.0f);
+ CExplosion::RemoveAllExplosionsInArea(GetPos(), 4000.0f);
+ CProjectileInfo::RemoveAllProjectiles();
+ CWorld::SetAllCarsCanBeDamaged(false);
+ CWorld::ExtinguishAllCarFiresInArea(GetPos(), 4000.0f);
+ CReplay::DisableReplays();
+
+ } else {
+ m_pPed->m_pWanted->m_bIgnoredByEveryone = false;
+ CPad::GetPad(0)->SetEnablePlayerControls(PLAYERCONTROL_PLAYERINFO);
+ m_pPed->bBulletProof = false;
+ m_pPed->bFireProof = false;
+ m_pPed->bCollisionProof = false;
+ m_pPed->bMeleeProof = false;
+ m_pPed->bOnlyDamagedByPlayer = false;
+ m_pPed->bExplosionProof = false;
+ m_pPed->m_bCanBeDamaged = true;
+ CWorld::SetAllCarsCanBeDamaged(true);
+ CReplay::EnableReplays();
+ }
+}
+
+void
+CPlayerInfo::BlowUpRCBuggy(bool actually)
+{
+ if (!m_pRemoteVehicle || m_pRemoteVehicle->bRemoveFromWorld)
+ return;
+
+ CRemote::TakeRemoteControlledCarFromPlayer(actually);
+ if (actually)
+ m_pRemoteVehicle->BlowUpCar(FindPlayerPed());
+}
+
+#ifdef GTA_PC
+void
+CPlayerInfo::SetPlayerSkin(const char *skin)
+{
+ strncpy(m_aSkinName, skin, 32);
+ LoadPlayerSkin();
+}
+
+void
+CPlayerInfo::LoadPlayerSkin()
+{
+ DeletePlayerSkin();
+
+ m_pSkinTexture = CPlayerSkin::GetSkinTexture(m_aSkinName);
+}
+
+void
+CPlayerInfo::DeletePlayerSkin()
+{
+ if (m_pSkinTexture) {
+ RwTextureDestroy(m_pSkinTexture);
+ m_pSkinTexture = nil;
+ }
+}
+#endif
diff --git a/src/core/PlayerInfo.h b/src/core/PlayerInfo.h
index 7d99a4e0..a3896ebb 100644
--- a/src/core/PlayerInfo.h
+++ b/src/core/PlayerInfo.h
@@ -10,7 +10,7 @@ enum eWastedBustedState
WBSTATE_FAILED_CRITICAL_MISSION,
};
-enum eBustedAudioState : uint8
+enum eBustedAudioState
{
BUSTEDAUDIO_NONE,
BUSTEDAUDIO_LOADING,
@@ -82,15 +82,14 @@ public:
bool m_bGetOutOfJailFree;
bool m_bGetOutOfHospitalFree;
bool m_bDriveByAllowed;
- eBustedAudioState m_nBustedAudioStatus;
+ uint8 m_nBustedAudioStatus;
int16 m_nCurrentBustedAudio;
+#ifdef GTA_PC
char m_aSkinName[32];
RwTexture *m_pSkinTexture;
+#endif
void MakePlayerSafe(bool);
- void LoadPlayerSkin();
- void DeletePlayerSkin();
- void SetPlayerSkin(char* skin);
const CVector &GetPos();
void Process(void);
void KillPlayer(void);
@@ -107,5 +106,19 @@ public:
void SavePlayerInfo(uint8 *buf, uint32* size);
void FindClosestCarSectorList(CPtrList&, CPed*, float, float, float, float, float*, CVehicle**);
- ~CPlayerInfo() { };
+#ifdef GTA_PC
+ void LoadPlayerSkin();
+ void SetPlayerSkin(const char *skin);
+ void DeletePlayerSkin();
+#endif
};
+
+CPlayerPed *FindPlayerPed(void);
+CVehicle *FindPlayerVehicle(void);
+CVehicle *FindPlayerTrain(void);
+CEntity *FindPlayerEntity(void);
+CVector FindPlayerCoors(void);
+const CVector &FindPlayerSpeed(void);
+const CVector &FindPlayerCentreOfWorld(int32 player);
+const CVector &FindPlayerCentreOfWorld_NoSniperShift(void);
+float FindPlayerHeading(void); \ No newline at end of file
diff --git a/src/core/Pools.cpp b/src/core/Pools.cpp
index cbc57902..dfc7a82f 100644
--- a/src/core/Pools.cpp
+++ b/src/core/Pools.cpp
@@ -13,6 +13,7 @@
#include "Streaming.h"
#include "Wanted.h"
#include "World.h"
+#include "MemoryHeap.h"
//--MIAMI: file done
@@ -27,19 +28,39 @@ CDummyPool *CPools::ms_pDummyPool;
CAudioScriptObjectPool *CPools::ms_pAudioScriptObjectPool;
CColModelPool *CPools::ms_pColModelPool;
+#if defined GTA_PS2 && !defined MASTER // or USE_CUSTOM_ALLOCATOR
+// not in VC. perhaps ifdef'ed away
+#define CHECKMEM(msg) CMemCheck::AllocateMemCheckBlock(msg)
+#else
+#define CHECKMEM(msg)
+#endif
+
void
CPools::Initialise(void)
{
+ PUSH_MEMID(MEMID_POOLS);
+ CHECKMEM("before pools");
ms_pPtrNodePool = new CCPtrNodePool(NUMPTRNODES, "PtrNode");
+ CHECKMEM("after CPtrNodePool");
ms_pEntryInfoNodePool = new CEntryInfoNodePool(NUMENTRYINFOS, "EntryInfoNode");
+ CHECKMEM("after CEntryInfoNodePool");
ms_pPedPool = new CPedPool(NUMPEDS, "Peds");
+ CHECKMEM("after CPedPool");
ms_pVehiclePool = new CVehiclePool(NUMVEHICLES, "Vehicles");
+ CHECKMEM("after CVehiclePool");
ms_pBuildingPool = new CBuildingPool(NUMBUILDINGS, "Buildings");
+ CHECKMEM("after CBuildingPool");
ms_pTreadablePool = new CTreadablePool(NUMTREADABLES, "Treadables");
+ CHECKMEM("after CTreadablePool");
ms_pObjectPool = new CObjectPool(NUMOBJECTS, "Objects");
+ CHECKMEM("after CObjectPool");
ms_pDummyPool = new CDummyPool(NUMDUMMIES, "Dummys");
+ CHECKMEM("after CDummyPool");
ms_pAudioScriptObjectPool = new CAudioScriptObjectPool(NUMAUDIOSCRIPTOBJECTS, "AudioScriptObj");
+ CHECKMEM("after cAudioScriptObjectPool");
ms_pColModelPool = new CColModelPool(NUMCOLMODELS, "ColModel");
+ CHECKMEM("after pools");
+ POP_MEMID();
}
void
diff --git a/src/core/References.cpp b/src/core/References.cpp
index 52abbc3e..dc83d96d 100644
--- a/src/core/References.cpp
+++ b/src/core/References.cpp
@@ -22,6 +22,83 @@ CReferences::Init(void)
}
void
+CEntity::RegisterReference(CEntity **pent)
+{
+ if(IsBuilding())
+ return;
+ CReference *ref;
+ // check if already registered
+ for(ref = m_pFirstReference; ref; ref = ref->next)
+ if(ref->pentity == pent)
+ return;
+ // have to allocate new reference
+ ref = CReferences::pEmptyList;
+ if(ref){
+ CReferences::pEmptyList = ref->next;
+
+ ref->pentity = pent;
+ ref->next = m_pFirstReference;
+ m_pFirstReference = ref;
+ return;
+ }
+ return;
+}
+
+// Clean up the reference from *pent -> 'this'
+void
+CEntity::CleanUpOldReference(CEntity **pent)
+{
+ CReference* ref, ** lastnextp;
+ lastnextp = &m_pFirstReference;
+ for (ref = m_pFirstReference; ref; ref = ref->next) {
+ if (ref->pentity == pent) {
+ *lastnextp = ref->next;
+ ref->next = CReferences::pEmptyList;
+ CReferences::pEmptyList = ref;
+ break;
+ }
+ lastnextp = &ref->next;
+ }
+}
+
+// Clear all references to this entity
+void
+CEntity::ResolveReferences(void)
+{
+ CReference *ref;
+ // clear pointers to this entity
+ for(ref = m_pFirstReference; ref; ref = ref->next)
+ if(*ref->pentity == this)
+ *ref->pentity = nil;
+ // free list
+ if(m_pFirstReference){
+ for(ref = m_pFirstReference; ref->next; ref = ref->next)
+ ;
+ ref->next = CReferences::pEmptyList;
+ CReferences::pEmptyList = m_pFirstReference;
+ m_pFirstReference = nil;
+ }
+}
+
+// Free all references that no longer point to this entity
+void
+CEntity::PruneReferences(void)
+{
+ CReference *ref, *next, **lastnextp;
+ lastnextp = &m_pFirstReference;
+ for(ref = m_pFirstReference; ref; ref = next){
+ next = ref->next;
+ if(*ref->pentity == this)
+ lastnextp = &ref->next;
+ else{
+ *lastnextp = ref->next;
+ ref->next = CReferences::pEmptyList;
+ CReferences::pEmptyList = ref;
+ }
+ }
+}
+
+void
CReferences::RemoveReferencesToPlayer(void)
{
if(FindPlayerVehicle())
diff --git a/src/core/Stats.cpp b/src/core/Stats.cpp
index e078e6d0..8d61c484 100644
--- a/src/core/Stats.cpp
+++ b/src/core/Stats.cpp
@@ -5,9 +5,21 @@
#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;
@@ -43,8 +55,8 @@ float CStats::GarbagePickups;
float CStats::IceCreamSold;
float CStats::TopShootingRangeScore;
float CStats::ShootingRank;
-int32 CStats::ProgressMade;
-int32 CStats::TotalProgressInGame;
+float CStats::ProgressMade;
+float CStats::TotalProgressInGame;
int32 CStats::CarsExploded;
int32 CStats::PeopleKilledByPlayer;
float CStats::MaximumJumpDistance;
@@ -115,7 +127,7 @@ void CStats::Init()
for (int i = 0; i < NUM_PEDTYPES; i++)
PedsKilledOfThisType[i] = 0;
HelisDestroyed = 0;
- ProgressMade = 0;
+ ProgressMade = 0.0f;
KgsOfExplosivesUsed = 0;
BulletsThatHit = 0;
TyresPopped = 0;
@@ -346,27 +358,27 @@ wchar *CStats::FindCriminalRatingString()
}
wchar *CStats::FindChaseString(float fMediaLevel) {
- if (fMediaLevel < 20.0f) return TheText.Get("MEDIA1");
- if (fMediaLevel < 50.0f) return TheText.Get("MEDIA2");
- if (fMediaLevel < 75.0f) return TheText.Get("MEDIA3");
- if (fMediaLevel < 100.0f) return TheText.Get("MEDIA4");
- if (fMediaLevel < 150.0f) return TheText.Get("MEDIA5");
- if (fMediaLevel < 200.0f) return TheText.Get("MEDIA6");
- if (fMediaLevel < 250.0f) return TheText.Get("MEDIA7");
- if (fMediaLevel < 300.0f) return TheText.Get("MEDIA8");
- if (fMediaLevel < 350.0f) return TheText.Get("MEDIA9");
- if (fMediaLevel < 400.0f) return TheText.Get("MEDIA10");
- if (fMediaLevel < 500.0f) return TheText.Get("MEDIA11");
- if (fMediaLevel < 600.0f) return TheText.Get("MEDIA12");
- if (fMediaLevel < 700.0f) return TheText.Get("MEDIA13");
- if (fMediaLevel < 800.0f) return TheText.Get("MEDIA14");
- if (fMediaLevel < 900.0f) return TheText.Get("MEDIA15");
- if (fMediaLevel < 1000.0f) return TheText.Get("MEDIA16");
- if (fMediaLevel < 1200.0f) return TheText.Get("MEDIA17");
- if (fMediaLevel < 1400.0f) return TheText.Get("MEDIA18");
- if (fMediaLevel < 1600.0f) return TheText.Get("MEDIA19");
- if (fMediaLevel < 1800.0f) return TheText.Get("MEDIA20");
- return TheText.Get("MEDIA21");
+ 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()
@@ -387,16 +399,16 @@ int32 CStats::FindCriminalRatingNumber()
}
if (RoundsFiredByPlayer > 100)
- rating += (float)CStats::BulletsThatHit / (float)CStats::RoundsFiredByPlayer * 500.0f;
+ rating += (float)BulletsThatHit / (float)RoundsFiredByPlayer * 500.0f;
if (TotalProgressInGame)
- rating += (float)CStats::ProgressMade / (float)CStats::TotalProgressInGame * 1000.0f;
+ rating += ProgressMade / TotalProgressInGame * 1000.0f;
return rating;
}
float CStats::GetPercentageProgress()
{
- float percentCompleted = (CStats::TotalProgressInGame == 0 ? 0 :
- CStats::ProgressMade * 100.0f / (CGame::nastyGame ? CStats::TotalProgressInGame : CStats::TotalProgressInGame - 1.0f));
+ float percentCompleted = (TotalProgressInGame == 0.f ? 0.f :
+ 100.0f * ProgressMade / (CGame::nastyGame ? TotalProgressInGame : TotalProgressInGame - 1.0f));
return Min(percentCompleted, 100.0f);
}
@@ -773,4 +785,657 @@ CStats::PopulateFavoriteRadioStationList()
float* pListenTimeArray = DMAudio.GetListenTimeArray();
for (int i = 0; i < NUM_RADIOS; i++)
FavoriteRadioStationList[i] = pListenTimeArray[i];
-} \ No newline at end of file
+}
+
+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 49f84657..7fa69396 100644
--- a/src/core/Stats.h
+++ b/src/core/Stats.h
@@ -49,8 +49,8 @@ public:
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;
@@ -147,4 +147,6 @@ public:
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 40d4acee..2fd8bf1c 100644
--- a/src/core/Streaming.cpp
+++ b/src/core/Streaming.cpp
@@ -32,6 +32,10 @@
#include "ColStore.h"
#include "DMAudio.h"
#include "Script.h"
+#include "MemoryMgr.h"
+#include "MemoryHeap.h"
+#include "Font.h"
+#include "Frontend.h"
//--MIAMI: file done (possibly bugs)
@@ -289,12 +293,22 @@ CStreaming::Shutdown(void)
}
}
+#ifndef MASTER
+uint64 timeProcessingTXD;
+uint64 timeProcessingDFF;
+#endif
+
void
CStreaming::Update(void)
{
CStreamingInfo *si, *prev;
bool requestedSubway = false;
+#ifndef MASTER
+ timeProcessingTXD = 0;
+ timeProcessingDFF = 0;
+#endif
+
UpdateMemoryUsed();
if(ms_channelError != -1){
@@ -332,6 +346,10 @@ CStreaming::Update(void)
CColStore::EnsureCollisionIsInMemory(FindPlayerCoors());
}
+ // TODO: PrintRequestList
+ //if (CPad::GetPad(1)->GetLeftShoulder2JustDown() && CPad::GetPad(1)->GetRightShoulder1() && CPad::GetPad(1)->GetRightShoulder2())
+ // PrintRequestList();
+
for(si = ms_endRequestedList.m_prev; si != &ms_startRequestedList; si = prev){
prev = si->m_prev;
if((si->m_flags & (STREAMFLAGS_KEEP_IN_MEMORY|STREAMFLAGS_PRIORITY)) == 0)
@@ -463,6 +481,14 @@ GetObjectName(int streamId)
return objname;
}
+#ifdef USE_CUSTOM_ALLOCATOR
+RpAtomic*
+RegisterAtomicMemPtrsCB(RpAtomic *atomic, void *data)
+{
+ // empty because we expect models to be pre-instanced
+ return atomic;
+}
+#endif
bool
CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId)
@@ -497,10 +523,13 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId)
// Set Txd and anims to use
CTxdStore::AddRef(mi->GetTxdSlot());
+#if GTA_VERSION > GTAVC_PS2
if(animId != -1)
CAnimManager::AddAnimBlockRef(animId);
- CTxdStore::SetCurrentTxd(mi->GetTxdSlot());
+#endif
+ PUSH_MEMID(MEMID_STREAM_MODELS);
+ CTxdStore::SetCurrentTxd(mi->GetTxdSlot());
if(mi->IsSimple()){
success = CFileLoader::LoadAtomicFile(stream, streamId);
// TODO(MIAMI)? complain if file is not pre-instanced. we hardly are interested in that
@@ -512,14 +541,21 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId)
ms_aInfoForModel[streamId].m_loadState = STREAMSTATE_STARTED;
}else{
success = CFileLoader::LoadClumpFile(stream, streamId);
+#ifdef USE_CUSTOM_ALLOCATOR
+ if(success)
+ RpClumpForAllAtomics((RpClump*)mi->GetRwObject(), RegisterAtomicMemPtrsCB, nil);
+#endif
}
+ POP_MEMID();
UpdateMemoryUsed();
// Txd and anims no longer needed unless we only read part of the file
if(ms_aInfoForModel[streamId].m_loadState != STREAMSTATE_STARTED){
CTxdStore::RemoveRefWithoutDelete(mi->GetTxdSlot());
+#if GTA_VERSION > GTAVC_PS2
if(animId != -1)
CAnimManager::RemoveAnimBlockRefWithoutDelete(animId);
+#endif
}
if(!success){
@@ -538,12 +574,14 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId)
return false;
}
+ PUSH_MEMID(MEMID_STREAM_TEXUTRES);
if(ms_bLoadingBigModel || cdsize > 200){
success = CTxdStore::StartLoadTxd(streamId - STREAM_OFFSET_TXD, stream);
if(success)
ms_aInfoForModel[streamId].m_loadState = STREAMSTATE_STARTED;
}else
success = CTxdStore::LoadTxd(streamId - STREAM_OFFSET_TXD, stream);
+ POP_MEMID();
UpdateMemoryUsed();
if(!success){
@@ -554,7 +592,10 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId)
return false;
}
}else if(streamId >= STREAM_OFFSET_COL && streamId < STREAM_OFFSET_ANIM){
- if(!CColStore::LoadCol(streamId-STREAM_OFFSET_COL, mem.start, mem.length)){
+ PUSH_MEMID(MEMID_STREAM_COLLISION);
+ bool success = CColStore::LoadCol(streamId-STREAM_OFFSET_COL, mem.start, mem.length);
+ POP_MEMID();
+ if(!success){
debug("Failed to load %s.col\n", CColStore::GetColName(streamId - STREAM_OFFSET_COL));
RemoveModel(streamId);
ReRequestModel(streamId);
@@ -569,8 +610,10 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId)
RwStreamClose(stream, &mem);
return false;
}
+ PUSH_MEMID(MEMID_STREAM_ANIMATION);
CAnimManager::LoadAnimFile(stream, true, nil);
CAnimManager::CreateAnimAssocGroups();
+ POP_MEMID();
}
RwStreamClose(stream, &mem);
@@ -603,7 +646,9 @@ CStreaming::ConvertBufferToObject(int8 *buf, int32 streamId)
// Mark objects as loaded
if(ms_aInfoForModel[streamId].m_loadState != STREAMSTATE_STARTED){
ms_aInfoForModel[streamId].m_loadState = STREAMSTATE_LOADED;
+#ifndef USE_CUSTOM_ALLOCATOR
ms_memoryUsed += ms_aInfoForModel[streamId].GetCdSize() * CDSTREAM_SECTOR_SIZE;
+#endif
}
endTime = CTimer::GetCurrentTimeInCycles() / CTimer::GetCyclesPerMillisecond();
@@ -638,26 +683,39 @@ CStreaming::FinishLoadingLargeFile(int8 *buf, int32 streamId)
if(streamId < STREAM_OFFSET_TXD){
// Model
mi = CModelInfo::GetModelInfo(streamId);
+ PUSH_MEMID(MEMID_STREAM_MODELS);
CTxdStore::SetCurrentTxd(mi->GetTxdSlot());
success = CFileLoader::FinishLoadClumpFile(stream, streamId);
- if(success)
+ if(success){
+#ifdef USE_CUSTOM_ALLOCATOR
+ RpClumpForAllAtomics((RpClump*)mi->GetRwObject(), RegisterAtomicMemPtrsCB, nil);
+#endif
success = AddToLoadedVehiclesList(streamId);
+ }
+ POP_MEMID();
mi->RemoveRef();
CTxdStore::RemoveRefWithoutDelete(mi->GetTxdSlot());
+#if GTA_VERSION > GTAVC_PS2
if(mi->GetAnimFileIndex() != -1)
CAnimManager::RemoveAnimBlockRefWithoutDelete(mi->GetAnimFileIndex());
+#endif
}else if(streamId >= STREAM_OFFSET_TXD && streamId < STREAM_OFFSET_COL){
// Txd
CTxdStore::AddRef(streamId - STREAM_OFFSET_TXD);
+ PUSH_MEMID(MEMID_STREAM_TEXUTRES);
success = CTxdStore::FinishLoadTxd(streamId - STREAM_OFFSET_TXD, stream);
+ POP_MEMID();
CTxdStore::RemoveRefWithoutDelete(streamId - STREAM_OFFSET_TXD);
}else{
assert(0 && "invalid streamId");
}
RwStreamClose(stream, &mem);
+
ms_aInfoForModel[streamId].m_loadState = STREAMSTATE_LOADED;
+#ifndef USE_CUSTOM_ALLOCATOR
ms_memoryUsed += ms_aInfoForModel[streamId].GetCdSize() * CDSTREAM_SECTOR_SIZE;
+#endif
if(!success){
RemoveModel(streamId);
@@ -740,7 +798,15 @@ CStreaming::RequestBigBuildings(eLevelName level)
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 && b->bIsBIGBuilding
+#ifdef NO_ISLAND_LOADING
+ && (((FrontEndMenuManager.m_PrefsIslandLoading != CMenuManager::ISLAND_LOADING_LOW) && (b != pIslandLODmainlandEntity) &&
+ (b != pIslandLODbeachEntity)) ||
+ (b->m_level == level))
+#else
+ && b->m_level == level
+#endif
+ )
if(!b->bStreamBIGBuilding)
RequestModel(b->GetModelIndex(), BIGBUILDINGFLAGS);
}
@@ -757,8 +823,11 @@ CStreaming::RequestBigBuildings(eLevelName level, const CVector &pos)
for(i = n; i >= 0; i--){
b = CPools::GetBuildingPool()->GetSlot(i);
if(b && b->bIsBIGBuilding
-#ifndef NO_ISLAND_LOADING
- && b->m_level == level
+#ifdef NO_ISLAND_LOADING
+ && (((FrontEndMenuManager.m_PrefsIslandLoading != CMenuManager::ISLAND_LOADING_LOW) && (b != pIslandLODmainlandEntity) && (b != pIslandLODbeachEntity)
+ ) || (b->m_level == level))
+#else
+ && b->m_level == level
#endif
)
if(b->bStreamBIGBuilding){
@@ -828,7 +897,7 @@ CStreaming::InstanceLoadedModels(const CVector &pos)
void
CStreaming::RequestIslands(eLevelName level)
{
-#ifndef NO_ISLAND_LOADING
+ ISLAND_LOADING_ISNT(HIGH)
switch(level){
case LEVEL_MAINLAND:
if(islandLODbeach != -1)
@@ -840,7 +909,6 @@ CStreaming::RequestIslands(eLevelName level)
break;
default: break;
}
-#endif
}
static char *IGnames[] = {
@@ -1170,12 +1238,13 @@ CStreaming::RemoveBuildingsNotInArea(int32 area)
void
CStreaming::RemoveUnusedBigBuildings(eLevelName level)
{
-#ifndef NO_ISLAND_LOADING
+ ISLAND_LOADING_IS(LOW)
+ {
if(level != LEVEL_BEACH)
RemoveBigBuildings(LEVEL_BEACH);
if(level != LEVEL_MAINLAND)
RemoveBigBuildings(LEVEL_MAINLAND);
-#endif
+ }
RemoveIslandsNotUsed(level);
}
@@ -1195,7 +1264,6 @@ DeleteIsland(CEntity *island)
void
CStreaming::RemoveIslandsNotUsed(eLevelName level)
{
-#ifndef NO_ISLAND_LOADING
int i;
if(pIslandLODmainlandEntity == nil)
for(i = CPools::GetBuildingPool()->GetSize()-1; i >= 0; i--){
@@ -1207,7 +1275,12 @@ CStreaming::RemoveIslandsNotUsed(eLevelName level)
if(building->GetModelIndex() == islandLODbeach)
pIslandLODbeachEntity = building;
}
-
+#ifdef NO_ISLAND_LOADING
+ if(FrontEndMenuManager.m_PrefsIslandLoading == CMenuManager::ISLAND_LOADING_HIGH) {
+ DeleteIsland(pIslandLODmainlandEntity);
+ DeleteIsland(pIslandLODbeachEntity);
+ } else
+#endif
switch(level){
case LEVEL_MAINLAND:
DeleteIsland(pIslandLODmainlandEntity);
@@ -1217,7 +1290,6 @@ CStreaming::RemoveIslandsNotUsed(eLevelName level)
break;
}
-#endif // !NO_ISLAND_LOADING
}
void
@@ -1818,26 +1890,36 @@ CStreaming::LoadBigBuildingsWhenNeeded(void)
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);
-
+ ISLAND_LOADING_IS(LOW)
+ {
+ DMAudio.SetEffectsFadeVol(0);
+ CPad::StopPadsShaking();
+ CCollision::LoadCollisionScreen(CGame::currLevel);
+ DMAudio.Service();
+
+ RemoveUnusedBigBuildings(CGame::currLevel);
+ RemoveUnusedBuildings(CGame::currLevel);
+ RemoveUnusedModelsInLoadedList();
+ CGame::TidyUpMemory(true, true);
+ }
CReplay::EmptyReplayBuffer();
if(CGame::currLevel != LEVEL_GENERIC)
LoadSplash(GetLevelSplashScreen(CGame::currLevel));
- CStreaming::RequestBigBuildings(CGame::currLevel, TheCamera.GetPosition());
+ ISLAND_LOADING_IS(LOW)
+ CStreaming::RequestBigBuildings(CGame::currLevel, TheCamera.GetPosition());
+ else if(FrontEndMenuManager.m_PrefsIslandLoading == CMenuManager::ISLAND_LOADING_MEDIUM) {
+ RemoveIslandsNotUsed(CGame::currLevel);
+ CStreaming::RequestIslands(CGame::currLevel);
+ }
+
CStreaming::LoadAllRequestedModels(false);
CGame::TidyUpMemory(true, true);
CTimer::Resume();
- DMAudio.SetEffectsFadeVol(127);
+
+ ISLAND_LOADING_IS(LOW)
+ DMAudio.SetEffectsFadeVol(127);
}
@@ -2415,19 +2497,27 @@ CStreaming::FlushRequestList(void)
void
CStreaming::ImGonnaUseStreamingMemory(void)
{
- // empty
+ PUSH_MEMID(MEMID_STREAM);
}
void
CStreaming::IHaveUsedStreamingMemory(void)
{
+ POP_MEMID();
UpdateMemoryUsed();
}
void
CStreaming::UpdateMemoryUsed(void)
{
- // empty
+#ifdef USE_CUSTOM_ALLOCATOR
+ ms_memoryUsed =
+ gMainHeap.GetMemoryUsed(MEMID_STREAM) +
+ gMainHeap.GetMemoryUsed(MEMID_STREAM_MODELS) +
+ gMainHeap.GetMemoryUsed(MEMID_STREAM_TEXUTRES) +
+ gMainHeap.GetMemoryUsed(MEMID_STREAM_COLLISION) +
+ gMainHeap.GetMemoryUsed(MEMID_STREAM_ANIMATION);
+#endif
}
#define STREAM_DIST 80.0f
@@ -3041,3 +3131,71 @@ CStreaming::UpdateForAnimViewer(void)
CStreaming::RetryLoadFile(CStreaming::ms_channelError);
}
}
+
+
+void
+CStreaming::PrintStreamingBufferState()
+{
+ char str[128];
+ wchar wstr[128];
+ uint32 offset, size;
+
+ CTimer::Stop();
+ int i = 0;
+ while (i < NUMSTREAMINFO) {
+ while (true) {
+ int j = 0;
+ DoRWStuffStartOfFrame(50, 50, 50, 0, 0, 0, 255);
+ CPad::UpdatePads();
+ CSprite2d::InitPerFrame();
+ CFont::InitPerFrame();
+ DefinedState();
+
+ CRect unusedRect(0, 0, RsGlobal.maximumWidth, RsGlobal.maximumHeight);
+ CRGBA unusedColor(255, 255, 255, 255);
+ CFont::SetFontStyle(FONT_BANK);
+ CFont::SetBackgroundOff();
+ CFont::SetWrapx(DEFAULT_SCREEN_WIDTH);
+ CFont::SetScale(0.5f, 0.75f);
+ CFont::SetCentreOff();
+ CFont::SetCentreSize(DEFAULT_SCREEN_WIDTH);
+ CFont::SetJustifyOff();
+ CFont::SetColor(CRGBA(200, 200, 200, 200));
+ CFont::SetBackGroundOnlyTextOff();
+ int modelIndex = i;
+ if (modelIndex < NUMSTREAMINFO) {
+ int y = 24;
+ for ( ; j < 34 && modelIndex < NUMSTREAMINFO; modelIndex++) {
+ CStreamingInfo *streamingInfo = &ms_aInfoForModel[modelIndex];
+ CBaseModelInfo *modelInfo = CModelInfo::GetModelInfo(modelIndex);
+ if (streamingInfo->m_loadState != STREAMSTATE_LOADED || !streamingInfo->GetCdPosnAndSize(offset, size))
+ continue;
+
+ if (modelIndex >= STREAM_OFFSET_TXD)
+ sprintf(str, "txd %s, refs %d, size %dK, flags 0x%x", CTxdStore::GetTxdName(modelIndex - STREAM_OFFSET_TXD),
+ CTxdStore::GetNumRefs(modelIndex - STREAM_OFFSET_TXD), 2 * size, streamingInfo->m_flags);
+ else
+ sprintf(str, "model %d,%s, refs%d, size%dK, flags%x", modelIndex, modelInfo->GetName(), modelInfo->GetNumRefs(), 2 * size,
+ streamingInfo->m_flags);
+ AsciiToUnicode(str, wstr);
+ CFont::PrintString(24.0f, y, wstr);
+ y += 12;
+ j++;
+ }
+ }
+
+ if (CPad::GetPad(1)->GetCrossJustDown())
+ i = modelIndex;
+
+ if (!CPad::GetPad(1)->GetTriangleJustDown())
+ break;
+
+ i = 0;
+ CFont::DrawFonts();
+ DoRWStuffEndOfFrame();
+ }
+ CFont::DrawFonts();
+ DoRWStuffEndOfFrame();
+ }
+ CTimer::Update();
+} \ No newline at end of file
diff --git a/src/core/Streaming.h b/src/core/Streaming.h
index dd85ce97..a67384f6 100644
--- a/src/core/Streaming.h
+++ b/src/core/Streaming.h
@@ -197,11 +197,11 @@ public:
static void DeleteFarAwayRwObjects(const CVector &pos);
static void DeleteAllRwObjects(void);
static void DeleteRwObjectsAfterDeath(const CVector &pos);
- static void DeleteRwObjectsBehindCamera(size_t mem);
+ static void DeleteRwObjectsBehindCamera(size_t mem); // originally signed
static void DeleteRwObjectsInSectorList(CPtrList &list);
static void DeleteRwObjectsInOverlapSectorList(CPtrList &list, int32 x, int32 y);
- static bool DeleteRwObjectsBehindCameraInSectorList(CPtrList &list, size_t mem);
- static bool DeleteRwObjectsNotInFrustumInSectorList(CPtrList &list, size_t mem);
+ static bool DeleteRwObjectsBehindCameraInSectorList(CPtrList &list, size_t mem); // originally signed
+ static bool DeleteRwObjectsNotInFrustumInSectorList(CPtrList &list, size_t mem); // originally signed
static void LoadScene(const CVector &pos);
static void LoadSceneCollision(const CVector &pos);
@@ -210,4 +210,6 @@ public:
static void MemoryCardLoad(uint8 *buffer, uint32 length);
static void UpdateForAnimViewer(void);
+
+ static void PrintStreamingBufferState();
};
diff --git a/src/core/World.cpp b/src/core/World.cpp
index 4c700f10..6413a620 100644
--- a/src/core/World.cpp
+++ b/src/core/World.cpp
@@ -35,7 +35,7 @@
CColPoint gaTempSphereColPoints[MAX_COLLISION_POINTS];
-CPtrList CWorld::ms_bigBuildingsList[4];
+CPtrList CWorld::ms_bigBuildingsList[NUM_LEVELS];
CPtrList CWorld::ms_listMovingEntityPtrs;
CSector CWorld::ms_aSectors[NUMSECTORS_Y][NUMSECTORS_X];
uint16 CWorld::ms_nCurrentScanCode;
@@ -147,13 +147,13 @@ CWorld::ClearExcitingStuffFromArea(const CVector &pos, float radius, bool bRemov
}
}
CCarCtrl::RemoveFromInterestingVehicleList(pVehicle);
- CWorld::Remove(pVehicle);
+ Remove(pVehicle);
delete pVehicle;
}
}
CObject::DeleteAllTempObjectsInArea(pos, radius);
gFireManager.ExtinguishPoint(pos, radius);
- CWorld::ExtinguishAllCarFiresInArea(pos, radius);
+ ExtinguishAllCarFiresInArea(pos, radius);
CExplosion::RemoveAllExplosionsInArea(pos, radius);
if(bRemoveProjectilesAndTidyUpShadows) {
CProjectileInfo::RemoveAllProjectiles();
@@ -796,7 +796,7 @@ CWorld::FindObjectsOfTypeInRange(uint32 modelId, const CVector &position, float
int16 *nEntitiesFound, int16 maxEntitiesToFind, CEntity **aEntities, bool bBuildings,
bool bVehicles, bool bPeds, bool bObjects, bool bDummies)
{
- CWorld::AdvanceCurrentScanCode();
+ AdvanceCurrentScanCode();
*nEntitiesFound = 0;
const CVector2D vecSectorStartPos(position.x - radius, position.y - radius);
const CVector2D vecSectorEndPos(position.x + radius, position.y + radius);
@@ -813,42 +813,42 @@ CWorld::FindObjectsOfTypeInRange(uint32 modelId, const CVector &position, float
for(int32 x = nStartX; x <= nEndX; x++) {
CSector *pSector = GetSector(x, y);
if(bBuildings) {
- CWorld::FindObjectsOfTypeInRangeSectorList(
+ FindObjectsOfTypeInRangeSectorList(
modelId, pSector->m_lists[ENTITYLIST_BUILDINGS], position, radius, bCheck2DOnly,
nEntitiesFound, maxEntitiesToFind, aEntities);
- CWorld::FindObjectsOfTypeInRangeSectorList(
+ FindObjectsOfTypeInRangeSectorList(
modelId, pSector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP], position, radius,
bCheck2DOnly, nEntitiesFound, maxEntitiesToFind, aEntities);
}
if(bVehicles) {
- CWorld::FindObjectsOfTypeInRangeSectorList(
+ FindObjectsOfTypeInRangeSectorList(
modelId, pSector->m_lists[ENTITYLIST_VEHICLES], position, radius, bCheck2DOnly,
nEntitiesFound, maxEntitiesToFind, aEntities);
- CWorld::FindObjectsOfTypeInRangeSectorList(
+ FindObjectsOfTypeInRangeSectorList(
modelId, pSector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], position, radius,
bCheck2DOnly, nEntitiesFound, maxEntitiesToFind, aEntities);
}
if(bPeds) {
- CWorld::FindObjectsOfTypeInRangeSectorList(
+ FindObjectsOfTypeInRangeSectorList(
modelId, pSector->m_lists[ENTITYLIST_PEDS], position, radius, bCheck2DOnly,
nEntitiesFound, maxEntitiesToFind, aEntities);
- CWorld::FindObjectsOfTypeInRangeSectorList(
+ FindObjectsOfTypeInRangeSectorList(
modelId, pSector->m_lists[ENTITYLIST_PEDS_OVERLAP], position, radius, bCheck2DOnly,
nEntitiesFound, maxEntitiesToFind, aEntities);
}
if(bObjects) {
- CWorld::FindObjectsOfTypeInRangeSectorList(
+ FindObjectsOfTypeInRangeSectorList(
modelId, pSector->m_lists[ENTITYLIST_OBJECTS], position, radius, bCheck2DOnly,
nEntitiesFound, maxEntitiesToFind, aEntities);
- CWorld::FindObjectsOfTypeInRangeSectorList(
+ FindObjectsOfTypeInRangeSectorList(
modelId, pSector->m_lists[ENTITYLIST_OBJECTS_OVERLAP], position, radius,
bCheck2DOnly, nEntitiesFound, maxEntitiesToFind, aEntities);
}
if(bDummies) {
- CWorld::FindObjectsOfTypeInRangeSectorList(
+ FindObjectsOfTypeInRangeSectorList(
modelId, pSector->m_lists[ENTITYLIST_DUMMIES], position, radius, bCheck2DOnly,
nEntitiesFound, maxEntitiesToFind, aEntities);
- CWorld::FindObjectsOfTypeInRangeSectorList(
+ FindObjectsOfTypeInRangeSectorList(
modelId, pSector->m_lists[ENTITYLIST_DUMMIES_OVERLAP], position, radius,
bCheck2DOnly, nEntitiesFound, maxEntitiesToFind, aEntities);
}
@@ -942,26 +942,26 @@ CEntity *
CWorld::TestSphereAgainstSectorList(CPtrList &list, CVector spherePos, float radius, CEntity *entityToIgnore,
bool ignoreSomeObjects)
{
- static CColModel sphereCol;
+ static CColModel OurColModel;
CColSphere sphere;
- sphereCol.boundingSphere.center.x = 0.0f;
- sphereCol.boundingSphere.center.y = 0.0f;
- sphereCol.boundingSphere.center.z = 0.0f;
- sphereCol.boundingSphere.radius = radius;
- sphereCol.boundingBox.min.x = -radius;
- sphereCol.boundingBox.min.y = -radius;
- sphereCol.boundingBox.min.z = -radius;
- sphereCol.boundingBox.max.x = radius;
- sphereCol.boundingBox.max.y = radius;
- sphereCol.boundingBox.max.z = radius;
- sphereCol.numSpheres = 1;
+ OurColModel.boundingSphere.center.x = 0.0f;
+ OurColModel.boundingSphere.center.y = 0.0f;
+ OurColModel.boundingSphere.center.z = 0.0f;
+ OurColModel.boundingSphere.radius = radius;
+ OurColModel.boundingBox.min.x = -radius;
+ OurColModel.boundingBox.min.y = -radius;
+ OurColModel.boundingBox.min.z = -radius;
+ OurColModel.boundingBox.max.x = radius;
+ OurColModel.boundingBox.max.y = radius;
+ OurColModel.boundingBox.max.z = radius;
+ OurColModel.numSpheres = 1;
sphere.Set(radius, CVector(0.0f, 0.0f, 0.0f));
- sphereCol.spheres = &sphere;
- sphereCol.numLines = 0;
- sphereCol.numBoxes = 0;
- sphereCol.numTriangles = 0;
- sphereCol.ownsCollisionVolumes = false;
+ OurColModel.spheres = &sphere;
+ OurColModel.numLines = 0;
+ OurColModel.numBoxes = 0;
+ OurColModel.numTriangles = 0;
+ OurColModel.ownsCollisionVolumes = false;
CMatrix sphereMat;
sphereMat.SetTranslate(spherePos);
@@ -980,7 +980,7 @@ CWorld::TestSphereAgainstSectorList(CPtrList &list, CVector spherePos, float rad
if(e->GetBoundRadius() + radius > distance) {
CColModel *eCol = CModelInfo::GetModelInfo(e->GetModelIndex())->GetColModel();
int collidedSpheres =
- CCollision::ProcessColModels(sphereMat, sphereCol, e->GetMatrix(), *eCol,
+ CCollision::ProcessColModels(sphereMat, OurColModel, e->GetMatrix(), *eCol,
gaTempSphereColPoints, nil, nil);
if(collidedSpheres != 0 ||
@@ -1070,7 +1070,7 @@ CWorld::FindObjectsKindaColliding(const CVector &position, float radius, bool bC
int16 maxEntitiesToFind, CEntity **aEntities, bool bBuildings, bool bVehicles,
bool bPeds, bool bObjects, bool bDummies)
{
- CWorld::AdvanceCurrentScanCode();
+ AdvanceCurrentScanCode();
*nCollidingEntities = 0;
const CVector2D vecSectorStartPos(position.x - radius, position.y - radius);
const CVector2D vecSectorEndPos(position.x + radius, position.y + radius);
@@ -1087,42 +1087,42 @@ CWorld::FindObjectsKindaColliding(const CVector &position, float radius, bool bC
for(int32 x = nStartX; x <= nEndX; x++) {
CSector *pSector = GetSector(x, y);
if(bBuildings) {
- CWorld::FindObjectsKindaCollidingSectorList(
+ FindObjectsKindaCollidingSectorList(
pSector->m_lists[ENTITYLIST_BUILDINGS], position, radius, bCheck2DOnly,
nCollidingEntities, maxEntitiesToFind, aEntities);
- CWorld::FindObjectsKindaCollidingSectorList(
+ FindObjectsKindaCollidingSectorList(
pSector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP], position, radius, bCheck2DOnly,
nCollidingEntities, maxEntitiesToFind, aEntities);
}
if(bVehicles) {
- CWorld::FindObjectsKindaCollidingSectorList(
+ FindObjectsKindaCollidingSectorList(
pSector->m_lists[ENTITYLIST_VEHICLES], position, radius, bCheck2DOnly,
nCollidingEntities, maxEntitiesToFind, aEntities);
- CWorld::FindObjectsKindaCollidingSectorList(
+ FindObjectsKindaCollidingSectorList(
pSector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], position, radius, bCheck2DOnly,
nCollidingEntities, maxEntitiesToFind, aEntities);
}
if(bPeds) {
- CWorld::FindObjectsKindaCollidingSectorList(pSector->m_lists[ENTITYLIST_PEDS], position,
+ FindObjectsKindaCollidingSectorList(pSector->m_lists[ENTITYLIST_PEDS], position,
radius, bCheck2DOnly, nCollidingEntities,
maxEntitiesToFind, aEntities);
- CWorld::FindObjectsKindaCollidingSectorList(
+ FindObjectsKindaCollidingSectorList(
pSector->m_lists[ENTITYLIST_PEDS_OVERLAP], position, radius, bCheck2DOnly,
nCollidingEntities, maxEntitiesToFind, aEntities);
}
if(bObjects) {
- CWorld::FindObjectsKindaCollidingSectorList(
+ FindObjectsKindaCollidingSectorList(
pSector->m_lists[ENTITYLIST_OBJECTS], position, radius, bCheck2DOnly,
nCollidingEntities, maxEntitiesToFind, aEntities);
- CWorld::FindObjectsKindaCollidingSectorList(
+ FindObjectsKindaCollidingSectorList(
pSector->m_lists[ENTITYLIST_OBJECTS_OVERLAP], position, radius, bCheck2DOnly,
nCollidingEntities, maxEntitiesToFind, aEntities);
}
if(bDummies) {
- CWorld::FindObjectsKindaCollidingSectorList(
+ FindObjectsKindaCollidingSectorList(
pSector->m_lists[ENTITYLIST_DUMMIES], position, radius, bCheck2DOnly,
nCollidingEntities, maxEntitiesToFind, aEntities);
- CWorld::FindObjectsKindaCollidingSectorList(
+ FindObjectsKindaCollidingSectorList(
pSector->m_lists[ENTITYLIST_DUMMIES_OVERLAP], position, radius, bCheck2DOnly,
nCollidingEntities, maxEntitiesToFind, aEntities);
}
@@ -1156,7 +1156,7 @@ CWorld::FindObjectsIntersectingCube(const CVector &vecStartPos, const CVector &v
int16 maxEntitiesToFind, CEntity **aEntities, bool bBuildings, bool bVehicles,
bool bPeds, bool bObjects, bool bDummies)
{
- CWorld::AdvanceCurrentScanCode();
+ AdvanceCurrentScanCode();
*nIntersecting = 0;
const int32 nStartX = Max(GetSectorIndexX(vecStartPos.x), 0);
const int32 nStartY = Max(GetSectorIndexY(vecStartPos.y), 0);
@@ -1164,49 +1164,49 @@ CWorld::FindObjectsIntersectingCube(const CVector &vecStartPos, const CVector &v
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(vecSectorPos.x), NUMSECTORS_X);
- const int32 nEndY = Min(GetSectorIndexY(vecSectorPos.y), NUMSECTORS_Y);
+ const int32 nEndX = Min(GetSectorIndexX(vecStartPos.x), NUMSECTORS_X);
+ const int32 nEndY = Min(GetSectorIndexY(vecStartPos.y), NUMSECTORS_Y);
#endif
for(int32 y = nStartY; y <= nEndY; y++) {
for(int32 x = nStartX; x <= nEndX; x++) {
CSector *pSector = GetSector(x, y);
if(bBuildings) {
- CWorld::FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_BUILDINGS],
+ FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_BUILDINGS],
vecStartPos, vecEndPos, nIntersecting,
maxEntitiesToFind, aEntities);
- CWorld::FindObjectsIntersectingCubeSectorList(
+ FindObjectsIntersectingCubeSectorList(
pSector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP], vecStartPos, vecEndPos,
nIntersecting, maxEntitiesToFind, aEntities);
}
if(bVehicles) {
- CWorld::FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_VEHICLES],
+ FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_VEHICLES],
vecStartPos, vecEndPos, nIntersecting,
maxEntitiesToFind, aEntities);
- CWorld::FindObjectsIntersectingCubeSectorList(
+ FindObjectsIntersectingCubeSectorList(
pSector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], vecStartPos, vecEndPos,
nIntersecting, maxEntitiesToFind, aEntities);
}
if(bPeds) {
- CWorld::FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_PEDS],
+ FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_PEDS],
vecStartPos, vecEndPos, nIntersecting,
maxEntitiesToFind, aEntities);
- CWorld::FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_PEDS_OVERLAP],
+ FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_PEDS_OVERLAP],
vecStartPos, vecEndPos, nIntersecting,
maxEntitiesToFind, aEntities);
}
if(bObjects) {
- CWorld::FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_OBJECTS],
+ FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_OBJECTS],
vecStartPos, vecEndPos, nIntersecting,
maxEntitiesToFind, aEntities);
- CWorld::FindObjectsIntersectingCubeSectorList(
+ FindObjectsIntersectingCubeSectorList(
pSector->m_lists[ENTITYLIST_OBJECTS_OVERLAP], vecStartPos, vecEndPos, nIntersecting,
maxEntitiesToFind, aEntities);
}
if(bDummies) {
- CWorld::FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_DUMMIES],
+ FindObjectsIntersectingCubeSectorList(pSector->m_lists[ENTITYLIST_DUMMIES],
vecStartPos, vecEndPos, nIntersecting,
maxEntitiesToFind, aEntities);
- CWorld::FindObjectsIntersectingCubeSectorList(
+ FindObjectsIntersectingCubeSectorList(
pSector->m_lists[ENTITYLIST_DUMMIES_OVERLAP], vecStartPos, vecEndPos, nIntersecting,
maxEntitiesToFind, aEntities);
}
@@ -1242,7 +1242,7 @@ CWorld::FindObjectsIntersectingAngledCollisionBox(const CBox &boundingBox, const
CEntity **aEntities, bool bBuildings, bool bVehicles, bool bPeds,
bool bObjects, bool bDummies)
{
- CWorld::AdvanceCurrentScanCode();
+ AdvanceCurrentScanCode();
*nEntitiesFound = 0;
const int32 nStartX = Max(GetSectorIndexX(fStartX), 0);
const int32 nStartY = Max(GetSectorIndexY(fStartY), 0);
@@ -1257,42 +1257,42 @@ CWorld::FindObjectsIntersectingAngledCollisionBox(const CBox &boundingBox, const
for(int32 x = nStartX; x <= nEndX; x++) {
CSector *pSector = GetSector(x, y);
if(bBuildings) {
- CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList(
+ FindObjectsIntersectingAngledCollisionBoxSectorList(
pSector->m_lists[ENTITYLIST_BUILDINGS], boundingBox, matrix, position,
nEntitiesFound, maxEntitiesToFind, aEntities);
- CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList(
+ FindObjectsIntersectingAngledCollisionBoxSectorList(
pSector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP], boundingBox, matrix, position,
nEntitiesFound, maxEntitiesToFind, aEntities);
}
if(bVehicles) {
- CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList(
+ FindObjectsIntersectingAngledCollisionBoxSectorList(
pSector->m_lists[ENTITYLIST_VEHICLES], boundingBox, matrix, position,
nEntitiesFound, maxEntitiesToFind, aEntities);
- CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList(
+ FindObjectsIntersectingAngledCollisionBoxSectorList(
pSector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], boundingBox, matrix, position,
nEntitiesFound, maxEntitiesToFind, aEntities);
}
if(bPeds) {
- CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList(
+ FindObjectsIntersectingAngledCollisionBoxSectorList(
pSector->m_lists[ENTITYLIST_PEDS], boundingBox, matrix, position, nEntitiesFound,
maxEntitiesToFind, aEntities);
- CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList(
+ FindObjectsIntersectingAngledCollisionBoxSectorList(
pSector->m_lists[ENTITYLIST_PEDS_OVERLAP], boundingBox, matrix, position,
nEntitiesFound, maxEntitiesToFind, aEntities);
}
if(bObjects) {
- CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList(
+ FindObjectsIntersectingAngledCollisionBoxSectorList(
pSector->m_lists[ENTITYLIST_OBJECTS], boundingBox, matrix, position, nEntitiesFound,
maxEntitiesToFind, aEntities);
- CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList(
+ FindObjectsIntersectingAngledCollisionBoxSectorList(
pSector->m_lists[ENTITYLIST_OBJECTS_OVERLAP], boundingBox, matrix, position,
nEntitiesFound, maxEntitiesToFind, aEntities);
}
if(bDummies) {
- CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList(
+ FindObjectsIntersectingAngledCollisionBoxSectorList(
pSector->m_lists[ENTITYLIST_DUMMIES], boundingBox, matrix, position, nEntitiesFound,
maxEntitiesToFind, aEntities);
- CWorld::FindObjectsIntersectingAngledCollisionBoxSectorList(
+ FindObjectsIntersectingAngledCollisionBoxSectorList(
pSector->m_lists[ENTITYLIST_DUMMIES_OVERLAP], boundingBox, matrix, position,
nEntitiesFound, maxEntitiesToFind, aEntities);
}
@@ -1327,7 +1327,7 @@ CWorld::FindMissionEntitiesIntersectingCube(const CVector &vecStartPos, const CV
int16 maxEntitiesToFind, CEntity **aEntities, bool bVehicles, bool bPeds,
bool bObjects)
{
- CWorld::AdvanceCurrentScanCode();
+ AdvanceCurrentScanCode();
*nIntersecting = 0;
const int32 nStartX = Max(GetSectorIndexX(vecStartPos.x), 0);
const int32 nStartY = Max(GetSectorIndexY(vecStartPos.y), 0);
@@ -1342,26 +1342,26 @@ CWorld::FindMissionEntitiesIntersectingCube(const CVector &vecStartPos, const CV
for(int32 x = nStartX; x <= nEndX; x++) {
CSector *pSector = GetSector(x, y);
if(bVehicles) {
- CWorld::FindMissionEntitiesIntersectingCubeSectorList(
+ FindMissionEntitiesIntersectingCubeSectorList(
pSector->m_lists[ENTITYLIST_VEHICLES], vecStartPos, vecEndPos, nIntersecting,
maxEntitiesToFind, aEntities, true, false);
- CWorld::FindMissionEntitiesIntersectingCubeSectorList(
+ FindMissionEntitiesIntersectingCubeSectorList(
pSector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], vecStartPos, vecEndPos,
nIntersecting, maxEntitiesToFind, aEntities, true, false);
}
if(bPeds) {
- CWorld::FindMissionEntitiesIntersectingCubeSectorList(
+ FindMissionEntitiesIntersectingCubeSectorList(
pSector->m_lists[ENTITYLIST_PEDS], vecStartPos, vecEndPos, nIntersecting,
maxEntitiesToFind, aEntities, false, true);
- CWorld::FindMissionEntitiesIntersectingCubeSectorList(
+ FindMissionEntitiesIntersectingCubeSectorList(
pSector->m_lists[ENTITYLIST_PEDS_OVERLAP], vecStartPos, vecEndPos, nIntersecting,
maxEntitiesToFind, aEntities, false, true);
}
if(bObjects) {
- CWorld::FindMissionEntitiesIntersectingCubeSectorList(
+ FindMissionEntitiesIntersectingCubeSectorList(
pSector->m_lists[ENTITYLIST_OBJECTS], vecStartPos, vecEndPos, nIntersecting,
maxEntitiesToFind, aEntities, false, false);
- CWorld::FindMissionEntitiesIntersectingCubeSectorList(
+ FindMissionEntitiesIntersectingCubeSectorList(
pSector->m_lists[ENTITYLIST_OBJECTS_OVERLAP], vecStartPos, vecEndPos, nIntersecting,
maxEntitiesToFind, aEntities, false, false);
}
@@ -1399,102 +1399,6 @@ CWorld::FindMissionEntitiesIntersectingCubeSectorList(CPtrList &list, const CVec
}
}
-CPlayerPed *
-FindPlayerPed(void)
-{
- return CWorld::Players[CWorld::PlayerInFocus].m_pPed;
-}
-
-CVehicle *
-FindPlayerVehicle(void)
-{
- CPlayerPed *ped = FindPlayerPed();
- if(ped && ped->InVehicle()) return ped->m_pMyVehicle;
- return nil;
-}
-
-CVehicle *
-FindPlayerTrain(void)
-{
- if(FindPlayerVehicle() && FindPlayerVehicle()->IsTrain())
- return FindPlayerVehicle();
- else
- return nil;
-}
-
-CEntity *
-FindPlayerEntity(void)
-{
- CPlayerPed *ped = FindPlayerPed();
- if(ped->InVehicle())
- return ped->m_pMyVehicle;
- else
- return ped;
-}
-
-CVector
-FindPlayerCoors(void)
-{
-#ifdef FIX_BUGS
- if (CReplay::IsPlayingBack())
- return TheCamera.GetPosition();
-#endif
- CPlayerPed *ped = FindPlayerPed();
- if(ped->InVehicle())
- return ped->m_pMyVehicle->GetPosition();
- else
- return ped->GetPosition();
-}
-
-CVector &
-FindPlayerSpeed(void)
-{
-#ifdef FIX_BUGS
- static CVector vecTmpVector(0.0f, 0.0f, 0.0f);
- if (CReplay::IsPlayingBack())
- return vecTmpVector;
-#endif
- CPlayerPed *ped = FindPlayerPed();
- if(ped->InVehicle())
- return ped->m_pMyVehicle->m_vecMoveSpeed;
- else
- return ped->m_vecMoveSpeed;
-}
-
-const CVector &
-FindPlayerCentreOfWorld(int32 player)
-{
-#ifdef FIX_BUGS
- if(CReplay::IsPlayingBack()) return TheCamera.GetPosition();
-#endif
- if(CCarCtrl::bCarsGeneratedAroundCamera) return TheCamera.GetPosition();
- if(CWorld::Players[player].m_pRemoteVehicle) return CWorld::Players[player].m_pRemoteVehicle->GetPosition();
- if(FindPlayerVehicle()) return FindPlayerVehicle()->GetPosition();
- return CWorld::Players[player].m_pPed->GetPosition();
-}
-
-const CVector &
-FindPlayerCentreOfWorld_NoSniperShift(void)
-{
-#ifdef FIX_BUGS
- if (CReplay::IsPlayingBack()) return TheCamera.GetPosition();
-#endif
- if(CCarCtrl::bCarsGeneratedAroundCamera) return TheCamera.GetPosition();
- if(CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle)
- return CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle->GetPosition();
- if(FindPlayerVehicle()) return FindPlayerVehicle()->GetPosition();
- return FindPlayerPed()->GetPosition();
-}
-
-float
-FindPlayerHeading(void)
-{
- if(CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle)
- return CWorld::Players[CWorld::PlayerInFocus].m_pRemoteVehicle->GetForward().Heading();
- if(FindPlayerVehicle()) return FindPlayerVehicle()->GetForward().Heading();
- return FindPlayerPed()->GetForward().Heading();
-}
-
void
CWorld::ClearCarsFromArea(float x1, float y1, float z1, float x2, float y2, float z2)
{
@@ -1517,7 +1421,7 @@ CWorld::ClearCarsFromArea(float x1, float y1, float z1, float x2, float y2, floa
}
}
CCarCtrl::RemoveFromInterestingVehicleList(pVehicle);
- CWorld::Remove(pVehicle);
+ Remove(pVehicle);
delete pVehicle;
}
}
@@ -1543,7 +1447,7 @@ CWorld::ClearPedsFromArea(float x1, float y1, float z1, float x2, float y2, floa
void
CWorld::CallOffChaseForArea(float x1, float y1, float x2, float y2)
{
- CWorld::AdvanceCurrentScanCode();
+ AdvanceCurrentScanCode();
float fStartX = x1 - 10.0f;
float fStartY = y1 - 10.0f;
float fEndX = x2 + 10.0f;
@@ -1560,12 +1464,12 @@ CWorld::CallOffChaseForArea(float x1, float y1, float x2, float y2)
for(int32 y = nStartY; y <= nEndY; y++) {
for(int32 x = nStartX; x <= nEndX; x++) {
CSector *pSector = GetSector(x, y);
- CWorld::CallOffChaseForAreaSectorListVehicles(pSector->m_lists[ENTITYLIST_VEHICLES], x1, y1, x2,
+ CallOffChaseForAreaSectorListVehicles(pSector->m_lists[ENTITYLIST_VEHICLES], x1, y1, x2,
y2, fStartX, fStartY, fEndX, fEndY);
- CWorld::CallOffChaseForAreaSectorListVehicles(pSector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], x1,
+ CallOffChaseForAreaSectorListVehicles(pSector->m_lists[ENTITYLIST_VEHICLES_OVERLAP], x1,
y1, x2, y2, fStartX, fStartY, fEndX, fEndY);
- CWorld::CallOffChaseForAreaSectorListPeds(pSector->m_lists[ENTITYLIST_PEDS], x1, y1, x2, y2);
- CWorld::CallOffChaseForAreaSectorListPeds(pSector->m_lists[ENTITYLIST_PEDS_OVERLAP], x1, y1, x2,
+ CallOffChaseForAreaSectorListPeds(pSector->m_lists[ENTITYLIST_PEDS], x1, y1, x2, y2);
+ CallOffChaseForAreaSectorListPeds(pSector->m_lists[ENTITYLIST_PEDS_OVERLAP], x1, y1, x2,
y2);
}
}
@@ -1580,7 +1484,7 @@ CWorld::CallOffChaseForAreaSectorListVehicles(CPtrList &list, float x1, float y1
if(pVehicle->m_scanCode != GetCurrentScanCode()) {
pVehicle->m_scanCode = GetCurrentScanCode();
const CVector &vehiclePos = pVehicle->GetPosition();
- eCarMission carMission = pVehicle->AutoPilot.m_nCarMission;
+ uint8 carMission = pVehicle->AutoPilot.m_nCarMission;
if(pVehicle != FindPlayerVehicle() && vehiclePos.x > fStartX && vehiclePos.x < fEndX &&
vehiclePos.y > fStartY && vehiclePos.y < fEndY && pVehicle->bIsLawEnforcer &&
(carMission == MISSION_RAMPLAYER_FARAWAY || carMission == MISSION_RAMPLAYER_CLOSE ||
@@ -1739,14 +1643,24 @@ CWorld::ExtinguishAllCarFiresInArea(CVector point, float range)
}
}
+inline void
+AddSteamsFromGround(CPtrList& list)
+{
+ CPtrNode* pNode = list.first;
+ while (pNode) {
+ ((CEntity*)pNode->item)->AddSteamsFromGround(nil);
+ pNode = pNode->next;
+ }
+}
+
void
CWorld::AddParticles(void)
{
for(int32 y = 0; y < NUMSECTORS_Y; y++) {
for(int32 x = 0; x < NUMSECTORS_X; x++) {
CSector *pSector = GetSector(x, y);
- CEntity::AddSteamsFromGround(pSector->m_lists[ENTITYLIST_BUILDINGS]);
- CEntity::AddSteamsFromGround(pSector->m_lists[ENTITYLIST_DUMMIES]);
+ AddSteamsFromGround(pSector->m_lists[ENTITYLIST_BUILDINGS]);
+ AddSteamsFromGround(pSector->m_lists[ENTITYLIST_DUMMIES]);
}
}
}
@@ -1758,44 +1672,52 @@ CWorld::ShutDown(void)
CSector *pSector = GetSector(i % NUMSECTORS_X, i / NUMSECTORS_Y);
for(CPtrNode *pNode = pSector->m_lists[ENTITYLIST_BUILDINGS].first; pNode; pNode = pNode->next) {
CEntity *pEntity = (CEntity *)pNode->item;
- CWorld::Remove(pEntity);
+ Remove(pEntity);
delete pEntity;
}
for(CPtrNode *pNode = pSector->m_lists[ENTITYLIST_VEHICLES].first; pNode; pNode = pNode->next) {
CEntity *pEntity = (CEntity *)pNode->item;
- CWorld::Remove(pEntity);
+ Remove(pEntity);
delete pEntity;
}
for(CPtrNode *pNode = pSector->m_lists[ENTITYLIST_PEDS].first; pNode; pNode = pNode->next) {
CEntity *pEntity = (CEntity *)pNode->item;
- CWorld::Remove(pEntity);
+ Remove(pEntity);
delete pEntity;
}
for(CPtrNode *pNode = pSector->m_lists[ENTITYLIST_OBJECTS].first; pNode; pNode = pNode->next) {
CEntity *pEntity = (CEntity *)pNode->item;
- CWorld::Remove(pEntity);
+ Remove(pEntity);
delete pEntity;
}
for(CPtrNode *pNode = pSector->m_lists[ENTITYLIST_DUMMIES].first; pNode; pNode = pNode->next) {
CEntity *pEntity = (CEntity *)pNode->item;
- CWorld::Remove(pEntity);
+ Remove(pEntity);
delete pEntity;
}
+#ifndef FIX_BUGS
pSector->m_lists[ENTITYLIST_BUILDINGS].Flush();
pSector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP].Flush();
pSector->m_lists[ENTITYLIST_DUMMIES].Flush();
pSector->m_lists[ENTITYLIST_DUMMIES_OVERLAP].Flush();
+#endif
}
- for(int32 i = 0; i < 4; i++) {
- for(CPtrNode *pNode = GetBigBuildingList((eLevelName)i).first; pNode; pNode = pNode->next) {
+ for(int32 i = 0; i < NUM_LEVELS; i++) {
+ for(CPtrNode *pNode = ms_bigBuildingsList[i].first; pNode; pNode = pNode->next) {
CEntity *pEntity = (CEntity *)pNode->item;
// Maybe remove from world here?
delete pEntity;
}
- GetBigBuildingList((eLevelName)i).Flush();
+ ms_bigBuildingsList[i].Flush();
}
for(int i = 0; i < NUMSECTORS_X * NUMSECTORS_Y; i++) {
CSector *pSector = GetSector(i % NUMSECTORS_X, i / NUMSECTORS_Y);
+#ifdef FIX_BUGS
+ pSector->m_lists[ENTITYLIST_BUILDINGS].Flush();
+ pSector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP].Flush();
+ pSector->m_lists[ENTITYLIST_DUMMIES].Flush();
+ pSector->m_lists[ENTITYLIST_DUMMIES_OVERLAP].Flush();
+#endif
if(pSector->m_lists[ENTITYLIST_BUILDINGS].first) {
sprintf(gString, "Building list %d,%d not empty\n", i % NUMSECTORS_X, i / NUMSECTORS_Y);
pSector->m_lists[ENTITYLIST_BUILDINGS].Flush();
@@ -1840,19 +1762,19 @@ CWorld::ClearForRestart(void)
CSector *pSector = GetSector(i % NUMSECTORS_X, i / NUMSECTORS_Y);
for(CPtrNode *pNode = pSector->m_lists[ENTITYLIST_PEDS].first; pNode; pNode = pNode->next) {
CEntity *pEntity = (CEntity *)pNode->item;
- CWorld::Remove(pEntity);
+ Remove(pEntity);
delete pEntity;
}
for(CPtrNode *pNode = GetBigBuildingList(LEVEL_GENERIC).first; pNode; pNode = pNode->next) {
CVehicle *pVehicle = (CVehicle *)pNode->item;
if(pVehicle && pVehicle->IsVehicle() && pVehicle->IsPlane()) {
- CWorld::Remove(pVehicle);
+ Remove(pVehicle);
delete pVehicle;
}
}
for(CPtrNode *pNode = pSector->m_lists[ENTITYLIST_VEHICLES].first; pNode; pNode = pNode->next) {
CEntity *pEntity = (CEntity *)pNode->item;
- CWorld::Remove(pEntity);
+ Remove(pEntity);
delete pEntity;
}
}
@@ -1885,7 +1807,7 @@ CWorld::RepositionOneObject(CEntity *pEntity)
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 = FindGroundZFor3DCoord(position.x, position.y,
position.z + fHeight, nil) -
fBoundingBoxMinZ;
pEntity->m_matrix.UpdateRW();
@@ -1918,7 +1840,7 @@ CWorld::RepositionOneObject(CEntity *pEntity)
if(modelId == MI_BUOY) {
bool bFound = true;
const CVector &position = pEntity->GetPosition();
- float fGroundZ = CWorld::FindGroundZFor3DCoord(position.x, position.y,
+ float fGroundZ = FindGroundZFor3DCoord(position.x, position.y,
position.z + OBJECT_REPOSITION_OFFSET_Z, &bFound);
CColModel *pColModel = pEntity->GetColModel();
float fHeight = pColModel->boundingBox.max.z - pColModel->boundingBox.min.z;
@@ -1983,17 +1905,17 @@ CWorld::RemoveStaticObjects()
CSector *pSector = GetSector(i % NUMSECTORS_X, i / NUMSECTORS_Y);
for(CPtrNode *pNode = pSector->m_lists[ENTITYLIST_BUILDINGS].first; pNode; pNode = pNode->next) {
CEntity *pEntity = (CEntity *)pNode->item;
- CWorld::Remove(pEntity);
+ Remove(pEntity);
delete pEntity;
}
for(CPtrNode *pNode = pSector->m_lists[ENTITYLIST_OBJECTS].first; pNode; pNode = pNode->next) {
CEntity *pEntity = (CEntity *)pNode->item;
- CWorld::Remove(pEntity);
+ Remove(pEntity);
delete pEntity;
}
for(CPtrNode *pNode = pSector->m_lists[ENTITYLIST_DUMMIES].first; pNode; pNode = pNode->next) {
CEntity *pEntity = (CEntity *)pNode->item;
- CWorld::Remove(pEntity);
+ Remove(pEntity);
delete pEntity;
}
pSector->m_lists[ENTITYLIST_BUILDINGS].Flush();
@@ -2017,7 +1939,8 @@ CWorld::Process(void)
if (csObj->IsObject())
RpAnimBlendClumpUpdateAnimations(csObj->GetClump(), 0.02f * CTimer::GetTimeStepNonClipped());
else {
- csObj->bOffscreen = !csObj->GetIsOnScreen();
+ if (!csObj->bOffscreen)
+ csObj->bOffscreen = !csObj->GetIsOnScreen();
RpAnimBlendClumpUpdateAnimations(csObj->GetClump(), 0.02f * CTimer::GetTimeStep(), !csObj->bOffscreen);
}
}
@@ -2032,17 +1955,13 @@ CWorld::Process(void)
} else {
for(CPtrNode *node = ms_listMovingEntityPtrs.first; node; node = node->next) {
CEntity *movingEnt = (CEntity *)node->item;
-#ifdef SQUEEZE_PERFORMANCE
- if (movingEnt->bRemoveFromWorld) {
- RemoveEntityInsteadOfProcessingIt(movingEnt);
- } else
-#endif
- if(movingEnt->m_rwObject && RwObjectGetType(movingEnt->m_rwObject) == rpCLUMP &&
+ if(!movingEnt->bRemoveFromWorld && movingEnt->m_rwObject && RwObjectGetType(movingEnt->m_rwObject) == rpCLUMP &&
RpAnimBlendClumpGetFirstAssociation(movingEnt->GetClump())) {
if (movingEnt->IsObject())
RpAnimBlendClumpUpdateAnimations(movingEnt->GetClump(), 0.02f * CTimer::GetTimeStepNonClipped());
else {
- movingEnt->bOffscreen = !movingEnt->GetIsOnScreen();
+ if (!movingEnt->bOffscreen)
+ movingEnt->bOffscreen = !movingEnt->GetIsOnScreen();
RpAnimBlendClumpUpdateAnimations(movingEnt->GetClump(), 0.02f * CTimer::GetTimeStep(), !movingEnt->bOffscreen);
}
}
@@ -2200,11 +2119,11 @@ CWorld::TriggerExplosion(const CVector &position, float fRadius, float fPower, C
for(int32 y = nStartY; y <= nEndY; y++) {
for(int32 x = nStartX; x <= nEndX; x++) {
CSector *pSector = GetSector(x, y);
- CWorld::TriggerExplosionSectorList(pSector->m_lists[ENTITYLIST_VEHICLES], position, fRadius,
+ TriggerExplosionSectorList(pSector->m_lists[ENTITYLIST_VEHICLES], position, fRadius,
fPower, pCreator, bProcessVehicleBombTimer);
- CWorld::TriggerExplosionSectorList(pSector->m_lists[ENTITYLIST_PEDS], position, fRadius, fPower,
+ TriggerExplosionSectorList(pSector->m_lists[ENTITYLIST_PEDS], position, fRadius, fPower,
pCreator, bProcessVehicleBombTimer);
- CWorld::TriggerExplosionSectorList(pSector->m_lists[ENTITYLIST_OBJECTS], position, fRadius,
+ TriggerExplosionSectorList(pSector->m_lists[ENTITYLIST_OBJECTS], position, fRadius,
fPower, pCreator, bProcessVehicleBombTimer);
}
}
@@ -2262,7 +2181,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 / 14000.0f * fDamageMultiplier /
+ vecDistance * (fPower * pEntity->m_fMass / 1400.0f * fDamageMultiplier /
Max(fMagnitude, 0.01f));
vecForceDir.z = Max(vecForceDir.z, 0.0f);
if(pEntity == FindPlayerPed()) vecForceDir.z = Min(vecForceDir.z, 1.0f);
diff --git a/src/core/World.h b/src/core/World.h
index be32db20..59bf634c 100644
--- a/src/core/World.h
+++ b/src/core/World.h
@@ -55,7 +55,7 @@ struct CStoredCollPoly;
class CWorld
{
- static CPtrList ms_bigBuildingsList[4];
+ static CPtrList ms_bigBuildingsList[NUM_LEVELS];
static CPtrList ms_listMovingEntityPtrs;
static CSector ms_aSectors[NUMSECTORS_Y][NUMSECTORS_X];
static uint16 ms_nCurrentScanCode;
@@ -178,15 +178,3 @@ public:
};
extern CColPoint gaTempSphereColPoints[MAX_COLLISION_POINTS];
-
-class CPlayerPed;
-class CVehicle;
-CPlayerPed *FindPlayerPed(void);
-CVehicle *FindPlayerVehicle(void);
-CVehicle *FindPlayerTrain(void);
-CEntity *FindPlayerEntity(void);
-CVector FindPlayerCoors(void);
-CVector &FindPlayerSpeed(void);
-const CVector &FindPlayerCentreOfWorld(int32 player);
-const CVector &FindPlayerCentreOfWorld_NoSniperShift(void);
-float FindPlayerHeading(void);
diff --git a/src/core/ZoneCull.h b/src/core/ZoneCull.h
index 8200b09a..d7780caf 100644
--- a/src/core/ZoneCull.h
+++ b/src/core/ZoneCull.h
@@ -17,12 +17,12 @@ enum eZoneAttribs
struct CAttributeZone
{
- float minx;
- float maxx;
- float miny;
- float maxy;
- float minz;
- float maxz;
+ int16 minx;
+ int16 maxx;
+ int16 miny;
+ int16 maxy;
+ int16 minz;
+ int16 maxz;
int16 attributes;
int16 wantedLevel;
};
diff --git a/src/core/Zones.cpp b/src/core/Zones.cpp
index 8abe0f1e..55b43c10 100644
--- a/src/core/Zones.cpp
+++ b/src/core/Zones.cpp
@@ -209,6 +209,9 @@ CTheZones::PostZoneCreation(void)
for(i = 1; i < TotalNumberOfNavigationZones; i++)
InsertZoneIntoZoneHierarchy(&NavigationZoneArray[i]);
InitialiseAudioZoneArray();
+#ifndef MASTER
+ CheckZonesForOverlap();
+#endif
}
void
@@ -222,8 +225,7 @@ CTheZones::CheckZonesForOverlap(void)
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);
+ sprintf(str, "Info zone %s contains %s\n", InfoZoneArray[j].name, InfoZoneArray[i].name);
}
}
diff --git a/src/core/common.h b/src/core/common.h
index 0e6bd60f..155b5dba 100644
--- a/src/core/common.h
+++ b/src/core/common.h
@@ -73,21 +73,24 @@ typedef int16_t int16;
typedef uint32_t uint32;
typedef int32_t int32;
typedef uintptr_t uintptr;
+typedef intptr_t intptr;
typedef uint64_t uint64;
typedef int64_t int64;
// hardcode ucs-2
typedef uint16_t wchar;
+#if defined(_MSC_VER)
+typedef ptrdiff_t ssize_t;
+#endif
+
#ifndef nil
#define nil NULL
#endif
#include "config.h"
-#ifdef PED_SKIN
#include <rphanim.h>
#include <rpskin.h>
-#endif
#ifdef __GNUC__
#define TYPEALIGN(n) __attribute__ ((aligned (n)))
@@ -220,6 +223,8 @@ 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))
@@ -249,8 +254,14 @@ void re3_usererror(const char *format, ...);
#define DEBUGBREAK() __debugbreak();
-#define debug(f, ...) re3_debug("[DBG]: " f, ## __VA_ARGS__)
+// Switch to enable development messages.
+#if 1
+#define DEV(f, ...)
+#else
#define DEV(f, ...) re3_debug("[DEV]: " f, ## __VA_ARGS__)
+#endif
+
+#define debug(f, ...) re3_debug("[DBG]: " f, ## __VA_ARGS__)
#define TRACE(f, ...) re3_trace(__FILE__, __LINE__, __FUNCTION__, f, ## __VA_ARGS__)
#define Error(f, ...) re3_debug("[ERROR]: " f, ## __VA_ARGS__)
#define USERERROR(f, ...) re3_usererror(f, ## __VA_ARGS__)
@@ -487,4 +498,4 @@ inline T *WriteSaveBuf(uint8 *&buf, uint32 &length, const T &value)
assert(ReadSaveBuf<uint32>(buf,len) == size);
-void cprintf(char*, ...); \ No newline at end of file
+void cprintf(char*, ...);
diff --git a/src/core/config.h b/src/core/config.h
index 822cf83f..8fd3bc1c 100644
--- a/src/core/config.h
+++ b/src/core/config.h
@@ -7,7 +7,7 @@ enum Config {
MAX_CDIMAGES = 8, // additional cdimages
MAX_CDCHANNELS = 5,
- MODELINFOSIZE = 6500,
+ MODELINFOSIZE = 6500, // 4900 on PS2
TXDSTORESIZE = 1385,
COLSTORESIZE = 31,
EXTRADIRSIZE = 256,
@@ -36,7 +36,7 @@ enum Config {
NUMDUMMIES = 2340,
NUMAUDIOSCRIPTOBJECTS = 192,
NUMCOLMODELS = 4400,
- NUMCUTSCENEOBJECTS = 50, // does not exist in VC
+ NUMCUTSCENEOBJECTS = 50, // not a pool in VC
NUMANIMBLOCKS = 35,
NUMANIMATIONS = 450,
@@ -146,10 +146,6 @@ enum Config {
NUM_SHORTCUT_START_POINTS = 16
};
-// We'll use this once we're ready to become independent of the game
-// Use it to mark bugs in the code that will prevent the game from working then
-//#define STANDALONE
-
// We don't expect to compile for PS2 or Xbox
// but it might be interesting for documentation purposes
#define GTA_PC
@@ -176,6 +172,19 @@ enum Config {
#define FINAL
#endif
+// Version defines
+#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 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
#define NO_CDCHECK
@@ -183,23 +192,30 @@ enum Config {
// those infamous texts
#define DRAW_GAME_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 VU_COLLISION
#elif defined GTA_PC
-//# define GTA3_STEAM_PATCH
-//# define GTAVC_JP_PATCH
# ifdef GTA_PS2_STUFF
# define USE_PS2_RAND
# define RANDOMSPLASH // use random splash as on PS2
# define PS2_MATFX
# endif
+# define PC_PLAYER_CONTROLS // mouse player/cam mode
+# define GTA_REPLAY
+# define GTA_SCENE_EDIT
#elif defined GTA_XBOX
#endif
#ifdef VU_COLLISION
-#define COMPRESSED_COL_VECTORS // current need compressed vectors in this code
+#define COMPRESSED_COL_VECTORS // currently need compressed vectors in this code
#endif
#ifdef MASTER
@@ -225,6 +241,7 @@ enum Config {
#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
@@ -240,24 +257,20 @@ enum Config {
#define PS2_ALPHA_TEST // emulate ps2 alpha test
#define IMPROVED_VIDEOMODE // save and load videomode parameters instead of a magic number
#define DISABLE_LOADING_SCREEN // disable the loading screen which vastly improves the loading time
-//#define NO_ISLAND_LOADING // disable loadscreen between islands via loading all island data at once, consumes more memory and CPU
+#define DISABLE_VSYNC_ON_TEXTURE_CONVERSION // make texture conversion work faster by disabling vsync
//#define USE_TEXTURE_POOL
-//#define CUTSCENE_BORDERS_SWITCH
#ifdef LIBRW
-//#define EXTENDED_COLOURFILTER // more options for colour filter (replaces mblur)
-//#define EXTENDED_PIPELINES // custom render pipelines (includes Neo)
-//#define NEW_RENDERER // leeds-like world rendering, needs librw
+#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
-//#define MULTISAMPLING // adds MSAA option TODO
-#ifdef LIBRW
-// these are not supported with librw yet
-# undef MULTISAMPLING
+#ifndef EXTENDED_COLOURFILTER
+#undef SCREEN_DROPLETS // we need the backbuffer for this effect
#endif
// Water & Particle
-#define PC_PARTICLE
-//#define PS2_ALTERNATIVE_CARSPLASH // unused on PS2
// #define PC_WATER
#define WATER_CHEATS
@@ -278,32 +291,48 @@ enum Config {
#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 BETA_SLIDING_TEXT
#define PC_MENU
#ifndef PC_MENU
# define PS2_MENU
//# define PS2_MENU_USEALLPAGEICONS
#else
-# define MAP_ENHANCEMENTS // Adding waypoint etc.
+# define MAP_ENHANCEMENTS // Adding waypoint and better mouse support
# define TRIANGLE_BACK_BUTTON
//# define CIRCLE_BACK_BUTTON
-//#define CUSTOM_FRONTEND_OPTIONS
-# define GRAPHICS_MENU_OPTIONS
-#define LEGACY_MENU_OPTIONS
+#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 CUTSCENE_BORDERS_SWITCH
+//# define MULTISAMPLING // adds MSAA option
+# define INVERT_LOOK_FOR_PAD // enable the hidden option
+# endif
+#endif
// Script
#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
#endif
//#define SIMPLIER_MISSIONS // apply simplifications from mobile
#define USE_ADVANCED_SCRIPT_DEBUG_OUTPUT
-#define SCRIPT_LOG_FILE_LEVEL 1 // 0 == no log, 1 == overwrite every frame, 2 == full log
+#define SCRIPT_LOG_FILE_LEVEL 0 // 0 == no log, 1 == overwrite every frame, 2 == full log
#ifndef USE_ADVANCED_SCRIPT_DEBUG_OUTPUT
#define USE_BASIC_SCRIPT_DEBUG_OUTPUT
@@ -322,9 +351,6 @@ enum Config {
#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 CANCELLABLE_CAR_ENTER
// Camera
@@ -336,10 +362,15 @@ enum Config {
//#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
+
//#define SQUEEZE_PERFORMANCE
#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
diff --git a/src/core/main.cpp b/src/core/main.cpp
index 48e0ff76..85e04540 100644
--- a/src/core/main.cpp
+++ b/src/core/main.cpp
@@ -63,12 +63,15 @@
#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"
GlobalScene Scene;
@@ -86,7 +89,7 @@ bool gbModelViewer;
bool gbShowTimebars;
#endif
-int32 frameCount;
+volatile int32 frameCount;
RwRGBA gColourTop;
@@ -107,8 +110,24 @@ void TheGame(void);
void DebugMenuPopulate(void);
#endif
+#ifndef FINAL
+bool gbPrintMemoryUsage;
+#endif
+
+#ifdef GTA_PS2
+#define WANT_TO_LOAD TheMemoryCard.m_bWantToLoad
+#define FOUND_GAME_TO_LOAD TheMemoryCard.b_FoundRecentSavedGameWantToLoad
+#else
+#define WANT_TO_LOAD FrontEndMenuManager.m_bWantToLoad
+#define FOUND_GAME_TO_LOAD b_FoundRecentSavedGameWantToLoad
+#endif
+
#ifdef NEW_RENDERER
bool gbNewRenderer;
+#endif
+#ifdef FIX_BUGS
+// need to clear stencil for mblur fx. no idea why it works in the original game
+// also for clearing out water rects in new renderer
#define CLEARMODE (rwCAMERACLEARZ | rwCAMERACLEARSTENCIL)
#else
#define CLEARMODE (rwCAMERACLEARZ)
@@ -389,21 +408,82 @@ PluginAttach(void)
return TRUE;
}
+#ifdef GTA_PS2
+#define NUM_PREALLOC_ATOMICS 1800
+#define NUM_PREALLOC_CLUMPS 80
+#define NUM_PREALLOC_FRAMES 2600
+#define NUM_PREALLOC_GEOMETRIES 850
+#define NUM_PREALLOC_TEXDICTS 121
+#define NUM_PREALLOC_TEXTURES 1700
+#define NUM_PREALLOC_MATERIALS 2600
+bool preAlloc;
+
+void
+PreAllocateRwObjects(void)
+{
+ int i;
+
+ PUSH_MEMID(MEMID_PRE_ALLOC);
+ void **tmp = new void*[0x8000];
+ preAlloc = true;
+
+ for(i = 0; i < NUM_PREALLOC_ATOMICS; i++)
+ tmp[i] = RpAtomicCreate();
+ for(i = 0; i < NUM_PREALLOC_ATOMICS; i++)
+ RpAtomicDestroy((RpAtomic*)tmp[i]);
+
+ for(i = 0; i < NUM_PREALLOC_CLUMPS; i++)
+ tmp[i] = RpClumpCreate();
+ for(i = 0; i < NUM_PREALLOC_CLUMPS; i++)
+ RpClumpDestroy((RpClump*)tmp[i]);
+
+ for(i = 0; i < NUM_PREALLOC_FRAMES; i++)
+ tmp[i] = RwFrameCreate();
+ for(i = 0; i < NUM_PREALLOC_FRAMES; i++)
+ RwFrameDestroy((RwFrame*)tmp[i]);
+
+ for(i = 0; i < NUM_PREALLOC_GEOMETRIES; i++)
+ tmp[i] = RpGeometryCreate(0, 0, 0);
+ for(i = 0; i < NUM_PREALLOC_GEOMETRIES; i++)
+ RpGeometryDestroy((RpGeometry*)tmp[i]);
+
+ for(i = 0; i < NUM_PREALLOC_TEXDICTS; i++)
+ tmp[i] = RwTexDictionaryCreate();
+ for(i = 0; i < NUM_PREALLOC_TEXDICTS; i++)
+ RwTexDictionaryDestroy((RwTexDictionary*)tmp[i]);
+
+ for(i = 0; i < NUM_PREALLOC_TEXTURES; i++)
+ tmp[i] = RwTextureCreate(RwRasterCreate(0, 0, 0, 0));
+ for(i = 0; i < NUM_PREALLOC_TEXDICTS; i++)
+ RwTextureDestroy((RwTexture*)tmp[i]);
+
+ for(i = 0; i < NUM_PREALLOC_MATERIALS; i++)
+ tmp[i] = RpMaterialCreate();
+ for(i = 0; i < NUM_PREALLOC_MATERIALS; i++)
+ RpMaterialDestroy((RpMaterial*)tmp[i]);
+
+ delete[] tmp;
+ preAlloc = false;
+ POP_MEMID();
+}
+#endif
+
static RwBool
Initialise3D(void *param)
{
+ PUSH_MEMID(MEMID_RENDER);
+
if (RsRwInitialize(param))
{
+ POP_MEMID();
+
#ifdef DEBUGMENU
DebugMenuInit();
DebugMenuPopulate();
#endif // !DEBUGMENU
- bool ret = CGame::InitialiseRenderWare();
-#ifdef EXTENDED_PIPELINES
- CustomPipes::CustomPipeInit(); // need Scene.world for this
-#endif
- return ret;
+ return CGame::InitialiseRenderWare();
}
+ POP_MEMID();
return (FALSE);
}
@@ -411,9 +491,6 @@ Initialise3D(void *param)
static void
Terminate3D(void)
{
-#ifdef EXTENDED_PIPELINES
- CustomPipes::CustomPipeShutdown();
-#endif
CGame::ShutdownRenderWare();
#ifdef DEBUGMENU
DebugMenuShutdown();
@@ -591,8 +668,10 @@ LoadingScreen(const char *str1, const char *str2, const char *splashscreen)
AsciiToUnicode(str1, tmpstr);
CFont::PrintString(hpos, top, tmpstr);
top += 22*yscale;
- AsciiToUnicode(str2, tmpstr);
- CFont::PrintString(hpos, top, tmpstr);
+ if (str2) {
+ AsciiToUnicode(str2, tmpstr);
+ CFont::PrintString(hpos, top, tmpstr);
+ }
#endif
}
@@ -747,6 +826,185 @@ tZonePrint ZonePrint[] =
};
#ifndef MASTER
+
+void
+PrintMemoryUsage(void)
+{
+// little hack
+if(CPools::GetPtrNodePool() == nil)
+return;
+
+ // Style taken from LCS, modified for III
+// CFont::SetFontStyle(FONT_PAGER);
+ CFont::SetFontStyle(FONT_BANK);
+ CFont::SetBackgroundOff();
+ CFont::SetWrapx(640.0f);
+// CFont::SetScale(0.5f, 0.75f);
+ CFont::SetScale(0.4f, 0.75f);
+ CFont::SetCentreOff();
+ CFont::SetCentreSize(640.0f);
+ CFont::SetJustifyOff();
+ CFont::SetPropOn();
+ CFont::SetColor(CRGBA(200, 200, 200, 200));
+ CFont::SetBackGroundOnlyTextOff();
+ CFont::SetDropShadowPosition(0);
+
+ float y;
+
+#ifdef USE_CUSTOM_ALLOCATOR
+ y = 24.0f;
+ sprintf(gString, "Total: %d blocks, %d bytes", gMainHeap.m_totalBlocksUsed, gMainHeap.m_totalMemUsed);
+ AsciiToUnicode(gString, gUString);
+ CFont::PrintString(24.0f, y, gUString);
+ y += 12.0f;
+
+ sprintf(gString, "Game: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_GAME), gMainHeap.GetMemoryUsed(MEMID_GAME));
+ AsciiToUnicode(gString, gUString);
+ CFont::PrintString(24.0f, y, gUString);
+ y += 12.0f;
+
+ sprintf(gString, "World: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_WORLD), gMainHeap.GetMemoryUsed(MEMID_WORLD));
+ AsciiToUnicode(gString, gUString);
+ CFont::PrintString(24.0f, y, gUString);
+ y += 12.0f;
+
+ sprintf(gString, "Render: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_RENDER), gMainHeap.GetMemoryUsed(MEMID_RENDER));
+ AsciiToUnicode(gString, gUString);
+ CFont::PrintString(24.0f, y, gUString);
+ y += 12.0f;
+
+ sprintf(gString, "PreAlloc: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_PRE_ALLOC), gMainHeap.GetMemoryUsed(MEMID_PRE_ALLOC));
+ AsciiToUnicode(gString, gUString);
+ CFont::PrintString(24.0f, y, gUString);
+ y += 12.0f;
+
+ sprintf(gString, "Default Models: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_DEF_MODELS), gMainHeap.GetMemoryUsed(MEMID_DEF_MODELS));
+ AsciiToUnicode(gString, gUString);
+ CFont::PrintString(24.0f, y, gUString);
+ y += 12.0f;
+
+ sprintf(gString, "Textures: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_TEXTURES), gMainHeap.GetMemoryUsed(MEMID_TEXTURES));
+ AsciiToUnicode(gString, gUString);
+ CFont::PrintString(24.0f, y, gUString);
+ y += 12.0f;
+
+ sprintf(gString, "Streaming: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_STREAM), gMainHeap.GetMemoryUsed(MEMID_STREAM));
+ AsciiToUnicode(gString, gUString);
+ CFont::PrintString(24.0f, y, gUString);
+ y += 12.0f;
+
+ sprintf(gString, "Streamed Models: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_STREAM_MODELS), gMainHeap.GetMemoryUsed(MEMID_STREAM_MODELS));
+ AsciiToUnicode(gString, gUString);
+ CFont::PrintString(24.0f, y, gUString);
+ y += 12.0f;
+
+ sprintf(gString, "Streamed LODs: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_STREAM_LODS), gMainHeap.GetMemoryUsed(MEMID_STREAM_LODS));
+ AsciiToUnicode(gString, gUString);
+ CFont::PrintString(24.0f, y, gUString);
+ y += 12.0f;
+
+ sprintf(gString, "Streamed Textures: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_STREAM_TEXUTRES), gMainHeap.GetMemoryUsed(MEMID_STREAM_TEXUTRES));
+ AsciiToUnicode(gString, gUString);
+ CFont::PrintString(24.0f, y, gUString);
+ y += 12.0f;
+
+ sprintf(gString, "Streamed Collision: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_STREAM_COLLISION), gMainHeap.GetMemoryUsed(MEMID_STREAM_COLLISION));
+ AsciiToUnicode(gString, gUString);
+ CFont::PrintString(24.0f, y, gUString);
+ y += 12.0f;
+
+ sprintf(gString, "Streamed Animation: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_STREAM_ANIMATION), gMainHeap.GetMemoryUsed(MEMID_STREAM_ANIMATION));
+ AsciiToUnicode(gString, gUString);
+ CFont::PrintString(24.0f, y, gUString);
+ y += 12.0f;
+
+ sprintf(gString, "Ped Attr: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_PED_ATTR), gMainHeap.GetMemoryUsed(MEMID_PED_ATTR));
+ AsciiToUnicode(gString, gUString);
+ CFont::PrintString(24.0f, y, gUString);
+ y += 12.0f;
+
+ sprintf(gString, "Animation: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_ANIMATION), gMainHeap.GetMemoryUsed(MEMID_ANIMATION));
+ AsciiToUnicode(gString, gUString);
+ CFont::PrintString(24.0f, y, gUString);
+ y += 12.0f;
+
+ sprintf(gString, "Pools: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_POOLS), gMainHeap.GetMemoryUsed(MEMID_POOLS));
+ AsciiToUnicode(gString, gUString);
+ CFont::PrintString(24.0f, y, gUString);
+ y += 12.0f;
+
+ sprintf(gString, "Collision: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_COLLISION), gMainHeap.GetMemoryUsed(MEMID_COLLISION));
+ AsciiToUnicode(gString, gUString);
+ CFont::PrintString(24.0f, y, gUString);
+ y += 12.0f;
+
+ sprintf(gString, "Game Process: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_GAME_PROCESS), gMainHeap.GetMemoryUsed(MEMID_GAME_PROCESS));
+ AsciiToUnicode(gString, gUString);
+ CFont::PrintString(24.0f, y, gUString);
+ y += 12.0f;
+
+ sprintf(gString, "Script: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_SCRIPT), gMainHeap.GetMemoryUsed(MEMID_SCRIPT));
+ AsciiToUnicode(gString, gUString);
+ CFont::PrintString(24.0f, y, gUString);
+ y += 12.0f;
+
+ sprintf(gString, "Cars: %d blocks, %d bytes", gMainHeap.GetBlocksUsed(MEMID_CARS), gMainHeap.GetMemoryUsed(MEMID_CARS));
+ AsciiToUnicode(gString, gUString);
+ CFont::PrintString(24.0f, y, gUString);
+ y += 12.0f;
+#endif
+
+ y = 132.0f;
+ AsciiToUnicode("Pools usage:", gUString);
+ CFont::PrintString(400.0f, y, gUString);
+ y += 12.0f;
+
+ sprintf(gString, "PtrNode: %d/%d", CPools::GetPtrNodePool()->GetNoOfUsedSpaces(), CPools::GetPtrNodePool()->GetSize());
+ AsciiToUnicode(gString, gUString);
+ CFont::PrintString(400.0f, y, gUString);
+ y += 12.0f;
+
+ sprintf(gString, "EntryInfoNode: %d/%d", CPools::GetEntryInfoNodePool()->GetNoOfUsedSpaces(), CPools::GetEntryInfoNodePool()->GetSize());
+ AsciiToUnicode(gString, gUString);
+ CFont::PrintString(400.0f, y, gUString);
+ y += 12.0f;
+
+ sprintf(gString, "Ped: %d/%d", CPools::GetPedPool()->GetNoOfUsedSpaces(), CPools::GetPedPool()->GetSize());
+ AsciiToUnicode(gString, gUString);
+ CFont::PrintString(400.0f, y, gUString);
+ y += 12.0f;
+
+ sprintf(gString, "Vehicle: %d/%d", CPools::GetVehiclePool()->GetNoOfUsedSpaces(), CPools::GetVehiclePool()->GetSize());
+ AsciiToUnicode(gString, gUString);
+ CFont::PrintString(400.0f, y, gUString);
+ y += 12.0f;
+
+ sprintf(gString, "Building: %d/%d", CPools::GetBuildingPool()->GetNoOfUsedSpaces(), CPools::GetBuildingPool()->GetSize());
+ AsciiToUnicode(gString, gUString);
+ CFont::PrintString(400.0f, y, gUString);
+ y += 12.0f;
+
+ sprintf(gString, "Treadable: %d/%d", CPools::GetTreadablePool()->GetNoOfUsedSpaces(), CPools::GetTreadablePool()->GetSize());
+ AsciiToUnicode(gString, gUString);
+ CFont::PrintString(400.0f, y, gUString);
+ y += 12.0f;
+
+ sprintf(gString, "Object: %d/%d", CPools::GetObjectPool()->GetNoOfUsedSpaces(), CPools::GetObjectPool()->GetSize());
+ AsciiToUnicode(gString, gUString);
+ CFont::PrintString(400.0f, y, gUString);
+ y += 12.0f;
+
+ sprintf(gString, "Dummy: %d/%d", CPools::GetDummyPool()->GetNoOfUsedSpaces(), CPools::GetDummyPool()->GetSize());
+ AsciiToUnicode(gString, gUString);
+ CFont::PrintString(400.0f, y, gUString);
+ y += 12.0f;
+
+ sprintf(gString, "AudioScriptObjects: %d/%d", CPools::GetAudioScriptObjectPool()->GetNoOfUsedSpaces(), CPools::GetAudioScriptObjectPool()->GetSize());
+ AsciiToUnicode(gString, gUString);
+ CFont::PrintString(400.0f, y, gUString);
+ y += 12.0f;
+}
+
void
DisplayGameDebugText()
{
@@ -759,8 +1017,10 @@ DisplayGameDebugText()
TWEAKBOOL(bDisplayPosn);
TWEAKBOOL(bDisplayCheatStr);
}
-#endif
+ if(gbPrintMemoryUsage)
+ PrintMemoryUsage();
+#endif
char str[200];
wchar ustr[200];
@@ -872,18 +1132,19 @@ void
MattRenderScene(void)
{
// this calls CMattRenderer::Render
- CWorld::AdvanceCurrentScanCode();
+ /// CWorld::AdvanceCurrentScanCode();
// CMattRenderer::ResetRenderStates
- CRenderer::ClearForFrame();
+ /// CRenderer::ClearForFrame(); // before ConstructRenderList
// CClock::CalcEnvMapTimeMultiplicator
+ RwRenderStateSet(rwRENDERSTATECULLMODE, (void*)rwCULLMODECULLNONE);
CWaterLevel::RenderWater(); // actually CMattRenderer::RenderWater
// CClock::ms_EnvMapTimeMultiplicator = 1.0f;
// cWorldStream::ClearDynamics
- CRenderer::ConstructRenderList();
+ /// CRenderer::ConstructRenderList(); // before PreRender
if(gbRenderWorld0)
CRenderer::RenderWorld(0); // roads
// CMattRenderer::ResetRenderStates
- CRenderer::PreRender();
+ /// CRenderer::PreRender(); // has to be called before BeginUpdate because of cutscene shadows
CCoronas::RenderReflections();
if(gbRenderWorld1)
CRenderer::RenderWorld(1); // opaque
@@ -897,6 +1158,7 @@ if(gbRenderBoats)
CRenderer::RenderBoats();
if(gbRenderFadingInUnderwaterEntities)
CRenderer::RenderFadingInUnderwaterEntities();
+ RwRenderStateSet(rwRENDERSTATECULLMODE, (void*)rwCULLMODECULLNONE);
if(gbRenderWater)
CRenderer::RenderTransparentWater();
@@ -920,8 +1182,7 @@ RenderScene_new(void)
}
// TODO
-bool FredIsInFirstPersonCam(void) { return true; } // this seems to give the best result in all cases
-
+bool FredIsInFirstPersonCam(void) { return false; }
void
RenderEffects_new(void)
{
@@ -941,10 +1202,11 @@ if(gbRenderWorld2)
if(gbRenderVehicles)
CRenderer::RenderVehicles();
}else{
-if(gbRenderVehicles)
- CRenderer::RenderVehicles();
+ // 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)
@@ -1090,9 +1352,11 @@ Render2dStuff(void)
MusicManager.DisplayRadioStationName();
TheConsole.Display();
+#ifdef GTA_SCENE_EDIT
if(CSceneEdit::m_bEditOn)
CSceneEdit::Draw();
else
+#endif
CHud::Draw();
CSpecialFX::Render2DFXs();
@@ -1116,13 +1380,7 @@ RenderMenus(void)
{
if (FrontEndMenuManager.m_bMenuActive)
{
-#ifdef PS2
- gMainHeap.PushMemId(_TODOCONST(17));
-#endif
FrontEndMenuManager.DrawFrontEnd();
-#ifdef PS2
- gMainHeap.PopMemId();
-#endif
}
}
@@ -1162,21 +1420,12 @@ Idle(void *arg)
tbEndTimer("DMAudio.Service");
if(CGame::bDemoMode && CTimer::GetTimeInMilliseconds() > (3*60 + 30)*1000 && !CCutsceneMgr::IsCutsceneProcessing()){
-#ifdef PS2_MENU
- TheMemoryCard.m_bWantToLoad = false;
- FrontEndMenuManager.m_bWantToRestart = true;
-#else
+ WANT_TO_LOAD = false;
FrontEndMenuManager.m_bWantToRestart = true;
- FrontEndMenuManager.m_bWantToLoad = false;
-#endif
return;
}
-#ifdef PS2_MENU
- if ( FrontEndMenuManager.m_bWantToRestart || TheMemoryCard.b_FoundRecentSavedGameWantToLoad )
-#else
- if(FrontEndMenuManager.m_bWantToRestart || b_FoundRecentSavedGameWantToLoad)
-#endif
+ if(FrontEndMenuManager.m_bWantToRestart || FOUND_GAME_TO_LOAD)
{
return;
}
@@ -1188,28 +1437,30 @@ Idle(void *arg)
if(!FrontEndMenuManager.m_bMenuActive && TheCamera.GetScreenFadeStatus() != FADE_2)
{
-#ifdef GTA_PC
- // This is from SA, but it's nice for windowed mode
- RwV2d pos;
- pos.x = SCREEN_WIDTH / 2.0f;
- pos.y = SCREEN_HEIGHT / 2.0f;
- RsMouseSetPos(&pos);
+ // This is from SA, but it's nice for windowed mode
+#if defined(GTA_PC) && !defined(RW_GL3)
+ RwV2d pos;
+ pos.x = SCREEN_WIDTH / 2.0f;
+ pos.y = SCREEN_HEIGHT / 2.0f;
+ RsMouseSetPos(&pos);
#endif
-#ifdef NEW_RENDERER
- if(!gbNewRenderer)
-#endif
-{
+
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");
-}
#ifdef FIX_BUGS
RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void *)FALSE); // TODO: temp? this fixes OpenGL render but there should be a better place for this
@@ -1220,12 +1471,12 @@ Idle(void *arg)
if(CWeather::LightningFlash && !CCullZones::CamNoRain()){
if(!DoRWStuffStartOfFrame_Horizon(255, 255, 255, 255, 255, 255, 255))
- return;
+ goto popret;
}else{
if(!DoRWStuffStartOfFrame_Horizon(CTimeCycle::GetSkyTopRed(), CTimeCycle::GetSkyTopGreen(), CTimeCycle::GetSkyTopBlue(),
CTimeCycle::GetSkyBottomRed(), CTimeCycle::GetSkyBottomGreen(), CTimeCycle::GetSkyBottomBlue(),
255))
- return;
+ goto popret;
}
DefinedState();
@@ -1246,10 +1497,17 @@ Idle(void *arg)
RenderDebugShit();
RenderEffects();
- tbStartTimer(0, "RenderMotionBlur");
if((TheCamera.m_BlurType == MOTION_BLUR_NONE || TheCamera.m_BlurType == MOTION_BLUR_LIGHT_SCENE) &&
TheCamera.m_ScreenReductionPercentage > 0.0f)
TheCamera.SetMotionBlurAlpha(150);
+
+#ifdef SCREEN_DROPLETS
+ CPostFX::GetBackBuffer(Scene.camera);
+ ScreenDroplets::Process();
+ ScreenDroplets::Render();
+#endif
+
+ tbStartTimer(0, "RenderMotionBlur");
TheCamera.RenderMotionBlur();
tbEndTimer("RenderMotionBlur");
@@ -1266,7 +1524,7 @@ Idle(void *arg)
CVisibilityPlugins::SetRenderWareCamera(Scene.camera);
RwCameraClear(Scene.camera, &gColourTop, CLEARMODE);
if(!RsCameraBeginUpdate(Scene.camera))
- return;
+ goto popret;
}
tbStartTimer(0, "RenderMenus");
@@ -1275,7 +1533,7 @@ Idle(void *arg)
#ifdef PS2_MENU
if ( TheMemoryCard.m_bWantToLoad )
- return;
+ goto popret;
#endif
tbStartTimer(0, "DoFade");
@@ -1286,15 +1544,22 @@ Idle(void *arg)
Render2dStuffAfterFade();
tbEndTimer("Render2dStuff-Fade");
// CCredits::Render(); // They added it to function above and also forgot it here
-
+#ifdef XBOX_MESSAGE_SCREEN
+ FrontEndMenuManager.DrawOverlays();
+#endif
if (gbShowTimebars)
tbDisplay();
DoRWStuffEndOfFrame();
+ POP_MEMID(); // MEMID_RENDER
+
if(g_SlowMode)
ProcessSlowMode();
+ return;
+
+popret: POP_MEMID(); // MEMID_RENDER
}
void
@@ -1319,6 +1584,9 @@ FrontendIdle(void)
DefinedState(); // seems redundant, but breaks resolution change.
RenderMenus();
+#ifdef XBOX_MESSAGE_SCREEN
+ FrontEndMenuManager.DrawOverlays();
+#endif
DoFade();
Render2dStuffAfterFade();
CFont::DrawFonts();
@@ -1404,15 +1672,6 @@ AppEventHandler(RsEvent event, void *param)
return rsEVENTPROCESSED;
}
-#ifndef MASTER
- case rsANIMVIEWER:
- {
- TheModelViewer();
-
- return rsEVENTPROCESSED;
- }
-#endif
-
default:
{
return rsEVENTNOTPROCESSED;
@@ -1428,48 +1687,49 @@ TheModelViewer(void)
//TODO
#else
- CDraw::CalculateAspectRatio();
+ // 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()*0.5f, CTimeCycle::GetSkyTopGreen()*0.5f, CTimeCycle::GetSkyTopBlue()*0.5f,
CTimeCycle::GetSkyBottomRed(), CTimeCycle::GetSkyBottomGreen(), CTimeCycle::GetSkyBottomBlue(),
255);
- CSprite2d::InitPerFrame();
- CFont::InitPerFrame();
+ CSprite2d::SetRecipNearClip(); // X
+ CSprite2d::InitPerFrame(); // X
+ CFont::InitPerFrame(); // X
DefinedState();
CVisibilityPlugins::InitAlphaEntityList();
CAnimViewer::Render();
- Render2dStuff();
+ Render2dStuff(); // X
DoRWStuffEndOfFrame();
+ CTimer::Update();
#endif
}
#endif
-#ifdef PS2
+
+#ifdef GTA_PS2
void TheGame(void)
{
printf("Into TheGame!!!\n");
-#ifdef GTA_PS2
- gMainHeap.PushMemId(_TODOCONST(1));
-#endif
+ PUSH_MEMID(MEMID_GAME); // NB: not popped
CTimer::Initialise();
-#ifdef GTA_PS2
- CGame::Initialise();
-#else
CGame::Initialise("DATA\\GTA3.DAT");
-#endif
Const char *splash = GetRandomSplashScreen(); // inlined here
LoadingScreen("Starting Game", NULL, splash);
#ifdef GTA_PS2
+ // TODO(MIAMI): not checked yet
if ( TheMemoryCard.CheckCardInserted(CARD_ONE) == CMemoryCard::NO_ERR_SUCCESS
&& TheMemoryCard.ChangeDirectory(CARD_ONE, TheMemoryCard.Cards[CARD_ONE].dir)
&& TheMemoryCard.FindMostRecentFileName(CARD_ONE, TheMemoryCard.MostRecentFile) == true
@@ -1493,77 +1753,53 @@ void TheGame(void)
while (true)
{
-#ifdef PS2
- if (TheMemoryCard.m_bWantToLoad)
-#else
- if (FrontEndMenuManager.m_bWantToLoad)
-#endif
+ if (FOUND_GAME_TO_LOAD)
{
Const char *splash1 = GetLevelSplashScreen(CGame::currLevel);
LoadSplash(splash1);
}
-#ifdef PS2
- TheMemoryCard.m_bWantToLoad = false;
-#else
- FrontEndMenuManager.m_bWantToLoad = false;
-#endif
+ WANT_TO_LOAD = false;
CTimer::Update();
-#ifdef PS2
- while (!(FrontEndMenuManager.m_bWantToRestart || TheMemoryCard.b_FoundRecentSavedGameWantToLoad))
-#else
- while (!(FrontEndMenuManager.m_bWantToRestart || b_FoundRecentSavedGameWantToLoad))
-#endif
+ while (!(FrontEndMenuManager.m_bWantToRestart || FOUND_GAME_TO_LOAD))
{
CSprite2d::InitPerFrame();
CFont::InitPerFrame();
-#ifdef GTA_PS2
- gMainHeap.PushMemId(_TODOCONST(12));
-#endif
- CPointLights::NumLights = 0;
+ PUSH_MEMID(MEMID_GAME_PROCESS)
+ CPointLights::InitPerFrame();
CGame::Process();
-#ifdef GTA_PS2
- gMainHeap.PopMemId();
-#endif
+ POP_MEMID();
DMAudio.Service();
if (CGame::bDemoMode && CTimer::GetTimeInMilliseconds() > (3*60 + 30)*1000 && !CCutsceneMgr::IsCutsceneProcessing())
{
-#ifdef PS2
- TheMemoryCard.m_bWantToLoad = false;
-#else
- FrontEndMenuManager.m_bWantToLoad = false;
-#endif
+ WANT_TO_LOAD = false;
FrontEndMenuManager.m_bWantToRestart = true;
break;
}
-#ifdef PS2
- if (FrontEndMenuManager.m_bWantToRestart || TheMemoryCard.b_FoundRecentSavedGameWantToLoad)
-#else
- if (FrontEndMenuManager.m_bWantToRestart || b_FoundRecentSavedGameWantToLoad)
-#endif
+ if (FrontEndMenuManager.m_bWantToRestart || FOUND_GAME_TO_LOAD)
break;
SetLightsWithTimeOfDayColour(Scene.world);
-#ifdef GTA_PS2
- gMainHeap.PushMemId(_TODOCONST(15));
-#endif
- // 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_RENDER);
+
+ CRenderer::ConstructRenderList();
+
+ if ((!FrontEndMenuManager.m_bMenuActive || FrontEndMenuManager.m_bRenderGameInMenu == true) && TheCamera.GetScreenFadeStatus() != FADE_2 )
{
-#ifdef GTA_PS2
- gMainHeap.PushMemId(_TODOCONST(11));
-#endif
- CRenderer::ConstructRenderList();
CRenderer::PreRender();
-#ifdef GTA_PS2
- gMainHeap.PopMemId();
+ // TODO(MIAMI): something ps2all specific
+
+#ifdef FIX_BUGS
+ // This has to be done BEFORE RwCameraBeginUpdate
+ RwCameraSetFarClipPlane(Scene.camera, CTimeCycle::GetFarClip());
+ RwCameraSetFogDistance(Scene.camera, CTimeCycle::GetFogStart());
#endif
if (CWeather::LightningFlash && !CCullZones::CamNoRain())
@@ -1572,8 +1808,10 @@ void TheGame(void)
DoRWStuffStartOfFrame_Horizon(CTimeCycle::GetSkyTopRed(), CTimeCycle::GetSkyTopGreen(), CTimeCycle::GetSkyTopBlue(), CTimeCycle::GetSkyBottomRed(), CTimeCycle::GetSkyBottomGreen(), CTimeCycle::GetSkyBottomBlue(), 255);
DefinedState();
+#ifndef FIX_BUGS
RwCameraSetFarClipPlane(Scene.camera, CTimeCycle::GetFarClip());
RwCameraSetFogDistance(Scene.camera, CTimeCycle::GetFogStart());
+#endif
RenderScene();
RenderDebugShit();
@@ -1590,21 +1828,14 @@ void TheGame(void)
CameraSize(Scene.camera, NULL, SCREEN_VIEWWINDOW, SCREEN_ASPECT_RATIO);
CVisibilityPlugins::SetRenderWareCamera(Scene.camera);
RwCameraClear(Scene.camera, &gColourTop, CLEARMODE);
- if (!RsCameraBeginUpdate(Scene.camera))
- break;
+ RsCameraBeginUpdate(Scene.camera);
}
RenderMenus();
-#ifdef PS2
- if (TheMemoryCard.m_bWantToLoad)
-#else
- if (FrontEndMenuManager.m_bWantToLoad)
-#endif
+ if (WANT_TO_LOAD)
{
-#ifdef GTA_PS2
- gMainHeap.PopMemId();
-#endif
+ POP_MEMID(); // MEMID_RENDER
break;
}
@@ -1621,9 +1852,7 @@ void TheGame(void)
CTimer::Update();
-#ifdef GTA_PS2
- gMainHeap.PopMemId();
-#endif
+ POP_MEMID(): // MEMID_RENDER
if (g_SlowMode)
ProcessSlowMode();
@@ -1635,24 +1864,12 @@ void TheGame(void)
CGame::ShutDownForRestart();
CTimer::Stop();
-#ifdef PS2
- if (FrontEndMenuManager.m_bWantToRestart || TheMemoryCard.b_FoundRecentSavedGameWantToLoad)
-#else
- if (FrontEndMenuManager.m_bWantToRestart || b_FoundRecentSavedGameWantToLoad)
-#endif
+ if (FrontEndMenuManager.m_bWantToRestart || FOUND_GAME_TO_LOAD)
{
-#ifdef PS2
- if (TheMemoryCard.b_FoundRecentSavedGameWantToLoad)
-#else
- if (b_FoundRecentSavedGameWantToLoad)
-#endif
+ if (FOUND_GAME_TO_LOAD)
{
FrontEndMenuManager.m_bWantToRestart = true;
-#ifdef PS2
- TheMemoryCard.m_bWantToLoad = true;
-#else
- FrontEndMenuManager.m_bWantToLoad = true;
-#endif
+ WANT_TO_LOAD = true;
}
CGame::InitialiseWhenRestarting();
@@ -1671,11 +1888,7 @@ void TheGame(void)
void SystemInit()
{
-#ifdef __MWERKS__
- mwInit();
-#endif
-
-#ifdef GTA_PS2
+#ifdef USE_CUSTOM_ALLOCATOR
InitMemoryMgr();
#endif
@@ -1684,7 +1897,7 @@ void SystemInit()
char path[256];
- sprintf(path, "cdrom0:\\%s%s;1", "SYSTEM\\", "IOPRP23.IMG");
+ sprintf(path, "cdrom0:\\%s%s;1", "SYSTEM\\", "IOPRP241.IMG");
sceSifInitRpc(0);
@@ -1698,14 +1911,10 @@ void SystemInit()
CFileMgr::InitCdSystem();
sceFsReset();
-#endif
- CFileMgr::Initialise();
-
-#ifdef GTA_PS2
CFileMgr::InitCd();
- Char modulepath[256];
+ char modulepath[256];
strcpy(modulepath, "cdrom0:\\");
strcat(modulepath, "SYSTEM\\");
@@ -1736,6 +1945,16 @@ void SystemInit()
strcat(modulepath, "SYSTEM\\");
strcat(modulepath, "MCSERV.IRX");
LoadModule(modulepath);
+
+ strcpy(modulepath, "cdrom0:\\");
+ strcat(modulepath, "SYSTEM\\");
+ strcat(modulepath, "CDSTREAM.IRX");
+ LoadModule(modulepath);
+
+ strcpy(modulepath, "cdrom0:\\");
+ strcat(modulepath, "SYSTEM\\");
+ strcat(modulepath, "SAMPMAN2.IRX");
+ LoadModule(modulepath);
#endif
@@ -1765,6 +1984,7 @@ void SystemInit()
FrontEndMenuManager.m_PrefsAllowNastyGame = true;
#ifdef GTA_PS2
+ // TODO(MIAMI): this code probably went elsewhere?
int32 lang = sceScfGetLanguage();
if ( lang == SCE_ITALIAN_LANGUAGE )
FrontEndMenuManager.m_PrefsLanguage = LANGUAGE_ITALIAN;
@@ -1792,59 +2012,160 @@ void SystemInit()
//
#endif
-#ifdef PS2
+#ifdef GTA_PS2
TheMemoryCard.Init();
#endif
}
-void GameInit()
+int VBlankCounter(int ca)
+{
+ frameCount++;
+ ExitHandler();
+ return 0;
+}
+
+// linked against by RW!
+extern "C" void WaitVBlank(void)
+{
+ int32 startFrame = frameCount;
+ while(startFrame == frameCount);
+}
+
+void GameInit(bool onlyRW)
{
- if ( !gameAlreadyInitialised )
+ if(onlyRW)
{
#ifdef GTA_PS2
- char path[256];
-
- strcpy(path, "cdrom0:\\");
- strcat(path, "SYSTEM\\");
- strcat(path, "CDSTREAM.IRX");
- LoadModule(path);
-
- strcpy(path, "cdrom0:\\");
- strcat(path, "SYSTEM\\");
- strcat(path, "SAMPMAN.IRX");
- LoadModule(path);
-
- strcpy(path, "cdrom0:\\");
- strcat(path, "SYSTEM\\");
- strcat(path, "MUSICSTR.IRX");
- LoadModule(path);
+ Initialise3D(nil);
+#else
+ Initialise3D(nil); //TODO: window parameter
#endif
- CdStreamInit(MAX_CDCHANNELS);
-
-#ifdef PS2
- Initialise3D(); //no params
+ gameAlreadyInitialised = true;
+ }
+ else
+ {
+ if ( !gameAlreadyInitialised )
+#ifdef GTA_PS2
+ Initialise3D(nil);
#else
- //TODO
+ Initialise3D(nil); //TODO: window parameter
#endif
-
+ }
+
#ifdef GTA_PS2
char *files[] =
{
"\\ANIM\\CUTS.IMG;1",
"\\ANIM\\CUTS.DIR;1",
"\\ANIM\\PED.IFP;1",
- "\\MODELS\\FRONTEND.TXD;1",
+ "\\MODELS\\FRONTEN1.TXD;1",
+ "\\MODELS\\FRONTEN2.TXD;1",
"\\MODELS\\FONTS.TXD;1",
"\\MODELS\\HUD.TXD;1",
"\\MODELS\\PARTICLE.TXD;1",
"\\MODELS\\MISC.TXD;1",
"\\MODELS\\GENERIC.TXD;1",
"\\MODELS\\GTA3.DIR;1",
+ // TODO: japanese?
+#ifdef GTA_PAL
"\\TEXT\\ENGLISH.GXT;1",
"\\TEXT\\FRENCH.GXT;1",
"\\TEXT\\GERMAN.GXT;1",
"\\TEXT\\ITALIAN.GXT;1",
"\\TEXT\\SPANISH.GXT;1",
+#else
+ "\\TEXT\\AMERICAN.GXT;1",
+#endif
+ "\\MODELS\\COLL\\GENERIC.COL;1",
+ "\\MODELS\\COLL\\VEHICLES.COL;1",
+ "\\MODELS\\COLL\\PEDS.COL;1",
+ "\\MODELS\\COLL\\WEAPONS.COL;1",
+ "\\MODELS\\GENERIC\\AIR_VLO.DFF;1",
+ "\\MODELS\\GENERIC\\WHEELS.DFF;1",
+ "\\MODELS\\GENERIC\\ARROW.DFF;1",
+ "\\MODELS\\GENERIC\\ZONECYLB.DFF;1",
+ "\\DATA\\HANDLING.CFG;1",
+ "\\DATA\\SURFACE.DAT;1",
+ "\\DATA\\PEDSTATS.DAT;1",
+ "\\DATA\\TIMECYC.DAT;1",
+ "\\DATA\\PARTICLE.CFG;1",
+ "\\DATA\\DEFAULT.DAT;1",
+ "\\DATA\\DEFAULT.IDE;1",
+ "\\DATA\\GTA_VC.DAT;1",
+ "\\DATA\\OBJECT.DAT;1",
+ "\\DATA\\MAP.ZON;1",
+ "\\DATA\\NAVIG.ZON;1",
+ "\\DATA\\INFO.ZON;1",
+ "\\DATA\\WATERPRO.DAT;1",
+ "\\DATA\\MAIN.SCM;1",
+ "\\DATA\\CARCOLS.DAT;1",
+ "\\DATA\\PED.DAT;1",
+ "\\DATA\\FISTFITE.DAT;1",
+ "\\DATA\\WEAPON.DAT;1",
+ "\\DATA\\PEDGRP.DAT;1",
+ "\\DATA\\PATHS\\FLIGHT.DAT;1",
+ "\\DATA\\PATHS\\FLIGHT2.DAT;1",
+ "\\DATA\\PATHS\\FLIGHT3.DAT;1",
+ "\\DATA\\PATHS\\SPATH0.DAT;1",
+ "\\DATA\\MAPS\\LITTLEHA\\LITTLEHA.IDE;1",
+ "\\DATA\\MAPS\\DOWNTOWN\\DOWNTOWN.IDE;1",
+ "\\DATA\\MAPS\\DOWNTOWS\\DOWNTOWS.IDE;1",
+ "\\DATA\\MAPS\\DOCKS\\DOCKS.IDE;1",
+ "\\DATA\\MAPS\\WASHINTN\\WASHINTN.IDE;1",
+ "\\DATA\\MAPS\\WASHINTS\\WASHINTS.IDE;1",
+ "\\DATA\\MAPS\\OCEANDRV\\OCEANDRV.IDE;1",
+ "\\DATA\\MAPS\\OCEANDN\\OCEANDN.IDE;1",
+ "\\DATA\\MAPS\\GOLF\\GOLF.IDE;1",
+ "\\DATA\\MAPS\\BRIDGE\\BRIDGE.IDE;1",
+ "\\DATA\\MAPS\\STARISL\\STARISL.IDE;1",
+ "\\DATA\\MAPS\\NBEACHBT\\NBEACHBT.IDE;1",
+ "\\DATA\\MAPS\\NBEACHW\\NBEACHW.IDE;1",
+ "\\DATA\\MAPS\\NBEACH\\NBEACH.IDE;1",
+ "\\DATA\\MAPS\\BANK\\BANK.IDE;1",
+ "\\DATA\\MAPS\\MALL\\MALL.IDE;1",
+ "\\DATA\\MAPS\\YACHT\\YACHT.IDE;1",
+ "\\DATA\\MAPS\\CISLAND\\CISLAND.IDE;1",
+ "\\DATA\\MAPS\\CLUB\\CLUB.IDE;1",
+ "\\DATA\\MAPS\\HOTEL\\HOTEL.IDE;1",
+ "\\DATA\\MAPS\\LAWYERS\\LAWYERS.IDE;1",
+ "\\DATA\\MAPS\\STRIPCLB\\STRIPCLB.IDE;1",
+ "\\DATA\\MAPS\\AIRPORT\\AIRPORT.IDE;1",
+ "\\DATA\\MAPS\\HAITI\\HAITI.IDE;1",
+ "\\DATA\\MAPS\\HAITIN\\HAITIN.IDE;1",
+ "\\DATA\\MAPS\\CONCERTH\\CONCERTH.IDE;1",
+ "\\DATA\\MAPS\\MANSION\\MANSION.IDE;1",
+ "\\DATA\\MAPS\\ISLANDSF\\ISLANDSF.IDE;1",
+ "\\DATA\\MAPS\\LITTLEHA\\LITTLEHA.IPL;1",
+ "\\DATA\\MAPS\\DOWNTOWN\\DOWNTOWN.IPL;1",
+ "\\DATA\\MAPS\\DOWNTOWS\\DOWNTOWS.IPL;1",
+ "\\DATA\\MAPS\\DOCKS\\DOCKS.IPL;1",
+ "\\DATA\\MAPS\\WASHINTN\\WASHINTN.IPL;1",
+ "\\DATA\\MAPS\\WASHINTS\\WASHINTS.IPL;1",
+ "\\DATA\\MAPS\\OCEANDRV\\OCEANDRV.IPL;1",
+ "\\DATA\\MAPS\\OCEANDN\\OCEANDN.IPL;1",
+ "\\DATA\\MAPS\\GOLF\\GOLF.IPL;1",
+ "\\DATA\\MAPS\\BRIDGE\\BRIDGE.IPL;1",
+ "\\DATA\\MAPS\\STARISL\\STARISL.IPL;1",
+ "\\DATA\\MAPS\\NBEACHBT\\NBEACHBT.IPL;1",
+ "\\DATA\\MAPS\\NBEACH\\NBEACH.IPL;1",
+ "\\DATA\\MAPS\\NBEACHW\\NBEACHW.IPL;1",
+ "\\DATA\\MAPS\\CISLAND\\CISLAND.IPL;1",
+ "\\DATA\\MAPS\\AIRPORT\\AIRPORT.IPL;1",
+ "\\DATA\\MAPS\\HAITI\\HAITI.IPL;1",
+ "\\DATA\\MAPS\\HAITIN\\HAITIN.IPL;1",
+ "\\DATA\\MAPS\\ISLANDSF\\ISLANDSF.IPL;1",
+ "\\DATA\\MAPS\\BANK\\BANK.IPL;1",
+ "\\DATA\\MAPS\\MALL\\MALL.IPL;1",
+ "\\DATA\\MAPS\\YACHT\\YACHT.IPL;1",
+ "\\DATA\\MAPS\\CLUB\\CLUB.IPL;1",
+ "\\DATA\\MAPS\\HOTEL\\HOTEL.IPL;1",
+ "\\DATA\\MAPS\\LAWYERS\\LAWYERS.IPL;1",
+ "\\DATA\\MAPS\\STRIPCLB\\STRIPCLB.IPL;1",
+ "\\DATA\\MAPS\\CONCERTH\\CONCERTH.IPL;1",
+ "\\DATA\\MAPS\\MANSION\\MANSION.IPL;1",
+ "\\DATA\\MAPS\\GENERIC.IDE;1",
+ "\\DATA\\OCCLU.IPL;1",
+ "\\DATA\\MAPS\\PATHS.IPL;1",
"\\TXD\\LOADSC0.TXD;1",
"\\TXD\\LOADSC1.TXD;1",
"\\TXD\\LOADSC2.TXD;1",
@@ -1859,93 +2180,17 @@ void GameInit()
"\\TXD\\LOADSC11.TXD;1",
"\\TXD\\LOADSC12.TXD;1",
"\\TXD\\LOADSC13.TXD;1",
- "\\TXD\\LOADSC14.TXD;1",
- "\\TXD\\LOADSC15.TXD;1",
- "\\TXD\\LOADSC16.TXD;1",
- "\\TXD\\LOADSC17.TXD;1",
- "\\TXD\\LOADSC18.TXD;1",
- "\\TXD\\LOADSC19.TXD;1",
- "\\TXD\\LOADSC20.TXD;1",
- "\\TXD\\LOADSC21.TXD;1",
- "\\TXD\\LOADSC22.TXD;1",
- "\\TXD\\LOADSC23.TXD;1",
- "\\TXD\\LOADSC24.TXD;1",
- "\\TXD\\LOADSC25.TXD;1",
- "\\TXD\\NEWS.TXD;1",
- "\\MODELS\\COLL\\GENERIC.COL;1",
- "\\MODELS\\COLL\\INDUST.COL;1",
- "\\MODELS\\COLL\\COMMER.COL;1",
- "\\MODELS\\COLL\\SUBURB.COL;1",
- "\\MODELS\\COLL\\WEAPONS.COL;1",
- "\\MODELS\\COLL\\VEHICLES.COL;1",
- "\\MODELS\\COLL\\PEDS.COL;1",
- "\\MODELS\\GENERIC\\AIR_VLO.DFF;1",
- "\\MODELS\\GENERIC\\WEAPONS.DFF;1",
- "\\MODELS\\GENERIC\\WHEELS.DFF;1",
- "\\MODELS\\GENERIC\\LOPLYGUY.DFF;1",
- "\\MODELS\\GENERIC\\ARROW.DFF;1",
- "\\MODELS\\GENERIC\\ZONECYLB.DFF;1",
- "\\DATA\\MAPS\\COMNTOP.IPL;1",
- "\\DATA\\MAPS\\COMNBTM.IPL;1",
- "\\DATA\\MAPS\\COMSE.IPL;1",
- "\\DATA\\MAPS\\COMSW.IPL;1",
- "\\DATA\\MAPS\\CULL.IPL;1",
- "\\DATA\\MAPS\\INDUSTNE.IPL;1",
- "\\DATA\\MAPS\\INDUSTNW.IPL;1",
- "\\DATA\\MAPS\\INDUSTSE.IPL;1",
- "\\DATA\\MAPS\\INDUSTSW.IPL;1",
- "\\DATA\\MAPS\\SUBURBNE.IPL;1",
- "\\DATA\\MAPS\\SUBURBSW.IPL;1",
- "\\DATA\\MAPS\\OVERVIEW.IPL;1",
- "\\DATA\\MAPS\\PROPS.IPL;1",
- "\\DATA\\MAPS\\GTA3.IDE;1",
- "\\DATA\\PATHS\\FLIGHT.DAT;1",
- "\\DATA\\PATHS\\FLIGHT2.DAT;1",
- "\\DATA\\PATHS\\FLIGHT3.DAT;1",
- "\\DATA\\PATHS\\FLIGHT4.DAT;1",
- "\\DATA\\PATHS\\TRACKS.DAT;1",
- "\\DATA\\PATHS\\TRACKS2.DAT;1",
- "\\DATA\\PATHS\\CHASE0.DAT;1",
- "\\DATA\\PATHS\\CHASE1.DAT;1",
- "\\DATA\\PATHS\\CHASE2.DAT;1",
- "\\DATA\\PATHS\\CHASE3.DAT;1",
- "\\DATA\\PATHS\\CHASE4.DAT;1",
- "\\DATA\\PATHS\\CHASE5.DAT;1",
- "\\DATA\\PATHS\\CHASE6.DAT;1",
- "\\DATA\\PATHS\\CHASE7.DAT;1",
- "\\DATA\\PATHS\\CHASE10.DAT;1",
- "\\DATA\\PATHS\\CHASE11.DAT;1",
- "\\DATA\\PATHS\\CHASE14.DAT;1",
- "\\DATA\\PATHS\\CHASE16.DAT;1",
- "\\DATA\\PATHS\\CHASE18.DAT;1",
- "\\DATA\\PATHS\\CHASE19.DAT;1"
+ "\\TXD\\SPLASH1.TXD;1"
};
for ( int32 i = 0; i < ARRAY_SIZE(files); i++ )
SkyRegisterFileOnCd([i]);
#endif
- CreateDebugFont();
-
#ifdef GTA_PS2
- AddIntcHandler(_TODOCONST(2), VBlankCounter, 0);
+ AddIntcHandler(INTC_VBLANK_S, VBlankCounter, 0);
#endif
- CameraSize(Scene.camera, NULL, DEFAULT_VIEWWINDOW, DEFAULT_ASPECT_RATIO);
-
- CSprite2d::SetRecipNearClip();
- CTxdStore::Initialise();
-#ifdef GTA_PS2
- gMainHeap.PushMemId(_TODOCONST(9));
-#endif
- CFont::Initialise();
- CHud::Initialise();
-#ifdef GTA_PS2
- gMainHeap.PopMemId();
-#endif
-
- ValidateVersion();
-
#ifdef GTA_PS2
sceCdCLOCK rtc;
sceCdReadClock(&rtc);
@@ -1957,8 +2202,57 @@ void GameInit()
//TODO: mysrand();
#endif
- gameAlreadyInitialised = true;
+ // gameAlreadyInitialised = true; // why is this gone?
+ }
+}
+
+int32 SkipAllMPEGs;
+int32 gMemoryStickLoadOK;
+
+void PlayIntroMPEGs()
+{
+#ifdef GTA_PS2
+ if (gameAlreadyInitialised)
+ RpSkySuspend();
+
+ InitMPEGPlayer();
+
+ float skipTime; // wrong type, should be int
+#ifdef GTA_PAL
+ if(gMemoryStickLoadOK)
+ skipTime = 2500000;
+ else
+ skipTime = 5300000;
+
+ if(!SkipAllMPEGs)
+ PlayMPEG("cdrom0:\\MOVIES\\VCPAL.PSS;1", false, unk);
+
+ if(!SkipAllMPEGs){
+ SkipAllMPEGs = true;
+ PlayMPEG("cdrom0:\\MOVIES\\VICEPAL.PSS;1", true, 0);
+ }
+#else
+ if(gMemoryStickLoadOK)
+ skipTime = 2750000;
+ else
+ skipTime = 5500000;
+
+ if(!SkipAllMPEGs)
+ PlayMPEG("cdrom0:\\MOVIES\\VCNTSC.PSS;1", false, unk);
+
+ if(!SkipAllMPEGs){
+ SkipAllMPEGs = true;
+ PlayMPEG("cdrom0:\\MOVIES\\VICE.PSS;1", true, 0);
}
+#endif
+
+ ShutdownMPEGPlayer();
+
+ if ( gameAlreadyInitialised )
+ RpSkyResume();
+#else
+ //TODO
+#endif
}
int
@@ -1969,14 +2263,16 @@ main(int argc, char *argv[])
#endif
SystemInit();
-
-#ifdef PS2
+
+ if(RsEventHandler(rsINITIALIZE, nil) == rsEVENTERROR)
+ return 0;
+
+#ifdef GTA_PS2
int32 r = TheMemoryCard.CheckCardStateAtGameStartUp(CARD_ONE);
- if ( r == CMemoryCard::ERR_DIRNOENTRY || r == CMemoryCard::ERR_NOFORMAT
- && r != CMemoryCard::ERR_OPENNOENTRY && r != CMemoryCard::ERR_NONE )
+ if ( r == CMemoryCard::ERR_DIRNOENTRY || r == CMemoryCard::ERR_NOFORMAT )
{
- GameInit();
+ GameInit(true);
TheText.Unload();
TheText.Load();
@@ -1984,43 +2280,24 @@ main(int argc, char *argv[])
CFont::Initialise();
FrontEndMenuManager.DrawMemoryCardStartUpMenus();
- }
+ }else if(r == CMemoryCard::ERR_OPENNOENTRY)
+ gMemoryStickLoadOK = false;
+ else if(r == CMemoryCard::ERR_NONE)
+ gMemoryStickLoadOK = true;
#endif
-
-#ifdef GTA_PS2
- {
- if (gameAlreadyInitialised)
- RpSkySuspend();
-
- InitMPEGPlayer();
-
- PlayMPEG("cdrom0:\\MOVIES\\DMAPAL.PSS;1", false);
- if (CGame::frenchGame || CGame::germanGame)
- PlayMPEG("cdrom0:\\MOVIES\\INTROPAF.PSS;1", true);
- else
- PlayMPEG("cdrom0:\\MOVIES\\INTROPAL.PSS;1", true);
+ PlayIntroMPEGs();
- ShutdownMPEGPlayer();
+ GameInit(false);
- if ( gameAlreadyInitialised )
- RpSkyResume();
- }
-#else
- //TODO
-#endif
+ frameCount = 0;
+ while(frameCount < 100);
- GameInit();
+ CGame::InitialiseOnceAfterRW();
- if ( CGame::frenchGame || CGame::germanGame )
- LoadingScreen(NULL, version_name, "loadsc24");
- else
- LoadingScreen(NULL, version_name, "loadsc0");
-
- DMAudio.Initialise();
-
TheGame();
-
+
+#if 0 // maybe ifndef FINAL or MASTER?
CGame::ShutDown();
RwEngineStop();
@@ -2030,7 +2307,7 @@ main(int argc, char *argv[])
#ifdef __MWERKS__
mwExit(); // metrowerks shutdown
#endif
-
+#endif
return 0;
}
#endif
diff --git a/src/core/main.h b/src/core/main.h
index f428224e..37a82fb2 100644
--- a/src/core/main.h
+++ b/src/core/main.h
@@ -20,11 +20,16 @@ extern bool gbShowTimebars;
#define gbShowTimebars false
#endif
+#ifndef FINAL
+extern bool gbPrintMemoryUsage;
+#endif
+
class CSprite2d;
bool DoRWStuffStartOfFrame(int16 TopRed, int16 TopGreen, int16 TopBlue, int16 BottomRed, int16 BottomGreen, int16 BottomBlue, int16 Alpha);
bool DoRWStuffStartOfFrame_Horizon(int16 TopRed, int16 TopGreen, int16 TopBlue, int16 BottomRed, int16 BottomGreen, int16 BottomBlue, int16 Alpha);
void DoRWStuffEndOfFrame(void);
+void PreAllocateRwObjects(void);
void InitialiseGame(void);
void LoadingScreen(const char *str1, const char *str2, const char *splashscreen);
void LoadingIslandScreen(const char *levelName);
@@ -39,6 +44,11 @@ void ResetLoadingScreenBar(void);
void TheModelViewer(void);
#endif
+#ifdef LOAD_INI_SETTINGS
+void LoadINISettings();
+void SaveINISettings();
+#endif
+
#ifdef NEW_RENDERER
extern bool gbNewRenderer;
bool FredIsInFirstPersonCam(void);
diff --git a/src/core/re3.cpp b/src/core/re3.cpp
index ebfa8de5..5e3d8922 100644
--- a/src/core/re3.cpp
+++ b/src/core/re3.cpp
@@ -13,13 +13,10 @@
#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 "Ped.h"
-#include "Particle.h"
#include "Console.h"
#include "Debug.h"
#include "Hud.h"
@@ -29,13 +26,18 @@
#include "Radar.h"
#include "debugmenu.h"
#include "Frontend.h"
-#include "Text.h"
#include "WaterLevel.h"
#include "main.h"
#include "Script.h"
#include "MBlur.h"
#include "postfx.h"
#include "custompipes.h"
+#include "MemoryHeap.h"
+#include "FileMgr.h"
+
+#ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS
+#include "ControllerConfig.h"
+#endif
#ifndef _WIN32
#include "assert.h"
@@ -75,6 +77,195 @@ mysrand(unsigned int seed)
myrand_seed = seed;
}
+#ifdef CUSTOM_FRONTEND_OPTIONS
+#include "frontendoption.h"
+
+void
+CustomFrontendOptionsPopulate(void)
+{
+ // Moved to an array in MenuScreensCustom.cpp, but APIs are still available. see frontendoption.h
+
+ // These work only if we have neo folder, so they're dynamically added
+#ifdef EXTENDED_PIPELINES
+ const char *vehPipelineNames[] = { "FED_MFX", "FED_NEO" };
+ const char *off_on[] = { "FEM_OFF", "FEM_ON" };
+ int fd = CFileMgr::OpenFile("neo/neo.txd","r");
+ if (fd) {
+#ifdef GRAPHICS_MENU_OPTIONS
+ FrontendOptionSetCursor(MENUPAGE_GRAPHICS_SETTINGS, -3, false);
+ FrontendOptionAddSelect("FED_VPL", 0, 0, MENUALIGN_LEFT, vehPipelineNames, ARRAY_SIZE(vehPipelineNames), (int8*)&CustomPipes::VehiclePipeSwitch, false, nil, "VehiclePipeline");
+ FrontendOptionAddSelect("FED_PRM", 0, 0, MENUALIGN_LEFT, off_on, 2, (int8*)&CustomPipes::RimlightEnable, false, nil, "NeoRimLight");
+ FrontendOptionAddSelect("FED_WLM", 0, 0, MENUALIGN_LEFT, off_on, 2, (int8*)&CustomPipes::LightmapEnable, false, nil, "NeoLightMaps");
+ FrontendOptionAddSelect("FED_RGL", 0, 0, MENUALIGN_LEFT, off_on, 2, (int8*)&CustomPipes::GlossEnable, false, nil, "NeoRoadGloss");
+#else
+ FrontendOptionSetCursor(MENUPAGE_DISPLAY_SETTINGS, -3, false);
+ FrontendOptionAddSelect("FED_VPL", 0, 0, MENUALIGN_LEFT, vehPipelineNames, ARRAY_SIZE(vehPipelineNames), (int8*)&CustomPipes::VehiclePipeSwitch, false, nil, "VehiclePipeline");
+ FrontendOptionAddSelect("FED_PRM", 0, 0, MENUALIGN_LEFT, off_on, 2, (int8*)&CustomPipes::RimlightEnable, false, nil, "NeoRimLight");
+ FrontendOptionAddSelect("FED_WLM", 0, 0, MENUALIGN_LEFT, off_on, 2, (int8*)&CustomPipes::LightmapEnable, false, nil, "NeoLightMaps");
+ FrontendOptionAddSelect("FED_RGL", 0, 0, MENUALIGN_LEFT, off_on, 2, (int8*)&CustomPipes::GlossEnable, false, nil, "NeoRoadGloss");
+#endif
+ CFileMgr::CloseFile(fd);
+ }
+#endif
+
+}
+#endif
+
+#ifdef LOAD_INI_SETTINGS
+#include "ini_parser.hpp"
+
+linb::ini cfg;
+int CheckAndReadIniInt(const char *cat, const char *key, int original)
+{
+ std::string strval = cfg.get(cat, key, "");
+ const char *value = strval.c_str();
+ if (value && value[0] != '\0')
+ return atoi(value);
+
+ return original;
+}
+
+float CheckAndReadIniFloat(const char *cat, const char *key, float original)
+{
+ std::string strval = cfg.get(cat, key, "");
+ const char *value = strval.c_str();
+ if (value && value[0] != '\0')
+ return atof(value);
+
+ return original;
+}
+
+void CheckAndSaveIniInt(const char *cat, const char *key, int val, bool &changed)
+{
+ char temp[10];
+ if (atoi(cfg.get(cat, key, "xxx").c_str()) != val) { // if .ini doesn't have our key, compare with xxx and forcefully add it
+ changed = true;
+ sprintf(temp, "%u", val);
+ cfg.set(cat, key, temp);
+ }
+}
+
+void CheckAndSaveIniFloat(const char *cat, const char *key, float val, bool &changed)
+{
+ char temp[10];
+ if (atof(cfg.get(cat, key, "xxx").c_str()) != val) { // if .ini doesn't have our key, compare with xxx and forcefully add it
+ changed = true;
+ sprintf(temp, "%f", val);
+ cfg.set(cat, key, temp);
+ }
+}
+
+void LoadINISettings()
+{
+ cfg.load_file("reVC.ini");
+
+#ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS
+ // Written by assuming the codes below will run after _InputInitialiseJoys().
+ strcpy(gSelectedJoystickName, cfg.get("DetectJoystick", "JoystickName", "").c_str());
+
+ if(gSelectedJoystickName[0] != '\0') {
+ for (int i = 0; i <= GLFW_JOYSTICK_LAST; i++) {
+ if (glfwJoystickPresent(i) && strncmp(gSelectedJoystickName, glfwGetJoystickName(i), strlen(gSelectedJoystickName)) == 0) {
+ if (PSGLOBAL(joy1id) != -1) {
+ PSGLOBAL(joy2id) = PSGLOBAL(joy1id);
+ }
+ PSGLOBAL(joy1id) = i;
+ int count;
+ glfwGetJoystickButtons(PSGLOBAL(joy1id), &count);
+
+ // We need to init and reload bindings, because;
+ // 1-joypad button number may differ with saved/prvly connected one
+ // 2-bindings are not init'ed if there is no joypad at the start
+ ControlsManager.InitDefaultControlConfigJoyPad(count);
+ CFileMgr::SetDirMyDocuments();
+ int32 gta3set = CFileMgr::OpenFile("gta3.set", "r");
+ if (gta3set) {
+ ControlsManager.LoadSettings(gta3set);
+ CFileMgr::CloseFile(gta3set);
+ }
+ CFileMgr::SetDir("");
+ break;
+ }
+ }
+ }
+#endif
+
+#ifdef CUSTOM_FRONTEND_OPTIONS
+ for (int i = 0; i < MENUPAGES; i++) {
+ for (int j = 0; j < NUM_MENUROWS; j++) {
+ CMenuScreenCustom::CMenuEntry &option = aScreens[i].m_aEntries[j];
+ if (option.m_Action == MENUACTION_NOTHING)
+ break;
+
+ // CFO check
+ if (option.m_Action < MENUACTION_NOTHING && option.m_CFO->save) {
+ // CFO only supports saving uint8 right now
+ *option.m_CFO->value = CheckAndReadIniInt("FrontendOptions", option.m_CFO->save, *option.m_CFO->value);
+ if (option.m_Action == MENUACTION_CFO_SELECT) {
+ option.m_CFOSelect->lastSavedValue = option.m_CFOSelect->displayedValue = *option.m_CFO->value;
+ }
+ }
+ }
+ }
+#endif
+
+#ifdef EXTENDED_COLOURFILTER
+ CPostFX::Intensity = CheckAndReadIniFloat("CustomPipesValues", "PostFXIntensity", CPostFX::Intensity);
+#endif
+#ifdef EXTENDED_PIPELINES
+ CustomPipes::VehicleShininess = CheckAndReadIniFloat("CustomPipesValues", "NeoVehicleShininess", CustomPipes::VehicleShininess);
+ CustomPipes::VehicleSpecularity = CheckAndReadIniFloat("CustomPipesValues", "NeoVehicleSpecularity", CustomPipes::VehicleSpecularity);
+ CustomPipes::RimlightMult = CheckAndReadIniFloat("CustomPipesValues", "RimlightMult", CustomPipes::RimlightMult);
+ CustomPipes::LightmapMult = CheckAndReadIniFloat("CustomPipesValues", "LightmapMult", CustomPipes::LightmapMult);
+ CustomPipes::GlossMult = CheckAndReadIniFloat("CustomPipesValues", "GlossMult", CustomPipes::GlossMult);
+#endif
+ gBackfaceCulling = CheckAndReadIniInt("Rendering", "BackfaceCulling", gBackfaceCulling);
+}
+
+void SaveINISettings()
+{
+ bool changed = false;
+ char temp[4];
+
+#ifdef DONT_TRUST_RECOGNIZED_JOYSTICKS
+ if (strncmp(cfg.get("DetectJoystick", "JoystickName", "").c_str(), gSelectedJoystickName, strlen(gSelectedJoystickName)) != 0) {
+ changed = true;
+ cfg.set("DetectJoystick", "JoystickName", gSelectedJoystickName);
+ }
+#endif
+#ifdef CUSTOM_FRONTEND_OPTIONS
+ for (int i = 0; i < MENUPAGES; i++) {
+ for (int j = 0; j < NUM_MENUROWS; j++) {
+ CMenuScreenCustom::CMenuEntry &option = aScreens[i].m_aEntries[j];
+ if (option.m_Action == MENUACTION_NOTHING)
+ break;
+
+ if (option.m_Action < MENUACTION_NOTHING && option.m_CFO->save) {
+ // Beware: CFO only supports saving uint8 right now
+ CheckAndSaveIniInt("FrontendOptions", option.m_CFO->save, *option.m_CFO->value, changed);
+ }
+ }
+ }
+#endif
+
+#ifdef EXTENDED_COLOURFILTER
+ CheckAndSaveIniFloat("CustomPipesValues", "PostFXIntensity", CPostFX::Intensity, changed);
+#endif
+#ifdef EXTENDED_PIPELINES
+ CheckAndSaveIniFloat("CustomPipesValues", "NeoVehicleShininess", CustomPipes::VehicleShininess, changed);
+ CheckAndSaveIniFloat("CustomPipesValues", "NeoVehicleSpecularity", CustomPipes::VehicleSpecularity, changed);
+ CheckAndSaveIniFloat("CustomPipesValues", "RimlightMult", CustomPipes::RimlightMult, changed);
+ CheckAndSaveIniFloat("CustomPipesValues", "LightmapMult", CustomPipes::LightmapMult, changed);
+ CheckAndSaveIniFloat("CustomPipesValues", "GlossMult", CustomPipes::GlossMult, changed);
+#endif
+ CheckAndSaveIniInt("Rendering", "BackfaceCulling", gBackfaceCulling, changed);
+
+ if (changed)
+ cfg.write_file("reVC.ini");
+}
+
+#endif
+
#ifdef DEBUGMENU
void WeaponCheat1();
void WeaponCheat2();
@@ -256,7 +447,7 @@ void CTweakVars::Add(CTweakVar *var)
TweakVarsListSize = 0;
}
if(TweakVarsListSize > 63)
- TweakVarsList = (CTweakVar**) realloc(TweakVarsList, (TweakVarsListSize + 1) * sizeof(var));
+ TweakVarsList = (CTweakVar**) realloc(TweakVarsList, (TweakVarsListSize + 1) * sizeof(*var));
TweakVarsList[TweakVarsListSize++] = var;
// TweakVarsList.push_back(var);
@@ -484,8 +675,17 @@ extern bool gbRenderWorld2;
DebugMenuAddVarBool8("Render", "Don't render Objects", &gbDontRenderObjects, nil);
DebugMenuAddVarBool8("Render", "Don't Render Water", &gbDontRenderWater, nil);
+#ifndef FINAL
+ DebugMenuAddVarBool8("Debug", "Print Memory Usage", &gbPrintMemoryUsage, nil);
+#ifdef USE_CUSTOM_ALLOCATOR
+ DebugMenuAddCmd("Debug", "Parse Heap", ParseHeap);
+#endif
+#endif
+
DebugMenuAddVarBool8("Debug", "pad 1 -> pad 2", &CPad::m_bMapPadOneToPadTwo, nil);
+#ifdef GTA_SCENE_EDIT
DebugMenuAddVarBool8("Debug", "Edit on", &CSceneEdit::m_bEditOn, nil);
+#endif
#ifdef MAP_ENHANCEMENTS
DebugMenuAddCmd("Debug", "Teleport to map waypoint", TeleportToWaypoint);
#endif
diff --git a/src/core/templates.h b/src/core/templates.h
index 9f5bd5ea..19881219 100644
--- a/src/core/templates.h
+++ b/src/core/templates.h
@@ -1,31 +1,31 @@
#pragma once
-template<typename T, int n>
+template<typename T, int32 n>
class CStore
{
public:
- int allocPtr;
+ int32 allocPtr;
T store[n];
- T *alloc(void){
- if(this->allocPtr >= n){
+ T *Alloc(void){
+ if(allocPtr >= n){
printf("Size of this thing:%d needs increasing\n", n);
assert(0);
}
- return &this->store[this->allocPtr++];
+ return &store[allocPtr++];
}
- void clear(void){
- this->allocPtr = 0;
+ void Clear(void){
+ allocPtr = 0;
}
- int getIndex(T *item){
- assert(item >= &this->store[0]);
- assert(item < &this->store[n]);
- return item - this->store;
+ int32 GetIndex(T *item){
+ assert(item >= &store[0]);
+ assert(item < &store[n]);
+ return item - store;
}
- T *getItem(int index){
+ T *GetItem(int32 index){
assert(index >= 0);
assert(index < n);
- return &this->store[index];
+ return &store[index];
}
};
@@ -40,15 +40,13 @@ class CPool
};
uint8 u;
} *m_flags;
- int m_size;
- int m_allocPtr;
+ int32 m_size;
+ int32 m_allocPtr;
public:
- // TODO(MIAMI): remove ctor without name argument
- CPool(int size, const char *name){
- // TODO: use new here
- m_entries = (U*)malloc(sizeof(U)*size);
- m_flags = (Flags*)malloc(sizeof(Flags)*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 = -1;
for(int i = 0; i < size; i++){
@@ -61,15 +59,15 @@ public:
}
void Flush() {
if (m_size > 0) {
- free(m_entries);
- free(m_flags);
+ delete[] (uint8*)m_entries;
+ delete[] (uint8*)m_flags;
m_entries = nil;
m_flags = nil;
m_size = 0;
m_allocPtr = 0;
}
}
- int GetSize(void) const { return m_size; }
+ int32 GetSize(void) const { return m_size; }
T *New(void){
bool wrapped = false;
do
@@ -93,12 +91,12 @@ public:
m_flags[m_allocPtr].id++;
return (T*)&m_entries[m_allocPtr];
}
- T *New(int handle){
+ T *New(int32 handle){
T *entry = (T*)&m_entries[handle>>8];
SetNotFreeAt(handle);
return entry;
}
- void SetNotFreeAt(int handle){
+ void SetNotFreeAt(int32 handle){
int idx = handle>>8;
m_flags[idx].free = 0;
m_flags[idx].id = handle & 0x7F;
@@ -123,15 +121,22 @@ public:
return m_flags[handle>>8].u == (handle & 0xFF) ?
(T*)&m_entries[handle >> 8] : nil;
}
- int GetIndex(T *entry){
- int i = GetJustIndex(entry);
- return m_flags[i].u + (i<<8);
+ int32 GetIndex(T* entry) {
+ int i = GetJustIndex_NoFreeAssert(entry);
+ return m_flags[i].u + (i << 8);
+ }
+ 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;
}
- int GetJustIndex(T *entry){
- // TODO: the cast is unsafe
- return (int)((U*)entry - m_entries);
+ int32 GetJustIndex_NoFreeAssert(T* entry) {
+ int index = ((U*)entry - m_entries);
+ // Please don't add unsafe assert here, because at least one func. use this to check if entity is ped or vehicle.
+ return index;
}
- int GetNoOfUsedSpaces(void) const {
+ int32 GetNoOfUsedSpaces(void) const {
int i;
int n = 0;
for(i = 0; i < m_size; i++)
@@ -141,8 +146,8 @@ public:
}
bool IsFreeSlot(int i) { return !!m_flags[i].free; }
void ClearStorage(uint8 *&flags, U *&entries){
- free(flags);
- free(entries);
+ delete[] (uint8*)flags;
+ delete[] (uint8*)entries;
flags = nil;
entries = nil;
}
@@ -156,8 +161,8 @@ public:
debug("CopyBack:%d (/%d)\n", GetNoOfUsedSpaces(), m_size); /* Assumed inlining */
}
void Store(uint8 *&flags, U *&entries){
- flags = (uint8*)malloc(sizeof(uint8)*m_size);
- entries = (U*)malloc(sizeof(U)*m_size);
+ flags = (uint8*)new uint8[sizeof(uint8)*m_size];
+ entries = (U*)new uint8[sizeof(U)*m_size];
memcpy(flags, m_flags, sizeof(uint8)*m_size);
memcpy(entries, m_entries, sizeof(U)*m_size);
debug("Stored:%d (/%d)\n", GetNoOfUsedSpaces(), m_size); /* Assumed inlining */
@@ -236,7 +241,7 @@ public:
link->Remove(); // remove from list
freeHead.Insert(link); // insert into free list
}
- int Count(void){
+ int32 Count(void){
int n = 0;
CLink<T> *lnk;
for(lnk = head.next; lnk != &tail; lnk = lnk->next)
diff --git a/src/entities/Dummy.cpp b/src/entities/Dummy.cpp
index 544e24a6..580245a8 100644
--- a/src/entities/Dummy.cpp
+++ b/src/entities/Dummy.cpp
@@ -58,7 +58,7 @@ IsDummyPointerValid(CDummy* pDummy)
{
if (!pDummy)
return false;
- int index = CPools::GetDummyPool()->GetJustIndex(pDummy);
+ int index = CPools::GetDummyPool()->GetJustIndex_NoFreeAssert(pDummy);
#ifdef FIX_BUGS
if (index < 0 || index >= CPools::GetDummyPool()->GetSize())
#else
diff --git a/src/entities/Entity.cpp b/src/entities/Entity.cpp
index 2285c93f..9b6be5f6 100644
--- a/src/entities/Entity.cpp
+++ b/src/entities/Entity.cpp
@@ -4,34 +4,27 @@
#include "RwHelper.h"
#include "ModelIndices.h"
#include "Timer.h"
-#include "Placeable.h"
#include "Entity.h"
#include "Object.h"
-#include "ParticleObject.h"
-#include "Lights.h"
#include "World.h"
#include "Camera.h"
#include "Glass.h"
-#include "Clock.h"
#include "Weather.h"
#include "Timecycle.h"
-#include "Bridge.h"
#include "TrafficLights.h"
#include "Coronas.h"
#include "PointLights.h"
#include "Shadows.h"
#include "Pickups.h"
#include "SpecialFX.h"
-#include "References.h"
#include "TxdStore.h"
#include "Zones.h"
+#include "MemoryHeap.h"
#include "Bones.h"
#include "Debug.h"
-#include "Renderer.h"
#include "Ped.h"
#include "Dummy.h"
#include "WindModifiers.h"
-#include "Occlusion.h"
//--MIAMI: file done
@@ -101,186 +94,6 @@ CEntity::~CEntity(void)
}
void
-CEntity::GetBoundCentre(CVector &out)
-{
- out = m_matrix * CModelInfo::GetModelInfo(m_modelIndex)->GetColModel()->boundingSphere.center;
-};
-
-bool
-CEntity::GetIsTouching(CVector const &center, float radius)
-{
- return sq(GetBoundRadius()+radius) > (GetBoundCentre()-center).MagnitudeSqr();
-}
-
-bool
-CEntity::GetIsOnScreen(void)
-{
- return TheCamera.IsSphereVisible(GetBoundCentre(), GetBoundRadius(),
- &TheCamera.GetCameraMatrix());
-}
-
-bool
-CEntity::GetIsOnScreenComplex(void)
-{
- RwV3d boundBox[8];
-
- if(TheCamera.IsPointVisible(GetBoundCentre(), &TheCamera.GetCameraMatrix()))
- return true;
-
- CRect rect = GetBoundRect();
- CColModel *colmodel = CModelInfo::GetModelInfo(m_modelIndex)->GetColModel();
- float z = GetPosition().z;
- float minz = z + colmodel->boundingBox.min.z;
- float maxz = z + colmodel->boundingBox.max.z;
- boundBox[0].x = rect.left;
- boundBox[0].y = rect.bottom;
- boundBox[0].z = minz;
- boundBox[1].x = rect.left;
- boundBox[1].y = rect.top;
- boundBox[1].z = minz;
- boundBox[2].x = rect.right;
- boundBox[2].y = rect.bottom;
- boundBox[2].z = minz;
- boundBox[3].x = rect.right;
- boundBox[3].y = rect.top;
- boundBox[3].z = minz;
- boundBox[4].x = rect.left;
- boundBox[4].y = rect.bottom;
- boundBox[4].z = maxz;
- boundBox[5].x = rect.left;
- boundBox[5].y = rect.top;
- boundBox[5].z = maxz;
- boundBox[6].x = rect.right;
- boundBox[6].y = rect.bottom;
- boundBox[6].z = maxz;
- boundBox[7].x = rect.right;
- boundBox[7].y = rect.top;
- boundBox[7].z = maxz;
-
- return TheCamera.IsBoxVisible(boundBox, &TheCamera.GetCameraMatrix());
-}
-
-void
-CEntity::Add(void)
-{
- int x, xstart, xmid, xend;
- int y, ystart, ymid, yend;
- CSector *s;
- CPtrList *list;
-
- CRect bounds = GetBoundRect();
- xstart = CWorld::GetSectorIndexX(bounds.left);
- xend = CWorld::GetSectorIndexX(bounds.right);
- xmid = CWorld::GetSectorIndexX((bounds.left + bounds.right)/2.0f);
- ystart = CWorld::GetSectorIndexY(bounds.top);
- yend = CWorld::GetSectorIndexY(bounds.bottom);
- ymid = CWorld::GetSectorIndexY((bounds.top + bounds.bottom)/2.0f);
- assert(xstart >= 0);
- assert(xend < NUMSECTORS_X);
- assert(ystart >= 0);
- assert(yend < NUMSECTORS_Y);
-
- for(y = ystart; y <= yend; y++)
- for(x = xstart; x <= xend; x++){
- s = CWorld::GetSector(x, y);
- if(x == xmid && y == ymid) switch(m_type){
- case ENTITY_TYPE_BUILDING:
- list = &s->m_lists[ENTITYLIST_BUILDINGS];
- break;
- case ENTITY_TYPE_VEHICLE:
- list = &s->m_lists[ENTITYLIST_VEHICLES];
- break;
- case ENTITY_TYPE_PED:
- list = &s->m_lists[ENTITYLIST_PEDS];
- break;
- case ENTITY_TYPE_OBJECT:
- list = &s->m_lists[ENTITYLIST_OBJECTS];
- break;
- case ENTITY_TYPE_DUMMY:
- list = &s->m_lists[ENTITYLIST_DUMMIES];
- break;
- }else switch(m_type){
- case ENTITY_TYPE_BUILDING:
- list = &s->m_lists[ENTITYLIST_BUILDINGS_OVERLAP];
- break;
- case ENTITY_TYPE_VEHICLE:
- list = &s->m_lists[ENTITYLIST_VEHICLES_OVERLAP];
- break;
- case ENTITY_TYPE_PED:
- list = &s->m_lists[ENTITYLIST_PEDS_OVERLAP];
- break;
- case ENTITY_TYPE_OBJECT:
- list = &s->m_lists[ENTITYLIST_OBJECTS_OVERLAP];
- break;
- case ENTITY_TYPE_DUMMY:
- list = &s->m_lists[ENTITYLIST_DUMMIES_OVERLAP];
- break;
- }
- list->InsertItem(this);
- }
-}
-
-void
-CEntity::Remove(void)
-{
- int x, xstart, xmid, xend;
- int y, ystart, ymid, yend;
- CSector *s;
- CPtrList *list;
-
- CRect bounds = GetBoundRect();
- xstart = CWorld::GetSectorIndexX(bounds.left);
- xend = CWorld::GetSectorIndexX(bounds.right);
- xmid = CWorld::GetSectorIndexX((bounds.left + bounds.right)/2.0f);
- ystart = CWorld::GetSectorIndexY(bounds.top);
- yend = CWorld::GetSectorIndexY(bounds.bottom);
- ymid = CWorld::GetSectorIndexY((bounds.top + bounds.bottom)/2.0f);
- assert(xstart >= 0);
- assert(xend < NUMSECTORS_X);
- assert(ystart >= 0);
- assert(yend < NUMSECTORS_Y);
-
- for(y = ystart; y <= yend; y++)
- for(x = xstart; x <= xend; x++){
- s = CWorld::GetSector(x, y);
- if(x == xmid && y == ymid) switch(m_type){
- case ENTITY_TYPE_BUILDING:
- list = &s->m_lists[ENTITYLIST_BUILDINGS];
- break;
- case ENTITY_TYPE_VEHICLE:
- list = &s->m_lists[ENTITYLIST_VEHICLES];
- break;
- case ENTITY_TYPE_PED:
- list = &s->m_lists[ENTITYLIST_PEDS];
- break;
- case ENTITY_TYPE_OBJECT:
- list = &s->m_lists[ENTITYLIST_OBJECTS];
- break;
- case ENTITY_TYPE_DUMMY:
- list = &s->m_lists[ENTITYLIST_DUMMIES];
- break;
- }else switch(m_type){
- case ENTITY_TYPE_BUILDING:
- list = &s->m_lists[ENTITYLIST_BUILDINGS_OVERLAP];
- break;
- case ENTITY_TYPE_VEHICLE:
- list = &s->m_lists[ENTITYLIST_VEHICLES_OVERLAP];
- break;
- case ENTITY_TYPE_PED:
- list = &s->m_lists[ENTITYLIST_PEDS_OVERLAP];
- break;
- case ENTITY_TYPE_OBJECT:
- list = &s->m_lists[ENTITYLIST_OBJECTS_OVERLAP];
- break;
- case ENTITY_TYPE_DUMMY:
- list = &s->m_lists[ENTITYLIST_DUMMIES_OVERLAP];
- break;
- }
- list->RemoveItem(this);
- }
-}
-
-void
CEntity::SetModelIndex(uint32 id)
{
m_modelIndex = id;
@@ -301,7 +114,11 @@ CEntity::CreateRwObject(void)
CBaseModelInfo *mi;
mi = CModelInfo::GetModelInfo(m_modelIndex);
+
+ PUSH_MEMID(MEMID_WORLD);
m_rwObject = mi->CreateInstance();
+ POP_MEMID();
+
if(m_rwObject){
if(IsBuilding())
gBuildings++;
@@ -314,6 +131,48 @@ CEntity::CreateRwObject(void)
}
void
+CEntity::AttachToRwObject(RwObject *obj)
+{
+ m_rwObject = obj;
+ if(m_rwObject){
+ if(RwObjectGetType(m_rwObject) == rpATOMIC)
+ m_matrix.Attach(RwFrameGetMatrix(RpAtomicGetFrame((RpAtomic*)m_rwObject)), false);
+ else if(RwObjectGetType(m_rwObject) == rpCLUMP)
+ m_matrix.Attach(RwFrameGetMatrix(RpClumpGetFrame((RpClump*)m_rwObject)), false);
+ CModelInfo::GetModelInfo(m_modelIndex)->AddRef();
+ }
+}
+
+void
+CEntity::DetachFromRwObject(void)
+{
+ if(m_rwObject)
+ CModelInfo::GetModelInfo(m_modelIndex)->RemoveRef();
+ m_rwObject = nil;
+ m_matrix.Detach();
+}
+
+RpAtomic*
+AtomicRemoveAnimFromSkinCB(RpAtomic *atomic, void *data)
+{
+ if(RpSkinGeometryGetSkin(RpAtomicGetGeometry(atomic))){
+ RpHAnimHierarchy *hier = RpSkinAtomicGetHAnimHierarchy(atomic);
+#ifdef LIBRW
+ if(hier && hier->interpolator->currentAnim){
+ RpHAnimAnimationDestroy(hier->interpolator->currentAnim);
+ hier->interpolator->currentAnim = nil;
+ }
+#else
+ if(hier && hier->currentAnim){
+ RpHAnimAnimationDestroy(hier->currentAnim->pCurrentAnim);
+ hier->currentAnim = nil;
+ }
+#endif
+ }
+ return atomic;
+}
+
+void
CEntity::DeleteRwObject(void)
{
RwFrame *f;
@@ -336,35 +195,6 @@ CEntity::DeleteRwObject(void)
}
}
-void
-CEntity::UpdateRwFrame(void)
-{
- if(m_rwObject){
- if(RwObjectGetType(m_rwObject) == rpATOMIC)
- RwFrameUpdateObjects(RpAtomicGetFrame((RpAtomic*)m_rwObject));
- else if(RwObjectGetType(m_rwObject) == rpCLUMP)
- RwFrameUpdateObjects(RpClumpGetFrame((RpClump*)m_rwObject));
- }
-}
-
-void
-CEntity::SetupBigBuilding(void)
-{
- CSimpleModelInfo *mi;
-
- mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(m_modelIndex);
- bIsBIGBuilding = true;
- bStreamingDontDelete = true;
- bUsesCollision = false;
- m_level = CTheZones::GetLevelFromPosition(&GetPosition());
- 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
CEntity::GetBoundRect(void)
{
@@ -386,6 +216,74 @@ CEntity::GetBoundRect(void)
return rect;
}
+CVector
+CEntity::GetBoundCentre(void)
+{
+ CVector v;
+ GetBoundCentre(v);
+ return v;
+}
+
+void
+CEntity::GetBoundCentre(CVector &out)
+{
+ out = m_matrix * CModelInfo::GetModelInfo(m_modelIndex)->GetColModel()->boundingSphere.center;
+}
+
+float
+CEntity::GetBoundRadius(void)
+{
+ return CModelInfo::GetModelInfo(m_modelIndex)->GetColModel()->boundingSphere.radius;
+}
+
+void
+CEntity::UpdateRwFrame(void)
+{
+ if(m_rwObject){
+ if(RwObjectGetType(m_rwObject) == rpATOMIC)
+ RwFrameUpdateObjects(RpAtomicGetFrame((RpAtomic*)m_rwObject));
+ else if(RwObjectGetType(m_rwObject) == rpCLUMP)
+ RwFrameUpdateObjects(RpClumpGetFrame((RpClump*)m_rwObject));
+ }
+}
+
+void
+CEntity::UpdateRpHAnim(void)
+{
+ if(IsClumpSkinned(GetClump())){
+ RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(GetClump());
+ RpHAnimHierarchyUpdateMatrices(hier);
+#if 0
+ int i;
+ char buf[256];
+ if(this == (CEntity*)FindPlayerPed())
+ for(i = 0; i < hier->numNodes; i++){
+ RpHAnimStdInterpFrame *kf = (RpHAnimStdInterpFrame*)rpHANIMHIERARCHYGETINTERPFRAME(hier, i);
+ sprintf(buf, "%6.3f %6.3f %6.3f %6.3f %6.3f %6.3f %6.3f %d %s",
+ kf->q.imag.x, kf->q.imag.y, kf->q.imag.z, kf->q.real,
+ kf->t.x, kf->t.y, kf->t.z,
+ HIERNODEID(hier, i),
+ ConvertBoneTag2BoneName(HIERNODEID(hier, i)));
+ CDebug::PrintAt(buf, 10, 1+i*3);
+
+ RwMatrix *m = &RpHAnimHierarchyGetMatrixArray(hier)[i];
+ sprintf(buf, "%6.3f %6.3f %6.3f %6.3f",
+ m->right.x, m->up.x, m->at.x, m->pos.x);
+ CDebug::PrintAt(buf, 80, 1+i*3+0);
+ sprintf(buf, "%6.3f %6.3f %6.3f %6.3f",
+ m->right.y, m->up.y, m->at.y, m->pos.y);
+ CDebug::PrintAt(buf, 80, 1+i*3+1);
+ sprintf(buf, "%6.3f %6.3f %6.3f %6.3f",
+ m->right.z, m->up.z, m->at.z, m->pos.z);
+ CDebug::PrintAt(buf, 80, 1+i*3+2);
+ }
+
+ void RenderSkeleton(RpHAnimHierarchy *hier);
+ RenderSkeleton(hier);
+#endif
+ }
+}
+
bool
CEntity::HasPreRenderEffects(void)
{
@@ -511,15 +409,6 @@ CEntity::PreRender(void)
}
void
-CEntity::PreRenderForGlassWindow(void)
-{
- if(((CSimpleModelInfo*)CModelInfo::GetModelInfo(m_modelIndex))->m_isArtistGlass)
- return;
- CGlass::AskForObjectToBeRenderedInGlass(this);
- bIsVisible = false;
-}
-
-void
CEntity::Render(void)
{
if(m_rwObject){
@@ -533,416 +422,213 @@ CEntity::Render(void)
}
bool
-CEntity::SetupLighting(void)
+CEntity::GetIsTouching(CVector const &center, float radius)
{
- return false;
+ return sq(GetBoundRadius()+radius) > (GetBoundCentre()-center).MagnitudeSqr();
}
-void
-CEntity::AttachToRwObject(RwObject *obj)
+bool
+CEntity::IsVisible(void)
{
- m_rwObject = obj;
- if(m_rwObject){
- if(RwObjectGetType(m_rwObject) == rpATOMIC)
- m_matrix.Attach(RwFrameGetMatrix(RpAtomicGetFrame((RpAtomic*)m_rwObject)), false);
- else if(RwObjectGetType(m_rwObject) == rpCLUMP)
- m_matrix.Attach(RwFrameGetMatrix(RpClumpGetFrame((RpClump*)m_rwObject)), false);
- CModelInfo::GetModelInfo(m_modelIndex)->AddRef();
- }
+ return m_rwObject && bIsVisible && GetIsOnScreen();
}
-void
-CEntity::DetachFromRwObject(void)
+bool
+CEntity::IsVisibleComplex(void)
{
- if(m_rwObject)
- CModelInfo::GetModelInfo(m_modelIndex)->RemoveRef();
- m_rwObject = nil;
- m_matrix.Detach();
+ return m_rwObject && bIsVisible && GetIsOnScreenComplex();
}
-void
-CEntity::RegisterReference(CEntity **pent)
+bool
+CEntity::GetIsOnScreen(void)
{
- if(IsBuilding())
- return;
- CReference *ref;
- // check if already registered
- for(ref = m_pFirstReference; ref; ref = ref->next)
- if(ref->pentity == pent)
- return;
- // have to allocate new reference
- ref = CReferences::pEmptyList;
- if(ref){
- CReferences::pEmptyList = ref->next;
-
- ref->pentity = pent;
- ref->next = m_pFirstReference;
- m_pFirstReference = ref;
- return;
- }
- return;
+ return TheCamera.IsSphereVisible(GetBoundCentre(), GetBoundRadius(),
+ &TheCamera.GetCameraMatrix());
}
-// Clear all references to this entity
-void
-CEntity::ResolveReferences(void)
+bool
+CEntity::GetIsOnScreenComplex(void)
{
- CReference *ref;
- // clear pointers to this entity
- for(ref = m_pFirstReference; ref; ref = ref->next)
- if(*ref->pentity == this)
- *ref->pentity = nil;
- // free list
- if(m_pFirstReference){
- for(ref = m_pFirstReference; ref->next; ref = ref->next)
- ;
- ref->next = CReferences::pEmptyList;
- CReferences::pEmptyList = m_pFirstReference;
- m_pFirstReference = nil;
- }
-}
+ RwV3d boundBox[8];
-// Free all references that no longer point to this entity
-void
-CEntity::PruneReferences(void)
-{
- CReference *ref, *next, **lastnextp;
- lastnextp = &m_pFirstReference;
- for(ref = m_pFirstReference; ref; ref = next){
- next = ref->next;
- if(*ref->pentity == this)
- lastnextp = &ref->next;
- else{
- *lastnextp = ref->next;
- ref->next = CReferences::pEmptyList;
- CReferences::pEmptyList = ref;
- }
- }
-}
+ if(TheCamera.IsPointVisible(GetBoundCentre(), &TheCamera.GetCameraMatrix()))
+ return true;
-// Clean up the reference from *pent -> 'this'
-void
-CEntity::CleanUpOldReference(CEntity **pent)
-{
- CReference* ref, ** lastnextp;
- lastnextp = &m_pFirstReference;
- for (ref = m_pFirstReference; ref; ref = ref->next) {
- if (ref->pentity == pent) {
- *lastnextp = ref->next;
- ref->next = CReferences::pEmptyList;
- CReferences::pEmptyList = ref;
- break;
- }
- lastnextp = &ref->next;
- }
+ CRect rect = GetBoundRect();
+ CColModel *colmodel = CModelInfo::GetModelInfo(m_modelIndex)->GetColModel();
+ float z = GetPosition().z;
+ float minz = z + colmodel->boundingBox.min.z;
+ float maxz = z + colmodel->boundingBox.max.z;
+ boundBox[0].x = rect.left;
+ boundBox[0].y = rect.bottom;
+ boundBox[0].z = minz;
+ boundBox[1].x = rect.left;
+ boundBox[1].y = rect.top;
+ boundBox[1].z = minz;
+ boundBox[2].x = rect.right;
+ boundBox[2].y = rect.bottom;
+ boundBox[2].z = minz;
+ boundBox[3].x = rect.right;
+ boundBox[3].y = rect.top;
+ boundBox[3].z = minz;
+ boundBox[4].x = rect.left;
+ boundBox[4].y = rect.bottom;
+ boundBox[4].z = maxz;
+ boundBox[5].x = rect.left;
+ boundBox[5].y = rect.top;
+ boundBox[5].z = maxz;
+ boundBox[6].x = rect.right;
+ boundBox[6].y = rect.bottom;
+ boundBox[6].z = maxz;
+ boundBox[7].x = rect.right;
+ boundBox[7].y = rect.top;
+ boundBox[7].z = maxz;
+
+ return TheCamera.IsBoxVisible(boundBox, &TheCamera.GetCameraMatrix());
}
void
-CEntity::UpdateRpHAnim(void)
+CEntity::Add(void)
{
- if(IsClumpSkinned(GetClump())){
- RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(GetClump());
- RpHAnimHierarchyUpdateMatrices(hier);
-#if 0
- int i;
- char buf[256];
- if(this == (CEntity*)FindPlayerPed())
- for(i = 0; i < hier->numNodes; i++){
- RpHAnimStdInterpFrame *kf = (RpHAnimStdInterpFrame*)rpHANIMHIERARCHYGETINTERPFRAME(hier, i);
- sprintf(buf, "%6.3f %6.3f %6.3f %6.3f %6.3f %6.3f %6.3f %d %s",
- kf->q.imag.x, kf->q.imag.y, kf->q.imag.z, kf->q.real,
- kf->t.x, kf->t.y, kf->t.z,
- HIERNODEID(hier, i),
- ConvertBoneTag2BoneName(HIERNODEID(hier, i)));
- CDebug::PrintAt(buf, 10, 1+i*3);
-
- RwMatrix *m = &RpHAnimHierarchyGetMatrixArray(hier)[i];
- sprintf(buf, "%6.3f %6.3f %6.3f %6.3f",
- m->right.x, m->up.x, m->at.x, m->pos.x);
- CDebug::PrintAt(buf, 80, 1+i*3+0);
- sprintf(buf, "%6.3f %6.3f %6.3f %6.3f",
- m->right.y, m->up.y, m->at.y, m->pos.y);
- CDebug::PrintAt(buf, 80, 1+i*3+1);
- sprintf(buf, "%6.3f %6.3f %6.3f %6.3f",
- m->right.z, m->up.z, m->at.z, m->pos.z);
- CDebug::PrintAt(buf, 80, 1+i*3+2);
- }
+ int x, xstart, xmid, xend;
+ int y, ystart, ymid, yend;
+ CSector *s;
+ CPtrList *list;
- void RenderSkeleton(RpHAnimHierarchy *hier);
- RenderSkeleton(hier);
-#endif
- }
-}
+ CRect bounds = GetBoundRect();
+ xstart = CWorld::GetSectorIndexX(bounds.left);
+ xend = CWorld::GetSectorIndexX(bounds.right);
+ xmid = CWorld::GetSectorIndexX((bounds.left + bounds.right)/2.0f);
+ ystart = CWorld::GetSectorIndexY(bounds.top);
+ yend = CWorld::GetSectorIndexY(bounds.bottom);
+ ymid = CWorld::GetSectorIndexY((bounds.top + bounds.bottom)/2.0f);
+ assert(xstart >= 0);
+ assert(xend < NUMSECTORS_X);
+ assert(ystart >= 0);
+ assert(yend < NUMSECTORS_Y);
-void
-CEntity::AddSteamsFromGround(CVector *unused)
-{
- int i, n;
- C2dEffect *effect;
- CVector pos;
-
- n = CModelInfo::GetModelInfo(GetModelIndex())->GetNum2dEffects();
- for(i = 0; i < n; i++){
- effect = CModelInfo::GetModelInfo(GetModelIndex())->Get2dEffect(i);
- if(effect->type != EFFECT_PARTICLE)
- continue;
-
- pos = GetMatrix() * effect->pos;
- switch(effect->particle.particleType){
- case 0:
- CParticleObject::AddObject(POBJECT_PAVEMENT_STEAM, pos, effect->particle.dir, effect->particle.scale, false);
- break;
- case 1:
- CParticleObject::AddObject(POBJECT_WALL_STEAM, pos, effect->particle.dir, effect->particle.scale, false);
- break;
- case 2:
- CParticleObject::AddObject(POBJECT_DRY_ICE, pos, effect->particle.scale, false);
- break;
- case 3:
- CParticleObject::AddObject(POBJECT_SMALL_FIRE, pos, effect->particle.dir, effect->particle.scale, false);
- break;
- case 4:
- CParticleObject::AddObject(POBJECT_DARK_SMOKE, pos, effect->particle.dir, effect->particle.scale, false);
- break;
- case 5:
- CParticleObject::AddObject(POBJECT_WATER_FOUNTAIN_VERT, pos, effect->particle.dir, effect->particle.scale, false);
- break;
- case 6:
- CParticleObject::AddObject(POBJECT_WATER_FOUNTAIN_HORIZ, pos, effect->particle.dir, effect->particle.scale, false);
- break;
+ for(y = ystart; y <= yend; y++)
+ for(x = xstart; x <= xend; x++){
+ s = CWorld::GetSector(x, y);
+ if(x == xmid && y == ymid) switch(m_type){
+ case ENTITY_TYPE_BUILDING:
+ list = &s->m_lists[ENTITYLIST_BUILDINGS];
+ break;
+ case ENTITY_TYPE_VEHICLE:
+ list = &s->m_lists[ENTITYLIST_VEHICLES];
+ break;
+ case ENTITY_TYPE_PED:
+ list = &s->m_lists[ENTITYLIST_PEDS];
+ break;
+ case ENTITY_TYPE_OBJECT:
+ list = &s->m_lists[ENTITYLIST_OBJECTS];
+ break;
+ case ENTITY_TYPE_DUMMY:
+ list = &s->m_lists[ENTITYLIST_DUMMIES];
+ break;
+ }else switch(m_type){
+ case ENTITY_TYPE_BUILDING:
+ list = &s->m_lists[ENTITYLIST_BUILDINGS_OVERLAP];
+ break;
+ case ENTITY_TYPE_VEHICLE:
+ list = &s->m_lists[ENTITYLIST_VEHICLES_OVERLAP];
+ break;
+ case ENTITY_TYPE_PED:
+ list = &s->m_lists[ENTITYLIST_PEDS_OVERLAP];
+ break;
+ case ENTITY_TYPE_OBJECT:
+ list = &s->m_lists[ENTITYLIST_OBJECTS_OVERLAP];
+ break;
+ case ENTITY_TYPE_DUMMY:
+ list = &s->m_lists[ENTITYLIST_DUMMIES_OVERLAP];
+ break;
+ }
+ list->InsertItem(this);
}
- }
}
void
-CEntity::ProcessLightsForEntity(void)
+CEntity::Remove(void)
{
- int i, n;
- C2dEffect *effect;
- CVector pos;
- bool lightOn, lightFlickering;
- uint32 flashTimer1, flashTimer2, flashTimer3;
-
- if(bRenderDamaged || !bIsVisible || GetUp().z < 0.96f)
- return;
-
- flashTimer1 = 0;
- flashTimer2 = 0;
- flashTimer3 = 0;
-
- n = CModelInfo::GetModelInfo(GetModelIndex())->GetNum2dEffects();
- for(i = 0; i < n; i++, flashTimer1 += 0x80, flashTimer2 += 0x100, flashTimer3 += 0x200){
- effect = CModelInfo::GetModelInfo(GetModelIndex())->Get2dEffect(i);
+ int x, xstart, xmid, xend;
+ int y, ystart, ymid, yend;
+ CSector *s;
+ CPtrList *list;
- switch(effect->type){
- case EFFECT_LIGHT:
- pos = GetMatrix() * effect->pos;
+ CRect bounds = GetBoundRect();
+ xstart = CWorld::GetSectorIndexX(bounds.left);
+ xend = CWorld::GetSectorIndexX(bounds.right);
+ xmid = CWorld::GetSectorIndexX((bounds.left + bounds.right)/2.0f);
+ ystart = CWorld::GetSectorIndexY(bounds.top);
+ yend = CWorld::GetSectorIndexY(bounds.bottom);
+ ymid = CWorld::GetSectorIndexY((bounds.top + bounds.bottom)/2.0f);
+ assert(xstart >= 0);
+ assert(xend < NUMSECTORS_X);
+ assert(ystart >= 0);
+ assert(yend < NUMSECTORS_Y);
- lightOn = false;
- lightFlickering = false;
- switch(effect->light.lightType){
- case LIGHT_ON:
- lightOn = true;
- break;
- case LIGHT_ON_NIGHT:
- if(CClock::GetHours() > 18 || CClock::GetHours() < 7)
- lightOn = true;
- break;
- case LIGHT_FLICKER:
- if((CTimer::GetTimeInMilliseconds() ^ m_randomSeed) & 0x60)
- lightOn = true;
- else
- lightFlickering = true;
- if((CTimer::GetTimeInMilliseconds()>>11 ^ m_randomSeed) & 3)
- lightOn = true;
- 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;
+ for(y = ystart; y <= yend; y++)
+ for(x = xstart; x <= xend; x++){
+ s = CWorld::GetSector(x, y);
+ if(x == xmid && y == ymid) switch(m_type){
+ case ENTITY_TYPE_BUILDING:
+ list = &s->m_lists[ENTITYLIST_BUILDINGS];
break;
- case LIGHT_FLASH1_NIGHT:
- if(CClock::GetHours() > 18 || CClock::GetHours() < 7)
- if((CTimer::GetTimeInMilliseconds() + flashTimer1) & 0x200)
- lightOn = true;
+ case ENTITY_TYPE_VEHICLE:
+ list = &s->m_lists[ENTITYLIST_VEHICLES];
break;
- case LIGHT_FLASH2:
- if((CTimer::GetTimeInMilliseconds() + flashTimer2) & 0x400)
- lightOn = true;
+ case ENTITY_TYPE_PED:
+ list = &s->m_lists[ENTITYLIST_PEDS];
break;
- case LIGHT_FLASH2_NIGHT:
- if(CClock::GetHours() > 18 || CClock::GetHours() < 7)
- if((CTimer::GetTimeInMilliseconds() + flashTimer2) & 0x400)
- lightOn = true;
+ case ENTITY_TYPE_OBJECT:
+ list = &s->m_lists[ENTITYLIST_OBJECTS];
break;
- case LIGHT_FLASH3:
- if((CTimer::GetTimeInMilliseconds() + flashTimer3) & 0x800)
- lightOn = true;
+ case ENTITY_TYPE_DUMMY:
+ list = &s->m_lists[ENTITYLIST_DUMMIES];
break;
- case LIGHT_FLASH3_NIGHT:
- if(CClock::GetHours() > 18 || CClock::GetHours() < 7)
- if((CTimer::GetTimeInMilliseconds() + flashTimer3) & 0x800)
- lightOn = true;
+ }else switch(m_type){
+ case ENTITY_TYPE_BUILDING:
+ list = &s->m_lists[ENTITYLIST_BUILDINGS_OVERLAP];
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;
- }
+ case ENTITY_TYPE_VEHICLE:
+ list = &s->m_lists[ENTITYLIST_VEHICLES_OVERLAP];
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;
- }
- }
+ case ENTITY_TYPE_PED:
+ list = &s->m_lists[ENTITYLIST_PEDS_OVERLAP];
break;
- case LIGHT_BRIDGE_FLASH1:
- if(CBridge::ShouldLightsBeFlashing() && CTimer::GetTimeInMilliseconds() & 0x200)
- lightOn = true;
+ case ENTITY_TYPE_OBJECT:
+ list = &s->m_lists[ENTITYLIST_OBJECTS_OVERLAP];
break;
- case LIGHT_BRIDGE_FLASH2:
- if(CBridge::ShouldLightsBeFlashing() && (CTimer::GetTimeInMilliseconds() & 0x1FF) < 60)
- lightOn = true;
+ case ENTITY_TYPE_DUMMY:
+ list = &s->m_lists[ENTITYLIST_DUMMIES_OVERLAP];
break;
}
+ list->RemoveItem(this);
+ }
+}
- if(effect->light.flags & LIGHTFLAG_HIDE_OBJECT){
- if(lightOn)
- bDoNotRender = false;
- else
- bDoNotRender = true;
- return;
- }
-
- // Corona
- if(lightOn)
- CCoronas::RegisterCorona((uintptr)this + i,
- effect->col.r, effect->col.g, effect->col.b, 255,
- pos, effect->light.size, effect->light.dist,
- effect->light.corona, effect->light.flareType, effect->light.roadReflection,
- effect->light.flags&LIGHTFLAG_LOSCHECK, CCoronas::STREAK_OFF, 0.0f,
- !!(effect->light.flags&LIGHTFLAG_LONG_DIST));
- else if(lightFlickering)
- CCoronas::RegisterCorona((uintptr)this + i,
- 0, 0, 0, 255,
- pos, effect->light.size, effect->light.dist,
- effect->light.corona, effect->light.flareType, effect->light.roadReflection,
- effect->light.flags&LIGHTFLAG_LOSCHECK, CCoronas::STREAK_OFF, 0.0f,
- !!(effect->light.flags&LIGHTFLAG_LONG_DIST));
-
- // Pointlight
- bool alreadyProcessedFog;
- alreadyProcessedFog = false;
- if(effect->light.range != 0.0f && lightOn){
- if(effect->col.r == 0 && effect->col.g == 0 && effect->col.b == 0){
- CPointLights::AddLight(CPointLights::LIGHT_POINT,
- pos, CVector(0.0f, 0.0f, 0.0f),
- effect->light.range,
- 0.0f, 0.0f, 0.0f,
- CPointLights::FOG_NONE, true);
- }else{
- CPointLights::AddLight(CPointLights::LIGHT_POINT,
- pos, CVector(0.0f, 0.0f, 0.0f),
- effect->light.range,
- effect->col.r*CTimeCycle::GetSpriteBrightness()/255.0f,
- effect->col.g*CTimeCycle::GetSpriteBrightness()/255.0f,
- effect->col.b*CTimeCycle::GetSpriteBrightness()/255.0f,
- (effect->light.flags & LIGHTFLAG_FOG) >> 1,
- true);
- alreadyProcessedFog = true;
- }
- }
-
- if(!alreadyProcessedFog){
- if(effect->light.flags & LIGHTFLAG_FOG_ALWAYS){
- CPointLights::AddLight(CPointLights::LIGHT_FOGONLY_ALWAYS,
- pos, CVector(0.0f, 0.0f, 0.0f),
- 0.0f,
- effect->col.r/255.0f, effect->col.g/255.0f, effect->col.b/255.0f,
- CPointLights::FOG_ALWAYS, true);
- }else if(effect->light.flags & LIGHTFLAG_FOG_NORMAL && lightOn && effect->light.range == 0.0f){
- CPointLights::AddLight(CPointLights::LIGHT_FOGONLY,
- pos, CVector(0.0f, 0.0f, 0.0f),
- 0.0f,
- effect->col.r/255.0f, effect->col.g/255.0f, effect->col.b/255.0f,
- CPointLights::FOG_NORMAL, true);
- }
- }
+float
+CEntity::GetDistanceFromCentreOfMassToBaseOfModel(void)
+{
+ return -CModelInfo::GetModelInfo(m_modelIndex)->GetColModel()->boundingBox.min.z;
+}
- // 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;
+void
+CEntity::SetupBigBuilding(void)
+{
+ CSimpleModelInfo *mi;
- 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;
- }
- }
+ mi = (CSimpleModelInfo*)CModelInfo::GetModelInfo(m_modelIndex);
+ bIsBIGBuilding = true;
+ bStreamingDontDelete = true;
+ bUsesCollision = false;
+ m_level = CTheZones::GetLevelFromPosition(&GetPosition());
+ 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());
}
float WindTabel[] = {
@@ -1036,14 +722,67 @@ CEntity::ModifyMatrixForBannerInWind(void)
UpdateRwFrame();
}
-void
-CEntity::AddSteamsFromGround(CPtrList& list)
+void
+CEntity::PreRenderForGlassWindow(void)
+{
+ if(((CSimpleModelInfo*)CModelInfo::GetModelInfo(m_modelIndex))->m_isArtistGlass)
+ return;
+ CGlass::AskForObjectToBeRenderedInGlass(this);
+ bIsVisible = false;
+}
+
+/*
+0x487A10 - SetAtomicAlphaCB
+0x4879E0 - SetClumpAlphaCB
+*/
+
+RpMaterial*
+SetAtomicAlphaCB(RpMaterial *material, void *data)
{
- CPtrNode *pNode = list.first;
- while (pNode) {
- ((CEntity*)pNode->item)->AddSteamsFromGround(nil);
- pNode = pNode->next;
+ ((RwRGBA*)RpMaterialGetColor(material))->alpha = (uint8)(uintptr)data;
+ return material;
+}
+
+RpAtomic*
+SetClumpAlphaCB(RpAtomic *atomic, void *data)
+{
+ RpGeometry *geometry = RpAtomicGetGeometry(atomic);
+ RpGeometrySetFlags(geometry, RpGeometryGetFlags(geometry) | rpGEOMETRYMODULATEMATERIALCOLOR);
+ RpGeometryForAllMaterials(geometry, SetAtomicAlphaCB, (void*)data);
+ return atomic;
+}
+
+void
+CEntity::SetRwObjectAlpha(int32 alpha)
+{
+ if (m_rwObject != nil) {
+ switch (RwObjectGetType(m_rwObject)) {
+ case rpATOMIC: {
+ RpGeometry *geometry = RpAtomicGetGeometry((RpAtomic*)m_rwObject);
+ RpGeometrySetFlags(geometry, RpGeometryGetFlags(geometry) | rpGEOMETRYMODULATEMATERIALCOLOR);
+ RpGeometryForAllMaterials(geometry, SetAtomicAlphaCB, (void*)alpha);
+ break;
+ }
+ case rpCLUMP:
+ RpClumpForAllAtomics((RpClump*)m_rwObject, SetClumpAlphaCB, (void*)alpha);
+ break;
+ }
+ }
+}
+
+bool IsEntityPointerValid(CEntity* pEntity)
+{
+ if (!pEntity)
+ return false;
+ switch (pEntity->GetType()) {
+ case ENTITY_TYPE_NOTHING: return false;
+ case ENTITY_TYPE_BUILDING: return IsBuildingPointerValid((CBuilding*)pEntity);
+ case ENTITY_TYPE_VEHICLE: return IsVehiclePointerValid((CVehicle*)pEntity);
+ case ENTITY_TYPE_PED: return IsPedPointerValid((CPed*)pEntity);
+ case ENTITY_TYPE_OBJECT: return IsObjectPointerValid((CObject*)pEntity);
+ case ENTITY_TYPE_DUMMY: return IsDummyPointerValid((CDummy*)pEntity);
}
+ return false;
}
#ifdef COMPATIBLE_SAVES
@@ -1160,84 +899,3 @@ CEntity::LoadEntityFlags(uint8*& buf)
}
#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 08d1900a..2749e3f7 100644
--- a/src/entities/Entity.h
+++ b/src/entities/Entity.h
@@ -6,7 +6,7 @@
struct CReference;
class CPtrList;
-enum eEntityType : uint8
+enum eEntityType
{
ENTITY_TYPE_NOTHING = 0,
ENTITY_TYPE_BUILDING,
@@ -16,7 +16,7 @@ enum eEntityType : uint8
ENTITY_TYPE_DUMMY,
};
-enum eEntityStatus : uint8
+enum eEntityStatus
{
STATUS_PLAYER,
STATUS_PLAYER_PLAYBACKFROMBUFFER,
@@ -99,10 +99,10 @@ public:
CReference *m_pFirstReference;
public:
- eEntityType GetType() const { return (eEntityType)m_type; }
- void SetType(eEntityType type) { m_type = type; }
- eEntityStatus GetStatus() const { return (eEntityStatus)m_status; }
- void SetStatus(eEntityStatus status) { m_status = status; }
+ uint8 GetType() const { return m_type; }
+ void SetType(uint8 type) { m_type = type; }
+ 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 || bIsStaticWaitingForCollision; }
void SetIsStatic(bool state) { bIsStatic = state; }
@@ -130,7 +130,7 @@ public:
virtual void PreRender(void);
virtual void Render(void);
virtual bool SetupLighting(void);
- virtual void RemoveLighting(bool) {}
+ virtual void RemoveLighting(bool);
virtual void FlagToDestroyWhenNextProcessed(void) {}
bool IsBuilding(void) { return m_type == ENTITY_TYPE_BUILDING; }
@@ -149,14 +149,14 @@ public:
}
void GetBoundCentre(CVector &out);
- CVector GetBoundCentre(void) { CVector v; GetBoundCentre(v); return v; }
- float GetBoundRadius(void) { return CModelInfo::GetModelInfo(m_modelIndex)->GetColModel()->boundingSphere.radius; }
- float GetDistanceFromCentreOfMassToBaseOfModel(void) { return -CModelInfo::GetModelInfo(m_modelIndex)->GetColModel()->boundingBox.min.z; }
+ CVector GetBoundCentre(void);
+ float GetBoundRadius(void);
+ float GetDistanceFromCentreOfMassToBaseOfModel(void);
bool GetIsTouching(CVector const &center, float r);
bool GetIsOnScreen(void);
bool GetIsOnScreenComplex(void);
- bool IsVisible(void) { return m_rwObject && bIsVisible && GetIsOnScreen(); }
- bool IsVisibleComplex(void) { return m_rwObject && bIsVisible && GetIsOnScreenComplex(); }
+ bool IsVisible(void);
+ bool IsVisibleComplex(void);
bool IsEntityOccluded(void);
int16 GetModelIndex(void) const { return m_modelIndex; }
void UpdateRwFrame(void);
@@ -171,9 +171,7 @@ public:
void PruneReferences(void);
void CleanUpOldReference(CEntity **pent);
-#ifdef PED_SKIN
void UpdateRpHAnim(void);
-#endif
void PreRenderForGlassWindow(void);
void AddSteamsFromGround(CVector *unused);
@@ -181,8 +179,6 @@ public:
void ModifyMatrixForBannerInWind(void);
void ProcessLightsForEntity(void);
void SetRwObjectAlpha(int32 alpha);
-
- static void AddSteamsFromGround(CPtrList& list);
};
bool IsEntityPointerValid(CEntity*);
diff --git a/src/extras/custompipes.cpp b/src/extras/custompipes.cpp
index 2ae87950..2cecf1c0 100644
--- a/src/extras/custompipes.cpp
+++ b/src/extras/custompipes.cpp
@@ -44,7 +44,7 @@ CustomMatCopy(void *dst, void *src, int32, int32)
-static rw::TexDictionary *neoTxd;
+rw::TexDictionary *neoTxd;
bool bRenderingEnvMap;
int32 EnvMapSize = 128;
@@ -133,7 +133,11 @@ EnvMapRender(void)
EnvMapCam->getFrame()->matrix.pos = camPos;
EnvMapCam->getFrame()->transform(&EnvMapCam->getFrame()->matrix, rw::COMBINEREPLACE);
- rw::RGBA skycol = { CTimeCycle::GetSkyBottomRed(), CTimeCycle::GetSkyBottomGreen(), CTimeCycle::GetSkyBottomBlue(), 255 };
+ rw::RGBA skycol;
+ skycol.red = CTimeCycle::GetSkyBottomRed();
+ skycol.green = CTimeCycle::GetSkyBottomGreen();
+ skycol.blue = CTimeCycle::GetSkyBottomBlue();
+ skycol.alpha = 255;
EnvMapCam->clear(&skycol, rwCAMERACLEARZ|rwCAMERACLEARIMAGE);
RwCameraBeginUpdate(EnvMapCam);
bRenderingEnvMap = true;
@@ -337,7 +341,7 @@ ReadTweakValueTable(char *fp, InterpolatedValue &interp)
* Neo Vehicle pipe
*/
-int32 VehiclePipeSwitch = VEHICLEPIPE_NEO;
+int32 VehiclePipeSwitch = VEHICLEPIPE_MATFX;
float VehicleShininess = 1.0f;
float VehicleSpecularity = 1.0f;
InterpolatedFloat Fresnel(0.4f);
diff --git a/src/extras/custompipes.h b/src/extras/custompipes.h
index 6e9c6517..ca3f0fb4 100644
--- a/src/extras/custompipes.h
+++ b/src/extras/custompipes.h
@@ -6,6 +6,7 @@
namespace CustomPipes {
+extern rw::TexDictionary *neoTxd;
struct CustomMatExt
{
diff --git a/src/extras/custompipes_d3d9.cpp b/src/extras/custompipes_d3d9.cpp
index 06ce1461..a195a4cc 100644
--- a/src/extras/custompipes_d3d9.cpp
+++ b/src/extras/custompipes_d3d9.cpp
@@ -132,13 +132,15 @@ vehicleRenderCB(rw::Atomic *atomic, rw::d3d9::InstanceDataHeader *header)
inst++;
}
+ d3d::setTexture(1, nil);
+
SetRenderState(SRCBLEND, BLENDSRCALPHA);
}
void
CreateVehiclePipe(void)
{
- if(CFileMgr::LoadFile("neo/carTweakingTable.dat", work_buff, sizeof(work_buff), "r") == 0)
+ if(CFileMgr::LoadFile("neo/carTweakingTable.dat", work_buff, sizeof(work_buff), "r") <= 0)
printf("Error: couldn't open 'neo/carTweakingTable.dat'\n");
else{
char *fp = (char*)work_buff;
@@ -170,6 +172,9 @@ DestroyVehiclePipe(void)
rw::d3d::destroyVertexShader(neoVehicle_VS);
neoVehicle_VS = nil;
+ rw::d3d::destroyPixelShader(neoVehicle_PS);
+ neoVehicle_PS = nil;
+
((rw::d3d9::ObjPipeline*)vehiclePipe)->destroy();
vehiclePipe = nil;
}
@@ -244,12 +249,13 @@ worldRenderCB(rw::Atomic *atomic, rw::d3d9::InstanceDataHeader *header)
drawInst(header, inst);
inst++;
}
+ d3d::setTexture(1, nil);
}
void
CreateWorldPipe(void)
{
- if(CFileMgr::LoadFile("neo/worldTweakingTable.dat", work_buff, sizeof(work_buff), "r") == 0)
+ if(CFileMgr::LoadFile("neo/worldTweakingTable.dat", work_buff, sizeof(work_buff), "r") <= 0)
printf("Error: couldn't open 'neo/worldTweakingTable.dat'\n");
else
ReadTweakValueTable((char*)work_buff, WorldLightmapBlend);
@@ -360,6 +366,12 @@ CreateGlossPipe(void)
void
DestroyGlossPipe(void)
{
+ rw::d3d::destroyVertexShader(neoGloss_VS);
+ neoGloss_VS = nil;
+
+ rw::d3d::destroyPixelShader(neoGloss_PS);
+ neoGloss_PS = nil;
+
((rw::d3d9::ObjPipeline*)glossPipe)->destroy();
glossPipe = nil;
}
@@ -489,7 +501,7 @@ rimSkinRenderCB(rw::Atomic *atomic, rw::d3d9::InstanceDataHeader *header)
void
CreateRimLightPipes(void)
{
- if(CFileMgr::LoadFile("neo/rimTweakingTable.dat", work_buff, sizeof(work_buff), "r") == 0)
+ if(CFileMgr::LoadFile("neo/rimTweakingTable.dat", work_buff, sizeof(work_buff), "r") <= 0)
printf("Error: couldn't open 'neo/rimTweakingTable.dat'\n");
else{
char *fp = (char*)work_buff;
diff --git a/src/extras/custompipes_gl.cpp b/src/extras/custompipes_gl.cpp
index dbd4d7d6..5f372530 100644
--- a/src/extras/custompipes_gl.cpp
+++ b/src/extras/custompipes_gl.cpp
@@ -133,6 +133,8 @@ vehicleRenderCB(rw::Atomic *atomic, rw::gl3::InstanceDataHeader *header)
inst++;
}
+ setTexture(1, nil);
+
SetRenderState(SRCBLEND, BLENDSRCALPHA);
#ifndef RW_GL_USE_VAOS
@@ -146,7 +148,7 @@ CreateVehiclePipe(void)
using namespace rw;
using namespace rw::gl3;
- if(CFileMgr::LoadFile("neo/carTweakingTable.dat", work_buff, sizeof(work_buff), "r") == 0)
+ if(CFileMgr::LoadFile("neo/carTweakingTable.dat", work_buff, sizeof(work_buff), "r") <= 0)
printf("Error: couldn't open 'neo/carTweakingTable.dat'\n");
else{
char *fp = (char*)work_buff;
@@ -158,13 +160,8 @@ CreateVehiclePipe(void)
{
-#ifdef RW_GLES2
-#include "gl2_shaders/neoVehicle_fs_gl2.inc"
-#include "gl2_shaders/neoVehicle_vs_gl2.inc"
-#else
-#include "shaders/neoVehicle_fs_gl3.inc"
-#include "shaders/neoVehicle_vs_gl3.inc"
-#endif
+#include "shaders/neoVehicle_fs_gl.inc"
+#include "shaders/neoVehicle_vs_gl.inc"
const char *vs[] = { shaderDecl, header_vert_src, neoVehicle_vert_src, nil };
const char *fs[] = { shaderDecl, header_frag_src, neoVehicle_frag_src, nil };
neoVehicleShader = Shader::create(vs, fs);
@@ -256,6 +253,7 @@ 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
@@ -267,19 +265,14 @@ CreateWorldPipe(void)
using namespace rw;
using namespace rw::gl3;
- if(CFileMgr::LoadFile("neo/worldTweakingTable.dat", work_buff, sizeof(work_buff), "r") == 0)
+ if(CFileMgr::LoadFile("neo/worldTweakingTable.dat", work_buff, sizeof(work_buff), "r") <= 0)
printf("Error: couldn't open 'neo/worldTweakingTable.dat'\n");
else
ReadTweakValueTable((char*)work_buff, WorldLightmapBlend);
{
-#ifdef RW_GLES2
-#include "gl2_shaders/neoWorldIII_fs_gl2.inc"
-#include "gl2_shaders/default_UV2_gl2.inc"
-#else
-#include "shaders/neoWorldVC_fs_gl3.inc"
-#include "shaders/default_UV2_gl3.inc"
-#endif
+#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, neoWorldVC_frag_src, nil };
neoWorldShader = Shader::create(vs, fs);
@@ -381,13 +374,8 @@ CreateGlossPipe(void)
using namespace rw::gl3;
{
-#ifdef RW_GLES2
-#include "gl2_shaders/neoGloss_fs_gl2.inc"
-#include "gl2_shaders/neoGloss_vs_gl2.inc"
-#else
-#include "shaders/neoGloss_fs_gl3.inc"
-#include "shaders/neoGloss_vs_gl3.inc"
-#endif
+#include "shaders/neoGloss_fs_gl.inc"
+#include "shaders/neoGloss_vs_gl.inc"
const char *vs[] = { shaderDecl, header_vert_src, neoGloss_vert_src, nil };
const char *fs[] = { shaderDecl, header_frag_src, neoGloss_frag_src, nil };
neoGlossShader = Shader::create(vs, fs);
@@ -546,7 +534,7 @@ CreateRimLightPipes(void)
{
using namespace rw::gl3;
- if(CFileMgr::LoadFile("neo/rimTweakingTable.dat", work_buff, sizeof(work_buff), "r") == 0)
+ if(CFileMgr::LoadFile("neo/rimTweakingTable.dat", work_buff, sizeof(work_buff), "r") <= 0)
printf("Error: couldn't open 'neo/rimTweakingTable.dat'\n");
else{
char *fp = (char*)work_buff;
@@ -558,13 +546,8 @@ CreateRimLightPipes(void)
}
{
-#ifdef RW_GLES2
-#include "gl2_shaders/simple_fs_gl2.inc"
-#include "gl2_shaders/neoRimSkin_gl2.inc"
-#else
-#include "shaders/simple_fs_gl3.inc"
-#include "shaders/neoRimSkin_gl3.inc"
-#endif
+#include "shaders/simple_fs_gl.inc"
+#include "shaders/neoRimSkin_gl.inc"
const char *vs[] = { shaderDecl, header_vert_src, neoRimSkin_vert_src, nil };
const char *fs[] = { shaderDecl, header_frag_src, simple_frag_src, nil };
neoRimSkinShader = Shader::create(vs, fs);
@@ -572,13 +555,8 @@ CreateRimLightPipes(void)
}
{
-#ifdef RW_GLES2
-#include "gl2_shaders/simple_fs_gl2.inc"
-#include "gl2_shaders/neoRim_gl2.inc"
-#else
-#include "shaders/simple_fs_gl3.inc"
-#include "shaders/neoRim_gl3.inc"
-#endif
+#include "shaders/simple_fs_gl.inc"
+#include "shaders/neoRim_gl.inc"
const char *vs[] = { shaderDecl, header_vert_src, neoRim_vert_src, nil };
const char *fs[] = { shaderDecl, header_frag_src, simple_frag_src, nil };
neoRimShader = Shader::create(vs, fs);
diff --git a/src/extras/debugmenu.cpp b/src/extras/debugmenu.cpp
index 3a4c4175..533b97f5 100644
--- a/src/extras/debugmenu.cpp
+++ b/src/extras/debugmenu.cpp
@@ -5,7 +5,7 @@
#include "ControllerConfig.h"
#include "Timer.h"
#include "rtcharse.h"
-#include "inttypes.h"
+#include "re3_inttypes.h"
#include "debugmenu.h"
#include <new>
diff --git a/src/extras/debugmenu.h b/src/extras/debugmenu.h
index eb56c8f9..c2198aca 100644
--- a/src/extras/debugmenu.h
+++ b/src/extras/debugmenu.h
@@ -15,7 +15,7 @@ struct MenuEntry
Menu *menu;
MenuEntry(const char *name);
- virtual ~MenuEntry(void) {}
+ virtual ~MenuEntry(void) { free((void*)name); }
};
typedef MenuEntry DebugMenuEntry;
diff --git a/src/extras/frontendoption.cpp b/src/extras/frontendoption.cpp
new file mode 100644
index 00000000..1f154250
--- /dev/null
+++ b/src/extras/frontendoption.cpp
@@ -0,0 +1,167 @@
+#include "common.h"
+
+#ifdef CUSTOM_FRONTEND_OPTIONS
+#include "Frontend.h"
+#include "Text.h"
+
+int lastOgScreen = MENUPAGES; // means no new pages
+
+int numCustomFrontendOptions = 0;
+int numCustomFrontendScreens = 0;
+
+int optionCursor = -2;
+int currentMenu;
+bool optionOverwrite = false;
+
+void GoBack()
+{
+ FrontEndMenuManager.SwitchToNewScreen(-1);
+}
+
+uint8
+GetNumberOfMenuOptions(int screen)
+{
+ uint8 Rows = 0;
+ for (int i = 0; i < NUM_MENUROWS; i++) {
+ if (aScreens[screen].m_aEntries[i].m_Action == MENUACTION_NOTHING)
+ break;
+
+ ++Rows;
+ }
+ return Rows;
+}
+
+uint8
+GetLastMenuScreen()
+{
+ int8 page = -1;
+ for (int i = 0; i < MENUPAGES; i++) {
+ if (strcmp(aScreens[i].m_ScreenName, "") == 0 && aScreens[i].m_PreviousPage == MENUPAGE_NONE)
+ break;
+
+ ++page;
+ }
+ return page;
+}
+
+int8 RegisterNewScreen(const char *name, int prevPage, ReturnPrevPageFunc returnPrevPageFunc)
+{
+ if (lastOgScreen == MENUPAGES)
+ lastOgScreen = GetLastMenuScreen();
+
+ numCustomFrontendScreens++;
+ 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 = prevPage;
+ aScreens[id].returnPrevPageFunc = returnPrevPageFunc;
+ return id;
+}
+
+int8 RegisterNewOption()
+{
+ numCustomFrontendOptions++;
+ uint8 numOptions = GetNumberOfMenuOptions(currentMenu);
+ uint8 curIdx;
+ if (optionCursor < 0) {
+ optionCursor = curIdx = numOptions + optionCursor + 1;
+ } else
+ curIdx = optionCursor;
+
+ if (!optionOverwrite) {
+ if (aScreens[currentMenu].m_aEntries[curIdx].m_Action != MENUACTION_NOTHING) {
+ for (int i = numOptions - 1; i >= curIdx; i--) {
+ memcpy(&aScreens[currentMenu].m_aEntries[i + 1], &aScreens[currentMenu].m_aEntries[i], sizeof(CMenuScreenCustom::CMenuEntry));
+ }
+ }
+ }
+ optionCursor++;
+ return curIdx;
+}
+
+void FrontendOptionSetCursor(int screen, int8 option, bool overwrite)
+{
+ currentMenu = screen;
+ optionCursor = option;
+ optionOverwrite = overwrite;
+}
+
+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];
+
+ // We can't use custom text on those :shrug:
+ switch (action) {
+ case MENUACTION_SCREENRES:
+ strcpy(option.m_EntryName, "FED_RES");
+ break;
+ case MENUACTION_AUDIOHW:
+ strcpy(option.m_EntryName, "FEA_3DH");
+ break;
+ default:
+ 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, 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*));
+ memcpy(option.m_CFOSelect->rightTexts, rightTexts, numRightTexts * sizeof(char*));
+ option.m_CFOSelect->numRightTexts = numRightTexts;
+ option.m_CFOSelect->value = var;
+ if (var) {
+ option.m_CFOSelect->displayedValue = *var;
+ option.m_CFOSelect->lastSavedValue = *var;
+ }
+ option.m_CFOSelect->save = saveName;
+ option.m_CFOSelect->onlyApplyOnEnter = onlyApplyOnEnter;
+ option.m_CFOSelect->changeFunc = changeFunc;
+}
+
+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;
+ option.m_CFODynamic->buttonPressFunc = buttonPressFunc;
+ option.m_CFODynamic->value = var;
+ option.m_CFODynamic->save = saveName;
+}
+
+// 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->lineHeight = lineHeight;
+ screen->showLeftRightHelper = showLeftRightHelper;
+
+ return screenOrder;
+}
+#endif
diff --git a/src/extras/frontendoption.h b/src/extras/frontendoption.h
new file mode 100644
index 00000000..6670c323
--- /dev/null
+++ b/src/extras/frontendoption.h
@@ -0,0 +1,86 @@
+#pragma once
+#include "common.h"
+
+#ifdef CUSTOM_FRONTEND_OPTIONS
+
+// ! There are 2 ways to use CFO,
+// 1st; by adding a new option to the array in MenuScreensCustom.cpp and passing attributes/CBs to it
+// 2nd; by calling the functions listed at the bottom of this file.
+
+// -- Option types
+//
+// Static/select: You allocate the variable, pass it to function and game sets it from user input among the strings given to function,
+// optionally you can add post-change event via ChangeFunc(only called on enter if onlyApplyOnEnter set, or set immediately)
+// You can store the option in an INI file if you pass the key(as a char array) to corresponding parameter.
+//
+// Dynamic: Passing variable to function is only needed if you want to store it, otherwise you should do
+// all the operations with ButtonPressFunc, this includes allocating the variable.
+// Left-side text is passed while creating and static, but ofc right-side text is dynamic -
+// you should return it in DrawFunc, which is called on every draw.
+//
+// Built-in action: As the name suggests, any action that game has built-in. But as an extra you can set the option text,
+
+// -- Returned via ButtonPressFunc() action param.
+#define FEOPTION_ACTION_LEFT 0
+#define FEOPTION_ACTION_RIGHT 1
+#define FEOPTION_ACTION_SELECT 2
+#define FEOPTION_ACTION_FOCUSLOSS 3
+
+// -- Callbacks
+
+// pretty much in everything I guess, and optional in all of them
+typedef void (*ReturnPrevPageFunc)();
+
+// for static options
+typedef void (*ChangeFunc)(int8 before, int8 after); // called after updating the value.
+ // only called on enter if onlyApplyOnEnter set, otherwise called on every value change
+
+// for dynamic options
+typedef wchar* (*DrawFunc)(bool* disabled, bool userHovering); // you must return a pointer for right text.
+ // you can also set *disabled if you want to gray it out.
+typedef void (*ButtonPressFunc)(int8 action); // see FEOPTION_ACTIONs above
+
+// -- Internal things
+void CustomFrontendOptionsPopulate();
+extern int lastOgScreen; // for reloading
+extern int numCustomFrontendOptions;
+extern int numCustomFrontendScreens;
+
+// -- To be used in ButtonPressFunc / ChangeFunc(this one would be weird):
+void GoBack(void);
+
+uint8 GetNumberOfMenuOptions(int screen);
+
+// !!! We're now moved to MenuScreensCustom.cpp, which houses an array that keeps all original+custom options.
+// But you can still use the APIs below, and manipulate aScreens while in game.
+
+// Limits:
+// The code relies on that you won't use more then NUM_MENUROWS(18) options on one page, and won't exceed the MENUPAGES of pages.
+// Also congrats if you can make 18 options visible at once.
+
+// Texts:
+// All text parameters accept char[8] GXT key.
+
+// Execute direction:
+// All of the calls below eventually manipulate the aScreens array, so keep in mind to add/replace options in order,
+// i.e. don't set cursor to 8 first and then 3.
+
+
+// -- Placing the cursor to append/overwrite option
+//
+// Done via FrontendOptionSetCursor(screen, position, overwrite = false), parameters explained below:
+// Screen: as the name suggests. Also accepts the screen IDs returned from FrontendScreenAdd.
+// Option: if positive, next AddOption call will put the option to there and progress the cursor.
+// if negative, cursor will be placed on bottom-(pos+1), so -1 means the very bottom, -2 means before the back button etc.
+// Overwrite: Use to overwrite the options, not appending a new one. AddOption calls will still progress the cursor.
+
+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, 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);
+
+// 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 7e9df4e7..2ea08141 100644
--- a/src/extras/postfx.cpp
+++ b/src/extras/postfx.cpp
@@ -152,13 +152,8 @@ CPostFX::Open(RwCamera *cam)
using namespace rw::gl3;
{
-#ifdef RW_GLES2
-#include "gl2_shaders/im2d_gl2.inc"
-#include "gl2_shaders/colourfilterVC_fs_gl2.inc"
-#else
-#include "shaders/im2d_gl3.inc"
-#include "shaders/colourfilterVC_fs_gl3.inc"
-#endif
+#include "shaders/im2d_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, colourfilterVC_frag_src, nil };
colourFilterVC = Shader::create(vs, fs);
@@ -166,17 +161,12 @@ CPostFX::Open(RwCamera *cam)
}
{
-#ifdef RW_GLES2
-#include "gl2_shaders/im2d_gl2.inc"
-#include "gl2_shaders/contrast_fs_gl2.inc"
-#else
-#include "shaders/im2d_gl3.inc"
-#include "shaders/contrast_fs_gl3.inc"
+#include "shaders/im2d_gl.inc"
+#include "shaders/contrast_fs_gl.inc"
const char *vs[] = { shaderDecl, header_vert_src, im2d_vert_src, nil };
const char *fs[] = { shaderDecl, header_frag_src, contrast_frag_src, nil };
contrast = Shader::create(vs, fs);
assert(contrast);
-#endif
}
#endif
@@ -386,6 +376,14 @@ CPostFX::NeedFrontBuffer(int32 type)
}
void
+CPostFX::GetBackBuffer(RwCamera *cam)
+{
+ RwRasterPushContext(pBackBuffer);
+ RwRasterRenderFast(RwCameraGetRaster(cam), 0, 0);
+ RwRasterPopContext();
+}
+
+void
CPostFX::Render(RwCamera *cam, uint32 red, uint32 green, uint32 blue, uint32 blur, int32 type, uint32 bluralpha)
{
if(pFrontBuffer == nil)
@@ -401,11 +399,8 @@ CPostFX::Render(RwCamera *cam, uint32 red, uint32 green, uint32 blue, uint32 blu
blur = AvgAlpha;
}
- if(NeedBackBuffer()){
- RwRasterPushContext(pBackBuffer);
- RwRasterRenderFast(RwCameraGetRaster(cam), 0, 0);
- RwRasterPopContext();
- }
+ if(NeedBackBuffer())
+ GetBackBuffer(cam);
DefinedState();
diff --git a/src/extras/postfx.h b/src/extras/postfx.h
index ace2e4a8..db702bf3 100644
--- a/src/extras/postfx.h
+++ b/src/extras/postfx.h
@@ -39,6 +39,7 @@ public:
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);
static bool UseBlurColours(void) { return EffectSwitch != POSTFX_SIMPLE; }
};
diff --git a/src/extras/inttypes.h b/src/extras/re3_inttypes.h
index bf0c53e2..bf0c53e2 100644
--- a/src/extras/inttypes.h
+++ b/src/extras/re3_inttypes.h
diff --git a/src/extras/screendroplets.cpp b/src/extras/screendroplets.cpp
new file mode 100644
index 00000000..6ea72f09
--- /dev/null
+++ b/src/extras/screendroplets.cpp
@@ -0,0 +1,817 @@
+#define WITH_D3D
+#include "common.h"
+
+#ifdef SCREEN_DROPLETS
+
+#ifndef LIBRW
+#error "Need librw for SCREEN_DROPLETS"
+#endif
+
+#include "General.h"
+#include "main.h"
+#include "RwHelper.h"
+#include "Timer.h"
+#include "Camera.h"
+#include "World.h"
+#include "ZoneCull.h"
+#include "Weather.h"
+#include "ParticleObject.h"
+ #include "Pad.h"
+#include "RenderBuffer.h"
+#include "custompipes.h"
+#include "postfx.h"
+#include "screendroplets.h"
+
+// for 640
+#define MAXSIZE 15
+#define MINSIZE 4
+
+int ScreenDroplets::ms_initialised;
+RwTexture *ScreenDroplets::ms_maskTex;
+RwTexture *ScreenDroplets::ms_screenTex;
+
+bool ScreenDroplets::ms_enabled = true;
+bool ScreenDroplets::ms_movingEnabled = true;
+
+ScreenDroplets::ScreenDrop ScreenDroplets::ms_drops[ScreenDroplets::MAXDROPS];
+int ScreenDroplets::ms_numDrops;
+ScreenDroplets::ScreenDropMoving ScreenDroplets::ms_dropsMoving[ScreenDroplets::MAXDROPSMOVING];
+int ScreenDroplets::ms_numDropsMoving;
+
+CVector ScreenDroplets::ms_prevCamUp;
+CVector ScreenDroplets::ms_prevCamPos;
+CVector ScreenDroplets::ms_camMoveDelta;
+float ScreenDroplets::ms_camMoveDist;
+CVector ScreenDroplets::ms_screenMoveDelta;
+float ScreenDroplets::ms_screenMoveDist;
+float ScreenDroplets::ms_camUpAngle;
+
+int ScreenDroplets::ms_splashDuration;
+CParticleObject *ScreenDroplets::ms_splashObject;
+
+struct Im2DVertexUV2 : rw::RWDEVICE::Im2DVertex
+{
+ rw::float32 u2, v2;
+};
+
+#ifdef RW_D3D9
+static void *screenDroplet_PS;
+#endif
+#ifdef RW_GL3
+static rw::gl3::Shader *screenDroplet;
+#endif
+
+// platform specific
+static void openim2d_uv2(void);
+static void closeim2d_uv2(void);
+static void RenderIndexedPrimitive_UV2(RwPrimitiveType primType, Im2DVertexUV2 *vertices, RwInt32 numVertices, RwImVertexIndex *indices, RwInt32 numIndices);
+
+static Im2DVertexUV2 VertexBuffer[TEMPBUFFERVERTSIZE];
+
+void
+ScreenDroplets::Initialise(void)
+{
+ Clear();
+ ms_splashDuration = -1;
+ ms_splashObject = nil;
+}
+
+// Create white circle mask for rain drops
+static RwTexture*
+CreateDropMask(int32 size)
+{
+ RwImage *img = RwImageCreate(size, size, 32);
+ RwImageAllocatePixels(img);
+
+ uint8 *pixels = RwImageGetPixels(img);
+ int32 stride = RwImageGetStride(img);
+
+ for(int y = 0; y < size; y++){
+ float yf = ((y + 0.5f)/size - 0.5f)*2.0f;
+ for(int x = 0; x < size; x++){
+ float xf = ((x + 0.5f)/size - 0.5f)*2.0f;
+ memset(&pixels[y*stride + x*4], xf*xf + yf*yf < 1.0f ? 0xFF : 0x00, 4);
+ }
+ }
+
+ int32 width, height, depth, format;
+ RwImageFindRasterFormat(img, rwRASTERTYPETEXTURE, &width, &height, &depth, &format);
+ RwRaster *ras = RwRasterCreate(width, height, depth, format);
+ RwRasterSetFromImage(ras, img);
+ RwImageDestroy(img);
+ return RwTextureCreate(ras);
+}
+
+void
+ScreenDroplets::InitDraw(void)
+{
+ ms_maskTex = CreateDropMask(64);
+
+ ms_screenTex = RwTextureCreate(nil);
+ RwTextureSetFilterMode(ms_screenTex, rwFILTERLINEAR);
+
+ openim2d_uv2();
+#ifdef RW_D3D9
+#include "shaders/screenDroplet_PS.inc"
+ screenDroplet_PS = rw::d3d::createPixelShader(screenDroplet_PS_cso);
+#endif
+#ifdef RW_GL3
+ using namespace rw::gl3;
+ {
+#include "shaders/im2d_UV2_gl.inc"
+#include "shaders/screenDroplet_fs_gl.inc"
+ const char *vs[] = { shaderDecl, header_vert_src, im2d_UV2_vert_src, nil };
+ const char *fs[] = { shaderDecl, header_frag_src, screenDroplet_frag_src, nil };
+ screenDroplet = Shader::create(vs, fs);
+ assert(screenDroplet);
+ }
+#endif
+
+ ms_initialised = 1;
+}
+
+void
+ScreenDroplets::Shutdown(void)
+{
+ if(ms_maskTex){
+ RwTextureDestroy(ms_maskTex);
+ ms_maskTex = nil;
+ }
+ if(ms_screenTex){
+ RwTextureSetRaster(ms_screenTex, nil);
+ RwTextureDestroy(ms_screenTex);
+ ms_screenTex = nil;
+ }
+#ifdef RW_D3D9
+ if(screenDroplet_PS){
+ rw::d3d::destroyPixelShader(screenDroplet_PS);
+ screenDroplet_PS = nil;
+ }
+#endif
+#ifdef RW_GL3
+ if(screenDroplet){
+ screenDroplet->destroy();
+ screenDroplet = nil;
+ }
+#endif
+
+ closeim2d_uv2();
+}
+
+void
+ScreenDroplets::Process(void)
+{
+ ProcessCameraMovement();
+ SprayDrops();
+ ProcessMoving();
+ Fade();
+}
+
+static void
+FlushBuffer(void)
+{
+ if(TempBufferIndicesStored){
+ RenderIndexedPrimitive_UV2(rwPRIMTYPETRILIST,
+ VertexBuffer, TempBufferVerticesStored,
+ TempBufferRenderIndexList, TempBufferIndicesStored);
+ TempBufferVerticesStored = 0;
+ TempBufferIndicesStored = 0;
+ }
+}
+
+static int
+StartStoring(int numIndices, int numVertices, RwImVertexIndex **indexStart, Im2DVertexUV2 **vertexStart)
+{
+ if(TempBufferIndicesStored + numIndices >= TEMPBUFFERINDEXSIZE ||
+ TempBufferVerticesStored + numVertices >= TEMPBUFFERVERTSIZE)
+ FlushBuffer();
+ *indexStart = &TempBufferRenderIndexList[TempBufferIndicesStored];
+ *vertexStart = &VertexBuffer[TempBufferVerticesStored];
+ int vertOffset = TempBufferVerticesStored;
+ TempBufferIndicesStored += numIndices;
+ TempBufferVerticesStored += numVertices;
+ return vertOffset;
+}
+
+void
+ScreenDroplets::Render(void)
+{
+ ScreenDrop *drop;
+
+ DefinedState();
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, RwTextureGetRaster(ms_maskTex));
+ RwRenderStateSet(rwRENDERSTATEFOGENABLE, FALSE);
+ RwRenderStateSet(rwRENDERSTATEZTESTENABLE, FALSE);
+ RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, FALSE);
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
+
+ RwTextureSetRaster(ms_screenTex, CPostFX::pBackBuffer);
+#ifdef RW_D3D9
+ rw::d3d::im2dOverridePS = screenDroplet_PS;
+ rw::d3d::setTexture(1, ms_screenTex);
+#endif
+#ifdef RW_GL3
+ rw::gl3::im2dOverrideShader = screenDroplet;
+ rw::gl3::setTexture(1, ms_screenTex);
+#endif
+
+ RenderBuffer::ClearRenderBuffer();
+ for(drop = &ms_drops[0]; drop < &ms_drops[MAXDROPS]; drop++)
+ if(drop->active)
+ AddToRenderList(drop);
+ FlushBuffer();
+
+#ifdef RW_D3D9
+ rw::d3d::im2dOverridePS = nil;
+ rw::d3d::setTexture(1, nil);
+#endif
+#ifdef RW_GL3
+ rw::gl3::im2dOverrideShader = nil;
+ rw::gl3::setTexture(1, nil);
+#endif
+
+ RwRenderStateSet(rwRENDERSTATEFOGENABLE, FALSE);
+ RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATEZWRITEENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, nil);
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, FALSE);
+}
+
+void
+ScreenDroplets::AddToRenderList(ScreenDroplets::ScreenDrop *drop)
+{
+ static float xy[] = {
+ -1.0f, -1.0f,
+ -1.0f, 1.0f,
+ 1.0f, 1.0f,
+ 1.0f, -1.0f
+ };
+ static float uv[] = {
+ 0.0f, 0.0f,
+ 0.0f, 1.0f,
+ 1.0f, 1.0f,
+ 1.0f, 0.0f
+ };
+
+ int i;
+ RwImVertexIndex *indices;
+ Im2DVertexUV2 *verts;
+ int first = StartStoring(6, 4, &indices, &verts);
+
+ float scale = 0.5f*SCREEN_SCALE_X(drop->size);
+
+ float screenz = RwIm2DGetNearScreenZ();
+ float z = RwCameraGetNearClipPlane(Scene.camera);
+ float recipz = 1.0f/z;
+
+ float magSize = SCREEN_SCALE_Y(drop->magnification*(300.0f-40.0f) + 40.0f);
+ float ul = drop->x - magSize;
+ float vt = drop->y - magSize;
+ float ur = drop->x + magSize;
+ float vb = drop->y + magSize;
+ ul = Max(ul, 0.0f)/RwRasterGetWidth(CPostFX::pBackBuffer);
+ vt = Max(vt, 0.0f)/RwRasterGetHeight(CPostFX::pBackBuffer);
+ ur = Min(ur, SCREEN_WIDTH)/RwRasterGetWidth(CPostFX::pBackBuffer);
+ vb = Min(vb, SCREEN_HEIGHT)/RwRasterGetHeight(CPostFX::pBackBuffer);
+
+ for(i = 0; i < 4; i++){
+ RwIm2DVertexSetScreenX(&verts[i], drop->x + xy[i*2]*scale);
+ RwIm2DVertexSetScreenY(&verts[i], drop->y + xy[i*2+1]*scale);
+ RwIm2DVertexSetScreenZ(&verts[i], screenz);
+ RwIm2DVertexSetCameraZ(&verts[i], z);
+ RwIm2DVertexSetRecipCameraZ(&verts[i], recipz);
+ RwIm2DVertexSetIntRGBA(&verts[i], drop->color.r, drop->color.g, drop->color.b, drop->color.a);
+ RwIm2DVertexSetU(&verts[i], uv[i*2], recipz);
+ RwIm2DVertexSetV(&verts[i], uv[i*2+1], recipz);
+
+ verts[i].u2 = i < 2 ? ul : ur;
+ verts[i].v2 = i % 3 ? vt : vb;
+ }
+ indices[0] = first + 0;
+ indices[1] = first + 1;
+ indices[2] = first + 2;
+ indices[3] = first + 2;
+ indices[4] = first + 3;
+ indices[5] = first + 0;
+}
+
+void
+ScreenDroplets::Clear(void)
+{
+ ScreenDrop *drop;
+ for(drop = &ms_drops[0]; drop < &ms_drops[MAXDROPS]; drop++)
+ drop->active = false;
+ ms_numDrops = 0;
+}
+
+ScreenDroplets::ScreenDrop*
+ScreenDroplets::NewDrop(float x, float y, float size, float lifetime, bool fades, int r, int g, int b)
+{
+ ScreenDrop *drop;
+ int i;
+
+ for(i = 0, drop = ms_drops; i < MAXDROPS; i++, drop++)
+ if(!ms_drops[i].active)
+ goto found;
+ return nil;
+found:
+ ms_numDrops++;
+ drop->x = x;
+ drop->y = y;
+ drop->size = size;
+ drop->magnification = (MAXSIZE - size + 1.0f) / (MAXSIZE - MINSIZE + 1.0f);
+ drop->fades = fades;
+ drop->active = true;
+ drop->color.r = r;
+ drop->color.g = g;
+ drop->color.b = b;
+ drop->color.a = 255;
+ drop->time = 0.0f;
+ drop->lifetime = lifetime;
+ return drop;
+}
+
+void
+ScreenDroplets::SetMoving(ScreenDroplets::ScreenDrop *drop)
+{
+ ScreenDropMoving *moving;
+ for(moving = ms_dropsMoving; moving < &ms_dropsMoving[MAXDROPSMOVING]; moving++)
+ if(moving->drop == nil)
+ goto found;
+ return;
+found:
+ ms_numDropsMoving++;
+ moving->drop = drop;
+ moving->dist = 0.0f;
+}
+
+void
+ScreenDroplets::FillScreen(int n)
+{
+ float x, y, size;
+ ScreenDrop *drop;
+
+ if(!ms_initialised)
+ return;
+ ms_numDrops = 0;
+ for(drop = &ms_drops[0]; drop < &ms_drops[MAXDROPS]; drop++){
+ drop->active = false;
+ if(drop < &ms_drops[n]){
+ x = CGeneral::GetRandomNumber() % (int)SCREEN_WIDTH;
+ y = CGeneral::GetRandomNumber() % (int)SCREEN_HEIGHT;
+ size = CGeneral::GetRandomNumberInRange(MINSIZE, MAXSIZE);
+ NewDrop(x, y, size, 2000.0f, true);
+ }
+ }
+}
+
+void
+ScreenDroplets::FillScreenMoving(float amount, bool isBlood)
+{
+ int n = (ms_screenMoveDelta.z > 5.0f ? 1.5f : 1.0f)*amount*20.0f;
+ float x, y, size;
+ ScreenDrop *drop;
+
+ while(n--)
+ if(ms_numDrops < MAXDROPS && ms_numDropsMoving < MAXDROPSMOVING){
+ x = CGeneral::GetRandomNumber() % (int)SCREEN_WIDTH;
+ y = CGeneral::GetRandomNumber() % (int)SCREEN_HEIGHT;
+ size = CGeneral::GetRandomNumberInRange(MINSIZE, MAXSIZE);
+ drop = nil;
+ if(isBlood)
+ drop = NewDrop(x, y, size, 2000.0f, true, 255, 0, 0);
+ else
+ drop = NewDrop(x, y, size, 2000.0f, true);
+ if(drop)
+ SetMoving(drop);
+ }
+}
+
+void
+ScreenDroplets::RegisterSplash(CParticleObject *pobj)
+{
+ CVector dist = pobj->GetPosition() - ms_prevCamPos;
+ if(dist.MagnitudeSqr() < 20.0f){
+ ms_splashDuration = 14;
+ ms_splashObject = pobj;
+ }
+}
+
+void
+ScreenDroplets::ProcessCameraMovement(void)
+{
+ RwMatrix *camMat = RwFrameGetMatrix(RwCameraGetFrame(Scene.camera));
+ CVector camPos = camMat->pos;
+ CVector camUp = camMat->at;
+ ms_camMoveDelta = camPos - ms_prevCamPos;
+ ms_camMoveDist = ms_camMoveDelta.Magnitude();
+
+ ms_prevCamUp = camUp;
+ ms_prevCamPos = camPos;
+
+ ms_screenMoveDelta.x = -RwV3dDotProduct(&camMat->right, &ms_camMoveDelta);
+ ms_screenMoveDelta.y = RwV3dDotProduct(&camMat->up, &ms_camMoveDelta);
+ ms_screenMoveDelta.z = RwV3dDotProduct(&camMat->at, &ms_camMoveDelta);
+ ms_screenMoveDelta *= 10.0f;
+ ms_screenMoveDist = ms_screenMoveDelta.Magnitude2D();
+
+ uint16 mode = TheCamera.Cams[TheCamera.ActiveCam].Mode;
+ bool isTopDown = mode == CCam::MODE_TOPDOWN || mode == CCam::MODE_GTACLASSIC || mode == CCam::MODE_TOP_DOWN_PED;
+ bool isLookingInDirection = FindPlayerVehicle() && mode == CCam::MODE_1STPERSON &&
+ (CPad::GetPad(0)->GetLookBehindForCar() || CPad::GetPad(0)->GetLookLeft() || CPad::GetPad(0)->GetLookRight());
+ ms_enabled = !isTopDown && !isLookingInDirection;
+ ms_movingEnabled = !isTopDown && !isLookingInDirection;
+
+ // 0 when looking stright up, 180 when looking up or down
+ ms_camUpAngle = RADTODEG(Acos(clamp(camUp.z, -1.0f, 1.0f)));
+}
+
+void
+ScreenDroplets::SprayDrops(void)
+{
+ bool noRain = CCullZones::PlayerNoRain() || CCullZones::CamNoRain();
+ if(!noRain && CWeather::Rain > 0.0f && ms_enabled){
+ // 180 when looking stright up, 0 when looking up or down
+ float angle = 180.0f - ms_camUpAngle;
+ angle = Max(angle, 40.0f); // want at least some rain
+ FillScreenMoving((angle - 40.0f) / 150.0f * CWeather::Rain * 0.5f);
+ }
+
+ int i;
+ for(i = 0; i < MAX_AUDIOHYDRANTS; i++){
+ CAudioHydrant *hyd = CAudioHydrant::Get(i);
+ if (hyd->pParticleObject){
+ CVector dist = hyd->pParticleObject->GetPosition() - ms_prevCamPos;
+ if(dist.MagnitudeSqr() > 40.0f ||
+ DotProduct(dist, ms_prevCamUp) < 0.0f) continue;
+
+ FillScreenMoving(1.0f);
+ }
+ }
+
+ static int ndrops[] = {
+ 125, 250, 500, 1000, 1000,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+ };
+ if(ms_splashDuration >= 0){
+ if(ms_numDrops < MAXDROPS) {
+ float numDropMult = 1.0f;
+ if(ms_splashObject){
+ float dist = (ms_splashObject->GetPosition() - ms_prevCamPos).Magnitude();
+ numDropMult = 1.0f - (dist - 5.0f)/15.0f;
+ if(numDropMult < 0) numDropMult = 0.0f; // fix
+ }
+ int n = ndrops[ms_splashDuration] * numDropMult;
+ while(n--)
+ if(ms_numDrops < MAXDROPS){
+ float x = CGeneral::GetRandomNumber() % (int)SCREEN_WIDTH;
+ float y = CGeneral::GetRandomNumber() % (int)SCREEN_HEIGHT;
+ float size = CGeneral::GetRandomNumberInRange(MINSIZE, MAXSIZE);
+ NewDrop(x, y, size, 10000.0f, false);
+ }
+ }
+ ms_splashDuration--;
+ }
+}
+
+void
+ScreenDroplets::NewTrace(ScreenDroplets::ScreenDropMoving *moving)
+{
+ if(ms_numDrops < MAXDROPS){
+ moving->dist = 0.0f;
+ NewDrop(moving->drop->x, moving->drop->y, MINSIZE, 500.0f, true,
+ moving->drop->color.r, moving->drop->color.g, moving->drop->color.b);
+ }
+}
+
+void
+ScreenDroplets::MoveDrop(ScreenDroplets::ScreenDropMoving *moving)
+{
+ ScreenDrop *drop = moving->drop;
+ if(!ms_movingEnabled)
+ return;
+ if(!drop->active){
+ moving->drop = nil;
+ ms_numDropsMoving--;
+ return;
+ }
+ if(ms_screenMoveDelta.z > 0.0f && ms_camMoveDist > 0.3f){
+ if(ms_screenMoveDist > 0.5f && TheCamera.Cams[TheCamera.ActiveCam].Mode != CCam::MODE_1STPERSON){
+ // movement when camera turns
+ moving->dist += ms_screenMoveDist;
+ if(moving->dist > 20.0f && drop->color.a > 100)
+ NewTrace(moving);
+
+ drop->x -= ms_screenMoveDelta.x;
+ drop->y += ms_screenMoveDelta.y;
+ }else{
+ // movement out of center
+ float d = ms_screenMoveDelta.z*0.2f;
+ float dx, dy, sum;
+ dx = drop->x - SCREEN_WIDTH*0.5f + ms_screenMoveDelta.x;
+ if(TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_1STPERSON)
+ dy = drop->y - SCREEN_HEIGHT*1.2f - ms_screenMoveDelta.y;
+ else
+ dy = drop->y - SCREEN_HEIGHT*0.5f - ms_screenMoveDelta.y;
+ sum = fabs(dx) + fabs(dy);
+ if(sum > 0.001f){
+ dx /= sum;
+ dy /= sum;
+ }
+ moving->dist += d;
+ if(moving->dist > 20.0f && drop->color.a > 100)
+ NewTrace(moving);
+ drop->x += dx * d;
+ drop->y += dy * d;
+ }
+
+ if(drop->x < 0.0f || drop->y < 0.0f ||
+ drop->x > SCREEN_WIDTH || drop->y > SCREEN_HEIGHT){
+ moving->drop = nil;
+ ms_numDropsMoving--;
+ }
+ }
+}
+
+void
+ScreenDroplets::ProcessMoving(void)
+{
+ ScreenDropMoving *moving;
+ if(!ms_movingEnabled)
+ return;
+ for(moving = ms_dropsMoving; moving < &ms_dropsMoving[MAXDROPSMOVING]; moving++)
+ if(moving->drop)
+ MoveDrop(moving);
+}
+
+void
+ScreenDroplets::Fade(void)
+{
+ ScreenDrop *drop;
+ for(drop = &ms_drops[0]; drop < &ms_drops[MAXDROPS]; drop++)
+ if(drop->active)
+ drop->Fade();
+}
+
+void
+ScreenDroplets::ScreenDrop::Fade(void)
+{
+ int delta = CTimer::GetTimeStepInMilliseconds();
+ time += delta;
+ if(time < lifetime){
+ color.a = 255 - time/lifetime*255;
+ }else if(fades){
+ ScreenDroplets::ms_numDrops--;
+ active = false;
+ }
+}
+
+
+/*
+ * Im2D with two uv coors
+ */
+
+#ifdef RW_D3D9
+// stolen from RW, not in a public header
+namespace rw {
+namespace d3d {
+void addDynamicVB(uint32 length, uint32 fvf, IDirect3DVertexBuffer9 **buf); // NB: don't share this pointer
+void removeDynamicVB(IDirect3DVertexBuffer9 **buf);
+void addDynamicIB(uint32 length, IDirect3DIndexBuffer9 **buf); // NB: don't share this pointer
+void removeDynamicIB(IDirect3DIndexBuffer9 **buf);
+}
+}
+// different than im2d
+#define NUMINDICES 1024
+#define NUMVERTICES 1024
+
+static int primTypeMap[] = {
+ D3DPT_POINTLIST, // invalid
+ D3DPT_LINELIST,
+ D3DPT_LINESTRIP,
+ D3DPT_TRIANGLELIST,
+ D3DPT_TRIANGLESTRIP,
+ D3DPT_TRIANGLEFAN,
+ D3DPT_POINTLIST, // actually not supported!
+};
+// end of stolen stuff
+
+
+static IDirect3DVertexDeclaration9 *im2ddecl_uv2;
+static IDirect3DVertexBuffer9 *im2dvertbuf_uv2;
+static IDirect3DIndexBuffer9 *im2dindbuf_uv2;
+
+void
+openim2d_uv2(void)
+{
+ using namespace rw;
+ using namespace d3d;
+ D3DVERTEXELEMENT9 elements[5] = {
+ { 0, 0, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITIONT, 0 },
+ { 0, offsetof(Im2DVertexUV2, color), D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 0 },
+ { 0, offsetof(Im2DVertexUV2, u), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0 },
+ { 0, offsetof(Im2DVertexUV2, u2), D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1 },
+ D3DDECL_END()
+ };
+ assert(im2ddecl_uv2 == nil);
+ im2ddecl_uv2 = (IDirect3DVertexDeclaration9*)d3d9::createVertexDeclaration((d3d9::VertexElement*)elements);
+ assert(im2ddecl_uv2);
+
+ assert(im2dvertbuf_uv2 == nil);
+ im2dvertbuf_uv2 = (IDirect3DVertexBuffer9*)createVertexBuffer(NUMVERTICES*sizeof(Im2DVertexUV2), 0, true);
+ assert(im2dvertbuf_uv2);
+ addDynamicVB(NUMVERTICES*sizeof(Im2DVertexUV2), 0, &im2dvertbuf_uv2);
+
+ assert(im2dindbuf_uv2 == nil);
+ im2dindbuf_uv2 = (IDirect3DIndexBuffer9*)createIndexBuffer(NUMINDICES*sizeof(rw::uint16), true);
+ assert(im2dindbuf_uv2);
+ addDynamicIB(NUMINDICES*sizeof(rw::uint16), &im2dindbuf_uv2);
+}
+
+void
+closeim2d_uv2(void)
+{
+ using namespace rw;
+ using namespace d3d;
+
+ d3d9::destroyVertexDeclaration(im2ddecl_uv2);
+ im2ddecl_uv2 = nil;
+
+ removeDynamicVB(&im2dvertbuf_uv2);
+ destroyVertexBuffer(im2dvertbuf_uv2);
+ im2dvertbuf_uv2 = nil;
+
+ removeDynamicIB(&im2dindbuf_uv2);
+ destroyIndexBuffer(im2dindbuf_uv2);
+ im2dindbuf_uv2 = nil;
+}
+
+void
+RenderIndexedPrimitive_UV2(RwPrimitiveType primType, Im2DVertexUV2 *vertices, RwInt32 numVertices, RwImVertexIndex *indices, RwInt32 numIndices)
+{
+ using namespace rw;
+ using namespace d3d;
+
+ if(numVertices > NUMVERTICES ||
+ numIndices > NUMINDICES){
+ // TODO: error
+ return;
+ }
+ rw::uint16 *lockedindices = lockIndices(im2dindbuf_uv2, 0, numIndices*sizeof(rw::uint16), D3DLOCK_DISCARD);
+ memcpy(lockedindices, indices, numIndices*sizeof(rw::uint16));
+ unlockIndices(im2dindbuf_uv2);
+
+ rw::uint8 *lockedvertices = lockVertices(im2dvertbuf_uv2, 0, numVertices*sizeof(Im2DVertexUV2), D3DLOCK_DISCARD);
+ memcpy(lockedvertices, vertices, numVertices*sizeof(Im2DVertexUV2));
+ unlockVertices(im2dvertbuf_uv2);
+
+ setStreamSource(0, im2dvertbuf_uv2, 0, sizeof(Im2DVertexUV2));
+ setIndices(im2dindbuf_uv2);
+ setVertexDeclaration(im2ddecl_uv2);
+
+ if(im2dOverridePS)
+ setPixelShader(im2dOverridePS);
+ else if(engine->device.getRenderState(TEXTURERASTER))
+ setPixelShader(im2d_tex_PS);
+ else
+ setPixelShader(im2d_PS);
+
+ d3d::flushCache();
+
+ rw::uint32 primCount = 0;
+ switch(primType){
+ case PRIMTYPELINELIST:
+ primCount = numIndices/2;
+ break;
+ case PRIMTYPEPOLYLINE:
+ primCount = numIndices-1;
+ break;
+ case PRIMTYPETRILIST:
+ primCount = numIndices/3;
+ break;
+ case PRIMTYPETRISTRIP:
+ primCount = numIndices-2;
+ break;
+ case PRIMTYPETRIFAN:
+ primCount = numIndices-2;
+ break;
+ case PRIMTYPEPOINTLIST:
+ primCount = numIndices;
+ break;
+ }
+ d3ddevice->DrawIndexedPrimitive((D3DPRIMITIVETYPE)primTypeMap[primType], 0,
+ 0, numVertices,
+ 0, primCount);
+}
+#endif
+
+#ifdef RW_GL3
+// different than im2d
+#define NUMINDICES 1024
+#define NUMVERTICES 1024
+
+static rw::gl3::AttribDesc im2d_UV2_attribDesc[4] = {
+ { rw::gl3::ATTRIB_POS, GL_FLOAT, GL_FALSE, 4,
+ sizeof(Im2DVertexUV2), 0 },
+ { rw::gl3::ATTRIB_COLOR, GL_UNSIGNED_BYTE, GL_TRUE, 4,
+ sizeof(Im2DVertexUV2), offsetof(Im2DVertexUV2, r) },
+ { rw::gl3::ATTRIB_TEXCOORDS0, GL_FLOAT, GL_FALSE, 2,
+ sizeof(Im2DVertexUV2), offsetof(Im2DVertexUV2, u) },
+ { rw::gl3::ATTRIB_TEXCOORDS1, GL_FLOAT, GL_FALSE, 2,
+ sizeof(Im2DVertexUV2), offsetof(Im2DVertexUV2, u2) }
+};
+
+static int primTypeMap[] = {
+ GL_POINTS, // invalid
+ GL_LINES,
+ GL_LINE_STRIP,
+ GL_TRIANGLES,
+ GL_TRIANGLE_STRIP,
+ GL_TRIANGLE_FAN,
+ GL_POINTS
+};
+
+static int32 u_xform;
+
+uint32 im2D_UV2_Vbo, im2D_UV2_Ibo;
+#ifdef RW_GL_USE_VAOS
+uint32 im2D_UV2_Vao;
+#endif
+
+void
+openim2d_uv2(void)
+{
+ u_xform = rw::gl3::registerUniform("u_xform"); // this doesn't add a new one, so it's safe
+
+ glGenBuffers(1, &im2D_UV2_Ibo);
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, im2D_UV2_Ibo);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, NUMINDICES*2, nil, GL_STREAM_DRAW);
+
+ glGenBuffers(1, &im2D_UV2_Vbo);
+ glBindBuffer(GL_ARRAY_BUFFER, im2D_UV2_Vbo);
+ glBufferData(GL_ARRAY_BUFFER, NUMVERTICES*sizeof(Im2DVertexUV2), nil, GL_STREAM_DRAW);
+
+#ifdef RW_GL_USE_VAOS
+ glGenVertexArrays(1, &im2D_UV2_Vao);
+ glBindVertexArray(im2D_UV2_Vao);
+ setAttribPointers(im2d_UV2_attribDesc, 4);
+#endif
+}
+
+void
+closeim2d_uv2(void)
+{
+ glDeleteBuffers(1, &im2D_UV2_Ibo);
+ glDeleteBuffers(1, &im2D_UV2_Vbo);
+#ifdef RW_GL_USE_VAOS
+ glDeleteVertexArrays(1, &im2D_UV2_Vao);
+#endif
+}
+
+void
+RenderIndexedPrimitive_UV2(RwPrimitiveType primType, Im2DVertexUV2 *vertices, RwInt32 numVertices, RwImVertexIndex *indices, RwInt32 numIndices)
+{
+ using namespace rw;
+ using namespace gl3;
+
+ GLfloat xform[4];
+ Camera *cam;
+ cam = (Camera*)engine->currentCamera;
+
+#ifdef RW_GL_USE_VAOS
+ glBindVertexArray(im2D_UV2_Vao);
+#endif
+
+ glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, im2D_UV2_Ibo);
+ glBufferData(GL_ELEMENT_ARRAY_BUFFER, NUMINDICES*2, nil, GL_STREAM_DRAW);
+ glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, numIndices*2, indices);
+
+ glBindBuffer(GL_ARRAY_BUFFER, im2D_UV2_Vbo);
+ glBufferData(GL_ARRAY_BUFFER, NUMVERTICES*sizeof(Im2DVertexUV2), nil, GL_STREAM_DRAW);
+ glBufferSubData(GL_ARRAY_BUFFER, 0, numVertices*sizeof(Im2DVertexUV2), vertices);
+
+ xform[0] = 2.0f/cam->frameBuffer->width;
+ xform[1] = -2.0f/cam->frameBuffer->height;
+ xform[2] = -1.0f;
+ xform[3] = 1.0f;
+
+ if(im2dOverrideShader)
+ im2dOverrideShader->use();
+ else
+ assert(0);//im2dShader->use();
+#ifndef RW_GL_USE_VAOS
+ setAttribPointers(im2d_UV2_attribDesc, 4);
+#endif
+
+ glUniform4fv(currentShader->uniformLocations[u_xform], 1, xform);
+
+ flushCache();
+ glDrawElements(primTypeMap[primType], numIndices,
+ GL_UNSIGNED_SHORT, nil);
+#ifndef RW_GL_USE_VAOS
+ disableAttribPointers(im2d_UV2_attribDesc, 4);
+#endif
+}
+#endif
+
+#endif
diff --git a/src/extras/screendroplets.h b/src/extras/screendroplets.h
new file mode 100644
index 00000000..090b1923
--- /dev/null
+++ b/src/extras/screendroplets.h
@@ -0,0 +1,78 @@
+#pragma once
+
+#ifdef SCREEN_DROPLETS
+
+class CParticleObject;
+
+class ScreenDroplets
+{
+public:
+ enum {
+ MAXDROPS = 2000,
+ MAXDROPSMOVING = 700
+ };
+
+ class ScreenDrop
+ {
+ public:
+ float x, y, time; // shorts on xbox (short float?)
+ float size, magnification, lifetime; // "
+ CRGBA color;
+ bool active;
+ bool fades;
+
+ void Fade(void);
+ };
+
+ struct ScreenDropMoving
+ {
+ ScreenDrop *drop;
+ float dist;
+ };
+
+ static int ms_initialised;
+ static RwTexture *ms_maskTex;
+ static RwTexture *ms_screenTex;
+
+ static bool ms_enabled;
+ static bool ms_movingEnabled;
+
+ static ScreenDrop ms_drops[MAXDROPS];
+ static int ms_numDrops;
+ static ScreenDropMoving ms_dropsMoving[MAXDROPSMOVING];
+ static int ms_numDropsMoving;
+
+ static CVector ms_prevCamUp;
+ static CVector ms_prevCamPos;
+ static CVector ms_camMoveDelta;
+ static float ms_camMoveDist;
+ static CVector ms_screenMoveDelta;
+ static float ms_screenMoveDist;
+ static float ms_camUpAngle;
+
+ static int ms_splashDuration;
+ static CParticleObject *ms_splashObject;
+
+ static void Initialise(void);
+ static void InitDraw(void);
+ static void Shutdown(void);
+ static void Process(void);
+ static void Render(void);
+ static void AddToRenderList(ScreenDrop *drop);
+
+ static void Clear(void);
+ static ScreenDrop *NewDrop(float x, float y, float size, float lifetime, bool fades, int r = 255, int g = 255, int b = 255);
+ static void SetMoving(ScreenDroplets::ScreenDrop *drop);
+ static void FillScreen(int n);
+ static void FillScreenMoving(float amount, bool isBlood = false);
+ static void RegisterSplash(CParticleObject *pobj);
+
+ static void ProcessCameraMovement(void);
+ static void SprayDrops(void);
+ static void NewTrace(ScreenDroplets::ScreenDropMoving *moving);
+ static void MoveDrop(ScreenDropMoving *moving);
+ static void ProcessMoving(void);
+ static void Fade(void);
+};
+
+#endif
diff --git a/src/extras/shaders/Makefile b/src/extras/shaders/Makefile
index 605190c9..5089e16a 100644
--- a/src/extras/shaders/Makefile
+++ b/src/extras/shaders/Makefile
@@ -1,67 +1,78 @@
-all: im2d_gl3.inc simple_fs_gl3.inc default_UV2_gl3.inc \
- colourfilterVC_fs_gl3.inc contrast_fs_gl3.inc \
- neoRim_gl3.inc neoRimSkin_gl3.inc \
- neoWorldVC_fs_gl3.inc neoGloss_vs_gl3.inc neoGloss_fs_gl3.inc \
- neoVehicle_vs_gl3.inc neoVehicle_fs_gl3.inc
+all: im2d_gl.inc simple_fs_gl.inc default_UV2_gl.inc \
+ colourfilterVC_fs_gl.inc contrast_fs_gl.inc \
+ neoRim_gl.inc neoRimSkin_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
-im2d_gl3.inc: im2d.vert
+im2d_gl.inc: im2d.vert
(echo 'const char *im2d_vert_src =';\
sed 's/..*/"&\\n"/' im2d.vert;\
- echo ';') >im2d_gl3.inc
+ echo ';') >im2d_gl.inc
-colourfilterVC_fs_gl3.inc: colourfilterVC.frag
+colourfilterVC_fs_gl.inc: colourfilterVC.frag
(echo 'const char *colourfilterVC_frag_src =';\
sed 's/..*/"&\\n"/' colourfilterVC.frag;\
- echo ';') >colourfilterVC_fs_gl3.inc
-simple_fs_gl3.inc: simple.frag
+ echo ';') >colourfilterVC_fs_gl.inc
+simple_fs_gl.inc: simple.frag
(echo 'const char *simple_frag_src =';\
sed 's/..*/"&\\n"/' simple.frag;\
- echo ';') >simple_fs_gl3.inc
+ echo ';') >simple_fs_gl.inc
-default_UV2_gl3.inc: default_UV2.vert
+default_UV2_gl.inc: default_UV2.vert
(echo 'const char *default_UV2_vert_src =';\
sed 's/..*/"&\\n"/' default_UV2.vert;\
- echo ';') >default_UV2_gl3.inc
+ echo ';') >default_UV2_gl.inc
-contrast_fs_gl3.inc: contrast.frag
+contrast_fs_gl.inc: contrast.frag
(echo 'const char *contrast_frag_src =';\
sed 's/..*/"&\\n"/' contrast.frag;\
- echo ';') >contrast_fs_gl3.inc
+ echo ';') >contrast_fs_gl.inc
-neoRim_gl3.inc: neoRim.vert
+neoRim_gl.inc: neoRim.vert
(echo 'const char *neoRim_vert_src =';\
sed 's/..*/"&\\n"/' neoRim.vert;\
- echo ';') >neoRim_gl3.inc
+ echo ';') >neoRim_gl.inc
-neoRimSkin_gl3.inc: neoRimSkin.vert
+neoRimSkin_gl.inc: neoRimSkin.vert
(echo 'const char *neoRimSkin_vert_src =';\
sed 's/..*/"&\\n"/' neoRimSkin.vert;\
- echo ';') >neoRimSkin_gl3.inc
+ echo ';') >neoRimSkin_gl.inc
-neoWorldVC_fs_gl3.inc: neoWorldVC.frag
+neoWorldVC_fs_gl.inc: neoWorldVC.frag
(echo 'const char *neoWorldVC_frag_src =';\
sed 's/..*/"&\\n"/' neoWorldVC.frag;\
- echo ';') >neoWorldVC_fs_gl3.inc
+ echo ';') >neoWorldVC_fs_gl.inc
-neoGloss_fs_gl3.inc: neoGloss.frag
+neoGloss_fs_gl.inc: neoGloss.frag
(echo 'const char *neoGloss_frag_src =';\
sed 's/..*/"&\\n"/' neoGloss.frag;\
- echo ';') >neoGloss_fs_gl3.inc
+ echo ';') >neoGloss_fs_gl.inc
-neoGloss_vs_gl3.inc: neoGloss.vert
+neoGloss_vs_gl.inc: neoGloss.vert
(echo 'const char *neoGloss_vert_src =';\
sed 's/..*/"&\\n"/' neoGloss.vert;\
- echo ';') >neoGloss_vs_gl3.inc
+ echo ';') >neoGloss_vs_gl.inc
-neoVehicle_vs_gl3.inc: neoVehicle.vert
+neoVehicle_vs_gl.inc: neoVehicle.vert
(echo 'const char *neoVehicle_vert_src =';\
sed 's/..*/"&\\n"/' neoVehicle.vert;\
- echo ';') >neoVehicle_vs_gl3.inc
+ echo ';') >neoVehicle_vs_gl.inc
-neoVehicle_fs_gl3.inc: neoVehicle.frag
+neoVehicle_fs_gl.inc: neoVehicle.frag
(echo 'const char *neoVehicle_frag_src =';\
sed 's/..*/"&\\n"/' neoVehicle.frag;\
- echo ';') >neoVehicle_fs_gl3.inc
+ echo ';') >neoVehicle_fs_gl.inc
+
+im2d_UV2_gl.inc: im2d_UV2.vert
+ (echo 'const char *im2d_UV2_vert_src =';\
+ sed 's/..*/"&\\n"/' im2d_UV2.vert;\
+ echo ';') >im2d_UV2_gl.inc
+
+screenDroplet_fs_gl.inc: screenDroplet.frag
+ (echo 'const char *screenDroplet_frag_src =';\
+ sed 's/..*/"&\\n"/' screenDroplet.frag;\
+ echo ';') >screenDroplet_fs_gl.inc
diff --git a/src/extras/shaders/colourfilterVC.frag b/src/extras/shaders/colourfilterVC.frag
index 5069af52..9db3950e 100644
--- a/src/extras/shaders/colourfilterVC.frag
+++ b/src/extras/shaders/colourfilterVC.frag
@@ -1,17 +1,15 @@
uniform sampler2D tex0;
uniform vec4 u_blurcolor;
-in vec4 v_color;
-in vec2 v_tex0;
-in float v_fog;
-
-out vec4 color;
+FSIN vec4 v_color;
+FSIN vec2 v_tex0;
+FSIN float v_fog;
void
main(void)
{
float a = u_blurcolor.a;
- vec4 doublec = clamp(u_blurcolor*2, 0.0, 1.0);
+ 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++){
@@ -20,7 +18,10 @@ main(void)
tmp += prev*u_blurcolor;
prev = clamp(tmp, 0.0, 1.0);
}
+ vec4 color;
color.rgb = prev.rgb;
color.a = 1.0f;
+
+ FRAGCOLOR(color);
}
diff --git a/src/extras/shaders/colourfilterVC_fs_gl3.inc b/src/extras/shaders/colourfilterVC_fs_gl.inc
index d11cdc5a..1f9bf6d8 100644
--- a/src/extras/shaders/colourfilterVC_fs_gl3.inc
+++ b/src/extras/shaders/colourfilterVC_fs_gl.inc
@@ -2,17 +2,15 @@ const char *colourfilterVC_frag_src =
"uniform sampler2D tex0;\n"
"uniform vec4 u_blurcolor;\n"
-"in vec4 v_color;\n"
-"in vec2 v_tex0;\n"
-"in float v_fog;\n"
-
-"out vec4 color;\n"
+"FSIN vec4 v_color;\n"
+"FSIN vec2 v_tex0;\n"
+"FSIN float v_fog;\n"
"void\n"
"main(void)\n"
"{\n"
" float a = u_blurcolor.a;\n"
-" vec4 doublec = clamp(u_blurcolor*2, 0.0, 1.0);\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"
@@ -21,8 +19,11 @@ const char *colourfilterVC_frag_src =
" tmp += prev*u_blurcolor;\n"
" prev = clamp(tmp, 0.0, 1.0);\n"
" }\n"
+" vec4 color;\n"
" color.rgb = prev.rgb;\n"
" color.a = 1.0f;\n"
+
+" FRAGCOLOR(color);\n"
"}\n"
;
diff --git a/src/extras/shaders/contrast.frag b/src/extras/shaders/contrast.frag
index d6dec478..1b93f6fe 100644
--- a/src/extras/shaders/contrast.frag
+++ b/src/extras/shaders/contrast.frag
@@ -2,17 +2,18 @@ uniform sampler2D tex0;
uniform vec3 u_contrastAdd;
uniform vec3 u_contrastMult;
-in vec4 v_color;
-in vec2 v_tex0;
-in float v_fog;
-
-out vec4 color;
+FSIN vec4 v_color;
+FSIN vec2 v_tex0;
+FSIN float v_fog;
void
main(void)
{
vec4 dst = texture(tex0, vec2(v_tex0.x, 1.0-v_tex0.y));
+ vec4 color;
color.rgb = dst.rgb*u_contrastMult + u_contrastAdd;
color.a = 1.0f;
+
+ FRAGCOLOR(color);
}
diff --git a/src/extras/shaders/contrast_fs_gl3.inc b/src/extras/shaders/contrast_fs_gl.inc
index 58aaf079..97f78194 100644
--- a/src/extras/shaders/contrast_fs_gl3.inc
+++ b/src/extras/shaders/contrast_fs_gl.inc
@@ -3,18 +3,19 @@ const char *contrast_frag_src =
"uniform vec3 u_contrastAdd;\n"
"uniform vec3 u_contrastMult;\n"
-"in vec4 v_color;\n"
-"in vec2 v_tex0;\n"
-"in float v_fog;\n"
-
-"out vec4 color;\n"
+"FSIN vec4 v_color;\n"
+"FSIN vec2 v_tex0;\n"
+"FSIN float v_fog;\n"
"void\n"
"main(void)\n"
"{\n"
" vec4 dst = texture(tex0, vec2(v_tex0.x, 1.0-v_tex0.y));\n"
+" vec4 color;\n"
" color.rgb = dst.rgb*u_contrastMult + u_contrastAdd;\n"
" color.a = 1.0f;\n"
+
+" FRAGCOLOR(color);\n"
"}\n"
;
diff --git a/src/extras/shaders/default_UV2.vert b/src/extras/shaders/default_UV2.vert
index 3dbad20f..694c012b 100644
--- a/src/extras/shaders/default_UV2.vert
+++ b/src/extras/shaders/default_UV2.vert
@@ -1,13 +1,9 @@
-layout(location = 0) in vec3 in_pos;
-layout(location = 1) in vec3 in_normal;
-layout(location = 2) in vec4 in_color;
-layout(location = 3) in vec2 in_tex0;
-layout(location = 4) in vec2 in_tex1;
+VSIN(ATTRIB_POS) vec3 in_pos;
-out vec4 v_color;
-out vec2 v_tex0;
-out vec2 v_tex1;
-out float v_fog;
+VSOUT vec4 v_color;
+VSOUT vec2 v_tex0;
+VSOUT vec2 v_tex1;
+VSOUT float v_fog;
void
main(void)
diff --git a/src/extras/shaders/default_UV2_gl3.inc b/src/extras/shaders/default_UV2_gl.inc
index 14106b29..450f3d9a 100644
--- a/src/extras/shaders/default_UV2_gl3.inc
+++ b/src/extras/shaders/default_UV2_gl.inc
@@ -1,14 +1,10 @@
const char *default_UV2_vert_src =
-"layout(location = 0) in vec3 in_pos;\n"
-"layout(location = 1) in vec3 in_normal;\n"
-"layout(location = 2) in vec4 in_color;\n"
-"layout(location = 3) in vec2 in_tex0;\n"
-"layout(location = 4) in vec2 in_tex1;\n"
+"VSIN(ATTRIB_POS) vec3 in_pos;\n"
-"out vec4 v_color;\n"
-"out vec2 v_tex0;\n"
-"out vec2 v_tex1;\n"
-"out float v_fog;\n"
+"VSOUT vec4 v_color;\n"
+"VSOUT vec2 v_tex0;\n"
+"VSOUT vec2 v_tex1;\n"
+"VSOUT float v_fog;\n"
"void\n"
"main(void)\n"
diff --git a/src/extras/shaders/im2d.vert b/src/extras/shaders/im2d.vert
index 241593b1..fcd81c2c 100644
--- a/src/extras/shaders/im2d.vert
+++ b/src/extras/shaders/im2d.vert
@@ -1,12 +1,10 @@
uniform vec4 u_xform;
-layout(location = 0) in vec4 in_pos;
-layout(location = 2) in vec4 in_color;
-layout(location = 3) in vec2 in_tex0;
+VSIN(ATTRIB_POS) vec4 in_pos;
-out vec4 v_color;
-out vec2 v_tex0;
-out float v_fog;
+VSOUT vec4 v_color;
+VSOUT vec2 v_tex0;
+VSOUT float v_fog;
void
main(void)
diff --git a/src/extras/shaders/im2d_UV2.vert b/src/extras/shaders/im2d_UV2.vert
new file mode 100644
index 00000000..e5fd4d08
--- /dev/null
+++ b/src/extras/shaders/im2d_UV2.vert
@@ -0,0 +1,21 @@
+uniform vec4 u_xform;
+
+VSIN(ATTRIB_POS) vec4 in_pos;
+
+VSOUT vec4 v_color;
+VSOUT vec2 v_tex0;
+VSOUT vec2 v_tex1;
+VSOUT float v_fog;
+
+void
+main(void)
+{
+ gl_Position = in_pos;
+ gl_Position.w = 1.0;
+ gl_Position.xy = gl_Position.xy * u_xform.xy + u_xform.zw;
+ v_fog = DoFog(gl_Position.z);
+ gl_Position.xyz *= gl_Position.w;
+ v_color = in_color;
+ v_tex0 = in_tex0;
+ v_tex1 = in_tex1;
+}
diff --git a/src/extras/shaders/im2d_UV2_gl.inc b/src/extras/shaders/im2d_UV2_gl.inc
new file mode 100644
index 00000000..3feb2bc1
--- /dev/null
+++ b/src/extras/shaders/im2d_UV2_gl.inc
@@ -0,0 +1,23 @@
+const char *im2d_UV2_vert_src =
+"uniform vec4 u_xform;\n"
+
+"VSIN(ATTRIB_POS) vec4 in_pos;\n"
+
+"VSOUT vec4 v_color;\n"
+"VSOUT vec2 v_tex0;\n"
+"VSOUT vec2 v_tex1;\n"
+"VSOUT float v_fog;\n"
+
+"void\n"
+"main(void)\n"
+"{\n"
+" gl_Position = in_pos;\n"
+" gl_Position.w = 1.0;\n"
+" gl_Position.xy = gl_Position.xy * u_xform.xy + u_xform.zw;\n"
+" v_fog = DoFog(gl_Position.z);\n"
+" gl_Position.xyz *= gl_Position.w;\n"
+" v_color = in_color;\n"
+" v_tex0 = in_tex0;\n"
+" v_tex1 = in_tex1;\n"
+"}\n"
+;
diff --git a/src/extras/shaders/im2d_gl3.inc b/src/extras/shaders/im2d_gl.inc
index 68341b39..d11f5d33 100644
--- a/src/extras/shaders/im2d_gl3.inc
+++ b/src/extras/shaders/im2d_gl.inc
@@ -1,13 +1,11 @@
const char *im2d_vert_src =
"uniform vec4 u_xform;\n"
-"layout(location = 0) in vec4 in_pos;\n"
-"layout(location = 2) in vec4 in_color;\n"
-"layout(location = 3) in vec2 in_tex0;\n"
+"VSIN(ATTRIB_POS) vec4 in_pos;\n"
-"out vec4 v_color;\n"
-"out vec2 v_tex0;\n"
-"out float v_fog;\n"
+"VSOUT vec4 v_color;\n"
+"VSOUT vec2 v_tex0;\n"
+"VSOUT float v_fog;\n"
"void\n"
"main(void)\n"
diff --git a/src/extras/shaders/neoGloss.frag b/src/extras/shaders/neoGloss.frag
index 14ef0e15..4f097b0b 100644
--- a/src/extras/shaders/neoGloss.frag
+++ b/src/extras/shaders/neoGloss.frag
@@ -4,17 +4,15 @@ uniform vec4 u_reflProps;
#define glossMult (u_reflProps.x)
-in vec3 v_normal;
-in vec3 v_light;
-in vec2 v_tex0;
-in float v_fog;
-
-out vec4 color;
+FSIN vec3 v_normal;
+FSIN vec3 v_light;
+FSIN vec2 v_tex0;
+FSIN float v_fog;
void
main(void)
{
- color = texture(tex0, vec2(v_tex0.x, 1.0-v_tex0.y));
+ vec4 color = texture(tex0, vec2(v_tex0.x, 1.0-v_tex0.y));
vec3 n = 2.0*v_normal-1.0; // unpack
vec3 v = 2.0*v_light-1.0; //
@@ -22,5 +20,7 @@ main(void)
color = s*s*s*s*s*s*s*s*color*v_fog*glossMult;
DoAlphaTest(color.a);
+
+ FRAGCOLOR(color);
}
diff --git a/src/extras/shaders/neoGloss.vert b/src/extras/shaders/neoGloss.vert
index 78dd1b33..41102f3f 100644
--- a/src/extras/shaders/neoGloss.vert
+++ b/src/extras/shaders/neoGloss.vert
@@ -1,15 +1,11 @@
uniform vec3 u_eye;
+VSIN(ATTRIB_POS) vec3 in_pos;
-layout(location = 0) in vec3 in_pos;
-layout(location = 1) in vec3 in_normal;
-layout(location = 2) in vec4 in_color;
-layout(location = 3) in vec2 in_tex0;
-
-out vec3 v_normal;
-out vec3 v_light;
-out vec2 v_tex0;
-out float v_fog;
+VSOUT vec3 v_normal;
+VSOUT vec3 v_light;
+VSOUT vec2 v_tex0;
+VSOUT float v_fog;
void
main(void)
diff --git a/src/extras/shaders/neoGloss_fs_gl3.inc b/src/extras/shaders/neoGloss_fs_gl.inc
index 736b0c5d..67e9724e 100644
--- a/src/extras/shaders/neoGloss_fs_gl3.inc
+++ b/src/extras/shaders/neoGloss_fs_gl.inc
@@ -5,17 +5,15 @@ const char *neoGloss_frag_src =
"#define glossMult (u_reflProps.x)\n"
-"in vec3 v_normal;\n"
-"in vec3 v_light;\n"
-"in vec2 v_tex0;\n"
-"in float v_fog;\n"
-
-"out vec4 color;\n"
+"FSIN vec3 v_normal;\n"
+"FSIN vec3 v_light;\n"
+"FSIN vec2 v_tex0;\n"
+"FSIN float v_fog;\n"
"void\n"
"main(void)\n"
"{\n"
-" color = texture(tex0, vec2(v_tex0.x, 1.0-v_tex0.y));\n"
+" vec4 color = texture(tex0, vec2(v_tex0.x, 1.0-v_tex0.y));\n"
" vec3 n = 2.0*v_normal-1.0; // unpack\n"
" vec3 v = 2.0*v_light-1.0; //\n"
@@ -23,6 +21,8 @@ const char *neoGloss_frag_src =
" color = s*s*s*s*s*s*s*s*color*v_fog*glossMult;\n"
" DoAlphaTest(color.a);\n"
+
+" FRAGCOLOR(color);\n"
"}\n"
;
diff --git a/src/extras/shaders/neoGloss_vs_gl3.inc b/src/extras/shaders/neoGloss_vs_gl.inc
index 4adc9cb2..dffb423f 100644
--- a/src/extras/shaders/neoGloss_vs_gl3.inc
+++ b/src/extras/shaders/neoGloss_vs_gl.inc
@@ -1,16 +1,12 @@
const char *neoGloss_vert_src =
"uniform vec3 u_eye;\n"
+"VSIN(ATTRIB_POS) vec3 in_pos;\n"
-"layout(location = 0) in vec3 in_pos;\n"
-"layout(location = 1) in vec3 in_normal;\n"
-"layout(location = 2) in vec4 in_color;\n"
-"layout(location = 3) in vec2 in_tex0;\n"
-
-"out vec3 v_normal;\n"
-"out vec3 v_light;\n"
-"out vec2 v_tex0;\n"
-"out float v_fog;\n"
+"VSOUT vec3 v_normal;\n"
+"VSOUT vec3 v_light;\n"
+"VSOUT vec2 v_tex0;\n"
+"VSOUT float v_fog;\n"
"void\n"
"main(void)\n"
diff --git a/src/extras/shaders/neoRim.vert b/src/extras/shaders/neoRim.vert
index 4a2b545f..81ee1090 100644
--- a/src/extras/shaders/neoRim.vert
+++ b/src/extras/shaders/neoRim.vert
@@ -3,14 +3,11 @@ uniform vec4 u_rampStart;
uniform vec4 u_rampEnd;
uniform vec3 u_rimData;
-layout(location = 0) in vec3 in_pos;
-layout(location = 1) in vec3 in_normal;
-layout(location = 2) in vec4 in_color;
-layout(location = 3) in vec2 in_tex0;
-
-out vec4 v_color;
-out vec2 v_tex0;
-out float v_fog;
+VSIN(ATTRIB_POS) vec3 in_pos;
+
+VSOUT vec4 v_color;
+VSOUT vec2 v_tex0;
+VSOUT float v_fog;
void
main(void)
diff --git a/src/extras/shaders/neoRimSkin.vert b/src/extras/shaders/neoRimSkin.vert
index f16f2310..1515ad71 100644
--- a/src/extras/shaders/neoRimSkin.vert
+++ b/src/extras/shaders/neoRimSkin.vert
@@ -5,16 +5,11 @@ uniform vec4 u_rampStart;
uniform vec4 u_rampEnd;
uniform vec3 u_rimData;
-layout(location = 0) in vec3 in_pos;
-layout(location = 1) in vec3 in_normal;
-layout(location = 2) in vec4 in_color;
-layout(location = 3) in vec2 in_tex0;
-layout(location = 11) in vec4 in_weights;
-layout(location = 12) in vec4 in_indices;
-
-out vec4 v_color;
-out vec2 v_tex0;
-out float v_fog;
+VSIN(ATTRIB_POS) vec3 in_pos;
+
+VSOUT vec4 v_color;
+VSOUT vec2 v_tex0;
+VSOUT float v_fog;
void
main(void)
diff --git a/src/extras/shaders/neoRimSkin_gl3.inc b/src/extras/shaders/neoRimSkin_gl.inc
index 70948e1f..01b739b2 100644
--- a/src/extras/shaders/neoRimSkin_gl3.inc
+++ b/src/extras/shaders/neoRimSkin_gl.inc
@@ -6,16 +6,11 @@ const char *neoRimSkin_vert_src =
"uniform vec4 u_rampEnd;\n"
"uniform vec3 u_rimData;\n"
-"layout(location = 0) in vec3 in_pos;\n"
-"layout(location = 1) in vec3 in_normal;\n"
-"layout(location = 2) in vec4 in_color;\n"
-"layout(location = 3) in vec2 in_tex0;\n"
-"layout(location = 11) in vec4 in_weights;\n"
-"layout(location = 12) in vec4 in_indices;\n"
-
-"out vec4 v_color;\n"
-"out vec2 v_tex0;\n"
-"out float v_fog;\n"
+"VSIN(ATTRIB_POS) vec3 in_pos;\n"
+
+"VSOUT vec4 v_color;\n"
+"VSOUT vec2 v_tex0;\n"
+"VSOUT float v_fog;\n"
"void\n"
"main(void)\n"
diff --git a/src/extras/shaders/neoRim_gl3.inc b/src/extras/shaders/neoRim_gl.inc
index 7e36e95a..7cd199d0 100644
--- a/src/extras/shaders/neoRim_gl3.inc
+++ b/src/extras/shaders/neoRim_gl.inc
@@ -4,14 +4,11 @@ const char *neoRim_vert_src =
"uniform vec4 u_rampEnd;\n"
"uniform vec3 u_rimData;\n"
-"layout(location = 0) in vec3 in_pos;\n"
-"layout(location = 1) in vec3 in_normal;\n"
-"layout(location = 2) in vec4 in_color;\n"
-"layout(location = 3) in vec2 in_tex0;\n"
-
-"out vec4 v_color;\n"
-"out vec2 v_tex0;\n"
-"out float v_fog;\n"
+"VSIN(ATTRIB_POS) vec3 in_pos;\n"
+
+"VSOUT vec4 v_color;\n"
+"VSOUT vec2 v_tex0;\n"
+"VSOUT float v_fog;\n"
"void\n"
"main(void)\n"
diff --git a/src/extras/shaders/neoVehicle.frag b/src/extras/shaders/neoVehicle.frag
index 96d4a632..2ac24f70 100644
--- a/src/extras/shaders/neoVehicle.frag
+++ b/src/extras/shaders/neoVehicle.frag
@@ -1,13 +1,11 @@
uniform sampler2D tex0;
uniform sampler2D tex1;
-in vec4 v_color;
-in vec4 v_reflcolor;
-in vec2 v_tex0;
-in vec2 v_tex1;
-in float v_fog;
-
-out vec4 color;
+FSIN vec4 v_color;
+FSIN vec4 v_reflcolor;
+FSIN vec2 v_tex0;
+FSIN vec2 v_tex1;
+FSIN float v_fog;
void
main(void)
@@ -20,9 +18,12 @@ main(void)
vec3 pass2 = v_reflcolor.rgb * v_fog;
+ vec4 color;
color.rgb = pass1.rgb*pass1.a + pass2;
color.a = pass1.a;
// color.rgb = mix(u_fogColor.rgb, color.rgb, v_fog);
DoAlphaTest(color.a);
+
+ FRAGCOLOR(color);
}
diff --git a/src/extras/shaders/neoVehicle.vert b/src/extras/shaders/neoVehicle.vert
index f2f54d6d..f0224ddb 100644
--- a/src/extras/shaders/neoVehicle.vert
+++ b/src/extras/shaders/neoVehicle.vert
@@ -8,16 +8,13 @@ uniform vec4 u_specColor[5];
#define shininess (u_reflProps.z)
#define specularity (u_reflProps.w)
-layout(location = 0) in vec3 in_pos;
-layout(location = 1) in vec3 in_normal;
-layout(location = 2) in vec4 in_color;
-layout(location = 3) in vec2 in_tex0;
-
-out vec4 v_color;
-out vec4 v_reflcolor;
-out vec2 v_tex0;
-out vec2 v_tex1;
-out float v_fog;
+VSIN(ATTRIB_POS) vec3 in_pos;
+
+VSOUT vec4 v_color;
+VSOUT vec4 v_reflcolor;
+VSOUT vec2 v_tex0;
+VSOUT vec2 v_tex1;
+VSOUT float v_fog;
vec3 DoDirLightSpec(vec3 Ldir, vec3 Lcol, vec3 N, vec3 V, float power)
{
diff --git a/src/extras/shaders/neoVehicle_fs_gl3.inc b/src/extras/shaders/neoVehicle_fs_gl.inc
index c75ba717..20537440 100644
--- a/src/extras/shaders/neoVehicle_fs_gl3.inc
+++ b/src/extras/shaders/neoVehicle_fs_gl.inc
@@ -2,13 +2,11 @@ const char *neoVehicle_frag_src =
"uniform sampler2D tex0;\n"
"uniform sampler2D tex1;\n"
-"in vec4 v_color;\n"
-"in vec4 v_reflcolor;\n"
-"in vec2 v_tex0;\n"
-"in vec2 v_tex1;\n"
-"in float v_fog;\n"
-
-"out vec4 color;\n"
+"FSIN vec4 v_color;\n"
+"FSIN vec4 v_reflcolor;\n"
+"FSIN vec2 v_tex0;\n"
+"FSIN vec2 v_tex1;\n"
+"FSIN float v_fog;\n"
"void\n"
"main(void)\n"
@@ -21,10 +19,13 @@ const char *neoVehicle_frag_src =
" vec3 pass2 = v_reflcolor.rgb * v_fog;\n"
+" vec4 color;\n"
" color.rgb = pass1.rgb*pass1.a + pass2;\n"
" color.a = pass1.a;\n"
"// color.rgb = mix(u_fogColor.rgb, color.rgb, v_fog);\n"
" DoAlphaTest(color.a);\n"
+
+" FRAGCOLOR(color);\n"
"}\n"
;
diff --git a/src/extras/shaders/neoVehicle_vs_gl3.inc b/src/extras/shaders/neoVehicle_vs_gl.inc
index 268180e1..b7b42622 100644
--- a/src/extras/shaders/neoVehicle_vs_gl3.inc
+++ b/src/extras/shaders/neoVehicle_vs_gl.inc
@@ -9,16 +9,13 @@ const char *neoVehicle_vert_src =
"#define shininess (u_reflProps.z)\n"
"#define specularity (u_reflProps.w)\n"
-"layout(location = 0) in vec3 in_pos;\n"
-"layout(location = 1) in vec3 in_normal;\n"
-"layout(location = 2) in vec4 in_color;\n"
-"layout(location = 3) in vec2 in_tex0;\n"
-
-"out vec4 v_color;\n"
-"out vec4 v_reflcolor;\n"
-"out vec2 v_tex0;\n"
-"out vec2 v_tex1;\n"
-"out float v_fog;\n"
+"VSIN(ATTRIB_POS) vec3 in_pos;\n"
+
+"VSOUT vec4 v_color;\n"
+"VSOUT vec4 v_reflcolor;\n"
+"VSOUT vec2 v_tex0;\n"
+"VSOUT vec2 v_tex1;\n"
+"VSOUT float v_fog;\n"
"vec3 DoDirLightSpec(vec3 Ldir, vec3 Lcol, vec3 N, vec3 V, float power)\n"
"{\n"
diff --git a/src/extras/shaders/neoWorldVC.frag b/src/extras/shaders/neoWorldVC.frag
index 0270f305..08cae743 100644
--- a/src/extras/shaders/neoWorldVC.frag
+++ b/src/extras/shaders/neoWorldVC.frag
@@ -3,12 +3,10 @@ uniform sampler2D tex1;
uniform vec4 u_lightMap;
-in vec4 v_color;
-in vec2 v_tex0;
-in vec2 v_tex1;
-in float v_fog;
-
-out vec4 color;
+FSIN vec4 v_color;
+FSIN vec2 v_tex0;
+FSIN vec2 v_tex1;
+FSIN float v_fog;
void
main(void)
@@ -16,10 +14,13 @@ 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));
- color = t0*v_color*(1 + u_lightMap*(t1-1));
+ 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);
DoAlphaTest(color.a);
+
+ FRAGCOLOR(color);
}
diff --git a/src/extras/shaders/neoWorldVC_fs_gl3.inc b/src/extras/shaders/neoWorldVC_fs_gl.inc
index c861d334..b4385fc7 100644
--- a/src/extras/shaders/neoWorldVC_fs_gl3.inc
+++ b/src/extras/shaders/neoWorldVC_fs_gl.inc
@@ -4,12 +4,10 @@ const char *neoWorldVC_frag_src =
"uniform vec4 u_lightMap;\n"
-"in vec4 v_color;\n"
-"in vec2 v_tex0;\n"
-"in vec2 v_tex1;\n"
-"in float v_fog;\n"
-
-"out vec4 color;\n"
+"FSIN vec4 v_color;\n"
+"FSIN vec2 v_tex0;\n"
+"FSIN vec2 v_tex1;\n"
+"FSIN float v_fog;\n"
"void\n"
"main(void)\n"
@@ -17,11 +15,14 @@ const char *neoWorldVC_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"
-" color = t0*v_color*(1 + u_lightMap*(t1-1));\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"
" DoAlphaTest(color.a);\n"
+
+" FRAGCOLOR(color);\n"
"}\n"
;
diff --git a/src/extras/shaders/screenDroplet.frag b/src/extras/shaders/screenDroplet.frag
new file mode 100644
index 00000000..84d30bd5
--- /dev/null
+++ b/src/extras/shaders/screenDroplet.frag
@@ -0,0 +1,18 @@
+uniform sampler2D tex0;
+uniform sampler2D tex1;
+
+FSIN vec4 v_color;
+FSIN vec2 v_tex0;
+FSIN vec2 v_tex1;
+FSIN float v_fog;
+
+void
+main(void)
+{
+ vec4 color;
+ color = v_color*texture(tex0, vec2(v_tex0.x, 1.0-v_tex0.y));
+ color *= texture(tex1, vec2(v_tex1.x, 1.0-v_tex1.y));
+
+ FRAGCOLOR(color);
+}
+
diff --git a/src/extras/shaders/screenDroplet_PS.cso b/src/extras/shaders/screenDroplet_PS.cso
new file mode 100644
index 00000000..5508096b
--- /dev/null
+++ b/src/extras/shaders/screenDroplet_PS.cso
Binary files differ
diff --git a/src/extras/shaders/screenDroplet_PS.hlsl b/src/extras/shaders/screenDroplet_PS.hlsl
new file mode 100644
index 00000000..4d41da68
--- /dev/null
+++ b/src/extras/shaders/screenDroplet_PS.hlsl
@@ -0,0 +1,17 @@
+struct VS_out {
+ float4 Position : POSITION;
+ float2 TexCoord0 : TEXCOORD0;
+ float2 TexCoord1 : TEXCOORD1;
+ float4 Color : COLOR0;
+};
+
+sampler2D tex0 : register(s0);
+sampler2D tex1 : register(s1);
+
+float4 main(VS_out input) : COLOR
+{
+ float4 color = input.Color;
+ color *= tex2D(tex0, input.TexCoord0.xy);
+ color *= tex2D(tex1, input.TexCoord1.xy);
+ return color;
+}
diff --git a/src/extras/shaders/screenDroplet_PS.inc b/src/extras/shaders/screenDroplet_PS.inc
new file mode 100644
index 00000000..c2055188
--- /dev/null
+++ b/src/extras/shaders/screenDroplet_PS.inc
@@ -0,0 +1,29 @@
+static unsigned char screenDroplet_PS_cso[] = {
+ 0x00, 0x02, 0xff, 0xff, 0xfe, 0xff, 0x2c, 0x00, 0x43, 0x54, 0x41, 0x42,
+ 0x1c, 0x00, 0x00, 0x00, 0x7b, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xff,
+ 0x02, 0x00, 0x00, 0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00,
+ 0x74, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
+ 0x01, 0x00, 0x02, 0x00, 0x4c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0x5c, 0x00, 0x00, 0x00, 0x03, 0x00, 0x01, 0x00, 0x01, 0x00, 0x06, 0x00,
+ 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x65, 0x78, 0x30,
+ 0x00, 0xab, 0xab, 0xab, 0x04, 0x00, 0x0c, 0x00, 0x01, 0x00, 0x01, 0x00,
+ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x65, 0x78, 0x31,
+ 0x00, 0xab, 0xab, 0xab, 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, 0x1f, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x03, 0xb0, 0x1f, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x80,
+ 0x01, 0x00, 0x03, 0xb0, 0x1f, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x80,
+ 0x00, 0x00, 0x0f, 0x90, 0x1f, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x90,
+ 0x00, 0x08, 0x0f, 0xa0, 0x1f, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x90,
+ 0x01, 0x08, 0x0f, 0xa0, 0x42, 0x00, 0x00, 0x03, 0x00, 0x00, 0x0f, 0x80,
+ 0x00, 0x00, 0xe4, 0xb0, 0x00, 0x08, 0xe4, 0xa0, 0x42, 0x00, 0x00, 0x03,
+ 0x01, 0x00, 0x0f, 0x80, 0x01, 0x00, 0xe4, 0xb0, 0x01, 0x08, 0xe4, 0xa0,
+ 0x05, 0x00, 0x00, 0x03, 0x00, 0x00, 0x0f, 0x80, 0x00, 0x00, 0xe4, 0x80,
+ 0x00, 0x00, 0xe4, 0x90, 0x05, 0x00, 0x00, 0x03, 0x00, 0x00, 0x0f, 0x80,
+ 0x01, 0x00, 0xe4, 0x80, 0x00, 0x00, 0xe4, 0x80, 0x01, 0x00, 0x00, 0x02,
+ 0x00, 0x08, 0x0f, 0x80, 0x00, 0x00, 0xe4, 0x80, 0xff, 0xff, 0x00, 0x00
+};
diff --git a/src/extras/shaders/screenDroplet_fs_gl.inc b/src/extras/shaders/screenDroplet_fs_gl.inc
new file mode 100644
index 00000000..dd393b02
--- /dev/null
+++ b/src/extras/shaders/screenDroplet_fs_gl.inc
@@ -0,0 +1,20 @@
+const char *screenDroplet_frag_src =
+"uniform sampler2D tex0;\n"
+"uniform sampler2D tex1;\n"
+
+"FSIN vec4 v_color;\n"
+"FSIN vec2 v_tex0;\n"
+"FSIN vec2 v_tex1;\n"
+"FSIN float v_fog;\n"
+
+"void\n"
+"main(void)\n"
+"{\n"
+" vec4 color;\n"
+" color = v_color*texture(tex0, vec2(v_tex0.x, 1.0-v_tex0.y));\n"
+" color *= texture(tex1, vec2(v_tex1.x, 1.0-v_tex1.y));\n"
+
+" FRAGCOLOR(color);\n"
+"}\n"
+
+;
diff --git a/src/extras/shaders/simple.frag b/src/extras/shaders/simple.frag
index 87157beb..c85bf089 100644
--- a/src/extras/shaders/simple.frag
+++ b/src/extras/shaders/simple.frag
@@ -1,16 +1,17 @@
uniform sampler2D tex0;
-in vec4 v_color;
-in vec2 v_tex0;
-in float v_fog;
-
-out vec4 color;
+FSIN vec4 v_color;
+FSIN vec2 v_tex0;
+FSIN float v_fog;
void
main(void)
{
+ vec4 color;
color = v_color*texture(tex0, vec2(v_tex0.x, 1.0-v_tex0.y));
color.rgb = mix(u_fogColor.rgb, color.rgb, v_fog);
DoAlphaTest(color.a);
+
+ FRAGCOLOR(color);
}
diff --git a/src/extras/shaders/simple_fs_gl3.inc b/src/extras/shaders/simple_fs_gl.inc
index 47d89971..614d79a0 100644
--- a/src/extras/shaders/simple_fs_gl3.inc
+++ b/src/extras/shaders/simple_fs_gl.inc
@@ -1,18 +1,19 @@
const char *simple_frag_src =
"uniform sampler2D tex0;\n"
-"in vec4 v_color;\n"
-"in vec2 v_tex0;\n"
-"in float v_fog;\n"
-
-"out vec4 color;\n"
+"FSIN vec4 v_color;\n"
+"FSIN vec2 v_tex0;\n"
+"FSIN float v_fog;\n"
"void\n"
"main(void)\n"
"{\n"
+" vec4 color;\n"
" color = v_color*texture(tex0, vec2(v_tex0.x, 1.0-v_tex0.y));\n"
" color.rgb = mix(u_fogColor.rgb, color.rgb, v_fog);\n"
" DoAlphaTest(color.a);\n"
+
+" FRAGCOLOR(color);\n"
"}\n"
;
diff --git a/src/fakerw/fake.cpp b/src/fakerw/fake.cpp
index 5d53605d..37567927 100644
--- a/src/fakerw/fake.cpp
+++ b/src/fakerw/fake.cpp
@@ -16,9 +16,14 @@ using namespace rw;
RwUInt8 RwObjectGetType(const RwObject *obj) { return obj->type; }
-void *RwMalloc(size_t size) { return malloc(size); }
-void *RwCalloc(size_t numObj, size_t sizeObj) { return calloc(numObj, sizeObj); }
-void RwFree(void *mem) { free(mem); }
+void *RwMalloc(size_t size) { return engine->memfuncs.rwmalloc(size, 0); }
+void *RwCalloc(size_t numObj, size_t sizeObj) {
+ void *mem = RwMalloc(numObj*sizeObj);
+ if(mem)
+ memset(mem, 0, numObj*sizeObj);
+ return mem;
+}
+void RwFree(void *mem) { engine->memfuncs.rwfree(mem); }
//RwReal RwV3dNormalize(RwV3d * out, const RwV3d * in);
@@ -166,8 +171,8 @@ RwFrame *RwCameraGetFrame(const RwCamera *camera) { return camera->getFrame(
RwImage *RwImageCreate(RwInt32 width, RwInt32 height, RwInt32 depth) { return Image::create(width, height, depth); }
RwBool RwImageDestroy(RwImage * image) { image->destroy(); return true; }
-RwImage *RwImageAllocatePixels(RwImage * image);
-RwImage *RwImageFreePixels(RwImage * image);
+RwImage *RwImageAllocatePixels(RwImage * image) { image->allocate(); return image; }
+RwImage *RwImageFreePixels(RwImage * image) { image->free(); return image; }
RwImage *RwImageCopy(RwImage * destImage, const RwImage * sourceImage);
RwImage *RwImageResize(RwImage * image, RwInt32 width, RwInt32 height);
RwImage *RwImageApplyMask(RwImage * image, const RwImage * mask);
@@ -182,10 +187,10 @@ RwImage *RwImageSetPixels(RwImage * image, RwUInt8 * pixels) { image->pixels
RwImage *RwImageSetPalette(RwImage * image, RwRGBA * palette) { image->palette = (uint8*)palette; return image; }
RwInt32 RwImageGetWidth(const RwImage * image) { return image->width; }
RwInt32 RwImageGetHeight(const RwImage * image) { return image->height; }
-RwInt32 RwImageGetDepth(const RwImage * image);
-RwInt32 RwImageGetStride(const RwImage * image);
-RwUInt8 *RwImageGetPixels(const RwImage * image);
-RwRGBA *RwImageGetPalette(const RwImage * image);
+RwInt32 RwImageGetDepth(const RwImage * image) { return image->depth; }
+RwInt32 RwImageGetStride(const RwImage * image) { return image->stride; }
+RwUInt8 *RwImageGetPixels(const RwImage * image) { return image->pixels; }
+RwRGBA *RwImageGetPalette(const RwImage * image) { return (RwRGBA*)image->palette; }
RwUInt32 RwRGBAToPixel(RwRGBA * rgbIn, RwInt32 rasterFormat);
RwRGBA *RwRGBASetFromPixel(RwRGBA * rgbOut, RwUInt32 pixelValue, RwInt32 rasterFormat);
RwBool RwImageSetGamma(RwReal gammaValue);
@@ -537,8 +542,27 @@ RwBool RwRenderStateSet(RwRenderState state, void *value)
}
}
+static rw::MemoryFunctions gMemfuncs;
+static void *(*real_malloc)(size_t size);
+static void *(*real_realloc)(void *mem, size_t newSize);
+static void *mallocWrap(size_t sz, uint32 hint) { if(sz == 0) return nil; return real_malloc(sz); }
+static void *reallocWrap(void *p, size_t sz, uint32 hint) { return real_realloc(p, sz); }
+
+
// WARNING: unused parameters
-RwBool RwEngineInit(RwMemoryFunctions *memFuncs, RwUInt32 initFlags, RwUInt32 resArenaSize) { Engine::init(); return true; }
+RwBool RwEngineInit(RwMemoryFunctions *memFuncs, RwUInt32 initFlags, RwUInt32 resArenaSize) {
+ if(memFuncs){
+ real_malloc = memFuncs->rwmalloc;
+ real_realloc = memFuncs->rwrealloc;
+ gMemfuncs.rwmalloc = mallocWrap;
+ gMemfuncs.rwrealloc = reallocWrap;
+ gMemfuncs.rwfree = memFuncs->rwfree;
+ Engine::init(&gMemfuncs);
+ }else{
+ Engine::init(nil);
+ }
+ return true;
+}
// TODO: this is platform dependent
RwBool RwEngineOpen(RwEngineOpenParams *initParams) {
static EngineOpenParams openParams;
@@ -578,6 +602,9 @@ void RwD3D8EngineSetRefreshRate(RwUInt32 refreshRate) {}
RwBool RwD3D8DeviceSupportsDXTTexture(void) { return true; }
+void RwD3D8EngineSetMultiSamplingLevels(RwUInt32 level) { Engine::setMultiSamplingLevels(level); }
+RwUInt32 RwD3D8EngineGetMaxMultiSamplingLevels(void) { return Engine::getMaxMultiSamplingLevels(); }
+
RpMaterial *RpMaterialCreate(void) { return Material::create(); }
RwBool RpMaterialDestroy(RpMaterial *material) { material->destroy(); return true; }
@@ -936,16 +963,3 @@ RtCharset *RtCharsetSetColors(RtCharset * charSet, const RwRGBA * foreGround,
RtCharset *RtCharsetGetDesc(RtCharset * charset, RtCharsetDesc * desc) { *desc = charset->desc; return charset; }
RtCharset *RtCharsetCreate(const RwRGBA * foreGround, const RwRGBA * backGround) { return Charset::create(foreGround, backGround); }
RwBool RtCharsetDestroy(RtCharset * charSet) { charSet->destroy(); return true; }
-
-
-
-// fake shit
-RwInt32 _rwD3D8FindCorrectRasterFormat(RwRasterType type, RwInt32 flags)
-{
-#ifdef RW_GL3
- if(flags & (rwRASTERFORMATPAL8 | rwRASTERFORMAT8888))
- return 'NOPE';
- return 'YUP';
-#endif
- return flags & 0xF00;
-}
diff --git a/src/fakerw/rwcore.h b/src/fakerw/rwcore.h
index 31bc5541..e5d21865 100644
--- a/src/fakerw/rwcore.h
+++ b/src/fakerw/rwcore.h
@@ -411,3 +411,5 @@ RwFrame *RwCameraGetFrame(const RwCamera *camera);
void RwD3D8EngineSetRefreshRate(RwUInt32 refreshRate);
RwBool RwD3D8DeviceSupportsDXTTexture(void);
+void RwD3D8EngineSetMultiSamplingLevels(RwUInt32 level);
+RwUInt32 RwD3D8EngineGetMaxMultiSamplingLevels(void);
diff --git a/src/fakerw/rwplcore.h b/src/fakerw/rwplcore.h
index 79c745b6..511f7678 100644
--- a/src/fakerw/rwplcore.h
+++ b/src/fakerw/rwplcore.h
@@ -141,15 +141,15 @@ RwUInt8 RwObjectGetType(const RwObject *obj);
***********************************************
*/
-struct RwMemoryFunctions;
-/*
+struct RwMemoryFunctions
{
+ // NB: from RW 3.6 on the allocating functions take
+ // a hint parameter!
void *(*rwmalloc)(size_t size);
void (*rwfree)(void *mem);
void *(*rwrealloc)(void *mem, size_t newSize);
void *(*rwcalloc)(size_t numObj, size_t sizeObj);
};
-*/
void *RwMalloc(size_t size);
void RwFree(void *mem);
diff --git a/src/math/Matrix.h b/src/math/Matrix.h
index bf811af7..d32b1d93 100644
--- a/src/math/Matrix.h
+++ b/src/math/Matrix.h
@@ -23,15 +23,6 @@ public:
void UpdateRW(void);
void operator=(CMatrix const &rhs);
CMatrix &operator+=(CMatrix const &rhs);
-#ifdef RWCORE_H
- operator RwMatrix (void) const {
- return m_matrix;
- }
-
- operator RwMatrix *(void) {
- return &m_matrix;
- }
-#endif
CMatrix &operator*=(CMatrix const &rhs);
const CVector &GetPosition(void) const { return *(CVector*)&m_matrix.pos; }
diff --git a/src/math/Quaternion.h b/src/math/Quaternion.h
index a5a34626..47c94f7c 100644
--- a/src/math/Quaternion.h
+++ b/src/math/Quaternion.h
@@ -12,6 +12,11 @@ public:
float MagnitudeSqr(void) const { return x*x + y*y + z*z + w*w; }
void Normalise(void);
void Multiply(const CQuaternion &q1, const CQuaternion &q2);
+ void Invert(void){ // Conjugate would have been a better name
+ x = -x;
+ y = -y;
+ z = -z;
+ }
const CQuaternion &operator+=(CQuaternion const &right) {
x += right.x;
diff --git a/src/math/Vector.h b/src/math/Vector.h
index 082b296f..02128454 100644
--- a/src/math/Vector.h
+++ b/src/math/Vector.h
@@ -1,23 +1,22 @@
#pragma once
-class CVector
+class CVector : public RwV3d
{
public:
- float x, y, z;
CVector(void) {}
- CVector(float x, float y, float z) : x(x), y(y), z(z) {}
-#ifdef RWCORE_H
- CVector(const RwV3d &v) : x(v.x), y(v.y), z(v.z) {}
-
- operator RwV3d (void) const {
- RwV3d vecRw = { this->x, this->y, this->z };
- return vecRw;
+ CVector(float x, float y, float z)
+ {
+ this->x = x;
+ this->y = y;
+ this->z = z;
}
-
- operator RwV3d *(void) {
- return (RwV3d*)this;
+
+ CVector(const RwV3d &v)
+ {
+ x = v.x;
+ y = v.y;
+ z = v.z;
}
-#endif
// (0,1,0) means no rotation. So get right vector and its atan
float Heading(void) const { return Atan2(-x, y); }
float Magnitude(void) const { return Sqrt(x*x + y*y + z*z); }
@@ -65,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/VuVector.h b/src/math/VuVector.h
index f90818e0..30d62cfc 100644
--- a/src/math/VuVector.h
+++ b/src/math/VuVector.h
@@ -8,18 +8,7 @@ public:
CVuVector(float x, float y, float z) : CVector(x, y, z) {}
CVuVector(float x, float y, float z, float w) : CVector(x, y, z), w(w) {}
CVuVector(const CVector &v) : CVector(v.x, v.y, v.z) {}
-#ifdef RWCORE_H
- CVuVector(const RwV3d &v) : CVector(v.x, v.y, v.z) {}
-
- operator RwV3d (void) const {
- RwV3d vecRw = { this->x, this->y, this->z };
- return vecRw;
- }
-
- operator RwV3d *(void) {
- return (RwV3d*)this;
- }
-#endif
+ CVuVector(const RwV3d &v) : CVector(v) {}
/*
void Normalise(void) {
float sq = MagnitudeSqr();
diff --git a/src/modelinfo/BaseModelInfo.cpp b/src/modelinfo/BaseModelInfo.cpp
index 31bb2500..f05be242 100644
--- a/src/modelinfo/BaseModelInfo.cpp
+++ b/src/modelinfo/BaseModelInfo.cpp
@@ -88,7 +88,7 @@ CBaseModelInfo::Add2dEffect(C2dEffect *fx)
if(m_2dEffectsID >= 0)
m_num2dEffects++;
else{
- m_2dEffectsID = CModelInfo::Get2dEffectStore().getIndex(fx);
+ m_2dEffectsID = CModelInfo::Get2dEffectStore().GetIndex(fx);
m_num2dEffects = 1;
}
}
@@ -97,7 +97,7 @@ C2dEffect*
CBaseModelInfo::Get2dEffect(int n)
{
if(m_2dEffectsID >= 0)
- return CModelInfo::Get2dEffectStore().getItem(m_2dEffectsID+n);
+ return CModelInfo::Get2dEffectStore().GetItem(m_2dEffectsID+n);
else
return nil;
}
diff --git a/src/modelinfo/BaseModelInfo.h b/src/modelinfo/BaseModelInfo.h
index e7dd9e4b..23ba5e66 100644
--- a/src/modelinfo/BaseModelInfo.h
+++ b/src/modelinfo/BaseModelInfo.h
@@ -4,7 +4,7 @@
#define MAX_MODEL_NAME (21)
-enum ModelInfoType : uint8
+enum ModelInfoType
{
MITYPE_NA,
MITYPE_SIMPLE,
@@ -17,7 +17,6 @@ enum ModelInfoType : uint8
MITYPE_XTRACOMPS, // unused but still in enum
MITYPE_HAND // xbox and mobile
};
-VALIDATE_SIZE(ModelInfoType, 1);
class C2dEffect;
@@ -25,7 +24,7 @@ class CBaseModelInfo
{
protected:
char m_name[MAX_MODEL_NAME];
- ModelInfoType m_type;
+ uint8 m_type;
uint8 m_num2dEffects;
bool m_bOwnsColModel;
CColModel *m_colModel;
@@ -47,7 +46,7 @@ public:
virtual int GetAnimFileIndex(void) { return -1; }
// one day it becomes virtual
- ModelInfoType GetModelType() const { return m_type; }
+ uint8 GetModelType() const { return m_type; }
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; }
@@ -59,9 +58,9 @@ public:
bool DoesOwnColModel(void) { return m_bOwnsColModel; }
void DeleteCollisionModel(void);
void ClearTexDictionary(void) { m_txdSlot = -1; }
- short GetObjectID(void) { return m_objectId; }
+ int16 GetObjectID(void) { return m_objectId; }
void SetObjectID(int16 id) { m_objectId = id; }
- short GetTxdSlot(void) { return m_txdSlot; }
+ int16 GetTxdSlot(void) { return m_txdSlot; }
void AddRef(void);
void RemoveRef(void);
void SetTexDictionary(const char *name);
diff --git a/src/modelinfo/ModelIndices.cpp b/src/modelinfo/ModelIndices.cpp
index 056c3733..98c7fb38 100644
--- a/src/modelinfo/ModelIndices.cpp
+++ b/src/modelinfo/ModelIndices.cpp
@@ -3,7 +3,7 @@
#include "General.h"
#include "ModelIndices.h"
-#define X(name, var) int16 var;
+#define X(name, var) int16 var = -1;
MODELINDICES
#undef X
diff --git a/src/modelinfo/ModelInfo.cpp b/src/modelinfo/ModelInfo.cpp
index 961efa84..9e5b0470 100644
--- a/src/modelinfo/ModelInfo.cpp
+++ b/src/modelinfo/ModelInfo.cpp
@@ -33,13 +33,13 @@ CModelInfo::Initialise(void)
for(i = 0; i < MODELINFOSIZE; i++)
ms_modelInfoPtrs[i] = nil;
- ms_2dEffectStore.clear();
- ms_simpleModelStore.clear();
- ms_timeModelStore.clear();
- ms_weaponModelStore.clear();
- ms_clumpModelStore.clear();
- ms_pedModelStore.clear();
- ms_vehicleModelStore.clear();
+ ms_2dEffectStore.Clear();
+ ms_simpleModelStore.Clear();
+ ms_timeModelStore.Clear();
+ ms_weaponModelStore.Clear();
+ ms_clumpModelStore.Clear();
+ ms_pedModelStore.Clear();
+ ms_vehicleModelStore.Clear();
m = AddSimpleModel(MI_CAR_DOOR);
m->SetColModel(&CTempColModels::ms_colModelDoor1);
@@ -109,20 +109,20 @@ CModelInfo::ShutDown(void)
for(i = 0; i < ms_2dEffectStore.allocPtr; i++)
ms_2dEffectStore.store[i].Shutdown();
- ms_2dEffectStore.clear();
- ms_simpleModelStore.clear();
- ms_timeModelStore.clear();
- ms_weaponModelStore.clear();
- ms_pedModelStore.clear();
- ms_clumpModelStore.clear();
- ms_vehicleModelStore.clear();
+ ms_2dEffectStore.Clear();
+ ms_simpleModelStore.Clear();
+ ms_timeModelStore.Clear();
+ ms_weaponModelStore.Clear();
+ ms_pedModelStore.Clear();
+ ms_clumpModelStore.Clear();
+ ms_vehicleModelStore.Clear();
}
CSimpleModelInfo*
CModelInfo::AddSimpleModel(int id)
{
CSimpleModelInfo *modelinfo;
- modelinfo = CModelInfo::ms_simpleModelStore.alloc();
+ modelinfo = CModelInfo::ms_simpleModelStore.Alloc();
CModelInfo::ms_modelInfoPtrs[id] = modelinfo;
modelinfo->Init();
return modelinfo;
@@ -132,7 +132,7 @@ CTimeModelInfo*
CModelInfo::AddTimeModel(int id)
{
CTimeModelInfo *modelinfo;
- modelinfo = CModelInfo::ms_timeModelStore.alloc();
+ modelinfo = CModelInfo::ms_timeModelStore.Alloc();
CModelInfo::ms_modelInfoPtrs[id] = modelinfo;
modelinfo->Init();
return modelinfo;
@@ -142,7 +142,7 @@ CWeaponModelInfo*
CModelInfo::AddWeaponModel(int id)
{
CWeaponModelInfo *modelinfo;
- modelinfo = CModelInfo::ms_weaponModelStore.alloc();
+ modelinfo = CModelInfo::ms_weaponModelStore.Alloc();
CModelInfo::ms_modelInfoPtrs[id] = modelinfo;
modelinfo->Init();
return modelinfo;
@@ -152,7 +152,7 @@ CClumpModelInfo*
CModelInfo::AddClumpModel(int id)
{
CClumpModelInfo *modelinfo;
- modelinfo = CModelInfo::ms_clumpModelStore.alloc();
+ modelinfo = CModelInfo::ms_clumpModelStore.Alloc();
CModelInfo::ms_modelInfoPtrs[id] = modelinfo;
modelinfo->m_clump = nil;
return modelinfo;
@@ -162,7 +162,7 @@ CPedModelInfo*
CModelInfo::AddPedModel(int id)
{
CPedModelInfo *modelinfo;
- modelinfo = CModelInfo::ms_pedModelStore.alloc();
+ modelinfo = CModelInfo::ms_pedModelStore.Alloc();
CModelInfo::ms_modelInfoPtrs[id] = modelinfo;
modelinfo->m_clump = nil;
return modelinfo;
@@ -172,7 +172,7 @@ CVehicleModelInfo*
CModelInfo::AddVehicleModel(int id)
{
CVehicleModelInfo *modelinfo;
- modelinfo = CModelInfo::ms_vehicleModelStore.alloc();
+ modelinfo = CModelInfo::ms_vehicleModelStore.Alloc();
CModelInfo::ms_modelInfoPtrs[id] = modelinfo;
modelinfo->m_clump = nil;
modelinfo->m_vehicleType = -1;
@@ -251,7 +251,7 @@ CModelInfo::IsPlaneModel(int32 id)
void
CModelInfo::ReInit2dEffects()
{
- ms_2dEffectStore.clear();
+ ms_2dEffectStore.Clear();
for (int i = 0; i < MODELINFOSIZE; i++) {
if (ms_modelInfoPtrs[i])
diff --git a/src/modelinfo/PedModelInfo.h b/src/modelinfo/PedModelInfo.h
index e878a59b..86e6b74a 100644
--- a/src/modelinfo/PedModelInfo.h
+++ b/src/modelinfo/PedModelInfo.h
@@ -2,7 +2,6 @@
#include "ClumpModelInfo.h"
#include "PedType.h"
-#include "PedStats.h"
enum PedNode {
PED_TORSO = 0, // has no bone!
diff --git a/src/modelinfo/TimeModelInfo.cpp b/src/modelinfo/TimeModelInfo.cpp
index d4f92293..c1c18dac 100644
--- a/src/modelinfo/TimeModelInfo.cpp
+++ b/src/modelinfo/TimeModelInfo.cpp
@@ -2,6 +2,7 @@
#include "Camera.h"
#include "ModelInfo.h"
+#include "General.h"
CTimeModelInfo*
CTimeModelInfo::FindOtherTimeModel(void)
@@ -23,7 +24,7 @@ CTimeModelInfo::FindOtherTimeModel(void)
for(i = 0; i < MODELINFOSIZE; i++){
CBaseModelInfo *mi = CModelInfo::GetModelInfo(i);
if (mi && mi->GetModelType() == MITYPE_TIME &&
- strncmp(name, mi->GetName(), 24) == 0){
+ !CGeneral::faststrncmp(name, mi->GetName(), MAX_MODEL_NAME)){
m_otherTimeModelID = i;
return (CTimeModelInfo*)mi;
}
diff --git a/src/modelinfo/VehicleModelInfo.cpp b/src/modelinfo/VehicleModelInfo.cpp
index 5d69a921..6dc9e5b0 100644
--- a/src/modelinfo/VehicleModelInfo.cpp
+++ b/src/modelinfo/VehicleModelInfo.cpp
@@ -333,7 +333,7 @@ CVehicleModelInfo::SetAtomicRendererCB(RpAtomic *atomic, void *data)
name = GetFrameNodeName(RpAtomicGetFrame(atomic));
alpha = false;
RpGeometryForAllMaterials(RpAtomicGetGeometry(atomic), HasAlphaMaterialCB, &alpha);
- if(strstr(name, "_hi") || strncmp(name, "extra", 5) == 0){
+ if(strstr(name, "_hi") || !CGeneral::faststrncmp(name, "extra", 5)) {
if(alpha || strncmp(name, "windscreen", 10) == 0)
CVisibilityPlugins::SetAtomicRenderCallback(atomic, CVisibilityPlugins::RenderVehicleHiDetailAlphaCB);
else
@@ -359,7 +359,7 @@ CVehicleModelInfo::SetAtomicRendererCB_BigVehicle(RpAtomic *atomic, void *data)
name = GetFrameNodeName(RpAtomicGetFrame(atomic));
alpha = false;
RpGeometryForAllMaterials(RpAtomicGetGeometry(atomic), HasAlphaMaterialCB, &alpha);
- if(strstr(name, "_hi") || strncmp(name, "extra", 5) == 0){
+ if(strstr(name, "_hi") || !CGeneral::faststrncmp(name, "extra", 5)) {
if(alpha)
CVisibilityPlugins::SetAtomicRenderCallback(atomic, CVisibilityPlugins::RenderVehicleHiDetailAlphaCB_BigVehicle);
else
@@ -407,7 +407,7 @@ CVehicleModelInfo::SetAtomicRendererCB_Boat(RpAtomic *atomic, void *data)
clump = (RpClump*)data;
name = GetFrameNodeName(RpAtomicGetFrame(atomic));
- if(strcmp(name, "boat_hi") == 0 || strncmp(name, "extra", 5) == 0)
+ if(strcmp(name, "boat_hi") == 0 || !CGeneral::faststrncmp(name, "extra", 5))
CVisibilityPlugins::SetAtomicRenderCallback(atomic, CVisibilityPlugins::RenderVehicleHiDetailCB_Boat);
else if(strstr(name, "_hi"))
CVisibilityPlugins::SetAtomicRenderCallback(atomic, CVisibilityPlugins::RenderVehicleHiDetailCB);
@@ -453,7 +453,7 @@ CVehicleModelInfo::SetAtomicRendererCB_RealHeli(RpAtomic *atomic, void *data)
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){
+ else if(strstr(name, "_hi") || !CGeneral::faststrncmp(name, "extra", 5)) {
if(alpha || strncmp(name, "windscreen", 10) == 0)
CVisibilityPlugins::SetAtomicRenderCallback(atomic, CVisibilityPlugins::RenderVehicleHiDetailAlphaCB);
else
@@ -484,7 +484,7 @@ CVehicleModelInfo::SetAtomicRenderCallbacks(void)
RpClumpForAllAtomics(m_clump, SetAtomicRendererCB_BigVehicle, nil);
else if(m_vehicleType == VEHICLE_TYPE_BOAT)
RpClumpForAllAtomics(m_clump, SetAtomicRendererCB_Boat, m_clump);
- else if(mod_HandlingManager.GetHandlingData((eHandlingId)m_handlingId)->Flags & HANDLING_IS_HELI)
+ 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);
@@ -549,7 +549,7 @@ CVehicleModelInfo::PreprocessHierarchy(void)
if(desc[i].flags & VEHICLE_FLAG_POS){
f = assoc.frame;
- rwvec = (RwV3d*)&m_positions[desc[i].hierId];
+ rwvec = &m_positions[desc[i].hierId];
*rwvec = *RwMatrixGetPos(RwFrameGetMatrix(f));
for(f = RwFrameGetParent(f); f; f = RwFrameGetParent(f))
RwV3dTransformPoints(rwvec, rwvec, 1, RwFrameGetMatrix(f));
@@ -614,7 +614,7 @@ CVehicleModelInfo::SetVehicleComponentFlags(RwFrame *frame, uint32 flags)
{
tHandlingData *handling;
- handling = mod_HandlingManager.GetHandlingData((eHandlingId)m_handlingId);
+ handling = mod_HandlingManager.GetHandlingData((tVehicleType)m_handlingId);
#define SETFLAGS(f) RwFrameForAllObjects(frame, SetAtomicFlagCB, (void*)(f))
@@ -1011,11 +1011,11 @@ CVehicleModelInfo::LoadVehicleColours(void)
continue;
if(section == NONE){
- if(strncmp(&line[start], "col", 3) == 0)
+ if(line[start] == 'c' && line[start + 1] == 'o' && line[start + 2] == 'l')
section = COLOURS;
- else if(strncmp(&line[start], "car", 3) == 0)
+ if(line[start] == 'c' && line[start + 1] == 'a' && line[start + 2] == 'r')
section = CARS;
- }else if(strncmp(&line[start], "end", 3) == 0){
+ }else if(line[start] == 'e' && line[start + 1] == 'n' && line[start + 2] == 'd'){
section = NONE;
}else if(section == COLOURS){
sscanf(&line[start], // BUG: games doesn't add start
diff --git a/src/modelinfo/VehicleModelInfo.h b/src/modelinfo/VehicleModelInfo.h
index d03ab9bf..c7a41126 100644
--- a/src/modelinfo/VehicleModelInfo.h
+++ b/src/modelinfo/VehicleModelInfo.h
@@ -24,7 +24,7 @@ enum {
ATOMIC_FLAG_NOCULL = 0x800,
};
-enum eVehicleType : uint8{
+enum eVehicleType {
VEHICLE_TYPE_CAR,
VEHICLE_TYPE_BOAT,
VEHICLE_TYPE_TRAIN,
diff --git a/src/objects/Object.cpp b/src/objects/Object.cpp
index 93b6d581..0605f54f 100644
--- a/src/objects/Object.cpp
+++ b/src/objects/Object.cpp
@@ -14,6 +14,12 @@
#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;
@@ -33,8 +39,8 @@ 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;
@@ -47,7 +53,7 @@ CObject::CObject(void)
bHasBeenDamaged = false;
m_nRefModelIndex = -1;
bUseVehicleColours = false;
-// bIsStreetLight = false; // duplicate
+ // bIsStreetLight = false; // duplicate
m_pCurSurface = nil;
m_pCollidingEntity = nil;
m_nBeachballBounces = 0;
@@ -84,16 +90,16 @@ 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);
@@ -107,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;
@@ -115,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();
@@ -245,7 +314,7 @@ CObject::Render(void)
bool
CObject::SetupLighting(void)
{
- if(bRenderScorched){
+ if (bRenderScorched) {
WorldReplaceNormalLightsWithScorched(Scene.world, 0.1f);
return true;
} else if (bIsPickup) {
@@ -262,14 +331,14 @@ CObject::SetupLighting(void)
void
CObject::RemoveLighting(bool reset)
{
- if(reset) {
+ if (reset) {
SetAmbientColours();
DeActivateDirectional();
}
}
-void
-CObject::ObjectDamage(float amount)
+void
+CObject::ObjectDamage(float amount)
{
if (!m_nCollisionDamageEffect || !bUsesCollision)
return;
@@ -287,132 +356,361 @@ CObject::ObjectDamage(float amount)
}
#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;
}
- else {
+ case DAMAGE_EFFECT_CHANGE_THEN_SMASH: {
+ if (!bRenderDamaged) {
+ bRenderDamaged = true;
+ return;
+ }
+ // fall through
+ }
+ case DAMAGE_EFFECT_SMASH_COMPLETELY: {
bIsVisible = false;
bUsesCollision = false;
+ if (!GetIsStatic()) {
+ RemoveFromMovingList();
+ }
SetIsStatic(true);
bExplosionProof = true;
SetMoveSpeed(0.0f, 0.0f, 0.0f);
SetTurnSpeed(0.0f, 0.0f, 0.0f);
+ break;
}
- break;
- case DAMAGE_EFFECT_SMASH_CARDBOARD_COMPLETELY: {
- bIsVisible = false;
- bUsesCollision = false;
- SetIsStatic(true);
- bExplosionProof = true;
- SetMoveSpeed(0.0f, 0.0f, 0.0f);
- SetTurnSpeed(0.0f, 0.0f, 0.0f);
- const RwRGBA color = { 96, 48, 0, 255 };
- for (int32 i = 0; i < 25; i++) {
- CVector vecDir(CGeneral::GetRandomNumberInRange(-0.35f, 0.7f),
- CGeneral::GetRandomNumberInRange(-0.35f, 0.7f),
- CGeneral::GetRandomNumberInRange(0.1f, 0.15f) + 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.18f);
- int32 nRotationSpeed = CGeneral::GetRandomNumberInRange(-40, 80);
- CParticle::AddParticle(PARTICLE_CAR_DEBRIS, vecPos, vecDir, nil, fSize, randomColor, nRotationSpeed, 0, currentFrame, 0);
+ case DAMAGE_EFFECT_SMASH_CARDBOARD_COMPLETELY:
+ case DAMAGE_EFFECT_SMASH_YELLOW_TARGET_COMPLETELY:
+ {
+ bIsVisible = false;
+ bUsesCollision = false;
+ if (!GetIsStatic()) {
+ RemoveFromMovingList();
+ }
+ SetIsStatic(true);
+ bExplosionProof = true;
+ SetMoveSpeed(0.0f, 0.0f, 0.0f);
+ SetTurnSpeed(0.0f, 0.0f, 0.0f);
+ const RwRGBA color = { 96, 48, 0, 255 };
+ for (int32 i = 0; i < 25; i++) {
+ CVector vecDir = CVector(
+ CGeneral::GetRandomNumberInRange(-0.35f, 0.35f),
+ CGeneral::GetRandomNumberInRange(-0.35f, 0.35f),
+ CGeneral::GetRandomNumberInRange(0.10f, 0.25f) + fDirectionZ
+ );
+ ++nFrameGen;
+ int32 currentFrame = nFrameGen & 3;
+ RwRGBA randomColor = color;
+ switch (m_nCollisionDamageEffect) {
+ case DAMAGE_EFFECT_SMASH_CARDBOARD_COMPLETELY: {
+ float fRandom = CGeneral::GetRandomNumberInRange(0.01f, 1.0f);
+ randomColor.red *= fRandom;
+ randomColor.green *= fRandom;
+ randomColor.blue *= fRandom;
+ break;
+ }
+ case DAMAGE_EFFECT_SMASH_YELLOW_TARGET_COMPLETELY: {
+ randomColor.red = 0xff;
+ randomColor.green = 0xfc;
+ break;
+ }
+ }
+ float fSize = CGeneral::GetRandomNumberInRange(0.02f, 0.20f);
+ int32 nRotationSpeed = CGeneral::GetRandomNumberInRange(-40, 40);
+ CParticle::AddParticle(PARTICLE_CAR_DEBRIS, vecPos, vecDir, nil, fSize, randomColor, nRotationSpeed, 0, currentFrame, 0);
+ }
+ PlayOneShotScriptObject(SCRIPT_SOUND_BOX_DESTROYED_2, vecPos);
+ break;
}
- PlayOneShotScriptObject(SCRIPT_SOUND_BOX_DESTROYED_2, vecPos);
- break;
- }
- case DAMAGE_EFFECT_SMASH_WOODENBOX_COMPLETELY: {
- bIsVisible = false;
- bUsesCollision = false;
- SetIsStatic(true);
- bExplosionProof = true;
- SetMoveSpeed(0.0f, 0.0f, 0.0f);
- SetTurnSpeed(0.0f, 0.0f, 0.0f);
- const RwRGBA color = { 128, 128, 128, 255 };
- for (int32 i = 0; i < 45; i++) {
- CVector vecDir(CGeneral::GetRandomNumberInRange(-0.35f, 0.7f),
- CGeneral::GetRandomNumberInRange(-0.35f, 0.7f),
- CGeneral::GetRandomNumberInRange(0.1f, 0.15f) + fDirectionZ);
- ++nFrameGen;
- int32 currentFrame = nFrameGen & 3;
- float fRandom = CGeneral::GetRandomNumberInRange(0.5f, 0.5f);
- RwRGBA randomColor = { uint8(color.red * fRandom), uint8(color.green * fRandom), uint8(color.blue * fRandom), color.alpha };
- float fSize = CGeneral::GetRandomNumberInRange(0.02f, 0.18f);
- int32 nRotationSpeed = CGeneral::GetRandomNumberInRange(-40, 80);
- CParticle::AddParticle(PARTICLE_CAR_DEBRIS, vecPos, vecDir, nil, fSize, randomColor, nRotationSpeed, 0, currentFrame, 0);
+ case DAMAGE_EFFECT_SMASH_WOODENBOX_COMPLETELY:
+ {
+ bIsVisible = false;
+ bUsesCollision = false;
+ if (!GetIsStatic()) {
+ RemoveFromMovingList();
+ }
+ SetIsStatic(true);
+ bExplosionProof = true;
+ SetMoveSpeed(0.0f, 0.0f, 0.0f);
+ SetTurnSpeed(0.0f, 0.0f, 0.0f);
+ static const RwRGBA color = { 128, 128, 128, 255 };
+ CVector position = GetPosition();
+ for (int32 i = 0; i < 45; i++) {
+ CVector vecDir = CVector(
+ CGeneral::GetRandomNumberInRange(-0.35f, 0.35f),
+ CGeneral::GetRandomNumberInRange(-0.35f, 0.35f),
+ CGeneral::GetRandomNumberInRange(0.10f, 0.25f) + fDirectionZ
+ );
+ ++nFrameGen;
+ int32 currentFrame = nFrameGen & 3;
+ float fRandom = CGeneral::GetRandomNumberInRange(0.5f, 1.0f);
+ RwRGBA randomColor = { uint8(color.red * fRandom), uint8(color.green * fRandom), uint8(color.blue * fRandom), color.alpha };
+ float fSize = CGeneral::GetRandomNumberInRange(0.02f, 0.20f);
+ int32 nRotationSpeed = CGeneral::GetRandomNumberInRange(-40, 40);
+ CParticle::AddParticle(PARTICLE_CAR_DEBRIS, vecPos, vecDir, nil, fSize, randomColor, nRotationSpeed, 0, currentFrame, 0);
+ }
+ PlayOneShotScriptObject(SCRIPT_SOUND_BOX_DESTROYED_1, vecPos);
+ break;
}
- PlayOneShotScriptObject(SCRIPT_SOUND_BOX_DESTROYED_1, vecPos);
- break;
- }
- case DAMAGE_EFFECT_SMASH_TRAFFICCONE_COMPLETELY: {
- bIsVisible = false;
- bUsesCollision = false;
- SetIsStatic(true);
- bExplosionProof = true;
- SetMoveSpeed(0.0f, 0.0f, 0.0f);
- SetTurnSpeed(0.0f, 0.0f, 0.0f);
- const RwRGBA color1 = { 200, 0, 0, 255 };
- const RwRGBA color2 = { 200, 200, 200, 255 };
- for (int32 i = 0; i < 10; i++) {
- CVector vecDir(CGeneral::GetRandomNumberInRange(-0.35f, 0.7f),
- CGeneral::GetRandomNumberInRange(-0.35f, 0.7f),
- CGeneral::GetRandomNumberInRange(0.1f, 0.15f) + fDirectionZ);
- ++nFrameGen;
- int32 currentFrame = nFrameGen & 3;
- RwRGBA color = color2;
- if (nFrameGen & 1)
- color = color1;
- float fSize = CGeneral::GetRandomNumberInRange(0.02f, 0.18f);
- int32 nRotationSpeed = CGeneral::GetRandomNumberInRange(-40, 80);
- CParticle::AddParticle(PARTICLE_CAR_DEBRIS, vecPos, vecDir, nil, fSize, color, nRotationSpeed, 0, currentFrame, 0);
+ case DAMAGE_EFFECT_SMASH_TRAFFICCONE_COMPLETELY:
+ case DAMAGE_EFFECT_BURST_BEACHBALL:
+ {
+ bIsVisible = false;
+ bUsesCollision = false;
+ if (!GetIsStatic()) {
+ RemoveFromMovingList();
+ }
+ SetIsStatic(true);
+ bExplosionProof = true;
+ SetMoveSpeed(0.0f, 0.0f, 0.0f);
+ SetTurnSpeed(0.0f, 0.0f, 0.0f);
+ const RwRGBA color1 = { 200, 0, 0, 255 };
+ const RwRGBA color2 = { 200, 200, 200, 255 };
+ for (int32 i = 0; i < 10; i++) {
+ CVector vecDir = CVector(
+ CGeneral::GetRandomNumberInRange(-0.35f, 0.35f),
+ CGeneral::GetRandomNumberInRange(-0.35f, 0.35f),
+ CGeneral::GetRandomNumberInRange(0.10f, 0.25f) + fDirectionZ
+ );
+ ++nFrameGen;
+ int32 currentFrame = nFrameGen & 3;
+ RwRGBA color = color2;
+ if (nFrameGen & 1)
+ color = color1;
+ float fSize = CGeneral::GetRandomNumberInRange(0.02f, 0.20f);
+ int32 nRotationSpeed = CGeneral::GetRandomNumberInRange(-40, 40);
+ CParticle::AddParticle(PARTICLE_CAR_DEBRIS, vecPos, vecDir, nil, fSize, color, nRotationSpeed, 0, currentFrame, 0);
+ }
+ if (m_nCollisionDamageEffect == DAMAGE_EFFECT_BURST_BEACHBALL) {
+ PlayOneShotScriptObject(SCRIPT_SOUND_HIT_BALL, vecPos);
+ } else {
+ PlayOneShotScriptObject(SCRIPT_SOUND_TIRE_COLLISION, vecPos);
+ }
+ break;
}
- PlayOneShotScriptObject(SCRIPT_SOUND_TIRE_COLLISION, vecPos);
- break;
- }
- case DAMAGE_EFFECT_SMASH_BARPOST_COMPLETELY: {
- bIsVisible = false;
- bUsesCollision = false;
- SetIsStatic(true);
- bExplosionProof = true;
- SetMoveSpeed(0.0f, 0.0f, 0.0f);
- SetTurnSpeed(0.0f, 0.0f, 0.0f);
- const RwRGBA color1 = { 200, 0, 0, 255 };
- const RwRGBA color2 = { 200, 200, 200, 255 };
- for (int32 i = 0; i < 32; i++) {
- CVector vecDir(CGeneral::GetRandomNumberInRange(-0.35f, 0.7f),
- CGeneral::GetRandomNumberInRange(-0.35f, 0.7f),
- CGeneral::GetRandomNumberInRange(0.1f, 0.15f) + fDirectionZ);
- ++nFrameGen;
- int32 currentFrame = nFrameGen & 3;
- RwRGBA color = color2;
- if (nFrameGen & 1)
- color = color1;
- float fSize = CGeneral::GetRandomNumberInRange(0.02f, 0.18f);
- int32 nRotationSpeed = CGeneral::GetRandomNumberInRange(-40, 80);
- CParticle::AddParticle(PARTICLE_CAR_DEBRIS, vecPos, vecDir, nil, fSize, color, nRotationSpeed, 0, currentFrame, 0);
+ case DAMAGE_EFFECT_SMASH_BARPOST_COMPLETELY:
+ {
+ bIsVisible = false;
+ bUsesCollision = false;
+ if (!GetIsStatic()) {
+ RemoveFromMovingList();
+ }
+ SetIsStatic(true);
+ bExplosionProof = true;
+ SetMoveSpeed(0.0f, 0.0f, 0.0f);
+ SetTurnSpeed(0.0f, 0.0f, 0.0f);
+ const RwRGBA color1 = { 200, 0, 0, 255 };
+ const RwRGBA color2 = { 200, 200, 200, 255 };
+ SetMoveSpeed(0.0f, 0.0f, 0.0f);
+ SetTurnSpeed(0.0f, 0.0f, 0.0f);
+ for (int32 i = 0; i < 32; i++) {
+ CVector vecDir = CVector(
+ CGeneral::GetRandomNumberInRange(-0.35f, 0.35f),
+ CGeneral::GetRandomNumberInRange(-0.35f, 0.35f),
+ CGeneral::GetRandomNumberInRange(0.10f, 0.25f) + fDirectionZ
+ );
+ ++nFrameGen;
+ int32 currentFrame = nFrameGen & 3;
+ const RwRGBA &color = nFrameGen & 1 ? color1 : color2;
+ float fSize = CGeneral::GetRandomNumberInRange(0.02f, 0.20f);
+ int32 nRotationSpeed = CGeneral::GetRandomNumberInRange(-40, 40);
+ CParticle::AddParticle(PARTICLE_CAR_DEBRIS, vecPos, vecDir, nil, fSize, color, nRotationSpeed, 0, currentFrame, 0);
+ }
+ PlayOneShotScriptObject(SCRIPT_SOUND_METAL_COLLISION, vecPos);
+ break;
}
- PlayOneShotScriptObject(SCRIPT_SOUND_METAL_COLLISION, vecPos);
- break;
- }
+ case DAMAGE_EFFECT_SMASH_NEWSTANDNEW1:
+ case DAMAGE_EFFECT_SMASH_NEWSTANDNEW2:
+ case DAMAGE_EFFECT_SMASH_NEWSTANDNEW3:
+ case DAMAGE_EFFECT_SMASH_NEWSTANDNEW4:
+ case DAMAGE_EFFECT_SMASH_NEWSTANDNEW5:
+ {
+ bIsVisible = false;
+ bUsesCollision = false;
+ if (!GetIsStatic()) {
+ RemoveFromMovingList();
+ }
+ SetIsStatic(true);
+ bExplosionProof = true;
+ SetMoveSpeed(0.0f, 0.0f, 0.0f);
+ SetTurnSpeed(0.0f, 0.0f, 0.0f);
+ CRGBA possibleColor1;
+ CRGBA possibleColor2;
+ switch (m_nCollisionDamageEffect) {
+ case DAMAGE_EFFECT_SMASH_NEWSTANDNEW1:
+ possibleColor1 = CRGBA(0xC0, 0x3E, 0xC, 0xFF);
+ possibleColor2 = possibleColor1;
+ break;
+ case DAMAGE_EFFECT_SMASH_NEWSTANDNEW2:
+ possibleColor1 = CRGBA(0xA3, 0x36, 0x21, 0xFF);
+ possibleColor2 = possibleColor1;
+ break;
+ case DAMAGE_EFFECT_SMASH_NEWSTANDNEW3:
+ possibleColor1 = CRGBA(0x12, 0x31, 0x24, 0xFF);
+ possibleColor2 = possibleColor1;
+ break;
+ case DAMAGE_EFFECT_SMASH_NEWSTANDNEW4:
+ possibleColor1 = CRGBA(0xC0, 0xC8, 0xBE, 0xFF);
+ possibleColor2 = CRGBA(0x10, 0x57, 0x85, 0xFF);
+ break;
+ case DAMAGE_EFFECT_SMASH_NEWSTANDNEW5:
+ possibleColor1 = CRGBA(0xD0, 0x94, 0x1B, 0xFF);
+ possibleColor2 = possibleColor1;
+ break;
+ }
+ for (int32 i = 0; i < 16; i++) {
+ CVector vecDir(
+ CGeneral::GetRandomNumberInRange(-0.35f, 0.35f),
+ CGeneral::GetRandomNumberInRange(-0.35f, 0.35f),
+ CGeneral::GetRandomNumberInRange(0.10f, 0.15f) + fDirectionZ
+ );
+ float fSize = CGeneral::GetRandomNumberInRange(0.02f, 0.20f);
+ int32 nRotationSpeed = CGeneral::GetRandomNumberInRange(-40, 40);
+ ++nFrameGen;
+ int32 nCurFrame = nFrameGen & 0x3;
+ CRGBA &selectedColor = nFrameGen & 0x1 ? possibleColor1 : possibleColor2;
+ CParticle::AddParticle(PARTICLE_CAR_DEBRIS, vecPos, vecDir, nil, fSize, selectedColor, nRotationSpeed, 0, nCurFrame, 0);
+ if (!(i % 7)) {
+ static CRGBA secondParticleColors[4] = {
+ CRGBA(0xA0, 0x60, 0x60, 0xFF),
+ CRGBA(0x60, 0xA0, 0x60, 0xFF),
+ CRGBA(0x60, 0x60, 0xA0, 0xFF),
+ CRGBA(0xA0, 0xA0, 0xA0, 0xFF)
+ };
+ vecDir *= 0.5f;
+ CRGBA &secondParticleColor = secondParticleColors[nFrameGen & 3];
+ int32 nSecondRotationSpeed = CGeneral::GetRandomNumberInRange(-40, 40);
+ CParticle::AddParticle(PARTICLE_DEBRIS, vecPos, vecDir, nil, 0.1f, secondParticleColor, nSecondRotationSpeed, 0, 1, 0);
+ }
+ }
+ PlayOneShotScriptObject(SCRIPT_SOUND_METAL_COLLISION, vecPos);
+ break;
+ }
+ case DAMAGE_EFFECT_SMASH_VEGPALM:
+ {
+ static RwRGBA primaryColor1 = { 0x39, 0x4D, 0x29, 0xff };
+ static RwRGBA primaryColor2 = { 0x94, 0x7D, 0x73, 0xff };
+ bIsVisible = false;
+ bUsesCollision = false;
+ if (!GetIsStatic()) {
+ RemoveFromMovingList();
+ }
+ SetIsStatic(true);
+ bExplosionProof = true;
+ SetMoveSpeed(0.0f, 0.0f, 0.0f);
+ SetTurnSpeed(0.0f, 0.0f, 0.0f);
+ float fRadius = GetColModel()->boundingSphere.radius;
+ for (int32 i = 0; i < 32; i++) {
+ CVector particleDir = CVector(
+ CGeneral::GetRandomNumberInRange(-0.25f, 0.25f),
+ CGeneral::GetRandomNumberInRange(-0.25f, 0.25f),
+ CGeneral::GetRandomNumberInRange(-0.05f, 0.05f) + fDirectionZ
+ );
+ CVector particlePos = vecPos;
+ particlePos.z += CGeneral::GetRandomNumberInRange(0.0f, 1.0f) * fRadius;
+ ++nFrameGen;
+ int32 nRotationSpeed = CGeneral::GetRandomNumberInRange(-40, 40);
+ int32 nCurFrame = nFrameGen & 0x3;
+ float fSize = CGeneral::GetRandomNumberInRange(0.02f, 0.20f);
+ RwRGBA& particleColor = nFrameGen & 1 ? primaryColor1 : primaryColor2;
+ CParticle::AddParticle(PARTICLE_CAR_DEBRIS, particlePos, particleDir, nil, fSize, particleColor, nRotationSpeed, 0, nCurFrame, 0);
+ if ((i % 7) == 0) {
+ static RwRGBA secondaryColor = { 0x9A, 0x99, 0x99, 0x3E };
+ CParticle::AddParticle(PARTICLE_DEBRIS, particlePos, particleDir, nil, 0.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;
}
}
}
@@ -424,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;
@@ -447,8 +745,8 @@ CObject::Init(void)
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
@@ -457,7 +755,7 @@ CObject::Init(void)
if (GetModelIndex() == MI_BUOY)
bTouchingWater = true;
- if(CModelInfo::GetModelInfo(GetModelIndex())->GetModelType() == MITYPE_WEAPON)
+ if (CModelInfo::GetModelInfo(GetModelIndex())->GetModelType() == MITYPE_WEAPON)
bIsWeapon = true;
bIsStreetLight = IsLightObject(GetModelIndex());
@@ -486,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;
@@ -496,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;
@@ -509,13 +807,13 @@ 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++) {
CObject *pObject = objectPool->GetSlot(i);
- if (pObject && pObject->ObjectCreatedBy == TEMP_OBJECT && fRadius * fRadius > pObject->GetPosition().MagnitudeSqr()) {
+ if (pObject && pObject->ObjectCreatedBy == TEMP_OBJECT && (point - pObject->GetPosition()).MagnitudeSqr() < SQR(fRadius)) {
CWorld::Remove(pObject);
delete pObject;
}
@@ -523,11 +821,11 @@ CObject::DeleteAllTempObjectsInArea(CVector point, float fRadius)
}
bool
-IsObjectPointerValid(CObject* pObject)
+IsObjectPointerValid(CObject *pObject)
{
if (!pObject)
return false;
- int index = CPools::GetObjectPool()->GetJustIndex(pObject);
+ int index = CPools::GetObjectPool()->GetJustIndex_NoFreeAssert(pObject);
#ifdef FIX_BUGS
if (index < 0 || index >= CPools::GetObjectPool()->GetSize())
#else
diff --git a/src/objects/Object.h b/src/objects/Object.h
index bc74b58b..e34043a8 100644
--- a/src/objects/Object.h
+++ b/src/objects/Object.h
@@ -32,23 +32,23 @@ enum CollisionDamageEffect
DAMAGE_EFFECT_CHANGE_THEN_SMASH,
DAMAGE_EFFECT_SMASH_CARDBOARD_COMPLETELY = 50,
- DAMAGE_EFFECT_SMASH_YELLOW_TARGET_COMPLETELY,
+ 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_NEWSTANDNEW1 = 91,
- DAMAGE_EFFECT_SMASH_NEWSTANDNEW21,
- DAMAGE_EFFECT_SMASH_NEWSTANDNEW31,
- DAMAGE_EFFECT_SMASH_NEWSTANDNEW41,
- DAMAGE_EFFECT_SMASH_NEWSTANDNEW51,
+ 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,
+ DAMAGE_EFFECT_SMASH_BEACHLOUNGE_TOWEL = 132,
};
class CVehicle;
@@ -76,7 +76,7 @@ public:
uint8 m_nCollisionDamageEffect;
uint8 m_nSpecialCollisionResponseCases;
bool m_bCameraToAvoidThisObject;
- int8 m_nBeachballBounces;
+ uint8 m_nBeachballBounces;
uint32 m_obj_unused1;
uint32 m_nEndOfLifeTime;
int16 m_nRefModelIndex;
diff --git a/src/objects/ParticleObject.cpp b/src/objects/ParticleObject.cpp
index 6ed74214..4d080d1f 100644
--- a/src/objects/ParticleObject.cpp
+++ b/src/objects/ParticleObject.cpp
@@ -8,6 +8,7 @@
#include "Camera.h"
#include "Game.h"
#include "DMAudio.h"
+#include "screendroplets.h"
CParticleObject gPObjectArray[MAX_PARTICLEOBJECTS];
@@ -18,6 +19,8 @@ CParticleObject *CParticleObject::pUnusedListHead;
CAudioHydrant List[MAX_AUDIOHYDRANTS];
+CAudioHydrant *CAudioHydrant::Get(int n) { return &List[n]; }
+
bool
CAudioHydrant::Add(CParticleObject *particleobject)
{
@@ -246,6 +249,9 @@ CParticleObject::AddObject(uint16 type, CVector const &pos, CVector const &targe
pobj->m_nNumEffectCycles = 0;
pobj->m_nSkipFrames = 1;
pobj->m_nCreationChance = 0;
+#ifdef SCREEN_DROPLETS
+ ScreenDroplets::RegisterSplash(pobj);
+#endif
break;
}
diff --git a/src/objects/ParticleObject.h b/src/objects/ParticleObject.h
index a29d7bd4..f199e533 100644
--- a/src/objects/ParticleObject.h
+++ b/src/objects/ParticleObject.h
@@ -107,4 +107,6 @@ public:
static bool Add (CParticleObject *particleobject);
static void Remove(CParticleObject *particleobject);
+
+ static CAudioHydrant *Get(int n); // for neo screen droplets
}; \ No newline at end of file
diff --git a/src/objects/Projectile.h b/src/objects/Projectile.h
index 2f2b541c..4b3eb4b8 100644
--- a/src/objects/Projectile.h
+++ b/src/objects/Projectile.h
@@ -1,7 +1,5 @@
#pragma once
-#pragma once
-
#include "Object.h"
class CProjectile : public CObject
diff --git a/src/peds/CivilianPed.cpp b/src/peds/CivilianPed.cpp
index 18a0e2a3..079024f6 100644
--- a/src/peds/CivilianPed.cpp
+++ b/src/peds/CivilianPed.cpp
@@ -18,7 +18,7 @@
#include <float.h>
#endif
-// --MIAMI: file done except TODOs
+// --MIAMI: file done
CCivilianPed::CCivilianPed(ePedType pedtype, uint32 mi) : CPed(pedtype)
{
@@ -228,7 +228,7 @@ CCivilianPed::CivilianAI(void)
void
CCivilianPed::ProcessControl(void)
{
- if (CharCreatedBy == TODO_CHAR)
+ if (CharCreatedBy == UNK_CHAR)
return;
CPed::ProcessControl();
@@ -314,7 +314,7 @@ CCivilianPed::ProcessControl(void)
for (int j = 0; j < m_numNearPeds; ++j) {
CPed *nearPed = m_nearPeds[j];
if (nearPed->m_nPedType == m_nPedType && nearPed->m_nPedState == PED_WANDER_PATH) {
- nearPed->m_nPedState = PED_UNKNOWN;
+ nearPed->SetPedState(PED_UNKNOWN);
}
}
}
@@ -420,6 +420,32 @@ CCivilianPed::ProcessControl(void)
Avoid();
}
+// --MIAMI: Done
+bool
+CPed::RunToReportCrime(eCrimeType crimeToReport)
+{
+ // 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;
+
+ CVector pos = GetPosition();
+ int phoneId = gPhoneInfo.FindNearestFreePhone(&pos);
+
+ if (phoneId == -1)
+ return false;
+
+ CPhone* phone = &gPhoneInfo.m_aPhones[phoneId];
+ if (phone->m_nState != PHONE_STATE_FREE)
+ return false;
+
+ bRunningToPhone = true;
+ SetSeek(phone->m_vecPos, 0.3f);
+ SetMoveState(PEDMOVE_RUN);
+ m_phoneId = phoneId;
+ m_crimeToReportOnPhone = crimeToReport;
+ return true;
+}
+
const int32 gFrequencyOfAttractorAttempt = 11;
const float gDistanceToSeekAttractors = 50.0f;
const float gMaxDistanceToAttract = 10.0f;
diff --git a/src/peds/CivilianPed.h b/src/peds/CivilianPed.h
index a7fb766b..dcd49a96 100644
--- a/src/peds/CivilianPed.h
+++ b/src/peds/CivilianPed.h
@@ -23,6 +23,4 @@ public:
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 10490a69..762c7f1a 100644
--- a/src/peds/CopPed.cpp
+++ b/src/peds/CopPed.cpp
@@ -96,9 +96,7 @@ CCopPed::CCopPed(eCopType copType, int32 modifier) : CPed(PEDTYPE_COP)
field_61C = 0;
field_624 = 0;
m_pStinger = new CStinger;
- if (m_pPointGunAt)
- m_pPointGunAt->CleanUpOldReference(&m_pPointGunAt);
- m_pPointGunAt = nil;
+ SetWeaponLockOnTarget(nil);
}
CCopPed::~CCopPed()
@@ -251,7 +249,7 @@ CCopPed::ArrestPlayer(void)
CPed *suspect = (CPed*)m_pSeekTarget;
if (suspect) {
if (suspect->CanSetPedState())
- suspect->m_nPedState = PED_ARRESTED;
+ suspect->SetPedState(PED_ARRESTED);
if (suspect->bInVehicle && m_pMyVehicle && suspect->m_pMyVehicle == m_pMyVehicle) {
@@ -266,7 +264,7 @@ CCopPed::ArrestPlayer(void)
CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_ARREST_GUN, 4.0f);
CVector suspMidPos;
- suspect->m_pedIK.GetComponentPosition(*(RwV3d *)&suspMidPos, PED_MID);
+ suspect->m_pedIK.GetComponentPosition(suspMidPos, PED_MID);
m_fRotationDest = CGeneral::GetRadianAngleBetweenPoints(suspMidPos.x, suspMidPos.y,
GetPosition().x, GetPosition().y);
@@ -493,12 +491,7 @@ CCopPed::CopAI(void)
false, true, false, false, true, false, false)
|| foundEnt && foundEnt == playerOrHisVeh) {
- if (m_pPointGunAt)
- m_pPointGunAt->CleanUpOldReference((CEntity**) &m_pPointGunAt);
- m_pPointGunAt = playerOrHisVeh;
- if (playerOrHisVeh)
- playerOrHisVeh->RegisterReference((CEntity**) &m_pPointGunAt);
-
+ SetWeaponLockOnTarget(playerOrHisVeh);
SetAttack(playerOrHisVeh);
SetShootTimer(CGeneral::GetRandomNumberInRange(500, 1000));
}
@@ -880,4 +873,4 @@ CCopPed::ProcessStingerCop(void)
} else {
ClearPursuit();
}
-} \ No newline at end of file
+}
diff --git a/src/peds/CopPed.h b/src/peds/CopPed.h
index 06fe54b0..3f5ae06d 100644
--- a/src/peds/CopPed.h
+++ b/src/peds/CopPed.h
@@ -48,6 +48,4 @@ public:
void ProcessStingerCop(void);
};
-#ifndef PED_SKIN
-VALIDATE_SIZE(CCopPed, 0x558);
-#endif
+VALIDATE_SIZE(CCopPed, 0x62C);
diff --git a/src/peds/EmergencyPed.cpp b/src/peds/EmergencyPed.cpp
index 24d9a6a1..2eabfe04 100644
--- a/src/peds/EmergencyPed.cpp
+++ b/src/peds/EmergencyPed.cpp
@@ -230,8 +230,8 @@ CEmergencyPed::MedicAI(void)
if (nearestAccident) {
m_pRevivedPed = nearestAccident->m_pVictim;
m_pRevivedPed->RegisterReference((CEntity**)&m_pRevivedPed);
- m_pRevivedPed->m_pedIK.GetComponentPosition(*(RwV3d *)&midPos, PED_MID);
- m_pRevivedPed->m_pedIK.GetComponentPosition(*(RwV3d *)&headPos, PED_HEAD);
+ m_pRevivedPed->m_pedIK.GetComponentPosition(midPos, PED_MID);
+ m_pRevivedPed->m_pedIK.GetComponentPosition(headPos, PED_HEAD);
SetObjective(OBJECTIVE_GOTO_AREA_ON_FOOT, CVector((headPos + midPos) * 0.5f));
bIsRunning = true;
m_nEmergencyPedState = EMERGENCY_PED_DETERMINE_NEXT_STATE;
@@ -270,8 +270,8 @@ CEmergencyPed::MedicAI(void)
m_nEmergencyPedState = EMERGENCY_PED_STOP;
break;
}
- m_pRevivedPed->m_pedIK.GetComponentPosition(*(RwV3d *)&midPos, PED_MID);
- m_pRevivedPed->m_pedIK.GetComponentPosition(*(RwV3d *)&headPos, PED_HEAD);
+ m_pRevivedPed->m_pedIK.GetComponentPosition(midPos, PED_MID);
+ m_pRevivedPed->m_pedIK.GetComponentPosition(headPos, PED_HEAD);
SetObjective(OBJECTIVE_GOTO_AREA_ON_FOOT, CVector((headPos + midPos) * 0.5f));
bIsRunning = true;
--m_pAttendedAccident->m_nMedicsAttending;
@@ -324,8 +324,8 @@ CEmergencyPed::MedicAI(void)
if (!m_pRevivedPed || m_pRevivedPed->m_fHealth > 0.0f)
m_nEmergencyPedState = EMERGENCY_PED_DETERMINE_NEXT_STATE;
else {
- m_pRevivedPed->m_pedIK.GetComponentPosition(*(RwV3d *)&midPos, PED_MID);
- m_pRevivedPed->m_pedIK.GetComponentPosition(*(RwV3d *)&headPos, PED_HEAD);
+ m_pRevivedPed->m_pedIK.GetComponentPosition(midPos, PED_MID);
+ m_pRevivedPed->m_pedIK.GetComponentPosition(headPos, PED_HEAD);
midPos = (headPos + midPos) * 0.5f;
m_fRotationDest = CGeneral::GetRadianAngleBetweenPoints(
midPos.x, midPos.y,
@@ -346,8 +346,8 @@ CEmergencyPed::MedicAI(void)
m_nEmergencyPedState = EMERGENCY_PED_DETERMINE_NEXT_STATE;
break;
}
- m_pRevivedPed->m_pedIK.GetComponentPosition(*(RwV3d *)&midPos, PED_MID);
- m_pRevivedPed->m_pedIK.GetComponentPosition(*(RwV3d *)&headPos, PED_HEAD);
+ m_pRevivedPed->m_pedIK.GetComponentPosition(midPos, PED_MID);
+ m_pRevivedPed->m_pedIK.GetComponentPosition(headPos, PED_HEAD);
midPos = (headPos + midPos) * 0.5f;
m_fRotationDest = CGeneral::GetRadianAngleBetweenPoints(
midPos.x, midPos.y,
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/Ped.cpp b/src/peds/Ped.cpp
index 51b16663..e408c5bb 100644
--- a/src/peds/Ped.cpp
+++ b/src/peds/Ped.cpp
@@ -3,138 +3,52 @@
#include "main.h"
#include "Pools.h"
#include "Particle.h"
-#include "Stats.h"
-#include "World.h"
#include "RpAnimBlend.h"
#include "Bones.h"
#include "Ped.h"
-#include "Wanted.h"
-#include "PlayerPed.h"
-#include "PedType.h"
-#include "AnimBlendClumpData.h"
#include "AnimBlendAssociation.h"
#include "Fire.h"
-#include "Glass.h"
#include "DMAudio.h"
#include "General.h"
-#include "SurfaceTable.h"
#include "VisibilityPlugins.h"
-#include "AudioManager.h"
#include "HandlingMgr.h"
#include "Replay.h"
-#include "Camera.h"
#include "Radar.h"
#include "PedPlacement.h"
#include "Shadows.h"
#include "Weather.h"
#include "ZoneCull.h"
#include "Population.h"
-#include "Renderer.h"
-#include "Lights.h"
-#include "PointLights.h"
#include "Pad.h"
#include "Phones.h"
-#include "Darkel.h"
-#include "PathFind.h"
-#include "ModelIndices.h"
-#include "FileMgr.h"
-#include "TempColModels.h"
-#include "Pickups.h"
-#include "Train.h"
#include "TrafficLights.h"
-#include "PedRoutes.h"
-#include "Sprite.h"
-#include "RwHelper.h"
-#include "Font.h"
-#include "Text.h"
#include "CopPed.h"
#include "Script.h"
#include "CarCtrl.h"
#include "Garages.h"
#include "WaterLevel.h"
-#include "CarAI.h"
-#include "Zones.h"
-#include "Cranes.h"
#include "Timecycle.h"
#include "ParticleObject.h"
#include "Floater.h"
-#include "Range2D.h"
+#include "Range2D.h"
#include "Streaming.h"
#include "PedAttractor.h"
-#include "Debug.h"
#include "GameLogic.h"
#include "Bike.h"
#include "WindModifiers.h"
#include "CutsceneShadow.h"
#include "Clock.h"
-// --MIAMI: file done except TODOs
-
-#define CAN_SEE_ENTITY_ANGLE_THRESHOLD DEGTORAD(60.0f)
+// --MIAMI: file done
CPed *gapTempPedList[50];
uint16 gnNumTempPedList;
static CColPoint aTempPedColPts[MAX_COLLISION_POINTS];
-// TODO(Miami)
-#define AUDIO_NOT_READY
-
-uint16 nPlayerInComboMove;
-
-RpClump *flyingClumpTemp;
-
-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 }
-};
-
uint16 CPed::nThreatReactionRangeMultiplier = 1;
uint16 CPed::nEnterCarRangeMultiplier = 1;
-CVector vecPedCarDoorAnimOffset;
-CVector vecPedCarDoorLoAnimOffset;
-CVector vecPedVanRearDoorAnimOffset;
-CVector vecPedQuickDraggedOutCarAnimOffset;
-CVector vecPedDraggedOutCarAnimOffset;
-CVector vecPedTrainDoorAnimOffset;
-CVector vecPedStdBikeJumpRhsAnimOffset;
-CVector vecPedVespaBikeJumpRhsAnimOffset;
-CVector vecPedHarleyBikeJumpRhsAnimOffset;
-CVector vecPedDirtBikeJumpRhsAnimOffset;
-CVector vecPedBikeKickAnimOffset;
-
bool CPed::bNastyLimbsCheat;
bool CPed::bFannyMagnetCheat;
bool CPed::bPedCheat3;
@@ -148,67 +62,6 @@ void CPed::operator delete(void *p, int handle) { CPools::GetPedPool()->Delete((
float gfTommyFatness = 1.0f;
// --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 being decreased after removing ourself from vehicle.
- m_pMyVehicle->RemovePassenger(this);
- }
- if (m_nPedState == PED_EXIT_CAR || m_nPedState == PED_DRAG_FROM_CAR)
- m_pMyVehicle->m_nGettingOutFlags &= ~door_flag;
- bInVehicle = false;
- m_pMyVehicle = nil;
- } else if (EnteringCar()) {
- QuitEnteringCar();
- }
- 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::FlagToDestroyWhenNextProcessed(void)
-{
- bRemoveFromWorld = true;
- if (!InVehicle())
- return;
- if (m_pMyVehicle->pDriver == this){
- m_pMyVehicle->pDriver = nil;
- if (IsPlayer() && m_pMyVehicle->GetStatus() != STATUS_WRECKED)
- m_pMyVehicle->SetStatus(STATUS_ABANDONED);
- }else{
- m_pMyVehicle->RemovePassenger(this);
- }
- bInVehicle = false;
- m_pMyVehicle = nil;
-
- if (CharCreatedBy == MISSION_CHAR)
- SetPedState(PED_DEAD);
- else
- SetPedState(PED_NONE);
- m_pVehicleAnim = nil;
-}
-
-// --MIAMI: Done
CPed::CPed(uint32 pedType) : m_pedIK(this)
{
#ifdef USE_CUTSCENE_SHADOW_FOR_PED
@@ -287,8 +140,8 @@ CPed::CPed(uint32 pedType) : m_pedIK(this)
m_fleeFromPos = CVector2D(0.0f, 0.0f);
m_fleeTimer = 0;
m_threatEx = nil;
- m_vecSeekPosEx = CVector(0.0f, 0.0f, 0.0f);
- m_distanceToCountSeekDoneEx = 0.0f;
+ m_vecSpotToGuard = CVector(0.0f, 0.0f, 0.0f);
+ m_radiusToGuard = 0.0f;
m_nWaitState = WAITSTATE_FALSE;
m_nWaitTimer = 0;
m_pCollidingEntity = nil;
@@ -411,9 +264,7 @@ CPed::CPed(uint32 pedType) : m_pedIK(this)
bVehExitWillBeInstant = false;
bHasAlreadyBeenRecorded = false;
bFallenDown = false;
-#ifdef PED_SKIN
bDontAcceptIKLookAts = false;
-#endif
bReachedAttractorHeadingTarget = false;
bTurnedAroundOnAttractor = false;
#ifdef KANGAROO_CHEAT
@@ -468,7 +319,7 @@ CPed::CPed(uint32 pedType) : m_pedIK(this)
bCanGiveUpSunbathing = true;
m_audioEntityId = DMAudio.CreateEntity(AUDIOTYPE_PHYSICAL, this);
- DMAudio.SetEntityStatus(m_audioEntityId, 1);
+ DMAudio.SetEntityStatus(m_audioEntityId, true);
m_fearFlags = CPedType::GetThreats(m_nPedType);
m_threatEntity = nil;
m_eventOrThreat = CVector2D(0.0f, 0.0f);
@@ -512,9 +363,7 @@ CPed::CPed(uint32 pedType) : m_pedIK(this)
m_vehicleInAccident = nil;
m_attractor = nil;
m_positionInQueue = -1;
-#ifdef PED_SKIN
m_pWeaponModel = nil;
-#endif
m_delayedSoundID = -1;
m_delayedSoundTimer = 0;
CPopulation::UpdatePedCount((ePedType)m_nPedType, false);
@@ -522,2168 +371,98 @@ CPed::CPed(uint32 pedType) : m_pedIK(this)
}
// --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) {
-
- // 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 {
- if (HasWeaponSlot(slot)) {
-
- // TODO(Miami): Make an enum for that
- if (slot == 4 || slot == 5 || slot == 6)
- 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 (GetWeapon(slot).m_eWeaponState != WEAPONSTATE_OUT_OF_AMMO)
- GetWeapon(slot).m_eWeaponState = WEAPONSTATE_READY;
-
- return slot;
-}
-
-static RwObject*
-RemoveAllModelCB(RwObject *object, void *data)
-{
- RpAtomic *atomic = (RpAtomic*)object;
- if (CVisibilityPlugins::GetAtomicModelInfo(atomic)) {
- RpClumpRemoveAtomic(RpAtomicGetClump(atomic), atomic);
- RpAtomicDestroy(atomic);
- }
- return object;
-}
-
-static PedOnGroundState
-CheckForPedsOnGroundToAttack(CPed *attacker, CPed **pedOnGround)
-{
- PedOnGroundState stateToReturn;
- float angleToFace;
- CPed *currentPed = nil;
- PedState currentPedState;
- CPed *pedOnTheFloor = nil;
- CPed *deadPed = nil;
- CPed *pedBelow = nil;
- bool foundDead = false;
- bool foundOnTheFloor = false;
- bool foundBelow = false;
- float angleDiff;
- float distance;
-
- if (!CGame::nastyGame)
- return NO_PED;
-
- for (int currentPedId = 0; currentPedId < attacker->m_numNearPeds; currentPedId++) {
-
- currentPed = attacker->m_nearPeds[currentPedId];
-
- CVector posDifference = currentPed->GetPosition() - attacker->GetPosition();
- distance = posDifference.Magnitude();
-
- if (distance < 2.0f) {
- angleToFace = CGeneral::GetRadianAngleBetweenPoints(
- currentPed->GetPosition().x, currentPed->GetPosition().y,
- attacker->GetPosition().x, attacker->GetPosition().y);
-
- angleToFace = CGeneral::LimitRadianAngle(angleToFace);
- attacker->m_fRotationCur = CGeneral::LimitRadianAngle(attacker->m_fRotationCur);
-
- angleDiff = Abs(angleToFace - attacker->m_fRotationCur);
-
- if (angleDiff > PI)
- angleDiff = 2 * PI - angleDiff;
-
- currentPedState = currentPed->m_nPedState;
-
- if (currentPed->OnGroundOrGettingUp()) {
- if (distance < 2.0f && angleDiff < DEGTORAD(65.0f)) {
- if (currentPedState == PED_DEAD) {
- foundDead = 1;
- if (!deadPed)
- deadPed = currentPed;
- } else if (!currentPed->IsPedHeadAbovePos(-0.6f)) {
- foundOnTheFloor = 1;
- if (!pedOnTheFloor)
- pedOnTheFloor = currentPed;
- }
- }
- } else if ((distance < 0.8f && angleDiff < DEGTORAD(75.0f))
- || (distance < 1.3f && angleDiff < DEGTORAD(55.0f))
- || (distance < 1.7f && angleDiff < DEGTORAD(35.0f))
- || (distance < 2.0f && angleDiff < DEGTORAD(30.0f))) {
-
- // Either this condition or below one was probably returning 4 early in development. See Fight().
- foundBelow = 1;
- pedBelow = currentPed;
- break;
- } else {
- if (angleDiff < DEGTORAD(75.0f)) {
- foundBelow = 1;
- if (!pedBelow)
- pedBelow = currentPed;
- }
- }
- }
- }
-
- if (foundOnTheFloor) {
- currentPed = pedOnTheFloor;
- stateToReturn = PED_ON_THE_FLOOR;
- } else if (foundDead) {
- currentPed = deadPed;
- stateToReturn = PED_DEAD_ON_THE_FLOOR;
- } else if (foundBelow) {
- currentPed = pedBelow;
- stateToReturn = PED_IN_FRONT_OF_ATTACKER;
- } else {
- currentPed = nil;
- stateToReturn = NO_PED;
- }
-
- if (pedOnGround)
- *pedOnGround = currentPed;
-
- return stateToReturn;
-}
-
-// --MIAMI: Done
-bool
-CPed::IsPlayer(void)
-{
-#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::UseGroundColModel(void)
-{
- return m_nPedState == PED_FALL ||
- m_nPedState == PED_DIVE_AWAY ||
- m_nPedState == PED_DIE ||
- m_nPedState == PED_DEAD;
-}
-
-// --MIAMI: Done
-bool
-CPed::CanSetPedState(void)
-{
- return !DyingOrDead() && m_nPedState != PED_ARRESTED && !EnteringCar() && m_nPedState != PED_STEAL_CAR;
-}
-
-// --MIAMI: Done
-bool
-CPed::IsPedInControl(void)
-{
- return m_nPedState <= PED_STATES_NO_AI
- && !bIsInTheAir && !bIsLanding
- && m_fHealth > 0.0f;
-}
-
-// --MIAMI: Done
-bool
-CPed::CanStrafeOrMouseControl(void)
-{
-#ifdef FREE_CAM
- if (CCamera::bFreeCam)
- 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_ANSWER_MOBILE;
-}
-
-// --MIAMI: Done
-void
-CPed::AddWeaponModel(int id)
-{
- if (id != -1) {
- if (m_pWeaponModel)
- RemoveWeaponModel(-1);
-
- 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();
- }
-}
-
-// --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();
- }
-
- if (!IsPlayer())
- Say(SOUND_PED_ATTACK);
-
- bCanPointGunAtTarget = m_pedIK.PointGunAtPosition(vector);
- if (m_pLookTarget != m_pSeekTarget) {
- SetLookFlag(m_pSeekTarget, true, true);
- }
-
- } else {
- if (IsPlayer()) {
- bCanPointGunAtTarget = m_pedIK.PointGunInDirection(m_fLookDirection, ((CPlayerPed*)this)->m_fFPSMoveHeading);
- } else {
- bCanPointGunAtTarget = m_pedIK.PointGunInDirection(m_fLookDirection, 0.0f);
- }
- }
-}
-
-// --MIAMI: Done
-// III leftover and unused
-void
-CPed::ApplyHeadShot(eWeaponType weaponType, CVector pos, bool evenOnPlayer)
-{
- CVector pos2 = CVector(
- pos.x,
- pos.y,
- pos.z + 0.1f
- );
-
- if (!IsPlayer() || evenOnPlayer) {
- ++CStats::HeadsPopped;
-
- // 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();
- // }
-
- 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);
-
- if (CEntity::GetIsOnScreen()) {
- for(int i=0; i < 32; i++) {
- CParticle::AddParticle(PARTICLE_BLOOD_SMALL,
- pos2, CVector(0.0f, 0.0f, 0.03f),
- nil, 0.0f, 0, 0, 0, 0);
- }
-
- for (int i = 0; i < 16; i++) {
- CParticle::AddParticle(PARTICLE_DEBRIS2,
- pos2,
- CVector(0.0f, 0.0f, 0.01f),
- nil, 0.0f, 0, 0, 0, 0);
- }
- }
- }
-}
-
-static RwObject*
-SetPedAtomicVisibilityCB(RwObject* object, void* data)
-{
- if (data == nil)
- RpAtomicSetFlags((RpAtomic*)object, 0);
- return object;
-}
-
-static RwFrame*
-RecurseFrameChildrenVisibilityCB(RwFrame* frame, void* data)
-{
- RwFrameForAllObjects(frame, SetPedAtomicVisibilityCB, data);
- RwFrameForAllChildren(frame, RecurseFrameChildrenVisibilityCB, nil);
- return frame;
-}
-
-// --MIAMI: Done
-void
-CPed::RemoveBodyPart(PedNode nodeId, int8 direction)
-{
- RwFrame *frame;
- CVector pos;
-
- frame = m_pFrames[nodeId]->frame;
- if (frame) {
- if (CGame::nastyGame) {
- 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);
-
- for (int i = 0; i < 16; i++) {
- CParticle::AddParticle(PARTICLE_BLOOD_SMALL,
- pos,
- CVector(0.0f, 0.0f, 0.03f),
- nil, 0.0f, 0, 0, 0, 0);
- }
- }
- bBodyPartJustCameOff = true;
- m_bodyPartBleeding = nodeId;
- }
- } else {
- printf("Trying to remove ped component");
- }
-}
-
-// --MIAMI: Done
-void
-CPed::SetLookFlag(CEntity *target, bool keepTryingToLook, bool cancelPrevious)
-{
- if (m_lookTimer < CTimer::GetTimeInMilliseconds() || cancelPrevious) {
- bIsLooking = true;
- bIsRestoringLook = false;
- m_pLookTarget = target;
- m_pLookTarget->RegisterReference((CEntity**)&m_pLookTarget);
- m_fLookDirection = 999999.0f;
- m_lookTimer = 0;
- bKeepTryingToLook = keepTryingToLook;
- if (CanUseTorsoWhenLooking()) {
- m_pedIK.m_flags &= ~CPedIK::LOOKAROUND_HEAD_ONLY;
- }
- }
-}
-
-// --MIAMI: Done
-void
-CPed::SetLookFlag(float direction, bool keepTryingToLook, bool cancelPrevious)
-{
- if (m_lookTimer < CTimer::GetTimeInMilliseconds() || cancelPrevious) {
- bIsLooking = true;
- bIsRestoringLook = false;
- m_fLookDirection = direction;
- m_pLookTarget = nil;
- m_lookTimer = 0;
- bKeepTryingToLook = keepTryingToLook;
- if (CanUseTorsoWhenLooking()) {
- m_pedIK.m_flags &= ~CPedIK::LOOKAROUND_HEAD_ONLY;
- }
- }
-}
-
-// --MIAMI: Done
-void
-CPed::SetLookTimer(int time)
-{
- if (CTimer::GetTimeInMilliseconds() > m_lookTimer) {
- m_lookTimer = CTimer::GetTimeInMilliseconds() + time;
- }
-}
-
-// --MIAMI: Done
-bool
-CPed::OurPedCanSeeThisOne(CEntity *target, bool shootablesDoBlock)
-{
- CColPoint colpoint;
- CEntity *ent;
-
- CVector2D dist = CVector2D(target->GetPosition()) - CVector2D(GetPosition());
-
- // Check if target is behind ped
- if (DotProduct2D(dist, CVector2D(GetForward())) < 0.0f)
- return false;
-
- // Check if target is too far away
- if (dist.Magnitude() >= 40.0f)
- return false;
-
- // Check line of sight from head
- 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
-void
-CPed::Avoid(void)
-{
- CPed *nearestPed;
-
- if(m_pedStats->m_temper > m_pedStats->m_fear && m_pedStats->m_temper > 50)
- return;
-
- if (CTimer::GetTimeInMilliseconds() > m_nPedStateTimer) {
-
- if (m_nMoveState != PEDMOVE_NONE && m_nMoveState != PEDMOVE_STILL) {
- nearestPed = m_nearPeds[0];
-
- if (nearestPed && nearestPed->m_nPedState != PED_DEAD && nearestPed != m_pSeekTarget && nearestPed != m_pedInObjective) {
-
- // Check if this ped wants to avoid the nearest one
- if (CPedType::GetAvoid(m_nPedType) & CPedType::GetFlag(nearestPed->m_nPedType)) {
-
- // Further codes checks whether the distance between us and ped will be equal or below 1.0, if we walk up to him by 1.25 meters.
- // If so, we want to avoid it, so we turn our body 45 degree and look to somewhere else.
-
- // Game converts from radians to degress and back again here, doesn't make much sense
- CVector2D forward(-Sin(m_fRotationCur), Cos(m_fRotationCur));
- forward.Normalise(); // this is kinda pointless
-
- // Move forward 1.25 meters
- CVector2D testPosition = CVector2D(GetPosition()) + forward*1.25f;
-
- // Get distance to ped we want to avoid
- CVector2D distToPed = CVector2D(nearestPed->GetPosition()) - testPosition;
-
- if (distToPed.Magnitude() <= 1.0f && OurPedCanSeeThisOne((CEntity*)nearestPed)) {
- m_nPedStateTimer = CTimer::GetTimeInMilliseconds()
- + 500 + (m_randomSeed + 3 * CTimer::GetFrameCounter())
- % 1000 / 5;
-
- m_fRotationDest += DEGTORAD(45.0f);
- if (!bIsLooking) {
- SetLookFlag(nearestPed, false);
- SetLookTimer(CGeneral::GetRandomNumberInRange(500, 800));
- }
- }
- }
- }
- }
- }
-}
-
-
-// --MIAMI: Done
-void
-CPed::ClearAimFlag(void)
-{
- if (bIsAimingGun) {
- bIsAimingGun = false;
- bIsRestoringGun = true;
- m_pedIK.m_flags &= ~CPedIK::AIMS_WITH_ARM;
- m_lookTimer = 0;
- }
-
- if (IsPlayer())
- ((CPlayerPed*)this)->m_fFPSMoveHeading = 0.0f;
-}
-
-// --MIAMI: Done
-void
-CPed::ClearLookFlag(void) {
- if (bIsLooking) {
- bIsLooking = false;
- bIsRestoringLook = true;
- bShakeFist = false;
-
- if (CanUseTorsoWhenLooking())
- m_pedIK.m_flags &= ~CPedIK::LOOKAROUND_HEAD_ONLY;
-
- if (IsPlayer())
- m_lookTimer = CTimer::GetTimeInMilliseconds() + 2000;
- else
- m_lookTimer = CTimer::GetTimeInMilliseconds() + 4000;
-
- if (m_nPedState == PED_LOOK_HEADING || m_nPedState == PED_LOOK_ENTITY) {
- ClearLook();
- }
- }
-}
-
-// --MIAMI: Done
-bool
-CPed::IsPedHeadAbovePos(float zOffset)
-{
- return zOffset + GetPosition().z < GetNodePosition(PED_HEAD).z;
-}
-
-// --MIAMI: Done
-void
-CPed::FinishedReloadCB(CAnimBlendAssociation *reloadAssoc, void *arg)
-{
- CPed *ped = (CPed*)arg;
- CWeaponInfo *weapon = CWeaponInfo::GetWeaponInfo(ped->GetWeapon()->m_eWeaponType);
-
- 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
-void
-CPed::FinishedAttackCB(CAnimBlendAssociation *attackAssoc, void *arg)
-{
- CAnimBlendAssociation *newAnim, *reloadAnimAssoc = nil;
- CPed *ped = (CPed*)arg;
- CWeaponInfo *currentWeapon = CWeaponInfo::GetWeaponInfo(ped->GetWeapon()->m_eWeaponType);
-
- if (ped->m_nPedState != PED_ATTACK) {
- if (ped->bIsDucking && ped->IsPedInControl()) {
- if (currentWeapon->m_bReload) {
- reloadAnimAssoc = RpAnimBlendClumpGetAssociation(ped->GetClump(), GetCrouchReloadAnim(currentWeapon));
- }
- if (currentWeapon->m_bCrouchFire && 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;
- }
- }
- }
- return;
- }
- 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);
- return;
- }
-
- if (ped->bIsDucking && ped->bCrouchWhenShooting) {
- if (currentWeapon->m_bReload) {
- reloadAnimAssoc = RpAnimBlendClumpGetAssociation(ped->GetClump(), GetCrouchReloadAnim(currentWeapon));
- }
- if (currentWeapon->m_bCrouchFire && 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;
- }
- }
-
- if (!ped->bIsAttacking)
- ped->ClearAttack();
-
- return;
- }
-
- 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);
- }
- }
- }
-
- if (!ped->bIsAttacking)
- ped->ClearAttack();
- }
-}
-
-// --MIAMI: Done except commented things
-void
-CPed::Attack(void)
+CPed::~CPed(void)
{
- CAnimBlendAssociation *weaponAnimAssoc;
- int32 weaponAnim;
- eWeaponType ourWeaponType;
- float weaponAnimTime;
- eWeaponFire ourWeaponFire;
- float animLoopEnd;
- CWeaponInfo *ourWeapon;
- bool attackShouldContinue;
- CAnimBlendAssociation *reloadAnimAssoc;
- CAnimBlendAssociation *throwAssoc;
- float delayBetweenAnimAndFire;
- float animLoopStart;
- CVector firePos;
-
- ourWeaponType = GetWeapon()->m_eWeaponType;
- ourWeapon = CWeaponInfo::GetWeaponInfo(ourWeaponType);
- ourWeaponFire = ourWeapon->m_eWeaponFire;
- weaponAnimAssoc = nil;
- attackShouldContinue = bIsAttacking;
- reloadAnimAssoc = nil;
- throwAssoc = nil;
- animLoopStart = ourWeapon->m_fAnimLoopStart;
- animLoopEnd = ourWeapon->m_fAnimLoopEnd;
- delayBetweenAnimAndFire = ourWeapon->m_fAnimFrameFire;
- weaponAnim = ourWeapon->m_AnimToPlay;
-
- 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 (ourWeapon->m_bReload) {
- reloadAnimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetReloadAnim(ourWeapon));
- }
-
- if (!!ourWeapon->m_bReload && !reloadAnimAssoc) {
- reloadAnimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetCrouchReloadAnim(ourWeapon));
- }
-
- if ( reloadAnimAssoc && reloadAnimAssoc->IsRunning() ) {
- if (!IsPlayer() || ((CPlayerPed*)this)->m_bHaveTargetSelected)
- ClearAttack();
- return;
- }
-
- 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) {
- 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 (!throwAssoc) {
- if (attackShouldContinue) {
- if (ourWeaponFire != WEAPON_FIRE_PROJECTILE || !IsPlayer() || ((CPlayerPed*)this)->m_bHaveTargetSelected) {
- if (bCrouchWhenShooting && bIsDucking && !!ourWeapon->m_bCrouchFire) {
- weaponAnimAssoc = CAnimManager::BlendAnimation(GetClump(), ourWeapon->m_AnimToPlay, 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);
- weaponAnimAssoc->SetRun();
-
- if (weaponAnimAssoc->currentTime == weaponAnimAssoc->hierarchy->totalLength)
- weaponAnimAssoc->SetCurrentTime(0.0f);
-
- if (IsPlayer()) {
- ((CPlayerPed*)this)->m_fAttackButtonCounter = 0.0f;
- ((CPlayerPed*)this)->m_bHaveTargetSelected = false;
- }
- }
- } else
- FinishedAttackCB(nil, this);
-
- }
- 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;
- }
- }
-
- float animStart = ourWeapon->m_fAnimLoopStart * 0.4f;
- weaponAnimTime = weaponAnimAssoc->currentTime;
- if (weaponAnimTime > animStart && weaponAnimTime - weaponAnimAssoc->timeStep <= animStart) {
- 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 (ourWeaponType != WEAPONTYPE_CHAINSAW
- || !meleeAttackStarted && delayBetweenAnimAndFire - 0.5f >= weaponAnimAssoc->currentTime
- || weaponAnimAssoc->currentTime - weaponAnimAssoc->timeStep > delayBetweenAnimAndFire) {
-
- 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;
-
- } else {
- firePos = ourWeapon->m_vecFireOffset;
-
- if (ourWeaponType != WEAPONTYPE_KATANA && ourWeaponType != WEAPONTYPE_CHAINSAW) {
- if (ourWeapon->m_eWeaponFire != WEAPON_FIRE_MELEE) {
- TransformToNode(firePos, (weaponAnimAssoc->animId == ANIM_MELEE_ATTACK_2ND && ourWeapon->m_AnimToPlay == ASSOCGRP_UNARMED) ? PED_FOOTR : PED_HANDR);
- } else {
- firePos = GetMatrix() * firePos;
- }
- } else {
- if (weaponAnimAssoc->animId == ANIM_MELEE_ATTACK_2ND)
- firePos.z = 0.7f * ourWeapon->m_fRadius - 1.0f;
-
- firePos = GetMatrix() * firePos;
- }
-
- GetWeapon()->Fire(this, &firePos);
-
- if (ourWeaponType == WEAPONTYPE_MOLOTOV || ourWeaponType == WEAPONTYPE_GRENADE || ourWeaponType == WEAPONTYPE_DETONATOR_GRENADE ||
- ourWeaponType == WEAPONTYPE_TEARGAS) {
- RemoveWeaponModel(ourWeapon->m_nModelId);
- }
- if (!GetWeapon()->m_nAmmoTotal && ourWeaponFire != WEAPON_FIRE_MELEE && FindPlayerPed() != this) {
- SelectGunIfArmed();
- }
-
- if (GetWeapon()->m_eWeaponState == WEAPONSTATE_MELEE_MADECONTACT) {
- int damagerType = ENTITY_TYPE_NOTHING;
- if (m_pDamageEntity && (m_fDamageImpulse == 0.0f || !m_pDamageEntity->IsBuilding())) {
- damagerType = m_pDamageEntity->GetType();
- }
- switch (ourWeapon->m_AnimToPlay) {
- case ASSOCGRP_UNARMED:
- if (weaponAnimAssoc->animId == ANIM_MELEE_ATTACK || weaponAnimAssoc->animId == ANIM_MELEE_ATTACK_START) {
-#ifdef AUDIO_NOT_READY
- DMAudio.PlayOneShot(m_audioEntityId, SOUND_FIGHT_46, 0.0f);
-#else
- DMAudio.PlayOneShot(m_audioEntityId, SOUND_FIGHT_46, (damagerType | (ourWeaponType << 8)));
-#endif
- }
- break;
- case ASSOCGRP_KNIFE:
- case ASSOCGRP_BASEBALLBAT:
- case ASSOCGRP_GOLFCLUB:
- case ASSOCGRP_CHAINSAW:
-#ifdef AUDIO_NOT_READY
- DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_BAT_ATTACK, 1.0f);
-#else
- DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_BAT_ATTACK, (damagerType | (ourWeaponType << 8)));
-#endif
- break;
- default:
- break;
- }
-
- if (bIsAttacking || CTimer::GetTimeInMilliseconds() < m_shootTimer) {
- weaponAnimAssoc->callbackType = 0;
- }
- }
-
- attackShouldContinue = false;
- }
- } else {
- CVector firePos = ourWeapon->m_vecFireOffset;
-
- if (weaponAnimAssoc->animId == 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 (ourWeapon->m_eWeaponFire == WEAPON_FIRE_INSTANT_HIT && ourWeapon->m_AnimToPlay == ASSOCGRP_SHOTGUN) {
- weaponAnimTime = weaponAnimAssoc->currentTime;
- firePos = ourWeapon->m_vecFireOffset;
-
- if (weaponAnimTime > 1.0f && weaponAnimTime - weaponAnimAssoc->timeStep <= 1.0f && weaponAnimAssoc->IsRunning()) {
- TransformToNode(firePos, PED_HANDR);
-
- CVector gunshellPos(
- firePos.x - 0.6f * GetForward().x,
- firePos.y - 0.6f * GetForward().y,
- firePos.z - 0.15f * GetUp().z
- );
-
- CVector2D gunshellRot(
- GetRight().x,
- GetRight().y
- );
-
- gunshellRot.Normalise();
- GetWeapon()->AddGunshell(this, gunshellPos, gunshellRot, 0.025f);
- }
- }
-
- // TODO(Miami): CSpecialFX::AddWeaponStreak
-
- // Anim breakout on running
- if (IsPlayer()) {
- if (CPad::GetPad(0)->GetSprint()) {
- if (!attackShouldContinue && weaponAnimAssoc->currentTime > ourWeapon->m_fAnimBreakout) {
- weaponAnimAssoc->blendDelta = -4.0f;
- FinishedAttackCB(nil, this);
- return;
- }
- }
- }
-
- 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();
-#ifdef AUDIO_NOT_READY
- DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_AK47_BULLET_ECHO, 0.0f);
-#else
- DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_AK47_BULLET_ECHO, GetWeapon()->m_eWeaponType);
-#endif
- return;
- }
- }
- if (weaponAnimTime - 2.0f * weaponAnimAssoc->timeStep <= animLoopEnd
- && (bIsAttacking || CTimer::GetTimeInMilliseconds() < m_shootTimer)
- && (GetWeapon()->m_eWeaponState != WEAPONSTATE_RELOADING
- || GetWeapon()->m_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())) {
-
- 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 {
- weaponAnimAssoc = CAnimManager::BlendAnimation(GetClump(), ourWeapon->m_AnimToPlay, GetSecondFireAnim(ourWeapon), 8.0f);
- }
- weaponAnimAssoc->SetFinishCallback(FinishedAttackCB, this);
- } else {
- weaponAnimAssoc->SetCurrentTime(animLoopStart);
- weaponAnimAssoc->SetRun();
- }
- }
- } 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 < animLoopEnd) {
-
-#ifdef AUDIO_NOT_READY
- DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_AK47_BULLET_ECHO, 0.0f);
-#else
- DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_AK47_BULLET_ECHO, ourWeaponType);
+#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 being decreased after removing ourself from vehicle.
+ m_pMyVehicle->RemovePassenger(this);
}
-
- // 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::RemoveWeaponModel(int modelId)
-{
- // modelId is not used!! This function just removes the current weapon.
- 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;
- }
- }
-
- 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;
-}
-
-// --MIAMI: Done
-void
-CPed::SetCurrentWeapon(eWeaponType weaponType)
-{
- SetCurrentWeapon(CWeaponInfo::GetWeaponInfo(weaponType)->m_nWeaponSlot);
-}
-
-// --MIAMI: Done
-void
-CPed::SetCurrentWeapon(int slot)
-{
- 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;
-
- if (FindPlayerPed() && IsPlayer())
- ((CPlayerPed*)this)->m_nSelectedWepSlot = m_currentWeapon;
-
- if (HasWeaponSlot(slot)) {
- weaponInfo = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType);
- AddWeaponModel(weaponInfo->m_nModelId);
- }
-}
-
-// --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 < TOTAL_WEAPON_SLOTS; i++) {
- if (GetWeapon(i).m_nAmmoTotal > 0) {
- eWeaponType weaponType = GetWeapon(i).m_eWeaponType;
-
- 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;
- }
- }
- }
- SetCurrentWeapon(WEAPONTYPE_UNARMED);
- return false;
-}
-
-// --MIAMI: Done
-void
-CPed::Duck(void)
-{
- if (CTimer::GetTimeInMilliseconds() > m_duckTimer)
- ClearDuck();
- else if (bIsDucking && bCrouchWhenShooting) {
- CWeaponInfo *weapon = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType);
- CAnimBlendAssociation *attackAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_CROUCH);
- if (!attackAssoc) {
- if(!!weapon->m_bCrouchFire)
- attackAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetCrouchFireAnim(weapon));
- }
- if (!attackAssoc) {
- if(!!weapon->m_bReload)
- attackAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetCrouchReloadAnim(weapon));
- }
- if (!attackAssoc) {
- bIsDucking = false;
- }
- }
-}
-
-// --MIAMI: Done
-void
-CPed::ClearDuck(bool clearTimer)
-{
- CAnimBlendAssociation *animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DUCK_DOWN);
- if (!animAssoc) {
- animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DUCK_LOW);
- }
- if (!animAssoc) {
- animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_CROUCH);
- }
-
- if (animAssoc) {
- animAssoc->flags |= ASSOC_DELETEFADEDOUT;
- animAssoc->blendDelta = -4.0f;
- }
- bIsDucking = false;
-
- if (clearTimer) {
- m_duckTimer = 0;
- }
-}
-
-// --MIAMI: Done
-void
-CPed::ClearPointGunAt(void)
-{
- CAnimBlendAssociation *animAssoc;
- CWeaponInfo *weaponInfo;
-
- ClearLookFlag();
- ClearAimFlag();
- bIsPointingGunAt = false;
- if (m_nPedState == PED_AIM_GUN || m_nPedState == PED_ATTACK) {
- SetPedState(PED_IDLE);
- RestorePreviousState();
- }
- weaponInfo = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType);
- animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_FIRE);
- if (!animAssoc || animAssoc->blendDelta < 0.0f) {
- if (!!weaponInfo->m_bCrouchFire) {
- animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetCrouchFireAnim(weaponInfo));
- }
- }
- if (animAssoc) {
- animAssoc->flags |= ASSOC_DELETEFADEDOUT;
- animAssoc->blendDelta = -4.0f;
- }
-}
-
-// --MIAMI: Done
-void
-CPed::BeingDraggedFromCar(void)
-{
- AnimationId enterAnim;
- bool dontRunAnim = false;
-
- if (!m_pVehicleAnim) {
- 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(), assocGroup, enterAnim);
-
- m_pVehicleAnim->SetFinishCallback(PedSetDraggedOutCarCB, this);
-
- 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);
- LineUpPedWithCar(LINE_UP_TO_CAR_START);
-
- } else {
- LineUpPedWithCar(LINE_UP_TO_CAR_2);
- }
-
- static float mult = 5.f;
- if (m_objective == OBJECTIVE_LEAVE_CAR_AND_DIE) {
- if (m_pMyVehicle) {
- m_pMyVehicle->ProcessOpenDoor(m_vehEnterType, NUM_STD_ANIMS, m_pVehicleAnim->currentTime * mult);
- }
+ if (m_nPedState == PED_EXIT_CAR || m_nPedState == PED_DRAG_FROM_CAR)
+ m_pMyVehicle->m_nGettingOutFlags &= ~door_flag;
+ bInVehicle = false;
+ m_pMyVehicle = nil;
+ } else if (EnteringCar()) {
+ QuitEnteringCar();
}
-}
-
-// --MIAMI: Done
-void
-CPed::RestartNonPartialAnims(void)
-{
- CAnimBlendAssociation *assoc;
+ if (m_pFire)
+ m_pFire->Extinguish();
- for (assoc = RpAnimBlendClumpGetFirstAssociation(GetClump()); assoc; assoc = RpAnimBlendGetNextAssociation(assoc)) {
- if (!assoc->IsPartial())
- assoc->SetRun();
- }
+ ClearWeapons();
+ if (bCarPassenger)
+ CPopulation::ms_nTotalCarPassengerPeds--;
+ if (bMiamiViceCop)
+ CPopulation::NumMiamiViceCops--;
+ CPopulation::UpdatePedCount((ePedType)m_nPedType, true);
+ DMAudio.DestroyEntity(m_audioEntityId);
}
// --MIAMI: Done
void
-CPed::PedSetDraggedOutCarCB(CAnimBlendAssociation *dragAssoc, void *arg)
-{
- CAnimBlendAssociation *quickJackedAssoc;
- 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)
- dragAssoc->blendDelta = -1000.0f;
- }
- ped->RestartNonPartialAnims();
- ped->m_pVehicleAnim = nil;
- ped->m_pSeekTarget = nil;
- vehicle = ped->m_pMyVehicle;
-
- 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)
- vehicle->m_nDoorLock = CARLOCK_UNLOCKED;
-
- if (ped->m_nPedType == PEDTYPE_COP && vehicle->IsLawEnforcementVehicle())
- vehicle->ChangeLawEnforcerState(false);
- } else {
- vehicle->RemovePassenger(ped);
- }
- }
- ped->bInVehicle = false;
- if (ped->IsPlayer())
- AudioManager.PlayerJustLeftCar();
-
- 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;
- }
-
- if (quickJackedAssoc) {
- dragAssoc->SetDeleteCallback(PedSetQuickDraggedOutCarPositionCB, ped);
- } else {
- dragAssoc->SetDeleteCallback(PedSetDraggedOutCarPositionCB, ped);
- if (ped->CanSetPedState())
- CAnimManager::BlendAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_GETUP1, 1000.0f);
- }
-
- ped->ReplaceWeaponWhenExitingVehicle();
-
- ped->m_nStoredMoveState = PEDMOVE_NONE;
- ped->bVehExitWillBeInstant = false;
-}
-
-// --MIAMI: Done
-CVector
-CPed::GetLocalPositionToOpenCarDoor(CVehicle *veh, uint32 component, float seatPosMult)
-{
- CVehicleModelInfo *vehModel;
- CVector vehDoorPos;
- CVector vehDoorOffset;
- float seatOffset;
-
- vehModel = (CVehicleModelInfo *)CModelInfo::GetModelInfo(veh->GetModelIndex());
-
- 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 {
- if (veh->bIsVan && (component == CAR_DOOR_LR || component == CAR_DOOR_RR)) {
- seatOffset = 0.0f;
- vehDoorOffset = vecPedVanRearDoorAnimOffset;
- } else {
- 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;
-
- 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_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);
- }
- return vehDoorPos - vehDoorOffset;
- }
-}
-
-// --MIAMI: Done
-CVector
-CPed::GetPositionToOpenCarDoor(CVehicle *veh, uint32 component)
+CPed::Initialise(void)
{
- CVector vehDoorPos = GetPositionToOpenCarDoor(veh, component, 1.0f);
-
-/*
- // Unused
- vehDoorPosWithoutOffset = veh->GetMatrix() * localVehDoorPos;
-*/
- return vehDoorPos;
-}
-
-// --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;
+ debug("Initialising CPed...\n");
+ CPedType::Initialise();
+ LoadFightData();
+ SetAnimOffsetForEnterOrExitVehicle();
+ debug("CPed ready\n");
}
// --MIAMI: Done
void
-CPed::LineUpPedWithCar(PedLineUpPhase phase)
+CPed::SetModelIndex(uint32 mi)
{
- bool vehIsUpsideDown = false;
- int vehAnim;
- float seatPosMult = 0.0f;
- float currentZ;
- float adjustedTimeStep;
- CVector autoZPos;
-
- if (CReplay::IsPlayingBack())
- return;
-
- if (!bChangedSeat && phase != LINE_UP_TO_CAR_2) {
- 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;
- }
- }
- 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 (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);
- }
- }
- }
- return;
- }
- if (phase == LINE_UP_TO_CAR_START) {
- m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f);
- }
- CVehicle *veh = m_pMyVehicle;
-
- // Not quite right, IsUpsideDown func. checks for <= -0.9f.
- if (veh->GetUp().z <= -0.8f)
- vehIsUpsideDown = true;
-
- if (m_vehEnterType == CAR_DOOR_RF || m_vehEnterType == CAR_DOOR_RR) {
- if (vehIsUpsideDown) {
- m_fRotationDest = -PI + veh->GetForward().Heading();
- } else if (veh->bIsBus) {
- m_fRotationDest = 0.5f * PI + veh->GetForward().Heading();
- } else {
- m_fRotationDest = veh->GetForward().Heading();
- }
- } else if (m_vehEnterType == CAR_DOOR_LF || m_vehEnterType == CAR_DOOR_LR) {
- if (vehIsUpsideDown) {
- m_fRotationDest = veh->GetForward().Heading();
- } else if (veh->bIsBus) {
- m_fRotationDest = -0.5f * PI + veh->GetForward().Heading();
- } else {
- m_fRotationDest = veh->GetForward().Heading();
- }
- } else {
- // I don't know will this part ever run(maybe boats?), but the game also handles that. I don't know is it intentional.
-
- if (vehIsUpsideDown) {
- 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();
- }
- }
-
- bool multExtractedFromAnim = false;
- bool multExtractedFromAnimBus = false;
- float zBlend;
- if (m_pVehicleAnim) {
- vehAnim = m_pVehicleAnim->animId;
-
- switch (vehAnim) {
- case ANIM_CAR_JACKED_RHS:
- case ANIM_CAR_LJACKED_RHS:
- case ANIM_CAR_JACKED_LHS:
- case ANIM_CAR_LJACKED_LHS:
- case ANIM_VAN_GETIN_L:
- case ANIM_VAN_GETIN:
- multExtractedFromAnim = true;
- zBlend = Max(m_pVehicleAnim->GetProgress() - 0.3f, 0.0f) / (1.0f - 0.3f);
- // fall through
-
- 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:
-
- if (!multExtractedFromAnim) {
- multExtractedFromAnim = true;
- zBlend = Max(m_pVehicleAnim->GetProgress() - 0.5f, 0.0f) / (1.0f - 0.5f);
- }
- // fall through
-
- case ANIM_CAR_CRAWLOUT_RHS:
- case ANIM_CAR_CRAWLOUT_RHS2:
- case ANIM_VAN_GETOUT_L:
- case ANIM_VAN_GETOUT:
- 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:
- if (veh && veh->IsCar() && veh->bIsBus) {
- multExtractedFromAnimBus = true;
- zBlend = Min(m_pVehicleAnim->GetProgress(), 0.5f) / 0.5f;
- }
- // fall through
-
- case ANIM_CAR_QJACK:
- case ANIM_CAR_GETIN_LOW_LHS:
- case ANIM_CAR_GETIN_LOW_RHS:
- case ANIM_DRIVE_BOAT:
- seatPosMult = m_pVehicleAnim->GetTimeLeft() / m_pVehicleAnim->hierarchy->totalLength;
- break;
- case ANIM_CAR_CLOSEDOOR_LHS:
- case ANIM_CAR_CLOSEDOOR_LOW_LHS:
- case ANIM_CAR_CLOSEDOOR_RHS:
- case ANIM_CAR_CLOSEDOOR_LOW_RHS:
- case ANIM_CAR_SHUFFLE_RHS:
- 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:
- case ANIM_COACH_OPEN_R:
- case ANIM_COACH_IN_L:
- case ANIM_COACH_IN_R:
- case ANIM_COACH_OUT_L:
- 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;
-
- if (phase == LINE_UP_TO_CAR_2) {
- neededPos = GetPosition();
- } else {
- neededPos = GetPositionToOpenCarDoor(veh, m_vehEnterType, seatPosMult);
- }
-
- autoZPos = neededPos;
-
- if (veh->bIsInWater) {
- if (veh->m_vehType == VEHICLE_TYPE_BOAT && veh->IsUpsideDown())
- autoZPos.z += 1.0f;
- } else {
- CPedPlacement::FindZCoorForPed(&autoZPos);
- }
-
- if (phase == LINE_UP_TO_CAR_END || phase == LINE_UP_TO_CAR_2) {
- neededPos.z = GetPosition().z;
-
- // Getting out
- if (!veh->bIsBus || (veh->bIsBus && vehIsUpsideDown)) {
- float nextZSpeed = m_vecMoveSpeed.z - GRAVITY * CTimer::GetTimeStep();
-
- // If we're not in ground at next step, apply animation
- if (neededPos.z + nextZSpeed >= autoZPos.z) {
- m_vecMoveSpeed.z = nextZSpeed;
- ApplyMoveSpeed();
- // Removing below line breaks the animation
- neededPos.z = GetPosition().z;
- } else {
- neededPos.z = autoZPos.z;
- m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f);
- }
- }
- }
-
- if (autoZPos.z > neededPos.z) {
- 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 {
- 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;
- m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f);
- } else if (neededPos.z <= currentZ && m_pVehicleAnim && vehAnim != ANIM_VAN_CLOSE_L && vehAnim != ANIM_VAN_CLOSE) {
- adjustedTimeStep = Min(m_pVehicleAnim->timeStep, 0.1f);
-
- // Smoothly change ped position
- neededPos.z = currentZ - (currentZ - neededPos.z) / (m_pVehicleAnim->GetTimeLeft() / adjustedTimeStep);
- }
- }
- } else {
- // We may need to raise up the ped
- if (phase == LINE_UP_TO_CAR_START) {
- currentZ = GetPosition().z;
-
- if (neededPos.z > currentZ) {
- if (multExtractedFromAnimBus) {
- neededPos.z = (neededPos.z - currentZ) * zBlend + currentZ;
- } else {
- 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)) {
- adjustedTimeStep = Min(m_pVehicleAnim->timeStep, 0.1f);
-
- // Smoothly change ped position
- neededPos.z = (neededPos.z - currentZ) / (m_pVehicleAnim->GetTimeLeft() / adjustedTimeStep) + currentZ;
- } else if (EnteringCar() || m_nPedState == PED_DRIVING && veh->IsBike()) {
- neededPos.z = Max(currentZ, autoZPos.z);
- }
- }
- }
- }
- }
-
- bool stillGettingInOut = false;
- if (CTimer::GetTimeInMilliseconds() < m_nPedStateTimer)
- stillGettingInOut = veh->m_vehType != VEHICLE_TYPE_BOAT || bOnBoat;
-
- if (!stillGettingInOut) {
- m_fRotationCur = m_fRotationDest;
- } else {
- float limitedDest = CGeneral::LimitRadianAngle(m_fRotationDest);
- float timeUntilStateChange = (m_nPedStateTimer - CTimer::GetTimeInMilliseconds())/600.0f;
-
- if (timeUntilStateChange <= 0.0f) {
- m_vecOffsetSeek.x = 0.0f;
- m_vecOffsetSeek.y = 0.0f;
- }
- m_vecOffsetSeek.z = 0.0f;
-
- neededPos -= timeUntilStateChange * m_vecOffsetSeek;
-
- if (PI + m_fRotationCur < limitedDest) {
- limitedDest -= 2 * PI;
- } else if (m_fRotationCur - PI > limitedDest) {
- limitedDest += 2 * PI;
- }
- m_fRotationCur -= (m_fRotationCur - limitedDest) * (1.0f - timeUntilStateChange);
- }
+ CEntity::SetModelIndex(mi);
+ RpAnimBlendClumpInit(GetClump());
+ RpAnimBlendClumpFillFrameArray(GetClump(), m_pFrames);
+ CPedModelInfo *modelInfo = (CPedModelInfo *)CModelInfo::GetModelInfo(GetModelIndex());
+ SetPedStats(modelInfo->m_pedStatType);
+ m_headingRate = m_pedStats->m_headingChangeRate;
+ m_animGroup = (AssocGroupId) modelInfo->m_animGroup;
+ CAnimManager::AddAnimation(GetClump(), m_animGroup, ANIM_IDLE_STANCE);
- 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));
-
- 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);
+ if (!CanUseTorsoWhenLooking())
+ m_pedIK.m_flags |= CPedIK::LOOKAROUND_HEAD_ONLY;
- vehDoorMat = vehDoorMat * correctionMat;
- }
- GetMatrix() = vehDoorMat;
- }
+ // This is a mistake by R*, velocity is CVector, whereas m_vecAnimMoveDelta is CVector2D.
+ (*RPANIMBLENDCLUMPDATA(m_rwObject))->velocity = (CVector*) &m_vecAnimMoveDelta;
-}
+ if(modelInfo->GetHitColModel() == nil)
+ modelInfo->CreateHitColModelSkinned(GetClump());
-// --MIAMI: Done
-static void
-particleProduceFootDust(CPed *ped, CVector const &pos, float size, int times)
-{
- switch (ped->m_nSurfaceTouched)
+ UpdateRpHAnim();
+#ifdef USE_CUTSCENE_SHADOW_FOR_PED
+ if (!m_pRTShadow)
{
- case SURFACE_TARMAC:
- 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;
- default:
- break;
- }
-}
-
-// --MIAMI: Done
-static void
-particleProduceFootSplash(CPed *ped, CVector const &pos, float size, int times)
-{
- 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);
-
- 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);
+ 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::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--;
-
- if (m_bloodyFootprintCountOrDeathTime == 0)
- bDoBloodyFootprints = false;
- }
- }
-
- if (!bIsStanding)
- return;
-
- for (; assoc; assoc = RpAnimBlendGetNextAssociation(assoc)) {
- if (assoc->flags & ASSOC_WALK) {
- walkRunAssoc = assoc;
- walkRunAssocBlend += assoc->blendAmount;
- } else if ((assoc->flags & ASSOC_NOWALK) == 0) {
- idleAssocBlend += assoc->blendAmount;
- }
- }
-
- if (walkRunAssoc && walkRunAssocBlend > 0.5f && idleAssocBlend < 1.0f) {
-
- float stepStart = 1.f / 15.f;
- float stepEnd = walkRunAssoc->hierarchy->totalLength / 2.0f + stepStart;
- float currentTime = walkRunAssoc->currentTime;
-
- 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 (bDoBloodyFootprints) {
- CVector2D top(forward * 0.26f);
- CVector2D right(GetRight() * (stepPart == 1 ? 0.14f : 0.1f));
-
- CShadows::AddPermanentShadow(SHADOWTYPE_DARK, gpBloodPoolTex, &adjustedFootPos,
- top.x, top.y,
- right.x, right.y,
- 255, 255, 0, 0, 4.0f, 3000, 1.0f);
-
- if (m_bloodyFootprintCountOrDeathTime <= 20) {
- m_bloodyFootprintCountOrDeathTime = 0;
- bDoBloodyFootprints = false;
- } else {
- m_bloodyFootprintCountOrDeathTime -= 20;
- }
- }
- if (m_nSurfaceTouched == SURFACE_SAND || m_nSurfaceTouched == SURFACE_SAND_BEACH) {
- CVector2D top(forward * -0.26f);
- CVector2D right(GetRight() * (stepPart == 1 ? 0.1f : 0.14f));
-
- CShadows::AddPermanentShadow(SHADOWTYPE_DARK, gpShadowPedTex, &adjustedFootPos,
- top.x, top.y,
- right.x, right.y,
- 120, 250, 250, 50, 4.0f, 5000, 1.0f);
- }
- if (CWeather::Rain <= 0.1f || CCullZones::CamNoRain() || CCullZones::PlayerNoRain()) {
- if (IsPlayer())
- particleProduceFootDust(this, adjustedFootPos, 0.0f, 4);
-
- } else if (stepPart == 2) {
- particleProduceFootSplash(this, adjustedFootPos, 0.15f, 4);
- }
- }
- }
- }
-
- if (IsPlayer() && !walkRunAssoc && bIsLanding) {
- if (!footPosLok)
- TransformToNode(footPosL, PED_FOOTL);
-
- CVector forward = GetForward();
-
- CVector adjustedFootPosL = footPosL;
- adjustedFootPosL.z -= 0.1f;
- adjustedFootPosL += 0.2f * forward;
- if (bDoBloodyFootprints) {
- CVector2D top(forward * 0.26f);
- CVector2D right(GetRight() * 0.14f);
-
- CShadows::AddPermanentShadow(SHADOWTYPE_DARK, gpBloodPoolTex, &adjustedFootPosL,
- top.x, top.y,
- right.x, right.y,
- 255, 255, 0, 0, 4.0f, 3000, 1.0f);
-
- if (m_bloodyFootprintCountOrDeathTime <= 20) {
- m_bloodyFootprintCountOrDeathTime = 0;
- bDoBloodyFootprints = false;
- }
- else {
- m_bloodyFootprintCountOrDeathTime -= 20;
- }
- }
- if (!isSkater) {
- if (m_nSurfaceTouched == SURFACE_SAND || m_nSurfaceTouched == SURFACE_SAND_BEACH) {
- CVector2D top(forward * -0.26f);
- CVector2D right(GetRight() * 0.14f);
-
- CShadows::AddPermanentShadow(SHADOWTYPE_DARK, gpShadowPedTex, &adjustedFootPosL,
- top.x, top.y,
- right.x, right.y,
- 120, 250, 250, 50, 4.0f, 5000, 1.0f);
- }
- }
- 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;
- }
- }
- 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) {
- float particleSize = pedSpeed * 2.0f;
-
- if (particleSize < 0.25f)
- particleSize = 0.25f;
-
- if (particleSize > 0.75f)
- particleSize = 0.75f;
-
- CVector particlePos = GetPosition() + GetForward() * 0.3f;
- particlePos.z -= 1.2f;
-
- CVector particleDir = m_vecMoveSpeed * -0.75f;
-
- particleDir.z = CGeneral::GetRandomNumberInRange(0.01f, 0.03f);
- 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);
- }
-
- 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
-bool
-CPed::IsPointerValid(void)
+CPed::SetPedStats(ePedStats pedStat)
{
- int pedIndex = CPools::GetPedPool()->GetIndex(this) >> 8;
- if (pedIndex < 0 || pedIndex >= NUMPEDS)
- return false;
-
- if (m_entryInfoList.first || FindPlayerPed() == this)
- return true;
-
- return false;
+ m_pedStats = CPedStats::ms_apPedStats[pedStat];
}
// --MIAMI: Done
-// Some kind of binary sort
void
-CPed::SortPeds(CPed **list, int min, int max)
+CPed::DeleteRwObject()
{
- if (min >= max)
- return;
-
- CVector leftDiff, rightDiff;
- CVector middleDiff = GetPosition() - list[(max + min) / 2]->GetPosition();
- float middleDist = middleDiff.Magnitude();
-
- int left = max;
- int right = min;
- while(right <= left){
- float rightDist, leftDist;
- do {
- rightDiff = GetPosition() - list[right]->GetPosition();
- rightDist = rightDiff.Magnitude();
- } while (middleDist > rightDist && ++right);
-
- do {
- leftDiff = GetPosition() - list[left]->GetPosition();
- leftDist = leftDiff.Magnitude();
- } while (middleDist < leftDist && left--);
-
- if (right <= left) {
- CPed *ped = list[right];
- list[right] = list[left];
- list[left] = ped;
- right++;
- left--;
- }
- }
- SortPeds(list, min, left);
- SortPeds(list, right, max);
+ CEntity::DeleteRwObject();
}
// --MIAMI: Done
@@ -2763,1393 +542,207 @@ CPed::BuildPedLists(void)
}
// --MIAMI: Done
-void
-CPed::SetPedStats(ePedStats pedStat)
-{
- m_pedStats = CPedStats::ms_apPedStats[pedStat];
-}
-
-// --MIAMI: Done
bool
-CPed::CanUseTorsoWhenLooking(void)
-{
- return m_nPedState != PED_DRIVING && m_nPedState != PED_DRAG_FROM_CAR && !bIsDucking &&
- m_animGroup != ASSOCGRP_SEXYWOMAN && m_animGroup != ASSOCGRP_WOMAN;
-}
-
-// --MIAMI: Done
-void
-CPed::SetModelIndex(uint32 mi)
-{
- CEntity::SetModelIndex(mi);
- RpAnimBlendClumpInit(GetClump());
- RpAnimBlendClumpFillFrameArray(GetClump(), m_pFrames);
- CPedModelInfo *modelInfo = (CPedModelInfo *)CModelInfo::GetModelInfo(GetModelIndex());
- SetPedStats(modelInfo->m_pedStatType);
- m_headingRate = m_pedStats->m_headingChangeRate;
- 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;
-
- 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::RemoveLighting(bool reset)
-{
- if (!bRenderScorched) {
- CRenderer::RemoveVehiclePedLights(this, reset);
- if (reset)
- ReSetAmbientAndDirectionalColours();
- }
- SetAmbientColours();
- DeActivateDirectional();
-}
-
-// --MIAMI: Done
-bool
-CPed::SetupLighting(void)
-{
- ActivateDirectional();
- SetAmbientColoursForPedsCarsAndObjects();
-
-#ifndef MASTER
- // Originally this was being called through iteration of Sectors, but putting it here is better.
- if (GetDebugDisplay() != 0 && !IsPlayer())
- DebugRenderOnePedText();
-#endif
-
- if (bRenderScorched) {
- WorldReplaceNormalLightsWithScorched(Scene.world, 0.1f);
- } 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 (lightMult != 1.0f) {
- SetAmbientAndDirectionalColours(lightMult);
- return true;
- }
- }
- return false;
-}
-
-// --MIAMI: Done
-void
-CPed::Teleport(CVector pos)
-{
- CWorld::Remove(this);
- SetPosition(pos);
- bIsStanding = false;
- m_nPedStateTimer = 0;
- m_actionX = 0.0f;
- m_actionY = 0.0f;
- m_pDamageEntity = nil;
- CWorld::Add(this);
-}
-
-// --MIAMI: Done
-void
-CPed::CalculateNewOrientation(void)
-{
- if (CReplay::IsPlayingBack() || !IsPedInControl())
- return;
-
- SetHeading(m_fRotationCur);
-}
-
-// --MIAMI: Done
-float
-CPed::WorkOutHeadingForMovingFirstPerson(float offset)
-{
- if (!IsPlayer())
- return 0.0f;
-
- CPad *pad0 = CPad::GetPad(0);
- float leftRight = pad0->GetPedWalkLeftRight();
- float upDown = pad0->GetPedWalkUpDown();
- float &angle = ((CPlayerPed*)this)->m_fWalkAngle;
-
- if (upDown != 0.0f) {
- angle = CGeneral::GetRadianAngleBetweenPoints(0.0f, 0.0f, -leftRight, upDown);
- } else {
- if (leftRight < 0.0f)
- angle = HALFPI;
- else if (leftRight > 0.0f)
- angle = -HALFPI;
- }
-
- return CGeneral::LimitRadianAngle(offset + angle);
-}
-
-// --MIAMI: Done
-void
-CPed::CalculateNewVelocity(void)
+CPed::OurPedCanSeeThisOne(CEntity *target, bool shootablesDoBlock)
{
- if (IsPedInControl()) {
- float headAmount = DEGTORAD(m_headingRate) * CTimer::GetTimeStep();
- m_fRotationCur = CGeneral::LimitRadianAngle(m_fRotationCur);
- float limitedRotDest = CGeneral::LimitRadianAngle(m_fRotationDest);
-
- if (m_fRotationCur - PI > limitedRotDest) {
- limitedRotDest += 2 * PI;
- } else if(PI + m_fRotationCur < limitedRotDest) {
- limitedRotDest -= 2 * PI;
- }
-
- float neededTurn = limitedRotDest - m_fRotationCur;
- if (neededTurn <= headAmount) {
- if (neededTurn > (-headAmount))
- m_fRotationCur += neededTurn;
- else
- m_fRotationCur -= headAmount;
- } else {
- m_fRotationCur += headAmount;
- }
- }
-
- CVector2D forward(Sin(m_fRotationCur), Cos(m_fRotationCur));
-
- m_moved.x = CrossProduct2D(m_vecAnimMoveDelta, forward); // (m_vecAnimMoveDelta.x * Cos(m_fRotationCur)) + -Sin(m_fRotationCur) * m_vecAnimMoveDelta.y;
- m_moved.y = DotProduct2D(m_vecAnimMoveDelta, forward); // m_vecAnimMoveDelta.y* Cos(m_fRotationCur) + (m_vecAnimMoveDelta.x * Sin(m_fRotationCur));
-
- if (CTimer::GetTimeStep() >= 0.01f) {
- m_moved = m_moved * (1 / CTimer::GetTimeStep());
- } else {
- m_moved = m_moved * (1 / 100.0f);
- }
-
- if ((!TheCamera.Cams[TheCamera.ActiveCam].GetWeaponFirstPersonOn() && !TheCamera.Cams[0].Using3rdPersonMouseCam())
- || FindPlayerPed() != this || !CanStrafeOrMouseControl()) {
-
- if (FindPlayerPed() == this)
- FindPlayerPed()->m_fWalkAngle = 0.0f;
- return;
- }
-
- float walkAngle = WorkOutHeadingForMovingFirstPerson(m_fRotationCur);
- float pedSpeed = m_moved.Magnitude();
- float localWalkAngle = CGeneral::LimitRadianAngle(walkAngle - m_fRotationCur);
-
- if (localWalkAngle < -0.5f * PI) {
- localWalkAngle += PI;
- } else if (localWalkAngle > 0.5f * PI) {
- localWalkAngle -= PI;
- }
-
- // Interestingly this part is responsible for diagonal walking.
- if (localWalkAngle > -DEGTORAD(50.0f) && localWalkAngle < DEGTORAD(50.0f)) {
- TheCamera.Cams[TheCamera.ActiveCam].m_fPlayerVelocity = pedSpeed;
- m_moved = CVector2D(-Sin(walkAngle), Cos(walkAngle)) * pedSpeed;
- }
-
- CAnimBlendAssociation *idleAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_STANCE);
- CAnimBlendAssociation *fightAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_FIGHT_IDLE);
- if(!fightAssoc)
- fightAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_TIRED);
-
- if(!fightAssoc)
- fightAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_CROUCHRELOAD);
-
- if ((!idleAssoc || idleAssoc->blendAmount < 0.5f) && !fightAssoc && !bIsDucking) {
- LimbOrientation newUpperLegs;
- newUpperLegs.yaw = localWalkAngle;
-
- if (newUpperLegs.yaw < -DEGTORAD(100.0f)) {
- newUpperLegs.yaw += PI;
- } else if (newUpperLegs.yaw > DEGTORAD(100.0f)) {
- newUpperLegs.yaw -= PI;
- }
+ CColPoint colpoint;
+ CEntity *ent;
- if (newUpperLegs.yaw > -DEGTORAD(50.0f) && newUpperLegs.yaw < DEGTORAD(50.0f)) {
- 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;
- }
- }
-}
+ CVector2D dist = CVector2D(target->GetPosition()) - CVector2D(GetPosition());
-// --MIAMI: Done, but what is TODO_CHAR??
-bool
-CPed::CanBeDeleted(void)
-{
- if (bInVehicle)
+ // Check if target is behind ped
+ if (DotProduct2D(dist, CVector2D(GetForward())) < 0.0f)
return false;
- switch (CharCreatedBy) {
- case RANDOM_CHAR:
- return true;
- case MISSION_CHAR:
- return false;
- case TODO_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 TODO_CHAR:
- return false;
- default:
- return true;
- }
-}
-
-// --MIAMI: Done
-bool
-CPed::CanPedDriveOff(void)
-{
- if (m_nPedState != PED_DRIVING || m_lookTimer > CTimer::GetTimeInMilliseconds())
+ // Check if target is too far away
+ if (dist.Magnitude() >= 40.0f)
return false;
- for (int i = 0; i < m_numNearPeds; i++) {
- CPed *nearPed = m_nearPeds[i];
- if (nearPed->m_nPedType == m_nPedType && nearPed->m_objective == OBJECTIVE_ENTER_CAR_AS_PASSENGER && nearPed->m_carInObjective == m_carInObjective) {
- m_lookTimer = CTimer::GetTimeInMilliseconds() + 1000;
- return false;
- }
- }
- return true;
-}
-
-// --MIAMI: Done
-bool
-CPed::CanPedJumpThis(CEntity *unused, CVector *damageNormal = nil)
-{
- if (m_nSurfaceTouched == SURFACE_WATER)
- return true;
-
- CVector pos = GetPosition();
- CVector forwardOffset = GetForward();
- if (damageNormal && damageNormal->z > 0.17f) {
- if (damageNormal->z > 0.9f)
- return false;
-
- 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();
- if (damageNormal->z > 0.5f) {
- CVector invDamageNormal(-damageNormal->x, -damageNormal->y, 0.0f);
- invDamageNormal *= 1.0f / collPower;
- CVector estimatedJumpDist = invDamageNormal + collPower * invDamageNormal * ourCol->spheres->radius;
- forwardOffset = estimatedJumpDist * Min(2.0f / collPower, 4.0f);
- } else {
- forwardOffset += collPower * ourCol->spheres->radius * forwardOffset;
- }
- } else {
- pos.z -= 0.15f;
- }
-
- CVector forwardPos = pos + forwardOffset;
- return CWorld::GetIsLineOfSightClear(pos, forwardPos, true, false, false, true, false, false, false);
-}
-
-// --MIAMI: Done
-bool
-CPed::CanPedReturnToState(void)
-{
- return m_nPedState <= PED_STATES_NO_AI && m_nPedState != PED_AIM_GUN && m_nPedState != PED_ATTACK &&
- m_nPedState != PED_FIGHT && m_nPedState != PED_STEP_AWAY && m_nPedState != PED_SNIPER_MODE && m_nPedState != PED_LOOK_ENTITY;
-}
-
-// --MIAMI: Done
-bool
-CPed::CanSeeEntity(CEntity *entity, float threshold = CAN_SEE_ENTITY_ANGLE_THRESHOLD)
-{
- float neededAngle = CGeneral::GetRadianAngleBetweenPoints(
- entity->GetPosition().x,
- entity->GetPosition().y,
- GetPosition().x,
- GetPosition().y);
-
- if (neededAngle < 0.0f)
- neededAngle += TWOPI;
- else if (neededAngle > TWOPI)
- neededAngle -= TWOPI;
-
- float ourAngle = m_fRotationCur;
- if (ourAngle < 0.0f)
- ourAngle += TWOPI;
- else if (ourAngle > TWOPI)
- ourAngle -= TWOPI;
-
- float neededTurn = Abs(neededAngle - ourAngle);
-
- return neededTurn < threshold || TWOPI - threshold < neededTurn;
-}
-
-// --MIAMI: Done
-bool
-CPed::IsTemporaryObjective(eObjective objective)
-{
- return objective == OBJECTIVE_LEAVE_CAR || objective == OBJECTIVE_SET_LEADER ||
- objective == OBJECTIVE_LEAVE_CAR_AND_DIE || objective == OBJECTIVE_ENTER_CAR_AS_DRIVER ||
- objective == OBJECTIVE_ENTER_CAR_AS_PASSENGER;
-}
-
-// --MIAMI: Done
-void
-CPed::SetMoveState(eMoveState state)
-{
- m_nMoveState = state;
-}
-
-// --MIAMI: Done
-void
-CPed::SetObjectiveTimer(int time)
-{
- if (time == 0) {
- m_objectiveTimer = 0;
- } else if (CTimer::GetTimeInMilliseconds() > m_objectiveTimer) {
- m_objectiveTimer = CTimer::GetTimeInMilliseconds() + time;
- }
-}
-
-// --MIAMI: Done
-void
-CPed::ForceStoredObjective(eObjective objective)
-{
- if (objective != OBJECTIVE_ENTER_CAR_AS_DRIVER && objective != OBJECTIVE_ENTER_CAR_AS_PASSENGER) {
- m_prevObjective = m_objective;
- return;
- }
-
- 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
-void
-CPed::SetStoredObjective(void)
-{
- if (m_objective == m_prevObjective)
- return;
-
- 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::RestorePreviousObjective(void)
-{
- if (m_objective == OBJECTIVE_NONE)
- return;
-
- if (m_objective != OBJECTIVE_LEAVE_CAR && m_objective != OBJECTIVE_ENTER_CAR_AS_PASSENGER && m_objective != OBJECTIVE_ENTER_CAR_AS_DRIVER
- && m_nPedState != PED_CARJACK)
- m_pedInObjective = nil;
-
- if (m_objective == OBJECTIVE_WAIT_IN_CAR_THEN_GET_OUT) {
- m_objective = OBJECTIVE_NONE;
- if (m_pMyVehicle)
- SetObjective(OBJECTIVE_LEAVE_CAR, m_pMyVehicle);
-
- } else {
- m_objective = m_prevObjective;
- m_prevObjective = OBJECTIVE_NONE;
- }
- bObjectiveCompleted = false;
-}
-
-// --MIAMI: Done
-void
-CPed::SetLeader(CEntity *leader)
-{
- m_leader = (CPed*)leader;
-
- if (m_leader) {
- m_leader->bIsLeader = true;
- m_leader->RegisterReference((CEntity**)&m_leader);
- }
+ // Check line of sight from head
+ 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::SetObjective(eObjective newObj, void *entity)
+CPed::SortPeds(CPed **list, int min, int max)
{
- if (DyingOrDead())
- return;
-
- if (m_prevObjective == newObj && m_prevObjective != OBJECTIVE_NONE)
- return;
-
- if (entity == this)
- return;
-
- if (m_attachedTo && newObj != OBJECTIVE_KILL_CHAR_ON_FOOT && newObj != OBJECTIVE_KILL_CHAR_ANY_MEANS && newObj != OBJECTIVE_DESTROY_OBJECT && newObj != OBJECTIVE_DESTROY_CAR)
+ if (min >= max)
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:
- case OBJECTIVE_LEAVE_CAR_AND_DIE:
- return;
- case OBJECTIVE_ENTER_CAR_AS_PASSENGER:
- case OBJECTIVE_ENTER_CAR_AS_DRIVER:
- case OBJECTIVE_DESTROY_CAR:
- case OBJECTIVE_SOLICIT_VEHICLE:
- case OBJECTIVE_BUY_ICE_CREAM:
- if (m_carInObjective == entity)
- return;
+ CVector leftDiff, rightDiff;
+ CVector middleDiff = GetPosition() - list[(max + min) / 2]->GetPosition();
+ float middleDist = middleDiff.Magnitude();
- if (newObj == OBJECTIVE_BUY_ICE_CREAM && bBoughtIceCream)
- return;
+ int left = max;
+ int right = min;
+ while(right <= left){
+ float rightDist, leftDist;
+ do {
+ rightDiff = GetPosition() - list[right]->GetPosition();
+ rightDist = rightDiff.Magnitude();
+ } while (middleDist > rightDist && ++right);
- 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_WAIT_IN_CAR_THEN_GET_OUT && (newObj == OBJECTIVE_LEAVE_CAR || newObj == OBJECTIVE_LEAVE_CAR_AND_DIE)
- && !bInVehicle)
- return;
- }
+ do {
+ leftDiff = GetPosition() - list[left]->GetPosition();
+ leftDist = leftDiff.Magnitude();
+ } while (middleDist < leftDist && left--);
- bObjectiveCompleted = false;
- ClearPointGunAt();
- m_objectiveTimer = 0;
- if (!IsTemporaryObjective(m_objective) || IsTemporaryObjective(newObj)) {
- if (m_objective != newObj) {
- if (IsTemporaryObjective(newObj))
- ForceStoredObjective(newObj);
- else
- SetStoredObjective();
+ if (right <= left) {
+ CPed *ped = list[right];
+ list[right] = list[left];
+ list[left] = ped;
+ right++;
+ left--;
}
- m_objective = newObj;
- } else {
- m_prevObjective = newObj;
- }
-
- 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.
- SetObjectiveTimer((uintptr)entity);
- break;
- 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;
-
- 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; // 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:
-
- 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:
- m_pedInObjective = (CPed*)entity;
- m_pedInObjective->RegisterReference((CEntity**)&m_pedInObjective);
- m_pedFormation = FORMATION_REAR;
- break;
- case OBJECTIVE_LEAVE_CAR:
- case OBJECTIVE_LEAVE_CAR_AND_DIE:
- case OBJECTIVE_FLEE_CAR:
- m_carInObjective = (CVehicle*)entity;
- m_carInObjective->RegisterReference((CEntity **)&m_carInObjective);
- if (!m_carInObjective->bIsBus || m_leaveCarTimer != 0)
- break;
-
- for (int i = 0; i < m_carInObjective->m_nNumMaxPassengers; i++) {
- if (m_carInObjective->pPassengers[i] == this) {
- m_leaveCarTimer = CTimer::GetTimeInMilliseconds() + 1200 * i;
- break;
- }
- }
-
- break;
- case OBJECTIVE_DESTROY_OBJECT:
- if (m_pPointGunAt)
- m_pPointGunAt->CleanUpOldReference(&m_pPointGunAt);
- m_pPointGunAt = (CPed*)entity;
- if (entity)
- ((CEntity*)entity)->RegisterReference((CEntity**) &m_pPointGunAt);
- 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() && m_pCurrentPhysSurface != entity) {
- RestorePreviousObjective();
- break;
- }
- // fall through
- case OBJECTIVE_DESTROY_CAR:
- case OBJECTIVE_SOLICIT_VEHICLE:
- case OBJECTIVE_BUY_ICE_CREAM:
- m_carInObjective = (CVehicle*)entity;
- m_carInObjective->RegisterReference((CEntity**)&m_carInObjective);
- m_pSeekTarget = m_carInObjective;
- m_pSeekTarget->RegisterReference((CEntity**)&m_pSeekTarget);
- m_vecSeekPos = CVector(0.0f, 0.0f, 0.0f);
- if (newObj == OBJECTIVE_SOLICIT_VEHICLE) {
- m_objectiveTimer = CTimer::GetTimeInMilliseconds() + 10000;
- } else if (m_objective == OBJECTIVE_ENTER_CAR_AS_PASSENGER && CharCreatedBy == MISSION_CHAR &&
- (m_carInObjective->GetStatus() == STATUS_PLAYER_DISABLED || CPad::GetPad(CWorld::PlayerInFocus)->ArePlayerControlsDisabled())) {
- SetObjectiveTimer(14000);
- } else {
- m_objectiveTimer = 0;
- }
- break;
- case OBJECTIVE_SET_LEADER:
- 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;
- }
-}
-
-// --MIAMI: Done
-void
-CPed::SetIdle(void)
-{
- if (m_nPedState != PED_IDLE && m_nPedState != PED_MUG && m_nPedState != PED_FLEE_ENTITY) {
- if (m_nPedState == PED_AIM_GUN)
- ClearPointGunAt();
-
- SetPedState(PED_IDLE);
- SetMoveState(PEDMOVE_STILL);
- m_nLastPedState = PED_NONE;
- }
- if (m_nWaitState == WAITSTATE_FALSE) {
- m_nWaitTimer = CTimer::GetTimeInMilliseconds() + CGeneral::GetRandomNumberInRange(2000, 4000);
}
+ SortPeds(list, min, left);
+ SortPeds(list, right, max);
}
// --MIAMI: Done
void
-CPed::SetObjective(eObjective newObj)
+CPed::SetMoveState(eMoveState state)
{
- 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
- || m_objective == OBJECTIVE_LEAVE_CAR_AND_DIE) && !IsPlayer() && !IsPedInControl()) {
-
- bStartWanderPathOnFoot = true;
- } else {
- m_objective = OBJECTIVE_NONE;
- m_prevObjective = OBJECTIVE_NONE;
- }
- } else if (m_prevObjective != newObj || m_prevObjective == OBJECTIVE_NONE) {
- SetObjectiveTimer(0);
-
- if (m_objective == newObj)
- return;
-
- if (IsTemporaryObjective(m_objective)) {
- m_prevObjective = newObj;
- } else {
- if (m_objective != newObj)
- SetStoredObjective();
-
- m_objective = newObj;
- }
- bObjectiveCompleted = false;
-
- switch (newObj) {
- case OBJECTIVE_NONE:
- m_prevObjective = OBJECTIVE_NONE;
- break;
- case OBJECTIVE_HAIL_TAXI:
- m_nWaitTimer = 0;
- SetIdle();
- SetMoveState(PEDMOVE_STILL);
- break;
- default:
- break;
- }
- }
+ m_nMoveState = state;
}
// --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
-CPed::SetObjective(eObjective newObj, int16 routePoint, int16 routeType)
+CPed::SetMoveAnim(void)
{
- if (DyingOrDead())
- return;
-
- if (m_prevObjective == newObj && m_prevObjective != OBJECTIVE_NONE)
+ if (m_nStoredMoveState == m_nMoveState || !IsPedInControl() || m_attachedTo)
return;
- if (m_objective == newObj && newObj == OBJECTIVE_FOLLOW_ROUTE && m_routeLastPoint == routePoint && m_routeType == routeType)
+ if (m_nMoveState == PEDMOVE_NONE) {
+ m_nStoredMoveState = PEDMOVE_NONE;
return;
-
- ClearPointGunAt();
- SetObjectiveTimer(0);
-
- bObjectiveCompleted = false;
- if (IsTemporaryObjective(m_objective)) {
- m_prevObjective = newObj;
- } else {
- if (m_objective != newObj)
- SetStoredObjective();
-
- m_objective = newObj;
- }
-
- if (newObj == OBJECTIVE_FOLLOW_ROUTE) {
- SetFollowRoute(routePoint, routeType);
}
-}
-// --MIAMI: Done
-void
-CPed::ClearChat(void)
-{
- CAnimBlendAssociation *animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_CHAT);
- if (animAssoc) {
- animAssoc->blendDelta = -8.0f;
- animAssoc->flags |= ASSOC_DELETEFADEDOUT;
- }
- bIsTalking = false;
- ClearLookFlag();
- RestorePreviousState();
- if (m_objective == OBJECTIVE_BUY_ICE_CREAM) {
- bBoughtIceCream = true;
- SetObjective(OBJECTIVE_NONE);
- SetWanderPath(CGeneral::GetRandomNumberInRange(0, 8));
- }
-}
-
-// --MIAMI: Done
-bool
-CPed::IsGangMember(void)
-{
- return m_nPedType >= PEDTYPE_GANG1 && m_nPedType <= PEDTYPE_GANG9;
-}
-
-// --MIAMI: Done
-void
-CPed::InformMyGangOfAttack(CEntity *attacker)
-{
- CPed *attackerPed;
-
- if (m_objective == OBJECTIVE_KILL_CHAR_ON_FOOT || m_objective == OBJECTIVE_KILL_CHAR_ANY_MEANS)
- return;
+ AssocGroupId animGroupToUse;
+ if (m_leader && m_leader->IsPlayer())
+ animGroupToUse = ASSOCGRP_PLAYER;
+ else
+ animGroupToUse = m_animGroup;
- if (attacker->IsPed()) {
- attackerPed = (CPed*)attacker;
- } else {
- if (!attacker->IsVehicle())
- return;
+ CAnimBlendAssociation *animAssoc = RpAnimBlendClumpGetFirstAssociation(GetClump(), ASSOC_BLOCK);
+ if (!animAssoc) {
+ animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_FIGHT_IDLE);
+ if (!animAssoc)
+ animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_MELEE_IDLE_FIGHTMODE);
- attackerPed = ((CVehicle*)attacker)->pDriver;
- if (!attackerPed)
+ if (animAssoc && m_nPedState == PED_FIGHT)
return;
- }
- if (attackerPed->m_nPedType == PEDTYPE_COP)
- return;
-
- for (int i = 0; i < m_numNearPeds; i++) {
- 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) {
- nearPed->SetObjective(OBJECTIVE_KILL_CHAR_ON_FOOT, attackerPed);
- nearPed->SetObjectiveTimer(30000);
+ if (animAssoc) {
+ CAnimBlendAssociation *idleAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_STANCE);
+ if (!idleAssoc || idleAssoc->blendDelta <= 0.0f) {
+ animAssoc->flags |= ASSOC_DELETEFADEDOUT;
+ animAssoc = CAnimManager::BlendAnimation(GetClump(), animGroupToUse, ANIM_IDLE_STANCE, 8.0f);
}
}
}
-}
-
-// --MIAMI: Done
-void
-CPed::QuitEnteringCar(void)
-{
- CVehicle *veh = m_pMyVehicle;
- if (m_pVehicleAnim)
- m_pVehicleAnim->blendDelta = -1000.0f;
-
- RestartNonPartialAnims();
-
- if (!RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_STANCE))
- CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_IDLE_STANCE, 100.0f);
-
- if (veh) {
- if (m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER || m_nPedState == PED_CARJACK)
- veh->bIsBeingCarJacked = false;
-
- if (veh->m_nNumGettingIn != 0)
- veh->m_nNumGettingIn--;
-
- if (m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER || m_objective == OBJECTIVE_ENTER_CAR_AS_PASSENGER)
- RestorePreviousObjective();
-
- 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;
-
- if (DyingOrDead()) {
- if (m_pVehicleAnim) {
- m_pVehicleAnim->blendDelta = -4.0f;
- m_pVehicleAnim->flags |= ASSOC_DELETEFADEDOUT;
- m_pVehicleAnim->flags &= ~ASSOC_RUNNING;
- }
- } else
- SetIdle();
-
- m_pVehicleAnim = nil;
-
- if (veh) {
- if (veh->AutoPilot.m_nCruiseSpeed == 0 && veh->VehicleCreatedBy == RANDOM_VEHICLE)
- veh->AutoPilot.m_nCruiseSpeed = 17;
- }
-}
-
-// --MIAMI: Done
-void
-CPed::ReactToAttack(CEntity *attacker)
-{
- if (IsPlayer() && attacker->IsPed()) {
- InformMyGangOfAttack(attacker);
- SetLookFlag(attacker, true);
- 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);
- }
-
- } 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
- && (m_pMyVehicle->GetStatus() == STATUS_SIMPLE || m_pMyVehicle->GetStatus() == STATUS_PHYSICS)
- && m_pMyVehicle->AutoPilot.m_nCarMission == MISSION_CRUISE) {
-
- 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 if ((IsPedInControl() || m_nPedState == PED_DRIVING) && (CharCreatedBy != MISSION_CHAR || bRespondsToThreats)) {
- CPed *ourLeader = m_leader;
- if (ourLeader != attacker && (!ourLeader || FindPlayerPed() != ourLeader) && attacker->IsPed()) {
-
- CPed *attackerPed = (CPed*)attacker;
- if (bNotAllowedToDuck) {
- if (!attackerPed->GetWeapon()->IsTypeMelee()) {
- m_duckAndCoverTimer = CTimer::GetTimeInMilliseconds();
- return;
- }
- } else if (bCrouchWhenShooting || bKindaStayInSamePlace) {
- SetDuck(CGeneral::GetRandomNumberInRange(1000,3000));
+ if (!animAssoc) {
+ animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_TIRED);
+ if (animAssoc)
+ if (m_nWaitState == WAITSTATE_STUCK || m_nWaitState == WAITSTATE_FINISH_FLEE)
return;
- }
- 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);
- }
+ if (animAssoc) {
+ CAnimBlendAssociation *idleAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_STANCE);
+ if (!idleAssoc || idleAssoc->blendDelta <= 0.0f) {
+ animAssoc->flags |= ASSOC_DELETEFADEDOUT;
+ animAssoc = CAnimManager::BlendAnimation(GetClump(), animGroupToUse, ANIM_IDLE_STANCE, 4.0f);
}
}
}
-}
-
-
-// --MIAMI: Done
-bool
-CPed::TurnBody(void)
-{
- bool turnDone = true;
-
- if (m_pLookTarget)
- m_fLookDirection = CGeneral::GetRadianAngleBetweenPoints(
- m_pLookTarget->GetPosition().x,
- m_pLookTarget->GetPosition().y,
- GetPosition().x,
- GetPosition().y);
-
- float limitedLookDir = CGeneral::LimitRadianAngle(m_fLookDirection);
- float currentRot = m_fRotationCur;
-
- if (currentRot - PI > limitedLookDir)
- limitedLookDir += 2 * PI;
- else if (PI + currentRot < limitedLookDir)
- limitedLookDir -= 2 * PI;
-
- float neededTurn = currentRot - limitedLookDir;
- m_fRotationDest = limitedLookDir;
-
- if (Abs(neededTurn) > 0.05f) {
- turnDone = false;
- currentRot -= neededTurn * 0.2f;
- }
-
- m_fRotationCur = currentRot;
- m_fLookDirection = limitedLookDir;
- return turnDone;
-}
-
-// --MIAMI: Done
-void
-CPed::Chat(void)
-{
- // We're already looking to our partner
- if (bIsLooking && TurnBody())
- ClearLookFlag();
-
- if (!m_pLookTarget || !m_pLookTarget->IsPed()) {
- ClearChat();
- return;
- }
-
- CPed *partner = (CPed*) m_pLookTarget;
+ if (!animAssoc) {
+ m_nStoredMoveState = m_nMoveState;
+ if (m_nMoveState == PEDMOVE_WALK || m_nMoveState == PEDMOVE_RUN || m_nMoveState == PEDMOVE_SPRINT) {
+ for (CAnimBlendAssociation *assoc = RpAnimBlendClumpGetFirstAssociation(GetClump(), ASSOC_PARTIAL);
+ assoc; assoc = RpAnimBlendGetNextAssociation(assoc, ASSOC_PARTIAL)) {
- 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)
- ReactToAttack(partner->m_pedInObjective);
- }
- return;
- }
- if (bIsTalking) {
- if (CGeneral::GetRandomNumber() < 512) {
- CAnimBlendAssociation *chatAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_CHAT);
- if (chatAssoc) {
- chatAssoc->blendDelta = -4.0f;
- chatAssoc->flags |= ASSOC_DELETEFADEDOUT;
+ if (!(assoc->flags & ASSOC_FADEOUTWHENDONE)) {
+ assoc->blendDelta = -2.0f;
+ assoc->flags |= ASSOC_DELETEFADEDOUT;
+ }
}
- bIsTalking = false;
- } else
- Say(SOUND_PED_CHAT);
-
- } else {
-
- if (CGeneral::GetRandomNumber() < 20 && !RpAnimBlendClumpGetFirstAssociation(GetClump(), ASSOC_IDLE)) {
- CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_XPRESS_SCRATCH, 4.0f);
- }
- if (!bIsTalking && !RpAnimBlendClumpGetFirstAssociation(GetClump(), ASSOC_IDLE)) {
- CAnimBlendAssociation *chatAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_IDLE_CHAT, 4.0f);
- float chatTime = CGeneral::GetRandomNumberInRange(0.0f, 3.0f);
- chatAssoc->SetCurrentTime(chatTime);
- bIsTalking = true;
- Say(SOUND_PED_CHAT);
+ ClearAimFlag();
+ ClearLookFlag();
}
- }
- if (m_standardTimer && CTimer::GetTimeInMilliseconds() > m_standardTimer) {
- ClearChat();
- m_standardTimer = CTimer::GetTimeInMilliseconds() + 30000;
- }
-}
-// --MIAMI: Done
-void
-CPed::CheckAroundForPossibleCollisions(void)
-{
- CVector ourCentre, objCentre;
- CEntity *objects[8];
- int16 maxObject;
-
- if (CTimer::GetTimeInMilliseconds() <= m_nPedStateTimer)
- return;
-
- GetBoundCentre(ourCentre);
-
- CWorld::FindObjectsInRange(ourCentre, 10.0f, true, &maxObject, 6, objects, false, true, false, true, false);
- for (int i = 0; i < maxObject; i++) {
- CEntity *object = objects[i];
- if (bRunningToPhone) {
- if (gPhoneInfo.PhoneAtThisPosition(object->GetPosition()))
+ switch (m_nMoveState) {
+ case PEDMOVE_STILL:
+ animAssoc = CAnimManager::BlendAnimation(GetClump(), animGroupToUse, ANIM_IDLE_STANCE, 4.0f);
break;
- }
- object->GetBoundCentre(objCentre);
- float radius = object->GetBoundRadius();
- if (radius > 4.5f || radius < 1.0f)
- radius = 1.0f;
-
- // Developers gave up calculating Z diff. later according to asm.
- float diff = CVector(ourCentre - objCentre).MagnitudeSqr2D();
-
- if (sq(radius + 1.0f) > diff)
- m_fRotationDest += DEGTORAD(22.5f);
- }
-}
-
-// --MIAMI: Done
-bool
-CPed::MakePhonecall(void)
-{
- if (CTimer::GetTimeInMilliseconds() <= m_phoneTalkTimer)
- return false;
-
- SetIdle();
- gPhoneInfo.m_aPhones[m_phoneId].m_nState = PHONE_STATE_FREE;
- m_phoneId = -1;
- return true;
-}
-
-// --MIAMI: Done
-bool
-CPed::FacePhone(void)
-{
- // 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);
-
- SetLookFlag(phoneDir, false);
- bool turnDone = TurnBody();
- if (turnDone) {
- SetIdle();
- ClearLookFlag();
- m_phoneTalkTimer = CTimer::GetTimeInMilliseconds() + 10000;
- }
- return turnDone;
-#else
- float currentRot = RADTODEG(m_fRotationCur);
- float phoneDir = CGeneral::GetRadianAngleBetweenPoints(
- gPhoneInfo.m_aPhones[m_phoneId].m_vecPos.x,
- gPhoneInfo.m_aPhones[m_phoneId].m_vecPos.y,
- GetPosition().x,
- GetPosition().y);
-
- SetLookFlag(phoneDir, false);
- phoneDir = CGeneral::LimitAngle(phoneDir);
- m_moved = CVector2D(0.0f, 0.0f);
-
- if (currentRot - 180.0f > phoneDir)
- phoneDir += 2 * 180.0f;
- else if (180.0f + currentRot < phoneDir)
- phoneDir -= 2 * 180.0f;
-
- float neededTurn = currentRot - phoneDir;
-
- if (Abs(neededTurn) <= 0.75f) {
- SetIdle();
- ClearLookFlag();
- m_phoneTalkTimer = CTimer::GetTimeInMilliseconds() + 10000;
- return true;
- } else {
- m_fRotationCur = DEGTORAD(currentRot - neededTurn * 0.2f);
- return false;
- }
-#endif
-}
-
-// --MIAMI: Done
-CPed *
-CPed::CheckForDeadPeds(void)
-{
- int event;
- if (CEventList::FindClosestEvent(EVENT_DEAD_PED, GetPosition(), &event)) {
- int pedHandle = gaEvent[event].entityRef;
- if (pedHandle && gaEvent[event].entityType == EVENT_ENTITY_PED) {
- bGonnaInvestigateEvent = true;
- return CPools::GetPed(pedHandle);
- }
- }
- bGonnaInvestigateEvent = false;
- return nil;
-}
-
-// --MIAMI: Done
-bool
-CPed::CheckForExplosions(CVector2D &area)
-{
- int event = 0;
- if (CEventList::FindClosestEvent(EVENT_EXPLOSION, GetPosition(), &event)) {
- area.x = gaEvent[event].posn.x;
- area.y = gaEvent[event].posn.y;
- CEntity *actualEntity = nil;
-
- switch (gaEvent[event].entityType) {
- case EVENT_ENTITY_PED:
- actualEntity = CPools::GetPed(gaEvent[event].entityRef);
+ case PEDMOVE_WALK:
+ animAssoc = CAnimManager::BlendAnimation(GetClump(), animGroupToUse, ANIM_WALK, 1.0f);
break;
- case EVENT_ENTITY_VEHICLE:
- actualEntity = CPools::GetVehicle(gaEvent[event].entityRef);
+ case PEDMOVE_RUN:
+ if (m_nPedState == PED_FLEE_ENTITY) {
+ animAssoc = CAnimManager::BlendAnimation(GetClump(), animGroupToUse, ANIM_RUN, 3.0f);
+ } else {
+ animAssoc = CAnimManager::BlendAnimation(GetClump(), animGroupToUse, ANIM_RUN, 1.0f);
+ }
break;
- case EVENT_ENTITY_OBJECT:
- actualEntity = CPools::GetObject(gaEvent[event].entityRef);
+ case PEDMOVE_SPRINT:
+ animAssoc = CAnimManager::BlendAnimation(GetClump(), animGroupToUse, ANIM_SPRINT, 1.0f);
break;
default:
break;
}
- if (actualEntity) {
- m_pEventEntity = actualEntity;
- m_pEventEntity->RegisterReference((CEntity **) &m_pEventEntity);
- bGonnaInvestigateEvent = true;
- } else
- bGonnaInvestigateEvent = false;
-
- CEventList::ClearEvent(event);
- return true;
- } else if (CEventList::FindClosestEvent(EVENT_FIRE, GetPosition(), &event)) {
- area.x = gaEvent[event].posn.x;
- area.y = gaEvent[event].posn.y;
- CEventList::ClearEvent(event);
- bGonnaInvestigateEvent = false;
- return true;
- }
-
- bGonnaInvestigateEvent = false;
- return false;
-}
-
-// --MIAMI: Done
-CPed *
-CPed::CheckForGunShots(void)
-{
- int event;
- if (CEventList::FindClosestEvent(EVENT_GUNSHOT, GetPosition(), &event)) {
- if (gaEvent[event].entityType == EVENT_ENTITY_PED) {
- // Probably due to we don't want peds to go gunshot area? (same on VC)
- bGonnaInvestigateEvent = false;
- return CPools::GetPed(gaEvent[event].entityRef);
- }
- }
- bGonnaInvestigateEvent = false;
- return nil;
-}
-
-// --MIAMI: Done
-PointBlankNecessity
-CPed::CheckForPointBlankPeds(CPed *pedToVerify)
-{
- float pbDistance = 1.1f;
- if (GetWeapon()->IsType2Handed())
- pbDistance = 1.6f;
-
- for (int i = 0; i < m_numNearPeds; i++) {
- CPed *nearPed = m_nearPeds[i];
-
- if (!pedToVerify || pedToVerify == nearPed) {
-
- CVector diff = nearPed->GetPosition() - GetPosition();
- if (diff.MagnitudeSqr() < SQR(pbDistance)) {
-
- float neededAngle = CGeneral::GetRadianAngleBetweenPoints(
- nearPed->GetPosition().x, nearPed->GetPosition().y,
- GetPosition().x, GetPosition().y);
- neededAngle = CGeneral::LimitRadianAngle(neededAngle);
- m_fRotationCur = CGeneral::LimitRadianAngle(m_fRotationCur);
-
- float neededTurn = Abs(neededAngle - m_fRotationCur);
-
- if (neededTurn > PI)
- neededTurn = 2*PI - neededTurn;
-
- PedState nearPedState = nearPed->m_nPedState;
+ if (animAssoc) {
+ if (m_leader) {
+ CAnimBlendAssociation *walkAssoc = RpAnimBlendClumpGetAssociation(m_leader->GetClump(), ANIM_WALK);
+ if (!walkAssoc)
+ walkAssoc = RpAnimBlendClumpGetAssociation(m_leader->GetClump(), ANIM_RUN);
- if (nearPedState == PED_FALL || nearPedState == PED_GETUP || nearPedState == PED_DIE || nearPedState == PED_DEAD || nearPedState == PED_DIVE_AWAY)
- return NO_POINT_BLANK_PED;
+ if (!walkAssoc)
+ walkAssoc = RpAnimBlendClumpGetAssociation(m_leader->GetClump(), ANIM_SPRINT);
- if (neededTurn < CAN_SEE_ENTITY_ANGLE_THRESHOLD) {
- if (pedToVerify == nearPed)
- return POINT_BLANK_FOR_WANTED_PED;
+ if (walkAssoc) {
+ animAssoc->speed = walkAssoc->speed;
+ } else {
+ if (CharCreatedBy == MISSION_CHAR)
+ animAssoc->speed = 1.0f;
else
- return POINT_BLANK_FOR_SOMEONE_ELSE;
+ animAssoc->speed = 1.2f - m_randomSeed * 0.4f / MYRAND_MAX;
+
}
+ } else {
+ if (CharCreatedBy == MISSION_CHAR)
+ animAssoc->speed = 1.0f;
+ else
+ animAssoc->speed = 1.2f - m_randomSeed * 0.4f / MYRAND_MAX;
}
}
}
- return NO_POINT_BLANK_PED;
-}
-
-// --MIAMI: Done
-bool
-CPed::CheckIfInTheAir(void)
-{
- if (bInVehicle)
- return false;
-
- CVector pos = GetPosition();
- CColPoint foundColPoint;
- CEntity *foundEntity;
-
- float startZ = pos.z - 1.54f;
- bool foundGround = CWorld::ProcessVerticalLine(pos, startZ, foundColPoint, foundEntity, true, true, false, true, false, false, nil);
- if (!foundGround && m_nPedState != PED_JUMP)
- {
- pos.z -= FEET_OFFSET;
- if (CWorld::TestSphereAgainstWorld(pos, 0.15f, this, true, false, false, false, false, false))
- foundGround = true;
- }
- return !foundGround;
-}
-
-// --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
void
-CPed::ClearAll(void)
-{
- if (!IsPedInControl() && m_nPedState != PED_DEAD)
- return;
-
- SetPedState(PED_NONE);
- m_nMoveState = PEDMOVE_NONE;
- m_pSeekTarget = nil;
- m_vecSeekPos = CVector(0.0f, 0.0f, 0.0f);
- m_fleeFromPos = CVector2D(0.0f, 0.0f);
- m_fleeFrom = nil;
- m_fleeTimer = 0;
- m_threatEx = nil;
- bUsesCollision = true;
- ClearPointGunAt();
- bIsPointingGunAt = false;
- bRenderPedInCar = true;
- bKnockedUpIntoAir = false;
- bKnockedOffBike = false;
- m_pCollidingEntity = nil;
-}
-
-// --MIAMI: Done
-void
-CPed::ClearAttack(void)
-{
- if (m_nPedState != PED_ATTACK || (bIsDucking && !IsPlayer()) || m_nWaitState == WAITSTATE_PLAYANIM_DUCK)
- return;
-
- if (FindPlayerPed() == this && TheCamera.Using1stPersonWeaponMode()) {
- SetPointGunAt(nil);
- } else if (bIsPointingGunAt) {
- if (m_pLookTarget)
- SetPointGunAt(m_pLookTarget);
- else
- ClearPointGunAt();
- } else if (m_objective != OBJECTIVE_NONE) {
- SetIdle();
- } else {
- RestorePreviousState();
- }
-}
-
-// --MIAMI: Done
-void
-CPed::ClearAttackByRemovingAnim(void)
+CPed::StopNonPartialAnims(void)
{
- if (m_nPedState != PED_ATTACK)
- return;
-
- CWeaponInfo *weapon = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType);
- CAnimBlendAssociation *weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetPrimaryFireAnim(weapon));
+ CAnimBlendAssociation *assoc;
- if (!weaponAssoc) {
- if (!!weapon->m_bCrouchFire)
- weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetCrouchFireAnim(weapon));
- }
- if (!weaponAssoc) {
- if(!!weapon->m_bFinish3rd)
- weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetFinishingAttackAnim(weapon));
- }
- if (!weaponAssoc) {
- if(!!weapon->m_bUse2nd)
- weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetSecondFireAnim(weapon));
- }
- if (!weaponAssoc) {
- if(!!weapon->m_bCop3rd)
- weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_SPECIAL);
- }
- if (weaponAssoc) {
- weaponAssoc->blendDelta = -8.0f;
- weaponAssoc->flags &= ~ASSOC_RUNNING;
- weaponAssoc->flags |= ASSOC_DELETEFADEDOUT;
- weaponAssoc->SetDeleteCallback(FinishedAttackCB, this);
- } else {
- ClearAttack();
+ for (assoc = RpAnimBlendClumpGetFirstAssociation(GetClump()); assoc; assoc = RpAnimBlendGetNextAssociation(assoc)) {
+ if (!assoc->IsPartial())
+ assoc->flags &= ~ASSOC_RUNNING;
}
}
// --MIAMI: Done
void
-CPed::StopNonPartialAnims(void)
+CPed::RestartNonPartialAnims(void)
{
CAnimBlendAssociation *assoc;
for (assoc = RpAnimBlendClumpGetFirstAssociation(GetClump()); assoc; assoc = RpAnimBlendGetNextAssociation(assoc)) {
if (!assoc->IsPartial())
- assoc->flags &= ~ASSOC_RUNNING;
+ assoc->SetRun();
}
}
@@ -4174,881 +767,6 @@ CPed::SetStoredState(void)
// --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)
- return;
- }
-
- m_threatEntity = nil;
- if (DyingOrDead())
- return;
-
- CAnimBlendAssociation *dieAssoc = nil;
- if (m_nPedState == PED_FALL || m_nPedState == PED_GETUP)
- delta *= 0.5f;
-
- SetStoredState();
- ClearAll();
- m_fHealth = 0.0f;
- if (m_nPedState == PED_DRIVING) {
- if (!IsPlayer() && (!m_pMyVehicle || !m_pMyVehicle->IsBike()))
- FlagToDestroyWhenNextProcessed();
- } else if (bInVehicle) {
- if (m_pVehicleAnim)
- m_pVehicleAnim->blendDelta = -1000.0f;
- } else if (EnteringCar()) {
- QuitEnteringCar();
- }
-
- SetPedState(PED_DIE);
- if (animId == NUM_STD_ANIMS) {
- bIsPedDieAnimPlaying = false;
- } else {
- dieAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, animId, delta);
- if (speed > 0.0f)
- dieAssoc->speed = speed;
-
- dieAssoc->flags &= ~ASSOC_FADEOUTWHENDONE;
- if (dieAssoc->IsRunning()) {
- dieAssoc->SetFinishCallback(FinishDieAnimCB, this);
- bIsPedDieAnimPlaying = true;
- }
- }
-
- 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
-bool
-CPed::InflictDamage(CEntity *damagedBy, eWeaponType method, float damage, ePedPieceTypes pedPiece, uint8 direction)
-{
- CPlayerPed *player = FindPlayerPed();
- float dieDelta = 4.0f;
- float dieSpeed = 0.0f;
- AnimationId dieAnim = ANIM_KO_SHOT_FRONT1;
- bool headShot = false;
- 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 (method == WEAPONTYPE_DROWNING && !bDrownsInWater)
- return false;
-
- if (!bUsesCollision && (!bInVehicle || m_nPedState != PED_DRIVING) && method != WEAPONTYPE_DROWNING)
- return false;
-
- if (bOnlyDamagedByPlayer && damagedBy != player && damagedBy != FindPlayerVehicle() &&
- method != WEAPONTYPE_DROWNING && method != WEAPONTYPE_EXPLOSION)
- return false;
-
- float healthImpact;
- if (IsPlayer())
- healthImpact = damage * 0.33f;
- 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_GETUP) {
- if (!IsPedHeadAbovePos(-0.3f)) {
- if (RpAnimBlendClumpGetFirstAssociation(GetClump(), ASSOC_FRONTAL))
- dieAnim = ANIM_FLOOR_HIT_F;
- else
- dieAnim = ANIM_FLOOR_HIT;
- dieDelta *= 2.0f;
- dieSpeed = 0.5f;
- 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_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 {
- 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;
- }
- }
- 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 (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 {
- dieAnim = ANIM_KO_SHOT_FACE;
- }
- } else {
- dieAnim = ANIM_KO_SHOT_FACE;
- RemoveBodyPart(PED_HEAD, direction);
- headShot = true;
- willLinger = true;
- }
- break;
- case WEAPONTYPE_COLT45:
- case WEAPONTYPE_SHOTGUN:
- case WEAPONTYPE_STUBBY_SHOTGUN:
- case WEAPONTYPE_SPAS12_SHOTGUN:
- case WEAPONTYPE_TEC9:
- case WEAPONTYPE_UZI:
- case WEAPONTYPE_SILENCED_INGRAM:
- case WEAPONTYPE_MP5:
- case WEAPONTYPE_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 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) {
- 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_FRONT1;
-
- willLinger = false;
- } else {
- switch (pedPiece) {
- case PEDPIECE_TORSO:
- willLinger = false;
- dieAnim = ANIM_KO_SHOT_FRONT1;
- break;
- case PEDPIECE_MID:
- willLinger = false;
- dieAnim = ANIM_KO_SHOT_STOM;
- break;
- case PEDPIECE_LEFTARM:
- dieAnim = ANIM_KO_SHOT_ARML;
- RemoveBodyPart(PED_UPPERARML, direction);
- willLinger = true;
- break;
- case PEDPIECE_RIGHTARM:
- dieAnim = ANIM_KO_SHOT_ARMR;
- RemoveBodyPart(PED_UPPERARMR, direction);
- willLinger = true;
- break;
- case PEDPIECE_LEFTLEG:
- dieAnim = ANIM_KO_SHOT_LEGL;
- RemoveBodyPart(PED_UPPERLEGL, direction);
- willLinger = true;
- break;
- case PEDPIECE_RIGHTLEG:
- dieAnim = ANIM_KO_SHOT_LEGR;
- RemoveBodyPart(PED_UPPERLEGR, direction);
- willLinger = true;
- break;
- case PEDPIECE_HEAD:
- dieAnim = ANIM_KO_SHOT_FACE;
- RemoveBodyPart(PED_HEAD, direction);
- headShot = true;
- willLinger = true;
- break;
- default:
- break;
- }
- }
- break;
- case WEAPONTYPE_GRENADE:
- case WEAPONTYPE_ROCKETLAUNCHER:
- case WEAPONTYPE_EXPLOSION:
- if (bExplosionProof)
- return false;
-
- if (CGame::nastyGame && !IsPlayer() && !bInVehicle &&
- 1.0f + healthImpact > m_fArmour + m_fHealth) {
-
- random = CGeneral::GetRandomNumber();
- if (random & 1)
- RemoveBodyPart(PED_UPPERARML, direction);
- if (random & 2)
- RemoveBodyPart(PED_UPPERLEGR, direction);
- if (random & 4)
- RemoveBodyPart(PED_HEAD, direction);
- if (random & 8)
- RemoveBodyPart(PED_UPPERARMR, direction);
- if (random & 0x10)
- RemoveBodyPart(PED_UPPERLEGL, direction);
- if (bBodyPartJustCameOff)
- willLinger = true;
- }
- // fall through
- case WEAPONTYPE_MOLOTOV:
- if (bExplosionProof)
- return false;
-
- 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;
- }
- break;
- case WEAPONTYPE_FLAMETHROWER:
- if (bFireProof)
- return false;
-
- dieAnim = ANIM_KO_SHOT_FRONT1;
- break;
- case WEAPONTYPE_RAMMEDBYCAR:
- case WEAPONTYPE_RUNOVERBYCAR:
- if (bCollisionProof)
- return false;
-
- random = CGeneral::GetRandomNumber() & 3;
- switch (random) {
- case 0:
- if ((pedPiece != PEDPIECE_LEFTARM || random <= 1)
- && (pedPiece != PEDPIECE_MID || random != 1)) {
- if (pedPiece == PEDPIECE_RIGHTARM && random > 1
- || pedPiece == PEDPIECE_MID && random == 2)
-
- dieAnim = ANIM_KO_SPIN_L;
- else
- dieAnim = ANIM_KO_SKID_FRONT;
- } else
- dieAnim = ANIM_KO_SPIN_R;
-
- break;
- case 1:
- if (m_nPedState == PED_DIVE_AWAY)
- dieAnim = ANIM_KD_LEFT;
- else
- dieAnim = ANIM_KO_SPIN_R;
- break;
- case 2:
- if ((pedPiece != PEDPIECE_LEFTARM || random <= 1)
- && (pedPiece != PEDPIECE_MID || random != 1)) {
- if ((pedPiece != PEDPIECE_RIGHTARM || random <= 1)
- && (pedPiece != PEDPIECE_MID || random != 2)) {
- dieAnim = ANIM_KO_SKID_BACK;
- } else {
- dieAnim = ANIM_KD_RIGHT;
- }
- } else
- dieAnim = ANIM_KD_LEFT;
- break;
- case 3:
- if (m_nPedState == PED_DIVE_AWAY)
- dieAnim = ANIM_KD_RIGHT;
- else
- dieAnim = ANIM_KO_SPIN_L;
- break;
- default:
- break;
- }
- if (damagedBy && pedPiece != PEDPIECE_TORSO) {
- CVehicle *vehicle = (CVehicle*)damagedBy;
- if (method == WEAPONTYPE_RAMMEDBYCAR) {
- float vehSpeed = vehicle->m_vecMoveSpeed.Magnitude();
- dieDelta = 8.0f * vehSpeed + 4.0f;
- } else {
- float vehSpeed = vehicle->m_vecMoveSpeed.Magnitude();
- dieDelta = 12.0f * vehSpeed + 4.0f;
- dieSpeed = 16.0f * vehSpeed + 1.0f;
- }
- }
- break;
- case WEAPONTYPE_DROWNING:
- dieAnim = ANIM_DROWN;
- break;
- case WEAPONTYPE_FALL:
- if (bCollisionProof)
- return false;
-
- 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;
- }
- break;
- default:
- break;
- }
- }
-
- if (m_fArmour != 0.0f && method != WEAPONTYPE_DROWNING) {
- if (player == this)
- CWorld::Players[CWorld::PlayerInFocus].m_nTimeLastArmourLoss = CTimer::GetTimeInMilliseconds();
-
- if (healthImpact < m_fArmour) {
- m_fArmour = m_fArmour - healthImpact;
- healthImpact = 0.0f;
- } else {
- healthImpact = healthImpact - m_fArmour;
- m_fArmour = 0.0f;
- }
- }
-
- if (healthImpact != 0.0f) {
- if (player == this)
- 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) {
- m_fHealth -= healthImpact;
- return false;
- }
-
- if (bInVehicle) {
- if (method != WEAPONTYPE_DROWNING) {
- if (m_pMyVehicle) {
- CVehicle* pVehicle = m_pMyVehicle;
- bool bDone = false;
- if (m_pMyVehicle->IsBike()) {
- m_fHealth = 0.0f;
- ((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;
- }
- }
- 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(pVehicle->pPassengers); i++) {
- CPed* passenger = pVehicle->pPassengers[i];
- if (passenger && passenger != this && damagedBy)
- passenger->ReactToAttack(damagedBy);
- }
-
- CPed *driverOfVeh = pVehicle->pDriver;
- if (driverOfVeh && driverOfVeh != this && damagedBy)
- driverOfVeh->ReactToAttack(damagedBy);
-
- if (damagedBy == FindPlayerPed() || damagedBy && damagedBy == FindPlayerVehicle()) {
- CDarkel::RegisterKillByPlayer(this, method, headShot);
- m_threatEntity = FindPlayerPed();
- } else {
- CDarkel::RegisterKillNotByPlayer(this, method);
- }
- if (bDone)
- return true;
- }
- m_fHealth = 1.0f;
- return false;
- }
- m_fHealth = 0.0f;
- if (player == this)
- m_pMyVehicle->SetStatus(STATUS_PLAYER_DISABLED);
-
- 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()) {
- 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) {
- bIsInTheAir = false;
- if (FindPlayerPed() == this)
- CStats::TimesDrowned++;
- }
-
- return true;
- }
-}
-
-// --MIAMI: Done
-void
-CPed::ClearFlee(void)
-{
- RestorePreviousState();
- bUsePedNodeSeek = false;
- m_standardTimer = 0;
- m_fleeTimer = 0;
-}
-
-// --MIAMI: Done
-void
-CPed::ClearFall(void)
-{
- SetGetUp();
-}
-
-// --MIAMI: Done
-void
-CPed::SetGetUp(void)
-{
- if (m_nPedState == PED_GETUP && bGetUpAnimStarted)
- return;
-
- if (!CanSetPedState())
- return;
-
- if (m_fHealth >= 1.0f || IsPedHeadAbovePos(-0.3f)) {
- if (bUpdateAnimHeading) {
- m_fRotationCur = CGeneral::LimitRadianAngle(m_fRotationCur);
- m_fRotationCur -= HALFPI;
- bUpdateAnimHeading = false;
- }
- if (m_nPedState != PED_GETUP) {
- SetStoredState();
- SetPedState(PED_GETUP);
- }
-
- CVehicle *collidingVeh = (CVehicle*)m_pCollidingEntity;
- CVehicle *veh = (CVehicle*)CPedPlacement::IsPositionClearOfCars(&GetPosition());
- 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(),
- aTempPedColPts, nil, nil) > 0)) {
-
- bGetUpAnimStarted = false;
- if (IsPlayer())
- InflictDamage(nil, WEAPONTYPE_RUNOVERBYCAR, CTimer::GetTimeStep(), PEDPIECE_TORSO, 0);
- else {
- if (!CPad::GetPad(0)->ArePlayerControlsDisabled())
- return;
-
- 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)) {
- CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_RUN, 8.0f);
- } else {
- CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_IDLE_STANCE, 8.0f);
- }
- animAssoc->flags |= ASSOC_DELETEFADEDOUT;
- }
-
- if (m_nWaitState == WAITSTATE_SUN_BATHE_IDLE) {
- m_headingRate = 0.0f;
-
- // TODO(Miami): Looks like that should've been another getup anim but R* forgot it. Visit here later
- 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);
- } else {
- m_fHealth = 0.0f;
- SetDie(NUM_STD_ANIMS, 4.0f, 0.0f);
- }
-}
-
-// --MIAMI: Done
-void
-CPed::ClearInvestigateEvent(void)
-{
- CAnimBlendAssociation *animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_ROAD_CROSS);
- if (!animAssoc)
- animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_XPRESS_SCRATCH);
- if (!animAssoc)
- animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_HBHB);
- if (!animAssoc)
- animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_CHAT);
- if (animAssoc) {
- animAssoc->blendDelta = -8.0f;
- animAssoc->flags |= ASSOC_DELETEFADEDOUT;
- }
- if (m_eventType > EVENT_EXPLOSION)
- m_standardTimer = CTimer::GetTimeInMilliseconds() + 15000;
-
- bGonnaInvestigateEvent = false;
- m_pEventEntity = nil;
- ClearLookFlag();
- RestorePreviousState();
- if(m_nMoveState == PEDMOVE_NONE || m_nMoveState == PEDMOVE_STILL)
- SetMoveState(PEDMOVE_WALK);
-}
-
-// --MIAMI: Done
-void
-CPed::ClearLeader(void)
-{
- if (!m_leader)
- return;
-
- m_leader = nil;
- if (IsPedInControl()) {
- SetObjective(OBJECTIVE_NONE);
- if (CharCreatedBy == MISSION_CHAR) {
- SetIdle();
- } else {
- SetWanderPath(CGeneral::GetRandomNumberInRange(0,8));
- }
- } else if (m_objective != OBJECTIVE_NONE) {
- bClearObjective = true;
- }
-}
-
-// --MIAMI: Done
-void
-CPed::ClearLook(void)
-{
- RestorePreviousState();
- ClearLookFlag();
-}
-
-// --MIAMI: Done
-void
-CPed::ClearObjective(void)
-{
- if (IsPedInControl() || m_nPedState == PED_DRIVING) {
- m_objective = OBJECTIVE_NONE;
- m_pedInObjective = nil;
- m_carInObjective = nil;
-
- if (m_nPedState == PED_DRIVING && m_pMyVehicle) {
- if (m_pMyVehicle->pDriver != this) {
- if(!IsPlayer())
- bWanderPathAfterExitingCar = true;
-
- SetObjective(OBJECTIVE_LEAVE_CAR, m_pMyVehicle);
- }
- m_nLastPedState = PED_NONE;
- } else {
- SetIdle();
- SetMoveState(PEDMOVE_STILL);
- }
- } else {
- bClearObjective = true;
- }
-}
-
-// --MIAMI: Done
-void
-CPed::ClearPause(void)
-{
- RestorePreviousState();
-}
-
-// --MIAMI: Done
-void
-CPed::ClearSeek(void)
-{
- SetIdle();
- bRunningToPhone = false;
-}
-
-// --MIAMI: Done
-bool
-CPed::SetWanderPath(int8 pathStateDest)
-{
- uint8 nextPathState;
-
- if (IsPlayer())
- return false;
-
- if (IsPedInControl()) {
- if (bKindaStayInSamePlace) {
- SetIdle();
- return false;
- } else {
- m_nPathDir = pathStateDest;
- if (pathStateDest == 0)
- pathStateDest = CGeneral::GetRandomNumberInRange(1, 7);
-
- ThePaths.FindNextNodeWandering(PATH_PED, GetPosition(), &m_pLastPathNode, &m_pNextPathNode,
- m_nPathDir, &nextPathState);
-
- // Circular loop until we find a node for current m_nPathDir
- while (!m_pNextPathNode) {
- m_nPathDir = (m_nPathDir+1) % 8;
-
- // We're at where we started and couldn't find any node
- if (m_nPathDir == pathStateDest) {
- ClearAll();
- SetIdle();
- return false;
- }
- ThePaths.FindNextNodeWandering(PATH_PED, GetPosition(), &m_pLastPathNode, &m_pNextPathNode,
- m_nPathDir, &nextPathState);
- }
-
- // We did it, save next path state and return true
- m_nPathDir = nextPathState;
- SetPedState(PED_WANDER_PATH);
- SetMoveState(PEDMOVE_WALK);
- bIsRunning = false;
- return true;
- }
- } else {
- m_nPathDir = pathStateDest;
- bStartWanderPathOnFoot = true;
- return false;
- }
-}
-
-// --MIAMI: Done
-void
-CPed::ClearWeapons(void)
-{
- RemoveWeaponModel(-1);
- for (int i = 0; i < ARRAY_SIZE(m_weapons); i++) {
- GetWeapon(i).Shutdown();
- }
- SetCurrentWeapon(WEAPONTYPE_UNARMED);
-}
-
-// --MIAMI: Done
-void
-CPed::RestoreGunPosition(void)
-{
- if (bIsLooking) {
- m_pedIK.m_flags &= ~CPedIK::LOOKAROUND_HEAD_ONLY;
- bIsRestoringGun = false;
- } else if (m_pedIK.RestoreGunPosn()) {
- bIsRestoringGun = false;
- } else {
- if (IsPlayer())
- ((CPlayerPed*)this)->m_fFPSMoveHeading = 0.0f;
- }
-}
-
-// --MIAMI: Done
-void
-CPed::RestoreHeadingRate(void)
-{
- m_headingRate = m_pedStats->m_headingChangeRate;
-}
-
-// --MIAMI: Done
-void
-CPed::RestoreHeadingRateCB(CAnimBlendAssociation *assoc, void *arg)
-{
- ((CPed*)arg)->RestoreHeadingRate();
-}
-
-// --MIAMI: Done
-void
CPed::RestorePreviousState(void)
{
if (!CanSetPedState() || m_nPedState == PED_FALL)
@@ -5090,8 +808,7 @@ CPed::RestorePreviousState(void)
SetWanderPath(m_nPedState == PED_FOLLOW_PATH ? m_nPathDir : CGeneral::GetRandomNumber() & 7);
break;
default:
- PedState oldState = m_nLastPedState;
- SetPedState(oldState);
+ SetPedState(m_nLastPedState);
SetMoveState((eMoveState) m_nPrevMoveState);
break;
}
@@ -5100,5874 +817,924 @@ CPed::RestorePreviousState(void)
}
// --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::SetAimFlag(float angle)
-{
- bIsAimingGun = true;
- bIsRestoringGun = false;
- m_fLookDirection = 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::SetPointGunAt(CEntity *to)
-{
- if (to) {
- SetLookFlag(to, true, true);
- SetAimFlag(to);
- SetLookTimer(INT32_MAX);
- }
-
- 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)
- SetStoredState();
-
- SetPedState(PED_AIM_GUN);
- bIsPointingGunAt = true;
- SetMoveState(PEDMOVE_STILL);
-
- CAnimBlendAssociation *aimAssoc;
-
- 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 && 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 && !IsPlayer())
- Say(SOUND_PED_ATTACK);
-}
-
-// --MIAMI: Done
-void
-CPed::SetAmmo(eWeaponType weaponType, uint32 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(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::GrantAmmo(eWeaponType weaponType, uint32 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(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::SetEvasiveStep(CEntity *reason, uint8 animType)
-{
- AnimationId stepAnim;
-
- if (m_nPedState == PED_STEP_AWAY || !IsPedInControl() || ((IsPlayer() || !bRespondsToThreats) && animType == 0))
- return;
-
- float angleToFace = CGeneral::GetRadianAngleBetweenPoints(
- reason->GetPosition().x, reason->GetPosition().y,
- GetPosition().x, GetPosition().y);
- angleToFace = CGeneral::LimitRadianAngle(angleToFace);
- m_fRotationCur = CGeneral::LimitRadianAngle(m_fRotationCur);
- float neededTurn = Abs(angleToFace - m_fRotationCur);
- bool vehPressedHorn = false;
-
- if (neededTurn > PI)
- neededTurn = TWOPI - neededTurn;
-
- CVehicle *veh = (CVehicle*)reason;
- if (reason->IsVehicle() && veh->m_vehType == VEHICLE_TYPE_CAR) {
- if (veh->m_nCarHornTimer != 0) {
- vehPressedHorn = true;
- if (!IsPlayer())
- animType = 1;
- }
- }
- if (neededTurn <= DEGTORAD(90.0f) || veh->GetModelIndex() == MI_RCBANDIT || vehPressedHorn || animType != 0) {
- SetLookFlag(veh, true);
- if ((CGeneral::GetRandomNumber() & 1) && veh->GetModelIndex() != MI_RCBANDIT && animType == 0) {
- stepAnim = ANIM_IDLE_TAXI;
-
- } else {
- float vehDirection = CGeneral::GetRadianAngleBetweenPoints(
- veh->m_vecMoveSpeed.x, veh->m_vecMoveSpeed.y,
- 0.0f, 0.0f);
-
- // Let's turn our back to the "reason"
- angleToFace += PI;
-
- if (angleToFace > PI)
- angleToFace -= TWOPI;
-
- // We don't want to run towards car's direction
- float dangerZone = angleToFace - vehDirection;
- dangerZone = CGeneral::LimitRadianAngle(dangerZone);
-
- // So, add or subtract 90deg (jump to left/right) according to that
- if (dangerZone <= 0.0f)
- angleToFace = HALFPI + vehDirection;
- else
- angleToFace = vehDirection - HALFPI;
-
- stepAnim = NUM_STD_ANIMS;
- if (animType == 0 || animType == 1)
- stepAnim = ANIM_EV_STEP;
- else if (animType == 2)
- stepAnim = ANIM_HANDSCOWER;
- }
- if (!RpAnimBlendClumpGetAssociation(GetClump(), stepAnim)) {
- CAnimBlendAssociation *stepAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, stepAnim, 8.0f);
- stepAssoc->flags &= ~ASSOC_DELETEFADEDOUT;
- stepAssoc->SetFinishCallback(PedEvadeCB, this);
-
- if (animType == 0)
- Say(SOUND_PED_EVADE);
-
- m_fRotationCur = CGeneral::LimitRadianAngle(angleToFace);
- ClearAimFlag();
- SetStoredState();
- SetPedState(PED_STEP_AWAY);
- }
- }
-}
-
-// --MIAMI: Done
-void
-CPed::SetEvasiveDive(CPhysical *reason, uint8 onlyRandomJump)
-{
- if (!IsPedInControl() || !bRespondsToThreats)
- return;
-
- CAnimBlendAssociation *animAssoc;
- float angleToFace, neededTurn;
- bool handsUp = false;
-
- angleToFace = m_fRotationCur;
- CVehicle *veh = (CVehicle*) reason;
- if (reason->IsVehicle() && veh->m_vehType == VEHICLE_TYPE_CAR && veh->m_nCarHornTimer != 0 && !IsPlayer()) {
- onlyRandomJump = true;
- }
-
- if (onlyRandomJump) {
- if (reason) {
- // Simple version of my bug fix below. Doesn't calculate "danger zone", selects jump direction randomly.
- // Also doesn't include random hands up, sound etc. Only used on player ped and peds running from gun shots.
-
- float vehDirection = CGeneral::GetRadianAngleBetweenPoints(
- veh->m_vecMoveSpeed.x, veh->m_vecMoveSpeed.y,
- 0.0f, 0.0f);
- angleToFace = (CGeneral::GetRandomNumber() & 1) * PI + (-0.5f*PI) + vehDirection;
- angleToFace = CGeneral::LimitRadianAngle(angleToFace);
- }
- } else {
- if (IsPlayer()) {
- ((CPlayerPed*)this)->m_nEvadeAmount = 5;
- ((CPlayerPed*)this)->m_pEvadingFrom = reason;
- reason->RegisterReference((CEntity**) &((CPlayerPed*)this)->m_pEvadingFrom);
- return;
- }
-
- angleToFace = CGeneral::GetRadianAngleBetweenPoints(
- reason->GetPosition().x, reason->GetPosition().y,
- GetPosition().x, GetPosition().y);
- angleToFace = CGeneral::LimitRadianAngle(angleToFace);
- m_fRotationCur = CGeneral::LimitRadianAngle(m_fRotationCur);
-
- // 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,
- 0.0f, 0.0f);
-
- // Let's turn our back to the "reason"
- angleToFace += PI;
-
- if (angleToFace > PI)
- angleToFace -= 2 * PI;
-
- // We don't want to dive towards car's direction
- float dangerZone = angleToFace - vehDirection;
- dangerZone = CGeneral::LimitRadianAngle(dangerZone);
-
- // So, add or subtract 90deg (jump to left/right) according to that
- if (dangerZone > 0.0f)
- angleToFace = 0.5f * PI + vehDirection;
- else
- angleToFace = vehDirection - 0.5f * PI;
-#endif
-
- neededTurn = Abs(angleToFace - m_fRotationCur);
-
- if (neededTurn > PI)
- neededTurn = 2 * PI - neededTurn;
-
- if (neededTurn <= 0.5f*PI) {
- if (CGeneral::GetRandomNumber() & 1)
- handsUp = true;
- } else {
- 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);
- }
-
- if (handsUp || !IsPlayer() && m_pedStats->m_flags & STAT_NO_DIVE) {
- m_fRotationCur = angleToFace;
- ClearLookFlag();
- ClearAimFlag();
- SetLookFlag(reason, true);
- animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_HANDSUP);
- if (animAssoc)
- return;
-
- animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_HANDSUP, 8.0f);
- animAssoc->flags &= ~ASSOC_DELETEFADEDOUT;
- animAssoc->SetFinishCallback(PedEvadeCB, this);
- SetStoredState();
- SetPedState(PED_STEP_AWAY);
- } else {
- m_fRotationCur = angleToFace;
- ClearLookFlag();
- ClearAimFlag();
- SetStoredState();
- m_nPedState = PED_DIVE_AWAY;
- animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_EV_DIVE, 8.0f);
- animAssoc->SetFinishCallback(PedEvadeCB, this);
- }
-
- if (reason->IsVehicle() && m_nPedType == PEDTYPE_COP) {
- if (veh->pDriver && veh->pDriver->IsPlayer()) {
- CWanted *wanted = FindPlayerPed()->m_pWanted;
- wanted->RegisterCrime_Immediately(CRIME_RECKLESS_DRIVING, GetPosition(), (uintptr)this, false);
- wanted->RegisterCrime_Immediately(CRIME_SPEEDING, GetPosition(), (uintptr)this, false);
- }
- }
-}
-
-// --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;
-
- if (m_attackTimer > CTimer::GetTimeInMilliseconds() || m_nWaitState == WAITSTATE_SURPRISE || (bIsDucking && !bCrouchWhenShooting))
- return;
-
- 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
- bIsAttacking = true;
-
- return;
- }
-
- if (GetWeapon()->m_eWeaponType == WEAPONTYPE_UNARMED || curWeapon->m_bFightMode || GetWeapon()->m_eWeaponType == WEAPONTYPE_BRASSKNUCKLE) {
- if (IsPlayer() ||
- (m_nPedState != PED_FIGHT && m_nMoveState != PEDMOVE_NONE && m_nMoveState != PEDMOVE_STILL
- && !(m_pedStats->m_flags & STAT_SHOPPING_BAGS) && curWeapon->m_bPartialAttack)) {
-
- if (m_nPedState != PED_ATTACK) {
- 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);
- }
- } else {
- 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) {
- 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 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 (m_nPedState == PED_ATTACK) {
- bIsAttacking = true;
- return;
- }
-
- if (IsPlayer() || (!victimPed || victimPed->IsPedInControl())) {
- if (IsPlayer())
- CPad::GetPad(0)->ResetAverageWeapon();
-
- PointBlankNecessity pointBlankStatus;
- if ((curWeapon->m_eWeaponFire == WEAPON_FIRE_INSTANT_HIT || GetWeapon()->m_eWeaponType == WEAPONTYPE_FLAMETHROWER)
- && 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
- && (pointBlankStatus = CheckForPointBlankPeds(victimPed)) != NO_POINT_BLANK_PED) {
- ClearAimFlag();
-
- // This condition is pointless
- if (pointBlankStatus == POINT_BLANK_FOR_WANTED_PED || !victimPed && (IsPlayer() || !m_carInObjective))
- StartFightAttack(200);
- } else {
- if (!curWeapon->m_bCanAim)
- m_pSeekTarget = nil;
-
- if (m_nPedState != PED_AIM_GUN)
- SetStoredState();
-
- SetPedState(PED_ATTACK);
- SetMoveState(PEDMOVE_NONE);
- 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;
-
- 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 {
- 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();
- if (animAssoc->currentTime == animAssoc->hierarchy->totalLength)
- animAssoc->SetCurrentTime(0.0f);
-
- animAssoc->SetFinishCallback(FinishedAttackCB, this);
- }
- return;
- }
-
- if (GetWeapon()->m_eWeaponType == WEAPONTYPE_BASEBALLBAT && victimPed->m_nPedState == PED_GETUP)
- SetWaitState(WAITSTATE_SURPRISE, nil);
-
- SetLookFlag(victim, true, true);
- SetLookTimer(100);
-}
-
-// --MIAMI: Done
-void
-CPed::StartFightAttack(uint8 buttonPressure)
-{
- if (!IsPedInControl() || (m_attackTimer > CTimer::GetTimeInMilliseconds() && buttonPressure != 0))
- return;
-
- if (m_nPedState == PED_FIGHT) {
- m_fightButtonPressure = buttonPressure;
- return;
- }
-
- if (m_nPedState != PED_AIM_GUN)
- SetStoredState();
-
- if (m_nWaitState != WAITSTATE_FALSE) {
- ClearWaitState();
- RestoreHeadingRate();
- }
-
- CAnimBlendAssociation* animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_RUN_STOP);
- if (!animAssoc)
- animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_RUN_STOP_R);
-
- if (animAssoc) {
- RestoreHeadingRate();
- }
- SetMoveState(PEDMOVE_NONE);
- m_nStoredMoveState = PEDMOVE_NONE;
- 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 {
- fightIdleAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_FIGHT_IDLE, 1000.0f);
- }
- m_lastFightMove = FIGHTMOVE_IDLE;
- m_curFightMove = IsPlayer() ? ChooseAttackPlayer(buttonPressure, fightWithWeapon) : ChooseAttackAI(buttonPressure, fightWithWeapon);
-
- SetPedState(PED_FIGHT);
- m_fightButtonPressure = 0;
-
- 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;
- }
-
- m_fightState = FIGHTSTATE_NO_MOVE;
- m_takeAStepAfterAttack = false;
- bIsAttacking = true;
-
- if (IsPlayer())
- nPlayerInComboMove = 0;
-}
-
-// --MIAMI: Done
-void
-CPed::LoadFightData(void)
+uint32
+CPed::ScanForThreats(void)
{
- float startFireTime, endFireTime, comboFollowOnTime, strikeRadius, extendReachMultiplier;
- int damage, flags;
- char line[256], moveName[32], animName[32], hitLevel;
- int moveId = 0;
-
- CAnimBlendAssociation *animAssoc;
-
- size_t bp, buflen;
- int lp, linelen;
-
- buflen = CFileMgr::LoadFile("DATA\\fistfite.dat", work_buff, sizeof(work_buff), "r");
-
- for (bp = 0; bp < buflen; ) {
- // read file line by line
- for (linelen = 0; work_buff[bp] != '\n' && bp < buflen; bp++) {
- line[linelen++] = work_buff[bp];
- }
- bp++;
- line[linelen] = '\0';
-
- // skip white space
- for (lp = 0; line[lp] <= ' ' && line[lp] != '\0'; lp++);
-
- if (line[lp] == '\0' ||
- line[lp] == '#')
- continue;
-
- sscanf(
- &line[lp],
- "%s %f %f %f %f %f %c %s %d %d",
- moveName,
- &startFireTime,
- &endFireTime,
- &comboFollowOnTime,
- &strikeRadius,
- &extendReachMultiplier,
- &hitLevel,
- animName,
- &damage,
- &flags);
-
- if (strncmp(moveName, "ENDWEAPONDATA", 13) == 0)
- return;
-
- tFightMoves[moveId].startFireTime = startFireTime / 30.0f;
- 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;
-
- switch (hitLevel) {
- case 'G':
- tFightMoves[moveId].hitLevel = HITLEVEL_GROUND;
- break;
- case 'H':
- tFightMoves[moveId].hitLevel = HITLEVEL_HIGH;
- break;
- case 'L':
- tFightMoves[moveId].hitLevel = HITLEVEL_LOW;
- break;
- case 'M':
- tFightMoves[moveId].hitLevel = HITLEVEL_MEDIUM;
- break;
- case 'N':
- tFightMoves[moveId].hitLevel = HITLEVEL_NULL;
- break;
- default:
- break;
- }
-
- 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++;
+ int fearFlags = m_fearFlags;
+ CVector ourPos = GetPosition();
+ float closestPedDist = 60.0f;
+ CVector2D explosionPos = GetPosition();
+ if (fearFlags & PED_FLAG_EXPLOSION && CheckForExplosions(explosionPos)) {
+ m_eventOrThreat = explosionPos;
+ return PED_FLAG_EXPLOSION;
}
-}
-
-// --MIAMI: Done
-// Actually GetLocalDirectionTo(Turn/Look)
-int
-CPed::GetLocalDirection(const CVector2D &posOffset)
-{
- int direction;
- float angle;
-
- for (angle = posOffset.Heading() - m_fRotationCur + DEGTORAD(45.0f); angle < 0.0f; angle += TWOPI);
-
- for (direction = RADTODEG(angle)/90.0f; direction > 3; direction -= 4);
-
- // 0-forward, 1-left, 2-backward, 3-right.
- return direction;
-}
-
-// --MIAMI: Done
-bool
-CPed::FightStrike(CVector &touchedNodePos, bool fightWithWeapon)
-{
- CColModel *hisCol;
- CVector attackDistance;
- float maxDistanceToBeat;
- CPed *nearPed;
- CVector extendedTouchPoint;
-
- 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;
- CGlass::BreakGlassPhysically(touchedNodePos, radius);
-
- for (int i = 0; i < m_numNearPeds; i++) {
- int8 pedFound = 0;
- nearPed = m_nearPeds[i];
- if (!fightWithWeapon && GetWeapon()->m_eWeaponType != WEAPONTYPE_UNARMED && GetWeapon()->m_eWeaponType != WEAPONTYPE_BRASSKNUCKLE)
- maxDistanceToBeat = nearPed->GetBoundRadius() + radius + 0.1f;
- else
- maxDistanceToBeat = nearPed->GetBoundRadius() + radius;
-
- 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(maxDistanceToBeat) > potentialAttackDistance.MagnitudeSqr()) {
-
- for (int j = 0; j < hisCol->numSpheres; j++) {
- attackDistance = hisCol->spheres[j].center;
- attackDistance -= touchedNodePos;
- CColSphere *hisPieces = hisCol->spheres;
- maxDistanceToBeat = hisPieces[j].radius + radius;
-
- // We can beat him too
- if (sq(maxDistanceToBeat) > attackDistance.MagnitudeSqr()) {
- 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 (m_fightState == FIGHTSTATE_NO_MOVE)
- m_fightState = FIGHTSTATE_1;
-
- 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;
- }
- }
-
- 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;
- }
- }
- 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;
-
- if (!victim->DyingOrDead()) {
- if(fightingWithWeapon)
- victim->InflictDamage(this, GetWeapon()->m_eWeaponType, damageMult, (ePedPieceTypes)piece, direction);
- else
- victim->InflictDamage(this, WEAPONTYPE_UNARMED, damageMult * 3.0f, (ePedPieceTypes)piece, direction);
- }
-
- if (CGame::nastyGame && weaponInfo->m_AnimToPlay == ASSOCGRP_KNIFE && m_curFightMove >= FIGHTMOVE_MELEE1
- && victim->GetIsOnScreen()) {
-
- static float particleRightLen = 0.05f;
- static float particleUpLen = 0.05f;
-
- // Just for particles. We will restore it below.
- dir /= (20.0f * dir.Magnitude());
- if (m_curFightMove == FIGHTMOVE_MELEE1) {
- float rightMult = -particleRightLen;
- dir += particleUpLen * GetUp() + rightMult * GetRight();
-
- } else if (m_curFightMove == FIGHTMOVE_MELEE2) {
- float upMult = 2.0f * particleUpLen;
- dir += particleRightLen * GetRight() + upMult * GetUp();
- }
- CParticle::AddParticle(PARTICLE_BLOOD_SPURT, bloodPos, dir, nil, 0.0f, 0, 0, 0, 0);
- CParticle::AddParticle(PARTICLE_BLOOD_SPURT, bloodPos, dir, nil, 0.0f, 0, 0, 0, 0);
- if (IsPlayer()) {
- CParticle::AddParticle(PARTICLE_BLOOD_SPURT, bloodPos, dir, nil, 0.0f, 0, 0, 0, 0);
- CParticle::AddParticle(PARTICLE_BLOOD_SPURT, bloodPos, dir, nil, 0.0f, 0, 0, 0, 0);
- }
- if (!(CGeneral::GetRandomNumber() & 3)) {
- CParticle::AddParticle(PARTICLE_TEST, bloodPos, dir, nil, 0.0f, 0, 0, 0, 0);
- }
- } else if (CGame::nastyGame && (tFightMoves[m_curFightMove].hitLevel > HITLEVEL_MEDIUM || fightingWithWeapon)
- && victim->GetIsOnScreen()) {
-
- // Just for particles. We will restore it below.
- dir /= (10.0f * dir.Magnitude());
- for (int i = 0; i < 4; i++) {
- CParticle::AddParticle(PARTICLE_BLOOD, bloodPos, dir, nil, 0.0f, 0, 0, 0, 0);
- }
- }
-
- eWeaponType weaponType = GetWeapon()->m_eWeaponType;
- if (!fightingWithWeapon) {
- if (!victim->OnGround()) {
- float curVictimHealth = victim->m_fHealth;
- if (curVictimHealth > 0.0f
- && (curVictimHealth < 30.0f && oldVictimHealth > 30.0f
- || weaponType != WEAPONTYPE_UNARMED && weaponType != WEAPONTYPE_BRASSKNUCKLE && IsPlayer()
- || victim->m_pedStats->m_flags & STAT_ONE_HIT_KNOCKDOWN || brassKnucklePunch)) {
-
- victim->SetFall(0, (AnimationId)(direction + ANIM_KO_SKID_FRONT), 0);
- if (victim->m_nPedState == PED_FALL)
- victim->bIsStanding = false;
- }
- }
- }
-
- 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 {
- moveMult = Min(damageMult * 2.0f, 14.0f);
+ 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;
}
- }
- victim->ApplyMoveForce(moveMult * 0.6 * dir);
- }
-
- if (weaponType != WEAPONTYPE_KNIFE && weaponType != WEAPONTYPE_MACHETE
- && weaponType != WEAPONTYPE_KATANA && weaponType != WEAPONTYPE_CHAINSAW) {
-
- 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
-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 (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);
}
}
}
- 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
+ CPed *deadPed;
+ if (fearFlags & PED_FLAG_DEADPEDS && CharCreatedBy != MISSION_CHAR
+ && (deadPed = CheckForDeadPeds()) != nil && (deadPed->GetPosition() - ourPos).MagnitudeSqr() < sq(20.0f)
#ifdef FIX_BUGS
- switch (CGeneral::GetRandomNumberInRange(0,4)) {
-#else
- switch (CGeneral::GetRandomNumberInRange(0,3)) {
+ && !deadPed->bIsInWater
#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
-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)) {
- return FIGHTMOVE_IDLE;
- }
-
- if (weaponInfo->m_bGround2nd)
- return FIGHTMOVE_MELEE2;
- if (weaponInfo->m_bGround3rd)
- return FIGHTMOVE_MELEE3;
-
- return FIGHTMOVE_GROUNDKICK;
- }
- 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_IDLE;
- } else {
- return FIGHTMOVE_GROUNDKICK;
- }
- }
- 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
-void
-CPed::SetFall(int extraTime, AnimationId animId, uint8 evenIfNotInControl)
-{
- if (m_attachedTo)
- return;
-
- if (!IsPedInControl() && (!evenIfNotInControl || DyingOrDead()))
- return;
-
- ClearLookFlag();
- ClearAimFlag();
- SetStoredState();
- SetPedState(PED_FALL);
- 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 = 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()) {
- if (fallAssoc->animId != ANIM_CAR_ROLLOUT_LHS && fallAssoc->animId != ANIM_CAR_ROLLOUT_RHS) {
- m_getUpTimer = 1000.0f * fallAssoc->hierarchy->totalLength
- + CTimer::GetTimeInMilliseconds()
- + 500.0f;
- } else {
- 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()
- + extraTime
- + ((m_randomSeed + CTimer::GetFrameCounter()) % 1000);
- }
+ ) {
+ m_pEventEntity = deadPed;
+ m_pEventEntity->RegisterReference((CEntity **) &m_pEventEntity);
+ return PED_FLAG_DEADPEDS;
} else {
- m_getUpTimer = extraTime
- + CTimer::GetTimeInMilliseconds()
- + 1000
- + ((m_randomSeed + CTimer::GetFrameCounter()) % 1000);
- }
- bFallenDown = true;
-}
-
-// --MIAMI: Done
-void
-CPed::SetFlee(CEntity *fleeFrom, int time)
-{
- if (!IsPedInControl() || bKindaStayInSamePlace || !fleeFrom)
- return;
-
- SetStoredState();
- SetPedState(PED_FLEE_ENTITY);
- bUsePedNodeSeek = true;
- SetMoveState(PEDMOVE_RUN);
- m_fleeFrom = fleeFrom;
- m_fleeFrom->RegisterReference((CEntity **) &m_fleeFrom);
-
- if (time <= 0)
- m_fleeTimer = 0;
- else
- m_fleeTimer = CTimer::GetTimeInMilliseconds() + time;
-
- float angleToFace = CGeneral::GetRadianAngleBetweenPoints(
- GetPosition().x, GetPosition().y,
- fleeFrom->GetPosition().x, fleeFrom->GetPosition().y);
-
- m_fRotationDest = CGeneral::LimitRadianAngle(angleToFace);
- if (m_fRotationCur - PI > m_fRotationDest) {
- m_fRotationDest += 2 * PI;
- } else if (PI + m_fRotationCur < m_fRotationDest) {
- m_fRotationDest -= 2 * PI;
- }
-}
-
-// --MIAMI: Done
-void
-CPed::SetFlee(CVector2D const &from, int time)
-{
- if (CTimer::GetTimeInMilliseconds() < m_nPedStateTimer || !IsPedInControl() || bKindaStayInSamePlace)
- return;
-
- if (m_nPedState != PED_FLEE_ENTITY) {
- SetStoredState();
- SetPedState(PED_FLEE_POS);
- SetMoveState(PEDMOVE_RUN);
- m_fleeFromPos = from;
- }
-
- bUsePedNodeSeek = true;
- m_pNextPathNode = nil;
- m_fleeTimer = CTimer::GetTimeInMilliseconds() + time;
-
- float angleToFace = CGeneral::GetRadianAngleBetweenPoints(
- GetPosition().x, GetPosition().y,
- from.x, from.y);
-
- m_fRotationDest = CGeneral::LimitRadianAngle(angleToFace);
- if (m_fRotationCur - PI > m_fRotationDest) {
- m_fRotationDest += 2 * PI;
- } else if (PI + m_fRotationCur < m_fRotationDest) {
- m_fRotationDest -= 2 * PI;
- }
-}
-
-// --MIAMI: Done
-void
-CPed::SetWaitState(eWaitState state, void *time)
-{
- 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);
-
- switch (state) {
- case WAITSTATE_TRAFFIC_LIGHTS:
- m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 500;
- SetMoveState(PEDMOVE_STILL);
- break;
- case WAITSTATE_CROSS_ROAD:
- m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 1000;
- CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_IDLE_HBHB, 4.0f);
- break;
- case WAITSTATE_CROSS_ROAD_LOOK:
- CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_ROAD_CROSS, 8.0f);
+ uint32 flagsOfNearPed = 0;
- if (time)
- m_nWaitTimer = CTimer::GetTimeInMilliseconds() + *(int*)time;
- else
- m_nWaitTimer = CTimer::GetTimeInMilliseconds() + CGeneral::GetRandomNumberInRange(2000,5000);
-
- break;
- case WAITSTATE_LOOK_PED:
- 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;
- m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 3500;
- animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_IDLE_HBHB, 4.0f);
-#ifdef FIX_BUGS
- animAssoc->SetFinishCallback(RestoreHeadingRateCB, this);
-#endif
- break;
- case WAITSTATE_HITWALL:
- m_headingRate = 2.0f;
- m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 5000;
- animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_HIT_WALL, 16.0f);
- animAssoc->flags |= ASSOC_DELETEFADEDOUT;
- animAssoc->flags |= ASSOC_FADEOUTWHENDONE;
- animAssoc->SetDeleteCallback(FinishedWaitCB, this);
-
- if (m_objective == OBJECTIVE_ENTER_CAR_AS_PASSENGER && CharCreatedBy == RANDOM_CHAR && m_nPedState == PED_SEEK_CAR) {
- ClearObjective();
- RestorePreviousState();
- m_hitRecoverTimer = CTimer::GetTimeInMilliseconds() + 30000;
- }
- break;
- case WAITSTATE_TURN180:
- m_headingRate = 0.0f;
- m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 5000;
- animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_TURN_180, 4.0f);
- animAssoc->SetFinishCallback(FinishedWaitCB, this);
- break;
- case WAITSTATE_SURPRISE:
- m_headingRate = 0.0f;
- m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 2000;
- animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_HIT_WALL, 4.0f);
- animAssoc->SetFinishCallback(FinishedWaitCB, this);
- break;
- case WAITSTATE_STUCK:
- SetMoveState(PEDMOVE_STILL);
- SetMoveAnim();
- m_headingRate = 0.0f;
- m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 5000;
- animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_IDLE_TIRED, 4.0f);
-#ifdef FIX_BUGS
- 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();
- m_hitRecoverTimer = CTimer::GetTimeInMilliseconds() + 30000;
- }
- break;
- case WAITSTATE_LOOK_ABOUT:
- SetMoveState(PEDMOVE_STILL);
- SetMoveAnim();
- m_headingRate = 0.0f;
- m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 5000;
- animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_IDLE_HBHB, 4.0f);
-#ifdef FIX_BUGS
- animAssoc->SetFinishCallback(RestoreHeadingRateCB, this);
-#endif
-
- break;
- case WAITSTATE_PLAYANIM_COWER:
- waitAnim = ANIM_HANDSCOWER;
- case WAITSTATE_PLAYANIM_HANDSUP:
- if (waitAnim == NUM_STD_ANIMS)
- waitAnim = ANIM_HANDSUP;
- case WAITSTATE_PLAYANIM_HANDSCOWER:
- if (waitAnim == NUM_STD_ANIMS)
- waitAnim = ANIM_HANDSCOWER;
- m_headingRate = 0.0f;
- if (time)
- m_nWaitTimer = CTimer::GetTimeInMilliseconds() + *(int*)time;
- else
- m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 3000;
-
- animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, waitAnim, 4.0f);
- animAssoc->SetDeleteCallback(FinishedWaitCB, this);
- break;
- case WAITSTATE_PLAYANIM_DUCK:
- waitAnim = ANIM_DUCK_DOWN;
- case WAITSTATE_PLAYANIM_TAXI:
- if (waitAnim == NUM_STD_ANIMS)
- waitAnim = ANIM_IDLE_TAXI;
- case WAITSTATE_PLAYANIM_CHAT:
- if (waitAnim == NUM_STD_ANIMS)
- waitAnim = ANIM_IDLE_CHAT;
- if (time)
- m_nWaitTimer = CTimer::GetTimeInMilliseconds() + *(int*)time;
- else
- m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 3000;
+ CPed *pedToFearFrom = nil;
+ bool weSawOurEnemy = false;
+ bool weMaySeeOurEnemy = false;
+ float closestEnemyDist = 60.0f;
+ if ((CTimer::GetFrameCounter() + (uint8)m_randomSeed + 16) & 4) {
- animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, waitAnim, 4.0f);
- animAssoc->flags &= ~ASSOC_FADEOUTWHENDONE;
- animAssoc->flags |= ASSOC_DELETEFADEDOUT;
- animAssoc->SetDeleteCallback(FinishedWaitCB, this);
- break;
- case WAITSTATE_FINISH_FLEE:
- SetMoveState(PEDMOVE_STILL);
- SetMoveAnim();
- m_headingRate = 0.0f;
- m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 2500;
- animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_IDLE_TIRED, 4.0f);
-#ifdef FIX_BUGS
- 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);
+ for (int i = 0; i < m_numNearPeds; ++i) {
+ if (CharCreatedBy == RANDOM_CHAR && m_nearPeds[i]->CharCreatedBy == MISSION_CHAR && !m_nearPeds[i]->IsPlayer()) {
+ continue;
}
- }
- 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:
- ClearWaitState();
- RestoreHeadingRate();
- return;
- }
- m_nWaitState = state;
-}
-
-// --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 17, total 17), second is the one of we fight with (from 18 to 27, total 10).
- enum {
- 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
- };
- 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 }
- };
-
- 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;
+ // BUG: Putting this here will result in returning the flags of farthest ped to us, since m_nearPeds is sorted by distance.
+ // Fixed at the bottom of the function.
+ flagsOfNearPed = CPedType::GetFlag(m_nearPeds[i]->m_nPedType);
- // 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];
-
- } else {
- if (hitTo->m_nPedState == PED_DEAD || hitTo->UseGroundColModel()) {
- soundId = hitSoundsByFightMoves[m_curFightMove - FIGHTMOVE_STDPUNCH][FIGHTMOVE_HITONFLOOR - FIGHTMOVE_HITFRONT];
- } else {
- soundId = hitSoundsByFightMoves[m_curFightMove - FIGHTMOVE_STDPUNCH][FIGHTMOVE_HITFRONT - FIGHTMOVE_HITFRONT];
- }
- }
-
- if (soundId != NO_SND)
- DMAudio.PlayOneShot(m_audioEntityId, soundId, (weapon << 8) | 3);
-}
-
-// --MIAMI: Done
-void
-CPed::CollideWithPed(CPed *collideWith)
-{
- CAnimBlendAssociation *animAssoc;
- AnimationId animToPlay;
-
- bool weAreMissionChar = CharCreatedBy == MISSION_CHAR;
- bool heIsMissionChar = collideWith->CharCreatedBy == MISSION_CHAR;
- CVector posDiff = collideWith->GetPosition() - GetPosition();
- 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;
-
- if (m_nMoveState != PEDMOVE_NONE && m_nMoveState != PEDMOVE_STILL) {
-
- if ((!IsPlayer() || ((CPlayerPed*)this)->m_fMoveSpeed <= 1.8f)
- && (IsPlayer() || heIsMissionChar && weAreMissionChar || m_nMoveState != PEDMOVE_RUN && m_nMoveState != PEDMOVE_SPRINT
- || m_objective == OBJECTIVE_FOLLOW_CHAR_IN_FORMATION && m_pedInObjective == collideWith
- || 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) {
-
- if (CTimer::GetTimeInMilliseconds() > m_nPedStateTimer) {
-
- if (heIsMissionChar || !weAreMissionChar && collideWith->m_nMoveState != PEDMOVE_STILL) {
-
- if (weAreMissionChar && (m_nPedState == PED_SEEK_POS || m_nPedState == PED_SEEK_ENTITY)) {
-
- if (collideWith->m_nMoveState != PEDMOVE_STILL
- && (!collideWith->IsPlayer() || collideWith->IsPlayer() && CPad::GetPad(0)->ArePlayerControlsDisabled())) {
- float seekPosDist = (GetPosition() - m_vecSeekPos).MagnitudeSqr2D();
- float heAndSeekPosDist = (collideWith->GetPosition() - m_vecSeekPos).MagnitudeSqr2D();
+ if (flagsOfNearPed & fearFlags) {
+ if (m_nearPeds[i]->m_fHealth > 0.0f) {
+ if (OurPedCanSeeThisOne(m_nearPeds[i], !!bIgnoreThreatsBehindObjects)) {
+ if (m_nearPeds[i]->m_nPedState == PED_ATTACK) {
+ if (m_nearPeds[i]->m_pedInObjective == this) {
- if (seekPosDist <= heAndSeekPosDist) {
- waitTime = 1000;
- collideWith->SetWaitState(WAITSTATE_CROSS_ROAD_LOOK, &waitTime);
- collideWith->m_nPedStateTimer = CTimer::GetTimeInMilliseconds() + waitTime;
- } else {
- waitTime = 500;
- SetWaitState(WAITSTATE_CROSS_ROAD_LOOK, &waitTime);
- m_nPedStateTimer = CTimer::GetTimeInMilliseconds() + waitTime;
+ float enemyDistSqr = (m_nearPeds[i]->GetPosition() - ourPos).MagnitudeSqr2D();
+ if (sq(closestEnemyDist) > enemyDistSqr) {
+ float enemyDist = Sqrt(enemyDistSqr);
+ weSawOurEnemy = true;
+ closestPedDist = enemyDist;
+ closestEnemyDist = enemyDist;
+ pedToFearFrom = m_nearPeds[i];
}
- } else if (collideWith->m_nMoveState == PEDMOVE_STILL) {
- SetDirectionToWalkAroundObject(collideWith);
}
} else {
- 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 {
- SetDirectionToWalkAroundObject(collideWith);
+ float nearPedDistSqr = (m_nearPeds[i]->GetPosition() - ourPos).MagnitudeSqr2D();
+ if (sq(closestPedDist) > nearPedDistSqr && !weSawOurEnemy) {
+ closestPedDist = Sqrt(nearPedDistSqr);
+ pedToFearFrom = m_nearPeds[i];
}
}
- } else {
- if (m_pedStats->m_temper <= m_pedStats->m_fear
- || GetWeapon()->m_eWeaponType != WEAPONTYPE_UNARMED
- || weAreMissionChar
- || collideWith->m_nPedType == PEDTYPE_CIVFEMALE
- || collideWith->m_nPedType == m_nPedType
- || collideWith->GetWeapon()->m_eWeaponType != WEAPONTYPE_UNARMED) {
- SetDirectionToWalkAroundObject(collideWith);
- Say(SOUND_PED_CHAT);
- } else {
- TurnBody();
- SetAttack(collideWith);
- m_fRotationCur = 0.3f + m_fRotationCur;
- m_fRotationDest = m_fRotationCur;
- }
- m_nPedStateTimer = CTimer::GetTimeInMilliseconds() + CGeneral::GetRandomNumberInRange(250, 450);
- }
- }
- } else {
- if (m_pedInObjective && (collideWith == m_pedInObjective || collideWith->m_pedInObjective == m_pedInObjective) && CTimer::GetTimeInMilliseconds() > m_nPedStateTimer) {
- if (heLooksToUs) {
- SetEvasiveStep(collideWith, 1);
- m_nPedStateTimer = CTimer::GetTimeInMilliseconds() + 3000;
- }
- } else if (weDontLookToHim && IsPedInControl()) {
-
- if (m_pedStats != collideWith->m_pedStats) {
+ } else if (!weSawOurEnemy) {
+ CPed *nearPed = m_nearPeds[i];
+ if (nearPed->m_nPedState == PED_ATTACK) {
+ CColPoint foundCol;
+ CEntity *foundEnt;
- if (collideWith->m_pedStats->m_fear <= 100 - m_pedStats->m_temper || collideWith->IsPlayer()
- || CTimer::GetTimeInMilliseconds() < m_nPedStateTimer) {
+ // We don't see him yet but he's behind a ped, vehicle or object
+ if (!CWorld::ProcessLineOfSight(ourPos, nearPed->GetPosition(), foundCol, foundEnt,
+ true, false, false, !!bIgnoreThreatsBehindObjects, false, false, false)) {
- if (collideWith->IsPlayer()) {
- // He's on our right side
- if (DotProduct(posDiff,GetRight()) <= 0.0f)
- m_fRotationCur -= m_headingRate;
- else
- m_fRotationCur += m_headingRate;
- } else {
- // He's on our right side
- if (DotProduct(posDiff, collideWith->GetRight()) <= 0.0f)
- collideWith->m_fRotationCur -= collideWith->m_headingRate;
- else
- collideWith->m_fRotationCur += collideWith->m_headingRate;
- }
- } else {
- SetLookFlag(collideWith, false);
- TurnBody();
- animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_FIGHT_PPUNCH, 8.0f);
- animAssoc->flags |= ASSOC_FADEOUTWHENDONE;
- m_nPedStateTimer = CTimer::GetTimeInMilliseconds() + 2000;
- if (!heIsMissionChar) {
- CVector2D posDiff2D(posDiff);
- int direction = collideWith->GetLocalDirection(posDiff2D);
- collideWith->StartFightDefend(direction, HITLEVEL_HIGH, 5);
+ if (nearPed->m_pedInObjective == this) {
+ float enemyDistSqr = (m_nearPeds[i]->GetPosition() - ourPos).MagnitudeSqr2D();
+ if (sq(closestEnemyDist) > enemyDistSqr) {
+ float enemyDist = Sqrt(enemyDistSqr);
+ weMaySeeOurEnemy = true;
+ closestPedDist = enemyDist;
+ closestEnemyDist = enemyDist;
+ pedToFearFrom = m_nearPeds[i];
+ }
+ } else if (!nearPed->GetWeapon()->IsTypeMelee() && !weMaySeeOurEnemy) {
+ float nearPedDistSqr = (m_nearPeds[i]->GetPosition() - ourPos).MagnitudeSqr2D();
+ if (sq(closestPedDist) > nearPedDistSqr) {
+ weMaySeeOurEnemy = true;
+ closestPedDist = Sqrt(nearPedDistSqr);
+ pedToFearFrom = m_nearPeds[i];
+ }
+ }
}
}
}
}
}
- } 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();
- moveForce.z += 0.1f;
- ApplyMoveForce(moveForce);
- if (collideWith->m_nMoveState != PEDMOVE_RUN && collideWith->m_nMoveState != PEDMOVE_SPRINT)
- animToPlay = ANIM_HIT_LEFT;
- else
- animToPlay = ANIM_SHOT_LEFT_PARTIAL;
- } else if (heLooksToUs) {
- CVector moveForce = GetRight() * -1.0f;
- moveForce.z += 0.1f;
- ApplyMoveForce(moveForce);
- if (collideWith->m_nMoveState != PEDMOVE_RUN && collideWith->m_nMoveState != PEDMOVE_SPRINT)
- animToPlay = ANIM_HIT_RIGHT;
- else
- animToPlay = ANIM_SHOT_RIGHT_PARTIAL;
- } else {
- if (collideWith->m_nMoveState != PEDMOVE_RUN && collideWith->m_nMoveState != PEDMOVE_SPRINT)
- animToPlay = ANIM_HIT_BACK;
- else
- animToPlay = ANIM_SHOT_BACK_PARTIAL;
- }
-
- if (collideWith->IsPedInControl() && CTimer::GetTimeInMilliseconds() > collideWith->m_nPedStateTimer) {
- animAssoc = CAnimManager::BlendAnimation(collideWith->GetClump(), ASSOCGRP_STD, animToPlay, 8.0f);
- animAssoc->flags |= ASSOC_FADEOUTWHENDONE;
- collideWith->m_nPedStateTimer = CTimer::GetTimeInMilliseconds() + 1000;
- if (m_nPedState == PED_ATTACK)
- DMAudio.PlayOneShot(m_audioEntityId, SOUND_FIGHT_46, 0.0f);
- }
- } else {
- // We're at his right side
- if (DotProduct(posDiff, collideWith->GetRight()) <= 0.0f) {
- CVector moveForce = GetRight() * -1.0f;
- moveForce.z += 0.1f;
- ApplyMoveForce(moveForce);
- if (heLooksToUs)
- animToPlay = ANIM_KO_SPIN_L;
- else
- animToPlay = ANIM_KD_RIGHT;
- } else {
- CVector moveForce = GetRight();
- moveForce.z += 0.1f;
- ApplyMoveForce(moveForce);
- if (heLooksToUs)
- animToPlay = ANIM_KO_SPIN_R;
- else
- animToPlay = ANIM_KD_LEFT;
- }
-
- if (m_nPedState == PED_ATTACK && collideWith->IsPedInControl())
- DMAudio.PlayOneShot(m_audioEntityId, SOUND_49, 0.0f);
-
- collideWith->SetFall(3000, animToPlay, 0);
- }
- } else {
- if (!IsPedInControl())
- return;
-
- if (collideWith->m_nMoveState == PEDMOVE_NONE || collideWith->m_nMoveState == PEDMOVE_STILL)
- return;
-
- if (m_nPedType != collideWith->m_nPedType || m_nPedType == PEDTYPE_CIVMALE || m_nPedType == PEDTYPE_CIVFEMALE) {
-
- if (!weAreMissionChar && heLooksToUs && m_pedStats->m_fear > 100 - collideWith->m_pedStats->m_temper) {
-
- if (CGeneral::GetRandomNumber() & 1 && CTimer::GetTimeInMilliseconds() < m_nPedStateTimer){
- SetEvasiveStep(collideWith, 2);
- m_nPedStateTimer = CTimer::GetTimeInMilliseconds() + 3000;
- } else if (collideWith->m_nMoveState > PEDMOVE_WALK) {
- waitTime = 2000;
- SetWaitState(WAITSTATE_PLAYANIM_DUCK, &waitTime);
- }
- }
- } else if (heLooksToUs
- && collideWith->m_nPedState != PED_STEP_AWAY
- && m_nPedState != PED_STEP_AWAY
- && CTimer::GetTimeInMilliseconds() > m_nPedStateTimer) {
-
- SetEvasiveStep(collideWith, 1);
- m_nPedStateTimer = CTimer::GetTimeInMilliseconds() + 3000;
}
}
- if (IsPlayer()) {
- SetLookFlag(collideWith, true);
- SetLookTimer(800);
- }
- } else {
- bool isRunning = m_nMoveState == PEDMOVE_RUN || m_nMoveState == PEDMOVE_SPRINT;
- SetFindPathAndFlee(collideWith, 5000, !isRunning);
- }
-}
-
-// --MIAMI: Done
-void
-CPed::CreateDeadPedMoney(void)
-{
- if (!CGame::nastyGame)
- return;
-
- if ((GetModelIndex() >= MI_COP && GetModelIndex() <= MI_FIREMAN) || (CharCreatedBy == MISSION_CHAR && !bMoneyHasBeenGivenByScript) || bInVehicle)
- return;
-
- int money = m_nPedMoney;
- if (money < 10)
- return;
-
- CVector pickupPos = GetPosition();
- CPickups::CreateSomeMoney(pickupPos, money);
- m_nPedMoney = 0;
-}
-
-// --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((CGeneral::GetRandomNumber() % 256) * PI / 128) + GetPosition().x;
- pickupPos.y = 1.5f * Cos((CGeneral::GetRandomNumber() % 256) * PI / 128) + GetPosition().y;
- pickupPos.z = CWorld::FindGroundZFor3DCoord(pickupPos.x, pickupPos.y, pickupPos.z, &found) + 0.5f;
-
- if (!found)
- continue;
-
- CVector pedPos = GetPosition();
- pedPos.z += 0.3f;
-
- CVector pedToPickup = pickupPos - pedPos;
- float distance = pedToPickup.Magnitude();
-
- // outer edge of pickup
- distance = (distance + 0.4f) / distance;
- CVector pickupPos2 = pedPos;
- pickupPos2 += distance * pedToPickup;
-
- if ((pickupPos - FindPlayerCoors()).Magnitude2D() > 2.0f || i > NUMBER_OF_ATTEMPTS / 2) {
+ int16 lastVehicle;
+ CEntity* vehicles[8];
+ CWorld::FindObjectsInRange(ourPos, 20.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];
- if (i > NUMBER_OF_ATTEMPTS / 2 || !CPickups::TestForPickupsInBubble(pickupPos, 1.3f)) {
+ CPed *driver = nearVeh->pDriver;
+ if (driver) {
- if (CWorld::GetIsLineOfSightClear(pickupPos2, pedPos,
- true, i < NUMBER_OF_ATTEMPTS / 2, false, i < NUMBER_OF_ATTEMPTS / 2, false, false, false)) {
+ // BUG: Same bug as above. Fixed at the bottom of function.
+ flagsOfNearPed = CPedType::GetFlag(driver->m_nPedType);
+ if (flagsOfNearPed & fearFlags) {
- 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 (driver->m_fHealth > 0.0f && OurPedCanSeeThisOne(nearVeh->pDriver)) {
+ // FIX: Taken from VC
+#ifdef FIX_BUGS
+ float driverDistSqr = (driver->GetPosition() - ourPos).MagnitudeSqr2D();
+#else
+ float driverDistSqr = (CVector2D(ourPos) - explosionPos).MagnitudeSqr();
+#endif
+ if (sq(closestPedDist) > driverDistSqr) {
+ closestPedDist = Sqrt(driverDistSqr);
+ pedToFearFrom = nearVeh->pDriver;
+ }
}
}
}
}
- }
- *x = GetPosition().x;
- *y = GetPosition().y;
- *z = GetPosition().z + 0.4f;
-#undef NUMBER_OF_ATTEMPTS
-}
-
-// --MIAMI: Done
-void
-CPed::CreateDeadPedWeaponPickups(void)
-{
- CVector pickupPos;
-
- if (bInVehicle)
- return;
-
- for(int i = 0; i < TOTAL_WEAPON_SLOTS; i++) {
+ m_threatEntity = pedToFearFrom;
+ if (m_threatEntity)
+ m_threatEntity->RegisterReference((CEntity **) &m_threatEntity);
- eWeaponType weapon = GetWeapon(i).m_eWeaponType;
- int weaponAmmo = GetWeapon(i).m_nAmmoTotal;
- if (weapon == WEAPONTYPE_UNARMED || weapon == WEAPONTYPE_DETONATOR || (weaponAmmo == 0 && !GetWeapon(i).IsTypeMelee()))
- continue;
+#ifdef FIX_BUGS
+ if (pedToFearFrom)
+ flagsOfNearPed = CPedType::GetFlag(((CPed*)m_threatEntity)->m_nPedType);
+ else
+ flagsOfNearPed = 0;
+#endif
- 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));
- }
+ return flagsOfNearPed;
}
- ClearWeapons();
}
// --MIAMI: Done
void
-CPed::SetAttackTimer(uint32 time)
-{
- if (CTimer::GetTimeInMilliseconds() > m_attackTimer)
- m_attackTimer = Max(m_shootTimer, CTimer::GetTimeInMilliseconds()) + time;
-}
-
-// --MIAMI: Done
-void
-CPed::SetBeingDraggedFromCar(CVehicle *veh, uint32 vehEnterType, bool quickJack)
+CPed::ScanForDelayedResponseThreats(void)
{
- if (m_nPedState == PED_DRAG_FROM_CAR)
+ if (m_threatFlags)
return;
- bUsesCollision = false;
- m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f);
- m_nLastPedState = PED_IDLE;
- SetMoveState(PEDMOVE_STILL);
- m_pSeekTarget = veh;
- m_pSeekTarget->RegisterReference((CEntity **) &m_pSeekTarget);
-
- 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);
- else
- veh->SetStatus(STATUS_ABANDONED);
- }
- RemoveInCarAnims();
- SetMoveState(PEDMOVE_NONE);
- LineUpPedWithCar(veh->IsBike() ? LINE_UP_TO_CAR_FALL : LINE_UP_TO_CAR_START);
- m_pVehicleAnim = nil;
- SetPedState(PED_DRAG_FROM_CAR);
- bChangedSeat = false;
- bWillBeQuickJacked = quickJack;
-
- SetHeading(m_fRotationCur);
-
- Say(SOUND_PED_CAR_JACKED);
- SetRadioStation();
-
- if(veh->IsBike())
- veh->m_nGettingOutFlags |= GetBikeDoorFlagInclJumpInFromFront(m_vehEnterType);
- else
- veh->m_nGettingOutFlags |= GetCarDoorFlag(m_vehEnterType);
-}
-
-// --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);
+ m_threatEntity = nil;
+ m_pEventEntity = nil;
+ m_threatFlags = ScanForThreats();
+ if (m_threatFlags) {
+ if (m_threatEntity || m_pEventEntity) {
+ m_threatCheckTimer = CTimer::GetTimeInMilliseconds() + m_threatCheckInterval;
return;
}
- SetObjective(OBJECTIVE_NONE);
- SetWanderPath(CGeneral::GetRandomNumberInRange(0, 8));
- } else {
- SetObjective(OBJECTIVE_NONE);
- SetWanderPath(CGeneral::GetRandomNumberInRange(0, 8));
- }
-}
-
-// --MIAMI: Done
-void
-CPed::SetBuyIceCream(void)
-{
- if (m_nPedState == PED_BUY_ICECREAM || !IsPedInControl())
- return;
-
- if (!m_carInObjective)
- return;
-
- SetPedState(PED_BUY_ICECREAM);
-}
-
-// --MIAMI: Done
-void
-CPed::SetChat(CEntity *chatWith, uint32 time)
-{
- if (m_nPedState != PED_CHAT) {
- m_nLastPedState = PED_NONE;
- SetStoredState();
- }
-
- SetPedState(PED_CHAT);
- SetMoveState(PEDMOVE_STILL);
- m_lookTimer = 0;
- SetLookFlag(chatWith, true);
- m_standardTimer = CTimer::GetTimeInMilliseconds() + time;
- m_lookTimer = CTimer::GetTimeInMilliseconds() + 3000;
-}
-
-// --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);
- }
-}
-
-// --MIAMI: Done
-void
-CPed::SetDead(void)
-{
- if (!RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DROWN))
- bUsesCollision = false;
-
- m_fHealth = 0.0f;
- if (m_nPedState == PED_DRIVING)
- bIsVisible = false;
-
- SetPedState(PED_DEAD);
- m_pVehicleAnim = nil;
- m_pCollidingEntity = nil;
-
- CWeaponInfo *weapon = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType);
- RemoveWeaponModel(weapon->m_nModelId);
-
- m_currentWeapon = WEAPONTYPE_UNARMED;
- CEventList::RegisterEvent(EVENT_INJURED_PED, EVENT_ENTITY_PED, this, nil, 250);
- if (this != FindPlayerPed()) {
- RemoveWeaponAnims(0, -1000.0f);
- CreateDeadPedWeaponPickups();
- CreateDeadPedMoney();
+ m_threatFlags = 0;
}
-
- m_bloodyFootprintCountOrDeathTime = CTimer::GetTimeInMilliseconds();
- m_deadBleeding = false;
- bDoBloodyFootprints = false;
- bVehExitWillBeInstant = false;
- CEventList::RegisterEvent(EVENT_DEAD_PED, EVENT_ENTITY_PED, this, nil, 1000);
-}
-
-// --MIAMI: Done
-void
-CPed::SetSeek(CEntity *seeking, float distanceToCountDone)
-{
- if (!IsPedInControl())
- return;
-
- if (m_nPedState == PED_SEEK_ENTITY && m_pSeekTarget == seeking)
- return;
-
- if (!seeking || m_nPedState == PED_FOLLOW_PATH)
- return;
-
- if (m_nPedState != PED_SEEK_ENTITY)
- SetStoredState();
-
- SetPedState(PED_SEEK_ENTITY);
- m_distanceToCountSeekDone = distanceToCountDone;
- m_pSeekTarget = seeking;
- m_pSeekTarget->RegisterReference((CEntity **) &m_pSeekTarget);
- SetMoveState(PEDMOVE_STILL);
+ m_threatCheckTimer = 0;
}
// --MIAMI: Done
void
-CPed::SetSeek(CVector pos, float distanceToCountDone)
+CPed::CheckThreatValidity(void)
{
- if (!IsPedInControl()
- || (m_nPedState == PED_SEEK_POS && m_vecSeekPos.x == pos.x && m_vecSeekPos.y == pos.y) || m_nPedState == PED_FOLLOW_PATH)
- return;
-
- if (!CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bCanAimWithArm) {
- ClearPointGunAt();
+ if (m_threatEntity && !IsEntityPointerValid(m_threatEntity)) {
+ m_threatFlags = 0;
+ m_threatEntity = nil;
}
-
- if (m_nPedState != PED_SEEK_POS)
- SetStoredState();
-
- SetPedState(PED_SEEK_POS);
- m_distanceToCountSeekDone = distanceToCountDone;
- m_vecSeekPos = pos;
-}
-
-// --MIAMI: Done
-void
-CPed::DeadPedMakesTyresBloody(void)
-{
- int minX = CWorld::GetSectorIndexX(GetPosition().x - 2.0f);
- if (minX < 0) minX = 0;
- int minY = CWorld::GetSectorIndexY(GetPosition().y - 2.0f);
- if (minY < 0) minY = 0;
- int maxX = CWorld::GetSectorIndexX(GetPosition().x + 2.0f);
- if (maxX > NUMSECTORS_X-1) maxX = NUMSECTORS_X-1;
- int maxY = CWorld::GetSectorIndexY(GetPosition().y + 2.0f);
- if (maxY > NUMSECTORS_Y-1) maxY = NUMSECTORS_Y-1;
-
- CWorld::AdvanceCurrentScanCode();
-
- for (int curY = minY; curY <= maxY; curY++) {
- for (int curX = minX; curX <= maxX; curX++) {
- CSector *sector = CWorld::GetSector(curX, curY);
- MakeTyresMuddySectorList(sector->m_lists[ENTITYLIST_VEHICLES]);
- MakeTyresMuddySectorList(sector->m_lists[ENTITYLIST_VEHICLES_OVERLAP]);
- }
+ if (m_pEventEntity && !IsEntityPointerValid(m_pEventEntity)) {
+ m_threatFlags = 0;
+ m_pEventEntity = nil;
}
-}
-
-// --MIAMI: Done
-void
-CPed::Die(void)
-{
- // UNUSED: This is a perfectly empty function.
+ if (!m_threatEntity && !m_pEventEntity)
+ m_threatFlags = 0;
}
// --MIAMI: Done
bool
-CPed::DuckAndCover(void)
+CPed::CanUseTorsoWhenLooking(void)
{
- if (!m_pedInObjective || CTimer::GetTimeInMilliseconds() <= m_duckAndCoverTimer)
- return false;
-
- if (bKindaStayInSamePlace){
-
- if (CTimer::GetTimeInMilliseconds() <= m_leaveCarTimer) {
- if (!m_pLookTarget || m_pLookTarget != m_pedInObjective) {
- m_pLookTarget = m_pedInObjective;
- m_pLookTarget->RegisterReference((CEntity **) &m_pLookTarget);
- }
- if (!bIsAimingGun)
- SetAimFlag(m_pedInObjective);
-
- } else {
- bKindaStayInSamePlace = false;
- if (bIsDucking)
- ClearDuck(true);
-
- bCrouchWhenShooting = false;
- bDuckAndCover = false;
- m_headingRate = 10.0f;
- m_duckAndCoverTimer = CTimer::GetTimeInMilliseconds() + CGeneral::GetRandomNumberInRange(20000,30000);
- if (m_pSeekTarget && m_pSeekTarget->IsVehicle())
- ((CVehicle*)m_pSeekTarget)->m_numPedsUseItAsCover--;
- }
- return false;
- }
-
- int16 lastVehicle = 0;
- CEntity* vehicles[8];
-
- bool justDucked = false;
- CVehicle *foundVeh = nil;
- float maxDist = 225.0f;
- if (bIsDucking)
- ClearDuck(true);
-
- bCrouchWhenShooting = false;
- bool duckingWithoutVeh = false;
- if (CTimer::GetTimeInMilliseconds() > m_leaveCarTimer) {
-
- 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->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;
- foundVeh = veh;
- }
- }
- }
- if (foundVeh) {
- // Unused.
- // CVector lfWheelPos, rfWheelPos;
- // foundVeh->GetComponentWorldPosition(CAR_WHEEL_RF, rfWheelPos);
- // foundVeh->GetComponentWorldPosition(CAR_WHEEL_LF, lfWheelPos);
- CVector rightSide, leftSide;
-
- // 3 persons can use the car as cover. Found the correct position for us.
- if (foundVeh->m_numPedsUseItAsCover == 2) {
- rightSide = CVector(1.5f, -0.5f, 0.0f);
- leftSide = CVector(-1.5f, -0.5f, 0.0f);
- } else if (foundVeh->m_numPedsUseItAsCover == 1) {
- rightSide = CVector(1.5f, 0.5f, 0.0f);
- leftSide = CVector(-1.5f, 0.5f, 0.0f);
- } else if (foundVeh->m_numPedsUseItAsCover == 0) {
- rightSide = CVector(1.5f, 0.0f, 0.0f);
- leftSide = CVector(-1.5f, 0.0f, 0.0f);
- }
-
- CMatrix vehMatrix(foundVeh->GetMatrix());
- CVector duckAtRightSide = Multiply3x3(vehMatrix, rightSide) + foundVeh->GetPosition();
-
- CVector duckAtLeftSide = Multiply3x3(vehMatrix, leftSide) + foundVeh->GetPosition();
-
- CVector distWithPedRightSide = m_pedInObjective->GetPosition() - duckAtRightSide;
- CVector distWithPedLeftSide = m_pedInObjective->GetPosition() - duckAtLeftSide;
-
- CVector duckPos;
- if (distWithPedRightSide.MagnitudeSqr() <= distWithPedLeftSide.MagnitudeSqr())
- duckPos = duckAtLeftSide;
- else
- duckPos = duckAtRightSide;
-
- 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) {
- m_carInObjective = foundVeh;
- 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 if (!duckingWithoutVeh) {
- bDuckAndCover = false;
- }
- }
-
- if (!justDucked && !bDuckAndCover)
- return false;
-
- if (!Seek()) {
- if (m_nMoveState == PEDMOVE_STILL) {
- bDuckAndCover = false;
- return false;
- } else
+ if (m_nPedState != PED_DRIVING && m_nPedState != PED_DRAG_FROM_CAR && !bIsDucking) {
+ if (m_animGroup != ASSOCGRP_SEXYWOMAN && m_animGroup != ASSOCGRP_WOMAN)
return true;
}
-
- bKindaStayInSamePlace = true;
- bDuckAndCover = false;
- m_vecSeekPos = CVector(0.0f, 0.0f, 0.0f);
- if (m_pSeekTarget && m_pSeekTarget->IsVehicle())
- ((CVehicle*)m_pSeekTarget)->m_numPedsUseItAsCover++;
-
- SetIdle();
- SetMoveState(PEDMOVE_STILL);
- SetMoveAnim();
- if (!m_pLookTarget || m_pLookTarget != m_pedInObjective) {
- m_pLookTarget = m_pedInObjective;
- m_pLookTarget->RegisterReference((CEntity **) &m_pLookTarget);
- }
-
- m_leaveCarTimer = CTimer::GetTimeInMilliseconds() + CGeneral::GetRandomNumberInRange(3000, 6000);
- bCrouchWhenShooting = true;
- SetDuck(CGeneral::GetRandomNumberInRange(2000, 5000), true);
return false;
}
// --MIAMI: Done
void
-CPed::EndFight(uint8 endType)
-{
- if (m_nPedState != PED_FIGHT)
- return;
-
- m_curFightMove = FIGHTMOVE_NULL;
- RestorePreviousState();
- CAnimBlendAssociation *animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_FIGHT_IDLE);
- if (!animAssoc)
- animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_CROUCHRELOAD);
-
- if (animAssoc)
- animAssoc->flags |= ASSOC_DELETEFADEDOUT;
-
- switch (endType) {
- case ENDFIGHT_NORMAL:
- CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_IDLE_STANCE, 8.0f);
- CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_FIGHT2_IDLE, 8.0f);
- break;
- case ENDFIGHT_WITH_A_STEP:
- CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_IDLE_STANCE, 1.0f);
- CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_WALK_START, 8.0f);
- break;
- case ENDFIGHT_FAST:
- CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_IDLE_STANCE, 8.0f);
- CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_FIGHT2_IDLE, 8.0f)->speed = 2.0f;
- break;
- default:
- break;
- }
- m_nWaitTimer = 0;
-}
-
-// --MIAMI: Done
-void
-CPed::EnterCar(void)
-{
- if (IsNotInWreckedVehicle() && m_fHealth > 0.0f) {
- CVehicle *veh = m_pMyVehicle;
-
- // Not used.
- // CVector posForDoor = GetPositionToOpenCarDoor(veh, m_vehEnterType);
-
- if (veh->CanPedOpenLocks(this)) {
- if (m_vehEnterType && m_pVehicleAnim) {
- veh->ProcessOpenDoor(m_vehEnterType, m_pVehicleAnim->animId, m_pVehicleAnim->currentTime);
- }
- }
- 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();
- }
-}
-
-// --MIAMI: Done
-uint8
-CPed::GetNearestTrainPedPosition(CVehicle *train, CVector &enterPos)
+CPed::SetLookFlag(float direction, bool keepTryingToLook, bool cancelPrevious)
{
- CVector enterStepOffset;
- CVehicleModelInfo *trainModel = (CVehicleModelInfo *)CModelInfo::GetModelInfo(train->GetModelIndex());
- CMatrix trainMat = CMatrix(train->GetMatrix());
- CVector leftEntryPos, rightEntryPos, midEntryPos;
- float distLeftEntry, distRightEntry, distMidEntry;
-
- // enterStepOffset = vecPedCarDoorAnimOffset;
- enterStepOffset = CVector(1.5f, 0.0f, 0.0f);
-
- if (train->pPassengers[TRAIN_POS_LEFT_ENTRY]) {
- distLeftEntry = 999.0f;
- } else {
- leftEntryPos = trainModel->m_positions[TRAIN_POS_LEFT_ENTRY] - enterStepOffset;
- leftEntryPos = Multiply3x3(trainMat, leftEntryPos);
- leftEntryPos += train->GetPosition();
- distLeftEntry = (leftEntryPos - GetPosition()).Magnitude();
- }
-
- if (train->pPassengers[TRAIN_POS_MID_ENTRY]) {
- distMidEntry = 999.0f;
- } else {
- midEntryPos = trainModel->m_positions[TRAIN_POS_MID_ENTRY] - enterStepOffset;
- midEntryPos = Multiply3x3(trainMat, midEntryPos);
- midEntryPos += train->GetPosition();
- distMidEntry = (midEntryPos - GetPosition()).Magnitude();
- }
-
- if (train->pPassengers[TRAIN_POS_RIGHT_ENTRY]) {
- distRightEntry = 999.0f;
- } else {
- rightEntryPos = trainModel->m_positions[TRAIN_POS_RIGHT_ENTRY] - enterStepOffset;
- rightEntryPos = Multiply3x3(trainMat, rightEntryPos);
- rightEntryPos += train->GetPosition();
- distRightEntry = (rightEntryPos - GetPosition()).Magnitude();
- }
-
- if (distMidEntry < distLeftEntry) {
- if (distMidEntry < distRightEntry) {
- enterPos = midEntryPos;
- m_vehEnterType = TRAIN_POS_MID_ENTRY;
- } else {
- enterPos = rightEntryPos;
- m_vehEnterType = TRAIN_POS_RIGHT_ENTRY;
+ if (m_lookTimer < CTimer::GetTimeInMilliseconds() || cancelPrevious) {
+ bIsLooking = true;
+ bIsRestoringLook = false;
+ m_fLookDirection = direction;
+ m_pLookTarget = nil;
+ m_lookTimer = 0;
+ bKeepTryingToLook = keepTryingToLook;
+ if (CanUseTorsoWhenLooking()) {
+ m_pedIK.m_flags &= ~CPedIK::LOOKAROUND_HEAD_ONLY;
}
- } else if (distRightEntry < distLeftEntry) {
- enterPos = rightEntryPos;
- m_vehEnterType = TRAIN_POS_RIGHT_ENTRY;
- } else {
- enterPos = leftEntryPos;
- m_vehEnterType = TRAIN_POS_LEFT_ENTRY;
}
-
- return 1;
}
// --MIAMI: Done
-uint8
-CPed::GetNearestTrainDoor(CVehicle *train, CVector &doorPos)
-{
- GetNearestTrainPedPosition(train, doorPos);
-/*
- // Not used.
- CVehicleModelInfo* trainModel = (CVehicleModelInfo*)CModelInfo::GetModelInfo(train->m_modelIndex);
- CMatrix trainMat = CMatrix(train->GetMatrix());
-
- doorPos = trainModel->m_positions[m_vehEnterType];
- doorPos.x -= 1.5f;
- doorPos = Multiply3x3(trainMat, doorPos);
- doorPos += train->GetPosition();
-*/
- return 1;
-}
-
-#ifdef GTA_TRAIN
void
-CPed::LineUpPedWithTrain(void)
+CPed::SetLookFlag(CEntity *target, bool keepTryingToLook, bool cancelPrevious)
{
- CVector lineUpPos;
- CVehicleModelInfo *trainModel = (CVehicleModelInfo *)CModelInfo::GetModelInfo(m_pMyVehicle->GetModelIndex());
- CVector enterOffset(1.5f, 0.0f, -0.2f);
-
- m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f);
- m_fRotationCur = m_pMyVehicle->GetForward().Heading() - HALFPI;
- m_fRotationDest = m_fRotationCur;
-
- if (!bInVehicle) {
- GetNearestTrainDoor(m_pMyVehicle, lineUpPos);
- lineUpPos.z += 0.2f;
- } else {
- if (m_pMyVehicle->pPassengers[TRAIN_POS_LEFT_ENTRY] == this) {
-
- lineUpPos = trainModel->m_positions[TRAIN_POS_LEFT_ENTRY] - enterOffset;
-
- } else if (m_pMyVehicle->pPassengers[TRAIN_POS_MID_ENTRY] == this) {
-
- lineUpPos = trainModel->m_positions[TRAIN_POS_MID_ENTRY] - enterOffset;
-
- } else if (m_pMyVehicle->pPassengers[TRAIN_POS_RIGHT_ENTRY] == this) {
-
- lineUpPos = trainModel->m_positions[TRAIN_POS_RIGHT_ENTRY] - enterOffset;
+ if (m_lookTimer < CTimer::GetTimeInMilliseconds() || cancelPrevious) {
+ bIsLooking = true;
+ bIsRestoringLook = false;
+ m_pLookTarget = target;
+ m_pLookTarget->RegisterReference((CEntity**)&m_pLookTarget);
+ m_fLookDirection = 999999.0f;
+ m_lookTimer = 0;
+ bKeepTryingToLook = keepTryingToLook;
+ if (CanUseTorsoWhenLooking()) {
+ m_pedIK.m_flags &= ~CPedIK::LOOKAROUND_HEAD_ONLY;
}
- lineUpPos = Multiply3x3(m_pMyVehicle->GetMatrix(), lineUpPos);
- lineUpPos += m_pMyVehicle->GetPosition();
- }
-
- if (m_pVehicleAnim) {
- float percentageLeft = m_pVehicleAnim->GetTimeLeft() / m_pVehicleAnim->hierarchy->totalLength;
- lineUpPos += (GetPosition() - lineUpPos) * percentageLeft;
}
-
- SetPosition(lineUpPos);
- SetHeading(m_fRotationCur);
-}
-
-void
-CPed::EnterTrain(void)
-{
- LineUpPedWithTrain();
-}
-
-void
-CPed::ExitTrain(void)
-{
- LineUpPedWithTrain();
}
-#endif
// --MIAMI: Done
void
-CPed::ExitCar(void)
-{
- 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;
- }
+CPed::ClearLookFlag(void) {
+ if (bIsLooking) {
+ bIsLooking = false;
+ bIsRestoringLook = true;
+ bShakeFist = false;
- AnimationId exitAnim = (AnimationId) m_pVehicleAnim->animId;
- float animTime = m_pVehicleAnim->currentTime;
+ if (CanUseTorsoWhenLooking())
+ m_pedIK.m_flags &= ~CPedIK::LOOKAROUND_HEAD_ONLY;
- if (exitAnim == ANIM_BIKE_GETOFF_BACK) {
- if (animTime > 0.35f && m_pMyVehicle && m_pMyVehicle->IsBike())
- ((CBike*)m_pMyVehicle)->KnockOffRider(WEAPONTYPE_UNARMED, 0, this, false);
+ if (IsPlayer())
+ m_lookTimer = CTimer::GetTimeInMilliseconds() + 2000;
else
- LineUpPedWithCar(LINE_UP_TO_CAR_FALL);
-
- } 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_FALL);
- }
- } else {
- m_pMyVehicle->ProcessOpenDoor(m_vehEnterType, exitAnim, animTime);
-
- 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);
- }
- }
+ m_lookTimer = CTimer::GetTimeInMilliseconds() + 4000;
- // 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 (m_nPedState == PED_LOOK_HEADING || m_nPedState == PED_LOOK_ENTITY) {
+ ClearLook();
}
}
}
// --MIAMI: Done
void
-CPed::Fall(void)
+CPed::MoveHeadToLook(void)
{
- if (m_getUpTimer != UINT32_MAX && CTimer::GetTimeInMilliseconds() > m_getUpTimer && bIsStanding)
- ClearFall();
-
- 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);
+ CVector lookPos;
- if (!fallAssoc)
- fallAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_FALL_FRONT);
+ if (m_lookTimer && CTimer::GetTimeInMilliseconds() > m_lookTimer) {
+ ClearLookFlag();
+ }
- if (fallAssoc) {
- bKnockedUpIntoAir = false;
- bKnockedOffBike = false;
- fallAssoc->speed = 3.0f;
- if (IsPlayer())
- Say(SOUND_PED_LAND);
+ 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 {
- firstPartialAssoc = RpAnimBlendClumpGetFirstAssociation(GetClump(), ASSOC_PARTIAL);
- if (firstPartialAssoc && !firstPartialAssoc->IsRunning()) {
- bKnockedUpIntoAir = false;
- bKnockedOffBike = false;
- }
- }
- }
-}
-
-// --MIAMI: Done
-void
-CPed::Fight(void)
-{
- CAnimBlendAssociation *currentAssoc, *animAssoc;
- 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:
- return;
- case FIGHTMOVE_IDLE2NORM:
- m_curFightMove = FIGHTMOVE_NULL;
- RestorePreviousState();
-
- // FIX: Uninitialized
- currentAssoc = nil;
- break;
- case FIGHTMOVE_IDLE:
- currentAssoc = nil;
- break;
- default:
- currentAssoc = RpAnimBlendClumpGetAssociation(GetClump(), tFightMoves[m_curFightMove].animId);
- 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) {
-
- // TODO(Miami): AddWeaponStreak
- // CSpecialFX::AddWeaponStreak(v2->m_weapons[(char)v2->m_currentWeapon].nWeaponId);
- }
- }
- }
-
- if (!bIsAttacking && IsPlayer()) {
- if (currentAssoc) {
- currentAssoc->blendDelta = -1000.0f;
- currentAssoc->flags |= ASSOC_DELETEFADEDOUT;
- currentAssoc->flags &= ~ASSOC_RUNNING;
+ lookPos = m_pLookTarget->GetPosition();
}
- if (m_takeAStepAfterAttack)
- EndFight(ENDFIGHT_WITH_A_STEP);
- else
- EndFight(ENDFIGHT_FAST);
-
- } else if (currentAssoc && m_fightState > FIGHTSTATE_MOVE_FINISHED) {
- float animTime = currentAssoc->currentTime;
- 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_KNEE:
- TransformToNode(touchingNodePos, PED_LOWERLEGR);
- break;
- case FIGHTMOVE_PUNCHHOOK:
- case FIGHTMOVE_PUNCHJAB:
- TransformToNode(touchingNodePos, PED_HANDL);
- break;
- 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_pedIK.LookAtPosition(lookPos)) {
+ if (!bKeepTryingToLook) {
+ ClearLookFlag();
}
-
- FightStrike(touchingNodePos, fightWithWeapon);
- m_fightButtonPressure = 0;
return;
}
- if (curMove.hitLevel != HITLEVEL_NULL) {
- if (animTime > curMove.endFireTime && weaponInfo->m_AnimToPlay != ASSOCGRP_KNIFE) {
- if (IsPlayer())
- currentAssoc->speed = 1.0f;
- else
- currentAssoc->speed = 0.8f;
- }
-
- 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 (GetWeapon()->m_eWeaponType != WEAPONTYPE_UNARMED && GetWeapon()->m_eWeaponType != WEAPONTYPE_BRASSKNUCKLE && !fightWithWeapon) {
- EndFight(ENDFIGHT_FAST);
-
- } else if (m_fightButtonPressure != 0) {
- if (!IsPlayer())
- Say(SOUND_PED_ATTACK);
-
- if (m_curFightMove != FIGHTMOVE_IDLE)
- m_lastFightMove = m_curFightMove;
+ if (!bShakeFist || bIsAimingGun || bIsRestoringGun)
+ return;
- m_curFightMove = IsPlayer() ? ChooseAttackPlayer(m_fightButtonPressure, fightWithWeapon) : ChooseAttackAI(m_fightButtonPressure, fightWithWeapon);
+ if (m_nPedState == PED_ANSWER_MOBILE)
+ return;
- if (m_curFightMove != FIGHTMOVE_IDLE) {
+ if (m_lookTimer - CTimer::GetTimeInMilliseconds() >= 1000)
+ return;
- animAssoc = CAnimManager::BlendAnimation(GetClump(), m_curFightMove < FIGHTMOVE_MELEE1 ? ASSOCGRP_STD : weaponInfo->m_AnimToPlay,
- tFightMoves[m_curFightMove].animId, 8.0f);
+ bool handFreeToMove = false;
+ AnimationId animToPlay = NUM_STD_ANIMS;
- if (weaponInfo->m_AnimToPlay != ASSOCGRP_KNIFE || m_curFightMove < FIGHTMOVE_MELEE1) {
- if (m_curFightMove == FIGHTMOVE_BACKKICK)
- animAssoc->speed = 1.15f;
- else
- animAssoc->speed = 0.8f;
- } else {
- 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 (!GetWeapon()->IsType2Handed() && GetWeapon()->m_eWeaponType != WEAPONTYPE_ROCKETLAUNCHER)
+ handFreeToMove = true;
- if (m_fightState == FIGHTSTATE_MOVE_FINISHED && animAssoc->currentTime != 0.0f) {
- animAssoc->SetRun();
- if (!IsPlayer())
- animAssoc->SetCurrentTime(0.0f);
- }
- if (IsPlayer())
- animAssoc->SetCurrentTime(0.08f);
+ if (IsPlayer() && handFreeToMove) {
- animAssoc->SetFinishCallback(FinishFightMoveCB, this);
- m_fightButtonPressure = 0;
- }
- m_fightState = FIGHTSTATE_NO_MOVE;
- } else if (m_takeAStepAfterAttack && m_curFightMove != FIGHTMOVE_SHUFFLE_F
-#ifndef FIX_BUGS
- && CheckForPedsOnGroundToAttack(this, nil) == 4) {
+ if (m_pLookTarget->IsPed()) {
+#ifdef FIX_BUGS
+ if (m_pedStats->m_temper > 49 || ((CPed*)m_pLookTarget)->m_nPedType == PEDTYPE_COP)
#else
- && CheckForPedsOnGroundToAttack(this, nil) == PED_IN_FRONT_OF_ATTACKER) {
+ if (m_pedStats->m_temper < 49 || ((CPed*)m_pLookTarget)->m_nPedType == PEDTYPE_COP)
#endif
- m_lastFightMove = m_curFightMove;
- m_curFightMove = FIGHTMOVE_SHUFFLE_F;
- animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), tFightMoves[m_curFightMove].animId);
-
- if (animAssoc) {
- animAssoc->SetCurrentTime(0.0f);
- animAssoc->blendDelta = 4.0f;
- animAssoc->SetRun();
- } else {
- animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, tFightMoves[m_curFightMove].animId, 32.0f);
- }
- animAssoc->SetFinishCallback(FinishFightMoveCB, this);
- m_fightState = FIGHTSTATE_NO_MOVE;
- m_fightButtonPressure = 0;
- m_takeAStepAfterAttack = false;
-
- } else if (m_takeAStepAfterAttack) {
- EndFight(ENDFIGHT_FAST);
-
- } else if (m_curFightMove == FIGHTMOVE_IDLE) {
- if (CTimer::GetTimeInMilliseconds() > m_nWaitTimer) {
- EndFight(ENDFIGHT_NORMAL);
+ 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 (handFreeToMove && (CGeneral::GetRandomNumber() & 1)) {
+ animToPlay = ANIM_FUCKU;
}
- } else {
- m_lastFightMove = m_curFightMove;
- m_curFightMove = FIGHTMOVE_IDLE;
- if (IsPlayer())
- m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 500;
- else
- m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 2000;
- }
-}
-
-// --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)
-{
- for (int i = 0; i < node->numLinks; i++) {
-
- CPathNode *testNode = &ThePaths.m_pathNodes[ThePaths.ConnectedNode(i + node->firstLink)];
-
- if (testNode && testNode != closeNode && testNode != closeNode2) {
- CVector2D posDiff(ped->m_vecSeekPos - testNode->GetPosition());
- float dist = posDiff.MagnitudeSqr();
-
- if (farDist.MagnitudeSqr() > dist) {
+ if (animToPlay != NUM_STD_ANIMS) {
+ CAnimBlendAssociation *newAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, animToPlay, 4.0f);
- if (closeDist.MagnitudeSqr() <= dist) {
- ped->m_pNextPathNode = closeNode;
- closeDist = posDiff;
- } else {
- ped->m_pNextPathNode = (closeNode2 ? closeNode2 : testNode);
- farDist = posDiff;
- }
+ if (newAssoc) {
+ newAssoc->flags |= ASSOC_FADEOUTWHENDONE;
+ newAssoc->flags |= ASSOC_DELETEFADEDOUT;
}
-
- if (--runCount > 0)
- SelectClosestNodeForSeek(ped, testNode, closeDist, farDist, closeNode, (closeNode2 ? closeNode2 : testNode), runCount);
}
+ bShakeFist = false;
+ } else if (m_fLookDirection == 999999.0f) {
+ ClearLookFlag();
+ } else if (!m_pedIK.LookInDirection(m_fLookDirection, 0.0f)) {
+ if (!bKeepTryingToLook)
+ ClearLookFlag();
}
}
// --MIAMI: Done
-bool
-CPed::FindBestCoordsFromNodes(CVector unused, CVector *bestCoords)
+void
+CPed::RestoreHeadPosition(void)
{
- if (m_pNextPathNode || !bUsePedNodeSeek)
- return false;
-
- CVector ourPos = GetPosition();
-
- int closestNodeId = ThePaths.FindNodeClosestToCoors(GetPosition(), 1, 999999.9f, false, false);
-
- CVector seekObjPos = m_vecSeekPos;
- seekObjPos.z += 1.0f;
-
- if (CWorld::GetIsLineOfSightClear(ourPos, seekObjPos, true, false, false, true, false, false, false))
- return false;
-
- m_pNextPathNode = nil;
-
- CVector2D seekPosDist (m_vecSeekPos - ourPos);
-
- CPathNode *closestNode = &ThePaths.m_pathNodes[closestNodeId];
- CVector2D closeDist(m_vecSeekPos - closestNode->GetPosition());
-
- SelectClosestNodeForSeek(this, closestNode, closeDist, seekPosDist, closestNode, nil);
-
- if (m_pNextPathNode) {
-
- // 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(!CanUseTorsoWhenLooking())
+ m_pedIK.m_flags |= CPedIK::LOOKAROUND_HEAD_ONLY;
- if ((correctedCoords - ourPos).MagnitudeSqr2D() < seekPosDist.MagnitudeSqr()) {
- correctedCoords = CPathFind::TakeWidthIntoAccountForWandering(m_pNextPathNode, m_randomSeed);
- *bestCoords = correctedCoords;
- return true;
- }
- m_pNextPathNode = nil;
+ if (m_pedIK.RestoreLookAt()) {
+ bIsRestoringLook = false;
+ if(CanUseTorsoWhenLooking())
+ m_pedIK.m_flags &= ~CPedIK::LOOKAROUND_HEAD_ONLY;
}
-
- return false;
}
// --MIAMI: Done
void
-CPed::FinishDieAnimCB(CAnimBlendAssociation *animAssoc, void *arg)
+CPed::SetAimFlag(float angle)
{
- CPed *ped = (CPed*)arg;
-
- if (ped->bIsPedDieAnimPlaying)
- ped->bIsPedDieAnimPlaying = false;
-}
+ bIsAimingGun = true;
+ bIsRestoringGun = false;
+ m_fLookDirection = angle;
+ m_lookTimer = 0;
+ m_pLookTarget = nil;
+ m_pSeekTarget = nil;
-// --MIAMI: Done
-void
-CPed::FinishFightMoveCB(CAnimBlendAssociation *animAssoc, void *arg)
-{
- CPed *ped = (CPed*)arg;
+ if (bIsDucking)
+ m_pedIK.m_flags &= ~CPedIK::AIMS_WITH_ARM;
- if (tFightMoves[ped->m_curFightMove].animId == animAssoc->animId) {
- ped->m_fightState = FIGHTSTATE_MOVE_FINISHED;
- animAssoc->blendDelta = -1000.0f;
- }
+ if (CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->IsFlagSet(WEAPONFLAG_CANAIM_WITHARM))
+ m_pedIK.m_flags |= CPedIK::AIMS_WITH_ARM;
+ else
+ m_pedIK.m_flags &= ~CPedIK::AIMS_WITH_ARM;
}
// --MIAMI: Done
void
-CPed::FinishHitHeadCB(CAnimBlendAssociation *animAssoc, void *arg)
+CPed::SetAimFlag(CEntity *to)
{
- CPed *ped = (CPed*)arg;
-
- if (animAssoc) {
- animAssoc->blendDelta = -4.0f;
- animAssoc->flags |= ASSOC_DELETEFADEDOUT;
- }
-
- if (ped->m_nPedState == PED_JUMP)
- ped->RestorePreviousState();
-
- ped->bIsLanding = false;
+ 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::FinishJumpCB(CAnimBlendAssociation *animAssoc, void *arg)
+CPed::ClearAimFlag(void)
{
- CPed *ped = (CPed*)arg;
-
- ped->bResetWalkAnims = true;
- ped->bIsLanding = false;
+ if (bIsAimingGun) {
+ bIsAimingGun = false;
+ bIsRestoringGun = true;
+ m_pedIK.m_flags &= ~CPedIK::AIMS_WITH_ARM;
+ m_lookTimer = 0;
+ }
- animAssoc->blendDelta = -1000.0f;
+ if (IsPlayer())
+ ((CPlayerPed*)this)->m_fFPSMoveHeading = 0.0f;
}
// --MIAMI: Done
void
-CPed::FinishLaunchCB(CAnimBlendAssociation *animAssoc, void *arg)
+CPed::AimGun(void)
{
- CPed *ped = (CPed*)arg;
-
- if (ped->m_nPedState != PED_JUMP)
- return;
-
- CVector forward(0.09f * ped->GetForward() + ped->GetPosition());
- forward.z += CModelInfo::GetModelInfo(ped->GetModelIndex())->GetColModel()->spheres->center.z + 0.35f;
-
- CEntity *obstacle = CWorld::TestSphereAgainstWorld(forward, 0.25f, nil, true, true, false, true, false, false);
- if (!obstacle) {
- // Forward of forward
- forward += 0.15f * ped->GetForward();
- forward.z += 0.15f;
- 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;
- CAnimBlendAssociation *handsCoverAssoc = CAnimManager::BlendAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_HIT_WALL, 8.0f);
- handsCoverAssoc->flags &= ~ASSOC_FADEOUTWHENDONE;
- handsCoverAssoc->SetFinishCallback(FinishHitHeadCB, ped);
- ped->bIsLanding = true;
- return;
- }
-
- float velocityFromAnim = 0.1f;
- CAnimBlendAssociation *sprintAssoc = RpAnimBlendClumpGetAssociation(ped->GetClump(), ANIM_SPRINT);
-
- if (sprintAssoc) {
- velocityFromAnim = 0.05f * sprintAssoc->blendAmount + 0.17f;
- } else {
- CAnimBlendAssociation *runAssoc = RpAnimBlendClumpGetAssociation(ped->GetClump(), ANIM_RUN);
- if (runAssoc) {
- velocityFromAnim = 0.07f * runAssoc->blendAmount + 0.1f;
- }
- }
+ CVector vector;
- 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() || ped->m_pCurrentPhysSurface) {
+ if (IsPlayer() && bIsDucking)
+ m_pedIK.m_flags &= ~CPedIK::AIMS_WITH_ARM;
-#ifdef FREE_CAM
- if (TheCamera.Cams[0].Using3rdPersonMouseCam() && !CCamera::bFreeCam) {
-#else
- if (TheCamera.Cams[0].Using3rdPersonMouseCam()) {
-#endif
- float fpsAngle = ped->WorkOutHeadingForMovingFirstPerson(ped->m_fRotationCur);
- ped->m_vecMoveSpeed.x = -velocityFromAnim * Sin(fpsAngle);
- ped->m_vecMoveSpeed.y = velocityFromAnim * Cos(fpsAngle);
+ if (m_pSeekTarget) {
+ if (m_pSeekTarget->IsPed()) {
+ ((CPed*)m_pSeekTarget)->m_pedIK.GetComponentPosition(vector, PED_MID);
} else {
- ped->m_vecMoveSpeed.x = -velocityFromAnim * Sin(ped->m_fRotationCur);
- ped->m_vecMoveSpeed.y = velocityFromAnim * Cos(ped->m_fRotationCur);
- }
-
- if (ped->m_pCurrentPhysSurface) {
- ped->m_vecMoveSpeed.x += ped->m_pCurrentPhysSurface->m_vecMoveSpeed.x;
- ped->m_vecMoveSpeed.y += ped->m_pCurrentPhysSurface->m_vecMoveSpeed.y;
+ vector = m_pSeekTarget->GetPosition();
}
- }
-
- ped->bIsStanding = false;
- ped->bIsInTheAir = true;
- animAssoc->blendDelta = -1000.0f;
- CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_JUMP_GLIDE);
-
- if (ped->bDoBloodyFootprints) {
- CVector bloodPos(0.0f, 0.0f, 0.0f);
- ped->TransformToNode(bloodPos, PED_FOOTL);
-
- bloodPos.z -= 0.1f;
- bloodPos += 0.2f * ped->GetForward();
-
- CShadows::AddPermanentShadow(SHADOWTYPE_DARK, gpBloodPoolTex, &bloodPos,
- 0.26f * ped->GetForward().x,
- 0.26f * ped->GetForward().y,
- 0.14f * ped->GetRight().x,
- 0.14f * ped->GetRight().y,
- 255, 255, 0, 0, 4.0f, 3000, 1.0f);
- bloodPos = CVector(0.0f, 0.0f, 0.0f);
- ped->TransformToNode(bloodPos, PED_FOOTR);
+ if (!IsPlayer())
+ Say(SOUND_PED_ATTACK);
- bloodPos.z -= 0.1f;
- bloodPos += 0.2f * ped->GetForward();
- CShadows::AddPermanentShadow(SHADOWTYPE_DARK, gpBloodPoolTex, &bloodPos,
- 0.26f * ped->GetForward().x,
- 0.26f * ped->GetForward().y,
- 0.14f * ped->GetRight().x,
- 0.14f * ped->GetRight().y,
- 255, 255, 0, 0, 4.0f, 3000, 1.0f);
+ bCanPointGunAtTarget = m_pedIK.PointGunAtPosition(vector);
+ if (m_pLookTarget != m_pSeekTarget) {
+ SetLookFlag(m_pSeekTarget, true, true);
+ }
- if (ped->m_bloodyFootprintCountOrDeathTime <= 40) {
- ped->m_bloodyFootprintCountOrDeathTime = 0;
- ped->bDoBloodyFootprints = false;
+ } else {
+ if (IsPlayer()) {
+ bCanPointGunAtTarget = m_pedIK.PointGunInDirection(m_fLookDirection, ((CPlayerPed*)this)->m_fFPSMoveHeading);
} else {
- ped->m_bloodyFootprintCountOrDeathTime -= 40;
+ bCanPointGunAtTarget = m_pedIK.PointGunInDirection(m_fLookDirection, 0.0f);
}
}
}
// --MIAMI: Done
void
-CPed::FinishedWaitCB(CAnimBlendAssociation *animAssoc, void *arg)
+CPed::RestoreGunPosition(void)
{
- CPed *ped = (CPed*)arg;
+ if (bIsLooking) {
+ m_pedIK.m_flags &= ~CPedIK::LOOKAROUND_HEAD_ONLY;
+ bIsRestoringGun = false;
+ } else if (m_pedIK.RestoreGunPosn()) {
+ bIsRestoringGun = false;
+ } else {
+ if (IsPlayer())
+ ((CPlayerPed*)this)->m_fFPSMoveHeading = 0.0f;
+ }
+}
- ped->m_nWaitTimer = 0;
- ped->RestoreHeadingRate();
- ped->Wait();
+// --MIAMI: Done
+bool
+CPed::CanWeRunAndFireWithWeapon(void)
+{
+ return CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->IsFlagSet(WEAPONFLAG_CANAIM_WITHARM);
}
// --MIAMI: Done
void
-CPed::Wait(void)
+CPed::ScanForInterestingStuff(void)
{
- AnimationId mustHaveAnim = NUM_STD_ANIMS;
- CAnimBlendAssociation *animAssoc;
- CPed *pedWeLook;
-
- if (DyingOrDead()) {
- ClearWaitState();
- RestoreHeadingRate();
+ if (!IsPedInControl())
return;
- }
-
- switch (m_nWaitState) {
-
- case WAITSTATE_TRAFFIC_LIGHTS:
- if (CTimer::GetTimeInMilliseconds() > m_nWaitTimer) {
- if (CTrafficLights::LightForPeds() == PED_LIGHTS_WALK) {
- ClearWaitState();
- SetMoveState(PEDMOVE_WALK);
- }
- }
- break;
- case WAITSTATE_CROSS_ROAD:
- if (CTimer::GetTimeInMilliseconds() > m_nWaitTimer) {
- if (CGeneral::GetRandomNumber() & 1 || !m_nWaitTimer)
- ClearWaitState();
- else
- SetWaitState(WAITSTATE_CROSS_ROAD_LOOK, nil);
-
- animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_HBHB);
- if (animAssoc) {
- animAssoc->blendDelta = -8.0f;
- animAssoc->flags |= ASSOC_DELETEFADEDOUT;
- }
- }
- break;
+ if (m_objective != OBJECTIVE_NONE)
+ return;
- case WAITSTATE_CROSS_ROAD_LOOK:
- if (CTimer::GetTimeInMilliseconds() > m_nWaitTimer) {
- ClearWaitState();
- animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_ROAD_CROSS);
- if (animAssoc) {
- animAssoc->blendDelta = -8.0f;
- animAssoc->flags |= ASSOC_DELETEFADEDOUT;
- }
- }
- break;
+ if (CharCreatedBy == MISSION_CHAR)
+ return;
- case WAITSTATE_DOUBLEBACK:
- if (CTimer::GetTimeInMilliseconds() <= m_nWaitTimer) {
- uint32 timeLeft = m_nWaitTimer - CTimer::GetTimeInMilliseconds();
- if (timeLeft < 2500 && timeLeft > 2000) {
- m_nWaitTimer -= 500;
- CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_XPRESS_SCRATCH, 4.0f);
- }
- } else {
- ClearWaitState();
- SetMoveState(PEDMOVE_WALK);
- }
- break;
+ LookForSexyPeds();
+ LookForSexyCars();
+ if (LookForInterestingNodes())
+ return;
- case WAITSTATE_HITWALL:
- if (CTimer::GetTimeInMilliseconds() <= m_nWaitTimer) {
- if (m_collidingThingTimer > CTimer::GetTimeInMilliseconds()) {
- m_collidingThingTimer = CTimer::GetTimeInMilliseconds() + 2500;
- }
- } else {
- ClearWaitState();
- }
- break;
+ if (m_nPedType == PEDTYPE_CRIMINAL && m_hitRecoverTimer < CTimer::GetTimeInMilliseconds()) {
+ if (CGeneral::GetRandomNumber() % 100 < 10) {
+ int mostExpensiveVehAround = -1;
+ int bestMonetaryValue = 0;
- case WAITSTATE_TURN180:
- if (CTimer::GetTimeInMilliseconds() > m_nWaitTimer) {
- ClearWaitState();
- m_fRotationCur = m_fRotationCur + PI;
- if (m_nPedState == PED_INVESTIGATE)
- ClearInvestigateEvent();
- }
+ CVector pos = GetPosition();
+ int16 lastVehicle;
+ CEntity *vehicles[8];
+ CWorld::FindObjectsInRange(pos, 10.0f, true, &lastVehicle, 6, vehicles, false, true, false, false, false);
- if (m_collidingThingTimer > CTimer::GetTimeInMilliseconds()) {
- m_collidingThingTimer = CTimer::GetTimeInMilliseconds() + 2500;
- }
- break;
+ for (int i = 0; i < lastVehicle; i++) {
+ CVehicle* veh = (CVehicle*)vehicles[i];
- case WAITSTATE_SURPRISE:
- if (CTimer::GetTimeInMilliseconds() > m_nWaitTimer) {
- if (RpAnimBlendClumpGetAssociation(GetClump(), ANIM_HIT_WALL)) {
- animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_XPRESS_SCRATCH, 4.0f);
- animAssoc->SetFinishCallback(FinishedWaitCB, this);
- m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 5000;
- } else {
- ClearWaitState();
+ if (veh->VehicleCreatedBy != MISSION_VEHICLE) {
+ if (veh->m_vecMoveSpeed.Magnitude() <= 0.1f && veh->IsVehicleNormal()
+ && veh->IsCar() && bestMonetaryValue < veh->pHandling->nMonetaryValue) {
+ mostExpensiveVehAround = i;
+ bestMonetaryValue = veh->pHandling->nMonetaryValue;
+ }
}
}
- break;
-
- case WAITSTATE_STUCK:
- if (CTimer::GetTimeInMilliseconds() <= m_nWaitTimer)
- break;
-
- animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_TIRED);
-
- if (!animAssoc)
- animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_TURN_180);
- if (!animAssoc)
- animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_XPRESS_SCRATCH);
- if (!animAssoc)
- animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_ROAD_CROSS);
-
- if (animAssoc) {
- if (animAssoc->IsPartial()) {
- animAssoc->blendDelta = -8.0f;
- animAssoc->flags |= ASSOC_DELETEFADEDOUT;
- } else {
- animAssoc->flags |= ASSOC_DELETEFADEDOUT;
- CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_IDLE_STANCE, 4.0f);
- }
-
- if (animAssoc->animId == ANIM_TURN_180) {
- m_fRotationCur = CGeneral::LimitRadianAngle(PI + m_fRotationCur);
- ClearWaitState();
- SetMoveState(PEDMOVE_WALK);
- m_nStoredMoveState = PEDMOVE_NONE;
- m_panicCounter = 0;
- return;
- }
+ if (bestMonetaryValue > 2000 && mostExpensiveVehAround != -1 && vehicles[mostExpensiveVehAround]) {
+ SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, vehicles[mostExpensiveVehAround]);
+ m_hitRecoverTimer = CTimer::GetTimeInMilliseconds() + 5000;
+ return;
}
+ m_hitRecoverTimer = CTimer::GetTimeInMilliseconds() + 5000;
+ } else if (m_objective != OBJECTIVE_MUG_CHAR && !(CGeneral::GetRandomNumber() & 7)) {
+ CPed *charToMug = nil;
+ for (int i = 0; i < m_numNearPeds; ++i) {
+ CPed *nearPed = m_nearPeds[i];
- AnimationId animToPlay;
-
- switch (CGeneral::GetRandomNumber() & 3) {
- case 0:
- animToPlay = ANIM_ROAD_CROSS;
- break;
- case 1:
- animToPlay = ANIM_IDLE_TIRED;
- break;
- case 2:
- animToPlay = ANIM_XPRESS_SCRATCH;
- break;
- case 3:
- animToPlay = ANIM_TURN_180;
- break;
- default:
+ if ((nearPed->GetPosition() - GetPosition()).MagnitudeSqr() > sq(7.0f))
break;
- }
-
- animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, animToPlay, 4.0f);
-
- if (animToPlay == ANIM_TURN_180)
- animAssoc->SetFinishCallback(FinishedWaitCB, this);
-
- m_nWaitTimer = CTimer::GetTimeInMilliseconds() + CGeneral::GetRandomNumberInRange(1500, 5000);
- break;
-
- case WAITSTATE_LOOK_ABOUT:
- if (CTimer::GetTimeInMilliseconds() > m_nWaitTimer) {
- ClearWaitState();
- animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_HBHB);
- if (animAssoc) {
- animAssoc->blendDelta = -8.0f;
- animAssoc->flags |= ASSOC_DELETEFADEDOUT;
- }
- }
- break;
-
- case WAITSTATE_PLAYANIM_HANDSUP:
- mustHaveAnim = ANIM_HANDSUP;
-
- case WAITSTATE_PLAYANIM_HANDSCOWER:
- if (mustHaveAnim == NUM_STD_ANIMS)
- mustHaveAnim = ANIM_HANDSCOWER;
-
- animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), mustHaveAnim);
- pedWeLook = (CPed*) m_pLookTarget;
-
- if ((!m_pLookTarget || !m_pLookTarget->IsPed() || pedWeLook->m_pPointGunAt)
- && m_nPedState != PED_FLEE_ENTITY
- && m_nPedState != PED_ATTACK
- && CTimer::GetTimeInMilliseconds() <= m_nWaitTimer
- && animAssoc) {
-
- if (pedWeLook)
- TurnBody();
- } else {
- 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);
- }
- } else if (m_pedStats->m_fear <= 100 - pedWeLook->m_pedStats->m_temper) {
- if (GetWeapon()->IsTypeMelee()) {
- if(m_pedStats->m_flags & STAT_GUN_PANIC) {
- 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);
-
- if (m_nPedType != PEDTYPE_COP) {
- ProcessObjective();
- SetMoveState(PEDMOVE_WALK);
- }
- } else {
- SetObjective(OBJECTIVE_NONE);
- SetWanderPath(CGeneral::GetRandomNumberInRange(0.0f, 8.0f));
- }
- } else {
- SetObjective(OBJECTIVE_KILL_CHAR_ON_FOOT, m_pLookTarget);
- SetObjectiveTimer(20000);
- }
- } else {
- 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;
- }
- SetMoveState(PEDMOVE_RUN);
- Say(SOUND_PED_FLEE_RUN);
- }
- }
- }
- animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), mustHaveAnim);
- if (animAssoc) {
- animAssoc->blendDelta = -4.0f;
- animAssoc->flags |= ASSOC_DELETEFADEDOUT;
- }
- }
- break;
- case WAITSTATE_PLAYANIM_COWER:
- mustHaveAnim = ANIM_HANDSCOWER;
-
- case WAITSTATE_PLAYANIM_DUCK:
- if (mustHaveAnim == NUM_STD_ANIMS)
- mustHaveAnim = ANIM_DUCK_DOWN;
-
- case WAITSTATE_PLAYANIM_TAXI:
- if (mustHaveAnim == NUM_STD_ANIMS)
- mustHaveAnim = ANIM_IDLE_TAXI;
-
- case WAITSTATE_PLAYANIM_CHAT:
- if (mustHaveAnim == NUM_STD_ANIMS)
- mustHaveAnim = ANIM_IDLE_CHAT;
-
- if (CTimer::GetTimeInMilliseconds() > m_nWaitTimer) {
- animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), mustHaveAnim);
- if (animAssoc) {
- animAssoc->blendDelta = -4.0f;
- animAssoc->flags |= ASSOC_DELETEFADEDOUT;
- }
- 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) {
-
- if (m_pLookTarget)
- m_pLookTarget->CleanUpOldReference(&m_pLookTarget);
- m_pLookTarget = m_pedInObjective;
- m_pLookTarget->RegisterReference((CEntity **) &m_pLookTarget);
- TurnBody();
- }
+ if ((nearPed->m_nPedType == PEDTYPE_CIVFEMALE || nearPed->m_nPedType == PEDTYPE_CIVMALE
+ || nearPed->m_nPedType == PEDTYPE_CRIMINAL || nearPed->m_nPedType == PEDTYPE_UNUSED1
+ || nearPed->m_nPedType == PEDTYPE_PROSTITUTE)
+ && nearPed->CharCreatedBy != MISSION_CHAR
+ && nearPed->IsPedShootable()
+ && nearPed->m_objective != OBJECTIVE_MUG_CHAR) {
+ charToMug = nearPed;
+ break;
}
}
- break;
+ if (charToMug)
+ SetObjective(OBJECTIVE_MUG_CHAR, charToMug);
- case WAITSTATE_FINISH_FLEE:
- animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_TIRED);
- if (animAssoc) {
- if (CTimer::GetTimeInMilliseconds() > m_nWaitTimer) {
- animAssoc->flags |= ASSOC_DELETEFADEDOUT;
- CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_IDLE_STANCE, 4.0f);
- int timer = 2000;
- ClearWaitState();
- SetWaitState(WAITSTATE_CROSS_ROAD_LOOK, &timer);
- }
- } else {
- 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();
+ m_hitRecoverTimer = CTimer::GetTimeInMilliseconds() + 5000;
+ }
+ }
- } 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;
- }
+ if (m_nPedState == PED_WANDER_PATH) {
+ if (CGeneral::GetRandomNumberInRange(0.0f, 1.0f) < 0.5f) {
+ if (CTimer::GetTimeInMilliseconds() > m_standardTimer) {
+ for (int i = 0; i < m_numNearPeds; i ++) {
+ if (m_nearPeds[i] && m_nearPeds[i]->m_nPedState == PED_WANDER_PATH) {
+ if ((GetPosition() - m_nearPeds[i]->GetPosition()).Magnitude() < 1.8f
+ && CanSeeEntity(m_nearPeds[i])
+ && m_nearPeds[i]->CanSeeEntity(this)
+ && WillChat(m_nearPeds[i])) {
- 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);
- }
+ int time = CGeneral::GetRandomNumber() % 4000 + 10000;
+ SetChat(m_nearPeds[i], time);
+ m_nearPeds[i]->SetChat(this, time);
}
}
}
}
- 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;
+ } else {
+ m_standardTimer = CTimer::GetTimeInMilliseconds() + 200;
+ }
}
-
- if(!m_nWaitState)
- RestoreHeadingRate();
}
// --MIAMI: Done
bool
-CPed::Seek(void)
+CPed::WillChat(CPed *stranger)
{
- float distanceToCountItDone = m_distanceToCountSeekDone;
- eMoveState nextMove = PEDMOVE_NONE;
-
- if (m_objective != OBJECTIVE_ENTER_CAR_AS_DRIVER) {
-
- if (m_nPedState != PED_EXIT_TRAIN && m_nPedState != PED_ENTER_TRAIN && m_nPedState != PED_SEEK_IN_BOAT &&
- m_objective != OBJECTIVE_ENTER_CAR_AS_PASSENGER && m_objective != OBJECTIVE_SOLICIT_VEHICLE && !bDuckAndCover) {
-
- if ((!m_pedInObjective || !m_pedInObjective->bInVehicle)
- && (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)->IsCar()) {
- distanceToCountItDone = 2.5f;
- } else {
- CVehicleModelInfo *vehModel = (CVehicleModelInfo *)CModelInfo::GetModelInfo(obstacle->GetModelIndex());
- float yLength = vehModel->GetColModel()->boundingBox.max.y
- - vehModel->GetColModel()->boundingBox.min.y;
- distanceToCountItDone = yLength * 0.55f;
- }
- }
- }
+ if (m_pNextPathNode && m_pLastPathNode) {
+ if (m_pNextPathNode != m_pLastPathNode && ThePaths.TestCrossesRoad(m_pNextPathNode, m_pLastPathNode)) {
+ return false;
}
}
-
- 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);
+ if (m_nSurfaceTouched == SURFACE_TARMAC)
return false;
- }
-
- float seekPosDist = (m_vecSeekPos - GetPosition()).Magnitude2D();
- if (seekPosDist < 2.0f || m_objective == OBJECTIVE_GOTO_AREA_ON_FOOT) {
-
- if (m_objective == OBJECTIVE_FOLLOW_CHAR_IN_FORMATION) {
-
- if (m_pedInObjective->m_nMoveState != PEDMOVE_STILL)
- nextMove = m_pedInObjective->m_nMoveState;
- } else
- nextMove = PEDMOVE_WALK;
-
- } else if (m_objective != OBJECTIVE_FOLLOW_CHAR_IN_FORMATION) {
-
- 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;
-
- } else if (seekPosDist <= 2.0f) {
-
- if (m_pedInObjective->m_nMoveState != PEDMOVE_STILL)
- nextMove = m_pedInObjective->m_nMoveState;
-
- } else {
- nextMove = PEDMOVE_RUN;
- }
-
- if (m_nPedState == PED_SEEK_ENTITY) {
- if (m_pSeekTarget->IsPed()) {
- if (((CPed*)m_pSeekTarget)->bInVehicle)
- distanceToCountItDone += 2.0f;
- }
- }
-
- CVector *nextNode = SeekFollowingPath();
-
- if (nextNode || seekPosDist >= distanceToCountItDone) {
- if (bIsRunning && nextMove != PEDMOVE_SPRINT)
- nextMove = PEDMOVE_RUN;
-
- if (CTimer::GetTimeInMilliseconds() <= m_nPedStateTimer) {
-
- if (m_actionX != 0.0f && m_actionY != 0.0f) {
-
- m_fRotationDest = CGeneral::GetRadianAngleBetweenPoints(
- m_actionX, m_actionY,
- GetPosition().x, GetPosition().y);
-
- float neededTurn = Abs(m_fRotationDest - m_fRotationCur);
-
- if (neededTurn > PI)
- neededTurn = TWOPI - neededTurn;
-
- if (neededTurn > HALFPI) {
- if (seekPosDist >= 1.0f) {
- if (seekPosDist < 2.0f) {
- if (bIsRunning)
- nextMove = PEDMOVE_RUN;
- else
- nextMove = PEDMOVE_WALK;
- }
- } else {
- nextMove = PEDMOVE_STILL;
- }
- }
-
- CVector2D moveDist(GetPosition().x - m_actionX, GetPosition().y - m_actionY);
- if (moveDist.Magnitude() < 0.5f) {
- m_nPedStateTimer = 0;
- m_actionX = 0.f;
- m_actionY = 0.f;
- }
- }
-
- } else {
- 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);
-
- if (neededTurn > PI)
- neededTurn = TWOPI - neededTurn;
-
- if (neededTurn > HALFPI) {
- if (seekPosDist >= 1.0f && neededTurn <= DEGTORAD(135.0f)) {
- if (seekPosDist < 2.0f)
- nextMove = PEDMOVE_WALK;
- } else {
- nextMove = PEDMOVE_STILL;
- }
- }
- }
-
- 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_nPedState != PED_FOLLOW_PATH && m_objective != OBJECTIVE_GOTO_CHAR_ON_FOOT && m_nWaitState == WAITSTATE_FALSE)) {
-
- SetMoveState(nextMove);
- }
-
- SetMoveAnim();
+ if (stranger == this)
+ return false;
+ if (m_nPedType == stranger->m_nPedType)
+ 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;
- }
-
- if ((m_objective != OBJECTIVE_FOLLOW_CHAR_IN_FORMATION || m_pedInObjective->m_nMoveState == PEDMOVE_STILL) && m_nMoveState != PEDMOVE_STILL) {
- m_nPedStateTimer = 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_SPRINT_TO_AREA ||
- m_objective == OBJECTIVE_GOTO_AREA_ANY_MEANS || IsUseAttractorObjective(m_objective)) {
-
- if (m_pNextPathNode)
- m_pNextPathNode = nil;
- else
- bScriptObjectiveCompleted = true;
-
- bUsePedNodeSeek = true;
- }
-
return true;
}
// --MIAMI: Done
-CVector*
-CPed::SeekFollowingPath(void)
-{
- 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
void
-CPed::Flee(void)
+CPed::CalculateNewVelocity(void)
{
- if (CTimer::GetTimeInMilliseconds() > m_fleeTimer && m_fleeTimer) {
- bool mayFinishFleeing = true;
- if (m_nPedState == PED_FLEE_ENTITY) {
- if ((CVector2D(GetPosition()) - ms_vec2DFleePosition).MagnitudeSqr() < sq(30.0f))
- mayFinishFleeing = false;
- }
-
- 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) {
- 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);
- }
- return;
- }
- 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;
- uint8 curDirectionShouldBe = 9; // means not defined yet
-
- if (m_nPedStateTimer < CTimer::GetTimeInMilliseconds()
- && m_collidingThingTimer < CTimer::GetTimeInMilliseconds()) {
-
- if (m_pNextPathNode && CTimer::GetTimeInMilliseconds() > m_standardTimer) {
-
- curDirectionShouldBe = CGeneral::GetNodeHeadingFromVector(GetPosition().x - ms_vec2DFleePosition.x, GetPosition().y - ms_vec2DFleePosition.y);
- if (m_nPathDir < curDirectionShouldBe)
- m_nPathDir += 8;
-
- int dirDiff = m_nPathDir - curDirectionShouldBe;
- if (dirDiff > 2 && dirDiff < 6) {
- realLastNode = nil;
- m_pLastPathNode = m_pNextPathNode;
- m_pNextPathNode = nil;
- }
- }
-
- if (m_pNextPathNode) {
- m_vecSeekPos = CPathFind::TakeWidthIntoAccountForWandering(m_pNextPathNode, m_randomSeed);
- if (m_nMoveState == PEDMOVE_RUN)
- bIsRunning = true;
-
- eMoveState moveState = m_nMoveState;
- if (Seek()) {
- realLastNode = m_pLastPathNode;
- m_pLastPathNode = m_pNextPathNode;
- m_pNextPathNode = nil;
- }
- bIsRunning = false;
- SetMoveState(moveState);
- }
- }
-
- if (!m_pNextPathNode) {
- if (curDirectionShouldBe == 9) {
- curDirectionShouldBe = CGeneral::GetNodeHeadingFromVector(GetPosition().x - ms_vec2DFleePosition.x, GetPosition().y - ms_vec2DFleePosition.y);
- }
- ThePaths.FindNextNodeWandering(PATH_PED, GetPosition(), &m_pLastPathNode, &m_pNextPathNode,
- curDirectionShouldBe,
- &nextDirection);
-
- if (curDirectionShouldBe < nextDirection)
- curDirectionShouldBe += 8;
-
- if (m_pNextPathNode && m_pNextPathNode != realLastNode && m_pNextPathNode != m_pLastPathNode && curDirectionShouldBe - nextDirection != 4) {
- m_nPathDir = nextDirection;
- m_standardTimer = CTimer::GetTimeInMilliseconds() + 2000;
- } else {
- bUsePedNodeSeek = false;
- SetMoveState(PEDMOVE_RUN);
- Flee();
- }
- }
- return;
- }
-
- if ((m_nPedState == PED_FLEE_ENTITY || m_nPedState == PED_ON_FIRE) && m_nPedStateTimer < CTimer::GetTimeInMilliseconds()) {
-
- float angleToFleeFromPos = CGeneral::GetRadianAngleBetweenPoints(
- GetPosition().x,
- GetPosition().y,
- ms_vec2DFleePosition.x,
- ms_vec2DFleePosition.y);
-
- m_fRotationDest = CGeneral::LimitRadianAngle(angleToFleeFromPos);
-
- if (m_fRotationCur - PI > m_fRotationDest)
- m_fRotationDest += TWOPI;
- else if (PI + m_fRotationCur < m_fRotationDest)
- m_fRotationDest -= TWOPI;
- }
-
- if (CTimer::GetTimeInMilliseconds() >= m_collidingThingTimer)
- return;
-
- if (!m_collidingEntityWhileFleeing)
- return;
-
- double collidingThingPriorityMult = (double)(m_collidingThingTimer - CTimer::GetTimeInMilliseconds()) * 2.0 / 2500;
-
- if (collidingThingPriorityMult <= 1.5) {
- double angleToFleeEntity = CGeneral::GetRadianAngleBetweenPoints(
- GetPosition().x,
- GetPosition().y,
- m_collidingEntityWhileFleeing->GetPosition().x,
- m_collidingEntityWhileFleeing->GetPosition().y);
- angleToFleeEntity = CGeneral::LimitRadianAngle(angleToFleeEntity);
-
- double angleToFleeCollidingThing = CGeneral::GetRadianAngleBetweenPoints(
- m_vecDamageNormal.x,
- m_vecDamageNormal.y,
- 0.0f,
- 0.0f);
- angleToFleeCollidingThing = CGeneral::LimitRadianAngle(angleToFleeCollidingThing);
-
- if (angleToFleeEntity - PI > angleToFleeCollidingThing)
- angleToFleeCollidingThing += TWOPI;
- else if (PI + angleToFleeEntity < angleToFleeCollidingThing)
- angleToFleeCollidingThing -= TWOPI;
-
- if (collidingThingPriorityMult <= 1.0f) {
- // Range [0.0, 1.0]
-
- float angleToFleeBoth = (angleToFleeCollidingThing + angleToFleeEntity) * 0.5f;
-
- if (m_fRotationDest - PI > angleToFleeBoth)
- angleToFleeBoth += TWOPI;
- else if (PI + m_fRotationDest < angleToFleeBoth)
- angleToFleeBoth -= TWOPI;
-
- m_fRotationDest = (1.0f - collidingThingPriorityMult) * m_fRotationDest + collidingThingPriorityMult * angleToFleeBoth;
- } else {
- // Range (1.0, 1.5]
+ if (IsPedInControl()) {
+ float headAmount = DEGTORAD(m_headingRate) * CTimer::GetTimeStep();
+ m_fRotationCur = CGeneral::LimitRadianAngle(m_fRotationCur);
+ float limitedRotDest = CGeneral::LimitRadianAngle(m_fRotationDest);
- double adjustedMult = (collidingThingPriorityMult - 1.0f) * 2.0f;
- m_fRotationDest = angleToFleeEntity * (1.0 - adjustedMult) + adjustedMult * angleToFleeCollidingThing;
+ if (m_fRotationCur - PI > limitedRotDest) {
+ limitedRotDest += 2 * PI;
+ } else if(PI + m_fRotationCur < limitedRotDest) {
+ limitedRotDest -= 2 * PI;
}
- } else {
- m_fRotationDest = CGeneral::GetRadianAngleBetweenPoints(
- m_vecDamageNormal.x,
- m_vecDamageNormal.y,
- 0.0f,
- 0.0f);
- m_fRotationDest = CGeneral::LimitRadianAngle(m_fRotationDest);
- }
-
- m_fRotationCur = CGeneral::LimitRadianAngle(m_fRotationCur);
-
- if (m_fRotationCur - PI > m_fRotationDest)
- m_fRotationDest += TWOPI;
- else if (PI + m_fRotationCur < m_fRotationDest)
- m_fRotationDest -= TWOPI;
-}
-
-// --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());
- }
- }
+ float neededTurn = limitedRotDest - m_fRotationCur;
+ if (neededTurn <= headAmount) {
+ if (neededTurn > (-headAmount))
+ m_fRotationCur += neededTurn;
+ else
+ m_fRotationCur -= headAmount;
} else {
- RestorePreviousState();
- ClearFollowPath();
- m_pathNodeTimer = 0;
- }
- }
-}
-
-// --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;
- return GetPosition();
- }
- m_pedInObjective = m_pedInObjective->m_pedInObjective;
- }
-
- CVector formationOffset;
- float offset = CGeneral::GetRandomNumberInRange(1.f, 1.25f) * 1.75f;
- switch (m_pedFormation) {
- case FORMATION_REAR:
- formationOffset = CVector(0.0f, -offset, 0.0f);
- break;
- case FORMATION_REAR_LEFT:
- formationOffset = CVector(-offset, -offset, 0.0f);
- break;
- case FORMATION_REAR_RIGHT:
- formationOffset = CVector(offset, -offset, 0.0f);
- break;
- case FORMATION_FRONT_LEFT:
- formationOffset = CVector(-offset, offset, 0.0f);
- break;
- case FORMATION_FRONT_RIGHT:
- formationOffset = CVector(offset, offset, 0.0f);
- break;
- case FORMATION_LEFT:
- formationOffset = CVector(-offset, 0.0f, 0.0f);
- break;
- case FORMATION_RIGHT:
- formationOffset = CVector(offset, 0.0f, 0.0f);
- break;
- case FORMATION_FRONT:
- formationOffset = CVector(0.0f, offset, 0.0f);
- break;
- default:
- formationOffset = CVector(0.0f, 0.0f, 0.0f);
- break;
- }
- return m_pedInObjective->GetMatrix() * formationOffset;
-}
-
-// --MIAMI: Done
-void
-CPed::GetNearestDoor(CVehicle *veh, CVector &posToOpen)
-{
- CVector *enterOffset = nil;
- 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;
- }
- }
+ m_fRotationCur += headAmount;
}
- } else if (m_vehEnterType == CAR_DOOR_LF && veh->pDriver && !veh->bLowVehicle && !veh->bIsBus) {
- enterOffset = &vecPedQuickDraggedOutCarAnimOffset;
}
- CVector lfPos = GetPositionToOpenCarDoor(veh, CAR_DOOR_LF);
- CVector rfPos = GetPositionToOpenCarDoor(veh, CAR_DOOR_RF);
+ CVector2D forward(Sin(m_fRotationCur), Cos(m_fRotationCur));
- // Left front door is closer
- if ((lfPos - GetPosition()).MagnitudeSqr2D() < (rfPos - GetPosition()).MagnitudeSqr2D()) {
+ m_moved.x = CrossProduct2D(m_vecAnimMoveDelta, forward); // (m_vecAnimMoveDelta.x * Cos(m_fRotationCur)) + -Sin(m_fRotationCur) * m_vecAnimMoveDelta.y;
+ m_moved.y = DotProduct2D(m_vecAnimMoveDelta, forward); // m_vecAnimMoveDelta.y* Cos(m_fRotationCur) + (m_vecAnimMoveDelta.x * Sin(m_fRotationCur));
- if (veh->IsRoomForPedToLeaveCar(CAR_DOOR_LF, enterOffset)) {
- m_vehEnterType = CAR_DOOR_LF;
- posToOpen = lfPos;
- } else if (veh->IsRoomForPedToLeaveCar(CAR_DOOR_RF, enterOffset)) {
- m_vehEnterType = CAR_DOOR_RF;
- posToOpen = rfPos;
- }
+ if (CTimer::GetTimeStep() >= 0.01f) {
+ m_moved = m_moved * (1 / CTimer::GetTimeStep());
} else {
-
- if (veh->IsRoomForPedToLeaveCar(CAR_DOOR_RF, enterOffset)) {
-
- CPed *rfPassenger = veh->pPassengers[0];
- 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)) {
-
- m_vehEnterType = CAR_DOOR_LF;
- posToOpen = lfPos;
- } else {
- m_vehEnterType = CAR_DOOR_RF;
- posToOpen = rfPos;
- }
- } else if (veh->IsRoomForPedToLeaveCar(CAR_DOOR_LF, enterOffset)) {
- m_vehEnterType = CAR_DOOR_LF;
- posToOpen = lfPos;
- }
- }
-}
-
-// --MIAMI: Done
-bool
-CPed::GetNearestPassengerDoor(CVehicle *veh, CVector &posToOpen)
-{
- CVector rfPos, lrPos, rrPos;
- bool canEnter = false;
-
- CVehicleModelInfo *vehModel = (CVehicleModelInfo *)CModelInfo::GetModelInfo(veh->GetModelIndex());
-
- switch (veh->GetModelIndex()) {
- case MI_BUS:
- m_vehEnterType = CAR_DOOR_RF;
- posToOpen = GetPositionToOpenCarDoor(veh, CAR_DOOR_RF);
- return true;
- case MI_RHINO:
- default:
- break;
- }
-
- CVector2D rfPosDist(999.0f, 999.0f);
- CVector2D lrPosDist(999.0f, 999.0f);
- CVector2D rrPosDist(999.0f, 999.0f);
-
- 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)) {
-
- rfPos = GetPositionToOpenCarDoor(veh, CAR_DOOR_RF);
- canEnter = true;
- rfPosDist = rfPos - GetPosition();
+ m_moved = m_moved * (1 / 100.0f);
}
- if (vehModel->m_numDoors == 4) {
- if (!veh->pPassengers[1]
- && !(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[2]
- && !(veh->m_nGettingInFlags & CAR_DOOR_FLAG_RR)
- && veh->IsRoomForPedToLeaveCar(CAR_DOOR_RR, nil)) {
- rrPos = GetPositionToOpenCarDoor(veh, CAR_DOOR_RR);
- canEnter = true;
- rrPosDist = rrPos - GetPosition();
- }
-
- // When the door we should enter is blocked by some object.
- if (!canEnter)
- veh->ShufflePassengersToMakeSpace();
- }
+ if ((!TheCamera.Cams[TheCamera.ActiveCam].GetWeaponFirstPersonOn() && !TheCamera.Cams[0].Using3rdPersonMouseCam())
+ || FindPlayerPed() != this || !CanStrafeOrMouseControl()) {
- CVector2D nextToCompare = rfPosDist;
- posToOpen = rfPos;
- m_vehEnterType = CAR_DOOR_RF;
- if (lrPosDist.MagnitudeSqr() < nextToCompare.MagnitudeSqr()) {
- m_vehEnterType = CAR_DOOR_LR;
- posToOpen = lrPos;
- nextToCompare = lrPosDist;
+ if (FindPlayerPed() == this)
+ FindPlayerPed()->m_fWalkAngle = 0.0f;
+ return;
}
- if (rrPosDist.MagnitudeSqr() < nextToCompare.MagnitudeSqr()) {
- m_vehEnterType = CAR_DOOR_RR;
- posToOpen = rrPos;
- }
- return canEnter;
-}
-
-// --MIAMI: Done
-int
-CPed::GetNextPointOnRoute(void)
-{
- int16 nextPoint = m_routePointsBeingPassed + m_routePointsPassed + m_routeStartPoint;
-
- // Route is complete
- if (nextPoint < 0 || nextPoint > NUMPEDROUTES || m_routeLastPoint != CRouteNode::GetRouteThisPointIsOn(nextPoint)) {
+ float walkAngle = WorkOutHeadingForMovingFirstPerson(m_fRotationCur);
+ float pedSpeed = m_moved.Magnitude();
+ float localWalkAngle = CGeneral::LimitRadianAngle(walkAngle - m_fRotationCur);
- switch (m_routeType) {
- case PEDROUTE_STOP_WHEN_DONE:
- nextPoint = -1;
- break;
- case PEDROUTE_GO_BACKWARD_WHEN_DONE:
- m_routePointsBeingPassed = -m_routePointsBeingPassed;
- nextPoint = m_routePointsBeingPassed + m_routePointsPassed + m_routeStartPoint;
- break;
- case PEDROUTE_GO_TO_START_WHEN_DONE:
- m_routePointsPassed = -1;
- nextPoint = m_routePointsBeingPassed + m_routePointsPassed + m_routeStartPoint;
- break;
- default:
- break;
- }
+ if (localWalkAngle < -0.5f * PI) {
+ localWalkAngle += PI;
+ } else if (localWalkAngle > 0.5f * PI) {
+ localWalkAngle -= PI;
}
- return nextPoint;
-}
-
-// --MIAMI: Done
-int
-CPed::GetWeaponSlot(eWeaponType weaponType)
-{
- return CWeaponInfo::GetWeaponInfo(weaponType)->m_nWeaponSlot;
-}
-
-// --MIAMI: Done
-bool
-CPed::CanWeRunAndFireWithWeapon(void)
-{
- return CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bCanAimWithArm;
-}
-// --MIAMI: Done
-void
-CPed::GoToNearestDoor(CVehicle *veh)
-{
- CVector posToOpen;
- GetNearestDoor(veh, posToOpen);
- SetSeek(posToOpen, 0.5f);
- SetMoveState(PEDMOVE_RUN);
-}
-
-// --MIAMI: Done
-bool
-CPed::HaveReachedNextPointOnRoute(float distToCountReached)
-{
- if ((m_nextRoutePointPos - GetPosition()).Magnitude2D() < distToCountReached) {
- m_routePointsPassed += m_routePointsBeingPassed;
- return true;
+ // Interestingly this part is responsible for diagonal walking.
+ if (localWalkAngle > -DEGTORAD(50.0f) && localWalkAngle < DEGTORAD(50.0f)) {
+ TheCamera.Cams[TheCamera.ActiveCam].m_fPlayerVelocity = pedSpeed;
+ m_moved = CVector2D(-Sin(walkAngle), Cos(walkAngle)) * pedSpeed;
}
- return false;
-}
-// --MIAMI: Done
-void
-CPed::Idle(void)
-{
- CVehicle *veh = m_pMyVehicle;
- if (veh && veh->m_nGettingOutFlags && m_vehEnterType) {
-
- if (veh->m_nGettingOutFlags & GetCarDoorFlag(m_vehEnterType)) {
+ CAnimBlendAssociation *idleAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_STANCE);
+ CAnimBlendAssociation *fightAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_FIGHT_IDLE);
+ if(!fightAssoc)
+ fightAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_TIRED);
- if (m_objective != OBJECTIVE_KILL_CHAR_ON_FOOT) {
+ if(!fightAssoc)
+ fightAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_MELEE_IDLE_FIGHTMODE);
- CVector doorPos = GetPositionToOpenCarDoor(veh, m_vehEnterType);
- CVector doorDist = GetPosition() - doorPos;
+ if ((!idleAssoc || idleAssoc->blendAmount < 0.5f) && !fightAssoc && !bIsDucking) {
+ LimbOrientation newUpperLegs;
+ newUpperLegs.yaw = localWalkAngle;
- if (doorDist.MagnitudeSqr() < sq(0.5f)) {
- SetMoveState(PEDMOVE_WALK);
- return;
- }
- }
+ if (newUpperLegs.yaw < -DEGTORAD(100.0f)) {
+ newUpperLegs.yaw += PI;
+ } else if (newUpperLegs.yaw > DEGTORAD(100.0f)) {
+ newUpperLegs.yaw -= PI;
}
- }
-
- if (m_nMoveState != PEDMOVE_STILL && !IsPlayer())
- SetMoveState(PEDMOVE_STILL);
-
- m_moved = CVector2D(0.0f, 0.0f);
-}
-
-// --MIAMI: Done
-void
-CPed::InTheAir(void)
-{
- CColPoint foundCol;
- CEntity *foundEnt;
-
- CVector ourPos = GetPosition();
- CVector bitBelow = GetPosition();
- bitBelow.z -= 4.04f;
- 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 || bIsStanding)
- SetLanding();
- } 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);
- }
+ if (newUpperLegs.yaw > -DEGTORAD(50.0f) && newUpperLegs.yaw < DEGTORAD(50.0f)) {
+ 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
-void
-CPed::SetLanding(void)
+float
+CPed::WorkOutHeadingForMovingFirstPerson(float offset)
{
- if (DyingOrDead())
- return;
-
- CAnimBlendAssociation *fallAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_FALL_FALL);
- CAnimBlendAssociation *landAssoc;
-
- if (fallAssoc && bIsDrowning)
- return;
-
- RpAnimBlendClumpSetBlendDeltas(GetClump(), ASSOC_PARTIAL, -1000.0f);
- 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 (!IsPlayer())
+ return 0.0f;
- if (m_nPedType == PEDTYPE_COP) {
- if (bKnockedUpIntoAir)
- bKnockedUpIntoAir = false;
- }
+ CPad *pad0 = CPad::GetPad(0);
+ float leftRight = pad0->GetPedWalkLeftRight();
+ float upDown = pad0->GetPedWalkUpDown();
+ float &angle = ((CPlayerPed*)this)->m_fWalkAngle;
+ if (upDown != 0.0f) {
+ angle = CGeneral::GetRadianAngleBetweenPoints(0.0f, 0.0f, -leftRight, upDown);
} else {
- landAssoc = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_FALL_LAND);
- DMAudio.PlayOneShot(m_audioEntityId, SOUND_FALL_LAND, 1.0f);
- }
-
- landAssoc->SetFinishCallback(PedLandCB, this);
- bIsInTheAir = false;
- bIsLanding = true;
-}
-
-// --MIAMI: Done
-void
-CPed::Initialise(void)
-{
- debug("Initialising CPed...\n");
- CPedType::Initialise();
- LoadFightData();
- SetAnimOffsetForEnterOrExitVehicle();
- debug("CPed ready\n");
-}
-
-// --MIAMI: Done
-void
-CPed::SetAnimOffsetForEnterOrExitVehicle(void)
-{
- // FIX: 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;
- CAnimManager::UncompressAnimation(enterAssoc);
- if (seq->numFrames > 0) {
- if (!seq->HasTranslation())
- vecPedDraggedOutCarAnimOffset = CVector(0.0f, 0.0f, 0.0f);
- else {
- KeyFrameTrans *lastFrame = (KeyFrameTrans*)seq->GetKeyFrame(seq->numFrames - 1);
- vecPedDraggedOutCarAnimOffset = lastFrame->translation;
- }
- }
-
- enterAssoc = CAnimManager::GetAnimAssociation(ASSOCGRP_STD, ANIM_CAR_GETIN_LHS)->hierarchy;
- seq = enterAssoc->sequences;
- CAnimManager::UncompressAnimation(enterAssoc);
- if (seq->numFrames > 0) {
- if (!seq->HasTranslation())
- vecPedCarDoorAnimOffset = CVector(0.0f, 0.0f, 0.0f);
- else {
- KeyFrameTrans *lastFrame = (KeyFrameTrans*)seq->GetKeyFrame(seq->numFrames - 1);
- vecPedCarDoorAnimOffset = lastFrame->translation;
- }
- }
-
- enterAssoc = CAnimManager::GetAnimAssociation(ASSOCGRP_STD, ANIM_CAR_GETIN_LOW_LHS)->hierarchy;
- seq = enterAssoc->sequences;
- CAnimManager::UncompressAnimation(enterAssoc);
- if (seq->numFrames > 0) {
- if (!seq->HasTranslation())
- vecPedCarDoorLoAnimOffset = CVector(0.0f, 0.0f, 0.0f);
- else {
- KeyFrameTrans *lastFrame = (KeyFrameTrans*)seq->GetKeyFrame(seq->numFrames - 1);
- vecPedCarDoorLoAnimOffset = lastFrame->translation;
- }
- }
-
- enterAssoc = CAnimManager::GetAnimAssociation(ASSOCGRP_STD, ANIM_CAR_QJACKED)->hierarchy;
- seq = enterAssoc->sequences;
- CAnimManager::UncompressAnimation(enterAssoc);
- if (seq->numFrames > 0) {
- if (!seq->HasTranslation())
- vecPedQuickDraggedOutCarAnimOffset = CVector(0.0f, 0.0f, 0.0f);
- else {
- KeyFrameTrans *lastFrame = (KeyFrameTrans*)seq->GetKeyFrame(seq->numFrames - 1);
- vecPedQuickDraggedOutCarAnimOffset = lastFrame->translation;
- }
- }
-
- enterAssoc = CAnimManager::GetAnimAssociation(ASSOCGRP_VAN, ANIM_VAN_GETIN_L)->hierarchy;
- seq = enterAssoc->sequences;
- CAnimManager::UncompressAnimation(enterAssoc);
- if (seq->numFrames > 0) {
- if (!seq->HasTranslation())
- vecPedVanRearDoorAnimOffset = CVector(0.0f, 0.0f, 0.0f);
- else {
- KeyFrameTrans *lastFrame = (KeyFrameTrans*)seq->GetKeyFrame(seq->numFrames - 1);
- vecPedVanRearDoorAnimOffset = lastFrame->translation;
- }
- }
- // 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) {
- if (!seq->HasTranslation())
- vecPedTrainDoorAnimOffset = CVector(0.0f, 0.0f, 0.0f);
- else {
- KeyFrameTrans *lastFrame = (KeyFrameTrans*)seq->GetKeyFrame(seq->numFrames - 1);
- 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;
- }
+ if (leftRight < 0.0f)
+ angle = HALFPI;
+ else if (leftRight > 0.0f)
+ angle = -HALFPI;
}
- CAnimManager::RemoveAnimBlockRef(vanBlock);
- CAnimManager::RemoveAnimBlockRef(bikesBlock);
- CAnimManager::RemoveAnimBlockRef(bikevBlock);
- CAnimManager::RemoveAnimBlockRef(bikehBlock);
- CAnimManager::RemoveAnimBlockRef(bikedBlock);
+ return CGeneral::LimitRadianAngle(offset + angle);
}
// --MIAMI: Done
void
-CPed::InvestigateEvent(void)
+CPed::UpdatePosition(void)
{
- CAnimBlendAssociation *animAssoc;
- AnimationId animToPlay;
- AssocGroupId animGroup;
-
- if (m_nWaitState == WAITSTATE_TURN180)
- return;
-
- if (CTimer::GetTimeInMilliseconds() > m_standardTimer) {
-
- if (m_standardTimer) {
- if (m_eventType < EVENT_UNK)
- SetWaitState(WAITSTATE_TURN180, nil);
-
- m_standardTimer = 0;
- } else {
- ClearInvestigateEvent();
- }
+ if (CReplay::IsPlayingBack() || !bIsStanding || m_attachedTo)
return;
- }
-
- CVector2D vecDist = m_eventOrThreat - GetPosition();
- float distSqr = vecDist.MagnitudeSqr();
- if (sq(m_distanceToCountSeekDone) >= distSqr) {
-
- m_fRotationDest = CGeneral::GetRadianAngleBetweenPoints(vecDist.x, vecDist.y, 0.0f, 0.0f);
- SetMoveState(PEDMOVE_STILL);
-
- switch (m_eventType) {
- case EVENT_DEAD_PED:
- case EVENT_HIT_AND_RUN:
- case EVENT_HIT_AND_RUN_COP:
-
- if (CTimer::GetTimeInMilliseconds() > m_lookTimer) {
- animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_ROAD_CROSS);
-
- if (animAssoc) {
- animAssoc->blendDelta = -8.0f;
- animAssoc->flags |= ASSOC_DELETEFADEDOUT;
- if (m_pEventEntity)
- SetLookFlag(m_pEventEntity, true);
- SetLookTimer(CGeneral::GetRandomNumberInRange(1500, 4000));
-
- } else if (CGeneral::GetRandomNumber() & 3) {
- ClearLookFlag();
- CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_ROAD_CROSS, 4.0f);
-
- SetLookTimer(CGeneral::GetRandomNumberInRange(1000, 2500));
- Say(SOUND_PED_CHAT_EVENT);
-
- } else {
- ClearInvestigateEvent();
- }
- }
- break;
- case EVENT_FIRE:
- case EVENT_EXPLOSION:
-
- if (bHasACamera && CTimer::GetTimeInMilliseconds() > m_lookTimer) {
- animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_CAM);
- if (!animAssoc)
- animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_STANCE);
-
- if (animAssoc && animAssoc->animId == ANIM_IDLE_CAM) {
- CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_IDLE_STANCE, 4.0f);
- SetLookTimer(CGeneral::GetRandomNumberInRange(1000, 2500));
-
- } else if (CGeneral::GetRandomNumber() & 3) {
- CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_IDLE_CAM, 4.0f);
- SetLookTimer(CGeneral::GetRandomNumberInRange(2500, 5000));
- if (!CGame::germanGame)
- Say(SOUND_PED_CHAT_EVENT);
-
- } else {
- m_standardTimer = 0;
- }
-
- } else if (CTimer::GetTimeInMilliseconds() > m_lookTimer) {
- animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_STANCE);
- if (!animAssoc)
- animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_HBHB);
-
- if (!animAssoc)
- animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_XPRESS_SCRATCH);
-
- if (animAssoc && animAssoc->animId == ANIM_IDLE_STANCE) {
- if (CGeneral::GetRandomNumber() & 1)
- animToPlay = ANIM_IDLE_HBHB;
- else
- animToPlay = ANIM_XPRESS_SCRATCH;
-
- CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, animToPlay, 4.0f);
- SetLookTimer(CGeneral::GetRandomNumberInRange(1500, 4000));
-
- } else if (animAssoc && animAssoc->animId == ANIM_IDLE_HBHB) {
- animAssoc->blendDelta = -8.0f;
- animAssoc->flags |= ASSOC_DELETEFADEDOUT;
- if (CGeneral::GetRandomNumber() & 1) {
- animToPlay = ANIM_IDLE_STANCE;
- animGroup = m_animGroup;
- } else {
- animToPlay = ANIM_XPRESS_SCRATCH;
- animGroup = ASSOCGRP_STD;
- }
-
- CAnimManager::BlendAnimation(GetClump(), animGroup, animToPlay, 4.0f);
- SetLookTimer(CGeneral::GetRandomNumberInRange(1000, 2500));
-
- } else {
- if (CGeneral::GetRandomNumber() & 1) {
- animToPlay = ANIM_IDLE_STANCE;
- animGroup = m_animGroup;
- } else {
- animToPlay = ANIM_IDLE_HBHB;
- animGroup = ASSOCGRP_STD;
- }
-
- CAnimManager::BlendAnimation(GetClump(), animGroup, animToPlay, 4.0f);
- SetLookTimer(CGeneral::GetRandomNumberInRange(1000, 2500));
- }
- if (!CGame::germanGame)
- Say(SOUND_PED_CHAT_EVENT);
- }
- break;
- case EVENT_ICECREAM:
- case EVENT_SHOPSTALL:
+ CVector2D velocityChange;
- m_fRotationDest = m_fAngleToEvent;
- if (CTimer::GetTimeInMilliseconds() > m_lookTimer) {
+ SetHeading(m_fRotationCur);
+ if (m_pCurrentPhysSurface) {
+ CVector2D velocityOfSurface;
+ if (!IsPlayer() && m_pCurrentPhysSurface->IsVehicle() && ((CVehicle*)m_pCurrentPhysSurface)->IsBoat()) {
- if (m_lookTimer) {
- animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_ROAD_CROSS);
+ // It seems R* didn't like m_vecOffsetFromPhysSurface for boats
+ CVector offsetToSurface = GetPosition() - m_pCurrentPhysSurface->GetPosition();
+ offsetToSurface.z -= FEET_OFFSET;
- if (animAssoc) {
- animAssoc->blendDelta = -8.0f;
- animAssoc->flags |= ASSOC_DELETEFADEDOUT;
- if (m_eventType == EVENT_ICECREAM)
- animToPlay = ANIM_IDLE_CHAT;
- else
- animToPlay = ANIM_XPRESS_SCRATCH;
- CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, animToPlay,4.0f);
- SetLookTimer(CGeneral::GetRandomNumberInRange(2000, 5000));
+ CVector surfaceMoveVelocity = m_pCurrentPhysSurface->m_vecMoveSpeed;
+ CVector surfaceTurnVelocity = CrossProduct(m_pCurrentPhysSurface->m_vecTurnSpeed, offsetToSurface);
- } else {
- animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_CHAT);
- if (animAssoc) {
- animAssoc->blendDelta = -8.0f;
- animAssoc->flags |= ASSOC_DELETEFADEDOUT;
- ClearInvestigateEvent();
- } else {
- animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_XPRESS_SCRATCH);
- if (animAssoc) {
- animAssoc->blendDelta = -8.0f;
- animAssoc->flags |= ASSOC_DELETEFADEDOUT;
- }
- ClearInvestigateEvent();
- }
- }
- } else {
- CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_ROAD_CROSS, 4.0f);
- SetLookTimer(CGeneral::GetRandomNumberInRange(1000, 2500));
- }
- }
- break;
- default:
- return;
+ // Also we use that weird formula instead of friction if it's boat
+ float slideMult = -m_pCurrentPhysSurface->m_vecTurnSpeed.MagnitudeSqr();
+ velocityOfSurface = slideMult * offsetToSurface * CTimer::GetTimeStep() + (surfaceTurnVelocity + surfaceMoveVelocity);
+ m_vecMoveSpeed.z = slideMult * offsetToSurface.z * CTimer::GetTimeStep() + (surfaceTurnVelocity.z + surfaceMoveVelocity.z);
+ } else {
+ velocityOfSurface = m_pCurrentPhysSurface->GetSpeed(m_vecOffsetFromPhysSurface);
}
- } else {
- m_vecSeekPos.x = m_eventOrThreat.x;
- m_vecSeekPos.y = m_eventOrThreat.y;
- m_vecSeekPos.z = GetPosition().z;
- Seek();
+ // Reminder: m_moved is displacement from walking/running.
+ velocityChange = m_moved + velocityOfSurface - m_vecMoveSpeed;
+ m_fRotationCur += m_pCurrentPhysSurface->m_vecTurnSpeed.z * CTimer::GetTimeStep();
+ m_fRotationDest += m_pCurrentPhysSurface->m_vecTurnSpeed.z * CTimer::GetTimeStep();
+ } else if (m_nSurfaceTouched == SURFACE_STEEP_CLIFF && (m_vecDamageNormal.x != 0.0f || m_vecDamageNormal.y != 0.0f)) {
+ // Ped got damaged by steep slope
+ m_vecMoveSpeed = CVector(0.0f, 0.0f, -0.001f);
+ // some kind of
+ CVector2D reactionForce = m_vecDamageNormal;
+ reactionForce.Normalise();
- if (m_eventType < EVENT_ICECREAM) {
- if (sq(5.0f + m_distanceToCountSeekDone) < distSqr) {
- SetMoveState(PEDMOVE_RUN);
- return;
- }
- }
- if (m_eventType <= EVENT_EXPLOSION || m_eventType >= EVENT_SHOPSTALL) {
- SetMoveState(PEDMOVE_WALK);
- return;
- }
- if (distSqr > sq(1.2f)) {
- SetMoveState(PEDMOVE_WALK);
- return;
- }
+ velocityChange = 0.02f * reactionForce + m_moved;
- 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);
- willStandStill = true;
- break;
- }
+ float reactionAndVelocityDotProd = DotProduct2D(reactionForce, velocityChange);
+ // they're in same direction
+ if (reactionAndVelocityDotProd < 0.0f) {
+ velocityChange -= reactionAndVelocityDotProd * reactionForce;
}
-
- if (!willStandStill)
- SetMoveState(PEDMOVE_WALK);
- }
-}
-
-// --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;
- }
- return false;
-}
-
-// --MIAMI: Done
-bool
-CPed::IsPedShootable(void)
-{
- return m_nPedState <= PED_STATES_NO_ST;
-}
-
-// --MIAMI: Done
-bool
-CPed::IsRoomToBeCarJacked(void)
-{
- if (!m_pMyVehicle)
- return false;
-
- CVector offset;
- if (m_pMyVehicle->IsBike()) {
- offset = vecPedStdBikeJumpRhsAnimOffset;
- } else if (m_pMyVehicle->bLowVehicle || m_nPedType == PEDTYPE_COP) {
- offset = vecPedDraggedOutCarAnimOffset;
} else {
- offset = vecPedQuickDraggedOutCarAnimOffset;
- }
-
- offset.z = 0.0f;
- if (m_pMyVehicle->IsRoomForPedToLeaveCar(CAR_DOOR_LF, &offset)) {
- return true;
- }
-
- return false;
-}
-
-// --MIAMI: Done
-void
-CPed::KillPedWithCar(CVehicle *car, float impulse)
-{
- CVehicleModelInfo *vehModel;
- CColModel *vehColModel;
- uint8 damageDir;
- PedNode nodeToDamage;
- eWeaponType killMethod;
-
- if (m_nPedState == PED_FALL || m_nPedState == PED_DIE) {
- if (!m_pCollidingEntity || car->GetStatus() == STATUS_PLAYER)
- m_pCollidingEntity = car;
- return;
- }
-
- if (m_nPedState == PED_DEAD)
- return;
-
- if (m_pCurSurface) {
- if (m_pCurSurface->IsVehicle() && (((CVehicle*)m_pCurSurface)->IsBoat()|| IsPlayer()))
- return;
+ velocityChange = m_moved - m_vecMoveSpeed;
}
-
- CVector distVec = GetPosition() - car->GetPosition();
-
- if ((impulse > 12.0f || car->GetModelIndex() == MI_TRAIN) && !IsPlayer()) {
- nodeToDamage = PED_TORSO;
- killMethod = WEAPONTYPE_RAMMEDBYCAR;
- uint8 randVal = CGeneral::GetRandomNumber() & 3;
-
- if (car == FindPlayerVehicle()) {
- float carSpeed = car->m_vecMoveSpeed.Magnitude();
- uint8 shakeFreq;
- if (100.0f * carSpeed * 2000.0f / car->m_fMass + 80.0f <= 250.0f) {
- shakeFreq = 100.0f * carSpeed * 2000.0f / car->m_fMass + 80.0f;
- } else {
- shakeFreq = 250.0f;
- }
- CPad::GetPad(0)->StartShake(40000 / shakeFreq, shakeFreq);
- }
- bIsStanding = false;
- damageDir = GetLocalDirection(-m_vecMoveSpeed);
- vehModel = (CVehicleModelInfo *)CModelInfo::GetModelInfo(car->GetModelIndex());
- vehColModel = vehModel->GetColModel();
- float carRightAndDistDotProd = DotProduct(distVec, car->GetRight());
-
- if (car->GetModelIndex() == MI_TRAIN) {
- killMethod = WEAPONTYPE_RUNOVERBYCAR;
- nodeToDamage = PED_HEAD;
- m_vecMoveSpeed = 0.9f * car->m_vecMoveSpeed;
- m_vecMoveSpeed.z = 0.0f;
- if (damageDir == 1 || damageDir == 3)
- damageDir = 2;
- if (CGame::nastyGame)
- DMAudio.PlayOneShot(m_audioEntityId, SOUND_SPLATTER, 0.0f);
-
- // Car doesn't look to us
- } else if (DotProduct(car->m_vecMoveSpeed, car->GetForward()) >= 0.0f){
-
- if (0.99f * vehColModel->boundingBox.max.x < Abs(carRightAndDistDotProd)) {
-
- // We're at the right of the car
- if (carRightAndDistDotProd <= 0.0f)
- nodeToDamage = PED_UPPERARML;
- else
- nodeToDamage = PED_UPPERARMR;
-
- if (Abs(DotProduct(distVec, car->GetForward())) < 0.85f * vehColModel->boundingBox.max.y) {
- killMethod = WEAPONTYPE_RUNOVERBYCAR;
- m_vecMoveSpeed = 0.9f * car->m_vecMoveSpeed;
- m_vecMoveSpeed.z = 0.0f;
- if (damageDir == 1 || damageDir == 3)
- damageDir = 2;
- if (CGame::nastyGame)
- DMAudio.PlayOneShot(m_audioEntityId, SOUND_SPLATTER, 0.0f);
-
- }
- } else {
- float carFrontAndDistDotProd = DotProduct(distVec, car->GetForward());
-
- // carFrontAndDistDotProd <= 0.0 car looks to us
- if ((carFrontAndDistDotProd <= 0.1 || randVal <= 1) && randVal != 0) {
- killMethod = WEAPONTYPE_RUNOVERBYCAR;
- nodeToDamage = PED_HEAD;
- m_vecMoveSpeed = 0.9f * car->m_vecMoveSpeed;
- m_vecMoveSpeed.z = 0.0f;
- if (damageDir == 1 || damageDir == 3)
- damageDir = 2;
-
- if (CGame::nastyGame)
- DMAudio.PlayOneShot(m_audioEntityId, SOUND_SPLATTER, 0.0f);
-
- } else {
- nodeToDamage = PED_MID;
- float vehColMaxY = vehColModel->boundingBox.max.y;
- float vehColMinY = vehColModel->boundingBox.min.y;
- float vehColMaxZ = vehColModel->boundingBox.max.z;
- float carFrontZ = car->GetForward().z;
- float carHighestZ, carLength;
-
- if (carFrontZ < -0.2f) {
- // Highest point of car's back
- carHighestZ = (car->GetMatrix() * CVector(0.0f, vehColMinY, vehColMaxZ)).z;
- carLength = vehColMaxY - vehColMinY;
-
- } else if (carFrontZ > 0.1f) {
- // Highest point of car's front
- carHighestZ = (car->GetMatrix() * CVector(0.0f, vehColMaxY, vehColMaxZ)).z;
- float highestZDist = carHighestZ - GetPosition().z;
- if (highestZDist > 0.0f) {
- GetMatrix().GetPosition().z += 0.5f * highestZDist;
- carHighestZ += highestZDist * 0.25f;
- }
- carLength = vehColMaxY;
-
- } else {
- // Highest point of car's front
- carHighestZ = (car->GetMatrix() * CVector(0.0f, vehColMaxY, vehColMaxZ)).z;
- carLength = vehColMaxY;
- }
-
- float pedJumpSpeedToReachHighestZ = (carHighestZ - GetPosition().z) / (carLength / car->m_vecMoveSpeed.Magnitude());
-
- // TODO: What are we doing down here?
- float unknown = ((CGeneral::GetRandomNumber() % 256) * 0.002 + 1.5) * pedJumpSpeedToReachHighestZ;
-
- // After this point distVec isn't really distVec.
- distVec = car->m_vecMoveSpeed;
- distVec.Normalise();
- distVec *= 0.2 * unknown;
-
- if (damageDir != 1 && damageDir != 3)
- distVec.z += unknown;
- else
- distVec.z += 1.5f * unknown;
-
- m_vecMoveSpeed = distVec;
- damageDir += 2;
- if (damageDir > 3)
- damageDir = damageDir - 4;
-
- if (car->IsCar()) {
- CObject *bonnet = ((CAutomobile*)car)->RemoveBonnetInPedCollision();
-
- if (bonnet) {
- if (CGeneral::GetRandomNumber() & 1) {
- bonnet->m_vecMoveSpeed += Multiply3x3(car->GetMatrix(), CVector(0.1f, 0.0f, 0.5f));
- } else {
- bonnet->m_vecMoveSpeed += Multiply3x3(car->GetMatrix(), CVector(-0.1f, 0.0f, 0.5f));
- }
- CVector forceDir = car->GetUp() * 10.0f;
- bonnet->ApplyTurnForce(forceDir, car->GetForward());
- }
- }
- }
- }
- }
-
- if (car->pDriver) {
- CEventList::RegisterEvent((m_nPedType == PEDTYPE_COP ? EVENT_HIT_AND_RUN_COP : EVENT_HIT_AND_RUN), EVENT_ENTITY_PED, this, car->pDriver, 1000);
- }
-
- ePedPieceTypes pieceToDamage;
- switch (nodeToDamage) {
- case PED_HEAD:
- pieceToDamage = PEDPIECE_HEAD;
- break;
- case PED_UPPERARML:
- pieceToDamage = PEDPIECE_LEFTARM;
- break;
- case PED_UPPERARMR:
- pieceToDamage = PEDPIECE_RIGHTARM;
- break;
- default:
- pieceToDamage = PEDPIECE_MID;
- break;
- }
- InflictDamage(car, killMethod, 1000.0f, pieceToDamage, damageDir);
-
- if (DyingOrDead()
- && bIsPedDieAnimPlaying && !m_pCollidingEntity) {
- m_pCollidingEntity = car;
- }
- if (nodeToDamage == PED_MID)
- bKnockedUpIntoAir = true;
- else
- bKnockedUpIntoAir = false;
-
- distVec.Normalise();
-
- distVec *= Min(car->m_fMass / 1400.0f, 1.0f);
- car->ApplyMoveForce(distVec * -100.0f);
- Say(SOUND_PED_DEFEND);
-
- } else if (m_vecDamageNormal.z < -0.8f && impulse > 3.0f
- || impulse > 6.0f && (!IsPlayer() || impulse > 10.0f)) {
-
- bIsStanding = false;
- uint8 fallDirection = GetLocalDirection(-car->m_vecMoveSpeed);
- float damage;
- if (IsPlayer() && car->GetModelIndex() == MI_TRAIN)
- damage = 150.0f;
- else
- damage = 30.0f;
- InflictDamage(car, WEAPONTYPE_RAMMEDBYCAR, damage, PEDPIECE_TORSO, fallDirection);
- SetFall(1000, (AnimationId)(fallDirection + ANIM_KO_SKID_FRONT), true);
-
- if (OnGround() && !m_pCollidingEntity &&
- (!IsPlayer() || bHasHitWall || car->GetModelIndex() == MI_TRAIN || m_vecDamageNormal.z < -0.8f)) {
-
- m_pCollidingEntity = car;
- }
-
- bKnockedUpIntoAir = false;
- if (car->GetModelIndex() != MI_TRAIN && !bHasHitWall) {
- m_vecMoveSpeed = car->m_vecMoveSpeed * 0.75f;
+ // Take time step into account
+ 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()) {
+ changeMult = 0.002f * CTimer::GetTimeStep();
+ } else if (!(m_pCurrentPhysSurface->IsVehicle() && ((CVehicle*)m_pCurrentPhysSurface)->IsBoat())) {
+ changeMult = 0.01f * CTimer::GetTimeStep();
}
- m_vecMoveSpeed.z = 0.0f;
- distVec.Normalise();
- distVec *= Min(car->m_fMass / 1400.0f, 1.0f);
- car->ApplyMoveForce(distVec * -60.0f);
- Say(SOUND_PED_DEFEND);
- }
- if (IsGangMember()) {
- CPed *driver = car->pDriver;
- if (driver && driver->IsPlayer()
-#ifdef FIX_BUGS
- && (CharCreatedBy != MISSION_CHAR || bRespondsToThreats) && (!m_leader || m_leader != driver)
-#endif
- ) {
- RegisterThreatWithGangPeds(driver);
+ if (speedChange > changeMult) {
+ velocityChange = velocityChange * (changeMult / speedChange);
}
}
+ m_vecMoveSpeed.x += velocityChange.x;
+ m_vecMoveSpeed.y += velocityChange.y;
}
// --MIAMI: Done
void
-CPed::Look(void)
-{
- TurnBody();
-}
-
-// --MIAMI: Done
-bool
-CPed::LookForInterestingNodes(void)
+CPed::CalculateNewOrientation(void)
{
- CBaseModelInfo *model;
- CPtrNode *ptrNode;
- CVector effectDist;
- C2dEffect *effect;
- CMatrix *objMat;
-
- if ((CTimer::GetFrameCounter() + (m_randomSeed % 256)) & 7 || CTimer::GetTimeInMilliseconds() <= m_standardTimer) {
- return false;
- }
- bool found = false;
- uint8 randVal = CGeneral::GetRandomNumber() % 256;
-
- int minX = CWorld::GetSectorIndexX(GetPosition().x - CHECK_NEARBY_THINGS_MAX_DIST);
- if (minX < 0) minX = 0;
- int minY = CWorld::GetSectorIndexY(GetPosition().y - CHECK_NEARBY_THINGS_MAX_DIST);
- if (minY < 0) minY = 0;
- int maxX = CWorld::GetSectorIndexX(GetPosition().x + CHECK_NEARBY_THINGS_MAX_DIST);
-#ifdef FIX_BUGS
- if (maxX >= NUMSECTORS_X) maxX = NUMSECTORS_X - 1;
-#else
- if (maxX >= NUMSECTORS_X) maxX = NUMSECTORS_X;
-#endif
-
- int maxY = CWorld::GetSectorIndexY(GetPosition().y + CHECK_NEARBY_THINGS_MAX_DIST);
-#ifdef FIX_BUGS
- if (maxY >= NUMSECTORS_Y) maxY = NUMSECTORS_Y - 1;
-#else
- if (maxY >= NUMSECTORS_Y) maxY = NUMSECTORS_Y;
-#endif
-
- for (int curY = minY; curY <= maxY && !found; curY++) {
- for (int curX = minX; curX <= maxX && !found; curX++) {
- CSector *sector = CWorld::GetSector(curX, curY);
-
- for (ptrNode = sector->m_lists[ENTITYLIST_VEHICLES].first; ptrNode && !found; ptrNode = ptrNode->next) {
- CVehicle *veh = (CVehicle*)ptrNode->item;
- model = veh->GetModelInfo();
- if (model->GetNum2dEffects() != 0) {
- for (int e = 0; e < model->GetNum2dEffects(); e++) {
- effect = model->Get2dEffect(e);
- if (effect->type == EFFECT_ATTRACTOR && effect->attractor.probability >= randVal) {
- objMat = &veh->GetMatrix();
- CVector effectPos = veh->GetMatrix() * effect->pos;
- effectDist = effectPos - GetPosition();
- if (effectDist.MagnitudeSqr() < sq(8.0f)) {
- found = true;
- break;
- }
- }
- }
- }
- }
- for (ptrNode = sector->m_lists[ENTITYLIST_OBJECTS].first; ptrNode && !found; ptrNode = ptrNode->next) {
- CObject *obj = (CObject*)ptrNode->item;
- model = CModelInfo::GetModelInfo(obj->GetModelIndex());
- if (model->GetNum2dEffects() != 0) {
- for (int e = 0; e < model->GetNum2dEffects(); e++) {
- effect = model->Get2dEffect(e);
- if (effect->type == EFFECT_ATTRACTOR && effect->attractor.probability >= randVal) {
- objMat = &obj->GetMatrix();
- CVector effectPos = obj->GetMatrix() * effect->pos;
- effectDist = effectPos - GetPosition();
- if (effectDist.MagnitudeSqr() < sq(8.0f)) {
- found = true;
- break;
- }
- }
- }
- }
- }
- for (ptrNode = sector->m_lists[ENTITYLIST_BUILDINGS].first; ptrNode && !found; ptrNode = ptrNode->next) {
- CBuilding *building = (CBuilding*)ptrNode->item;
- model = CModelInfo::GetModelInfo(building->GetModelIndex());
- if (model->GetNum2dEffects() != 0) {
- for (int e = 0; e < model->GetNum2dEffects(); e++) {
- effect = model->Get2dEffect(e);
- if (effect->type == EFFECT_ATTRACTOR && effect->attractor.probability >= randVal) {
- objMat = &building->GetMatrix();
- CVector effectPos = building->GetMatrix() * effect->pos;
- effectDist = effectPos - GetPosition();
- if (effectDist.MagnitudeSqr() < sq(8.0f)) {
- found = true;
- break;
- }
- }
- }
- }
- }
- for (ptrNode = sector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP].first; ptrNode && !found; ptrNode = ptrNode->next) {
- CBuilding *building = (CBuilding*)ptrNode->item;
- model = CModelInfo::GetModelInfo(building->GetModelIndex());
- if (model->GetNum2dEffects() != 0) {
- for (int e = 0; e < model->GetNum2dEffects(); e++) {
- effect = model->Get2dEffect(e);
- if (effect->type == EFFECT_ATTRACTOR && effect->attractor.probability >= randVal) {
- objMat = &building->GetMatrix();
- CVector effectPos = building->GetMatrix() * effect->pos;
- effectDist = effectPos - GetPosition();
- if (effectDist.MagnitudeSqr() < sq(8.0f)) {
- found = true;
- break;
- }
- }
- }
- }
- }
- }
- }
-
- if (!found)
- return false;
-
- CVector effectFrontLocal = Multiply3x3(*objMat, effect->attractor.dir);
- float angleToFace = CGeneral::GetRadianAngleBetweenPoints(effectFrontLocal.x, effectFrontLocal.y, 0.0f, 0.0f);
- randVal = CGeneral::GetRandomNumber() % 256;
- if (randVal <= m_randomSeed % 256) {
- m_standardTimer = CTimer::GetTimeInMilliseconds() + 2000;
- SetLookFlag(angleToFace, true);
- SetLookTimer(1000);
- return false;
- }
+ if (CReplay::IsPlayingBack() || !IsPedInControl())
+ return;
- CVector2D effectPos = *objMat * effect->pos;
- switch (effect->attractor.type) {
- case ATTRACTORTYPE_ICECREAM:
- SetInvestigateEvent(EVENT_ICECREAM, effectPos, 0.1f, 15000, angleToFace);
- break;
- case ATTRACTORTYPE_STARE:
- SetInvestigateEvent(EVENT_SHOPSTALL, effectPos, 1.0f,
- CGeneral::GetRandomNumberInRange(8000, 10 * effect->attractor.probability + 8500),
- angleToFace);
- break;
- default:
- return true;
- }
- return true;
+ SetHeading(m_fRotationCur);
}
// --MIAMI: Done
void
-CPed::SetInvestigateEvent(eEventType event, CVector2D pos, float distanceToCountDone, uint16 time, float angle)
+CPed::ClearAll(void)
{
- if (!IsPedInControl() || CharCreatedBy == MISSION_CHAR)
+ if (!IsPedInControl() && m_nPedState != PED_DEAD)
return;
- SetStoredState();
- bFindNewNodeAfterStateRestore = false;
- SetPedState(PED_INVESTIGATE);
- m_standardTimer = CTimer::GetTimeInMilliseconds() + time;
- m_eventType = event;
- m_eventOrThreat = pos;
- m_distanceToCountSeekDone = distanceToCountDone;
- m_fAngleToEvent = angle;
-
- if (m_eventType >= EVENT_ICECREAM)
- m_lookTimer = 0;
- else
- CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_HANDSCOWER, 4.0f);
-
+ SetPedState(PED_NONE);
+ SetMoveState(PEDMOVE_NONE);
+ m_pSeekTarget = nil;
+ m_vecSeekPos = CVector(0.0f, 0.0f, 0.0f);
+ m_fleeFromPos = CVector2D(0.0f, 0.0f);
+ m_fleeFrom = nil;
+ m_fleeTimer = 0;
+ m_threatEx = nil;
+ bUsesCollision = true;
+ ClearPointGunAt();
+ bIsPointingGunAt = false;
+ bRenderPedInCar = true;
+ bKnockedUpIntoAir = false;
+ bKnockedOffBike = false;
+ m_pCollidingEntity = nil;
}
// --MIAMI: Done
void
-CPed::LookForSexyCars(void)
+CPed::ProcessBuoyancy(void)
{
- CEntity *vehicles[8];
- CVehicle *veh;
- int foundVehId = 0;
- int bestPriceYet = 0;
- int16 lastVehicle;
+ float buoyancyLevel = 1.1f;
+ static uint32 nGenerateRaindrops = 0;
+ static uint32 nGenerateWaterCircles = 0;
+ CRGBA color;
- if (!IsPedInControl() && m_nPedState != PED_DRIVING)
+ if (bInVehicle)
return;
- if (m_lookTimer < CTimer::GetTimeInMilliseconds()) {
- CWorld::FindObjectsInRange(GetPosition(), 10.0f, true, &lastVehicle, 6, vehicles, false, true, false, false, false);
-
- for (int vehId = 0; vehId < lastVehicle; vehId++) {
- veh = (CVehicle*)vehicles[vehId];
- if (veh != m_pMyVehicle && bestPriceYet < veh->pHandling->nMonetaryValue) {
- foundVehId = vehId;
- bestPriceYet = veh->pHandling->nMonetaryValue;
- }
- }
- if (lastVehicle > 0 && bestPriceYet > 40000)
- SetLookFlag(vehicles[foundVehId], false);
-
- m_lookTimer = CTimer::GetTimeInMilliseconds() + 10000;
- }
-}
-
-// --MIAMI: Done
-void
-CPed::LookForSexyPeds(void)
-{
- if ((!IsPedInControl() && m_nPedState != PED_DRIVING)
- || m_lookTimer >= CTimer::GetTimeInMilliseconds() || m_nPedType != PEDTYPE_CIVMALE)
- return;
+ CVector buoyancyPoint;
+ CVector buoyancyImpulse;
- for (int i = 0; i < m_numNearPeds; i++) {
- if (CanSeeEntity(m_nearPeds[i])) {
- if ((GetPosition() - m_nearPeds[i]->GetPosition()).Magnitude() < 10.0f) {
- CPed *nearPed = m_nearPeds[i];
- if ((nearPed->m_pedStats->m_sexiness > m_pedStats->m_sexiness)
- && nearPed->m_nPedType == PEDTYPE_CIVFEMALE) {
+ if (DyingOrDead())
+ buoyancyLevel = 1.8f;
- SetLookFlag(nearPed, true);
- m_lookTimer = CTimer::GetTimeInMilliseconds() + 4000;
- Say(SOUND_PED_CHAT_SEXY);
- return;
- }
- }
+ 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->bRenderScorched) {
+ bIsInWater = false;
+ return;
}
- }
- m_lookTimer = CTimer::GetTimeInMilliseconds() + 10000;
-}
-
-// --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->m_scanCode != CWorld::GetCurrentScanCode()) {
- veh->m_scanCode = CWorld::GetCurrentScanCode();
-
- 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;
- case 1:
- approxWheelOffset = CVector(-vehCol->boundingBox.max.x, vehCol->boundingBox.min.y, 0.0f);
- break;
- case 2:
- approxWheelOffset = CVector(vehCol->boundingBox.max.x, vehCol->boundingBox.max.y, 0.0f);
- break;
- case 3:
- approxWheelOffset = CVector(vehCol->boundingBox.max.x, vehCol->boundingBox.min.y, 0.0f);
- break;
- default:
- break;
- }
-
- // 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);
- }
- }
- }
- }
- }
- }
- } 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;
- }
-
- // 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);
+ 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()) {
+ if (bTryingToReachDryLand) {
+ if (buoyancyImpulse.z / m_fMass > GRAVITY * 0.4f * CTimer::GetTimeStep()) {
+ bTryingToReachDryLand = false;
+ CVector pos = GetPosition();
+ if (PlacePedOnDryLand()) {
+ if (m_fHealth > 20.0f)
+ InflictDamage(nil, WEAPONTYPE_DROWNING, 15.0f, PEDPIECE_TORSO, false);
- if (bike == FindPlayerVehicle()) {
- CPad::GetPad(0)->StartShake(300, 70);
- }
- }
- }
- }
- }
+ if (bIsInTheAir) {
+ RpAnimBlendClumpSetBlendDeltas(GetClump(), ASSOC_PARTIAL, -1000.0f);
+ bIsInTheAir = false;
}
+ pos.z = pos.z - 0.8f;
+ CParticleObject::AddObject(POBJECT_PED_WATER_SPLASH, pos, CVector(0.0f, 0.0f, 0.0f), 0.0f, 50, color, true);
+ m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f);
+ SetPedState(PED_IDLE);
+ return;
}
}
}
}
- }
-}
-
-// --MIAMI: Done
-void
-CPed::Mug(void)
-{
- if (m_pSeekTarget && m_pSeekTarget->IsPed()) {
-
- if (CTimer::GetTimeInMilliseconds() <= m_attackTimer - 2000) {
- if ((m_pSeekTarget->GetPosition() - GetPosition()).Magnitude() > 3.0f)
- m_wepSkills = 50;
-
- Say(SOUND_PED_MUGGING);
- ((CPed*)m_pSeekTarget)->Say(SOUND_PED_ROBBED);
- } else {
- SetWanderPath(CGeneral::GetRandomNumber() & 7);
- SetFlee(m_pSeekTarget, 20000);
- }
-
- } else {
- SetIdle();
- }
-}
-
-// --MIAMI: Done
-void
-CPed::MoveHeadToLook(void)
-{
- CVector lookPos;
-
- if (m_lookTimer && CTimer::GetTimeInMilliseconds() > m_lookTimer) {
- ClearLookFlag();
- }
-
- 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 {
- lookPos = m_pLookTarget->GetPosition();
+ 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 (!m_pedIK.LookAtPosition(lookPos)) {
- if (!bKeepTryingToLook) {
- ClearLookFlag();
+ if (buoyancyImpulse.z / m_fMass > GRAVITY * 0.25f * CTimer::GetTimeStep()) {
+ if (speedMult == 0.0f) {
+ speedMult = pow(0.9f, CTimer::GetTimeStep());
}
- return;
- }
-
- if (!bShakeFist || bIsAimingGun || bIsRestoringGun)
- return;
-
- if (m_nPedState == PED_ANSWER_MOBILE)
- return;
-
- if (m_lookTimer - CTimer::GetTimeInMilliseconds() >= 1000)
- return;
-
- bool handFreeToMove = false;
- AnimationId animToPlay = NUM_STD_ANIMS;
-
- if (!GetWeapon()->IsType2Handed() && GetWeapon()->m_eWeaponType != WEAPONTYPE_ROCKETLAUNCHER)
- handFreeToMove = true;
-
- if (IsPlayer() && handFreeToMove) {
-
- if (m_pLookTarget->IsPed()) {
-#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_FUCKU;
- else if(m_pedStats->m_temper < 47)
- animToPlay = ANIM_FIGHT_PPUNCH;
+ 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 {
- if (m_pedStats->m_temper > 49 || m_pLookTarget->GetModelIndex() == MI_POLICE)
- animToPlay = ANIM_FUCKU;
- }
- } else if (handFreeToMove && (CGeneral::GetRandomNumber() & 1)) {
- animToPlay = ANIM_FUCKU;
- }
-
- if (animToPlay != NUM_STD_ANIMS) {
- CAnimBlendAssociation *newAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, animToPlay, 4.0f);
+ 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 (newAssoc) {
- newAssoc->flags |= ASSOC_FADEOUTWHENDONE;
- newAssoc->flags |= ASSOC_DELETEFADEDOUT;
+ 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;
}
}
- bShakeFist = false;
- } else if (m_fLookDirection == 999999.0f) {
- ClearLookFlag();
- } else if (!m_pedIK.LookInDirection(m_fLookDirection, 0.0f)) {
- if (!bKeepTryingToLook)
- ClearLookFlag();
- }
-}
-
-// --MIAMI: Done
-void
-CPed::Pause(void)
-{
- m_moved = CVector2D(0.0f, 0.0f);
- if (CTimer::GetTimeInMilliseconds() > m_leaveCarTimer)
- ClearPause();
-}
-
-// --MIAMI: Done
-void
-CPed::PedAnimAlignCB(CAnimBlendAssociation *animAssoc, void *arg)
-{
- CPed *ped = (CPed*)arg;
-
- CVehicle *veh = ped->m_pMyVehicle;
- if (animAssoc)
- animAssoc->blendDelta = -1000.0f;
-
- if (!ped->IsNotInWreckedVehicle())
- return;
-
- if (!ped->EnteringCar()) {
- if (ped->m_nPedState != PED_DRIVING)
- 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;
- bool itsLow = !!veh->bLowVehicle;
- eDoors enterDoor;
-
- switch (ped->m_vehEnterType) {
- case CAR_DOOR_RF:
- itsVan = false;
- enterDoor = DOOR_FRONT_RIGHT;
- break;
- case CAR_DOOR_RR:
- enterDoor = DOOR_REAR_RIGHT;
- break;
- case CAR_DOOR_LF:
- itsVan = false;
- enterDoor = DOOR_FRONT_LEFT;
- break;
- case CAR_DOOR_LR:
- enterDoor = DOOR_REAR_LEFT;
- break;
- default:
- 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;
+ if (nGenerateWaterCircles && CTimer::GetTimeInMilliseconds() >= nGenerateWaterCircles) {
+ CVector pos = GetPosition();
+ float level = 0.0f;
+ if (CWaterLevel::GetWaterLevel(pos, &level, false))
+ pos.z = level;
- } 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 (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 (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 || 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) {
- ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_VAN, ANIM_VAN_GETIN);
- } else if (itsBus) {
- ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_COACH, ANIM_COACH_IN_R);
- } else if (itsLow) {
- 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);
- }
- } else if (itsVan) {
- ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_VAN, ANIM_VAN_GETIN_L);
- } else if (itsBus) {
- ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_COACH, ANIM_COACH_IN_L);
- } else if (itsLow) {
- 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);
-
- } else if (veh->CanPedOpenLocks(ped)) {
-
- veh->AutoPilot.m_nCruiseSpeed = 0;
- if (enterDoor != DOOR_FRONT_LEFT && enterDoor != DOOR_REAR_LEFT) {
- if (itsVan) {
- ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_VAN, ANIM_VAN_OPEN);
- } else if (itsBus) {
- 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_VAN, ANIM_VAN_OPEN_L);
- } else if (itsBus) {
- 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) {
-
- if (!veh->bLowVehicle
- && veh->pDriver->CharCreatedBy != MISSION_CHAR
- && veh->pDriver->m_nPedState == PED_DRIVING) {
-
- ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_QJACK);
- ped->m_pVehicleAnim->SetFinishCallback(PedAnimGetInCB, 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;
+ 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);
}
- ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_OPEN_LHS);
}
- ped->m_pVehicleAnim->SetFinishCallback(PedAnimDoorOpenCB, ped);
-
- } else {
- if (enterDoor != DOOR_FRONT_LEFT && enterDoor != DOOR_REAR_LEFT)
- ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_DOORLOCKED_RHS);
- else
- ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_DOORLOCKED_LHS);
-
- ped->bCancelEnteringCar = true;
- ped->m_pVehicleAnim->SetFinishCallback(PedAnimDoorOpenCB, ped);
- }
+ } else
+ bTouchingWater = false;
}
// --MIAMI: Done?
@@ -11004,11 +1771,7 @@ CPed::ProcessControl(void)
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) {
@@ -11565,11 +2328,7 @@ CPed::ProcessControl(void)
ApplyMoveForce(forceDir);
}
- if ((bIsInTheAir && !DyingOrDead())
-#ifdef VC_PED_PORTS
- || (!bIsStanding && !bWasStanding && m_nPedState == PED_FALL)
-#endif
- ) {
+ if ((bIsInTheAir && !DyingOrDead()) || (!bIsStanding && !bWasStanding && m_nPedState == PED_FALL)) {
if (m_nPedStateTimer > 0 && m_nPedStateTimer <= 1000) {
forceDir = GetPosition() - m_vecHitLastPos;
} else {
@@ -11590,11 +2349,7 @@ CPed::ProcessControl(void)
if (m_nCollisionRecords == 1 && m_aCollisionRecords[0] != nil && m_aCollisionRecords[0]->IsBuilding()
&& m_nPedStateTimer > 50.0f / (2.0f * adjustedTs) && m_nPedStateTimer * 1.0f / 250.0f > Abs(forceDir.z)) {
offsetToCheck.x = -forceDir.y;
-#ifdef VC_PED_PORTS
offsetToCheck.z = 1.0f;
-#else
- offsetToCheck.z = 0.0f;
-#endif
offsetToCheck.y = forceDir.x;
offsetToCheck.Normalise();
@@ -11619,7 +2374,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)) {
@@ -11636,7 +2390,6 @@ CPed::ProcessControl(void)
SetLanding();
bIsStanding = true;
}
-#endif
if (obstacleForFlyingZ < obstacleForFlyingOtherDirZ) {
offsetToCheck *= -1.0f;
}
@@ -11657,12 +2410,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)
@@ -11679,7 +2426,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()) {
@@ -11735,17 +2481,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 (!bHeadStuckInCollision || FEET_OFFSET + foundCol.point.z < GetPosition().z) {
GetMatrix().GetPosition().z = FEET_OFFSET + foundCol.point.z;
GetMatrix().UpdateRW();
if (bHeadStuckInCollision)
bHeadStuckInCollision = false;
}
-#else
- GetMatrix().GetPosition().z = FEET_OFFSET + foundCol.point.z;
- GetMatrix().UpdateRW();
-#endif
SetLanding();
bIsStanding = true;
}
@@ -11847,6 +2588,48 @@ CPed::ProcessControl(void)
if (m_nWaitState != WAITSTATE_FALSE)
Wait();
+#ifdef CANCELLABLE_CAR_ENTER
+ static bool cancelJack = false;
+ if (IsPlayer()) {
+ if (EnteringCar() && m_pVehicleAnim) {
+ CPad *pad = CPad::GetPad(0);
+
+ if (!pad->ArePlayerControlsDisabled()) {
+ int vehAnim = m_pVehicleAnim->animId;
+
+ int16 padWalkX = pad->GetPedWalkLeftRight();
+ int16 padWalkY = pad->GetPedWalkUpDown();
+ if (Abs(padWalkX) > 0.0f || Abs(padWalkY) > 0.0f) {
+ if (vehAnim == ANIM_CAR_OPEN_LHS || vehAnim == ANIM_CAR_OPEN_RHS || vehAnim == ANIM_COACH_OPEN_L || vehAnim == ANIM_COACH_OPEN_R ||
+ vehAnim == ANIM_VAN_OPEN_L || vehAnim == ANIM_VAN_OPEN) {
+
+ if (!m_pMyVehicle->pDriver) {
+ cancelJack = false;
+ bCancelEnteringCar = true;
+ } else
+ cancelJack = true;
+ } else if (vehAnim == ANIM_CAR_QJACK && m_pVehicleAnim->GetTimeLeft() > 0.75f) {
+ cancelJack = true;
+ } else if (vehAnim == ANIM_CAR_PULLOUT_LHS || vehAnim == ANIM_CAR_PULLOUT_LOW_LHS || vehAnim == ANIM_CAR_PULLOUT_LOW_RHS || vehAnim == ANIM_CAR_PULLOUT_RHS) {
+ bCancelEnteringCar = true;
+ cancelJack = false;
+ }
+ }
+ if (cancelJack && vehAnim == ANIM_CAR_QJACK && m_pVehicleAnim->GetTimeLeft() > 0.75f && m_pVehicleAnim->GetTimeLeft() < 0.78f) {
+ cancelJack = false;
+ QuitEnteringCar();
+ RestorePreviousObjective();
+ }
+ if (cancelJack && (vehAnim == ANIM_CAR_PULLOUT_LHS || vehAnim == ANIM_CAR_PULLOUT_LOW_LHS || vehAnim == ANIM_CAR_PULLOUT_LOW_RHS || vehAnim == ANIM_CAR_PULLOUT_RHS)) {
+ cancelJack = false;
+ bCancelEnteringCar = true;
+ }
+ }
+ } else
+ cancelJack = false;
+ }
+#endif
+
switch (m_nPedState) {
case PED_IDLE:
Idle();
@@ -11865,83 +2648,9 @@ CPed::ProcessControl(void)
case PED_WANDER_PATH:
WanderPath();
break;
- case PED_SEEK_POS:
- case PED_SEEK_ENTITY:
- case PED_PURSUE:
- case PED_SNIPER_MODE:
- case PED_ROCKET_MODE:
- case PED_DUMMY:
- case PED_FACE_PHONE:
- case PED_MAKE_CALL:
- case PED_MUG:
- case PED_AI_CONTROL:
- case PED_FOLLOW_ROUTE:
- case PED_CPR:
- case PED_SOLICIT:
- case PED_STEP_AWAY:
- case PED_SUN_BATHE:
- case PED_FLASH:
- case PED_JOG:
- case PED_UNKNOWN:
- case PED_STATES_NO_AI:
- case PED_ABSEIL:
- case PED_SIT:
- case PED_JUMP:
- case PED_STAGGER:
- case PED_DIVE_AWAY:
- case PED_STATES_NO_ST:
- case PED_ARREST_PLAYER:
- case PED_PASSENGER:
- case PED_TAXI_PASSENGER:
- case PED_OPEN_DOOR:
- case PED_DEAD:
- case PED_DRAG_FROM_CAR:
- case PED_STEAL_CAR:
- case PED_EXIT_CAR:
- break;
case PED_ENTER_CAR:
case PED_CARJACK:
{
-#ifdef CANCELLABLE_CAR_ENTER
- if (!IsPlayer() || !m_pVehicleAnim)
- break;
-
- CPad *pad = CPad::GetPad(0);
-
- if (pad->ArePlayerControlsDisabled())
- break;
-
- int vehAnim = m_pVehicleAnim->animId;
-
- static bool cancelJack = false;
- int16 padWalkX = pad->GetPedWalkLeftRight();
- int16 padWalkY = pad->GetPedWalkUpDown();
- if (Abs(padWalkX) > 0.0f || Abs(padWalkY) > 0.0f) {
- if (vehAnim == ANIM_CAR_OPEN_LHS || vehAnim == ANIM_CAR_OPEN_RHS || vehAnim == ANIM_COACH_OPEN_L || vehAnim == ANIM_COACH_OPEN_R ||
- vehAnim == ANIM_VAN_OPEN_L || vehAnim == ANIM_VAN_OPEN) {
-
- if (!m_pMyVehicle->pDriver) {
- cancelJack = false;
- bCancelEnteringCar = true;
- } else
- cancelJack = true;
- } else if (vehAnim == ANIM_CAR_QJACK && m_pVehicleAnim->GetTimeLeft() > 0.75f) {
- cancelJack = true;
- } else if (vehAnim == ANIM_CAR_PULLOUT_LHS || vehAnim == ANIM_CAR_PULLOUT_LOW_LHS || vehAnim == ANIM_CAR_PULLOUT_LOW_RHS || vehAnim == ANIM_CAR_PULLOUT_RHS) {
- bCancelEnteringCar = true;
- cancelJack = false;
- }
- }
- if (cancelJack && vehAnim == ANIM_CAR_QJACK && m_pVehicleAnim->GetTimeLeft() > 0.75f && m_pVehicleAnim->GetTimeLeft() < 0.78f) {
- cancelJack = false;
- QuitEnteringCar();
- RestorePreviousObjective();
- }
- if (cancelJack && (vehAnim == ANIM_CAR_PULLOUT_LHS || vehAnim == ANIM_CAR_PULLOUT_LOW_LHS || vehAnim == ANIM_CAR_PULLOUT_LOW_RHS || vehAnim == ANIM_CAR_PULLOUT_RHS)) {
- cancelJack = false;
- bCancelEnteringCar = true;
- }
-#endif
break;
}
case PED_FLEE_POS:
@@ -11962,19 +2671,19 @@ CPed::ProcessControl(void)
Flee();
break;
case PED_FOLLOW_PATH:
- CPed::FollowPath();
+ FollowPath();
break;
case PED_PAUSE:
- CPed::Pause();
+ Pause();
break;
case PED_ATTACK:
- CPed::Attack();
+ Attack();
break;
case PED_FIGHT:
- CPed::Fight();
+ Fight();
break;
case PED_CHAT:
- CPed::Chat();
+ Chat();
break;
case PED_AIM_GUN:
if (m_pPointGunAt && m_pPointGunAt->IsPed()
@@ -12170,3547 +2879,526 @@ CPed::ProcessControl(void)
}
// --MIAMI: Done
-void
-CPed::SetInTheAir(void)
-{
- if (bIsInTheAir)
- return;
-
- bIsInTheAir = true;
- CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_FALL_GLIDE, 4.0f);
-
- if (m_nPedState == PED_ATTACK) {
- ClearAttack();
- ClearPointGunAt();
- } else if (m_nPedState == PED_FIGHT) {
- EndFight(ENDFIGHT_FAST);
- }
-
-}
-
-// --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::PointGunAt(void)
-{
- CWeaponInfo *weaponInfo = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType);
- 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 > 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
- m_pedIK.m_flags &= ~CPedIK::AIMS_WITH_ARM;
- }
-}
-
-// --MIAMI: Done
-void
-CPed::PedAnimDoorCloseCB(CAnimBlendAssociation *animAssoc, void *arg)
-{
- CPed *ped = (CPed*)arg;
-
- CAutomobile *veh = (CAutomobile*)(ped->m_pMyVehicle);
-
- if (!ped->IsNotInWreckedVehicle() || ped->DyingOrDead())
- return;
-
- if (ped->EnteringCar()) {
- bool isLow = !!veh->bLowVehicle;
-
- if (!veh->bIsBus)
- veh->ProcessOpenDoor(ped->m_vehEnterType, ANIM_CAR_CLOSEDOOR_LHS, 1.0f);
-
- eDoors door;
- switch (ped->m_vehEnterType) {
- case CAR_DOOR_RF: door = DOOR_FRONT_RIGHT; break;
- case CAR_DOOR_RR: door = DOOR_REAR_RIGHT; break;
- case CAR_DOOR_LF: door = DOOR_FRONT_LEFT; break;
- case CAR_DOOR_LR: door = DOOR_REAR_LEFT; break;
- default: assert(0);
- }
-
- 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 || 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
- && veh->pDriver->m_objective != OBJECTIVE_LEAVE_CAR_AND_DIE
- || !veh->IsRoomForPedToLeaveCar(CAR_DOOR_LF, nil))))) {
-
- 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;
- PedSetInCarCB(nil, ped);
-
- ped->SetObjective(OBJECTIVE_LEAVE_CAR, veh);
- if (!ped->IsPlayer())
- ped->bFleeAfterExitingCar = true;
-
- ped->bUsePedNodeSeek = true;
- ped->m_pNextPathNode = nil;
-
- } else {
- if (animAssoc)
- animAssoc->blendDelta = -1000.0f;
-
- if (isLow)
- ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_LSHUFFLE_RHS);
- else
- ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_SHUFFLE_RHS);
-
- ped->m_pVehicleAnim->SetFinishCallback(PedSetInCarCB, ped);
- }
- } else if (ped->m_nPedState != PED_DRIVING) {
- ped->QuitEnteringCar();
- }
-}
-
-// --MIAMI: Done
-void
-CPed::PedAnimDoorCloseRollingCB(CAnimBlendAssociation* animAssoc, void* arg)
-{
- CPed* ped = (CPed*)arg;
-
- CAutomobile* veh = (CAutomobile*)(ped->m_pMyVehicle);
-
- if (animAssoc)
- animAssoc->blendDelta = -1000.0f;
-
- if (veh->bLowVehicle) {
- veh->ProcessOpenDoor(CAR_DOOR_LF, ANIM_CAR_ROLLDOOR_LOW, 1.0f);
- } else {
- veh->ProcessOpenDoor(CAR_DOOR_LF, ANIM_CAR_ROLLDOOR, 1.0f);
- }
-
- veh->m_nGettingOutFlags &= ~CAR_DOOR_FLAG_LF;
-
- if (veh->Damage.GetDoorStatus(DOOR_FRONT_LEFT) == DOOR_STATUS_SWINGING)
- veh->Damage.SetDoorStatus(DOOR_FRONT_LEFT, DOOR_STATUS_OK);
-}
-
-// --MIAMI: Done
-void
-CPed::PedAnimDoorOpenCB(CAnimBlendAssociation* animAssoc, void* arg)
+int32
+CPed::ProcessEntityCollision(CEntity *collidingEnt, CColPoint *collidingPoints)
{
- CPed* ped = (CPed*)arg;
-
- CVehicle* veh = ped->m_pMyVehicle;
-
- if (animAssoc)
- animAssoc->blendDelta = -1000.0f;
-
- if (!ped->IsNotInWreckedVehicle())
- return;
-
- if (!ped->EnteringCar()) {
- if(ped->m_nPedState != PED_DRIVING)
- ped->QuitEnteringCar();
-
- return;
- }
-
- eDoors door;
- CPed *pedInSeat = nil;
- switch (ped->m_vehEnterType) {
- 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);
- }
-
- if (ped->m_fHealth == 0.0f || CPad::GetPad(0)->ArePlayerControlsDisabled() && pedInSeat && pedInSeat->IsPlayer()) {
- ped->QuitEnteringCar();
- return;
- }
-
- bool isVan = veh->bIsVan;
- bool isBus = veh->bIsBus;
- bool isLow = veh->bLowVehicle;
- bool vehUpsideDown = veh->IsUpsideDown();
- if (ped->bCancelEnteringCar) {
- if (ped->IsPlayer()) {
- if (veh->pDriver) {
- if (veh->pDriver->m_nPedType == PEDTYPE_COP) {
- FindPlayerPed()->SetWantedLevelNoDrop(1);
- }
- }
- }
-#ifdef CANCELLABLE_CAR_ENTER
- if (!veh->IsDoorMissing(door) && veh->CanPedOpenLocks(ped) && veh->IsCar()) {
- ((CAutomobile*)veh)->Damage.SetDoorStatus(door, DOOR_STATUS_SWINGING);
- }
-#endif
- ped->QuitEnteringCar();
- ped->RestorePreviousObjective();
- ped->bCancelEnteringCar = false;
- return;
- }
- if (!veh->IsDoorMissing(door) && veh->IsCar()) {
- ((CAutomobile*)veh)->Damage.SetDoorStatus(door, DOOR_STATUS_SWINGING);
- }
+ bool collidedWithBoat = false;
+ bool belowTorsoCollided = false;
+ float gravityEffect = -0.15f * CTimer::GetTimeStep();
+ CColPoint intersectionPoint;
+ CColLine ourLine;
- 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);
- else
- ped->SetFall(1000, ANIM_KO_SPIN_L, false);
-
- return;
- }
- veh->ProcessOpenDoor(ped->m_vehEnterType, ANIM_CAR_OPEN_LHS, 1.0f);
+ CColModel *ourCol = CModelInfo::GetModelInfo(GetModelIndex())->GetColModel();
+ CColModel *hisCol = CModelInfo::GetModelInfo(collidingEnt->GetModelIndex())->GetColModel();
- if (ped->m_vehEnterType == CAR_DOOR_LF || ped->m_vehEnterType == CAR_DOOR_RF)
- isVan = false;
+ if (!bUsesCollision && !bJustCheckCollision)
+ return false;
- if (ped->m_nPedState != PED_CARJACK || isBus) {
+ if (collidingEnt->IsVehicle() && ((CVehicle*)collidingEnt)->IsBoat())
+ collidedWithBoat = true;
- 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) {
- ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_COACH, ANIM_COACH_IN_L);
- } 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);
+ // ofc we're not vehicle
+ if (!m_bIsVehicleBeingShifted && !bSkipLineCol && !collidingEnt->IsPed()) {
+ if (!bCollisionProcessed) {
+ m_pCurrentPhysSurface = nil;
+ if (bIsStanding) {
+ bIsStanding = false;
+ bWasStanding = true;
}
- } else {
- 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);
+ bCollisionProcessed = true;
+ m_fCollisionSpeed += m_vecMoveSpeed.Magnitude2D() * CTimer::GetTimeStep();
+ bStillOnValidPoly = false;
+ if (IsPlayer() || m_fCollisionSpeed >= 1.0f
+ && (m_fCollisionSpeed >= 2.0f || m_nPedState != PED_WANDER_PATH)) {
+ m_collPoly.valid = false;
+ m_fCollisionSpeed = 0.0f;
+ bHitSteepSlope = false;
} 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->SetFinishCallback(PedAnimGetInCB, ped);
- } else {
- CPed *pedToDragOut = nil;
- switch (ped->m_vehEnterType) {
- case CAR_DOOR_RF: pedToDragOut = veh->pPassengers[0]; break;
- case CAR_DOOR_RR: pedToDragOut = veh->pPassengers[2]; break;
- case CAR_DOOR_LF: pedToDragOut = veh->pDriver; break;
- case CAR_DOOR_LR: pedToDragOut = veh->pPassengers[1]; break;
- default: assert(0);
- }
-
- if (vehUpsideDown) {
- ped->QuitEnteringCar();
- if (ped->m_nPedType == PEDTYPE_COP)
- ((CCopPed*)ped)->SetArrestPlayer(ped->m_pedInObjective);
- }
-
- 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();
- pedToDragOut = nil;
- } else {
- if (isLow)
- ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_PULLOUT_LOW_RHS);
- else
- ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_PULLOUT_RHS);
-
- ped->m_pVehicleAnim->SetFinishCallback(PedAnimPullPedOutCB, ped);
+ CVector pos = GetPosition();
+ float potentialGroundZ = GetPosition().z - FEET_OFFSET;
+ if (bWasStanding) {
+ pos.z += -0.25f;
+ potentialGroundZ += gravityEffect;
}
- } else if (ped->m_nPedType == PEDTYPE_COP) {
- ped->QuitEnteringCar();
- if (ped->m_pedInObjective && ped->m_pedInObjective->m_nPedState == PED_DRIVING) {
- veh->SetStatus(STATUS_PLAYER_DISABLED);
-
- if (ped->m_pedInObjective->IsPlayer()) {
- ((CCopPed*)ped)->SetArrestPlayer(ped->m_pedInObjective);
- } else {
- ped->ClearObjective();
- ped->SetWanderPath(CGeneral::GetRandomNumberInRange(0.f, 8.f));
+ if (CCollision::IsStoredPolyStillValidVerticalLine(pos, potentialGroundZ, intersectionPoint, &m_collPoly)) {
+ bStillOnValidPoly = true;
+ if(!bHeadStuckInCollision || FEET_OFFSET + intersectionPoint.point.z < GetPosition().z) {
+ GetMatrix().GetPosition().z = FEET_OFFSET + intersectionPoint.point.z;
+ if (bHeadStuckInCollision)
+ bHeadStuckInCollision = false;
}
-
- } else if (!veh->IsDoorMissing(DOOR_FRONT_RIGHT)) {
- ((CAutomobile*)veh)->Damage.SetDoorStatus(DOOR_FRONT_RIGHT, DOOR_STATUS_SWINGING);
+ m_vecMoveSpeed.z = 0.0f;
+ bIsStanding = true;
+ } else {
+ m_collPoly.valid = false;
+ m_fCollisionSpeed = 0.0f;
+ bHitSteepSlope = false;
}
- } 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->SetFinishCallback(PedAnimGetInCB, ped);
- }
- } else if (pedToDragOut) {
-
- 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_PULLOUT_LOW_LHS);
- else
- 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) {
- 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 (!bStillOnValidPoly) {
+ CVector potentialCenter = GetPosition();
+ potentialCenter.z = GetPosition().z - 0.52f;
- if (player != pedToDragOut) {
- pedToDragOut->SetBeingDraggedFromCar(veh, ped->m_vehEnterType, false);
- if (pedToDragOut->IsGangMember())
- pedToDragOut->RegisterThreatWithGangPeds(ped);
+ // 0.52f should be a ped's approx. radius
+ float totalRadiusWhenCollided = collidingEnt->GetBoundRadius() + 0.52f - gravityEffect;
+ if (bWasStanding) {
+ if (collidedWithBoat) {
+ potentialCenter.z += 2.0f * gravityEffect;
+ totalRadiusWhenCollided += Abs(gravityEffect);
+ } else {
+ potentialCenter.z += gravityEffect;
+ }
}
- }
- }
- return;
-}
-
-// --MIAMI: Done
-void
-CPed::SetJump(void)
-{
- if (!bInVehicle && m_nPedState != PED_JUMP && !RpAnimBlendClumpGetAssociation(GetClump(), ANIM_JUMP_LAUNCH) &&
- (m_nSurfaceTouched != SURFACE_STEEP_CLIFF || DotProduct(GetForward(), m_vecDamageNormal) >= 0.0f)) {
+ if (sq(totalRadiusWhenCollided) > (potentialCenter - collidingEnt->GetBoundCentre()).MagnitudeSqr()) {
+ ourLine.p0 = GetPosition();
+ ourLine.p1 = GetPosition();
+ ourLine.p1.z = GetPosition().z - FEET_OFFSET;
+ if (bWasStanding) {
+ ourLine.p1.z = ourLine.p1.z + gravityEffect;
+ ourLine.p0.z = ourLine.p0.z + -0.25f;
+ }
+ float minDist = 1.0f;
+ belowTorsoCollided = CCollision::ProcessVerticalLine(ourLine, collidingEnt->GetMatrix(), *hisCol,
+ intersectionPoint, minDist, false, false, &m_collPoly);
- SetStoredState();
- SetPedState(PED_JUMP);
- CAnimBlendAssociation *jumpAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_JUMP_LAUNCH, 8.0f);
- jumpAssoc->SetFinishCallback(FinishLaunchCB, this);
- m_fRotationDest = m_fRotationCur;
- }
-}
+ 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, false, &m_collPoly);
+ }
+ if (belowTorsoCollided) {
+ if (!bIsStanding
+ || FEET_OFFSET + intersectionPoint.point.z > GetPosition().z
+ || collidedWithBoat && 3.12f + intersectionPoint.point.z > GetPosition().z) {
-// --MIAMI: Done
-void
-CPed::RemoveInCarAnims(void)
-{
- CAnimBlendAssociation* assoc;
+ if (!collidingEnt->IsVehicle() && !collidingEnt->IsObject()) {
+ m_pCurSurface = collidingEnt;
+ collidingEnt->RegisterReference((CEntity**)&m_pCurSurface);
+ bTryingToReachDryLand = false;
+ bOnBoat = false;
+ } else {
+ m_pCurrentPhysSurface = (CPhysical*)collidingEnt;
+ collidingEnt->RegisterReference((CEntity**)&m_pCurrentPhysSurface);
+ m_vecOffsetFromPhysSurface = intersectionPoint.point - collidingEnt->GetPosition();
+ m_pCurSurface = collidingEnt;
+ collidingEnt->RegisterReference((CEntity**)&m_pCurSurface);
+ m_collPoly.valid = false;
+ if (collidingEnt->IsVehicle() && ((CVehicle*)collidingEnt)->IsBoat()) {
+ bOnBoat = true;
+ } else {
+ bOnBoat = false;
+ }
+ }
- for (assoc = RpAnimBlendClumpGetFirstAssociation(GetClump(), ASSOC_DRIVING); assoc;
- assoc = RpAnimBlendGetNextAssociation(assoc, ASSOC_DRIVING)) {
- assoc->flags |= ASSOC_DELETEFADEDOUT;
- assoc->blendDelta = -1000.0f;
- }
-}
+ if (!bHeadStuckInCollision || FEET_OFFSET + intersectionPoint.point.z < GetPosition().z) {
+ GetMatrix().GetPosition().z = FEET_OFFSET + intersectionPoint.point.z;
+ if (bHeadStuckInCollision)
+ bHeadStuckInCollision = false;
+ }
+ m_nSurfaceTouched = intersectionPoint.surfaceB;
+ if (m_nSurfaceTouched == SURFACE_STEEP_CLIFF) {
+ bHitSteepSlope = true;
+ m_vecDamageNormal = intersectionPoint.normal;
+ }
+ }
-// --MIAMI: Done
-void
-CPed::PedAnimGetInCB(CAnimBlendAssociation *animAssoc, void *arg)
-{
- CPed *ped = (CPed*) arg;
+ float upperSpeedLimit = 0.33f;
+ float lowerSpeedLimit = -0.25f;
+ float speed = m_vecMoveSpeed.Magnitude2D();
+ if (m_nPedState == PED_IDLE) {
+ upperSpeedLimit *= 2.0f;
+ lowerSpeedLimit *= 1.5f;
+ }
+ CAnimBlendAssociation *fallAnim = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_FALL_FALL);
+ if (!bWasStanding && speed > upperSpeedLimit && (!bPushedAlongByCar || m_vecMoveSpeed.z < lowerSpeedLimit)
+ && m_pCollidingEntity != collidingEnt) {
- CVehicle *veh = ped->m_pMyVehicle;
- if (animAssoc)
- animAssoc->blendDelta = -1000.0f;
+ float damage = 100.0f * Max(speed - 0.25f, 0.0f);
+ float damage2 = damage;
+ if (m_vecMoveSpeed.z < -0.25f)
+ damage += (-0.25f - m_vecMoveSpeed.z) * 150.0f;
- if (!ped->IsNotInWreckedVehicle() || ped->DyingOrDead())
- return;
+ 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);
+ }
+ if (CSurfaceTable::IsSoftLanding(intersectionPoint.surfaceB))
+ damage *= 0.5f;
- if (!ped->EnteringCar()) {
- if(ped->m_nPedState != PED_DRIVING)
- ped->QuitEnteringCar();
- return;
- }
+ InflictDamage(collidingEnt, WEAPONTYPE_FALL, damage, PEDPIECE_TORSO, dir);
+ if (IsPlayer() && damage2 > 5.0f)
+ Say(SOUND_PED_LAND);
- ped->RemoveWeaponWhenEnteringVehicle();
- if (ped->IsPlayer() && ped->bGonnaKillTheCarJacker && ((CPlayerPed*)ped)->m_pArrestingCop) {
- PedSetInCarCB(nil, ped);
- ped->m_nLastPedState = ped->m_nPedState;
- ped->SetPedState(PED_ARRESTED);
- ped->bGonnaKillTheCarJacker = false;
- if (veh) {
- veh->m_nNumGettingIn = 0;
- veh->m_nGettingInFlags = 0;
- veh->bIsHandbrakeOn = true;
- veh->SetStatus(STATUS_PLAYER_DISABLED);
+ } else if (!bWasStanding && fallAnim && -0.016f * CTimer::GetTimeStep() > m_vecMoveSpeed.z) {
+ InflictDamage(collidingEnt, WEAPONTYPE_FALL, 15.0f, PEDPIECE_TORSO, 2);
+ }
+ m_vecMoveSpeed.z = 0.0f;
+ bIsStanding = true;
+ } else {
+ bOnBoat = false;
+ }
+ }
}
- return;
}
- if (ped->IsPlayer() && ped->m_vehEnterType == CAR_DOOR_LF
- && (Pads[0].GetAccelerate() >= 255.0f || Pads[0].GetBrake() >= 255.0f)
- && 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;
- eDoors enterDoor;
- switch (ped->m_vehEnterType) {
- case CAR_DOOR_RF:
- isVan = false;
- enterDoor = DOOR_FRONT_RIGHT;
- break;
- case CAR_DOOR_RR:
- enterDoor = DOOR_REAR_RIGHT;
- break;
- case CAR_DOOR_LF:
- isVan = false;
- enterDoor = DOOR_FRONT_LEFT;
- break;
- case CAR_DOOR_LR:
- enterDoor = DOOR_REAR_LEFT;
- break;
- default:
- break;
- }
- 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);
- }
+ int ourCollidedSpheres = CCollision::ProcessColModels(GetMatrix(), *ourCol, collidingEnt->GetMatrix(), *hisCol, collidingPoints, nil, nil);
+ if (ourCollidedSpheres > 0 || belowTorsoCollided) {
+ AddCollisionRecord(collidingEnt);
+ if (!collidingEnt->IsBuilding())
+ ((CPhysical*)collidingEnt)->AddCollisionRecord(this);
- CPed *driver = veh->pDriver;
- if (driver && (ped->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER || ped->m_nPedState == PED_CARJACK)) {
- if (veh->bIsBus) {
- driver->SetObjective(OBJECTIVE_LEAVE_CAR, veh);
- if (driver->IsPlayer()) {
- veh->bIsHandbrakeOn = true;
- veh->SetStatus(STATUS_PLAYER_DISABLED);
- }
- driver->bBusJacked = true;
- veh->bIsBeingCarJacked = false;
- PedSetInCarCB(nil, ped);
- if (ped->m_nPedType == PEDTYPE_COP
- || ped->m_objective == OBJECTIVE_KILL_CHAR_ON_FOOT
- || ped->m_objective == OBJECTIVE_KILL_CHAR_ANY_MEANS) {
- ped->SetObjective(OBJECTIVE_LEAVE_CAR, veh);
- }
- ped->m_leaveCarTimer = CTimer::GetTimeInMilliseconds() + 400;
- return;
+ if (ourCollidedSpheres > 0 && (collidingEnt->IsBuilding() || collidingEnt->GetIsStatic())) {
+ bHasHitWall = true;
}
- if (driver != ped && ped->m_vehEnterType != CAR_DOOR_LF) {
- if (!driver->IsPlayer()) {
- driver->bUsePedNodeSeek = true;
- driver->m_pLastPathNode = nil;
- if (driver->m_pedStats->m_temper <= driver->m_pedStats->m_fear
- || driver->CharCreatedBy == MISSION_CHAR
- || veh->VehicleCreatedBy == MISSION_VEHICLE) {
- driver->bFleeAfterExitingCar = true;
- } else {
- driver->bGonnaKillTheCarJacker = true;
- veh->pDriver->SetObjective(OBJECTIVE_KILL_CHAR_ON_FOOT, ped);
-
- if (veh->pDriver->m_nPedType == PEDTYPE_COP && ped->IsPlayer()) {
- FindPlayerPed()->SetWantedLevelNoDrop(1);
+ }
+ if (collidingEnt->IsBuilding() || collidingEnt->GetIsStatic()) {
+ if (bWasStanding) {
+ CVector sphereNormal;
+ float normalLength;
+ for(int sphere = 0; sphere < ourCollidedSpheres; sphere++) {
+ sphereNormal = collidingPoints[sphere].normal;
+ if (sphereNormal.z >= -1.0f || !IsPlayer()) {
+ normalLength = sphereNormal.Magnitude2D();
+ if (normalLength != 0.0f) {
+ sphereNormal.x = sphereNormal.x / normalLength;
+ sphereNormal.y = sphereNormal.y / normalLength;
}
+ } 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;
+ bHeadStuckInCollision = true;
}
+ sphereNormal.Normalise();
+ collidingPoints[sphere].normal = sphereNormal;
+ if (collidingPoints[sphere].surfaceB == SURFACE_STEEP_CLIFF)
+ bHitSteepSlope = true;
}
- if ((ped->m_nPedType != PEDTYPE_EMERGENCY || veh->pDriver->m_nPedType != PEDTYPE_EMERGENCY)
- && (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);
- veh->pDriver->SetRadioStation();
- 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) || !doorClosed || isBus) {
- PedAnimDoorCloseCB(nil, ped);
- } else {
- if (enterDoor != DOOR_FRONT_LEFT && enterDoor != DOOR_REAR_LEFT) {
- if (isVan) {
- ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_VAN, ANIM_VAN_CLOSE);
- } else if (isLow) {
- ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_CLOSEDOOR_LOW_RHS);
- } else {
- ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_CLOSEDOOR_RHS);
- }
- } else if (isVan) {
- ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_VAN, ANIM_VAN_CLOSE_L);
- } else if (isLow) {
- ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_CLOSEDOOR_LOW_LHS);
- } else {
- ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_CLOSEDOOR_LHS);
}
- ped->m_pVehicleAnim->SetFinishCallback(PedAnimDoorCloseCB, ped);
}
+ return ourCollidedSpheres;
}
-#ifdef GTA_TRAIN
-void
-CPed::SetPedPositionInTrain(void)
-{
- LineUpPedWithTrain();
-}
-#endif
-
// --MIAMI: Done
-void
-CPed::PedAnimPullPedOutCB(CAnimBlendAssociation* animAssoc, void* arg)
+static void
+particleProduceFootSplash(CPed *ped, CVector const &pos, float size, int times)
{
- CPed* ped = (CPed*)arg;
-
- CVehicle* veh = ped->m_pMyVehicle;
- if (animAssoc)
- animAssoc->blendDelta = -1000.0f;
-
- if (ped->EnteringCar()) {
- if (!ped->IsNotInWreckedVehicle())
- return;
-
-#ifdef CANCELLABLE_CAR_ENTER
- if (ped->bCancelEnteringCar) {
- ped->QuitEnteringCar();
- ped->RestorePreviousObjective();
- ped->bCancelEnteringCar = false;
- return;
- }
-#endif
-
- bool isLow = !!veh->bLowVehicle;
-
- int padNo;
- if (ped->IsPlayer()) {
-
- // BUG? This will cause crash if m_nPedType is bigger then 1, there are only 2 pads
- switch (ped->m_nPedType) {
- case PEDTYPE_PLAYER1:
- padNo = 0;
- break;
- case PEDTYPE_PLAYER2:
- padNo = 1;
- break;
- case PEDTYPE_PLAYER3:
- padNo = 2;
- break;
- case PEDTYPE_PLAYER4:
- padNo = 3;
- break;
- }
- CPad *pad = CPad::GetPad(padNo);
-
- if (!pad->ArePlayerControlsDisabled()) {
-
- if (pad->GetTarget()
- || pad->NewState.LeftStickX
- || pad->NewState.LeftStickY
- || pad->NewState.DPadUp
- || pad->NewState.DPadDown
- || pad->NewState.DPadLeft
- || pad->NewState.DPadRight) {
- ped->QuitEnteringCar();
- ped->RestorePreviousObjective();
- return;
- }
- }
- }
+ 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);
- if (ped->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER) {
- 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
- ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_GETIN_LHS);
- } else {
- 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->SetFinishCallback(PedAnimGetInCB, ped);
- } else {
- ped->QuitEnteringCar();
- }
- } else if(ped->m_nPedState != PED_DRIVING) {
- ped->QuitEnteringCar();
+ 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);
}
}
// --MIAMI: Done
-void
-CPed::PedAnimStepOutCarCB(CAnimBlendAssociation* animAssoc, void* arg)
+static void
+particleProduceFootDust(CPed *ped, CVector const &pos, float size, int times)
{
- CPed* ped = (CPed*)arg;
-
- CVehicle* veh = ped->m_pMyVehicle;
- 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;
- }
- CVector posForZ = ped->GetPosition();
- CPedPlacement::FindZCoorForPed(&posForZ);
- if (ped->GetPosition().z - 0.5f > posForZ.z) {
- PedSetOutCarCB(nil, ped);
- return;
- }
-
- veh->m_nStaticFrames = 0;
- veh->m_vecMoveSpeed += CVector(0.001f, 0.001f, 0.001f);
- veh->m_vecTurnSpeed += CVector(0.001f, 0.001f, 0.001f);
- if (!veh->bIsBus)
- veh->ProcessOpenDoor(ped->m_vehEnterType, ANIM_CAR_GETOUT_LHS, 1.0f);
-
- /*
- // Duplicate and only in PC for some reason
- if (!veh) {
- PedSetOutCarCB(nil, ped);
- return;
- }
- */
- eDoors door;
- switch (ped->m_vehEnterType) {
- case CAR_DOOR_RF:
- door = DOOR_FRONT_RIGHT;
- break;
- case CAR_DOOR_RR:
- door = DOOR_REAR_RIGHT;
- break;
- case CAR_DOOR_LF:
- door = DOOR_FRONT_LEFT;
- break;
- case CAR_DOOR_LR:
- door = DOOR_REAR_LEFT;
+ switch (ped->m_nSurfaceTouched)
+ {
+ case SURFACE_TARMAC:
+ 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;
default:
break;
}
- bool closeDoor = !veh->IsDoorMissing(door);
-
- int padNo;
- if (ped->IsPlayer()) {
-
- // BUG? This will cause crash if m_nPedType is bigger then 1, there are only 2 pads
- switch (ped->m_nPedType) {
- case PEDTYPE_PLAYER1:
- padNo = 0;
- break;
- case PEDTYPE_PLAYER2:
- padNo = 1;
- break;
- case PEDTYPE_PLAYER3:
- padNo = 2;
- break;
- case PEDTYPE_PLAYER4:
- padNo = 3;
- break;
- }
- CPad* pad = CPad::GetPad(padNo);
- bool engineIsIntact = veh->IsCar() && ((CAutomobile*)veh)->Damage.GetEngineStatus() >= 225;
- if (!pad->ArePlayerControlsDisabled() && veh->m_nDoorLock != CARLOCK_FORCE_SHUT_DOORS
- && (pad->GetTarget()
- || pad->NewState.LeftStickX
- || pad->NewState.LeftStickY
- || pad->NewState.DPadUp
- || pad->NewState.DPadDown
- || pad->NewState.DPadLeft
- || pad->NewState.DPadRight)
- || veh->bIsBus
- || veh->m_pCarFire
- || engineIsIntact) {
- closeDoor = false;
- }
- }
-
- if (ped->m_objective == OBJECTIVE_LEAVE_CAR_AND_DIE)
- closeDoor = false;
-
- if (!closeDoor) {
- if (!veh->IsDoorMissing(door) && !veh->bIsBus) {
- ((CAutomobile*)veh)->Damage.SetDoorStatus(door, DOOR_STATUS_SWINGING);
- }
- PedSetOutCarCB(nil, ped);
- return;
- }
-
- if (ped->bFleeAfterExitingCar || ped->bGonnaKillTheCarJacker) {
- // POTENTIAL BUG? Why DOOR_FRONT_LEFT instead of door variable? or vice versa?
- if (!veh->IsDoorMissing(door))
- ((CAutomobile*)veh)->Damage.SetDoorStatus(DOOR_FRONT_LEFT, DOOR_STATUS_SWINGING);
- } else {
- switch (door) {
- case DOOR_FRONT_LEFT:
- ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_CLOSE_LHS);
- break;
- case DOOR_FRONT_RIGHT:
- ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_CLOSE_RHS);
- break;
- case DOOR_REAR_LEFT:
- ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_CLOSE_LHS);
- break;
- case DOOR_REAR_RIGHT:
- ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_CLOSE_RHS);
- break;
- default:
- break;
- }
- }
-
- if (ped->m_pVehicleAnim)
- ped->m_pVehicleAnim->SetFinishCallback(PedSetOutCarCB, ped);
- return;
-}
-
-// --MIAMI: Done
-void
-CPed::PedEvadeCB(CAnimBlendAssociation* animAssoc, void* arg)
-{
- CPed* ped = (CPed*)arg;
-
- if (!animAssoc) {
- 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) {
- ped->m_getUpTimer = CTimer::GetTimeInMilliseconds() + 1;
- ped->SetPedState(PED_FALL);
- }
- animAssoc->flags &= ~ASSOC_FADEOUTWHENDONE;
- animAssoc->flags |= ASSOC_DELETEFADEDOUT;
-
- } else if (animAssoc->flags & ASSOC_FADEOUTWHENDONE) {
- ped->ClearLookFlag();
- if (ped->m_nPedState == PED_DIVE_AWAY || ped->m_nPedState == PED_STEP_AWAY)
- ped->RestorePreviousState();
-
- } else if (ped->m_nPedState != PED_ARRESTED) {
- animAssoc->flags |= ASSOC_DELETEFADEDOUT;
- if (animAssoc->blendDelta >= 0.0f)
- animAssoc->blendDelta = -4.0f;
-
- ped->ClearLookFlag();
- if (ped->m_nPedState == PED_DIVE_AWAY || ped->m_nPedState == PED_STEP_AWAY) {
- ped->RestorePreviousState();
- }
- }
}
// --MIAMI: Done
void
-CPed::PedGetupCB(CAnimBlendAssociation* animAssoc, void* arg)
-{
- CPed* ped = (CPed*)arg;
-
- if (ped->m_nPedState == PED_GETUP)
- RpAnimBlendClumpSetBlendDeltas(ped->GetClump(), ASSOC_PARTIAL, -1000.0f);
-
- ped->bFallenDown = false;
- animAssoc->blendDelta = -1000.0f;
- if (ped->m_nPedState == PED_GETUP)
- ped->RestorePreviousState();
-
- 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->bGetUpAnimStarted = false;
-}
-
-// --MIAMI: Done
-void
-CPed::PedLandCB(CAnimBlendAssociation* animAssoc, void* arg)
+CPed::PlayFootSteps(void)
{
- CPed* ped = (CPed*)arg;
-
- animAssoc->blendDelta = -1000.0f;
- ped->bIsLanding = false;
-
- if (ped->m_nPedState == PED_JUMP)
- ped->RestorePreviousState();
-}
+ CAnimBlendAssociation *assoc = RpAnimBlendClumpGetFirstAssociation(GetClump());
+ CAnimBlendAssociation *walkRunAssoc = nil;
+ float walkRunAssocBlend = 0.0f, idleAssocBlend = 0.0f;
+ bool isSkater = m_pedStats == CPedStats::ms_apPedStats[PEDSTAT_SKATER];
-// --MIAMI: Done
-void
-CPed::PedSetDraggedOutCarPositionCB(CAnimBlendAssociation* animAssoc, void* arg)
-{
- CPed *ped = (CPed*)arg;
+ CVector footPosL(0.0f, 0.0f, 0.0f), footPosR(0.0f, 0.0f, 0.0f);
+ bool footPosLok = false, footPosRok = false;
- ped->bUsesCollision = true;
- ped->RestartNonPartialAnims();
+ if (bDoBloodyFootprints) {
+ if (m_bloodyFootprintCountOrDeathTime > 0 && m_bloodyFootprintCountOrDeathTime < 300) {
+ m_bloodyFootprintCountOrDeathTime--;
- 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;
+ if (m_bloodyFootprintCountOrDeathTime == 0)
+ bDoBloodyFootprints = false;
}
- } else {
- draggedOutOffset = vecPedDraggedOutCarAnimOffset;
- }
- if (ped->m_vehEnterType == CAR_DOOR_RF || ped->m_vehEnterType == CAR_DOOR_RR)
- draggedOutOffset.x = -draggedOutOffset.x;
-
- CVector posAfterBeingDragged = Multiply3x3(pedMat, draggedOutOffset);
- posAfterBeingDragged += ped->GetPosition();
- CPedPlacement::FindZCoorForPed(&posAfterBeingDragged);
- ped->m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f);
- ped->SetPosition(posAfterBeingDragged);
-
- if (ped->m_pMyVehicle && !ped->m_pMyVehicle->IsBike() && !ped->m_pMyVehicle->IsRoomForPedToLeaveCar(ped->m_vehEnterType, &vecPedDraggedOutCarAnimOffset)) {
- ped->PositionPedOutOfCollision();
}
- if (!ped->CanSetPedState())
- return;
-
- if (!ped->m_pMyVehicle) {
- ped->SetIdle();
- ped->SetGetUp();
+ if (!bIsStanding)
return;
- }
-
- CPed *driver = ped->m_pMyVehicle->pDriver;
-
- if (ped->IsPlayer()) {
- ped->SetIdle();
-
- } else if (ped->bFleeAfterExitingCar) {
- ped->bFleeAfterExitingCar = false;
- ped->SetFlee(ped->m_pMyVehicle->GetPosition(), 4000);
-
- } else if (ped->bWanderPathAfterExitingCar) {
- ped->SetWanderPath(CGeneral::GetRandomNumberInRange(0.0f, 8.0f));
- ped->bWanderPathAfterExitingCar = false;
-
- } else if (ped->bGonnaKillTheCarJacker) {
- // Kill objective is already set at this point.
-
- ped->bGonnaKillTheCarJacker = false;
- if (!ped->m_pedInObjective || !(CGeneral::GetRandomNumber() & 1)) {
- if (!driver || driver == ped || driver->IsPlayer() && CTheScripts::IsPlayerOnAMission()) {
- ped->SetPedState(PED_NONE);
- ped->m_nLastPedState = PED_NONE;
- ped->SetFlee(ped->m_pMyVehicle->GetPosition(), 4000);
- } else {
- ped->ClearObjective();
- 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 && driver
- && driver->IsPlayer() && !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 && !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);
+ for (; assoc; assoc = RpAnimBlendGetNextAssociation(assoc)) {
+ if (assoc->flags & ASSOC_WALK) {
+ walkRunAssoc = assoc;
+ walkRunAssocBlend += assoc->blendAmount;
+ } else if ((assoc->flags & ASSOC_NOWALK) == 0) {
+ idleAssocBlend += assoc->blendAmount;
}
}
- ped->SetGetUp();
-}
-// --MIAMI: Done
-void
-CPed::PedSetInCarCB(CAnimBlendAssociation *animAssoc, void *arg)
-{
- CPed *ped = (CPed*)arg;
-
- CVehicle *veh = ped->m_pMyVehicle;
+ if (walkRunAssoc && walkRunAssocBlend > 0.5f && idleAssocBlend < 1.0f) {
- // Pointless code
- if (!veh)
- return;
+ float stepStart = 1.f / 15.f;
+ float stepEnd = walkRunAssoc->hierarchy->totalLength / 2.0f + stepStart;
+ float currentTime = walkRunAssoc->currentTime;
- // 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
- && (ped->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER || ped->m_nPedState == PED_CARJACK)) {
+ if (isSkater) {
+ // both are unused
+ static float stepStartSection = 1.0f;
+ static float animSections = 15.f;
- if (!ped->IsPlayer() && (ped->CharCreatedBy != MISSION_CHAR || driver->IsPlayer())) {
- ped->QuitEnteringCar();
- return;
- }
- if (driver->CharCreatedBy == MISSION_CHAR) {
- PedSetOutCarCB(nil, veh->pDriver);
- if (driver->m_pMyVehicle) {
- driver->PositionPedOutOfCollision();
+ float moveStart, soundVolume, skateTime;
+ if (walkRunAssoc->animId == ANIM_WALK) {
+ moveStart = 0.0f;
+ skateTime = 8.f / 15.f;
} else {
- driver->m_pMyVehicle = veh;
- driver->PositionPedOutOfCollision();
- driver->m_pMyVehicle = nil;
- }
- veh->pDriver = nil;
- } else {
- driver->SetDead();
- driver->FlagToDestroyWhenNextProcessed();
- veh->pDriver = nil;
- }
- }
-
- 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;
-
- ped->bInVehicle = true;
- if (ped->m_nPedType == PEDTYPE_PROSTITUTE) {
- if (veh->pDriver) {
- if (veh->pDriver->IsPlayer() && ped->CharCreatedBy == RANDOM_CHAR) {
- CWorld::Players[CWorld::PlayerInFocus].m_nSexFrequency = 1000;
- CWorld::Players[CWorld::PlayerInFocus].m_nNextSexMoneyUpdateTime = CTimer::GetTimeInMilliseconds() + 1000;
- CWorld::Players[CWorld::PlayerInFocus].m_nNextSexFrequencyUpdateTime = CTimer::GetTimeInMilliseconds() + 3000;
- CWorld::Players[CWorld::PlayerInFocus].m_pHooker = (CCivilianPed*)ped;
- }
- }
- }
- if (ped->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER || ped->m_nPedState == PED_CARJACK)
- veh->bIsBeingCarJacked = false;
-
- if (veh->m_nNumGettingIn)
- --veh->m_nNumGettingIn;
-
- if (ped->IsPlayer() && ((CPlayerPed*)ped)->m_bAdrenalineActive)
- ((CPlayerPed*)ped)->ClearAdrenaline();
-
- if (veh->IsBoat()) {
- if (ped->IsPlayer()) {
- CCarCtrl::RegisterVehicleOfInterest(veh);
- 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);
- }
- veh->SetStatus(STATUS_PLAYER);
- AudioManager.PlayerJustGotInCar();
- }
- veh->SetDriver(ped);
- if (!veh->bEngineOn)
- veh->bEngineOn = true;
-
- ped->SetPedState(PED_DRIVING);
- ped->StopNonPartialAnims();
- ped->RemoveWeaponWhenEnteringVehicle();
- return;
- }
-
- if (ped->m_pVehicleAnim)
- ped->m_pVehicleAnim->blendDelta = -1000.0f;
-
- ped->bDoBloodyFootprints = false;
- if (veh->m_nAlarmState == -1)
- veh->m_nAlarmState = 15000;
-
- if (ped->IsPlayer()) {
- 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);
- }
- veh->SetStatus(STATUS_PLAYER);
- }
- AudioManager.PlayerJustGotInCar();
- } else if (ped->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER) {
- 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);
- }
- veh->SetStatus(STATUS_PHYSICS);
- }
-
- 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->bStayInCarOnJack && !passenger->bHeldHostageInCar && (passenger->m_leader != ped || !ped->bIsLeader)) {
- passenger->SetObjective(OBJECTIVE_LEAVE_CAR, veh);
- passenger->m_leaveCarTimer = CTimer::GetTimeInMilliseconds();
+ moveStart = 0.0f;
+ skateTime = 5.f / 15.f;
}
- }
- }
-
- if (ped->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER || ped->m_nPedState == PED_CARJACK) {
- veh->SetDriver(ped);
- if (veh->VehicleCreatedBy == PARKED_VEHICLE) {
- veh->VehicleCreatedBy = RANDOM_VEHICLE;
- ++CCarCtrl::NumRandomCars;
- --CCarCtrl::NumParkedCars;
- }
- if (veh->bIsAmbulanceOnDuty) {
- veh->bIsAmbulanceOnDuty = false;
- --CCarCtrl::NumAmbulancesOnDuty;
- }
- if (veh->bIsFireTruckOnDuty) {
- veh->bIsFireTruckOnDuty = false;
- --CCarCtrl::NumFiretrucksOnDuty;
- }
- if (ped->m_nPedType == PEDTYPE_COP && veh->IsLawEnforcementVehicle())
- veh->ChangeLawEnforcerState(true);
-
- if (!veh->bEngineOn) {
- veh->bEngineOn = true;
- DMAudio.PlayOneShot(ped->m_audioEntityId, SOUND_CAR_ENGINE_START, 1.0f);
- }
- if (ped->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER && ped->CharCreatedBy == RANDOM_CHAR
- && ped != FindPlayerPed() && ped->m_nPedType != PEDTYPE_EMERGENCY) {
-
- CCarCtrl::JoinCarWithRoadSystem(veh);
- veh->AutoPilot.m_nCarMission = MISSION_CRUISE;
- veh->AutoPilot.m_nTempAction = TEMPACT_NONE;
- veh->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_AVOID_CARS;
- veh->AutoPilot.m_nCruiseSpeed = 25;
- }
- 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_SPRINT_TO_AREA || ped->m_prevObjective == OBJECTIVE_KILL_CHAR_ON_FOOT)
- ped->m_prevObjective = OBJECTIVE_NONE;
-
- ped->RestorePreviousObjective();
- }
-
- } 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) {
- case CAR_DOOR_RF:
- veh->AddPassenger(ped, 0);
+ 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 CAR_DOOR_RR:
- veh->AddPassenger(ped, 2);
+ case ADHESIVE_SAND:
+ if (CGeneral::GetRandomNumber() % 64) {
+ m_vecAnimMoveDelta *= 0.2f;
+ } else {
+ SetFall(0, ANIM_KO_SKID_BACK, false);
+ }
+ soundVolume = 0.2f;
break;
- case CAR_DOOR_LR:
- veh->AddPassenger(ped, 1);
+ case ADHESIVE_WET:
+ m_vecAnimMoveDelta *= 0.3f;
+ soundVolume = 0.2f;
break;
default:
- veh->AddPassenger(ped);
- break;
- }
- }
- ped->SetPedState(PED_DRIVING);
- 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();
-
- // VC has conditional OBJECTIVE_LEAVE_CAR here, which runs if it entered the first dead condition.
-
- if(slowDown)
- veh->AutoPilot.m_nCruiseSpeed = 17;
- }
-
- 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);
-
- switch (ped->m_objective) {
- case OBJECTIVE_KILL_CHAR_ON_FOOT:
- case OBJECTIVE_KILL_CHAR_ANY_MEANS:
- case OBJECTIVE_LEAVE_CAR:
- case OBJECTIVE_FOLLOW_CAR_IN_CAR:
- 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);
- }
-
- ped->AddInCarAnims(veh, veh->pDriver == ped);
- if (veh->bIsBus)
- ped->bRenderPedInCar = false;
-
- // FIX: RegisterVehicleOfInterest not just registers the vehicle, but also updates register time. So remove the IsThisVehicleInteresting check.
-#ifndef FIX_BUGS
- if (ped->IsPlayer() && !CCarCtrl::IsThisVehicleInteresting(veh) && veh->VehicleCreatedBy != MISSION_VEHICLE) {
-#else
- if (ped->IsPlayer() && veh->VehicleCreatedBy != MISSION_VEHICLE) {
-#endif
- CCarCtrl::RegisterVehicleOfInterest(veh);
-
- if (!veh->bHasBeenOwnedByPlayer && veh->VehicleCreatedBy != MISSION_VEHICLE)
- CEventList::RegisterEvent(EVENT_STEAL_CAR, EVENT_ENTITY_VEHICLE, veh, ped, 1500);
-
- veh->bHasBeenOwnedByPlayer = true;
- }
- ped->bChangedSeat = true;
-}
-
-// --MIAMI: Done :D
-void
-CPed::PedSetInTrainCB(CAnimBlendAssociation* animAssoc, void* arg)
-{
- CPed *ped = (CPed*)arg;
- CTrain *veh = (CTrain*)ped->m_pMyVehicle;
-
- if (!veh)
- return;
-
- ped->bInVehicle = true;
- ped->SetPedState(PED_DRIVING);
- ped->RestorePreviousObjective();
- ped->SetMoveState(PEDMOVE_STILL);
- veh->AddPassenger(ped);
-}
-
-// --MIAMI: Done
-void
-CPed::PedStaggerCB(CAnimBlendAssociation* animAssoc, void* arg)
-{
- /*
- CPed *ped = (CPed*)arg;
-
- if (ped->m_nPedState == PED_STAGGER)
- // nothing
- */
-}
-
-// --MIAMI: Done
-bool
-CPed::RunToReportCrime(eCrimeType crimeToReport)
-{
- // 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;
-
- CVector pos = GetPosition();
- int phoneId = gPhoneInfo.FindNearestFreePhone(&pos);
-
- if (phoneId == -1)
- return false;
-
- CPhone *phone = &gPhoneInfo.m_aPhones[phoneId];
- if (phone->m_nState != PHONE_STATE_FREE)
- return false;
-
- bRunningToPhone = true;
- SetSeek(phone->m_vecPos, 0.3f);
- SetMoveState(PEDMOVE_RUN);
- m_phoneId = phoneId;
- m_crimeToReportOnPhone = crimeToReport;
- return true;
-}
-
-// --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()) {
- 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->CharCreatedBy == RANDOM_CHAR && nearPed != this && nearPed->m_nPedType == m_nPedType)
- nearPed->m_fearFlags |= CPedType::GetFlag(attackerPed->m_nPedType);
- }
- }
- }
- }
- }
-
- if (attackerPed && attackerPed->IsPlayer() && (attackerPed->m_nPedState == PED_CARJACK || attackerPed->bInVehicle)) {
- if (!attackerPed->m_pMyVehicle || attackerPed->m_pMyVehicle->GetModelIndex() != MI_TOPFUN) {
- int16 lastVehicle;
- CEntity *vehicles[8];
- CWorld::FindObjectsInRange(GetPosition(), 30.0f, true, &lastVehicle, 6, vehicles, false, true, false, false, false);
-
- if (lastVehicle > 8)
- lastVehicle = 8;
-
- for (int j = 0; j < lastVehicle; ++j) {
- CVehicle *nearVeh = (CVehicle*) vehicles[j];
-
- if (nearVeh->VehicleCreatedBy != MISSION_VEHICLE) {
- CPed *nearVehDriver = nearVeh->pDriver;
-
- 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;
- nearVeh->AutoPilot.m_nCarMission = MISSION_RAMPLAYER_FARAWAY;
- nearVeh->SetStatus(STATUS_PHYSICS);
- nearVeh->AutoPilot.m_nTempAction = TEMPACT_NONE;
- nearVeh->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_AVOID_CARS;
- }
- }
- }
- }
- }
- }
-}
-
-// --MIAMI: Done
-void
-CPed::ReactToPointGun(CEntity *entWithGun)
-{
- CPed *pedWithGun = (CPed*)entWithGun;
- int waitTime;
-
- 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 || (m_nPedType == PEDTYPE_GANG7 && pedWithGun == FindPlayerPed()))
- return;
-
- if (m_leader) {
- if (FindPlayerPed() == m_leader)
- return;
-
- ClearLeader();
- }
- if (m_pedStats->m_flags & STAT_GUN_PANIC
- && (m_nPedState != PED_ATTACK || GetWeapon()->IsTypeMelee())
- && m_nPedState != PED_FLEE_ENTITY && m_nPedState != PED_AIM_GUN) {
-
- waitTime = CGeneral::GetRandomNumberInRange(3000, 6000);
- SetWaitState(WAITSTATE_PLAYANIM_HANDSCOWER, &waitTime);
- Say(SOUND_PED_HANDS_COWER);
- m_pLookTarget = pedWithGun;
- m_pLookTarget->RegisterReference((CEntity **) &m_pLookTarget);
- SetMoveState(PEDMOVE_NONE);
-
- } else if (m_nPedType != pedWithGun->m_nPedType) {
- if (IsGangMember() || m_nPedType == PEDTYPE_EMERGENCY || m_nPedType == PEDTYPE_FIREMAN) {
- RegisterThreatWithGangPeds(pedWithGun);
- }
-
- if (m_nPedType == PEDTYPE_COP) {
- if (pedWithGun->IsPlayer()) {
- ((CPlayerPed*)pedWithGun)->m_pWanted->SetWantedLevelNoDrop(2);
- }
- if (bCrouchWhenShooting || bKindaStayInSamePlace) {
- SetDuck(CGeneral::GetRandomNumberInRange(1000, 3000));
- }
-
- } else if (m_nPedType != PEDTYPE_COP
- && (m_nPedState != PED_ATTACK || GetWeapon()->IsTypeMelee())
- && (m_nPedState != PED_FLEE_ENTITY || pedWithGun->IsPlayer() && m_fleeFrom != pedWithGun)
- && m_nPedState != PED_AIM_GUN && m_objective != OBJECTIVE_KILL_CHAR_ON_FOOT) {
-
- waitTime = CGeneral::GetRandomNumberInRange(3000, 6000);
- SetWaitState(WAITSTATE_PLAYANIM_HANDSUP, &waitTime);
- Say(SOUND_PED_HANDS_UP);
- m_pLookTarget = pedWithGun;
- m_pLookTarget->RegisterReference((CEntity **) &m_pLookTarget);
- SetMoveState(PEDMOVE_NONE);
- if (m_nPedState == PED_FLEE_ENTITY) {
- m_fleeFrom = pedWithGun;
- m_fleeFrom->RegisterReference((CEntity **) &m_fleeFrom);
- }
-
- if (FindPlayerPed() == pedWithGun && bRichFromMugging) {
- int money = CGeneral::GetRandomNumberInRange(100, 300);
- 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));
- }
- }
- bRichFromMugging = false;
- }
- }
- }
-}
-
-// --MIAMI: Done
-void
-CPed::PedSetOutCarCB(CAnimBlendAssociation *animAssoc, void *arg)
-{
- CPed *ped = (CPed*)arg;
-
- CVehicle *veh = ped->m_pMyVehicle;
-
- bool startedToRun = false;
- ped->bUsesCollision = true;
- ped->m_actionX = 0.0f;
- ped->m_actionY = 0.0f;
- ped->bVehExitWillBeInstant = false;
- if (veh && veh->IsBoat())
- ped->ApplyMoveSpeed();
-
- if (ped->m_objective == OBJECTIVE_LEAVE_CAR)
- ped->RestorePreviousObjective();
- else if (ped->m_objective == OBJECTIVE_LEAVE_CAR_AND_DIE) {
- ped->m_fHealth = 0.0f;
- ped->SetDie(ANIM_FLOOR_HIT, 4.0f, 0.5f);
- }
-
- ped->bInVehicle = false;
- 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) {
- ped->SetIdle();
- 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;
- if (ped->bFleeAfterExitingCar && veh) {
- ped->bFleeAfterExitingCar = false;
- ped->SetFlee(veh->GetPosition(), 12000);
- ped->bUsePedNodeSeek = true;
- ped->m_pNextPathNode = nil;
- if (CGeneral::GetRandomNumber() & 1 || ped->m_pedStats->m_fear > 70) {
- ped->SetMoveState(PEDMOVE_SPRINT);
- ped->Say(SOUND_PED_FLEE_SPRINT);
- } else {
- ped->SetMoveState(PEDMOVE_RUN);
- ped->Say(SOUND_PED_FLEE_RUN);
- }
- startedToRun = true;
-
- // This is not a good way to do this...
- ped->m_nLastPedState = PED_WANDER_PATH;
-
- } else if (ped->bWanderPathAfterExitingCar) {
- ped->SetWanderPath(CGeneral::GetRandomNumberInRange(0.0f, 8.0f));
- ped->bWanderPathAfterExitingCar = false;
- if (ped->m_nPedType == PEDTYPE_PROSTITUTE)
- ped->SetObjectiveTimer(30000);
- ped->m_nLastPedState = PED_NONE;
-
- } else if (ped->bGonnaKillTheCarJacker) {
-
- // Kill objective is already given at this point.
- ped->bGonnaKillTheCarJacker = false;
- if (ped->m_pedInObjective) {
- if (!(CGeneral::GetRandomNumber() & 1)
- && ped->m_nPedType != PEDTYPE_COP
- && (!ped->m_pedInObjective->IsPlayer() || !CTheScripts::IsPlayerOnAMission())) {
- ped->ClearObjective();
- ped->SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, veh);
- }
- ped->m_leaveCarTimer = CTimer::GetTimeInMilliseconds() + 1500;
+ soundVolume = 1.f;
+ break;
}
- int waitTime = 1500;
- ped->SetWaitState(WAITSTATE_PLAYANIM_COWER, &waitTime);
- ped->SetMoveState(PEDMOVE_RUN);
- startedToRun = true;
- } 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 if (ped->m_nPedState == PED_DRIVING) {
- ped->m_nPedState = PED_IDLE;
- }
-#endif
-
- if (animAssoc)
- animAssoc->blendDelta = -1000.0f;
-
- ped->RestartNonPartialAnims();
- ped->m_pVehicleAnim = nil;
- ped->m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f);
- veh = ped->m_pMyVehicle;
- if (veh) {
- if (ped->m_nPedType == PEDTYPE_PROSTITUTE) {
- if (veh->pDriver) {
- if (veh->pDriver->IsPlayer() && ped->CharCreatedBy == RANDOM_CHAR) {
- CWorld::Players[CWorld::PlayerInFocus].m_nNextSexMoneyUpdateTime = 0;
- CWorld::Players[CWorld::PlayerInFocus].m_nNextSexFrequencyUpdateTime = 0;
- CWorld::Players[CWorld::PlayerInFocus].m_pHooker = nil;
- CWorld::Players[CWorld::PlayerInFocus].m_nMoney -= 100;
- if (CWorld::Players[CWorld::PlayerInFocus].m_nMoney < 0)
- CWorld::Players[CWorld::PlayerInFocus].m_nMoney = 0;
+ 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)));
}
}
- }
- 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);
- if (veh->m_nDoorLock == CARLOCK_LOCKED_INITIALLY)
- 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);
- }
-
- if (veh->bIsBus && !veh->IsUpsideDown() && !veh->IsOnItsSide()) {
- float angleAfterExit;
- if (ped->m_vehEnterType == CAR_DOOR_LF) {
- angleAfterExit = HALFPI + veh->GetForward().Heading();
- } else {
- angleAfterExit = veh->GetForward().Heading() - HALFPI;
- }
- ped->SetHeading(angleAfterExit);
- ped->m_fRotationDest = angleAfterExit;
- ped->m_fRotationCur = angleAfterExit;
- if (!ped->bBusJacked)
- ped->SetMoveState(PEDMOVE_WALK);
- }
- if (CGarages::IsPointWithinAnyGarage(ped->GetPosition()))
- veh->bLightsOn = false;
- }
-
- if (ped->IsPlayer())
- AudioManager.PlayerJustLeftCar();
-
- ped->ReplaceWeaponWhenExitingVehicle();
-
- ped->bOnBoat = false;
- if (ped->bBusJacked) {
- ped->SetFall(1500, ANIM_KO_SKID_BACK, false);
- ped->bBusJacked = false;
- }
- ped->m_nStoredMoveState = PEDMOVE_NONE;
- if (!ped->IsPlayer()) {
- // It's a shame...
-#ifdef FIX_BUGS
- int createdBy = ped->CharCreatedBy;
-#else
- int createdBy = !ped->CharCreatedBy;
-#endif
-
- if (createdBy == MISSION_CHAR && !startedToRun)
- ped->SetMoveState(PEDMOVE_WALK);
- }
- ped->bHeldHostageInCar = false;
-}
-
-// --MIAMI: Done, but enumarate weapon slots
-void
-CPed::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() && 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::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);
- }
-}
-
-#ifdef GTA_TRAIN
-void
-CPed::PedSetOutTrainCB(CAnimBlendAssociation *animAssoc, void *arg)
-{
- CPed *ped = (CPed*)arg;
-
- CVehicle *veh = ped->m_pMyVehicle;
-
- if (ped->m_pVehicleAnim)
- ped->m_pVehicleAnim->blendDelta = -1000.0f;
-
- ped->bUsesCollision = true;
- ped->m_pVehicleAnim = nil;
- ped->bInVehicle = false;
- ped->m_nPedState = PED_IDLE;
- ped->RestorePreviousObjective();
- ped->SetMoveState(PEDMOVE_STILL);
-
- CMatrix pedMat(ped->GetMatrix());
- ped->m_fRotationCur = HALFPI + veh->GetForward().Heading();
- ped->m_fRotationDest = ped->m_fRotationCur;
- CVector posAfterExit = Multiply3x3(pedMat, vecPedTrainDoorAnimOffset);
- posAfterExit += ped->GetPosition();
- CPedPlacement::FindZCoorForPed(&posAfterExit);
- ped->m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f);
- ped->SetPosition(posAfterExit);
- ped->SetHeading(ped->m_fRotationCur);
- veh->RemovePassenger(ped);
-}
-#endif
-
-// --MIAMI: Done
-bool
-CPed::PlacePedOnDryLand(void)
-{
- float waterLevel = 0.0f;
- CEntity *foundEnt = nil;
- CColPoint foundCol;
- float foundColZ;
-
- CWaterLevel::GetWaterLevelNoWaves(GetPosition().x, GetPosition().y, GetPosition().z, &waterLevel);
-
- CVector potentialGround = GetPosition();
- potentialGround.z = waterLevel;
-
- if (!CWorld::TestSphereAgainstWorld(potentialGround, 5.0f, nil, true, false, false, false, false, false))
- return false;
-
- CVector potentialGroundDist = gaTempSphereColPoints[0].point - GetPosition();
- potentialGroundDist.z = 0.0f;
- potentialGroundDist.Normalise();
-
- CVector posToCheck = 0.5f * potentialGroundDist + gaTempSphereColPoints[0].point;
- posToCheck.z = 3.0f + waterLevel;
-
- if (CWorld::ProcessVerticalLine(posToCheck, waterLevel - 1.0f, foundCol, foundEnt, true, true, false, true, false, false, nil)) {
- foundColZ = foundCol.point.z;
- if (foundColZ >= waterLevel) {
- posToCheck.z = 0.8f + foundColZ;
- SetPosition(posToCheck);
- bIsStanding = true;
- bWasStanding = true;
- return true;
- }
- }
-
- posToCheck = 5.0f * potentialGroundDist + GetPosition();
- posToCheck.z = 3.0f + waterLevel;
-
- if (!CWorld::ProcessVerticalLine(posToCheck, waterLevel - 1.0f, foundCol, foundEnt, true, true, false, true, false, false, nil))
- return false;
-
- foundColZ = foundCol.point.z;
- if (foundColZ < waterLevel)
- return false;
-
- posToCheck.z = 0.8f + foundColZ;
- SetPosition(posToCheck);
- bIsStanding = true;
- bWasStanding = true;
- return true;
-}
-
-// --MIAMI: Done
-void
-CPed::PedSetQuickDraggedOutCarPositionCB(CAnimBlendAssociation *animAssoc, void *arg)
-{
- CPed *ped = (CPed*)arg;
-
- CVehicle *veh = ped->m_pMyVehicle;
-
- CVector finalPos;
- CVector draggedOutOffset;
- CVector finalLocalPos;
-
- CMatrix pedMat(ped->GetMatrix());
- ped->bUsesCollision = true;
- ped->RestartNonPartialAnims();
- draggedOutOffset = vecPedQuickDraggedOutCarAnimOffset;
- if (ped->m_vehEnterType == CAR_DOOR_RF || ped->m_vehEnterType == CAR_DOOR_RR)
- draggedOutOffset.x = -draggedOutOffset.x;
-
- finalLocalPos = Multiply3x3(pedMat, draggedOutOffset);
- finalPos = finalLocalPos + ped->GetPosition();
- CPedPlacement::FindZCoorForPed(&finalPos);
- ped->m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f);
- ped->SetPosition(finalPos);
-
- if (veh) {
- ped->m_fRotationDest = veh->GetForward().Heading() - HALFPI;
- ped->m_fRotationCur = ped->m_fRotationDest;
- ped->CalculateNewOrientation();
-
- if (!veh->IsRoomForPedToLeaveCar(ped->m_vehEnterType, &vecPedQuickDraggedOutCarAnimOffset))
- ped->PositionPedOutOfCollision();
- }
+ int stepPart = 0;
+
+ // This section is shortened/optimized for sanity.
- if (!ped->CanSetPedState())
- return;
+ if (currentTime >= stepStart && currentTime - walkRunAssoc->timeStep < stepStart)
+ stepPart = 1;
+ else if (currentTime >= stepEnd && currentTime - walkRunAssoc->timeStep < stepEnd)
+ stepPart = 2;
- ped->SetIdle();
- if (veh) {
- if (ped->bFleeAfterExitingCar) {
- ped->bFleeAfterExitingCar = false;
- ped->SetFlee(veh->GetPosition(), 14000);
+ 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;
+ }
- } else if (ped->bWanderPathAfterExitingCar) {
- ped->SetWanderPath(CGeneral::GetRandomNumberInRange(0.0f, 8.0f));
- ped->bWanderPathAfterExitingCar = false;
+ CVector forward = GetForward();
- } else if (ped->bGonnaKillTheCarJacker) {
- ped->bGonnaKillTheCarJacker = false;
- if (ped->m_pedInObjective && CGeneral::GetRandomNumber() & 1) {
- if (ped->m_objective != OBJECTIVE_KILL_CHAR_ON_FOOT)
- ped->SetObjective(OBJECTIVE_KILL_CHAR_ON_FOOT, ped->m_pedInObjective);
+ adjustedFootPos.z -= 0.1f;
+ adjustedFootPos += 0.2f * forward;
- } else {
- CPed *driver = veh->pDriver;
- if (!driver || driver == ped || driver->IsPlayer() && CTheScripts::IsPlayerOnAMission()) {
- ped->SetFlee(veh->GetPosition(), 14000);
- } else {
- ped->ClearObjective();
- ped->SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, veh);
- }
- ped->bUsePedNodeSeek = true;
- ped->m_pNextPathNode = nil;
- ped->Say(SOUND_PED_FLEE_RUN);
- }
- } else {
- if (ped->m_pedStats->m_temper > ped->m_pedStats->m_fear
- && ped->CharCreatedBy != MISSION_CHAR && veh->VehicleCreatedBy != MISSION_VEHICLE
- && veh->pDriver && veh->pDriver->IsPlayer()
- && !CTheScripts::IsPlayerOnAMission()) {
- ped->SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, veh);
+ if (bDoBloodyFootprints) {
+ CVector2D top(forward * 0.26f);
+ CVector2D right(GetRight() * (stepPart == 1 ? 0.14f : 0.1f));
- } else {
- if (ped->m_pedStats->m_temper > ped->m_pedStats->m_fear && ped->CharCreatedBy != MISSION_CHAR
- && ped->m_pMyVehicle->VehicleCreatedBy != MISSION_VEHICLE && !veh->pDriver
- && FindPlayerPed()->m_carInObjective == ped->m_pMyVehicle && !CTheScripts::IsPlayerOnAMission())
- ped->SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, veh);
+ CShadows::AddPermanentShadow(SHADOWTYPE_DARK, gpBloodPoolTex, &adjustedFootPos,
+ top.x, top.y,
+ right.x, right.y,
+ 255, 255, 0, 0, 4.0f, 3000, 1.0f);
- else {
- ped->SetFindPathAndFlee(veh->GetPosition(), 10000);
- if (CGeneral::GetRandomNumber() & 1 || ped->m_pedStats->m_fear > 70) {
- ped->SetMoveState(PEDMOVE_SPRINT);
- ped->Say(SOUND_PED_FLEE_SPRINT);
+ if (m_bloodyFootprintCountOrDeathTime <= 20) {
+ m_bloodyFootprintCountOrDeathTime = 0;
+ bDoBloodyFootprints = false;
} else {
- ped->Say(SOUND_PED_FLEE_RUN);
+ m_bloodyFootprintCountOrDeathTime -= 20;
}
}
- }
- }
- }
- if (ped->m_nLastPedState == PED_IDLE)
- ped->m_nLastPedState = PED_WANDER_PATH;
-}
-
-// --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;
- }
- }
+ if (m_nSurfaceTouched == SURFACE_SAND || m_nSurfaceTouched == SURFACE_SAND_BEACH) {
+ CVector2D top(forward * -0.26f);
+ CVector2D right(GetRight() * (stepPart == 1 ? 0.1f : 0.14f));
- 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;
+ CShadows::AddPermanentShadow(SHADOWTYPE_DARK, gpShadowPedTex, &adjustedFootPos,
+ top.x, top.y,
+ right.x, right.y,
+ 120, 250, 250, 50, 4.0f, 5000, 1.0f);
}
- }
- }
- }
- 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;
-}
+ if (CWeather::Rain <= 0.1f || CCullZones::CamNoRain() || CCullZones::PlayerNoRain()) {
+ if (IsPlayer())
+ particleProduceFootDust(this, adjustedFootPos, 0.0f, 4);
-// --MIAMI: Done
-// "Any" means he shouldn't have to be in vehicle.
-bool
-CPed::PositionAnyPedOutOfCollision(void)
-{
- CVehicle *veh;
- CVector posNearVeh;
- CVector posSomewhereClose;
- bool putNearVeh = false;
- bool putSomewhereClose = false;
- int smallestDistNearVeh = 999;
- int smallestDistSomewhereClose = 999;
-
- CVector vehPos = m_pMyVehicle->GetPosition();
- CVector potentialPos;
- potentialPos.y = GetPosition().y - 3.5f;
- potentialPos.z = GetPosition().z;
-
- for (int yTry = 0; yTry < 15; yTry++) {
- potentialPos.x = GetPosition().x - 3.5f;
-
- for (int xTry = 0; xTry < 15; xTry++) {
- CPedPlacement::FindZCoorForPed(&potentialPos);
- 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) {
- if (potentialChangeSqr < smallestDistNearVeh) {
- posNearVeh = potentialPos;
- putNearVeh = true;
- smallestDistNearVeh = potentialChangeSqr;
- }
- } else if (potentialChangeSqr < smallestDistSomewhereClose) {
- smallestDistSomewhereClose = potentialChangeSqr;
- posSomewhereClose = potentialPos;
- putSomewhereClose = true;
+ } else if (stepPart == 2) {
+ particleProduceFootSplash(this, adjustedFootPos, 0.15f, 4);
}
}
- potentialPos.x += 0.5f;
}
- potentialPos.y += 0.5f;
- }
-
- if (!putSomewhereClose && !putNearVeh)
- return false;
-
- // We refrain from using posNearVeh, probably because of it may be top of the vehicle.
- if (putSomewhereClose) {
- SetPosition(posSomewhereClose);
- } else {
- CVector vehSize = veh->GetModelInfo()->GetColModel()->boundingBox.max;
- posNearVeh.z += vehSize.z;
- SetPosition(posNearVeh);
}
- return true;
-}
-
-// --MIAMI: Done
-bool
-CPed::PossiblyFindBetterPosToSeekCar(CVector *pos, CVehicle *veh)
-{
- bool foundIt = false;
-
- CVector helperPos = GetPosition();
- helperPos.z = pos->z - 0.5f;
-
- CVector foundPos = *pos;
- foundPos.z -= 0.5f;
-
- // If there is another car between target car and us.
- if (CWorld::TestSphereAgainstWorld((foundPos + helperPos) / 2.0f, 0.25f, veh, false, true, false, false, false, false)) {
-
- CColModel *vehCol = veh->GetModelInfo()->GetColModel();
- CVector *colMin = &vehCol->boundingBox.min;
- CVector *colMax = &vehCol->boundingBox.max;
-
- CVector leftRearPos = CVector(colMin->x - 0.5f, colMin->y - 0.5f, 0.0f);
- CVector rightRearPos = CVector(0.5f + colMax->x, colMin->y - 0.5f, 0.0f);
- CVector leftFrontPos = CVector(colMin->x - 0.5f, 0.5f + colMax->y, 0.0f);
- CVector rightFrontPos = CVector(0.5f + colMax->x, 0.5f + colMax->y, 0.0f);
-
- leftRearPos = veh->GetMatrix() * leftRearPos;
- rightRearPos = veh->GetMatrix() * rightRearPos;
- leftFrontPos = veh->GetMatrix() * leftFrontPos;
- rightFrontPos = veh->GetMatrix() * rightFrontPos;
-
- // Makes helperPos veh-ped distance vector.
- helperPos -= veh->GetPosition();
- // ?!? I think it's absurd to use this unless another function like SeekCar finds next pos. with it and we're trying to simulate it's behaviour.
- // On every run it returns another pos. for ped, with same distance to the veh.
- // Sequence of positions are not guaranteed, it depends on global pos. (So sometimes it returns positions to make ped draw circle, sometimes don't)
- helperPos = veh->GetMatrix() * helperPos;
-
- float vehForwardHeading = veh->GetForward().Heading();
-
- // I'm absolutely not sure about these namings.
- // NTVF = needed turn if we're looking to vehicle front and wanna look to...
-
- float potentialLrHeading = Atan2(leftRearPos.x - helperPos.x, leftRearPos.y - helperPos.y);
- float NTVF_LR = CGeneral::LimitRadianAngle(potentialLrHeading - vehForwardHeading);
-
- float potentialRrHeading = Atan2(rightRearPos.x - helperPos.x, rightRearPos.y - helperPos.y);
- float NTVF_RR = CGeneral::LimitRadianAngle(potentialRrHeading - vehForwardHeading);
-
- float potentialLfHeading = Atan2(leftFrontPos.x - helperPos.x, leftFrontPos.y - helperPos.y);
- float NTVF_LF = CGeneral::LimitRadianAngle(potentialLfHeading - vehForwardHeading);
-
- float potentialRfHeading = Atan2(rightFrontPos.x - helperPos.x, rightFrontPos.y - helperPos.y);
- float NTVF_RF = CGeneral::LimitRadianAngle(potentialRfHeading - vehForwardHeading);
-
- bool canHeadToLr = NTVF_LR <= -PI || NTVF_LR >= -HALFPI;
+ if (IsPlayer() && !walkRunAssoc && bIsLanding) {
+ if (!footPosLok)
+ TransformToNode(footPosL, PED_FOOTL);
- bool canHeadToRr = NTVF_RR <= HALFPI || NTVF_RR >= PI;
+ CVector forward = GetForward();
- bool canHeadToLf = NTVF_LF >= 0.0f || NTVF_LF <= -HALFPI;
+ CVector adjustedFootPosL = footPosL;
+ adjustedFootPosL.z -= 0.1f;
+ adjustedFootPosL += 0.2f * forward;
+ if (bDoBloodyFootprints) {
+ CVector2D top(forward * 0.26f);
+ CVector2D right(GetRight() * 0.14f);
- bool canHeadToRf = NTVF_RF <= 0.0f || NTVF_RF >= HALFPI;
+ CShadows::AddPermanentShadow(SHADOWTYPE_DARK, gpBloodPoolTex, &adjustedFootPosL,
+ top.x, top.y,
+ right.x, right.y,
+ 255, 255, 0, 0, 4.0f, 3000, 1.0f);
- // Only order of conditions are different among enterTypes.
- if (m_vehEnterType == CAR_DOOR_RR) {
- if (canHeadToRr) {
- foundPos = rightRearPos;
- foundIt = true;
- } else if (canHeadToRf) {
- foundPos = rightFrontPos;
- foundIt = true;
- } else if (canHeadToLr) {
- foundPos = leftRearPos;
- foundIt = true;
- } else if (canHeadToLf) {
- foundPos = leftFrontPos;
- foundIt = true;
- }
- } else if(m_vehEnterType == CAR_DOOR_RF) {
- if (canHeadToRf) {
- foundPos = rightFrontPos;
- foundIt = true;
- } else if (canHeadToRr) {
- foundPos = rightRearPos;
- foundIt = true;
- } else if (canHeadToLf) {
- foundPos = leftFrontPos;
- foundIt = true;
- } else if (canHeadToLr) {
- foundPos = leftRearPos;
- foundIt = true;
- }
- } else if (m_vehEnterType == CAR_DOOR_LF) {
- if (canHeadToLf) {
- foundPos = leftFrontPos;
- foundIt = true;
- } else if (canHeadToLr) {
- foundPos = leftRearPos;
- foundIt = true;
- } else if (canHeadToRf) {
- foundPos = rightFrontPos;
- foundIt = true;
- } else if (canHeadToRr) {
- foundPos = rightRearPos;
- foundIt = true;
+ if (m_bloodyFootprintCountOrDeathTime <= 20) {
+ m_bloodyFootprintCountOrDeathTime = 0;
+ bDoBloodyFootprints = false;
}
- } else if (m_vehEnterType == CAR_DOOR_LR) {
- if (canHeadToLr) {
- foundPos = leftRearPos;
- foundIt = true;
- } else if (canHeadToLf) {
- foundPos = leftFrontPos;
- foundIt = true;
- } else if (canHeadToRr) {
- foundPos = rightRearPos;
- foundIt = true;
- } else if (canHeadToRf) {
- foundPos = rightFrontPos;
- foundIt = true;
+ else {
+ m_bloodyFootprintCountOrDeathTime -= 20;
}
}
- }
- if (!foundIt)
- return false;
-
- helperPos = GetPosition() - foundPos;
- helperPos.z = 0.0f;
- if (helperPos.MagnitudeSqr() <= sq(0.5f))
- return false;
-
- pos->x = foundPos.x;
- pos->y = foundPos.y;
- return true;
-}
-
-CVector vecTestTemp(-1.0f, -1.0f, -1.0f);
-
-// --MIAMI: Done
-void
-CPed::Render(void)
-{
- if (bInVehicle && m_pMyVehicle && m_nPedState != PED_EXIT_CAR && m_nPedState != PED_DRAG_FROM_CAR) {
- if (!bRenderPedInCar)
- 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();
-
- if(m_pWeaponModel){
- RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(GetClump());
- int idx = RpHAnimIDGetIndex(hier, m_pFrames[PED_HANDR]->nodeID);
- RwMatrix *mat = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
- RwFrame *frame = RpAtomicGetFrame(m_pWeaponModel);
- *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();
+ if (!isSkater) {
+ if (m_nSurfaceTouched == SURFACE_SAND || m_nSurfaceTouched == SURFACE_SAND_BEACH) {
+ CVector2D top(forward * -0.26f);
+ CVector2D right(GetRight() * 0.14f);
- RwFrameUpdateObjects(frame);
- RpAtomicRender(player->m_pMinigunTopAtomic);
+ CShadows::AddPermanentShadow(SHADOWTYPE_DARK, gpShadowPedTex, &adjustedFootPosL,
+ top.x, top.y,
+ right.x, right.y,
+ 120, 250, 250, 50, 4.0f, 5000, 1.0f);
}
}
- }
-}
+ if(!footPosRok)
+ TransformToNode(footPosR, PED_FOOTR);
-// --MIAMI: Done
-void
-CPed::ProcessObjective(void)
-{
- if (bClearObjective && (IsPedInControl() || m_nPedState == PED_DRIVING)) {
- ClearObjective();
- bClearObjective = false;
- }
- UpdateFromLeader();
+ CVector adjustedFootPosR = footPosR;
+ adjustedFootPosR.z -= 0.1f;
+ adjustedFootPosR += 0.2f * forward;
- CVector carOrOurPos;
- CVector targetCarOrHisPos;
- CVector distWithTarget;
+ if (bDoBloodyFootprints) {
+ CVector2D top(forward * 0.26f);
+ CVector2D right(GetRight() * 0.1f);
- if (m_objective != OBJECTIVE_NONE && (IsPedInControl() || m_nPedState == PED_DRIVING)) {
- if (bInVehicle) {
- if (!m_pMyVehicle) {
- bInVehicle = false;
- return;
- }
- carOrOurPos = m_pMyVehicle->GetPosition();
- } else {
- carOrOurPos = GetPosition();
- }
+ 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_pedInObjective) {
- if (m_pedInObjective->InVehicle() && m_pedInObjective->m_nPedState != PED_DRAG_FROM_CAR) {
- targetCarOrHisPos = m_pedInObjective->m_pMyVehicle->GetPosition();
+ if (m_bloodyFootprintCountOrDeathTime <= 20) {
+ m_bloodyFootprintCountOrDeathTime = 0;
+ bDoBloodyFootprints = false;
} else {
- targetCarOrHisPos = m_pedInObjective->GetPosition();
+ m_bloodyFootprintCountOrDeathTime -= 20;
}
- distWithTarget = targetCarOrHisPos - carOrOurPos;
- } else if (m_carInObjective) {
- targetCarOrHisPos = m_carInObjective->GetPosition();
- distWithTarget = targetCarOrHisPos - carOrOurPos;
}
+ if (!isSkater) {
+ if (m_nSurfaceTouched == SURFACE_SAND || m_nSurfaceTouched == SURFACE_SAND_BEACH) {
+ CVector2D top(forward * -0.26f);
+ CVector2D right(GetRight() * 0.14f);
- switch (m_objective) {
- case OBJECTIVE_WAIT_ON_FOOT:
- 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;
- } else if (m_nPedState != PED_FLEE_POS) {
- CVector2D fleePos = GetPosition();
- SetFlee(fleePos, 10000);
- bUsePedNodeSeek = true;
- m_pNextPathNode = nil;
- }
- break;
- case OBJECTIVE_GUARD_SPOT:
- {
- distWithTarget = m_vecSeekPosEx - GetPosition();
- if (m_pedInObjective) {
- SetLookFlag(m_pedInObjective, true);
- m_pLookTarget = m_pedInObjective;
- m_pLookTarget->RegisterReference((CEntity **) &m_pLookTarget);
- TurnBody();
- }
- float distWithTargetSc = distWithTarget.Magnitude();
- if (2.0f * m_distanceToCountSeekDoneEx >= distWithTargetSc) {
- if (m_pedInObjective && m_pedInObjective->m_nPedState != PED_DEAD) {
- if (distWithTargetSc <= m_distanceToCountSeekDoneEx)
- SetIdle();
- else {
- CVector seekPos = m_vecSeekPosEx;
- SetSeek(seekPos, m_distanceToCountSeekDoneEx);
- }
- } else if (CTimer::GetTimeInMilliseconds() > m_lookTimer) {
- int threatType = ScanForThreats();
- SetLookTimer(CGeneral::GetRandomNumberInRange(500, 1500));
-
- // Second condition is pointless and isn't there in Mobile.
- if (threatType == PED_FLAG_GUN || (threatType == PED_FLAG_EXPLOSION && m_threatEntity) || m_threatEntity) {
- if (m_threatEntity->IsPed())
- SetObjective(OBJECTIVE_KILL_CHAR_ON_FOOT, m_threatEntity);
- }
- }
- } else {
- CVector seekPos = m_vecSeekPosEx;
- SetSeek(seekPos, m_distanceToCountSeekDoneEx);
- }
- break;
- }
- case OBJECTIVE_WAIT_IN_CAR:
- SetPedState(PED_DRIVING);
- break;
- case OBJECTIVE_WAIT_IN_CAR_THEN_GET_OUT:
- SetPedState(PED_DRIVING);
- break;
- case OBJECTIVE_KILL_CHAR_ANY_MEANS:
- {
- if (m_pedInObjective) {
- if (m_pedInObjective->IsPlayer() && CharCreatedBy != MISSION_CHAR
- && m_nPedType != PEDTYPE_COP && FindPlayerPed()->m_pWanted->m_CurrentCops != 0
- && !bKindaStayInSamePlace) {
-
- SetObjective(OBJECTIVE_FLEE_ON_FOOT_TILL_SAFE);
- break;
- }
- if (InVehicle()) {
- 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;
- if (m_nPedType == PEDTYPE_COP) {
- m_pMyVehicle->AutoPilot.m_nCruiseSpeed = (FindPlayerPed()->m_pWanted->m_nWantedLevel * 0.1f + 0.6f) * (GAME_SPEED_TO_CARAI_SPEED * m_pMyVehicle->pHandling->Transmission.fUnkMaxVelocity);
- m_pMyVehicle->AutoPilot.m_nCarMission = CCarAI::FindPoliceCarMissionForWantedLevel();
- } else {
- m_pMyVehicle->AutoPilot.m_nCruiseSpeed = GAME_SPEED_TO_CARAI_SPEED * m_pMyVehicle->pHandling->Transmission.fUnkMaxVelocity * 0.8f;
- m_pMyVehicle->AutoPilot.m_nCarMission = MISSION_RAMPLAYER_FARAWAY;
- }
- m_pMyVehicle->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_AVOID_CARS;
- }
- } else {
- bool targetHasVeh = m_pedInObjective->bInVehicle;
- 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);
- }
- }
- break;
- }
- if (distWithTarget.Magnitude() > 30.0f && !bKindaStayInSamePlace) {
- if (m_pMyVehicle) {
- m_pMyVehicle->AutoPilot.m_nCruiseSpeed = 0;
- SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, m_pMyVehicle);
- } else {
- float closestVehDist = 60.0f;
- int16 lastVehicle;
- CEntity* vehicles[8];
- 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];
- /*
- Not used.
- CVector vehSpeed = nearVeh->GetSpeed();
- CVector ourSpeed = GetSpeed();
- */
- CVector vehDistVec = nearVeh->GetPosition() - GetPosition();
- if (vehDistVec.Magnitude() < closestVehDist && m_pedInObjective->m_pMyVehicle != nearVeh
- && nearVeh->CanPedOpenLocks(this) && nearVeh->m_fHealth > 250.f) {
-
- foundVeh = nearVeh;
- closestVehDist = vehDistVec.Magnitude();
- }
- }
- 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);
- } else if (!GetIsOnScreen()) {
- CVector ourPos = GetPosition();
- int closestNode = ThePaths.FindNodeClosestToCoors(ourPos, PATH_CAR, 20.0f);
- if (closestNode >= 0) {
- int16 colliding;
- CWorld::FindObjectsKindaColliding(
- ThePaths.m_pathNodes[closestNode].GetPosition(), 10.0f, true, &colliding, 2, nil, false, true, true, false, false);
- if (!colliding) {
- CZoneInfo zoneInfo;
- int chosenCarClass;
- CTheZones::GetZoneInfoForTimeOfDay(&ourPos, &zoneInfo);
- 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->SetHeading(DEGTORAD(200.0f));
- newVeh->SetStatus(STATUS_ABANDONED);
- newVeh->m_nDoorLock = CARLOCK_UNLOCKED;
- CWorld::Add(newVeh);
- m_pMyVehicle = newVeh;
- if (m_pMyVehicle) {
- m_pMyVehicle->RegisterReference((CEntity **) &m_pMyVehicle);
- m_pMyVehicle->AutoPilot.m_nCruiseSpeed = 0;
- SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, m_pMyVehicle);
- }
- }
- }
- }
- }
- }
- break;
- }
- } else {
- ClearLookFlag();
- bObjectiveCompleted = true;
- }
- }
- case OBJECTIVE_KILL_CHAR_ON_FOOT:
- {
- if (m_objective == OBJECTIVE_KILL_CHAR_ON_FOOT && InVehicle()) {
- SetObjective(OBJECTIVE_LEAVE_CAR, m_pMyVehicle);
- break;
- }
- if (!m_pedInObjective || m_pedInObjective->DyingOrDead()) {
- bObjectiveCompleted = true;
- ClearLookFlag();
- SetMoveAnim();
- break;
- }
- if (m_pedInObjective) {
- int status;
- if (GetWeapon()->IsTypeMelee())
- status = KillCharOnFootMelee(carOrOurPos, targetCarOrHisPos, distWithTarget);
- else
- status = KillCharOnFootArmed(carOrOurPos, targetCarOrHisPos, distWithTarget);
-
- if (status == WATCH_UNTIL_HE_DISAPPEARS)
- return;
- if (status == CANT_ATTACK)
- break;
- }
- SetMoveAnim();
- break;
- }
- case OBJECTIVE_FLEE_CHAR_ON_FOOT_TILL_SAFE:
- case OBJECTIVE_FLEE_CHAR_ON_FOOT_ALWAYS:
- {
- if (InVehicle()) {
- if (m_nPedState == PED_DRIVING)
- SetObjective(OBJECTIVE_LEAVE_CAR, m_pMyVehicle);
- } else if (m_nPedState != PED_FLEE_ENTITY) {
- int time;
- if (m_objective == OBJECTIVE_FLEE_CHAR_ON_FOOT_ALWAYS)
- time = 0;
- else
- 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()) {
- if (distWithTargetSc <= safeDistance) {
- 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();
- }
- if (distWithTargetSc > 2.0f)
- 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) {
- if (m_leader && m_leader->m_nMoveState == PEDMOVE_SPRINT)
- SetMoveState(PEDMOVE_SPRINT);
- else
- SetMoveState(PEDMOVE_RUN);
- } else {
- if (m_leader && m_leader->m_nMoveState != PEDMOVE_STILL
- && m_leader->m_nMoveState != PEDMOVE_NONE) {
- if (m_leader->IsPlayer()) {
- if (distWithTargetSc >= 3.0f && FindPlayerPed()->m_fMoveSpeed >= 1.3f)
- SetMoveState(PEDMOVE_RUN);
- else
- SetMoveState(PEDMOVE_WALK);
- } else {
- SetMoveState(m_leader->m_nMoveState);
- }
- } else if (distWithTargetSc <= 3.0f) {
- SetMoveState(PEDMOVE_WALK);
- } else {
- SetMoveState(PEDMOVE_RUN);
- }
- }
- }
- if (m_objective == OBJECTIVE_GOTO_CHAR_ON_FOOT_WALKING && m_nMoveState > PEDMOVE_STILL)
- SetMoveState(PEDMOVE_WALK);
- }
- } else {
- SetObjective(OBJECTIVE_NONE);
- }
- break;
- }
- case OBJECTIVE_FOLLOW_CHAR_IN_FORMATION:
- {
- if (m_pedInObjective) {
- CVector posToGo = GetFormationPosition();
- distWithTarget = posToGo - carOrOurPos;
- SetSeek(posToGo, 1.0f);
- if (distWithTarget.Magnitude() <= 3.0f) {
- SetSeek(posToGo, 1.0f);
- if (m_pedInObjective && m_pedInObjective->m_nMoveState != PEDMOVE_STILL)
- SetMoveState(m_pedInObjective->m_nMoveState);
- } else {
- SetSeek(posToGo, 1.0f);
- SetMoveState(PEDMOVE_RUN);
- }
- } else {
- SetObjective(OBJECTIVE_NONE);
- }
- break;
- }
- case OBJECTIVE_ENTER_CAR_AS_PASSENGER:
- {
- if (m_carInObjective) {
- if (!bInVehicle && m_carInObjective->m_nNumPassengers >= m_carInObjective->m_nNumMaxPassengers) {
- RestorePreviousObjective();
- RestorePreviousState();
- if (IsPedInControl())
- m_pMyVehicle = nil;
-
- break;
- }
-
- if (m_prevObjective == OBJECTIVE_HAIL_TAXI && !((CAutomobile*)m_carInObjective)->bTaxiLight) {
- RestorePreviousObjective();
- ClearObjective();
- SetWanderPath(CGeneral::GetRandomNumber() & 7);
- bIsRunning = false;
- break;
- }
- if (m_objectiveTimer && m_objectiveTimer < CTimer::GetTimeInMilliseconds()) {
- if (!EnteringCar()) {
- bool 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_LR;
- 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)) {
- m_vehEnterType = CAR_DOOR_RF;
- foundSeat = true;
- }
- }
- if (foundSeat) {
- SetPosition(GetPositionToOpenCarDoor(m_carInObjective, m_vehEnterType));
- SetEnterCar(m_carInObjective, m_vehEnterType);
- }
- }
- m_objectiveTimer = 0;
- }
- }
- // fall through
+ CShadows::AddPermanentShadow(SHADOWTYPE_DARK, gpShadowPedTex, &adjustedFootPosR,
+ top.x, top.y,
+ right.x, right.y,
+ 120, 250, 250, 50, 4.0f, 5000, 1.0f);
}
- case OBJECTIVE_ENTER_CAR_AS_DRIVER:
- {
- if (!m_carInObjective || bInVehicle) {
- if (bInVehicle && m_pMyVehicle != m_carInObjective) {
- SetExitCar(m_pMyVehicle, 0);
- } else {
- bObjectiveCompleted = true;
- bScriptObjectiveCompleted = true;
- RestorePreviousState();
- }
- } else {
- if (m_leaveCarTimer > CTimer::GetTimeInMilliseconds()) {
- SetMoveState(PEDMOVE_STILL);
- break;
- }
- if (IsPedInControl()) {
- if (m_prevObjective == OBJECTIVE_KILL_CHAR_ANY_MEANS) {
- if (distWithTarget.Magnitude() < 20.0f) {
- RestorePreviousObjective();
- RestorePreviousState();
- return;
- }
- if (m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER) {
- 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;
- }
- }
- }
- } else if (m_objective != OBJECTIVE_ENTER_CAR_AS_PASSENGER) {
- if (m_carInObjective->pDriver
- && (CharCreatedBy != MISSION_CHAR || m_carInObjective->pDriver->CharCreatedBy != RANDOM_CHAR)
- ) {
- if (m_carInObjective->pDriver->m_nPedType == m_nPedType) {
- SetObjective(OBJECTIVE_ENTER_CAR_AS_PASSENGER, m_carInObjective);
- m_carInObjective->bIsBeingCarJacked = false;
- }
- }
- }
- if (m_carInObjective->IsUpsideDown() && m_carInObjective->m_vehType != VEHICLE_TYPE_BIKE) {
- RestorePreviousObjective();
- RestorePreviousState();
- return;
- }
- if (!m_carInObjective->IsBoat() || m_nPedState == PED_SEEK_IN_BOAT) {
- if (m_nPedState != PED_SEEK_CAR)
- SetSeekCar(m_carInObjective, 0);
- } else {
- SetSeekBoatPosition(m_carInObjective);
- }
- if (m_nMoveState == PEDMOVE_STILL && !bVehEnterDoorIsBlocked)
- SetMoveState(PEDMOVE_RUN);
+ }
+ }
- if (m_carInObjective && m_carInObjective->m_fHealth > 0.0f) {
- distWithTarget = m_carInObjective->GetPosition() - GetPosition();
- if (!bInVehicle) {
- if (nEnterCarRangeMultiplier * ENTER_CAR_MAX_DIST < distWithTarget.Magnitude()) {
- if (!m_carInObjective->pDriver && !m_carInObjective->GetIsOnScreen() && !GetIsOnScreen())
- WarpPedToNearEntityOffScreen(m_carInObjective);
-
- if (CharCreatedBy != MISSION_CHAR || m_prevObjective == OBJECTIVE_KILL_CHAR_ANY_MEANS
- || IsPlayer() && !CPad::GetPad(0)->ArePlayerControlsDisabled()) {
- RestorePreviousObjective();
- RestorePreviousState();
- if (IsPedInControl())
- m_pMyVehicle = nil;
- } else {
- SetIdle();
- SetMoveState(PEDMOVE_STILL);
- }
- }
- }
- } else if (!bInVehicle) {
- RestorePreviousObjective();
- RestorePreviousState();
- if (IsPedInControl())
- m_pMyVehicle = nil;
- }
- }
- }
- 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) {
- ClearLookFlag();
- bObjectiveCompleted = true;
- break;
- }
- float distWithTargetSc = distWithTarget.Magnitude();
- CWeaponInfo *wepInfo = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType);
- float wepRange = wepInfo->m_fRange;
- m_pLookTarget = m_carInObjective;
- m_pLookTarget->RegisterReference((CEntity **) &m_pLookTarget);
-
- m_pSeekTarget = m_carInObjective;
- m_pSeekTarget->RegisterReference((CEntity**) &m_pSeekTarget);
-
- TurnBody();
- if (m_carInObjective->m_fHealth <= 0.0f) {
- ClearLookFlag();
- bScriptObjectiveCompleted = true;
- break;
- }
+ 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) {
+ float particleSize = pedSpeed * 2.0f;
- 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;
- maxShotPos.Normalise();
- maxShotPos = maxShotPos * wepInfo->m_fRange + ourHead;
-
- CWorld::bIncludeDeadPeds = true;
- CColPoint foundCol;
- CEntity *foundEnt;
- CWorld::ProcessLineOfSight(ourHead, maxShotPos, foundCol, foundEnt,
- true, true, true, true, false, true, false);
- CWorld::bIncludeDeadPeds = false;
- if (foundEnt == m_carInObjective) {
- SetAttack(m_carInObjective);
- if (m_pPointGunAt)
- m_pPointGunAt->CleanUpOldReference((CEntity**)&m_pPointGunAt);
- m_pPointGunAt = m_carInObjective;
- if (m_pPointGunAt)
- m_pPointGunAt->RegisterReference((CEntity **) &m_pPointGunAt);
-
- SetShootTimer(CGeneral::GetRandomNumberInRange(500, 2000));
- if (distWithTargetSc > 10.0f && !bKindaStayInSamePlace) {
- SetAttackTimer(CGeneral::GetRandomNumberInRange(2000, 5000));
- } else {
- SetAttackTimer(CGeneral::GetRandomNumberInRange(50, 300));
- SetMoveState(PEDMOVE_STILL);
- }
- }
- } 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;
+ if (particleSize < 0.25f)
+ particleSize = 0.25f;
- SetSeek(m_carInObjective, safeDistance);
- SetMoveState(PEDMOVE_RUN);
- }
- }
- SetLookFlag(m_carInObjective, false);
- TurnBody();
- break;
- }
- case OBJECTIVE_GOTO_AREA_ON_FOOT:
- case OBJECTIVE_RUN_TO_AREA:
- case OBJECTIVE_SPRINT_TO_AREA:
- {
- if (InVehicle()) {
- SetObjective(OBJECTIVE_LEAVE_CAR, m_pMyVehicle);
- } else {
- distWithTarget = m_nextRoutePointPos - GetPosition();
- distWithTarget.z = 0.0f;
- if (sq(m_distanceToCountSeekDone) >= distWithTarget.MagnitudeSqr()) {
- bObjectiveCompleted = true;
- bScriptObjectiveCompleted = true;
- SetMoveState(PEDMOVE_STILL);
- } else if (CTimer::GetTimeInMilliseconds() > m_nPedStateTimer || m_nPedState != PED_SEEK_POS) {
- if (bUsePedNodeSeek) {
- CVector bestCoords(0.0f, 0.0f, 0.0f);
- m_vecSeekPos = m_nextRoutePointPos;
-
- 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 = CPathFind::TakeWidthIntoAccountForWandering(m_pNextPathNode, m_randomSeed);
- }
- CVector seekPos = m_vecSeekPos;
- SetSeek(m_vecSeekPos, m_distanceToCountSeekDone);
- }
- }
+ if (particleSize > 0.75f)
+ particleSize = 0.75f;
- break;
- }
- case OBJECTIVE_GUARD_ATTACK:
- {
- if (m_pedInObjective) {
- SetLookFlag(m_pedInObjective, true);
- m_pLookTarget = m_pedInObjective;
- m_pLookTarget->RegisterReference((CEntity **) &m_pLookTarget);
- m_lookTimer = m_attackTimer;
- TurnBody();
- float distWithTargetSc = distWithTarget.Magnitude();
- if (distWithTargetSc >= 20.0f) {
- RestorePreviousObjective();
- } else if (m_attackTimer < CTimer::GetTimeInMilliseconds()) {
- if (m_nPedState != PED_SEEK_ENTITY && distWithTargetSc >= 2.0f) {
- SetSeek(m_pedInObjective, 1.0f);
- } else {
- SetAttack(m_pedInObjective);
- SetShootTimer(CGeneral::GetRandomNumberInRange(500.0f, 1500.0f));
- }
- SetAttackTimer(1000);
- }
- } else {
- RestorePreviousObjective();
- }
- break;
- }
- case OBJECTIVE_FOLLOW_ROUTE:
- if (HaveReachedNextPointOnRoute(1.0f)) {
- int nextPoint = GetNextPointOnRoute();
- m_nextRoutePointPos = CRouteNode::GetPointPosition(nextPoint);
- } else {
- CVector seekPos = m_nextRoutePointPos;
- SetSeek(seekPos, 0.8f);
- }
- break;
- case OBJECTIVE_SOLICIT_VEHICLE:
- if (m_carInObjective) {
- if (m_objectiveTimer <= CTimer::GetTimeInMilliseconds()) {
- if (!bInVehicle) {
- SetObjective(OBJECTIVE_NONE);
- SetWanderPath(CGeneral::GetRandomNumber() & 7);
- m_objectiveTimer = CTimer::GetTimeInMilliseconds() + 10000;
- if (IsPedInControl())
- m_pMyVehicle = nil;
- }
- } else {
- if (m_nPedState != PED_FLEE_ENTITY && m_nPedState != PED_SOLICIT)
- SetSeekCar(m_carInObjective, 0);
- }
- } else {
- RestorePreviousObjective();
- RestorePreviousState();
- if (IsPedInControl())
- m_pMyVehicle = nil;
- }
- break;
- case OBJECTIVE_HAIL_TAXI:
- if (!RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_TAXI) && CTimer::GetTimeInMilliseconds() > m_nWaitTimer) {
- Say(SOUND_PED_TAXI_WAIT);
- CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_IDLE_TAXI, 4.0f);
- m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 2000;
- }
- break;
- case OBJECTIVE_CATCH_TRAIN:
- {
- if (m_carInObjective) {
- SetObjective(OBJECTIVE_ENTER_CAR_AS_PASSENGER, m_carInObjective);
- } else {
- CVehicle* trainToEnter = nil;
- float closestCarDist = CHECK_NEARBY_THINGS_MAX_DIST;
- CVector pos = GetPosition();
- int16 lastVehicle;
- CEntity* vehicles[8];
-
- CWorld::FindObjectsInRange(pos, 10.0f, true, &lastVehicle, 6, vehicles, false, true, false, false, false);
- for (int i = 0; i < lastVehicle; i++) {
- CVehicle* nearVeh = (CVehicle*)vehicles[i];
- if (nearVeh->IsTrain()) {
- CVector vehDistVec = GetPosition() - nearVeh->GetPosition();
- float vehDist = vehDistVec.Magnitude();
- if (vehDist < closestCarDist && m_pedInObjective->m_pMyVehicle != nearVeh)
- {
- trainToEnter = nearVeh;
- closestCarDist = vehDist;
- }
- }
- }
- if (trainToEnter) {
- m_carInObjective = trainToEnter;
- m_carInObjective->RegisterReference((CEntity **) &m_carInObjective);
- }
- }
- break;
- }
- case OBJECTIVE_BUY_ICE_CREAM:
- if (m_carInObjective) {
- if (m_nPedState != PED_FLEE_ENTITY && m_nPedState != PED_BUY_ICECREAM && m_nPedState != PED_CHAT)
- SetSeekCar(m_carInObjective, 0);
- }
- 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 = nEnterCarRangeMultiplier * ENTER_CAR_MAX_DIST;
- CVector pos = GetPosition();
- int16 lastVehicle;
- CEntity *vehicles[8];
-
- 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 (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();
- float vehDist = vehDistVec.Magnitude();
- if (vehDist < closestCarDist) {
- carToSteal = nearVeh;
- closestCarDist = vehDist;
- }
- }
- }
- }
- }
- if (carToSteal) {
- SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, carToSteal);
- m_hitRecoverTimer = CTimer::GetTimeInMilliseconds() + 5000;
- } else {
- RestorePreviousObjective();
- RestorePreviousState();
- }
- }
- break;
- }
- case OBJECTIVE_MUG_CHAR:
- {
- if (m_pedInObjective) {
- if (m_pedInObjective->IsPlayer() || m_pedInObjective->bInVehicle || m_pedInObjective->m_fHealth <= 0.0f) {
- ClearObjective();
- return;
- }
- if (m_pedInObjective->m_nMoveState > PEDMOVE_WALK) {
- ClearObjective();
- return;
- }
- if (m_pedInObjective->m_objective == OBJECTIVE_KILL_CHAR_ON_FOOT && m_pedInObjective->m_pedInObjective == this) {
- SetObjective(OBJECTIVE_FLEE_CHAR_ON_FOOT_TILL_SAFE, m_pedInObjective);
- SetMoveState(PEDMOVE_SPRINT);
- return;
- }
- if (m_pedInObjective->m_nPedState == PED_FLEE_ENTITY && m_fleeFrom == this
- || m_pedInObjective->m_objective == OBJECTIVE_FLEE_CHAR_ON_FOOT_TILL_SAFE && m_pedInObjective->m_pedInObjective == this) {
- ClearObjective();
- SetFindPathAndFlee(m_pedInObjective, 15000, true);
- return;
- }
- float distWithTargetScSqr = distWithTarget.MagnitudeSqr();
- if (distWithTargetScSqr <= sq(10.0f)) {
- if (distWithTargetScSqr <= sq(1.4f)) {
- 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->GetProgress() > 0.8f)) {
- CAnimBlendAssociation *punchAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_FIGHT_PPUNCH, 8.0f);
- punchAssoc->flags |= ASSOC_DELETEFADEDOUT;
- punchAssoc->flags |= ASSOC_FADEOUTWHENDONE;
- CVector2D offset(distWithTarget.x, distWithTarget.y);
- int dir = m_pedInObjective->GetLocalDirection(offset);
- m_pedInObjective->StartFightDefend(dir, HITLEVEL_HIGH, 5);
- m_pedInObjective->ReactToAttack(this);
- m_pedInObjective->Say(SOUND_PED_ROBBED);
- 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
- CPed *victim = m_pedInObjective;
- ClearObjective();
- if (victim->m_objective != OBJECTIVE_KILL_CHAR_ON_FOOT
- || victim->m_pedInObjective != this) {
- SetFindPathAndFlee(victim, 15000, true);
- m_nLastPedState = PED_WANDER_PATH;
- } else {
- SetObjective(OBJECTIVE_FLEE_CHAR_ON_FOOT_TILL_SAFE, victim);
- SetMoveState(PEDMOVE_SPRINT);
- m_nLastPedState = PED_WANDER_PATH;
- }
- }
- } else {
- eWeaponType weaponType = GetWeapon()->m_eWeaponType;
- if (weaponType != WEAPONTYPE_UNARMED && weaponType != WEAPONTYPE_BASEBALLBAT)
- SetCurrentWeapon(WEAPONTYPE_UNARMED);
+ CVector particlePos = GetPosition() + GetForward() * 0.3f;
+ particlePos.z -= 1.2f;
- CAnimBlendAssociation *newReloadAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_FUCKU, 8.0f);
- newReloadAssoc->flags |= ASSOC_DELETEFADEDOUT;
- newReloadAssoc->flags |= ASSOC_FADEOUTWHENDONE;
- }
- } else {
- SetSeek(m_pedInObjective, 1.0f);
- CAnimBlendAssociation *walkAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WALK);
+ CVector particleDir = m_vecMoveSpeed * -0.75f;
- if (walkAssoc)
- walkAssoc->speed = 1.3f;
- }
- } else {
- ClearObjective();
- SetWanderPath(CGeneral::GetRandomNumber() & 7);
- }
- } else {
- m_objective = OBJECTIVE_NONE;
- 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();
- SetFlee(m_pMyVehicle, 6000);
- break;
- }
- // fall through
- case OBJECTIVE_LEAVE_CAR:
- if (CTimer::GetTimeInMilliseconds() > m_leaveCarTimer) {
- 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
- || m_pMyVehicle->IsBoat()
- || m_pMyVehicle->m_vecMoveSpeed.MagnitudeSqr2D() < sq(0.005f))) {
-#ifdef GTA_TRAIN
- if (m_pMyVehicle->IsTrain())
- SetExitTrain(m_pMyVehicle);
- else
-#endif
- if (m_pMyVehicle->IsBoat())
- SetExitBoat(m_pMyVehicle);
- else
- SetExitCar(m_pMyVehicle, 0);
- }
- } else {
- RestorePreviousObjective();
- }
- }
- if (bHeldHostageInCar) {
- if (CTheScripts::IsPlayerOnAMission()) {
- CVehicle *playerVeh = FindPlayerVehicle();
- if (playerVeh && playerVeh->IsPassenger(this)) {
- if (m_leaveCarTimer != 0)
- m_leaveCarTimer = 0;
- }
- }
- }
- break;
- case OBJECTIVE_AIM_GUN_AT:
- if (m_pedInObjective) {
- if (!bObstacleShowedUpDuringKillObjective)
- SetPointGunAt(m_pedInObjective);
+ particleDir.z = CGeneral::GetRandomNumberInRange(0.01f, 0.03f);
+ 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);
+ }
- 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;
- }
- }
- }
- }
+ if (m_nPedState == PED_JUMP) {
+ CVector particlePos = GetPosition();
+ particlePos.z -= 0.1f;
- 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;
- }
- }
- if (bObjectiveCompleted
- || m_objectiveTimer > 0 && CTimer::GetTimeInMilliseconds() > m_objectiveTimer) {
- RestorePreviousObjective();
- if (m_objectiveTimer > CTimer::GetTimeInMilliseconds() || !m_objectiveTimer)
- m_objectiveTimer = CTimer::GetTimeInMilliseconds() - 1;
-
- if (CharCreatedBy != RANDOM_CHAR || bInVehicle) {
- if (IsPedInControl())
- RestorePreviousState();
- } else {
- SetWanderPath(CGeneral::GetRandomNumber() & 7);
- }
- ClearAimFlag();
- ClearLookFlag();
+ 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
-void
-CPed::SetShootTimer(uint32 time)
-{
- if (CTimer::GetTimeInMilliseconds() > m_shootTimer) {
- m_shootTimer = CTimer::GetTimeInMilliseconds() + time;
- }
-}
-
-// --MIAMI: Done
-void
-CPed::SetSeekCar(CVehicle *car, uint32 doorNode)
-{
- if (m_nPedState == PED_SEEK_CAR)
- return;
-
- if (!CanSetPedState() || m_nPedState == PED_DRIVING)
- return;
-
- SetStoredState();
- m_pSeekTarget = car;
- m_pSeekTarget->RegisterReference((CEntity**) &m_pSeekTarget);
- m_carInObjective = car;
- m_carInObjective->RegisterReference((CEntity**) &m_carInObjective);
- m_pMyVehicle = car;
- m_pMyVehicle->RegisterReference((CEntity**) &m_pMyVehicle);
- // m_pSeekTarget->RegisterReference((CEntity**) &m_pSeekTarget);
- m_vehEnterType = doorNode;
- m_distanceToCountSeekDone = 0.5f;
- SetPedState(PED_SEEK_CAR);
-
-}
-
-// --MIAMI: Done
-void
-CPed::SetSeekBoatPosition(CVehicle *boat)
+// Actually GetLocalDirectionTo(Turn/Look)
+int
+CPed::GetLocalDirection(const CVector2D &posOffset)
{
- if (m_nPedState == PED_SEEK_IN_BOAT || boat->pDriver || !IsPedInControl())
- return;
+ int direction;
+ float angle;
- SetStoredState();
- m_carInObjective = boat;
- m_carInObjective->RegisterReference((CEntity **) &m_carInObjective);
- m_pMyVehicle = boat;
- m_pMyVehicle->RegisterReference((CEntity **) &m_pMyVehicle);
- m_distanceToCountSeekDone = 0.5f;
- SetPedState(PED_SEEK_IN_BOAT);
-}
+ for (angle = posOffset.Heading() - m_fRotationCur + DEGTORAD(45.0f); angle < 0.0f; angle += TWOPI);
-#ifdef GTA_TRAIN
-void
-CPed::SetExitTrain(CVehicle* train)
-{
- if (m_nPedState == PED_EXIT_TRAIN || train->GetStatus() != STATUS_TRAIN_NOT_MOVING || !((CTrain*)train)->Doors[0].IsFullyOpen())
- return;
+ for (direction = RADTODEG(angle)/90.0f; direction > 3; direction -= 4);
- /*
- // Not used
- CVector exitPos;
- GetNearestTrainPedPosition(train, exitPos);
- */
- m_nPedState = PED_EXIT_TRAIN;
- m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_TRAIN_GETOUT, 4.0f);
- m_pVehicleAnim->SetFinishCallback(PedSetOutTrainCB, this);
- bUsesCollision = false;
- LineUpPedWithTrain();
+ // 0-forward, 1-left, 2-backward, 3-right.
+ return direction;
}
-#endif
// --MIAMI: Done
bool
@@ -16173,466 +3861,934 @@ CPed::SetDirectionToWalkAroundObject(CEntity *obj)
}
// --MIAMI: Done
-int32
-CPed::ProcessEntityCollision(CEntity *collidingEnt, CColPoint *collidingPoints)
+bool
+CPed::IsPedInControl(void)
{
- bool collidedWithBoat = false;
- bool belowTorsoCollided = false;
- float gravityEffect = -0.15f * CTimer::GetTimeStep();
- CColPoint intersectionPoint;
- CColLine ourLine;
+ return m_nPedState <= PED_STATES_NO_AI
+ && !bIsInTheAir && !bIsLanding
+ && m_fHealth > 0.0f;
+}
- CColModel *ourCol = CModelInfo::GetModelInfo(GetModelIndex())->GetColModel();
- CColModel *hisCol = CModelInfo::GetModelInfo(collidingEnt->GetModelIndex())->GetColModel();
+// --MIAMI: Done
+bool
+CPed::IsPedShootable(void)
+{
+ return m_nPedState <= PED_STATES_NO_ST;
+}
- if (!bUsesCollision && !bJustCheckCollision)
+// --MIAMI: Done
+bool
+CPed::UseGroundColModel(void)
+{
+ return m_nPedState == PED_FALL ||
+ m_nPedState == PED_DIVE_AWAY ||
+ m_nPedState == PED_DIE ||
+ m_nPedState == PED_DEAD;
+}
+
+// --MIAMI: Done
+bool
+CPed::CanPedReturnToState(void)
+{
+ return m_nPedState <= PED_STATES_NO_AI && m_nPedState != PED_AIM_GUN && m_nPedState != PED_ATTACK &&
+ 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)
+{
+#ifdef FREE_CAM
+ if (CCamera::bFreeCam)
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_ANSWER_MOBILE;
+}
- if (collidingEnt->IsVehicle() && ((CVehicle*)collidingEnt)->IsBoat())
- collidedWithBoat = true;
+// --MIAMI: Done
+void
+CPed::PedSetPreviousStateCB(CAnimBlendAssociation* assoc, void* arg)
+{
+ CPed* ped = (CPed*)arg;
+ ped->RestorePreviousState();
+ ped->m_pVehicleAnim = nil;
+}
- // ofc we're not vehicle
- if (!m_bIsVehicleBeingShifted && !bSkipLineCol && !collidingEnt->IsPed()) {
- if (!bCollisionProcessed) {
- m_pCurrentPhysSurface = nil;
- if (bIsStanding) {
- bIsStanding = false;
- bWasStanding = true;
+// --MIAMI: Done
+void
+CPed::PedGetupCB(CAnimBlendAssociation* animAssoc, void* arg)
+{
+ CPed* ped = (CPed*)arg;
+
+ if (ped->m_nPedState == PED_GETUP)
+ RpAnimBlendClumpSetBlendDeltas(ped->GetClump(), ASSOC_PARTIAL, -1000.0f);
+
+ ped->bFallenDown = false;
+ animAssoc->blendDelta = -1000.0f;
+ if (ped->m_nPedState == PED_GETUP)
+ ped->RestorePreviousState();
+
+ 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->bGetUpAnimStarted = false;
+}
+
+// --MIAMI: Done
+void
+CPed::PedLandCB(CAnimBlendAssociation* animAssoc, void* arg)
+{
+ CPed* ped = (CPed*)arg;
+
+ animAssoc->blendDelta = -1000.0f;
+ ped->bIsLanding = false;
+
+ if (ped->m_nPedState == PED_JUMP)
+ ped->RestorePreviousState();
+}
+
+// --MIAMI: Done
+void
+CPed::PedStaggerCB(CAnimBlendAssociation* animAssoc, void* arg)
+{
+ /*
+ CPed *ped = (CPed*)arg;
+
+ if (ped->m_nPedState == PED_STAGGER)
+ // nothing
+ */
+}
+// --MIAMI: Done
+void
+CPed::PedSetOutCarCB(CAnimBlendAssociation *animAssoc, void *arg)
+{
+ CPed *ped = (CPed*)arg;
+
+ CVehicle *veh = ped->m_pMyVehicle;
+
+ bool startedToRun = false;
+ ped->bUsesCollision = true;
+ ped->m_actionX = 0.0f;
+ ped->m_actionY = 0.0f;
+ ped->bVehExitWillBeInstant = false;
+ if (veh && veh->IsBoat())
+ ped->ApplyMoveSpeed();
+
+ if (ped->m_objective == OBJECTIVE_LEAVE_CAR)
+ ped->RestorePreviousObjective();
+ else if (ped->m_objective == OBJECTIVE_LEAVE_CAR_AND_DIE) {
+ ped->m_fHealth = 0.0f;
+ ped->SetDie(ANIM_FLOOR_HIT, 4.0f, 0.5f);
+ }
+
+ ped->bInVehicle = false;
+ 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) {
+ ped->SetIdle();
+ 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);
}
- bCollisionProcessed = true;
- m_fCollisionSpeed += m_vecMoveSpeed.Magnitude2D() * CTimer::GetTimeStep();
- bStillOnValidPoly = false;
- if (IsPlayer() || m_fCollisionSpeed >= 1.0f
- && (m_fCollisionSpeed >= 2.0f || m_nPedState != PED_WANDER_PATH)) {
- m_collPoly.valid = false;
- m_fCollisionSpeed = 0.0f;
- bHitSteepSlope = false;
+ } else
+ ped->RestorePreviousState();
+
+ veh = ped->m_pMyVehicle;
+ if (ped->bFleeAfterExitingCar && veh) {
+ ped->bFleeAfterExitingCar = false;
+ ped->SetFlee(veh->GetPosition(), 12000);
+ ped->bUsePedNodeSeek = true;
+ ped->m_pNextPathNode = nil;
+ if (CGeneral::GetRandomNumber() & 1 || ped->m_pedStats->m_fear > 70) {
+ ped->SetMoveState(PEDMOVE_SPRINT);
+ ped->Say(SOUND_PED_FLEE_SPRINT);
} else {
- CVector pos = GetPosition();
- float potentialGroundZ = GetPosition().z - FEET_OFFSET;
- if (bWasStanding) {
- pos.z += -0.25f;
- potentialGroundZ += gravityEffect;
- }
- if (CCollision::IsStoredPolyStillValidVerticalLine(pos, potentialGroundZ, intersectionPoint, &m_collPoly)) {
- bStillOnValidPoly = true;
- if(!bHeadStuckInCollision || FEET_OFFSET + intersectionPoint.point.z < GetPosition().z) {
- GetMatrix().GetPosition().z = FEET_OFFSET + intersectionPoint.point.z;
- if (bHeadStuckInCollision)
- bHeadStuckInCollision = false;
- }
- m_vecMoveSpeed.z = 0.0f;
- bIsStanding = true;
- } else {
- m_collPoly.valid = false;
- m_fCollisionSpeed = 0.0f;
- bHitSteepSlope = false;
+ ped->SetMoveState(PEDMOVE_RUN);
+ ped->Say(SOUND_PED_FLEE_RUN);
+ }
+ startedToRun = true;
+
+ // This is not a good way to do this...
+ ped->m_nLastPedState = PED_WANDER_PATH;
+
+ } else if (ped->bWanderPathAfterExitingCar) {
+ ped->SetWanderPath(CGeneral::GetRandomNumberInRange(0.0f, 8.0f));
+ ped->bWanderPathAfterExitingCar = false;
+ if (ped->m_nPedType == PEDTYPE_PROSTITUTE)
+ ped->SetObjectiveTimer(30000);
+ ped->m_nLastPedState = PED_NONE;
+
+ } else if (ped->bGonnaKillTheCarJacker) {
+
+ // Kill objective is already given at this point.
+ ped->bGonnaKillTheCarJacker = false;
+ if (ped->m_pedInObjective) {
+ if (!(CGeneral::GetRandomNumber() & 1)
+ && ped->m_nPedType != PEDTYPE_COP
+ && (!ped->m_pedInObjective->IsPlayer() || !CTheScripts::IsPlayerOnAMission())) {
+ ped->ClearObjective();
+ ped->SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, veh);
}
+ ped->m_leaveCarTimer = CTimer::GetTimeInMilliseconds() + 1500;
}
+ int waitTime = 1500;
+ ped->SetWaitState(WAITSTATE_PLAYANIM_COWER, &waitTime);
+ ped->SetMoveState(PEDMOVE_RUN);
+ startedToRun = true;
+ } 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));
}
+ } else if (ped->m_nPedState == PED_DRIVING) {
+ ped->m_nPedState = PED_IDLE;
+ }
- if (!bStillOnValidPoly) {
- CVector potentialCenter = GetPosition();
- potentialCenter.z = GetPosition().z - 0.52f;
+ if (animAssoc)
+ animAssoc->blendDelta = -1000.0f;
- // 0.52f should be a ped's approx. radius
- float totalRadiusWhenCollided = collidingEnt->GetBoundRadius() + 0.52f - gravityEffect;
- if (bWasStanding) {
- if (collidedWithBoat) {
- potentialCenter.z += 2.0f * gravityEffect;
- totalRadiusWhenCollided += Abs(gravityEffect);
- } else {
- potentialCenter.z += gravityEffect;
+ ped->RestartNonPartialAnims();
+ ped->m_pVehicleAnim = nil;
+ ped->m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f);
+ veh = ped->m_pMyVehicle;
+ if (veh) {
+ if (ped->m_nPedType == PEDTYPE_PROSTITUTE) {
+ if (veh->pDriver) {
+ if (veh->pDriver->IsPlayer() && ped->CharCreatedBy == RANDOM_CHAR) {
+ CWorld::Players[CWorld::PlayerInFocus].m_nNextSexMoneyUpdateTime = 0;
+ CWorld::Players[CWorld::PlayerInFocus].m_nNextSexFrequencyUpdateTime = 0;
+ CWorld::Players[CWorld::PlayerInFocus].m_pHooker = nil;
+ CWorld::Players[CWorld::PlayerInFocus].m_nMoney -= 100;
+ if (CWorld::Players[CWorld::PlayerInFocus].m_nMoney < 0)
+ CWorld::Players[CWorld::PlayerInFocus].m_nMoney = 0;
}
}
- if (sq(totalRadiusWhenCollided) > (potentialCenter - collidingEnt->GetBoundCentre()).MagnitudeSqr()) {
- ourLine.p0 = GetPosition();
- ourLine.p1 = GetPosition();
- ourLine.p1.z = GetPosition().z - FEET_OFFSET;
- if (bWasStanding) {
- ourLine.p1.z = ourLine.p1.z + gravityEffect;
- ourLine.p0.z = ourLine.p0.z + -0.25f;
- }
- float minDist = 1.0f;
- belowTorsoCollided = CCollision::ProcessVerticalLine(ourLine, collidingEnt->GetMatrix(), *hisCol,
- intersectionPoint, minDist, false, false, &m_collPoly);
+ }
+ if (veh && veh->IsBike())
+ // BUG?
+ veh->m_nGettingOutFlags &= ~GetBikeDoorFlag(ped->m_vehEnterType);
+ else
+ veh->m_nGettingOutFlags &= ~GetCarDoorFlag(ped->m_vehEnterType);
- 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, false, &m_collPoly);
+ if (veh->pDriver == ped) {
+ veh->RemoveDriver();
+ veh->SetStatus(STATUS_ABANDONED);
+ if (veh->m_nDoorLock == CARLOCK_LOCKED_INITIALLY)
+ 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;
}
- if (belowTorsoCollided) {
- if (!bIsStanding
- || FEET_OFFSET + intersectionPoint.point.z > GetPosition().z
- || collidedWithBoat && 3.12f + intersectionPoint.point.z > GetPosition().z) {
+ }
+ } else {
+ veh->RemovePassenger(ped);
+ }
- if (!collidingEnt->IsVehicle() && !collidingEnt->IsObject()) {
- m_pCurSurface = collidingEnt;
- collidingEnt->RegisterReference((CEntity**)&m_pCurSurface);
- bTryingToReachDryLand = false;
- bOnBoat = false;
- } else {
- m_pCurrentPhysSurface = (CPhysical*)collidingEnt;
- collidingEnt->RegisterReference((CEntity**)&m_pCurrentPhysSurface);
- m_vecOffsetFromPhysSurface = intersectionPoint.point - collidingEnt->GetPosition();
- m_pCurSurface = collidingEnt;
- collidingEnt->RegisterReference((CEntity**)&m_pCurSurface);
- m_collPoly.valid = false;
- if (collidingEnt->IsVehicle() && ((CVehicle*)collidingEnt)->IsBoat()) {
- bOnBoat = true;
- } else {
- bOnBoat = false;
- }
- }
+ if (veh->bIsBus && !veh->IsUpsideDown() && !veh->IsOnItsSide()) {
+ float angleAfterExit;
+ if (ped->m_vehEnterType == CAR_DOOR_LF) {
+ angleAfterExit = HALFPI + veh->GetForward().Heading();
+ } else {
+ angleAfterExit = veh->GetForward().Heading() - HALFPI;
+ }
+ ped->SetHeading(angleAfterExit);
+ ped->m_fRotationDest = angleAfterExit;
+ ped->m_fRotationCur = angleAfterExit;
+ if (!ped->bBusJacked)
+ ped->SetMoveState(PEDMOVE_WALK);
+ }
+ if (CGarages::IsPointWithinAnyGarage(ped->GetPosition()))
+ veh->bLightsOn = false;
+ }
- if (!bHeadStuckInCollision || FEET_OFFSET + intersectionPoint.point.z < GetPosition().z) {
- GetMatrix().GetPosition().z = FEET_OFFSET + intersectionPoint.point.z;
- if (bHeadStuckInCollision)
- bHeadStuckInCollision = false;
- }
- m_nSurfaceTouched = intersectionPoint.surfaceB;
- if (m_nSurfaceTouched == SURFACE_STEEP_CLIFF) {
- bHitSteepSlope = true;
- m_vecDamageNormal = intersectionPoint.normal;
- }
- }
+ if (ped->IsPlayer())
+ AudioManager.PlayerJustLeftCar();
- float upperSpeedLimit = 0.33f;
- float lowerSpeedLimit = -0.25f;
- float speed = m_vecMoveSpeed.Magnitude2D();
- if (m_nPedState == PED_IDLE) {
- upperSpeedLimit *= 2.0f;
- lowerSpeedLimit *= 1.5f;
- }
- CAnimBlendAssociation *fallAnim = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_FALL_FALL);
- if (!bWasStanding && speed > upperSpeedLimit && (!bPushedAlongByCar || m_vecMoveSpeed.z < lowerSpeedLimit)
- && m_pCollidingEntity != collidingEnt) {
+ ped->ReplaceWeaponWhenExitingVehicle();
- float damage = 100.0f * Max(speed - 0.25f, 0.0f);
- float damage2 = damage;
- if (m_vecMoveSpeed.z < -0.25f)
- damage += (-0.25f - m_vecMoveSpeed.z) * 150.0f;
+ ped->bOnBoat = false;
+ if (ped->bBusJacked) {
+ ped->SetFall(1500, ANIM_KO_SKID_BACK, false);
+ ped->bBusJacked = false;
+ }
+ ped->m_nStoredMoveState = PEDMOVE_NONE;
+ if (!ped->IsPlayer()) {
+ // It's a shame...
+#ifdef FIX_BUGS
+ int createdBy = ped->CharCreatedBy;
+#else
+ int createdBy = !ped->CharCreatedBy;
+#endif
- 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);
- }
- if (CSurfaceTable::IsSoftLanding(intersectionPoint.surfaceB))
- damage *= 0.5f;
+ if (createdBy == MISSION_CHAR && !startedToRun)
+ ped->SetMoveState(PEDMOVE_WALK);
+ }
+ ped->bHeldHostageInCar = false;
+}
- InflictDamage(collidingEnt, WEAPONTYPE_FALL, damage, PEDPIECE_TORSO, dir);
- if (IsPlayer() && damage2 > 5.0f)
- Say(SOUND_PED_LAND);
+// --MIAMI: Done
+void
+CPed::PedSetDraggedOutCarCB(CAnimBlendAssociation *dragAssoc, void *arg)
+{
+ CAnimBlendAssociation *quickJackedAssoc;
+ CVehicle *vehicle;
+ CPed *ped = (CPed*)arg;
- } else if (!bWasStanding && fallAnim && -0.016f * CTimer::GetTimeStep() > m_vecMoveSpeed.z) {
- InflictDamage(collidingEnt, WEAPONTYPE_FALL, 15.0f, PEDPIECE_TORSO, 2);
- }
- m_vecMoveSpeed.z = 0.0f;
- bIsStanding = true;
- } else {
- bOnBoat = false;
- }
+ 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)
+ dragAssoc->blendDelta = -1000.0f;
+ }
+ ped->RestartNonPartialAnims();
+ ped->m_pVehicleAnim = nil;
+ ped->m_pSeekTarget = nil;
+ vehicle = ped->m_pMyVehicle;
+
+ 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)
+ vehicle->m_nDoorLock = CARLOCK_UNLOCKED;
+
+ if (ped->m_nPedType == PEDTYPE_COP && vehicle->IsLawEnforcementVehicle())
+ vehicle->ChangeLawEnforcerState(false);
+ } else {
+ vehicle->RemovePassenger(ped);
+ }
+ }
+ ped->bInVehicle = false;
+ if (ped->IsPlayer())
+ AudioManager.PlayerJustLeftCar();
+
+ 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;
+ }
+
+ if (quickJackedAssoc) {
+ dragAssoc->SetDeleteCallback(PedSetQuickDraggedOutCarPositionCB, ped);
+ } else {
+ dragAssoc->SetDeleteCallback(PedSetDraggedOutCarPositionCB, ped);
+ if (ped->CanSetPedState())
+ CAnimManager::BlendAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_GETUP1, 1000.0f);
+ }
+
+ ped->ReplaceWeaponWhenExitingVehicle();
+
+ ped->m_nStoredMoveState = PEDMOVE_NONE;
+ ped->bVehExitWillBeInstant = false;
+}
+
+// --MIAMI: Done
+void
+CPed::PedSetInCarCB(CAnimBlendAssociation *animAssoc, void *arg)
+{
+ CPed *ped = (CPed*)arg;
+
+ CVehicle *veh = ped->m_pMyVehicle;
+
+ // Pointless code
+ if (!veh)
+ return;
+
+ // 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
+ && (ped->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER || ped->m_nPedState == PED_CARJACK)) {
+
+ if (!ped->IsPlayer() && (ped->CharCreatedBy != MISSION_CHAR || driver->IsPlayer())) {
+ ped->QuitEnteringCar();
+ return;
+ }
+ if (driver->CharCreatedBy == MISSION_CHAR) {
+ PedSetOutCarCB(nil, veh->pDriver);
+ if (driver->m_pMyVehicle) {
+ driver->PositionPedOutOfCollision();
+ } else {
+ driver->m_pMyVehicle = veh;
+ driver->PositionPedOutOfCollision();
+ driver->m_pMyVehicle = nil;
}
+ veh->pDriver = nil;
+ } else {
+ driver->SetDead();
+ driver->FlagToDestroyWhenNextProcessed();
+ veh->pDriver = nil;
}
}
- int ourCollidedSpheres = CCollision::ProcessColModels(GetMatrix(), *ourCol, collidingEnt->GetMatrix(), *hisCol, collidingPoints, nil, nil);
- if (ourCollidedSpheres > 0 || belowTorsoCollided) {
- AddCollisionRecord(collidingEnt);
- if (!collidingEnt->IsBuilding())
- ((CPhysical*)collidingEnt)->AddCollisionRecord(this);
+ if (ped->bRemoveMeWhenIGotIntoCar) {
+ ped->bRemoveMeWhenIGotIntoCar = false;
+ ped->bRemoveFromWorld = true;
+ }
+ if (ped->bCollectBusFare) {
+ ped->bCollectBusFare = false;
+ if (FindPlayerPed())
+ FindPlayerPed()->m_nLastBusFareCollected += 5;
+ }
- if (ourCollidedSpheres > 0 && (collidingEnt->IsBuilding() || collidingEnt->GetIsStatic())) {
- bHasHitWall = true;
+ if (!ped->IsNotInWreckedVehicle() || ped->DyingOrDead())
+ return;
+
+ ped->bInVehicle = true;
+ if (ped->m_nPedType == PEDTYPE_PROSTITUTE) {
+ if (veh->pDriver) {
+ if (veh->pDriver->IsPlayer() && ped->CharCreatedBy == RANDOM_CHAR) {
+ CWorld::Players[CWorld::PlayerInFocus].m_nSexFrequency = 1000;
+ CWorld::Players[CWorld::PlayerInFocus].m_nNextSexMoneyUpdateTime = CTimer::GetTimeInMilliseconds() + 1000;
+ CWorld::Players[CWorld::PlayerInFocus].m_nNextSexFrequencyUpdateTime = CTimer::GetTimeInMilliseconds() + 3000;
+ CWorld::Players[CWorld::PlayerInFocus].m_pHooker = (CCivilianPed*)ped;
+ }
}
}
- if (collidingEnt->IsBuilding() || collidingEnt->GetIsStatic()) {
- if (bWasStanding) {
- CVector sphereNormal;
- float normalLength;
- for(int sphere = 0; sphere < ourCollidedSpheres; sphere++) {
- sphereNormal = collidingPoints[sphere].normal;
- if (sphereNormal.z >= -1.0f || !IsPlayer()) {
- normalLength = sphereNormal.Magnitude2D();
- if (normalLength != 0.0f) {
- sphereNormal.x = sphereNormal.x / normalLength;
- sphereNormal.y = sphereNormal.y / normalLength;
- }
- } 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;
- bHeadStuckInCollision = true;
- }
- sphereNormal.Normalise();
- collidingPoints[sphere].normal = sphereNormal;
- if (collidingPoints[sphere].surfaceB == SURFACE_STEEP_CLIFF)
- bHitSteepSlope = true;
+ if (ped->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER || ped->m_nPedState == PED_CARJACK)
+ veh->bIsBeingCarJacked = false;
+
+ if (veh->m_nNumGettingIn)
+ --veh->m_nNumGettingIn;
+
+ if (ped->IsPlayer() && ((CPlayerPed*)ped)->m_bAdrenalineActive)
+ ((CPlayerPed*)ped)->ClearAdrenaline();
+
+ if (veh->IsBoat()) {
+ if (ped->IsPlayer()) {
+ CCarCtrl::RegisterVehicleOfInterest(veh);
+ 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);
+ }
+ veh->SetStatus(STATUS_PLAYER);
+ AudioManager.PlayerJustGotInCar();
+ }
+ veh->SetDriver(ped);
+ if (!veh->bEngineOn)
+ veh->bEngineOn = true;
+
+ ped->SetPedState(PED_DRIVING);
+ ped->StopNonPartialAnims();
+ ped->RemoveWeaponWhenEnteringVehicle();
+ return;
+ }
+
+ if (ped->m_pVehicleAnim)
+ ped->m_pVehicleAnim->blendDelta = -1000.0f;
+
+ ped->bDoBloodyFootprints = false;
+ if (veh->m_nAlarmState == -1)
+ veh->m_nAlarmState = 15000;
+
+ if (ped->IsPlayer()) {
+ 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);
}
+ veh->SetStatus(STATUS_PLAYER);
+ }
+ AudioManager.PlayerJustGotInCar();
+ } else if (ped->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER) {
+ 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);
}
+ veh->SetStatus(STATUS_PHYSICS);
}
- return ourCollidedSpheres;
+
+ 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->bStayInCarOnJack && !passenger->bHeldHostageInCar && (passenger->m_leader != ped || !ped->bIsLeader)) {
+ passenger->SetObjective(OBJECTIVE_LEAVE_CAR, veh);
+ passenger->m_leaveCarTimer = CTimer::GetTimeInMilliseconds();
+ }
+ }
+ }
+
+ if (ped->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER || ped->m_nPedState == PED_CARJACK) {
+ veh->SetDriver(ped);
+ if (veh->VehicleCreatedBy == PARKED_VEHICLE) {
+ veh->VehicleCreatedBy = RANDOM_VEHICLE;
+ ++CCarCtrl::NumRandomCars;
+ --CCarCtrl::NumParkedCars;
+ }
+ if (veh->bIsAmbulanceOnDuty) {
+ veh->bIsAmbulanceOnDuty = false;
+ --CCarCtrl::NumAmbulancesOnDuty;
+ }
+ if (veh->bIsFireTruckOnDuty) {
+ veh->bIsFireTruckOnDuty = false;
+ --CCarCtrl::NumFiretrucksOnDuty;
+ }
+ if (ped->m_nPedType == PEDTYPE_COP && veh->IsLawEnforcementVehicle())
+ veh->ChangeLawEnforcerState(true);
+
+ if (!veh->bEngineOn) {
+ veh->bEngineOn = true;
+ DMAudio.PlayOneShot(ped->m_audioEntityId, SOUND_CAR_ENGINE_START, 1.0f);
+ }
+ if (ped->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER && ped->CharCreatedBy == RANDOM_CHAR
+ && ped != FindPlayerPed() && ped->m_nPedType != PEDTYPE_EMERGENCY) {
+
+ CCarCtrl::JoinCarWithRoadSystem(veh);
+ veh->AutoPilot.m_nCarMission = MISSION_CRUISE;
+ veh->AutoPilot.m_nTempAction = TEMPACT_NONE;
+ veh->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_AVOID_CARS;
+ veh->AutoPilot.m_nCruiseSpeed = 25;
+ }
+ 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_SPRINT_TO_AREA || ped->m_prevObjective == OBJECTIVE_KILL_CHAR_ON_FOOT)
+ ped->m_prevObjective = OBJECTIVE_NONE;
+
+ ped->RestorePreviousObjective();
+ }
+
+ } 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) {
+ case CAR_DOOR_RF:
+ veh->AddPassenger(ped, 0);
+ break;
+ case CAR_DOOR_RR:
+ veh->AddPassenger(ped, 2);
+ break;
+ case CAR_DOOR_LR:
+ veh->AddPassenger(ped, 1);
+ break;
+ default:
+ veh->AddPassenger(ped);
+ break;
+ }
+ }
+ ped->SetPedState(PED_DRIVING);
+ 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();
+
+ // VC has conditional OBJECTIVE_LEAVE_CAR here, which runs if it entered the first dead condition.
+
+ if(slowDown)
+ veh->AutoPilot.m_nCruiseSpeed = 17;
+ }
+
+ 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);
+
+ switch (ped->m_objective) {
+ case OBJECTIVE_KILL_CHAR_ON_FOOT:
+ case OBJECTIVE_KILL_CHAR_ANY_MEANS:
+ case OBJECTIVE_LEAVE_CAR:
+ case OBJECTIVE_FOLLOW_CAR_IN_CAR:
+ 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);
+ }
+
+ ped->AddInCarAnims(veh, veh->pDriver == ped);
+ if (veh->bIsBus)
+ ped->bRenderPedInCar = false;
+
+ // FIX: RegisterVehicleOfInterest not just registers the vehicle, but also updates register time. So remove the IsThisVehicleInteresting check.
+#ifndef FIX_BUGS
+ if (ped->IsPlayer() && !CCarCtrl::IsThisVehicleInteresting(veh) && veh->VehicleCreatedBy != MISSION_VEHICLE) {
+#else
+ if (ped->IsPlayer() && veh->VehicleCreatedBy != MISSION_VEHICLE) {
+#endif
+ CCarCtrl::RegisterVehicleOfInterest(veh);
+
+ if (!veh->bHasBeenOwnedByPlayer && veh->VehicleCreatedBy != MISSION_VEHICLE)
+ CEventList::RegisterEvent(EVENT_STEAL_CAR, EVENT_ENTITY_VEHICLE, veh, ped, 1500);
+
+ veh->bHasBeenOwnedByPlayer = true;
+ }
+ ped->bChangedSeat = true;
}
// --MIAMI: Done
-void
-CPed::SetFormation(eFormation type)
+bool
+CPed::CanBeDeleted(void)
{
- // FIX: Formations in GetFormationPosition were in range 1-8, whereas in here it's 0-7.
- // To not change the behaviour, range in here tweaked by 1 with the use of enum.
-
- switch (m_pedFormation) {
- case FORMATION_REAR:
- case FORMATION_REAR_LEFT:
- case FORMATION_REAR_RIGHT:
- case FORMATION_FRONT_LEFT:
- case FORMATION_FRONT_RIGHT:
- case FORMATION_LEFT:
- case FORMATION_RIGHT:
- case FORMATION_FRONT:
- break;
+ if (bInVehicle)
+ return false;
+
+ switch (CharCreatedBy) {
+ case RANDOM_CHAR:
+ return true;
+ case MISSION_CHAR:
+ return false;
+ case UNK_CHAR:
+ return false;
default:
- Error("Unknown formation type, PedAI.cpp");
- break;
+ 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;
}
- m_pedFormation = type;
}
// --MIAMI: Done
void
-CPed::SetFollowRoute(int16 currentPoint, int16 routeType)
+CPed::AddWeaponModel(int id)
{
- m_routeLastPoint = currentPoint;
- m_routeType = routeType;
- m_routePointsBeingPassed = 1;
- m_routePointsPassed = 0;
- m_objective = OBJECTIVE_FOLLOW_ROUTE;
- m_routeStartPoint = CRouteNode::GetRouteStart(currentPoint);
- m_nextRoutePointPos = CRouteNode::GetPointPosition(GetNextPointOnRoute());
+ if (id != -1) {
+ if (m_pWeaponModel)
+ RemoveWeaponModel(-1);
+
+ 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();
+ }
}
-// "Wander range" state is unused in game, and you can't use it without SetWanderRange anyway
+static RwObject*
+RemoveAllModelCB(RwObject *object, void *data)
+{
+ RpAtomic *atomic = (RpAtomic*)object;
+ if (CVisibilityPlugins::GetAtomicModelInfo(atomic)) {
+ RpClumpRemoveAtomic(RpAtomicGetClump(atomic), atomic);
+ RpAtomicDestroy(atomic);
+ }
+ return object;
+}
+
+// --MIAMI: Done
void
-CPed::WanderRange(void)
+CPed::RemoveWeaponModel(int modelId)
{
- bool arrived = Seek();
- if (arrived) {
- Idle();
- if ((m_randomSeed + 3 * CTimer::GetFrameCounter()) % 1000 > 997) {
- CVector2D newCoords2D = m_wanderRangeBounds->GetRandomPointInRange();
- SetSeek(CVector(newCoords2D.x, newCoords2D.y, GetPosition().z), 2.5f);
+ // modelId is not used!! This function just removes the current weapon.
+ 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;
+ }
+ }
+
+ 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;
}
// --MIAMI: Done
-bool
-CPed::WillChat(CPed *stranger)
+void
+CPed::RequestDelayedWeapon()
{
- if (m_pNextPathNode && m_pLastPathNode) {
- if (m_pNextPathNode != m_pLastPathNode && ThePaths.TestCrossesRoad(m_pNextPathNode, m_pLastPathNode)) {
- return false;
+ 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, 1);
+ m_delayedWeapon = WEAPONTYPE_UNIDENTIFIED;
}
}
- if (m_nSurfaceTouched == SURFACE_TARMAC)
- return false;
- if (stranger == this)
- return false;
- if (m_nPedType == stranger->m_nPedType)
- 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;
}
-#ifdef GTA_TRAIN
+// --MIAMI: Done
void
-CPed::SetEnterTrain(CVehicle *train, uint32 unused)
+CPed::GiveDelayedWeapon(eWeaponType weapon, uint32 ammo)
{
- if (m_nPedState == PED_ENTER_TRAIN || !((CTrain*)train)->Doors[0].IsFullyOpen())
- return;
+ 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);
- /*
- // Not used
- CVector enterPos;
- GetNearestTrainPedPosition(train, enterPos);
- */
- m_fRotationCur = train->GetForward().Heading() - HALFPI;
- m_pMyVehicle = train;
- m_pMyVehicle->RegisterReference((CEntity **) &m_pMyVehicle);
+ if ((modelId1 == -1 || CStreaming::HasModelLoaded(modelId1))
+ && (modelId2 == -1 || CStreaming::HasModelLoaded(modelId2))) {
+ GiveWeapon(m_delayedWeapon, m_delayedWeaponAmmo, true);
+ m_delayedWeapon = WEAPONTYPE_UNIDENTIFIED;
+ }
+ }
+}
- m_nPedState = PED_ENTER_TRAIN;
- m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_TRAIN_GETIN, 4.0f);
- m_pVehicleAnim->SetFinishCallback(PedSetInTrainCB, this);
- bUsesCollision = false;
- LineUpPedWithTrain();
- if (IsPlayer()) {
- if (((CPlayerPed*)this)->m_bAdrenalineActive)
- ((CPlayerPed*)this)->ClearAdrenaline();
+// --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) {
+
+ // 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 {
+ 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 (GetWeapon(slot).m_eWeaponState != WEAPONSTATE_OUT_OF_AMMO)
+ GetWeapon(slot).m_eWeaponState = WEAPONSTATE_READY;
+
+ return slot;
}
-#endif
-// --MIAMI: Done, but what is this parameter for?
+// --MIAMI: Done
+int
+CPed::GetWeaponSlot(eWeaponType weaponType)
+{
+ return CWeaponInfo::GetWeaponInfo(weaponType)->m_nWeaponSlot;
+}
+
+// --MIAMI: Done
void
-CPed::SetDuck(uint32 time, bool sth)
+CPed::SetCurrentWeapon(int slot)
{
- if (bIsDucking || CTimer::GetTimeInMilliseconds() <= m_duckTimer && !sth) {
- if (sth && CTimer::GetTimeInMilliseconds() + time > m_duckTimer)
- m_duckTimer = CTimer::GetTimeInMilliseconds() + time;
+ 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;
- 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) {
- CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_DUCK_DOWN, 4.0f);
- bIsDucking = true;
- m_duckTimer = CTimer::GetTimeInMilliseconds() + time;
- }
+ 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::SeekBoatPosition(void)
+CPed::SetCurrentWeapon(eWeaponType weaponType)
{
- if (m_carInObjective && !m_carInObjective->pDriver) {
- CVehicleModelInfo *boatModel = m_carInObjective->GetModelInfo();
-
- CVector enterOffset;
- enterOffset = boatModel->GetFrontSeatPosn();
- enterOffset.x = 0.0f;
- CMatrix boatMat(m_carInObjective->GetMatrix());
- SetMoveState(PEDMOVE_WALK);
- m_vecSeekPos = boatMat * enterOffset;
- if (Seek()) {
- // We arrived to the boat
- m_vehEnterType = 0;
- SetEnterCar(m_carInObjective, 0);
- }
- } else
- RestorePreviousState();
+ SetCurrentWeapon(CWeaponInfo::GetWeaponInfo(weaponType)->m_nWeaponSlot);
}
// --MIAMI: Done
void
-CPed::SetEnterCar(CVehicle *car, uint32 unused)
+CPed::GrantAmmo(eWeaponType weaponType, uint32 ammo)
{
- if (CCranes::IsThisCarBeingCarriedByAnyCrane(car)) {
- RestorePreviousState();
- RestorePreviousObjective();
- } else {
- uint8 doorFlag;
- eDoors door;
- 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;
+ int slot = CWeaponInfo::GetWeaponInfo(weaponType)->m_nWeaponSlot;
+ if (slot == -1)
+ return;
- 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;
+ GetWeapon(slot).m_nAmmoTotal += ammo;
+ if (weaponType < WEAPONTYPE_TOTALWEAPONS && weaponType > WEAPONTYPE_UNARMED && CWeaponInfo::ms_aMaxAmmoForWeapon[weaponType] >= 0) {
- 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
- || car->bIsBeingCarJacked || m_pVehicleAnim
- || doorFlag && !car->IsDoorReady(door) && !car->IsDoorFullyOpen(door))
- SetMoveState(PEDMOVE_STILL);
- else
- SetEnterCar_AllClear(car, m_vehEnterType, doorFlag);
+ // 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);
}
+
+ if (GetWeapon(slot).m_eWeaponState == WEAPONSTATE_OUT_OF_AMMO && GetWeapon(slot).m_nAmmoTotal > 0)
+ GetWeapon(slot).m_eWeaponState = WEAPONSTATE_READY;
}
// --MIAMI: Done
void
-CPed::SetRadioStation(void)
+CPed::SetAmmo(eWeaponType weaponType, uint32 ammo)
{
- CPedModelInfo* modelInfo = (CPedModelInfo*)CModelInfo::GetModelInfo(GetModelIndex());
-
- if (IsPlayer() || !m_pMyVehicle || m_pMyVehicle->pDriver != this)
+ int slot = CWeaponInfo::GetWeaponInfo(weaponType)->m_nWeaponSlot;
+ if (slot == -1)
return;
- 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 = modelInfo->radio2;
- }
+ 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 {
- m_pMyVehicle->m_nRadioStation = DMAudio.GetFavouriteRadioStation();
+ 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;
}
-inline bool
-CPed::IsNotInWreckedVehicle()
+// --MIAMI: Done
+void
+CPed::ClearWeapons(void)
+{
+ RemoveWeaponModel(-1);
+ for (int i = 0; i < ARRAY_SIZE(m_weapons); i++) {
+ GetWeapon(i).Shutdown();
+ }
+ SetCurrentWeapon(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)
{
- return m_pMyVehicle != nil && m_pMyVehicle->GetStatus() != STATUS_WRECKED;
+ 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() && GetWeaponSlot(weaponType) == 5) {
+ if (m_storedWeapon != WEAPONTYPE_UNIDENTIFIED) {
+ SetCurrentWeapon(m_storedWeapon);
+ m_storedWeapon = WEAPONTYPE_UNIDENTIFIED;
+ }
+ } else {
+ AddWeaponModel(CWeaponInfo::GetWeaponInfo(weaponType)->m_nModelId);
+ }
}
// --MIAMI: Done
@@ -16644,11 +4800,7 @@ 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();
- }
-#endif
+ UpdateRpHAnim();
bool bIsWindModifierTurnedOn = false;
float fAnyDirectionShift = 1.0f;
@@ -16669,7 +4821,7 @@ CPed::PreRender(void)
fWindMult = DotProduct(m_pMyVehicle->m_vecMoveSpeed, GetForward());
if (fWindMult > 0.4f) {
float volume = (fWindMult - 0.4f) / 0.6f;
- DMAudio.PlayOneShot(m_audioEntityId, SOUND_SET_202, volume); //TODO(MIAMI): revise when audio is done
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_SHIRT_WIND_FLAP, volume);
}
}
@@ -16872,221 +5024,1285 @@ CPed::PreRender(void)
}
}
+CVector vecTestTemp(-1.0f, -1.0f, -1.0f);
+
// --MIAMI: Done
void
-CPed::ProcessBuoyancy(void)
+CPed::Render(void)
{
- float buoyancyLevel = 1.1f;
- static uint32 nGenerateRaindrops = 0;
- static uint32 nGenerateWaterCircles = 0;
- CRGBA color;
+ if (bInVehicle && m_pMyVehicle && m_nPedState != PED_EXIT_CAR && m_nPedState != PED_DRAG_FROM_CAR) {
+ if (!bRenderPedInCar)
+ return;
- if (bInVehicle)
- 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;
+ }
+ }
- CVector buoyancyPoint;
- CVector buoyancyImpulse;
+ CEntity::Render();
- if (DyingOrDead())
- buoyancyLevel = 1.8f;
+ if(m_pWeaponModel){
+ RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(GetClump());
+ int idx = RpHAnimIDGetIndex(hier, m_pFrames[PED_HANDR]->nodeID);
+ RwMatrix *mat = &RpHAnimHierarchyGetMatrixArray(hier)[idx];
+ RwFrame *frame = RpAtomicGetFrame(m_pWeaponModel);
+ *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;
- 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->bRenderScorched) {
- bIsInWater = false;
- return;
+ 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);
+ }
}
- 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()) {
- if (bTryingToReachDryLand) {
- if (buoyancyImpulse.z / m_fMass > GRAVITY * 0.4f * CTimer::GetTimeStep()) {
- bTryingToReachDryLand = false;
- CVector pos = GetPosition();
- if (PlacePedOnDryLand()) {
- if (m_fHealth > 20.0f)
- InflictDamage(nil, WEAPONTYPE_DROWNING, 15.0f, PEDPIECE_TORSO, false);
+ }
+}
- if (bIsInTheAir) {
- RpAnimBlendClumpSetBlendDeltas(GetClump(), ASSOC_PARTIAL, -1000.0f);
- bIsInTheAir = false;
- }
- pos.z = pos.z - 0.8f;
- CParticleObject::AddObject(POBJECT_PED_WATER_SPLASH, pos, CVector(0.0f, 0.0f, 0.0f), 0.0f, 50, color, true);
- m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f);
- SetPedState(PED_IDLE);
- return;
- }
+// --MIAMI: Done
+void
+CPed::CheckAroundForPossibleCollisions(void)
+{
+ CVector ourCentre, objCentre;
+ CEntity *objects[8];
+ int16 maxObject;
+
+ if (CTimer::GetTimeInMilliseconds() <= m_nPedStateTimer)
+ return;
+
+ GetBoundCentre(ourCentre);
+
+ CWorld::FindObjectsInRange(ourCentre, 10.0f, true, &maxObject, 6, objects, false, true, false, true, false);
+ for (int i = 0; i < maxObject; i++) {
+ CEntity *object = objects[i];
+ if (bRunningToPhone) {
+ if (gPhoneInfo.PhoneAtThisPosition(object->GetPosition()))
+ break;
+ }
+ object->GetBoundCentre(objCentre);
+ float radius = object->GetBoundRadius();
+ if (radius > 4.5f || radius < 1.0f)
+ radius = 1.0f;
+
+ // Developers gave up calculating Z diff. later according to asm.
+ float diff = CVector(ourCentre - objCentre).MagnitudeSqr2D();
+
+ if (sq(radius + 1.0f) > diff)
+ m_fRotationDest += DEGTORAD(22.5f);
+ }
+}
+
+// --MIAMI: Done
+void
+CPed::SetIdle(void)
+{
+ if (m_nPedState != PED_IDLE && m_nPedState != PED_MUG && m_nPedState != PED_FLEE_ENTITY) {
+ if (m_nPedState == PED_AIM_GUN)
+ ClearPointGunAt();
+
+ 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)
+{
+ CVehicle *veh = m_pMyVehicle;
+ if (veh && veh->m_nGettingOutFlags && m_vehEnterType) {
+
+ if (veh->m_nGettingOutFlags & GetCarDoorFlag(m_vehEnterType)) {
+
+ if (m_objective != OBJECTIVE_KILL_CHAR_ON_FOOT) {
+
+ CVector doorPos = GetPositionToOpenCarDoor(veh, m_vehEnterType);
+ CVector doorDist = GetPosition() - doorPos;
+
+ if (doorDist.MagnitudeSqr() < sq(0.5f)) {
+ SetMoveState(PEDMOVE_WALK);
+ return;
}
}
}
- 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 (m_nMoveState != PEDMOVE_STILL && !IsPlayer())
+ SetMoveState(PEDMOVE_STILL);
+
+ m_moved = CVector2D(0.0f, 0.0f);
+}
+
+// --MIAMI: Done
+void
+CPed::ClearPause(void)
+{
+ RestorePreviousState();
+}
+
+// --MIAMI: Done
+void
+CPed::Pause(void)
+{
+ m_moved = CVector2D(0.0f, 0.0f);
+ if (CTimer::GetTimeInMilliseconds() > m_leaveCarTimer)
+ ClearPause();
+}
+
+// --MIAMI: Done
+void
+CPed::SetFall(int extraTime, AnimationId animId, uint8 evenIfNotInControl)
+{
+ if (m_attachedTo)
+ return;
+
+ if (!IsPedInControl() && (!evenIfNotInControl || DyingOrDead()))
+ return;
+
+ ClearLookFlag();
+ ClearAimFlag();
+ SetStoredState();
+ SetPedState(PED_FALL);
+ 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);
}
- if (buoyancyImpulse.z / m_fMass > GRAVITY * 0.25f * CTimer::GetTimeStep()) {
- if (speedMult == 0.0f) {
- speedMult = pow(0.9f, CTimer::GetTimeStep());
+ } else {
+ 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()) {
+ 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;
}
- 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_getUpTimer = 1000.0f * fallAssoc->hierarchy->totalLength
+ + CTimer::GetTimeInMilliseconds()
+ + extraTime
+ + ((m_randomSeed + CTimer::GetFrameCounter()) % 1000);
+ }
+ } else {
+ m_getUpTimer = extraTime
+ + CTimer::GetTimeInMilliseconds()
+ + 1000
+ + ((m_randomSeed + CTimer::GetFrameCounter()) % 1000);
+ }
+ bFallenDown = true;
+}
+
+// --MIAMI: Done
+void
+CPed::ClearFall(void)
+{
+ SetGetUp();
+}
+
+// --MIAMI: Done
+void
+CPed::Fall(void)
+{
+ if (m_getUpTimer != UINT32_MAX && CTimer::GetTimeInMilliseconds() > m_getUpTimer && bIsStanding)
+ ClearFall();
+
+ 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 {
- 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;
+ 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;
- 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 (time > 0.667f && time - fallAssoc->timeStep <= 0.667f) {
+ fallAssoc->SetCurrentTime(0.0f);
+ fallAssoc->SetRun();
}
}
- if (nGenerateWaterCircles && CTimer::GetTimeInMilliseconds() >= nGenerateWaterCircles) {
- CVector pos = GetPosition();
- float level = 0.0f;
- if (CWaterLevel::GetWaterLevel(pos, &level, false))
- pos.z = level;
+ } else if ((bKnockedUpIntoAir || bKnockedOffBike) && bIsStanding && !bWasStanding) {
+ fallAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_FALL_BACK);
- 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 (!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;
}
}
- 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) {
- 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);
+// --MIAMI: Done
+bool
+CPed::CheckIfInTheAir(void)
+{
+ if (bInVehicle)
+ return false;
+
+ CVector pos = GetPosition();
+ CColPoint foundColPoint;
+ CEntity *foundEntity;
+
+ float startZ = pos.z - 1.54f;
+ bool foundGround = CWorld::ProcessVerticalLine(pos, startZ, foundColPoint, foundEntity, true, true, false, true, false, false, nil);
+ if (!foundGround && m_nPedState != PED_JUMP)
+ {
+ pos.z -= FEET_OFFSET;
+ if (CWorld::TestSphereAgainstWorld(pos, 0.15f, this, true, false, false, false, false, false))
+ foundGround = true;
+ }
+ return !foundGround;
+}
+
+// --MIAMI: Done
+void
+CPed::SetInTheAir(void)
+{
+ if (bIsInTheAir)
+ return;
+
+ bIsInTheAir = true;
+ CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_FALL_GLIDE, 4.0f);
+
+ if (m_nPedState == PED_ATTACK) {
+ ClearAttack();
+ ClearPointGunAt();
+ } else if (m_nPedState == PED_FIGHT) {
+ EndFight(ENDFIGHT_FAST);
+ }
+
+}
+
+// --MIAMI: Done
+void
+CPed::InTheAir(void)
+{
+ CColPoint foundCol;
+ CEntity *foundEnt;
+
+ CVector ourPos = GetPosition();
+ CVector bitBelow = GetPosition();
+ bitBelow.z -= 4.04f;
+
+ 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 || bIsStanding)
+ SetLanding();
+ } 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);
}
}
- } else
- bTouchingWater = false;
+ }
}
// --MIAMI: Done
void
-CPed::SetSolicit(uint32 time)
+CPed::SetLanding(void)
{
- if (m_nPedState == PED_SOLICIT || !IsPedInControl() || !m_carInObjective)
+ if (DyingOrDead())
return;
- if (CharCreatedBy != MISSION_CHAR && m_carInObjective->m_nNumGettingIn == 0
- && CTimer::GetTimeInMilliseconds() < m_objectiveTimer) {
- if (m_vehEnterType == CAR_DOOR_LF) {
- m_fRotationDest = m_carInObjective->GetForward().Heading() - HALFPI;
- } else {
- m_fRotationDest = m_carInObjective->GetForward().Heading() + HALFPI;
+ CAnimBlendAssociation *fallAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_FALL_FALL);
+ CAnimBlendAssociation *landAssoc;
+
+ if (fallAssoc && bIsDrowning)
+ return;
+
+ RpAnimBlendClumpSetBlendDeltas(GetClump(), ASSOC_PARTIAL, -1000.0f);
+ 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;
}
- if (Abs(m_fRotationDest - m_fRotationCur) < HALFPI) {
- m_standardTimer = CTimer::GetTimeInMilliseconds() + time;
+ } else {
+ landAssoc = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_FALL_LAND);
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_FALL_LAND, 1.0f);
+ }
- if(!m_carInObjective->bIsVan && !m_carInObjective->bIsBus)
- m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_HOOKERTALK, 4.0f);
+ landAssoc->SetFinishCallback(PedLandCB, this);
+ bIsInTheAir = false;
+ bIsLanding = true;
+}
- SetPedState(PED_SOLICIT);
+// --MIAMI: Done
+void
+CPed::SetGetUp(void)
+{
+ if (m_nPedState == PED_GETUP && bGetUpAnimStarted)
+ return;
+
+ if (!CanSetPedState())
+ return;
+
+ if (m_fHealth >= 1.0f || IsPedHeadAbovePos(-0.3f)) {
+ if (bUpdateAnimHeading) {
+ m_fRotationCur = CGeneral::LimitRadianAngle(m_fRotationCur);
+ m_fRotationCur -= HALFPI;
+ bUpdateAnimHeading = false;
+ }
+ if (m_nPedState != PED_GETUP) {
+ SetStoredState();
+ SetPedState(PED_GETUP);
+ }
+
+ CVehicle *collidingVeh = (CVehicle*)m_pCollidingEntity;
+ CVehicle *veh = (CVehicle*)CPedPlacement::IsPositionClearOfCars(&GetPosition());
+ 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(),
+ aTempPedColPts, nil, nil) > 0)) {
+
+ bGetUpAnimStarted = false;
+ if (IsPlayer())
+ InflictDamage(nil, WEAPONTYPE_RUNOVERBYCAR, CTimer::GetTimeStep(), PEDPIECE_TORSO, 0);
+ 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)) {
+ CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_RUN, 8.0f);
+ } else {
+ CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_IDLE_STANCE, 8.0f);
+ }
+ animAssoc->flags |= ASSOC_DELETEFADEDOUT;
+ }
+
+ 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);
+ } else {
+ m_fHealth = 0.0f;
+ SetDie(NUM_STD_ANIMS, 4.0f, 0.0f);
+ }
+}
+
+// --MIAMI: Done
+void
+CPed::Mug(void)
+{
+ if (m_pSeekTarget && m_pSeekTarget->IsPed()) {
+
+ if (CTimer::GetTimeInMilliseconds() <= m_attackTimer - 2000) {
+ if ((m_pSeekTarget->GetPosition() - GetPosition()).Magnitude() > 3.0f)
+ m_wepSkills = 50;
+
+ Say(SOUND_PED_MUGGING);
+ ((CPed*)m_pSeekTarget)->Say(SOUND_PED_ROBBED);
+ } else {
+ SetWanderPath(CGeneral::GetRandomNumber() & 7);
+ SetFlee(m_pSeekTarget, 20000);
+ }
+
+ } else {
+ SetIdle();
+ }
+}
+
+// --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)
+{
+ if (CTimer::GetTimeInMilliseconds() > m_lookTimer) {
+ m_lookTimer = CTimer::GetTimeInMilliseconds() + time;
+ }
+}
+
+// --MIAMI: Done
+void
+CPed::SetAttackTimer(uint32 time)
+{
+ if (CTimer::GetTimeInMilliseconds() > m_attackTimer)
+ m_attackTimer = Max(m_shootTimer, CTimer::GetTimeInMilliseconds()) + time;
+}
+
+// --MIAMI: Done
+void
+CPed::SetShootTimer(uint32 time)
+{
+ if (CTimer::GetTimeInMilliseconds() > m_shootTimer) {
+ m_shootTimer = CTimer::GetTimeInMilliseconds() + time;
}
}
// --MIAMI: Done
+void
+CPed::ClearLook(void)
+{
+ RestorePreviousState();
+ ClearLookFlag();
+}
+
+// --MIAMI: Done
+void
+CPed::Look(void)
+{
+ TurnBody();
+}
+
+// --MIAMI: Done
bool
-CPed::SetFollowPathStatic(void)
+CPed::TurnBody(void)
{
- ClearFollowPath();
- if (sq(m_followPathAbortDist) > (GetPosition() - m_followPathDestPos).MagnitudeSqr()
- && CWorld::IsWanderPathClear(GetPosition(), m_followPathDestPos, 0.5f, 4)) {
+ bool turnDone = true;
- 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);
+ if (m_pLookTarget)
+ m_fLookDirection = CGeneral::GetRadianAngleBetweenPoints(
+ m_pLookTarget->GetPosition().x,
+ m_pLookTarget->GetPosition().y,
+ GetPosition().x,
+ GetPosition().y);
+
+ float limitedLookDir = CGeneral::LimitRadianAngle(m_fLookDirection);
+ float currentRot = m_fRotationCur;
+
+ if (currentRot - PI > limitedLookDir)
+ limitedLookDir += 2 * PI;
+ else if (PI + currentRot < limitedLookDir)
+ limitedLookDir -= 2 * PI;
+
+ float neededTurn = currentRot - limitedLookDir;
+ m_fRotationDest = limitedLookDir;
+
+ if (Abs(neededTurn) > 0.05f) {
+ turnDone = false;
+ currentRot -= neededTurn * 0.2f;
+ }
+
+ m_fRotationCur = currentRot;
+ m_fLookDirection = limitedLookDir;
+ 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_FOLLOW_PATH)
+ return;
+
+ if (!CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->IsFlagSet(WEAPONFLAG_CANAIM_WITHARM)) {
+ ClearPointGunAt();
+ }
+
+ if (m_nPedState != PED_SEEK_POS)
+ SetStoredState();
+
+ SetPedState(PED_SEEK_POS);
+ m_distanceToCountSeekDone = distanceToCountDone;
+ m_vecSeekPos = pos;
+}
+// --MIAMI: Done
+void
+CPed::SetSeek(CEntity *seeking, float distanceToCountDone)
+{
+ if (!IsPedInControl())
+ return;
+
+ if (m_nPedState == PED_SEEK_ENTITY && m_pSeekTarget == seeking)
+ return;
+
+ if (!seeking || m_nPedState == PED_FOLLOW_PATH)
+ return;
+
+ if (m_nPedState != PED_SEEK_ENTITY)
+ SetStoredState();
+
+ SetPedState(PED_SEEK_ENTITY);
+ m_distanceToCountSeekDone = distanceToCountDone;
+ m_pSeekTarget = seeking;
+ m_pSeekTarget->RegisterReference((CEntity **) &m_pSeekTarget);
+ SetMoveState(PEDMOVE_STILL);
+}
+
+// --MIAMI: Done
+void
+CPed::ClearSeek(void)
+{
+ SetIdle();
+ bRunningToPhone = false;
+}
+
+// --MIAMI: Done
+bool
+CPed::Seek(void)
+{
+ float distanceToCountItDone = m_distanceToCountSeekDone;
+ eMoveState nextMove = PEDMOVE_NONE;
+
+ if (m_objective != OBJECTIVE_ENTER_CAR_AS_DRIVER) {
+
+ if (m_nPedState != PED_EXIT_TRAIN && m_nPedState != PED_ENTER_TRAIN && m_nPedState != PED_SEEK_IN_BOAT &&
+ m_objective != OBJECTIVE_ENTER_CAR_AS_PASSENGER && m_objective != OBJECTIVE_SOLICIT_VEHICLE && !bDuckAndCover) {
+
+ if ((!m_pedInObjective || !m_pedInObjective->bInVehicle)
+ && (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)->IsCar()) {
+ distanceToCountItDone = 2.5f;
+ } else {
+ CVehicleModelInfo *vehModel = (CVehicleModelInfo *)CModelInfo::GetModelInfo(obstacle->GetModelIndex());
+ float yLength = vehModel->GetColModel()->boundingBox.max.y
+ - vehModel->GetColModel()->boundingBox.min.y;
+ distanceToCountItDone = yLength * 0.55f;
+ }
+ }
+ }
}
- SetPedState(PED_NONE);
- return true;
+ }
+
+ 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) {
+
+ if (m_objective == OBJECTIVE_FOLLOW_CHAR_IN_FORMATION) {
+
+ if (m_pedInObjective->m_nMoveState != PEDMOVE_STILL)
+ nextMove = m_pedInObjective->m_nMoveState;
+ } else
+ nextMove = PEDMOVE_WALK;
+
+ } else if (m_objective != OBJECTIVE_FOLLOW_CHAR_IN_FORMATION) {
+
+ 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;
+
+ } else if (seekPosDist <= 2.0f) {
+
+ if (m_pedInObjective->m_nMoveState != PEDMOVE_STILL)
+ nextMove = m_pedInObjective->m_nMoveState;
+
} else {
- ThePaths.DoPathSearch(PATH_PED, GetPosition(), -1, m_followPathDestPos, m_pathNodesToGo, &m_nNumPathNodes,
- ARRAY_SIZE(m_pathNodesToGo), nil, nil, 999999.9f, -1);
+ nextMove = PEDMOVE_RUN;
+ }
- 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];
+ if (m_nPedState == PED_SEEK_ENTITY) {
+ if (m_pSeekTarget->IsPed()) {
+ if (((CPed*)m_pSeekTarget)->bInVehicle)
+ distanceToCountItDone += 2.0f;
+ }
+ }
+
+ CVector *nextNode = SeekFollowingPath();
+
+ if (nextNode || seekPosDist >= distanceToCountItDone) {
+ if (bIsRunning && nextMove != PEDMOVE_SPRINT)
+ nextMove = PEDMOVE_RUN;
+
+ if (CTimer::GetTimeInMilliseconds() <= m_nPedStateTimer) {
+
+ if (m_actionX != 0.0f && m_actionY != 0.0f) {
+
+ m_fRotationDest = CGeneral::GetRadianAngleBetweenPoints(
+ m_actionX, m_actionY,
+ GetPosition().x, GetPosition().y);
+
+ float neededTurn = Abs(m_fRotationDest - m_fRotationCur);
+
+ if (neededTurn > PI)
+ neededTurn = TWOPI - neededTurn;
+
+ if (neededTurn > HALFPI) {
+ if (seekPosDist >= 1.0f) {
+ if (seekPosDist < 2.0f) {
+ if (bIsRunning)
+ nextMove = PEDMOVE_RUN;
+ else
+ nextMove = PEDMOVE_WALK;
+ }
+ } else {
+ nextMove = PEDMOVE_STILL;
+ }
+ }
+
+ CVector2D moveDist(GetPosition().x - m_actionX, GetPosition().y - m_actionY);
+ if (moveDist.Magnitude() < 0.5f) {
+ m_nPedStateTimer = 0;
+ m_actionX = 0.f;
+ m_actionY = 0.f;
}
- --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;
+ } else {
+ 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);
+
+ if (neededTurn > PI)
+ neededTurn = TWOPI - neededTurn;
+
+ if (neededTurn > HALFPI) {
+ if (seekPosDist >= 1.0f && neededTurn <= DEGTORAD(135.0f)) {
+ if (seekPosDist < 2.0f)
+ nextMove = PEDMOVE_WALK;
+ } else {
+ nextMove = PEDMOVE_STILL;
}
}
+ }
- m_nCurPathNodeId = 0;
- if (m_pCurPathNode) {
- for (int j = 0; j < m_nNumPathNodes; ++j) {
- if (m_pathNodesToGo[j] == m_pCurPathNode) {
- m_nCurPathNodeId = j;
- break;
- }
+ 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_nPedState != PED_FOLLOW_PATH && m_objective != OBJECTIVE_GOTO_CHAR_ON_FOOT && m_nWaitState == WAITSTATE_FALSE)) {
+
+ SetMoveState(nextMove);
+ }
+
+ SetMoveAnim();
+ return false;
+ }
+
+ if ((m_objective != OBJECTIVE_FOLLOW_CHAR_IN_FORMATION || m_pedInObjective->m_nMoveState == PEDMOVE_STILL) && m_nMoveState != PEDMOVE_STILL) {
+ m_nPedStateTimer = 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_SPRINT_TO_AREA ||
+ m_objective == OBJECTIVE_GOTO_AREA_ANY_MEANS || IsUseAttractorObjective(m_objective)) {
+
+ if (m_pNextPathNode)
+ m_pNextPathNode = nil;
+ else
+ bScriptObjectiveCompleted = true;
+
+ bUsePedNodeSeek = true;
+ }
+
+ return true;
+}
+
+// --MIAMI: Done
+void
+CPed::SetFlee(CVector2D const &from, int time)
+{
+ if (CTimer::GetTimeInMilliseconds() < m_nPedStateTimer || !IsPedInControl() || bKindaStayInSamePlace)
+ return;
+
+ if (m_nPedState != PED_FLEE_ENTITY) {
+ SetStoredState();
+ SetPedState(PED_FLEE_POS);
+ SetMoveState(PEDMOVE_RUN);
+ m_fleeFromPos = from;
+ }
+
+ bUsePedNodeSeek = true;
+ m_pNextPathNode = nil;
+ m_fleeTimer = CTimer::GetTimeInMilliseconds() + time;
+
+ float angleToFace = CGeneral::GetRadianAngleBetweenPoints(
+ GetPosition().x, GetPosition().y,
+ from.x, from.y);
+
+ m_fRotationDest = CGeneral::LimitRadianAngle(angleToFace);
+ if (m_fRotationCur - PI > m_fRotationDest) {
+ m_fRotationDest += 2 * PI;
+ } else if (PI + m_fRotationCur < m_fRotationDest) {
+ m_fRotationDest -= 2 * PI;
+ }
+}
+
+// --MIAMI: Done
+void
+CPed::SetFlee(CEntity *fleeFrom, int time)
+{
+ if (!IsPedInControl() || bKindaStayInSamePlace || !fleeFrom)
+ return;
+
+ SetStoredState();
+ SetPedState(PED_FLEE_ENTITY);
+ bUsePedNodeSeek = true;
+ SetMoveState(PEDMOVE_RUN);
+ m_fleeFrom = fleeFrom;
+ m_fleeFrom->RegisterReference((CEntity **) &m_fleeFrom);
+
+ if (time <= 0)
+ m_fleeTimer = 0;
+ else
+ m_fleeTimer = CTimer::GetTimeInMilliseconds() + time;
+
+ float angleToFace = CGeneral::GetRadianAngleBetweenPoints(
+ GetPosition().x, GetPosition().y,
+ fleeFrom->GetPosition().x, fleeFrom->GetPosition().y);
+
+ m_fRotationDest = CGeneral::LimitRadianAngle(angleToFace);
+ if (m_fRotationCur - PI > m_fRotationDest) {
+ m_fRotationDest += 2 * PI;
+ } else if (PI + m_fRotationCur < m_fRotationDest) {
+ m_fRotationDest -= 2 * PI;
+ }
+}
+
+// --MIAMI: Done
+void
+CPed::ClearFlee(void)
+{
+ RestorePreviousState();
+ bUsePedNodeSeek = false;
+ m_standardTimer = 0;
+ m_fleeTimer = 0;
+}
+
+// --MIAMI: Done
+void
+CPed::Flee(void)
+{
+ if (CTimer::GetTimeInMilliseconds() > m_fleeTimer && m_fleeTimer) {
+ bool mayFinishFleeing = true;
+ if (m_nPedState == PED_FLEE_ENTITY) {
+ if ((CVector2D(GetPosition()) - ms_vec2DFleePosition).MagnitudeSqr() < sq(30.0f))
+ mayFinishFleeing = false;
+ }
+
+ 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) {
+ 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);
+ }
+ return;
+ }
+ 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;
+ uint8 curDirectionShouldBe = 9; // means not defined yet
+
+ if (m_nPedStateTimer < CTimer::GetTimeInMilliseconds()
+ && m_collidingThingTimer < CTimer::GetTimeInMilliseconds()) {
+
+ if (m_pNextPathNode && CTimer::GetTimeInMilliseconds() > m_standardTimer) {
+
+ curDirectionShouldBe = CGeneral::GetNodeHeadingFromVector(GetPosition().x - ms_vec2DFleePosition.x, GetPosition().y - ms_vec2DFleePosition.y);
+ if (m_nPathDir < curDirectionShouldBe)
+ m_nPathDir += 8;
+
+ int dirDiff = m_nPathDir - curDirectionShouldBe;
+ if (dirDiff > 2 && dirDiff < 6) {
+ realLastNode = nil;
+ m_pLastPathNode = m_pNextPathNode;
+ m_pNextPathNode = nil;
}
}
- m_pCurPathNode = m_pathNodesToGo[m_nCurPathNodeId];
- PedState oldLastState = m_nLastPedState;
- m_nLastPedState = PED_NONE;
- SetStoredState();
- if (m_nLastPedState == PED_NONE)
- m_nLastPedState = oldLastState;
- m_nPedState = PED_FOLLOW_PATH;
- m_nMoveState = m_followPathMoveState;
- return true;
+ if (m_pNextPathNode) {
+ m_vecSeekPos = CPathFind::TakeWidthIntoAccountForWandering(m_pNextPathNode, m_randomSeed);
+ if (m_nMoveState == PEDMOVE_RUN)
+ bIsRunning = true;
+
+ eMoveState moveState = m_nMoveState;
+ if (Seek()) {
+ realLastNode = m_pLastPathNode;
+ m_pLastPathNode = m_pNextPathNode;
+ m_pNextPathNode = nil;
+ }
+ bIsRunning = false;
+ SetMoveState(moveState);
+ }
+ }
+
+ if (!m_pNextPathNode) {
+ if (curDirectionShouldBe == 9) {
+ curDirectionShouldBe = CGeneral::GetNodeHeadingFromVector(GetPosition().x - ms_vec2DFleePosition.x, GetPosition().y - ms_vec2DFleePosition.y);
+ }
+ ThePaths.FindNextNodeWandering(PATH_PED, GetPosition(), &m_pLastPathNode, &m_pNextPathNode,
+ curDirectionShouldBe,
+ &nextDirection);
+
+ if (curDirectionShouldBe < nextDirection)
+ curDirectionShouldBe += 8;
+
+ if (m_pNextPathNode && m_pNextPathNode != realLastNode && m_pNextPathNode != m_pLastPathNode && curDirectionShouldBe - nextDirection != 4) {
+ m_nPathDir = nextDirection;
+ m_standardTimer = CTimer::GetTimeInMilliseconds() + 2000;
+ } else {
+ bUsePedNodeSeek = false;
+ SetMoveState(PEDMOVE_RUN);
+ Flee();
+ }
+ }
+ return;
+ }
+
+ if ((m_nPedState == PED_FLEE_ENTITY || m_nPedState == PED_ON_FIRE) && m_nPedStateTimer < CTimer::GetTimeInMilliseconds()) {
+
+ float angleToFleeFromPos = CGeneral::GetRadianAngleBetweenPoints(
+ GetPosition().x,
+ GetPosition().y,
+ ms_vec2DFleePosition.x,
+ ms_vec2DFleePosition.y);
+
+ m_fRotationDest = CGeneral::LimitRadianAngle(angleToFleeFromPos);
+
+ if (m_fRotationCur - PI > m_fRotationDest)
+ m_fRotationDest += TWOPI;
+ else if (PI + m_fRotationCur < m_fRotationDest)
+ m_fRotationDest -= TWOPI;
+ }
+
+ if (CTimer::GetTimeInMilliseconds() >= m_collidingThingTimer)
+ return;
+
+ if (!m_collidingEntityWhileFleeing)
+ return;
+
+ double collidingThingPriorityMult = (double)(m_collidingThingTimer - CTimer::GetTimeInMilliseconds()) * 2.0 / 2500;
+
+ if (collidingThingPriorityMult <= 1.5) {
+ double angleToFleeEntity = CGeneral::GetRadianAngleBetweenPoints(
+ GetPosition().x,
+ GetPosition().y,
+ m_collidingEntityWhileFleeing->GetPosition().x,
+ m_collidingEntityWhileFleeing->GetPosition().y);
+ angleToFleeEntity = CGeneral::LimitRadianAngle(angleToFleeEntity);
+
+ double angleToFleeCollidingThing = CGeneral::GetRadianAngleBetweenPoints(
+ m_vecDamageNormal.x,
+ m_vecDamageNormal.y,
+ 0.0f,
+ 0.0f);
+ angleToFleeCollidingThing = CGeneral::LimitRadianAngle(angleToFleeCollidingThing);
+
+ if (angleToFleeEntity - PI > angleToFleeCollidingThing)
+ angleToFleeCollidingThing += TWOPI;
+ else if (PI + angleToFleeEntity < angleToFleeCollidingThing)
+ angleToFleeCollidingThing -= TWOPI;
+
+ if (collidingThingPriorityMult <= 1.0f) {
+ // Range [0.0, 1.0]
+
+ float angleToFleeBoth = (angleToFleeCollidingThing + angleToFleeEntity) * 0.5f;
+
+ if (m_fRotationDest - PI > angleToFleeBoth)
+ angleToFleeBoth += TWOPI;
+ else if (PI + m_fRotationDest < angleToFleeBoth)
+ angleToFleeBoth -= TWOPI;
+
+ m_fRotationDest = (1.0f - collidingThingPriorityMult) * m_fRotationDest + collidingThingPriorityMult * angleToFleeBoth;
} 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);
+ // Range (1.0, 1.5]
+
+ double adjustedMult = (collidingThingPriorityMult - 1.0f) * 2.0f;
+ m_fRotationDest = angleToFleeEntity * (1.0 - adjustedMult) + adjustedMult * angleToFleeCollidingThing;
+ }
+ } else {
+ m_fRotationDest = CGeneral::GetRadianAngleBetweenPoints(
+ m_vecDamageNormal.x,
+ m_vecDamageNormal.y,
+ 0.0f,
+ 0.0f);
+ m_fRotationDest = CGeneral::LimitRadianAngle(m_fRotationDest);
+ }
+
+ m_fRotationCur = CGeneral::LimitRadianAngle(m_fRotationCur);
+
+ if (m_fRotationCur - PI > m_fRotationDest)
+ m_fRotationDest += TWOPI;
+ else if (PI + m_fRotationCur < m_fRotationDest)
+ m_fRotationDest -= TWOPI;
+
+}
+
+// "Wander range" state is unused in game, and you can't use it without SetWanderRange anyway
+void
+CPed::WanderRange(void)
+{
+ bool arrived = Seek();
+ if (arrived) {
+ Idle();
+ if ((m_randomSeed + 3 * CTimer::GetFrameCounter()) % 1000 > 997) {
+ CVector2D newCoords2D = m_wanderRangeBounds->GetRandomPointInRange();
+ SetSeek(CVector(newCoords2D.x, newCoords2D.y, GetPosition().z), 2.5f);
+ }
+ }
+}
+
+// --MIAMI: Done
+bool
+CPed::SetWanderPath(int8 pathStateDest)
+{
+ uint8 nextPathState;
+
+ if (IsPlayer())
+ return false;
+
+ if (IsPedInControl()) {
+ if (bKindaStayInSamePlace) {
+ SetIdle();
+ return false;
+ } else {
+ m_nPathDir = pathStateDest;
+ if (pathStateDest == 0)
+ pathStateDest = CGeneral::GetRandomNumberInRange(1, 7);
+
+ ThePaths.FindNextNodeWandering(PATH_PED, GetPosition(), &m_pLastPathNode, &m_pNextPathNode,
+ m_nPathDir, &nextPathState);
+
+ // Circular loop until we find a node for current m_nPathDir
+ while (!m_pNextPathNode) {
+ m_nPathDir = (m_nPathDir+1) % 8;
+
+ // We're at where we started and couldn't find any node
+ if (m_nPathDir == pathStateDest) {
+ ClearAll();
+ SetIdle();
+ return false;
+ }
+ ThePaths.FindNextNodeWandering(PATH_PED, GetPosition(), &m_pLastPathNode, &m_pNextPathNode,
+ m_nPathDir, &nextPathState);
}
- SetPedState(PED_NONE);
+
+ // We did it, save next path state and return true
+ m_nPathDir = nextPathState;
+ SetPedState(PED_WANDER_PATH);
+ SetMoveState(PEDMOVE_WALK);
+ bIsRunning = false;
return true;
}
+ } else {
+ m_nPathDir = pathStateDest;
+ bStartWanderPathOnFoot = true;
+ return false;
+ }
+}
+
+// --MIAMI: Done
+void
+CPed::WanderPath(void)
+{
+ if (!m_pNextPathNode) {
+ printf("THIS SHOULDN@T HAPPEN TOO OFTEN\n");
+ SetIdle();
+ return;
+ }
+ if (m_nWaitState == WAITSTATE_FALSE) {
+ if (m_nMoveState == PEDMOVE_STILL || m_nMoveState == PEDMOVE_NONE)
+ SetMoveState(PEDMOVE_WALK);
+ }
+ 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;
+ uint8 randVal = (m_randomSeed + 3 * CTimer::GetFrameCounter()) % 100;
+
+ // We don't prefer 180-degree turns in normal situations
+ uint8 dirWeWouldntPrefer = m_nPathDir;
+ if (dirWeWouldntPrefer <= 3)
+ dirWeWouldntPrefer += 4;
+ else
+ dirWeWouldntPrefer -= 4;
+
+ 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;
+ m_nPathDir %= 8;
+ }
+ } else {
+ m_nPathDir -= 2;
+ if (m_nPathDir < 0)
+ m_nPathDir += 8;
+ }
+
+ m_pLastPathNode = m_pNextPathNode;
+ ThePaths.FindNextNodeWandering(PATH_PED, GetPosition(), &m_pLastPathNode, &m_pNextPathNode,
+ m_nPathDir, &dirToSet);
+
+ 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) {
+ tryCount++;
+ m_nPathDir = (m_nPathDir + 1) % 8;
+
+ // We're at where we started and couldn't find any node
+ if (tryCount > 7) {
+ if (!nodeWeWouldntPrefer) {
+ ClearAll();
+ SetIdle();
+ // Probably this text carried over here after copy-pasting this loop from early version of SetWanderPath.
+ Error("Can't find valid path node, SetWanderPath, Ped.cpp");
+ return;
+ }
+ m_pNextPathNode = nodeWeWouldntPrefer;
+ dirToSet = dirWeWouldntPrefer2;
+ } else {
+ ThePaths.FindNextNodeWandering(PATH_PED, GetPosition(), &m_pLastPathNode, &m_pNextPathNode,
+ m_nPathDir, &dirToSet);
+ if (m_pNextPathNode) {
+ if (dirToSet == dirWeWouldntPrefer) {
+ nodeWeWouldntPrefer = m_pNextPathNode;
+ dirWeWouldntPrefer2 = dirToSet;
+ 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;
+ }
+ }
+ }
+ }
+
+ m_nPathDir = dirToSet;
+ if (m_pLastPathNode == m_pNextPathNode) {
+ m_pNextPathNode = previousLastNode;
+ SetWaitState(WAITSTATE_DOUBLEBACK, nil);
+ Say(SOUND_PED_WAIT_DOUBLEBACK);
+ } else if (ThePaths.TestForPedTrafficLight(m_pLastPathNode, m_pNextPathNode)) {
+ SetWaitState(WAITSTATE_TRAFFIC_LIGHTS, nil);
+ } else if (ThePaths.TestCrossesRoad(m_pLastPathNode, m_pNextPathNode)) {
+ SetWaitState(WAITSTATE_CROSS_ROAD, nil);
+ } else if (m_pNextPathNode == previousLastNode) {
+ SetWaitState(WAITSTATE_DOUBLEBACK, nil);
+ Say(SOUND_PED_WAIT_DOUBLEBACK);
}
}
+// --MIAMI: Done
+void
+CPed::Avoid(void)
+{
+ CPed *nearestPed;
+
+ if(m_pedStats->m_temper > m_pedStats->m_fear && m_pedStats->m_temper > 50)
+ return;
+
+ if (CTimer::GetTimeInMilliseconds() > m_nPedStateTimer) {
+
+ if (m_nMoveState != PEDMOVE_NONE && m_nMoveState != PEDMOVE_STILL) {
+ nearestPed = m_nearPeds[0];
+
+ if (nearestPed && nearestPed->m_nPedState != PED_DEAD && nearestPed != m_pSeekTarget && nearestPed != m_pedInObjective) {
+
+ // Check if this ped wants to avoid the nearest one
+ if (CPedType::GetAvoid(m_nPedType) & CPedType::GetFlag(nearestPed->m_nPedType)) {
+
+ // Further codes checks whether the distance between us and ped will be equal or below 1.0, if we walk up to him by 1.25 meters.
+ // If so, we want to avoid it, so we turn our body 45 degree and look to somewhere else.
+
+ // Game converts from radians to degress and back again here, doesn't make much sense
+ CVector2D forward(-Sin(m_fRotationCur), Cos(m_fRotationCur));
+ forward.Normalise(); // this is kinda pointless
+
+ // Move forward 1.25 meters
+ CVector2D testPosition = CVector2D(GetPosition()) + forward*1.25f;
+
+ // Get distance to ped we want to avoid
+ CVector2D distToPed = CVector2D(nearestPed->GetPosition()) - testPosition;
+
+ if (distToPed.Magnitude() <= 1.0f && OurPedCanSeeThisOne((CEntity*)nearestPed)) {
+ m_nPedStateTimer = CTimer::GetTimeInMilliseconds()
+ + 500 + (m_randomSeed + 3 * CTimer::GetFrameCounter())
+ % 1000 / 5;
+
+ m_fRotationDest += DEGTORAD(45.0f);
+ if (!bIsLooking) {
+ SetLookFlag(nearestPed, false);
+ SetLookTimer(CGeneral::GetRandomNumberInRange(500, 800));
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+// --MIAMI: Done
+CVector*
+CPed::SeekFollowingPath(void)
+{
+ 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
@@ -17143,6 +6359,75 @@ CPed::SetFollowPath(CVector dest, float radius, eMoveState state, CEntity* walkA
// --MIAMI: Done
bool
+CPed::SetFollowPathStatic(void)
+{
+ 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);
@@ -17505,8 +6790,8 @@ CPed::SetFollowPathDynamic(void)
if (m_nLastPedState == PED_NONE)
m_nLastPedState = oldLastState;
- m_nPedState = PED_FOLLOW_PATH;
- m_nMoveState = m_followPathMoveState;
+ SetPedState(PED_FOLLOW_PATH);
+ SetMoveState(m_followPathMoveState);
return true;
} else {
@@ -17525,691 +6810,678 @@ CPed::SetFollowPathDynamic(void)
}
}
+// --MIAMI: Done
void
-AddYardieDoorSmoke(CVehicle *veh, uint32 doorNode)
+CPed::ClearFollowPath()
{
- 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());
+ for (int i = 0; i < ARRAY_SIZE(m_pathNodesToGo); i++) {
+ m_pathNodesToGo[i] = nil;
}
+ m_nNumPathNodes = 0;
+ m_nCurPathNodeId = 0;
}
// --MIAMI: Done
-// wantedDoorNode = 0 means that func. will determine it
void
-CPed::SetExitCar(CVehicle *veh, uint32 wantedDoorNode)
+CPed::FollowPath(void)
{
- uint32 optedDoorNode = wantedDoorNode;
- bool teleportNeeded = false;
- bool isLow = !!veh->bLowVehicle;
+ 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;
- 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;
+ if (Seek()) {
+ if (m_nCurPathNodeId == m_nNumPathNodes) {
+ RestorePreviousState();
+ ClearFollowPath();
+ SetFollowPath(m_followPathDestPos, m_followPathAbortDist, m_followPathMoveState, m_followPathWalkAroundEnt,
+ m_followPathTargetEnt, m_pathNodeTimer - CTimer::GetTimeInMilliseconds());
}
}
- return;
+ } else {
+ RestorePreviousState();
+ ClearFollowPath();
+ m_pathNodeTimer = 0;
}
}
+}
+
+// --MIAMI: Done
+void
+CPed::SetEvasiveStep(CEntity *reason, uint8 animType)
+{
+ AnimationId stepAnim;
- if (m_nPedState == PED_EXIT_CAR || m_nPedState == PED_DRAG_FROM_CAR)
+ if (m_nPedState == PED_STEP_AWAY || !IsPedInControl() || ((IsPlayer() || !bRespondsToThreats) && animType == 0))
return;
- m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f);
- m_vecTurnSpeed = CVector(0.0f, 0.0f, 0.0f);
- if (wantedDoorNode == 0) {
- 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_LR;
- } else {
- 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;
+ float angleToFace = CGeneral::GetRadianAngleBetweenPoints(
+ reason->GetPosition().x, reason->GetPosition().y,
+ GetPosition().x, GetPosition().y);
+ angleToFace = CGeneral::LimitRadianAngle(angleToFace);
+ m_fRotationCur = CGeneral::LimitRadianAngle(m_fRotationCur);
+ float neededTurn = Abs(angleToFace - m_fRotationCur);
+ bool vehPressedHorn = false;
- break;
- }
- }
+ if (neededTurn > PI)
+ neededTurn = TWOPI - neededTurn;
+
+ CVehicle *veh = (CVehicle*)reason;
+ if (reason->IsVehicle() && veh->IsCar()) {
+ if (veh->m_nCarHornTimer != 0) {
+ vehPressedHorn = true;
+ if (!IsPlayer())
+ animType = 1;
}
}
- bool someoneExitsFromOurExitDoor = false;
- bool someoneEntersFromOurExitDoor = false;
- 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;
+ if (neededTurn <= DEGTORAD(90.0f) || veh->GetModelIndex() == MI_RCBANDIT || vehPressedHorn || animType != 0) {
+ SetLookFlag(veh, true);
+ if ((CGeneral::GetRandomNumber() & 1) && veh->GetModelIndex() != MI_RCBANDIT && animType == 0) {
+ stepAnim = ANIM_IDLE_TAXI;
+
+ } else {
+ float vehDirection = CGeneral::GetRadianAngleBetweenPoints(
+ veh->m_vecMoveSpeed.x, veh->m_vecMoveSpeed.y,
+ 0.0f, 0.0f);
+
+ // Let's turn our back to the "reason"
+ angleToFace += PI;
+
+ if (angleToFace > PI)
+ angleToFace -= TWOPI;
+
+ // We don't want to run towards car's direction
+ float dangerZone = angleToFace - vehDirection;
+ dangerZone = CGeneral::LimitRadianAngle(dangerZone);
+
+ // So, add or subtract 90deg (jump to left/right) according to that
+ if (dangerZone > 0.0f)
+ angleToFace = vehDirection - HALFPI;
+ else
+ angleToFace = vehDirection + HALFPI;
+
+ stepAnim = NUM_STD_ANIMS;
+ if (animType == 0 || animType == 1)
+ stepAnim = ANIM_EV_STEP;
+ else if (animType == 2)
+ stepAnim = ANIM_HANDSCOWER;
}
- } 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 (!RpAnimBlendClumpGetAssociation(GetClump(), stepAnim)) {
+ CAnimBlendAssociation *stepAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, stepAnim, 8.0f);
+ stepAssoc->flags &= ~ASSOC_DELETEFADEDOUT;
+ stepAssoc->SetFinishCallback(PedEvadeCB, this);
+
+ if (animType == 0)
+ Say(SOUND_PED_EVADE);
+
+ m_fRotationCur = CGeneral::LimitRadianAngle(angleToFace);
+ ClearAimFlag();
+ SetStoredState();
+ SetPedState(PED_STEP_AWAY);
}
}
- if (someoneEntersFromOurExitDoor && m_objective == OBJECTIVE_LEAVE_CAR) {
- RestorePreviousObjective();
+}
+
+// --MIAMI: Done
+void
+CPed::SetEvasiveDive(CPhysical *reason, uint8 onlyRandomJump)
+{
+ if (!IsPedInControl() || !bRespondsToThreats)
return;
+
+ CAnimBlendAssociation *animAssoc;
+ float angleToFace, neededTurn;
+ bool handsUp = false;
+
+ angleToFace = m_fRotationCur;
+ CVehicle *veh = (CVehicle*) reason;
+ if (reason->IsVehicle() && veh->m_vehType == VEHICLE_TYPE_CAR && veh->m_nCarHornTimer != 0 && !IsPlayer()) {
+ onlyRandomJump = true;
}
- if (!someoneExitsFromOurExitDoor || m_nPedType == PEDTYPE_COP && veh->bIsBus) {
-#if defined GTAVC_JP_PATCH || defined FIX_BUGS
- if (veh->pDriver == this && !IsPlayer() && veh == CGameLogic::pShortCutTaxi) {
- m_objective = OBJECTIVE_NONE;
+
+ if (onlyRandomJump) {
+ if (reason) {
+ // Simple version of my bug fix below. Doesn't calculate "danger zone", selects jump direction randomly.
+ // Also doesn't include random hands up, sound etc. Only used on player ped and peds running from gun shots.
+
+ float vehDirection = CGeneral::GetRadianAngleBetweenPoints(
+ veh->m_vecMoveSpeed.x, veh->m_vecMoveSpeed.y,
+ 0.0f, 0.0f);
+ angleToFace = (CGeneral::GetRandomNumber() & 1) * PI + (-0.5f*PI) + vehDirection;
+ angleToFace = CGeneral::LimitRadianAngle(angleToFace);
+ }
+ } else {
+ if (IsPlayer()) {
+ ((CPlayerPed*)this)->m_nEvadeAmount = 5;
+ ((CPlayerPed*)this)->m_pEvadingFrom = reason;
+ reason->RegisterReference((CEntity**) &((CPlayerPed*)this)->m_pEvadingFrom);
return;
}
+
+ angleToFace = CGeneral::GetRadianAngleBetweenPoints(
+ reason->GetPosition().x, reason->GetPosition().y,
+ GetPosition().x, GetPosition().y);
+ angleToFace = CGeneral::LimitRadianAngle(angleToFace);
+ m_fRotationCur = CGeneral::LimitRadianAngle(m_fRotationCur);
+
+ // 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,
+ 0.0f, 0.0f);
+
+ // Let's turn our back to the "reason"
+ angleToFace += PI;
+
+ if (angleToFace > PI)
+ angleToFace -= 2 * PI;
+
+ // We don't want to dive towards car's direction
+ float dangerZone = angleToFace - vehDirection;
+ dangerZone = CGeneral::LimitRadianAngle(dangerZone);
+
+ // So, add or subtract 90deg (jump to left/right) according to that
+ if (dangerZone > 0.0f)
+ angleToFace = 0.5f * PI + vehDirection;
+ else
+ angleToFace = vehDirection - 0.5f * PI;
#endif
- bool thereIsRoom;
- if (canJumpOut) {
- thereIsRoom = 1;
+
+ neededTurn = Abs(angleToFace - m_fRotationCur);
+
+ if (neededTurn > PI)
+ neededTurn = 2 * PI - neededTurn;
+
+ if (neededTurn <= 0.5f*PI) {
+ if (CGeneral::GetRandomNumber() & 1)
+ handsUp = true;
} else {
- // Again, unused...
- // CVector exitPos = GetPositionToOpenCarDoor(veh, optedDoorNode);
- thereIsRoom = veh->IsRoomForPedToLeaveCar(optedDoorNode, nil);
+ if (CGeneral::GetRandomNumber() & 7)
+ return;
}
- if (!thereIsRoom) {
- bool trySideSeat = false;
- CPed *pedOnSideSeat;
- int firstOptedDoor = optedDoorNode;
- if (veh->IsBike()) {
- switch (optedDoorNode) {
- case CAR_DOOR_RF:
- optedDoorNode = CAR_DOOR_LF;
- break;
- case CAR_DOOR_RR:
- optedDoorNode = CAR_DOOR_LR;
- break;
- case CAR_DOOR_LF:
- optedDoorNode = CAR_DOOR_RF;
- 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;
+ // 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);
+ }
- 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;
+ if (handsUp || !IsPlayer() && m_pedStats->m_flags & STAT_NO_DIVE) {
+ m_fRotationCur = angleToFace;
+ ClearLookFlag();
+ ClearAimFlag();
+ SetLookFlag(reason, true);
+ animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_HANDSUP);
+ if (animAssoc)
+ return;
- 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;
+ animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_HANDSUP, 8.0f);
+ animAssoc->flags &= ~ASSOC_DELETEFADEDOUT;
+ animAssoc->SetFinishCallback(PedEvadeCB, this);
+ SetStoredState();
+ SetPedState(PED_STEP_AWAY);
+ } else {
+ m_fRotationCur = angleToFace;
+ ClearLookFlag();
+ ClearAimFlag();
+ SetStoredState();
+ SetPedState(PED_DIVE_AWAY);
+ animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_EV_DIVE, 8.0f);
+ animAssoc->SetFinishCallback(PedEvadeCB, this);
+ }
- 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;
+ if (reason->IsVehicle() && m_nPedType == PEDTYPE_COP) {
+ if (veh->pDriver && veh->pDriver->IsPlayer()) {
+ CWanted *wanted = FindPlayerPed()->m_pWanted;
+ wanted->RegisterCrime_Immediately(CRIME_RECKLESS_DRIVING, GetPosition(), (uintptr)this, false);
+ wanted->RegisterCrime_Immediately(CRIME_SPEEDING, GetPosition(), (uintptr)this, false);
+ }
+ }
+}
- break;
- default:
- break;
- }
- }
- if (trySideSeat) {
- if (!pedOnSideSeat || !IsPlayer() && CharCreatedBy != MISSION_CHAR)
- return;
+// --MIAMI: Done
+void
+CPed::PedEvadeCB(CAnimBlendAssociation* animAssoc, void* arg)
+{
+ CPed* ped = (CPed*)arg;
- switch (optedDoorNode) {
- case CAR_DOOR_RF:
- optedDoorNode = CAR_DOOR_LF;
- break;
- case CAR_DOOR_RR:
- optedDoorNode = CAR_DOOR_LR;
- break;
- case CAR_DOOR_LF:
- optedDoorNode = CAR_DOOR_RF;
- break;
- case CAR_DOOR_LR:
- optedDoorNode = CAR_DOOR_RR;
- break;
- default:
- break;
- }
- }
- // ...
- // CVector exitPos = GetPositionToOpenCarDoor(veh, optedDoorNode);
- if (!veh->IsRoomForPedToLeaveCar(optedDoorNode, nil)) {
- if (!IsPlayer() && CharCreatedBy != MISSION_CHAR)
- return;
+ if (!animAssoc) {
+ ped->ClearLookFlag();
+ if (ped->m_nPedState == PED_DIVE_AWAY || ped->m_nPedState == PED_STEP_AWAY)
+ ped->RestorePreviousState();
- // needed for PositionPedOutOfCollision()
- optedDoorNode = firstOptedDoor;
- m_vehEnterType = firstOptedDoor;
- PositionPedOutOfCollision();
- teleportNeeded = true;
- }
+ } else if (animAssoc->animId == ANIM_EV_DIVE) {
+ ped->bUpdateAnimHeading = true;
+ ped->ClearLookFlag();
+ if (ped->m_nPedState == PED_DIVE_AWAY) {
+ ped->m_getUpTimer = CTimer::GetTimeInMilliseconds() + 1;
+ ped->SetPedState(PED_FALL);
}
+ animAssoc->flags &= ~ASSOC_FADEOUTWHENDONE;
+ animAssoc->flags |= ASSOC_DELETEFADEDOUT;
- if (!teleportNeeded && veh->IsOnItsSide()) {
- m_vehEnterType = optedDoorNode;
- PositionPedOutOfCollision();
- teleportNeeded = true;
- }
+ } else if (animAssoc->flags & ASSOC_FADEOUTWHENDONE) {
+ ped->ClearLookFlag();
+ if (ped->m_nPedState == PED_DIVE_AWAY || ped->m_nPedState == PED_STEP_AWAY)
+ ped->RestorePreviousState();
- if (m_nPedState == PED_FLEE_POS) {
- m_nLastPedState = PED_FLEE_POS;
- m_nPrevMoveState = PEDMOVE_RUN;
- SetMoveState(PEDMOVE_SPRINT);
- } else {
- m_nLastPedState = PED_IDLE;
- m_nPrevMoveState = PEDMOVE_STILL;
- SetMoveState(PEDMOVE_STILL);
+ } else if (ped->m_nPedState != PED_ARRESTED) {
+ animAssoc->flags |= ASSOC_DELETEFADEDOUT;
+ if (animAssoc->blendDelta >= 0.0f)
+ animAssoc->blendDelta = -4.0f;
+
+ ped->ClearLookFlag();
+ if (ped->m_nPedState == PED_DIVE_AWAY || ped->m_nPedState == PED_STEP_AWAY) {
+ ped->RestorePreviousState();
}
+ }
+}
- bUsesCollision = false;
- m_pSeekTarget = veh;
- m_pSeekTarget->RegisterReference((CEntity**) &m_pSeekTarget);
- m_vehEnterType = optedDoorNode;
- 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);
- veh->AutoPilot.m_nCruiseSpeed = 0;
+// --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)
+ return;
+ }
- 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);
-
- } 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;
-
- // 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;
- }
+ m_threatEntity = nil;
+ if (DyingOrDead())
+ return;
- // Passenger get off
- if (m_vehEnterType == CAR_BUMP_REAR || m_vehEnterType == CAR_BOOT) {
- m_pVehicleAnim->SetFinishCallback(RestoreHeadingRateCB, this);
- m_headingRate = 0.0f;
+ CAnimBlendAssociation *dieAssoc = nil;
+ if (m_nPedState == PED_FALL || m_nPedState == PED_GETUP)
+ delta *= 0.5f;
- } else {
- veh->m_nGettingOutFlags |= exitFlags;
- m_pVehicleAnim->SetFinishCallback(PedAnimStepOutCarCB, this);
- }
+ SetStoredState();
+ ClearAll();
+ m_fHealth = 0.0f;
+ if (m_nPedState == PED_DRIVING) {
+ if (!IsPlayer() && (!m_pMyVehicle || !m_pMyVehicle->IsBike()))
+ FlagToDestroyWhenNextProcessed();
+ } else if (bInVehicle) {
+ if (m_pVehicleAnim)
+ m_pVehicleAnim->blendDelta = -1000.0f;
+ } else if (EnteringCar()) {
+ QuitEnteringCar();
+ }
- } else {
- switch (m_vehEnterType) {
- case CAR_DOOR_RF:
- 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);
- }
- break;
- case CAR_DOOR_RR:
- 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 {
- m_pVehicleAnim = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_GETOUT_RHS);
- }
- break;
- case CAR_DOOR_LF:
- 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);
- }
- break;
- case CAR_DOOR_LR:
- 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 {
- m_pVehicleAnim = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_GETOUT_LHS);
- }
- break;
- default:
- break;
- }
- if (!bBusJacked && !canJumpOut) {
- veh->m_nGettingOutFlags |= GetCarDoorFlag(m_vehEnterType);
- }
- m_pVehicleAnim->SetFinishCallback(canJumpOut ? RestoreHeadingRateCB : PedAnimStepOutCarCB, this);
- }
+ SetPedState(PED_DIE);
+ if (animId == NUM_STD_ANIMS) {
+ bIsPedDieAnimPlaying = false;
+ } else {
+ dieAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, animId, delta);
+ if (speed > 0.0f)
+ dieAssoc->speed = speed;
+
+ dieAssoc->flags &= ~ASSOC_FADEOUTWHENDONE;
+ if (dieAssoc->IsRunning()) {
+ dieAssoc->SetFinishCallback(FinishDieAnimCB, this);
+ bIsPedDieAnimPlaying = true;
}
- bChangedSeat = false;
- if (veh->bIsBus)
- bRenderPedInCar = true;
+ }
- SetRadioStation();
- if (veh->pDriver == this) {
- if (IsPlayer())
- veh->SetStatus(STATUS_PLAYER_DISABLED);
- else
- veh->SetStatus(STATUS_ABANDONED);
+ 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::ScanForInterestingStuff(void)
+CPed::FinishDieAnimCB(CAnimBlendAssociation *animAssoc, void *arg)
{
- if (!IsPedInControl())
- return;
+ CPed *ped = (CPed*)arg;
- if (m_objective != OBJECTIVE_NONE)
- return;
+ if (ped->bIsPedDieAnimPlaying)
+ ped->bIsPedDieAnimPlaying = false;
+}
- if (CharCreatedBy == MISSION_CHAR)
- return;
+// --MIAMI: Done
+void
+CPed::SetDead(void)
+{
+ if (!RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DROWN))
+ bUsesCollision = false;
- LookForSexyPeds();
- LookForSexyCars();
- if (LookForInterestingNodes())
- return;
+ m_fHealth = 0.0f;
+ if (m_nPedState == PED_DRIVING)
+ bIsVisible = false;
- if (m_nPedType == PEDTYPE_CRIMINAL && m_hitRecoverTimer < CTimer::GetTimeInMilliseconds()) {
- if (CGeneral::GetRandomNumber() % 100 >= 10) {
- if (m_objective != OBJECTIVE_MUG_CHAR && !(CGeneral::GetRandomNumber() & 7)) {
- CPed *charToMug = nil;
- for (int i = 0; i < m_numNearPeds; ++i) {
- CPed *nearPed = m_nearPeds[i];
+ SetPedState(PED_DEAD);
+ m_pVehicleAnim = nil;
+ m_pCollidingEntity = nil;
- if ((nearPed->GetPosition() - GetPosition()).MagnitudeSqr() > sq(7.0f))
- break;
+ CWeaponInfo *weapon = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType);
+ RemoveWeaponModel(weapon->m_nModelId);
- if ((nearPed->m_nPedType == PEDTYPE_CIVFEMALE || nearPed->m_nPedType == PEDTYPE_CIVMALE
- || nearPed->m_nPedType == PEDTYPE_CRIMINAL || nearPed->m_nPedType == PEDTYPE_UNUSED1
- || nearPed->m_nPedType == PEDTYPE_PROSTITUTE)
- && nearPed->CharCreatedBy != MISSION_CHAR
- && nearPed->IsPedShootable()
- && nearPed->m_objective != OBJECTIVE_MUG_CHAR) {
- charToMug = nearPed;
- break;
- }
- }
- if (charToMug)
- SetObjective(OBJECTIVE_MUG_CHAR, charToMug);
+ m_currentWeapon = WEAPONTYPE_UNARMED;
+ CEventList::RegisterEvent(EVENT_INJURED_PED, EVENT_ENTITY_PED, this, nil, 250);
+ if (this != FindPlayerPed()) {
+ RemoveWeaponAnims(0, -1000.0f);
+ CreateDeadPedWeaponPickups();
+ CreateDeadPedMoney();
+ }
- m_hitRecoverTimer = CTimer::GetTimeInMilliseconds() + 5000;
- }
- } else {
- int mostExpensiveVehAround = -1;
- int bestMonetaryValue = 0;
+ m_bloodyFootprintCountOrDeathTime = CTimer::GetTimeInMilliseconds();
+ m_deadBleeding = false;
+ bDoBloodyFootprints = false;
+ bVehExitWillBeInstant = false;
+ CEventList::RegisterEvent(EVENT_DEAD_PED, EVENT_ENTITY_PED, this, nil, 1000);
+}
- CVector pos = GetPosition();
- int16 lastVehicle;
- CEntity *vehicles[8];
- CWorld::FindObjectsInRange(pos, 10.0f, true, &lastVehicle, 6, vehicles, false, true, false, false, false);
+// --MIAMI: Done
+void
+CPed::Die(void)
+{
+ // UNUSED: This is a perfectly empty function.
+}
- for (int i = 0; i < lastVehicle; i++) {
- CVehicle* veh = (CVehicle*)vehicles[i];
+// --MIAMI: Done
+void
+CPed::SetChat(CEntity *chatWith, uint32 time)
+{
+ if (m_nPedState != PED_CHAT) {
+ m_nLastPedState = PED_NONE;
+ SetStoredState();
+ }
- if (veh->VehicleCreatedBy != MISSION_VEHICLE) {
- if (veh->m_vecMoveSpeed.Magnitude() <= 0.1f && veh->IsVehicleNormal()
- && veh->IsCar() && bestMonetaryValue < veh->pHandling->nMonetaryValue) {
- mostExpensiveVehAround = i;
- bestMonetaryValue = veh->pHandling->nMonetaryValue;
- }
- }
- }
- if (bestMonetaryValue > 2000 && mostExpensiveVehAround != -1 && vehicles[mostExpensiveVehAround]) {
- SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, vehicles[mostExpensiveVehAround]);
- m_hitRecoverTimer = CTimer::GetTimeInMilliseconds() + 5000;
- return;
- }
- m_hitRecoverTimer = CTimer::GetTimeInMilliseconds() + 5000;
- }
+ SetPedState(PED_CHAT);
+ SetMoveState(PEDMOVE_STILL);
+ m_lookTimer = 0;
+ SetLookFlag(chatWith, true);
+ m_standardTimer = CTimer::GetTimeInMilliseconds() + time;
+ m_lookTimer = CTimer::GetTimeInMilliseconds() + 3000;
+}
+
+// --MIAMI: Done
+void
+CPed::Chat(void)
+{
+ // We're already looking to our partner
+ if (bIsLooking && TurnBody())
+ ClearLookFlag();
+
+ if (!m_pLookTarget || !m_pLookTarget->IsPed()) {
+ ClearChat();
+ return;
}
- if (m_nPedState == PED_WANDER_PATH) {
- if (CGeneral::GetRandomNumberInRange(0.0f, 1.0f) >= 0.5f) {
- m_standardTimer = CTimer::GetTimeInMilliseconds() + 200;
- } else {
- if (CTimer::GetTimeInMilliseconds() > m_standardTimer) {
- for (int i = 0; i < m_numNearPeds; i ++) {
- if (m_nearPeds[i] && m_nearPeds[i]->m_nPedState == PED_WANDER_PATH) {
- if ((GetPosition() - m_nearPeds[i]->GetPosition()).Magnitude() < 1.8f
- && CanSeeEntity(m_nearPeds[i])
- && m_nearPeds[i]->CanSeeEntity(this)
- && WillChat(m_nearPeds[i])) {
+ CPed *partner = (CPed*) m_pLookTarget;
- int time = CGeneral::GetRandomNumber() % 4000 + 10000;
- SetChat(m_nearPeds[i], time);
- m_nearPeds[i]->SetChat(this, time);
- }
- }
- }
- }
+ 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)
+ ReactToAttack(partner->m_pedInObjective);
}
+ return;
}
-/*
- // This part isn't there in VC, is it removed?
- if (!CGame::noProstitutes && m_nPedType == PEDTYPE_PROSTITUTE && CharCreatedBy != MISSION_CHAR
- && m_objectiveTimer < CTimer::GetTimeInMilliseconds() && !CTheScripts::IsPlayerOnAMission()) {
+ if (bIsTalking) {
+ if (CGeneral::GetRandomNumber() < 512) {
+ CAnimBlendAssociation *chatAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_CHAT);
+ if (chatAssoc) {
+ chatAssoc->blendDelta = -4.0f;
+ chatAssoc->flags |= ASSOC_DELETEFADEDOUT;
+ }
+ bIsTalking = false;
+ } else
+ Say(SOUND_PED_CHAT);
- 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);
+ } else {
- for (int i = 0; i < lastVehicle; i++) {
- CVehicle* veh = (CVehicle*)vehicles[i];
+ if (CGeneral::GetRandomNumber() < 20 && !RpAnimBlendClumpGetFirstAssociation(GetClump(), ASSOC_IDLE)) {
+ CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_XPRESS_SCRATCH, 4.0f);
+ }
+ if (!bIsTalking && !RpAnimBlendClumpGetFirstAssociation(GetClump(), ASSOC_IDLE)) {
+ CAnimBlendAssociation *chatAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_IDLE_CHAT, 4.0f);
+ float chatTime = CGeneral::GetRandomNumberInRange(0.0f, 3.0f);
+ chatAssoc->SetCurrentTime(chatTime);
- 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;
- }
- }
- }
+ bIsTalking = true;
+ Say(SOUND_PED_CHAT);
}
}
-*/
+ if (m_standardTimer && CTimer::GetTimeInMilliseconds() > m_standardTimer) {
+ ClearChat();
+ m_standardTimer = CTimer::GetTimeInMilliseconds() + 30000;
+ }
}
// --MIAMI: Done
-uint32
-CPed::ScanForThreats(void)
+void
+CPed::ClearChat(void)
{
- int fearFlags = m_fearFlags;
- CVector ourPos = GetPosition();
- float closestPedDist = 60.0f;
- CVector2D explosionPos = GetPosition();
- if (fearFlags & PED_FLAG_EXPLOSION && CheckForExplosions(explosionPos)) {
- m_eventOrThreat = explosionPos;
- return PED_FLAG_EXPLOSION;
+ CAnimBlendAssociation *animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_CHAT);
+ if (animAssoc) {
+ animAssoc->blendDelta = -8.0f;
+ animAssoc->flags |= ASSOC_DELETEFADEDOUT;
}
-
- 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;
- }
+ bIsTalking = false;
+ ClearLookFlag();
+ RestorePreviousState();
+ if (m_objective == OBJECTIVE_BUY_ICE_CREAM) {
+ bBoughtIceCream = true;
+ SetObjective(OBJECTIVE_NONE);
+ SetWanderPath(CGeneral::GetRandomNumberInRange(0, 8));
+ }
+}
- 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);
- }
- }
+// --MIAMI: Done
+bool
+CPed::FacePhone(void)
+{
+ // 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);
+
+ SetLookFlag(phoneDir, false);
+ bool turnDone = TurnBody();
+ if (turnDone) {
+ SetIdle();
+ ClearLookFlag();
+ m_phoneTalkTimer = CTimer::GetTimeInMilliseconds() + 10000;
}
+ return turnDone;
+#else
+ float currentRot = RADTODEG(m_fRotationCur);
+ float phoneDir = CGeneral::GetRadianAngleBetweenPoints(
+ gPhoneInfo.m_aPhones[m_phoneId].m_vecPos.x,
+ gPhoneInfo.m_aPhones[m_phoneId].m_vecPos.y,
+ GetPosition().x,
+ GetPosition().y);
- CPed *deadPed = nil;
- if (fearFlags & PED_FLAG_DEADPEDS && CharCreatedBy != MISSION_CHAR
- && (deadPed = CheckForDeadPeds()) != nil && (deadPed->GetPosition() - ourPos).MagnitudeSqr() < sq(20.0f)) {
- m_pEventEntity = deadPed;
- m_pEventEntity->RegisterReference((CEntity **) &m_pEventEntity);
- return PED_FLAG_DEADPEDS;
+ SetLookFlag(phoneDir, false);
+ phoneDir = CGeneral::LimitAngle(phoneDir);
+ m_moved = CVector2D(0.0f, 0.0f);
+
+ if (currentRot - 180.0f > phoneDir)
+ phoneDir += 2 * 180.0f;
+ else if (180.0f + currentRot < phoneDir)
+ phoneDir -= 2 * 180.0f;
+
+ float neededTurn = currentRot - phoneDir;
+
+ if (Abs(neededTurn) <= 0.75f) {
+ SetIdle();
+ ClearLookFlag();
+ m_phoneTalkTimer = CTimer::GetTimeInMilliseconds() + 10000;
+ return true;
} else {
- uint32 flagsOfSomePed = 0;
+ m_fRotationCur = DEGTORAD(currentRot - neededTurn * 0.2f);
+ return false;
+ }
+#endif
+}
- CPed *pedToFearFrom = nil;
- bool weSawOurEnemy = false;
- bool weMaySeeOurEnemy = false;
- float closestEnemyDist = 60.0f;
- if ((CTimer::GetFrameCounter() + (uint8)m_randomSeed + 16) & 4) {
+// --MIAMI: Done
+bool
+CPed::MakePhonecall(void)
+{
+ if (CTimer::GetTimeInMilliseconds() <= m_phoneTalkTimer)
+ return false;
- for (int i = 0; i < m_numNearPeds; ++i) {
- if (CharCreatedBy == RANDOM_CHAR && m_nearPeds[i]->CharCreatedBy == MISSION_CHAR && !m_nearPeds[i]->IsPlayer()) {
- continue;
- }
+ SetIdle();
+ gPhoneInfo.m_aPhones[m_phoneId].m_nState = PHONE_STATE_FREE;
+ m_phoneId = -1;
+ return true;
+}
- // BUG: Explained at the same occurence of this bug above. Fixed at the bottom of the function.
- flagsOfSomePed = CPedType::GetFlag(m_nearPeds[i]->m_nPedType);
+// --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);
+}
- if (flagsOfSomePed & fearFlags) {
- if (m_nearPeds[i]->m_fHealth > 0.0f) {
- if (OurPedCanSeeThisOne(m_nearPeds[i], !!bIgnoreThreatsBehindObjects)) {
- if (m_nearPeds[i]->m_nPedState == PED_ATTACK) {
- if (m_nearPeds[i]->m_pedInObjective == this) {
+// --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;
+ }
+ ped->m_lookTimer = 0;
+}
- float enemyDistSqr = (m_nearPeds[i]->GetPosition() - ourPos).MagnitudeSqr2D();
- if (sq(closestEnemyDist) > enemyDistSqr) {
- float enemyDist = Sqrt(enemyDistSqr);
- weSawOurEnemy = true;
- closestPedDist = enemyDist;
- closestEnemyDist = enemyDist;
- pedToFearFrom = m_nearPeds[i];
- }
- }
- } else {
- float nearPedDistSqr = (m_nearPeds[i]->GetPosition() - ourPos).MagnitudeSqr2D();
- if (sq(closestPedDist) > nearPedDistSqr && !weSawOurEnemy) {
- closestPedDist = Sqrt(nearPedDistSqr);
- pedToFearFrom = m_nearPeds[i];
- }
- }
- } else if (!weSawOurEnemy) {
- CPed *nearPed = m_nearPeds[i];
- if (nearPed->m_nPedState == PED_ATTACK) {
- CColPoint foundCol;
- CEntity *foundEnt;
+// --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;
- // We don't see him yet but he's behind a ped, vehicle or object
- if (!CWorld::ProcessLineOfSight(ourPos, nearPed->GetPosition(), foundCol, foundEnt,
- true, false, false, !!bIgnoreThreatsBehindObjects, false, false, false)) {
+ RemoveWeaponModel(-1);
+ }
+}
- if (nearPed->m_pedInObjective == this) {
- float enemyDistSqr = (m_nearPeds[i]->GetPosition() - ourPos).MagnitudeSqr2D();
- if (sq(closestEnemyDist) > enemyDistSqr) {
- float enemyDist = Sqrt(enemyDistSqr);
- weMaySeeOurEnemy = true;
- closestPedDist = enemyDist;
- closestEnemyDist = enemyDist;
- pedToFearFrom = m_nearPeds[i];
- }
- } else if (!nearPed->GetWeapon()->IsTypeMelee() && !weMaySeeOurEnemy) {
- float nearPedDistSqr = (m_nearPeds[i]->GetPosition() - ourPos).MagnitudeSqr2D();
- if (sq(closestPedDist) > nearPedDistSqr) {
- weMaySeeOurEnemy = true;
- closestPedDist = Sqrt(nearPedDistSqr);
- pedToFearFrom = m_nearPeds[i];
- }
- }
- }
- }
- }
- }
- }
- }
- }
+// --MIAMI: Done
+void
+CPed::ClearAnswerMobile(void)
+{
+ if (m_nLastPedState == PED_ANSWER_MOBILE)
+ m_nLastPedState = PED_NONE;
- int16 lastVehicle;
- CEntity* vehicles[8];
- CWorld::FindObjectsInRange(ourPos, 20.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];
+ 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);
- CPed *driver = nearVeh->pDriver;
- if (driver) {
+ if (m_nPedState == PED_ANSWER_MOBILE) {
+ m_nPedState = PED_IDLE;
+ RestorePreviousState();
+ m_pVehicleAnim = nil;
+ }
+}
- // BUG: Same bug as above. Fixed at the bottom of function.
- flagsOfSomePed = CPedType::GetFlag(driver->m_nPedType);
- if (CPedType::GetFlag(driver->m_nPedType) & fearFlags) {
+// --MIAMI: Done
+void
+CPed::AnswerMobile(void)
+{
+ if (!IsPedInControl())
+ return;
- if (driver->m_fHealth > 0.0f && OurPedCanSeeThisOne(nearVeh->pDriver)) {
- // FIX: Taken from VC
-#ifdef FIX_BUGS
- float driverDistSqr = (driver->GetPosition() - ourPos).MagnitudeSqr2D();
-#else
- float driverDistSqr = (CVector2D(ourPos) - explosionPos).MagnitudeSqr();
-#endif
- if (sq(closestPedDist) > driverDistSqr) {
- closestPedDist = Sqrt(driverDistSqr);
- pedToFearFrom = nearVeh->pDriver;
- }
- }
- }
+ 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;
}
}
- m_threatEntity = pedToFearFrom;
- if (m_threatEntity)
- m_threatEntity->RegisterReference((CEntity **) &m_threatEntity);
+ } else {
+ CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_PHONE_TALK, 4.0f);
+ }
+}
-#ifdef FIX_BUGS
- if (pedToFearFrom)
- flagsOfSomePed = CPedType::GetFlag(((CPed*)m_threatEntity)->m_nPedType);
- else
- flagsOfSomePed = 0;
-#endif
+// --MIAMI: Done
+void
+CPed::Teleport(CVector pos)
+{
+ CWorld::Remove(this);
+ SetPosition(pos);
+ bIsStanding = false;
+ m_nPedStateTimer = 0;
+ m_actionX = 0.0f;
+ m_actionY = 0.0f;
+ m_pDamageEntity = nil;
+ CWorld::Add(this);
+}
+
+// --MIAMI: Done
+void
+CPed::SetSeekCar(CVehicle *car, uint32 doorNode)
+{
+ if (m_nPedState == PED_SEEK_CAR)
+ return;
+
+ if (!CanSetPedState() || m_nPedState == PED_DRIVING)
+ return;
+
+ SetStoredState();
+ m_pSeekTarget = car;
+ m_pSeekTarget->RegisterReference((CEntity**) &m_pSeekTarget);
+ m_carInObjective = car;
+ m_carInObjective->RegisterReference((CEntity**) &m_carInObjective);
+ m_pMyVehicle = car;
+ m_pMyVehicle->RegisterReference((CEntity**) &m_pMyVehicle);
+ // m_pSeekTarget->RegisterReference((CEntity**) &m_pSeekTarget);
+ m_vehEnterType = doorNode;
+ m_distanceToCountSeekDone = 0.5f;
+ SetPedState(PED_SEEK_CAR);
- return flagsOfSomePed;
- }
}
// --MIAMI: Done
@@ -18396,481 +7668,141 @@ CPed::SeekCar(void)
}
// --MIAMI: Done
-void
-CPed::StartFightDefend(uint8 direction, uint8 hitLevel, uint8 unk)
+bool
+CPed::CheckForExplosions(CVector2D &area)
{
- if (m_nPedState == PED_DEAD) {
- if (CGame::nastyGame) {
- if (hitLevel == HITLEVEL_GROUND) {
- CAnimBlendAssociation *floorHitAssoc;
- if (RpAnimBlendClumpGetFirstAssociation(GetClump(), ASSOC_FRONTAL)) {
- floorHitAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_FLOOR_HIT_F, 8.0f);
- } else {
- floorHitAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, tFightMoves[FIGHTMOVE_HITONFLOOR].animId, 8.0f);
- }
- if (floorHitAssoc) {
- floorHitAssoc->SetCurrentTime(0.0f);
- floorHitAssoc->SetRun();
- floorHitAssoc->flags &= ~ASSOC_FADEOUTWHENDONE;
- }
- }
- if (CGame::nastyGame) {
- CVector headPos = GetNodePosition(PED_HEAD);
- for(int i = 0; i < 4; ++i) {
- CVector bloodDir(0.0f, 0.0f, 0.1f);
- CVector bloodPos = headPos - 0.2f * GetForward();
- CParticle::AddParticle(PARTICLE_BLOOD, bloodPos, bloodDir, nil, 0.0f, 0, 0, 0, 0);
- }
- }
- }
- } else if (m_nPedState == PED_FALL) {
- if (hitLevel == HITLEVEL_GROUND && !IsPedHeadAbovePos(-0.3f)) {
- CAnimBlendAssociation *floorHitAssoc = RpAnimBlendClumpGetFirstAssociation(GetClump(), ASSOC_FRONTAL) ?
- CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_FLOOR_HIT_F, 8.0f) :
- CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_FLOOR_HIT, 8.0f);
- if (floorHitAssoc) {
- floorHitAssoc->flags &= ~ASSOC_FADEOUTWHENDONE;
- floorHitAssoc->flags |= ASSOC_DELETEFADEDOUT;
- }
- }
- } 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)) {
-
- if (hitLevel != HITLEVEL_HIGH && hitLevel != HITLEVEL_LOW || (IsPlayer() || CGeneral::GetRandomNumber() & 1) && CGeneral::GetRandomNumber() & 7) {
- if (IsPlayer() || CGeneral::GetRandomNumber() & 1) {
- AnimationId shotAnim;
- switch (direction) {
- case 1:
- shotAnim = ANIM_SHOT_LEFT_PARTIAL;
- break;
- case 2:
- shotAnim = ANIM_SHOT_BACK_PARTIAL;
- break;
- case 3:
- shotAnim = ANIM_SHOT_RIGHT_PARTIAL;
- break;
- default:
- shotAnim = ANIM_SHOT_FRONT_PARTIAL;
- break;
- }
- CAnimBlendAssociation *shotAssoc = RpAnimBlendClumpGetAssociation(GetClump(), shotAnim);
- if (!shotAssoc || shotAssoc->blendDelta < 0.0f)
- shotAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, shotAnim, 8.0f);
-
- shotAssoc->SetCurrentTime(0.0f);
- shotAssoc->SetRun();
- shotAssoc->flags |= ASSOC_FADEOUTWHENDONE;
- } else {
- int time = CGeneral::GetRandomNumberInRange(1000, 3000);
- SetWaitState(WAITSTATE_PLAYANIM_DUCK, &time);
- }
- } else {
- bool fall = true;
- AnimationId hitAnim;
- switch (direction) {
- case 1:
- hitAnim = ANIM_KO_SPIN_R;
- break;
- case 2:
- if (CGeneral::GetRandomNumber() & 1) {
- fall = false;
- hitAnim = ANIM_HIT_BACK;
- } else {
- hitAnim = ANIM_KO_SKID_BACK;
- }
- break;
- case 3:
- hitAnim = ANIM_KO_SPIN_L;
- break;
- default:
- if (hitLevel == HITLEVEL_LOW) {
- hitAnim = ANIM_KO_SHOT_STOM;
- } else if (CGeneral::GetRandomNumber() & 1) {
- fall = false;
- hitAnim = ANIM_HIT_WALK;
- } else if (CGeneral::GetRandomNumber() & 1) {
- fall = false;
- hitAnim = ANIM_HIT_HEAD;
- } else {
- hitAnim = ANIM_KO_SHOT_FACE;
- }
- break;
- }
- if (fall) {
- SetFall(500, hitAnim, false);
- } else {
- CAnimBlendAssociation *hitAssoc = RpAnimBlendClumpGetAssociation(GetClump(), hitAnim);
- if (!hitAssoc || hitAssoc->blendDelta < 0.0f)
- hitAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, hitAnim, 8.0f);
-
- hitAssoc->SetCurrentTime(0.0f);
- hitAssoc->SetRun();
- hitAssoc->flags |= ASSOC_FADEOUTWHENDONE;
- }
- }
- Say(SOUND_PED_DEFEND);
- } else {
- Say(SOUND_PED_DEFEND);
- switch (hitLevel) {
- case HITLEVEL_GROUND:
- m_curFightMove = FIGHTMOVE_HITONFLOOR;
- break;
- case HITLEVEL_LOW:
- 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;
- }
- m_curFightMove = FIGHTMOVE_HITBODY;
- break;
- case HITLEVEL_HIGH:
- switch (direction) {
- case 1:
- m_curFightMove = FIGHTMOVE_HITLEFT;
- break;
- case 2:
- m_curFightMove = FIGHTMOVE_HITBACK;
- break;
- case 3:
- m_curFightMove = FIGHTMOVE_HITRIGHT;
- break;
- default:
- if (unk <= 5)
- m_curFightMove = FIGHTMOVE_HITHEAD;
- else
- m_curFightMove = FIGHTMOVE_HITBIGSTEP;
- break;
- }
- break;
- default:
- switch (direction) {
- case 1:
- m_curFightMove = FIGHTMOVE_HITLEFT;
- break;
- case 2:
- m_curFightMove = FIGHTMOVE_HITBACK;
- break;
- case 3:
- m_curFightMove = FIGHTMOVE_HITRIGHT;
- break;
- default:
- if (unk <= 5)
- m_curFightMove = FIGHTMOVE_HITCHEST;
- else
- m_curFightMove = FIGHTMOVE_HITBIGSTEP;
- break;
- }
- break;
- }
- if (m_nPedState == PED_GETUP && !IsPedHeadAbovePos(0.0f))
- m_curFightMove = FIGHTMOVE_HITONFLOOR;
-
- if (m_nPedState == PED_FIGHT) {
- CAnimBlendAssociation *moveAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, tFightMoves[m_curFightMove].animId, 8.0f);
- moveAssoc->SetCurrentTime(0.0f);
- moveAssoc->SetFinishCallback(FinishFightMoveCB, this);
- if (IsPlayer())
- moveAssoc->speed = 1.2f;
+ int event = 0;
+ if (CEventList::FindClosestEvent(EVENT_EXPLOSION, GetPosition(), &event)) {
+ area.x = gaEvent[event].posn.x;
+ area.y = gaEvent[event].posn.y;
+ CEntity *actualEntity = nil;
- m_takeAStepAfterAttack = 0;
- m_fightButtonPressure = 0;
+ switch (gaEvent[event].entityType) {
+ case EVENT_ENTITY_PED:
+ actualEntity = CPools::GetPed(gaEvent[event].entityRef);
+ break;
+ case EVENT_ENTITY_VEHICLE:
+ actualEntity = CPools::GetVehicle(gaEvent[event].entityRef);
+ break;
+ case EVENT_ENTITY_OBJECT:
+ actualEntity = CPools::GetObject(gaEvent[event].entityRef);
+ break;
+ default:
+ break;
+ }
- } 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.2f;
+ if (actualEntity) {
+ m_pEventEntity = actualEntity;
+ m_pEventEntity->RegisterReference((CEntity **) &m_pEventEntity);
+ bGonnaInvestigateEvent = true;
+ } else
+ bGonnaInvestigateEvent = false;
- } else {
- if (m_nPedState != PED_AIM_GUN && m_nPedState != PED_ATTACK)
- SetStoredState();
+ CEventList::ClearEvent(event);
+ return true;
+ } else if (CEventList::FindClosestEvent(EVENT_FIRE, GetPosition(), &event)) {
+ area.x = gaEvent[event].posn.x;
+ area.y = gaEvent[event].posn.y;
+ CEventList::ClearEvent(event);
+ bGonnaInvestigateEvent = false;
+ return true;
+ }
- if (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) {
- walkStartAssoc->flags |= ASSOC_DELETEFADEDOUT;
- walkStartAssoc->blendDelta = -1000.0f;
- }
- CAnimBlendAssociation *walkStopAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_RUN_STOP);
- if (!walkStopAssoc)
- walkStopAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_RUN_STOP_R);
- if (walkStopAssoc) {
- walkStopAssoc->flags |= ASSOC_DELETEFADEDOUT;
- walkStopAssoc->blendDelta = -1000.0f;
- RestoreHeadingRate();
- }
- SetMoveState(PEDMOVE_NONE);
- m_nStoredMoveState = PEDMOVE_NONE;
- 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;
- }
+ bGonnaInvestigateEvent = false;
+ return false;
+}
- if (m_pedInObjective && m_pedInObjective->IsPlayer() && !IsPlayer())
- ((CPlayerPed*)m_pedInObjective)->RemovePedFromMeleeList(this);
+// --MIAMI: Done
+CPed *
+CPed::CheckForGunShots(void)
+{
+ int event;
+ if (CEventList::FindClosestEvent(EVENT_GUNSHOT, GetPosition(), &event)) {
+ if (gaEvent[event].entityType == EVENT_ENTITY_PED) {
+ // Probably due to we don't want peds to go gunshot area? (same on VC)
+ bGonnaInvestigateEvent = false;
+ return CPools::GetPed(gaEvent[event].entityRef);
}
}
+ bGonnaInvestigateEvent = false;
+ return nil;
}
// --MIAMI: Done
-void
-CPed::UpdateFromLeader(void)
+CPed *
+CPed::CheckForDeadPeds(void)
{
- if (CTimer::GetTimeInMilliseconds() <= m_objectiveTimer)
- return;
-
- if (!m_leader)
- return;
-
- CVector leaderDist;
- if (m_leader->InVehicle())
- leaderDist = m_leader->m_pMyVehicle->GetPosition() - GetPosition();
- else
- leaderDist = m_leader->GetPosition() - GetPosition();
-
- if (leaderDist.Magnitude() > 30.0f) {
- if (bWaitForLeaderToComeCloser) {
- if (IsPedInControl()) {
- SetObjective(OBJECTIVE_NONE);
- SetIdle();
- SetMoveState(PEDMOVE_STILL);
- }
- return;
- }
- bWaitForLeaderToComeCloser = true;
- } else
- bWaitForLeaderToComeCloser = false;
-
- if (IsPedInControl()) {
- if (m_nWaitState == WAITSTATE_PLAYANIM_TAXI)
- WarpPedToNearLeaderOffScreen();
-
- if (m_leader->m_nPedState == PED_DEAD) {
- SetLeader(nil);
- SetObjective(OBJECTIVE_FLEE_ON_FOOT_TILL_SAFE);
- return;
- }
- if (!m_leader->bInVehicle) {
- if (m_leader->m_objective != OBJECTIVE_ENTER_CAR_AS_DRIVER) {
- if (bInVehicle) {
- if (m_objective != OBJECTIVE_WAIT_IN_CAR_THEN_GET_OUT && m_objective != OBJECTIVE_LEAVE_CAR)
- SetObjective(OBJECTIVE_LEAVE_CAR, m_pMyVehicle);
-
- return;
- }
- if (m_objective == OBJECTIVE_ENTER_CAR_AS_PASSENGER) {
- RestorePreviousObjective();
- RestorePreviousState();
- }
- }
- if (m_nPedType == PEDTYPE_PROSTITUTE && CharCreatedBy == RANDOM_CHAR) {
- SetLeader(nil);
- return;
- }
- }
- if (bInVehicle || !m_leader->bInVehicle || m_leader->m_nPedState != PED_DRIVING) {
- if (m_leader->m_objective != OBJECTIVE_NONE && (!m_leader->IsPlayer() || m_leader->m_objective != OBJECTIVE_WAIT_ON_FOOT)
- && m_objective != m_leader->m_objective) {
-
- switch (m_leader->m_objective) {
- case OBJECTIVE_WAIT_ON_FOOT:
- case OBJECTIVE_FLEE_ON_FOOT_TILL_SAFE:
- case OBJECTIVE_WAIT_IN_CAR:
- case OBJECTIVE_FOLLOW_ROUTE:
- SetObjective(m_leader->m_objective);
- m_objectiveTimer = m_leader->m_objectiveTimer;
- break;
- case OBJECTIVE_GUARD_SPOT:
- SetObjective(OBJECTIVE_GUARD_SPOT, m_leader->m_vecSeekPosEx);
- 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;
- }
- break;
- 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;
- }
- break;
- case OBJECTIVE_GUARD_ATTACK:
- return;
- case OBJECTIVE_HAIL_TAXI:
- m_leader = nil;
- SetObjective(OBJECTIVE_NONE);
- break;
- default:
- SetObjective(OBJECTIVE_GOTO_CHAR_ON_FOOT, m_leader);
- SetObjectiveTimer(0);
- break;
- }
- } else {
- 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) {
- SetObjective(OBJECTIVE_KILL_CHAR_ON_FOOT, lookTargetOfLeader);
- SetObjectiveTimer(8000);
- SetLookFlag(m_leader->m_pLookTarget, false);
- SetLookTimer(500);
- }
- } else {
- if (IsPedInControl() && m_nPedState != PED_ATTACK) {
- if (m_leader->m_objective != OBJECTIVE_NONE || m_objective != OBJECTIVE_NONE || m_leader->m_nPedState != PED_CHAT || m_nPedState != PED_CHAT) {
- SetObjective(OBJECTIVE_GOTO_CHAR_ON_FOOT, m_leader);
- SetObjectiveTimer(0);
- } else {
- SetObjective(OBJECTIVE_NONE);
- }
- }
- if (m_nPedState == PED_IDLE && m_leader->IsPlayer() && !bDontFight) {
- if (ScanForThreats() && m_threatEntity) {
- m_pLookTarget = m_threatEntity;
- m_pLookTarget->RegisterReference((CEntity **) &m_pLookTarget);
- TurnBody();
- if (m_attackTimer < CTimer::GetTimeInMilliseconds() && !GetWeapon()->IsTypeMelee()) {
- if (m_pPointGunAt)
- m_pPointGunAt->CleanUpOldReference(&m_pPointGunAt);
- m_pPointGunAt = m_threatEntity;
- if (m_threatEntity)
- m_threatEntity->RegisterReference((CEntity **) &m_pPointGunAt);
- SetAttack(m_threatEntity);
- }
- }
- }
- }
- }
- } else {
- if (m_objective != OBJECTIVE_ENTER_CAR_AS_PASSENGER && m_objective != OBJECTIVE_ENTER_CAR_AS_DRIVER) {
- if (m_leader->m_pMyVehicle->m_nNumPassengers < m_leader->m_pMyVehicle->m_nNumMaxPassengers)
- SetObjective(OBJECTIVE_ENTER_CAR_AS_PASSENGER, m_leader->m_pMyVehicle);
- }
- }
- } else if (bInVehicle) {
- if ((!m_leader->bInVehicle || m_leader->m_nPedState == PED_EXIT_CAR) && m_objective != OBJECTIVE_WAIT_IN_CAR_THEN_GET_OUT) {
-
- switch (m_leader->m_objective) {
- case OBJECTIVE_ENTER_CAR_AS_PASSENGER:
- case OBJECTIVE_ENTER_CAR_AS_DRIVER:
- if (m_pMyVehicle == m_leader->m_pMyVehicle || m_pMyVehicle == m_leader->m_carInObjective)
- break;
-
- // fall through
- default:
- if (m_pMyVehicle && m_objective != OBJECTIVE_LEAVE_CAR) {
- m_leaveCarTimer = CTimer::GetTimeInMilliseconds() + 250;
- SetObjective(OBJECTIVE_LEAVE_CAR, m_pMyVehicle);
- }
-
- break;
- }
+ int event;
+ if (CEventList::FindClosestEvent(EVENT_DEAD_PED, GetPosition(), &event)) {
+ int pedHandle = gaEvent[event].entityRef;
+ if (pedHandle && gaEvent[event].entityType == EVENT_ENTITY_PED) {
+ bGonnaInvestigateEvent = true;
+ return CPools::GetPed(pedHandle);
}
}
+ bGonnaInvestigateEvent = false;
+ return nil;
}
// --MIAMI: Done
-void
-CPed::UpdatePosition(void)
+bool
+CPed::IsPlayer(void) const
{
- if (CReplay::IsPlayingBack() || !bIsStanding || m_attachedTo)
- return;
-
- CVector2D velocityChange;
-
- SetHeading(m_fRotationCur);
- if (m_pCurrentPhysSurface) {
- CVector2D velocityOfSurface;
- CPhysical *curSurface = m_pCurrentPhysSurface;
- if (!IsPlayer() && m_pCurrentPhysSurface->IsVehicle() && ((CVehicle*)m_pCurrentPhysSurface)->IsBoat()) {
+#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
+}
- // It seems R* didn't like m_vecOffsetFromPhysSurface for boats
- CVector offsetToSurface = GetPosition() - curSurface->GetPosition();
- offsetToSurface.z -= FEET_OFFSET;
+// --MIAMI: Done
+bool
+CPed::IsGangMember(void) const
+{
+ return m_nPedType >= PEDTYPE_GANG1 && m_nPedType <= PEDTYPE_GANG9;
+}
- CVector surfaceMoveVelocity = curSurface->m_vecMoveSpeed;
- CVector surfaceTurnVelocity = CrossProduct(curSurface->m_vecTurnSpeed, offsetToSurface);
+// --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();
+}
- // Also we use that weird formula instead of friction if it's boat
- float slideMult = -curSurface->m_vecTurnSpeed.MagnitudeSqr();
- velocityOfSurface = slideMult * offsetToSurface * CTimer::GetTimeStep() + (surfaceTurnVelocity + surfaceMoveVelocity);
- m_vecMoveSpeed.z = slideMult * offsetToSurface.z * CTimer::GetTimeStep() + (surfaceTurnVelocity.z + surfaceMoveVelocity.z);
- } else {
- velocityOfSurface = curSurface->GetSpeed(m_vecOffsetFromPhysSurface);
- }
- // Reminder: m_moved is displacement from walking/running.
- velocityChange = m_moved + velocityOfSurface - m_vecMoveSpeed;
- m_fRotationCur += curSurface->m_vecTurnSpeed.z * CTimer::GetTimeStep();
- m_fRotationDest += curSurface->m_vecTurnSpeed.z * CTimer::GetTimeStep();
- } else if (m_nSurfaceTouched != SURFACE_STEEP_CLIFF || m_vecDamageNormal.x == 0.0f && m_vecDamageNormal.y == 0.0f) {
- velocityChange = m_moved - m_vecMoveSpeed;
- } else {
- // Ped got damaged by steep slope
- m_vecMoveSpeed = CVector(0.0f, 0.0f, -0.001f);
- // some kind of
- CVector2D reactionForce = m_vecDamageNormal * (1.0f / m_vecDamageNormal.Magnitude2D());
+// --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;
+}
- velocityChange = 0.02f * reactionForce + m_moved;
+// --MIAMI: Done
+bool
+CPed::IsPointerValid(void)
+{
+ int pedIndex = CPools::GetPedPool()->GetIndex(this) >> 8;
+ if (pedIndex < 0 || pedIndex >= NUMPEDS)
+ return false;
- float reactionAndVelocityDotProd = DotProduct2D(reactionForce, velocityChange);
- // they're in same direction
- if (reactionAndVelocityDotProd < 0.0f) {
- velocityChange -= reactionAndVelocityDotProd * reactionForce;
- }
- }
-
- // Take time step into account
- 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()) {
- if (!m_pCurrentPhysSurface->IsVehicle() || !((CVehicle*)m_pCurrentPhysSurface)->IsBoat())
- changeMult = 0.01f * CTimer::GetTimeStep();
- } else {
- changeMult = 0.002f * CTimer::GetTimeStep();
- }
+ if (m_entryInfoList.first || FindPlayerPed() == this)
+ return true;
- if (speedChange > changeMult) {
- velocityChange = velocityChange * (changeMult / speedChange);
- }
- }
- m_vecMoveSpeed.x += velocityChange.x;
- m_vecMoveSpeed.y += velocityChange.y;
+ return false;
}
// --MIAMI: Done
@@ -18950,9 +7882,10 @@ 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 = HALFPI + m_pMyVehicle->GetForward().Heading();
+ m_fRotationCur = m_pMyVehicle->GetForward().Heading() + HALFPI;
tempMat.SetTranslate(0.0f, 0.0f, 0.0f);
tempMat.RotateZ(HALFPI);
newMat = newMat * tempMat;
@@ -18965,729 +7898,1101 @@ CPed::SetPedPositionInCar(void)
GetMatrix() = newMat;
}
-static RwObject*
-CloneAtomicToFrameCB(RwObject *frame, void *data)
+// --MIAMI: Done
+void
+CPed::LookForSexyPeds(void)
{
- RpAtomic *newAtomic = RpAtomicClone((RpAtomic*)frame);
- RpAtomicSetFrame(newAtomic, (RwFrame*)data);
- RpClumpAddAtomic(flyingClumpTemp, newAtomic);
- CVisibilityPlugins::SetAtomicRenderCallback(newAtomic, nil);
- return frame;
-}
+ if ((!IsPedInControl() && m_nPedState != PED_DRIVING)
+ || m_lookTimer >= CTimer::GetTimeInMilliseconds() || m_nPedType != PEDTYPE_CIVMALE)
+ return;
-static RwFrame*
-RecurseFrameChildrenToCloneCB(RwFrame *frame, void *data)
-{
- RwFrame *newFrame = RwFrameCreate();
- RwFrameAddChild((RwFrame*)data, newFrame);
- RwFrameTransform(newFrame, RwFrameGetMatrix(frame), rwCOMBINEREPLACE);
- RwFrameForAllObjects(frame, CloneAtomicToFrameCB, newFrame);
- RwFrameForAllChildren(frame, RecurseFrameChildrenToCloneCB, newFrame);
- return newFrame;
+ for (int i = 0; i < m_numNearPeds; i++) {
+ if (CanSeeEntity(m_nearPeds[i])) {
+ if ((GetPosition() - m_nearPeds[i]->GetPosition()).Magnitude() < 10.0f) {
+ CPed *nearPed = m_nearPeds[i];
+ if ((nearPed->m_pedStats->m_sexiness > m_pedStats->m_sexiness)
+ && nearPed->m_nPedType == PEDTYPE_CIVFEMALE) {
+
+ SetLookFlag(nearPed, true);
+ m_lookTimer = CTimer::GetTimeInMilliseconds() + 4000;
+ Say(SOUND_PED_CHAT_SEXY);
+ return;
+ }
+ }
+ }
+ }
+ m_lookTimer = CTimer::GetTimeInMilliseconds() + 10000;
}
// --MIAMI: Done
-CObject*
-CPed::SpawnFlyingComponent(int pedNode, int8 direction)
+void
+CPed::LookForSexyCars(void)
{
- // VC doesn't have detachable limbs :shrug:
- return nil;
+ CEntity *vehicles[8];
+ CVehicle *veh;
+ int foundVehId = 0;
+ int bestPriceYet = 0;
+ int16 lastVehicle;
+
+ if (!IsPedInControl() && m_nPedState != PED_DRIVING)
+ return;
+
+ if (m_lookTimer < CTimer::GetTimeInMilliseconds()) {
+ CWorld::FindObjectsInRange(GetPosition(), 10.0f, true, &lastVehicle, 6, vehicles, false, true, false, false, false);
+
+ for (int vehId = 0; vehId < lastVehicle; vehId++) {
+ veh = (CVehicle*)vehicles[vehId];
+ if (veh != m_pMyVehicle && bestPriceYet < veh->pHandling->nMonetaryValue) {
+ foundVehId = vehId;
+ bestPriceYet = veh->pHandling->nMonetaryValue;
+ }
+ }
+ if (lastVehicle > 0 && bestPriceYet > 40000)
+ SetLookFlag(vehicles[foundVehId], false);
+
+ m_lookTimer = CTimer::GetTimeInMilliseconds() + 10000;
+ }
}
// --MIAMI: Done
-void
-CPed::WarpPedIntoCar(CVehicle *car)
+bool
+CPed::LookForInterestingNodes(void)
{
- bInVehicle = true;
- m_pMyVehicle = car;
- m_pMyVehicle->RegisterReference((CEntity **) &m_pMyVehicle);
- m_carInObjective = car;
- m_carInObjective->RegisterReference((CEntity **) &m_carInObjective);
- SetPedState(PED_DRIVING);
- bUsesCollision = false;
- bIsInTheAir = false;
- bVehExitWillBeInstant = true;
- if (m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER) {
- car->SetDriver(this);
- car->pDriver->RegisterReference((CEntity **) &car->pDriver);
+ CBaseModelInfo *model;
+ CPtrNode *ptrNode;
+ CVector effectDist;
+ C2dEffect *effect;
+ CMatrix *objMat;
- } 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;
- car->pPassengers[i]->RegisterReference((CEntity **) &car->pPassengers[i]);
- break;
+ if ((CTimer::GetFrameCounter() + (m_randomSeed % 256)) & 7 || CTimer::GetTimeInMilliseconds() <= m_standardTimer) {
+ return false;
+ }
+ bool found = false;
+ uint8 randVal = CGeneral::GetRandomNumber() % 256;
+
+ int minX = CWorld::GetSectorIndexX(GetPosition().x - CHECK_NEARBY_THINGS_MAX_DIST);
+ if (minX < 0) minX = 0;
+ int minY = CWorld::GetSectorIndexY(GetPosition().y - CHECK_NEARBY_THINGS_MAX_DIST);
+ if (minY < 0) minY = 0;
+ int maxX = CWorld::GetSectorIndexX(GetPosition().x + CHECK_NEARBY_THINGS_MAX_DIST);
+#ifdef FIX_BUGS
+ if (maxX >= NUMSECTORS_X) maxX = NUMSECTORS_X - 1;
+#else
+ if (maxX >= NUMSECTORS_X) maxX = NUMSECTORS_X;
+#endif
+
+ int maxY = CWorld::GetSectorIndexY(GetPosition().y + CHECK_NEARBY_THINGS_MAX_DIST);
+#ifdef FIX_BUGS
+ if (maxY >= NUMSECTORS_Y) maxY = NUMSECTORS_Y - 1;
+#else
+ if (maxY >= NUMSECTORS_Y) maxY = NUMSECTORS_Y;
+#endif
+
+ for (int curY = minY; curY <= maxY && !found; curY++) {
+ for (int curX = minX; curX <= maxX && !found; curX++) {
+ CSector *sector = CWorld::GetSector(curX, curY);
+
+ for (ptrNode = sector->m_lists[ENTITYLIST_VEHICLES].first; ptrNode && !found; ptrNode = ptrNode->next) {
+ CVehicle *veh = (CVehicle*)ptrNode->item;
+ model = veh->GetModelInfo();
+ if (model->GetNum2dEffects() != 0) {
+ for (int e = 0; e < model->GetNum2dEffects(); e++) {
+ effect = model->Get2dEffect(e);
+ if (effect->type == EFFECT_ATTRACTOR && effect->attractor.probability >= randVal) {
+ objMat = &veh->GetMatrix();
+ CVector effectPos = veh->GetMatrix() * effect->pos;
+ effectDist = effectPos - GetPosition();
+ if (effectDist.MagnitudeSqr() < sq(8.0f)) {
+ found = true;
+ break;
+ }
+ }
+ }
+ }
+ }
+ for (ptrNode = sector->m_lists[ENTITYLIST_OBJECTS].first; ptrNode && !found; ptrNode = ptrNode->next) {
+ CObject *obj = (CObject*)ptrNode->item;
+ model = CModelInfo::GetModelInfo(obj->GetModelIndex());
+ if (model->GetNum2dEffects() != 0) {
+ for (int e = 0; e < model->GetNum2dEffects(); e++) {
+ effect = model->Get2dEffect(e);
+ if (effect->type == EFFECT_ATTRACTOR && effect->attractor.probability >= randVal) {
+ objMat = &obj->GetMatrix();
+ CVector effectPos = obj->GetMatrix() * effect->pos;
+ effectDist = effectPos - GetPosition();
+ if (effectDist.MagnitudeSqr() < sq(8.0f)) {
+ found = true;
+ break;
+ }
+ }
+ }
+ }
+ }
+ for (ptrNode = sector->m_lists[ENTITYLIST_BUILDINGS].first; ptrNode && !found; ptrNode = ptrNode->next) {
+ CBuilding *building = (CBuilding*)ptrNode->item;
+ model = CModelInfo::GetModelInfo(building->GetModelIndex());
+ if (model->GetNum2dEffects() != 0) {
+ for (int e = 0; e < model->GetNum2dEffects(); e++) {
+ effect = model->Get2dEffect(e);
+ if (effect->type == EFFECT_ATTRACTOR && effect->attractor.probability >= randVal) {
+ objMat = &building->GetMatrix();
+ CVector effectPos = building->GetMatrix() * effect->pos;
+ effectDist = effectPos - GetPosition();
+ if (effectDist.MagnitudeSqr() < sq(8.0f)) {
+ found = true;
+ break;
+ }
+ }
+ }
+ }
+ }
+ for (ptrNode = sector->m_lists[ENTITYLIST_BUILDINGS_OVERLAP].first; ptrNode && !found; ptrNode = ptrNode->next) {
+ CBuilding *building = (CBuilding*)ptrNode->item;
+ model = CModelInfo::GetModelInfo(building->GetModelIndex());
+ if (model->GetNum2dEffects() != 0) {
+ for (int e = 0; e < model->GetNum2dEffects(); e++) {
+ effect = model->Get2dEffect(e);
+ if (effect->type == EFFECT_ATTRACTOR && effect->attractor.probability >= randVal) {
+ objMat = &building->GetMatrix();
+ CVector effectPos = building->GetMatrix() * effect->pos;
+ effectDist = effectPos - GetPosition();
+ if (effectDist.MagnitudeSqr() < sq(8.0f)) {
+ found = true;
+ break;
+ }
+ }
+ }
+ }
}
}
- } else
- return;
-
- if (IsPlayer()) {
- car->SetStatus(STATUS_PLAYER);
- AudioManager.PlayerJustGotInCar();
- CCarCtrl::RegisterVehicleOfInterest(car);
- } else {
- car->SetStatus(STATUS_PHYSICS);
}
- CWorld::Remove(this);
- SetPosition(car->GetPosition());
- CWorld::Add(this);
+ if (!found)
+ return false;
- if (car->bIsAmbulanceOnDuty) {
- car->bIsAmbulanceOnDuty = false;
- --CCarCtrl::NumAmbulancesOnDuty;
+ CVector effectFrontLocal = Multiply3x3(*objMat, effect->attractor.dir);
+ float angleToFace = CGeneral::GetRadianAngleBetweenPoints(effectFrontLocal.x, effectFrontLocal.y, 0.0f, 0.0f);
+ randVal = CGeneral::GetRandomNumber() % 256;
+ if (randVal <= m_randomSeed % 256) {
+ m_standardTimer = CTimer::GetTimeInMilliseconds() + 2000;
+ SetLookFlag(angleToFace, true);
+ SetLookTimer(1000);
+ return false;
}
- if (car->bIsFireTruckOnDuty) {
- car->bIsFireTruckOnDuty = false;
- --CCarCtrl::NumFiretrucksOnDuty;
+
+ CVector2D effectPos = *objMat * effect->pos;
+ switch (effect->attractor.type) {
+ case ATTRACTORTYPE_ICECREAM:
+ SetInvestigateEvent(EVENT_ICECREAM, effectPos, 0.1f, 15000, angleToFace);
+ break;
+ case ATTRACTORTYPE_STARE:
+ SetInvestigateEvent(EVENT_SHOPSTALL, effectPos, 1.0f,
+ CGeneral::GetRandomNumberInRange(8000, 10 * effect->attractor.probability + 8500),
+ angleToFace);
+ break;
+ default:
+ return true;
}
- if (!car->bEngineOn) {
- car->bEngineOn = true;
- DMAudio.PlayOneShot(car->m_audioEntityId, SOUND_CAR_ENGINE_START, 1.0f);
+ 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;
+ }
}
- RpAnimBlendClumpSetBlendDeltas(GetClump(), ASSOC_PARTIAL, -1000.0f);
+ if (CTimer::GetTimeInMilliseconds() > ped->m_nWaitTimer && assoc)
+ assoc->flags &= ~ASSOC_REPEAT;
- AddInCarAnims(car, car->pDriver == this);
- RemoveWeaponWhenEnteringVehicle();
+ if (!assoc || assoc->blendDelta < 0.0f) {
+ int selectedAnimOffset;
+ do
+ selectedAnimOffset = CGeneral::GetRandomNumberInRange(0, amount);
+ while (assoc && first + selectedAnimOffset == assoc->animId);
- if (car->bIsBus)
- bRenderPedInCar = false;
+ assoc = CAnimManager::BlendAnimation(ped->GetClump(), animGroup, (AnimationId)(first + selectedAnimOffset), 3.0f);
- bChangedSeat = true;
+ 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::SetObjective(eObjective newObj, float heading, const CVector& pos)
+CPed::ClearWaitState(void)
{
- 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;
+ 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::SetObjective(eObjective newObj, CVector dest)
+CPed::SetWaitState(eWaitState state, void *time)
{
- if (DyingOrDead())
+ AnimationId waitAnim = NUM_STD_ANIMS;
+ CAnimBlendAssociation *animAssoc;
+
+ if (!IsPedInControl())
return;
- if (m_prevObjective != OBJECTIVE_NONE && m_prevObjective == newObj)
+ if (m_nWaitState == WAITSTATE_RIOT && state != WAITSTATE_FALSE)
return;
- if (m_objective == newObj) {
- 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)
- return;
- }
- }
+ if (state != m_nWaitState)
+ FinishedWaitCB(nil, this);
- ClearPointGunAt();
- m_objectiveTimer = 0;
- bObjectiveCompleted = false;
- switch (newObj) {
- case OBJECTIVE_GUARD_SPOT:
- m_vecSeekPosEx = dest;
- m_distanceToCountSeekDoneEx = 5.0f;
+ switch (state) {
+ case WAITSTATE_TRAFFIC_LIGHTS:
+ m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 500;
SetMoveState(PEDMOVE_STILL);
break;
- case OBJECTIVE_GUARD_AREA:
- case OBJECTIVE_WAIT_IN_CAR:
- case OBJECTIVE_WAIT_IN_CAR_THEN_GET_OUT:
- 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_FOLLOW_CAR_IN_CAR:
- 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:
+ case WAITSTATE_CROSS_ROAD:
+ m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 1000;
+ CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_IDLE_HBHB, 4.0f);
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;
- 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();
+ case WAITSTATE_CROSS_ROAD_LOOK:
+ CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_ROAD_CROSS, 8.0f);
+
+ if (time)
+ m_nWaitTimer = CTimer::GetTimeInMilliseconds() + *(int*)time;
+ else
+ m_nWaitTimer = CTimer::GetTimeInMilliseconds() + CGeneral::GetRandomNumberInRange(2000,5000);
+
+ break;
+ case WAITSTATE_LOOK_PED:
+ 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;
+ m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 3500;
+ animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_IDLE_HBHB, 4.0f);
+#ifdef FIX_BUGS
+ animAssoc->SetFinishCallback(RestoreHeadingRateCB, this);
+#endif
+ break;
+ case WAITSTATE_HITWALL:
+ m_headingRate = 2.0f;
+ m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 5000;
+ animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_HIT_WALL, 16.0f);
+ animAssoc->flags |= ASSOC_DELETEFADEDOUT;
+ animAssoc->flags |= ASSOC_FADEOUTWHENDONE;
+ animAssoc->SetDeleteCallback(FinishedWaitCB, this);
+
+ if (m_objective == OBJECTIVE_ENTER_CAR_AS_PASSENGER && CharCreatedBy == RANDOM_CHAR && m_nPedState == PED_SEEK_CAR) {
+ ClearObjective();
+ RestorePreviousState();
+ m_hitRecoverTimer = CTimer::GetTimeInMilliseconds() + 30000;
}
- 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 WAITSTATE_TURN180:
+ m_headingRate = 0.0f;
+ m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 5000;
+ animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_TURN_180, 4.0f);
+ animAssoc->SetFinishCallback(FinishedWaitCB, this);
+ break;
+ case WAITSTATE_SURPRISE:
+ m_headingRate = 0.0f;
+ m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 2000;
+ animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_HIT_WALL, 4.0f);
+ animAssoc->SetFinishCallback(FinishedWaitCB, this);
+ break;
+ case WAITSTATE_STUCK:
+ SetMoveState(PEDMOVE_STILL);
+ SetMoveAnim();
+ m_headingRate = 0.0f;
+ m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 5000;
+ animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_IDLE_TIRED, 4.0f);
+#ifdef FIX_BUGS
+ 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();
+ m_hitRecoverTimer = CTimer::GetTimeInMilliseconds() + 30000;
}
break;
- case OBJECTIVE_RUN_TO_AREA:
- case OBJECTIVE_SPRINT_TO_AREA:
- bIsRunning = true;
- 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;
+ case WAITSTATE_LOOK_ABOUT:
+ SetMoveState(PEDMOVE_STILL);
+ SetMoveAnim();
+ m_headingRate = 0.0f;
+ m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 5000;
+ animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_IDLE_HBHB, 4.0f);
+#ifdef FIX_BUGS
+ animAssoc->SetFinishCallback(RestoreHeadingRateCB, this);
+#endif
+
break;
- default: break;
- }
+ case WAITSTATE_PLAYANIM_COWER:
+ waitAnim = ANIM_HANDSCOWER;
+ case WAITSTATE_PLAYANIM_HANDSUP:
+ if (waitAnim == NUM_STD_ANIMS)
+ waitAnim = ANIM_HANDSUP;
+ case WAITSTATE_PLAYANIM_HANDSCOWER:
+ if (waitAnim == NUM_STD_ANIMS)
+ waitAnim = ANIM_HANDSCOWER;
+ m_headingRate = 0.0f;
+ if (time)
+ m_nWaitTimer = CTimer::GetTimeInMilliseconds() + *(int*)time;
+ else
+ m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 3000;
- if (IsTemporaryObjective(m_objective)) {
- m_prevObjective = newObj;
- } else {
- if (m_objective != newObj)
- SetStoredObjective();
+ animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, waitAnim, 4.0f);
+ animAssoc->SetDeleteCallback(FinishedWaitCB, this);
+ break;
+ case WAITSTATE_PLAYANIM_DUCK:
+ waitAnim = ANIM_DUCK_DOWN;
+ case WAITSTATE_PLAYANIM_TAXI:
+ if (waitAnim == NUM_STD_ANIMS)
+ waitAnim = ANIM_IDLE_TAXI;
+ case WAITSTATE_PLAYANIM_CHAT:
+ if (waitAnim == NUM_STD_ANIMS)
+ waitAnim = ANIM_IDLE_CHAT;
+ if (time)
+ m_nWaitTimer = CTimer::GetTimeInMilliseconds() + *(int*)time;
+ else
+ m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 3000;
- m_objective = newObj;
+ animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, waitAnim, 4.0f);
+ animAssoc->flags &= ~ASSOC_FADEOUTWHENDONE;
+ animAssoc->flags |= ASSOC_DELETEFADEDOUT;
+ animAssoc->SetDeleteCallback(FinishedWaitCB, this);
+ break;
+ case WAITSTATE_FINISH_FLEE:
+ SetMoveState(PEDMOVE_STILL);
+ SetMoveAnim();
+ m_headingRate = 0.0f;
+ m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 2500;
+ animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_IDLE_TIRED, 4.0f);
+#ifdef FIX_BUGS
+ 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:
+ ClearWaitState();
+ RestoreHeadingRate();
+ return;
}
+ m_nWaitState = state;
}
// --MIAMI: Done
void
-CPed::SetMoveAnim(void)
+CPed::Wait(void)
{
- if (m_nStoredMoveState == m_nMoveState || !IsPedInControl() || m_attachedTo)
- return;
+ AnimationId mustHaveAnim = NUM_STD_ANIMS;
+ CAnimBlendAssociation *animAssoc;
+ CPed *pedWeLook;
- if (m_nMoveState == PEDMOVE_NONE) {
- m_nStoredMoveState = PEDMOVE_NONE;
+ if (DyingOrDead()) {
+ ClearWaitState();
+ RestoreHeadingRate();
return;
}
- AssocGroupId animGroupToUse;
- if (m_leader && m_leader->IsPlayer())
- animGroupToUse = ASSOCGRP_PLAYER;
- else
- animGroupToUse = m_animGroup;
+ switch (m_nWaitState) {
- CAnimBlendAssociation *animAssoc = RpAnimBlendClumpGetFirstAssociation(GetClump(), ASSOC_BLOCK);
- if (!animAssoc) {
- animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_FIGHT_IDLE);
- if (!animAssoc)
- animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_CROUCHRELOAD);
+ case WAITSTATE_TRAFFIC_LIGHTS:
+ if (CTimer::GetTimeInMilliseconds() > m_nWaitTimer) {
+ if (CTrafficLights::LightForPeds() == PED_LIGHTS_WALK) {
+ ClearWaitState();
+ SetMoveState(PEDMOVE_WALK);
+ }
+ }
+ break;
- if (animAssoc && m_nPedState == PED_FIGHT)
- return;
+ case WAITSTATE_CROSS_ROAD:
+ if (CTimer::GetTimeInMilliseconds() > m_nWaitTimer) {
+ if (CGeneral::GetRandomNumber() & 1 || !m_nWaitTimer)
+ ClearWaitState();
+ else
+ SetWaitState(WAITSTATE_CROSS_ROAD_LOOK, nil);
- if (animAssoc) {
- CAnimBlendAssociation *idleAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_STANCE);
- if (!idleAssoc || idleAssoc->blendDelta <= 0.0f) {
- animAssoc->flags |= ASSOC_DELETEFADEDOUT;
- animAssoc = CAnimManager::BlendAnimation(GetClump(), animGroupToUse, ANIM_IDLE_STANCE, 8.0f);
+ animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_HBHB);
+ if (animAssoc) {
+ animAssoc->blendDelta = -8.0f;
+ animAssoc->flags |= ASSOC_DELETEFADEDOUT;
+ }
}
- }
- }
- if (!animAssoc) {
- animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_TIRED);
- if (animAssoc)
- if (m_nWaitState == WAITSTATE_STUCK || m_nWaitState == WAITSTATE_FINISH_FLEE)
- return;
+ break;
- if (animAssoc) {
- CAnimBlendAssociation *idleAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_STANCE);
- if (!idleAssoc || idleAssoc->blendDelta <= 0.0f) {
- animAssoc->flags |= ASSOC_DELETEFADEDOUT;
- animAssoc = CAnimManager::BlendAnimation(GetClump(), animGroupToUse, ANIM_IDLE_STANCE, 4.0f);
+ case WAITSTATE_CROSS_ROAD_LOOK:
+ if (CTimer::GetTimeInMilliseconds() > m_nWaitTimer) {
+ ClearWaitState();
+ animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_ROAD_CROSS);
+ if (animAssoc) {
+ animAssoc->blendDelta = -8.0f;
+ animAssoc->flags |= ASSOC_DELETEFADEDOUT;
+ }
}
- }
- }
- if (!animAssoc) {
- m_nStoredMoveState = m_nMoveState;
- if (m_nMoveState == PEDMOVE_WALK || m_nMoveState == PEDMOVE_RUN || m_nMoveState == PEDMOVE_SPRINT) {
- for (CAnimBlendAssociation *assoc = RpAnimBlendClumpGetFirstAssociation(GetClump(), ASSOC_PARTIAL);
- assoc; assoc = RpAnimBlendGetNextAssociation(assoc, ASSOC_PARTIAL)) {
+ break;
- if (!(assoc->flags & ASSOC_FADEOUTWHENDONE)) {
- assoc->blendDelta = -2.0f;
- assoc->flags |= ASSOC_DELETEFADEDOUT;
+ case WAITSTATE_DOUBLEBACK:
+ if (CTimer::GetTimeInMilliseconds() <= m_nWaitTimer) {
+ uint32 timeLeft = m_nWaitTimer - CTimer::GetTimeInMilliseconds();
+ if (timeLeft < 2500 && timeLeft > 2000) {
+ m_nWaitTimer -= 500;
+ CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_XPRESS_SCRATCH, 4.0f);
}
+ } else {
+ ClearWaitState();
+ SetMoveState(PEDMOVE_WALK);
}
+ break;
- ClearAimFlag();
- ClearLookFlag();
- }
+ case WAITSTATE_HITWALL:
+ if (CTimer::GetTimeInMilliseconds() <= m_nWaitTimer) {
+ if (m_collidingThingTimer > CTimer::GetTimeInMilliseconds()) {
+ m_collidingThingTimer = CTimer::GetTimeInMilliseconds() + 2500;
+ }
+ } else {
+ ClearWaitState();
+ }
+ break;
- switch (m_nMoveState) {
- case PEDMOVE_STILL:
- animAssoc = CAnimManager::BlendAnimation(GetClump(), animGroupToUse, ANIM_IDLE_STANCE, 4.0f);
- break;
- case PEDMOVE_WALK:
- animAssoc = CAnimManager::BlendAnimation(GetClump(), animGroupToUse, ANIM_WALK, 1.0f);
- break;
- case PEDMOVE_RUN:
- if (m_nPedState == PED_FLEE_ENTITY) {
- animAssoc = CAnimManager::BlendAnimation(GetClump(), animGroupToUse, ANIM_RUN, 3.0f);
+ case WAITSTATE_TURN180:
+ if (CTimer::GetTimeInMilliseconds() > m_nWaitTimer) {
+ ClearWaitState();
+ m_fRotationCur = m_fRotationCur + PI;
+ if (m_nPedState == PED_INVESTIGATE)
+ ClearInvestigateEvent();
+ }
+
+ if (m_collidingThingTimer > CTimer::GetTimeInMilliseconds()) {
+ m_collidingThingTimer = CTimer::GetTimeInMilliseconds() + 2500;
+ }
+ break;
+
+ case WAITSTATE_SURPRISE:
+ if (CTimer::GetTimeInMilliseconds() > m_nWaitTimer) {
+ if (RpAnimBlendClumpGetAssociation(GetClump(), ANIM_HIT_WALL)) {
+ animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_XPRESS_SCRATCH, 4.0f);
+ animAssoc->SetFinishCallback(FinishedWaitCB, this);
+ m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 5000;
} else {
- animAssoc = CAnimManager::BlendAnimation(GetClump(), animGroupToUse, ANIM_RUN, 1.0f);
+ ClearWaitState();
}
+ }
+ break;
+
+ case WAITSTATE_STUCK:
+ if (CTimer::GetTimeInMilliseconds() <= m_nWaitTimer)
break;
- case PEDMOVE_SPRINT:
- animAssoc = CAnimManager::BlendAnimation(GetClump(), animGroupToUse, ANIM_SPRINT, 1.0f);
- break;
- default:
- break;
- }
- if (animAssoc) {
- if (m_leader) {
- CAnimBlendAssociation *walkAssoc = RpAnimBlendClumpGetAssociation(m_leader->GetClump(), ANIM_WALK);
- if (!walkAssoc)
- walkAssoc = RpAnimBlendClumpGetAssociation(m_leader->GetClump(), ANIM_RUN);
+ animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_TIRED);
- if (!walkAssoc)
- walkAssoc = RpAnimBlendClumpGetAssociation(m_leader->GetClump(), ANIM_SPRINT);
+ if (!animAssoc)
+ animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_TURN_180);
+ if (!animAssoc)
+ animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_XPRESS_SCRATCH);
+ if (!animAssoc)
+ animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_ROAD_CROSS);
- if (walkAssoc) {
- animAssoc->speed = walkAssoc->speed;
+ if (animAssoc) {
+ if (animAssoc->IsPartial()) {
+ animAssoc->blendDelta = -8.0f;
+ animAssoc->flags |= ASSOC_DELETEFADEDOUT;
} else {
- if (CharCreatedBy == MISSION_CHAR)
- animAssoc->speed = 1.0f;
- else
- animAssoc->speed = 1.2f - m_randomSeed * 0.4f / MYRAND_MAX;
-
+ animAssoc->flags |= ASSOC_DELETEFADEDOUT;
+ CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_IDLE_STANCE, 4.0f);
}
- } else {
- if (CharCreatedBy == MISSION_CHAR)
- animAssoc->speed = 1.0f;
- else
- animAssoc->speed = 1.2f - m_randomSeed * 0.4f / MYRAND_MAX;
- }
- }
- }
-}
+ if (animAssoc->animId == ANIM_TURN_180) {
+ m_fRotationCur = CGeneral::LimitRadianAngle(PI + m_fRotationCur);
+ ClearWaitState();
+ SetMoveState(PEDMOVE_WALK);
+ m_nStoredMoveState = PEDMOVE_NONE;
+ m_panicCounter = 0;
+ return;
+ }
+ }
-// --MIAMI: Done
-void
-CPed::SetEnterCar_AllClear(CVehicle *car, uint32 doorNode, uint32 doorFlag)
-{
- float zDiff = 0.0f;
- car->m_nGettingInFlags |= doorFlag;
- bVehEnterDoorIsBlocked = false;
- if (m_nPedState != PED_SEEK_CAR && m_nPedState != PED_SEEK_IN_BOAT)
- SetStoredState();
+ AnimationId animToPlay;
- m_pSeekTarget = car;
- 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->IsBike()) {
- car->bIsBeingCarJacked = true;
- }
+ switch (CGeneral::GetRandomNumber() & 3) {
+ case 0:
+ animToPlay = ANIM_ROAD_CROSS;
+ break;
+ case 1:
+ animToPlay = ANIM_IDLE_TIRED;
+ break;
+ case 2:
+ animToPlay = ANIM_XPRESS_SCRATCH;
+ break;
+ case 3:
+ animToPlay = ANIM_TURN_180;
+ break;
+ default:
+ break;
+ }
- m_pMyVehicle = (CVehicle*)m_pSeekTarget;
- m_pMyVehicle->RegisterReference((CEntity**) &m_pMyVehicle);
- ((CVehicle*)m_pSeekTarget)->m_nNumGettingIn++;
- bUsesCollision = false;
- CVector doorOpenPos = GetPositionToOpenCarDoor(car, m_vehEnterType);
+ animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, animToPlay, 4.0f);
- // Because buses have stairs
- if (!m_pMyVehicle->bIsBus)
- zDiff = Max(0.0f, doorOpenPos.z - GetPosition().z);
+ if (animToPlay == ANIM_TURN_180)
+ animAssoc->SetFinishCallback(FinishedWaitCB, this);
- m_vecOffsetSeek = doorOpenPos - GetPosition();
- m_nPedStateTimer = CTimer::GetTimeInMilliseconds() + 600;
+ m_nWaitTimer = CTimer::GetTimeInMilliseconds() + CGeneral::GetRandomNumberInRange(1500, 5000);
+ break;
- 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);
+ case WAITSTATE_LOOK_ABOUT:
+ if (CTimer::GetTimeInMilliseconds() > m_nWaitTimer) {
+ ClearWaitState();
+ animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_HBHB);
+ if (animAssoc) {
+ animAssoc->blendDelta = -8.0f;
+ animAssoc->flags |= ASSOC_DELETEFADEDOUT;
+ }
+ }
+ break;
- PedSetInCarCB(nil, this);
- bVehExitWillBeInstant = true;
+ case WAITSTATE_PLAYANIM_HANDSUP:
+ mustHaveAnim = ANIM_HANDSUP;
+
+ case WAITSTATE_PLAYANIM_HANDSCOWER:
+ if (mustHaveAnim == NUM_STD_ANIMS)
+ mustHaveAnim = ANIM_HANDSCOWER;
- } else if (car->IsBike()) {
- PedAnimAlignCB(0, this);
- car->AutoPilot.m_nCruiseSpeed = 0;
+ animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), mustHaveAnim);
+ pedWeLook = (CPed*) m_pLookTarget;
- } else {
- 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);
- }
-}
+ if ((!m_pLookTarget || !m_pLookTarget->IsPed() || pedWeLook->m_pPointGunAt)
+ && m_nPedState != PED_FLEE_ENTITY
+ && m_nPedState != PED_ATTACK
+ && CTimer::GetTimeInMilliseconds() <= m_nWaitTimer
+ && animAssoc) {
-// --MIAMI: Done
-void
-CPed::WanderPath(void)
-{
- if (!m_pNextPathNode) {
- printf("THIS SHOULDN@T HAPPEN TOO OFTEN\n");
- SetIdle();
- return;
- }
- if (m_nWaitState == WAITSTATE_FALSE) {
- if (m_nMoveState == PEDMOVE_STILL || m_nMoveState == PEDMOVE_NONE)
- SetMoveState(PEDMOVE_WALK);
- }
- m_vecSeekPos = CPathFind::TakeWidthIntoAccountForWandering(m_pNextPathNode, m_randomSeed);
- m_vecSeekPos.z += 1.0f;
+ if (pedWeLook)
+ TurnBody();
+ } else {
+ 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);
+ }
- // 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;
+ } else if (m_pedStats->m_fear <= 100 - pedWeLook->m_pedStats->m_temper) {
+ if (GetWeapon()->IsTypeMelee()) {
+ if(m_pedStats->m_flags & STAT_GUN_PANIC) {
+ SetObjective(OBJECTIVE_FLEE_CHAR_ON_FOOT_TILL_SAFE, m_pLookTarget);
+ if (m_nPedState == PED_FLEE_ENTITY || m_nPedState == PED_FLEE_POS) {
- CPathNode *previousLastNode = m_pLastPathNode;
- uint8 randVal = (m_randomSeed + 3 * CTimer::GetFrameCounter()) % 100;
+ bUsePedNodeSeek = true;
+ m_pNextPathNode = nil;
+ }
+ if (m_nMoveState != PEDMOVE_RUN)
+ SetMoveState(PEDMOVE_WALK);
- // We don't prefer 180-degree turns in normal situations
- uint8 dirWeWouldntPrefer = m_nPathDir;
- if (dirWeWouldntPrefer <= 3)
- dirWeWouldntPrefer += 4;
- else
- dirWeWouldntPrefer -= 4;
+ if (m_nPedType != PEDTYPE_COP) {
+ ProcessObjective();
+ SetMoveState(PEDMOVE_WALK);
+ }
+ } else {
+ SetObjective(OBJECTIVE_NONE);
+ SetWanderPath(CGeneral::GetRandomNumberInRange(0.0f, 8.0f));
+ }
+ } else {
+ SetObjective(OBJECTIVE_KILL_CHAR_ON_FOOT, m_pLookTarget);
+ SetObjectiveTimer(20000);
+ }
+ } else {
+ 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;
+ }
+ SetMoveState(PEDMOVE_RUN);
+ Say(SOUND_PED_FLEE_RUN);
+ }
+ }
+ }
+ animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), mustHaveAnim);
+ if (animAssoc) {
+ animAssoc->blendDelta = -4.0f;
+ animAssoc->flags |= ASSOC_DELETEFADEDOUT;
+ }
+ }
+ break;
+ case WAITSTATE_PLAYANIM_COWER:
+ mustHaveAnim = ANIM_HANDSCOWER;
- CPathNode *nodeWeWouldntPrefer = nil;
- uint8 dirToSet = 9; // means undefined
- uint8 dirWeWouldntPrefer2 = 9; // means undefined
- uint8 tryCount = 0;
+ case WAITSTATE_PLAYANIM_DUCK:
+ if (mustHaveAnim == NUM_STD_ANIMS)
+ mustHaveAnim = ANIM_DUCK_DOWN;
- if (randVal <= 90) {
- if (randVal > 80) {
- m_nPathDir += 2;
- m_nPathDir %= 8;
- }
- } else {
- m_nPathDir -= 2;
- if (m_nPathDir < 0)
- m_nPathDir += 8;
- }
+ case WAITSTATE_PLAYANIM_TAXI:
+ if (mustHaveAnim == NUM_STD_ANIMS)
+ mustHaveAnim = ANIM_IDLE_TAXI;
- m_pLastPathNode = m_pNextPathNode;
- ThePaths.FindNextNodeWandering(PATH_PED, GetPosition(), &m_pLastPathNode, &m_pNextPathNode,
- m_nPathDir, &dirToSet);
+ case WAITSTATE_PLAYANIM_CHAT:
+ if (mustHaveAnim == NUM_STD_ANIMS)
+ mustHaveAnim = ANIM_IDLE_CHAT;
- 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;
- }
- }
+ if (CTimer::GetTimeInMilliseconds() > m_nWaitTimer) {
+ animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), mustHaveAnim);
+ if (animAssoc) {
+ animAssoc->blendDelta = -4.0f;
+ animAssoc->flags |= ASSOC_DELETEFADEDOUT;
+ }
+ 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) {
- // NB: SetWanderPath checks for m_nPathDir == dirToStartWith, this one checks for tryCount > 7
- while (!m_pNextPathNode) {
- tryCount++;
- m_nPathDir = (m_nPathDir + 1) % 8;
+ if (m_pLookTarget)
+ m_pLookTarget->CleanUpOldReference(&m_pLookTarget);
+ m_pLookTarget = m_pedInObjective;
+ m_pLookTarget->RegisterReference((CEntity **) &m_pLookTarget);
+ TurnBody();
+ }
+ }
+ }
+ break;
- // We're at where we started and couldn't find any node
- if (tryCount > 7) {
- if (!nodeWeWouldntPrefer) {
- ClearAll();
- SetIdle();
- // Probably this text carried over here after copy-pasting this loop from early version of SetWanderPath.
- Error("Can't find valid path node, SetWanderPath, Ped.cpp");
- return;
+ case WAITSTATE_FINISH_FLEE:
+ animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_TIRED);
+ if (animAssoc) {
+ if (CTimer::GetTimeInMilliseconds() > m_nWaitTimer) {
+ animAssoc->flags |= ASSOC_DELETEFADEDOUT;
+ CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_IDLE_STANCE, 4.0f);
+ int timer = 2000;
+ ClearWaitState();
+ SetWaitState(WAITSTATE_CROSS_ROAD_LOOK, &timer);
+ }
+ } else {
+ ClearWaitState();
}
- m_pNextPathNode = nodeWeWouldntPrefer;
- dirToSet = dirWeWouldntPrefer2;
- } else {
- ThePaths.FindNextNodeWandering(PATH_PED, GetPosition(), &m_pLastPathNode, &m_pNextPathNode,
- m_nPathDir, &dirToSet);
- if (m_pNextPathNode) {
- if (dirToSet == dirWeWouldntPrefer) {
- nodeWeWouldntPrefer = m_pNextPathNode;
- dirWeWouldntPrefer2 = dirToSet;
+ 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);
+ }
}
}
- if (((CPedModelInfo*)CModelInfo::GetModelInfo(m_modelIndex))->m_pedStatType == PEDSTAT_SKATER) {
- if (m_pNextPathNode) {
- CVector unpacked(m_pNextPathNode->GetPosition() / 8.f);
- if (!CPopulation::IsSkateable(unpacked))
+ 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;
}
- }
- }
- m_nPathDir = dirToSet;
- if (m_pLastPathNode == m_pNextPathNode) {
- m_pNextPathNode = previousLastNode;
- SetWaitState(WAITSTATE_DOUBLEBACK, nil);
- Say(SOUND_PED_WAIT_DOUBLEBACK);
- } else if (ThePaths.TestForPedTrafficLight(m_pLastPathNode, m_pNextPathNode)) {
- SetWaitState(WAITSTATE_TRAFFIC_LIGHTS, nil);
- } else if (ThePaths.TestCrossesRoad(m_pLastPathNode, m_pNextPathNode)) {
- SetWaitState(WAITSTATE_CROSS_ROAD, nil);
- } else if (m_pNextPathNode == previousLastNode) {
- SetWaitState(WAITSTATE_DOUBLEBACK, nil);
- Say(SOUND_PED_WAIT_DOUBLEBACK);
+ 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;
}
+
+ if(!m_nWaitState)
+ RestoreHeadingRate();
}
// --MIAMI: Done
-bool
-CPed::WarpPedToNearEntityOffScreen(CEntity *warpTo)
+void
+CPed::DeleteSunbatheIdleAnimCB(CAnimBlendAssociation *assoc, void *arg)
{
- bool teleported = false;
- if (GetIsOnScreen() || m_leaveCarTimer > CTimer::GetTimeInMilliseconds())
- return false;
+ CPed *ped = (CPed*) arg;
- CVector warpToPos = warpTo->GetPosition();
- CVector distVec = warpToPos - GetPosition();
- float halfOfDist = distVec.Magnitude() * 0.5f;
- CVector halfNormalizedDist = distVec / halfOfDist;
-
- CVector appropriatePos = GetPosition();
- 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) {
- 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 (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();
}
- m_leaveCarTimer = CTimer::GetTimeInMilliseconds() + 3000;
- return teleported;
+ ped->m_nWaitTimer = 0;
+ ped->RestoreHeadingRate();
+ ped->Wait();
}
// --MIAMI: Done
-bool
-CPed::WarpPedToNearLeaderOffScreen(void)
+void
+CPed::FinishedWaitCB(CAnimBlendAssociation *animAssoc, void *arg)
{
- bool teleported = false;
- if (GetIsOnScreen() || m_leaveCarTimer > CTimer::GetTimeInMilliseconds())
- return false;
+ CPed *ped = (CPed*)arg;
- CVector warpToPos = m_leader->GetPosition();
- CVector distVec = warpToPos - GetPosition();
- float halfOfDist = distVec.Magnitude() * 0.5f;
- CVector halfNormalizedDist = distVec / halfOfDist;
-
- CVector appropriatePos = GetPosition();
- 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) {
- 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;
+ ped->m_nWaitTimer = 0;
+ ped->RestoreHeadingRate();
+ ped->Wait();
}
// --MIAMI: Done
void
-CPed::SetCarJack_AllClear(CVehicle* car, uint32 doorNode, uint32 doorFlag)
+CPed::RestoreHeadingRate(void)
{
- if (m_nPedState != PED_SEEK_CAR)
- SetStoredState();
-
- m_pSeekTarget = car;
- m_pSeekTarget->RegisterReference((CEntity**)&m_pSeekTarget);
- SetPedState(PED_CARJACK);
- car->bIsBeingCarJacked = true;
- m_pMyVehicle = (CVehicle*)m_pSeekTarget;
- m_pMyVehicle->RegisterReference((CEntity**)&m_pMyVehicle);
- ((CVehicle*)m_pSeekTarget)->m_nNumGettingIn++;
-
- 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;
-
- if(car->IsBike()){
- bUsesCollision = false;
- PedAnimAlignCB(nil, this);
- } else {
- float zDiff = Max(0.0f, carEnterPos.z - GetPosition().z);
- bUsesCollision = false;
+ m_headingRate = m_pedStats->m_headingChangeRate;
+}
- 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);
+// --MIAMI: Done
+void
+CPed::RestoreHeadingRateCB(CAnimBlendAssociation *assoc, void *arg)
+{
+ ((CPed*)arg)->RestoreHeadingRate();
+}
- m_pVehicleAnim->SetFinishCallback(PedAnimAlignCB, this);
+// --MIAMI: Done
+void
+CPed::FlagToDestroyWhenNextProcessed(void)
+{
+ bRemoveFromWorld = true;
+ if (!InVehicle())
+ return;
+ if (m_pMyVehicle->pDriver == this){
+ m_pMyVehicle->pDriver = nil;
+ if (IsPlayer() && m_pMyVehicle->GetStatus() != STATUS_WRECKED)
+ m_pMyVehicle->SetStatus(STATUS_ABANDONED);
+ }else{
+ m_pMyVehicle->RemovePassenger(this);
}
+ bInVehicle = false;
+ m_pMyVehicle = nil;
+
+ if (CharCreatedBy == MISSION_CHAR)
+ SetPedState(PED_DEAD);
+ else
+ SetPedState(PED_NONE);
+ m_pVehicleAnim = nil;
}
// --MIAMI: Done
void
-CPed::SetCarJack(CVehicle* car)
+CPed::SetSolicit(uint32 time)
{
- uint8 doorFlag;
- eDoors door;
- CPed *pedInSeat = nil;
-
- if (car->IsBoat())
+ if (m_nPedState == PED_SOLICIT || !IsPedInControl() || !m_carInObjective)
return;
- 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];
- 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_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 (CharCreatedBy != MISSION_CHAR && m_carInObjective->m_nNumGettingIn == 0
+ && CTimer::GetTimeInMilliseconds() < m_objectiveTimer) {
+ if (m_vehEnterType == CAR_DOOR_LF) {
+ m_fRotationDest = m_carInObjective->GetForward().Heading() - HALFPI;
+ } else {
+ m_fRotationDest = m_carInObjective->GetForward().Heading() + HALFPI;
}
- }
- if(car->bIsBus)
- pedInSeat = car->pDriver;
+ if (Abs(m_fRotationDest - m_fRotationCur) < HALFPI) {
+ m_standardTimer = CTimer::GetTimeInMilliseconds() + time;
+
+ if(!m_carInObjective->bIsVan && !m_carInObjective->bIsBus)
+ m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_HOOKERTALK, 4.0f);
- if (m_fHealth > 0.0f && (IsPlayer() || m_objective == OBJECTIVE_KILL_CHAR_ON_FOOT || m_objective == OBJECTIVE_KILL_CHAR_ANY_MEANS ||
- 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)))
- if (!car->bIsBeingCarJacked && !(doorFlag & car->m_nGettingInFlags) && !(doorFlag & car->m_nGettingOutFlags))
- SetCarJack_AllClear(car, m_vehEnterType, doorFlag);
+ SetPedState(PED_SOLICIT);
+ }
+ }
}
// --MIAMI: Done
@@ -19738,463 +9043,500 @@ CPed::Solicit(void)
// --MIAMI: Done
void
-CPed::SetExitBoat(CVehicle *boat)
+CPed::SetBuyIceCream(void)
{
- SetPedState(PED_IDLE);
- CVector newPos = GetPosition();
- RemoveInCarAnims();
- CColModel* boatCol = boat->GetColModel();
- if (boat->IsUpsideDown()) {
- newPos = { 0.0f, 0.0f, boatCol->boundingBox.min.z };
- newPos = boat->GetMatrix() * newPos;
- newPos.z += 1.0f;
- m_vehEnterType = CAR_DOOR_RF;
- PedSetOutCarCB(nil, this);
- bIsStanding = true;
- m_pCurSurface = boat;
- m_pCurSurface->RegisterReference((CEntity**)&m_pCurSurface);
- m_pCurrentPhysSurface = boat;
- } else {
- 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;
- }
+ if (m_nPedState == PED_BUY_ICECREAM || !IsPedInControl())
+ 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;
+ if (!m_carInObjective)
+ return;
+
+ SetPedState(PED_BUY_ICECREAM);
}
// --MIAMI: Done
void
-CPed::SetNewAttraction(CPedAttractor* pAttractor, const CVector& pos, float heading, float time, int32 qid)
+CPed::BuyIceCream(void)
{
- 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;
+ 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));
}
- SetObjectiveTimer(time);
- m_positionInQueue = qid;
}
// --MIAMI: Done
-void
-CPed::ClearWaitState(void)
+bool
+CPed::PossiblyFindBetterPosToSeekCar(CVector *pos, CVehicle *veh)
{
- 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);
+ bool foundIt = false;
- } 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);
+ CVector helperPos = GetPosition();
+ helperPos.z = pos->z - 0.5f;
- } 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");
+ CVector foundPos = *pos;
+ foundPos.z -= 0.5f;
- 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();
+ // If there is another car between target car and us.
+ if (CWorld::TestSphereAgainstWorld((foundPos + helperPos) / 2.0f, 0.25f, veh, false, true, false, false, false, false)) {
- break;
- case WAITSTATE_BOMBER:
- assoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_BOMBER);
- if (assoc)
- assoc->blendDelta = -8.0f;
- break;
- case WAITSTATE_STRIPPER:
- {
- CAnimBlock* stripAnimBlock = CAnimManager::GetAnimationBlock("strip");
+ CColModel *vehCol = veh->GetModelInfo()->GetColModel();
+ CVector *colMin = &vehCol->boundingBox.min;
+ CVector *colMax = &vehCol->boundingBox.max;
- 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;
-}
+ CVector leftRearPos = CVector(colMin->x - 0.5f, colMin->y - 0.5f, 0.0f);
+ CVector rightRearPos = CVector(0.5f + colMax->x, colMin->y - 0.5f, 0.0f);
+ CVector leftFrontPos = CVector(colMin->x - 0.5f, 0.5f + colMax->y, 0.0f);
+ CVector rightFrontPos = CVector(0.5f + colMax->x, 0.5f + colMax->y, 0.0f);
-#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));
-void
-CPed::Save(uint8*& buf)
-{
- SkipSaveBuf(buf, 52);
- CopyToBuf(buf, GetPosition().x);
- CopyToBuf(buf, GetPosition().y);
- CopyToBuf(buf, GetPosition().z);
- SkipSaveBuf(buf, 288);
- CopyToBuf(buf, CharCreatedBy);
- SkipSaveBuf(buf, 499);
- CopyToBuf(buf, m_fHealth);
- CopyToBuf(buf, m_fArmour);
- SkipSaveBuf(buf, 172);
- for (int i = 0; i < 10; i++) // has to be hardcoded
- m_weapons[i].Save(buf);
- SkipSaveBuf(buf, 252);
-}
+ leftRearPos = veh->GetMatrix() * leftRearPos;
+ rightRearPos = veh->GetMatrix() * rightRearPos;
+ leftFrontPos = veh->GetMatrix() * leftFrontPos;
+ rightFrontPos = veh->GetMatrix() * rightFrontPos;
-void
-CPed::Load(uint8*& buf)
-{
- SkipSaveBuf(buf, 52);
- CopyFromBuf(buf, GetMatrix().GetPosition().x);
- CopyFromBuf(buf, GetMatrix().GetPosition().y);
- CopyFromBuf(buf, GetMatrix().GetPosition().z);
- SkipSaveBuf(buf, 288);
- CopyFromBuf(buf, CharCreatedBy);
- SkipSaveBuf(buf, 499);
- CopyFromBuf(buf, m_fHealth);
- CopyFromBuf(buf, m_fArmour);
- SkipSaveBuf(buf, 172);
- m_currentWeapon = WEAPONTYPE_UNARMED;
+ // Makes helperPos veh-ped distance vector.
+ helperPos -= veh->GetPosition();
- CWeapon bufWeapon;
- for (int i = 0; i < 10; i++) { // has to be hardcoded
- bufWeapon.Load(buf);
+ // ?!? I think it's absurd to use this unless another function like SeekCar finds next pos. with it and we're trying to simulate it's behaviour.
+ // On every run it returns another pos. for ped, with same distance to the veh.
+ // Sequence of positions are not guaranteed, it depends on global pos. (So sometimes it returns positions to make ped draw circle, sometimes don't)
+ helperPos = veh->GetMatrix() * helperPos;
- 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);
+ float vehForwardHeading = veh->GetForward().Heading();
- CStreaming::LoadAllRequestedModels(false);
+ // I'm absolutely not sure about these namings.
+ // NTVF = needed turn if we're looking to vehicle front and wanna look to...
+
+ float potentialLrHeading = Atan2(leftRearPos.x - helperPos.x, leftRearPos.y - helperPos.y);
+ float NTVF_LR = CGeneral::LimitRadianAngle(potentialLrHeading - vehForwardHeading);
+
+ float potentialRrHeading = Atan2(rightRearPos.x - helperPos.x, rightRearPos.y - helperPos.y);
+ float NTVF_RR = CGeneral::LimitRadianAngle(potentialRrHeading - vehForwardHeading);
+
+ float potentialLfHeading = Atan2(leftFrontPos.x - helperPos.x, leftFrontPos.y - helperPos.y);
+ float NTVF_LF = CGeneral::LimitRadianAngle(potentialLfHeading - vehForwardHeading);
+
+ float potentialRfHeading = Atan2(rightFrontPos.x - helperPos.x, rightFrontPos.y - helperPos.y);
+ float NTVF_RF = CGeneral::LimitRadianAngle(potentialRfHeading - vehForwardHeading);
+
+ bool canHeadToLr = NTVF_LR <= -PI || NTVF_LR >= -HALFPI;
+
+ bool canHeadToRr = NTVF_RR <= HALFPI || NTVF_RR >= PI;
+
+ bool canHeadToLf = NTVF_LF >= 0.0f || NTVF_LF <= -HALFPI;
+
+ bool canHeadToRf = NTVF_RF <= 0.0f || NTVF_RF >= HALFPI;
+
+ // Only order of conditions are different among enterTypes.
+ if (m_vehEnterType == CAR_DOOR_RR) {
+ if (canHeadToRr) {
+ foundPos = rightRearPos;
+ foundIt = true;
+ } else if (canHeadToRf) {
+ foundPos = rightFrontPos;
+ foundIt = true;
+ } else if (canHeadToLr) {
+ foundPos = leftRearPos;
+ foundIt = true;
+ } else if (canHeadToLf) {
+ foundPos = leftFrontPos;
+ foundIt = true;
+ }
+ } else if(m_vehEnterType == CAR_DOOR_RF) {
+ if (canHeadToRf) {
+ foundPos = rightFrontPos;
+ foundIt = true;
+ } else if (canHeadToRr) {
+ foundPos = rightRearPos;
+ foundIt = true;
+ } else if (canHeadToLf) {
+ foundPos = leftFrontPos;
+ foundIt = true;
+ } else if (canHeadToLr) {
+ foundPos = leftRearPos;
+ foundIt = true;
+ }
+ } else if (m_vehEnterType == CAR_DOOR_LF) {
+ if (canHeadToLf) {
+ foundPos = leftFrontPos;
+ foundIt = true;
+ } else if (canHeadToLr) {
+ foundPos = leftRearPos;
+ foundIt = true;
+ } else if (canHeadToRf) {
+ foundPos = rightFrontPos;
+ foundIt = true;
+ } else if (canHeadToRr) {
+ foundPos = rightRearPos;
+ foundIt = true;
+ }
+ } else if (m_vehEnterType == CAR_DOOR_LR) {
+ if (canHeadToLr) {
+ foundPos = leftRearPos;
+ foundIt = true;
+ } else if (canHeadToLf) {
+ foundPos = leftFrontPos;
+ foundIt = true;
+ } else if (canHeadToRr) {
+ foundPos = rightRearPos;
+ foundIt = true;
+ } else if (canHeadToRf) {
+ foundPos = rightFrontPos;
+ foundIt = true;
}
- GiveWeapon(bufWeapon.m_eWeaponType, bufWeapon.m_nAmmoTotal, false);
}
}
- SkipSaveBuf(buf, 252);
+ if (!foundIt)
+ return false;
+
+ helperPos = GetPosition() - foundPos;
+ helperPos.z = 0.0f;
+ if (helperPos.MagnitudeSqr() <= sq(0.5f))
+ return false;
+
+ pos->x = foundPos.x;
+ pos->y = foundPos.y;
+ return true;
}
-#undef CopyFromBuf
-#undef CopyToBuf
-#endif
// --MIAMI: Done
void
-CPed::GiveDelayedWeapon(eWeaponType weapon, uint32 ammo)
+CPed::SetLeader(CEntity *leader)
{
- 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);
+ m_leader = (CPed*)leader;
- if ((modelId1 == -1 || CStreaming::HasModelLoaded(modelId1))
- && (modelId2 == -1 || CStreaming::HasModelLoaded(modelId2))) {
- GiveWeapon(m_delayedWeapon, m_delayedWeaponAmmo, true);
- m_delayedWeapon = WEAPONTYPE_UNIDENTIFIED;
- }
+ if (m_leader) {
+ m_leader->bIsLeader = true;
+ m_leader->RegisterReference((CEntity**)&m_leader);
}
}
// --MIAMI: Done
-void
-CPed::RequestDelayedWeapon()
+bool
+CPed::CanPedJumpThis(CEntity *unused, CVector *damageNormal)
{
- 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 (m_nSurfaceTouched == SURFACE_WATER)
+ return true;
- if ((modelId1 == -1 || CStreaming::HasModelLoaded(modelId1))
- && (modelId2 == -1 || CStreaming::HasModelLoaded(modelId2))) {
- GiveWeapon(m_delayedWeapon, m_delayedWeaponAmmo, 1);
- m_delayedWeapon = WEAPONTYPE_UNIDENTIFIED;
+ CVector pos = GetPosition();
+ CVector forwardOffset = GetForward();
+ if (damageNormal && damageNormal->z > 0.17f) {
+ if (damageNormal->z > 0.9f)
+ return false;
+
+ 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();
+ if (damageNormal->z > 0.5f) {
+ CVector invDamageNormal(-damageNormal->x, -damageNormal->y, 0.0f);
+ invDamageNormal *= 1.0f / collPower;
+ CVector estimatedJumpDist = invDamageNormal + collPower * invDamageNormal * ourCol->spheres->radius;
+ forwardOffset = estimatedJumpDist * Min(2.0f / collPower, 4.0f);
+ } else {
+ forwardOffset += collPower * ourCol->spheres->radius * forwardOffset;
}
+ } else {
+ pos.z -= 0.15f;
}
+
+ CVector forwardPos = pos + forwardOffset;
+ return CWorld::GetIsLineOfSightClear(pos, forwardPos, true, false, false, true, false, false, false);
}
// --MIAMI: Done
void
-CPed::ClearFollowPath()
+CPed::SetJump(void)
{
- for (int i = 0; i < ARRAY_SIZE(m_pathNodesToGo); i++) {
- m_pathNodesToGo[i] = nil;
+ 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);
+ jumpAssoc->SetFinishCallback(FinishLaunchCB, this);
+ m_fRotationDest = m_fRotationCur;
}
- m_nNumPathNodes = 0;
- m_nCurPathNodeId = 0;
}
// --MIAMI: Done
void
-CPed::AddInCarAnims(CVehicle* car, bool isDriver)
+CPed::FinishLaunchCB(CAnimBlendAssociation *animAssoc, void *arg)
{
- 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);
+ CPed *ped = (CPed*)arg;
+
+ if (ped->m_nPedState != PED_JUMP)
+ return;
+
+ 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) {
+ // Forward of forward
+ forward += 0.15f * ped->GetForward();
+ forward.z += 0.15f;
+ 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;
+ CAnimBlendAssociation *handsCoverAssoc = CAnimManager::BlendAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_HIT_WALL, 8.0f);
+ handsCoverAssoc->flags &= ~ASSOC_FADEOUTWHENDONE;
+ handsCoverAssoc->SetFinishCallback(FinishHitHeadCB, ped);
+ ped->bIsLanding = true;
+ return;
+ }
+
+ float velocityFromAnim = 0.1f;
+ CAnimBlendAssociation *sprintAssoc = RpAnimBlendClumpGetAssociation(ped->GetClump(), ANIM_SPRINT);
+
+ if (sprintAssoc) {
+ velocityFromAnim = 0.05f * sprintAssoc->blendAmount + 0.17f;
+ } else {
+ CAnimBlendAssociation *runAssoc = RpAnimBlendClumpGetAssociation(ped->GetClump(), ANIM_RUN);
+ if (runAssoc) {
+ velocityFromAnim = 0.07f * runAssoc->blendAmount + 0.1f;
}
- } else if (car->IsBike()) {
- if (isDriver) {
- m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ((CBike*)car)->m_bikeAnimType, ANIM_BIKE_RIDE, 100.0f);
+ }
+
+ 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() || ped->m_pCurrentPhysSurface) {
+
+#ifdef FREE_CAM
+ if (TheCamera.Cams[0].Using3rdPersonMouseCam() && !CCamera::bFreeCam) {
+#else
+ if (TheCamera.Cams[0].Using3rdPersonMouseCam()) {
+#endif
+ float fpsAngle = ped->WorkOutHeadingForMovingFirstPerson(ped->m_fRotationCur);
+ ped->m_vecMoveSpeed.x = -velocityFromAnim * Sin(fpsAngle);
+ ped->m_vecMoveSpeed.y = velocityFromAnim * Cos(fpsAngle);
} else {
- m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ((CBike*)car)->m_bikeAnimType, ANIM_BIKE_PASSENGER, 100.0f);
+ ped->m_vecMoveSpeed.x = -velocityFromAnim * Sin(ped->m_fRotationCur);
+ ped->m_vecMoveSpeed.y = velocityFromAnim * Cos(ped->m_fRotationCur);
}
- } 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);
- }
+
+ if (ped->m_pCurrentPhysSurface) {
+ ped->m_vecMoveSpeed.x += ped->m_pCurrentPhysSurface->m_vecMoveSpeed.x;
+ ped->m_vecMoveSpeed.y += ped->m_pCurrentPhysSurface->m_vecMoveSpeed.y;
}
}
- StopNonPartialAnims();
-}
+ ped->bIsStanding = false;
+ ped->bIsInTheAir = true;
+ animAssoc->blendDelta = -1000.0f;
+ CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_JUMP_GLIDE);
-// --MIAMI: Done
-bool
-CPed::CanBeDamagedByThisGangMember(CPed* who)
-{
- return m_gangFlags & (1 << (who->m_nPedType - PEDTYPE_GANG1));
+ if (ped->bDoBloodyFootprints) {
+ CVector bloodPos(0.0f, 0.0f, 0.0f);
+ ped->TransformToNode(bloodPos, PED_FOOTL);
+
+ bloodPos.z -= 0.1f;
+ bloodPos += 0.2f * ped->GetForward();
+
+ CShadows::AddPermanentShadow(SHADOWTYPE_DARK, gpBloodPoolTex, &bloodPos,
+ 0.26f * ped->GetForward().x,
+ 0.26f * ped->GetForward().y,
+ 0.14f * ped->GetRight().x,
+ 0.14f * ped->GetRight().y,
+ 255, 255, 0, 0, 4.0f, 3000, 1.0f);
+
+ bloodPos = CVector(0.0f, 0.0f, 0.0f);
+ ped->TransformToNode(bloodPos, PED_FOOTR);
+
+ bloodPos.z -= 0.1f;
+ bloodPos += 0.2f * ped->GetForward();
+ CShadows::AddPermanentShadow(SHADOWTYPE_DARK, gpBloodPoolTex, &bloodPos,
+ 0.26f * ped->GetForward().x,
+ 0.26f * ped->GetForward().y,
+ 0.14f * ped->GetRight().x,
+ 0.14f * ped->GetRight().y,
+ 255, 255, 0, 0, 4.0f, 3000, 1.0f);
+
+ if (ped->m_bloodyFootprintCountOrDeathTime <= 40) {
+ ped->m_bloodyFootprintCountOrDeathTime = 0;
+ ped->bDoBloodyFootprints = false;
+ } else {
+ ped->m_bloodyFootprintCountOrDeathTime -= 40;
+ }
+ }
}
// --MIAMI: Done
void
-CPed::Undress(const char* name)
+CPed::FinishJumpCB(CAnimBlendAssociation *animAssoc, void *arg)
{
- int mi = GetModelIndex();
- CAnimBlendAssociation* pAnim = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_PHONE_OUT);
- if (pAnim)
- FinishTalkingOnMobileCB(pAnim, this);
+ CPed *ped = (CPed*)arg;
- DeleteRwObject();
- if (IsPlayer())
- mi = MI_PLAYER;
- CStreaming::RequestSpecialModel(mi, name, STREAMFLAGS_DEPENDENCY | STREAMFLAGS_SCRIPTOWNED);
- CWorld::Remove(this);
+ ped->bResetWalkAnims = true;
+ ped->bIsLanding = false;
+
+ animAssoc->blendDelta = -1000.0f;
}
// --MIAMI: Done
void
-FinishTalkingOnMobileCB(CAnimBlendAssociation *assoc, void *arg)
+CPed::FinishHitHeadCB(CAnimBlendAssociation *animAssoc, 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;
+
+ if (animAssoc) {
+ animAssoc->blendDelta = -4.0f;
+ animAssoc->flags |= ASSOC_DELETEFADEDOUT;
}
- ped->m_lookTimer = 0;
+
+ if (ped->m_nPedState == PED_JUMP)
+ ped->RestorePreviousState();
+
+ ped->bIsLanding = false;
}
// --MIAMI: Done
-void
-StartTalkingOnMobileCB(CAnimBlendAssociation* assoc, void* arg)
+bool
+CPed::CanPedDriveOff(void)
{
- CPed* ped = (CPed*)arg;
- if (ped->m_nPedState == PED_ANSWER_MOBILE)
- CAnimManager::BlendAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_PHONE_TALK, 4.0f);
-}
+ if (m_nPedState != PED_DRIVING || m_lookTimer > CTimer::GetTimeInMilliseconds())
+ return false;
+ for (int i = 0; i < m_numNearPeds; i++) {
+ CPed *nearPed = m_nearPeds[i];
+ if (nearPed->m_nPedType == m_nPedType && nearPed->m_objective == OBJECTIVE_ENTER_CAR_AS_PASSENGER && nearPed->m_carInObjective == m_carInObjective) {
+ m_lookTimer = CTimer::GetTimeInMilliseconds() + 1000;
+ return false;
+ }
+ }
+ return true;
+}
// --MIAMI: Done
void
-CPed::SetAnswerMobile(void)
+CPed::SetRadioStation(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;
+ CPedModelInfo* modelInfo = (CPedModelInfo*)CModelInfo::GetModelInfo(GetModelIndex());
- RemoveWeaponModel(-1);
+ if (IsPlayer() || !m_pMyVehicle || m_pMyVehicle->pDriver != this)
+ return;
+
+ 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 = modelInfo->radio2;
+ }
+ } else {
+ m_pMyVehicle->m_nRadioStation = DMAudio.GetFavouriteRadioStation();
}
}
// --MIAMI: Done
void
-CPed::ClearAnswerMobile(void)
+CPed::WarpPedIntoCar(CVehicle *car)
{
- if (m_nLastPedState == PED_ANSWER_MOBILE)
- m_nLastPedState = PED_NONE;
+ bInVehicle = true;
+ m_pMyVehicle = car;
+ m_pMyVehicle->RegisterReference((CEntity **) &m_pMyVehicle);
+ m_carInObjective = car;
+ m_carInObjective->RegisterReference((CEntity **) &m_carInObjective);
+ SetPedState(PED_DRIVING);
+ bUsesCollision = false;
+ bIsInTheAir = false;
+ bVehExitWillBeInstant = true;
+ if (m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER) {
+ car->SetDriver(this);
+ car->pDriver->RegisterReference((CEntity **) &car->pDriver);
- if (RpAnimBlendClumpGetAssociation(GetClump(), ANIM_PHONE_TALK)) {
- CAnimBlendAssociation *assoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_PHONE_OUT, 8.0f);
- assoc->SetFinishCallback(FinishTalkingOnMobileCB, this);
+ } 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;
+ car->pPassengers[i]->RegisterReference((CEntity **) &car->pPassengers[i]);
+ break;
+ }
+ }
} else
- FinishTalkingOnMobileCB(nil, this);
+ return;
- if (m_nPedState == PED_ANSWER_MOBILE) {
- m_nPedState = PED_IDLE;
- RestorePreviousState();
- m_pVehicleAnim = nil;
+ if (IsPlayer()) {
+ car->SetStatus(STATUS_PLAYER);
+ AudioManager.PlayerJustGotInCar();
+ CCarCtrl::RegisterVehicleOfInterest(car);
+ } else {
+ car->SetStatus(STATUS_PHYSICS);
}
+
+ CWorld::Remove(this);
+ SetPosition(car->GetPosition());
+ CWorld::Add(this);
+
+ if (car->bIsAmbulanceOnDuty) {
+ car->bIsAmbulanceOnDuty = false;
+ --CCarCtrl::NumAmbulancesOnDuty;
+ }
+ if (car->bIsFireTruckOnDuty) {
+ car->bIsFireTruckOnDuty = false;
+ --CCarCtrl::NumFiretrucksOnDuty;
+ }
+ if (!car->bEngineOn) {
+ car->bEngineOn = true;
+ DMAudio.PlayOneShot(car->m_audioEntityId, SOUND_CAR_ENGINE_START, 1.0f);
+ }
+
+ RpAnimBlendClumpSetBlendDeltas(GetClump(), ASSOC_PARTIAL, -1000.0f);
+
+ AddInCarAnims(car, car->pDriver == this);
+ RemoveWeaponWhenEnteringVehicle();
+
+ if (car->bIsBus)
+ bRenderPedInCar = false;
+
+ bChangedSeat = true;
}
// --MIAMI: Done
-void
-CPed::Dress(void)
+bool
+CPed::HasAttractor(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();
+ return m_attractor != nil;
}
// --MIAMI: Done
void
-CPed::AnswerMobile(void)
+CPed::SetNewAttraction(CPedAttractor* pAttractor, const CVector& pos, float heading, float time, int32 qid)
{
- if (!IsPedInControl())
+ if (!m_attractor)
+ m_attractor = pAttractor;
+ if (m_attractor != pAttractor)
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);
+ 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
@@ -20271,330 +9613,6 @@ CPed::DettachPedFromEntity(void)
// --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::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::PositionAttachedPed()
{
if(!m_attachedTo)
@@ -20646,704 +9664,101 @@ CPed::PositionAttachedPed()
}
// --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 wepRange = 0.3f;
- float wepRangeAdjusted = wepInfo->m_fRange / 2.f;
-
- if (GetWeapon()->m_eWeaponType == WEAPONTYPE_UNARMED && !IsPlayer() && !(m_pedStats->m_flags & STAT_CAN_KICK))
- wepRangeAdjusted -= 0.3f;
-
- if (distWithTargetSc <= 5.f && victimPlayer && !victimPlayer->m_bDrunkVisualsWearOff) {
-
- if (m_pedInObjective->EnteringCar() && wepRangeAdjusted > 2.f) {
- m_vecSeekPos = m_pedInObjective->GetPosition();
- wepRangeAdjusted = 1.0f;
- wepRange = 0.5f;
- } else {
- int8 attackDir = victimPlayer->FindMeleeAttackPoint(this, distWithTarget, endOfAttack);
- if (attackDir == -1) {
- m_vecSeekPos = victimPlayer->GetPosition();
- wepRange = 4.0f;
- } else {
- victimPlayer->GetMeleeAttackCoords(m_vecSeekPos, attackDir, wepRangeAdjusted);
- distWithTargetSc = (m_vecSeekPos - GetPosition()).Magnitude();
- canReachVictim = true;
- }
- }
- } else {
- m_vecSeekPos = m_pedInObjective->GetPosition();
- wepRange = Max(0.8f, 0.9f * wepRangeAdjusted);
- wepRangeAdjusted = 1.1f * wepRangeAdjusted;
- if (victimPlayer && victimPlayer->m_bDrunkVisualsWearOff)
- 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 > wepRange && !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 / wepRangeAdjusted;
- CVector distVec = GetPosition() - m_pedInObjective->GetPosition();
- float distSqr = distVec.MagnitudeSqr();
- if (sq(wepRangeAdjusted) > 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, wepRange);
- else
- SetSeek(m_pedInObjective, wepRange);
- }
- return ATTACK_IN_PROGRESS;
- }
-
- if (m_attackTimer < CTimer::GetTimeInMilliseconds()
- && distWithTargetSc < wepRangeAdjusted && 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
-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);
- if (m_pPointGunAt)
- m_pPointGunAt->CleanUpOldReference(&m_pPointGunAt);
-
- m_pPointGunAt = vehOfTarget;
- if (vehOfTarget)
- vehOfTarget->RegisterReference((CEntity **) &m_pPointGunAt);
-
- 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);
- if (m_pPointGunAt)
- m_pPointGunAt->CleanUpOldReference(&m_pPointGunAt);
-
- m_pPointGunAt = m_pedInObjective;
- if (m_pedInObjective)
- m_pedInObjective->RegisterReference((CEntity**)&m_pPointGunAt);
-
- 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
void
-CPed::ScanForDelayedResponseThreats(void)
+CPed::Undress(const char* name)
{
- if (m_threatFlags)
- return;
+ int mi = GetModelIndex();
+ CAnimBlendAssociation* pAnim = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_PHONE_OUT);
+ if (pAnim)
+ FinishTalkingOnMobileCB(pAnim, this);
- 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;
+ DeleteRwObject();
+ if (IsPlayer())
+ mi = MI_PLAYER;
+ CStreaming::RequestSpecialModel(mi, name, STREAMFLAGS_DEPENDENCY | STREAMFLAGS_SCRIPTOWNED);
+ CWorld::Remove(this);
}
// --MIAMI: Done
void
-CPed::DeleteSunbatheIdleAnimCB(CAnimBlendAssociation *assoc, void *arg)
+CPed::Dress(void)
{
- 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();
+ 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();
}
-// --MIAMI: Done
void
-CPed::PedSetPreviousStateCB(CAnimBlendAssociation* assoc, void* arg)
+CPed::Say(uint16 audio, int32 time)
{
- CPed* ped = (CPed*)arg;
- ped->RestorePreviousState();
- ped->m_pVehicleAnim = nil;
+ if (m_delayedSoundID == -1) {
+ m_delayedSoundID = audio;
+ m_delayedSoundTimer = CTimer::GetTimeInMilliseconds() + time;
+ }
}
-// --MIAMI: Done
+#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));
void
-CPed::PedAnimShuffleCB(CAnimBlendAssociation* assoc, void* arg)
+CPed::Save(uint8*& buf)
{
- CPed *ped = (CPed*)arg;
- if (ped->EnteringCar()) {
- PedSetInCarCB(nil, ped);
- } else if (ped->m_nPedState != PED_DRIVING) {
- ped->QuitEnteringCar();
- }
+ SkipSaveBuf(buf, 52);
+ CopyToBuf(buf, GetPosition().x);
+ CopyToBuf(buf, GetPosition().y);
+ CopyToBuf(buf, GetPosition().z);
+ SkipSaveBuf(buf, 288);
+ CopyToBuf(buf, CharCreatedBy);
+ SkipSaveBuf(buf, 499);
+ CopyToBuf(buf, m_fHealth);
+ CopyToBuf(buf, m_fArmour);
+ SkipSaveBuf(buf, 172);
+ for (int i = 0; i < 10; i++) // has to be hardcoded
+ m_weapons[i].Save(buf);
+ SkipSaveBuf(buf, 252);
}
-// --MIAMI: Done
void
-PlayRandomAnimationsFromAnimBlock(CPed* ped, AssocGroupId animGroup, uint32 first, uint32 amount)
+CPed::Load(uint8*& buf)
{
- 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;
+ SkipSaveBuf(buf, 52);
+ CopyFromBuf(buf, GetMatrix().GetPosition().x);
+ CopyFromBuf(buf, GetMatrix().GetPosition().y);
+ CopyFromBuf(buf, GetMatrix().GetPosition().z);
+ SkipSaveBuf(buf, 288);
+ CopyFromBuf(buf, CharCreatedBy);
+ SkipSaveBuf(buf, 499);
+ CopyFromBuf(buf, m_fHealth);
+ CopyFromBuf(buf, m_fArmour);
+ SkipSaveBuf(buf, 172);
+ m_currentWeapon = WEAPONTYPE_UNARMED;
- if (!assoc || assoc->blendDelta < 0.0f) {
- int selectedAnimOffset;
- do
- selectedAnimOffset = CGeneral::GetRandomNumberInRange(0, amount);
- while (assoc && first + selectedAnimOffset == assoc->animId);
+ CWeapon bufWeapon;
+ for (int i = 0; i < 10; i++) { // has to be hardcoded
+ bufWeapon.Load(buf);
- assoc = CAnimManager::BlendAnimation(ped->GetClump(), animGroup, (AnimationId)(first + selectedAnimOffset), 3.0f);
+ 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);
- 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;
+ CStreaming::LoadAllRequestedModels(false);
+ }
+ GiveWeapon(bufWeapon.m_eWeaponType, bufWeapon.m_nAmmoTotal, false);
+ }
}
+ SkipSaveBuf(buf, 252);
}
-
-// --MIAMI: Done
-bool
-IsPedPointerValid_NotInWorld(CPed* pPed)
-{
- if (!pPed)
- return false;
- int index = CPools::GetPedPool()->GetJustIndex(pPed);
-#ifdef FIX_BUGS
- if (index < 0 || index >= NUMPEDS)
-#else
- if (index < 0 || index > NUMPEDS)
+#undef CopyFromBuf
+#undef CopyToBuf
#endif
- return false;
- return true;
-}
-
-// --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
-void
-CPed::SetLook(CEntity* to)
-{
- if (IsPedInControl()) {
- SetStoredState();
- SetPedState(PED_LOOK_ENTITY);
- SetLookFlag(to, false);
- }
-}
-
-// --MIAMI: Done
-// Unused
-void
-CPed::SetLook(float direction)
-{
- if (IsPedInControl()) {
- SetStoredState();
- SetPedState(PED_LOOK_HEADING);
- SetLookFlag(direction, false);
- }
-}
-
-// --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);
-}
diff --git a/src/peds/Ped.h b/src/peds/Ped.h
index 497994c2..88a16a95 100644
--- a/src/peds/Ped.h
+++ b/src/peds/Ped.h
@@ -5,7 +5,7 @@
#include "Crime.h"
#include "EventList.h"
#include "PedIK.h"
-#include "PedStats.h"
+#include "PedType.h"
#include "Physical.h"
#include "Weapon.h"
#include "WeaponInfo.h"
@@ -15,6 +15,7 @@
#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)
class CAccident;
class CObject;
@@ -51,7 +52,7 @@ enum eFormation
FORMATION_FRONT
};
-enum FightState : int8 {
+enum FightState {
FIGHTSTATE_MOVE_FINISHED = -2,
FIGHTSTATE_JUST_ATTACKED,
FIGHTSTATE_NO_MOVE,
@@ -186,7 +187,7 @@ enum eWaitState {
WAITSTATE_PLAYANIM_HANDSUP_SIMPLE,
};
-enum eObjective : uint32 {
+enum eObjective {
OBJECTIVE_NONE,
OBJECTIVE_WAIT_ON_FOOT,
OBJECTIVE_WAIT_ON_FOOT_FOR_COP,
@@ -253,7 +254,7 @@ enum eObjective : uint32 {
enum {
RANDOM_CHAR = 1,
MISSION_CHAR,
- TODO_CHAR, // TODO(Miami)
+ UNK_CHAR,
};
enum PedLineUpPhase {
@@ -270,7 +271,7 @@ enum PedOnGroundState {
PED_DEAD_ON_THE_FLOOR
};
-enum PointBlankNecessity : uint8 {
+enum PointBlankNecessity {
NO_POINT_BLANK_PED,
POINT_BLANK_FOR_WANTED_PED,
POINT_BLANK_FOR_SOMEONE_ELSE
@@ -597,7 +598,7 @@ public:
uint32 m_curFightMove;
uint32 m_lastFightMove;
uint8 m_fightButtonPressure;
- FightState m_fightState;
+ int8 m_fightState;
bool m_takeAStepAfterAttack;
uint8 m_bleedCounter;
CFire *m_pFire;
@@ -641,8 +642,8 @@ public:
uint16 m_queuedSound;
bool m_canTalk;
uint32 m_lastComment;
- CVector m_vecSeekPosEx; // used for OBJECTIVE_GUARD_SPOT
- float m_distanceToCountSeekDoneEx; // used for OBJECTIVE_GUARD_SPOT
+ CVector m_vecSpotToGuard;
+ float m_radiusToGuard;
static void *operator new(size_t);
static void *operator new(size_t, int);
@@ -652,6 +653,7 @@ public:
CPed(uint32 pedType);
~CPed(void);
+ void DeleteRwObject();
void SetModelIndex(uint32 mi);
void ProcessControl(void);
void Teleport(CVector);
@@ -701,7 +703,7 @@ public:
void CalculateNewOrientation(void);
float WorkOutHeadingForMovingFirstPerson(float);
void CalculateNewVelocity(void);
- bool CanSeeEntity(CEntity*, float);
+ bool CanSeeEntity(CEntity*, float threshold = CAN_SEE_ENTITY_ANGLE_THRESHOLD);
void RestorePreviousObjective(void);
void SetIdle(void);
#ifdef _MSC_VER
@@ -727,7 +729,7 @@ public:
CPed *CheckForDeadPeds(void);
bool CheckForExplosions(CVector2D &area);
CPed *CheckForGunShots(void);
- PointBlankNecessity CheckForPointBlankPeds(CPed*);
+ uint8 CheckForPointBlankPeds(CPed*);
bool CheckIfInTheAir(void);
void ClearAll(void);
void SetPointGunAt(CEntity*);
@@ -771,6 +773,7 @@ public:
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*);
@@ -907,7 +910,7 @@ public:
static void PedAnimShuffleCB(CAnimBlendAssociation *assoc, void *arg);
static void PedSetGetInCarPositionCB(CAnimBlendAssociation* assoc, void* arg);
- bool IsPlayer(void);
+ bool IsPlayer(void) const;
bool IsFemale(void) { return m_nPedType == PEDTYPE_CIVFEMALE || m_nPedType == PEDTYPE_PROSTITUTE; }
bool UseGroundColModel(void);
bool CanSetPedState(void);
@@ -927,7 +930,7 @@ public:
void SetStoredObjective(void);
void SetLeader(CEntity* leader);
void SetPedStats(ePedStats);
- bool IsGangMember(void);
+ bool IsGangMember(void) const;
void Die(void);
#ifdef GTA_TRAIN
void EnterTrain(void);
@@ -953,7 +956,7 @@ public:
void UpdatePosition(void);
CObject *SpawnFlyingComponent(int, int8);
void SetCarJack_AllClear(CVehicle*, uint32, uint32);
- bool CanPedJumpThis(CEntity*, CVector*);
+ bool CanPedJumpThis(CEntity *unused, CVector *damageNormal = nil);
void SetNewAttraction(CPedAttractor* pAttractor, const CVector& pos, float, float, int);
void ClearWaitState(void);
void Undress(const char*);
@@ -970,7 +973,7 @@ public:
PedState GetPedState(void) { return m_nPedState; }
void SetPedState(PedState state)
{
- if (GetPedState() == PED_FOLLOW_PATH)
+ if (GetPedState() == PED_FOLLOW_PATH && state != PED_FOLLOW_PATH)
ClearFollowPath();
m_nPedState = state;
}
@@ -983,7 +986,7 @@ public:
bool Driving(void) { return m_nPedState == PED_DRIVING; }
bool InVehicle(void) { return bInVehicle && m_pMyVehicle; } // True when ped is sitting/standing in vehicle, not in enter/exit state.
bool EnteringCar(void) { return m_nPedState == PED_ENTER_CAR || m_nPedState == PED_CARJACK; }
- bool HasAttractor(void) { return m_attractor != nil; }
+ bool 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 ||
@@ -992,20 +995,30 @@ public:
void ReplaceWeaponWhenExitingVehicle(void);
void RemoveWeaponWhenEnteringVehicle(void);
- bool IsNotInWreckedVehicle();
+ 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)
+ if (m_nPedType == PEDTYPE_COP && weapon->IsFlagSet(WEAPONFLAG_COP3_RD))
return ANIM_WEAPON_FIRE_3RD;
else
return GetPrimaryFireAnim(weapon);
}
+ static AnimationId Get3rdFireAnim(CWeaponInfo* weapon) {
+ if (weapon->IsFlagSet(WEAPONFLAG_COP3_RD))
+ return ANIM_WEAPON_FIRE_3RD;
+ else
+ return (AnimationId)0;
+ }
+
static AnimationId GetFireAnimGround(CWeaponInfo* weapon, bool kickFloorIfNone = true) {
- if (!!weapon->m_bGround2nd)
+ if (weapon->IsFlagSet(WEAPONFLAG_GROUND_2ND))
return ANIM_WEAPON_CROUCHFIRE;
- else if (!!weapon->m_bGround3rd)
+ else if (weapon->IsFlagSet(WEAPONFLAG_GROUND_3RD))
return ANIM_WEAPON_FIRE_3RD;
else if (kickFloorIfNone)
return ANIM_KICK_FLOOR;
@@ -1014,53 +1027,68 @@ public:
}
static AnimationId GetPrimaryFireAnim(CWeaponInfo* weapon) {
- if (weapon->m_bAnimDetonate)
+ if (weapon->IsFlagSet(WEAPONFLAG_ANIMDETONATE))
return ANIM_BOMBER;
else
return ANIM_WEAPON_FIRE;
}
static AnimationId GetCrouchReloadAnim(CWeaponInfo* weapon) {
- if (!!weapon->m_bReload)
+ if (weapon->IsFlagSet(WEAPONFLAG_RELOAD))
return ANIM_WEAPON_CROUCHRELOAD;
else
return (AnimationId)0;
}
static AnimationId GetCrouchFireAnim(CWeaponInfo* weapon) {
- if (!!weapon->m_bCrouchFire)
+ if (weapon->IsFlagSet(WEAPONFLAG_CROUCHFIRE))
return ANIM_WEAPON_CROUCHFIRE;
else
return (AnimationId)0;
}
static AnimationId GetReloadAnim(CWeaponInfo* weapon) {
- if (!!weapon->m_bReload)
+ if (weapon->IsFlagSet(WEAPONFLAG_RELOAD))
return ANIM_WEAPON_RELOAD;
else
return (AnimationId)0;
}
static AnimationId GetFightIdleWithMeleeAnim(CWeaponInfo* weapon) {
- if (!!weapon->m_bFightMode)
+ if (weapon->IsFlagSet(WEAPONFLAG_FIGHTMODE))
return ANIM_MELEE_IDLE_FIGHTMODE;
else
return (AnimationId)0;
}
static AnimationId GetFinishingAttackAnim(CWeaponInfo* weapon) {
- if (!!weapon->m_bFinish3rd)
+ if (weapon->IsFlagSet(WEAPONFLAG_FINISH_3RD))
return ANIM_MELEE_ATTACK_FINISH;
else
return (AnimationId)0;
}
static AnimationId GetSecondFireAnim(CWeaponInfo* weapon) {
- if (!!weapon->m_bUse2nd)
+ if (weapon->IsFlagSet(WEAPONFLAG_USE_2ND))
return ANIM_WEAPON_FIRE_2ND; // or ANIM_MELEE_ATTACK_2ND
else
return (AnimationId)0;
}
+
+ static AnimationId GetMeleeStartAnim(CWeaponInfo* weapon) {
+ if (weapon->IsFlagSet(WEAPONFLAG_PARTIALATTACK))
+ return ANIM_MELEE_ATTACK_START;
+ else
+ return (AnimationId)0;
+ }
+
+ static AnimationId GetThrowAnim(CWeaponInfo *weapon)
+ {
+ if (weapon->IsFlagSet(WEAPONFLAG_THROW))
+ return ANIM_THROWABLE_START_THROW;
+ else
+ return (AnimationId)0;
+ }
// --
// My additions, because there were many, many instances of that.
@@ -1083,6 +1111,16 @@ public:
}
// --
+ inline void SetWeaponLockOnTarget(CEntity *target)
+ {
+ 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)
{
@@ -1098,7 +1136,7 @@ public:
RpHAnimHierarchy *hier = GetAnimHierarchyFromSkinClump(GetClump());
int32 idx = RpHAnimIDGetIndex(hier, m_pFrames[node]->nodeID);
RwMatrix *mats = RpHAnimHierarchyGetMatrixArray(hier);
- RwV3dTransformPoints((RwV3d*)&pos, (RwV3d*)&pos, 1, &mats[idx]);
+ RwV3dTransformPoints(&pos, &pos, 1, &mats[idx]);
}
// set by 0482:set_threat_reaction_range_multiplier opcode
@@ -1141,10 +1179,7 @@ void FinishTalkingOnMobileCB(CAnimBlendAssociation* assoc, void* arg);
void StartTalkingOnMobileCB(CAnimBlendAssociation* assoc, void* arg);
void PlayRandomAnimationsFromAnimBlock(CPed* ped, AssocGroupId animGroup, uint32 first, uint32 amount);
-// TODO(Miami): Change those when Ped struct is done
-#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
new file mode 100644
index 00000000..364e18d8
--- /dev/null
+++ b/src/peds/PedAI.cpp
@@ -0,0 +1,6939 @@
+#include "common.h"
+
+#include "main.h"
+#include "Particle.h"
+#include "RpAnimBlend.h"
+#include "Ped.h"
+#include "Wanted.h"
+#include "AnimBlendAssociation.h"
+#include "DMAudio.h"
+#include "General.h"
+#include "HandlingMgr.h"
+#include "Replay.h"
+#include "Camera.h"
+#include "PedPlacement.h"
+#include "ZoneCull.h"
+#include "Pad.h"
+#include "Pickups.h"
+#include "Train.h"
+#include "PedRoutes.h"
+#include "CopPed.h"
+#include "Script.h"
+#include "CarCtrl.h"
+#include "WaterLevel.h"
+#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;
+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)
+{
+ if (time == 0) {
+ m_objectiveTimer = 0;
+ } else if (CTimer::GetTimeInMilliseconds() > m_objectiveTimer) {
+ m_objectiveTimer = CTimer::GetTimeInMilliseconds() + time;
+ }
+}
+
+// --MIAMI: Done
+void
+CPed::SetStoredObjective(void)
+{
+ if (m_objective == m_prevObjective)
+ return;
+
+ 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)
+{
+ if (objective != OBJECTIVE_ENTER_CAR_AS_DRIVER && objective != OBJECTIVE_ENTER_CAR_AS_PASSENGER) {
+ m_prevObjective = m_objective;
+ return;
+ }
+
+ 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 ||
+ 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() || 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
+ || m_objective == OBJECTIVE_LEAVE_CAR_AND_DIE) && !IsPlayer() && !IsPedInControl()) {
+
+ bStartWanderPathOnFoot = true;
+ } else {
+ m_objective = OBJECTIVE_NONE;
+ m_prevObjective = OBJECTIVE_NONE;
+ }
+ } else if (m_prevObjective != newObj || m_prevObjective == OBJECTIVE_NONE) {
+ SetObjectiveTimer(0);
+
+ if (m_objective == newObj)
+ return;
+
+ if (IsTemporaryObjective(m_objective)) {
+ m_prevObjective = newObj;
+ } else {
+ if (m_objective != newObj)
+ SetStoredObjective();
+
+ m_objective = newObj;
+ }
+ bObjectiveCompleted = false;
+
+ switch (newObj) {
+ case OBJECTIVE_NONE:
+ m_prevObjective = OBJECTIVE_NONE;
+ break;
+ case OBJECTIVE_HAIL_TAXI:
+ m_nWaitTimer = 0;
+ SetIdle();
+ SetMoveState(PEDMOVE_STILL);
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+// --MIAMI: Done
+void
+CPed::SetObjective(eObjective newObj, void *entity)
+{
+ if (DyingOrDead())
+ return;
+
+ if (m_prevObjective == newObj && m_prevObjective != OBJECTIVE_NONE)
+ return;
+
+ if (entity == this)
+ return;
+
+ 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:
+ case OBJECTIVE_LEAVE_CAR_AND_DIE:
+ return;
+ case OBJECTIVE_ENTER_CAR_AS_PASSENGER:
+ case OBJECTIVE_ENTER_CAR_AS_DRIVER:
+ case OBJECTIVE_DESTROY_CAR:
+ case OBJECTIVE_SOLICIT_VEHICLE:
+ case OBJECTIVE_BUY_ICE_CREAM:
+ 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_WAIT_IN_CAR_THEN_GET_OUT && (newObj == OBJECTIVE_LEAVE_CAR || newObj == OBJECTIVE_LEAVE_CAR_AND_DIE)
+ && !bInVehicle)
+ return;
+ }
+
+ bObjectiveCompleted = false;
+ ClearPointGunAt();
+ m_objectiveTimer = 0;
+ if (IsTemporaryObjective(m_objective) && !IsTemporaryObjective(newObj)) {
+ m_prevObjective = newObj;
+ } else {
+ if (m_objective != newObj) {
+ if (IsTemporaryObjective(newObj))
+ ForceStoredObjective(newObj);
+ else
+ SetStoredObjective();
+ }
+ m_objective = newObj;
+ }
+
+ 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.
+ SetObjectiveTimer((uintptr)entity);
+ break;
+ 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;
+
+ 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; // 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:
+
+ 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:
+ m_pedInObjective = (CPed*)entity;
+ m_pedInObjective->RegisterReference((CEntity**)&m_pedInObjective);
+ m_pedFormation = FORMATION_REAR;
+ break;
+ case OBJECTIVE_LEAVE_CAR:
+ case OBJECTIVE_LEAVE_CAR_AND_DIE:
+ case OBJECTIVE_FLEE_CAR:
+ m_carInObjective = (CVehicle*)entity;
+ m_carInObjective->RegisterReference((CEntity **)&m_carInObjective);
+ if (m_carInObjective->bIsBus && m_leaveCarTimer == 0) {
+ for (int i = 0; i < m_carInObjective->m_nNumMaxPassengers; i++) {
+ if (m_carInObjective->pPassengers[i] == this) {
+ m_leaveCarTimer = CTimer::GetTimeInMilliseconds() + 1200 * i;
+ break;
+ }
+ }
+ }
+
+ 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)->IsBoat() && !IsPlayer() && m_pCurrentPhysSurface != entity) {
+ RestorePreviousObjective();
+ break;
+ }
+ // fall through
+ case OBJECTIVE_DESTROY_CAR:
+ case OBJECTIVE_SOLICIT_VEHICLE:
+ case OBJECTIVE_BUY_ICE_CREAM:
+ m_carInObjective = (CVehicle*)entity;
+ m_carInObjective->RegisterReference((CEntity**)&m_carInObjective);
+ m_pSeekTarget = m_carInObjective;
+ m_pSeekTarget->RegisterReference((CEntity**)&m_pSeekTarget);
+ m_vecSeekPos = CVector(0.0f, 0.0f, 0.0f);
+ if (newObj == OBJECTIVE_SOLICIT_VEHICLE) {
+ m_objectiveTimer = CTimer::GetTimeInMilliseconds() + 10000;
+ } else if (m_objective == OBJECTIVE_ENTER_CAR_AS_PASSENGER && CharCreatedBy == MISSION_CHAR &&
+ (m_carInObjective->GetStatus() == STATUS_PLAYER_DISABLED || CPad::GetPad(CWorld::PlayerInFocus)->ArePlayerControlsDisabled())) {
+ SetObjectiveTimer(14000);
+ } else {
+ m_objectiveTimer = 0;
+ }
+ break;
+ case OBJECTIVE_SET_LEADER:
+ 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;
+ }
+}
+
+// --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
+CPed::SetObjective(eObjective newObj, int16 routePoint, int16 routeType)
+{
+ if (DyingOrDead())
+ return;
+
+ if (m_prevObjective == newObj && m_prevObjective != OBJECTIVE_NONE)
+ return;
+
+ 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;
+ } else {
+ if (m_objective != newObj)
+ SetStoredObjective();
+
+ m_objective = newObj;
+ }
+
+ if (newObj == OBJECTIVE_FOLLOW_ROUTE) {
+ SetFollowRoute(routePoint, routeType);
+ }
+}
+
+// --MIAMI: Done
+void
+CPed::SetObjective(eObjective newObj, CVector dest)
+{
+ if (DyingOrDead())
+ return;
+
+ if (m_prevObjective != OBJECTIVE_NONE && m_prevObjective == newObj)
+ return;
+
+ if (m_objective == newObj) {
+ 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_vecSpotToGuard == dest)
+ return;
+ }
+ }
+
+ ClearPointGunAt();
+ m_objectiveTimer = 0;
+ bObjectiveCompleted = false;
+ switch (newObj) {
+ case OBJECTIVE_GUARD_SPOT:
+ m_vecSpotToGuard = dest;
+ m_radiusToGuard = 5.0f;
+ SetMoveState(PEDMOVE_STILL);
+ break;
+ case OBJECTIVE_GUARD_AREA:
+ case OBJECTIVE_WAIT_IN_CAR:
+ case OBJECTIVE_WAIT_IN_CAR_THEN_GET_OUT:
+ 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_FOLLOW_CAR_IN_CAR:
+ 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;
+ 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;
+ m_vecSeekPos = m_nextRoutePointPos;
+ m_distanceToCountSeekDone = 0.5f;
+ bUsePedNodeSeek = true;
+ if (sq(m_distanceToCountSeekDone) > (m_nextRoutePointPos - GetPosition()).MagnitudeSqr2D())
+ return;
+ break;
+ default: break;
+ }
+
+ if (IsTemporaryObjective(m_objective)) {
+ m_prevObjective = newObj;
+ } else {
+ if (m_objective != newObj)
+ SetStoredObjective();
+
+ m_objective = newObj;
+ }
+}
+
+// --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;
+ m_pedInObjective = nil;
+ m_carInObjective = nil;
+
+ if (m_nPedState == PED_DRIVING && m_pMyVehicle) {
+ if (m_pMyVehicle->pDriver != this) {
+ if(!IsPlayer())
+ bWanderPathAfterExitingCar = true;
+
+ SetObjective(OBJECTIVE_LEAVE_CAR, m_pMyVehicle);
+ }
+ m_nLastPedState = PED_NONE;
+ } else {
+ SetIdle();
+ SetMoveState(PEDMOVE_STILL);
+ }
+ } else {
+ bClearObjective = true;
+ }
+}
+
+// --MIAMI: Done
+void
+CPed::ClearLeader(void)
+{
+ if (!m_leader)
+ return;
+
+ m_leader = nil;
+ if (IsPedInControl()) {
+ SetObjective(OBJECTIVE_NONE);
+ if (CharCreatedBy == MISSION_CHAR) {
+ SetIdle();
+ } else {
+ SetWanderPath(CGeneral::GetRandomNumberInRange(0,8));
+ }
+ } else if (m_objective != OBJECTIVE_NONE) {
+ bClearObjective = true;
+ }
+}
+
+// --MIAMI: Done
+void
+CPed::UpdateFromLeader(void)
+{
+ if (CTimer::GetTimeInMilliseconds() <= m_objectiveTimer)
+ return;
+
+ if (!m_leader)
+ return;
+
+ CVector leaderDist;
+ if (m_leader->InVehicle())
+ leaderDist = m_leader->m_pMyVehicle->GetPosition() - GetPosition();
+ else
+ leaderDist = m_leader->GetPosition() - GetPosition();
+
+ if (leaderDist.Magnitude() > 30.0f) {
+ if (bWaitForLeaderToComeCloser) {
+ if (IsPedInControl()) {
+ SetObjective(OBJECTIVE_NONE);
+ SetIdle();
+ SetMoveState(PEDMOVE_STILL);
+ }
+ return;
+ }
+ bWaitForLeaderToComeCloser = true;
+ } else
+ bWaitForLeaderToComeCloser = false;
+
+ if (IsPedInControl()) {
+ if (m_nWaitState == WAITSTATE_PLAYANIM_TAXI)
+ WarpPedToNearLeaderOffScreen();
+
+ if (m_leader->m_nPedState == PED_DEAD) {
+ SetLeader(nil);
+ SetObjective(OBJECTIVE_FLEE_ON_FOOT_TILL_SAFE);
+ return;
+ }
+ if (!m_leader->bInVehicle) {
+ if (m_leader->m_objective != OBJECTIVE_ENTER_CAR_AS_DRIVER) {
+ if (bInVehicle) {
+ if (m_objective != OBJECTIVE_WAIT_IN_CAR_THEN_GET_OUT && m_objective != OBJECTIVE_LEAVE_CAR)
+ SetObjective(OBJECTIVE_LEAVE_CAR, m_pMyVehicle);
+
+ return;
+ }
+ if (m_objective == OBJECTIVE_ENTER_CAR_AS_PASSENGER) {
+ RestorePreviousObjective();
+ RestorePreviousState();
+ }
+ }
+ if (m_nPedType == PEDTYPE_PROSTITUTE && CharCreatedBy == RANDOM_CHAR) {
+ SetLeader(nil);
+ return;
+ }
+ }
+ if (!bInVehicle && m_leader->bInVehicle && m_leader->m_nPedState == PED_DRIVING) {
+ if (m_objective != OBJECTIVE_ENTER_CAR_AS_PASSENGER && m_objective != OBJECTIVE_ENTER_CAR_AS_DRIVER) {
+ if (m_leader->m_pMyVehicle->m_nNumPassengers < m_leader->m_pMyVehicle->m_nNumMaxPassengers)
+ SetObjective(OBJECTIVE_ENTER_CAR_AS_PASSENGER, m_leader->m_pMyVehicle);
+ }
+ } 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 && !bDontFight) {
+ CEntity *lookTargetOfLeader = m_leader->m_pLookTarget;
+
+ 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);
+ SetLookTimer(500);
+ }
+ } else {
+ if (IsPedInControl() && m_nPedState != PED_ATTACK) {
+ 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);
+ }
+ }
+ if (m_nPedState == PED_IDLE && m_leader->IsPlayer() && !bDontFight) {
+ if (ScanForThreats() && m_threatEntity) {
+ m_pLookTarget = m_threatEntity;
+ m_pLookTarget->RegisterReference((CEntity **) &m_pLookTarget);
+ TurnBody();
+ if (m_attackTimer < CTimer::GetTimeInMilliseconds() && !GetWeapon()->IsTypeMelee()) {
+ SetWeaponLockOnTarget(m_threatEntity);
+ SetAttack(m_threatEntity);
+ }
+ }
+ }
+ }
+ } else {
+ switch (m_leader->m_objective) {
+ case OBJECTIVE_WAIT_ON_FOOT:
+ case OBJECTIVE_FLEE_ON_FOOT_TILL_SAFE:
+ case OBJECTIVE_WAIT_IN_CAR:
+ case OBJECTIVE_FOLLOW_ROUTE:
+ SetObjective(m_leader->m_objective);
+ m_objectiveTimer = m_leader->m_objectiveTimer;
+ break;
+ case OBJECTIVE_GUARD_SPOT:
+ 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;
+ }
+ break;
+ 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;
+ }
+ break;
+ case OBJECTIVE_GUARD_ATTACK:
+ return;
+ case OBJECTIVE_HAIL_TAXI:
+ m_leader = nil;
+ SetObjective(OBJECTIVE_NONE);
+ break;
+ default:
+ SetObjective(OBJECTIVE_GOTO_CHAR_ON_FOOT, m_leader);
+ SetObjectiveTimer(0);
+ break;
+ }
+ }
+ } else if (bInVehicle) {
+ if ((!m_leader->bInVehicle || m_leader->m_nPedState == PED_EXIT_CAR) && m_objective != OBJECTIVE_WAIT_IN_CAR_THEN_GET_OUT) {
+
+ switch (m_leader->m_objective) {
+ case OBJECTIVE_ENTER_CAR_AS_PASSENGER:
+ case OBJECTIVE_ENTER_CAR_AS_DRIVER:
+ if (m_pMyVehicle == m_leader->m_pMyVehicle || m_pMyVehicle == m_leader->m_carInObjective)
+ break;
+
+ // fall through
+ default:
+ if (m_pMyVehicle && m_objective != OBJECTIVE_LEAVE_CAR) {
+ m_leaveCarTimer = CTimer::GetTimeInMilliseconds() + 250;
+ SetObjective(OBJECTIVE_LEAVE_CAR, m_pMyVehicle);
+ }
+
+ break;
+ }
+ }
+ }
+}
+
+// --MIAMI: Done
+void
+CPed::RestorePreviousObjective(void)
+{
+ if (m_objective == OBJECTIVE_NONE)
+ return;
+
+ if (m_objective != OBJECTIVE_LEAVE_CAR && m_objective != OBJECTIVE_ENTER_CAR_AS_PASSENGER && m_objective != OBJECTIVE_ENTER_CAR_AS_DRIVER
+ && m_nPedState != PED_CARJACK)
+ m_pedInObjective = nil;
+
+ if (m_objective == OBJECTIVE_WAIT_IN_CAR_THEN_GET_OUT) {
+ m_objective = OBJECTIVE_NONE;
+ if (m_pMyVehicle)
+ SetObjective(OBJECTIVE_LEAVE_CAR, m_pMyVehicle);
+
+ } else {
+ m_objective = m_prevObjective;
+ m_prevObjective = OBJECTIVE_NONE;
+ }
+ bObjectiveCompleted = false;
+}
+
+// --MIAMI: Done
+void
+CPed::ProcessObjective(void)
+{
+ if (bClearObjective && (IsPedInControl() || m_nPedState == PED_DRIVING)) {
+ ClearObjective();
+ bClearObjective = false;
+ }
+ UpdateFromLeader();
+
+ CVector carOrOurPos;
+ CVector targetCarOrHisPos;
+ CVector distWithTarget;
+
+ if (m_objective != OBJECTIVE_NONE && (IsPedInControl() || m_nPedState == PED_DRIVING)) {
+ if (bInVehicle) {
+ if (!m_pMyVehicle) {
+ bInVehicle = false;
+ return;
+ }
+ carOrOurPos = m_pMyVehicle->GetPosition();
+ } else {
+ carOrOurPos = GetPosition();
+ }
+
+ if (m_pedInObjective) {
+ if (m_pedInObjective->InVehicle() && m_pedInObjective->m_nPedState != PED_DRAG_FROM_CAR) {
+ targetCarOrHisPos = m_pedInObjective->m_pMyVehicle->GetPosition();
+ } else {
+ targetCarOrHisPos = m_pedInObjective->GetPosition();
+ }
+ distWithTarget = targetCarOrHisPos - carOrOurPos;
+ } else if (m_carInObjective) {
+ targetCarOrHisPos = m_carInObjective->GetPosition();
+ distWithTarget = targetCarOrHisPos - carOrOurPos;
+ }
+
+ switch (m_objective) {
+ case OBJECTIVE_WAIT_ON_FOOT:
+ 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;
+ } else if (m_nPedState != PED_FLEE_POS) {
+ CVector2D fleePos = GetPosition();
+ SetFlee(fleePos, 10000);
+ bUsePedNodeSeek = true;
+ m_pNextPathNode = nil;
+ }
+ break;
+ case OBJECTIVE_GUARD_SPOT:
+ {
+ distWithTarget = m_vecSpotToGuard - GetPosition();
+ if (m_pedInObjective) {
+ SetLookFlag(m_pedInObjective, true);
+ m_pLookTarget = m_pedInObjective;
+ m_pLookTarget->RegisterReference((CEntity **) &m_pLookTarget);
+ TurnBody();
+ }
+ float distWithTargetSc = distWithTarget.Magnitude();
+ if (2.0f * m_radiusToGuard >= distWithTargetSc) {
+ if (m_pedInObjective && m_pedInObjective->m_nPedState != PED_DEAD) {
+ if (distWithTargetSc <= m_radiusToGuard)
+ SetIdle();
+ else {
+ CVector seekPos = m_vecSpotToGuard;
+ SetSeek(seekPos, m_radiusToGuard);
+ }
+ } else if (CTimer::GetTimeInMilliseconds() > m_lookTimer) {
+ int threatType = ScanForThreats();
+ SetLookTimer(CGeneral::GetRandomNumberInRange(500, 1500));
+
+ // Second condition is pointless and isn't there in Mobile.
+ if (threatType == PED_FLAG_GUN || (threatType == PED_FLAG_EXPLOSION && m_threatEntity) || m_threatEntity) {
+ if (m_threatEntity->IsPed())
+ SetObjective(OBJECTIVE_KILL_CHAR_ON_FOOT, m_threatEntity);
+ }
+ }
+ } else {
+ CVector seekPos = m_vecSpotToGuard;
+ SetSeek(seekPos, m_radiusToGuard);
+ }
+ break;
+ }
+ case OBJECTIVE_WAIT_IN_CAR:
+ SetPedState(PED_DRIVING);
+ break;
+ case OBJECTIVE_WAIT_IN_CAR_THEN_GET_OUT:
+ SetPedState(PED_DRIVING);
+ break;
+ case OBJECTIVE_KILL_CHAR_ANY_MEANS:
+ {
+ if (m_pedInObjective) {
+ if (m_pedInObjective->IsPlayer() && CharCreatedBy != MISSION_CHAR
+ && m_nPedType != PEDTYPE_COP && FindPlayerPed()->m_pWanted->m_CurrentCops != 0
+ && !bKindaStayInSamePlace) {
+
+ SetObjective(OBJECTIVE_FLEE_ON_FOOT_TILL_SAFE);
+ break;
+ }
+ if (InVehicle()) {
+ 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;
+ if (m_nPedType == PEDTYPE_COP) {
+ m_pMyVehicle->AutoPilot.m_nCruiseSpeed = (FindPlayerPed()->m_pWanted->m_nWantedLevel * 0.1f + 0.6f) * (GAME_SPEED_TO_CARAI_SPEED * m_pMyVehicle->pHandling->Transmission.fUnkMaxVelocity);
+ m_pMyVehicle->AutoPilot.m_nCarMission = CCarAI::FindPoliceCarMissionForWantedLevel();
+ } else {
+ m_pMyVehicle->AutoPilot.m_nCruiseSpeed = GAME_SPEED_TO_CARAI_SPEED * m_pMyVehicle->pHandling->Transmission.fUnkMaxVelocity * 0.8f;
+ m_pMyVehicle->AutoPilot.m_nCarMission = MISSION_RAMPLAYER_FARAWAY;
+ }
+ m_pMyVehicle->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_AVOID_CARS;
+ }
+ } else {
+ bool targetHasVeh = m_pedInObjective->bInVehicle;
+ 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);
+ }
+ }
+ break;
+ }
+ if (distWithTarget.Magnitude() > 30.0f && !bKindaStayInSamePlace) {
+ if (m_pMyVehicle) {
+ m_pMyVehicle->AutoPilot.m_nCruiseSpeed = 0;
+ SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, m_pMyVehicle);
+ } else {
+ float closestVehDist = 60.0f;
+ int16 lastVehicle;
+ CEntity* vehicles[8];
+ 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];
+ /*
+ Not used.
+ CVector vehSpeed = nearVeh->GetSpeed();
+ CVector ourSpeed = GetSpeed();
+ */
+ CVector vehDistVec = nearVeh->GetPosition() - GetPosition();
+ if (vehDistVec.Magnitude() < closestVehDist && m_pedInObjective->m_pMyVehicle != nearVeh
+ && nearVeh->CanPedOpenLocks(this) && nearVeh->m_fHealth > 250.f) {
+
+ foundVeh = nearVeh;
+ closestVehDist = vehDistVec.Magnitude();
+ }
+ }
+ 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);
+ } else if (!GetIsOnScreen()) {
+ CVector ourPos = GetPosition();
+ int closestNode = ThePaths.FindNodeClosestToCoors(ourPos, PATH_CAR, 20.0f);
+ if (closestNode >= 0) {
+ int16 colliding;
+ CWorld::FindObjectsKindaColliding(
+ ThePaths.m_pathNodes[closestNode].GetPosition(), 10.0f, true, &colliding, 2, nil, false, true, true, false, false);
+ if (!colliding) {
+ CZoneInfo zoneInfo;
+ int chosenCarClass;
+ CTheZones::GetZoneInfoForTimeOfDay(&ourPos, &zoneInfo);
+ 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->SetHeading(DEGTORAD(200.0f));
+ newVeh->SetStatus(STATUS_ABANDONED);
+ newVeh->m_nDoorLock = CARLOCK_UNLOCKED;
+ CWorld::Add(newVeh);
+ m_pMyVehicle = newVeh;
+ if (m_pMyVehicle) {
+ m_pMyVehicle->RegisterReference((CEntity **) &m_pMyVehicle);
+ m_pMyVehicle->AutoPilot.m_nCruiseSpeed = 0;
+ SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, m_pMyVehicle);
+ }
+ }
+ }
+ }
+ }
+ }
+ break;
+ }
+ } else {
+ ClearLookFlag();
+ bObjectiveCompleted = true;
+ }
+ }
+ case OBJECTIVE_KILL_CHAR_ON_FOOT:
+ {
+ if (m_objective == OBJECTIVE_KILL_CHAR_ON_FOOT && InVehicle()) {
+ SetObjective(OBJECTIVE_LEAVE_CAR, m_pMyVehicle);
+ break;
+ }
+ if (!m_pedInObjective || m_pedInObjective->DyingOrDead()) {
+ bObjectiveCompleted = true;
+ ClearLookFlag();
+ SetMoveAnim();
+ break;
+ }
+ if (m_pedInObjective) {
+ int status;
+ if (GetWeapon()->IsTypeMelee())
+ status = KillCharOnFootMelee(carOrOurPos, targetCarOrHisPos, distWithTarget);
+ else
+ status = KillCharOnFootArmed(carOrOurPos, targetCarOrHisPos, distWithTarget);
+
+ if (status == WATCH_UNTIL_HE_DISAPPEARS)
+ return;
+ if (status == CANT_ATTACK)
+ break;
+ }
+ SetMoveAnim();
+ break;
+ }
+ case OBJECTIVE_FLEE_CHAR_ON_FOOT_TILL_SAFE:
+ case OBJECTIVE_FLEE_CHAR_ON_FOOT_ALWAYS:
+ {
+ if (InVehicle()) {
+ if (m_nPedState == PED_DRIVING)
+ SetObjective(OBJECTIVE_LEAVE_CAR, m_pMyVehicle);
+ } else if (m_nPedState != PED_FLEE_ENTITY) {
+ int time;
+ if (m_objective == OBJECTIVE_FLEE_CHAR_ON_FOOT_ALWAYS)
+ time = 0;
+ else
+ 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()) {
+ if (distWithTargetSc <= safeDistance) {
+ 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();
+ }
+ if (distWithTargetSc > 2.0f)
+ 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) {
+ if (m_leader && m_leader->m_nMoveState == PEDMOVE_SPRINT)
+ SetMoveState(PEDMOVE_SPRINT);
+ else
+ SetMoveState(PEDMOVE_RUN);
+ } else {
+ if (m_leader && m_leader->m_nMoveState != PEDMOVE_STILL
+ && m_leader->m_nMoveState != PEDMOVE_NONE) {
+ if (m_leader->IsPlayer()) {
+ if (distWithTargetSc >= 3.0f && FindPlayerPed()->m_fMoveSpeed >= 1.3f)
+ SetMoveState(PEDMOVE_RUN);
+ else
+ SetMoveState(PEDMOVE_WALK);
+ } else {
+ SetMoveState(m_leader->m_nMoveState);
+ }
+ } else if (distWithTargetSc <= 3.0f) {
+ SetMoveState(PEDMOVE_WALK);
+ } else {
+ SetMoveState(PEDMOVE_RUN);
+ }
+ }
+ }
+ if (m_objective == OBJECTIVE_GOTO_CHAR_ON_FOOT_WALKING && m_nMoveState > PEDMOVE_STILL)
+ SetMoveState(PEDMOVE_WALK);
+ }
+ } else {
+ SetObjective(OBJECTIVE_NONE);
+ }
+ break;
+ }
+ case OBJECTIVE_FOLLOW_CHAR_IN_FORMATION:
+ {
+ if (m_pedInObjective) {
+ CVector posToGo = GetFormationPosition();
+ distWithTarget = posToGo - carOrOurPos;
+ SetSeek(posToGo, 1.0f);
+ if (distWithTarget.Magnitude() <= 3.0f) {
+ SetSeek(posToGo, 1.0f);
+ if (m_pedInObjective && m_pedInObjective->m_nMoveState != PEDMOVE_STILL)
+ SetMoveState(m_pedInObjective->m_nMoveState);
+ } else {
+ SetSeek(posToGo, 1.0f);
+ SetMoveState(PEDMOVE_RUN);
+ }
+ } else {
+ SetObjective(OBJECTIVE_NONE);
+ }
+ break;
+ }
+ case OBJECTIVE_ENTER_CAR_AS_PASSENGER:
+ {
+ if (m_carInObjective) {
+ if (!bInVehicle && m_carInObjective->m_nNumPassengers >= m_carInObjective->m_nNumMaxPassengers) {
+ RestorePreviousObjective();
+ RestorePreviousState();
+ if (IsPedInControl())
+ m_pMyVehicle = nil;
+
+ break;
+ }
+
+ if (m_prevObjective == OBJECTIVE_HAIL_TAXI && !((CAutomobile*)m_carInObjective)->bTaxiLight) {
+ RestorePreviousObjective();
+ ClearObjective();
+ SetWanderPath(CGeneral::GetRandomNumber() & 7);
+ bIsRunning = false;
+ break;
+ }
+ if (m_objectiveTimer && m_objectiveTimer < CTimer::GetTimeInMilliseconds()) {
+ if (!EnteringCar()) {
+ bool 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_LR;
+ 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)) {
+ m_vehEnterType = CAR_DOOR_RF;
+ foundSeat = true;
+ }
+ }
+ if (foundSeat) {
+ SetPosition(GetPositionToOpenCarDoor(m_carInObjective, m_vehEnterType));
+ SetEnterCar(m_carInObjective, m_vehEnterType);
+ }
+ }
+ m_objectiveTimer = 0;
+ }
+ }
+ // fall through
+ }
+ case OBJECTIVE_ENTER_CAR_AS_DRIVER:
+ {
+ if (!m_carInObjective || bInVehicle) {
+ if (bInVehicle && m_pMyVehicle != m_carInObjective) {
+ SetExitCar(m_pMyVehicle, 0);
+ } else {
+ bObjectiveCompleted = true;
+ bScriptObjectiveCompleted = true;
+ RestorePreviousState();
+ }
+ } else {
+ if (m_leaveCarTimer > CTimer::GetTimeInMilliseconds()) {
+ SetMoveState(PEDMOVE_STILL);
+ break;
+ }
+ if (IsPedInControl()) {
+ if (m_prevObjective == OBJECTIVE_KILL_CHAR_ANY_MEANS) {
+ if (distWithTarget.Magnitude() < 20.0f) {
+ RestorePreviousObjective();
+ RestorePreviousState();
+ return;
+ }
+ if (m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER) {
+ 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;
+ }
+ }
+ }
+ } else if (m_objective != OBJECTIVE_ENTER_CAR_AS_PASSENGER) {
+ if (m_carInObjective->pDriver
+ && (CharCreatedBy != MISSION_CHAR || m_carInObjective->pDriver->CharCreatedBy != RANDOM_CHAR)
+ ) {
+ if (m_carInObjective->pDriver->m_nPedType == m_nPedType) {
+ SetObjective(OBJECTIVE_ENTER_CAR_AS_PASSENGER, m_carInObjective);
+ m_carInObjective->bIsBeingCarJacked = false;
+ }
+ }
+ }
+ if (m_carInObjective->IsUpsideDown() && m_carInObjective->m_vehType != VEHICLE_TYPE_BIKE) {
+ RestorePreviousObjective();
+ RestorePreviousState();
+ return;
+ }
+ if (!m_carInObjective->IsBoat() || m_nPedState == PED_SEEK_IN_BOAT) {
+ if (m_nPedState != PED_SEEK_CAR)
+ SetSeekCar(m_carInObjective, 0);
+ } else {
+ SetSeekBoatPosition(m_carInObjective);
+ }
+ if (m_nMoveState == PEDMOVE_STILL && !bVehEnterDoorIsBlocked)
+ SetMoveState(PEDMOVE_RUN);
+
+ if (m_carInObjective && m_carInObjective->m_fHealth > 0.0f) {
+ distWithTarget = m_carInObjective->GetPosition() - GetPosition();
+ if (!bInVehicle) {
+ if (nEnterCarRangeMultiplier * ENTER_CAR_MAX_DIST < distWithTarget.Magnitude()) {
+ if (!m_carInObjective->pDriver && !m_carInObjective->GetIsOnScreen() && !GetIsOnScreen())
+ WarpPedToNearEntityOffScreen(m_carInObjective);
+
+ if (CharCreatedBy != MISSION_CHAR || m_prevObjective == OBJECTIVE_KILL_CHAR_ANY_MEANS
+ || IsPlayer() && !CPad::GetPad(0)->ArePlayerControlsDisabled()) {
+ RestorePreviousObjective();
+ RestorePreviousState();
+ if (IsPedInControl())
+ m_pMyVehicle = nil;
+ } else {
+ SetIdle();
+ SetMoveState(PEDMOVE_STILL);
+ }
+ }
+ }
+ } else if (!bInVehicle) {
+ RestorePreviousObjective();
+ RestorePreviousState();
+ if (IsPedInControl())
+ m_pMyVehicle = nil;
+ }
+ }
+ }
+ 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) {
+ ClearLookFlag();
+ bObjectiveCompleted = true;
+ break;
+ }
+ float distWithTargetSc = distWithTarget.Magnitude();
+ CWeaponInfo *wepInfo = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType);
+ float wepRange = wepInfo->m_fRange;
+ m_pLookTarget = m_carInObjective;
+ m_pLookTarget->RegisterReference((CEntity **) &m_pLookTarget);
+
+ m_pSeekTarget = m_carInObjective;
+ m_pSeekTarget->RegisterReference((CEntity**) &m_pSeekTarget);
+
+ TurnBody();
+ if (m_carInObjective->m_fHealth <= 0.0f) {
+ ClearLookFlag();
+ bScriptObjectiveCompleted = true;
+ break;
+ }
+
+ 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;
+ 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 == m_carInObjective) {
+ SetAttack(m_carInObjective);
+ SetWeaponLockOnTarget(m_carInObjective);
+ SetShootTimer(CGeneral::GetRandomNumberInRange(500, 2000));
+ if (distWithTargetSc > 10.0f && !bKindaStayInSamePlace) {
+ SetAttackTimer(CGeneral::GetRandomNumberInRange(2000, 5000));
+ } else {
+ SetAttackTimer(CGeneral::GetRandomNumberInRange(50, 300));
+ SetMoveState(PEDMOVE_STILL);
+ }
+ }
+ } 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;
+
+ SetSeek(m_carInObjective, safeDistance);
+ SetMoveState(PEDMOVE_RUN);
+ }
+ }
+ SetLookFlag(m_carInObjective, false);
+ TurnBody();
+ break;
+ }
+ case OBJECTIVE_GOTO_AREA_ON_FOOT:
+ case OBJECTIVE_RUN_TO_AREA:
+ case OBJECTIVE_SPRINT_TO_AREA:
+ {
+ if (InVehicle()) {
+ SetObjective(OBJECTIVE_LEAVE_CAR, m_pMyVehicle);
+ } else {
+ distWithTarget = m_nextRoutePointPos - GetPosition();
+ distWithTarget.z = 0.0f;
+ if (sq(m_distanceToCountSeekDone) >= distWithTarget.MagnitudeSqr()) {
+ bObjectiveCompleted = true;
+ bScriptObjectiveCompleted = true;
+ SetMoveState(PEDMOVE_STILL);
+ } else if (CTimer::GetTimeInMilliseconds() > m_nPedStateTimer || m_nPedState != PED_SEEK_POS) {
+ if (bUsePedNodeSeek) {
+ CVector bestCoords(0.0f, 0.0f, 0.0f);
+ m_vecSeekPos = m_nextRoutePointPos;
+
+ 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 = CPathFind::TakeWidthIntoAccountForWandering(m_pNextPathNode, m_randomSeed);
+ }
+ CVector seekPos = m_vecSeekPos;
+ SetSeek(m_vecSeekPos, m_distanceToCountSeekDone);
+ }
+ }
+
+ break;
+ }
+ case OBJECTIVE_GUARD_ATTACK:
+ {
+ if (m_pedInObjective) {
+ SetLookFlag(m_pedInObjective, true);
+ m_pLookTarget = m_pedInObjective;
+ m_pLookTarget->RegisterReference((CEntity **) &m_pLookTarget);
+ m_lookTimer = m_attackTimer;
+ TurnBody();
+ float distWithTargetSc = distWithTarget.Magnitude();
+ if (distWithTargetSc >= 20.0f) {
+ RestorePreviousObjective();
+ } else if (m_attackTimer < CTimer::GetTimeInMilliseconds()) {
+ if (m_nPedState != PED_SEEK_ENTITY && distWithTargetSc >= 2.0f) {
+ SetSeek(m_pedInObjective, 1.0f);
+ } else {
+ SetAttack(m_pedInObjective);
+ SetShootTimer(CGeneral::GetRandomNumberInRange(500.0f, 1500.0f));
+ }
+ SetAttackTimer(1000);
+ }
+ } else {
+ RestorePreviousObjective();
+ }
+ break;
+ }
+ case OBJECTIVE_FOLLOW_ROUTE:
+ if (HaveReachedNextPointOnRoute(1.0f)) {
+ int nextPoint = GetNextPointOnRoute();
+ m_nextRoutePointPos = CRouteNode::GetPointPosition(nextPoint);
+ } else {
+ CVector seekPos = m_nextRoutePointPos;
+ SetSeek(seekPos, 0.8f);
+ }
+ break;
+ case OBJECTIVE_SOLICIT_VEHICLE:
+ if (m_carInObjective) {
+ if (m_objectiveTimer <= CTimer::GetTimeInMilliseconds()) {
+ if (!bInVehicle) {
+ SetObjective(OBJECTIVE_NONE);
+ SetWanderPath(CGeneral::GetRandomNumber() & 7);
+ m_objectiveTimer = CTimer::GetTimeInMilliseconds() + 10000;
+ if (IsPedInControl())
+ m_pMyVehicle = nil;
+ }
+ } else {
+ if (m_nPedState != PED_FLEE_ENTITY && m_nPedState != PED_SOLICIT)
+ SetSeekCar(m_carInObjective, 0);
+ }
+ } else {
+ RestorePreviousObjective();
+ RestorePreviousState();
+ if (IsPedInControl())
+ m_pMyVehicle = nil;
+ }
+ break;
+ case OBJECTIVE_HAIL_TAXI:
+ if (!RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_TAXI) && CTimer::GetTimeInMilliseconds() > m_nWaitTimer) {
+ Say(SOUND_PED_TAXI_WAIT);
+ CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_IDLE_TAXI, 4.0f);
+ m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 2000;
+ }
+ break;
+ case OBJECTIVE_CATCH_TRAIN:
+ {
+ if (m_carInObjective) {
+ SetObjective(OBJECTIVE_ENTER_CAR_AS_PASSENGER, m_carInObjective);
+ } else {
+ CVehicle* trainToEnter = nil;
+ float closestCarDist = CHECK_NEARBY_THINGS_MAX_DIST;
+ CVector pos = GetPosition();
+ int16 lastVehicle;
+ CEntity* vehicles[8];
+
+ CWorld::FindObjectsInRange(pos, 10.0f, true, &lastVehicle, 6, vehicles, false, true, false, false, false);
+ for (int i = 0; i < lastVehicle; i++) {
+ CVehicle* nearVeh = (CVehicle*)vehicles[i];
+ if (nearVeh->IsTrain()) {
+ CVector vehDistVec = GetPosition() - nearVeh->GetPosition();
+ float vehDist = vehDistVec.Magnitude();
+ if (vehDist < closestCarDist && m_pedInObjective->m_pMyVehicle != nearVeh)
+ {
+ trainToEnter = nearVeh;
+ closestCarDist = vehDist;
+ }
+ }
+ }
+ if (trainToEnter) {
+ m_carInObjective = trainToEnter;
+ m_carInObjective->RegisterReference((CEntity **) &m_carInObjective);
+ }
+ }
+ break;
+ }
+ case OBJECTIVE_BUY_ICE_CREAM:
+ if (m_carInObjective) {
+ if (m_nPedState != PED_FLEE_ENTITY && m_nPedState != PED_BUY_ICECREAM && m_nPedState != PED_CHAT)
+ SetSeekCar(m_carInObjective, 0);
+ }
+ 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 = nEnterCarRangeMultiplier * ENTER_CAR_MAX_DIST;
+ CVector pos = GetPosition();
+ int16 lastVehicle;
+ CEntity *vehicles[8];
+
+ 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 (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();
+ float vehDist = vehDistVec.Magnitude();
+ if (vehDist < closestCarDist) {
+ carToSteal = nearVeh;
+ closestCarDist = vehDist;
+ }
+ }
+ }
+ }
+ }
+ if (carToSteal) {
+ SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, carToSteal);
+ m_hitRecoverTimer = CTimer::GetTimeInMilliseconds() + 5000;
+ } else {
+ RestorePreviousObjective();
+ RestorePreviousState();
+ }
+ }
+ break;
+ }
+ case OBJECTIVE_MUG_CHAR:
+ {
+ if (m_pedInObjective) {
+ if (m_pedInObjective->IsPlayer() || m_pedInObjective->bInVehicle || m_pedInObjective->m_fHealth <= 0.0f) {
+ ClearObjective();
+ return;
+ }
+ if (m_pedInObjective->m_nMoveState > PEDMOVE_WALK) {
+ ClearObjective();
+ return;
+ }
+ if (m_pedInObjective->m_objective == OBJECTIVE_KILL_CHAR_ON_FOOT && m_pedInObjective->m_pedInObjective == this) {
+ SetObjective(OBJECTIVE_FLEE_CHAR_ON_FOOT_TILL_SAFE, m_pedInObjective);
+ SetMoveState(PEDMOVE_SPRINT);
+ return;
+ }
+ if (m_pedInObjective->m_nPedState == PED_FLEE_ENTITY && m_fleeFrom == this
+ || m_pedInObjective->m_objective == OBJECTIVE_FLEE_CHAR_ON_FOOT_TILL_SAFE && m_pedInObjective->m_pedInObjective == this) {
+ ClearObjective();
+ SetFindPathAndFlee(m_pedInObjective, 15000, true);
+ return;
+ }
+ float distWithTargetScSqr = distWithTarget.MagnitudeSqr();
+ if (distWithTargetScSqr <= sq(10.0f)) {
+ if (distWithTargetScSqr <= sq(1.4f)) {
+ 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->GetProgress() > 0.8f)) {
+ CAnimBlendAssociation *punchAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_FIGHT_PPUNCH, 8.0f);
+ punchAssoc->flags |= ASSOC_DELETEFADEDOUT;
+ punchAssoc->flags |= ASSOC_FADEOUTWHENDONE;
+ CVector2D offset(distWithTarget.x, distWithTarget.y);
+ int dir = m_pedInObjective->GetLocalDirection(offset);
+ m_pedInObjective->StartFightDefend(dir, HITLEVEL_HIGH, 5);
+ m_pedInObjective->ReactToAttack(this);
+ m_pedInObjective->Say(SOUND_PED_ROBBED);
+ Say(SOUND_PED_MUGGING);
+ bRichFromMugging = true;
+
+ // FIX: ClearObjective() clears m_pedInObjective, so get it before call
+ CPed *victim = m_pedInObjective;
+ ClearObjective();
+ if (victim->m_objective != OBJECTIVE_KILL_CHAR_ON_FOOT
+ || victim->m_pedInObjective != this) {
+ SetFindPathAndFlee(victim, 15000, true);
+ m_nLastPedState = PED_WANDER_PATH;
+ } else {
+ SetObjective(OBJECTIVE_FLEE_CHAR_ON_FOOT_TILL_SAFE, victim);
+ SetMoveState(PEDMOVE_SPRINT);
+ m_nLastPedState = PED_WANDER_PATH;
+ }
+ }
+ } else {
+ eWeaponType weaponType = GetWeapon()->m_eWeaponType;
+ if (weaponType != WEAPONTYPE_UNARMED && weaponType != WEAPONTYPE_BASEBALLBAT)
+ SetCurrentWeapon(WEAPONTYPE_UNARMED);
+
+ CAnimBlendAssociation *newReloadAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_FUCKU, 8.0f);
+ newReloadAssoc->flags |= ASSOC_DELETEFADEDOUT;
+ newReloadAssoc->flags |= ASSOC_FADEOUTWHENDONE;
+ }
+ } else {
+ SetSeek(m_pedInObjective, 1.0f);
+ CAnimBlendAssociation *walkAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WALK);
+
+ if (walkAssoc)
+ walkAssoc->speed = 1.3f;
+ }
+ } else {
+ ClearObjective();
+ SetWanderPath(CGeneral::GetRandomNumber() & 7);
+ }
+ } else {
+ m_objective = OBJECTIVE_NONE;
+ 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();
+ SetFlee(m_pMyVehicle, 6000);
+ break;
+ }
+ // fall through
+ case OBJECTIVE_LEAVE_CAR:
+ if (CTimer::GetTimeInMilliseconds() > m_leaveCarTimer) {
+ 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
+ || m_pMyVehicle->IsBoat()
+ || m_pMyVehicle->m_vecMoveSpeed.MagnitudeSqr2D() < sq(0.005f))) {
+#ifdef GTA_TRAIN
+ if (m_pMyVehicle->IsTrain())
+ SetExitTrain(m_pMyVehicle);
+ else
+#endif
+ if (m_pMyVehicle->IsBoat())
+ SetExitBoat(m_pMyVehicle);
+ else
+ SetExitCar(m_pMyVehicle, 0);
+ }
+ } else {
+ RestorePreviousObjective();
+ }
+ }
+ if (bHeldHostageInCar) {
+ if (CTheScripts::IsPlayerOnAMission()) {
+ CVehicle *playerVeh = FindPlayerVehicle();
+ if (playerVeh && playerVeh->IsPassenger(this)) {
+ if (m_leaveCarTimer != 0)
+ m_leaveCarTimer = 0;
+ }
+ }
+ }
+ break;
+ 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;
+ }
+ }
+ }
+ }
+
+ 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;
+ }
+ }
+ if (bObjectiveCompleted
+ || m_objectiveTimer > 0 && CTimer::GetTimeInMilliseconds() > m_objectiveTimer) {
+ RestorePreviousObjective();
+ if (m_objectiveTimer > CTimer::GetTimeInMilliseconds() || !m_objectiveTimer)
+ m_objectiveTimer = CTimer::GetTimeInMilliseconds() - 1;
+
+ if (CharCreatedBy != RANDOM_CHAR || bInVehicle) {
+ if (IsPedInControl())
+ RestorePreviousState();
+ } else {
+ SetWanderPath(CGeneral::GetRandomNumber() & 7);
+ }
+ ClearAimFlag();
+ ClearLookFlag();
+ }
+ }
+}
+
+// --MIAMI: Done
+void
+CPed::SetFollowRoute(int16 currentPoint, int16 routeType)
+{
+ m_routeLastPoint = currentPoint;
+ 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)
+{
+ int16 nextPoint = m_routePointsBeingPassed + m_routePointsPassed + m_routeStartPoint;
+
+ // Route is complete
+ if (nextPoint < 0 || nextPoint > NUMPEDROUTES || m_routeLastPoint != CRouteNode::GetRouteThisPointIsOn(nextPoint)) {
+
+ switch (m_routeType) {
+ case PEDROUTE_STOP_WHEN_DONE:
+ nextPoint = -1;
+ break;
+ case PEDROUTE_GO_BACKWARD_WHEN_DONE:
+ m_routePointsBeingPassed = -m_routePointsBeingPassed;
+ nextPoint = m_routePointsBeingPassed + m_routePointsPassed + m_routeStartPoint;
+ break;
+ case PEDROUTE_GO_TO_START_WHEN_DONE:
+ m_routePointsPassed = -1;
+ nextPoint = m_routePointsBeingPassed + m_routePointsPassed + m_routeStartPoint;
+ break;
+ default:
+ break;
+ }
+ }
+ return nextPoint;
+}
+
+// --MIAMI: Done
+bool
+CPed::HaveReachedNextPointOnRoute(float distToCountReached)
+{
+ if ((m_nextRoutePointPos - GetPosition()).Magnitude2D() < distToCountReached) {
+ m_routePointsPassed += m_routePointsBeingPassed;
+ return true;
+ }
+ return false;
+}
+
+// --MIAMI: Done
+bool
+CPed::CanSeeEntity(CEntity *entity, float threshold)
+{
+ float neededAngle = CGeneral::GetRadianAngleBetweenPoints(
+ entity->GetPosition().x,
+ entity->GetPosition().y,
+ GetPosition().x,
+ GetPosition().y);
+
+ if (neededAngle < 0.0f)
+ neededAngle += TWOPI;
+ else if (neededAngle > TWOPI)
+ neededAngle -= TWOPI;
+
+ float ourAngle = m_fRotationCur;
+ if (ourAngle < 0.0f)
+ ourAngle += TWOPI;
+ else if (ourAngle > TWOPI)
+ ourAngle -= TWOPI;
+
+ float neededTurn = Abs(neededAngle - ourAngle);
+
+ 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 < TOTAL_WEAPON_SLOTS; i++) {
+ if (GetWeapon(i).m_nAmmoTotal > 0) {
+ eWeaponType weaponType = GetWeapon(i).m_eWeaponType;
+
+ 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;
+ }
+ }
+ }
+ SetCurrentWeapon(WEAPONTYPE_UNARMED);
+ return false;
+}
+// --MIAMI: Done
+void
+CPed::ReactToPointGun(CEntity *entWithGun)
+{
+ CPed *pedWithGun = (CPed*)entWithGun;
+ int waitTime;
+
+ 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 || (m_nPedType == PEDTYPE_GANG7 && pedWithGun == FindPlayerPed()))
+ return;
+
+ if (m_leader) {
+ if (FindPlayerPed() == m_leader)
+ return;
+
+ ClearLeader();
+ }
+ if (m_pedStats->m_flags & STAT_GUN_PANIC
+ && (m_nPedState != PED_ATTACK || GetWeapon()->IsTypeMelee())
+ && m_nPedState != PED_FLEE_ENTITY && m_nPedState != PED_AIM_GUN) {
+
+ waitTime = CGeneral::GetRandomNumberInRange(3000, 6000);
+ SetWaitState(WAITSTATE_PLAYANIM_HANDSCOWER, &waitTime);
+ Say(SOUND_PED_HANDS_COWER);
+ m_pLookTarget = pedWithGun;
+ m_pLookTarget->RegisterReference((CEntity **) &m_pLookTarget);
+ SetMoveState(PEDMOVE_NONE);
+
+ } else if (m_nPedType != pedWithGun->m_nPedType) {
+ if (IsGangMember() || m_nPedType == PEDTYPE_EMERGENCY || m_nPedType == PEDTYPE_FIREMAN) {
+ RegisterThreatWithGangPeds(pedWithGun);
+ }
+
+ if (m_nPedType == PEDTYPE_COP) {
+ if (pedWithGun->IsPlayer()) {
+ ((CPlayerPed*)pedWithGun)->m_pWanted->SetWantedLevelNoDrop(2);
+ if (bCrouchWhenShooting || bKindaStayInSamePlace) {
+ SetDuck(CGeneral::GetRandomNumberInRange(1000, 3000));
+ return;
+ }
+ }
+ }
+
+ if (m_nPedType != PEDTYPE_COP
+ && (m_nPedState != PED_ATTACK || GetWeapon()->IsTypeMelee())
+ && (m_nPedState != PED_FLEE_ENTITY || pedWithGun->IsPlayer() && m_fleeFrom != pedWithGun)
+ && m_nPedState != PED_AIM_GUN && m_objective != OBJECTIVE_KILL_CHAR_ON_FOOT) {
+
+ waitTime = CGeneral::GetRandomNumberInRange(3000, 6000);
+ SetWaitState(WAITSTATE_PLAYANIM_HANDSUP, &waitTime);
+ Say(SOUND_PED_HANDS_UP);
+ m_pLookTarget = pedWithGun;
+ m_pLookTarget->RegisterReference((CEntity **) &m_pLookTarget);
+ SetMoveState(PEDMOVE_NONE);
+ if (m_nPedState == PED_FLEE_ENTITY) {
+ m_fleeFrom = pedWithGun;
+ m_fleeFrom->RegisterReference((CEntity **) &m_fleeFrom);
+ }
+
+ if (FindPlayerPed() == pedWithGun && bRichFromMugging) {
+ int money = CGeneral::GetRandomNumberInRange(100, 300);
+ int pickupCount = money / 40 + 1;
+ int moneyPerPickup = money / pickupCount;
+
+ for (int i = 0; i < pickupCount; i++) {
+ float pickupX = 1.5f * Sin((CGeneral::GetRandomNumber() % 256)/256.0f * TWOPI) + GetPosition().x;
+ float pickupY = 1.5f * Cos((CGeneral::GetRandomNumber() % 256)/256.0f * TWOPI) + 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));
+ }
+ }
+ bRichFromMugging = false;
+ }
+ }
+ }
+}
+
+// --MIAMI: Done
+void
+CPed::ReactToAttack(CEntity *attacker)
+{
+ if (IsPlayer() && attacker->IsPed()) {
+ InformMyGangOfAttack(attacker);
+ SetLookFlag(attacker, true);
+ 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);
+ }
+
+ } 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
+ && (m_pMyVehicle->GetStatus() == STATUS_SIMPLE || m_pMyVehicle->GetStatus() == STATUS_PHYSICS)
+ && m_pMyVehicle->AutoPilot.m_nCarMission == MISSION_CRUISE) {
+
+ 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 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) {
+ if (!attackerPed->GetWeapon()->IsTypeMelee()) {
+ m_duckAndCoverTimer = CTimer::GetTimeInMilliseconds();
+ return;
+ }
+ } else if (bCrouchWhenShooting || bKindaStayInSamePlace) {
+ SetDuck(CGeneral::GetRandomNumberInRange(1000,3000));
+ return;
+ }
+
+ 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);
+ }
+ }
+ }
+ }
+}
+
+// --MIAMI: Done
+void
+CPed::PedAnimAlignCB(CAnimBlendAssociation *animAssoc, void *arg)
+{
+ CPed *ped = (CPed*)arg;
+
+ CVehicle *veh = ped->m_pMyVehicle;
+ if (animAssoc)
+ animAssoc->blendDelta = -1000.0f;
+
+ if (!ped->IsNotInWreckedVehicle())
+ return;
+
+ if (!ped->EnteringCar()) {
+ if (ped->m_nPedState != PED_DRIVING)
+ 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;
+ bool itsLow = !!veh->bLowVehicle;
+ eDoors enterDoor;
+
+ switch (ped->m_vehEnterType) {
+ case CAR_DOOR_RF:
+ itsVan = false;
+ enterDoor = DOOR_FRONT_RIGHT;
+ break;
+ case CAR_DOOR_RR:
+ enterDoor = DOOR_REAR_RIGHT;
+ break;
+ case CAR_DOOR_LF:
+ itsVan = false;
+ enterDoor = DOOR_FRONT_LEFT;
+ break;
+ case CAR_DOOR_LR:
+ enterDoor = DOOR_REAR_LEFT;
+ break;
+ default:
+ 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 || 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) {
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_VAN, ANIM_VAN_GETIN);
+ } else if (itsBus) {
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_COACH, ANIM_COACH_IN_R);
+ } else if (itsLow) {
+ 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);
+ }
+ } else if (itsVan) {
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_VAN, ANIM_VAN_GETIN_L);
+ } else if (itsBus) {
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_COACH, ANIM_COACH_IN_L);
+ } else if (itsLow) {
+ 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);
+
+ } else if (veh->CanPedOpenLocks(ped)) {
+
+ veh->AutoPilot.m_nCruiseSpeed = 0;
+ if (enterDoor != DOOR_FRONT_LEFT && enterDoor != DOOR_REAR_LEFT) {
+ if (itsVan) {
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_VAN, ANIM_VAN_OPEN);
+ } else if (itsBus) {
+ 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_VAN, ANIM_VAN_OPEN_L);
+ } else if (itsBus) {
+ 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) {
+
+ if (!veh->bLowVehicle
+ && veh->pDriver->CharCreatedBy != MISSION_CHAR
+ && veh->pDriver->m_nPedState == PED_DRIVING) {
+
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_QJACK);
+ ped->m_pVehicleAnim->SetFinishCallback(PedAnimGetInCB, 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);
+
+ } else {
+ if (enterDoor != DOOR_FRONT_LEFT && enterDoor != DOOR_REAR_LEFT)
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_DOORLOCKED_RHS);
+ else
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_DOORLOCKED_LHS);
+
+ ped->bCancelEnteringCar = true;
+ ped->m_pVehicleAnim->SetFinishCallback(PedAnimDoorOpenCB, ped);
+ }
+}
+
+// --MIAMI: Done
+void
+CPed::PedAnimDoorOpenCB(CAnimBlendAssociation* animAssoc, void* arg)
+{
+ CPed* ped = (CPed*)arg;
+
+ CVehicle* veh = ped->m_pMyVehicle;
+
+ if (animAssoc)
+ animAssoc->blendDelta = -1000.0f;
+
+ if (!ped->IsNotInWreckedVehicle())
+ return;
+
+ if (!ped->EnteringCar()) {
+ if(ped->m_nPedState != PED_DRIVING)
+ ped->QuitEnteringCar();
+
+ return;
+ }
+
+ eDoors door;
+ CPed *pedInSeat = nil;
+ switch (ped->m_vehEnterType) {
+ 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);
+ }
+
+ if (ped->m_fHealth == 0.0f || CPad::GetPad(0)->ArePlayerControlsDisabled() && pedInSeat && pedInSeat->IsPlayer()) {
+ ped->QuitEnteringCar();
+ return;
+ }
+
+ bool isVan = veh->bIsVan;
+ bool isBus = veh->bIsBus;
+ bool isLow = veh->bLowVehicle;
+ bool vehUpsideDown = veh->IsUpsideDown();
+ if (ped->bCancelEnteringCar) {
+ if (ped->IsPlayer()) {
+ if (veh->pDriver) {
+ if (veh->pDriver->m_nPedType == PEDTYPE_COP) {
+ FindPlayerPed()->SetWantedLevelNoDrop(1);
+ }
+ }
+ }
+#ifdef CANCELLABLE_CAR_ENTER
+ if (!veh->IsDoorMissing(door) && veh->CanPedOpenLocks(ped) && veh->IsCar()) {
+ ((CAutomobile*)veh)->Damage.SetDoorStatus(door, DOOR_STATUS_SWINGING);
+ }
+#endif
+ ped->QuitEnteringCar();
+ ped->RestorePreviousObjective();
+ ped->bCancelEnteringCar = false;
+ return;
+ }
+ if (!veh->IsDoorMissing(door) && veh->IsCar()) {
+ ((CAutomobile*)veh)->Damage.SetDoorStatus(door, DOOR_STATUS_SWINGING);
+ }
+
+ 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);
+ else
+ ped->SetFall(1000, ANIM_KO_SPIN_L, false);
+
+ return;
+ }
+ veh->ProcessOpenDoor(ped->m_vehEnterType, ANIM_CAR_OPEN_LHS, 1.0f);
+
+ if (ped->m_vehEnterType == CAR_DOOR_LF || ped->m_vehEnterType == CAR_DOOR_RF)
+ isVan = false;
+
+ if (ped->m_nPedState != PED_CARJACK || isBus) {
+
+ 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) {
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_COACH, ANIM_COACH_IN_L);
+ } 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);
+ }
+ } else {
+ 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->SetFinishCallback(PedAnimGetInCB, ped);
+ } else {
+ CPed *pedToDragOut = nil;
+ switch (ped->m_vehEnterType) {
+ case CAR_DOOR_RF: pedToDragOut = veh->pPassengers[0]; break;
+ case CAR_DOOR_RR: pedToDragOut = veh->pPassengers[2]; break;
+ case CAR_DOOR_LF: pedToDragOut = veh->pDriver; break;
+ case CAR_DOOR_LR: pedToDragOut = veh->pPassengers[1]; break;
+ default: assert(0);
+ }
+
+ if (vehUpsideDown) {
+ ped->QuitEnteringCar();
+ if (ped->m_nPedType == PEDTYPE_COP)
+ ((CCopPed*)ped)->SetArrestPlayer(ped->m_pedInObjective);
+ }
+
+ 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();
+ pedToDragOut = nil;
+ } else {
+ if (isLow)
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_PULLOUT_LOW_RHS);
+ else
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_PULLOUT_RHS);
+
+ ped->m_pVehicleAnim->SetFinishCallback(PedAnimPullPedOutCB, ped);
+ }
+ } else if (ped->m_nPedType == PEDTYPE_COP) {
+ ped->QuitEnteringCar();
+ if (ped->m_pedInObjective && ped->m_pedInObjective->m_nPedState == PED_DRIVING) {
+ veh->SetStatus(STATUS_PLAYER_DISABLED);
+
+ 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 {
+ 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->SetFinishCallback(PedAnimGetInCB, ped);
+ }
+ } else if (pedToDragOut) {
+
+ 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_PULLOUT_LOW_LHS);
+ else
+ 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) {
+ 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 (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)
+{
+ CPed* ped = (CPed*)arg;
+
+ CVehicle* veh = ped->m_pMyVehicle;
+ if (animAssoc)
+ animAssoc->blendDelta = -1000.0f;
+
+ if (ped->EnteringCar()) {
+ if (!ped->IsNotInWreckedVehicle())
+ return;
+
+#ifdef CANCELLABLE_CAR_ENTER
+ if (ped->bCancelEnteringCar) {
+ ped->QuitEnteringCar();
+ ped->RestorePreviousObjective();
+ ped->bCancelEnteringCar = false;
+ return;
+ }
+#endif
+
+ bool isLow = !!veh->bLowVehicle;
+
+ int padNo;
+ if (ped->IsPlayer()) {
+
+ // BUG? This will cause crash if m_nPedType is bigger then 1, there are only 2 pads
+ switch (ped->m_nPedType) {
+ case PEDTYPE_PLAYER1:
+ padNo = 0;
+ break;
+ case PEDTYPE_PLAYER2:
+ padNo = 1;
+ break;
+ case PEDTYPE_PLAYER3:
+ padNo = 2;
+ break;
+ case PEDTYPE_PLAYER4:
+ padNo = 3;
+ break;
+ }
+ CPad *pad = CPad::GetPad(padNo);
+
+ if (!pad->ArePlayerControlsDisabled()) {
+
+ if (pad->GetTarget()
+ || pad->NewState.LeftStickX
+ || pad->NewState.LeftStickY
+ || pad->NewState.DPadUp
+ || pad->NewState.DPadDown
+ || pad->NewState.DPadLeft
+ || pad->NewState.DPadRight) {
+ ped->QuitEnteringCar();
+ ped->RestorePreviousObjective();
+ return;
+ }
+ }
+ }
+
+ if (ped->m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER) {
+ 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
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_GETIN_LHS);
+ } else {
+ 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->SetFinishCallback(PedAnimGetInCB, ped);
+ } else {
+ ped->QuitEnteringCar();
+ }
+ } else if(ped->m_nPedState != PED_DRIVING) {
+ ped->QuitEnteringCar();
+ }
+}
+
+// --MIAMI: Done
+void
+CPed::PedAnimGetInCB(CAnimBlendAssociation *animAssoc, void *arg)
+{
+ CPed *ped = (CPed*) arg;
+
+ CVehicle *veh = ped->m_pMyVehicle;
+ if (animAssoc)
+ animAssoc->blendDelta = -1000.0f;
+
+ if (!ped->IsNotInWreckedVehicle() || ped->DyingOrDead())
+ return;
+
+ if (!ped->EnteringCar()) {
+ if(ped->m_nPedState != PED_DRIVING)
+ ped->QuitEnteringCar();
+ return;
+ }
+
+ ped->RemoveWeaponWhenEnteringVehicle();
+ if (ped->IsPlayer() && ped->bGonnaKillTheCarJacker && ((CPlayerPed*)ped)->m_pArrestingCop) {
+ PedSetInCarCB(nil, ped);
+ ped->m_nLastPedState = ped->m_nPedState;
+ ped->SetPedState(PED_ARRESTED);
+ ped->bGonnaKillTheCarJacker = false;
+ if (veh) {
+ veh->m_nNumGettingIn = 0;
+ veh->m_nGettingInFlags = 0;
+ veh->bIsHandbrakeOn = true;
+ veh->SetStatus(STATUS_PLAYER_DISABLED);
+ }
+ return;
+ }
+ if (ped->IsPlayer() && ped->m_vehEnterType == CAR_DOOR_LF
+ && (Pads[0].GetAccelerate() >= 255.0f || Pads[0].GetBrake() >= 255.0f)
+ && 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;
+ eDoors enterDoor;
+ switch (ped->m_vehEnterType) {
+ case CAR_DOOR_RF:
+ isVan = false;
+ enterDoor = DOOR_FRONT_RIGHT;
+ break;
+ case CAR_DOOR_RR:
+ enterDoor = DOOR_REAR_RIGHT;
+ break;
+ case CAR_DOOR_LF:
+ isVan = false;
+ enterDoor = DOOR_FRONT_LEFT;
+ break;
+ case CAR_DOOR_LR:
+ enterDoor = DOOR_REAR_LEFT;
+ break;
+ default:
+ break;
+ }
+ 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) {
+ driver->SetObjective(OBJECTIVE_LEAVE_CAR, veh);
+ if (driver->IsPlayer()) {
+ veh->bIsHandbrakeOn = true;
+ veh->SetStatus(STATUS_PLAYER_DISABLED);
+ }
+ driver->bBusJacked = true;
+ veh->bIsBeingCarJacked = false;
+ PedSetInCarCB(nil, ped);
+ if (ped->m_nPedType == PEDTYPE_COP
+ || ped->m_objective == OBJECTIVE_KILL_CHAR_ON_FOOT
+ || ped->m_objective == OBJECTIVE_KILL_CHAR_ANY_MEANS) {
+ ped->SetObjective(OBJECTIVE_LEAVE_CAR, veh);
+ }
+ ped->m_leaveCarTimer = CTimer::GetTimeInMilliseconds() + 400;
+ return;
+ }
+ if (driver != ped && ped->m_vehEnterType != CAR_DOOR_LF) {
+ if (!driver->IsPlayer()) {
+ driver->bUsePedNodeSeek = true;
+ driver->m_pLastPathNode = nil;
+ if (driver->m_pedStats->m_temper <= driver->m_pedStats->m_fear
+ || driver->CharCreatedBy == MISSION_CHAR
+ || veh->VehicleCreatedBy == MISSION_VEHICLE) {
+ driver->bFleeAfterExitingCar = true;
+ } else {
+ driver->bGonnaKillTheCarJacker = true;
+ veh->pDriver->SetObjective(OBJECTIVE_KILL_CHAR_ON_FOOT, ped);
+
+ if (veh->pDriver->m_nPedType == PEDTYPE_COP && ped->IsPlayer()) {
+ FindPlayerPed()->SetWantedLevelNoDrop(1);
+ }
+ }
+ }
+ if ((ped->m_nPedType != PEDTYPE_EMERGENCY || veh->pDriver->m_nPedType != PEDTYPE_EMERGENCY)
+ && (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);
+ veh->pDriver->SetRadioStation();
+ 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) || !doorClosed || isBus) {
+ PedAnimDoorCloseCB(nil, ped);
+ } else {
+ if (enterDoor != DOOR_FRONT_LEFT && enterDoor != DOOR_REAR_LEFT) {
+ if (isVan) {
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_VAN, ANIM_VAN_CLOSE);
+ } else if (isLow) {
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_CLOSEDOOR_LOW_RHS);
+ } else {
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_CLOSEDOOR_RHS);
+ }
+ } else if (isVan) {
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_VAN, ANIM_VAN_CLOSE_L);
+ } else if (isLow) {
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_CLOSEDOOR_LOW_LHS);
+ } else {
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_CLOSEDOOR_LHS);
+ }
+ 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)
+{
+ CPed *ped = (CPed*)arg;
+
+ CAutomobile *veh = (CAutomobile*)(ped->m_pMyVehicle);
+
+ if (!ped->IsNotInWreckedVehicle() || ped->DyingOrDead())
+ return;
+
+ if (ped->EnteringCar()) {
+ bool isLow = !!veh->bLowVehicle;
+
+ if (!veh->bIsBus)
+ veh->ProcessOpenDoor(ped->m_vehEnterType, ANIM_CAR_CLOSEDOOR_LHS, 1.0f);
+
+ eDoors door;
+ switch (ped->m_vehEnterType) {
+ case CAR_DOOR_RF: door = DOOR_FRONT_RIGHT; break;
+ case CAR_DOOR_RR: door = DOOR_REAR_RIGHT; break;
+ case CAR_DOOR_LF: door = DOOR_FRONT_LEFT; break;
+ case CAR_DOOR_LR: door = DOOR_REAR_LEFT; break;
+ default: assert(0);
+ }
+
+ 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 || 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
+ && veh->pDriver->m_objective != OBJECTIVE_LEAVE_CAR_AND_DIE
+ || !veh->IsRoomForPedToLeaveCar(CAR_DOOR_LF, nil))))) {
+
+ 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;
+ PedSetInCarCB(nil, ped);
+
+ ped->SetObjective(OBJECTIVE_LEAVE_CAR, veh);
+ if (!ped->IsPlayer())
+ ped->bFleeAfterExitingCar = true;
+
+ ped->bUsePedNodeSeek = true;
+ ped->m_pNextPathNode = nil;
+
+ } else {
+ if (animAssoc)
+ animAssoc->blendDelta = -1000.0f;
+
+ if (isLow)
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_LSHUFFLE_RHS);
+ else
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_SHUFFLE_RHS);
+
+ ped->m_pVehicleAnim->SetFinishCallback(PedSetInCarCB, ped);
+ }
+ } 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)
+{
+ // FIX: Formations in GetFormationPosition were in range 1-8, whereas in here it's 0-7.
+ // To not change the behaviour, range in here tweaked by 1 with the use of enum.
+
+ switch (m_pedFormation) {
+ case FORMATION_REAR:
+ case FORMATION_REAR_LEFT:
+ case FORMATION_REAR_RIGHT:
+ case FORMATION_FRONT_LEFT:
+ case FORMATION_FRONT_RIGHT:
+ case FORMATION_LEFT:
+ case FORMATION_RIGHT:
+ case FORMATION_FRONT:
+ break;
+ default:
+ Error("Unknown formation type, PedAI.cpp");
+ break;
+ }
+ 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;
+ return GetPosition();
+ }
+ m_pedInObjective = m_pedInObjective->m_pedInObjective;
+ }
+
+ CVector formationOffset;
+ float offset = CGeneral::GetRandomNumberInRange(1.f, 1.25f) * 1.75f;
+ switch (m_pedFormation) {
+ case FORMATION_REAR:
+ formationOffset = CVector(0.0f, -offset, 0.0f);
+ break;
+ case FORMATION_REAR_LEFT:
+ formationOffset = CVector(-offset, -offset, 0.0f);
+ break;
+ case FORMATION_REAR_RIGHT:
+ formationOffset = CVector(offset, -offset, 0.0f);
+ break;
+ case FORMATION_FRONT_LEFT:
+ formationOffset = CVector(-offset, offset, 0.0f);
+ break;
+ case FORMATION_FRONT_RIGHT:
+ formationOffset = CVector(offset, offset, 0.0f);
+ break;
+ case FORMATION_LEFT:
+ formationOffset = CVector(-offset, 0.0f, 0.0f);
+ break;
+ case FORMATION_RIGHT:
+ formationOffset = CVector(offset, 0.0f, 0.0f);
+ break;
+ case FORMATION_FRONT:
+ formationOffset = CVector(0.0f, offset, 0.0f);
+ break;
+ default:
+ formationOffset = CVector(0.0f, 0.0f, 0.0f);
+ break;
+ }
+ 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->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;
+ }
+ CVector posForZ = ped->GetPosition();
+ CPedPlacement::FindZCoorForPed(&posForZ);
+ if (ped->GetPosition().z - 0.5f > posForZ.z) {
+ PedSetOutCarCB(nil, ped);
+ return;
+ }
+
+ veh->m_nStaticFrames = 0;
+ veh->m_vecMoveSpeed += CVector(0.001f, 0.001f, 0.001f);
+ veh->m_vecTurnSpeed += CVector(0.001f, 0.001f, 0.001f);
+ if (!veh->bIsBus)
+ veh->ProcessOpenDoor(ped->m_vehEnterType, ANIM_CAR_GETOUT_LHS, 1.0f);
+
+ /*
+ // Duplicate and only in PC for some reason
+ if (!veh) {
+ PedSetOutCarCB(nil, ped);
+ return;
+ }
+ */
+ eDoors door;
+ switch (ped->m_vehEnterType) {
+ case CAR_DOOR_RF:
+ door = DOOR_FRONT_RIGHT;
+ break;
+ case CAR_DOOR_RR:
+ door = DOOR_REAR_RIGHT;
+ break;
+ case CAR_DOOR_LF:
+ door = DOOR_FRONT_LEFT;
+ break;
+ case CAR_DOOR_LR:
+ door = DOOR_REAR_LEFT;
+ break;
+ default:
+ break;
+ }
+ bool closeDoor = !veh->IsDoorMissing(door);
+
+ int padNo;
+ if (ped->IsPlayer()) {
+
+ // BUG? This will cause crash if m_nPedType is bigger then 1, there are only 2 pads
+ switch (ped->m_nPedType) {
+ case PEDTYPE_PLAYER1:
+ padNo = 0;
+ break;
+ case PEDTYPE_PLAYER2:
+ padNo = 1;
+ break;
+ case PEDTYPE_PLAYER3:
+ padNo = 2;
+ break;
+ case PEDTYPE_PLAYER4:
+ padNo = 3;
+ break;
+ }
+ CPad* pad = CPad::GetPad(padNo);
+ bool engineIsIntact = veh->IsCar() && ((CAutomobile*)veh)->Damage.GetEngineStatus() >= 225;
+ if (!pad->ArePlayerControlsDisabled() && veh->m_nDoorLock != CARLOCK_FORCE_SHUT_DOORS
+ && (pad->GetTarget()
+ || pad->NewState.LeftStickX
+ || pad->NewState.LeftStickY
+ || pad->NewState.DPadUp
+ || pad->NewState.DPadDown
+ || pad->NewState.DPadLeft
+ || pad->NewState.DPadRight)
+ || veh->bIsBus
+ || veh->m_pCarFire
+ || engineIsIntact) {
+ closeDoor = false;
+ }
+ }
+
+ if (ped->m_objective == OBJECTIVE_LEAVE_CAR_AND_DIE)
+ closeDoor = false;
+
+ if (!closeDoor) {
+ if (!veh->IsDoorMissing(door) && !veh->bIsBus) {
+ ((CAutomobile*)veh)->Damage.SetDoorStatus(door, DOOR_STATUS_SWINGING);
+ }
+ PedSetOutCarCB(nil, ped);
+ return;
+ }
+
+ if (ped->bFleeAfterExitingCar || ped->bGonnaKillTheCarJacker) {
+#ifdef FIX_BUGS
+ if (!veh->IsDoorMissing(door))
+ ((CAutomobile*)veh)->Damage.SetDoorStatus(door, DOOR_STATUS_SWINGING);
+ PedSetOutCarCB(nil, ped);
+ return;
+#else
+ if (!veh->IsDoorMissing(door))
+ ((CAutomobile*)veh)->Damage.SetDoorStatus(DOOR_FRONT_LEFT, DOOR_STATUS_SWINGING);
+#endif
+ } else {
+ switch (door) {
+ case DOOR_FRONT_LEFT:
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_CLOSE_LHS);
+ break;
+ case DOOR_FRONT_RIGHT:
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_CLOSE_RHS);
+ break;
+ case DOOR_REAR_LEFT:
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_CLOSE_LHS);
+ break;
+ case DOOR_REAR_RIGHT:
+ ped->m_pVehicleAnim = CAnimManager::AddAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_CAR_CLOSE_RHS);
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (ped->m_pVehicleAnim)
+ ped->m_pVehicleAnim->SetFinishCallback(PedSetOutCarCB, ped);
+ return;
+}
+
+// --MIAMI: Done
+void
+CPed::LineUpPedWithCar(PedLineUpPhase phase)
+{
+ bool vehIsUpsideDown = false;
+ int vehAnim;
+ float seatPosMult = 0.0f;
+ float currentZ;
+ float adjustedTimeStep;
+ CVector autoZPos;
+
+ if (CReplay::IsPlayingBack())
+ return;
+
+ if (!bChangedSeat && phase != LINE_UP_TO_CAR_2) {
+ 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;
+ }
+ }
+ 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 (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);
+ }
+ }
+ }
+ return;
+ }
+ if (phase == LINE_UP_TO_CAR_START) {
+ m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f);
+ }
+ CVehicle *veh = m_pMyVehicle;
+
+ // Not quite right, IsUpsideDown func. checks for <= -0.9f.
+ if (veh->GetUp().z <= -0.8f)
+ vehIsUpsideDown = true;
+
+ if (m_vehEnterType == CAR_DOOR_RF || m_vehEnterType == CAR_DOOR_RR) {
+ if (vehIsUpsideDown) {
+ m_fRotationDest = -PI + veh->GetForward().Heading();
+ } else if (veh->bIsBus) {
+ m_fRotationDest = 0.5f * PI + veh->GetForward().Heading();
+ } else {
+ m_fRotationDest = veh->GetForward().Heading();
+ }
+ } else if (m_vehEnterType == CAR_DOOR_LF || m_vehEnterType == CAR_DOOR_LR) {
+ if (vehIsUpsideDown) {
+ m_fRotationDest = veh->GetForward().Heading();
+ } else if (veh->bIsBus) {
+ m_fRotationDest = -0.5f * PI + veh->GetForward().Heading();
+ } else {
+ m_fRotationDest = veh->GetForward().Heading();
+ }
+ } else {
+ // I don't know will this part ever run(maybe boats?), but the game also handles that. I don't know is it intentional.
+
+ if (vehIsUpsideDown) {
+ 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();
+ }
+ }
+
+ bool multExtractedFromAnim = false;
+ bool multExtractedFromAnimBus = false;
+ float zBlend;
+ if (m_pVehicleAnim) {
+ vehAnim = m_pVehicleAnim->animId;
+
+ switch (vehAnim) {
+ case ANIM_CAR_JACKED_RHS:
+ case ANIM_CAR_LJACKED_RHS:
+ case ANIM_CAR_JACKED_LHS:
+ case ANIM_CAR_LJACKED_LHS:
+ case ANIM_VAN_GETIN_L:
+ case ANIM_VAN_GETIN:
+ multExtractedFromAnim = true;
+ zBlend = Max(m_pVehicleAnim->GetProgress() - 0.3f, 0.0f) / (1.0f - 0.3f);
+ // fall through
+
+ 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:
+
+ if (!multExtractedFromAnim) {
+ multExtractedFromAnim = true;
+ zBlend = Max(m_pVehicleAnim->GetProgress() - 0.5f, 0.0f) / (1.0f - 0.5f);
+ }
+ // fall through
+
+ case ANIM_CAR_CRAWLOUT_RHS:
+ case ANIM_CAR_CRAWLOUT_RHS2:
+ case ANIM_VAN_GETOUT_L:
+ case ANIM_VAN_GETOUT:
+ 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:
+ if (veh && veh->IsCar() && veh->bIsBus) {
+ multExtractedFromAnimBus = true;
+ zBlend = Min(m_pVehicleAnim->GetProgress(), 0.5f) / 0.5f;
+ }
+ // fall through
+
+ case ANIM_CAR_QJACK:
+ case ANIM_CAR_GETIN_LOW_LHS:
+ case ANIM_CAR_GETIN_LOW_RHS:
+ case ANIM_DRIVE_BOAT:
+ seatPosMult = m_pVehicleAnim->GetTimeLeft() / m_pVehicleAnim->hierarchy->totalLength;
+ break;
+ case ANIM_CAR_CLOSEDOOR_LHS:
+ case ANIM_CAR_CLOSEDOOR_LOW_LHS:
+ case ANIM_CAR_CLOSEDOOR_RHS:
+ case ANIM_CAR_CLOSEDOOR_LOW_RHS:
+ case ANIM_CAR_SHUFFLE_RHS:
+ 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:
+ case ANIM_COACH_OPEN_R:
+ case ANIM_COACH_IN_L:
+ case ANIM_COACH_IN_R:
+ case ANIM_COACH_OUT_L:
+ 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;
+
+ if (phase == LINE_UP_TO_CAR_2) {
+ neededPos = GetPosition();
+ } else {
+ neededPos = GetPositionToOpenCarDoor(veh, m_vehEnterType, seatPosMult);
+ }
+
+ autoZPos = neededPos;
+
+ if (veh->bIsInWater) {
+ if (veh->m_vehType == VEHICLE_TYPE_BOAT && veh->IsUpsideDown())
+ autoZPos.z += 1.0f;
+ } else {
+ CPedPlacement::FindZCoorForPed(&autoZPos);
+ }
+
+ if (phase == LINE_UP_TO_CAR_END || phase == LINE_UP_TO_CAR_2) {
+ neededPos.z = GetPosition().z;
+
+ // Getting out
+ if (!veh->bIsBus || (veh->bIsBus && vehIsUpsideDown)) {
+ float nextZSpeed = m_vecMoveSpeed.z - GRAVITY * CTimer::GetTimeStep();
+
+ // If we're not in ground at next step, apply animation
+ if (neededPos.z + nextZSpeed >= autoZPos.z) {
+ m_vecMoveSpeed.z = nextZSpeed;
+ ApplyMoveSpeed();
+ // Removing below line breaks the animation
+ neededPos.z = GetPosition().z;
+ } else {
+ neededPos.z = autoZPos.z;
+ m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f);
+ }
+ }
+ }
+
+ if (autoZPos.z > neededPos.z) {
+ 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 {
+ 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;
+ m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f);
+ } else if (neededPos.z <= currentZ && m_pVehicleAnim && vehAnim != ANIM_VAN_CLOSE_L && vehAnim != ANIM_VAN_CLOSE) {
+ adjustedTimeStep = Min(m_pVehicleAnim->timeStep, 0.1f);
+
+ // Smoothly change ped position
+ neededPos.z = currentZ - (currentZ - neededPos.z) / (m_pVehicleAnim->GetTimeLeft() / adjustedTimeStep);
+ }
+ }
+ } else {
+ // We may need to raise up the ped
+ if (phase == LINE_UP_TO_CAR_START) {
+ currentZ = GetPosition().z;
+
+ if (neededPos.z > currentZ) {
+ if (multExtractedFromAnimBus) {
+ neededPos.z = (neededPos.z - currentZ) * zBlend + currentZ;
+ } else {
+ 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)) {
+ adjustedTimeStep = Min(m_pVehicleAnim->timeStep, 0.1f);
+
+ // Smoothly change ped position
+ neededPos.z = (neededPos.z - currentZ) / (m_pVehicleAnim->GetTimeLeft() / adjustedTimeStep) + currentZ;
+ } else if (EnteringCar() || m_nPedState == PED_DRIVING && veh->IsBike()) {
+ neededPos.z = Max(currentZ, autoZPos.z);
+ }
+ }
+ }
+ }
+ }
+
+ bool stillGettingInOut = false;
+ if (CTimer::GetTimeInMilliseconds() < m_nPedStateTimer)
+ stillGettingInOut = veh->m_vehType != VEHICLE_TYPE_BOAT || bOnBoat;
+
+ if (!stillGettingInOut) {
+ m_fRotationCur = m_fRotationDest;
+ } else {
+ float limitedDest = CGeneral::LimitRadianAngle(m_fRotationDest);
+ float timeUntilStateChange = (m_nPedStateTimer - CTimer::GetTimeInMilliseconds())/600.0f;
+
+ if (timeUntilStateChange <= 0.0f) {
+ m_vecOffsetSeek.x = 0.0f;
+ m_vecOffsetSeek.y = 0.0f;
+ }
+ m_vecOffsetSeek.z = 0.0f;
+
+ neededPos -= timeUntilStateChange * m_vecOffsetSeek;
+
+ if (PI + m_fRotationCur < limitedDest) {
+ limitedDest -= 2 * PI;
+ } else if (m_fRotationCur - PI > limitedDest) {
+ limitedDest += 2 * PI;
+ }
+ m_fRotationCur -= (m_fRotationCur - limitedDest) * (1.0f - timeUntilStateChange);
+ }
+
+ 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));
+
+ 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)
+{
+ uint8 doorFlag;
+ eDoors door;
+ CPed *pedInSeat = nil;
+
+ if (car->IsBoat())
+ return;
+
+ 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];
+ 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_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 ||
+ 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)))
+ if (!car->bIsBeingCarJacked && !(doorFlag & car->m_nGettingInFlags) && !(doorFlag & car->m_nGettingOutFlags))
+ SetCarJack_AllClear(car, m_vehEnterType, doorFlag);
+}
+
+// --MIAMI: Done
+void
+CPed::SetCarJack_AllClear(CVehicle* car, uint32 doorNode, uint32 doorFlag)
+{
+ if (m_nPedState != PED_SEEK_CAR)
+ SetStoredState();
+
+ m_pSeekTarget = car;
+ m_pSeekTarget->RegisterReference((CEntity**)&m_pSeekTarget);
+ SetPedState(PED_CARJACK);
+ car->bIsBeingCarJacked = true;
+ m_pMyVehicle = (CVehicle*)m_pSeekTarget;
+ m_pMyVehicle->RegisterReference((CEntity**)&m_pMyVehicle);
+ ((CVehicle*)m_pSeekTarget)->m_nNumGettingIn++;
+
+ 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;
+
+ 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);
+ }
+}
+
+// --MIAMI: Done
+void
+CPed::SetBeingDraggedFromCar(CVehicle *veh, uint32 vehEnterType, bool quickJack)
+{
+ if (m_nPedState == PED_DRAG_FROM_CAR)
+ return;
+
+ bUsesCollision = false;
+ m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f);
+ m_nLastPedState = PED_IDLE;
+ SetMoveState(PEDMOVE_STILL);
+ m_pSeekTarget = veh;
+ m_pSeekTarget->RegisterReference((CEntity **) &m_pSeekTarget);
+
+ 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);
+ else
+ veh->SetStatus(STATUS_ABANDONED);
+ }
+ RemoveInCarAnims();
+ SetMoveState(PEDMOVE_NONE);
+ LineUpPedWithCar(veh->IsBike() ? LINE_UP_TO_CAR_FALL : LINE_UP_TO_CAR_START);
+ m_pVehicleAnim = nil;
+ SetPedState(PED_DRAG_FROM_CAR);
+ bChangedSeat = false;
+ bWillBeQuickJacked = quickJack;
+
+ SetHeading(m_fRotationCur);
+
+ Say(SOUND_PED_CAR_JACKED);
+ SetRadioStation();
+
+ if(veh->IsBike())
+ veh->m_nGettingOutFlags |= GetBikeDoorFlagInclJumpInFromFront(m_vehEnterType);
+ else
+ veh->m_nGettingOutFlags |= GetCarDoorFlag(m_vehEnterType);
+}
+
+// --MIAMI: Done
+void
+CPed::BeingDraggedFromCar(void)
+{
+ AnimationId enterAnim;
+ bool dontRunAnim = false;
+
+ if (!m_pVehicleAnim) {
+ 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(), assocGroup, enterAnim);
+
+ m_pVehicleAnim->SetFinishCallback(PedSetDraggedOutCarCB, this);
+
+ 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);
+ LineUpPedWithCar(LINE_UP_TO_CAR_START);
+
+ } else {
+ LineUpPedWithCar(LINE_UP_TO_CAR_2);
+ }
+
+ static float mult = 5.f;
+ if (m_objective == OBJECTIVE_LEAVE_CAR_AND_DIE) {
+ if (m_pMyVehicle) {
+ m_pMyVehicle->ProcessOpenDoor(m_vehEnterType, NUM_STD_ANIMS, m_pVehicleAnim->currentTime * mult);
+ }
+ }
+}
+
+// --MIAMI: Done
+void
+CPed::SetEnterCar(CVehicle *car, uint32 unused)
+{
+ if (CCranes::IsThisCarBeingCarriedByAnyCrane(car)) {
+ RestorePreviousState();
+ RestorePreviousObjective();
+ } else {
+ uint8 doorFlag;
+ eDoors door;
+ 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
+ || car->bIsBeingCarJacked || m_pVehicleAnim
+ || doorFlag && !car->IsDoorReady(door) && !car->IsDoorFullyOpen(door))
+ SetMoveState(PEDMOVE_STILL);
+ else
+ SetEnterCar_AllClear(car, m_vehEnterType, doorFlag);
+ }
+}
+
+// --MIAMI: Done
+void
+CPed::SetEnterCar_AllClear(CVehicle *car, uint32 doorNode, uint32 doorFlag)
+{
+ float zDiff = 0.0f;
+ car->m_nGettingInFlags |= doorFlag;
+ bVehEnterDoorIsBlocked = false;
+ if (m_nPedState != PED_SEEK_CAR && m_nPedState != PED_SEEK_IN_BOAT)
+ SetStoredState();
+
+ m_pSeekTarget = car;
+ 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->IsBike()) {
+ car->bIsBeingCarJacked = true;
+ }
+
+ m_pMyVehicle = (CVehicle*)m_pSeekTarget;
+ m_pMyVehicle->RegisterReference((CEntity**) &m_pMyVehicle);
+ ((CVehicle*)m_pSeekTarget)->m_nNumGettingIn++;
+ bUsesCollision = false;
+ CVector doorOpenPos = GetPositionToOpenCarDoor(car, m_vehEnterType);
+
+ // Because buses have stairs
+ if (!m_pMyVehicle->bIsBus)
+ zDiff = Max(0.0f, doorOpenPos.z - GetPosition().z);
+
+ m_vecOffsetSeek = doorOpenPos - GetPosition();
+ m_nPedStateTimer = CTimer::GetTimeInMilliseconds() + 600;
+
+ 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);
+
+ PedSetInCarCB(nil, this);
+ bVehExitWillBeInstant = true;
+
+ } else if (car->IsBike()) {
+ PedAnimAlignCB(0, this);
+ car->AutoPilot.m_nCruiseSpeed = 0;
+
+ } else {
+ 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);
+ }
+}
+
+// --MIAMI: Done
+void
+CPed::EnterCar(void)
+{
+ if (IsNotInWreckedVehicle() && m_fHealth > 0.0f) {
+ CVehicle *veh = m_pMyVehicle;
+
+ // Not used.
+ // CVector posForDoor = GetPositionToOpenCarDoor(veh, m_vehEnterType);
+
+ if (veh->CanPedOpenLocks(this)) {
+ if (m_vehEnterType && m_pVehicleAnim) {
+ veh->ProcessOpenDoor(m_vehEnterType, m_pVehicleAnim->animId, m_pVehicleAnim->currentTime);
+ }
+ }
+ 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();
+ }
+}
+
+// --MIAMI: Done
+void
+CPed::QuitEnteringCar(void)
+{
+ CVehicle *veh = m_pMyVehicle;
+ if (m_pVehicleAnim)
+ m_pVehicleAnim->blendDelta = -1000.0f;
+
+ RestartNonPartialAnims();
+
+ if (!RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_STANCE))
+ CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_IDLE_STANCE, 100.0f);
+
+ if (veh) {
+ if (m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER || m_nPedState == PED_CARJACK)
+ veh->bIsBeingCarJacked = false;
+
+ if (veh->m_nNumGettingIn != 0)
+ veh->m_nNumGettingIn--;
+
+ if (m_objective == OBJECTIVE_ENTER_CAR_AS_DRIVER || m_objective == OBJECTIVE_ENTER_CAR_AS_PASSENGER)
+ RestorePreviousObjective();
+
+ 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;
+
+ if (DyingOrDead()) {
+ if (m_pVehicleAnim) {
+ m_pVehicleAnim->blendDelta = -4.0f;
+ m_pVehicleAnim->flags |= ASSOC_DELETEFADEDOUT;
+ m_pVehicleAnim->flags &= ~ASSOC_RUNNING;
+ }
+ } else
+ SetIdle();
+
+ m_pVehicleAnim = nil;
+
+ if (veh) {
+ if (veh->AutoPilot.m_nCruiseSpeed == 0 && veh->VehicleCreatedBy == RANDOM_VEHICLE)
+ veh->AutoPilot.m_nCruiseSpeed = 17;
+ }
+}
+
+// --MIAMI: Done
+void
+CPed::SetExitBoat(CVehicle *boat)
+{
+ SetPedState(PED_IDLE);
+ CVector newPos = GetPosition();
+ RemoveInCarAnims();
+ CColModel* boatCol = boat->GetColModel();
+ if (boat->IsUpsideDown()) {
+ newPos = { 0.0f, 0.0f, boatCol->boundingBox.min.z };
+ newPos = boat->GetMatrix() * newPos;
+ newPos.z += 1.0f;
+ m_vehEnterType = CAR_DOOR_RF;
+ PedSetOutCarCB(nil, this);
+ bIsStanding = true;
+ m_pCurSurface = boat;
+ m_pCurSurface->RegisterReference((CEntity**)&m_pCurSurface);
+ m_pCurrentPhysSurface = boat;
+ } else {
+ 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;
+ }
+
+ 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;
+}
+
+// --MIAMI: Done
+// wantedDoorNode = 0 means that func. will determine it
+void
+CPed::SetExitCar(CVehicle *veh, uint32 wantedDoorNode)
+{
+ uint32 optedDoorNode = wantedDoorNode;
+ bool teleportNeeded = false;
+ bool isLow = !!veh->bLowVehicle;
+
+ 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;
+ }
+ }
+
+ if (m_nPedState == PED_EXIT_CAR || m_nPedState == PED_DRAG_FROM_CAR)
+ return;
+
+ m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f);
+ m_vecTurnSpeed = CVector(0.0f, 0.0f, 0.0f);
+ if (wantedDoorNode == 0) {
+ 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_LR;
+ } else {
+ 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;
+ }
+ }
+ }
+ }
+ bool someoneExitsFromOurExitDoor = false;
+ bool someoneEntersFromOurExitDoor = false;
+ 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) {
+#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;
+ int firstOptedDoor = optedDoorNode;
+ if (veh->IsBike()) {
+ switch (optedDoorNode) {
+ case CAR_DOOR_RF:
+ optedDoorNode = CAR_DOOR_LF;
+ break;
+ case CAR_DOOR_RR:
+ optedDoorNode = CAR_DOOR_LR;
+ break;
+ case CAR_DOOR_LF:
+ optedDoorNode = CAR_DOOR_RF;
+ 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;
+ 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)
+ return;
+
+ switch (optedDoorNode) {
+ case CAR_DOOR_RF:
+ optedDoorNode = CAR_DOOR_LF;
+ break;
+ case CAR_DOOR_RR:
+ optedDoorNode = CAR_DOOR_LR;
+ break;
+ case CAR_DOOR_LF:
+ optedDoorNode = CAR_DOOR_RF;
+ break;
+ case CAR_DOOR_LR:
+ optedDoorNode = CAR_DOOR_RR;
+ break;
+ default:
+ break;
+ }
+ }
+ // ...
+ // CVector exitPos = GetPositionToOpenCarDoor(veh, optedDoorNode);
+ if (!veh->IsRoomForPedToLeaveCar(optedDoorNode, nil)) {
+ 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;
+ SetMoveState(PEDMOVE_SPRINT);
+ } else {
+ m_nLastPedState = PED_IDLE;
+ m_nPrevMoveState = PEDMOVE_STILL;
+ SetMoveState(PEDMOVE_STILL);
+ }
+
+ bUsesCollision = false;
+ m_pSeekTarget = veh;
+ m_pSeekTarget->RegisterReference((CEntity**) &m_pSeekTarget);
+ m_vehEnterType = optedDoorNode;
+ 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);
+ 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);
+
+ } 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;
+
+ // 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;
+ }
+
+ // Passenger get off
+ if (m_vehEnterType == CAR_BUMP_REAR || m_vehEnterType == CAR_BOOT) {
+ m_pVehicleAnim->SetFinishCallback(RestoreHeadingRateCB, this);
+ m_headingRate = 0.0f;
+
+ } else {
+ veh->m_nGettingOutFlags |= exitFlags;
+ m_pVehicleAnim->SetFinishCallback(PedAnimStepOutCarCB, this);
+ }
+
+ } else {
+ switch (m_vehEnterType) {
+ case CAR_DOOR_RF:
+ 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);
+ }
+ break;
+ case CAR_DOOR_RR:
+ 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 {
+ m_pVehicleAnim = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_GETOUT_RHS);
+ }
+ break;
+ case CAR_DOOR_LF:
+ 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);
+ }
+ break;
+ case CAR_DOOR_LR:
+ 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 {
+ m_pVehicleAnim = CAnimManager::AddAnimation(GetClump(), ASSOCGRP_STD, ANIM_CAR_GETOUT_LHS);
+ }
+ break;
+ default:
+ break;
+ }
+ if (!bBusJacked && !canJumpOut) {
+ veh->m_nGettingOutFlags |= GetCarDoorFlag(m_vehEnterType);
+ }
+ m_pVehicleAnim->SetFinishCallback(canJumpOut ? RestoreHeadingRateCB : PedAnimStepOutCarCB, this);
+ }
+ }
+ bChangedSeat = false;
+ if (veh->bIsBus)
+ bRenderPedInCar = true;
+
+ SetRadioStation();
+ if (veh->pDriver == this) {
+ if (IsPlayer())
+ veh->SetStatus(STATUS_PLAYER_DISABLED);
+ else
+ veh->SetStatus(STATUS_ABANDONED);
+ }
+ }
+}
+
+// --MIAMI: Done
+void
+CPed::ExitCar(void)
+{
+ 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;
+
+ 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);
+
+ } 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_FALL);
+ }
+ } else {
+ m_pMyVehicle->ProcessOpenDoor(m_vehEnterType, exitAnim, animTime);
+
+ 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);
+ }
+ }
+}
+
+// --MIAMI: Done
+CVector
+CPed::GetPositionToOpenCarDoor(CVehicle *veh, uint32 component)
+{
+ CVector vehDoorPos = GetPositionToOpenCarDoor(veh, component, 1.0f);
+
+/*
+ // Unused
+ vehDoorPosWithoutOffset = veh->GetMatrix() * localVehDoorPos;
+*/
+ return vehDoorPos;
+}
+
+// --MIAMI: Done
+void
+CPed::GetNearestDoor(CVehicle *veh, CVector &posToOpen)
+{
+ CVector *enterOffset = nil;
+ 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;
+ }
+
+ CVector lfPos = GetPositionToOpenCarDoor(veh, CAR_DOOR_LF);
+ CVector rfPos = GetPositionToOpenCarDoor(veh, CAR_DOOR_RF);
+
+ // Left front door is closer
+ if ((lfPos - GetPosition()).MagnitudeSqr2D() < (rfPos - GetPosition()).MagnitudeSqr2D()) {
+
+ if (veh->IsRoomForPedToLeaveCar(CAR_DOOR_LF, enterOffset)) {
+ m_vehEnterType = CAR_DOOR_LF;
+ posToOpen = lfPos;
+ } else if (veh->IsRoomForPedToLeaveCar(CAR_DOOR_RF, enterOffset)) {
+ m_vehEnterType = CAR_DOOR_RF;
+ posToOpen = rfPos;
+ }
+ } else {
+
+ if (veh->IsRoomForPedToLeaveCar(CAR_DOOR_RF, enterOffset)) {
+
+ CPed *rfPassenger = veh->pPassengers[0];
+ 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)) {
+
+ m_vehEnterType = CAR_DOOR_LF;
+ posToOpen = lfPos;
+ } else {
+ m_vehEnterType = CAR_DOOR_RF;
+ posToOpen = rfPos;
+ }
+ } else if (veh->IsRoomForPedToLeaveCar(CAR_DOOR_LF, enterOffset)) {
+ m_vehEnterType = CAR_DOOR_LF;
+ posToOpen = lfPos;
+ }
+ }
+}
+
+// --MIAMI: Done
+bool
+CPed::GetNearestPassengerDoor(CVehicle *veh, CVector &posToOpen)
+{
+ CVector rfPos, lrPos, rrPos;
+ bool canEnter = false;
+
+ CVehicleModelInfo *vehModel = (CVehicleModelInfo *)CModelInfo::GetModelInfo(veh->GetModelIndex());
+
+ switch (veh->GetModelIndex()) {
+ case MI_BUS:
+ m_vehEnterType = CAR_DOOR_RF;
+ posToOpen = GetPositionToOpenCarDoor(veh, CAR_DOOR_RF);
+ return true;
+ case MI_RHINO:
+ default:
+ break;
+ }
+
+ CVector2D rfPosDist(999.0f, 999.0f);
+ CVector2D lrPosDist(999.0f, 999.0f);
+ CVector2D rrPosDist(999.0f, 999.0f);
+
+ 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)) {
+
+ rfPos = GetPositionToOpenCarDoor(veh, CAR_DOOR_RF);
+ canEnter = true;
+ rfPosDist = rfPos - GetPosition();
+ }
+
+ if (vehModel->m_numDoors == 4) {
+ if (!veh->pPassengers[1]
+ && !(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[2]
+ && !(veh->m_nGettingInFlags & CAR_DOOR_FLAG_RR)
+ && veh->IsRoomForPedToLeaveCar(CAR_DOOR_RR, nil)) {
+ rrPos = GetPositionToOpenCarDoor(veh, CAR_DOOR_RR);
+ canEnter = true;
+ rrPosDist = rrPos - GetPosition();
+ }
+
+ // When the door we should enter is blocked by some object.
+ if (!canEnter)
+ veh->ShufflePassengersToMakeSpace();
+ }
+
+ CVector2D nextToCompare = rfPosDist;
+ posToOpen = rfPos;
+ m_vehEnterType = CAR_DOOR_RF;
+ if (lrPosDist.MagnitudeSqr() < nextToCompare.MagnitudeSqr()) {
+ m_vehEnterType = CAR_DOOR_LR;
+ posToOpen = lrPos;
+ nextToCompare = lrPosDist;
+ }
+
+ if (rrPosDist.MagnitudeSqr() < nextToCompare.MagnitudeSqr()) {
+ m_vehEnterType = CAR_DOOR_RR;
+ posToOpen = rrPos;
+ }
+ return canEnter;
+}
+
+// --MIAMI: Done
+void
+CPed::GoToNearestDoor(CVehicle *veh)
+{
+ CVector posToOpen;
+ GetNearestDoor(veh, posToOpen);
+ SetSeek(posToOpen, 0.5f);
+ 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_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;
+ CAnimManager::UncompressAnimation(enterAssoc);
+ if (seq->numFrames > 0) {
+ if (!seq->HasTranslation())
+ vecPedDraggedOutCarAnimOffset = CVector(0.0f, 0.0f, 0.0f);
+ else {
+ KeyFrameTrans *lastFrame = (KeyFrameTrans*)seq->GetKeyFrame(seq->numFrames - 1);
+ vecPedDraggedOutCarAnimOffset = lastFrame->translation;
+ }
+ }
+
+ enterAssoc = CAnimManager::GetAnimAssociation(ASSOCGRP_STD, ANIM_CAR_GETIN_LHS)->hierarchy;
+ seq = enterAssoc->sequences;
+ CAnimManager::UncompressAnimation(enterAssoc);
+ if (seq->numFrames > 0) {
+ if (!seq->HasTranslation())
+ vecPedCarDoorAnimOffset = CVector(0.0f, 0.0f, 0.0f);
+ else {
+ KeyFrameTrans *lastFrame = (KeyFrameTrans*)seq->GetKeyFrame(seq->numFrames - 1);
+ vecPedCarDoorAnimOffset = lastFrame->translation;
+ }
+ }
+
+ enterAssoc = CAnimManager::GetAnimAssociation(ASSOCGRP_STD, ANIM_CAR_GETIN_LOW_LHS)->hierarchy;
+ seq = enterAssoc->sequences;
+ CAnimManager::UncompressAnimation(enterAssoc);
+ if (seq->numFrames > 0) {
+ if (!seq->HasTranslation())
+ vecPedCarDoorLoAnimOffset = CVector(0.0f, 0.0f, 0.0f);
+ else {
+ KeyFrameTrans *lastFrame = (KeyFrameTrans*)seq->GetKeyFrame(seq->numFrames - 1);
+ vecPedCarDoorLoAnimOffset = lastFrame->translation;
+ }
+ }
+
+ enterAssoc = CAnimManager::GetAnimAssociation(ASSOCGRP_STD, ANIM_CAR_QJACKED)->hierarchy;
+ seq = enterAssoc->sequences;
+ CAnimManager::UncompressAnimation(enterAssoc);
+ if (seq->numFrames > 0) {
+ if (!seq->HasTranslation())
+ vecPedQuickDraggedOutCarAnimOffset = CVector(0.0f, 0.0f, 0.0f);
+ else {
+ KeyFrameTrans *lastFrame = (KeyFrameTrans*)seq->GetKeyFrame(seq->numFrames - 1);
+ vecPedQuickDraggedOutCarAnimOffset = lastFrame->translation;
+ }
+ }
+
+ enterAssoc = CAnimManager::GetAnimAssociation(ASSOCGRP_VAN, ANIM_VAN_GETIN_L)->hierarchy;
+ seq = enterAssoc->sequences;
+ CAnimManager::UncompressAnimation(enterAssoc);
+ if (seq->numFrames > 0) {
+ if (!seq->HasTranslation())
+ vecPedVanRearDoorAnimOffset = CVector(0.0f, 0.0f, 0.0f);
+ else {
+ KeyFrameTrans *lastFrame = (KeyFrameTrans*)seq->GetKeyFrame(seq->numFrames - 1);
+ vecPedVanRearDoorAnimOffset = lastFrame->translation;
+ }
+ }
+ // 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) {
+ if (!seq->HasTranslation())
+ vecPedTrainDoorAnimOffset = CVector(0.0f, 0.0f, 0.0f);
+ else {
+ KeyFrameTrans *lastFrame = (KeyFrameTrans*)seq->GetKeyFrame(seq->numFrames - 1);
+ 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)
+{
+ CPed *ped = (CPed*)arg;
+
+ CVehicle *veh = ped->m_pMyVehicle;
+
+ CVector finalPos;
+ CVector draggedOutOffset;
+
+ CMatrix pedMat(ped->GetMatrix());
+ ped->bUsesCollision = true;
+ ped->RestartNonPartialAnims();
+ draggedOutOffset = vecPedQuickDraggedOutCarAnimOffset;
+ if (ped->m_vehEnterType == CAR_DOOR_RF || ped->m_vehEnterType == CAR_DOOR_RR)
+ draggedOutOffset.x = -draggedOutOffset.x;
+
+ finalPos = Multiply3x3(pedMat, draggedOutOffset) + ped->GetPosition();
+ CPedPlacement::FindZCoorForPed(&finalPos);
+ ped->m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f);
+ ped->SetPosition(finalPos);
+
+ if (veh) {
+ ped->m_fRotationDest = veh->GetForward().Heading() - HALFPI;
+ ped->m_fRotationCur = ped->m_fRotationDest;
+ ped->CalculateNewOrientation();
+
+ if (!veh->IsRoomForPedToLeaveCar(ped->m_vehEnterType, &vecPedQuickDraggedOutCarAnimOffset))
+ ped->PositionPedOutOfCollision();
+ }
+
+ if (!ped->CanSetPedState())
+ return;
+
+ ped->SetIdle();
+ if (veh) {
+ if (ped->bFleeAfterExitingCar) {
+ ped->bFleeAfterExitingCar = false;
+ ped->SetFlee(veh->GetPosition(), 14000);
+
+ } else if (ped->bWanderPathAfterExitingCar) {
+ ped->SetWanderPath(CGeneral::GetRandomNumberInRange(0.0f, 8.0f));
+ ped->bWanderPathAfterExitingCar = false;
+
+ } else if (ped->bGonnaKillTheCarJacker) {
+ ped->bGonnaKillTheCarJacker = false;
+ if (ped->m_pedInObjective && CGeneral::GetRandomNumber() & 1) {
+ if (ped->m_objective != OBJECTIVE_KILL_CHAR_ON_FOOT)
+ ped->SetObjective(OBJECTIVE_KILL_CHAR_ON_FOOT, ped->m_pedInObjective);
+
+ } else {
+ CPed *driver = veh->pDriver;
+ if (!driver || driver == ped || driver->IsPlayer() && CTheScripts::IsPlayerOnAMission()) {
+ ped->SetFlee(veh->GetPosition(), 14000);
+ } else {
+ ped->ClearObjective();
+ ped->SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, veh);
+ }
+ ped->bUsePedNodeSeek = true;
+ ped->m_pNextPathNode = nil;
+ ped->Say(SOUND_PED_FLEE_RUN);
+ }
+ } else if (ped->m_pedStats->m_temper > ped->m_pedStats->m_fear
+ && ped->CharCreatedBy != MISSION_CHAR && veh->VehicleCreatedBy != MISSION_VEHICLE
+ && veh->pDriver && veh->pDriver->IsPlayer()
+ && !CTheScripts::IsPlayerOnAMission()) {
+ ped->SetObjective(OBJECTIVE_ENTER_CAR_AS_DRIVER, veh);
+
+ } 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);
+
+ } else {
+ ped->SetFindPathAndFlee(veh->GetPosition(), 10000);
+ if (CGeneral::GetRandomNumber() & 1 || ped->m_pedStats->m_fear > 70) {
+ ped->SetMoveState(PEDMOVE_SPRINT);
+ ped->Say(SOUND_PED_FLEE_SPRINT);
+ } else {
+ ped->Say(SOUND_PED_FLEE_RUN);
+ }
+ }
+ }
+ if (ped->m_nLastPedState == PED_IDLE)
+ ped->m_nLastPedState = PED_WANDER_PATH;
+}
+
+// --MIAMI: Done
+void
+CPed::PedSetDraggedOutCarPositionCB(CAnimBlendAssociation* animAssoc, void* arg)
+{
+ CPed *ped = (CPed*)arg;
+
+ ped->bUsesCollision = true;
+ ped->RestartNonPartialAnims();
+
+ 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)
+ draggedOutOffset.x = -draggedOutOffset.x;
+
+ CVector posAfterBeingDragged = Multiply3x3(pedMat, draggedOutOffset);
+ posAfterBeingDragged += ped->GetPosition();
+ CPedPlacement::FindZCoorForPed(&posAfterBeingDragged);
+ ped->m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f);
+ ped->SetPosition(posAfterBeingDragged);
+
+ if (ped->m_pMyVehicle && !ped->m_pMyVehicle->IsBike() && !ped->m_pMyVehicle->IsRoomForPedToLeaveCar(ped->m_vehEnterType, &vecPedDraggedOutCarAnimOffset)) {
+ ped->PositionPedOutOfCollision();
+ }
+
+ if (!ped->CanSetPedState())
+ return;
+
+ if (!ped->m_pMyVehicle) {
+ ped->SetIdle();
+ ped->SetGetUp();
+ return;
+ }
+
+ CPed *driver = ped->m_pMyVehicle->pDriver;
+
+ if (ped->IsPlayer()) {
+ ped->SetIdle();
+
+ } else if (ped->bFleeAfterExitingCar) {
+ ped->bFleeAfterExitingCar = false;
+ ped->SetFlee(ped->m_pMyVehicle->GetPosition(), 4000);
+
+ } else if (ped->bWanderPathAfterExitingCar) {
+ ped->SetWanderPath(CGeneral::GetRandomNumberInRange(0.0f, 8.0f));
+ ped->bWanderPathAfterExitingCar = false;
+
+ } else if (ped->bGonnaKillTheCarJacker) {
+ // Kill objective is already set at this point.
+
+ ped->bGonnaKillTheCarJacker = false;
+ if (!ped->m_pedInObjective || !(CGeneral::GetRandomNumber() & 1)) {
+ if (!driver || driver == ped || driver->IsPlayer() && CTheScripts::IsPlayerOnAMission()) {
+ ped->SetPedState(PED_NONE);
+ ped->m_nLastPedState = PED_NONE;
+ ped->SetFlee(ped->m_pMyVehicle->GetPosition(), 4000);
+ } else {
+ ped->ClearObjective();
+ 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 && driver
+ && driver->IsPlayer() && !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 && !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)
+{
+ GetNearestTrainPedPosition(train, doorPos);
+/*
+ // Not used.
+ CVehicleModelInfo* trainModel = (CVehicleModelInfo*)CModelInfo::GetModelInfo(train->m_modelIndex);
+ CMatrix trainMat = CMatrix(train->GetMatrix());
+
+ doorPos = trainModel->m_positions[m_vehEnterType];
+ doorPos.x -= 1.5f;
+ doorPos = Multiply3x3(trainMat, doorPos);
+ doorPos += train->GetPosition();
+*/
+ return 1;
+}
+
+// --MIAMI: Done
+uint8
+CPed::GetNearestTrainPedPosition(CVehicle *train, CVector &enterPos)
+{
+ CVector enterStepOffset;
+ CVehicleModelInfo *trainModel = (CVehicleModelInfo *)CModelInfo::GetModelInfo(train->GetModelIndex());
+ CMatrix trainMat = CMatrix(train->GetMatrix());
+ CVector leftEntryPos, rightEntryPos, midEntryPos;
+ float distLeftEntry, distRightEntry, distMidEntry;
+
+ // enterStepOffset = vecPedCarDoorAnimOffset;
+ enterStepOffset = CVector(1.5f, 0.0f, 0.0f);
+
+ if (train->pPassengers[TRAIN_POS_LEFT_ENTRY]) {
+ distLeftEntry = 999.0f;
+ } else {
+ leftEntryPos = trainModel->m_positions[TRAIN_POS_LEFT_ENTRY] - enterStepOffset;
+ leftEntryPos = Multiply3x3(trainMat, leftEntryPos);
+ leftEntryPos += train->GetPosition();
+ distLeftEntry = (leftEntryPos - GetPosition()).Magnitude();
+ }
+
+ if (train->pPassengers[TRAIN_POS_MID_ENTRY]) {
+ distMidEntry = 999.0f;
+ } else {
+ midEntryPos = trainModel->m_positions[TRAIN_POS_MID_ENTRY] - enterStepOffset;
+ midEntryPos = Multiply3x3(trainMat, midEntryPos);
+ midEntryPos += train->GetPosition();
+ distMidEntry = (midEntryPos - GetPosition()).Magnitude();
+ }
+
+ if (train->pPassengers[TRAIN_POS_RIGHT_ENTRY]) {
+ distRightEntry = 999.0f;
+ } else {
+ rightEntryPos = trainModel->m_positions[TRAIN_POS_RIGHT_ENTRY] - enterStepOffset;
+ rightEntryPos = Multiply3x3(trainMat, rightEntryPos);
+ rightEntryPos += train->GetPosition();
+ distRightEntry = (rightEntryPos - GetPosition()).Magnitude();
+ }
+
+ if (distMidEntry < distLeftEntry) {
+ if (distMidEntry < distRightEntry) {
+ enterPos = midEntryPos;
+ m_vehEnterType = TRAIN_POS_MID_ENTRY;
+ } else {
+ enterPos = rightEntryPos;
+ m_vehEnterType = TRAIN_POS_RIGHT_ENTRY;
+ }
+ } else if (distRightEntry < distLeftEntry) {
+ enterPos = rightEntryPos;
+ m_vehEnterType = TRAIN_POS_RIGHT_ENTRY;
+ } else {
+ enterPos = leftEntryPos;
+ m_vehEnterType = TRAIN_POS_LEFT_ENTRY;
+ }
+
+ return 1;
+}
+
+// --MIAMI: Done :D
+void
+CPed::PedSetInTrainCB(CAnimBlendAssociation* animAssoc, void* arg)
+{
+ CPed *ped = (CPed*)arg;
+ CTrain *veh = (CTrain*)ped->m_pMyVehicle;
+
+ if (!veh)
+ return;
+
+ ped->bInVehicle = true;
+ ped->SetPedState(PED_DRIVING);
+ ped->RestorePreviousObjective();
+ ped->SetMoveState(PEDMOVE_STILL);
+ veh->AddPassenger(ped);
+}
+
+#ifdef GTA_TRAIN
+void
+CPed::SetEnterTrain(CVehicle *train, uint32 unused)
+{
+ if (m_nPedState == PED_ENTER_TRAIN || !((CTrain*)train)->Doors[0].IsFullyOpen())
+ return;
+
+ /*
+ // Not used
+ CVector enterPos;
+ GetNearestTrainPedPosition(train, enterPos);
+ */
+ m_fRotationCur = train->GetForward().Heading() - HALFPI;
+ m_pMyVehicle = train;
+ m_pMyVehicle->RegisterReference((CEntity **) &m_pMyVehicle);
+
+ SetPedState(PED_ENTER_TRAIN);
+ m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_TRAIN_GETIN, 4.0f);
+ m_pVehicleAnim->SetFinishCallback(PedSetInTrainCB, this);
+ bUsesCollision = false;
+ LineUpPedWithTrain();
+ if (IsPlayer()) {
+ if (((CPlayerPed*)this)->m_bAdrenalineActive)
+ ((CPlayerPed*)this)->ClearAdrenaline();
+ }
+}
+
+void
+CPed::EnterTrain(void)
+{
+ LineUpPedWithTrain();
+}
+
+void
+CPed::SetPedPositionInTrain(void)
+{
+ LineUpPedWithTrain();
+}
+
+void
+CPed::LineUpPedWithTrain(void)
+{
+ CVector lineUpPos;
+ CVehicleModelInfo *trainModel = (CVehicleModelInfo *)CModelInfo::GetModelInfo(m_pMyVehicle->GetModelIndex());
+ CVector enterOffset(1.5f, 0.0f, -0.2f);
+
+ m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f);
+ m_fRotationCur = m_pMyVehicle->GetForward().Heading() - HALFPI;
+ m_fRotationDest = m_fRotationCur;
+
+ if (!bInVehicle) {
+ GetNearestTrainDoor(m_pMyVehicle, lineUpPos);
+ lineUpPos.z += 0.2f;
+ } else {
+ if (m_pMyVehicle->pPassengers[TRAIN_POS_LEFT_ENTRY] == this) {
+
+ lineUpPos = trainModel->m_positions[TRAIN_POS_LEFT_ENTRY] - enterOffset;
+
+ } else if (m_pMyVehicle->pPassengers[TRAIN_POS_MID_ENTRY] == this) {
+
+ lineUpPos = trainModel->m_positions[TRAIN_POS_MID_ENTRY] - enterOffset;
+
+ } else if (m_pMyVehicle->pPassengers[TRAIN_POS_RIGHT_ENTRY] == this) {
+
+ lineUpPos = trainModel->m_positions[TRAIN_POS_RIGHT_ENTRY] - enterOffset;
+ }
+ lineUpPos = Multiply3x3(m_pMyVehicle->GetMatrix(), lineUpPos);
+ lineUpPos += m_pMyVehicle->GetPosition();
+ }
+
+ if (m_pVehicleAnim) {
+ float percentageLeft = m_pVehicleAnim->GetTimeLeft() / m_pVehicleAnim->hierarchy->totalLength;
+ lineUpPos += (GetPosition() - lineUpPos) * percentageLeft;
+ }
+
+ SetPosition(lineUpPos);
+ SetHeading(m_fRotationCur);
+}
+
+void
+CPed::SetExitTrain(CVehicle* train)
+{
+ if (m_nPedState == PED_EXIT_TRAIN || train->GetStatus() != STATUS_TRAIN_NOT_MOVING || !((CTrain*)train)->Doors[0].IsFullyOpen())
+ return;
+
+ /*
+ // Not used
+ CVector exitPos;
+ GetNearestTrainPedPosition(train, exitPos);
+ */
+ SetPedState(PED_EXIT_TRAIN);
+ m_pVehicleAnim = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_TRAIN_GETOUT, 4.0f);
+ m_pVehicleAnim->SetFinishCallback(PedSetOutTrainCB, this);
+ bUsesCollision = false;
+ LineUpPedWithTrain();
+}
+
+void
+CPed::ExitTrain(void)
+{
+ LineUpPedWithTrain();
+}
+
+void
+CPed::PedSetOutTrainCB(CAnimBlendAssociation *animAssoc, void *arg)
+{
+ CPed *ped = (CPed*)arg;
+
+ CVehicle *veh = ped->m_pMyVehicle;
+
+ if (ped->m_pVehicleAnim)
+ ped->m_pVehicleAnim->blendDelta = -1000.0f;
+
+ ped->bUsesCollision = true;
+ ped->m_pVehicleAnim = nil;
+ ped->bInVehicle = false;
+ ped->SetPedState(PED_IDLE);
+ ped->RestorePreviousObjective();
+ ped->SetMoveState(PEDMOVE_STILL);
+
+ CMatrix pedMat(ped->GetMatrix());
+ ped->m_fRotationCur = HALFPI + veh->GetForward().Heading();
+ ped->m_fRotationDest = ped->m_fRotationCur;
+ CVector posAfterExit = Multiply3x3(pedMat, vecPedTrainDoorAnimOffset);
+ posAfterExit += ped->GetPosition();
+ CPedPlacement::FindZCoorForPed(&posAfterExit);
+ ped->m_vecMoveSpeed = CVector(0.0f, 0.0f, 0.0f);
+ ped->SetPosition(posAfterExit);
+ 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()) {
+ 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->CharCreatedBy == RANDOM_CHAR && nearPed != this && nearPed->m_nPedType == m_nPedType)
+ nearPed->m_fearFlags |= CPedType::GetFlag(attackerPed->m_nPedType);
+ }
+ }
+ }
+ }
+ }
+
+ if (attackerPed && attackerPed->IsPlayer() && (attackerPed->m_nPedState == PED_CARJACK || attackerPed->bInVehicle)) {
+ if (!attackerPed->m_pMyVehicle || attackerPed->m_pMyVehicle->GetModelIndex() != MI_TOPFUN) {
+ int16 lastVehicle;
+ CEntity *vehicles[8];
+ CWorld::FindObjectsInRange(GetPosition(), 30.0f, true, &lastVehicle, 6, vehicles, false, true, false, false, false);
+
+ if (lastVehicle > 8)
+ lastVehicle = 8;
+
+ for (int j = 0; j < lastVehicle; ++j) {
+ CVehicle *nearVeh = (CVehicle*) vehicles[j];
+
+ if (nearVeh->VehicleCreatedBy != MISSION_VEHICLE) {
+ CPed *nearVehDriver = nearVeh->pDriver;
+
+ 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;
+ nearVeh->AutoPilot.m_nCarMission = MISSION_RAMPLAYER_FARAWAY;
+ nearVeh->SetStatus(STATUS_PHYSICS);
+ nearVeh->AutoPilot.m_nTempAction = TEMPACT_NONE;
+ nearVeh->AutoPilot.m_nDrivingStyle = DRIVINGSTYLE_AVOID_CARS;
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+// --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)
+{
+ for (int i = 0; i < node->numLinks; i++) {
+
+ CPathNode *testNode = &ThePaths.m_pathNodes[ThePaths.ConnectedNode(i + node->firstLink)];
+
+ if (testNode && testNode != closeNode && testNode != closeNode2) {
+ CVector2D posDiff(ped->m_vecSeekPos - testNode->GetPosition());
+ float dist = posDiff.MagnitudeSqr();
+
+ if (farDist.MagnitudeSqr() > dist) {
+
+ if (closeDist.MagnitudeSqr() > dist) {
+ ped->m_pNextPathNode = (closeNode2 ? closeNode2 : testNode);
+ farDist = posDiff;
+ } else {
+ ped->m_pNextPathNode = closeNode;
+ closeDist = posDiff;
+ }
+ }
+
+ if (--runCount > 0)
+ SelectClosestNodeForSeek(ped, testNode, closeDist, farDist, closeNode, (closeNode2 ? closeNode2 : testNode), runCount);
+ }
+ }
+}
+
+// --MIAMI: Done
+bool
+CPed::FindBestCoordsFromNodes(CVector unused, CVector *bestCoords)
+{
+ if (m_pNextPathNode || !bUsePedNodeSeek)
+ return false;
+
+ const CVector &ourPos = GetPosition();
+
+ int closestNodeId = ThePaths.FindNodeClosestToCoors(GetPosition(), 1, 999999.9f);
+
+ CVector seekObjPos = m_vecSeekPos;
+ seekObjPos.z += 1.0f;
+
+ if (CWorld::GetIsLineOfSightClear(ourPos, seekObjPos, true, false, false, true, false, false, false))
+ return false;
+
+ m_pNextPathNode = nil;
+
+ CVector2D seekPosDist (m_vecSeekPos - ourPos);
+
+ CPathNode *closestNode = &ThePaths.m_pathNodes[closestNodeId];
+ CVector2D closeDist(m_vecSeekPos - closestNode->GetPosition());
+
+ SelectClosestNodeForSeek(this, closestNode, closeDist, seekPosDist, closestNode, nil);
+
+ if (m_pNextPathNode) {
+
+ // 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;
+ }
+
+ return false;
+}
+
+// --MIAMI: Done
+bool
+CPed::DuckAndCover(void)
+{
+ if (!m_pedInObjective || CTimer::GetTimeInMilliseconds() <= m_duckAndCoverTimer)
+ return false;
+
+ if (bKindaStayInSamePlace){
+
+ if (CTimer::GetTimeInMilliseconds() <= m_leaveCarTimer) {
+ if (!m_pLookTarget || m_pLookTarget != m_pedInObjective) {
+ m_pLookTarget = m_pedInObjective;
+ m_pLookTarget->RegisterReference((CEntity **) &m_pLookTarget);
+ }
+ if (!bIsAimingGun)
+ SetAimFlag(m_pedInObjective);
+
+ } else {
+ bKindaStayInSamePlace = false;
+ if (bIsDucking)
+ ClearDuck(true);
+
+ bCrouchWhenShooting = false;
+ bDuckAndCover = false;
+ m_headingRate = 10.0f;
+ m_duckAndCoverTimer = CTimer::GetTimeInMilliseconds() + CGeneral::GetRandomNumberInRange(20000,30000);
+ if (m_pSeekTarget && m_pSeekTarget->IsVehicle())
+ ((CVehicle*)m_pSeekTarget)->m_numPedsUseItAsCover--;
+ }
+ return false;
+ }
+
+ int16 lastVehicle = 0;
+ CEntity* vehicles[8];
+
+ bool justDucked = false;
+ CVehicle *foundVeh = nil;
+ float maxDist = 225.0f;
+ if (bIsDucking)
+ ClearDuck(true);
+
+ bCrouchWhenShooting = false;
+ bool duckingWithoutVeh = false;
+ if (CTimer::GetTimeInMilliseconds() > m_leaveCarTimer) {
+
+ 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->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;
+ foundVeh = veh;
+ }
+ }
+ }
+ if (foundVeh) {
+ // Unused.
+ // CVector lfWheelPos, rfWheelPos;
+ // foundVeh->GetComponentWorldPosition(CAR_WHEEL_RF, rfWheelPos);
+ // foundVeh->GetComponentWorldPosition(CAR_WHEEL_LF, lfWheelPos);
+ CVector rightSide, leftSide;
+
+ // 3 persons can use the car as cover. Found the correct position for us.
+ if (foundVeh->m_numPedsUseItAsCover == 2) {
+ rightSide = CVector(1.5f, -0.5f, 0.0f);
+ leftSide = CVector(-1.5f, -0.5f, 0.0f);
+ } else if (foundVeh->m_numPedsUseItAsCover == 1) {
+ rightSide = CVector(1.5f, 0.5f, 0.0f);
+ leftSide = CVector(-1.5f, 0.5f, 0.0f);
+ } else if (foundVeh->m_numPedsUseItAsCover == 0) {
+ rightSide = CVector(1.5f, 0.0f, 0.0f);
+ leftSide = CVector(-1.5f, 0.0f, 0.0f);
+ }
+
+ CMatrix vehMatrix(foundVeh->GetMatrix());
+ CVector duckAtRightSide = Multiply3x3(vehMatrix, rightSide) + foundVeh->GetPosition();
+
+ CVector duckAtLeftSide = Multiply3x3(vehMatrix, leftSide) + foundVeh->GetPosition();
+
+ CVector distWithPedRightSide = m_pedInObjective->GetPosition() - duckAtRightSide;
+ CVector distWithPedLeftSide = m_pedInObjective->GetPosition() - duckAtLeftSide;
+
+ CVector duckPos;
+ if (distWithPedRightSide.MagnitudeSqr() <= distWithPedLeftSide.MagnitudeSqr())
+ duckPos = duckAtLeftSide;
+ else
+ duckPos = duckAtRightSide;
+
+ 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) {
+ m_carInObjective = foundVeh;
+ 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 if (!duckingWithoutVeh) {
+ bDuckAndCover = false;
+ }
+ }
+
+ if (!justDucked && !bDuckAndCover)
+ return false;
+
+ if (!Seek()) {
+ if (m_nMoveState == PEDMOVE_STILL) {
+ bDuckAndCover = false;
+ return false;
+ } else
+ return true;
+ }
+
+ bKindaStayInSamePlace = true;
+ bDuckAndCover = false;
+ m_vecSeekPos = CVector(0.0f, 0.0f, 0.0f);
+ if (m_pSeekTarget && m_pSeekTarget->IsVehicle())
+ ((CVehicle*)m_pSeekTarget)->m_numPedsUseItAsCover++;
+
+ SetIdle();
+ SetMoveState(PEDMOVE_STILL);
+ SetMoveAnim();
+ if (!m_pLookTarget || m_pLookTarget != m_pedInObjective) {
+ m_pLookTarget = m_pedInObjective;
+ m_pLookTarget->RegisterReference((CEntity **) &m_pLookTarget);
+ }
+
+ 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)
+{
+ CVehicleModelInfo *vehModel;
+ CVector vehDoorPos;
+ CVector vehDoorOffset;
+ float seatOffset;
+
+ vehModel = (CVehicleModelInfo *)CModelInfo::GetModelInfo(veh->GetModelIndex());
+
+ 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 {
+ if (veh->bIsVan && (component == CAR_DOOR_LR || component == CAR_DOOR_RR)) {
+ seatOffset = 0.0f;
+ vehDoorOffset = vecPedVanRearDoorAnimOffset;
+ } else {
+ 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;
+
+ 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_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);
+ }
+ return vehDoorPos - vehDoorOffset;
+ }
+}
+
+// --MIAMI: Done, but what is this parameter for?
+void
+CPed::SetDuck(uint32 time, bool sth)
+{
+ if (bIsDucking || CTimer::GetTimeInMilliseconds() <= m_duckTimer && !sth) {
+ if (sth && CTimer::GetTimeInMilliseconds() + time > m_duckTimer)
+ m_duckTimer = CTimer::GetTimeInMilliseconds() + time;
+ return;
+ }
+
+ CAnimBlendAssociation *duckAssoc;
+ if (bCrouchWhenShooting) {
+ duckAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_WEAPON_CROUCH, 4.0f);
+ duckAssoc->flags &= ~ASSOC_FADEOUTWHENDONE;
+ bIsDucking = true;
+ m_duckTimer = CTimer::GetTimeInMilliseconds() + time;
+ } else {
+ CAnimBlendAssociation *duckAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DUCK_DOWN);
+ if (!duckAssoc || duckAssoc->blendDelta < 0.0f) {
+ CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_DUCK_DOWN, 4.0f);
+ bIsDucking = true;
+ m_duckTimer = CTimer::GetTimeInMilliseconds() + 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 *crouchAnim = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_CROUCH);
+ if (!crouchAnim) {
+ if(GetCrouchFireAnim(weapon))
+ crouchAnim = RpAnimBlendClumpGetAssociation(GetClump(), GetCrouchFireAnim(weapon));
+ }
+ if (!crouchAnim) {
+ if(GetCrouchReloadAnim(weapon))
+ crouchAnim = RpAnimBlendClumpGetAssociation(GetClump(), GetCrouchReloadAnim(weapon));
+ }
+ if (!crouchAnim) {
+ bIsDucking = false;
+#if defined FIX_BUGS || defined FREE_CAM
+ if (IsPlayer())
+ bCrouchWhenShooting = false;
+#endif
+ }
+ }
+}
+
+// --MIAMI: Done
+void
+CPed::ClearDuck(bool clearTimer)
+{
+ CAnimBlendAssociation *animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DUCK_DOWN);
+ if (!animAssoc) {
+ animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_DUCK_LOW);
+ }
+ if (!animAssoc) {
+ animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_CROUCH);
+ }
+
+ if (animAssoc) {
+ animAssoc->flags |= ASSOC_DELETEFADEDOUT;
+ animAssoc->blendDelta = -4.0f;
+ }
+ bIsDucking = false;
+
+ if (clearTimer) {
+ m_duckTimer = 0;
+ }
+}
+
+// --MIAMI: Done
+void
+CPed::InformMyGangOfAttack(CEntity *attacker)
+{
+ CPed *attackerPed;
+
+ if (m_objective == OBJECTIVE_KILL_CHAR_ON_FOOT || m_objective == OBJECTIVE_KILL_CHAR_ANY_MEANS)
+ return;
+
+ if (attacker->IsPed()) {
+ attackerPed = (CPed*)attacker;
+ } else {
+ if (!attacker->IsVehicle())
+ return;
+
+ attackerPed = ((CVehicle*)attacker)->pDriver;
+ if (!attackerPed)
+ return;
+ }
+
+ if (attackerPed->m_nPedType == PEDTYPE_COP)
+ return;
+
+ for (int i = 0; i < m_numNearPeds; i++) {
+ 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) {
+ nearPed->SetObjective(OBJECTIVE_KILL_CHAR_ON_FOOT, attackerPed);
+ nearPed->SetObjectiveTimer(30000);
+ }
+ }
+ }
+}
+
+// --MIAMI: Done
+void
+CPed::PedAnimDoorCloseRollingCB(CAnimBlendAssociation* animAssoc, void* arg)
+{
+ CPed* ped = (CPed*)arg;
+
+ CAutomobile* veh = (CAutomobile*)(ped->m_pMyVehicle);
+
+ if (animAssoc)
+ animAssoc->blendDelta = -1000.0f;
+
+ if (veh->bLowVehicle) {
+ veh->ProcessOpenDoor(CAR_DOOR_LF, ANIM_CAR_ROLLDOOR_LOW, 1.0f);
+ } else {
+ veh->ProcessOpenDoor(CAR_DOOR_LF, ANIM_CAR_ROLLDOOR, 1.0f);
+ }
+
+ veh->m_nGettingOutFlags &= ~CAR_DOOR_FLAG_LF;
+
+ if (veh->Damage.GetDoorStatus(DOOR_FRONT_LEFT) == DOOR_STATUS_SWINGING)
+ 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 || !IsPedInControl())
+ return;
+
+ SetStoredState();
+ m_carInObjective = boat;
+ m_carInObjective->RegisterReference((CEntity **) &m_carInObjective);
+ m_pMyVehicle = boat;
+ m_pMyVehicle->RegisterReference((CEntity **) &m_pMyVehicle);
+ m_distanceToCountSeekDone = 0.5f;
+ SetPedState(PED_SEEK_IN_BOAT);
+}
+
+// --MIAMI: Done
+void
+CPed::SeekBoatPosition(void)
+{
+ if (m_carInObjective && !m_carInObjective->pDriver) {
+ CVehicleModelInfo *boatModel = m_carInObjective->GetModelInfo();
+
+ CVector enterOffset;
+ enterOffset = boatModel->GetFrontSeatPosn();
+ enterOffset.x = 0.0f;
+ CMatrix boatMat(m_carInObjective->GetMatrix());
+ SetMoveState(PEDMOVE_WALK);
+ m_vecSeekPos = boatMat * enterOffset;
+ if (Seek()) {
+ // We arrived to the boat
+ m_vehEnterType = 0;
+ SetEnterCar(m_carInObjective, 0);
+ }
+ } else
+ RestorePreviousState();
+}
+
+// --MIAMI: Done
+bool
+CPed::IsRoomToBeCarJacked(void)
+{
+ if (!m_pMyVehicle)
+ return false;
+
+ CVector offset;
+ if (m_pMyVehicle->IsBike()) {
+ offset = vecPedStdBikeJumpRhsAnimOffset;
+ } else if (m_pMyVehicle->bLowVehicle || m_nPedType == PEDTYPE_COP) {
+ offset = vecPedDraggedOutCarAnimOffset;
+ } else {
+ offset = vecPedQuickDraggedOutCarAnimOffset;
+ }
+
+ offset.z = 0.0f;
+ if (m_pMyVehicle->IsRoomForPedToLeaveCar(CAR_DOOR_LF, &offset)) {
+ return true;
+ }
+
+ return false;
+}
+
+// --MIAMI: Done
+void
+CPed::AddInCarAnims(CVehicle* car, bool isDriver)
+{
+ 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;
+
+ 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;
+ 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;
+ bool putNearVeh = false;
+ bool putSomewhereClose = false;
+ int smallestDistNearVeh = 999;
+ int smallestDistSomewhereClose = 999;
+
+ CVector vehPos = m_pMyVehicle->GetPosition();
+ CVector potentialPos;
+ potentialPos.y = GetPosition().y - 3.5f;
+ potentialPos.z = GetPosition().z;
+
+ for (int yTry = 0; yTry < 15; yTry++) {
+ potentialPos.x = GetPosition().x - 3.5f;
+
+ for (int xTry = 0; xTry < 15; xTry++) {
+ CPedPlacement::FindZCoorForPed(&potentialPos);
+ 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) {
+ if (potentialChangeSqr < smallestDistNearVeh) {
+ posNearVeh = potentialPos;
+ putNearVeh = true;
+ smallestDistNearVeh = potentialChangeSqr;
+ }
+ } else if (potentialChangeSqr < smallestDistSomewhereClose) {
+ smallestDistSomewhereClose = potentialChangeSqr;
+ posSomewhereClose = potentialPos;
+ putSomewhereClose = true;
+ }
+ }
+ potentialPos.x += 0.5f;
+ }
+ potentialPos.y += 0.5f;
+ }
+
+ if (!putSomewhereClose && !putNearVeh)
+ return false;
+
+ // We refrain from using posNearVeh, probably because of it may be top of the vehicle.
+ if (putSomewhereClose) {
+ SetPosition(posSomewhereClose);
+ } else {
+ CVector vehSize = veh->GetModelInfo()->GetColModel()->boundingBox.max;
+ posNearVeh.z += vehSize.z;
+ SetPosition(posNearVeh);
+ }
+ return true;
+}
+
+// --MIAMI: Done
+bool
+CPed::WarpPedToNearLeaderOffScreen(void)
+{
+ bool teleported = false;
+ if (GetIsOnScreen() || m_leaveCarTimer > CTimer::GetTimeInMilliseconds())
+ return false;
+
+ CVector warpToPos = m_leader->GetPosition();
+ CVector distVec = warpToPos - GetPosition();
+ float halfOfDist = distVec.Magnitude() * 0.5f;
+ CVector halfNormalizedDist = distVec / halfOfDist;
+
+ CVector appropriatePos = GetPosition();
+ 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) {
+ 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)
+{
+ bool teleported = false;
+ if (GetIsOnScreen() || m_leaveCarTimer > CTimer::GetTimeInMilliseconds())
+ return false;
+
+ CVector warpToPos = warpTo->GetPosition();
+ CVector distVec = warpToPos - GetPosition();
+ float halfOfDist = distVec.Magnitude() * 0.5f;
+ CVector halfNormalizedDist = distVec / halfOfDist;
+
+ CVector appropriatePos = GetPosition();
+ 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) {
+ 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;
+}
+
+// --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
index 05e72ed3..eeb65398 100644
--- a/src/peds/PedAttractor.cpp
+++ b/src/peds/PedAttractor.cpp
@@ -4,6 +4,7 @@
#include "General.h"
#include "Vehicle.h"
#include "World.h"
+#include "MemoryHeap.h"
const int gcMaxSizeOfAtmQueue = 1;
const int gcMaxSizeOfSeatQueue = 1;
@@ -18,8 +19,18 @@ std::vector<CVector> CPedShelterAttractor::ms_displacements;
CPedAttractorManager* GetPedAttractorManager()
{
- static CPedAttractorManager manager;
- return &manager;
+// mobile just has a static here:
+/*
+ static CPedAttractorManager pedAttrMgr;
+ return &pedAttrMgr;
+*/
+ static CPedAttractorManager *pedAttrMgr;
+ if(pedAttrMgr == nil){
+ PUSH_MEMID(MEMID_PED_ATTR);
+ pedAttrMgr = new CPedAttractorManager;
+ POP_MEMID();
+ }
+ return pedAttrMgr;
}
CVehicleToEffect::CVehicleToEffect(CVehicle* pVehicle) : m_pVehicle(pVehicle)
@@ -100,8 +111,10 @@ const C2dEffect* CPedAttractorManager::GetEffectForIceCreamVan(CVehicle* pVehicl
return assoc->ChooseEffect(pos);
}
}
+ PUSH_MEMID(MEMID_PED_ATTR);
CVehicleToEffect effect(pVehicle);
vVehicleToEffect.push_back(effect);
+ POP_MEMID();
return effect.ChooseEffect(pos);
}
@@ -645,6 +658,7 @@ CPedAttractor* CPedAttractorManager::RegisterPed(CPed* pPed, C2dEffect* pEffect,
pRegisteredAttractor->RegisterPed(pPed);
return pRegisteredAttractor;
}
+ PUSH_MEMID(MEMID_PED_ATTR);
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;
@@ -653,6 +667,7 @@ CPedAttractor* CPedAttractorManager::RegisterPed(CPed* pPed, C2dEffect* pEffect,
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;
}
+ POP_MEMID();
if (pRegisteredAttractor)
pRegisteredAttractor->RegisterPed(pPed);
return pRegisteredAttractor;
diff --git a/src/peds/PedChat.cpp b/src/peds/PedChat.cpp
index 71739902..470b7eeb 100644
--- a/src/peds/PedChat.cpp
+++ b/src/peds/PedChat.cpp
@@ -152,13 +152,4 @@ CPed::Say(uint16 audio)
m_queuedSound = audio;
}
}
-}
-
-void
-CPed::Say(uint16 audio, int32 time)
-{
- if (m_delayedSoundID == -1) {
- m_delayedSoundID = audio;
- m_delayedSoundTimer = CTimer::GetTimeInMilliseconds() + time;
- }
} \ No newline at end of file
diff --git a/src/peds/PedFight.cpp b/src/peds/PedFight.cpp
new file mode 100644
index 00000000..79c6f367
--- /dev/null
+++ b/src/peds/PedFight.cpp
@@ -0,0 +1,4217 @@
+#include "common.h"
+
+#include "main.h"
+#include "RpAnimBlend.h"
+#include "AnimBlendClumpData.h"
+#include "AnimBlendAssociation.h"
+#include "Camera.h"
+#include "CarCtrl.h"
+#include "Darkel.h"
+#include "DMAudio.h"
+#include "FileMgr.h"
+#include "General.h"
+#include "Object.h"
+#include "Pad.h"
+#include "Particle.h"
+#include "Ped.h"
+#include "PlayerPed.h"
+#include "Stats.h"
+#include "TempColModels.h"
+#include "VisibilityPlugins.h"
+#include "Vehicle.h"
+#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;
+
+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
+CheckForPedsOnGroundToAttack(CPed *attacker, CPed **pedOnGround)
+{
+ PedOnGroundState stateToReturn;
+ float angleToFace;
+ CPed *currentPed = nil;
+ PedState currentPedState;
+ CPed *pedOnTheFloor = nil;
+ CPed *deadPed = nil;
+ CPed *pedBelow = nil;
+ bool foundDead = false;
+ bool foundOnTheFloor = false;
+ bool foundBelow = false;
+ float angleDiff;
+ float distance;
+
+ if (!CGame::nastyGame)
+ return NO_PED;
+
+ for (int currentPedId = 0; currentPedId < attacker->m_numNearPeds; currentPedId++) {
+
+ currentPed = attacker->m_nearPeds[currentPedId];
+
+ CVector posDifference = currentPed->GetPosition() - attacker->GetPosition();
+ distance = posDifference.Magnitude();
+
+ if (distance < 2.0f) {
+ angleToFace = CGeneral::GetRadianAngleBetweenPoints(
+ currentPed->GetPosition().x, currentPed->GetPosition().y,
+ attacker->GetPosition().x, attacker->GetPosition().y);
+
+ angleToFace = CGeneral::LimitRadianAngle(angleToFace);
+ attacker->m_fRotationCur = CGeneral::LimitRadianAngle(attacker->m_fRotationCur);
+
+ angleDiff = Abs(angleToFace - attacker->m_fRotationCur);
+
+ if (angleDiff > PI)
+ angleDiff = 2 * PI - angleDiff;
+
+ currentPedState = currentPed->m_nPedState;
+
+ if (currentPed->OnGroundOrGettingUp()) {
+ if (distance < 2.0f && angleDiff < DEGTORAD(65.0f)) {
+ if (currentPedState == PED_DEAD) {
+ foundDead = 1;
+ if (!deadPed)
+ deadPed = currentPed;
+ } else if (!currentPed->IsPedHeadAbovePos(-0.6f)) {
+ foundOnTheFloor = 1;
+ if (!pedOnTheFloor)
+ pedOnTheFloor = currentPed;
+ }
+ }
+ } else if ((distance < 0.8f && angleDiff < DEGTORAD(75.0f))
+ || (distance < 1.3f && angleDiff < DEGTORAD(55.0f))
+ || (distance < 1.7f && angleDiff < DEGTORAD(35.0f))
+ || (distance < 2.0f && angleDiff < DEGTORAD(30.0f))) {
+
+ // Either this condition or below one was probably returning 4 early in development. See Fight().
+ foundBelow = 1;
+ pedBelow = currentPed;
+ break;
+ } else {
+ if (angleDiff < DEGTORAD(75.0f)) {
+ foundBelow = 1;
+ if (!pedBelow)
+ pedBelow = currentPed;
+ }
+ }
+ }
+ }
+
+ if (foundOnTheFloor) {
+ currentPed = pedOnTheFloor;
+ stateToReturn = PED_ON_THE_FLOOR;
+ } else if (foundDead) {
+ currentPed = deadPed;
+ stateToReturn = PED_DEAD_ON_THE_FLOOR;
+ } else if (foundBelow) {
+ currentPed = pedBelow;
+ stateToReturn = PED_IN_FRONT_OF_ATTACKER;
+ } else {
+ currentPed = nil;
+ stateToReturn = NO_PED;
+ }
+
+ if (pedOnGround)
+ *pedOnGround = currentPed;
+
+ return stateToReturn;
+}
+
+// --MIAMI: Done
+void
+CPed::SetPointGunAt(CEntity *to)
+{
+ if (to) {
+ SetLookFlag(to, true, true);
+ SetAimFlag(to);
+ SetLookTimer(INT32_MAX);
+ }
+
+ 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)
+ SetStoredState();
+
+ SetPedState(PED_AIM_GUN);
+ bIsPointingGunAt = true;
+ SetMoveState(PEDMOVE_STILL);
+
+ CAnimBlendAssociation *aimAssoc;
+
+ 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 && 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 && !IsPlayer())
+ Say(SOUND_PED_ATTACK);
+}
+
+// --MIAMI: Done
+void
+CPed::PointGunAt(void)
+{
+ CWeaponInfo *weaponInfo = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType);
+ float animLoopStart = weaponInfo->m_fAnimLoopStart;
+ CAnimBlendAssociation *weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_FIRE);
+ if (!weaponAssoc || weaponAssoc->blendDelta < 0.0f) {
+ if (weaponInfo->IsFlagSet(WEAPONFLAG_CROUCHFIRE)) {
+ weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetCrouchFireAnim(weaponInfo));
+ animLoopStart = weaponInfo->m_fAnim2LoopStart;
+ }
+ }
+
+ if (weaponAssoc && weaponAssoc->currentTime > animLoopStart * 0.4f) {
+ weaponAssoc->SetCurrentTime(animLoopStart);
+ weaponAssoc->flags &= ~ASSOC_RUNNING;
+
+ if (bIsDucking)
+ m_pedIK.m_flags &= ~CPedIK::AIMS_WITH_ARM;
+
+ if (weaponInfo->IsFlagSet(WEAPONFLAG_CANAIM_WITHARM))
+ m_pedIK.m_flags |= CPedIK::AIMS_WITH_ARM;
+ else
+ m_pedIK.m_flags &= ~CPedIK::AIMS_WITH_ARM;
+ }
+}
+
+// --MIAMI: Done
+void
+CPed::ClearPointGunAt(void)
+{
+ CAnimBlendAssociation *animAssoc;
+ CWeaponInfo *weaponInfo;
+
+ ClearLookFlag();
+ ClearAimFlag();
+ bIsPointingGunAt = false;
+ if (m_nPedState == PED_AIM_GUN || m_nPedState == PED_ATTACK) {
+ SetPedState(PED_IDLE);
+ RestorePreviousState();
+ }
+ weaponInfo = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType);
+ animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_FIRE);
+ if (!animAssoc || animAssoc->blendDelta < 0.0f) {
+ if (weaponInfo->IsFlagSet(WEAPONFLAG_CROUCHFIRE)) {
+ animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetCrouchFireAnim(weaponInfo));
+ }
+ }
+ if (animAssoc) {
+ animAssoc->flags |= ASSOC_DELETEFADEDOUT;
+ animAssoc->blendDelta = -4.0f;
+ }
+}
+
+// --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;
+
+ if (m_attackTimer > CTimer::GetTimeInMilliseconds() || m_nWaitState == WAITSTATE_SURPRISE || (bIsDucking && !bCrouchWhenShooting))
+ return;
+
+ if (curWeapon->IsFlagSet(WEAPONFLAG_RELOAD) &&
+ (RpAnimBlendClumpGetAssociation(GetClump(), GetReloadAnim(curWeapon)) || RpAnimBlendClumpGetAssociation(GetClump(), GetCrouchReloadAnim(curWeapon)))) {
+ if (!IsPlayer() || m_nPedState != PED_ATTACK || ((CPlayerPed*)this)->m_bHaveTargetSelected)
+ bIsAttacking = false;
+ else
+ bIsAttacking = true;
+
+ return;
+ }
+
+ if (GetWeapon()->m_eWeaponType == WEAPONTYPE_UNARMED || curWeapon->IsFlagSet(WEAPONFLAG_FIGHTMODE) || GetWeapon()->m_eWeaponType == WEAPONTYPE_BRASSKNUCKLE) {
+ if (IsPlayer() ||
+ (m_nPedState != PED_FIGHT && m_nMoveState != PEDMOVE_NONE && m_nMoveState != PEDMOVE_STILL
+ && !(m_pedStats->m_flags & STAT_SHOPPING_BAGS) && curWeapon->IsFlagSet(WEAPONFLAG_PARTIALATTACK))) {
+
+ 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);
+ }
+ } else {
+ StartFightAttack(CGeneral::GetRandomNumber());
+ }
+ return;
+ }
+
+ if (curWeapon->IsFlagSet(WEAPONFLAG_PARTIALATTACK) &&
+ (IsPlayer() && ((CPlayerPed*)this)->m_fMoveSpeed >= 1.0f ||
+ m_nMoveState == PEDMOVE_WALK || m_nMoveState == PEDMOVE_RUN)) {
+
+ if (m_nPedState != PED_ATTACK) {
+ SetPedState(PED_ATTACK);
+ bIsAttacking = false;
+ CAnimBlendAssociation* animAssoc = CAnimManager::BlendAnimation(GetClump(), curWeapon->m_AnimToPlay, ANIM_MELEE_ATTACK_START, 8.0f);
+ animAssoc->SetRun();
+ if (animAssoc->currentTime == animAssoc->hierarchy->totalLength)
+ animAssoc->SetCurrentTime(0.0f);
+
+ animAssoc->SetFinishCallback(FinishedAttackCB, this);
+ }
+ return;
+ }
+
+ if (m_pSeekTarget)
+ m_pSeekTarget->CleanUpOldReference(&m_pSeekTarget);
+ m_pSeekTarget = victim;
+ if (m_pSeekTarget)
+ m_pSeekTarget->RegisterReference((CEntity **) &m_pSeekTarget);
+
+ if (curWeapon->IsFlagSet(WEAPONFLAG_CANAIM)) {
+ CVector aimPos = GetRight() * 0.1f + GetForward() * 0.2f + GetPosition();
+ aimPos += GetUp() * 0.35f;
+ CEntity *obstacle = CWorld::TestSphereAgainstWorld(aimPos, 0.2f, nil, true, false, false, true, false, false);
+ if (obstacle) {
+ 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 if (this == FindPlayerPed() && TheCamera.Cams[0].Using3rdPersonMouseCam()) {
+ SetAimFlag(m_fRotationCur);
+ ((CPlayerPed*)this)->m_fFPSMoveHeading = TheCamera.Find3rdPersonQuickAimPitch();
+ } else if (curWeapon->IsFlagSet(WEAPONFLAG_CANAIM_WITHARM)) {
+ SetAimFlag(m_fRotationCur);
+ }
+ }
+ if (m_nPedState == PED_ATTACK) {
+ bIsAttacking = true;
+ return;
+ }
+
+ if (IsPlayer() || (!victimPed || victimPed->IsPedInControl())) {
+ if (IsPlayer())
+ CPad::GetPad(0)->ResetAverageWeapon();
+
+ uint8 pointBlankStatus;
+ if ((curWeapon->m_eWeaponFire == WEAPON_FIRE_INSTANT_HIT || GetWeapon()->m_eWeaponType == WEAPONTYPE_FLAMETHROWER)
+ && 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
+ && (pointBlankStatus = CheckForPointBlankPeds(victimPed)) != NO_POINT_BLANK_PED) {
+ ClearAimFlag();
+
+ // This condition is pointless
+ if (pointBlankStatus == POINT_BLANK_FOR_WANTED_PED || !victimPed && (IsPlayer() || !m_carInObjective))
+ StartFightAttack(200);
+ } else {
+ if (!curWeapon->IsFlagSet(WEAPONFLAG_CANAIM))
+ m_pSeekTarget = nil;
+
+ if (m_nPedState != PED_AIM_GUN)
+ SetStoredState();
+
+ SetPedState(PED_ATTACK);
+ SetMoveState(PEDMOVE_NONE);
+ if (bCrouchWhenShooting && bIsDucking && curWeapon->IsFlagSet(WEAPONFLAG_CROUCHFIRE)) {
+ CAnimBlendAssociation* curMoveAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetCrouchFireAnim(curWeapon));
+ if (curMoveAssoc) {
+ if (strcmp(CAnimManager::GetAnimAssociation(curWeapon->m_AnimToPlay, GetCrouchFireAnim(curWeapon))->hierarchy->name, curMoveAssoc->hierarchy->name) != 0) {
+ delete curMoveAssoc;
+ }
+ }
+ animAssoc = CAnimManager::BlendAnimation(GetClump(), curWeapon->m_AnimToPlay, GetCrouchFireAnim(curWeapon), 8.0f);
+ } else {
+ float animDelta = 8.0f;
+ if (curWeapon->m_eWeaponFire == WEAPON_FIRE_MELEE)
+ animDelta = 1000.0f;
+
+ AnimationId fireAnim;
+ if (curWeapon->IsFlagSet(WEAPONFLAG_THROW))
+ fireAnim = ANIM_THROWABLE_START_THROW;
+ else if (CGame::nastyGame && (curWeapon->IsFlagSet(WEAPONFLAG_GROUND_2ND) || curWeapon->IsFlagSet(WEAPONFLAG_GROUND_3RD))) {
+ PedOnGroundState pedOnGround = CheckForPedsOnGroundToAttack(this, nil);
+ if (pedOnGround > PED_IN_FRONT_OF_ATTACKER || pedOnGround == NO_PED && bIsStanding && m_pCurSurface && m_pCurSurface->IsVehicle()) {
+ fireAnim = GetFireAnimGround(curWeapon, false);
+ } else {
+ fireAnim = GetFireAnimNotDucking(curWeapon);
+ }
+ } else {
+ 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();
+ if (animAssoc->currentTime == animAssoc->hierarchy->totalLength)
+ animAssoc->SetCurrentTime(0.0f);
+
+ animAssoc->SetFinishCallback(FinishedAttackCB, this);
+ }
+ return;
+ }
+
+ if (GetWeapon()->m_eWeaponType == WEAPONTYPE_BASEBALLBAT && victimPed->m_nPedState == PED_GETUP)
+ SetWaitState(WAITSTATE_SURPRISE, nil);
+
+ SetLookFlag(victim, true, true);
+ SetLookTimer(100);
+}
+
+// --MIAMI: Done
+void
+CPed::ClearAttack(void)
+{
+ if (m_nPedState != PED_ATTACK || (bIsDucking && !IsPlayer()) || m_nWaitState == WAITSTATE_PLAYANIM_DUCK)
+ return;
+
+ if (FindPlayerPed() == this && TheCamera.Using1stPersonWeaponMode()) {
+ SetPointGunAt(nil);
+ } else if (bIsPointingGunAt) {
+ if (m_pLookTarget)
+ SetPointGunAt(m_pLookTarget);
+ else
+ ClearPointGunAt();
+ } else if (m_objective != OBJECTIVE_NONE) {
+ SetIdle();
+ } else {
+ RestorePreviousState();
+ }
+}
+
+// --MIAMI: Done
+void
+CPed::ClearAttackByRemovingAnim(void)
+{
+ if (m_nPedState != PED_ATTACK)
+ return;
+
+ CWeaponInfo *weapon = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType);
+ CAnimBlendAssociation *weaponAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetPrimaryFireAnim(weapon));
+
+ 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();
+ }
+}
+
+// --MIAMI: Done
+void
+CPed::FinishedAttackCB(CAnimBlendAssociation *attackAssoc, void *arg)
+{
+ CAnimBlendAssociation *newAnim, *reloadAnimAssoc = nil;
+ CPed *ped = (CPed*)arg;
+ CWeaponInfo *currentWeapon = CWeaponInfo::GetWeaponInfo(ped->GetWeapon()->m_eWeaponType);
+
+ 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);
+
+ } 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;
+ }
+ }
+
+ if (!ped->bIsAttacking)
+ ped->ClearAttack();
+
+ } 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);
+ }
+ }
+ }
+
+ 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->DyingOrDead())
+ return;
+
+ if (ped->bIsDucking && ped->bCrouchWhenShooting) {
+ CAnimBlendAssociation *crouchFireAssoc = nil;
+ if (weapon->IsFlagSet(WEAPONFLAG_CROUCHFIRE)) {
+ crouchFireAssoc = RpAnimBlendClumpGetAssociation(ped->GetClump(), GetCrouchFireAnim(weapon));
+ }
+ if (weapon->IsFlagSet(WEAPONFLAG_RELOAD) && reloadAssoc) {
+ if (reloadAssoc->animId == GetCrouchReloadAnim(weapon) && !crouchFireAssoc) {
+ CAnimBlendAssociation *crouchAssoc = CAnimManager::BlendAnimation(ped->GetClump(), ASSOCGRP_STD, ANIM_WEAPON_CROUCH, 8.0f);
+ crouchAssoc->SetCurrentTime(crouchAssoc->hierarchy->totalLength);
+ crouchAssoc->flags &= ~ASSOC_RUNNING;
+ }
+ }
+ } else if (weapon->IsFlagSet(WEAPONFLAG_RELOAD_LOOP2START) && ped->bIsAttacking) {
+ CAnimBlendAssociation *fireAssoc =
+ CAnimManager::BlendAnimation(ped->GetClump(), weapon->m_AnimToPlay, GetPrimaryFireAnim(weapon), 8.0f);
+ fireAssoc->SetFinishCallback(FinishedAttackCB, ped);
+ fireAssoc->SetRun();
+ if (fireAssoc->currentTime == reloadAssoc->hierarchy->totalLength)
+ fireAssoc->SetCurrentTime(Max(weapon->m_fAnimLoopStart - 0.04f, 0.0f));
+ else if (fireAssoc->currentTime < weapon->m_fAnimLoopStart)
+ fireAssoc->SetCurrentTime(Max(weapon->m_fAnimLoopStart - 0.04f, 0.0f));
+ }
+}
+
+// --MIAMI: Done
+uint8
+CPed::CheckForPointBlankPeds(CPed *pedToVerify)
+{
+ float pbDistance = 1.1f;
+ if (GetWeapon()->IsType2Handed())
+ pbDistance = 1.6f;
+
+ for (int i = 0; i < m_numNearPeds; i++) {
+ CPed *nearPed = m_nearPeds[i];
+
+ if (!pedToVerify || pedToVerify == nearPed) {
+
+ CVector diff = nearPed->GetPosition() - GetPosition();
+ if (diff.MagnitudeSqr() < SQR(pbDistance)) {
+
+ float neededAngle = CGeneral::GetRadianAngleBetweenPoints(
+ nearPed->GetPosition().x, nearPed->GetPosition().y,
+ GetPosition().x, GetPosition().y);
+ neededAngle = CGeneral::LimitRadianAngle(neededAngle);
+ m_fRotationCur = CGeneral::LimitRadianAngle(m_fRotationCur);
+
+ float neededTurn = Abs(neededAngle - m_fRotationCur);
+
+ if (neededTurn > PI)
+ neededTurn = 2*PI - neededTurn;
+
+ 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) {
+ if (pedToVerify == nearPed)
+ return POINT_BLANK_FOR_WANTED_PED;
+ else
+ return POINT_BLANK_FOR_SOMEONE_ELSE;
+ }
+ }
+ }
+ }
+ return NO_POINT_BLANK_PED;
+}
+
+// --MIAMI: Done except commented things
+void
+CPed::Attack(void)
+{
+ CAnimBlendAssociation *weaponAnimAssoc;
+ int32 weaponAnim;
+ eWeaponType ourWeaponType;
+ float weaponAnimTime;
+ eWeaponFire ourWeaponFire;
+ float animLoopEnd;
+ CWeaponInfo *ourWeapon;
+ bool attackShouldContinue;
+ CAnimBlendAssociation *reloadAnimAssoc;
+ CAnimBlendAssociation *throwAssoc;
+ float delayBetweenAnimAndFire;
+ float animLoopStart;
+ CVector firePos;
+
+ ourWeaponType = GetWeapon()->m_eWeaponType;
+ ourWeapon = CWeaponInfo::GetWeaponInfo(ourWeaponType);
+ ourWeaponFire = ourWeapon->m_eWeaponFire;
+ weaponAnimAssoc = nil;
+ attackShouldContinue = !!bIsAttacking;
+ reloadAnimAssoc = nil;
+ throwAssoc = nil;
+ animLoopStart = ourWeapon->m_fAnimLoopStart;
+ animLoopEnd = ourWeapon->m_fAnimLoopEnd;
+ delayBetweenAnimAndFire = ourWeapon->m_fAnimFrameFire;
+ weaponAnim = ourWeapon->m_AnimToPlay;
+
+ if (bIsDucking) {
+ if(GetCrouchFireAnim(ourWeapon) && bCrouchWhenShooting) {
+ weaponAnimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetCrouchFireAnim(ourWeapon));
+ if (weaponAnimAssoc) {
+ animLoopStart = ourWeapon->m_fAnim2LoopStart;
+ animLoopEnd = ourWeapon->m_fAnim2LoopEnd;
+ delayBetweenAnimAndFire = ourWeapon->m_fAnim2FrameFire;
+ }
+ }
+ } else {
+ 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 (GetReloadAnim(ourWeapon)) {
+ reloadAnimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetReloadAnim(ourWeapon));
+ }
+
+ if (GetCrouchReloadAnim(ourWeapon) && !reloadAnimAssoc) {
+ reloadAnimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetCrouchReloadAnim(ourWeapon));
+ }
+
+ if ( reloadAnimAssoc && reloadAnimAssoc->IsRunning() ) {
+ if (!IsPlayer() || ((CPlayerPed*)this)->m_bHaveTargetSelected)
+ ClearAttack();
+ return;
+ }
+
+ if ( reloadAnimAssoc ) {
+ reloadAnimAssoc->flags |= ASSOC_DELETEFADEDOUT;
+ if ( reloadAnimAssoc->blendDelta >= 0.0f )
+ reloadAnimAssoc->blendDelta = -8.0f;
+ }
+
+ if (GetThrowAnim(ourWeapon)) {
+ throwAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetThrowAnim(ourWeapon));
+ }
+
+ if ( CTimer::GetTimeInMilliseconds() < m_shootTimer )
+ attackShouldContinue = true;
+
+ bool meleeAttackStarted = false;
+ if ( !weaponAnimAssoc ) {
+ if (GetMeleeStartAnim(ourWeapon)) {
+ weaponAnimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetMeleeStartAnim(ourWeapon));
+ if ( weaponAnimAssoc ) {
+ if ( IsPlayer() )
+ meleeAttackStarted = true;
+
+ switch ( ourWeapon->m_AnimToPlay ) {
+ case ASSOCGRP_UNARMED:
+ case ASSOCGRP_SCREWDRIVER:
+ case ASSOCGRP_KNIFE:
+ case ASSOCGRP_BASEBALLBAT:
+ case ASSOCGRP_GOLFCLUB:
+ case ASSOCGRP_CHAINSAW:
+ delayBetweenAnimAndFire = 0.2f;
+ animLoopStart = 0.1f;
+ break;
+ default:
+ break;
+ }
+ animLoopEnd = 99.9f;
+ }
+ }
+ }
+ if (!weaponAnimAssoc) {
+ if (GetSecondFireAnim(ourWeapon)) {
+ weaponAnimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetSecondFireAnim(ourWeapon));
+ if (weaponAnimAssoc) {
+ animLoopStart = ourWeapon->m_fAnim2LoopStart;
+ animLoopEnd = ourWeapon->m_fAnim2LoopEnd;
+ delayBetweenAnimAndFire = ourWeapon->m_fAnim2FrameFire;
+ }
+ }
+ }
+ if (!weaponAnimAssoc) {
+ weaponAnimAssoc = RpAnimBlendClumpGetAssociation(GetClump(), GetFireAnimGround(ourWeapon));
+ if (weaponAnimAssoc) {
+ animLoopStart = ourWeapon->m_fAnim2LoopStart;
+ animLoopEnd = ourWeapon->m_fAnim2LoopEnd;
+ delayBetweenAnimAndFire = ourWeapon->m_fAnim2FrameFire;
+ }
+ }
+
+ if (!weaponAnimAssoc) {
+ if (!throwAssoc) {
+ if (attackShouldContinue) {
+ if (ourWeaponFire != WEAPON_FIRE_PROJECTILE || !IsPlayer() || ((CPlayerPed*)this)->m_bHaveTargetSelected) {
+ if (bCrouchWhenShooting && bIsDucking && GetCrouchFireAnim(ourWeapon)) {
+ weaponAnimAssoc = CAnimManager::BlendAnimation(GetClump(), ourWeapon->m_AnimToPlay, GetCrouchFireAnim(ourWeapon), 8.0f);
+
+ } else if(GetSecondFireAnim(ourWeapon) && CGeneral::GetRandomNumber() & 1){
+ weaponAnimAssoc = CAnimManager::BlendAnimation(GetClump(), ourWeapon->m_AnimToPlay, GetSecondFireAnim(ourWeapon), 8.0f);
+
+ } else if(!CGame::nastyGame || ourWeaponFire != WEAPON_FIRE_MELEE ||
+ GetFireAnimGround(ourWeapon) ||
+ 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);
+ weaponAnimAssoc->SetRun();
+
+ if (weaponAnimAssoc->currentTime == weaponAnimAssoc->hierarchy->totalLength)
+ weaponAnimAssoc->SetCurrentTime(0.0f);
+
+ if (IsPlayer()) {
+ ((CPlayerPed*)this)->m_fAttackButtonCounter = 0.0f;
+ ((CPlayerPed*)this)->m_bHaveTargetSelected = false;
+ }
+ }
+ } else
+ FinishedAttackCB(nil, this);
+
+ }
+ 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;
+ }
+ }
+
+ float animStart = animLoopStart * 0.4f;
+ weaponAnimTime = weaponAnimAssoc->currentTime;
+ if (weaponAnimTime > animStart && weaponAnimTime - weaponAnimAssoc->timeStep <= animStart) {
+ if (!bIsDucking && !GetFireAnimNotDucking(ourWeapon) && ourWeapon->IsFlagSet(WEAPONFLAG_CANAIM_WITHARM))
+ m_pedIK.m_flags |= CPedIK::AIMS_WITH_ARM;
+ else
+ m_pedIK.m_flags &= ~CPedIK::AIMS_WITH_ARM;
+ }
+
+ if (ourWeaponType != WEAPONTYPE_CHAINSAW
+ || !meleeAttackStarted && delayBetweenAnimAndFire - 0.5f >= weaponAnimAssoc->currentTime
+ || weaponAnimAssoc->currentTime - weaponAnimAssoc->timeStep > delayBetweenAnimAndFire) {
+
+ 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;
+
+ } else {
+ firePos = ourWeapon->m_vecFireOffset;
+
+ if(ourWeapon->m_AnimToPlay != ASSOCGRP_BASEBALLBAT && ourWeapon->m_AnimToPlay != ASSOCGRP_GOLFCLUB) {
+ if (ourWeapon->m_eWeaponFire != WEAPON_FIRE_MELEE) {
+ TransformToNode(firePos, (weaponAnimAssoc->animId == ANIM_MELEE_ATTACK_2ND && ourWeapon->m_AnimToPlay == ASSOCGRP_UNARMED) ? PED_FOOTR : PED_HANDR);
+ } else {
+ firePos = GetMatrix() * firePos;
+ }
+ } else {
+ if (weaponAnimAssoc->animId == ANIM_MELEE_ATTACK_2ND)
+ firePos.z = 0.7f * ourWeapon->m_fRadius - 1.0f;
+
+ firePos = GetMatrix() * firePos;
+ }
+
+ GetWeapon()->Fire(this, &firePos);
+
+ if (ourWeaponType == WEAPONTYPE_MOLOTOV || ourWeaponType == WEAPONTYPE_GRENADE || ourWeaponType == WEAPONTYPE_DETONATOR_GRENADE ||
+ ourWeaponType == WEAPONTYPE_TEARGAS) {
+ RemoveWeaponModel(CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_nModelId);
+ }
+ if (!GetWeapon()->m_nAmmoTotal && ourWeaponFire != WEAPON_FIRE_MELEE && FindPlayerPed() != this) {
+ SelectGunIfArmed();
+ }
+
+ if (GetWeapon()->m_eWeaponState == WEAPONSTATE_MELEE_MADECONTACT) {
+ int damagerType = ENTITY_TYPE_NOTHING;
+ if (m_pDamageEntity && (m_fDamageImpulse == 0.0f || !m_pDamageEntity->IsBuilding())) {
+ damagerType = m_pDamageEntity->GetType();
+ }
+ switch (ourWeapon->m_AnimToPlay) {
+ case ASSOCGRP_UNARMED:
+ if (weaponAnimAssoc->animId == ANIM_MELEE_ATTACK || weaponAnimAssoc->animId == ANIM_MELEE_ATTACK_START)
+ 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;
+ }
+ }
+
+ 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 (ourWeapon->m_eWeaponFire == WEAPON_FIRE_INSTANT_HIT && ourWeapon->m_AnimToPlay == ASSOCGRP_SHOTGUN) {
+ weaponAnimTime = weaponAnimAssoc->currentTime;
+
+ if (weaponAnimTime > 1.0f && weaponAnimTime - weaponAnimAssoc->timeStep <= 1.0f && weaponAnimAssoc->IsRunning()) {
+ firePos = ourWeapon->m_vecFireOffset;
+ TransformToNode(firePos, PED_HANDR);
+
+ CVector gunshellPos(
+ firePos.x - 0.6f * GetForward().x,
+ firePos.y - 0.6f * GetForward().y,
+ firePos.z - 0.15f * GetUp().z
+ );
+
+ CVector2D gunshellRot(
+ GetRight().x,
+ GetRight().y
+ );
+
+ gunshellRot.Normalise();
+ GetWeapon()->AddGunshell(this, gunshellPos, gunshellRot, 0.025f);
+ }
+ }
+
+ 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()) {
+ if (!attackShouldContinue && weaponAnimAssoc->currentTime > ourWeapon->m_fAnimBreakout) {
+ weaponAnimAssoc->blendDelta = -4.0f;
+ FinishedAttackCB(nil, this);
+ return;
+ }
+ }
+ }
+
+ 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 (GetReloadAnim(ourWeapon) && !reloadAnimAssoc) {
+ if (!CWorld::Players[CWorld::PlayerInFocus].m_bFastReload) {
+ CAnimBlendAssociation *newReloadAssoc = CAnimManager::BlendAnimation(
+ GetClump(), ourWeapon->m_AnimToPlay,
+ bIsDucking && GetCrouchReloadAnim(ourWeapon) ? GetCrouchReloadAnim(ourWeapon) : GetReloadAnim(ourWeapon),
+ 8.0f);
+ newReloadAssoc->SetFinishCallback(FinishedReloadCB, this);
+ }
+ ClearLookFlag();
+ ClearAimFlag();
+ bIsAttacking = false;
+ bIsPointingGunAt = false;
+ m_shootTimer = CTimer::GetTimeInMilliseconds();
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_WEAPON_AK47_BULLET_ECHO, GetWeapon()->m_eWeaponType);
+ return;
+ }
+ }
+ if (weaponAnimTime - 2.0f * weaponAnimAssoc->timeStep <= animLoopEnd
+ && (bIsAttacking || CTimer::GetTimeInMilliseconds() < m_shootTimer)
+ && (GetWeapon()->m_eWeaponState != WEAPONSTATE_RELOADING
+ || GetWeapon()->m_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())) {
+
+ AnimationId fireAnim = GetFireAnimGround(ourWeapon, false);
+ if (weaponAnimAssoc->animId == fireAnim)
+ weaponAnimAssoc->SetCurrentTime(0.1f);
+ else {
+ if (GetFireAnimGround(ourWeapon, false)) {
+ weaponAnimAssoc = CAnimManager::BlendAnimation(GetClump(), ourWeapon->m_AnimToPlay, fireAnim, 8.0f);
+ } else {
+ weaponAnimAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_KICK_FLOOR, 8.0f);
+ }
+ }
+ weaponAnimAssoc->SetFinishCallback(FinishedAttackCB, this);
+ } else if (GetSecondFireAnim(ourWeapon)) {
+ if (weaponAnimAssoc->animId == GetSecondFireAnim(ourWeapon)) {
+ weaponAnimAssoc = CAnimManager::BlendAnimation(GetClump(), ourWeapon->m_AnimToPlay, ANIM_WEAPON_FIRE, 8.0f);
+ } else {
+ weaponAnimAssoc = CAnimManager::BlendAnimation(GetClump(), ourWeapon->m_AnimToPlay, GetSecondFireAnim(ourWeapon), 8.0f);
+ }
+ weaponAnimAssoc->SetFinishCallback(FinishedAttackCB, this);
+ } else {
+ weaponAnimAssoc->SetCurrentTime(animLoopStart);
+ weaponAnimAssoc->SetRun();
+ }
+ } 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 < 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;
+ }
+ }
+ }
+
+ if (weaponAnimAssoc->currentTime > delayBetweenAnimAndFire)
+ attackShouldContinue = false;
+
+ bIsAttacking = attackShouldContinue;
+}
+
+// --MIAMI: Done
+void
+CPed::StartFightAttack(uint8 buttonPressure)
+{
+ if (!IsPedInControl() || (m_attackTimer > CTimer::GetTimeInMilliseconds() && buttonPressure != 0))
+ return;
+
+ if (m_nPedState == PED_FIGHT) {
+ m_fightButtonPressure = buttonPressure;
+ return;
+ }
+
+ if (m_nPedState != PED_AIM_GUN)
+ SetStoredState();
+
+ if (m_nWaitState != WAITSTATE_FALSE) {
+ ClearWaitState();
+ RestoreHeadingRate();
+ }
+
+ CAnimBlendAssociation* animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_RUN_STOP);
+ if (!animAssoc)
+ animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_RUN_STOP_R);
+
+ if (animAssoc) {
+ RestoreHeadingRate();
+ }
+ SetMoveState(PEDMOVE_NONE);
+ m_nStoredMoveState = PEDMOVE_NONE;
+ 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 {
+ fightIdleAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_FIGHT_IDLE, 1000.0f);
+ }
+ m_lastFightMove = FIGHTMOVE_IDLE;
+ m_curFightMove = IsPlayer() ? ChooseAttackPlayer(buttonPressure, fightWithWeapon) : ChooseAttackAI(buttonPressure, fightWithWeapon);
+
+ SetPedState(PED_FIGHT);
+ m_fightButtonPressure = 0;
+
+ 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;
+ }
+
+ m_fightState = FIGHTSTATE_NO_MOVE;
+ m_takeAStepAfterAttack = false;
+ bIsAttacking = true;
+
+ if (IsPlayer())
+ nPlayerInComboMove = 0;
+}
+
+// --MIAMI: Done
+void
+CPed::StartFightDefend(uint8 direction, uint8 hitLevel, uint8 unk)
+{
+ if (m_nPedState == PED_DEAD) {
+ if (CGame::nastyGame) {
+ if (hitLevel == HITLEVEL_GROUND) {
+ CAnimBlendAssociation *floorHitAssoc;
+ if (RpAnimBlendClumpGetFirstAssociation(GetClump(), ASSOC_FRONTAL)) {
+ floorHitAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_FLOOR_HIT_F, 8.0f);
+ } else {
+ floorHitAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, tFightMoves[FIGHTMOVE_HITONFLOOR].animId, 8.0f);
+ }
+ if (floorHitAssoc) {
+ floorHitAssoc->SetCurrentTime(0.0f);
+ floorHitAssoc->SetRun();
+ floorHitAssoc->flags &= ~ASSOC_FADEOUTWHENDONE;
+ }
+ }
+ if (CGame::nastyGame) {
+ CVector headPos = GetNodePosition(PED_HEAD);
+ for(int i = 0; i < 4; ++i) {
+ CVector bloodDir(0.0f, 0.0f, 0.1f);
+ CVector bloodPos = headPos - 0.2f * GetForward();
+ CParticle::AddParticle(PARTICLE_BLOOD, bloodPos, bloodDir, nil, 0.0f, 0, 0, 0, 0);
+ }
+ }
+ }
+ } else if (m_nPedState == PED_FALL) {
+ if (hitLevel == HITLEVEL_GROUND && !IsPedHeadAbovePos(-0.3f)) {
+ CAnimBlendAssociation *floorHitAssoc = RpAnimBlendClumpGetFirstAssociation(GetClump(), ASSOC_FRONTAL) ?
+ CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_FLOOR_HIT_F, 8.0f) :
+ CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_FLOOR_HIT, 8.0f);
+ if (floorHitAssoc) {
+ floorHitAssoc->flags &= ~ASSOC_FADEOUTWHENDONE;
+ floorHitAssoc->flags |= ASSOC_DELETEFADEDOUT;
+ }
+ }
+ } 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)) {
+
+ if (hitLevel != HITLEVEL_HIGH && hitLevel != HITLEVEL_LOW || (IsPlayer() || CGeneral::GetRandomNumber() & 1) && CGeneral::GetRandomNumber() & 7) {
+ if (IsPlayer() || CGeneral::GetRandomNumber() & 1) {
+ AnimationId shotAnim;
+ switch (direction) {
+ case 1:
+ shotAnim = ANIM_SHOT_LEFT_PARTIAL;
+ break;
+ case 2:
+ shotAnim = ANIM_SHOT_BACK_PARTIAL;
+ break;
+ case 3:
+ shotAnim = ANIM_SHOT_RIGHT_PARTIAL;
+ break;
+ default:
+ shotAnim = ANIM_SHOT_FRONT_PARTIAL;
+ break;
+ }
+ CAnimBlendAssociation *shotAssoc = RpAnimBlendClumpGetAssociation(GetClump(), shotAnim);
+ if (!shotAssoc || shotAssoc->blendDelta < 0.0f)
+ shotAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, shotAnim, 8.0f);
+
+ shotAssoc->SetCurrentTime(0.0f);
+ shotAssoc->SetRun();
+ shotAssoc->flags |= ASSOC_FADEOUTWHENDONE;
+ } else {
+ int time = CGeneral::GetRandomNumberInRange(1000, 3000);
+ SetWaitState(WAITSTATE_PLAYANIM_DUCK, &time);
+ }
+ } else {
+ bool fall = true;
+ AnimationId hitAnim;
+ switch (direction) {
+ case 1:
+ hitAnim = ANIM_KO_SPIN_R;
+ break;
+ case 2:
+ if (CGeneral::GetRandomNumber() & 1) {
+ fall = false;
+ hitAnim = ANIM_HIT_BACK;
+ } else {
+ hitAnim = ANIM_KO_SKID_BACK;
+ }
+ break;
+ case 3:
+ hitAnim = ANIM_KO_SPIN_L;
+ break;
+ default:
+ if (hitLevel == HITLEVEL_LOW) {
+ hitAnim = ANIM_KO_SHOT_STOM;
+ } else if (CGeneral::GetRandomNumber() & 1) {
+ fall = false;
+ hitAnim = ANIM_HIT_WALK;
+ } else if (CGeneral::GetRandomNumber() & 1) {
+ fall = false;
+ hitAnim = ANIM_HIT_HEAD;
+ } else {
+ hitAnim = ANIM_KO_SHOT_FACE;
+ }
+ break;
+ }
+ if (fall) {
+ SetFall(500, hitAnim, false);
+ } else {
+ CAnimBlendAssociation *hitAssoc = RpAnimBlendClumpGetAssociation(GetClump(), hitAnim);
+ if (!hitAssoc || hitAssoc->blendDelta < 0.0f)
+ hitAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, hitAnim, 8.0f);
+
+ hitAssoc->SetCurrentTime(0.0f);
+ hitAssoc->SetRun();
+ hitAssoc->flags |= ASSOC_FADEOUTWHENDONE;
+ }
+ }
+ Say(SOUND_PED_DEFEND);
+ } else {
+ Say(SOUND_PED_DEFEND);
+ switch (hitLevel) {
+ case HITLEVEL_GROUND:
+ m_curFightMove = FIGHTMOVE_HITONFLOOR;
+ break;
+ case HITLEVEL_LOW:
+ 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;
+ }
+ m_curFightMove = FIGHTMOVE_HITBODY;
+ break;
+ case HITLEVEL_HIGH:
+ switch (direction) {
+ case 1:
+ m_curFightMove = FIGHTMOVE_HITLEFT;
+ break;
+ case 2:
+ m_curFightMove = FIGHTMOVE_HITBACK;
+ break;
+ case 3:
+ m_curFightMove = FIGHTMOVE_HITRIGHT;
+ break;
+ default:
+ if (unk <= 5)
+ m_curFightMove = FIGHTMOVE_HITHEAD;
+ else
+ m_curFightMove = FIGHTMOVE_HITBIGSTEP;
+ break;
+ }
+ break;
+ default:
+ switch (direction) {
+ case 1:
+ m_curFightMove = FIGHTMOVE_HITLEFT;
+ break;
+ case 2:
+ m_curFightMove = FIGHTMOVE_HITBACK;
+ break;
+ case 3:
+ m_curFightMove = FIGHTMOVE_HITRIGHT;
+ break;
+ default:
+ if (unk <= 5)
+ m_curFightMove = FIGHTMOVE_HITCHEST;
+ else
+ m_curFightMove = FIGHTMOVE_HITBIGSTEP;
+ break;
+ }
+ break;
+ }
+ if (m_nPedState == PED_GETUP && !IsPedHeadAbovePos(0.0f))
+ m_curFightMove = FIGHTMOVE_HITONFLOOR;
+
+ if (m_nPedState == PED_FIGHT) {
+ CAnimBlendAssociation *moveAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, tFightMoves[m_curFightMove].animId, 8.0f);
+ moveAssoc->SetCurrentTime(0.0f);
+ moveAssoc->SetFinishCallback(FinishFightMoveCB, this);
+ if (IsPlayer())
+ moveAssoc->speed = 1.2f;
+
+ m_takeAStepAfterAttack = 0;
+ m_fightButtonPressure = 0;
+
+ } else if (IsPlayer() && GetWeapon()->m_eWeaponType != WEAPONTYPE_UNARMED && GetWeapon()->m_eWeaponType != WEAPONTYPE_BRASSKNUCKLE &&
+ !CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->IsFlagSet(WEAPONFLAG_FIGHTMODE)) {
+ CAnimBlendAssociation *moveAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, tFightMoves[m_curFightMove].animId, 4.0f);
+ moveAssoc->SetCurrentTime(0.0f);
+ moveAssoc->speed = 1.2f;
+
+ } else {
+ if (m_nPedState != PED_AIM_GUN && m_nPedState != PED_ATTACK)
+ SetStoredState();
+
+ if (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) {
+ walkStartAssoc->flags |= ASSOC_DELETEFADEDOUT;
+ walkStartAssoc->blendDelta = -1000.0f;
+ }
+ CAnimBlendAssociation *walkStopAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_RUN_STOP);
+ if (!walkStopAssoc)
+ walkStopAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_RUN_STOP_R);
+ if (walkStopAssoc) {
+ walkStopAssoc->flags |= ASSOC_DELETEFADEDOUT;
+ walkStopAssoc->blendDelta = -1000.0f;
+ RestoreHeadingRate();
+ }
+ SetMoveState(PEDMOVE_NONE);
+ m_nStoredMoveState = PEDMOVE_NONE;
+ 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 fightWithWeapon = false;
+
+ eWeaponType weapon = GetWeapon()->m_eWeaponType;
+ CWeaponInfo *weaponInfo = CWeaponInfo::GetWeaponInfo(weapon);
+
+ if (weaponInfo->IsFlagSet(WEAPONFLAG_FIGHTMODE) && weapon != WEAPONTYPE_UNARMED) {
+ fightWithWeapon = true;
+ tFightMoves[FIGHTMOVE_MELEE1].startFireTime = weaponInfo->m_fAnimFrameFire;
+ tFightMoves[FIGHTMOVE_MELEE1].endFireTime = weaponInfo->m_fAnimLoopEnd;
+ tFightMoves[FIGHTMOVE_MELEE2].startFireTime = weaponInfo->m_fAnim2FrameFire;
+ tFightMoves[FIGHTMOVE_MELEE2].endFireTime = weaponInfo->m_fAnim2LoopEnd;
+ tFightMoves[FIGHTMOVE_MELEE3].startFireTime = weaponInfo->m_fAnim2FrameFire;
+ tFightMoves[FIGHTMOVE_MELEE3].endFireTime = weaponInfo->m_fAnim2LoopEnd;
+ }
+
+ switch (m_curFightMove) {
+ case FIGHTMOVE_NULL:
+ return;
+ case FIGHTMOVE_IDLE2NORM:
+ m_curFightMove = FIGHTMOVE_NULL;
+ RestorePreviousState();
+
+ // FIX: Uninitialized
+ currentAssoc = nil;
+ break;
+ case FIGHTMOVE_IDLE:
+ currentAssoc = nil;
+ break;
+ default:
+ currentAssoc = RpAnimBlendClumpGetAssociation(GetClump(), tFightMoves[m_curFightMove].animId);
+ 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;
+ currentAssoc->flags |= ASSOC_DELETEFADEDOUT;
+ currentAssoc->flags &= ~ASSOC_RUNNING;
+ }
+ if (m_takeAStepAfterAttack)
+ EndFight(ENDFIGHT_WITH_A_STEP);
+ else
+ EndFight(ENDFIGHT_FAST);
+
+ } else if (currentAssoc && m_fightState > FIGHTSTATE_MOVE_FINISHED) {
+ float animTime = currentAssoc->currentTime;
+ 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_KNEE:
+ TransformToNode(touchingNodePos, PED_LOWERLEGR);
+ break;
+ case FIGHTMOVE_PUNCHHOOK:
+ case FIGHTMOVE_PUNCHJAB:
+ TransformToNode(touchingNodePos, PED_HANDL);
+ break;
+ 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;
+ }
+
+ FightStrike(touchingNodePos, fightWithWeapon);
+ m_fightButtonPressure = 0;
+ return;
+ }
+
+ if (curMove.hitLevel != HITLEVEL_NULL) {
+ if (animTime > curMove.endFireTime && weaponInfo->m_AnimToPlay != ASSOCGRP_KNIFE) {
+ if (IsPlayer())
+ currentAssoc->speed = 1.0f;
+ else
+ currentAssoc->speed = 0.8f;
+ }
+
+ 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 (GetWeapon()->m_eWeaponType != WEAPONTYPE_UNARMED && GetWeapon()->m_eWeaponType != WEAPONTYPE_BRASSKNUCKLE && !fightWithWeapon) {
+ EndFight(ENDFIGHT_FAST);
+
+ } else if (m_fightButtonPressure != 0) {
+ if (!IsPlayer())
+ Say(SOUND_PED_ATTACK);
+
+ if (m_curFightMove != FIGHTMOVE_IDLE)
+ m_lastFightMove = m_curFightMove;
+
+ m_curFightMove = IsPlayer() ? ChooseAttackPlayer(m_fightButtonPressure, fightWithWeapon) : ChooseAttackAI(m_fightButtonPressure, fightWithWeapon);
+
+ if (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) {
+ if (m_curFightMove == FIGHTMOVE_BACKKICK)
+ animAssoc->speed = 1.15f;
+ else
+ animAssoc->speed = 0.8f;
+ } else {
+ 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 (m_fightState == FIGHTSTATE_MOVE_FINISHED && animAssoc->currentTime != 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;
+ } else if (m_takeAStepAfterAttack && m_curFightMove != FIGHTMOVE_SHUFFLE_F
+#ifndef FIX_BUGS
+ && CheckForPedsOnGroundToAttack(this, nil) == 4) {
+#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);
+
+ if (animAssoc) {
+ animAssoc->SetCurrentTime(0.0f);
+ animAssoc->blendDelta = 4.0f;
+ animAssoc->SetRun();
+ } else {
+ animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, tFightMoves[m_curFightMove].animId, 32.0f);
+ }
+ animAssoc->SetFinishCallback(FinishFightMoveCB, this);
+ m_fightState = FIGHTSTATE_NO_MOVE;
+ m_fightButtonPressure = 0;
+ m_takeAStepAfterAttack = false;
+
+ } else if (m_takeAStepAfterAttack) {
+ EndFight(ENDFIGHT_FAST);
+
+ } else if (m_curFightMove == FIGHTMOVE_IDLE) {
+ if (CTimer::GetTimeInMilliseconds() > m_nWaitTimer) {
+ EndFight(ENDFIGHT_NORMAL);
+ }
+
+ } else {
+ m_lastFightMove = m_curFightMove;
+ m_curFightMove = FIGHTMOVE_IDLE;
+ if (IsPlayer())
+ m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 500;
+ else
+ m_nWaitTimer = CTimer::GetTimeInMilliseconds() + 2000;
+ }
+}
+
+// --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->IsFlagSet(WEAPONFLAG_GROUND_2ND))
+ return FIGHTMOVE_MELEE2;
+ if (weaponInfo->IsFlagSet(WEAPONFLAG_GROUND_3RD))
+ return FIGHTMOVE_MELEE3;
+
+ return FIGHTMOVE_GROUNDKICK;
+ } else {
+ return FIGHTMOVE_IDLE;
+ }
+ }
+ if (dist < 2.f) {
+ if (m_curFightMove == FIGHTMOVE_MELEE1) {
+ if (GetSecondFireAnim(weaponInfo))
+ return FIGHTMOVE_MELEE2;
+ }
+ if (m_curFightMove == FIGHTMOVE_MELEE2) {
+ if (GetFinishingAttackAnim(weaponInfo))
+ return FIGHTMOVE_MELEE3;
+ }
+ return FIGHTMOVE_MELEE1;
+ }
+ return FIGHTMOVE_SHUFFLE_F;
+ }
+ if (!hasShoppingBags) {
+ if (punchOnly) {
+ if (dist < 1.4f)
+ return FIGHTMOVE_PUNCH;
+ } else {
+ if (m_pedInObjective->OnGroundOrGettingUp()) {
+ if (CGame::nastyGame && dist < 1.2f && !m_pedInObjective->IsPlayer()
+ && (m_pedInObjective->m_nPedState == PED_DEAD || !m_pedInObjective->IsPedHeadAbovePos(-0.3f))) {
+
+ return FIGHTMOVE_GROUNDKICK;
+ } else {
+ return FIGHTMOVE_IDLE;
+ }
+ }
+ if (dist < 0.95f && canKneeHead)
+ return FIGHTMOVE_KNEE;
+ if (dist < 1.4f)
+ return FIGHTMOVE_PUNCH;
+ if (dist < 2.f && canKick) {
+ int nextMove = FIGHTMOVE_LONGKICK;
+ if (canRoundhouse && CGeneral::GetRandomNumber() & 1)
+ nextMove = FIGHTMOVE_ROUNDHOUSE;
+ return nextMove;
+ }
+ }
+ return FIGHTMOVE_SHUFFLE_F;
+ }
+ if (dist < 2.f)
+ return FIGHTMOVE_ROUNDHOUSE;
+ else
+ return FIGHTMOVE_SHUFFLE_F;
+}
+
+// --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->IsFlagSet(WEAPONFLAG_GROUND_2ND)) {
+ choosenMove = FIGHTMOVE_MELEE2;
+ } else if (fightWithWeapon && weaponInfo->IsFlagSet(WEAPONFLAG_GROUND_3RD)) {
+ choosenMove = FIGHTMOVE_MELEE3;
+ } else {
+ choosenMove = FIGHTMOVE_GROUNDKICK;
+ }
+ if (groundAttackAlivePed)
+ m_fRotationDest = groundAttackAliveAngle;
+ else
+ m_fRotationDest = groundAttackDeadAngle;
+
+ m_fRotationCur = m_fRotationDest;
+ m_lookTimer = 0;
+ if (groundAttackAlivePed)
+ SetLookFlag(groundAttackAlivePed, 1, 0);
+ else
+ SetLookFlag(groundAttackDeadPed, 1, 0);
+
+ SetLookTimer(1500u);
+
+ } else if (walkUpTo) {
+ choosenMove = FIGHTMOVE_SHUFFLE_F;
+ m_fRotationCur = m_fRotationDest = walkAngle;
+ m_lookTimer = 0;
+ SetLookFlag(walkUpTo, true);
+ SetLookTimer(1500);
+
+ } else if (fightWithWeapon) {
+ // No enemy, fight with space
+ if (GetWeapon()->m_eWeaponType == WEAPONTYPE_SCREWDRIVER) {
+ choosenMove = FIGHTMOVE_MELEE3;
+ } else {
+ if (m_lastFightMove == FIGHTMOVE_MELEE1 && GetFinishingAttackAnim(weaponInfo)) {
+ choosenMove = FIGHTMOVE_MELEE2;
+ } else if (m_lastFightMove == FIGHTMOVE_MELEE2 && GetFinishingAttackAnim(weaponInfo)) {
+ choosenMove = FIGHTMOVE_MELEE3;
+ } else {
+ choosenMove = FIGHTMOVE_MELEE1;
+ }
+ }
+ } else {
+ // Max number GetRandomNumberInRange returns is max-1
+#ifdef FIX_BUGS
+ switch (CGeneral::GetRandomNumberInRange(0,4)) {
+#else
+ switch (CGeneral::GetRandomNumberInRange(0,3)) {
+#endif
+ case 0:
+ choosenMove = FIGHTMOVE_PUNCHJAB;
+ break;
+ case 1:
+ choosenMove = FIGHTMOVE_PUNCH;
+ break;
+ case 2:
+ choosenMove = FIGHTMOVE_LONGKICK;
+ break;
+ case 3:
+ choosenMove = FIGHTMOVE_KNEE;
+ break;
+ default:
+ break;
+ }
+ }
+ return choosenMove;
+}
+
+// --MIAMI: Done
+void
+CPed::EndFight(uint8 endType)
+{
+ if (m_nPedState != PED_FIGHT)
+ return;
+
+ 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;
+
+ switch (endType) {
+ case ENDFIGHT_NORMAL:
+ CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_IDLE_STANCE, 8.0f);
+ CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_FIGHT2_IDLE, 8.0f);
+ break;
+ case ENDFIGHT_WITH_A_STEP:
+ CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_IDLE_STANCE, 1.0f);
+ CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_WALK_START, 8.0f);
+ break;
+ case ENDFIGHT_FAST:
+ CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_IDLE_STANCE, 8.0f);
+ CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_FIGHT2_IDLE, 8.0f)->speed = 2.0f;
+ break;
+ default:
+ break;
+ }
+ 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 17, total 17), second is the one of we fight with (from 18 to 27, total 10).
+ enum {
+ 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
+ };
+ 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 }
+ };
+
+ 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 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];
+
+ } else {
+ if (hitTo->m_nPedState == PED_DEAD || hitTo->UseGroundColModel()) {
+ soundId = hitSoundsByFightMoves[m_curFightMove - FIGHTMOVE_STDPUNCH][FIGHTMOVE_HITONFLOOR - FIGHTMOVE_HITFRONT];
+ } else {
+ soundId = hitSoundsByFightMoves[m_curFightMove - FIGHTMOVE_STDPUNCH][FIGHTMOVE_HITFRONT - FIGHTMOVE_HITFRONT];
+ }
+ }
+
+ if (soundId != NO_SND)
+ DMAudio.PlayOneShot(m_audioEntityId, soundId, (weapon << 8) | 3);
+}
+
+// --MIAMI: Done
+bool
+CPed::FightStrike(CVector &touchedNodePos, bool fightWithWeapon)
+{
+ CColModel *hisCol;
+ CVector attackDistance;
+ float maxDistanceToBeat;
+ CPed *nearPed;
+ CVector extendedTouchPoint;
+
+ 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;
+
+ 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 (!fightWithWeapon && GetWeapon()->m_eWeaponType != WEAPONTYPE_UNARMED && GetWeapon()->m_eWeaponType != WEAPONTYPE_BRASSKNUCKLE)
+ maxDistanceToBeat = nearPed->GetBoundRadius() + radius + 0.1f;
+ else
+ maxDistanceToBeat = nearPed->GetBoundRadius() + radius;
+
+ 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(maxDistanceToBeat) > potentialAttackDistance.MagnitudeSqr()) {
+
+ for (int j = 0; j < hisCol->numSpheres; j++) {
+ attackDistance = hisCol->spheres[j].center;
+ attackDistance -= touchedNodePos;
+ CColSphere *hisPieces = hisCol->spheres;
+ maxDistanceToBeat = hisPieces[j].radius + radius;
+
+ // We can beat him too
+ if (sq(maxDistanceToBeat) > attackDistance.MagnitudeSqr()) {
+ 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 (m_fightState == FIGHTSTATE_NO_MOVE)
+ m_fightState = FIGHTSTATE_1;
+
+ 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->IsFlagSet(WEAPONFLAG_FIGHTMODE)) {
+ fightingWithWeapon = true;
+ if (m_curFightMove >= FIGHTMOVE_MELEE1) {
+ damageMult = weaponInfo->m_nDamage;
+ if (m_curFightMove == FIGHTMOVE_MELEE3 && GetWeapon()->m_eWeaponType != WEAPONTYPE_SCREWDRIVER)
+ damageMult *= 5;
+ }
+ }
+
+ 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;
+ }
+ }
+ 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;
+
+ if (!victim->DyingOrDead()) {
+ if(fightingWithWeapon)
+ victim->InflictDamage(this, GetWeapon()->m_eWeaponType, damageMult, (ePedPieceTypes)piece, direction);
+ else
+ victim->InflictDamage(this, WEAPONTYPE_UNARMED, damageMult * 3.0f, (ePedPieceTypes)piece, direction);
+ }
+
+ if (CGame::nastyGame && weaponInfo->m_AnimToPlay == ASSOCGRP_KNIFE && m_curFightMove >= FIGHTMOVE_MELEE1
+ && victim->GetIsOnScreen()) {
+
+ static float particleRightLen = 0.05f;
+ static float particleUpLen = 0.05f;
+
+ // Just for particles. We will restore it below.
+ dir /= (20.0f * dir.Magnitude());
+ if (m_curFightMove == FIGHTMOVE_MELEE1) {
+ float rightMult = -particleRightLen;
+ dir += particleUpLen * GetUp() + rightMult * GetRight();
+
+ } else if (m_curFightMove == FIGHTMOVE_MELEE2) {
+ float upMult = 2.0f * particleUpLen;
+ dir += particleRightLen * GetRight() + upMult * GetUp();
+ }
+ CParticle::AddParticle(PARTICLE_BLOOD_SPURT, bloodPos, dir, nil, 0.0f, 0, 0, 0, 0);
+ CParticle::AddParticle(PARTICLE_BLOOD_SPURT, bloodPos, dir, nil, 0.0f, 0, 0, 0, 0);
+ if (IsPlayer()) {
+ CParticle::AddParticle(PARTICLE_BLOOD_SPURT, bloodPos, dir, nil, 0.0f, 0, 0, 0, 0);
+ CParticle::AddParticle(PARTICLE_BLOOD_SPURT, bloodPos, dir, nil, 0.0f, 0, 0, 0, 0);
+ }
+ if (!(CGeneral::GetRandomNumber() & 3)) {
+ CParticle::AddParticle(PARTICLE_TEST, bloodPos, dir, nil, 0.0f, 0, 0, 0, 0);
+ }
+ } else if (CGame::nastyGame && (tFightMoves[m_curFightMove].hitLevel > HITLEVEL_MEDIUM || fightingWithWeapon)
+ && victim->GetIsOnScreen()) {
+
+ // Just for particles. We will restore it below.
+ dir /= (10.0f * dir.Magnitude());
+ for (int i = 0; i < 4; i++) {
+ CParticle::AddParticle(PARTICLE_BLOOD, bloodPos, dir, nil, 0.0f, 0, 0, 0, 0);
+ }
+ }
+
+ eWeaponType weaponType = GetWeapon()->m_eWeaponType;
+ if (!fightingWithWeapon) {
+ if (!victim->OnGround()) {
+ float curVictimHealth = victim->m_fHealth;
+ if (curVictimHealth > 0.0f
+ && (curVictimHealth < 30.0f && oldVictimHealth > 30.0f
+ || weaponType != WEAPONTYPE_UNARMED && weaponType != WEAPONTYPE_BRASSKNUCKLE && IsPlayer()
+ || victim->m_pedStats->m_flags & STAT_ONE_HIT_KNOCKDOWN || brassKnucklePunch)) {
+
+ victim->SetFall(0, (AnimationId)(direction + ANIM_KO_SKID_FRONT), 0);
+ if (victim->m_nPedState == PED_FALL)
+ victim->bIsStanding = false;
+ }
+ }
+ }
+
+ 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 {
+ moveMult = Min(damageMult * 2.0f, 14.0f);
+ }
+ }
+
+ victim->ApplyMoveForce(moveMult * 0.6 * dir);
+ }
+
+ if (weaponType != WEAPONTYPE_KNIFE && weaponType != WEAPONTYPE_MACHETE
+ && weaponType != WEAPONTYPE_KATANA && weaponType != WEAPONTYPE_CHAINSAW) {
+
+ 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)
+{
+ CPed *ped = (CPed*)arg;
+
+ if (tFightMoves[ped->m_curFightMove].animId == animAssoc->animId) {
+ ped->m_fightState = FIGHTSTATE_MOVE_FINISHED;
+ animAssoc->blendDelta = -1000.0f;
+ }
+}
+
+// --MIAMI: Done
+void
+CPed::LoadFightData(void)
+{
+ float startFireTime, endFireTime, comboFollowOnTime, strikeRadius, extendReachMultiplier;
+ int damage, flags;
+ char line[256], moveName[32], animName[32], hitLevel;
+ int moveId = 0;
+
+ CAnimBlendAssociation *animAssoc;
+
+ size_t bp, buflen;
+ int lp, linelen;
+
+ buflen = CFileMgr::LoadFile("DATA\\fistfite.dat", work_buff, sizeof(work_buff), "r");
+
+ for (bp = 0; bp < buflen; ) {
+ // read file line by line
+ for (linelen = 0; work_buff[bp] != '\n' && bp < buflen; bp++) {
+ line[linelen++] = work_buff[bp];
+ }
+ bp++;
+ line[linelen] = '\0';
+
+ // skip white space
+ for (lp = 0; line[lp] <= ' ' && line[lp] != '\0'; lp++);
+
+ if (line[lp] == '\0' ||
+ line[lp] == '#')
+ continue;
+
+ sscanf(
+ &line[lp],
+ "%s %f %f %f %f %f %c %s %d %d",
+ moveName,
+ &startFireTime,
+ &endFireTime,
+ &comboFollowOnTime,
+ &strikeRadius,
+ &extendReachMultiplier,
+ &hitLevel,
+ animName,
+ &damage,
+ &flags);
+
+ if (strncmp(moveName, "ENDWEAPONDATA", 13) == 0)
+ return;
+
+ tFightMoves[moveId].startFireTime = startFireTime / 30.0f;
+ 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;
+
+ switch (hitLevel) {
+ case 'G':
+ tFightMoves[moveId].hitLevel = HITLEVEL_GROUND;
+ break;
+ case 'H':
+ tFightMoves[moveId].hitLevel = HITLEVEL_HIGH;
+ break;
+ case 'L':
+ tFightMoves[moveId].hitLevel = HITLEVEL_LOW;
+ break;
+ case 'M':
+ tFightMoves[moveId].hitLevel = HITLEVEL_MEDIUM;
+ break;
+ case 'N':
+ tFightMoves[moveId].hitLevel = HITLEVEL_NULL;
+ break;
+ default:
+ break;
+ }
+
+ if (strcmp(animName, "default") != 0) {
+ if (strcmp(animName, "null") != 0) {
+ animAssoc = CAnimManager::GetAnimAssociation(ASSOCGRP_STD, animName);
+ tFightMoves[moveId].animId = (AnimationId)animAssoc->animId;
+ } else {
+ tFightMoves[moveId].animId = ANIM_WALK;
+ }
+ }
+ moveId++;
+ }
+}
+
+// --MIAMI: Done
+void
+CPed::SetInvestigateEvent(eEventType event, CVector2D pos, float distanceToCountDone, uint16 time, float angle)
+{
+ if (!IsPedInControl() || CharCreatedBy == MISSION_CHAR)
+ return;
+
+ SetStoredState();
+ bFindNewNodeAfterStateRestore = false;
+ SetPedState(PED_INVESTIGATE);
+ m_standardTimer = CTimer::GetTimeInMilliseconds() + time;
+ m_eventType = event;
+ m_eventOrThreat = pos;
+ m_distanceToCountSeekDone = distanceToCountDone;
+ m_fAngleToEvent = angle;
+
+ if (m_eventType >= EVENT_ICECREAM)
+ m_lookTimer = 0;
+ else
+ CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_HANDSCOWER, 4.0f);
+
+}
+
+// --MIAMI: Done
+void
+CPed::InvestigateEvent(void)
+{
+ CAnimBlendAssociation *animAssoc;
+ AnimationId animToPlay;
+ AssocGroupId animGroup;
+
+ if (m_nWaitState == WAITSTATE_TURN180)
+ return;
+
+ if (CTimer::GetTimeInMilliseconds() > m_standardTimer) {
+
+ if (m_standardTimer) {
+ if (m_eventType < EVENT_UNK)
+ SetWaitState(WAITSTATE_TURN180, nil);
+
+ m_standardTimer = 0;
+ } else {
+ ClearInvestigateEvent();
+ }
+ return;
+ }
+
+ CVector2D vecDist = m_eventOrThreat - GetPosition();
+ float distSqr = vecDist.MagnitudeSqr();
+ if (sq(m_distanceToCountSeekDone) >= distSqr) {
+
+ m_fRotationDest = CGeneral::GetRadianAngleBetweenPoints(vecDist.x, vecDist.y, 0.0f, 0.0f);
+ SetMoveState(PEDMOVE_STILL);
+
+ switch (m_eventType) {
+ case EVENT_DEAD_PED:
+ case EVENT_HIT_AND_RUN:
+ case EVENT_HIT_AND_RUN_COP:
+
+ if (CTimer::GetTimeInMilliseconds() > m_lookTimer) {
+ animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_ROAD_CROSS);
+
+ if (animAssoc) {
+ animAssoc->blendDelta = -8.0f;
+ animAssoc->flags |= ASSOC_DELETEFADEDOUT;
+ if (m_pEventEntity)
+ SetLookFlag(m_pEventEntity, true);
+
+ SetLookTimer(CGeneral::GetRandomNumberInRange(1500, 4000));
+
+ } else if (CGeneral::GetRandomNumber() & 3) {
+ ClearLookFlag();
+ CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_ROAD_CROSS, 4.0f);
+
+ SetLookTimer(CGeneral::GetRandomNumberInRange(1000, 2500));
+ Say(SOUND_PED_CHAT_EVENT);
+
+ } else {
+ ClearInvestigateEvent();
+ }
+ }
+ break;
+ case EVENT_FIRE:
+ case EVENT_EXPLOSION:
+
+ if (bHasACamera && CTimer::GetTimeInMilliseconds() > m_lookTimer) {
+ animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_CAM);
+ if (!animAssoc)
+ animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_STANCE);
+
+ if (animAssoc && animAssoc->animId == ANIM_IDLE_CAM) {
+ CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_IDLE_STANCE, 4.0f);
+ SetLookTimer(CGeneral::GetRandomNumberInRange(1000, 2500));
+
+ } else if (CGeneral::GetRandomNumber() & 3) {
+ CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_IDLE_CAM, 4.0f);
+ SetLookTimer(CGeneral::GetRandomNumberInRange(2500, 5000));
+ if (!CGame::germanGame)
+ Say(SOUND_PED_CHAT_EVENT);
+
+ } else {
+ m_standardTimer = 0;
+ }
+
+ } else if (CTimer::GetTimeInMilliseconds() > m_lookTimer) {
+ animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_STANCE);
+ if (!animAssoc)
+ animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_HBHB);
+
+ if (!animAssoc)
+ animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_XPRESS_SCRATCH);
+
+ if (animAssoc && animAssoc->animId == ANIM_IDLE_STANCE) {
+ if (CGeneral::GetRandomNumber() & 1)
+ animToPlay = ANIM_IDLE_HBHB;
+ else
+ animToPlay = ANIM_XPRESS_SCRATCH;
+
+ CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, animToPlay, 4.0f);
+ SetLookTimer(CGeneral::GetRandomNumberInRange(1500, 4000));
+
+ } else if (animAssoc && animAssoc->animId == ANIM_IDLE_HBHB) {
+ animAssoc->blendDelta = -8.0f;
+ animAssoc->flags |= ASSOC_DELETEFADEDOUT;
+ if (CGeneral::GetRandomNumber() & 1) {
+ animToPlay = ANIM_IDLE_STANCE;
+ animGroup = m_animGroup;
+ } else {
+ animToPlay = ANIM_XPRESS_SCRATCH;
+ animGroup = ASSOCGRP_STD;
+ }
+
+ CAnimManager::BlendAnimation(GetClump(), animGroup, animToPlay, 4.0f);
+ SetLookTimer(CGeneral::GetRandomNumberInRange(1000, 2500));
+
+ } else {
+ if (CGeneral::GetRandomNumber() & 1) {
+ animToPlay = ANIM_IDLE_STANCE;
+ animGroup = m_animGroup;
+ } else {
+ animToPlay = ANIM_IDLE_HBHB;
+ animGroup = ASSOCGRP_STD;
+ }
+
+ CAnimManager::BlendAnimation(GetClump(), animGroup, animToPlay, 4.0f);
+ SetLookTimer(CGeneral::GetRandomNumberInRange(1000, 2500));
+ }
+ if (!CGame::germanGame)
+ Say(SOUND_PED_CHAT_EVENT);
+ }
+ break;
+ case EVENT_ICECREAM:
+ case EVENT_SHOPSTALL:
+
+ m_fRotationDest = m_fAngleToEvent;
+ if (CTimer::GetTimeInMilliseconds() > m_lookTimer) {
+
+ if (m_lookTimer) {
+ animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_ROAD_CROSS);
+
+ if (animAssoc) {
+ animAssoc->blendDelta = -8.0f;
+ animAssoc->flags |= ASSOC_DELETEFADEDOUT;
+ if (m_eventType == EVENT_ICECREAM)
+ animToPlay = ANIM_IDLE_CHAT;
+ else
+ animToPlay = ANIM_XPRESS_SCRATCH;
+ CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, animToPlay,4.0f);
+ SetLookTimer(CGeneral::GetRandomNumberInRange(2000, 5000));
+
+ } else {
+ animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_CHAT);
+ if (animAssoc) {
+ animAssoc->blendDelta = -8.0f;
+ animAssoc->flags |= ASSOC_DELETEFADEDOUT;
+ ClearInvestigateEvent();
+ } else {
+ animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_XPRESS_SCRATCH);
+ if (animAssoc) {
+ animAssoc->blendDelta = -8.0f;
+ animAssoc->flags |= ASSOC_DELETEFADEDOUT;
+ }
+ ClearInvestigateEvent();
+ }
+ }
+ } else {
+ CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_ROAD_CROSS, 4.0f);
+ SetLookTimer(CGeneral::GetRandomNumberInRange(1000, 2500));
+ }
+ }
+ break;
+ default:
+ return;
+ }
+ } else {
+ m_vecSeekPos.x = m_eventOrThreat.x;
+ m_vecSeekPos.y = m_eventOrThreat.y;
+ m_vecSeekPos.z = GetPosition().z;
+ Seek();
+
+ if (m_eventType < EVENT_ICECREAM) {
+ if (sq(5.0f + m_distanceToCountSeekDone) < distSqr) {
+ SetMoveState(PEDMOVE_RUN);
+ return;
+ }
+ }
+ if (m_eventType <= EVENT_EXPLOSION || m_eventType >= EVENT_SHOPSTALL) {
+ SetMoveState(PEDMOVE_WALK);
+ return;
+ }
+ if (distSqr > sq(1.2f)) {
+ SetMoveState(PEDMOVE_WALK);
+ 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);
+ willStandStill = true;
+ break;
+ }
+ }
+
+ if (!willStandStill)
+ SetMoveState(PEDMOVE_WALK);
+ }
+}
+
+// --MIAMI: Done
+void
+CPed::ClearInvestigateEvent(void)
+{
+ CAnimBlendAssociation *animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_ROAD_CROSS);
+ if (!animAssoc)
+ animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_XPRESS_SCRATCH);
+ if (!animAssoc)
+ animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_HBHB);
+ if (!animAssoc)
+ animAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_CHAT);
+ if (animAssoc) {
+ animAssoc->blendDelta = -8.0f;
+ animAssoc->flags |= ASSOC_DELETEFADEDOUT;
+ }
+ if (m_eventType > EVENT_EXPLOSION)
+ m_standardTimer = CTimer::GetTimeInMilliseconds() + 15000;
+
+ bGonnaInvestigateEvent = false;
+ m_pEventEntity = nil;
+ ClearLookFlag();
+ RestorePreviousState();
+ if(m_nMoveState == PEDMOVE_NONE || m_nMoveState == PEDMOVE_STILL)
+ SetMoveState(PEDMOVE_WALK);
+}
+
+// --MIAMI: Done
+bool
+CPed::InflictDamage(CEntity *damagedBy, eWeaponType method, float damage, ePedPieceTypes pedPiece, uint8 direction)
+{
+ CPlayerPed *player = FindPlayerPed();
+ float dieDelta = 4.0f;
+ float dieSpeed = 0.0f;
+ AnimationId dieAnim = ANIM_KO_SHOT_FRONT1;
+ bool headShot = false;
+ 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 (method == WEAPONTYPE_DROWNING && !bDrownsInWater)
+ return false;
+
+ if (!bUsesCollision && (!bInVehicle || m_nPedState != PED_DRIVING) && method != WEAPONTYPE_DROWNING)
+ return false;
+
+ if (bOnlyDamagedByPlayer && damagedBy != player && damagedBy != FindPlayerVehicle() &&
+ method != WEAPONTYPE_DROWNING && method != WEAPONTYPE_EXPLOSION)
+ return false;
+
+ float healthImpact;
+ if (IsPlayer())
+ healthImpact = damage * 0.33f;
+ 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_GETUP) {
+ if (!IsPedHeadAbovePos(-0.3f)) {
+ if (RpAnimBlendClumpGetFirstAssociation(GetClump(), ASSOC_FRONTAL))
+ dieAnim = ANIM_FLOOR_HIT_F;
+ else
+ dieAnim = ANIM_FLOOR_HIT;
+ dieDelta *= 2.0f;
+ dieSpeed = 0.5f;
+ 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_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 {
+ 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;
+ }
+ }
+ 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 (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 {
+ dieAnim = ANIM_KO_SHOT_FACE;
+ }
+ } else {
+ dieAnim = ANIM_KO_SHOT_FACE;
+ RemoveBodyPart(PED_HEAD, direction);
+ headShot = true;
+ willLinger = true;
+ }
+ break;
+ case WEAPONTYPE_COLT45:
+ case WEAPONTYPE_SHOTGUN:
+ case WEAPONTYPE_STUBBY_SHOTGUN:
+ case WEAPONTYPE_SPAS12_SHOTGUN:
+ case WEAPONTYPE_TEC9:
+ case WEAPONTYPE_UZI:
+ case WEAPONTYPE_SILENCED_INGRAM:
+ case WEAPONTYPE_MP5:
+ case WEAPONTYPE_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 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) {
+ 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_FRONT1;
+
+ willLinger = false;
+ } else {
+ switch (pedPiece) {
+ case PEDPIECE_TORSO:
+ willLinger = false;
+ dieAnim = ANIM_KO_SHOT_FRONT1;
+ break;
+ case PEDPIECE_MID:
+ willLinger = false;
+ dieAnim = ANIM_KO_SHOT_STOM;
+ break;
+ case PEDPIECE_LEFTARM:
+ dieAnim = ANIM_KO_SHOT_ARML;
+ RemoveBodyPart(PED_UPPERARML, direction);
+ willLinger = true;
+ break;
+ case PEDPIECE_RIGHTARM:
+ dieAnim = ANIM_KO_SHOT_ARMR;
+ RemoveBodyPart(PED_UPPERARMR, direction);
+ willLinger = true;
+ break;
+ case PEDPIECE_LEFTLEG:
+ dieAnim = ANIM_KO_SHOT_LEGL;
+ RemoveBodyPart(PED_UPPERLEGL, direction);
+ willLinger = true;
+ break;
+ case PEDPIECE_RIGHTLEG:
+ dieAnim = ANIM_KO_SHOT_LEGR;
+ RemoveBodyPart(PED_UPPERLEGR, direction);
+ willLinger = true;
+ break;
+ case PEDPIECE_HEAD:
+ dieAnim = ANIM_KO_SHOT_FACE;
+ RemoveBodyPart(PED_HEAD, direction);
+ headShot = true;
+ willLinger = true;
+ break;
+ default:
+ break;
+ }
+ }
+ break;
+ case WEAPONTYPE_GRENADE:
+ case WEAPONTYPE_ROCKETLAUNCHER:
+ case WEAPONTYPE_EXPLOSION:
+ if (bExplosionProof)
+ return false;
+
+ if (CGame::nastyGame && !IsPlayer() && !bInVehicle &&
+ 1.0f + healthImpact > m_fArmour + m_fHealth) {
+
+ random = CGeneral::GetRandomNumber();
+ if (random & 1)
+ RemoveBodyPart(PED_UPPERARML, direction);
+ if (random & 2)
+ RemoveBodyPart(PED_UPPERLEGR, direction);
+ if (random & 4)
+ RemoveBodyPart(PED_HEAD, direction);
+ if (random & 8)
+ RemoveBodyPart(PED_UPPERARMR, direction);
+ if (random & 0x10)
+ RemoveBodyPart(PED_UPPERLEGL, direction);
+ if (bBodyPartJustCameOff)
+ willLinger = true;
+ }
+ // fall through
+ case WEAPONTYPE_MOLOTOV:
+ if (bExplosionProof)
+ return false;
+
+ 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;
+ }
+ break;
+ case WEAPONTYPE_FLAMETHROWER:
+ if (bFireProof)
+ return false;
+
+ dieAnim = ANIM_KO_SHOT_FRONT1;
+ break;
+ case WEAPONTYPE_RAMMEDBYCAR:
+ case WEAPONTYPE_RUNOVERBYCAR:
+ if (bCollisionProof)
+ return false;
+
+ random = CGeneral::GetRandomNumber() & 3;
+ switch (random) {
+ case 0:
+ if ((pedPiece != PEDPIECE_LEFTARM || random <= 1)
+ && (pedPiece != PEDPIECE_MID || random != 1)) {
+ if (pedPiece == PEDPIECE_RIGHTARM && random > 1
+ || pedPiece == PEDPIECE_MID && random == 2)
+
+ dieAnim = ANIM_KO_SPIN_L;
+ else
+ dieAnim = ANIM_KO_SKID_FRONT;
+ } else
+ dieAnim = ANIM_KO_SPIN_R;
+
+ break;
+ case 1:
+ if (m_nPedState == PED_DIVE_AWAY)
+ dieAnim = ANIM_KD_LEFT;
+ else
+ dieAnim = ANIM_KO_SPIN_R;
+ break;
+ case 2:
+ if ((pedPiece != PEDPIECE_LEFTARM || random <= 1)
+ && (pedPiece != PEDPIECE_MID || random != 1)) {
+ if ((pedPiece != PEDPIECE_RIGHTARM || random <= 1)
+ && (pedPiece != PEDPIECE_MID || random != 2)) {
+ dieAnim = ANIM_KO_SKID_BACK;
+ } else {
+ dieAnim = ANIM_KD_RIGHT;
+ }
+ } else
+ dieAnim = ANIM_KD_LEFT;
+ break;
+ case 3:
+ if (m_nPedState == PED_DIVE_AWAY)
+ dieAnim = ANIM_KD_RIGHT;
+ else
+ dieAnim = ANIM_KO_SPIN_L;
+ break;
+ default:
+ break;
+ }
+ if (damagedBy && pedPiece != PEDPIECE_TORSO) {
+ CVehicle *vehicle = (CVehicle*)damagedBy;
+ if (method == WEAPONTYPE_RAMMEDBYCAR) {
+ float vehSpeed = vehicle->m_vecMoveSpeed.Magnitude();
+ dieDelta = 8.0f * vehSpeed + 4.0f;
+ } else {
+ float vehSpeed = vehicle->m_vecMoveSpeed.Magnitude();
+ dieDelta = 12.0f * vehSpeed + 4.0f;
+ dieSpeed = 16.0f * vehSpeed + 1.0f;
+ }
+ }
+ break;
+ case WEAPONTYPE_DROWNING:
+ dieAnim = ANIM_DROWN;
+ break;
+ case WEAPONTYPE_FALL:
+ if (bCollisionProof)
+ return false;
+
+ 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;
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ if (m_fArmour != 0.0f && method != WEAPONTYPE_DROWNING) {
+ if (player == this)
+ CWorld::Players[CWorld::PlayerInFocus].m_nTimeLastArmourLoss = CTimer::GetTimeInMilliseconds();
+
+ if (healthImpact < m_fArmour) {
+ m_fArmour = m_fArmour - healthImpact;
+ healthImpact = 0.0f;
+ } else {
+ healthImpact = healthImpact - m_fArmour;
+ m_fArmour = 0.0f;
+ }
+ }
+
+ if (healthImpact != 0.0f) {
+ if (player == this)
+ 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) {
+ m_fHealth -= healthImpact;
+ return false;
+ }
+
+ if (bInVehicle) {
+ if (method != WEAPONTYPE_DROWNING) {
+ if (m_pMyVehicle) {
+ CVehicle* pVehicle = m_pMyVehicle;
+ bool bDone = false;
+ if (m_pMyVehicle->IsBike()) {
+ m_fHealth = 0.0f;
+ ((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;
+ }
+ }
+ 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(pVehicle->pPassengers); i++) {
+ CPed* passenger = pVehicle->pPassengers[i];
+ if (passenger && passenger != this && damagedBy)
+ passenger->ReactToAttack(damagedBy);
+ }
+
+ CPed *driverOfVeh = pVehicle->pDriver;
+ if (driverOfVeh && driverOfVeh != this && damagedBy)
+ driverOfVeh->ReactToAttack(damagedBy);
+
+ if (damagedBy == FindPlayerPed() || damagedBy && damagedBy == FindPlayerVehicle()) {
+ CDarkel::RegisterKillByPlayer(this, method, headShot);
+ m_threatEntity = FindPlayerPed();
+ } else {
+ CDarkel::RegisterKillNotByPlayer(this, method);
+ }
+ if (bDone)
+ return true;
+ }
+ m_fHealth = 1.0f;
+ return false;
+ }
+ m_fHealth = 0.0f;
+ if (player == this)
+ m_pMyVehicle->SetStatus(STATUS_PLAYER_DISABLED);
+
+ 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()) {
+ 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) {
+ bIsInTheAir = false;
+ if (FindPlayerPed() == this)
+ CStats::TimesDrowned++;
+ }
+
+ return true;
+ }
+}
+
+static RwObject*
+SetPedAtomicVisibilityCB(RwObject* object, void* data)
+{
+ if (data == nil)
+ RpAtomicSetFlags((RpAtomic*)object, 0);
+ return object;
+}
+
+static RwFrame*
+RecurseFrameChildrenVisibilityCB(RwFrame* frame, void* data)
+{
+ RwFrameForAllObjects(frame, SetPedAtomicVisibilityCB, data);
+ RwFrameForAllChildren(frame, RecurseFrameChildrenVisibilityCB, nil);
+ return frame;
+}
+
+static RwObject*
+CloneAtomicToFrameCB(RwObject *frame, void *data)
+{
+ RpAtomic *newAtomic = RpAtomicClone((RpAtomic*)frame);
+ RpAtomicSetFrame(newAtomic, (RwFrame*)data);
+ RpClumpAddAtomic(flyingClumpTemp, newAtomic);
+ CVisibilityPlugins::SetAtomicRenderCallback(newAtomic, nil);
+ return frame;
+}
+
+static RwFrame*
+RecurseFrameChildrenToCloneCB(RwFrame *frame, void *data)
+{
+ RwFrame *newFrame = RwFrameCreate();
+ RwFrameAddChild((RwFrame*)data, newFrame);
+ RwFrameTransform(newFrame, RwFrameGetMatrix(frame), rwCOMBINEREPLACE);
+ RwFrameForAllObjects(frame, CloneAtomicToFrameCB, newFrame);
+ RwFrameForAllChildren(frame, RecurseFrameChildrenToCloneCB, newFrame);
+ return newFrame;
+}
+
+// --MIAMI: Done
+void
+CPed::RemoveBodyPart(PedNode nodeId, int8 direction)
+{
+ RwFrame *frame;
+ CVector pos;
+
+ frame = m_pFrames[nodeId]->frame;
+ if (frame) {
+ if (CGame::nastyGame) {
+ 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);
+
+ for (int i = 0; i < 16; i++) {
+ CParticle::AddParticle(PARTICLE_BLOOD_SMALL,
+ pos,
+ CVector(0.0f, 0.0f, 0.03f),
+ nil, 0.0f, 0, 0, 0, 0);
+ }
+ }
+ bBodyPartJustCameOff = true;
+ m_bodyPartBleeding = nodeId;
+ }
+ } else {
+ printf("Trying to remove ped component");
+ }
+}
+
+// --MIAMI: Done
+CObject*
+CPed::SpawnFlyingComponent(int pedNode, int8 direction)
+{
+ // VC doesn't have detachable limbs :shrug:
+ return nil;
+}
+
+// --MIAMI: Done
+// III leftover and unused
+void
+CPed::ApplyHeadShot(eWeaponType weaponType, CVector pos, bool evenOnPlayer)
+{
+ CVector pos2 = CVector(
+ pos.x,
+ pos.y,
+ pos.z + 0.1f
+ );
+
+ if (!IsPlayer() || evenOnPlayer) {
+ ++CStats::HeadsPopped;
+
+ // 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();
+ // }
+
+ 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);
+
+ if (CEntity::GetIsOnScreen()) {
+ for(int i=0; i < 32; i++) {
+ CParticle::AddParticle(PARTICLE_BLOOD_SMALL,
+ pos2, CVector(0.0f, 0.0f, 0.03f),
+ nil, 0.0f, 0, 0, 0, 0);
+ }
+
+ for (int i = 0; i < 16; i++) {
+ CParticle::AddParticle(PARTICLE_DEBRIS2,
+ pos2,
+ CVector(0.0f, 0.0f, 0.01f),
+ nil, 0.0f, 0, 0, 0, 0);
+ }
+ }
+ }
+}
+
+// --MIAMI: Done
+bool
+CPed::IsPedHeadAbovePos(float zOffset)
+{
+ return zOffset + GetPosition().z < GetNodePosition(PED_HEAD).z;
+}
+
+// --MIAMI: Done
+bool
+CPed::PlacePedOnDryLand(void)
+{
+ float waterLevel = 0.0f;
+ CEntity *foundEnt = nil;
+ CColPoint foundCol;
+ float foundColZ;
+
+ CWaterLevel::GetWaterLevelNoWaves(GetPosition().x, GetPosition().y, GetPosition().z, &waterLevel);
+
+ CVector potentialGround = GetPosition();
+ potentialGround.z = waterLevel;
+
+ if (!CWorld::TestSphereAgainstWorld(potentialGround, 5.0f, nil, true, false, false, false, false, false))
+ return false;
+
+ CVector potentialGroundDist = gaTempSphereColPoints[0].point - GetPosition();
+ potentialGroundDist.z = 0.0f;
+ potentialGroundDist.Normalise();
+
+ CVector posToCheck = 0.5f * potentialGroundDist + gaTempSphereColPoints[0].point;
+ posToCheck.z = 3.0f + waterLevel;
+
+ if (CWorld::ProcessVerticalLine(posToCheck, waterLevel - 1.0f, foundCol, foundEnt, true, true, false, true, false, false, nil)) {
+ foundColZ = foundCol.point.z;
+ if (foundColZ >= waterLevel) {
+ posToCheck.z = 0.8f + foundColZ;
+ SetPosition(posToCheck);
+ bIsStanding = true;
+ bWasStanding = true;
+ return true;
+ }
+ }
+
+ posToCheck = 5.0f * potentialGroundDist + GetPosition();
+ posToCheck.z = 3.0f + waterLevel;
+
+ if (!CWorld::ProcessVerticalLine(posToCheck, waterLevel - 1.0f, foundCol, foundEnt, true, true, false, true, false, false, nil))
+ return false;
+
+ foundColZ = foundCol.point.z;
+ if (foundColZ < waterLevel)
+ return false;
+
+ posToCheck.z = 0.8f + foundColZ;
+ SetPosition(posToCheck);
+ bIsStanding = true;
+ bWasStanding = true;
+ return true;
+}
+
+// --MIAMI: Done
+void
+CPed::CollideWithPed(CPed *collideWith)
+{
+ CAnimBlendAssociation *animAssoc;
+ AnimationId animToPlay;
+
+ bool weAreMissionChar = CharCreatedBy == MISSION_CHAR;
+ bool heIsMissionChar = collideWith->CharCreatedBy == MISSION_CHAR;
+ CVector posDiff = collideWith->GetPosition() - GetPosition();
+ 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;
+
+ if (m_nMoveState != PEDMOVE_NONE && m_nMoveState != PEDMOVE_STILL) {
+
+ if ((!IsPlayer() || ((CPlayerPed*)this)->m_fMoveSpeed <= 1.8f)
+ && (IsPlayer() || heIsMissionChar && weAreMissionChar || m_nMoveState != PEDMOVE_RUN && m_nMoveState != PEDMOVE_SPRINT
+ || m_objective == OBJECTIVE_FOLLOW_CHAR_IN_FORMATION && m_pedInObjective == collideWith
+ || 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) {
+
+ if (CTimer::GetTimeInMilliseconds() > m_nPedStateTimer) {
+
+ if (heIsMissionChar || !weAreMissionChar && collideWith->m_nMoveState != PEDMOVE_STILL) {
+
+ if (weAreMissionChar && (m_nPedState == PED_SEEK_POS || m_nPedState == PED_SEEK_ENTITY)) {
+
+ if (collideWith->m_nMoveState != PEDMOVE_STILL
+ && (!collideWith->IsPlayer() || collideWith->IsPlayer() && CPad::GetPad(0)->ArePlayerControlsDisabled())) {
+ float seekPosDist = (GetPosition() - m_vecSeekPos).MagnitudeSqr2D();
+ float heAndSeekPosDist = (collideWith->GetPosition() - m_vecSeekPos).MagnitudeSqr2D();
+
+ if (seekPosDist <= heAndSeekPosDist) {
+ waitTime = 1000;
+ collideWith->SetWaitState(WAITSTATE_CROSS_ROAD_LOOK, &waitTime);
+ collideWith->m_nPedStateTimer = CTimer::GetTimeInMilliseconds() + waitTime;
+ } else {
+ waitTime = 500;
+ SetWaitState(WAITSTATE_CROSS_ROAD_LOOK, &waitTime);
+ m_nPedStateTimer = CTimer::GetTimeInMilliseconds() + waitTime;
+ }
+ } else if (collideWith->m_nMoveState == PEDMOVE_STILL) {
+ SetDirectionToWalkAroundObject(collideWith);
+ }
+ } else {
+ 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 {
+ SetDirectionToWalkAroundObject(collideWith);
+ }
+ }
+ } else {
+ if (m_pedStats->m_temper <= m_pedStats->m_fear
+ || GetWeapon()->m_eWeaponType != WEAPONTYPE_UNARMED
+ || weAreMissionChar
+ || collideWith->m_nPedType == PEDTYPE_CIVFEMALE
+ || collideWith->m_nPedType == m_nPedType
+ || collideWith->GetWeapon()->m_eWeaponType != WEAPONTYPE_UNARMED) {
+ SetDirectionToWalkAroundObject(collideWith);
+ Say(SOUND_PED_CHAT);
+ } else {
+ TurnBody();
+ SetAttack(collideWith);
+ m_fRotationCur = 0.3f + m_fRotationCur;
+ m_fRotationDest = m_fRotationCur;
+ }
+ m_nPedStateTimer = CTimer::GetTimeInMilliseconds() + CGeneral::GetRandomNumberInRange(250, 450);
+ }
+ }
+ } else {
+ if (m_pedInObjective && (collideWith == m_pedInObjective || collideWith->m_pedInObjective == m_pedInObjective) && CTimer::GetTimeInMilliseconds() > m_nPedStateTimer) {
+ if (heLooksToUs) {
+ SetEvasiveStep(collideWith, 1);
+ m_nPedStateTimer = CTimer::GetTimeInMilliseconds() + 3000;
+ }
+ } else if (weDontLookToHim && IsPedInControl()) {
+
+ if (m_pedStats != collideWith->m_pedStats) {
+
+ 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
+ if (DotProduct(posDiff,GetRight()) <= 0.0f)
+ m_fRotationCur -= m_headingRate;
+ else
+ m_fRotationCur += m_headingRate;
+ } else {
+ // He's on our right side
+ if (DotProduct(posDiff, collideWith->GetRight()) <= 0.0f)
+ collideWith->m_fRotationCur -= collideWith->m_headingRate;
+ else
+ collideWith->m_fRotationCur += collideWith->m_headingRate;
+ }
+ } else {
+ SetLookFlag(collideWith, false);
+ TurnBody();
+ animAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_FIGHT_PPUNCH, 8.0f);
+ animAssoc->flags |= ASSOC_FADEOUTWHENDONE;
+ m_nPedStateTimer = CTimer::GetTimeInMilliseconds() + 2000;
+ if (!heIsMissionChar) {
+ CVector2D posDiff2D(posDiff);
+ int direction = collideWith->GetLocalDirection(posDiff2D);
+ collideWith->StartFightDefend(direction, HITLEVEL_HIGH, 5);
+ }
+ }
+ }
+ }
+ }
+ } 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();
+ moveForce.z += 0.1f;
+ ApplyMoveForce(moveForce);
+ if (collideWith->m_nMoveState != PEDMOVE_RUN && collideWith->m_nMoveState != PEDMOVE_SPRINT)
+ animToPlay = ANIM_HIT_LEFT;
+ else
+ animToPlay = ANIM_SHOT_LEFT_PARTIAL;
+ } else if (heLooksToUs) {
+ CVector moveForce = GetRight() * -1.0f;
+ moveForce.z += 0.1f;
+ ApplyMoveForce(moveForce);
+ if (collideWith->m_nMoveState != PEDMOVE_RUN && collideWith->m_nMoveState != PEDMOVE_SPRINT)
+ animToPlay = ANIM_HIT_RIGHT;
+ else
+ animToPlay = ANIM_SHOT_RIGHT_PARTIAL;
+ } else {
+ if (collideWith->m_nMoveState != PEDMOVE_RUN && collideWith->m_nMoveState != PEDMOVE_SPRINT)
+ animToPlay = ANIM_HIT_BACK;
+ else
+ animToPlay = ANIM_SHOT_BACK_PARTIAL;
+ }
+
+ if (collideWith->IsPedInControl() && CTimer::GetTimeInMilliseconds() > collideWith->m_nPedStateTimer) {
+ animAssoc = CAnimManager::BlendAnimation(collideWith->GetClump(), ASSOCGRP_STD, animToPlay, 8.0f);
+ animAssoc->flags |= ASSOC_FADEOUTWHENDONE;
+ collideWith->m_nPedStateTimer = CTimer::GetTimeInMilliseconds() + 1000;
+ if (m_nPedState == PED_ATTACK)
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_FIGHT_46, 0.0f);
+ }
+ } else {
+ // We're at his right side
+ if (DotProduct(posDiff, collideWith->GetRight()) <= 0.0f) {
+ CVector moveForce = GetRight() * -1.0f;
+ moveForce.z += 0.1f;
+ ApplyMoveForce(moveForce);
+ if (heLooksToUs)
+ animToPlay = ANIM_KO_SPIN_L;
+ else
+ animToPlay = ANIM_KD_RIGHT;
+ } else {
+ CVector moveForce = GetRight();
+ moveForce.z += 0.1f;
+ ApplyMoveForce(moveForce);
+ if (heLooksToUs)
+ animToPlay = ANIM_KO_SPIN_R;
+ else
+ animToPlay = ANIM_KD_LEFT;
+ }
+
+ if (m_nPedState == PED_ATTACK && collideWith->IsPedInControl())
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_49, 0.0f);
+
+ collideWith->SetFall(3000, animToPlay, 0);
+ }
+ } else {
+ if (!IsPedInControl())
+ return;
+
+ if (collideWith->m_nMoveState == PEDMOVE_NONE || collideWith->m_nMoveState == PEDMOVE_STILL)
+ return;
+
+ if (m_nPedType != collideWith->m_nPedType || m_nPedType == PEDTYPE_CIVMALE || m_nPedType == PEDTYPE_CIVFEMALE) {
+
+ if (!weAreMissionChar && heLooksToUs && m_pedStats->m_fear > 100 - collideWith->m_pedStats->m_temper) {
+
+ if (CGeneral::GetRandomNumber() & 1 && CTimer::GetTimeInMilliseconds() < m_nPedStateTimer){
+ SetEvasiveStep(collideWith, 2);
+ m_nPedStateTimer = CTimer::GetTimeInMilliseconds() + 3000;
+ } else if (collideWith->m_nMoveState > PEDMOVE_WALK) {
+ waitTime = 2000;
+ SetWaitState(WAITSTATE_PLAYANIM_DUCK, &waitTime);
+ }
+ }
+ } else if (heLooksToUs
+ && collideWith->m_nPedState != PED_STEP_AWAY
+ && m_nPedState != PED_STEP_AWAY
+ && CTimer::GetTimeInMilliseconds() > m_nPedStateTimer) {
+
+ SetEvasiveStep(collideWith, 1);
+ m_nPedStateTimer = CTimer::GetTimeInMilliseconds() + 3000;
+ }
+ }
+
+ if (IsPlayer()) {
+ SetLookFlag(collideWith, true);
+ SetLookTimer(800);
+ }
+ } else {
+ bool isRunning = m_nMoveState == PEDMOVE_RUN || m_nMoveState == PEDMOVE_SPRINT;
+ SetFindPathAndFlee(collideWith, 5000, !isRunning);
+ }
+}
+
+// --MIAMI: Done
+void
+CPed::KillPedWithCar(CVehicle *car, float impulse)
+{
+ CVehicleModelInfo *vehModel;
+ CColModel *vehColModel;
+ uint8 damageDir;
+ PedNode nodeToDamage;
+ eWeaponType killMethod;
+
+ if (m_nPedState == PED_FALL || m_nPedState == PED_DIE) {
+ if (!m_pCollidingEntity || car->GetStatus() == STATUS_PLAYER)
+ m_pCollidingEntity = car;
+ return;
+ }
+
+ if (m_nPedState == PED_DEAD)
+ return;
+
+ if (m_pCurSurface) {
+ if (m_pCurSurface->IsVehicle() && (((CVehicle*)m_pCurSurface)->IsBoat()|| IsPlayer()))
+ return;
+ }
+
+ CVector distVec = GetPosition() - car->GetPosition();
+
+ if ((impulse > 12.0f || car->GetModelIndex() == MI_TRAIN) && !IsPlayer()) {
+ nodeToDamage = PED_TORSO;
+ killMethod = WEAPONTYPE_RAMMEDBYCAR;
+ uint8 randVal = CGeneral::GetRandomNumber() & 3;
+
+ if (car == FindPlayerVehicle()) {
+ float carSpeed = car->m_vecMoveSpeed.Magnitude();
+ uint8 shakeFreq;
+ if (100.0f * carSpeed * 2000.0f / car->m_fMass + 80.0f <= 250.0f) {
+ shakeFreq = 100.0f * carSpeed * 2000.0f / car->m_fMass + 80.0f;
+ } else {
+ shakeFreq = 250.0f;
+ }
+ CPad::GetPad(0)->StartShake(40000 / shakeFreq, shakeFreq);
+ }
+ bIsStanding = false;
+ damageDir = GetLocalDirection(-m_vecMoveSpeed);
+ vehModel = (CVehicleModelInfo *)CModelInfo::GetModelInfo(car->GetModelIndex());
+ vehColModel = vehModel->GetColModel();
+ float carRightAndDistDotProd = DotProduct(distVec, car->GetRight());
+
+ if (car->GetModelIndex() == MI_TRAIN) {
+ killMethod = WEAPONTYPE_RUNOVERBYCAR;
+ nodeToDamage = PED_HEAD;
+ m_vecMoveSpeed = 0.9f * car->m_vecMoveSpeed;
+ m_vecMoveSpeed.z = 0.0f;
+ if (damageDir == 1 || damageDir == 3)
+ damageDir = 2;
+ if (CGame::nastyGame)
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_SPLATTER, 0.0f);
+
+ // Car doesn't look to us
+ } else if (DotProduct(car->m_vecMoveSpeed, car->GetForward()) >= 0.0f){
+
+ if (0.99f * vehColModel->boundingBox.max.x < Abs(carRightAndDistDotProd)) {
+
+ // We're at the right of the car
+ if (carRightAndDistDotProd <= 0.0f)
+ nodeToDamage = PED_UPPERARML;
+ else
+ nodeToDamage = PED_UPPERARMR;
+
+ if (Abs(DotProduct(distVec, car->GetForward())) < 0.85f * vehColModel->boundingBox.max.y) {
+ killMethod = WEAPONTYPE_RUNOVERBYCAR;
+ m_vecMoveSpeed = 0.9f * car->m_vecMoveSpeed;
+ m_vecMoveSpeed.z = 0.0f;
+ if (damageDir == 1 || damageDir == 3)
+ damageDir = 2;
+ if (CGame::nastyGame)
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_SPLATTER, 0.0f);
+
+ }
+ } else {
+ float carFrontAndDistDotProd = DotProduct(distVec, car->GetForward());
+
+ // carFrontAndDistDotProd <= 0.0 car looks to us
+ if ((carFrontAndDistDotProd <= 0.1 || randVal <= 1) && randVal != 0) {
+ killMethod = WEAPONTYPE_RUNOVERBYCAR;
+ nodeToDamage = PED_HEAD;
+ m_vecMoveSpeed = 0.9f * car->m_vecMoveSpeed;
+ m_vecMoveSpeed.z = 0.0f;
+ if (damageDir == 1 || damageDir == 3)
+ damageDir = 2;
+
+ if (CGame::nastyGame)
+ DMAudio.PlayOneShot(m_audioEntityId, SOUND_SPLATTER, 0.0f);
+
+ } else {
+ nodeToDamage = PED_MID;
+ float vehColMaxY = vehColModel->boundingBox.max.y;
+ float vehColMinY = vehColModel->boundingBox.min.y;
+ float vehColMaxZ = vehColModel->boundingBox.max.z;
+ float carFrontZ = car->GetForward().z;
+ float carHighestZ, carLength;
+
+ if (carFrontZ < -0.2f) {
+ // Highest point of car's back
+ carHighestZ = (car->GetMatrix() * CVector(0.0f, vehColMinY, vehColMaxZ)).z;
+ carLength = vehColMaxY - vehColMinY;
+
+ } else if (carFrontZ > 0.1f) {
+ // Highest point of car's front
+ carHighestZ = (car->GetMatrix() * CVector(0.0f, vehColMaxY, vehColMaxZ)).z;
+ float highestZDist = carHighestZ - GetPosition().z;
+ if (highestZDist > 0.0f) {
+ GetMatrix().GetPosition().z += 0.5f * highestZDist;
+ carHighestZ += highestZDist * 0.25f;
+ }
+ carLength = vehColMaxY;
+
+ } else {
+ // Highest point of car's front
+ carHighestZ = (car->GetMatrix() * CVector(0.0f, vehColMaxY, vehColMaxZ)).z;
+ carLength = vehColMaxY;
+ }
+
+ float pedJumpSpeedToReachHighestZ = (carHighestZ - GetPosition().z) / (carLength / car->m_vecMoveSpeed.Magnitude());
+
+ // TODO: What are we doing down here?
+ float unknown = ((CGeneral::GetRandomNumber() % 256) * 0.002 + 1.5) * pedJumpSpeedToReachHighestZ;
+
+ // After this point distVec isn't really distVec.
+ distVec = car->m_vecMoveSpeed;
+ distVec.Normalise();
+ distVec *= 0.2 * unknown;
+
+ if (damageDir != 1 && damageDir != 3)
+ distVec.z += unknown;
+ else
+ distVec.z += 1.5f * unknown;
+
+ m_vecMoveSpeed = distVec;
+ damageDir += 2;
+ if (damageDir > 3)
+ damageDir = damageDir - 4;
+
+ if (car->IsCar()) {
+ CObject *bonnet = ((CAutomobile*)car)->RemoveBonnetInPedCollision();
+
+ if (bonnet) {
+ if (CGeneral::GetRandomNumber() & 1) {
+ bonnet->m_vecMoveSpeed += Multiply3x3(car->GetMatrix(), CVector(0.1f, 0.0f, 0.5f));
+ } else {
+ bonnet->m_vecMoveSpeed += Multiply3x3(car->GetMatrix(), CVector(-0.1f, 0.0f, 0.5f));
+ }
+ CVector forceDir = car->GetUp() * 10.0f;
+ bonnet->ApplyTurnForce(forceDir, car->GetForward());
+ }
+ }
+ }
+ }
+ }
+
+ if (car->pDriver) {
+ CEventList::RegisterEvent((m_nPedType == PEDTYPE_COP ? EVENT_HIT_AND_RUN_COP : EVENT_HIT_AND_RUN), EVENT_ENTITY_PED, this, car->pDriver, 1000);
+ }
+
+ ePedPieceTypes pieceToDamage;
+ switch (nodeToDamage) {
+ case PED_HEAD:
+ pieceToDamage = PEDPIECE_HEAD;
+ break;
+ case PED_UPPERARML:
+ pieceToDamage = PEDPIECE_LEFTARM;
+ break;
+ case PED_UPPERARMR:
+ pieceToDamage = PEDPIECE_RIGHTARM;
+ break;
+ default:
+ pieceToDamage = PEDPIECE_MID;
+ break;
+ }
+ InflictDamage(car, killMethod, 1000.0f, pieceToDamage, damageDir);
+
+ if (DyingOrDead()
+ && bIsPedDieAnimPlaying && !m_pCollidingEntity) {
+ m_pCollidingEntity = car;
+ }
+ if (nodeToDamage == PED_MID)
+ bKnockedUpIntoAir = true;
+ else
+ bKnockedUpIntoAir = false;
+
+ distVec.Normalise();
+
+ distVec *= Min(car->m_fMass / 1400.0f, 1.0f);
+ car->ApplyMoveForce(distVec * -100.0f);
+ Say(SOUND_PED_DEFEND);
+
+ } else if (m_vecDamageNormal.z < -0.8f && impulse > 3.0f
+ || impulse > 6.0f && (!IsPlayer() || impulse > 10.0f)) {
+
+ bIsStanding = false;
+ uint8 fallDirection = GetLocalDirection(-car->m_vecMoveSpeed);
+ float damage;
+ if (IsPlayer() && car->GetModelIndex() == MI_TRAIN)
+ damage = 150.0f;
+ else
+ damage = 30.0f;
+
+ InflictDamage(car, WEAPONTYPE_RAMMEDBYCAR, damage, PEDPIECE_TORSO, fallDirection);
+ SetFall(1000, (AnimationId)(fallDirection + ANIM_KO_SKID_FRONT), true);
+
+ if (OnGround() && !m_pCollidingEntity &&
+ (!IsPlayer() || bHasHitWall || car->GetModelIndex() == MI_TRAIN || m_vecDamageNormal.z < -0.8f)) {
+
+ m_pCollidingEntity = car;
+ }
+
+ bKnockedUpIntoAir = false;
+ if (car->GetModelIndex() != MI_TRAIN && !bHasHitWall) {
+ m_vecMoveSpeed = car->m_vecMoveSpeed * 0.75f;
+ }
+ m_vecMoveSpeed.z = 0.0f;
+ distVec.Normalise();
+ distVec *= Min(car->m_fMass / 1400.0f, 1.0f);
+ car->ApplyMoveForce(distVec * -60.0f);
+ Say(SOUND_PED_DEFEND);
+ }
+
+ if (IsGangMember()) {
+ CPed *driver = car->pDriver;
+ if (driver && driver->IsPlayer()
+#ifdef FIX_BUGS
+ && (CharCreatedBy != MISSION_CHAR || bRespondsToThreats) && (!m_leader || m_leader != driver)
+#endif
+ ) {
+ RegisterThreatWithGangPeds(driver);
+ }
+ }
+}
+
+// --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.h b/src/peds/PedIK.h
index 7dcf0ef3..ee719fea 100644
--- a/src/peds/PedIK.h
+++ b/src/peds/PedIK.h
@@ -52,7 +52,6 @@ public:
bool PointGunInDirectionUsingArm(float targetYaw, float targetPitch);
bool PointGunAtPosition(CVector const& position);
void GetComponentPosition(RwV3d &pos, uint32 node);
- void GetComponentPosition(CVector &pos, uint32 node) { GetComponentPosition(*(RwV3d*)pos, node); }
void RotateTorso(AnimBlendFrameData* animBlend, LimbOrientation* limb, bool changeRoll);
void ExtractYawAndPitchLocal(RwMatrix *mat, float *yaw, float *pitch);
void ExtractYawAndPitchLocalSkinned(AnimBlendFrameData *node, float *yaw, float *pitch);
diff --git a/src/peds/PedStats.cpp b/src/peds/PedStats.cpp
deleted file mode 100644
index fe594bdf..00000000
--- a/src/peds/PedStats.cpp
+++ /dev/null
@@ -1,120 +0,0 @@
-#include "common.h"
-
-#include "General.h"
-#include "FileMgr.h"
-#include "PedStats.h"
-
-// --MIAMI: file done
-
-CPedStats *CPedStats::ms_apPedStats[NUM_PEDSTATS];
-
-void
-CPedStats::Initialise(void)
-{
- int i;
-
- debug("Initialising CPedStats...\n");
- for(i = 0; i < NUM_PEDSTATS; i++){
- ms_apPedStats[i] = new CPedStats;
- ms_apPedStats[i]->m_type = PEDSTAT_PLAYER;
- ms_apPedStats[i]->m_name[8] = 'R'; // WHAT?
- ms_apPedStats[i]->m_fleeDistance = 20.0f;
- ms_apPedStats[i]->m_headingChangeRate = 15.0f;
- ms_apPedStats[i]->m_fear = 50;
- ms_apPedStats[i]->m_temper = 50;
- ms_apPedStats[i]->m_lawfulness = 50;
- ms_apPedStats[i]->m_sexiness = 50;
- ms_apPedStats[i]->m_attackStrength = 1.0f;
- ms_apPedStats[i]->m_defendWeakness = 1.0f;
- ms_apPedStats[i]->m_flags = 0;
- }
- debug("Loading pedstats data...\n");
- CPedStats::LoadPedStats();
- debug("CPedStats ready\n");
-}
-
-void
-CPedStats::Shutdown(void)
-{
- int i;
- debug("Shutting down CPedStats...\n");
- for(i = 0; i < NUM_PEDSTATS; i++)
- delete ms_apPedStats[i];
- debug("CPedStats shut down\n");
-}
-
-void
-CPedStats::LoadPedStats(void)
-{
- char *buf;
- char line[256];
- char name[32];
- size_t bp, buflen;
- int lp, linelen;
- int type;
- float fleeDist, headingChangeRate, attackStrength, defendWeakness;
- int fear, temper, lawfullness, sexiness, flags;
-
-
- type = 0;
- buf = new char[16 * 1024];
-
- CFileMgr::SetDir("DATA");
- buflen = CFileMgr::LoadFile("PEDSTATS.DAT", (uint8*)buf, 16 * 1024, "r");
- CFileMgr::SetDir("");
-
- for(bp = 0; bp < buflen; ){
- // read file line by line
- for(linelen = 0; buf[bp] != '\n' && bp < buflen; bp++){
- if(buf[bp] == '\r' || buf[bp] == ',' || buf[bp] == '\t')
- line[linelen++] = ' ';
- else
- line[linelen++] = buf[bp];
- }
- bp++;
- line[linelen] = '\0';
-
- // skip white space
- for(lp = 0; line[lp] <= ' '; lp++);
-
- if(lp >= linelen || // FIX: game uses == here, but this is safer if we have empty lines
- line[lp] == '#')
- continue;
-
- sscanf(&line[lp], "%s %f %f %d %d %d %d %f %f %d",
- name,
- &fleeDist,
- &headingChangeRate,
- &fear,
- &temper,
- &lawfullness,
- &sexiness,
- &attackStrength,
- &defendWeakness,
- &flags);
- ms_apPedStats[type]->m_type = (ePedStats)type;
- strncpy(ms_apPedStats[type]->m_name, name, 24); // FIX: game uses strcpy
- ms_apPedStats[type]->m_fleeDistance = fleeDist;
- ms_apPedStats[type]->m_headingChangeRate = headingChangeRate;
- ms_apPedStats[type]->m_fear = fear;
- ms_apPedStats[type]->m_temper = temper;
- ms_apPedStats[type]->m_lawfulness = lawfullness;
- ms_apPedStats[type]->m_sexiness = sexiness;
- ms_apPedStats[type]->m_attackStrength = attackStrength;
- ms_apPedStats[type]->m_defendWeakness = defendWeakness;
- ms_apPedStats[type]->m_flags = flags;
- type++;
- }
-
- delete[] buf;
-}
-
-ePedStats
-CPedStats::GetPedStatType(char *name)
-{
- for(uint16 type = 0; type < NUM_PEDSTATS; type++)
- if(!CGeneral::faststrcmp(ms_apPedStats[type]->m_name, name))
- return (ePedStats) type;
-
- return NUM_PEDSTATS;
-}
diff --git a/src/peds/PedStats.h b/src/peds/PedStats.h
deleted file mode 100644
index 7fc8cdbf..00000000
--- a/src/peds/PedStats.h
+++ /dev/null
@@ -1,85 +0,0 @@
-#pragma once
-
-enum ePedStats
-{
- PEDSTAT_PLAYER,
- PEDSTAT_COP,
- PEDSTAT_MEDIC,
- PEDSTAT_FIREMAN,
- PEDSTAT_GANG1,
- PEDSTAT_GANG2,
- PEDSTAT_GANG3,
- PEDSTAT_GANG4,
- PEDSTAT_GANG5,
- PEDSTAT_GANG6,
- PEDSTAT_GANG7,
- PEDSTAT_STREET_GUY,
- PEDSTAT_SUIT_GUY,
- PEDSTAT_SENSIBLE_GUY,
- PEDSTAT_GEEK_GUY,
- PEDSTAT_OLD_GUY,
- PEDSTAT_TOUGH_GUY,
- PEDSTAT_STREET_GIRL,
- PEDSTAT_SUIT_GIRL,
- PEDSTAT_SENSIBLE_GIRL,
- PEDSTAT_GEEK_GIRL,
- PEDSTAT_OLD_GIRL,
- PEDSTAT_TOUGH_GIRL,
- PEDSTAT_TRAMP_MALE,
- PEDSTAT_TRAMP_FEMALE,
- PEDSTAT_TOURIST,
- PEDSTAT_PROSTITUTE,
- PEDSTAT_CRIMINAL,
- PEDSTAT_BUSKER,
- PEDSTAT_TAXIDRIVER,
- PEDSTAT_PSYCHO,
- PEDSTAT_STEWARD,
- PEDSTAT_SPORTSFAN,
- PEDSTAT_SHOPPER,
- PEDSTAT_OLDSHOPPER,
- PEDSTAT_BEACH_GUY,
- PEDSTAT_BEACH_GIRL,
- PEDSTAT_SKATER,
- PEDSTAT_STD_MISSION,
- PEDSTAT_COWARD,
-
- NUM_PEDSTATS
-};
-
-// flags
-enum
-{
- STAT_PUNCH_ONLY = 1,
- STAT_CAN_KNEE_HEAD = 2,
- STAT_CAN_KICK = 4,
- STAT_CAN_ROUNDHOUSE = 8,
- STAT_NO_DIVE = 0x10,
- STAT_ONE_HIT_KNOCKDOWN = 0x20,
- STAT_SHOPPING_BAGS = 0x40,
- STAT_GUN_PANIC = 0x80
-};
-
-class CPedStats
-{
-public:
- ePedStats m_type;
- char m_name[24];
- float m_fleeDistance;
- float m_headingChangeRate;
- int8 m_fear;
- int8 m_temper;
- int8 m_lawfulness;
- int8 m_sexiness;
- float m_attackStrength;
- float m_defendWeakness;
- int16 m_flags;
-
- static CPedStats *ms_apPedStats[NUM_PEDSTATS];
-
- static void Initialise(void);
- static void Shutdown(void);
- static void LoadPedStats(void);
- static ePedStats GetPedStatType(char *name);
-};
-
-VALIDATE_SIZE(CPedStats, 0x34);
diff --git a/src/peds/PedType.cpp b/src/peds/PedType.cpp
index 8a631e7a..5565b90f 100644
--- a/src/peds/PedType.cpp
+++ b/src/peds/PedType.cpp
@@ -1,11 +1,13 @@
#include "common.h"
+#include "General.h"
#include "FileMgr.h"
#include "PedType.h"
// --MIAMI: file done
CPedType *CPedType::ms_apPedType[NUM_PEDTYPES];
+CPedStats *CPedStats::ms_apPedStats[NUM_PEDSTATS];
void
CPedType::Initialise(void)
@@ -45,7 +47,7 @@ CPedType::LoadPedData(void)
char *buf;
char line[256];
char word[32];
- size_t bp, buflen;
+ ssize_t bp, buflen;
int lp, linelen;
int type;
uint32 flags;
@@ -54,9 +56,9 @@ CPedType::LoadPedData(void)
type = NUM_PEDTYPES;
buf = new char[16 * 1024];
- CFileMgr::SetDir("DATA");
- buflen = CFileMgr::LoadFile("PED.DAT", (uint8*)buf, 16 * 1024, "r");
- CFileMgr::SetDir("");
+ CFileMgr::SetDir("DATA");
+ buflen = CFileMgr::LoadFile("PED.DAT", (uint8*)buf, 16 * 1024, "r");
+ CFileMgr::SetDir("");
for(bp = 0; bp < buflen; ){
// read file line by line
@@ -79,7 +81,7 @@ CPedType::LoadPedData(void)
// Game uses just "line" here since sscanf already trims whitespace, but this is safer
sscanf(&line[lp], "%s", word);
- if(strncmp(word, "Threat", 7) == 0){
+ if(strcmp(word, "Threat") == 0){
flags = 0;
lp += 7;
while(sscanf(&line[lp], "%s", word) == 1 && lp <= linelen){
@@ -92,7 +94,7 @@ CPedType::LoadPedData(void)
lp++;
}
ms_apPedType[type]->m_threats = flags;
- }else if(strncmp(word, "Avoid", 6) == 0){
+ }else if(strcmp(word, "Avoid") == 0){
flags = 0;
lp += 6;
while(sscanf(&line[lp], "%s", word) == 1 && lp <= linelen){
@@ -204,3 +206,114 @@ INITSAVEBUF
*ms_apPedType[i] = ReadSaveBuf<CPedType>(buf);
VALIDATESAVEBUF(size)
}
+
+void
+CPedStats::Initialise(void)
+{
+ int i;
+
+ debug("Initialising CPedStats...\n");
+ for(i = 0; i < NUM_PEDSTATS; i++){
+ ms_apPedStats[i] = new CPedStats;
+ ms_apPedStats[i]->m_type = PEDSTAT_PLAYER;
+ ms_apPedStats[i]->m_name[8] = 'R'; // WHAT?
+ ms_apPedStats[i]->m_fleeDistance = 20.0f;
+ ms_apPedStats[i]->m_headingChangeRate = 15.0f;
+ ms_apPedStats[i]->m_fear = 50;
+ ms_apPedStats[i]->m_temper = 50;
+ ms_apPedStats[i]->m_lawfulness = 50;
+ ms_apPedStats[i]->m_sexiness = 50;
+ ms_apPedStats[i]->m_attackStrength = 1.0f;
+ ms_apPedStats[i]->m_defendWeakness = 1.0f;
+ ms_apPedStats[i]->m_flags = 0;
+ }
+ debug("Loading pedstats data...\n");
+ CPedStats::LoadPedStats();
+ debug("CPedStats ready\n");
+}
+
+void
+CPedStats::Shutdown(void)
+{
+ int i;
+ debug("Shutting down CPedStats...\n");
+ for(i = 0; i < NUM_PEDSTATS; i++)
+ delete ms_apPedStats[i];
+ debug("CPedStats shut down\n");
+}
+
+void
+CPedStats::LoadPedStats(void)
+{
+ char *buf;
+ char line[256];
+ char name[32];
+ ssize_t bp, buflen;
+ int lp, linelen;
+ int type;
+ float fleeDist, headingChangeRate, attackStrength, defendWeakness;
+ int fear, temper, lawfullness, sexiness, flags;
+
+
+ type = 0;
+ buf = new char[16 * 1024];
+
+ CFileMgr::SetDir("DATA");
+ buflen = CFileMgr::LoadFile("PEDSTATS.DAT", (uint8*)buf, 16 * 1024, "r");
+ CFileMgr::SetDir("");
+
+ for(bp = 0; bp < buflen; ){
+ // read file line by line
+ for(linelen = 0; buf[bp] != '\n' && bp < buflen; bp++){
+ if(buf[bp] == '\r' || buf[bp] == ',' || buf[bp] == '\t')
+ line[linelen++] = ' ';
+ else
+ line[linelen++] = buf[bp];
+ }
+ bp++;
+ line[linelen] = '\0';
+
+ // skip white space
+ for(lp = 0; line[lp] <= ' '; lp++);
+
+ if(lp >= linelen || // FIX: game uses == here, but this is safer if we have empty lines
+ line[lp] == '#')
+ continue;
+
+ sscanf(&line[lp], "%s %f %f %d %d %d %d %f %f %d",
+ name,
+ &fleeDist,
+ &headingChangeRate,
+ &fear,
+ &temper,
+ &lawfullness,
+ &sexiness,
+ &attackStrength,
+ &defendWeakness,
+ &flags);
+ ms_apPedStats[type]->m_type = (ePedStats)type;
+ strncpy(ms_apPedStats[type]->m_name, name, 24); // FIX: game uses strcpy
+ ms_apPedStats[type]->m_fleeDistance = fleeDist;
+ ms_apPedStats[type]->m_headingChangeRate = headingChangeRate;
+ ms_apPedStats[type]->m_fear = fear;
+ ms_apPedStats[type]->m_temper = temper;
+ ms_apPedStats[type]->m_lawfulness = lawfullness;
+ ms_apPedStats[type]->m_sexiness = sexiness;
+ ms_apPedStats[type]->m_attackStrength = attackStrength;
+ ms_apPedStats[type]->m_defendWeakness = defendWeakness;
+ ms_apPedStats[type]->m_flags = flags;
+ type++;
+ }
+
+ delete[] buf;
+}
+
+ePedStats
+CPedStats::GetPedStatType(char *name)
+{
+ for(uint16 type = 0; type < NUM_PEDSTATS; type++)
+ if(!CGeneral::faststrcmp(ms_apPedStats[type]->m_name, name))
+ return (ePedStats) type;
+
+ return NUM_PEDSTATS;
+}
diff --git a/src/peds/PedType.h b/src/peds/PedType.h
index e2eafb4f..a4698bbb 100644
--- a/src/peds/PedType.h
+++ b/src/peds/PedType.h
@@ -92,3 +92,87 @@ public:
};
VALIDATE_SIZE(CPedType, 0x20);
+
+enum ePedStats
+{
+ PEDSTAT_PLAYER,
+ PEDSTAT_COP,
+ PEDSTAT_MEDIC,
+ PEDSTAT_FIREMAN,
+ PEDSTAT_GANG1,
+ PEDSTAT_GANG2,
+ PEDSTAT_GANG3,
+ PEDSTAT_GANG4,
+ PEDSTAT_GANG5,
+ PEDSTAT_GANG6,
+ PEDSTAT_GANG7,
+ PEDSTAT_STREET_GUY,
+ PEDSTAT_SUIT_GUY,
+ PEDSTAT_SENSIBLE_GUY,
+ PEDSTAT_GEEK_GUY,
+ PEDSTAT_OLD_GUY,
+ PEDSTAT_TOUGH_GUY,
+ PEDSTAT_STREET_GIRL,
+ PEDSTAT_SUIT_GIRL,
+ PEDSTAT_SENSIBLE_GIRL,
+ PEDSTAT_GEEK_GIRL,
+ PEDSTAT_OLD_GIRL,
+ PEDSTAT_TOUGH_GIRL,
+ PEDSTAT_TRAMP_MALE,
+ PEDSTAT_TRAMP_FEMALE,
+ PEDSTAT_TOURIST,
+ PEDSTAT_PROSTITUTE,
+ PEDSTAT_CRIMINAL,
+ PEDSTAT_BUSKER,
+ PEDSTAT_TAXIDRIVER,
+ PEDSTAT_PSYCHO,
+ PEDSTAT_STEWARD,
+ PEDSTAT_SPORTSFAN,
+ PEDSTAT_SHOPPER,
+ PEDSTAT_OLDSHOPPER,
+ PEDSTAT_BEACH_GUY,
+ PEDSTAT_BEACH_GIRL,
+ PEDSTAT_SKATER,
+ PEDSTAT_STD_MISSION,
+ PEDSTAT_COWARD,
+
+ NUM_PEDSTATS
+};
+
+// flags
+enum
+{
+ STAT_PUNCH_ONLY = 1,
+ STAT_CAN_KNEE_HEAD = 2,
+ STAT_CAN_KICK = 4,
+ STAT_CAN_ROUNDHOUSE = 8,
+ STAT_NO_DIVE = 0x10,
+ STAT_ONE_HIT_KNOCKDOWN = 0x20,
+ STAT_SHOPPING_BAGS = 0x40,
+ STAT_GUN_PANIC = 0x80
+};
+
+class CPedStats
+{
+public:
+ ePedStats m_type;
+ char m_name[24];
+ float m_fleeDistance;
+ float m_headingChangeRate;
+ int8 m_fear;
+ int8 m_temper;
+ int8 m_lawfulness;
+ int8 m_sexiness;
+ float m_attackStrength;
+ float m_defendWeakness;
+ int16 m_flags;
+
+ static CPedStats *ms_apPedStats[NUM_PEDSTATS];
+
+ static void Initialise(void);
+ static void Shutdown(void);
+ static void LoadPedStats(void);
+ static ePedStats GetPedStatType(char *name);
+};
+
+VALIDATE_SIZE(CPedStats, 0x34);
diff --git a/src/peds/PlayerPed.cpp b/src/peds/PlayerPed.cpp
index 76599777..8220b370 100644
--- a/src/peds/PlayerPed.cpp
+++ b/src/peds/PlayerPed.cpp
@@ -18,9 +18,15 @@
#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
1752;
@@ -30,6 +36,12 @@ const uint32 CPlayerPed::nSaveStructSize =
int32 idleAnimBlockIndex;
+CPad*
+GetPadFromPlayer(CPlayerPed*)
+{
+ return CPad::GetPad(0);
+}
+
CPlayerPed::~CPlayerPed()
{
delete m_pWanted;
@@ -52,10 +64,7 @@ CPlayerPed::CPlayerPed(void) : CPed(PEDTYPE_PLAYER1)
m_nSelectedWepSlot = 0;
m_nSpeedTimer = 0;
m_bSpeedTimerFlag = false;
-
- if (m_pPointGunAt)
- m_pPointGunAt->CleanUpOldReference(&m_pPointGunAt);
- m_pPointGunAt = nil;
+ SetWeaponLockOnTarget(nil);
SetPedState(PED_IDLE);
#ifndef FIX_BUGS
m_fCurrentStamina = m_fMaxStamina = 150.0f;
@@ -68,7 +77,7 @@ CPlayerPed::CPlayerPed(void) : CPed(PEDTYPE_PLAYER1)
m_bHaveTargetSelected = false;
m_bHasLockOnTarget = false;
m_bCanBeDamaged = true;
- m_bDrunkVisualsWearOff = false;
+ m_bNoPosForMeleeAttack = false;
m_fWalkAngle = 0.0f;
m_fFPSMoveHeading = 0.0f;
m_pMinigunTopAtomic = nil;
@@ -76,13 +85,13 @@ CPlayerPed::CPlayerPed(void) : CPed(PEDTYPE_PLAYER1)
m_fGunSpinAngle = 0.0;
m_nPadDownPressedInMilliseconds = 0;
m_nTargettableObjects[0] = m_nTargettableObjects[1] = m_nTargettableObjects[2] = m_nTargettableObjects[3] = -1;
- unused1 = false;
+ 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_nCheckPlayersIndex = 0;
+ m_nAttackDirToCheck = 0;
m_nLastBusFareCollected = 0;
idleAnimBlockIndex = CAnimManager::GetAnimationBlockIndex("playidles");
}
@@ -92,28 +101,28 @@ void
CPlayerPed::ClearWeaponTarget()
{
if (m_nPedType == PEDTYPE_PLAYER1) {
- if (m_pPointGunAt)
- m_pPointGunAt->CleanUpOldReference(&m_pPointGunAt);
-
- m_pPointGunAt = nil;
+ SetWeaponLockOnTarget(nil);
TheCamera.ClearPlayerWeaponMode();
CWeaponEffects::ClearCrossHair();
}
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)
{
@@ -125,23 +134,21 @@ CPlayerPed::MakeObjectTargettable(int32 handle)
}
}
+// --MIAMI: Done
// I don't know the actual purpose of parameter
void
CPlayerPed::AnnoyPlayerPed(bool annoyedByPassingEntity)
{
if (m_pedStats->m_temper < 52) {
m_pedStats->m_temper++;
- } else {
- if (annoyedByPassingEntity) {
- if (m_pedStats->m_temper < 55) {
- m_pedStats->m_temper++;
- } else {
- m_pedStats->m_temper = 46;
- }
- }
+ } else if (annoyedByPassingEntity && m_pedStats->m_temper < 55) {
+ m_pedStats->m_temper++;
+ } else if (annoyedByPassingEntity) {
+ m_pedStats->m_temper = 46;
}
}
+// --MIAMI: Done
void
CPlayerPed::ClearAdrenaline(void)
{
@@ -151,6 +158,7 @@ CPlayerPed::ClearAdrenaline(void)
}
}
+// --MIAMI: Done
CPlayerInfo *
CPlayerPed::GetPlayerInfoForThisPlayerPed()
{
@@ -160,6 +168,7 @@ CPlayerPed::GetPlayerInfoForThisPlayerPed()
return nil;
}
+// --MIAMI: Done
void
CPlayerPed::SetupPlayerPed(int32 index)
{
@@ -175,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)
{
@@ -203,7 +215,7 @@ CPlayerPed::UseSprintEnergy(void)
}
}
-// --MIAMI: Use that on everywhere except ProcessPlayerWeapon
+// --MIAMI: Done
void
CPlayerPed::MakeChangesForNewWeapon(eWeaponType weapon)
{
@@ -216,7 +228,7 @@ CPlayerPed::MakeChangesForNewWeapon(eWeaponType weapon)
GetWeapon()->m_nAmmoInClip = Min(GetWeapon()->m_nAmmoTotal, CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_nAmountofAmmunition);
- if (!(CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bCanAim))
+ if (CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->IsFlagSet(WEAPONFLAG_CANAIM))
ClearWeaponTarget();
// WEAPONTYPE_SNIPERRIFLE? Wut?
@@ -228,7 +240,7 @@ CPlayerPed::MakeChangesForNewWeapon(eWeaponType weapon)
TheCamera.ClearPlayerWeaponMode();
}
-// --MIAMI: Done, but this should be only called from ProcessPlayerWeapon
+// --MIAMI: Done
void
CPlayerPed::MakeChangesForNewWeapon(int32 slot)
{
@@ -236,6 +248,7 @@ CPlayerPed::MakeChangesForNewWeapon(int32 slot)
MakeChangesForNewWeapon(m_weapons[slot].m_eWeaponType);
}
+// --MIAMI: Done
void
CPlayerPed::ReApplyMoveAnims(void)
{
@@ -244,7 +257,7 @@ CPlayerPed::ReApplyMoveAnims(void)
for(int i = 0; i < ARRAY_SIZE(moveAnims); i++) {
CAnimBlendAssociation *curMoveAssoc = RpAnimBlendClumpGetAssociation(GetClump(), moveAnims[i]);
if (curMoveAssoc) {
- if (strcmp(CAnimManager::GetAnimAssociation(m_animGroup, moveAnims[i])->hierarchy->name, curMoveAssoc->hierarchy->name) != 0) {
+ if (CGeneral::faststrcmp(CAnimManager::GetAnimAssociation(m_animGroup, moveAnims[i])->hierarchy->name, curMoveAssoc->hierarchy->name)) {
CAnimBlendAssociation *newMoveAssoc = CAnimManager::AddAnimation(GetClump(), m_animGroup, moveAnims[i]);
newMoveAssoc->blendDelta = curMoveAssoc->blendDelta;
newMoveAssoc->blendAmount = curMoveAssoc->blendAmount;
@@ -278,7 +291,6 @@ CPlayerPed::SetInitialState(void)
ClearLookFlag();
bIsPointingGunAt = false;
bRenderPedInCar = true;
-
if (m_pFire)
m_pFire->Extinguish();
@@ -303,6 +315,7 @@ CPlayerPed::SetInitialState(void)
m_attachWepAmmo = 0;
}
+// --MIAMI: Done
void
CPlayerPed::SetRealMoveAnim(void)
{
@@ -328,9 +341,9 @@ CPlayerPed::SetRealMoveAnim(void)
if (!curIdleAssoc)
curIdleAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_FIGHT_IDLE);
if (!curIdleAssoc)
- curIdleAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_CROUCHRELOAD);
+ curIdleAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_MELEE_IDLE_FIGHTMODE);
- if ((!curRunStopAssoc || !(curRunStopAssoc->IsRunning())) && (!curRunStopRAssoc || !(curRunStopRAssoc->IsRunning()))) {
+ if (!((curRunStopAssoc && curRunStopAssoc->IsRunning()) || (curRunStopRAssoc && curRunStopRAssoc->IsRunning()))) {
if (curRunStopAssoc && curRunStopAssoc->blendDelta >= 0.0f || curRunStopRAssoc && curRunStopRAssoc->blendDelta >= 0.0f) {
if (curRunStopAssoc) {
@@ -345,7 +358,7 @@ CPlayerPed::SetRealMoveAnim(void)
RestoreHeadingRate();
if (!curIdleAssoc) {
- if (m_fCurrentStamina < 0.0f && !bIsAimingGun && !CWorld::TestSphereAgainstWorld(GetPosition(), 0.0f,
+ if (m_fCurrentStamina < 0.0f && !bIsAimingGun && !CWorld::TestSphereAgainstWorld(GetPosition(), 0.5f,
nil, true, false, false, false, false, false)) {
curIdleAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_IDLE_TIRED, 8.0f);
@@ -359,7 +372,7 @@ CPlayerPed::SetRealMoveAnim(void)
} else if (m_fMoveSpeed == 0.0f && !curSprintAssoc) {
if (!curIdleAssoc) {
- if (m_fCurrentStamina < 0.0f && !bIsAimingGun && !CWorld::TestSphereAgainstWorld(GetPosition(), 0.0f,
+ if (m_fCurrentStamina < 0.0f && !bIsAimingGun && !CWorld::TestSphereAgainstWorld(GetPosition(), 0.5f,
nil, true, false, false, false, false, false)) {
curIdleAssoc = CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_IDLE_TIRED, 4.0f);
@@ -375,15 +388,15 @@ CPlayerPed::SetRealMoveAnim(void)
} else if (m_nPedState != PED_FIGHT) {
if (m_fCurrentStamina < 0.0f && !bIsAimingGun && curIdleAssoc->animId != ANIM_IDLE_TIRED
- && !CWorld::TestSphereAgainstWorld(GetPosition(), 0.0f, nil, true, false, false, false, false, false)) {
+ && !CWorld::TestSphereAgainstWorld(GetPosition(), 0.5f, nil, true, false, false, false, false, false)) {
CAnimManager::BlendAnimation(GetClump(), ASSOCGRP_STD, ANIM_IDLE_TIRED, 4.0f);
} else if (curIdleAssoc->animId != ANIM_IDLE_STANCE) {
CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_IDLE_STANCE, 4.0f);
}
}
-
m_nMoveState = PEDMOVE_STILL;
+
} else {
if (curIdleAssoc) {
if (curWalkStartAssoc) {
@@ -401,7 +414,7 @@ CPlayerPed::SetRealMoveAnim(void)
delete RpAnimBlendClumpGetAssociation(GetClump(), ANIM_IDLE_TIRED);
CAnimBlendAssociation *fightIdleAnim = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_FIGHT_IDLE);
if (!fightIdleAnim)
- fightIdleAnim = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_WEAPON_CROUCHRELOAD);
+ fightIdleAnim = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_MELEE_IDLE_FIGHTMODE);
delete fightIdleAnim;
delete curSprintAssoc;
@@ -439,6 +452,7 @@ CPlayerPed::SetRealMoveAnim(void)
}
if (curSprintAssoc && (m_nMoveState != PEDMOVE_SPRINT || m_fMoveSpeed < 0.4f)) {
+ // Stop sprinting in various conditions
if (curSprintAssoc->blendAmount == 0.0f) {
curSprintAssoc->blendDelta = -1000.0f;
curSprintAssoc->flags |= ASSOC_DELETEFADEDOUT;
@@ -462,8 +476,8 @@ CPlayerPed::SetRealMoveAnim(void)
curRunAssoc->flags &= ~ASSOC_RUNNING;
curRunAssoc->blendAmount = 0.0f;
curRunAssoc->blendDelta = 0.0f;
- } else if (curSprintAssoc->blendDelta >= 0.0f) {
+ } else if (curSprintAssoc->blendDelta >= 0.0f) { // this condition is absent on mobile
// Stop sprinting when tired
curSprintAssoc->flags |= ASSOC_DELETEFADEDOUT;
curSprintAssoc->blendDelta = -1.0f;
@@ -473,7 +487,9 @@ CPlayerPed::SetRealMoveAnim(void)
curSprintAssoc->blendDelta = -8.0f;
curRunAssoc->blendDelta = 8.0f;
}
+
} else if (curWalkStartAssoc) {
+ // Walk start and walk/run shouldn't run at the same time
curWalkAssoc->flags &= ~ASSOC_RUNNING;
curRunAssoc->flags &= ~ASSOC_RUNNING;
curWalkAssoc->blendAmount = 0.0f;
@@ -481,11 +497,13 @@ CPlayerPed::SetRealMoveAnim(void)
} else if (m_nMoveState == PEDMOVE_SPRINT) {
if (curSprintAssoc) {
+ // We have anim, do it
if (curSprintAssoc->blendDelta < 0.0f) {
curSprintAssoc->blendDelta = 2.0f;
curRunAssoc->blendDelta = -2.0f;
}
} else {
+ // Transition between run-sprint
curWalkAssoc->blendAmount = 0.0f;
curRunAssoc->blendAmount = 1.0f;
curSprintAssoc = CAnimManager::BlendAnimation(GetClump(), m_animGroup, ANIM_SPRINT, 2.0f);
@@ -505,6 +523,8 @@ CPlayerPed::SetRealMoveAnim(void)
curRunAssoc->blendAmount = 1.0f;
m_nMoveState = PEDMOVE_RUN;
}
+ curWalkAssoc->blendDelta = 0.0f;
+ curRunAssoc->blendDelta = 0.0f;
}
}
}
@@ -531,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)
{
@@ -541,21 +567,57 @@ CPlayerPed::RestoreSprintEnergy(float restoreSpeed)
m_fCurrentStamina += restoreSpeed * CTimer::GetTimeStep() * 0.5f;
}
-
-// TODO(Miami)
-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_TEC9 || weapon == WEAPONTYPE_SILENCED_INGRAM || weapon == WEAPONTYPE_MP5 ||
- weapon == WEAPONTYPE_SHOTGUN || weapon == WEAPONTYPE_RUGER || weapon == WEAPONTYPE_M4 || 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)
{
@@ -563,6 +625,7 @@ CPlayerPed::DoStuffToGoOnFire(void)
TheCamera.ClearPlayerWeaponMode();
}
+// --MIAMI: Done
bool
CPlayerPed::DoesTargetHaveToBeBroken(CVector target, CWeapon *weaponUsed)
{
@@ -571,18 +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_RUGER)
- 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)
@@ -601,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;
@@ -617,7 +676,7 @@ CPlayerPed::IsThisPedAttackingPlayer(CPed *suspect)
default:
break;
}
- return false;
+ return suspect->m_nPedState == PED_ABSEIL;
}
// --MIAMI: Done
@@ -638,6 +697,7 @@ CPlayerPed::PlayerControlSniper(CPad *padUsed)
if (!padUsed->GetTarget() && !m_attachedTo) {
RestorePreviousState();
TheCamera.ClearPlayerWeaponMode();
+ return;
}
int firingRate = GetWeapon()->m_eWeaponType == WEAPONTYPE_LASERSCOPE ? 333 : 266;
@@ -656,7 +716,7 @@ CPlayerPed::PlayerControlSniper(CPad *padUsed)
GetWeapon()->Update(m_audioEntityId, nil);
}
-// --MIAMI: Done except commented thing
+// --MIAMI: Done
// I think R* also used goto in here.
void
CPlayerPed::ProcessWeaponSwitch(CPad *padUsed)
@@ -664,8 +724,7 @@ CPlayerPed::ProcessWeaponSwitch(CPad *padUsed)
if (CDarkel::FrenzyOnGoing() || m_attachedTo)
goto switchDetectDone;
- // TODO(Miami): byte_A10B57
- if (!m_pPointGunAt && /* !byte_A10B57 && */ GetWeapon()->m_eWeaponType != WEAPONTYPE_DETONATOR) {
+ if (!m_pPointGunAt && !bDontAllowWeaponChange && GetWeapon()->m_eWeaponType != WEAPONTYPE_DETONATOR) {
if (padUsed->CycleWeaponRightJustDown()) {
if (TheCamera.PlayerWeaponMode.Mode != CCam::MODE_M16_1STPERSON
@@ -759,7 +818,7 @@ CPlayerPed::PlayerControlM16(CPad *padUsed)
bCrouchWhenShooting = false;
}
- if (!padUsed->GetTarget()) {
+ if (!padUsed->GetTarget() && !m_attachedTo) {
RestorePreviousState();
TheCamera.ClearPlayerWeaponMode();
}
@@ -796,7 +855,7 @@ CPlayerPed::PlayerControlFighter(CPad *padUsed)
bIsAttacking = false;
}
- if (!CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bHeavy && padUsed->JumpJustDown()) {
+ if (!CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->IsFlagSet(WEAPONFLAG_HEAVY) && padUsed->JumpJustDown()) {
if (m_nEvadeAmount != 0 && m_pEvadingFrom) {
SetEvasiveDive((CPhysical*)m_pEvadingFrom, 1);
m_nEvadeAmount = 0;
@@ -816,14 +875,7 @@ CPlayerPed::PlayerControl1stPersonRunAround(CPad *padUsed)
float padMove = CVector2D(leftRight, upDown).Magnitude();
float padMoveInGameUnit = padMove / PAD_MOVE_TO_GAME_WORLD_MOVE;
if (padMoveInGameUnit > 0.0f) {
-#ifdef FREE_CAM
- if (!CCamera::bFreeCam)
- m_fRotationDest = CGeneral::LimitRadianAngle(TheCamera.Orientation);
- else
- m_fRotationDest = CGeneral::GetRadianAngleBetweenPoints(0.0f, 0.0f, -leftRight, upDown) - TheCamera.Orientation;
-#else
m_fRotationDest = CGeneral::LimitRadianAngle(TheCamera.Orientation);
-#endif
m_fMoveSpeed = Min(padMoveInGameUnit, 0.07f * CTimer::GetTimeStep() + m_fMoveSpeed);
} else {
m_fMoveSpeed = 0.0f;
@@ -831,8 +883,7 @@ CPlayerPed::PlayerControl1stPersonRunAround(CPad *padUsed)
if (m_nPedState == PED_JUMP) {
if (bIsInTheAir) {
- if (bUsesCollision && !bHitSteepSlope &&
- (!bHitSomethingLastFrame || m_vecDamageNormal.z > 0.6f)
+ if (bUsesCollision && !bHitSteepSlope && (!bHitSomethingLastFrame || m_vecDamageNormal.z > 0.6f)
&& m_fDistanceTravelled < CTimer::GetTimeStep() * 0.02 && m_vecMoveSpeed.MagnitudeSqr() < 0.01f) {
float angleSin = Sin(m_fRotationCur); // originally sin(DEGTORAD(RADTODEG(m_fRotationCur))) o_O
@@ -849,15 +900,15 @@ CPlayerPed::PlayerControl1stPersonRunAround(CPad *padUsed)
return;
}
- if (!(CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bHeavy)
- && padUsed->GetSprint()) {
+ if (!CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->IsFlagSet(WEAPONFLAG_HEAVY) && padUsed->GetSprint()) {
m_nMoveState = PEDMOVE_SPRINT;
}
if (m_nPedState != PED_FIGHT)
SetRealMoveAnim();
- if (!bIsInTheAir && !(CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bHeavy)
- && padUsed->JumpJustDown() && m_nPedState != PED_JUMP) {
+ if (!bIsInTheAir && !(CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->IsFlagSet(WEAPONFLAG_HEAVY)) &&
+ padUsed->JumpJustDown() && m_nPedState != PED_JUMP) {
+
ClearAttack();
ClearWeaponTarget();
if (m_nEvadeAmount != 0 && m_pEvadingFrom) {
@@ -868,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);
@@ -919,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) {
@@ -947,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)
{
@@ -959,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) {
@@ -971,45 +1029,80 @@ CPlayerPed::EvaluateTarget(CEntity *candidate, CEntity **targetPtr, float *lastC
}
bool
+CPlayerPed::CanIKReachThisTarget(CVector target, CWeapon* weapon, bool zRotImportant)
+{
+ float angleToFace = CGeneral::GetRadianAngleBetweenPoints(target.x, target.y, GetPosition().x, GetPosition().y);
+ float angleDiff = CGeneral::LimitRadianAngle(angleToFace - m_fRotationCur);
+
+ return (!zRotImportant || CWeaponInfo::GetWeaponInfo(weapon->m_eWeaponType)->IsFlagSet(WEAPONFLAG_CANAIM_WITHARM) || Abs(angleDiff) <= HALFPI) &&
+ (CWeaponInfo::GetWeaponInfo(weapon->m_eWeaponType)->IsFlagSet(WEAPONFLAG_CANAIM_WITHARM) || Abs(target.z - GetPosition().z) <= (target - GetPosition()).Magnitude2D());
+}
+
+void
+CPlayerPed::RotatePlayerToTrackTarget(void)
+{
+ if (CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->IsFlagSet(WEAPONFLAG_CANAIM_WITHARM))
+ return;
+
+ float angleToFace = CGeneral::GetRadianAngleBetweenPoints(
+ m_pPointGunAt->GetPosition().x, m_pPointGunAt->GetPosition().y,
+ GetPosition().x, GetPosition().y);
+
+ float angleDiff = CGeneral::LimitRadianAngle(m_fRotationCur - angleToFace);
+ if (angleDiff < -DEGTORAD(25.0f)) {
+ m_fRotationCur -= angleDiff + DEGTORAD(25.0f);
+ m_fRotationDest -= angleDiff + DEGTORAD(25.0f);
+
+ } else if (angleDiff > DEGTORAD(25.0f)) {
+ m_fRotationCur -= angleDiff - DEGTORAD(25.0f);
+ m_fRotationDest -= angleDiff - DEGTORAD(25.0f);
+ }
+}
+
+// --MIAMI: Done
+bool
CPlayerPed::FindNextWeaponLockOnTarget(CEntity *previousTarget, bool lookToLeft)
{
CEntity *nextTarget = nil;
float weaponRange = CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_fRange;
- // nextTarget = nil;
+ // nextTarget = nil; // duplicate
float lastCloseness = -10000.0f;
- // unused
- // CGeneral::GetATanOfXY(GetForward().x, GetForward().y);
+ // CGeneral::GetATanOfXY(GetForward().x, GetForward().y); // unused
CVector distVec = previousTarget->GetPosition() - GetPosition();
float referenceBeta = CGeneral::GetATanOfXY(distVec.x, distVec.y);
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;
- m_pPointGunAt = nextTarget;
- if (nextTarget)
- nextTarget->RegisterReference((CEntity**)&m_pPointGunAt);
+ SetWeaponLockOnTarget(nextTarget);
+ bDontAllowWeaponChange = true;
SetPointGunAt(nextTarget);
return true;
}
+// --MIAMI: Done
bool
CPlayerPed::FindWeaponLockOnTarget(void)
{
@@ -1019,40 +1112,43 @@ CPlayerPed::FindWeaponLockOnTarget(void)
if (m_pPointGunAt) {
CVector distVec = m_pPointGunAt->GetPosition() - GetPosition();
if (distVec.Magnitude2D() > weaponRange) {
- m_pPointGunAt = nil;
+ SetWeaponLockOnTarget(nil);
return false;
} else {
return true;
}
}
- // nextTarget = nil;
+ // nextTarget = nil; // duplicate
float lastCloseness = -10000.0f;
float referenceBeta = CGeneral::GetATanOfXY(GetForward().x, GetForward().y);
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;
- m_pPointGunAt = nextTarget;
- if (nextTarget)
- nextTarget->RegisterReference((CEntity**)&m_pPointGunAt);
+ SetWeaponLockOnTarget(nextTarget);
+ bDontAllowWeaponChange = true;
SetPointGunAt(nextTarget);
Say(SOUND_PED_AIMING);
return true;
@@ -1063,6 +1159,7 @@ void
CPlayerPed::ProcessAnimGroups(void)
{
AssocGroupId groupToSet;
+#ifdef PC_PLAYER_CONTROLS
if ((m_fWalkAngle <= -DEGTORAD(50.0f) || m_fWalkAngle >= DEGTORAD(50.0f))
&& TheCamera.Cams[TheCamera.ActiveCam].Using3rdPersonMouseCam()
&& CanStrafeOrMouseControl()) {
@@ -1097,7 +1194,9 @@ CPlayerPed::ProcessAnimGroups(void)
else
groupToSet = ASSOCGRP_PLAYERBACK;
}
- } else {
+ } else
+#endif
+ {
if (GetWeapon()->m_eWeaponType == WEAPONTYPE_ROCKETLAUNCHER) {
groupToSet = ASSOCGRP_PLAYERROCKET;
} else {
@@ -1131,7 +1230,6 @@ CPlayerPed::ProcessAnimGroups(void)
}
}
-// TODO(Miami)
void
CPlayerPed::ProcessPlayerWeapon(CPad *padUsed)
{
@@ -1152,7 +1250,7 @@ CPlayerPed::ProcessPlayerWeapon(CPad *padUsed)
bCrouchWhenShooting = false;
}
- if(weaponInfo->m_bCanAim)
+ if(weaponInfo->IsFlagSet(WEAPONFLAG_CANAIM))
m_wepAccuracy = 95;
else
m_wepAccuracy = 100;
@@ -1199,12 +1297,7 @@ CPlayerPed::ProcessPlayerWeapon(CPad *padUsed)
} else {
m_fAttackButtonCounter = 0.0f;
}
-#ifdef FREE_CAM
- if (CCamera::bFreeCam && weaponInfo->m_eWeaponFire == WEAPON_FIRE_MELEE && m_fMoveSpeed < 1.0f)
- StartFightAttack(padUsed->GetWeapon());
- else
-#endif
- SetAttack(m_pPointGunAt);
+ SetAttack(m_pPointGunAt);
} else {
if (m_nPedState == PED_ATTACK) {
if (padUsed->WeaponJustDown()) {
@@ -1217,12 +1310,12 @@ CPlayerPed::ProcessPlayerWeapon(CPad *padUsed)
m_bHaveTargetSelected = false;
}
if (GetWeapon()->m_eWeaponType != WEAPONTYPE_UNARMED && GetWeapon()->m_eWeaponType != WEAPONTYPE_BRASSKNUCKLE &&
- !weaponInfo->m_bFightMode) {
+ !weaponInfo->IsFlagSet(WEAPONFLAG_FIGHTMODE)) {
if (GetWeapon()->m_eWeaponType != WEAPONTYPE_DETONATOR && GetWeapon()->m_eWeaponType != WEAPONTYPE_DETONATOR_GRENADE ||
padUsed->WeaponJustDown())
-
SetAttack(nil);
+
} else if (padUsed->WeaponJustDown()) {
if (m_fMoveSpeed < 1.0f || m_nPedState == PED_FIGHT)
StartFightAttack(padUsed->GetWeapon());
@@ -1241,36 +1334,38 @@ CPlayerPed::ProcessPlayerWeapon(CPad *padUsed)
#ifdef FREE_CAM
static int8 changedHeadingRate = 0;
+ static int8 pointedGun = 0;
if (changedHeadingRate == 2) changedHeadingRate = 1;
+ if (pointedGun == 2) pointedGun = 1;
// Rotate player/arm when shooting. We don't have auto-rotation anymore
if (CCamera::m_bUseMouse3rdPerson && CCamera::bFreeCam &&
m_nSelectedWepSlot == m_currentWeapon && m_nMoveState != PEDMOVE_SPRINT) {
+#define CAN_AIM_WITH_ARM (weaponInfo->IsFlagSet(WEAPONFLAG_CANAIM_WITHARM) && !bIsDucking && !bCrouchWhenShooting)
// Weapons except throwable and melee ones
if (weaponInfo->m_nWeaponSlot > 2) {
- if ((padUsed->GetTarget() && weaponInfo->m_bCanAimWithArm) || padUsed->GetWeapon()) {
+ 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);
bIsPointingGunAt = false; // to not stop after attack
}
-
+ pointedGun = 2;
SetLookFlag(limitedCam, true);
SetAimFlag(limitedCam);
-#ifdef VC_PED_PORTS
SetLookTimer(INT32_MAX); // removing this makes head move for real, but I experinced some bugs.
-#endif
+
} else {
m_fRotationDest = limitedCam;
changedHeadingRate = 2;
m_headingRate = 12.5f;
// Anim. fix for shotgun, ak47 and m16 (we must finish rot. it quickly)
- if (weaponInfo->m_bCanAim && padUsed->WeaponJustDown()) {
+ if (weaponInfo->IsFlagSet(WEAPONFLAG_CANAIM) && padUsed->WeaponJustDown()) {
m_fRotationCur = CGeneral::LimitRadianAngle(m_fRotationCur);
float limitedRotDest = m_fRotationDest;
@@ -1283,17 +1378,21 @@ CPlayerPed::ProcessPlayerWeapon(CPad *padUsed)
m_fRotationCur += (limitedRotDest - m_fRotationCur) / 2;
}
}
- } else if (weaponInfo->m_bCanAimWithArm)
- ClearPointGunAt();
+ }
}
+#undef CAN_AIM_WITH_ARM
}
if (changedHeadingRate == 1) {
changedHeadingRate = 0;
RestoreHeadingRate();
}
+ if (pointedGun == 1 && m_nPedState != PED_ATTACK) {
+ pointedGun = 0;
+ ClearPointGunAt();
+ }
#endif
- if (padUsed->GetTarget() && m_nSelectedWepSlot == m_currentWeapon && m_nMoveState != PEDMOVE_SPRINT && !TheCamera.Using1stPersonWeaponMode() && weaponInfo->m_bCanAim) {
+ if (padUsed->GetTarget() && m_nSelectedWepSlot == m_currentWeapon && m_nMoveState != PEDMOVE_SPRINT && !TheCamera.Using1stPersonWeaponMode() && weaponInfo->IsFlagSet(WEAPONFLAG_CANAIM)) {
if (m_pPointGunAt) {
// what??
if (!m_pPointGunAt
@@ -1307,19 +1406,23 @@ CPlayerPed::ProcessPlayerWeapon(CPad *padUsed)
return;
}
- CPed *gunPointed = (CPed*)m_pPointGunAt;
- if (gunPointed && gunPointed->IsPed() &&
- ((gunPointed->bInVehicle && (!gunPointed->m_pMyVehicle || !gunPointed->m_pMyVehicle->IsBike())) || !CGame::nastyGame && gunPointed->DyingOrDead())) {
+ if (m_pPointGunAt->IsPed() && (
+#ifndef AIMING_VEHICLE_OCCUPANTS
+ (((CPed*)m_pPointGunAt)->bInVehicle && (!((CPed*)m_pPointGunAt)->m_pMyVehicle || !((CPed*)m_pPointGunAt)->m_pMyVehicle->IsBike())) ||
+#endif
+ !CGame::nastyGame && ((CPed*)m_pPointGunAt)->DyingOrDead())) {
ClearWeaponTarget();
return;
}
if (CPlayerPed::DoesTargetHaveToBeBroken(m_pPointGunAt->GetPosition(), GetWeapon()) ||
- (!bCanPointGunAtTarget && !weaponInfo->m_bCanAimWithArm)) {
+ (!bCanPointGunAtTarget && !weaponInfo->IsFlagSet(WEAPONFLAG_CANAIM_WITHARM))) { // this line isn't on Mobile, idk why
ClearWeaponTarget();
return;
}
- // TODO(Miami): RotatePlayerToTrackTarget
+ if (m_pPointGunAt) {
+ RotatePlayerToTrackTarget();
+ }
if (m_pPointGunAt) {
if (padUsed->ShiftTargetLeftJustDown())
@@ -1329,12 +1432,8 @@ 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) || !CCamera::m_bUseMouse3rdPerson) {
-#else
- else if (!CCamera::m_bUseMouse3rdPerson) {
-#endif
+
+ } else if (!CCamera::m_bUseMouse3rdPerson) {
if (padUsed->TargetJustDown() || TheCamera.m_bJustJumpedOutOf1stPersonBecauseOfTarget)
FindWeaponLockOnTarget();
}
@@ -1343,16 +1442,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(*(RwV3d *)&markPos, PED_MID);
+ ((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 {
@@ -1362,17 +1457,29 @@ CPlayerPed::ProcessPlayerWeapon(CPad *padUsed)
m_bHasLockOnTarget = m_pPointGunAt != nil;
}
+bool
+CPlayerPed::MovementDisabledBecauseOfTargeting(void)
+{
+ return m_pPointGunAt && !CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->IsFlagSet(WEAPONFLAG_CANAIM_WITHARM);
+}
+
+// --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 {
@@ -1382,12 +1489,8 @@ CPlayerPed::PlayerControlZelda(CPad *padUsed)
if (padMoveInGameUnit > 0.0f || smoothSprayWithoutMove) {
float padHeading = CGeneral::GetRadianAngleBetweenPoints(0.0f, 0.0f, -leftRight, upDown);
float neededTurn = CGeneral::LimitRadianAngle(padHeading - camOrientation);
- if (doSmoothSpray) {
- if (GetWeapon()->m_eWeaponType == WEAPONTYPE_FLAMETHROWER || GetWeapon()->m_eWeaponType == WEAPONTYPE_COLT45
- || CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_nWeaponSlot == 5)
- 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;
}
@@ -1401,8 +1504,7 @@ CPlayerPed::PlayerControlZelda(CPad *padUsed)
if (m_nPedState == PED_JUMP) {
if (bIsInTheAir) {
- if (bUsesCollision && !bHitSteepSlope &&
- (!bHitSomethingLastFrame || m_vecDamageNormal.z > 0.6f)
+ if (bUsesCollision && !bHitSteepSlope && (!bHitSomethingLastFrame || m_vecDamageNormal.z > 0.6f)
&& m_fDistanceTravelled < CTimer::GetTimeStep() * 0.02 && m_vecMoveSpeed.MagnitudeSqr() < 0.01f) {
float angleSin = Sin(m_fRotationCur); // originally sin(DEGTORAD(RADTODEG(m_fRotationCur))) o_O
@@ -1419,16 +1521,15 @@ CPlayerPed::PlayerControlZelda(CPad *padUsed)
return;
}
- if (!(CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bHeavy)
- && padUsed->GetSprint()) {
-
- if (!m_pCurrentPhysSurface || !m_pCurrentPhysSurface->bInfiniteMass || m_pCurrentPhysSurface->m_phy_flagA08)
+ if (!CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->IsFlagSet(WEAPONFLAG_HEAVY) && padUsed->GetSprint()) {
+ if (!m_pCurrentPhysSurface || (!m_pCurrentPhysSurface->bInfiniteMass || m_pCurrentPhysSurface->m_phy_flagA08))
m_nMoveState = PEDMOVE_SPRINT;
}
+
if (m_nPedState != PED_FIGHT)
SetRealMoveAnim();
- if (!bIsInTheAir && !(CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->m_bHeavy)
+ if (!bIsInTheAir && !CWeaponInfo::GetWeaponInfo(GetWeapon()->m_eWeaponType)->IsFlagSet(WEAPONFLAG_HEAVY)
&& padUsed->JumpJustDown() && m_nPedState != PED_JUMP) {
ClearAttack();
ClearWeaponTarget();
@@ -1443,32 +1544,165 @@ CPlayerPed::PlayerControlZelda(CPad *padUsed)
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);
@@ -1486,27 +1720,30 @@ 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 (!rollDoorAssoc) {
- rollDoorAssoc = RpAnimBlendClumpGetAssociation(GetClump(), ANIM_CAR_ROLLDOOR_LOW);
- }
+ 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);
- // These comparisons are wrong, they return uint16
- if (m_pMyVehicle->m_nGettingOutFlags & CAR_DOOR_FLAG_LF || rollDoorAssoc || 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);
- 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);
+ } else {
+ // 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);
+ }
+ }
}
}
return;
@@ -1515,8 +1752,8 @@ CPlayerPed::ProcessControl(void)
m_nMoveState = PEDMOVE_STILL;
if (bIsLanding)
RunningLand(padUsed);
- if (padUsed && padUsed->WeaponJustDown() && !TheCamera.Using1stPersonWeaponMode()) {
+ if (padUsed && padUsed->WeaponJustDown() && !TheCamera.Using1stPersonWeaponMode()) {
// ...Really?
eWeaponType playerWeapon = FindPlayerPed()->GetWeapon()->m_eWeaponType;
if (playerWeapon == WEAPONTYPE_SNIPERRIFLE || playerWeapon == WEAPONTYPE_LASERSCOPE) {
@@ -1539,12 +1776,19 @@ CPlayerPed::ProcessControl(void)
if (TheCamera.Using1stPersonWeaponMode()) {
if (padUsed)
PlayerControlFighter(padUsed);
- } else if (TheCamera.Cams[0].Using3rdPersonMouseCam()) {
+
+ } else if (TheCamera.Cams[0].Using3rdPersonMouseCam()
+#ifdef FREE_CAM
+ && !CCamera::bFreeCam
+#endif
+ ) {
if (padUsed)
PlayerControl1stPersonRunAround(padUsed);
+
} else if (m_nPedState == PED_FIGHT) {
if (padUsed)
PlayerControlFighter(padUsed);
+
} else if (padUsed) {
PlayerControlZelda(padUsed);
}
@@ -1552,46 +1796,6 @@ CPlayerPed::ProcessControl(void)
if (IsPedInControl() && m_nPedState != PED_ANSWER_MOBILE && padUsed)
ProcessPlayerWeapon(padUsed);
break;
- case PED_LOOK_ENTITY:
- case PED_LOOK_HEADING:
- case PED_WANDER_RANGE:
- case PED_WANDER_PATH:
- case PED_PURSUE:
- case PED_FOLLOW_PATH:
- case PED_ROCKET_MODE:
- case PED_DUMMY:
- case PED_PAUSE:
- case PED_FACE_PHONE:
- case PED_MAKE_CALL:
- case PED_CHAT:
- case PED_MUG:
- case PED_AI_CONTROL:
- case PED_FOLLOW_ROUTE:
- case PED_CPR:
- case PED_SOLICIT:
- case PED_BUY_ICECREAM:
- case PED_INVESTIGATE:
- case PED_STEP_AWAY:
- case PED_ON_FIRE:
- case PED_SUN_BATHE:
- case PED_FLASH:
- case PED_JOG:
- case PED_UNKNOWN:
- case PED_STATES_NO_AI:
- case PED_ABSEIL:
- case PED_SIT:
- case PED_STAGGER:
- case PED_DIVE_AWAY:
- case PED_STATES_NO_ST:
- case PED_ARREST_PLAYER:
- case PED_DRIVING:
- case PED_PASSENGER:
- case PED_TAXI_PASSENGER:
- case PED_OPEN_DOOR:
- case PED_DIE:
- case PED_DEAD:
- case PED_HANDS_UP:
- break;
case PED_SEEK_ENTITY:
m_vecSeekPos = m_pSeekTarget->GetPosition();
@@ -1621,6 +1825,7 @@ CPlayerPed::ProcessControl(void)
if (GetWeapon()->m_eWeaponType == WEAPONTYPE_SNIPERRIFLE || GetWeapon()->m_eWeaponType == WEAPONTYPE_LASERSCOPE) {
if (padUsed)
PlayerControlSniper(padUsed);
+
} else if (padUsed) {
PlayerControlM16(padUsed);
}
@@ -1670,6 +1875,8 @@ CPlayerPed::ProcessControl(void)
if (m_nLastPedState == PED_DRAG_FROM_CAR && m_pVehicleAnim)
BeingDraggedFromCar();
break;
+ default:
+ break;
}
if (padUsed && IsPedShootable() && m_nPedState != PED_ANSWER_MOBILE && m_nLastPedState != PED_ANSWER_MOBILE) {
ProcessWeaponSwitch(padUsed);
@@ -1683,20 +1890,18 @@ 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 (Abs(rightTurnAngle - m_fLookDirection) < Abs(leftTurnAngle - m_fLookDirection))
- camAngle = rightTurnAngle;
- else
- camAngle = leftTurnAngle;
- } else {
+
+ if (m_fLookDirection == 999999.0f || bIsDucking)
camAngle = rightTurnAngle;
- }
+ else if (Abs(rightTurnAngle - m_fLookDirection) < Abs(leftTurnAngle - m_fLookDirection))
+ camAngle = rightTurnAngle;
+ else
+ camAngle = leftTurnAngle;
}
SetLookFlag(camAngle, true);
SetLookTimer(CTimer::GetTimeStepInMilliseconds() * 5.0f);
@@ -1722,18 +1927,23 @@ CPlayerPed::ProcessControl(void)
m_bSpeedTimerFlag = false;
}
+ 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();
-#ifdef PED_SKIN
- if (!bIsVisible && IsClumpSkinned(GetClump()))
+ if (!bIsVisible)
UpdateRpHAnim();
-#endif
}
+// --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)
@@ -1746,7 +1956,6 @@ CPlayerPed::DoesPlayerWantNewWeapon(eWeaponType weapon, bool onlyIfSlotIsEmpty)
return m_nPedState != PED_ATTACK && m_nPedState != PED_AIM_GUN || slot != m_currentWeapon;
}
-// TODO(Miami): This only works on gamepad cam! This isn't fair
void
CPlayerPed::PlayIdleAnimations(CPad *padUsed)
{
@@ -1816,6 +2025,84 @@ CPlayerPed::PlayIdleAnimations(CPad *padUsed)
// --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;
diff --git a/src/peds/PlayerPed.h b/src/peds/PlayerPed.h
index 8a6e7576..3c58f7f5 100644
--- a/src/peds/PlayerPed.h
+++ b/src/peds/PlayerPed.h
@@ -31,12 +31,12 @@ public:
bool m_bAdrenalineActive;
bool m_bHasLockOnTarget;
bool m_bCanBeDamaged;
- bool m_bDrunkVisualsWearOff; // TODO(Miami): That may be something else
+ bool m_bNoPosForMeleeAttack;
+ bool unk1;
CVector m_vecSafePos[6]; // safe places from the player, for example behind a tree
CPed *m_pPedAtSafePos[6];
CPed *m_pMeleeList[6]; // reachable peds at each direction(6)
- char unused1;
- int16 m_nCheckPlayersIndex;
+ 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
@@ -45,6 +45,8 @@ public:
unsigned int m_nPadDownPressedInMilliseconds;
unsigned int m_nLastBusFareCollected;
+ static bool bDontAllowWeaponChange;
+
CPlayerPed();
~CPlayerPed();
void SetMoveAnim() { };
@@ -64,18 +66,18 @@ 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);
@@ -87,6 +89,12 @@ public:
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);
@@ -100,6 +108,4 @@ public:
static const uint32 nSaveStructSize;
};
-#ifndef PED_SKIN
-VALIDATE_SIZE(CPlayerPed, 0x5F0);
-#endif
+//VALIDATE_SIZE(CPlayerPed, 0x5F0);
diff --git a/src/render/Clouds.cpp b/src/render/Clouds.cpp
index 15bae90b..c7554356 100644
--- a/src/render/Clouds.cpp
+++ b/src/render/Clouds.cpp
@@ -129,7 +129,7 @@ CClouds::Render(void)
CSprite::InitSpriteBuffer();
float minute = CClock::GetHours()*60 + CClock::GetMinutes() + CClock::GetSeconds()/60.0f;
- RwV3d campos = *(RwV3d*)&TheCamera.GetPosition();
+ RwV3d campos = TheCamera.GetPosition();
// Moon
float moonfadeout = Abs(minute - 180.0f); // fully visible at 3AM
diff --git a/src/render/Coronas.cpp b/src/render/Coronas.cpp
index c40577d7..515e1000 100644
--- a/src/render/Coronas.cpp
+++ b/src/render/Coronas.cpp
@@ -2,6 +2,7 @@
#include "main.h"
#include "General.h"
+#include "Entity.h"
#include "RenderBuffer.h"
#include "TxdStore.h"
#include "Camera.h"
@@ -12,6 +13,10 @@
#include "Collision.h"
#include "Timecycle.h"
#include "Coronas.h"
+#include "PointLights.h"
+#include "Shadows.h"
+#include "Clock.h"
+#include "Bridge.h"
//--MIAMI: file done
@@ -271,7 +276,7 @@ CCoronas::Render(void)
CVector spriteCoors;
float spritew, spriteh;
- if(!CSprite::CalcScreenCoors(aCoronas[i].coors, spriteCoors, &spritew, &spriteh, true)){
+ if(!CSprite::CalcScreenCoors(aCoronas[i].coors, &spriteCoors, &spritew, &spriteh, true)){
aCoronas[i].offScreen = true;
aCoronas[i].sightClear = false;
}else{
@@ -478,7 +483,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){
@@ -669,7 +674,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{
@@ -715,3 +720,234 @@ CRegisteredCorona::Update(void)
firstUpdate = false;
registeredThisFrame = false;
}
+
+void
+CEntity::ProcessLightsForEntity(void)
+{
+ int i, n;
+ C2dEffect *effect;
+ CVector pos;
+ bool lightOn, lightFlickering;
+ uint32 flashTimer1, flashTimer2, flashTimer3;
+
+ if(bRenderDamaged || !bIsVisible || GetUp().z < 0.96f)
+ return;
+
+ flashTimer1 = 0;
+ flashTimer2 = 0;
+ flashTimer3 = 0;
+
+ n = CModelInfo::GetModelInfo(GetModelIndex())->GetNum2dEffects();
+ for(i = 0; i < n; i++, flashTimer1 += 0x80, flashTimer2 += 0x100, flashTimer3 += 0x200){
+ effect = CModelInfo::GetModelInfo(GetModelIndex())->Get2dEffect(i);
+
+ 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 = 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){
+ 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)
+ 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)
+ 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)
+ 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){
+ if(m_randomSeed > 16)
+ lightOn = true;
+ else{
+ if((CTimer::GetTimeInMilliseconds() ^ m_randomSeed*8) & 0x60)
+ lightOn = true;
+ else
+ lightFlickering = true;
+ if((CTimer::GetTimeInMilliseconds()>>11 ^ m_randomSeed*8) & 3)
+ lightOn = true;
+ }
+ }
+ break;
+ case LIGHT_BRIDGE_FLASH1:
+ if(CBridge::ShouldLightsBeFlashing() && CTimer::GetTimeInMilliseconds() & 0x200)
+ lightOn = true;
+ break;
+ case LIGHT_BRIDGE_FLASH2:
+ if(CBridge::ShouldLightsBeFlashing() && (CTimer::GetTimeInMilliseconds() & 0x1FF) < 60)
+ lightOn = true;
+ break;
+ }
+
+ if(effect->light.flags & LIGHTFLAG_HIDE_OBJECT){
+ if(lightOn)
+ bDoNotRender = false;
+ else
+ bDoNotRender = true;
+ return;
+ }
+
+ // Corona
+ if(lightOn)
+ CCoronas::RegisterCorona((uintptr)this + i,
+ effect->col.r, effect->col.g, effect->col.b, 255,
+ pos, effect->light.size, effect->light.dist,
+ effect->light.corona, effect->light.flareType, effect->light.roadReflection,
+ effect->light.flags&LIGHTFLAG_LOSCHECK, CCoronas::STREAK_OFF, 0.0f,
+ !!(effect->light.flags&LIGHTFLAG_LONG_DIST));
+ else if(lightFlickering)
+ CCoronas::RegisterCorona((uintptr)this + i,
+ 0, 0, 0, 255,
+ pos, effect->light.size, effect->light.dist,
+ effect->light.corona, effect->light.flareType, effect->light.roadReflection,
+ effect->light.flags&LIGHTFLAG_LOSCHECK, CCoronas::STREAK_OFF, 0.0f,
+ !!(effect->light.flags&LIGHTFLAG_LONG_DIST));
+
+ // Pointlight
+ bool alreadyProcessedFog;
+ alreadyProcessedFog = false;
+ if(effect->light.range != 0.0f && lightOn){
+ if(effect->col.r == 0 && effect->col.g == 0 && effect->col.b == 0){
+ CPointLights::AddLight(CPointLights::LIGHT_POINT,
+ pos, CVector(0.0f, 0.0f, 0.0f),
+ effect->light.range,
+ 0.0f, 0.0f, 0.0f,
+ CPointLights::FOG_NONE, true);
+ }else{
+ CPointLights::AddLight(CPointLights::LIGHT_POINT,
+ pos, CVector(0.0f, 0.0f, 0.0f),
+ effect->light.range,
+ effect->col.r*CTimeCycle::GetSpriteBrightness()/255.0f,
+ effect->col.g*CTimeCycle::GetSpriteBrightness()/255.0f,
+ effect->col.b*CTimeCycle::GetSpriteBrightness()/255.0f,
+ (effect->light.flags & LIGHTFLAG_FOG) >> 1,
+ true);
+ alreadyProcessedFog = true;
+ }
+ }
+
+ if(!alreadyProcessedFog){
+ if(effect->light.flags & LIGHTFLAG_FOG_ALWAYS){
+ CPointLights::AddLight(CPointLights::LIGHT_FOGONLY_ALWAYS,
+ pos, CVector(0.0f, 0.0f, 0.0f),
+ 0.0f,
+ effect->col.r/255.0f, effect->col.g/255.0f, effect->col.b/255.0f,
+ CPointLights::FOG_ALWAYS, true);
+ }else if(effect->light.flags & LIGHTFLAG_FOG_NORMAL && lightOn && effect->light.range == 0.0f){
+ CPointLights::AddLight(CPointLights::LIGHT_FOGONLY,
+ pos, CVector(0.0f, 0.0f, 0.0f),
+ 0.0f,
+ effect->col.r/255.0f, effect->col.g/255.0f, effect->col.b/255.0f,
+ CPointLights::FOG_NORMAL, true);
+ }
+ }
+
+ // Light shadow
+ if(effect->light.shadowSize != 0.0f){
+ if(lightOn){
+ CShadows::StoreStaticShadow((uintptr)this + i, SHADOWTYPE_ADDITIVE,
+ effect->light.shadow, &pos,
+ effect->light.shadowSize, 0.0f,
+ 0.0f, -effect->light.shadowSize,
+ 128,
+ effect->col.r*CTimeCycle::GetSpriteBrightness()*effect->light.shadowIntensity/255.0f,
+ effect->col.g*CTimeCycle::GetSpriteBrightness()*effect->light.shadowIntensity/255.0f,
+ effect->col.b*CTimeCycle::GetSpriteBrightness()*effect->light.shadowIntensity/255.0f,
+ 15.0f, 1.0f, 40.0f, false, 0.0f);
+ }else if(lightFlickering){
+ CShadows::StoreStaticShadow((uintptr)this + i, SHADOWTYPE_ADDITIVE,
+ effect->light.shadow, &pos,
+ effect->light.shadowSize, 0.0f,
+ 0.0f, -effect->light.shadowSize,
+ 0, 0.0f, 0.0f, 0.0f,
+ 15.0f, 1.0f, 40.0f, false, 0.0f);
+ }
+ }
+ break;
+
+ case EFFECT_SUNGLARE:
+ if(CWeather::SunGlare >= 0.0f){
+ CVector pos = GetMatrix() * effect->pos;
+ CVector glareDir = pos - GetPosition();
+ glareDir.Normalise();
+ CVector camDir = TheCamera.GetPosition() - pos;
+ float dist = camDir.Magnitude();
+ camDir *= 2.0f/dist;
+ glareDir += camDir;
+ glareDir.Normalise();
+ float camAngle = -DotProduct(glareDir, CTimeCycle::GetSunDirection());
+ if(camAngle > 0.0f){
+ float intens = Sqrt(camAngle) * CWeather::SunGlare;
+ pos += camDir;
+ CCoronas::RegisterCorona((uintptr)this + 33 + i,
+ intens * (CTimeCycle::GetSunCoreRed() + 2*255)/3.0f,
+ intens * (CTimeCycle::GetSunCoreGreen() + 2*255)/3.0f,
+ intens * (CTimeCycle::GetSunCoreBlue() + 2*255)/3.0f,
+ 255,
+ pos, 0.5f*CWeather::SunGlare*Sqrt(dist), 120.0f,
+ CCoronas::TYPE_STAR, CCoronas::FLARE_NONE,
+ CCoronas::REFLECTION_OFF, CCoronas::LOSCHECK_OFF,
+ CCoronas::STREAK_OFF, 0.0f);
+ }
+ }
+ break;
+ }
+ }
+} \ No newline at end of file
diff --git a/src/render/Fluff.cpp b/src/render/Fluff.cpp
index 3c0d3708..157be0c8 100644
--- a/src/render/Fluff.cpp
+++ b/src/render/Fluff.cpp
@@ -744,7 +744,7 @@ void CScrollBar::Render()
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE);
CVector coronaCoord, screenCoord;
- float screenW, screenH;
+ float screenW, screenH;
for (int i = 1; i < ARRAY_SIZE(m_MessageBar); ++i)
{
for (int j = 0; j < 5; ++j)
@@ -756,7 +756,7 @@ void CScrollBar::Render()
// Render main coronas
if (m_MessageBar[i] & (1 << j))
{
- if (CSprite::CalcScreenCoors(coronaCoord, screenCoord, &screenW, &screenH, true))
+ if (CSprite::CalcScreenCoors(coronaCoord, &screenCoord, &screenW, &screenH, true))
{
CSprite::RenderBufferedOneXLUSprite(
screenCoord.x, screenCoord.y, screenCoord.z,
@@ -768,7 +768,7 @@ void CScrollBar::Render()
// Render smaller and faded coronas for a trailing effect
else if (m_MessageBar[i - 1] & (1 << j))
{
- if (CSprite::CalcScreenCoors(coronaCoord, screenCoord, &screenW, &screenH, true))
+ if (CSprite::CalcScreenCoors(coronaCoord, &screenCoord, &screenW, &screenH, true))
{
CSprite::RenderBufferedOneXLUSprite(
screenCoord.x, screenCoord.y, screenCoord.z,
@@ -1291,7 +1291,7 @@ INITSAVEBUF
for (int32 j = 0; j < 6; j++) {
if (pPath->m_pObjects[j] != nil)
- pPath->m_pObjects[j] = (CObject*)(CPools::GetObjectPool()->GetJustIndex(pPath->m_pObjects[j]) + 1);
+ pPath->m_pObjects[j] = (CObject*)(CPools::GetObjectPool()->GetJustIndex_NoFreeAssert(pPath->m_pObjects[j]) + 1);
}
for (int32 j = 0; j < aArray[i].m_numNodes; j++) {
diff --git a/src/render/Font.cpp b/src/render/Font.cpp
index 78a8599e..d6a06db8 100644
--- a/src/render/Font.cpp
+++ b/src/render/Font.cpp
@@ -3,6 +3,9 @@
#include "Sprite2d.h"
#include "TxdStore.h"
#include "Font.h"
+#ifdef BUTTON_ICONS
+#include "FileMgr.h"
+#endif
#include "Timer.h"
void
@@ -224,6 +227,12 @@ union tFontRenderStatePointer
tFontRenderStatePointer FontRenderStatePointer;
uint8 FontRenderStateBuf[1024];
+#ifdef BUTTON_ICONS
+CSprite2d CFont::ButtonSprite[MAX_BUTTON_ICONS];
+int CFont::PS2Symbol = BUTTON_NONE;
+int CFont::ButtonsSlot = -1;
+#endif // BUTTON_ICONS
+
void
CFont::Initialise(void)
{
@@ -279,6 +288,34 @@ CFont::Initialise(void)
SetAlphaFade(255.0f);
SetDropShadowPosition(0);
CTxdStore::PopCurrentTxd();
+
+#ifdef BUTTON_ICONS
+ if (int file = CFileMgr::OpenFile("MODELS/X360BTNS.TXD")) {
+ CFileMgr::CloseFile(file);
+ ButtonsSlot = CTxdStore::AddTxdSlot("buttons");
+ CTxdStore::LoadTxd(ButtonsSlot, "MODELS/X360BTNS.TXD");
+ CTxdStore::AddRef(ButtonsSlot);
+ CTxdStore::PushCurrentTxd();
+ CTxdStore::SetCurrentTxd(ButtonsSlot);
+#if 0 // unused
+ ButtonSprite[BUTTON_UP].SetTexture("up");
+ ButtonSprite[BUTTON_DOWN].SetTexture("down");
+ ButtonSprite[BUTTON_LEFT].SetTexture("left");
+ ButtonSprite[BUTTON_RIGHT].SetTexture("right");
+#endif
+ ButtonSprite[BUTTON_CROSS].SetTexture("cross");
+ ButtonSprite[BUTTON_CIRCLE].SetTexture("circle");
+ ButtonSprite[BUTTON_SQUARE].SetTexture("square");
+ ButtonSprite[BUTTON_TRIANGLE].SetTexture("triangle");
+ ButtonSprite[BUTTON_L1].SetTexture("l1");
+ ButtonSprite[BUTTON_L2].SetTexture("l2");
+ ButtonSprite[BUTTON_L3].SetTexture("l3");
+ ButtonSprite[BUTTON_R1].SetTexture("r1");
+ ButtonSprite[BUTTON_R2].SetTexture("r2");
+ ButtonSprite[BUTTON_R3].SetTexture("r3");
+ CTxdStore::PopCurrentTxd();
+ }
+#endif // BUTTON_ICONS
}
#ifdef MORE_LANGUAGES
@@ -327,6 +364,13 @@ CFont::ReloadFonts(uint8 set)
void
CFont::Shutdown(void)
{
+#ifdef BUTTON_ICONS
+ if (ButtonsSlot != -1) {
+ for (int i = 0; i < MAX_BUTTON_ICONS; i++)
+ ButtonSprite[i].Delete();
+ CTxdStore::RemoveTxdSlot(ButtonsSlot);
+ }
+#endif
Sprite[0].Delete();
Sprite[1].Delete();
#ifdef MORE_LANGUAGES
@@ -347,7 +391,33 @@ CFont::InitPerFrame(void)
FontRenderStatePointer.pRenderState = (CFontRenderState*)FontRenderStateBuf;
SetDropShadowPosition(0);
NewLine = 0;
+#ifdef BUTTON_ICONS
+ PS2Symbol = BUTTON_NONE;
+#endif
+}
+
+#ifdef BUTTON_ICONS
+void
+CFont::DrawButton(float x, float y)
+{
+ if (x <= 0.0f || x > SCREEN_WIDTH || y <= 0.0f || y > SCREEN_HEIGHT)
+ return;
+
+ if (PS2Symbol != BUTTON_NONE) {
+ CRect rect;
+ rect.left = x;
+ rect.top = Details.scaleY + Details.scaleY + y;
+ rect.right = Details.scaleY * 17.0f + x;
+ rect.bottom = Details.scaleY * 19.0f + y;
+
+ int vertexAlphaState;
+ RwRenderStateGet(rwRENDERSTATEVERTEXALPHAENABLE, &vertexAlphaState);
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void *)TRUE);
+ ButtonSprite[PS2Symbol].Draw(rect, CRGBA(255, 255, 255, Details.color.a));
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void *)vertexAlphaState);
+ }
}
+#endif
void
CFont::PrintChar(float x, float y, wchar c)
@@ -374,7 +444,11 @@ CFont::PrintChar(float x, float y, wchar c)
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,
@@ -390,9 +464,9 @@ CFont::PrintChar(float x, float y, wchar c)
x + 32.0f * RenderState.scaleX * 1.0f,
y + 33.0f * RenderState.scaleY * 0.5f),
RenderState.color,
- xoff / 16.0f, yoff / 12.8f,
- (xoff + 1.0f) / 16.0f - 0.001f, yoff / 12.8f - 0.017f,
- xoff / 16.0f, (yoff + 1.0f) / 12.8f,
+ 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
@@ -851,6 +925,15 @@ CFont::PrintString(float x, float y, wchar *start, wchar *&end, float spwidth, f
c = *s - ' ';
if (Details.slant != 0.0f && !IsJapanese())
y = (Details.slantRefX - x) * Details.slant + Details.slantRefY;
+
+#ifdef BUTTON_ICONS
+ if (PS2Symbol != BUTTON_NONE) {
+ DrawButton(x, y);
+ x += Details.scaleY * 17.0f;
+ PS2Symbol = BUTTON_NONE;
+ }
+#endif
+
PrintChar(x, y, c);
x += GetCharacterSize(c);
if (c == 0 && (!NewLine || !IsJapanese())) // space
@@ -972,6 +1055,7 @@ CFont::GetCharacterWidth(wchar c)
else
return Size[LanguageSet][Details.style][192];
#else
+
if (Details.proportional)
return Size[Details.style][c];
else
@@ -1017,6 +1101,11 @@ CFont::GetCharacterSize(wchar c)
else
return Size[LanguageSet][Details.style][209] * Details.scaleX;
#else
+
+#ifdef FIX_BUGS
+ // PS2 don't call FindNewCharacter in here at all, and also uses different chars for some symbols
+ if (!Details.bFontHalfTexture && c == 30) c = 61; // wanted star
+#endif
if (Details.bFontHalfTexture)
c = FindNewCharacter(c);
if (Details.proportional)
@@ -1041,6 +1130,30 @@ CFont::GetStringWidth(wchar *s, bool spaces)
do {
while (*s == '~' || *s == JAP_TERMINATION) {
s++;
+#ifdef BUTTON_ICONS
+ switch (*s) {
+#if 0 // unused
+ case 'U':
+ case 'D':
+ case '<':
+ case '>':
+#endif
+ case 'X':
+ case 'O':
+ case 'Q':
+ case 'T':
+ case 'K':
+ case 'M':
+ case 'A':
+ case 'J':
+ case 'V':
+ case 'C':
+ w += 17.0f * Details.scaleY;
+ break;
+ default:
+ break;
+ }
+#endif
while (!(*s == '~' || *s == JAP_TERMINATION)) s++;
s++;
}
@@ -1055,6 +1168,30 @@ CFont::GetStringWidth(wchar *s, bool spaces)
for (wchar c = *s; (c != ' ' || spaces) && c != '\0'; c = *(++s)) {
if (c == '~') {
s++;
+#ifdef BUTTON_ICONS
+ switch (*s) {
+#if 0 // unused
+ case 'U':
+ case 'D':
+ case '<':
+ case '>':
+#endif
+ case 'X':
+ case 'O':
+ case 'Q':
+ case 'T':
+ case 'K':
+ case 'M':
+ case 'A':
+ case 'J':
+ case 'V':
+ case 'C':
+ w += 17.0f * Details.scaleY;
+ break;
+ default:
+ break;
+ }
+#endif
while (*s != '~') {
s++;
}
@@ -1142,6 +1279,24 @@ CFont::ParseToken(wchar *s, bool japShit)
case 'r': SetColor(CRGBA(113, 43, 73, 255)); break;
case 'w': SetColor(CRGBA(175, 175, 175, 255)); break;
case 'y': SetColor(CRGBA(210, 196, 106, 255)); break;
+#ifdef BUTTON_ICONS
+#if 0 // unused
+ case 'U': PS2Symbol = BUTTON_UP; break;
+ case 'D': PS2Symbol = BUTTON_DOWN; break;
+ case '<': PS2Symbol = BUTTON_LEFT; break;
+ case '>': PS2Symbol = BUTTON_RIGHT; break;
+#endif
+ case 'X': PS2Symbol = BUTTON_CROSS; break;
+ case 'O': PS2Symbol = BUTTON_CIRCLE; break;
+ case 'Q': PS2Symbol = BUTTON_SQUARE; break;
+ case 'T': PS2Symbol = BUTTON_TRIANGLE; break;
+ case 'K': PS2Symbol = BUTTON_L1; break;
+ case 'M': PS2Symbol = BUTTON_L2; break;
+ case 'A': PS2Symbol = BUTTON_L3; break;
+ case 'J': PS2Symbol = BUTTON_R1; break;
+ case 'V': PS2Symbol = BUTTON_R2; break;
+ case 'C': PS2Symbol = BUTTON_R3; break;
+#endif
}
} else if (IsJapanese()) {
if ((*s & 0x7FFF) == 'N' || (*s & 0x7FFF) == 'n')
@@ -1186,6 +1341,24 @@ CFont::ParseToken(wchar *s)
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;
+ case 'D': PS2Symbol = BUTTON_DOWN; break;
+ case '<': PS2Symbol = BUTTON_LEFT; break;
+ case '>': PS2Symbol = BUTTON_RIGHT; break;
+#endif
+ case 'X': PS2Symbol = BUTTON_CROSS; break;
+ case 'O': PS2Symbol = BUTTON_CIRCLE; break;
+ case 'Q': PS2Symbol = BUTTON_SQUARE; break;
+ case 'T': PS2Symbol = BUTTON_TRIANGLE; break;
+ case 'K': PS2Symbol = BUTTON_L1; break;
+ case 'M': PS2Symbol = BUTTON_L2; break;
+ case 'A': PS2Symbol = BUTTON_L3; break;
+ case 'J': PS2Symbol = BUTTON_R1; break;
+ case 'V': PS2Symbol = BUTTON_R2; break;
+ case 'C': PS2Symbol = BUTTON_R3; break;
+#endif
}
while(*s != '~') s++;
if (*(++s) == '~')
@@ -1356,6 +1529,10 @@ CFont::RenderFontBuffer()
PrintChar(textPosX + 2.0f, textPosY, c);
textPosX += 2.0f;
}
+#ifdef FIX_BUGS
+ // PS2 uses different chars for some symbols
+ if (!RenderState.bFontHalfTexture && c == 30) c = 61; // wanted star
+#endif
textPosX += RenderState.scaleX * (RenderState.proportional ? Size[RenderState.style][c] : Size[RenderState.style][209]);
if (c == '\0')
textPosX += RenderState.fExtraSpace;
@@ -1437,3 +1614,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 47a39f73..d61ca6e7 100644
--- a/src/render/Font.h
+++ b/src/render/Font.h
@@ -91,6 +91,31 @@ enum
#define FONT_LOCALE(style) (style)
#endif
+#ifdef BUTTON_ICONS
+enum
+{
+ BUTTON_NONE = -1,
+#if 0 // unused
+ BUTTON_UP,
+ BUTTON_DOWN,
+ BUTTON_LEFT,
+ BUTTON_RIGHT,
+#endif
+ BUTTON_CROSS,
+ BUTTON_CIRCLE,
+ BUTTON_SQUARE,
+ BUTTON_TRIANGLE,
+ BUTTON_L1,
+ BUTTON_L2,
+ BUTTON_L3,
+ BUTTON_R1,
+ BUTTON_R2,
+ BUTTON_R3,
+ MAX_BUTTON_ICONS
+};
+#endif // BUTTON_ICONS
+
+
class CFont
{
#ifdef MORE_LANGUAGES
@@ -106,11 +131,24 @@ public:
static CFontDetails Details;
static CFontRenderState RenderState;
+#ifdef BUTTON_ICONS
+ static int32 ButtonsSlot;
+ static CSprite2d ButtonSprite[MAX_BUTTON_ICONS];
+ static int PS2Symbol;
+
+ static void DrawButton(float x, float y);
+#endif // BUTTON_ICONS
+
+
static void Initialise(void);
static void Shutdown(void);
static void InitPerFrame(void);
static void PrintChar(float x, float y, wchar c);
static void PrintString(float x, float y, wchar *s);
+#ifdef XBOX_SUBTITLES
+ static void PrintStringFromBottom(float x, float y, wchar *str);
+ static void PrintOutlinedString(float x, float y, wchar *str, float outlineStrength, bool fromBottom, CRGBA outlineColor);
+#endif
static int GetNumberLines(float xstart, float ystart, wchar *s);
static void GetTextRect(CRect *rect, float xstart, float ystart, wchar *s);
#ifdef MORE_LANGUAGES
@@ -200,6 +238,7 @@ public:
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 536d94e0..a11495a9 100644
--- a/src/render/Glass.cpp
+++ b/src/render/Glass.cpp
@@ -1,4 +1,4 @@
-#include "common.h"
+#include "common.h"
#include "Glass.h"
#include "Timer.h"
@@ -150,7 +150,11 @@ CFallingGlassPane::Render(void)
fwdNorm.Normalise();
uint8 alpha = CGlass::CalcAlphaWithNormal(&fwdNorm);
- int32 time = clamp(CTimer::GetTimeInMilliseconds() - m_nTimer, 0, 500);
+#ifdef FIX_BUGS
+ uint16 time = clamp(CTimer::GetTimeInMilliseconds() > m_nTimer ? CTimer::GetTimeInMilliseconds() - m_nTimer : 0u, 0u, 500u);
+#else
+ uint16 time = clamp(CTimer::GetTimeInMilliseconds() - m_nTimer, 0, 500);
+#endif
uint8 color = int32( float(alpha) * (float(time) / 500) );
diff --git a/src/render/Hud.cpp b/src/render/Hud.cpp
index 239d0de4..c4e78a91 100644
--- a/src/render/Hud.cpp
+++ b/src/render/Hud.cpp
@@ -1172,6 +1172,10 @@ void CHud::Draw()
onceItWasWidescreen = true;
if (FrontEndMenuManager.m_PrefsShowSubtitles || !CCutsceneMgr::IsRunning()) {
+#ifdef CUTSCENE_BORDERS_SWITCH
+ if (!FrontEndMenuManager.m_PrefsCutsceneBorders)
+ CFont::SetDropShadowPosition(2);
+#endif
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);
@@ -1558,15 +1562,8 @@ void CHud::DrawAfterFade()
CFont::SetFontStyle(FONT_LOCALE(FONT_STANDARD));
CFont::SetDropShadowPosition(2);
CFont::SetDropColor(CRGBA(0, 0, 0, 255));
-#ifdef BETA_SLIDING_TEXT
-
- CFont::SetColor(ODDJOB2_COLOR);
- CFont::PrintString(SCREEN_WIDTH / 2 - SCREEN_SCALE_X(OddJob2XOffset), SCREEN_SCALE_Y(217.0f), m_BigMessage[5]);
-#else
-
CFont::SetColor(ODDJOB2_COLOR);
CFont::PrintString(SCREEN_WIDTH / 2, SCREEN_SCALE_Y(217.0f), m_BigMessage[5]);
-#endif
}
}
@@ -1615,11 +1612,7 @@ void CHud::DrawAfterFade()
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]));
-#ifdef BETA_SLIDING_TEXT
- CFont::PrintString(BigMessageX[1], SCREEN_SCALE_FROM_BOTTOM(140.0f), m_BigMessage[1]);
-#else
CFont::PrintString(SCREEN_SCALE_FROM_RIGHT(20.0f), SCREEN_SCALE_FROM_BOTTOM(140.0f), m_BigMessage[1]);
-#endif
} else {
m_ZoneFadeTimer = 0;
BigMessageX[1] = SCREEN_SCALE_FROM_RIGHT(DEFAULT_SCREEN_WIDTH + 60.0f);
diff --git a/src/render/MBlur.cpp b/src/render/MBlur.cpp
index 08298a1f..44d4f1d4 100644
--- a/src/render/MBlur.cpp
+++ b/src/render/MBlur.cpp
@@ -7,10 +7,15 @@
#include <d3d8caps.h>
#endif
+#include "General.h"
#include "RwHelper.h"
#include "Camera.h"
-#include "MBlur.h"
+#include "Timecycle.h"
+#include "Particle.h"
#include "Timer.h"
+#include "Hud.h"
+#include "Frontend.h"
+#include "MBlur.h"
#include "postfx.h"
// Originally taken from RW example 'mblur'
@@ -21,6 +26,8 @@ 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 };
@@ -244,6 +251,84 @@ CMBlur::CreateImmediateModeData(RwCamera *cam, RwRect *rect)
}
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
CMBlur::MotionBlurRender(RwCamera *cam, uint32 red, uint32 green, uint32 blue, uint32 blur, int32 type, uint32 bluralpha)
{
#ifdef EXTENDED_COLOURFILTER
@@ -415,7 +500,8 @@ CMBlur::OverlayRender(RwCamera *cam, RwRaster *raster, RwRGBA color, int32 type,
RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, Vertex, 4, Index, 6);
}
- // TODO(MIAMI): OverlayRenderFx
+ if(type != MOTION_BLUR_SNIPER)
+ OverlayRenderFx(cam, pFrontBuffer);
RwRenderStateSet(rwRENDERSTATEFOGENABLE, (void*)FALSE);
RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE);
@@ -437,4 +523,277 @@ CMBlur::ClearDrunkBlur()
{
Drunkness = 0.0f;
CTimer::SetTimeScale(1.0f);
-} \ No newline at end of file
+}
+
+#define NUM_RENDER_FX 64
+
+static RwRect fxRect[NUM_RENDER_FX];
+static FxType fxType[NUM_RENDER_FX];
+static float fxZ[NUM_RENDER_FX];
+
+bool
+CMBlur::PosInside(RwRect *rect, float x1, float y1, float x2, float y2)
+{
+ if((rect->x < x1 - 10.0f || rect->x > x2 + 10.0f || rect->y < y1 - 10.0f || rect->y > y2 + 10.0f) &&
+ (rect->w < x1 - 10.0f || rect->w > x2 + 10.0f || rect->h < y1 - 10.0f || rect->h > y2 + 10.0f) &&
+ (rect->x < x1 - 10.0f || rect->x > x2 + 10.0f || rect->h < y1 - 10.0f || rect->h > y2 + 10.0f) &&
+ (rect->w < x1 - 10.0f || rect->w > x2 + 10.0f || rect->y < y1 - 10.0f || rect->y > y2 + 10.0f))
+ return false;
+ return true;
+}
+
+bool
+CMBlur::AddRenderFx(RwCamera *cam, RwRect *rect, float z, FxType type)
+{
+ if(pBufVertCount >= NUM_RENDER_FX)
+ return false;
+
+ rect->x = Max(rect->x, 0);
+ rect->y = Max(rect->y, 0);
+ rect->w = Min(rect->w, SCREEN_WIDTH);
+ rect->h = Min(rect->h, SCREEN_HEIGHT);
+ if(rect->x >= rect->w || rect->y >= rect->h)
+ return false;
+
+ switch(type){
+ case FXTYPE_WATER1:
+ case FXTYPE_WATER2:
+ case FXTYPE_BLOOD1:
+ case FXTYPE_BLOOD2:
+ case FXTYPE_HEATHAZE: // code seems to be duplicated for this case
+ for(int i = 0; i < pBufVertCount; i++)
+ if(fxType[i] == type && PosInside(rect, fxRect[i].x-10.0f, fxRect[i].y-10.0f, fxRect[i].w+10.0f, fxRect[i].h+10.0f))
+ return false;
+ // TODO: fix aspect ratio scaling
+ // radar
+ if(PosInside(rect, 40.0f, SCREEN_SCALE_FROM_BOTTOM(116.0f), 40.0f + SCREEN_SCALE_X(94.0f), SCREEN_SCALE_FROM_BOTTOM(116.0f - 76.0f)))
+ return false;
+ // HUD
+ if(PosInside(rect, 400.0f, 0.0f, SCREEN_WIDTH, 90.0f))
+ return false;
+ // vehicle name
+ if(CHud::m_VehicleState != 0 && PosInside(rect, SCREEN_WIDTH/2, 350.0f, SCREEN_WIDTH, SCREEN_HEIGHT))
+ return false;
+ // zone name
+ if(CHud::m_ZoneState != 0 && PosInside(rect, SCREEN_WIDTH/2, 350.0f, SCREEN_WIDTH, SCREEN_HEIGHT))
+ return false;
+ break;
+ }
+
+ fxRect[pBufVertCount] = *rect;
+ fxZ[pBufVertCount] = z;
+ fxType[pBufVertCount] = type;
+ pBufVertCount++;
+
+ return true;
+}
+
+void
+CMBlur::OverlayRenderFx(RwCamera *cam, RwRaster *frontBuf)
+{
+ bool drawWaterDrops = false;
+ RwIm2DVertex verts[4];
+ int red = (0.75f*CTimeCycle::GetDirectionalRed() + CTimeCycle::GetAmbientRed())*0.55f * 255;
+ int green = (0.75f*CTimeCycle::GetDirectionalGreen() + CTimeCycle::GetAmbientGreen())*0.55f * 255;
+ int blue = (0.75f*CTimeCycle::GetDirectionalBlue() + CTimeCycle::GetAmbientBlue())*0.55f * 255;
+ red = clamp(red, 0, 255);
+ green = clamp(green, 0, 255);
+ blue = clamp(blue, 0, 255);
+
+ RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)TRUE);
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)TRUE);
+
+#ifdef LIBRW
+ rw::SetRenderState(rw::STENCILENABLE, TRUE);
+#else
+ RwD3D8SetRenderState(D3DRS_STENCILENABLE, TRUE);
+#endif
+
+ for(int i = 0; i < pBufVertCount; i++)
+ switch(fxType[i]){
+ case FXTYPE_WATER1:
+ case FXTYPE_WATER2:
+ case FXTYPE_BLOOD1:
+ case FXTYPE_BLOOD2: {
+ drawWaterDrops = true;
+ int32 width = Pow(2.0f, int32(log2(RwRasterGetWidth (RwCameraGetRaster(cam))))+1);
+ int32 height = Pow(2.0f, int32(log2(RwRasterGetHeight(RwCameraGetRaster(cam))))+1);
+
+ float u1Off = (fxRect[i].w - fxRect[i].x)/width;
+ float u2Off = u1Off - (fxRect[i].w - fxRect[i].x + 0.5f)*0.66f/width;
+ float halfHeight = (fxRect[i].h - fxRect[i].y + 0.5f)*0.25f/height;
+
+ if(RwRasterGetDepth(RwCameraGetRaster(cam)) == 16){
+ if(fxType[i] == FXTYPE_BLOOD1 || fxType[i] == FXTYPE_BLOOD2)
+ CreateImmediateModeData(cam, &fxRect[i], verts, CRGBA(255, 0, 0, 128), 0.0f, 0.0f, 0.0f, 0.0f, fxZ[i], true);
+ else
+ CreateImmediateModeData(cam, &fxRect[i], verts, CRGBA(32, 32, 32, 225), 0.0f, 0.0f, 0.0f, 0.0f, fxZ[i], true);
+ }else{
+ CreateImmediateModeData(cam, &fxRect[i], verts, CRGBA(32, 32, 32, 225), 0.0f, 0.0f, 0.0f, 0.0f, fxZ[i], true);
+ }
+
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpDotRaster);
+#ifdef LIBRW
+ rw::SetRenderState(rw::STENCILFUNCTION, rw::STENCILALWAYS);
+ rw::SetRenderState(rw::STENCILFUNCTIONREF, 1);
+ rw::SetRenderState(rw::STENCILFUNCTIONMASK, 0xFFFFFFFF);
+ rw::SetRenderState(rw::STENCILFUNCTIONWRITEMASK, 0xFFFFFFFF);
+ rw::SetRenderState(rw::STENCILZFAIL, rw::STENCILKEEP);
+ rw::SetRenderState(rw::STENCILFAIL, rw::STENCILKEEP);
+ rw::SetRenderState(rw::STENCILPASS, rw::STENCILREPLACE);
+#else
+ RwD3D8SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS);
+ RwD3D8SetRenderState(D3DRS_STENCILREF, 1);
+ RwD3D8SetRenderState(D3DRS_STENCILMASK, 0xFFFFFFFF);
+ RwD3D8SetRenderState(D3DRS_STENCILWRITEMASK, 0xFFFFFFFF);
+ RwD3D8SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
+ RwD3D8SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
+ RwD3D8SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
+#endif
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE);
+ RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, verts, 4, Index, 6);
+
+ if(RwRasterGetDepth(RwCameraGetRaster(cam)) != 16){
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, frontBuf);
+#ifdef LIBRW
+ rw::SetRenderState(rw::STENCILFUNCTION, rw::STENCILEQUAL);
+ rw::SetRenderState(rw::STENCILPASS, rw::STENCILKEEP);
+#else
+ RwD3D8SetRenderState(D3DRS_STENCILFUNC, D3DCMP_EQUAL);
+ RwD3D8SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
+#endif
+ if(BlurOn){
+ if(fxType[i] == FXTYPE_BLOOD1 || fxType[i] == FXTYPE_BLOOD2)
+ CreateImmediateModeData(cam, &fxRect[i], verts, CRGBA(255, 0, 0, 255), u1Off, 0.0f+halfHeight, u2Off, 0.0f-halfHeight, fxZ[i], false);
+ else
+ CreateImmediateModeData(cam, &fxRect[i], verts, CRGBA(225, 225, 225, 160), u1Off, 0.0f+halfHeight, u2Off, 0.0f-halfHeight, fxZ[i], false);
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDDESTALPHA);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVDESTALPHA);
+ }else{
+ if(fxType[i] == FXTYPE_BLOOD1 || fxType[i] == FXTYPE_BLOOD2)
+ CreateImmediateModeData(cam, &fxRect[i], verts, CRGBA(255, 0, 0, 128), u1Off, 0.0f+halfHeight, u2Off, 0.0f-halfHeight, fxZ[i], false);
+ else
+ CreateImmediateModeData(cam, &fxRect[i], verts, CRGBA(128, 128, 128, 32), u1Off, 0.0f+halfHeight, u2Off, 0.0f-halfHeight, fxZ[i], false);
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
+ }
+ RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, verts, 4, Index, 6);
+ }
+ break;
+ }
+ case FXTYPE_SPLASH1:
+ case FXTYPE_SPLASH2:
+ case FXTYPE_SPLASH3:
+ drawWaterDrops = true;
+ break;
+
+ case FXTYPE_HEATHAZE:
+ if(TheCamera.GetScreenFadeStatus() == FADE_0 && frontBuf){
+ int alpha = FrontEndMenuManager.m_PrefsBrightness > 255 ?
+ FrontEndMenuManager.m_PrefsBrightness - 90 :
+ FrontEndMenuManager.m_PrefsBrightness - 130;
+ alpha = clamp(alpha, 16, 200)/2;
+
+ CreateImmediateModeData(cam, &fxRect[i], verts, CRGBA(0, 0, 0, alpha), 0.0f, 0.0f, 0.0f, 0.0f, fxZ[i], true);
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpHeatHazeRaster);
+#ifdef LIBRW
+ rw::SetRenderState(rw::STENCILFUNCTION, rw::STENCILALWAYS);
+ rw::SetRenderState(rw::STENCILFUNCTIONREF, 1);
+ rw::SetRenderState(rw::STENCILFUNCTIONMASK, 0xFFFFFFFF);
+ rw::SetRenderState(rw::STENCILFUNCTIONWRITEMASK, 0xFFFFFFFF);
+ rw::SetRenderState(rw::STENCILZFAIL, rw::STENCILKEEP);
+ rw::SetRenderState(rw::STENCILFAIL, rw::STENCILKEEP);
+ rw::SetRenderState(rw::STENCILPASS, rw::STENCILREPLACE);
+#else
+ RwD3D8SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS);
+ RwD3D8SetRenderState(D3DRS_STENCILREF, 1);
+ RwD3D8SetRenderState(D3DRS_STENCILMASK, 0xFFFFFFFF);
+ RwD3D8SetRenderState(D3DRS_STENCILWRITEMASK, 0xFFFFFFFF);
+ RwD3D8SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
+ RwD3D8SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
+ RwD3D8SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
+#endif
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE);
+ RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, verts, 4, Index, 6);
+
+ CreateImmediateModeData(cam, &fxRect[i], verts, CRGBA(255, 255, 255, alpha),
+ CGeneral::GetRandomNumberInRange(-0.002f, 0.002f),
+ CGeneral::GetRandomNumberInRange(-0.002f, 0.002f),
+ CGeneral::GetRandomNumberInRange(-0.002f, 0.002f),
+ CGeneral::GetRandomNumberInRange(-0.002f, 0.002f),
+ fxZ[i], false);
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, frontBuf);
+#ifdef LIBRW
+ rw::SetRenderState(rw::STENCILFUNCTION, rw::STENCILEQUAL);
+ rw::SetRenderState(rw::STENCILPASS, rw::STENCILKEEP);
+#else
+ RwD3D8SetRenderState(D3DRS_STENCILFUNC, D3DCMP_EQUAL);
+ RwD3D8SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
+#endif
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
+ RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, verts, 4, Index, 6);
+ }
+ break;
+ }
+#ifdef LIBRW
+ rw::SetRenderState(rw::STENCILENABLE, FALSE);
+#else
+ RwD3D8SetRenderState(D3DRS_STENCILENABLE, FALSE);
+#endif
+
+ if(drawWaterDrops){
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDONE);
+
+ // Draw drops
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpRainDripRaster[0]);
+ for(int i = 0; i < pBufVertCount; i++)
+ if(fxType[i] == FXTYPE_WATER1 || fxType[i] == FXTYPE_BLOOD1){
+ CreateImmediateModeData(cam, &fxRect[i], verts, CRGBA(red, green, blue, fxType[i] == FXTYPE_BLOOD1 ? 255 : 192),
+ 0.0f, 0.0f, 0.0f, 0.0f, fxZ[i], true);
+ RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, verts, 4, Index, 6);
+ }
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpRainDripRaster[1]);
+ for(int i = 0; i < pBufVertCount; i++)
+ if(fxType[i] == FXTYPE_WATER2 || fxType[i] == FXTYPE_BLOOD2){
+ CreateImmediateModeData(cam, &fxRect[i], verts, CRGBA(red, green, blue, fxType[i] == FXTYPE_BLOOD2 ? 255 : 192),
+ 0.0f, 0.0f, 0.0f, 0.0f, fxZ[i], true);
+ RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, verts, 4, Index, 6);
+ }
+
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpCarSplashRaster[0]);
+ for(int i = 0; i < pBufVertCount; i++)
+ if(fxType[i] == FXTYPE_SPLASH1 || fxType[i] == FXTYPE_SPLASH2 || fxType[i] == FXTYPE_SPLASH3){
+ CreateImmediateModeData(cam, &fxRect[i], verts, CRGBA(200, 200, 200, 255),
+ 0.0f, 0.0f, 0.0f, 0.0f, fxZ[i], true);
+ RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, verts, 4, Index, 6);
+ }
+
+ // Darken the water drops
+ int alpha = 192*0.5f;
+ RwRenderStateSet(rwRENDERSTATESRCBLEND, (void*)rwBLENDSRCALPHA);
+ RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void*)rwBLENDINVSRCALPHA);
+
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpRainDripDarkRaster[0]);
+ for(int i = 0; i < pBufVertCount; i++)
+ if(fxType[i] == FXTYPE_WATER1){
+ CreateImmediateModeData(cam, &fxRect[i], verts, CRGBA(red, green, blue, alpha),
+ 0.0f, 0.0f, 0.0f, 0.0f, fxZ[i], true);
+ RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, verts, 4, Index, 6);
+ }
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, gpRainDripDarkRaster[1]);
+ for(int i = 0; i < pBufVertCount; i++)
+ if(fxType[i] == FXTYPE_WATER2){
+ CreateImmediateModeData(cam, &fxRect[i], verts, CRGBA(red, green, blue, alpha),
+ 0.0f, 0.0f, 0.0f, 0.0f, fxZ[i], true);
+ RwIm2DRenderIndexedPrimitive(rwPRIMTYPETRILIST, verts, 4, Index, 6);
+ }
+ }
+
+ RwRenderStateSet(rwRENDERSTATEZTESTENABLE, (void*)FALSE);
+ RwRenderStateSet(rwRENDERSTATEVERTEXALPHAENABLE, (void*)FALSE);
+ pBufVertCount = 0;
+}
diff --git a/src/render/MBlur.h b/src/render/MBlur.h
index c2572256..3dc53082 100644
--- a/src/render/MBlur.h
+++ b/src/render/MBlur.h
@@ -2,12 +2,14 @@
enum FxType
{
- FXTYPE_0 = 0,
- FXTYPE_1,
- FXTYPE_2,
- FXTYPE_3,
- FXTYPE_4,
- FXTYPE_5,
+ FXTYPE_WATER1,
+ FXTYPE_WATER2,
+ FXTYPE_BLOOD1,
+ FXTYPE_BLOOD2,
+ FXTYPE_HEATHAZE,
+ FXTYPE_SPLASH1,
+ FXTYPE_SPLASH2,
+ FXTYPE_SPLASH3
};
class CMBlur
@@ -19,16 +21,19 @@ public:
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();
- //TODO
- static void AddRenderFx(RwCamera *,RwRect *,float,FxType)
- {}
+ 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
index 79ce0461..2b15e75b 100644
--- a/src/render/Occlusion.cpp
+++ b/src/render/Occlusion.cpp
@@ -1,6 +1,7 @@
#include "common.h"
#include "main.h"
+#include "Entity.h"
#include "Occlusion.h"
#include "Game.h"
#include "Camera.h"
@@ -292,6 +293,11 @@ COcclusion::ProcessBeforeRendering(void)
{
NumActiveOccluders = 0;
+#ifndef MASTER
+ if (gbModelViewer)
+ return;
+#endif
+
if (CGame::currArea != AREA_MAIN_MAP)
return;
@@ -488,3 +494,36 @@ void COcclusion::Render() {
DefinedState();
}
#endif
+
+bool CEntity::IsEntityOccluded(void) {
+
+ CVector coors;
+ float width, height;
+
+ if (COcclusion::NumActiveOccluders == 0 || !CalcScreenCoors(GetBoundCentre(), &coors, &width, &height))
+ return false;
+
+ float area = Max(width, height) * GetBoundRadius() * 0.9f;
+
+ for (int i = 0; i < COcclusion::NumActiveOccluders; i++) {
+ if (coors.z - (GetBoundRadius() * 0.85f) > COcclusion::aActiveOccluders[i].radius) {
+ if (COcclusion::aActiveOccluders[i].IsPointWithinOcclusionArea(coors.x, coors.y, area)) {
+ return true;
+ }
+
+ if (COcclusion::aActiveOccluders[i].IsPointWithinOcclusionArea(coors.x, coors.y, 0.0f)) {
+ CVector min = m_matrix * CModelInfo::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;
+} \ No newline at end of file
diff --git a/src/render/Particle.cpp b/src/render/Particle.cpp
index 6a42bc4d..0ad4681d 100644
--- a/src/render/Particle.cpp
+++ b/src/render/Particle.cpp
@@ -213,19 +213,19 @@ RwTexture *gpSparkTex;
RwTexture *gpNewspaperTex;
RwTexture *gpGunSmokeTex;
RwTexture *gpDotTex;
-RwTexture *gpHeathazeTex;
+RwTexture *gpHeatHazeTex;
RwTexture *gpBeastieTex;
-RwTexture *gpRaindripTex1[MAX_RAINDRIP_FILES];
-RwTexture *gpRaindripTex2[MAX_RAINDRIP_FILES];
+RwTexture *gpRainDripTex[MAX_RAINDRIP_FILES];
+RwTexture *gpRainDripDarkTex[MAX_RAINDRIP_FILES];
RwRaster *gpSparkRaster;
RwRaster *gpNewspaperRaster;
RwRaster *gpGunSmokeRaster;
RwRaster *gpDotRaster;
-RwRaster *gpHeathazeRaster;
+RwRaster *gpHeatHazeRaster;
RwRaster *gpBeastieRaster;
-RwRaster *gpRaindripRaster1[MAX_RAINDRIP_FILES];
-RwRaster *gpRaindripRaster2[MAX_RAINDRIP_FILES];
+RwRaster *gpRainDripRaster[MAX_RAINDRIP_FILES];
+RwRaster *gpRainDripDarkRaster[MAX_RAINDRIP_FILES];
float CParticle::ms_afRandTable[CParticle::RAND_TABLE_SIZE];
CParticle *CParticle::m_pUnusedListHead;
@@ -411,9 +411,11 @@ void CParticle::Initialise()
gpFlame5Tex = RwTextureRead("flame5", nil);
-#ifdef FIX_BUGS
+//#ifdef FIX_BUGS
+#if 0
gpFlame5Raster = RwTextureGetRaster(gpFlame5Tex);
#else
+ // this seems to have become more of a design choice
gpFlame5Raster = RwTextureGetRaster(gpFlame1Tex); // copy-paste bug ?
#endif
@@ -465,23 +467,23 @@ void CParticle::Initialise()
gpDotTex = RwTextureRead("dot", nil);
gpDotRaster = RwTextureGetRaster(gpDotTex);
- gpHeathazeTex = RwTextureRead("heathaze", nil);
- gpHeathazeRaster = RwTextureGetRaster(gpHeathazeTex);
+ gpHeatHazeTex = RwTextureRead("heathaze", nil);
+ gpHeatHazeRaster = RwTextureGetRaster(gpHeatHazeTex);
gpBeastieTex = RwTextureRead("beastie", nil);
gpBeastieRaster = RwTextureGetRaster(gpBeastieTex);
- gpRaindripTex1[0] = RwTextureRead("raindrip64", nil);
- gpRaindripRaster1[0] = RwTextureGetRaster(gpRaindripTex1[0]);
+ gpRainDripTex[0] = RwTextureRead("raindrip64", nil);
+ gpRainDripRaster[0] = RwTextureGetRaster(gpRainDripTex[0]);
- gpRaindripTex1[1] = RwTextureRead("raindripb64", nil);
- gpRaindripRaster1[1] = RwTextureGetRaster(gpRaindripTex1[1]);
+ gpRainDripTex[1] = RwTextureRead("raindripb64", nil);
+ gpRainDripRaster[1] = RwTextureGetRaster(gpRainDripTex[1]);
- gpRaindripTex2[0] = RwTextureRead("raindrip64_d", nil);
- gpRaindripRaster2[0] = RwTextureGetRaster(gpRaindripTex2[0]);
+ gpRainDripDarkTex[0] = RwTextureRead("raindrip64_d", nil);
+ gpRainDripDarkRaster[0] = RwTextureGetRaster(gpRainDripDarkTex[0]);
- gpRaindripTex2[1] = RwTextureRead("raindripb64_d", nil);
- gpRaindripRaster2[1] = RwTextureGetRaster(gpRaindripTex2[1]);
+ gpRainDripDarkTex[1] = RwTextureRead("raindripb64_d", nil);
+ gpRainDripDarkRaster[1] = RwTextureGetRaster(gpRainDripDarkTex[1]);
CTxdStore::PopCurrentTxd();
@@ -586,7 +588,7 @@ void CParticle::Initialise()
break;
case PARTICLE_TEARGAS:
- entry->m_ppRaster = &gpHeathazeRaster;
+ entry->m_ppRaster = &gpHeatHazeRaster;
break;
case PARTICLE_SHARD:
@@ -749,11 +751,11 @@ void CParticle::Shutdown()
for ( int32 i = 0; i < MAX_RAINDRIP_FILES; i++ )
{
- RwTextureDestroy(gpRaindripTex1[i]);
- gpRaindripTex1[i] = nil;
+ RwTextureDestroy(gpRainDripTex[i]);
+ gpRainDripTex[i] = nil;
- RwTextureDestroy(gpRaindripTex2[i]);
- gpRaindripTex2[i] = nil;
+ RwTextureDestroy(gpRainDripDarkTex[i]);
+ gpRainDripDarkTex[i] = nil;
}
RwTextureDestroy(gpBoatWakeTex);
@@ -812,8 +814,8 @@ void CParticle::Shutdown()
RwTextureDestroy(gpDotTex);
gpDotTex = nil;
- RwTextureDestroy(gpHeathazeTex);
- gpHeathazeTex = nil;
+ RwTextureDestroy(gpHeatHazeTex);
+ gpHeatHazeTex = nil;
RwTextureDestroy(gpBeastieTex);
gpBeastieTex = nil;
@@ -941,7 +943,7 @@ CParticle *CParticle::AddParticle(tParticleType type, CVector const &vecPos, CVe
CVector screen;
float w, h;
- if ( !CSprite::CalcScreenCoors(vecPos, screen, &w, &h, true) )
+ if ( !CSprite::CalcScreenCoors(vecPos, &screen, &w, &h, true) )
return nil;
pParticle->m_vecPosition = screen;
@@ -1913,9 +1915,9 @@ void CParticle::Render()
FxType fxtype;
if ( particle->m_nCurrentFrame != 0 )
- fxtype = FXTYPE_1;
+ fxtype = FXTYPE_WATER2;
else
- fxtype = FXTYPE_0;
+ fxtype = FXTYPE_WATER1;
CMBlur::AddRenderFx(Scene.camera, &rect, screenZ, fxtype);
@@ -1939,9 +1941,9 @@ void CParticle::Render()
FxType fxtype;
if ( particle->m_nCurrentFrame )
- fxtype = FXTYPE_3;
+ fxtype = FXTYPE_BLOOD2;
else
- fxtype = FXTYPE_2;
+ fxtype = FXTYPE_BLOOD1;
CMBlur::AddRenderFx(Scene.camera, &rect, screenZ, fxtype);
@@ -1957,7 +1959,7 @@ void CParticle::Render()
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_4);
+ CMBlur::AddRenderFx(Scene.camera, &rect, screenZ, FXTYPE_HEATHAZE);
canDraw = false;
}
@@ -1993,7 +1995,7 @@ void CParticle::Render()
break;
}
- CMBlur::AddRenderFx(Scene.camera, &rect, screenZ, FXTYPE_4);
+ CMBlur::AddRenderFx(Scene.camera, &rect, screenZ, FXTYPE_HEATHAZE);
canDraw = false;
}
@@ -2034,7 +2036,7 @@ void CParticle::Render()
float w;
float h;
- if ( CSprite::CalcScreenCoors(particle->m_vecPosition, coors, &w, &h, true) )
+ if ( CSprite::CalcScreenCoors(particle->m_vecPosition, &coors, &w, &h, true) )
{
if ( i == PARTICLE_ENGINE_STEAM
@@ -2115,7 +2117,7 @@ void CParticle::Render()
* (CSprite::GetFarScreenZ() - CSprite::GetNearScreenZ()) * CDraw::GetFarClipZ()
/ ( (CDraw::GetFarClipZ() - CDraw::GetNearClipZ()) * coors.z ) + CSprite::GetNearScreenZ();
- CMBlur::AddRenderFx(Scene.camera, &rect, screenZ, FXTYPE_5);
+ CMBlur::AddRenderFx(Scene.camera, &rect, screenZ, FXTYPE_SPLASH1);
}
else
{
@@ -2189,7 +2191,7 @@ void CParticle::Render()
float fTrailLength;
CVector vecScreenPosition;
- if ( CSprite::CalcScreenCoors(vecPrevPos, vecScreenPosition, &fTrailLength, &fRotation, true) )
+ if ( CSprite::CalcScreenCoors(vecPrevPos, &vecScreenPosition, &fTrailLength, &fRotation, true) )
{
CVector2D vecDist
(
@@ -2470,3 +2472,43 @@ void CParticle::HandleShootableBirdsStuff(CEntity *entity, CVector const&camPos)
}
}
+
+void
+CEntity::AddSteamsFromGround(CVector *unused)
+{
+ int i, n;
+ C2dEffect *effect;
+ CVector pos;
+
+ n = CModelInfo::GetModelInfo(GetModelIndex())->GetNum2dEffects();
+ for(i = 0; i < n; i++){
+ effect = CModelInfo::GetModelInfo(GetModelIndex())->Get2dEffect(i);
+ if(effect->type != EFFECT_PARTICLE)
+ continue;
+
+ pos = GetMatrix() * effect->pos;
+ switch(effect->particle.particleType){
+ case 0:
+ CParticleObject::AddObject(POBJECT_PAVEMENT_STEAM, pos, effect->particle.dir, effect->particle.scale, false);
+ break;
+ case 1:
+ CParticleObject::AddObject(POBJECT_WALL_STEAM, pos, effect->particle.dir, effect->particle.scale, false);
+ break;
+ case 2:
+ CParticleObject::AddObject(POBJECT_DRY_ICE, pos, effect->particle.scale, false);
+ break;
+ case 3:
+ CParticleObject::AddObject(POBJECT_SMALL_FIRE, pos, effect->particle.dir, effect->particle.scale, false);
+ break;
+ case 4:
+ CParticleObject::AddObject(POBJECT_DARK_SMOKE, pos, effect->particle.dir, effect->particle.scale, false);
+ break;
+ case 5:
+ CParticleObject::AddObject(POBJECT_WATER_FOUNTAIN_VERT, pos, effect->particle.dir, effect->particle.scale, false);
+ break;
+ case 6:
+ CParticleObject::AddObject(POBJECT_WATER_FOUNTAIN_HORIZ, pos, effect->particle.dir, effect->particle.scale, false);
+ break;
+ }
+ }
+}
diff --git a/src/render/Particle.h b/src/render/Particle.h
index 9c496fe1..5542dc02 100644
--- a/src/render/Particle.h
+++ b/src/render/Particle.h
@@ -99,5 +99,10 @@ public:
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/PlayerSkin.cpp b/src/render/PlayerSkin.cpp
index 261bbec0..1626716f 100644
--- a/src/render/PlayerSkin.cpp
+++ b/src/render/PlayerSkin.cpp
@@ -14,6 +14,7 @@
#include "RwHelper.h"
#include "Timer.h"
#include "Lights.h"
+#include "MemoryMgr.h"
//--MIAMI: file done
@@ -75,6 +76,7 @@ LoadPlayerDff(void)
void
CPlayerSkin::Initialise(void)
{
+ // empty on PS2
m_txdSlot = CTxdStore::AddTxdSlot("skin");
CTxdStore::Create(m_txdSlot);
CTxdStore::AddRef(m_txdSlot);
@@ -83,6 +85,7 @@ CPlayerSkin::Initialise(void)
void
CPlayerSkin::Shutdown(void)
{
+ // empty on PS2
CTxdStore::RemoveTxdSlot(m_txdSlot);
}
diff --git a/src/render/PointLights.cpp b/src/render/PointLights.cpp
index b09b07bd..c8f21d21 100644
--- a/src/render/PointLights.cpp
+++ b/src/render/PointLights.cpp
@@ -239,7 +239,7 @@ 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::RenderBufferedOneXLUSprite_Rotate_Aspect(spriteCoors.x, spriteCoors.y, spriteCoors.z,
@@ -287,7 +287,7 @@ CPointLights::RenderFogEffect(void)
intensity *= 1.0f - sq(lightdist / FOG_AREA_RADIUS);
CVector fogcoors(xi, yi, groundZ + 1.6f);
- if(CSprite::CalcScreenCoors(fogcoors, spriteCoors, &spritew, &spriteh, true)){
+ if(CSprite::CalcScreenCoors(fogcoors, &spriteCoors, &spritew, &spriteh, true)) {
float rotation = (CTimer::GetTimeInMilliseconds()&0x3FFF) * 2*3.14f / 0x4000;
float size = FogSizes[r>>1];
CSprite::RenderBufferedOneXLUSprite_Rotate_Aspect(spriteCoors.x, spriteCoors.y, spriteCoors.z,
diff --git a/src/render/Renderer.cpp b/src/render/Renderer.cpp
index c2982d6d..660b05fe 100644
--- a/src/render/Renderer.cpp
+++ b/src/render/Renderer.cpp
@@ -24,9 +24,12 @@
#include "Occlusion.h"
#include "Renderer.h"
#include "custompipes.h"
+#include "Frontend.h"
//--MIAMI: file done
+bool gbShowPedRoadGroups;
+bool gbShowCarRoadGroups;
bool gbShowCollisionPolys;
bool gbShowCollisionLines;
bool gbBigWhiteDebugLightSwitchedOn;
@@ -37,6 +40,10 @@ bool gbDontRenderPeds;
bool gbDontRenderObjects;
bool gbDontRenderVehicles;
+// unused
+int16 TestCloseThings;
+int16 TestBigThings;
+
struct EntityInfo
{
CEntity *ent;
@@ -61,14 +68,10 @@ CVehicle *CRenderer::m_pFirstPersonVehicle;
bool CRenderer::m_loadingPriority;
float CRenderer::ms_lodDistScale = 1.2f;
-#ifdef FIX_BUGS
-#define LOD_DISTANCE (300.0f*TheCamera.LODDistMultiplier)
-#else
-#define LOD_DISTANCE 300.0f
-#endif
-#define FADE_DISTANCE 20.0f
-#define STREAM_DISTANCE 30.0f
-
+// unused
+BlockedRange CRenderer::aBlockedRanges[16];
+BlockedRange* CRenderer::pFullBlockedRanges;
+BlockedRange* CRenderer::pEmptyBlockedRanges;
void
CRenderer::Init(void)
@@ -346,45 +349,45 @@ enum {
static RwRGBAReal black;
-#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
SetStencilState(int state)
{
switch(state){
// disable stencil
case 0:
- rw::d3d::setRenderState(D3DRS_STENCILENABLE, FALSE);
+ rw::SetRenderState(rw::STENCILENABLE, FALSE);
break;
// test against stencil
case 1:
- rw::d3d::setRenderState(D3DRS_STENCILENABLE, TRUE);
- rw::d3d::setRenderState(D3DRS_STENCILFUNC, D3DCMP_NOTEQUAL);
- rw::d3d::setRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_KEEP);
- rw::d3d::setRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_KEEP);
- rw::d3d::setRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_KEEP);
- rw::d3d::setRenderState(D3DRS_STENCILMASK, 0xFF);
- rw::d3d::setRenderState(D3DRS_STENCILREF, 0xFF);
+ 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::d3d::setRenderState(D3DRS_STENCILENABLE, TRUE);
- rw::d3d::setRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS);
- rw::d3d::setRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE);
- rw::d3d::setRenderState(D3DRS_STENCILREF, 0xFF);
+ 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)
{
@@ -537,30 +540,6 @@ struct BuildingInst
static BuildingInst blendInsts[3][2000];
static int numBlendInsts[3];
-static void
-SetStencilState(int state)
-{
- switch(state){
- // disable stencil
- case 0:
- glDisable(GL_STENCIL_TEST);
- break;
- // test against stencil
- case 1:
- glEnable(GL_STENCIL_TEST);
- glStencilFunc(GL_NOTEQUAL, 0xFF, 0xFF);
- glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
- glStencilMask(0xFF);
- break;
- // write to stencil
- case 2:
- glEnable(GL_STENCIL_TEST);
- glStencilFunc(GL_ALWAYS, 0xFF, 0xFF);
- glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
- break;
- }
-}
-
static bool
IsTextureTransparent(RwTexture *tex)
{
@@ -711,12 +690,13 @@ 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());
- ent->bImBeingRendered = true; // TODO: this seems wrong, but do we even need it?
-
int pass = PASS_BLEND;
if(mi->m_additive) // very questionable
pass = PASS_ADD;
@@ -1188,7 +1168,7 @@ CRenderer::SetupBigBuildingVisibility(CEntity *ent)
if(RpAtomicGetGeometry(a) != RpAtomicGetGeometry(rwobj))
RpAtomicSetGeometry(rwobj, RpAtomicGetGeometry(a), rpATOMICSAMEBOUNDINGSPHERE); // originally 5 (mistake?)
mi->IncreaseAlpha();
- if(!ent->IsVisibleComplex() || ent->IsEntityOccluded()){
+ if(!ent->IsVisible() || !ent->GetIsOnScreenComplex() || ent->IsEntityOccluded()){
mi->m_alpha = 255;
return VIS_INVISIBLE;
}
@@ -1232,7 +1212,7 @@ CRenderer::SetupBigBuildingVisibility(CEntity *ent)
if(RpAtomicGetGeometry(a) != RpAtomicGetGeometry(rwobj))
RpAtomicSetGeometry(rwobj, RpAtomicGetGeometry(a), rpATOMICSAMEBOUNDINGSPHERE); // originally 5 (mistake?)
mi->IncreaseAlpha();
- if(!ent->IsVisibleComplex() || ent->IsEntityOccluded()){
+ if(!ent->IsVisible() || !ent->GetIsOnScreenComplex() || ent->IsEntityOccluded()){
mi->m_alpha = 255;
return VIS_INVISIBLE;
}
@@ -1253,7 +1233,21 @@ CRenderer::ConstructRenderList(void)
ms_nNoOfInVisibleEntities = 0;
}
ms_vecCameraPosition = TheCamera.GetPosition();
- // TODO: blocked ranges, but unused
+
+ // unused
+ pFullBlockedRanges = nil;
+ pEmptyBlockedRanges = aBlockedRanges;
+ for(int i = 0; i < 16; i++){
+ aBlockedRanges[i].prev = &aBlockedRanges[i-1];
+ aBlockedRanges[i].next = &aBlockedRanges[i+1];
+ }
+ aBlockedRanges[0].prev = nil;
+ aBlockedRanges[15].next = nil;
+
+ // unused
+ TestCloseThings = 0;
+ TestBigThings = 0;
+
ScanWorld();
}
@@ -1333,7 +1327,7 @@ CRenderer::ScanWorld(void)
vectors[CORNER_PRIO_RIGHT].x = vectors[CORNER_LOD_RIGHT].x * 0.2f;
vectors[CORNER_PRIO_RIGHT].y = vectors[CORNER_LOD_RIGHT].y * 0.2f;
vectors[CORNER_PRIO_RIGHT].z = vectors[CORNER_LOD_RIGHT].z;
- RwV3dTransformPoints((RwV3d*)vectors, (RwV3d*)vectors, 9, cammatrix);
+ RwV3dTransformPoints(vectors, vectors, 9, cammatrix);
m_loadingPriority = false;
if(TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOPDOWN ||
@@ -1403,8 +1397,19 @@ CRenderer::ScanWorld(void)
poly[2].y = CWorld::GetSectorY(vectors[CORNER_FAR_TOPRIGHT].y);
ScanSectorPoly(poly, 3, ScanSectorList);
}
-
- ScanBigBuildingList(CWorld::GetBigBuildingList(CGame::currLevel));
+
+#ifdef NO_ISLAND_LOADING
+ if (FrontEndMenuManager.m_PrefsIslandLoading == CMenuManager::ISLAND_LOADING_HIGH) {
+ ScanBigBuildingList(CWorld::GetBigBuildingList(LEVEL_BEACH));
+ ScanBigBuildingList(CWorld::GetBigBuildingList(LEVEL_MAINLAND));
+ } else
+#endif
+ {
+#ifdef FIX_BUGS
+ if(CCollision::ms_collisionInMemory != LEVEL_GENERIC)
+#endif
+ ScanBigBuildingList(CWorld::GetBigBuildingList(CGame::currLevel));
+ }
ScanBigBuildingList(CWorld::GetBigBuildingList(LEVEL_GENERIC));
}
}
@@ -1453,7 +1458,7 @@ CRenderer::RequestObjectsInFrustum(void)
vectors[CORNER_PRIO_RIGHT].x = vectors[CORNER_LOD_RIGHT].x * 0.2f;
vectors[CORNER_PRIO_RIGHT].y = vectors[CORNER_LOD_RIGHT].y * 0.2f;
vectors[CORNER_PRIO_RIGHT].z = vectors[CORNER_LOD_RIGHT].z;
- RwV3dTransformPoints((RwV3d*)vectors, (RwV3d*)vectors, 9, cammatrix);
+ RwV3dTransformPoints(vectors, vectors, 9, cammatrix);
if(TheCamera.Cams[TheCamera.ActiveCam].Mode == CCam::MODE_TOPDOWN ||
#ifdef FIX_BUGS
@@ -1492,6 +1497,56 @@ CRenderer::RequestObjectsInFrustum(void)
}
}
+bool
+CEntity::SetupLighting(void)
+{
+ return false;
+}
+
+void
+CEntity::RemoveLighting(bool)
+{
+}
+
+// --MIAMI: Done
+bool
+CPed::SetupLighting(void)
+{
+ ActivateDirectional();
+ SetAmbientColoursForPedsCarsAndObjects();
+
+#ifndef MASTER
+ // Originally this was being called through iteration of Sectors, but putting it here is better.
+ if (GetDebugDisplay() != 0 && !IsPlayer())
+ DebugRenderOnePedText();
+#endif
+
+ if (bRenderScorched) {
+ WorldReplaceNormalLightsWithScorched(Scene.world, 0.1f);
+ } 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 (lightMult != 1.0f) {
+ SetAmbientAndDirectionalColours(lightMult);
+ return true;
+ }
+ }
+ return false;
+}
+
+// --MIAMI: Done
+void
+CPed::RemoveLighting(bool reset)
+{
+ if (!bRenderScorched) {
+ CRenderer::RemoveVehiclePedLights(this, reset);
+ if (reset)
+ ReSetAmbientAndDirectionalColours();
+ }
+ SetAmbientColours();
+ DeActivateDirectional();
+}
+
float
CalcNewDelta(RwV2d *a, RwV2d *b)
{
diff --git a/src/render/Renderer.h b/src/render/Renderer.h
index b579bb4c..9b202098 100644
--- a/src/render/Renderer.h
+++ b/src/render/Renderer.h
@@ -2,6 +2,16 @@
class CEntity;
+#ifdef FIX_BUGS
+#define LOD_DISTANCE (300.0f*TheCamera.LODDistMultiplier)
+#else
+#define LOD_DISTANCE 300.0f
+#endif
+#define FADE_DISTANCE 20.0f
+#define STREAM_DISTANCE 30.0f
+
+extern bool gbShowPedRoadGroups;
+extern bool gbShowCarRoadGroups;
extern bool gbShowCollisionPolys;
extern bool gbShowCollisionLines;
extern bool gbBigWhiteDebugLightSwitchedOn;
@@ -15,6 +25,13 @@ extern bool gbDontRenderVehicles;
class CVehicle;
class CPtrList;
+// unused
+struct BlockedRange
+{
+ float a, b; // unknown
+ BlockedRange *prev, *next;
+};
+
class CRenderer
{
static int32 ms_nNoOfVisibleEntities;
@@ -32,6 +49,10 @@ class CRenderer
static CVector ms_vecCameraPosition;
static CVehicle *m_pFirstPersonVehicle;
+ // unused
+ static BlockedRange aBlockedRanges[16];
+ static BlockedRange *pFullBlockedRanges;
+ static BlockedRange *pEmptyBlockedRanges;
public:
static float ms_lodDistScale;
static bool m_loadingPriority;
diff --git a/src/render/Shadows.cpp b/src/render/Shadows.cpp
index a964ceb6..e8be23bd 100644
--- a/src/render/Shadows.cpp
+++ b/src/render/Shadows.cpp
@@ -2229,7 +2229,7 @@ CShadows::CastShadowEntityXYZ(CEntity *pEntity, CVector *pPosn,
sphere.Set(2.0f, center);
RwV3d point;
- RwV3dTransformPoints(&point, center, 1, &invMatrix);
+ RwV3dTransformPoints(&point, &center, 1, &invMatrix);
CColSphere colSphere;
colSphere.Set(2.0f, CVector(point), 0, 0);
@@ -2252,7 +2252,7 @@ CShadows::CastShadowEntityXYZ(CEntity *pEntity, CVector *pPosn,
p[1] += offset;
p[2] += offset;
- if ( !ShadowRenderTriangleCB((RwV3d *)p, n, &proj) )
+ if ( !ShadowRenderTriangleCB(p, &n, &proj) )
break;
}
i++;
diff --git a/src/render/SpecialFX.cpp b/src/render/SpecialFX.cpp
index 665a41ab..e17caa97 100644
--- a/src/render/SpecialFX.cpp
+++ b/src/render/SpecialFX.cpp
@@ -1384,21 +1384,25 @@ CMoneyMessages::Render()
void
CMoneyMessages::RegisterOne(CVector vecPos, const char *pText, uint8 bRed, uint8 bGreen, uint8 bBlue, float fSize, float fOpacity)
{
- uint32 nIndex = 0;
- while (aMoneyMessages[nIndex].m_nTimeRegistered != 0) {
- if (++nIndex >= NUMMONEYMESSAGES) return;
- }
-
- // Add data of this money message to the array
- AsciiToUnicode(pText, aMoneyMessages[nIndex].m_aText);
+ uint32 i;
+#ifdef FIX_BUGS
+ for(i = 0; i < NUMMONEYMESSAGES && aMoneyMessages[i].m_nTimeRegistered != 0; i++);
+#else
+ for(i = 0; aMoneyMessages[i].m_nTimeRegistered != 0 && i < NUMMONEYMESSAGES; i++);
+#endif
- aMoneyMessages[nIndex].m_nTimeRegistered = CTimer::GetTimeInMilliseconds();
- aMoneyMessages[nIndex].m_vecPosition = vecPos;
- aMoneyMessages[nIndex].m_Colour.red = bRed;
- aMoneyMessages[nIndex].m_Colour.green = bGreen;
- aMoneyMessages[nIndex].m_Colour.blue = bBlue;
- aMoneyMessages[nIndex].m_fSize = fSize;
- aMoneyMessages[nIndex].m_fOpacity = fOpacity;
+ if(i < NUMMONEYMESSAGES) {
+ // Add data of this money message to the array
+ AsciiToUnicode(pText, aMoneyMessages[i].m_aText);
+
+ aMoneyMessages[i].m_nTimeRegistered = CTimer::GetTimeInMilliseconds();
+ aMoneyMessages[i].m_vecPosition = vecPos;
+ aMoneyMessages[i].m_Colour.red = bRed;
+ aMoneyMessages[i].m_Colour.green = bGreen;
+ aMoneyMessages[i].m_Colour.blue = bBlue;
+ aMoneyMessages[i].m_fSize = fSize;
+ aMoneyMessages[i].m_fOpacity = fOpacity;
+ }
}
CRGBA FoamColour(255, 255, 255, 255);
diff --git a/src/render/WaterLevel.cpp b/src/render/WaterLevel.cpp
index 88c45c79..b698a5b2 100644
--- a/src/render/WaterLevel.cpp
+++ b/src/render/WaterLevel.cpp
@@ -1,6 +1,7 @@
#include "common.h"
#include "main.h"
#include "FileMgr.h"
+#include "FileLoader.h"
#include "TxdStore.h"
#include "Timer.h"
#include "Weather.h"
@@ -17,6 +18,7 @@
#include "ParticleMgr.h"
#include "RwHelper.h"
#include "Streaming.h"
+#include "ColStore.h"
#include "CdStream.h"
#include "Pad.h"
#include "RenderBuffer.h"
@@ -43,8 +45,8 @@ float _TEXTURE_WAKE_ADDV;
int32 CWaterLevel::ms_nNoOfWaterLevels;
float CWaterLevel::ms_aWaterZs[48];
CRect CWaterLevel::ms_aWaterRects[48];
-uint8 CWaterLevel::aWaterBlockList[WATER_BLOCK_SECTORS][WATER_BLOCK_SECTORS];
-uint8 CWaterLevel::aWaterFineBlockList[WATER_FINEBLOCK_SECTORS][WATER_FINEBLOCK_SECTORS];
+int8 CWaterLevel::aWaterBlockList[MAX_LARGE_SECTORS][MAX_LARGE_SECTORS];
+int8 CWaterLevel::aWaterFineBlockList[MAX_SMALL_SECTORS][MAX_SMALL_SECTORS];
bool CWaterLevel::WavesCalculatedThisFrame;
@@ -115,15 +117,19 @@ WaterLevelInitialise(Const char *pWaterDat)
{
CWaterLevel::ms_nNoOfWaterLevels = 0;
- int32 hFile;
-
+#ifdef MASTER
+ int32 hFile = -1;
+
do
{
hFile = CFileMgr::OpenFile("DATA\\waterpro.dat", "rb");
}
while ( hFile < 0 );
+#else
+ int32 hFile = CFileMgr::OpenFile("DATA\\waterpro.dat", "rb");
+#endif
- if ( hFile > 0 )
+ if (hFile > 0)
{
CFileMgr::Read(hFile, (char *)&CWaterLevel::ms_nNoOfWaterLevels, sizeof(CWaterLevel::ms_nNoOfWaterLevels));
CFileMgr::Read(hFile, (char *)CWaterLevel::ms_aWaterZs, sizeof(CWaterLevel::ms_aWaterZs));
@@ -132,6 +138,142 @@ WaterLevelInitialise(Const char *pWaterDat)
CFileMgr::Read(hFile, (char *)CWaterLevel::aWaterFineBlockList, sizeof(CWaterLevel::aWaterFineBlockList));
CFileMgr::CloseFile(hFile);
}
+#ifndef MASTER
+ else
+ {
+ printf("Init waterlevels\n");
+
+ // collision is streamed in VC
+ CColStore::LoadAllCollision();
+
+ CFileMgr::SetDir("");
+ hFile = CFileMgr::OpenFile(pWaterDat, "r");
+
+ char *line;
+
+ while ((line = CFileLoader::LoadLine(hFile)))
+ {
+ if (*line && *line != ';' && !strstr(line, "* ;end of file"))
+ {
+ float z, l, b, r, t;
+ sscanf(line, "%f %f %f %f %f", &z, &l, &b, &r, &t);
+ CWaterLevel::AddWaterLevel(l, b, r, t, z);
+ }
+ }
+
+ CFileMgr::CloseFile(hFile);
+
+ for (int32 x = 0; x < MAX_SMALL_SECTORS; x++)
+ {
+ for (int32 y = 0; y < MAX_SMALL_SECTORS; y++)
+ {
+ CWaterLevel::aWaterFineBlockList[x][y] = NO_WATER;
+ }
+ }
+
+ // rasterize water rects read from file
+ for (int32 i = 0; i < CWaterLevel::ms_nNoOfWaterLevels; i++)
+ {
+ 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;
+
+ 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);
+
+ for (int32 x = l; x <= r; x++)
+ {
+ for (int32 y = t; y <= b; y++)
+ {
+ CWaterLevel::aWaterFineBlockList[x][y] = i;
+ }
+ }
+ }
+
+ // 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 - WATER_X_OFFSET;
+
+ for (int32 y = 0; y < MAX_SMALL_SECTORS; y++)
+ {
+ if (CWaterLevel::aWaterFineBlockList[x][y] >= 0)
+ {
+ float worldY = WATER_START_Y + y * SMALL_SECTOR_SIZE;
+
+ int32 i;
+ for (i = 0; i <= 8; i++)
+ {
+ for (int32 j = 0; j <= 8; j++)
+ {
+ 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) &&
+ (!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
+ i = 1000;
+ break;
+ }
+ }
+
+ if (i < 1000)
+ CWaterLevel::aWaterFineBlockList[x][y] = NO_WATER;
+ }
+ }
+ }
+
+ 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 (CWaterLevel::aWaterFineBlockList[x * 2][y * 2] >= 0)
+ {
+ CWaterLevel::aWaterBlockList[x][y] = CWaterLevel::aWaterFineBlockList[x * 2][y * 2];
+ }
+ else if (CWaterLevel::aWaterFineBlockList[x * 2 + 1][y * 2] >= 0)
+ {
+ CWaterLevel::aWaterBlockList[x][y] = CWaterLevel::aWaterFineBlockList[x * 2 + 1][y * 2];
+ }
+ else if (CWaterLevel::aWaterFineBlockList[x * 2][y * 2 + 1] >= 0)
+ {
+ CWaterLevel::aWaterBlockList[x][y] = CWaterLevel::aWaterFineBlockList[x * 2][y * 2 + 1];
+ }
+ else if (CWaterLevel::aWaterFineBlockList[x * 2 + 1][y * 2 + 1] >= 0)
+ {
+ CWaterLevel::aWaterBlockList[x][y] = CWaterLevel::aWaterFineBlockList[x * 2 + 1][y * 2 + 1];
+ }
+ else
+ {
+ CWaterLevel::aWaterBlockList[x][y] = NO_WATER;
+ }
+ }
+ }
+
+ hFile = CFileMgr::OpenFileForWriting("data\\waterpro.dat");
+
+ if (hFile > 0)
+ {
+ 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
CTxdStore::PushCurrentTxd();
@@ -397,6 +539,170 @@ CWaterLevel::DestroyWavyAtomic()
#undef _DELETE_ATOMIC
}
+#ifndef MASTER
+void
+CWaterLevel::AddWaterLevel(float fXLeft, float fYBottom, float fXRight, float fYTop, float fLevel)
+{
+ ms_aWaterRects[ms_nNoOfWaterLevels] = CRect(fXLeft, fYBottom, fXRight, fYTop);
+ ms_aWaterZs[ms_nNoOfWaterLevels] = fLevel;
+ ms_nNoOfWaterLevels++;
+}
+
+bool
+CWaterLevel::WaterLevelAccordingToRectangles(float fX, float fY, float *pfOutLevel)
+{
+ if (ms_nNoOfWaterLevels <= 0) return false;
+
+ for (int32 i = 0; i < ms_nNoOfWaterLevels; i++)
+ {
+ if (fX >= ms_aWaterRects[i].left && fX <= ms_aWaterRects[i].right
+ && fY >= ms_aWaterRects[i].top && fY <= ms_aWaterRects[i].bottom)
+ {
+ if (pfOutLevel) *pfOutLevel = ms_aWaterZs[i];
+
+ return true;
+ }
+ }
+
+ return false;
+}
+
+bool
+CWaterLevel::TestVisibilityForFineWaterBlocks(const CVector &worldPos)
+{
+ static CVector2D tab[] =
+ {
+ { 50.0f, 50.0f },
+ { -50.0f, 50.0f },
+ { -50.0f, -50.0f },
+ { 50.0f, -50.0f },
+ { 50.0f, 0.0f },
+ { -50.0f, 0.0f },
+ { 0.0f, -50.0f },
+ { 0.0f, 50.0f },
+ };
+
+ CEntity *entity;
+ CColPoint col;
+ CVector lineStart, lineEnd;
+
+ lineStart = worldPos;
+
+ if (!CWorld::ProcessVerticalLine(lineStart, lineStart.z + 100.0f, col, entity, true, false, false, false, true, false, nil))
+ {
+ lineStart.x += 0.4f;
+ lineStart.y += 0.4f;
+
+ if (!CWorld::ProcessVerticalLine(lineStart, lineStart.z + 100.0f, col, entity, true, false, false, false, true, false, nil))
+ {
+ return false;
+ }
+ }
+
+ for (int32 i = 0; i < ARRAY_SIZE(tab); i++)
+ {
+ lineStart = worldPos;
+ lineEnd = worldPos;
+
+ lineEnd.x += tab[i].x;
+ lineEnd.y += tab[i].y;
+ lineEnd.z += 100.0f;
+
+ if ((lineEnd.x > WORLD_MIN_X && lineEnd.x < WORLD_MAX_X) && (lineEnd.y > WORLD_MIN_Y && lineEnd.y < WORLD_MAX_Y))
+ {
+ if (!CWorld::ProcessLineOfSight(lineStart, lineEnd, col, entity, true, false, false, false, true, false, nil))
+ {
+ lineStart.x += 0.4f;
+ lineStart.y += 0.4f;
+ lineEnd.x += 0.4f;
+ lineEnd.y += 0.4f;
+
+ if (!CWorld::ProcessLineOfSight(lineStart, lineEnd, col, entity, true, false, false, false, true, false, nil))
+ {
+ return false;
+ }
+ }
+ }
+ }
+
+ return true;
+}
+
+void
+CWaterLevel::RemoveIsolatedWater()
+{
+ bool (*isConnected)[MAX_SMALL_SECTORS] = new bool[MAX_SMALL_SECTORS][MAX_SMALL_SECTORS];
+
+ for (int32 x = 0; x < MAX_SMALL_SECTORS; x++)
+ {
+ for (int32 y = 0; y < MAX_SMALL_SECTORS; y++)
+ {
+ isConnected[x][y] = false;
+ }
+ }
+
+ isConnected[0][0] = true;
+ bool keepGoing;
+
+ do
+ {
+ keepGoing = false;
+
+ for (int32 x = 0; x < MAX_SMALL_SECTORS; x++)
+ {
+ for (int32 y = 0; y < MAX_SMALL_SECTORS; y++)
+ {
+ if (aWaterFineBlockList[x][y] < 0 || isConnected[x][y])
+ continue;
+
+ if (x > 0 && isConnected[x - 1][y])
+ {
+ isConnected[x][y] = true;
+ keepGoing = true;
+ }
+
+ if (y > 0 && isConnected[x][y - 1])
+ {
+ isConnected[x][y] = true;
+ keepGoing = true;
+ }
+
+ if (x + 1 < MAX_SMALL_SECTORS && isConnected[x + 1][y])
+ {
+ isConnected[x][y] = true;
+ keepGoing = true;
+ }
+
+ if (y + 1 < MAX_SMALL_SECTORS && isConnected[x][y + 1])
+ {
+ isConnected[x][y] = true;
+ keepGoing = true;
+ }
+ }
+ }
+ }
+ while (keepGoing);
+
+ int32 numRemoved = 0;
+
+ for (int32 x = 0; x < MAX_SMALL_SECTORS; x++)
+ {
+ for (int32 y = 0; y < MAX_SMALL_SECTORS; y++)
+ {
+ if (aWaterFineBlockList[x][y] >= 0 && !isConnected[x][y] && ms_aWaterZs[aWaterFineBlockList[x][y]] == 6.0f)
+ {
+ numRemoved++;
+ aWaterFineBlockList[x][y] = NO_WATER;
+ }
+ }
+ }
+
+ printf("Removed %d isolated patches of water\n", numRemoved);
+
+ delete[] isConnected;
+}
+#endif
+
bool
CWaterLevel::GetWaterLevel(float fX, float fY, float fZ, float *pfOutLevel, bool bDontCheckZ)
{
@@ -542,38 +848,38 @@ inline bool
_IsColideWithBlock(int32 x, int32 y, int32 &block)
{
block = CWaterLevel::aWaterFineBlockList[x + 0][y + 0];
- if (!(block & 0x80))
+ if (block >= 0)
return true;
block = CWaterLevel::aWaterFineBlockList[x + 0][y + 1];
- if (!(block & 0x80))
+ if (block >= 0)
{
block = CWaterLevel::aWaterFineBlockList[x + 0][y + 2];
- if (!(block & 0x80))
+ if (block >= 0)
return true;
}
block = CWaterLevel::aWaterFineBlockList[x + 1][y + 0];
- if (!(block & 0x80))
+ if (block >= 0)
return true;
block = CWaterLevel::aWaterFineBlockList[x + 1][y + 1];
- if (!(block & 0x80))
+ if (block >= 0)
{
block = CWaterLevel::aWaterFineBlockList[x + 1][y + 2];
- if (!(block & 0x80))
+ if (block >= 0)
return true;
}
block = CWaterLevel::aWaterFineBlockList[x + 2][y + 0];
- if (!(block & 0x80))
+ if (block >= 0)
return true;
block = CWaterLevel::aWaterFineBlockList[x + 2][y + 1];
- if (!(block & 0x80))
+ if (block >= 0)
{
block = CWaterLevel::aWaterFineBlockList[x + 2][y + 2];
- if (!(block & 0x80))
+ if (block >= 0)
return true;
}
@@ -693,10 +999,10 @@ CWaterLevel::RenderWater()
{
for ( int32 y = nStartY; y <= nEndY; y++ )
{
- if ( !(aWaterBlockList[2*x+0][2*y+0] & 0x80)
- || !(aWaterBlockList[2*x+1][2*y+0] & 0x80)
- || !(aWaterBlockList[2*x+0][2*y+1] & 0x80)
- || !(aWaterBlockList[2*x+1][2*y+1] & 0x80) )
+ 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);
@@ -716,16 +1022,16 @@ CWaterLevel::RenderWater()
float fZ;
- if ( !(aWaterBlockList[2*x+0][2*y+0] & 0x80) )
+ 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] & 0x80) )
+ 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] & 0x80) )
+ 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] & 0x80) )
+ if ( aWaterBlockList[2*x+1][2*y+1] >= 0 )
fZ = ms_aWaterZs[ aWaterBlockList[2*x+1][2*y+1] ];
if ( fHugeSectorDistToCamSqr >= SQR(500.0f) )
@@ -960,10 +1266,10 @@ CWaterLevel::RenderTransparentWater(void)
{
for ( int32 y = nStartY; y <= nEndY; y++ )
{
- if ( !(aWaterBlockList[2*x+0][2*y+0] & 0x80)
- || !(aWaterBlockList[2*x+1][2*y+0] & 0x80)
- || !(aWaterBlockList[2*x+0][2*y+1] & 0x80)
- || !(aWaterBlockList[2*x+1][2*y+1] & 0x80) )
+ 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);
@@ -991,7 +1297,7 @@ CWaterLevel::RenderTransparentWater(void)
{
for ( int32 y2 = 2*y; y2 <= 2*y+1; y2++ )
{
- if ( !(aWaterBlockList[x2][y2] & 0x80) )
+ if ( aWaterBlockList[x2][y2] >= 0 )
{
float fLargeX = WATER_FROM_LARGE_SECTOR_X(x2) - WATER_X_OFFSET;
float fLargeY = WATER_FROM_LARGE_SECTOR_Y(y2);
@@ -1025,7 +1331,7 @@ CWaterLevel::RenderTransparentWater(void)
float fZ;
// WS
- if ( !(aWaterFineBlockList[2*x2+0][2*y2+0] & 0x80) )
+ if ( aWaterFineBlockList[2*x2+0][2*y2+0] >= 0 )
{
float fSmallX = fLargeX;
float fSmallY = fLargeY;
@@ -1042,7 +1348,7 @@ CWaterLevel::RenderTransparentWater(void)
}
// SE
- if ( !(aWaterFineBlockList[2*x2+1][2*y2+0] & 0x80) )
+ if ( aWaterFineBlockList[2*x2+1][2*y2+0] >= 0 )
{
float fSmallX = fLargeX + (LARGE_SECTOR_SIZE/2);
float fSmallY = fLargeY;
@@ -1059,7 +1365,7 @@ CWaterLevel::RenderTransparentWater(void)
}
// WN
- if ( !(aWaterFineBlockList[2*x2+0][2*y2+1] & 0x80) )
+ if ( aWaterFineBlockList[2*x2+0][2*y2+1] >= 0 )
{
float fSmallX = fLargeX;
float fSmallY = fLargeY + (LARGE_SECTOR_SIZE/2);
@@ -1076,7 +1382,7 @@ CWaterLevel::RenderTransparentWater(void)
}
//NE
- if ( !(aWaterFineBlockList[2*x2+1][2*y2+1] & 0x80) )
+ if ( aWaterFineBlockList[2*x2+1][2*y2+1] >= 0 )
{
float fSmallX = fLargeX + (LARGE_SECTOR_SIZE/2);
float fSmallY = fLargeY + (LARGE_SECTOR_SIZE/2);
@@ -2588,7 +2894,7 @@ CWaterLevel::CalcDistanceToWater(float fX, float fY)
{
for ( int32 y = nStartY; y <= nEndY; y++ )
{
- if ( !(aWaterFineBlockList[x][y] & 0x80) )
+ if ( aWaterFineBlockList[x][y] >= 0 )
{
float fSectorX = WATER_FROM_SMALL_SECTOR_X(x) - WATER_X_OFFSET;
float fSectorY = WATER_FROM_SMALL_SECTOR_Y(y);
diff --git a/src/render/WaterLevel.h b/src/render/WaterLevel.h
index 0e682305..5a497ddf 100644
--- a/src/render/WaterLevel.h
+++ b/src/render/WaterLevel.h
@@ -2,10 +2,10 @@
#define WATER_X_OFFSET (400.0f)
-#define WATER_BLOCK_SECTORS MAX_LARGE_SECTORS
-#define WATER_FINEBLOCK_SECTORS MAX_SMALL_SECTORS
#define WATER_Z_OFFSET (0.5f)
+#define NO_WATER -128
+
#define MAX_SMALL_SECTORS 128
#define MAX_LARGE_SECTORS 64
#define MAX_HUGE_SECTORS 32
@@ -25,7 +25,6 @@
#define WATER_WIDTH ((WATER_END_X - WATER_START_X))
#define WATER_HEIGHT ((WATER_END_Y - WATER_START_Y))
-
#define WATER_UNSIGN_X(x) ( (x) + (WATER_WIDTH /2) )
#define WATER_UNSIGN_Y(y) ( (y) + (WATER_HEIGHT/2) )
#define WATER_SIGN_X(x) ( (x) - (WATER_WIDTH /2) )
@@ -38,7 +37,7 @@
// 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 )
@@ -104,31 +103,35 @@ public:
static int32 ms_nNoOfWaterLevels;
static float ms_aWaterZs[48];
static CRect ms_aWaterRects[48];
- static uint8 aWaterBlockList[WATER_BLOCK_SECTORS][WATER_BLOCK_SECTORS]; // 64x64 Large blocks 64x64 each
- static uint8 aWaterFineBlockList[WATER_FINEBLOCK_SECTORS][WATER_FINEBLOCK_SECTORS]; // 128x128 Small blocks 32x32 each
+ 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 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 RenderTransparentWater(void);
// unused
@@ -151,11 +154,11 @@ public:
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);
@@ -163,18 +166,18 @@ public:
static void RenderAndEmptyRenderBuffer();
static bool GetGroundLevel(CVector const &vecPosn, float *pfOutLevel, ColData *pData, float fDistance);
-
+
// unused
static bool IsLocationOutOfWorldBounds_WS(CVector const &vecPosn, int nOffset);
// unused
static bool GetGroundLevel_WS(CVector const & vecPosn, float *pfOutLevel, ColData *pData, float fDistance);
static bool GetWaterDepth(CVector const &vecPosn, float *pfDepth, float *pfLevelNoWaves, float *pfGroundLevel);
-
+
static void RenderSeaBirds();
static void RenderShipsOnHorizon();
-
+
static void HandleSeaLifeForms();
-
+
static void HandleBeachToysStuff(void);
static CEntity *CreateBeachToy(CVector const &vec, eBeachToy beachtoy);
};
diff --git a/src/render/Weather.cpp b/src/render/Weather.cpp
index 3f242362..52e93951 100644
--- a/src/render/Weather.cpp
+++ b/src/render/Weather.cpp
@@ -139,7 +139,7 @@ void CWeather::Init(void)
ForcedWeatherType = WEATHER_RANDOM;
SoundHandle = DMAudio.CreateEntity(AUDIOTYPE_WEATHER, (void*)1);
if (SoundHandle >= 0)
- DMAudio.SetEntityStatus(SoundHandle, 1);
+ DMAudio.SetEntityStatus(SoundHandle, true);
}
void CWeather::Update(void)
diff --git a/src/rw/Lights.cpp b/src/rw/Lights.cpp
index 3657e2c7..e0dff850 100644
--- a/src/rw/Lights.cpp
+++ b/src/rw/Lights.cpp
@@ -3,6 +3,7 @@
#include <rpworld.h>
#include "Lights.h"
+#include "Timer.h"
#include "Timecycle.h"
#include "Coronas.h"
#include "Weather.h"
@@ -276,6 +277,46 @@ SetAmbientAndDirectionalColours(float f)
RpLightSetColor(pDirect, &DirectionalLightColour);
}
+// unused
+void
+SetFlashyColours(float f)
+{
+ if(CTimer::GetTimeInMilliseconds() & 0x100){
+ AmbientLightColour.red = 1.0f;
+ AmbientLightColour.green = 1.0f;
+ AmbientLightColour.blue = 1.0f;
+
+ DirectionalLightColour.red = DirectionalLightColourForFrame.red;
+ DirectionalLightColour.green = DirectionalLightColourForFrame.green;
+ DirectionalLightColour.blue = DirectionalLightColourForFrame.blue;
+
+ RpLightSetColor(pAmbient, &AmbientLightColour);
+ RpLightSetColor(pDirect, &DirectionalLightColour);
+ }else{
+ SetAmbientAndDirectionalColours(f * 0.75f);
+ }
+}
+
+// unused
+void
+SetFlashyColours_Mild(float f)
+{
+ if(CTimer::GetTimeInMilliseconds() & 0x100){
+ AmbientLightColour.red = 0.65f;
+ AmbientLightColour.green = 0.65f;
+ AmbientLightColour.blue = 0.65f;
+
+ DirectionalLightColour.red = DirectionalLightColourForFrame.red;
+ DirectionalLightColour.green = DirectionalLightColourForFrame.green;
+ DirectionalLightColour.blue = DirectionalLightColourForFrame.blue;
+
+ RpLightSetColor(pAmbient, &AmbientLightColour);
+ RpLightSetColor(pDirect, &DirectionalLightColour);
+ }else{
+ SetAmbientAndDirectionalColours(f * 0.9f);
+ }
+}
+
void
SetBrightMarkerColours(float f)
{
diff --git a/src/rw/Lights.h b/src/rw/Lights.h
index c3543d77..ad355adb 100644
--- a/src/rw/Lights.h
+++ b/src/rw/Lights.h
@@ -14,6 +14,8 @@ void WorldReplaceScorchedLightsWithNormal(RpWorld *world);
void AddAnExtraDirectionalLight(RpWorld *world, float dirx, float diry, float dirz, float red, float green, float blue);
void RemoveExtraDirectionalLights(RpWorld *world);
void SetAmbientAndDirectionalColours(float f);
+void SetFlashyColours(float f);
+void SetFlashyColours_Mild(float f);
void SetBrightMarkerColours(float f);
void ReSetAmbientAndDirectionalColours(void);
void DeActivateDirectional(void);
diff --git a/src/rw/MemoryHeap.cpp b/src/rw/MemoryHeap.cpp
new file mode 100644
index 00000000..285a7c70
--- /dev/null
+++ b/src/rw/MemoryHeap.cpp
@@ -0,0 +1,499 @@
+#include "common.h"
+#include "main.h"
+#include "FileMgr.h"
+#include "Timer.h"
+#include "ModelInfo.h"
+#include "Streaming.h"
+#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); } }
+//#define MEMORYHEAP_ASSERT_MESSAGE(cond, message) { if (!(cond)) { printf("ASSERT File:%s Line:%d:\n\t%s\n", __FILE__, __LINE__, message); exit(1); } }
+
+#define MEMORYHEAP_ASSERT(cond) assert(cond)
+#define MEMORYHEAP_ASSERT_MESSAGE(cond, message) assert(cond)
+
+// registered pointers that we keep track of
+void **gPtrList[4000];
+int32 numPtrs;
+int32 gPosnInList;
+// indices into the ptr list in here are free
+CStack<int32, 4000> m_ptrListIndexStack;
+// how much memory we've moved
+uint32 memMoved;
+
+CMemoryHeap gMainHeap;
+
+void
+CMemoryHeap::Init(uint32 total)
+{
+ MEMORYHEAP_ASSERT((total != 0xF) != 0);
+
+ m_totalMemUsed = 0;
+ m_memUsed = nil;
+ m_currentMemID = MEMID_FREE;
+ m_blocksUsed = nil;
+ m_totalBlocksUsed = 0;
+ m_unkMemId = -1;
+
+ uint8 *mem = (uint8*)malloc(total);
+ assert(((uintptr)mem & 0xF) == 0);
+ m_start = (HeapBlockDesc*)mem;
+ m_end = (HeapBlockDesc*)(mem + total - sizeof(HeapBlockDesc));
+ m_start->m_memId = MEMID_FREE;
+ m_start->m_size = total - 2*sizeof(HeapBlockDesc);
+ m_end->m_memId = MEMID_GAME;
+ m_end->m_size = 0;
+
+ m_freeList.m_last.m_size = INT_MAX;
+ m_freeList.Init();
+ m_freeList.Insert(m_start);
+
+ // TODO: figure out what these are and use sizeof
+ m_fixedSize[0].Init(0x10);
+ m_fixedSize[1].Init(0x20);
+ m_fixedSize[2].Init(0xE0);
+ m_fixedSize[3].Init(0x60);
+ m_fixedSize[4].Init(0x1C0);
+ m_fixedSize[5].Init(0x50);
+
+ m_currentMemID = MEMID_FREE; // disable registration
+ m_memUsed = (uint32*)Malloc(NUM_MEMIDS * sizeof(uint32));
+ m_blocksUsed = (uint32*)Malloc(NUM_MEMIDS * sizeof(uint32));
+ RegisterMalloc(GetDescFromHeapPointer(m_memUsed));
+ RegisterMalloc(GetDescFromHeapPointer(m_blocksUsed));
+
+ m_currentMemID = MEMID_GAME;
+ for(int i = 0; i < NUM_MEMIDS; i++){
+ m_memUsed[i] = 0;
+ m_blocksUsed[i] = 0;
+ }
+}
+
+void
+CMemoryHeap::RegisterMalloc(HeapBlockDesc *block)
+{
+ block->m_memId = m_currentMemID;
+ if(m_currentMemID == MEMID_FREE)
+ return;
+ m_totalMemUsed += block->m_size + sizeof(HeapBlockDesc);
+ m_memUsed[m_currentMemID] += block->m_size + sizeof(HeapBlockDesc);
+ m_blocksUsed[m_currentMemID]++;
+ m_totalBlocksUsed++;
+}
+
+void
+CMemoryHeap::RegisterFree(HeapBlockDesc *block)
+{
+ if(block->m_memId == MEMID_FREE)
+ return;
+ m_totalMemUsed -= block->m_size + sizeof(HeapBlockDesc);
+ m_memUsed[block->m_memId] -= block->m_size + sizeof(HeapBlockDesc);
+ m_blocksUsed[block->m_memId]--;
+ m_totalBlocksUsed--;
+}
+
+void*
+CMemoryHeap::Malloc(uint32 size)
+{
+ static int recursion = 0;
+
+ // weird way to round up
+ if((size & 0xF) != 0)
+ size = (size&~0xF) + 0x10;
+
+ recursion++;
+
+ // See if we can allocate from one of the fixed-size lists
+ for(int i = 0; i < NUM_FIXED_MEMBLOCKS; i++){
+ CommonSize *list = &m_fixedSize[i];
+ if(m_fixedSize[i].m_size == size){
+ HeapBlockDesc *block = list->Malloc();
+ if(block){
+ RegisterMalloc(block);
+ recursion--;
+ return block->GetDataPointer();
+ }
+ break;
+ }
+ }
+
+ // now try the normal free list
+ HeapBlockDesc *next;
+ for(HeapBlockDesc *block = m_freeList.m_first.m_next;
+ block != &m_freeList.m_last;
+ block = next){
+ MEMORYHEAP_ASSERT(block->m_memId == MEMID_FREE);
+ MEMORYHEAP_ASSERT_MESSAGE(block >= m_start && block <= m_end, "Block outside of memory");
+
+ // make sure block has maximum size
+ uint32 initialsize = block->m_size;
+ uint32 blocksize = CombineFreeBlocks(block);
+#ifdef FIX_BUGS
+ // has to be done here because block can be moved
+ next = block->m_next;
+#endif
+ if(initialsize != blocksize){
+ block->RemoveHeapFreeBlock();
+ HeapBlockDesc *pos = block->m_prev->FindSmallestFreeBlock(block->m_size);
+ block->InsertHeapFreeBlock(pos->m_prev);
+ }
+ if(block->m_size >= size){
+ // got space to allocate from!
+ block->RemoveHeapFreeBlock();
+ FillInBlockData(block, block->GetNextConsecutive(), size);
+ recursion--;
+ return block->GetDataPointer();
+ }
+#ifndef FIX_BUGS
+ next = block->m_next;
+#endif
+ }
+
+ // oh no, we're losing, try to free some stuff
+ static bool removeCollision = false;
+ static bool removeIslands = false;
+ static bool removeBigBuildings = false;
+ size_t initialMemoryUsed = CStreaming::ms_memoryUsed;
+ CStreaming::MakeSpaceFor(0xCFE800 - CStreaming::ms_memoryUsed);
+ if (recursion > 10)
+ CGame::TidyUpMemory(true, false);
+ else if (recursion > 6)
+ CGame::TidyUpMemory(false, true);
+ if (initialMemoryUsed == CStreaming::ms_memoryUsed && recursion > 11) {
+ if (!removeCollision && !CGame::playingIntro) {
+ CModelInfo::RemoveColModelsFromOtherLevels(LEVEL_GENERIC);
+ removeCollision = true;
+ }
+ else if (!removeIslands && !CGame::playingIntro) {
+ CStreaming::RemoveIslandsNotUsed(LEVEL_INDUSTRIAL);
+ CStreaming::RemoveIslandsNotUsed(LEVEL_COMMERCIAL);
+ CStreaming::RemoveIslandsNotUsed(LEVEL_SUBURBAN);
+ removeIslands = true;
+ }
+ else if (!removeBigBuildings) {
+ CStreaming::RemoveBigBuildings(LEVEL_INDUSTRIAL);
+ CStreaming::RemoveBigBuildings(LEVEL_COMMERCIAL);
+ CStreaming::RemoveBigBuildings(LEVEL_SUBURBAN);
+ }
+ else {
+ LoadingScreen("NO MORE MEMORY", nil, nil);
+ LoadingScreen("NO MORE MEMORY", nil, nil);
+ }
+ CGame::TidyUpMemory(true, false);
+ }
+ void *mem = Malloc(size);
+ if (removeCollision) {
+ CTimer::Stop();
+ // TODO: different on PS2
+ CFileLoader::LoadCollisionFromDatFile(CCollision::ms_collisionInMemory);
+ removeCollision = false;
+ CTimer::Update();
+ }
+ if (removeBigBuildings || removeIslands) {
+ CTimer::Stop();
+ if (!CGame::playingIntro)
+ CStreaming::RequestBigBuildings(CGame::currLevel);
+ CStreaming::LoadAllRequestedModels(true);
+ removeBigBuildings = false;
+ removeIslands = false;
+ CTimer::Update();
+ }
+ recursion--;
+ return mem;
+}
+
+void*
+CMemoryHeap::Realloc(void *ptr, uint32 size)
+{
+ if(ptr == nil)
+ return Malloc(size);
+
+ // weird way to round up
+ if((size & 0xF) != 0)
+ size = (size&~0xF) + 0x10;
+
+ HeapBlockDesc *block = GetDescFromHeapPointer(ptr);
+
+#ifdef FIX_BUGS
+ // better handling of size < block->m_size
+ if(size == 0){
+ Free(ptr);
+ return nil;
+ }
+ if(block->m_size >= size){
+ // shrink allocated block
+ RegisterFree(block);
+ PushMemId(block->m_memId);
+ FillInBlockData(block, block->GetNextConsecutive(), size);
+ PopMemId();
+ return ptr;
+ }
+#else
+ // not growing. just returning here is a bit cheap though
+ if(block->m_size >= size)
+ return ptr;
+#endif
+
+ // have to grow allocated block
+ HeapBlockDesc *next = block->GetNextConsecutive();
+ MEMORYHEAP_ASSERT_MESSAGE(next >= m_start && next <= m_end, "Block outside of memory");
+ if(next->m_memId == MEMID_FREE){
+ // try to grow the current block
+ // make sure the next free block has maximum size
+ uint32 freespace = CombineFreeBlocks(next);
+ HeapBlockDesc *end = next->GetNextConsecutive();
+ MEMORYHEAP_ASSERT_MESSAGE(end >= m_start && end <= m_end, "Block outside of memory");
+ // why the sizeof here?
+ if(block->m_size + next->m_size + sizeof(HeapBlockDesc) >= size){
+ // enough space to grow
+ next->RemoveHeapFreeBlock();
+ RegisterFree(block);
+ PushMemId(block->m_memId);
+ FillInBlockData(block, next->GetNextConsecutive(), size);
+ PopMemId();
+ return ptr;
+ }
+ }
+
+ // can't grow the existing block, have to get a new one and copy
+ PushMemId(block->m_memId);
+ void *dst = Malloc(size);
+ PopMemId();
+ memcpy(dst, ptr, block->m_size);
+ Free(ptr);
+ return dst;
+}
+
+void
+CMemoryHeap::Free(void *ptr)
+{
+ HeapBlockDesc *block = GetDescFromHeapPointer(ptr);
+ MEMORYHEAP_ASSERT_MESSAGE(block->m_memId != MEMID_FREE, "MemoryHeap corrupt");
+ MEMORYHEAP_ASSERT(m_unkMemId == -1 || m_unkMemId == block->m_memId);
+
+ RegisterFree(block);
+ block->m_memId = MEMID_FREE;
+ CombineFreeBlocks(block);
+ FreeBlock(block);
+ if(block->m_ptrListIndex != -1){
+ int32 idx = block->m_ptrListIndex;
+ gPtrList[idx] = nil;
+ m_ptrListIndexStack.push(idx);
+ }
+ block->m_ptrListIndex = -1;
+}
+
+// allocate 'size' bytes from 'block'
+void
+CMemoryHeap::FillInBlockData(HeapBlockDesc *block, HeapBlockDesc *end, uint32 size)
+{
+ block->m_size = size;
+ block->m_ptrListIndex = -1;
+ HeapBlockDesc *remainder = block->GetNextConsecutive();
+ MEMORYHEAP_ASSERT(remainder <= end);
+
+ if(remainder < end-1){
+ RegisterMalloc(block);
+
+ // can fit another block in the remaining space
+ remainder->m_size = GetSizeBetweenBlocks(remainder, end);
+ remainder->m_memId = MEMID_FREE;
+ MEMORYHEAP_ASSERT(remainder->m_size != 0);
+ FreeBlock(remainder);
+ }else{
+ // fully allocate this one
+ if(remainder < end)
+ // no gaps allowed
+ block->m_size = GetSizeBetweenBlocks(block, end);
+ RegisterMalloc(block);
+ }
+}
+
+// Make sure free block has no other free blocks after it
+uint32
+CMemoryHeap::CombineFreeBlocks(HeapBlockDesc *block)
+{
+ HeapBlockDesc *next = block->GetNextConsecutive();
+ if(next->m_memId != MEMID_FREE)
+ return block->m_size;
+ // get rid of free blocks after this one and adjust size
+ for(; next->m_memId == MEMID_FREE; next = next->GetNextConsecutive())
+ next->RemoveHeapFreeBlock();
+ block->m_size = GetSizeBetweenBlocks(block, next);
+ return block->m_size;
+}
+
+// Try to move all registered memory blocks into more optimal location
+void
+CMemoryHeap::TidyHeap(void)
+{
+ for(int i = 0; i < numPtrs; i++){
+ if(gPtrList[i] == nil || *gPtrList[i] == nil)
+ continue;
+ HeapBlockDesc *newblock = WhereShouldMemoryMove(*gPtrList[i]);
+ if(newblock)
+ *gPtrList[i] = MoveHeapBlock(newblock, GetDescFromHeapPointer(*gPtrList[i]));
+ }
+}
+
+// MIAMI: this is empty
+void
+CMemoryHeap::RegisterMemPointer(void *ptr)
+{
+ HeapBlockDesc *block = GetDescFromHeapPointer(*(void**)ptr);
+
+ if(block->m_ptrListIndex != -1)
+ return; // already registered
+
+ int index;
+ if(m_ptrListIndexStack.sp > 0){
+ // re-use a previously free'd index
+ index = m_ptrListIndexStack.pop();
+ }else{
+ // have to find a new index
+ index = gPosnInList;
+
+ void **pp = gPtrList[index];
+ // we're replacing an old pointer here??
+ if(pp && *pp && *pp != (void*)0xDDDDDDDD)
+ GetDescFromHeapPointer(*pp)->m_ptrListIndex = -1;
+
+ gPosnInList++;
+ if(gPosnInList == 4000)
+ gPosnInList = 0;
+ if(numPtrs < 4000)
+ numPtrs++;
+ }
+ gPtrList[index] = (void**)ptr;
+ block->m_ptrListIndex = index;
+}
+
+void*
+CMemoryHeap::MoveMemory(void *ptr)
+{
+ HeapBlockDesc *newblock = WhereShouldMemoryMove(ptr);
+ if(newblock)
+ return MoveHeapBlock(newblock, GetDescFromHeapPointer(ptr));
+ else
+ return ptr;
+}
+
+HeapBlockDesc*
+CMemoryHeap::WhereShouldMemoryMove(void *ptr)
+{
+ HeapBlockDesc *block = GetDescFromHeapPointer(ptr);
+ MEMORYHEAP_ASSERT(block->m_memId != MEMID_FREE);
+
+ HeapBlockDesc *next = block->GetNextConsecutive();
+ if(next->m_memId != MEMID_FREE)
+ return nil;
+
+ // we want to move the block into another block
+ // such that the free space between this and the next block can be minimized
+ HeapBlockDesc *newblock = m_freeList.m_first.FindSmallestFreeBlock(block->m_size);
+ // size of free space wouldn't decrease, so return
+ if(newblock->m_size >= block->m_size + next->m_size)
+ return nil;
+ // size of free space wouldn't decrease enough
+ if(newblock->m_size >= 16 + 1.125f*block->m_size) // what are 16 and 1.125 here? sizeof(HeapBlockDesc)?
+ return nil;
+ return newblock;
+}
+
+void*
+CMemoryHeap::MoveHeapBlock(HeapBlockDesc *dst, HeapBlockDesc *src)
+{
+ PushMemId(src->m_memId);
+ dst->RemoveHeapFreeBlock();
+ FillInBlockData(dst, dst->GetNextConsecutive(), src->m_size);
+ PopMemId();
+ memcpy(dst->GetDataPointer(), src->GetDataPointer(), src->m_size);
+ memMoved += src->m_size;
+ dst->m_ptrListIndex = src->m_ptrListIndex;
+ src->m_ptrListIndex = -1;
+ Free(src->GetDataPointer());
+ return dst->GetDataPointer();
+}
+
+uint32
+CMemoryHeap::GetMemoryUsed(int32 id)
+{
+ return m_memUsed[id];
+}
+
+uint32
+CMemoryHeap::GetBlocksUsed(int32 id)
+{
+ return m_blocksUsed[id];
+}
+
+void
+CMemoryHeap::PopMemId(void)
+{
+ assert(m_idStack.sp > 0);
+ m_currentMemID = m_idStack.pop();
+ assert(m_currentMemID != MEMID_FREE);
+}
+
+void
+CMemoryHeap::PushMemId(int32 id)
+{
+ MEMORYHEAP_ASSERT(id != MEMID_FREE);
+ assert(m_idStack.sp < 16);
+ m_idStack.push(m_currentMemID);
+ m_currentMemID = id;
+}
+
+void
+CMemoryHeap::ParseHeap(void)
+{
+ char tmp[16];
+ int fd = CFileMgr::OpenFileForWriting("heap.txt");
+ CTimer::Stop();
+
+ // CMemoryHeap::IntegrityCheck();
+
+ uint32 addrQW = 0;
+ for(HeapBlockDesc *block = m_start; block < m_end; block = block->GetNextConsecutive()){
+ char chr = '*'; // free
+ if(block->m_memId != MEMID_FREE)
+ chr = block->m_memId-1 + 'A';
+ int numQW = block->m_size>>4;
+
+ if((addrQW & 0x3F) == 0){
+ sprintf(tmp, "\n%5dK:", addrQW>>6);
+ CFileMgr::Write(fd, tmp, 8);
+ }
+ CFileMgr::Write(fd, "#", 1); // the descriptor, has to be 16 bytes!!!!
+ addrQW++;
+
+ while(numQW--){
+ if((addrQW & 0x3F) == 0){
+ sprintf(tmp, "\n%5dK:", addrQW>>6);
+ CFileMgr::Write(fd, tmp, 8);
+ }
+ CFileMgr::Write(fd, &chr, 1);
+ addrQW++;
+ }
+ }
+
+ CTimer::Update();
+ CFileMgr::CloseFile(fd);
+}
+
+
+void
+CommonSize::Init(uint32 size)
+{
+ m_freeList.Init();
+ m_size = size;
+ m_failed = 0;
+ m_remaining = 0;
+}
+
+#endif
diff --git a/src/rw/MemoryHeap.h b/src/rw/MemoryHeap.h
new file mode 100644
index 00000000..1a9a51f8
--- /dev/null
+++ b/src/rw/MemoryHeap.h
@@ -0,0 +1,204 @@
+#pragma once
+
+// some windows shit
+#ifdef MoveMemory
+#undef MoveMemory
+#endif
+
+#ifdef USE_CUSTOM_ALLOCATOR
+#define PUSH_MEMID(id) gMainHeap.PushMemId(id)
+#define POP_MEMID() gMainHeap.PopMemId()
+#define REGISTER_MEMPTR(ptr) gMainHeap.RegisterMemPointer(ptr)
+#else
+#define PUSH_MEMID(id)
+#define POP_MEMID()
+#define REGISTER_MEMPTR(ptr)
+#endif
+
+enum {
+ MEMID_FREE,
+ 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"
+ MEMID_STREAM_LODS = 8, // "Streamed LODs"
+ MEMID_STREAM_TEXUTRES = 9, // "Streamed Textures"
+ MEMID_STREAM_COLLISION = 10, // "Streamed Collision"
+ MEMID_STREAM_ANIMATION = 11, // "Streamed Animation"
+ MEMID_TEXTURES = 12, // "Textures"
+ MEMID_COLLISION = 13, // "Collision"
+ MEMID_PRE_ALLOC = 14, // "PreAlloc"
+ MEMID_GAME_PROCESS = 15, // "Game Process"
+ MEMID_SCRIPT = 16, // "Script"
+ MEMID_CARS = 17, // "Cars"
+ MEMID_RENDER = 18, // "Render"
+ MEMID_PED_ATTR = 19, // "Ped Attr"
+ NUM_MEMIDS,
+
+ NUM_FIXED_MEMBLOCKS = 6
+};
+
+template<typename T, uint32 N>
+class CStack
+{
+public:
+ T values[N];
+ uint32 sp;
+
+ CStack() : sp(0) {}
+ void push(const T& val) { values[sp++] = val; }
+ T& pop() { return values[--sp]; }
+};
+
+
+struct HeapBlockDesc
+{
+ uint32 m_size;
+ int16 m_memId;
+ int16 m_ptrListIndex;
+ HeapBlockDesc *m_next;
+ HeapBlockDesc *m_prev;
+
+ HeapBlockDesc *GetNextConsecutive(void)
+ {
+ return (HeapBlockDesc*)((uintptr)this + sizeof(HeapBlockDesc) + m_size);
+ }
+
+ void *GetDataPointer(void)
+ {
+ return (void*)((uintptr)this + sizeof(HeapBlockDesc));
+ }
+
+ void RemoveHeapFreeBlock(void)
+ {
+ m_next->m_prev = m_prev;
+ m_prev->m_next = m_next;
+ }
+
+ // after node
+ void InsertHeapFreeBlock(HeapBlockDesc *node)
+ {
+ m_next = node->m_next;
+ node->m_next->m_prev = this;
+ m_prev = node;
+ node->m_next = this;
+ }
+
+ HeapBlockDesc *FindSmallestFreeBlock(uint32 size)
+ {
+ HeapBlockDesc *b;
+ for(b = m_next; b->m_size < size; b = b->m_next);
+ return b;
+ }
+};
+
+#ifdef USE_CUSTOM_ALLOCATOR
+// TODO: figure something out for 64 bit pointers
+static_assert(sizeof(HeapBlockDesc) == 0x10, "HeapBlockDesc must have 0x10 size otherwise most of assumptions don't make sense");
+#endif
+
+struct HeapBlockList
+{
+ HeapBlockDesc m_first;
+ HeapBlockDesc m_last;
+
+ void Init(void)
+ {
+ m_first.m_next = &m_last;
+ m_last.m_prev = &m_first;
+ }
+
+ void Insert(HeapBlockDesc *node)
+ {
+ node->InsertHeapFreeBlock(&m_first);
+ }
+};
+
+struct CommonSize
+{
+ HeapBlockList m_freeList;
+ uint32 m_size;
+ uint32 m_failed;
+ uint32 m_remaining;
+
+ void Init(uint32 size);
+ void Free(HeapBlockDesc *node)
+ {
+ m_freeList.Insert(node);
+ m_remaining++;
+ }
+ HeapBlockDesc *Malloc(void)
+ {
+ if(m_freeList.m_first.m_next == &m_freeList.m_last){
+ m_failed++;
+ return nil;
+ }
+ HeapBlockDesc *block = m_freeList.m_first.m_next;
+ m_remaining--;
+ block->RemoveHeapFreeBlock();
+ block->m_ptrListIndex = -1;
+ return block;
+ }
+};
+
+class CMemoryHeap
+{
+public:
+ HeapBlockDesc *m_start;
+ HeapBlockDesc *m_end;
+ HeapBlockList m_freeList;
+ CommonSize m_fixedSize[NUM_FIXED_MEMBLOCKS];
+ uint32 m_totalMemUsed;
+ CStack<int32, 16> m_idStack;
+ uint32 m_currentMemID;
+ uint32 *m_memUsed;
+ uint32 m_totalBlocksUsed;
+ uint32 *m_blocksUsed;
+ uint32 m_unkMemId;
+
+ CMemoryHeap(void) : m_start(nil) {}
+ void Init(uint32 total);
+ void RegisterMalloc(HeapBlockDesc *block);
+ void RegisterFree(HeapBlockDesc *block);
+ void *Malloc(uint32 size);
+ void *Realloc(void *ptr, uint32 size);
+ void Free(void *ptr);
+ void FillInBlockData(HeapBlockDesc *block, HeapBlockDesc *end, uint32 size);
+ uint32 CombineFreeBlocks(HeapBlockDesc *block);
+ void *MoveMemory(void *ptr);
+ HeapBlockDesc *WhereShouldMemoryMove(void *ptr);
+ void *MoveHeapBlock(HeapBlockDesc *dst, HeapBlockDesc *src);
+ void PopMemId(void);
+ void PushMemId(int32 id);
+ void RegisterMemPointer(void *ptr);
+ void TidyHeap(void);
+ uint32 GetMemoryUsed(int32 id);
+ uint32 GetBlocksUsed(int32 id);
+ int32 GetLargestFreeBlock(void) { return m_freeList.m_last.m_prev->m_size; }
+
+ void ParseHeap(void);
+
+ HeapBlockDesc *GetDescFromHeapPointer(void *block)
+ {
+ return (HeapBlockDesc*)((uintptr)block - sizeof(HeapBlockDesc));
+ }
+ uint32 GetSizeBetweenBlocks(HeapBlockDesc *first, HeapBlockDesc *second)
+ {
+ return (uintptr)second - (uintptr)first - sizeof(HeapBlockDesc);
+ }
+ void FreeBlock(HeapBlockDesc *block){
+ for(int i = 0; i < NUM_FIXED_MEMBLOCKS; i++){
+ if(m_fixedSize[i].m_size == block->m_size){
+ m_fixedSize[i].Free(block);
+ return;
+ }
+ }
+ HeapBlockDesc *b = m_freeList.m_first.FindSmallestFreeBlock(block->m_size);
+ block->InsertHeapFreeBlock(b->m_prev);
+ }
+};
+
+extern CMemoryHeap gMainHeap;
diff --git a/src/rw/MemoryMgr.cpp b/src/rw/MemoryMgr.cpp
new file mode 100644
index 00000000..e2f6f144
--- /dev/null
+++ b/src/rw/MemoryMgr.cpp
@@ -0,0 +1,130 @@
+#include "common.h"
+#include "MemoryHeap.h"
+#include "MemoryMgr.h"
+
+
+uint8 *pMemoryTop;
+
+void
+InitMemoryMgr(void)
+{
+#ifdef USE_CUSTOM_ALLOCATOR
+#ifdef GTA_PS2
+#error "finish this"
+#else
+ // randomly allocate 128mb
+ gMainHeap.Init(128*1024*1024);
+#endif
+#endif
+}
+
+
+RwMemoryFunctions memFuncs = {
+ MemoryMgrMalloc,
+ MemoryMgrFree,
+ MemoryMgrRealloc,
+ MemoryMgrCalloc
+};
+
+#ifdef USE_CUSTOM_ALLOCATOR
+// game seems to be using heap directly here, but this is nicer
+void *operator new(size_t sz) { return MemoryMgrMalloc(sz); }
+void *operator new[](size_t sz) { return MemoryMgrMalloc(sz); }
+void operator delete(void *ptr) noexcept { MemoryMgrFree(ptr); }
+void operator delete[](void *ptr) noexcept { MemoryMgrFree(ptr); }
+#endif
+
+void*
+MemoryMgrMalloc(size_t size)
+{
+#ifdef USE_CUSTOM_ALLOCATOR
+ void *mem = gMainHeap.Malloc(size);
+#else
+ void *mem = malloc(size);
+#endif
+ if((uint8*)mem + size > pMemoryTop)
+ pMemoryTop = (uint8*)mem + size ;
+ return mem;
+}
+
+void*
+MemoryMgrRealloc(void *ptr, size_t size)
+{
+#ifdef USE_CUSTOM_ALLOCATOR
+ void *mem = gMainHeap.Realloc(ptr, size);
+#else
+ void *mem = realloc(ptr, size);
+#endif
+ if((uint8*)mem + size > pMemoryTop)
+ pMemoryTop = (uint8*)mem + size ;
+ return mem;
+}
+
+void*
+MemoryMgrCalloc(size_t num, size_t size)
+{
+#ifdef USE_CUSTOM_ALLOCATOR
+ void *mem = gMainHeap.Malloc(num*size);
+#else
+ void *mem = calloc(num, size);
+#endif
+ if((uint8*)mem + size > pMemoryTop)
+ pMemoryTop = (uint8*)mem + size ;
+#ifdef FIX_BUGS
+ memset(mem, 0, num*size);
+#endif
+ return mem;
+}
+
+void
+MemoryMgrFree(void *ptr)
+{
+#ifdef USE_CUSTOM_ALLOCATOR
+#ifdef FIX_BUGS
+ // i don't suppose this is handled by RW?
+ if(ptr == nil) return;
+#endif
+ gMainHeap.Free(ptr);
+#else
+ free(ptr);
+#endif
+}
+
+void *
+RwMallocAlign(RwUInt32 size, RwUInt32 align)
+{
+#ifdef FIX_BUGS
+ uintptr ptralign = align-1;
+ void *mem = (void *)MemoryMgrMalloc(size + sizeof(uintptr) + ptralign);
+
+ ASSERT(mem != nil);
+
+ void *addr = (void *)((((uintptr)mem) + sizeof(uintptr) + ptralign) & ~ptralign);
+
+ ASSERT(addr != nil);
+#else
+ void *mem = (void *)MemoryMgrMalloc(size + align);
+
+ ASSERT(mem != nil);
+
+ void *addr = (void *)((((uintptr)mem) + align) & ~(align - 1));
+
+ ASSERT(addr != nil);
+#endif
+
+ *(((void **)addr) - 1) = mem;
+
+ return addr;
+}
+
+void
+RwFreeAlign(void *mem)
+{
+ ASSERT(mem != nil);
+
+ void *addr = *(((void **)mem) - 1);
+
+ ASSERT(addr != nil);
+
+ MemoryMgrFree(addr);
+}
diff --git a/src/rw/MemoryMgr.h b/src/rw/MemoryMgr.h
new file mode 100644
index 00000000..e2962806
--- /dev/null
+++ b/src/rw/MemoryMgr.h
@@ -0,0 +1,12 @@
+#pragma once
+
+extern RwMemoryFunctions memFuncs;
+void InitMemoryMgr(void);
+
+void *MemoryMgrMalloc(size_t size);
+void *MemoryMgrRealloc(void *ptr, size_t size);
+void *MemoryMgrCalloc(size_t num, size_t size);
+void MemoryMgrFree(void *ptr);
+
+void *RwMallocAlign(RwUInt32 size, RwUInt32 align);
+void RwFreeAlign(void *mem);
diff --git a/src/rw/RwHelper.cpp b/src/rw/RwHelper.cpp
index 4c4fc434..cab3b68c 100644
--- a/src/rw/RwHelper.cpp
+++ b/src/rw/RwHelper.cpp
@@ -18,7 +18,7 @@ bool gPS2alphaTest = true;
#else
bool gPS2alphaTest = false;
#endif
-bool gBackfaceCulling;
+bool gBackfaceCulling = true;
#if !defined(FINAL) || defined(DEBUGMENU)
static bool charsetOpen;
@@ -63,45 +63,6 @@ void FlushObrsPrintfs()
#endif
}
-void *
-RwMallocAlign(RwUInt32 size, RwUInt32 align)
-{
-#ifdef FIX_BUGS
- uintptr ptralign = align-1;
- void *mem = (void *)malloc(size + sizeof(uintptr) + ptralign);
-
- ASSERT(mem != nil);
-
- void *addr = (void *)((((uintptr)mem) + sizeof(uintptr) + ptralign) & ~ptralign);
-
- ASSERT(addr != nil);
-#else
- void *mem = (void *)malloc(size + align);
-
- ASSERT(mem != nil);
-
- void *addr = (void *)((((uintptr)mem) + align) & ~(align - 1));
-
- ASSERT(addr != nil);
-#endif
-
- *(((void **)addr) - 1) = mem;
-
- return addr;
-}
-
-void
-RwFreeAlign(void *mem)
-{
- ASSERT(mem != nil);
-
- void *addr = *(((void **)mem) - 1);
-
- ASSERT(addr != nil);
-
- free(addr);
-}
-
void
DefinedState(void)
{
@@ -328,26 +289,6 @@ HAnimAnimationCreateForHierarchy(RpHAnimHierarchy *hier)
return anim;
}
-RpAtomic*
-AtomicRemoveAnimFromSkinCB(RpAtomic *atomic, void *data)
-{
- if(RpSkinGeometryGetSkin(RpAtomicGetGeometry(atomic))){
- RpHAnimHierarchy *hier = RpSkinAtomicGetHAnimHierarchy(atomic);
-#ifdef LIBRW
- if(hier && hier->interpolator->currentAnim){
- RpHAnimAnimationDestroy(hier->interpolator->currentAnim);
- hier->interpolator->currentAnim = nil;
- }
-#else
- if(hier && hier->currentAnim){
- RpHAnimAnimationDestroy(hier->currentAnim->pCurrentAnim);
- hier->currentAnim = nil;
- }
-#endif
- }
- return atomic;
-}
-
void
RenderSkeleton(RpHAnimHierarchy *hier)
{
@@ -727,13 +668,6 @@ CameraCreate(RwInt32 width, RwInt32 height, RwBool zBuffer)
return (nil);
}
-#ifdef USE_TEXTURE_POOL
-WRAPPER void _TexturePoolsInitialise() { EAXJMP(0x6271E0); }
-WRAPPER void _TexturePoolsShutdown() { EAXJMP(0x627080); }
-WRAPPER void _TexturePoolsFinalShutdown() { EAXJMP(0x626F80); }
-WRAPPER void _TexturePoolsUnknown(bool) { EAXJMP(0x626F70); }
-#endif
-
#ifdef LIBRW
#include <rpmatfx.h>
#include "VehicleModelInfo.h"
diff --git a/src/rw/RwHelper.h b/src/rw/RwHelper.h
index cbcbb2e0..9352d1fd 100644
--- a/src/rw/RwHelper.h
+++ b/src/rw/RwHelper.h
@@ -3,9 +3,6 @@
extern bool gPS2alphaTest;
extern bool gBackfaceCulling;
-void *RwMallocAlign(RwUInt32 size, RwUInt32 align);
-void RwFreeAlign(void *mem);
-
void OpenCharsetSafe();
void CreateDebugFont();
void DestroyDebugFont();
@@ -54,8 +51,6 @@ RwCamera *CameraCreate(RwInt32 width,
RwBool zBuffer);
-void _TexturePoolsInitialise();
-void _TexturePoolsShutdown();
RpAtomic *ConvertPlatformAtomic(RpAtomic *atomic, void *data);
diff --git a/src/rw/TexRead.cpp b/src/rw/TexRead.cpp
index ad7d8fec..c5252f77 100644
--- a/src/rw/TexRead.cpp
+++ b/src/rw/TexRead.cpp
@@ -24,6 +24,7 @@
#include "Sprite2d.h"
#include "Text.h"
#include "RwHelper.h"
+#include "Frontend.h"
#endif //GTA_PC
float texLoadTime;
@@ -165,12 +166,82 @@ RwTexDictionaryGtaStreamRead2(RwStream *stream, RwTexDictionary *texDict)
}
#ifdef GTA_PC
-#ifdef RWLIBS
+
+#ifdef LIBRW
+
+#define CAPSVERSION 0
+
+struct GPUcaps
+{
+ uint32 version; // so we can force regeneration easily
+ uint32 platform;
+ uint32 subplatform;
+ uint32 dxtSupport;
+};
+
+static void
+GetGPUcaps(GPUcaps *caps)
+{
+ caps->version = CAPSVERSION;
+ caps->platform = rw::platform;
+ caps->subplatform = 0;
+ caps->dxtSupport = 0;
+ // TODO: more later
+#ifdef RW_GL3
+ caps->subplatform = rw::gl3::gl3Caps.gles;
+ caps->dxtSupport = rw::gl3::gl3Caps.dxtSupported;
+#endif
+#ifdef RW_D3D9
+ caps->dxtSupport = 1; // TODO, probably
+#endif
+}
+
+void
+ReadVideoCardCapsFile(GPUcaps *caps)
+{
+ memset(caps, 0, sizeof(GPUcaps));
+
+ int32 file = CFileMgr::OpenFile("DATA\\CAPS.DAT", "rb");
+ if (file != 0) {
+ CFileMgr::Read(file, (char*)&caps->version, 4);
+ CFileMgr::Read(file, (char*)&caps->platform, 4);
+ CFileMgr::Read(file, (char*)&caps->subplatform, 4);
+ CFileMgr::Read(file, (char*)&caps->dxtSupport, 4);
+ CFileMgr::CloseFile(file);
+ }
+}
+
+bool
+CheckVideoCardCaps(void)
+{
+ GPUcaps caps, fcaps;
+ GetGPUcaps(&caps);
+ ReadVideoCardCapsFile(&fcaps);
+ return caps.version != fcaps.version ||
+ caps.platform != fcaps.platform ||
+ caps.subplatform != fcaps.subplatform ||
+ caps.dxtSupport != fcaps.dxtSupport;
+}
+
+void
+WriteVideoCardCapsFile(void)
+{
+ GPUcaps caps;
+ GetGPUcaps(&caps);
+ int32 file = CFileMgr::OpenFile("DATA\\CAPS.DAT", "wb");
+ if (file != 0) {
+ CFileMgr::Write(file, (char*)&caps.version, 4);
+ CFileMgr::Write(file, (char*)&caps.platform, 4);
+ CFileMgr::Write(file, (char*)&caps.subplatform, 4);
+ CFileMgr::Write(file, (char*)&caps.dxtSupport, 4);
+ CFileMgr::CloseFile(file);
+ }
+}
+
+
+#else
extern "C" RwInt32 _rwD3D8FindCorrectRasterFormat(RwRasterType type, RwInt32 flags);
extern "C" RwBool _rwD3D8CheckValidTextureFormat(RwInt32 format);
-#else
-RwInt32 _rwD3D8FindCorrectRasterFormat(RwRasterType type, RwInt32 flags);
-#endif
void
ReadVideoCardCapsFile(uint32 &cap32, uint32 &cap24, uint32 &cap16, uint32 &cap8)
{
@@ -217,6 +288,7 @@ WriteVideoCardCapsFile(void)
CFileMgr::CloseFile(file);
}
}
+#endif
bool
CanVideoCardDoDXT(void)
@@ -313,6 +385,22 @@ CreateTxdImageForVideoCard()
return false;
}
+#ifdef RW_GL3
+ // so we can read back DXT with GLES
+ // only works for textures that are not yet loaded
+ // so let's hope that is the case for all
+ rw::gl3::needToReadBackTextures = true;
+#endif
+
+#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 = FrontEndMenuManager.m_PrefsVsync;
+ int8 frameLimiterState = FrontEndMenuManager.m_PrefsFrameLimiter;
+ FrontEndMenuManager.m_PrefsVsync = 0;
+ FrontEndMenuManager.m_PrefsFrameLimiter = 0;
+#endif
+
int32 i;
for (i = 0; i < TXDSTORESIZE; i++) {
ConvertingTexturesScreen(i, TXDSTORESIZE, "CVT_MSG");
@@ -340,6 +428,9 @@ CreateTxdImageForVideoCard()
delete []buf;
delete pDir;
CStreaming::RemoveTxd(i);
+#ifdef RW_GL3
+ rw::gl3::needToReadBackTextures = false;
+#endif
return false;
}
@@ -363,9 +454,19 @@ CreateTxdImageForVideoCard()
}
}
+#ifdef DISABLE_VSYNC_ON_TEXTURE_CONVERSION
+ // restore vsync and frame limiter states
+ FrontEndMenuManager.m_PrefsVsync = vsyncState;
+ FrontEndMenuManager.m_PrefsFrameLimiter = frameLimiterState;
+#endif
+
RwStreamClose(img, nil);
delete []buf;
+#ifdef RW_GL3
+ rw::gl3::needToReadBackTextures = false;
+#endif
+
if (!pDir->WriteDirFile("models\\txd.dir")) {
DealWithTxdWriteError(i, TXDSTORESIZE, "CVT_ERR");
delete pDir;
diff --git a/src/rw/TexturePools.cpp b/src/rw/TexturePools.cpp
new file mode 100644
index 00000000..c2ba6cf9
--- /dev/null
+++ b/src/rw/TexturePools.cpp
@@ -0,0 +1,221 @@
+#ifndef LIBRW
+
+#include <d3d8.h>
+#define WITHD3D
+#include "common.h"
+#include "TexturePools.h"
+
+// TODO: this needs to be integrated into RW
+
+extern "C" LPDIRECT3DDEVICE8 _RwD3DDevice;
+
+CTexturePool aTexturePools[12];
+CPaletteList PaletteList;
+int numTexturePools;
+int MaxPaletteIndex;
+bool bUsePaletteIndex = true;
+
+
+void
+CTexturePool::Create(D3DFORMAT _Format, int _size, uint32 mipmapLevels, int32 numTextures)
+{
+ Format = _Format;
+ size = _size;
+ levels = mipmapLevels;
+ pTextures = new IDirect3DTexture8 *[numTextures];
+ texturesMax = numTextures;
+ texturesNum = 0;
+ texturesUsed = 0;
+}
+
+void
+CTexturePool::Release()
+{
+ int i = 0;
+ while (i < texturesNum) {
+ pTextures[i]->Release();
+ i++;
+ }
+
+ delete[] pTextures;
+
+ pTextures = nil;
+ texturesNum = 0;
+ texturesUsed = 0;
+}
+
+IDirect3DTexture8 *
+CTexturePool::FindTexture()
+{
+ if (texturesNum == 0)
+ return nil;
+ texturesUsed--;
+ return pTextures[--texturesNum];
+}
+
+bool
+CTexturePool::AddTexture(IDirect3DTexture8 *texture)
+{
+ ++texturesUsed;
+ if (texturesNum >= texturesMax)
+ return false;
+ pTextures[texturesNum] = texture;
+ ++texturesNum;
+ return true;
+}
+
+void
+CTexturePool::Resize(int numTextures)
+{
+ if (numTextures == texturesMax)
+ return;
+
+ IDirect3DTexture8 **newTextures = new IDirect3DTexture8 *[numTextures];
+
+ for (int i = 0; i < texturesNum && i < numTextures; i++)
+ newTextures[i] = pTextures[i];
+
+ if (numTextures < texturesNum) {
+ for (int i = numTextures; i < texturesNum; i++)
+ pTextures[i]->Release();
+ }
+ delete[] pTextures;
+ pTextures = newTextures;
+ texturesMax = numTextures;
+}
+
+void
+CPaletteList::Alloc(int max)
+{
+ Data = new int[max];
+ Max = max;
+ Num = 0;
+}
+
+void
+CPaletteList::Free()
+{
+ delete[] Data;
+ Data = nil;
+ Num = 0;
+}
+
+int
+CPaletteList::Find()
+{
+ if (Num == 0)
+ return -1;
+ return Data[--Num];
+}
+
+void
+CPaletteList::Add(int item)
+{
+ if (Num < Max)
+ Data[Num++] = item;
+ else {
+ Resize(2 * Max);
+ Add(item);
+ }
+}
+
+void
+CPaletteList::Resize(int max)
+{
+ if (max == Max)
+ return;
+
+ int *newData = new int[4 * max];
+ for (int i = 0; i < Num && i < max; i++)
+ newData[i] = Data[i];
+ delete[] Data;
+ Data = newData;
+ Max = max;
+}
+
+HRESULT
+CreateTexture(int width, int height, int levels, D3DFORMAT Format, IDirect3DTexture8 **texture)
+{
+ if (width == height) {
+ for (int i = 0; i < numTexturePools; i++) {
+ if (width != aTexturePools[i].GetSize() && levels == aTexturePools[i].levels && Format == aTexturePools[i].Format)
+ *texture = aTexturePools[i].FindTexture();
+ }
+ }
+ if (*texture)
+ return D3D_OK;
+ else
+ return _RwD3DDevice->CreateTexture(width, height, levels, 0, Format, D3DPOOL_MANAGED, texture);
+}
+
+void
+ReleaseTexture(IDirect3DTexture8 *texture)
+{
+ int levels = 1;
+ if (texture->GetLevelCount() > 1)
+ levels = 0;
+
+ D3DSURFACE_DESC SURFACE_DESC;
+
+ texture->GetLevelDesc(0, &SURFACE_DESC);
+
+ if (SURFACE_DESC.Width == SURFACE_DESC.Height) {
+ for (int i = 0; i < numTexturePools; i++) {
+ if (SURFACE_DESC.Width == aTexturePools[i].GetSize() && SURFACE_DESC.Format == aTexturePools[i].Format && levels == aTexturePools[i].levels) {
+ if (!aTexturePools[i].AddTexture(texture)) {
+ if (aTexturePools[i].texturesUsed > 3 * aTexturePools[i].texturesMax / 2) {
+ aTexturePools[i].Resize(2 * aTexturePools[i].texturesMax);
+ aTexturePools[i].texturesUsed--;
+ aTexturePools[i].AddTexture(texture);
+ } else {
+ texture->Release();
+ }
+ }
+ return;
+ }
+ }
+ }
+ if (numTexturePools < 12 && bUsePaletteIndex && levels != 0 && SURFACE_DESC.Width == SURFACE_DESC.Height &&
+ (SURFACE_DESC.Width == 64 || SURFACE_DESC.Width == 128 || SURFACE_DESC.Width == 256)) {
+ aTexturePools[numTexturePools].Create(SURFACE_DESC.Format, SURFACE_DESC.Width, 1, 16);
+ aTexturePools[numTexturePools].AddTexture(texture);
+ numTexturePools++;
+ } else
+ texture->Release();
+}
+
+int
+FindAvailablePaletteIndex()
+{
+ int index = PaletteList.Find();
+ if (index == -1)
+ index = MaxPaletteIndex++;
+ return index;
+}
+
+void
+AddAvailablePaletteIndex(int index)
+{
+ if (bUsePaletteIndex)
+ PaletteList.Add(index);
+}
+
+void
+_TexturePoolsInitialise()
+{
+ PaletteList.Alloc(100);
+ MaxPaletteIndex = 0;
+}
+
+void
+_TexturePoolsShutdown()
+{
+ for (int i = 0; i < numTexturePools; i++)
+ aTexturePools[i].Release();
+
+ numTexturePools = 0;
+ bUsePaletteIndex = false;
+ PaletteList.Free();
+}
+
+#endif // !LIBRW \ No newline at end of file
diff --git a/src/rw/TexturePools.h b/src/rw/TexturePools.h
new file mode 100644
index 00000000..75187432
--- /dev/null
+++ b/src/rw/TexturePools.h
@@ -0,0 +1,42 @@
+#pragma once
+
+class CTexturePool
+{
+public:
+ D3DFORMAT Format;
+ int size;
+ uint32 levels;
+ int32 texturesMax;
+ int32 texturesUsed;
+ int32 texturesNum;
+ IDirect3DTexture8 **pTextures;
+
+public:
+ CTexturePool() {}
+ void Create(D3DFORMAT _Format, int size, uint32 mipmapLevels, int32 numTextures);
+ void Release();
+ IDirect3DTexture8 *FindTexture();
+ bool AddTexture(IDirect3DTexture8 *texture);
+ void Resize(int numTextures);
+#ifdef FIX_BUGS
+ int GetSize() { return size; }
+#else
+ float GetSize() { return size; }
+#endif
+};
+
+class CPaletteList
+{
+ int Max;
+ int Num;
+ int *Data;
+public:
+ void Alloc(int max);
+ void Free();
+ int Find();
+ void Add(int item);
+ void Resize(int max);
+};
+
+void _TexturePoolsInitialise();
+void _TexturePoolsShutdown(); \ No newline at end of file
diff --git a/src/rw/VisibilityPlugins.cpp b/src/rw/VisibilityPlugins.cpp
index c79cb52b..83c3c5bc 100644
--- a/src/rw/VisibilityPlugins.cpp
+++ b/src/rw/VisibilityPlugins.cpp
@@ -1,5 +1,6 @@
#include "common.h"
+#include "RwHelper.h"
#include "templates.h"
#include "main.h"
#include "Entity.h"
@@ -11,11 +12,10 @@
#include "VisibilityPlugins.h"
#include "World.h"
#include "custompipes.h"
+#include "MemoryHeap.h"
//--MIAMI: file done
-#define FADE_DISTANCE 20.0f
-
CLinkList<CVisibilityPlugins::AlphaObjectInfo> CVisibilityPlugins::m_alphaList;
CLinkList<CVisibilityPlugins::AlphaObjectInfo> CVisibilityPlugins::m_alphaBoatAtomicList;
CLinkList<CVisibilityPlugins::AlphaObjectInfo> CVisibilityPlugins::m_alphaEntityList;
@@ -39,6 +39,8 @@ float CVisibilityPlugins::ms_bigVehicleLod1Dist;
float CVisibilityPlugins::ms_pedLod1Dist;
float CVisibilityPlugins::ms_pedFadeDist;
+#define RENDERCALLBACK AtomicDefaultRenderCallBack
+
void
CVisibilityPlugins::Initialise(void)
{
@@ -132,6 +134,10 @@ CVisibilityPlugins::InsertAtomicIntoBoatSortedList(RpAtomic *a, float dist)
return !!m_alphaBoatAtomicList.InsertSorted(item);
}
+// can't increase this yet unfortunately...
+// probably have to fix fading for this so material alpha isn't overwritten
+#define VEHICLE_LODDIST_MULTIPLIER (TheCamera.GenerationDistMultiplier)
+
void
CVisibilityPlugins::SetRenderWareCamera(RwCamera *camera)
{
@@ -144,13 +150,13 @@ CVisibilityPlugins::SetRenderWareCamera(RwCamera *camera)
else
ms_cullCompsDist = sq(TheCamera.LODDistMultiplier * 20.0f);
- ms_vehicleLod0Dist = sq(70.0f * TheCamera.GenerationDistMultiplier);
- ms_vehicleLod1Dist = sq(90.0f * TheCamera.GenerationDistMultiplier);
- ms_vehicleFadeDist = sq(100.0f * TheCamera.GenerationDistMultiplier);
- ms_bigVehicleLod0Dist = sq(60.0f * TheCamera.GenerationDistMultiplier);
- ms_bigVehicleLod1Dist = sq(150.0f * TheCamera.GenerationDistMultiplier);
- 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;
@@ -187,7 +193,7 @@ CVisibilityPlugins::RenderAtomicList(CLinkList<AlphaObjectInfo> &list)
{
CLink<AlphaObjectInfo> *node;
for(node = list.tail.prev; node != &list.head; node = node->prev)
- AtomicDefaultRenderCallBack(node->item.atomic);
+ RENDERCALLBACK(node->item.atomic);
}
void
@@ -257,11 +263,11 @@ CVisibilityPlugins::RenderWheelAtomicCB(RpAtomic *atomic)
mi = GetAtomicModelInfo(atomic);
len = Sqrt(DistToCameraSq);
- lodatm = mi->GetAtomicFromDistance(len * TheCamera.LODDistMultiplier / TheCamera.GenerationDistMultiplier);
+ lodatm = mi->GetAtomicFromDistance(len * TheCamera.LODDistMultiplier / VEHICLE_LODDIST_MULTIPLIER);
if(lodatm){
if(RpAtomicGetGeometry(lodatm) != RpAtomicGetGeometry(atomic))
RpAtomicSetGeometry(atomic, RpAtomicGetGeometry(lodatm), rpATOMICSAMEBOUNDINGSPHERE);
- AtomicDefaultRenderCallBack(atomic);
+ RENDERCALLBACK(atomic);
}
return atomic;
}
@@ -278,7 +284,7 @@ CVisibilityPlugins::RenderObjNormalAtomic(RpAtomic *atomic)
len = RwV3dLength(&view);
if(RwV3dDotProduct(&view, RwMatrixGetUp(m)) < -0.3f*len && len > 8.0f)
return atomic;
- AtomicDefaultRenderCallBack(atomic);
+ RENDERCALLBACK(atomic);
return atomic;
}
@@ -292,7 +298,7 @@ CVisibilityPlugins::RenderAlphaAtomic(RpAtomic *atomic, int alpha)
flags = RpGeometryGetFlags(geo);
RpGeometrySetFlags(geo, flags | rpGEOMETRYMODULATEMATERIALCOLOR);
RpGeometryForAllMaterials(geo, SetAlphaCB, (void*)alpha);
- AtomicDefaultRenderCallBack(atomic);
+ RENDERCALLBACK(atomic);
RpGeometryForAllMaterials(geo, SetAlphaCB, (void*)255);
RpGeometrySetFlags(geo, flags);
return atomic;
@@ -312,7 +318,7 @@ CVisibilityPlugins::RenderWeaponCB(RpAtomic *atomic)
maxdist = mi->GetLodDistance(0);
distsq = RwV3dDotProduct(&view, &view);
if(distsq < maxdist*maxdist)
- AtomicDefaultRenderCallBack(atomic);
+ RENDERCALLBACK(atomic);
return atomic;
}
@@ -334,7 +340,7 @@ CVisibilityPlugins::RenderFadingAtomic(RpAtomic *atomic, float camdist)
fadefactor = 1.0f;
alpha = mi->m_alpha * fadefactor;
if(alpha == 255)
- AtomicDefaultRenderCallBack(atomic);
+ RENDERCALLBACK(atomic);
else{
RpGeometry *geo = RpAtomicGetGeometry(lodatm);
uint32 flags = RpGeometryGetFlags(geo);
@@ -342,7 +348,7 @@ CVisibilityPlugins::RenderFadingAtomic(RpAtomic *atomic, float camdist)
RpGeometryForAllMaterials(geo, SetAlphaCB, (void*)alpha);
if(geo != RpAtomicGetGeometry(atomic))
RpAtomicSetGeometry(atomic, geo, rpATOMICSAMEBOUNDINGSPHERE); // originally 5 (mistake?)
- AtomicDefaultRenderCallBack(atomic);
+ RENDERCALLBACK(atomic);
RpGeometryForAllMaterials(geo, SetAlphaCB, (void*)255);
RpGeometrySetFlags(geo, flags);
}
@@ -371,7 +377,7 @@ CVisibilityPlugins::RenderVehicleHiDetailCB(RpAtomic *atomic)
if(dot > 0.0f && ((flags & ATOMIC_FLAG_ANGLECULL) || 0.1f*DistToCameraSq < dot*dot))
return atomic;
}
- AtomicDefaultRenderCallBack(atomic);
+ RENDERCALLBACK(atomic);
}
return atomic;
}
@@ -395,10 +401,10 @@ CVisibilityPlugins::RenderVehicleHiDetailAlphaCB(RpAtomic *atomic)
if(flags & ATOMIC_FLAG_DRAWLAST){
// sort before clump
if(!InsertAtomicIntoSortedList(atomic, DistToCameraSq - 0.0001f))
- AtomicDefaultRenderCallBack(atomic);
+ RENDERCALLBACK(atomic);
}else{
if(!InsertAtomicIntoSortedList(atomic, DistToCameraSq + dot))
- AtomicDefaultRenderCallBack(atomic);
+ RENDERCALLBACK(atomic);
}
}
return atomic;
@@ -420,7 +426,7 @@ CVisibilityPlugins::RenderVehicleHiDetailCB_BigVehicle(RpAtomic *atomic)
if(dot > 0.0f)
return atomic;
}
- AtomicDefaultRenderCallBack(atomic);
+ RENDERCALLBACK(atomic);
}
return atomic;
}
@@ -442,7 +448,7 @@ CVisibilityPlugins::RenderVehicleHiDetailAlphaCB_BigVehicle(RpAtomic *atomic)
return atomic;
if(!InsertAtomicIntoSortedList(atomic, DistToCameraSq + dot))
- AtomicDefaultRenderCallBack(atomic);
+ RENDERCALLBACK(atomic);
}
return atomic;
}
@@ -451,7 +457,7 @@ RpAtomic*
CVisibilityPlugins::RenderVehicleHiDetailCB_Boat(RpAtomic *atomic)
{
if(DistToCameraSq < ms_bigVehicleLod1Dist)
- AtomicDefaultRenderCallBack(atomic);
+ RENDERCALLBACK(atomic);
return atomic;
}
@@ -461,9 +467,9 @@ CVisibilityPlugins::RenderVehicleHiDetailAlphaCB_Boat(RpAtomic *atomic)
if(DistToCameraSq < ms_vehicleLod0Dist){
if(GetAtomicId(atomic) & ATOMIC_FLAG_DRAWLAST){
if(!InsertAtomicIntoBoatSortedList(atomic, DistToCameraSq))
- AtomicDefaultRenderCallBack(atomic);
+ RENDERCALLBACK(atomic);
}else
- AtomicDefaultRenderCallBack(atomic);
+ RENDERCALLBACK(atomic);
}
return atomic;
}
@@ -485,7 +491,7 @@ CVisibilityPlugins::RenderVehicleLowDetailCB_BigVehicle(RpAtomic *atomic)
if(dot > 0.0f)
return atomic;
}
- AtomicDefaultRenderCallBack(atomic);
+ RENDERCALLBACK(atomic);
}
return atomic;
}
@@ -508,7 +514,7 @@ CVisibilityPlugins::RenderVehicleLowDetailAlphaCB_BigVehicle(RpAtomic *atomic)
return atomic;
if(!InsertAtomicIntoSortedList(atomic, DistToCameraSq + dot))
- AtomicDefaultRenderCallBack(atomic);
+ RENDERCALLBACK(atomic);
}
return atomic;
}
@@ -523,7 +529,7 @@ CVisibilityPlugins::RenderVehicleReallyLowDetailCB(RpAtomic *atomic)
if(DistToCameraSq >= ms_vehicleLod0Dist){
alpha = GetClumpAlpha(clump);
if(alpha == 255)
- AtomicDefaultRenderCallBack(atomic);
+ RENDERCALLBACK(atomic);
else
RenderAlphaAtomic(atomic, alpha);
}
@@ -535,7 +541,7 @@ RpAtomic*
CVisibilityPlugins::RenderVehicleReallyLowDetailCB_BigVehicle(RpAtomic *atomic)
{
if(DistToCameraSq >= ms_bigVehicleLod1Dist)
- AtomicDefaultRenderCallBack(atomic);
+ RENDERCALLBACK(atomic);
return atomic;
}
@@ -555,7 +561,7 @@ CVisibilityPlugins::RenderTrainHiDetailCB(RpAtomic *atomic)
if(dot > 0.0f && ((flags & ATOMIC_FLAG_ANGLECULL) || 0.1f*DistToCameraSq < dot*dot))
return atomic;
}
- AtomicDefaultRenderCallBack(atomic);
+ RENDERCALLBACK(atomic);
}
return atomic;
}
@@ -579,10 +585,10 @@ CVisibilityPlugins::RenderTrainHiDetailAlphaCB(RpAtomic *atomic)
if(flags & ATOMIC_FLAG_DRAWLAST){
// sort before clump
if(!InsertAtomicIntoSortedList(atomic, DistToCameraSq - 0.0001f))
- AtomicDefaultRenderCallBack(atomic);
+ RENDERCALLBACK(atomic);
}else{
if(!InsertAtomicIntoSortedList(atomic, DistToCameraSq + dot))
- AtomicDefaultRenderCallBack(atomic);
+ RENDERCALLBACK(atomic);
}
}
return atomic;
@@ -600,7 +606,7 @@ CVisibilityPlugins::RenderVehicleRotorAlphaCB(RpAtomic *atomic)
RwV3dSub(&cam2atm, &RwFrameGetLTM(RpAtomicGetFrame(atomic))->pos, ms_pCameraPosn);
dot = RwV3dDotProduct(&cam2atm, &RwFrameGetLTM(clumpframe)->at);
if(!InsertAtomicIntoSortedList(atomic, DistToCameraSq + dot*20.0f))
- AtomicDefaultRenderCallBack(atomic);
+ RENDERCALLBACK(atomic);
}
return atomic;
}
@@ -618,7 +624,7 @@ CVisibilityPlugins::RenderVehicleTailRotorAlphaCB(RpAtomic *atomic)
RwV3dSub(&cam2atm, &atmMat->pos, ms_pCameraPosn);
dot = RwV3dDotProduct(&cam2atm, &clumpMat->up) + RwV3dDotProduct(&cam2atm, &clumpMat->right);
if(!InsertAtomicIntoSortedList(atomic, DistToCameraSq - dot))
- AtomicDefaultRenderCallBack(atomic);
+ RENDERCALLBACK(atomic);
}
return atomic;
}
@@ -628,7 +634,7 @@ CVisibilityPlugins::RenderPlayerCB(RpAtomic *atomic)
{
if(CWorld::Players[0].m_pSkinTexture)
RpGeometryForAllMaterials(RpAtomicGetGeometry(atomic), SetTextureCB, CWorld::Players[0].m_pSkinTexture);
- AtomicDefaultRenderCallBack(atomic);
+ RENDERCALLBACK(atomic);
return atomic;
}
@@ -642,7 +648,7 @@ CVisibilityPlugins::RenderPedCB(RpAtomic *atomic)
if(RwV3dDotProduct(&cam2atm, &cam2atm) < ms_pedLod1Dist){
alpha = GetClumpAlpha(RpAtomicGetClump(atomic));
if(alpha == 255)
- AtomicDefaultRenderCallBack(atomic);
+ RENDERCALLBACK(atomic);
else
RenderAlphaAtomic(atomic, alpha);
}
@@ -833,12 +839,11 @@ CVisibilityPlugins::GetAtomicId(RpAtomic *atomic)
return ATOMICEXT(atomic)->flags;
}
-// This is rather useless, but whatever
void
CVisibilityPlugins::SetAtomicRenderCallback(RpAtomic *atomic, RpAtomicCallBackRender cb)
{
if(cb == nil)
- cb = AtomicDefaultRenderCallBack; // not necessary
+ cb = RENDERCALLBACK; // not necessary
RpAtomicSetRenderCallBack(atomic, cb);
}
@@ -867,12 +872,12 @@ CVisibilityPlugins::FrameCopyConstructor(void *dst, const void *src, int32, int3
}
void
-CVisibilityPlugins::SetFrameHierarchyId(RwFrame *frame, uintptr id)
+CVisibilityPlugins::SetFrameHierarchyId(RwFrame *frame, intptr id)
{
FRAMEEXT(frame)->id = id;
}
-uintptr
+intptr
CVisibilityPlugins::GetFrameHierarchyId(RwFrame *frame)
{
return FRAMEEXT(frame)->id;
@@ -909,7 +914,7 @@ void
CVisibilityPlugins::SetClumpModelInfo(RpClump *clump, CClumpModelInfo *modelInfo)
{
CVehicleModelInfo *vmi;
- SetFrameHierarchyId(RpClumpGetFrame(clump), (uintptr)modelInfo);
+ SetFrameHierarchyId(RpClumpGetFrame(clump), (intptr)modelInfo);
// Unused
switch (modelInfo->GetModelType()) {
diff --git a/src/rw/VisibilityPlugins.h b/src/rw/VisibilityPlugins.h
index 03833c9c..13365c7a 100644
--- a/src/rw/VisibilityPlugins.h
+++ b/src/rw/VisibilityPlugins.h
@@ -115,10 +115,10 @@ public:
struct FrameExt
{
// BUG: this is abused to hold a pointer by SetClumpModelInfo
- uintptr id;
+ intptr id;
};
- static void SetFrameHierarchyId(RwFrame *frame, uintptr id);
- static uintptr GetFrameHierarchyId(RwFrame *frame);
+ static void SetFrameHierarchyId(RwFrame *frame, intptr id);
+ static intptr GetFrameHierarchyId(RwFrame *frame);
static void *FrameConstructor(void *object, int32 offset, int32 len);
static void *FrameDestructor(void *object, int32 offset, int32 len);
diff --git a/src/save/MemoryCard.cpp b/src/save/MemoryCard.cpp
index a24b754c..c8ebcd86 100644
--- a/src/save/MemoryCard.cpp
+++ b/src/save/MemoryCard.cpp
@@ -11,6 +11,7 @@
#include "Clock.h"
#include "MBlur.h"
#include "Date.h"
+#include "Font.h"
#include "FileMgr.h"
#include "Game.h"
#include "GameLogic.h"
diff --git a/src/skel/crossplatform.cpp b/src/skel/crossplatform.cpp
index 4b7d3d9a..37c94cb4 100644
--- a/src/skel/crossplatform.cpp
+++ b/src/skel/crossplatform.cpp
@@ -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 1635781b..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>.
@@ -83,9 +87,6 @@ enum eGameState
GS_FRONTEND,
GS_INIT_PLAYING_GAME,
GS_PLAYING_GAME,
-#ifndef MASTER
- GS_ANIMVIEWER,
-#endif
};
extern RwUInt32 gGameState;
diff --git a/src/skel/glfw/glfw.cpp b/src/skel/glfw/glfw.cpp
index 26a3a509..f039819c 100644
--- a/src/skel/glfw/glfw.cpp
+++ b/src/skel/glfw/glfw.cpp
@@ -40,6 +40,7 @@
#include "Sprite2d.h"
#include "AnimViewer.h"
#include "Font.h"
+#include "MemoryMgr.h"
#define MAX_SUBSYSTEMS (16)
@@ -70,9 +71,6 @@ static psGlobalType PsGlobal;
#define PSGLOBAL(var) (((psGlobalType *)(RsGlobal.ps))->var)
-#undef MAKEPOINTS
-#define MAKEPOINTS(l) (*((POINTS /*FAR*/ *)&(l)))
-
size_t _dwMemAvailPhys;
RwUInt32 gGameState;
@@ -249,8 +247,10 @@ double
psTimer(void)
{
struct timespec start;
-#ifdef __linux__
+#if defined(CLOCK_MONOTONIC_RAW)
clock_gettime(CLOCK_MONOTONIC_RAW, &start);
+#elif defined(CLOCK_MONOTONIC_FAST)
+ clock_gettime(CLOCK_MONOTONIC_FAST, &start);
#else
clock_gettime(CLOCK_MONOTONIC, &start);
#endif
@@ -280,7 +280,11 @@ psMouseSetPos(RwV2d *pos)
RwMemoryFunctions*
psGetMemoryFunctions(void)
{
+#ifdef USE_CUSTOM_ALLOCATOR
+ return &memFuncs;
+#else
return nil;
+#endif
}
/*
@@ -839,7 +843,10 @@ psSelectDevice()
PSGLOBAL(fullScreen) = !FrontEndMenuManager.m_nPrefsWindowed;
#endif
-
+
+#ifdef MULTISAMPLING
+ RwD3D8EngineSetMultiSamplingLevels(1 << FrontEndMenuManager.m_nPrefsMSAALevel);
+#endif
return TRUE;
}
@@ -873,6 +880,36 @@ void _InputInitialiseJoys()
PSGLOBAL(joy1id) = -1;
PSGLOBAL(joy2id) = -1;
+ // Load our gamepad mappings.
+#define SDL_GAMEPAD_DB_PATH "gamecontrollerdb.txt"
+ FILE *f = fopen(SDL_GAMEPAD_DB_PATH, "rb");
+ if (f) {
+ fseek(f, 0, SEEK_END);
+ size_t fsize = ftell(f);
+ fseek(f, 0, SEEK_SET);
+
+ char *db = (char*)malloc(fsize + 1);
+ if (fread(db, 1, fsize, f) == fsize) {
+ db[fsize] = '\0';
+
+ if (glfwUpdateGamepadMappings(db) == GLFW_FALSE)
+ Error("glfwUpdateGamepadMappings didn't succeed, check " SDL_GAMEPAD_DB_PATH ".\n");
+ } else
+ Error("fread on " SDL_GAMEPAD_DB_PATH " wasn't successful.\n");
+
+ free(db);
+ fclose(f);
+ } else
+ printf("You don't seem to have copied " SDL_GAMEPAD_DB_PATH " file from re3/gamefiles to GTA3 directory. Some gamepads may not be recognized.\n");
+
+#undef SDL_GAMEPAD_DB_PATH
+
+ // But always overwrite it with the one in SDL_GAMECONTROLLERCONFIG.
+ char const* EnvControlConfig = getenv("SDL_GAMECONTROLLERCONFIG");
+ if (EnvControlConfig != nil) {
+ glfwUpdateGamepadMappings(EnvControlConfig);
+ }
+
for (int i = 0; i <= GLFW_JOYSTICK_LAST; i++) {
if (glfwJoystickPresent(i) && !IsThisJoystickBlacklisted(i)) {
if (PSGLOBAL(joy1id) == -1)
@@ -894,9 +931,12 @@ void _InputInitialiseJoys()
}
}
+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;
}
@@ -905,10 +945,17 @@ 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. Not supported on glfw anyway
- return false;
+ // 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)
@@ -917,7 +964,7 @@ void psPostRWinit(void)
RwEngineGetVideoModeInfo(&vm, GcurSelVM);
glfwSetKeyCallback(PSGLOBAL(window), keypressCB);
- glfwSetWindowSizeCallback(PSGLOBAL(window), resizeCB);
+ glfwSetFramebufferSizeCallback(PSGLOBAL(window), resizeCB);
glfwSetScrollCallback(PSGLOBAL(window), scrollCB);
glfwSetCursorPosCallback(PSGLOBAL(window), cursorCB);
glfwSetCursorEnterCallback(PSGLOBAL(window), cursorEnterCB);
@@ -1189,15 +1236,15 @@ void InitialiseLanguage()
}
}
- TheText.Unload();
- TheText.Load();
-
#ifndef _WIN32
// TODO this is needed for strcasecmp to work correctly across all languages, but can these cause other problems??
setlocale(LC_CTYPE, "C");
setlocale(LC_COLLATE, "C");
setlocale(LC_NUMERIC, "C");
#endif
+
+ TheText.Unload();
+ TheText.Load();
}
/*
@@ -1244,17 +1291,11 @@ void resizeCB(GLFWwindow* window, int width, int height) {
* memory things don't work.
*/
/* redraw window */
-#ifndef MASTER
- if (RwInitialised && (gGameState == GS_PLAYING_GAME || gGameState == GS_ANIMVIEWER))
- {
- RsEventHandler((gGameState == GS_PLAYING_GAME ? rsIDLE : rsANIMVIEWER), (void *)TRUE);
- }
-#else
+
if (RwInitialised && gGameState == GS_PLAYING_GAME)
{
RsEventHandler(rsIDLE, (void *)TRUE);
}
-#endif
if (RwInitialised && height > 0 && width > 0) {
RwRect r;
@@ -1438,8 +1479,13 @@ _InputTranslateShiftKeyUpDown(RsKeyCodes *rs) {
// TODO this only works in frontend(and luckily only frontend use this). Fun fact: if I get pos manually in game, glfw reports that it's > 32000
void
cursorCB(GLFWwindow* window, double xpos, double ypos) {
- FrontEndMenuManager.m_nMouseTempPosX = xpos;
- FrontEndMenuManager.m_nMouseTempPosY = ypos;
+ if (!FrontEndMenuManager.m_bMenuActive)
+ return;
+
+ int winw, winh;
+ glfwGetWindowSize(PSGLOBAL(window), &winw, &winh);
+ FrontEndMenuManager.m_nMouseTempPosX = xpos * (RsGlobal.maximumWidth / winw);
+ FrontEndMenuManager.m_nMouseTempPosY = ypos * (RsGlobal.maximumHeight / winh);
}
void
@@ -1462,12 +1508,14 @@ WinMain(HINSTANCE instance,
RwChar** argv;
SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, nil, SPIF_SENDCHANGE);
-#if 1
- // TODO: make this an option somewhere
- AllocConsole();
- freopen("CONIN$", "r", stdin);
- freopen("CONOUT$", "w", stdout);
- freopen("CONOUT$", "w", stderr);
+#ifndef MASTER
+ if (strstr(cmdLine, "-console"))
+ {
+ AllocConsole();
+ freopen("CONIN$", "r", stdin);
+ freopen("CONOUT$", "w", stdout);
+ freopen("CONOUT$", "w", stderr);
+ }
#endif
#else
@@ -1478,6 +1526,10 @@ main(int argc, char *argv[])
RwV2d pos;
RwInt32 i;
+#ifdef USE_CUSTOM_ALLOCATOR
+ InitMemoryMgr();
+#endif
+
#ifndef _WIN32
struct sigaction act;
act.sa_sigaction = terminateHandler;
@@ -1622,18 +1674,6 @@ main(int argc, char *argv[])
FrontEndMenuManager.DrawMemoryCardStartUpMenus();
}
#endif
-
- if (TurnOnAnimViewer)
- {
-#ifndef MASTER
- CAnimViewer::Initialise();
-#ifndef PS2_MENU
- FrontEndMenuManager.m_bGameNotLoaded = false;
-#endif
- gGameState = GS_ANIMVIEWER;
- TurnOnAnimViewer = false;
-#endif
- }
initkeymap();
@@ -1653,6 +1693,18 @@ main(int argc, char *argv[])
* Enter the message processing loop...
*/
+#ifndef MASTER
+ if (gbModelViewer) {
+ // This is TheModelViewer in LCS
+ LoadingScreen("Loading the ModelViewer", NULL, GetRandomSplashScreen());
+ CAnimViewer::Initialise();
+ CTimer::Update();
+#ifndef PS2_MENU
+ FrontEndMenuManager.m_bGameNotLoaded = false;
+#endif
+ }
+#endif
+
#ifdef PS2_MENU
if (TheMemoryCard.m_bWantToLoad)
LoadSplash(GetLevelSplashScreen(CGame::currLevel));
@@ -1667,7 +1719,13 @@ main(int argc, char *argv[])
#endif
{
glfwPollEvents();
- if( ForegroundApp )
+#ifndef MASTER
+ if (gbModelViewer) {
+ // This is TheModelViewerCore in LCS
+ TheModelViewer();
+ } else
+#endif
+ if ( ForegroundApp )
{
switch ( gGameState )
{
@@ -1871,18 +1929,6 @@ main(int argc, char *argv[])
}
break;
}
-#ifndef MASTER
- case GS_ANIMVIEWER:
- {
- float ms = (float)CTimer::GetCurrentTimeInCycles() / (float)CTimer::GetCyclesPerMillisecond();
- if (RwInitialised)
- {
- if (!FrontEndMenuManager.m_PrefsFrameLimiter || (1000.0f / (float)RsGlobal.maxFPS) < ms)
- RsEventHandler(rsANIMVIEWER, (void*)TRUE);
- }
- break;
- }
-#endif
}
}
else
@@ -1954,12 +2000,13 @@ main(int argc, char *argv[])
}
else
{
- if ( gGameState == GS_PLAYING_GAME )
- CGame::ShutDown();
#ifndef MASTER
- else if ( gGameState == GS_ANIMVIEWER )
+ if ( gbModelViewer )
CAnimViewer::Shutdown();
+ else
#endif
+ if ( gGameState == GS_PLAYING_GAME )
+ CGame::ShutDown();
CTimer::Stop();
@@ -1980,13 +2027,13 @@ main(int argc, char *argv[])
#endif
}
-
- if ( gGameState == GS_PLAYING_GAME )
- CGame::ShutDown();
#ifndef MASTER
- else if ( gGameState == GS_ANIMVIEWER )
+ if ( gbModelViewer )
CAnimViewer::Shutdown();
+ else
#endif
+ if ( gGameState == GS_PLAYING_GAME )
+ CGame::ShutDown();
DMAudio.Terminate();
diff --git a/src/skel/skeleton.cpp b/src/skel/skeleton.cpp
index e21abb17..6f6b3744 100644
--- a/src/skel/skeleton.cpp
+++ b/src/skel/skeleton.cpp
@@ -10,13 +10,13 @@
#include "skeleton.h"
#include "platform.h"
+#include "main.h"
+#include "MemoryHeap.h"
// --MIAMI: file done
static RwBool DefaultVideoMode = TRUE;
-bool TurnOnAnimViewer = false;
-
RsGlobalType RsGlobal;
#ifdef _WIN32
@@ -161,7 +161,7 @@ rsPreInitCommandLine(RwChar *arg)
#ifndef MASTER
if (!strcmp(arg, RWSTRING("-animviewer")))
{
- TurnOnAnimViewer = TRUE;
+ gbModelViewer = TRUE;
return TRUE;
}
diff --git a/src/skel/skeleton.h b/src/skel/skeleton.h
index 1c468179..380b6c05 100644
--- a/src/skel/skeleton.h
+++ b/src/skel/skeleton.h
@@ -79,11 +79,8 @@ enum RsEvent
rsPADANALOGUERIGHTRESET,
rsPREINITCOMMANDLINE,
rsACTIVATE,
- rsANIMVIEWER,
};
-extern bool TurnOnAnimViewer;
-
typedef enum RsEvent RsEvent;
typedef RsEventStatus (*RsInputEventHandler)(RsEvent event, void *param);
diff --git a/src/skel/win/win.cpp b/src/skel/win/win.cpp
index a10a1a92..1fd959f2 100644
--- a/src/skel/win/win.cpp
+++ b/src/skel/win/win.cpp
@@ -98,6 +98,7 @@ static psGlobalType PsGlobal;
#include "Sprite2d.h"
#include "AnimViewer.h"
#include "Font.h"
+#include "MemoryMgr.h"
VALIDATE_SIZE(psGlobalType, 0x28);
@@ -309,7 +310,11 @@ psMouseSetPos(RwV2d *pos)
RwMemoryFunctions*
psGetMemoryFunctions(void)
{
+#ifdef USE_CUSTOM_ALLOCATOR
+ return &memFuncs;
+#else
return nil;
+#endif
}
/*
@@ -1008,17 +1013,11 @@ MainWndProc(HWND window, UINT message, WPARAM wParam, LPARAM lParam)
RECT rect;
/* redraw window */
-#ifndef MASTER
- if (RwInitialised && (gGameState == GS_PLAYING_GAME || gGameState == GS_ANIMVIEWER))
- {
- RsEventHandler((gGameState == GS_PLAYING_GAME ? rsIDLE : rsANIMVIEWER), (void *)TRUE);
- }
-#else
+
if (RwInitialised && gGameState == GS_PLAYING_GAME)
{
RsEventHandler(rsIDLE, (void *)TRUE);
}
-#endif
/* Manually resize window */
rect.left = rect.top = 0;
@@ -2005,11 +2004,19 @@ WinMain(HINSTANCE instance,
RwChar **argv;
SystemParametersInfo(SPI_SETFOREGROUNDLOCKTIMEOUT, 0, nil, SPIF_SENDCHANGE);
- // TODO: make this an option somewhere
- AllocConsole();
- freopen("CONIN$", "r", stdin);
- freopen("CONOUT$", "w", stdout);
- freopen("CONOUT$", "w", stderr);
+#ifndef MASTER
+ if (strstr(cmdLine, "-console"))
+ {
+ AllocConsole();
+ freopen("CONIN$", "r", stdin);
+ freopen("CONOUT$", "w", stdout);
+ freopen("CONOUT$", "w", stderr);
+ }
+#endif
+
+#ifdef USE_CUSTOM_ALLOCATOR
+ InitMemoryMgr();
+#endif
/*
* Initialize the platform independent data.
@@ -2169,17 +2176,17 @@ WinMain(HINSTANCE instance,
}
#endif
- if (TurnOnAnimViewer)
- {
#ifndef MASTER
+ if (gbModelViewer) {
+ // This is TheModelViewer in LCS
+ LoadingScreen("Loading the ModelViewer", NULL, GetRandomSplashScreen());
CAnimViewer::Initialise();
+ CTimer::Update();
#ifndef PS2_MENU
FrontEndMenuManager.m_bGameNotLoaded = false;
#endif
- gGameState = GS_ANIMVIEWER;
- TurnOnAnimViewer = false;
-#endif
}
+#endif
while ( TRUE )
{
@@ -2224,6 +2231,12 @@ WinMain(HINSTANCE instance,
DispatchMessage(&message);
}
}
+#ifndef MASTER
+ else if (gbModelViewer) {
+ // This is TheModelViewerCore in LCS
+ TheModelViewer();
+ }
+#endif
else if( ForegroundApp )
{
switch ( gGameState )
@@ -2443,18 +2456,6 @@ WinMain(HINSTANCE instance,
}
break;
}
-#ifndef MASTER
- case GS_ANIMVIEWER:
- {
- float ms = (float)CTimer::GetCurrentTimeInCycles() / (float)CTimer::GetCyclesPerMillisecond();
- if (RwInitialised)
- {
- if (!FrontEndMenuManager.m_PrefsFrameLimiter || (1000.0f / (float)RsGlobal.maxFPS) < ms)
- RsEventHandler(rsANIMVIEWER, (void*)TRUE);
- }
- break;
- }
-#endif
}
}
else
@@ -2526,12 +2527,13 @@ WinMain(HINSTANCE instance,
}
else
{
- if ( gGameState == GS_PLAYING_GAME )
- CGame::ShutDown();
#ifndef MASTER
- else if ( gGameState == GS_ANIMVIEWER )
+ if ( gbModelViewer )
CAnimViewer::Shutdown();
+ else
#endif
+ if ( gGameState == GS_PLAYING_GAME )
+ CGame::ShutDown();
CTimer::Stop();
@@ -2553,12 +2555,13 @@ WinMain(HINSTANCE instance,
}
- if ( gGameState == GS_PLAYING_GAME )
- CGame::ShutDown();
#ifndef MASTER
- else if ( gGameState == GS_ANIMVIEWER )
+ if ( gbModelViewer )
CAnimViewer::Shutdown();
+ else
#endif
+ if ( gGameState == GS_PLAYING_GAME )
+ CGame::ShutDown();
DMAudio.Terminate();
diff --git a/src/text/Text.cpp b/src/text/Text.cpp
index 5adc576a..5f7a07cc 100644
--- a/src/text/Text.cpp
+++ b/src/text/Text.cpp
@@ -205,7 +205,7 @@ CText::GetNameOfLoadedMissionText(char *outName)
void
CText::ReadChunkHeader(ChunkHeader *buf, int32 file, size_t *offset)
{
-#if DUMB
+#if THIS_IS_STUPID
char *_buf = (char*)buf;
for (int i = 0; i < sizeof(ChunkHeader); i++) {
CFileMgr::Read(file, &_buf[i], 1);
@@ -318,7 +318,7 @@ CKeyArray::Load(size_t length, int file, size_t* offset)
entries = new CKeyEntry[numEntries];
rawbytes = (char*)entries;
-#if DUMB
+#if THIS_IS_STUPID
for (uint32 i = 0; i < length; i++) {
CFileMgr::Read(file, &rawbytes[i], 1);
(*offset)++;
@@ -412,7 +412,7 @@ CData::Load(size_t length, int file, size_t * offset)
chars = new wchar[numChars];
rawbytes = (char*)chars;
-#if DUMB
+#if THIS_IS_STUPID
for(uint32 i = 0; i < length; i++){
CFileMgr::Read(file, &rawbytes[i], 1);
(*offset)++;
@@ -434,7 +434,7 @@ CData::Unload(void)
void
CMissionTextOffsets::Load(size_t table_size, int file, size_t *offset, int)
{
-#if DUMB
+#if THIS_IS_STUPID
size_t num_of_entries = table_size / sizeof(CMissionTextOffsets::Entry);
for (size_t mi = 0; mi < num_of_entries; mi++) {
for (uint32 i = 0; i < sizeof(data[mi].szMissionName); i++) {
diff --git a/src/vehicles/Automobile.cpp b/src/vehicles/Automobile.cpp
index 8d95bcd9..8a771a40 100644
--- a/src/vehicles/Automobile.cpp
+++ b/src/vehicles/Automobile.cpp
@@ -48,6 +48,7 @@
#include "PlayerPed.h"
#include "Object.h"
#include "Automobile.h"
+#include "Bike.h"
//--MIAMI: file done
@@ -99,8 +100,8 @@ CAutomobile::CAutomobile(int32 id, uint8 CreatedBy)
break;
}
- pHandling = mod_HandlingManager.GetHandlingData((eHandlingId)mi->m_handlingId);
- pFlyingHandling = mod_HandlingManager.GetFlyingPointer((eHandlingId)mi->m_handlingId);
+ 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;
@@ -808,7 +809,7 @@ CAutomobile::ProcessControl(void)
// dampen springs
for(i = 0; i < 4; i++)
- if(m_aSuspensionSpringRatio[i] < 1.0f)
+ if(m_aSuspensionSpringRatio[i] < 0.99999f)
ApplySpringDampening(pHandling->fSuspensionDampingLevel,
springDirections[i], contactPoints[i], contactSpeeds[i]);
@@ -849,7 +850,7 @@ CAutomobile::ProcessControl(void)
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 brakeBiasRear = neutralHandling ? 1.0f : 2.0f-pHandling->fBrakeBias; // looks like a bug, but it was correct in III...
float tractionBiasFront = neutralHandling ? 1.0f : 2.0f*pHandling->fTractionBias;
float tractionBiasRear = neutralHandling ? 1.0f : 2.0f-tractionBiasFront;
@@ -937,7 +938,7 @@ CAutomobile::ProcessControl(void)
adhesion *= CSurfaceTable::GetWetMultiplier(m_aWheelColPoints[CARWHEEL_FRONT_LEFT].surfaceB);
WheelState[CARWHEEL_FRONT_LEFT] = m_aWheelState[CARWHEEL_FRONT_LEFT];
- if(Damage.GetWheelStatus(VEHWHEEL_FRONT_LEFT) == WHEEL_STATUS_BURST)
+ if(Damage.GetWheelStatus(CARWHEEL_FRONT_LEFT) == WHEEL_STATUS_BURST)
ProcessWheel(wheelFwd, wheelRight,
contactSpeeds[CARWHEEL_FRONT_LEFT], contactPoints[CARWHEEL_FRONT_LEFT],
m_nWheelsOnGround, fThrust,
@@ -980,7 +981,7 @@ CAutomobile::ProcessControl(void)
adhesion *= CSurfaceTable::GetWetMultiplier(m_aWheelColPoints[CARWHEEL_FRONT_RIGHT].surfaceB);
WheelState[CARWHEEL_FRONT_RIGHT] = m_aWheelState[CARWHEEL_FRONT_RIGHT];
- if(Damage.GetWheelStatus(VEHWHEEL_FRONT_RIGHT) == WHEEL_STATUS_BURST)
+ if(Damage.GetWheelStatus(CARWHEEL_FRONT_RIGHT) == WHEEL_STATUS_BURST)
ProcessWheel(wheelFwd, wheelRight,
contactSpeeds[CARWHEEL_FRONT_RIGHT], contactPoints[CARWHEEL_FRONT_RIGHT],
m_nWheelsOnGround, fThrust,
@@ -1041,7 +1042,7 @@ CAutomobile::ProcessControl(void)
if(m_aWheelTimer[CARWHEEL_REAR_LEFT] > 0.0f || m_aWheelTimer[CARWHEEL_REAR_RIGHT] > 0.0f){
CVector wheelFwd = GetForward();
- CVector wheelRight = GetRight();
+ CVector wheelRight = GetRight(); // overwritten for resp. wheel
float rearBrake = brake;
float rearTraction = traction;
@@ -1072,7 +1073,6 @@ 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);
@@ -1084,7 +1084,7 @@ CAutomobile::ProcessControl(void)
adhesion *= CSurfaceTable::GetWetMultiplier(m_aWheelColPoints[CARWHEEL_REAR_LEFT].surfaceB);
WheelState[CARWHEEL_REAR_LEFT] = m_aWheelState[CARWHEEL_REAR_LEFT];
- if(Damage.GetWheelStatus(VEHWHEEL_REAR_LEFT) == WHEEL_STATUS_BURST)
+ if(Damage.GetWheelStatus(CARWHEEL_REAR_LEFT) == WHEEL_STATUS_BURST)
ProcessWheel(wheelFwd, wheelRight,
contactSpeeds[CARWHEEL_REAR_LEFT], contactPoints[CARWHEEL_REAR_LEFT],
m_nWheelsOnGround, fThrust,
@@ -1109,7 +1109,7 @@ CAutomobile::ProcessControl(void)
#ifdef FIX_BUGS
// Shouldn't we reset these after the left wheel?
wheelFwd = GetForward();
- wheelRight = GetRight();
+ wheelRight = GetRight(); // actually useless
#endif
if(m_aWheelTimer[CARWHEEL_REAR_RIGHT] > 0.0f){
@@ -1118,7 +1118,6 @@ CAutomobile::ProcessControl(void)
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);
@@ -1130,7 +1129,7 @@ CAutomobile::ProcessControl(void)
adhesion *= CSurfaceTable::GetWetMultiplier(m_aWheelColPoints[CARWHEEL_REAR_RIGHT].surfaceB);
WheelState[CARWHEEL_REAR_RIGHT] = m_aWheelState[CARWHEEL_REAR_RIGHT];
- if(Damage.GetWheelStatus(VEHWHEEL_REAR_RIGHT) == WHEEL_STATUS_BURST)
+ if(Damage.GetWheelStatus(CARWHEEL_REAR_RIGHT) == WHEEL_STATUS_BURST)
ProcessWheel(wheelFwd, wheelRight,
contactSpeeds[CARWHEEL_REAR_RIGHT], contactPoints[CARWHEEL_REAR_RIGHT],
m_nWheelsOnGround, fThrust,
@@ -1166,7 +1165,9 @@ CAutomobile::ProcessControl(void)
if(!IsRealHeli()){
if(m_aWheelTimer[CARWHEEL_REAR_LEFT] <= 0.0f){
- if(mod_HandlingManager.HasFrontWheelDrive(pHandling->nIdentifier) || acceleration == 0.0f)
+ if(bIsHandbrakeOn)
+ m_aWheelSpeed[CARWHEEL_REAR_LEFT] = 0.0f;
+ else if(mod_HandlingManager.HasFrontWheelDrive(pHandling->nIdentifier) || acceleration == 0.0f)
m_aWheelSpeed[CARWHEEL_REAR_LEFT] *= 0.95f;
else{
if(acceleration > 0.0f){
@@ -1180,7 +1181,9 @@ CAutomobile::ProcessControl(void)
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)
+ if(bIsHandbrakeOn)
+ m_aWheelSpeed[CARWHEEL_REAR_RIGHT] = 0.0f;
+ else if(mod_HandlingManager.HasFrontWheelDrive(pHandling->nIdentifier) || acceleration == 0.0f)
m_aWheelSpeed[CARWHEEL_REAR_RIGHT] *= 0.95f;
else{
if(acceleration > 0.0f){
@@ -1225,7 +1228,7 @@ CAutomobile::ProcessControl(void)
adhesion *= CSurfaceTable::GetWetMultiplier(m_aWheelColPoints[CARWHEEL_FRONT_LEFT].surfaceB);
WheelState[CARWHEEL_FRONT_LEFT] = m_aWheelState[CARWHEEL_FRONT_LEFT];
- if(Damage.GetWheelStatus(VEHWHEEL_FRONT_LEFT) == WHEEL_STATUS_BURST)
+ if(Damage.GetWheelStatus(CARWHEEL_FRONT_LEFT) == WHEEL_STATUS_BURST)
ProcessWheel(wheelFwd, wheelRight,
contactSpeeds[CARWHEEL_FRONT_LEFT], contactPoints[CARWHEEL_FRONT_LEFT],
m_nWheelsOnGround, fThrust,
@@ -1268,7 +1271,7 @@ CAutomobile::ProcessControl(void)
adhesion *= CSurfaceTable::GetWetMultiplier(m_aWheelColPoints[CARWHEEL_FRONT_RIGHT].surfaceB);
WheelState[CARWHEEL_FRONT_RIGHT] = m_aWheelState[CARWHEEL_FRONT_RIGHT];
- if(Damage.GetWheelStatus(VEHWHEEL_FRONT_RIGHT) == WHEEL_STATUS_BURST)
+ if(Damage.GetWheelStatus(CARWHEEL_FRONT_RIGHT) == WHEEL_STATUS_BURST)
ProcessWheel(wheelFwd, wheelRight,
contactSpeeds[CARWHEEL_FRONT_RIGHT], contactPoints[CARWHEEL_FRONT_RIGHT],
m_nWheelsOnGround, fThrust,
@@ -1719,11 +1722,11 @@ CAutomobile::PreRender(void)
int i, j, n;
CVehicleModelInfo *mi = (CVehicleModelInfo*)CModelInfo::GetModelInfo(GetModelIndex());
- if(GetModelIndex() == MI_RHINO && m_aCarNodes[CAR_BONNET]){
+ if(GetModelIndex() == MI_RHINO && m_aCarNodes[CAR_WINDSCREEN]){
// Rotate Rhino turret
CMatrix m;
CVector p;
- m.Attach(RwFrameGetMatrix(m_aCarNodes[CAR_BONNET]));
+ m.Attach(RwFrameGetMatrix(m_aCarNodes[CAR_WINDSCREEN]));
p = m.GetPosition();
m.SetRotateZ(m_fCarGunLR);
m.Translate(p);
@@ -3187,7 +3190,11 @@ CAutomobile::ProcessControlInputs(uint8 pad)
// 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;
@@ -3205,7 +3212,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)
@@ -3834,7 +3841,7 @@ CAutomobile::DoDriveByShootings(void)
return;
CWeapon *weapon = pDriver->GetWeapon();
- if(CWeaponInfo::GetWeaponInfo(weapon->m_eWeaponType)->m_nWeaponSlot != 5)
+ if(CWeaponInfo::GetWeaponInfo(weapon->m_eWeaponType)->m_nWeaponSlot != WEAPONSLOT_SUBMACHINEGUN)
return;
weapon->Update(pDriver->m_audioEntityId, nil);
@@ -4861,10 +4868,10 @@ CAutomobile::BurstTyre(uint8 wheel, bool applyForces)
return;
switch(wheel){
- case CAR_PIECE_WHEEL_LF: wheel = VEHWHEEL_FRONT_LEFT; break;
- case CAR_PIECE_WHEEL_LR: wheel = VEHWHEEL_REAR_LEFT; break;
- case CAR_PIECE_WHEEL_RF: wheel = VEHWHEEL_FRONT_RIGHT; break;
- case CAR_PIECE_WHEEL_RR: wheel = VEHWHEEL_REAR_RIGHT; break;
+ case CAR_PIECE_WHEEL_LF: wheel = CARWHEEL_FRONT_LEFT; break;
+ case CAR_PIECE_WHEEL_RF: wheel = CARWHEEL_FRONT_RIGHT; break;
+ case CAR_PIECE_WHEEL_LR: wheel = CARWHEEL_REAR_LEFT; break;
+ case CAR_PIECE_WHEEL_RR: wheel = CARWHEEL_REAR_RIGHT; break;
}
int status = Damage.GetWheelStatus(wheel);
@@ -5073,7 +5080,7 @@ CAutomobile::BlowUpCarsInPath(void)
m_aCollisionRecords[i]->GetModelIndex() != MI_RHINO &&
!m_aCollisionRecords[i]->bRenderScorched){
if(this == FindPlayerVehicle())
- CEventList::RegisterEvent(EVENT_EXPLOSION, EVENT_ENTITY_VEHICLE, this, FindPlayerPed(), 2000);
+ CEventList::RegisterEvent(EVENT_EXPLOSION, EVENT_ENTITY_VEHICLE, m_aCollisionRecords[i], FindPlayerPed(), 2000);
((CVehicle*)m_aCollisionRecords[i])->BlowUpCar(this);
}
}
@@ -5109,6 +5116,141 @@ CAutomobile::HasCarStoppedBecauseOfLight(void)
return false;
}
+// --MIAMI: Done
+void
+CPed::DeadPedMakesTyresBloody(void)
+{
+ int minX = CWorld::GetSectorIndexX(GetPosition().x - 2.0f);
+ if (minX < 0) minX = 0;
+ int minY = CWorld::GetSectorIndexY(GetPosition().y - 2.0f);
+ if (minY < 0) minY = 0;
+ int maxX = CWorld::GetSectorIndexX(GetPosition().x + 2.0f);
+ if (maxX > NUMSECTORS_X-1) maxX = NUMSECTORS_X-1;
+ int maxY = CWorld::GetSectorIndexY(GetPosition().y + 2.0f);
+ if (maxY > NUMSECTORS_Y-1) maxY = NUMSECTORS_Y-1;
+
+ CWorld::AdvanceCurrentScanCode();
+
+ for (int curY = minY; curY <= maxY; curY++) {
+ for (int curX = minX; curX <= maxX; curX++) {
+ CSector *sector = CWorld::GetSector(curX, curY);
+ MakeTyresMuddySectorList(sector->m_lists[ENTITYLIST_VEHICLES]);
+ MakeTyresMuddySectorList(sector->m_lists[ENTITYLIST_VEHICLES_OVERLAP]);
+ }
+ }
+}
+
+// --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->m_scanCode != CWorld::GetCurrentScanCode()) {
+ veh->m_scanCode = CWorld::GetCurrentScanCode();
+
+ 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;
+ case 1:
+ approxWheelOffset = CVector(-vehCol->boundingBox.max.x, vehCol->boundingBox.min.y, 0.0f);
+ break;
+ case 2:
+ approxWheelOffset = CVector(vehCol->boundingBox.max.x, vehCol->boundingBox.max.y, 0.0f);
+ break;
+ case 3:
+ approxWheelOffset = CVector(vehCol->boundingBox.max.x, vehCol->boundingBox.min.y, 0.0f);
+ break;
+ default:
+ break;
+ }
+
+ // 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);
+ }
+ }
+ }
+ }
+ }
+ }
+ } 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;
+ }
+
+ // 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);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
void
CAutomobile::SetBusDoorTimer(uint32 timer, uint8 type)
{
@@ -5627,7 +5769,7 @@ CAutomobile::PopBoot(void)
case DOOR_STATUS_OK:
case DOOR_STATUS_SMASHED:
Doors[DOOR_BOOT].m_fAngle = Doors[DOOR_BOOT].m_fMinAngle;
- CMatrix mat(RwFrameGetMatrix(m_aCarNodes[DOOR_BOOT]));
+ 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;
diff --git a/src/vehicles/Automobile.h b/src/vehicles/Automobile.h
index b2f0643c..16d86917 100644
--- a/src/vehicles/Automobile.h
+++ b/src/vehicles/Automobile.h
@@ -7,8 +7,6 @@
class CObject;
-// These are used for all the wheel arrays
-// DON'T confuse with VEHWHEEL, which are vehicle components
enum {
CARWHEEL_FRONT_LEFT,
CARWHEEL_REAR_LEFT,
@@ -35,6 +33,9 @@ public:
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 bFixedColour : 1;
uint8 bBigWheels : 1;
@@ -44,6 +45,9 @@ public:
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;
diff --git a/src/vehicles/Bike.cpp b/src/vehicles/Bike.cpp
index 62633464..0cfbedc1 100644
--- a/src/vehicles/Bike.cpp
+++ b/src/vehicles/Bike.cpp
@@ -93,9 +93,9 @@ CBike::CBike(int32 id, uint8 CreatedBy)
SetModelIndex(id);
- pHandling = mod_HandlingManager.GetHandlingData((eHandlingId)mi->m_handlingId);
- pBikeHandling = mod_HandlingManager.GetBikePointer((eHandlingId)mi->m_handlingId);
- pFlyingHandling = mod_HandlingManager.GetFlyingPointer((eHandlingId)mi->m_handlingId);
+ 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;
@@ -202,9 +202,11 @@ CVector vecTestResistance(0.9995f, 0.9f, 0.95f);
float fDAxisX = 1.0f;
float fDAxisXExtra = 100.0f;
float fDAxisY = 1000.0f;
-float fInAirXRes = 0.88f;
+float fInAirXRes = 0.98f;
float fFlySpeedMult = -0.6f;
+#pragma optimize("", off) // a workaround for another compiler bug =P, original had optimize off for this function too though
+
void
CBike::ProcessControl(void)
{
@@ -476,7 +478,7 @@ CBike::ProcessControl(void)
if(m_vecMoveSpeedAvg.MagnitudeSqr() <= sq(moveSpeedLimit*CTimer::GetTimeStep()) &&
m_vecTurnSpeedAvg.MagnitudeSqr() <= sq(turnSpeedLimit*CTimer::GetTimeStep()) &&
- m_fDistanceTravelled < distanceLimit &&
+ m_fDistanceTravelled < distanceLimit ||
makeStatic){
m_nStaticFrames++;
@@ -1144,7 +1146,12 @@ CBike::ProcessControl(void)
float suspChange = m_aSuspensionSpringRatioPrev[i] - m_aSuspensionSpringRatio[i];
if(suspChange > 0.3f && (i == BIKESUSP_F1 || i == BIKESUSP_R1) && speedsq > 0.04f){
if(GetStatus() == STATUS_PLAYER || GetStatus() == STATUS_PHYSICS){
+#ifdef FIX_BUGS
+ // only two wheels but 4 suspensions
+ if(m_wheelStatus[i/2] == WHEEL_STATUS_BURST)
+#else
if(m_wheelStatus[i] == WHEEL_STATUS_BURST)
+#endif
DMAudio.PlayOneShot(m_audioEntityId, SOUND_CAR_JUMP_2, suspChange);
else
DMAudio.PlayOneShot(m_audioEntityId, SOUND_CAR_JUMP, suspChange);
@@ -1213,7 +1220,8 @@ CBike::ProcessControl(void)
// Balance bike
if(bBalancedByRider || bIsBeingPickedUp || bIsStanding){
- float onSideness = clamp(DotProduct(GetRight(), m_vecAvgSurfaceNormal), -1.0f, 1.0f);
+ float onSideness = DotProduct(GetRight(), m_vecAvgSurfaceNormal);
+ onSideness = clamp(onSideness, -1.0f, 1.0f);
CVector worldCOM = Multiply3x3(GetMatrix(), m_vecCentreOfMass);
// Keep bike upright
if(bBalancedByRider){
@@ -1256,6 +1264,8 @@ CBike::ProcessControl(void)
}
}
+#pragma optimize("", on)
+
void
CBike::Teleport(CVector pos)
{
@@ -1596,7 +1606,7 @@ CBike::PreRender(void)
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((RwV3d*)&forkAxis, -m_fWheelAngle);
+ quat.Set(&forkAxis, -m_fWheelAngle);
quat.Get(rot.m_attachment);
rot.Update();
diff --git a/src/vehicles/Boat.cpp b/src/vehicles/Boat.cpp
index 7fea8c6e..695d380f 100644
--- a/src/vehicles/Boat.cpp
+++ b/src/vehicles/Boat.cpp
@@ -26,6 +26,7 @@
#include "AnimBlendAssociation.h"
#include "RpAnimBlend.h"
#include "Record.h"
+#include "Shadows.h"
//--MIAMI: file done
@@ -63,9 +64,9 @@ CBoat::CBoat(int mi, uint8 owner) : CVehicle(owner)
m_nPoliceShoutTimer = CTimer::GetTimeInMilliseconds();
SetModelIndex(mi);
- pHandling = mod_HandlingManager.GetHandlingData((eHandlingId)minfo->m_handlingId);
- pFlyingHandling = mod_HandlingManager.GetFlyingPointer((eHandlingId)minfo->m_handlingId);
- pBoatHandling = mod_HandlingManager.GetBoatPointer((eHandlingId)minfo->m_handlingId);
+ 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;
@@ -442,7 +443,7 @@ CBoat::ProcessControl(void)
CVector wakePos = GetPosition() + sternPos;
// no actual particles for player...
}else if(IsVisible() && ((CTimer::GetFrameCounter() + m_randomSeed) & 1) &&
- CVisibilityPlugins::GetDistanceSquaredFromCamera((RwV3d*)&propellerWorld) < SQR(70.0f * TheCamera.GenerationDistMultiplier)){
+ CVisibilityPlugins::GetDistanceSquaredFromCamera(&propellerWorld) < SQR(70.0f * TheCamera.GenerationDistMultiplier)){
jetDir.z = 0.015f;
jetDir.x *= 3.5f;
jetDir.y *= 3.5f;
@@ -612,7 +613,7 @@ CBoat::ProcessControl(void)
splashDir.z += 0.0003f*m_nDeltaVolumeUnderWater;
CWaterLevel::GetWaterLevel(splashPos, &waterLevel, true);
if(splashPos.z-waterLevel < 3.0f &&
- CVisibilityPlugins::GetDistanceSquaredFromCamera((RwV3d*)&splashPos) < SQR(70.0f * TheCamera.GenerationDistMultiplier)){
+ 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),
@@ -669,7 +670,7 @@ CBoat::ProcessControl(void)
splashDir.z += 0.0003f*m_nDeltaVolumeUnderWater;
CWaterLevel::GetWaterLevel(splashPos, &waterLevel, true);
if(splashPos.z-waterLevel < 3.0f &&
- CVisibilityPlugins::GetDistanceSquaredFromCamera((RwV3d*)&splashPos) < SQR(70.0f * TheCamera.GenerationDistMultiplier)){
+ 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),
@@ -1006,7 +1007,7 @@ CBoat::PreRender(void)
if(atomic)
SetComponentAtomicAlpha(atomic, Max(150-alpha, 0));
}
- //CShadows::StoreShadowForVehicle(this);
+ 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]){
diff --git a/src/vehicles/Cranes.cpp b/src/vehicles/Cranes.cpp
index 2a571a67..8433a0ba 100644
--- a/src/vehicles/Cranes.cpp
+++ b/src/vehicles/Cranes.cpp
@@ -629,11 +629,11 @@ void CCranes::Save(uint8* buf, uint32* size)
for (int i = 0; i < NUM_CRANES; i++) {
CCrane *pCrane = WriteSaveBuf(buf, aCranes[i]);
if (pCrane->m_pCraneEntity != nil)
- pCrane->m_pCraneEntity = (CBuilding*)(CPools::GetBuildingPool()->GetJustIndex(pCrane->m_pCraneEntity) + 1);
+ pCrane->m_pCraneEntity = (CBuilding*)(CPools::GetBuildingPool()->GetJustIndex_NoFreeAssert(pCrane->m_pCraneEntity) + 1);
if (pCrane->m_pHook != nil)
- pCrane->m_pHook = (CObject*)(CPools::GetObjectPool()->GetJustIndex(pCrane->m_pHook) + 1);
+ pCrane->m_pHook = (CObject*)(CPools::GetObjectPool()->GetJustIndex_NoFreeAssert(pCrane->m_pHook) + 1);
if (pCrane->m_pVehiclePickedUp != nil)
- pCrane->m_pVehiclePickedUp = (CVehicle*)(CPools::GetVehiclePool()->GetJustIndex(pCrane->m_pVehiclePickedUp) + 1);
+ pCrane->m_pVehiclePickedUp = (CVehicle*)(CPools::GetVehiclePool()->GetJustIndex_NoFreeAssert(pCrane->m_pVehiclePickedUp) + 1);
}
VALIDATESAVEBUF(*size);
diff --git a/src/vehicles/Cranes.h b/src/vehicles/Cranes.h
index 45ea7a8d..162f9af9 100644
--- a/src/vehicles/Cranes.h
+++ b/src/vehicles/Cranes.h
@@ -11,7 +11,7 @@ class CBuilding;
class CCrane
{
public:
- enum CraneState : uint8 {
+ enum CraneState {
IDLE = 0,
GOING_TOWARDS_TARGET = 1,
LIFTING_TARGET = 2,
@@ -19,7 +19,7 @@ public:
ROTATING_TARGET = 4,
DROPPING_TARGET = 5
};
- enum CraneStatus : uint8 {
+ enum CraneStatus {
NONE = 0,
ACTIVATED = 1,
DEACTIVATED = 2
@@ -46,8 +46,8 @@ public:
CVector2D m_vecHookVelocity;
CVehicle *m_pVehiclePickedUp;
uint32 m_nTimeForNextCheck;
- CraneStatus m_nCraneStatus;
- CraneState m_nCraneState;
+ uint8 m_nCraneStatus;
+ uint8 m_nCraneState;
uint8 m_nVehiclesCollected;
bool m_bIsCrusher;
bool m_bIsMilitaryCrane;
diff --git a/src/vehicles/HandlingMgr.cpp b/src/vehicles/HandlingMgr.cpp
index 3d5d4e77..b8c8566c 100644
--- a/src/vehicles/HandlingMgr.cpp
+++ b/src/vehicles/HandlingMgr.cpp
@@ -2,6 +2,7 @@
#include "main.h"
#include "FileMgr.h"
+#include "Physical.h"
#include "HandlingMgr.h"
//--MIAMI: done
@@ -172,7 +173,7 @@ cHandlingDataMgr::LoadHandlingData(void)
end = start+1;
// yeah, this is kinda crappy
- if(strncmp(line, ";the end", 9) == 0)
+ if(strcmp(line, ";the end") == 0)
keepGoing = 0;
else if(line[0] != ';'){
if(line[0] == '!'){
@@ -187,7 +188,7 @@ cHandlingDataMgr::LoadHandlingData(void)
handlingId = FindExactWord(word, (const char*)VehicleNames, 14, NUMHANDLINGS);
assert(handlingId >= 0 && handlingId < NUMHANDLINGS);
bikeHandling = GetBikePointer(handlingId);
- bikeHandling->nIdentifier = (eHandlingId)handlingId;
+ bikeHandling->nIdentifier = (tVehicleType)handlingId;
break;
case 2: bikeHandling->fLeanFwdCOM = atof(word); break;
case 3: bikeHandling->fLeanFwdForce = atof(word); break;
@@ -220,7 +221,7 @@ cHandlingDataMgr::LoadHandlingData(void)
handlingId = FindExactWord(word, (const char*)VehicleNames, 14, NUMHANDLINGS);
assert(handlingId >= 0 && handlingId < NUMHANDLINGS);
flyingHandling = GetFlyingPointer(handlingId);
- flyingHandling->nIdentifier = (eHandlingId)handlingId;
+ flyingHandling->nIdentifier = (tVehicleType)handlingId;
break;
case 2: flyingHandling->fThrust = atof(word); break;
case 3: flyingHandling->fThrustFallOff = atof(word); break;
@@ -255,7 +256,7 @@ cHandlingDataMgr::LoadHandlingData(void)
handlingId = FindExactWord(word, (const char*)VehicleNames, 14, NUMHANDLINGS);
assert(handlingId >= 0 && handlingId < NUMHANDLINGS);
boatHandling = GetBoatPointer(handlingId);
- boatHandling->nIdentifier = (eHandlingId)handlingId;
+ boatHandling->nIdentifier = (tVehicleType)handlingId;
break;
case 2: boatHandling->fThrustY = atof(word); break;
case 3: boatHandling->fThrustZ = atof(word); break;
@@ -284,7 +285,7 @@ cHandlingDataMgr::LoadHandlingData(void)
handlingId = FindExactWord(word, (const char*)VehicleNames, 14, NUMHANDLINGS);
assert(handlingId >= 0 && handlingId < NUMHANDLINGS);
handling = &HandlingData[handlingId];
- handling->nIdentifier = (eHandlingId)handlingId;
+ handling->nIdentifier = (tVehicleType)handlingId;
break;
case 1: handling->fMass = atof(word); break;
case 2: handling->Dimension.x = atof(word); break;
@@ -348,18 +349,18 @@ cHandlingDataMgr::FindExactWord(const char *word, const char *words, int wordLen
void
cHandlingDataMgr::ConvertDataToGameUnits(tHandlingData *handling)
{
- // TODO: figure out what exactly is being converted here
+ // convert distance to m, time to 1/50s
float velocity, a, b, specificVolume;
- handling->Transmission.fEngineAcceleration /= 2500.0f;
- handling->Transmission.fMaxVelocity /= 180.0f;
- handling->fBrakeDeceleration /= 2500.0f;
+ handling->Transmission.fEngineAcceleration *= 1.0f/(50.0f*50.0f);
+ handling->Transmission.fMaxVelocity *= 1000.0f/(60.0f*60.0f * 50.0f);
+ handling->fBrakeDeceleration *= 1.0f/(50.0f*50.0f);
handling->fTurnMass = (sq(handling->Dimension.x) + sq(handling->Dimension.y)) * handling->fMass / 12.0f;
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;
+ handling->fBuoyancy = 100.0f/handling->nPercentSubmerged * GRAVITY*handling->fMass;
// What the hell is going on here?
specificVolume = handling->Dimension.x*handling->Dimension.z*0.5f / handling->fMass; // ?
diff --git a/src/vehicles/HandlingMgr.h b/src/vehicles/HandlingMgr.h
index e93f7879..446395f2 100644
--- a/src/vehicles/HandlingMgr.h
+++ b/src/vehicles/HandlingMgr.h
@@ -2,7 +2,7 @@
#include "Transmission.h"
-enum eHandlingId
+enum tVehicleType
{
HANDLING_LANDSTAL,
HANDLING_IDAHO,
@@ -120,6 +120,11 @@ enum eHandlingId
NUMBOATHANDLINGS = HANDLING_SEAPLANE+1 - HANDLING_PREDATOR,
};
+enum tField // most likely a handling field enum, never used so :shrug:
+{
+
+};
+
enum
{
HANDLING_1G_BOOST = 1,
@@ -154,7 +159,7 @@ enum
struct tHandlingData
{
- eHandlingId nIdentifier;
+ tVehicleType nIdentifier;
float fMass;
float fInvMass;
float fTurnMass;
@@ -170,7 +175,7 @@ struct tHandlingData
float fSteeringLock;
float fTractionLoss;
float fTractionBias;
- float fABS; // should be VC leftover
+ float fUnused;
float fSuspensionForceLevel;
float fSuspensionDampingLevel;
float fSuspensionUpperLimit;
@@ -187,7 +192,7 @@ struct tHandlingData
struct tBikeHandlingData
{
- eHandlingId nIdentifier;
+ tVehicleType nIdentifier;
float fLeanFwdCOM;
float fLeanFwdForce;
float fLeanBakCOM;
@@ -207,7 +212,7 @@ struct tBikeHandlingData
struct tBoatHandlingData
{
- eHandlingId nIdentifier;
+ tVehicleType nIdentifier;
float fThrustY;
float fThrustZ;
float fThrustAppZ;
@@ -222,7 +227,7 @@ struct tBoatHandlingData
struct tFlyingHandlingData
{
- eHandlingId nIdentifier;
+ tVehicleType nIdentifier;
float fThrust;
float fThrustFallOff;
float fYaw;
@@ -239,6 +244,8 @@ struct tFlyingHandlingData
CVector vecSpeedRes;
};
+class CVehicle;
+
class cHandlingDataMgr
{
float field_0; // unused it seems
@@ -258,14 +265,15 @@ public:
void Initialise(void);
void LoadHandlingData(void);
int FindExactWord(const char *word, const char *words, int wordLen, int numWords);
+ void ConvertDataToWorldUnits(tHandlingData *handling);
void ConvertDataToGameUnits(tHandlingData *handling);
void ConvertBikeDataToGameUnits(tBikeHandlingData *handling);
int32 GetHandlingId(const char *name);
- tHandlingData *GetHandlingData(eHandlingId id) { return &HandlingData[id]; }
+ 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(eHandlingId id) { return HandlingData[id].Transmission.nDriveType == 'R'; }
- bool HasFrontWheelDrive(eHandlingId id) { return HandlingData[id].Transmission.nDriveType == 'F'; }
+ bool HasRearWheelDrive(tVehicleType id) { return HandlingData[id].Transmission.nDriveType == 'R'; }
+ bool HasFrontWheelDrive(tVehicleType id) { return HandlingData[id].Transmission.nDriveType == 'F'; }
};
extern cHandlingDataMgr mod_HandlingManager;
diff --git a/src/vehicles/Heli.cpp b/src/vehicles/Heli.cpp
index d6a237e5..644fdde8 100644
--- a/src/vehicles/Heli.cpp
+++ b/src/vehicles/Heli.cpp
@@ -57,7 +57,7 @@ CHeli::CHeli(int32 id, uint8 CreatedBy)
CVehicleModelInfo *mi = (CVehicleModelInfo*)CModelInfo::GetModelInfo(id);
m_vehType = VEHICLE_TYPE_HELI;
- pHandling = mod_HandlingManager.GetHandlingData((eHandlingId)mi->m_handlingId);
+ pHandling = mod_HandlingManager.GetHandlingData((tVehicleType)mi->m_handlingId);
SetModelIndex(id);
m_heliStatus = HELI_STATUS_HOVER;
m_pathState = 0;
diff --git a/src/vehicles/Plane.cpp b/src/vehicles/Plane.cpp
index ffe9ffbf..5b5536fd 100644
--- a/src/vehicles/Plane.cpp
+++ b/src/vehicles/Plane.cpp
@@ -18,6 +18,7 @@
#include "HandlingMgr.h"
#include "Heli.h"
#include "Plane.h"
+#include "MemoryHeap.h"
//--MIAMI: file done
@@ -70,7 +71,7 @@ CPlane::CPlane(int32 id, uint8 CreatedBy)
{
CVehicleModelInfo *mi = (CVehicleModelInfo*)CModelInfo::GetModelInfo(id);
m_vehType = VEHICLE_TYPE_PLANE;
- pHandling = mod_HandlingManager.GetHandlingData((eHandlingId)mi->m_handlingId);
+ pHandling = mod_HandlingManager.GetHandlingData((tVehicleType)mi->m_handlingId);
SetModelIndex(id);
m_fMass = 100000000.0f;
@@ -564,9 +565,11 @@ CPlane::ProcessControl(void)
if(m_rwObject && RwObjectGetType(m_rwObject) == rpCLUMP){
DeleteRwObject();
if(mi->m_planeLodId != -1){
+ PUSH_MEMID(MEMID_WORLD);
m_rwObject = CModelInfo::GetModelInfo(mi->m_planeLodId)->CreateInstance();
+ POP_MEMID();
if(m_rwObject)
- m_matrix.Attach(RwFrameGetMatrix(RpAtomicGetFrame((RpAtomic*)m_rwObject)));
+ m_matrix.AttachRW(RwFrameGetMatrix(RpAtomicGetFrame((RpAtomic*)m_rwObject)));
}
}
}else if(CStreaming::HasModelLoaded(GetModelIndex())){
diff --git a/src/vehicles/Train.cpp b/src/vehicles/Train.cpp
index fb8361c5..1a4af307 100644
--- a/src/vehicles/Train.cpp
+++ b/src/vehicles/Train.cpp
@@ -44,7 +44,7 @@ CTrain::CTrain(int32 id, uint8 CreatedBy)
#ifdef GTA_TRAIN
CVehicleModelInfo *mi = (CVehicleModelInfo*)CModelInfo::GetModelInfo(id);
m_vehType = VEHICLE_TYPE_TRAIN;
- pHandling = mod_HandlingManager.GetHandlingData((eHandlingId)mi->m_handlingId);
+ pHandling = mod_HandlingManager.GetHandlingData((tVehicleType)mi->m_handlingId);
SetModelIndex(id);
Doors[0].Init(0.8f, 0.0f, 1, 0);
diff --git a/src/vehicles/Vehicle.cpp b/src/vehicles/Vehicle.cpp
index f083e0f6..56de3562 100644
--- a/src/vehicles/Vehicle.cpp
+++ b/src/vehicles/Vehicle.cpp
@@ -2492,7 +2492,7 @@ IsVehiclePointerValid(CVehicle* pVehicle)
{
if (!pVehicle)
return false;
- int index = CPools::GetVehiclePool()->GetJustIndex(pVehicle);
+ int index = CPools::GetVehiclePool()->GetJustIndex_NoFreeAssert(pVehicle);
#ifdef FIX_BUGS
if (index < 0 || index >= NUMVEHICLES)
#else
diff --git a/src/vehicles/Vehicle.h b/src/vehicles/Vehicle.h
index 004f1fd9..a42106cc 100644
--- a/src/vehicles/Vehicle.h
+++ b/src/vehicles/Vehicle.h
@@ -102,14 +102,6 @@ enum eLights
VEHLIGHT_REAR_RIGHT,
};
-enum eWheels
-{
- VEHWHEEL_FRONT_LEFT,
- VEHWHEEL_FRONT_RIGHT,
- VEHWHEEL_REAR_LEFT,
- VEHWHEEL_REAR_RIGHT,
-};
-
enum
{
CAR_PIECE_BONNET = 1,
@@ -248,8 +240,9 @@ public:
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;
@@ -259,7 +252,9 @@ public:
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;
@@ -281,7 +276,7 @@ public:
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);
diff --git a/src/weapons/Explosion.cpp b/src/weapons/Explosion.cpp
index 515dff94..74137dc0 100644
--- a/src/weapons/Explosion.cpp
+++ b/src/weapons/Explosion.cpp
@@ -121,7 +121,12 @@ CExplosion::AddExplosion(CEntity *explodingEntity, CEntity *culprit, eExplosionT
#endif
int n = 0;
+#ifdef FIX_BUGS
+ while (n < ARRAY_SIZE(gaExplosion) && gaExplosion[n].m_nIteration != 0)
+#else
+ // array overrun is UB
while (gaExplosion[n].m_nIteration != 0 && n < ARRAY_SIZE(gaExplosion))
+#endif
n++;
if (n == ARRAY_SIZE(gaExplosion))
return false;
@@ -220,7 +225,7 @@ CExplosion::AddExplosion(CEntity *explodingEntity, CEntity *culprit, eExplosionT
} else if (veh->IsComponentPresent(CAR_BOOT)) {
veh->GetComponentWorldPosition(CAR_BOOT, componentPos);
}
- if (componentPos != nil) {
+ if (componentPos.x != 0.0f) {
int rn = (CGeneral::GetRandomNumber() & 1) + 1;
for (int i = 0; i < rn; i++)
CParticle::AddJetExplosion(componentPos, (CGeneral::GetRandomNumber() & 7) / 7.0f + 1.5f, 0.5f);
diff --git a/src/weapons/ProjectileInfo.cpp b/src/weapons/ProjectileInfo.cpp
index 754da5f7..0930756c 100644
--- a/src/weapons/ProjectileInfo.cpp
+++ b/src/weapons/ProjectileInfo.cpp
@@ -159,8 +159,12 @@ CProjectileInfo::AddProjectile(CEntity *entity, eWeaponType weapon, CVector pos,
}
int i = 0;
+#ifdef FIX_BUGS
+ while (i < ARRAY_SIZE(gaProjectileInfo) && gaProjectileInfo[i].m_bInUse) i++;
+#else
+ // array overrun is UB
while (gaProjectileInfo[i].m_bInUse && i < ARRAY_SIZE(gaProjectileInfo)) i++;
-
+#endif
if (i == ARRAY_SIZE(gaProjectileInfo))
return false;
diff --git a/src/weapons/ShotInfo.cpp b/src/weapons/ShotInfo.cpp
index ae7b9d2d..a03ed16f 100644
--- a/src/weapons/ShotInfo.cpp
+++ b/src/weapons/ShotInfo.cpp
@@ -78,7 +78,7 @@ CShotInfo::AddShot(CEntity *sourceEntity, eWeaponType weapon, CVector startPos,
gaShotInfo[slot].m_areaAffected.z += CShotInfo::ms_afRandTable[CGeneral::GetRandomNumber() % ARRAY_SIZE(ms_afRandTable)];
}
gaShotInfo[slot].m_areaAffected.Normalise();
- if (weaponInfo->m_bRandSpeed)
+ if (weaponInfo->IsFlagSet(WEAPONFLAG_RAND_SPEED))
gaShotInfo[slot].m_areaAffected *= CShotInfo::ms_afRandTable[CGeneral::GetRandomNumber() % ARRAY_SIZE(ms_afRandTable)] + weaponInfo->m_fSpeed;
else
gaShotInfo[slot].m_areaAffected *= weaponInfo->m_fSpeed;
@@ -119,10 +119,10 @@ CShotInfo::Update()
shot.m_inUse = false;
}
- if (weaponInfo->m_bSlowsDown)
+ if (weaponInfo->IsFlagSet(WEAPONFLAG_SLOWS_DOWN))
shot.m_areaAffected *= pow(0.96, CTimer::GetTimeStep()); // FRAMERATE
- if (weaponInfo->m_bExpands)
+ if (weaponInfo->IsFlagSet(WEAPONFLAG_EXPANDS))
shot.m_radius += 0.075f * CTimer::GetTimeStep();
shot.m_startPos += CTimer::GetTimeStep() * shot.m_areaAffected;
diff --git a/src/weapons/Weapon.cpp b/src/weapons/Weapon.cpp
index 1d32487b..e2213399 100644
--- a/src/weapons/Weapon.cpp
+++ b/src/weapons/Weapon.cpp
@@ -36,9 +36,6 @@
#include "Sprite.h"
#include "Pickups.h"
-// TODO(Miami)
-#define AUDIO_NOT_READY
-
float fReloadAnimSampleFraction[5] = { 0.5f, 0.7f, 0.75f, 0.75f, 0.7f };
float fSeaSparrowAimingAngle = 10.0f;
float fHunterAimingAngle = 30.0f;
@@ -502,14 +499,14 @@ CWeapon::FireMelee(CEntity *shooter, CVector &fireSource)
bool collided = false;
if (victimPed->m_nPedState == PED_DRIVING && (m_eWeaponType == WEAPONTYPE_UNARMED || m_eWeaponType == WEAPONTYPE_BRASSKNUCKLE
- || info->m_bFightMode))
+ || info->IsFlagSet(WEAPONFLAG_FIGHTMODE)))
continue;
float victimPedRadius = victimPed->GetBoundRadius() + info->m_fRadius;
if ( victimPed->bUsesCollision || victimPed->Dead() || victimPed->Driving() )
{
CVector victimPedPos = victimPed->GetPosition();
- if ( SQR(victimPedRadius) > (victimPedPos-(*fireSource)).MagnitudeSqr() )
+ if ( SQR(victimPedRadius) > (victimPedPos-fireSource).MagnitudeSqr() )
{
CVector collisionDist;
CColModel* victimPedCol = &CTempColModels::ms_colModelPed1;
@@ -531,9 +528,9 @@ CWeapon::FireMelee(CEntity *shooter, CVector &fireSource)
CColSphere *sphere = &victimPedCol->spheres[s];
if (useLocalPos)
- collisionDist = sphere->center - (*fireSource);
+ collisionDist = sphere->center - fireSource;
else
- collisionDist = victimPedPos + sphere->center - (*fireSource);
+ collisionDist = victimPedPos + sphere->center - fireSource;
if ( SQR(sphere->radius + info->m_fRadius) > collisionDist.MagnitudeSqr() )
{
@@ -876,7 +873,7 @@ CWeapon::FireInstantHit(CEntity *shooter, CVector *fireSource)
CPed *threatAttack = (CPed*)shooterPed->m_pPointGunAt;
if ( threatAttack->IsPed() )
{
- threatAttack->m_pedIK.GetComponentPosition(*(RwV3d *)&target, PED_MID);
+ threatAttack->m_pedIK.GetComponentPosition(target, PED_MID);
threatAttack->ReactToPointGun(shooter);
}
else
@@ -1011,7 +1008,7 @@ CWeapon::FireInstantHit(CEntity *shooter, CVector *fireSource)
target.y += rotOffset.y * info->m_fRange;
CParticle::HandleShootableBirdsStuff(shooter, *fireSource);
- if (shooter->IsPed() && ((CPed*)shooter)->bDoomAim && (shooter != FindPlayerPed() || !info->m_bCanAim))
+ if (shooter->IsPed() && ((CPed*)shooter)->bDoomAim && (shooter != FindPlayerPed() || !info->IsFlagSet(WEAPONFLAG_CANAIM)))
{
CWeapon::DoDoomAiming(shooter, fireSource, &target);
}
@@ -1460,7 +1457,8 @@ CWeapon::DoBulletImpact(CEntity *shooter, CEntity *victim,
#ifndef FIX_BUGS
CVector dist = point->point - (*source);
- CVector smokePos = point->point - Max(0.1f * dist.Magnitude(), 0.2f) / dist.Magnitude();
+ float distMagnitude = dist.Magnitude();
+ CVector smokePos = point->point - Max(distMagnitude / 10.0f, 0.2f) * dist / distMagnitude;
#else
CVector smokePos = point->point;
#endif // !FIX_BUGS
@@ -1475,7 +1473,7 @@ CWeapon::DoBulletImpact(CEntity *shooter, CEntity *victim,
}
case ENTITY_TYPE_VEHICLE:
{
- if (point->pieceB >= SURFACE_LAMP_POST && point->pieceB <= SURFACE_METAL_CHAIN_FENCE) {
+ if (point->pieceB >= CAR_PIECE_WHEEL_LF && point->pieceB <= CAR_PIECE_WHEEL_RR) {
((CVehicle*)victim)->BurstTyre(point->pieceB, true);
for (int32 i = 0; i < 4; i++)
@@ -1489,9 +1487,9 @@ CWeapon::DoBulletImpact(CEntity *shooter, CEntity *victim,
CParticle::AddParticle(PARTICLE_SPARK, point->point, point->normal * 0.05f);
#ifndef FIX_BUGS
- CVector dist = point.point - (*fireSource);
+ CVector dist = point->point - (*source);
CVector offset = dist - Max(0.2f * dist.Magnitude(), 0.5f) * CVector(ahead.x, ahead.y, 0.0f);
- CVector smokePos = *fireSource + offset;
+ CVector smokePos = *source + offset;
#else
CVector smokePos = point->point;
#endif
@@ -1705,7 +1703,7 @@ CWeapon::FireShotgun(CEntity *shooter, CVector *fireSource)
{
CVector pos;
if (shooterPed->m_pPointGunAt->IsPed()) {
- ((CPed*)shooterPed->m_pPointGunAt)->m_pedIK.GetComponentPosition(*(RwV3d *)&pos, PED_MID);
+ ((CPed*)shooterPed->m_pPointGunAt)->m_pedIK.GetComponentPosition(pos, PED_MID);
} else {
pos = ((CPed*)shooterPed->m_pPointGunAt)->GetPosition();
}
@@ -1869,7 +1867,7 @@ CWeapon::FireShotgun(CEntity *shooter, CVector *fireSource)
{
case ENTITY_TYPE_VEHICLE:
{
- if (point.pieceB >= SURFACE_LAMP_POST && point.pieceB <= SURFACE_METAL_CHAIN_FENCE) {
+ if (point.pieceB >= CAR_PIECE_WHEEL_LF && point.pieceB <= CAR_PIECE_WHEEL_RR) {
((CVehicle*)victim)->BurstTyre(point.pieceB, true);
for (int32 i = 0; i < 4; i++)
@@ -2169,7 +2167,7 @@ CWeapon::LaserScopeDot(CVector *pOutPos, float *pOutSize)
CVector pos = foundCol.point;
float w, h;
- if ( CSprite::CalcScreenCoors(foundCol.point, pos, &w, &h, true) )
+ if ( CSprite::CalcScreenCoors(foundCol.point, &pos, &w, &h, true) )
{
*pOutPos = pos;
*pOutSize = w * 0.05f;
@@ -2264,7 +2262,7 @@ CWeapon::TakePhotograph(CEntity *shooter)
CVector pos;
float w, h;
- if ( CSprite::CalcScreenCoors(pedPos, pos, &w, &h, false) )
+ 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 )
@@ -2899,26 +2897,15 @@ CWeapon::Update(int32 audioEntity, CPed *pedToAdjustSound)
default:
break;
}
- if (reloadAssoc->GetProgress() >= soundStart && (reloadAssoc->currentTime - reloadAssoc->timeStep) / reloadAssoc->hierarchy->totalLength < soundStart) {
-#ifdef AUDIO_NOT_READY
- DMAudio.PlayOneShot(audioEntity, SOUND_WEAPON_RELOAD, 0.0f);
-#else
+ if (reloadAssoc->GetProgress() >= soundStart && (reloadAssoc->currentTime - reloadAssoc->timeStep) / reloadAssoc->hierarchy->totalLength < soundStart)
DMAudio.PlayOneShot(audioEntity, SOUND_WEAPON_RELOAD, m_eWeaponType);
-#endif
- }
if (CTimer::GetTimeInMilliseconds() > m_nTimer && reloadAssoc->GetProgress() < 0.9f) {
m_nTimer = CTimer::GetTimeInMilliseconds();
}
} else {
uint32 timePassed = m_nTimer - CWeaponInfo::ms_aReloadSampleTime[m_eWeaponType];
if (CTimer::GetPreviousTimeInMilliseconds() < timePassed && CTimer::GetTimeInMilliseconds() >= timePassed)
- {
-#ifdef AUDIO_NOT_READY
- DMAudio.PlayOneShot(audioEntity, SOUND_WEAPON_RELOAD, 0.0f);
-#else
DMAudio.PlayOneShot(audioEntity, SOUND_WEAPON_RELOAD, m_eWeaponType);
-#endif
- }
}
}
@@ -3171,6 +3158,21 @@ CWeapon::HasWeaponAmmoToBeUsed(void)
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;
+ }
+ return false;
+}
+
bool
CWeapon::ProcessLineOfSight(CVector const &point1, CVector const &point2, CColPoint &point, CEntity *&entity, eWeaponType type, CEntity *shooter, bool checkBuildings, bool checkVehicles, bool checkPeds, bool checkObjects, bool checkDummies, bool ignoreSeeThrough, bool ignoreSomeObjects)
{
diff --git a/src/weapons/WeaponEffects.cpp b/src/weapons/WeaponEffects.cpp
index 42d4f52c..b0df610f 100644
--- a/src/weapons/WeaponEffects.cpp
+++ b/src/weapons/WeaponEffects.cpp
@@ -8,7 +8,6 @@
#include "WeaponType.h"
RwTexture *gpCrossHairTex;
-RwRaster *gpCrossHairRaster;
CWeaponEffects gCrossHair;
@@ -40,7 +39,6 @@ CWeaponEffects::Init(void)
CTxdStore::SetCurrentTxd(slot);
gpCrossHairTex = RwTextureRead("target256", "target256m");
- gpCrossHairRaster = RwTextureGetRaster(gpCrossHairTex);
CTxdStore::PopCurrentTxd();
}
@@ -99,7 +97,7 @@ CWeaponEffects::Render(void)
#else
RwRenderStateSet(rwRENDERSTATEDESTBLEND, (void *)rwBLENDINVDESTALPHA);
#endif
- RwRenderStateSet(rwRENDERSTATETEXTURERASTER, (void *)gpCrossHairRaster);
+ RwRenderStateSet(rwRENDERSTATETEXTURERASTER, (void *)RwTextureGetRaster(gpCrossHairTex));
RwV3d pos;
float w, h;
diff --git a/src/weapons/WeaponInfo.cpp b/src/weapons/WeaponInfo.cpp
index b911805d..acb11a88 100644
--- a/src/weapons/WeaponInfo.cpp
+++ b/src/weapons/WeaponInfo.cpp
@@ -105,7 +105,6 @@ CWeaponInfo::GetWeaponInfo(eWeaponType weaponType)
return &ms_apWeaponInfos[weaponType];
}
-// --MIAMI: done except WEAPONTYPE_TOTALWEAPONS value
void
CWeaponInfo::Initialise(void)
{
@@ -130,19 +129,14 @@ CWeaponInfo::Initialise(void)
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;
+ ms_apWeaponInfos[i].m_Flags = WEAPONFLAG_USE_GRAVITY | WEAPONFLAG_SLOWS_DOWN | WEAPONFLAG_RAND_SPEED | WEAPONFLAG_EXPANDS | WEAPONFLAG_EXPLODES;
+ ms_apWeaponInfos[i].m_nWeaponSlot = WEAPONSLOT_UNARMED;
}
debug("Loading weapon data...\n");
LoadWeaponData();
debug("CWeaponInfo ready\n");
}
-// --MIAMI: Done, commented parts wait for weapons port
void
CWeaponInfo::LoadWeaponData(void)
{
@@ -170,10 +164,9 @@ CWeaponInfo::LoadWeaponData(void)
line[linelen] = '\0';
// skip white space
- for (lp = 0; line[lp] <= ' '; lp++);
+ for (lp = 0; line[lp] <= ' ' && line[lp] != '\0'; lp++);
- if (lp >= linelen || // FIX: game uses == here, but this is safer if we have empty lines
- line[lp] == '#')
+ if (line[lp] == '\0' || line[lp] == '#')
continue;
spread = 0.0f;
@@ -248,30 +241,7 @@ CWeaponInfo::LoadWeaponData(void)
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;
- ms_apWeaponInfos[weaponType].m_bRandSpeed = (flags >> 3) & 1;
- ms_apWeaponInfos[weaponType].m_bExpands = (flags >> 4) & 1;
- ms_apWeaponInfos[weaponType].m_bExplodes = (flags >> 5) & 1;
- ms_apWeaponInfos[weaponType].m_bCanAim = (flags >> 6) & 1;
- ms_apWeaponInfos[weaponType].m_bCanAimWithArm = (flags >> 7) & 1;
- 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_Flags = flags;
ms_apWeaponInfos[weaponType].m_nWeaponSlot = weaponSlot;
if (animLoopEnd < 98.0f && weaponType != WEAPONTYPE_FLAMETHROWER && !CWeapon::IsShotgun(weaponType))
diff --git a/src/weapons/WeaponInfo.h b/src/weapons/WeaponInfo.h
index 7ce3d861..0f53dded 100644
--- a/src/weapons/WeaponInfo.h
+++ b/src/weapons/WeaponInfo.h
@@ -4,7 +4,31 @@
#include "AnimationId.h"
#include "WeaponType.h"
-enum AssocGroupId;
+enum
+{
+ WEAPONFLAG_USE_GRAVITY = 1,
+ WEAPONFLAG_SLOWS_DOWN = 1 << 1,
+ WEAPONFLAG_DISSIPATES = 1 << 2,
+ WEAPONFLAG_RAND_SPEED = 1 << 3,
+ WEAPONFLAG_EXPANDS = 1 << 4,
+ WEAPONFLAG_EXPLODES = 1 << 5,
+ WEAPONFLAG_CANAIM = 1 << 6,
+ WEAPONFLAG_CANAIM_WITHARM = 1 << 7,
+ WEAPONFLAG_1ST_PERSON = 1 << 8,
+ WEAPONFLAG_HEAVY = 1 << 9,
+ WEAPONFLAG_THROW = 1 << 10,
+ WEAPONFLAG_RELOAD_LOOP2START = 1 << 11,
+ WEAPONFLAG_USE_2ND = 1 << 12,
+ WEAPONFLAG_GROUND_2ND = 1 << 13,
+ WEAPONFLAG_FINISH_3RD = 1 << 14,
+ WEAPONFLAG_RELOAD = 1 << 15,
+ WEAPONFLAG_FIGHTMODE = 1 << 16,
+ WEAPONFLAG_CROUCHFIRE = 1 << 17,
+ WEAPONFLAG_COP3_RD = 1 << 18,
+ WEAPONFLAG_GROUND_3RD = 1 << 19,
+ WEAPONFLAG_PARTIALATTACK = 1 << 20,
+ WEAPONFLAG_ANIMDETONATE = 1 << 21,
+};
class CWeaponInfo {
static CWeaponInfo ms_apWeaponInfos[WEAPONTYPE_TOTALWEAPONS];
@@ -34,31 +58,7 @@ public:
float m_fAnimBreakout;
int32 m_nModelId;
int32 m_nModel2Id;
- // flags
- uint8 m_bUseGravity : 1;
- uint8 m_bSlowsDown : 1;
- uint8 m_bDissipates : 1;
- uint8 m_bRandSpeed : 1;
- uint8 m_bExpands : 1;
- 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_Flags;
uint32 m_nWeaponSlot;
@@ -68,6 +68,8 @@ 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; }
+ bool IsFlagSet(uint32 flag) const { return (m_Flags & flag) != 0; }
};
VALIDATE_SIZE(CWeaponInfo, 0x64);