void CCharacterCamera::CameraThink() { BaseClass::CameraThink(); CCharacter* pCharacter = m_hCharacter; if (!pCharacter) return; if (GetThirdPerson()) { SetGlobalOrigin(GetThirdPersonCameraPosition()); SetGlobalAngles(VectorAngles(GetThirdPersonCameraDirection())); } else { SetGlobalOrigin(pCharacter->GetGlobalOrigin() + pCharacter->GetUpVector() * (TFloat)pCharacter->EyeHeight()); SetGlobalAngles(pCharacter->GetViewAngles()); } }
void CSPCharacter::LockViewToPlanet() { // Now lock the roll value to the planet. CPlanet* pNearestPlanet = GetNearestPlanet(); if (!pNearestPlanet) return; Matrix4x4 mGlobalRotation = GetGlobalTransform(); mGlobalRotation.SetTranslation(CScalableVector()); // Construct a "local space" for the planet Vector vecPlanetUp = GetUpVector(); Vector vecPlanetForward = mGlobalRotation.GetForwardVector(); Vector vecPlanetRight = vecPlanetForward.Cross(vecPlanetUp).Normalized(); vecPlanetForward = vecPlanetUp.Cross(vecPlanetRight).Normalized(); Matrix4x4 mPlanet(vecPlanetForward, vecPlanetUp, vecPlanetRight); Matrix4x4 mPlanetInverse = mPlanet; mPlanetInverse.InvertTR(); // Bring our current view angles into that local space Matrix4x4 mLocalRotation = mPlanetInverse * mGlobalRotation; EAngle angLocalRotation = mLocalRotation.GetAngles(); // Lock them so that the roll is 0 // I'm sure there's a way to do this without converting to euler but at this point I don't care. angLocalRotation.r = 0; Matrix4x4 mLockedLocalRotation; mLockedLocalRotation.SetAngles(angLocalRotation); // Bring it back out to global space Matrix4x4 mLockedRotation = mPlanet * mLockedLocalRotation; // Only use the changed r value to avoid floating point crap EAngle angNewLockedRotation = GetGlobalAngles(); EAngle angOverloadRotation = mLockedRotation.GetAngles(); // Lerp our way there float flTimeToLocked = 1; if (GameServer()->GetGameTime() - m_flLastEnteredAtmosphere > flTimeToLocked) angNewLockedRotation.r = angOverloadRotation.r; else angNewLockedRotation.r = RemapValClamped(SLerp(GameServer()->GetGameTime() - m_flLastEnteredAtmosphere, 0.3f), 0, flTimeToLocked, m_flRollFromSpace, angOverloadRotation.r); SetGlobalAngles(angNewLockedRotation); }
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(); } } }