Initial CPuddleToadGamma imps

This commit is contained in:
Phillip Stephens 2018-11-30 16:44:33 -08:00
parent 7223231010
commit 9948532957
6 changed files with 439 additions and 10 deletions

View File

@ -111,7 +111,7 @@ public:
void Add(EMaterialTypes type)
{
x0_list |= (1ull << u32(type));
x0_list |= (1ull << u64(type));
}
void Add(const CMaterialList& l)
@ -121,7 +121,7 @@ public:
void Remove(EMaterialTypes type)
{
x0_list &= ~(1ull << u32(type));
x0_list &= ~(1ull << u64(type));
}
void Remove(const CMaterialList& other)
@ -131,7 +131,7 @@ public:
bool HasMaterial(EMaterialTypes type) const
{
return (x0_list & (1ull << u32(type))) != 0;
return (x0_list & (1ull << u64(type))) != 0;
}
bool SharesMaterials(const CMaterialList& other)

View File

@ -1,17 +1,360 @@
#include "CPuddleToadGamma.hpp"
#include "GameGlobalObjects.hpp"
#include "CSimplePool.hpp"
#include "CStateManager.hpp"
#include "World/CPlayer.hpp"
#include "Collision/CGameCollision.hpp"
#include "TCastTo.hpp"
namespace urde::MP1
{
const zeus::CVector3f CPuddleToadGamma::skBellyOffset(0.f, 0.1f, -.3f);
CPuddleToadGamma::CPuddleToadGamma(TUniqueId uid, std::string_view name, EFlavorType flavor, const CEntityInfo& info,
const zeus::CTransform& xf, CModelData&& mData, const CPatternedInfo& pInfo,
const CActorParameters& aParms, float f1, float f2, float f3,
const zeus::CVector3f& v1,
float f4, float f5, float f6, const CDamageInfo& dInfo1, const CDamageInfo& dInfo2)
: CPatterned(ECharacter::PuddleToad, uid, name, flavor, info, xf, std::move(mData), pInfo, EMovementType::Flyer,
EColliderType::Zero, EBodyType::Restricted, aParms, EKnockBackVariant::Large)
const zeus::CVector3f& v1, float f4, float f5, float f6, const CDamageInfo& dInfo1,
const CDamageInfo& dInfo2, CAssetId dcln)
: CPatterned(ECharacter::PuddleToad, uid, name, flavor, info, xf, std::move(mData), pInfo, EMovementType::Flyer,
EColliderType::Zero, EBodyType::Restricted, aParms, EKnockBackVariant::Large), x570_(dInfo1),
x58c_(dInfo2), x5a8_(f1), x5ac_(std::cos(zeus::degToRad(f2 * 0.5f))), x5b0_(f3), x5b4_(v1), x5c0_(f4), x5c4_(f5),
x5c8_(f6), x5e8_24_(false), x5e8_25_(false), x5e8_26_(false)
{
x401_26_disableMove = true;
x460_knockBackController.SetEnableBurn(false);
x460_knockBackController.SetEnableLaggedBurnDeath(false);
x460_knockBackController.SetEnableShock(false);
x460_knockBackController.SetX81_31(false);
SetMovable(false);
if (dcln.IsValid() && g_ResFactory->GetResourceTypeById(dcln) != 0)
{
TLockedToken<CCollidableOBBTreeGroupContainer> container = g_SimplePool->GetObj({FOURCC('DCLN'), dcln});
x5e4_collisionTreePrim.reset(new CCollidableOBBTreeGroup(container.GetObj(), GetMaterialList()));
}
}
void CPuddleToadGamma::SetSolid(CStateManager& mgr, bool solid)
{
if (solid)
{
AddMaterial(EMaterialTypes::Solid, mgr);
RemoveMaterial(EMaterialTypes::NonSolidDamageable, mgr);
} else
{
RemoveMaterial(EMaterialTypes::Solid, mgr);
AddMaterial(EMaterialTypes::NonSolidDamageable, mgr);
}
}
const CCollisionPrimitive* CPuddleToadGamma::GetCollisionPrimitive() const
{
if (!x5e4_collisionTreePrim)
return CPhysicsActor::GetCollisionPrimitive();
return x5e4_collisionTreePrim.get();
}
zeus::CTransform CPuddleToadGamma::GetPrimitiveTransform() const
{
zeus::CTransform xf = GetTransform();
xf.origin += GetPrimitiveOffset();
return xf;
}
void CPuddleToadGamma::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr)
{
CPatterned::AcceptScriptMsg(msg, uid, mgr);
if (msg == EScriptObjectMessage::Registered)
{
x450_bodyController->Activate(mgr);
zeus::CTransform bellyXf = GetLctrTransform(mBellyLocatorName);
zeus::CVector3f bellyOffset = GetTransform().rotate(skBellyOffset);
x5d8_ = x5cc_ = bellyXf.origin + bellyOffset;
RemoveMaterial(EMaterialTypes::Target, EMaterialTypes::Orbit, mgr);
AddMaterial(EMaterialTypes::Immovable, mgr);
AddMaterial(EMaterialTypes::SolidCharacter);
}
}
void CPuddleToadGamma::Think(float dt, CStateManager& mgr)
{
CPatterned::Think(dt, mgr);
if (x5e8_25_)
x56c_ += dt;
}
std::experimental::optional<zeus::CAABox> CPuddleToadGamma::GetTouchBounds() const
{
if (!GetActive())
return {};
return (x5e4_collisionTreePrim ? x5e4_collisionTreePrim->CalculateAABox(GetTransform()) : GetBoundingBox());
}
void CPuddleToadGamma::CenterPlayer(CStateManager& mgr, const zeus::CVector3f& pos, float dt)
{
zeus::CVector3f dir = (mgr.GetPlayer().GetTranslation() - pos).normalized();
mgr.GetPlayer().SetVelocityWR((1.f / (2.f * dt)) * dir);
}
const CDamageVulnerability* CPuddleToadGamma::GetDamageVulnerability(const zeus::CVector3f& pos,
const zeus::CVector3f& dir,
const CDamageInfo& dInfo) const
{
if (x5e8_24_ && (x5d8_ - pos).magSquared() < 4.f)
return CAi::GetDamageVulnerability();
return &CDamageVulnerability::ImmuneVulnerabilty();
}
void CPuddleToadGamma::DoUserAnimEvent(CStateManager& mgr, const CInt32POINode& node, EUserEventType type, float dt)
{
if (type == EUserEventType::Projectile)
{
ShootPlayer(mgr, x5c0_);
return;
}
CPatterned::DoUserAnimEvent(mgr, node, type, dt);
}
bool CPuddleToadGamma::SpotPlayer(CStateManager&, float arg)
{
return x56c_ >= x5c8_;
}
bool CPuddleToadGamma::ShouldAttack(CStateManager&, float)
{
return x56c_ >= x5c4_;
}
bool CPuddleToadGamma::LostInterest(CStateManager& mgr, float)
{
zeus::CAABox box = *GetTouchBounds();
zeus::CAABox plBox = mgr.GetPlayer().GetBoundingBox();
return !box.intersects(plBox);
}
void CPuddleToadGamma::ShootPlayer(CStateManager&, float)
{
}
bool CPuddleToadGamma::InAttackPosition(CStateManager& mgr, float)
{
return mgr.GetPlayer().GetMorphballTransitionState() == CPlayer::EPlayerMorphBallState::Morphed &&
PlayerInVortexArea(mgr);
}
static CMaterialFilter kSolidFilter = CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Solid},
{EMaterialTypes::Character,
EMaterialTypes::Player,
EMaterialTypes::ProjectilePassthrough});
bool CPuddleToadGamma::PlayerInVortexArea(const CStateManager& mgr)
{
CPlayer& player = mgr.GetPlayer();
zeus::CTransform xf = GetLctrTransform(mMouthLocatorName);
zeus::CVector3f playerOffset =
player.GetTranslation() + zeus::CVector3f{0.f, 0.f, player.GetMorphBall()->GetBallRadius()};
zeus::CVector3f rotatedOffset = GetTransform().rotate(zeus::CVector3f::skForward);
zeus::CVector3f vec1 = (playerOffset - (xf.origin - (1.f * rotatedOffset)));
float f31 = vec1.normalized().dot(rotatedOffset);
float f28 = vec1.magnitude();
float f26 = (player.GetTranslation() - (xf.origin - (4.f * rotatedOffset))).normalized().dot(rotatedOffset);
if (f28 > 2.f)
{
CRayCastResult result = mgr.RayStaticIntersection(vec1, 1.f / f28 * vec1,
f28 - player.GetMorphBall()->GetBallRadius(), kSolidFilter);
if (result.IsValid())
return false;
}
return (f28 < x5b0_ && f31 > 0.f && f26 > x5ac_);
}
void CPuddleToadGamma::InActive(CStateManager& mgr, EStateMsg msg, float)
{
if (msg == EStateMsg::Activate)
{
x450_bodyController->SetLocomotionType(pas::ELocomotionType::Relaxed);
SetSolid(mgr, true);
mgr.GetPlayer().Set_X590(true);
x330_stateMachineState.SetDelay(2.f);
}
}
void CPuddleToadGamma::Active(CStateManager& mgr, EStateMsg msg, float)
{
if (msg == EStateMsg::Activate)
{
x450_bodyController->SetLocomotionType(pas::ELocomotionType::Lurk);
zeus::CTransform xf = GetLctrTransform(mBellyLocatorName);
x5cc_ = xf.origin + GetTransform().rotate(skBellyOffset);
x56c_ = 0.f;
x5e8_25_ = true;
SetSolid(mgr, true);
mgr.GetPlayer().Set_X590(true);
} else if (msg == EStateMsg::Deactivate)
{
x5e8_25_ = false;
}
}
void CPuddleToadGamma::Suck(CStateManager& mgr, EStateMsg msg, float arg)
{
if (msg == EStateMsg::Activate)
{
SetSolid(mgr, false);
mgr.GetPlayer().Set_X590(false);
mgr.GetPlayer().GetMorphBall()->DisableHalfPipeStatus();
} else if (msg == EStateMsg::Update)
{
if (x568_ == 0)
{
if (x450_bodyController->GetBodyStateInfo().GetCurrentStateId() == pas::EAnimationState::LoopReaction)
{
x568_ = 1;
return;
}
x450_bodyController->GetCommandMgr().DeliverCmd(CBCLoopReactionCmd(pas::EReactionType::Zero));
} else if (x568_ == 1)
SuckPlayer(mgr, arg);
} else if (msg == EStateMsg::Deactivate)
{
x450_bodyController->GetCommandMgr().DeliverCmd(CBodyStateCmd(EBodyStateCmd::ExitState));
}
}
void CPuddleToadGamma::SuckPlayer(CStateManager& mgr, float arg)
{
CPlayer& player = mgr.GetPlayer();
if (player.GetMorphballTransitionState() != CPlayer::EPlayerMorphBallState::Morphed)
return;
zeus::CVector3f posDiff = player.GetTranslation() - x5cc_;
if (posDiff.magnitude() < 3.f)
{
player.Stop();
CenterPlayer(mgr, x5cc_, arg);
return;
}
float d = x5a8_ * (x5b0_ / (posDiff.magnitude() * posDiff.magnitude()));
zeus::CVector3f force = d * (player.GetMass() * -posDiff);
player.ApplyForceWR(force, zeus::CAxisAngle::sIdentity);
}
void CPuddleToadGamma::Attack(CStateManager& mgr, EStateMsg msg, float)
{
if (msg == EStateMsg::Activate)
{
mgr.GetPlayer().Stop();
mgr.GetPlayer().SetVelocityWR({});
x450_bodyController->GetCommandMgr().DeliverCmd(CBCMeleeAttackCmd(pas::ESeverity::One));
x5e8_26_ = false;
mgr.GetPlayer().GetMorphBall()->SetBombJumpState(CMorphBall::EBombJumpState::BombJumpDisabled);
} else if (msg == EStateMsg::Update)
{
if (!x5e8_26_)
{
zeus::CTransform xf = GetLctrTransform(mBellyLocatorName);
x5cc_ = xf.origin + GetTransform().rotate(skBellyOffset);
SetPlayerPosition(mgr, x5cc_);
} else if (LostInterest(mgr, 0.f))
SetSolid(mgr, true);
} else if (msg == EStateMsg::Deactivate)
{
SetSolid(mgr, true);
mgr.GetPlayer().Set_X590(true);
mgr.GetPlayer().GetMorphBall()->SetBombJumpState(CMorphBall::EBombJumpState::BombJumpAvailable);
x5e8_24_ = false;
}
}
void CPuddleToadGamma::SetPlayerPosition(CStateManager& mgr, const zeus::CVector3f& targetPos)
{
float preThinkDt = x500_preThinkDt;
CPlayer& player = mgr.GetPlayer();
player.Stop();
player.SetVelocityWR({});
bool hadPlayerMaterial = player.GetMaterialList().HasMaterial(EMaterialTypes::Player);
if (hadPlayerMaterial)
player.RemoveMaterial(EMaterialTypes::GroundCollider, mgr);
player.RemoveMaterial(EMaterialTypes::Player, mgr);
bool hadSolidMaterial = GetMaterialList().HasMaterial(EMaterialTypes::Solid);
if (hadSolidMaterial)
RemoveMaterial(EMaterialTypes::Solid, mgr);
CPhysicsState physState = player.GetPhysicsState();
player.Stop();
player.MoveToWR(targetPos, preThinkDt);
CGameCollision::Move(mgr, player, preThinkDt, nullptr);
physState.SetTranslation(player.GetTranslation());
player.SetPhysicsState(physState);
if (hadPlayerMaterial)
player.AddMaterial(EMaterialTypes::GroundCollider, mgr);
player.AddMaterial(EMaterialTypes::Player, mgr);
if (hadSolidMaterial)
AddMaterial(EMaterialTypes::Solid, mgr);
}
bool CPuddleToadGamma::Inside(CStateManager& mgr, float)
{
if (mgr.GetPlayer().GetMorphballTransitionState() != CPlayer::EPlayerMorphBallState::Morphed)
return false;
zeus::CVector3f posDiff = mgr.GetPlayer().GetTranslation() - x5cc_;
return posDiff.dot(GetTransform().frontVector()) <= 0.f &&
posDiff.magSquared() < 2.f;
}
void CPuddleToadGamma::Crouch(CStateManager& mgr, EStateMsg msg, float)
{
if (msg == EStateMsg::Activate)
{
x568_ = 0;
x56c_ = 0.f;
x5e8_25_ = true;
x5e8_24_ = true;
mgr.GetPlayer().Stop();
mgr.GetPlayer().SetVelocityWR({});
SendScriptMsgs(EScriptObjectState::Inside, mgr, EScriptObjectMessage::None);
if (!mgr.GetPlayer().AttachActorToPlayer(GetUniqueId(), false))
x56c_ = 100.f;
SetSolid(mgr, false);
mgr.GetPlayer().Set_X590(false);
mgr.GetPlayer().GetMorphBall()->DisableHalfPipeStatus();
SetSolid(mgr, false);
}
else if (msg == EStateMsg::Update)
{
zeus::CTransform xf = GetLctrTransform(mBellyLocatorName);
x5cc_ = xf.origin + GetTransform().rotate(skBellyOffset);
SetPlayerPosition(mgr, x5cc_);
if (x568_ == 0)
{
if (x450_bodyController->GetBodyStateInfo().GetCurrentStateId() == pas::EAnimationState::Locomotion)
x568_ = 1;
else
x450_bodyController->SetLocomotionType(pas::ELocomotionType::Crouch);
}
}
else if (msg == EStateMsg::Deactivate)
{
if (mgr.GetPlayer().GetAttachedActor() == GetUniqueId())
mgr.GetPlayer().DetachActorFromPlayer();
mgr.GetPlayer().Set_X590(true);
x5e8_25_ = false;
}
}
}

