2020-01-15 12:07:48 +00:00
|
|
|
#include "Runtime/MP1/World/CMetroid.hpp"
|
2020-05-08 08:19:51 +00:00
|
|
|
|
|
|
|
#include "Runtime/CStateManager.hpp"
|
|
|
|
#include "Runtime/Character/CPASAnimParmData.hpp"
|
|
|
|
#include "Runtime/Weapon/CGameProjectile.hpp"
|
|
|
|
#include "Runtime/World/CTeamAiMgr.hpp"
|
|
|
|
#include "Runtime/World/CWorld.hpp"
|
2020-01-15 12:07:48 +00:00
|
|
|
#include "Runtime/World/ScriptLoader.hpp"
|
2017-07-05 18:34:12 +00:00
|
|
|
|
2018-12-08 05:30:43 +00:00
|
|
|
namespace urde::MP1 {
|
2017-07-05 18:34:12 +00:00
|
|
|
|
|
|
|
CMetroidData::CMetroidData(CInputStream& in)
|
2018-12-08 05:30:43 +00:00
|
|
|
: x0_dVuln1(in)
|
|
|
|
, x68_dVuln2(in)
|
|
|
|
, xd0_(in.readFloatBig())
|
|
|
|
, xd4_(in.readFloatBig())
|
|
|
|
, xd8_(in.readFloatBig())
|
|
|
|
, xdc_(in.readFloatBig())
|
|
|
|
, xe0_(in.readFloatBig())
|
|
|
|
, xe4_(in.readFloatBig()) {
|
|
|
|
xe8_animParms1 = ScriptLoader::LoadAnimationParameters(in);
|
|
|
|
xf8_animParms2 = ScriptLoader::LoadAnimationParameters(in);
|
|
|
|
x108_animParms3 = ScriptLoader::LoadAnimationParameters(in);
|
|
|
|
x118_animParms4 = ScriptLoader::LoadAnimationParameters(in);
|
2020-05-08 08:19:51 +00:00
|
|
|
x128_24_startsInWall = in.readBool();
|
2017-07-05 18:34:12 +00:00
|
|
|
}
|
|
|
|
|
2017-11-13 06:19:18 +00:00
|
|
|
CMetroid::CMetroid(TUniqueId uid, std::string_view name, EFlavorType flavor, const CEntityInfo& info,
|
2017-07-05 18:34:12 +00:00
|
|
|
const zeus::CTransform& xf, CModelData&& mData, const CPatternedInfo& pInfo,
|
2020-05-08 08:19:51 +00:00
|
|
|
const CActorParameters& aParms, const CMetroidData& metroidData, TUniqueId other)
|
2018-12-08 05:30:43 +00:00
|
|
|
: CPatterned(ECharacter::Metroid, uid, name, flavor, info, xf, std::move(mData), pInfo, EMovementType::Flyer,
|
2020-05-08 08:19:51 +00:00
|
|
|
EColliderType::One, EBodyType::Flyer, aParms, EKnockBackVariant::Medium)
|
|
|
|
, x56c_data(metroidData)
|
|
|
|
, x6a0_collisionPrimitive(zeus::CSphere{zeus::skZero3f, 0.9f * GetModelData()->GetScale().y()}, GetMaterialList())
|
|
|
|
, x6c0_pathFindSearch(nullptr, 3, pInfo.GetPathfindingIndex(), 1.f, 1.f)
|
|
|
|
, x7cc_animParmsidx(flavor == EFlavorType::Two ? 0 : 1)
|
|
|
|
, x7d0_scale1(GetModelData()->GetScale())
|
|
|
|
, x7dc_scale2(GetModelData()->GetScale())
|
|
|
|
, x7e8_scale3(GetModelData()->GetScale())
|
|
|
|
, x81c_patternedInfo(pInfo)
|
|
|
|
, x954_actParams(aParms)
|
|
|
|
, x9bc_(other) {
|
|
|
|
x808_loopAttackDistance =
|
|
|
|
GetAnimationDistance(CPASAnimParmData{9, CPASAnimParm::FromEnum(2), CPASAnimParm::FromEnum(3)});
|
|
|
|
UpdateTouchBounds();
|
|
|
|
SetCoefficientOfRestitutionModifier(0.9f);
|
|
|
|
x460_knockBackController.SetX82_24(false);
|
|
|
|
x460_knockBackController.SetEnableBurn(false);
|
|
|
|
x460_knockBackController.SetEnableBurnDeath(false);
|
|
|
|
x460_knockBackController.SetEnableShock(false);
|
|
|
|
if (flavor == CPatterned::EFlavorType::Two) {
|
|
|
|
x460_knockBackController.SetEnableFreeze(false);
|
|
|
|
}
|
|
|
|
x81c_patternedInfo.SetActive(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CMetroid::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) {
|
|
|
|
CPatterned::AcceptScriptMsg(msg, uid, mgr);
|
|
|
|
switch (msg) {
|
|
|
|
case EScriptObjectMessage::Registered:
|
|
|
|
x450_bodyController->Activate(mgr);
|
|
|
|
UpdateVolume();
|
|
|
|
break;
|
|
|
|
case EScriptObjectMessage::Alert:
|
|
|
|
x9bf_24_alert = true;
|
|
|
|
break;
|
|
|
|
case EScriptObjectMessage::Deactivate:
|
|
|
|
SwarmRemove(mgr);
|
|
|
|
break;
|
|
|
|
case EScriptObjectMessage::Damage:
|
|
|
|
if (TCastToConstPtr<CGameProjectile> projectile = mgr.GetObjectById(uid)) {
|
|
|
|
const CDamageInfo& damageInfo = projectile->GetDamageInfo();
|
|
|
|
if (GetDamageVulnerability()->WeaponHits(damageInfo.GetWeaponMode(), false)) {
|
|
|
|
ApplyGrowth(damageInfo.GetDamage());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
x9bf_24_alert = true;
|
|
|
|
break;
|
|
|
|
case EScriptObjectMessage::InitializedInArea:
|
|
|
|
if (x698_teamAiMgrId == kInvalidUniqueId) {
|
|
|
|
x698_teamAiMgrId = CTeamAiMgr::GetTeamAiMgr(*this, mgr);
|
|
|
|
}
|
|
|
|
x6c0_pathFindSearch.SetArea(mgr.GetWorld()->GetAreaAlways(GetAreaIdAlways())->GetPostConstructed()->x10bc_pathArea);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CMetroid::Think(float dt, CStateManager& mgr) {
|
|
|
|
if (!GetActive()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (CTeamAiMgr::GetTeamAiRole(mgr, x698_teamAiMgrId, GetUniqueId()) == nullptr) {
|
|
|
|
SwarmAdd(mgr);
|
|
|
|
}
|
|
|
|
UpdateAttackChance(mgr, dt);
|
|
|
|
SuckEnergyFromTarget(mgr, dt);
|
|
|
|
PreventWorldCollisions(mgr, dt);
|
|
|
|
UpdateTouchBounds();
|
|
|
|
RestoreSolidCollision(mgr);
|
|
|
|
CPatterned::Think(dt, mgr);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CMetroid::DoUserAnimEvent(CStateManager& mgr, const CInt32POINode& node, EUserEventType eType, float dt) {
|
|
|
|
if (eType == EUserEventType::GenerateEnd) {
|
|
|
|
AddMaterial(EMaterialTypes::Solid, mgr);
|
|
|
|
} else {
|
|
|
|
CPatterned::DoUserAnimEvent(mgr, node, eType, dt);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
EWeaponCollisionResponseTypes CMetroid::GetCollisionResponseType(const zeus::CVector3f& vec1,
|
|
|
|
const zeus::CVector3f& vec2, const CWeaponMode& mode,
|
|
|
|
EProjectileAttrib attribute) const {
|
|
|
|
EWeaponCollisionResponseTypes types = EWeaponCollisionResponseTypes::Unknown33;
|
|
|
|
if (!GetDamageVulnerability()->WeaponHurts(mode, false) && x450_bodyController->GetPercentageFrozen() <= 0.f) {
|
|
|
|
types = EWeaponCollisionResponseTypes::Unknown58;
|
|
|
|
}
|
|
|
|
return types;
|
|
|
|
}
|
2017-07-05 18:34:12 +00:00
|
|
|
|
2018-12-08 05:30:43 +00:00
|
|
|
} // namespace urde::MP1
|