Merge branch 'master' of ssh://git.axiodl.com:6431/AxioDL/urde into shader-refactor

This commit is contained in:
Jack Andersen 2018-10-06 16:59:32 -10:00
commit 9461e98512
71 changed files with 1568 additions and 172 deletions

View File

@ -73,5 +73,5 @@ notifications:
on_build_status_changed: false
# Uncomment this to debug AppVeyor failures.
#on_finish:
# - ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))
on_finish:
- ps: $blockRdp = $true; iex ((new-object net.webclient).DownloadString('https://raw.githubusercontent.com/appveyor/ci/master/scripts/enable-rdp.ps1'))

View File

@ -9,9 +9,9 @@
#define GRPgroup002B 43
#define SFXsfx06DC 1756
#define SFXwpn_bomb_drop 1756
#define SFXsfx06DD 1757
#define SFXsfx06DE 1758
#define SFXwpn_bomb_explo 1758
#define SFXwpn_chargeup_ice 1759
#define SFXsfx06E0 1760
#define SFXsfx06E1 1761

View File

@ -294,7 +294,7 @@ struct PatternedInfo : BigDNA
Value<atUint32> unknown11;
Value<atVec3f> unknown12;
UniqueID32 particle1;
Value<atUint32> unknown13;
UniqueID32 electric;
Value<atVec3f> unknown14;
UniqueID32 particle2;
Value<atUint32> soundID2;
@ -312,6 +312,11 @@ struct PatternedInfo : BigDNA
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle1);
ent->name = name + "_part1";
}
if (electric)
{
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(electric);
ent->name = name + "_elsc";
}
if (particle2)
{
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle2);
@ -324,6 +329,7 @@ struct PatternedInfo : BigDNA
animationParameters.depANCS(pathsOut);
g_curSpec->flattenDependencies(stateMachine, pathsOut);
g_curSpec->flattenDependencies(particle1, pathsOut);
g_curSpec->flattenDependencies(electric, pathsOut);
g_curSpec->flattenDependencies(particle2, pathsOut);
}
};

View File

@ -289,6 +289,9 @@ void CMapArea::CMapAreaSurface::PostConstruct(const u8* buf, std::vector<u32>& i
void CMapArea::CMapAreaSurface::Draw(const zeus::CVector3f* verts, const zeus::CColor& surfColor,
const zeus::CColor& lineColor, float lineWidth, int instIdx) const
{
if (instIdx >= m_instances.size())
return;
Instance& instance = const_cast<Instance&>(m_instances[instIdx]);
if (surfColor.a)

View File

@ -204,7 +204,7 @@ void CMappableObject::Draw(int curArea, const CMapWorldInfo& mwInfo,
TLockedToken<CTexture> tex = g_SimplePool->GetObj(SObjectTag{FOURCC('TXTR'), iconRes});
if (!m_texQuadFilter || m_texQuadFilter->GetTex().GetObj() != tex.GetObj())
const_cast<CMappableObject*>(this)->m_texQuadFilter.emplace(EFilterType::Blend, tex);
const_cast<CMappableObject*>(this)->m_texQuadFilter.emplace(EFilterType::Add, tex);
CTexturedQuadFilter::Vert verts[4] =
{

View File

@ -41,6 +41,7 @@ public:
void InitializeWorldLayers(const std::vector<CWorldLayers::Area>& layers);
u32 GetAreaLayerCount(int areaIdx) const { return x0_areaLayers[areaIdx].m_layerCount; }
u32 GetAreaCount() const { return x0_areaLayers.size(); }
void PutTo(CBitStreamWriter& writer) const;
};

View File

@ -216,7 +216,7 @@ bool CResLoader::FindResource(CAssetId id) const
return true;
}
Log.report(logvisor::Fatal, "Unable to find asset %08X", id);
Log.report(logvisor::Warning, "Unable to find asset %08X", id);
return false;
}

View File

@ -1734,7 +1734,7 @@ bool CStateManager::ApplyLocalDamage(const zeus::CVector3f& vec1, const zeus::CV
hInfo->SetHP(newHp);
bool significant = std::fabs(newHp - hInfo->GetHP()) >= 0.00001;
if (player)
if (player && GetPlayerState()->CanTakeDamage())
{
player->TakeDamage(significant, vec1, mulDam, weapMode.GetType(), *this);
if (newHp <= 0.f)
@ -2008,8 +2008,11 @@ void CStateManager::Update(float dt)
xf94_27_inMapScreen = false;
}
g_GameState->CurrentWorldState().SetAreaId(x8cc_nextAreaId);
x850_world->TravelToArea(x8cc_nextAreaId, *this, false);
if (!m_warping)
{
g_GameState->CurrentWorldState().SetAreaId(x8cc_nextAreaId);
x850_world->TravelToArea(x8cc_nextAreaId, *this, false);
}
ClearGraveyard();
++x8d8_updateFrameIdx;

View File

@ -235,6 +235,7 @@ private:
CColoredQuadFilter m_deathWhiteout = { EFilterType::Add };
CColoredQuadFilter m_escapeWhiteout = { EFilterType::Add };
bool m_warping = false;
void UpdateThermalVisor();
static void RendererDrawCallback(const void*, const void*, int);
@ -472,6 +473,8 @@ public:
std::shared_ptr<CWorldLayerState>& WorldLayerStateNC() { return x8c8_worldLayerState; }
static float g_EscapeShakeCountdown;
static bool g_EscapeShakeCountdownInit;
void SetWarping(bool v) { m_warping = true; }
};
}

View File

@ -237,7 +237,7 @@ bool CAnimData::IsAdditiveAnimationActive(u32 idx) const
return search->second.IsActive();
}
void CAnimData::DelAdditiveAnimation(u32 idx)
void CAnimData::DelAdditiveAnimation(s32 idx)
{
u32 animIdx = xc_charInfo.GetAnimationIndex(idx);
for (std::pair<u32, CAdditiveAnimPlayback>& anim : x434_additiveAnims)
@ -252,7 +252,7 @@ void CAnimData::DelAdditiveAnimation(u32 idx)
}
}
void CAnimData::AddAdditiveAnimation(u32 idx, float weight, bool active, bool fadeOut)
void CAnimData::AddAdditiveAnimation(s32 idx, float weight, bool active, bool fadeOut)
{
u32 animIdx = xc_charInfo.GetAnimationIndex(idx);
for (std::pair<u32, CAdditiveAnimPlayback>& anim : x434_additiveAnims)

View File

@ -176,8 +176,8 @@ public:
const std::shared_ptr<CAnimTreeNode>& GetRootAnimationTree() const { return x1f8_animRoot; }
const std::shared_ptr<CAnimTreeNode>& GetAdditiveAnimationTree(u32) const;
bool IsAdditiveAnimationActive(u32) const;
void DelAdditiveAnimation(u32);
void AddAdditiveAnimation(u32, float, bool, bool);
void DelAdditiveAnimation(s32);
void AddAdditiveAnimation(s32, float, bool, bool);
float GetAdditiveAnimationWeight(u32 idx) const;
std::shared_ptr<CAnimationManager> GetAnimationManager();
const CCharacterInfo& GetCharacterInfo() const { return xc_charInfo; }

View File

@ -90,7 +90,7 @@ void CBodyController::Update(float dt, CStateManager& mgr)
if (x300_25_active)
{
x300_24_animationOver =
!x0_actor.GetModelData()->GetAnimationData()->IsAnimTimeRemaining(dt, "Whole Body");
!x0_actor.GetModelData()->GetAnimationData()->IsAnimTimeRemaining(dt, "Whole Body"sv);
x4_cmdMgr.BlendSteeringCmds();
x2dc_rot = zeus::CQuaternion::skNoRotation;
UpdateBody(dt, mgr);
@ -306,7 +306,7 @@ void CBodyController::UpdateFrozenInfo(float dt, CStateManager& mgr)
{
UnFreeze();
x0_actor.SendScriptMsgs(EScriptObjectState::UnFrozen, mgr, EScriptObjectMessage::None);
mgr.GetActorModelParticles()->StartIce(x0_actor, mgr);
mgr.GetActorModelParticles()->StartIce(x0_actor);
return;
}
if (x310_timeFrozen <= totalTime)

View File

@ -63,6 +63,7 @@ public:
const CBodyStateInfo& GetBodyStateInfo() const { return x2a4_bodyStateInfo; }
CBodyStateInfo& BodyStateInfo() { return x2a4_bodyStateInfo; }
float GetTurnSpeed() const { return x2fc_turnSpeed; }
void SetLocomotionType(pas::ELocomotionType type) { x2ec_locomotionType = type; }
pas::ELocomotionType GetLocomotionType() const { return x2ec_locomotionType; }
CActor& GetOwner() const { return x0_actor; }
bool IsAnimationOver() const { return x300_24_animationOver; }
@ -106,6 +107,7 @@ public:
EBodyType GetBodyType() const { return x2f4_bodyType; }
bool HasBeenFrozen() const { return x300_27_hasBeenFrozen; }
float GetRestrictedFlyerMoveSpeed() const { return x330_restrictedFlyerMoveSpeed; }
bool GetActive() const { return x300_25_active; }
};
}

View File

@ -29,15 +29,15 @@ CCharacterInfo::CParticleResData::CParticleResData(CInputStream& in, u16 tableCo
}
}
static std::vector<std::pair<u32, std::pair<std::string, std::string>>>
static std::vector<std::pair<s32, std::pair<std::string, std::string>>>
MakeAnimInfoVector(CInputStream& in)
{
std::vector<std::pair<u32, std::pair<std::string, std::string>>> ret;
std::vector<std::pair<s32, std::pair<std::string, std::string>>> ret;
u32 animInfoCount = in.readUint32Big();
ret.reserve(animInfoCount);
for (u32 i=0 ; i<animInfoCount ; ++i)
{
u32 idx = in.readUint32Big();
s32 idx = in.readInt32Big();
std::string a = in.readString();
std::string b = in.readString();
ret.emplace_back(idx, std::make_pair(a, b));
@ -99,4 +99,15 @@ CCharacterInfo::CCharacterInfo(CInputStream& in)
}
}
const s32 CCharacterInfo::GetAnimationIndex(std::string_view name) const
{
for (const auto& pair : x20_animInfo)
{
if (pair.second.second.compare(name.data()) == 0)
return pair.first;
}
return -1;
}
}

View File

@ -29,7 +29,7 @@ private:
CAssetId x14_cmdl;
CAssetId x18_cskr;
CAssetId x1c_cinf;
std::vector<std::pair<u32, std::pair<std::string, std::string>>> x20_animInfo;
std::vector<std::pair<s32, std::pair<std::string, std::string>>> x20_animInfo;
CPASDatabase x30_pasDatabase;
CParticleResData x44_partRes;
u32 x84_unk;
@ -61,6 +61,8 @@ public:
const CParticleResData& GetParticleResData() const { return x44_partRes; }
s32 GetAnimationIndex(s32 idx) const { return xb0_animIdxs.at(idx); }
const CPASDatabase& GetPASDatabase() const { return x30_pasDatabase; }
const s32 GetAnimationIndex(std::string_view) const;
};
}

View File

@ -110,7 +110,7 @@ CSequenceFundamentals CSequenceHelper::ComputeSequenceFundamentals()
if (i < x10_treeNodes.size()-1)
{
node = CTreeUtils::GetTransitionTree(node,
CAnimTreeNode::Cast(x10_treeNodes[i+1]->Clone()), x0_animCtx);
CAnimTreeNode::Cast(std::move(x10_treeNodes[i+1]->Clone())), x0_animCtx);
}
}
}

View File

@ -35,4 +35,15 @@ CSteeringBehaviors::ProjectOrbitalPosition(const zeus::CVector3f& pos, const zeu
return usePos;
}
bool CSteeringBehaviors::SolveQuadratic(float f30, float f31, float f3, float f4, float& out1, float& out2)
{
float f1 = f31 * f31 - 4.f * f30 * f3;
if (f1 > FLT_EPSILON && std::fabs(f1) < FLT_EPSILON)
return false;
out1 = -f31 + std::sqrt(f1) / 2.f * f30;
out2 = -f31 - std::sqrt(f1) / 2.f * f30;
return true;
}
}

View File

@ -13,6 +13,7 @@ class CSteeringBehaviors
public:
static zeus::CVector3f ProjectOrbitalPosition(const zeus::CVector3f& pos, const zeus::CVector3f& vel,
const zeus::CVector3f& orbitPoint, float dt, float preThinkDt);
static bool SolveQuadratic(float, float, float, float, float&, float&);
};
}

View File

