12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355 |
- /*
- ===========================================================================
- 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 );
- }
- if ( spawnArgs.GetBool( "spin" ) || gameLocal.isMultiplayer ) {
- spin = true;
- BecomeActive( TH_THINK );
- }
- //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;
- }
- /*
- ===============================================================================
- 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 );
- PostEventMS( &EV_CamShot, 250 );
- }
- /*
- ================
- idObjective::Spawn
- ================
- */
- void idObjective::Spawn( void ) {
- Hide();
- 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;
- // 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;
- }
- /*
- ================
- 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 );
- }
- /*
- ================
- idMoveableItem::Restore
- ================
- */
- void idMoveableItem::Restore( idRestoreGame *savefile ) {
- savefile->ReadStaticObject( physicsObj );
- RestorePhysics( &physicsObj );
- savefile->ReadClipModel( trigger );
- savefile->ReadParticle( smoke );
- savefile->ReadInt( smokeTime );
- }
- /*
- ================
- idMoveableItem::Spawn
- ================
- */
- void idMoveableItem::Spawn( void ) {
- idTraceModel trm;
- float density, friction, bouncyness, tsize;
- idStr clipModelName;
- idBounds bounds;
- // 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;
- 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 );
- }
- }
- /*
- ================
- 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() ) ) {
- smokeTime = 0;
- BecomeInactive( TH_UPDATEPARTICLES );
- }
- }
- Present();
- }
- /*
- ================
- 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 );
- }
- // 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" ) );
- player->hud->SetStateString( "objectivetitle", spawnArgs.GetString( "objectivetitle" ) );
- 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 );
- }
- }
- }
|