Merge pull request #54 from foxtacles/isleupd2

Update from isledecomp/isle
This commit is contained in:
Christian Semmler 2025-01-11 10:37:51 -07:00 committed by GitHub
commit c91260e440
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
19 changed files with 365 additions and 314 deletions

View File

@ -28,6 +28,7 @@ public:
// SIZE 0x38 // SIZE 0x38
struct SpawnLocation { struct SpawnLocation {
// FUNCTION: LEGO1 0x1001a6f0
SpawnLocation() {} SpawnLocation() {}
// FUNCTION: LEGO1 0x1001b1b0 // FUNCTION: LEGO1 0x1001b1b0

View File

@ -93,6 +93,10 @@ public:
LegoCarBuild(); LegoCarBuild();
~LegoCarBuild() override; ~LegoCarBuild() override;
// FUNCTION: LEGO1 0x10022930
// FUNCTION: BETA10 0x10070070
MxBool VTable0x5c() override { return TRUE; } // vtable+0x5c
// FUNCTION: LEGO1 0x10022940 // FUNCTION: LEGO1 0x10022940
// FUNCTION: BETA10 0x10070090 // FUNCTION: BETA10 0x10070090
const char* ClassName() const override // vtable+0x0c const char* ClassName() const override // vtable+0x0c
@ -112,7 +116,6 @@ public:
MxResult Create(MxDSAction& p_dsAction) override; // vtable+0x18 MxResult Create(MxDSAction& p_dsAction) override; // vtable+0x18
void ReadyWorld() override; // vtable+0x50 void ReadyWorld() override; // vtable+0x50
MxBool VTable0x5c() override; // vtable+0x5c
MxBool Escape() override; // vtable+0x64 MxBool Escape() override; // vtable+0x64
void Enable(MxBool p_enable) override; // vtable+0x68 void Enable(MxBool p_enable) override; // vtable+0x68
virtual void VTable0x6c(); // vtable+0x6c virtual void VTable0x6c(); // vtable+0x6c

View File

@ -2,6 +2,7 @@
#define LEGOEXTRAACTOR_H #define LEGOEXTRAACTOR_H
#include "legoanimactor.h" #include "legoanimactor.h"
#include "legopathboundary.h"
// VTABLE: LEGO1 0x100d6c00 LegoAnimActor // VTABLE: LEGO1 0x100d6c00 LegoAnimActor
// VTABLE: LEGO1 0x100d6c10 LegoPathActor // VTABLE: LEGO1 0x100d6c10 LegoPathActor
@ -36,9 +37,9 @@ public:
return !strcmp(p_name, LegoExtraActor::ClassName()) || LegoAnimActor::IsA(p_name); return !strcmp(p_name, LegoExtraActor::ClassName()) || LegoAnimActor::IsA(p_name);
} }
void SetWorldSpeed(MxFloat p_worldSpeed) override; // vtable+0x30 void SetWorldSpeed(MxFloat p_worldSpeed) override; // vtable+0x30
MxS32 VTable0x68(Vector3&, Vector3&, Vector3&) override; // vtable+0x68 MxS32 VTable0x68(Vector3& p_point1, Vector3& p_point2, Vector3& p_point3) override; // vtable+0x68
MxU32 VTable0x6c( inline MxU32 VTable0x6c(
LegoPathBoundary* p_boundary, LegoPathBoundary* p_boundary,
Vector3& p_v1, Vector3& p_v1,
Vector3& p_v2, Vector3& p_v2,
@ -77,6 +78,108 @@ private:
LegoAnimActorStruct* m_disAnim; // 0x64 LegoAnimActorStruct* m_disAnim; // 0x64
}; };
// FUNCTION: LEGO1 0x1002b980
inline MxU32 LegoExtraActor::VTable0x6c(
LegoPathBoundary* p_boundary,
Vector3& p_v1,
Vector3& p_v2,
float p_f1,
float p_f2,
Vector3& p_v3
)
{
LegoAnimPresenterSet& presenters = p_boundary->GetPresenters();
for (LegoAnimPresenterSet::iterator itap = presenters.begin(); itap != presenters.end(); itap++) {
if ((*itap)->VTable0x94(p_v1, p_v2, p_f1, p_f2, p_v3)) {
return 1;
}
}
LegoPathActorSet& plpas = p_boundary->GetActors();
LegoPathActorSet lpas(plpas);
for (LegoPathActorSet::iterator itpa = lpas.begin(); itpa != lpas.end(); itpa++) {
if (plpas.find(*itpa) != plpas.end()) {
LegoPathActor* actor = *itpa;
if (this != actor && !(actor->GetActorState() & LegoPathActor::c_noCollide)) {
LegoROI* roi = actor->GetROI();
if ((roi != NULL && roi->GetVisibility()) || actor->GetCameraFlag()) {
if (actor->GetUserNavFlag()) {
MxMatrix local2world = roi->GetLocal2World();
Vector3 local60(local2world[3]);
Mx3DPointFloat local54(p_v1);
local54 -= local60;
float local1c = p_v2.Dot(p_v2, p_v2);
float local24 = p_v2.Dot(p_v2, local54) * 2.0f;
float local20 = local54.Dot(local54, local54);
if (m_unk0x15 != 0 && local20 < 10.0f) {
return 0;
}
local20 -= 1.0f;
if (local1c >= 0.001 || local1c <= -0.001) {
float local40 = (local24 * local24) + (local20 * local1c * -4.0f);
if (local40 >= -0.001) {
local1c *= 2.0f;
local24 = -local24;
if (local40 < 0.0f) {
local40 = 0.0f;
}
local40 = sqrt(local40);
float local20X = (local24 + local40) / local1c;
float local1cX = (local24 - local40) / local1c;
if (local1cX < local20X) {
local40 = local20X;
local20X = local1cX;
local1cX = local40;
}
if ((local20X >= 0.0f && local20X <= p_f1) || (local1cX >= 0.0f && local1cX <= p_f1) ||
(local20X <= -0.01 && p_f1 + 0.01 <= local1cX)) {
p_v3 = p_v1;
if (HitActor(actor, TRUE) < 0) {
return 0;
}
actor->HitActor(this, FALSE);
return 2;
}
}
}
}
else {
if (roi->FUN_100a9410(p_v1, p_v2, p_f1, p_f2, p_v3, m_collideBox && actor->GetCollideBox())) {
if (HitActor(actor, TRUE) < 0) {
return 0;
}
actor->HitActor(this, FALSE);
return 2;
}
}
}
}
}
}
if (m_unk0x15 != 0) {
m_unk0x15--;
}
return 0;
}
// GLOBAL: LEGO1 0x100d6be8 // GLOBAL: LEGO1 0x100d6be8
// LegoExtraActor::`vbtable'{for `LegoAnimActor'} // LegoExtraActor::`vbtable'{for `LegoAnimActor'}