@ -1046,6 +1046,11 @@ void CBooRenderer::AddParticleGen(const CParticleGen& gen)
}
}
void CBooRenderer::AddParticleGen(const CParticleGen& gen, const zeus::CVector3f& pos, const zeus::CAABox& bounds)
{
Buckets::Insert(pos, bounds, EDrawableType::Particle, &gen, xb0_viewPlane, 0);
}
void CBooRenderer::AddPlaneObject(const void* obj, const zeus::CAABox& aabb, const zeus::CPlane& plane, int type)
{
zeus::CVector3f closePoint = aabb.closestPointAlongVector(xb0_viewPlane.normal());

View File

@ -221,6 +221,7 @@ public:
void DrawModelFlat(const CModel& model, const CModelFlags& flags, bool unsortedOnly);
void PostRenderFogs();
void AddParticleGen(const CParticleGen&);
void AddParticleGen(const CParticleGen&, const zeus::CVector3f&, const zeus::CAABox&);
void AddPlaneObject(const void*, const zeus::CAABox&, const zeus::CPlane&, int);
void AddDrawable(void const *, const zeus::CVector3f&, const zeus::CAABox&, int, EDrawableSorting);
void SetDrawableCallback(TDrawableCallback, const void*);

View File

@ -266,7 +266,7 @@ CBooModel::ModelInstance* CBooModel::PushNewModelInstance(int sharedLayoutBuf)
if (!x40_24_texturesLoaded && !g_DummyTextures)
return nullptr;
if (m_instances.size() >= 256)
if (m_instances.size() >= 512)
Log.report(logvisor::Fatal, "Model buffer overflow");
m_instances.emplace_back();
ModelInstance& newInst = m_instances.back();

View File

@ -57,6 +57,7 @@ public:
virtual void DrawModelFlat(const CModel& model, const CModelFlags& flags, bool unsortedOnly)=0;
virtual void PostRenderFogs()=0;
virtual void AddParticleGen(const CParticleGen&)=0;
virtual void AddParticleGen(const CParticleGen&, const zeus::CVector3f&, const zeus::CAABox&)=0;
virtual void AddPlaneObject(const void*, const zeus::CAABox&, const zeus::CPlane&, int)=0;
virtual void AddDrawable(void const *, const zeus::CVector3f&, const zeus::CAABox&, int, EDrawableSorting)=0;
virtual void SetDrawableCallback(TDrawableCallback, const void*)=0;

View File

@ -1597,7 +1597,7 @@ void CSamusHud::Draw(const CStateManager& mgr, float alpha,
if (x29c_decoIntf && !x2cc_preLoadCountdown)
x29c_decoIntf->Draw();
if (x2bc_nextState >= EHudState::Combat && x2bc_nextState <= EHudState::Scan)
if (x2bc_nextState >= EHudState::Combat && x2bc_nextState < EHudState::Scan)
{
if (hudVis &&
helmetVis != CInGameGuiManager::EHelmetVisMode::ReducedUpdate &&

View File

@ -368,10 +368,16 @@ void CMain::AddWorldPaks()
for (int i=0 ; i<9 ; ++i)
{
std::string path(pakPrefix);
if (i != 0)
path += '0' + i;
std::string lowerPath(path);
athena::utility::tolower(lowerPath);
if (CDvdFile::FileExists((path + ".upak").c_str()))
loader->AddPakFileAsync(path, false, true);
else if (CDvdFile::FileExists((lowerPath + ".upak").c_str()))
loader->AddPakFileAsync(lowerPath, false, true);
}
loader->WaitForPakFileLoadingComplete();
}
@ -493,7 +499,7 @@ void CMain::Give(hecl::Console* console, const std::vector<std::string>& args)
else
pState->DecrPickup(eType, zeus::clamp(0u, u32(abs(itemAmt)), pState->GetItemAmount(eType)));
}
g_StateManager->Player()->AsyncLoadSuit(*g_StateManager);
console->report(hecl::Console::Level::Info, "Cheater....., Greatly increasing Metroid encounters, have fun!");
}
@ -533,6 +539,7 @@ void CMain::Teleport(hecl::Console *, const std::vector<std::string>& args)
void CMain::ListWorlds(hecl::Console* con, const std::vector<std::string> &)
{
if (g_ResFactory && g_ResFactory->GetResLoader())
{
for (const auto& pak : g_ResFactory->GetResLoader()->GetPaks())
@ -540,11 +547,70 @@ void CMain::ListWorlds(hecl::Console* con, const std::vector<std::string> &)
{
for (const auto& named : pak->GetNameList())
if (named.second.type == SBIG('MLVL'))
con->report(hecl::Console::Level::Info, "%s '%08X'", named.first.c_str(), named.second.id.Value());
{
con->report(hecl::Console::Level::Info, "%s '%08X'", named.first.c_str(),
named.second.id.Value());
}
}
}
}
void CMain::WarpTo(hecl::Console* con, const std::vector<std::string>& args)
{
if (!g_StateManager)
return;
if (args.size() < 1)
return;
TAreaId aId;
std::string worldName;
if (args.size() == 2)
{
worldName = args[0];
athena::utility::tolower(worldName);
aId = strtol(args[1].c_str(), nullptr, 10);
}
else
aId = strtol(args[0].c_str(), nullptr, 10);
if (!worldName.empty() && g_ResFactory && g_ResFactory->GetResLoader())
{
bool found = false;
for (const auto& pak : g_ResFactory->GetResLoader()->GetPaks())
{
if (found)
break;
if (pak->IsWorldPak())
{
for (const auto& named : pak->GetNameList())
if (named.second.type == SBIG('MLVL'))
{
std::string name = named.first;
athena::utility::tolower(name);
if (name.find(worldName) != std::string::npos)
{
g_GameState->SetCurrentWorldId(named.second.id);
found = true;
break;
}
}
}
}
}
g_GameState->GetWorldTransitionManager()->DisableTransition();
if (aId >= g_GameState->CurrentWorldState().GetLayerState()->GetAreaCount())
aId = 0;
g_GameState->CurrentWorldState().SetAreaId(aId);
g_Main->SetFlowState(EFlowState::None);
g_StateManager->SetWarping(true);
g_StateManager->SetShouldQuitGame(true);
}
void CMain::StreamNewGameState(CBitStreamReader& r, u32 idx)
{
bool fusionBackup = g_GameState->SystemOptions().GetPlayerFusionSuitActive();
@ -646,11 +712,12 @@ void CMain::Init(const hecl::Runtime::FileStoreManager& storeMgr,
m_mainWindow = window;
m_cvarMgr = cvarMgr;
m_console = std::make_unique<hecl::Console>(m_cvarMgr);
m_console->registerCommand("quit"sv, "Quits the game immediately"sv, ""sv, std::bind(&CMain::quit, this, std::placeholders::_1, std::placeholders::_2));
m_console->registerCommand("Quit"sv, "Quits the game immediately"sv, ""sv, std::bind(&CMain::quit, this, std::placeholders::_1, std::placeholders::_2));
m_console->registerCommand("Give"sv, "Gives the player the specified item, maxing it out"sv, ""sv, std::bind(&CMain::Give, this, std::placeholders::_1, std::placeholders::_2), hecl::SConsoleCommand::ECommandFlags::Cheat);
m_console->registerCommand("Teleport"sv, "Teleports the player to the specified coordinates in worldspace"sv, "x y z [dX dY dZ]"sv, std::bind(&CMain::Teleport, this, std::placeholders::_1, std::placeholders::_2), (hecl::SConsoleCommand::ECommandFlags::Cheat | hecl::SConsoleCommand::ECommandFlags::Developer));
m_console->registerCommand("God"sv, "Disables damage given by enemies and objects"sv, ""sv, std::bind(&CMain::God, this, std::placeholders::_1, std::placeholders::_2), hecl::SConsoleCommand::ECommandFlags::Cheat);
m_console->registerCommand("listWorlds"sv, "Lists loaded worlds"sv, ""sv, std::bind(&CMain::ListWorlds, this, std::placeholders::_1, std::placeholders::_2), hecl::SConsoleCommand::ECommandFlags::Normal);
m_console->registerCommand("ListWorlds"sv, "Lists loaded worlds"sv, ""sv, std::bind(&CMain::ListWorlds, this, std::placeholders::_1, std::placeholders::_2), hecl::SConsoleCommand::ECommandFlags::Normal);
m_console->registerCommand("WarpTo"sv, "Warps to a given area and world"sv, "[worldname] areaId"sv, std::bind(&CMain::WarpTo, this, std::placeholders::_1, std::placeholders::_2), hecl::SConsoleCommand::ECommandFlags::Normal);
InitializeSubsystems();
x128_globalObjects.PostInitialize();

View File

@ -335,6 +335,7 @@ public:
void God(hecl::Console*, const std::vector<std::string>&);
void Teleport(hecl::Console*, const std::vector<std::string>&);
void ListWorlds(hecl::Console*, const std::vector<std::string>&);
void WarpTo(hecl::Console*, const std::vector<std::string>&);
hecl::Console* Console() const { return m_console.get(); }
};

View File

@ -19,6 +19,7 @@ public:
};
private:
public:
DEFINE_PATTERNED(Beetle)
CBeetle(TUniqueId, std::string_view, const CEntityInfo&, const zeus::CTransform&, CModelData&&,
const CPatternedInfo&, CPatterned::EFlavorType,EEntranceType, const CDamageInfo &, const CDamageVulnerability&,
const zeus::CVector3f&, float, float, float, const CDamageVulnerability&, const CActorParameters&,

View File

@ -35,7 +35,7 @@ class CMetaree : public CPatterned
u32 x5cc_;
public:
static constexpr ECharacter CharacterType = ECharacter::Metaree;
DEFINE_PATTERNED(Metaree)
CMetaree(TUniqueId, std::string_view, EFlavorType, const CEntityInfo&, const zeus::CTransform&, CModelData&&,
const CPatternedInfo&, const CDamageInfo&, float, const zeus::CVector3f&, float, EBodyType, float, float,
const CActorParameters&);

View File

@ -29,7 +29,7 @@ public:
class CMetroid : public CPatterned
{
public:
static constexpr ECharacter CharacterType = ECharacter::Metroid;
DEFINE_PATTERNED(Metroid)
CMetroid(TUniqueId uid, std::string_view name, EFlavorType flavor, const CEntityInfo& info,
const zeus::CTransform& xf, CModelData&& mData, const CPatternedInfo& pInfo,
const CActorParameters& aParms, const CMetroidData& metroidData);

View File

@ -10,7 +10,7 @@ namespace urde::MP1
class CMetroidBeta : public CPatterned
{
public:
static constexpr ECharacter CharacterType = ECharacter::MetroidBeta;
DEFINE_PATTERNED(MetroidBeta)
CMetroidBeta(TUniqueId uid, std::string_view name, const CEntityInfo& info,
const zeus::CTransform& xf, CModelData&& mData, const CPatternedInfo& pInfo,
const CActorParameters& aParms, const CMetroidData& metroidData);

View File

@ -103,7 +103,7 @@ struct SPrimeExoRoomParameters
class CMetroidPrimeExo : public CPatterned
{
public:
static constexpr ECharacter CharacterType = ECharacter::MetroidPrimeExo;
DEFINE_PATTERNED(MetroidPrimeExo)
CMetroidPrimeExo(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf,
CModelData&& mData, const CPatternedInfo& pInfo, const CActorParameters& aParms,
u32 pw1, const CCameraShakeData& shakeData1, const CCameraShakeData& shakeData2,

View File

@ -13,6 +13,7 @@ namespace MP1
class CNewIntroBoss : public CPatterned
{
public:
DEFINE_PATTERNED(NewIntroBoss)
CNewIntroBoss(TUniqueId uid, std::string_view name, const CEntityInfo& info,
const zeus::CTransform& xf, CModelData&& mData, const CPatternedInfo& pInfo,
const CActorParameters& actParms, float, u32, const CDamageInfo& dInfo,

View File

@ -1,19 +1,270 @@
#include "CParasite.hpp"
#include "Character/CModelData.hpp"
#include "TCastTo.hpp"
#include "World/CActorParameters.hpp"
#include "World/CPatternedInfo.hpp"
#include "World/CWorld.hpp"
#include "World/CGameArea.hpp"
#include "World/CPlayer.hpp"
#include "CStateManager.hpp"
#include "TCastTo.hpp"
namespace urde::MP1 {
CParasite::CParasite(TUniqueId uid, std::string_view name, EFlavorType flavor, const CEntityInfo &info, const zeus::CTransform &xf,
CModelData &&mData, const CPatternedInfo &pInfo, u32, float, float, float, float, float, float, float, float,
float, float, float, float, float, float, float, float, float, float, bool, u32, const CDamageVulnerability &,
const CParasiteInfo &, u16, u16, u16, u32, u32, float, const CActorParameters &aParams)
: CWallWalker(ECharacter::Parasite, uid, name, flavor, info, xf, std::move(mData), pInfo, EMovementType::Ground, EColliderType::One, EBodyType::WallWalker,
aParams, -1, 0)
namespace urde::MP1
{
const float CParasite::flt_805A8FB0 = 2.f * std::sqrt(2.5f / 24.525002f);
const float CParasite::skAttackVelocity = 15.f / 2.f * (std::sqrt(2.5f / 24.525002f));
short CParasite::word_805A8FC0 = 0;
const float CParasite::flt_805A8FB8 = 2.f * std::sqrt(2.5f / 24.525002f);
const float CParasite::skRetreatVelocity = 3.f / 2.f * std::sqrt(2.5f / 24.525002f);
CParasite::CParasite(TUniqueId uid, std::string_view name, EFlavorType flavor, const CEntityInfo &info,
const zeus::CTransform &xf, CModelData &&mData, const CPatternedInfo &pInfo, EBodyType bodyType,
float f1, 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,
bool b1, u32 w1, const CDamageVulnerability& dVuln,const CDamageInfo& parInfo, u16 sfxId1,
u16 sfxId2, u16 sfxId3, u32 w2, u32 w3, float f19, const CActorParameters &aParams)
: CWallWalker(ECharacter::Parasite, uid, name, flavor, info, xf, std::move(mData), pInfo, EMovementType::Flyer,
EColliderType::Zero, bodyType, aParams, f7, f4, 0, f2, w1, f17, b1)
, x64c_(dVuln)
, x6b4_(parInfo)
, x6d0_(f1)
, x6d4_(f3)
, x6dc_(f5)
, x6e0_(f6)
, x6e4_(f8)
, x6e8_(f9)
, x6ec_(f10)
, x6f0_(f11)
, x6f4_(f12)
, x6f8_(f13)
, x6fc_(f14)
, x700_(f15)
, x704_(f16)
, x708_(pInfo.GetHeight() * 0.5f)
, x710_(f18)
, x714_(f19)
, x73c_(CSfxManager::TranslateSFXID(sfxId1))
, x73e_(CSfxManager::TranslateSFXID(sfxId2))
, x740_(CSfxManager::TranslateSFXID(sfxId3))
{
x742_28_ = true;
x742_30_ = true;
switch(x5d0_)
{
case 2:
//x460_.x81_25_ = false;
case 1:
//x460_.sub80233d64(false);
break;
case 3:
default:
break;
}
if (x5d0_ == 1)
{
}
}
void CParasite::Accept(IVisitor &visitor) { visitor.Visit(this); }
void CParasite::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr)
{
CPatterned::AcceptScriptMsg(msg, uid, mgr);
if (msg == EScriptObjectMessage::Registered)
{
x450_bodyController->Activate(mgr);
/* TODO: Finish 8015A0E8*/
}
else if (msg == EScriptObjectMessage::Deleted)
{
//mgr.xf54_.sub80125d88(GetUniqueId());
if (x5d0_ != 3)
DestroyActorManager(mgr);
}
else if (msg == EScriptObjectMessage::Jumped && x742_25_)
{
UpdateJumpVelocity();
x742_25_ = false;
}
else if (msg == EScriptObjectMessage::Activate)
{
x5d6_27_ = false;
if (x5d0_ != 0)
x450_bodyController->SetLocomotionType(pas::ELocomotionType::Lurk);
}
else if (msg == EScriptObjectMessage::SuspendedMove)
{
}
}
void CParasite::PreThink(float dt, CStateManager& mgr)
{
CWallWalker::PreThink(dt, mgr);
x743_26_ = false;
}
void CParasite::Think(float dt, CStateManager& mgr)
{
if (!GetActive())
return;
++x5d4_;
if (x5d0_ == 3)
UpdateCollisionActors(mgr);
x5d6_26_ = false;
CGameArea* area = mgr.WorldNC()->GetArea(GetAreaIdAlways());
CGameArea::EOcclusionState r6 = CGameArea::EOcclusionState::Occluded;
if (area->IsPostConstructed())
r6 = area->GetPostConstructed()->x10dc_occlusionState;
if (r6 != CGameArea::EOcclusionState::Visible)
x5d6_26_ = true;
if (!x5d6_26_)
{
zeus::CVector3f plVec = mgr.GetPlayer().GetTranslation();
float distance = (GetTranslation() - plVec).magnitude() ;
if (distance > x5c4_)
{
CRayCastResult res = mgr.RayStaticIntersection(plVec, (GetTranslation() - plVec).normalized(), distance,
CMaterialFilter::skPassEverything);
if (res.IsValid())
x5d6_26_ = true;
}
}
if (x5d6_26_)
{
xf8_24_movable = x5d6_26_;
return;
}
xf8_24_movable = !xf8_24_movable;
if (!x5d6_27_)
{
if (x450_bodyController->IsFrozen())
{
if ((GetTranslation() - x614_).magSquared() < 0.3f /* <- Used to be a static variable */ * dt)
x60c_ += dt;
else
x60c_ = 0.f;
x614_ = GetTranslation();
if (x608_ > 0.f)
x608_ -= dt;
else
x608_ = 0.f;
}
}
if (x400_25_)
{
CPlayer* pl = mgr.Player();
float radius;
if (pl->GetMorphballTransitionState() == CPlayer::EPlayerMorphBallState::Morphed && !x742_30_)
radius = x590_colSphere.GetSphere().radius;
else
radius = x708_;
zeus::CAABox aabox{GetTranslation() - radius, GetTranslation() + radius};
auto plBox = pl->GetTouchBounds();
if (plBox && plBox->intersects(aabox))
{
if (!x742_30_)
{
x742_30_ = true;
x742_27_ = false;
}
if (x420_curDamageTime <= 0.f)
{
mgr.ApplyDamage(GetUniqueId(), pl->GetUniqueId(), GetUniqueId(), GetContactDamage(),
CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Solid}, {}), {});
x420_curDamageTime = x424_damageWaitTime;
}
}
}
CWallWalker::Think(dt, mgr);
if (x5d6_27_)
return;
if (x450_bodyController->IsFrozen())
return;
x3b4_speed = x604_;
if (x5d6_24_)
AlignToFloor(mgr, x590_colSphere.GetSphere().radius, GetTranslation() + 2.f * dt * x138_velocity, dt);
x742_27_ = false;
}
void CParasite::DestroyActorManager(CStateManager& mgr)
{
//x620_->Destroy(mgr);
}
void CParasite::UpdateJumpVelocity()
{
x150_momentum.x = 0;
x150_momentum.y = 0;
x150_momentum.z = -GetWeight();
zeus::CVector3f vec;
if (!x742_30_)
{
vec = skAttackVelocity * GetTransform().frontVector();
vec.z = 0.5f * skRetreatVelocity;
}
else
{
vec = skRetreatVelocity * GetTransform().frontVector();
vec.z = 0.5f * skAttackVelocity;
}
float f30 = x150_momentum.z / xe8_mass;
float f31 = x600_ - GetTranslation().z;
zeus::CVector3f vec2;
vec2.x = x5f8_ - GetTranslation().x;
vec2.y = x5fc_ * GetTranslation().y;
vec2.z = 0.f;
float f29 = vec2.magnitude();
if (f29 > FLT_EPSILON)
{
vec2 *= zeus::CVector3f{1.f / f29};
float f28 = vec2.dot(vec);
if (f28 > FLT_EPSILON)
{
float f27 = 0.f;
bool isNeg = f31 < 0.f;
float out1, out2;
if (CSteeringBehaviors::SolveQuadratic(f30, vec.z, -f31, vec2.y, out1, out2))
f27 = isNeg ? out1 : out2;
if (!isNeg)
f27 = f27 * f29 / f28;
if (f27 < 10.f)
{
vec = f29 / f27 * vec2;
vec.z = (0.5f * f30 * f27 + f31 / f27);
}
}
}
SetVelocityWR(vec);
}
void CParasite::AlignToFloor(CStateManager&, float, const zeus::CVector3f&, float)
{
}
} // namespace urde::MP1

View File

@ -2,7 +2,7 @@
#define __URDE_MP1_CPARASITE_HPP__
#include "World/CWallWalker.hpp"
#include "Collision/CCollisionActorManager.hpp"
namespace urde
{
class CModelData;
@ -10,40 +10,109 @@ class CModelData;
namespace urde::MP1
{
struct CParasiteInfo
{
u32 x0_ = 0;
union
{
struct
{
bool x4_24_ : 1; bool x4_26_ : 1;
};
u32 x4_dummy = 0;
};
float x8_ = 0.f;
float xc_ = 0.f;
float x10_ = 0.f;
float x14_ = 0.f;
union
{
struct
{
bool x18_24_ : 1;
};
u32 x18_dummy = 0;
};
};
class CParasite : public CWallWalker
{
class CRepulsor
{
};
static const float flt_805A8FB0;
static const float skAttackVelocity;
static short word_805A8FC0;
static const float flt_805A8FB8;
static const float skRetreatVelocity;
std::vector<CRepulsor> x5d8_doorRepulsors;
s32 x5e8_ = -1;
float x5ec_ = 0.f;
float x5f0_ = 0.f;
float x5f4_ = 0.f;
float x5f8_ = 0.f;
float x5fc_ = 0.f;
float x600_ = 0.f;
float x604_ = 1.f;
float x608_ = 0.f;
float x60c_ = 0.f;
zeus::CVector3f x614_;
std::unique_ptr<CCollisionActorManager> x620_ = 0;
u32 x624_ = 0;
float x628_ = 0.f;
float x62c_ = 0.f;
float x630_ = 0.f;
float x634_ = 0.f;
float x638_ = 0.f;
float x640_ = 0.f;
float x644_ = 0.f;
float x648_ = 0.f;
CDamageVulnerability x64c_;
CDamageInfo x6b4_;
float x6d0_;
float x6d4_;
float x6dc_;
float x6e0_;
float x6e4_;
float x6e8_;
float x6ec_;
float x6f0_;
float x6f4_;
float x6f8_;
float x6fc_;
float x700_;
float x704_;
float x708_;
float x710_;
float x714_;
float x718_ = 0.f;
float x71c_ = 0.f;
float x720_ = 0.f;
float x724_ = 0.f;
float x728_ = 0.f;
float x72c_ = 0.f;
float x730_ = 0.f;
float x734_ = 0.f;
float x738_ = 0.f;
s16 x73c_;
s16 x73e_;
s16 x740_;
union
{
struct
{
bool x742_24_ : 1;
bool x742_25_ : 1;
bool x742_26_ : 1;
bool x742_27_ : 1;
bool x742_28_ : 1;
bool x742_29_ : 1;
bool x742_30_ : 1;
bool x742_31_ : 1;
bool x743_24_ : 1;
bool x743_25_ : 1;
bool x743_26_ : 1;
bool x743_27_ : 1;
};
u16 _dummy = 0;
};
public:
CParasite(TUniqueId uid, std::string_view name, EFlavorType flavor, const CEntityInfo& info, const zeus::CTransform& xf,
CModelData&& mData, const CPatternedInfo&, u32, float, float, float, float, float, float, float, float, float,
float, float, float, float, float, float, float, float, float, bool, u32, const CDamageVulnerability&, const CParasiteInfo&, u16, u16,
u16, u32, u32, float, const CActorParameters&);
DEFINE_PATTERNED(Parasite)
CParasite(TUniqueId uid, std::string_view name, EFlavorType flavor, const CEntityInfo& info,
const zeus::CTransform& xf, CModelData&& mData, const CPatternedInfo&, EBodyType, float, float, float,
float, float, float, float, float, float, float, float, float, float, float, float, float, float, float,
bool, u32, const CDamageVulnerability&, const CDamageInfo&, u16, u16, u16, u32, u32, float,
const CActorParameters&);
void Accept(IVisitor&);
void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&);
void PreThink(float, CStateManager&);
void Think(float dt, CStateManager& mgr);
void DestroyActorManager(CStateManager& mgr);
void UpdateJumpVelocity();
void UpdateCollisionActors(CStateManager&) {}
CDamageInfo GetContactDamage() const
{
if (x5d0_ == 1 && x743_24_)
return x6b4_;
return CPatterned::GetContactDamage();
}
void AlignToFloor(CStateManager&, float, const zeus::CVector3f&, float);
};
}
#endif // __URDE_MP1_CPARASITE_HPP__

View File

@ -9,7 +9,7 @@ namespace urde::MP1
class CPuddleToadGamma : public CPatterned
{
public:
static constexpr ECharacter CharacterType = ECharacter::PuddleToad;
DEFINE_PATTERNED(PuddleToad)
CPuddleToadGamma(TUniqueId uid, std::string_view name, EFlavorType flavor, const CEntityInfo& info,
const zeus::CTransform& xf, CModelData&& mData, const CPatternedInfo& pInfo,
const CActorParameters& aParms, float f1, float f2, float f3, const zeus::CVector3f& v1,

View File

@ -62,6 +62,7 @@ class CRidley : public CPatterned
{
CRidleyData x568_;
public:
DEFINE_PATTERNED(Ridley)
CRidley(TUniqueId, std::string_view, const CEntityInfo&, const zeus::CTransform&, CModelData&&,
const CPatternedInfo&, const CActorParameters&, CInputStream&, u32);

View File

@ -8,8 +8,9 @@ namespace MP1
CSeedling::CSeedling(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf,
CModelData&& mData, const CPatternedInfo& pInfo, const CActorParameters& actParms,
CAssetId, CAssetId, const CDamageInfo&, const CDamageInfo&, float, float, float, float)
: CWallWalker(ECharacter::Seedling, uid, name, EFlavorType::Zero, info, xf, std::move(mData), pInfo, EMovementType::Ground, EColliderType::Zero, EBodyType::WallWalker, actParms, 0, 4)
CAssetId, CAssetId, const CDamageInfo&, const CDamageInfo&, float f1, float f2, float f3, float f4)
: CWallWalker(ECharacter::Seedling, uid, name, EFlavorType::Zero, info, xf, std::move(mData), pInfo,
EMovementType::Ground, EColliderType::Zero, EBodyType::WallWalker, actParms, f1, f2, 0, f3, 4, f4, false)
{
}

View File

@ -10,6 +10,7 @@ namespace MP1
class CSeedling : public CWallWalker
{
public:
DEFINE_PATTERNED(Seedling)
CSeedling(TUniqueId, std::string_view, const CEntityInfo&, const zeus::CTransform&,
CModelData&&, const CPatternedInfo&, const CActorParameters&,
CAssetId, CAssetId, const CDamageInfo&, const CDamageInfo&,

View File

@ -9,6 +9,10 @@ namespace urde::MP1
class CSpacePirate : public CPatterned
{
public:
DEFINE_PATTERNED(SpacePirate)
private:
class CSpacePirateData
{
float x0_;

View File

@ -9,7 +9,7 @@ namespace urde
class CThardusRockProjectile : public CPatterned
{
public:
static constexpr ECharacter CharacterType = ECharacter::ThardusRockProjectile;
DEFINE_PATTERNED(ThardusRockProjectile)
CThardusRockProjectile(TUniqueId uid, std::string_view name, const CEntityInfo& info,
const zeus::CTransform& xf, CModelData&& modelData, const CActorParameters& aParms,
const CPatternedInfo& patternedInfo, const std::vector<CModelData>& mDataVec, u32);

View File

@ -11,6 +11,7 @@ namespace MP1
class CWarWasp : public CPatterned
{
public:
DEFINE_PATTERNED(WarWasp)
CWarWasp(TUniqueId uid, std::string_view name, const CEntityInfo& info,
const zeus::CTransform& xf, CModelData&& mData, const CPatternedInfo& pInfo,
CPatterned::EFlavorType flavor, CPatterned::EColliderType, const CDamageInfo& dInfo1,

View File

@ -63,12 +63,12 @@ bool CCEKeyframeEmitter::GetValue(int frame, zeus::CColor& valOut) const
bool CCEConstant::GetValue(int frame, zeus::CColor& valOut) const
{
float a, b, c, d;
x4_a->GetValue(frame, a);
x8_b->GetValue(frame, b);
xc_c->GetValue(frame, c);
x10_d->GetValue(frame, d);
valOut = zeus::CColor(a, b, c, d);
float r, g, b, a;
x4_r->GetValue(frame, r);
x8_g->GetValue(frame, g);
xc_b->GetValue(frame, b);
x10_a->GetValue(frame, a);
valOut = zeus::CColor(r, g, b, a);
return false;
}

View File

@ -24,14 +24,14 @@ public:
class CCEConstant : public CColorElement
{
std::unique_ptr<CRealElement> x4_a;
std::unique_ptr<CRealElement> x8_b;
std::unique_ptr<CRealElement> xc_c;
std::unique_ptr<CRealElement> x10_d;
std::unique_ptr<CRealElement> x4_r;
std::unique_ptr<CRealElement> x8_g;
std::unique_ptr<CRealElement> xc_b;
std::unique_ptr<CRealElement> x10_a;
public:
CCEConstant(std::unique_ptr<CRealElement>&& a, std::unique_ptr<CRealElement>&& b,
std::unique_ptr<CRealElement>&& c, std::unique_ptr<CRealElement>&& d)
: x4_a(std::move(a)), x8_b(std::move(b)), xc_c(std::move(c)), x10_d(std::move(d)) {}
: x4_r(std::move(a)), x8_g(std::move(b)), xc_b(std::move(c)), x10_a(std::move(d)) {}
bool GetValue(int frame, zeus::CColor& colorOut) const;
};

View File

@ -625,7 +625,7 @@ bool CParticleElectric::Update(double dt)
return ret;
}
void CParticleElectric::Render(const CActorLights*)
void CParticleElectric::Render(const CActorLights* lights)
{
if (x3e8_electricManagers.size())
{
@ -640,13 +640,13 @@ void CParticleElectric::Render(const CActorLights*)
if (x450_25_haveGPSM)
{
for (int i=0 ; i<x154_SCNT ; ++i)
x400_gpsmGenerators[i]->Render();
x400_gpsmGenerators[i]->Render(lights);
}
if (x450_26_haveEPSM)
{
for (int i=0 ; i<x154_SCNT ; ++i)
x410_epsmGenerators[i]->Render();
x410_epsmGenerators[i]->Render(lights);
}
}

View File

@ -5,15 +5,16 @@
namespace urde
{
CUVEAnimTexture::CUVEAnimTexture(TToken<CTexture>&& tex, std::unique_ptr<CIntElement>&& a,
std::unique_ptr<CIntElement>&& b, std::unique_ptr<CIntElement>&& c,
std::unique_ptr<CIntElement>&& d, std::unique_ptr<CIntElement>&& e, bool f)
: x4_tex(std::move(tex)), x24_loop(f), x28_cycleFrames(std::move(e))
CUVEAnimTexture::CUVEAnimTexture(TToken<CTexture>&& tex, std::unique_ptr<CIntElement>&& tileW,
std::unique_ptr<CIntElement>&& tileH, std::unique_ptr<CIntElement>&& strideW,
std::unique_ptr<CIntElement>&& strideH, std::unique_ptr<CIntElement>&& cycleFrames,
bool loop)
: x4_tex(std::move(tex)), x24_loop(loop), x28_cycleFrames(std::move(cycleFrames))
{
a->GetValue(0, x10_tileW);
b->GetValue(0, x14_tileH);
c->GetValue(0, x18_strideW);
d->GetValue(0, x1c_strideH);
tileW->GetValue(0, x10_tileW);
tileH->GetValue(0, x14_tileH);
strideW->GetValue(0, x18_strideW);
strideH->GetValue(0, x1c_strideH);
int width = x4_tex.GetObj()->GetWidth();
int height = x4_tex.GetObj()->GetHeight();

View File

@ -55,9 +55,9 @@ struct CUVEAnimTexture : public CUVElement
std::unique_ptr<CIntElement> x28_cycleFrames;
std::vector<SUVElementSet> x2c_uvElems;
public:
CUVEAnimTexture(TToken<CTexture>&& tex, std::unique_ptr<CIntElement>&& a, std::unique_ptr<CIntElement>&& b,
std::unique_ptr<CIntElement>&& c, std::unique_ptr<CIntElement>&& d,
std::unique_ptr<CIntElement>&& e, bool f);
CUVEAnimTexture(TToken<CTexture>&& tex, std::unique_ptr<CIntElement>&& tileW, std::unique_ptr<CIntElement>&& tileH,
std::unique_ptr<CIntElement>&& strideW, std::unique_ptr<CIntElement>&& strideH,
std::unique_ptr<CIntElement>&& cycleFrames, bool loop);
TLockedToken<CTexture> GetValueTexture(int frame) const
{
return TLockedToken<CTexture>(x4_tex);

View File

@ -15,9 +15,11 @@ CBeamProjectile::CBeamProjectile(const TToken<CWeaponDescription>& wDesc, std::s
, x2f0_(1.f / x2ec_)
, x2f4_(f1)
, x300_(b1 == false ? x2ec_ : 0.f)
, x308_(f2)
, x464_24_(b1)
, x464_25_(false)
{
}
std::experimental::optional<zeus::CAABox> CBeamProjectile::GetTouchBounds() const

View File

@ -1,9 +1,17 @@
#include "CBomb.hpp"
#include "Particle/CElementGen.hpp"
#include "World/CPlayer.hpp"
#include "World/CMorphBall.hpp"
#include "GameGlobalObjects.hpp"
#include "Graphics/CBooRenderer.hpp"
#include "World/CGameLight.hpp"
#include "TCastTo.hpp"
#include "DataSpec/DNAMP1/SFX/Weapons.h"
namespace urde
{
CBomb::CBomb(const TToken<CGenDescription>& particle1, const TToken<CGenDescription>& particle2,
CBomb::CBomb(const TCachedToken<CGenDescription>& particle1, const TCachedToken<CGenDescription>& particle2,
TUniqueId uid, TAreaId aid, TUniqueId playerId, float f1,
const zeus::CTransform& xf, const CDamageInfo& dInfo)
: CWeapon(uid, aid, true, playerId, EWeaponType::Bomb, "Bomb", xf,
@ -12,8 +20,166 @@ CBomb::CBomb(const TToken<CGenDescription>& particle1, const TToken<CGenDescript
{EMaterialTypes::Projectile, EMaterialTypes::Bomb}),
{EMaterialTypes::Projectile, EMaterialTypes::Bomb}, dInfo, EProjectileAttrib::Bombs,
CModelData::CModelDataNull())
, x17c_fuseTime(f1)
, x180_particle1(new CElementGen(particle1, CElementGen::EModelOrientationType::Normal,
CElementGen::EOptionalSystemFlags::One))
, x184_particle2(new CElementGen(particle2, CElementGen::EModelOrientationType::Normal,
CElementGen::EOptionalSystemFlags::One))
, x18c_(particle2.GetObj())
, x190_24_isNotDetonated(true)
, x190_25_(false)
, x190_26_disableFuse(false)
{
x180_particle1->SetGlobalTranslation(xf.origin);
x184_particle2->SetGlobalTranslation(xf.origin);
}
void CBomb::Accept(urde::IVisitor& visitor)
{
visitor.Visit(this);
}
void CBomb::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr)
{
if (msg == EScriptObjectMessage::Registered)
{
x188_lightId = mgr.AllocateUniqueId();
CGameLight* gameLight = new CGameLight(x188_lightId, GetAreaIdAlways(), false,
std::string("Bomb_PLight") + GetName().data(), GetTransform(), GetUniqueId(),
x184_particle2->GetLight(), reinterpret_cast<size_t>(x18c_), 1, 0.f);
mgr.AddObject(gameLight);
mgr.AddWeaponId(xec_ownerId, xf0_weaponType);
CSfxManager::AddEmitter(SFXwpn_bomb_drop, GetTranslation(), {}, true, false, 0x7f, -1);
mgr.InformListeners(GetTranslation(), EListenNoiseType::Bomb);
return;
}
else if (msg == EScriptObjectMessage::Deleted)
{
if (x188_lightId != kInvalidUniqueId)
mgr.FreeScriptObject(x188_lightId);
if (x190_24_isNotDetonated)
mgr.RemoveWeaponId(xec_ownerId, xf0_weaponType);
return;
}
CActor::AcceptScriptMsg(msg, uid, mgr);
}
static CMaterialFilter kSolidFilter = CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Solid},
{EMaterialTypes::Character, EMaterialTypes::Player,
EMaterialTypes::ProjectilePassthrough});
void CBomb::Think(float dt, urde::CStateManager& mgr)
{
CWeapon::Think(dt, mgr);
if (x190_24_isNotDetonated)
{
if (x17c_fuseTime <= 0.f)
{
Explode(GetTranslation(), mgr);
if (TCastToPtr<CGameLight> light = mgr.ObjectById(x188_lightId))
light->SetActive(true);
}
if (x17c_fuseTime > 0.5f)
x180_particle1->Update(dt);
else
UpdateLight(dt, mgr);
if (!x190_26_disableFuse)
x17c_fuseTime -= dt;
}
else
{
UpdateLight(dt, mgr);
if (x184_particle2->IsSystemDeletable())
mgr.FreeScriptObject(GetUniqueId());
}
if (x190_24_isNotDetonated)
{
if (x164_.magSquared() > 0.f)
x158_ += dt * x164_;
if (x158_.magSquared() > 0.f)
{
x170_prevLocation = GetTranslation();
CActor::SetTranslation((dt * x158_) + GetTranslation());
zeus::CVector3f diffVec = (GetTranslation() - x170_prevLocation);
float diffMag = diffVec.magnitude();
if (diffMag == 0.f)
Explode(GetTranslation(), mgr);
else
{
CRayCastResult res = mgr.RayStaticIntersection(x170_prevLocation, (1.f / diffMag) * diffVec, diffMag,
kSolidFilter);
if (res.IsValid())
Explode(GetTranslation(), mgr);
}
}
}
x180_particle1->SetGlobalTranslation(GetTranslation());
x184_particle2->SetGlobalTranslation(GetTranslation());
}
void CBomb::AddToRenderer(const zeus::CFrustum& frustum, const urde::CStateManager& mgr) const
{
zeus::CVector3f origin = GetTranslation();
float ballRadius = mgr.GetPlayer().GetMorphBall()->GetBallRadius();
zeus::CAABox aabox(origin - (0.9f * ballRadius), origin + (0.9f * ballRadius));
zeus::CVector3f closestPoint = aabox.closestPointAlongVector(CGraphics::g_ViewMatrix.frontVector());
if (x190_24_isNotDetonated&& x17c_fuseTime > 0.5f)
g_Renderer->AddParticleGen(*x180_particle1, closestPoint, aabox);
else
g_Renderer->AddParticleGen(*x184_particle2, closestPoint, aabox);
}
void CBomb::Touch(CActor&, urde::CStateManager&)
{
#if 0
x190_24_isNotDetonated; /* wat? */
#endif
}
std::experimental::optional<zeus::CAABox> CBomb::GetTouchBounds() const
{
float radius = (x190_24_isNotDetonated ? 0.2f : x12c_curDamageInfo.GetRadius());
float minX = (x170_prevLocation.x >= GetTranslation().x ? x170_prevLocation.x : GetTranslation().x) - radius;
float minY = (x170_prevLocation.y >= GetTranslation().y ? x170_prevLocation.y : GetTranslation().y) - radius;
float minZ = (x170_prevLocation.z >= GetTranslation().z ? x170_prevLocation.z : GetTranslation().z) - radius;
float maxX = (x170_prevLocation.x >= GetTranslation().x ? x170_prevLocation.x : GetTranslation().x) + radius;
float maxY = (x170_prevLocation.y >= GetTranslation().y ? x170_prevLocation.y : GetTranslation().y) + radius;
float maxZ = (x170_prevLocation.z >= GetTranslation().z ? x170_prevLocation.z : GetTranslation().z) + radius;
return {{minX, minY, minZ, maxX, maxY, maxZ}};
}
void CBomb::Explode(const zeus::CVector3f& pos, CStateManager& mgr)
{
mgr.ApplyDamageToWorld(xec_ownerId, *this, pos, x12c_curDamageInfo, xf8_filter);
CSfxManager::AddEmitter(SFXwpn_bomb_explo, GetTranslation(), {}, true, false, 0x7f, -1);
mgr.InformListeners(pos, EListenNoiseType::Bomb);
mgr.RemoveWeaponId(xec_ownerId, xf0_weaponType);
x190_24_isNotDetonated = false;
}
void CBomb::UpdateLight(float dt, CStateManager& mgr)
{
x184_particle2->Update(dt);
if (x188_lightId == kInvalidUniqueId)
return;
if (TCastToPtr<CGameLight> light = mgr.ObjectById(x188_lightId))
if (light->GetActive())
light->SetLight(x184_particle2->GetLight());
}
}

View File

@ -7,12 +7,35 @@
namespace urde
{
class CElementGen;
class CBomb : public CWeapon
{
zeus::CVector3f x158_;
zeus::CVector3f x164_;
zeus::CVector3f x170_prevLocation;
float x17c_fuseTime;
std::unique_ptr<CElementGen> x180_particle1;
std::unique_ptr<CElementGen> x184_particle2;
TUniqueId x188_lightId = kInvalidUniqueId;
const CGenDescription* x18c_;
bool x190_24_isNotDetonated : 1;
bool x190_25_ : 1;
bool x190_26_disableFuse : 1;
public:
CBomb(const TToken<CGenDescription>& particle1, const TToken<CGenDescription>& particle2,
CBomb(const TCachedToken<CGenDescription>& particle1, const TCachedToken<CGenDescription>& particle2,
TUniqueId uid, TAreaId aid, TUniqueId playerId, float f1,
const zeus::CTransform& xf, const CDamageInfo& dInfo);
void Accept(IVisitor&);
void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&);
void Think(float, CStateManager&);
void AddToRenderer(const zeus::CFrustum&, const CStateManager&) const;
void Render(const CStateManager&) const {}
void Touch(CActor&, CStateManager&);
void Explode(const zeus::CVector3f&, CStateManager&);
void UpdateLight(float, CStateManager&);
std::experimental::optional<zeus::CAABox> GetTouchBounds() const;
};
}

View File

@ -1720,7 +1720,7 @@ void CPlayerGun::UpdateWeaponFire(float dt, const CPlayerState& playerState, CSt
x835_29_powerBombReady = false;
if (!x835_31_actorAttached)
{
x835_28_bombReady = false;
x835_28_bombReady = true;
if (x53a_powerBomb != kInvalidUniqueId &&
!mgr.CanCreateProjectile(x538_playerId, EWeaponType::PowerBomb, 1))
{
@ -2596,11 +2596,12 @@ void CPlayerGun::DropBomb(EBWeapon weapon, CStateManager& mgr)
if (x308_bombCount <= 0)
return;
zeus::CVector3f plPos = mgr.GetPlayer().GetTranslation();
zeus::CTransform xf = zeus::CTransform::Translate({plPos.x,
plPos.y, plPos.z + g_tweakPlayer->GetPlayerBallHalfExtent()});
CBomb* bomb =
new CBomb(x784_bombEffects[u32(weapon)][0], x784_bombEffects[u32(weapon)][1], mgr.AllocateUniqueId(),
mgr.GetPlayer().GetAreaId(), x538_playerId, x354_bombFuseTime,
zeus::CTransform::Translate(zeus::CVector3f{0.f, g_tweakPlayer->GetPlayerBallHalfExtent(), 0.f}),
g_tweakPlayerGun->GetBombInfo());
mgr.GetPlayer().GetAreaId(), x538_playerId, x354_bombFuseTime, xf,g_tweakPlayerGun->GetBombInfo());
mgr.AddObject(bomb);
if (x308_bombCount == 3)
@ -2623,11 +2624,11 @@ TUniqueId CPlayerGun::DropPowerBomb(CStateManager& mgr)
: CDamageInfo(CWeaponMode::PowerBomb(), 0.f, 0.f, 0.f));
TUniqueId uid = mgr.AllocateUniqueId();
CPowerBomb* pBomb =
new CPowerBomb(x784_bombEffects[1][0], uid, kInvalidAreaId, x538_playerId,
zeus::CTransform::Translate(mgr.GetPlayer().GetTranslation() +
zeus::CVector3f{0.f, g_tweakPlayer->GetPlayerBallHalfExtent(), 0.f}),
dInfo);
zeus::CVector3f plVec = mgr.GetPlayer().GetTranslation();
zeus::CTransform xf = zeus::CTransform::Translate({plVec.x,
plVec.y,
plVec.z + g_tweakPlayer->GetPlayerBallHalfExtent()});
CPowerBomb* pBomb = new CPowerBomb(x784_bombEffects[1][0], uid, kInvalidAreaId, x538_playerId, xf, dInfo);
mgr.AddObject(*pBomb);
return uid;
}

View File

@ -1,8 +1,19 @@
#include "CPowerBomb.hpp"
#include "Runtime/Particle/CElementGen.hpp"
#include "World/CDamageInfo.hpp"
#include "CStateManager.hpp"
#include "GameGlobalObjects.hpp"
#include "Graphics/CBooRenderer.hpp"
#include "CPlayerState.hpp"
#include "World/CPlayer.hpp"
#include "DataSpec/DNAMP1/SFX/Weapons.h"
#include "TCastTo.hpp"
namespace urde
{
const zeus::CColor CPowerBomb::kFadeColor(COLOR(0xffffff7));
CPowerBomb::CPowerBomb(const TToken<CGenDescription>& particle, TUniqueId uid, TAreaId aid,
TUniqueId playerId, const zeus::CTransform& xf, const CDamageInfo& dInfo)
: CWeapon(uid, aid, true, playerId, EWeaponType::PowerBomb, "PowerBomb", xf,
@ -11,8 +22,97 @@ CPowerBomb::CPowerBomb(const TToken<CGenDescription>& particle, TUniqueId uid, T
{EMaterialTypes::Projectile, EMaterialTypes::PowerBomb}),
{EMaterialTypes::Projectile, EMaterialTypes::PowerBomb}, dInfo, EProjectileAttrib::PowerBombs,
CModelData::CModelDataNull())
, x158_24_canStartFilter(true)
, x158_25_filterEnabled(false)
, x164_radiusIncrement(dInfo.GetRadius() / 2.5f)
, x168_particle(new CElementGen(particle))
, x16c_radius(dInfo.GetRadius())
{
x168_particle->SetGlobalTranslation(GetTranslation());
}
void CPowerBomb::Accept(IVisitor& visitor)
{
visitor.Visit(this);
}
void CPowerBomb::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr)
{
if (msg == EScriptObjectMessage::Registered)
{
mgr.AddWeaponId(xec_ownerId, xf0_weaponType);
if (mgr.GetPlayerState()->IsPlayerAlive())
{
CSfxManager::AddEmitter(SFXsfx0710, GetTranslation(), {}, true, false, 0x7f, -1);
mgr.InformListeners(GetTranslation(), EListenNoiseType::Bomb);
}
else
{
auto handle = CSfxManager::AddEmitter(SFXsfx073F, GetTranslation(), {}, true, false, 0x7f, -1);
mgr.Player()->ApplySubmergedPitchBend(handle);
}
}
else if (msg == EScriptObjectMessage::Deleted)
{
if (x15c_curTime > 0.7f)
mgr.GetCameraFilterPass(6).DisableFilter(0.f);
mgr.RemoveWeaponId(xec_ownerId, xf0_weaponType);
}
CActor::AcceptScriptMsg(msg, uid, mgr);
}
void CPowerBomb::Think(float dt, CStateManager& mgr)
{
CWeapon::Think(dt, mgr);
if (x158_24_canStartFilter)
{
if (x15c_curTime > 1.f && !x158_25_filterEnabled)
{
mgr.GetCameraFilterPass(6).SetFilter(EFilterType::Add, EFilterShape::Fullscreen, 1.5f, kFadeColor, -1);
x158_25_filterEnabled = true;
}
if (x15c_curTime > 2.5f)
x158_24_canStartFilter = false;
}
else if (x15c_curTime > 3.75 && x158_25_filterEnabled)
{
mgr.GetCameraFilterPass(6).DisableFilter(.5f);
x158_25_filterEnabled = false;
}
if (x15c_curTime > 7.f)
{
if (x168_particle->IsSystemDeletable())
mgr.FreeScriptObject(GetUniqueId());
}
if (x15c_curTime > 30.f)
{
mgr.FreeScriptObject(GetUniqueId());
return;
}
if (x15c_curTime > 1.f && x15c_curTime < 4.f)
{
x110_origDamageInfo.SetRadius(x160_curRadius);
ApplyDynamicDamage(GetTranslation(), mgr);
x160_curRadius += x164_radiusIncrement;
}
x168_particle->Update(dt);
x15c_curTime += dt;
}
void CPowerBomb::AddToRenderer(const zeus::CFrustum&, const CStateManager&) const
{
g_Renderer->AddParticleGen(*x168_particle);
}
void CPowerBomb::ApplyDynamicDamage(const zeus::CVector3f& pos, urde::CStateManager& mgr)
{
mgr.ApplyDamageToWorld(xec_ownerId, *this, pos, x12c_curDamageInfo, xf8_filter);
}
}

View File

@ -7,14 +7,30 @@
namespace urde
{
class CElementGen;
class CPowerBomb : public CWeapon
{
static const zeus::CColor kFadeColor;
bool x158_24_canStartFilter : 1;
bool x158_25_filterEnabled : 1;
float x15c_curTime = 0.f;
float x160_ = 0.f;
float x160_curRadius = 0.f;
float x164_radiusIncrement;
std::unique_ptr<CElementGen> x168_particle;
float x16c_radius;
public:
CPowerBomb(const TToken<CGenDescription>& particle, TUniqueId uid, TAreaId aid,
TUniqueId playerId, const zeus::CTransform& xf, const CDamageInfo& dInfo);
void Accept(IVisitor& visitor);
void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&);
void Think(float, CStateManager&);
void AddToRenderer(const zeus::CFrustum&, const CStateManager&) const;
void Render(const CStateManager&) const {}
std::experimental::optional<zeus::CAABox> GetTouchBounds() const { return {}; }
void Touch(CActor&, CStateManager&) { /*x158_24_canStartFilter; */}
float GetCurTime() const { return x15c_curTime; }
void ApplyDynamicDamage(const zeus::CVector3f&, CStateManager&);
};
}

View File

@ -288,9 +288,18 @@ std::list<CActorModelParticles::CItem>::iterator CActorModelParticles::FindOrCre
return x0_items.emplace(x0_items.end(), act, *this);
}
void CActorModelParticles::StartIce(CActor& actor, CStateManager& mgr)
void CActorModelParticles::StartIce(CActor& actor)
{
}
void CActorModelParticles::StopElectric(CActor& act)
{
if (!act.GetPointGeneratorParticles())
{
auto iter = FindSystem(act.GetUniqueId());
if (iter != x0_items.cend() && iter->xc0_particleElectric)
iter->xc0_particleElectric->SetParticleEmission(false);
}
}
void CActorModelParticles::AddRainSplashGenerator(CActor& act, CStateManager& mgr, u32 maxSplashes,

View File

@ -95,11 +95,30 @@ public:
void SetupHook(TUniqueId uid);
std::list<CItem>::const_iterator FindSystem(TUniqueId uid) const;
std::list<CItem>::iterator FindOrCreateSystem(CActor& act);
void StartIce(CActor& actor, CStateManager& mgr);
void StartIce(CActor& actor);
void AddRainSplashGenerator(CActor& act, CStateManager& mgr, u32 maxSplashes,
u32 genRate, float minZ);
void RemoveRainSplashGenerator(CActor& act);
void Render(const CActor& actor) const;
void StartElectric(CActor& act)
{
auto iter = FindOrCreateSystem(act);
if (iter->xc0_particleElectric && !iter->xc0_particleElectric->GetParticleEmission())
iter->xc0_particleElectric->SetParticleEmission(true);
}
void StopElectric(CActor& act);
void LightDudeOnFire(CActor& act)
{
auto iter = FindOrCreateSystem(act);
/* iter->sub801e5a04(false); */
if (iter->x6c_ > 0.f)
iter->x70_ = true;
}
};
}

View File

@ -9,6 +9,7 @@ namespace urde
enum class EStateMsg
{
One = 1,
Two = 2,
Twenty = 20
};

View File

@ -1,5 +1,6 @@
#include <Runtime/CStateManager.hpp>
#include <Runtime/MP1/World/CSpacePirate.hpp>
#include "CPatterned.hpp"
#include "Runtime/CStateManager.hpp"
#include "CPatternedInfo.hpp"
#include "TCastTo.hpp"
#include "CActorParameters.hpp"
@ -9,6 +10,9 @@
#include "CPlayer.hpp"
#include "Weapon/CGameProjectile.hpp"
#include "Character/CAnimData.hpp"
#include "TCastTo.hpp"
#include "MP1/World/CSpacePirate.hpp"
#include "World/CStateMachine.hpp"
namespace urde
{
@ -54,7 +58,7 @@ x3fc_flavor(flavor)
x402_30_ = x402_31_ = actorParms.HasThermalHeat();
x403_25_ = true;
x403_26_ = true;
x404_ = pInfo.x34_damageInfo;
x404_contactDamage = pInfo.x34_contactDamageInfo;
x424_damageWaitTime = pInfo.x50_damageWaitTime;
x454_deathSfx = pInfo.xe8_deathSfx;
x458_iceShatterSfx = pInfo.x134_iceShatterSfx;
@ -76,15 +80,116 @@ x3fc_flavor(flavor)
if (pInfo.x130_particle2.IsValid())
x54c_ = { g_SimplePool->GetObj({FOURCC('PART'), pInfo.x130_particle2})};
if (x404_.GetRadius() > 0.f)
x404_.SetRadius(0.f);
if (x404_contactDamage.GetRadius() > 0.f)
x404_contactDamage.SetRadius(0.f);
xe6_29_renderParticleDBInside = false;
x402_27_ = x64_modelData->HasModel(CModelData::EWhichModel::XRay);
BuildBodyController(bodyType);
}
void CPatterned::Think(float dt, urde::CStateManager& mgr)
void CPatterned::Accept(urde::IVisitor& visitor)
{
visitor.Visit(this);
}
void CPatterned::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr)
{
CAi::AcceptScriptMsg(msg, uid, mgr);
switch(msg)
{
case EScriptObjectMessage::Registered:
{
if (x508_colliderType == EColliderType::Zero)
{
CMaterialList include = GetMaterialFilter().GetIncludeList();
CMaterialList exclude = GetMaterialFilter().GetExcludeList();
include.Remove(EMaterialTypes::Character);
exclude.Add(EMaterialTypes::Character);
SetMaterialFilter(CMaterialFilter::MakeIncludeExclude(include, exclude));
}
if (HasModelData() && GetModelData()->HasAnimData() && GetModelData()->GetAnimationData()->GetIceModel())
{
/* TODO Initialize CVertexMorphEffect located at 0x8007CC7C */
}
xf8_25_angularEnabled = true;
break;
}
case EScriptObjectMessage::OnFloor:
{
if (!x328_25_)
{
x150_momentum = {};
AddMaterial(EMaterialTypes::GroundCollider, mgr);
}
x328_27_onGround = true;
break;
}
case EScriptObjectMessage::Falling:
{
if (!x328_25_)
{
if (x450_bodyController->GetPercentageFrozen() == 0.f)
{
x150_momentum = {0.f, 0.f, -GetWeight()};
RemoveMaterial(EMaterialTypes::GroundCollider, mgr);
}
}
x328_27_onGround = false;
break;
}
case EScriptObjectMessage::Activate:
x3a0_ = GetTranslation();
break;
case EScriptObjectMessage::Deleted:
if (x330_stateMachineState.GetActorState() != nullptr)
x330_stateMachineState.GetActorState()->CallFunc(mgr, *this, EStateMsg::Two, 0.f);
break;
case EScriptObjectMessage::Damage:
{
if (TCastToConstPtr<CGameProjectile> proj = mgr.GetObjectById(uid))
{
const CDamageInfo& info = proj->GetDamageInfo();
if (info.GetWeaponMode().GetType() == EWeaponType::Wave)
{
if (x460_.x81_26_ && info.GetWeaponMode().IsComboed() && HealthInfo(mgr))
{
x401_31_ = true;
KnockBack(GetTransform().frontVector(), mgr, info, EKnockBackType::One, false,
info.GetKnockBackPower());
// x460_.sub80233D30(2);
}
}
else if (info.GetWeaponMode().GetType() == EWeaponType::Plasma)
{
if (x460_.x81_27_ && info.GetWeaponMode().IsCharged() && HealthInfo(mgr))
{
KnockBack(GetTransform().frontVector(), mgr, info, EKnockBackType::One, false, info.GetKnockBackPower());
// x460_.sub80233D30(2);
}
}
if (mgr.GetPlayer().GetUniqueId() == proj->GetOwnerId())
x400_24_ = true;
}
break;
}
case EScriptObjectMessage::InvulnDamage:
{
if (TCastToConstPtr<CGameProjectile> proj = mgr.GetObjectById(uid))
{
if (proj->GetOwnerId() == mgr.GetPlayer().GetUniqueId())
x400_24_ = true;
}
break;
}
default: break;
}
}
void CPatterned::Think(float dt, CStateManager& mgr)
{
if (!GetActive())
return;
@ -103,6 +208,146 @@ void CPatterned::Think(float dt, urde::CStateManager& mgr)
if (froz > 0.8f)
x400_29_ = true;
}
if (x400_25_ && !x400_28_ && x400_29_)
{
if (x3e0_ > 0.f && x400_29_)
{
SendScriptMsgs(EScriptObjectState::UNKS4, mgr, EScriptObjectMessage::None);
sub8007ab34(mgr);
}
else
{
SendScriptMsgs(EScriptObjectState::UNKS4, mgr, EScriptObjectMessage::None);
sub8007ace8(mgr);
}
}
else if (!x400_29_)
{
x3e0_ -= dt;
if (x403_26_)
{
if (x330_stateMachineState.sub8007FB9C())
{
u32 unk = x330_stateMachineState.sub8007FB9C();
bool isDead = false; //sub8007A454(unk, "Dead"sv);
if (!isDead && x330_stateMachineState.x8_time > 15.f)
sub8007ace8(mgr);
}
}
}
sub8007a68c(dt, mgr);
x3e4_ = HealthInfo(mgr)->GetHP();
if (!x330_stateMachineState.x4_state)
x330_stateMachineState.SetState(mgr, *this, GetStateMachine(), "Start"sv);
zeus::CVector3f diffVec = x4e4_ - GetTranslation();
if (!x328_25_)
diffVec.z = 0.f;
if (diffVec.magSquared() > (0.1f * dt))
x4f0_ += dt;
else
x4f0_ = 0.f;
if (x460_.x81_26_ && x401_31_ && x402_24_)
Shock(0.5f + mgr.GetActiveRandom()->Range(0.f, 0.5f), 0.2f);
x402_24_ = x401_24_;
x401_31_ = false;
if (x450_bodyController->IsElectrocuting())
{
mgr.GetActorModelParticles()->StartElectric(*this);
if (x3f0_ > 0.f && x400_25_)
{
CDamageInfo dInfo({EWeaponType::Wave}, x3f0_, 0.f, 0.f);
mgr.ApplyDamage(kInvalidUniqueId, GetUniqueId(), kInvalidUniqueId, dInfo,
CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Solid}, {}), {});
}
}
else
{
if (x3f0_!= 0.f)
{
//x450_bodyController->sub80139f0c(x3f0_);
mgr.GetActorModelParticles()->StopElectric(*this);
}
}
if (x450_bodyController->IsOnFire())
{
if (x400_25_)
{
mgr.GetActorModelParticles()->LightDudeOnFire(*this);
CDamageInfo dInfo({EWeaponType::Wave}, x3f0_, 0.f, 0.f);
mgr.ApplyDamage(kInvalidUniqueId, GetUniqueId(), kInvalidUniqueId, dInfo,
CMaterialFilter::MakeIncludeExclude({EMaterialTypes::Solid}, {}), {});
}
}
else if (x3ec_ > 0.f)
x3ec_ = 0.f;
//if (x450_bodyController->IsFrozen())
//mgr.GetActorModelParticles()->sub801e5044(*this);
if (!x401_27_ || x401_28_)
x3e8_ = -0.33333334f;
if (x401_30_)
{
x401_30_ = false;
Death(mgr, GetTransform().frontVector(), EStateMsg::Twenty);
}
float thinkDt = (x400_25_ ? dt : dt * sub80078a88());
x450_bodyController->Update(thinkDt, mgr);
x450_bodyController->MultiplyPlaybackRate(x3b4_speed);
SAdvancementDeltas deltas = UpdateAnimation(thinkDt, mgr, !x450_bodyController->IsFrozen());
x434_posDelta = deltas.x0_posDelta;
x440_rotDelta = deltas.xc_rotDelta;
if (x403_25_ && x450_bodyController->GetPercentageFrozen() < 1.f)
x330_stateMachineState.Update(mgr, *this, thinkDt);
ThinkAboutMove(thinkDt);
//x460_.sub80233b58(thinkDt, mgr, *this);
x4e4_ = GetTranslation() + PredictMotion(thinkDt).x0_translation;
x328_26_ = false;
if (x420_curDamageTime > 0.f)
x420_curDamageTime -= dt;
if (x401_28_ && x3f4_ > dt)
x3f4_ -= dt;
xd0_thermalMag = x50c_thermalMag;
sub8007a5b8(dt);
if (!x450_bodyController->IsFrozen())
{
if (x3a0_ == zeus::CVector3f())
x3a0_ = GetTranslation();
if (x3cc_playerLeashRadius != 0.f)
{
zeus::CVector3f diffVec = (GetTranslation() - mgr.GetPlayer().GetTranslation());
if (diffVec.magSquared() > x3cc_playerLeashRadius)
x3d4_curPlayerLeashTime += dt;
else
x3d4_curPlayerLeashTime = 0.f;
}
}
else
RemoveEmitter();
if (x2f8_ > 0.f)
x2f8_ -= dt;
}
void CPatterned::Touch(CActor& act, CStateManager& mgr)
@ -117,6 +362,17 @@ void CPatterned::Touch(CActor& act, CStateManager& mgr)
}
}
std::experimental::optional<zeus::CAABox> CPatterned::GetTouchBounds() const
{
return GetBoundingBox();
}
bool CPatterned::CanRenderUnsorted(const urde::CStateManager& mgr) const
{
return x64_modelData->GetAnimationData()->GetParticleDB().AreAnySystemsDrawnWithModel() ? false :
CActor::CanRenderUnsorted(mgr);
}
zeus::CVector3f CPatterned::GetAimPosition(const urde::CStateManager& mgr, float dt) const
{
zeus::CVector3f offset;
@ -172,4 +428,109 @@ void CPatterned::SetupPlayerCollision(bool v)
}
float CPatterned::sub80078a88()
{
float f0 = (x401_28_ ? x3f4_ / 1.f : 1.f);
return zeus::max(0.1f, f0);
}
void CPatterned::PreRender(CStateManager& mgr, const zeus::CFrustum& frustum)
{
#if 1
if (mgr.GetPlayerState()->GetActiveVisor(mgr ) == CPlayerState::EPlayerVisor::Thermal)
{
SetCalculateLighting(false);
x90_actorLights->BuildConstantAmbientLighting(zeus::CColor::skWhite);
}
else
SetCalculateLighting(true);
zeus::CColor col = x42c_;
u8 alpha = GetModelAlphau8(mgr);
if (x402_27_ && mgr.GetPlayerState()->GetActiveVisor(mgr) == CPlayerState::EPlayerVisor::XRay)
alpha = 0x4C;
if (alpha < 0xFF)
{
if (col.r == 0.f && col.g == 0.f && col.b == 0.f)
col = zeus::CColor::skWhite;
}
if (x401_29_ && alpha > 0x7F)
{
}
#endif
CActor::PreRender(mgr, frustum);
}
void CPatterned::ThinkAboutMove(float dt)
{
bool doMove = true;
if (!x328_25_ && ! x328_27_onGround)
{
x310_.zeroOut();
doMove = false;
}
if (doMove && x39c_ < x390_)
{
zeus::CVector3f frontVec = GetTransform().frontVector();
zeus::CVector3f x31cCpy = x31c_;
if (x31c_.magSquared() > 0.1f)
x31cCpy.normalize();
float mag = frontVec.dot(x31cCpy);
switch (x3f8_)
{
case 0:
if (!x328_26_)
break;
case 1:
{
doMove = false;
if (mag > 0.85)
{
doMove = true;
x3f8_ = 2;
break;
}
x3f8_ = 1;
}
case 2:
x3f8_ = 3;
case 3:
{
doMove = true;
if (!x328_26_)
{
x3f8_ = 0;
break;
}
if (mag > 0.89)
x3f8_ = 4;
break;
}
case 4:
{
x328_24_ = true;
doMove = false;
x3f8_ = 0;
}
default:
break;
}
}
if (!x401_26_ && doMove)
{
const CBodyState* state = x450_bodyController->GetBodyStateInfo().GetCurrentState();
if (state->ApplyAnimationDeltas() && !zeus::close_enough(x2e0_destPos - GetTranslation(), {}))
MoveToOR((x64_modelData->GetScale() * x434_posDelta) * x55c_, dt);
}
RotateToOR(x440_rotDelta, dt);
}
}

View File

@ -10,10 +10,14 @@
#include "TCastTo.hpp"
#include "CDamageInfo.hpp"
#ifndef DEFINE_PATTERNED
#define DEFINE_PATTERNED(type) static constexpr ECharacter CharacterType = ECharacter::type;
#endif
namespace urde
{
class CPatternedInfo;
class CProjectileInfo;
class CPatternedUnknown2
{
friend class CPatterned;
@ -103,7 +107,7 @@ public:
protected:
u32 x2d8_ = -1;
TUniqueId x2dc_ = kInvalidUniqueId;
zeus::CVector3f x2e0_;
zeus::CVector3f x2e0_destPos;
zeus::CVector3f x2ec_;
float x2f8_ = 0.f;
float x2fc_minAttackRange;
@ -112,6 +116,7 @@ protected:
float x308_attackTimeVariation;
u32 x30c_ = 0;
zeus::CVector3f x310_;
zeus::CVector3f x31c_;
union
{
struct
@ -152,7 +157,7 @@ protected:
float x3c8_leashRadius;
float x3cc_playerLeashRadius;
float x3d0_playerLeashTime;
float x3d4_ = 0.f;
float x3d4_curPlayerLeashTime = 0.f;
float x3d8_;
float x3dc_;
float x3e0_;
@ -199,12 +204,14 @@ protected:
u32 _dummy2 = 0;
};
CDamageInfo x404_;
float x420_ = 0.f;
CDamageInfo x404_contactDamage;
float x420_curDamageTime = 0.f;
float x424_damageWaitTime;
float x428_ = -1.f;
zeus::CColor x42c_ = zeus::CColor::skBlack;
zeus::CColor x430_ = skDamageColor;
zeus::CVector3f x434_posDelta;
zeus::CQuaternion x440_rotDelta;
CSteeringBehaviors x45c_;
std::unique_ptr<CBodyController> x450_bodyController;
u32 x454_deathSfx;
@ -226,20 +233,22 @@ protected:
std::experimental::optional<TLockedToken<CElectricDescription>> x530_;
zeus::CVector3f x540_;
std::experimental::optional<TLockedToken<CGenDescription>> x54c_;
/* x55c_ */
/* x560_ */
/* x564_ */
zeus::CVector3f x55c_;
public:
CPatterned(ECharacter character, TUniqueId uid, std::string_view name, EFlavorType flavor, const CEntityInfo& info,
const zeus::CTransform& xf, CModelData&& mData, const CPatternedInfo& pinfo,
CPatterned::EMovementType movement, EColliderType collider, EBodyType body,
const CActorParameters& params, int variant);
void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&) {}
void Accept(IVisitor&);
void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&);
void PreThink(float, CStateManager& mgr) { CEntity::Think(x500_, mgr); }
void Think(float, CStateManager&);
void PreRender(CStateManager&, const zeus::CFrustum&);
void Touch(CActor&, CStateManager&);
virtual void Death(CStateManager&, const zeus::CVector3f&, EStateMsg) {}
virtual void KnockBack(const zeus::CVector3f&, CStateManager&, const CDamageInfo& info, EKnockBackType, bool, float) {}
std::experimental::optional<zeus::CAABox> GetTouchBounds() const;
bool CanRenderUnsorted(const CStateManager& mgr) const;
zeus::CVector3f GetOrbitPosition(const CStateManager& mgr) const
{
return GetAimPosition(mgr, 0.f);
@ -247,6 +256,47 @@ public:
zeus::CVector3f GetAimPosition(const CStateManager& mgr, float) const;
void Death(CStateManager&, const zeus::CVector3f&, EStateMsg) {}
void KnockBack(const zeus::CVector3f&, CStateManager&, const CDamageInfo& info, EKnockBackType, bool, float) {}
void TakeDamage(const zeus::CVector3f&, float) { x428_ = 0.33f;}
bool FixedRandom(CStateManager&, float) { return x330_stateMachineState.GetRandom() < x330_stateMachineState.x14_; }
bool Random(CStateManager&, float dt) { return x330_stateMachineState.GetRandom() < dt; }
//bool FixedDelay(CStateManager&, float dt) { return x330_stateMachineState.GetDelay() == dt; }
bool Default() { return true; }
virtual bool KnockbackWhenFrozen() const { return true;}
virtual void sub8007ace8(CStateManager&) {}
virtual void sub8007ab34(CStateManager&) {}
virtual void Burn(float, float) {}
virtual void Shock(float, float) {}
virtual void ThinkAboutMove(float);
virtual void GetSearchPath() {}
virtual CDamageInfo GetContactDamage() const { return x404_contactDamage; }
virtual u8 GetModelAlphau8(const CStateManager&) const { return u8(x42c_.a * 255);}
virtual bool IsOnGround() const { return x328_27_onGround; }
virtual float GetGravityConstant() const { return 24.525002f; }
virtual CProjectileInfo* GetProjectileInfo() { return nullptr; }
virtual void PhazeOut(CStateManager&) {}
virtual TLockedToken<CGenDescription>& GetX520() { return x520_.value(); }
float GetDamageDuration() const { return x504_damageDur; }
zeus::CVector3f GetGunEyePos() const;
void BuildBodyController(EBodyType);
const CBodyController* GetBodyController() const { return x450_bodyController.get(); }
CBodyController* BodyController() { return x450_bodyController.get(); }
void SetupPlayerCollision(bool);
void SetDestPos(const zeus::CVector3f& pos) { x2e0_destPos = pos; }
void sub8007a68c(float, CStateManager&) {}
float sub80078a88();
void sub8007a5b8(float) {}
bool GetX328_26() const { return x328_26_; }
bool GetX402_28() const { return x402_28_; }
//region Casting Functions
template <class T>
static T* CastTo(CEntity* ent)
{
@ -279,18 +329,7 @@ public:
return nullptr;
}
bool GetX328_26() const { return x328_26_; }
bool GetX402_28() const { return x402_28_; }
virtual bool IsOnGround() const { return x328_27_onGround; }
virtual float GetGravityConstant() const { return 24.525002f; }
float GetDamageDuration() const { return x504_damageDur; }
zeus::CVector3f GetGunEyePos() const;
void BuildBodyController(EBodyType);
const CBodyController* GetBodyController() const { return x450_bodyController.get(); }
CBodyController* BodyController() { return x450_bodyController.get(); }
void SetupPlayerCollision(bool);
//endregion
};
}

View File

@ -18,7 +18,7 @@ CPatternedInfo::CPatternedInfo(CInputStream& in, u32 pcount)
, x28_leashRadius(in.readFloatBig())
, x2c_playerLeashRadius(in.readFloatBig())
, x30_playerLeashTime(in.readFloatBig())
, x34_damageInfo(in)
, x34_contactDamageInfo(in)
, x50_damageWaitTime(in.readFloatBig())
, x54_healthInfo(in)
, x5c_damageVulnerability(in)

View File

@ -27,7 +27,7 @@ class CPatternedInfo
float x28_leashRadius;
float x2c_playerLeashRadius;
float x30_playerLeashTime;
CDamageInfo x34_damageInfo;
CDamageInfo x34_contactDamageInfo;
float x50_damageWaitTime;
CHealthInfo x54_healthInfo;
CDamageVulnerability x5c_damageVulnerability;
@ -62,6 +62,9 @@ public:
CAnimationParameters& GetAnimationParameters() { return xec_animParams; }
const CAnimationParameters& GetAnimationParameters() const { return xec_animParams; }
float GetHalfExtent() const { return xc4_halfExtent; }
float GetHeight() const { return xc8_height; }
};
}

View File

@ -247,17 +247,14 @@ void CPhysicsActor::ComputeDerivedQuantities()
bool CPhysicsActor::WillMove(const CStateManager&)
{
if (!zeus::close_enough(zeus::CVector3f::skZero, x138_velocity) ||
!zeus::close_enough(zeus::CVector3f::skZero, x168_impulse) ||
!zeus::close_enough(zeus::CVector3f::skZero, x174_torque) ||
!zeus::close_enough(zeus::CVector3f::skZero, x18c_moveImpulse) ||
!zeus::close_enough(zeus::CVector3f::skZero, x144_angularVelocity) ||
!zeus::close_enough(zeus::CVector3f::skZero, x180_angularImpulse) ||
!zeus::close_enough(zeus::CVector3f::skZero, x198_moveAngularImpulse) ||
!zeus::close_enough(zeus::CVector3f::skZero, GetTotalForcesWR()))
return true;
return false;
return !zeus::close_enough(zeus::CVector3f::skZero, x138_velocity) ||
!zeus::close_enough(zeus::CVector3f::skZero, x168_impulse) ||
!zeus::close_enough(zeus::CVector3f::skZero, x174_torque) ||
!zeus::close_enough(zeus::CVector3f::skZero, x18c_moveImpulse) ||
!zeus::close_enough(zeus::CVector3f::skZero, x144_angularVelocity) ||
!zeus::close_enough(zeus::CVector3f::skZero, x180_angularImpulse) ||
!zeus::close_enough(zeus::CVector3f::skZero, x198_moveAngularImpulse) ||
!zeus::close_enough(zeus::CVector3f::skZero, GetTotalForcesWR());
}
void CPhysicsActor::SetPhysicsState(const CPhysicsState& state)

View File

@ -383,7 +383,7 @@ void CPlayer::UpdateMorphBallTransition(float dt, CStateManager& mgr)
x7cc_transitionSuit = suit;
CAnimRes useRes = x7d0_animRes;
useRes.SetCharacterNodeId(s32(x7cc_transitionSuit));
SetModelData(std::make_unique<CModelData>(x7d0_animRes));
SetModelData(std::make_unique<CModelData>(useRes));
SetIntoBallReadyAnimation(mgr);
}
return;

View File

@ -278,7 +278,7 @@ void CScriptEffect::Render(const CStateManager& mgr) const
if (xf4_electric && xf4_electric->GetParticleCount() > 0)
{
g_NumParticlesRendered += xf4_electric->GetParticleCount();
xf4_electric->Render();
xf4_electric->Render(GetActorLights());
}
}

View File

@ -13,11 +13,14 @@ CScriptSpawnPoint::CScriptSpawnPoint(TUniqueId uid, std::string_view name, const
bool defaultSpawn, bool active, bool morphed)
: CEntity(uid, info, active, name), x34_xf(xf), x64_itemCounts(itemCounts)
{
#ifndef NDEBUG
x64_itemCounts[int(CPlayerState::EItemType::ThermalVisor)] = 1;
x64_itemCounts[int(CPlayerState::EItemType::XRayVisor)] = 1;
x64_itemCounts[int(CPlayerState::EItemType::GrappleBeam)] = 1;
x64_itemCounts[int(CPlayerState::EItemType::BoostBall)] = 1;
x64_itemCounts[int(CPlayerState::EItemType::ChargeBeam)] = 1;
x64_itemCounts[int(CPlayerState::EItemType::PowerBombs)] = 1;
#endif
x10c_24_firstSpawn = defaultSpawn;
x10c_25_morphed = morphed;
}

View File

@ -1,14 +1,64 @@
#include "CScriptSteam.hpp"
#include "CStateManager.hpp"
#include "CPlayer.hpp"
#include "TCastTo.hpp"
namespace urde
{
CScriptSteam::CScriptSteam(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CVector3f& pos,
const zeus::CAABox& aabb, const CDamageInfo& dInfo, const zeus::CVector3f& orientedForce,
ETriggerFlags flags, bool active, CAssetId, float, float, float, float, bool)
ETriggerFlags flags, bool active, CAssetId texture, float f1, float f2, float f3, float f4,
bool b1)
: CScriptTrigger(uid, name, info, pos, aabb, dInfo, orientedForce, flags, active, false, false)
, x150_(b1)
, x154_texture(texture)
, x158_(f1)
, x15c_alphaInDur(f2 / f1)
, x160_alphaOutDur(f3 / f1)
{
float r3 = (aabb.max.z < aabb.max.y ? aabb.max.z : aabb.max.y);
r3 = (r3 < aabb.max.x ? r3 : aabb.max.x);
if (f4 - 0.f >= 0.000009999999747378752f)
r3 = (r3 < f2 ? r3 : f4);
x164_ = r3;
x168_ = 1.f / x164_;
}
void CScriptSteam::Accept(IVisitor& visitor)
{
visitor.Visit(this);
}
void CScriptSteam::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr)
{
if (msg == EScriptObjectMessage::Deactivate)
mgr.Player()->SetVisorSteam(0.f, x158_, x160_alphaOutDur, CAssetId(), x150_);
CScriptTrigger::AcceptScriptMsg(msg, uid, mgr);
}
void CScriptSteam::Think(float dt, CStateManager& mgr)
{
if (!GetActive())
return;
CScriptTrigger::Think(dt, mgr);
if (x148_28_playerTriggerProc && mgr.GetCameraManager()->GetFluidCounter() == 0)
{
zeus::CVector3f eyePos = mgr.GetPlayer().GetEyePosition();
zeus::CVector3f posDiff = (GetTranslation() - eyePos);
float mag = posDiff.magnitude();
float distance = (mag >= x164_ ? 0.f : std::cos((1.5707964f * mag) * x168_) * x158_);
mgr.Player()->SetVisorSteam(distance, x15c_alphaInDur, x160_alphaOutDur, x154_texture, x150_);
if (x150_)
mgr.GetEnvFxManager()->SetXB54(2.f * distance);
}
else
mgr.Player()->SetVisorSteam(0.f, x15c_alphaInDur, x160_alphaOutDur, CAssetId(), x150_);
}
}

