From d033ddeb1dee36c81ec5f1f30adcb3994f059c06 Mon Sep 17 00:00:00 2001 From: Phillip Stephens Date: Tue, 31 Mar 2020 06:38:18 -0700 Subject: [PATCH 1/9] Initial CDrone imp --- DataSpec/DNAMP1/ScriptObjects/Drone.hpp | 6 +- Runtime/MP1/World/CDrone.cpp | 32 +++++++++ Runtime/MP1/World/CDrone.hpp | 21 ++++++ Runtime/MP1/World/CMakeLists.txt | 5 ++ Runtime/World/CVisorFlare.hpp | 2 + Runtime/World/ScriptLoader.cpp | 87 ++++++++++++++++++++++++- 6 files changed, 149 insertions(+), 4 deletions(-) create mode 100644 Runtime/MP1/World/CDrone.cpp create mode 100644 Runtime/MP1/World/CDrone.hpp diff --git a/DataSpec/DNAMP1/ScriptObjects/Drone.hpp b/DataSpec/DNAMP1/ScriptObjects/Drone.hpp index daf8c0665..6d75d1eba 100644 --- a/DataSpec/DNAMP1/ScriptObjects/Drone.hpp +++ b/DataSpec/DNAMP1/ScriptObjects/Drone.hpp @@ -18,9 +18,9 @@ struct Drone : IScriptObject { DamageInfo damageInfo1; Value unknown3; DamageInfo damageInfo2; - Value unknown4; - Value unknown5; - Value unknown6; + UniqueID32 unknown4; + UniqueID32 unknown5; + UniqueID32 unknown6; FlareDefinition flareDefinition1; FlareDefinition flareDefinition2; FlareDefinition flareDefinition3; diff --git a/Runtime/MP1/World/CDrone.cpp b/Runtime/MP1/World/CDrone.cpp new file mode 100644 index 000000000..f2c2b86af --- /dev/null +++ b/Runtime/MP1/World/CDrone.cpp @@ -0,0 +1,32 @@ +#include "Runtime/MP1/World/CDrone.hpp" + +#include "TCastTo.hpp" // Generated file, do not modify include path + +namespace urde::MP1 { +CDrone::CDrone(TUniqueId uid, std::string_view name, EFlavorType flavor, const CEntityInfo& info, + const zeus::CTransform& xf, float f1, CModelData&& mData, const CPatternedInfo& pInfo, + const CActorParameters& actParms, EMovementType movement, EColliderType colliderType, EBodyType bodyType, + const CDamageInfo& dInfo1, CAssetId w1, const CDamageInfo& dInfo2, CAssetId w2, + const std::vector& flares, float f2, float f3, float f4, float f5, float f6, + float f7, float f8, float f9, float f10, float f11, float f12, float f13, float f14, float f15, + float f16, float f17, float f18, float f19, float f20, float f21, float f22, float f23, float f24, + CAssetId w3, bool b1) +: CPatterned(ECharacter::Drone, uid, name, flavor, info, xf, std::move(mData), pInfo, movement, colliderType, bodyType, + actParms, EKnockBackVariant(flavor == EFlavorType::Zero)) {} + +void CDrone::Accept(IVisitor& visitor) { visitor.Visit(this); } +void CDrone::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CStateManager& mgr) { + CPatterned::AcceptScriptMsg(msg, sender, mgr); + + switch (msg) { + case EScriptObjectMessage::Registered: + x450_bodyController->Activate(mgr); + x450_bodyController->SetLocomotionType(pas::ELocomotionType::Lurk); + x450_bodyController->BodyStateInfo().SetMaximumPitch(0.f); + break; + default: + break; + } +} + +} // namespace urde::MP1 diff --git a/Runtime/MP1/World/CDrone.hpp b/Runtime/MP1/World/CDrone.hpp new file mode 100644 index 000000000..86e4d1689 --- /dev/null +++ b/Runtime/MP1/World/CDrone.hpp @@ -0,0 +1,21 @@ +#pragma once + +#include "Runtime/World/CPatterned.hpp" +#include "Runtime/World/CVisorFlare.hpp" + +namespace urde::MP1 { +class CDrone : public CPatterned { +public: + DEFINE_PATTERNED(Drone); + CDrone(TUniqueId uid, std::string_view name, EFlavorType flavor, const CEntityInfo& info, const zeus::CTransform& xf, + float f1, CModelData&& mData, const CPatternedInfo& pInfo, const CActorParameters& actParms, + EMovementType movement, EColliderType colliderType, EBodyType bodyType, const CDamageInfo& dInfo1, CAssetId w1, + const CDamageInfo& dInfo2, CAssetId w2, const std::vector& flares, float f2, float f3, + float f4, float f5, float f6, float f7, float f8, float f9, float f10, float f11, float f12, float f13, + float f14, float f15, float f16, float f17, float f18, float f19, float f20, float f21, float f22, float f23, + float f24, CAssetId w3, bool b1); + + void Accept(IVisitor& visitor); + void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CStateManager& mgr); +}; +} // namespace urde::MP1 diff --git a/Runtime/MP1/World/CMakeLists.txt b/Runtime/MP1/World/CMakeLists.txt index e0c88ce2e..265e3c6b3 100644 --- a/Runtime/MP1/World/CMakeLists.txt +++ b/Runtime/MP1/World/CMakeLists.txt @@ -9,6 +9,11 @@ set(MP1_WORLD_SOURCES CBurrower.hpp CBurrower.cpp CChozoGhost.hpp CChozoGhost.cpp CElitePirate.hpp CElitePirate.cpp + CDrone.hpp CDrone.cpp + CSpacePirate.hpp CSpacePirate.cpp + CParasite.hpp CParasite.cpp + CBabygoth.hpp CBabygoth.cpp + CTryclops.hpp CTryclops.cpp CEnergyBall.hpp CEnergyBall.cpp CEyeball.hpp CEyeball.cpp CFireFlea.hpp CFireFlea.cpp diff --git a/Runtime/World/CVisorFlare.hpp b/Runtime/World/CVisorFlare.hpp index b1c084de2..5dd42fabc 100644 --- a/Runtime/World/CVisorFlare.hpp +++ b/Runtime/World/CVisorFlare.hpp @@ -25,6 +25,8 @@ public: zeus::CColor x10_color; public: + CFlareDef()=default; + CFlareDef(const CFlareDef&)=default; CFlareDef(const TToken& tex, float f1, float f2, const zeus::CColor& color) : x0_tex(tex), x8_f1(f1), xc_f2(f2), x10_color(color) { x0_tex.Lock(); diff --git a/Runtime/World/ScriptLoader.cpp b/Runtime/World/ScriptLoader.cpp index 1f2ad0087..5ab636679 100644 --- a/Runtime/World/ScriptLoader.cpp +++ b/Runtime/World/ScriptLoader.cpp @@ -27,6 +27,7 @@ #include "Runtime/MP1/World/CJellyZap.hpp" #include "Runtime/MP1/World/CMagdolite.hpp" #include "Runtime/MP1/World/CMetaree.hpp" +#include "Runtime/MP1/World/CDrone.hpp" #include "Runtime/MP1/World/CMetroid.hpp" #include "Runtime/MP1/World/CMetroidBeta.hpp" #include "Runtime/MP1/World/CMetroidPrimeRelay.hpp" @@ -2001,8 +2002,92 @@ CEntity* ScriptLoader::LoadPointOfInterest(CStateManager& mgr, CInputStream& in, pointSize); } +std::optional LoadFlareDef(CInputStream& in) { + if (in.readUint32Big() == 4) { + CAssetId textureId(in); + float f1 = in.readFloatBig(); + float f2 = in.readFloatBig(); + zeus::CColor color = zeus::CColor::ReadRGBABig(in); + if (textureId.IsValid()) { + return {CVisorFlare::CFlareDef(g_SimplePool->GetObj({SBIG('TXTR'), textureId}), f1, f2, color)}; + } + } + + return {}; +} + CEntity* ScriptLoader::LoadDrone(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info) { - return nullptr; + if (propCount != 45 && EnsurePropertyCount(propCount, 45, "Drone")) + 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); + float f1 = in.readFloatBig(); + const auto [patternedValid, patternedPropCount] = CPatternedInfo::HasCorrectParameterCount(in); + if (!patternedValid) + return nullptr; + CPatternedInfo pInfo(in, patternedPropCount); + CActorParameters actParms = LoadActorParameters(in); + CDamageInfo dInfo1(in); + u32 w1 = in.readUint32Big(); + CDamageInfo dInfo2(in); + CAssetId aId1(in); + in.seek(4); // Unused + CAssetId aId2(in); + std::optional def1 = LoadFlareDef(in); + std::optional def2 = LoadFlareDef(in); + std::optional def3 = LoadFlareDef(in); + std::optional def4 = LoadFlareDef(in); + std::optional def5 = LoadFlareDef(in); + std::vector flares(5); + if (def1) + flares.push_back(*def1); + if (def2) + flares.push_back(*def2); + if (def3) + flares.push_back(*def3); + if (def4) + flares.push_back(*def4); + if (def4) + flares.push_back(*def4); + + const auto& animParms = pInfo.GetAnimationParameters(); + if (g_ResFactory->GetResourceTypeById(animParms.GetACSFile()) != SBIG('ANCS')) + return nullptr; + + float f2 = in.readFloatBig(); + float f3 = in.readFloatBig(); + float f4 = in.readFloatBig(); + float f5 = in.readFloatBig(); + float f6 = in.readFloatBig(); + float f7 = in.readFloatBig(); + float f8 = in.readFloatBig(); + float f9 = in.readFloatBig(); + float f10 = in.readFloatBig(); + float f11 = in.readFloatBig(); + float f12 = in.readFloatBig(); + float f13 = in.readFloatBig(); + float f14 = in.readFloatBig(); + float f15 = in.readFloatBig(); + float f16 = in.readFloatBig(); + float f17 = in.readFloatBig(); + float f18 = in.readFloatBig(); + float f19 = in.readFloatBig(); + float f20 = in.readFloatBig(); + float f21 = in.readFloatBig(); + float f22 = in.readFloatBig(); + float f23 = in.readFloatBig(); + float f24 = in.readFloatBig(); + CAssetId crscId(in); + bool b1 = in.readBool(); + CModelData mData( + CAnimRes(animParms.GetACSFile(), animParms.GetCharacter(), scale, animParms.GetInitialAnimation(), true)); + return new MP1::CDrone(mgr.AllocateUniqueId(), name, flavor, info, xf, f1, std::move(mData), pInfo, actParms, + CPatterned::EMovementType::Flyer, CPatterned::EColliderType::One, EBodyType::Pitchable, dInfo1, + aId2, dInfo2, aId2, flares, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, + f17, f18, f19, f20, f21, f22, f23, f24, crscId, b1); } CEntity* ScriptLoader::LoadMetroid(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info) { From ff0cf969c2aca212abb7e5ba112bc0eb4053b3b9 Mon Sep 17 00:00:00 2001 From: Phillip Stephens Date: Sat, 4 Apr 2020 04:46:22 -0700 Subject: [PATCH 2/9] Initial CDrone imps --- DataSpec/DNAMP1/ScriptObjects/Drone.hpp | 4 +- Runtime/MP1/World/CDrone.cpp | 77 +++++++++++++++++-- Runtime/MP1/World/CDrone.hpp | 98 +++++++++++++++++++++++-- Runtime/World/ScriptLoader.cpp | 5 +- 4 files changed, 170 insertions(+), 14 deletions(-) diff --git a/DataSpec/DNAMP1/ScriptObjects/Drone.hpp b/DataSpec/DNAMP1/ScriptObjects/Drone.hpp index 6d75d1eba..af29fad9d 100644 --- a/DataSpec/DNAMP1/ScriptObjects/Drone.hpp +++ b/DataSpec/DNAMP1/ScriptObjects/Drone.hpp @@ -19,7 +19,7 @@ struct Drone : IScriptObject { Value unknown3; DamageInfo damageInfo2; UniqueID32 unknown4; - UniqueID32 unknown5; + Value unused; UniqueID32 unknown6; FlareDefinition flareDefinition1; FlareDefinition flareDefinition2; @@ -73,6 +73,8 @@ struct Drone : IScriptObject { void gatherDependencies(std::vector& pathsOut, std::vector& lazyOut) const override { + g_curSpec->flattenDependencies(unknown4, pathsOut); + g_curSpec->flattenDependencies(unknown6, pathsOut); g_curSpec->flattenDependencies(crsc, pathsOut); flareDefinition1.depIDs(pathsOut); flareDefinition2.depIDs(pathsOut); diff --git a/Runtime/MP1/World/CDrone.cpp b/Runtime/MP1/World/CDrone.cpp index f2c2b86af..1dbbca48b 100644 --- a/Runtime/MP1/World/CDrone.cpp +++ b/Runtime/MP1/World/CDrone.cpp @@ -1,18 +1,76 @@ #include "Runtime/MP1/World/CDrone.hpp" +#include "Runtime/Audio/CSfxManager.hpp" +#include "Runtime/World/CPatternedInfo.hpp" +#include "Runtime/CSimplePool.hpp" +#include "Runtime/GameGlobalObjects.hpp" + #include "TCastTo.hpp" // Generated file, do not modify include path namespace urde::MP1 { CDrone::CDrone(TUniqueId uid, std::string_view name, EFlavorType flavor, const CEntityInfo& info, const zeus::CTransform& xf, float f1, CModelData&& mData, const CPatternedInfo& pInfo, const CActorParameters& actParms, EMovementType movement, EColliderType colliderType, EBodyType bodyType, - const CDamageInfo& dInfo1, CAssetId w1, const CDamageInfo& dInfo2, CAssetId w2, - const std::vector& flares, float f2, float f3, float f4, float f5, float f6, - float f7, float f8, float f9, float f10, float f11, float f12, float f13, float f14, float f15, - float f16, float f17, float f18, float f19, float f20, float f21, float f22, float f23, float f24, - CAssetId w3, bool b1) + const CDamageInfo& dInfo1, CAssetId aId1, const CDamageInfo& dInfo2, CAssetId aId2, + std::vector flares, float f2, float f3, float f4, float f5, float f6, float f7, + float f8, float f9, float f10, float f11, float f12, float f13, float f14, float f15, float f16, + float f17, float f18, float f19, float f20, CAssetId crscId, float f21, float f22, float f23, float f24, + s32 sId, bool b1) : CPatterned(ECharacter::Drone, uid, name, flavor, info, xf, std::move(mData), pInfo, movement, colliderType, bodyType, - actParms, EKnockBackVariant(flavor == EFlavorType::Zero)) {} + actParms, EKnockBackVariant(flavor == EFlavorType::Zero)) +, x568_(aId1) +, x56c_(g_SimplePool->GetObj({SBIG('CRSC'), crscId})) +, x57c_flares(std::move(flares)) +, x590_(dInfo1) +, x5ac_(dInfo2) +, x5e4_(f23) +, x5ec_(f1) +, x5f0_(f2) +, x5f4_(f3) +, x5f8_(f4) +, x5fc_(f5) +, x600_(f11) +, x608_(f6) +, x60c_(f7) +, x610_(f8) +, x614_(f9) +, x618_(f10) +, x61c_(f12) +, x620_(f20) +, x63c_(f13) +, x640_(f14) +, x648_(f15) +, x64c_(f16) +, x650_(f17) +, x654_(f18) +, x658_(f19) +, x65c_(f21) +, x660_(f22) +, x664_(f24) +, x690_(zeus::CSphere({0.f, 0.f, 1.8f}, 1.1f), CActor::GetMaterialList()) +, x6b0_pathFind(nullptr, 3 + int(b1), pInfo.GetPathfindingIndex(), 1.f, 2.4f) +, x7cc_(CSfxManager::TranslateSFXID(sId)) +, x82c_(std::make_unique(CStaticRes{aId2, zeus::skOne3f})) +, x830_13_(0) +, x830_10_(0) +, x834_24_(false) +, x834_25_(false) +, x834_26_(false) +, x834_27_(false) +, x834_28_(false) +, x834_29_(false) +, x834_30_(false) +, x834_31_(false) +, x835_24_(false) +, x835_25_(b1) +, x835_26_(false) { + UpdateTouchBounds(pInfo.GetHalfExtent()); + x460_knockBackController.SetEnableShock(true); + x460_knockBackController.SetAvailableState(EKnockBackAnimationState::Hurled, false); + x460_knockBackController.SetLocomotionDuringElectrocution(true); + MakeThermalColdAndHot(); + CreateShadow(flavor != EFlavorType::One); +} void CDrone::Accept(IVisitor& visitor) { visitor.Visit(this); } void CDrone::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CStateManager& mgr) { @@ -29,4 +87,11 @@ void CDrone::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CStateM } } +void CDrone::UpdateTouchBounds(float radius) { + const zeus::CTransform xf = GetLctrTransform("Skeleton_Root"sv); + const zeus::CVector3f diff = xf.origin - GetTranslation(); + SetBoundingBox(zeus::CAABox{diff - radius, diff + radius}); + x6b0_pathFind.SetRadius(0.25f + radius); +} + } // namespace urde::MP1 diff --git a/Runtime/MP1/World/CDrone.hpp b/Runtime/MP1/World/CDrone.hpp index 86e4d1689..d27d5866b 100644 --- a/Runtime/MP1/World/CDrone.hpp +++ b/Runtime/MP1/World/CDrone.hpp @@ -1,19 +1,107 @@ #pragma once +#include "Runtime/Collision/CCollidableSphere.hpp" #include "Runtime/World/CPatterned.hpp" +#include "Runtime/World/CPathFindSearch.hpp" #include "Runtime/World/CVisorFlare.hpp" namespace urde::MP1 { class CDrone : public CPatterned { + CAssetId x568_; + TLockedToken x56c_; + CCollisionResponseData* x574_; + TUniqueId x578_ = kInvalidUniqueId; + TUniqueId x57a_ = kInvalidUniqueId; + std::vector x57c_flares; + u32 x58c_ = 2; + CDamageInfo x590_; + CDamageInfo x5ac_; + float x5c8_ = 0.f; + float x5cc_ = 0.f; + float x5d0_ = 0.f; + float x5d4_ = 0.f; + float x5d8_ = 0.f; + float x5dc_ = 0.f; + float x5e0_ = 0.f; + float x5e4_; + float x5e8_ = 0.f; + float x5ec_; + float x5f0_; + float x5f4_; + float x5f8_; + float x5fc_; + float x600_; + float x604_ = 0.f; + float x608_; + float x60c_; + float x610_; + float x614_; + float x618_; + float x61c_; + float x620_; + float x624_ = 0.f; + float x628_ = 0.f; + float x62c_ = 0.f; + float x630_ = 0.f; + float x634_ = 0.f; + float x638_ = 0.f; + float x63c_; + float x640_; + float x644_ = 0.f; + float x648_; + float x64c_; + float x650_; + float x654_; + float x658_; + float x65c_; + float x660_; + float x664_; + float x668_ = 0.f; + float x66c_ = 0.f; + zeus::CVector3f x670_; + zeus::CVector3f x67c_; + TUniqueId x688_ = kInvalidUniqueId; + CCollidableSphere x690_; + CPathFindSearch x6b0_pathFind; + zeus::CAxisAngle x794_; + zeus::CVector3f x7a0_; + float x7ac_ = 0.f; + float x7b0_ = 0.f; + float x7b4_ = 0.f; + float x7b8_ = 0.f; + float x7bc_ = 0.f; + s32 x7c8_ = 0; + s16 x7cc_; + s32 x7d0_ = 0; + rstl::reserved_vector x7d4_; + rstl::reserved_vector x7e0_; + rstl::reserved_vector x7fc_; + rstl::reserved_vector x818_; + rstl::reserved_vector x824_; + std::unique_ptr x82c_; + u8 x830_13_ : 2; + u8 x830_10_ : 2; + bool x834_24_ : 1; + bool x834_25_ : 1; + bool x834_26_ : 1; + bool x834_27_ : 1; + bool x834_28_ : 1; + bool x834_29_ : 1; + bool x834_30_ : 1; + bool x834_31_ : 1; + bool x835_24_ : 1; + bool x835_25_ : 1; + bool x835_26_ : 1; + void UpdateTouchBounds(float radius); public: DEFINE_PATTERNED(Drone); CDrone(TUniqueId uid, std::string_view name, EFlavorType flavor, const CEntityInfo& info, const zeus::CTransform& xf, float f1, CModelData&& mData, const CPatternedInfo& pInfo, const CActorParameters& actParms, - EMovementType movement, EColliderType colliderType, EBodyType bodyType, const CDamageInfo& dInfo1, CAssetId w1, - const CDamageInfo& dInfo2, CAssetId w2, const std::vector& flares, float f2, float f3, - float f4, float f5, float f6, float f7, float f8, float f9, float f10, float f11, float f12, float f13, - float f14, float f15, float f16, float f17, float f18, float f19, float f20, float f21, float f22, float f23, - float f24, CAssetId w3, bool b1); + EMovementType movement, EColliderType colliderType, EBodyType bodyType, const CDamageInfo& dInfo1, + CAssetId aId1, const CDamageInfo& dInfo2, CAssetId aId2, std::vector flares, float f2, + float f3, float f4, float f5, float f6, float f7, float f8, float f9, float f10, float f11, float f12, + float f13, float f14, float f15, float f16, float f17, float f18, float f19, float f20, CAssetId crscId, + float f21, float f22, float f23, float f24, s32 w3, bool b1); void Accept(IVisitor& visitor); void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CStateManager& mgr); diff --git a/Runtime/World/ScriptLoader.cpp b/Runtime/World/ScriptLoader.cpp index 5ab636679..48dc21d59 100644 --- a/Runtime/World/ScriptLoader.cpp +++ b/Runtime/World/ScriptLoader.cpp @@ -2076,18 +2076,19 @@ CEntity* ScriptLoader::LoadDrone(CStateManager& mgr, CInputStream& in, int propC float f18 = in.readFloatBig(); float f19 = in.readFloatBig(); float f20 = in.readFloatBig(); + CAssetId crscId(in); float f21 = in.readFloatBig(); float f22 = in.readFloatBig(); float f23 = in.readFloatBig(); float f24 = in.readFloatBig(); - CAssetId crscId(in); + s32 soundId = in.readUint32Big(); bool b1 = in.readBool(); CModelData mData( CAnimRes(animParms.GetACSFile(), animParms.GetCharacter(), scale, animParms.GetInitialAnimation(), true)); return new MP1::CDrone(mgr.AllocateUniqueId(), name, flavor, info, xf, f1, std::move(mData), pInfo, actParms, CPatterned::EMovementType::Flyer, CPatterned::EColliderType::One, EBodyType::Pitchable, dInfo1, aId2, dInfo2, aId2, flares, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, - f17, f18, f19, f20, f21, f22, f23, f24, crscId, b1); + f17, f18, f19, f20, crscId, f21, f22, f23, f24, soundId, b1); } CEntity* ScriptLoader::LoadMetroid(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info) { From 08b1dbcf4f374cb0939cbdcdb4892bb4c517508c Mon Sep 17 00:00:00 2001 From: Phillip Stephens Date: Sat, 4 Apr 2020 06:55:08 -0700 Subject: [PATCH 3/9] Drone: Implement AcceptScriptMsg --- Runtime/MP1/World/CDrone.cpp | 211 ++++++++++++++++++++++++++++++++++- Runtime/MP1/World/CDrone.hpp | 62 +++++++++- 2 files changed, 267 insertions(+), 6 deletions(-) diff --git a/Runtime/MP1/World/CDrone.cpp b/Runtime/MP1/World/CDrone.cpp index 1dbbca48b..824dde63d 100644 --- a/Runtime/MP1/World/CDrone.cpp +++ b/Runtime/MP1/World/CDrone.cpp @@ -1,9 +1,14 @@ #include "Runtime/MP1/World/CDrone.hpp" #include "Runtime/Audio/CSfxManager.hpp" -#include "Runtime/World/CPatternedInfo.hpp" #include "Runtime/CSimplePool.hpp" +#include "Runtime/CStateManager.hpp" #include "Runtime/GameGlobalObjects.hpp" +#include "Runtime/Weapon/CWeapon.hpp" +#include "Runtime/World/CGameLight.hpp" +#include "Runtime/World/CPatternedInfo.hpp" +#include "Runtime/World/CTeamAiMgr.hpp" +#include "Runtime/World/CWorld.hpp" #include "TCastTo.hpp" // Generated file, do not modify include path @@ -73,20 +78,199 @@ CDrone::CDrone(TUniqueId uid, std::string_view name, EFlavorType flavor, const C } void CDrone::Accept(IVisitor& visitor) { visitor.Visit(this); } +void CDrone::Think(float dt, CStateManager& mgr) { CPatterned::Think(dt, mgr); } + void CDrone::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CStateManager& mgr) { CPatterned::AcceptScriptMsg(msg, sender, mgr); switch (msg) { + case EScriptObjectMessage::Activate: { + SetLightEnabled(mgr, true); + AddToTeam(mgr); + break; + } + case EScriptObjectMessage::Deactivate: + case EScriptObjectMessage::Deleted: { + for (TUniqueId& unkId : x7d4_) { + if (unkId != kInvalidUniqueId) { + mgr.FreeScriptObject(unkId); + unkId = kInvalidUniqueId; + } + } + RemoveFromTeam(mgr); + mgr.GetPlayerState()->GetStaticInterference().RemoveSource(GetUniqueId()); + if (x578_lightId != kInvalidUniqueId) { + mgr.FreeScriptObject(x578_lightId); + } + if (x57a_ != kInvalidUniqueId) { + mgr.FreeScriptObject(x57a_); + } + + if (x7d0_) { + CSfxManager::RemoveEmitter(x7d0_); + x7d0_.reset(); + } + break; + } + case EScriptObjectMessage::Alert: + x834_29_ = true; + break; + case EScriptObjectMessage::OnFloor: + if (!x835_26_ && x834_24_) { + x835_26_ = true; + MassiveFrozenDeath(mgr); + } + break; case EScriptObjectMessage::Registered: x450_bodyController->Activate(mgr); x450_bodyController->SetLocomotionType(pas::ELocomotionType::Lurk); x450_bodyController->BodyStateInfo().SetMaximumPitch(0.f); + x5cc_ = 0.f; + x460_knockBackController.SetEnableFreeze(false); + AddMaterial(EMaterialTypes::AIJoint, mgr); + x578_lightId = mgr.AllocateUniqueId(); + mgr.AddObject(new CGameLight(x578_lightId, GetAreaIdAlways(), GetActive(), "LaserLight"sv, {}, GetUniqueId(), + CLight::BuildPoint(zeus::skZero3f, zeus::skRed), 0, 0, 0.f)); break; + case EScriptObjectMessage::InitializedInArea: { + x6b0_pathFind.SetArea(mgr.GetWorld()->GetAreaAlways(GetAreaIdAlways())->GetPostConstructed()->x10bc_pathArea); + if (x688_teamMgr == kInvalidUniqueId) { + x688_teamMgr = CTeamAiMgr::GetTeamAiMgr(*this, mgr); + if (GetActive()) { + AddToTeam(mgr); + } + } + + x604_ = HealthInfo(mgr)->GetHP(); + x55c_moveScale = 1.f / GetModelData()->GetScale(); + if (x835_25_) + SetSoundEventPitchBend(0); + break; + } default: break; } } +void CDrone::PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) { + CPatterned::PreRender(mgr, frustum); + if (x3fc_flavor == EFlavorType::One) { + if (HasModelData() && GetModelData()->HasAnimData()) { + if (GetModelAlphau8(mgr) == 0) + GetModelData()->GetAnimationData()->BuildPose(); + } + } +} + +void CDrone::AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const { + CPatterned::AddToRenderer(frustum, mgr); +} + +void CDrone::Render(const CStateManager& mgr) const { + bool isOne = x3fc_flavor == EFlavorType::One; + if (!isOne || GetModelAlphau8(mgr) != 0) { + if (isOne && mgr.GetPlayerState()->GetActiveVisor(mgr) == CPlayerState::EPlayerVisor::XRay) { + CGraphics::SetFog(ERglFogMode::PerspLin, 0.f, 75.f, zeus::skBlack); + GetModelData()->GetAnimationData()->GetParticleDB().RenderSystemsToBeDrawnFirst(); + mgr.SetupFogForArea3XRange(GetAreaIdAlways()); + } + CPatterned::Render(mgr); + if (isOne && mgr.GetPlayerState()->GetActiveVisor(mgr) == CPlayerState::EPlayerVisor::XRay) { + CGraphics::SetFog(ERglFogMode::PerspLin, 0.f, 75.f, zeus::skBlack); + GetModelData()->GetAnimationData()->GetParticleDB().RenderSystemsToBeDrawnLast(); + mgr.SetupFogForArea3XRange(GetAreaIdAlways()); + } + + if (isOne && zeus::close_enough(x5dc_, 0)) { + x82c_->Render(mgr, GetLctrTransform("Shield_LCTR"sv), GetActorLights(), + CModelFlags{8, 0, 3, zeus::CColor::lerp({1.f, 0.f, 0.f, 1.f}, zeus::skWhite, x5e8_)}); + } + } +} +bool CDrone::CanRenderUnsorted(const CStateManager& mgr) const { + if (zeus::close_enough(x5dc_, 0.f)) + return false; + return CPatterned::CanRenderUnsorted(mgr); +} + +const CDamageVulnerability* CDrone::GetDamageVulnerability(const zeus::CVector3f&, const zeus::CVector3f& dir, + const CDamageInfo&) const { + if (x3fc_flavor == EFlavorType::One && HitShield(-dir)) { + return &CDamageVulnerability::ImmuneVulnerabilty(); + } + return CAi::GetDamageVulnerability(); +} +void CDrone::Touch(CActor& act, CStateManager& mgr) { + CPatterned::Touch(act, mgr); + if (TCastToPtr weapon = act) { + if (IsAlive()) { + x834_24_ = weapon->GetType() == EWeaponType::Wave; + if (HitShield(weapon->GetTranslation() - GetTranslation())) { + x5e8_ = 1.f; + } + } + } +} + +EWeaponCollisionResponseTypes CDrone::GetCollisionResponseType(const zeus::CVector3f&, const zeus::CVector3f& dir, + const CWeaponMode&, EProjectileAttrib) const { + if (x3fc_flavor == EFlavorType::One && HitShield(-dir)) { + return EWeaponCollisionResponseTypes::Unknown86; + } + return EWeaponCollisionResponseTypes::Unknown36; +} + +void CDrone::DoUserAnimEvent(CStateManager& mgr, const CInt32POINode& node, EUserEventType type, float dt) { + CPatterned::DoUserAnimEvent(mgr, node, type, dt); +} +const CCollisionPrimitive* CDrone::GetCollisionPrimitive() const { return CPhysicsActor::GetCollisionPrimitive(); } +void CDrone::Death(CStateManager& mgr, const zeus::CVector3f& direction, EScriptObjectState state) { + CPatterned::Death(mgr, direction, state); +} +void CDrone::KnockBack(const zeus::CVector3f& backVec, CStateManager& mgr, const CDamageInfo& info, EKnockBackType type, + bool inDeferred, float magnitude) { + CPatterned::KnockBack(backVec, mgr, info, type, inDeferred, magnitude); +} +void CDrone::Patrol(CStateManager& mgr, EStateMsg msg, float dt) { CPatterned::Patrol(mgr, msg, dt); } +void CDrone::PathFind(CStateManager& mgr, EStateMsg msg, float dt) { CPatterned::PathFind(mgr, msg, dt); } +void CDrone::TargetPlayer(CStateManager& mgr, EStateMsg msg, float dt) { CPatterned::TargetPlayer(mgr, msg, dt); } +void CDrone::TargetCover(CStateManager& mgr, EStateMsg msg, float dt) { CAi::TargetCover(mgr, msg, dt); } +void CDrone::Deactivate(CStateManager& mgr, EStateMsg msg, float dt) { CAi::Deactivate(mgr, msg, dt); } +void CDrone::Attack(CStateManager& mgr, EStateMsg msg, float dt) {} +void CDrone::Active(CStateManager& mgr, EStateMsg msg, float dt) { CAi::Active(mgr, msg, dt); } +void CDrone::Flee(CStateManager& mgr, EStateMsg msg, float dt) { CAi::Flee(mgr, msg, dt); } +void CDrone::ProjectileAttack(CStateManager& mgr, EStateMsg msg, float dt) { CAi::ProjectileAttack(mgr, msg, dt); } +void CDrone::TelegraphAttack(CStateManager& mgr, EStateMsg msg, float dt) { CAi::TelegraphAttack(mgr, msg, dt); } +void CDrone::Dodge(CStateManager& mgr, EStateMsg msg, float dt) { CAi::Dodge(mgr, msg, dt); } +void CDrone::Retreat(CStateManager& mgr, EStateMsg msg, float dt) { CAi::Retreat(mgr, msg, dt); } +void CDrone::Cover(CStateManager& mgr, EStateMsg msg, float dt) { CAi::Cover(mgr, msg, dt); } +void CDrone::SpecialAttack(CStateManager& mgr, EStateMsg msg, float dt) { CAi::SpecialAttack(mgr, msg, dt); } +void CDrone::PathFindEx(CStateManager& mgr, EStateMsg msg, float dt) { CAi::PathFindEx(mgr, msg, dt); } +bool CDrone::Leash(CStateManager& mgr, float arg) { return CPatterned::Leash(mgr, arg); } +bool CDrone::InRange(CStateManager& mgr, float arg) { return CPatterned::InRange(mgr, arg); } +bool CDrone::SpotPlayer(CStateManager& mgr, float arg) { return CPatterned::SpotPlayer(mgr, arg); } +bool CDrone::AnimOver(CStateManager& mgr, float arg) { return CPatterned::AnimOver(mgr, arg); } +bool CDrone::ShouldAttack(CStateManager& mgr, float arg) { return CAi::ShouldAttack(mgr, arg); } +bool CDrone::HearShot(CStateManager& mgr, float arg) { return CAi::HearShot(mgr, arg); } +bool CDrone::CoverCheck(CStateManager& mgr, float arg) { return CAi::CoverCheck(mgr, arg); } +bool CDrone::LineOfSight(CStateManager& mgr, float arg) { return CAi::LineOfSight(mgr, arg); } +bool CDrone::ShouldMove(CStateManager& mgr, float arg) { return CAi::ShouldMove(mgr, arg); } +bool CDrone::CodeTrigger(CStateManager& mgr, float arg) { return CPatterned::CodeTrigger(mgr, arg); } +void CDrone::Burn(float duration, float damage) { CPatterned::Burn(duration, damage); } +CPathFindSearch* CDrone::GetSearchPath() { return CPatterned::GetSearchPath(); } + +void CDrone::BuildNearList(EMaterialTypes includeMat, EMaterialTypes excludeMat, + rstl::reserved_vector& listOut, float radius, CStateManager& mgr) { + const zeus::CVector3f pos = GetTranslation(); + mgr.BuildNearList(listOut, zeus::CAABox(pos - radius, pos + radius), + CMaterialFilter::MakeIncludeExclude({includeMat}, {excludeMat}), nullptr); +} +void CDrone::SetLightEnabled(CStateManager& mgr, bool activate) { + mgr.SendScriptMsgAlways(x578_lightId, GetUniqueId(), + activate ? EScriptObjectMessage::Activate : EScriptObjectMessage::Deactivate); +} +void CDrone::UpdateVisorFlare(CStateManager& mgr) {} + void CDrone::UpdateTouchBounds(float radius) { const zeus::CTransform xf = GetLctrTransform("Skeleton_Root"sv); const zeus::CVector3f diff = xf.origin - GetTranslation(); @@ -94,4 +278,29 @@ void CDrone::UpdateTouchBounds(float radius) { x6b0_pathFind.SetRadius(0.25f + radius); } +bool CDrone::HitShield(const zeus::CVector3f& dir) const { + if (x3fc_flavor == EFlavorType::One && zeus::close_enough(x5dc_, 0.f)) { + return GetLctrTransform("Shield_LCTR"sv).basis[1].dot(dir.normalized()) > 0.85f; + } + + return false; +} +void CDrone::AddToTeam(CStateManager& mgr) const { + if (x688_teamMgr == kInvalidUniqueId) { + return; + } + + if (TCastToPtr teamMgr = mgr.ObjectById(x688_teamMgr)) { + teamMgr->AssignTeamAiRole(*this, CTeamAiRole::ETeamAiRole::Ranged, CTeamAiRole::ETeamAiRole::Melee, + CTeamAiRole::ETeamAiRole::Invalid); + } +} +void CDrone::RemoveFromTeam(CStateManager& mgr) const { + if (TCastToPtr teamMgr = mgr.ObjectById(x688_teamMgr)) { + if (teamMgr->IsPartOfTeam(GetUniqueId())) { + teamMgr->RemoveTeamAiRole(GetUniqueId()); + } + } +} + } // namespace urde::MP1 diff --git a/Runtime/MP1/World/CDrone.hpp b/Runtime/MP1/World/CDrone.hpp index d27d5866b..a8e20d6cc 100644 --- a/Runtime/MP1/World/CDrone.hpp +++ b/Runtime/MP1/World/CDrone.hpp @@ -10,7 +10,7 @@ class CDrone : public CPatterned { CAssetId x568_; TLockedToken x56c_; CCollisionResponseData* x574_; - TUniqueId x578_ = kInvalidUniqueId; + TUniqueId x578_lightId = kInvalidUniqueId; TUniqueId x57a_ = kInvalidUniqueId; std::vector x57c_flares; u32 x58c_ = 2; @@ -60,7 +60,7 @@ class CDrone : public CPatterned { float x66c_ = 0.f; zeus::CVector3f x670_; zeus::CVector3f x67c_; - TUniqueId x688_ = kInvalidUniqueId; + TUniqueId x688_teamMgr = kInvalidUniqueId; CCollidableSphere x690_; CPathFindSearch x6b0_pathFind; zeus::CAxisAngle x794_; @@ -72,7 +72,7 @@ class CDrone : public CPatterned { float x7bc_ = 0.f; s32 x7c8_ = 0; s16 x7cc_; - s32 x7d0_ = 0; + CSfxHandle x7d0_; rstl::reserved_vector x7d4_; rstl::reserved_vector x7e0_; rstl::reserved_vector x7fc_; @@ -93,6 +93,10 @@ class CDrone : public CPatterned { bool x835_25_ : 1; bool x835_26_ : 1; void UpdateTouchBounds(float radius); + bool HitShield(const zeus::CVector3f& dir) const; + void AddToTeam(CStateManager& mgr) const; + void RemoveFromTeam(CStateManager& mgr) const; + public: DEFINE_PATTERNED(Drone); CDrone(TUniqueId uid, std::string_view name, EFlavorType flavor, const CEntityInfo& info, const zeus::CTransform& xf, @@ -103,7 +107,55 @@ public: float f13, float f14, float f15, float f16, float f17, float f18, float f19, float f20, CAssetId crscId, float f21, float f22, float f23, float f24, s32 w3, bool b1); - void Accept(IVisitor& visitor); - void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CStateManager& mgr); + void Accept(IVisitor& visitor) override; + void Think(float dt, CStateManager& mgr) override; + void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CStateManager& mgr) override; + void PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) override; + void AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const override; + void Render(const CStateManager &mgr) const override; + bool CanRenderUnsorted(const CStateManager& mgr) const override; + const CDamageVulnerability* GetDamageVulnerability() const override { return CAi::GetDamageVulnerability(); } + const CDamageVulnerability* GetDamageVulnerability(const zeus::CVector3f&, const zeus::CVector3f&, + const CDamageInfo&) const override; + void Touch(CActor& act, CStateManager& mgr) override; + EWeaponCollisionResponseTypes GetCollisionResponseType(const zeus::CVector3f&, const zeus::CVector3f&, + const CWeaponMode&, EProjectileAttrib) const override; + void DoUserAnimEvent(CStateManager& mgr, const CInt32POINode& node, EUserEventType type, float dt) override; + const CCollisionPrimitive* GetCollisionPrimitive() const override; + void Death(CStateManager& mgr, const zeus::CVector3f& direction, EScriptObjectState state) override; + void KnockBack(const zeus::CVector3f&, CStateManager&, const CDamageInfo& info, EKnockBackType type, bool inDeferred, + float magnitude) override; + void Patrol(CStateManager&, EStateMsg msg, float dt) override; + void PathFind(CStateManager&, EStateMsg msg, float dt) override; + void TargetPlayer(CStateManager&, EStateMsg msg, float dt) override; + void TargetCover(CStateManager&, EStateMsg msg, float dt) override; + void Deactivate(CStateManager&, EStateMsg msg, float dt) override; + void Attack(CStateManager&, EStateMsg msg, float dt) override; + void Active(CStateManager&, EStateMsg msg, float dt) override; + void Flee(CStateManager&, EStateMsg msg, float dt) override; + void ProjectileAttack(CStateManager&, EStateMsg msg, float dt) override; + void TelegraphAttack(CStateManager&, EStateMsg msg, float dt) override; + void Dodge(CStateManager&, EStateMsg msg, float dt) override; + void Retreat(CStateManager&, EStateMsg msg, float dt) override; + void Cover(CStateManager&, EStateMsg msg, float dt) override; + void SpecialAttack(CStateManager&, EStateMsg msg, float dt) override; + void PathFindEx(CStateManager&, EStateMsg msg, float dt) override; + bool Leash(CStateManager&, float arg) override; + bool InRange(CStateManager&, float arg) override; + bool SpotPlayer(CStateManager&, float arg) override; + bool AnimOver(CStateManager&, float arg) override; + bool ShouldAttack(CStateManager&, float arg) override; + bool HearShot(CStateManager&, float arg) override; + bool CoverCheck(CStateManager&, float arg) override; + bool LineOfSight(CStateManager&, float arg) override; + bool ShouldMove(CStateManager&, float arg) override; + bool CodeTrigger(CStateManager&, float arg) override; + void Burn(float duration, float damage) override; + CPathFindSearch* GetSearchPath() override; + virtual void BuildNearList(EMaterialTypes includeMat, EMaterialTypes excludeMat, + rstl::reserved_vector& listOut, float radius, CStateManager& mgr); + virtual void SetLightEnabled(CStateManager& mgr, bool activate); + virtual void UpdateVisorFlare(CStateManager& mgr); + virtual int sub_8015f150() { return 3; } }; } // namespace urde::MP1 From e4c3248ad89c44875bd6d6e2ef61c9c4a2a21891 Mon Sep 17 00:00:00 2001 From: Phillip Stephens Date: Sun, 5 Apr 2020 00:31:34 -0700 Subject: [PATCH 4/9] Drone: Start implementing state functions --- Runtime/MP1/World/CDrone.cpp | 326 +++++++++++++++++++++++++++++++---- Runtime/MP1/World/CDrone.hpp | 34 ++-- 2 files changed, 314 insertions(+), 46 deletions(-) diff --git a/Runtime/MP1/World/CDrone.cpp b/Runtime/MP1/World/CDrone.cpp index 824dde63d..46f69ce0f 100644 --- a/Runtime/MP1/World/CDrone.cpp +++ b/Runtime/MP1/World/CDrone.cpp @@ -4,9 +4,11 @@ #include "Runtime/CSimplePool.hpp" #include "Runtime/CStateManager.hpp" #include "Runtime/GameGlobalObjects.hpp" +#include "Runtime/Particle/CWeaponDescription.hpp" #include "Runtime/Weapon/CWeapon.hpp" #include "Runtime/World/CGameLight.hpp" #include "Runtime/World/CPatternedInfo.hpp" +#include "Runtime/World/CPlayer.hpp" #include "Runtime/World/CTeamAiMgr.hpp" #include "Runtime/World/CWorld.hpp" @@ -29,7 +31,7 @@ CDrone::CDrone(TUniqueId uid, std::string_view name, EFlavorType flavor, const C , x590_(dInfo1) , x5ac_(dInfo2) , x5e4_(f23) -, x5ec_(f1) +, x5ec_turnSpeed(f1) , x5f0_(f2) , x5f4_(f3) , x5f8_(f4) @@ -55,7 +57,7 @@ CDrone::CDrone(TUniqueId uid, std::string_view name, EFlavorType flavor, const C , x690_(zeus::CSphere({0.f, 0.f, 1.8f}, 1.1f), CActor::GetMaterialList()) , x6b0_pathFind(nullptr, 3 + int(b1), pInfo.GetPathfindingIndex(), 1.f, 2.4f) , x7cc_(CSfxManager::TranslateSFXID(sId)) -, x82c_(std::make_unique(CStaticRes{aId2, zeus::skOne3f})) +, x82c_shieldModel(std::make_unique(CStaticRes{aId2, zeus::skOne3f})) , x830_13_(0) , x830_10_(0) , x834_24_(false) @@ -63,8 +65,8 @@ CDrone::CDrone(TUniqueId uid, std::string_view name, EFlavorType flavor, const C , x834_26_(false) , x834_27_(false) , x834_28_(false) -, x834_29_(false) -, x834_30_(false) +, x834_29_codeTrigger(false) +, x834_30_visible(false) , x834_31_(false) , x835_24_(false) , x835_25_(b1) @@ -113,7 +115,7 @@ void CDrone::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CStateM break; } case EScriptObjectMessage::Alert: - x834_29_ = true; + x834_29_codeTrigger = true; break; case EScriptObjectMessage::OnFloor: if (!x835_26_ && x834_24_) { @@ -162,10 +164,6 @@ void CDrone::PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) { } } -void CDrone::AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const { - CPatterned::AddToRenderer(frustum, mgr); -} - void CDrone::Render(const CStateManager& mgr) const { bool isOne = x3fc_flavor == EFlavorType::One; if (!isOne || GetModelAlphau8(mgr) != 0) { @@ -182,8 +180,9 @@ void CDrone::Render(const CStateManager& mgr) const { } if (isOne && zeus::close_enough(x5dc_, 0)) { - x82c_->Render(mgr, GetLctrTransform("Shield_LCTR"sv), GetActorLights(), - CModelFlags{8, 0, 3, zeus::CColor::lerp({1.f, 0.f, 0.f, 1.f}, zeus::skWhite, x5e8_)}); + x82c_shieldModel->Render( + mgr, GetLctrTransform("Shield_LCTR"sv), GetActorLights(), + CModelFlags{8, 0, 3, zeus::CColor::lerp({1.f, 0.f, 0.f, 1.f}, zeus::skWhite, x5e8_shieldTime)}); } } } @@ -206,7 +205,7 @@ void CDrone::Touch(CActor& act, CStateManager& mgr) { if (IsAlive()) { x834_24_ = weapon->GetType() == EWeaponType::Wave; if (HitShield(weapon->GetTranslation() - GetTranslation())) { - x5e8_ = 1.f; + x5e8_shieldTime = 1.f; } } } @@ -221,43 +220,271 @@ EWeaponCollisionResponseTypes CDrone::GetCollisionResponseType(const zeus::CVect } void CDrone::DoUserAnimEvent(CStateManager& mgr, const CInt32POINode& node, EUserEventType type, float dt) { + switch (type) { + case EUserEventType::Projectile: + // sub80165984(mgr, GetLctrTransform(node.GetLocatorName())); + return; + case EUserEventType::Delete: + if (x7d0_) { + CSfxManager::RemoveEmitter(x7d0_); + x7d0_.reset(); + } + MassiveDeath(mgr); + break; + case EUserEventType::DamageOn: { + if (IsAlive() && x835_24_) { + UpdateLaser(mgr, 0, true); + x824_[0] = true; + SetVisorFlareEnabled(mgr, true); + } else if (x3fc_flavor == EFlavorType::One) { + UpdateLaser(mgr, 1, true); + x824_[1] = true; + } + return; + } + case EUserEventType::DamageOff: { + if (x824_[0]) { + UpdateLaser(mgr, 0, false); + x824_[0] = false; + SetVisorFlareEnabled(mgr, false); + } else if (x3fc_flavor == EFlavorType::One) { + UpdateLaser(mgr, 1, false); + x824_[1] = false; + } + return; + } + case EUserEventType::FadeIn: { + if (x3fc_flavor == EFlavorType::One) + x834_30_visible = true; + return; + } + case EUserEventType::FadeOut: { + if (x3fc_flavor == EFlavorType::One) + x834_30_visible = false; + return; + } + default: + break; + } CPatterned::DoUserAnimEvent(mgr, node, type, dt); } -const CCollisionPrimitive* CDrone::GetCollisionPrimitive() const { return CPhysicsActor::GetCollisionPrimitive(); } +const CCollisionPrimitive* CDrone::GetCollisionPrimitive() const { + if (!x834_28_) + return &x690_; + return CPatterned::GetCollisionPrimitive(); +} + void CDrone::Death(CStateManager& mgr, const zeus::CVector3f& direction, EScriptObjectState state) { - CPatterned::Death(mgr, direction, state); + if (!IsAlive()) + return; + + x824_[0] = false; + x824_[1] = false; + UpdateLaser(mgr, 0, false); + UpdateLaser(mgr, 1, false); + SetVisorFlareEnabled(mgr, false); + + if (x3e4_lastHP - HealthInfo(mgr)->GetHP() < x3d8_xDamageThreshold || x834_24_) { + x330_stateMachineState.SetState(mgr, *this, GetStateMachine(), "Dead"sv); + } else { + x834_28_ = true; + if (x3e0_xDamageDelay <= 0.f) { + SetTransform(zeus::lookAt(GetTranslation(), GetTranslation() - direction) * + zeus::CTransform::RotateX(zeus::degToRad(45.f))); + } + + if (x450_bodyController->GetPercentageFrozen() > 0.f) { + x450_bodyController->UnFreeze(); + } + + x400_25_alive = false; + SendScriptMsgs(state, mgr, EScriptObjectMessage::None); + } } void CDrone::KnockBack(const zeus::CVector3f& backVec, CStateManager& mgr, const CDamageInfo& info, EKnockBackType type, bool inDeferred, float magnitude) { CPatterned::KnockBack(backVec, mgr, info, type, inDeferred, magnitude); } -void CDrone::Patrol(CStateManager& mgr, EStateMsg msg, float dt) { CPatterned::Patrol(mgr, msg, dt); } -void CDrone::PathFind(CStateManager& mgr, EStateMsg msg, float dt) { CPatterned::PathFind(mgr, msg, dt); } -void CDrone::TargetPlayer(CStateManager& mgr, EStateMsg msg, float dt) { CPatterned::TargetPlayer(mgr, msg, dt); } -void CDrone::TargetCover(CStateManager& mgr, EStateMsg msg, float dt) { CAi::TargetCover(mgr, msg, dt); } -void CDrone::Deactivate(CStateManager& mgr, EStateMsg msg, float dt) { CAi::Deactivate(mgr, msg, dt); } -void CDrone::Attack(CStateManager& mgr, EStateMsg msg, float dt) {} +void CDrone::Patrol(CStateManager& mgr, EStateMsg msg, float dt) { + if (msg == EStateMsg::Activate) { + x450_bodyController->SetLocomotionType(pas::ELocomotionType::Lurk); + SetLightEnabled(mgr, true); + x834_25_ = true; + } else if (msg == EStateMsg::Update) { + rstl::reserved_vector nearList; + BuildNearList(EMaterialTypes::Character, EMaterialTypes::Player, nearList, 5.f, mgr); + if (nearList.empty()) + return; + zeus::CVector3f sep = x45c_steeringBehaviors.Separation( + *this, static_cast(mgr.GetObjectById(nearList[0]))->GetTranslation(), 5.f); + if (!sep.isZero()) { + x450_bodyController->GetCommandMgr().DeliverCmd(CBCLocomotionCmd(sep, zeus::skZero3f, 0.5f)); + } + } else if (msg == EStateMsg::Deactivate) { + SetLightEnabled(mgr, false); + x834_25_ = false; + } + CPatterned::Patrol(mgr, msg, dt); +} +void CDrone::PathFind(CStateManager& mgr, EStateMsg msg, float dt) { + if (msg == EStateMsg::Activate) { + zeus::CVector3f searchOff = GetTranslation() + zeus::CVector3f{0.f, 0.f, x664_}; + CPathFindSearch::EResult res = GetSearchPath()->Search(GetTranslation(), searchOff); + if (res != CPathFindSearch::EResult::Success && + (res == CPathFindSearch::EResult::NoDestPoint || res == CPathFindSearch::EResult::NoPath)) { + if (GetSearchPath()->FindClosestReachablePoint(GetTranslation(), searchOff) == + CPathFindSearch::EResult::Success) { + GetSearchPath()->Search(GetTranslation(), searchOff); + SetDestPos(searchOff); + } + } + x834_30_visible = true; + } else if (msg == EStateMsg::Update) { + CPatterned::PathFind(mgr, msg, dt); + x450_bodyController->GetCommandMgr().BlendSteeringCmds(); + zeus::CVector3f moveVec = x450_bodyController->GetCommandMgr().GetMoveVector(); + if (moveVec.canBeNormalized()) { + moveVec.normalize(); + ApplyImpulseWR(GetMass() * (x5e4_ * moveVec), {}); + zeus::CVector3f target = (mgr.GetPlayer().GetAimPosition(mgr, 0.f) - GetTranslation()); + x450_bodyController->GetCommandMgr().DeliverCmd( + CBCLocomotionCmd(FLT_EPSILON * GetTransform().basis[1], target.normalized(), 1.f)); + x450_bodyController->GetCommandMgr().DeliverTargetVector(target); + StrafeFromCompanions(mgr); + if (x630_ <= 0.f) { + x634_ = 0.333333f; + } + } else if (x630_ <= 0.f) { + x634_ = 0.f; + } + } else if (msg == EStateMsg::Deactivate) { + CPatterned::PathFind(mgr, msg, dt); + } +} +void CDrone::TargetPlayer(CStateManager& mgr, EStateMsg msg, float dt) { + if (msg == EStateMsg::Activate) { + x3b8_turnSpeed = x5ec_turnSpeed; + if (x450_bodyController->GetLocomotionType() != pas::ELocomotionType::Combat) + x450_bodyController->SetLocomotionType(pas::ELocomotionType::Combat); + SetDestPos(mgr.GetPlayer().GetAimPosition(mgr, 0.f)); + x400_24_hitByPlayerProjectile = false; + if (x3fc_flavor == EFlavorType::One) + x834_30_visible = true; + x330_stateMachineState.SetDelay(std::max(0.f, x624_)); + } else if (msg == EStateMsg::Update) { + zeus::CVector3f target = (mgr.GetPlayer().GetAimPosition(mgr, 0.f) - GetTranslation()); + x450_bodyController->GetCommandMgr().DeliverCmd( + CBCLocomotionCmd(FLT_EPSILON * GetTransform().basis[1], target.normalized(), 1.f)); + x450_bodyController->GetCommandMgr().DeliverTargetVector(target); + StrafeFromCompanions(mgr); + if (x630_ <= 0.f) + x634_ = 0.f; + } else if (msg == EStateMsg::Deactivate) { + SetDestPos(mgr.GetPlayer().GetTranslation() + zeus::CVector3f{0.f, 0.f, x664_}); + } +} +void CDrone::TargetCover(CStateManager& mgr, EStateMsg msg, float dt) { + if (msg != EStateMsg::Update) + return; + /* Don't ask I have no idea.... */ + const zeus::CVector3f vec = {1.f * x5e4_ * 0.f, 1.f * x5e4_ * 0.f, 1.f * x5e4_ * 0.f}; + ApplyImpulseWR(GetMoveToORImpulseWR(GetTransform().transposeRotate(vec), 1.f), {}); +} + +void CDrone::Deactivate(CStateManager& mgr, EStateMsg msg, float dt) { + if (msg != EStateMsg::Activate) + return; + DeathDelete(mgr); +} + +void CDrone::Attack(CStateManager& mgr, EStateMsg msg, float dt) { CAi::Attack(mgr, msg, dt); } void CDrone::Active(CStateManager& mgr, EStateMsg msg, float dt) { CAi::Active(mgr, msg, dt); } void CDrone::Flee(CStateManager& mgr, EStateMsg msg, float dt) { CAi::Flee(mgr, msg, dt); } void CDrone::ProjectileAttack(CStateManager& mgr, EStateMsg msg, float dt) { CAi::ProjectileAttack(mgr, msg, dt); } -void CDrone::TelegraphAttack(CStateManager& mgr, EStateMsg msg, float dt) { CAi::TelegraphAttack(mgr, msg, dt); } +void CDrone::TelegraphAttack(CStateManager& mgr, EStateMsg msg, float dt) { + if (msg == EStateMsg::Activate) { + x7c8_ = 0; + } else if (msg == EStateMsg::Update) { + if (x7c8_ == 1 && x450_bodyController->GetBodyStateInfo().GetCurrentStateId() != pas::EAnimationState::Taunt) { + x7c8_ = 2; + } else if (x7c8_ == 0) { + if (x450_bodyController->GetBodyStateInfo().GetCurrentStateId() == pas::EAnimationState::Taunt) { + x7c8_ = 1; + } else { + x450_bodyController->GetCommandMgr().DeliverCmd(CBCTauntCmd(pas::ETauntType::One)); + } + } + } else if (msg == EStateMsg::Deactivate) { + SendScriptMsgs(EScriptObjectState::Zero, mgr, EScriptObjectMessage::None); + } +} void CDrone::Dodge(CStateManager& mgr, EStateMsg msg, float dt) { CAi::Dodge(mgr, msg, dt); } void CDrone::Retreat(CStateManager& mgr, EStateMsg msg, float dt) { CAi::Retreat(mgr, msg, dt); } void CDrone::Cover(CStateManager& mgr, EStateMsg msg, float dt) { CAi::Cover(mgr, msg, dt); } void CDrone::SpecialAttack(CStateManager& mgr, EStateMsg msg, float dt) { CAi::SpecialAttack(mgr, msg, dt); } -void CDrone::PathFindEx(CStateManager& mgr, EStateMsg msg, float dt) { CAi::PathFindEx(mgr, msg, dt); } -bool CDrone::Leash(CStateManager& mgr, float arg) { return CPatterned::Leash(mgr, arg); } -bool CDrone::InRange(CStateManager& mgr, float arg) { return CPatterned::InRange(mgr, arg); } -bool CDrone::SpotPlayer(CStateManager& mgr, float arg) { return CPatterned::SpotPlayer(mgr, arg); } -bool CDrone::AnimOver(CStateManager& mgr, float arg) { return CPatterned::AnimOver(mgr, arg); } -bool CDrone::ShouldAttack(CStateManager& mgr, float arg) { return CAi::ShouldAttack(mgr, arg); } +void CDrone::PathFindEx(CStateManager& mgr, EStateMsg msg, float dt) { + CPatterned::PathFind(mgr, msg, dt); + if (msg == EStateMsg::Activate) { + zeus::CVector3f searchOff = GetTranslation() + zeus::CVector3f{0.f, 0.f, x664_}; + CPathFindSearch::EResult res = GetSearchPath()->Search(GetTranslation(), searchOff); + if (res != CPathFindSearch::EResult::Success && + (res == CPathFindSearch::EResult::NoDestPoint || res == CPathFindSearch::EResult::NoPath)) { + if (GetSearchPath()->FindClosestReachablePoint(GetTranslation(), searchOff) == + CPathFindSearch::EResult::Success) { + GetSearchPath()->Search(GetTranslation(), searchOff); + SetDestPos(searchOff); + } + } + } +} + +bool CDrone::Leash(CStateManager& mgr, float arg) { + return (mgr.GetPlayer().GetTranslation() - GetTranslation()).magSquared() < x3c8_leashRadius * x3c8_leashRadius; +} +bool CDrone::InRange(CStateManager& mgr, float arg) { + return (mgr.GetPlayer().GetTranslation() - GetTranslation()).magSquared() < x300_maxAttackRange * x300_maxAttackRange; +} +bool CDrone::SpotPlayer(CStateManager& mgr, float arg) { + if ((mgr.GetPlayer().GetTranslation() - GetTranslation()).magSquared() > x3bc_detectionRange) + return false; + + if (!LineOfSight(mgr, arg)) + return false; + + return (GetTransform().basis[1] + x5cc_ * GetTransform().basis[0]) + .normalized() + .dot((mgr.GetPlayer().GetAimPosition(mgr, 0.f) - GetTranslation()).normalized()) > 0.5f; +} +bool CDrone::AnimOver(CStateManager& mgr, float arg) { return x7c8_ == 2; } +bool CDrone::ShouldAttack(CStateManager& mgr, float arg) { + if (x5d0_ > 0.f) + return false; + if (TCastToPtr teamMgr = mgr.ObjectById(x688_teamMgr)) { + if (teamMgr->HasTeamAiRole(GetUniqueId())) + teamMgr->AddRangedAttacker(GetUniqueId()); + } + return true; +} bool CDrone::HearShot(CStateManager& mgr, float arg) { return CAi::HearShot(mgr, arg); } -bool CDrone::CoverCheck(CStateManager& mgr, float arg) { return CAi::CoverCheck(mgr, arg); } -bool CDrone::LineOfSight(CStateManager& mgr, float arg) { return CAi::LineOfSight(mgr, arg); } -bool CDrone::ShouldMove(CStateManager& mgr, float arg) { return CAi::ShouldMove(mgr, arg); } -bool CDrone::CodeTrigger(CStateManager& mgr, float arg) { return CPatterned::CodeTrigger(mgr, arg); } +bool CDrone::CoverCheck(CStateManager& mgr, float arg) { + if (!zeus::close_enough(x67c_, zeus::skZero3f)) { + const zeus::CVector3f diff = x670_ - GetTranslation(); + return x67c_.dot(diff) < 0.0f || diff.magSquared() < 0.25f; + } + + return true; +} +bool CDrone::LineOfSight(CStateManager& mgr, float arg) { + return mgr.RayCollideWorld( + GetTranslation(), mgr.GetPlayer().GetAimPosition(mgr, 0.f), + CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Solid, EMaterialTypes::Character}, + {EMaterialTypes::Player, EMaterialTypes::ProjectilePassthrough}), + this); +} +bool CDrone::ShouldMove(CStateManager& mgr, float arg) { return x644_ <= 0.f; } +bool CDrone::CodeTrigger(CStateManager& mgr, float arg) { return x834_29_codeTrigger; } void CDrone::Burn(float duration, float damage) { CPatterned::Burn(duration, damage); } -CPathFindSearch* CDrone::GetSearchPath() { return CPatterned::GetSearchPath(); } +CPathFindSearch* CDrone::GetSearchPath() { return &x6b0_pathFind; } void CDrone::BuildNearList(EMaterialTypes includeMat, EMaterialTypes excludeMat, rstl::reserved_vector& listOut, float radius, CStateManager& mgr) { @@ -269,6 +496,9 @@ void CDrone::SetLightEnabled(CStateManager& mgr, bool activate) { mgr.SendScriptMsgAlways(x578_lightId, GetUniqueId(), activate ? EScriptObjectMessage::Activate : EScriptObjectMessage::Deactivate); } + +void CDrone::SetVisorFlareEnabled(CStateManager& mgr, bool activate) {} + void CDrone::UpdateVisorFlare(CStateManager& mgr) {} void CDrone::UpdateTouchBounds(float radius) { @@ -302,5 +532,37 @@ void CDrone::RemoveFromTeam(CStateManager& mgr) const { } } } +void CDrone::UpdateLaser(CStateManager& mgr, u32 laserIdx, bool b1) {} +void CDrone::FireProjectile(CStateManager& mgr, const zeus::CTransform& xf, const TToken& weapon) {} +void CDrone::StrafeFromCompanions(CStateManager& mgr) { + if (x450_bodyController->GetBodyStateInfo().GetCurrentStateId() == pas::EAnimationState::Step) + return; + rstl::reserved_vector nearList; + BuildNearList(EMaterialTypes::Character, EMaterialTypes::Player, nearList, x61c_, mgr); + if (nearList.empty()) + return; + float minDist = FLT_MAX; + zeus::CVector3f nearestPos; + for (TUniqueId uid : nearList) { + if (const CActor* act = static_cast(mgr.GetObjectById(uid))) { + const float dist = (act->GetTranslation() - GetTranslation()).magSquared(); + if (uid != GetUniqueId() && dist < minDist) { + minDist = dist; + nearestPos = act->GetTranslation(); + } + } + } + + if (nearestPos.isZero()) + return; + + zeus::CVector3f off = nearestPos - GetTranslation(); + const float rightOff = GetTransform().basis[0].dot(off); + if (rightOff > -0.2f && rightOff < 0.2f) { + x450_bodyController->GetCommandMgr().DeliverCmd(CBCStepCmd(pas::EStepDirection::Left, pas::EStepType::Normal)); + } else { + x450_bodyController->GetCommandMgr().DeliverCmd(CBCStepCmd(pas::EStepDirection::Right, pas::EStepType::Normal)); + } +} } // namespace urde::MP1 diff --git a/Runtime/MP1/World/CDrone.hpp b/Runtime/MP1/World/CDrone.hpp index a8e20d6cc..61576bf18 100644 --- a/Runtime/MP1/World/CDrone.hpp +++ b/Runtime/MP1/World/CDrone.hpp @@ -5,7 +5,9 @@ #include "Runtime/World/CPathFindSearch.hpp" #include "Runtime/World/CVisorFlare.hpp" -namespace urde::MP1 { +namespace urde { +class CWeaponDescription; +namespace MP1 { class CDrone : public CPatterned { CAssetId x568_; TLockedToken x56c_; @@ -24,8 +26,8 @@ class CDrone : public CPatterned { float x5dc_ = 0.f; float x5e0_ = 0.f; float x5e4_; - float x5e8_ = 0.f; - float x5ec_; + float x5e8_shieldTime = 0.f; + float x5ec_turnSpeed; float x5f0_; float x5f4_; float x5f8_; @@ -73,12 +75,12 @@ class CDrone : public CPatterned { s32 x7c8_ = 0; s16 x7cc_; CSfxHandle x7d0_; - rstl::reserved_vector x7d4_; - rstl::reserved_vector x7e0_; - rstl::reserved_vector x7fc_; - rstl::reserved_vector x818_; - rstl::reserved_vector x824_; - std::unique_ptr x82c_; + rstl::reserved_vector x7d4_ = {{kInvalidUniqueId, kInvalidUniqueId}}; + rstl::reserved_vector x7e0_ = {{zeus::skZero3f, zeus::skZero3f}}; + rstl::reserved_vector x7fc_ = {{zeus::skZero3f, zeus::skZero3f}};; + rstl::reserved_vector x818_ = {{0.f, 0.f}}; + rstl::reserved_vector x824_ = {{false, false}}; + std::unique_ptr x82c_shieldModel; u8 x830_13_ : 2; u8 x830_10_ : 2; bool x834_24_ : 1; @@ -86,8 +88,8 @@ class CDrone : public CPatterned { bool x834_26_ : 1; bool x834_27_ : 1; bool x834_28_ : 1; - bool x834_29_ : 1; - bool x834_30_ : 1; + bool x834_29_codeTrigger : 1; + bool x834_30_visible : 1; bool x834_31_ : 1; bool x835_24_ : 1; bool x835_25_ : 1; @@ -96,6 +98,9 @@ class CDrone : public CPatterned { bool HitShield(const zeus::CVector3f& dir) const; void AddToTeam(CStateManager& mgr) const; void RemoveFromTeam(CStateManager& mgr) const; + void UpdateLaser(CStateManager& mgr, u32 laserIdx, bool b1); + void FireProjectile(CStateManager& mgr, const zeus::CTransform& xf, const TToken& weapon); + void StrafeFromCompanions(CStateManager& mgr); public: DEFINE_PATTERNED(Drone); @@ -111,8 +116,7 @@ public: void Think(float dt, CStateManager& mgr) override; void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CStateManager& mgr) override; void PreRender(CStateManager& mgr, const zeus::CFrustum& frustum) override; - void AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const override; - void Render(const CStateManager &mgr) const override; + void Render(const CStateManager& mgr) const override; bool CanRenderUnsorted(const CStateManager& mgr) const override; const CDamageVulnerability* GetDamageVulnerability() const override { return CAi::GetDamageVulnerability(); } const CDamageVulnerability* GetDamageVulnerability(const zeus::CVector3f&, const zeus::CVector3f&, @@ -155,7 +159,9 @@ public: virtual void BuildNearList(EMaterialTypes includeMat, EMaterialTypes excludeMat, rstl::reserved_vector& listOut, float radius, CStateManager& mgr); virtual void SetLightEnabled(CStateManager& mgr, bool activate); + virtual void SetVisorFlareEnabled(CStateManager& mgr, bool activate); virtual void UpdateVisorFlare(CStateManager& mgr); virtual int sub_8015f150() { return 3; } }; -} // namespace urde::MP1 +} // namespace MP1 +} // namespace urde From 4c3caa2a7f3eba95d9d83d003f1c7d60cecfaa59 Mon Sep 17 00:00:00 2001 From: Phillip Stephens Date: Sun, 5 Apr 2020 08:28:35 -0700 Subject: [PATCH 5/9] Drone: Initial Think imp --- Runtime/MP1/World/CDrone.cpp | 208 ++++++++++++++++++++++++++++++++--- Runtime/MP1/World/CDrone.hpp | 1 + 2 files changed, 195 insertions(+), 14 deletions(-) diff --git a/Runtime/MP1/World/CDrone.cpp b/Runtime/MP1/World/CDrone.cpp index 46f69ce0f..909a1357c 100644 --- a/Runtime/MP1/World/CDrone.cpp +++ b/Runtime/MP1/World/CDrone.cpp @@ -80,7 +80,27 @@ CDrone::CDrone(TUniqueId uid, std::string_view name, EFlavorType flavor, const C } void CDrone::Accept(IVisitor& visitor) { visitor.Visit(this); } -void CDrone::Think(float dt, CStateManager& mgr) { CPatterned::Think(dt, mgr); } + +void CDrone::Think(float dt, CStateManager& mgr) { + if (x3fc_flavor != EFlavorType::One) { + if (mgr.GetPlayerState()->GetActiveVisor(mgr) != CPlayerState::EPlayerVisor::XRay) { + x42c_color.a() = std::max(0.f, x428_damageCooldownTimer / 0.33f); + } + } + + if (GetBodyController()->IsElectrocuting() && (x824_[0] || x824_[1])) { + x824_[0] = false; + x824_[1] = false; + UpdateLaser(mgr, 0, false); + UpdateLaser(mgr, 1, false); + SetVisorFlareEnabled(mgr, false); + } + CPatterned::Think(dt, mgr); + + if (!GetActive()) + return; + // TODO: Finish +} void CDrone::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CStateManager& mgr) { CPatterned::AcceptScriptMsg(msg, sender, mgr); @@ -186,6 +206,7 @@ void CDrone::Render(const CStateManager& mgr) const { } } } + bool CDrone::CanRenderUnsorted(const CStateManager& mgr) const { if (zeus::close_enough(x5dc_, 0.f)) return false; @@ -199,6 +220,7 @@ const CDamageVulnerability* CDrone::GetDamageVulnerability(const zeus::CVector3f } return CAi::GetDamageVulnerability(); } + void CDrone::Touch(CActor& act, CStateManager& mgr) { CPatterned::Touch(act, mgr); if (TCastToPtr weapon = act) { @@ -220,6 +242,7 @@ EWeaponCollisionResponseTypes CDrone::GetCollisionResponseType(const zeus::CVect } void CDrone::DoUserAnimEvent(CStateManager& mgr, const CInt32POINode& node, EUserEventType type, float dt) { + // TODO: Finish switch (type) { case EUserEventType::Projectile: // sub80165984(mgr, GetLctrTransform(node.GetLocatorName())); @@ -268,6 +291,7 @@ void CDrone::DoUserAnimEvent(CStateManager& mgr, const CInt32POINode& node, EUse } CPatterned::DoUserAnimEvent(mgr, node, type, dt); } + const CCollisionPrimitive* CDrone::GetCollisionPrimitive() const { if (!x834_28_) return &x690_; @@ -301,10 +325,18 @@ void CDrone::Death(CStateManager& mgr, const zeus::CVector3f& direction, EScript SendScriptMsgs(state, mgr, EScriptObjectMessage::None); } } + void CDrone::KnockBack(const zeus::CVector3f& backVec, CStateManager& mgr, const CDamageInfo& info, EKnockBackType type, bool inDeferred, float magnitude) { + if (!IsAlive()) + return; CPatterned::KnockBack(backVec, mgr, info, type, inDeferred, magnitude); + if (GetKnockBackController().GetActiveParms().x0_animState == EKnockBackAnimationState::Invalid) + return; + x630_ = 0.5f; + x634_ = 1.f; } + void CDrone::Patrol(CStateManager& mgr, EStateMsg msg, float dt) { if (msg == EStateMsg::Activate) { x450_bodyController->SetLocomotionType(pas::ELocomotionType::Lurk); @@ -326,6 +358,7 @@ void CDrone::Patrol(CStateManager& mgr, EStateMsg msg, float dt) { } CPatterned::Patrol(mgr, msg, dt); } + void CDrone::PathFind(CStateManager& mgr, EStateMsg msg, float dt) { if (msg == EStateMsg::Activate) { zeus::CVector3f searchOff = GetTranslation() + zeus::CVector3f{0.f, 0.f, x664_}; @@ -361,6 +394,7 @@ void CDrone::PathFind(CStateManager& mgr, EStateMsg msg, float dt) { CPatterned::PathFind(mgr, msg, dt); } } + void CDrone::TargetPlayer(CStateManager& mgr, EStateMsg msg, float dt) { if (msg == EStateMsg::Activate) { x3b8_turnSpeed = x5ec_turnSpeed; @@ -383,6 +417,7 @@ void CDrone::TargetPlayer(CStateManager& mgr, EStateMsg msg, float dt) { SetDestPos(mgr.GetPlayer().GetTranslation() + zeus::CVector3f{0.f, 0.f, x664_}); } } + void CDrone::TargetCover(CStateManager& mgr, EStateMsg msg, float dt) { if (msg != EStateMsg::Update) return; @@ -397,10 +432,29 @@ void CDrone::Deactivate(CStateManager& mgr, EStateMsg msg, float dt) { DeathDelete(mgr); } -void CDrone::Attack(CStateManager& mgr, EStateMsg msg, float dt) { CAi::Attack(mgr, msg, dt); } -void CDrone::Active(CStateManager& mgr, EStateMsg msg, float dt) { CAi::Active(mgr, msg, dt); } -void CDrone::Flee(CStateManager& mgr, EStateMsg msg, float dt) { CAi::Flee(mgr, msg, dt); } -void CDrone::ProjectileAttack(CStateManager& mgr, EStateMsg msg, float dt) { CAi::ProjectileAttack(mgr, msg, dt); } +void CDrone::Attack(CStateManager& mgr, EStateMsg msg, float dt) { + // TODO: Finish +} + +void CDrone::Active(CStateManager& mgr, EStateMsg msg, float dt) { + if (msg == EStateMsg::Activate) { + x330_stateMachineState.SetDelay(x5f0_); + GetBodyController()->SetLocomotionType(pas::ELocomotionType::Relaxed); + } else if (msg == EStateMsg::Deactivate) { + x5d0_ = x5f8_; + } +} + +void CDrone::Flee(CStateManager& mgr, EStateMsg msg, float dt) { + if (msg == EStateMsg::Activate) { + } else if (msg == EStateMsg::Update) { + } +} + +void CDrone::ProjectileAttack(CStateManager& mgr, EStateMsg msg, float dt) { + // TODO: Finish +} + void CDrone::TelegraphAttack(CStateManager& mgr, EStateMsg msg, float dt) { if (msg == EStateMsg::Activate) { x7c8_ = 0; @@ -418,10 +472,127 @@ void CDrone::TelegraphAttack(CStateManager& mgr, EStateMsg msg, float dt) { SendScriptMsgs(EScriptObjectState::Zero, mgr, EScriptObjectMessage::None); } } -void CDrone::Dodge(CStateManager& mgr, EStateMsg msg, float dt) { CAi::Dodge(mgr, msg, dt); } -void CDrone::Retreat(CStateManager& mgr, EStateMsg msg, float dt) { CAi::Retreat(mgr, msg, dt); } -void CDrone::Cover(CStateManager& mgr, EStateMsg msg, float dt) { CAi::Cover(mgr, msg, dt); } -void CDrone::SpecialAttack(CStateManager& mgr, EStateMsg msg, float dt) { CAi::SpecialAttack(mgr, msg, dt); } + +void CDrone::Dodge(CStateManager& mgr, EStateMsg msg, float dt) { + if (msg == EStateMsg::Activate) { + x7c8_ = 0; + x630_ = 0.5f; + x634_ = 1.f; + if (x3fc_flavor == EFlavorType::One) + x834_30_visible = true; + } else if (msg == EStateMsg::Update) { + if (x7c8_ == 0) { + GetBodyController()->GetCommandMgr().DeliverCmd(CBodyStateCmd(EBodyStateCmd::NextState)); + if (x58c_ == 5) { + GetBodyController()->GetCommandMgr().DeliverCmd(CBCStepCmd(pas::EStepDirection::Left, pas::EStepType::Dodge)); + x58c_ = 2; + } else if (x58c_ == 4) { + GetBodyController()->GetCommandMgr().DeliverCmd(CBCStepCmd(pas::EStepDirection::Down, pas::EStepType::Dodge)); + x58c_ = 5; + } else if (x58c_ == 3) { + GetBodyController()->GetCommandMgr().DeliverCmd(CBCStepCmd(pas::EStepDirection::Up, pas::EStepType::Dodge)); + x58c_ = 4; + } else if (x58c_ == 2) { + GetBodyController()->GetCommandMgr().DeliverCmd(CBCStepCmd(pas::EStepDirection::Right, pas::EStepType::Dodge)); + x58c_ = 3; + } + x7c8_ = 1; + } else if (x7c8_ == 1 && + GetBodyController()->GetBodyStateInfo().GetCurrentStateId() != pas::EAnimationState::Step) { + x7c8_ = 2; + } + GetBodyController()->GetCommandMgr().DeliverTargetVector( + (mgr.GetPlayer().GetTranslation() + zeus::CVector3f{0.f, 0.f, 1.f}) - GetTranslation()); + } +} + +void CDrone::Retreat(CStateManager& mgr, EStateMsg msg, float dt) { + if (msg == EStateMsg::Activate) { + x7c8_ = 0; + if (x3fc_flavor == EFlavorType::One) { + x834_30_visible = true; + } + x330_stateMachineState.SetDelay(x65c_); + } else if (msg == EStateMsg::Update) { + if (x7c8_ == 0) { + if (GetBodyController()->GetBodyStateInfo().GetCurrentStateId() == pas::EAnimationState::Step) { + x7c8_ = 1; + } else { + GetBodyController()->GetCommandMgr().DeliverCmd( + CBCStepCmd(pas::EStepDirection::Forward, pas::EStepType::Normal)); + } + } else if (x7c8_ == 1 && + GetBodyController()->GetBodyStateInfo().GetCurrentStateId() != pas::EAnimationState::Step) { + x7c8_ = 2; + } else if (x7c8_ == 2) { + x7c8_ = 0; + } + + GetBodyController()->GetCommandMgr().DeliverTargetVector( + (mgr.GetPlayer().GetTranslation() - GetTranslation()).normalized()); + if (x630_ <= 0.f) { + x634_ = 0.333333; // 1/3 + } + } +} + +void CDrone::Cover(CStateManager& mgr, EStateMsg msg, float dt) { + if (msg == EStateMsg::Activate) { + x67c_ = zeus::skZero3f; + x670_ = GetTranslation(); + for (int i = 0; i < 4; ++i) { + float dVar11 = (x64c_ - x648_) * mgr.GetActiveRandom()->Float() + x648_; + int v = mgr.GetActiveRandom()->Next(); + float angle = 0.f; + if (((v >> 3) & 1) == 0) { + const float angleMin = 270.f - x654_; + const float angleMax = 270.f + x650_; + angle = zeus::degToRad((angleMax - angleMin) * x648_ + angleMin); + } else { + const float angleMin = 90.f - x654_; + const float angleMax = 90.f + x650_; + angle = zeus::degToRad((angleMax - angleMin) * x648_ + angleMin); + } + zeus::CQuaternion quat; + quat.rotateZ(angle); + const zeus::CVector3f end = + GetTranslation() + + quat.transform((dVar11 * (mgr.GetPlayer().GetAimPosition(mgr, 0.f) - GetTranslation()).normalized())); + if (mgr.RayCollideWorld(GetTranslation(), end, CMaterialFilter::MakeInclude({EMaterialTypes::Solid}), this)) { + x670_ = end; + x67c_ = end - GetTranslation(); + if (x67c_.canBeNormalized()) + x67c_.normalize(); + } + } + } else if (msg == EStateMsg::Update) { + ApplyImpulseWR(GetMoveToORImpulseWR(GetTransform().transposeRotate(dt * (x658_ * x67c_)), dt), zeus::CAxisAngle()); + x450_bodyController->GetCommandMgr().DeliverCmd( + CBCLocomotionCmd(FLT_EPSILON * GetTransform().basis[1], + (mgr.GetPlayer().GetAimPosition(mgr, 0.f) - GetTranslation()).normalized(), 1.f)); + } else if (msg == EStateMsg::Deactivate) { + x644_ = (x640_ - x63c_) * mgr.GetActiveRandom()->Float() + x63c_; + } +} + +void CDrone::SpecialAttack(CStateManager& mgr, EStateMsg msg, float dt) { + if (msg == EStateMsg::Activate) { + if (x3fc_flavor == EFlavorType::One) { + x834_30_visible = true; + } + x330_stateMachineState.SetDelay(x660_); + GetBodyController()->SetLocomotionType(pas::ELocomotionType::Internal10); + } else if (msg == EStateMsg::Update) { + GetBodyController()->GetCommandMgr().DeliverCmd(CBCLocomotionCmd(GetTransform().basis[1], zeus::skZero3f, 1.f)); + zeus::CVector3f local_74 = + (mgr.GetPlayer().GetAimPosition(mgr, 0.f) + mgr.GetPlayer().GetTranslation()) - GetTranslation(); + if (((x668_ < x664_ && local_74.z() > 0.f) || (x668_ > x664_)) && local_74.canBeNormalized()) { + ApplyImpulseWR(GetMoveToORImpulseWR(GetTransform().transposeRotate(dt * (x5e4_ * local_74.normalized())), dt), + zeus::CAxisAngle()); + } + } +} + void CDrone::PathFindEx(CStateManager& mgr, EStateMsg msg, float dt) { CPatterned::PathFind(mgr, msg, dt); if (msg == EStateMsg::Activate) { @@ -465,7 +636,10 @@ bool CDrone::ShouldAttack(CStateManager& mgr, float arg) { } return true; } -bool CDrone::HearShot(CStateManager& mgr, float arg) { return CAi::HearShot(mgr, arg); } +bool CDrone::HearShot(CStateManager& mgr, float arg) { + // TODO: Finish + return CAi::HearShot(mgr, arg); +} bool CDrone::CoverCheck(CStateManager& mgr, float arg) { if (!zeus::close_enough(x67c_, zeus::skZero3f)) { const zeus::CVector3f diff = x670_ - GetTranslation(); @@ -483,7 +657,8 @@ bool CDrone::LineOfSight(CStateManager& mgr, float arg) { } bool CDrone::ShouldMove(CStateManager& mgr, float arg) { return x644_ <= 0.f; } bool CDrone::CodeTrigger(CStateManager& mgr, float arg) { return x834_29_codeTrigger; } -void CDrone::Burn(float duration, float damage) { CPatterned::Burn(duration, damage); } +void CDrone::Burn(float duration, float damage) { /* Intentionally empty */ +} CPathFindSearch* CDrone::GetSearchPath() { return &x6b0_pathFind; } void CDrone::BuildNearList(EMaterialTypes includeMat, EMaterialTypes excludeMat, @@ -499,7 +674,9 @@ void CDrone::SetLightEnabled(CStateManager& mgr, bool activate) { void CDrone::SetVisorFlareEnabled(CStateManager& mgr, bool activate) {} -void CDrone::UpdateVisorFlare(CStateManager& mgr) {} +void CDrone::UpdateVisorFlare(CStateManager& mgr) { + // TODO: Finish +} void CDrone::UpdateTouchBounds(float radius) { const zeus::CTransform xf = GetLctrTransform("Skeleton_Root"sv); @@ -532,8 +709,11 @@ void CDrone::RemoveFromTeam(CStateManager& mgr) const { } } } -void CDrone::UpdateLaser(CStateManager& mgr, u32 laserIdx, bool b1) {} -void CDrone::FireProjectile(CStateManager& mgr, const zeus::CTransform& xf, const TToken& weapon) {} +void CDrone::UpdateLaser(CStateManager& mgr, u32 laserIdx, bool b1) { + // TODO: Finish +} +void CDrone::FireProjectile(CStateManager& mgr, const zeus::CTransform& xf, const TToken& weapon) { +} void CDrone::StrafeFromCompanions(CStateManager& mgr) { if (x450_bodyController->GetBodyStateInfo().GetCurrentStateId() == pas::EAnimationState::Step) return; diff --git a/Runtime/MP1/World/CDrone.hpp b/Runtime/MP1/World/CDrone.hpp index 61576bf18..73a81c071 100644 --- a/Runtime/MP1/World/CDrone.hpp +++ b/Runtime/MP1/World/CDrone.hpp @@ -83,6 +83,7 @@ class CDrone : public CPatterned { std::unique_ptr x82c_shieldModel; u8 x830_13_ : 2; u8 x830_10_ : 2; + u16 x832_; bool x834_24_ : 1; bool x834_25_ : 1; bool x834_26_ : 1; From 37c8b9d33c275ae545ae9fb55feed0e3d4184253 Mon Sep 17 00:00:00 2001 From: Phillip Stephens Date: Tue, 7 Apr 2020 16:11:34 -0700 Subject: [PATCH 6/9] Drone: Implement Think --- Runtime/MP1/World/CDrone.cpp | 149 ++++++++++++++++++++++++++++++++++- Runtime/MP1/World/CDrone.hpp | 10 ++- 2 files changed, 152 insertions(+), 7 deletions(-) diff --git a/Runtime/MP1/World/CDrone.cpp b/Runtime/MP1/World/CDrone.cpp index 909a1357c..ed2158863 100644 --- a/Runtime/MP1/World/CDrone.cpp +++ b/Runtime/MP1/World/CDrone.cpp @@ -1,6 +1,8 @@ +#include #include "Runtime/MP1/World/CDrone.hpp" #include "Runtime/Audio/CSfxManager.hpp" +#include "Runtime/Collision/CGameCollision.hpp" #include "Runtime/CSimplePool.hpp" #include "Runtime/CStateManager.hpp" #include "Runtime/GameGlobalObjects.hpp" @@ -9,9 +11,12 @@ #include "Runtime/World/CGameLight.hpp" #include "Runtime/World/CPatternedInfo.hpp" #include "Runtime/World/CPlayer.hpp" +#include "Runtime/World/CScriptWater.hpp" #include "Runtime/World/CTeamAiMgr.hpp" #include "Runtime/World/CWorld.hpp" +#include "DataSpec/DNAMP1/SFX/Drones.h" + #include "TCastTo.hpp" // Generated file, do not modify include path namespace urde::MP1 { @@ -99,7 +104,117 @@ void CDrone::Think(float dt, CStateManager& mgr) { if (!GetActive()) return; - // TODO: Finish + + x5c8_ -= dt; + if (x7c4_ > 0.f) { + x7c4_ -= dt; + } + + if (x5d0_ > 0.f) { + x5d0_ -= (mgr.GetPlayer().GetMorphballTransitionState() == CPlayer::EPlayerMorphBallState::Morphed ? 3.f * dt : dt); + } + + if (x624_ > 0.f) { + x624_ -= dt; + } + + if (x644_ > 0.f) { + x644_ -= dt; + } + + if (x824_[0] || (x824_[1] && IsAlive())) { + sub_80163c40(dt, mgr); + UpdateVisorFlare(mgr); + } + + if (x834_25_ && IsAlive()) { + UpdateScanner(mgr, dt); + } + + const float dist = (mgr.GetPlayer().GetTranslation() - GetTranslation()).magSquared(); + if (x834_28_ && dist < x60c_ * x60c_) { + mgr.GetPlayerState()->GetStaticInterference().RemoveSource(GetUniqueId()); + mgr.GetPlayerState()->GetStaticInterference().AddSource( + GetUniqueId(), std::max(0.f, mgr.GetPlayerState()->GetStaticInterference().GetTotalInterference() - x608_), + 0.2f); + } + + if (!x834_28_ && dist < x614_ * x614_) { + mgr.GetPlayerState()->GetStaticInterference().RemoveSource(GetUniqueId()); + mgr.GetPlayerState()->GetStaticInterference().AddSource( + GetUniqueId(), std::max(0.f, mgr.GetPlayerState()->GetStaticInterference().GetTotalInterference() - x610_), + 0.2f); + } + + if (!x834_28_ && IsAlive() && !x835_25_) { + x5e0_ -= dt; + if (x5e0_ < 0.f) { + sub_801633a8(mgr); + x5e0_ = 0.1f; + } + } + + const float healthDiff = x604_ - HealthInfo(mgr)->GetHP(); + if (!zeus::close_enough(x600_, 0.f)) { + x5d0_ -= healthDiff / x600_; + x624_ -= healthDiff / x600_; + } + x604_ = HealthInfo(mgr)->GetHP(); + if (x3fc_flavor == EFlavorType::One) { + if (!x834_30_visible) { + x5dc_ = zeus::max(0.f, x5dc_ - (3.f * dt)); + } else { + x5dc_ = zeus::max(0.f, x5dc_ + (3.f * dt)); + } + x5e8_shieldTime = zeus::max(0.f, x5e8_shieldTime - dt); + + if (zeus::close_enough(x5dc_, 0.f) && x7d0_) { + CSfxManager::RemoveEmitter(x7d0_); + x7d0_.reset(); + } else if (!x7d0_ && IsAlive()) { + x7d0_ = CSfxManager::AddEmitter(SFXsfx00DD, GetTranslation(), zeus::skZero3f, true, true, 127, GetAreaIdAlways()); + } + } + sub_8015f25c(dt, mgr); + sub_8015f158(dt); + + if (!x835_25_) { + CGameCollision::AvoidStaticCollisionWithinRadius(mgr, *this, 8, dt, 0.25f, 3.5f * GetModelData()->GetScale().y(), + 3000.f, 0.5f); + } + if (x66c_ > 0.f) { + x66c_ -= dt; + } else { + x668_ = mgr.RayStaticIntersection(GetTranslation(), zeus::skDown, 1000.f, + CMaterialFilter::MakeInclude({EMaterialTypes::Solid})) + .GetT(); + x66c_ = 0.f; + } + + if (IsAlive() && x835_25_) { + zeus::CAABox box = GetBoundingBox(); + box.accumulateBounds(20.f * zeus::skDown); + rstl::reserved_vector nearList; + mgr.BuildNearList(nearList, GetBoundingBox(), CMaterialFilter::MakeInclude({EMaterialTypes::Trigger}), this); + for (TUniqueId id : nearList) { + if (const TCastToConstPtr water = mgr.GetObjectById(id)) { + zeus::CAABox waterBox = water->GetTriggerBoundsWR(); + if (waterBox.max.z() - GetTranslation().z() < 3.f) { + float z = 20.f; + if (waterBox.max.z() - GetTranslation().z() < 1.5f) { + z = 60.f; + } + ApplyImpulseWR(GetMoveToORImpulseWR(GetTransform().transposeRotate(z * zeus::skDown), dt), + zeus::CAxisAngle()); + } + } + } + } + if (IsAlive() && x668_ < x664_) { + ApplyImpulseWR(GetMoveToORImpulseWR(GetTransform().transposeRotate(dt * (1.f * zeus::skUp)), dt), + zeus::CAxisAngle()); + xe7_31_targetable = IsAlive(); + } } void CDrone::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CStateManager& mgr) { @@ -682,7 +797,7 @@ void CDrone::UpdateTouchBounds(float radius) { const zeus::CTransform xf = GetLctrTransform("Skeleton_Root"sv); const zeus::CVector3f diff = xf.origin - GetTranslation(); SetBoundingBox(zeus::CAABox{diff - radius, diff + radius}); - x6b0_pathFind.SetRadius(0.25f + radius); + x6b0_pathFind.SetCharacterRadius(0.25f + radius); } bool CDrone::HitShield(const zeus::CVector3f& dir) const { @@ -712,8 +827,9 @@ void CDrone::RemoveFromTeam(CStateManager& mgr) const { void CDrone::UpdateLaser(CStateManager& mgr, u32 laserIdx, bool b1) { // TODO: Finish } -void CDrone::FireProjectile(CStateManager& mgr, const zeus::CTransform& xf, const TToken& weapon) { -} + +void CDrone::FireProjectile(CStateManager& mgr, const zeus::CTransform& xf, const TToken& weapon) {} + void CDrone::StrafeFromCompanions(CStateManager& mgr) { if (x450_bodyController->GetBodyStateInfo().GetCurrentStateId() == pas::EAnimationState::Step) return; @@ -745,4 +861,29 @@ void CDrone::StrafeFromCompanions(CStateManager& mgr) { x450_bodyController->GetCommandMgr().DeliverCmd(CBCStepCmd(pas::EStepDirection::Right, pas::EStepType::Normal)); } } +void CDrone::UpdateScanner(CStateManager& mgr, float dt) { + x5d4_ = zeus::CRelAngle::MakeRelativeAngle(1.2f * dt + x5d4_); + x5d8_ = zeus::CRelAngle::MakeRelativeAngle(x5d8_); + float angle = zeus::clamp(0.f, 0.5f * (1.f + std::sin(x5d4_)), 1.f); + if (std::fpclassify(angle) != FP_SUBNORMAL) + x5d8_ += 0.03f * std::pow(angle, 5.f); + zeus::CVector3f vec = + GetTransform().rotate(zeus::CVector3f(0.5f * std::cos(x5d8_), 1.f, 0.5f * std::sin(2.05f * x5d8_)).normalized()); + TUniqueId id; + rstl::reserved_vector nearList; + nearList.push_back(GetUniqueId()); + auto res = mgr.RayWorldIntersection( + id, GetLctrTransform("Beacon_LCTR"sv).origin + (0.2f * vec), vec, 10000.f, + CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Solid}, {EMaterialTypes::ProjectilePassthrough}), nearList); + if (res.IsValid() && x578_lightId != kInvalidUniqueId) { + if (TCastToPtr light = mgr.ObjectById(x578_lightId)) { + light->SetTranslation(res.GetPoint()); + x7ac_lightPos = res.GetPoint(); + } + } +} +void CDrone::sub_80163c40(float, CStateManager& mgr) {} +void CDrone::sub_801633a8(CStateManager& mgr) {} +void CDrone::sub_8015f25c(float dt, CStateManager& mgr) {} +void CDrone::sub_8015f158(float dt) {} } // namespace urde::MP1 diff --git a/Runtime/MP1/World/CDrone.hpp b/Runtime/MP1/World/CDrone.hpp index 73a81c071..a9585e39a 100644 --- a/Runtime/MP1/World/CDrone.hpp +++ b/Runtime/MP1/World/CDrone.hpp @@ -67,11 +67,10 @@ class CDrone : public CPatterned { CPathFindSearch x6b0_pathFind; zeus::CAxisAngle x794_; zeus::CVector3f x7a0_; - float x7ac_ = 0.f; - float x7b0_ = 0.f; - float x7b4_ = 0.f; + zeus::CVector3f x7ac_lightPos; float x7b8_ = 0.f; float x7bc_ = 0.f; + float x7c4_ = 0.f; s32 x7c8_ = 0; s16 x7cc_; CSfxHandle x7d0_; @@ -102,7 +101,12 @@ class CDrone : public CPatterned { void UpdateLaser(CStateManager& mgr, u32 laserIdx, bool b1); void FireProjectile(CStateManager& mgr, const zeus::CTransform& xf, const TToken& weapon); void StrafeFromCompanions(CStateManager& mgr); + void UpdateScanner(CStateManager& mgr, float dt); + void sub_80163c40(float, CStateManager& mgr); + void sub_801633a8(CStateManager& mgr); + void sub_8015f25c(float dt, CStateManager& mgr); + void sub_8015f158(float dt); public: DEFINE_PATTERNED(Drone); CDrone(TUniqueId uid, std::string_view name, EFlavorType flavor, const CEntityInfo& info, const zeus::CTransform& xf, From 784e9568194c52dbc666d7c074b98997db845c29 Mon Sep 17 00:00:00 2001 From: Phillip Stephens Date: Tue, 7 Apr 2020 16:13:11 -0700 Subject: [PATCH 7/9] Drone: Remove redundant include --- Runtime/MP1/World/CDrone.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/Runtime/MP1/World/CDrone.cpp b/Runtime/MP1/World/CDrone.cpp index ed2158863..58c938794 100644 --- a/Runtime/MP1/World/CDrone.cpp +++ b/Runtime/MP1/World/CDrone.cpp @@ -1,4 +1,3 @@ -#include #include "Runtime/MP1/World/CDrone.hpp" #include "Runtime/Audio/CSfxManager.hpp" From 94dbd091aefe1944c38aa230a0795a158848362c Mon Sep 17 00:00:00 2001 From: Phillip Stephens Date: Wed, 8 Apr 2020 10:54:46 -0700 Subject: [PATCH 8/9] Implement CDroneLaser --- Runtime/MP1/World/CDroneLaser.cpp | 72 +++++++++++++++++++++++++++++++ Runtime/MP1/World/CDroneLaser.hpp | 25 +++++++++++ Runtime/MP1/World/CMakeLists.txt | 1 + 3 files changed, 98 insertions(+) create mode 100644 Runtime/MP1/World/CDroneLaser.cpp create mode 100644 Runtime/MP1/World/CDroneLaser.hpp diff --git a/Runtime/MP1/World/CDroneLaser.cpp b/Runtime/MP1/World/CDroneLaser.cpp new file mode 100644 index 000000000..80b0d2fb1 --- /dev/null +++ b/Runtime/MP1/World/CDroneLaser.cpp @@ -0,0 +1,72 @@ +#include "Runtime/MP1/World/CDroneLaser.hpp" + +#include "Runtime/CSimplePool.hpp" +#include "Runtime/CStateManager.hpp" +#include "Runtime/GameGlobalObjects.hpp" +#include "Runtime/Graphics/CBooRenderer.hpp" +#include "Runtime/Particle/CElementGen.hpp" +#include "Runtime/World/CActorParameters.hpp" +#include "Runtime/World/CGameLight.hpp" + +#include "TCastTo.hpp" // Generated file, do not modify include path + +namespace urde::MP1 { +CDroneLaser::CDroneLaser(TUniqueId uid, TAreaId aId, const zeus::CTransform& xf, CAssetId particle) +: CActor(uid, true, "DroneLaser"sv, CEntityInfo(aId, CEntity::NullConnectionList), xf, CModelData::CModelDataNull(), + CMaterialList(EMaterialTypes::NoStepLogic), CActorParameters::None(), kInvalidUniqueId) +, xf8_beamDesc(g_SimplePool->GetObj({SBIG('PART'), particle})) +, x104_beamParticle(std::make_unique(xf8_beamDesc, CElementGen::EModelOrientationType::Normal, + CElementGen::EOptionalSystemFlags::One)) {} +void CDroneLaser::Accept(IVisitor& visitor) { visitor.Visit(this); } + +void CDroneLaser::Think(float dt, CStateManager& mgr) { x104_beamParticle->Update(dt); } + +void CDroneLaser::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CStateManager& mgr) { + CActor::AcceptScriptMsg(msg, sender, mgr); + + if (msg == EScriptObjectMessage::Deactivate) { + SetScannerLightActive(mgr, false); + x104_beamParticle->SetParticleEmission(false); + } else if (msg == EScriptObjectMessage::Activate) { + SetScannerLightActive(mgr, true); + x104_beamParticle->SetParticleEmission(true); + } else if (msg == EScriptObjectMessage::Deleted) { + if (xf4_scannerLight != kInvalidUniqueId) { + mgr.FreeScriptObject(xf4_); + xf4_scannerLight = kInvalidUniqueId; + } + } else if (msg == EScriptObjectMessage::Registered) { + xf4_scannerLight = mgr.AllocateUniqueId(); + mgr.AddObject(new CGameLight(xf4_scannerLight, GetAreaIdAlways(), GetActive(), "LaserScanner"sv, zeus::CTransform(), + GetUniqueId(), CLight::BuildPoint(zeus::skZero3f, zeus::skRed), 0, 0, 0.f)); + } +} + +void CDroneLaser::AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const { + g_Renderer->AddParticleGen(*x104_beamParticle); + EnsureRendered(mgr); +} + +void CDroneLaser::Render(const CStateManager& mgr) const { + // g_Renderer->SetDepthReadWrite(true, true); + RenderBeam(4, 0.01f, zeus::CColor(1.f, .9f, .9f, 1.f), true); + // g_Renderer->SetDepthReadWrite(true, false); + RenderBeam(5, 0.06f, zeus::CColor(.4f, .0f, .0f, .5f), true); + RenderBeam(7, 0.06f, zeus::CColor(.4f, .2f, .2f, .1f), true); +} + +void CDroneLaser::CalculateRenderBounds() { + zeus::CAABox box = zeus::skInvertedBox; + const zeus::CVector3f diff = xe8_ - GetTranslation(); + const float mag1 = 0.2f * diff.magnitude(); + box.accumulateBounds(diff); + box.accumulateBounds(xe8_ + (mag1 * GetTransform().basis[2])); + box.accumulateBounds(xe8_ - (mag1 * GetTransform().basis[2])); + x9c_renderBounds = box; +} +void CDroneLaser::SetScannerLightActive(CStateManager& mgr, bool activate) { + mgr.SendScriptMsgAlways(xf4_, GetUniqueId(), + activate ? EScriptObjectMessage::Activate : EScriptObjectMessage::Deactivate); +} +void CDroneLaser::RenderBeam(u32 w, float f, const zeus::CColor& col, bool) const {} +} // namespace urde::MP1 diff --git a/Runtime/MP1/World/CDroneLaser.hpp b/Runtime/MP1/World/CDroneLaser.hpp new file mode 100644 index 000000000..783873353 --- /dev/null +++ b/Runtime/MP1/World/CDroneLaser.hpp @@ -0,0 +1,25 @@ +#pragma once +#include "Runtime/World/CActor.hpp" + +namespace urde { +class CElementGen; +namespace MP1 { +class CDroneLaser : public CActor { + zeus::CVector3f xe8_ = zeus::skZero3f; + TUniqueId xf4_scannerLight = kInvalidUniqueId; + TLockedToken xf8_beamDesc; + std::unique_ptr x104_beamParticle; + + void SetScannerLightActive(CStateManager& mgr, bool activate); + void RenderBeam(u32 w, float f, const zeus::CColor& col, bool) const; +public: + CDroneLaser(TUniqueId uid, TAreaId aId, const zeus::CTransform& xf, CAssetId particle); + void Accept(IVisitor& visitor) override; + void Think(float dt, CStateManager& mgr) override; + void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CStateManager& mgr) override; + void AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const override; + void Render(const CStateManager& mgr) const override; + void CalculateRenderBounds() override; +}; +} // namespace MP1 +} // namespace urde \ No newline at end of file diff --git a/Runtime/MP1/World/CMakeLists.txt b/Runtime/MP1/World/CMakeLists.txt index 265e3c6b3..16e6daaa9 100644 --- a/Runtime/MP1/World/CMakeLists.txt +++ b/Runtime/MP1/World/CMakeLists.txt @@ -10,6 +10,7 @@ set(MP1_WORLD_SOURCES CChozoGhost.hpp CChozoGhost.cpp CElitePirate.hpp CElitePirate.cpp CDrone.hpp CDrone.cpp + CDroneLaser.hpp CDroneLaser.cpp CSpacePirate.hpp CSpacePirate.cpp CParasite.hpp CParasite.cpp CBabygoth.hpp CBabygoth.cpp From 244e9febb3bef3d7c70d37b126a3d09eaae87a20 Mon Sep 17 00:00:00 2001 From: Phillip Stephens Date: Wed, 8 Apr 2020 12:20:27 -0700 Subject: [PATCH 9/9] Minor fixes --- Runtime/MP1/World/CDrone.cpp | 56 +++++++++++++++++++++++++++---- Runtime/MP1/World/CDrone.hpp | 5 ++- Runtime/MP1/World/CDroneLaser.cpp | 4 +-- 3 files changed, 53 insertions(+), 12 deletions(-) diff --git a/Runtime/MP1/World/CDrone.cpp b/Runtime/MP1/World/CDrone.cpp index 58c938794..5d79dea7a 100644 --- a/Runtime/MP1/World/CDrone.cpp +++ b/Runtime/MP1/World/CDrone.cpp @@ -6,6 +6,7 @@ #include "Runtime/CStateManager.hpp" #include "Runtime/GameGlobalObjects.hpp" #include "Runtime/Particle/CWeaponDescription.hpp" +#include "Runtime/Weapon/CGameProjectile.hpp" #include "Runtime/Weapon/CWeapon.hpp" #include "Runtime/World/CGameLight.hpp" #include "Runtime/World/CPatternedInfo.hpp" @@ -18,6 +19,8 @@ #include "TCastTo.hpp" // Generated file, do not modify include path +#include + namespace urde::MP1 { CDrone::CDrone(TUniqueId uid, std::string_view name, EFlavorType flavor, const CEntityInfo& info, const zeus::CTransform& xf, float f1, CModelData&& mData, const CPatternedInfo& pInfo, @@ -62,8 +65,8 @@ CDrone::CDrone(TUniqueId uid, std::string_view name, EFlavorType flavor, const C , x6b0_pathFind(nullptr, 3 + int(b1), pInfo.GetPathfindingIndex(), 1.f, 2.4f) , x7cc_(CSfxManager::TranslateSFXID(sId)) , x82c_shieldModel(std::make_unique(CStaticRes{aId2, zeus::skOne3f})) -, x830_13_(0) -, x830_10_(0) +, x832_a(0) +, x832_b(0) , x834_24_(false) , x834_25_(false) , x834_26_(false) @@ -520,9 +523,9 @@ void CDrone::TargetPlayer(CStateManager& mgr, EStateMsg msg, float dt) { x834_30_visible = true; x330_stateMachineState.SetDelay(std::max(0.f, x624_)); } else if (msg == EStateMsg::Update) { - zeus::CVector3f target = (mgr.GetPlayer().GetAimPosition(mgr, 0.f) - GetTranslation()); + zeus::CVector3f target = (mgr.GetPlayer().GetAimPosition(mgr, 0.f) - GetTranslation()).normalized(); x450_bodyController->GetCommandMgr().DeliverCmd( - CBCLocomotionCmd(FLT_EPSILON * GetTransform().basis[1], target.normalized(), 1.f)); + CBCLocomotionCmd(FLT_EPSILON * GetTransform().basis[1], target, 1.f)); x450_bodyController->GetCommandMgr().DeliverTargetVector(target); StrafeFromCompanions(mgr); if (x630_ <= 0.f) @@ -561,7 +564,35 @@ void CDrone::Active(CStateManager& mgr, EStateMsg msg, float dt) { void CDrone::Flee(CStateManager& mgr, EStateMsg msg, float dt) { if (msg == EStateMsg::Activate) { + x7c8_ = 0; + x832_b = 0; + if (mgr.RayStaticIntersection(GetTranslation(), -GetTransform().frontVector(), 4.f, + CMaterialFilter::MakeInclude({EMaterialTypes::Solid})) + .IsValid()) { + x832_b = mgr.GetActiveRandom()->Float() > 0.5f ? 1 : 2; + } } else if (msg == EStateMsg::Update) { + if (x7c8_ == 0) { + if (GetBodyController()->GetBodyStateInfo().GetCurrentStateId() == pas::EAnimationState::Step) { + x7c8_ = 1; + } else { + if (x832_b == 0) { + GetBodyController()->GetCommandMgr().DeliverCmd( + CBCStepCmd(pas::EStepDirection::Backward, pas::EStepType::BreakDodge)); + } else if (x832_b == 1) { + GetBodyController()->GetCommandMgr().DeliverCmd( + CBCStepCmd(pas::EStepDirection::Left, pas::EStepType::Normal)); + } else if (x832_b == 2) { + GetBodyController()->GetCommandMgr().DeliverCmd( + CBCStepCmd(pas::EStepDirection::Right, pas::EStepType::Normal)); + } + } + } else if (x7c8_ == 1 && + GetBodyController()->GetBodyStateInfo().GetCurrentStateId() != pas::EAnimationState::Step) { + x7c8_ = 2; + } + GetBodyController()->GetCommandMgr().DeliverTargetVector( + (mgr.GetPlayer().GetTranslation() - GetTranslation()).normalized()); } } @@ -633,7 +664,7 @@ void CDrone::Retreat(CStateManager& mgr, EStateMsg msg, float dt) { x7c8_ = 1; } else { GetBodyController()->GetCommandMgr().DeliverCmd( - CBCStepCmd(pas::EStepDirection::Forward, pas::EStepType::Normal)); + CBCStepCmd(pas::EStepDirection::Backward, pas::EStepType::Normal)); } } else if (x7c8_ == 1 && GetBodyController()->GetBodyStateInfo().GetCurrentStateId() != pas::EAnimationState::Step) { @@ -726,9 +757,11 @@ void CDrone::PathFindEx(CStateManager& mgr, EStateMsg msg, float dt) { bool CDrone::Leash(CStateManager& mgr, float arg) { return (mgr.GetPlayer().GetTranslation() - GetTranslation()).magSquared() < x3c8_leashRadius * x3c8_leashRadius; } + bool CDrone::InRange(CStateManager& mgr, float arg) { return (mgr.GetPlayer().GetTranslation() - GetTranslation()).magSquared() < x300_maxAttackRange * x300_maxAttackRange; } + bool CDrone::SpotPlayer(CStateManager& mgr, float arg) { if ((mgr.GetPlayer().GetTranslation() - GetTranslation()).magSquared() > x3bc_detectionRange) return false; @@ -740,7 +773,9 @@ bool CDrone::SpotPlayer(CStateManager& mgr, float arg) { .normalized() .dot((mgr.GetPlayer().GetAimPosition(mgr, 0.f) - GetTranslation()).normalized()) > 0.5f; } + bool CDrone::AnimOver(CStateManager& mgr, float arg) { return x7c8_ == 2; } + bool CDrone::ShouldAttack(CStateManager& mgr, float arg) { if (x5d0_ > 0.f) return false; @@ -750,10 +785,17 @@ bool CDrone::ShouldAttack(CStateManager& mgr, float arg) { } return true; } + bool CDrone::HearShot(CStateManager& mgr, float arg) { - // TODO: Finish - return CAi::HearShot(mgr, arg); + rstl::reserved_vector nearList; + BuildNearList(EMaterialTypes::Projectile, EMaterialTypes::Player, nearList, 10.f, mgr); + return std::find_if(nearList.begin(), nearList.end(), [&mgr](TUniqueId uid) { + if (TCastToConstPtr wp = mgr.GetObjectById(uid)) + return wp->GetType() != EWeaponType::AI; + return false; + }) != nearList.end(); } + bool CDrone::CoverCheck(CStateManager& mgr, float arg) { if (!zeus::close_enough(x67c_, zeus::skZero3f)) { const zeus::CVector3f diff = x670_ - GetTranslation(); diff --git a/Runtime/MP1/World/CDrone.hpp b/Runtime/MP1/World/CDrone.hpp index a9585e39a..2939884c3 100644 --- a/Runtime/MP1/World/CDrone.hpp +++ b/Runtime/MP1/World/CDrone.hpp @@ -80,9 +80,8 @@ class CDrone : public CPatterned { rstl::reserved_vector x818_ = {{0.f, 0.f}}; rstl::reserved_vector x824_ = {{false, false}}; std::unique_ptr x82c_shieldModel; - u8 x830_13_ : 2; - u8 x830_10_ : 2; - u16 x832_; + u8 x832_a : 3; + u8 x832_b : 3; bool x834_24_ : 1; bool x834_25_ : 1; bool x834_26_ : 1; diff --git a/Runtime/MP1/World/CDroneLaser.cpp b/Runtime/MP1/World/CDroneLaser.cpp index 80b0d2fb1..2d12a9352 100644 --- a/Runtime/MP1/World/CDroneLaser.cpp +++ b/Runtime/MP1/World/CDroneLaser.cpp @@ -32,7 +32,7 @@ void CDroneLaser::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CS x104_beamParticle->SetParticleEmission(true); } else if (msg == EScriptObjectMessage::Deleted) { if (xf4_scannerLight != kInvalidUniqueId) { - mgr.FreeScriptObject(xf4_); + mgr.FreeScriptObject(xf4_scannerLight); xf4_scannerLight = kInvalidUniqueId; } } else if (msg == EScriptObjectMessage::Registered) { @@ -65,7 +65,7 @@ void CDroneLaser::CalculateRenderBounds() { x9c_renderBounds = box; } void CDroneLaser::SetScannerLightActive(CStateManager& mgr, bool activate) { - mgr.SendScriptMsgAlways(xf4_, GetUniqueId(), + mgr.SendScriptMsgAlways(xf4_scannerLight, GetUniqueId(), activate ? EScriptObjectMessage::Activate : EScriptObjectMessage::Deactivate); } void CDroneLaser::RenderBeam(u32 w, float f, const zeus::CColor& col, bool) const {}