mirror of https://github.com/AxioDL/metaforce.git
Various CScriptSpecialFunction implementation, more debugOverlay CVars
This commit is contained in:
parent
8f9d7da3ee
commit
c0b8b89a9b
|
@ -26,6 +26,107 @@ static logvisor::Module Log("urde::SpecMP2");
|
|||
extern hecl::Database::DataSpecEntry SpecEntMP2;
|
||||
extern hecl::Database::DataSpecEntry SpecEntMP2ORIG;
|
||||
|
||||
static const std::unordered_set<uint32_t> IndividualOrigIDs =
|
||||
{
|
||||
0xB7BBD0B4,
|
||||
0x1F9DA858,
|
||||
0x2A13C23E,
|
||||
0xF13452F8,
|
||||
0xA91A7703,
|
||||
0xC042EC91,
|
||||
0x12A12131,
|
||||
0x5F556002,
|
||||
0xA9798329,
|
||||
0xB306E26F,
|
||||
0xCD7B1ACA,
|
||||
0x8ADA8184,
|
||||
0x1A29C0E6,
|
||||
0x5D9F9796,
|
||||
0x951546A8,
|
||||
0x7946C4C5,
|
||||
0x409AA72E,
|
||||
};
|
||||
|
||||
struct OriginalIDs
|
||||
{
|
||||
static void Generate(PAKRouter<DNAMP2::PAKBridge>& pakRouter, hecl::Database::Project& project)
|
||||
{
|
||||
std::unordered_set<UniqueID32> addedIDs;
|
||||
std::vector<UniqueID32> originalIDs;
|
||||
|
||||
pakRouter.enumerateResources([&](const DNAMP1::PAK::Entry* ent) {
|
||||
if (ent->type == FOURCC('MLVL') ||
|
||||
ent->type == FOURCC('SCAN') ||
|
||||
ent->type == FOURCC('MREA') ||
|
||||
IndividualOrigIDs.find(ent->id.toUint32()) != IndividualOrigIDs.end())
|
||||
{
|
||||
if (addedIDs.find(ent->id) == addedIDs.cend())
|
||||
{
|
||||
addedIDs.insert(ent->id);
|
||||
originalIDs.push_back(ent->id);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
});
|
||||
std::sort(originalIDs.begin(), originalIDs.end());
|
||||
|
||||
athena::io::YAMLDocWriter yamlW("MP2OriginalIDs");
|
||||
for (const UniqueID32& id : originalIDs)
|
||||
{
|
||||
hecl::ProjectPath path = pakRouter.getWorking(id);
|
||||
yamlW.writeString(id.toString().c_str(), path.getRelativePathUTF8());
|
||||
}
|
||||
hecl::ProjectPath path(project.getProjectWorkingPath(), "MP2/!original_ids.yaml");
|
||||
path.makeDirChain(false);
|
||||
athena::io::FileWriter fileW(path.getAbsolutePath());
|
||||
yamlW.finish(&fileW);
|
||||
}
|
||||
|
||||
static void Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath)
|
||||
{
|
||||
hecl::Database::Project& project = inPath.getProject();
|
||||
athena::io::YAMLDocReader r;
|
||||
athena::io::FileReader fr(inPath.getAbsolutePath());
|
||||
if (!fr.isOpen() || !r.parse(&fr))
|
||||
return;
|
||||
|
||||
std::vector<std::pair<UniqueID32, UniqueID32>> originalIDs;
|
||||
originalIDs.reserve(r.getRootNode()->m_mapChildren.size());
|
||||
for (const auto& node : r.getRootNode()->m_mapChildren)
|
||||
{
|
||||
char* end = const_cast<char*>(node.first.c_str());
|
||||
u32 id = strtoul(end, &end, 16);
|
||||
if (end != node.first.c_str() + 8)
|
||||
continue;
|
||||
|
||||
hecl::ProjectPath path(project.getProjectWorkingPath(), node.second->m_scalarString.c_str());
|
||||
originalIDs.push_back(std::make_pair(id, path.hash().val32()));
|
||||
}
|
||||
std::sort(originalIDs.begin(), originalIDs.end(),
|
||||
[](const std::pair<UniqueID32, UniqueID32>& a, const std::pair<UniqueID32, UniqueID32>& b) {
|
||||
return a.first < b.first;
|
||||
});
|
||||
|
||||
athena::io::FileWriter w(outPath.getAbsolutePath());
|
||||
w.writeUint32Big(originalIDs.size());
|
||||
for (const auto& idPair : originalIDs)
|
||||
{
|
||||
idPair.first.write(w);
|
||||
idPair.second.write(w);
|
||||
}
|
||||
|
||||
std::sort(originalIDs.begin(), originalIDs.end(),
|
||||
[](const std::pair<UniqueID32, UniqueID32>& a, const std::pair<UniqueID32, UniqueID32>& b) {
|
||||
return a.second < b.second;
|
||||
});
|
||||
for (const auto& idPair : originalIDs)
|
||||
{
|
||||
idPair.second.write(w);
|
||||
idPair.first.write(w);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct SpecMP2 : SpecBase
|
||||
{
|
||||
bool checkStandaloneID(const char* id) const
|
||||
|
@ -42,12 +143,21 @@ struct SpecMP2 : SpecBase
|
|||
hecl::ProjectPath m_workPath;
|
||||
hecl::ProjectPath m_cookPath;
|
||||
PAKRouter<DNAMP2::PAKBridge> m_pakRouter;
|
||||
IDRestorer<UniqueID32> m_idRestorer;
|
||||
|
||||
void setThreadProject()
|
||||
{
|
||||
SpecBase::setThreadProject();
|
||||
UniqueIDBridge::SetIDRestorer(&m_idRestorer);
|
||||
}
|
||||
|
||||
SpecMP2(const hecl::Database::DataSpecEntry* specEntry, hecl::Database::Project& project, bool pc)
|
||||
: SpecBase(specEntry, project, pc),
|
||||
m_workPath(project.getProjectWorkingPath(), _S("MP2")),
|
||||
m_cookPath(project.getProjectCookedPath(SpecEntMP2), _S("MP2")),
|
||||
m_pakRouter(*this, m_workPath, m_cookPath) {}
|
||||
m_pakRouter(*this, m_workPath, m_cookPath),
|
||||
m_idRestorer({project.getProjectWorkingPath(), "MP2/!original_ids.yaml"}, project)
|
||||
{}
|
||||
|
||||
void buildPaks(nod::Node& root,
|
||||
const std::vector<hecl::SystemString>& args,
|
||||
|
@ -281,6 +391,9 @@ struct SpecMP2 : SpecBase
|
|||
|
||||
process.waitUntilComplete();
|
||||
|
||||
/* Generate original ID mapping for MLVL and SCAN entries - marks complete project */
|
||||
OriginalIDs::Generate(m_pakRouter, m_project);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -413,6 +526,20 @@ struct SpecMP2 : SpecBase
|
|||
DNAMAPU::MAPU::Cook(mapu, out);
|
||||
progress(_S("Done"));
|
||||
}
|
||||
|
||||
UniqueID32 newToOriginal(urde::CAssetId id) const
|
||||
{
|
||||
if (UniqueID32 origId = m_idRestorer.newToOriginal({uint32_t(id.Value()), true}))
|
||||
return {origId.toUint32(), true};
|
||||
return {uint32_t(id.Value()), true};
|
||||
}
|
||||
|
||||
urde::CAssetId originalToNew(UniqueID32 id) const
|
||||
{
|
||||
if (UniqueID32 newId = m_idRestorer.originalToNew(id))
|
||||
return newId.toUint32();
|
||||
return id.toUint32();
|
||||
}
|
||||
};
|
||||
|
||||
hecl::Database::DataSpecEntry SpecEntMP2
|
||||
|
|
|
@ -160,7 +160,7 @@ CGameState::CGameState(CBitStreamReader& stream, u32 saveIdx)
|
|||
|
||||
for (u32 i = 0; i < 128; i++)
|
||||
x0_[i] = stream.ReadEncoded(8);
|
||||
//u32 tsSeconds = stream.ReadEncoded(32);
|
||||
stream.ReadEncoded(32);
|
||||
|
||||
x228_24_hardMode = stream.ReadEncoded(1);
|
||||
x228_25_initPowerupsAtFirstSpawn = stream.ReadEncoded(1);
|
||||
|
@ -173,7 +173,6 @@ CGameState::CGameState(CBitStreamReader& stream, u32 saveIdx)
|
|||
xa0_playTime = conv.doub;
|
||||
|
||||
x98_playerState = std::make_shared<CPlayerState>(stream);
|
||||
//float currentHealth = x98_playerState->GetHealthInfo().GetHP();
|
||||
|
||||
x17c_gameOptions = CGameOptions(stream);
|
||||
x1f8_hintOptions = CHintOptions(stream);
|
||||
|
|
|
@ -180,6 +180,11 @@ bool CMemoryCardSys::InitializePump()
|
|||
return false;
|
||||
}
|
||||
|
||||
std::pair<TAreaId, s32> CMemoryCardSys::GetAreaAndWorldIdForSaveId(s32 saveId) const
|
||||
{
|
||||
return {kInvalidAreaId, -1};
|
||||
}
|
||||
|
||||
void CMemoryCardSys::CCardFileInfo::LockBannerToken(CAssetId bannerTxtr, CSimplePool& sp)
|
||||
{
|
||||
x3c_bannerTex = bannerTxtr;
|
||||
|
|
|
@ -164,6 +164,7 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
std::pair<TAreaId, s32> GetAreaAndWorldIdForSaveId(s32 saveId) const;
|
||||
static kabufuda::ProbeResults CardProbe(kabufuda::ECardSlot port);
|
||||
static ECardResult MountCard(kabufuda::ECardSlot port);
|
||||
static ECardResult UnmountCard(kabufuda::ECardSlot port);
|
||||
|
|
|
@ -69,13 +69,14 @@ CPlayerState::CPlayerState()
|
|||
CPlayerState::CPlayerState(CBitStreamReader& stream)
|
||||
: x188_staticIntf(5)
|
||||
{
|
||||
x4_enabledItems = u32(stream.ReadEncoded(0x20u));
|
||||
x0_24_alive = true;
|
||||
x4_enabledItems = u32(stream.ReadEncoded(32));
|
||||
union
|
||||
{
|
||||
float fHP;
|
||||
u32 iHP;
|
||||
} hp;
|
||||
hp.iHP = u32(stream.ReadEncoded(0x20u));
|
||||
hp.iHP = u32(stream.ReadEncoded(32));
|
||||
xc_health.SetHP(hp.fHP);
|
||||
x8_currentBeam = EBeamId(stream.ReadEncoded(CBitStreamReader::GetBitCount(5)));
|
||||
x20_currentSuit = EPlayerSuit(stream.ReadEncoded(CBitStreamReader::GetBitCount(4)));
|
||||
|
|
|
@ -469,7 +469,7 @@ public:
|
|||
}
|
||||
TUniqueId GetPlayerActorHead() const { return xf6c_playerActorHead; }
|
||||
void SetPlayerActorHead(TUniqueId id) { xf6c_playerActorHead = id; }
|
||||
|
||||
std::shared_ptr<CWorldLayerState>& WorldLayerStateNC() { return x8c8_worldLayerState; }
|
||||
static float g_EscapeShakeCountdown;
|
||||
static bool g_EscapeShakeCountdownInit;
|
||||
};
|
||||
|
|
|
@ -7,6 +7,8 @@ namespace urde
|
|||
{
|
||||
enum class ERumbleFxId
|
||||
{
|
||||
Zero = 0,
|
||||
One = 1,
|
||||
CameraShake = 6,
|
||||
EscapeSequenceShake = 7,
|
||||
PlayerBump = 11,
|
||||
|
@ -14,7 +16,11 @@ enum class ERumbleFxId
|
|||
PlayerMissileFire = 13,
|
||||
PlayerGrappleFire = 14,
|
||||
PlayerLand = 15,
|
||||
PlayerGrappleSwoosh = 17
|
||||
PlayerGrappleSwoosh = 17,
|
||||
Twenty = 20,
|
||||
TwentyOne = 21,
|
||||
TwentyTwo = 22,
|
||||
TwentyThree = 23
|
||||
};
|
||||
enum class ERumblePriority
|
||||
{
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "CEnvFxManager.hpp"
|
||||
#include "Graphics/CTexture.hpp"
|
||||
#include "CActor.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
|
@ -43,4 +44,8 @@ void CEnvFxManager::Cleanup()
|
|||
xb70_ = 0;
|
||||
}
|
||||
|
||||
void CEnvFxManager::sub801e4f10(CActor*, float, const CStateManager& , u32, u32)
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ namespace urde
|
|||
{
|
||||
class CStateManager;
|
||||
class CTexture;
|
||||
class CActor;
|
||||
|
||||
enum class EEnvFxType
|
||||
{
|
||||
|
@ -85,6 +86,7 @@ public:
|
|||
bool GetX24() const { return x24_; }
|
||||
float GetRainMagnitude() const { return x30_rainMagnitude; }
|
||||
void Cleanup();
|
||||
void sub801e4f10(CActor*, float, const CStateManager&, u32, u32);
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -428,7 +428,7 @@ CGameArea::CGameArea(CInputStream& in, int idx, int mlvlVersion)
|
|||
|
||||
x84_mrea = in.readUint32Big();
|
||||
if (mlvlVersion > 15)
|
||||
x88_areaId = in.readUint32Big();
|
||||
x88_areaId = in.readInt32Big();
|
||||
else
|
||||
x88_areaId = -1;
|
||||
|
||||
|
|
|
@ -100,13 +100,13 @@ class CGameArea final : public IGameArea
|
|||
friend class CWorld;
|
||||
friend class CStateManager;
|
||||
|
||||
int x4_selfIdx;
|
||||
TAreaId x4_selfIdx;
|
||||
CAssetId x8_nameSTRG;
|
||||
zeus::CTransform xc_transform;
|
||||
zeus::CTransform x3c_invTransform;
|
||||
zeus::CAABox x6c_aabb;
|
||||
CAssetId x84_mrea;
|
||||
u32 x88_areaId;
|
||||
s32 x88_areaId;
|
||||
std::vector<u16> x8c_attachedAreaIndices;
|
||||
std::vector<SObjectTag> x9c_deps1;
|
||||
std::vector<SObjectTag> xac_deps2;
|
||||
|
@ -372,6 +372,8 @@ public:
|
|||
CGameArea* GetNext() const { return x130_next; }
|
||||
|
||||
static void WarmupShaders(const SObjectTag& mreaTag);
|
||||
|
||||
s32 GetAreaSaveId() const { return x88_areaId; }
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
#include "CScriptPlatform.hpp"
|
||||
#include "Collision/CMaterialList.hpp"
|
||||
#include "Collision/CCollidableOBBTreeGroup.hpp"
|
||||
#include "World/CScriptWaypoint.hpp"
|
||||
#include "World/CScriptColorModulate.hpp"
|
||||
#include "World/CWorld.hpp"
|
||||
#include "CStateManager.hpp"
|
||||
#include "TCastTo.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
|
||||
|
@ -18,26 +21,173 @@ static CMaterialList MakePlatformMaterialList()
|
|||
|
||||
CScriptPlatform::CScriptPlatform(TUniqueId uid, std::string_view name, const CEntityInfo& info,
|
||||
const zeus::CTransform& xf, CModelData&& mData, const CActorParameters& actParms,
|
||||
const zeus::CAABox& aabb, float f1, bool, float f2, bool active,
|
||||
const zeus::CAABox& aabb, float f1, bool b1, float f2, bool active,
|
||||
const CHealthInfo& hInfo, const CDamageVulnerability& dVuln,
|
||||
const std::experimental::optional<TLockedToken<CCollidableOBBTreeGroupContainer>>& dcln,
|
||||
bool, u32, u32)
|
||||
bool b2, u32 w1, u32 w2)
|
||||
: CPhysicsActor(uid, active, name, info, xf, std::move(mData), MakePlatformMaterialList(), aabb, SMoverData(15000.f),
|
||||
actParms, 0.3f, 0.1f)
|
||||
, x28c_(hInfo)
|
||||
, x294_(hInfo)
|
||||
, x29c_(dVuln)
|
||||
, x25c_currentMass(f1)
|
||||
, x28c_initialHealth(hInfo)
|
||||
, x294_health(hInfo)
|
||||
, x29c_damageVuln(dVuln)
|
||||
, x304_treeGroupContainer(dcln)
|
||||
{
|
||||
x348_ = f2;
|
||||
x34c_ = w1;
|
||||
x350_ = w2;
|
||||
x356_24_dead = false;;
|
||||
x356_25_ = false;
|
||||
x356_26_ = b1;
|
||||
x356_27_ = false;
|
||||
x356_28_ = b2;
|
||||
x356_29_ = false;
|
||||
x356_30_ = false;
|
||||
x356_31_ = true;
|
||||
CActor::SetMaterialFilter(CMaterialFilter::MakeIncludeExclude(
|
||||
CMaterialList(EMaterialTypes::Solid),
|
||||
CMaterialList(EMaterialTypes::NoStaticCollision, EMaterialTypes::NoPlatformCollision, EMaterialTypes::Platform)));
|
||||
if (x304_treeGroupContainer)
|
||||
x314_treeGroup = std::make_unique<CCollidableOBBTreeGroup>(x304_treeGroupContainer->GetObj(), x68_material);
|
||||
|
||||
}
|
||||
|
||||
void CScriptPlatform::Accept(IVisitor& visitor) { visitor.Visit(this); }
|
||||
|
||||
void CScriptPlatform::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr)
|
||||
{
|
||||
switch(msg)
|
||||
{
|
||||
case EScriptObjectMessage::InitializedInArea:
|
||||
BuildSlaveList(mgr);
|
||||
break;
|
||||
case EScriptObjectMessage::AddPlatformRider:
|
||||
AddRider(x318_riders, uid, this, mgr);
|
||||
break;
|
||||
case EScriptObjectMessage::Stop:
|
||||
{
|
||||
x25c_currentMass = 0.f;
|
||||
Stop();
|
||||
break;
|
||||
}
|
||||
case EScriptObjectMessage::Next:
|
||||
{
|
||||
x25a_targetWaypoint = GetNext(x258_currentWaypoint, mgr);
|
||||
if (x25a_targetWaypoint == kInvalidUniqueId)
|
||||
mgr.SendScriptMsg(this, GetUniqueId(), EScriptObjectMessage::Stop);
|
||||
else if (TCastToPtr<CScriptWaypoint> wp = mgr.ObjectById(x25a_targetWaypoint))
|
||||
{
|
||||
x25c_currentMass = 0.f;
|
||||
Stop();
|
||||
x270_ = wp->GetTranslation() - GetTranslation();
|
||||
SetTranslation(wp->GetTranslation());
|
||||
|
||||
x258_currentWaypoint = x25a_targetWaypoint;
|
||||
x25a_targetWaypoint = GetNext(x258_currentWaypoint, mgr);
|
||||
mgr.SendScriptMsg(wp, GetUniqueId(), EScriptObjectMessage::Arrived);
|
||||
#if 0
|
||||
if (!x328_slaves1.empty() || !x338_slaves2.empty())
|
||||
DragSlaves(bitVector, x270_);
|
||||
|
||||
/* TODO: Implement bitvector */
|
||||
#endif
|
||||
x270_ = zeus::CVector3f::skZero;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case EScriptObjectMessage::Start:
|
||||
{
|
||||
x25a_targetWaypoint = GetNext(x258_currentWaypoint, mgr);
|
||||
if (x25a_targetWaypoint == kInvalidUniqueId)
|
||||
mgr.SendScriptMsg(this, GetUniqueId(), EScriptObjectMessage::Stop);
|
||||
else
|
||||
x25c_currentMass = 0.f;
|
||||
break;
|
||||
}
|
||||
case EScriptObjectMessage::Reset:
|
||||
{
|
||||
x356_24_dead = false;
|
||||
x294_health = x28c_initialHealth;
|
||||
break;
|
||||
}
|
||||
case EScriptObjectMessage::Increment:
|
||||
{
|
||||
if (GetActive())
|
||||
CScriptColorModulate::FadeInHelper(mgr, GetUniqueId(), x268_fadeInTime);
|
||||
else
|
||||
mgr.SendScriptMsg(this, GetUniqueId(), EScriptObjectMessage::Activate);
|
||||
break;
|
||||
}
|
||||
case EScriptObjectMessage::Decrement:
|
||||
CScriptColorModulate::FadeOutHelper(mgr, GetUniqueId(), x26c_fadeOutTime);
|
||||
break;
|
||||
case EScriptObjectMessage::Deleted:
|
||||
DecayRiders(x318_riders, 0.f, mgr);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
CPhysicsActor::AcceptScriptMsg(msg, uid, mgr);
|
||||
}
|
||||
|
||||
void CScriptPlatform::PreThink(float dt, CStateManager& mgr)
|
||||
{
|
||||
DecayRiders(x318_riders, dt, mgr);
|
||||
x264_ -= dt;
|
||||
x260_ -= dt;
|
||||
if (x260_ <= 0.f)
|
||||
{
|
||||
x270_ = zeus::CVector3f::skZero;
|
||||
zeus::CTransform xf = x34_transform;
|
||||
CMotionState mState = GetMotionState();
|
||||
if (GetActive())
|
||||
{
|
||||
for (SRiders& rider : x318_riders)
|
||||
{
|
||||
if (TCastToPtr<CPhysicsActor> act = mgr.ObjectById(rider.x0_uid))
|
||||
rider.x8_transform.origin = x34_transform.transposeRotate(act->GetTranslation() - GetTranslation());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
x27c_ = Move(dt, mgr);
|
||||
}
|
||||
|
||||
void CScriptPlatform::Think(float dt, CStateManager& mgr)
|
||||
{
|
||||
if (!GetActive())
|
||||
return;
|
||||
|
||||
if (HasModelData() && GetModelData()->HasAnimData())
|
||||
{
|
||||
if (!x356_25_)
|
||||
UpdateAnimation(dt, mgr, true);
|
||||
if (x356_28_ && mgr.GetWorld()->GetNeededEnvFx() == EEnvFxType::Rain)
|
||||
{
|
||||
if (HasModelData() && (GetModelData()->HasAnimData() || GetModelData()->HasNormalModel())
|
||||
&& mgr.GetEnvFxManager()->GetRainMagnitude() != 0.f)
|
||||
mgr.GetEnvFxManager()->sub801e4f10(this, 0.f, mgr, x34c_, x350_);
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (!x328_slaves1.empty() || !x338_slaves2.empty())
|
||||
DragSlaves(bitVector, x270_);
|
||||
|
||||
/* TODO: Implement bitvector */
|
||||
#endif
|
||||
|
||||
if (x356_24_dead)
|
||||
return;
|
||||
|
||||
if (HealthInfo(mgr)->GetHP() <= 0.f)
|
||||
{
|
||||
x356_24_dead = true;
|
||||
SendScriptMsgs(EScriptObjectState::Dead, mgr, EScriptObjectMessage::None);
|
||||
}
|
||||
}
|
||||
|
||||
std::experimental::optional<zeus::CAABox> CScriptPlatform::GetTouchBounds() const
|
||||
{
|
||||
if (x314_treeGroup)
|
||||
|
@ -64,4 +214,68 @@ bool CScriptPlatform::IsSlave(TUniqueId id) const
|
|||
[id](const SRiders& rider){ return rider.x0_uid == id; });
|
||||
return search != x338_slaves2.end();
|
||||
}
|
||||
|
||||
void CScriptPlatform::BuildSlaveList(CStateManager& mgr)
|
||||
{
|
||||
}
|
||||
|
||||
void CScriptPlatform::AddRider(std::vector<SRiders>&, TUniqueId, const CPhysicsActor*, CStateManager& )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
TUniqueId CScriptPlatform::GetNext(TUniqueId uid, CStateManager& mgr)
|
||||
{
|
||||
TCastToConstPtr<CScriptWaypoint> nextWp = mgr.GetObjectById(uid);
|
||||
if (!nextWp)
|
||||
return GetWaypoint(mgr);
|
||||
|
||||
TUniqueId next = nextWp->NextWaypoint(mgr);
|
||||
if (TCastToConstPtr<CScriptWaypoint>(mgr.GetObjectById(next)))
|
||||
x25c_currentMass = xe8_mass;
|
||||
|
||||
return next;
|
||||
}
|
||||
|
||||
TUniqueId CScriptPlatform::GetWaypoint(CStateManager& mgr)
|
||||
{
|
||||
for (const SConnection& conn : x20_conns)
|
||||
{
|
||||
if (conn.x4_msg == EScriptObjectMessage::Follow)
|
||||
return mgr.GetIdForScript(conn.x8_objId);
|
||||
}
|
||||
|
||||
return kInvalidUniqueId;
|
||||
}
|
||||
|
||||
void CScriptPlatform::SplashThink(const zeus::CAABox &, const CFluidPlane &, float, CStateManager &) const
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
zeus::CQuaternion CScriptPlatform::Move(float, CStateManager& mgr)
|
||||
{
|
||||
TUniqueId nextWaypoint = x25a_targetWaypoint;
|
||||
if (x25a_targetWaypoint == kInvalidUniqueId)
|
||||
nextWaypoint = GetNext(x258_currentWaypoint, mgr);
|
||||
|
||||
TCastToPtr<CScriptWaypoint> wp = mgr.ObjectById(nextWaypoint);
|
||||
if (x258_currentWaypoint != kInvalidUniqueId)
|
||||
{
|
||||
if (wp && !wp->GetActive())
|
||||
nextWaypoint = GetNext(x258_currentWaypoint, mgr);
|
||||
if (nextWaypoint == kInvalidUniqueId)
|
||||
{
|
||||
if (TCastToPtr<CScriptWaypoint> wp = mgr.ObjectById(x258_currentWaypoint))
|
||||
if (wp->GetActive())
|
||||
nextWaypoint = wp->GetUniqueId();
|
||||
}
|
||||
}
|
||||
|
||||
if (nextWaypoint == kInvalidUniqueId)
|
||||
return zeus::CQuaternion::skNoRotation;
|
||||
|
||||
/* TODO: Finish */
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ namespace urde
|
|||
{
|
||||
class CCollidableOBBTreeGroup;
|
||||
class CCollidableOBBTreeGroupContainer;
|
||||
class CFluidPlane;
|
||||
|
||||
struct SRiders
|
||||
{
|
||||
|
@ -22,18 +23,18 @@ struct SRiders
|
|||
class CScriptPlatform : public CPhysicsActor
|
||||
{
|
||||
u32 x254_;
|
||||
TUniqueId x258_ = kInvalidUniqueId;
|
||||
TUniqueId x25a_ = kInvalidUniqueId;
|
||||
float x25c_;
|
||||
float x260_;
|
||||
float x264_;
|
||||
float x268_;
|
||||
float x26c_;
|
||||
TUniqueId x258_currentWaypoint = kInvalidUniqueId;
|
||||
TUniqueId x25a_targetWaypoint = kInvalidUniqueId;
|
||||
float x25c_currentMass;
|
||||
float x260_ = 0.f;
|
||||
float x264_ = 0.f;
|
||||
float x268_fadeInTime = 0.f;
|
||||
float x26c_fadeOutTime = 0.f;
|
||||
zeus::CVector3f x270_;
|
||||
zeus::CQuaternion x27c_;
|
||||
CHealthInfo x28c_;
|
||||
CHealthInfo x294_;
|
||||
CDamageVulnerability x29c_;
|
||||
CHealthInfo x28c_initialHealth;
|
||||
CHealthInfo x294_health;
|
||||
CDamageVulnerability x29c_damageVuln;
|
||||
std::experimental::optional<TLockedToken<CCollidableOBBTreeGroupContainer>> x304_treeGroupContainer;
|
||||
std::unique_ptr<CCollidableOBBTreeGroup> x314_treeGroup;
|
||||
std::vector<SRiders> x318_riders;
|
||||
|
@ -42,12 +43,12 @@ class CScriptPlatform : public CPhysicsActor
|
|||
float x348_;
|
||||
u32 x34c_;
|
||||
u32 x350_;
|
||||
TUniqueId x354_;
|
||||
TUniqueId x354_ = kInvalidUniqueId;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
bool x356_24_ : 1;
|
||||
bool x356_24_dead : 1;
|
||||
bool x356_25_ : 1;
|
||||
bool x356_26_ : 1;
|
||||
bool x356_27_ : 1;
|
||||
|
@ -66,6 +67,9 @@ public:
|
|||
const std::experimental::optional<TLockedToken<CCollidableOBBTreeGroupContainer>>& dcln, bool, u32, u32);
|
||||
|
||||
void Accept(IVisitor& visitor);
|
||||
void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&);
|
||||
void PreThink(float, CStateManager&);
|
||||
void Think(float, CStateManager&);
|
||||
std::experimental::optional<zeus::CAABox> GetTouchBounds() const;
|
||||
bool IsRider(TUniqueId id) const;
|
||||
bool IsSlave(TUniqueId id) const;
|
||||
|
@ -75,6 +79,17 @@ public:
|
|||
const std::vector<SRiders>& GetX338() const { return x338_slaves2; }
|
||||
void AddSlave(TUniqueId, CStateManager&) {}
|
||||
bool HasComplexCollision() const { return x314_treeGroup.operator bool(); }
|
||||
void BuildSlaveList(CStateManager&);
|
||||
void AddRider(std::vector<SRiders>&, TUniqueId, const CPhysicsActor*, CStateManager&);
|
||||
TUniqueId GetNext(TUniqueId, CStateManager&);
|
||||
TUniqueId GetWaypoint(CStateManager&);
|
||||
|
||||
const CDamageVulnerability* GetDamageVulnerability() const { return &x29c_damageVuln; }
|
||||
CHealthInfo* HealthInfo(CStateManager&) { return &x294_health; }
|
||||
void DecayRiders(std::vector<SRiders>&, float, CStateManager&) {}
|
||||
|
||||
virtual void SplashThink(const zeus::CAABox&, const CFluidPlane&, float, CStateManager&) const;
|
||||
virtual zeus::CQuaternion Move(float, CStateManager&);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include "Audio/CSfxManager.hpp"
|
||||
#include "TCastTo.hpp"
|
||||
#include "GameGlobalObjects.hpp"
|
||||
#include "CMemoryCardSys.hpp"
|
||||
#include "CGameState.hpp"
|
||||
#include "CStateManager.hpp"
|
||||
#include "IMain.hpp"
|
||||
|
@ -17,7 +18,7 @@ CScriptSpecialFunction::CScriptSpecialFunction(TUniqueId uid, std::string_view n
|
|||
const zeus::CTransform& xf, ESpecialFunction func,
|
||||
std::string_view lcName, float f1, float f2, float f3, float f4,
|
||||
const zeus::CVector3f& vec, const zeus::CColor& col, bool active,
|
||||
const CDamageInfo& dInfo, CAssetId aId1, CAssetId aId2, CAssetId aId3,
|
||||
const CDamageInfo& dInfo, s32 aId1, s32 aId2, CAssetId aId3,
|
||||
s16 sId1, s16 sId2, s16 sId3)
|
||||
: CActor(uid, active, name, info, xf, CModelData::CModelDataNull(), CMaterialList(), CActorParameters::None(),
|
||||
kInvalidUniqueId)
|
||||
|
@ -33,8 +34,8 @@ CScriptSpecialFunction::CScriptSpecialFunction(TUniqueId uid, std::string_view n
|
|||
, x170_(CSfxManager::TranslateSFXID(sId1))
|
||||
, x172_(CSfxManager::TranslateSFXID(sId2))
|
||||
, x174_(CSfxManager::TranslateSFXID(sId3))
|
||||
, x1bc_(aId1)
|
||||
, x1c0_(aId2)
|
||||
, x1bc_areaSaveId(aId1)
|
||||
, x1c0_layerIdx(aId2)
|
||||
, x1c4_(aId3)
|
||||
{
|
||||
x1e4_26_ = true;
|
||||
|
@ -88,6 +89,15 @@ void CScriptSpecialFunction::Think(float dt, CStateManager& mgr)
|
|||
default: break;
|
||||
}
|
||||
}
|
||||
static const ERumbleFxId fxTranslation[6] =
|
||||
{
|
||||
ERumbleFxId::Twenty,
|
||||
ERumbleFxId::One,
|
||||
ERumbleFxId::TwentyOne,
|
||||
ERumbleFxId::TwentyTwo,
|
||||
ERumbleFxId::TwentyThree,
|
||||
ERumbleFxId::Zero
|
||||
};
|
||||
|
||||
void CScriptSpecialFunction::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr)
|
||||
{
|
||||
|
@ -332,8 +342,54 @@ void CScriptSpecialFunction::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId
|
|||
}
|
||||
case ESpecialFunction::ScriptLayerController:
|
||||
{
|
||||
if (msg == EScriptObjectMessage::Decrement || msg == EScriptObjectMessage::Increment)
|
||||
{
|
||||
if (x1bc_areaSaveId != -1 && x1c0_layerIdx != -1)
|
||||
{
|
||||
TAreaId aId = mgr.GetWorld()->GetAreaIdForSaveId(x1bc_areaSaveId);
|
||||
std::shared_ptr<CWorldLayerState> worldLayerState;
|
||||
if (aId != kInvalidAreaId)
|
||||
worldLayerState = mgr.WorldLayerStateNC();
|
||||
else
|
||||
{
|
||||
std::pair<CAssetId, TAreaId> worldAreaPair = g_MemoryCardSys->GetAreaAndWorldIdForSaveId(x1bc_areaSaveId);
|
||||
if (worldAreaPair.first.IsValid())
|
||||
{
|
||||
worldLayerState = g_GameState->StateForWorld(worldAreaPair.first).GetLayerState();
|
||||
aId = worldAreaPair.second;
|
||||
}
|
||||
}
|
||||
|
||||
if (aId != kInvalidAreaId)
|
||||
worldLayerState->SetLayerActive(aId, x1c0_layerIdx, msg == EScriptObjectMessage::Increment);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
/*
|
||||
For some bizarre reason ScriptLayerController drops into EnvFxDensityController
|
||||
[[fallthrough]];
|
||||
We won't do that though
|
||||
*/
|
||||
case ESpecialFunction::EnvFxDensityController:
|
||||
{
|
||||
if (msg == EScriptObjectMessage::Action)
|
||||
mgr.GetEnvFxManager()->SetFxDensity(s32(x100_), xfc_);
|
||||
break;
|
||||
}
|
||||
case ESpecialFunction::RumbleEffect:
|
||||
if (msg == EScriptObjectMessage::Action)
|
||||
{
|
||||
s32 rumbFx = s32(x100_);
|
||||
/* Retro originally did not check the upper bounds, this could potentially cause a crash
|
||||
* with some runtimes, so let's make sure we're not out of bounds in either direction
|
||||
*/
|
||||
if (rumbFx < 0 || rumbFx >= 6)
|
||||
break;
|
||||
|
||||
mgr.GetRumbleManager().Rumble(mgr, fxTranslation[rumbFx], 1.f, ERumblePriority::One);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -92,8 +92,8 @@ private:
|
|||
u32 x1a8_ = 2;
|
||||
zeus::CVector3f x1ac_ = zeus::CVector3f::skZero;
|
||||
bool x1b8_ = true;
|
||||
CAssetId x1bc_;
|
||||
CAssetId x1c0_;
|
||||
s32 x1bc_areaSaveId;
|
||||
s32 x1c0_layerIdx;
|
||||
CAssetId x1c4_;
|
||||
std::experimental::optional<zeus::CAABox> x1c8_;
|
||||
union
|
||||
|
@ -118,7 +118,7 @@ private:
|
|||
public:
|
||||
CScriptSpecialFunction(TUniqueId, std::string_view, const CEntityInfo&, const zeus::CTransform&, ESpecialFunction,
|
||||
std::string_view, float, float, float, float, const zeus::CVector3f&, const zeus::CColor&,
|
||||
bool, const CDamageInfo&, CAssetId, CAssetId, CAssetId, s16, s16, s16);
|
||||
bool, const CDamageInfo&, s32, s32, CAssetId, s16, s16, s16);
|
||||
|
||||
void Accept(IVisitor& visitor);
|
||||
void Think(float, CStateManager &);
|
||||
|
|
|
@ -775,4 +775,23 @@ bool CWorld::AreSkyNeedsMet() const
|
|||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
TAreaId CWorld::GetAreaIdForSaveId(s32 saveId) const
|
||||
{
|
||||
if (saveId == -1)
|
||||
return kInvalidAreaId;
|
||||
|
||||
if (x18_areas.size() <= 0)
|
||||
return kInvalidAreaId;
|
||||
|
||||
TAreaId cur = 0;
|
||||
for (const auto& area : x18_areas)
|
||||
{
|
||||
if (area->x88_areaId == saveId)
|
||||
return cur;
|
||||
++cur;
|
||||
}
|
||||
|
||||
return kInvalidAreaId;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -211,6 +211,7 @@ public:
|
|||
EEnvFxType GetNeededEnvFx() const { return xc4_neededFx; }
|
||||
CAssetId GetWorldAssetId() const { return x8_mlvlId; }
|
||||
bool AreSkyNeedsMet() const;
|
||||
TAreaId GetAreaIdForSaveId(s32 saveId) const;
|
||||
};
|
||||
|
||||
struct CWorldLayers
|
||||
|
|
|
@ -2387,7 +2387,7 @@ CEntity* ScriptLoader::LoadFogVolume(CStateManager& mgr, CInputStream& in, int p
|
|||
|
||||
return new CScriptSpecialFunction(mgr.AllocateUniqueId(), name, info, ConvertEditorEulerToTransform4f(center, {}),
|
||||
CScriptSpecialFunction::ESpecialFunction::FogVolume, "", flickerSpeed, f2, 0.f,
|
||||
0.f, volume, fogColor, active, CDamageInfo(), CAssetId(), CAssetId(), CAssetId(),
|
||||
0.f, volume, fogColor, active, CDamageInfo(), -1, -1, CAssetId(),
|
||||
-1, -1, -1);
|
||||
}
|
||||
|
||||
|
@ -2448,7 +2448,7 @@ CEntity* ScriptLoader::LoadEnvFxDensityController(CStateManager& mgr, CInputStre
|
|||
return new CScriptSpecialFunction(mgr.AllocateUniqueId(), name, info, zeus::CTransform::Identity(),
|
||||
CScriptSpecialFunction::ESpecialFunction::EnvFxDensityController, "", density, w1,
|
||||
0.f, 0.f, zeus::CVector3f::skZero, zeus::CColor::skBlack, active, CDamageInfo(),
|
||||
CAssetId(), CAssetId(), CAssetId(), -1, -1, -1);
|
||||
-1, -1, CAssetId(), -1, -1, -1);
|
||||
}
|
||||
|
||||
CEntity* ScriptLoader::LoadMagdolite(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info)
|
||||
|
|
2
hecl-gui
2
hecl-gui
|
@ -1 +1 @@
|
|||
Subproject commit 53a4334b239e7653536e8663880a79660c93ebb6
|
||||
Subproject commit 690a69707dea51eead11d4c0e7246603c6e8e52c
|
Loading…
Reference in New Issue