mirror of https://github.com/AxioDL/metaforce.git
148 lines
5.1 KiB
C++
148 lines
5.1 KiB
C++
#include "CFlickerBat.hpp"
|
|
#include "CStateManager.hpp"
|
|
#include "Camera/CCameraManager.hpp"
|
|
#include "Camera/CGameCamera.hpp"
|
|
#include "Collision/CGameCollision.hpp"
|
|
#include "World/CPlayer.hpp"
|
|
#include "TCastTo.hpp"
|
|
|
|
namespace urde::MP1 {
|
|
|
|
CFlickerBat::CFlickerBat(TUniqueId uid, std::string_view name, CPatterned::EFlavorType flavor, const CEntityInfo& info,
|
|
const zeus::CTransform& xf, CModelData&& mData, const CPatternedInfo& pInfo,
|
|
EColliderType colType, bool b1, const CActorParameters& actParms, bool b2)
|
|
: CPatterned(ECharacter::FlickerBat, uid, name, flavor, info, xf, std::move(mData), pInfo, EMovementType::Flyer,
|
|
colType, EBodyType::Pitchable, actParms, EKnockBackVariant::Small)
|
|
, x580_24_(false)
|
|
, x580_25_heardShot(false)
|
|
, x580_26_(false)
|
|
, x580_27_(b2)
|
|
, x574_state(EFlickerBatState(b1)) {
|
|
|
|
SetupPlayerCollision(b1);
|
|
x3d8_xDamageThreshold = 0.f;
|
|
x402_27_noXrayModel = false;
|
|
}
|
|
|
|
void CFlickerBat::Accept(IVisitor& visitor) { visitor.Visit(this); }
|
|
|
|
void CFlickerBat::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) {
|
|
CPatterned::AcceptScriptMsg(msg, uid, mgr);
|
|
|
|
if (msg == EScriptObjectMessage::Registered) {
|
|
RemoveMaterial(EMaterialTypes::Solid, mgr);
|
|
/* TODO: Implement xf3c_ in CStateManager (skipping 801311B8 - 80131224) */
|
|
x450_bodyController->Activate(mgr);
|
|
x450_bodyController->BodyStateInfo().SetMaximumPitch(zeus::degToRad(60.f));
|
|
} else if (msg == EScriptObjectMessage::Deleted) {
|
|
/* sub80125D88(mgr.xf3c_, uid) */
|
|
}
|
|
}
|
|
|
|
void CFlickerBat::Think(float dt, CStateManager& mgr) {
|
|
if (!GetActive())
|
|
return;
|
|
|
|
x402_29_drawParticles = mgr.GetPlayerState()->GetActiveVisor(mgr) != CPlayerState::EPlayerVisor::XRay;
|
|
|
|
if (GetFlickerBatState() == EFlickerBatState::Two || GetFlickerBatState() == EFlickerBatState::Three) {
|
|
x578_ -= dt;
|
|
if (x578_ <= 0.f) {
|
|
if (GetFlickerBatState() == EFlickerBatState::Two)
|
|
SetFlickerBatState(EFlickerBatState::Zero, mgr);
|
|
else
|
|
SetFlickerBatState(EFlickerBatState::One, mgr);
|
|
}
|
|
}
|
|
|
|
CPatterned::Think(dt, mgr);
|
|
}
|
|
|
|
void CFlickerBat::Render(const CStateManager& mgr) const { CPatterned::Render(mgr); }
|
|
|
|
void CFlickerBat::Touch(CActor& act, CStateManager& mgr) { CPatterned::Touch(act, mgr); }
|
|
|
|
void CFlickerBat::DoUserAnimEvent(CStateManager& mgr, const CInt32POINode& node, EUserEventType type, float dt) {
|
|
CPatterned::DoUserAnimEvent(mgr, node, type, dt);
|
|
}
|
|
|
|
void CFlickerBat::Death(CStateManager& mgr, const zeus::CVector3f& direction, EScriptObjectState state) {
|
|
SetFlickerBatState(EFlickerBatState::Zero, mgr);
|
|
CPatterned::Death(mgr, direction, state);
|
|
}
|
|
|
|
bool CFlickerBat::CanBeShot(CStateManager& mgr, int) {
|
|
return (GetFlickerBatState() == EFlickerBatState::Zero || GetFlickerBatState() == EFlickerBatState::Two ||
|
|
mgr.GetPlayerState()->GetCurrentVisor() == CPlayerState::EPlayerVisor::XRay);
|
|
}
|
|
|
|
void CFlickerBat::Patrol(CStateManager& mgr, EStateMsg state, float dt) { CPatterned::Patrol(mgr, state, dt); }
|
|
|
|
void CFlickerBat::Attack(CStateManager&, EStateMsg, float) {}
|
|
|
|
void CFlickerBat::Shuffle(CStateManager&, EStateMsg, float) {}
|
|
|
|
void CFlickerBat::Taunt(CStateManager&, EStateMsg, float) {}
|
|
|
|
bool CFlickerBat::InPosition(CStateManager& mgr, float arg) {
|
|
return GetTransform().frontVector().dot(mgr.GetPlayer().GetAimPosition(mgr, 0.f) - GetTranslation()) > 0.f;
|
|
}
|
|
|
|
bool CFlickerBat::HearShot(CStateManager&, float) {
|
|
if (x580_25_heardShot) {
|
|
x580_25_heardShot = false;
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
void CFlickerBat::SetFlickerBatState(EFlickerBatState state, CStateManager& mgr) {
|
|
if (state == x574_state)
|
|
return;
|
|
|
|
FlickerBatStateChanged(state, mgr);
|
|
x574_state = state;
|
|
}
|
|
|
|
void CFlickerBat::FlickerBatStateChanged(EFlickerBatState state, CStateManager& mgr) {
|
|
if (state == EFlickerBatState::Zero) {
|
|
if (mgr.GetPlayerState()->GetCurrentVisor() != CPlayerState::EPlayerVisor::XRay)
|
|
CreateShadow(true);
|
|
|
|
AddMaterial(EMaterialTypes::Target, mgr);
|
|
} else if (state == EFlickerBatState::One) {
|
|
SetMuted(true);
|
|
RemoveMaterial(EMaterialTypes::Target, mgr);
|
|
} else if (state == EFlickerBatState::Two) {
|
|
if (mgr.GetPlayerState()->GetCurrentVisor() != CPlayerState::EPlayerVisor::XRay) {
|
|
CreateShadow(true);
|
|
SetMuted(false);
|
|
}
|
|
|
|
CheckStaticIntersection(mgr);
|
|
SetupPlayerCollision(true);
|
|
} else if (state == EFlickerBatState::Three) {
|
|
if (mgr.GetPlayerState()->GetCurrentVisor() != CPlayerState::EPlayerVisor::XRay)
|
|
CreateShadow(true);
|
|
|
|
CheckStaticIntersection(mgr);
|
|
SetupPlayerCollision(false);
|
|
}
|
|
}
|
|
|
|
void CFlickerBat::CheckStaticIntersection(CStateManager& mgr) {
|
|
if (!x580_27_) {
|
|
x580_26_ = false;
|
|
return;
|
|
}
|
|
|
|
zeus::CVector3f camPos = mgr.GetCameraManager()->GetCurrentCamera(mgr)->GetTranslation();
|
|
zeus::CVector3f diff = GetBoundingBox().center() - camPos;
|
|
float mag = diff.magnitude();
|
|
diff *= zeus::CVector3f(1.f / mag);
|
|
x580_26_ = CGameCollision::RayStaticIntersectionBool(mgr, camPos, diff, mag,
|
|
CMaterialFilter::MakeExclude({EMaterialTypes::SeeThrough}));
|
|
}
|
|
|
|
} // namespace urde::MP1
|