//----------------------------------------------------------------------------- // Default to a simple single trace, but allow overriding. // This is used for the strider, so it can determine the height based on the legs. //----------------------------------------------------------------------------- void UnitBaseAirLocomotion::UpdateCurrentHeight() { trace_t pm; UTIL_TraceHull( mv->origin, mv->origin-Vector(0, 0, MAX_TRACE_LENGTH), WorldAlignMins(), WorldAlignMaxs(), MASK_NPCWORLDSTATIC, m_pOuter, GetOuter()->CalculateIgnoreOwnerCollisionGroup(), &pm ); m_fCurrentHeight = fabs( pm.endpos.z-mv->origin.z ); }
int CFlyingMonster :: CheckLocalMove ( const Vector &vecStart, const Vector &vecEnd, CBaseEntity *pTarget, float *pflDist ) { // UNDONE: need to check more than the endpoint if (FBitSet(pev->flags, FL_SWIM) && (UTIL_PointContents(vecEnd) != CONTENTS_WATER)) { // ALERT(at_aiconsole, "can't swim out of water\n"); return FALSE; } TraceResult tr; UTIL_TraceHull( vecStart + Vector( 0, 0, 32 ), vecEnd + Vector( 0, 0, 32 ), dont_ignore_monsters, large_hull, edict(), &tr ); // ALERT( at_console, "%.0f %.0f %.0f : ", vecStart.x, vecStart.y, vecStart.z ); // ALERT( at_console, "%.0f %.0f %.0f\n", vecEnd.x, vecEnd.y, vecEnd.z ); if (pflDist) { *pflDist = ( (tr.vecEndPos - Vector( 0, 0, 32 )) - vecStart ).Length();// get the distance. } // ALERT( at_console, "check %d %d %f\n", tr.fStartSolid, tr.fAllSolid, tr.flFraction ); if (tr.fStartSolid || tr.flFraction < 1.0) { if ( pTarget && pTarget->edict() == gpGlobals->trace_ent ) return LOCALMOVE_VALID; return LOCALMOVE_INVALID; } return LOCALMOVE_VALID; }
//========================================================= // CheckMeleeAttack1 - jump like crazy if the enemy gets too close. //========================================================= int CNPC_HAssassin::MeleeAttack1Conditions ( float flDot, float flDist ) { if ( m_flNextJump < gpGlobals->curtime && ( flDist <= 128 || HasMemory( MEMORY_BADJUMP )) && GetEnemy() != NULL ) { trace_t tr; Vector vecMin = Vector( random->RandomFloat( 0, -64), random->RandomFloat( 0, -64 ), 0 ); Vector vecMax = Vector( random->RandomFloat( 0, 64), random->RandomFloat( 0, 64 ), 160 ); Vector vecDest = GetAbsOrigin() + Vector( random->RandomFloat( -64, 64), random->RandomFloat( -64, 64 ), 160 ); UTIL_TraceHull( GetAbsOrigin() + Vector( 0, 0, 36 ), GetAbsOrigin() + Vector( 0, 0, 36 ), vecMin, vecMax, MASK_SOLID, this, COLLISION_GROUP_NONE, &tr ); //NDebugOverlay::Box( GetAbsOrigin() + Vector( 0, 0, 36 ), vecMin, vecMax, 0,0, 255, 0, 2.0 ); if ( tr.startsolid || tr.fraction < 1.0) { return COND_TOO_CLOSE_TO_ATTACK; } float flGravity = sv_gravity.GetFloat(); float time = sqrt( 160 / (0.5 * flGravity)); float speed = flGravity * time / 160; m_vecJumpVelocity = ( vecDest - GetAbsOrigin() ) * speed; return COND_CAN_MELEE_ATTACK1; } if ( flDist > 128 ) return COND_TOO_FAR_TO_ATTACK; return COND_NONE; }
//========================================================= // CheckMeleeAttack1 - jump like crazy if the enemy gets too close. //========================================================= BOOL CHAssassin :: CheckMeleeAttack1 ( float flDot, float flDist ) { if ( m_flNextJump < gpGlobals->time && (flDist <= 128 || HasMemory( bits_MEMORY_BADJUMP )) && m_hEnemy != NULL ) { TraceResult tr; Vector vecDest = pev->origin + Vector( RANDOM_FLOAT( -64, 64), RANDOM_FLOAT( -64, 64 ), 160 ); UTIL_TraceHull( pev->origin + Vector( 0, 0, 36 ), vecDest + Vector( 0, 0, 36 ), dont_ignore_monsters, human_hull, ENT(pev), &tr); if ( tr.fStartSolid || tr.flFraction < 1.0) { return FALSE; } float flGravity = g_psv_gravity->value; float time = sqrt( 160 / (0.5 * flGravity)); float speed = flGravity * time / 160; m_vecJumpVelocity = (vecDest - pev->origin) * speed; return TRUE; } return FALSE; }
// Overridden for Gargantua because his swing starts lower as // a percentage of his height (otherwise he swings over the // players head) //========================================================= CBaseEntity* CGargantua::GargantuaCheckTraceHullAttack(float flDist, int iDamage, int iDmgType) { TraceResult tr; UTIL_MakeVectors( GetAbsAngles() ); Vector vecStart = GetAbsOrigin(); vecStart.z += 64; Vector vecEnd = vecStart + (gpGlobals->v_forward * flDist) - (gpGlobals->v_up * flDist * 0.3); UTIL_TraceHull( vecStart, vecEnd, dont_ignore_monsters, Hull::HEAD, ENT(pev), &tr ); if ( tr.pHit ) { CBaseEntity *pEntity = CBaseEntity::Instance( tr.pHit ); if ( iDamage > 0 ) { pEntity->TakeDamage( this, this, iDamage, iDmgType ); } return pEntity; } return NULL; }
bool NPC::WalkMove(void) { if (!IsOnFloor(GetEntity())) return false; // P.45 - Walk Move improve if (pev->speed == 0.0f) return false; int stepSize = 18; MakeVectors(pev->angles); Vector dest = pev->origin; dest.z += stepSize; Vector src = pev->origin + gpGlobals->v_forward * 3; TraceResult tr; UTIL_TraceHull(dest, src, ignore_monsters, head_hull, GetEntity(), &tr); if (tr.flFraction != 1.0f) //tr.flFraction > 0.0f && { float newOriginZ = pev->origin.z + (tr.vecEndPos.z - GetBottomOrigin (GetEntity ()).z) - stepSize; if (newOriginZ > pev->origin.z && (newOriginZ - pev->origin.z) <= stepSize) { pev->origin.z = newOriginZ + 0.5f; return true; } } return false; }
//========================================================= // CheckTraceHullAttack - expects a length to trace, amount // of damage to do, and damage type. Returns a pointer to // the damaged entity in case the monster wishes to do // other stuff to the victim (punchangle, etc) // // Used for many contact-range melee attacks. Bites, claws, etc. //========================================================= CBaseEntity* CBaseMonster :: CheckTraceHullAttack( float flDist, int iDamage, int iDmgType ) { TraceResult tr; if (IsPlayer()) UTIL_MakeVectors( pev->angles ); else UTIL_MakeAimVectors( pev->angles ); Vector vecStart = pev->origin; vecStart.z += pev->size.z * 0.5; Vector vecEnd = vecStart + (gpGlobals->v_forward * flDist ); UTIL_TraceHull( vecStart, vecEnd, dont_ignore_monsters, head_hull, ENT(pev), &tr ); if ( tr.pHit ) { CBaseEntity *pEntity = CBaseEntity::Instance( tr.pHit ); if ( iDamage > 0 ) { pEntity->TakeDamage( pev, pev, iDamage, iDmgType ); } return pEntity; } return NULL; }
// here bot updates important info that is used multiple times along the thinking process void CSDKBot::InfoGathering() { if (!GetEnemy()) { m_flBotToEnemyDist = 9999; m_flHeightDifToEnemy = 0; m_bEnemyOnSights = false; m_flDistTraveled += fabs(GetLocalVelocity().Length()); // this is used for stuck checking, return; } m_flBotToEnemyDist = (GetLocalOrigin() - GetEnemy()->GetLocalOrigin()).Length(); trace_t tr; UTIL_TraceHull( EyePosition(), GetEnemy()->EyePosition() - Vector(0,0,20), -BotTestHull, BotTestHull, MASK_SHOT, this, COLLISION_GROUP_NONE, &tr ); if( tr.m_pEnt == GetEnemy() ) // vision line between both m_bEnemyOnSights = true; else m_bEnemyOnSights = false; m_bInRangeToAttack = (m_flBotToEnemyDist < m_flMinRangeAttack) && FInViewCone( GetEnemy() ); m_flDistTraveled += fabs(GetLocalVelocity().Length()); // this is used for stuck checking, m_flHeightDifToEnemy = GetLocalOrigin().z - GetEnemy()->GetLocalOrigin().z; }
bool CMomentumGameMovement::CanUnduck() { trace_t trace; Vector newOrigin; VectorCopy(mv->GetAbsOrigin(), newOrigin); if (player->GetGroundEntity() != NULL) { newOrigin += VEC_DUCK_HULL_MIN - VEC_HULL_MIN; } else { // If in air an letting go of croush, make sure we can offset origin to make // up for uncrouching Vector hullSizeNormal = VEC_HULL_MAX - VEC_HULL_MIN; Vector hullSizeCrouch = VEC_DUCK_HULL_MAX - VEC_DUCK_HULL_MIN; newOrigin += -0.5f * (hullSizeNormal - hullSizeCrouch); } UTIL_TraceHull(mv->GetAbsOrigin(), newOrigin, VEC_HULL_MIN, VEC_HULL_MAX, PlayerSolidMask(), player, COLLISION_GROUP_PLAYER_MOVEMENT, &trace); if (trace.startsolid || (trace.fraction != 1.0f)) return false; return true; }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CFuncLadder::DrawDebugGeometryOverlays() { #if !defined( CLIENT_DLL ) BaseClass::DrawDebugGeometryOverlays(); Vector playerMins = VEC_HULL_MIN; Vector playerMaxs = VEC_HULL_MAX; Vector topPosition; Vector bottomPosition; GetTopPosition( topPosition ); GetBottomPosition( bottomPosition ); NDebugOverlay::Box( topPosition, playerMins, playerMaxs, 255,0,0,127, 0 ); NDebugOverlay::Box( bottomPosition, playerMins, playerMaxs, 0,0,255,127, 0 ); NDebugOverlay::EntityBounds(this, 200, 180, 63, 63, 0); trace_t bottomtrace; UTIL_TraceHull( m_vecPlayerMountPositionBottom, m_vecPlayerMountPositionBottom, playerMins, playerMaxs, MASK_PLAYERSOLID_BRUSHONLY, NULL, COLLISION_GROUP_PLAYER_MOVEMENT, &bottomtrace ); int c = m_Dismounts.Count(); for ( int i = 0 ; i < c ; i++ ) { CInfoLadderDismount *pt = m_Dismounts[ i ]; if ( !pt ) continue; NDebugOverlay::Box(pt->GetAbsOrigin(),Vector( -16, -16, 0 ), Vector( 16, 16, 8 ), 150,0,0, 63, 0); } #endif }
//----------------------------------------------------------------------------- // Purpose: // Input : *pChild - //----------------------------------------------------------------------------- void CBaseNPCMaker::ChildPostSpawn( CAI_BaseNPC *pChild ) { // If I'm stuck inside any props, remove them bool bFound = true; while ( bFound ) { trace_t tr; UTIL_TraceHull( pChild->GetAbsOrigin(), pChild->GetAbsOrigin(), pChild->WorldAlignMins(), pChild->WorldAlignMaxs(), MASK_NPCSOLID, pChild, COLLISION_GROUP_NONE, &tr ); //NDebugOverlay::Box( pChild->GetAbsOrigin(), pChild->WorldAlignMins(), pChild->WorldAlignMaxs(), 0, 255, 0, 32, 5.0 ); if ( tr.fraction != 1.0 && tr.m_pEnt ) { if ( FClassnameIs( tr.m_pEnt, "prop_physics" ) ) { // Set to non-solid so this loop doesn't keep finding it tr.m_pEnt->AddSolidFlags( FSOLID_NOT_SOLID ); UTIL_RemoveImmediate( tr.m_pEnt ); continue; } } bFound = false; } if ( m_hIgnoreEntity != NULL ) { pChild->SetOwnerEntity( m_hIgnoreEntity ); } }
void CSDKPlayer::FindSafePos(Vector &startPos) { bool hasSafePos = false; const float playerWidth = GetPlayerMaxs().x - GetPlayerMins().x; const int maxChecks = 5; for (int x = 0; x < maxChecks; x++) { for (int y = 0; y < maxChecks; y++) { for (int sign = -1; sign <= 1; sign += 2) { Vector checkPos = startPos + sign * Vector(x * playerWidth, y * playerWidth, 0); trace_t trace; UTIL_TraceHull(checkPos, checkPos - Vector(0, 0, 100), GetPlayerMins(), GetPlayerMaxs(), MASK_PLAYERSOLID, this, COLLISION_GROUP_PLAYER, &trace); if (!trace.startsolid && trace.fraction != 1.0f) { hasSafePos = true; startPos = trace.endpos; break; } } if (hasSafePos) break; } if (hasSafePos) break; } if (!hasSafePos) startPos.z += GetPlayerMaxs().z * 2; }
//----------------------------------------------------------------------------- // Purpose: // Input : flDot - // flDist - // Output : int CNPC_Assassin::RangeAttack1Conditions //----------------------------------------------------------------------------- int CNPC_Assassin::RangeAttack2Conditions ( float flDot, float flDist ) { if ( m_flNextLungeTime > gpGlobals->curtime ) return 0; float lungeRange = GetSequenceMoveDist( SelectWeightedSequence( (Activity) ACT_ASSASSIN_FLIP_FORWARD ) ); if ( flDist < lungeRange * 0.25f ) return COND_TOO_CLOSE_TO_ATTACK; if ( flDist > lungeRange * 1.5f ) return COND_TOO_FAR_TO_ATTACK; if ( flDot < 0.75f ) return COND_NOT_FACING_ATTACK; if ( GetEnemy() == NULL ) return 0; // Check for a clear path trace_t tr; UTIL_TraceHull( GetAbsOrigin(), GetEnemy()->GetAbsOrigin(), GetHullMins(), GetHullMaxs(), MASK_NPCSOLID, this, COLLISION_GROUP_NONE, &tr ); if ( tr.fraction == 1.0f || tr.m_pEnt == GetEnemy() ) return COND_CAN_RANGE_ATTACK2; return 0; }
void C_HL2MP_Player::CalcView( Vector &eyeOrigin, QAngle &eyeAngles, float &zNear, float &zFar, float &fov ) { // third or first person ragdolls if ( m_lifeState != LIFE_ALIVE && !IsObserver() ) { // First person ragdolls if ( cl_fp_ragdoll.GetBool() && m_hRagdoll.Get() ) { // pointer to the ragdoll C_HL2MPRagdoll *pRagdoll = (C_HL2MPRagdoll*)m_hRagdoll.Get(); // gets its origin and angles pRagdoll->GetAttachment( pRagdoll->LookupAttachment( "eyes" ), eyeOrigin, eyeAngles ); Vector vForward; AngleVectors( eyeAngles, &vForward ); if ( cl_fp_ragdoll_auto.GetBool() ) { // DM: Don't use first person view when we are very close to something trace_t tr; UTIL_TraceLine( eyeOrigin, eyeOrigin + ( vForward * 10000 ), MASK_ALL, pRagdoll, COLLISION_GROUP_NONE, &tr ); if ( (!(tr.fraction < 1) || (tr.endpos.DistTo(eyeOrigin) > 25)) ) return; } else return; } eyeOrigin = vec3_origin; eyeAngles = vec3_angle; Vector origin = EyePosition(); IRagdoll *pRagdoll = GetRepresentativeRagdoll(); if ( pRagdoll ) { origin = pRagdoll->GetRagdollOrigin(); origin.z += VEC_DEAD_VIEWHEIGHT.z; // look over ragdoll, not through } BaseClass::CalcView( eyeOrigin, eyeAngles, zNear, zFar, fov ); eyeOrigin = origin; Vector vForward; AngleVectors( eyeAngles, &vForward ); VectorNormalize( vForward ); VectorMA( origin, -CHASE_CAM_DISTANCE, vForward, eyeOrigin ); Vector WALL_MIN( -WALL_OFFSET, -WALL_OFFSET, -WALL_OFFSET ); Vector WALL_MAX( WALL_OFFSET, WALL_OFFSET, WALL_OFFSET ); trace_t trace; // clip against world // HACK don't recompute positions while doing RayTrace C_BaseEntity::EnableAbsRecomputations( false ); UTIL_TraceHull( origin, eyeOrigin, WALL_MIN, WALL_MAX, MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &trace ); C_BaseEntity::EnableAbsRecomputations( true ); if (trace.fraction < 1.0) { eyeOrigin = trace.endpos; } return; } BaseClass::CalcView( eyeOrigin, eyeAngles, zNear, zFar, fov ); }
//----------------------------------------------------------------------------- // Purpose: Determines if a player can be safely moved towards a point // Input: pos - position to test move to, fVertDist - how far to trace downwards to see if the player would fall, // radius - how close the player can be to the object, objPos - position of the object to avoid, // objDir - direction the object is travelling //----------------------------------------------------------------------------- bool C_BaseHLPlayer::TestMove( const Vector &pos, float fVertDist, float radius, const Vector &objPos, const Vector &objDir ) { trace_t trUp; trace_t trOver; trace_t trDown; float flHit1, flHit2; UTIL_TraceHull( GetAbsOrigin(), pos, GetPlayerMins(), GetPlayerMaxs(), MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &trOver ); if ( trOver.fraction < 1.0f ) { // check if the endpos intersects with the direction the object is travelling. if it doesn't, this is a good direction to move. if ( objDir.IsZero() || ( IntersectInfiniteRayWithSphere( objPos, objDir, trOver.endpos, radius, &flHit1, &flHit2 ) && ( ( flHit1 >= 0.0f ) || ( flHit2 >= 0.0f ) ) ) ) { // our first trace failed, so see if we can go farther if we step up. // trace up to see if we have enough room. UTIL_TraceHull( GetAbsOrigin(), GetAbsOrigin() + Vector( 0, 0, m_Local.m_flStepSize ), GetPlayerMins(), GetPlayerMaxs(), MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &trUp ); // do a trace from the stepped up height UTIL_TraceHull( trUp.endpos, pos + Vector( 0, 0, trUp.endpos.z - trUp.startpos.z ), GetPlayerMins(), GetPlayerMaxs(), MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &trOver ); if ( trOver.fraction < 1.0f ) { // check if the endpos intersects with the direction the object is travelling. if it doesn't, this is a good direction to move. if ( objDir.IsZero() || ( IntersectInfiniteRayWithSphere( objPos, objDir, trOver.endpos, radius, &flHit1, &flHit2 ) && ( ( flHit1 >= 0.0f ) || ( flHit2 >= 0.0f ) ) ) ) { return false; } } } } // trace down to see if this position is on the ground UTIL_TraceLine( trOver.endpos, trOver.endpos - Vector( 0, 0, fVertDist ), MASK_SOLID_BRUSHONLY, NULL, COLLISION_GROUP_NONE, &trDown ); if ( trDown.fraction == 1.0f ) return false; return true; }
void CStomp::Think( void ) { trace_t tr; SetNextThink( gpGlobals->curtime + 0.1 ); // Do damage for this frame Vector vecStart = GetAbsOrigin(); vecStart.z += 30; Vector vecEnd = vecStart + (m_vecMoveDir * m_flSpeed * gpGlobals->frametime); UTIL_TraceHull( vecStart, vecEnd, Vector(-32, -32, -32), Vector(32, 32, 32), MASK_SOLID, m_pOwner, COLLISION_GROUP_NONE, &tr ); // NDebugOverlay::Line( vecStart, vecEnd, 0, 255, 0, false, 10.0f ); if ( tr.m_pEnt ) { CBaseEntity *pEntity = tr.m_pEnt; CTakeDamageInfo info( this, this, 50, DMG_SONIC ); CalculateMeleeDamageForce( &info, m_vecMoveDir, tr.endpos ); pEntity->TakeDamage( info ); } // Accelerate the effect m_flSpeed += (gpGlobals->frametime) * m_uiFramerate; m_uiFramerate += (gpGlobals->frametime) * 2000; // Move and spawn trails while ( gpGlobals->curtime - m_flDmgTime > STOMP_INTERVAL ) { SetAbsOrigin( GetAbsOrigin() + m_vecMoveDir * m_flSpeed * STOMP_INTERVAL ); for ( int i = 0; i < 2; i++ ) { CSprite *pSprite = CSprite::SpriteCreate( GARG_STOMP_SPRITE_NAME, GetAbsOrigin(), TRUE ); if ( pSprite ) { UTIL_TraceLine( GetAbsOrigin(), GetAbsOrigin() - Vector(0,0,500), MASK_SOLID, this, COLLISION_GROUP_NONE, &tr ); pSprite->SetAbsOrigin( tr.endpos ); // pSprite->pev->velocity = Vector(RandomFloat(-200,200),RandomFloat(-200,200),175); pSprite->SetNextThink( gpGlobals->curtime + 0.3 ); pSprite->SetThink( &CSprite::SUB_Remove ); pSprite->SetTransparency( kRenderTransAdd, 255, 255, 255, 255, kRenderFxFadeFast ); } g_pEffects->EnergySplash( tr.endpos, tr.plane.normal ); } m_flDmgTime += STOMP_INTERVAL; // Scale has the "life" of this effect m_flScale -= STOMP_INTERVAL * m_flSpeed; if ( m_flScale <= 0 ) { // Life has run out UTIL_Remove(this); // STOP_SOUND( edict(), CHAN_BODY, GARG_STOMP_BUZZ_SOUND ); CPASAttenuationFilter filter( this ); StopSound( entindex(), CHAN_STATIC, GARG_STOMP_BUZZ_SOUND ); } } }
void CStomp::Think( void ) { TraceResult tr; pev->nextthink = gpGlobals->time + 0.1; // Do damage for this frame Vector vecStart = GetAbsOrigin(); vecStart.z += 30; Vector vecEnd = vecStart + (pev->movedir * pev->speed * STOMP_FRAMETIME); UTIL_TraceHull( vecStart, vecEnd, dont_ignore_monsters, head_hull, ENT(pev), &tr ); if ( tr.pHit && tr.pHit != pev->owner ) { CBaseEntity *pEntity = CBaseEntity::Instance( tr.pHit ); entvars_t *pevOwner = pev; if ( pev->owner ) pevOwner = VARS(pev->owner); if ( pEntity ) pEntity->TakeDamage( pev, pevOwner, gSkillData.gargantuaDmgStomp, DMG_SONIC ); } // Accelerate the effect pev->speed = pev->speed + (STOMP_FRAMETIME) * pev->framerate; pev->framerate = pev->framerate + (STOMP_FRAMETIME) * 1500; // Move and spawn trails while ( gpGlobals->time - pev->dmgtime > STOMP_INTERVAL ) { SetAbsOrigin( GetAbsOrigin() + pev->movedir * pev->speed * STOMP_INTERVAL ); for ( int i = 0; i < 2; i++ ) { CSprite *pSprite = CSprite::SpriteCreate( GARG_STOMP_SPRITE_NAME, GetAbsOrigin(), TRUE ); if ( pSprite ) { UTIL_TraceLine( GetAbsOrigin(), GetAbsOrigin() - Vector( 0, 0, 500 ), ignore_monsters, edict(), &tr ); pSprite->SetAbsOrigin( tr.vecEndPos ); pSprite->SetAbsVelocity( Vector(RANDOM_FLOAT(-200,200),RANDOM_FLOAT(-200,200),175)); // pSprite->AnimateAndDie( RANDOM_FLOAT( 8.0, 12.0 ) ); pSprite->pev->nextthink = gpGlobals->time + 0.3; pSprite->SetThink( SUB_Remove ); pSprite->SetTransparency( kRenderTransAdd, 255, 255, 255, 255, kRenderFxFadeFast ); } } pev->dmgtime += STOMP_INTERVAL; // Scale has the "life" of this effect pev->scale -= STOMP_INTERVAL * pev->speed; if ( pev->scale <= 0 ) { // Life has run out UTIL_Remove(this); STOP_SOUND( edict(), CHAN_BODY, GARG_STOMP_BUZZ_SOUND ); } } }
CReservePlayerSpot *CReservePlayerSpot::ReserveSpot( CBasePlayer *owner, const Vector& org, const Vector& mins, const Vector& maxs, bool& validspot ) { CReservePlayerSpot *spot = ( CReservePlayerSpot * )CreateEntityByName( "reserved_spot" ); Assert( spot ); spot->SetAbsOrigin( org ); UTIL_SetSize( spot, mins, maxs ); spot->SetOwnerEntity( owner ); spot->Spawn(); // See if spot is valid trace_t tr; UTIL_TraceHull( org, org, mins, maxs, MASK_PLAYERSOLID, owner, COLLISION_GROUP_PLAYER_MOVEMENT, &tr ); validspot = !tr.startsolid; if ( !validspot ) { Vector org2 = org + Vector( 0, 0, 1 ); // See if spot is valid trace_t tr; UTIL_TraceHull( org2, org2, mins, maxs, MASK_PLAYERSOLID, owner, COLLISION_GROUP_PLAYER_MOVEMENT, &tr ); validspot = !tr.startsolid; } return spot; }
//------------------------------------------------------------------------------ // Purpose : Starts the swing of the weapon and determines the animation //------------------------------------------------------------------------------ void CWeaponCrowbar::Swing( void ) { // Try a ray CBasePlayer *pOwner = ToBasePlayer( GetOwner() ); if ( !pOwner ) return; Vector swingStart = pOwner->Weapon_ShootPosition( ); Vector forward; pOwner->EyeVectors( &forward, NULL, NULL ); Vector swingEnd = swingStart + forward * CROWBAR_RANGE; UTIL_TraceLine( swingStart, swingEnd, MASK_SHOT_HULL, pOwner, COLLISION_GROUP_NONE, &m_traceHit ); m_nHitActivity = ACT_VM_HITCENTER; if ( m_traceHit.fraction == 1.0 ) { float bludgeonHullRadius = 1.732f * BLUDGEON_HULL_DIM; // hull is +/- 16, so use cuberoot of 2 to determine how big the hull is from center to the corner point // Back off by hull "radius" swingEnd -= forward * bludgeonHullRadius; UTIL_TraceHull( swingStart, swingEnd, g_bludgeonMins, g_bludgeonMaxs, MASK_SHOT_HULL, pOwner, COLLISION_GROUP_NONE, &m_traceHit ); if ( m_traceHit.fraction < 1.0 ) { m_nHitActivity = ChooseIntersectionPointAndActivity( m_traceHit, g_bludgeonMins, g_bludgeonMaxs, pOwner ); } } // ------------------------- // Miss // ------------------------- if ( m_traceHit.fraction == 1.0f ) { m_nHitActivity = ACT_VM_MISSCENTER; //Play swing sound WeaponSound( SINGLE ); //Setup our next attack times m_flNextPrimaryAttack = gpGlobals->curtime + CROWBAR_REFIRE_MISS; } else { Hit(); //Setup our next attack times m_flNextPrimaryAttack = gpGlobals->curtime + CROWBAR_REFIRE_HIT; } //Send the anim SendWeaponAnim( m_nHitActivity ); pOwner->SetAnimation( PLAYER_ATTACK1 ); }
// check a throw from vecSrc. If not valid, move the position back along the line to vecEye void CWeaponGrenade::CheckThrowPosition( CBasePlayer *pPlayer, const Vector &vecEye, Vector &vecSrc ) { trace_t tr; UTIL_TraceHull( vecEye, vecSrc, -Vector(GRENADE_RADIUS+2,GRENADE_RADIUS+2,GRENADE_RADIUS+2), Vector(GRENADE_RADIUS+2,GRENADE_RADIUS+2,GRENADE_RADIUS+2), pPlayer->PhysicsSolidMaskForEntity(), pPlayer, pPlayer->GetCollisionGroup(), &tr ); if ( tr.DidHit() ) vecSrc = tr.endpos; }
//----------------------------------------------------------------------------- // Purpose: Check to see if we should spawn another instance //----------------------------------------------------------------------------- void CEnvEntityMaker::CheckSpawnThink( void ) { SetNextThink( gpGlobals->curtime + 0.5f ); // Do we have an instance? if ( m_hCurrentInstance ) { // If Wait-For-Destruction is set, abort immediately if ( m_spawnflags & SF_ENTMAKER_WAITFORDESTRUCTION ) return; } // Do we have a blocker? if ( m_hCurrentBlocker ) { // If it hasn't moved, abort immediately if ( m_vecBlockerOrigin == m_hCurrentBlocker->GetAbsOrigin() ) return; } // Check to see if there's enough room to spawn trace_t tr; UTIL_TraceHull( GetAbsOrigin(), GetAbsOrigin(), m_vecEntityMins, m_vecEntityMaxs, MASK_SOLID, this, COLLISION_GROUP_NONE, &tr ); if ( tr.m_pEnt || tr.startsolid ) { // Store off our blocker to check later m_hCurrentBlocker = tr.m_pEnt; if ( m_hCurrentBlocker ) { m_vecBlockerOrigin = m_hCurrentBlocker->GetAbsOrigin(); } return; } // We're clear, now check to see if the player's looking if ( !(m_spawnflags & SF_ENTMAKER_IGNOREFACING) ) { 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 Vector vLookDir = pPlayer->EyeDirection3D(); Vector vTargetDir = GetAbsOrigin() - pPlayer->EyePosition(); VectorNormalize(vTargetDir); float fDotPr = DotProduct(vLookDir,vTargetDir); if ( fDotPr > 0 ) return; } } } // Clear, no player watching, so spawn! SpawnEntity(); }
Vector DropToGround( CBaseEntity *pMainEnt, const Vector &vPos, const Vector &vMins, const Vector &vMaxs ) { trace_t trace; UTIL_TraceHull( vPos, vPos + Vector( 0, 0, -500 ), vMins, vMaxs, MASK_SOLID, pMainEnt, COLLISION_GROUP_NONE, &trace ); return trace.endpos; }
bool UTIL_IsSpaceEmpty( CBaseEntity *pMainEnt, const Vector &vMin, const Vector &vMax ) { Vector vHalfDims = ( vMax - vMin ) * 0.5f; Vector vCenter = vMin + vHalfDims; trace_t trace; UTIL_TraceHull( vCenter, vCenter, -vHalfDims, vHalfDims, MASK_SOLID, pMainEnt, COLLISION_GROUP_NONE, &trace ); bool bClear = ( trace.fraction == 1 && trace.allsolid != 1 && (trace.startsolid != 1) ); return bClear; }
//--------------------------------------------------------- //--------------------------------------------------------- void CNPC_Assassin::HandleAnimEvent( animevent_t *pEvent ) { if ( pEvent->event == AE_ASSASIN_FIRE_PISTOL_RIGHT ) { FirePistol( 0 ); return; } if ( pEvent->event == AE_ASSASIN_FIRE_PISTOL_LEFT ) { FirePistol( 1 ); return; } if ( pEvent->event == AE_ASSASIN_KICK_HIT ) { Vector attackDir = BodyDirection2D(); Vector attackPos = WorldSpaceCenter() + ( attackDir * 64.0f ); trace_t tr; UTIL_TraceHull( WorldSpaceCenter(), attackPos, -Vector(8,8,8), Vector(8,8,8), MASK_SHOT_HULL, this, COLLISION_GROUP_NONE, &tr ); if ( ( tr.m_pEnt != NULL ) && ( tr.DidHitWorld() == false ) ) { if ( tr.m_pEnt->m_takedamage != DAMAGE_NO ) { CTakeDamageInfo info( this, this, 5, DMG_CLUB ); CalculateMeleeDamageForce( &info, (tr.endpos - tr.startpos), tr.endpos ); tr.m_pEnt->TakeDamage( info ); CBasePlayer *pPlayer = ToBasePlayer( tr.m_pEnt ); if ( pPlayer != NULL ) { //Kick the player angles pPlayer->ViewPunch( QAngle( -30, 40, 10 ) ); } EmitSound( "Zombie.AttackHit" ); //EmitSound( "Assassin.AttackHit" ); } } else { EmitSound( "Assassin.AttackMiss" ); //EmitSound( "Assassin.AttackMiss" ); } return; } BaseClass::HandleAnimEvent( pEvent ); }
// // VecCheckThrow - returns the velocity vector at which an object should be thrown from vecspot1 to hit vecspot2. // returns vec3_origin if throw is not feasible. // Vector VecCheckThrow ( CBaseEntity *pEdict, const Vector &vecSpot1, Vector vecSpot2, float flSpeed, float flGravityAdj, Vector *vecMins, Vector *vecMaxs ) { float flGravity = sv_gravity.GetFloat() * flGravityAdj; Vector vecGrenadeVel = (vecSpot2 - vecSpot1); // throw at a constant time float time = vecGrenadeVel.Length( ) / flSpeed; vecGrenadeVel = vecGrenadeVel * (1.0 / time); // adjust upward toss to compensate for gravity loss vecGrenadeVel.z += flGravity * time * 0.5; Vector vecApex = vecSpot1 + (vecSpot2 - vecSpot1) * 0.5; vecApex.z += 0.5 * flGravity * (time * 0.5) * (time * 0.5); trace_t tr; UTIL_TraceLine(vecSpot1, vecApex, MASK_SOLID, pEdict, COLLISION_GROUP_NONE, &tr); if (tr.fraction != 1.0) { // fail! //NDebugOverlay::Line( vecSpot1, vecApex, 255, 0, 0, true, 5.0 ); return vec3_origin; } //NDebugOverlay::Line( vecSpot1, vecApex, 0, 255, 0, true, 5.0 ); UTIL_TraceLine(vecSpot2, vecApex, MASK_SOLID_BRUSHONLY, pEdict, COLLISION_GROUP_NONE, &tr); if (tr.fraction != 1.0) { // fail! //NDebugOverlay::Line( vecApex, vecSpot2, 255, 0, 0, true, 5.0 ); return vec3_origin; } //NDebugOverlay::Line( vecApex, vecSpot2, 0, 255, 0, true, 5.0 ); if ( vecMins && vecMaxs ) { // Check to ensure the entity's hull can travel the first half of the grenade throw UTIL_TraceHull( vecSpot1, vecApex, *vecMins, *vecMaxs, MASK_SOLID, pEdict, COLLISION_GROUP_NONE, &tr); if ( tr.fraction < 1.0 ) { //NDebugOverlay::SweptBox( vecSpot1, tr.endpos, *vecMins, *vecMaxs, vec3_angle, 255, 0, 0, 64, 5.0 ); return vec3_origin; } } //NDebugOverlay::SweptBox( vecSpot1, vecApex, *vecMins, *vecMaxs, vec3_angle, 0, 255, 0, 64, 5.0 ); return vecGrenadeVel; }
static void MoveToGround( Vector *position, CBaseEntity *ignore, const Vector &mins, const Vector &maxs ) { trace_t tr; // Find point on floor where enemy would stand at chasePosition Vector floor = *position; floor.z -= 1024; UTIL_TraceHull( *position, floor, mins, maxs, MASK_NPCSOLID, ignore, COLLISION_GROUP_NONE, &tr ); if ( tr.fraction < 1 ) { position->z = tr.endpos.z; } }
// Make sure we aren't going to throw the grenade INTO something! void CGEWeaponRocketLauncher::CheckLaunchPosition( const Vector &vecEye, Vector &vecSrc ) { CBaseCombatCharacter *pOwner = GetOwner(); if ( !pOwner ) return; trace_t tr; UTIL_TraceHull( vecEye, vecSrc, -Vector(6,6,6), Vector(6,6,6), pOwner->PhysicsSolidMaskForEntity(), pOwner, pOwner->GetCollisionGroup(), &tr ); if ( tr.DidHit() ) vecSrc = tr.endpos; }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CWeaponCGuard::DelayedFire( void ) { if ( m_flChargeTime >= gpGlobals->curtime ) return; if ( m_bFired ) return; m_bFired = true; // Only the player fires this way so we can cast CBasePlayer *pPlayer = ToBasePlayer( GetOwner() ); if ( pPlayer == NULL ) return; // Abort here to handle burst and auto fire modes if ( (GetMaxClip1() != -1 && m_iClip1 == 0) || (GetMaxClip1() == -1 && !pPlayer->GetAmmoCount(m_iPrimaryAmmoType) ) ) return; // MUST call sound before removing a round from the clip of a CMachineGun WeaponSound(SINGLE); pPlayer->DoMuzzleFlash(); // To make the firing framerate independent, we may have to fire more than one bullet here on low-framerate systems, // especially if the weapon we're firing has a really fast rate of fire. if ( GetSequence() != SelectWeightedSequence( ACT_VM_PRIMARYATTACK ) ) { m_flNextPrimaryAttack = gpGlobals->curtime; } // Make sure we don't fire more than the amount in the clip, if this weapon uses clips if ( UsesClipsForAmmo1() ) { m_iClip1 = m_iClip1 - 1; } // Fire the bullets Vector vecSrc = pPlayer->Weapon_ShootPosition( ); Vector vecAiming = pPlayer->GetRadialAutoVector( NEW_AUTOAIM_RADIUS, NEW_AUTOAIM_DIST ); //Factor in the view kick AddViewKick(); Vector impactPoint = vecSrc + ( vecAiming * MAX_TRACE_LENGTH ); trace_t tr; UTIL_TraceHull( vecSrc, impactPoint, Vector( -2, -2, -2 ), Vector( 2, 2, 2 ), MASK_SHOT, pPlayer, COLLISION_GROUP_NONE, &tr ); CreateConcussiveBlast( tr.endpos, tr.plane.normal, this, 1.0 ); }
float CASW_Spawn_Manager::traceHull(const Vector vecSpawnPos, const Vector vecMins, const Vector vecMaxs, int x, int y) { trace_t tr; UTIL_TraceHull( vecSpawnPos, vecSpawnPos + Vector( vecMaxs.x * x, vecMaxs.y * y, 0 ), vecMins, vecMaxs, MASK_NPCSOLID, NULL, COLLISION_GROUP_NONE, &tr ); return tr.fraction; }
void CC_CreatePlayerBall(const CCommand &args) { if (!SDKGameRules()->IsIntermissionState() || SDKGameRules()->IsCeremony()) return; CSDKPlayer *pPl = ToSDKPlayer(UTIL_GetCommandClient()); if (!CSDKPlayer::IsOnField(pPl)) return; if (pPl->GetFlags() & FL_REMOTECONTROLLED) return; trace_t tr; CTraceFilterSkipTwoEntities traceFilter(pPl, pPl->GetPlayerBall(), COLLISION_GROUP_NONE); UTIL_TraceHull( pPl->GetLocalOrigin() + VEC_VIEW, pPl->GetLocalOrigin() + VEC_VIEW + pPl->EyeDirection3D() * 150, -Vector(BALL_PHYS_RADIUS, BALL_PHYS_RADIUS, BALL_PHYS_RADIUS), Vector(BALL_PHYS_RADIUS, BALL_PHYS_RADIUS, BALL_PHYS_RADIUS), MASK_SOLID, &traceFilter, &tr); Vector pos = tr.endpos; if (pPl->GetPlayerBall()) { if (pPl->GetPlayerBall()->GetHoldingPlayer()) { //pPl->GetPlayerBall()->RemoveFromPlayerHands(pPl->GetPlayerBall()->GetHoldingPlayer()); pPl->GetPlayerBall()->State_Transition(BALL_STATE_NORMAL); } if (sv_ball_update_physics.GetBool()) pPl->GetPlayerBall()->CreateVPhysics(); pPl->GetPlayerBall()->SetPos(pos, false); pPl->GetPlayerBall()->RemoveAllTouches(); } else pPl->SetPlayerBall(CreatePlayerBall(pos, pPl)); //pPl->GetPlayerBall()->m_nSkin = pPl->GetPlayerBallSkin() == -1 ? g_IOSRand.RandomInt(0, BALL_SKIN_COUNT - 1) : pPl->GetPlayerBallSkin(); pPl->GetPlayerBall()->SetSkinName(pPl->GetPlayerBallSkinName()); pPl->GetPlayerBall()->SetBallCannonMode(false); pPl->GetPlayerBall()->SaveBallCannonSettings(); pPl->m_Shared.SetStamina(100); }