View File

@ -1,18 +1,74 @@
#pragma once
#include "World/CPatterned.hpp"
#include "Collision/CCollidableOBBTreeGroup.hpp"
namespace urde::MP1
{
class CPuddleToadGamma : public CPatterned
class CPuddleToadGamma final : public CPatterned
{
static constexpr std::string_view mMouthLocatorName = "MOUTH_LCTR_SDK"sv;
static constexpr std::string_view mBellyLocatorName = "SAMUS_POS_LCTR_SDK"sv;
static const zeus::CVector3f skBellyOffset;
u32 x568_ = 0;
float x56c_ = 0.f;
CDamageInfo x570_;
CDamageInfo x58c_;
float x5a8_;
float x5ac_;
float x5b0_;
zeus::CVector3f x5b4_;
float x5c0_;
float x5c4_;
float x5c8_;
zeus::CVector3f x5cc_;
zeus::CVector3f x5d8_;
std::unique_ptr<CCollidableOBBTreeGroup> x5e4_collisionTreePrim;
bool x5e8_24_ : 1;
bool x5e8_25_ : 1;
bool x5e8_26_ : 1;
void SetSolid(CStateManager&, bool);
static void CenterPlayer(CStateManager&, const zeus::CVector3f&, float);
void ShootPlayer(CStateManager&, float);
void SuckPlayer(CStateManager&, float);
bool PlayerInVortexArea(const CStateManager&);
void SetPlayerPosition(CStateManager&, const zeus::CVector3f&);
public:
DEFINE_PATTERNED(PuddleToad)
CPuddleToadGamma(TUniqueId uid, std::string_view name, EFlavorType flavor, const CEntityInfo& info,
const zeus::CTransform& xf, CModelData&& mData, const CPatternedInfo& pInfo,
const CActorParameters& aParms, float f1, float f2, float f3, const zeus::CVector3f& v1,
float f4, float f5, float f6, const CDamageInfo& dInfo1, const CDamageInfo& dInfo2);
float f4, float f5, float f6, const CDamageInfo& dInfo1, const CDamageInfo& dInfo2, CAssetId dcln);
void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&);
void Think(float dt, CStateManager& mgr);
void DoUserAnimEvent(CStateManager& mgr, const CInt32POINode& node, EUserEventType type, float dt);
std::experimental::optional<zeus::CAABox> GetTouchBounds() const;
const CDamageVulnerability*
GetDamageVulnerability(const zeus::CVector3f&, const zeus::CVector3f&, const CDamageInfo&) const;
const CDamageVulnerability* GetDamageVulnerability() const { return &CDamageVulnerability::ImmuneVulnerabilty(); }
const CCollisionPrimitive* GetCollisionPrimitive() const;
zeus::CTransform GetPrimitiveTransform() const;
void InActive(CStateManager&, EStateMsg, float);
void Active(CStateManager&, EStateMsg, float);
void Suck(CStateManager&, EStateMsg, float);
void Attack(CStateManager&, EStateMsg, float);
void Crouch(CStateManager&, EStateMsg, float);
bool InAttackPosition(CStateManager&, float);
bool SpotPlayer(CStateManager&, float);
bool ShouldAttack(CStateManager&, float);
bool LostInterest(CStateManager&, float);
bool Inside(CStateManager&, float);
};
}

