12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165 |
- /*
- ===========================================================================
- Doom 3 GPL Source Code
- Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company.
- This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?).
- Doom 3 Source Code 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.
- Doom 3 Source Code 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 Doom 3 Source Code. If not, see <http://www.gnu.org/licenses/>.
- In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below.
- If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA.
- ===========================================================================
- */
- #include "../idlib/precompiled.h"
- #pragma hdrstop
- #include "Game_local.h"
- /*
- ===============================================================================
- idItem
- ===============================================================================
- */
- const idEventDef EV_DropToFloor( "<dropToFloor>" );
- const idEventDef EV_RespawnItem( "respawn" );
- const idEventDef EV_RespawnFx( "<respawnFx>" );
- const idEventDef EV_GetPlayerPos( "<getplayerpos>" );
- const idEventDef EV_HideObjective( "<hideobjective>", "e" );
- const idEventDef EV_CamShot( "<camshot>" );
- CLASS_DECLARATION( idEntity, idItem )
- EVENT( EV_DropToFloor, idItem::Event_DropToFloor )
- EVENT( EV_Touch, idItem::Event_Touch )
- EVENT( EV_Activate, idItem::Event_Trigger )
- EVENT( EV_RespawnItem, idItem::Event_Respawn )
- EVENT( EV_RespawnFx, idItem::Event_RespawnFx )
- END_CLASS
- /*
- ================
- idItem::idItem
- ================
- */
- idItem::idItem() {
- spin = false;
- inView = false;
- inViewTime = 0;
- lastCycle = 0;
- lastRenderViewTime = -1;
- itemShellHandle = -1;
- shellMaterial = NULL;
- orgOrigin.Zero();
- canPickUp = true;
- fl.networkSync = true;
- }
- /*
- ================
- idItem::~idItem
- ================
- */
- idItem::~idItem() {
- // remove the highlight shell
- if ( itemShellHandle != -1 ) {
- gameRenderWorld->FreeEntityDef( itemShellHandle );
- }
- }
- /*
- ================
- idItem::Save
- ================
- */
- void idItem::Save( idSaveGame *savefile ) const {
- savefile->WriteVec3( orgOrigin );
- savefile->WriteBool( spin );
- savefile->WriteBool( pulse );
- savefile->WriteBool( canPickUp );
- savefile->WriteMaterial( shellMaterial );
- savefile->WriteBool( inView );
- savefile->WriteInt( inViewTime );
- savefile->WriteInt( lastCycle );
- savefile->WriteInt( lastRenderViewTime );
- }
- /*
- ================
- idItem::Restore
- ================
- */
- void idItem::Restore( idRestoreGame *savefile ) {
- savefile->ReadVec3( orgOrigin );
- savefile->ReadBool( spin );
- savefile->ReadBool( pulse );
- savefile->ReadBool( canPickUp );
- savefile->ReadMaterial( shellMaterial );
- savefile->ReadBool( inView );
- savefile->ReadInt( inViewTime );
- savefile->ReadInt( lastCycle );
- savefile->ReadInt( lastRenderViewTime );
- itemShellHandle = -1;
- }
- /*
- ================
- idItem::UpdateRenderEntity
- ================
- */
- bool idItem::UpdateRenderEntity( renderEntity_s *renderEntity, const renderView_t *renderView ) const {
- if ( lastRenderViewTime == renderView->time ) {
- return false;
- }
- lastRenderViewTime = renderView->time;
- // check for glow highlighting if near the center of the view
- idVec3 dir = renderEntity->origin - renderView->vieworg;
- dir.Normalize();
- float d = dir * renderView->viewaxis[0];
- // two second pulse cycle
- float cycle = ( renderView->time - inViewTime ) / 2000.0f;
- if ( d > 0.94f ) {
- if ( !inView ) {
- inView = true;
- if ( cycle > lastCycle ) {
- // restart at the beginning
- inViewTime = renderView->time;
- cycle = 0.0f;
- }
- }
- } else {
- if ( inView ) {
- inView = false;
- lastCycle = ceil( cycle );
- }
- }
- // fade down after the last pulse finishes
- if ( !inView && cycle > lastCycle ) {
- renderEntity->shaderParms[4] = 0.0f;
- } else {
- // pulse up in 1/4 second
- cycle -= (int)cycle;
- if ( cycle < 0.1f ) {
- renderEntity->shaderParms[4] = cycle * 10.0f;
- } else if ( cycle < 0.2f ) {
- renderEntity->shaderParms[4] = 1.0f;
- } else if ( cycle < 0.3f ) {
- renderEntity->shaderParms[4] = 1.0f - ( cycle - 0.2f ) * 10.0f;
- } else {
- // stay off between pulses
- renderEntity->shaderParms[4] = 0.0f;
- }
- }
- // update every single time this is in view
- return true;
- }
- /*
- ================
- idItem::ModelCallback
- ================
- */
- bool idItem::ModelCallback( renderEntity_t *renderEntity, const renderView_t *renderView ) {
- const idItem *ent;
- // this may be triggered by a model trace or other non-view related source
- if ( !renderView ) {
- return false;
- }
- ent = static_cast<idItem *>(gameLocal.entities[ renderEntity->entityNum ]);
- if ( !ent ) {
- gameLocal.Error( "idItem::ModelCallback: callback with NULL game entity" );
- }
- return ent->UpdateRenderEntity( renderEntity, renderView );
- }
- /*
- ================
- idItem::Think
- ================
- */
- void idItem::Think( void ) {
- if ( thinkFlags & TH_THINK ) {
- if ( spin ) {
- idAngles ang;
- idVec3 org;
- ang.pitch = ang.roll = 0.0f;
- ang.yaw = ( gameLocal.time & 4095 ) * 360.0f / -4096.0f;
- SetAngles( ang );
- float scale = 0.005f + entityNumber * 0.00001f;
-
- org = orgOrigin;
- org.z += 4.0f + cos( ( gameLocal.time + 2000 ) * scale ) * 4.0f;
- SetOrigin( org );
- }
- }
- Present();
- }
- /*
- ================
- idItem::Present
- ================
- */
- void idItem::Present( void ) {
- idEntity::Present();
- if ( !fl.hidden && pulse ) {
- // also add a highlight shell model
- renderEntity_t shell;
- shell = renderEntity;
- // we will mess with shader parms when the item is in view
- // to give the "item pulse" effect
- shell.callback = idItem::ModelCallback;
- shell.entityNum = entityNumber;
- shell.customShader = shellMaterial;
- if ( itemShellHandle == -1 ) {
- itemShellHandle = gameRenderWorld->AddEntityDef( &shell );
- } else {
- gameRenderWorld->UpdateEntityDef( itemShellHandle, &shell );
- }
- }
- }
- /*
- ================
- idItem::Spawn
- ================
- */
- void idItem::Spawn( void ) {
- idStr giveTo;
- idEntity * ent;
- float tsize;
- if ( spawnArgs.GetBool( "dropToFloor" ) ) {
- PostEventMS( &EV_DropToFloor, 0 );
- }
- if ( spawnArgs.GetFloat( "triggersize", "0", tsize ) ) {
- GetPhysics()->GetClipModel()->LoadModel( idTraceModel( idBounds( vec3_origin ).Expand( tsize ) ) );
- GetPhysics()->GetClipModel()->Link( gameLocal.clip );
- }
- if ( spawnArgs.GetBool( "start_off" ) ) {
- GetPhysics()->SetContents( 0 );
- Hide();
- } else {
- GetPhysics()->SetContents( CONTENTS_TRIGGER );
- }
- giveTo = spawnArgs.GetString( "owner" );
- if ( giveTo.Length() ) {
- ent = gameLocal.FindEntity( giveTo );
- if ( !ent ) {
- gameLocal.Error( "Item couldn't find owner '%s'", giveTo.c_str() );
- }
- PostEventMS( &EV_Touch, 0, ent, NULL );
- }
- #ifdef CTF
- // idItemTeam does not rotate and bob
- if ( spawnArgs.GetBool( "spin" ) || (gameLocal.isMultiplayer && !this->IsType( idItemTeam::Type ) ) ) {
- spin = true;
- BecomeActive( TH_THINK );
- }
- #else
- if ( spawnArgs.GetBool( "spin" ) || gameLocal.isMultiplayer ) {
- spin = true;
- BecomeActive( TH_THINK );
- }
- #endif
- //pulse = !spawnArgs.GetBool( "nopulse" );
- //temp hack for tim
- pulse = false;
- orgOrigin = GetPhysics()->GetOrigin();
- canPickUp = !( spawnArgs.GetBool( "triggerFirst" ) || spawnArgs.GetBool( "no_touch" ) );
- inViewTime = -1000;
- lastCycle = -1;
- itemShellHandle = -1;
- shellMaterial = declManager->FindMaterial( "itemHighlightShell" );
- }
- /*
- ================
- idItem::GetAttributes
- ================
- */
- void idItem::GetAttributes( idDict &attributes ) {
- int i;
- const idKeyValue *arg;
- for( i = 0; i < spawnArgs.GetNumKeyVals(); i++ ) {
- arg = spawnArgs.GetKeyVal( i );
- if ( arg->GetKey().Left( 4 ) == "inv_" ) {
- attributes.Set( arg->GetKey().Right( arg->GetKey().Length() - 4 ), arg->GetValue() );
- }
- }
- }
- /*
- ================
- idItem::GiveToPlayer
- ================
- */
- bool idItem::GiveToPlayer( idPlayer *player ) {
- if ( player == NULL ) {
- return false;
- }
- if ( spawnArgs.GetBool( "inv_carry" ) ) {
- return player->GiveInventoryItem( &spawnArgs );
- }
-
- return player->GiveItem( this );
- }
- /*
- ================
- idItem::Pickup
- ================
- */
- bool idItem::Pickup( idPlayer *player ) {
-
- if ( !GiveToPlayer( player ) ) {
- return false;
- }
- if ( gameLocal.isServer ) {
- ServerSendEvent( EVENT_PICKUP, NULL, false, -1 );
- }
- // play pickup sound
- StartSound( "snd_acquire", SND_CHANNEL_ITEM, 0, false, NULL );
- // trigger our targets
- ActivateTargets( player );
- // clear our contents so the object isn't picked up twice
- GetPhysics()->SetContents( 0 );
- // hide the model
- Hide();
- // add the highlight shell
- if ( itemShellHandle != -1 ) {
- gameRenderWorld->FreeEntityDef( itemShellHandle );
- itemShellHandle = -1;
- }
- float respawn = spawnArgs.GetFloat( "respawn" );
- bool dropped = spawnArgs.GetBool( "dropped" );
- bool no_respawn = spawnArgs.GetBool( "no_respawn" );
- if ( gameLocal.isMultiplayer && respawn == 0.0f ) {
- respawn = 20.0f;
- }
- if ( respawn && !dropped && !no_respawn ) {
- const char *sfx = spawnArgs.GetString( "fxRespawn" );
- if ( sfx && *sfx ) {
- PostEventSec( &EV_RespawnFx, respawn - 0.5f );
- }
- PostEventSec( &EV_RespawnItem, respawn );
- } else if ( !spawnArgs.GetBool( "inv_objective" ) && !no_respawn ) {
- // give some time for the pickup sound to play
- // FIXME: Play on the owner
- if ( !spawnArgs.GetBool( "inv_carry" ) ) {
- PostEventMS( &EV_Remove, 5000 );
- }
- }
- BecomeInactive( TH_THINK );
- return true;
- }
- /*
- ================
- idItem::ClientPredictionThink
- ================
- */
- void idItem::ClientPredictionThink( void ) {
- // only think forward because the state is not synced through snapshots
- if ( !gameLocal.isNewFrame ) {
- return;
- }
- Think();
- }
- /*
- ================
- idItem::WriteFromSnapshot
- ================
- */
- void idItem::WriteToSnapshot( idBitMsgDelta &msg ) const {
- msg.WriteBits( IsHidden(), 1 );
- }
- /*
- ================
- idItem::ReadFromSnapshot
- ================
- */
- void idItem::ReadFromSnapshot( const idBitMsgDelta &msg ) {
- if ( msg.ReadBits( 1 ) ) {
- Hide();
- } else {
- Show();
- }
- }
- /*
- ================
- idItem::ClientReceiveEvent
- ================
- */
- bool idItem::ClientReceiveEvent( int event, int time, const idBitMsg &msg ) {
- switch( event ) {
- case EVENT_PICKUP: {
- // play pickup sound
- StartSound( "snd_acquire", SND_CHANNEL_ITEM, 0, false, NULL );
- // hide the model
- Hide();
- // remove the highlight shell
- if ( itemShellHandle != -1 ) {
- gameRenderWorld->FreeEntityDef( itemShellHandle );
- itemShellHandle = -1;
- }
- return true;
- }
- case EVENT_RESPAWN: {
- Event_Respawn();
- return true;
- }
- case EVENT_RESPAWNFX: {
- Event_RespawnFx();
- return true;
- }
- default: {
- return idEntity::ClientReceiveEvent( event, time, msg );
- }
- }
- return false;
- }
- /*
- ================
- idItem::Event_DropToFloor
- ================
- */
- void idItem::Event_DropToFloor( void ) {
- trace_t trace;
- // don't drop the floor if bound to another entity
- if ( GetBindMaster() != NULL && GetBindMaster() != this ) {
- return;
- }
- gameLocal.clip.TraceBounds( trace, renderEntity.origin, renderEntity.origin - idVec3( 0, 0, 64 ), renderEntity.bounds, MASK_SOLID | CONTENTS_CORPSE, this );
- SetOrigin( trace.endpos );
- }
- /*
- ================
- idItem::Event_Touch
- ================
- */
- void idItem::Event_Touch( idEntity *other, trace_t *trace ) {
- if ( !other->IsType( idPlayer::Type ) ) {
- return;
- }
- if ( !canPickUp ) {
- return;
- }
- Pickup( static_cast<idPlayer *>(other) );
- }
- /*
- ================
- idItem::Event_Trigger
- ================
- */
- void idItem::Event_Trigger( idEntity *activator ) {
- if ( !canPickUp && spawnArgs.GetBool( "triggerFirst" ) ) {
- canPickUp = true;
- return;
- }
- if ( activator && activator->IsType( idPlayer::Type ) ) {
- Pickup( static_cast<idPlayer *>( activator ) );
- }
- }
- /*
- ================
- idItem::Event_Respawn
- ================
- */
- void idItem::Event_Respawn( void ) {
- if ( gameLocal.isServer ) {
- ServerSendEvent( EVENT_RESPAWN, NULL, false, -1 );
- }
- BecomeActive( TH_THINK );
- Show();
- inViewTime = -1000;
- lastCycle = -1;
- GetPhysics()->SetContents( CONTENTS_TRIGGER );
- SetOrigin( orgOrigin );
- StartSound( "snd_respawn", SND_CHANNEL_ITEM, 0, false, NULL );
- CancelEvents( &EV_RespawnItem ); // don't double respawn
- }
- /*
- ================
- idItem::Event_RespawnFx
- ================
- */
- void idItem::Event_RespawnFx( void ) {
- if ( gameLocal.isServer ) {
- ServerSendEvent( EVENT_RESPAWNFX, NULL, false, -1 );
- }
- const char *sfx = spawnArgs.GetString( "fxRespawn" );
- if ( sfx && *sfx ) {
- idEntityFx::StartFx( sfx, NULL, NULL, this, true );
- }
- }
- /*
- ===============================================================================
- idItemPowerup
- ===============================================================================
- */
- /*
- ===============
- idItemPowerup
- ===============
- */
- CLASS_DECLARATION( idItem, idItemPowerup )
- END_CLASS
- /*
- ================
- idItemPowerup::idItemPowerup
- ================
- */
- idItemPowerup::idItemPowerup() {
- time = 0;
- type = 0;
- }
- /*
- ================
- idItemPowerup::Save
- ================
- */
- void idItemPowerup::Save( idSaveGame *savefile ) const {
- savefile->WriteInt( time );
- savefile->WriteInt( type );
- }
- /*
- ================
- idItemPowerup::Restore
- ================
- */
- void idItemPowerup::Restore( idRestoreGame *savefile ) {
- savefile->ReadInt( time );
- savefile->ReadInt( type );
- }
- /*
- ================
- idItemPowerup::Spawn
- ================
- */
- void idItemPowerup::Spawn( void ) {
- time = spawnArgs.GetInt( "time", "30" );
- type = spawnArgs.GetInt( "type", "0" );
- }
- /*
- ================
- idItemPowerup::GiveToPlayer
- ================
- */
- bool idItemPowerup::GiveToPlayer( idPlayer *player ) {
- if ( player->spectating ) {
- return false;
- }
- player->GivePowerUp( type, time * 1000 );
- return true;
- }
- #ifdef CTF
- /*
- ===============================================================================
- idItemTeam
- Used for flags in Capture the Flag
- ===============================================================================
- */
- // temporarely removed these events
- const idEventDef EV_FlagReturn( "flagreturn", "e" );
- const idEventDef EV_TakeFlag( "takeflag", "e" );
- const idEventDef EV_DropFlag( "dropflag", "d" );
- const idEventDef EV_FlagCapture( "flagcapture" );
- CLASS_DECLARATION( idItem, idItemTeam )
- EVENT( EV_FlagReturn, idItemTeam::Event_FlagReturn )
- EVENT( EV_TakeFlag, idItemTeam::Event_TakeFlag )
- EVENT( EV_DropFlag, idItemTeam::Event_DropFlag )
- EVENT( EV_FlagCapture, idItemTeam::Event_FlagCapture )
- END_CLASS
- /*
- ===============
- idItemTeam::idItemTeam
- ===============
- */
- idItemTeam::idItemTeam() {
- team = -1;
- carried = false;
- dropped = false;
- lastDrop = 0;
- itemGlowHandle = -1;
- skinDefault = NULL;
- skinCarried = NULL;
- scriptTaken = NULL;
- scriptDropped = NULL;
- scriptReturned = NULL;
- scriptCaptured = NULL;
- lastNuggetDrop = 0;
- nuggetName = 0;
- }
- /*
- ===============
- idItemTeam::~idItemTeam
- ===============
- */
- idItemTeam::~idItemTeam() {
- FreeLightDef();
- }
- /*
- ===============
- idItemTeam::Spawn
- ===============
- */
- void idItemTeam::Spawn( void ) {
- team = spawnArgs.GetInt( "team" );
- returnOrigin = GetPhysics()->GetOrigin() + idVec3( 0, 0, 20 );
- returnAxis = GetPhysics()->GetAxis();
- BecomeActive( TH_THINK );
- const char * skinName;
- skinName = spawnArgs.GetString( "skin", "" );
- if ( skinName[0] )
- skinDefault = declManager->FindSkin( skinName );
- skinName = spawnArgs.GetString( "skin_carried", "" );
- if ( skinName[0] )
- skinCarried = declManager->FindSkin( skinName );
- nuggetName = spawnArgs.GetString( "nugget_name", "" );
- if ( !nuggetName[0] ) {
- nuggetName = NULL;
- }
- scriptTaken = LoadScript( "script_taken" );
- scriptDropped = LoadScript( "script_dropped" );
- scriptReturned = LoadScript( "script_returned" );
- scriptCaptured = LoadScript( "script_captured" );
- /* Spawn attached dlight */
- /*
- idDict args;
- idVec3 lightOffset( 0.0f, 20.0f, 0.0f );
- // Set up the flag's dynamic light
- memset( &itemGlow, 0, sizeof( itemGlow ) );
- itemGlow.axis = mat3_identity;
- itemGlow.lightRadius.x = 128.0f;
- itemGlow.lightRadius.y = itemGlow.lightRadius.z = itemGlow.lightRadius.x;
- itemGlow.noShadows = true;
- itemGlow.pointLight = true;
- itemGlow.shaderParms[ SHADERPARM_RED ] = 0.0f;
- itemGlow.shaderParms[ SHADERPARM_GREEN ] = 0.0f;
- itemGlow.shaderParms[ SHADERPARM_BLUE ] = 0.0f;
- itemGlow.shaderParms[ SHADERPARM_ALPHA ] = 0.0f;
- // Select a shader based on the team
- if ( team == 0 )
- itemGlow.shader = declManager->FindMaterial( "lights/redflag" );
- else
- itemGlow.shader = declManager->FindMaterial( "lights/blueflag" );
- */
- idMoveableItem::Spawn();
- physicsObj.SetContents( 0 );
- physicsObj.SetClipMask( MASK_SOLID | CONTENTS_MOVEABLECLIP );
- physicsObj.SetGravity( idVec3( 0, 0, spawnArgs.GetInt("gravity", "-30" ) ) );
- }
- /*
- ===============
- idItemTeam::LoadScript
- ===============
- */
- function_t * idItemTeam::LoadScript( char * script ) {
- function_t * function = NULL;
- idStr funcname = spawnArgs.GetString( script, "" );
- if ( funcname.Length() ) {
- function = gameLocal.program.FindFunction( funcname );
- if ( function == NULL ) {
- #ifdef _DEBUG
- gameLocal.Warning( "idItemTeam '%s' at (%s) calls unknown function '%s'", name.c_str(), GetPhysics()->GetOrigin().ToString(0), funcname.c_str() );
- #endif
- }
- }
- return function;
- }
- /*
- ===============
- idItemTeam::Think
- ===============
- */
- void idItemTeam::Think( void ) {
- idMoveableItem::Think();
- TouchTriggers();
- // TODO : only update on updatevisuals
- /*idVec3 offset( 0.0f, 0.0f, 20.0f );
- itemGlow.origin = GetPhysics()->GetOrigin() + offset;
- if ( itemGlowHandle == -1 ) {
- itemGlowHandle = gameRenderWorld->AddLightDef( &itemGlow );
- } else {
- gameRenderWorld->UpdateLightDef( itemGlowHandle, &itemGlow );
- }*/
- #if 1
- // should only the server do this?
- if ( gameLocal.isServer && nuggetName && carried && ( !lastNuggetDrop || (gameLocal.time - lastNuggetDrop) > spawnArgs.GetInt("nugget_frequency") ) ) {
- SpawnNugget( GetPhysics()->GetOrigin() );
- lastNuggetDrop = gameLocal.time;
- }
- #endif
- // return dropped flag after si_flagDropTimeLimit seconds
- if ( dropped && !carried && lastDrop != 0 && (gameLocal.time - lastDrop) > ( si_flagDropTimeLimit.GetInteger()*1000 ) ) {
- Return(); // return flag after 30 seconds on ground
- return;
- }
- }
- /*
- ===============
- idItemTeam::Pickup
- ===============
- */
- bool idItemTeam::Pickup( idPlayer *player ) {
- if ( !gameLocal.mpGame.IsGametypeFlagBased() ) /* CTF */
- return false;
- if ( gameLocal.mpGame.GetGameState() == idMultiplayerGame::WARMUP ||
- gameLocal.mpGame.GetGameState() == idMultiplayerGame::COUNTDOWN )
- return false;
- // wait 2 seconds after drop before beeing picked up again
- if ( lastDrop != 0 && (gameLocal.time - lastDrop) < spawnArgs.GetInt("pickupDelay", "500") )
- return false;
-
- if ( carried == false && player->team != this->team ) {
- PostEventMS( &EV_TakeFlag, 0, player );
- return true;
- } else if ( carried == false && dropped == true && player->team == this->team ) {
- gameLocal.mpGame.PlayerScoreCTF( player->entityNumber, 5 );
- // return flag
- PostEventMS( &EV_FlagReturn, 0, player );
- return false;
- }
- return false;
- }
- /*
- ===============
- idItemTeam::ClientReceiveEvent
- ===============
- */
- bool idItemTeam::ClientReceiveEvent( int event, int time, const idBitMsg &msg ) {
- gameLocal.DPrintf("ClientRecieveEvent: %i\n", event );
- switch ( event ) {
- case EVENT_TAKEFLAG: {
- idPlayer * player = static_cast<idPlayer *>(gameLocal.entities[ msg.ReadBits( GENTITYNUM_BITS ) ]);
- if ( player == NULL ) {
- gameLocal.Warning( "NULL player takes flag?\n" );
- return false;
- }
- Event_TakeFlag( player );
- }
- return true;
- case EVENT_DROPFLAG : {
- bool death = bool( msg.ReadBits( 1 ) == 1 );
- Event_DropFlag( death );
- }
- return true;
- case EVENT_FLAGRETURN : {
- Hide();
- FreeModelDef();
- FreeLightDef();
- Event_FlagReturn();
- }
- return true;
- case EVENT_FLAGCAPTURE : {
- Hide();
- FreeModelDef();
- FreeLightDef();
- Event_FlagCapture();
- }
- return true;
- };
- return false;
- }
- /*
- ================
- idItemTeam::Drop
- ================
- */
- void idItemTeam::Drop( bool death )
- {
- // PostEventMS( &EV_DropFlag, 0, int(death == true) );
- // had to remove the delayed drop because of drop flag on disconnect
- Event_DropFlag( death );
- }
- /*
- ================
- idItemTeam::Return
- ================
- */
- void idItemTeam::Return( idPlayer * player )
- {
- if ( team != 0 && team != 1 )
- return;
- // PostEventMS( &EV_FlagReturn, 0 );
- Event_FlagReturn();
- }
- /*
- ================
- idItemTeam::Capture
- ================
- */
- void idItemTeam::Capture( void )
- {
- if ( team != 0 && team != 1 )
- return;
- PostEventMS( &EV_FlagCapture, 0 );
- }
- /*
- ================
- idItemTeam::PrivateReturn
- ================
- */
- void idItemTeam::PrivateReturn( void )
- {
- Unbind();
- if ( gameLocal.isServer && carried && !dropped ) {
- int playerIdx = gameLocal.mpGame.GetFlagCarrier( 1-team );
- if ( playerIdx != -1 ) {
- idPlayer * player = static_cast<idPlayer*>( gameLocal.entities[ playerIdx ] );
- player->carryingFlag = false;
- } else {
- gameLocal.Warning( "BUG: carried flag has no carrier before return" );
- }
- }
- dropped = false;
- carried = false;
- SetOrigin( returnOrigin );
- SetAxis( returnAxis );
- trigger->Link( gameLocal.clip, this, 0, GetPhysics()->GetOrigin(), mat3_identity );
- SetSkin( skinDefault );
- // Turn off the light
- /*itemGlow.shaderParms[ SHADERPARM_RED ] = 0.0f;
- itemGlow.shaderParms[ SHADERPARM_GREEN ] = 0.0f;
- itemGlow.shaderParms[ SHADERPARM_BLUE ] = 0.0f;
- itemGlow.shaderParms[ SHADERPARM_ALPHA ] = 0.0f;
- if ( itemGlowHandle != -1 )
- gameRenderWorld->UpdateLightDef( itemGlowHandle, &itemGlow );*/
- GetPhysics()->SetLinearVelocity( idVec3(0, 0, 0) );
- GetPhysics()->SetAngularVelocity( idVec3(0, 0, 0) );
- }
- /*
- ================
- idItemTeam::Event_TakeFlag
- ================
- */
- void idItemTeam::Event_TakeFlag( idPlayer * player ) {
- gameLocal.DPrintf("Event_TakeFlag()!\n");
- if ( gameLocal.isServer ) {
- idBitMsg msg;
- byte msgBuf[MAX_EVENT_PARAM_SIZE];
- // Send the event
- msg.Init( msgBuf, sizeof( msgBuf ) );
- msg.BeginWriting();
- msg.WriteBits( player->entityNumber, GENTITYNUM_BITS );
- ServerSendEvent( EVENT_TAKEFLAG, &msg, false, -1 );
- gameLocal.mpGame.PlayTeamSound( player->team, SND_FLAG_TAKEN_THEIRS );
- gameLocal.mpGame.PlayTeamSound( team, SND_FLAG_TAKEN_YOURS );
- gameLocal.mpGame.PrintMessageEvent( -1, idMultiplayerGame::MSG_FLAGTAKEN, team, player->entityNumber );
- // dont drop a nugget RIGHT away
- lastNuggetDrop = gameLocal.time - gameLocal.random.RandomInt( 1000 );
- }
- BindToJoint( player, g_flagAttachJoint.GetString(), true );
- idVec3 origin( g_flagAttachOffsetX.GetFloat(), g_flagAttachOffsetY.GetFloat(), g_flagAttachOffsetZ.GetFloat() );
- idAngles angle( g_flagAttachAngleX.GetFloat(), g_flagAttachAngleY.GetFloat(), g_flagAttachAngleZ.GetFloat() );
- SetAngles( angle );
- SetOrigin( origin );
- // Turn the light on
- /*itemGlow.shaderParms[ SHADERPARM_RED ] = 1.0f;
- itemGlow.shaderParms[ SHADERPARM_GREEN ] = 1.0f;
- itemGlow.shaderParms[ SHADERPARM_BLUE ] = 1.0f;
- itemGlow.shaderParms[ SHADERPARM_ALPHA ] = 1.0f;
- if ( itemGlowHandle != -1 )
- gameRenderWorld->UpdateLightDef( itemGlowHandle, &itemGlow );*/
- if ( scriptTaken ) {
- idThread *thread = new idThread();
- thread->CallFunction( scriptTaken, false );
- thread->DelayedStart( 0 );
- }
- dropped = false;
- carried = true;
- player->carryingFlag = true;
- SetSkin( skinCarried );
- UpdateVisuals();
- UpdateGuis();
- if ( gameLocal.isServer ) {
- if ( team == 0 )
- gameLocal.mpGame.player_red_flag = player->entityNumber;
- else
- gameLocal.mpGame.player_blue_flag = player->entityNumber;
- }
- }
- /*
- ================
- idItemTeam::Event_DropFlag
- ================
- */
- void idItemTeam::Event_DropFlag( bool death ) {
- gameLocal.DPrintf("Event_DropFlag()!\n");
- if ( gameLocal.isServer ) {
- idBitMsg msg;
- byte msgBuf[MAX_EVENT_PARAM_SIZE];
- // Send the event
- msg.Init( msgBuf, sizeof( msgBuf ) );
- msg.BeginWriting();
- msg.WriteBits( death, 1 );
- ServerSendEvent( EVENT_DROPFLAG, &msg, false, -1 );
- if ( gameLocal.mpGame.IsFlagMsgOn() ) {
- gameLocal.mpGame.PlayTeamSound( 1-team, SND_FLAG_DROPPED_THEIRS );
- gameLocal.mpGame.PlayTeamSound( team, SND_FLAG_DROPPED_YOURS );
- gameLocal.mpGame.PrintMessageEvent( -1, idMultiplayerGame::MSG_FLAGDROP, team );
- }
- }
- lastDrop = gameLocal.time;
- BecomeActive( TH_THINK );
- Show();
- if ( death )
- GetPhysics()->SetLinearVelocity( idVec3(0, 0, 0) );
- else
- GetPhysics()->SetLinearVelocity( idVec3(0, 0, 20) );
- GetPhysics()->SetAngularVelocity( idVec3(0, 0, 0) );
- // GetPhysics()->SetLinearVelocity( ( GetPhysics()->GetLinearVelocity() * GetBindMaster()->GetPhysics()->GetAxis() ) + GetBindMaster()->GetPhysics()->GetLinearVelocity() );
- if ( GetBindMaster() ) {
- const idBounds bounds = GetPhysics()->GetBounds();
- idVec3 origin = GetBindMaster()->GetPhysics()->GetOrigin() + idVec3(0, 0, ( bounds[1].z-bounds[0].z )*0.6f );
- Unbind();
- SetOrigin( origin );
- }
- idAngles angle = GetPhysics()->GetAxis().ToAngles();
- angle.roll = 0;
- angle.pitch = 0;
- SetAxis( angle.ToMat3() );
- dropped = true;
- carried = false;
- if ( scriptDropped ) {
- idThread *thread = new idThread();
- thread->CallFunction( scriptDropped, false );
- thread->DelayedStart( 0 );
- }
- SetSkin( skinDefault );
- UpdateVisuals();
- UpdateGuis();
- if ( gameLocal.isServer ) {
- if ( team == 0 )
- gameLocal.mpGame.player_red_flag = -1;
- else
- gameLocal.mpGame.player_blue_flag = -1;
-
- }
- }
- /*
- ================
- idItemTeam::Event_FlagReturn
- ================
- */
- void idItemTeam::Event_FlagReturn( idPlayer * player ) {
- gameLocal.DPrintf("Event_FlagReturn()!\n");
- if ( gameLocal.isServer ) {
- ServerSendEvent( EVENT_FLAGRETURN, NULL, false, -1 );
- if ( gameLocal.mpGame.IsFlagMsgOn() ) {
- gameLocal.mpGame.PlayTeamSound( 1-team, SND_FLAG_RETURN );
- gameLocal.mpGame.PlayTeamSound( team, SND_FLAG_RETURN );
- int entitynum = 255;
- if ( player ) {
- entitynum = player->entityNumber;
- }
- gameLocal.mpGame.PrintMessageEvent( -1, idMultiplayerGame::MSG_FLAGRETURN, team, entitynum );
- }
- }
- BecomeActive( TH_THINK );
- Show();
- PrivateReturn();
- if ( scriptReturned ) {
- idThread *thread = new idThread();
- thread->CallFunction( scriptReturned, false );
- thread->DelayedStart( 0 );
- }
- UpdateVisuals();
- UpdateGuis();
- // Present();
- if ( gameLocal.isServer ) {
- if ( team == 0 )
- gameLocal.mpGame.player_red_flag = -1;
- else
- gameLocal.mpGame.player_blue_flag = -1;
- }
- }
- /*
- ================
- idItemTeam::Event_FlagCapture
- ================
- */
- void idItemTeam::Event_FlagCapture( void ) {
- gameLocal.DPrintf("Event_FlagCapture()!\n");
- if ( gameLocal.isServer ) {
- ServerSendEvent( EVENT_FLAGCAPTURE, NULL, false, -1 );
- gameLocal.mpGame.PlayTeamSound( 1-team, SND_FLAG_CAPTURED_THEIRS );
- gameLocal.mpGame.PlayTeamSound( team, SND_FLAG_CAPTURED_YOURS );
- gameLocal.mpGame.TeamScoreCTF( 1-team, 1 );
- int playerIdx = gameLocal.mpGame.GetFlagCarrier( 1-team );
- if ( playerIdx != -1 ) {
- gameLocal.mpGame.PlayerScoreCTF( playerIdx, 10 );
- } else {
- playerIdx = 255;
- }
- gameLocal.mpGame.PrintMessageEvent( -1, idMultiplayerGame::MSG_FLAGCAPTURE, team, playerIdx );
- }
- BecomeActive( TH_THINK );
- Show();
- PrivateReturn();
- if ( scriptCaptured ) {
- idThread *thread = new idThread();
- thread->CallFunction( scriptCaptured, false );
- thread->DelayedStart( 0 );
- }
- UpdateVisuals();
- UpdateGuis();
-
- if ( gameLocal.isServer ) {
- if ( team == 0 )
- gameLocal.mpGame.player_red_flag = -1;
- else
- gameLocal.mpGame.player_blue_flag = -1;
- }
-
- }
- /*
- ================
- idItemTeam::FreeLightDef
- ================
- */
- void idItemTeam::FreeLightDef( void ) {
- if ( itemGlowHandle != -1 ) {
- gameRenderWorld->FreeLightDef( itemGlowHandle );
- itemGlowHandle = -1;
- }
- }
- /*
- ================
- idItemTeam::SpawnNugget
- ================
- */
- void idItemTeam::SpawnNugget( idVec3 pos ) {
- idAngles angle( gameLocal.random.RandomInt(spawnArgs.GetInt("nugget_pitch", "30")), gameLocal.random.RandomInt(spawnArgs.GetInt("nugget_yaw", "360" )), 0 );
- float velocity = float(gameLocal.random.RandomInt( 40 )+15);
- velocity *= spawnArgs.GetFloat("nugget_velocity", "1" );
- idEntity * ent = idMoveableItem::DropItem( nuggetName, pos, GetPhysics()->GetAxis(), angle.ToMat3()*idVec3(velocity, velocity, velocity), 0, spawnArgs.GetInt("nugget_removedelay") );
- idPhysics_RigidBody * physics = static_cast<idPhysics_RigidBody *>( ent->GetPhysics() );
- if ( physics && physics->IsType( idPhysics_RigidBody::Type ) ) {
- physics->DisableImpact();
- }
- }
- /*
- ================
- idItemTeam::Event_FlagCapture
- ================
- */
- void idItemTeam::WriteToSnapshot( idBitMsgDelta &msg ) const {
- msg.WriteBits( carried, 1 );
- msg.WriteBits( dropped, 1 );
- WriteBindToSnapshot( msg );
- idMoveableItem::WriteToSnapshot( msg );
- }
- /*
- ================
- idItemTeam::ReadFromSnapshot
- ================
- */
- void idItemTeam::ReadFromSnapshot( const idBitMsgDelta &msg ) {
- carried = msg.ReadBits( 1 ) == 1;
- dropped = msg.ReadBits( 1 ) == 1;
- ReadBindFromSnapshot( msg );
- if ( msg.HasChanged() )
- {
- UpdateGuis();
- if ( carried == true )
- SetSkin( skinCarried );
- else
- SetSkin( skinDefault );
- }
- idMoveableItem::ReadFromSnapshot( msg );
- }
- /*
- ================
- idItemTeam::UpdateGuis
- Update all client's huds wrt the flag status.
- ================
- */
- void idItemTeam::UpdateGuis( void ) {
- idPlayer *player;
-
- for ( int i = 0; i < gameLocal.numClients; i++ ) {
- player = static_cast<idPlayer *>( gameLocal.entities[ i ] );
- if ( player == NULL || player->hud == NULL )
- continue;
- player->hud->SetStateInt( "red_flagstatus", gameLocal.mpGame.GetFlagStatus( 0 ) );
- player->hud->SetStateInt( "blue_flagstatus", gameLocal.mpGame.GetFlagStatus( 1 ) );
- player->hud->SetStateInt( "red_team_score", gameLocal.mpGame.GetFlagPoints( 0 ) );
- player->hud->SetStateInt( "blue_team_score", gameLocal.mpGame.GetFlagPoints( 1 ) );
- }
- }
- /*
- ================
- idItemTeam::Present
- ================
- */
- void idItemTeam::Present( void ) {
- // hide the flag for localplayer if in first person
- if ( carried && GetBindMaster() ) {
- idPlayer * player = static_cast<idPlayer *>( GetBindMaster() );
- if ( player == gameLocal.GetLocalPlayer() && !pm_thirdPerson.GetBool() ) {
- FreeModelDef();
- BecomeActive( TH_UPDATEVISUALS );
- return;
- }
- }
- idEntity::Present();
- }
- #endif
- /*
- ===============================================================================
- idObjective
- ===============================================================================
- */
- CLASS_DECLARATION( idItem, idObjective )
- EVENT( EV_Activate, idObjective::Event_Trigger )
- EVENT( EV_HideObjective, idObjective::Event_HideObjective )
- EVENT( EV_GetPlayerPos, idObjective::Event_GetPlayerPos )
- EVENT( EV_CamShot, idObjective::Event_CamShot )
- END_CLASS
- /*
- ================
- idObjective::idObjective
- ================
- */
- idObjective::idObjective() {
- playerPos.Zero();
- }
- /*
- ================
- idObjective::Save
- ================
- */
- void idObjective::Save( idSaveGame *savefile ) const {
- savefile->WriteVec3( playerPos );
- }
- /*
- ================
- idObjective::Restore
- ================
- */
- void idObjective::Restore( idRestoreGame *savefile ) {
- savefile->ReadVec3( playerPos );
- }
- /*
- ================
- idObjective::Spawn
- ================
- */
- void idObjective::Spawn( void ) {
- Hide();
- if ( cvarSystem->GetCVarBool( "com_makingBuild") ) {
- PostEventMS( &EV_CamShot, 250 );
- }
- }
- /*
- ================
- idObjective::Event_Screenshot
- ================
- */
- void idObjective::Event_CamShot( ) {
- const char *camName;
- idStr shotName = gameLocal.GetMapName();
- shotName.StripFileExtension();
- shotName += "/";
- shotName += spawnArgs.GetString( "screenshot" );
- shotName.SetFileExtension( ".tga" );
- if ( spawnArgs.GetString( "camShot", "", &camName ) ) {
- idEntity *ent = gameLocal.FindEntity( camName );
- if ( ent && ent->cameraTarget ) {
- const renderView_t *view = ent->cameraTarget->GetRenderView();
- renderView_t fullView = *view;
- fullView.width = SCREEN_WIDTH;
- fullView.height = SCREEN_HEIGHT;
- #ifdef _D3XP
- // HACK : always draw sky-portal view if there is one in the map, this isn't real-time
- if ( gameLocal.portalSkyEnt.GetEntity() && g_enablePortalSky.GetBool() ) {
- renderView_t portalView = fullView;
- portalView.vieworg = gameLocal.portalSkyEnt.GetEntity()->GetPhysics()->GetOrigin();
- // setup global fixup projection vars
- if ( 1 ) {
- int vidWidth, vidHeight;
- idVec2 shiftScale;
- renderSystem->GetGLSettings( vidWidth, vidHeight );
- float pot;
- int temp;
- int w = vidWidth;
- for (temp = 1 ; temp < w ; temp<<=1) {
- }
- pot = (float)temp;
- shiftScale.x = (float)w / pot;
- int h = vidHeight;
- for (temp = 1 ; temp < h ; temp<<=1) {
- }
- pot = (float)temp;
- shiftScale.y = (float)h / pot;
- fullView.shaderParms[4] = shiftScale.x;
- fullView.shaderParms[5] = shiftScale.y;
- }
- gameRenderWorld->RenderScene( &portalView );
- renderSystem->CaptureRenderToImage( "_currentRender" );
- }
- #endif
- // draw a view to a texture
- renderSystem->CropRenderSize( 256, 256, true );
- gameRenderWorld->RenderScene( &fullView );
- renderSystem->CaptureRenderToFile( shotName );
- renderSystem->UnCrop();
- }
- }
- }
- /*
- ================
- idObjective::Event_Trigger
- ================
- */
- void idObjective::Event_Trigger( idEntity *activator ) {
- idPlayer *player = gameLocal.GetLocalPlayer();
- if ( player ) {
- //Pickup( player );
- if ( spawnArgs.GetString( "inv_objective", NULL ) ) {
- if ( player && player->hud ) {
- idStr shotName = gameLocal.GetMapName();
- shotName.StripFileExtension();
- shotName += "/";
- shotName += spawnArgs.GetString( "screenshot" );
- shotName.SetFileExtension( ".tga" );
- player->hud->SetStateString( "screenshot", shotName );
- player->hud->SetStateString( "objective", "1" );
- player->hud->SetStateString( "objectivetext", spawnArgs.GetString( "objectivetext" ) );
- player->hud->SetStateString( "objectivetitle", spawnArgs.GetString( "objectivetitle" ) );
- player->GiveObjective( spawnArgs.GetString( "objectivetitle" ), spawnArgs.GetString( "objectivetext" ), shotName );
- // a tad slow but keeps from having to update all objectives in all maps with a name ptr
- for( int i = 0; i < gameLocal.num_entities; i++ ) {
- if ( gameLocal.entities[ i ] && gameLocal.entities[ i ]->IsType( idObjectiveComplete::Type ) ) {
- if ( idStr::Icmp( spawnArgs.GetString( "objectivetitle" ), gameLocal.entities[ i ]->spawnArgs.GetString( "objectivetitle" ) ) == 0 ){
- gameLocal.entities[ i ]->spawnArgs.SetBool( "objEnabled", true );
- break;
- }
- }
- }
- PostEventMS( &EV_GetPlayerPos, 2000 );
- }
- }
- }
- }
- /*
- ================
- idObjective::Event_GetPlayerPos
- ================
- */
- void idObjective::Event_GetPlayerPos() {
- idPlayer *player = gameLocal.GetLocalPlayer();
- if ( player ) {
- playerPos = player->GetPhysics()->GetOrigin();
- PostEventMS( &EV_HideObjective, 100, player );
- }
- }
- /*
- ================
- idObjective::Event_HideObjective
- ================
- */
- void idObjective::Event_HideObjective(idEntity *e) {
- idPlayer *player = gameLocal.GetLocalPlayer();
- if ( player ) {
- idVec3 v = player->GetPhysics()->GetOrigin() - playerPos;
- if ( v.Length() > 64.0f ) {
- player->HideObjective();
- PostEventMS( &EV_Remove, 0 );
- } else {
- PostEventMS( &EV_HideObjective, 100, player );
- }
- }
- }
- /*
- ===============================================================================
- idVideoCDItem
- ===============================================================================
- */
- CLASS_DECLARATION( idItem, idVideoCDItem )
- END_CLASS
- /*
- ================
- idVideoCDItem::Spawn
- ================
- */
- void idVideoCDItem::Spawn( void ) {
- }
- /*
- ================
- idVideoCDItem::GiveToPlayer
- ================
- */
- bool idVideoCDItem::GiveToPlayer( idPlayer *player ) {
- idStr str = spawnArgs.GetString( "video" );
- if ( player && str.Length() ) {
- player->GiveVideo( str, &spawnArgs );
- }
- return true;
- }
- /*
- ===============================================================================
- idPDAItem
- ===============================================================================
- */
- CLASS_DECLARATION( idItem, idPDAItem )
- END_CLASS
- /*
- ================
- idPDAItem::GiveToPlayer
- ================
- */
- bool idPDAItem::GiveToPlayer(idPlayer *player) {
- const char *str = spawnArgs.GetString( "pda_name" );
- if ( player ) {
- player->GivePDA( str, &spawnArgs );
- }
- return true;
- }
- /*
- ===============================================================================
- idMoveableItem
-
- ===============================================================================
- */
- CLASS_DECLARATION( idItem, idMoveableItem )
- EVENT( EV_DropToFloor, idMoveableItem::Event_DropToFloor )
- EVENT( EV_Gib, idMoveableItem::Event_Gib )
- END_CLASS
- /*
- ================
- idMoveableItem::idMoveableItem
- ================
- */
- idMoveableItem::idMoveableItem() {
- trigger = NULL;
- smoke = NULL;
- smokeTime = 0;
- #ifdef _D3XP
- nextSoundTime = 0;
- #endif
- #ifdef CTF
- repeatSmoke = false;
- #endif
- }
- /*
- ================
- idMoveableItem::~idMoveableItem
- ================
- */
- idMoveableItem::~idMoveableItem() {
- if ( trigger ) {
- delete trigger;
- }
- }
- /*
- ================
- idMoveableItem::Save
- ================
- */
- void idMoveableItem::Save( idSaveGame *savefile ) const {
- savefile->WriteStaticObject( physicsObj );
- savefile->WriteClipModel( trigger );
- savefile->WriteParticle( smoke );
- savefile->WriteInt( smokeTime );
- #ifdef _D3XP
- savefile->WriteInt( nextSoundTime );
- #endif
- }
- /*
- ================
- idMoveableItem::Restore
- ================
- */
- void idMoveableItem::Restore( idRestoreGame *savefile ) {
- savefile->ReadStaticObject( physicsObj );
- RestorePhysics( &physicsObj );
- savefile->ReadClipModel( trigger );
- savefile->ReadParticle( smoke );
- savefile->ReadInt( smokeTime );
- #ifdef _D3XP
- savefile->ReadInt( nextSoundTime );
- #endif
- }
- /*
- ================
- idMoveableItem::Spawn
- ================
- */
- void idMoveableItem::Spawn( void ) {
- idTraceModel trm;
- float density, friction, bouncyness, tsize;
- idStr clipModelName;
- idBounds bounds;
- #ifdef _D3XP
- SetTimeState ts( timeGroup );
- #endif
- // create a trigger for item pickup
- spawnArgs.GetFloat( "triggersize", "16.0", tsize );
- trigger = new idClipModel( idTraceModel( idBounds( vec3_origin ).Expand( tsize ) ) );
- trigger->Link( gameLocal.clip, this, 0, GetPhysics()->GetOrigin(), GetPhysics()->GetAxis() );
- trigger->SetContents( CONTENTS_TRIGGER );
- // check if a clip model is set
- spawnArgs.GetString( "clipmodel", "", clipModelName );
- if ( !clipModelName[0] ) {
- clipModelName = spawnArgs.GetString( "model" ); // use the visual model
- }
- // load the trace model
- if ( !collisionModelManager->TrmFromModel( clipModelName, trm ) ) {
- gameLocal.Error( "idMoveableItem '%s': cannot load collision model %s", name.c_str(), clipModelName.c_str() );
- return;
- }
- // if the model should be shrinked
- if ( spawnArgs.GetBool( "clipshrink" ) ) {
- trm.Shrink( CM_CLIP_EPSILON );
- }
- // get rigid body properties
- spawnArgs.GetFloat( "density", "0.5", density );
- density = idMath::ClampFloat( 0.001f, 1000.0f, density );
- spawnArgs.GetFloat( "friction", "0.05", friction );
- friction = idMath::ClampFloat( 0.0f, 1.0f, friction );
- spawnArgs.GetFloat( "bouncyness", "0.6", bouncyness );
- bouncyness = idMath::ClampFloat( 0.0f, 1.0f, bouncyness );
- // setup the physics
- physicsObj.SetSelf( this );
- physicsObj.SetClipModel( new idClipModel( trm ), density );
- physicsObj.SetOrigin( GetPhysics()->GetOrigin() );
- physicsObj.SetAxis( GetPhysics()->GetAxis() );
- physicsObj.SetBouncyness( bouncyness );
- physicsObj.SetFriction( 0.6f, 0.6f, friction );
- physicsObj.SetGravity( gameLocal.GetGravity() );
- physicsObj.SetContents( CONTENTS_RENDERMODEL );
- physicsObj.SetClipMask( MASK_SOLID | CONTENTS_MOVEABLECLIP );
- SetPhysics( &physicsObj );
- smoke = NULL;
- smokeTime = 0;
- #ifdef _D3XP
- nextSoundTime = 0;
- #endif
- const char *smokeName = spawnArgs.GetString( "smoke_trail" );
- if ( *smokeName != '\0' ) {
- smoke = static_cast<const idDeclParticle *>( declManager->FindType( DECL_PARTICLE, smokeName ) );
- smokeTime = gameLocal.time;
- BecomeActive( TH_UPDATEPARTICLES );
- }
- #ifdef CTF
- repeatSmoke = spawnArgs.GetBool( "repeatSmoke", "0" );
- #endif
- }
- /*
- ================
- idMoveableItem::Think
- ================
- */
- void idMoveableItem::Think( void ) {
- RunPhysics();
- if ( thinkFlags & TH_PHYSICS ) {
- // update trigger position
- trigger->Link( gameLocal.clip, this, 0, GetPhysics()->GetOrigin(), mat3_identity );
- }
-
- if ( thinkFlags & TH_UPDATEPARTICLES ) {
- if ( !gameLocal.smokeParticles->EmitSmoke( smoke, smokeTime, gameLocal.random.CRandomFloat(), GetPhysics()->GetOrigin(), GetPhysics()->GetAxis(), timeGroup /*_D3XP*/ ) ) {
- #ifdef CTF
- if ( !repeatSmoke ) {
- smokeTime = 0;
- BecomeInactive( TH_UPDATEPARTICLES );
- } else {
- smokeTime = gameLocal.time;
- }
- #else
- smokeTime = 0;
- BecomeInactive( TH_UPDATEPARTICLES );
- #endif
- }
- }
- Present();
- }
- #ifdef _D3XP
- /*
- =================
- idMoveableItem::Collide
- =================
- */
- bool idMoveableItem::Collide( const trace_t &collision, const idVec3 &velocity ) {
- float v, f;
- v = -( velocity * collision.c.normal );
- if ( v > 80 && gameLocal.time > nextSoundTime ) {
- f = v > 200 ? 1.0f : idMath::Sqrt( v - 80 ) * 0.091f;
- if ( StartSound( "snd_bounce", SND_CHANNEL_ANY, 0, false, NULL ) ) {
- // don't set the volume unless there is a bounce sound as it overrides the entire channel
- // which causes footsteps on ai's to not honor their shader parms
- SetSoundVolume( f );
- }
- nextSoundTime = gameLocal.time + 500;
- }
- return false;
- }
- #endif
- /*
- ================
- idMoveableItem::Pickup
- ================
- */
- bool idMoveableItem::Pickup( idPlayer *player ) {
- bool ret = idItem::Pickup( player );
- if ( ret ) {
- trigger->SetContents( 0 );
- }
- return ret;
- }
- /*
- ================
- idMoveableItem::DropItem
- ================
- */
- idEntity *idMoveableItem::DropItem( const char *classname, const idVec3 &origin, const idMat3 &axis, const idVec3 &velocity, int activateDelay, int removeDelay ) {
- idDict args;
- idEntity *item;
- args.Set( "classname", classname );
- args.Set( "dropped", "1" );
- // we sometimes drop idMoveables here, so set 'nodrop' to 1 so that it doesn't get put on the floor
- args.Set( "nodrop", "1" );
- if ( activateDelay ) {
- args.SetBool( "triggerFirst", true );
- }
- gameLocal.SpawnEntityDef( args, &item );
- if ( item ) {
- // set item position
- item->GetPhysics()->SetOrigin( origin );
- item->GetPhysics()->SetAxis( axis );
- item->GetPhysics()->SetLinearVelocity( velocity );
- item->UpdateVisuals();
- if ( activateDelay ) {
- item->PostEventMS( &EV_Activate, activateDelay, item );
- }
- if ( !removeDelay ) {
- removeDelay = 5 * 60 * 1000;
- }
- // always remove a dropped item after 5 minutes in case it dropped to an unreachable location
- item->PostEventMS( &EV_Remove, removeDelay );
- }
- return item;
- }
- /*
- ================
- idMoveableItem::DropItems
- The entity should have the following key/value pairs set:
- "def_drop<type>Item" "item def"
- "drop<type>ItemJoint" "joint name"
- "drop<type>ItemRotation" "pitch yaw roll"
- "drop<type>ItemOffset" "x y z"
- "skin_drop<type>" "skin name"
- To drop multiple items the following key/value pairs can be used:
- "def_drop<type>Item<X>" "item def"
- "drop<type>Item<X>Joint" "joint name"
- "drop<type>Item<X>Rotation" "pitch yaw roll"
- "drop<type>Item<X>Offset" "x y z"
- where <X> is an aribtrary string.
- ================
- */
- void idMoveableItem::DropItems( idAnimatedEntity *ent, const char *type, idList<idEntity *> *list ) {
- const idKeyValue *kv;
- const char *skinName, *c, *jointName;
- idStr key, key2;
- idVec3 origin;
- idMat3 axis;
- idAngles angles;
- const idDeclSkin *skin;
- jointHandle_t joint;
- idEntity *item;
- // drop all items
- kv = ent->spawnArgs.MatchPrefix( va( "def_drop%sItem", type ), NULL );
- while ( kv ) {
- c = kv->GetKey().c_str() + kv->GetKey().Length();
- if ( idStr::Icmp( c - 5, "Joint" ) != 0 && idStr::Icmp( c - 8, "Rotation" ) != 0 ) {
- key = kv->GetKey().c_str() + 4;
- key2 = key;
- key += "Joint";
- key2 += "Offset";
- jointName = ent->spawnArgs.GetString( key );
- joint = ent->GetAnimator()->GetJointHandle( jointName );
- if ( !ent->GetJointWorldTransform( joint, gameLocal.time, origin, axis ) ) {
- gameLocal.Warning( "%s refers to invalid joint '%s' on entity '%s'\n", key.c_str(), jointName, ent->name.c_str() );
- origin = ent->GetPhysics()->GetOrigin();
- axis = ent->GetPhysics()->GetAxis();
- }
- if ( g_dropItemRotation.GetString()[0] ) {
- angles.Zero();
- sscanf( g_dropItemRotation.GetString(), "%f %f %f", &angles.pitch, &angles.yaw, &angles.roll );
- } else {
- key = kv->GetKey().c_str() + 4;
- key += "Rotation";
- ent->spawnArgs.GetAngles( key, "0 0 0", angles );
- }
- axis = angles.ToMat3() * axis;
- origin += ent->spawnArgs.GetVector( key2, "0 0 0" );
- item = DropItem( kv->GetValue(), origin, axis, vec3_origin, 0, 0 );
- if ( list && item ) {
- list->Append( item );
- }
- }
- kv = ent->spawnArgs.MatchPrefix( va( "def_drop%sItem", type ), kv );
- }
- // change the skin to hide all items
- skinName = ent->spawnArgs.GetString( va( "skin_drop%s", type ) );
- if ( skinName[0] ) {
- skin = declManager->FindSkin( skinName );
- ent->SetSkin( skin );
- }
- }
- /*
- ======================
- idMoveableItem::WriteToSnapshot
- ======================
- */
- void idMoveableItem::WriteToSnapshot( idBitMsgDelta &msg ) const {
- physicsObj.WriteToSnapshot( msg );
- }
- /*
- ======================
- idMoveableItem::ReadFromSnapshot
- ======================
- */
- void idMoveableItem::ReadFromSnapshot( const idBitMsgDelta &msg ) {
- physicsObj.ReadFromSnapshot( msg );
- if ( msg.HasChanged() ) {
- UpdateVisuals();
- }
- }
- /*
- ============
- idMoveableItem::Gib
- ============
- */
- void idMoveableItem::Gib( const idVec3 &dir, const char *damageDefName ) {
- // spawn smoke puff
- const char *smokeName = spawnArgs.GetString( "smoke_gib" );
- if ( *smokeName != '\0' ) {
- const idDeclParticle *smoke = static_cast<const idDeclParticle *>( declManager->FindType( DECL_PARTICLE, smokeName ) );
- gameLocal.smokeParticles->EmitSmoke( smoke, gameLocal.time, gameLocal.random.CRandomFloat(), renderEntity.origin, renderEntity.axis, timeGroup /*_D3XP*/ );
- }
- // remove the entity
- PostEventMS( &EV_Remove, 0 );
- }
- /*
- ================
- idMoveableItem::Event_DropToFloor
- ================
- */
- void idMoveableItem::Event_DropToFloor( void ) {
- // the physics will drop the moveable to the floor
- }
- /*
- ============
- idMoveableItem::Event_Gib
- ============
- */
- void idMoveableItem::Event_Gib( const char *damageDefName ) {
- Gib( idVec3( 0, 0, 1 ), damageDefName );
- }
- /*
- ===============================================================================
- idMoveablePDAItem
- ===============================================================================
- */
- CLASS_DECLARATION( idMoveableItem, idMoveablePDAItem )
- END_CLASS
- /*
- ================
- idMoveablePDAItem::GiveToPlayer
- ================
- */
- bool idMoveablePDAItem::GiveToPlayer(idPlayer *player) {
- const char *str = spawnArgs.GetString( "pda_name" );
- if ( player ) {
- player->GivePDA( str, &spawnArgs );
- }
- return true;
- }
- /*
- ===============================================================================
- idItemRemover
- ===============================================================================
- */
- CLASS_DECLARATION( idEntity, idItemRemover )
- EVENT( EV_Activate, idItemRemover::Event_Trigger )
- END_CLASS
- /*
- ================
- idItemRemover::Spawn
- ================
- */
- void idItemRemover::Spawn( void ) {
- }
- /*
- ================
- idItemRemover::RemoveItem
- ================
- */
- void idItemRemover::RemoveItem( idPlayer *player ) {
- const char *remove;
-
- remove = spawnArgs.GetString( "remove" );
- player->RemoveInventoryItem( remove );
- }
- /*
- ================
- idItemRemover::Event_Trigger
- ================
- */
- void idItemRemover::Event_Trigger( idEntity *activator ) {
- if ( activator->IsType( idPlayer::Type ) ) {
- RemoveItem( static_cast<idPlayer *>(activator) );
- }
- }
- /*
- ===============================================================================
- idObjectiveComplete
- ===============================================================================
- */
- CLASS_DECLARATION( idItemRemover, idObjectiveComplete )
- EVENT( EV_Activate, idObjectiveComplete::Event_Trigger )
- EVENT( EV_HideObjective, idObjectiveComplete::Event_HideObjective )
- EVENT( EV_GetPlayerPos, idObjectiveComplete::Event_GetPlayerPos )
- END_CLASS
- /*
- ================
- idObjectiveComplete::idObjectiveComplete
- ================
- */
- idObjectiveComplete::idObjectiveComplete() {
- playerPos.Zero();
- }
- /*
- ================
- idObjectiveComplete::Save
- ================
- */
- void idObjectiveComplete::Save( idSaveGame *savefile ) const {
- savefile->WriteVec3( playerPos );
- }
- /*
- ================
- idObjectiveComplete::Restore
- ================
- */
- void idObjectiveComplete::Restore( idRestoreGame *savefile ) {
- savefile->ReadVec3( playerPos );
- }
- /*
- ================
- idObjectiveComplete::Spawn
- ================
- */
- void idObjectiveComplete::Spawn( void ) {
- spawnArgs.SetBool( "objEnabled", false );
- Hide();
- }
- /*
- ================
- idObjectiveComplete::Event_Trigger
- ================
- */
- void idObjectiveComplete::Event_Trigger( idEntity *activator ) {
- if ( !spawnArgs.GetBool( "objEnabled" ) ) {
- return;
- }
- idPlayer *player = gameLocal.GetLocalPlayer();
- if ( player ) {
- RemoveItem( player );
- if ( spawnArgs.GetString( "inv_objective", NULL ) ) {
- if ( player->hud ) {
- player->hud->SetStateString( "objective", "2");
- player->hud->SetStateString( "objectivetext", spawnArgs.GetString( "objectivetext" ) );
- #ifdef _D3XP
- player->hud->SetStateString( "objectivecompletetitle", spawnArgs.GetString( "objectivetitle" ) );
- #else
- player->hud->SetStateString( "objectivetitle", spawnArgs.GetString( "objectivetitle" ) );
- #endif
- player->CompleteObjective( spawnArgs.GetString( "objectivetitle" ) );
- PostEventMS( &EV_GetPlayerPos, 2000 );
- }
- }
- }
- }
- /*
- ================
- idObjectiveComplete::Event_GetPlayerPos
- ================
- */
- void idObjectiveComplete::Event_GetPlayerPos() {
- idPlayer *player = gameLocal.GetLocalPlayer();
- if ( player ) {
- playerPos = player->GetPhysics()->GetOrigin();
- PostEventMS( &EV_HideObjective, 100, player );
- }
- }
- /*
- ================
- idObjectiveComplete::Event_HideObjective
- ================
- */
- void idObjectiveComplete::Event_HideObjective( idEntity *e ) {
- idPlayer *player = gameLocal.GetLocalPlayer();
- if ( player ) {
- idVec3 v = player->GetPhysics()->GetOrigin();
- v -= playerPos;
- if ( v.Length() > 64.0f ) {
- player->hud->HandleNamedEvent( "closeObjective" );
- PostEventMS( &EV_Remove, 0 );
- } else {
- PostEventMS( &EV_HideObjective, 100, player );
- }
- }
- }
|