void CSPCharacter::Think() { BaseClass::Think(); CPlanet* pPlanet = GetNearestPlanet(); if (pPlanet && !HasMoveParent()) { m_flLastEnteredAtmosphere = GameServer()->GetGameTime(); m_flRollFromSpace = GetGlobalAngles().r; } SetMoveParent(pPlanet); if (pPlanet) { // Estimate this planet's mass given things we know about earth. Assume equal densities. double flEarthVolume = 1097509500000000000000.0; // cubic meters double flEarthMass = 5974200000000000000000000.0; // kilograms // 4/3 * pi * r^3 = volume of a sphere CScalableFloat flPlanetVolume = pPlanet->GetRadius()*pPlanet->GetRadius()*pPlanet->GetRadius()*(M_PI*4/3); double flPlanetMass = RemapVal(flPlanetVolume, CScalableFloat(), CScalableFloat(flEarthVolume, SCALE_METER), 0, flEarthMass); double flG = 0.0000000000667384; // Gravitational constant CScalableVector vecDistance = (pPlanet->GetGlobalOrigin() - GetGlobalOrigin()); CScalableFloat flDistance = vecDistance.Length(); CScalableFloat flGravity = CScalableFloat(flPlanetMass*flG, SCALE_METER)/(flDistance*flDistance); CScalableVector vecGravity = vecDistance * flGravity / flDistance; SetGlobalGravity(vecGravity); } }
void CLaser::OnSetOwner(CBaseEntity* pOwner) { BaseClass::OnSetOwner(pOwner); CDigitank* pTank = dynamic_cast<CDigitank*>(pOwner); if (!pTank) return; SetGlobalAngles(VectorAngles((pTank->GetLastAim() - GetGlobalOrigin()).Normalized())); SetGlobalOrigin(pOwner->GetGlobalOrigin()); SetGlobalVelocity(Vector(0,0,0)); SetGlobalGravity(Vector(0,0,0)); m_flTimeExploded = GameServer()->GetGameTime(); Vector vecForward, vecRight; AngleVectors(GetGlobalAngles(), &vecForward, &vecRight, NULL); for (size_t i = 0; i < GameServer()->GetMaxEntities(); i++) { CBaseEntity* pEntity = CBaseEntity::GetEntity(i); if (!pEntity) continue; if (!pEntity->TakesDamage()) continue; if (pEntity->GetOwner() == pOwner->GetOwner()) continue; float flDistance = DistanceToPlane(pEntity->GetGlobalOrigin(), GetGlobalOrigin(), vecRight); if (flDistance > 4 + pEntity->GetBoundingRadius()) continue; // Cull objects behind if (vecForward.Dot(pEntity->GetGlobalOrigin() - GetGlobalOrigin()) < 0) continue; if (pEntity->Distance(GetGlobalOrigin()) > LaserLength()) continue; pEntity->TakeDamage(pOwner, this, DAMAGE_LASER, m_flDamage, flDistance < pEntity->GetBoundingRadius()-2); CDigitank* pTank = dynamic_cast<CDigitank*>(pEntity); if (pTank) { float flRockIntensity = 0.5f; Vector vecDirection = (pTank->GetGlobalOrigin() - pOwner->GetGlobalOrigin()).Normalized(); pTank->RockTheBoat(flRockIntensity, vecDirection); } } CDigitanksPlayer* pCurrentTeam = DigitanksGame()->GetCurrentLocalDigitanksPlayer(); if (pCurrentTeam && pCurrentTeam->GetVisibilityAtPoint(GetGlobalOrigin()) < 0.1f) { if (pCurrentTeam->GetVisibilityAtPoint(GetGlobalOrigin() + AngleVector(GetGlobalAngles())*LaserLength()) < 0.1f) { // If the start and end points are both in the fog of war, delete it now that we've aready done the damage so it doesn't get rendered later. if (GameNetwork()->IsHost()) Delete(); } } }