bool CHostageImprov::FaceTowards(const Vector &target, float deltaT) { bool bError = false; Vector2D to = (target - GetFeet()).Make2D(); #ifndef PLAY_GAMEDLL to.NormalizeInPlace(); #else // TODO: fix test demo float_precision float_x = target.x - GetFeet().x; float_precision float_y = target.y - GetFeet().y; float_precision flLen = to.Length(); if (flLen <= 0) { to.x = 1; to.y = 0; } else { to.x = float_x / flLen; to.y = float_y / flLen; } #endif float moveAngle = GetMoveAngle(); Vector2D lat(BotCOS(moveAngle), BotSIN(moveAngle)); Vector2D dir(-lat.y, lat.x); float_precision dot = DotProduct(to, dir); if (DotProduct(to, lat) < 0.0f) { if (dot >= 0.0f) dot = 1.0f; else dot = -1.0f; bError = true; } const float maxTurnRate = 0.05f; if (bError || Q_fabs(dot) >= maxTurnRate) { const float tolerance = 300.0f; float moveRatio = dot * deltaT * tolerance + moveAngle; BotCOS(moveRatio); BotSIN(moveRatio); m_moveAngle = moveRatio; m_hostage->pev->angles.y = moveRatio; return false; } return true; }
void CCSBot::Panic(CBasePlayer *pEnemy) { if (IsSurprised()) return; Vector2D dir(BotCOS(pev->v_angle.y), BotSIN(pev->v_angle.y)); Vector2D perp(-dir.y, dir.x); Vector spot; if (GetProfile()->GetSkill() >= 0.5f) { Vector2D toEnemy = (pEnemy->pev->origin - pev->origin).Make2D(); toEnemy.NormalizeInPlace(); float along = DotProduct(toEnemy, dir); float c45 = 0.7071f; float size = 100.0f; real_t shift = RANDOM_FLOAT(-75.0, 75.0); if (along > c45) { spot.x = pev->origin.x + dir.x * size + perp.x * shift; spot.y = pev->origin.y + dir.y * size + perp.y * shift; } else if (along < -c45) { spot.x = pev->origin.x - dir.x * size + perp.x * shift; spot.y = pev->origin.y - dir.y * size + perp.y * shift; } else if (DotProduct(toEnemy, perp) > 0.0) { spot.x = pev->origin.x + perp.x * size + dir.x * shift; spot.y = pev->origin.y + perp.y * size + dir.y * shift; } else { spot.x = pev->origin.x - perp.x * size + dir.x * shift; spot.y = pev->origin.y - perp.y * size + dir.y * shift; } } else { const float offset = 200.0f; real_t side = RANDOM_FLOAT(-offset, offset) * 2.0f; spot.x = pev->origin.x - dir.x * offset + perp.x * side; spot.y = pev->origin.y - dir.y * offset + perp.y * side; } spot.z = pev->origin.z + RANDOM_FLOAT(-50.0, 50.0); // we are stunned for a moment m_surpriseDelay = RANDOM_FLOAT(0.1, 0.2); m_surpriseTimestamp = gpGlobals->time; SetLookAt("Panic", &spot, PRIORITY_HIGH, 0, 0, 5.0); PrintIfWatched("Aaaah!\n"); }
bool CHostageImprov::__MAKE_VHOOK(IsPlayerLookingAtMe)(CBasePlayer *other, float cosTolerance) const { Vector2D toOther = (other->pev->origin - GetCentroid()).Make2D(); toOther.NormalizeInPlace(); UTIL_MakeVectors(other->pev->punchangle + other->pev->v_angle); Vector2D otherDir = gpGlobals->v_forward.Make2D(); otherDir.NormalizeInPlace(); if (-cosTolerance > DotProduct(toOther, otherDir)) { if (IsVisible(other->EyePosition())) { return true; } } return false; }
// Return true if we can see any part of the player // Check parts in order of importance. Return the first part seen in "visParts" if it is non-NULL. bool CCSBot::__MAKE_VHOOK(IsVisible)(CBasePlayer *player, bool testFOV, unsigned char *visParts) const { Vector spot = player->pev->origin; VisiblePartType testVisParts = NONE; // finish chest check if (IsVisible(&spot, testFOV)) testVisParts |= CHEST; // check top of head spot = spot + Vector(0, 0, 25.0f); if (IsVisible(&spot, testFOV)) testVisParts |= HEAD; // check feet const float standFeet = 34.0f; const float crouchFeet = 14.0f; if (player->pev->flags & FL_DUCKING) spot.z = player->pev->origin.z - crouchFeet; else spot.z = player->pev->origin.z - standFeet; // check feet if (IsVisible(&spot, testFOV)) testVisParts |= FEET; // check "edges" const float edgeOffset = 13.0f; Vector2D dir = (player->pev->origin - pev->origin).Make2D(); dir.NormalizeInPlace(); Vector2D perp(-dir.y, dir.x); spot = player->pev->origin + Vector(perp.x * edgeOffset, perp.y * edgeOffset, 0); if (IsVisible(&spot, testFOV)) testVisParts |= LEFT_SIDE; spot = player->pev->origin - Vector(perp.x * edgeOffset, perp.y * edgeOffset, 0); if (IsVisible(&spot, testFOV)) testVisParts |= RIGHT_SIDE; if (visParts != NULL) *visParts = testVisParts; if (testVisParts != NONE) return true; return false; }
void vParticleRenderer_Trail::SetStepData( vParticle *p, vTrailStep_t &step ) { step.center = p->vecPos; Vector2D up = vecLastPos - p->vecPos; up.NormalizeInPlace(); Vector2D right( -up.y, up.x ); right *= p->GetCurrentSize(); step.a = p->vecPos - right; step.b = p->vecPos + right; }
void vParticleOperator_GravityWorld::Simulate( vParticle *parent ) { float dot_z = DotProduct( MainViewForward(), Vector( 0, 0, -1 ) ); float rotation_dir = Sign( dot_z ); int vx, vy, w, t; vgui::surface()->GetFullscreenViewport( vx, vy, w, t ); Vector screen; if ( ScreenTransform( MainViewOrigin() + Vector( 0, 0, 100 ), screen ) ) ScreenTransform( MainViewOrigin() - Vector( 0, 0, 100 ), screen ); screen *= Vector( 0.5f, -0.5f, 0 ); screen += Vector( 0.5f, 0.5f, 0 ); Vector2D gravity_center( w * screen.x, t * screen.y ); Vector2D delta = parent->vecPos - gravity_center; float screenLength = delta.NormalizeInPlace(); delta *= rotation_dir * -1.0f; Vector2D accel = delta * vParticle::GetRelativeScale() * GetImpulse( parent ) * amt; float speedMult = 1.0f; if ( rotation_dir > 0 ) { float drag = RemapValClamped( rotation_dir, 0.5f, 1, 1, 0.00001f ); ScaleByFrametime( drag ); speedMult = RemapValClamped( (screenLength/vParticle::GetRelativeScale()), 0, 1000, 0, 1 ) * (1.0f - drag) + drag; } parent->vecVelocity += accel; parent->vecVelocity *= speedMult; }
void CHostageImprov::__MAKE_VHOOK(OnTouch)(CBaseEntity *other) { const char *classname; Vector2D to; const float pushForce = 20.0f; classname = STRING(other->pev->classname); if (cv_hostage_debug.value != 0.0) { CONSOLE_ECHO("%5.1f: Hostage hit '%s'\n", gpGlobals->time, classname); } m_collisionTimer.Start(); if (FStrEq(classname, "worldspawn")) { const float lookAheadRange = 30.0f; float ground; Vector normal = Vector(0, 0, 1); Vector alongFloor; TraceResult result; bool isStep = false; UTIL_MakeVectors(m_hostage->pev->angles); if (!GetSimpleGroundHeightWithFloor(&GetEyes(), &ground, &normal)) return; if (cv_hostage_debug.value < 0.0) { UTIL_DrawBeamPoints(GetFeet() + normal * 50, GetFeet(), 2, 255, 255, 0); } alongFloor = CrossProduct(normal, gpGlobals->v_right); Vector pos = alongFloor * lookAheadRange; for (float_precision offset = 1.0f; offset <= 18.0f; offset += 3.0f) { Vector vecStart = GetFeet(); vecStart.z += offset; UTIL_TraceLine(vecStart, vecStart + pos, ignore_monsters, dont_ignore_glass, m_hostage->pev->pContainingEntity, &result); if (result.flFraction < 1.0f && result.vecPlaneNormal.z < MaxUnitZSlope) { isStep = true; break; } } if (isStep) { float stepAheadGround = pos.z; Vector stepAheadNormal = Vector(0, 0, stepAheadGround); m_inhibitObstacleAvoidance.Start(0.5); for (float range = 1.0f; range <= 30.5f; range += 5.0f) { Vector stepAhead = GetFeet() + alongFloor * range; stepAhead.z = GetEyes().z; if (GetSimpleGroundHeightWithFloor(&stepAhead, &stepAheadGround, &stepAheadNormal)) { float dz = stepAheadGround - GetFeet().z; if (dz > 0.0f && dz < 18.0f) { m_hostage->pev->origin.z = stepAheadGround + 3.0f; break; } } } } else if (!IsMoving() && !IsUsingLadder()) { bool isSeam = false; const float checkSeamRange = 50.0f; Vector posBehind; posBehind = GetEyes() - alongFloor * checkSeamRange; UTIL_TraceLine(posBehind, posBehind - Vector(0, 0, 9999), ignore_monsters, dont_ignore_glass, m_hostage->pev->pContainingEntity, &result); if (result.flFraction < 1.0f && DotProduct(result.vecPlaneNormal, normal) < 1.0f) { isSeam = true; } else { Vector posAhead = GetEyes() + alongFloor * checkSeamRange; UTIL_TraceLine(posAhead, posAhead - Vector(0, 0, 9999), ignore_monsters, dont_ignore_glass, m_hostage->pev->pContainingEntity, &result); if (result.flFraction < 1.0f && DotProduct(result.vecPlaneNormal, normal) < 1.0f) isSeam = true; } if (isSeam) { if (cv_hostage_debug.value != 0.0) { CONSOLE_ECHO("Hostage stuck on seam.\n"); } const float nudge = 3.0f; m_hostage->pev->origin.z += nudge; } } } else if (FStrEq(classname, "func_breakable")) { other->TakeDamage(m_hostage->pev, m_hostage->pev, 9999.9, DMG_BULLET); } else if (other->IsPlayer() || FClassnameIs(other->pev, "hostage_entity")) { to = (m_hostage->pev->origin - other->pev->origin).Make2D(); to.NormalizeInPlace(); m_vel.x += to.x * pushForce; m_vel.y += to.y * pushForce; } }
float GetAmountOfPlayerVisible(Vector vecSrc, CBaseEntity *entity) { float retval = 0.0f; TraceResult tr; Vector spot; const float topOfHead = 25.0f; const float standFeet = 34.0f; const float crouchFeet = 14.0f; const float edgeOffset = 13.0f; if (!entity->IsPlayer()) { UTIL_TraceLine(vecSrc, entity->pev->origin, ignore_monsters, NULL, &tr); if (tr.flFraction == 1.0f) retval = 1.0f; return retval; } UTIL_TraceLine(vecSrc, entity->pev->origin, ignore_monsters, NULL, &tr); if (tr.flFraction == 1.0f) retval += 0.4f; spot = entity->pev->origin + Vector(0, 0, topOfHead); UTIL_TraceLine(vecSrc, spot, ignore_monsters, NULL, &tr); if (tr.flFraction == 1.0f) retval += 0.2f; spot = entity->pev->origin; if (entity->pev->flags & FL_DUCKING) spot.z -= crouchFeet; else spot.z -= standFeet; UTIL_TraceLine(vecSrc, spot, ignore_monsters, NULL, &tr); if (tr.flFraction == 1.0f) retval += 0.2f; Vector2D dir = (entity->pev->origin - vecSrc).Make2D(); dir.NormalizeInPlace(); Vector2D perp(-dir.y * edgeOffset, dir.x * edgeOffset); spot = entity->pev->origin + Vector(perp.x, perp.y, 0); UTIL_TraceLine(vecSrc, spot, ignore_monsters, NULL, &tr); if (tr.flFraction == 1.0f) retval += 0.1; spot = entity->pev->origin - Vector(perp.x, perp.y, 0); UTIL_TraceLine(vecSrc, spot, ignore_monsters, NULL, &tr); if (tr.flFraction == 1.0f) retval += 0.1; return retval; }