//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- int CNPC_CraneDriver::SelectSchedule( void ) { if ( HasSpawnFlags(SF_VEHICLEDRIVER_INACTIVE) ) return BaseClass::SelectSchedule(); // If we've got an object to pickup, so go get it if ( m_hPickupTarget ) { // Only clear the pickup target if we managed to pick something up if ( m_hCrane->GetTotalMassOnCrane() > 0 ) { if ( m_bForcedPickup ) { m_OnPickedUpObject.FireOutput( m_hPickupTarget, this ); } // Remember what we dropped so we go try something else if we can. m_PreviouslyPickedUpObjects.AddToTail( m_hPickupTarget ); m_hPickupTarget = NULL; } else { if ( m_NPCState == NPC_STATE_IDLE ) { m_IdealNPCState = NPC_STATE_ALERT; } return SCHED_CRANE_PICKUP_OBJECT; } } // If we're currently being forced to pickup something, do only that if ( m_bForcedPickup ) { if ( m_hPickupTarget ) return SCHED_CRANE_PICKUP_OBJECT; // We've picked up our target, we're waiting to be told where to put it return SCHED_IDLE_STAND; } // If we've been told to drop something off, do that if ( m_bForcedDropoff ) return SCHED_CRANE_FORCED_DROP; switch ( m_NPCState ) { case NPC_STATE_IDLE: break; case NPC_STATE_ALERT: break; case NPC_STATE_COMBAT: if ( HasCondition( COND_CAN_RANGE_ATTACK1 ) ) { // Do we have anything on the crane? If not, look for something if ( m_hCrane->GetTotalMassOnCrane() == 0 ) return SCHED_CRANE_FIND_LARGE_OBJECT; // We've got something on the crane, so try and drop it on the enemy return SCHED_CRANE_RANGE_ATTACK1; } // We can't attack him, so if we don't have anything on the crane, grab something if ( m_hCrane->GetTotalMassOnCrane() == 0 ) return SCHED_CRANE_FIND_LARGE_OBJECT; } return BaseClass::SelectSchedule(); }
//----------------------------------------------------------------------------- // Purpose: Input handler for making the explosion explode. //----------------------------------------------------------------------------- void CEnvExplosion::InputExplode( inputdata_t &inputdata ) { trace_t tr; SetModelName( NULL_STRING );//invisible SetSolid( SOLID_NONE );// intangible Vector vecSpot = GetAbsOrigin() + Vector( 0 , 0 , 8 ); UTIL_TraceLine( vecSpot, vecSpot + Vector( 0, 0, -40 ), (MASK_SOLID_BRUSHONLY | MASK_WATER), this, COLLISION_GROUP_NONE, &tr ); // Pull out of the wall a bit. We used to move the explosion origin itself, but that seems unnecessary, not to mention a // little weird when you consider that it might be in hierarchy. Instead we just calculate a new virtual position at // which to place the explosion. We don't use that new position to calculate radius damage because according to Steve's // comment, that adversely affects the force vector imparted on explosion victims when they ragdoll. Vector vecExplodeOrigin = GetAbsOrigin(); if ( tr.fraction != 1.0 ) { vecExplodeOrigin = tr.endpos + (tr.plane.normal * 24 ); } // draw decal if (! ( m_spawnflags & SF_ENVEXPLOSION_NODECAL)) { UTIL_DecalTrace( &tr, "Scorch" ); } // It's stupid that this entity's spawnflags and the flags for the // explosion temp ent don't match up. But because they don't, we // have to reinterpret some of the spawnflags to determine which // flags to pass to the temp ent. int nFlags = TE_EXPLFLAG_NONE; if( m_spawnflags & SF_ENVEXPLOSION_NOFIREBALL ) { nFlags |= TE_EXPLFLAG_NOFIREBALL; } if( m_spawnflags & SF_ENVEXPLOSION_NOSOUND ) { nFlags |= TE_EXPLFLAG_NOSOUND; } if ( m_spawnflags & SF_ENVEXPLOSION_RND_ORIENT ) { nFlags |= TE_EXPLFLAG_ROTATE; } if ( m_nRenderMode == kRenderTransAlpha ) { nFlags |= TE_EXPLFLAG_DRAWALPHA; } else if ( m_nRenderMode != kRenderTransAdd ) { nFlags |= TE_EXPLFLAG_NOADDITIVE; } if( m_spawnflags & SF_ENVEXPLOSION_NOPARTICLES ) { nFlags |= TE_EXPLFLAG_NOPARTICLES; } if( m_spawnflags & SF_ENVEXPLOSION_NODLIGHTS ) { nFlags |= TE_EXPLFLAG_NODLIGHTS; } if ( m_spawnflags & SF_ENVEXPLOSION_NOFIREBALLSMOKE ) { nFlags |= TE_EXPLFLAG_NOFIREBALLSMOKE; } //Get the damage override if specified int iRadius = ( m_iRadiusOverride > 0 ) ? m_iRadiusOverride : ( m_iMagnitude * 2.5f ); CPASFilter filter( vecExplodeOrigin ); te->Explosion( filter, 0.0, &vecExplodeOrigin, ( m_sFireballSprite < 1 ) ? g_sModelIndexFireball : m_sFireballSprite, !( m_spawnflags & SF_ENVEXPLOSION_NOFIREBALL ) ? ( m_spriteScale / 10.0 ) : 0.0, 15, nFlags, iRadius, m_iMagnitude ); // do damage if ( !( m_spawnflags & SF_ENVEXPLOSION_NODAMAGE ) ) { CBaseEntity *pAttacker = GetOwnerEntity() ? GetOwnerEntity() : this; // Only calculate damage type if we didn't get a custom one passed in int iDamageType = m_iCustomDamageType; if ( iDamageType == -1 ) { iDamageType = HasSpawnFlags( SF_ENVEXPLOSION_GENERIC_DAMAGE ) ? DMG_GENERIC : DMG_BLAST; } CTakeDamageInfo info( m_hInflictor ? m_hInflictor : this, pAttacker, m_iMagnitude, iDamageType ); if( HasSpawnFlags( SF_ENVEXPLOSION_SURFACEONLY ) ) { info.AddDamageType( DMG_BLAST_SURFACE ); } if ( m_flDamageForce ) { // Not the right direction, but it'll be fixed up by RadiusDamage. info.SetDamagePosition( GetAbsOrigin() ); info.SetDamageForce( Vector( m_flDamageForce, 0, 0 ) ); } RadiusDamage( info, GetAbsOrigin(), iRadius, m_iClassIgnore, m_hEntityIgnore.Get() ); } SetThink( &CEnvExplosion::Smoke ); SetNextThink( gpGlobals->curtime + 0.3 ); // Only do these effects if we're not submerged if ( UTIL_PointContents( GetAbsOrigin() ) & CONTENTS_WATER ) { // draw sparks if ( !( m_spawnflags & SF_ENVEXPLOSION_NOSPARKS ) ) { int sparkCount = random->RandomInt(0,3); for ( int i = 0; i < sparkCount; i++ ) { QAngle angles; VectorAngles( tr.plane.normal, angles ); Create( "spark_shower", vecExplodeOrigin, angles, NULL ); } } } }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CNPC_Combine_Cannon::Spawn( void ) { Precache(); /// HACK: SetModel( "models/combine_soldier.mdl" ); // Setup our ancillary beams but keep them hidden for now CreateLaser(); CreateAncillaryBeams(); m_iAmmoType = GetAmmoDef()->Index( "CombineHeavyCannon" ); SetHullType( HULL_HUMAN ); SetHullSizeNormal(); UTIL_SetSize( this, Vector( -16, -16 , 0 ), Vector( 16, 16, 64 ) ); SetSolid( SOLID_BBOX ); AddSolidFlags( FSOLID_NOT_STANDABLE ); SetMoveType( MOVETYPE_FLY ); m_bloodColor = DONT_BLEED; m_iHealth = 10; m_flFieldOfView = DOT_45DEGREE; m_NPCState = NPC_STATE_NONE; if( HasSpawnFlags( SF_STARTDISABLED ) ) { m_fEnabled = false; } else { m_fEnabled = true; } CapabilitiesClear(); CapabilitiesAdd( bits_CAP_INNATE_RANGE_ATTACK1 | bits_CAP_SIMPLE_RADIUS_DAMAGE ); m_HackedGunPos = Vector ( 0, 0, 0 ); AddSpawnFlags( SF_NPC_LONG_RANGE | SF_NPC_ALWAYSTHINK ); NPCInit(); // Limit our look distance SetDistLook( m_flSightDist ); AddEffects( EF_NODRAW ); AddSolidFlags( FSOLID_NOT_SOLID ); // Point the cursor straight ahead so that the sniper's // first sweep of the laser doesn't look weird. Vector vecForward; AngleVectors( GetLocalAngles(), &vecForward ); m_vecPaintCursor = GetBulletOrigin() + vecForward * 1024; // none! GetEnemies()->SetFreeKnowledgeDuration( 0.0f ); GetEnemies()->SetEnemyDiscardTime( 2.0f ); m_flTimeLastAttackedPlayer = 0.0f; }
void CRotButton::Spawn( void ) { //---------------------------------------------------- //determine sounds for buttons //a sound of 0 should not make a sound //---------------------------------------------------- if ( m_sounds ) { m_sNoise = MakeButtonSound( m_sounds ); PrecacheScriptSound(m_sNoise.ToCStr()); } else { m_sNoise = NULL_STRING; } // set the axis of rotation CBaseToggle::AxisDir(); // check for clockwise rotation if ( HasSpawnFlags( SF_DOOR_ROTATE_BACKWARDS) ) { m_vecMoveAng = m_vecMoveAng * -1; } SetMoveType( MOVETYPE_PUSH ); #ifdef HL1_DLL SetSolid( SOLID_BSP ); #else SetSolid( SOLID_VPHYSICS ); #endif if ( HasSpawnFlags( SF_ROTBUTTON_NOTSOLID ) ) { AddEFlags( EFL_USE_PARTITION_WHEN_NOT_SOLID ); AddSolidFlags( FSOLID_NOT_SOLID ); } SetModel( STRING( GetModelName() ) ); if (m_flSpeed == 0) m_flSpeed = 40; if (m_flWait == 0) m_flWait = 1; if (m_iHealth > 0) { m_takedamage = DAMAGE_YES; } m_toggle_state = TS_AT_BOTTOM; m_vecAngle1 = GetLocalAngles(); m_vecAngle2 = GetLocalAngles() + m_vecMoveAng * m_flMoveDistance; ASSERTSZ(m_vecAngle1 != m_vecAngle2, "rotating button start/end positions are equal\n"); m_fStayPushed = (m_flWait == -1 ? TRUE : FALSE); m_fRotating = TRUE; SetUse(&CRotButton::ButtonUse); // // If touching activates the button, set its touch function. // if (!HasSpawnFlags(SF_BUTTON_TOUCH_ACTIVATES)) { SetTouch ( NULL ); } else { SetTouch( &CRotButton::ButtonTouch ); } CreateVPhysics(); }
void CAI_ScriptConditions::EvaluationThink() { if ( m_fDisabled == true ) return; int iActorsDone = 0; for ( int i = 0; i < m_ElementList.Count(); ) { CAI_ScriptConditionsElement *pConditionElement = &m_ElementList[i]; if ( pConditionElement == NULL ) { i++; continue; } CBaseEntity *pActor = pConditionElement->GetActor(); CBaseEntity *pActivator = this; #ifdef HL2_EPISODIC if ( pActor && HasSpawnFlags( SF_ACTOR_AS_ACTIVATOR ) ) { pActivator = pActor; } #endif AssertMsg( !m_fDisabled, ("Violated invariant between CAI_ScriptConditions disabled state and think func setting") ); if ( m_Actor != NULL_STRING && !pActor ) { if ( m_ElementList.Count() == 1 ) { DevMsg( "Warning: Active AI script conditions associated with an non-existant or destroyed NPC\n" ); m_NoValidActors.FireOutput( this, this, 0 ); } iActorsDone++; m_ElementList.Remove( i ); continue; } i++; if( m_flMinTimeout > 0 && pConditionElement->GetTimeOut()->Expired() ) { ScrCondDbgMsg( ( "%s firing output OnConditionsTimeout (%f seconds)\n", STRING( GetEntityName() ), pConditionElement->GetTimeOut()->GetInterval() ) ); iActorsDone++; m_OnConditionsTimeout.FireOutput( pActivator, this ); continue; } bool result = true; const int nEvaluators = sizeof( gm_Evaluators ) / sizeof( gm_Evaluators[0] ); EvalArgs_t args = { pActor, GetPlayer(), m_hTarget.Get() }; for ( int i = 0; i < nEvaluators; ++i ) { if ( !(this->*gm_Evaluators[i].pfnEvaluator)( args ) ) { pConditionElement->GetTimer()->Reset(); result = false; ScrCondDbgMsg( ( "%s failed on: %s\n", GetDebugName(), gm_Evaluators[ i ].pszName ) ); break; } } if ( result ) { ScrCondDbgMsg( ( "%s waiting... %f\n", GetDebugName(), pConditionElement->GetTimer()->GetRemaining() ) ); } if ( result && pConditionElement->GetTimer()->Expired() ) { ScrCondDbgMsg( ( "%s firing output OnConditionsSatisfied\n", GetDebugName() ) ); // Default behavior for now, provide worldcraft option later. iActorsDone++; m_OnConditionsSatisfied.FireOutput( pActivator, this ); } } //All done! if ( iActorsDone == m_ElementList.Count() ) { Disable(); m_ElementList.Purge(); } SetThinkTime(); }
//----------------------------------------------------------------------------- // Purpose: Starts the door going to its "up" position (simply ToggleData->vecPosition2). //----------------------------------------------------------------------------- void CBaseDoor::DoorGoUp( void ) { edict_t *pevActivator; UpdateAreaPortals( true ); // It could be going-down, if blocked. ASSERT(m_toggle_state == TS_AT_BOTTOM || m_toggle_state == TS_GOING_DOWN); // emit door moving and stop sounds on CHAN_STATIC so that the multicast doesn't // filter them out and leave a client stuck with looping door sounds! if ( !HasSpawnFlags(SF_DOOR_SILENT ) ) { // If we're not moving already, start the moving noise if ( m_toggle_state != TS_GOING_UP && m_toggle_state != TS_GOING_DOWN ) { StartMovingSound(); } } m_toggle_state = TS_GOING_UP; SetMoveDone( &CBaseDoor::DoorHitTop ); if ( IsRotatingDoor() ) // !!! BUGBUG Triggered doors don't work with this yet { float sign = 1.0; if ( m_hActivator != NULL ) { pevActivator = m_hActivator->edict(); if ( !HasSpawnFlags( SF_DOOR_ONEWAY ) && m_vecMoveAng.y ) // Y axis rotation, move away from the player { // Positive is CCW, negative is CW, so make 'sign' 1 or -1 based on which way we want to open. // Important note: All doors face East at all times, and twist their local angle to open. // So you can't look at the door's facing to determine which way to open. Vector nearestPoint; CollisionProp()->CalcNearestPoint( m_hActivator->GetAbsOrigin(), &nearestPoint ); Vector activatorToNearestPoint = nearestPoint - m_hActivator->GetAbsOrigin(); activatorToNearestPoint.z = 0; Vector activatorToOrigin = GetAbsOrigin() - m_hActivator->GetAbsOrigin(); activatorToOrigin.z = 0; // Point right hand at door hinge, curl hand towards closest spot on door, if thumb // is up, open door CW. -- Department of Basic Cross Product Understanding for Noobs Vector cross = activatorToOrigin.Cross( activatorToNearestPoint ); if( cross.z > 0.0f ) { sign = -1.0f; } } } AngularMove(m_vecAngle2*sign, m_flSpeed); } else { LinearMove(m_vecPosition2, m_flSpeed); } //Fire our open ouput m_OnOpen.FireOutput( this, this ); }
void CBaseButton::Spawn( ) { //---------------------------------------------------- //determine sounds for buttons //a sound of 0 should not make a sound //---------------------------------------------------- if ( m_sounds ) { m_sNoise = MakeButtonSound( m_sounds ); PrecacheScriptSound(m_sNoise.ToCStr()); } else { m_sNoise = NULL_STRING; } Precache(); if ( HasSpawnFlags( SF_BUTTON_SPARK_IF_OFF ) )// this button should spark in OFF state { SetThink ( &CBaseButton::ButtonSpark ); SetNextThink( gpGlobals->curtime + 0.5f );// no hurry, make sure everything else spawns } // Convert movedir from angles to a vector QAngle angMoveDir = QAngle( m_vecMoveDir.x, m_vecMoveDir.y, m_vecMoveDir.z ); AngleVectors( angMoveDir, &m_vecMoveDir ); SetMoveType( MOVETYPE_PUSH ); SetSolid( SOLID_BSP ); SetModel( STRING( GetModelName() ) ); if (m_flSpeed == 0) { m_flSpeed = 40; } m_takedamage = DAMAGE_YES; if (m_flWait == 0) { m_flWait = 1; } if (m_flLip == 0) { m_flLip = 4; } m_toggle_state = TS_AT_BOTTOM; m_vecPosition1 = GetLocalOrigin(); // Subtract 2 from size because the engine expands bboxes by 1 in all directions making the size too big Vector vecButtonOBB = CollisionProp()->OBBSize(); vecButtonOBB -= Vector( 2, 2, 2 ); m_vecPosition2 = m_vecPosition1 + (m_vecMoveDir * (DotProductAbs( m_vecMoveDir, vecButtonOBB ) - m_flLip)); // Is this a non-moving button? if ( ((m_vecPosition2 - m_vecPosition1).Length() < 1) || HasSpawnFlags(SF_BUTTON_DONTMOVE) ) { m_vecPosition2 = m_vecPosition1; } m_fStayPushed = (m_flWait == -1 ? TRUE : FALSE); m_fRotating = FALSE; if (HasSpawnFlags(SF_BUTTON_LOCKED)) { m_bLocked = true; } // // If using activates the button, set its use function. // if (HasSpawnFlags(SF_BUTTON_USE_ACTIVATES)) { SetUse(&CBaseButton::ButtonUse); } else { SetUse(NULL); } // // If touching activates the button, set its touch function. // if (HasSpawnFlags(SF_BUTTON_TOUCH_ACTIVATES)) { SetTouch( &CBaseButton::ButtonTouch ); } else { SetTouch ( NULL ); } CreateVPhysics(); }
//----------------------------------------------------------------------------- // Chooses an item when the player is full //----------------------------------------------------------------------------- void CItem_DynamicResupply::SpawnFullItem( CItem_DynamicResupply *pMaster, CBasePlayer *pPlayer, int iDebug ) { // Can we not actually spawn the item? if ( !HasSpawnFlags(SF_DYNAMICRESUPPLY_ALWAYS_SPAWN) ) return; float flRatio[NUM_AMMO_ITEMS]; int i; float flTotalProb = 0.0f; for ( i = 0; i < NUM_AMMO_ITEMS; ++i ) { int iAmmoType = GetAmmoDef()->Index( g_DynamicResupplyAmmoItems[i].sAmmoDef ); bool bCanSpawn = pPlayer->Weapon_GetWpnForAmmo( iAmmoType ) != NULL; if ( bCanSpawn && ( g_DynamicResupplyAmmoItems[i].flFullProbability != 0 ) && ( pMaster->m_flDesiredAmmo[i] != 0.0f ) ) { flTotalProb += g_DynamicResupplyAmmoItems[i].flFullProbability; flRatio[i] = flTotalProb; } else { flRatio[i] = -1.0f; } } if ( flTotalProb == 0.0f ) { // If we're supposed to fallback to just a health vial, do that and finish. if ( pMaster->HasSpawnFlags(SF_DYNAMICRESUPPLY_FALLBACK_TO_VIAL) ) { CBaseEntity::Create( "item_healthvial", GetAbsOrigin(), GetAbsAngles(), this ); if ( iDebug ) { Msg("Player is full, spawning item_healthvial due to spawnflag.\n", g_DynamicResupplyAmmoItems[i].sEntityName ); } return; } // Otherwise, spawn the first ammo item in the list flRatio[0] = 1.0f; flTotalProb = 1.0f; } float flChoice = random->RandomFloat( 0.0f, flTotalProb ); for ( i = 0; i < NUM_AMMO_ITEMS; ++i ) { if ( flChoice <= flRatio[i] ) { CBaseEntity::Create( g_DynamicResupplyAmmoItems[i].sEntityName, GetAbsOrigin(), GetAbsAngles(), this ); if ( iDebug ) { Msg("Player is full, spawning %s \n", g_DynamicResupplyAmmoItems[i].sEntityName ); } return; } } if ( iDebug ) { Msg("Player is full on all health + ammo, is not spawning.\n" ); } }
//----------------------------------------------------------------------------- // Purpose: Returns whether or not it is OK to make an NPC at this instant. //----------------------------------------------------------------------------- bool CBaseNPCMaker::CanMakeNPC( bool bIgnoreSolidEntities ) { if( ai_inhibit_spawners.GetBool() ) return false; if ( m_nMaxLiveChildren > 0 && m_nLiveChildren >= m_nMaxLiveChildren ) {// not allowed to make a new one yet. Too many live ones out right now. return false; } if ( m_iszIngoreEnt != NULL_STRING ) { m_hIgnoreEntity = gEntList.FindEntityByName( NULL, m_iszIngoreEnt ); } Vector mins = GetAbsOrigin() - Vector( 34, 34, 0 ); Vector maxs = GetAbsOrigin() + Vector( 34, 34, 0 ); maxs.z = GetAbsOrigin().z; // If we care about not hitting solid entities, look for 'em if ( !bIgnoreSolidEntities ) { CBaseEntity *pList[128]; int count = UTIL_EntitiesInBox( pList, 128, mins, maxs, FL_CLIENT|FL_NPC ); if ( count ) { //Iterate through the list and check the results for ( int i = 0; i < count; i++ ) { //Don't build on top of another entity if ( pList[i] == NULL ) continue; //If one of the entities is solid, then we may not be able to spawn now if ( ( pList[i]->GetSolidFlags() & FSOLID_NOT_SOLID ) == false ) { // Since the outer method doesn't work well around striders on account of their huge bounding box. // Find the ground under me and see if a human hull would fit there. trace_t tr; UTIL_TraceHull( GetAbsOrigin() + Vector( 0, 0, 2 ), GetAbsOrigin() - Vector( 0, 0, 8192 ), NAI_Hull::Mins(HULL_HUMAN), NAI_Hull::Maxs(HULL_HUMAN), MASK_NPCSOLID, m_hIgnoreEntity, COLLISION_GROUP_NONE, &tr ); if( !HumanHullFits( tr.endpos + Vector( 0, 0, 1 ) ) ) { return false; } } } } } // Do we need to check to see if the player's looking? if ( HasSpawnFlags( SF_NPCMAKER_HIDEFROMPLAYER ) ) { for ( int i = 1; i <= gpGlobals->maxClients; i++ ) { CBasePlayer *pPlayer = UTIL_PlayerByIndex(i); if ( pPlayer ) { // Only spawn if the player's looking away from me if( pPlayer->FInViewCone( GetAbsOrigin() ) && pPlayer->FVisible( GetAbsOrigin() ) ) { if ( !(pPlayer->GetFlags() & FL_NOTARGET) ) return false; DevMsg( 2, "Spawner %s spawning even though seen due to notarget\n", STRING( GetEntityName() ) ); } } } } return true; }
//----------------------------------------------------------------------------- // Purpose: Called when spawning, after keyvalues have been set. //----------------------------------------------------------------------------- void CFuncRotating::Spawn( ) { #ifdef TF_DLL AddSpawnFlags( SF_BRUSH_ROTATE_CLIENTSIDE ); #endif // // Maintain compatibility with previous maps. // if (m_flVolume == 0.0) { m_flVolume = 1.0; } // // If the designer didn't set a sound attenuation, default to one. // if ( HasSpawnFlags(SF_BRUSH_ROTATE_SMALLRADIUS) ) { m_flAttenuation = ATTN_IDLE; } else if ( HasSpawnFlags(SF_BRUSH_ROTATE_MEDIUMRADIUS) ) { m_flAttenuation = ATTN_STATIC; } else if ( HasSpawnFlags(SF_BRUSH_ROTATE_LARGERADIUS) ) { m_flAttenuation = ATTN_NORM; } else { m_flAttenuation = ATTN_NORM; } // // Prevent divide by zero if level designer forgets friction! // if ( m_flFanFriction == 0 ) { m_flFanFriction = 1; } // // Build the axis of rotation based on spawnflags. // if ( HasSpawnFlags(SF_BRUSH_ROTATE_Z_AXIS) ) { m_vecMoveAng = QAngle(0,0,1); } else if ( HasSpawnFlags(SF_BRUSH_ROTATE_X_AXIS) ) { m_vecMoveAng = QAngle(1,0,0); } else { m_vecMoveAng = QAngle(0,1,0); // y-axis } // // Check for reverse rotation. // if ( HasSpawnFlags(SF_BRUSH_ROTATE_BACKWARDS) ) { m_vecMoveAng = m_vecMoveAng * -1; } SetSolid( SOLID_VPHYSICS ); // // Some rotating objects like fake volumetric lights will not be solid. // if ( HasSpawnFlags(SF_ROTATING_NOT_SOLID) ) { AddSolidFlags( FSOLID_NOT_SOLID ); SetMoveType( MOVETYPE_PUSH ); } else { RemoveSolidFlags( FSOLID_NOT_SOLID ); SetMoveType( MOVETYPE_PUSH ); } SetModel( STRING( GetModelName() ) ); SetUse( &CFuncRotating::RotatingUse ); // // Did level designer forget to assign a maximum speed? Prevent a divide by // zero in RampPitchVol as well as allowing the rotator to work. // m_flMaxSpeed = fabs( m_flMaxSpeed ); if (m_flMaxSpeed == 0) { m_flMaxSpeed = 100; } // // If the brush should be initially rotating, use it in a little while. // if ( HasSpawnFlags(SF_BRUSH_ROTATE_START_ON) ) { SetThink( &CFuncRotating::SUB_CallUseToggle ); SetNextThink( gpGlobals->curtime + .2 ); // leave a magic delay for client to start up } // // Can this brush inflict pain? // if ( HasSpawnFlags(SF_BRUSH_HURT) ) { SetTouch( &CFuncRotating::HurtTouch ); } // // Set speed to 0 in case there's an old "speed" key lying around. // m_flSpeed = 0; Precache( ); CreateVPhysics(); m_angStart = GetLocalAngles(); // Slam the object back to solid - if we really want it to be solid. if ( m_bSolidBsp ) { SetSolid( SOLID_BSP ); } if ( HasSpawnFlags(SF_BRUSH_ROTATE_CLIENTSIDE) ) { m_vecClientOrigin = GetLocalOrigin(); m_vecClientAngles = GetLocalAngles(); } }
void CTriggerMomentumPush::EndTouch(CBaseEntity *pOther) { if (pOther && HasSpawnFlags(SF_PUSH_ONEND) && pOther->IsPlayer()) OnSuccessfulTouch(pOther); }
bool IsMaster( void ) const { return HasSpawnFlags( SF_TONEMAP_MASTER ); }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CASW_Broadcast_Camera::FollowTarget( ) { //if (m_hPlayer == NULL) //return; if ( m_hTarget == NULL ) { Disable(); return; } if ( !HasSpawnFlags(SF_CAMERA_PLAYER_INFINITE_WAIT) && (!m_hTarget || m_flReturnTime < gpGlobals->curtime) ) { Disable(); return; } UpdateAllPlayers(); QAngle vecGoal; if ( m_iAttachmentIndex ) { Vector vecOrigin; m_hTarget->GetBaseAnimating()->GetAttachment( m_iAttachmentIndex, vecOrigin ); VectorAngles( vecOrigin - GetAbsOrigin(), vecGoal ); } else { if ( m_hTarget ) { VectorAngles( m_hTarget->GetAbsOrigin() - GetAbsOrigin(), vecGoal ); } else { // Use the viewcontroller's angles vecGoal = GetAbsAngles(); } } // Should we just snap to the goal angles? if ( m_bSnapToGoal ) { SetAbsAngles( vecGoal ); m_bSnapToGoal = false; } else { // UNDONE: Can't we just use UTIL_AngleDiff here? QAngle angles = GetLocalAngles(); if (angles.y > 360) angles.y -= 360; if (angles.y < 0) angles.y += 360; SetLocalAngles( angles ); float dx = vecGoal.x - GetLocalAngles().x; float dy = vecGoal.y - GetLocalAngles().y; if (dx < -180) dx += 360; if (dx > 180) dx = dx - 360; if (dy < -180) dy += 360; if (dy > 180) dy = dy - 360; QAngle vecAngVel; vecAngVel.Init( dx * 40 * gpGlobals->frametime, dy * 40 * gpGlobals->frametime, GetLocalAngularVelocity().z ); SetLocalAngularVelocity(vecAngVel); } if (!HasSpawnFlags(SF_CAMERA_PLAYER_TAKECONTROL)) { SetAbsVelocity( GetAbsVelocity() * 0.8 ); if (GetAbsVelocity().Length( ) < 10.0) { SetAbsVelocity( vec3_origin ); } } SetNextThink( gpGlobals->curtime ); Move(); }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CASW_Broadcast_Camera::Enable( void ) { m_state = USE_ON; //if ( !m_hPlayer || !m_hPlayer->IsPlayer() ) //{ //m_hPlayer = UTIL_GetLocalPlayer(); //} //if ( !m_hPlayer ) //{ //DispatchUpdateTransmitState(); //return; //} //if ( m_hPlayer->IsPlayer() ) //{ //m_nPlayerButtons = ((CBasePlayer*)m_hPlayer.Get())->m_nButtons; //} //if ( HasSpawnFlags( SF_CAMERA_PLAYER_NOT_SOLID ) ) //{ //m_hPlayer->AddSolidFlags( FSOLID_NOT_SOLID ); //} m_flReturnTime = gpGlobals->curtime + m_flWait; m_flSpeed = m_initialSpeed; m_targetSpeed = m_initialSpeed; if ( HasSpawnFlags( SF_CAMERA_PLAYER_SNAP_TO ) ) { m_bSnapToGoal = true; } //if ( HasSpawnFlags(SF_CAMERA_PLAYER_TARGET ) ) //{ //m_hTarget = m_hPlayer; //} //else //{ m_hTarget = GetNextTarget(); //} // If we don't have a target, ignore the attachment / etc if ( m_hTarget ) { m_iAttachmentIndex = 0; if ( m_iszTargetAttachment != NULL_STRING ) { if ( !m_hTarget->GetBaseAnimating() ) { Warning("%s tried to target an attachment (%s) on target %s, which has no model.\n", GetClassname(), STRING(m_iszTargetAttachment), STRING(m_hTarget->GetEntityName()) ); } else { m_iAttachmentIndex = m_hTarget->GetBaseAnimating()->LookupAttachment( STRING(m_iszTargetAttachment) ); if ( !m_iAttachmentIndex ) { Warning("%s could not find attachment %s on target %s.\n", GetClassname(), STRING(m_iszTargetAttachment), STRING(m_hTarget->GetEntityName()) ); } } } } //if (HasSpawnFlags(SF_CAMERA_PLAYER_TAKECONTROL ) ) //{ //((CBasePlayer*)m_hPlayer.Get())->EnableControl(FALSE); //} if ( m_sPath != NULL_STRING ) { m_pPath = gEntList.FindEntityByName( NULL, m_sPath, NULL); //, m_hPlayer ); } else { m_pPath = NULL; } m_flStopTime = gpGlobals->curtime; if ( m_pPath ) { if ( m_pPath->m_flSpeed != 0 ) m_targetSpeed = m_pPath->m_flSpeed; m_flStopTime += m_pPath->GetDelay(); m_vecMoveDir = m_pPath->GetLocalOrigin() - GetLocalOrigin(); m_moveDistance = VectorNormalize( m_vecMoveDir ); m_flStopTime = gpGlobals->curtime + m_pPath->GetDelay(); } else { m_moveDistance = 0; } /* if ( m_pPath ) { if ( m_pPath->m_flSpeed != 0 ) m_targetSpeed = m_pPath->m_flSpeed; Msg("target speed is %f\n", m_targetSpeed); m_flStopTime += m_pPath->GetDelay(); } */ // copy over player information //if (HasSpawnFlags(SF_CAMERA_PLAYER_POSITION ) ) //{ //UTIL_SetOrigin( this, m_hPlayer->EyePosition() ); //SetLocalAngles( QAngle( m_hPlayer->GetLocalAngles().x, m_hPlayer->GetLocalAngles().y, 0 ) ); //SetAbsVelocity( m_hPlayer->GetAbsVelocity() ); //} //else //{ SetAbsVelocity( vec3_origin ); //} UpdateAllPlayers(); //((CBasePlayer*)m_hPlayer.Get())->SetViewEntity( this ); // Hide the player's viewmodel //if ( ((CBasePlayer*)m_hPlayer.Get())->GetActiveWeapon() ) //{ //((CBasePlayer*)m_hPlayer.Get())->GetActiveWeapon()->AddEffects( EF_NODRAW ); //} // Only track if we have a target if ( m_hTarget ) { // follow the player down SetThink( &CASW_Broadcast_Camera::FollowTarget ); SetNextThink( gpGlobals->curtime ); } //m_moveDistance = 0; m_vecLastPos = GetAbsOrigin(); Move(); DispatchUpdateTransmitState(); }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CFuncLadder::Spawn() { BaseClass::Spawn(); // Entity is symbolid SetSolid( SOLID_NONE ); SetMoveType( MOVETYPE_NONE ); SetCollisionGroup( COLLISION_GROUP_NONE ); //AddFlag( FL_WORLDBRUSH ); SetModelName( NULL_STRING ); // Make entity invisible AddEffects( EF_NODRAW ); // No model but should still network AddEFlags( EFL_FORCE_CHECK_TRANSMIT ); Vector playerMins = VEC_HULL_MIN; Vector playerMaxs = VEC_HULL_MAX; // This will swap them if they are inverted SetEndPoints( m_vecPlayerMountPositionTop, m_vecPlayerMountPositionBottom ); #if !defined( CLIENT_DLL ) trace_t bottomtrace, toptrace; UTIL_TraceHull( m_vecPlayerMountPositionBottom, m_vecPlayerMountPositionBottom, playerMins, playerMaxs, MASK_PLAYERSOLID_BRUSHONLY, NULL, COLLISION_GROUP_PLAYER_MOVEMENT, &bottomtrace ); UTIL_TraceHull( m_vecPlayerMountPositionTop, m_vecPlayerMountPositionTop, playerMins, playerMaxs, MASK_PLAYERSOLID_BRUSHONLY, NULL, COLLISION_GROUP_PLAYER_MOVEMENT, &toptrace ); if ( bottomtrace.startsolid || toptrace.startsolid ) { if ( bottomtrace.startsolid ) { DevMsg( 1, "Warning, funcladder with blocked bottom point (%.2f %.2f %.2f) stuck in (%s)\n", m_vecPlayerMountPositionBottom.GetX(), m_vecPlayerMountPositionBottom.GetY(), m_vecPlayerMountPositionBottom.GetZ(), bottomtrace.m_pEnt ? UTIL_VarArgs( "%s/%s", bottomtrace.m_pEnt->GetClassname(), bottomtrace.m_pEnt->GetEntityName().ToCStr() ) //UTIL_VarArgs( "%s/%s", bottomtrace.m_pEnt->GetClassname(), STRING(bottomtrace.m_pEnt->GetEntityName()) ) ? : "NULL" ); } if ( toptrace.startsolid ) { DevMsg( 1, "Warning, funcladder with blocked top point (%.2f %.2f %.2f) stuck in (%s)\n", m_vecPlayerMountPositionTop.GetX(), m_vecPlayerMountPositionTop.GetY(), m_vecPlayerMountPositionTop.GetZ(), toptrace.m_pEnt ? UTIL_VarArgs( "%s/%s", toptrace.m_pEnt->GetClassname(), toptrace.m_pEnt->GetEntityName().ToCStr() ) //UTIL_VarArgs( "%s/%s", toptrace.m_pEnt->GetClassname(), STRING(toptrace.m_pEnt->GetEntityName()) ) ? : "NULL" ); } // Force geometry overlays on, but only if developer 2 is set... if ( developer.GetInt() > 1 ) { m_debugOverlays |= OVERLAY_TEXT_BIT; } } m_vecPlayerMountPositionTop -= GetAbsOrigin(); m_vecPlayerMountPositionBottom -= GetAbsOrigin(); // Compute mins, maxs of points // Vector mins( MAX_COORD_INTEGER, MAX_COORD_INTEGER, MAX_COORD_INTEGER ); Vector maxs( -MAX_COORD_INTEGER, -MAX_COORD_INTEGER, -MAX_COORD_INTEGER ); int i; for ( i = 0; i < 3; i++ ) { if ( m_vecPlayerMountPositionBottom.m_Value[ i ] < mins[ i ] ) { mins[ i ] = m_vecPlayerMountPositionBottom.m_Value[ i ]; } if ( m_vecPlayerMountPositionBottom.m_Value[ i ] > maxs[ i ] ) { maxs[ i ] = m_vecPlayerMountPositionBottom.m_Value[ i ]; } if ( m_vecPlayerMountPositionTop.m_Value[ i ] < mins[ i ] ) { mins[ i ] = m_vecPlayerMountPositionTop.m_Value[ i ]; } if ( m_vecPlayerMountPositionTop.m_Value[ i ] > maxs[ i ] ) { maxs[ i ] = m_vecPlayerMountPositionTop.m_Value[ i ]; } } // Expand mins/maxs by player hull size mins += playerMins; maxs += playerMaxs; UTIL_SetSize( this, mins, maxs ); m_bFakeLadder = HasSpawnFlags(SF_LADDER_DONTGETON); #endif }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CTemplateNPCMaker::MakeNPC( void ) { // If we should be using the radius spawn method instead, do so if ( m_flRadius && HasSpawnFlags(SF_NPCMAKER_ALWAYSUSERADIUS) ) { MakeNPCInRadius(); return; } if (!CanMakeNPC( ( m_iszDestinationGroup != NULL_STRING ) )) return; CNPCSpawnDestination *pDestination = NULL; if ( m_iszDestinationGroup != NULL_STRING ) { pDestination = FindSpawnDestination(); if ( !pDestination ) { DevMsg( 2, "%s '%s' failed to find a valid spawnpoint in destination group: '%s'\n", GetClassname(), STRING(GetEntityName()), STRING(m_iszDestinationGroup) ); return; } } CAI_BaseNPC *pent = NULL; CBaseEntity *pEntity = NULL; MapEntity_ParseEntity( pEntity, STRING(m_iszTemplateData), NULL ); if ( pEntity != NULL ) { pent = (CAI_BaseNPC *)pEntity; } if ( !pent ) { Warning("NULL Ent in NPCMaker!\n" ); return; } if ( pDestination ) { pent->SetAbsOrigin( pDestination->GetAbsOrigin() ); // Strip pitch and roll from the spawner's angles. Pass only yaw to the spawned NPC. QAngle angles = pDestination->GetAbsAngles(); angles.x = 0.0; angles.z = 0.0; pent->SetAbsAngles( angles ); pDestination->OnSpawnedNPC( pent ); } else { pent->SetAbsOrigin( GetAbsOrigin() ); // Strip pitch and roll from the spawner's angles. Pass only yaw to the spawned NPC. QAngle angles = GetAbsAngles(); angles.x = 0.0; angles.z = 0.0; pent->SetAbsAngles( angles ); } m_OnSpawnNPC.Set( pEntity, pEntity, this ); if ( m_spawnflags & SF_NPCMAKER_FADE ) { pent->AddSpawnFlags( SF_NPC_FADE_CORPSE ); } pent->RemoveSpawnFlags( SF_NPC_TEMPLATE ); if ( ( m_spawnflags & SF_NPCMAKER_NO_DROP ) == false ) { pent->RemoveSpawnFlags( SF_NPC_FALL_TO_GROUND ); // don't fall, slam } ChildPreSpawn( pent ); DispatchSpawn( pent ); pent->SetOwnerEntity( this ); DispatchActivate( pent ); ChildPostSpawn( pent ); m_nLiveChildren++;// count this NPC if (!(m_spawnflags & SF_NPCMAKER_INF_CHILD)) { m_nMaxNumNPCs--; if ( IsDepleted() ) { m_OnAllSpawned.FireOutput( this, this ); // Disable this forever. Don't kill it because it still gets death notices SetThink( NULL ); SetUse( NULL ); } } }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CBaseDoor::Spawn() { Precache(); #ifdef HL1_DLL SetSolid( SOLID_BSP ); #else if ( GetMoveParent() && GetRootMoveParent()->GetSolid() == SOLID_BSP ) { SetSolid( SOLID_BSP ); } else { SetSolid( SOLID_VPHYSICS ); } #endif // Convert movedir from angles to a vector QAngle angMoveDir = QAngle( m_vecMoveDir.x, m_vecMoveDir.y, m_vecMoveDir.z ); AngleVectors( angMoveDir, &m_vecMoveDir ); SetModel( STRING( GetModelName() ) ); m_vecPosition1 = GetLocalOrigin(); // Subtract 2 from size because the engine expands bboxes by 1 in all directions making the size too big Vector vecOBB = CollisionProp()->OBBSize(); vecOBB -= Vector( 2, 2, 2 ); m_vecPosition2 = m_vecPosition1 + (m_vecMoveDir * (DotProductAbs( m_vecMoveDir, vecOBB ) - m_flLip)); if ( !IsRotatingDoor() ) { if ( ( m_eSpawnPosition == FUNC_DOOR_SPAWN_OPEN ) || HasSpawnFlags( SF_DOOR_START_OPEN_OBSOLETE ) ) { // swap pos1 and pos2, put door at pos2 UTIL_SetOrigin( this, m_vecPosition2); m_toggle_state = TS_AT_TOP; } else { m_toggle_state = TS_AT_BOTTOM; } } if (HasSpawnFlags(SF_DOOR_LOCKED)) { m_bLocked = true; } SetMoveType( MOVETYPE_PUSH ); if (m_flSpeed == 0) { m_flSpeed = 100; } SetTouch( &CBaseDoor::DoorTouch ); if ( !FClassnameIs( this, "func_water" ) ) { if ( HasSpawnFlags(SF_DOOR_PASSABLE) ) { //normal door AddEFlags( EFL_USE_PARTITION_WHEN_NOT_SOLID ); AddSolidFlags( FSOLID_NOT_SOLID ); } if ( HasSpawnFlags( SF_DOOR_NONSOLID_TO_PLAYER ) ) { SetCollisionGroup( COLLISION_GROUP_PASSABLE_DOOR ); // HACKHACK: Set this hoping that any children of the door that get blocked by the player // will get fixed up by vphysics // NOTE: We could decouple this as a separate behavior, but managing player collisions is already complex enough. // NOTE: This is necessary to prevent the player from blocking the wrecked train car in ep2_outland_01 AddFlag( FL_UNBLOCKABLE_BY_PLAYER ); } if ( m_bIgnoreDebris ) { // both of these flags want to set the collision group and // there isn't a combo group Assert( !HasSpawnFlags( SF_DOOR_NONSOLID_TO_PLAYER ) ); if ( HasSpawnFlags( SF_DOOR_NONSOLID_TO_PLAYER ) ) { Warning("Door %s with conflicting collision settings, removing ignoredebris\n", GetDebugName() ); } else { SetCollisionGroup( COLLISION_GROUP_INTERACTIVE ); } } } if ( ( m_eSpawnPosition == FUNC_DOOR_SPAWN_OPEN ) && HasSpawnFlags( SF_DOOR_START_OPEN_OBSOLETE ) ) { Warning("Door %s using obsolete 'Start Open' spawnflag with 'Spawn Position' set to 'Open'. Reverting to old behavior.\n", GetDebugName() ); } CreateVPhysics(); }
//----------------------------------------------------------------------------- // Purpose: // Input : &info - // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- void CNPC_CombineS::Event_Killed( const CTakeDamageInfo &info ) { // Don't bother if we've been told not to, or the player has a megaphyscannon if ( combine_spawn_health.GetBool() == false || PlayerHasMegaPhysCannon() ) { BaseClass::Event_Killed( info ); return; } CBasePlayer *pPlayer = ToBasePlayer( info.GetAttacker() ); if ( !pPlayer ) { CPropVehicleDriveable *pVehicle = dynamic_cast<CPropVehicleDriveable *>( info.GetAttacker() ) ; if ( pVehicle && pVehicle->GetDriver() && pVehicle->GetDriver()->IsPlayer() ) { pPlayer = assert_cast<CBasePlayer *>( pVehicle->GetDriver() ); } } if ( pPlayer != NULL ) { // Elites drop alt-fire ammo, so long as they weren't killed by dissolving. if( IsElite() ) { #ifdef HL2_EPISODIC if ( HasSpawnFlags( SF_COMBINE_NO_AR2DROP ) == false ) #endif { CBaseEntity *pItem = DropItem( "item_ammo_ar2_altfire", WorldSpaceCenter()+RandomVector(-4,4), RandomAngle(0,360) ); if ( pItem ) { IPhysicsObject *pObj = pItem->VPhysicsGetObject(); if ( pObj ) { Vector vel = RandomVector( -64.0f, 64.0f ); AngularImpulse angImp = RandomAngularImpulse( -300.0f, 300.0f ); vel[2] = 0.0f; pObj->AddVelocity( &vel, &angImp ); } if( info.GetDamageType() & DMG_DISSOLVE ) { CBaseAnimating *pAnimating = dynamic_cast<CBaseAnimating*>(pItem); if( pAnimating ) { pAnimating->Dissolve( NULL, gpGlobals->curtime, false, ENTITY_DISSOLVE_NORMAL ); } } else { WeaponManager_AddManaged( pItem ); } } } } #ifdef HL2_DLL CHalfLife2 *pGameRules = static_cast<CHalfLife2 *>(g_pGameRules); #elif defined(TF_CLASSIC) CTFGameRules *pGameRules = TFGameRules(); #endif // Attempt to drop health if ( pGameRules->NPC_ShouldDropHealth( pPlayer ) ) { DropItem( "item_healthvial", WorldSpaceCenter()+RandomVector(-4,4), RandomAngle(0,360) ); pGameRules->NPC_DroppedHealth(); } // Don't drop grenades in TF2C, TF2 players don't need that. #ifndef TF_CLASSIC if ( HasSpawnFlags( SF_COMBINE_NO_GRENADEDROP ) == false ) { // Attempt to drop a grenade if ( pGameRules->NPC_ShouldDropGrenade( pPlayer ) ) { DropItem( "weapon_frag", WorldSpaceCenter()+RandomVector(-4,4), RandomAngle(0,360) ); pGameRules->NPC_DroppedGrenade(); } } #endif } BaseClass::Event_Killed( info ); }
//----------------------------------------------------------------------------- // Purpose: // Input : pActivator - // pCaller - // useType - // value - //----------------------------------------------------------------------------- void CMomentaryRotButton::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) { if ( m_bDisabled == true ) return; if (m_bLocked) { if ( OnUseLocked( pActivator ) && HasSpawnFlags( SF_BUTTON_JIGGLE_ON_USE_LOCKED ) ) { // Jiggle two degrees. float flDist = 2.0 / m_flMoveDistance; // Must be first! g_EventQueue.AddEvent( this, "_DisableUpdateTarget", 0, this, this ); variant_t value; value.SetFloat( flDist ); g_EventQueue.AddEvent( this, "SetPosition", value, 0.01, this, this ); value.SetFloat( 0.0 ); g_EventQueue.AddEvent( this, "SetPosition", value, 0.1, this, this ); value.SetFloat( 0.5 * flDist ); g_EventQueue.AddEvent( this, "SetPosition", value, 0.2, this, this ); value.SetFloat( 0.0 ); g_EventQueue.AddEvent( this, "SetPosition", value, 0.3, this, this ); // Must be last! And must be late enough to cover the settling time. g_EventQueue.AddEvent( this, "_EnableUpdateTarget", 0.5, this, this ); } return; } // // Reverse our direction and play movement sound every time the player // pauses between uses. // bool bPlaySound = false; if ( !m_lastUsed ) { bPlaySound = true; m_direction = -m_direction; //Alert that we've been pressed m_OnPressed.FireOutput( m_hActivator, this ); } m_lastUsed = 1; float flPos = GetPos( GetLocalAngles() ); UpdateSelf( flPos, bPlaySound ); // // Think every frame while we are moving. // HACK: Don't reset the think time if we already have a pending think. // This works around an issue with host_thread_mode > 0 when the player's // clock runs ahead of the server. // if ( !m_pfnThink ) { SetThink( &CMomentaryRotButton::UpdateThink ); SetNextThink( gpGlobals->curtime ); } }
//----------------------------------------------------------------------------- // Purpose: // Input : &info - // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- void CNPC_CombineAce::Event_Killed( const CTakeDamageInfo &info ) { if (!(g_Language.GetInt() == LANGUAGE_GERMAN || UTIL_IsLowViolence()) && info.GetDamageType() & (DMG_BLAST | DMG_CRUSH) && !(info.GetDamageType() & (DMG_DISSOLVE)) && !PlayerHasMegaPhysCannon()) { Vector vecDamageDir = info.GetDamageForce(); SpawnBlood(GetAbsOrigin(), g_vecAttackDir, BloodColor(), info.GetDamage()); DispatchParticleEffect("headshotspray", GetAbsOrigin(), GetAbsAngles(), this); EmitSound("Gore.Headshot"); float flFadeTime = 25.0; CGib::SpawnSpecificGibs(this, 1, 750, 1500, "models/gibs/soldier_ace_head.mdl", flFadeTime); Vector vecRagForce; vecRagForce.x = random->RandomFloat(-400, 400); vecRagForce.y = random->RandomFloat(-400, 400); vecRagForce.z = random->RandomFloat(0, 250); Vector vecRagDmgForce = (vecRagForce + vecDamageDir); CBaseEntity *pLeftArmGib = CreateRagGib("models/gibs/soldier_ace_left_arm.mdl", GetAbsOrigin(), GetAbsAngles(), vecRagDmgForce, flFadeTime, IsOnFire()); if (pLeftArmGib) { color32 color = pLeftArmGib->GetRenderColor(); pLeftArmGib->SetRenderColor(color.r, color.g, color.b, color.a); } CBaseEntity *pRightArmGib = CreateRagGib("models/gibs/soldier_ace_right_arm.mdl", GetAbsOrigin(), GetAbsAngles(), vecRagDmgForce, flFadeTime, IsOnFire()); if (pRightArmGib) { color32 color = pRightArmGib->GetRenderColor(); pRightArmGib->SetRenderColor(color.r, color.g, color.b, color.a); } CBaseEntity *pTorsoGib = CreateRagGib("models/gibs/soldier_ace_torso.mdl", GetAbsOrigin(), GetAbsAngles(), vecRagDmgForce, flFadeTime, IsOnFire()); if (pTorsoGib) { color32 color = pTorsoGib->GetRenderColor(); pTorsoGib->SetRenderColor(color.r, color.g, color.b, color.a); } CBaseEntity *pPelvisGib = CreateRagGib("models/gibs/soldier_ace_pelvis.mdl", GetAbsOrigin(), GetAbsAngles(), vecRagDmgForce, flFadeTime, IsOnFire()); if (pPelvisGib) { color32 color = pPelvisGib->GetRenderColor(); pPelvisGib->SetRenderColor(color.r, color.g, color.b, color.a); } CBaseEntity *pLeftLegGib = CreateRagGib("models/gibs/soldier_ace_left_leg.mdl", GetAbsOrigin(), GetAbsAngles(), vecRagDmgForce, flFadeTime, IsOnFire()); if (pLeftLegGib) { color32 color = pLeftLegGib->GetRenderColor(); pLeftLegGib->SetRenderColor(color.r, color.g, color.b, color.a); } CBaseEntity *pRightLegGib = CreateRagGib("models/gibs/soldier_ace_right_leg.mdl", GetAbsOrigin(), GetAbsAngles(), vecRagDmgForce, flFadeTime, IsOnFire()); if (pRightLegGib) { color32 color = pRightLegGib->GetRenderColor(); pRightLegGib->SetRenderColor(color.r, color.g, color.b, color.a); } //now add smaller gibs. CGib::SpawnSpecificGibs(this, 3, 750, 1500, "models/gibs/pgib_p3.mdl", flFadeTime); CGib::SpawnSpecificGibs(this, 3, 750, 1500, "models/gibs/pgib_p4.mdl", flFadeTime); if (!m_bNoArmor && combine_ace_shieldspawnmode.GetInt() > 0) { pArmor->Remove(); DropItem("item_shield", WorldSpaceCenter() + RandomVector(-4, 4), RandomAngle(0, 360)); } Vector forceVector = CalcDamageForceVector(info); // Drop any weapon that I own if (VPhysicsGetObject()) { Vector weaponForce = forceVector * VPhysicsGetObject()->GetInvMass(); Weapon_Drop(m_hActiveWeapon, NULL, &weaponForce); } else { Weapon_Drop(m_hActiveWeapon); } if (info.GetAttacker()->IsPlayer()) { ((CSingleplayRules*)GameRules())->NPCKilled(this, info); } UTIL_Remove(this); SetThink(NULL); return; } // Don't bother if we've been told not to, or the player has a megaphyscannon if ( combine_ace_spawn_health.GetBool() == false || PlayerHasMegaPhysCannon() ) { BaseClass::Event_Killed( info ); return; } SetEyeState(ACE_EYE_DEAD); if (!m_bNoArmor && combine_ace_shieldspawnmode.GetInt() > 0) { pArmor->Remove(); } CBasePlayer *pPlayer = ToBasePlayer( info.GetAttacker() ); if ( !pPlayer ) { CPropVehicleDriveable *pVehicle = dynamic_cast<CPropVehicleDriveable *>( info.GetAttacker() ) ; if ( pVehicle && pVehicle->GetDriver() && pVehicle->GetDriver()->IsPlayer() ) { pPlayer = assert_cast<CBasePlayer *>( pVehicle->GetDriver() ); } } if ( pPlayer != NULL ) { // Elites drop alt-fire ammo, so long as they weren't killed by dissolving. #ifdef HL2_EPISODIC if (HasSpawnFlags(SF_COMBINE_NO_AR2DROP) == false) #endif { if (FClassnameIs(GetActiveWeapon(), "weapon_ar2")) { CBaseEntity *pItem = DropItem("item_ammo_ar2_altfire", WorldSpaceCenter() + RandomVector(-4, 4), RandomAngle(0, 360)); if (pItem) { IPhysicsObject *pObj = pItem->VPhysicsGetObject(); if (pObj) { Vector vel = RandomVector(-64.0f, 64.0f); AngularImpulse angImp = RandomAngularImpulse(-300.0f, 300.0f); vel[2] = 0.0f; pObj->AddVelocity(&vel, &angImp); } if (info.GetDamageType() & DMG_DISSOLVE) { CBaseAnimating *pAnimating = dynamic_cast<CBaseAnimating*>(pItem); if (pAnimating) { pAnimating->Dissolve(NULL, gpGlobals->curtime, false, ENTITY_DISSOLVE_NORMAL); } } else { WeaponManager_AddManaged(pItem); } } } else if (FClassnameIs(GetActiveWeapon(), "weapon_smg1")) { CBaseEntity *pItem = DropItem("item_ammo_smg1_grenade", WorldSpaceCenter() + RandomVector(-4, 4), RandomAngle(0, 360)); if (pItem) { IPhysicsObject *pObj = pItem->VPhysicsGetObject(); if (pObj) { Vector vel = RandomVector(-64.0f, 64.0f); AngularImpulse angImp = RandomAngularImpulse(-300.0f, 300.0f); vel[2] = 0.0f; pObj->AddVelocity(&vel, &angImp); } if (info.GetDamageType() & DMG_DISSOLVE) { CBaseAnimating *pAnimating = dynamic_cast<CBaseAnimating*>(pItem); if (pAnimating) { pAnimating->Dissolve(NULL, gpGlobals->curtime, false, ENTITY_DISSOLVE_NORMAL); } } else { WeaponManager_AddManaged(pItem); } } } } CHalfLife2 *pHL2GameRules = static_cast<CHalfLife2 *>(g_pGameRules); // Attempt to drop health if ( pHL2GameRules->NPC_ShouldDropHealth( pPlayer ) ) { DropItem( "item_healthvial", WorldSpaceCenter()+RandomVector(-4,4), RandomAngle(0,360) ); pHL2GameRules->NPC_DroppedHealth(); } if (!m_bNoArmor && combine_ace_shieldspawnmode.GetInt() > 0) { DropItem("item_shield", WorldSpaceCenter() + RandomVector(-4, 4), RandomAngle(0, 360)); } } BaseClass::Event_Killed( info ); }
//----------------------------------------------------------------------------- // Purpose: Enables or disables the use capability based on our spawnflags. //----------------------------------------------------------------------------- int CBaseButton::ObjectCaps(void) { return((BaseClass::ObjectCaps() & ~FCAP_ACROSS_TRANSITION) | (HasSpawnFlags(SF_BUTTON_USE_ACTIVATES) ? (FCAP_IMPULSE_USE | FCAP_USE_IN_RADIUS) : 0)); }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CNPC_CombineAce::Spawn( void ) { Precache(); SetModel( "models/combine_ace_soldier.mdl" ); //Give him a random amount of grenades on spawn if (combine_ace_spawnwithgrenades.GetBool()) { if (g_pGameRules->IsSkillLevel(SKILL_HARD)) { m_iNumGrenades = random->RandomInt(2, 3); } else if (g_pGameRules->IsSkillLevel(SKILL_VERYHARD)) { m_iNumGrenades = random->RandomInt(4, 6); } else if (g_pGameRules->IsSkillLevel(SKILL_NIGHTMARE)) { m_iNumGrenades = random->RandomInt(8, 12); } else { m_iNumGrenades = random->RandomInt(0, 2); } } m_fIsElite = true; m_fIsAce = true; // Stronger, tougher. SetHealth(sk_combine_ace_health.GetFloat()); SetMaxHealth(sk_combine_ace_health.GetFloat()); SetKickDamage(sk_combine_ace_kick.GetFloat()); CapabilitiesAdd( bits_CAP_ANIMATEDFACE ); CapabilitiesAdd( bits_CAP_MOVE_SHOOT ); CapabilitiesAdd( bits_CAP_MOVE_JUMP ); CapabilitiesAdd( bits_CAP_DOORS_GROUP ); int attachment = LookupAttachment("eyes"); // Start up the eye glow m_pEyeSprite = CSprite::SpriteCreate("sprites/redglow1.vmt", GetLocalOrigin(), false); if (m_pEyeSprite != NULL) { m_pEyeSprite->SetAttachment(this, attachment); m_pEyeSprite->SetTransparency(kRenderTransAdd, 255, 255, 255, 200, kRenderFxNone); m_pEyeSprite->SetScale(0.25f); } // Start up the eye trail m_pEyeTrail = CSpriteTrail::SpriteTrailCreate("sprites/bluelaser1.vmt", GetLocalOrigin(), false); if (m_pEyeTrail != NULL) { m_pEyeTrail->SetAttachment(this, attachment); m_pEyeTrail->SetTransparency(kRenderTransAdd, 255, 0, 0, 200, kRenderFxNone); m_pEyeTrail->SetStartWidth(8.0f); m_pEyeTrail->SetLifeTime(0.75f); } SetEyeState(ACE_EYE_DORMANT); if (combine_ace_shieldspawnmode.GetInt() == 1) { SpawnArmorPieces(); } else if (combine_ace_shieldspawnmode.GetInt() > 1) { int iShieldRandom = random->RandomInt(0, 3); if (iShieldRandom == 0) { SpawnArmorPieces(); } else { pArmor = NULL; m_bNoArmor = true; } } else { pArmor = NULL; m_bNoArmor = true; } BaseClass::Spawn(); #if HL2_EPISODIC if (m_iUseMarch && !HasSpawnFlags(SF_NPC_START_EFFICIENT)) { Msg( "Soldier %s is set to use march anim, but is not an efficient AI. The blended march anim can only be used for dead-ahead walks!\n", GetDebugName() ); } #endif }
//----------------------------------------------------------------------------- // Purpose: Called when spawning, after keyvalues have been handled. //----------------------------------------------------------------------------- void CMomentaryRotButton::Spawn( void ) { CBaseToggle::AxisDir(); m_bUpdateTarget = true; if ( m_flSpeed == 0 ) { m_flSpeed = 100; } // Clamp start position and issue bounds warning if (m_flStartPosition < 0.0 || m_flStartPosition > 1.0) { Warning("WARNING: Momentary door (%s) start position not between 0 and 1. Clamping.\n",GetDebugName()); m_flStartPosition = clamp(m_IdealYaw, 0, 1); } // Check direction fields (for backward compatibility) if (m_direction != 1 && m_direction != -1) { m_direction = 1; } if (m_flMoveDistance < 0) { m_vecMoveAng = m_vecMoveAng * -1; m_flMoveDistance = -m_flMoveDistance; } m_start = GetLocalAngles() - m_vecMoveAng * m_flMoveDistance * m_flStartPosition; m_end = GetLocalAngles() + m_vecMoveAng * m_flMoveDistance * (1-m_flStartPosition); m_IdealYaw = m_flStartPosition; // Force start direction at end points if (m_flStartPosition == 0.0) { m_direction = -1; } else if (m_flStartPosition == 1.0) { m_direction = 1; } if (HasSpawnFlags(SF_BUTTON_LOCKED)) { m_bLocked = true; } if ( HasSpawnFlags( SF_BUTTON_USE_ACTIVATES ) ) { if ( m_sounds ) { m_sNoise = MakeButtonSound( m_sounds ); PrecacheScriptSound(m_sNoise.ToCStr()); } else { m_sNoise = NULL_STRING; } m_lastUsed = 0; UpdateTarget(0,this); } #ifdef HL1_DLL SetSolid( SOLID_BSP ); #else SetSolid( SOLID_VPHYSICS ); #endif if (HasSpawnFlags(SF_ROTBUTTON_NOTSOLID)) { AddEFlags( EFL_USE_PARTITION_WHEN_NOT_SOLID ); AddSolidFlags( FSOLID_NOT_SOLID ); } SetMoveType( MOVETYPE_PUSH ); SetModel( STRING( GetModelName() ) ); CreateVPhysics(); // Slam the object back to solid - if we really want it to be solid. if ( m_bSolidBsp ) { SetSolid( SOLID_BSP ); } m_bDisabled = false; }
//----------------------------------------------------------------------------- // Purpose: // Input : &info - // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- void CNPC_CombineS::Event_Killed( const CTakeDamageInfo &info ) { if (!(g_Language.GetInt() == LANGUAGE_GERMAN || UTIL_IsLowViolence()) && info.GetDamageType() & (DMG_BLAST | DMG_CRUSH) && !(info.GetDamageType() & (DMG_DISSOLVE)) && !PlayerHasMegaPhysCannon()) { Vector vecDamageDir = info.GetDamageForce(); SpawnBlood(GetAbsOrigin(), g_vecAttackDir, BloodColor(), info.GetDamage()); DispatchParticleEffect("headshotspray", GetAbsOrigin(), GetAbsAngles(), this); EmitSound("Gore.Headshot"); float flFadeTime = 25.0; CGib::SpawnSpecificGibs(this, 1, 750, 1500, "models/gibs/soldier_head.mdl", flFadeTime); Vector vecRagForce; vecRagForce.x = random->RandomFloat(-400, 400); vecRagForce.y = random->RandomFloat(-400, 400); vecRagForce.z = random->RandomFloat(0, 250); Vector vecRagDmgForce = (vecRagForce + vecDamageDir); CBaseEntity *pLeftArmGib = CreateRagGib("models/gibs/soldier_left_arm.mdl", GetAbsOrigin(), GetAbsAngles(), vecRagDmgForce, flFadeTime, IsOnFire()); if (pLeftArmGib) { color32 color = pLeftArmGib->GetRenderColor(); pLeftArmGib->SetRenderColor(color.r, color.g, color.b, color.a); } CBaseEntity *pRightArmGib = CreateRagGib("models/gibs/soldier_right_arm.mdl", GetAbsOrigin(), GetAbsAngles(), vecRagDmgForce, flFadeTime, IsOnFire()); if (pRightArmGib) { color32 color = pRightArmGib->GetRenderColor(); pRightArmGib->SetRenderColor(color.r, color.g, color.b, color.a); } CBaseEntity *pTorsoGib = CreateRagGib("models/gibs/soldier_torso.mdl", GetAbsOrigin(), GetAbsAngles(), vecRagDmgForce, flFadeTime, IsOnFire()); if (pTorsoGib) { color32 color = pTorsoGib->GetRenderColor(); pTorsoGib->SetRenderColor(color.r, color.g, color.b, color.a); } CBaseEntity *pPelvisGib = CreateRagGib("models/gibs/soldier_pelvis.mdl", GetAbsOrigin(), GetAbsAngles(), vecRagDmgForce, flFadeTime, IsOnFire()); if (pPelvisGib) { color32 color = pPelvisGib->GetRenderColor(); pPelvisGib->SetRenderColor(color.r, color.g, color.b, color.a); } CBaseEntity *pLeftLegGib = CreateRagGib("models/gibs/soldier_left_leg.mdl", GetAbsOrigin(), GetAbsAngles(), vecRagDmgForce, flFadeTime, IsOnFire()); if (pLeftLegGib) { color32 color = pLeftLegGib->GetRenderColor(); pLeftLegGib->SetRenderColor(color.r, color.g, color.b, color.a); } CBaseEntity *pRightLegGib = CreateRagGib("models/gibs/soldier_right_leg.mdl", GetAbsOrigin(), GetAbsAngles(), vecRagDmgForce, flFadeTime, IsOnFire()); if (pRightLegGib) { color32 color = pRightLegGib->GetRenderColor(); pRightLegGib->SetRenderColor(color.r, color.g, color.b, color.a); } //now add smaller gibs. CGib::SpawnSpecificGibs(this, 3, 750, 1500, "models/gibs/pgib_p3.mdl", flFadeTime); CGib::SpawnSpecificGibs(this, 3, 750, 1500, "models/gibs/pgib_p4.mdl", flFadeTime); Vector forceVector = CalcDamageForceVector(info); // Drop any weapon that I own if (VPhysicsGetObject()) { Vector weaponForce = forceVector * VPhysicsGetObject()->GetInvMass(); Weapon_Drop(m_hActiveWeapon, NULL, &weaponForce); } else { Weapon_Drop(m_hActiveWeapon); } if (info.GetAttacker()->IsPlayer()) { ((CSingleplayRules*)GameRules())->NPCKilled(this, info); } UTIL_Remove(this); SetThink(NULL); return; } // Don't bother if we've been told not to, or the player has a megaphyscannon if ( combine_spawn_health.GetBool() == false || PlayerHasMegaPhysCannon() ) { BaseClass::Event_Killed( info ); return; } CBasePlayer *pPlayer = ToBasePlayer( info.GetAttacker() ); if ( !pPlayer ) { CPropVehicleDriveable *pVehicle = dynamic_cast<CPropVehicleDriveable *>( info.GetAttacker() ) ; if ( pVehicle && pVehicle->GetDriver() && pVehicle->GetDriver()->IsPlayer() ) { pPlayer = assert_cast<CBasePlayer *>( pVehicle->GetDriver() ); } } if ( pPlayer != NULL ) { CHalfLife2 *pHL2GameRules = static_cast<CHalfLife2 *>(g_pGameRules); // Attempt to drop health if ( pHL2GameRules->NPC_ShouldDropHealth( pPlayer ) ) { DropItem( "item_healthvial", WorldSpaceCenter()+RandomVector(-4,4), RandomAngle(0,360) ); pHL2GameRules->NPC_DroppedHealth(); } if ( HasSpawnFlags( SF_COMBINE_NO_GRENADEDROP ) == false ) { // Attempt to drop a grenade if ( pHL2GameRules->NPC_ShouldDropGrenade( pPlayer ) ) { DropItem( "weapon_frag", WorldSpaceCenter()+RandomVector(-4,4), RandomAngle(0,360) ); pHL2GameRules->NPC_DroppedGrenade(); } } } BaseClass::Event_Killed( info ); }
//----------------------------------------------------------------------------- // Purpose: Catches the monster-specific events that occur when tagged animation // frames are played. // Input : pEvent - //----------------------------------------------------------------------------- void CNPC_PoisonZombie::HandleAnimEvent( animevent_t *pEvent ) { if ( pEvent->event == AE_ZOMBIE_POISON_PICKUP_CRAB ) { EnableCrab( m_nThrowCrab, false ); SetBodygroup( ZOMBIE_BODYGROUP_THROW, 1 ); return; } if ( pEvent->event == AE_ZOMBIE_POISON_THROW_WARN_SOUND ) { BreatheOffShort(); EmitSound( "NPC_PoisonZombie.ThrowWarn" ); return; } if ( pEvent->event == AE_ZOMBIE_POISON_THROW_SOUND ) { BreatheOffShort(); EmitSound( "NPC_PoisonZombie.Throw" ); return; } if ( pEvent->event == AE_ZOMBIE_POISON_THROW_CRAB ) { SetBodygroup( ZOMBIE_BODYGROUP_THROW, 0 ); CBlackHeadcrab *pCrab = (CBlackHeadcrab *)CreateNoSpawn( GetHeadcrabClassname(), EyePosition(), vec3_angle, this ); pCrab->AddSpawnFlags( SF_NPC_FALL_TO_GROUND ); // Fade if our parent is supposed to if ( HasSpawnFlags( SF_NPC_FADE_CORPSE ) ) { pCrab->AddSpawnFlags( SF_NPC_FADE_CORPSE ); } // make me the crab's owner to avoid collision issues pCrab->SetOwnerEntity( this ); pCrab->Spawn(); pCrab->SetLocalAngles( GetLocalAngles() ); pCrab->SetActivity( ACT_RANGE_ATTACK1 ); pCrab->SetNextThink( gpGlobals->curtime ); pCrab->PhysicsSimulate(); pCrab->GetMotor()->SetIdealYaw( GetAbsAngles().y ); if ( IsOnFire() ) { pCrab->Ignite( 100.0 ); } CBaseEntity *pEnemy = GetEnemy(); if ( pEnemy ) { Vector vecEnemyEyePos = pEnemy->EyePosition(); pCrab->ThrowAt( vecEnemyEyePos ); } if (m_nCrabCount == 0) { CapabilitiesRemove( bits_CAP_INNATE_RANGE_ATTACK1 | bits_CAP_INNATE_RANGE_ATTACK2 ); } m_flNextCrabThrowTime = gpGlobals->curtime + random->RandomInt( ZOMBIE_THROW_MIN_DELAY, ZOMBIE_THROW_MAX_DELAY ); return; } if ( pEvent->event == AE_ZOMBIE_POISON_SPIT ) { Vector forward; QAngle qaPunch( 45, random->RandomInt(-5, 5), random->RandomInt(-5, 5) ); AngleVectors( GetLocalAngles(), &forward ); forward = forward * 200; ClawAttack( GetClawAttackRange(), sk_zombie_poison_dmg_spit.GetFloat(), qaPunch, forward, ZOMBIE_BLOOD_BITE ); return; } BaseClass::HandleAnimEvent( pEvent ); }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CEnvBeam::Spawn( void ) { if ( !m_iszSpriteName ) { SetThink( &CEnvBeam::SUB_Remove ); return; } BaseClass::Spawn(); m_noiseAmplitude = MIN(MAX_BEAM_NOISEAMPLITUDE, m_noiseAmplitude); // Check for tapering if ( HasSpawnFlags( SF_BEAM_TAPEROUT ) ) { SetWidth( m_boltWidth ); SetEndWidth( 0 ); } else { SetWidth( m_boltWidth ); SetEndWidth( GetWidth() ); // Note: EndWidth is not scaled } // if a non-targetentity endpoint was specified, transform it into local relative space // so it can move along with the base if (!m_vEndPointWorld.IsZero()) { WorldToEntitySpace( m_vEndPointWorld, &m_vEndPointRelative ); } else { m_vEndPointRelative.Zero(); } if ( ServerSide() ) { SetThink( &CEnvBeam::UpdateThink ); SetNextThink( gpGlobals->curtime ); SetFireTime( gpGlobals->curtime ); if ( GetEntityName() != NULL_STRING ) { if ( !(m_spawnflags & SF_BEAM_STARTON) ) { AddEffects( EF_NODRAW ); m_active = 0; SetNextThink( TICK_NEVER_THINK ); } else { m_active = 1; } } } else { m_active = 0; if ( !GetEntityName() || FBitSet(m_spawnflags, SF_BEAM_STARTON) ) { SetThink( &CEnvBeam::StrikeThink ); SetNextThink( gpGlobals->curtime + 1.0f ); } } }
//========================================================= // Selecciona un objeto al azar. //========================================================= const char *CLoot::SelectRandomItem() { int pRandom = random->RandomInt(1, 15); const char *pResult = ""; if ( pRandom == 1 && HasSpawnFlags(SF_SPAWN_PISTOL) ) pResult = "item_ammo_pistol"; if ( pRandom == 2 && HasSpawnFlags(SF_SPAWN_AR2) ) pResult = "item_ammo_ar2"; if ( pRandom == 3 && HasSpawnFlags(SF_SPAWN_SMG1) ) pResult = "item_ammo_smg1"; if ( pRandom == 4 && HasSpawnFlags(SF_SPAWN_SHOTGUN) ) pResult = "item_box_buckshot"; if ( pRandom == 5 && HasSpawnFlags(SF_SPAWN_357) ) pResult = "item_ammo_357"; //if ( pRandom == 6 && HasSpawnFlags(SF_SPAWN_ALYXGUN) ) //pResult = "weapon_alyxgun"; if ( pRandom == 7 && HasSpawnFlags(SF_SPAWN_CROSSBOW) ) pResult = "item_ammo_crossbow"; if ( pRandom == 8 && HasSpawnFlags(SF_SPAWN_FRAG) ) pResult = "weapon_frag"; if ( pRandom == 9 && HasSpawnFlags(SF_SPAWN_HEALTHKIT) ) { if ( random->RandomInt(1, 5) == 2 ) pResult = "item_healthvial"; else pResult = "item_healthkit"; } if ( pRandom == 10 && HasSpawnFlags(SF_SPAWN_BATTERY) ) pResult = "item_battery"; if ( pRandom == 11 && HasSpawnFlags(SF_SPAWN_BLOOD) ) pResult = "item_bloodkit"; if ( pRandom == 12 && HasSpawnFlags(SF_SPAWN_BANDAGE) ) pResult = "item_bandage"; if ( pRandom == 13 && HasSpawnFlags(SF_SPAWN_SODA) ) pResult = "item_soda"; if ( pRandom == 14 && HasSpawnFlags(SF_SPAWN_FOOD) ) pResult = "item_food"; // Hacemos otra pasada a la suerte. if ( pResult == "" ) return SelectRandomItem(); // Es munición. if ( Q_stristr(pResult, "ammo") && pResult != "item_ammo_crossbow" ) { // ¡Suerte! Toca una caja grande de munición. if ( random->RandomInt(1, 5) > 3 ) pResult = CFmtStr("%s_large", pResult); } return pResult; }
//--------------------------------------------------------- //--------------------------------------------------------- void CAI_Relationship::ChangeRelationships( int disposition, int iReverting, CBaseEntity *pActivator, CBaseEntity *pCaller ) { if( iReverting != NOT_REVERTING && m_iPreviousDisposition == -1 ) { // Trying to revert without having ever set the relationships! DevMsg( 2, "ai_relationship cannot revert changes before they are applied!\n"); return; } const int MAX_HANDLED = 512; CUtlVectorFixed<CBaseCombatCharacter *, MAX_HANDLED> subjectList; CUtlVectorFixed<CBaseCombatCharacter *, MAX_HANDLED> targetList; // Add any special subjects we found CBaseEntity *pSpecialSubject = FindEntityForProceduralName( m_iszSubject, pActivator, pCaller ); if ( pSpecialSubject && pSpecialSubject->MyCombatCharacterPointer() ) { subjectList.AddToTail( pSpecialSubject->MyCombatCharacterPointer() ); } // Add any special targets we found CBaseEntity *pSpecialTarget = FindEntityForProceduralName( m_target, pActivator, pCaller ); if ( pSpecialTarget && pSpecialTarget->MyCombatCharacterPointer() ) { targetList.AddToTail( pSpecialTarget->MyCombatCharacterPointer() ); } // ------------------------------- // Search for targets and subjects // ------------------------------- float radiusSq = Square( m_flRadius ); // Search players first for ( int i = 1; i <= gpGlobals->maxClients; i++ ) { if ( subjectList.Count() == MAX_HANDLED || targetList.Count() == MAX_HANDLED ) { DevMsg( "Too many entities handled by ai_relationship %s\n", GetDebugName() ); break; } CBasePlayer *pPlayer = UTIL_PlayerByIndex( i ); if ( pPlayer ) { if( IsASubject( pPlayer ) ) { if ( m_flRadius == 0.0 || GetAbsOrigin().DistToSqr( pPlayer->GetAbsOrigin() ) <= radiusSq ) subjectList.AddToTail( pPlayer ); } else if( IsATarget( pPlayer ) ) { targetList.AddToTail( pPlayer ); } } } // Search NPCs for ( int i = 0; i < g_AI_Manager.NumAIs(); i++ ) { if ( subjectList.Count() == MAX_HANDLED || targetList.Count() == MAX_HANDLED ) { DevMsg( "Too many entities handled by ai_relationship %s\n", GetDebugName() ); break; } CAI_BaseNPC *pNPC = (g_AI_Manager.AccessAIs())[i]; if ( pNPC ) { if( IsASubject( pNPC ) ) { if ( m_flRadius == 0.0 || GetAbsOrigin().DistToSqr( pNPC->GetAbsOrigin() ) <= radiusSq ) subjectList.AddToTail( pNPC ); } else if( IsATarget( pNPC ) ) { targetList.AddToTail( pNPC ); } } } // If either list is still empty, we have a problem. if( subjectList.Count() == 0 ) { DevMsg( 2, "ai_relationship '%s' finds no subject(s) called: %s\n", GetDebugName(), STRING( m_iszSubject ) ); return; } else if ( targetList.Count() == 0 ) { DevMsg( 2, "ai_relationship '%s' finds no target(s) called: %s\n", GetDebugName(), STRING( m_target ) ); return; } // Ok, lists are populated. Apply all relationships. for ( int i = 0 ; i < subjectList.Count(); i++ ) { CBaseCombatCharacter *pSubject = subjectList[ i ]; for ( int j = 0 ; j < targetList.Count(); j++ ) { CBaseCombatCharacter *pTarget = targetList[ j ]; if ( m_iPreviousDisposition == -1 && iReverting == NOT_REVERTING ) { // Set previous disposition. m_iPreviousDisposition = pSubject->IRelationType( pTarget ); m_iPreviousRank = pSubject->IRelationPriority( pTarget ); } if ( iReverting == REVERTING_TO_PREV ) { pSubject->AddEntityRelationship( pTarget, (Disposition_t)m_iPreviousDisposition, m_iPreviousRank ); if( m_bReciprocal ) { pTarget->AddEntityRelationship( pSubject, (Disposition_t)m_iPreviousDisposition, m_iPreviousRank ); } } else if ( iReverting == REVERTING_TO_DEFAULT ) { pSubject->RemoveEntityRelationship( pTarget ); if( m_bReciprocal ) { pTarget->RemoveEntityRelationship( pSubject ); } } else if( pSubject->IRelationType(pTarget) != disposition || pSubject->IRelationPriority(pTarget) != m_iRank || HasSpawnFlags( SF_RELATIONSHIP_NOTIFY_SUBJECT ) || HasSpawnFlags( SF_RELATIONSHIP_NOTIFY_TARGET ) ) { // Apply the relationship to the subject pSubject->AddEntityRelationship( pTarget, (Disposition_t)disposition, m_iRank ); // Make the subject aware of the target if ( HasSpawnFlags( SF_RELATIONSHIP_NOTIFY_SUBJECT ) ) { DiscloseNPCLocation( pSubject, pTarget ); } // Make the target aware of the subject if ( HasSpawnFlags( SF_RELATIONSHIP_NOTIFY_TARGET ) ) { DiscloseNPCLocation( pTarget, pSubject ); } // This relationship is applied to target and subject alike if ( m_bReciprocal ) { // Apply the relationship to the target pTarget->AddEntityRelationship( pSubject, (Disposition_t)disposition, m_iRank ); } } } } }
void CWeaponHL2MPBase::FallInit( void ) { #ifndef CLIENT_DLL SetModel( GetWorldModel() ); VPhysicsDestroyObject(); if ( HasSpawnFlags( SF_NORESPAWN ) == false ) { SetMoveType( MOVETYPE_NONE ); SetSolid( SOLID_BBOX ); AddSolidFlags( FSOLID_TRIGGER ); UTIL_DropToFloor( this, MASK_SOLID ); } else { if ( !VPhysicsInitNormal( SOLID_BBOX, GetSolidFlags() | FSOLID_TRIGGER, false ) ) { SetMoveType( MOVETYPE_NONE ); SetSolid( SOLID_BBOX ); AddSolidFlags( FSOLID_TRIGGER ); } else { #if !defined( CLIENT_DLL ) // Constrained start? if ( HasSpawnFlags( SF_WEAPON_START_CONSTRAINED ) ) { //Constrain the weapon in place IPhysicsObject *pReferenceObject, *pAttachedObject; pReferenceObject = g_PhysWorldObject; pAttachedObject = VPhysicsGetObject(); if ( pReferenceObject && pAttachedObject ) { constraint_fixedparams_t fixed; fixed.Defaults(); fixed.InitWithCurrentObjectState( pReferenceObject, pAttachedObject ); fixed.constraint.forceLimit = lbs2kg( 10000 ); fixed.constraint.torqueLimit = lbs2kg( 10000 ); IPhysicsConstraint *pConstraint = GetConstraint(); pConstraint = physenv->CreateFixedConstraint( pReferenceObject, pAttachedObject, NULL, fixed ); pConstraint->SetGameData( (void *) this ); } } #endif //CLIENT_DLL } } SetPickupTouch(); SetThink( &CBaseCombatWeapon::FallThink ); SetNextThink( gpGlobals->curtime + 0.1f ); #endif }
//----------------------------------------------------------------------------- // Purpose: Checks to see if it's time to change controllers //----------------------------------------------------------------------------- void CControlZone::ReevaluateControllingTeam( void ) { // Count the number of players in each team int i; memset( m_iPlayersInZone, 0, sizeof( m_iPlayersInZone ) ); for ( i = 0; i < m_ZonePlayerList.Size(); i++ ) { if ( m_ZonePlayerList[i] != NULL && (m_ZonePlayerList[i]->GetTeamNumber() > 0) ) { m_iPlayersInZone[ m_ZonePlayerList[i]->GetTeamNumber() ] += 1; } } // Abort immediately if we're not using touches to changes teams if ( HasSpawnFlags( CZF_DONT_USE_TOUCHES ) ) return; // if we're locked in place, no changes can occur to controlling team except through an explicit map ResetTeam if ( m_iLocked ) return; bool foundAnyTeam = false; int teamFound = 0; // check to see if any teams have no players for ( i = 0; i < GetNumberOfTeams(); i++ ) { if ( m_iPlayersInZone[i] ) { if ( foundAnyTeam ) { // we've already found a team, so it's being contested; teamFound = ZONE_CONTESTED; break; } foundAnyTeam = true; teamFound = i; } } // no one in the area! if ( teamFound == 0 ) { // just leave it as it is, let it continue to change team // exception: if the zone state is contested, and there aren't any players in the zone, // just return to the team who used to own the zone. if ( GetTeamNumber() == ZONE_CONTESTED ) { ChangeTeam(m_iDefendingTeam); SetControllingTeam( this, m_iDefendingTeam ); } return; } // if it's the same controlling team, don't worry about it if ( teamFound == GetTeamNumber() ) { // the right team is in control, don't even think of switching m_iTryingToChangeToTeam = 0; SetNextThink( TICK_NEVER_THINK ); return; } // Find out if the zone isn't owned by anyone at all (hasn't been touched since the map started, and it started un-owned) bool bHasBeenOwned = true; if ( m_iDefendingTeam == 0 && GetTeamNumber() == 0 ) bHasBeenOwned = false; // if it's not contested, always go to contested mode if ( GetTeamNumber() != ZONE_CONTESTED && teamFound != GetTeamNumber() ) { // Unowned zones are captured immediately (no contesting stage) if ( bHasBeenOwned ) teamFound = ZONE_CONTESTED; } // if it's the team we're trying to change to, don't worry about it if ( teamFound == m_iTryingToChangeToTeam ) return; // set up the time to change to the new team soon m_iTryingToChangeToTeam = teamFound; // changing from contested->uncontested and visa-versa have different delays if ( m_iTryingToChangeToTeam != ZONE_CONTESTED ) { if ( !bHasBeenOwned ) { DevMsg( 1, "trigger_controlzone: (%s) changing team to %d NOW\n", GetDebugName(), m_iTryingToChangeToTeam ); SetNextThink( gpGlobals->curtime + 0.1f ); } else { DevMsg( 1, "trigger_controlzone: (%s) changing team to %d in %.2f seconds\n", GetDebugName(), m_iTryingToChangeToTeam, m_flTimeTillCaptured ); SetNextThink( gpGlobals->curtime + m_flTimeTillCaptured ); } } else { DevMsg( 1, "trigger_controlzone: (%s) changing to contested in %f seconds\n", GetDebugName(), m_flTimeTillContested ); SetNextThink( gpGlobals->curtime + m_flTimeTillContested ); } }