View File

@ -8,10 +8,21 @@ namespace urde
class CScriptSteam : public CScriptTrigger
{
bool x150_;
CAssetId x154_texture;
float x158_;
float x15c_alphaInDur;
float x160_alphaOutDur;
float x164_ = 0.f;
float x168_ = 0.f;
public:
CScriptSteam(TUniqueId, std::string_view name, const CEntityInfo& info, const zeus::CVector3f& pos,
const zeus::CAABox&, const CDamageInfo& dInfo, const zeus::CVector3f& orientedForce,
ETriggerFlags flags, bool active, CAssetId, float, float, float, float, bool);
void Accept(IVisitor&);
void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&);
void Think(float, CStateManager&);
};
}

View File

@ -28,6 +28,7 @@ public:
TUniqueId FollowWaypoint(CStateManager& mgr) const;
TUniqueId NextWaypoint(CStateManager& mgr) const;
float GetSpeed() const { return xe8_speed; }
float GetF0() const { return xf0_; }
};
}

View File

@ -86,7 +86,7 @@ void CStateMachineState::Setup(const CStateMachine* machine)
x0_machine = machine;
x4_state = nullptr;
x8_time = 0.f;
xc_ = 0.f;
xc_random = 0.f;
x10_ = 0.f;
}

View File

