8480 lines
299 KiB
C++
8480 lines
299 KiB
C++
//
|
|
// filename: VehicleFactory.cpp
|
|
// description:
|
|
//
|
|
|
|
// --- Include Files ------------------------------------------------------------
|
|
|
|
// C headers
|
|
|
|
// Rage headers
|
|
#if __BANK
|
|
#include "bank/bkmgr.h"
|
|
#include "bank/bank.h"
|
|
#include "bank/combo.h"
|
|
#include "bank/slider.h"
|
|
#include "physics/WorldProbe/worldprobe.h"
|
|
#include "fwsys/gameskeleton.h"
|
|
#include "fwdecorator/decoratorExtension.h"
|
|
#include "fwdecorator/decoratorInterface.h"
|
|
#endif
|
|
#include "ai/task/task.h"
|
|
#include "file/default_paths.h"
|
|
#include "fragment/tune.h"
|
|
#include "fwdebug/picker.h"
|
|
#include "fwdrawlist/drawlistmgr.h"
|
|
#include "fwscript/scriptguid.h"
|
|
#include "string/stringutil.h"
|
|
#include "system/nelem.h"
|
|
#include "system/new.h"
|
|
|
|
#include "file/stream.h"
|
|
#include "file/token.h"
|
|
|
|
// Game headers
|
|
#include "animation/MoveVehicle.h"
|
|
#include "audio/heliaudioentity.h"
|
|
#include "audio/trainaudioentity.h"
|
|
#include "audio/caraudioentity.h"
|
|
#include "audio/planeaudioentity.h"
|
|
#include "audio/boataudioentity.h"
|
|
#include "audio/bicycleaudioentity.h"
|
|
#include "audio/traileraudioentity.h"
|
|
#include "camera/CamInterface.h"
|
|
#include "camera/debug/DebugDirector.h"
|
|
#include "camera/CamInterface.h"
|
|
#include "camera/debug/DebugDirector.h"
|
|
#include "camera/gameplay/GameplayDirector.h"
|
|
#include "camera/system/CameraManager.h"
|
|
#include "camera/helpers/Frame.h"
|
|
#include "camera/viewports/ViewportManager.h"
|
|
#include "Control/replay/Replay.h"
|
|
#include "debug/DebugScene.h"
|
|
#include "debug/debugGlobals.h"
|
|
#include "frontend/MiniMap.h"
|
|
#include "game/weather.h"
|
|
#include "ModelInfo/ModelInfo.h"
|
|
#include "ModelInfo/ModelInfo_Factories.h"
|
|
#include "modelInfo/vehicleModelInfo.h"
|
|
#include "modelinfo/VehicleModelInfoColors.h"
|
|
#include "network/Objects/NetworkObjectPopulationMgr.h"
|
|
#include "pathserver/ExportCollision.h"
|
|
#include "peds/ped.h"
|
|
#include "peds/PedFactory.h"
|
|
#include "peds/PedIntelligence.h"
|
|
#include "peds/PopCycle.h"
|
|
#include "peds/popzones.h"
|
|
#include "physics/gtaInst.h"
|
|
#include "physics/physics.h"
|
|
#include "scene/DataFileMgr.h"
|
|
#include "scene/world/gameWorld.h"
|
|
#include "scene/RegdRefTypes.h"
|
|
#include "script/Handlers/GameScriptEntity.h"
|
|
#include "script/script.h"
|
|
#include "script/script_cars_and_peds.h"
|
|
#include "streaming/populationstreaming.h"
|
|
#include "streaming/streaming.h" // For CStreaming::HasObjectLoaded(), etc.
|
|
#include "system/memmanager.h"
|
|
#include "Task/Physics/TaskNMBalance.h"
|
|
#include "Task/Vehicle/TaskCarAccessories.h"
|
|
#include "Task/Vehicle/TaskCar.h"
|
|
#include "Task/Vehicle/TaskEnterVehicle.h"
|
|
#include "Task/Vehicle/TaskInVehicle.h"
|
|
#include "timecycle/TimeCycle.h"
|
|
#include "vehicleAI/task/TaskVehicleAnimation.h"
|
|
#include "vehicleAi/task/TaskVehiclePlayer.h"
|
|
#include "vehicleAI/VehicleIntelligence.h"
|
|
#include "vehicles/AmphibiousAutomobile.h"
|
|
#include "vehicles/bike.h"
|
|
#include "vehicles/DraftVehicle.h"
|
|
#include "vehicles/bmx.h"
|
|
#include "vehicles/boat.h"
|
|
#include "vehicles/heli.h"
|
|
#include "vehicles/planes.h"
|
|
#include "vehicles/vehiclepopulation.h"
|
|
#include "vehicles/Submarine.h"
|
|
#include "vehicles/trailer.h"
|
|
#include "vehicles/train.h"
|
|
#include "vehicles/VehicleDefines.h"
|
|
#include "vehicles/vehicleFactory.h"
|
|
#include "vehicles/VehicleGadgets.h"
|
|
#include "renderer/ApplyDamage.h"
|
|
#include "vehicles/Metadata/AIHandlingInfo.h"
|
|
#include "vehicles/Metadata/VehicleMetadataManager.h"
|
|
#include "vehicles/Metadata/VehicleDebug.h"
|
|
#include "vehicles/Metadata/VehicleSeatInfo.h"
|
|
#include "shaders/CustomShaderEffectVehicle.h"
|
|
#include "script/commands_vehicle.h"
|
|
#include "Tools/smokeTest.h"
|
|
#include "vfx/misc/Fire.h"
|
|
#include "vfx/particles/PtFxManager.h"
|
|
#include "vfx/vehicleglass/VehicleGlassSmashTest.h"
|
|
#include "network/NetworkInterface.h"
|
|
#include "network/Debug/NetworkDebug.h"
|
|
#include "system/poolallocator.h"
|
|
#include "renderer/ApplyDamage.h"
|
|
|
|
#if __BANK
|
|
#include "Task/Default/TaskPlayer.h"
|
|
#endif //__BANK
|
|
|
|
AI_VEHICLE_OPTIMISATIONS()
|
|
VEHICLE_OPTIMISATIONS()
|
|
|
|
RAGE_DEFINE_CHANNEL(boatTrailer)
|
|
|
|
// --- Defines ------------------------------------------------------------------
|
|
|
|
// --- Constants ----------------------------------------------------------------
|
|
|
|
// --- Structure/Class Definitions ----------------------------------------------
|
|
|
|
// --- Globals ------------------------------------------------------------------
|
|
PARAM(defaultVehicle,"define default vehicle (used for U/Shift+U)");
|
|
PARAM(defaultVehicleTrailer,"define default vehicle trailer (used for U/Shift+U)");
|
|
|
|
PARAM(debugvehicle,"create vehicle bank by default");
|
|
XPARAM(debugtrain);
|
|
|
|
XPARAM(disablewheelintegrationtask);
|
|
|
|
// --- Static Globals -----------------------------------------------------------
|
|
|
|
static ObjectNameIdAssociation carIds[VEH_NUM_NODES + 1] =
|
|
{
|
|
{"chassis", VEH_CHASSIS},
|
|
{"chassis_lowlod", VEH_CHASSIS_LOWLOD},
|
|
{"chassis_dummy", VEH_CHASSIS_DUMMY},
|
|
|
|
{"door_dside_f", VEH_DOOR_DSIDE_F},
|
|
{"door_dside_r", VEH_DOOR_DSIDE_R},
|
|
{"door_pside_f", VEH_DOOR_PSIDE_F},
|
|
{"door_pside_r", VEH_DOOR_PSIDE_R},
|
|
|
|
{"handle_dside_f", VEH_HANDLE_DSIDE_F},
|
|
{"handle_dside_r", VEH_HANDLE_DSIDE_R},
|
|
{"handle_pside_f", VEH_HANDLE_PSIDE_F},
|
|
{"handle_pside_r", VEH_HANDLE_PSIDE_R},
|
|
|
|
{"wheel_lf", VEH_WHEEL_LF},
|
|
{"wheel_rf", VEH_WHEEL_RF},
|
|
{"wheel_lm1", VEH_WHEEL_LM1},
|
|
{"wheel_rm1", VEH_WHEEL_RM1},
|
|
{"wheel_lm2", VEH_WHEEL_LM2},
|
|
{"wheel_rm2", VEH_WHEEL_RM2},
|
|
{"wheel_lm3", VEH_WHEEL_LM3},
|
|
{"wheel_rm3", VEH_WHEEL_RM3},
|
|
{"wheel_lr", VEH_WHEEL_LR},
|
|
{"wheel_rr", VEH_WHEEL_RR},
|
|
|
|
{"suspension_lf", VEH_SUSPENSION_LF},
|
|
{"suspension_rf", VEH_SUSPENSION_RF},
|
|
{"suspension_lm", VEH_SUSPENSION_LM},
|
|
{"suspension_rm", VEH_SUSPENSION_RM},
|
|
{"suspension_lr", VEH_SUSPENSION_LR},
|
|
{"suspension_rr", VEH_SUSPENSION_RR},
|
|
{"spring_rf", VEH_SPRING_RF},
|
|
{"spring_lf", VEH_SPRING_LF},
|
|
{"spring_rr", VEH_SPRING_RR},
|
|
{"spring_lr", VEH_SPRING_LR},
|
|
{"transmission_f", VEH_TRANSMISSION_F},
|
|
{"transmission_m", VEH_TRANSMISSION_M},
|
|
{"transmission_r", VEH_TRANSMISSION_R},
|
|
{"hub_lf", VEH_WHEELHUB_LF},
|
|
{"hub_rf", VEH_WHEELHUB_RF},
|
|
{"hub_lm1", VEH_WHEELHUB_LM1},
|
|
{"hub_rm1", VEH_WHEELHUB_RM1},
|
|
{"hub_lm2", VEH_WHEELHUB_LM2},
|
|
{"hub_rm2", VEH_WHEELHUB_RM2},
|
|
{"hub_lm3", VEH_WHEELHUB_LM3},
|
|
{"hub_rm3", VEH_WHEELHUB_RM3},
|
|
{"hub_lr", VEH_WHEELHUB_LR},
|
|
{"hub_rr", VEH_WHEELHUB_RR},
|
|
|
|
{"windscreen", VEH_WINDSCREEN},
|
|
{"windscreen_r", VEH_WINDSCREEN_R},
|
|
{"window_lf", VEH_WINDOW_LF},
|
|
{"window_rf", VEH_WINDOW_RF},
|
|
{"window_lr", VEH_WINDOW_LR},
|
|
{"window_rr", VEH_WINDOW_RR},
|
|
{"window_lm", VEH_WINDOW_LM},
|
|
{"window_rm", VEH_WINDOW_RM},
|
|
|
|
{"bodyshell", VEH_BODYSHELL},
|
|
{"bumper_f", VEH_BUMPER_F},
|
|
{"bumper_r", VEH_BUMPER_R},
|
|
{"wing_rf", VEH_WING_RF},
|
|
{"wing_lf", VEH_WING_LF},
|
|
{"bonnet", VEH_BONNET},
|
|
{"boot", VEH_BOOT},
|
|
{"cargodoor", VEH_BOOT_2},
|
|
{"exhaust", VEH_EXHAUST},
|
|
{"exhaust_2", VEH_EXHAUST_2},
|
|
{"exhaust_3", VEH_EXHAUST_3},
|
|
{"exhaust_4", VEH_EXHAUST_4},
|
|
{"exhaust_5", VEH_EXHAUST_5},
|
|
{"exhaust_6", VEH_EXHAUST_6},
|
|
{"exhaust_7", VEH_EXHAUST_7},
|
|
{"exhaust_8", VEH_EXHAUST_8},
|
|
{"exhaust_9", VEH_EXHAUST_9},
|
|
{"exhaust_10", VEH_EXHAUST_10},
|
|
{"exhaust_11", VEH_EXHAUST_11},
|
|
{"exhaust_12", VEH_EXHAUST_12},
|
|
{"exhaust_13", VEH_EXHAUST_13},
|
|
{"exhaust_14", VEH_EXHAUST_14},
|
|
{"exhaust_15", VEH_EXHAUST_15},
|
|
{"exhaust_16", VEH_EXHAUST_16},
|
|
{"engine", VEH_ENGINE},
|
|
{"overheat", VEH_OVERHEAT},
|
|
{"overheat_2", VEH_OVERHEAT_2},
|
|
{"petrolcap", VEH_PETROLCAP},
|
|
{"petroltank", VEH_PETROLTANK},
|
|
{"petroltank_l", VEH_PETROLTANK_L},
|
|
{"petroltank_r", VEH_PETROLTANK_R},
|
|
{"steering", VEH_STEERING_WHEEL},
|
|
{"steeringwheel", VEH_CAR_STEERING_WHEEL},
|
|
{"hbgrip_l", VEH_HBGRIP_L},
|
|
{"hbgrip_r", VEH_HBGRIP_R},
|
|
{"thrust", VEH_ROCKET_BOOST},
|
|
{"thrust_2", VEH_ROCKET_BOOST_2},
|
|
{"thrust_3", VEH_ROCKET_BOOST_3},
|
|
{"thrust_4", VEH_ROCKET_BOOST_4},
|
|
{"thrust_5", VEH_ROCKET_BOOST_5},
|
|
{"thrust_6", VEH_ROCKET_BOOST_6},
|
|
{"thrust_7", VEH_ROCKET_BOOST_7},
|
|
{"thrust_8", VEH_ROCKET_BOOST_8},
|
|
|
|
{"headlight_l", VEH_HEADLIGHT_L},
|
|
{"headlight_r", VEH_HEADLIGHT_R},
|
|
{"taillight_l", VEH_TAILLIGHT_L},
|
|
{"taillight_r", VEH_TAILLIGHT_R},
|
|
{"indicator_lf", VEH_INDICATOR_LF},
|
|
{"indicator_rf", VEH_INDICATOR_RF},
|
|
{"indicator_lr", VEH_INDICATOR_LR},
|
|
{"indicator_rr", VEH_INDICATOR_RR},
|
|
{"brakelight_l", VEH_BRAKELIGHT_L},
|
|
{"brakelight_r", VEH_BRAKELIGHT_R},
|
|
{"brakelight_m", VEH_BRAKELIGHT_M},
|
|
{"reversinglight_l",VEH_REVERSINGLIGHT_L},
|
|
{"reversinglight_r",VEH_REVERSINGLIGHT_R},
|
|
{"neon_l", VEH_NEON_L},
|
|
{"neon_r", VEH_NEON_R},
|
|
{"neon_f", VEH_NEON_F},
|
|
{"neon_b", VEH_NEON_B},
|
|
{"extralight_1", VEH_EXTRALIGHT_1},
|
|
{"extralight_2", VEH_EXTRALIGHT_2},
|
|
{"extralight_3", VEH_EXTRALIGHT_3},
|
|
{"extralight_4", VEH_EXTRALIGHT_4},
|
|
|
|
{"emissives", VEH_EMISSIVES},
|
|
{"numberplate", VEH_NUMBERPLATE},
|
|
{"interiorlight", VEH_INTERIORLIGHT},
|
|
|
|
{"platelight", VEH_PLATELIGHT},
|
|
{"dashglow", VEH_DASHLIGHT},
|
|
{"doorlight_lf", VEH_DOORLIGHT_LF},
|
|
{"doorlight_rf", VEH_DOORLIGHT_RF},
|
|
{"doorlight_lr", VEH_DOORLIGHT_LR},
|
|
{"doorlight_rr", VEH_DOORLIGHT_RR},
|
|
|
|
{"siren1", VEH_SIREN_1},
|
|
{"siren2", VEH_SIREN_2},
|
|
{"siren3", VEH_SIREN_3},
|
|
{"siren4", VEH_SIREN_4},
|
|
{"siren5", VEH_SIREN_5},
|
|
{"siren6", VEH_SIREN_6},
|
|
{"siren7", VEH_SIREN_7},
|
|
{"siren8", VEH_SIREN_8},
|
|
{"siren9", VEH_SIREN_9},
|
|
{"siren10", VEH_SIREN_10},
|
|
{"siren11", VEH_SIREN_11},
|
|
{"siren12", VEH_SIREN_12},
|
|
{"siren13", VEH_SIREN_13},
|
|
{"siren14", VEH_SIREN_14},
|
|
{"siren15", VEH_SIREN_15},
|
|
{"siren16", VEH_SIREN_16},
|
|
{"siren17", VEH_SIREN_17},
|
|
{"siren18", VEH_SIREN_18},
|
|
{"siren19", VEH_SIREN_19},
|
|
{"siren20", VEH_SIREN_20},
|
|
|
|
{"siren_glass1", VEH_SIREN_GLASS_1},
|
|
{"siren_glass2", VEH_SIREN_GLASS_2},
|
|
{"siren_glass3", VEH_SIREN_GLASS_3},
|
|
{"siren_glass4", VEH_SIREN_GLASS_4},
|
|
{"siren_glass5", VEH_SIREN_GLASS_5},
|
|
{"siren_glass6", VEH_SIREN_GLASS_6},
|
|
{"siren_glass7", VEH_SIREN_GLASS_7},
|
|
{"siren_glass8", VEH_SIREN_GLASS_8},
|
|
{"siren_glass9", VEH_SIREN_GLASS_9},
|
|
{"siren_glass10", VEH_SIREN_GLASS_10},
|
|
{"siren_glass11", VEH_SIREN_GLASS_11},
|
|
{"siren_glass12", VEH_SIREN_GLASS_12},
|
|
{"siren_glass13", VEH_SIREN_GLASS_13},
|
|
{"siren_glass14", VEH_SIREN_GLASS_14},
|
|
{"siren_glass15", VEH_SIREN_GLASS_15},
|
|
{"siren_glass16", VEH_SIREN_GLASS_16},
|
|
{"siren_glass17", VEH_SIREN_GLASS_17},
|
|
{"siren_glass18", VEH_SIREN_GLASS_18},
|
|
{"siren_glass19", VEH_SIREN_GLASS_19},
|
|
{"siren_glass20", VEH_SIREN_GLASS_20},
|
|
|
|
{"dials", VEH_DIALS},
|
|
|
|
{"light_cover", VEH_LIGHTCOVER},
|
|
|
|
{"bobble_head", VEH_BOBBLE_HEAD},
|
|
{"bobble_base", VEH_BOBBLE_BASE},
|
|
{"bobble_hand", VEH_BOBBLE_HAND},
|
|
{"engineblock", VEH_BOBBLE_ENGINE},
|
|
|
|
{"spoiler", VEH_SPOILER},
|
|
{"struts", VEH_STRUTS},
|
|
|
|
{"spflap_l", VEH_FLAP_L},
|
|
{"spflap_r", VEH_FLAP_R},
|
|
|
|
{"misc_a", VEH_MISC_A},
|
|
{"misc_b", VEH_MISC_B},
|
|
{"misc_c", VEH_MISC_C},
|
|
{"misc_d", VEH_MISC_D},
|
|
{"misc_e", VEH_MISC_E},
|
|
{"misc_f", VEH_MISC_F},
|
|
{"misc_g", VEH_MISC_G},
|
|
{"misc_h", VEH_MISC_H},
|
|
{"misc_i", VEH_MISC_I},
|
|
{"misc_j", VEH_MISC_J},
|
|
{"misc_k", VEH_MISC_K},
|
|
{"misc_l", VEH_MISC_L},
|
|
{"misc_m", VEH_MISC_M},
|
|
{"misc_n", VEH_MISC_N},
|
|
{"misc_o", VEH_MISC_O},
|
|
{"misc_p", VEH_MISC_P},
|
|
{"misc_q", VEH_MISC_Q},
|
|
{"misc_r", VEH_MISC_R},
|
|
{"misc_s", VEH_MISC_S},
|
|
{"misc_t", VEH_MISC_T},
|
|
{"misc_u", VEH_MISC_U},
|
|
{"misc_v", VEH_MISC_V},
|
|
{"misc_w", VEH_MISC_W},
|
|
{"misc_x", VEH_MISC_X},
|
|
{"misc_y", VEH_MISC_Y},
|
|
{"misc_z", VEH_MISC_Z},
|
|
{"misc_1", VEH_MISC_1},
|
|
{"misc_2", VEH_MISC_2},
|
|
|
|
{"weapon_1a", VEH_WEAPON_1A},
|
|
{"weapon_1b", VEH_WEAPON_1B},
|
|
{"weapon_1c", VEH_WEAPON_1C},
|
|
{"weapon_1d", VEH_WEAPON_1D},
|
|
{"weapon_1a_rot", VEH_WEAPON_1A_ROT},
|
|
{"weapon_1b_rot", VEH_WEAPON_1B_ROT},
|
|
{"weapon_1c_rot", VEH_WEAPON_1C_ROT},
|
|
{"weapon_1d_rot", VEH_WEAPON_1D_ROT},
|
|
{"weapon_2a", VEH_WEAPON_2A},
|
|
{"weapon_2b", VEH_WEAPON_2B},
|
|
{"weapon_2c", VEH_WEAPON_2C},
|
|
{"weapon_2d", VEH_WEAPON_2D},
|
|
{"weapon_2e", VEH_WEAPON_2E},
|
|
{"weapon_2f", VEH_WEAPON_2F},
|
|
{"weapon_2g", VEH_WEAPON_2G},
|
|
{"weapon_2h", VEH_WEAPON_2H},
|
|
{"weapon_2a_rot", VEH_WEAPON_2A_ROT},
|
|
{"weapon_2b_rot", VEH_WEAPON_2B_ROT},
|
|
{"weapon_2c_rot", VEH_WEAPON_2C_ROT},
|
|
{"weapon_2d_rot", VEH_WEAPON_2D_ROT},
|
|
{"weapon_3a", VEH_WEAPON_3A},
|
|
{"weapon_3b", VEH_WEAPON_3B},
|
|
{"weapon_3c", VEH_WEAPON_3C},
|
|
{"weapon_3d", VEH_WEAPON_3D},
|
|
{"weapon_3a_rot", VEH_WEAPON_3A_ROT},
|
|
{"weapon_3b_rot", VEH_WEAPON_3B_ROT},
|
|
{"weapon_3c_rot", VEH_WEAPON_3C_ROT},
|
|
{"weapon_3d_rot", VEH_WEAPON_3D_ROT},
|
|
{"weapon_4a", VEH_WEAPON_4A},
|
|
{"weapon_4b", VEH_WEAPON_4B},
|
|
{"weapon_4c", VEH_WEAPON_4C},
|
|
{"weapon_4d", VEH_WEAPON_4D},
|
|
{"weapon_4a_rot", VEH_WEAPON_4A_ROT},
|
|
{"weapon_4b_rot", VEH_WEAPON_4B_ROT},
|
|
{"weapon_4c_rot", VEH_WEAPON_4C_ROT},
|
|
{"weapon_4d_rot", VEH_WEAPON_4D_ROT},
|
|
|
|
{"weapon_5a", VEH_WEAPON_5A},
|
|
{"weapon_5b", VEH_WEAPON_5B},
|
|
{"weapon_5c", VEH_WEAPON_5C},
|
|
{"weapon_5d", VEH_WEAPON_5D},
|
|
{"weapon_5e", VEH_WEAPON_5E},
|
|
{"weapon_5f", VEH_WEAPON_5F},
|
|
{"weapon_5g", VEH_WEAPON_5G},
|
|
{"weapon_5h", VEH_WEAPON_5H},
|
|
{"weapon_5i", VEH_WEAPON_5I},
|
|
{"weapon_5j", VEH_WEAPON_5J},
|
|
{"weapon_5k", VEH_WEAPON_5K},
|
|
{"weapon_5l", VEH_WEAPON_5L},
|
|
{"weapon_5m", VEH_WEAPON_5M},
|
|
{"weapon_5n", VEH_WEAPON_5N},
|
|
{"weapon_5o", VEH_WEAPON_5O},
|
|
{"weapon_5p", VEH_WEAPON_5P},
|
|
{"weapon__5q", VEH_WEAPON_5Q},
|
|
{"weapon_5r", VEH_WEAPON_5R},
|
|
{"weapon_5s", VEH_WEAPON_5S},
|
|
{"weapon_5t", VEH_WEAPON_5T},
|
|
{"weapon_5u", VEH_WEAPON_5U},
|
|
{"weapon_5v", VEH_WEAPON_5V},
|
|
{"weapon_5w", VEH_WEAPON_5W},
|
|
{"weapon_5x", VEH_WEAPON_5X},
|
|
{"weapon_5y", VEH_WEAPON_5Y},
|
|
{"weapon_5z", VEH_WEAPON_5Z},
|
|
{"weapon_5aa", VEH_WEAPON_5AA},
|
|
{"weapon_5an", VEH_WEAPON_5AB},
|
|
{"weapon_5ac", VEH_WEAPON_5AC},
|
|
{"weapon_5ad", VEH_WEAPON_5AD},
|
|
{"weapon_5ae", VEH_WEAPON_5AE},
|
|
{"weapon_5af", VEH_WEAPON_5AF},
|
|
{"weapon_5ag", VEH_WEAPON_5AG},
|
|
{"weapon_5ah", VEH_WEAPON_5AH},
|
|
{"weapon_5ai", VEH_WEAPON_5AI},
|
|
{"weapon_5aj", VEH_WEAPON_5AJ},
|
|
{"weapon_5ak", VEH_WEAPON_5AK},
|
|
|
|
{"weapon_5a_rot", VEH_WEAPON_5A_ROT},
|
|
{"weapon_5b_rot", VEH_WEAPON_5B_ROT},
|
|
{"weapon_5c_rot", VEH_WEAPON_5C_ROT},
|
|
{"weapon_5d_rot", VEH_WEAPON_5D_ROT},
|
|
{"weapon_5e_rot", VEH_WEAPON_5E_ROT},
|
|
{"weapon_5f_rot", VEH_WEAPON_5F_ROT},
|
|
{"weapon_5g_rot", VEH_WEAPON_5G_ROT},
|
|
{"weapon_5h_rot", VEH_WEAPON_5H_ROT},
|
|
{"weapon_5i_rot", VEH_WEAPON_5I_ROT},
|
|
{"weapon_5j_rot", VEH_WEAPON_5J_ROT},
|
|
{"weapon_5k_rot", VEH_WEAPON_5K_ROT},
|
|
{"weapon_5l_rot", VEH_WEAPON_5L_ROT},
|
|
{"weapon_5m_rot", VEH_WEAPON_5M_ROT},
|
|
{"weapon_5n_rot", VEH_WEAPON_5N_ROT},
|
|
{"weapon_5o_rot", VEH_WEAPON_5O_ROT},
|
|
{"weapon_5p_rot", VEH_WEAPON_5P_ROT},
|
|
{"weapon_5q_rot", VEH_WEAPON_5Q_ROT},
|
|
{"weapon_5r_rot", VEH_WEAPON_5R_ROT},
|
|
{"weapon_5s_rot", VEH_WEAPON_5S_ROT},
|
|
{"weapon_5t_rot", VEH_WEAPON_5T_ROT},
|
|
{"weapon_5u_rot", VEH_WEAPON_5U_ROT},
|
|
{"weapon_5v_rot", VEH_WEAPON_5V_ROT},
|
|
{"weapon_5w_rot", VEH_WEAPON_5W_ROT},
|
|
{"weapon_5x_rot", VEH_WEAPON_5X_ROT},
|
|
{"weapon_5y_rot", VEH_WEAPON_5Y_ROT},
|
|
{"weapon_5z_rot", VEH_WEAPON_5Z_ROT},
|
|
{"weapon_5aa_rot", VEH_WEAPON_5AA_ROT},
|
|
{"weapon_5an_rot", VEH_WEAPON_5AB_ROT},
|
|
{"weapon_5ac_rot", VEH_WEAPON_5AC_ROT},
|
|
{"weapon_5ad_rot", VEH_WEAPON_5AD_ROT},
|
|
{"weapon_5ae_rot", VEH_WEAPON_5AE_ROT},
|
|
{"weapon_5af_rot", VEH_WEAPON_5AF_ROT},
|
|
{"weapon_5ag_rot", VEH_WEAPON_5AG_ROT},
|
|
{"weapon_5ah_rot", VEH_WEAPON_5AH_ROT},
|
|
{"weapon_5ai_rot", VEH_WEAPON_5AI_ROT},
|
|
{"weapon_5aj_rot", VEH_WEAPON_5AJ_ROT},
|
|
{"weapon_5ak_rot", VEH_WEAPON_5AK_ROT},
|
|
|
|
|
|
{"weapon_6a", VEH_WEAPON_6A},
|
|
{"weapon_6b", VEH_WEAPON_6B},
|
|
{"weapon_6c", VEH_WEAPON_6C},
|
|
{"weapon_6d", VEH_WEAPON_6D},
|
|
{"weapon_6a_rot", VEH_WEAPON_6A_ROT},
|
|
{"weapon_6b_rot", VEH_WEAPON_6B_ROT},
|
|
{"weapon_6c_rot", VEH_WEAPON_6C_ROT},
|
|
{"weapon_6d_rot", VEH_WEAPON_6D_ROT},
|
|
{"turret_1base", VEH_TURRET_1_BASE},
|
|
{"turret_1barrel", VEH_TURRET_1_BARREL},
|
|
{"turret_2base", VEH_TURRET_2_BASE},
|
|
{"turret_2barrel", VEH_TURRET_2_BARREL},
|
|
{"turret_3base", VEH_TURRET_3_BASE},
|
|
{"turret_3barrel", VEH_TURRET_3_BARREL},
|
|
{"turret_4base", VEH_TURRET_4_BASE},
|
|
{"turret_4barrel", VEH_TURRET_4_BARREL},
|
|
{"ammobelt", VEH_TURRET_AMMO_BELT},
|
|
|
|
{"searchlight_base", VEH_SEARCHLIGHT_BASE},
|
|
{"searchlight_light", VEH_SEARCHLIGHT_BARREL},
|
|
|
|
{"attach_female", VEH_ATTACH},
|
|
{"roof", VEH_ROOF},
|
|
{"roof2", VEH_ROOF2},
|
|
|
|
{"soft_1", VEH_SOFTTOP_1},
|
|
{"soft_2", VEH_SOFTTOP_2},
|
|
{"soft_3", VEH_SOFTTOP_3},
|
|
{"soft_4", VEH_SOFTTOP_4},
|
|
{"soft_5", VEH_SOFTTOP_5},
|
|
{"soft_6", VEH_SOFTTOP_6},
|
|
{"soft_7", VEH_SOFTTOP_7},
|
|
{"soft_8", VEH_SOFTTOP_8},
|
|
{"soft_9", VEH_SOFTTOP_9},
|
|
{"soft_10", VEH_SOFTTOP_10},
|
|
{"soft_11", VEH_SOFTTOP_11},
|
|
{"soft_12", VEH_SOFTTOP_12},
|
|
{"soft_13", VEH_SOFTTOP_13},
|
|
|
|
{"pontoon_l", VEH_PONTOON_L},
|
|
{"pontoon_r", VEH_PONTOON_R},
|
|
|
|
{"forks", VEH_FORKS},
|
|
{"mast", VEH_MAST},
|
|
{"carriage", VEH_CARRIAGE},
|
|
{"fork_l", VEH_FORK_LEFT},
|
|
{"fork_r", VEH_FORK_RIGHT},
|
|
{"forks_attach", VEH_FORKS_ATTACH},
|
|
|
|
{"frame_1", VEH_HANDLER_FRAME_1},
|
|
{"frame_2", VEH_HANDLER_FRAME_2},
|
|
{"frame_3", VEH_HANDLER_FRAME_3},
|
|
{"frame_pickup_1", VEH_HANDLER_FRAME_PICKUP_1},
|
|
{"frame_pickup_2", VEH_HANDLER_FRAME_PICKUP_2},
|
|
{"frame_pickup_3", VEH_HANDLER_FRAME_PICKUP_3},
|
|
{"frame_pickup_4", VEH_HANDLER_FRAME_PICKUP_4},
|
|
|
|
{"no_ped_col_step_l", VEH_DODO_NO_PED_COL_STEP_L},
|
|
{"no_ped_col_strut_1_l", VEH_DODO_NO_PED_COL_STRUT_1_L},
|
|
{"no_ped_col_strut_2_l", VEH_DODO_NO_PED_COL_STRUT_2_L},
|
|
{"no_ped_col_step_r", VEH_DODO_NO_PED_COL_STEP_R},
|
|
{"no_ped_col_strut_1_r", VEH_DODO_NO_PED_COL_STRUT_1_R},
|
|
{"no_ped_col_strut_2_r", VEH_DODO_NO_PED_COL_STRUT_2_R},
|
|
|
|
{"freight_cont", VEH_FREIGHTCONT2_CONTAINER},
|
|
{"freight_bogey", VEH_FREIGHTCONT2_BOGEY},
|
|
|
|
{"freightgrain_slidedoor", VEH_FREIGHTGRAIN_SLIDING_DOOR},
|
|
|
|
{"door_hatch_r", VEH_DOOR_HATCH_R},
|
|
{"door_hatch_l", VEH_DOOR_HATCH_L},
|
|
|
|
{"tow_arm", VEH_TOW_ARM},
|
|
{"tow_mount_a", VEH_TOW_MOUNT_A},
|
|
{"tow_mount_b", VEH_TOW_MOUNT_B},
|
|
|
|
{"tipper", VEH_TIPPER},
|
|
|
|
{"combine_reel", VEH_PICKUP_REEL},
|
|
{"combine_auger", VEH_AUGER},
|
|
|
|
{"slipstream_l", VEH_SLIPSTREAM_L},
|
|
{"slipstream_r", VEH_SLIPSTREAM_R},
|
|
|
|
{"arm_1", VEH_ARM1},
|
|
{"arm_2", VEH_ARM2},
|
|
{"arm_3", VEH_ARM3},
|
|
{"arm_4", VEH_ARM4},
|
|
|
|
{"scoop", VEH_DIGGER_ARM},
|
|
{"bodyshell", VEH_ARTICULATED_DIGGER_ARM_BASE},
|
|
{"boom", VEH_ARTICULATED_DIGGER_ARM_BOOM},
|
|
{"stick", VEH_ARTICULATED_DIGGER_ARM_STICK},
|
|
{"bucket", VEH_ARTICULATED_DIGGER_ARM_BUCKET},
|
|
|
|
{"shovel_2", VEH_DIGGER_SHOVEL_2},
|
|
{"shovel_3", VEH_DIGGER_SHOVEL_3},
|
|
|
|
{"Lookat_UpprPiston_head", VEH_CUTTER_ARM_1},
|
|
{"Lookat_LowrPiston_boom", VEH_CUTTER_ARM_2},
|
|
{"Boom_Driver", VEH_CUTTER_BOOM_DRIVER},
|
|
{"cutter_driver", VEH_CUTTER_CUTTER_DRIVER},
|
|
|
|
{"vehicle_blocker", VEH_VEHICLE_BLOCKER},
|
|
|
|
{"extra_1", VEH_EXTRA_1},
|
|
{"extra_2", VEH_EXTRA_2},
|
|
{"extra_3", VEH_EXTRA_3},
|
|
{"extra_4", VEH_EXTRA_4},
|
|
{"extra_5", VEH_EXTRA_5},
|
|
{"extra_6", VEH_EXTRA_6},
|
|
{"extra_7", VEH_EXTRA_7},
|
|
{"extra_8", VEH_EXTRA_8},
|
|
{"extra_9", VEH_EXTRA_9},
|
|
{"extra_ten", VEH_EXTRA_10}, // Name it to "extra_ten", as the hash of "extra_10" clashes with "headlight_r"
|
|
|
|
{"extra_11", VEH_EXTRA_11},
|
|
{"extra_12", VEH_EXTRA_12},
|
|
|
|
{"break_extra_1", VEH_BREAKABLE_EXTRA_1},
|
|
{"break_extra_2", VEH_BREAKABLE_EXTRA_2},
|
|
{"break_extra_3", VEH_BREAKABLE_EXTRA_3},
|
|
{"break_extra_4", VEH_BREAKABLE_EXTRA_4},
|
|
{"break_extra_5", VEH_BREAKABLE_EXTRA_5},
|
|
{"break_extra_6", VEH_BREAKABLE_EXTRA_6},
|
|
{"break_extra_7", VEH_BREAKABLE_EXTRA_7},
|
|
{"break_extra_8", VEH_BREAKABLE_EXTRA_8},
|
|
{"break_extra_9", VEH_BREAKABLE_EXTRA_9},
|
|
{"break_extra_10", VEH_BREAKABLE_EXTRA_10},
|
|
|
|
{"mod_col_1", VEH_MOD_COLLISION_1},
|
|
{"mod_col_2", VEH_MOD_COLLISION_2},
|
|
{"mod_col_3", VEH_MOD_COLLISION_3},
|
|
{"mod_col_4", VEH_MOD_COLLISION_4},
|
|
{"mod_col_5", VEH_MOD_COLLISION_5},
|
|
{ "mod_col_6", VEH_MOD_COLLISION_6 },
|
|
{ "mod_col_7", VEH_MOD_COLLISION_7 },
|
|
{ "mod_col_8", VEH_MOD_COLLISION_8 },
|
|
{ "mod_col_9", VEH_MOD_COLLISION_9 },
|
|
{ "mod_col_10", VEH_MOD_COLLISION_10 },
|
|
{ "mod_col_11", VEH_MOD_COLLISION_11 },
|
|
{ "mod_col_12", VEH_MOD_COLLISION_12 },
|
|
{ "mod_col_13", VEH_MOD_COLLISION_13 },
|
|
{ "mod_col_14", VEH_MOD_COLLISION_14 },
|
|
{ "mod_col_15", VEH_MOD_COLLISION_15 },
|
|
{ "mod_col_16", VEH_MOD_COLLISION_16 },
|
|
|
|
{"parachute_open", VEH_PARACHUTE_OPEN},
|
|
{"parachute_deploy",VEH_PARACHUTE_DEPLOY},
|
|
|
|
{"wedge", VEH_RAMMING_SCOOP},
|
|
|
|
{"turret_1mod", VEH_TURRET_1_MOD},
|
|
{"turret_2mod", VEH_TURRET_2_MOD},
|
|
{"turret_3mod", VEH_TURRET_3_MOD},
|
|
{"turret_4mod", VEH_TURRET_4_MOD},
|
|
|
|
{"missileflap_2a", VEH_MISSILEFLAP_2A},
|
|
{"missileflap_2b", VEH_MISSILEFLAP_2B},
|
|
{"missileflap_2c", VEH_MISSILEFLAP_2C},
|
|
{"missileflap_2d", VEH_MISSILEFLAP_2D},
|
|
{"missileflap_2e", VEH_MISSILEFLAP_2E},
|
|
{"missileflap_2f", VEH_MISSILEFLAP_2F},
|
|
|
|
{"extendable_l", VEH_EXTENDABLE_SIDE_L},
|
|
{"extendable_r", VEH_EXTENDABLE_SIDE_R},
|
|
|
|
{"extendable_lf", VEH_EXTENDABLE_A},
|
|
{"extendable_rf", VEH_EXTENDABLE_B},
|
|
{"extendable_lr", VEH_EXTENDABLE_C},
|
|
{"extendable_rr", VEH_EXTENDABLE_D},
|
|
|
|
{ "rotator_l", VEH_ROTATOR_L },
|
|
{ "rotator_r", VEH_ROTATOR_R },
|
|
|
|
{"mod_a", VEH_MOD_A},
|
|
{"mod_b", VEH_MOD_B},
|
|
{"mod_c", VEH_MOD_C},
|
|
{"mod_d", VEH_MOD_D},
|
|
{"mod_e", VEH_MOD_E},
|
|
{"mod_f", VEH_MOD_F},
|
|
{"mod_g", VEH_MOD_G},
|
|
{"mod_h", VEH_MOD_H},
|
|
{"mod_i", VEH_MOD_I},
|
|
{"mod_j", VEH_MOD_J},
|
|
{"mod_k", VEH_MOD_K},
|
|
{"mod_l", VEH_MOD_L},
|
|
{"mod_m", VEH_MOD_M},
|
|
{"mod_n", VEH_MOD_N},
|
|
{"mod_o", VEH_MOD_O},
|
|
{"mod_p", VEH_MOD_P},
|
|
{"mod_q", VEH_MOD_Q},
|
|
{"mod_r", VEH_MOD_R},
|
|
{"mod_s", VEH_MOD_S},
|
|
{"mod_t", VEH_MOD_T},
|
|
{"mod_u", VEH_MOD_U},
|
|
{"mod_v", VEH_MOD_V},
|
|
{"mod_w", VEH_MOD_W},
|
|
{"mod_x", VEH_MOD_X},
|
|
{"mod_y", VEH_MOD_Y},
|
|
{"mod_z", VEH_MOD_Z},
|
|
{"mod_aa", VEH_MOD_AA},
|
|
{"mod_ab", VEH_MOD_AB},
|
|
{"mod_ac", VEH_MOD_AC},
|
|
{"mod_ad", VEH_MOD_AD},
|
|
{"mod_ae", VEH_MOD_AE},
|
|
{"mod_af", VEH_MOD_AF},
|
|
{"mod_ag", VEH_MOD_AG},
|
|
{"mod_ah", VEH_MOD_AH},
|
|
{"mod_ai", VEH_MOD_AI},
|
|
{"mod_aj", VEH_MOD_AJ},
|
|
{"mod_ak", VEH_MOD_AK},
|
|
|
|
{"turret_a1mod", VEH_TURRET_A1_MOD},
|
|
{"turret_a2mod", VEH_TURRET_A2_MOD},
|
|
{"turret_a3mod", VEH_TURRET_A3_MOD},
|
|
{"turret_a4mod", VEH_TURRET_A4_MOD},
|
|
|
|
{"turret_b1mod", VEH_TURRET_B1_MOD},
|
|
{"turret_b2mod", VEH_TURRET_B2_MOD},
|
|
{"turret_b3mod", VEH_TURRET_B3_MOD},
|
|
{"turret_b4mod", VEH_TURRET_B4_MOD},
|
|
|
|
{"turret_a1base", VEH_TURRET_A1_BASE},
|
|
{"turret_a1barrel", VEH_TURRET_A1_BARREL},
|
|
{"turret_a2base", VEH_TURRET_A2_BASE},
|
|
{"turret_a2barrel", VEH_TURRET_A2_BARREL},
|
|
{"turret_a3base", VEH_TURRET_A3_BASE},
|
|
{"turret_a3barrel", VEH_TURRET_A3_BARREL},
|
|
{"turret_a4base", VEH_TURRET_A4_BASE},
|
|
{"turret_a4barrel", VEH_TURRET_A4_BARREL},
|
|
{"a_ammobelt", VEH_TURRET_A_AMMO_BELT},
|
|
|
|
{"turret_b1base", VEH_TURRET_B1_BASE},
|
|
{"turret_b1barrel", VEH_TURRET_B1_BARREL},
|
|
{"turret_b2base", VEH_TURRET_B2_BASE},
|
|
{"turret_b2barrel", VEH_TURRET_B2_BARREL},
|
|
{"turret_b3base", VEH_TURRET_B3_BASE},
|
|
{"turret_b3barrel", VEH_TURRET_B3_BARREL},
|
|
{"turret_b4base", VEH_TURRET_B4_BASE},
|
|
{"turret_b4barrel", VEH_TURRET_B4_BARREL},
|
|
{"b_ammobelt", VEH_TURRET_B_AMMO_BELT},
|
|
|
|
{"suspension_lm1", VEH_SUSPENSION_LM1},
|
|
{"suspension_rm1", VEH_SUSPENSION_RM1},
|
|
{"transmission_m1", VEH_TRANSMISSION_M1},
|
|
|
|
{"leg_fl", VEH_LEG_FL},
|
|
{"leg_fr", VEH_LEG_FR},
|
|
{"leg_rl", VEH_LEG_RL},
|
|
{"leg_rr", VEH_LEG_RR},
|
|
|
|
{"panel_l1", VEH_PANEL_L1},
|
|
{"panel_l2", VEH_PANEL_L2},
|
|
{"panel_l3", VEH_PANEL_L3},
|
|
{"panel_l4", VEH_PANEL_L4},
|
|
{"panel_l5", VEH_PANEL_L5},
|
|
|
|
{"panel_r1", VEH_PANEL_R1},
|
|
{"panel_r2", VEH_PANEL_R2},
|
|
{"panel_r3", VEH_PANEL_R3},
|
|
{"panel_r4", VEH_PANEL_R4},
|
|
{"panel_r5", VEH_PANEL_R5},
|
|
|
|
{"f_wing_l", VEH_FOLDING_WING_L},
|
|
{"f_wing_r", VEH_FOLDING_WING_R},
|
|
|
|
{"stand", VEH_STAND},
|
|
|
|
{"pbusspeaker", VEH_SPEAKER},
|
|
|
|
{ "nozzles_f", VEH_NOZZLE_F },
|
|
{ "nozzles_r", VEH_NOZZLE_R },
|
|
|
|
// Extra arena mode bones
|
|
{ "rblade_1mod", VEH_BLADE_R_1_MOD },
|
|
{ "rblade_1fast", VEH_BLADE_R_1_FAST },
|
|
|
|
{ "rblade_2mod", VEH_BLADE_R_2_MOD },
|
|
{ "rblade_2fast", VEH_BLADE_R_2_FAST },
|
|
|
|
{ "rblade_3mod", VEH_BLADE_R_3_MOD },
|
|
{ "rblade_3fast", VEH_BLADE_R_3_FAST },
|
|
|
|
{ "fblade_1mod", VEH_BLADE_F_1_MOD },
|
|
{ "fblade_1fast", VEH_BLADE_F_1_FAST },
|
|
|
|
{ "fblade_2mod", VEH_BLADE_F_2_MOD },
|
|
{ "fblade_2fast", VEH_BLADE_F_2_FAST },
|
|
|
|
{ "fblade_3mod", VEH_BLADE_F_3_MOD },
|
|
{ "fblade_3fast", VEH_BLADE_F_3_FAST },
|
|
|
|
{ "sblade_1mod", VEH_BLADE_S_1_MOD },
|
|
{ "sblade_l_1fast", VEH_BLADE_S_1_L_FAST },
|
|
{ "sblade_r_1fast", VEH_BLADE_S_1_R_FAST },
|
|
|
|
{ "sblade_2mod", VEH_BLADE_S_2_MOD },
|
|
{ "sblade_l_2fast", VEH_BLADE_S_2_L_FAST },
|
|
{ "sblade_r_2fast", VEH_BLADE_S_2_R_FAST },
|
|
|
|
{ "sblade_3mod", VEH_BLADE_S_3_MOD },
|
|
{ "sblade_l_3fast", VEH_BLADE_S_3_L_FAST },
|
|
{ "sblade_r_3fast", VEH_BLADE_S_3_R_FAST },
|
|
|
|
{ "spike_1mod", VEH_SPIKE_1_MOD },
|
|
{ "spike_1ped_col", VEH_SPIKE_1_PED },
|
|
{ "spike1car_col", VEH_SPIKE_1_CAR },
|
|
|
|
{ "spike_2mod", VEH_SPIKE_2_MOD },
|
|
{ "spike_2ped_col", VEH_SPIKE_2_PED },
|
|
{ "spike_2car_col", VEH_SPIKE_2_CAR },
|
|
|
|
{ "spike_3mod", VEH_SPIKE_3_MOD },
|
|
{ "spike_3ped_col", VEH_SPIKE_3_PED },
|
|
{ "spike_3car_col", VEH_SPIKE_3_CAR },
|
|
|
|
{ "scoop_1mod", VEH_SCOOP_1_MOD },
|
|
{ "scoop_2mod", VEH_SCOOP_2_MOD },
|
|
{ "scoop_3mod", VEH_SCOOP_3_MOD },
|
|
|
|
{ "miscwobble_1", VEH_BOBBLE_MISC_1 },
|
|
{ "miscwobble_2", VEH_BOBBLE_MISC_2 },
|
|
{ "miscwobble_3", VEH_BOBBLE_MISC_3 },
|
|
{ "miscwobble_4", VEH_BOBBLE_MISC_4 },
|
|
{ "miscwobble_5", VEH_BOBBLE_MISC_5 },
|
|
{ "miscwobble_6", VEH_BOBBLE_MISC_6 },
|
|
{ "miscwobble_7", VEH_BOBBLE_MISC_7 },
|
|
{ "miscwobble_8", VEH_BOBBLE_MISC_8 },
|
|
|
|
{ "supercharger_1", VEH_SUPERCHARGER_1 },
|
|
{ "supercharger_2", VEH_SUPERCHARGER_2 },
|
|
{ "supercharger_3", VEH_SUPERCHARGER_3 },
|
|
|
|
{ "ramp_1mod", VEH_RAMP_1_MOD },
|
|
{ "ramp_2mod", VEH_RAMP_2_MOD },
|
|
{ "ramp_3mod", VEH_RAMP_3_MOD },
|
|
|
|
{ "tombstone", VEH_TOMBSTONE },
|
|
|
|
{ "spike_1modf", VEH_FRONT_SPIKE_1 },
|
|
{ "spike_2modf", VEH_FRONT_SPIKE_2 },
|
|
{ "spike_3modf", VEH_FRONT_SPIKE_3 },
|
|
|
|
{ "ram_1mod", VEH_RAMMING_BAR_1 },
|
|
{ "ram_2mod", VEH_RAMMING_BAR_2 },
|
|
{ "ram_3mod", VEH_RAMMING_BAR_3 },
|
|
{ "ram_4mod", VEH_RAMMING_BAR_4 },
|
|
|
|
{0,0}
|
|
};
|
|
|
|
static ObjectNameIdAssociation quadBikeIds[QUADBIKE_NUM_OVERRIDDEN_NODES + 1] =
|
|
{
|
|
{"handlebars", QUADBIKE_HANDLEBARS},
|
|
{"forks_u", QUADBIKE_FORKS_U},
|
|
{"forks_l", QUADBIKE_FORKS_L},
|
|
{0,0}
|
|
};
|
|
|
|
static ObjectNameIdAssociation bikeIds[BIKE_NUM_OVERRIDDEN_NODES + 1] =
|
|
{
|
|
{"chassis", BIKE_CHASSIS},
|
|
{"forks_u", BIKE_FORKS_U},
|
|
{"forks_l", BIKE_FORKS_L},
|
|
{"handlebars", BIKE_HANDLEBARS},
|
|
{"wheel_f", BIKE_WHEEL_F},
|
|
{"swingarm", BIKE_SWINGARM},
|
|
{"wheel_r", BIKE_WHEEL_R},
|
|
{0,0}
|
|
};
|
|
|
|
static ObjectNameIdAssociation bmxIds[BMX_NUM_OVERRIDDEN_NODES + 1] =
|
|
{
|
|
{"chassis", BMX_CHASSIS},
|
|
{"forks_u", BMX_FORKS_U},
|
|
{"forks_l", BMX_FORKS_L},
|
|
{"wheel_lf", BMX_WHEEL_F},
|
|
{"wheel_lr", BMX_WHEEL_R},
|
|
{"transmission_r", BMX_SWINGARM},
|
|
{"handlebars", BMX_HANDLEBARS},
|
|
{"crank", BMX_CHAINSET},
|
|
{"pedal_r", BMX_PEDAL_L},
|
|
{"pedal_l", BMX_PEDAL_R},
|
|
{0,0}
|
|
};
|
|
|
|
|
|
static ObjectNameIdAssociation boatIds[BOAT_NUM_OVERRIDDEN_NODES + 1] =
|
|
{
|
|
{"static_prop", BOAT_STATIC_PROP},
|
|
{"moving_prop", BOAT_MOVING_PROP},
|
|
{"static_prop2", BOAT_STATIC_PROP2},
|
|
{"moving_prop2", BOAT_MOVING_PROP2},
|
|
{"rudder", BOAT_RUDDER},
|
|
{"rudder2", BOAT_RUDDER2},
|
|
{"handlebars", BOAT_HANDLEBARS},
|
|
{0,0}
|
|
};
|
|
|
|
static ObjectNameIdAssociation trainIds[TRAIN_NUM_OVERRIDDEN_NODES + 1] =
|
|
{
|
|
{"wheel_rf1_dummy", TRAIN_WHEEL_RF1},
|
|
{"wheel_rf2_dummy", TRAIN_WHEEL_RF2},
|
|
{"wheel_rf3_dummy", TRAIN_WHEEL_RF3},
|
|
{"wheel_rb1_dummy", TRAIN_WHEEL_RR1},
|
|
{"wheel_rb2_dummy", TRAIN_WHEEL_RR2},
|
|
{"wheel_rb3_dummy", TRAIN_WHEEL_RR3},
|
|
{"wheel_lf1_dummy", TRAIN_WHEEL_LF1},
|
|
{"wheel_lf2_dummy", TRAIN_WHEEL_LF2},
|
|
{"wheel_lf3_dummy", TRAIN_WHEEL_LF3},
|
|
{"wheel_lb1_dummy", TRAIN_WHEEL_LR1},
|
|
{"wheel_lb2_dummy", TRAIN_WHEEL_LR2},
|
|
{"wheel_lb3_dummy", TRAIN_WHEEL_LR3},
|
|
{"bogie_front", TRAIN_BOGIE_FRONT},
|
|
{"bogie_rear", TRAIN_BOGIE_REAR},
|
|
{"interior", TRAIN_INTERIOR},
|
|
#if !__FINAL
|
|
{"armyboxcar_slidedoor", TRAIN_BOXCAR_SLIDE_DOOR},
|
|
{"armyboxcar_slidedoor2", TRAIN_BOXCAR_SLIDE_DOOR2},
|
|
#endif // #if !__FINAL
|
|
{0,0}
|
|
};
|
|
|
|
static ObjectNameIdAssociation heliIds[HELI_NUM_OVERRIDDEN_NODES + 1] =
|
|
{
|
|
{"rotor_main", HELI_ROTOR_MAIN},
|
|
{"rotor_rear", HELI_ROTOR_REAR},
|
|
{"rotor_main_2", HELI_ROTOR_MAIN_2},
|
|
{"rotor_rear_2", HELI_ROTOR_REAR_2},
|
|
{"rudder", HELI_RUDDER},
|
|
{"elevators", HELI_ELEVATORS},
|
|
{"tail", HELI_TAIL},
|
|
{"outriggers_l", HELI_OUTRIGGERS_L},
|
|
{"outriggers_r", HELI_OUTRIGGERS_R},
|
|
{"rope_attach_a", HELI_ROPE_ATTACH_A},
|
|
{"rope_attach_b", HELI_ROPE_ATTACH_B},
|
|
{"extra_7", HELI_NOSE_VARIANT_A},
|
|
{"extra_8", HELI_NOSE_VARIANT_B},
|
|
{"extra_9", HELI_NOSE_VARIANT_C},
|
|
{"wing_l", HELI_WING_L},
|
|
{"wing_r", HELI_WING_R},
|
|
{"airbrake_l", HELI_AIRBRAKE_L},
|
|
{"airbrake_r", HELI_AIRBRAKE_R},
|
|
{"afterburner", HELI_AFTERBURNER},
|
|
{"afterburner_2", HELI_AFTERBURNER_2},
|
|
{"hbgrip_low_l", HELI_HBGRIP_LOW_L},
|
|
{"hbgrip_low_r", HELI_HBGRIP_LOW_R},
|
|
|
|
{0,0}
|
|
};
|
|
|
|
static ObjectNameIdAssociation blimpIds[BLIMP_NUM_OVERRIDDEN_NODES + 1] =
|
|
{
|
|
{"prop_1", BLIMP_PROP_1},
|
|
{"prop_2", BLIMP_PROP_2},
|
|
{"elevator_l", BLIMP_ELEVATOR_L},
|
|
{"elevator_r", BLIMP_ELEVATOR_R},
|
|
{"rudder_l", BLIMP_RUDDER_UPPER},
|
|
{"rudder_r", BLIMP_RUDDER_LOWER},
|
|
{"misc_c", BLIMP_SHELL},
|
|
{"misc_d", BLIMP_SHELL_FRAME_1},
|
|
{"misc_e", BLIMP_SHELL_FRAME_2},
|
|
{"misc_f", BLIMP_SHELL_FRAME_3},
|
|
{"misc_g", BLIMP_SHELL_FRAME_4},
|
|
{"engine_l", BLIMP_ENGINE_L},
|
|
{"engine_r", BLIMP_ENGINE_R},
|
|
{0,0}
|
|
};
|
|
|
|
static ObjectNameIdAssociation planeIds[PLANE_NUM_OVERRIDDEN_NODES + 1] =
|
|
{
|
|
{"prop_1", PLANE_PROP_1},
|
|
{"prop_2", PLANE_PROP_2},
|
|
{"prop_3", PLANE_PROP_3},
|
|
{"prop_4", PLANE_PROP_4},
|
|
{"prop_5", PLANE_PROP_5},
|
|
{"prop_6", PLANE_PROP_6},
|
|
{"prop_7", PLANE_PROP_7},
|
|
{"prop_8", PLANE_PROP_8},
|
|
{"rudder", PLANE_RUDDER},
|
|
{"rudder_2", PLANE_RUDDER_2},
|
|
{"elevator_l", PLANE_ELEVATOR_L},
|
|
{"elevator_r", PLANE_ELEVATOR_R},
|
|
{"aileron_l", PLANE_AILERON_L},
|
|
{"aileron_r", PLANE_AILERON_R},
|
|
{"airbrake_l", PLANE_AIRBRAKE_L},
|
|
{"airbrake_r", PLANE_AIRBRAKE_R},
|
|
{"wing_l", PLANE_WING_L},
|
|
{"wing_r", PLANE_WING_R},
|
|
{"wing_lr", PLANE_WING_RL},
|
|
{"wing_rr", PLANE_WING_RR},
|
|
{"tail", PLANE_TAIL},
|
|
{"engine_l", PLANE_ENGINE_L},
|
|
{"engine_r", PLANE_ENGINE_R},
|
|
{"nozzles_f", PLANE_NOZZLE_F},
|
|
{"nozzles_r", PLANE_NOZZLE_R},
|
|
{"afterburner", PLANE_AFTERBURNER},
|
|
{"afterburner_2", PLANE_AFTERBURNER_2},
|
|
{"afterburner_3", PLANE_AFTERBURNER_3},
|
|
{"afterburner_4", PLANE_AFTERBURNER_4},
|
|
{"wingtip_1", PLANE_WINGTIP_1},
|
|
{"wingtip_2", PLANE_WINGTIP_2},
|
|
{"exhaustvent", PLANE_EXHAUST_VENT},
|
|
{"handlebars", PLANE_HANDLEBARS},
|
|
{"wingflap_l", PLANE_WINGFLAP_L},
|
|
{"wingflap_r", PLANE_WINGFLAP_R},
|
|
{0,0}
|
|
};
|
|
|
|
static ObjectNameIdAssociation landingGearIds[ LANDING_GEAR_NUM_OVERRIDDEN_NODES + 1 ] =
|
|
{
|
|
{"gear_door_fl", LANDING_GEAR_DOOR_FL},
|
|
{"gear_door_fr", LANDING_GEAR_DOOR_FR},
|
|
{"gear_door_rl1", LANDING_GEAR_DOOR_RL1},
|
|
{"gear_door_rr1", LANDING_GEAR_DOOR_RR1},
|
|
{"gear_door_rl2", LANDING_GEAR_DOOR_RL2},
|
|
{"gear_door_rr2", LANDING_GEAR_DOOR_RR2},
|
|
{"gear_door_rml", LANDING_GEAR_DOOR_RML},
|
|
{"gear_door_rmr", LANDING_GEAR_DOOR_RMR},
|
|
{"gear_f", LANDING_GEAR_F},
|
|
{"gear_rl", LANDING_GEAR_RL},
|
|
{"gear_lm1", LANDING_GEAR_LM1},
|
|
{"gear_rr", LANDING_GEAR_RR},
|
|
{"gear_rm1", LANDING_GEAR_RM1},
|
|
{"gear_rm", LANDING_GEAR_RM},
|
|
{0,0}
|
|
};
|
|
|
|
static ObjectNameIdAssociation subIds[SUB_NUM_OVERRIDDEN_NODES + 1] =
|
|
{
|
|
{"prop_1", SUB_PROPELLER_1},
|
|
{"prop_2", SUB_PROPELLER_2},
|
|
{"prop_3", SUB_PROPELLER_3},
|
|
{"prop_4", SUB_PROPELLER_4},
|
|
{"prop_left", SUB_PROPELLER_LEFT},
|
|
{"prop_right", SUB_PROPELLER_RIGHT},
|
|
{"rudder", SUB_RUDDER},
|
|
{"rudder2", SUB_RUDDER2},
|
|
{"elevator_l", SUB_ELEVATOR_L},
|
|
{"elevator_r", SUB_ELEVATOR_R},
|
|
{0,0}
|
|
};
|
|
|
|
static ObjectNameIdAssociation trailerIds[TRAILER_NUM_OVERRIDDEN_NODES +1] =
|
|
{
|
|
{"legs", TRAILER_LEGS},
|
|
{"attach_male", TRAILER_ATTACH},
|
|
{0, 0}
|
|
};
|
|
|
|
static ObjectNameIdAssociation draftVehIds[DRAFTVEH_NUM_OVERRIDDEN_NODES +1] =
|
|
{
|
|
{"draft_animal_attach_lr", DRAFTVEH_ANIMAL_ATTACH_LR},
|
|
{"draft_animal_attach_rr", DRAFTVEH_ANIMAL_ATTACH_RR},
|
|
{"draft_animal_attach_lm", DRAFTVEH_ANIMAL_ATTACH_LM},
|
|
{"draft_animal_attach_rm", DRAFTVEH_ANIMAL_ATTACH_RM},
|
|
{"draft_animal_attach_lf", DRAFTVEH_ANIMAL_ATTACH_LF},
|
|
{"draft_animal_attach_rf", DRAFTVEH_ANIMAL_ATTACH_RF},
|
|
{0, 0}
|
|
};
|
|
|
|
static ObjectNameIdAssociation submarineCarIds[SUBMARINECAR_NUM_OVERRIDDEN_NODES +1] =
|
|
{
|
|
{"static_prop", SUBMARINECAR_PROPELLER_1},
|
|
{"static_prop2", SUBMARINECAR_PROPELLER_2},
|
|
{"rudder", SUBMARINECAR_RUDDER_1},
|
|
{"rudder2", SUBMARINECAR_RUDDER_2},
|
|
{"elevator_l", SUBMARINECAR_ELEVATOR_L},
|
|
{"elevator_r", SUBMARINECAR_ELEVATOR_R},
|
|
{"wheelcover_l", SUBMARINECAR_WHEELCOVER_L},
|
|
{"wheelcover_r", SUBMARINECAR_WHEELCOVER_R},
|
|
{"fin_mount", SUBMARINECAR_FIN_MOUNT},
|
|
{"dplane_l", SUBMARINECAR_DRIVE_PLANE_L},
|
|
{"dplane_r", SUBMARINECAR_DRIVE_PLANE_R},
|
|
{0,0}
|
|
};
|
|
|
|
static ObjectNameIdAssociation amphibiousAutomobileIds[AMPHIBIOUS_AUTOMOBILE_NUM_OVERRIDDEN_NODES +1] =
|
|
{
|
|
{"static_prop", AMPHIBIOUS_AUTOMOBILE_STATIC_PROP},
|
|
{"moving_prop", AMPHIBIOUS_AUTOMOBILE_MOVING_PROP},
|
|
{"static_prop2", AMPHIBIOUS_AUTOMOBILE_STATIC_PROP2},
|
|
{"moving_prop2", AMPHIBIOUS_AUTOMOBILE_MOVING_PROP2},
|
|
{"rudder", AMPHIBIOUS_AUTOMOBILE_RUDDER},
|
|
{"rudder2", AMPHIBIOUS_AUTOMOBILE_RUDDER2},
|
|
{0,0}
|
|
};
|
|
|
|
static ObjectNameIdAssociation amphibiousQuadIds[AMPHIBIOUS_QUAD_NUM_OVERRIDDEN_NODES +1] =
|
|
{
|
|
{"handlebars", QUADBIKE_HANDLEBARS},
|
|
{"static_prop", AMPHIBIOUS_AUTOMOBILE_STATIC_PROP},
|
|
{0,0}
|
|
};
|
|
|
|
|
|
// --- Static class members -----------------------------------------------------
|
|
ObjectNameIdAssociation* CVehicleFactory::pBmxModelOverrideDesc = bmxIds;
|
|
|
|
ObjectNameIdAssociation* CVehicleFactory::ms_modelDesc[VEHICLE_TYPE_NUM] =
|
|
{
|
|
CVehicleFactory::pVehModelDesc,
|
|
CVehicleFactory::pPlaneModelOverrideDesc,
|
|
CVehicleFactory::pTrailerModelOverrideDesc,
|
|
CVehicleFactory::pQuadBikeModelOverrideDesc,
|
|
CVehicleFactory::pDraftVehModelOverrideDesc,
|
|
CVehicleFactory::pSubmarineCarModelOverrideDesc,
|
|
CVehicleFactory::pAmphibiousAutomobileModelOverrideDesc,
|
|
CVehicleFactory::pAmphibiousQuadModelOverrideDesc,
|
|
CVehicleFactory::pHeliModelOverrideDesc,
|
|
CVehicleFactory::pBlimpModelOverrideDesc,
|
|
CVehicleFactory::pHeliModelOverrideDesc,
|
|
CVehicleFactory::pBikeModelOverrideDesc,
|
|
CVehicleFactory::pBmxModelOverrideDesc,
|
|
CVehicleFactory::pBoatModelOverrideDesc,
|
|
CVehicleFactory::pTrainModelOverrideDesc,
|
|
CVehicleFactory::pSubModelOverrideDesc,
|
|
};
|
|
|
|
u16* CVehicleFactory::ms_modelDescHashes[VEHICLE_TYPE_NUM] =
|
|
{
|
|
CVehicleFactory::pVehModelDescHashes,
|
|
CVehicleFactory::pPlaneModelOverrideDescHashes,
|
|
CVehicleFactory::pTrailerModelOverrideDescHashes,
|
|
CVehicleFactory::pQuadBikeModelOverrideDescHashes,
|
|
CVehicleFactory::pDraftVehModelOverrideDescHashes,
|
|
CVehicleFactory::pSubmarineCarModelOverrideDescHashes,
|
|
CVehicleFactory::pAmphibiousAutomobileModelOverrideDescHashes,
|
|
CVehicleFactory::pAmphibiousQuadModelOverrideDescHashes,
|
|
CVehicleFactory::pHeliModelOverrideDescHashes,
|
|
CVehicleFactory::pBlimpModelOverrideDescHashes,
|
|
CVehicleFactory::pHeliModelOverrideDescHashes,
|
|
CVehicleFactory::pBikeModelOverrideDescHashes,
|
|
CVehicleFactory::pBmxModelOverrideDescHashes,
|
|
CVehicleFactory::pBoatModelOverrideDescHashes,
|
|
CVehicleFactory::pTrainModelOverrideDescHashes,
|
|
CVehicleFactory::pSubModelOverrideDescHashes
|
|
};
|
|
|
|
// +1 for the all option
|
|
#define BANK_VEHICLE_TYPES (VEHICLE_TYPE_NUM+1)
|
|
#define BANK_VEHICLE_TYPE_ALL (VEHICLE_TYPE_NUM)
|
|
|
|
const char* CVehicleFactory::ms_modelTypes[] =
|
|
{
|
|
"Vehicle",
|
|
"Plane",
|
|
"Trailer",
|
|
"QuadBike",
|
|
"Draft",
|
|
"Submarine Car",
|
|
"Amphibious Automobile",
|
|
"Amphibious QuadBike",
|
|
"Heli",
|
|
"Blimp",
|
|
"AutoGyro",
|
|
"Bike",
|
|
"Bmx",
|
|
"Boat",
|
|
"Train",
|
|
"Sub",
|
|
"All"
|
|
};
|
|
|
|
#define BANK_VEHICLE_SWANK (SWANKNESS_MAX+1)
|
|
#define BANK_VEHICLE_SWANK_ALL (SWANKNESS_MAX)
|
|
|
|
const char* CVehicleFactory::ms_swankTypes[BANK_VEHICLE_SWANK] =
|
|
{
|
|
"Crap",
|
|
"Nice crap",
|
|
"Meh",
|
|
"Decent",
|
|
"Nice",
|
|
"Super nice",
|
|
"All"
|
|
};
|
|
|
|
#define BANK_VEHICLE_CLASS (VC_MAX + 1)
|
|
#define BANK_VEHICLE_CLASS_ALL (VC_MAX)
|
|
const char* CVehicleFactory::ms_classTypes[ BANK_VEHICLE_CLASS ] =
|
|
{
|
|
"COMPACT",
|
|
"SEDAN",
|
|
"SUV",
|
|
"COUPE",
|
|
"MUSCLE",
|
|
"SPORT_CLASSIC",
|
|
"SPORT",
|
|
"SUPER",
|
|
"MOTORCYCLE",
|
|
"OFF_ROAD",
|
|
"INDUSTRIAL",
|
|
"UTILITY",
|
|
"VAN",
|
|
"CYCLE",
|
|
"BOAT",
|
|
"HELICOPTER",
|
|
"PLANE",
|
|
"SERVICE",
|
|
"EMERGENCY",
|
|
"MILITARY",
|
|
"COMMERCIAL",
|
|
"RAIL",
|
|
"OPEN WHEEL",
|
|
"ALL"
|
|
};
|
|
|
|
CompileTimeAssert(VEHICLE_TYPE_NUM == (sizeof(CVehicleFactory::ms_modelDesc)/sizeof(ObjectNameIdAssociation*))); // If this fails someone has added a new vehicle type. Check array above!
|
|
CompileTimeAssert(VEHICLE_TYPE_NUM == (sizeof(CVehicleFactory::ms_modelDescHashes)/sizeof(u16*))); // If this fails someone has added a new vehicle type. Check array above!
|
|
CompileTimeAssert(BANK_VEHICLE_TYPES == (sizeof(CVehicleFactory::ms_modelTypes)/sizeof(const char*))); // If this fails someone has added a new vehicle type. Check array above!
|
|
|
|
CVehicleFactory* CVehicleFactory::sm_pInstance = NULL;
|
|
|
|
ObjectNameIdAssociation* CVehicleFactory::pVehModelDesc = carIds;
|
|
ObjectNameIdAssociation* CVehicleFactory::pQuadBikeModelOverrideDesc = quadBikeIds;
|
|
ObjectNameIdAssociation* CVehicleFactory::pBikeModelOverrideDesc = bikeIds;
|
|
ObjectNameIdAssociation* CVehicleFactory::pBoatModelOverrideDesc = boatIds;
|
|
ObjectNameIdAssociation* CVehicleFactory::pTrainModelOverrideDesc = trainIds;
|
|
ObjectNameIdAssociation* CVehicleFactory::pHeliModelOverrideDesc = heliIds;
|
|
ObjectNameIdAssociation* CVehicleFactory::pBlimpModelOverrideDesc = blimpIds;
|
|
ObjectNameIdAssociation* CVehicleFactory::pPlaneModelOverrideDesc = planeIds;
|
|
ObjectNameIdAssociation* CVehicleFactory::pSubModelOverrideDesc = subIds;
|
|
ObjectNameIdAssociation* CVehicleFactory::pTrailerModelOverrideDesc = trailerIds;
|
|
ObjectNameIdAssociation* CVehicleFactory::pDraftVehModelOverrideDesc = draftVehIds;
|
|
ObjectNameIdAssociation* CVehicleFactory::pSubmarineCarModelOverrideDesc = submarineCarIds;
|
|
ObjectNameIdAssociation* CVehicleFactory::pAmphibiousAutomobileModelOverrideDesc = amphibiousAutomobileIds;
|
|
ObjectNameIdAssociation* CVehicleFactory::pAmphibiousQuadModelOverrideDesc = amphibiousQuadIds;
|
|
|
|
ObjectNameIdAssociation* CVehicleFactory::pLandingGearModelOverrideDesc = landingGearIds;
|
|
|
|
u16 CVehicleFactory::pVehModelDescHashes[VEH_NUM_NODES];
|
|
u16 CVehicleFactory::pQuadBikeModelOverrideDescHashes[QUADBIKE_NUM_OVERRIDDEN_NODES];
|
|
u16 CVehicleFactory::pBikeModelOverrideDescHashes[BIKE_NUM_OVERRIDDEN_NODES];
|
|
u16 CVehicleFactory::pBmxModelOverrideDescHashes[BMX_NUM_OVERRIDDEN_NODES];
|
|
u16 CVehicleFactory::pBoatModelOverrideDescHashes[BOAT_NUM_OVERRIDDEN_NODES];
|
|
u16 CVehicleFactory::pTrainModelOverrideDescHashes[TRAIN_NUM_OVERRIDDEN_NODES];
|
|
u16 CVehicleFactory::pHeliModelOverrideDescHashes[HELI_NUM_OVERRIDDEN_NODES];
|
|
u16 CVehicleFactory::pBlimpModelOverrideDescHashes[BLIMP_NUM_OVERRIDDEN_NODES];
|
|
u16 CVehicleFactory::pPlaneModelOverrideDescHashes[PLANE_NUM_OVERRIDDEN_NODES];
|
|
u16 CVehicleFactory::pSubModelOverrideDescHashes[SUB_NUM_OVERRIDDEN_NODES];
|
|
u16 CVehicleFactory::pTrailerModelOverrideDescHashes[TRAILER_NUM_OVERRIDDEN_NODES];
|
|
u16 CVehicleFactory::pDraftVehModelOverrideDescHashes[DRAFTVEH_NUM_OVERRIDDEN_NODES];
|
|
u16 CVehicleFactory::pSubmarineCarModelOverrideDescHashes[SUBMARINECAR_NUM_OVERRIDDEN_NODES];
|
|
u16 CVehicleFactory::pAmphibiousAutomobileModelOverrideDescHashes[AMPHIBIOUS_AUTOMOBILE_NUM_OVERRIDDEN_NODES];
|
|
u16 CVehicleFactory::pAmphibiousQuadModelOverrideDescHashes[AMPHIBIOUS_QUAD_NUM_OVERRIDDEN_NODES];
|
|
u16 CVehicleFactory::pLandingGearModelOverrideDescHashes[LANDING_GEAR_NUM_OVERRIDDEN_NODES];
|
|
|
|
|
|
CVehicleFactory::sDestroyedVeh CVehicleFactory::ms_reuseDestroyedVehArray[MAX_DESTROYED_VEHS_CACHED];
|
|
bool CVehicleFactory::ms_reuseDestroyedVehs = true; // when destroying vehicles we cache them for a while and reuse them when the same type is spawned again
|
|
u32 CVehicleFactory::ms_reuseDestroyedVehCacheTime = 10000; // time in ms how long we should keep cached vehicles around
|
|
u32 CVehicleFactory::ms_reuseDestroyedVehCount = 0; // keep track of how many vehicles we have cached
|
|
|
|
bool CVehicleFactory::ms_bFarDrawVehicles = false;
|
|
u8 CVehicleFactory::ms_uCurrentBoatTrailersWithoutBoats = 0;
|
|
u8 CVehicleFactory::ms_uCurrentBoatTrailersWithBoats = 0;
|
|
|
|
|
|
// --- Debug stuff? ----
|
|
#if __BANK
|
|
bool CVehicleFactory::ms_reuseDestroyedVehsDebugOutput = false;
|
|
bool CVehicleFactory::ms_rearDoorsCanOpen = false;
|
|
|
|
// vehicle combo box variables
|
|
|
|
s32 CVehicleFactory::numDLCNames = 0;
|
|
bkCombo* CVehicleFactory::pLayoutCombo = NULL;
|
|
bkCombo* CVehicleFactory::pDLCCombo = NULL;
|
|
atArray<const char*> CVehicleFactory::emptyNames;
|
|
s32 CVehicleFactory::currVehicleNameSelection = 0;
|
|
s32 CVehicleFactory::currVehicleTypeSelection = BANK_VEHICLE_TYPE_ALL;
|
|
s32 CVehicleFactory::currVehicleLayoutSelection = 0;
|
|
s32 CVehicleFactory::currVehicleDLCSelection = 0;
|
|
s32 CVehicleFactory::currVehicleSwankSelection = BANK_VEHICLE_SWANK_ALL;
|
|
s32 CVehicleFactory::currVehicleClassSelection = BANK_VEHICLE_CLASS_ALL;
|
|
s32 CVehicleFactory::currVehicleTrailerNameSelection = 0;
|
|
atArray<const char*> CVehicleFactory::vehicleNames;
|
|
|
|
static s32* vehicleSorts;
|
|
static u32 numVehicleNames;
|
|
static s32* vehicleTrailerSorts;
|
|
static u32 numVehicleTrailerNames;
|
|
static bkBank* pBank = NULL;
|
|
static bkButton* pCreateBankButton = NULL;
|
|
static bkCombo* pVehicleCombo = NULL;
|
|
static bkCombo* pVehicleTrailerCombo = NULL;
|
|
static bool bNeedToUpdateVehicleList = false; //Do we need to update the vehicle list?
|
|
static bool bVehicleNeedsToBeHotwired = false;
|
|
static bool bVehicleInstantStartEngineOnWarp = true;
|
|
static bool bCreateAsMissionCar = false;
|
|
static bool bCreateAsPersonalCar = false;
|
|
static bool bCreateAsGangCar = false;
|
|
static bool bPlaceOnRoadProperly = false;
|
|
static bool bLockDoors = false;
|
|
static int nForceExtraOn = 0;
|
|
static bool bBulletProof = false;
|
|
static bool bFireProof = false;
|
|
static bool bCollisionProof = false;
|
|
static bool bMeleeProof = false;
|
|
static bool bExplosionProof = false;
|
|
|
|
#define CAR_NAME_LENGTH (16)
|
|
static s32 numCarsAvailable = 0;
|
|
u32 CVehicleFactory::carModelId = fwModelId::MI_INVALID;
|
|
u32 CVehicleFactory::trailerModelId = fwModelId::MI_INVALID;
|
|
//static s32 carModelNum = 0;
|
|
static float carDropHeight = 5.0f;
|
|
static float carTestHeight = -1.5f;
|
|
static float carDropRotation = 0.0f;
|
|
static bool bUseDebugCamRotation = true;
|
|
static s32 carSoundHornTime = 0;
|
|
|
|
static bool bLowerOrRaiseRoofInstantly = false;
|
|
static bool bDoorCanBeReset = false;
|
|
|
|
static bool sbCheatAbs = false;
|
|
static bool sbCheatTractionControl = false;
|
|
static bool sbCheatStabilityControl = false;
|
|
static bool sbCheatGrip1 = false;
|
|
static bool sbCheatGrip2 = false;
|
|
static bool sbCheatPower1 = false;
|
|
static bool sbCheatPower2 = false;
|
|
static float sfTopSpeedAdjustment = 0.0f;
|
|
#if __DEV
|
|
static float sfPetrolTankLevel = 65.0f;
|
|
#endif
|
|
float gfPlayerCarInvMassScale = 1.8f;
|
|
|
|
RegdVeh CVehicleFactory::ms_pLastCreatedVehicle(NULL);
|
|
RegdVeh CVehicleFactory::ms_pLastLastCreatedVehicle(NULL);
|
|
bool CVehicleFactory::ms_bFireCarForcePos = false;
|
|
bool CVehicleFactory::ms_bDisplayVehicleNames = false;
|
|
bool CVehicleFactory::ms_bDisplayVehicleLayout = false;
|
|
bool CVehicleFactory::ms_bDisplayCreateLocation = false;
|
|
bool CVehicleFactory::ms_bRegenerateFireVehicle = true;
|
|
bool CVehicleFactory::ms_bDisplayTyreWearRate = false;
|
|
bool CVehicleFactory::ms_bDisplaySteerAngle = false;
|
|
bool CVehicleFactory::ms_bPlayAnimPhysical = false;
|
|
bool CVehicleFactory::ms_bSpawnTrailers = true;
|
|
bool CVehicleFactory::ms_bForceHd = false;
|
|
float CVehicleFactory::ms_fLodMult = 1.f;
|
|
s8 CVehicleFactory::ms_clampedRenderLod = -1;
|
|
bool CVehicleFactory::ms_bflyingAce = false;
|
|
s32 CVehicleFactory::ms_iSeatToEnter = 0;
|
|
s32 CVehicleFactory::ms_iDoorToOpen = 0;
|
|
s32 CVehicleFactory::ms_iTyreNumber = 0;
|
|
s32 CVehicleFactory::ms_variationDebugColor = 0;
|
|
s32 CVehicleFactory::ms_variationDebugWindowTint = -1;
|
|
bool CVehicleFactory::ms_variationAllExtras = false;
|
|
bool CVehicleFactory::ms_variationDebugDraw = false;
|
|
bool CVehicleFactory::ms_variationExtras[VEH_LAST_EXTRA - VEH_EXTRA_1 + 1] = {false};
|
|
bkSlider* CVehicleFactory::ms_variationColorSlider = NULL;
|
|
bkSlider* CVehicleFactory::ms_variationWindowTintSlider = NULL;
|
|
float CVehicleFactory::ms_fSetEngineNewHealth = ENGINE_HEALTH_MAX;
|
|
|
|
// mods
|
|
s32 CVehicleFactory::ms_variationMod[] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1 };
|
|
|
|
bkSlider* CVehicleFactory::ms_variationSliders[] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
|
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
|
|
|
|
|
|
|
|
//s32 CVehicleFactory::ms_variationSpoilerMod = -1;
|
|
//s32 CVehicleFactory::ms_variationBumperFMod = -1;
|
|
//s32 CVehicleFactory::ms_variationBumperRMod = -1;
|
|
//s32 CVehicleFactory::ms_variationSkirtMod = -1;
|
|
//s32 CVehicleFactory::ms_variationExhaustMod = -1;
|
|
//s32 CVehicleFactory::ms_variationChassisMod = -1;
|
|
//s32 CVehicleFactory::ms_variationGrillMod = -1;
|
|
//s32 CVehicleFactory::ms_variationBonnetMod = -1;
|
|
//s32 CVehicleFactory::ms_variationWingLMod = -1;
|
|
//s32 CVehicleFactory::ms_variationWingRMod = -1;
|
|
//s32 CVehicleFactory::ms_variationRoofMod = -1;
|
|
//s32 CVehicleFactory::ms_variationEngineMod = -1;
|
|
//s32 CVehicleFactory::ms_variationBrakesMod = -1;
|
|
//s32 CVehicleFactory::ms_variationGearboxMod = -1;
|
|
//s32 CVehicleFactory::ms_variationHornMod = -1;
|
|
//s32 CVehicleFactory::ms_variationSuspensionMod = -1;
|
|
//s32 CVehicleFactory::ms_variationArmourMod = -1;
|
|
//s32 CVehicleFactory::ms_variationWheelMod = -1;
|
|
//s32 CVehicleFactory::ms_variationRearWheelMod = -1;
|
|
//s32 CVehicleFactory::ms_variationLiveryMod = -1;
|
|
//bkSlider* CVehicleFactory::ms_variationSpoilerSlider = NULL;
|
|
//bkSlider* CVehicleFactory::ms_variationBumperFSlider = NULL;
|
|
//bkSlider* CVehicleFactory::ms_variationBumperRSlider = NULL;
|
|
//bkSlider* CVehicleFactory::ms_variationSkirtSlider = NULL;
|
|
//bkSlider* CVehicleFactory::ms_variationExhaustSlider = NULL;
|
|
//bkSlider* CVehicleFactory::ms_variationChassisSlider = NULL;
|
|
//bkSlider* CVehicleFactory::ms_variationGrillSlider = NULL;
|
|
//bkSlider* CVehicleFactory::ms_variationBonnetSlider = NULL;
|
|
//bkSlider* CVehicleFactory::ms_variationWingLSlider = NULL;
|
|
//bkSlider* CVehicleFactory::ms_variationWingRSlider = NULL;
|
|
//bkSlider* CVehicleFactory::ms_variationRoofSlider = NULL;
|
|
//bkSlider* CVehicleFactory::ms_variationEngineSlider = NULL;
|
|
//bkSlider* CVehicleFactory::ms_variationBrakesSlider = NULL;
|
|
//bkSlider* CVehicleFactory::ms_variationGearboxSlider = NULL;
|
|
//bkSlider* CVehicleFactory::ms_variationHornSlider = NULL;
|
|
//bkSlider* CVehicleFactory::ms_variationSuspensionSlider = NULL;
|
|
//bkSlider* CVehicleFactory::ms_variationArmourSlider = NULL;
|
|
//bkSlider* CVehicleFactory::ms_variationWheelSlider = NULL;
|
|
//bkSlider* CVehicleFactory::ms_variationRearWheelSlider = NULL;
|
|
//bkSlider* CVehicleFactory::ms_variationLiveryModSlider = NULL;
|
|
|
|
bkSlider* CVehicleFactory::ms_liverySlider = NULL;
|
|
bkSlider* CVehicleFactory::ms_livery2Slider = NULL;
|
|
s32 CVehicleFactory::ms_currentLivery = -1;
|
|
s32 CVehicleFactory::ms_currentLivery2 = -1;
|
|
float CVehicleFactory::ms_vehicleLODScaling = 1.0f;
|
|
float CVehicleFactory::ms_vehicleHiStreamScaling = 1.0f;
|
|
bool CVehicleFactory::ms_bShowVehicleLODLevelData = false;
|
|
bool CVehicleFactory::ms_bShowVehicleLODLevel = false;
|
|
bool CVehicleFactory::ms_variationRenderMods = true;
|
|
bool CVehicleFactory::ms_variationRandomMods = true;
|
|
|
|
u32 CVehicleFactory::ms_numCachedCarsCreated = 0;
|
|
u32 CVehicleFactory::ms_numNonCachedCarsCreated = 0;
|
|
bool CVehicleFactory::ms_resetCacheStats = false;
|
|
|
|
bool CVehicleFactory::ms_bLogCreatedVehicles = false;
|
|
bool CVehicleFactory::ms_bLogDestroyedVehicles = false;
|
|
u32 CVehicleFactory::ms_iDestroyedVehicleCount = 0;
|
|
bool CVehicleFactory::ms_bForceDials = false;
|
|
|
|
|
|
static Vector3 sFireCarPos(VEC3_ZERO);
|
|
static Vector3 sFireCarDirn(1.0f, 0.0f, 0.0f);
|
|
static Vector3 sFireCarOrient(VEC3_ZERO);
|
|
static Vector3 sFireObjectOffset(0.0f, 10.0f, 0.0f);
|
|
static float sFireCarVel = 5.0f;
|
|
static Vector3 svFireCarSpin(VEC3_ZERO);
|
|
|
|
static Vector3 sRoofImpulse(VEC3_ZERO);
|
|
static float sDoorOpenAmount = 1.0f;
|
|
|
|
static bool sSpawnCarsOnTrailer = true;
|
|
static bool sSpawnCarsWithNoBreaking = false;
|
|
|
|
CVehicle *CVehicleFactory::GetCreatedVehicle()
|
|
{
|
|
return (CVehicleFactory::ms_pLastCreatedVehicle);
|
|
}
|
|
CVehicle *CVehicleFactory::GetPreviouslyCreatedVehicle()
|
|
{
|
|
return (CVehicleFactory::ms_pLastLastCreatedVehicle);
|
|
}
|
|
#endif // __BANK
|
|
|
|
|
|
// --- Code ---------------------------------------------------------------------
|
|
|
|
//
|
|
// name: CVehicleFactory::CVehicleFactory
|
|
// description: Constructor
|
|
CVehicleFactory::CVehicleFactory()
|
|
{
|
|
#if (__XENON || __PS3)
|
|
#define VEHICLE_HEAP_SIZE (464 << 10)
|
|
#else
|
|
#define VEHICLE_HEAP_SIZE ((464 << 10) * 10)
|
|
#endif
|
|
|
|
sysMemStartFlex();
|
|
CVehicle::InitPool(VEHICLE_HEAP_SIZE, VEHICLE_POOL_SIZE, MEMBUCKET_GAMEPLAY);
|
|
sysMemEndFlex();
|
|
|
|
#if __DEV
|
|
CVehicle::GetPool()->RegisterPoolCallback(CVehicle::PoolFullCallback);
|
|
#endif // __DEV
|
|
|
|
CWheel::InitPool( MEMBUCKET_GAMEPLAY );
|
|
|
|
#if (__XENON || __PS3)
|
|
#define VEHICLE_AUDIO_HEAP_SIZE (488 << 10)
|
|
#else
|
|
#define VEHICLE_AUDIO_HEAP_SIZE ((488 << 10) * 10)
|
|
#endif
|
|
|
|
audVehicleAudioEntity::InitPool(VEHICLE_AUDIO_HEAP_SIZE, VEHICLE_POOL_SIZE, MEMBUCKET_AUDIO);
|
|
|
|
BANK_ONLY(CWheel::ms_bUseWheelIntegrationTask = !PARAM_disablewheelintegrationtask.Get();)
|
|
|
|
CAircraftDamage::DamageFlame::InitPool( MEMBUCKET_GAMEPLAY );
|
|
|
|
for (s32 i = 0; i < VEH_NUM_NODES; ++i)
|
|
if (pVehModelDesc[i].pName)
|
|
pVehModelDescHashes[i] = atHash16U(pVehModelDesc[i].pName);
|
|
for (s32 i = 0; i < QUADBIKE_NUM_OVERRIDDEN_NODES; ++i)
|
|
if (pQuadBikeModelOverrideDesc[i].pName)
|
|
pQuadBikeModelOverrideDescHashes[i] = atHash16U(pQuadBikeModelOverrideDesc[i].pName);
|
|
for (s32 i = 0; i < BIKE_NUM_OVERRIDDEN_NODES; ++i)
|
|
if (pBikeModelOverrideDesc[i].pName)
|
|
pBikeModelOverrideDescHashes[i] = atHash16U(pBikeModelOverrideDesc[i].pName);
|
|
for (s32 i = 0; i < BMX_NUM_OVERRIDDEN_NODES; ++i)
|
|
if (pBmxModelOverrideDesc[i].pName)
|
|
pBmxModelOverrideDescHashes[i] = atHash16U(pBmxModelOverrideDesc[i].pName);
|
|
for (s32 i = 0; i < BOAT_NUM_OVERRIDDEN_NODES; ++i)
|
|
if (pBoatModelOverrideDesc[i].pName)
|
|
pBoatModelOverrideDescHashes[i] = atHash16U(pBoatModelOverrideDesc[i].pName);
|
|
for (s32 i = 0; i < TRAIN_NUM_OVERRIDDEN_NODES; ++i)
|
|
if (pTrainModelOverrideDesc[i].pName)
|
|
pTrainModelOverrideDescHashes[i] = atHash16U(pTrainModelOverrideDesc[i].pName);
|
|
for (s32 i = 0; i < HELI_NUM_OVERRIDDEN_NODES; ++i)
|
|
if (pHeliModelOverrideDesc[i].pName)
|
|
pHeliModelOverrideDescHashes[i] = atHash16U(pHeliModelOverrideDesc[i].pName);
|
|
for (s32 i = 0; i < BLIMP_NUM_OVERRIDDEN_NODES; ++i)
|
|
if (pBlimpModelOverrideDesc[i].pName)
|
|
pBlimpModelOverrideDescHashes[i] = atHash16U(pBlimpModelOverrideDesc[i].pName);
|
|
for (s32 i = 0; i < PLANE_NUM_OVERRIDDEN_NODES; ++i)
|
|
if (pPlaneModelOverrideDesc[i].pName)
|
|
pPlaneModelOverrideDescHashes[i] = atHash16U(pPlaneModelOverrideDesc[i].pName);
|
|
for (s32 i = 0; i < SUB_NUM_OVERRIDDEN_NODES; ++i)
|
|
if (pSubModelOverrideDesc[i].pName)
|
|
pSubModelOverrideDescHashes[i] = atHash16U(pSubModelOverrideDesc[i].pName);
|
|
for (s32 i = 0; i < TRAILER_NUM_OVERRIDDEN_NODES; ++i)
|
|
if (pTrailerModelOverrideDesc[i].pName)
|
|
pTrailerModelOverrideDescHashes[i] = atHash16U(pTrailerModelOverrideDesc[i].pName);
|
|
for (s32 i = 0; i < DRAFTVEH_NUM_OVERRIDDEN_NODES; ++i)
|
|
if (pDraftVehModelOverrideDesc[i].pName)
|
|
pDraftVehModelOverrideDescHashes[i] = atHash16U(pDraftVehModelOverrideDesc[i].pName);
|
|
for (s32 i = 0; i < SUBMARINECAR_NUM_OVERRIDDEN_NODES; ++i)
|
|
if (pSubmarineCarModelOverrideDesc[i].pName)
|
|
pSubmarineCarModelOverrideDescHashes[i] = atHash16U(pSubmarineCarModelOverrideDesc[i].pName);
|
|
for (s32 i = 0; i < AMPHIBIOUS_AUTOMOBILE_NUM_OVERRIDDEN_NODES; ++i)
|
|
if (pAmphibiousAutomobileModelOverrideDesc[i].pName)
|
|
pAmphibiousAutomobileModelOverrideDescHashes[i] = atHash16U(pAmphibiousAutomobileModelOverrideDesc[i].pName);
|
|
for (s32 i = 0; i < AMPHIBIOUS_QUAD_NUM_OVERRIDDEN_NODES; ++i)
|
|
if (pAmphibiousQuadModelOverrideDesc[i].pName)
|
|
pAmphibiousQuadModelOverrideDescHashes[i] = atHash16U(pAmphibiousQuadModelOverrideDesc[i].pName);
|
|
for (s32 i = 0; i < LANDING_GEAR_NUM_OVERRIDDEN_NODES; ++i)
|
|
if (pLandingGearModelOverrideDesc[i].pName)
|
|
pLandingGearModelOverrideDescHashes[i] = atHash16U(pLandingGearModelOverrideDesc[i].pName);
|
|
}
|
|
|
|
//
|
|
// name: CVehicleFactory::~CVehicleFactory
|
|
// description: Destructor
|
|
CVehicleFactory::~CVehicleFactory()
|
|
{
|
|
CVehicle::ShutdownPool();
|
|
CWheel::ShutdownPool();
|
|
|
|
ClearDestroyedVehCache();
|
|
CAircraftDamage::DamageFlame::ShutdownPool();
|
|
#if __BANK
|
|
vehicleNames.Reset();
|
|
|
|
delete []vehicleSorts;
|
|
delete []vehicleTrailerSorts;
|
|
vehicleSorts = vehicleTrailerSorts = NULL;
|
|
#endif //__BANK
|
|
}
|
|
|
|
|
|
void CVehicleFactory::CreateFactory()
|
|
{
|
|
Assert(sm_pInstance == NULL);
|
|
sm_pInstance = rage_new CVehicleFactory;
|
|
}
|
|
|
|
void CVehicleFactory::DestroyFactory()
|
|
{
|
|
Assert(sm_pInstance);
|
|
|
|
delete sm_pInstance;
|
|
sm_pInstance = NULL;
|
|
}
|
|
|
|
|
|
//
|
|
// name: CVehicleFactory::Create
|
|
// description: Default factory create function. Individual projects can override this
|
|
// parameters: vehicleType
|
|
// modelIndex
|
|
// created
|
|
CVehicle* CVehicleFactory::Create(fwModelId modelId, const eEntityOwnedBy ownedBy, const u32 popType, const Matrix34 *pMat, bool bClone, bool bCreateAsInactive)
|
|
{
|
|
PF_AUTO_PUSH_TIMEBAR("Vehicle Create");
|
|
CVehicle* pReturnVehicle = NULL;
|
|
CVehicleModelInfo* pModelInfo = ((CVehicleModelInfo* )CModelInfo::GetBaseModelInfo(modelId));
|
|
Assert(pModelInfo);
|
|
Assert(pModelInfo->GetModelType()==MI_TYPE_VEHICLE);
|
|
|
|
if(pModelInfo==NULL)
|
|
{
|
|
Warningf("CVehicleFactory::Create pModelInfo==NULL --> return NULL");
|
|
return NULL;
|
|
}
|
|
|
|
#if __BANK
|
|
if (pModelInfo->GetVehicleType() == VEHICLE_TYPE_TRAILER && !ms_bSpawnTrailers)
|
|
{
|
|
Warningf("CVehicleFactory::Create pModelInfo->GetVehicleType() == VEHICLE_TYPE_TRAILER && !ms_bSpawnTrailers --> return NULL");
|
|
return NULL;
|
|
}
|
|
#endif
|
|
|
|
if(!FRAGCACHEMGR->CanGetNewCacheEntries(1))
|
|
{
|
|
Warningf("CVehicleFactory::Create FRAGCACHEMGR->CanGetNewCacheEntries(1) == false --> return NULL");
|
|
return NULL;
|
|
}
|
|
|
|
bool wasCached = false;
|
|
#if 0
|
|
if (ownedBy != ENTITY_OWNEDBY_SCRIPT)
|
|
pReturnVehicle = CreateVehFromDestroyedCache(modelId, ownedBy, popType, pMat, bCreateAsInactive);
|
|
#endif
|
|
|
|
if (!pReturnVehicle)
|
|
{
|
|
pReturnVehicle = CreateVehicle(pModelInfo->GetVehicleType(), ownedBy, popType);
|
|
|
|
Assert(pReturnVehicle && !pReturnVehicle->GetIsRetainedByInteriorProxy());
|
|
Assert(pReturnVehicle && pReturnVehicle->GetOwnerEntityContainer() == NULL);
|
|
|
|
if(pReturnVehicle==NULL)
|
|
{
|
|
Warningf("CVehicleFactory::Create pReturnVehicle==NULL --> return NULL");
|
|
return NULL;
|
|
}
|
|
|
|
CVehiclePopulation::IncrementNumVehiclesCreatedThisCycle();
|
|
|
|
pReturnVehicle->m_nVehicleFlags.bCreatedByFactory = true;
|
|
|
|
if(pMat)
|
|
{
|
|
pReturnVehicle->SetMatrix(*pMat);
|
|
#if DEBUG_DRAW
|
|
pReturnVehicle->m_vCreatedPos = RCC_VEC3V(pMat->d);
|
|
pReturnVehicle->m_vCreatedDir = RCC_VEC3V(pMat->b);
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
Matrix34 identity(Matrix34::IdentityType);
|
|
pReturnVehicle->SetMatrix(identity);
|
|
}
|
|
|
|
// SetModelId will try to activate unless this is set.
|
|
pReturnVehicle->m_nVehicleFlags.bCreatingAsInactive = bCreateAsInactive;
|
|
|
|
// call SetModelId() AFTER we init the matrix so that physics can be initialized properly
|
|
pReturnVehicle->SetModelId(modelId);
|
|
|
|
SetFarDraw(pReturnVehicle);
|
|
|
|
BANK_ONLY(ms_numNonCachedCarsCreated++;)
|
|
}
|
|
else
|
|
{
|
|
wasCached = true;
|
|
BANK_ONLY(ms_numCachedCarsCreated++;)
|
|
}
|
|
|
|
if (pModelInfo && pModelInfo->GetVehicleType() == VEHICLE_TYPE_TRAILER && pModelInfo->GetVehicleFlag(CVehicleModelInfoFlags::FLAG_SPAWN_BOAT_ON_TRAILER))
|
|
{
|
|
++ms_uCurrentBoatTrailersWithoutBoats;
|
|
boatTrailerDebugf3("Create: added trailer, ms_uCurrentBoatTrailersWithoutBoats = %u", ms_uCurrentBoatTrailersWithoutBoats);
|
|
#if !__NO_OUTPUT
|
|
if(ms_uCurrentBoatTrailersWithBoats > ms_uMaxBoatTrailersWithBoats)
|
|
{
|
|
boatTrailerWarningf("Too many trailers with boats (%u, max %u)", ms_uCurrentBoatTrailersWithBoats, ms_uMaxBoatTrailersWithBoats);
|
|
}
|
|
if(ms_uCurrentBoatTrailersWithoutBoats > (ms_uMaxBoatTrailersWithoutBoats + 1)) // Allow one extra, as it could turn into a trailer with a boat.
|
|
{
|
|
boatTrailerWarningf("Too many trailers without boats (%u, max %u + 1)", ms_uCurrentBoatTrailersWithoutBoats, ms_uMaxBoatTrailersWithoutBoats);
|
|
}
|
|
#endif // !__NO_OUTPUT
|
|
}
|
|
|
|
// Shouldn't already be in the spatial array at this point, regardless of whether they were created
|
|
// fresh or came from the cache.
|
|
Assert(!pReturnVehicle->GetSpatialArrayNode().IsInserted());
|
|
|
|
Assert(!pReturnVehicle->GetIsRetainedByInteriorProxy());
|
|
Assert(pReturnVehicle->GetOwnerEntityContainer() == NULL);
|
|
|
|
// ******* NETWORK REGISTRATION HAS TO BE DONE BEFORE ANY FURTHER STATE CHANGES ON THE VEHICLE! *******************
|
|
|
|
////////////////////
|
|
// THIS SHOULD REALLY BE SPLIT BETWEEN PROJECT SPECIFIC AND CORE VEHICLE TYPES IN THEIR RESPECTIVE VEHICLE FACTORIES
|
|
////////////////////
|
|
|
|
pReturnVehicle->m_nPhysicalFlags.bNotToBeNetworked = !bClone;
|
|
|
|
if (bClone && NetworkInterface::IsGameInProgress())
|
|
{
|
|
if(!RegisterVehicleToNetwork(pReturnVehicle, popType))
|
|
{
|
|
// vehicle could not be registered as there is no available network objects for it, so it has to be removed
|
|
// unless it is a mission object, which is queued to be registered later
|
|
Destroy(pReturnVehicle);
|
|
pReturnVehicle = NULL;
|
|
}
|
|
}
|
|
|
|
if (pReturnVehicle)
|
|
{
|
|
if (!wasCached)
|
|
AssignVehicleGadgets(pReturnVehicle);
|
|
|
|
// modify the vehicle dirt level based on the popzone values
|
|
float dirtMin = CPopCycle::GetCurrentZoneVehDirtMin();
|
|
float dirtMax = CPopCycle::GetCurrentZoneVehDirtMax();
|
|
Color32 dirtCol = CPopCycle::GetCurrentZoneDirtCol();
|
|
|
|
if (dirtMin >= 0.f && dirtMax >= 0.f)
|
|
{
|
|
u32 vehDirtMin = pModelInfo->GetDefaultDirtLevelMin();
|
|
u32 vehDirtMax = pModelInfo->GetDefaultDirtLevelMax();
|
|
u32 popDirtMin = (u32)(dirtMin * 15.f);
|
|
u32 popDirtMax = (u32)(dirtMax * 15.f);
|
|
float resDirt = (float)fwRandom::GetRandomNumberInRange((int)(vehDirtMin + popDirtMin) / 2, (int)(vehDirtMax + popDirtMax) / 2);
|
|
resDirt = Clamp(resDirt, 0.0f, 15.0f);
|
|
pReturnVehicle->SetBodyDirtLevel(resDirt);
|
|
}
|
|
|
|
if (dirtCol.GetColor() != 0)
|
|
{
|
|
// modify dirt tint based on weather modifier
|
|
float dirtWeatherMod = g_timeCycle.GetStaleDirtModifier();
|
|
Color32 col(dirtCol.GetRedf() * dirtWeatherMod, dirtCol.GetGreenf() * dirtWeatherMod, dirtCol.GetBluef() * dirtWeatherMod, dirtCol.GetAlphaf());
|
|
|
|
pReturnVehicle->SetBodyDirtColor(col);
|
|
}
|
|
|
|
// Make it snow
|
|
const u32 xmasWeather = g_weather.GetTypeIndex("XMAS");
|
|
const bool isXmasWeather = (g_weather.GetPrevTypeIndex() == xmasWeather) || (g_weather.GetNextTypeIndex() == xmasWeather);
|
|
if((CNetwork::IsGameInProgress() REPLAY_ONLY(|| CReplayMgr::AllowXmasSnow())) && isXmasWeather)
|
|
{
|
|
Color32 snowCol(240,240,240,255);
|
|
pReturnVehicle->SetBodyDirtColor(snowCol);
|
|
}
|
|
|
|
CSpatialArrayNode& spatialArrayNode = pReturnVehicle->GetSpatialArrayNode();
|
|
Assert(!spatialArrayNode.IsInserted());
|
|
CVehicle::GetSpatialArray().Insert(spatialArrayNode);
|
|
if(spatialArrayNode.IsInserted())
|
|
{
|
|
pReturnVehicle->UpdateInSpatialArray();
|
|
}
|
|
|
|
pReturnVehicle->m_vecInitialSpawnPosition = VECTOR3_TO_VEC3V(pMat->GetVector(3));
|
|
|
|
pReturnVehicle->UpdateBodyColourRemapping(false);
|
|
}
|
|
|
|
|
|
#if __BANK
|
|
if(ms_bLogCreatedVehicles && pReturnVehicle)
|
|
{
|
|
CViewport* gameViewport = gVpMan.GetGameViewport();
|
|
if(gameViewport)
|
|
{
|
|
static u32 iCount = 0;
|
|
char text[128];
|
|
|
|
const Vector3 vVehiclePos = VEC3V_TO_VECTOR3(pReturnVehicle->GetTransform().GetPosition());
|
|
const Vector3 vCameraPos = VEC3V_TO_VECTOR3(gameViewport->GetGrcViewport().GetCameraPosition());
|
|
const float fDist = (vCameraPos - vVehiclePos).Mag();
|
|
|
|
sprintf(text, "%i : %s", iCount, pReturnVehicle->GetModelName());
|
|
grcDebugDraw::Text(vVehiclePos, Color_green, 0, -grcDebugDraw::GetScreenSpaceTextHeight(), text, false, -(s32)(10.0f / fwTimer::GetTimeStep()));
|
|
grcDebugDraw::Sphere(vVehiclePos, 0.25f, Color_green4, false, -(s32)(10.0f / fwTimer::GetTimeStep()));
|
|
|
|
Displayf("**************************************************************************************************");
|
|
Displayf("CVehicleFactory::Create() : %i", iCount);
|
|
Displayf("NAME : %s, DISTANCE : %.1f, POSITION : %.1f, %.1f, %.1f, VEHICLE: 0x%p, RANGESCALE : %.1f", pReturnVehicle->GetModelName(), fDist, vVehiclePos.x, vVehiclePos.y, vVehiclePos.z, pReturnVehicle, CVehiclePopulation::GetPopulationRangeScale());
|
|
sysStack::PrintStackTrace();
|
|
Displayf("**************************************************************************************************");
|
|
|
|
iCount++;
|
|
}
|
|
}
|
|
#endif // __BANK
|
|
|
|
return pReturnVehicle;
|
|
}
|
|
|
|
|
|
bool CVehicleFactory::RegisterVehicleToNetwork(CVehicle* pReturnVehicle, const u32 popType)
|
|
{
|
|
bool bRegistered = false;
|
|
NetObjFlags globalFlags = (popType == POPTYPE_MISSION) ? CNetObjGame::GLOBALFLAG_SCRIPTOBJECT : 0;
|
|
|
|
switch (pReturnVehicle->GetVehicleType())
|
|
{
|
|
case VEHICLE_TYPE_CAR:
|
|
bRegistered = NetworkInterface::RegisterObject((CAutomobile*)pReturnVehicle, 0, globalFlags) ;
|
|
break;
|
|
case VEHICLE_TYPE_BIKE:
|
|
bRegistered = NetworkInterface::RegisterObject((CBike*)pReturnVehicle, 0, globalFlags);
|
|
break;
|
|
case VEHICLE_TYPE_QUADBIKE:
|
|
bRegistered = NetworkInterface::RegisterObject((CQuadBike*)pReturnVehicle, 0, globalFlags);
|
|
break;
|
|
case VEHICLE_TYPE_BICYCLE:
|
|
bRegistered = NetworkInterface::RegisterObject((CBmx*)pReturnVehicle, 0, globalFlags);
|
|
break;
|
|
case VEHICLE_TYPE_TRAIN:
|
|
bRegistered = NetworkInterface::RegisterObject((CTrain*)pReturnVehicle, 0, globalFlags, true);
|
|
break;
|
|
case VEHICLE_TYPE_BOAT:
|
|
bRegistered = NetworkInterface::RegisterObject((CBoat*)pReturnVehicle, 0, globalFlags);
|
|
break;
|
|
case VEHICLE_TYPE_HELI:
|
|
bRegistered = NetworkInterface::RegisterObject((CHeli*)pReturnVehicle, 0, globalFlags);
|
|
break;
|
|
case VEHICLE_TYPE_PLANE:
|
|
bRegistered = NetworkInterface::RegisterObject((CPlane*)pReturnVehicle, 0, globalFlags);
|
|
break;
|
|
case VEHICLE_TYPE_AUTOGYRO:
|
|
bRegistered = NetworkInterface::RegisterObject((CAutogyro*)pReturnVehicle, 0, globalFlags);
|
|
break;
|
|
case VEHICLE_TYPE_SUBMARINE:
|
|
bRegistered = NetworkInterface::RegisterObject((CSubmarine*)pReturnVehicle, 0, globalFlags);
|
|
break;
|
|
case VEHICLE_TYPE_TRAILER:
|
|
bRegistered = NetworkInterface::RegisterObject((CTrailer*)pReturnVehicle, 0, globalFlags);
|
|
break;
|
|
#if ENABLE_DRAFT_VEHICLE
|
|
case VEHICLE_TYPE_DRAFT:
|
|
bRegistered = NetworkInterface::RegisterObject((CDraftVeh*)pReturnVehicle, 0, globalFlags);
|
|
break;
|
|
#endif
|
|
case VEHICLE_TYPE_SUBMARINECAR:
|
|
bRegistered = NetworkInterface::RegisterObject((CSubmarineCar*)pReturnVehicle, 0, globalFlags);
|
|
break;
|
|
case VEHICLE_TYPE_AMPHIBIOUS_AUTOMOBILE:
|
|
bRegistered = NetworkInterface::RegisterObject((CAmphibiousAutomobile*)pReturnVehicle, 0, globalFlags);
|
|
break;
|
|
case VEHICLE_TYPE_AMPHIBIOUS_QUADBIKE:
|
|
bRegistered = NetworkInterface::RegisterObject((CAmphibiousQuadBike*)pReturnVehicle, 0, globalFlags);
|
|
break;
|
|
case VEHICLE_TYPE_BLIMP:
|
|
bRegistered = NetworkInterface::RegisterObject((CBlimp*)pReturnVehicle, 0, globalFlags);
|
|
break;
|
|
default:
|
|
Assert(0);
|
|
}
|
|
|
|
if (!bRegistered && !(popType == POPTYPE_MISSION || popType == POPTYPE_PERMANENT))
|
|
{
|
|
#if __ASSERT
|
|
Warningf("CVehicleFactory::Create !bRegistered && !(popType == POPTYPE_MISSION || popType == POPTYPE_PERMANENT) -- train[%d] --> Destroy and pReturnVehicle = NULL bRegistered[%d] popType[%d]",pReturnVehicle->GetVehicleType() == VEHICLE_TYPE_TRAIN,bRegistered,popType);
|
|
#if __BANK
|
|
Warningf("CVehicleFactory::Create Note: GetLastRegistrationFailureReason[%s]",NetworkInterface::GetLastRegistrationFailureReason());
|
|
|
|
int typecount = 0;
|
|
CVehicle::Pool* pool = CVehicle::GetPool();
|
|
s32 i = (s32) pool->GetSize();
|
|
while(i--)
|
|
{
|
|
CVehicle* pVehicle = pool->GetSlot(i);
|
|
if( pVehicle && (pReturnVehicle->GetVehicleType() == pVehicle->GetVehicleType()) )
|
|
typecount++;
|
|
}
|
|
|
|
netGameObjectWrapper<CDynamicEntity> wrapper(pReturnVehicle);
|
|
NetworkObjectType objectType = static_cast<NetworkObjectType>(wrapper.GetNetworkObjectType());
|
|
|
|
u32 numLocalObjectsOwnedOfType = CNetworkObjectPopulationMgr::GetNumLocalObjects(objectType);
|
|
u32 numRemoteObjectsOfType = CNetworkObjectPopulationMgr::GetNumRemoteObjects(objectType);
|
|
u32 maxObjectsAllowedToOwnOfType = CNetworkObjectPopulationMgr::GetMaxObjectsAllowedToOwnOfType(objectType);
|
|
|
|
bool bIsOwningTooManyObjects = NetworkInterface::GetObjectManager().IsOwningTooManyObjects();
|
|
|
|
int totalNumVehicles = CNetworkObjectPopulationMgr::GetTotalNumVehicles();
|
|
|
|
Warningf("CVehicleFactory::Create Note: typecount[%d] numLocalObjectsOwnedOfType[%d] numRemoteObjectsOfType[%d] maxObjectsAllowedToOwnOfType[%d] bIsOwningTooManyObjects[%d] TotalNumVehicles[%d] MAX_NUM_NETOBJVEHICLES[%d]",typecount,numLocalObjectsOwnedOfType,numRemoteObjectsOfType,maxObjectsAllowedToOwnOfType,bIsOwningTooManyObjects,totalNumVehicles,MAX_NUM_NETOBJVEHICLES);
|
|
#endif
|
|
#endif
|
|
|
|
// vehicle could not be registered as there is no available network objects for it, so it has to be removed
|
|
// unless it is a mission object, which is queued to be registered later
|
|
// returning false here means the vehicle will be destroyed
|
|
return false;
|
|
}
|
|
|
|
|
|
return true;
|
|
}
|
|
|
|
//
|
|
// name: CVehicleFactory::CreateAndAttachTrailer
|
|
// description: Creates a trailer and attaches it to the vehicle specified
|
|
// parameters: trailer model id
|
|
// target vehicle pointer to attach trailer to
|
|
// vehicle creation matrix
|
|
CVehicle* CVehicleFactory::CreateAndAttachTrailer(fwModelId trailerId, CVehicle* targetVehicle, const Matrix34& creationMatrix, const eEntityOwnedBy ownedBy, const u32 popType, const bool bExtendBoxesForCollisionTests)
|
|
{
|
|
int parentBone = targetVehicle->GetBoneIndex(VEH_ATTACH);
|
|
CVehicle* trailer = NULL;
|
|
if (trailerId.IsValid() && parentBone > -1)
|
|
{
|
|
if (!CModelInfo::HaveAssetsLoaded(trailerId))
|
|
{
|
|
// if this is a boat trailer, don't request it unless we have boats loaded
|
|
CVehicleModelInfo* tmi = (CVehicleModelInfo*)CModelInfo::GetBaseModelInfo(trailerId);
|
|
if (tmi && tmi->GetVehicleFlag(CVehicleModelInfoFlags::FLAG_SPAWN_BOAT_ON_TRAILER))
|
|
{
|
|
if (gPopStreaming.GetLoadedBoats().CountMembers() <= 0)
|
|
{
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
CModelInfo::RequestAssets(trailerId, STRFLAG_FORCE_LOAD | STRFLAG_DONTDELETE);
|
|
Assert(targetVehicle);
|
|
trailerId = targetVehicle->GetVehicleModelInfo()->GetRandomLoadedTrailer();
|
|
if (!trailerId.IsValid())
|
|
return NULL;
|
|
|
|
if (CNetwork::IsGameInProgress() && !CVehicle::IsTypeAllowedInMP(trailerId.GetModelIndex()))
|
|
return NULL;
|
|
}
|
|
|
|
CVehicleModelInfo* trailerModelInfo = (CVehicleModelInfo*)CModelInfo::GetBaseModelInfo(trailerId);
|
|
Assertf(trailerModelInfo, "Invalid model info for trailer id %d (%s)", trailerId.GetModelIndex(), trailerModelInfo->GetModelName());
|
|
if (trailerModelInfo && trailerModelInfo->GetStructure())
|
|
{
|
|
if (trailerModelInfo->GetDistanceSqrToClosestInstance(creationMatrix.d, false) < (trailerModelInfo->GetIdenticalModelSpawnDistance() * trailerModelInfo->GetIdenticalModelSpawnDistance()))
|
|
return NULL;
|
|
|
|
if ( trailerModelInfo && trailerModelInfo->GetVehicleFlag(CVehicleModelInfoFlags::FLAG_SPAWN_BOAT_ON_TRAILER) )
|
|
{
|
|
const bool bTooManyTrailersWithoutBoats = ms_uCurrentBoatTrailersWithoutBoats > ms_uMaxBoatTrailersWithoutBoats; // Strictly greater-than; if it's equal, allow it, as it could turn into a trailer with a boat
|
|
const bool bAtMaximumTrailersWithBoats = ms_uCurrentBoatTrailersWithBoats >= ms_uMaxBoatTrailersWithBoats;
|
|
const bool bTrailerWithoutBoatCanAddBoat = (ms_uCurrentBoatTrailersWithoutBoats <= ms_uMaxBoatTrailersWithoutBoats && !bAtMaximumTrailersWithBoats);
|
|
|
|
// If this is a boat trailer, ensure we are not over the maximum number.
|
|
if ( bTooManyTrailersWithoutBoats || !bTrailerWithoutBoatCanAddBoat )
|
|
{
|
|
boatTrailerDebugf3("CreateAndAttachTrailer: Disallowed trailer creation, ms_uCurrentBoatTrailersWithoutBoats = %u, ms_uCurrentTrailersWithBoats = %u", ms_uCurrentBoatTrailersWithoutBoats, ms_uCurrentBoatTrailersWithBoats);
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
int trailerBone = trailerModelInfo->GetBoneIndex(TRAILER_ATTACH);
|
|
|
|
// Assert that it is possible to attach this vehicle to other vehicle
|
|
Assertf(trailerBone > -1, "This trailer has no attach point: %s", trailerModelInfo->GetModelName());
|
|
if(trailerBone > -1)
|
|
{
|
|
// simulate attach to parent to get the matrix
|
|
Matrix34 matNew(Matrix34::IdentityType);
|
|
|
|
Mat34V trailerMtx;
|
|
trailerModelInfo->GetFragType()->GetSkeletonData().ComputeObjectTransform(trailerBone, trailerMtx);
|
|
matNew.Transpose3x4(RCC_MATRIX34(trailerMtx));
|
|
|
|
Matrix34 matParent;
|
|
targetVehicle->GetGlobalMtx(parentBone, matParent);
|
|
matNew.Dot(matParent);
|
|
|
|
// check trailer for collision and spawn it only if there's room
|
|
Assert(trailerModelInfo->GetFragType());
|
|
phBound *bound = (phBound *)trailerModelInfo->GetFragType()->GetPhysics(0)->GetCompositeBounds();
|
|
int nTestTypeFlags = ArchetypeFlags::GTA_BOX_VEHICLE_TYPE|ArchetypeFlags::GTA_VEHICLE_TYPE|ArchetypeFlags::GTA_PED_TYPE|ArchetypeFlags::GTA_OBJECT_TYPE;
|
|
// extend bbox check 2m down (and 2m up)
|
|
const Vector3 vecExtendBoxMinLarge(-0.25f,-1.5f,-2.0f);
|
|
const Vector3 vecExtendBoxMaxLarge(0.25f, 0.25f, 0.0f);
|
|
const Vector3 vecExtendBoxMinReg(0.0f,0.0f,-2.0f);
|
|
const Vector3 vecExtendBoxMaxReg(0.0f, 0.0f, 0.0f);
|
|
|
|
const Vector3 vecExtendBoxMin = bExtendBoxesForCollisionTests ? vecExtendBoxMinLarge : vecExtendBoxMinReg;
|
|
const Vector3 vecExtendBoxMax = bExtendBoxesForCollisionTests ? vecExtendBoxMaxLarge : vecExtendBoxMaxReg;
|
|
|
|
WorldProbe::CShapeTestBoundingBoxDesc bboxDesc;
|
|
bboxDesc.SetBound(bound);
|
|
bboxDesc.SetTransform(&matNew);
|
|
bboxDesc.SetIncludeFlags(nTestTypeFlags);
|
|
bboxDesc.SetExcludeEntity(targetVehicle);
|
|
bboxDesc.SetExtensionToBoundingBoxMin(vecExtendBoxMin);
|
|
bboxDesc.SetExtensionToBoundingBoxMax(vecExtendBoxMax);
|
|
|
|
if(!WorldProbe::GetShapeTestManager()->SubmitTest(bboxDesc) BANK_ONLY(|| ms_pLastCreatedVehicle == targetVehicle))
|
|
{
|
|
if (CModelInfo::HaveAssetsLoaded(trailerId))
|
|
{
|
|
trailer = CVehicleFactory::GetFactory()->Create(trailerId, ownedBy, popType, &creationMatrix);
|
|
|
|
// warp the trailer onto the vehicle
|
|
if (trailer && trailer->GetVehicleType() == VEHICLE_TYPE_TRAILER)
|
|
{
|
|
((CTrailer*)trailer)->AttachToParentVehicle(targetVehicle, true);
|
|
targetVehicle->m_nVehicleFlags.bCanMakeIntoDummyVehicle = CVehicleAILodManager::ms_bAllowTrailersToConvertFromReal;
|
|
trailer->m_nVehicleFlags.bCanMakeIntoDummyVehicle = CVehicleAILodManager::ms_bAllowTrailersToConvertFromReal;
|
|
|
|
// Make sure to set bHasParentVehicle. This normally happens at the beginning of the trailer's intelligence update,
|
|
// but we need it now so the trailer and its parent can both go superdummy from the start.
|
|
Assertf(trailer->GetAttachParentVehicleDummyOrPhysical(), "Expected valid trailer attachment.");
|
|
trailer->m_nVehicleFlags.bHasParentVehicle = true;
|
|
}
|
|
else if (trailer)
|
|
{
|
|
Destroy(trailer);
|
|
trailer = NULL;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#if !__NO_OUTPUT
|
|
if (trailer)
|
|
{
|
|
CVehicleModelInfo* tmi = (CVehicleModelInfo*)CModelInfo::GetBaseModelInfo(trailerId);
|
|
if (tmi && tmi->GetVehicleFlag(CVehicleModelInfoFlags::FLAG_SPAWN_BOAT_ON_TRAILER))
|
|
{
|
|
// ms_uCurrentBoatTrailersWithoutBoats incremented in Create() above.
|
|
boatTrailerDebugf3("CreateAndAttachTrailer: added trailer, ms_uCurrentBoatTrailersWithoutBoats = %u", ms_uCurrentBoatTrailersWithoutBoats);
|
|
if(ms_uCurrentBoatTrailersWithBoats > ms_uMaxBoatTrailersWithBoats)
|
|
{
|
|
boatTrailerWarningf("Too many trailers with boats (%u, max %u)", ms_uCurrentBoatTrailersWithBoats, ms_uMaxBoatTrailersWithBoats);
|
|
}
|
|
if(ms_uCurrentBoatTrailersWithoutBoats > (ms_uMaxBoatTrailersWithoutBoats + 1)) // Allow one extra, as it could turn into a trailer with a boat.
|
|
{
|
|
boatTrailerWarningf("Too many trailers without boats (%u, max %u + 1)", ms_uCurrentBoatTrailersWithoutBoats, ms_uMaxBoatTrailersWithoutBoats);
|
|
}
|
|
|
|
}
|
|
}
|
|
#endif // !__NO_OUTPUT
|
|
|
|
return trailer;
|
|
}
|
|
|
|
float ProbeForWheelPosition(const CVehicle* trailer, const Vector3& carPos, const Vector3& wheelOffset, float wheelHeightAboveGround)
|
|
{
|
|
const float probeOffsetZ = 2.f;
|
|
float bestZ = carPos.z;
|
|
|
|
const int nInitialNumResults = 8;
|
|
WorldProbe::CShapeTestProbeDesc probeDesc;
|
|
WorldProbe::CShapeTestFixedResults<nInitialNumResults> probeResults;
|
|
probeDesc.SetResultsStructure(&probeResults);
|
|
Vector3 probeStart = carPos;
|
|
probeStart.x += wheelOffset.x;
|
|
probeStart.y += wheelOffset.y;
|
|
Vector3 probeEnd = probeStart;
|
|
probeEnd.z -= probeOffsetZ;
|
|
probeDesc.SetStartAndEnd(probeStart, probeEnd);
|
|
probeDesc.SetDomainForTest(WorldProbe::TEST_AGAINST_INDIVIDUAL_OBJECTS);
|
|
probeDesc.SetIncludeEntity(trailer);
|
|
WorldProbe::GetShapeTestManager()->SubmitTest(probeDesc);
|
|
int nBestHit = -1;
|
|
float fBestDeltaZ = LARGE_FLOAT;
|
|
|
|
WorldProbe::ResultIterator it;
|
|
int hit = 0;
|
|
for(it = probeResults.begin(); it < probeResults.end(); ++it, ++hit)
|
|
{
|
|
if(it->GetHitDetected() && rage::Abs((it->GetHitPosition() - carPos).z) < fBestDeltaZ)
|
|
{
|
|
nBestHit = hit;
|
|
fBestDeltaZ = rage::Abs((it->GetHitPosition() - carPos).z);
|
|
}
|
|
}
|
|
|
|
if(nBestHit > -1)
|
|
bestZ = probeResults[nBestHit].GetHitPosition().z + wheelHeightAboveGround;
|
|
|
|
return bestZ;
|
|
}
|
|
|
|
void ProbeForBoatPosition(CVehicle* spawnBoat, Matrix34* boatMat, const Vector3& trailerPos, const Vector3& lowSupport, const Vector3& highSupport, const Vector3& frontSupport)
|
|
{
|
|
const int nInitialNumResults = 8;
|
|
|
|
int nBestHit = -1;
|
|
float fBestDeltaZ = LARGE_FLOAT;
|
|
|
|
// test low support
|
|
{
|
|
WorldProbe::CShapeTestProbeDesc probeDesc;
|
|
WorldProbe::CShapeTestFixedResults<nInitialNumResults> probeResults;
|
|
probeDesc.SetResultsStructure(&probeResults);
|
|
|
|
Vector3 probeStart = trailerPos + lowSupport;
|
|
Vector3 probeEnd = probeStart;
|
|
probeEnd.z = boatMat->d.z;
|
|
probeDesc.SetStartAndEnd(probeStart, probeEnd);
|
|
probeDesc.SetDomainForTest(WorldProbe::TEST_AGAINST_INDIVIDUAL_OBJECTS);
|
|
probeDesc.SetIncludeEntity(spawnBoat);
|
|
WorldProbe::GetShapeTestManager()->SubmitTest(probeDesc);
|
|
|
|
WorldProbe::ResultIterator it;
|
|
int hit = 0;
|
|
for(it = probeResults.begin(); it < probeResults.end(); ++it, ++hit)
|
|
{
|
|
if(it->GetHitDetected() && rage::Abs((it->GetHitPosition() - probeStart).z) < fBestDeltaZ)
|
|
{
|
|
nBestHit = hit;
|
|
fBestDeltaZ = rage::Abs((it->GetHitPosition() - probeStart).z);
|
|
}
|
|
}
|
|
}
|
|
|
|
// test high support (optional if we don't care about minor glitches)
|
|
{
|
|
WorldProbe::CShapeTestProbeDesc probeDesc;
|
|
WorldProbe::CShapeTestFixedResults<nInitialNumResults> probeResults;
|
|
probeDesc.SetResultsStructure(&probeResults);
|
|
|
|
Vector3 probeStart = trailerPos + highSupport;
|
|
Vector3 probeEnd = probeStart;
|
|
probeEnd.z = boatMat->d.z;
|
|
probeDesc.SetStartAndEnd(probeStart, probeEnd);
|
|
probeDesc.SetDomainForTest(WorldProbe::TEST_AGAINST_INDIVIDUAL_OBJECTS);
|
|
probeDesc.SetIncludeEntity(spawnBoat);
|
|
WorldProbe::GetShapeTestManager()->SubmitTest(probeDesc);
|
|
|
|
WorldProbe::ResultIterator it;
|
|
int hit = 0;
|
|
for(it = probeResults.begin(); it < probeResults.end(); ++it, ++hit)
|
|
{
|
|
if(it->GetHitDetected() && rage::Abs((it->GetHitPosition() - probeStart).z) < fBestDeltaZ)
|
|
{
|
|
nBestHit = hit;
|
|
fBestDeltaZ = rage::Abs((it->GetHitPosition() - probeStart).z);
|
|
}
|
|
}
|
|
}
|
|
|
|
// fix position if we hit anything
|
|
if (nBestHit >= 0)
|
|
{
|
|
boatMat->d.z -= fBestDeltaZ;
|
|
spawnBoat->SetMatrix(*boatMat);
|
|
}
|
|
|
|
// test front support and move boat forward if needed
|
|
{
|
|
WorldProbe::CShapeTestProbeDesc probeDesc;
|
|
WorldProbe::CShapeTestFixedResults<nInitialNumResults> probeResults;
|
|
probeDesc.SetResultsStructure(&probeResults);
|
|
|
|
Vec3V vForward = spawnBoat->GetVehicleForwardDirection();
|
|
Vector3 forward = RCC_VECTOR3(vForward);
|
|
forward.Normalize();
|
|
|
|
Vector3 probeStart = trailerPos + frontSupport;
|
|
Vector3 probeEnd = probeStart - forward * 2.f;
|
|
probeDesc.SetStartAndEnd(probeStart, probeEnd);
|
|
probeDesc.SetDomainForTest(WorldProbe::TEST_AGAINST_INDIVIDUAL_OBJECTS);
|
|
probeDesc.SetIncludeEntity(spawnBoat);
|
|
WorldProbe::GetShapeTestManager()->SubmitTest(probeDesc);
|
|
|
|
nBestHit = -1;
|
|
float fBestDelta = LARGE_FLOAT;
|
|
WorldProbe::ResultIterator it;
|
|
int hit = 0;
|
|
for(it = probeResults.begin(); it < probeResults.end(); ++it, ++hit)
|
|
{
|
|
if(it->GetHitDetected())
|
|
{
|
|
float dist = (it->GetHitPosition() - probeStart).Mag2();
|
|
if (dist < fBestDelta)
|
|
{
|
|
nBestHit = hit;
|
|
fBestDelta = dist;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (nBestHit >= 0)
|
|
{
|
|
boatMat->d += forward * rage::Sqrtf(fBestDelta);
|
|
spawnBoat->SetMatrix(*boatMat);
|
|
}
|
|
}
|
|
}
|
|
|
|
bool CVehicleFactory::GetPositionAndRotationForCargoTrailer(CTrailer* trailer, const int index, CVehicle* pVehicle, Vector3& vPosOut, Quaternion& qRotationOut)
|
|
{
|
|
if (!trailer || !pVehicle)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
Matrix34 creationMat;
|
|
Matrix34 trailerMat = MAT34V_TO_MATRIX34(trailer->GetMatrix());
|
|
|
|
CVehicleModelInfo* vehMi = pVehicle->GetVehicleModelInfo();
|
|
// make sure vehicle has loaded
|
|
if(!CModelInfo::HaveAssetsLoaded(pVehicle->GetModelId()))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// rotate offset so it lines up with the trailer orientation
|
|
Vector3 offset = CTrailer::sm_offsets[index];
|
|
trailerMat.Transform3x3(offset);
|
|
|
|
creationMat = trailerMat;
|
|
creationMat.d += offset;
|
|
|
|
// try to find correct height for vehicle placement
|
|
float frontHeightAboveGround, rearHeightAboveGround;
|
|
CVehicle::CalculateHeightsAboveRoad(pVehicle->GetModelId(), &frontHeightAboveGround, &rearHeightAboveGround);
|
|
|
|
Vector3 posFront = CWheel::GetWheelOffset(vehMi, VEH_WHEEL_LF);
|
|
Vector3 posRear = CWheel::GetWheelOffset(vehMi, VEH_WHEEL_LR);
|
|
|
|
// rotate wheel position vectors to world space
|
|
Vector3 transPosFront;
|
|
Vector3 transPosRear;
|
|
trailerMat.Transform3x3(posFront, transPosFront);
|
|
trailerMat.Transform3x3(posRear, transPosRear);
|
|
|
|
// find collision for wheels
|
|
float rearWheelZ = ProbeForWheelPosition(trailer, creationMat.d, transPosRear, rearHeightAboveGround);
|
|
float frontWheelZ = ProbeForWheelPosition(trailer, creationMat.d, transPosFront, frontHeightAboveGround);
|
|
|
|
// set z position of vehicle to middle and rotate vehicle
|
|
creationMat.d.z = 0.5f * (rearWheelZ + frontWheelZ);
|
|
float wheelToWheelDist = rage::Abs(posFront.y - posRear.y); // along y, forward axis of vehicle
|
|
float heightDiff = frontWheelZ - rearWheelZ;
|
|
float angle = atanf(heightDiff / wheelToWheelDist);
|
|
float origAngle = rage::Atan2f(creationMat.b.z, creationMat.c.z); // get current angle around x (since the one we just calculated should be the final angle)
|
|
angle -= origAngle;
|
|
creationMat.RotateLocalX(angle); // rotate around x so the forward axis is rotated
|
|
|
|
Matrix34 trailerAttachMat;
|
|
trailer->GetGlobalMtx(trailer->GetBoneIndex(TRAILER_ATTACH), trailerAttachMat);
|
|
Matrix34 offsetMat;
|
|
offsetMat.DotTranspose(creationMat, trailerAttachMat);
|
|
Quaternion offsetRot;
|
|
offsetRot.FromMatrix34(offsetMat);
|
|
|
|
vPosOut = offsetMat.d;
|
|
qRotationOut = offsetRot;
|
|
|
|
return true;
|
|
}
|
|
|
|
//
|
|
// name: CVehicleFactory::AddCarsOnTrailer
|
|
// description: Adds cars on the trailer specified. the cars to be spawned need to be loaded into memory.
|
|
// parameters: trailer pointer
|
|
// location for creation
|
|
// owned by identifier
|
|
// population type identifier
|
|
// optional list of cars to spawn. if NULL is passed it it will use random cars available in memory (that have the spawn_on_trailer flag set)
|
|
void CVehicleFactory::AddCarsOnTrailer(CTrailer* trailer, fwInteriorLocation location, eEntityOwnedBy ownedBy, ePopType popType, fwModelId* carsToSpawn)
|
|
{
|
|
CVehicleModelInfo* mi = trailer->GetVehicleModelInfo();
|
|
Assert(mi);
|
|
|
|
if (!mi->GetVehicleFlag(CVehicleModelInfoFlags::FLAG_SPAWN_ON_TRAILER))
|
|
return;
|
|
|
|
// if no car list is passed in, try to create a list from vehicles loaded in memory that have the spawn on trailer flag set
|
|
fwModelId loadedVehIds[MAX_CARGO_VEHICLES];
|
|
if (!carsToSpawn)
|
|
{
|
|
CLoadedModelGroup loadedCars = gPopStreaming.GetAppropriateLoadedCars();
|
|
loadedCars.RemoveVehModelsWithFlagSet(CVehicleModelInfoFlags::FLAG_SPAWN_ON_TRAILER, false);
|
|
s32 numLoadedCars = loadedCars.CountMembers();
|
|
|
|
if (numLoadedCars == 0)
|
|
return;
|
|
|
|
for (s32 i = 0; i < MAX_CARGO_VEHICLES; ++i)
|
|
{
|
|
loadedVehIds[i] = fwModelId(strLocalIndex(loadedCars.GetMember(fwRandom::GetRandomNumberInRange(0, numLoadedCars))));
|
|
|
|
if (CScriptCars::GetSuppressedCarModels().HasModelBeenSuppressed(loadedVehIds[i].GetModelIndex()))
|
|
loadedVehIds[i].Invalidate();
|
|
}
|
|
carsToSpawn = loadedVehIds;
|
|
}
|
|
|
|
// create our vehicles
|
|
Matrix34 creationMat;
|
|
Matrix34 trailerMat = MAT34V_TO_MATRIX34(trailer->GetMatrix());
|
|
|
|
// Pick a random number of cargo vehicles for this trailer
|
|
static int kMinCargoVehs = 3;
|
|
static int kMaxCargoVehs = 5;
|
|
int iNumCargoVehsToPlace = fwRandom::GetRandomNumberInRange(Min(kMinCargoVehs,kMaxCargoVehs),kMaxCargoVehs+1);
|
|
for (s32 i = 0; i < MAX_CARGO_VEHICLES; ++i)
|
|
{
|
|
float fRand = fwRandom::GetRandomNumberInRange(0.0f,1.0f);
|
|
if(fRand > (float)(iNumCargoVehsToPlace) / (MAX_CARGO_VEHICLES-i))
|
|
{
|
|
continue;
|
|
}
|
|
iNumCargoVehsToPlace--;
|
|
|
|
fwModelId vehId = carsToSpawn[i];
|
|
if (!vehId.IsValid())
|
|
continue;
|
|
|
|
CVehicleModelInfo* vehMi = (CVehicleModelInfo*)CModelInfo::GetBaseModelInfo(vehId);
|
|
|
|
// make sure vehicle has loaded
|
|
if(!CModelInfo::HaveAssetsLoaded(vehId))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// rotate offset so it lines up with the trailer orientation
|
|
Vector3 offset = CTrailer::sm_offsets[i];
|
|
trailerMat.Transform3x3(offset);
|
|
|
|
creationMat = trailerMat;
|
|
creationMat.d += offset;
|
|
|
|
// try to find correct height for vehicle placement
|
|
float frontHeightAboveGround, rearHeightAboveGround;
|
|
CVehicle::CalculateHeightsAboveRoad(vehId, &frontHeightAboveGround, &rearHeightAboveGround);
|
|
|
|
Vector3 posFront = CWheel::GetWheelOffset(vehMi, VEH_WHEEL_LF);
|
|
Vector3 posRear = CWheel::GetWheelOffset(vehMi, VEH_WHEEL_LR);
|
|
|
|
// rotate wheel position vectors to world space
|
|
Vector3 transPosFront;
|
|
Vector3 transPosRear;
|
|
trailerMat.Transform3x3(posFront, transPosFront);
|
|
trailerMat.Transform3x3(posRear, transPosRear);
|
|
|
|
// find collision for wheels
|
|
float rearWheelZ = ProbeForWheelPosition(trailer, creationMat.d, transPosRear, rearHeightAboveGround);
|
|
float frontWheelZ = ProbeForWheelPosition(trailer, creationMat.d, transPosFront, frontHeightAboveGround);
|
|
|
|
// set z position of vehicle to middle and rotate vehicle
|
|
creationMat.d.z = 0.5f * (rearWheelZ + frontWheelZ);
|
|
float wheelToWheelDist = rage::Abs(posFront.y - posRear.y); // along y, forward axis of vehicle
|
|
float heightDiff = frontWheelZ - rearWheelZ;
|
|
float angle = atanf(heightDiff / wheelToWheelDist);
|
|
float origAngle = rage::Atan2f(creationMat.b.z, creationMat.c.z); // get current angle around x (since the one we just calculated should be the final angle)
|
|
angle -= origAngle;
|
|
creationMat.RotateLocalX(angle); // rotate around x so the forward axis is rotated
|
|
|
|
// spawn vehicle
|
|
CVehicle* spawnVeh = CVehicleFactory::GetFactory()->Create(vehId, ownedBy, popType, &creationMat);
|
|
CGameWorld::Add(spawnVeh, location);
|
|
|
|
Matrix34 trailerAttachMat;
|
|
trailer->GetGlobalMtx(trailer->GetBoneIndex(TRAILER_ATTACH), trailerAttachMat);
|
|
Matrix34 offsetMat;
|
|
offsetMat.DotTranspose(creationMat, trailerAttachMat);
|
|
Quaternion offsetRot;
|
|
offsetRot.FromMatrix34(offsetMat);
|
|
|
|
//save off our offset from the parent so we know where to keep the vehicle in superdummy mode
|
|
//spawnVeh->SetParentTrailerEntity1Offset(offsetMat.d);
|
|
|
|
//offset.d is where the vehicle is in trailer space.
|
|
//offsetRot is the rotation of the vehicle in trailer space
|
|
//Vector3 vEntity2Offset = creationMat.Transform(trailerAttachMat.d);
|
|
spawnVeh->SetParentTrailerEntity2Offset(offsetMat.d);
|
|
spawnVeh->SetParentTrailerEntityRotation(offsetRot);
|
|
|
|
spawnVeh->AttachToPhysicalBasic(trailer, (s16)trailer->GetBoneIndex(TRAILER_ATTACH), ATTACH_STATE_BASIC | ATTACH_FLAG_INITIAL_WARP | ATTACH_FLAG_COL_ON | ATTACH_FLAG_DELETE_WITH_PARENT, &offsetMat.d, &offsetRot);
|
|
trailer->AddCargoVehicle(i, spawnVeh);
|
|
spawnVeh->SetParentTrailer(trailer);
|
|
}
|
|
}
|
|
|
|
//
|
|
// name: CVehicleFactory::AddBoatOnTrailer
|
|
// description: Adds a boat on the trailer specified. the boat to be spawned needs to be loaded in memory.
|
|
// parameters: trailer pointer
|
|
// location for creation
|
|
// owned by identifier
|
|
// population type identifier
|
|
// optional boat type to spawn
|
|
// returns true if a boat is created.
|
|
bool CVehicleFactory::AddBoatOnTrailer(CTrailer* trailer, fwInteriorLocation location, eEntityOwnedBy ownedBy, ePopType popType, fwModelId* boatToSpawn)
|
|
{
|
|
CVehicleModelInfo* mi = trailer->GetVehicleModelInfo();
|
|
Assert(mi);
|
|
|
|
if (!mi->GetVehicleFlag(CVehicleModelInfoFlags::FLAG_SPAWN_BOAT_ON_TRAILER))
|
|
return false;
|
|
|
|
if (ms_uCurrentBoatTrailersWithBoats >= ms_uMaxBoatTrailersWithBoats)
|
|
{
|
|
boatTrailerDebugf3("AddBoatOnTrailer: BLOCKED boat creation, ms_uCurrentBoatTrailersWithBoats = %u", ms_uCurrentBoatTrailersWithBoats);
|
|
return false;
|
|
}
|
|
|
|
fwModelId vehModel;
|
|
if (!boatToSpawn || !boatToSpawn->IsValid())
|
|
{
|
|
CLoadedModelGroup loadedBoats = gPopStreaming.GetLoadedBoats();
|
|
loadedBoats.RemoveVehModelsWithFlagSet(CVehicleModelInfoFlags::FLAG_SPAWN_BOAT_ON_TRAILER, false);
|
|
s32 numBoats = loadedBoats.CountMembers();
|
|
|
|
if (numBoats == 0)
|
|
return false;
|
|
|
|
vehModel = fwModelId(strLocalIndex(loadedBoats.GetMember(fwRandom::GetRandomNumberInRange(0, numBoats))));
|
|
}
|
|
else
|
|
{
|
|
vehModel = *boatToSpawn;
|
|
}
|
|
|
|
if (!vehModel.IsValid())
|
|
return false;
|
|
|
|
// make sure vehicle has loaded
|
|
if(!CModelInfo::HaveAssetsLoaded(vehModel))
|
|
return false;
|
|
|
|
// create our boat
|
|
Matrix34 trailerMat = MAT34V_TO_MATRIX34(trailer->GetMatrix());
|
|
Matrix34 creationMat = trailerMat;
|
|
creationMat.d.z -= mi->GetBoundingBoxMin().z;
|
|
|
|
// FA: these are hardcoded values for the boattrailer, if we end up with several layouts we'll need to expose these to meta data
|
|
Vector3 offsets[3] =
|
|
{
|
|
Vector3(0.42f, -1.58f, -0.19f), // low rest shelf
|
|
Vector3(0.86f, -3.30f, 0.13f), // high support pad at the back
|
|
Vector3(0.f, 2.55f, 0.58f) // front support, trace from this horizontally backwards
|
|
};
|
|
|
|
// move the boat backwards a bit so it doesn't intersect the car
|
|
Vector3 offset(0.f, -1.5f, 0.f);
|
|
trailerMat.Transform3x3(offset);
|
|
creationMat.d += offset;
|
|
|
|
CVehicle* spawnBoat = CVehicleFactory::GetFactory()->Create(vehModel, ownedBy, popType, &creationMat);
|
|
if (!Verifyf(spawnBoat, "Vehicle factory failed to created boat! id: %d", vehModel.GetModelIndex()))
|
|
return false;
|
|
|
|
trailerMat.Transform3x3(offsets[0]);
|
|
trailerMat.Transform3x3(offsets[1]);
|
|
trailerMat.Transform3x3(offsets[2]);
|
|
ProbeForBoatPosition(spawnBoat, &creationMat, trailerMat.d, offsets[0], offsets[1], offsets[2]);
|
|
|
|
CGameWorld::Add(spawnBoat, location);
|
|
|
|
Matrix34 trailerAttachMat;
|
|
trailer->GetGlobalMtx(trailer->GetBoneIndex(TRAILER_ATTACH), trailerAttachMat);
|
|
Matrix34 offsetMat;
|
|
offsetMat.DotTranspose(creationMat, trailerAttachMat);
|
|
Quaternion offsetRot;
|
|
offsetRot.FromMatrix34(offsetMat);
|
|
|
|
spawnBoat->SetParentTrailerEntity2Offset(offsetMat.d);
|
|
spawnBoat->SetParentTrailerEntityRotation(offsetRot);
|
|
|
|
spawnBoat->AttachToPhysicalBasic(trailer, (s16)trailer->GetBoneIndex(TRAILER_ATTACH), ATTACH_STATE_BASIC | ATTACH_FLAG_INITIAL_WARP | ATTACH_FLAG_COL_ON | ATTACH_FLAG_DELETE_WITH_PARENT, &offsetMat.d, &offsetRot);
|
|
trailer->AddCargoVehicle(0, spawnBoat);
|
|
spawnBoat->SetParentTrailer(trailer);
|
|
|
|
++ms_uCurrentBoatTrailersWithBoats;
|
|
if(ms_uCurrentBoatTrailersWithoutBoats > 0)
|
|
{
|
|
--ms_uCurrentBoatTrailersWithoutBoats;
|
|
}
|
|
boatTrailerDebugf3("AddBoatOnTrailer: ms_uCurrentBoatTrailersWithoutBoats = %u, ms_uCurrentBoatTrailersWithBoats = %u", ms_uCurrentBoatTrailersWithoutBoats, ms_uCurrentBoatTrailersWithBoats);
|
|
|
|
return true;
|
|
}
|
|
|
|
void CVehicleFactory::DetachedBoatOnTrailer()
|
|
{
|
|
if(ms_uCurrentBoatTrailersWithBoats > 0)
|
|
{
|
|
--ms_uCurrentBoatTrailersWithBoats;
|
|
}
|
|
++ms_uCurrentBoatTrailersWithoutBoats;
|
|
boatTrailerDebugf3("DetachedBoatOnTrailer: ms_uCurrentBoatTrailersWithoutBoats = %u, ms_uCurrentBoatTrailersWithBoats = %u", ms_uCurrentBoatTrailersWithoutBoats, ms_uCurrentBoatTrailersWithBoats);
|
|
}
|
|
|
|
bool CVehicleFactory::DestroyBoatTrailerIfNecessary(CTrailer** ppOutTrailer)
|
|
{
|
|
if (!ppOutTrailer)
|
|
{
|
|
return false;
|
|
}
|
|
if (!*ppOutTrailer)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
CVehicleModelInfo* mi = (*ppOutTrailer)->GetVehicleModelInfo();
|
|
Assert(mi);
|
|
|
|
// If for some reason you called this function on a non-boat-trailer, return.
|
|
if (!mi->GetVehicleFlag(CVehicleModelInfoFlags::FLAG_SPAWN_BOAT_ON_TRAILER))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// Check to see if a boat exists.
|
|
if (!(*ppOutTrailer)->HasCargoVehicles())
|
|
{
|
|
if (ms_uCurrentBoatTrailersWithoutBoats > ms_uMaxBoatTrailersWithoutBoats)
|
|
{
|
|
// Destroy will decrement ms_uCurrentBoatTrailersWithoutBoats
|
|
GetFactory()->Destroy(*ppOutTrailer);
|
|
*ppOutTrailer = NULL;
|
|
boatTrailerDebugf3("DestroyBoatTrailerIfNecessary: DESTROYING trailer without boat, ms_uCurrentBoatTrailersWithoutBoats = %u", ms_uCurrentBoatTrailersWithoutBoats);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
#if !__NO_OUTPUT
|
|
if(ms_uCurrentBoatTrailersWithBoats > ms_uMaxBoatTrailersWithBoats)
|
|
{
|
|
boatTrailerWarningf("Too many trailers with boats (%u, max %u)", ms_uCurrentBoatTrailersWithBoats, ms_uMaxBoatTrailersWithBoats);
|
|
}
|
|
if(ms_uCurrentBoatTrailersWithoutBoats > (ms_uMaxBoatTrailersWithoutBoats + 1)) // Allow one extra, as it could turn into a trailer with a boat.
|
|
{
|
|
boatTrailerWarningf("Too many trailers without boats (%u, max %u + 1)", ms_uCurrentBoatTrailersWithoutBoats, ms_uMaxBoatTrailersWithoutBoats);
|
|
}
|
|
#endif // !__NO_OUTPUT
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
void CVehicleFactory::DestroyChildrenVehicles(CVehicle * pVehicle, bool UNUSED_PARAM(cached))
|
|
{
|
|
// Destroy dummy children
|
|
if (pVehicle->HasDummyAttachmentChildren())
|
|
{
|
|
if(pVehicle->IsNetworkClone())
|
|
{
|
|
Assertf(0, "Warning: Trying to delete clone %s attachments!", pVehicle->GetNetworkObject()->GetLogName());
|
|
}
|
|
else
|
|
{
|
|
for (int i=0; i < pVehicle->GetMaxNumDummyAttachmentChildren(); i++)
|
|
{
|
|
CVehicle* pDummyAttachedVeh = pVehicle->GetDummyAttachmentChild(i);
|
|
if (pDummyAttachedVeh)
|
|
{
|
|
pVehicle->DummyDetachChild(i);
|
|
|
|
const bool bCanDelete = !pDummyAttachedVeh->GetNetworkObject() || pDummyAttachedVeh->GetNetworkObject()->CanDelete();
|
|
|
|
Assertf(bCanDelete, "Can't delete child vehicle! This should have been checked before calling this function!");
|
|
|
|
if (bCanDelete REPLAY_ONLY(&& !CReplayMgr::IsEditModeActive()))
|
|
{
|
|
// TODO: Any reason we don't cache the attached vehicles?
|
|
Destroy(pDummyAttachedVeh);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Detach any mission vehicle attached to a tow-arm to prevent it from being destroyed below.
|
|
for(int i=0; i<pVehicle->GetNumberOfVehicleGadgets(); i++)
|
|
{
|
|
CVehicleGadget * pGadget = pVehicle->GetVehicleGadget(i);
|
|
if(pGadget && pGadget->GetType()==VGT_TOW_TRUCK_ARM)
|
|
{
|
|
CVehicleGadgetTowArm * pTowArm = static_cast<CVehicleGadgetTowArm*>(pGadget);
|
|
if(const CVehicle * pAttachedVehicle = pTowArm->GetAttachedVehicle())
|
|
{
|
|
if(pAttachedVehicle->PopTypeIsMission())
|
|
{
|
|
pTowArm->DetachVehicle(pVehicle,true,true);
|
|
}
|
|
}
|
|
}
|
|
else if(pGadget && (pGadget->GetType()==VGT_PICK_UP_ROPE || pGadget->GetType()==VGT_PICK_UP_ROPE_MAGNET))
|
|
{
|
|
CVehicleGadgetPickUpRope * pPickUpRope = static_cast<CVehicleGadgetPickUpRope*>(pGadget);
|
|
if(const CVehicle * pAttachedVehicle = pPickUpRope->GetAttachedVehicle())
|
|
{
|
|
if(pAttachedVehicle->PopTypeIsMission())
|
|
{
|
|
pPickUpRope->DetachEntity(pVehicle,true,true);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// Destroy children attached via CPhysical. Only recurses through vehicle attachments. This used to happen in ~CPhysical,
|
|
// but now CGameWorld::Remove() detaches objects so the connection is lost. This may be creating orphaned objects elsewhere.
|
|
fwAttachmentEntityExtension *attachExt = pVehicle->GetAttachmentExtension();
|
|
if(attachExt)
|
|
{
|
|
CPhysical* pCurChild = static_cast<CPhysical*>(attachExt->GetChildAttachment());
|
|
while(pCurChild)
|
|
{
|
|
fwAttachmentEntityExtension &curChildAttachExt = pCurChild->GetAttachmentExtensionRef();
|
|
CPhysical* pNextChild = static_cast<CPhysical*>(curChildAttachExt.GetSiblingAttachment());
|
|
if(pCurChild->GetIsTypeVehicle())
|
|
{
|
|
CVehicle* pChildVeh = static_cast<CVehicle*>(pCurChild);
|
|
if (pChildVeh)
|
|
{
|
|
const bool bCanDelete = !pChildVeh->GetNetworkObject() || pChildVeh->GetNetworkObject()->CanDelete();
|
|
|
|
Assertf(bCanDelete, "Can't delete child vehicle! This should have been checked before calling this function!");
|
|
|
|
if (bCanDelete REPLAY_ONLY(&& !CReplayMgr::IsEditModeActive()))
|
|
{
|
|
// TODO: Any reason we don't cache the attached vehicles?
|
|
Destroy(pChildVeh);
|
|
}
|
|
}
|
|
}
|
|
pCurChild = pNextChild;
|
|
}
|
|
}
|
|
|
|
if (pVehicle->InheritsFromTrailer())
|
|
{
|
|
for (s32 i = 0; i < MAX_CARGO_VEHICLES; ++i)
|
|
{
|
|
CVehicle* pCargoVehicle = ((CTrailer*)pVehicle)->GetCargoVehicle(i);
|
|
if (pCargoVehicle)
|
|
{
|
|
((CTrailer*)pVehicle)->RemoveCargoVehicle(pCargoVehicle);
|
|
REPLAY_ONLY(if(!CReplayMgr::IsEditModeActive()))
|
|
{
|
|
Destroy(pCargoVehicle);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
void CVehicleFactory::DeleteOrCacheVehicle(CVehicle * pVehicle, bool cached)
|
|
{
|
|
// don't add helis to the cache, it won't give us any wins and they don't seem to play nice with it
|
|
if (cached && !pVehicle->GetIsRotaryAircraft() && !gPopStreaming.IsCarDiscarded(pVehicle->GetModelIndex()))
|
|
{
|
|
AddDestroyedVehToCache(pVehicle);
|
|
}
|
|
else
|
|
{
|
|
delete pVehicle;
|
|
}
|
|
}
|
|
|
|
#if __BANK
|
|
void CVehicleFactory::LogDestroyedVehicle(CVehicle * pVehicle, const char * pCallerDesc, s32 iTextOffsetY, Color32 iTextCol)
|
|
{
|
|
if(ms_bLogDestroyedVehicles)
|
|
{
|
|
CViewport* gameViewport = gVpMan.GetGameViewport();
|
|
if(gameViewport)
|
|
{
|
|
char text[128];
|
|
|
|
const Vector3 vVehiclePos = VEC3V_TO_VECTOR3(pVehicle->GetTransform().GetPosition());
|
|
const Vector3 vCameraPos = VEC3V_TO_VECTOR3(gameViewport->GetGrcViewport().GetCameraPosition());
|
|
const float fDist = (vCameraPos - vVehiclePos).Mag();
|
|
|
|
const char *pLogName;
|
|
if(NetworkInterface::IsGameInProgress())
|
|
{
|
|
pLogName = pVehicle->GetNetworkObject() ? pVehicle->GetNetworkObject()->GetLogName() : "";
|
|
}
|
|
else
|
|
{
|
|
pLogName = pVehicle->GetDebugNameFromObjectID();
|
|
}
|
|
|
|
sprintf(text, "%i : %s %s", ms_iDestroyedVehicleCount, pVehicle->GetModelName(), pLogName);
|
|
grcDebugDraw::Text(vVehiclePos, iTextCol, 0, -grcDebugDraw::GetScreenSpaceTextHeight() + iTextOffsetY, text, false, -(s32)(10.0f / fwTimer::GetTimeStep()));
|
|
grcDebugDraw::Sphere(vVehiclePos, 0.25f, Color_yellow4, false, -(s32)(10.0f / fwTimer::GetTimeStep()));
|
|
|
|
Displayf("**************************************************************************************************");
|
|
Displayf("%s : %i", pCallerDesc, ms_iDestroyedVehicleCount);
|
|
Displayf("NAME : %s %s, DISTANCE : %.1f, POSITION : %.1f, %.1f, %.1f, VEHICLE : 0x%p, RANGESCALE : %.1f", pVehicle->GetModelName(), pLogName, fDist, vVehiclePos.x, vVehiclePos.y, vVehiclePos.z, pVehicle, CVehiclePopulation::GetPopulationRangeScale());
|
|
Displayf("REASON : %s", CVehiclePopulation::GetLastRemovalReason());
|
|
sysStack::PrintStackTrace();
|
|
Displayf("**************************************************************************************************");
|
|
|
|
ms_iDestroyedVehicleCount++;
|
|
}
|
|
}
|
|
}
|
|
#endif // __BANK
|
|
|
|
//
|
|
// name: CVehicleFactory::Destroy
|
|
// description: Default factory destroy function. Individual projects can override this
|
|
// parameters: pVehicle
|
|
void CVehicleFactory::Destroy(CVehicle* pVehicle, bool cached)
|
|
{
|
|
Assert(pVehicle);
|
|
|
|
#if __BANK
|
|
LogDestroyedVehicle(pVehicle, "CVehicleFactory::Destroy", 0, Color_yellow);
|
|
#endif
|
|
|
|
CVehiclePopulation::IncrementNumVehiclesDestroyedThisCycle();
|
|
|
|
// don't destroy vehicle if it's on the population cache list
|
|
if (IsVehInDestroyedCache(pVehicle))
|
|
{
|
|
pVehicle->ClearAllKnownRefs();
|
|
return;
|
|
}
|
|
|
|
// inform network object manager about this vehicle being deleted
|
|
if (pVehicle->GetNetworkObject())
|
|
{
|
|
if (pVehicle->IsNetworkClone())
|
|
{
|
|
if (pVehicle->GetNetworkObject()->IsScriptObject() && !pVehicle->PopTypeIsMission())
|
|
Assertf(0, "Warning: clone %s is being destroyed (it is not a mission vehicle anymore)!", pVehicle->GetNetworkObject()->GetLogName());
|
|
else
|
|
Assertf(0, "Warning: clone %s is being destroyed!", pVehicle->GetNetworkObject()->GetLogName());
|
|
|
|
// bail out
|
|
return;
|
|
}
|
|
|
|
NetworkInterface::UnregisterObject(pVehicle);
|
|
}
|
|
|
|
if (pVehicle && pVehicle->GetVehicleType() == VEHICLE_TYPE_TRAILER)
|
|
{
|
|
CVehicleModelInfo* tmi = pVehicle->GetVehicleModelInfo();
|
|
if (tmi && tmi->GetVehicleFlag(CVehicleModelInfoFlags::FLAG_SPAWN_BOAT_ON_TRAILER))
|
|
{
|
|
CTrailer* pTrailer = static_cast<CTrailer*>(pVehicle);
|
|
if (pTrailer->HasCargoVehicles())
|
|
{
|
|
if (ms_uCurrentBoatTrailersWithBoats > 0)
|
|
{
|
|
--ms_uCurrentBoatTrailersWithBoats;
|
|
}
|
|
#if !__NO_OUTPUT
|
|
else
|
|
{
|
|
boatTrailerWarningf("Incorrect accounting for ms_uCurrentBoatTrailersWithBoats - deleting one when ms_uCurrentBoatTrailersWithBoats == 0");
|
|
}
|
|
#endif // !__NO_OUTPUT
|
|
boatTrailerDebugf3("Destroy: removed trailer with boat, ms_uCurrentBoatTrailersWithBoats = %u", ms_uCurrentBoatTrailersWithBoats);
|
|
}
|
|
else
|
|
{
|
|
if (ms_uCurrentBoatTrailersWithoutBoats > 0)
|
|
{
|
|
--ms_uCurrentBoatTrailersWithoutBoats;
|
|
}
|
|
#if !__NO_OUTPUT
|
|
else
|
|
{
|
|
boatTrailerWarningf("Incorrect accounting for ms_uCurrentBoatTrailersWithoutBoats - deleting one when ms_uCurrentBoatTrailersWithBoats == 0");
|
|
}
|
|
#endif // !__NO_OUTPUT
|
|
boatTrailerDebugf3("Destroy: removed trailer without boat, ms_uCurrentBoatTrailersWithoutBoats = %u", ms_uCurrentBoatTrailersWithoutBoats);
|
|
}
|
|
}
|
|
}
|
|
|
|
Assert(pVehicle->m_nVehicleFlags.bCreatedByFactory);
|
|
pVehicle->m_nVehicleFlags.bCreatedByFactory = false;
|
|
|
|
DestroyChildrenVehicles(pVehicle,cached);
|
|
|
|
CSpatialArrayNode& node = pVehicle->GetSpatialArrayNode();
|
|
if(node.IsInserted())
|
|
{
|
|
CVehicle::GetSpatialArray().Remove(node);
|
|
}
|
|
|
|
REPLAY_ONLY(CReplayMgr::OnDelete(pVehicle));
|
|
|
|
CGameWorld::Remove(pVehicle);
|
|
|
|
CTheScripts::UnregisterEntity(pVehicle, false);
|
|
|
|
#if 0
|
|
DeleteOrCacheVehicle(pVehicle,cached);
|
|
#else
|
|
delete pVehicle;
|
|
#endif
|
|
}
|
|
|
|
CVehicle* CVehicleFactory::CreateVehicle(s32 nVehicleType, const eEntityOwnedBy ownedBy, const u32 popType)
|
|
{
|
|
CVehicle *pReturnVehicle = NULL;
|
|
#if __BANK
|
|
if(CVehicle::GetPool() && CVehicle::GetPool()->GetNoOfFreeSpaces() == 0)
|
|
{
|
|
if (NetworkInterface::IsGameInProgress())
|
|
{
|
|
Displayf("*** VEHICLE POOL FULL ****\n");
|
|
|
|
CVehicle::Pool* pool = CVehicle::GetPool();
|
|
for(int i= 0; i< pool->GetSize(); i++)
|
|
{
|
|
CVehicle* pVehicle = pool->GetSlot(i);
|
|
|
|
if(pVehicle)
|
|
{
|
|
Vector3 pos = VEC3V_TO_VECTOR3(pVehicle->GetTransform().GetPosition());
|
|
Displayf("%d: 0x%p (Model: %s. Net obj: %s. Pos: %f, %f, %f. Script created: %s)\n", i, pVehicle, pVehicle->GetModelName(), pVehicle->GetNetworkObject() ? pVehicle->GetNetworkObject()->GetLogName() : "-none-", pos.x, pos.y, pos.z, pVehicle->PopTypeIsMission() ? "true" : "false");
|
|
}
|
|
else
|
|
{
|
|
Displayf("%d: Empty\n", i);
|
|
}
|
|
}
|
|
}
|
|
Assertf(false, "Vehicle Pool Full, Size == %d (you need to raise PoolSize in common/data/gameconfig.xml)", (s32)CVehicle::GetPool()->GetSize());
|
|
return NULL;
|
|
}
|
|
#endif
|
|
|
|
switch(nVehicleType)
|
|
{
|
|
case VEHICLE_TYPE_CAR:
|
|
pReturnVehicle = rage_new CAutomobile(ownedBy, popType, VEHICLE_TYPE_CAR);
|
|
break;
|
|
case VEHICLE_TYPE_QUADBIKE:
|
|
pReturnVehicle = rage_new CQuadBike(ownedBy, popType);
|
|
break;
|
|
case VEHICLE_TYPE_BIKE:
|
|
pReturnVehicle = rage_new CBike(ownedBy, popType, VEHICLE_TYPE_BIKE);
|
|
break;
|
|
case VEHICLE_TYPE_BICYCLE:
|
|
pReturnVehicle = rage_new CBmx(ownedBy, popType);
|
|
break;
|
|
case VEHICLE_TYPE_BOAT:
|
|
pReturnVehicle = rage_new CBoat(ownedBy, popType);
|
|
break;
|
|
case VEHICLE_TYPE_TRAIN:
|
|
pReturnVehicle = rage_new CTrain(ownedBy, popType);
|
|
break;
|
|
case VEHICLE_TYPE_HELI:
|
|
pReturnVehicle = rage_new CHeli(ownedBy, popType);
|
|
break;
|
|
case VEHICLE_TYPE_PLANE:
|
|
pReturnVehicle = rage_new CPlane(ownedBy, popType);
|
|
break;
|
|
case VEHICLE_TYPE_AUTOGYRO:
|
|
pReturnVehicle = rage_new CAutogyro(ownedBy, popType);
|
|
break;
|
|
case VEHICLE_TYPE_SUBMARINE:
|
|
pReturnVehicle = rage_new CSubmarine(ownedBy, popType);
|
|
break;
|
|
case VEHICLE_TYPE_TRAILER:
|
|
pReturnVehicle = rage_new CTrailer(ownedBy, popType);
|
|
break;
|
|
#if ENABLE_DRAFT_VEHICLE
|
|
case VEHICLE_TYPE_DRAFT:
|
|
pReturnVehicle = rage_new CDraftVeh(ownedBy, popType);
|
|
break;
|
|
#endif
|
|
case VEHICLE_TYPE_SUBMARINECAR:
|
|
pReturnVehicle = rage_new CSubmarineCar(ownedBy, popType);
|
|
break;
|
|
case VEHICLE_TYPE_AMPHIBIOUS_AUTOMOBILE:
|
|
pReturnVehicle = rage_new CAmphibiousAutomobile(ownedBy, popType);
|
|
break;
|
|
case VEHICLE_TYPE_AMPHIBIOUS_QUADBIKE:
|
|
pReturnVehicle = rage_new CAmphibiousQuadBike(ownedBy, popType);
|
|
break;
|
|
case VEHICLE_TYPE_BLIMP:
|
|
pReturnVehicle = rage_new CBlimp(ownedBy, popType);
|
|
break;
|
|
default:
|
|
Assertf(false, "Unknown vehicle type");
|
|
break;
|
|
}
|
|
|
|
#if NAVMESH_EXPORT
|
|
// Don't attempt to init audio for collision exporter, it will crash
|
|
if(CNavMeshDataExporter::WillExportCollision())
|
|
return pReturnVehicle;
|
|
#endif
|
|
|
|
if(pReturnVehicle)
|
|
{
|
|
switch(nVehicleType)
|
|
{
|
|
case VEHICLE_TYPE_HELI:
|
|
case VEHICLE_TYPE_AUTOGYRO:
|
|
case VEHICLE_TYPE_BLIMP:
|
|
pReturnVehicle->m_VehicleAudioEntity = rage_new audHeliAudioEntity();
|
|
break;
|
|
case VEHICLE_TYPE_TRAIN:
|
|
pReturnVehicle->m_VehicleAudioEntity = rage_new audTrainAudioEntity();
|
|
break;
|
|
case VEHICLE_TYPE_PLANE:
|
|
pReturnVehicle->m_VehicleAudioEntity = rage_new audPlaneAudioEntity();
|
|
break;
|
|
case VEHICLE_TYPE_BOAT:
|
|
case VEHICLE_TYPE_SUBMARINE:
|
|
pReturnVehicle->m_VehicleAudioEntity = rage_new audBoatAudioEntity();
|
|
break;
|
|
case VEHICLE_TYPE_CAR:
|
|
case VEHICLE_TYPE_AMPHIBIOUS_AUTOMOBILE:
|
|
case VEHICLE_TYPE_BIKE:
|
|
case VEHICLE_TYPE_AMPHIBIOUS_QUADBIKE:
|
|
case VEHICLE_TYPE_SUBMARINECAR:
|
|
case VEHICLE_TYPE_QUADBIKE:
|
|
#if ENABLE_DRAFT_VEHICLE
|
|
case VEHICLE_TYPE_DRAFT:
|
|
#endif
|
|
pReturnVehicle->m_VehicleAudioEntity = rage_new audCarAudioEntity();
|
|
break;
|
|
case VEHICLE_TYPE_BICYCLE:
|
|
pReturnVehicle->m_VehicleAudioEntity = rage_new audBicycleAudioEntity();
|
|
break;
|
|
case VEHICLE_TYPE_TRAILER:
|
|
pReturnVehicle->m_VehicleAudioEntity = rage_new audTrailerAudioEntity();
|
|
break;
|
|
default:
|
|
audWarningf("Vehicle type [%d] does not have a custom audVehicleAudioEntity this can lead to asserts looking like Assert(m_EngineSubmixIndex >= 0 && m_ExhaustSubmixIndex >= 0)", nVehicleType);
|
|
pReturnVehicle->m_VehicleAudioEntity = rage_new audVehicleAudioEntity();
|
|
break;
|
|
}
|
|
|
|
// audDisplayf("%s (0x%p) created %s audio entity (0x%p)", ms_modelTypes[nVehicleType], pReturnVehicle, pReturnVehicle->m_VehicleAudioEntity? audVehicleAudioEntity::GetVehicleTypeName(pReturnVehicle->m_VehicleAudioEntity->GetAudioVehicleType()) : "NULL", pReturnVehicle->m_VehicleAudioEntity);
|
|
|
|
pReturnVehicle->m_VehicleAudioEntity->Init(pReturnVehicle);
|
|
|
|
REPLAY_ONLY(CReplayMgr::OnCreateEntity(pReturnVehicle));
|
|
}
|
|
|
|
return pReturnVehicle;
|
|
}
|
|
|
|
bool CVehicleFactory::GetVehicleType(char* name, s32& nVehicleType)
|
|
{
|
|
if(!strcmp(name, "bicycle"))
|
|
{
|
|
nVehicleType = VEHICLE_TYPE_BICYCLE;
|
|
}
|
|
else if(!strcmp(name, "car"))
|
|
{
|
|
nVehicleType = VEHICLE_TYPE_CAR;
|
|
}
|
|
else if(!strcmp(name, "quadbike"))
|
|
{
|
|
nVehicleType = VEHICLE_TYPE_QUADBIKE;
|
|
}
|
|
else if(!strcmp(name, "bike"))
|
|
{
|
|
nVehicleType = VEHICLE_TYPE_BIKE;
|
|
}
|
|
else if(!strcmp(name, "boat"))
|
|
{
|
|
nVehicleType = VEHICLE_TYPE_BOAT;
|
|
}
|
|
else if(!strcmp(name, "train"))
|
|
{
|
|
nVehicleType = VEHICLE_TYPE_TRAIN;
|
|
}
|
|
else if(!strcmp(name, "heli"))
|
|
{
|
|
nVehicleType = VEHICLE_TYPE_HELI;
|
|
}
|
|
else if(!strcmp(name, "plane"))
|
|
{
|
|
nVehicleType = VEHICLE_TYPE_PLANE;
|
|
}
|
|
else if(!strcmp(name, "autogyro"))
|
|
{
|
|
nVehicleType = VEHICLE_TYPE_AUTOGYRO;
|
|
}
|
|
else if(!strcmp(name, "submarine"))
|
|
{
|
|
nVehicleType = VEHICLE_TYPE_SUBMARINE;
|
|
}
|
|
else if(!strcmp(name, "trailer"))
|
|
{
|
|
nVehicleType = VEHICLE_TYPE_TRAILER;
|
|
}
|
|
#if ENABLE_DRAFT_VEHICLE
|
|
else if(!strcmp(name, "draft"))
|
|
{
|
|
nVehicleType = VEHICLE_TYPE_DRAFT;
|
|
}
|
|
#endif
|
|
else if(!strcmp(name, "submarinecar"))
|
|
{
|
|
nVehicleType = VEHICLE_TYPE_SUBMARINECAR;
|
|
}
|
|
else if(strcmp(name, "amphibiousAutomobile"))
|
|
{
|
|
nVehicleType = VEHICLE_TYPE_AMPHIBIOUS_AUTOMOBILE;
|
|
}
|
|
else if(strcmp(name, "amphibiousQuadbike"))
|
|
{
|
|
nVehicleType = VEHICLE_TYPE_AMPHIBIOUS_QUADBIKE;
|
|
}
|
|
else if(!strcmp(name, "blimp"))
|
|
{
|
|
nVehicleType = VEHICLE_TYPE_BLIMP;
|
|
}
|
|
else
|
|
{
|
|
Assertf(false, "Unknown vehicle type name");
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
ObjectNameIdAssociation* CVehicleFactory::GetBaseVehicleTypeDesc(int UNUSED_PARAM(nType))
|
|
{
|
|
return ms_modelDesc[0];
|
|
}
|
|
|
|
ObjectNameIdAssociation* CVehicleFactory::GetExtraVehicleTypeDesc(int nType)
|
|
{
|
|
Assert(nType < VEHICLE_TYPE_NUM);
|
|
return ms_modelDesc[nType];
|
|
}
|
|
|
|
ObjectNameIdAssociation* CVehicleFactory::GetExtraLandingGearTypeDesc()
|
|
{
|
|
return pLandingGearModelOverrideDesc;
|
|
}
|
|
|
|
u16* CVehicleFactory::GetBaseVehicleTypeDescHashes(int UNUSED_PARAM(nType))
|
|
{
|
|
return ms_modelDescHashes[0];
|
|
}
|
|
|
|
u16* CVehicleFactory::GetExtraVehicleTypeDescHashes(int nType)
|
|
{
|
|
Assert(nType < VEHICLE_TYPE_NUM);
|
|
return ms_modelDescHashes[nType];
|
|
}
|
|
|
|
u16* CVehicleFactory::GetExtraLandingGearTypeDescHashes()
|
|
{
|
|
return pLandingGearModelOverrideDescHashes;
|
|
}
|
|
|
|
void CVehicleFactory::AssignVehicleGadgets(CVehicle* pVehicle)
|
|
{
|
|
CVehicleGadget* pGadget = NULL;
|
|
if(pVehicle)
|
|
{
|
|
// scan for vehicle weapons
|
|
|
|
// Stuff will be added here for special case vehicles
|
|
|
|
if(pVehicle->pHandling->mFlags & MF_HAS_TRACKS)
|
|
{
|
|
ENABLE_FRAG_OPTIMIZATION_ONLY(pVehicle->GiveFragCacheEntry(true);)
|
|
pGadget = rage_new CVehicleTracks();
|
|
pVehicle->AddVehicleGadget(pGadget);
|
|
}
|
|
if(pVehicle->pHandling->hFlags & HF_ENABLE_LEAN)
|
|
{
|
|
pGadget = rage_new CVehicleLeanHelper();
|
|
pVehicle->AddVehicleGadget(pGadget);
|
|
}
|
|
|
|
if(pVehicle->GetVehicleModelInfo() && pVehicle->GetVehicleModelInfo()->GetVehicleFlag(CVehicleModelInfoFlags::FLAG_PARKING_SENSORS))
|
|
{
|
|
static dev_float sParkingSensorRadius = 0.4f;
|
|
CVehicleGadgetParkingSensor *pParkingSensor = rage_new CVehicleGadgetParkingSensor(pVehicle, sParkingSensorRadius);
|
|
pVehicle->AddVehicleGadget(pParkingSensor);
|
|
}
|
|
|
|
// Search for attach point
|
|
int iAttachHelperBoneIndex = pVehicle->GetBoneIndex(VEH_ATTACH);
|
|
if(iAttachHelperBoneIndex > -1)
|
|
{
|
|
pGadget = rage_new CVehicleTrailerAttachPoint(iAttachHelperBoneIndex);
|
|
pVehicle->AddVehicleGadget(pGadget);
|
|
pVehicle->m_nVehicleFlags.bMayBecomeParkedSuperDummy = false;
|
|
}
|
|
|
|
// Search for a digger arm
|
|
iAttachHelperBoneIndex = pVehicle->GetBoneIndex(VEH_DIGGER_ARM);
|
|
if(iAttachHelperBoneIndex > -1)
|
|
{
|
|
ENABLE_FRAG_OPTIMIZATION_ONLY(pVehicle->GiveFragCacheEntry(true);)
|
|
static dev_float fDiggerArmSleepMoveSpeed = 1.0f;
|
|
static dev_float fDiggerArmDefaultRatio = 0.25f;
|
|
|
|
CVehicleGadgetDiggerArm *pDiggerArmGadget = rage_new CVehicleGadgetDiggerArm(iAttachHelperBoneIndex, fDiggerArmSleepMoveSpeed);
|
|
pDiggerArmGadget->InitJointLimits(pVehicle->GetVehicleModelInfo());
|
|
pVehicle->AddVehicleGadget(pDiggerArmGadget);
|
|
|
|
pDiggerArmGadget->DriveJointToRatio(pVehicle, DIGGER_JOINT_BASE, fDiggerArmDefaultRatio);
|
|
pDiggerArmGadget->InitAudio(pVehicle);
|
|
return;
|
|
}
|
|
|
|
if(pVehicle->InheritsFromTrailer() &&
|
|
( !MI_TRAILER_TRAILERLARGE.IsValid() || MI_TRAILER_TRAILERLARGE.GetName().GetHash() != pVehicle->GetModelNameHash() ) &&
|
|
( !MI_TRAILER_TRAILERSMALL2.IsValid() || MI_TRAILER_TRAILERSMALL2.GetName().GetHash() != pVehicle->GetModelNameHash() ) )// This is a gadget for tr3 trailer
|
|
{
|
|
// Search for a boat boom
|
|
iAttachHelperBoneIndex = pVehicle->GetBoneIndex(VEH_MISC_E);
|
|
if(iAttachHelperBoneIndex > -1)
|
|
{
|
|
ENABLE_FRAG_OPTIMIZATION_ONLY(pVehicle->GiveFragCacheEntry(true);)
|
|
static dev_float fBooomMoveSpeed = 1.0f;
|
|
|
|
CVehicleGadgetBoatBoom *pBoatBoomGadget = rage_new CVehicleGadgetBoatBoom(iAttachHelperBoneIndex, fBooomMoveSpeed);
|
|
pBoatBoomGadget->InitJointLimits(pVehicle->GetVehicleModelInfo());
|
|
pVehicle->AddVehicleGadget(pBoatBoomGadget);
|
|
}
|
|
}
|
|
|
|
|
|
// Search for a tow truck arm.
|
|
iAttachHelperBoneIndex = pVehicle->GetBoneIndex(VEH_TOW_ARM);
|
|
if(iAttachHelperBoneIndex > -1)
|
|
{
|
|
ENABLE_FRAG_OPTIMIZATION_ONLY(pVehicle->GiveFragCacheEntry(true);)
|
|
s32 iMountAAttachHelperBoneIndex = pVehicle->GetBoneIndex(VEH_TOW_MOUNT_A);
|
|
s32 iMountBAttachHelperBoneIndex = pVehicle->GetBoneIndex(VEH_TOW_MOUNT_B);
|
|
|
|
static dev_float fTowArmMoveSpeed = 0.125f;
|
|
|
|
//Make sure the bones are valid
|
|
Assert(pVehicle->GetSkeleton() && iMountAAttachHelperBoneIndex < pVehicle->GetSkeleton()->GetBoneCount() && iMountBAttachHelperBoneIndex < pVehicle->GetSkeleton()->GetBoneCount());
|
|
|
|
|
|
CVehicleGadgetTowArm *pTowArmGadget = rage_new CVehicleGadgetTowArm(iAttachHelperBoneIndex, iMountAAttachHelperBoneIndex, iMountBAttachHelperBoneIndex, fTowArmMoveSpeed );
|
|
pTowArmGadget->Init(pVehicle, pVehicle->GetVehicleModelInfo());
|
|
pVehicle->AddVehicleGadget(pTowArmGadget);
|
|
}
|
|
|
|
// Search for the forks on a forklift
|
|
iAttachHelperBoneIndex = pVehicle->GetBoneIndex(VEH_FORKS);
|
|
s32 iAttachHelperBoneIndexA = pVehicle->GetBoneIndex(VEH_CARRIAGE);
|
|
if(iAttachHelperBoneIndex > -1 && iAttachHelperBoneIndexA > -1)
|
|
{
|
|
ENABLE_FRAG_OPTIMIZATION_ONLY(pVehicle->GiveFragCacheEntry(true);)
|
|
static dev_float fForkliftArmSleepMoveSpeed = 0.5f;
|
|
|
|
CVehicleGadgetForks *pForkLiftGadget = rage_new CVehicleGadgetForks(iAttachHelperBoneIndex, iAttachHelperBoneIndexA, fForkliftArmSleepMoveSpeed );
|
|
pForkLiftGadget->Init(pVehicle);
|
|
pForkLiftGadget->InitJointLimits(pVehicle->GetVehicleModelInfo());
|
|
pVehicle->AddVehicleGadget(pForkLiftGadget);
|
|
}
|
|
|
|
// Search for the frame on a Handler
|
|
iAttachHelperBoneIndex = pVehicle->GetBoneIndex(VEH_HANDLER_FRAME_1);
|
|
iAttachHelperBoneIndexA = pVehicle->GetBoneIndex(VEH_HANDLER_FRAME_2);
|
|
if(iAttachHelperBoneIndex > -1 && iAttachHelperBoneIndexA > -1)
|
|
{
|
|
ENABLE_FRAG_OPTIMIZATION_ONLY(pVehicle->GiveFragCacheEntry(true);)
|
|
static dev_float fHandlerFrameSleepMoveSpeed = 0.5f;
|
|
|
|
CVehicleGadgetHandlerFrame* pForkLiftGadget = rage_new CVehicleGadgetHandlerFrame(iAttachHelperBoneIndex, iAttachHelperBoneIndexA, fHandlerFrameSleepMoveSpeed);
|
|
pForkLiftGadget->Init(pVehicle);
|
|
pForkLiftGadget->InitJointLimits(pVehicle->GetVehicleModelInfo());
|
|
pVehicle->AddVehicleGadget(pForkLiftGadget);
|
|
}
|
|
|
|
// Search for bomb bay
|
|
iAttachHelperBoneIndex = pVehicle->GetBoneIndex(VEH_DOOR_HATCH_R);
|
|
iAttachHelperBoneIndexA = pVehicle->GetBoneIndex(VEH_DOOR_HATCH_L);
|
|
if(iAttachHelperBoneIndex > -1 && iAttachHelperBoneIndexA > -1)
|
|
{
|
|
ENABLE_FRAG_OPTIMIZATION_ONLY(pVehicle->GiveFragCacheEntry(true);)
|
|
static dev_float fBombBayDoorsMoveSpeed = 1.0f;
|
|
|
|
CVehicleGadgetBombBay *pBombBayGadget = rage_new CVehicleGadgetBombBay(iAttachHelperBoneIndex, iAttachHelperBoneIndexA, fBombBayDoorsMoveSpeed);
|
|
pBombBayGadget->InitJointLimits(pVehicle->GetVehicleModelInfo());
|
|
pVehicle->AddVehicleGadget(pBombBayGadget);
|
|
}
|
|
|
|
// Search for a thresher.
|
|
if(pVehicle->GetBoneIndex(VEH_PICKUP_REEL) > -1 && pVehicle->GetBoneIndex(VEH_AUGER) > -1)
|
|
{
|
|
ENABLE_FRAG_OPTIMIZATION_ONLY(pVehicle->GiveFragCacheEntry(true);)
|
|
static dev_float fThreserRotationSpeed = 0.5f;
|
|
|
|
s32 iPickupReelBoneIndex = pVehicle->GetBoneIndex(VEH_PICKUP_REEL);
|
|
s32 iAugerBoneIndex = pVehicle->GetBoneIndex(VEH_AUGER);
|
|
|
|
CVehicleGadgetThresher *pThresherGadget = rage_new CVehicleGadgetThresher(pVehicle, iPickupReelBoneIndex, iAugerBoneIndex, fThreserRotationSpeed );
|
|
|
|
pThresherGadget->InitJointLimits(pVehicle->GetVehicleModelInfo());
|
|
|
|
pVehicle->AddVehicleGadget(pThresherGadget);
|
|
}
|
|
|
|
//search for an articulated digger arm boom stick and bucket bone
|
|
int iBaseAttachHelperBoneIndex = pVehicle->GetBoneIndex(VEH_ARTICULATED_DIGGER_ARM_BASE);
|
|
int iBoomAttachHelperBoneIndex = pVehicle->GetBoneIndex(VEH_ARTICULATED_DIGGER_ARM_BOOM);
|
|
int iStickAttachHelperBoneIndex = pVehicle->GetBoneIndex(VEH_ARTICULATED_DIGGER_ARM_STICK);
|
|
int iBucketAttachHelperBoneIndex = pVehicle->GetBoneIndex(VEH_ARTICULATED_DIGGER_ARM_BUCKET);
|
|
if(iBaseAttachHelperBoneIndex > VEH_INVALID_ID && (iBoomAttachHelperBoneIndex > VEH_INVALID_ID || iStickAttachHelperBoneIndex > VEH_INVALID_ID || iBucketAttachHelperBoneIndex > VEH_INVALID_ID) )
|
|
{
|
|
ENABLE_FRAG_OPTIMIZATION_ONLY(pVehicle->GiveFragCacheEntry(true);)
|
|
static dev_float fDiggerArmSleepMoveSpeed = 1.0f;
|
|
static dev_float fDiggerBoomJointInitRatio = 0.25f;//Keep the digger bucket off the ground when spawning
|
|
|
|
CVehicleGadgetArticulatedDiggerArm *pDiggerArmGadget = rage_new CVehicleGadgetArticulatedDiggerArm( fDiggerArmSleepMoveSpeed );
|
|
pDiggerArmGadget->SetDiggerJointBone(DIGGER_JOINT_BASE,iBaseAttachHelperBoneIndex);
|
|
pDiggerArmGadget->SetDiggerJointBone(DIGGER_JOINT_BOOM,iBoomAttachHelperBoneIndex);
|
|
pDiggerArmGadget->SetDiggerJointBone(DIGGER_JOINT_STICK,iStickAttachHelperBoneIndex);
|
|
pDiggerArmGadget->SetDiggerJointBone(DIGGER_JOINT_BUCKET,iBucketAttachHelperBoneIndex);
|
|
pDiggerArmGadget->InitJointLimits(pVehicle->GetVehicleModelInfo());
|
|
pDiggerArmGadget->DriveJointToRatio(pVehicle, DIGGER_JOINT_BOOM, fDiggerBoomJointInitRatio);
|
|
pDiggerArmGadget->InitAudio(pVehicle);
|
|
pVehicle->AddVehicleGadget(pDiggerArmGadget);
|
|
}
|
|
|
|
|
|
|
|
//search for an articulated EOD arm and just set it up like a digger for now
|
|
iBaseAttachHelperBoneIndex = pVehicle->GetBoneIndex(VEH_ARM1);
|
|
iBoomAttachHelperBoneIndex = pVehicle->GetBoneIndex(VEH_ARM2);
|
|
iStickAttachHelperBoneIndex = pVehicle->GetBoneIndex(VEH_ARM3);
|
|
iBucketAttachHelperBoneIndex = pVehicle->GetBoneIndex(VEH_ARM4);
|
|
if(iBoomAttachHelperBoneIndex > -1 && iStickAttachHelperBoneIndex > -1 && iBucketAttachHelperBoneIndex > -1)
|
|
{
|
|
ENABLE_FRAG_OPTIMIZATION_ONLY(pVehicle->GiveFragCacheEntry(true);)
|
|
static dev_float fEodArmSleepMoveSpeed = 1.0f;
|
|
|
|
CVehicleGadgetArticulatedDiggerArm *pDiggerArmGadget = rage_new CVehicleGadgetArticulatedDiggerArm( fEodArmSleepMoveSpeed );
|
|
pDiggerArmGadget->SetDiggerJointBone(DIGGER_JOINT_BASE,iBaseAttachHelperBoneIndex);
|
|
pDiggerArmGadget->SetDiggerJointBone(DIGGER_JOINT_BOOM,iBoomAttachHelperBoneIndex);
|
|
pDiggerArmGadget->SetDiggerJointBone(DIGGER_JOINT_STICK,iStickAttachHelperBoneIndex);
|
|
pDiggerArmGadget->SetDiggerJointBone(DIGGER_JOINT_BUCKET,iBucketAttachHelperBoneIndex);
|
|
pDiggerArmGadget->InitJointLimits(pVehicle->GetVehicleModelInfo());
|
|
pVehicle->AddVehicleGadget(pDiggerArmGadget);
|
|
}
|
|
|
|
// Make sure that each turret is registered for audio
|
|
if(pVehicle->GetVehicleWeaponMgr())
|
|
{
|
|
for(u32 loop = 0; loop < pVehicle->GetVehicleWeaponMgr()->GetNumTurrets(); loop++)
|
|
{
|
|
pVehicle->GetVehicleWeaponMgr()->GetTurret(loop)->InitAudio(pVehicle);
|
|
}
|
|
}
|
|
|
|
// Add a convertible roof audio handler if required
|
|
if(pVehicle->DoesVehicleHaveAConvertibleRoofAnimation())
|
|
{
|
|
pVehicle->GetVehicleAudioEntity()->CreateVehicleGadget(audVehicleGadget::AUD_VEHICLE_GADGET_ROOF);
|
|
}
|
|
|
|
if( ( pVehicle->GetBoneIndex(VEH_SPOILER) != -1 && pVehicle->GetBoneIndex(VEH_STRUTS) != -1 ) ||
|
|
( !CWheel::ms_bUseExtraWheelDownForce && pVehicle->pHandling->m_fDownforceModifier > 1.0f ) )
|
|
{
|
|
CVehicleGadgetDynamicSpoiler *pDynamicSpoilerGadget = rage_new CVehicleGadgetDynamicSpoiler();
|
|
pDynamicSpoilerGadget->InitAudio(pVehicle);
|
|
pVehicle->AddVehicleGadget(pDynamicSpoilerGadget);
|
|
}
|
|
|
|
if( pVehicle->GetVehicleType() == VEHICLE_TYPE_CAR &&
|
|
pVehicle->GetBoneIndex(VEH_FLAP_L) != -1 &&
|
|
pVehicle->GetBoneIndex(VEH_FLAP_R) != -1 )
|
|
{
|
|
CVehicleGadgetDynamicFlaps *pDynamicFlapsGadget = rage_new CVehicleGadgetDynamicFlaps();
|
|
pVehicle->AddVehicleGadget(pDynamicFlapsGadget);
|
|
}
|
|
}
|
|
}
|
|
|
|
void CVehicleFactory::ModifyVehicleTopSpeed(CVehicle* pVehicle, const float fPercentAdjustment)
|
|
{
|
|
if(pVehicle)
|
|
{
|
|
pVehicle->SetTopSpeedPercentage(fPercentAdjustment);
|
|
|
|
float adjustmentMultiplier = 1.0f + (fPercentAdjustment/100.0f);
|
|
|
|
// do drive and gear ratio conversion stuff
|
|
float fDriveForce = pVehicle->pHandling->m_fInitialDriveForce * adjustmentMultiplier;
|
|
float fDriveMaxFlatVel = pVehicle->pHandling->m_fInitialDriveMaxFlatVel * adjustmentMultiplier;
|
|
float fDriveMaxVel = fDriveMaxFlatVel * 1.2f; // add 20% to velocity used for gearing
|
|
|
|
// Setup the transmission
|
|
pVehicle->m_Transmission.SetupTransmission( fDriveForce,
|
|
fDriveMaxFlatVel,
|
|
fDriveMaxVel,
|
|
pVehicle->m_Transmission.GetNumGears(),
|
|
pVehicle );
|
|
|
|
if(pVehicle->GetSecondTransmission())
|
|
{
|
|
pVehicle->GetSecondTransmission()->SetupTransmission( fDriveForce,
|
|
fDriveMaxFlatVel,
|
|
fDriveMaxVel,
|
|
1,
|
|
pVehicle );
|
|
}
|
|
|
|
pVehicle->m_fDragCoeff = pVehicle->pHandling->m_fInitialDragCoeff;
|
|
if(adjustmentMultiplier != 0.0f)
|
|
{
|
|
pVehicle->m_fDragCoeff *= (1.0f/adjustmentMultiplier);
|
|
}
|
|
|
|
phArchetypeDamp *pArchetype = (phArchetypeDamp *)pVehicle->GetCurrentPhysicsInst()->GetArchetype();
|
|
pArchetype->ActivateDamping(phArchetypeDamp::LINEAR_V2, Vector3(pVehicle->m_fDragCoeff, pVehicle->m_fDragCoeff, 0.0f));
|
|
|
|
// Call this to make sure UpdateAirResistance() updates everything, since we have
|
|
// messed with the damping values and m_fDragCoeff, potentially.
|
|
pVehicle->RefreshAirResistance();
|
|
}
|
|
}
|
|
|
|
/////////////////////////////
|
|
/////////////////////////////
|
|
// Debug widgets
|
|
/////////////////////////////
|
|
//
|
|
#if __BANK
|
|
|
|
s32 GetPoolId(u32 nModelId)
|
|
{
|
|
CVehicleModelInfo *pVehModelInfo = (CVehicleModelInfo *)CModelInfo::GetBaseModelInfo(fwModelId(strLocalIndex(nModelId)));
|
|
fwArchetypeDynamicFactory<CVehicleModelInfo>& vehModelInfoStore = CModelInfo::GetVehicleModelInfoStore();
|
|
atArray<CVehicleModelInfo*> vehicleTypes;
|
|
vehModelInfoStore.GatherPtrs(vehicleTypes);
|
|
|
|
for(int i=0; i<vehicleTypes.GetCount(); i++)
|
|
{
|
|
if(vehicleTypes[i] == pVehModelInfo)
|
|
return i;
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
u32 GetModelIndex(s32 nPoolId)
|
|
{
|
|
fwArchetypeDynamicFactory<CVehicleModelInfo>& vehModelInfoStore = CModelInfo::GetVehicleModelInfoStore();
|
|
atArray<CVehicleModelInfo*> vehicleTypes;
|
|
vehModelInfoStore.GatherPtrs(vehicleTypes);
|
|
|
|
Assert(vehicleTypes[nPoolId]);
|
|
|
|
fwModelId carId;
|
|
CBaseModelInfo *pModelInfo = CModelInfo::GetBaseModelInfoFromName(vehicleTypes[nPoolId]->GetModelName(), &carId);
|
|
|
|
if(pModelInfo)
|
|
return carId.GetModelIndex();
|
|
|
|
return fwModelId::MI_INVALID;
|
|
}
|
|
|
|
|
|
void UpdateAvailableCarsCB(void)
|
|
{
|
|
fwArchetypeDynamicFactory<CVehicleModelInfo>& vehModelInfoStore = CModelInfo::GetVehicleModelInfoStore();
|
|
atArray<CVehicleModelInfo*> vehicleTypePtrs;
|
|
vehModelInfoStore.GatherPtrs(vehicleTypePtrs);
|
|
|
|
numCarsAvailable = vehicleTypePtrs.GetCount();
|
|
|
|
// pPedNumSlider->SetRange(0.0f, float(numCarsAvailable - 1));
|
|
}
|
|
|
|
void CVehicleFactory::CarNumChangeCB(void)
|
|
{
|
|
carModelId = GetModelIndex(vehicleSorts[currVehicleNameSelection]);
|
|
|
|
ms_variationDebugColor = 0;
|
|
ms_variationDebugWindowTint = -1;
|
|
if (carModelId != fwModelId::MI_INVALID)
|
|
{
|
|
CVehicleModelInfo* mi = (CVehicleModelInfo*)CModelInfo::GetBaseModelInfo(fwModelId(strLocalIndex(carModelId)));
|
|
if (mi && ms_variationColorSlider)
|
|
{
|
|
ms_variationColorSlider->SetRange(0.f, (float)mi->GetNumPossibleColours() - 1.f);
|
|
}
|
|
|
|
if (ms_variationWindowTintSlider)
|
|
{
|
|
ms_variationWindowTintSlider->SetRange(-1.f, (float)CVehicleModelInfo::GetVehicleColours()->m_WindowColors.GetCount() - 1.f);
|
|
}
|
|
}
|
|
}
|
|
|
|
void CVehicleFactory::TrailerNumChangeCB(void)
|
|
{
|
|
if(currVehicleTrailerNameSelection > 0)//0 is no trailer
|
|
trailerModelId = GetModelIndex(vehicleTrailerSorts[currVehicleTrailerNameSelection-1]);
|
|
else
|
|
trailerModelId = fwModelId::MI_INVALID;//no trailer selected
|
|
}
|
|
|
|
|
|
CVehicle *CreateCarAtMatrix(u32 modelId, Matrix34 *pMatrix, Vector3::Param offset = ORIGIN, bool bOnlyIfTheresRoom = false)
|
|
{
|
|
if(modelId != fwModelId::MI_INVALID)
|
|
{
|
|
fwModelId vehModelId((strLocalIndex(modelId)));
|
|
CVehicleModelInfo *pVehModelInfo = (CVehicleModelInfo *)CModelInfo::GetBaseModelInfo(vehModelId);
|
|
|
|
bool bForceLoad = false;
|
|
if(!CModelInfo::HaveAssetsLoaded(vehModelId))
|
|
{
|
|
CModelInfo::RequestAssets(vehModelId, STRFLAG_FORCE_LOAD|STRFLAG_PRIORITY_LOAD);
|
|
bForceLoad = true;
|
|
}
|
|
|
|
if(bForceLoad)
|
|
{
|
|
CStreaming::LoadAllRequestedObjects(true);
|
|
}
|
|
|
|
if(!CModelInfo::HaveAssetsLoaded(vehModelId))
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
Matrix34 matrix = *pMatrix;
|
|
if (pVehModelInfo)
|
|
{
|
|
matrix.d += Vector3(offset) * pVehModelInfo->GetBoundingSphereRadius();
|
|
}
|
|
|
|
if (bOnlyIfTheresRoom && pVehModelInfo)
|
|
{
|
|
if (!pVehModelInfo->GetFragType())
|
|
{
|
|
Displayf("CreateCar aborted due to car model info not having a frag type");
|
|
return NULL;
|
|
}
|
|
|
|
phBound *bound = (phBound *)pVehModelInfo->GetFragType()->GetPhysics(0)->GetCompositeBounds();
|
|
int nTestTypeFlags = ArchetypeFlags::GTA_BOX_VEHICLE_TYPE|ArchetypeFlags::GTA_VEHICLE_TYPE|ArchetypeFlags::GTA_PED_TYPE|ArchetypeFlags::GTA_OBJECT_TYPE|ArchetypeFlags::GTA_MAP_TYPE_VEHICLE;
|
|
|
|
WorldProbe::CShapeTestBoundDesc shapeTestDesc;
|
|
shapeTestDesc.SetBound(bound);
|
|
shapeTestDesc.SetTransform(&matrix);
|
|
shapeTestDesc.SetIncludeFlags(nTestTypeFlags);
|
|
|
|
if(WorldProbe::GetShapeTestManager()->SubmitTest(shapeTestDesc))
|
|
{
|
|
Displayf("CreateCar aborted due to an object blocking the spawn location");
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
CVehicle *pNewVehicle = CVehicleFactory::GetFactory()->Create(vehModelId, bCreateAsMissionCar ? ENTITY_OWNEDBY_SCRIPT : ENTITY_OWNEDBY_DEBUG, bCreateAsMissionCar ? POPTYPE_MISSION : POPTYPE_RANDOM_AMBIENT, &matrix, true, bPlaceOnRoadProperly);
|
|
if(pNewVehicle)
|
|
{
|
|
pNewVehicle->SetIsAbandoned();
|
|
|
|
pNewVehicle->m_nPhysicalFlags.bNotDamagedByBullets |= bBulletProof;
|
|
pNewVehicle->m_nPhysicalFlags.bNotDamagedByFlames |= bFireProof;
|
|
pNewVehicle->m_nPhysicalFlags.bNotDamagedByMelee |= bMeleeProof;
|
|
pNewVehicle->m_nPhysicalFlags.bNotDamagedByCollisions |= bCollisionProof;
|
|
pNewVehicle->m_nPhysicalFlags.bIgnoresExplosions |= bExplosionProof;
|
|
|
|
CGameWorld::Add(pNewVehicle, CGameWorld::OUTSIDE);
|
|
|
|
CPortalTracker* pPT = pNewVehicle->GetPortalTracker();
|
|
if (pPT)
|
|
{
|
|
pPT->RequestRescanNextUpdate();
|
|
pPT->Update(VEC3V_TO_VECTOR3(pNewVehicle->GetTransform().GetPosition()));
|
|
}
|
|
|
|
if(bCreateAsGangCar && pVehModelInfo->GetVehicleFlag(CVehicleModelInfoFlags::FLAG_EXTRAS_GANG))
|
|
{
|
|
pNewVehicle->InitExtraFlags(EXTRAS_SET_GANG);
|
|
pNewVehicle->Fix();
|
|
}
|
|
|
|
if(nForceExtraOn > 0)
|
|
{
|
|
pNewVehicle->m_nDisableExtras &= ~BIT(nForceExtraOn);
|
|
pNewVehicle->Fix();
|
|
}
|
|
|
|
if (pNewVehicle->GetCarDoorLocks() == CARLOCK_LOCKED_INITIALLY) // The game creates police cars with doors locked. For debug cars we don't want this.
|
|
{
|
|
pNewVehicle->SetCarDoorLocks(CARLOCK_UNLOCKED);
|
|
}
|
|
|
|
// can turn off hotwiring anims when testing stuff with cars...
|
|
pNewVehicle->m_nVehicleFlags.bCarNeedsToBeHotwired = bVehicleNeedsToBeHotwired;
|
|
pNewVehicle->m_nVehicleFlags.bHasBeenOwnedByPlayer = !bVehicleNeedsToBeHotwired;
|
|
|
|
if(bPlaceOnRoadProperly)
|
|
{
|
|
pNewVehicle->PlaceOnRoadAdjust();
|
|
pMatrix->Set(MAT34V_TO_MATRIX34(pNewVehicle->GetMatrix()));
|
|
}
|
|
|
|
if(bLockDoors)
|
|
{
|
|
pNewVehicle->SetCarDoorLocks(CARLOCK_LOCKED_BUT_CAN_BE_DAMAGED);
|
|
}
|
|
|
|
// If this is a train we set it to be de-railed. This way the process function wont move it to a train track
|
|
if (pNewVehicle->GetVehicleType() == VEHICLE_TYPE_TRAIN)
|
|
{
|
|
((CTrain*)pNewVehicle)->m_nTrainFlags.bCreatedAsScriptVehicle = true;
|
|
}
|
|
|
|
#if VEHICLE_GLASS_SMASH_TEST
|
|
VehicleGlassSmashTest(pNewVehicle);
|
|
#endif // VEHICLE_GLASS_SMASH_TEST
|
|
}
|
|
|
|
return pNewVehicle;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
void ReloadVehicleMetaDataCB()
|
|
{
|
|
CPopulationStreaming::FlushAllVehicleModelsHard();
|
|
|
|
const CDataFileMgr::DataFile* pData = DATAFILEMGR.GetFirstFile(CDataFileMgr::VEHICLE_METADATA_FILE);
|
|
while(DATAFILEMGR.IsValid(pData))
|
|
{
|
|
struct CVehicleModelInfo::InitDataList* pInitDataList = NULL;
|
|
if (PARSER.LoadObjectPtr(pData->m_filename, "meta", pInitDataList))
|
|
{
|
|
for (s32 i = 0; i < pInitDataList->m_InitDatas.GetCount(); ++i)
|
|
{
|
|
CVehicleModelInfo* pModelInfo = (CVehicleModelInfo*)CModelInfo::GetBaseModelInfoFromName(pInitDataList->m_InitDatas[i].m_modelName.c_str(), NULL);
|
|
if (!pModelInfo)
|
|
{
|
|
Assertf(false, "We don't support dynamically adding new vehicle models!");
|
|
// FA: though we probably could, is it as easy as adding the model here?
|
|
//CVehicleModelInfo* pModelInfo = CModelInfo::AddVehicleModel(pInitDataList->m_InitDatas[i].m_modelName.c_str());
|
|
//pModelInfo->Init(pInitDataList->m_InitDatas[i]);
|
|
}
|
|
else
|
|
{
|
|
pModelInfo->ReInit(pInitDataList->m_InitDatas[i]);
|
|
}
|
|
}
|
|
}
|
|
delete pInitDataList;
|
|
|
|
pData = DATAFILEMGR.GetNextFile(pData);
|
|
}
|
|
}
|
|
|
|
void CreateCar(bool bOnlyIfTheresRoom)
|
|
{
|
|
if(bCreateAsPersonalCar)
|
|
{
|
|
bCreateAsMissionCar = true;
|
|
}
|
|
|
|
CVehicle *pVehicle = NULL;
|
|
if(CVehicleFactory::carModelId != fwModelId::MI_INVALID)
|
|
{
|
|
#if VEHICLE_GLASS_SMASH_TEST
|
|
if (g_vehicleGlassSmashTest.m_smashTestAuto && pVehModelInfo)
|
|
{
|
|
static bool bShowVehicleName = false; // can turn this on from the debugger if we need to show the vehicle name (e.g. to catch a vehicle which crashes)
|
|
|
|
if (bShowVehicleName)
|
|
{
|
|
Displayf("creating \"%s\"", pVehModelInfo->GetModelName());
|
|
}
|
|
|
|
// [HACK GTAV]
|
|
if (stricmp(pVehModelInfo->GetModelName(), "blimp" ) == 0 || // don't create blimp during smash test
|
|
stricmp(pVehModelInfo->GetModelName(), "barracks") == 0 || // don't create barracks during smash test (crashes) -- see BS#919428
|
|
stricmp(pVehModelInfo->GetModelName(), "rdrcoch1") == 0 || // don't create rdrcoch1 during smash test (crashes) -- see BS#919198
|
|
stricmp(pVehModelInfo->GetModelName(), "rdrcoch2") == 0 || // don't create rdrcoch2 during smash test (crashes)
|
|
false)
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
#endif // VEHICLE_GLASS_SMASH_TEST
|
|
|
|
Matrix34 tempMat;
|
|
tempMat.Identity();
|
|
|
|
float fRotation = camInterface::GetDebugDirector().IsFreeCamActive() && bUseDebugCamRotation ? camInterface::GetHeading() : carDropRotation;
|
|
tempMat.RotateZ(fRotation);
|
|
|
|
tempMat.d = camInterface::GetDebugDirector().IsFreeCamActive() ? camInterface::GetPos() : VEC3V_TO_VECTOR3(CGameWorld::FindLocalPlayer()->GetTransform().GetPosition());
|
|
|
|
Vector3 vecCreateOffset = camInterface::GetFront();
|
|
vecCreateOffset.z = 0.0f;
|
|
vecCreateOffset.NormalizeSafe();
|
|
|
|
pVehicle = CreateCarAtMatrix(CVehicleFactory::carModelId, &tempMat, vecCreateOffset, bOnlyIfTheresRoom);
|
|
if( pVehicle )
|
|
{
|
|
pVehicle->GetPortalTracker()->ScanUntilProbeTrue();
|
|
|
|
//keep a record of the last created vehicle
|
|
if (CVehicleFactory::ms_pLastCreatedVehicle)
|
|
CVehicleFactory::ms_pLastLastCreatedVehicle = CVehicleFactory::ms_pLastCreatedVehicle;
|
|
CVehicleFactory::ms_pLastCreatedVehicle = pVehicle;
|
|
CVehicleFactory::ms_bForceHd = pVehicle->IsForcedHd();
|
|
CVehicleFactory::ms_fLodMult = pVehicle->GetLodMultiplier();
|
|
CVehicleFactory::ms_clampedRenderLod = pVehicle->GetClampedRenderLod();
|
|
|
|
if(bCreateAsPersonalCar)
|
|
{
|
|
CVehicleDebug::SetVehicleAsPersonalCB();
|
|
}
|
|
|
|
if (CVehicleFactory::ms_liverySlider)
|
|
{
|
|
float fMaxRange = -1.0f;
|
|
if(pVehicle->GetVehicleModelInfo()->GetVehicleFlag(CVehicleModelInfoFlags::FLAG_HAS_LIVERY))
|
|
fMaxRange = pVehicle->GetVehicleModelInfo()->GetLiveriesCount() - 1.0f;
|
|
|
|
CVehicleFactory::ms_liverySlider->SetRange(-1.0f, fMaxRange);
|
|
}
|
|
|
|
if (CVehicleFactory::ms_livery2Slider)
|
|
{
|
|
float fMaxRange = -1.0f;
|
|
if(pVehicle->GetVehicleModelInfo()->GetVehicleFlag(CVehicleModelInfoFlags::FLAG_HAS_LIVERY))
|
|
fMaxRange = pVehicle->GetVehicleModelInfo()->GetLiveries2Count() - 1.0f;
|
|
|
|
CVehicleFactory::ms_livery2Slider->SetRange(-1.0f, fMaxRange);
|
|
}
|
|
|
|
CVehicleFactory::VariationDebugColorChangeCB();
|
|
for (s32 i = 0; i <= VEH_LAST_EXTRA - VEH_EXTRA_1; ++i)
|
|
{
|
|
CVehicleFactory::ms_variationExtras[i] = CVehicleFactory::ms_pLastCreatedVehicle->GetIsExtraOn((eHierarchyId)(VEH_EXTRA_1 + i));
|
|
}
|
|
|
|
if (pVehicle->IsModded())
|
|
{
|
|
CVehicleFactory::VariationDebugUpdateMods();
|
|
}
|
|
|
|
|
|
if( sSpawnCarsWithNoBreaking &&
|
|
pVehicle->GetFragInst() )
|
|
{
|
|
pVehicle->GetFragInst()->SetDisableBreakable( true );
|
|
}
|
|
}
|
|
}
|
|
|
|
if(CVehicleFactory::trailerModelId != fwModelId::MI_INVALID && pVehicle)//should we add a trailer to this vehicle?
|
|
{
|
|
Assertf(pVehicle->GetBoneIndex(VEH_ATTACH) > -1, "Vehicle missing trailer attach point");
|
|
if(pVehicle->GetBoneIndex(VEH_ATTACH) > -1)//the vehicle must have an attach bone for this to work
|
|
{
|
|
Matrix34 tempMat;
|
|
tempMat.Identity();
|
|
tempMat.d = camInterface::GetDebugDirector().IsFreeCamActive() ? camInterface::GetPos() : VEC3V_TO_VECTOR3(CGameWorld::FindLocalPlayer()->GetTransform().GetPosition());
|
|
|
|
CVehicle* pTrailerVehicle = NULL;
|
|
if(CVehicleFactory::carModelId != fwModelId::MI_INVALID)
|
|
{
|
|
fwModelId trailerModelId((strLocalIndex(CVehicleFactory::trailerModelId)));
|
|
|
|
bool bForceLoad = false;
|
|
if(!CModelInfo::HaveAssetsLoaded(trailerModelId))
|
|
{
|
|
CModelInfo::RequestAssets(trailerModelId, STRFLAG_FORCE_LOAD|STRFLAG_PRIORITY_LOAD);
|
|
bForceLoad = true;
|
|
}
|
|
|
|
if(bForceLoad)
|
|
{
|
|
CStreaming::LoadAllRequestedObjects(true);
|
|
}
|
|
|
|
const bool bUseBiggerBoxesForCollisionTest = false;
|
|
pTrailerVehicle = CVehicleFactory::GetFactory()->CreateAndAttachTrailer(trailerModelId, pVehicle, tempMat, bCreateAsMissionCar ? ENTITY_OWNEDBY_SCRIPT : ENTITY_OWNEDBY_POPULATION, bCreateAsMissionCar ? POPTYPE_MISSION : POPTYPE_RANDOM_AMBIENT, bUseBiggerBoxesForCollisionTest);
|
|
}
|
|
|
|
//warp the trailer onto the vehicle
|
|
if(pTrailerVehicle && pTrailerVehicle->GetVehicleType() == VEHICLE_TYPE_TRAILER)
|
|
{
|
|
pTrailerVehicle->GetPortalTracker()->ScanUntilProbeTrue();
|
|
|
|
CTrailer* pTrailer = static_cast<CTrailer*>(pTrailerVehicle);
|
|
|
|
// create cars on trailer
|
|
if (sSpawnCarsOnTrailer)
|
|
{
|
|
if (pTrailer->GetVehicleModelInfo()->GetVehicleFlag(CVehicleModelInfoFlags::FLAG_SPAWN_BOAT_ON_TRAILER))
|
|
{
|
|
fwModelId boats[3] =
|
|
{
|
|
CModelInfo::GetModelIdFromName("squalo"),
|
|
CModelInfo::GetModelIdFromName("dinghy"),
|
|
CModelInfo::GetModelIdFromName("tropic")
|
|
};
|
|
|
|
fwModelId b = boats[fwRandom::GetRandomNumberInRange(0,3)];
|
|
if (b.IsValid() && !CModelInfo::HaveAssetsLoaded(b))
|
|
{
|
|
CModelInfo::RequestAssets(b, STRFLAG_FORCE_LOAD | STRFLAG_DONTDELETE);
|
|
CStreaming::LoadAllRequestedObjects();
|
|
}
|
|
|
|
if (!CVehicleFactory::GetFactory()->AddBoatOnTrailer(pTrailer, CGameWorld::OUTSIDE, ENTITY_OWNEDBY_POPULATION, POPTYPE_RANDOM_PARKED, &b))
|
|
{
|
|
// We failed to create a boat. Check to see if we're still allowed to have this trailer
|
|
CVehicleFactory::DestroyBoatTrailerIfNecessary((CTrailer**)&pTrailer);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
CVehicleFactory::GetFactory()->AddCarsOnTrailer(pTrailer, CGameWorld::OUTSIDE, ENTITY_OWNEDBY_POPULATION, POPTYPE_RANDOM_PARKED, NULL);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void CreateCarCB()
|
|
{
|
|
CreateCar(false);
|
|
}
|
|
|
|
void CreateChosenCarCB(void)
|
|
{
|
|
Vector3 pos = camInterface::GetDebugDirector().IsFreeCamActive() ? camInterface::GetPos() : VEC3V_TO_VECTOR3(CGameWorld::FindLocalPlayer()->GetTransform().GetPosition());
|
|
Vector3 vecCreateOffset = camInterface::GetFront();
|
|
vecCreateOffset.z = 0.0f;
|
|
vecCreateOffset.NormalizeSafe();
|
|
vecCreateOffset *= 10.f;
|
|
pos += vecCreateOffset;
|
|
|
|
bool police = false;
|
|
CVehicleFactory::carModelId = CVehiclePopulation::ChooseModel(&police, pos, false, false, false, 0, false, false, 2);
|
|
|
|
CreateCarCB();
|
|
}
|
|
|
|
static void ExplodeCarCB(void)
|
|
{
|
|
if(CVehicleFactory::ms_pLastCreatedVehicle)
|
|
{
|
|
CVehicleFactory::ms_pLastCreatedVehicle->BlowUpCar(NULL, false, true, false);
|
|
}
|
|
}
|
|
|
|
static void DisableVehicleCollisionCB(void)
|
|
{
|
|
CVehicle* pVeh = CVehicleDebug::GetFocusVehicle();
|
|
if(!pVeh && CVehicleFactory::ms_pLastCreatedVehicle)
|
|
{
|
|
pVeh = CVehicleFactory::ms_pLastCreatedVehicle;
|
|
}
|
|
|
|
if(pVeh)
|
|
{
|
|
pVeh->DisableCollision();
|
|
}
|
|
}
|
|
|
|
static void DisableVehicleCollisionCompletelyCB(void)
|
|
{
|
|
CVehicle* pVeh = CVehicleDebug::GetFocusVehicle();
|
|
if(!pVeh && CVehicleFactory::ms_pLastCreatedVehicle)
|
|
{
|
|
pVeh = CVehicleFactory::ms_pLastCreatedVehicle;
|
|
}
|
|
|
|
if(pVeh)
|
|
{
|
|
pVeh->DisableCollision(NULL, true);
|
|
}
|
|
}
|
|
|
|
static void EnableVehicleCollisionCB(void)
|
|
{
|
|
CVehicle* pVeh = CVehicleDebug::GetFocusVehicle();
|
|
if(!pVeh && CVehicleFactory::ms_pLastCreatedVehicle)
|
|
{
|
|
pVeh = CVehicleFactory::ms_pLastCreatedVehicle;
|
|
}
|
|
|
|
if(pVeh)
|
|
{
|
|
pVeh->EnableCollision();
|
|
}
|
|
}
|
|
|
|
static void ResetCarSuspensionCB(void)
|
|
{
|
|
if(CVehicleFactory::ms_pLastCreatedVehicle)
|
|
{
|
|
for(int i=0; i<CVehicleFactory::ms_pLastCreatedVehicle->GetNumWheels(); i++)
|
|
CVehicleFactory::ms_pLastCreatedVehicle->GetWheel(i)->Reset(false);
|
|
}
|
|
}
|
|
|
|
#if __DEV
|
|
static void ChangePetrolTankLevelCarCB(void)
|
|
{
|
|
if(CVehicleFactory::ms_pLastCreatedVehicle)
|
|
{
|
|
CVehicleFactory::ms_pLastCreatedVehicle->GetVehicleDamage()->SetPetrolTankLevel(sfPetrolTankLevel);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
static void SetVehicleOnFire(CVehicle* pVeh)
|
|
{
|
|
if(!pVeh)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if(g_fireMan.IsEntityOnFire(pVeh))
|
|
{
|
|
return;
|
|
}
|
|
|
|
int nFireBoneIndex = pVeh->GetBoneIndex(VEH_ENGINE);
|
|
if(nFireBoneIndex < 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
Matrix34 mFireBone;
|
|
pVeh->GetGlobalMtx(nFireBoneIndex, mFireBone);
|
|
|
|
const float fBurnTime = fwRandom::GetRandomNumberInRange(20.0f, 35.0f);
|
|
const float fBurnStrength = fwRandom::GetRandomNumberInRange(0.75f, 1.0f);
|
|
const float fPeakTime = fwRandom::GetRandomNumberInRange(0.5f, 1.0f);
|
|
|
|
// Start vehicle fire
|
|
Vec3V vPosLcl = CVfxHelper::GetLocalEntityPos(*pVeh, RCC_VEC3V(mFireBone.d));
|
|
Vec3V vNormLcl = CVfxHelper::GetLocalEntityDir(*pVeh, Vec3V(V_Z_AXIS_WZERO));
|
|
|
|
g_fireMan.StartVehicleFire(pVeh, -1, vPosLcl, vNormLcl, CGameWorld::FindLocalPlayer(), fBurnTime, fBurnStrength, fPeakTime, FIRE_DEFAULT_NUM_GENERATIONS, Vec3V(V_ZERO), BANK_ONLY(Vec3V(V_ZERO),) false);
|
|
}
|
|
|
|
static void SetVehicleOnFireCB(void)
|
|
{
|
|
CVehicle* pVeh = CVehicleDebug::GetFocusVehicle();
|
|
if(!pVeh && CVehicleFactory::ms_pLastCreatedVehicle)
|
|
{
|
|
pVeh = CVehicleFactory::ms_pLastCreatedVehicle;
|
|
}
|
|
|
|
if(pVeh)
|
|
{
|
|
SetVehicleOnFire(pVeh);
|
|
}
|
|
}
|
|
|
|
static void SetVehicleOnFireAndClearHealthCB(void)
|
|
{
|
|
CVehicle* pVeh = CVehicleDebug::GetFocusVehicle();
|
|
if(!pVeh && CVehicleFactory::ms_pLastCreatedVehicle)
|
|
{
|
|
pVeh = CVehicleFactory::ms_pLastCreatedVehicle;
|
|
}
|
|
|
|
if(pVeh)
|
|
{
|
|
SetVehicleOnFire(pVeh);
|
|
pVeh->SetHealth(0.0f);
|
|
}
|
|
}
|
|
|
|
static void SetVehicleSearchlightCB(void)
|
|
{
|
|
CVehicle* pVeh = CVehicleDebug::GetFocusVehicle();
|
|
if(!pVeh && CVehicleFactory::ms_pLastCreatedVehicle)
|
|
{
|
|
pVeh = CVehicleFactory::ms_pLastCreatedVehicle;
|
|
}
|
|
|
|
if(pVeh)
|
|
{
|
|
CVehicleWeaponMgr* pWeaponMgr = pVeh->GetVehicleWeaponMgr();
|
|
if(pWeaponMgr)
|
|
{
|
|
for(int i = 0; i < pWeaponMgr->GetNumVehicleWeapons(); i++)
|
|
{
|
|
CVehicleWeapon* pWeapon = pWeaponMgr->GetVehicleWeapon(i);
|
|
if(pWeapon)
|
|
{
|
|
if(pWeapon->GetType() == VGT_SEARCHLIGHT)
|
|
{
|
|
CSearchLight* pSearchLight = static_cast<CSearchLight*>(pWeapon);
|
|
bool bLightToggle = !pSearchLight->GetLightOn();
|
|
pSearchLight->SetLightOn(bLightToggle);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void DeleteCarCB(void)
|
|
{
|
|
if(CVehicleFactory::ms_pLastCreatedVehicle)
|
|
{
|
|
g_ptFxManager.RemovePtFxFromEntity(CVehicleFactory::ms_pLastCreatedVehicle);
|
|
|
|
CVehicleFactory::GetFactory()->Destroy(CVehicleFactory::ms_pLastCreatedVehicle);
|
|
CVehicleFactory::ms_pLastCreatedVehicle = NULL;
|
|
CVehicleFactory::ms_bForceHd = false;
|
|
CVehicleFactory::ms_fLodMult = 1.f;
|
|
CVehicleFactory::ms_clampedRenderLod = -1;
|
|
|
|
// Obbe was going to tell me how to stream the car out again, but he left
|
|
// if(pModelInfo->GetNumRefs()==0)
|
|
// {
|
|
// CStreaming::D
|
|
// }
|
|
}
|
|
}
|
|
|
|
void CreateNextCar(bool bOnlyIfTheresRoom)
|
|
{
|
|
// delete existing car if it exists - this widget is meant for cycling through vehicles
|
|
DeleteCarCB();
|
|
|
|
CVehicleFactory::currVehicleNameSelection++;
|
|
if(CVehicleFactory::currVehicleNameSelection >= numVehicleNames)
|
|
{
|
|
atDisplayf("Last vehicle has been loaded.");
|
|
CVehicleFactory::currVehicleNameSelection = 0;
|
|
}
|
|
CVehicleFactory::CarNumChangeCB();
|
|
CVehicleFactory::TrailerNumChangeCB();
|
|
|
|
CreateCar(bOnlyIfTheresRoom);
|
|
}
|
|
|
|
void CreateNextCarCB(void)
|
|
{
|
|
CreateNextCar(false);
|
|
}
|
|
|
|
void CreateNextBikeCB(void)
|
|
{
|
|
// delete existing car if it exists - this widget is meant for cycling through vehicles
|
|
DeleteCarCB();
|
|
|
|
int numVehiclesChecked = 0;
|
|
while(CVehicleFactory::currVehicleNameSelection < numCarsAvailable)
|
|
{
|
|
CVehicleFactory::currVehicleNameSelection++;
|
|
|
|
// Wrap around
|
|
if(CVehicleFactory::currVehicleNameSelection >= numCarsAvailable)
|
|
{
|
|
CVehicleFactory::currVehicleNameSelection = 0;
|
|
}
|
|
|
|
// Make sure we don't loop forever if a bike isn't found.
|
|
numVehiclesChecked++;
|
|
if(numVehiclesChecked >= numCarsAvailable)
|
|
{
|
|
CVehicleFactory::currVehicleNameSelection = 0;
|
|
break;
|
|
}
|
|
|
|
u32 carModelId = GetModelIndex(vehicleSorts[CVehicleFactory::currVehicleNameSelection]);
|
|
|
|
if (carModelId != fwModelId::MI_INVALID)
|
|
{
|
|
CVehicleModelInfo* mi = (CVehicleModelInfo*)CModelInfo::GetBaseModelInfo(fwModelId(strLocalIndex(carModelId)));
|
|
|
|
if(mi->GetIsBike())// Have we found a bike?
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
CVehicleFactory::CarNumChangeCB();
|
|
CVehicleFactory::TrailerNumChangeCB();
|
|
|
|
CreateCarCB();
|
|
}
|
|
|
|
void CycleNextColourCB()
|
|
{
|
|
if(CVehicleFactory::ms_pLastCreatedVehicle)
|
|
{
|
|
u8 nNewColour1, nNewColour2, nNewColour3, nNewColour4, nNewColour5, nNewColour6;
|
|
CVehicleFactory::ms_pLastCreatedVehicle->GetVehicleModelInfo()->ChooseVehicleColour(nNewColour1, nNewColour2, nNewColour3, nNewColour4, nNewColour5, nNewColour6, 1);
|
|
|
|
CVehicleFactory::ms_pLastCreatedVehicle->SetBodyColour1(nNewColour1);
|
|
CVehicleFactory::ms_pLastCreatedVehicle->SetBodyColour2(nNewColour2);
|
|
CVehicleFactory::ms_pLastCreatedVehicle->SetBodyColour3(nNewColour3);
|
|
CVehicleFactory::ms_pLastCreatedVehicle->SetBodyColour4(nNewColour4);
|
|
CVehicleFactory::ms_pLastCreatedVehicle->SetBodyColour5(nNewColour5);
|
|
CVehicleFactory::ms_pLastCreatedVehicle->SetBodyColour6(nNewColour6);
|
|
|
|
// let shaders know, that body colours changed
|
|
CVehicleFactory::ms_pLastCreatedVehicle->UpdateBodyColourRemapping();
|
|
}
|
|
}
|
|
|
|
void ChooseColorCB()
|
|
{
|
|
CVehicle* veh = NULL;
|
|
CEntity* selected = (CEntity*)g_PickerManager.GetSelectedEntity();
|
|
if (selected && selected->GetIsTypeVehicle())
|
|
veh = (CVehicle*)selected;
|
|
|
|
if (!veh)
|
|
veh = CVehicleFactory::ms_pLastCreatedVehicle;
|
|
|
|
if(veh)
|
|
{
|
|
u8 nNewColour1, nNewColour2, nNewColour3, nNewColour4, nNewColour5, nNewColour6;
|
|
veh->GetVehicleModelInfo()->ChooseVehicleColourFancy(veh, nNewColour1, nNewColour2, nNewColour3, nNewColour4, nNewColour5, nNewColour6);
|
|
|
|
veh->SetBodyColour1(nNewColour1);
|
|
veh->SetBodyColour2(nNewColour2);
|
|
veh->SetBodyColour3(nNewColour3);
|
|
veh->SetBodyColour4(nNewColour4);
|
|
veh->SetBodyColour5(nNewColour5);
|
|
veh->SetBodyColour6(nNewColour6);
|
|
|
|
// let shaders know, that body colours changed
|
|
veh->UpdateBodyColourRemapping();
|
|
}
|
|
}
|
|
|
|
fiStream *pLayoutsFile = NULL;
|
|
fiStream *pMinSeatHeightFile = NULL;
|
|
|
|
void VehicleModelInfoIterator(CVehicleModelInfo *pVehicleModelInfo)
|
|
{
|
|
Displayf("%s...", pVehicleModelInfo->GetModelName());
|
|
|
|
char szBuffer[256]; szBuffer[0] = '\0';
|
|
|
|
fwModelId vehicleModelId; fwArchetypeManager::GetArchetypeFromHashKey(pVehicleModelInfo->GetModelNameHash(), vehicleModelId);
|
|
CModelInfo::RequestAssets(vehicleModelId, STRFLAG_DONTDELETE | STRFLAG_FORCE_LOAD | STRFLAG_PRIORITY_LOAD);
|
|
CStreaming::LoadAllRequestedObjects(true);
|
|
Assert(CModelInfo::HaveAssetsLoaded(vehicleModelId));
|
|
|
|
Matrix34 mVehicle; mVehicle.Identity();
|
|
CVehicle *pVehicle = CVehicleFactory::GetFactory()->Create(vehicleModelId, ENTITY_OWNEDBY_DEBUG, POPTYPE_TOOL, &mVehicle, false, true);
|
|
Assert(pVehicle);
|
|
|
|
sprintf(szBuffer, "%s", pVehicleModelInfo->GetModelName());
|
|
pLayoutsFile->WriteByte(szBuffer, istrlen(szBuffer));
|
|
|
|
const CVehicleLayoutInfo *pVehicleLayoutInfo = pVehicleModelInfo->GetVehicleLayoutInfo();
|
|
const CModelSeatInfo *pModelSeatInfo = pVehicleModelInfo->GetModelSeatInfo();
|
|
if(pVehicleLayoutInfo && pModelSeatInfo)
|
|
{
|
|
const char *szVehiclePack = pVehicleModelInfo->GetVehicleDLCPack().TryGetCStr();
|
|
|
|
const char *szVehicleType;
|
|
switch(pVehicle->GetVehicleType())
|
|
{
|
|
case VEHICLE_TYPE_CAR : szVehicleType = "VEHICLE_TYPE_CAR" ; break;
|
|
case VEHICLE_TYPE_PLANE : szVehicleType = "VEHICLE_TYPE_PLANE" ; break;
|
|
case VEHICLE_TYPE_TRAILER : szVehicleType = "VEHICLE_TYPE_TRAILER" ; break;
|
|
case VEHICLE_TYPE_QUADBIKE : szVehicleType = "VEHICLE_TYPE_QUADBIKE" ; break;
|
|
case VEHICLE_TYPE_DRAFT : szVehicleType = "VEHICLE_TYPE_DRAFT" ; break;
|
|
case VEHICLE_TYPE_SUBMARINECAR : szVehicleType = "VEHICLE_TYPE_SUBMARINECAR" ; break;
|
|
case VEHICLE_TYPE_AMPHIBIOUS_AUTOMOBILE : szVehicleType = "VEHICLE_TYPE_AMPHIBIOUS_AUTOMOBILE" ; break;
|
|
case VEHICLE_TYPE_AMPHIBIOUS_QUADBIKE : szVehicleType = "VEHICLE_TYPE_AMPHIBIOUS_QUADBIKE" ; break;
|
|
case VEHICLE_TYPE_HELI : szVehicleType = "VEHICLE_TYPE_HELI" ; break;
|
|
case VEHICLE_TYPE_BLIMP : szVehicleType = "VEHICLE_TYPE_BLIMP" ; break;
|
|
case VEHICLE_TYPE_AUTOGYRO : szVehicleType = "VEHICLE_TYPE_AUTOGYRO" ; break;
|
|
case VEHICLE_TYPE_BIKE : szVehicleType = "VEHICLE_TYPE_BIKE" ; break;
|
|
case VEHICLE_TYPE_BICYCLE : szVehicleType = "VEHICLE_TYPE_BICYCLE" ; break;
|
|
case VEHICLE_TYPE_BOAT : szVehicleType = "VEHICLE_TYPE_BOAT" ; break;
|
|
case VEHICLE_TYPE_TRAIN : szVehicleType = "VEHICLE_TYPE_TRAIN" ; break;
|
|
case VEHICLE_TYPE_SUBMARINE : szVehicleType = "VEHICLE_TYPE_SUBMARINE" ; break;
|
|
default:
|
|
{
|
|
Assert(false);
|
|
szVehicleType = "UNKNOWN";
|
|
} break;
|
|
}
|
|
|
|
sprintf(szBuffer, ",%s,%s,%s,%s", szVehiclePack, szVehicleType, pVehicle->CarHasRoof() ? "TRUE" : "FALSE", pVehicleLayoutInfo->GetName().TryGetCStr());
|
|
pLayoutsFile->WriteByte(szBuffer, istrlen(szBuffer));
|
|
|
|
s32 iNumSeatsLayout = pVehicleLayoutInfo->GetNumSeats();
|
|
s32 iNumSeatsActual = pModelSeatInfo->GetNumSeats();
|
|
sprintf(szBuffer, ",%i,%i,%s", iNumSeatsLayout, iNumSeatsActual, iNumSeatsLayout == iNumSeatsActual ? "TRUE" : "FALSE");
|
|
pLayoutsFile->WriteByte(szBuffer, istrlen(szBuffer));
|
|
|
|
float fMinSeatHeight = pVehicleModelInfo->GetMinSeatHeight();
|
|
|
|
for(int i = 0, count = pModelSeatInfo->GetNumSeats(); i < count; i ++)
|
|
{
|
|
bool bHasHit = false;
|
|
float fHeight = 10.0f;
|
|
|
|
s32 seatBoneIdx = pModelSeatInfo->GetBoneIndexFromSeat(i);
|
|
if (seatBoneIdx >= 0)
|
|
{
|
|
Matrix34 mSeatTemp; pVehicle->GetGlobalMtx(seatBoneIdx, mSeatTemp);
|
|
Mat34V mSeat = RC_MAT34V(mSeatTemp);
|
|
Vec3V vSeat(V_ZERO); vSeat = Transform(mSeat, vSeat);
|
|
|
|
Vector3 startPosition = RC_VECTOR3(vSeat); startPosition.z += 0.6f;
|
|
Vector3 endPosition = RC_VECTOR3(vSeat); endPosition.z += 9.4f;
|
|
|
|
WorldProbe::CShapeTestProbeDesc probeTest;
|
|
WorldProbe::CShapeTestFixedResults<1> probeTestResults;
|
|
probeTest.SetResultsStructure(&probeTestResults);
|
|
probeTest.SetIncludeFlags(ArchetypeFlags::GTA_VEHICLE_TYPE);
|
|
probeTest.SetIsDirected(false);
|
|
probeTest.SetDomainForTest(WorldProbe::TEST_AGAINST_INDIVIDUAL_OBJECTS);
|
|
probeTest.SetIncludeEntity(pVehicle, WorldProbe::EIEO_DONT_ADD_VEHICLE_OCCUPANTS);
|
|
probeTest.SetStartAndEnd(startPosition, endPosition);
|
|
|
|
bHasHit = WorldProbe::GetShapeTestManager()->SubmitTest(probeTest);
|
|
if(bHasHit)
|
|
{
|
|
if(probeTestResults.GetNumHits() > 0)
|
|
{
|
|
WorldProbe::CShapeTestHitPoint &hitPoint = probeTestResults[0];
|
|
fHeight = (hitPoint.GetHitPosition().z - startPosition.z) + 0.6f;
|
|
}
|
|
}
|
|
|
|
if(fMinSeatHeight == -1.0f || fMinSeatHeight > fHeight)
|
|
{
|
|
fMinSeatHeight = fHeight;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
fHeight = -1.0f;
|
|
}
|
|
|
|
const CVehicleSeatInfo *pSeatInfo = pVehicleLayoutInfo->GetSeatInfo(i);
|
|
if(pSeatInfo)
|
|
{
|
|
sprintf(szBuffer, ",%s,%.3f,%.3f", pSeatInfo->GetName().TryGetCStr(), pSeatInfo->GetHairScale(), fHeight);
|
|
pLayoutsFile->WriteByte(szBuffer, istrlen(szBuffer));
|
|
}
|
|
}
|
|
|
|
if(pModelSeatInfo->GetNumSeats() > 0)
|
|
{
|
|
pVehicleModelInfo->SetMinSeatHeight(fMinSeatHeight);
|
|
|
|
sprintf(szBuffer, "%s,%.3f\n", pVehicleModelInfo->GetModelName(), fMinSeatHeight);
|
|
pMinSeatHeightFile->WriteByte(szBuffer, istrlen(szBuffer));
|
|
}
|
|
}
|
|
|
|
sprintf(szBuffer, "\n");
|
|
pLayoutsFile->WriteByte(szBuffer, istrlen(szBuffer));
|
|
|
|
CVehicleFactory::GetFactory()->Destroy(pVehicle); pVehicle = NULL;
|
|
|
|
CStreaming::ClearRequiredFlag(vehicleModelId.ConvertToStreamingIndex(), CModelInfo::GetStreamingModuleId(), STRFLAG_DONTDELETE);
|
|
}
|
|
|
|
void DumpVehicleLayoutsCB()
|
|
{
|
|
Displayf("Dumping vehicle layouts...");
|
|
|
|
ASSET.PushFolder(RS_PROJROOT);
|
|
|
|
// Open CSV file
|
|
pLayoutsFile = ASSET.Create("VehicleLayouts", "csv");
|
|
pMinSeatHeightFile = ASSET.Create("VehicleMinSeatHeights", "csv");
|
|
|
|
char szBuffer[256]; szBuffer[0] = '\0';
|
|
sprintf(szBuffer, "Model Name,Pack,Vehicle Type,Car Has Roof?,Layout Name, Seats (Layout), Seats (Validated), Matching Seat Data?\n");
|
|
pLayoutsFile->WriteByte(szBuffer, istrlen(szBuffer));
|
|
|
|
sprintf(szBuffer, "Vehicle,MinSeatHeight\n");
|
|
pMinSeatHeightFile->WriteByte(szBuffer, istrlen(szBuffer));
|
|
|
|
fwArchetypeDynamicFactory<CVehicleModelInfo>& vehModelInfoStore = CModelInfo::GetVehicleModelInfoStore();
|
|
vehModelInfoStore.ForAllItemsUsed(VehicleModelInfoIterator);
|
|
|
|
pLayoutsFile->Close(); pLayoutsFile = NULL;
|
|
pMinSeatHeightFile->Close(); pMinSeatHeightFile = NULL;
|
|
|
|
ASSET.PopFolder();
|
|
|
|
Displayf("Dumping vehicle layouts... done!");
|
|
}
|
|
|
|
void FireCarCB()
|
|
{
|
|
if(CVehicleFactory::ms_bRegenerateFireVehicle)
|
|
{
|
|
DeleteCarCB();
|
|
CreateCarCB();
|
|
}
|
|
else if(!CVehicleFactory::ms_pLastCreatedVehicle)
|
|
{
|
|
CreateCarCB();
|
|
}
|
|
|
|
if(CVehicleFactory::ms_pLastCreatedVehicle && sFireCarPos.IsNonZero())
|
|
{
|
|
Matrix34 matSet;
|
|
matSet.MakeRotateZ(sFireCarOrient.z);
|
|
matSet.RotateLocalX(sFireCarOrient.x);
|
|
matSet.RotateLocalY(sFireCarOrient.y);
|
|
matSet.d = sFireCarPos;
|
|
CVehicleFactory::ms_pLastCreatedVehicle->Teleport(matSet.d);
|
|
CVehicleFactory::ms_pLastCreatedVehicle->SetMatrix(matSet, true, true, true);
|
|
|
|
Vector3 vecSpeed = sFireCarDirn;
|
|
vecSpeed.NormalizeSafe(Vector3(1.0f,0.0f,0.0f));
|
|
vecSpeed.Scale(sFireCarVel);
|
|
CVehicleFactory::ms_pLastCreatedVehicle->SetVelocity(sFireCarVel * sFireCarDirn);
|
|
|
|
vecSpeed = svFireCarSpin;
|
|
matSet.Transform3x3(vecSpeed);
|
|
|
|
CVehicleFactory::ms_pLastCreatedVehicle->SetAngVelocity(svFireCarSpin);
|
|
|
|
}
|
|
}
|
|
|
|
void FireCarFromDebugCamCB()
|
|
{
|
|
const camFrame& freeCamFrame = camInterface::GetDebugDirector().GetFreeCamFrame();
|
|
sFireCarPos = freeCamFrame.GetPosition();
|
|
sFireCarDirn = freeCamFrame.GetFront();
|
|
|
|
FireCarCB();
|
|
}
|
|
|
|
|
|
|
|
#if ENABLE_CDEBUG
|
|
extern void DisplayObject(bool bDeletePrevious);
|
|
extern RegdEnt gpDisplayObject;
|
|
#endif // ENABLE_CDEBUG
|
|
|
|
void FireCarWithObjectCB()
|
|
{
|
|
if(CVehicleFactory::ms_bRegenerateFireVehicle)
|
|
{
|
|
DeleteCarCB();
|
|
CreateCarCB();
|
|
}
|
|
else if(!CVehicleFactory::ms_pLastCreatedVehicle)
|
|
{
|
|
CreateCarCB();
|
|
}
|
|
|
|
if(CVehicleFactory::ms_pLastCreatedVehicle && sFireCarPos.IsNonZero())
|
|
{
|
|
Matrix34 matSet;
|
|
matSet.MakeRotateZ(sFireCarOrient.z);
|
|
matSet.RotateLocalX(sFireCarOrient.x);
|
|
matSet.RotateLocalY(sFireCarOrient.y);
|
|
matSet.d = sFireCarPos;
|
|
CVehicleFactory::ms_pLastCreatedVehicle->Teleport(matSet.d);
|
|
CVehicleFactory::ms_pLastCreatedVehicle->SetMatrix(matSet, true, true, true);
|
|
|
|
Vector3 vecSpeed = sFireCarDirn;
|
|
vecSpeed.NormalizeSafe(Vector3(1.0f,0.0f,0.0f));
|
|
vecSpeed.Scale(sFireCarVel);
|
|
CVehicleFactory::ms_pLastCreatedVehicle->SetVelocity(sFireCarVel * sFireCarDirn);
|
|
|
|
vecSpeed = svFireCarSpin;
|
|
matSet.Transform3x3(vecSpeed);
|
|
|
|
CVehicleFactory::ms_pLastCreatedVehicle->SetAngVelocity(svFireCarSpin);
|
|
}
|
|
|
|
#if ENABLE_CDEBUG
|
|
DisplayObject(true);
|
|
|
|
if(gpDisplayObject && gpDisplayObject->GetIsPhysical())
|
|
{
|
|
CPhysical* pPhysicalObject = (CPhysical*)gpDisplayObject.Get();
|
|
Matrix34 matSet;
|
|
matSet.MakeRotateZ(sFireCarOrient.z);
|
|
|
|
Vector3 offset = sFireObjectOffset;
|
|
matSet.Transform3x3(offset);
|
|
matSet.d = sFireCarPos + offset;
|
|
|
|
pPhysicalObject->Teleport(matSet.d, true, false, true, false, true, false, true);
|
|
pPhysicalObject->SetMatrix(matSet, true, true, true);
|
|
}
|
|
#endif //ENABLE_CDEBUG
|
|
}
|
|
|
|
void FireCarWithObjectFromDebugCamCB()
|
|
{
|
|
const camFrame& freeCamFrame = camInterface::GetDebugDirector().GetFreeCamFrame();
|
|
sFireCarPos = freeCamFrame.GetPosition();
|
|
sFireCarDirn = freeCamFrame.GetFront();
|
|
|
|
FireCarWithObjectCB();
|
|
}
|
|
|
|
void FireCarOrientCB()
|
|
{
|
|
if(CVehicleFactory::ms_pLastCreatedVehicle && sFireCarPos.IsNonZero())
|
|
{
|
|
Matrix34 matSet;
|
|
matSet.MakeRotateZ(sFireCarOrient.z);
|
|
matSet.RotateLocalX(sFireCarOrient.x);
|
|
matSet.RotateLocalY(sFireCarOrient.y);
|
|
matSet.d = sFireCarPos;
|
|
CVehicleFactory::ms_pLastCreatedVehicle->Teleport(matSet.d);
|
|
CVehicleFactory::ms_pLastCreatedVehicle->SetMatrix(matSet, true, true, true);
|
|
|
|
CVehicleFactory::ms_pLastCreatedVehicle->DeActivatePhysics();
|
|
}
|
|
}
|
|
|
|
void FireCarForcePos()
|
|
{
|
|
if(CVehicleFactory::ms_pLastCreatedVehicle && sFireCarPos.IsNonZero())
|
|
{
|
|
Matrix34 matSet;
|
|
matSet.MakeRotateZ(sFireCarOrient.z);
|
|
matSet.RotateLocalX(sFireCarOrient.x);
|
|
matSet.RotateLocalY(sFireCarOrient.y);
|
|
matSet.d = sFireCarPos;
|
|
CVehicleFactory::ms_pLastCreatedVehicle->Teleport(matSet.d);
|
|
CVehicleFactory::ms_pLastCreatedVehicle->SetMatrix(matSet, true, true, true);
|
|
CVehicleFactory::ms_pLastCreatedVehicle->ActivatePhysics();
|
|
}
|
|
}
|
|
|
|
void FirePlayerRagdollCB()
|
|
{
|
|
if(CGameWorld::FindLocalPlayer() && !CGameWorld::FindLocalPlayer()->GetPedConfigFlag( CPED_CONFIG_FLAG_InVehicle ))
|
|
{
|
|
CPed* pPed = CGameWorld::FindLocalPlayer();
|
|
|
|
Matrix34 matSet;
|
|
matSet.MakeRotateZ(sFireCarOrient.z);
|
|
matSet.d = sFireCarPos;
|
|
pPed->Teleport(matSet.d, pPed->GetCurrentHeading(), false);
|
|
pPed->SetMatrix(matSet, true, true, true);
|
|
CPhysics::ClearManifoldsForInst(pPed->GetCurrentPhysicsInst());
|
|
|
|
CTaskNMBehaviour* pTaskNM = rage_new CTaskNMBalance(1000, 10000, NULL, 0);
|
|
CEventSwitch2NM event(10000, pTaskNM);
|
|
pTaskNM = NULL;
|
|
pPed->SwitchToRagdoll(event);
|
|
|
|
Vector3 vecSpeed = sFireCarDirn;
|
|
vecSpeed.NormalizeSafe(Vector3(1.0f,0.0f,0.0f));
|
|
vecSpeed.Scale(sFireCarVel);
|
|
pPed->SetVelocity(sFireCarVel * sFireCarDirn);
|
|
}
|
|
}
|
|
|
|
void FirePlayerRagdollFromDebugCamCB()
|
|
{
|
|
const camFrame& freeCamFrame = camInterface::GetDebugDirector().GetFreeCamFrame();
|
|
sFireCarPos = freeCamFrame.GetPosition();
|
|
sFireCarDirn = freeCamFrame.GetFront();
|
|
|
|
FirePlayerRagdollCB();
|
|
}
|
|
|
|
void FireObjectCB()
|
|
{
|
|
#if ENABLE_CDEBUG
|
|
DisplayObject(true);
|
|
|
|
if(gpDisplayObject && gpDisplayObject->GetIsPhysical())
|
|
{
|
|
CPhysical* pPhysicalObject = (CPhysical*)gpDisplayObject.Get();
|
|
Matrix34 matSet;
|
|
matSet.MakeRotateZ(sFireCarOrient.z);
|
|
matSet.d = sFireCarPos;
|
|
pPhysicalObject->Teleport(matSet.d, true, false, true, false, true, false, true);
|
|
pPhysicalObject->SetMatrix(matSet, true, true, true);
|
|
|
|
Vector3 vecSpeed = sFireCarDirn;
|
|
vecSpeed.NormalizeSafe(Vector3(1.0f,0.0f,0.0f));
|
|
vecSpeed.Scale(sFireCarVel);
|
|
|
|
if (fragInst* pFragInst = pPhysicalObject->GetFragInst())
|
|
{
|
|
pFragInst->BreakOffAboveGroup(0);
|
|
}
|
|
|
|
pPhysicalObject->SetVelocity(sFireCarVel * sFireCarDirn);
|
|
}
|
|
#endif // ENABLE_CDEBUG
|
|
}
|
|
|
|
void FireObjectFromDebugCamCB()
|
|
{
|
|
#if ENABLE_CDEBUG
|
|
const camFrame& freeCamFrame = camInterface::GetDebugDirector().GetFreeCamFrame();
|
|
sFireCarPos = freeCamFrame.GetPosition();
|
|
sFireCarDirn = freeCamFrame.GetFront();
|
|
|
|
FireObjectCB();
|
|
#endif // ENABLE_CDEBUG
|
|
}
|
|
|
|
const char* g_vehicleLaunchSettingsLocation = "C:\\VehicleLaunchSettings.txt";
|
|
void SaveSettingsCB()
|
|
{
|
|
// Open the file for writing
|
|
fiStream* stream = fiStream::Open(g_vehicleLaunchSettingsLocation, false);
|
|
if(!stream)
|
|
{
|
|
stream = fiStream::Create(g_vehicleLaunchSettingsLocation);
|
|
}
|
|
|
|
if(stream)
|
|
{
|
|
// Initialise the tokens
|
|
fiAsciiTokenizer token;
|
|
token.Init("launchSettings", stream);
|
|
|
|
// Write all the field names and values
|
|
|
|
// Vel
|
|
token.PutStrLine("Vel %f", sFireCarVel);
|
|
|
|
// Pos
|
|
token.PutStrLine("PosX %f", sFireCarPos.x);
|
|
token.PutStrLine("PosY %f", sFireCarPos.y);
|
|
token.PutStrLine("PosZ %f", sFireCarPos.z);
|
|
|
|
// Dir
|
|
token.PutStrLine("DirX %f", sFireCarDirn.x);
|
|
token.PutStrLine("DirY %f", sFireCarDirn.y);
|
|
token.PutStrLine("DirZ %f", sFireCarDirn.z);
|
|
|
|
// Orient
|
|
token.PutStrLine("OrientX %f", sFireCarOrient.x);
|
|
token.PutStrLine("OrientY %f", sFireCarOrient.y);
|
|
token.PutStrLine("OrientZ %f", sFireCarOrient.z);
|
|
|
|
// Offset
|
|
token.PutStrLine("OffsetX %f", sFireObjectOffset.x);
|
|
token.PutStrLine("OffsetY %f", sFireObjectOffset.y);
|
|
token.PutStrLine("OffsetZ %f", sFireObjectOffset.z);
|
|
|
|
stream->Close();
|
|
}
|
|
}
|
|
|
|
void LoadSettingsCB()
|
|
{
|
|
// Open the file for reading
|
|
fiStream* stream = fiStream::Open(g_vehicleLaunchSettingsLocation, true);
|
|
if(stream)
|
|
{
|
|
// Initialise the tokens
|
|
fiAsciiTokenizer token;
|
|
token.Init("launchSettings", stream);
|
|
|
|
// Read in all the field names and values
|
|
// We're just assuming everything will be there and in order - So just tossing the names rather than checking
|
|
char charBuff[128];
|
|
|
|
// Vel
|
|
token.GetToken(charBuff, 128);
|
|
sFireCarVel = token.GetFloat();
|
|
|
|
// PosX
|
|
token.GetToken(charBuff, 128);
|
|
sFireCarPos.x = token.GetFloat();
|
|
// PosY
|
|
token.GetToken(charBuff, 128);
|
|
sFireCarPos.y = token.GetFloat();
|
|
// PosZ
|
|
token.GetToken(charBuff, 128);
|
|
sFireCarPos.z = token.GetFloat();
|
|
|
|
// DirX
|
|
token.GetToken(charBuff, 128);
|
|
sFireCarDirn.x = token.GetFloat();
|
|
// DirY
|
|
token.GetToken(charBuff, 128);
|
|
sFireCarDirn.y = token.GetFloat();
|
|
// DirZ
|
|
token.GetToken(charBuff, 128);
|
|
sFireCarDirn.z = token.GetFloat();
|
|
|
|
// OrientX
|
|
token.GetToken(charBuff, 128);
|
|
sFireCarOrient.x = token.GetFloat();
|
|
// OrientY
|
|
token.GetToken(charBuff, 128);
|
|
sFireCarOrient.y = token.GetFloat();
|
|
// OrientZ
|
|
token.GetToken(charBuff, 128);
|
|
sFireCarOrient.z = token.GetFloat();
|
|
|
|
// OffsetX
|
|
token.GetToken(charBuff, 128);
|
|
sFireObjectOffset.x = token.GetFloat();
|
|
// OffsetY
|
|
token.GetToken(charBuff, 128);
|
|
sFireObjectOffset.y = token.GetFloat();
|
|
// OffsetZ
|
|
token.GetToken(charBuff, 128);
|
|
sFireObjectOffset.z = token.GetFloat();
|
|
|
|
stream->Close();
|
|
}
|
|
}
|
|
|
|
void DropFocusedVehicleAtCameraPosCB(void)
|
|
{
|
|
#if __DEV//def CAM_DEBUG
|
|
for(int i = 0; i < CDebugScene::FOCUS_ENTITIES_MAX; ++i)
|
|
{
|
|
CEntity* pEnt = CDebugScene::FocusEntities_Get(i);
|
|
if( pEnt && pEnt->GetIsTypeVehicle() )
|
|
{
|
|
CVehicle* pFocusVehicle = static_cast<CVehicle*>(pEnt);
|
|
|
|
camDebugDirector& debugDirector = camInterface::GetDebugDirector();
|
|
if(debugDirector.IsFreeCamActive())
|
|
{
|
|
const Vector3& pos = debugDirector.GetFreeCamFrame().GetPosition();
|
|
pFocusVehicle->Teleport(pos);
|
|
}
|
|
}
|
|
}
|
|
#endif // __DEV
|
|
}
|
|
|
|
void WarpPlayerIntoRecentCarCB()
|
|
{
|
|
CVehicle* pVehicle = CVehicleDebug::GetFocusVehicle();
|
|
if( pVehicle )
|
|
{
|
|
s32 seat = CVehicleFactory::ms_iSeatToEnter;
|
|
CPed* pPlayerPed = CGameWorld::FindLocalPlayer();
|
|
pPlayerPed->SetPedInVehicle(pVehicle, seat, CPed::PVF_IfForcedTestVehConversionCollision|CPed::PVF_Warp);
|
|
}
|
|
else if(CVehicleFactory::ms_pLastCreatedVehicle)
|
|
{
|
|
// skip the engine-start anim?
|
|
if (bVehicleInstantStartEngineOnWarp &&
|
|
!CVehicleFactory::ms_pLastCreatedVehicle->m_nVehicleFlags.bCarNeedsToBeHotwired)
|
|
CVehicleFactory::ms_pLastCreatedVehicle->SwitchEngineOn(true);
|
|
|
|
CPed* pPlayerPed = CGameWorld::FindLocalPlayer();
|
|
s32 seat = -1;
|
|
if( pPlayerPed->GetPedConfigFlag( CPED_CONFIG_FLAG_InVehicle ) &&
|
|
pPlayerPed->GetMyVehicle() )
|
|
{
|
|
seat = pPlayerPed->GetMyVehicle()->GetSeatManager()->GetPedsSeatIndex(pPlayerPed);
|
|
pPlayerPed->SetPedOutOfVehicle(CPed::PVF_Warp);
|
|
if( CVehicleFactory::ms_pLastCreatedVehicle != pPlayerPed->GetMyVehicle() )
|
|
{
|
|
seat = 0;
|
|
}
|
|
else
|
|
{
|
|
++seat;
|
|
if( seat >= pPlayerPed->GetMyVehicle()->GetSeatManager()->GetMaxSeats() )
|
|
seat = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pPlayerPed->GetPedIntelligence()->FlushImmediately();
|
|
seat = 0;
|
|
}
|
|
pPlayerPed->SetPedInVehicle(CVehicleFactory::ms_pLastCreatedVehicle, seat, CPed::PVF_IfForcedTestVehConversionCollision|CPed::PVF_Warp);
|
|
}
|
|
}
|
|
|
|
|
|
void WarpPlayerOutOfCarCB()
|
|
{
|
|
if(CVehicleFactory::ms_pLastCreatedVehicle)
|
|
{
|
|
CPed* pPlayerPed = CGameWorld::FindLocalPlayer();
|
|
pPlayerPed->SetPedOutOfVehicle(CPed::PVF_Warp);
|
|
}
|
|
}
|
|
|
|
void SetLaunchDirectionMatchOrientationCB()
|
|
{
|
|
Matrix34 matSet;
|
|
matSet.MakeRotateZ(sFireCarOrient.z);
|
|
matSet.RotateLocalX(sFireCarOrient.x);
|
|
matSet.RotateLocalY(sFireCarOrient.y);
|
|
|
|
sFireCarDirn = matSet.b;
|
|
}
|
|
|
|
void FireCarWithPlayerCB()
|
|
{
|
|
if(CVehicleFactory::ms_bRegenerateFireVehicle)
|
|
{
|
|
DeleteCarCB();
|
|
CreateCarCB();
|
|
}
|
|
else if(!CVehicleFactory::ms_pLastCreatedVehicle)
|
|
{
|
|
CreateCarCB();
|
|
}
|
|
|
|
if(CVehicleFactory::ms_pLastCreatedVehicle && sFireCarPos.IsNonZero())
|
|
{
|
|
|
|
WarpPlayerIntoRecentCarCB();
|
|
|
|
Matrix34 matSet;
|
|
matSet.MakeRotateZ(sFireCarOrient.z);
|
|
matSet.RotateLocalX(sFireCarOrient.x);
|
|
matSet.RotateLocalY(sFireCarOrient.y);
|
|
matSet.d = sFireCarPos;
|
|
CVehicleFactory::ms_pLastCreatedVehicle->Teleport(matSet.d);
|
|
CVehicleFactory::ms_pLastCreatedVehicle->SetMatrix(matSet, true, true, true);
|
|
|
|
Vector3 vecSpeed = sFireCarDirn;
|
|
vecSpeed.NormalizeSafe(Vector3(1.0f,0.0f,0.0f));
|
|
vecSpeed.Scale(sFireCarVel);
|
|
CVehicleFactory::ms_pLastCreatedVehicle->SetVelocity(sFireCarVel * sFireCarDirn);
|
|
|
|
vecSpeed = svFireCarSpin;
|
|
matSet.Transform3x3(vecSpeed);
|
|
|
|
CVehicleFactory::ms_pLastCreatedVehicle->SetAngVelocity(svFireCarSpin);
|
|
}
|
|
}
|
|
|
|
void FireCarWithPlayerFromDebugCamCB()
|
|
{
|
|
const camFrame& freeCamFrame = camInterface::GetDebugDirector().GetFreeCamFrame();
|
|
sFireCarPos = freeCamFrame.GetPosition();
|
|
sFireCarDirn = freeCamFrame.GetFront();
|
|
|
|
FireCarWithPlayerCB();
|
|
}
|
|
|
|
void GetPlayerToEnterSeat()
|
|
{
|
|
CPed* pPlayerPed = CGameWorld::FindLocalPlayer();
|
|
if( pPlayerPed && CVehicleFactory::ms_pLastCreatedVehicle)
|
|
{
|
|
s32 seat = CVehicleFactory::ms_iSeatToEnter;
|
|
|
|
// Return to the vehicle
|
|
pPlayerPed->GetPedIntelligence()->AddTaskAtPriority( rage_new CTaskEnterVehicle(CVehicleFactory::ms_pLastCreatedVehicle, SR_Specific, seat), PED_TASK_PRIORITY_PRIMARY);
|
|
}
|
|
}
|
|
|
|
void GetFocusPedToEnterSeat()
|
|
{
|
|
for(int i = 0; i < CDebugScene::FOCUS_ENTITIES_MAX; ++i)
|
|
{
|
|
CEntity* pEnt = CDebugScene::FocusEntities_Get(i);
|
|
if( pEnt && pEnt->GetIsTypePed() )
|
|
{
|
|
CPed* pFocusPed = static_cast<CPed*>(pEnt);
|
|
if( pFocusPed && CVehicleFactory::ms_pLastCreatedVehicle)
|
|
{
|
|
// Return to the vehicle
|
|
pFocusPed->GetPedIntelligence()->AddTaskAtPriority(rage_new CTaskEnterVehicle(CVehicleFactory::ms_pLastCreatedVehicle, SR_Specific, CVehicleFactory::ms_iSeatToEnter), PED_TASK_PRIORITY_PRIMARY);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void FireVehiclesRocketCB()
|
|
{
|
|
CVehicle* pVehicle = CVehicleDebug::GetFocusVehicle();
|
|
if(!pVehicle && CVehicleFactory::ms_pLastCreatedVehicle)
|
|
{
|
|
pVehicle = CVehicleFactory::ms_pLastCreatedVehicle;
|
|
}
|
|
|
|
if(pVehicle)
|
|
{
|
|
CPed* pLocalPlayer = CGameWorld::FindLocalPlayer();
|
|
|
|
if(!pVehicle->GetVehicleWeaponMgr())
|
|
{
|
|
pVehicle->CreateVehicleWeaponMgr();
|
|
}
|
|
|
|
CVehicleWeaponMgr* pVehWeaponMgr = pVehicle->GetVehicleWeaponMgr();
|
|
|
|
if(pVehWeaponMgr)
|
|
{
|
|
s32 seatIndex = 0; //Assume 0 is weapon firers seat
|
|
|
|
s32 numWeapons = pVehWeaponMgr->GetNumWeaponsForSeat(seatIndex);
|
|
CVehicleWeapon* pVehicleProjectileWeapon = NULL;
|
|
|
|
if( numWeapons > 0 )
|
|
{
|
|
atArray<CVehicleWeapon*> weaponArray;
|
|
pVehicle->GetVehicleWeaponMgr()->GetWeaponsForSeat(seatIndex,weaponArray);
|
|
|
|
for(int weaponIndex=0; weaponIndex<numWeapons;weaponIndex++)
|
|
{
|
|
CVehicleWeapon* pVehicleWeapon = weaponArray[weaponIndex];
|
|
const CWeaponInfo* pWeaponInfo = pVehicleWeapon->GetWeaponInfo();
|
|
|
|
if(pWeaponInfo && pWeaponInfo->GetIsProjectile())
|
|
{
|
|
pVehicleProjectileWeapon = pVehicleWeapon;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (pVehicleProjectileWeapon)
|
|
{
|
|
pVehicleProjectileWeapon->Fire(pLocalPlayer,pVehicle,VEC3_ZERO,NULL, true); //
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void SetEngineHealthCB()
|
|
{
|
|
CEntity* pEnt = CDebugScene::FocusEntities_Get(0);
|
|
if (pEnt && pEnt->GetIsTypeVehicle())
|
|
{
|
|
CVehicle* pVehicle = static_cast<CVehicle*>(pEnt);
|
|
pVehicle->GetVehicleDamage()->SetEngineHealth(CVehicleFactory::ms_fSetEngineNewHealth);
|
|
}
|
|
}
|
|
|
|
|
|
void breakOffLeftWingCB()
|
|
{
|
|
CVehicle* pVehicle = CVehicleDebug::GetFocusVehicle();
|
|
if(!pVehicle && CVehicleFactory::ms_pLastCreatedVehicle)
|
|
{
|
|
pVehicle = CVehicleFactory::ms_pLastCreatedVehicle;
|
|
}
|
|
|
|
if(pVehicle && pVehicle->InheritsFromPlane())
|
|
{
|
|
CPlane* pPlane = static_cast<CPlane*>(pVehicle);
|
|
pPlane->GetAircraftDamage().BreakOffSection(pPlane, CAircraftDamage::WING_L);
|
|
}
|
|
}
|
|
|
|
void breakOffRightWingCB()
|
|
{
|
|
CVehicle* pVehicle = CVehicleDebug::GetFocusVehicle();
|
|
if(!pVehicle && CVehicleFactory::ms_pLastCreatedVehicle)
|
|
{
|
|
pVehicle = CVehicleFactory::ms_pLastCreatedVehicle;
|
|
}
|
|
|
|
if(pVehicle && pVehicle->InheritsFromPlane())
|
|
{
|
|
CPlane* pPlane = static_cast<CPlane*>(pVehicle);
|
|
pPlane->GetAircraftDamage().BreakOffSection(pPlane, CAircraftDamage::WING_R);
|
|
}
|
|
}
|
|
|
|
void removeLandingGearCB()
|
|
{
|
|
CVehicle* pVehicle = CVehicleDebug::GetFocusVehicle();
|
|
if(!pVehicle && CVehicleFactory::ms_pLastCreatedVehicle)
|
|
{
|
|
pVehicle = CVehicleFactory::ms_pLastCreatedVehicle;
|
|
}
|
|
|
|
if(pVehicle && pVehicle->InheritsFromPlane())
|
|
{
|
|
CPlane* pPlane = static_cast<CPlane*>(pVehicle);
|
|
pPlane->GetLandingGear().ControlLandingGear(pPlane,CLandingGear::COMMAND_RETRACT_INSTANT);
|
|
}
|
|
else if( pVehicle && pVehicle->InheritsFromHeli() )
|
|
{
|
|
CHeli* pHeli = static_cast<CHeli*>( pVehicle );
|
|
|
|
if( pHeli->HasLandingGear() )
|
|
{
|
|
pHeli->GetLandingGear().ControlLandingGear( pHeli, CLandingGear::COMMAND_RETRACT_INSTANT );
|
|
}
|
|
}
|
|
}
|
|
|
|
void randomlyOpenAndCloseDoorsCB()
|
|
{
|
|
CVehicle* pVehicle = CVehicleDebug::GetFocusVehicle();
|
|
if(!pVehicle && CVehicleFactory::ms_pLastCreatedVehicle)
|
|
{
|
|
pVehicle = CVehicleFactory::ms_pLastCreatedVehicle;
|
|
}
|
|
|
|
if(pVehicle)
|
|
{
|
|
for(int d=0; d<pVehicle->GetNumDoors(); d++)
|
|
{
|
|
CCarDoor * pDoor = pVehicle->GetDoor(d);
|
|
const float fRatio = fwRandom::GetRandomNumberInRange(0.0f,1.0f);
|
|
pDoor->SetTargetDoorOpenRatio(fRatio, CCarDoor::DRIVEN_NORESET);
|
|
}
|
|
}
|
|
}
|
|
|
|
void setOutOfControlCB()
|
|
{
|
|
CVehicle* pVehicle = CVehicleDebug::GetFocusVehicle();
|
|
if(!pVehicle && CVehicleFactory::ms_pLastCreatedVehicle)
|
|
{
|
|
pVehicle = CVehicleFactory::ms_pLastCreatedVehicle;
|
|
}
|
|
|
|
if(pVehicle)
|
|
{
|
|
pVehicle->SetIsOutOfControl();
|
|
}
|
|
}
|
|
|
|
void openRoofCB()
|
|
{
|
|
if(CVehicleFactory::ms_pLastCreatedVehicle)
|
|
{
|
|
CTaskVehicleConvertibleRoof *convertibleRoof= rage_new CTaskVehicleConvertibleRoof();
|
|
convertibleRoof->SetState(CTaskVehicleConvertibleRoof::State_Lower_Roof);
|
|
CVehicleFactory::ms_pLastCreatedVehicle->GetIntelligence()->GetTaskManager()->GetTree(VEHICLE_TASK_TREE_SECONDARY)->SetTask(convertibleRoof, VEHICLE_TASK_SECONDARY_ANIM);
|
|
}
|
|
}
|
|
|
|
void closeRoofCB()
|
|
{
|
|
if(CVehicleFactory::ms_pLastCreatedVehicle)
|
|
{
|
|
CTaskVehicleConvertibleRoof *convertibleRoof= rage_new CTaskVehicleConvertibleRoof();
|
|
convertibleRoof->SetState(CTaskVehicleConvertibleRoof::State_Raise_Roof);
|
|
CVehicleFactory::ms_pLastCreatedVehicle->GetIntelligence()->GetTaskManager()->GetTree(VEHICLE_TASK_TREE_SECONDARY)->SetTask(convertibleRoof, VEHICLE_TASK_SECONDARY_ANIM);
|
|
}
|
|
}
|
|
|
|
void triggerCarAlarmCB()
|
|
{
|
|
if(CVehicleFactory::ms_pLastCreatedVehicle)
|
|
{
|
|
CVehicleFactory::ms_pLastCreatedVehicle->TriggerCarAlarm();
|
|
}
|
|
}
|
|
|
|
void outputDoorStuckDebugCB()
|
|
{
|
|
CPed *pPlayerPed = CPedFactory::GetFactory()->GetLocalPlayer();
|
|
if(pPlayerPed)
|
|
{
|
|
if(pPlayerPed->GetMyVehicle() && pPlayerPed->GetMyVehicle()->InheritsFromAutomobile())
|
|
{
|
|
CAutomobile *pPlayerVeh = static_cast<CAutomobile *>(pPlayerPed->GetMyVehicle());
|
|
for(int nDoor = 0; nDoor < pPlayerVeh->GetNumDoors(); ++nDoor)
|
|
{
|
|
CCarDoor *pDoor = pPlayerVeh->GetDoor(nDoor);
|
|
if(pDoor)
|
|
{
|
|
pDoor->OutputDoorStuckDebug();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void deployFoldingWingsCB()
|
|
{
|
|
if(CVehicleFactory::ms_pLastCreatedVehicle)
|
|
{
|
|
CVehicleFactory::ms_pLastCreatedVehicle->DeployFoldingWings(!CVehicleFactory::ms_pLastCreatedVehicle->GetAreFoldingWingsDeployed(),false);
|
|
}
|
|
}
|
|
|
|
void lowerRoofCB()
|
|
{
|
|
if(CVehicleFactory::ms_pLastCreatedVehicle)
|
|
{
|
|
CVehicleFactory::ms_pLastCreatedVehicle->LowerConvertibleRoof(bLowerOrRaiseRoofInstantly);
|
|
}
|
|
}
|
|
|
|
void raiseRoofCB()
|
|
{
|
|
if(CVehicleFactory::ms_pLastCreatedVehicle)
|
|
{
|
|
CVehicleFactory::ms_pLastCreatedVehicle->RaiseConvertibleRoof(bLowerOrRaiseRoofInstantly);
|
|
}
|
|
}
|
|
|
|
void openDoorCB()
|
|
{
|
|
CVehicle* pVehicle = CVehicleDebug::GetFocusVehicle();
|
|
if(!pVehicle && CVehicleFactory::ms_pLastCreatedVehicle)
|
|
{
|
|
pVehicle = CVehicleFactory::ms_pLastCreatedVehicle;
|
|
}
|
|
|
|
if(pVehicle)
|
|
{
|
|
CCarDoor * pDoor = pVehicle->GetDoorFromId(CVehicleModelInfo::GetSetupDoorIds()[CVehicleFactory::ms_iDoorToOpen]);
|
|
|
|
if(pDoor && pDoor->GetIsIntact(pVehicle))
|
|
{
|
|
pDoor->SetTargetDoorOpenRatio(sDoorOpenAmount, bDoorCanBeReset ? CCarDoor::DRIVEN_AUTORESET :CCarDoor::DRIVEN_NORESET, pVehicle);
|
|
}
|
|
}
|
|
}
|
|
|
|
void closeDoorCB()
|
|
{
|
|
CVehicle* pVehicle = CVehicleDebug::GetFocusVehicle();
|
|
if(!pVehicle && CVehicleFactory::ms_pLastCreatedVehicle)
|
|
{
|
|
pVehicle = CVehicleFactory::ms_pLastCreatedVehicle;
|
|
}
|
|
|
|
if(pVehicle)
|
|
{
|
|
CCarDoor * pDoor = pVehicle->GetDoorFromId(CVehicleModelInfo::GetSetupDoorIds()[CVehicleFactory::ms_iDoorToOpen]);
|
|
|
|
if(pDoor && pDoor->GetIsIntact(pVehicle))
|
|
{
|
|
pDoor->SetShutAndLatched(pVehicle);
|
|
}
|
|
}
|
|
}
|
|
|
|
void unlatchDoorCB()
|
|
{
|
|
CVehicle* pVehicle = CVehicleDebug::GetFocusVehicle();
|
|
if(!pVehicle && CVehicleFactory::ms_pLastCreatedVehicle)
|
|
{
|
|
pVehicle = CVehicleFactory::ms_pLastCreatedVehicle;
|
|
}
|
|
|
|
if(pVehicle)
|
|
{
|
|
CCarDoor * pDoor = pVehicle->GetDoorFromId(CVehicleModelInfo::GetSetupDoorIds()[CVehicleFactory::ms_iDoorToOpen]);
|
|
|
|
if(pDoor && pDoor->GetIsIntact(pVehicle))
|
|
{
|
|
pDoor->SetSwingingFree(pVehicle);
|
|
}
|
|
}
|
|
}
|
|
|
|
void breakOffDoorCB()
|
|
{
|
|
CVehicle* pVehicle = CVehicleDebug::GetFocusVehicle();
|
|
if(!pVehicle && CVehicleFactory::ms_pLastCreatedVehicle)
|
|
{
|
|
pVehicle = CVehicleFactory::ms_pLastCreatedVehicle;
|
|
}
|
|
|
|
if(pVehicle && !pVehicle->IsNetworkClone())
|
|
{
|
|
CCarDoor * pDoor = pVehicle->GetDoorFromId(CVehicleModelInfo::GetSetupDoorIds()[CVehicleFactory::ms_iDoorToOpen]);
|
|
|
|
if(pDoor && pDoor->GetIsIntact(pVehicle))
|
|
{
|
|
// need to break the latch order for the physics to be activated .. otherwise the door falls through the world
|
|
pDoor->BreakLatch(pVehicle);
|
|
pDoor->BreakOff(pVehicle);
|
|
}
|
|
}
|
|
}
|
|
|
|
void HydraulicSuspensionCB()
|
|
{
|
|
CVehicle* pVehicle = CVehicleFactory::ms_pLastCreatedVehicle.Get();
|
|
|
|
if(pVehicle && pVehicle->GetVehicleType() == VEHICLE_TYPE_CAR)
|
|
{
|
|
CAutomobile *pAutomobile = static_cast<CAutomobile*>(pVehicle);
|
|
pAutomobile->SetHydraulicsBounds( CVehicle::ms_fHydraulicVarianceUpperBoundMaxModifier * CVehicle::ms_fHydraulicSuspension,
|
|
-CVehicle::ms_fHydraulicVarianceLowerBoundMaxModifier * CVehicle::ms_fHydraulicSuspension);
|
|
pAutomobile->ActivatePhysics();
|
|
}
|
|
}
|
|
|
|
void resetSuspensionCB()
|
|
{
|
|
CVehicle* pVehicle = CVehicleFactory::ms_pLastCreatedVehicle.Get();
|
|
|
|
if(pVehicle)
|
|
{
|
|
pVehicle->ResetSuspension();
|
|
}
|
|
}
|
|
|
|
void setGroundClearanceCB()
|
|
{
|
|
CVehicle* pVehicle = CVehicleFactory::ms_pLastCreatedVehicle.Get();
|
|
|
|
if(pVehicle && pVehicle->GetVehicleType() == VEHICLE_TYPE_CAR)
|
|
{
|
|
CAutomobile *pAutomobile = static_cast<CAutomobile*>(pVehicle);
|
|
pAutomobile->UpdateDesiredGroundGroundClearance(CVehicle::ms_fForcedGroundClearance);
|
|
}
|
|
}
|
|
|
|
void openAllDoorsCB()
|
|
{
|
|
CVehicle* pVehicle = CVehicleDebug::GetFocusVehicle();
|
|
if(!pVehicle && CVehicleFactory::ms_pLastCreatedVehicle)
|
|
{
|
|
pVehicle = CVehicleFactory::ms_pLastCreatedVehicle;
|
|
}
|
|
|
|
if(pVehicle)
|
|
{
|
|
for(int i=0; i<pVehicle->GetNumDoors(); i++)
|
|
{
|
|
CCarDoor * pDoor = pVehicle->GetDoor(i);
|
|
|
|
if(pDoor && pDoor->GetIsIntact(pVehicle))
|
|
{
|
|
pDoor->SetTargetDoorOpenRatio(1.0f, CCarDoor::DRIVEN_NORESET|CCarDoor::DRIVEN_SPECIAL);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void closeAllDoorsCB()
|
|
{
|
|
CVehicle* pVehicle = CVehicleDebug::GetFocusVehicle();
|
|
if(!pVehicle && CVehicleFactory::ms_pLastCreatedVehicle)
|
|
{
|
|
pVehicle = CVehicleFactory::ms_pLastCreatedVehicle;
|
|
}
|
|
|
|
if(pVehicle)
|
|
{
|
|
for(int i=0; i<pVehicle->GetNumDoors(); i++)
|
|
{
|
|
CCarDoor * pDoor = pVehicle->GetDoor(i);
|
|
|
|
if(pDoor && pDoor->GetIsIntact(pVehicle))
|
|
{
|
|
pDoor->SetShutAndLatched(pVehicle);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void unlatchAllDoorsCB()
|
|
{
|
|
CVehicle* pVehicle = CVehicleDebug::GetFocusVehicle();
|
|
if(!pVehicle && CVehicleFactory::ms_pLastCreatedVehicle)
|
|
{
|
|
pVehicle = CVehicleFactory::ms_pLastCreatedVehicle;
|
|
}
|
|
|
|
if(pVehicle)
|
|
{
|
|
for(int i=0; i<pVehicle->GetNumDoors(); i++)
|
|
{
|
|
CCarDoor * pDoor = pVehicle->GetDoor(i);
|
|
|
|
if(pDoor && pDoor->GetIsIntact(pVehicle))
|
|
{
|
|
pVehicle->GetDoor(i)->SetSwingingFree(pVehicle);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void breakOffAllDoorsCB()
|
|
{
|
|
CVehicle* pVehicle = CVehicleDebug::GetFocusVehicle();
|
|
if(!pVehicle && CVehicleFactory::ms_pLastCreatedVehicle)
|
|
{
|
|
pVehicle = CVehicleFactory::ms_pLastCreatedVehicle;
|
|
}
|
|
|
|
if(pVehicle)
|
|
{
|
|
for(int i=0; i<pVehicle->GetNumDoors(); i++)
|
|
{
|
|
CCarDoor * pDoor = pVehicle->GetDoor(i);
|
|
|
|
if(pDoor && pDoor->GetIsIntact(pVehicle))
|
|
{
|
|
// need to break the latch order for the physics to be activated .. otherwise the door falls through the world
|
|
pDoor->BreakLatch(pVehicle);
|
|
pDoor->BreakOff(pVehicle);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void openBombBayDoorsCB()
|
|
{
|
|
if(CVehicleFactory::ms_pLastCreatedVehicle)
|
|
{
|
|
for(int i = 0; i < CVehicleFactory::ms_pLastCreatedVehicle->GetNumberOfVehicleGadgets(); i++)
|
|
{
|
|
CVehicleGadget *pVehicleGadget = CVehicleFactory::ms_pLastCreatedVehicle->GetVehicleGadget(i);
|
|
|
|
//do we have a bombbay gadget
|
|
if(pVehicleGadget->GetType() == VGT_BOMBBAY)
|
|
{
|
|
CVehicleGadgetBombBay *pBombBay = static_cast<CVehicleGadgetBombBay*>(pVehicleGadget);
|
|
|
|
pBombBay->OpenDoors(CVehicleFactory::ms_pLastCreatedVehicle);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void closeBombBayDoorsCB()
|
|
{
|
|
if(CVehicleFactory::ms_pLastCreatedVehicle)
|
|
{
|
|
for(int i = 0; i < CVehicleFactory::ms_pLastCreatedVehicle->GetNumberOfVehicleGadgets(); i++)
|
|
{
|
|
CVehicleGadget *pVehicleGadget = CVehicleFactory::ms_pLastCreatedVehicle->GetVehicleGadget(i);
|
|
|
|
//do we have a bombbay gadget
|
|
if(pVehicleGadget->GetType() == VGT_BOMBBAY)
|
|
{
|
|
CVehicleGadgetBombBay *pBombBay = static_cast<CVehicleGadgetBombBay*>(pVehicleGadget);
|
|
|
|
pBombBay->CloseDoors(CVehicleFactory::ms_pLastCreatedVehicle);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void swingOpenBooatBoomCB()
|
|
{
|
|
CVehicle* pVehicle = CVehicleDebug::GetFocusVehicle();
|
|
if(!pVehicle && CVehicleFactory::ms_pLastCreatedVehicle)
|
|
{
|
|
pVehicle = CVehicleFactory::ms_pLastCreatedVehicle;
|
|
}
|
|
|
|
if(pVehicle)
|
|
{
|
|
for(int i = 0; i < pVehicle->GetNumberOfVehicleGadgets(); i++)
|
|
{
|
|
CVehicleGadget *pVehicleGadget = pVehicle->GetVehicleGadget(i);
|
|
|
|
//do we have a boat boom gadget
|
|
if(pVehicleGadget->GetType() == VGT_BOATBOOM)
|
|
{
|
|
CVehicleGadgetBoatBoom *pBombBay = static_cast<CVehicleGadgetBoatBoom*>(pVehicleGadget);
|
|
|
|
pBombBay->SwingOutBoatBoom(pVehicle);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void swingInBooatBoomCB()
|
|
{
|
|
CVehicle* pVehicle = CVehicleDebug::GetFocusVehicle();
|
|
if(!pVehicle && CVehicleFactory::ms_pLastCreatedVehicle)
|
|
{
|
|
pVehicle = CVehicleFactory::ms_pLastCreatedVehicle;
|
|
}
|
|
|
|
if(pVehicle)
|
|
{
|
|
for(int i = 0; i < pVehicle->GetNumberOfVehicleGadgets(); i++)
|
|
{
|
|
CVehicleGadget *pVehicleGadget = pVehicle->GetVehicleGadget(i);
|
|
|
|
//do we have a boat boom gadget
|
|
if(pVehicleGadget->GetType() == VGT_BOATBOOM)
|
|
{
|
|
CVehicleGadgetBoatBoom *pBombBay = static_cast<CVehicleGadgetBoatBoom*>(pVehicleGadget);
|
|
|
|
pBombBay->SwingInBoatBoom(pVehicle);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void repairTyreCB()
|
|
{
|
|
if(CVehicleFactory::ms_pLastCreatedVehicle)
|
|
{
|
|
eHierarchyId nWheelId = CWheel::GetScriptWheelId(eScriptWheelList(CVehicleFactory::ms_iTyreNumber));
|
|
|
|
if(CVehicleFactory::ms_pLastCreatedVehicle->GetWheelFromId(nWheelId))
|
|
{
|
|
CVehicleFactory::ms_pLastCreatedVehicle->GetWheelFromId(nWheelId)->ResetDamage();
|
|
}
|
|
}
|
|
}
|
|
|
|
void breakOffTyreCB()
|
|
{
|
|
CVehicle* pVehicle = CVehicleDebug::GetFocusVehicle();
|
|
if(!pVehicle && CVehicleFactory::ms_pLastCreatedVehicle)
|
|
{
|
|
pVehicle = CVehicleFactory::ms_pLastCreatedVehicle;
|
|
}
|
|
|
|
if(pVehicle && !pVehicle->IsNetworkClone())
|
|
{
|
|
eHierarchyId nWheelId = CWheel::GetScriptWheelId(eScriptWheelList(CVehicleFactory::ms_iTyreNumber));
|
|
|
|
if(pVehicle->GetWheelFromId(nWheelId))
|
|
{
|
|
pVehicle->PartHasBrokenOff(pVehicle->GetWheelFromId(nWheelId)->GetHierarchyId());
|
|
fragInst *pFraginst = pVehicle->GetFragInst();
|
|
pFraginst->BreakOffAbove(pVehicle->GetWheelFromId(nWheelId)->GetFragChild());
|
|
pVehicle->SetWheelBroken(pVehicle->GetWheelIndexFromId(nWheelId));
|
|
CVehicle::ClearLastBrokenOffPart();
|
|
}
|
|
}
|
|
}
|
|
|
|
void ToggleBurnoutModeCB()
|
|
{
|
|
if(CVehicleFactory::ms_pLastCreatedVehicle)
|
|
{
|
|
CVehicle *pVehicle = CVehicleFactory::ms_pLastCreatedVehicle;
|
|
if( pVehicle->InheritsFromAutomobile())
|
|
{
|
|
CAutomobile *pAutomobile = static_cast<CAutomobile*>(pVehicle);
|
|
pAutomobile->EnableBurnoutMode(!pAutomobile->GetBurnoutMode());
|
|
}
|
|
}
|
|
}
|
|
|
|
void ToggleReduceGripModeCB()
|
|
{
|
|
if(CVehicleFactory::ms_pLastCreatedVehicle)
|
|
{
|
|
CVehicle *pVehicle = CVehicleFactory::ms_pLastCreatedVehicle;
|
|
if( pVehicle->InheritsFromAutomobile())
|
|
{
|
|
CAutomobile *pAutomobile = static_cast<CAutomobile*>(pVehicle);
|
|
pAutomobile->EnableReduceGripMode(!pAutomobile->GetReduceGripMode());
|
|
}
|
|
|
|
pVehicle->GetVehicleDamage()->GetIsDriveable();
|
|
}
|
|
}
|
|
|
|
void ToggleDriftTyresCB()
|
|
{
|
|
if(CVehicleFactory::ms_pLastCreatedVehicle)
|
|
{
|
|
CVehicle *pVehicle = CVehicleFactory::ms_pLastCreatedVehicle;
|
|
pVehicle->m_bDriftTyres = !pVehicle->m_bDriftTyres;
|
|
}
|
|
}
|
|
|
|
void ToggleHoldGearWithWheelspinFlagCB()
|
|
{
|
|
CVehicle::ms_bDebugIgnoreHoldGearWithWheelspinFlag = !CVehicle::ms_bDebugIgnoreHoldGearWithWheelspinFlag;
|
|
}
|
|
|
|
void ToggleReducedSuspensionForceCB()
|
|
{
|
|
CVehicle* pVehicle = CVehicleDebug::GetFocusVehicle();
|
|
if(!pVehicle && CVehicleFactory::ms_pLastCreatedVehicle)
|
|
{
|
|
pVehicle = CVehicleFactory::ms_pLastCreatedVehicle;
|
|
}
|
|
|
|
if (pVehicle)
|
|
{
|
|
bool bSuspensionForceReduced = false;
|
|
for(s32 index = 0; index < pVehicle->GetNumWheels(); index++)
|
|
{
|
|
CWheel *wheel = pVehicle->GetWheel(index);
|
|
gnetAssert(wheel);
|
|
|
|
if(wheel && wheel->GetReducedSuspensionForce())
|
|
{
|
|
bSuspensionForceReduced = true;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(pVehicle->InheritsFromAutomobile())
|
|
{
|
|
CAutomobile* pAutomobile = static_cast< CAutomobile* >( pVehicle );
|
|
pAutomobile->SetReducedSuspensionForce(!bSuspensionForceReduced);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
void toggleGravityCB()
|
|
{
|
|
CVehicle* pVehicle = CVehicleDebug::GetFocusVehicle();
|
|
if(!pVehicle && CVehicleFactory::ms_pLastCreatedVehicle)
|
|
{
|
|
pVehicle = CVehicleFactory::ms_pLastCreatedVehicle;
|
|
}
|
|
|
|
if(pVehicle)
|
|
{
|
|
if(pVehicle->GetGravityForWheellIntegrator() > 0.0f)
|
|
{
|
|
pVehicle->SetGravityForWheellIntegrator(0.0f);
|
|
}
|
|
else
|
|
{
|
|
pVehicle->SetGravityForWheellIntegrator(-GRAVITY);
|
|
}
|
|
}
|
|
}
|
|
|
|
void popOutWindscreenCB()
|
|
{
|
|
if(CVehicleFactory::ms_pLastCreatedVehicle)
|
|
{
|
|
CVehicleFactory::ms_pLastCreatedVehicle->GetVehicleDamage()->PopOutWindScreen();
|
|
}
|
|
}
|
|
|
|
|
|
void popOffRoofCB()
|
|
{
|
|
if(CVehicleFactory::ms_pLastCreatedVehicle)
|
|
{
|
|
CVehicleFactory::ms_pLastCreatedVehicle->GetVehicleDamage()->PopOffRoof(sRoofImpulse);
|
|
}
|
|
}
|
|
|
|
void ReloadHandlingDataCB()
|
|
{
|
|
CVehicle::Pool* pool = CVehicle::GetPool();
|
|
for(int i= 0; i< pool->GetSize(); i++)
|
|
{
|
|
CVehicle* pVehicle = pool->GetSlot(i);
|
|
if(pVehicle)
|
|
CVehicleFactory::GetFactory()->Destroy(pVehicle);
|
|
}
|
|
CHandlingDataMgr::ReloadHandlingData();
|
|
CModelInfo::UpdateVehicleHandlingInfos();
|
|
CModelInfo::UpdateVehicleClassInfos();
|
|
if(CVehicleFactory::ms_pLastCreatedVehicle)
|
|
{
|
|
CVehicleModelInfo* pModelInfo = CVehicleFactory::ms_pLastCreatedVehicle->GetVehicleModelInfo();
|
|
pModelInfo->InitPhys();
|
|
CVehicleFactory::ms_pLastCreatedVehicle->m_Transmission.SetupTransmission( CVehicleFactory::ms_pLastCreatedVehicle->pHandling->m_fInitialDriveForce,
|
|
CVehicleFactory::ms_pLastCreatedVehicle->pHandling->m_fInitialDriveMaxFlatVel,
|
|
CVehicleFactory::ms_pLastCreatedVehicle->pHandling->m_fInitialDriveMaxVel,
|
|
CVehicleFactory::ms_pLastCreatedVehicle->pHandling->m_nInitialDriveGears,
|
|
CVehicleFactory::ms_pLastCreatedVehicle );
|
|
|
|
if(CVehicleFactory::ms_pLastCreatedVehicle->GetSecondTransmission())
|
|
{
|
|
CVehicleFactory::ms_pLastCreatedVehicle->GetSecondTransmission()->SetupTransmission(CVehicleFactory::ms_pLastCreatedVehicle->pHandling->m_fInitialDriveForce,
|
|
CVehicleFactory::ms_pLastCreatedVehicle->pHandling->m_fInitialDriveMaxFlatVel,
|
|
CVehicleFactory::ms_pLastCreatedVehicle->pHandling->m_fInitialDriveMaxVel,
|
|
1,
|
|
CVehicleFactory::ms_pLastCreatedVehicle);
|
|
}
|
|
|
|
/*
|
|
CVehicleFactory::ms_pLastCreatedVehicle->SetupWheels(NULL);
|
|
CVehicleFactory::ms_pLastCreatedVehicle->hFlagsLocal = CVehicleFactory::ms_pLastCreatedVehicle->pHandling->hFlags;
|
|
|
|
phArchetypeDamp *pArchetype = (phArchetypeDamp *)CVehicleFactory::ms_pLastCreatedVehicle->GetCurrentPhysicsInst()->GetArchetype();
|
|
pArchetype->ActivateDamping(phArchetypeDamp::LINEAR_V2, Vector3(CVehicleFactory::ms_pLastCreatedVehicle->pHandling->m_fDragCoeff, CVehicleFactory::ms_pLastCreatedVehicle->pHandling->m_fDragCoeff, CVehicleFactory::ms_pLastCreatedVehicle->pHandling->m_fDragCoeff));
|
|
|
|
if(CVehicleFactory::ms_pLastCreatedVehicle->GetVehicleType()==VEHICLE_TYPE_HELI || CVehicleFactory::ms_pLastCreatedVehicle->GetVehicleType()==VEHICLE_TYPE_PLANE)
|
|
{
|
|
//if(CVehicleFactory::ms_pLastCreatedVehicle->pHandling->GetFlyingHandlingData()->fMoveRes > 0.0f)
|
|
pArchetype->ActivateDamping(phArchetypeDamp::LINEAR_V, Vector3(CVehicleFactory::ms_pLastCreatedVehicle->pHandling->GetFlyingHandlingData()->fMoveRes, CVehicleFactory::ms_pLastCreatedVehicle->pHandling->GetFlyingHandlingData()->fMoveRes, CVehicleFactory::ms_pLastCreatedVehicle->pHandling->GetFlyingHandlingData()->fMoveRes));
|
|
|
|
//if(CVehicleFactory::ms_pLastCreatedVehicle->pHandling->GetFlyingHandlingData()->vecTurnRes.Mag2() > 0.0f)
|
|
pArchetype->ActivateDamping(phArchetypeDamp::ANGULAR_V, CVehicleFactory::ms_pLastCreatedVehicle->pHandling->GetFlyingHandlingData()->vecTurnRes);
|
|
|
|
//if(CVehicleFactory::ms_pLastCreatedVehicle->pHandling->GetFlyingHandlingData()->vecSpeedRes.Mag2() > 0.0f)
|
|
pArchetype->ActivateDamping(phArchetypeDamp::ANGULAR_V2, CVehicleFactory::ms_pLastCreatedVehicle->pHandling->GetFlyingHandlingData()->vecSpeedRes);
|
|
}
|
|
*/
|
|
}
|
|
/*
|
|
if(FindPlayerVehicle() && FindPlayerVehicle()!=CVehicleFactory::ms_pLastCreatedVehicle)
|
|
{
|
|
CVehicleModelInfo* pModelInfo = (CVehicleModelInfo*)CModelInfo::GetModelInfo (FindPlayerVehicle()->GetModelIndex());
|
|
pModelInfo->InitPhys();
|
|
|
|
FindPlayerVehicle()->SetupWheels(NULL);
|
|
FindPlayerVehicle()->hFlagsLocal = FindPlayerVehicle()->pHandling->hFlags;
|
|
|
|
phArchetypeDamp *pArchetype = (phArchetypeDamp *)FindPlayerVehicle()->GetCurrentPhysicsInst()->GetArchetype();
|
|
pArchetype->ActivateDamping(phArchetypeDamp::LINEAR_V2, Vector3(FindPlayerVehicle()->pHandling->m_fDragCoeff, FindPlayerVehicle()->pHandling->m_fDragCoeff, FindPlayerVehicle()->pHandling->m_fDragCoeff));
|
|
|
|
if(FindPlayerVehicle()->GetVehicleType()==VEHICLE_TYPE_HELI || FindPlayerVehicle()->GetVehicleType()==VEHICLE_TYPE_PLANE)
|
|
{
|
|
//if(FindPlayerVehicle()->pHandling->GetFlyingHandlingData()->fMoveRes > 0.0f)
|
|
pArchetype->ActivateDamping(phArchetypeDamp::LINEAR_V, Vector3(FindPlayerVehicle()->pHandling->GetFlyingHandlingData()->fMoveRes, FindPlayerVehicle()->pHandling->GetFlyingHandlingData()->fMoveRes, FindPlayerVehicle()->pHandling->GetFlyingHandlingData()->fMoveRes));
|
|
|
|
//if(FindPlayerVehicle()->pHandling->GetFlyingHandlingData()->vecTurnRes.Mag2() > 0.0f)
|
|
pArchetype->ActivateDamping(phArchetypeDamp::ANGULAR_V, FindPlayerVehicle()->pHandling->GetFlyingHandlingData()->vecTurnRes);
|
|
|
|
//if(FindPlayerVehicle()->pHandling->GetFlyingHandlingData()->vecSpeedRes.Mag2() > 0.0f)
|
|
pArchetype->ActivateDamping(phArchetypeDamp::ANGULAR_V2, FindPlayerVehicle()->pHandling->GetFlyingHandlingData()->vecSpeedRes);
|
|
}
|
|
}
|
|
*/
|
|
}
|
|
|
|
void CycleHandlingDebugCB()
|
|
{
|
|
CVehicle::ms_nVehicleDebug += 1;
|
|
if(CVehicle::ms_nVehicleDebug >= VEH_DEBUG_END)
|
|
CVehicle::ms_nVehicleDebug = VEH_DEBUG_OFF;
|
|
if((CVehicle::ms_nVehicleDebug==VEH_DEBUG_PERFORMANCE || CVehicle::ms_nVehicleDebug==VEH_DEBUG_HANDLING)
|
|
&& NetworkDebug::GetDebugDisplaySettings().m_displayBasicInfo)
|
|
{
|
|
// Turn off network debug displays, so that the text won't overlap on top of each other
|
|
NetworkDebug::GetDebugDisplaySettings().m_displayBasicInfo = false;
|
|
}
|
|
}
|
|
|
|
void DisplayDownforceDebugCB()
|
|
{
|
|
CVehicle::ms_bVehicleDownforceDebug = !CVehicle::ms_bVehicleDownforceDebug;
|
|
}
|
|
|
|
void DisplayQADebugCB()
|
|
{
|
|
CVehicle::ms_bVehicleQADebug = !CVehicle::ms_bVehicleQADebug;
|
|
}
|
|
|
|
void RemoveTrailersCB()
|
|
{
|
|
s32 count = 0;
|
|
CVehicle::Pool* pool = CVehicle::GetPool();
|
|
s32 i = (s32) pool->GetSize();
|
|
while(i--)
|
|
{
|
|
CVehicle* pVehicle = pool->GetSlot(i);
|
|
if(pVehicle && pVehicle->GetVehicleType() == VEHICLE_TYPE_TRAILER)
|
|
{
|
|
CVehicleFactory::GetFactory()->Destroy(pVehicle);
|
|
count++;
|
|
}
|
|
}
|
|
|
|
Displayf("Removed %d trailers\n", count);
|
|
}
|
|
|
|
void DetachTrailerCB()
|
|
{
|
|
CVehicle *pParentVehicle = CVehicleFactory::ms_pLastCreatedVehicle;
|
|
|
|
if(pParentVehicle && pParentVehicle->GetAttachedTrailer())
|
|
{
|
|
pParentVehicle->GetAttachedTrailer()->DetachFromParent(0);
|
|
}
|
|
}
|
|
|
|
void ToggleOutriggersCB()
|
|
{
|
|
CVehicle *pParentVehicle = CVehicleFactory::ms_pLastCreatedVehicle;
|
|
|
|
if( pParentVehicle )
|
|
{
|
|
pParentVehicle->SetDeployOutriggers( !pParentVehicle->GetAreOutriggersBeingDeployed() );
|
|
}
|
|
}
|
|
|
|
void DropCarCB()
|
|
{
|
|
if(CVehicleFactory::ms_pLastCreatedVehicle)
|
|
{
|
|
Vector3 vecPos = VEC3V_TO_VECTOR3(CVehicleFactory::ms_pLastCreatedVehicle->GetTransform().GetPosition());
|
|
vecPos.z += carDropHeight;
|
|
|
|
float fSetHeading = -10.0f;
|
|
if(CVehicleFactory::ms_pLastCreatedVehicle->GetTransform().GetC().GetZf() < 0.3f)
|
|
fSetHeading = CVehicleFactory::ms_pLastCreatedVehicle->GetTransform().GetHeading();
|
|
|
|
CVehicleFactory::ms_pLastCreatedVehicle->Teleport(vecPos, fSetHeading, false);
|
|
}
|
|
}
|
|
|
|
void TestCarAgainstWorldCB()
|
|
{
|
|
if(CVehicleFactory::ms_pLastCreatedVehicle)
|
|
{
|
|
Matrix34 matTest = MAT34V_TO_MATRIX34(CVehicleFactory::ms_pLastCreatedVehicle->GetMatrix());
|
|
matTest.d.z += carTestHeight;
|
|
const CEntity** ppExcludeInst = (const CEntity**)&CVehicleFactory::ms_pLastCreatedVehicle;
|
|
if(CVehicle::TestVehicleBoundForCollision(
|
|
&matTest, CVehicleFactory::ms_pLastCreatedVehicle, fwModelId::MI_INVALID, ppExcludeInst, 1, NULL, ArchetypeFlags::GTA_ALL_MAP_TYPES))
|
|
{
|
|
Displayf("\nCar Test Hit");
|
|
}
|
|
}
|
|
}
|
|
|
|
void LockLastCar()
|
|
{
|
|
if(CVehicleFactory::ms_pLastCreatedVehicle)
|
|
{
|
|
CVehicleFactory::ms_pLastCreatedVehicle->SetCarDoorLocks(CARLOCK_LOCKED_BUT_CAN_BE_DAMAGED);
|
|
}
|
|
}
|
|
|
|
void ToggleDummyPhysicsCB()
|
|
{
|
|
if(CVehicleFactory::ms_pLastCreatedVehicle && CVehicleFactory::ms_pLastCreatedVehicle->GetVehicleType()==VEHICLE_TYPE_CAR)
|
|
{
|
|
CAutomobile * pAutomobile = ((CAutomobile*)CVehicleFactory::ms_pLastCreatedVehicle.Get());
|
|
|
|
if(CVehicleFactory::ms_pLastCreatedVehicle->GetCurrentPhysicsInst()==((CAutomobile*)CVehicleFactory::ms_pLastCreatedVehicle.Get())->GetVehicleFragInst())
|
|
{
|
|
pAutomobile->TryToMakeIntoDummy(VDM_DUMMY);
|
|
}
|
|
else
|
|
{
|
|
pAutomobile->TryToMakeFromDummy();
|
|
}
|
|
}
|
|
}
|
|
|
|
void FreezeVehicleCB()
|
|
{
|
|
if(CVehicleFactory::ms_pLastCreatedVehicle && !CVehicleFactory::ms_pLastCreatedVehicle->GetIsAnyFixedFlagSet())
|
|
{
|
|
CVehicleFactory::ms_pLastCreatedVehicle->SetFixedPhysics(true);
|
|
}
|
|
}
|
|
|
|
void UnfreezeVehicleCB()
|
|
{
|
|
if(CVehicleFactory::ms_pLastCreatedVehicle && CVehicleFactory::ms_pLastCreatedVehicle->GetIsAnyFixedFlagSet())
|
|
{
|
|
CVehicleFactory::ms_pLastCreatedVehicle->SetFixedPhysics(false);
|
|
}
|
|
}
|
|
|
|
void ToggleAnchorBoatCB()
|
|
{
|
|
if(CVehicleFactory::ms_pLastCreatedVehicle)
|
|
{
|
|
if(CVehicleFactory::ms_pLastCreatedVehicle->GetVehicleType()==VEHICLE_TYPE_BOAT)
|
|
{
|
|
CBoat* pBoat = (CBoat*)CVehicleFactory::ms_pLastCreatedVehicle.Get();
|
|
pBoat->GetAnchorHelper().Anchor(!pBoat->GetAnchorHelper().IsAnchored());
|
|
}
|
|
else if(CVehicleFactory::ms_pLastCreatedVehicle->GetVehicleType()==VEHICLE_TYPE_SUBMARINE)
|
|
{
|
|
CSubmarine* pSub = static_cast<CSubmarine*>(CVehicleFactory::ms_pLastCreatedVehicle.Get());
|
|
CSubmarineHandling* pSubHandling = pSub->GetSubHandling();
|
|
|
|
pSubHandling->GetAnchorHelper().Anchor(!pSubHandling->GetAnchorHelper().IsAnchored());
|
|
}
|
|
else if(CVehicleFactory::ms_pLastCreatedVehicle->GetVehicleType()==VEHICLE_TYPE_PLANE)
|
|
{
|
|
CSeaPlaneExtension* pSeaPlaneExtension = static_cast<CPlane*>(CVehicleFactory::ms_pLastCreatedVehicle.Get())->GetExtension<CSeaPlaneExtension>();
|
|
if(pSeaPlaneExtension)
|
|
{
|
|
CAnchorHelper& anchorHelper = pSeaPlaneExtension->GetAnchorHelper();
|
|
anchorHelper.Anchor(!anchorHelper.IsAnchored());
|
|
}
|
|
}
|
|
else if(CVehicleFactory::ms_pLastCreatedVehicle->GetVehicleType()==VEHICLE_TYPE_AMPHIBIOUS_AUTOMOBILE ||
|
|
CVehicleFactory::ms_pLastCreatedVehicle->GetVehicleType()==VEHICLE_TYPE_AMPHIBIOUS_QUADBIKE )
|
|
{
|
|
CAmphibiousAutomobile* pAmphiVehicle = (CAmphibiousAutomobile*)CVehicleFactory::ms_pLastCreatedVehicle.Get();
|
|
pAmphiVehicle->GetAnchorHelper().Anchor(!pAmphiVehicle->GetAnchorHelper().IsAnchored());
|
|
}
|
|
}
|
|
}
|
|
|
|
void SoundCarHornCB()
|
|
{
|
|
if(CVehicleFactory::ms_pLastCreatedVehicle && CVehicleFactory::ms_pLastCreatedVehicle->GetIsTypeVehicle())
|
|
{
|
|
vehicle_commands::CommandSoundCarHorn(CTheScripts::GetGUIDFromEntity(*(CVehicleFactory::ms_pLastCreatedVehicle.Get())), carSoundHornTime * 1000);
|
|
}
|
|
}
|
|
|
|
void ApplyCheatsToLastCarCB()
|
|
{
|
|
if(CVehicleFactory::ms_pLastCreatedVehicle)
|
|
{
|
|
u32 nCheats = 0;
|
|
if(sbCheatAbs) nCheats |= VEH_SET_ABS;
|
|
if(sbCheatTractionControl) nCheats |= VEH_SET_TC;
|
|
if(sbCheatStabilityControl) nCheats |= VEH_SET_SC;
|
|
if(sbCheatGrip1) nCheats |= VEH_SET_GRIP1;
|
|
if(sbCheatGrip2) nCheats |= VEH_SET_GRIP2;
|
|
if(sbCheatPower1) nCheats |= VEH_SET_POWER1;
|
|
if(sbCheatPower2) nCheats |= VEH_SET_POWER2;
|
|
|
|
CVehicleFactory::ms_pLastCreatedVehicle->SetCheatFlags(nCheats);
|
|
}
|
|
}
|
|
|
|
void ApplyCheatsToSelectedCarCB()
|
|
{
|
|
CVehicle *pVehicle = CVehicleDebug::GetFocusVehicle();
|
|
if(pVehicle)
|
|
{
|
|
u32 nCheats = 0;
|
|
if(sbCheatAbs) nCheats |= VEH_SET_ABS;
|
|
if(sbCheatTractionControl) nCheats |= VEH_SET_TC;
|
|
if(sbCheatStabilityControl) nCheats |= VEH_SET_SC;
|
|
if(sbCheatGrip1) nCheats |= VEH_SET_GRIP1;
|
|
if(sbCheatGrip2) nCheats |= VEH_SET_GRIP2;
|
|
if(sbCheatPower1) nCheats |= VEH_SET_POWER1;
|
|
if(sbCheatPower2) nCheats |= VEH_SET_POWER2;
|
|
|
|
pVehicle->SetCheatFlags(nCheats);
|
|
}
|
|
}
|
|
|
|
void ClearZeroSixtySixtyZeroGForceCarCB()
|
|
{
|
|
CAutomobile::ms_fBestSixtyToZeroTime = 0.0f;
|
|
CAutomobile::ms_fBestZeroToSixtyTime = 0.0f;
|
|
CAutomobile::ms_fHighestGForce = 0.0f;
|
|
}
|
|
|
|
void ApplyTopSpeedToLastCarCB()
|
|
{
|
|
CVehicleFactory::ModifyVehicleTopSpeed(CVehicleFactory::ms_pLastCreatedVehicle, sfTopSpeedAdjustment);
|
|
}
|
|
|
|
void ForceHdCB()
|
|
{
|
|
if (CVehicleFactory::ms_pLastCreatedVehicle)
|
|
{
|
|
CVehicleFactory::ms_pLastCreatedVehicle->SetForceHd(CVehicleFactory::ms_bForceHd);
|
|
}
|
|
}
|
|
|
|
void LodMultCB()
|
|
{
|
|
if (CVehicleFactory::ms_pLastCreatedVehicle)
|
|
{
|
|
CVehicleFactory::ms_pLastCreatedVehicle->SetLodMultiplier(CVehicleFactory::ms_fLodMult);
|
|
}
|
|
}
|
|
|
|
void ClampRenderLodCB()
|
|
{
|
|
if (CVehicleFactory::ms_pLastCreatedVehicle)
|
|
{
|
|
CVehicleFactory::ms_pLastCreatedVehicle->SetClampedRenderLod(CVehicleFactory::ms_clampedRenderLod);
|
|
}
|
|
}
|
|
|
|
static atArray<CVehicleModelInfo*> g_typeArray;
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
static int CbCompareModelInfos(const void* pVoidA, const void* pVoidB)
|
|
{
|
|
const s32* pA = (const s32*)pVoidA;
|
|
const s32* pB = (const s32*)pVoidB;
|
|
|
|
return stricmp(g_typeArray[*pA]->GetModelName(), g_typeArray[*pB]->GetModelName());
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
// name: UpdateMloList
|
|
// purpose:
|
|
// params: none
|
|
// returns: nothing
|
|
////////////////////////////////////////////////////////////////////////////
|
|
void CVehicleFactory::UpdateVehicleList()
|
|
{
|
|
u32 i=0;
|
|
|
|
emptyNames.Reset();
|
|
|
|
//get the modelInfo associated with this ped ID
|
|
fwArchetypeDynamicFactory<CVehicleModelInfo>& vehModelInfoStore = CModelInfo::GetVehicleModelInfoStore();
|
|
vehModelInfoStore.GatherPtrs(g_typeArray);
|
|
|
|
numVehicleNames = g_typeArray.GetCount();
|
|
|
|
delete []vehicleSorts;
|
|
vehicleSorts = rage_new s32[numVehicleNames];
|
|
|
|
int actualNum = 0;
|
|
for(i=0;i<numVehicleNames;i++)
|
|
{
|
|
if((currVehicleTypeSelection == BANK_VEHICLE_TYPE_ALL || g_typeArray[i]->GetVehicleType() == currVehicleTypeSelection) &&
|
|
(currVehicleLayoutSelection == CVehicleMetadataMgr::GetVehicleLayoutInfoCount() || (pLayoutCombo && !strcmp(g_typeArray[i]->GetVehicleLayoutInfo()->GetName().GetCStr(), pLayoutCombo->GetString(currVehicleLayoutSelection)))) &&
|
|
(currVehicleDLCSelection == numDLCNames || (pDLCCombo && !strcmp(g_typeArray[i]->GetVehicleDLCPack().GetCStr(),pDLCCombo->GetString(currVehicleDLCSelection)))) &&
|
|
(currVehicleSwankSelection == BANK_VEHICLE_SWANK_ALL || g_typeArray[i]->GetVehicleSwankness() == currVehicleSwankSelection) &&
|
|
( currVehicleClassSelection == BANK_VEHICLE_CLASS_ALL || g_typeArray[ i ]->GetVehicleClass() == currVehicleClassSelection ) )
|
|
{
|
|
vehicleSorts[actualNum] = i;
|
|
++actualNum;
|
|
}
|
|
}
|
|
|
|
numVehicleNames = actualNum;
|
|
|
|
numVehicleNames = actualNum;
|
|
|
|
// when we restart the game currVehicleNameSelection will possibly be higher than the total number of cars since it had all the DLC/patches vehicles
|
|
// to fix this we simply clamp the value
|
|
currVehicleNameSelection = (currVehicleNameSelection>=numVehicleNames && currVehicleNameSelection!=0) ? numVehicleNames-1 : currVehicleNameSelection;
|
|
|
|
if (currVehicleNameSelection < 0)
|
|
{
|
|
currVehicleNameSelection = 0;
|
|
}
|
|
|
|
qsort(vehicleSorts,numVehicleNames,sizeof(s32),CbCompareModelInfos);
|
|
vehicleNames.Reset();
|
|
|
|
for(i=0;i<numVehicleNames;i++)
|
|
{
|
|
vehicleNames.PushAndGrow(g_typeArray[vehicleSorts[i]]->GetModelName());
|
|
emptyNames.PushAndGrow("");
|
|
}
|
|
|
|
numVehicleTrailerNames = 0;
|
|
|
|
delete []vehicleTrailerSorts;
|
|
vehicleTrailerSorts = rage_new s32[numVehicleNames]; // A bit wasteful, could do a counting pass first and then a population pass to get around that.
|
|
|
|
//now create the list of trailers.
|
|
//loop through vehicles and find vehicles which are trailers.
|
|
for(i=0;i<numVehicleNames;i++)
|
|
{
|
|
if (g_typeArray[vehicleSorts[i]]->GetVehicleType() == VEHICLE_TYPE_TRAILER)
|
|
{
|
|
vehicleTrailerSorts[numVehicleTrailerNames] = vehicleSorts[i];
|
|
numVehicleTrailerNames++;
|
|
}
|
|
}
|
|
|
|
if(!pVehicleCombo)//make sure we have acombo box to add to.
|
|
return;
|
|
|
|
if(numVehicleNames == 0)
|
|
{
|
|
emptyNames.PushAndGrow("");
|
|
pVehicleCombo->UpdateCombo("Vehicle name", &currVehicleNameSelection, 1, &emptyNames[0]);
|
|
pVehicleCombo->SetString(0, "No Vehicle");
|
|
}
|
|
else
|
|
{
|
|
// this breaks!
|
|
//pVehicleCombo->UpdateCombo("Vehicle name", &currVehicleNameSelection, numVehicleNames, &vehicleNames[0], CarNumChangeCB);
|
|
|
|
// this works!
|
|
pVehicleCombo->UpdateCombo("Vehicle name", &currVehicleNameSelection, numVehicleNames, &emptyNames[0], CarNumChangeCB);
|
|
|
|
for(s32 i=0;i<vehicleNames.GetCount();i++)
|
|
{
|
|
// Model names are a mix of lower/upper/capital, converting all to lower makes things easier to read
|
|
atString vehicleName(vehicleNames[i]);
|
|
vehicleName.Lowercase();
|
|
pVehicleCombo->SetString(i, vehicleName.c_str());
|
|
}
|
|
}
|
|
|
|
if(numVehicleTrailerNames == 0)//no trailers found
|
|
{
|
|
emptyNames.PushAndGrow("");
|
|
pVehicleTrailerCombo->UpdateCombo("Trailer name", &currVehicleTrailerNameSelection, 1, &emptyNames[0]);
|
|
pVehicleTrailerCombo->SetString(0, "No trailer");
|
|
}
|
|
else
|
|
{
|
|
// As we are adding 1 to num vehicles below, we need to make sure emptyNames is big enough for this (only if we have to).
|
|
// This stops a crash, url:bugstar:1129262.
|
|
if((numVehicleTrailerNames+1) > emptyNames.GetCount())
|
|
{
|
|
emptyNames.PushAndGrow("");
|
|
}
|
|
|
|
//add 1 to num vehicles so we can have a no trailer selection
|
|
pVehicleTrailerCombo->UpdateCombo("Trailer name", &currVehicleTrailerNameSelection, numVehicleTrailerNames+1, &emptyNames[0], TrailerNumChangeCB);
|
|
|
|
pVehicleTrailerCombo->SetString(0, "No trailer");
|
|
|
|
//fill in the trailer names
|
|
for(s32 i=0;i<numVehicleTrailerNames;i++)
|
|
{
|
|
//now loop through the vehiclesorts created by the cars combo box to find the names of the trailers, I know its not great but it's better then storing them twice imho.
|
|
for(int k = 0; k < numVehicleNames; k++)
|
|
{
|
|
if(vehicleSorts[k] == vehicleTrailerSorts[i])
|
|
{
|
|
pVehicleTrailerCombo->SetString(i+1, vehicleNames[k]);//+1 off i as we have a "no trailer" selection that takes up slot 0
|
|
k = numVehicleNames;//break out of this loop
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
currVehicleNameSelection = 0;
|
|
currVehicleTrailerNameSelection = 0;
|
|
|
|
u32 defaultHash = MI_CAR_TAILGATER.GetName().GetHash();
|
|
if(PARAM_defaultVehicle.Get())
|
|
{
|
|
const char * defaultName = NULL;
|
|
PARAM_defaultVehicle.Get(defaultName);
|
|
|
|
atHashString name(defaultName);
|
|
defaultHash = name.GetHash();
|
|
}
|
|
|
|
|
|
for(u32 i = 0; i < numVehicleNames; i++)
|
|
{
|
|
// HARD CODE THE TAILGATER AS THE DEFAULT SPAWN VEHICLE AND IF WE CAN'T FIND THAT, CARRY ON AS BEFORE.
|
|
if (g_typeArray[vehicleSorts[i]]->GetModelNameHash() == defaultHash)
|
|
{
|
|
currVehicleNameSelection = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
u32 defaultTrailerHash = 0;
|
|
if(PARAM_defaultVehicleTrailer.Get())
|
|
{
|
|
const char * defaultTrailerName = NULL;
|
|
PARAM_defaultVehicleTrailer.Get(defaultTrailerName);
|
|
|
|
atHashString trailerName(defaultTrailerName);
|
|
defaultTrailerHash = trailerName.GetHash();
|
|
}
|
|
|
|
for(u32 i = 0; i < numVehicleTrailerNames; i++)
|
|
{
|
|
if (g_typeArray[vehicleTrailerSorts[i]]->GetModelNameHash() == defaultTrailerHash)
|
|
{
|
|
//0 is reserved for no trailer, consumers of this variable always subtract 1 for this reason.
|
|
currVehicleTrailerNameSelection = i + 1;
|
|
break;
|
|
}
|
|
}
|
|
|
|
g_typeArray.Reset();
|
|
}
|
|
|
|
void ValidateAllVehiclesCB(void)
|
|
{
|
|
#if __DEV
|
|
Displayf("Validation started!\n");
|
|
|
|
char pLine[255];
|
|
FileHandle fid;
|
|
bool fileOpen = false;
|
|
|
|
// Try and open a file for the results
|
|
CFileMgr::SetDir("common:/DATA");
|
|
fid = CFileMgr::OpenFileForWriting("VehicleValidation.csv");
|
|
CFileMgr::SetDir("");
|
|
if ( CFileMgr::IsValidFileHandle(fid) )
|
|
{
|
|
fileOpen = true;
|
|
sprintf(&pLine[0], "model name, num LODs\n");
|
|
ASSERT_ONLY(s32 ReturnVal =) CFileMgr::Write(fid, &pLine[0], istrlen(pLine));
|
|
Assert(ReturnVal > 0);
|
|
}
|
|
else
|
|
{
|
|
Displayf("\\common\\data\\VehicleValidation.csv is read only");
|
|
return;
|
|
}
|
|
|
|
u32 nVehicles = 0;
|
|
|
|
// start at current ped selection
|
|
for(u32 i = CVehicleFactory::currVehicleNameSelection; i<numCarsAvailable; i++)
|
|
{
|
|
// get the modelInfo associated with this ped ID
|
|
fwArchetypeDynamicFactory<CVehicleModelInfo>& vehicleModelInfoStore = CModelInfo::GetVehicleModelInfoStore();
|
|
atArray<CVehicleModelInfo*> vehicleTypesArray;
|
|
vehicleModelInfoStore.GatherPtrs(vehicleTypesArray);
|
|
|
|
CVehicleModelInfo& vehicleModelInfo = *vehicleTypesArray[ vehicleSorts[i] ];
|
|
u32 vehicleInfoIndex = CModelInfo::GetModelIdFromName(vehicleModelInfo.GetModelName()).GetModelIndex();
|
|
|
|
// get the name of the model used by this model info and display it
|
|
Displayf("Validating vehicle. Model name : %s\n", vehicleModelInfo.GetModelName());
|
|
|
|
// ensure that the model is loaded
|
|
fwModelId vehicleInfoId((strLocalIndex(vehicleInfoIndex)));
|
|
if (!CModelInfo::HaveAssetsLoaded(vehicleInfoId))
|
|
{
|
|
CModelInfo::RequestAssets(vehicleInfoId, STRFLAG_FORCE_LOAD|STRFLAG_PRIORITY_LOAD);
|
|
CStreaming::LoadAllRequestedObjects(true);
|
|
}
|
|
|
|
if (fileOpen)
|
|
{
|
|
sprintf(&pLine[0], "%s, %d\n",
|
|
vehicleModelInfo.GetModelName(),
|
|
vehicleModelInfo.GetNumAvailableLODs());
|
|
|
|
ASSERT_ONLY(s32 ReturnVal =) CFileMgr::Write(fid, &pLine[0], istrlen(pLine));
|
|
Assert(ReturnVal > 0);
|
|
|
|
nVehicles++;
|
|
}
|
|
|
|
// remove streamed in modelinfo if we can (ie. ref count is 0 and don't delete flags not set)
|
|
if (vehicleModelInfo.GetNumRefs() == 0)
|
|
{
|
|
fwModelId vehicleInfoId((strLocalIndex(vehicleInfoIndex)));
|
|
if (!(CModelInfo::GetAssetStreamFlags(vehicleInfoId) & STR_DONTDELETE_MASK))
|
|
{
|
|
CModelInfo::RemoveAssets(vehicleInfoId);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
Displayf("Summary\n");
|
|
Displayf("Total number of vehicles %d\n", nVehicles);
|
|
|
|
if (fileOpen)
|
|
{
|
|
Displayf("Saved \\common\\data\\VehicleValidation.csv");
|
|
CFileMgr::CloseFile(fid);
|
|
}
|
|
|
|
Displayf("Validation complete!\n");
|
|
#endif //__DEV
|
|
}
|
|
|
|
void CVehicleFactory::UpdateVehicleTypeList()
|
|
{
|
|
currVehicleNameSelection = 0;
|
|
currVehicleTrailerNameSelection = 0;
|
|
|
|
CVehicleFactory::UpdateVehicleList();
|
|
|
|
if(numVehicleNames)
|
|
{
|
|
carModelId = GetModelIndex(vehicleSorts[currVehicleNameSelection]);
|
|
}
|
|
}
|
|
|
|
extern void populateCarWithCrowd0CB(void);
|
|
extern void populateCarWithCrowd1CB(void);
|
|
//
|
|
// Widget to create a button for creating the vehicles bank
|
|
//
|
|
bool CVehicleFactory::InitWidgets(void)
|
|
{
|
|
pBank = &BANKMGR.CreateBank("Vehicles");
|
|
|
|
if(vehicleVerifyf(pBank, "Failed to create Vehicles bank"))
|
|
{
|
|
pCreateBankButton = pBank->AddButton("Create vehicle widgets", &CVehicleFactory::CreateBank);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
extern BankFloat bfCarDoorBreakThreshold; // from door.cpp
|
|
extern BankBool bbApplyCarDoorDeformation; // from door.cpp
|
|
extern BankFloat bfDeformationThresholdMPMult; // from vehicleDamage.cpp
|
|
BANK_ONLY(extern bool sbDisableMidairWheelIntegrator;)
|
|
//
|
|
// Widget to create test vehicles
|
|
//
|
|
void CVehicleFactory::CreateBank( void )
|
|
{
|
|
Assertf( pBank, "Vehicles bank needs to be created first" );
|
|
|
|
if( pCreateBankButton )//delete the create bank button
|
|
{
|
|
pCreateBankButton->Destroy();
|
|
pCreateBankButton = NULL;
|
|
}
|
|
else
|
|
{
|
|
//bank must already be setup as the create button doesn't exist so just return.
|
|
return;
|
|
}
|
|
|
|
pBank->AddToggle( "Toggle Allow Vehicle Pop to Add and Remove", &gbAllowVehGenerationOrRemoval );
|
|
|
|
pBank->PushGroup( "Create, Populate, and Warp", false );
|
|
fwArchetypeDynamicFactory<CVehicleModelInfo>& vehModelInfoStore = CModelInfo::GetVehicleModelInfoStore();
|
|
atArray<CVehicleModelInfo*> vehicleTypePtrs;
|
|
vehModelInfoStore.GatherPtrs( vehicleTypePtrs );
|
|
numCarsAvailable = vehicleTypePtrs.GetCount();
|
|
|
|
pBank->AddSlider( "No. Vehicles Available", &numCarsAvailable, 1, 256, 0 );
|
|
|
|
vehicleNames.Reset();
|
|
vehicleNames.PushAndGrow( "Inactive" );
|
|
vehicleNames.PushAndGrow( "Activate" );
|
|
pBank->AddCombo( "Type Filter", &currVehicleTypeSelection, BANK_VEHICLE_TYPES, &ms_modelTypes[ 0 ], UpdateVehicleTypeList );
|
|
AddLayoutFilterWidget();
|
|
AddDLCFilterWidget();
|
|
pBank->AddCombo( "Swank Filter", &currVehicleSwankSelection, BANK_VEHICLE_SWANK, &ms_swankTypes[ 0 ], UpdateVehicleTypeList );
|
|
pBank->AddCombo( "Class Filter", &currVehicleClassSelection, BANK_VEHICLE_CLASS, &ms_classTypes[ 0 ], UpdateVehicleTypeList );
|
|
pVehicleCombo = pBank->AddCombo( "Vehicle name", &currVehicleNameSelection, 2, &vehicleNames[ 0 ], UpdateVehicleList );
|
|
pVehicleTrailerCombo = pBank->AddCombo( "Trailer name", &currVehicleTrailerNameSelection, 2, &vehicleNames[ 0 ], UpdateVehicleList );
|
|
pBank->AddSlider( "Vehicle Id", &carModelId, 0, 1000, 0 );
|
|
|
|
pBank->AddButton( "Create Vehicle", CreateCarCB );
|
|
pBank->AddButton( "Create Next Vehicle", CreateNextCarCB );
|
|
pBank->AddButton( "Create Next Bike", CreateNextBikeCB );
|
|
pBank->AddButton( "Create Chosen Vehicle", CreateChosenCarCB );
|
|
pBank->AddButton( "Delete Vehicle", DeleteCarCB );
|
|
pBank->AddSeparator();
|
|
pBank->AddButton( "Disable Vehicle Collision", DisableVehicleCollisionCB );
|
|
pBank->AddButton( "Disable Vehicle Collision Completely", DisableVehicleCollisionCompletelyCB );
|
|
pBank->AddButton( "Enable Vehicle Collision", EnableVehicleCollisionCB );
|
|
pBank->AddButton( "Explode Vehicle", ExplodeCarCB );
|
|
pBank->AddButton( "Reset Car Suspension", ResetCarSuspensionCB );
|
|
pBank->AddButton( "Warp plyr into last Vehicle", WarpPlayerIntoRecentCarCB );
|
|
pBank->AddButton( "Warp plyr out of Vehicle", WarpPlayerOutOfCarCB );
|
|
pBank->AddButton( "Drop Vehicle At Camera Position", DropFocusedVehicleAtCameraPosCB, "Drops the focus vehicle at the camera position" );
|
|
|
|
pBank->AddButton( "Populate w'Crowd 1", populateCarWithCrowd0CB );
|
|
pBank->AddButton( "Populate w'Crowd 2", populateCarWithCrowd1CB );
|
|
|
|
pBank->AddButton( "Reload Handling", ReloadHandlingDataCB );
|
|
pBank->AddButton( "Cycle Handling Info", CycleHandlingDebugCB );
|
|
pBank->AddButton( "Display Downforce", DisplayDownforceDebugCB );
|
|
pBank->AddButton( "Display New QA Debug", DisplayQADebugCB );
|
|
|
|
pBank->AddButton( "Remove trailers from world", RemoveTrailersCB );
|
|
pBank->AddButton( "Detach trailer from vehicle", DetachTrailerCB );
|
|
pBank->AddButton( "Toggle outrigger legs", ToggleOutriggersCB );
|
|
|
|
pBank->AddToggle( "Allow trailers to spawn", &ms_bSpawnTrailers );
|
|
pBank->AddToggle( "Spawn cars on trailer", &sSpawnCarsOnTrailer );
|
|
pBank->AddToggle( "Spawn cars with no breaking", &sSpawnCarsWithNoBreaking );
|
|
|
|
pBank->AddButton( "Reload vehicle lod data", ReloadVehicleMetaDataCB );
|
|
pBank->PopGroup();
|
|
|
|
pBank->PushGroup( "Handling debug" );
|
|
pBank->AddSlider( "Debug draw scale", &CVehicle::ms_fVehicleDebugScale, 0.0f, 5.0f, 1.0f );
|
|
pBank->AddToggle( "Draw Rev Ratio", &CVehicle::ms_bDebugDrawRevRatio );
|
|
pBank->AddToggle( "Draw Speed Ratio", &CVehicle::ms_bDebugDrawSpeedRatio );
|
|
pBank->AddToggle( "Draw Drive Force", &CVehicle::ms_bDebugDrawDriveForce );
|
|
pBank->AddToggle( "Draw Clutch Ratio", &CVehicle::ms_bDebugDrawClutchRatio );
|
|
pBank->AddToggle( "Draw Wheel Speed", &CVehicle::ms_bDebugDrawWheelSpeed );
|
|
pBank->AddToggle( "Draw Manifold Pressure", &CVehicle::ms_bDebugDrawManifoldPressure );
|
|
pBank->AddToggle( "Draw Large Text", &CVehicle::ms_bDebugDrawLargeText );
|
|
|
|
pBank->PopGroup();
|
|
#if STENCIL_VEHICLE_INTERIOR
|
|
pBank->PushGroup( "Interior Stenciling", false );
|
|
pBank->AddToggle( "Enable", &CVehicle::ms_StencilOutInterior );
|
|
pBank->PopGroup();
|
|
#endif
|
|
|
|
pBank->PushGroup( "Creation Options", false );
|
|
pBank->AddToggle( "Created Vehicle Needs To Be Hotwired", &bVehicleNeedsToBeHotwired );
|
|
pBank->AddToggle( "Instant-Start Vehicle Engine on Warp", &bVehicleInstantStartEngineOnWarp );
|
|
pBank->AddToggle( "Create as mission Vehicle", &bCreateAsMissionCar );
|
|
pBank->AddToggle( "Create as personal Vehicle", &bCreateAsPersonalCar );
|
|
pBank->AddToggle( "Create as gang Vehicle", &bCreateAsGangCar );
|
|
pBank->AddToggle( "Place on road properly", &bPlaceOnRoadProperly );
|
|
pBank->AddToggle( "Lock doors", &bLockDoors );
|
|
pBank->AddSlider( "Force extra on", &nForceExtraOn, 0, 14, 1 );
|
|
pBank->AddButton( "Next Colour", CycleNextColourCB );
|
|
pBank->AddButton( "Choose color on selected vehicle", ChooseColorCB );
|
|
pBank->PushGroup( "Vehicle Proofs", false );
|
|
pBank->AddToggle( "Fire proof", &bFireProof );
|
|
pBank->AddToggle( "Explosion proof", &bExplosionProof );
|
|
pBank->AddToggle( "Collision proof", &bCollisionProof );
|
|
pBank->AddToggle( "Bullet proof", &bBulletProof );
|
|
pBank->AddToggle( "Melee proof", &bMeleeProof );
|
|
pBank->PopGroup();
|
|
pBank->PopGroup();
|
|
|
|
pBank->PushGroup( "Enter tasks", false );
|
|
pBank->AddSlider( "Seat", &ms_iSeatToEnter, 0, MAX_VEHICLE_SEATS, 1 );
|
|
pBank->AddButton( "Player enter car in seat", GetPlayerToEnterSeat );
|
|
pBank->AddButton( "Focus ped enter car in seat", GetFocusPedToEnterSeat );
|
|
pBank->PopGroup();
|
|
|
|
pBank->PushGroup( "Wheel impacts and shapetest" );
|
|
pBank->AddToggle( "Async wheel shapetests", &CAutomobile::ms_bUseAsyncWheelProbes );
|
|
pBank->AddToggle( "Draw wheel shapetest results", &CAutomobile::ms_bDrawWheelProbeResults );
|
|
pBank->AddToggle( "ms_bActivateWheelImpacts", &CWheel::ms_bActivateWheelImpacts );
|
|
pBank->AddToggle( "Don't compress on recently broken fragments", &CWheel::ms_bDontCompressOnRecentlyBrokenFragments );
|
|
pBank->AddToggle( "Precompute Extra Wheel Bound Impacts", &CVehicle::ms_bPrecomputeExtraWheelBoundImpacts );
|
|
pBank->PopGroup();
|
|
|
|
|
|
pBank->PushGroup( "Debug Options", false );
|
|
pBank->AddToggle( "Display Vehicle Names", &ms_bDisplayVehicleNames );
|
|
pBank->AddToggle( "Display Vehicle Addresses", &CVehicleIntelligence::m_bDisplayCarAddresses );
|
|
pBank->AddToggle( "Display Vehicle Layout", &ms_bDisplayVehicleLayout );
|
|
pBank->AddButton( "Dump Vehicle Layouts", DumpVehicleLayoutsCB );
|
|
pBank->AddToggle( "Display creation location", &ms_bDisplayCreateLocation );
|
|
pBank->AddToggle( "Vehicle status debug", &CVehicle::ms_bDebugVehicleStatus );
|
|
pBank->AddToggle( "Vehicle is driveable failure debug", &CVehicle::ms_bDebugVehicleIsDriveableFail );
|
|
pBank->AddToggle( "Vehicles consume petrol", CVehicle::GetConsumePetrolPtr() );
|
|
pBank->AddToggle( "Visualise petrol level", &CVehicle::m_bDebugVisPetrolLevel );
|
|
pBank->AddToggle( "Display Tyre Wear", &CVehicleFactory::ms_bDisplayTyreWearRate );
|
|
pBank->PushGroup( "Wheels debug info", false);
|
|
pBank->AddToggle( "Display steer angle", &CVehicleFactory::ms_bDisplaySteerAngle);
|
|
pBank->PopGroup();
|
|
pBank->PushGroup( "Fire Vehicle", false );
|
|
pBank->AddButton( "Fire Vehicle", FireCarCB );
|
|
pBank->AddButton( "Fire Vehicle from Debug Cam", FireCarFromDebugCamCB );
|
|
pBank->AddButton( "Fire Vehicle with Player", FireCarWithPlayerCB );
|
|
pBank->AddButton( "Fire Vehicle with Player from Debug Cam", FireCarWithPlayerFromDebugCamCB );
|
|
pBank->AddButton( "Fire Vehicle and Object", FireCarWithObjectCB );
|
|
pBank->AddButton( "Fire Vehicle and Object from Debug Cam", FireCarWithObjectFromDebugCamCB );
|
|
pBank->AddButton( "Fire Player Ragdoll", FirePlayerRagdollCB );
|
|
pBank->AddButton( "Fire Player Ragdoll from Debug Cam", FirePlayerRagdollFromDebugCamCB );
|
|
pBank->AddButton( "Fire Object", FireObjectCB );
|
|
pBank->AddButton( "Fire Object from Debug Cam", FireObjectFromDebugCamCB );
|
|
pBank->AddButton( "Set launch direction to vehicle heading", SetLaunchDirectionMatchOrientationCB );
|
|
pBank->AddButton( "SAVE Launch Settings", SaveSettingsCB );
|
|
pBank->AddButton( "LOAD Launch Settings", LoadSettingsCB );
|
|
pBank->AddSlider( "Vel", &sFireCarVel, 0.0f, 100.0f, 1.0f );
|
|
pBank->AddSlider( "Pos X", &sFireCarPos.x, -8000.0f, 8000.0f, 0.1f );
|
|
pBank->AddSlider( "Pos Y", &sFireCarPos.y, -8000.0f, 8000.0f, 0.1f );
|
|
pBank->AddSlider( "Pos Z", &sFireCarPos.z, -1000.0f, 5000.0f, 0.1f );
|
|
pBank->AddSlider( "Dirn X", &sFireCarDirn.x, -1.0f, 1.0f, 0.01f );
|
|
pBank->AddSlider( "Dirn Y", &sFireCarDirn.y, -1.0f, 1.0f, 0.01f );
|
|
pBank->AddSlider( "Dirn Z", &sFireCarDirn.z, -1.0f, 1.0f, 0.01f );
|
|
pBank->AddSlider( "Orient X", &sFireCarOrient.x, -PI, PI, 0.05f, FireCarOrientCB );
|
|
pBank->AddSlider( "Orient Y", &sFireCarOrient.y, -PI, PI, 0.05f, FireCarOrientCB );
|
|
pBank->AddSlider( "Orient Z", &sFireCarOrient.z, -PI, PI, 0.05f, FireCarOrientCB );
|
|
pBank->AddSlider( "Object offset X", &sFireObjectOffset.x, -3000.0f, 3000.0f, 0.1f );
|
|
pBank->AddSlider( "Object offset Y", &sFireObjectOffset.y, -3000.0f, 3000.0f, 0.1f );
|
|
pBank->AddSlider( "Object offset Z", &sFireObjectOffset.z, -3000.0f, 3000.0f, 0.1f );
|
|
pBank->PushGroup( "Turn speed" );
|
|
Vector3 vLimit( 100.0f, 100.0f, 100.0f );
|
|
pBank->AddSlider( "Turn speed", &svFireCarSpin, -vLimit, vLimit, vLimit / 1000.0f );
|
|
pBank->PopGroup();
|
|
pBank->AddToggle( "Force Pos", &ms_bFireCarForcePos );
|
|
pBank->AddToggle( "Regenerate vehicle", &ms_bRegenerateFireVehicle );
|
|
pBank->PopGroup();
|
|
|
|
pBank->PushGroup( "Weapon", false );
|
|
pBank->AddButton( "Fire Rocket If Available", FireVehiclesRocketCB );
|
|
pBank->PopGroup();
|
|
|
|
pBank->PushGroup( "Health", false );
|
|
pBank->AddButton( "Set Engine Health", SetEngineHealthCB );
|
|
pBank->AddSlider( "New Engine Health", &ms_fSetEngineNewHealth, ENGINE_DAMAGE_FINSHED, ENGINE_HEALTH_MAX, 100.0f );
|
|
pBank->PopGroup();
|
|
|
|
pBank->PushGroup( "Planes", false );
|
|
pBank->AddButton( "Break Off Left Wing", breakOffLeftWingCB );
|
|
pBank->AddButton( "Break Off Right Wing", breakOffRightWingCB );
|
|
pBank->AddButton( "Remove Landing Gears", removeLandingGearCB );
|
|
pBank->PopGroup();
|
|
|
|
pBank->PushGroup( "Doors", false );
|
|
pBank->AddButton( "Randomly open/close doors", randomlyOpenAndCloseDoorsCB );
|
|
pBank->AddButton( "Open all doors fully", openAllDoorsCB );
|
|
pBank->AddButton( "Close all doors", closeAllDoorsCB );
|
|
pBank->AddButton( "Unlatch all doors", unlatchAllDoorsCB );
|
|
pBank->AddButton( "Break off all doors", breakOffAllDoorsCB );
|
|
pBank->AddToggle( "Apply vehicle deformation to door hinges", &bbApplyCarDoorDeformation );
|
|
pBank->AddSlider( "Door break off threshold (meters)", &bfCarDoorBreakThreshold, 0.0f, 0.3f, 0.01f );
|
|
const char* doorNames[] = // same order as CVehicleModelInfo::ms_aSetupDoorIds
|
|
{
|
|
"VEH_DOOR_DSIDE_F",
|
|
"VEH_DOOR_DSIDE_R",
|
|
"VEH_DOOR_PSIDE_F",
|
|
"VEH_DOOR_PSIDE_R",
|
|
"VEH_BONNET",
|
|
"VEH_BOOT",
|
|
"VEH_BOOT_2",
|
|
"VEH_FOLDING_WING_L",
|
|
"VEH_FOLDING_WING_R"
|
|
};
|
|
CompileTimeAssert( NELEM( doorNames ) == NUM_VEH_DOORS_MAX );
|
|
pBank->AddCombo( "Door", &ms_iDoorToOpen, NELEM( doorNames ), doorNames );
|
|
pBank->AddSlider( "Open door ratio", &sDoorOpenAmount, 0.0f, 1.0f, 0.05f );
|
|
pBank->AddButton( "Open door", openDoorCB );
|
|
pBank->AddButton( "Close door", closeDoorCB );
|
|
pBank->AddButton( "Unlatch door", unlatchDoorCB );
|
|
pBank->AddButton( "Break off door", breakOffDoorCB );
|
|
pBank->AddToggle( "Door Can Be Reset", &bDoorCanBeReset );
|
|
|
|
pBank->AddButton( "Open bomb bay door", openBombBayDoorsCB );
|
|
pBank->AddButton( "Close bomb bay door", closeBombBayDoorsCB );
|
|
|
|
pBank->AddToggle( "Allow rear doors to open", &ms_rearDoorsCanOpen );
|
|
pBank->AddButton( "Trigger car alarm", triggerCarAlarmCB );
|
|
pBank->AddButton( "Output door stuck debug for local player", outputDoorStuckDebugCB );
|
|
pBank->AddButton( "Deploy Folding Wings", deployFoldingWingsCB );
|
|
pBank->PopGroup();
|
|
|
|
pBank->PushGroup( "Joints", false );
|
|
pBank->AddButton( "Swing open boat boom", swingOpenBooatBoomCB );
|
|
pBank->AddButton( "Swing in boat boom", swingInBooatBoomCB );
|
|
pBank->PopGroup();
|
|
|
|
pBank->PushGroup( "Tyres", false );
|
|
pBank->AddSlider( "Tyre index", &ms_iTyreNumber, 0, NUM_VEH_CWHEELS_MAX, 1 );
|
|
pBank->AddButton( "Repair Tyre", repairTyreCB );
|
|
pBank->AddButton( "Break off Tyre", breakOffTyreCB );
|
|
pBank->AddButton( "Toggle Burnout Mode", ToggleBurnoutModeCB );
|
|
pBank->AddButton( "Toggle Reduce Grip Mode", ToggleReduceGripModeCB );
|
|
pBank->AddButton( "Toggle Reduced Suspension Force", ToggleReducedSuspensionForceCB );
|
|
pBank->AddButton( "Toggle Drift Tyres", ToggleDriftTyresCB );
|
|
pBank->AddButton( "Toggle HOLD_GEAR_WITH_WHEELSPIN_FLAG", ToggleHoldGearWithWheelspinFlagCB );
|
|
pBank->PopGroup();
|
|
|
|
pBank->PushGroup( "Top Speed", false );
|
|
pBank->AddSlider( "Top Speed Modifier", &sfTopSpeedAdjustment, -50.0f, 5000.0f, 1.0f );
|
|
pBank->AddButton( "Apply To Last Car", ApplyTopSpeedToLastCarCB );
|
|
pBank->AddButton( "Clear 0-60, 60-0 and highest g force", ClearZeroSixtySixtyZeroGForceCarCB );
|
|
pBank->PopGroup();
|
|
|
|
pBank->PushGroup( "Convertible Roof", false );
|
|
pBank->AddButton( "Lower roof", lowerRoofCB );
|
|
pBank->AddButton( "Raise roof", raiseRoofCB );
|
|
pBank->AddToggle( "Lower/Raise instantly", &bLowerOrRaiseRoofInstantly );
|
|
pBank->PopGroup();
|
|
|
|
pBank->PushGroup( "Self Righting", false );
|
|
pBank->AddToggle( "Apply new self-righting", &CVehicle::sm_bUseNewSelfRighting );
|
|
pBank->AddSlider( "In air torque x", &CAutomobile::CAR_INAIR_ROT_X, 0.0f, 10.0f, 0.1f );
|
|
pBank->AddSlider( "In air torque y", &CAutomobile::CAR_INAIR_ROT_Y, 0.0f, 10.0f, 0.1f );
|
|
pBank->AddSlider( "In air torque z", &CAutomobile::CAR_INAIR_ROT_Z, -10.0f, 0.0f, 0.1f );
|
|
pBank->AddSlider( "Stuck torque x", &CAutomobile::CAR_STUCK_ROT_X, 0.0f, 10.0f, 0.1f );
|
|
pBank->AddSlider( "Stuck torque y", &CAutomobile::CAR_STUCK_ROT_Y, 0.0f, 10.0f, 0.1f );
|
|
pBank->AddSlider( "Stuck torque y in self righting direction", &CAutomobile::CAR_STUCK_ROT_Y_SELF_RIGHT, 0.0f, 30.0f, 0.1f );
|
|
pBank->AddSlider( "In air angular speed limit", &CAutomobile::CAR_INAIR_ROTLIM, 0.0f, 10.0f, 0.1f );
|
|
pBank->AddSlider( "Possibly stuck speed threshold", &CAutomobile::POSSIBLY_STUCK_SPEED, 0.0f, 5.0f, 0.01f );
|
|
pBank->AddSlider( "Completely stuck speed threshold", &CAutomobile::COMPLETELY_STUCK_SPEED, 0.0f, 5.0f, 0.01f );
|
|
pBank->AddSlider( "self righting bias cg offset z", &CVehicle::smVecSelfRightBiasCGOffset.z, -10.0f, 0.0f, 0.1f );
|
|
pBank->PopGroup();
|
|
|
|
pBank->AddButton( "Toggle Gravity", toggleGravityCB );
|
|
pBank->AddButton( "Pop out windscreen", popOutWindscreenCB );
|
|
pBank->AddButton( "Set out of Control", setOutOfControlCB );
|
|
pBank->AddSlider( "Roof impulse X", &sRoofImpulse.x, -50.0f, 50.0f, 0.1f );
|
|
pBank->AddSlider( "Roof impulse Y", &sRoofImpulse.y, -50.0f, 50.0f, 0.1f );
|
|
pBank->AddSlider( "Roof impulse Z", &sRoofImpulse.z, -50.0f, 50.0f, 0.1f );
|
|
pBank->AddButton( "Pop off roof", popOffRoofCB );
|
|
pBank->AddSlider( "Drop last Vehicle", &carDropHeight, 1.0f, 100.0f, 1.0f, DropCarCB );
|
|
pBank->AddSlider( "Test Vehicle against world", &carTestHeight, -10.0f, 10.0f, 0.1f, TestCarAgainstWorldCB );
|
|
pBank->AddToggle( "Use debug cam rotation", &bUseDebugCamRotation );
|
|
pBank->AddSlider( "Vehicle rotation", &carDropRotation, -3.141f, 3.141f, 0.1f );
|
|
pBank->AddButton( "Lock last Vehicle", LockLastCar );
|
|
pBank->AddButton( "Switch dummy physics", ToggleDummyPhysicsCB );
|
|
pBank->AddButton( "Freeze Vehicle", FreezeVehicleCB );
|
|
pBank->AddButton( "Unfreeze Vehicle", UnfreezeVehicleCB );
|
|
pBank->AddSlider( "Hydraulic suspension", &CVehicle::ms_fHydraulicSuspension, 0, 1.0f, 0.01f, HydraulicSuspensionCB );
|
|
pBank->AddSlider( "Test Gravity Scale", &CVehicle::ms_fGravityScale, 0.1f, 10.0f, 0.01f );
|
|
pBank->AddToggle( "Force bike lean", &CVehicle::ms_bForceBikeLean );
|
|
pBank->AddToggle( "Use Automobile BVH update", &CVehicle::ms_bUseAutomobileBVHupdate );
|
|
pBank->AddToggle( "Always update composite bound", &CVehicle::ms_bAlwaysUpdateCompositeBound );
|
|
pBank->AddToggle( "Force slow zone", &CVehicle::ms_bForceSlowZone );
|
|
pBank->AddButton( "Anchor boat", ToggleAnchorBoatCB );
|
|
pBank->AddButton( "Reset Suspension", resetSuspensionCB );
|
|
pBank->AddSlider( "Ground Clearance", &CVehicle::ms_fForcedGroundClearance, 0.0f, 2.5f, 0.01f );
|
|
pBank->AddButton( "Set Ground Clearance", setGroundClearanceCB );
|
|
pBank->AddSlider( "Bike Max Jump Time", &CBike::ms_fBikeJumpFullPowerTime, 0.0f, 10000.0f, 1.0f );
|
|
pBank->AddToggle( "Stop Vehicles Damaging", &gbStopVehiclesDamaging );
|
|
pBank->AddToggle( "Don't Display Dirt on Vehicles", &gbDontDisplayDirtOnVehicles );
|
|
pBank->AddToggle( "Use wheel integration task", &CWheel::ms_bUseWheelIntegrationTask );
|
|
pBank->AddToggle( "Disable mid-air integrator", &sbDisableMidairWheelIntegrator );
|
|
#if __DEV
|
|
pBank->AddToggle( "Stop Vehicles Exploding", &gbStopVehiclesExploding );
|
|
extern bool g_UseAdditionalWheelSweep;
|
|
pBank->AddToggle( "Use wheel additional sweep and don't add velocity", &g_UseAdditionalWheelSweep );
|
|
extern bool gbAlwaysRemoveWheelImpacts;
|
|
pBank->AddToggle( "Always remove wheel impacts", &gbAlwaysRemoveWheelImpacts );
|
|
pBank->AddSlider( "Force Vehicle Colors Mode", &CCustomShaderEffectVehicle::ms_nForceColorCars, 0, 2, 1 );
|
|
pBank->AddSlider( "Sound Horn", &carSoundHornTime, 0, 10, 1, SoundCarHornCB );
|
|
pBank->AddSlider( "Petrol Level", &sfPetrolTankLevel, 0.0f, 200.0f, 0.1f );
|
|
pBank->AddButton( "Set Petrol Level", ChangePetrolTankLevelCarCB );
|
|
pBank->AddToggle( "Render petrol tank damage", &gbRenderPetrolTankDamage );
|
|
#endif
|
|
pBank->AddSlider( "Player car inverse mass scale", &gfPlayerCarInvMassScale, 0.0f, 10.0f, 0.01f );
|
|
pBank->AddButton( "Set vehicle on fire", SetVehicleOnFireCB );
|
|
pBank->AddButton( "Set vehicle on fire and clear health", SetVehicleOnFireAndClearHealthCB );
|
|
pBank->AddButton( "Turn on searchlight", SetVehicleSearchlightCB );
|
|
pBank->AddSlider( "Ambient Occlusion height cutoff", &CVehicle::ms_fAOHeightCutoff, 1.0f, 75.0f, 0.5f );
|
|
pBank->PopGroup();
|
|
|
|
pBank->PushGroup( "Roof", false );
|
|
pBank->AddSlider( "Max speed squared for opening/closing roof(m/s)", &CTaskVehicleConvertibleRoof::ms_fMaximumSpeedToOpenRoofSq, 0.0f, 2000.0f, 0.001f );
|
|
pBank->AddButton( "Open roof", openRoofCB );
|
|
pBank->AddButton( "Close roof", closeRoofCB );
|
|
pBank->PopGroup();
|
|
|
|
pBank->PushGroup( "Handling cheats", false );
|
|
pBank->AddToggle( "Abs", &sbCheatAbs );
|
|
pBank->AddToggle( "Tc", &sbCheatTractionControl );
|
|
pBank->AddToggle( "Sc", &sbCheatStabilityControl );
|
|
pBank->AddToggle( "Grip1", &sbCheatGrip1 );
|
|
pBank->AddToggle( "Grip2", &sbCheatGrip2 );
|
|
pBank->AddToggle( "Power1", &sbCheatPower1 );
|
|
pBank->AddToggle( "Power2", &sbCheatPower2 );
|
|
pBank->AddButton( "Apply to last car", ApplyCheatsToLastCarCB );
|
|
pBank->AddButton( "Apply to selected car", ApplyCheatsToSelectedCarCB );
|
|
pBank->PopGroup();
|
|
|
|
pBank->PushGroup( "Passengers", false );
|
|
pBank->AddSlider( "Passenger Mass Mult", &CAutomobile::m_sfPassengerMassMult, -0.5f, 1.5f, 0.001f );
|
|
pBank->PopGroup();
|
|
|
|
pBank->PushGroup( "LOD", false );
|
|
gDrawListMgr->SetupLODWidgets( *pBank, (int*)1, (int*)1, NULL, (int*)1 );
|
|
pBank->AddToggle( "Force HD", &CVehicleFactory::ms_bForceHd, ForceHdCB );
|
|
pBank->AddSlider( "Lod multiplier", &CVehicleFactory::ms_fLodMult, 0.1f, 10.f, 0.01f, LodMultCB );
|
|
pBank->AddSlider( "Clamp render lod", &CVehicleFactory::ms_clampedRenderLod, -1, 3, 1, ClampRenderLodCB );
|
|
pBank->PopGroup();
|
|
|
|
pBank->PushGroup( "Flying Skill", false );
|
|
pBank->AddToggle( "Ace Pilot", &CVehicleFactory::ms_bflyingAce );
|
|
pBank->PopGroup();
|
|
|
|
#if __BANK
|
|
pBank->PushGroup( "Physics", false );
|
|
pBank->AddToggle( "PreComputeImpacts", &CVehicle::sm_PreComputeImpacts );
|
|
pBank->AddToggle( "Door Debug Output", &CCarDoor::sm_debugDoorPhysics );
|
|
pBank->PopGroup();
|
|
#endif
|
|
|
|
pBank->PushGroup( "Dials", false );
|
|
pBank->AddToggle( "Add Dials To Selected Vehicle", &CVehicleFactory::ms_bForceDials );
|
|
pBank->PopGroup();
|
|
|
|
CBike::InitWidgets( *pBank );
|
|
CQuadBike::InitWidgets( *pBank );
|
|
CPlane::InitWidgets( *pBank );
|
|
CPropeller::InitWidgets( *pBank );
|
|
CRotaryWingAircraft::InitWidgets();
|
|
CSearchLight::InitWidgets( *pBank );
|
|
CBoat::InitWidgets( *pBank );
|
|
CTrain::InitWidgets( *pBank );
|
|
CTrailer::InitWidgets( pBank );
|
|
|
|
CBoardingPointEditor::CreateWidgets( pBank );
|
|
CAIHandlingInfoMgr::AddWidgets( *pBank );
|
|
|
|
CVehicleGadget::AddWidgets( *pBank );
|
|
|
|
|
|
#if __DEV
|
|
CHeadlightTuningData::SetupHeadlightTuningBank( *pBank );
|
|
CNeonTuningData::SetupNeonTuningBank( *pBank );
|
|
#endif // __DEV
|
|
|
|
pBank->PushGroup( "Vehicle Damage" );
|
|
pBank->PushGroup( "Wheel Damage", false );
|
|
pBank->AddSlider( "Burst Chance", &CWheel::ms_fWheelBurstDamageChance, 0.0f, 1.0f, 0.001f );
|
|
pBank->AddSlider( "Break Chance", &CVehicleDamage::ms_fChanceToBreak, 0.0f, 1.0f, 0.001f );
|
|
pBank->AddSlider( "Damage Threshold", &CVehicle::sm_WheelDamageRadiusThreshold, 0.0f, 20.0f, 0.01f );
|
|
pBank->AddSlider( "Additional Undamaged Damage Thresh", &CVehicle::sm_WheelDamageRadiusThreshWheelDamageMax, 0.0f, 20.0f, 0.01f );
|
|
pBank->AddSlider( "Damaged Damage Thresh Reduction Scale", &CVehicle::sm_WheelDamageRadiusThreshWheelDamageScale, 0.0f, 20.0f, 0.01f );
|
|
pBank->AddSlider( "Damage Radius Scale", &CVehicle::sm_WheelDamageRadiusScale, 0.0f, 50.0f, 0.01f );
|
|
pBank->AddSlider( "Damage Inner Radius Scale", &CVehicle::sm_WheelSelfRadiusScale, 0.0f, 50.0f, 0.01f );
|
|
pBank->AddSlider( "Damage Heavy Radius Scale", &CVehicle::sm_WheelHeavyDamageRadiusScale, 0.0f, 50.0f, 0.01f );
|
|
pBank->AddSlider( "Damage Heavy Inner Radius Scale", &CVehicle::sm_WheelSelfHeavyWheelRadiusScale, 0.0f, 50.0f, 0.01f );
|
|
pBank->AddSlider( "Friction Damage Thresh For Burst", &CWheel::ms_fFrictionDamageThreshForBurst, 0.0f, 2.0f, 0.001f );
|
|
pBank->AddSlider( "Friction Damage Thresh For Burst", &CWheel::ms_fFrictionDamageThreshForBreak, 0.0f, 2.0f, 0.001f );
|
|
pBank->AddButton( "Break off all wheels", CVehicleDamage::BreakOffWheelsCB );
|
|
pBank->PopGroup();
|
|
pBank->AddSlider( "Deformation threshold multiplier for MP game", &bfDeformationThresholdMPMult, 0.0f, 5.0f, 0.01f );
|
|
pBank->AddSlider( "Max Vehicle Breaks Per Second", &CVehicle::ms_MaxVehicleBreaksPerSecond, 0.0f, 20.0f, 1.0f );
|
|
pBank->AddSlider( "Vehicle Breaks Per Second", &CVehicle::ms_VehicleBreaksPerSecond, 0.0f, 30.0f, 1.0f );
|
|
pBank->AddSlider( "Vehicle Break Rolling Window Size (seconds)", &CVehicle::ms_VehicleBreakWindowSize, 1, 30, 1 );
|
|
pBank->PushGroup( "Vehicle Deformation", true );
|
|
pBank->AddToggle( "Show both texture and rendertarget", &CVehicleDeformation::ms_bShowTextureAndRenderTarget );
|
|
pBank->AddSlider( "Texture and Rendertarget scale", &CVehicleDeformation::ms_fDisplayTextureScale, 0.0f, 10.0f, 0.1f );
|
|
pBank->AddToggle( "Display the damage map", &CVehicleDeformation::ms_bDisplayDamageMap );
|
|
pBank->AddToggle( "Display the damage multiplier", &CVehicleDeformation::ms_bDisplayDamageMult );
|
|
pBank->AddToggle( "Force global damage map scale", &CVehicleDeformation::ms_bForceDamageMapScale );
|
|
pBank->AddToggle( "Full damage (similar to explosion) for collisions below", &CVehicleDeformation::ms_bFullDamage );
|
|
pBank->AddSlider( "Global damage map scale", &CVehicleDeformation::ms_fForcedDamageMapScale, 0.0f, 1.0f, 0.01f );
|
|
pBank->AddSlider( "Weapon impact damage scale", &CVehicleDeformation::ms_fWeaponImpactDamageScale, 0.0f, 10.0f, 0.01f );
|
|
pBank->AddSlider( "Collision X Multiplier", &CVehicleDeformation::ms_fVehDefColMultX, 0.0f, 10.0f, 0.01f );
|
|
pBank->AddSlider( "Collision Y Multiplier", &CVehicleDeformation::ms_fVehDefColMultY, 0.0f, 10.0f, 0.01f );
|
|
pBank->AddSlider( "Collision Z Multiplier", &CVehicleDeformation::ms_fVehDefColMultZ, 0.0f, 10.0f, 0.01f );
|
|
pBank->AddSlider( "Collision Negative Y Multiplier", &CVehicleDeformation::ms_fVehDefColMultYNeg, 0.0f, 10.0f, 0.01f );
|
|
pBank->AddSlider( "Collision Negative Z Multiplier", &CVehicleDeformation::ms_fVehDefColMultZNeg, 0.0f, 10.0f, 0.01f );
|
|
pBank->AddSlider( "Roof Collision Negative Z Multiplier", &CVehicleDeformation::ms_fVehDefRoofColMultZNeg, 0.0f, 10.0f, 0.01f );
|
|
|
|
pBank->AddToggle( "Enable max z deformation clamping", &CVehicleDeformation::ms_bEnableRoofZDeformationClamping );
|
|
|
|
pBank->AddSlider( "Roof Max Z Deformation", &CVehicleDeformation::ms_fDeformationCarRoofMinZ, -0.5f, -0.1f, 0.01f );
|
|
pBank->AddSlider( "Car mod bone deformation multiplier", &CVehicleDeformation::ms_fCarModBoneDeformMult, 0.0f, 2.0f, 0.01f );
|
|
|
|
pBank->AddSlider( "Mods damage offset X", &CVehicleDeformation::m_OffsetDamageToMods_X, -2.0f, 2.0f, 0.01f );
|
|
pBank->AddSlider( "Mods damage offset Y", &CVehicleDeformation::m_OffsetDamageToMods_Y, -2.0f, 2.0f, 0.01f );
|
|
pBank->AddSlider( "Mods damage offset Z", &CVehicleDeformation::m_OffsetDamageToMods_Z, -2.0f, 2.0f, 0.01f );
|
|
|
|
pBank->AddSlider( "Car Damage lookup offset X", &CVehicleDeformation::m_DamageTextureOffset_X, -20.0f, 20.0f, 0.01f );
|
|
pBank->AddSlider( "Car Damage lookup offset Y", &CVehicleDeformation::m_DamageTextureOffset_Y, -20.0f, 20.0f, 0.01f );
|
|
pBank->AddSlider( "Car Damage lookup offset Z", &CVehicleDeformation::m_DamageTextureOffset_Z, -20.0f, 20.0f, 0.01f );
|
|
|
|
pBank->AddSlider( "Car Body Damage X coordinate", &CVehicleDeformation::m_ImpactPositionLocal_X, -20.0f, 20.0f, 0.01f );
|
|
pBank->AddSlider( "Car Body Damage Y coordinate", &CVehicleDeformation::m_ImpactPositionLocal_Y, -20.0f, 20.0f, 0.01f );
|
|
pBank->AddSlider( "Car Body Damage Z coordinate", &CVehicleDeformation::m_ImpactPositionLocal_Z, -20.0f, 20.0f, 0.01f );
|
|
|
|
pBank->AddSlider( "Car Body Impulse X", &CVehicleDeformation::m_Impulse_X, -1.0f, 1.0f, 0.01f );
|
|
pBank->AddSlider( "Car Body Impulse Y", &CVehicleDeformation::m_Impulse_Y, -1.0f, 1.0f, 0.01f );
|
|
pBank->AddSlider( "Car Body Impulse Z", &CVehicleDeformation::m_Impulse_Z, -1.0f, 1.0f, 0.01f );
|
|
|
|
pBank->AddSlider( "Car Body Damage Amount", &CVehicleDeformation::ms_fDamageAmount, 0.0f, 100000.0f, 0.01f );
|
|
pBank->AddSlider( "Car mod bone deformation multiplier", &CVehicleDeformation::ms_fCarModBoneDeformMult, 0.0f, 2.0f, 0.01f );
|
|
|
|
pBank->AddSlider( "Damage % to apply", &CVehicleDeformation::ms_fDamagePercent, 1.0f, 100.0f, 1.0f );
|
|
pBank->AddButton( "Damage car by (above) % of max health", CVehicleDamage::DamageCurrentCarByPercentage );
|
|
|
|
pBank->AddButton( "Damage car body now", CVehicleDamage::DamageCurrentCar );
|
|
pBank->AddButton( "Damage Driver side roof", CVehicleDamage::DamageDriverSideRoof );
|
|
pBank->AddButton( "Head On Collision", CVehicleDamage::HeadOnCollision );
|
|
pBank->AddButton( "Rear End Collision", CVehicleDamage::RearEndCollision );
|
|
pBank->AddButton( "Left side Collision", CVehicleDamage::LeftSideCollision );
|
|
pBank->AddButton( "Right side Collision", CVehicleDamage::RightSideCollision );
|
|
pBank->AddButton( "Tail Rotor Collision", CVehicleDamage::TailRotorCollision );
|
|
pBank->AddButton( "Submarine Implosion", CVehicleDamage::ImplodeSubmarine );
|
|
|
|
pBank->AddSlider( "Extra explosion impulses", &CVehicleDeformation::ms_iExtraExplosionDeformations, 0, MAX_IMPACTS_PER_VEHICLE_PER_FRAME - 1, 1 );
|
|
pBank->AddSlider( "Extra explosion damage", &CVehicleDeformation::ms_fExtraExplosionsDamage, 0.0f, 100.0f, 1.0f );
|
|
pBank->AddButton( "Random Smash", CVehicleDamage::RandomSmash );
|
|
|
|
pBank->AddToggle( "Enable AutoFix", &CVehicleDeformation::ms_bAutoFix );
|
|
pBank->AddButton( "Fix Damage", &CVehicleDamage::FixDamageForTests );
|
|
pBank->AddToggle( "Enable AutoSaving Damage Texture", &CVehicleDeformation::ms_bAutoSaveDamageTexture );
|
|
|
|
pBank->AddToggle( "Enable Bounds Update", &CVehicleDeformation::ms_bUpdateBoundsEnabled );
|
|
pBank->AddToggle( "Enable Bones Update", &CVehicleDeformation::ms_bUpdateBonesEnabled );
|
|
|
|
#if GPU_DAMAGE_WRITE_ENABLED
|
|
pBank->AddToggle( "Update Physics pre-sim", &CVehicleDeformation::ms_bUpdateDamageFromPhysicsThread );
|
|
pBank->AddToggle( "Enable GPU Damage", &CVehicleDamage::ms_bEnableGPUDamage );
|
|
pBank->AddSlider( "Forced Damage", &CVehicleDamage::ms_iForcedDamageEveryFrame, 0, MAX_IMPACTS_PER_VEHICLE_PER_FRAME, 1 );
|
|
#endif
|
|
pBank->AddToggle( "Display Damage Vectors", &CVehicleDamage::ms_bDisplayDamageVectors );
|
|
pBank->AddButton( "Save DamageTexture.jpg", CVehicleDamage::SaveDamageTexture );
|
|
pBank->AddButton( "Load DamageTexture.jpg", CVehicleDamage::LoadDamageTexture );
|
|
|
|
pBank->AddSlider( "Force propeller speed", &CVehicleDeformation::ms_fForcedPropellerSpeed, -100.0f, 100.0f, 1.0f );
|
|
pBank->AddSlider( "Large Vehicle Radius Multiplier", &CVehicleDeformation::ms_fLargeVehicleRadiusMultiplier, 0.0f, 1.5f, 0.1f );
|
|
|
|
#if VEHICLE_DEFORMATION_PROPORTIONAL
|
|
pBank->AddSlider( "Vehicle Damage Magnitude Multiplier", &CVehicleDeformation::ms_fDamageMagnitudeMult, 0.01f, 10.0f, 0.01f, CVehicleDamage::UpdateDamageMultiplier, "" );
|
|
#endif
|
|
pBank->AddToggle( "Enable Damaging around bone bounds", &CVehicleDeformation::ms_bEnableExtraBoneDeformations );
|
|
pBank->AddToggle( "Enable Car Roof Z-Deformation Clamping", &CVehicleDeformation::ms_bEnableRoofZDeformationClamping );
|
|
|
|
pBank->AddButton( "Drop a 5-ton container on this object at X meters height", CVehicleDamage::DropFiveTonContainer );
|
|
pBank->AddButton( "Remove wheel", CVehicleDamage::RemoveWheel );
|
|
|
|
pBank->AddToggle( "Hide Propellers", &CVehicleDeformation::ms_bHidePropellers );
|
|
pBank->AddSlider( "Force propeller speed", &CVehicleDeformation::ms_fForcedPropellerSpeed, -60.0f, 60.0f, 1.0f );
|
|
pBank->AddButton( "Break off helicopter tail", CVehicleDamage::RemoveHelicopterTail );
|
|
pBank->AddButton( "Break off helicopter propellers", CVehicleDamage::RemoveHelicopterPropellers );
|
|
|
|
pBank->PushGroup( "Network Damage Modifiers", false );
|
|
|
|
pBank->AddSlider( "Network front left damage", &CVehicleDamage::g_DamageDebug[ 0 ], 0, 3, 1 );
|
|
pBank->AddSlider( "Network front right damage", &CVehicleDamage::g_DamageDebug[ 1 ], 0, 3, 1 );
|
|
pBank->AddSlider( "Network middle left damage", &CVehicleDamage::g_DamageDebug[ 2 ], 0, 3, 1 );
|
|
pBank->AddSlider( "Network middle right damage", &CVehicleDamage::g_DamageDebug[ 3 ], 0, 3, 1 );
|
|
pBank->AddSlider( "Network rear left damage", &CVehicleDamage::g_DamageDebug[ 4 ], 0, 3, 1 );
|
|
pBank->AddSlider( "Network rear right damage", &CVehicleDamage::g_DamageDebug[ 5 ], 0, 3, 1 );
|
|
|
|
pBank->AddButton( "Network Smash", CVehicleDamage::NetworkSmashDebug );
|
|
pBank->AddButton( "Network Smash Random", CVehicleDamage::NetworkSmashDebugRandom );
|
|
|
|
pBank->AddSlider( "Network front left damage value", &CVehicleDamage::g_DamageValue[ 0 ], -1.0f, 10.0f, 0.0f );
|
|
pBank->AddSlider( "Network front right damage value", &CVehicleDamage::g_DamageValue[ 1 ], -1.0f, 10.0f, 0.0f );
|
|
pBank->AddSlider( "Network middle left damage value", &CVehicleDamage::g_DamageValue[ 2 ], -1.0f, 10.0f, 0.0f );
|
|
pBank->AddSlider( "Network middle right damage value", &CVehicleDamage::g_DamageValue[ 3 ], -1.0f, 10.0f, 0.0f );
|
|
pBank->AddSlider( "Network rear left damage value", &CVehicleDamage::g_DamageValue[ 4 ], -1.0f, 10.0f, 0.0f );
|
|
pBank->AddSlider( "Network rear right damage value", &CVehicleDamage::g_DamageValue[ 5 ], -1.0f, 10.0f, 0.0f );
|
|
|
|
pBank->AddSlider( "Front left level 0", &CVehicleDeformation::networkDamageModifiers[ 0 ][ 0 ], 0.0f, 10.0f, 0.01f );
|
|
pBank->AddSlider( "Front left level 1", &CVehicleDeformation::networkDamageModifiers[ 0 ][ 1 ], 0.0f, 10.0f, 0.01f );
|
|
pBank->AddSlider( "Front left level 2", &CVehicleDeformation::networkDamageModifiers[ 0 ][ 2 ], 0.0f, 10.0f, 0.01f );
|
|
pBank->AddSlider( "Front left level 3", &CVehicleDeformation::networkDamageModifiers[ 0 ][ 3 ], 0.0f, 10.0f, 0.01f );
|
|
|
|
pBank->AddSlider( "Front right level 0", &CVehicleDeformation::networkDamageModifiers[ 1 ][ 0 ], 0.0f, 10.0f, 0.01f );
|
|
pBank->AddSlider( "Front right level 1", &CVehicleDeformation::networkDamageModifiers[ 1 ][ 1 ], 0.0f, 10.0f, 0.01f );
|
|
pBank->AddSlider( "Front right level 2", &CVehicleDeformation::networkDamageModifiers[ 1 ][ 2 ], 0.0f, 10.0f, 0.01f );
|
|
pBank->AddSlider( "Front right level 3", &CVehicleDeformation::networkDamageModifiers[ 1 ][ 3 ], 0.0f, 10.0f, 0.01f );
|
|
|
|
pBank->AddSlider( "Middle left level 0", &CVehicleDeformation::networkDamageModifiers[ 2 ][ 0 ], 0.0f, 10.0f, 0.01f );
|
|
pBank->AddSlider( "Middle left level 1", &CVehicleDeformation::networkDamageModifiers[ 2 ][ 1 ], 0.0f, 10.0f, 0.01f );
|
|
pBank->AddSlider( "Middle left level 2", &CVehicleDeformation::networkDamageModifiers[ 2 ][ 2 ], 0.0f, 10.0f, 0.01f );
|
|
pBank->AddSlider( "Middle left level 3", &CVehicleDeformation::networkDamageModifiers[ 2 ][ 3 ], 0.0f, 10.0f, 0.01f );
|
|
|
|
pBank->AddSlider( "Middle right level 0", &CVehicleDeformation::networkDamageModifiers[ 3 ][ 0 ], 0.0f, 10.0f, 0.01f );
|
|
pBank->AddSlider( "Middle right level 1", &CVehicleDeformation::networkDamageModifiers[ 3 ][ 1 ], 0.0f, 10.0f, 0.01f );
|
|
pBank->AddSlider( "Middle right level 2", &CVehicleDeformation::networkDamageModifiers[ 3 ][ 2 ], 0.0f, 10.0f, 0.01f );
|
|
pBank->AddSlider( "Middle right level 3", &CVehicleDeformation::networkDamageModifiers[ 3 ][ 3 ], 0.0f, 10.0f, 0.01f );
|
|
|
|
pBank->AddSlider( "Rear left level 0", &CVehicleDeformation::networkDamageModifiers[ 4 ][ 0 ], 0.0f, 10.0f, 0.01f );
|
|
pBank->AddSlider( "Rear left level 1", &CVehicleDeformation::networkDamageModifiers[ 4 ][ 1 ], 0.0f, 10.0f, 0.01f );
|
|
pBank->AddSlider( "Rear left level 2", &CVehicleDeformation::networkDamageModifiers[ 4 ][ 2 ], 0.0f, 10.0f, 0.01f );
|
|
pBank->AddSlider( "Rear left level 3", &CVehicleDeformation::networkDamageModifiers[ 4 ][ 3 ], 0.0f, 10.0f, 0.01f );
|
|
|
|
pBank->AddSlider( "Rear right level 0", &CVehicleDeformation::networkDamageModifiers[ 5 ][ 0 ], 0.0f, 10.0f, 0.01f );
|
|
pBank->AddSlider( "Rear right level 1", &CVehicleDeformation::networkDamageModifiers[ 5 ][ 1 ], 0.0f, 10.0f, 0.01f );
|
|
pBank->AddSlider( "Rear right level 2", &CVehicleDeformation::networkDamageModifiers[ 5 ][ 2 ], 0.0f, 10.0f, 0.01f );
|
|
pBank->AddSlider( "Rear right level 3", &CVehicleDeformation::networkDamageModifiers[ 5 ][ 3 ], 0.0f, 10.0f, 0.01f );
|
|
|
|
pBank->PopGroup();
|
|
|
|
pBank->AddSlider( "Deformation Random Multiplier - Min", &CVehicleDeformation::ms_fVehDefColVarMultMin, 0.5f, 0.99f, 0.01f );
|
|
pBank->AddSlider( "Deformation Random Multiplier - Max", &CVehicleDeformation::ms_fVehDefColVarMultMax, 1.0f, 1.5f, 0.01f );
|
|
pBank->AddSlider( "Deformation Random Addition - Min", &CVehicleDeformation::ms_fVehDefColVarAddMin, -1.0f, 0.0f, 0.01f );
|
|
pBank->AddSlider( "Deformation Random Addition - Max", &CVehicleDeformation::ms_fVehDefColVarAddMax, 0.01f, 0.5f, 0.01f );
|
|
|
|
pBank->AddSlider( "Deformation Tuning - m_sfVehDefColMax1", &CVehicleDeformation::m_sfVehDefColMax1, 0.0f, 1.5f, 0.01f );
|
|
pBank->AddSlider( "Deformation Tuning - m_sfVehDefColMax2", &CVehicleDeformation::m_sfVehDefColMax2, 0.0f, 1.5f, 0.01f );
|
|
pBank->AddSlider( "Deformation Tuning - m_sfVehDefColMult2", &CVehicleDeformation::m_sfVehDefColMult2, 0.0f, 2.0f, 0.01f );
|
|
|
|
pBank->AddButton( "Set selected vehicle as source", CVehicleDamage::SetSourceVehicleCB );
|
|
pBank->PushGroup( "Texture Cache", true );
|
|
pBank->AddToggle( "Display Cache Stats", &CVehicleDeformation::ms_bDisplayTexCacheStats );
|
|
pBank->AddButton( "Force Cache clear", CVehicleDeformation::ClearTexCache );
|
|
pBank->PopGroup();
|
|
pBank->PopGroup();
|
|
|
|
pBank->AddToggle( "Never avoid vehicle explosion chain reactions", &CVehicleDamage::ms_bNeverAvoidVehicleExplosionChainReactions );
|
|
pBank->AddToggle( "Always avoid vehicle explosion chain reactions", &CVehicleDamage::ms_bAlwaysAvoidVehicleExplosionChainReactions );
|
|
pBank->AddToggle( "Use Vehicle Break Chance Multiplier Override", &CVehicleDamage::ms_bUseVehicleExplosionBreakChanceMultiplierOverride );
|
|
pBank->AddSlider( "Vehicle Break Chance Multiplier Override", &CVehicleDamage::ms_fVehicleExplosionBreakChanceMultiplierOverride, 0.0f, 1.0f, 0.05f );
|
|
CVehicleMetadataMgr::AddVehicleExplosionWidgets( *pBank );
|
|
|
|
pBank->PushGroup( "Damage Duplication" );
|
|
pBank->AddButton( "Set selected vehicle as source", CVehicleDamage::SetSourceVehicleCB );
|
|
pBank->AddButton( "Set selected vehicle as destination", CVehicleDamage::SetDestinationVehicleCB );
|
|
pBank->AddButton( "Duplicate damages from source to destination", CVehicleDamage::DuplicateDamageCB );
|
|
pBank->AddText( "Source", (int*)( &CVehicleDamage::ms_SourceVehicle ) );
|
|
pBank->AddText( "Destination", (int*)( &CVehicleDamage::ms_DestinationVehicle ) );
|
|
pBank->PopGroup();
|
|
|
|
pBank->PopGroup();
|
|
|
|
pBank->PushGroup( "Transmission Tuning", false );
|
|
CTransmission::AddWidgets( pBank );
|
|
pBank->PopGroup();
|
|
#if HACK_GTA4_BOUND_GEOM_SECOND_SURFACE
|
|
pBank->PushGroup( "Second Surface Tuning", false );
|
|
pBank->PushGroup( "standard" );
|
|
CVehicle::ms_vehicleSecondSurfaceConfig.AddWidgetsToBank( *pBank );
|
|
pBank->PopGroup();
|
|
pBank->PushGroup( "less sink" );
|
|
CVehicle::ms_vehicleSecondSurfaceConfigLessSink.AddWidgetsToBank( *pBank );
|
|
pBank->PopGroup();
|
|
pBank->PopGroup();
|
|
#endif // HACK_GTA4_BOUND_GEOM_SECOND_SURFACE
|
|
|
|
#if __BANK
|
|
SetupVehicleBank( *pBank );
|
|
#endif
|
|
|
|
#if CSE_VEHICLE_EDITABLEVALUES
|
|
CCustomShaderEffectVehicle::InitWidgets( *pBank );
|
|
#endif
|
|
|
|
pBank->PushGroup( "Animation" );
|
|
pBank->AddButton( "Play test on focus", PlayTestVehicleAnimCB );
|
|
pBank->AddToggle( "Play anim physically", &ms_bPlayAnimPhysical );
|
|
pBank->PopGroup();
|
|
|
|
pBank->PushGroup( "Tyre temperature" );
|
|
pBank->AddSlider( "Burst threshold", &CWheel::ms_fTyreTempBurstThreshold, 0.0f, 200.0f, 0.1f );
|
|
pBank->AddSlider( "Heat mult", &CWheel::ms_fTyreTempHeatMult, 0.0f, 10.0f, 0.01f );
|
|
pBank->AddSlider( "Cool mult", &CWheel::ms_fTyreTempCoolMult, 0.0f, 10.0f, 0.01f );
|
|
pBank->AddSlider( "Moving Cool mult", &CWheel::ms_fTyreTempCoolMovingMult, 0.0f, 10.0f, 0.01f );
|
|
pBank->PopGroup();
|
|
|
|
pBank->PushGroup( "Vehicle Burnout", false );
|
|
pBank->AddSlider( "Car burn out torque z", &CAutomobile::CAR_BURNOUT_ROT_Z, -10.0f, 0.0f, 0.1f );
|
|
pBank->AddSlider( "Car burn out angular speed limit", &CAutomobile::CAR_BURNOUT_ROTLIM, 0.0f, 10.0f, 0.1f );
|
|
pBank->AddSlider( "Quad bike burn out torque z", &CAutomobile::QUADBIKE_BURNOUT_ROT_Z, -10.0f, 0.0f, 0.1f );
|
|
pBank->AddSlider( "Quad bike burn out speed limit", &CAutomobile::QUADBIKE_BURNOUT_ROTLIM, 0.0f, 10.0f, 0.1f );
|
|
pBank->AddSlider( "Burn out wheel speed multiplier", &CAutomobile::BURNOUT_WHEEL_SPEED_MULT, 0.0f, 10.0f, 0.1f );
|
|
pBank->PopGroup();
|
|
|
|
pBank->PushGroup( "Franklin Vehicle Special", false );
|
|
pBank->AddSlider( "Steer Time Step Multiplier", &CTaskVehiclePlayerDriveAutomobile::sfSpecialAbilitySteeringTimeStepMult, 0.0f, 10.0f, 0.01f );
|
|
pBank->AddSlider( "Steer Speed Max", &CTaskVehiclePlayerDriveAutomobile::ms_fCAR_STEER_SMOOTH_RATE_STOPPED_SPECIAL, 0.0f, 50.0f, 0.1f );
|
|
pBank->AddSlider( "Steer Speed Min", &CTaskVehiclePlayerDriveAutomobile::ms_fCAR_STEER_SMOOTH_RATE_ATSPEED_SPECIAL, 0.0f, 50.0f, 0.1f );
|
|
pBank->PopGroup();
|
|
|
|
CVehicleModelInfo::AddWidgets( *pBank );
|
|
|
|
//update the car list if it's already been attempted to be updated once, as we don't want to call this before the level has loaded
|
|
if( bNeedToUpdateVehicleList )
|
|
CVehicleFactory::UpdateCarList();
|
|
|
|
|
|
pBank->PushGroup( "Vehicle Variations Debug", false );
|
|
u32 modelIndex = vehicleSorts ? GetModelIndex( vehicleSorts[ currVehicleNameSelection ] ) : fwModelId::MI_INVALID;
|
|
u32 maxColors = 1;
|
|
if( modelIndex != fwModelId::MI_INVALID )
|
|
{
|
|
CVehicleModelInfo* mi = (CVehicleModelInfo*)CModelInfo::GetBaseModelInfo( fwModelId( strLocalIndex( modelIndex ) ) );
|
|
if( mi )
|
|
{
|
|
VariationDebugUpdateColor();
|
|
maxColors = mi->GetNumPossibleColours();
|
|
}
|
|
}
|
|
|
|
|
|
ms_variationColorSlider = pBank->AddSlider( "Color", &ms_variationDebugColor, 0, Max( (int)1, (int)( maxColors - 1 ) ), 1, VariationDebugColorChangeCB );
|
|
ms_variationWindowTintSlider = pBank->AddSlider( "Window tint", &ms_variationDebugWindowTint, -1, CVehicleModelInfo::GetVehicleColours()->m_WindowColors.GetCount() - 1, 1, VariationDebugWindowTintChangeCB );
|
|
|
|
const char* modNames[] = // same order as CVehicleModelInfo::ms_aSetupDoorIds
|
|
{
|
|
"SPOILER",
|
|
"BUMPER_F",
|
|
"BUMPER_R",
|
|
"SKIRT",
|
|
"EXHAUST",
|
|
"CHASSIS",
|
|
"GRILL",
|
|
"BONNET",
|
|
"WING_L",
|
|
"WING_R",
|
|
"ROOF",
|
|
|
|
// Start new visual mods
|
|
"PLTHOLDER",
|
|
"PLTVANITY",
|
|
|
|
"INTERIOR1",
|
|
"INTERIOR2",
|
|
"INTERIOR3",
|
|
"INTERIOR4",
|
|
"INTERIOR5",
|
|
"SEATS",
|
|
"STEERING",
|
|
"KNOB",
|
|
"PLAQUE",
|
|
"ICE",
|
|
|
|
"TRUNK",
|
|
"HYDRO",
|
|
|
|
"ENGINEBAY1",
|
|
"ENGINEBAY2",
|
|
"ENGINEBAY3",
|
|
|
|
"CHASSIS2",
|
|
"CHASSIS3",
|
|
"CHASSIS4",
|
|
"CHASSIS5",
|
|
|
|
"DOOR_L",
|
|
"DOOR_R",
|
|
|
|
"LIVERY_MOD",
|
|
"LIGHTBAR",
|
|
// End new visual mods
|
|
|
|
// non visual mods (stats only)
|
|
"ENGINE",
|
|
"BRAKES",
|
|
"GEARBOX",
|
|
"HORN",
|
|
"SUSPENSION",
|
|
"ARMOUR",
|
|
|
|
"NITROUS",
|
|
"TURBO",
|
|
"SUBWOOFER",
|
|
"TYRE_SMOKE",
|
|
"HYDRAULICS",
|
|
"XENON_LIGHTS",
|
|
|
|
// other mods that require special care
|
|
"WHEELS",
|
|
"WHEELS_REAR_OR_HYDRAULICS",
|
|
};
|
|
|
|
for( int i = 0; i < VMT_MAX; i++ )
|
|
{
|
|
ms_variationSliders[ i ] = pBank->AddSlider( modNames[ i ], &ms_variationMod[ i ], -1, -1, 1, VariationDebugModChangeCB );
|
|
}
|
|
|
|
pBank->AddButton("Add mod kit to car", VariationDebugAddModKitCB);
|
|
pBank->AddToggle("Full randomization when adding mod kit to car", &ms_variationRandomMods);
|
|
pBank->AddToggle("Render mods", &ms_variationRenderMods);
|
|
|
|
pBank->AddButton("Set sprayed", SetSprayedCB);
|
|
pBank->AddButton("Clear sprayed", ClearSprayedCB);
|
|
|
|
pBank->PushGroup("Extras", false);
|
|
pBank->AddToggle("All extras", &ms_variationAllExtras, VariationDebugAllExtrasChangeCB);
|
|
char buf[32];
|
|
for (s32 i = 0; i <= VEH_LAST_EXTRA - VEH_EXTRA_1; ++i)
|
|
{
|
|
formatf(buf, "Extra %d", i + 1);
|
|
pBank->AddToggle(buf, &ms_variationExtras[i], VariationDebugExtrasChangeCB);
|
|
}
|
|
pBank->PopGroup();
|
|
pBank->AddToggle("Display car variation", &ms_variationDebugDraw);
|
|
pBank->PopGroup();
|
|
|
|
pBank->PushGroup("Liveries", false);
|
|
// these values will be updated when a car is created to track
|
|
ms_liverySlider = pBank->AddSlider("Current livery", &ms_currentLivery, -1, -1, 1, CarLiveryChangeCB);
|
|
ms_livery2Slider = pBank->AddSlider("Current livery2", &ms_currentLivery2, -1, -1, 1, CarLivery2ChangeCB);
|
|
pBank->PopGroup();
|
|
|
|
pBank->PushGroup("LOD debug tools", false);
|
|
// these values will be updated when a car is created to track
|
|
pBank->AddToggle("Show Vehicle LOD level", &ms_bShowVehicleLODLevel);
|
|
pBank->AddToggle("Show Vehicle LOD data", &ms_bShowVehicleLODLevelData);
|
|
pBank->AddButton("Validate all vehicles", ValidateAllVehiclesCB);
|
|
pBank->AddSlider("Vehicle LOD scaling", &ms_vehicleLODScaling, 0.1f, 2.0f, 0.1f);
|
|
pBank->AddSlider("Vehicle Hi Stream scaling", &ms_vehicleHiStreamScaling, 0.1f, 2.0f, 0.1f);
|
|
pBank->PopGroup();
|
|
|
|
pBank->PushGroup("Vehicle Rendering", false);
|
|
pBank->AddToggle("Render initial spawn point", &CVehicleDebug::ms_bRenderInitialSpawnPoint);
|
|
pBank->PopGroup();
|
|
|
|
//pBank->PushGroup( "Bobblehead", false );
|
|
// pBank->AddSlider("Stiffness X", &CBobbleHead::ms_bobbleHeadStiffness[ 0 ], 0.0f, 5000.0f, 10.0f);
|
|
// pBank->AddSlider("Stiffness Y", &CBobbleHead::ms_bobbleHeadStiffness[ 1 ], 0.0f, 5000.0f, 10.0f);
|
|
// pBank->AddSlider("Damping X", &CBobbleHead::ms_bobbleHeadDamping[ 0 ], 0.0f, 5.0f, 0.01f);
|
|
// pBank->AddSlider("Damping Y", &CBobbleHead::ms_bobbleHeadDamping[ 1 ], 0.0f, 5.0f, 0.01f);
|
|
// pBank->AddSlider("Limit X", &CBobbleHead::ms_bobbleHeadLimits[ 0 ], 0.0f, 1.5f, 0.01f);
|
|
// pBank->AddSlider("Limit Y", &CBobbleHead::ms_bobbleHeadLimits[ 1 ], 0.0f, 1.5f, 0.01f);
|
|
// pBank->AddSlider("Mass", &CBobbleHead::ms_bobbleHeadMass, 0.1f, 100.0f, 0.1f );
|
|
//pBank->PopGroup();
|
|
|
|
CVehicleDamage::SetupVehicleDoorDamageBank(*pBank);
|
|
CHeli::InitTurbulenceWidgets(*pBank);
|
|
}
|
|
|
|
void CVehicleFactory::UpdateCarList(void)
|
|
{
|
|
//if there is no combo box don't update the vehicle list
|
|
if(pVehicleCombo == NULL)
|
|
{
|
|
bNeedToUpdateVehicleList = true;
|
|
UpdateVehicleList();
|
|
}
|
|
else
|
|
{
|
|
bNeedToUpdateVehicleList = false;
|
|
UpdateAvailableCarsCB();
|
|
UpdateVehicleList();
|
|
CarNumChangeCB();
|
|
TrailerNumChangeCB();
|
|
}
|
|
}
|
|
|
|
|
|
// this function allows access to the create car callback for a debug key checked in debug.cpp
|
|
void CVehicleFactory::CreateCar(u32 modelId)
|
|
{
|
|
if(modelId != fwModelId::MI_INVALID )
|
|
{
|
|
carModelId = modelId;
|
|
}
|
|
CreateCarCB();
|
|
}
|
|
void CVehicleFactory::WarpPlayerOutOfCar()
|
|
{
|
|
WarpPlayerOutOfCarCB();
|
|
}
|
|
void CVehicleFactory::WarpPlayerIntoRecentCar()
|
|
{
|
|
WarpPlayerIntoRecentCarCB();
|
|
}
|
|
|
|
void CVehicleFactory::PlayTestVehicleAnimCB()
|
|
{
|
|
static strRequest animRequester;
|
|
|
|
CVehicle* pVehicle = CVehicleDebug::GetFocusVehicle();
|
|
|
|
if(!pVehicle)
|
|
{
|
|
return;
|
|
}
|
|
|
|
animRequester.Release();
|
|
|
|
|
|
static bool testDump = true;
|
|
|
|
const char* pDictName;
|
|
const char* pAnimName;
|
|
|
|
if(testDump)
|
|
{
|
|
// Find the clip
|
|
pDictName = "va_dump";
|
|
pAnimName = "dump_tipper";
|
|
}
|
|
else
|
|
{
|
|
pDictName = "va_feltzer2010";
|
|
pAnimName = "feltzer2010_roof";
|
|
}
|
|
|
|
|
|
// Stream the anim
|
|
strLocalIndex iSlot = fwAnimManager::FindSlot(pDictName);
|
|
|
|
if(iSlot != -1)
|
|
{
|
|
if(!animRequester.Request(iSlot,fwAnimManager::GetStreamingModuleId(),STRFLAG_PRIORITY_LOAD))
|
|
{
|
|
// Force load
|
|
CStreaming::LoadAllRequestedObjects(true);
|
|
}
|
|
|
|
Assert(animRequester.HasLoaded());
|
|
|
|
if(animRequester.HasLoaded())
|
|
{
|
|
// Play the anim on the focus vehicle
|
|
pVehicle->InitAnimLazy();
|
|
fragInstGta* pFragInst = pVehicle->GetVehicleFragInst();
|
|
Assert(pFragInst);
|
|
|
|
pFragInst->GetCacheEntry()->LazyArticulatedInit();
|
|
pVehicle->SetDriveMusclesToAnimation(ms_bPlayAnimPhysical);
|
|
|
|
pVehicle->GetMoveVehicle().GetClipHelper().BlendInClipByClip(pVehicle, fwAnimManager::GetClipIfExistsByName(pDictName, pAnimName), FAST_BLEND_IN_DELTA);
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
void CVehicleFactory::VariationDebugUpdateColor()
|
|
{
|
|
if (ms_pLastCreatedVehicle)
|
|
{
|
|
CVehicleModelInfo* mi = ms_pLastCreatedVehicle->GetVehicleModelInfo();
|
|
if (mi)
|
|
{
|
|
// find out which color combination the vehicle has
|
|
u8 col1 = ms_pLastCreatedVehicle->GetBodyColour1();
|
|
u8 col2 = ms_pLastCreatedVehicle->GetBodyColour2();
|
|
u8 col3 = ms_pLastCreatedVehicle->GetBodyColour3();
|
|
u8 col4 = ms_pLastCreatedVehicle->GetBodyColour4();
|
|
u8 col5 = ms_pLastCreatedVehicle->GetBodyColour5();
|
|
u8 col6 = ms_pLastCreatedVehicle->GetBodyColour6();
|
|
|
|
ms_variationDebugColor = 0;
|
|
for (s32 i = 0; i < mi->GetNumPossibleColours(); ++i)
|
|
{
|
|
if (mi->GetPossibleColours(0, i) == col1 &&
|
|
mi->GetPossibleColours(1, i) == col2 &&
|
|
mi->GetPossibleColours(2, i) == col3 &&
|
|
mi->GetPossibleColours(3, i) == col4 &&
|
|
mi->GetPossibleColours(4, i) == col5 &&
|
|
mi->GetPossibleColours(5, i) == col6 )
|
|
{
|
|
ms_variationDebugColor = i;
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
ms_variationDebugWindowTint = ms_pLastCreatedVehicle->GetVariationInstance().GetWindowTint();
|
|
}
|
|
}
|
|
|
|
inline int CVehicleFactory::VariationDebugGetLastVehMod(eVehicleModType slot) {
|
|
// Work around GetModIndexForType returning -1 as a u8 - i.e. 255
|
|
static bool dummy = false;
|
|
int idxMod = ms_pLastCreatedVehicle->GetVariationInstance().GetModIndexForType(slot, ms_pLastCreatedVehicle, dummy);
|
|
|
|
return idxMod == 255 ? -1 : idxMod;
|
|
}
|
|
|
|
void CVehicleFactory::VariationDebugUpdateMods()
|
|
{
|
|
if (!ms_pLastCreatedVehicle || !ms_pLastCreatedVehicle->IsModded())
|
|
return;
|
|
|
|
for( int i = 0; i < VMT_MAX; i++ )
|
|
{
|
|
if( ms_variationMod[ i ] )
|
|
{
|
|
ms_variationMod[ i ] = VariationDebugGetLastVehMod( (eVehicleModType)i );
|
|
}
|
|
}
|
|
|
|
//if (ms_variationSpoilerMod)
|
|
// ms_variationSpoilerMod = VariationDebugGetLastVehMod(VMT_SPOILER);
|
|
//if (ms_variationBumperFMod)
|
|
// ms_variationBumperFMod = VariationDebugGetLastVehMod(VMT_BUMPER_F);
|
|
//if (ms_variationBumperRMod)
|
|
// ms_variationBumperRMod = VariationDebugGetLastVehMod(VMT_BUMPER_R);
|
|
//if (ms_variationSkirtMod)
|
|
// ms_variationSkirtMod = VariationDebugGetLastVehMod(VMT_SKIRT);
|
|
//if (ms_variationExhaustMod)
|
|
// ms_variationExhaustMod = VariationDebugGetLastVehMod(VMT_EXHAUST);
|
|
//if (ms_variationChassisMod)
|
|
// ms_variationChassisMod = VariationDebugGetLastVehMod(VMT_CHASSIS);
|
|
//if (ms_variationGrillMod)
|
|
// ms_variationGrillMod = VariationDebugGetLastVehMod(VMT_GRILL);
|
|
//if (ms_variationBonnetMod)
|
|
// ms_variationBonnetMod = VariationDebugGetLastVehMod(VMT_BONNET);
|
|
//if (ms_variationWingLMod)
|
|
// ms_variationWingLMod = VariationDebugGetLastVehMod(VMT_WING_L);
|
|
//if (ms_variationWingRMod)
|
|
// ms_variationWingRMod = VariationDebugGetLastVehMod(VMT_WING_R);
|
|
//if (ms_variationRoofMod)
|
|
// ms_variationRoofMod = VariationDebugGetLastVehMod(VMT_ROOF);
|
|
//if (ms_variationEngineMod)
|
|
// ms_variationEngineMod = VariationDebugGetLastVehMod(VMT_ENGINE);
|
|
//if (ms_variationBrakesMod)
|
|
// ms_variationBrakesMod = VariationDebugGetLastVehMod(VMT_BRAKES);
|
|
//if (ms_variationGearboxMod)
|
|
// ms_variationGearboxMod = VariationDebugGetLastVehMod(VMT_GEARBOX);
|
|
//if (ms_variationHornMod)
|
|
// ms_variationHornMod = VariationDebugGetLastVehMod(VMT_HORN);
|
|
//if (ms_variationSuspensionMod)
|
|
// ms_variationSuspensionMod = VariationDebugGetLastVehMod(VMT_SUSPENSION);
|
|
//if (ms_variationArmourMod)
|
|
// ms_variationArmourMod = VariationDebugGetLastVehMod(VMT_ARMOUR);
|
|
//if (ms_variationWheelMod)
|
|
// ms_variationWheelMod = VariationDebugGetLastVehMod(VMT_WHEELS);
|
|
//if (ms_variationRearWheelMod)
|
|
// ms_variationRearWheelMod = VariationDebugGetLastVehMod(VMT_WHEELS_REAR_OR_HYDRAULICS);
|
|
//if (ms_variationLiveryMod)
|
|
// ms_variationLiveryMod = VariationDebugGetLastVehMod(VMT_LIVERY_MOD);
|
|
|
|
|
|
for( int i = 0; i < VMT_MAX; i++ )
|
|
{
|
|
if( ms_variationSliders[ i ] )
|
|
{
|
|
ms_variationSliders[ i ]->SetRange( -1.f, (float)ms_pLastCreatedVehicle->GetVariationInstance().GetNumModsForType( (eVehicleModType)i, ms_pLastCreatedVehicle ) - 1.f );
|
|
}
|
|
}
|
|
|
|
//if (ms_variationSpoilerSlider)
|
|
// ms_variationSpoilerSlider->SetRange(-1.f, (float)ms_pLastCreatedVehicle->GetVariationInstance().GetNumModsForType(VMT_SPOILER, ms_pLastCreatedVehicle) - 1.f);
|
|
//if (ms_variationBumperFSlider)
|
|
// ms_variationBumperFSlider->SetRange(-1.f, (float)ms_pLastCreatedVehicle->GetVariationInstance().GetNumModsForType(VMT_BUMPER_F, ms_pLastCreatedVehicle) - 1.f);
|
|
//if (ms_variationBumperRSlider)
|
|
// ms_variationBumperRSlider->SetRange(-1.f, (float)ms_pLastCreatedVehicle->GetVariationInstance().GetNumModsForType(VMT_BUMPER_R, ms_pLastCreatedVehicle) - 1.f);
|
|
//if (ms_variationSkirtSlider)
|
|
// ms_variationSkirtSlider->SetRange(-1.f, (float)ms_pLastCreatedVehicle->GetVariationInstance().GetNumModsForType(VMT_SKIRT, ms_pLastCreatedVehicle) - 1.f);
|
|
//if (ms_variationExhaustSlider)
|
|
// ms_variationExhaustSlider->SetRange(-1.f, (float)ms_pLastCreatedVehicle->GetVariationInstance().GetNumModsForType(VMT_EXHAUST, ms_pLastCreatedVehicle) - 1.f);
|
|
//if (ms_variationChassisSlider)
|
|
// ms_variationChassisSlider->SetRange(-1.f, (float)ms_pLastCreatedVehicle->GetVariationInstance().GetNumModsForType(VMT_CHASSIS, ms_pLastCreatedVehicle) - 1.f);
|
|
//if (ms_variationGrillSlider)
|
|
// ms_variationGrillSlider->SetRange(-1.f, (float)ms_pLastCreatedVehicle->GetVariationInstance().GetNumModsForType(VMT_GRILL, ms_pLastCreatedVehicle) - 1.f);
|
|
//if (ms_variationBonnetSlider)
|
|
// ms_variationBonnetSlider->SetRange(-1.f, (float)ms_pLastCreatedVehicle->GetVariationInstance().GetNumModsForType(VMT_BONNET, ms_pLastCreatedVehicle) - 1.f);
|
|
//if (ms_variationWingLSlider)
|
|
// ms_variationWingLSlider->SetRange(-1.f, (float)ms_pLastCreatedVehicle->GetVariationInstance().GetNumModsForType(VMT_WING_L, ms_pLastCreatedVehicle) - 1.f);
|
|
//if (ms_variationWingRSlider)
|
|
// ms_variationWingRSlider->SetRange(-1.f, (float)ms_pLastCreatedVehicle->GetVariationInstance().GetNumModsForType(VMT_WING_R, ms_pLastCreatedVehicle) - 1.f);
|
|
//if (ms_variationRoofSlider)
|
|
// ms_variationRoofSlider->SetRange(-1.f, (float)ms_pLastCreatedVehicle->GetVariationInstance().GetNumModsForType(VMT_ROOF, ms_pLastCreatedVehicle) - 1.f);
|
|
//if (ms_variationEngineSlider)
|
|
// ms_variationEngineSlider->SetRange(-1.f, (float)ms_pLastCreatedVehicle->GetVariationInstance().GetNumModsForType(VMT_ENGINE, ms_pLastCreatedVehicle) - 1.f);
|
|
//if (ms_variationBrakesSlider)
|
|
// ms_variationBrakesSlider->SetRange(-1.f, (float)ms_pLastCreatedVehicle->GetVariationInstance().GetNumModsForType(VMT_BRAKES, ms_pLastCreatedVehicle) - 1.f);
|
|
//if (ms_variationGearboxSlider)
|
|
// ms_variationGearboxSlider->SetRange(-1.f, (float)ms_pLastCreatedVehicle->GetVariationInstance().GetNumModsForType(VMT_GEARBOX, ms_pLastCreatedVehicle) - 1.f);
|
|
//if (ms_variationHornSlider)
|
|
// ms_variationHornSlider->SetRange(-1.f, (float)ms_pLastCreatedVehicle->GetVariationInstance().GetNumModsForType(VMT_HORN, ms_pLastCreatedVehicle) - 1.f);
|
|
//if (ms_variationSuspensionSlider)
|
|
// ms_variationSuspensionSlider->SetRange(-1.f, (float)ms_pLastCreatedVehicle->GetVariationInstance().GetNumModsForType(VMT_SUSPENSION, ms_pLastCreatedVehicle) - 1.f);
|
|
//if (ms_variationArmourSlider)
|
|
// ms_variationArmourSlider->SetRange(-1.f, (float)ms_pLastCreatedVehicle->GetVariationInstance().GetNumModsForType(VMT_ARMOUR, ms_pLastCreatedVehicle) - 1.f);
|
|
//if (ms_variationWheelSlider)
|
|
// ms_variationWheelSlider->SetRange(-1.f, (float)ms_pLastCreatedVehicle->GetVariationInstance().GetNumModsForType(VMT_WHEELS, ms_pLastCreatedVehicle) - 1.f);
|
|
//if (ms_variationRearWheelSlider)
|
|
// ms_variationRearWheelSlider->SetRange(-1.f, (float)ms_pLastCreatedVehicle->GetVariationInstance().GetNumModsForType(VMT_WHEELS_REAR_OR_HYDRAULICS, ms_pLastCreatedVehicle) - 1.f);
|
|
//if (ms_variationLiveryModSlider)
|
|
// ms_variationLiveryModSlider->SetRange(-1.f, (float)ms_pLastCreatedVehicle->GetVariationInstance().GetNumModsForType(VMT_LIVERY_MOD, ms_pLastCreatedVehicle) - 1.f);
|
|
}
|
|
|
|
void CVehicleFactory::VariationDebugColorChangeCB()
|
|
{
|
|
//if (ms_pLastCreatedVehicle)
|
|
//{
|
|
// CVehicleModelInfo* mi = ms_pLastCreatedVehicle->GetVehicleModelInfo();
|
|
// if (mi)
|
|
// {
|
|
// //ms_pLastCreatedVehicle->SetBodyColour1(mi->GetPossibleColours(0, ms_variationDebugColor));
|
|
// //ms_pLastCreatedVehicle->SetBodyColour2(mi->GetPossibleColours(1, ms_variationDebugColor));
|
|
// //ms_pLastCreatedVehicle->SetBodyColour3(mi->GetPossibleColours(2, ms_variationDebugColor));
|
|
// //ms_pLastCreatedVehicle->SetBodyColour4(mi->GetPossibleColours(3, ms_variationDebugColor));
|
|
// //ms_pLastCreatedVehicle->SetBodyColour5(mi->GetPossibleColours(4, ms_variationDebugColor));
|
|
// //ms_pLastCreatedVehicle->SetBodyColour6(mi->GetPossibleColours(5, ms_variationDebugColor));
|
|
|
|
// // let shaders know, that body colours changed
|
|
// //CVehicleFactory::ms_pLastCreatedVehicle->UpdateBodyColourRemapping();
|
|
// }
|
|
//}
|
|
}
|
|
|
|
void CVehicleFactory::VariationDebugWindowTintChangeCB()
|
|
{
|
|
if (ms_pLastCreatedVehicle)
|
|
{
|
|
ms_pLastCreatedVehicle->GetVariationInstance().SetWindowTint((u8)ms_variationDebugWindowTint);
|
|
}
|
|
}
|
|
|
|
void CVehicleFactory::VariationDebugModChangeCB()
|
|
{
|
|
if (ms_pLastCreatedVehicle)
|
|
{
|
|
for( int i = 0; i < VMT_MAX; i++ )
|
|
{
|
|
ms_pLastCreatedVehicle->GetVariationInstance().SetModIndexForType( (eVehicleModType)i, (u8)ms_variationMod[ i ], ms_pLastCreatedVehicle, false );
|
|
}
|
|
//ms_pLastCreatedVehicle->GetVariationInstance().SetModIndexForType(VMT_SPOILER, (u8)ms_variationSpoilerMod, ms_pLastCreatedVehicle, false);
|
|
//ms_pLastCreatedVehicle->GetVariationInstance().SetModIndexForType(VMT_BUMPER_F, (u8)ms_variationBumperFMod, ms_pLastCreatedVehicle, false);
|
|
//ms_pLastCreatedVehicle->GetVariationInstance().SetModIndexForType(VMT_BUMPER_R, (u8)ms_variationBumperRMod, ms_pLastCreatedVehicle, false);
|
|
//ms_pLastCreatedVehicle->GetVariationInstance().SetModIndexForType(VMT_SKIRT, (u8)ms_variationSkirtMod, ms_pLastCreatedVehicle, false);
|
|
//ms_pLastCreatedVehicle->GetVariationInstance().SetModIndexForType(VMT_EXHAUST, (u8)ms_variationExhaustMod, ms_pLastCreatedVehicle, false);
|
|
//ms_pLastCreatedVehicle->GetVariationInstance().SetModIndexForType(VMT_CHASSIS, (u8)ms_variationChassisMod, ms_pLastCreatedVehicle, false);
|
|
//ms_pLastCreatedVehicle->GetVariationInstance().SetModIndexForType(VMT_GRILL, (u8)ms_variationGrillMod, ms_pLastCreatedVehicle, false);
|
|
//ms_pLastCreatedVehicle->GetVariationInstance().SetModIndexForType(VMT_BONNET, (u8)ms_variationBonnetMod, ms_pLastCreatedVehicle, false);
|
|
//ms_pLastCreatedVehicle->GetVariationInstance().SetModIndexForType(VMT_WING_L, (u8)ms_variationWingLMod, ms_pLastCreatedVehicle, false);
|
|
//ms_pLastCreatedVehicle->GetVariationInstance().SetModIndexForType(VMT_WING_R, (u8)ms_variationWingRMod, ms_pLastCreatedVehicle, false);
|
|
//ms_pLastCreatedVehicle->GetVariationInstance().SetModIndexForType(VMT_ROOF, (u8)ms_variationRoofMod, ms_pLastCreatedVehicle, false);
|
|
//ms_pLastCreatedVehicle->GetVariationInstance().SetModIndexForType(VMT_ENGINE, (u8)ms_variationEngineMod, ms_pLastCreatedVehicle, false);
|
|
//ms_pLastCreatedVehicle->GetVariationInstance().SetModIndexForType(VMT_BRAKES, (u8)ms_variationBrakesMod, ms_pLastCreatedVehicle, false);
|
|
//ms_pLastCreatedVehicle->GetVariationInstance().SetModIndexForType(VMT_GEARBOX, (u8)ms_variationGearboxMod, ms_pLastCreatedVehicle, false);
|
|
//ms_pLastCreatedVehicle->GetVariationInstance().SetModIndexForType(VMT_HORN, (u8)ms_variationHornMod, ms_pLastCreatedVehicle, false);
|
|
//ms_pLastCreatedVehicle->GetVariationInstance().SetModIndexForType(VMT_SUSPENSION, (u8)ms_variationSuspensionMod, ms_pLastCreatedVehicle, false);
|
|
//ms_pLastCreatedVehicle->GetVariationInstance().SetModIndexForType(VMT_ARMOUR, (u8)ms_variationArmourMod, ms_pLastCreatedVehicle, false);
|
|
//ms_pLastCreatedVehicle->GetVariationInstance().SetModIndexForType(VMT_WHEELS, (u8)ms_variationWheelMod, ms_pLastCreatedVehicle, false);
|
|
//ms_pLastCreatedVehicle->GetVariationInstance().SetModIndexForType(VMT_WHEELS_REAR_OR_HYDRAULICS, (u8)ms_variationRearWheelMod, ms_pLastCreatedVehicle, false);
|
|
//ms_pLastCreatedVehicle->GetVariationInstance().SetModIndexForType(VMT_LIVERY_MOD, (u8)ms_variationLiveryMod, ms_pLastCreatedVehicle, false);
|
|
}
|
|
}
|
|
|
|
void CVehicleFactory::VariationDebugAddModKitCB()
|
|
{
|
|
if (ms_pLastCreatedVehicle)
|
|
{
|
|
ms_pLastCreatedVehicle->GetVehicleModelInfo()->GenerateVariation(ms_pLastCreatedVehicle, ms_pLastCreatedVehicle->GetVariationInstance(), ms_variationRandomMods);
|
|
VariationDebugUpdateMods();
|
|
}
|
|
else
|
|
{
|
|
if (CPed* localPlayer = CPedFactory::GetFactory()->GetLocalPlayer())
|
|
{
|
|
if (CVehicle* vehicle = localPlayer->GetMyVehicle())
|
|
{
|
|
ms_pLastCreatedVehicle = vehicle;
|
|
|
|
ms_pLastCreatedVehicle->GetVehicleModelInfo()->GenerateVariation(ms_pLastCreatedVehicle, ms_pLastCreatedVehicle->GetVariationInstance(), ms_variationRandomMods);
|
|
VariationDebugUpdateMods();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void CVehicleFactory::SetSprayedCB()
|
|
{
|
|
CVehicle* pVeh = CGameWorld::FindLocalPlayerVehicle();
|
|
if (!pVeh)
|
|
return;
|
|
|
|
fwExtensibleBase* pBase = (fwExtensibleBase*)pVeh;
|
|
|
|
|
|
atHashWithStringBank hash("Sprayed_Vehicle_Decorator");
|
|
bool val = true;
|
|
fwDecoratorExtension::Set((*pBase), hash, val);
|
|
}
|
|
|
|
void CVehicleFactory::ClearSprayedCB()
|
|
{
|
|
CVehicle* pVeh = CGameWorld::FindLocalPlayerVehicle();
|
|
if (!pVeh)
|
|
return;
|
|
|
|
fwExtensibleBase* pBase = (fwExtensibleBase*)pVeh;
|
|
|
|
atHashWithStringBank hash("Sprayed_Vehicle_Decorator");
|
|
fwDecoratorExtension::RemoveFrom((*pBase),hash);
|
|
}
|
|
|
|
void CVehicleFactory::VariationDebugExtrasChangeCB()
|
|
{
|
|
if (!CVehicleFactory::ms_pLastCreatedVehicle)
|
|
return;
|
|
|
|
for (s32 i = 0; i < VEH_LAST_EXTRA - VEH_EXTRA_1 + 1; ++i)
|
|
{
|
|
// since callback is called on each change, there's only one entry that can vary so we can break when we find the first one
|
|
// turning an extra on might cause other ones in an inclusion group to turn on so we have to break or else we might
|
|
// override and lose the correct state
|
|
if (CVehicleFactory::ms_pLastCreatedVehicle->GetIsExtraOn((eHierarchyId)(VEH_EXTRA_1 + i)) != ms_variationExtras[i])
|
|
{
|
|
CVehicleFactory::ms_pLastCreatedVehicle->TurnOffExtra((eHierarchyId)(VEH_EXTRA_1 + i), !ms_variationExtras[i]);
|
|
break;
|
|
}
|
|
}
|
|
|
|
// update the check boxes since inclusion groups could have changed the state of some extras
|
|
for (s32 f = 0; f <= VEH_LAST_EXTRA - VEH_EXTRA_1; ++f)
|
|
{
|
|
CVehicleFactory::ms_variationExtras[f] = CVehicleFactory::ms_pLastCreatedVehicle->GetIsExtraOn((eHierarchyId)(VEH_EXTRA_1 + f));
|
|
}
|
|
}
|
|
|
|
void CVehicleFactory::VariationDebugAllExtrasChangeCB()
|
|
{
|
|
for (s32 i = 0; i < VEH_LAST_EXTRA - VEH_EXTRA_1 + 1; ++i)
|
|
{
|
|
ms_variationExtras[i] = ms_variationAllExtras;
|
|
}
|
|
|
|
if (!CVehicleFactory::ms_pLastCreatedVehicle)
|
|
return;
|
|
|
|
for (s32 i = 0; i < VEH_LAST_EXTRA - VEH_EXTRA_1 + 1; ++i)
|
|
{
|
|
CVehicleFactory::ms_pLastCreatedVehicle->TurnOffExtra((eHierarchyId)(VEH_EXTRA_1 + i), !ms_variationExtras[i]);
|
|
}
|
|
}
|
|
|
|
void CVehicleFactory::UpdateWindowTintSlider()
|
|
{
|
|
if (ms_variationWindowTintSlider)
|
|
ms_variationWindowTintSlider = pBank->AddSlider("Window tint", &ms_variationDebugWindowTint, -1, CVehicleModelInfo::GetVehicleColours()->m_WindowColors.GetCount() - 1, 1, VariationDebugWindowTintChangeCB);
|
|
}
|
|
|
|
void CVehicleFactory::CarLiveryChangeCB(void)
|
|
{
|
|
if (ms_pLastCreatedVehicle)
|
|
{
|
|
ms_pLastCreatedVehicle->SetLiveryId(ms_currentLivery);
|
|
ms_pLastCreatedVehicle->UpdateBodyColourRemapping();
|
|
}
|
|
};
|
|
|
|
void CVehicleFactory::CarLivery2ChangeCB(void)
|
|
{
|
|
if (ms_pLastCreatedVehicle)
|
|
{
|
|
ms_pLastCreatedVehicle->SetLivery2Id(ms_currentLivery2);
|
|
ms_pLastCreatedVehicle->UpdateBodyColourRemapping();
|
|
}
|
|
};
|
|
|
|
#undef VISUALISE_RANGE
|
|
#define VISUALISE_RANGE (30.f * 30.f)
|
|
void CVehicleFactory::DebugUpdate()
|
|
{
|
|
if ( pCreateBankButton && (PARAM_debugvehicle.Get() || PARAM_debugtrain.Get()) )
|
|
{
|
|
CreateBank();
|
|
}
|
|
|
|
if (!ms_variationDebugDraw)
|
|
return;
|
|
|
|
CVehicle::Pool* pool = CVehicle::GetPool();
|
|
s32 i = (s32) pool->GetSize();
|
|
char buf[64];
|
|
while(i--)
|
|
{
|
|
CVehicle* pVehicle = pool->GetSlot(i);
|
|
if (!pVehicle)
|
|
continue;
|
|
|
|
CVehicleModelInfo* mi = pVehicle->GetVehicleModelInfo();
|
|
if (!mi)
|
|
continue;
|
|
|
|
Vector3 pos = VEC3V_TO_VECTOR3(pVehicle->GetTransform().GetPosition());
|
|
Vector3 vDiff = pos - camInterface::GetPos();
|
|
float fDist = vDiff.Mag2();
|
|
|
|
if(fDist >= VISUALISE_RANGE)
|
|
continue;
|
|
|
|
float fScale = 1.0f - (fDist / VISUALISE_RANGE);
|
|
Vector3 WorldCoors = pos + Vector3(0,0,1.1f);
|
|
u8 iAlpha = (u8)Clamp((int)(255.0f * fScale), 0, 255);
|
|
|
|
// find out which color combination the vehicle has
|
|
u8 col1 = pVehicle->GetBodyColour1();
|
|
u8 col2 = pVehicle->GetBodyColour2();
|
|
u8 col3 = pVehicle->GetBodyColour3();
|
|
u8 col4 = pVehicle->GetBodyColour4();
|
|
u8 col5 = pVehicle->GetBodyColour5();
|
|
u8 col6 = pVehicle->GetBodyColour6();
|
|
|
|
s32 colIdx = 0;
|
|
for (s32 i = 0; i < mi->GetNumPossibleColours(); ++i)
|
|
{
|
|
if (mi->GetPossibleColours(0, i) == col1 &&
|
|
mi->GetPossibleColours(1, i) == col2 &&
|
|
mi->GetPossibleColours(2, i) == col3 &&
|
|
mi->GetPossibleColours(3, i) == col4 &&
|
|
mi->GetPossibleColours(4, i) == col5 &&
|
|
mi->GetPossibleColours(5, i) == col6 )
|
|
{
|
|
colIdx = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
s32 iNumLines = 0;
|
|
const CVehicleVariationInstance& variation = pVehicle->GetVariationInstance();
|
|
|
|
formatf(buf, "Local color idx: %d", colIdx);
|
|
grcDebugDraw::Text(WorldCoors, CRGBA(255, 0, 0, iAlpha), 0, (iNumLines++) * grcDebugDraw::GetScreenSpaceTextHeight(), buf);
|
|
formatf(buf, "Body color 1: (%s)", CVehicleModelInfo::GetVehicleColours()->GetVehicleColourText(col1));
|
|
grcDebugDraw::Text(WorldCoors, CRGBA(255, 0, 0, iAlpha), 0, (iNumLines++) * grcDebugDraw::GetScreenSpaceTextHeight(), buf);
|
|
formatf(buf, "Body color 2: (%s)", CVehicleModelInfo::GetVehicleColours()->GetVehicleColourText(col2));
|
|
grcDebugDraw::Text(WorldCoors, CRGBA(255, 0, 0, iAlpha), 0, (iNumLines++) * grcDebugDraw::GetScreenSpaceTextHeight(), buf);
|
|
formatf(buf, "Body color 3: (%s)", CVehicleModelInfo::GetVehicleColours()->GetVehicleColourText(col3));
|
|
grcDebugDraw::Text(WorldCoors, CRGBA(255, 0, 0, iAlpha), 0, (iNumLines++) * grcDebugDraw::GetScreenSpaceTextHeight(), buf);
|
|
formatf(buf, "Body color 4: (%s)", CVehicleModelInfo::GetVehicleColours()->GetVehicleColourText(col4));
|
|
grcDebugDraw::Text(WorldCoors, CRGBA(255, 0, 0, iAlpha), 0, (iNumLines++) * grcDebugDraw::GetScreenSpaceTextHeight(), buf);
|
|
formatf(buf, "Body color 5: (%s)", CVehicleModelInfo::GetVehicleColours()->GetVehicleColourText(col5));
|
|
grcDebugDraw::Text(WorldCoors, CRGBA(255, 0, 0, iAlpha), 0, (iNumLines++) * grcDebugDraw::GetScreenSpaceTextHeight(), buf);
|
|
formatf(buf, "Body color 6: (%s)", CVehicleModelInfo::GetVehicleColours()->GetVehicleColourText(col6));
|
|
grcDebugDraw::Text(WorldCoors, CRGBA(255, 0, 0, iAlpha), 0, (iNumLines++) * grcDebugDraw::GetScreenSpaceTextHeight(), buf);
|
|
formatf(buf, "Window tint: (%s)", CVehicleModelInfo::GetVehicleColours()->GetVehicleColourText(variation.GetWindowTint()));
|
|
grcDebugDraw::Text(WorldCoors, CRGBA(255, 0, 0, iAlpha), 0, (iNumLines++) * grcDebugDraw::GetScreenSpaceTextHeight(), buf);
|
|
|
|
for (s32 l = 0; l < MAX_NUM_LIVERIES; ++l)
|
|
{
|
|
formatf(buf, "Livery %d colors: ", l);
|
|
for (s32 c = 0; c < MAX_NUM_LIVERY_COLORS; ++c)
|
|
{
|
|
u8 livCol = mi->GetLiveryColorIndex(l, c);
|
|
if (livCol != 255)
|
|
{
|
|
char buf2[16] = {0};
|
|
formatf(buf2, "%d ", livCol);
|
|
safecat(buf, buf2, sizeof(buf));
|
|
}
|
|
}
|
|
|
|
grcDebugDraw::Text(WorldCoors, CRGBA(255, 0, 0, iAlpha), 0, (iNumLines++) * grcDebugDraw::GetScreenSpaceTextHeight(), buf);
|
|
}
|
|
|
|
if (variation.GetKit())
|
|
{
|
|
switch (variation.GetKit()->GetType())
|
|
{
|
|
case MKT_STANDARD:
|
|
safecpy(buf, "Standard mod kit");
|
|
break;
|
|
case MKT_SPORT:
|
|
safecpy(buf, "Sport mod kit");
|
|
break;
|
|
case MKT_SUV:
|
|
safecpy(buf, "SUV mod kit");
|
|
break;
|
|
case MKT_SPECIAL:
|
|
safecpy(buf, "Special mod kit");
|
|
break;
|
|
default:
|
|
safecpy(buf, "Unknown (!) mod kit");
|
|
}
|
|
grcDebugDraw::Text(WorldCoors, CRGBA(255, 0, 0, iAlpha), 0, (iNumLines++) * grcDebugDraw::GetScreenSpaceTextHeight(), buf);
|
|
}
|
|
|
|
if (variation.IsToggleModOn(VMT_TYRE_SMOKE))
|
|
{
|
|
formatf(buf, "Tyre smoke (%d, %d, %d)", variation.GetSmokeColorR(), variation.GetSmokeColorG(), variation.GetSmokeColorB());
|
|
grcDebugDraw::Text(WorldCoors, CRGBA(255, 0, 0, iAlpha), 0, (iNumLines++) * grcDebugDraw::GetScreenSpaceTextHeight(), buf);
|
|
}
|
|
|
|
if (variation.GetModIndex(VMT_WHEELS) != INVALID_MOD)
|
|
{
|
|
const CVehicleWheel& wheel = CVehicleModelInfo::GetVehicleColours()->m_Wheels[pVehicle->GetVehicleModelInfo()->GetWheelType()][variation.GetModIndex(VMT_WHEELS)];
|
|
formatf(buf, "Wheels %s", wheel.GetNameHashString().GetCStr());
|
|
grcDebugDraw::Text(WorldCoors, CRGBA(255, 0, 0, iAlpha), 0, (iNumLines++) * grcDebugDraw::GetScreenSpaceTextHeight(), buf);
|
|
}
|
|
|
|
if (variation.GetModIndex(VMT_WHEELS_REAR_OR_HYDRAULICS) != INVALID_MOD)
|
|
{
|
|
Assertf(pVehicle->GetVehicleModelInfo()->GetWheelType() == VWT_BIKE, "Rear wheel mod on non bike type wheel for vehicle '%s'", pVehicle->GetVehicleModelInfo()->GetModelName());
|
|
const CVehicleWheel& wheel = CVehicleModelInfo::GetVehicleColours()->m_Wheels[pVehicle->GetVehicleModelInfo()->GetWheelType()][variation.GetModIndex(VMT_WHEELS_REAR_OR_HYDRAULICS)];
|
|
formatf(buf, "Rear Wheels %s", wheel.GetNameHashString().GetCStr());
|
|
grcDebugDraw::Text(WorldCoors, CRGBA(255, 0, 0, iAlpha), 0, (iNumLines++) * grcDebugDraw::GetScreenSpaceTextHeight(), buf);
|
|
}
|
|
|
|
if (variation.GetModIndex(VMT_SPOILER) != INVALID_MOD)
|
|
{
|
|
grcDebugDraw::Text(WorldCoors, CRGBA(255, 0, 0, iAlpha), 0, (iNumLines++) * grcDebugDraw::GetScreenSpaceTextHeight(), "Spoiler mod enabled");
|
|
}
|
|
|
|
for (s32 i = 0; i <= VEH_LAST_EXTRA - VEH_EXTRA_1; ++i)
|
|
{
|
|
if (!pVehicle->GetDoesExtraExist((eHierarchyId)(VEH_EXTRA_1 + i)))
|
|
continue;
|
|
|
|
formatf(buf, "VEH_EXTRA_%d is %s", i + 1, pVehicle->GetIsExtraOn((eHierarchyId)(VEH_EXTRA_1 + i)) ? "on" : "off");
|
|
grcDebugDraw::Text(WorldCoors, CRGBA(255, 0, 0, iAlpha), 0, (iNumLines++) * grcDebugDraw::GetScreenSpaceTextHeight(), buf);
|
|
}
|
|
|
|
if (variation.GetNumMods() > 0)
|
|
{
|
|
formatf(buf, "Engine modifier: %d%s", variation.GetEngineModifier(), "%");
|
|
grcDebugDraw::Text(WorldCoors, CRGBA(255, 0, 0, iAlpha), 0, (iNumLines++) * grcDebugDraw::GetScreenSpaceTextHeight(), buf);
|
|
formatf(buf, "Brakes modifier: %d%s", variation.GetBrakesModifier(), "%");
|
|
grcDebugDraw::Text(WorldCoors, CRGBA(255, 0, 0, iAlpha), 0, (iNumLines++) * grcDebugDraw::GetScreenSpaceTextHeight(), buf);
|
|
formatf(buf, "Gearbox modifier: %d%s", variation.GetGearboxModifier(), "%");
|
|
grcDebugDraw::Text(WorldCoors, CRGBA(255, 0, 0, iAlpha), 0, (iNumLines++) * grcDebugDraw::GetScreenSpaceTextHeight(), buf);
|
|
formatf(buf, "Armour modifier: %d%s", variation.GetArmourModifier(), "%");
|
|
grcDebugDraw::Text(WorldCoors, CRGBA(255, 0, 0, iAlpha), 0, (iNumLines++) * grcDebugDraw::GetScreenSpaceTextHeight(), buf);
|
|
formatf(buf, "Suspension modifier: %d%s", variation.GetSuspensionModifier(), "%");
|
|
grcDebugDraw::Text(WorldCoors, CRGBA(255, 0, 0, iAlpha), 0, (iNumLines++) * grcDebugDraw::GetScreenSpaceTextHeight(), buf);
|
|
formatf(buf, "Weight modifier: %d%s", variation.GetTotalWeightModifier(), "%");
|
|
grcDebugDraw::Text(WorldCoors, CRGBA(255, 0, 0, iAlpha), 0, (iNumLines++) * grcDebugDraw::GetScreenSpaceTextHeight(), buf);
|
|
|
|
|
|
if (variation.IsToggleModOn(VMT_NITROUS))
|
|
{
|
|
formatf(buf, "Nitrous ON!");
|
|
grcDebugDraw::Text(WorldCoors, CRGBA(255, 0, 0, iAlpha), 0, (iNumLines++) * grcDebugDraw::GetScreenSpaceTextHeight(), buf);
|
|
}
|
|
if (variation.IsToggleModOn(VMT_TURBO))
|
|
{
|
|
formatf(buf, "Turbo ON!");
|
|
grcDebugDraw::Text(WorldCoors, CRGBA(255, 0, 0, iAlpha), 0, (iNumLines++) * grcDebugDraw::GetScreenSpaceTextHeight(), buf);
|
|
}
|
|
if (variation.IsToggleModOn(VMT_SUBWOOFER))
|
|
{
|
|
formatf(buf, "Subwoofer ON!");
|
|
grcDebugDraw::Text(WorldCoors, CRGBA(255, 0, 0, iAlpha), 0, (iNumLines++) * grcDebugDraw::GetScreenSpaceTextHeight(), buf);
|
|
}
|
|
if (variation.IsToggleModOn(VMT_XENON_LIGHTS))
|
|
{
|
|
formatf(buf, "Xenon Lights ON!");
|
|
grcDebugDraw::Text(WorldCoors, CRGBA(255, 0, 0, iAlpha), 0, (iNumLines++) * grcDebugDraw::GetScreenSpaceTextHeight(), buf);
|
|
}
|
|
if (variation.IsToggleModOn(VMT_HYDRAULICS))
|
|
{
|
|
formatf(buf, "Hydraulics ON!");
|
|
grcDebugDraw::Text(WorldCoors, CRGBA(255, 0, 0, iAlpha), 0, (iNumLines++) * grcDebugDraw::GetScreenSpaceTextHeight(), buf);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
int CVehicleFactory::CbCompareNames(const char* cLeft, const char* cRight)
|
|
{
|
|
return (cLeft && cRight)? 0 > strcmp(cLeft, cRight) : cLeft < cRight;
|
|
}
|
|
|
|
void CVehicleFactory::AddLayoutFilterWidget()
|
|
{
|
|
CVehicleMetadataMgr& pInstance = CVehicleMetadataMgr::GetInstance();
|
|
if (!&pInstance)
|
|
{
|
|
return;
|
|
}
|
|
|
|
atArray<const char*> layoutNames;
|
|
for(s32 i = pInstance.GetVehicleLayoutInfoCount()-1; i >= 0; i--)
|
|
{
|
|
atHashWithStringNotFinal pLayoutHash = pInstance.GetVehicleLayoutInfoAtIndex(i)->GetName();
|
|
const char* cLayoutName = pLayoutHash.GetCStr();
|
|
layoutNames.PushAndGrow(cLayoutName);
|
|
}
|
|
|
|
if (layoutNames.GetCount() > 0)
|
|
{
|
|
std::sort(&layoutNames[0],&layoutNames[0] + layoutNames.GetCount(), CVehicleFactory::CbCompareNames);
|
|
|
|
layoutNames.PushAndGrow("All");
|
|
|
|
currVehicleLayoutSelection = layoutNames.GetCount()-1;
|
|
pLayoutCombo = pBank->AddCombo("Layout Filter", &currVehicleLayoutSelection, layoutNames.GetCount(), &layoutNames[0], UpdateVehicleTypeList);
|
|
}
|
|
}
|
|
|
|
void CVehicleFactory::AddDLCFilterWidget()
|
|
{
|
|
atArray<const char*> DLCNames;
|
|
DLCNames.Reset();
|
|
u32 iNumVehicles = g_typeArray.GetCount();
|
|
|
|
for (int i=0; i<iNumVehicles; i++)
|
|
{
|
|
atHashString dlcHashName = g_typeArray[i]->GetVehicleDLCPack();
|
|
const char* dlcName = dlcHashName.GetCStr();
|
|
if ( DLCNames.Find(dlcName) < 0)
|
|
{
|
|
DLCNames.PushAndGrow(dlcName);
|
|
}
|
|
}
|
|
|
|
numDLCNames = DLCNames.GetCount();
|
|
|
|
if (DLCNames.GetCount() > 0)
|
|
{
|
|
std::sort(&DLCNames[0],&DLCNames[0] + DLCNames.GetCount(), CVehicleFactory::CbCompareNames);
|
|
|
|
DLCNames.PushAndGrow("All");
|
|
currVehicleDLCSelection = numDLCNames;
|
|
|
|
pDLCCombo = pBank->AddCombo("DLC Pack Filter", &currVehicleDLCSelection, numDLCNames+1, &DLCNames[0], UpdateVehicleTypeList);
|
|
}
|
|
}
|
|
|
|
//*******************************************************************************
|
|
// CBoardingPointEditor - this class handles adding of boarding-points to boats.
|
|
|
|
bool CBoardingPointEditor::ms_bPlacementToolEnabled = false;
|
|
int CBoardingPointEditor::ms_iSelectedBoardingPoint = -1;
|
|
bool CBoardingPointEditor::ms_bRespositioningBoardingPoint = false;
|
|
float g_fNavMaxHeightChange = 0.0f;
|
|
float g_fNavMinZDist = 0.75f;
|
|
float g_fNavRes = 1.0f;
|
|
|
|
|
|
CBoardingPointEditor::CBoardingPointEditor()
|
|
{
|
|
|
|
}
|
|
CBoardingPointEditor::~CBoardingPointEditor()
|
|
{
|
|
Shutdown();
|
|
}
|
|
|
|
void CBoardingPointEditor::Init()
|
|
{
|
|
|
|
}
|
|
CBoardingPoints * GetBoardingPointsFromVehicle(CVehicle * pVehicle)
|
|
{
|
|
return pVehicle->pHandling->m_pBoardingPoints;
|
|
}
|
|
CBoardingPoints * GetBoardingPointsFromVehicleFactoryIndex(int iVehicle)
|
|
{
|
|
int iModelNum = vehicleSorts[iVehicle];
|
|
u32 iModelIndex = GetModelIndex(iModelNum);
|
|
if(iModelIndex != fwModelId::MI_INVALID)
|
|
{
|
|
CVehicleModelInfo * pVehModelInfo = (CVehicleModelInfo *)CModelInfo::GetBaseModelInfo(fwModelId(strLocalIndex(iModelIndex)));
|
|
if(pVehModelInfo)
|
|
{
|
|
CHandlingData * pBaseHandling = CHandlingDataMgr::GetHandlingDataByName(CVehicleFactory::vehicleNames[iVehicle]);
|
|
if(pBaseHandling)
|
|
{
|
|
return pBaseHandling->m_pBoardingPoints;
|
|
}
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
void CBoardingPointEditor::Process()
|
|
{
|
|
if(!ms_bPlacementToolEnabled)
|
|
return;
|
|
|
|
// Draw the boarding-points for the current boat
|
|
if(CVehicleFactory::ms_pLastCreatedVehicle &&
|
|
(CVehicleFactory::ms_pLastCreatedVehicle->GetVehicleType()==VEHICLE_TYPE_BOAT ||
|
|
CVehicleFactory::ms_pLastCreatedVehicle->GetVehicleType()==VEHICLE_TYPE_PLANE ||
|
|
CVehicleFactory::ms_pLastCreatedVehicle->GetVehicleType()==VEHICLE_TYPE_HELI ||
|
|
CVehicleFactory::ms_pLastCreatedVehicle->GetVehicleType()==VEHICLE_TYPE_TRAIN))
|
|
{
|
|
CBoardingPoints * pBoardingPoints = GetBoardingPointsFromVehicle( CVehicleFactory::ms_pLastCreatedVehicle.Get() );
|
|
|
|
if(pBoardingPoints && ms_bRespositioningBoardingPoint && ms_iSelectedBoardingPoint>=0 && ms_iSelectedBoardingPoint >= 0 && ms_iSelectedBoardingPoint < pBoardingPoints->m_iNumBoardingPoints)
|
|
{
|
|
Vector3 mouseScreen, mouseFar;
|
|
CDebugScene::GetMousePointing(mouseScreen, mouseFar);
|
|
|
|
WorldProbe::CShapeTestProbeDesc probeDesc;
|
|
WorldProbe::CShapeTestFixedResults<> probeResult;
|
|
probeDesc.SetResultsStructure(&probeResult);
|
|
probeDesc.SetStartAndEnd(mouseScreen, mouseFar);
|
|
probeDesc.SetIncludeFlags(ArchetypeFlags::GTA_VEHICLE_TYPE);
|
|
if(WorldProbe::GetShapeTestManager()->SubmitTest(probeDesc))
|
|
{
|
|
CEntity * pHitEntity = CPhysics::GetEntityFromInst(probeResult[0].GetHitInst());
|
|
|
|
if(pHitEntity && pHitEntity==CVehicleFactory::ms_pLastCreatedVehicle)
|
|
{
|
|
Vector3 vHitPos = VEC3V_TO_VECTOR3(pHitEntity->GetTransform().UnTransform(VECTOR3_TO_VEC3V(probeResult[0].GetHitPosition())));
|
|
|
|
pBoardingPoints->m_BoardingPoints[ms_iSelectedBoardingPoint].m_fPosition[0] = vHitPos.x;
|
|
pBoardingPoints->m_BoardingPoints[ms_iSelectedBoardingPoint].m_fPosition[1] = vHitPos.y;
|
|
pBoardingPoints->m_BoardingPoints[ms_iSelectedBoardingPoint].m_fPosition[2] = vHitPos.z;
|
|
}
|
|
}
|
|
}
|
|
|
|
if(ioMouse::GetPressedButtons()&ioMouse::MOUSE_LEFT)
|
|
ms_bRespositioningBoardingPoint = false;
|
|
|
|
if(pBoardingPoints)
|
|
{
|
|
for(int p=0; p<pBoardingPoints->m_iNumBoardingPoints; p++)
|
|
{
|
|
Vector3 vPos(pBoardingPoints->m_BoardingPoints[p].m_fPosition[0], pBoardingPoints->m_BoardingPoints[p].m_fPosition[1], pBoardingPoints->m_BoardingPoints[p].m_fPosition[2]);
|
|
Vector3 vDir(rage::Sinf(pBoardingPoints->m_BoardingPoints[p].m_fHeading), -rage::Cosf(pBoardingPoints->m_BoardingPoints[p].m_fHeading), 0.0f);
|
|
|
|
vPos = VEC3V_TO_VECTOR3(CVehicleFactory::ms_pLastCreatedVehicle.Get()->GetTransform().Transform(VECTOR3_TO_VEC3V(vPos)));
|
|
vDir = VEC3V_TO_VECTOR3(CVehicleFactory::ms_pLastCreatedVehicle.Get()->GetTransform().Transform3x3(VECTOR3_TO_VEC3V(vDir)));
|
|
|
|
static u32 iFlashTime = 0;
|
|
static bool bToggle = false;
|
|
|
|
if(fwTimer::GetTimeInMilliseconds()-iFlashTime > 600)
|
|
{
|
|
iFlashTime = fwTimer::GetTimeInMilliseconds();
|
|
bToggle = !bToggle;
|
|
}
|
|
|
|
const bool bAltCol = (bToggle && p==ms_iSelectedBoardingPoint);
|
|
|
|
const Color32 iSphereCol = bAltCol ? Color_turquoise : Color_turquoise4;
|
|
const Color32 iHdgCol = bAltCol ? Color_red : Color_red4;
|
|
|
|
grcDebugDraw::Sphere(vPos, PED_HUMAN_RADIUS, iSphereCol, false);
|
|
grcDebugDraw::Line(vPos, vPos + vDir, iHdgCol);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void CBoardingPointEditor::Shutdown()
|
|
{
|
|
|
|
}
|
|
|
|
void CBoardingPointEditor::CreateWidgets(bkBank * bank)
|
|
{
|
|
bank->PushGroup("Boat/Plane/Heli/Train Boarding-Points", false);
|
|
bank->AddToggle("Placement Tool Enabled", &ms_bPlacementToolEnabled);
|
|
|
|
bank->AddButton("Create Next Boat/Plane/Heli/Train", CreateNextBoatCB);
|
|
bank->AddButton("Create Prev Boat/Plane/Heli/Train", CreatePrevBoatCB);
|
|
bank->AddButton("Add Boarding-Point", AddBoardingPointCB);
|
|
bank->AddButton("Select Next", SelectNextBoardingPointCB);
|
|
bank->AddButton("Select Prev", SelectPrevBoardingPointCB);
|
|
bank->AddButton("Delete Current", DeleteCurrentBoardingPointCB);
|
|
bank->AddButton("Move Current", MoveCurrentBoardingPointCB);
|
|
bank->AddButton("Rotate Clockwise", RotateClockwiseCurrentBoardingPointCB);
|
|
bank->AddButton("Rotate AntiClockwise", RotateAntiClockwiseCurrentBoardingPointCB);
|
|
bank->AddButton("Move up", MoveUp);
|
|
bank->AddButton("Move down", MoveDown);
|
|
bank->AddButton("Move forward", MoveForward);
|
|
bank->AddButton("Move backward", MoveBackward);
|
|
bank->AddButton("Move left", MoveLeft);
|
|
bank->AddButton("Move right", MoveRight);
|
|
|
|
bank->AddButton("Save Boarding-Points Data", SaveBoardingPointsCB);
|
|
|
|
bank->PopGroup();
|
|
}
|
|
|
|
void CBoardingPointEditor::CreatePrevBoatCB()
|
|
{
|
|
CreateNextBoat(-1);
|
|
}
|
|
|
|
void CBoardingPointEditor::CreateNextBoatCB()
|
|
{
|
|
CreateNextBoat(1);
|
|
}
|
|
|
|
void CBoardingPointEditor::CreateNextBoat(int iDir)
|
|
{
|
|
if(!ms_bPlacementToolEnabled) return;
|
|
|
|
// delete existing car if it exists - this widget is meant for cycling through vehicles
|
|
DeleteCarCB();
|
|
|
|
bool bFoundBoat = false;
|
|
bool bFoundPlane = false;
|
|
bool bFoundHeli = false;
|
|
bool bFoundTrain = false;
|
|
|
|
while(!bFoundBoat && !bFoundPlane && !bFoundHeli && !bFoundTrain)
|
|
{
|
|
CVehicleFactory::currVehicleNameSelection += iDir;
|
|
|
|
if(CVehicleFactory::currVehicleNameSelection < 0)
|
|
CVehicleFactory::currVehicleNameSelection = numVehicleNames-1;
|
|
if(CVehicleFactory::currVehicleNameSelection >= numVehicleNames)
|
|
CVehicleFactory::currVehicleNameSelection = 0;
|
|
|
|
CVehicleFactory::carModelId = GetModelIndex(vehicleSorts[CVehicleFactory::currVehicleNameSelection]);
|
|
|
|
CVehicleModelInfo * pVehModelInfo = (CVehicleModelInfo *)CModelInfo::GetBaseModelInfo(fwModelId(strLocalIndex(CVehicleFactory::carModelId)));
|
|
if(pVehModelInfo->GetVehicleType()==VEHICLE_TYPE_BOAT)
|
|
bFoundBoat=true;
|
|
if(pVehModelInfo->GetVehicleType()==VEHICLE_TYPE_PLANE)
|
|
bFoundPlane=true;
|
|
if(pVehModelInfo->GetVehicleType()==VEHICLE_TYPE_HELI)
|
|
bFoundHeli=true;
|
|
if(pVehModelInfo->GetVehicleType()==VEHICLE_TYPE_TRAIN)
|
|
bFoundTrain=true;
|
|
}
|
|
|
|
CVehicleFactory::CarNumChangeCB();
|
|
CreateCarCB();
|
|
|
|
if(!CVehicleFactory::ms_pLastCreatedVehicle)
|
|
return;
|
|
CBoardingPoints * pBoardingPoints = GetBoardingPointsFromVehicle( CVehicleFactory::ms_pLastCreatedVehicle.Get() );
|
|
if(!pBoardingPoints)
|
|
return;
|
|
|
|
g_fNavMaxHeightChange = pBoardingPoints->m_fNavMaxHeightChange;
|
|
g_fNavMinZDist = pBoardingPoints->m_fNavMinZDist;
|
|
g_fNavRes = pBoardingPoints->m_fNavRes;
|
|
}
|
|
|
|
void CBoardingPointEditor::AddBoardingPointCB()
|
|
{
|
|
if(!ms_bPlacementToolEnabled) return;
|
|
if(!CVehicleFactory::ms_pLastCreatedVehicle)
|
|
return;
|
|
|
|
CBoardingPoints * pBoardingPoints = GetBoardingPointsFromVehicle( CVehicleFactory::ms_pLastCreatedVehicle.Get() );
|
|
if(!pBoardingPoints)
|
|
{
|
|
CVehicle * pVehicle = CVehicleFactory::ms_pLastCreatedVehicle.Get();
|
|
Assert(!pVehicle->pHandling->m_pBoardingPoints);
|
|
pVehicle->pHandling->m_pBoardingPoints = rage_new CBoardingPoints();
|
|
pBoardingPoints = pVehicle->pHandling->m_pBoardingPoints;
|
|
}
|
|
|
|
if(pBoardingPoints->m_iNumBoardingPoints < MAX_NUM_BOARDING_POINTS)
|
|
{
|
|
ms_iSelectedBoardingPoint = pBoardingPoints->m_iNumBoardingPoints;
|
|
pBoardingPoints->m_iNumBoardingPoints++;
|
|
|
|
pBoardingPoints->m_BoardingPoints[ms_iSelectedBoardingPoint].m_fPosition[0] = 0.0f;
|
|
pBoardingPoints->m_BoardingPoints[ms_iSelectedBoardingPoint].m_fPosition[1] = 0.0f;
|
|
pBoardingPoints->m_BoardingPoints[ms_iSelectedBoardingPoint].m_fPosition[2] = 0.0f;
|
|
pBoardingPoints->m_BoardingPoints[ms_iSelectedBoardingPoint].m_fHeading = 0.0f;
|
|
|
|
ms_bRespositioningBoardingPoint = true;
|
|
}
|
|
}
|
|
|
|
void CBoardingPointEditor::SelectNextBoardingPointCB()
|
|
{
|
|
if(!ms_bPlacementToolEnabled) return;
|
|
if(!CVehicleFactory::ms_pLastCreatedVehicle)
|
|
return;
|
|
|
|
CBoardingPoints * pBoardingPoints = GetBoardingPointsFromVehicle( CVehicleFactory::ms_pLastCreatedVehicle.Get() );
|
|
if(!pBoardingPoints)
|
|
return;
|
|
|
|
if(pBoardingPoints->m_iNumBoardingPoints==0)
|
|
{
|
|
ms_iSelectedBoardingPoint=-1;
|
|
return;
|
|
}
|
|
|
|
ms_iSelectedBoardingPoint++;
|
|
|
|
if(ms_iSelectedBoardingPoint >= pBoardingPoints->m_iNumBoardingPoints)
|
|
ms_iSelectedBoardingPoint = 0;
|
|
}
|
|
|
|
void CBoardingPointEditor::SelectPrevBoardingPointCB()
|
|
{
|
|
if(!ms_bPlacementToolEnabled) return;
|
|
if(!CVehicleFactory::ms_pLastCreatedVehicle)
|
|
return;
|
|
|
|
CBoardingPoints * pBoardingPoints = GetBoardingPointsFromVehicle( CVehicleFactory::ms_pLastCreatedVehicle.Get() );
|
|
if(!pBoardingPoints)
|
|
return;
|
|
|
|
if(pBoardingPoints->m_iNumBoardingPoints==0)
|
|
{
|
|
ms_iSelectedBoardingPoint=-1;
|
|
return;
|
|
}
|
|
|
|
ms_iSelectedBoardingPoint--;
|
|
|
|
if(ms_iSelectedBoardingPoint < 0)
|
|
ms_iSelectedBoardingPoint = pBoardingPoints->m_iNumBoardingPoints-1;
|
|
}
|
|
|
|
void CBoardingPointEditor::DeleteCurrentBoardingPointCB()
|
|
{
|
|
if(!ms_bPlacementToolEnabled) return;
|
|
if(!CVehicleFactory::ms_pLastCreatedVehicle)
|
|
return;
|
|
|
|
CBoardingPoints * pBoardingPoints = GetBoardingPointsFromVehicle( CVehicleFactory::ms_pLastCreatedVehicle.Get() );
|
|
if(!pBoardingPoints)
|
|
return;
|
|
|
|
if(ms_iSelectedBoardingPoint < 0 || ms_iSelectedBoardingPoint >= pBoardingPoints->m_iNumBoardingPoints || pBoardingPoints->m_iNumBoardingPoints==0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
for(int p=ms_iSelectedBoardingPoint; p<pBoardingPoints->m_iNumBoardingPoints-1; p++)
|
|
{
|
|
pBoardingPoints->m_BoardingPoints[p] = pBoardingPoints->m_BoardingPoints[p+1];
|
|
}
|
|
pBoardingPoints->m_iNumBoardingPoints--;
|
|
|
|
ms_iSelectedBoardingPoint = -1;
|
|
|
|
if(pBoardingPoints->m_iNumBoardingPoints == 0)
|
|
{
|
|
CVehicle * pVehicle = CVehicleFactory::ms_pLastCreatedVehicle.Get();
|
|
Assert(pVehicle->pHandling->m_pBoardingPoints);
|
|
delete pVehicle->pHandling->m_pBoardingPoints;
|
|
pVehicle->pHandling->m_pBoardingPoints = NULL;
|
|
}
|
|
}
|
|
|
|
void CBoardingPointEditor::MoveCurrentBoardingPointCB()
|
|
{
|
|
if(!ms_bPlacementToolEnabled) return;
|
|
if(!CVehicleFactory::ms_pLastCreatedVehicle)
|
|
return;
|
|
|
|
CBoardingPoints * pBoardingPoints = GetBoardingPointsFromVehicle( CVehicleFactory::ms_pLastCreatedVehicle.Get() );
|
|
if(!pBoardingPoints)
|
|
return;
|
|
|
|
if(ms_iSelectedBoardingPoint < 0 || ms_iSelectedBoardingPoint >= pBoardingPoints->m_iNumBoardingPoints || pBoardingPoints->m_iNumBoardingPoints==0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
ms_bRespositioningBoardingPoint = true;
|
|
}
|
|
|
|
void CBoardingPointEditor::RotateClockwiseCurrentBoardingPointCB()
|
|
{
|
|
if(!ms_bPlacementToolEnabled) return;
|
|
if(!CVehicleFactory::ms_pLastCreatedVehicle)
|
|
return;
|
|
|
|
CBoardingPoints * pBoardingPoints = GetBoardingPointsFromVehicle( CVehicleFactory::ms_pLastCreatedVehicle.Get() );
|
|
if(!pBoardingPoints)
|
|
return;
|
|
|
|
if(ms_iSelectedBoardingPoint < 0 || ms_iSelectedBoardingPoint >= pBoardingPoints->m_iNumBoardingPoints || pBoardingPoints->m_iNumBoardingPoints==0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
pBoardingPoints->m_BoardingPoints[ms_iSelectedBoardingPoint].m_fHeading -= ( DtoR * 10.0f);
|
|
if(pBoardingPoints->m_BoardingPoints[ms_iSelectedBoardingPoint].m_fHeading < 0.0f)
|
|
pBoardingPoints->m_BoardingPoints[ms_iSelectedBoardingPoint].m_fHeading += PI*2.0f;
|
|
}
|
|
|
|
void CBoardingPointEditor::RotateAntiClockwiseCurrentBoardingPointCB()
|
|
{
|
|
if(!ms_bPlacementToolEnabled) return;
|
|
if(!CVehicleFactory::ms_pLastCreatedVehicle)
|
|
return;
|
|
|
|
CBoardingPoints * pBoardingPoints = GetBoardingPointsFromVehicle( CVehicleFactory::ms_pLastCreatedVehicle.Get() );
|
|
if(!pBoardingPoints)
|
|
return;
|
|
|
|
if(ms_iSelectedBoardingPoint < 0 || ms_iSelectedBoardingPoint >= pBoardingPoints->m_iNumBoardingPoints || pBoardingPoints->m_iNumBoardingPoints==0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
pBoardingPoints->m_BoardingPoints[ms_iSelectedBoardingPoint].m_fHeading += ( DtoR * 10.0f);
|
|
if(pBoardingPoints->m_BoardingPoints[ms_iSelectedBoardingPoint].m_fHeading >= PI*2.0f)
|
|
pBoardingPoints->m_BoardingPoints[ms_iSelectedBoardingPoint].m_fHeading -= PI*2.0f;
|
|
}
|
|
dev_float MOVE_SPEED = 0.05f;
|
|
void CBoardingPointEditor::MoveUp()
|
|
{
|
|
if(!ms_bPlacementToolEnabled) return;
|
|
if(!CVehicleFactory::ms_pLastCreatedVehicle)
|
|
return;
|
|
|
|
CBoardingPoints * pBoardingPoints = GetBoardingPointsFromVehicle( CVehicleFactory::ms_pLastCreatedVehicle.Get() );
|
|
if(!pBoardingPoints)
|
|
return;
|
|
|
|
if(ms_iSelectedBoardingPoint < 0 || ms_iSelectedBoardingPoint >= pBoardingPoints->m_iNumBoardingPoints || pBoardingPoints->m_iNumBoardingPoints==0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
pBoardingPoints->m_BoardingPoints[ms_iSelectedBoardingPoint].m_fPosition[2] += MOVE_SPEED;
|
|
}
|
|
|
|
void CBoardingPointEditor::MoveDown()
|
|
{
|
|
if(!ms_bPlacementToolEnabled) return;
|
|
if(!CVehicleFactory::ms_pLastCreatedVehicle)
|
|
return;
|
|
|
|
CBoardingPoints * pBoardingPoints = GetBoardingPointsFromVehicle( CVehicleFactory::ms_pLastCreatedVehicle.Get() );
|
|
if(!pBoardingPoints)
|
|
return;
|
|
|
|
if(ms_iSelectedBoardingPoint < 0 || ms_iSelectedBoardingPoint >= pBoardingPoints->m_iNumBoardingPoints || pBoardingPoints->m_iNumBoardingPoints==0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
pBoardingPoints->m_BoardingPoints[ms_iSelectedBoardingPoint].m_fPosition[2] -= MOVE_SPEED;
|
|
}
|
|
|
|
void CBoardingPointEditor::MoveForward()
|
|
{
|
|
if(!ms_bPlacementToolEnabled) return;
|
|
if(!CVehicleFactory::ms_pLastCreatedVehicle)
|
|
return;
|
|
|
|
CBoardingPoints * pBoardingPoints = GetBoardingPointsFromVehicle( CVehicleFactory::ms_pLastCreatedVehicle.Get() );
|
|
if(!pBoardingPoints)
|
|
return;
|
|
|
|
if(ms_iSelectedBoardingPoint < 0 || ms_iSelectedBoardingPoint >= pBoardingPoints->m_iNumBoardingPoints || pBoardingPoints->m_iNumBoardingPoints==0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
Vector3 vHeading(0.0f, 1.0f, 0.0f);
|
|
vHeading.RotateZ(pBoardingPoints->m_BoardingPoints[ms_iSelectedBoardingPoint].m_fHeading);
|
|
|
|
|
|
pBoardingPoints->m_BoardingPoints[ms_iSelectedBoardingPoint].m_fPosition[0] -= vHeading.x * MOVE_SPEED;
|
|
pBoardingPoints->m_BoardingPoints[ms_iSelectedBoardingPoint].m_fPosition[1] -= vHeading.y * MOVE_SPEED;
|
|
}
|
|
|
|
void CBoardingPointEditor::MoveBackward()
|
|
{
|
|
if(!ms_bPlacementToolEnabled) return;
|
|
if(!CVehicleFactory::ms_pLastCreatedVehicle)
|
|
return;
|
|
|
|
CBoardingPoints * pBoardingPoints = GetBoardingPointsFromVehicle( CVehicleFactory::ms_pLastCreatedVehicle.Get() );
|
|
if(!pBoardingPoints)
|
|
return;
|
|
|
|
if(ms_iSelectedBoardingPoint < 0 || ms_iSelectedBoardingPoint >= pBoardingPoints->m_iNumBoardingPoints || pBoardingPoints->m_iNumBoardingPoints==0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
Vector3 vHeading(0.0f, 1.0f, 0.0f);
|
|
vHeading.RotateZ(pBoardingPoints->m_BoardingPoints[ms_iSelectedBoardingPoint].m_fHeading);
|
|
|
|
pBoardingPoints->m_BoardingPoints[ms_iSelectedBoardingPoint].m_fPosition[0] += vHeading.x * MOVE_SPEED;
|
|
pBoardingPoints->m_BoardingPoints[ms_iSelectedBoardingPoint].m_fPosition[1] += vHeading.y * MOVE_SPEED;
|
|
}
|
|
|
|
void CBoardingPointEditor::MoveLeft()
|
|
{
|
|
if(!ms_bPlacementToolEnabled) return;
|
|
if(!CVehicleFactory::ms_pLastCreatedVehicle)
|
|
return;
|
|
|
|
CBoardingPoints * pBoardingPoints = GetBoardingPointsFromVehicle( CVehicleFactory::ms_pLastCreatedVehicle.Get() );
|
|
if(!pBoardingPoints)
|
|
return;
|
|
|
|
if(ms_iSelectedBoardingPoint < 0 || ms_iSelectedBoardingPoint >= pBoardingPoints->m_iNumBoardingPoints || pBoardingPoints->m_iNumBoardingPoints==0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
Vector3 vHeading(1.0f, 0.0f, 0.0f);
|
|
vHeading.RotateZ(pBoardingPoints->m_BoardingPoints[ms_iSelectedBoardingPoint].m_fHeading);
|
|
|
|
pBoardingPoints->m_BoardingPoints[ms_iSelectedBoardingPoint].m_fPosition[0] += vHeading.x * MOVE_SPEED;
|
|
pBoardingPoints->m_BoardingPoints[ms_iSelectedBoardingPoint].m_fPosition[1] += vHeading.y * MOVE_SPEED;
|
|
}
|
|
|
|
void CBoardingPointEditor::MoveRight()
|
|
{
|
|
if(!ms_bPlacementToolEnabled) return;
|
|
if(!CVehicleFactory::ms_pLastCreatedVehicle)
|
|
return;
|
|
|
|
CBoardingPoints * pBoardingPoints = GetBoardingPointsFromVehicle( CVehicleFactory::ms_pLastCreatedVehicle.Get() );
|
|
if(!pBoardingPoints)
|
|
return;
|
|
|
|
if(ms_iSelectedBoardingPoint < 0 || ms_iSelectedBoardingPoint >= pBoardingPoints->m_iNumBoardingPoints || pBoardingPoints->m_iNumBoardingPoints==0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
Vector3 vHeading(1.0f, 0.0f, 0.0f);
|
|
vHeading.RotateZ(pBoardingPoints->m_BoardingPoints[ms_iSelectedBoardingPoint].m_fHeading);
|
|
|
|
pBoardingPoints->m_BoardingPoints[ms_iSelectedBoardingPoint].m_fPosition[0] -= vHeading.x * MOVE_SPEED;
|
|
pBoardingPoints->m_BoardingPoints[ms_iSelectedBoardingPoint].m_fPosition[1] -= vHeading.y * MOVE_SPEED;
|
|
}
|
|
|
|
void CBoardingPointEditor::SaveBoardingPointsCB()
|
|
{
|
|
if(!ms_bPlacementToolEnabled) return;
|
|
|
|
Assertf(0, "The game will now prompt for a text file to ouput the boarding points.\nThese should then be **copied/pasted** into \"VehicleExtras.dat\" in the appropriate section.\nDo not save the boarding-points data directly over \"VehicleExtras.dat\"!!");
|
|
|
|
char filename[512];
|
|
bool bOk = BANKMGR.OpenFile(filename, 512, "*.txt", true, "Save boarding-points to text file");
|
|
|
|
if(!bOk)
|
|
return;
|
|
|
|
fiStream * pFile = fiStream::Create(filename);
|
|
Assert(pFile);
|
|
if(!pFile)
|
|
return;
|
|
|
|
const char * pDesc = ";Start of boarding-points section\r\n;This section should be copied into \"VehicleExtras.dat\"\r\n\r\n";
|
|
pFile->Write(pDesc, istrlen(pDesc));
|
|
|
|
// First count how many boats we have
|
|
int iNumVehiclesWithBoardingPoints = 0;
|
|
int iVehicle;
|
|
|
|
for(iVehicle=0; iVehicle<numVehicleNames; iVehicle++)
|
|
{
|
|
CBoardingPoints * pBoardingPoints = GetBoardingPointsFromVehicleFactoryIndex(iVehicle);
|
|
if(pBoardingPoints)
|
|
iNumVehiclesWithBoardingPoints++;
|
|
}
|
|
|
|
char buffer[256];
|
|
|
|
sprintf(buffer, "START_BOARDING_POINTS\r\n\r\n");
|
|
pFile->Write(buffer, istrlen(buffer));
|
|
|
|
for(iVehicle=0; iVehicle<numVehicleNames; iVehicle++)
|
|
{
|
|
CBoardingPoints * pBoardingPoints = GetBoardingPointsFromVehicleFactoryIndex(iVehicle);
|
|
if(pBoardingPoints)
|
|
{
|
|
if(pBoardingPoints && pBoardingPoints->m_iNumBoardingPoints)
|
|
{
|
|
sprintf(buffer, "VEHICLE_NAME %s NUM_BOARDING_POINTS %i NAV_MAXHEIGHTCHANGE %f NAV_MINZDIST %f NAV_RES %f\r\n\r\n", CVehicleFactory::vehicleNames[iVehicle], pBoardingPoints->m_iNumBoardingPoints, pBoardingPoints->m_fNavMaxHeightChange, pBoardingPoints->m_fNavMinZDist, pBoardingPoints->m_fNavRes);
|
|
pFile->Write(buffer, istrlen(buffer));
|
|
|
|
for(int p=0; p<pBoardingPoints->m_iNumBoardingPoints; p++)
|
|
{
|
|
CBoardingPoint & bp = pBoardingPoints->m_BoardingPoints[p];
|
|
|
|
sprintf(buffer, "X %.2f Y %.2f Z %.2f HEADING %.2f\r\n", bp.m_fPosition[0], bp.m_fPosition[1], bp.m_fPosition[2], bp.m_fHeading);
|
|
pFile->Write(buffer, istrlen(buffer));
|
|
}
|
|
|
|
sprintf(buffer, "\r\n");
|
|
pFile->Write(buffer, istrlen(buffer));
|
|
}
|
|
}
|
|
}
|
|
sprintf(buffer, "END_BOARDING_POINTS\r\n\r\n");
|
|
pFile->Write(buffer, istrlen(buffer));
|
|
sprintf(buffer, ";End of boarding-points section\r\n\r\n");
|
|
pFile->Write(buffer, istrlen(buffer));
|
|
|
|
pFile->Close();
|
|
}
|
|
|
|
|
|
#endif //__BANK
|
|
|
|
void CVehicleFactory::AddDestroyedVehToCache(CVehicle* veh)
|
|
{
|
|
if (!veh)
|
|
return;
|
|
|
|
GPU_VEHICLE_DAMAGE_ONLY(CApplyDamage::RemoveVehicleDeformation(veh));
|
|
GPU_VEHICLE_DAMAGE_ONLY(CPhysics::RemoveVehicleDeformation(veh));
|
|
|
|
REPLAY_ONLY(CReplayMgr::OnDelete(veh));
|
|
|
|
// if we have the cache turned off or this is a modded vehicle, free it now
|
|
if (!ms_reuseDestroyedVehs || veh->GetStatus() == STATUS_WRECKED || veh->IsModded() || veh == CGameWorld::FindLocalPlayerVehicle())
|
|
{
|
|
delete veh;
|
|
return;
|
|
}
|
|
|
|
// Ensure that any vehicle being removed to the cache is removed from the pathserver also
|
|
CPathServerGta::MaybeRemoveDynamicObject(veh);
|
|
|
|
// Remove refs on this vehicle's dynamic navmesh if it has one
|
|
CPathServerGta::MaybeRemoveDynamicObjectNavMesh(veh);
|
|
|
|
|
|
// make sure we don't already have this pointer in the list
|
|
s32 firstFree = -1;
|
|
for (s32 i = 0; i < MAX_DESTROYED_VEHS_CACHED; ++i)
|
|
{
|
|
// skip if this vehicle is already on the list
|
|
if (ms_reuseDestroyedVehArray[i].veh == veh)
|
|
return;
|
|
|
|
if (firstFree == -1 && ms_reuseDestroyedVehArray[i].veh == NULL)
|
|
firstFree = i;
|
|
}
|
|
|
|
// we have a slot, cache the vehicle
|
|
if (firstFree > -1)
|
|
{
|
|
// Clean dummy transition surface
|
|
CWheel * const * ppWheels = veh->GetWheels();
|
|
for(int i=0; i<veh->GetNumWheels(); i++)
|
|
{
|
|
ppWheels[i]->EndDummyTransition();
|
|
}
|
|
|
|
veh->SetIsInPopulationCache(true);
|
|
|
|
// clean up peds in vehicle
|
|
for( s32 i = 0; i < MAX_VEHICLE_SEATS; i++ )
|
|
{
|
|
CPed* pPed = veh->GetSeatManager()->GetPedInSeat(i);
|
|
if (pPed)
|
|
{
|
|
Assert (!pPed->IsNetworkClone());
|
|
const bool bIsNetworkClone = pPed->GetNetworkObject() && !pPed->GetNetworkObject()->CanDelete();
|
|
|
|
// Dont delete mission or player peds or network clones, flushing immediately sets them outside the vehicle.
|
|
if (bIsNetworkClone || pPed->IsAPlayerPed() || pPed->PopTypeIsMission() || !CPedFactory::GetFactory()->DestroyPed(pPed, true))
|
|
pPed->GetPedIntelligence()->FlushImmediately();
|
|
|
|
Assertf(!veh->GetSeatManager()->GetPedInSeat(i), "CVehicleFactory::AddDestroyedVehToCache - expected the vehicle's passenger to have been removed");
|
|
}
|
|
}
|
|
veh->ResetSeatManagerForReuse();
|
|
veh->ResetExclusiveDriverForReuse();
|
|
BANK_ONLY(veh->ResetDebugObjectID());
|
|
veh->SetLastTimeHomedAt(0);
|
|
veh->SetEasyToLand(false);
|
|
|
|
for( s32 i = 0; i < MAX_NUM_VEHICLE_WEAPONS; i++ )
|
|
{
|
|
veh->SetRestrictedAmmoCount(i, -1);
|
|
}
|
|
|
|
veh->m_nCloneFlaggedForWreckedOrEmptyDeletionTime = 0;
|
|
|
|
if(veh->GetVehicleAudioEntity())
|
|
{
|
|
veh->GetVehicleAudioEntity()->Shutdown();
|
|
}
|
|
|
|
veh->m_nVehicleFlags.bUsingPretendOccupants = false;
|
|
veh->GetIntelligence()->FlushPretendOccupantEventGroup();
|
|
veh->GetIntelligence()->ResetPretendOccupantEventData();
|
|
veh->GetIntelligence()->SetNumPedsThatNeedTaskFromPretendOccupant(0);
|
|
|
|
veh->CarAlarmState = CAR_ALARM_NONE;
|
|
|
|
veh->RemoveBlip(BLIP_TYPE_CAR);
|
|
|
|
// detach trailers and towed cars
|
|
for (s32 i = 0; i < veh->GetNumberOfVehicleGadgets(); ++i)
|
|
{
|
|
CVehicleGadget* gadget = veh->GetVehicleGadget(i);
|
|
if (!gadget)
|
|
continue;
|
|
|
|
if(gadget->GetType() == VGT_TRAILER_ATTACH_POINT)
|
|
{
|
|
CVehicleTrailerAttachPoint* attachPoint = static_cast<CVehicleTrailerAttachPoint*>(gadget);
|
|
attachPoint->DetachTrailer(veh);
|
|
}
|
|
else if(gadget->GetType() == VGT_TOW_TRUCK_ARM)
|
|
{
|
|
CVehicleGadgetTowArm* towArm = static_cast<CVehicleGadgetTowArm*>(gadget);
|
|
towArm->DeleteRopesHookAndConstraints(veh);
|
|
}
|
|
else if(gadget->GetType() == VGT_PICK_UP_ROPE || gadget->GetType() == VGT_PICK_UP_ROPE_MAGNET)
|
|
{
|
|
CVehicleGadgetPickUpRope* pPickUpRope = static_cast<CVehicleGadgetPickUpRope*>(gadget);
|
|
pPickUpRope->DeleteRopesPropAndConstraints(veh);
|
|
}
|
|
}
|
|
|
|
veh->SetIsScheduled(false);
|
|
veh->GetPortalTracker()->DontRequestScaneNextUpdate();
|
|
veh->GetPortalTracker()->StopScanUntilProbeTrue();
|
|
|
|
// flush tasks
|
|
veh->GetIntelligence()->GetTaskManager()->AbortTasks();
|
|
|
|
veh->GetFrameCollisionHistory()->Reset();
|
|
veh->GetIntelligence()->ClearScanners();
|
|
|
|
if(veh->GetParentTrailer())
|
|
veh->GetParentTrailer()->RemoveCargoVehicle(veh);
|
|
veh->SetParentTrailer(NULL);
|
|
|
|
if(veh->GetDummyAttachmentParent())
|
|
veh->GetDummyAttachmentParent()->DummyDetachChild(veh);
|
|
|
|
if(veh->HasDummyAttachmentChildren())
|
|
veh->DummyDetachAllChildren();
|
|
|
|
// remove script guid so script can't grab this ped pointer while it's in the cache
|
|
fwScriptGuid::DeleteGuid(*veh);
|
|
|
|
veh->GetIntelligence()->SetCarWeAreBehind(NULL);
|
|
|
|
veh->SetVelocity(VEC3_ZERO);
|
|
veh->SetAngVelocity(VEC3_ZERO);
|
|
veh->SetSuperDummyVelocity(VEC3_ZERO);
|
|
|
|
if (veh->InheritsFromAutomobile())
|
|
((CAutomobile*)veh)->RemoveConstraints();
|
|
else if (veh->InheritsFromBike())
|
|
((CBike*)veh)->RemoveConstraint();
|
|
else if (veh->InheritsFromBoat())
|
|
{
|
|
CBoat* boat = (CBoat*)veh;
|
|
boat->DetachFromParentAndChildren(DETACH_FLAG_DONT_REMOVE_BASIC_ATTACHMENTS);
|
|
}
|
|
|
|
if (veh->GetDummyInst())
|
|
{
|
|
veh->GetDummyInst()->SetInstFlag(phInst::FLAG_NEVER_ACTIVATE, false);
|
|
|
|
if (veh->GetDummyInst()->IsInLevel())
|
|
{
|
|
CPhysics::GetLevel()->SetInstanceTypeAndIncludeFlags(veh->GetDummyInst()->GetLevelIndex(), 0, 0);
|
|
Vec3V vPos = veh->GetDummyInst()->GetPosition();
|
|
vPos.SetZf(-100.0f);
|
|
veh->GetDummyInst()->SetPosition(vPos);
|
|
if (CPhysics::GetLevel()->IsActive(veh->GetDummyInst()->GetLevelIndex()))
|
|
CPhysics::GetSimulator()->DeactivateObject(veh->GetDummyInst()->GetLevelIndex());
|
|
|
|
veh->RemoveConstraints(veh->GetDummyInst());
|
|
}
|
|
}
|
|
|
|
if (veh->GetVehicleFragInst())
|
|
{
|
|
veh->GetVehicleFragInst()->SetInstFlag(phInst::FLAG_NEVER_ACTIVATE, false);
|
|
|
|
if (veh->GetVehicleFragInst()->IsInLevel())
|
|
{
|
|
CPhysics::GetLevel()->SetInstanceTypeAndIncludeFlags(veh->GetVehicleFragInst()->GetLevelIndex(), 0, 0);
|
|
Vec3V vPos = veh->GetVehicleFragInst()->GetPosition();
|
|
vPos.SetZf(-100.0f);
|
|
veh->GetVehicleFragInst()->SetPosition(vPos);
|
|
if (CPhysics::GetLevel()->IsActive(veh->GetVehicleFragInst()->GetLevelIndex()))
|
|
CPhysics::GetSimulator()->DeactivateObject(veh->GetVehicleFragInst()->GetLevelIndex());
|
|
|
|
veh->RemoveConstraints(veh->GetFragInst());
|
|
}
|
|
}
|
|
|
|
veh->ClearAllKnownRefs();
|
|
|
|
ms_reuseDestroyedVehArray[firstFree].veh = veh;
|
|
ms_reuseDestroyedVehArray[firstFree].nukeTime = fwTimer::GetTimeInMilliseconds() + ms_reuseDestroyedVehCacheTime;
|
|
ms_reuseDestroyedVehArray[firstFree].framesUntilReuse = 5;
|
|
ms_reuseDestroyedVehCount++;
|
|
|
|
Assert(ms_reuseDestroyedVehArray[firstFree].veh);
|
|
|
|
#if __ASSERT
|
|
if(veh->InheritsFromAutomobile())
|
|
{
|
|
CAutomobile * pAuto = static_cast<CAutomobile*>(veh);
|
|
Assert(!pAuto->m_dummyStayOnRoadConstraintHandle.IsValid());
|
|
Assert(!pAuto->m_dummyRotationalConstraint.IsValid());
|
|
}
|
|
#endif
|
|
|
|
veh->PopTypeSet(POPTYPE_CACHE);
|
|
|
|
return;
|
|
}
|
|
|
|
// no space left, destroy vehicle
|
|
delete veh;
|
|
}
|
|
|
|
bool CVehicleFactory::IsVehInDestroyedCache(CVehicle* veh)
|
|
{
|
|
if (!veh)
|
|
return true;
|
|
|
|
for (s32 i = 0; i < MAX_DESTROYED_VEHS_CACHED; ++i)
|
|
{
|
|
if (ms_reuseDestroyedVehArray[i].veh && ms_reuseDestroyedVehArray[i].veh == veh)
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void CVehicleFactory::ClearDestroyedVehCache()
|
|
{
|
|
for (s32 i = 0; i < MAX_DESTROYED_VEHS_CACHED; ++i)
|
|
{
|
|
if (ms_reuseDestroyedVehArray[i].veh)
|
|
{
|
|
CVehicle* veh = ms_reuseDestroyedVehArray[i].veh;
|
|
ms_reuseDestroyedVehArray[i].veh = NULL;
|
|
veh->SetIsInPopulationCache(false);
|
|
|
|
// we can delete the vehicle like this because we've done all work of removing it from the world when it was added to this list
|
|
delete veh;
|
|
}
|
|
}
|
|
ms_reuseDestroyedVehCount = 0;
|
|
}
|
|
|
|
void CVehicleFactory::RemoveVehGroupFromCache(const CLoadedModelGroup& vehGroup)
|
|
{
|
|
const u32 numVehsInGroup = vehGroup.CountMembers();
|
|
if (!numVehsInGroup)
|
|
return;
|
|
|
|
for (s32 i = 0; i < MAX_DESTROYED_VEHS_CACHED; ++i)
|
|
{
|
|
for (s32 f = 0; f < numVehsInGroup; ++f)
|
|
{
|
|
u32 vehModelIndex = vehGroup.GetMember(f);
|
|
if (vehModelIndex == fwModelId::MI_INVALID)
|
|
continue;
|
|
|
|
if (ms_reuseDestroyedVehArray[i].veh && ms_reuseDestroyedVehArray[i].veh->GetModelIndex() == vehModelIndex)
|
|
{
|
|
CVehicle* veh = ms_reuseDestroyedVehArray[i].veh;
|
|
ms_reuseDestroyedVehArray[i].veh = NULL;
|
|
veh->SetIsInPopulationCache(false);
|
|
|
|
// we can delete the vehicle like this because we've done all work of removing it from the world when it was added to this list
|
|
delete veh;
|
|
ms_reuseDestroyedVehCount--;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void CVehicleFactory::ProcessDestroyedVehsCache()
|
|
{
|
|
u32 curTime = fwTimer::GetTimeInMilliseconds();
|
|
for (s32 i = 0; i < MAX_DESTROYED_VEHS_CACHED; ++i)
|
|
{
|
|
if (ms_reuseDestroyedVehArray[i].veh)
|
|
{
|
|
if (curTime >= ms_reuseDestroyedVehArray[i].nukeTime)
|
|
{
|
|
CVehicle* veh = ms_reuseDestroyedVehArray[i].veh;
|
|
ms_reuseDestroyedVehArray[i].veh = NULL;
|
|
veh->SetIsInPopulationCache(false);
|
|
|
|
// we can delete the vehicle like this because we've done all work of removing it from the world when it was added to this list
|
|
delete veh;
|
|
ms_reuseDestroyedVehCount--;
|
|
}
|
|
else
|
|
ms_reuseDestroyedVehArray[i].framesUntilReuse = (s8)rage::Max(0, ms_reuseDestroyedVehArray[i].framesUntilReuse - 1);
|
|
}
|
|
}
|
|
|
|
#if __BANK
|
|
if (ms_reuseDestroyedVehsDebugOutput)
|
|
{
|
|
u32 numCreatedCars = ms_numCachedCarsCreated + ms_numNonCachedCarsCreated;
|
|
float usage = (numCreatedCars > 0) ? (ms_numCachedCarsCreated / (float)numCreatedCars) : 0.f;
|
|
grcDebugDraw::AddDebugOutput("Cache usage: %.0f%% (cached %d - non cached %d)", usage * 100.f, ms_numCachedCarsCreated, ms_numNonCachedCarsCreated);
|
|
grcDebugDraw::AddDebugOutput("Cached destroyed vehs: %d", ms_reuseDestroyedVehCount);
|
|
u32 testCount = 0;
|
|
|
|
for (s32 i = 0; i < MAX_DESTROYED_VEHS_CACHED; ++i)
|
|
{
|
|
if (ms_reuseDestroyedVehArray[i].veh)
|
|
{
|
|
CVehicle* veh = ms_reuseDestroyedVehArray[i].veh;
|
|
grcDebugDraw::AddDebugOutput("Veh %2d - 0x%8x - %s - %d", testCount + 1, veh, veh->GetModelName(), (ms_reuseDestroyedVehArray[i].nukeTime - fwTimer::GetTimeInMilliseconds()) / 1000);
|
|
testCount++;
|
|
}
|
|
}
|
|
Assertf(testCount == ms_reuseDestroyedVehCount, "Reuse destroyed vehicle count is out of sync with array! (%d - %d)", testCount, ms_reuseDestroyedVehCount);
|
|
}
|
|
|
|
if (ms_resetCacheStats)
|
|
{
|
|
ms_numCachedCarsCreated = 0;
|
|
ms_numNonCachedCarsCreated = 0;
|
|
ms_resetCacheStats = false;
|
|
}
|
|
#endif
|
|
}
|
|
|
|
CVehicle* CVehicleFactory::CreateVehFromDestroyedCache(fwModelId modelId, const eEntityOwnedBy ownedBy, u32 popType, const Matrix34 *pMat, bool bCreateAsInactive)
|
|
{
|
|
// find a vehicle with the same model id in the cache
|
|
CVehicle* veh = NULL;
|
|
s32 cacheIndex = -1;
|
|
for (s32 i = 0; i < MAX_DESTROYED_VEHS_CACHED; ++i)
|
|
{
|
|
if (ms_reuseDestroyedVehArray[i].veh && ms_reuseDestroyedVehArray[i].veh->GetModelIndex() == modelId.GetModelIndex() && ms_reuseDestroyedVehArray[i].framesUntilReuse == 0)
|
|
{
|
|
veh = ms_reuseDestroyedVehArray[i].veh;
|
|
cacheIndex = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (!veh)
|
|
return NULL;
|
|
Assert(cacheIndex != -1);
|
|
|
|
#if __ASSERT
|
|
if (veh->HasAnExclusiveDriver())
|
|
{
|
|
aiAssertf(0, "Newly created vehicle %s didn't have it's exclusive driver cleared", veh->GetNetworkObject() ? veh->GetNetworkObject()->GetLogName() : veh->GetModelName());
|
|
}
|
|
#endif // __ASSERT
|
|
|
|
if (!aiVerifyf(veh->IsCollisionEnabled(), "Newly created vehicle %s doesn't have collision enabled from after reuse, force enabling collision", veh->GetNetworkObject() ? veh->GetNetworkObject()->GetLogName() : veh->GetModelName()))
|
|
{
|
|
veh->EnableCollision();
|
|
}
|
|
|
|
// set default values, as if ped was newly created by the factory
|
|
veh->SetOwnedBy(ownedBy);
|
|
veh->DelayedRemovalTimeReset();
|
|
|
|
veh->m_nVehicleFlags.bCreatedByFactory = true;
|
|
veh->m_nVehicleFlags.bInfluenceWantedLevel = true;
|
|
veh->m_nVehicleFlags.bCreatedByCarGen = false;
|
|
|
|
if (veh->GetDummyInst() && veh->GetDummyInst()->IsInLevel())
|
|
{
|
|
CPhysics::GetLevel()->SetInstanceTypeAndIncludeFlags(veh->GetDummyInst()->GetLevelIndex(), ArchetypeFlags::GTA_BOX_VEHICLE_TYPE, ArchetypeFlags::GTA_BOX_VEHICLE_INCLUDE_TYPES);
|
|
veh->SwitchCurrentPhysicsInst(veh->GetDummyInst());
|
|
//Assertf(!CPhysics::GetLevel()->IsActive(veh->GetDummyInst()->GetLevelIndex()), "Vehicle '%s' in cache has its dummy instance activated!", veh->GetModelName());
|
|
}
|
|
if (veh->GetVehicleFragInst() && veh->GetVehicleFragInst()->IsInLevel())
|
|
{
|
|
CPhysics::GetLevel()->SetInstanceTypeAndIncludeFlags(veh->GetVehicleFragInst()->GetLevelIndex(), ArchetypeFlags::GTA_VEHICLE_TYPE, ArchetypeFlags::GTA_VEHICLE_INCLUDE_TYPES);
|
|
veh->SwitchCurrentPhysicsInst(veh->GetVehicleFragInst());
|
|
//Assertf(!CPhysics::GetLevel()->IsActive(veh->GetVehicleFragInst()->GetLevelIndex()), "Vehicle '%s' in cache has its frag instance activated!", veh->GetModelName());
|
|
}
|
|
Assert(veh->GetCurrentPhysicsInst()->IsInLevel());
|
|
|
|
veh->SetIsInPopulationCache(false);
|
|
|
|
veh->Teleport(pMat->d, -10.0f, false, false);
|
|
if(pMat)
|
|
veh->SetMatrix(*pMat, true, true, true);
|
|
else
|
|
{
|
|
Matrix34 identity(Matrix34::IdentityType);
|
|
veh->SetMatrix(identity, true, true, true);
|
|
}
|
|
|
|
veh->m_nVehicleFlags.bCreatingAsInactive = bCreateAsInactive;
|
|
|
|
veh->m_TimeOfCreation = fwTimer::GetTimeInMilliseconds();
|
|
veh->m_CarGenThatCreatedUs = -1;
|
|
|
|
veh->CalculateInitialLightStateBasedOnClock();
|
|
|
|
veh->m_dummyConvertAttemptTimeMs = 0;
|
|
veh->m_realConvertAttemptTimeMs = 0;
|
|
veh->m_nRealVehicleIncludeFlags = 0;
|
|
//veh->m_NoHornCount = 0;
|
|
|
|
// intelligence
|
|
veh->GetIntelligence()->ResetVariables(fwTimer::GetTimeStep());
|
|
veh->GetIntelligence()->m_pCarThatIsBlockingUs = NULL;
|
|
veh->GetIntelligence()->LastTimeNotStuck = fwTimer::GetTimeInMilliseconds();
|
|
veh->GetIntelligence()->LastTimeHonkedAt = 0;
|
|
|
|
// Properly remove from any junction we might be in.
|
|
CVehicleIntelligence* pIntel = veh->GetIntelligence();
|
|
if(!pIntel->GetJunctionNode().IsEmpty())
|
|
{
|
|
CJunctions::RemoveVehicleFromJunction(veh, pIntel->GetJunctionNode());
|
|
}
|
|
pIntel->ResetCachedJunctionInfo();
|
|
|
|
veh->GetIntelligence()->InvalidateCachedNodeList();
|
|
veh->GetIntelligence()->InvalidateCachedFollowRoute();
|
|
veh->GetIntelligence()->MillisecondsNotMoving = 0;
|
|
veh->GetIntelligence()->m_fSmoothedSpeedSq = 0.0f;
|
|
veh->GetIntelligence()->DeleteScenarioPointHistory();
|
|
veh->GetIntelligence()->m_BackupFollowRoute.Invalidate();
|
|
veh->GetIntelligence()->m_nTimeLastTriedToShakePedFromRoof = 0;
|
|
veh->m_nVehicleFlags.bAvoidanceDirtyFlag = false;
|
|
veh->m_nVehicleFlags.SetSirenOn(false, false);
|
|
veh->m_nVehicleFlags.SetSirenMutedByScript(false);
|
|
veh->m_nVehicleFlags.bMadDriver = false;
|
|
veh->m_nVehicleFlags.bSlowChillinDriver = false;
|
|
veh->m_nVehicleFlags.bInMotionFromExplosion = false;
|
|
veh->m_nVehicleFlags.bIsAmbulanceOnDuty = false;
|
|
veh->m_nVehicleFlags.bIsFireTruckOnDuty = false;
|
|
veh->m_nVehicleFlags.bIsRacing = false;
|
|
veh->GetIntelligence()->SetPretendOccupantAggressivness(-1.0f);
|
|
veh->GetIntelligence()->SetPretendOccupantAbility(-1.0f);
|
|
veh->GetIntelligence()->SetCustomPathNodeStreamingRadius(-1.0f);
|
|
|
|
veh->GetPortalTracker()->Teleport();
|
|
veh->GetPortalTracker()->RequestRescanNextUpdate();
|
|
|
|
veh->PopTypeSet((ePopType)popType);
|
|
|
|
if (veh->IsDummy())
|
|
{
|
|
if(veh->InheritsFromTrailer())
|
|
{
|
|
// CTrailer::TryToMakeFromDummy fails because it expect to be converted from the parent vehicle's TryToMakeFromDummy. Just call directly here.
|
|
veh->CVehicle::TryToMakeFromDummy();
|
|
}
|
|
else
|
|
{
|
|
veh->TryToMakeFromDummy();
|
|
}
|
|
}
|
|
|
|
veh->Fix(false);
|
|
|
|
if(veh->GetVehicleAudioEntity())
|
|
{
|
|
veh->GetVehicleAudioEntity()->Init(veh);
|
|
}
|
|
|
|
// clear cache entry
|
|
ms_reuseDestroyedVehArray[cacheIndex].veh = NULL;
|
|
ms_reuseDestroyedVehCount--;
|
|
|
|
BANK_ONLY(veh->AssignDebugObjectID());
|
|
|
|
REPLAY_ONLY(CReplayMgr::OnCreateEntity(veh));
|
|
|
|
return veh;
|
|
}
|
|
|
|
void CVehicleFactory::SetFarDraw(CVehicle* pVehicle)
|
|
{
|
|
if (ms_bFarDrawVehicles)
|
|
{
|
|
if (!pVehicle->m_nVehicleFlags.bIsFarDrawEnabled)
|
|
{
|
|
pVehicle->SetLodDistance((u32)(2.0f * pVehicle->GetLodDistance())); // far draw doubles the fade distance
|
|
pVehicle->m_nVehicleFlags.bIsFarDrawEnabled = true;
|
|
}
|
|
} else {
|
|
if (pVehicle->m_nVehicleFlags.bIsFarDrawEnabled)
|
|
{
|
|
pVehicle->SetLodDistance((u32)(0.5f * pVehicle->GetLodDistance())); // reset fade distance to original value
|
|
pVehicle->m_nVehicleFlags.bIsFarDrawEnabled = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
void CVehicleFactory::SetFarDrawAllVehicles(bool val)
|
|
{
|
|
ms_bFarDrawVehicles = val;
|
|
|
|
CVehicle::Pool* pVehiclePool = CVehicle::GetPool();
|
|
Assert(pVehiclePool);
|
|
|
|
for(u32 i = 0; i<pVehiclePool->GetSize(); i++){
|
|
CVehicle* pVehicle = pVehiclePool->GetSlot(i);
|
|
if (pVehicle)
|
|
{
|
|
SetFarDraw(pVehicle);
|
|
}
|
|
}
|
|
|
|
}
|
|
|