mirror of https://github.com/AxioDL/metaforce.git
Initial CMagdolite imps
This commit is contained in:
parent
d3a44259c3
commit
d1c796f2a9
|
@ -1,22 +1,43 @@
|
||||||
#include "Runtime/MP1/World/CMagdolite.hpp"
|
#include "Runtime/MP1/World/CMagdolite.hpp"
|
||||||
|
|
||||||
|
#include "Runtime/Collision/CCollisionActor.hpp"
|
||||||
|
#include "Runtime/Collision/CCollisionActorManager.hpp"
|
||||||
|
#include "Runtime/Collision/CJointCollisionDescription.hpp"
|
||||||
|
#include "Runtime/Graphics/CSkinnedModel.hpp"
|
||||||
|
#include "Runtime/Weapon/CFlameThrower.hpp"
|
||||||
|
#include "Runtime/World/CPlayer.hpp"
|
||||||
|
#include "Runtime/World/CScriptWater.hpp"
|
||||||
|
#include "Runtime/World/CScriptWaypoint.hpp"
|
||||||
|
#include "Runtime/GameGlobalObjects.hpp"
|
||||||
|
#include "Runtime/CSimplePool.hpp"
|
||||||
|
#include "Runtime/CStateManager.hpp"
|
||||||
|
#include "TCastTo.hpp" // Generated file, do not modify include path
|
||||||
|
|
||||||
|
#include <array>
|
||||||
|
|
||||||
namespace urde::MP1 {
|
namespace urde::MP1 {
|
||||||
|
|
||||||
CMagdolite::CMagdoliteData::CMagdoliteData(CInputStream& in)
|
namespace {
|
||||||
: x0_propertyCount(in.readUint32Big())
|
constexpr std::array<SSphereJointInfo, 5> skSpineJoints{{
|
||||||
, x4_(in.readUint32Big())
|
{"spine1", 0.75f},
|
||||||
, x8_(in)
|
{"spine3", 0.75f},
|
||||||
, xc_(in.readUint32Big())
|
{"spine5", 0.75f},
|
||||||
, x10_(in.readFloatBig())
|
{"spine7", 0.75f},
|
||||||
, x18_(in.readFloatBig())
|
{"spine9", 0.75f},
|
||||||
, x1c_(in.readFloatBig()) {}
|
}};
|
||||||
|
|
||||||
|
constexpr std::array<SOBBJointInfo, 2> skHeadJoints{{
|
||||||
|
{"head", "Top_LCTR", {1.f, 0.15f, 0.5f}},
|
||||||
|
{"head", "Bottom_LCTR", {0.75f, 0.15f, 0.25f}},
|
||||||
|
}};
|
||||||
|
} // namespace
|
||||||
|
|
||||||
CMagdolite::CMagdolite(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf,
|
CMagdolite::CMagdolite(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf,
|
||||||
CModelData&& mData, const CPatternedInfo& pInfo, const CActorParameters& actParms, float f1,
|
CModelData&& mData, const CPatternedInfo& pInfo, const CActorParameters& actParms, float f1,
|
||||||
float f2, const CDamageInfo& dInfo1, const CDamageInfo& dInfo2,
|
float f2, const CDamageInfo& dInfo1, const CDamageInfo& dInfo2,
|
||||||
const CDamageVulnerability& dVuln1, const CDamageVulnerability& dVuln2, CAssetId modelId,
|
const CDamageVulnerability& dVuln1, const CDamageVulnerability& dVuln2, CAssetId modelId,
|
||||||
CAssetId skinId, float f3, float f4, float f5, float f6,
|
CAssetId skinId, float f3, float f4, float f5, float f6, const CFlameInfo& magData, float f7,
|
||||||
const CMagdolite::CMagdoliteData& magData, float f7, float f8, float f9)
|
float f8, float f9)
|
||||||
: CPatterned(ECharacter::Magdolite, uid, name, EFlavorType::Zero, info, xf, std::move(mData), pInfo,
|
: CPatterned(ECharacter::Magdolite, uid, name, EFlavorType::Zero, info, xf, std::move(mData), pInfo,
|
||||||
EMovementType::Flyer, EColliderType::One, EBodyType::BiPedal, actParms, EKnockBackVariant::Large)
|
EMovementType::Flyer, EColliderType::One, EBodyType::BiPedal, actParms, EKnockBackVariant::Large)
|
||||||
, x568_(f4)
|
, x568_(f4)
|
||||||
|
@ -26,28 +47,600 @@ CMagdolite::CMagdolite(TUniqueId uid, std::string_view name, const CEntityInfo&
|
||||||
, x578_(std::cos(zeus::degToRad(f2)))
|
, x578_(std::cos(zeus::degToRad(f2)))
|
||||||
, x57c_(f1)
|
, x57c_(f1)
|
||||||
, x584_boneTracker(*GetModelData()->GetAnimationData(), "head"sv, zeus::degToRad(f1), zeus::degToRad(90.f),
|
, x584_boneTracker(*GetModelData()->GetAnimationData(), "head"sv, zeus::degToRad(f1), zeus::degToRad(90.f),
|
||||||
EBoneTrackingFlags::ParentIk) {
|
EBoneTrackingFlags::ParentIk)
|
||||||
|
, x5bc_(dVuln1)
|
||||||
|
, x624_(dVuln2)
|
||||||
|
, x690_headlessModel(
|
||||||
|
CToken(TObjOwnerDerivedFromIObj<CSkinnedModel>::GetNewDerivedObject(std::make_unique<CSkinnedModel>(
|
||||||
|
g_SimplePool->GetObj({SBIG('CMDL'), modelId}), g_SimplePool->GetObj({SBIG('CSKR'), skinId}),
|
||||||
|
x64_modelData->GetAnimationData()->GetModelData()->GetLayoutInfo(), 1, 1))))
|
||||||
|
, x6a8_(magData)
|
||||||
|
, x6cc_(g_SimplePool->GetObj("FlameThrower"sv))
|
||||||
|
, x6d4_(dInfo1)
|
||||||
|
, x6f0_(dInfo2)
|
||||||
|
, x71c_(xf.origin)
|
||||||
|
, x744_(f7)
|
||||||
|
, x748_(f8)
|
||||||
|
, x74c_(f9) {
|
||||||
|
x460_knockBackController.SetAutoResetImpulse(false);
|
||||||
|
x460_knockBackController.SetEnableBurn(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CMagdolite::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) {
|
void CMagdolite::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) {
|
||||||
|
|
||||||
switch (msg) {
|
switch (msg) {
|
||||||
|
case EScriptObjectMessage::Touched:
|
||||||
|
ApplyContactDamage(uid, mgr);
|
||||||
|
break;
|
||||||
case EScriptObjectMessage::Damage:
|
case EScriptObjectMessage::Damage:
|
||||||
case EScriptObjectMessage::InvulnDamage:
|
case EScriptObjectMessage::InvulnDamage:
|
||||||
/* TODO Implement */
|
if (TCastToConstPtr<CGameProjectile> proj = mgr.GetObjectById(uid)) {
|
||||||
|
if (proj->GetOwnerId() == mgr.GetPlayer().GetUniqueId() &&
|
||||||
|
(GetBodyController()->GetPercentageFrozen() <= 0.f ||
|
||||||
|
x5bc_.GetVulnerability(proj->GetDamageInfo().GetWeaponMode(), false) == EVulnerability::Deflect)) {
|
||||||
|
if (x70c_ - HealthInfo(mgr)->GetHP() <= x574_ &&
|
||||||
|
x624_.GetVulnerability(proj->GetDamageInfo().GetWeaponMode(), false) != EVulnerability::Deflect) {
|
||||||
|
x400_24_hitByPlayerProjectile = true;
|
||||||
|
} else {
|
||||||
|
x70c_ = HealthInfo(mgr)->GetHP();
|
||||||
|
x754_24_ = true;
|
||||||
|
}
|
||||||
|
} else if (x400_24_hitByPlayerProjectile) {
|
||||||
|
x754_26_ = true;
|
||||||
|
x401_30_pendingDeath = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
case EScriptObjectMessage::Registered:
|
case EScriptObjectMessage::SuspendedMove: {
|
||||||
|
if (x580_)
|
||||||
|
x580_->SetMovable(mgr, false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case EScriptObjectMessage::Registered: {
|
||||||
x450_bodyController->Activate(mgr);
|
x450_bodyController->Activate(mgr);
|
||||||
RemoveMaterial(EMaterialTypes::Solid, mgr);
|
RemoveMaterial(EMaterialTypes::Solid, mgr);
|
||||||
AddMaterial(EMaterialTypes::NonSolidDamageable, mgr);
|
AddMaterial(EMaterialTypes::NonSolidDamageable, mgr);
|
||||||
x584_boneTracker.SetActive(false);
|
x584_boneTracker.SetActive(false);
|
||||||
CreateShadow(false);
|
CreateShadow(false);
|
||||||
/* TODO Finish */
|
const zeus::CVector3f boxExtents = GetBoundingBox().extents();
|
||||||
|
SetBoundingBox({-boxExtents, boxExtents});
|
||||||
|
SetupCollisionActors(mgr);
|
||||||
|
x330_stateMachineState.SetDelay(0.f);
|
||||||
|
CreateFlameThrower(mgr);
|
||||||
|
x70c_ = GetHealthInfo(mgr)->GetHP();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case EScriptObjectMessage::Deleted:
|
||||||
|
x580_->Destroy(mgr);
|
||||||
|
if (x6c8_flameThrowerId != kInvalidUniqueId) {
|
||||||
|
mgr.FreeScriptObject(x6c8_flameThrowerId);
|
||||||
|
x6c8_flameThrowerId = kInvalidUniqueId;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
CPatterned::AcceptScriptMsg(msg, uid, mgr);
|
CPatterned::AcceptScriptMsg(msg, uid, mgr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CMagdolite::ApplyContactDamage(TUniqueId uid, CStateManager& mgr) {
|
||||||
|
if (TCastToConstPtr<CCollisionActor> colAct = mgr.GetObjectById(uid)) {
|
||||||
|
if (!IsAlive())
|
||||||
|
return;
|
||||||
|
CDamageInfo dInfo = GetContactDamage();
|
||||||
|
|
||||||
|
for (TUniqueId testId : x69c_) {
|
||||||
|
if (testId == colAct->GetUniqueId()) {
|
||||||
|
dInfo = x6f0_;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (colAct->GetLastTouchedObject() == mgr.GetPlayer().GetUniqueId() && x420_curDamageRemTime <= 0.f) {
|
||||||
|
mgr.ApplyDamage(GetUniqueId(), mgr.GetPlayer().GetUniqueId(), GetUniqueId(), dInfo,
|
||||||
|
CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Solid}, {}), {});
|
||||||
|
x420_curDamageRemTime = x424_damageWaitTime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMagdolite::SetupCollisionActors(CStateManager& mgr) {
|
||||||
|
std::vector<CJointCollisionDescription> joints;
|
||||||
|
joints.reserve(8);
|
||||||
|
const CAnimData* animData = GetModelData()->GetAnimationData();
|
||||||
|
for (const auto& info : skSpineJoints) {
|
||||||
|
joints.push_back(CJointCollisionDescription::SphereCollision(animData->GetLocatorSegId(info.name), info.radius,
|
||||||
|
info.name, 200.f));
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& info : skHeadJoints) {
|
||||||
|
joints.push_back(CJointCollisionDescription::OBBAutoSizeCollision(
|
||||||
|
animData->GetLocatorSegId(info.from), animData->GetLocatorSegId(info.to), info.bounds,
|
||||||
|
CJointCollisionDescription::EOrientationType::One, info.to, 200.f));
|
||||||
|
}
|
||||||
|
x580_.reset(new CCollisionActorManager(mgr, GetUniqueId(), GetAreaIdAlways(), joints, GetActive()));
|
||||||
|
|
||||||
|
for (int i = 0; i < x580_->GetNumCollisionActors(); ++i) {
|
||||||
|
const auto& desc = x580_->GetCollisionDescFromIndex(i);
|
||||||
|
if (TCastToPtr<CCollisionActor> colAct = mgr.ObjectById(desc.GetCollisionActorId())) {
|
||||||
|
colAct->AddMaterial(EMaterialTypes::AIJoint, mgr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < x580_->GetNumCollisionActors(); ++i) {
|
||||||
|
const auto& desc = x580_->GetCollisionDescFromIndex(i);
|
||||||
|
if (desc.GetName().compare("Top_LCTR"sv) != 0 && desc.GetName().compare("Bottom_LCTR"sv) != 0) {
|
||||||
|
if (TCastToPtr<CCollisionActor> colAct = mgr.ObjectById(desc.GetCollisionActorId())) {
|
||||||
|
colAct->AddMaterial(EMaterialTypes::ProjectilePassthrough, mgr);
|
||||||
|
x69c_.push_back(colAct->GetUniqueId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMagdolite::CreateFlameThrower(CStateManager& mgr) {
|
||||||
|
if (x6c8_flameThrowerId != kInvalidUniqueId)
|
||||||
|
return;
|
||||||
|
|
||||||
|
x6c8_flameThrowerId = mgr.AllocateUniqueId();
|
||||||
|
mgr.AddObject(new CFlameThrower(x6cc_, "Magdolite_Flame"sv, EWeaponType::Plasma, x6a8_, {},
|
||||||
|
EMaterialTypes::CollisionActor, x6d4_, x6c8_flameThrowerId, GetAreaIdAlways(),
|
||||||
|
GetUniqueId(), EProjectileAttrib::None, CAssetId(), -1, CAssetId()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMagdolite::LaunchFlameThrower(CStateManager& mgr, bool fire) {
|
||||||
|
if ((!fire || x754_30_) && IsAlive()) {
|
||||||
|
if (CFlameThrower* fl = static_cast<CFlameThrower*>(mgr.ObjectById(x6c8_flameThrowerId))) {
|
||||||
|
if (!fire)
|
||||||
|
fl->Reset(mgr, false);
|
||||||
|
else
|
||||||
|
fl->Fire(GetTransform(), mgr, false);
|
||||||
|
}
|
||||||
|
x754_27_ = fire;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMagdolite::Think(float dt, CStateManager& mgr) {
|
||||||
|
CPatterned::Think(dt, mgr);
|
||||||
|
if (!GetActive())
|
||||||
|
return;
|
||||||
|
|
||||||
|
x758_ += dt;
|
||||||
|
if (GetBodyController()->GetPercentageFrozen() > 0.f && x754_27_) {
|
||||||
|
LaunchFlameThrower(mgr, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!IsAlive()) {
|
||||||
|
if (CFlameThrower* fl = static_cast<CFlameThrower*>(mgr.ObjectById(x6c8_flameThrowerId))) {
|
||||||
|
fl->SetTransform(GetLctrTransform("LCTR_MAGMOUTH"sv), dt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
zeus::CVector3f plPos = mgr.GetPlayer().GetTranslation();
|
||||||
|
zeus::CVector3f aimPos = mgr.GetPlayer().GetAimPosition(mgr, 0.f);
|
||||||
|
zeus::CTransform xf = GetLctrTransform("LCTR_MAGMOUTH"sv);
|
||||||
|
zeus::CVector3f aimDir = (aimPos - xf.origin).normalized();
|
||||||
|
float angleDiff = zeus::CVector3f::getAngleDiff(xf.basis[1], aimDir);
|
||||||
|
float dVar7 = std::min(angleDiff, zeus::degToRad(x57c_));
|
||||||
|
if (xf.basis[2].dot(aimDir) < 0.f) {
|
||||||
|
dVar7 = -dVar7;
|
||||||
|
}
|
||||||
|
|
||||||
|
float dVar8 = dVar7 + zeus::degToRad(x57c_) / 2.f * zeus::degToRad(x57c_);
|
||||||
|
float dVar2 = 1.f - dVar8;
|
||||||
|
x710_ = plPos * dVar2 + (aimPos * dVar8);
|
||||||
|
|
||||||
|
if (GetActive()) { // lol tautologies
|
||||||
|
if (IsAlive()) {
|
||||||
|
GetModelData()->GetAnimationData()->PreRender();
|
||||||
|
x584_boneTracker.Update(dt);
|
||||||
|
x584_boneTracker.PreRender(mgr, *GetModelData()->GetAnimationData(), GetTransform(), GetModelData()->GetScale(),
|
||||||
|
*GetBodyController());
|
||||||
|
|
||||||
|
if (CFlameThrower* fl = static_cast<CFlameThrower*>(mgr.ObjectById(x6c8_flameThrowerId))) {
|
||||||
|
fl->SetTransform(GetLctrTransform("LCTR_MAGMOUTH"sv), dt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
x580_->Update(dt, mgr, CCollisionActorManager::EUpdateOptions::ObjectSpace);
|
||||||
|
zeus::CTransform headXf = GetLocatorTransform("head"sv);
|
||||||
|
MoveCollisionPrimitive(headXf.rotate(GetModelData()->GetScale() * headXf.origin));
|
||||||
|
xe4_27_notInSortedLists = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (x750_ == 2) {
|
||||||
|
if (x738_ * 0.5f <= x734_)
|
||||||
|
x740_ -= x73c_ * dt;
|
||||||
|
else
|
||||||
|
x740_ += x73c_ * dt;
|
||||||
|
x734_ += x740_ * dt;
|
||||||
|
SetTranslation(GetTranslation() - zeus::CVector3f{0.f, 0.f, x740_ * dt});
|
||||||
|
if (GetTranslation().z() < x728_.z()) {
|
||||||
|
SetTranslation(x728_);
|
||||||
|
x750_ = 0;
|
||||||
|
}
|
||||||
|
} else if (x750_ == 1) {
|
||||||
|
if (x738_ * 0.5f <= x734_)
|
||||||
|
x740_ -= x73c_ * dt;
|
||||||
|
else
|
||||||
|
x740_ += x73c_ * dt;
|
||||||
|
x734_ += x740_ * dt;
|
||||||
|
|
||||||
|
SetTranslation(GetTranslation() + zeus::CVector3f{0.f, 0.f, x740_ * dt});
|
||||||
|
if (GetTranslation().z() > x728_.z()) {
|
||||||
|
SetTranslation(x728_);
|
||||||
|
x750_ = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void CMagdolite::DoUserAnimEvent(CStateManager& mgr, const CInt32POINode& node, EUserEventType type, float dt) {
|
||||||
|
|
||||||
|
if (type == EUserEventType::DamageOff) {
|
||||||
|
LaunchFlameThrower(mgr, false);
|
||||||
|
} else if (type == EUserEventType::DamageOn) {
|
||||||
|
LaunchFlameThrower(mgr, true);
|
||||||
|
} else if (type == EUserEventType::BreakLockOn) {
|
||||||
|
RemoveMaterial(EMaterialTypes::Target, EMaterialTypes::Orbit, mgr);
|
||||||
|
mgr.GetPlayer().SetOrbitRequestForTarget(GetUniqueId(), CPlayer::EPlayerOrbitRequest::ActivateOrbitSource, mgr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
CPatterned::DoUserAnimEvent(mgr, node, type, dt);
|
||||||
|
}
|
||||||
|
void CMagdolite::Death(CStateManager& mgr, const zeus::CVector3f& direction, EScriptObjectState state) {
|
||||||
|
if (IsAlive())
|
||||||
|
return;
|
||||||
|
zeus::CTransform tmpXf = GetTransform();
|
||||||
|
SetTransform(GetLctrTransform("head"sv));
|
||||||
|
SendScriptMsgs(EScriptObjectState::MassiveDeath, mgr, EScriptObjectMessage::None);
|
||||||
|
GenerateDeathExplosion(mgr);
|
||||||
|
SetTransform(tmpXf);
|
||||||
|
GetModelData()->GetAnimationData()->SubstituteModelData(x690_headlessModel);
|
||||||
|
x460_knockBackController.SetEnableFreeze(false);
|
||||||
|
GetBodyController()->UnFreeze();
|
||||||
|
if (!x754_26_)
|
||||||
|
x460_knockBackController.SetSeverity(pas::ESeverity::Two);
|
||||||
|
else
|
||||||
|
GetModelData()->GetAnimationData()->SubstituteModelData(x690_headlessModel);
|
||||||
|
|
||||||
|
CPatterned::Death(mgr, direction, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMagdolite::FluidFXThink(EFluidState state, CScriptWater& water, CStateManager& mgr) {
|
||||||
|
if (x754_28_ && state == EFluidState::InFluid) {
|
||||||
|
CFluidPlaneManager* flMgr = mgr.GetFluidPlaneManager();
|
||||||
|
if (flMgr->GetLastRippleDeltaTime(GetUniqueId()) >= 2.3f) {
|
||||||
|
zeus::CVector3f center = GetTranslation();
|
||||||
|
center.z() = float(water.GetTriggerBoundsWR().max.z());
|
||||||
|
water.GetFluidPlane().AddRipple(3.f, GetUniqueId(), center, water, mgr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMagdolite::SelectTarget(CStateManager& mgr, EStateMsg msg, float arg) {
|
||||||
|
if (msg == EStateMsg::Update) {
|
||||||
|
TUniqueId targetId = FindSuitableTarget(mgr, EScriptObjectState::Attack, EScriptObjectMessage::Follow);
|
||||||
|
if (targetId != kInvalidUniqueId) {
|
||||||
|
if (TCastToConstPtr<CScriptWaypoint> wp = mgr.GetObjectById(targetId)) {
|
||||||
|
SetTransform(wp->GetTransform());
|
||||||
|
x71c_ = GetTranslation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (msg == EStateMsg::Deactivate) {
|
||||||
|
UpdateOrientation(mgr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void CMagdolite::Generate(CStateManager& mgr, EStateMsg msg, float arg) {
|
||||||
|
if (msg == EStateMsg::Activate) {
|
||||||
|
x32c_animState = EAnimState::Ready;
|
||||||
|
x754_24_ = false;
|
||||||
|
} else if (msg == EStateMsg::Update) {
|
||||||
|
TryCommand(mgr, pas::EAnimationState::Generate, &CPatterned::TryGenerateNoXf, 0);
|
||||||
|
if (x32c_animState == EAnimState::Repeat)
|
||||||
|
GetBodyController()->SetLocomotionType(pas::ELocomotionType::Relaxed);
|
||||||
|
} else if (msg == EStateMsg::Deactivate) {
|
||||||
|
x32c_animState = EAnimState::NotReady;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void CMagdolite::Deactivate(CStateManager& mgr, EStateMsg msg, float arg) {
|
||||||
|
if (msg == EStateMsg::Activate) {
|
||||||
|
x32c_animState = EAnimState::Ready;
|
||||||
|
x754_24_ = false;
|
||||||
|
x584_boneTracker.SetActive(false);
|
||||||
|
} else if (msg == EStateMsg::Update) {
|
||||||
|
TryCommand(mgr, pas::EAnimationState::Step, &CPatterned::TryStep, int(pas::EStepDirection::Down));
|
||||||
|
if (x32c_animState == EAnimState::Repeat)
|
||||||
|
GetBodyController()->SetLocomotionType(pas::ELocomotionType::Internal7);
|
||||||
|
} else if (msg == EStateMsg::Deactivate) {
|
||||||
|
x32c_animState = EAnimState::NotReady;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void CMagdolite::Attack(CStateManager& mgr, EStateMsg msg, float arg) {
|
||||||
|
if (msg == EStateMsg::Activate) {
|
||||||
|
x32c_animState = EAnimState::Ready;
|
||||||
|
x584_boneTracker.SetActive(false);
|
||||||
|
zeus::CVector3f plPos = mgr.GetPlayer().GetTranslation();
|
||||||
|
zeus::CTransform headXf = GetLctrTransform("head"sv);
|
||||||
|
float zDiff = headXf.origin.z() - plPos.z();
|
||||||
|
|
||||||
|
float fVar1 = (zDiff - x74c_);
|
||||||
|
float fVar2 = 0.f;
|
||||||
|
if (fVar1 >= 0.f) {
|
||||||
|
fVar2 = fVar1;
|
||||||
|
if (x748_ < fVar1)
|
||||||
|
fVar2 = x748_;
|
||||||
|
}
|
||||||
|
x728_ = x71c_ - zeus::CVector3f(0.f, 0.f, fVar1 - fVar2);
|
||||||
|
x740_ = 0.f;
|
||||||
|
x734_ = 0.f;
|
||||||
|
x738_ = fVar2;
|
||||||
|
x73c_ = (2.f * x738_) / (x744_ * x744_);
|
||||||
|
if (GetTranslation().z() <= x728_.z())
|
||||||
|
x750_ = 1;
|
||||||
|
else
|
||||||
|
x750_ = 2;
|
||||||
|
x754_30_ = true;
|
||||||
|
} else if (msg == EStateMsg::Update) {
|
||||||
|
TryCommand(mgr, pas::EAnimationState::MeleeAttack, &CPatterned::TryMeleeAttack, 1);
|
||||||
|
zeus::CVector3f direction = (mgr.GetPlayer().GetTranslation().toVec2f() - GetTranslation().toVec2f()).normalized();
|
||||||
|
float angle = zeus::CVector3f::getAngleDiff(GetTransform().basis[1], direction);
|
||||||
|
if (GetTransform().basis[0].dot(direction) > 0.f)
|
||||||
|
angle *= -1.f;
|
||||||
|
|
||||||
|
if ((57.29f * angle) <= x3b8_turnSpeed && (57.29f * angle) < -x3b8_turnSpeed) {
|
||||||
|
angle = zeus::degToRad(-x3b8_turnSpeed);
|
||||||
|
} else {
|
||||||
|
angle = zeus::degToRad(x3b8_turnSpeed);
|
||||||
|
}
|
||||||
|
|
||||||
|
RotateInOneFrameOR(zeus::CQuaternion::fromAxisAngle({0.f, 0.f, 1.f}, angle), arg);
|
||||||
|
} else if (msg == EStateMsg::Deactivate) {
|
||||||
|
x32c_animState = EAnimState::NotReady;
|
||||||
|
LaunchFlameThrower(mgr, false);
|
||||||
|
x750_ = 1;
|
||||||
|
x728_ = x71c_;
|
||||||
|
x740_ = 0.f;
|
||||||
|
x744_ = 0.f;
|
||||||
|
x738_ = x728_.z() - GetTranslation().z();
|
||||||
|
x73c_ = (2.f * x738_) / (x744_ * x744_);
|
||||||
|
x754_30_ = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void CMagdolite::Active(CStateManager& mgr, EStateMsg msg, float arg) {
|
||||||
|
if (msg == EStateMsg::Activate) {
|
||||||
|
GetBodyController()->SetLocomotionType(pas::ELocomotionType::Lurk);
|
||||||
|
x584_boneTracker.SetActive(true);
|
||||||
|
x584_boneTracker.SetTarget(mgr.GetPlayer().GetUniqueId());
|
||||||
|
x400_24_hitByPlayerProjectile = false;
|
||||||
|
x754_29_ = false;
|
||||||
|
x330_stateMachineState.SetDelay(x568_);
|
||||||
|
} else if (msg == EStateMsg::Update) {
|
||||||
|
zeus::CVector3f posDiff = (mgr.GetPlayer().GetTranslation().toVec2f() - GetTranslation().toVec2f());
|
||||||
|
if (posDiff.canBeNormalized()) {
|
||||||
|
posDiff.normalize();
|
||||||
|
if (GetTransform().basis[1].dot(posDiff) < x578_)
|
||||||
|
GetBodyController()->GetCommandMgr().DeliverCmd(CBCLocomotionCmd({}, posDiff, 1.f));
|
||||||
|
}
|
||||||
|
} else if (msg == EStateMsg::Deactivate) {
|
||||||
|
x330_stateMachineState.SetDelay(((x570_ - x56c_) * mgr.GetActiveRandom()->Float()) + x56c_);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMagdolite::InActive(CStateManager& mgr, EStateMsg msg, float arg) {
|
||||||
|
if (msg == EStateMsg::Activate) {
|
||||||
|
xe7_27_enableRender = false;
|
||||||
|
GetBodyController()->SetLocomotionType(pas::ELocomotionType::Internal7);
|
||||||
|
RemoveMaterial(EMaterialTypes::Orbit, EMaterialTypes::Target, mgr);
|
||||||
|
} else if (msg == EStateMsg::Deactivate) {
|
||||||
|
AddMaterial(EMaterialTypes::Orbit, EMaterialTypes::Target, mgr);
|
||||||
|
x754_25_ = false;
|
||||||
|
UpdateOrientation(mgr);
|
||||||
|
xe7_27_enableRender = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void CMagdolite::GetUp(CStateManager& mgr, EStateMsg msg, float arg) {
|
||||||
|
if (msg == EStateMsg::Activate) {
|
||||||
|
x32c_animState = EAnimState::Ready;
|
||||||
|
x754_24_ = false;
|
||||||
|
x754_28_ = true;
|
||||||
|
AddMaterial(EMaterialTypes::Orbit, EMaterialTypes::Target, mgr);
|
||||||
|
} else if (msg == EStateMsg::Update) {
|
||||||
|
if (!x754_25_)
|
||||||
|
TryCommand(mgr, pas::EAnimationState::Step, &CPatterned::TryStep, int(pas::EStepDirection::Forward));
|
||||||
|
else
|
||||||
|
TryCommand(mgr, pas::EAnimationState::Step, &CPatterned::TryStep, int(pas::EStepDirection::Up));
|
||||||
|
if (x32c_animState == EAnimState::Repeat)
|
||||||
|
GetBodyController()->SetLocomotionType(pas::ELocomotionType::Lurk);
|
||||||
|
} else if (msg == EStateMsg::Deactivate) {
|
||||||
|
x32c_animState = EAnimState::NotReady;
|
||||||
|
x754_28_ = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMagdolite::Taunt(CStateManager& mgr, EStateMsg msg, float arg) {
|
||||||
|
if (msg == EStateMsg::Activate) {
|
||||||
|
x32c_animState = EAnimState::Ready;
|
||||||
|
x584_boneTracker.SetActive(true);
|
||||||
|
} else if (msg == EStateMsg::Update) {
|
||||||
|
TryCommand(mgr, pas::EAnimationState::Taunt, &CPatterned::TryTaunt, 1);
|
||||||
|
} else if (msg == EStateMsg::Deactivate) {
|
||||||
|
x32c_animState = EAnimState::NotReady;
|
||||||
|
x584_boneTracker.SetActive(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMagdolite::Lurk(CStateManager& mgr, EStateMsg msg, float arg) {
|
||||||
|
if (msg == EStateMsg::Activate) {
|
||||||
|
GetBodyController()->SetLocomotionType(pas::ELocomotionType::Relaxed);
|
||||||
|
x584_boneTracker.SetActive(false);
|
||||||
|
x330_stateMachineState.SetDelay(0.f);
|
||||||
|
AddMaterial(EMaterialTypes::Target, EMaterialTypes::Orbit, mgr);
|
||||||
|
} else if (msg == EStateMsg::Deactivate) {
|
||||||
|
x754_25_ = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void CMagdolite::ProjectileAttack(CStateManager& mgr, EStateMsg msg, float arg) {
|
||||||
|
if (msg == EStateMsg::Activate) {
|
||||||
|
x32c_animState = EAnimState::Ready;
|
||||||
|
LaunchFlameThrower(mgr, true);
|
||||||
|
x584_boneTracker.SetActive(true);
|
||||||
|
x584_boneTracker.SetNoHorizontalAim(true);
|
||||||
|
x584_boneTracker.SetTarget(kInvalidUniqueId);
|
||||||
|
x754_30_ = true;
|
||||||
|
} else if (msg == EStateMsg::Update) {
|
||||||
|
if (TooClose(mgr, 0.f)) {
|
||||||
|
TryCommand(mgr, pas::EAnimationState::ProjectileAttack, &CPatterned::TryProjectileAttack, 0);
|
||||||
|
} else {
|
||||||
|
TryCommand(mgr, pas::EAnimationState::ProjectileAttack, &CPatterned::TryProjectileAttack, 1);
|
||||||
|
}
|
||||||
|
x584_boneTracker.SetTargetPosition(x710_);
|
||||||
|
} else if (msg == EStateMsg::Deactivate) {
|
||||||
|
x32c_animState = EAnimState::NotReady;
|
||||||
|
LaunchFlameThrower(mgr, false);
|
||||||
|
x584_boneTracker.SetActive(false);
|
||||||
|
x584_boneTracker.SetNoHorizontalAim(false);
|
||||||
|
x754_30_ = false;
|
||||||
|
x584_boneTracker.SetTarget(mgr.GetPlayer().GetUniqueId());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMagdolite::Flinch(CStateManager& mgr, EStateMsg msg, float arg) {
|
||||||
|
if (msg == EStateMsg::Activate) {
|
||||||
|
x32c_animState = EAnimState::Ready;
|
||||||
|
x400_24_hitByPlayerProjectile = false;
|
||||||
|
x584_boneTracker.SetActive(false);
|
||||||
|
} else if (msg == EStateMsg::Update) {
|
||||||
|
TryCommand(mgr, pas::EAnimationState::KnockBack, &CPatterned::TryKnockBack, 0);
|
||||||
|
} else if (msg == EStateMsg::Deactivate) {
|
||||||
|
x32c_animState = EAnimState::NotReady;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void CMagdolite::Retreat(CStateManager& mgr, EStateMsg msg, float arg) {
|
||||||
|
if (msg == EStateMsg::Activate) {
|
||||||
|
x32c_animState = EAnimState::Ready;
|
||||||
|
x754_24_ = false;
|
||||||
|
x584_boneTracker.SetActive(false);
|
||||||
|
GetBodyController()->GetCommandMgr().DeliverCmd(CBodyStateCmd(EBodyStateCmd::NextState));
|
||||||
|
x754_28_ = true;
|
||||||
|
} else if (msg == EStateMsg::Update) {
|
||||||
|
TryCommand(mgr, pas::EAnimationState::Generate, &CPatterned::TryGenerate, 1);
|
||||||
|
if (x32c_animState == EAnimState::Repeat)
|
||||||
|
GetBodyController()->SetLocomotionType(pas::ELocomotionType::Internal7);
|
||||||
|
} else if (msg == EStateMsg::Deactivate) {
|
||||||
|
x754_28_ = false;
|
||||||
|
x32c_animState = EAnimState::NotReady;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CMagdolite::InAttackPosition(CStateManager& mgr, float arg) {
|
||||||
|
zeus::CTransform xf = GetLctrTransform("head"sv);
|
||||||
|
zeus::CVector3f plAimPos = mgr.GetPlayer().GetAimPosition(mgr, 0.f);
|
||||||
|
zeus::CVector3f diff = (plAimPos - GetTranslation());
|
||||||
|
if (GetTranslation().z() < plAimPos.z() && plAimPos.z() < xf.origin.z())
|
||||||
|
diff.z() = 0.f;
|
||||||
|
|
||||||
|
if (std::fabs(diff.magnitude()) >= FLT_EPSILON) {
|
||||||
|
printf("InAttackPosition: %08X 1\n", GetEditorId().id);
|
||||||
|
return ((1.f / diff.magnitude()) * diff).dot(GetTransform().basis[1]) < x578_;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("InAttackPosition: %08X 0\n", GetEditorId().id);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CMagdolite::Leash(CStateManager& mgr, float arg) {
|
||||||
|
float dist = (GetTranslation() - mgr.GetPlayer().GetTranslation()).magSquared();
|
||||||
|
bool ret = dist < x3c8_leashRadius * x3c8_leashRadius;
|
||||||
|
printf("Leash: %08X %i %f\n", GetEditorId().id, ret, dist);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CMagdolite::HasAttackPattern(CStateManager& mgr, float arg) {
|
||||||
|
bool ret = FindSuitableTarget(mgr, EScriptObjectState::Attack, EScriptObjectMessage::Follow) != kInvalidUniqueId;
|
||||||
|
printf("LineOfSight: %08X %i\n", GetEditorId().id, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
bool CMagdolite::LineOfSight(CStateManager& mgr, float arg) {
|
||||||
|
zeus::CTransform mouthXf = GetLctrTransform("LCTR_MAGMOUTH"sv);
|
||||||
|
zeus::CVector3f diff = x710_ - mouthXf.origin;
|
||||||
|
if (diff.canBeNormalized()) {
|
||||||
|
diff.normalize();
|
||||||
|
if (diff.dot(GetTransform().basis[1]) < x578_)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ret = mgr.RayCollideWorld(
|
||||||
|
mouthXf.origin, x710_,
|
||||||
|
CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Solid, EMaterialTypes::Character},
|
||||||
|
{EMaterialTypes::Player, EMaterialTypes::ProjectilePassthrough}),
|
||||||
|
this);
|
||||||
|
printf("LineOfSight: %08X %i\n", GetEditorId().id, ret);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
bool CMagdolite::ShouldRetreat(CStateManager& mgr, float arg) {
|
||||||
|
printf("ShouldRetreat: %08X %i\n", GetEditorId().id, x754_24_);
|
||||||
|
return x754_24_;
|
||||||
|
}
|
||||||
|
void CMagdolite::UpdateOrientation(CStateManager& mgr) {
|
||||||
|
zeus::CVector3f plDiff = (mgr.GetPlayer().GetTranslation().toVec2f() - GetTranslation().toVec2f());
|
||||||
|
plDiff = plDiff.normalized();
|
||||||
|
float angle = zeus::CVector3f::getAngleDiff(GetTransform().basis[1], plDiff);
|
||||||
|
if (GetTransform().basis[0].dot(plDiff) > 0.f)
|
||||||
|
angle *= -1.f;
|
||||||
|
zeus::CQuaternion q = GetTransform().basis;
|
||||||
|
q.rotateZ(angle);
|
||||||
|
SetTransform(q.toTransform(GetTranslation()));
|
||||||
|
}
|
||||||
|
|
||||||
|
TUniqueId CMagdolite::FindSuitableTarget(CStateManager& mgr, EScriptObjectState state, EScriptObjectMessage msg) {
|
||||||
|
float lastDistance = FLT_MAX;
|
||||||
|
int wpCount = 0;
|
||||||
|
float maxDistanceSq =
|
||||||
|
x754_29_ ? x3bc_detectionRange * x3bc_detectionRange : x300_maxAttackRange * x300_maxAttackRange;
|
||||||
|
|
||||||
|
TUniqueId tmpId = kInvalidUniqueId;
|
||||||
|
for (const auto& conn : x20_conns) {
|
||||||
|
if (conn.x0_state != state || conn.x4_msg != msg)
|
||||||
|
continue;
|
||||||
|
TUniqueId uid = mgr.GetIdForScript(conn.x8_objId);
|
||||||
|
if (const CEntity* ent = mgr.GetObjectById(uid)) {
|
||||||
|
if (!ent->GetActive())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (TCastToConstPtr<CScriptWaypoint> wp = ent) {
|
||||||
|
++wpCount;
|
||||||
|
const float dist = (wp->GetTranslation() - mgr.GetPlayer().GetTranslation()).magSquared();
|
||||||
|
if (dist < maxDistanceSq) {
|
||||||
|
if (dist < lastDistance) {
|
||||||
|
lastDistance = dist;
|
||||||
|
tmpId = uid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!x754_29_) {
|
||||||
|
int skipCount = mgr.GetActiveRandom()->Next();
|
||||||
|
skipCount = skipCount - (skipCount / wpCount) * wpCount;
|
||||||
|
for (const auto& conn : x20_conns) {
|
||||||
|
if (conn.x0_state != state || conn.x4_msg != msg)
|
||||||
|
continue;
|
||||||
|
TUniqueId uid = mgr.GetIdForScript(conn.x8_objId);
|
||||||
|
if (const CEntity* ent = mgr.GetObjectById(uid)) {
|
||||||
|
if (!ent->GetActive())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (TCastToConstPtr<CScriptWaypoint> wp = ent) {
|
||||||
|
tmpId = uid;
|
||||||
|
if (skipCount == 0)
|
||||||
|
break;
|
||||||
|
--skipCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return tmpId;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace urde::MP1
|
} // namespace urde::MP1
|
||||||
|
|
|
@ -1,9 +1,14 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Runtime/Character/CBoneTracking.hpp"
|
#include "Runtime/Character/CBoneTracking.hpp"
|
||||||
|
#include "Runtime/Weapon/CFlameInfo.hpp"
|
||||||
#include "Runtime/World/CPatterned.hpp"
|
#include "Runtime/World/CPatterned.hpp"
|
||||||
|
|
||||||
namespace urde::MP1 {
|
namespace urde {
|
||||||
|
class CCollisionActorManager;
|
||||||
|
class CSkinnedModel;
|
||||||
|
class CWeaponDescription;
|
||||||
|
namespace MP1 {
|
||||||
class CMagdolite : public CPatterned {
|
class CMagdolite : public CPatterned {
|
||||||
public:
|
public:
|
||||||
class CMagdoliteData {
|
class CMagdoliteData {
|
||||||
|
@ -26,15 +31,95 @@ private:
|
||||||
float x574_;
|
float x574_;
|
||||||
float x578_;
|
float x578_;
|
||||||
float x57c_;
|
float x57c_;
|
||||||
u32 x580_;
|
std::unique_ptr<CCollisionActorManager> x580_;
|
||||||
CBoneTracking x584_boneTracker;
|
CBoneTracking x584_boneTracker;
|
||||||
|
CDamageVulnerability x5bc_;
|
||||||
|
CDamageVulnerability x624_;
|
||||||
|
/* x68c_ */
|
||||||
|
TLockedToken<CSkinnedModel> x690_headlessModel;
|
||||||
|
TToken<CModel> x698_originalModel;
|
||||||
|
rstl::reserved_vector<TUniqueId, 5> x69c_;
|
||||||
|
CFlameInfo x6a8_;
|
||||||
|
TUniqueId x6c8_flameThrowerId = kInvalidUniqueId;
|
||||||
|
TLockedToken<CWeaponDescription> x6cc_;
|
||||||
|
CDamageInfo x6d4_;
|
||||||
|
CDamageInfo x6f0_;
|
||||||
|
float x70c_;
|
||||||
|
zeus::CVector3f x710_;
|
||||||
|
zeus::CVector3f x71c_;
|
||||||
|
zeus::CVector3f x728_;
|
||||||
|
float x734_ = 0.f;
|
||||||
|
float x738_ = 0.f;
|
||||||
|
float x73c_ = 0.f;
|
||||||
|
float x740_ = 0.f;
|
||||||
|
float x744_;
|
||||||
|
float x748_;
|
||||||
|
float x74c_;
|
||||||
|
u32 x750_ = 0;
|
||||||
|
#if 0
|
||||||
|
bool x754_24_ : 1 = false;
|
||||||
|
bool x754_25_ : 1 = false;
|
||||||
|
bool x754_26_ : 1 = false;
|
||||||
|
bool x754_27_ : 1 = false;
|
||||||
|
bool x754_28_ : 1 = false;
|
||||||
|
bool x754_29_ : 1 = true;
|
||||||
|
bool x754_30_ : 1 = false;
|
||||||
|
#else
|
||||||
|
bool x754_24_ = false;
|
||||||
|
bool x754_25_ = false;
|
||||||
|
bool x754_26_ = false;
|
||||||
|
bool x754_27_ = false;
|
||||||
|
bool x754_28_ = false;
|
||||||
|
bool x754_29_ = true;
|
||||||
|
bool x754_30_ = false;
|
||||||
|
#endif
|
||||||
|
float x758_ = 0.f;
|
||||||
|
|
||||||
|
void ApplyContactDamage(TUniqueId uid, CStateManager& mgr);
|
||||||
|
void SetupCollisionActors(CStateManager& mgr);
|
||||||
|
void CreateFlameThrower(CStateManager& mgr);
|
||||||
|
void LaunchFlameThrower(CStateManager& mgr, bool fire);
|
||||||
|
void UpdateOrientation(CStateManager& mgr);
|
||||||
|
TUniqueId FindSuitableTarget(CStateManager& mgr, EScriptObjectState state, EScriptObjectMessage msg);
|
||||||
public:
|
public:
|
||||||
DEFINE_PATTERNED(Magdolite)
|
DEFINE_PATTERNED(Magdolite)
|
||||||
CMagdolite(TUniqueId, std::string_view, const CEntityInfo&, const zeus::CTransform&, CModelData&&,
|
CMagdolite(TUniqueId, std::string_view, const CEntityInfo&, const zeus::CTransform&, CModelData&&,
|
||||||
const CPatternedInfo&, const CActorParameters&, float, float, const CDamageInfo&, const CDamageInfo&,
|
const CPatternedInfo&, const CActorParameters&, float, float, const CDamageInfo&, const CDamageInfo&,
|
||||||
const CDamageVulnerability&, const CDamageVulnerability&, CAssetId, CAssetId, float, float, float, float,
|
const CDamageVulnerability&, const CDamageVulnerability&, CAssetId, CAssetId, float, float, float, float,
|
||||||
const CMagdoliteData&, float, float, float);
|
const CFlameInfo& flameInfo, float, float, float);
|
||||||
|
|
||||||
void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&) override;
|
void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&) override;
|
||||||
|
void Think(float dt, CStateManager& mgr) override;
|
||||||
|
void Touch(CActor&, CStateManager&) override {};
|
||||||
|
const CDamageVulnerability* GetDamageVulnerability() const override {
|
||||||
|
return x400_25_alive ? CAi::GetDamageVulnerability() : &CDamageVulnerability::ImmuneVulnerabilty();
|
||||||
|
}
|
||||||
|
|
||||||
|
const CDamageVulnerability* GetDamageVulnerability(const zeus::CVector3f&, const zeus::CVector3f&,
|
||||||
|
const CDamageInfo&) const override {
|
||||||
|
return GetDamageVulnerability();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DoUserAnimEvent(CStateManager& mgr, const CInt32POINode& node, EUserEventType type, float dt) override;
|
||||||
|
void Death(CStateManager& mgr, const zeus::CVector3f& direction, EScriptObjectState state) override;
|
||||||
|
void FluidFXThink(EFluidState state, CScriptWater& water, CStateManager& mgr) override;
|
||||||
|
void SelectTarget(CStateManager& mgr, EStateMsg msg, float arg) override;
|
||||||
|
void Generate(CStateManager& mgr, EStateMsg msg, float arg) override;
|
||||||
|
void Deactivate(CStateManager& mgr, EStateMsg msg, float arg) override;
|
||||||
|
void Attack(CStateManager& mgr, EStateMsg msg, float arg) override;
|
||||||
|
void Active(CStateManager& mgr, EStateMsg msg, float arg) override;
|
||||||
|
void InActive(CStateManager& mgr, EStateMsg msg, float arg) override;
|
||||||
|
void GetUp(CStateManager& mgr, EStateMsg msg, float arg) override;
|
||||||
|
void Taunt(CStateManager& mgr, EStateMsg msg, float arg) override;
|
||||||
|
void Lurk(CStateManager& mgr, EStateMsg msg, float arg) override;
|
||||||
|
void ProjectileAttack(CStateManager& mgr, EStateMsg msg, float arg) override;
|
||||||
|
void Flinch(CStateManager& mgr, EStateMsg msg, float arg) override;
|
||||||
|
void Retreat(CStateManager& mgr, EStateMsg msg, float arg) override;
|
||||||
|
bool InAttackPosition(CStateManager& mgr, float arg) override;
|
||||||
|
bool Leash(CStateManager& mgr, float arg) override;
|
||||||
|
bool HasAttackPattern(CStateManager& mgr, float arg) override;
|
||||||
|
bool LineOfSight(CStateManager& mgr, float arg) override;
|
||||||
|
bool ShouldRetreat(CStateManager& mgr, float arg) override;
|
||||||
};
|
};
|
||||||
} // namespace urde::MP1
|
} // namespace MP1
|
||||||
|
} // namespace urde
|
||||||
|
|
|
@ -157,12 +157,15 @@ constexpr std::array skWingEffects{
|
||||||
"WingSparks8"sv,
|
"WingSparks8"sv,
|
||||||
};
|
};
|
||||||
|
|
||||||
constexpr std::array<SOBBRadiiJointInfo, 4> skTail{{{"Tail_1", "Tail_3", 0.66f},
|
constexpr std::array<SOBBRadiiJointInfo, 4> skTail{{
|
||||||
|
{"Tail_1", "Tail_3", 0.66f},
|
||||||
{"Tail_3", "Tail_5", 0.66f},
|
{"Tail_3", "Tail_5", 0.66f},
|
||||||
{"Tail_5", "Tail_7", 0.66f},
|
{"Tail_5", "Tail_7", 0.66f},
|
||||||
{"Tail_7", "Tail_9", 0.66f}}};
|
{"Tail_7", "Tail_9", 0.66f},
|
||||||
|
}};
|
||||||
|
|
||||||
constexpr std::array<SSphereJointInfo, 10> skSphereJoints{{{"Skeleton_Root", 0.6f},
|
constexpr std::array<SSphereJointInfo, 10> skSphereJoints{{
|
||||||
|
{"Skeleton_Root", 0.6f},
|
||||||
{"Spine_2", 0.6f},
|
{"Spine_2", 0.6f},
|
||||||
{"breastPlate_LCTR", 0.6f},
|
{"breastPlate_LCTR", 0.6f},
|
||||||
{"Head_1", 0.6f},
|
{"Head_1", 0.6f},
|
||||||
|
@ -171,7 +174,8 @@ constexpr std::array<SSphereJointInfo, 10> skSphereJoints{{{"Skeleton_Root", 0.6
|
||||||
{"L_ankle", 0.6f},
|
{"L_ankle", 0.6f},
|
||||||
{"R_ankle", 0.6f},
|
{"R_ankle", 0.6f},
|
||||||
{"L_pinky_1", 0.4f},
|
{"L_pinky_1", 0.4f},
|
||||||
{"R_pinky_1", 0.4f}}};
|
{"R_pinky_1", 0.4f},
|
||||||
|
}};
|
||||||
|
|
||||||
struct SSomeRidleyStruct3 {
|
struct SSomeRidleyStruct3 {
|
||||||
float x0_;
|
float x0_;
|
||||||
|
|
|
@ -198,7 +198,7 @@ void CSeedling::Generate(CStateManager& mgr, EStateMsg msg, float) {
|
||||||
if (msg == EStateMsg::Activate)
|
if (msg == EStateMsg::Activate)
|
||||||
x32c_animState = EAnimState::Ready;
|
x32c_animState = EAnimState::Ready;
|
||||||
else if (msg == EStateMsg::Update)
|
else if (msg == EStateMsg::Update)
|
||||||
TryCommand(mgr, pas::EAnimationState::Generate, &CPatterned::TryGenerate, 0);
|
TryCommand(mgr, pas::EAnimationState::Generate, &CPatterned::TryGenerateNoXf, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CSeedling::ShouldAttack(CStateManager& mgr, float) {
|
bool CSeedling::ShouldAttack(CStateManager& mgr, float) {
|
||||||
|
|
|
@ -3,6 +3,14 @@
|
||||||
namespace urde {
|
namespace urde {
|
||||||
|
|
||||||
CFlameInfo::CFlameInfo(s32 w1, s32 w2, CAssetId flameFxId, s32 w3, float f1, float f2, float f3)
|
CFlameInfo::CFlameInfo(s32 w1, s32 w2, CAssetId flameFxId, s32 w3, float f1, float f2, float f3)
|
||||||
: x0_(w1), x4_attributes(w2), x8_flameFxId(flameFxId), xc_length(w3), x10_(f1), x18_(f2), x1c_(f3) {}
|
: x0_propertyCount(w1), x4_attributes(w2), x8_flameFxId(flameFxId), xc_length(w3), x10_(f1), x18_(f2), x1c_(f3) {}
|
||||||
|
|
||||||
|
CFlameInfo::CFlameInfo(CInputStream& in)
|
||||||
|
: x0_propertyCount(in.readUint32Big())
|
||||||
|
, x4_attributes(in.readUint32Big())
|
||||||
|
, x8_flameFxId(in)
|
||||||
|
, xc_length(in.readUint32Big())
|
||||||
|
, x10_(in.readFloatBig())
|
||||||
|
, x18_(in.readFloatBig())
|
||||||
|
, x1c_(in.readFloatBig()) {}
|
||||||
} // namespace urde
|
} // namespace urde
|
||||||
|
|
|
@ -1,11 +1,12 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Runtime/Weapon/CGameProjectile.hpp"
|
#include "Runtime/Weapon/CGameProjectile.hpp"
|
||||||
|
#include "Runtime/IOStreams.hpp"
|
||||||
|
|
||||||
namespace urde {
|
namespace urde {
|
||||||
class CFlameInfo {
|
class CFlameInfo {
|
||||||
friend class CFlameThrower;
|
friend class CFlameThrower;
|
||||||
s32 x0_;
|
s32 x0_propertyCount;
|
||||||
s32 x4_attributes;
|
s32 x4_attributes;
|
||||||
CAssetId x8_flameFxId;
|
CAssetId x8_flameFxId;
|
||||||
s32 xc_length;
|
s32 xc_length;
|
||||||
|
@ -15,6 +16,7 @@ class CFlameInfo {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
CFlameInfo(s32, s32, CAssetId, s32, float, float, float);
|
CFlameInfo(s32, s32, CAssetId, s32, float, float, float);
|
||||||
|
CFlameInfo(CInputStream& in);
|
||||||
|
|
||||||
s32 GetAttributes() const { return x4_attributes; }
|
s32 GetAttributes() const { return x4_attributes; }
|
||||||
s32 GetLength() const { return xc_length; }
|
s32 GetLength() const { return xc_length; }
|
||||||
|
|
|
@ -651,8 +651,10 @@ bool CPatterned::Leash(CStateManager&, float arg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CPatterned::InDetectionRange(CStateManager& mgr, float arg) {
|
bool CPatterned::InDetectionRange(CStateManager& mgr, float arg) {
|
||||||
zeus::CVector3f delta = mgr.GetPlayer().GetTranslation() - GetTranslation();
|
zeus::CVector3f delta = GetTranslation() - mgr.GetPlayer().GetTranslation();
|
||||||
if (delta.magSquared() < x3bc_detectionRange * x3bc_detectionRange) {
|
const float maxRange = x3bc_detectionRange * x3bc_detectionRange;
|
||||||
|
const float dist = delta.magSquared();
|
||||||
|
if (dist < maxRange) {
|
||||||
if (x3c0_detectionHeightRange > 0.f)
|
if (x3c0_detectionHeightRange > 0.f)
|
||||||
return delta.z() * delta.z() < x3c0_detectionHeightRange * x3c0_detectionHeightRange;
|
return delta.z() * delta.z() < x3c0_detectionHeightRange * x3c0_detectionHeightRange;
|
||||||
return true;
|
return true;
|
||||||
|
@ -884,7 +886,11 @@ void CPatterned::TryMeleeAttack(CStateManager& mgr, int 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, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
void CPatterned::TryGenerateNoXf(CStateManager& mgr, int arg) {
|
||||||
|
x450_bodyController->GetCommandMgr().DeliverCmd(CBCGenerateCmd(pas::EGenerateType::Zero, x2e0_destPos, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPatterned::TryJump(CStateManager& mgr, int arg) {
|
void CPatterned::TryJump(CStateManager& mgr, int arg) {
|
||||||
|
@ -939,6 +945,10 @@ void CPatterned::TryGenerateDeactivate(urde::CStateManager& mgr, int arg) {
|
||||||
x450_bodyController->GetCommandMgr().DeliverCmd(CBCGenerateCmd(pas::EGenerateType(arg), zeus::skZero3f));
|
x450_bodyController->GetCommandMgr().DeliverCmd(CBCGenerateCmd(pas::EGenerateType(arg), zeus::skZero3f));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CPatterned::TryStep(CStateManager& mgr, int arg) {
|
||||||
|
x450_bodyController->GetCommandMgr().DeliverCmd(CBCStepCmd(pas::EStepDirection(arg), pas::EStepType::Normal));
|
||||||
|
}
|
||||||
|
|
||||||
void CPatterned::BuildBodyController(EBodyType bodyType) {
|
void CPatterned::BuildBodyController(EBodyType bodyType) {
|
||||||
if (x450_bodyController)
|
if (x450_bodyController)
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -322,6 +322,7 @@ public:
|
||||||
void TryProjectileAttack(CStateManager& mgr, int arg);
|
void TryProjectileAttack(CStateManager& mgr, int arg);
|
||||||
void TryMeleeAttack(CStateManager& mgr, int arg);
|
void TryMeleeAttack(CStateManager& mgr, int arg);
|
||||||
void TryGenerate(CStateManager& mgr, int arg);
|
void TryGenerate(CStateManager& mgr, int arg);
|
||||||
|
void TryGenerateNoXf(CStateManager& mgr, int arg);
|
||||||
void TryJump(CStateManager& mgr, int arg);
|
void TryJump(CStateManager& mgr, int arg);
|
||||||
void TryTurn(CStateManager& mgr, int arg);
|
void TryTurn(CStateManager& mgr, int arg);
|
||||||
void TryGetUp(CStateManager& mgr, int arg);
|
void TryGetUp(CStateManager& mgr, int arg);
|
||||||
|
@ -334,6 +335,7 @@ public:
|
||||||
void TryWallHang(CStateManager& mgr, int arg);
|
void TryWallHang(CStateManager& mgr, int arg);
|
||||||
void TryKnockBack(CStateManager& mgr, int arg);
|
void TryKnockBack(CStateManager& mgr, int arg);
|
||||||
void TryGenerateDeactivate(CStateManager& mgr, int arg);
|
void TryGenerateDeactivate(CStateManager& mgr, int arg);
|
||||||
|
void TryStep(CStateManager& mgr, int arg);
|
||||||
|
|
||||||
virtual bool KnockbackWhenFrozen() const { return true; }
|
virtual bool KnockbackWhenFrozen() const { return true; }
|
||||||
virtual void MassiveDeath(CStateManager& mgr);
|
virtual void MassiveDeath(CStateManager& mgr);
|
||||||
|
|
|
@ -65,6 +65,8 @@ void CStateMachineState::Update(CStateManager& mgr, CAi& ai, float delta) {
|
||||||
if (x4_state) {
|
if (x4_state) {
|
||||||
x8_time += delta;
|
x8_time += delta;
|
||||||
x4_state->CallFunc(mgr, ai, EStateMsg::Update, delta);
|
x4_state->CallFunc(mgr, ai, EStateMsg::Update, delta);
|
||||||
|
fmt::print(fmt("Update: {} {} {} - {} {}\n"), ai.GetUniqueId(), ai.GetEditorId(), ai.GetName(),
|
||||||
|
x4_state->xc_name, int(x4_state - x0_machine->GetStateVector().data()));
|
||||||
for (int i = 0; i < x4_state->GetNumTriggers(); ++i) {
|
for (int i = 0; i < x4_state->GetNumTriggers(); ++i) {
|
||||||
CAiTrigger* trig = x4_state->GetTrig(i);
|
CAiTrigger* trig = x4_state->GetTrig(i);
|
||||||
CAiState* state = nullptr;
|
CAiState* state = nullptr;
|
||||||
|
|
|
@ -3019,7 +3019,7 @@ CEntity* ScriptLoader::LoadMagdolite(CStateManager& mgr, CInputStream& in, int p
|
||||||
float f4 = in.readFloatBig();
|
float f4 = in.readFloatBig();
|
||||||
float f5 = in.readFloatBig();
|
float f5 = in.readFloatBig();
|
||||||
float f6 = in.readFloatBig();
|
float f6 = in.readFloatBig();
|
||||||
MP1::CMagdolite::CMagdoliteData magData(in);
|
CFlameInfo flameInfo(in);
|
||||||
float f7 = in.readFloatBig();
|
float f7 = in.readFloatBig();
|
||||||
float f8 = in.readFloatBig();
|
float f8 = in.readFloatBig();
|
||||||
float f9 = in.readFloatBig();
|
float f9 = in.readFloatBig();
|
||||||
|
@ -3030,7 +3030,7 @@ CEntity* ScriptLoader::LoadMagdolite(CStateManager& mgr, CInputStream& in, int p
|
||||||
|
|
||||||
return new MP1::CMagdolite(mgr.AllocateUniqueId(), actorHead.x0_name, info, actorHead.x10_transform,
|
return new MP1::CMagdolite(mgr.AllocateUniqueId(), actorHead.x0_name, info, actorHead.x10_transform,
|
||||||
std::move(modelData), pInfo, actorParameters, f1, f2, damageInfo1, damageInfo2,
|
std::move(modelData), pInfo, actorParameters, f1, f2, damageInfo1, damageInfo2,
|
||||||
damageVulnerability1, damageVulnerability2, modelId, skinId, f3, f4, f5, f6, magData, f7,
|
damageVulnerability1, damageVulnerability2, modelId, skinId, f3, f4, f5, f6, flameInfo, f7,
|
||||||
f8, f9);
|
f8, f9);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue