mirror of
https://github.com/isledecomp/isle-portable.git
synced 2026-01-12 02:41:14 +00:00
(SiLoader) Start actions attached to world startup when world is ready (#704)
This commit is contained in:
parent
017be000de
commit
ace6b7fc7e
@ -407,6 +407,8 @@ LegoOmni* LegoOmni::GetInstance()
|
||||
void LegoOmni::AddWorld(LegoWorld* p_world)
|
||||
{
|
||||
m_worldList->Append(p_world);
|
||||
|
||||
Extension<SiLoader>::Call(HandleWorld, p_world);
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x1005adb0
|
||||
|
||||
@ -23,6 +23,7 @@ class SiLoader {
|
||||
static bool Load();
|
||||
static std::optional<MxCore*> HandleFind(StreamObject p_object, LegoWorld* world);
|
||||
static std::optional<MxResult> HandleStart(MxDSAction& p_action);
|
||||
static MxBool HandleWorld(LegoWorld* p_world);
|
||||
static std::optional<MxBool> HandleRemove(StreamObject p_object, LegoWorld* world);
|
||||
static std::optional<MxBool> HandleDelete(MxDSAction& p_action);
|
||||
static MxBool HandleEndAction(MxEndActionNotificationParam& p_param);
|
||||
@ -47,6 +48,7 @@ class SiLoader {
|
||||
static bool LoadDirective(const char* p_directive);
|
||||
static MxStreamController* OpenStream(const char* p_file);
|
||||
static void ParseExtra(const MxAtomId& p_atom, si::Core* p_core, MxAtomId p_parentReplacedAtom = MxAtomId());
|
||||
static bool IsWorld(const StreamObject& p_object);
|
||||
};
|
||||
|
||||
#ifdef EXTENSIONS
|
||||
@ -70,6 +72,7 @@ bool SiLoader::ReplacedIn(MxDSAction& p_action, Args... p_args)
|
||||
constexpr auto Load = &SiLoader::Load;
|
||||
constexpr auto HandleFind = &SiLoader::HandleFind;
|
||||
constexpr auto HandleStart = &SiLoader::HandleStart;
|
||||
constexpr auto HandleWorld = &SiLoader::HandleWorld;
|
||||
constexpr auto HandleRemove = &SiLoader::HandleRemove;
|
||||
constexpr auto HandleDelete = &SiLoader::HandleDelete;
|
||||
constexpr auto HandleEndAction = &SiLoader::HandleEndAction;
|
||||
@ -78,6 +81,7 @@ constexpr auto ReplacedIn = [](auto&&... args) { return SiLoader::ReplacedIn(std
|
||||
constexpr decltype(&SiLoader::Load) Load = nullptr;
|
||||
constexpr decltype(&SiLoader::HandleFind) HandleFind = nullptr;
|
||||
constexpr decltype(&SiLoader::HandleStart) HandleStart = nullptr;
|
||||
constexpr decltype(&SiLoader::HandleWorld) HandleWorld = nullptr;
|
||||
constexpr decltype(&SiLoader::HandleRemove) HandleRemove = nullptr;
|
||||
constexpr decltype(&SiLoader::HandleDelete) HandleDelete = nullptr;
|
||||
constexpr decltype(&SiLoader::HandleEndAction) HandleEndAction = nullptr;
|
||||
|
||||
@ -83,7 +83,7 @@ std::optional<MxResult> SiLoader::HandleStart(MxDSAction& p_action)
|
||||
};
|
||||
|
||||
for (const auto& key : startWith) {
|
||||
if (key.first == object) {
|
||||
if (key.first == object && !IsWorld(key.first)) {
|
||||
MxDSAction action;
|
||||
start(key.second, p_action, action);
|
||||
}
|
||||
@ -128,6 +128,30 @@ std::optional<MxResult> SiLoader::HandleStart(MxDSAction& p_action)
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
MxBool SiLoader::HandleWorld(LegoWorld* p_world)
|
||||
{
|
||||
StreamObject object{p_world->GetAtomId(), p_world->GetEntityId()};
|
||||
auto start = [](const StreamObject& p_object, MxDSAction& p_out) {
|
||||
if (!OpenStream(p_object.first.GetInternal())) {
|
||||
return;
|
||||
}
|
||||
|
||||
p_out.SetAtomId(p_object.first);
|
||||
p_out.SetObjectId(p_object.second);
|
||||
p_out.SetUnknown24(-1);
|
||||
Start(&p_out);
|
||||
};
|
||||
|
||||
for (const auto& key : startWith) {
|
||||
if (key.first == object) {
|
||||
MxDSAction action;
|
||||
start(key.second, action);
|
||||
}
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
std::optional<MxBool> SiLoader::HandleRemove(StreamObject p_object, LegoWorld* world)
|
||||
{
|
||||
for (const auto& key : removeWith) {
|
||||
@ -362,3 +386,17 @@ void SiLoader::ParseExtra(const MxAtomId& p_atom, si::Core* p_core, MxAtomId p_p
|
||||
ParseExtra(p_atom, child, replacedAtom);
|
||||
}
|
||||
}
|
||||
|
||||
bool SiLoader::IsWorld(const StreamObject& p_object)
|
||||
{
|
||||
// The convention in LEGO Island is that world objects are always at ID 0
|
||||
if (p_object.second == 0) {
|
||||
for (int i = 0; i < LegoOmni::e_numWorlds; i++) {
|
||||
if (p_object.first == *Lego()->GetWorldAtom((LegoOmni::World) i)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user