View File

@ -154,6 +154,7 @@ public:
void SetEnableBurnDeath(bool b) { x81_28_enableBurnDeath = b; }
void SetEnableExplodeDeath(bool b) { x81_29_enableExplodeDeath = b; }
void SetEnableLaggedBurnDeath(bool b) { x81_30_enableLaggedBurnDeath = b; }
void SetX81_31(bool b) { x81_31_ = b; }
void SetX82_24(bool b) { x82_24_ = b; }
void SetLocomotionDuringElectrocution(bool b) { x82_26_locomotionDuringElectrocution = b; }
const KnockBackParms& GetActiveParms() const { return x4_activeParms; }

View File

@ -689,6 +689,7 @@ public:
EPlayerOrbitRequest GetOrbitRequest() const { return x30c_orbitRequest; }
bool IsShowingCrosshairs() const { return x9c4_25_showCrosshairs; }
bool IsSidewaysDashing() const { return x37c_sidewaysDashing; }
void Set_X590(bool b) { x590_ = b; }
};
}

View File

@ -86,6 +86,7 @@
#include "CScriptWorldTeleporter.hpp"
#include "CScriptDebugCameraWaypoint.hpp"
#include "CScriptSpiderBallAttractionSurface.hpp"
#include "MP1/World/CPuddleToadGamma.hpp"
#include "CScriptSpindleCamera.hpp"
#include "MP1/World/CAtomicAlpha.hpp"
#include "CSimplePool.hpp"
@ -1722,7 +1723,34 @@ CEntity* ScriptLoader::LoadSpiderBallAttractionSurface(CStateManager& mgr, CInpu
CEntity* ScriptLoader::LoadPuddleToadGamma(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info)
{
return nullptr;
if (!EnsurePropertyCount(propCount, 17, "PuddleToadGamma"))
return nullptr;
std::string name = mgr.HashInstanceName(in);
CPatterned::EFlavorType flavor = CPatterned::EFlavorType(in.readUint32Big());
zeus::CTransform xf = LoadEditorTransform(in);
zeus::CVector3f scale = zeus::CVector3f::ReadBig(in);
auto pair = CPatternedInfo::HasCorrectParameterCount(in);
if (!pair.first)
return nullptr;
CPatternedInfo pInfo(in, pair.second);
CActorParameters actParms = LoadActorParameters(in);
float f1 = in.readFloatBig();
float f2 = in.readFloatBig();
float f3 = in.readFloatBig();
zeus::CVector3f vec = zeus::CVector3f::ReadBig(in);
float f4 = in.readFloatBig();
float f5 = in.readFloatBig();
float f6 = in.readFloatBig();
CDamageInfo dInfo1(in);
CDamageInfo dInfo2(in);
CAssetId collisionData(in);
const CAnimationParameters& animParms = pInfo.GetAnimationParameters();
CModelData mData(CAnimRes(animParms.GetACSFile(), animParms.GetCharacter(), scale,
animParms.GetInitialAnimation(), true));
return new MP1::CPuddleToadGamma(mgr.AllocateUniqueId(), name, flavor, info, xf, std::move(mData), pInfo, actParms,
f1, f2, f3, vec, f4, f5, f6, dInfo1, dInfo2, collisionData);
}
CEntity* ScriptLoader::LoadDistanceFog(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info)