mirror of https://github.com/AxioDL/metaforce.git
Merge branch 'master' of ssh://git.axiodl.com:6431/AxioDL/urde
This commit is contained in:
commit
001d4ab7dc
|
@ -92,11 +92,7 @@ void CMapWorldInfo::SetIsMapped(TAreaId aid, bool mapped) {
|
||||||
|
|
||||||
bool CMapWorldInfo::IsWorldVisible(TAreaId aid) const { return x38_mapStationUsed || IsMapped(aid); }
|
bool CMapWorldInfo::IsWorldVisible(TAreaId aid) const { return x38_mapStationUsed || IsMapped(aid); }
|
||||||
|
|
||||||
bool CMapWorldInfo::IsAreaVisible(TAreaId aid) const {
|
bool CMapWorldInfo::IsAreaVisible(TAreaId aid) const { return IsAreaVisted(aid) || IsMapped(aid); }
|
||||||
if (IsAreaVisted(aid) || IsMapped(aid))
|
|
||||||
return true;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CMapWorldInfo::IsAnythingSet() const {
|
bool CMapWorldInfo::IsAnythingSet() const {
|
||||||
for (int i = 0; i < x0_visitedAreasAllocated; ++i)
|
for (int i = 0; i < x0_visitedAreasAllocated; ++i)
|
||||||
|
|
|
@ -623,6 +623,7 @@ void CMain::Init(const hecl::Runtime::FileStoreManager& storeMgr, hecl::CVarMana
|
||||||
m_mainWindow = window;
|
m_mainWindow = window;
|
||||||
m_cvarMgr = cvarMgr;
|
m_cvarMgr = cvarMgr;
|
||||||
m_console = std::make_unique<hecl::Console>(m_cvarMgr);
|
m_console = std::make_unique<hecl::Console>(m_cvarMgr);
|
||||||
|
m_console->init(window);
|
||||||
m_console->registerCommand("Quit"sv, "Quits the game immediately"sv, ""sv,
|
m_console->registerCommand("Quit"sv, "Quits the game immediately"sv, ""sv,
|
||||||
std::bind(&CMain::quit, this, std::placeholders::_1, std::placeholders::_2));
|
std::bind(&CMain::quit, this, std::placeholders::_1, std::placeholders::_2));
|
||||||
m_console->registerCommand("Give"sv, "Gives the player the specified item, maxing it out"sv, ""sv,
|
m_console->registerCommand("Give"sv, "Gives the player the specified item, maxing it out"sv, ""sv,
|
||||||
|
|
|
@ -90,6 +90,120 @@ void CFireFlea::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateM
|
||||||
bool CFireFlea::InPosition(CStateManager& mgr, float dt) {
|
bool CFireFlea::InPosition(CStateManager& mgr, float dt) {
|
||||||
if (x2dc_destObj == kInvalidUniqueId)
|
if (x2dc_destObj == kInvalidUniqueId)
|
||||||
return false;
|
return false;
|
||||||
return (xd80_ - GetTranslation()).magnitude() < 25.f;
|
return (xd80_targetPos - GetTranslation()).magnitude() < 25.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CFireFlea::HearShot(urde::CStateManager& mgr, float arg) {
|
||||||
|
x570_nearList.clear();
|
||||||
|
mgr.BuildNearList(x570_nearList, zeus::CAABox(GetTranslation() - 10.f, GetTranslation() + 10.f),
|
||||||
|
CMaterialFilter::MakeInclude({EMaterialTypes::Projectile}), nullptr);
|
||||||
|
|
||||||
|
return !x570_nearList.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CFireFlea::TargetPatrol(CStateManager& mgr, EStateMsg msg, float arg) {
|
||||||
|
if (msg == EStateMsg::Activate) {
|
||||||
|
CPatterned::Patrol(mgr, msg, arg);
|
||||||
|
UpdateDest(mgr);
|
||||||
|
xd80_targetPos = x2e0_destPos;
|
||||||
|
} else if (msg == EStateMsg::Update) {
|
||||||
|
if (auto* pathFind = GetSearchPath()) {
|
||||||
|
if (pathFind->GetResult() != CPathFindSearch::EResult::Success) {
|
||||||
|
zeus::CVector3f closestPoint = zeus::CVector3f::skZero;
|
||||||
|
if (pathFind->FindClosestReachablePoint(GetTranslation(), closestPoint) == CPathFindSearch::EResult::Success) {
|
||||||
|
zeus::CVector3f delta = FindSafeRoute(mgr, x45c_steeringBehaviors.Arrival(*this, xd80_targetPos, 5.f));
|
||||||
|
x450_bodyController->GetCommandMgr().DeliverCmd(CBCLocomotionCmd(delta, {}, 1.f));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
PathFind(mgr, msg, arg);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
x450_bodyController->GetCommandMgr().DeliverCmd(
|
||||||
|
CBCLocomotionCmd(x45c_steeringBehaviors.Arrival(*this, xd80_targetPos, 5.f), {}, 1.f));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
zeus::CVector3f CFireFlea::FindSafeRoute(CStateManager& mgr, const zeus::CVector3f& forward) {
|
||||||
|
float mag = forward.magnitude();
|
||||||
|
if (mag > 0.f) {
|
||||||
|
CRayCastResult res = mgr.RayStaticIntersection(GetTranslation(), forward.normalized(), 1.f,
|
||||||
|
CMaterialFilter::MakeInclude({EMaterialTypes::Solid}));
|
||||||
|
if (res.IsValid() || CheckNearWater(mgr, forward.normalized())) {
|
||||||
|
zeus::CVector3f right = forward.normalized().cross(zeus::CVector3f::skUp).normalized();
|
||||||
|
CRayCastResult res1 = mgr.RayStaticIntersection(GetTranslation(), right, 1.f,
|
||||||
|
CMaterialFilter::MakeInclude({EMaterialTypes::Solid}));
|
||||||
|
if (res1.IsValid()) {
|
||||||
|
zeus::CVector3f left = -right;
|
||||||
|
CRayCastResult res2 = mgr.RayStaticIntersection(GetTranslation(), left, 1.f,
|
||||||
|
CMaterialFilter::MakeInclude({EMaterialTypes::Solid}));
|
||||||
|
if (res2.IsValid()) {
|
||||||
|
zeus::CVector3f up = right.cross(forward.normalized());
|
||||||
|
CRayCastResult res3 = mgr.RayStaticIntersection(GetTranslation(), up, 1.f,
|
||||||
|
CMaterialFilter::MakeInclude({EMaterialTypes::Solid}));
|
||||||
|
if (res3.IsValid()) {
|
||||||
|
zeus::CVector3f down = -up;
|
||||||
|
CRayCastResult res4 = mgr.RayStaticIntersection(GetTranslation(), down, 1.f,
|
||||||
|
CMaterialFilter::MakeInclude({EMaterialTypes::Solid}));
|
||||||
|
if (res4.IsValid()) {
|
||||||
|
return mag * down;
|
||||||
|
} else {
|
||||||
|
return -forward;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return mag * up;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return mag * left;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return mag * right;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return forward;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CFireFlea::CheckNearWater(const CStateManager& mgr, const zeus::CVector3f& dir) {
|
||||||
|
rstl::reserved_vector<TUniqueId, 1024> nearList;
|
||||||
|
mgr.BuildNearList(nearList, GetTranslation(), dir, 2.f, CMaterialFilter::skPassEverything, nullptr);
|
||||||
|
|
||||||
|
for (TUniqueId id : nearList) {
|
||||||
|
if (TCastToConstPtr<CScriptWater> water = mgr.GetObjectById(id))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CFireFlea::Patrol(CStateManager& mgr, EStateMsg msg, float arg) {
|
||||||
|
if (!zeus::close_enough(x310_moveVec, {}))
|
||||||
|
x310_moveVec.normalize();
|
||||||
|
|
||||||
|
x310_moveVec = FindSafeRoute(mgr, x310_moveVec);
|
||||||
|
CPatterned::Patrol(mgr, msg, arg);
|
||||||
|
if (x2d8_patrolState == EPatrolState::Done)
|
||||||
|
mgr.FreeScriptObject(GetUniqueId());
|
||||||
|
}
|
||||||
|
|
||||||
|
void CFireFlea::Flee(CStateManager& mgr, EStateMsg msg, float) {
|
||||||
|
if (msg == EStateMsg::Activate) {
|
||||||
|
x450_bodyController->SetLocomotionType(pas::ELocomotionType::Lurk);
|
||||||
|
} else if (msg == EStateMsg::Update) {
|
||||||
|
if (x570_nearList.empty()) {
|
||||||
|
x450_bodyController->GetCommandMgr().DeliverCmd(CBCLocomotionCmd(FindSafeRoute(mgr, xd74_), {}, 1.f));
|
||||||
|
} else {
|
||||||
|
for (TUniqueId id : x570_nearList) {
|
||||||
|
if (const CActor* act = static_cast<const CActor*>(mgr.GetObjectById(id))) {
|
||||||
|
zeus::CVector3f fleeDirection = x45c_steeringBehaviors.Flee(*this, act->GetTranslation());
|
||||||
|
x450_bodyController->GetCommandMgr().DeliverCmd(CBCLocomotionCmd(FindSafeRoute(mgr, fleeDirection), {}, 1.f));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (msg == EStateMsg::Deactivate) {
|
||||||
|
x450_bodyController->SetLocomotionType(pas::ELocomotionType::Relaxed);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} // namespace urde::MP1
|
} // namespace urde::MP1
|
|
@ -24,13 +24,15 @@ class CFireFlea : public CPatterned {
|
||||||
};
|
};
|
||||||
float x568_ = 1.f;
|
float x568_ = 1.f;
|
||||||
float x56c_;
|
float x56c_;
|
||||||
u32 x570_ = 0;
|
rstl::reserved_vector<TUniqueId, 1024> x570_nearList;
|
||||||
float xe64_;
|
float xe64_;
|
||||||
zeus::CVector3f xd74_;
|
zeus::CVector3f xd74_;
|
||||||
zeus::CVector3f xd80_;
|
zeus::CVector3f xd80_targetPos;
|
||||||
CPathFindSearch xd8c_pathFind;
|
CPathFindSearch xd8c_pathFind;
|
||||||
|
|
||||||
static s32 sLightIdx;
|
static s32 sLightIdx;
|
||||||
|
zeus::CVector3f FindSafeRoute(CStateManager& mgr, const zeus::CVector3f& forward);
|
||||||
|
bool CheckNearWater(const CStateManager&, const zeus::CVector3f& dir);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DEFINE_PATTERNED(FireFlea)
|
DEFINE_PATTERNED(FireFlea)
|
||||||
|
@ -43,6 +45,10 @@ public:
|
||||||
void Dead(CStateManager&, EStateMsg msg, float dt);
|
void Dead(CStateManager&, EStateMsg msg, float dt);
|
||||||
bool Delay(CStateManager&, float arg);
|
bool Delay(CStateManager&, float arg);
|
||||||
bool InPosition(CStateManager& mgr, float dt);
|
bool InPosition(CStateManager& mgr, float dt);
|
||||||
|
bool HearShot(CStateManager&, float);
|
||||||
|
void TargetPatrol(CStateManager&, EStateMsg, float);
|
||||||
|
void Patrol(CStateManager&, EStateMsg, float);
|
||||||
|
void Flee(CStateManager&, EStateMsg, float);
|
||||||
CPathFindSearch* GetSearchPath() { return &xd8c_pathFind; }
|
CPathFindSearch* GetSearchPath() { return &xd8c_pathFind; }
|
||||||
};
|
};
|
||||||
} // namespace urde::MP1
|
} // namespace urde::MP1
|
|
@ -29,6 +29,7 @@ set(MP1_WORLD_SOURCES
|
||||||
CRidley.hpp CRidley.cpp
|
CRidley.hpp CRidley.cpp
|
||||||
CPuddleToadGamma.hpp CPuddleToadGamma.cpp
|
CPuddleToadGamma.hpp CPuddleToadGamma.cpp
|
||||||
CFlaahgraProjectile.hpp CFlaahgraProjectile.cpp
|
CFlaahgraProjectile.hpp CFlaahgraProjectile.cpp
|
||||||
CSpankWeed.hpp CSpankWeed.cpp)
|
CSpankWeed.hpp CSpankWeed.cpp
|
||||||
|
CPuddleSpore.hpp CPuddleSpore.cpp)
|
||||||
|
|
||||||
runtime_add_list(World MP1_WORLD_SOURCES)
|
runtime_add_list(World MP1_WORLD_SOURCES)
|
||||||
|
|
|
@ -0,0 +1,312 @@
|
||||||
|
#include "CPuddleSpore.hpp"
|
||||||
|
#include "Collision/CGameCollision.hpp"
|
||||||
|
#include "Weapon/CEnergyProjectile.hpp"
|
||||||
|
#include "Weapon/CGameProjectile.hpp"
|
||||||
|
#include "World/CPatternedInfo.hpp"
|
||||||
|
#include "World/CPlayer.hpp"
|
||||||
|
#include "World/CScriptWater.hpp"
|
||||||
|
#include "CStateManager.hpp"
|
||||||
|
#include "GameGlobalObjects.hpp"
|
||||||
|
#include "CSimplePool.hpp"
|
||||||
|
#include "TCastTo.hpp"
|
||||||
|
|
||||||
|
namespace urde::MP1 {
|
||||||
|
const std::string_view CPuddleSpore::kEyeLocators[16] = {
|
||||||
|
"Glow_1_LCTR"sv,
|
||||||
|
"Glow_2_LCTR"sv,
|
||||||
|
"Glow_3_LCTR"sv,
|
||||||
|
"Glow_4_LCTR"sv,
|
||||||
|
"Glow_5_LCTR"sv,
|
||||||
|
"Glow_6_LCTR"sv,
|
||||||
|
"Glow_7_LCTR"sv,
|
||||||
|
"Glow_8_LCTR"sv,
|
||||||
|
"Glow_9_LCTR"sv,
|
||||||
|
"Glow_10_LCTR"sv,
|
||||||
|
"Glow_11_LCTR"sv,
|
||||||
|
"Glow_12_LCTR"sv,
|
||||||
|
"Glow_13_LCTR"sv,
|
||||||
|
"Glow_14_LCTR"sv,
|
||||||
|
"Glow_15_LCTR"sv,
|
||||||
|
"Glow_16_LCTR"sv,
|
||||||
|
};
|
||||||
|
CPuddleSpore::CPuddleSpore(TUniqueId uid, std::string_view name, EFlavorType flavor, const CEntityInfo& info,
|
||||||
|
const zeus::CTransform& xf, CModelData&& mData, const CPatternedInfo& pInfo,
|
||||||
|
EColliderType colType, CAssetId glowFx, float f1, float f2, float f3, float f4, float f5,
|
||||||
|
const CActorParameters& actParms, CAssetId weapon, const CDamageInfo& dInfo)
|
||||||
|
: CPatterned(ECharacter::PuddleSpore, uid, name, flavor, info, xf, std::move(mData), pInfo, EMovementType::Flyer,
|
||||||
|
colType, EBodyType::Restricted, actParms, EKnockBackVariant::Medium)
|
||||||
|
, x570_(f1)
|
||||||
|
, x574_(f2)
|
||||||
|
, x578_(f3)
|
||||||
|
, x57c_(f4)
|
||||||
|
, x580_(f5)
|
||||||
|
, x584_bodyOrigin(pInfo.GetBodyOrigin())
|
||||||
|
, x590_halfExtent(pInfo.GetHalfExtent())
|
||||||
|
, x594_height(pInfo.GetHeight())
|
||||||
|
, x5a0_(CalculateBoundingBox(), GetMaterialList())
|
||||||
|
, x5ec_projectileInfo(weapon, dInfo)
|
||||||
|
, x5d0_(g_SimplePool->GetObj({SBIG('PART'), glowFx}))
|
||||||
|
, x614_24(false)
|
||||||
|
, x614_25(false) {
|
||||||
|
x5dc_elemGens.reserve(kEyeCount);
|
||||||
|
for (u32 i = 0; i < kEyeCount; ++i)
|
||||||
|
x5dc_elemGens.emplace_back(new CElementGen(x5d0_));
|
||||||
|
const_cast<TToken<CWeaponDescription>*>(&x5ec_projectileInfo.Token())->Lock();
|
||||||
|
x460_knockBackController.SetAutoResetImpulse(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
zeus::CAABox CPuddleSpore::CalculateBoundingBox() const {
|
||||||
|
return {((zeus::CVector3f(-x590_halfExtent, -x590_halfExtent, x598_) + x584_bodyOrigin) * 0.5f) +
|
||||||
|
(GetBaseBoundingBox().min * 0.95f),
|
||||||
|
((zeus::CVector3f(x590_halfExtent, x590_halfExtent, (x594_height * x59c_) + x598_) + x584_bodyOrigin) * 0.5f) +
|
||||||
|
(GetBaseBoundingBox().max * 0.95f)};
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPuddleSpore::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) {
|
||||||
|
if (msg == EScriptObjectMessage::InvulnDamage)
|
||||||
|
return;
|
||||||
|
if (msg == EScriptObjectMessage::Registered)
|
||||||
|
x450_bodyController->Activate(mgr);
|
||||||
|
|
||||||
|
CPatterned::AcceptScriptMsg(msg, uid, mgr);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CPuddleSpore::HitShell(const zeus::CVector3f& point) const {
|
||||||
|
if (x5c8_ != 1)
|
||||||
|
return true;
|
||||||
|
float distance = GetTransform().upVector().dot(zeus::CUnitVector3f(point - GetBoundingBox().center()));
|
||||||
|
return (distance <= -0.5f || distance >= 0.5f);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPuddleSpore::KnockPlayer(CStateManager&, float) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPuddleSpore::UpdateBoundingState(const zeus::CAABox& box, CStateManager& mgr, float dt) {
|
||||||
|
SetBoundingBox(box);
|
||||||
|
x5a0_ = CCollidableAABox(box, x68_material);
|
||||||
|
zeus::CAABox plBox;
|
||||||
|
CPlayer& player = mgr.GetPlayer();
|
||||||
|
zeus::CAABox selfBox = GetBoundingBox();
|
||||||
|
if (player.GetMorphballTransitionState() == CPlayer::EPlayerMorphBallState::Morphed) {
|
||||||
|
const float ballRad = player.GetMorphBall()->GetBallRadius();
|
||||||
|
zeus::CVector3f ballOffset = (player.GetTranslation() + zeus::CVector3f{0.f, 0.f, ballRad});
|
||||||
|
plBox = zeus::CAABox(ballOffset - ballRad, ballOffset + ballRad);
|
||||||
|
} else {
|
||||||
|
plBox = player.GetBoundingBox();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (selfBox.intersects(plBox)) {
|
||||||
|
float bias = (x5c8_ == 2 ? 0.001f : -0.0001f) + (selfBox.max.z() - plBox.min.z());
|
||||||
|
if (bias > 0.f && selfBox.max.z() < plBox.max.z()) {
|
||||||
|
bool hadPlayerMat = player.GetMaterialList().HasMaterial(EMaterialTypes::Player);
|
||||||
|
if (hadPlayerMat)
|
||||||
|
player.RemoveMaterial(EMaterialTypes::GroundCollider, mgr);
|
||||||
|
player.RemoveMaterial(EMaterialTypes::Player, mgr);
|
||||||
|
CPhysicsState state = player.GetPhysicsState();
|
||||||
|
player.MoveToOR(bias * zeus::CVector3f{0.f, 0.f, 1.f}, dt);
|
||||||
|
CGameCollision::Move(mgr, player, dt, nullptr);
|
||||||
|
state.SetTranslation(player.GetTranslation());
|
||||||
|
player.SetPhysicsState(state);
|
||||||
|
if (hadPlayerMat)
|
||||||
|
player.AddMaterial(EMaterialTypes::GroundCollider, mgr);
|
||||||
|
player.AddMaterial(EMaterialTypes::Player, mgr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPuddleSpore::PreThink(float dt, CStateManager& mgr) {
|
||||||
|
if (x5c8_ == 2)
|
||||||
|
AddMaterial(EMaterialTypes::SolidCharacter, mgr);
|
||||||
|
else
|
||||||
|
RemoveMaterial(EMaterialTypes::SolidCharacter, mgr);
|
||||||
|
|
||||||
|
UpdateBoundingState(CalculateBoundingBox(), mgr, dt);
|
||||||
|
CPatterned::PreThink(dt, mgr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPuddleSpore::Think(float dt, CStateManager& mgr) {
|
||||||
|
if (x614_25)
|
||||||
|
x56c_ += dt;
|
||||||
|
if (x614_24)
|
||||||
|
x568_ += dt;
|
||||||
|
HealthInfo(mgr)->SetHP(1000000.0f);
|
||||||
|
float t = (x56c_ / x570_) - 1.f >= -0.f ? 1.f : x56c_ / x570_;
|
||||||
|
zeus::CColor modColor = zeus::CColor::lerp(zeus::CColor::skWhite, zeus::CColor(1.f, 1.f, 1.f, 0.f), t);
|
||||||
|
for (u32 i = 0 ; i < kEyeCount ; ++i) {
|
||||||
|
const auto& elemGen = x5dc_elemGens[i];
|
||||||
|
elemGen->SetModulationColor(modColor);
|
||||||
|
elemGen->SetTranslation(GetLctrTransform(kEyeLocators[i]).origin);
|
||||||
|
elemGen->Update(dt);
|
||||||
|
}
|
||||||
|
|
||||||
|
CPatterned::Think(dt, mgr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPuddleSpore::Render(const CStateManager& mgr) const {
|
||||||
|
CPatterned::Render(mgr);
|
||||||
|
if (x56c_ > 0.01f) {
|
||||||
|
for (const auto& elemGen : x5dc_elemGens)
|
||||||
|
elemGen->Render(GetActorLights());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPuddleSpore::Touch(CActor& act, CStateManager& mgr) {
|
||||||
|
if (!x400_25_alive)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (TCastToPtr<CGameProjectile> proj = act) {
|
||||||
|
if (proj->GetOwnerId() == mgr.GetPlayer().GetUniqueId())
|
||||||
|
x400_24_hitByPlayerProjectile = HitShell(proj->GetTranslation());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPuddleSpore::FluidFXThink(EFluidState fState, CScriptWater& water, CStateManager& mgr) {
|
||||||
|
if (fState != EFluidState::InFluid)
|
||||||
|
return;
|
||||||
|
|
||||||
|
CFluidPlaneManager* planeManager = mgr.GetFluidPlaneManager();
|
||||||
|
if (planeManager->GetLastRippleDeltaTime(GetUniqueId()) >= 2.9f) {
|
||||||
|
zeus::CVector3f point = GetTranslation();
|
||||||
|
point.z() = float(water.GetTriggerBoundsWR().max.z());
|
||||||
|
water.GetFluidPlane().AddRipple(2.f, GetUniqueId(), point, water, mgr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPuddleSpore::DoUserAnimEvent(CStateManager& mgr, const CInt32POINode& node, EUserEventType type, float dt) {
|
||||||
|
if (type == EUserEventType::Projectile) {
|
||||||
|
CProjectileInfo* projInfo = GetProjectileInfo();
|
||||||
|
if (projInfo->Token() && projInfo->Token().IsLocked() &&
|
||||||
|
mgr.CanCreateProjectile(GetUniqueId(), EWeaponType::AI, 16)) {
|
||||||
|
mgr.AddObject(new CEnergyProjectile(true, projInfo->Token(), EWeaponType::AI,
|
||||||
|
GetLctrTransform(node.GetLocatorName()), EMaterialTypes::Character,
|
||||||
|
projInfo->GetDamage(), mgr.AllocateUniqueId(), GetAreaIdAlways(),
|
||||||
|
GetUniqueId(), kInvalidUniqueId, EProjectileAttrib::None, false,
|
||||||
|
zeus::CVector3f::skOne, {}, 0xFFFF, false));
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
CPatterned::DoUserAnimEvent(mgr, node, type, dt);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CPuddleSpore::ShouldTurn(CStateManager& mgr, float) {
|
||||||
|
zeus::CAABox plBox = mgr.GetPlayer().GetBoundingBox();
|
||||||
|
zeus::CAABox selfBox = GetBoundingBox();
|
||||||
|
|
||||||
|
if (plBox.max.z() >= selfBox.min.z() + selfBox.max.z() * 0.5f ||
|
||||||
|
plBox.max.x() < selfBox.min.x() ||
|
||||||
|
plBox.max.y() < selfBox.min.y() ||
|
||||||
|
selfBox.max.x() < plBox.min.y() ||
|
||||||
|
selfBox.max.y() < plBox.min.y() ||
|
||||||
|
x450_bodyController->GetBodyStateInfo().GetCurrentStateId() != pas::EAnimationState::Getup)
|
||||||
|
return x568_ >= x578_;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPuddleSpore::InActive(CStateManager&, EStateMsg msg, float) {
|
||||||
|
if (msg == EStateMsg::Activate) {
|
||||||
|
x450_bodyController->SetLocomotionType(pas::ELocomotionType::Relaxed);
|
||||||
|
x56c_ = 0.f;
|
||||||
|
x598_ = -1.f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPuddleSpore::Active(CStateManager&, EStateMsg msg, float) {
|
||||||
|
if (msg == EStateMsg::Activate) {
|
||||||
|
x450_bodyController->SetLocomotionType(pas::ELocomotionType::Lurk);
|
||||||
|
x568_ = 0.f;
|
||||||
|
x56c_ = 0.f;
|
||||||
|
x598_ = 0.f;
|
||||||
|
x614_24 = true;
|
||||||
|
x614_25 = true;
|
||||||
|
} else if (msg == EStateMsg::Deactivate) {
|
||||||
|
x614_24 = false;
|
||||||
|
x614_25 = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPuddleSpore::Run(CStateManager& mgr, EStateMsg msg, float) {
|
||||||
|
if (msg == EStateMsg::Activate) {
|
||||||
|
x5c8_ = 1;
|
||||||
|
x5cc_ = 0;
|
||||||
|
x568_ = 0.f;
|
||||||
|
x614_24 = false;
|
||||||
|
x598_ = 0.f;
|
||||||
|
x59c_ = 1.5f;
|
||||||
|
} else if (msg == EStateMsg::Update) {
|
||||||
|
if (x5cc_ == 0) {
|
||||||
|
if (x450_bodyController->GetBodyStateInfo().GetCurrentStateId() == pas::EAnimationState::LoopReaction) {
|
||||||
|
x5cc_ = 1;
|
||||||
|
x614_24 = true;
|
||||||
|
} else {
|
||||||
|
x450_bodyController->GetCommandMgr().DeliverCmd(CBCLoopReactionCmd(pas::EReactionType::Zero));
|
||||||
|
}
|
||||||
|
} else if (x5cc_ == 1 &&
|
||||||
|
x450_bodyController->GetBodyStateInfo().GetCurrentStateId() == pas::EAnimationState::LoopReaction) {
|
||||||
|
x5cc_ = 2;
|
||||||
|
}
|
||||||
|
} else if (msg == EStateMsg::Deactivate) {
|
||||||
|
x450_bodyController->GetCommandMgr().DeliverCmd(CBodyStateCmd(EBodyStateCmd::ExitState));
|
||||||
|
x5c8_ = 0;
|
||||||
|
x59c_ = 1.f;
|
||||||
|
x614_24 = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPuddleSpore::TurnAround(CStateManager& mgr, EStateMsg msg, float) {
|
||||||
|
if (msg == EStateMsg::Activate) {
|
||||||
|
x568_ = 0.f;
|
||||||
|
x56c_ = 0.f;
|
||||||
|
x400_24_hitByPlayerProjectile = false;
|
||||||
|
x598_ = -2.5f;
|
||||||
|
x5c8_ = 2;
|
||||||
|
x5cc_ = 0;
|
||||||
|
x614_24 = false;
|
||||||
|
} else if (msg == EStateMsg::Update) {
|
||||||
|
if (x5cc_ == 0) {
|
||||||
|
if (x450_bodyController->GetBodyStateInfo().GetCurrentStateId() == pas::EAnimationState::LieOnGround) {
|
||||||
|
x5cc_ = 1;
|
||||||
|
x614_24 = true;
|
||||||
|
} else {
|
||||||
|
x450_bodyController->GetCommandMgr().DeliverCmd(CBCKnockDownCmd({1.f, 0.f, 0.f}, pas::ESeverity::One));
|
||||||
|
}
|
||||||
|
} else if (x5cc_ == 1 && x450_bodyController->GetBodyStateInfo().GetCurrentStateId() == pas::EAnimationState::LieOnGround) {
|
||||||
|
x5cc_ = 2;
|
||||||
|
}
|
||||||
|
} else if (msg == EStateMsg::Deactivate) {
|
||||||
|
x614_24 = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPuddleSpore::GetUp(CStateManager& mgr, EStateMsg msg, float) {
|
||||||
|
if (msg == EStateMsg::Activate) {
|
||||||
|
x450_bodyController->GetCommandMgr().DeliverCmd(CBCGetupCmd(pas::EGetupType::Zero));
|
||||||
|
KnockPlayer(mgr, x580_);
|
||||||
|
x56c_ = 0.f;
|
||||||
|
x598_ = -1.f;
|
||||||
|
x5cc_ = 0;
|
||||||
|
} else if (msg == EStateMsg::Update) {
|
||||||
|
KnockPlayer(mgr, x580_ * 0.25f);
|
||||||
|
if (x5cc_ == 0) {
|
||||||
|
x450_bodyController->GetCommandMgr().DeliverCmd(CBCGetupCmd(pas::EGetupType::Zero));
|
||||||
|
if (x450_bodyController->GetBodyStateInfo().GetCurrentStateId() == pas::EAnimationState::Getup)
|
||||||
|
x5cc_ = 1;
|
||||||
|
} else if (x5cc_ == 1 && x450_bodyController->GetBodyStateInfo().GetCurrentStateId() != pas::EAnimationState::Getup) {
|
||||||
|
x5cc_ = 1;
|
||||||
|
}
|
||||||
|
} else if (msg == EStateMsg::Deactivate) {
|
||||||
|
x5c8_ = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPuddleSpore::Attack(CStateManager& mgr, EStateMsg msg, float) {
|
||||||
|
if (msg == EStateMsg::Activate) {
|
||||||
|
x32c_animState = EAnimState::One;
|
||||||
|
x598_ = 0.f;
|
||||||
|
} else if (msg == EStateMsg::Update) {
|
||||||
|
TryCommand(mgr, pas::EAnimationState::MeleeAttack, &CPatterned::TryMeleeAttack, 1);
|
||||||
|
} else if (msg == EStateMsg::Deactivate) {
|
||||||
|
x32c_animState = EAnimState::Zero;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,83 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "World/CPatterned.hpp"
|
||||||
|
#include "Weapon/CProjectileInfo.hpp"
|
||||||
|
#include "Particle/CElementGen.hpp"
|
||||||
|
|
||||||
|
namespace urde::MP1 {
|
||||||
|
class CPuddleSpore : public CPatterned {
|
||||||
|
static constexpr u32 kEyeCount = 16;
|
||||||
|
static const std::string_view kEyeLocators[16];
|
||||||
|
float x568_ = 0.f;
|
||||||
|
float x56c_ = 0.f;
|
||||||
|
float x570_;
|
||||||
|
float x574_;
|
||||||
|
float x578_;
|
||||||
|
float x57c_;
|
||||||
|
float x580_;
|
||||||
|
zeus::CVector3f x584_bodyOrigin;
|
||||||
|
float x590_halfExtent;
|
||||||
|
float x594_height;
|
||||||
|
float x598_ = 0.f;
|
||||||
|
float x59c_ = 1.f;
|
||||||
|
CCollidableAABox x5a0_;
|
||||||
|
u32 x5c8_ = 0;
|
||||||
|
u32 x5cc_ = 0;
|
||||||
|
TToken<CGenDescription> x5d0_;
|
||||||
|
std::vector<std::unique_ptr<CElementGen>> x5dc_elemGens; // originally a vector of CElementGen
|
||||||
|
CProjectileInfo x5ec_projectileInfo;
|
||||||
|
bool x614_24 : 1;
|
||||||
|
bool x614_25 : 1;
|
||||||
|
|
||||||
|
bool HitShell(const zeus::CVector3f& ) const;
|
||||||
|
void KnockPlayer(CStateManager&, float);
|
||||||
|
void UpdateBoundingState(const zeus::CAABox&, CStateManager&, float);
|
||||||
|
public:
|
||||||
|
DEFINE_PATTERNED(PuddleSpore)
|
||||||
|
|
||||||
|
CPuddleSpore(TUniqueId, std::string_view, EFlavorType, const CEntityInfo&, const zeus::CTransform&,
|
||||||
|
CModelData&&, const CPatternedInfo&, EColliderType, CAssetId, float, float, float, float, float,
|
||||||
|
const CActorParameters&, CAssetId, const CDamageInfo&);
|
||||||
|
|
||||||
|
void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr);
|
||||||
|
void PreThink(float, CStateManager&);
|
||||||
|
void Think(float, CStateManager&);
|
||||||
|
void Render(const CStateManager&) const;
|
||||||
|
void Touch(CActor&, CStateManager&);
|
||||||
|
void FluidFXThink(EFluidState, CScriptWater&, CStateManager&);
|
||||||
|
void KnockBack(const zeus::CVector3f& dir, CStateManager& mgr, const CDamageInfo& dInfo, EKnockBackType type,
|
||||||
|
bool inDeferred, float dt)
|
||||||
|
{
|
||||||
|
if (x5c8_ == 1)
|
||||||
|
return;
|
||||||
|
CPatterned::KnockBack(dir, mgr, dInfo, type, inDeferred, dt);
|
||||||
|
}
|
||||||
|
EWeaponCollisionResponseTypes GetCollisionResponseType(const zeus::CVector3f& point, const zeus::CVector3f&,
|
||||||
|
const CWeaponMode&, EProjectileAttrib) const
|
||||||
|
{
|
||||||
|
return HitShell(point) ? EWeaponCollisionResponseTypes::Unknown84 : EWeaponCollisionResponseTypes::Unknown34;
|
||||||
|
}
|
||||||
|
void DoUserAnimEvent(CStateManager&, const CInt32POINode&, EUserEventType, float);
|
||||||
|
void CollidedWith(TUniqueId uid, const CCollisionInfoList& colList, CStateManager& mgr)
|
||||||
|
{
|
||||||
|
if (x5c8_ == 2)
|
||||||
|
return;
|
||||||
|
CPatterned::CollidedWith(uid, colList, mgr);
|
||||||
|
}
|
||||||
|
const CCollisionPrimitive* GetCollisionPrimitive() const { return &x5a0_; }
|
||||||
|
zeus::CAABox CalculateBoundingBox() const;
|
||||||
|
CProjectileInfo* GetProjectileInfo() { return &x5ec_projectileInfo; }
|
||||||
|
|
||||||
|
bool InAttackPosition(CStateManager&, float) { return x568_ >= x570_; }
|
||||||
|
bool ShouldAttack(CStateManager&, float) { return x568_ >= x574_; }
|
||||||
|
bool ShouldTurn(CStateManager&, float);
|
||||||
|
bool AnimOver(CStateManager&, float) { return x5cc_ == 2; }
|
||||||
|
|
||||||
|
void InActive(CStateManager&, EStateMsg, float);
|
||||||
|
void Active(CStateManager&, EStateMsg, float);
|
||||||
|
void Run(CStateManager&, EStateMsg, float);
|
||||||
|
void TurnAround(CStateManager&, EStateMsg, float);
|
||||||
|
void GetUp(CStateManager&, EStateMsg, float);
|
||||||
|
void Attack(CStateManager&, EStateMsg, float);
|
||||||
|
};
|
||||||
|
}
|
|
@ -795,7 +795,7 @@ void CElementGen::Render(const CActorLights* actorLights) {
|
||||||
CGraphics::DisableAllLights();
|
CGraphics::DisableAllLights();
|
||||||
|
|
||||||
for (std::unique_ptr<CParticleGen>& child : x290_activePartChildren)
|
for (std::unique_ptr<CParticleGen>& child : x290_activePartChildren)
|
||||||
child->Render();
|
child->Render(actorLights);
|
||||||
|
|
||||||
CParticleGlobals::SParticleSystem* prevSystem = CParticleGlobals::g_currentParticleSystem;
|
CParticleGlobals::SParticleSystem* prevSystem = CParticleGlobals::g_currentParticleSystem;
|
||||||
CParticleGlobals::SParticleSystem thisSystem{FOURCC('PART'), this};
|
CParticleGlobals::SParticleSystem thisSystem{FOURCC('PART'), this};
|
||||||
|
|
|
@ -836,6 +836,9 @@ void CPatterned::TryLoopReaction(CStateManager& mgr, int arg) {
|
||||||
void CPatterned::TryProjectileAttack(CStateManager&, int arg) {
|
void CPatterned::TryProjectileAttack(CStateManager&, int arg) {
|
||||||
x450_bodyController->GetCommandMgr().DeliverCmd(CBCProjectileAttackCmd(pas::ESeverity(arg), x2e0_destPos, false));
|
x450_bodyController->GetCommandMgr().DeliverCmd(CBCProjectileAttackCmd(pas::ESeverity(arg), x2e0_destPos, false));
|
||||||
}
|
}
|
||||||
|
void CPatterned::TryMeleeAttack(CStateManager& mgr, int arg) {
|
||||||
|
x450_bodyController->GetCommandMgr().DeliverCmd(CBCMeleeAttackCmd(pas::ESeverity(arg)));
|
||||||
|
}
|
||||||
|
|
||||||
void CPatterned::TryGenerate(CStateManager& mgr, int arg) {
|
void CPatterned::TryGenerate(CStateManager& mgr, int arg) {
|
||||||
x450_bodyController->GetCommandMgr().DeliverCmd(CBCGenerateCmd(pas::EGenerateType(arg), x2e0_destPos, true));
|
x450_bodyController->GetCommandMgr().DeliverCmd(CBCGenerateCmd(pas::EGenerateType(arg), x2e0_destPos, true));
|
||||||
|
@ -1635,4 +1638,6 @@ bool CPatterned::ApplyBoneTracking() const {
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
} // namespace urde
|
} // namespace urde
|
||||||
|
|
|
@ -318,6 +318,7 @@ public:
|
||||||
void TryCommand(CStateManager& mgr, pas::EAnimationState state, CPatternedTryFunc func, int arg);
|
void TryCommand(CStateManager& mgr, pas::EAnimationState state, CPatternedTryFunc func, int arg);
|
||||||
void TryLoopReaction(CStateManager& mgr, int arg);
|
void TryLoopReaction(CStateManager& mgr, int arg);
|
||||||
void TryProjectileAttack(CStateManager& mgr, int arg);
|
void TryProjectileAttack(CStateManager& mgr, int arg);
|
||||||
|
void TryMeleeAttack(CStateManager& mgr, int arg);
|
||||||
void TryGenerate(CStateManager& mgr, int arg);
|
void TryGenerate(CStateManager& mgr, int arg);
|
||||||
void TryJump(CStateManager& mgr, int arg);
|
void TryJump(CStateManager& mgr, int arg);
|
||||||
void TryMeleeAttack(CStateManager& mgr, int arg);
|
void TryMeleeAttack(CStateManager& mgr, int arg);
|
||||||
|
|
|
@ -61,6 +61,7 @@ public:
|
||||||
float GetHalfExtent() const { return xc4_halfExtent; }
|
float GetHalfExtent() const { return xc4_halfExtent; }
|
||||||
float GetHeight() const { return xc8_height; }
|
float GetHeight() const { return xc8_height; }
|
||||||
const CHealthInfo& GetHealthInfo() const { return x54_healthInfo; }
|
const CHealthInfo& GetHealthInfo() const { return x54_healthInfo; }
|
||||||
|
zeus::CVector3f GetBodyOrigin() const { return xcc_bodyOrigin; }
|
||||||
CAnimationParameters& GetAnimationParameters() { return xec_animParams; }
|
CAnimationParameters& GetAnimationParameters() { return xec_animParams; }
|
||||||
const CAnimationParameters& GetAnimationParameters() const { return xec_animParams; }
|
const CAnimationParameters& GetAnimationParameters() const { return xec_animParams; }
|
||||||
u32 GetPathfindingIndex() const { return x10c_pathfindingIndex; }
|
u32 GetPathfindingIndex() const { return x10c_pathfindingIndex; }
|
||||||
|
|
|
@ -48,6 +48,7 @@
|
||||||
#include "CScriptEffect.hpp"
|
#include "CScriptEffect.hpp"
|
||||||
#include "CScriptGenerator.hpp"
|
#include "CScriptGenerator.hpp"
|
||||||
#include "CScriptGrapplePoint.hpp"
|
#include "CScriptGrapplePoint.hpp"
|
||||||
|
#include "MP1/World/CPuddleSpore.hpp"
|
||||||
#include "CScriptHUDMemo.hpp"
|
#include "CScriptHUDMemo.hpp"
|
||||||
#include "CScriptMazeNode.hpp"
|
#include "CScriptMazeNode.hpp"
|
||||||
#include "CScriptMemoryRelay.hpp"
|
#include "CScriptMemoryRelay.hpp"
|
||||||
|
@ -1605,8 +1606,25 @@ CEntity* ScriptLoader::LoadPuddleSpore(CStateManager& mgr, CInputStream& in, int
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
CPatternedInfo pInfo(in, pair.second);
|
CPatternedInfo pInfo(in, pair.second);
|
||||||
|
CActorParameters actParms = LoadActorParameters(in);
|
||||||
|
bool b1 = in.readBool();
|
||||||
|
CAssetId w1(in);
|
||||||
|
float f1 = in.readFloatBig();
|
||||||
|
float f2 = in.readFloatBig();
|
||||||
|
float f3 = in.readFloatBig();
|
||||||
|
float f4 = in.readFloatBig();
|
||||||
|
float f5 = in.readFloatBig();
|
||||||
|
CAssetId w2(in);
|
||||||
|
CDamageInfo dInfo(in);
|
||||||
|
|
||||||
|
const CAnimationParameters& animParms = pInfo.GetAnimationParameters();
|
||||||
|
if (g_ResFactory->GetResourceTypeById(animParms.GetACSFile()) != SBIG('ANCS'))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
|
CModelData mData(
|
||||||
|
CAnimRes(animParms.GetACSFile(), animParms.GetCharacter(), scale, animParms.GetInitialAnimation(), true));
|
||||||
|
return new MP1::CPuddleSpore(mgr.AllocateUniqueId(), name, flavor, info, xf, std::move(mData), pInfo,
|
||||||
|
CPatterned::EColliderType(b1), w1, f1, f2, f3, f4, f5, actParms, w2, dInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
CEntity* ScriptLoader::LoadDebugCameraWaypoint(CStateManager& mgr, CInputStream& in, int propCount,
|
CEntity* ScriptLoader::LoadDebugCameraWaypoint(CStateManager& mgr, CInputStream& in, int propCount,
|
||||||
|
|
Loading…
Reference in New Issue