void hhProxDoor::SpawnSoundTrigger() { idBounds bounds,localbounds; int i; int best; // Since models bounds are overestimated, we need to use the bounds from the // clipmodel, which was set before the over-estimation localbounds = GetPhysics()->GetBounds(); // find the thinnest axis, which will be the one we expand best = 0; for ( i = 1 ; i < 3 ; i++ ) { if ( localbounds[1][ i ] - localbounds[0][ i ] < localbounds[1][ best ] - localbounds[0][ best ] ) { best = i; } } localbounds[1][ best ] += 50; localbounds[0][ best ] -= 50; // Now transform into absolute coordintates if ( GetPhysics()->GetAxis().IsRotated() ) { bounds.FromTransformedBounds( localbounds, GetPhysics()->GetOrigin(), GetPhysics()->GetAxis() ); } else { bounds[0] = localbounds[0] + GetPhysics()->GetOrigin(); bounds[1] = localbounds[1] + GetPhysics()->GetOrigin(); } bounds[0] -= GetPhysics()->GetOrigin(); bounds[1] -= GetPhysics()->GetOrigin(); // create a trigger clip model sndTrigger = new idClipModel( idTraceModel( bounds ) ); sndTrigger->Link( gameLocal.clip, this, 254, GetPhysics()->GetOrigin(), mat3_identity ); sndTrigger->SetContents( CONTENTS_TRIGGER ); }
/* =============== idClip::Init =============== */ void idClip::Init( void ) { cmHandle_t h; idVec3 size, maxSector = vec3_origin; // clear clip sectors clipSectors = new clipSector_t[MAX_SECTORS]; memset( clipSectors, 0, MAX_SECTORS * sizeof( clipSector_t ) ); numClipSectors = 0; touchCount = -1; // get world map bounds h = collisionModelManager->LoadModel( "worldMap", false ); collisionModelManager->GetModelBounds( h, worldBounds ); // create world sectors CreateClipSectors_r( 0, worldBounds, maxSector ); size = worldBounds[1] - worldBounds[0]; gameLocal.Printf( "map bounds are (%1.1f, %1.1f, %1.1f)\n", size[0], size[1], size[2] ); gameLocal.Printf( "max clip sector is (%1.1f, %1.1f, %1.1f)\n", maxSector[0], maxSector[1], maxSector[2] ); // initialize a default clip model defaultClipModel.LoadModel( idTraceModel( idBounds( idVec3( 0, 0, 0 ) ).Expand( 8 ) ) ); // set counters to zero numRotations = numTranslations = numMotions = numRenderModelTraces = numContents = numContacts = 0; }
/* ================ 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 ); } }
END_CLASS /* =========== hhForceField::Spawn =========== */ void hhForceField::Spawn(void) { fl.takedamage = true; SetShaderParm( SHADERPARM_TIMEOFFSET, 1.0f ); SetShaderParm( SHADERPARM_MODE, 0.0f ); fade = 0.0f; activationRate = spawnArgs.GetFloat( "activationRate" ); deactivationRate = spawnArgs.GetFloat( "deactivationRate" ); undamageFadeRate = spawnArgs.GetFloat( "undamageFadeRate" ); // BecomeActive( TH_THINK|TH_TICKER ); cachedContents = CONTENTS_FORCEFIELD | CONTENTS_BLOCK_RADIUSDAMAGE | CONTENTS_SHOOTABLE; physicsObj.SetSelf( this ); if (spawnArgs.GetBool("isSimpleBox")) { // Simple boxes are cheaper and can be bound to other objects physicsObj.SetClipModel( new idClipModel(idTraceModel(GetPhysics()->GetBounds())), 1.0f ); physicsObj.SetContents( cachedContents ); physicsObj.SetOrigin( GetOrigin() ); physicsObj.SetAxis( GetAxis() ); SetPhysics( &physicsObj ); } else { // Non-simple has real per-poly collision with it's model, uses default static physics because we don't have a tracemodel. // This loses the activation of contacts on the object (so some things may not fall through when disabled), but in my tests, // the spirit proxy falls through fine. NOTE: To fix the movables, etc. not falling when these are turned off, I'm manually // Activating appropriate physics that overlap the bounds when Turned off. // physicsObj.SetClipModel( new idClipModel(GetPhysics()->GetClipModel()), 1.0f ); // physicsObj.SetContents( cachedContents ); // physicsObj.SetOrigin( GetOrigin() ); // physicsObj.SetAxis( GetAxis() ); // SetPhysics( &physicsObj ); // Apparently the flags need to be on the material to make projectiles hit these. GetPhysics()->SetContents(cachedContents); } EnterOnState(); damagedState = false; nextCollideFxTime = gameLocal.time; fl.networkSync = true; //always want to sync over the net }
/* ================ 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, 0); } 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"); }
/* ================= sdClientProjectile_Parabolic::InitPhysics ================= */ void sdClientProjectile_Parabolic::InitPhysics( void ) { float gravity = spawnArgs.GetFloat( "gravity" ); idVec3 gravVec = gameLocal.GetGravity(); gravVec.Normalize(); physicsObj.SetSelf( gameLocal.entities[ENTITYNUM_CLIENT] ); idBounds bounds; bounds[ 0 ] = spawnArgs.GetVector( "mins" ); bounds[ 1 ] = spawnArgs.GetVector( "mins" ); idClipModel* model = new idClipModel( idTraceModel( bounds ), false ); model->SetContents( 0 ); physicsObj.SetClipModel( model ); physicsObj.SetGravity( gravVec * gravity ); physicsObj.SetClipMask( MASK_PROJECTILE | CONTENTS_BODY | CONTENTS_SLIDEMOVER ); }
//-------------------------------- // hhProxDoor::Spawn //-------------------------------- void hhProxDoor::Spawn() { proxState = PROXSTATE_Inactive; doorSndState = PDOORSND_Closed; spawnArgs.GetBool( "startlocked", "0", doorLocked ); SetShaderParm( SHADERPARM_MODE, GetDoorShaderParm( doorLocked, true ) ); // 2=locked, 1=unlocked, 0=never locked if( !spawnArgs.GetFloat("trigger_distance", "0.0", maxDistance) ) { common->Warning( "No 'trigger_distance' specified for entityDef '%s'", this->GetEntityDefName() ); } if( !spawnArgs.GetFloat("movement_distance", "0.0", movementDistance) ) { common->Warning( "No 'movement_distance' specified for entityDef '%s'", this->GetEntityDefName() ); } lastDistance = movementDistance + 1.0f; // Safe default -mdl if( !spawnArgs.GetFloat("stop_distance", "0.0", stopDistance) ) { common->Warning( "No 'stop_distance' specificed for entityDef '%s'", this->GetEntityDefName() ); } spawnArgs.GetBool( "openForMonsters", "1", openForMonsters ); spawnArgs.GetFloat( "damage", "1", damage ); //Find any portal boundary we are on areaPortal = gameRenderWorld->FindPortal( GetPhysics()->GetAbsBounds() ); if (gameLocal.isMultiplayer) { fl.networkSync = true; if (gameLocal.isClient) { doorTrigger = new idClipModel( idTraceModel(idBounds(vec3_origin).Expand(maxDistance)) ); doorTrigger->Link( gameLocal.clip, this, 255, GetOrigin(), GetAxis() ); doorTrigger->SetContents( CONTENTS_TRIGGER ); SetAASAreaState( doorLocked ); //close the area state if we are locked... SetDoorState( PROXSTATE_Inactive ); } else { PostEventMS( &EV_PostSpawn, 50 ); //rww - this must be delayed or it will happen on the first server frame and we DON'T want that. } } else { //just call it now. some sp maps might target a door piece in the spawn function of an entity or something crazy like that. Event_PostSpawn(); } }
//-------------------------------- // hhProxDoor::Event_PostSpawn //-------------------------------- void hhProxDoor::Event_PostSpawn( void ) { int numSubObjs; int i; const char* objDef; //Parse and spawn our door sections numSubObjs = spawnArgs.GetInt( "num_doorobjs", "0" ); for( i = 0; i < numSubObjs; i++ ) { if( !spawnArgs.GetString( va("doorobject%i", i+1), "", &objDef ) ) { common->Warning( "failed to find doorobject%i", i+1 ); } else { //Set our default rotation/origin. idDict args; args.SetVector( "origin", this->GetOrigin() ); args.SetMatrix( "rotation", this->GetAxis() ); hhProxDoorSection* ent = static_cast<hhProxDoorSection*> ( gameLocal.SpawnObject(objDef, &args) ); if( !ent ) { common->Warning( "failed to spawn doorobject%i for entityDef '%s'", i+1, GetEntityDefName() ); } else { ent->proxyParent = this; doorPieces.Append( ent ); } } } //Spawn our trigger and link it up // if( doorLocked && !spawnArgs.GetBool("locktrigger") ) { //we would never be able to open the door, so don't spawn a trigger // } // else { doorTrigger = new idClipModel( idTraceModel(idBounds(vec3_origin).Expand(maxDistance)) ); doorTrigger->Link( gameLocal.clip, this, 255, GetOrigin(), GetAxis() ); doorTrigger->SetContents( CONTENTS_TRIGGER ); // } SpawnSoundTrigger(); SetAASAreaState( doorLocked ); //close the area state if we are locked... SetDoorState( PROXSTATE_Inactive ); }
/* ================ rvPhysics_Particle::Restore ================ */ void rvPhysics_Particle::Restore( idRestoreGame *savefile ) { savefile->ReadInt( current.atRest ); savefile->ReadVec3( current.localOrigin ); savefile->ReadMat3( current.localAxis ); savefile->ReadVec3( current.pushVelocity ); savefile->ReadVec3( current.origin ); savefile->ReadVec3( current.velocity ); savefile->ReadBool( current.onGround ); savefile->ReadBool( current.inWater ); // cnicholson: Added unsaved var savefile->ReadInt( saved.atRest ); // cnicholson: Added unsaved vars savefile->ReadVec3( saved.localOrigin ); savefile->ReadMat3( saved.localAxis ); savefile->ReadVec3( saved.pushVelocity ); savefile->ReadVec3( saved.origin ); savefile->ReadVec3( saved.velocity ); savefile->ReadBool( saved.onGround ); savefile->ReadBool( saved.inWater ); savefile->ReadFloat( linearFriction ); savefile->ReadFloat( angularFriction ); savefile->ReadFloat( contactFriction ); savefile->ReadFloat( bouncyness ); savefile->ReadBool ( allowBounce ); idBounds bounds; // cnicholson: Added unrestored var delete clipModel; savefile->ReadBounds ( bounds ); clipModel = new idClipModel ( idTraceModel ( bounds ) ); savefile->ReadBool( dropToFloor ); savefile->ReadBool( testSolid ); savefile->ReadBool( hasMaster ); savefile->ReadBool( isOrientated ); // cnicholson: Added unrestored var extraPassEntity.Restore( savefile ); savefile->ReadClipModel( clipModel ); }
/* ================ rvCTF_AssaultPoint::InitializeLinks ================ */ void rvCTF_AssaultPoint::Event_InitializeLinks( void ) { if( linked ) { return; } // pull in our targets toStrogg = gameLocal.FindEntity( spawnArgs.GetString( "targetStroggAP" ) ); toMarine = gameLocal.FindEntity( spawnArgs.GetString( "targetMarineAP" ) ); ResetIndices(); trigger = new idClipModel( idTraceModel( idBounds( vec3_origin ).Expand( 16.0f ) ) ); // RAVEN BEGIN // ddynerman: multiple clip worlds trigger->Link( this, 0, GetPhysics()->GetOrigin(), GetPhysics()->GetAxis() ); // RAVEN END trigger->SetContents ( CONTENTS_TRIGGER ); GetPhysics()->SetClipModel( NULL, 1.0f ); linked = true; }
/* ================ idPhysics::SetClipBox ================ */ void idPhysics::SetClipBox( const idBounds &bounds, float density ) { SetClipModel( new (TAG_PHYSICS_CLIP) idClipModel( idTraceModel( bounds ) ), density ); }
/* ================ idPhysics::SetClipBox ================ */ void idPhysics::SetClipBox( const idBounds &bounds, float density ) { SetClipModel( new idClipModel( idTraceModel( bounds ) ), density ); }
/* ================ 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" ) ) { 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" ); // ---> sikk - Modifier System // this is used for modifiers but can be specified for any item int removeDelay = spawnArgs.GetInt( "removeDelay" ); if ( removeDelay > 0 ) { PostEventSec( &EV_Remove, removeDelay ); } // <--- sikk - Modifier System // ---> sikk - Crumb Light idStr shaderName; idVec3 light_color; idVec3 light_offset; memset( &renderLight, 0, sizeof( renderLight ) ); shaderName = spawnArgs.GetString( "mtr_light_shader" ); if ( *(const char *)shaderName ) { renderLight.shader = declManager->FindMaterial( shaderName, false ); renderLight.pointLight = true; renderLight.lightRadius[0] = renderLight.lightRadius[1] = renderLight.lightRadius[2] = spawnArgs.GetFloat( "light_radius" ); spawnArgs.GetVector( "light_color", "1 1 1", light_color ); renderLight.shaderParms[0] = light_color[0]; renderLight.shaderParms[1] = light_color[1]; renderLight.shaderParms[2] = light_color[2]; renderLight.shaderParms[3] = spawnArgs.GetFloat( "light_brightness", "1.0" ); // sikk - alpha holds light brightness } spawnArgs.GetVector( "light_offset", "0 0 0", lightOffset ); // <--- sikk - Crumb Light // ---> sikk - Crumb count if ( spawnArgs.GetBool( "inv_crumb" ) ) { gameLocal.numCrumbs++; } // <--- sikk - Crumb count }