| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653 |
- /*
- ** Command & Conquer Renegade(tm)
- ** Copyright 2025 Electronic Arts Inc.
- **
- ** This program is free software: you can redistribute it and/or modify
- ** it under the terms of the GNU General Public License as published by
- ** the Free Software Foundation, either version 3 of the License, or
- ** (at your option) any later version.
- **
- ** This program is distributed in the hope that it will be useful,
- ** but WITHOUT ANY WARRANTY; without even the implied warranty of
- ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ** GNU General Public License for more details.
- **
- ** You should have received a copy of the GNU General Public License
- ** along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
- /***********************************************************************************************
- *** Confidential - Westwood Studios ***
- ***********************************************************************************************
- * *
- * Project Name : Commando *
- * *
- * $Archive:: /Commando/Code/Combat/vehicle.cpp $*
- * *
- * $Author:: Byon_g $*
- * *
- * $Modtime:: 3/29/02 4:08p $*
- * *
- * $Revision:: 266 $*
- * *
- *---------------------------------------------------------------------------------------------*
- * Functions: *
- * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
- /*
- ** Includes
- */
- #include "vehicle.h"
- #include "animcontrol.h"
- #include "debug.h"
- #include "combat.h"
- #include "pscene.h"
- #include "assets.h"
- #include "rendobj.h"
- #include "soldier.h"
- #include "weapons.h"
- #include "damage.h"
- #include "wwpacket.h"
- #include "gameobjmanager.h"
- #include <stdio.h>
- #include "WWAudio.H"
- #include "Sound3D.H"
- #include "vehiclephys.h"
- #include "motorcycle.h"
- #include "trackedvehicle.h"
- #include "vtolvehicle.h"
- #include "wheelvehicle.h"
- #include "wheel.h"
- #include "phys3.h"
- #include "humanphys.h"
- #include "persistfactory.h"
- #include "combatchunkid.h"
- #include "simpledefinitionfactory.h"
- #include "wwhack.h"
- #include "explosion.h"
- #include "surfaceeffects.h"
- #include "bitpackids.h"
- #include "wwprofile.h"
- #include "playertype.h"
- #include "playerdata.h"
- #include "translatedb.h"
- #include "apppackettypes.h"
- #include "stealtheffect.h"
- #include "gametype.h"
- #include "globalsettings.h"
- #include "basecontroller.h"
- #include "string_ids.h"
- #include "specialbuilds.h"
- /*
- ** Local prototypes
- */
- static void Set_Subobject_Visibility (RenderObjClass *model, int bone_index, bool show);
- /*
- ** Defines
- */
- #define NORMALIZE_RADIANS( v ) while ( v > (float)DEG_TO_RAD( 180.0f ) ) v -= (float)DEG_TO_RAD( 360.0f ); \
- while ( v < (float)DEG_TO_RAD( -180.0f ) ) v += (float)DEG_TO_RAD( 360.0f );
- //
- // Class statics
- //
- bool VehicleGameObj::DefaultDriverIsGunner = false;
- bool VehicleGameObj::CameraLockedToTurret = false;
- /*
- ** Target Steering Option.
- ** (gth) 07/11/2001 - making this default to true
- ** (gth) 08/21/2001 - new default is false, user can turn it on with a console command...
- */
- bool _Use_Target_Steering = false;
- bool VehicleGameObj::Toggle_Target_Steering( void )
- {
- return _Use_Target_Steering = !_Use_Target_Steering;
- }
- void VehicleGameObj::Set_Target_Steering( bool onoff )
- {
- _Use_Target_Steering = onoff;
- return ;
- }
- bool VehicleGameObj::Is_Target_Steering( void )
- {
- return _Use_Target_Steering;
- }
- /*
- ** VehicleGameObjDef
- */
- DECLARE_FORCE_LINK( Vehicle )
- SimplePersistFactoryClass<VehicleGameObjDef, CHUNKID_GAME_OBJECT_DEF_VEHICLE> _VehicleGameObjDefPersistFactory;
- DECLARE_DEFINITION_FACTORY(VehicleGameObjDef, CLASSID_GAME_OBJECT_DEF_VEHICLE, "Vehicle") _VehicleGameObjDefDefFactory;
- VehicleGameObjDef::VehicleGameObjDef( void ) :
- Type( VEHICLE_TYPE_CAR ),
- TurnRadius( 10.0f ),
- OccupantsVisible( true ),
- EngineSoundMaxPitchFactor( 2.0F ),
- SightDownMuzzle( false ),
- Aim2D( true ),
- SquishVelocity( 1.5f ),
- VehicleNameID( 0 ),
- NumSeats( 2 ),
- GDIDamageReportID(0),
- NodDamageReportID(0),
- GDIDestroyReportID(0),
- NodDestroyReportID(0)
- {
- // initialize all engine sound defs to zero
- for (int i=0; i<MAX_ENGINE_SOUND_STATES; i++) {
- EngineSound[i] = 0;
- }
- MODEL_DEF_PARAM( VehicleGameObjDef, PhysDefID, "DynamicPhysDef" );
- EDITABLE_PARAM( VehicleGameObjDef, ParameterClass::TYPE_STRING, TypeName );
- EDITABLE_PARAM( VehicleGameObjDef, ParameterClass::TYPE_STRING, Fire0Anim );
- EDITABLE_PARAM( VehicleGameObjDef, ParameterClass::TYPE_STRING, Fire1Anim );
- EDITABLE_PARAM( VehicleGameObjDef, ParameterClass::TYPE_STRING, Profile );
- EDITABLE_PARAM( VehicleGameObjDef, ParameterClass::TYPE_FLOAT, TurnRadius );
- EDITABLE_PARAM( VehicleGameObjDef, ParameterClass::TYPE_FLOAT, SquishVelocity );
- EDITABLE_PARAM( VehicleGameObjDef, ParameterClass::TYPE_BOOL, Aim2D );
- #ifdef PARAM_EDITING_ON
- EnumParameterClass *param;
- param = new EnumParameterClass( (int*)&Type );
- param->Set_Name ("Type");
- param->Add_Value ( "Car", VEHICLE_TYPE_CAR );
- param->Add_Value ( "Tank", VEHICLE_TYPE_TANK );
- param->Add_Value ( "Bike", VEHICLE_TYPE_BIKE );
- param->Add_Value ( "Flying", VEHICLE_TYPE_FLYING );
- param->Add_Value ( "Turret", VEHICLE_TYPE_TURRET );
- GENERIC_EDITABLE_PARAM(VehicleGameObjDef,param)
- #endif
- EDITABLE_PARAM( VehicleGameObjDef, ParameterClass::TYPE_BOOL, OccupantsVisible );
- // engine sounds
- FLOAT_EDITABLE_PARAM(VehicleGameObjDef, EngineSoundMaxPitchFactor, 1.0F, 10.0F);
- NAMED_EDITABLE_PARAM(VehicleGameObjDef, ParameterClass::TYPE_SOUNDDEFINITIONID, EngineSound[ENGINE_SOUND_STATE_STARTING],"Engine Start Sound");
- NAMED_EDITABLE_PARAM(VehicleGameObjDef, ParameterClass::TYPE_SOUNDDEFINITIONID, EngineSound[ENGINE_SOUND_STATE_RUNNING],"Engine Running Loop");
- NAMED_EDITABLE_PARAM(VehicleGameObjDef, ParameterClass::TYPE_SOUNDDEFINITIONID, EngineSound[ENGINE_SOUND_STATE_STOPPING],"Engine Stop Sound");
- // NAMED_EDITABLE_PARAM(VehicleGameObjDef, ParameterClass::TYPE_SOUNDDEFINITIONID, EngineSound[ENGINE_SOUND_STATE_OFF],"Engine Off Sound");
- EDITABLE_PARAM( VehicleGameObjDef, ParameterClass::TYPE_BOOL, SightDownMuzzle );
- EDITABLE_PARAM( VehicleGameObjDef, ParameterClass::TYPE_STRINGSDB_ID, VehicleNameID );
- EDITABLE_PARAM( VehicleGameObjDef, ParameterClass::TYPE_INT, NumSeats );
- EDITABLE_PARAM(VehicleGameObjDef, ParameterClass::TYPE_STRINGSDB_ID, GDIDamageReportID);
- EDITABLE_PARAM(VehicleGameObjDef, ParameterClass::TYPE_STRINGSDB_ID, NodDamageReportID);
- EDITABLE_PARAM(VehicleGameObjDef, ParameterClass::TYPE_STRINGSDB_ID, GDIDestroyReportID);
- EDITABLE_PARAM(VehicleGameObjDef, ParameterClass::TYPE_STRINGSDB_ID, NodDestroyReportID);
- }
- VehicleGameObjDef::~VehicleGameObjDef( void )
- {
- Free_Transition_List();
- }
- uint32 VehicleGameObjDef::Get_Class_ID (void) const
- {
- return CLASSID_GAME_OBJECT_DEF_VEHICLE;
- }
- PersistClass * VehicleGameObjDef::Create( void ) const
- {
- VehicleGameObj * obj = new VehicleGameObj;
- obj->Init( *this );
- return obj;
- }
- enum {
- CHUNKID_DEF_PARENT = 930991656,
- CHUNKID_DEF_VARIABLES,
- CHUNKID_DEF_TRANSITION,
- MICROCHUNKID_TYPE = 1,
- MICROCHUNKID_TYPE_NAME,
- MICROCHUNKID_FIRE0ANIM,
- MICROCHUNKID_FIRE1ANIM,
- MICROCHUNKID_PROFILE,
- MICROCHUNKID_WEAPON_TURN_TRANS,
- XXXMICROCHUNKID_SOUND,
- MICROCHUNKID_EMITER_NAME,
- MICROCHUNKID_EMITER_OFFSET,
- MICROCHUNKID_EMITER2_NAME,
- MICROCHUNKID_EMITER2_OFFSET,
- XXX_MICROCHUNKID_MASS,
- XXX_MICROCHUNKID_MAX_ENGINE_TORQUE,
- XXX_MICROCHUNKID_STEERING_ANGLE,
- XXX_MICROCHUNKID_SPRING_CONSTANT,
- XXX_MICROCHUNKID_DAMPING_COEFFIENT,
- XXX_MICROCHUNKID_SPRING_LENGTH,
- MICROCHUNKID_PHYS_ID,
- MICROCHUNKID_TURN_RADIUS,
- MICROCHUNKID_OCCUPANTS_VISIBLE,
- XXX_MICROCHUNKID_ENGINE_SOUND_RPM_SCALE_MIN,
- XXX_MICROCHUNKID_ENGINE_SOUND_RPM_SCALE_MAX,
- MICROCHUNKID_ENGINE_START_SOUND,
- MICROCHUNKID_ENGINE_RUN_SOUND,
- MICROCHUNKID_ENGINE_STOP_SOUND,
- MICROCHUNKID_ENGINE_OFF_SOUND,
- MICROCHUNKID_DEF_SIGHT_DOWN_MUZZLE,
- MICROCHUNKID_DEF_AIM_2D,
- MICROCHUNKID_DEF_SQUISH_VELOCITY,
- MICROCHUNKID_ENGINE_SOUND_MAX_PITCH_FACTOR,
- MICROCHUNKID_DEF_VEHICLE_NAME_ID,
- MICROCHUNKID_DEF_NUM_SEATS,
- MICROCHUNKID_DEF_GDI_DAMAGE_REPORT_ID,
- MICROCHUNKID_DEF_NOD_DAMAGE_REPORT_ID,
- MICROCHUNKID_DEF_GDI_DESTROY_REPORT_ID,
- MICROCHUNKID_DEF_NOD_DESTROY_REPORT_ID,
- };
- bool VehicleGameObjDef::Save( ChunkSaveClass & csave )
- {
- csave.Begin_Chunk( CHUNKID_DEF_PARENT );
- SmartGameObjDef::Save( csave );
- csave.End_Chunk();
- csave.Begin_Chunk( CHUNKID_DEF_VARIABLES );
- WRITE_MICRO_CHUNK( csave, MICROCHUNKID_TYPE, Type );
- WRITE_MICRO_CHUNK_WWSTRING( csave, MICROCHUNKID_TYPE_NAME, TypeName );
- WRITE_MICRO_CHUNK_WWSTRING( csave, MICROCHUNKID_FIRE0ANIM, Fire0Anim );
- WRITE_MICRO_CHUNK_WWSTRING( csave, MICROCHUNKID_FIRE1ANIM, Fire1Anim );
- WRITE_MICRO_CHUNK_WWSTRING( csave, MICROCHUNKID_PROFILE, Profile );
- WRITE_MICRO_CHUNK( csave, MICROCHUNKID_TURN_RADIUS, TurnRadius );
- WRITE_MICRO_CHUNK( csave, MICROCHUNKID_OCCUPANTS_VISIBLE, OccupantsVisible );
- WRITE_MICRO_CHUNK( csave, MICROCHUNKID_ENGINE_SOUND_MAX_PITCH_FACTOR, EngineSoundMaxPitchFactor );
- WRITE_MICRO_CHUNK( csave, MICROCHUNKID_ENGINE_START_SOUND, EngineSound[ENGINE_SOUND_STATE_STARTING] );
- WRITE_MICRO_CHUNK( csave, MICROCHUNKID_ENGINE_RUN_SOUND, EngineSound[ENGINE_SOUND_STATE_RUNNING] );
- WRITE_MICRO_CHUNK( csave, MICROCHUNKID_ENGINE_STOP_SOUND, EngineSound[ENGINE_SOUND_STATE_STOPPING] );
- WRITE_MICRO_CHUNK( csave, MICROCHUNKID_ENGINE_OFF_SOUND, EngineSound[ENGINE_SOUND_STATE_OFF] );
- WRITE_MICRO_CHUNK( csave, MICROCHUNKID_DEF_SIGHT_DOWN_MUZZLE, SightDownMuzzle );
- WRITE_MICRO_CHUNK( csave, MICROCHUNKID_DEF_AIM_2D, Aim2D );
- WRITE_MICRO_CHUNK( csave, MICROCHUNKID_DEF_SQUISH_VELOCITY, SquishVelocity );
- WRITE_MICRO_CHUNK( csave, MICROCHUNKID_DEF_VEHICLE_NAME_ID, VehicleNameID );
- WRITE_MICRO_CHUNK( csave, MICROCHUNKID_DEF_NUM_SEATS, NumSeats );
- WRITE_MICRO_CHUNK( csave, MICROCHUNKID_DEF_GDI_DAMAGE_REPORT_ID, GDIDamageReportID );
- WRITE_MICRO_CHUNK( csave, MICROCHUNKID_DEF_NOD_DAMAGE_REPORT_ID, NodDamageReportID );
- WRITE_MICRO_CHUNK( csave, MICROCHUNKID_DEF_GDI_DESTROY_REPORT_ID, GDIDestroyReportID );
- WRITE_MICRO_CHUNK( csave, MICROCHUNKID_DEF_NOD_DESTROY_REPORT_ID, NodDestroyReportID );
- csave.End_Chunk();
- // Save each of the transition 'definitions' in our list.
- for( int index = 0; index < Transitions.Count (); index ++ ) {
- TransitionDataClass *transition = Transitions[index];
- if( transition != NULL ) {
- // Save this transition 'defintion' to its own chunk.
- csave.Begin_Chunk( CHUNKID_DEF_TRANSITION );
- transition->Save( csave );
- csave.End_Chunk();
- }
- }
- return true;
- }
- bool VehicleGameObjDef::Load( ChunkLoadClass &cload )
- {
- Free_Transition_List ();
- while (cload.Open_Chunk()) {
- switch(cload.Cur_Chunk_ID()) {
- case CHUNKID_DEF_PARENT:
- SmartGameObjDef::Load( cload );
- break;
- case CHUNKID_DEF_TRANSITION:
- {
- TransitionDataClass *transition = new TransitionDataClass;
- transition->Load( cload );
- Transitions.Add( transition );
- }
- break;
- case CHUNKID_DEF_VARIABLES:
- while (cload.Open_Micro_Chunk()) {
- switch(cload.Cur_Micro_Chunk_ID()) {
- READ_MICRO_CHUNK( cload, MICROCHUNKID_TYPE, Type );
- READ_MICRO_CHUNK_WWSTRING( cload, MICROCHUNKID_TYPE_NAME, TypeName );
- READ_MICRO_CHUNK_WWSTRING( cload, MICROCHUNKID_FIRE0ANIM, Fire0Anim );
- READ_MICRO_CHUNK_WWSTRING( cload, MICROCHUNKID_FIRE1ANIM, Fire1Anim );
- READ_MICRO_CHUNK_WWSTRING( cload, MICROCHUNKID_PROFILE, Profile );
- READ_MICRO_CHUNK( cload, MICROCHUNKID_PHYS_ID, PhysDefID );
- READ_MICRO_CHUNK( cload, MICROCHUNKID_TURN_RADIUS, TurnRadius );
- READ_MICRO_CHUNK( cload, MICROCHUNKID_OCCUPANTS_VISIBLE, OccupantsVisible );
- READ_MICRO_CHUNK( cload, MICROCHUNKID_ENGINE_SOUND_MAX_PITCH_FACTOR, EngineSoundMaxPitchFactor);
- READ_MICRO_CHUNK( cload, MICROCHUNKID_ENGINE_START_SOUND, EngineSound[ENGINE_SOUND_STATE_STARTING] );
- READ_MICRO_CHUNK( cload, MICROCHUNKID_ENGINE_RUN_SOUND, EngineSound[ENGINE_SOUND_STATE_RUNNING] );
- READ_MICRO_CHUNK( cload, MICROCHUNKID_ENGINE_STOP_SOUND, EngineSound[ENGINE_SOUND_STATE_STOPPING] );
- READ_MICRO_CHUNK( cload, MICROCHUNKID_ENGINE_OFF_SOUND, EngineSound[ENGINE_SOUND_STATE_OFF] );
- READ_MICRO_CHUNK( cload, MICROCHUNKID_DEF_SIGHT_DOWN_MUZZLE, SightDownMuzzle );
- READ_MICRO_CHUNK( cload, MICROCHUNKID_DEF_AIM_2D, Aim2D );
- READ_MICRO_CHUNK( cload, MICROCHUNKID_DEF_SQUISH_VELOCITY, SquishVelocity );
- READ_MICRO_CHUNK( cload, MICROCHUNKID_DEF_VEHICLE_NAME_ID, VehicleNameID );
- READ_MICRO_CHUNK( cload, MICROCHUNKID_DEF_NUM_SEATS, NumSeats );
- READ_MICRO_CHUNK( cload, MICROCHUNKID_DEF_GDI_DAMAGE_REPORT_ID, GDIDamageReportID );
- READ_MICRO_CHUNK( cload, MICROCHUNKID_DEF_NOD_DAMAGE_REPORT_ID, NodDamageReportID );
- READ_MICRO_CHUNK( cload, MICROCHUNKID_DEF_GDI_DESTROY_REPORT_ID, GDIDestroyReportID );
- READ_MICRO_CHUNK( cload, MICROCHUNKID_DEF_NOD_DESTROY_REPORT_ID, NodDestroyReportID );
- default:
- Debug_Say(( "Unrecognized VehicleDef Variable chunkID\n" ));
- break;
- }
- cload.Close_Micro_Chunk();
- }
- break;
- default:
- Debug_Say(( "Unrecognized VehicleDef chunkID\n" ));
- break;
- }
- cload.Close_Chunk();
- }
- return true;
- }
- /*
- **
- */
- void VehicleGameObjDef::Free_Transition_List( void )
- {
- // Delete each of the transition 'definitions' in our list.
- for( int index = 0; index < Transitions.Count (); index ++ ) {
- TransitionDataClass *transition = Transitions[index];
- if( transition != NULL ) {
- delete transition;
- }
- }
- Transitions.Delete_All();
- return ;
- }
- const PersistFactoryClass & VehicleGameObjDef::Get_Factory (void) const
- {
- return _VehicleGameObjDefPersistFactory;
- }
- int VehicleGameObjDef::Get_Damage_Report(int team) const
- {
- if (PLAYERTYPE_GDI == team) {
- return GDIDamageReportID;
- } else if (PLAYERTYPE_NOD == team) {
- return NodDamageReportID;
- }
- return 0;
- }
- int VehicleGameObjDef::Get_Destroy_Report(int team) const
- {
- if (PLAYERTYPE_GDI == team) {
- return GDIDestroyReportID;
- } else if (PLAYERTYPE_NOD == team) {
- return NodDestroyReportID;
- }
- return 0;
- }
- /*
- ** VehicleGameObj
- */
- SimplePersistFactoryClass<VehicleGameObj, CHUNKID_GAME_OBJECT_VEHICLE> _VehicleGameObjPersistFactory;
- const PersistFactoryClass & VehicleGameObj::Get_Factory (void) const
- {
- return _VehicleGameObjPersistFactory;
- }
- VehicleGameObj::VehicleGameObj() :
- TurretBone( 0 ),
- BarrelBone( 0 ),
- TurretTurn( 0 ),
- BarrelTilt( 0 ),
- BarrelOffset( 0 ),
- Sound( NULL ),
- EngineSoundState( ENGINE_SOUND_STATE_OFF ),
- CachedEngineSound( NULL ),
- WheelSurfaceSound(NULL),
- TransitionsEnabled( true ),
- OccupiedSeats( 0 ),
- HasEnterTransitions( false ),
- HasExitTransitions( false ),
- VehicleDelivered(false),
- LockTimer( 0 )
- {
- DriverIsGunner = DefaultDriverIsGunner;
- Set_App_Packet_Type(APPPACKETTYPE_VEHICLE);
- }
- VehicleGameObj::~VehicleGameObj()
- {
- if ( Peek_Physical_Object() != NULL && COMBAT_SCENE != NULL) {
- // Make sure the exiters don't hit me
- Peek_Physical_Object()->Set_Collision_Group( UNCOLLIDEABLE_GROUP );
- // Eject all the occupants around the vehicle so they don't intersect
- Vector3 vehicle_pos;
- Peek_Physical_Object()->Get_Position( &vehicle_pos );
- for ( int i = 0; i < SeatOccupants.Length(); i++ ) {
- if ( SeatOccupants[i] != NULL ) {
- SeatOccupants[i]->Exit_Destroyed_Vehicle( i, vehicle_pos );
- }
- SeatOccupants[i] = NULL;
- }
- } else {
- for ( int i = 0; i < SeatOccupants.Length(); i++ ) {
- if ( SeatOccupants[i] != NULL ) {
- SeatOccupants[i]->Exit_Vehicle();
- }
- SeatOccupants[i] = NULL;
- }
- }
- Destroy_Transitions();
- if (Sound) {
- Sound->Remove_From_Scene ();
- Sound->Release_Ref ();
- Sound = NULL;
- }
- if (CachedEngineSound) {
- CachedEngineSound->Remove_From_Scene();
- REF_PTR_RELEASE(CachedEngineSound);
- }
- Release_Turret_Bones();
- Shutdown_Wheel_Effects();
- }
- /*
- **
- */
- void VehicleGameObj::Init( void )
- {
- DriverIsGunner = DefaultDriverIsGunner;
- // Vehicles are too complex to re-init
- // Init( Get_Definition() );
- }
- void VehicleGameObj::Init( const VehicleGameObjDef & definition )
- {
- DriverIsGunner = DefaultDriverIsGunner;
- SmartGameObj::Init( definition );
- SeatOccupants.Resize(definition.NumSeats);
- for ( int i = 0; i < SeatOccupants.Length(); i++ ) {
- SeatOccupants[i] = NULL;
- }
- Aquire_Turret_Bones();
- Init_Wheel_Effects();
- Create_And_Destroy_Transitions();
- Update_Damage_Meshes();
- //
- // Refine the app packet type if this is a turret
- //
- if (Get_Definition().Type == VEHICLE_TYPE_TURRET)
- {
- Set_App_Packet_Type(APPPACKETTYPE_TURRET);
- }
- //WWDEBUG_SAY((">> VehicleGameObj::Init, Type = %d\n", Get_Definition().Type));
- }
- const VehicleGameObjDef & VehicleGameObj::Get_Definition( void ) const
- {
- return (const VehicleGameObjDef &)BaseGameObj::Get_Definition();
- }
- /*
- ** VehicleGameObj Save and Load
- */
- enum {
- CHUNKID_PARENT = 923991632,
- CHUNKID_VARIABLES,
- XXXCHUNKID_ANIM_CONTROL,
- XXXCHUNKID_TRANSITION_LIST_OLD,
- CHUNKID_SEAT_LIST,
- MICROCHUNKID_TURRET_BONE = 1,
- MICROCHUNKID_BARREL_BONE,
- XXXMICROCHUNKID_PHYSICAL_OBJECT,
- MICROCHUNKID_TRANSITION_LIST_ENTRY_OLD,
- MICROCHUNKID_TURRET_TURN,
- MICROCHUNKID_BARREL_TILT,
- MICROCHUNKID_TRANSITIONS_ENABLED,
- MICROCHUNKID_OCCUPIED_SEATS,
- MICROCHUNKID_NUM_SEATS,
- };
- bool VehicleGameObj::Save( ChunkSaveClass & csave )
- {
- // Destroy the transitions, because we don't save them, and don't
- // want to have the vehicle have a un-matched reference to them.
- // Re-create at the end of save
- Destroy_Transitions();
- csave.Begin_Chunk( CHUNKID_PARENT );
- SmartGameObj::Save( csave );
- csave.End_Chunk();
- csave.Begin_Chunk( CHUNKID_VARIABLES );
- WRITE_MICRO_CHUNK( csave, MICROCHUNKID_TURRET_TURN, TurretTurn );
- WRITE_MICRO_CHUNK( csave, MICROCHUNKID_BARREL_TILT, BarrelTilt );
- WRITE_MICRO_CHUNK( csave, MICROCHUNKID_TRANSITIONS_ENABLED, TransitionsEnabled );
- WRITE_MICRO_CHUNK( csave, MICROCHUNKID_OCCUPIED_SEATS, OccupiedSeats );
- int num_seats = SeatOccupants.Length();
- WRITE_MICRO_CHUNK( csave, MICROCHUNKID_NUM_SEATS, num_seats );
- csave.End_Chunk();
- if ( num_seats != 0 ) {
- csave.Begin_Chunk( CHUNKID_SEAT_LIST );
- csave.Write( &SeatOccupants[0], num_seats * sizeof( SeatOccupants[0] ) );
- csave.End_Chunk();
- }
- Create_And_Destroy_Transitions();
- return true;
- }
- bool VehicleGameObj::Load( ChunkLoadClass &cload )
- {
- int num_seats = 0;
- while (cload.Open_Chunk()) {
- switch(cload.Cur_Chunk_ID()) {
- case CHUNKID_PARENT:
- SmartGameObj::Load( cload );
- break;
- case CHUNKID_VARIABLES:
- {
- while (cload.Open_Micro_Chunk()) {
- switch(cload.Cur_Micro_Chunk_ID()) {
- READ_MICRO_CHUNK( cload, MICROCHUNKID_TURRET_TURN, TurretTurn );
- READ_MICRO_CHUNK( cload, MICROCHUNKID_BARREL_TILT, BarrelTilt );
- READ_MICRO_CHUNK( cload, MICROCHUNKID_TRANSITIONS_ENABLED, TransitionsEnabled );
- READ_MICRO_CHUNK( cload, MICROCHUNKID_OCCUPIED_SEATS, OccupiedSeats );
- READ_MICRO_CHUNK( cload, MICROCHUNKID_NUM_SEATS, num_seats );
- default:
- Debug_Say(( "Unrecognized Vehicle Variable chunkID\n" ));
- break;
- }
- cload.Close_Micro_Chunk();
- }
- break;
- }
- case CHUNKID_SEAT_LIST:
- {
- if ( (num_seats == 0) || (num_seats != Get_Definition().NumSeats)) {
- SeatOccupants.Resize(Get_Definition().NumSeats);
- for ( int i = 0; i < SeatOccupants.Length(); i++ ) {
- SeatOccupants[i] = NULL;
- }
- break; // May be legacy
- }
- SeatOccupants.Resize( num_seats );
- cload.Read( &SeatOccupants[0], num_seats * sizeof( SeatOccupants[0] ) );
- for ( int i = 0; i < num_seats; i++ ) {
- if ( SeatOccupants[i] != NULL ) {
- REQUEST_POINTER_REMAP( (void **)&SeatOccupants[i] );
- }
- }
- break;
- }
- default:
- Debug_Say(( "Unrecognized Vehicle chunkID\n" ));
- break;
- }
- cload.Close_Chunk();
- }
- SaveLoadSystemClass::Register_Post_Load_Callback(this);
- return true;
- }
- void VehicleGameObj::On_Post_Load( void )
- {
- DriverIsGunner = DefaultDriverIsGunner;
- Init_Wheel_Effects();
- Aquire_Turret_Bones();
- SmartGameObj::On_Post_Load();
- Create_And_Destroy_Transitions();
- Update_Damage_Meshes();
- // For some reason??? some vehicles come in with an anim control, but no model in the anim control.
- if ( Get_Anim_Control() != NULL && Get_Anim_Control()->Peek_Model() == NULL ) {
- Get_Anim_Control()->Set_Model( Peek_Model() );
- }
- //
- // Refine the app packet type if this is a turret
- //
- if (Get_Definition().Type == VEHICLE_TYPE_TURRET)
- {
- Set_App_Packet_Type(APPPACKETTYPE_TURRET);
- }
- }
- #if 0
- void VehicleGameObj::Create_Transitions( void )
- {
- Destroy_Transitions();
- WWASSERT( TransitionInstances.Count() == 0 );
- const TRANSITION_DATA_LIST & trans_data_list = Get_Definition().Get_Transition_List();
- if ( trans_data_list.Count() != 0 ) { // new style
- if ( Seats[0] == NULL ) {
- Create_New_Transitions( TransitionDataClass::VEHICLE_ENTER_0 );
- } else {
- Create_New_Transitions( TransitionDataClass::VEHICLE_EXIT_0 );
- }
- if ( Seats[1] == NULL ) {
- Create_New_Transitions( TransitionDataClass::VEHICLE_ENTER_1 );
- } else {
- Create_New_Transitions( TransitionDataClass::VEHICLE_EXIT_1 );
- }
- }
- }
- #endif
- void VehicleGameObj::Destroy_Transitions( void )
- {
- HasEnterTransitions = false;
- HasExitTransitions = false;
- while ( TransitionInstances.Count() ) {
- TransitionManager::Destroy( TransitionInstances[0] );
- TransitionInstances.Delete( 0 );
- }
- // They get put in a list, so flush the list.
- TransitionManager::Destroy_Pending();
- }
- void VehicleGameObj::Create_And_Destroy_Transitions( void )
- {
- // Manage the enter transitions
- bool should_have_enter_transitions = (OccupiedSeats < Get_Definition().NumSeats) && TransitionsEnabled;
- if ( should_have_enter_transitions != HasEnterTransitions ) {
- if ( should_have_enter_transitions ) {
- Create_New_Transitions( TransitionDataClass::VEHICLE_ENTER );
- HasEnterTransitions = true;
- } else {
- Remove_Transitions( TransitionDataClass::VEHICLE_ENTER );
- HasEnterTransitions = false;
- }
- }
- // Manage the exit transitions
- bool should_have_exit_transitions = (OccupiedSeats > 0) && TransitionsEnabled;
- if ( should_have_exit_transitions != HasExitTransitions ) {
- if ( should_have_exit_transitions ) {
- Create_New_Transitions( TransitionDataClass::VEHICLE_EXIT );
- HasExitTransitions = true;
- } else {
- Remove_Transitions( TransitionDataClass::VEHICLE_EXIT );
- HasExitTransitions = false;
- }
- }
- }
- /*
- **
- */
- void VehicleGameObj::Aquire_Turret_Bones( void )
- {
- if ( TurretBone == 0 ) {
- TurretBone = Peek_Model()->Get_Bone_Index( "turret" );
- if ( TurretBone != 0 ) {
- Peek_Model()->Capture_Bone( TurretBone );
- if ( !Peek_Model()->Is_Bone_Captured( TurretBone ) ) {
- Debug_Say(( "VehicleGameObj::Aquire_Bones() : Turret Bone not captured for model %s\n",
- Peek_Model()->Get_Name()));
- TurretBone = 0;
- }
- }
- }
- BarrelOffset = 0;
- if ( BarrelBone == 0 ) {
- BarrelBone = Peek_Model()->Get_Bone_Index( "barrel" );
- if ( BarrelBone != 0 ) {
- Peek_Model()->Capture_Bone( BarrelBone );
- if ( !Peek_Model()->Is_Bone_Captured( BarrelBone ) ) {
- BarrelBone = 0;
- Debug_Say(( "VehicleGameObj::Aquire_Bones() : Barrel Bone not captured for model %s\n",
- Peek_Model()->Get_Name()));
- }
- }
- // find the barrel in turret space
- if ( TurretBone != 0 ) {
- Matrix3D turret_base = Peek_Model()->Get_Bone_Transform( TurretBone );
- Vector3 barrel_pos = Peek_Model()->Get_Bone_Transform( BarrelBone ).Get_Translation();
- Vector3 turret_space_barrel;
- Matrix3D::Inverse_Transform_Vector( turret_base, barrel_pos, &turret_space_barrel );
- BarrelOffset = turret_space_barrel.Y;
- if ( WWMath::Fabs( BarrelOffset ) < 0.1f ) {
- BarrelOffset = 0;
- }
- }
- }
- }
- void VehicleGameObj::Release_Turret_Bones( void )
- {
- if ( Peek_Model() ) {
- if ( TurretBone != 0 ) {
- if ( Peek_Model()->Is_Bone_Captured( TurretBone ) ) {
- Peek_Model()->Release_Bone( TurretBone );
- TurretBone = 0;
- }
- }
- if ( BarrelBone != 0 ) {
- if ( Peek_Model()->Is_Bone_Captured( BarrelBone ) ) {
- Peek_Model()->Release_Bone( BarrelBone );
- BarrelBone = 0;
- }
- }
- }
- BarrelOffset = 0;
- }
- void VehicleGameObj::Export_Creation( BitStreamClass &packet )
- {
- SmartGameObj::Export_Creation( packet );
- //
- // Send the lock status to the client
- //
- int lock_owner_id = 0;
- if (LockOwner != NULL) {
- lock_owner_id = LockOwner.Get_Ptr ()->Get_ID ();
- }
- packet.Add(lock_owner_id);
- if (lock_owner_id != 0) {
- packet.Add(LockTimer,BITPACK_VEHICLE_LOCK_TIMER);
- }
- return ;
- }
- void VehicleGameObj::Import_Creation( BitStreamClass &packet )
- {
- SmartGameObj::Import_Creation( packet );
- //
- // Get the lock status from the server
- //
- int lock_owner_id;
- packet.Get(lock_owner_id);
- if (lock_owner_id != 0) {
- LockOwner = GameObjManager::Find_PhysicalGameObj( lock_owner_id );
- packet.Get(LockTimer,BITPACK_VEHICLE_LOCK_TIMER);
- }
- return ;
- }
- void VehicleGameObj::Export_Rare( BitStreamClass &packet )
- {
- SmartGameObj::Export_Rare( packet );
- //
- // Export the seat occupants
- //
- for (int i = 0; i < SeatOccupants.Length(); i++) {
- if (SeatOccupants[i] == NULL) {
- const int NO_OCCUPANTS = -1;
- packet.Add(NO_OCCUPANTS);
- } else {
- packet.Add(SeatOccupants[i]->Get_ID());
- }
- }
- packet.Add(VehicleDelivered);
- }
- void VehicleGameObj::Import_Rare( BitStreamClass &packet )
- {
- WWASSERT(CombatManager::I_Am_Only_Client());
- SmartGameObj::Import_Rare( packet );
- //
- // Update the seat occupants
- //
- for (int i = 0; i < SeatOccupants.Length(); i++) {
- int occupant = packet.Get(occupant);
- if (occupant == -1) {
- //
- // Remove the occupant from the seat
- //
- if (SeatOccupants[i] != NULL) {
- Remove_Occupant (SeatOccupants[i]);
- }
- } else {
- if ((SeatOccupants[i] == NULL) || (SeatOccupants[i]->Get_ID() != occupant)) {
- SmartGameObj * obj = GameObjManager::Find_SmartGameObj(occupant);
- if (SeatOccupants[i] != NULL) {
- Remove_Occupant (SeatOccupants[i]);
- }
- if (obj != NULL) {
- //
- // Add the occupant to the seat
- //
- if (SeatOccupants[i] == NULL) {
- Add_Occupant (obj->As_SoldierGameObj(), i);
- }
- }
- }
- }
- }
- bool wasDelivered = VehicleDelivered;
- packet.Get(VehicleDelivered);
- if (!wasDelivered && VehicleDelivered) {
- BaseControllerClass* base = BaseControllerClass::Find_Base(Get_Player_Type());
- if (base) {
- base->On_Vehicle_Delivered(this);
- }
- }
- }
- //-----------------------------------------------------------------------------
- /*
- **
- */
- void VehicleGameObj::Import_Frequent(BitStreamClass & packet)
- {
- /*
- if (Get_Definition().Type == VEHICLE_TYPE_TURRET) {
- WWDEBUG_SAY(("VEHICLE_TYPE_TURRET::Import_Frequent: %s, %d, %d\n",
- Get_Definition().Get_Name(),
- Get_Definition().NumSeats,
- SeatOccupants.Length()));
- }
- */
- WWASSERT(CombatManager::I_Am_Only_Client());
- int rounds = packet.Get(rounds);
- if (Get_Weapon() != NULL) {
- Get_Weapon()->Set_Total_Rounds(rounds);
- }
- switch(Get_Definition().Type) {
- case VEHICLE_TYPE_BIKE:
- case VEHICLE_TYPE_CAR:
- case VEHICLE_TYPE_TANK:
- case VEHICLE_TYPE_FLYING:
- {
- VehiclePhysClass * p_obj = Peek_Vehicle_Phys();
- if (p_obj != NULL) {
- Vector3 sc_position;
- Quaternion q;
- Vector3 vel;
- Vector3 ang_vel;
- bool is_engine_on;
- packet.Get(is_engine_on);
- packet.Get(sc_position.X, BITPACK_WORLD_POSITION_X);
- packet.Get(sc_position.Y, BITPACK_WORLD_POSITION_Y);
- packet.Get(sc_position.Z, BITPACK_WORLD_POSITION_Z);
- packet.Get(q.X, BITPACK_VEHICLE_QUATERNION);
- packet.Get(q.Y, BITPACK_VEHICLE_QUATERNION);
- packet.Get(q.Z, BITPACK_VEHICLE_QUATERNION);
- packet.Get(q.W, BITPACK_VEHICLE_QUATERNION);
- q.Normalize();
- #ifdef MULTIPLAYERDEMO
- //
- // Mix up the packet order to make demo/non-demo code more incompatible.
- //
- packet.Get(vel.Y, BITPACK_VEHICLE_VELOCITY);
- packet.Get(vel.Z, BITPACK_VEHICLE_VELOCITY);
- packet.Get(vel.X, BITPACK_VEHICLE_VELOCITY);
- #else
- packet.Get(vel.X, BITPACK_VEHICLE_VELOCITY);
- packet.Get(vel.Y, BITPACK_VEHICLE_VELOCITY);
- packet.Get(vel.Z, BITPACK_VEHICLE_VELOCITY);
- #endif
-
- packet.Get(ang_vel.X, BITPACK_VEHICLE_ANGULAR_VELOCITY);
- packet.Get(ang_vel.Y, BITPACK_VEHICLE_ANGULAR_VELOCITY);
- packet.Get(ang_vel.Z, BITPACK_VEHICLE_ANGULAR_VELOCITY);
- if (COMBAT_STAR && (COMBAT_STAR->Get_Vehicle() == this)) {
- p_obj->Network_Latency_State_Update( sc_position,
- q,
- vel,
- ang_vel);
- } else {
- p_obj->Network_Interpolate_State_Update( sc_position,
- q,
- vel,
- ang_vel,
- 0.1f );
- }
- p_obj->Enable_Engine(is_engine_on);
- }
- break;
- }
- case VEHICLE_TYPE_TURRET:
- //WWDEBUG_SAY(("turret read %d\n", packet.Get_Bit_Write_Position()));
- break;
- default:
- WWASSERT( 0 );
- break;
- }
- packet.Get( DriverIsGunner );
- SmartGameObj::Import_Frequent(packet);
- WWASSERT(packet.Is_Flushed());
- }
- //-----------------------------------------------------------------------------
- void VehicleGameObj::Export_Frequent(BitStreamClass & packet)
- {
- Apply_Control(); // Make sure we have our drivers controls
- /*
- if (Get_Definition().Type == VEHICLE_TYPE_TURRET) {
- WWDEBUG_SAY(("VEHICLE_TYPE_TURRET::Export_Frequent: %s, %d, %d\n",
- Get_Definition().Get_Name(),
- Get_Definition().NumSeats,
- SeatOccupants.Length()));
- }
- */
- //
- // Vehicles never change their weapon type
- //
- int total_rounds = 0;
- if (Get_Weapon() != NULL) {
- total_rounds = Get_Weapon()->Get_Total_Rounds();
- }
- packet.Add(total_rounds);
- switch(Get_Definition().Type) {
- case VEHICLE_TYPE_BIKE:
- case VEHICLE_TYPE_TANK:
- case VEHICLE_TYPE_CAR:
- case VEHICLE_TYPE_FLYING:
- {
- VehiclePhysClass * p_obj = Peek_Vehicle_Phys();
- if (p_obj != NULL) {
- Vector3 pos;
- Quaternion q;
- Vector3 vel;
- Vector3 ang_vel;
- bool is_engine_on;
- p_obj->Get_Position(&pos);
- p_obj->Get_Orientation(&q);
- p_obj->Get_Velocity(&vel);
- p_obj->Get_Angular_Velocity(&ang_vel);
- is_engine_on = p_obj->Is_Engine_Enabled();
- packet.Add(is_engine_on);
- packet.Add(pos.X, BITPACK_WORLD_POSITION_X);
- packet.Add(pos.Y, BITPACK_WORLD_POSITION_Y);
- packet.Add(pos.Z, BITPACK_WORLD_POSITION_Z);
- packet.Add(q.X, BITPACK_VEHICLE_QUATERNION);
- packet.Add(q.Y, BITPACK_VEHICLE_QUATERNION);
- packet.Add(q.Z, BITPACK_VEHICLE_QUATERNION);
- packet.Add(q.W, BITPACK_VEHICLE_QUATERNION);
- #ifdef MULTIPLAYERDEMO
- //
- // Mix up the packet order to make demo/non-demo code more incompatible.
- //
- packet.Add(vel.Y, BITPACK_VEHICLE_VELOCITY);
- packet.Add(vel.Z, BITPACK_VEHICLE_VELOCITY);
- packet.Add(vel.X, BITPACK_VEHICLE_VELOCITY);
- #else
- packet.Add(vel.X, BITPACK_VEHICLE_VELOCITY);
- packet.Add(vel.Y, BITPACK_VEHICLE_VELOCITY);
- packet.Add(vel.Z, BITPACK_VEHICLE_VELOCITY);
- #endif
- packet.Add(ang_vel.X, BITPACK_VEHICLE_ANGULAR_VELOCITY);
- packet.Add(ang_vel.Y, BITPACK_VEHICLE_ANGULAR_VELOCITY);
- packet.Add(ang_vel.Z, BITPACK_VEHICLE_ANGULAR_VELOCITY);
- }
- break;
- }
- case VEHICLE_TYPE_TURRET:
- //WWDEBUG_SAY(("turret write %d\n", packet.Get_Bit_Write_Position()));
- break;
- default:
- WWASSERT(0);
- break;
- }
- packet.Add( DriverIsGunner );
- SmartGameObj::Export_Frequent(packet);
- }
- //-----------------------------------------------------------------------------
- void VehicleGameObj::Import_State_Cs(BitStreamClass & packet)
- {
- SmartGameObj::Import_State_Cs(packet);
- }
- void VehicleGameObj::Export_State_Cs(BitStreamClass & packet)
- {
- SmartGameObj::Export_State_Cs(packet);
- }
- void VehicleGameObj::Get_Velocity(Vector3 & vel)
- {
- VehiclePhysClass * vp = Peek_Vehicle_Phys();
- if (vp != NULL) {
- vp->Get_Velocity(&vel);
- } else {
- vel.Set(0,0,0);
- }
- }
- void VehicleGameObj::Set_Velocity(Vector3 & vel)
- {
- VehiclePhysClass * vehicle = Peek_Vehicle_Phys();
- if (vehicle != NULL) {
- vehicle->Set_Velocity(vel);
- }
- }
- void VehicleGameObj::Startup( void )
- {
- // Setup all Seats for entry
- Create_And_Destroy_Transitions();
- }
- void VehicleGameObj::Update_Turret( float weapon_turn, float weapon_tilt )
- {
- if ( TurretBone != 0 ) {
- Matrix3D facing(1);
- facing.Rotate_Z( weapon_turn );
- if ( BarrelBone == 0 ) { // if no barrel bone
- facing.Rotate_Y( -weapon_tilt ); // neg rotate y tilts up
- }
- Peek_Model()->Control_Bone( TurretBone, facing );
- }
- if ( BarrelBone != 0 ) {
- Matrix3D facing(1);
- facing.Rotate_Y( -weapon_tilt ); // neg rotate y tilts up
- Peek_Model()->Control_Bone( BarrelBone, facing );
- }
- }
- /*
- ** Vehicle Weapons
- */
- bool VehicleGameObj::Set_Targeting( const Vector3 & target_pos, bool do_tilt )
- {
- bool ready = true;
- //Debug_Say(( "Weapon set targeting %f %f %f\n", target_pos.X, target_pos.Y, target_pos.Z ));
- SmartGameObj::Set_Targeting( target_pos );
- // Find the desired turret tilt and turn
- float relative_turn = 0;
- float relative_tilt = 0;
- if ( TurretBone != 0 ) {
- // find the target pos in turret space
- Matrix3D turret_base = Peek_Model()->Get_Bone_Transform( TurretBone );
- Vector3 turret_space_target;
- Matrix3D::Inverse_Transform_Vector( turret_base, target_pos, &turret_space_target );
- // Set the tilt and turn
- relative_turn = WWMath::Atan2( turret_space_target.Y, turret_space_target.X );
- if ( BarrelOffset ) {
- turret_space_target.Z = 0;
- float barrel_offset_angle = WWMath::Atan2( BarrelOffset, turret_space_target.Length() );
- // Debug_Say(( "barrel angle %f %f\n", RAD_TO_DEG( barrel_offset_angle ), RAD_TO_DEG( relative_turn + barrel_offset_angle ) ));
- relative_turn -= barrel_offset_angle;
- }
- }
- if ( WWMath::Fabs( relative_turn ) < DEG_TO_RAD( 80 ) ) {
- if ( BarrelBone != 0 ) {
- // find the target pos in barrel space
- Matrix3D barrel_base = Peek_Model()->Get_Bone_Transform( BarrelBone );
- Vector3 barrel_space_target;
- Matrix3D::Inverse_Transform_Vector( barrel_base, target_pos, &barrel_space_target );
- float dist = barrel_space_target.Length();
- if ( dist ) {
- // Only tilt when the turn is within 80 deg
- relative_tilt = WWMath::Fast_Asin( barrel_space_target.Z / dist );
- }
- }
- }
- // Move the tilt and turn towards the desired, following rates and limits
- float max_move;
- max_move = Get_Definition().WeaponTurnRate * TimeManager::Get_Frame_Seconds();
- if ( Get_Definition().WeaponTurnRate < DEG_TO_RAD(1000) ) {
- TurretTurn += WWMath::Clamp( relative_turn, -max_move, max_move );
- if ( WWMath::Fabs( relative_turn ) > WWMath::Fabs( max_move ) ) {
- ready = false;
- }
- } else {
- TurretTurn += relative_turn;
- }
- TurretTurn = WWMath::Clamp( TurretTurn, Get_Definition().WeaponTurnMin, Get_Definition().WeaponTurnMax );
- max_move = Get_Definition().WeaponTiltRate * TimeManager::Get_Frame_Seconds();
- if ( do_tilt ) {
- if ( Get_Definition().WeaponTiltRate < DEG_TO_RAD(1000) ) {
- BarrelTilt += WWMath::Clamp( relative_tilt, -max_move, max_move );
- if ( WWMath::Fabs( relative_tilt ) > WWMath::Fabs( max_move ) ) {
- ready = false;
- }
- } else {
- BarrelTilt += relative_tilt;
- }
- }
- BarrelTilt = WWMath::Clamp( BarrelTilt, Get_Definition().WeaponTiltMin, Get_Definition().WeaponTiltMax );
- // Apply the turn and tilt to the bones
- Update_Turret( TurretTurn, BarrelTilt );
- // if a fast turner and had to turn, do it again,just to make sure (trying to fix obelisk)
- if ( Get_Definition().WeaponTurnRate > DEG_TO_RAD(1000) &&
- ( WWMath::Fabs(relative_turn) >= DEG_TO_RAD( 2 ) || WWMath::Fabs(relative_tilt) > DEG_TO_RAD( 2 ) ) ) {
- static int calls = 0;
- if ( calls < 3 ) {
- calls++;
- Set_Targeting( target_pos, do_tilt ); // recurse
- calls--;
- }
- ready = true;
- }
- return ready;
- }
- int VehicleGameObj::Get_Weapon_Control_Owner(void)
- {
- SoldierGameObj * gunner = Get_Gunner();
- if ( gunner && !Get_Driver_Is_Gunner() ) {
- return gunner->Get_Control_Owner();
- }
- SoldierGameObj * driver = Get_Driver();
- if ( driver ) {
- return driver->Get_Control_Owner();
- }
- return Get_Control_Owner();
- }
- /*
- void VehicleGameObj::Apply_Control( void )
- {
- SoldierGameObj * driver = Seats[DRIVER_SEAT];
- SoldierGameObj * gunner = Seats[GUNNER_SEAT];
- if ( gunner == NULL ) {
- gunner = driver;
- }
- bool target_steering = false;
- // If I have a driver, use his control
- if ( driver && !driver->In_Transition() ) {
- //Debug_Say(( "Vehicle copy driver's control\n" )); //copy his control???
- Control = driver->Get_Control();
- target_steering = true;
- } else if ( !Get_Action()->Is_Acting() ) {
- Control.Clear_Control(); // Bad for network????
- }
- // If i have a gunner, use him for the gun control
- if ( gunner && (gunner != driver) && !gunner->In_Transition() ) {
- Control.Set_Boolean( ControlClass::BOOLEAN_WEAPON_FIRE_PRIMARY, gunner->Get_Control().Get_Boolean( ControlClass::BOOLEAN_WEAPON_FIRE_PRIMARY ) );
- Control.Set_Boolean( ControlClass::BOOLEAN_WEAPON_FIRE_SECONDARY, gunner->Get_Control().Get_Boolean( ControlClass::BOOLEAN_WEAPON_FIRE_SECONDARY ) );
- Control.Set_Boolean( ControlClass::BOOLEAN_WEAPON_NEXT, gunner->Get_Control().Get_Boolean( ControlClass::BOOLEAN_WEAPON_NEXT ) );
- Control.Set_Boolean( ControlClass::BOOLEAN_WEAPON_PREV, gunner->Get_Control().Get_Boolean( ControlClass::BOOLEAN_WEAPON_PREV ) );
- Control.Set_Boolean( ControlClass::BOOLEAN_WEAPON_RELOAD, gunner->Get_Control().Get_Boolean( ControlClass::BOOLEAN_WEAPON_RELOAD ) );
- Control.Set_Boolean( ControlClass::BOOLEAN_WEAPON_USE, gunner->Get_Control().Get_Boolean( ControlClass::BOOLEAN_WEAPON_USE ) );
- }
- if ( target_steering ) {
- // Lets make turns come from the targeting
- Vector3 target_pos = Get_Targeting_Pos();
- Vector3 obj_space_target;
- Matrix3D::Inverse_Transform_Vector( Get_Transform(), target_pos, &obj_space_target );
- float target_direction = WWMath::Atan2( obj_space_target.Y, obj_space_target.X );
- float turn_amount = target_direction / DEG_TO_RAD( 60 );
- Control.Set_Analog( ControlClass::ANALOG_TURN_LEFT, turn_amount );
- }
- // Clamp turning
- Control.Set_Analog( ControlClass::ANALOG_TURN_LEFT,
- WWMath::Clamp( Control.Get_Analog( ControlClass::ANALOG_TURN_LEFT ), -1.0F, 1.0F ) );
- SmartGameObj::Apply_Control();
- }
- */
- void VehicleGameObj::Apply_Control( void )
- {
- SoldierGameObj * driver = Get_Driver();
- SoldierGameObj * gunner = Get_Gunner();
- if ( gunner == NULL || Get_Driver_Is_Gunner() ) {
- gunner = driver;
- }
- // if ( gunner || driver ) {
- if ( !CombatManager::Is_Gameplay_Permitted() ) {
- Clear_Control();
- Controller.Reset();
- if ( Peek_Vehicle_Phys() != NULL) {
- Peek_Vehicle_Phys()->Set_Velocity( Vector3(0,0,0) );
- }
- return;
- }
- // }
- bool target_steering = false;
- // If I have a driver, use his control
- if ( driver && !driver->In_Transition() && driver->Is_Human_Controlled () == true) {
- /*
- bool use_control = CombatManager::I_Am_Server() ||
- (CombatManager::Get_Client_Interpolation_Model() !=
- CLIENT_INTERPOLATION_PATHFIND) ||
- (CombatManager::I_Am_Client() &&
- driver->Get_Control_Owner() == CombatManager::Get_My_Id());
- //Debug_Say(( "Vehicle copy driver's control\n" )); //copy his control???
- if (use_control) {
- Control = driver->Get_Control();
- target_steering = true;
- }
- */
- //
- // This could be a little dodgy... does client do this?
- //
- Control = driver->Get_Control();
- target_steering = true;
- }
- // If i have a gunner, use him for the gun control
- if ( gunner && (gunner != driver) && !gunner->In_Transition() && !Get_Driver_Is_Gunner() ) {
- Control.Set_Boolean( ControlClass::BOOLEAN_WEAPON_FIRE_PRIMARY, gunner->Get_Control().Get_Boolean( ControlClass::BOOLEAN_WEAPON_FIRE_PRIMARY ) );
- Control.Set_Boolean( ControlClass::BOOLEAN_WEAPON_FIRE_SECONDARY, gunner->Get_Control().Get_Boolean( ControlClass::BOOLEAN_WEAPON_FIRE_SECONDARY ) );
- Control.Set_Boolean( ControlClass::BOOLEAN_WEAPON_RELOAD, gunner->Get_Control().Get_Boolean( ControlClass::BOOLEAN_WEAPON_RELOAD ) );
- }
- // Vehicles never change weapons
- Control.Set_Boolean( ControlClass::BOOLEAN_WEAPON_NEXT, false );
- Control.Set_Boolean( ControlClass::BOOLEAN_WEAPON_PREV, false );
- if ( target_steering && _Use_Target_Steering ) {
- // Target Steering kicks in if the user is pressing the accelerator key.
- if (Control.Get_Analog( ControlClass::ANALOG_MOVE_FORWARD ) >= 0.0f) {
- // Lets make turns come from the targeting
- Vector3 target_pos = Get_Targeting_Pos();
- Vector3 obj_space_target;
- Matrix3D::Inverse_Transform_Vector( Get_Transform(), target_pos, &obj_space_target );
- float target_direction = WWMath::Atan2( obj_space_target.Y, obj_space_target.X );
- // Offset the target direction if the user is turning while driving forward
- const float TARGET_STRAFE_ANGLE = DEG_TO_RADF(50.0f);
- target_direction += TARGET_STRAFE_ANGLE * Control.Get_Analog( ControlClass::ANALOG_TURN_LEFT );
- // Set the final steering angle
- float turn_amount = target_direction / DEG_TO_RAD( 60 ) * Control.Get_Analog( ControlClass::ANALOG_MOVE_FORWARD );
- Control.Set_Analog( ControlClass::ANALOG_TURN_LEFT, turn_amount );
- } else {
- // When over-riding the target steering with keyboard steering,
- // scale the turn rate down if we're going forward.
- if (Control.Get_Analog( ControlClass::ANALOG_MOVE_FORWARD ) > 0.0f) {
- Control.Set_Analog( ControlClass::ANALOG_TURN_LEFT, 0.5f * Control.Get_Analog(ControlClass::ANALOG_TURN_LEFT) );
- }
- }
- }
- // Clamp turning
- Control.Set_Analog( ControlClass::ANALOG_TURN_LEFT,
- WWMath::Clamp( Control.Get_Analog( ControlClass::ANALOG_TURN_LEFT ), -1.0F, 1.0F ) );
- SmartGameObj::Apply_Control();
- }
- static char * _profile_name = "Vehicle Think";
- void VehicleGameObj::Think( void )
- {
- { WWPROFILE( _profile_name );
- Apply_Control(); // ????
- Update_Transitions();
- }
- SmartGameObj::Think(); // Perform smart object thinking
- { WWPROFILE( _profile_name );
- Update_Sound_Effects();
- Update_Wheel_Effects();
- // Update the lock status
- if (LockTimer > 0.0f) {
- LockTimer -= TimeManager::Get_Frame_Seconds();
- } else {
- LockOwner = NULL;
- }
- // UnStealth if we don't have any occupants, and we aren't in single play
- if (StealthEffect != NULL) {
- if ((Get_Occupant_Count() == 0 ) && ( !IS_MISSION )) {
- StealthEffect->Enable_Stealth(false);
- }
- }
- }
- }
- static char * _post_profile_name = "Vehicle PostThink";
- void VehicleGameObj::Post_Think( void )
- {
- { WWPROFILE( _post_profile_name );
- RenderObjClass * model = Peek_Model();
- WWASSERT( model );
- for ( int i = 0; i < SeatOccupants.Length(); i++ ) {
- if ( SeatOccupants[i] != NULL ) {
- char bone_name[80];
- sprintf( bone_name, "SEAT%d", i );
- int seat_bone_index = model->Get_Bone_Index( bone_name );
- if ( seat_bone_index != -1 ) {
- Matrix3D seat = model->Get_Bone_Transform( seat_bone_index );
- if ( !SeatOccupants[i]->In_Transition() ) {
- SeatOccupants[i]->Set_Transform( seat );
- }
- } else {
- Debug_Say(( "No Seat bone %s\n", bone_name ));
- }
- }
- }
- }
- SmartGameObj::Post_Think();
- { WWPROFILE( _post_profile_name );
- if ( Get_Weapon() && !Get_Definition().Fire0Anim.Is_Empty() ) {
- Get_Weapon()->Reset_Anim_Update();
- int state = Get_Weapon()->Get_Anim_State();
- if ( state == WEAPON_ANIM_NOT_FIRING ) {
- Set_Animation( NULL );
- } else if ( state == WEAPON_ANIM_FIRING_0 ) {
- Set_Animation( Get_Definition().Fire0Anim );
- } else if ( state == WEAPON_ANIM_FIRING_1 ) {
- Set_Animation( !Get_Definition().Fire1Anim.Is_Empty() ? Get_Definition().Fire1Anim : Get_Definition().Fire0Anim );
- } else {
- Debug_Say(( "Bad Weapon Anim State\n" ));
- }
- }
- }
- }
- /*
- **
- */
- int VehicleGameObj::Get_Player_Type(void) const
- {
- // If they have a driver, they are his team.
- for (int i = 0; i < SeatOccupants.Length(); i++) {
- if (SeatOccupants[i] != NULL) {
- return SeatOccupants[i]->Get_Player_Type();
- }
- }
- #if 0 // Do this at exit time
- // in MP, empty vehicles are neutral
- if ( !IS_MISSION ) {
- return PLAYERTYPE_NEUTRAL;
- }
- #endif
- return SmartGameObj::Get_Player_Type();
- }
- /*
- **
- */
- void VehicleGameObj::Init_Wheel_Effects( void )
- {
- // Create an array of persistant surface emitters, one for each "real" wheel
- WWASSERT( WheelSurfaceEmitters.Length() == 0 );
- if ( (Peek_Vehicle_Phys() != NULL) &&
- (Peek_Vehicle_Phys()->Get_VehiclePhysDef()->Is_Fake() == false) )
- {
- int real_wheel_count = Peek_Vehicle_Phys()->Get_Real_Wheel_Count();
- WheelSurfaceEmitters.Resize(real_wheel_count);
- for (int i=0; i<real_wheel_count; i++) {
- WheelSurfaceEmitters[i] = SurfaceEffectsManager::Create_Persistant_Emitter();
- }
- }
- // Create a single persistant surface effect sound for tire squealing
- WWASSERT(WheelSurfaceSound == NULL);
- WheelSurfaceSound = SurfaceEffectsManager::Create_Persistant_Sound();
- }
- void VehicleGameObj::Shutdown_Wheel_Effects( void )
- {
- // Release the persistant surface emitters
- for (int i=0; i<WheelSurfaceEmitters.Length(); i++) {
- SurfaceEffectsManager::Destroy_Persistant_Emitter( WheelSurfaceEmitters[i] );
- WheelSurfaceEmitters[i] = NULL;
- }
- WheelSurfaceEmitters.Clear();
- // Release the persistant surface sound effect
- SurfaceEffectsManager::Destroy_Persistant_Sound(WheelSurfaceSound);
- WheelSurfaceSound = NULL;
- }
- void VehicleGameObj::Update_Wheel_Effects( void )
- {
- if ( (Peek_Vehicle_Phys() == NULL) ||
- (Peek_Vehicle_Phys()->Get_VehiclePhysDef()->Is_Fake()) )
- {
- return;
- }
- int roll_hitter_type = SurfaceEffectsManager::HITTER_TYPE_TIRE_ROLLING;
- int slide_hitter_type = SurfaceEffectsManager::HITTER_TYPE_TIRE_SLIDING;
- if ( Peek_Vehicle_Phys()->As_TrackedVehicleClass() != NULL) {
- roll_hitter_type = SurfaceEffectsManager::HITTER_TYPE_TRACK_ROLLING;
- slide_hitter_type = SurfaceEffectsManager::HITTER_TYPE_TRACK_SLIDING;
- }
- Vector3 vel;
- Peek_Vehicle_Phys()->Get_Velocity(&vel);
- float vlen2 = vel.Length2();
- // Update the emitters and sound
- const float EMITTER_SLIDE_THRESHOLD = 1.0f;
- const float EMITTER_ROLL_THRESHOLD2 = 2.0f * 2.0f;
- const float EMITTER_CINEMATIC_ROLL_AVEL = DEG_TO_RADF(1.0f);
- bool sound_done = false;
- if (WheelSurfaceEmitters.Length() > 0) {
- if ( Peek_Vehicle_Phys() != NULL) {
- int emitter_index = 0;
- int wheel_count = Peek_Vehicle_Phys()->Get_Wheel_Count();
- for (int i=0; i<wheel_count; i++) {
- SuspensionElementClass * wheel = Peek_Vehicle_Phys()->Peek_Wheel(i);
- if (wheel->Get_Flag(SuspensionElementClass::FAKE) == false) {
- // Look up the surface and hitter types
- int surface_type = wheel->Get_Contact_Surface();
- int hitter_type = SurfaceEffectsManager::HITTER_TYPE_NONE;
- // If stealthed, no emitters.
- if (Is_Stealthed()) {
- surface_type = SURFACE_TYPE_DEFAULT;
- }
- if (wheel->Get_Flag( SuspensionElementClass::INCONTACT ) ) {
- if (wheel->Get_Slip_Factor() > EMITTER_SLIDE_THRESHOLD) {
- hitter_type = slide_hitter_type;
- } else {
- // normally, trigger roll emitters by the velocity of the vehicle
- if (vlen2 > EMITTER_ROLL_THRESHOLD2) {
- hitter_type = roll_hitter_type;
- }
- // when attached to a cinematic, we deduce whether the wheels are rolling
- // by using the rotation delta feature of wheels
- if (Is_Attached_To_An_Object()) {
- float wheel_avel = WWMath::Fabs(wheel->Get_Rotation_Delta() / TimeManager::Get_Frame_Seconds());
- if (wheel_avel > EMITTER_CINEMATIC_ROLL_AVEL) {
- hitter_type = roll_hitter_type;
- }
- }
- }
- }
- // Update the emitter and move to the next emitter
- SurfaceEffectsManager::Update_Persistant_Emitter( WheelSurfaceEmitters[emitter_index],
- surface_type,
- hitter_type,
- wheel->Get_Wheel_Transform());
- emitter_index++;
- // If this is the sound generating wheel, update the sound
- // I'm just using the first engine wheel as the one that generates the tire sound effects.
- if (!sound_done && wheel->Get_Flag(SuspensionElementClass::ENGINE)) {
- SurfaceEffectsManager::Update_Persistant_Sound( WheelSurfaceSound,
- surface_type,
- hitter_type,
- Get_Transform());
- sound_done = true;
- }
- }
- }
- }
- }
- }
- void VehicleGameObj::Update_Sound_Effects(void)
- {
- if (Peek_Vehicle_Phys() == NULL) {
- return;
- }
- switch (EngineSoundState)
- {
- case ENGINE_SOUND_STATE_STARTING:
- {
- // play our ENGINE_STARTING sound, if it is finished or not found, destroy and go to ENGINE_RUNNING
- if ((CachedEngineSound == NULL) || ((CachedEngineSound != NULL) && (CachedEngineSound->Get_State()==AudibleSoundClass::STATE_STOPPED))) {
- Change_Engine_Sound_State(ENGINE_SOUND_STATE_RUNNING);
- }
- }
- break;
- case ENGINE_SOUND_STATE_RUNNING:
- {
- if (CachedEngineSound != NULL) {
- Update_Engine_Sound_Pitch ();
- }
- if (Peek_Vehicle_Phys()->Is_Engine_Enabled() == false) {
- Change_Engine_Sound_State(ENGINE_SOUND_STATE_STOPPING);
- }
- }
- break;
- case ENGINE_SOUND_STATE_STOPPING:
- {
- // play the ENGINE_STOPPING sound, if it is finished or not found, destroy and go to ENGINE_OFF
- if ((CachedEngineSound == NULL) || ((CachedEngineSound != NULL) && (CachedEngineSound->Get_State()==AudibleSoundClass::STATE_STOPPED))) {
- Change_Engine_Sound_State(ENGINE_SOUND_STATE_OFF);
- }
- }
- break;
- case ENGINE_SOUND_STATE_OFF:
- {
- // if the engine is on, go to ENGINE_STARTING
- if (Peek_Vehicle_Phys()->Is_Engine_Enabled() == true) {
- Change_Engine_Sound_State(ENGINE_SOUND_STATE_STARTING);
- }
- }
- break;
- default:
- WWDEBUG_SAY(("Error: Invalid Engine Sound State %d! file: %s line: %d\n",EngineSoundState,__FILE__,__LINE__));
- break;
- }
- }
- void VehicleGameObj::Change_Engine_Sound_State(int new_state)
- {
- if (CachedEngineSound != NULL) {
- CachedEngineSound->Remove_From_Scene();
- CachedEngineSound->Release_Ref();
- CachedEngineSound = NULL;
- }
- EngineSoundState = new_state;
- DefinitionClass * sound_def = DefinitionMgrClass::Find_Definition(Get_Definition().EngineSound[new_state]);
- if (sound_def != NULL) {
- CachedEngineSound = (AudibleSoundClass *)sound_def->Create();
- }
- if (CachedEngineSound != NULL) {
- CachedEngineSound->Add_To_Scene();
- CachedEngineSound->Attach_To_Object(Peek_Model());
- }
- return ;
- }
- void VehicleGameObj::Update_Engine_Sound_Pitch(void)
- {
- if (CachedEngineSound == NULL) {
- return ;
- }
- float pitch_factor = 1.0F;
- if (Peek_Vehicle_Phys() != NULL) {
- MotorVehicleClass * motophys = Peek_Physical_Object()->As_MotorVehicleClass();
- TrackedVehicleClass * trackphys = Peek_Physical_Object()->As_TrackedVehicleClass();
- VTOLVehicleClass * vtolphys = Peek_Physical_Object()->As_VTOLVehicleClass();
- float max_factor = Get_Definition().EngineSoundMaxPitchFactor;
- if (motophys != NULL) {
- // Wheeled vehicle engine pitch depends on their rpms
- float norm_rpm = motophys->Get_Normalized_Engine_RPM();
- if (norm_rpm < 0) {
- norm_rpm = -norm_rpm;
- }
- norm_rpm = WWMath::Clamp(norm_rpm,0.0f,1.0f);
- pitch_factor = 1.0F + ((max_factor - 1.0F) * norm_rpm);
- } else if (trackphys != NULL) {
- // Tracked vehicle engine pitch depends on their overall speed
- const float MAX_TRACKED_SPEED = 10.0f;
- Vector3 vel;
- trackphys->Get_Velocity(&vel);
- float norm_speed = WWMath::Clamp(vel.Length() / MAX_TRACKED_SPEED,0.0f,1.0f);
- pitch_factor = 1.0F + ((max_factor - 1.0F) * norm_speed);
- } else if (vtolphys != NULL) {
- // VTOL vehicle engine pitch depends on absolute acceleration
- const float MAX_VTOL_SPEED = 20.0f;
- Vector3 vel;
- vtolphys->Get_Velocity(&vel);
- float norm_speed = WWMath::Clamp(vel.Length() / MAX_VTOL_SPEED,0.0f,1.0f);
- pitch_factor = 1.0F + ((max_factor - 1.0F) * norm_speed);
- }
- }
- CachedEngineSound->Set_Pitch_Factor (pitch_factor);
- return ;
- }
- VehiclePhysClass *VehicleGameObj::Peek_Vehicle_Phys( void ) const
- {
- WWASSERT( Peek_Physical_Object() );
- return Peek_Physical_Object()->As_VehiclePhysClass(); // NOTE: sometimes will return NULL!
- }
- /*
- ** Occupants ( drivers, gunners, passengers )
- */
- void VehicleGameObj::Add_Occupant( SoldierGameObj * occupant )
- {
- // Add the the lowest empty seat
- for ( int i = 0; i < Get_Definition().NumSeats; i++ ) {
- if ( SeatOccupants[i] == NULL ) {
- Add_Occupant( occupant, i );
- break;;
- }
- }
- }
- void VehicleGameObj::Add_Occupant( SoldierGameObj * occupant, int seat_id )
- {
- WWASSERT( occupant );
- if ( SeatOccupants[seat_id] != NULL ) {
- Debug_Say(( "Vehicle already has an occupant in that seat\n" ));
- return;
- }
- if ( Find_Seat( occupant ) != -1 ) {
- Debug_Say(( "Soldier already in vehicle\n" ));
- }
- if ( seat_id == 0 ) {
- DriverIsGunner = DefaultDriverIsGunner;
- }
- Debug_Say(( "Soldier %p added to seat %d\n", occupant, seat_id ));
- if ( seat_id > Get_Definition().NumSeats-1 ) {
- Debug_Say(( "Adding to extra seat %d\n", seat_id ));
- }
- SeatOccupants[seat_id] = occupant;
- OccupiedSeats++;
- Set_Object_Dirty_Bit( NetworkObjectClass::BIT_RARE, true );
- const char * anim_name = NULL;
- if ( Get_Definition().Type == VEHICLE_TYPE_BIKE ) {
- anim_name = "S_A_HUMAN.H_A_V20A";
- } else {
- anim_name = "S_A_HUMAN.H_A_V10A";
- }
- occupant->Enter_Vehicle( this, anim_name );
- // Debug_Say(( "Vehicle has a occupant in seat %d\n", seat_id ));
- // possibily delete transitions
- Create_And_Destroy_Transitions();
- Enable_Engine(true);
- if ( Get_Definition().OccupantsVisible == false ) {
- occupant->Peek_Model()->Set_Hidden( true );
- }
- // Notify the observers that someone entered
- const GameObjObserverList & observer_list = Get_Observers();
- for( int index = 0; index < observer_list.Count(); index++ ) {
- observer_list[ index ]->Custom( this, CUSTOM_EVENT_VEHICLE_ENTERED, seat_id, occupant );
- }
- //
- // Reveal this vehicle to the player if he was the one to enter the vehicle
- //
- if ( occupant == COMBAT_STAR ) {
- EncyclopediaMgrClass::Reveal_Object( this );
- }
- //
- // Reset any action the vehicle was performing
- //
- if (Get_Action() != NULL) {
- Get_Action()->Reset(1);
- }
- //
- // Unlock the vehicle!
- //
- LockTimer = 0.0f;
- LockOwner = NULL;
- }
- int VehicleGameObj::Find_Seat( SoldierGameObj * occupant )
- {
- for ( int i = 0; i < SeatOccupants.Length(); i++ ) {
- if ( SeatOccupants[i] == occupant ) {
- return i;
- }
- }
- return -1;
- }
- void VehicleGameObj::Remove_Occupant( SoldierGameObj * occupant )
- {
- WWASSERT( occupant );
- int seat_num = Find_Seat( occupant );
- if ( seat_num == -1 ) {
- Debug_Say(( "Object is not in this vehicle\n" ));
- return;
- }
- // Do this anyway, just to make sure it happens.
- if ( Get_Definition().OccupantsVisible == false ) {
- if ( SeatOccupants[seat_num] && SeatOccupants[seat_num]->Peek_Model() ) {
- SeatOccupants[seat_num]->Peek_Model()->Set_Hidden( false );
- }
- }
- Debug_Say(( "Soldier %p removed from seat %d\n", occupant, seat_num ));
- SeatOccupants[seat_num]->Exit_Vehicle();
- SeatOccupants[seat_num] = NULL;
- OccupiedSeats--;
- // in MP, empty vehicles are neutral
- if ( !IS_MISSION && OccupiedSeats == 0 ) {
- Set_Player_Type( PLAYERTYPE_NEUTRAL );
- }
- Set_Object_Dirty_Bit( NetworkObjectClass::BIT_RARE, true );
- // possibily re-enable transitions
- Create_And_Destroy_Transitions();
- if ( seat_num == 0 ) {
- Enable_Engine(false);
- }
- // Notify the observers that someone left
- const GameObjObserverList & observer_list = Get_Observers();
- for( int index = 0; index < observer_list.Count(); index++ ) {
- observer_list[ index ]->Custom( this, CUSTOM_EVENT_VEHICLE_EXITED, seat_num, occupant );
- }
- }
- bool VehicleGameObj::Contains_Occupant( SoldierGameObj * occupant )
- {
- WWASSERT( occupant );
- for ( int i = 0; i < SeatOccupants.Length(); i++ ) {
- if ( SeatOccupants[i] == occupant ) {
- return true;
- }
- }
- return false;
- }
- int VehicleGameObj::Get_Occupant_Count(void)
- {
- int count = 0;
- for ( int i = 0; i < SeatOccupants.Length(); i++ ) {
- if ( SeatOccupants[i] != NULL ) {
- count++;
- }
- }
- return count;
- }
- bool VehicleGameObj::Is_Entry_Permitted( SoldierGameObj * p_soldier )
- {
- if (!CombatManager::Is_Gameplay_Permitted()) {
- //
- // You can't enter a vehicle if there are no opponents, etc
- //
- return false;
- }
- //
- // Do not permit a soldier to enter a vehicle if there is already
- // another soldier of a different player type in the vehicle.
- // Actually, only allow 2 Nods or 2 GDI's to share a vehicle...
- //
- WWASSERT(p_soldier != NULL);
- bool is_permitted = true;
- int player_type = p_soldier->Get_Player_Type();
- int i;
- for (i = 0; i < SeatOccupants.Length(); i++) {
- if (SeatOccupants[i] != NULL) {
- int seated_pt = SeatOccupants[i]->Get_Player_Type();
- if (seated_pt != player_type ||
- (seated_pt != PLAYERTYPE_NOD && seated_pt != PLAYERTYPE_GDI)) {
- is_permitted = false;
- break;
- }
- }
- }
- // If there are no entry transitions, entry is not possible
- bool entry_exists = false;
- for ( i = 0; i < TransitionInstances.Count(); i++ ) {
- // if ( ( TransitionInstances[i]->Get_Type() == TransitionDataClass::LEGACY_VEHICLE_ENTER_0 ) ||
- // ( TransitionInstances[i]->Get_Type() == TransitionDataClass::LEGACY_VEHICLE_ENTER_1 ) ) {
- if ( TransitionInstances[i]->Get_Type() == TransitionDataClass::VEHICLE_ENTER ) {
- entry_exists = true;
- }
- }
- if ( !entry_exists ) {
- is_permitted = false;
- }
- // If the vehicle is locked and you are not the lock owner, entry is not permitted
- if (Is_Locked() && (p_soldier != LockOwner.Get_Ptr())) {
- is_permitted = false;
- }
- return is_permitted;
- }
- void VehicleGameObj::Remove_Transitions( TransitionDataClass::StyleType transition_type )
- {
- for ( int i = 0; i < TransitionInstances.Count(); i++ ) {
- if ( TransitionInstances[i]->Get_Type() == transition_type ) {
- TransitionManager::Destroy( TransitionInstances[i] );
- TransitionInstances.Delete( i );
- i--;
- }
- }
- }
- void VehicleGameObj::Create_New_Transitions( TransitionDataClass::StyleType transition_type )
- {
- const TRANSITION_DATA_LIST & trans_data_list = Get_Definition().Get_Transition_List();
- for ( int i = 0; i < trans_data_list.Count(); i++ ) {
- if ( trans_data_list[i]->Get_Type() == transition_type ) {
- // make new instance
- TransitionInstanceClass * trans = new TransitionInstanceClass( *trans_data_list[i] );
- // setup
- trans->Set_Vehicle( this );
- // add to our list
- TransitionInstances.Add( trans );
- // add to master list
- TransitionManager::Add( trans );
- }
- }
- }
- void VehicleGameObj::Update_Transitions( void )
- {
- Matrix3D tm = Get_Transform();
- // Update all transitions
- for ( int i = 0; i < TransitionInstances.Count(); i++ ) {
- TransitionInstances[i]->Set_Parent_Transform( tm );
- }
- }
- void VehicleGameObj::Passenger_Entering( void )
- {
- // Play the passenger entering animation
- char string[80];
- sprintf( string, "V_%sL1.M_%sCL", Get_Definition().TypeName, Get_Definition().TypeName );
- Set_Animation( string );
- Get_Anim_Control()->Set_Mode( ANIM_MODE_ONCE );
- //Debug_Say(("VehicleGameObj::Passenger_Entering\n"));
- }
- void VehicleGameObj::Passenger_Exiting( void )
- {
- // Play the passenger leaving animation
- char string[80];
- sprintf( string, "V_%sL1.M_%sOP", Get_Definition().TypeName, Get_Definition().TypeName );
- Set_Animation( string );
- Get_Anim_Control()->Set_Mode( ANIM_MODE_ONCE );
- Control.Clear_Control();
- }
- //void VehicleGameObj::Get_Extended_Information(StringClass & description)
- void VehicleGameObj::Get_Description(StringClass & description)
- {
- StringClass line;
- line.Format("ID: %d\n", Get_ID());
- description += line;
- line.Format("NAME: %s\n", Get_Definition().Get_Name());
- description += line;
- line.Format("TEAM: %d\n", Get_Player_Type());
- description += line;
- line.Format("CONTR: %d\n", Get_Control_Owner());
- description += line;
- Vector3 position;
- Get_Position(&position);
- line.Format("POS: %-5.2f, %-5.2f, %-5.2f\n", position.X, position.Y, position.Z);
- description += line;
- Vector3 target = Get_Targeting_Pos();
- line.Format("TGT: %-5.2f, %-5.2f, %-5.2f\n", target.X, target.Y, target.Z);
- description += line;
- Vector3 velocity;
- Get_Velocity(velocity);
- line.Format("VEL: %-5.2f, %-5.2f, %-5.2f\n", velocity.X, velocity.Y, velocity.Z);
- description += line;
- line.Format("SPD: %-5.2f\n", velocity.Length());
- description += line;
- WeaponClass * p_weapon = Get_Weapon();
- if (p_weapon != NULL) {
- line.Format("WEAP: %s\n", p_weapon->Get_Name());
- description += line;
- line.Format("RNDS: %d\n", p_weapon->Get_Total_Rounds());
- description += line;
- }
- if (Get_Defense_Object() != NULL) {
- line.Format("HLTH: %-5.2f\n", Get_Defense_Object()->Get_Health());
- description += line;
- }
- if (Get_Driver() != NULL) {
- line.Format("DRVR: %d\n", Get_Driver()->Get_ID());
- description += line;
- }
- if (Get_Gunner() != NULL) {
- line.Format("GUNR: %d\n", Get_Gunner()->Get_ID());
- description += line;
- }
- line.Format("HIB: %d\n", Is_Hibernating());
- description += line;
- ControlClass & control = Get_Control();
- line.Format("CTRL: %d, %d, %5.2f, %5.2f, %5.2f, %5.2f\n",
- control.Get_One_Time_Boolean_Bits(),
- control.Get_Continuous_Boolean_Bits(),
- control.Get_Analog(ControlClass::ANALOG_MOVE_FORWARD),
- control.Get_Analog(ControlClass::ANALOG_MOVE_LEFT),
- control.Get_Analog(ControlClass::ANALOG_MOVE_UP),
- control.Get_Analog(ControlClass::ANALOG_TURN_LEFT));
- description += line;
- if (Get_Action() != NULL) {
- line.Format("ACTCT: %d\n", Get_Action()->Get_Act_Count());
- description += line;
- Vector3 move_loc = Get_Action()->Get_Parameters().MoveLocation;
- line.Format("MVLOC: (%5.2f, %5.2f, %5.2f)\n", move_loc.X, move_loc.Y, move_loc.Z);
- description += line;
- }
- line.Format ("ATTCH: %d\n", Is_Attached_To_An_Object ());
- description += line;
- line.Format("stlth: %d\n", Is_Stealth_Enabled());
- description += line;
- line.Format(" on: %d\n", Is_Stealthed());
- description += line;
- line.Format("ISC: %d\n", Get_Import_State_Count());
- description += line;
- }
- bool VehicleGameObj::Is_Engine_Enabled (void) const
- {
- if (Peek_Vehicle_Phys() != NULL) {
- return Peek_Vehicle_Phys()->Is_Engine_Enabled();
- } else {
- return false;
- }
- }
- void VehicleGameObj::Enable_Engine (bool onoff)
- {
- if (Peek_Vehicle_Phys() != NULL) {
- Peek_Vehicle_Phys()->Enable_Engine(onoff);
- }
- }
- void VehicleGameObj::Set_Precision(void)
- {
- cEncoderList::Set_Precision(BITPACK_VEHICLE_VELOCITY,
- -90.0f, 90.0f, 0.01f); // 200 mph = approx. 90 m/s
- cEncoderList::Set_Precision(BITPACK_VEHICLE_ANGULAR_VELOCITY,
- -20.0f, 20.0f, 0.01f); // to approx 6 PI
- cEncoderList::Set_Precision(BITPACK_VEHICLE_QUATERNION,
- -1.0f, 1.0f, 0.0005f); // -1 to 1
- cEncoderList::Set_Precision(BITPACK_VEHICLE_LOCK_TIMER,
- 0.0f, 16.0f, 0.25f);
- }
- void VehicleGameObj::Apply_Damage( const OffenseObjectClass & damager, float scale, int alternate_skin )
- {
- float starting_health = Get_Defense_Object()->Get_Health();
- //
- // Let the base class actually handle the call
- //
- SmartGameObj::Apply_Damage( damager, scale, alternate_skin );
- // Stats
- if ( starting_health > 0 && Get_Defense_Object()->Get_Health() <= 0 ) {
- if ( damager.Get_Owner() && damager.Get_Owner()->As_SoldierGameObj() != NULL ) {
- if ( damager.Get_Owner()->As_SoldierGameObj()->Get_Player_Data() != NULL ) {
- damager.Get_Owner()->As_SoldierGameObj()->Get_Player_Data()->Stats_Add_Vehicle_Destroyed();
- }
- }
- }
- //
- // Now make sure the model is in a state to match its damage level
- //
- Update_Damage_Meshes();
- }
- void VehicleGameObj::Update_Damage_Meshes( void )
- {
- //
- // Calculate what percent health we have after this damage
- //
- DefenseObjectClass *defense_object = Get_Defense_Object();
- if ( defense_object != NULL ) {
- float ending_health = defense_object->Get_Health() / defense_object->Get_Health_Max();
- //
- // Make sure we have a render object to lookup bones on
- //
- RenderObjClass *model = Peek_Model ();
- if (model != NULL) {
- bool show_damage25 = false;
- bool show_damage50 = false;
- bool show_damage75 = false;
- //
- // Determine what the visibility state of these bones should be
- //
- if (ending_health < 0.25F) {
- show_damage25 = true;
- show_damage50 = true;
- show_damage75 = true;
- } else if (ending_health < 0.5F) {
- show_damage25 = true;
- show_damage50 = true;
- } else if (ending_health < 0.75F) {
- show_damage25 = true;
- }
- static const char * DAMAGE25_BONE_NAME = "DAMAGE25";
- static const char * DAMAGE50_BONE_NAME = "DAMAGE50";
- static const char * DAMAGE75_BONE_NAME = "DAMAGE75";
- static int DAMAGE25_BONE_NAME_LEN = ::strlen( DAMAGE25_BONE_NAME );
- static int DAMAGE50_BONE_NAME_LEN = ::strlen( DAMAGE50_BONE_NAME );
- static int DAMAGE75_BONE_NAME_LEN = ::strlen( DAMAGE75_BONE_NAME );
- //
- // Loop over all the bones in the model, showing and hiding any that represent
- // damage levels
- //
- int bone_count = model->Get_Num_Bones();
- for ( int index = 0; index < bone_count; index ++) {
- const char *bone_name = model->Get_Bone_Name( index );
- if ( ::strnicmp( bone_name, DAMAGE25_BONE_NAME, DAMAGE25_BONE_NAME_LEN ) == 0 ) {
- //
- // Show/hide the subobjects associated with 25% damage
- //
- ::Set_Subobject_Visibility( model, index, show_damage25 );
- } else if ( ::strnicmp( bone_name, DAMAGE50_BONE_NAME, DAMAGE50_BONE_NAME_LEN ) == 0 ) {
- //
- // Show/hide the subobjects associated with 50% damage
- //
- ::Set_Subobject_Visibility( model, index, show_damage50 );
- } else if ( ::strnicmp( bone_name, DAMAGE75_BONE_NAME, DAMAGE75_BONE_NAME_LEN ) == 0 ) {
- //
- // Show/hide the subobjects associated with 75% damage
- //
- ::Set_Subobject_Visibility( model, index, show_damage75 );
- }
- }
- }
- }
- return ;
- }
- void Set_Subobject_Visibility (RenderObjClass *model, int bone_index, bool show)
- {
- WWASSERT( model != NULL );
- //
- // Loop over all the subobjects that are attached to this bone
- //
- int count = model->Get_Num_Sub_Objects_On_Bone( bone_index );
- for (int index = 0; index < count; index ++) {
- RenderObjClass *sub_obj = model->Get_Sub_Object_On_Bone(index, bone_index);
- if (sub_obj != NULL) {
- //
- // Show or hide this subobject
- //
- sub_obj->Set_Hidden (!show);
- sub_obj->Release_Ref();
- }
- }
- return ;
- }
- Matrix3D VehicleGameObj::Get_Look_Transform(void)
- {
- if ( Get_Definition().SightDownMuzzle ) {
- return Get_Muzzle();
- }
- return SmartGameObj::Get_Look_Transform();
- }
- const WCHAR * VehicleGameObj::Get_Vehicle_Name( void )
- {
- if ( Get_Definition().VehicleNameID != 0 ) {
- return TranslateDBClass::Get_String( Get_Definition().VehicleNameID );
- }
- return TRANSLATE(IDS_HUD_VEHICLE_NAME);
- }
- // Vehicles should explode when expired / flipped
- ExpirationReactionType VehicleGameObj::Object_Expired( PhysClass * observed_obj )
- {
- // Only on the server
- if ( CombatManager::I_Am_Server() ) {
- if ( Get_Definition().KilledExplosion != 0 && !Is_Delete_Pending() ) {
- Vector3 pos;
- Get_Position(&pos);
- WWASSERT(pos.Is_Valid());// most likely candidate for explosion damage bug....?
- ExplosionManager::Server_Explode( Get_Definition().KilledExplosion,pos,0 );
- }
- if ( !Is_Delete_Pending() ) {
- // notify the observers of killed
- const GameObjObserverList & observer_list = Get_Observers();
- for( int index = 0; index < observer_list.Count(); index++ ) {
- observer_list[ index ]->Killed( this, NULL );
- }
- }
- return SmartGameObj::Object_Expired( observed_obj );
- } else {
- return EXPIRATION_DENIED;
- }
- }
- /*
- **
- */
- SoldierGameObj * VehicleGameObj::Get_Driver(void)
- {
- if ( SeatOccupants.Length() > DRIVER_SEAT ) {
- return SeatOccupants[DRIVER_SEAT];
- }
- return NULL;
- }
- SoldierGameObj * VehicleGameObj::Get_Gunner(void)
- {
- if ( SeatOccupants.Length() > GUNNER_SEAT ) {
- return SeatOccupants[GUNNER_SEAT];
- }
- return NULL;
- }
- SoldierGameObj * VehicleGameObj::Get_Actual_Gunner(void)
- {
- SoldierGameObj * gunner = Get_Gunner();
- if ( gunner && !Get_Driver_Is_Gunner() ) {
- return gunner;
- }
- return Get_Driver();
- }
- float VehicleGameObj::Get_Stealth_Fade_Distance(void) const
- {
- if (IS_MISSION) {
- return GlobalSettingsDef::Get_Global_Settings()->Get_Stealth_Distance_Vehicle();
- } else {
- return GlobalSettingsDef::Get_Global_Settings()->Get_MP_Stealth_Distance_Vehicle();
- }
- }
- void VehicleGameObj::Set_Vehicle_Delivered(void)
- {
- VehicleDelivered = true;
- Set_Object_Dirty_Bit( NetworkObjectClass::BIT_RARE, true );
- }
- float VehicleGameObj::Get_Filter_Distance(void) const
- {
- if (Get_Definition().Type == VEHICLE_TYPE_TURRET) {
- WeaponClass *weapon = ((VehicleGameObj*)this)->Get_Weapon();
- float range = Get_Definition().SightRange;
- if (weapon != NULL) {
- range = min(weapon->Get_Range(), range);
- }
- return(range);
- }
- return(SmartGameObj::Get_Filter_Distance());
- }
- void VehicleGameObj::Ignore_Occupants( void )
- {
- for (int i = 0; i < SeatOccupants.Length(); i++) {
- if (SeatOccupants[i] != NULL) {
- if ( SeatOccupants[i]->Peek_Physical_Object() != NULL ) {
- SeatOccupants[i]->Peek_Physical_Object()->Inc_Ignore_Counter();
- }
- }
- }
- }
- void VehicleGameObj::Unignore_Occupants( void )
- {
- for (int i = 0; i < SeatOccupants.Length(); i++) {
- if (SeatOccupants[i] != NULL) {
- if ( SeatOccupants[i]->Peek_Physical_Object() != NULL ) {
- SeatOccupants[i]->Peek_Physical_Object()->Dec_Ignore_Counter();
- }
- }
- }
- }
- /*
- Vector3 current_position;
- Get_Position(¤t_position);
- Vector3 pos_error = current_position - sc_position;
- if (pos_error.Length() > 2.0f && Is_Attached_To_An_Object () == false) {
- Matrix3D tm(q, sc_position);
- p_obj->Set_Transform(tm);
- p_obj->Set_Velocity(vel);
- p_obj->Set_Angular_Velocity(ang_vel);
- } else if (Is_Attached_To_An_Object ()) {
- Debug_Say(( "Skipping vehicle position update - attached to bone.\n" ));
- }
- */
- /*
- // New temporary scheme : constantly correct to server position by linearly
- // interpolating a fraction of the error
- //
- Matrix3D dest_tm(q, sc_position);
- Matrix3D tm = ::Lerp(Get_Transform (), dest_tm, 0.1F);
- p_obj->Set_Transform(tm);
- p_obj->Set_Velocity(vel);
- p_obj->Set_Angular_Velocity(ang_vel);
- */
- /*
- packet.Add_Vector3(pos);
- packet.Add_Quaternion(q);
- packet.Add_Vector3(vel);
- packet.Add_Vector3(ang_vel);
- */
- /*
- void VehicleGameObj::Import_State_Sc(BitStreamClass & packet)
- {
- WWASSERT(CombatManager::I_Am_Only_Client());
- if (Get_Weapon() != NULL) {
- int rounds = packet.Get(rounds);
- Get_Weapon()->Set_Total_Rounds(rounds);
- }
- for (int i = 0; i < NUM_SEATS; i++) {
- int occupant = packet.Get(occupant);
- if (occupant == -1) {
- Seats[i] = NULL;
- } else {
- if ((Seats[i] == NULL) || (Seats[i]->Get_ID() != occupant)) {
- SmartGameObj * obj = GameObjManager::Find_SmartGameObj(occupant);
- Seats[i] = NULL;
- if (obj != NULL) {
- Seats[i] = obj->As_SoldierGameObj();
- }
- }
- }
- }
- switch(Get_Definition().Type) {
- case VEHICLE_TYPE_BIKE:
- case VEHICLE_TYPE_CAR:
- case VEHICLE_TYPE_TANK:
- {
- VehiclePhysClass * p_obj = Peek_Vehicle_Phys();
- WWASSERT(p_obj != NULL);
- Vector3 sc_position;
- Quaternion q;
- Vector3 vel;
- Vector3 ang_vel;
- //packet.Get_Vector3(pos);
- //packet.Get_Quaternion(q);
- //packet.Get_Vector3(vel);
- //packet.Get_Vector3(ang_vel);
- packet.Get(sc_position.X, BITPACK_WORLD_POSITION_X);
- packet.Get(sc_position.Y, BITPACK_WORLD_POSITION_Y);
- packet.Get(sc_position.Z, BITPACK_WORLD_POSITION_Z);
- packet.Get(q.X, BITPACK_VEHICLE_QUATERNION);
- packet.Get(q.Y, BITPACK_VEHICLE_QUATERNION);
- packet.Get(q.Z, BITPACK_VEHICLE_QUATERNION);
- packet.Get(q.W, BITPACK_VEHICLE_QUATERNION);
- packet.Get(vel.X, BITPACK_VEHICLE_VELOCITY);
- packet.Get(vel.Y, BITPACK_VEHICLE_VELOCITY);
- packet.Get(vel.Z, BITPACK_VEHICLE_VELOCITY);
- packet.Get(ang_vel.X, BITPACK_VEHICLE_ANGULAR_VELOCITY);
- packet.Get(ang_vel.Y, BITPACK_VEHICLE_ANGULAR_VELOCITY);
- packet.Get(ang_vel.Z, BITPACK_VEHICLE_ANGULAR_VELOCITY);
- switch (CombatManager::Get_Client_Interpolation_Model()) {
- case CLIENT_INTERPOLATION_SERVER_AUTHORITATIVE:
- case CLIENT_INTERPOLATION_SERVER_AUTHORITATIVE_WITH_BLENDING:
- {
- //Matrix3D tm(q, sc_position);
- //p_obj->Set_Transform(tm);
- //p_obj->Set_Velocity(vel);
- //p_obj->Set_Angular_Velocity(ang_vel);
- Vector3 current_position;
- Get_Position(¤t_position);
- Vector3 pos_error = current_position - sc_position;
- if (pos_error.Length() > 2.0f) {
- Matrix3D tm(q, sc_position);
- p_obj->Set_Transform(tm);
- p_obj->Set_Velocity(vel);
- p_obj->Set_Angular_Velocity(ang_vel);
- }
- break;
- }
- case CLIENT_INTERPOLATION_PATHFIND: {
- SoldierGameObj * p_driver = Seats[DRIVER_SEAT];
- if (p_driver != NULL && p_driver->Get_Control_Owner() == CombatManager::Get_My_Id()) {
- Matrix3D tm(q, sc_position);
- p_obj->Set_Transform(tm);
- p_obj->Set_Velocity(vel);
- p_obj->Set_Angular_Velocity(ang_vel);
- } else {
- ActionParamsStruct parameters;
- parameters.Priority = 1;
- parameters.MoveLocation = sc_position;
- parameters.MoveArrivedDistance = 0.1f;
- WWASSERT(Get_Action() != NULL);
- Get_Action()->Goto(parameters);
- }
- break;
- }
- default:
- WWASSERT(0);
- }
- break;
- }
- case VEHICLE_TYPE_FLYING:
- break;
- case VEHICLE_TYPE_TURRET:
- break;
- default:
- WWASSERT( 0 );
- break;
- }
- SmartGameObj::Import_State_Sc(packet);
- WWASSERT(packet.Is_Flushed());
- }
- */
|