@ -35,6 +35,7 @@ public:
class CAiState
{
friend class CStateMachineState;
CAiStateFunc x0_func;
const char* x4_name;
u32 x8_;
@ -77,11 +78,13 @@ public:
class CStateMachineState
{
friend class CPatterned;
const CStateMachine* x0_machine = nullptr;
CAiState* x4_state = nullptr;
float x8_time = 0.f;
float xc_ = 0.f;
float xc_random = 0.f;
float x10_ = 0.f;
float x14_;
union
{
struct
@ -93,7 +96,7 @@ class CStateMachineState
public:
CStateMachineState()=default;
void GetActorState() const;
CAiState* GetActorState() const { return x4_state; }
float GetTime() const;
void Update(CStateManager& mgr, CAi& ai, float delta)
@ -108,8 +111,15 @@ public:
void Setup(const CStateMachine* machine);
std::string GetName() const;
void SetDelay(float);
void GetRandom() const;
float GetRandom() const { return xc_random; }
float GetDelay() const;
u32 sub8007FB9C() const
{
if (x4_state)
return x4_state->xc_;
return 0;
}
};
CFactoryFnReturn FAiFiniteStateMachineFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& vparms,

View File

@ -1,11 +1,115 @@
#include "CWallWalker.hpp"
#include "CPatternedInfo.hpp"
#include "CStateManager.hpp"
#include "TCastTo.hpp"
#include "CScriptWaypoint.hpp"
namespace urde
{
CWallWalker::CWallWalker(ECharacter chr, TUniqueId uid, std::string_view name, EFlavorType flavType,
const CEntityInfo& eInfo, const zeus::CTransform& xf,
CModelData&& mData, const CPatternedInfo& pInfo, EMovementType mType,
EColliderType colType, EBodyType bType, const CActorParameters& aParms, s32 w1, u32 w2)
: CPatterned(chr, uid, name, flavType, eInfo, xf, std::move(mData), pInfo, mType, colType, bType, aParms, w1)
{}
EColliderType colType, EBodyType bType, const CActorParameters& aParms, float f1, float f2,
s32 w1, float f3, u32 w2, float f4, bool b1)
: CPatterned(chr, uid, name, flavType, eInfo, xf, std::move(mData), pInfo, mType, colType, bType, aParms, w1)
, x590_colSphere(zeus::CSphere(zeus::CVector3f::skZero, pInfo.GetHalfExtent()), x68_material)
, x5b0_(f1)
, x5b4_(f2)
, x5c0_(f3)
, x5c4_(f4)
, x5cc_bendingHackAnim(GetModelData()->GetAnimationData()->GetCharacterInfo().GetAnimationIndex("BendingAnimationHack"sv))
, x5d0_(w2)
, x5d6_24_(false)
, x5d6_25_(false)
, x5d6_26_(false)
, x5d6_27_(b1)
, x5d6_28_addBendingWeight(true)
, x5d6_29_applyBendingHack(false)
{
}
void CWallWalker::PreThink(float dt, CStateManager& mgr)
{
CPatterned::PreThink(dt, mgr);
if (!GetActive() || x5d6_26_ || x5bc_ > 0.f || x5d6_27_ || x450_bodyController->IsFrozen() || !x5d6_24_)
return;
zeus::CQuaternion quat(GetTransform().buildMatrix3f());
AddMotionState(PredictMotion(dt));
zeus::CQuaternion quat2(GetTransform().buildMatrix3f());
ClearForcesAndTorques();
if (x5d6_25_)
{
zeus::CPlane plane = x568_.GetPlane();
const float futureDt = (10.f * dt);
SetTranslation(GetTranslation() * (1.f - futureDt) +
(((GetTranslation() - ((plane.vec.dot(GetTranslation())) - plane.d) -
x590_colSphere.GetSphere().radius - 0.1f) * plane.vec) * futureDt));
}
else
MoveCollisionPrimitive(zeus::CVector3f::skZero);
}
void CWallWalker::Think(float dt, CStateManager& mgr)
{
if (!x450_bodyController->GetActive())
x450_bodyController->Activate(mgr);
CPatterned::Think(dt, mgr);
if (x5cc_bendingHackAnim == -1)
return;
if (x5d6_28_addBendingWeight)
{
if (x5c8_bendingHackWeight < 1.f)
{
x5c8_bendingHackWeight += (dt * x138_velocity.magnitude()) / 0.6f;
if (x5c8_bendingHackWeight >= 1.f)
x5c8_bendingHackWeight = 1.f;
}
}
else if (x5c8_bendingHackWeight > 0.f)
{
x5c8_bendingHackWeight -= (dt * x138_velocity.magnitude()) / 1.5f;
if (x5c8_bendingHackWeight < 0.f)
x5c8_bendingHackWeight = 0.f;
}
if (x5c8_bendingHackWeight <= 0.f && !x5d6_29_applyBendingHack)
return;
if (x5c8_bendingHackWeight > 0.0001f)
{
ModelData()->AnimationData()->AddAdditiveAnimation(x5cc_bendingHackAnim, x5c8_bendingHackWeight, true, false);
x5d6_29_applyBendingHack = true;
}
else
{
ModelData()->AnimationData()->DelAdditiveAnimation(x5cc_bendingHackAnim);
x5d6_29_applyBendingHack = false;
}
}
void CWallWalker::UpdateWPDestination(CStateManager& mgr)
{
if (TCastToPtr<CScriptWaypoint> wp = mgr.ObjectById(x2dc_))
{
zeus::CVector3f wpPos = wp->GetTranslation();
if ((wpPos - GetTranslation()).magSquared() < x5c0_ * x5c0_)
{
x2dc_ = wp->NextWaypoint(mgr);
if (std::fabs(wp->GetF0()) > 0.00001f)
{
x5bc_ = wp->GetF0();
if (x5d0_ == 0)
x450_bodyController->SetLocomotionType(pas::ELocomotionType::Relaxed);
mgr.SendScriptMsg(wp, GetUniqueId(), EScriptObjectMessage::Arrived);
}
}
SetDestPos(wpPos);
}
}
}

View File

@ -2,15 +2,43 @@
#define __URDE_CWALLWALKER_HPP__
#include "CPatterned.hpp"
#include "Collision/CCollisionSurface.hpp"
#include "Collision/CCollidableSphere.hpp"
namespace urde
{
class CWallWalker : public CPatterned
{
protected:
CCollisionSurface x568_ = CCollisionSurface(zeus::CVector3f(),
zeus::CVector3f::skForward,
zeus::CVector3f::skRight, -1);
CCollidableSphere x590_colSphere;
float x5b0_;
float x5b4_;
float x5b8_ = 0.f;
float x5bc_ = 0.f;
float x5c0_;
float x5c4_;
float x5c8_bendingHackWeight = 0.f;
s32 x5cc_bendingHackAnim;
u32 x5d0_;
s16 x5d4_ = 0;
bool x5d6_24_ : 1;
bool x5d6_25_ : 1;
bool x5d6_26_ : 1;
bool x5d6_27_ : 1;
bool x5d6_28_addBendingWeight : 1;
bool x5d6_29_applyBendingHack : 1;
public:
CWallWalker(ECharacter, TUniqueId, std::string_view, EFlavorType, const CEntityInfo&, const zeus::CTransform&,
CModelData&&, const CPatternedInfo&, EMovementType, EColliderType, EBodyType,
const CActorParameters&, s32, u32);
const CActorParameters&, float, float, s32, float, u32, float, bool);
void PreThink(float, CStateManager&);
void Think(float, CStateManager&);
const CCollisionPrimitive* GetCollisionPrimitive() const { return &x590_colSphere; }
void UpdateWPDestination(CStateManager&);
};
}
#endif // __URDE_CWALLWALKER_HPP__

