cs381/as6/components/GravityReceiverComponent.cpp

96 lines
2.7 KiB
C++

#include "components/GravityReceiverComponent.hpp"
#include "Entity.hpp"
#include "components/GravityWellComponent.hpp"
#include "components/NullZoneComponent.hpp"
#include "components/PhysicsComponent.hpp"
#include "components/StatsComponent.hpp"
#include "components/TransformComponent.hpp"
#include <algorithm>
#include <cmath>
void GravityReceiverComponent::Setup() {}
void GravityReceiverComponent::Update(float dt) {
if (!context || !context->probeEntity || entity != context->probeEntity) {
return;
}
if (!well && context->wellEntity) {
well = context->wellEntity;
}
if (!well) {
return;
}
auto myTransform = entity->GetComponent<TransformComponent>();
auto physics = entity->GetComponent<PhysicsComponent>();
auto wellTransform = well->GetComponent<TransformComponent>();
auto wellGravity = well->GetComponent<GravityWellComponent>();
if (!myTransform || !physics || !wellTransform || !wellGravity) {
return;
}
StatsComponent *statsPtr = nullptr;
if (context->statsEntity) {
auto stats = context->statsEntity->GetComponent<StatsComponent>();
if (stats) {
statsPtr = &stats->get();
}
}
if (!wellGravity->get().active) {
return;
}
if (statsPtr && statsPtr->value <= 0.0f) {
return;
}
inVoid = false;
if (context->entities) {
for (auto &other : *context->entities) {
if (!other || other.get() == entity) {
continue;
}
auto zone = other->GetComponent<NullZoneComponent>();
auto zoneTransform = other->GetComponent<TransformComponent>();
if (!zone || !zoneTransform) {
continue;
}
const float left = zoneTransform->get().x;
const float right = left + zone->get().width;
if (myTransform->get().x >= left && myTransform->get().x <= right) {
inVoid = true;
break;
}
}
}
if (inVoid) {
return;
}
const float dx = wellTransform->get().x - myTransform->get().x;
const float dy = wellTransform->get().y - myTransform->get().y;
const float dist = std::sqrt(dx * dx + dy * dy);
if (dist <= 0.0001f) {
return;
}
const float clampedDist = std::max(dist, wellGravity->get().minDist);
const float force = wellGravity->get().mass / (clampedDist * clampedDist);
const float nx = dx / dist;
const float ny = dy / dist;
physics->get().vx += nx * force * dt;
physics->get().vy += ny * force * dt;
if (statsPtr) {
statsPtr->Drain(statsPtr->drainRate * dt);
}
}
void GravityReceiverComponent::Cleanup() {}