View File

@ -138,6 +138,9 @@ public:
MxFloat& p_param5 MxFloat& p_param5
); );
// FUNCTION: BETA10 0x100e0160
MxBool ActorExists(LegoPathActor* p_actor) { return m_actors.find(p_actor) == m_actors.end() ? FALSE : TRUE; }
static MxResult Init(); static MxResult Init();
static MxResult Reset(); static MxResult Reset();

View File

@ -1,15 +1,18 @@
#ifndef LEGOWORLD_H #ifndef LEGOWORLD_H
#define LEGOWORLD_H #define LEGOWORLD_H
// clang-format off
#include "mxpresenterlist.h"
#include "legoentitylist.h"
#include "legocachesoundlist.h"
// clang-format on
#include "legoentity.h" #include "legoentity.h"
#include "legomain.h" #include "legomain.h"
#include "legopathcontrollerlist.h" #include "legopathcontrollerlist.h"
#include "mxpresenterlist.h"
#include "roi/legoroi.h" #include "roi/legoroi.h"
class LegoCacheSoundList;
class LegoCameraController; class LegoCameraController;
class LegoEntityList;
class LegoPathBoundary; class LegoPathBoundary;
class LegoHideAnimPresenter; class LegoHideAnimPresenter;
@ -44,8 +47,26 @@ public:
LegoWorld(); LegoWorld();
~LegoWorld() override; // vtable+0x00 ~LegoWorld() override; // vtable+0x00
MxLong Notify(MxParam& p_param) override; // vtable+0x04 MxLong Notify(MxParam& p_param) override; // vtable+0x04
MxResult Tickle() override; // vtable+0x08 MxResult Tickle() override; // vtable+0x08
MxResult Create(MxDSAction& p_dsAction) override; // vtable+0x18
void Destroy(MxBool p_fromDestructor) override; // vtable+0x1c
virtual void ReadyWorld(); // vtable+0x50
virtual LegoCameraController* VTable0x54(); // vtable+0x54
virtual void Add(MxCore* p_object); // vtable+0x58
// The BETA10 match could also be LegoWorld::Escape(), only the child classes might be able to tell
// FUNCTION: LEGO1 0x1001d670
// FUNCTION: BETA10 0x10017530
virtual MxBool VTable0x5c() { return FALSE; } // vtable+0x5c
// FUNCTION: LEGO1 0x100010a0
virtual void VTable0x60() {} // vtable+0x60
// FUNCTION: LEGO1 0x1001d680
virtual MxBool Escape() { return FALSE; } // vtable+0x64
virtual void Enable(MxBool p_enable); // vtable+0x68
// FUNCTION: LEGO1 0x1001d690 // FUNCTION: LEGO1 0x1001d690
// FUNCTION: BETA10 0x10017660 // FUNCTION: BETA10 0x10017660
@ -62,19 +83,6 @@ public:
return !strcmp(p_name, LegoWorld::ClassName()) || LegoEntity::IsA(p_name); return !strcmp(p_name, LegoWorld::ClassName()) || LegoEntity::IsA(p_name);
} }
MxResult Create(MxDSAction& p_dsAction) override; // vtable+0x18
void Destroy(MxBool p_fromDestructor) override; // vtable+0x1c
virtual void ReadyWorld(); // vtable+0x50
virtual LegoCameraController* VTable0x54(); // vtable+0x54
virtual void Add(MxCore* p_object); // vtable+0x58
virtual MxBool VTable0x5c(); // vtable+0x5c
// FUNCTION: LEGO1 0x100010a0
virtual void VTable0x60() {} // vtable+0x60
virtual MxBool Escape(); // vtable+0x64
virtual void Enable(MxBool p_enable); // vtable+0x68
MxBool PresentersPending(); MxBool PresentersPending();
void Remove(MxCore* p_object); void Remove(MxCore* p_object);
MxResult PlaceActor( MxResult PlaceActor(
@ -93,6 +101,7 @@ public:
Vector3& p_direction Vector3& p_direction
); );
void RemoveActor(LegoPathActor* p_actor); void RemoveActor(LegoPathActor* p_actor);
MxBool ActorExists(LegoPathActor* p_actor);
void FUN_1001fda0(LegoAnimPresenter* p_presenter); void FUN_1001fda0(LegoAnimPresenter* p_presenter);
void FUN_1001fe90(LegoAnimPresenter* p_presenter); void FUN_1001fe90(LegoAnimPresenter* p_presenter);
LegoPathBoundary* FindPathBoundary(const char* p_name); LegoPathBoundary* FindPathBoundary(const char* p_name);
@ -176,7 +185,8 @@ protected:
// TEMPLATE: LEGO1 0x10020b20 // TEMPLATE: LEGO1 0x10020b20
// _Tree<MxCore *,MxCore *,set<MxCore *,CoreSetCompare,allocator<MxCore *> >::_Kfn,CoreSetCompare,allocator<MxCore *> >::iterator::_Dec // _Tree<MxCore *,MxCore *,set<MxCore *,CoreSetCompare,allocator<MxCore *> >::_Kfn,CoreSetCompare,allocator<MxCore *> >::iterator::_Dec
// XTEMPLATE LEGO1 0x10020b70 // TEMPLATE: LEGO1 0x10020b70
// _Tree<MxCore *,MxCore *,set<MxCore *,CoreSetCompare,allocator<MxCore *> >::_Kfn,CoreSetCompare,allocator<MxCore *> >::lower_bound
// TEMPLATE: LEGO1 0x10020bb0 // TEMPLATE: LEGO1 0x10020bb0
// _Tree<MxCore *,MxCore *,set<MxCore *,CoreSetCompare,allocator<MxCore *> >::_Kfn,CoreSetCompare,allocator<MxCore *> >::_Buynode // _Tree<MxCore *,MxCore *,set<MxCore *,CoreSetCompare,allocator<MxCore *> >::_Kfn,CoreSetCompare,allocator<MxCore *> >::_Buynode

View File

@ -15,6 +15,9 @@ class RadioState : public LegoState {
public: public:
RadioState(); RadioState();
// FUNCTION: LEGO1 0x1002cf50
MxBool IsSerializable() override { return FALSE; } // vtable+0x14
// FUNCTION: LEGO1 0x1002cf60 // FUNCTION: LEGO1 0x1002cf60
// FUNCTION: BETA10 0x100f2850 // FUNCTION: BETA10 0x100f2850
const char* ClassName() const override // vtable+0x0c const char* ClassName() const override // vtable+0x0c
@ -29,8 +32,6 @@ public:
return !strcmp(p_name, RadioState::ClassName()) || LegoState::IsA(p_name); return !strcmp(p_name, RadioState::ClassName()) || LegoState::IsA(p_name);
} }
MxBool IsSerializable() override; // vtable+0x14
// SYNTHETIC: LEGO1 0x1002d020 // SYNTHETIC: LEGO1 0x1002d020
// RadioState::`scalar deleting destructor' // RadioState::`scalar deleting destructor'

View File

@ -19,9 +19,6 @@
DECOMP_SIZE_ASSERT(IslePathActor, 0x160) DECOMP_SIZE_ASSERT(IslePathActor, 0x160)
DECOMP_SIZE_ASSERT(IslePathActor::SpawnLocation, 0x38) DECOMP_SIZE_ASSERT(IslePathActor::SpawnLocation, 0x38)
// GLOBAL: LEGO1 0x10102b28
IslePathActor::SpawnLocation g_spawnLocations[IslePathActor::c_LOCATIONS_NUM];
// FUNCTION: LEGO1 0x1001a200 // FUNCTION: LEGO1 0x1001a200
IslePathActor::IslePathActor() IslePathActor::IslePathActor()
{ {
@ -157,6 +154,9 @@ void IslePathActor::Exit()
FUN_1003eda0(); FUN_1003eda0();
} }
// GLOBAL: LEGO1 0x10102b28
IslePathActor::SpawnLocation g_spawnLocations[IslePathActor::c_LOCATIONS_NUM];
// FUNCTION: LEGO1 0x1001a700 // FUNCTION: LEGO1 0x1001a700
void IslePathActor::RegisterSpawnLocations() void IslePathActor::RegisterSpawnLocations()
{ {

View File

@ -228,12 +228,6 @@ RadioState::RadioState()
m_active = FALSE; m_active = FALSE;
} }
// FUNCTION: LEGO1 0x1002cf50
MxBool RadioState::IsSerializable()
{
return FALSE;
}
// FUNCTION: LEGO1 0x1002d090 // FUNCTION: LEGO1 0x1002d090
MxU32 RadioState::FUN_1002d090() MxU32 RadioState::FUN_1002d090()
{ {

View File

@ -133,13 +133,6 @@ LegoCarBuild::LegoCarBuild()
NotificationManager()->Register(this); NotificationManager()->Register(this);
} }
// FUNCTION: LEGO1 0x10022930
// FUNCTION: BETA10 0x10070070
MxBool LegoCarBuild::VTable0x5c()
{
return TRUE;
}
// FUNCTION: LEGO1 0x10022a80 // FUNCTION: LEGO1 0x10022a80
// FUNCTION: BETA10 0x1006aea3 // FUNCTION: BETA10 0x1006aea3
LegoCarBuild::~LegoCarBuild() LegoCarBuild::~LegoCarBuild()

