void ProcessMenu(int value) { switch(value) { case 1: useVertexShader = !useVertexShader; if (useVertexShader) { glutChangeToMenuEntry(1, "Toggle vertex shader (currently ON)", 1); glAttachShader(progObj, vShader); } else { glutChangeToMenuEntry(1, "Toggle vertex shader (currently OFF)", 1); glDetachShader(progObj, vShader); } Relink(); break; case 2: useFragmentShader = !useFragmentShader; if (useFragmentShader) { glutChangeToMenuEntry(2, "Toggle fragment shader (currently ON)", 2); glAttachShader(progObj, fShader); } else { glutChangeToMenuEntry(2, "Toggle fragment shader (currently OFF)", 2); glDetachShader(progObj, fShader); } Relink(); break; case 3: doBlink = !doBlink; if (doBlink) { glutChangeToMenuEntry(3, "Toggle flicker (currently ON)", 3); } else { glutChangeToMenuEntry(3, "Toggle flicker (currently OFF)", 3); } if (!doBlink && (flickerLocation != -1)) glUniform1f(flickerLocation, 1.0f); break; default: break; } // Refresh the Window glutPostRedisplay(); }
//========================================================= // Materialize - make a CWeaponCSBase visible and tangible //========================================================= void CWeaponCSBase::Materialize() { if ( m_fEffects & EF_NODRAW ) { // changing from invisible state to visible. //Ken: Suppress the default sound //--- if( g_pGameRules->IsMultiplayer() ) { //EMIT_SOUND_DYN( ENT(pev), CHAN_WEAPON, "items/suitchargeok1.wav", 1, ATTN_NORM, 0, 150 ); } //--- m_fEffects &= ~EF_NODRAW; m_fEffects |= EF_MUZZLEFLASH; } AddSolidFlags( FSOLID_TRIGGER ); Relink(); //SetTouch( &CWeaponCSBase::DefaultTouch ); //Ken: Leave guns & items lying around in single-player //--- if( g_pGameRules->IsMultiplayer() ) { SetThink (&CWeaponCSBase::SUB_Remove); SetNextThink( gpGlobals->curtime + 1 ); } else { SetThink( NULL ); } }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CGrenadeBugBait::Spawn( void ) { Precache(); SetModel( GRENADE_MODEL ); SetMoveType( MOVETYPE_FLYGRAVITY, MOVECOLLIDE_FLY_BOUNCE ); SetSolid( SOLID_BBOX ); UTIL_SetSize( this, Vector( -2, -2, -2), Vector( 2, 2, 2 ) ); Relink(); SetTouch( BugBaitTouch ); m_takedamage = DAMAGE_NO; m_pSporeTrail = NULL; /* m_pSporeTrail = SporeTrail::CreateSporeTrail(); m_pSporeTrail->m_bEmit = true; m_pSporeTrail->m_flSpawnRate = 100.0f; m_pSporeTrail->m_flParticleLifetime = 1.0f; m_pSporeTrail->m_flStartSize = 1.0f; m_pSporeTrail->m_flEndSize = 1.0f; m_pSporeTrail->m_flSpawnRadius = 8.0f; m_pSporeTrail->m_vecEndColor = Vector( 0, 0, 0 ); */ }
void CBaseTurret::Deploy(void) { SetNextThink( gpGlobals->curtime + 0.1f ); StudioFrameAdvance( ); if ( m_Activity != ACT_TURRET_OPEN ) { m_iOn = 1; SetActivity( (Activity)ACT_TURRET_OPEN ); EmitSound( "NPC_Turret.Deploy" ); m_OnDeploy.FireOutput(NULL, this); } if (m_fSequenceFinished) { Vector curmins, curmaxs; curmins = WorldAlignMins(); curmaxs = WorldAlignMaxs(); curmaxs.z = m_iDeployHeight; curmins.z = -m_iDeployHeight; SetCollisionBounds( curmins, curmaxs ); Relink(); SetActivity( (Activity)ACT_TURRET_OPEN_IDLE ); m_flPlaybackRate = 0; SetThink(SearchThink); } m_flLastSight = gpGlobals->curtime + m_flMaxWait; }
//----------------------------------------------------------------------------- // Spawn //----------------------------------------------------------------------------- void CNPC_Eli :: Spawn() { Precache(); BaseClass::Spawn(); SetModel( "models/eli.mdl" ); SetHullType(HULL_HUMAN); SetHullSizeNormal(); SetSolid( SOLID_BBOX ); AddSolidFlags( FSOLID_NOT_STANDABLE ); SetMoveType( MOVETYPE_STEP ); SetBloodColor( BLOOD_COLOR_RED ); m_iHealth = 8; m_flFieldOfView = 0.5;// indicates the width of this NPC's forward view cone ( as a dotproduct result ) m_NPCState = NPC_STATE_NONE; CapabilitiesAdd( bits_CAP_MOVE_GROUND | bits_CAP_OPEN_DOORS | bits_CAP_ANIMATEDFACE | bits_CAP_TURN_HEAD ); NPCInit(); Relink(); }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CPlayer_Missile::InputActivate( inputdata_t &inputdata ) { // Make sure not already active if (m_bActive) { return; } BaseClass::InputActivate( inputdata ); Vector origin = GetLocalOrigin(); origin.z += 50; SetLocalOrigin( origin ); RemoveSolidFlags( FSOLID_NOT_SOLID ); Relink(); // Using player angles to determine turning. Initailze to 0,0,0 CHL2_Player* pPlayer = (CHL2_Player*)UTIL_PlayerByIndex( 1 ); Assert( pPlayer ); pPlayer->SetLocalAngles( vec3_angle ); // Note: Set GetLocalAngles(), not pl.v_angle pPlayer->SnapEyeAngles( vec3_angle ); // Force reset pPlayer->SetFOV( 100 ); engine->SetView( pPlayer->edict(), edict() ); m_flStatic = 0; SetThink(Launch); SetNextThink( gpGlobals->curtime + m_flLaunchDelay ); }
void CRagdollPropAttached::InitRagdollAttached( IPhysicsObject *pAttached, const Vector &forceVector, int forceBone, matrix3x4_t *pPrevBones, matrix3x4_t *pBoneToWorld, float dt, int collisionGroup, CBaseAnimating *pFollow, int boneIndexRoot, const Vector &boneLocalOrigin, int parentBoneAttach, const Vector &worldAttachOrigin ) { int ragdollAttachedIndex = 0; if ( parentBoneAttach > 0 ) { studiohdr_t *pStudioHdr = GetModelPtr(); mstudiobone_t *pBone = pStudioHdr->pBone( parentBoneAttach ); ragdollAttachedIndex = pBone->physicsbone; } InitRagdoll( forceVector, forceBone, vec3_origin, pPrevBones, pBoneToWorld, dt, collisionGroup, false ); IPhysicsObject *pRefObject = m_ragdoll.list[ragdollAttachedIndex].pObject; Vector attachmentPointRagdollSpace; pRefObject->WorldToLocal( attachmentPointRagdollSpace, worldAttachOrigin ); constraint_ragdollparams_t constraint; constraint.Defaults(); matrix3x4_t tmp, worldToAttached, worldToReference, constraintToWorld; Vector offsetWS; pAttached->LocalToWorld( offsetWS, boneLocalOrigin ); AngleMatrix( QAngle(0, pFollow->GetAbsAngles().y, 0 ), offsetWS, constraintToWorld ); constraint.axes[0].SetAxisFriction( -2, 2, 20 ); constraint.axes[1].SetAxisFriction( 0, 0, 0 ); constraint.axes[2].SetAxisFriction( -15, 15, 20 ); pAttached->GetPositionMatrix( tmp ); MatrixInvert( tmp, worldToAttached ); pRefObject->GetPositionMatrix( tmp ); MatrixInvert( tmp, worldToReference ); ConcatTransforms( worldToReference, constraintToWorld, constraint.constraintToReference ); ConcatTransforms( worldToAttached, constraintToWorld, constraint.constraintToAttached ); // for now, just slam this to be the passed in value MatrixSetColumn( attachmentPointRagdollSpace, 3, constraint.constraintToReference ); DisableCollisions( pAttached ); m_pAttachConstraint = physenv->CreateRagdollConstraint( pRefObject, pAttached, m_ragdoll.pGroup, constraint ); FollowEntity( pFollow ); SetOwnerEntity( pFollow ); RagdollActivate( m_ragdoll ); Relink(); m_boneIndexAttached = boneIndexRoot; m_ragdollAttachedObjectIndex = ragdollAttachedIndex; m_attachmentPointBoneSpace = boneLocalOrigin; Vector vTemp; MatrixGetColumn( constraint.constraintToReference, 3, vTemp ); m_attachmentPointRagdollSpace = vTemp; }
//----------------------------------------------------------------------------- // Purpose: Attaches the flame to an entity and moves with it // Input : pTarget - target entity to attach to //----------------------------------------------------------------------------- void CEntityFlame::AttachToEntity( CBaseEntity *pTarget ) { // For networking to the client. m_hEntAttached = pTarget; // So our heat emitter follows the entity around on the server. SetParent( pTarget ); Relink(); }
TreeNode* Relink(TreeNode *root) { if(!root || (!root->left && !root->right)) return root; TreeNode *left = root->left; TreeNode *right = root->right; root->left = NULL; if(left) { root->right = left; root = Relink(left); } if(right) { root->right = right; root = Relink(right); } return root; }
void CBoneFollower::VPhysicsUpdate( IPhysicsObject *pPhysics ) { Vector origin; QAngle angles; pPhysics->GetPosition( &origin, &angles ); SetAbsOrigin( origin ); SetAbsAngles( angles ); Relink(); }
void CBaseTurret::Retire(void) { // make the turret level m_vecGoalAngles = GetAngles( ); SetNextThink( gpGlobals->curtime + 0.1f ); StudioFrameAdvance( ); EyeOff( ); if ( m_Activity != ACT_TURRET_CLOSE ) { SetActivity( (Activity)ACT_TURRET_OPEN_IDLE ); if (!MoveTurret()) { SetActivity( (Activity)ACT_TURRET_CLOSE ); EmitSound( "NPC_Turret.Retire" ); m_OnRetire.FireOutput(NULL, this); } } else if (m_fSequenceFinished) { m_iOn = 0; m_flLastSight = 0; SetActivity( (Activity)ACT_TURRET_CLOSED_IDLE ); Vector curmins, curmaxs; curmins = WorldAlignMins(); curmaxs = WorldAlignMaxs(); curmaxs.z = m_iRetractHeight; curmins.z = -m_iRetractHeight; SetCollisionBounds( curmins, curmaxs ); Relink(); if (m_iAutoStart) { SetThink(AutoSearchThink); SetNextThink( gpGlobals->curtime + .1 ); } else { SetThink(SUB_DoNothing); } } }
void CRagdollPropAttached::Detach() { StopFollowingEntity(); SetOwnerEntity( NULL ); SetAbsAngles( vec3_angle ); SetMoveType( MOVETYPE_VPHYSICS ); physenv->DestroyConstraint( m_pAttachConstraint ); m_pAttachConstraint = NULL; // Go non-solid SetCollisionGroup( COLLISION_GROUP_DEBRIS ); Relink(); RecheckCollisionFilter(); }
void Program::DoLink () { while (oldModList != nil) { InputFile* doomed = (InputFile*) oldModList; oldModList = (InputFile*)oldModList->nn; doomed->Unlink(oldModList); delete doomed; } Base* insertPoint = inf->nn; ctdt->Link(insertPoint); if (fullLink) { FullLink(); } else { Relink(); } }
//----------------------------------------------------------------------------- // Purpose: Spawn the object //----------------------------------------------------------------------------- void CExtinguisherCharger::Spawn( void ) { Precache(); SetSolid( SOLID_BSP ); SetMoveType( MOVETYPE_PUSH ); UTIL_SetSize( this, EntitySpaceMins(), EntitySpaceMaxs() ); SetModel( STRING( GetModelName() ) ); Relink(); m_bSoundOn = false; CreateVPhysics(); }
void CRecharge::Spawn() { Precache( ); SetSolid( SOLID_BSP ); SetMoveType( MOVETYPE_PUSH ); Relink(); UTIL_SetSize(this, EntitySpaceMins(), EntitySpaceMaxs()); SetModel( STRING( GetModelName() ) ); m_iJuice = sk_suitcharger.GetFloat(); SetTextureFrameIndex( 0 ); CreateVPhysics(); }
void CRagdollProp::Spawn( void ) { Precache(); SetModel( STRING( GetModelName() ) ); Relink(); matrix3x4_t pBoneToWorld[MAXSTUDIOBONES]; BaseClass::SetupBones( pBoneToWorld, BONE_USED_BY_ANYTHING ); // FIXME: shouldn't this be a subset of the bones int collisionGroup = (m_spawnflags & SF_RAGDOLLPROP_DEBRIS) ? COLLISION_GROUP_DEBRIS : COLLISION_GROUP_NONE; InitRagdoll( vec3_origin, 0, vec3_origin, pBoneToWorld, pBoneToWorld, 0, collisionGroup, true ); // only send data when physics moves this object NetworkStateManualMode( true ); m_lastUpdateTickCount = 0; }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CPlayer_Missile::BlowUp(void) { // Don't take damage any more m_takedamage = DAMAGE_NO; // Mark as dead so won't be attacked m_lifeState = LIFE_DEAD; // Stop fly and launch sounds StopSound( "Player_Manhack.Fly" ); StopSound( "Player_Manhack.Fire" ); CPASFilter filter( GetAbsOrigin() ); te->Explosion( filter, 0.0, &GetAbsOrigin(), g_sModelIndexFireball, 2.0, 15, TE_EXPLFLAG_NONE, m_flDamageRadius, m_flDamage ); Vector vecForward = GetAbsVelocity(); VectorNormalize(vecForward); trace_t tr; UTIL_TraceLine ( GetAbsOrigin(), GetAbsOrigin() + 60*vecForward, MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &tr); UTIL_DecalTrace( &tr, "Scorch" ); UTIL_ScreenShake( GetAbsOrigin(), 25.0, 150.0, 1.0, 750, SHAKE_START ); CSoundEnt::InsertSound ( SOUND_DANGER, GetAbsOrigin(), 1024, 3.0 ); RadiusDamage ( CTakeDamageInfo( this, this, m_flDamage, DMG_BLAST ), GetAbsOrigin(), m_flDamageRadius, CLASS_NONE ); SetThink(ExplodeThink); SetTouch(NULL); m_vBounceVel = -0.2 * GetAbsVelocity(); AddSolidFlags( FSOLID_NOT_SOLID ); Relink(); // Stop emitting smoke if(m_hSmokeTrail) { ((SmokeTrail*)(CBaseEntity*)m_hSmokeTrail)->SetEmit(false); } }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CPhysBox::Spawn( void ) { Precache(); if ( HasSpawnFlags( SF_BREAK_TRIGGER_ONLY ) ) { m_takedamage = DAMAGE_NO; AddSpawnFlags( SF_BREAK_DONT_TAKE_PHYSICS_DAMAGE ); } else if ( m_iHealth == 0 ) { m_takedamage = DAMAGE_EVENTS_ONLY; AddSpawnFlags( SF_BREAK_DONT_TAKE_PHYSICS_DAMAGE ); } else { m_takedamage = DAMAGE_YES; } SetMoveType( MOVETYPE_NONE ); SetSolid( SOLID_VPHYSICS ); SetAbsVelocity( vec3_origin ); SetModel( STRING( GetModelName() ) ); Relink(); SetSolid( SOLID_VPHYSICS ); if ( HasSpawnFlags( SF_PHYSBOX_DEBRIS ) ) { SetCollisionGroup( COLLISION_GROUP_DEBRIS ); } CreateVPhysics(); m_hCarryingPlayer = NULL; SetTouch( &CPhysBox::BreakTouch ); if ( HasSpawnFlags( SF_BREAK_TRIGGER_ONLY ) ) // Only break on trigger { SetTouch( NULL ); } if ( m_impactEnergyScale == 0 ) { m_impactEnergyScale = 1.0; } }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CPlayer_Missile::ControlDeactivate( void ) { BaseClass::ControlDeactivate(); CHL2_Player* pPlayer = (CHL2_Player*)UTIL_PlayerByIndex( 1 ); Assert( pPlayer ); engine->SetView( pPlayer->edict(), pPlayer->edict() ); pPlayer->m_Local.m_iHideHUD &= ~HIDEHUD_WEAPONS; SetAbsVelocity( vec3_origin ); SetLocalAngles( m_vSpawnAng ); SetLocalOrigin( m_vSpawnPos ); m_fEffects |= EF_NODRAW; Relink(); }
void CRagdollProp::CalcRagdollSize( void ) { Vector minbox, maxbox; ExtractBbox( GetSequence(), minbox, maxbox ); SetCollisionBounds( minbox, maxbox ); if ( m_ragdoll.list[0].pObject ) { Vector rootPos, rootWorldPos; m_ragdoll.list[0].pObject->GetPosition( &rootWorldPos, NULL ); WorldToEntitySpace( rootWorldPos, &rootPos ); // BUGBUG: This doesn't work because the sequence doesn't necessarily include // the extrema of pose space. // An algorithm that should work correctly is to store a radius in each bone // Then walk the skeleton away from the root to each leaf, accumulating distance to parent // The node or leaf with the largest radius + Sum(dist to parent) is the ragdoll's radius // Next rev of the model file format, I'll add bone radius and fix this. Vector dist; const Vector ¢er = EntitySpaceCenter(); int i; for ( i = 0; i < 3; i++ ) { if ( rootPos[i] > center[i] ) { dist[i] = rootPos[i] - EntitySpaceMins()[i]; } else { dist[i] = EntitySpaceMaxs()[i] - rootPos[i]; } } float radius = dist.Length(); Vector curmins( -radius, -radius, -radius ); Vector curmaxs( radius, radius, radius ); SetCollisionBounds( curmins, curmaxs ); } m_savedESMins = EntitySpaceMins(); m_savedESMaxs = EntitySpaceMaxs(); Relink(); }
void CStickyBomb::Spawn() { m_hOperator = GetOwnerEntity(); Precache(); SetModel( STICKY_BOMB_MODEL ); SetSolid( SOLID_BBOX ); SetMoveType( MOVETYPE_FLYGRAVITY, MOVECOLLIDE_FLY_CUSTOM ); SetCollisionGroup( COLLISION_GROUP_NONE ); m_takedamage = DAMAGE_NO; SetNextThink( TICK_NEVER_THINK ); m_flAnimTime = gpGlobals->curtime; m_flPlaybackRate = 0.0; m_flCycle = 0; UTIL_SetSize( this, vec3_origin, vec3_origin ); Relink(); // no shadows, please. m_fEffects |= EF_NOSHADOW|EF_NORECEIVESHADOW; SetRenderColor( 255, 0, 0 ); }
//------------------------------------------------------------------------------ // Purpose : // Input : // Output : //------------------------------------------------------------------------------ void CNPC_LightStalk::Spawn( void ) { Precache(); SetModel( LIGHTSTALK_MODEL ); SetMoveType( MOVETYPE_NONE ); SetSolid( SOLID_BBOX ); AddSolidFlags( FSOLID_TRIGGER ); UTIL_SetSize( this, Vector(-80,-80,0), Vector(80,80,32)); Relink(); SetActivity( ACT_IDLE ); SetNextThink( gpGlobals->curtime + 0.1f ); m_pGlow = CSprite::SpriteCreate( LIGHTSTALK_GLOW_SPRITE, GetLocalOrigin() + Vector(0,0,(WorldAlignMins().z+WorldAlignMaxs().z)*0.5), false ); m_pGlow->SetTransparency( kRenderGlow, m_clrRender->r, m_clrRender->g, m_clrRender->b, m_clrRender->a, kRenderFxGlowShell ); m_pGlow->SetScale( 1.0 ); m_pGlow->SetAttachment( this, 1 ); LightRise(); }
//========================================================= // Spawn //========================================================= void CNPC_Gargantua::Spawn() { Precache( ); SetModel( "models/garg.mdl" ); SetNavType(NAV_GROUND); SetSolid( SOLID_BBOX ); AddSolidFlags( FSOLID_NOT_STANDABLE ); SetMoveType( MOVETYPE_STEP ); m_bloodColor = BLOOD_COLOR_GREEN; m_iHealth = sk_gargantua_health.GetFloat(); SetViewOffset( Vector ( 0, 0, 96 ) );// taken from mdl file m_flFieldOfView = -0.2;// width of forward view cone ( as a dotproduct result ) m_NPCState = NPC_STATE_NONE; CapabilitiesAdd( bits_CAP_MOVE_GROUND ); CapabilitiesAdd( bits_CAP_INNATE_RANGE_ATTACK1 | bits_CAP_INNATE_MELEE_ATTACK1 | bits_CAP_INNATE_MELEE_ATTACK2 ); SetHullType( HULL_WIDE_HUMAN ); SetHullSizeNormal(); m_pEyeGlow = CSprite::SpriteCreate( GARG_EYE_SPRITE_NAME, GetAbsOrigin(), FALSE ); m_pEyeGlow->SetTransparency( kRenderGlow, 255, 255, 255, 0, kRenderFxNoDissipation ); m_pEyeGlow->SetAttachment( this, 1 ); EyeOff(); m_seeTime = gpGlobals->curtime + 5; m_flameTime = gpGlobals->curtime + 2; NPCInit(); BaseClass::Spawn(); Relink(); }
void CPlantedC4::Init( CCSPlayer *pevOwner, Vector vecStart, QAngle vecAngles ) { SetMoveType( MOVETYPE_NONE ); SetSolid( SOLID_BBOX ); SetModel( PLANTED_C4_MODEL ); // Change this to c4 model SetCollisionBounds( Vector( 0, 0, 0 ), Vector( 8, 8, 8 ) ); SetAbsOrigin( vecStart ); SetAbsAngles( vecAngles ); SetOwnerEntity( pevOwner ); // Detonate in "time" seconds SetThink( &CPlantedC4::C4Think ); //pGrenade->SetTouch( &CPlantedC4::C4Touch ); SetNextThink( gpGlobals->curtime + 0.1f ); m_flC4Blow = gpGlobals->curtime + c4timer.GetInt(); m_flNextFreqInterval = c4timer.GetInt() / 4; m_flNextFreq = gpGlobals->curtime; m_flNextBeep = gpGlobals->curtime + 0.5; m_iCurWave = 0; m_sBeepName = NULL; m_flNextBlink = gpGlobals->curtime + BLINK_INTERVAL; m_flNextDefuse = 0; m_bStartDefuse = false; m_bJustBlew = false; SetFriction( 0.9 ); Relink(); }
//------------------------------------------------------------------------------ // Purpose : // Input : // Output : //------------------------------------------------------------------------------ void CNPC_CombineDropship::PrescheduleThink( void ) { BaseClass::PrescheduleThink(); // keep track of think time deltas for burn calc below float dt = gpGlobals->curtime - m_flLastTime; m_flLastTime = gpGlobals->curtime; switch( m_iLandState ) { case LANDING_NO: { if ( IsActivityFinished() && (GetActivity() != ACT_DROPSHIP_FLY_IDLE_EXAGG && GetActivity() != ACT_DROPSHIP_FLY_IDLE_CARGO) ) { if ( m_hContainer ) { SetIdealActivity( (Activity)ACT_DROPSHIP_FLY_IDLE_CARGO ); } else { SetIdealActivity( (Activity)ACT_DROPSHIP_FLY_IDLE_EXAGG ); } } DoRotorWash(); } break; case LANDING_LEVEL_OUT: { // Approach the drop point Vector vecToTarget = (GetDesiredPosition() - GetAbsOrigin()); float flDistance = vecToTarget.Length(); // If we're slowing, make it look like we're slowing /* if ( IsActivityFinished() && GetActivity() != ACT_DROPSHIP_DESCEND_IDLE ) { SetActivity( (Activity)ACT_DROPSHIP_DESCEND_IDLE ); } */ // Are we there yet? float flSpeed = GetAbsVelocity().Length(); if ( flDistance < 70 && flSpeed < 100 ) { m_flLandingSpeed = flSpeed; m_iLandState = LANDING_DESCEND; // save off current angles so we can work them out over time QAngle angles = GetLocalAngles(); m_existPitch = angles.x; m_existRoll = angles.z; } DoRotorWash(); } break; case LANDING_DESCEND: { float flAltitude; SetLocalAngularVelocity( vec3_angle ); // Ensure we land on the drop point Vector vecToTarget = (GetDesiredPosition() - GetAbsOrigin()); float flDistance = vecToTarget.Length(); float flRampedSpeed = m_flLandingSpeed * (flDistance / 70); Vector vecVelocity = (flRampedSpeed / flDistance) * vecToTarget; vecVelocity.z = -75; SetAbsVelocity( vecVelocity ); flAltitude = GetAltitude(); if ( IsActivityFinished() && GetActivity() != ACT_DROPSHIP_DESCEND_IDLE ) { SetActivity( (Activity)ACT_DROPSHIP_DESCEND_IDLE ); } if ( flAltitude < 72 ) { QAngle angles = GetLocalAngles(); // Level out quickly. angles.x = UTIL_Approach( 0.0, angles.x, 0.2 ); angles.z = UTIL_Approach( 0.0, angles.z, 0.2 ); SetLocalAngles( angles ); } else { // randomly move as if buffeted by ground effects // gently flatten ship from starting pitch/yaw m_existPitch = UTIL_Approach( 0.0, m_existPitch, 1 ); m_existRoll = UTIL_Approach( 0.0, m_existRoll, 1 ); QAngle angles = GetLocalAngles(); angles.x = m_existPitch + ( sin( gpGlobals->curtime * 3.5f ) * DROPSHIP_MAX_LAND_TILT ); angles.z = m_existRoll + ( sin( gpGlobals->curtime * 3.75f ) * DROPSHIP_MAX_LAND_TILT ); SetLocalAngles( angles ); // figure out where to face (nav point) Vector targetDir = GetDesiredPosition() - GetAbsOrigin(); // NDebugOverlay::Cross3D( m_pGoalEnt->GetAbsOrigin(), -Vector(2,2,2), Vector(2,2,2), 255, 0, 0, false, 20 ); QAngle targetAngles = GetAbsAngles(); targetAngles.y += UTIL_AngleDiff(UTIL_VecToYaw( targetDir ), targetAngles.y); // orient ship towards path corner on the way down angles = GetAbsAngles(); angles.y = UTIL_Approach(targetAngles.y, angles.y, 2 ); SetAbsAngles( angles ); } if ( flAltitude <= 0.5f ) { m_iLandState = LANDING_TOUCHDOWN; // upon landing, make sure ship is flat QAngle angles = GetLocalAngles(); angles.x = 0; angles.z = 0; SetLocalAngles( angles ); // TODO: Release cargo anim SetActivity( (Activity)ACT_DROPSHIP_DESCEND_IDLE ); } DoRotorWash(); // place danger sounds 1 foot above ground to get troops to scatter if they are below dropship Vector vecBottom = GetAbsOrigin(); vecBottom.z += WorldAlignMins().z; Vector vecSpot = vecBottom + Vector(0, 0, -1) * (GetAltitude() - 12 ); CSoundEnt::InsertSound( SOUND_DANGER, vecSpot, 400, 0.2, this, 0 ); CSoundEnt::InsertSound( SOUND_PHYSICS_DANGER, vecSpot, 400, 0.2, this, 1 ); // NDebugOverlay::Cross3D( vecSpot, -Vector(4,4,4), Vector(4,4,4), 255, 0, 255, false, 10.0f ); // now check to see if player is below us, if so, cause heat damage to them (i.e. get them to move) trace_t tr; Vector vecBBoxMin = CRATE_BBOX_MIN; // use flat box for check vecBBoxMin.z = -5; Vector vecBBoxMax = CRATE_BBOX_MAX; vecBBoxMax.z = 5; Vector pEndPoint = vecBottom + Vector(0, 0, -1) * ( GetAltitude() - 12 ); AI_TraceHull( vecBottom, pEndPoint, vecBBoxMin, vecBBoxMax, MASK_SOLID, this, COLLISION_GROUP_NONE, &tr ); if ( tr.fraction < 1.0f ) { if ( tr.GetEntityIndex() == 1 ) // player??? { CTakeDamageInfo info( this, this, 20 * dt, DMG_BURN ); CBasePlayer *pPlayer = UTIL_PlayerByIndex(1); pPlayer->TakeDamage( info ); } } } break; case LANDING_TOUCHDOWN: { if ( IsActivityFinished() && ( GetActivity() != ACT_DROPSHIP_DESCEND_IDLE ) ) { SetActivity( (Activity)ACT_DROPSHIP_DESCEND_IDLE ); } m_iLandState = LANDING_UNLOADING; m_flTroopDeployPause = gpGlobals->curtime + DROPSHIP_PAUSE_B4_TROOP_UNLOAD; m_flTimeTakeOff = m_flTroopDeployPause + DROPSHIP_DEPLOY_TIME; } break; case LANDING_UNLOADING: { // pause before dropping troops if ( gpGlobals->curtime > m_flTroopDeployPause ) { if ( m_hContainer ) // don't drop troops if we don't have a crate any more { SpawnTroops(); m_flTroopDeployPause = m_flTimeTakeOff + 2; // only drop once } } // manage engine wash and volume if ( m_flTimeTakeOff - gpGlobals->curtime < 0.5f ) { m_engineThrust = UTIL_Approach( 1.0f, m_engineThrust, 0.1f ); DoRotorWash(); } else { float idleVolume = 0.2f; m_engineThrust = UTIL_Approach( idleVolume, m_engineThrust, 0.04f ); if ( m_engineThrust > idleVolume ) { DoRotorWash(); // make sure we're kicking up dust/water as long as engine thrust is up } } if( gpGlobals->curtime > m_flTimeTakeOff ) { m_iLandState = LANDING_LIFTOFF; SetActivity( (Activity)ACT_DROPSHIP_LIFTOFF ); m_engineThrust = 1.0f; // ensure max volume once we're airborne if ( m_bIsFiring ) { StopCannon(); // kill cannon sounds if they are on } // detach container from ship if ( m_hContainer && m_leaveCrate ) { m_hContainer->SetParent(NULL); m_hContainer->SetMoveType( (MoveType_t)m_iContainerMoveType ); // If the container has a physics object, remove it's shadow IPhysicsObject *pPhysicsObject = m_hContainer->VPhysicsGetObject(); if ( pPhysicsObject ) { pPhysicsObject->RemoveShadowController(); } m_hContainer = NULL; } } } break; case LANDING_LIFTOFF: { // give us some clearance before changing back to larger hull -- keeps ship from getting stuck on // things like the player, etc since we "pop" the hull... if ( GetAltitude() > 120 ) { m_OnFinishedDropoff.FireOutput( this, this ); m_iLandState = LANDING_NO; // change bounding box back to normal ship hull Vector vecBBMin, vecBBMax; ExtractBbox( SelectHeaviestSequence( ACT_DROPSHIP_DEPLOY_IDLE ), vecBBMin, vecBBMax ); UTIL_SetSize( this, vecBBMin, vecBBMax ); Relink(); } } break; case LANDING_SWOOPING: { // Did we lose our pickup target? if ( !m_hPickupTarget ) { m_iLandState = LANDING_NO; } else { // Decrease altitude and speed to hit the target point. Vector vecToTarget = (GetDesiredPosition() - GetAbsOrigin()); float flDistance = vecToTarget.Length(); // Start cheating when we get near it if ( flDistance < 50 ) { /* if ( flDistance > 10 ) { // Cheat and ensure we touch the target float flSpeed = GetAbsVelocity().Length(); Vector vecVelocity = vecToTarget; VectorNormalize( vecVelocity ); SetAbsVelocity( vecVelocity * min(flSpeed,flDistance) ); } else */ { // Grab the target m_hContainer = m_hPickupTarget; m_hPickupTarget = NULL; m_iContainerMoveType = m_hContainer->GetMoveType(); // If the container has a physics object, move it to shadow IPhysicsObject *pPhysicsObject = m_hContainer->VPhysicsGetObject(); if ( pPhysicsObject ) { pPhysicsObject->SetShadow( Vector(1e4,1e4,1e4), AngularImpulse(1e4,1e4,1e4), false, false ); pPhysicsObject->UpdateShadow( GetAbsOrigin(), GetAbsAngles(), false, 0 ); } int iIndex = 0;//LookupAttachment("Cargo"); /* Vector vecOrigin; QAngle vecAngles; GetAttachment( iIndex, vecOrigin, vecAngles ); m_hContainer->SetAbsOrigin( vecOrigin ); m_hContainer->SetAbsAngles( vec3_angle ); */ m_hContainer->SetAbsOrigin( GetAbsOrigin() ); m_hContainer->SetParent(this, iIndex); m_hContainer->SetMoveType( MOVETYPE_PUSH ); m_hContainer->RemoveFlag( FL_ONGROUND ); m_hContainer->Relink(); m_hContainer->SetAbsAngles( vec3_angle ); m_OnFinishedPickup.FireOutput( this, this ); m_iLandState = LANDING_NO; } } } DoRotorWash(); } break; } DoCombatStuff(); if ( GetActivity() != GetIdealActivity() ) { //Msg( "setactivity" ); SetActivity( GetIdealActivity() ); } }
void flatten(TreeNode *root) { Relink(root); }