View File

@ -457,6 +457,7 @@ void CWorldTransManager::StartTextFadeOut()
void CWorldTransManager::DisableTransition()
{
x30_type = ETransType::Disabled;
x4_modelData.reset();
x8_textData.reset();
x44_26_goingUp = false;

View File

@ -1652,10 +1652,10 @@ CEntity* ScriptLoader::LoadParasite(CStateManager& mgr, CInputStream& in, int pr
const CAnimationParameters& animParms = pInfo.GetAnimationParameters();
CModelData mData(
CAnimRes(animParms.GetACSFile(), animParms.GetCharacter(), scale, animParms.GetInitialAnimation(), true));
return new MP1::CParasite(mgr.AllocateUniqueId(), name, flavor, info, xf, std::move(mData), pInfo, 6, f1, f2, f3,
f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15, f16, f17, 0.f, b1, 0,
CDamageVulnerability::NormalVulnerabilty(), MP1::CParasiteInfo(), -1, -1, -1, -1, -1, 0.f,
aParms);
return new MP1::CParasite(mgr.AllocateUniqueId(), name, flavor, info, xf, std::move(mData), pInfo,
EBodyType::WallWalker, f1, f2, f3, f4, f5, f6, f7, f8, f9, f10, f11, f12, f13, f14, f15,
f16, f17, 0.f, b1, 0, CDamageVulnerability::NormalVulnerabilty(), CDamageInfo(),
-1, -1, -1, -1, -1, 0.f, aParms);
}
CEntity* ScriptLoader::LoadPlayerHint(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info)
@ -2584,9 +2584,11 @@ CEntity* ScriptLoader::LoadGeemer(CStateManager& mgr, CInputStream& in, int prop
CModelData mData(CAnimRes(pInfo.GetAnimationParameters().GetACSFile(), pInfo.GetAnimationParameters().GetCharacter(),
actHead.x40_scale, pInfo.GetAnimationParameters().GetInitialAnimation(), true));
return new MP1::CParasite(mgr.AllocateUniqueId(), actHead.x0_name, CPatterned::EFlavorType::Zero, info, actHead.x10_transform,
std::move(mData), pInfo, 6, 0.f, f1, f2, f3, f4, 0.2f, 0.4f, 0.f, 0.f, 0.f, 0.f, 0.f, 1.f, f7, 0.f, 0.f,
f5, f6, false, 2, CDamageVulnerability::NormalVulnerabilty(), MP1::CParasiteInfo(), sId1, sId2, sId3, -1, -1, 0.f, actParms);
return new MP1::CParasite(mgr.AllocateUniqueId(), actHead.x0_name, CPatterned::EFlavorType::Zero, info,
actHead.x10_transform, std::move(mData), pInfo, EBodyType::WallWalker, 0.f, f1, f2, f3, f4, 0.2f, 0.4f, 0.f,
0.f, 0.f, 0.f, 0.f, 1.f, f7, 0.f, 0.f, f5, f6, false, 2,
CDamageVulnerability::NormalVulnerabilty(), CDamageInfo(), sId1, sId2, sId3, -1,
-1, 0.f, actParms);
}
CEntity* ScriptLoader::LoadSpindleCamera(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info)