View File

@ -661,7 +661,6 @@ MxBool LegoBuildingManager::FUN_10030110(LegoBuildingInfo* p_data)
} }
// FUNCTION: LEGO1 0x10030150 // FUNCTION: LEGO1 0x10030150
// FUNCTION: BETA10 0x100644ff
void LegoBuildingManager::ScheduleAnimation(LegoEntity* p_entity, MxLong p_length, MxBool p_haveSound, MxBool p_unk0x28) void LegoBuildingManager::ScheduleAnimation(LegoEntity* p_entity, MxLong p_length, MxBool p_haveSound, MxBool p_unk0x28)
{ {
m_world = CurrentWorld(); m_world = CurrentWorld();

View File

@ -618,7 +618,11 @@ void LegoPlantManager::ScheduleAnimation(LegoEntity* p_entity, MxLong p_length)
entry->m_entity = p_entity; entry->m_entity = p_entity;
entry->m_roi = p_entity->GetROI(); entry->m_roi = p_entity->GetROI();
entry->m_time = Timer()->GetTime() + p_length + 1000;
MxLong time = Timer()->GetTime();
time += p_length;
entry->m_time = time + 1000;
FUN_100271b0(p_entity, -1); FUN_100271b0(p_entity, -1);
} }

View File

@ -4,11 +4,9 @@
#include "legoanimationmanager.h" #include "legoanimationmanager.h"
#include "legoanimpresenter.h" #include "legoanimpresenter.h"
#include "legobuildingmanager.h" #include "legobuildingmanager.h"
#include "legocachesoundlist.h"
#include "legocachesoundmanager.h" #include "legocachesoundmanager.h"
#include "legocameracontroller.h" #include "legocameracontroller.h"
#include "legocontrolmanager.h" #include "legocontrolmanager.h"
#include "legoentitylist.h"
#include "legogamestate.h" #include "legogamestate.h"
#include "legoinputmanager.h" #include "legoinputmanager.h"
#include "legolocomotionanimpresenter.h" #include "legolocomotionanimpresenter.h"
@ -49,20 +47,6 @@ LegoWorld::LegoWorld() : m_list0x68(TRUE)
NotificationManager()->Register(this); NotificationManager()->Register(this);
} }
// FUNCTION: LEGO1 0x1001d670
// FUNCTION: BETA10 0x10017530
MxBool LegoWorld::VTable0x5c()
{
// The BETA10 match could also be LegoWorld::Escape(), only the child classes might be able to tell
return FALSE;
}
// FUNCTION: LEGO1 0x1001d680
MxBool LegoWorld::Escape()
{
return FALSE;
}
// FUNCTION: LEGO1 0x1001dfa0 // FUNCTION: LEGO1 0x1001dfa0
LegoWorld::~LegoWorld() LegoWorld::~LegoWorld()
{ {
@ -352,6 +336,21 @@ void LegoWorld::RemoveActor(LegoPathActor* p_actor)
} }
} }
// FUNCTION: BETA10 0x100da560
MxBool LegoWorld::ActorExists(LegoPathActor* p_actor)
{
LegoPathControllerListCursor cursor(&m_list0x68);
LegoPathController* controller;
while (cursor.Next(controller)) {
if (controller->ActorExists(p_actor) == TRUE) {
return TRUE;
}
}
return FALSE;
}
// FUNCTION: LEGO1 0x1001fda0 // FUNCTION: LEGO1 0x1001fda0
// FUNCTION: BETA10 0x100da621 // FUNCTION: BETA10 0x100da621
void LegoWorld::FUN_1001fda0(LegoAnimPresenter* p_presenter) void LegoWorld::FUN_1001fda0(LegoAnimPresenter* p_presenter)
@ -420,68 +419,88 @@ MxResult LegoWorld::GetCurrPathInfo(LegoPathBoundary** p_boundaries, MxS32& p_nu
// FUNCTION: BETA10 0x100da90b // FUNCTION: BETA10 0x100da90b
void LegoWorld::Add(MxCore* p_object) void LegoWorld::Add(MxCore* p_object)
{ {
if (p_object && !p_object->IsA("LegoWorld") && !p_object->IsA("LegoWorldPresenter")) { if (p_object == NULL || p_object->IsA("LegoWorld") || p_object->IsA("LegoWorldPresenter")) {
if (p_object->IsA("LegoAnimPresenter")) { return;
LegoAnimPresenter* animPresenter = (LegoAnimPresenter*) p_object; }
if (!SDL_strcasecmp(animPresenter->GetAction()->GetObjectName(), "ConfigAnimation")) { #ifndef BETA10
FUN_1003e050(animPresenter); if (p_object->IsA("LegoAnimPresenter")) {
animPresenter->GetAction()->SetDuration(animPresenter->GetAnimation()->GetDuration()); if (!SDL_strcasecmp(((LegoAnimPresenter*) p_object)->GetAction()->GetObjectName(), "ConfigAnimation")) {
} FUN_1003e050((LegoAnimPresenter*) p_object);
((LegoAnimPresenter*) p_object)
->GetAction()
->SetDuration(((LegoAnimPresenter*) p_object)->GetAnimation()->GetDuration());
}
}
#endif
if (p_object->IsA("MxControlPresenter")) {
MxPresenterListCursor cursor(&m_controlPresenters);
if (cursor.Find((MxPresenter*) p_object)) {
assert(0);
return;
} }
if (p_object->IsA("MxControlPresenter")) { m_controlPresenters.Append((MxPresenter*) p_object);
MxPresenterListCursor cursor(&m_controlPresenters); }
else if (p_object->IsA("MxEntity")) {
LegoEntityListCursor cursor(m_entityList);
if (cursor.Find((MxPresenter*) p_object)) { if (cursor.Find((LegoEntity*) p_object)) {
return; assert(0);
} return;
m_controlPresenters.Append((MxPresenter*) p_object);
} }
else if (p_object->IsA("MxEntity")) {
LegoEntityListCursor cursor(m_entityList);
if (cursor.Find((LegoEntity*) p_object)) { m_entityList->Append((LegoEntity*) p_object);
return; }
} else if (p_object->IsA("LegoLocomotionAnimPresenter") || p_object->IsA("LegoHideAnimPresenter") || p_object->IsA("LegoLoopingAnimPresenter")) {
MxPresenterListCursor cursor(&m_animPresenters);
m_entityList->Append((LegoEntity*) p_object); if (cursor.Find((MxPresenter*) p_object)) {
assert(0);
return;
} }
else if (p_object->IsA("LegoLocomotionAnimPresenter") || p_object->IsA("LegoHideAnimPresenter") || p_object->IsA("LegoLoopingAnimPresenter")) {
MxPresenterListCursor cursor(&m_animPresenters);
if (cursor.Find((MxPresenter*) p_object)) { ((MxPresenter*) p_object)->SendToCompositePresenter(Lego());
return; m_animPresenters.Append(((MxPresenter*) p_object));
}
((MxPresenter*) p_object)->SendToCompositePresenter(Lego()); if (p_object->IsA("LegoHideAnimPresenter")) {
m_animPresenters.Append(((MxPresenter*) p_object)); m_hideAnim = (LegoHideAnimPresenter*) p_object;
if (p_object->IsA("LegoHideAnimPresenter")) {
m_hideAnim = (LegoHideAnimPresenter*) p_object;
}
} }
else if (p_object->IsA("LegoCacheSound")) { }
LegoCacheSoundListCursor cursor(m_cacheSoundList); #ifndef BETA10
else if (p_object->IsA("LegoCacheSound")) {
LegoCacheSoundListCursor cursor(m_cacheSoundList);
if (cursor.Find((LegoCacheSound*) p_object)) { if (cursor.Find((LegoCacheSound*) p_object)) {
return; assert(0); // ?
return;
}
m_cacheSoundList->Append((LegoCacheSound*) p_object);
}
#endif
else {
MxCoreSet::iterator it = m_set0xa8.find(p_object);
if (it == m_set0xa8.end()) {
#ifdef BETA10
if (p_object->IsA("MxPresenter")) {
assert(static_cast<MxPresenter*>(p_object)->GetAction());
} }
#endif
m_cacheSoundList->Append((LegoCacheSound*) p_object); m_set0xa8.insert(p_object);
} }
else { else {
if (m_set0xa8.find(p_object) == m_set0xa8.end()) { assert(0);
m_set0xa8.insert(p_object);
}
} }
}
if (!m_set0xd0.empty() && p_object->IsA("MxPresenter")) { if (m_set0xd0.size() != 0 && p_object->IsA("MxPresenter")) {
if (((MxPresenter*) p_object)->IsEnabled()) { if (((MxPresenter*) p_object)->IsEnabled()) {
((MxPresenter*) p_object)->Enable(FALSE); ((MxPresenter*) p_object)->Enable(FALSE);
m_set0xd0.insert(p_object); m_set0xd0.insert(p_object);
}
} }
} }
} }
@ -490,61 +509,65 @@ void LegoWorld::Add(MxCore* p_object)
// FUNCTION: BETA10 0x100dad2a // FUNCTION: BETA10 0x100dad2a
void LegoWorld::Remove(MxCore* p_object) void LegoWorld::Remove(MxCore* p_object)
{ {
if (p_object) { MxCoreSet::iterator it;
MxCoreSet::iterator it;
if (p_object->IsA("MxControlPresenter")) { if (p_object == NULL) {
MxPresenterListCursor cursor(&m_controlPresenters); return;
}
if (cursor.Find((MxControlPresenter*) p_object)) { if (p_object->IsA("MxControlPresenter")) {
cursor.Detach(); MxPresenterListCursor cursor(&m_controlPresenters);
((MxControlPresenter*) p_object)->GetAction()->SetOrigin(Lego());
((MxControlPresenter*) p_object)->VTable0x68(TRUE); if (cursor.Find((MxControlPresenter*) p_object)) {
} cursor.Detach();
((MxControlPresenter*) p_object)->GetAction()->SetOrigin(Lego());
((MxControlPresenter*) p_object)->VTable0x68(TRUE);
} }
else if (p_object->IsA("LegoLocomotionAnimPresenter") || p_object->IsA("LegoHideAnimPresenter") || p_object->IsA("LegoLoopingAnimPresenter")) { }
MxPresenterListCursor cursor(&m_animPresenters); else if (p_object->IsA("LegoLocomotionAnimPresenter") || p_object->IsA("LegoHideAnimPresenter") || p_object->IsA("LegoLoopingAnimPresenter")) {
MxPresenterListCursor cursor(&m_animPresenters);
if (cursor.Find((MxPresenter*) p_object)) { if (cursor.Find((MxPresenter*) p_object)) {
cursor.Detach(); cursor.Detach();
}
if (p_object->IsA("LegoHideAnimPresenter")) {
m_hideAnim = NULL;
}
} }
else if (p_object->IsA("MxEntity")) {
if (p_object->IsA("LegoPathActor")) {
RemoveActor((LegoPathActor*) p_object);
}
if (m_entityList) { if (p_object->IsA("LegoHideAnimPresenter")) {
LegoEntityListCursor cursor(m_entityList); m_hideAnim = NULL;
}
if (cursor.Find((LegoEntity*) p_object)) { }
cursor.Detach(); else if (p_object->IsA("MxEntity")) {
} if (p_object->IsA("LegoPathActor")) {
} RemoveActor((LegoPathActor*) p_object);
} }
else if (p_object->IsA("LegoCacheSound")) {
LegoCacheSoundListCursor cursor(m_cacheSoundList);
if (cursor.Find((LegoCacheSound*) p_object)) { if (m_entityList) {
LegoEntityListCursor cursor(m_entityList);
if (cursor.Find((LegoEntity*) p_object)) {
cursor.Detach(); cursor.Detach();
} }
} }
else { }
it = m_set0xa8.find(p_object); #ifndef BETA10
if (it != m_set0xa8.end()) { else if (p_object->IsA("LegoCacheSound")) {
m_set0xa8.erase(it); LegoCacheSoundListCursor cursor(m_cacheSoundList);
}
}
it = m_set0xd0.find(p_object); if (cursor.Find((LegoCacheSound*) p_object)) {
if (it != m_set0xd0.end()) { cursor.Detach();
m_set0xd0.erase(it);
} }
} }
#endif
else {
it = m_set0xa8.find(p_object);
if (it != m_set0xa8.end()) {
m_set0xa8.erase(it);
}
}
it = m_set0xd0.find(p_object);
if (it != m_set0xd0.end()) {
m_set0xd0.erase(it);
}
} }
// FUNCTION: LEGO1 0x100213a0 // FUNCTION: LEGO1 0x100213a0
@ -661,57 +684,66 @@ MxCore* LegoWorld::Find(const MxAtomId& p_atom, MxS32 p_entityId)
// FUNCTION: BETA10 0x100db758 // FUNCTION: BETA10 0x100db758
void LegoWorld::Enable(MxBool p_enable) void LegoWorld::Enable(MxBool p_enable)
{ {
if (p_enable && !m_set0xd0.empty()) { MxCoreSet::iterator it;
if (CurrentWorld() != this) {
if (CurrentWorld()) {
AnimationManager()->FUN_10061010(FALSE);
CurrentWorld()->Enable(FALSE);
LegoEntityListCursor cursor(m_entityList); if (p_enable && m_set0xd0.size() != 0) {
LegoEntity* entity; if (CurrentWorld() == this) {
return;
while (cursor.Next(entity)) {
if (entity->GetROI()) {
entity->GetROI()->SetEntity(entity);
GetViewManager()->Add(entity->GetROI());
}
}
}
while (!m_set0xd0.empty()) {
MxCoreSet::iterator it = m_set0xd0.begin();
if ((*it)->IsA("MxPresenter")) {
((MxPresenter*) *it)->Enable(TRUE);
}
else if ((*it)->IsA("LegoPathController")) {
((LegoPathController*) *it)->Enable(TRUE);
}
m_set0xd0.erase(it);
}
SetCurrentWorld(this);
ControlManager()->FUN_10028df0(&m_controlPresenters);
InputManager()->SetCamera(m_cameraController);
if (m_cameraController) {
InputManager()->Register(m_cameraController->GetNavController());
Lego()->SetNavController(m_cameraController->GetNavController());
}
if (m_worldId != LegoOmni::e_undefined) {
PlantManager()->LoadWorldInfo(m_worldId);
AnimationManager()->LoadWorldInfo(m_worldId);
BuildingManager()->LoadWorldInfo();
AnimationManager()->Resume();
}
GameState()->ResetROI();
SetIsWorldActive(TRUE);
} }
if (CurrentWorld()) {
AnimationManager()->FUN_10061010(FALSE);
CurrentWorld()->Enable(FALSE);
LegoEntityListCursor cursor(m_entityList);
LegoEntity* entity;
while (cursor.Next(entity)) {
assert(entity->GetROI());
if (entity->GetROI()) {
#ifndef BETA10
entity->GetROI()->SetEntity(entity);
#endif
GetViewManager()->Add(entity->GetROI());
}
}
}
while (m_set0xd0.size() != 0) {
it = m_set0xd0.begin();
if ((*it)->IsA("MxPresenter")) {
((MxPresenter*) *it)->Enable(TRUE);
}
else if ((*it)->IsA("LegoPathController")) {
((LegoPathController*) *it)->Enable(TRUE);
}
m_set0xd0.erase(it);
}
SetCurrentWorld(this);
ControlManager()->FUN_10028df0(&m_controlPresenters);
InputManager()->SetCamera(m_cameraController);
if (m_cameraController) {
InputManager()->Register(m_cameraController->GetNavController());
Lego()->SetNavController(m_cameraController->GetNavController());
}
if (m_worldId != LegoOmni::e_undefined) {
PlantManager()->LoadWorldInfo(m_worldId);
AnimationManager()->LoadWorldInfo(m_worldId);
BuildingManager()->LoadWorldInfo();
AnimationManager()->Resume();
}
GameState()->ResetROI();
#ifndef BETA10
SetIsWorldActive(TRUE);
#endif
} }
else if (!p_enable && m_set0xd0.empty()) { else if (!p_enable && m_set0xd0.size() != 0) {
MxPresenter* presenter; MxPresenter* presenter;
LegoPathController* controller; LegoPathController* controller;
LegoPathActor* actor = UserActor(); LegoPathActor* actor = UserActor();
@ -725,7 +757,9 @@ void LegoWorld::Enable(MxBool p_enable)
if (m_worldId != LegoOmni::e_undefined) { if (m_worldId != LegoOmni::e_undefined) {
PlantManager()->Reset(m_worldId); PlantManager()->Reset(m_worldId);
#ifndef BETA10
BuildingManager()->Reset(); BuildingManager()->Reset();
#endif
} }
MxPresenterListCursor controlPresenterCursor(&m_controlPresenters); MxPresenterListCursor controlPresenterCursor(&m_controlPresenters);

View File

@ -3,7 +3,6 @@
#include "anim/legoanim.h" #include "anim/legoanim.h"
#include "legocachesoundmanager.h" #include "legocachesoundmanager.h"
#include "legolocomotionanimpresenter.h" #include "legolocomotionanimpresenter.h"
#include "legopathboundary.h"
#include "legosoundmanager.h" #include "legosoundmanager.h"
#include "legoworld.h" #include "legoworld.h"
#include "misc.h" #include "misc.h"
@ -421,105 +420,3 @@ MxS32 LegoExtraActor::VTable0x68(Vector3& p_point1, Vector3& p_point2, Vector3&
{ {
return LegoPathActor::VTable0x68(p_point1, p_point2, p_point3); return LegoPathActor::VTable0x68(p_point1, p_point2, p_point3);
} }
// FUNCTION: LEGO1 0x1002b980
MxU32 LegoExtraActor::VTable0x6c(
LegoPathBoundary* p_boundary,
Vector3& p_v1,
Vector3& p_v2,
float p_f1,
float p_f2,
Vector3& p_v3
)
{
LegoAnimPresenterSet& presenters = p_boundary->GetPresenters();
for (LegoAnimPresenterSet::iterator itap = presenters.begin(); itap != presenters.end(); itap++) {
if ((*itap)->VTable0x94(p_v1, p_v2, p_f1, p_f2, p_v3)) {
return 1;
}
}
LegoPathActorSet& plpas = p_boundary->GetActors();
LegoPathActorSet lpas(plpas);
for (LegoPathActorSet::iterator itpa = lpas.begin(); itpa != lpas.end(); itpa++) {
if (plpas.find(*itpa) != plpas.end()) {
LegoPathActor* actor = *itpa;
if (this != actor && !(actor->GetActorState() & LegoPathActor::c_noCollide)) {
LegoROI* roi = actor->GetROI();
if ((roi != NULL && roi->GetVisibility()) || actor->GetCameraFlag()) {
if (actor->GetUserNavFlag()) {
MxMatrix local2world = roi->GetLocal2World();
Vector3 local60(local2world[3]);
Mx3DPointFloat local54(p_v1);
local54 -= local60;
float local1c = p_v2.Dot(p_v2, p_v2);
float local24 = p_v2.Dot(p_v2, local54) * 2.0f;
float local20 = local54.Dot(local54, local54);
if (m_unk0x15 != 0 && local20 < 10.0f) {
return 0;
}
local20 -= 1.0f;
if (local1c >= 0.001 || local1c <= -0.001) {
float local40 = (local24 * local24) + (local20 * local1c * -4.0f);
if (local40 >= -0.001) {
local1c *= 2.0f;
local24 = -local24;
if (local40 < 0.0f) {
local40 = 0.0f;
}
local40 = sqrt(local40);
float local20X = (local24 + local40) / local1c;
float local1cX = (local24 - local40) / local1c;
if (local1cX < local20X) {
local40 = local20X;
local20X = local1cX;
local1cX = local40;
}
if ((local20X >= 0.0f && local20X <= p_f1) || (local1cX >= 0.0f && local1cX <= p_f1) ||
(local20X <= -0.01 && p_f1 + 0.01 <= local1cX)) {
p_v3 = p_v1;
if (HitActor(actor, TRUE) < 0) {
return 0;
}
actor->HitActor(this, FALSE);
return 2;
}
}
}
}
else {
if (roi->FUN_100a9410(p_v1, p_v2, p_f1, p_f2, p_v3, m_collideBox && actor->GetCollideBox())) {
if (HitActor(actor, TRUE) < 0) {
return 0;
}
actor->HitActor(this, FALSE);
return 2;
}
}
}
}
}
}
if (m_unk0x15 != 0) {
m_unk0x15--;
}
return 0;
}

View File

@ -520,11 +520,12 @@ MxResult LegoRaceCar::HitActor(LegoPathActor* p_actor, MxBool p_bool)
} }
} }
if (p_bool && m_worldSpeed != 0) { if (p_bool) {
return SUCCESS; return m_worldSpeed != 0 ? SUCCESS : FAILURE;
}
else {
return FAILURE;
} }
return FAILURE;
} }
} }
@ -720,11 +721,12 @@ MxResult LegoJetski::HitActor(LegoPathActor* p_actor, MxBool p_bool)
} }
} }
if (p_bool && m_worldSpeed != 0) { if (p_bool) {
return SUCCESS; return m_worldSpeed != 0 ? SUCCESS : FAILURE;
}
else {
return FAILURE;
} }
return FAILURE;
} }
} }

