From a0629c45a1b7632e3068b8d9f8aaad592ca4cee6 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Sun, 1 Mar 2026 10:04:13 -0800 Subject: [PATCH] Minimize LEGO1 changes: revert globals, move CreateCharacterClone to extension Revert plant/building manager globals back to private class statics (matching master) and use friend declarations for extension access. Move CreateCharacterClone out of LegoCharacterManager into a new CharacterCloner class in the multiplayer extension. --- CMakeLists.txt | 1 + .../legoomni/include/legobuildingmanager.h | 8 + .../legoomni/include/legocharactermanager.h | 7 +- .../lego/legoomni/include/legoplantmanager.h | 8 + .../src/common/legobuildingmanager.cpp | 8 +- .../src/common/legocharactermanager.cpp | 143 ---------------- .../legoomni/src/common/legoplantmanager.cpp | 12 +- .../extensions/multiplayer/charactercloner.h | 17 ++ .../src/multiplayer/charactercloner.cpp | 156 ++++++++++++++++++ extensions/src/multiplayer/networkmanager.cpp | 17 +- extensions/src/multiplayer/remoteplayer.cpp | 3 +- 11 files changed, 214 insertions(+), 166 deletions(-) create mode 100644 extensions/include/extensions/multiplayer/charactercloner.h create mode 100644 extensions/src/multiplayer/charactercloner.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 2ffd501b..6ccfe122 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -532,6 +532,7 @@ if (ISLE_EXTENSIONS) extensions/src/siloader.cpp extensions/src/textureloader.cpp extensions/src/multiplayer.cpp + extensions/src/multiplayer/charactercloner.cpp extensions/src/multiplayer/networkmanager.cpp extensions/src/multiplayer/remoteplayer.cpp extensions/src/multiplayer/websockettransport.cpp diff --git a/LEGO1/lego/legoomni/include/legobuildingmanager.h b/LEGO1/lego/legoomni/include/legobuildingmanager.h index 6e5908f3..6b65ff9a 100644 --- a/LEGO1/lego/legoomni/include/legobuildingmanager.h +++ b/LEGO1/lego/legoomni/include/legobuildingmanager.h @@ -12,6 +12,10 @@ class LegoStorage; class LegoWorld; class LegoCacheSound; class LegoPathBoundary; +namespace Multiplayer +{ +class NetworkManager; +} // SIZE 0x2c struct LegoBuildingInfo { @@ -98,7 +102,11 @@ class LegoBuildingManager : public MxCore { // LegoBuildingManager::`scalar deleting destructor' private: + friend class Multiplayer::NetworkManager; + static char* g_customizeAnimFile; + static MxS32 g_maxMove[16]; + static MxU32 g_maxSound; MxU8 m_nextVariant; // 0x08 MxBool m_boundariesDetermined; // 0x09 diff --git a/LEGO1/lego/legoomni/include/legocharactermanager.h b/LEGO1/lego/legoomni/include/legocharactermanager.h index 04aba71b..174a7747 100644 --- a/LEGO1/lego/legoomni/include/legocharactermanager.h +++ b/LEGO1/lego/legoomni/include/legocharactermanager.h @@ -13,6 +13,10 @@ class LegoActor; class LegoExtraActor; class LegoStorage; class LegoROI; +namespace Multiplayer +{ +class CharacterCloner; +} #pragma warning(disable : 4237) @@ -92,13 +96,14 @@ class LegoCharacterManager { MxU32 GetSoundId(LegoROI* p_roi, MxBool p_basedOnMood); MxU8 GetMood(LegoROI* p_roi); LegoROI* CreateAutoROI(const char* p_name, const char* p_lodName, MxBool p_createEntity); - LegoROI* CreateCharacterClone(const char* p_uniqueName, const char* p_characterType); MxResult UpdateBoundingSphereAndBox(LegoROI* p_roi); LegoROI* FUN_10085a80(const char* p_name, const char* p_lodName, MxBool p_createEntity); static const char* GetCustomizeAnimFile() { return g_customizeAnimFile; } private: + friend class Multiplayer::CharacterCloner; + LegoROI* CreateActorROI(const char* p_key); void RemoveROI(LegoROI* p_roi); LegoROI* FindChildROI(LegoROI* p_roi, const char* p_name); diff --git a/LEGO1/lego/legoomni/include/legoplantmanager.h b/LEGO1/lego/legoomni/include/legoplantmanager.h index b2ca536f..95d616ce 100644 --- a/LEGO1/lego/legoomni/include/legoplantmanager.h +++ b/LEGO1/lego/legoomni/include/legoplantmanager.h @@ -11,6 +11,10 @@ struct LegoPlantInfo; class LegoROI; class LegoStorage; class LegoWorld; +namespace Multiplayer +{ +class NetworkManager; +} // VTABLE: LEGO1 0x100d6758 // SIZE 0x2c @@ -67,6 +71,8 @@ class LegoPlantManager : public MxCore { // LegoPlantManager::`scalar deleting destructor' private: + friend class Multiplayer::NetworkManager; + void RemovePlant(MxS32 p_index, LegoOmni::World p_worldId); void AdjustHeight(MxS32 p_index); LegoPlantInfo* GetInfo(LegoEntity* p_entity); @@ -74,6 +80,8 @@ class LegoPlantManager : public MxCore { void AdjustCounter(LegoEntity* p_entity, MxS32 p_adjust); static char* g_customizeAnimFile; + static MxS32 g_maxMove[4]; + static MxU32 g_maxSound; LegoOmni::World m_worldId; // 0x08 MxBool m_boundariesDetermined; // 0x0c diff --git a/LEGO1/lego/legoomni/src/common/legobuildingmanager.cpp b/LEGO1/lego/legoomni/src/common/legobuildingmanager.cpp index eebf9fb5..f82747bf 100644 --- a/LEGO1/lego/legoomni/src/common/legobuildingmanager.cpp +++ b/LEGO1/lego/legoomni/src/common/legobuildingmanager.cpp @@ -197,7 +197,7 @@ LegoBuildingInfo g_buildingInfoInit[16] = { // clang-format on // GLOBAL: LEGO1 0x100f3738 -MxU32 g_buildingMaxSound = 6; +MxU32 LegoBuildingManager::g_maxSound = 6; // GLOBAL: LEGO1 0x100f373c MxU32 g_buildingSoundIdOffset = 0x3c; @@ -226,7 +226,7 @@ MxS32 g_buildingManagerConfig = 1; LegoBuildingInfo g_buildingInfo[16]; // GLOBAL: LEGO1 0x100f3748 -MxS32 g_buildingMaxMove[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 0}; +MxS32 LegoBuildingManager::g_maxMove[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 3, 3, 3, 0}; #define HAUS1_INDEX 12 @@ -493,7 +493,7 @@ MxBool LegoBuildingManager::SwitchSound(LegoEntity* p_entity) if (info != NULL && info->m_flags & LegoBuildingInfo::c_hasSounds) { info->m_sound++; - if (info->m_sound >= g_buildingMaxSound) { + if (info->m_sound >= g_maxSound) { info->m_sound = 0; } @@ -513,7 +513,7 @@ MxBool LegoBuildingManager::SwitchMove(LegoEntity* p_entity) if (info != NULL && info->m_flags & LegoBuildingInfo::c_hasMoves) { info->m_move++; - if (info->m_move >= g_buildingMaxMove[info - g_buildingInfo]) { + if (info->m_move >= g_maxMove[info - g_buildingInfo]) { info->m_move = 0; } diff --git a/LEGO1/lego/legoomni/src/common/legocharactermanager.cpp b/LEGO1/lego/legoomni/src/common/legocharactermanager.cpp index e4bed0f1..180b8eec 100644 --- a/LEGO1/lego/legoomni/src/common/legocharactermanager.cpp +++ b/LEGO1/lego/legoomni/src/common/legocharactermanager.cpp @@ -1110,146 +1110,3 @@ void CustomizeAnimFileVariable::SetValue(const char* p_value) BuildingManager()->SetCustomizeAnimFile(p_value); } } - -// Creates an independent multi-part character ROI clone for multiplayer. -// Same construction logic as CreateActorROI but with a unique name and -// no side effects on g_actorInfo[].m_roi. -LegoROI* LegoCharacterManager::CreateCharacterClone(const char* p_uniqueName, const char* p_characterType) -{ - MxBool success = FALSE; - LegoROI* roi = NULL; - BoundingSphere boundingSphere; - BoundingBox boundingBox; - MxMatrix mat; - CompoundObject* comp; - MxS32 i; - - Tgl::Renderer* renderer = VideoManager()->GetRenderer(); - ViewLODListManager* lodManager = GetViewLODListManager(); - LegoTextureContainer* textureContainer = TextureContainer(); - LegoActorInfo* info = GetActorInfo(p_characterType); - - if (info == NULL) { - goto done; - } - - roi = new LegoROI(renderer); - roi->SetName(p_uniqueName); - - boundingSphere.Center()[0] = g_actorLODs[c_topLOD].m_boundingSphere[0]; - boundingSphere.Center()[1] = g_actorLODs[c_topLOD].m_boundingSphere[1]; - boundingSphere.Center()[2] = g_actorLODs[c_topLOD].m_boundingSphere[2]; - boundingSphere.Radius() = g_actorLODs[c_topLOD].m_boundingSphere[3]; - roi->SetBoundingSphere(boundingSphere); - - boundingBox.Min()[0] = g_actorLODs[c_topLOD].m_boundingBox[0]; - boundingBox.Min()[1] = g_actorLODs[c_topLOD].m_boundingBox[1]; - boundingBox.Min()[2] = g_actorLODs[c_topLOD].m_boundingBox[2]; - boundingBox.Max()[0] = g_actorLODs[c_topLOD].m_boundingBox[3]; - boundingBox.Max()[1] = g_actorLODs[c_topLOD].m_boundingBox[4]; - boundingBox.Max()[2] = g_actorLODs[c_topLOD].m_boundingBox[5]; - roi->SetBoundingBox(boundingBox); - - comp = new CompoundObject(); - roi->SetComp(comp); - - for (i = 0; i < sizeOfArray(g_actorLODs) - 1; i++) { - char lodName[256]; - LegoActorInfo::Part& part = info->m_parts[i]; - - const char* parentName; - if (i == 0 || i == 1) { - parentName = part.m_partName[part.m_partNameIndices[part.m_partNameIndex]]; - } - else { - parentName = g_actorLODs[i + 1].m_parentName; - } - - ViewLODList* lodList = lodManager->Lookup(parentName); - MxS32 lodSize = lodList->Size(); - sprintf(lodName, "%s%d", p_uniqueName, i); - ViewLODList* dupLodList = lodManager->Create(lodName, lodSize); - - for (MxS32 j = 0; j < lodSize; j++) { - LegoLOD* lod = (LegoLOD*) (*lodList)[j]; - LegoLOD* clone = lod->Clone(renderer); - dupLodList->PushBack(clone); - } - - lodList->Release(); - lodList = dupLodList; - - LegoROI* childROI = new LegoROI(renderer, lodList); - lodList->Release(); - - childROI->SetName(g_actorLODs[i + 1].m_name); - childROI->SetParentROI(roi); - - BoundingSphere childBoundingSphere; - childBoundingSphere.Center()[0] = g_actorLODs[i + 1].m_boundingSphere[0]; - childBoundingSphere.Center()[1] = g_actorLODs[i + 1].m_boundingSphere[1]; - childBoundingSphere.Center()[2] = g_actorLODs[i + 1].m_boundingSphere[2]; - childBoundingSphere.Radius() = g_actorLODs[i + 1].m_boundingSphere[3]; - childROI->SetBoundingSphere(childBoundingSphere); - - BoundingBox childBoundingBox; - childBoundingBox.Min()[0] = g_actorLODs[i + 1].m_boundingBox[0]; - childBoundingBox.Min()[1] = g_actorLODs[i + 1].m_boundingBox[1]; - childBoundingBox.Min()[2] = g_actorLODs[i + 1].m_boundingBox[2]; - childBoundingBox.Max()[0] = g_actorLODs[i + 1].m_boundingBox[3]; - childBoundingBox.Max()[1] = g_actorLODs[i + 1].m_boundingBox[4]; - childBoundingBox.Max()[2] = g_actorLODs[i + 1].m_boundingBox[5]; - childROI->SetBoundingBox(childBoundingBox); - - CalcLocalTransform( - Mx3DPointFloat(g_actorLODs[i + 1].m_position), - Mx3DPointFloat(g_actorLODs[i + 1].m_direction), - Mx3DPointFloat(g_actorLODs[i + 1].m_up), - mat - ); - childROI->WrappedSetLocal2WorldWithWorldDataUpdate(mat); - - if (g_actorLODs[i + 1].m_flags & LegoActorLOD::c_useTexture && - (i != 0 || part.m_partNameIndices[part.m_partNameIndex] != 0)) { - - LegoTextureInfo* textureInfo = textureContainer->Get(part.m_names[part.m_nameIndices[part.m_nameIndex]]); - - if (textureInfo != NULL) { - childROI->SetTextureInfo(textureInfo); - childROI->SetLodColor(1.0F, 1.0F, 1.0F, 0.0F); - } - } - else if (g_actorLODs[i + 1].m_flags & LegoActorLOD::c_useColor || (i == 0 && part.m_partNameIndices[part.m_partNameIndex] == 0)) { - LegoFloat red, green, blue, alpha; - childROI->GetRGBAColor(part.m_names[part.m_nameIndices[part.m_nameIndex]], red, green, blue, alpha); - childROI->SetLodColor(red, green, blue, alpha); - } - - comp->push_back(childROI); - } - - CalcLocalTransform( - Mx3DPointFloat(g_actorLODs[c_topLOD].m_position), - Mx3DPointFloat(g_actorLODs[c_topLOD].m_direction), - Mx3DPointFloat(g_actorLODs[c_topLOD].m_up), - mat - ); - roi->WrappedSetLocal2WorldWithWorldDataUpdate(mat); - - { - LegoCharacter* character = new LegoCharacter(roi); - char* name = new char[SDL_strlen(p_uniqueName) + 1]; - SDL_strlcpy(name, p_uniqueName, SDL_strlen(p_uniqueName) + 1); - (*m_characters)[name] = character; - } - - success = TRUE; - -done: - if (!success && roi != NULL) { - delete roi; - roi = NULL; - } - - return roi; -} diff --git a/LEGO1/lego/legoomni/src/common/legoplantmanager.cpp b/LEGO1/lego/legoomni/src/common/legoplantmanager.cpp index c08722b1..206d03ff 100644 --- a/LEGO1/lego/legoomni/src/common/legoplantmanager.cpp +++ b/LEGO1/lego/legoomni/src/common/legoplantmanager.cpp @@ -37,7 +37,7 @@ float g_heightPerCount[] = {0.1f, 0.7f, 0.5f, 0.9f}; MxU8 g_counters[] = {1, 2, 2, 3}; // GLOBAL: LEGO1 0x100f315c -MxU32 g_plantMaxSound = 8; +MxU32 LegoPlantManager::g_maxSound = 8; // GLOBAL: LEGO1 0x100f3160 MxU32 g_plantSoundIdOffset = 56; @@ -46,7 +46,7 @@ MxU32 g_plantSoundIdOffset = 56; MxU32 g_plantSoundIdMoodOffset = 66; // GLOBAL: LEGO1 0x100f3168 -MxS32 g_plantMaxMove[4] = {3, 3, 3, 3}; +MxS32 LegoPlantManager::g_maxMove[4] = {3, 3, 3, 3}; // GLOBAL: LEGO1 0x100f3178 MxU32 g_plantAnimationId[4] = {30, 33, 36, 39}; @@ -433,8 +433,8 @@ MxBool LegoPlantManager::SwitchVariant(LegoEntity* p_entity) lodList->Release(); CharacterManager()->UpdateBoundingSphereAndBox(roi); - if (info->m_move != 0 && info->m_move >= g_plantMaxMove[info->m_variant]) { - info->m_move = g_plantMaxMove[info->m_variant] - 1; + if (info->m_move != 0 && info->m_move >= g_maxMove[info->m_variant]) { + info->m_move = g_maxMove[info->m_variant] - 1; } return TRUE; @@ -450,7 +450,7 @@ MxBool LegoPlantManager::SwitchSound(LegoEntity* p_entity) if (info != NULL) { info->m_sound++; - if (info->m_sound >= g_plantMaxSound) { + if (info->m_sound >= g_maxSound) { info->m_sound = 0; } @@ -470,7 +470,7 @@ MxBool LegoPlantManager::SwitchMove(LegoEntity* p_entity) if (info != NULL) { info->m_move++; - if (info->m_move >= g_plantMaxMove[info->m_variant]) { + if (info->m_move >= g_maxMove[info->m_variant]) { info->m_move = 0; } diff --git a/extensions/include/extensions/multiplayer/charactercloner.h b/extensions/include/extensions/multiplayer/charactercloner.h new file mode 100644 index 00000000..61dc8076 --- /dev/null +++ b/extensions/include/extensions/multiplayer/charactercloner.h @@ -0,0 +1,17 @@ +#pragma once + +class LegoCharacterManager; +class LegoROI; + +namespace Multiplayer +{ + +class CharacterCloner { +public: + // Creates an independent multi-part character ROI clone. + // Same construction logic as CreateActorROI but with a unique name and + // no side effects on g_actorInfo[].m_roi. + static LegoROI* Clone(LegoCharacterManager* p_charMgr, const char* p_uniqueName, const char* p_characterType); +}; + +} // namespace Multiplayer diff --git a/extensions/src/multiplayer/charactercloner.cpp b/extensions/src/multiplayer/charactercloner.cpp new file mode 100644 index 00000000..1ebd59a1 --- /dev/null +++ b/extensions/src/multiplayer/charactercloner.cpp @@ -0,0 +1,156 @@ +#include "extensions/multiplayer/charactercloner.h" + +#include "legoactors.h" +#include "legocharactermanager.h" +#include "legovideomanager.h" +#include "misc.h" +#include "misc/legocontainer.h" +#include "realtime/realtime.h" +#include "roi/legolod.h" +#include "roi/legoroi.h" +#include "viewmanager/viewlodlist.h" + +#include +#include + +using namespace Multiplayer; + +LegoROI* CharacterCloner::Clone(LegoCharacterManager* p_charMgr, const char* p_uniqueName, const char* p_characterType) +{ + MxBool success = FALSE; + LegoROI* roi = NULL; + BoundingSphere boundingSphere; + BoundingBox boundingBox; + MxMatrix mat; + CompoundObject* comp; + MxS32 i; + + Tgl::Renderer* renderer = VideoManager()->GetRenderer(); + ViewLODListManager* lodManager = GetViewLODListManager(); + LegoTextureContainer* textureContainer = TextureContainer(); + LegoActorInfo* info = p_charMgr->GetActorInfo(p_characterType); + + if (info == NULL) { + goto done; + } + + roi = new LegoROI(renderer); + roi->SetName(p_uniqueName); + + boundingSphere.Center()[0] = g_actorLODs[c_topLOD].m_boundingSphere[0]; + boundingSphere.Center()[1] = g_actorLODs[c_topLOD].m_boundingSphere[1]; + boundingSphere.Center()[2] = g_actorLODs[c_topLOD].m_boundingSphere[2]; + boundingSphere.Radius() = g_actorLODs[c_topLOD].m_boundingSphere[3]; + roi->SetBoundingSphere(boundingSphere); + + boundingBox.Min()[0] = g_actorLODs[c_topLOD].m_boundingBox[0]; + boundingBox.Min()[1] = g_actorLODs[c_topLOD].m_boundingBox[1]; + boundingBox.Min()[2] = g_actorLODs[c_topLOD].m_boundingBox[2]; + boundingBox.Max()[0] = g_actorLODs[c_topLOD].m_boundingBox[3]; + boundingBox.Max()[1] = g_actorLODs[c_topLOD].m_boundingBox[4]; + boundingBox.Max()[2] = g_actorLODs[c_topLOD].m_boundingBox[5]; + roi->SetBoundingBox(boundingBox); + + comp = new CompoundObject(); + roi->SetComp(comp); + + for (i = 0; i < sizeOfArray(g_actorLODs) - 1; i++) { + char lodName[256]; + LegoActorInfo::Part& part = info->m_parts[i]; + + const char* parentName; + if (i == 0 || i == 1) { + parentName = part.m_partName[part.m_partNameIndices[part.m_partNameIndex]]; + } + else { + parentName = g_actorLODs[i + 1].m_parentName; + } + + ViewLODList* lodList = lodManager->Lookup(parentName); + MxS32 lodSize = lodList->Size(); + sprintf(lodName, "%s%d", p_uniqueName, i); + ViewLODList* dupLodList = lodManager->Create(lodName, lodSize); + + for (MxS32 j = 0; j < lodSize; j++) { + LegoLOD* lod = (LegoLOD*) (*lodList)[j]; + LegoLOD* clone = lod->Clone(renderer); + dupLodList->PushBack(clone); + } + + lodList->Release(); + lodList = dupLodList; + + LegoROI* childROI = new LegoROI(renderer, lodList); + lodList->Release(); + + childROI->SetName(g_actorLODs[i + 1].m_name); + childROI->SetParentROI(roi); + + BoundingSphere childBoundingSphere; + childBoundingSphere.Center()[0] = g_actorLODs[i + 1].m_boundingSphere[0]; + childBoundingSphere.Center()[1] = g_actorLODs[i + 1].m_boundingSphere[1]; + childBoundingSphere.Center()[2] = g_actorLODs[i + 1].m_boundingSphere[2]; + childBoundingSphere.Radius() = g_actorLODs[i + 1].m_boundingSphere[3]; + childROI->SetBoundingSphere(childBoundingSphere); + + BoundingBox childBoundingBox; + childBoundingBox.Min()[0] = g_actorLODs[i + 1].m_boundingBox[0]; + childBoundingBox.Min()[1] = g_actorLODs[i + 1].m_boundingBox[1]; + childBoundingBox.Min()[2] = g_actorLODs[i + 1].m_boundingBox[2]; + childBoundingBox.Max()[0] = g_actorLODs[i + 1].m_boundingBox[3]; + childBoundingBox.Max()[1] = g_actorLODs[i + 1].m_boundingBox[4]; + childBoundingBox.Max()[2] = g_actorLODs[i + 1].m_boundingBox[5]; + childROI->SetBoundingBox(childBoundingBox); + + CalcLocalTransform( + Mx3DPointFloat(g_actorLODs[i + 1].m_position), + Mx3DPointFloat(g_actorLODs[i + 1].m_direction), + Mx3DPointFloat(g_actorLODs[i + 1].m_up), + mat + ); + childROI->WrappedSetLocal2WorldWithWorldDataUpdate(mat); + + if (g_actorLODs[i + 1].m_flags & LegoActorLOD::c_useTexture && + (i != 0 || part.m_partNameIndices[part.m_partNameIndex] != 0)) { + + LegoTextureInfo* textureInfo = textureContainer->Get(part.m_names[part.m_nameIndices[part.m_nameIndex]]); + + if (textureInfo != NULL) { + childROI->SetTextureInfo(textureInfo); + childROI->SetLodColor(1.0F, 1.0F, 1.0F, 0.0F); + } + } + else if (g_actorLODs[i + 1].m_flags & LegoActorLOD::c_useColor || (i == 0 && part.m_partNameIndices[part.m_partNameIndex] == 0)) { + LegoFloat red, green, blue, alpha; + childROI->GetRGBAColor(part.m_names[part.m_nameIndices[part.m_nameIndex]], red, green, blue, alpha); + childROI->SetLodColor(red, green, blue, alpha); + } + + comp->push_back(childROI); + } + + CalcLocalTransform( + Mx3DPointFloat(g_actorLODs[c_topLOD].m_position), + Mx3DPointFloat(g_actorLODs[c_topLOD].m_direction), + Mx3DPointFloat(g_actorLODs[c_topLOD].m_up), + mat + ); + roi->WrappedSetLocal2WorldWithWorldDataUpdate(mat); + + { + LegoCharacter* character = new LegoCharacter(roi); + char* name = new char[SDL_strlen(p_uniqueName) + 1]; + SDL_strlcpy(name, p_uniqueName, SDL_strlen(p_uniqueName) + 1); + (*p_charMgr->m_characters)[name] = character; + } + + success = TRUE; + +done: + if (!success && roi != NULL) { + delete roi; + roi = NULL; + } + + return roi; +} diff --git a/extensions/src/multiplayer/networkmanager.cpp b/extensions/src/multiplayer/networkmanager.cpp index 31b5f4d0..0270510a 100644 --- a/extensions/src/multiplayer/networkmanager.cpp +++ b/extensions/src/multiplayer/networkmanager.cpp @@ -18,11 +18,7 @@ #include extern MxU8 g_counters[]; -extern MxS32 g_plantMaxMove[]; -extern MxU32 g_plantMaxSound; extern MxU8 g_buildingInfoDownshift[]; -extern MxS32 g_buildingMaxMove[]; -extern MxU32 g_buildingMaxSound; using namespace Multiplayer; @@ -676,20 +672,20 @@ void NetworkManager::ApplyWorldEvent(uint8_t p_entityType, uint8_t p_changeType, } // Clamp move to the new variant's max (mirrors SwitchVariant) - if (info->m_move != 0 && info->m_move >= (MxU32) g_plantMaxMove[info->m_variant]) { - info->m_move = g_plantMaxMove[info->m_variant] - 1; + if (info->m_move != 0 && info->m_move >= (MxU32) LegoPlantManager::g_maxMove[info->m_variant]) { + info->m_move = LegoPlantManager::g_maxMove[info->m_variant] - 1; } } break; case CHANGE_SOUND: info->m_sound++; - if (info->m_sound >= g_plantMaxSound) { + if (info->m_sound >= LegoPlantManager::g_maxSound) { info->m_sound = 0; } break; case CHANGE_MOVE: info->m_move++; - if (info->m_move >= (MxU32) g_plantMaxMove[info->m_variant]) { + if (info->m_move >= (MxU32) LegoPlantManager::g_maxMove[info->m_variant]) { info->m_move = 0; } break; @@ -747,7 +743,7 @@ void NetworkManager::ApplyWorldEvent(uint8_t p_entityType, uint8_t p_changeType, case CHANGE_SOUND: if (info->m_flags & LegoBuildingInfo::c_hasSounds) { info->m_sound++; - if (info->m_sound >= g_buildingMaxSound) { + if (info->m_sound >= LegoBuildingManager::g_maxSound) { info->m_sound = 0; } } @@ -755,7 +751,7 @@ void NetworkManager::ApplyWorldEvent(uint8_t p_entityType, uint8_t p_changeType, case CHANGE_MOVE: if (info->m_flags & LegoBuildingInfo::c_hasMoves) { info->m_move++; - if (info->m_move >= (MxU32) g_buildingMaxMove[p_entityIndex]) { + if (info->m_move >= (MxU32) LegoBuildingManager::g_maxMove[p_entityIndex]) { info->m_move = 0; } } @@ -788,4 +784,3 @@ void NetworkManager::ApplyWorldEvent(uint8_t p_entityType, uint8_t p_changeType, } } } - diff --git a/extensions/src/multiplayer/remoteplayer.cpp b/extensions/src/multiplayer/remoteplayer.cpp index bca58315..4d22f636 100644 --- a/extensions/src/multiplayer/remoteplayer.cpp +++ b/extensions/src/multiplayer/remoteplayer.cpp @@ -2,6 +2,7 @@ #include "3dmanager/lego3dmanager.h" #include "anim/legoanim.h" +#include "extensions/multiplayer/charactercloner.h" #include "legoactor.h" #include "legoanimpresenter.h" #include "legocharactermanager.h" @@ -79,7 +80,7 @@ void RemotePlayer::Spawn(LegoWorld* p_isleWorld) return; } - m_roi = charMgr->CreateCharacterClone(m_uniqueName, actorName); + m_roi = CharacterCloner::Clone(charMgr, m_uniqueName, actorName); if (!m_roi) { return; }