View File

@ -12,13 +12,14 @@ public:
SetDestroy(Destroy); SetDestroy(Destroy);
} }
virtual MxS8 Compare(T, T) { return 0; } // vtable+0x14
~MxCollection() override {}
static void Destroy(T) {} static void Destroy(T) {}
void SetDestroy(void (*p_customDestructor)(T)) { this->m_customDestructor = p_customDestructor; } void SetDestroy(void (*p_customDestructor)(T)) { this->m_customDestructor = p_customDestructor; }
~MxCollection() override {}
virtual MxS8 Compare(T, T) { return 0; }
protected: protected:
MxU32 m_count; // 0x08 MxU32 m_count; // 0x08
void (*m_customDestructor)(T); // 0x0c void (*m_customDestructor)(T); // 0x0c

View File

@ -46,8 +46,7 @@ template <class T>
class MxList : protected MxCollection<T> { class MxList : protected MxCollection<T> {
public: public:
MxList() { m_first = m_last = NULL; } MxList() { m_first = m_last = NULL; }
~MxList() override { DeleteAll(); }
~MxList() override;
void Append(T p_obj) { InsertEntry(p_obj, this->m_last, NULL); } void Append(T p_obj) { InsertEntry(p_obj, this->m_last, NULL); }
void Prepend(T p_obj) { InsertEntry(p_obj, NULL, this->m_first); } void Prepend(T p_obj) { InsertEntry(p_obj, NULL, this->m_first); }
@ -127,12 +126,6 @@ public:
MxPtrListCursor(MxPtrList<T>* p_list) : MxListCursor<T*>(p_list) {} MxPtrListCursor(MxPtrList<T>* p_list) : MxListCursor<T*>(p_list) {}
}; };
template <class T>
MxList<T>::~MxList()
{
DeleteAll();
}
// Delete entries and values // Delete entries and values
template <class T> template <class T>
inline void MxList<T>::DeleteAll() inline void MxList<T>::DeleteAll()

View File

@ -52,4 +52,8 @@ public:
const float* operator[](int idx) const { return m_data[idx]; } const float* operator[](int idx) const { return m_data[idx]; }
}; };
#ifdef COMPAT_MODE
#include "matrix4d.inl.h"
#endif
#endif // MATRIX_H #endif // MATRIX_H

View File

@ -148,4 +148,10 @@ public:
friend class Mx4DPointFloat; friend class Mx4DPointFloat;
}; };
#ifdef COMPAT_MODE
#include "vector2d.inl.h"
#include "vector3d.inl.h"
#include "vector4d.inl.h"
#endif
#endif // VECTOR_H #endif // VECTOR_H

View File

@ -3,6 +3,9 @@
#include "vector.h" #include "vector.h"
#include <math.h>
#include <memory.h>
// FUNCTION: LEGO1 0x10002870 // FUNCTION: LEGO1 0x10002870
void Vector4::AddImpl(const float* p_value) void Vector4::AddImpl(const float* p_value)
{ {