mirror of
https://github.com/isledecomp/isle-portable.git
synced 2026-05-02 10:33:57 +00:00
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.
This commit is contained in:
parent
12a63c105c
commit
a0629c45a1
@ -532,6 +532,7 @@ if (ISLE_EXTENSIONS)
|
|||||||
extensions/src/siloader.cpp
|
extensions/src/siloader.cpp
|
||||||
extensions/src/textureloader.cpp
|
extensions/src/textureloader.cpp
|
||||||
extensions/src/multiplayer.cpp
|
extensions/src/multiplayer.cpp
|
||||||
|
extensions/src/multiplayer/charactercloner.cpp
|
||||||
extensions/src/multiplayer/networkmanager.cpp
|
extensions/src/multiplayer/networkmanager.cpp
|
||||||
extensions/src/multiplayer/remoteplayer.cpp
|
extensions/src/multiplayer/remoteplayer.cpp
|
||||||
extensions/src/multiplayer/websockettransport.cpp
|
extensions/src/multiplayer/websockettransport.cpp
|
||||||
|
|||||||
@ -12,6 +12,10 @@ class LegoStorage;
|
|||||||
class LegoWorld;
|
class LegoWorld;
|
||||||
class LegoCacheSound;
|
class LegoCacheSound;
|
||||||
class LegoPathBoundary;
|
class LegoPathBoundary;
|
||||||
|
namespace Multiplayer
|
||||||
|
{
|
||||||
|
class NetworkManager;
|
||||||
|
}
|
||||||
|
|
||||||
// SIZE 0x2c
|
// SIZE 0x2c
|
||||||
struct LegoBuildingInfo {
|
struct LegoBuildingInfo {
|
||||||
@ -98,7 +102,11 @@ class LegoBuildingManager : public MxCore {
|
|||||||
// LegoBuildingManager::`scalar deleting destructor'
|
// LegoBuildingManager::`scalar deleting destructor'
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
friend class Multiplayer::NetworkManager;
|
||||||
|
|
||||||
static char* g_customizeAnimFile;
|
static char* g_customizeAnimFile;
|
||||||
|
static MxS32 g_maxMove[16];
|
||||||
|
static MxU32 g_maxSound;
|
||||||
|
|
||||||
MxU8 m_nextVariant; // 0x08
|
MxU8 m_nextVariant; // 0x08
|
||||||
MxBool m_boundariesDetermined; // 0x09
|
MxBool m_boundariesDetermined; // 0x09
|
||||||
|
|||||||
@ -13,6 +13,10 @@ class LegoActor;
|
|||||||
class LegoExtraActor;
|
class LegoExtraActor;
|
||||||
class LegoStorage;
|
class LegoStorage;
|
||||||
class LegoROI;
|
class LegoROI;
|
||||||
|
namespace Multiplayer
|
||||||
|
{
|
||||||
|
class CharacterCloner;
|
||||||
|
}
|
||||||
|
|
||||||
#pragma warning(disable : 4237)
|
#pragma warning(disable : 4237)
|
||||||
|
|
||||||
@ -92,13 +96,14 @@ class LegoCharacterManager {
|
|||||||
MxU32 GetSoundId(LegoROI* p_roi, MxBool p_basedOnMood);
|
MxU32 GetSoundId(LegoROI* p_roi, MxBool p_basedOnMood);
|
||||||
MxU8 GetMood(LegoROI* p_roi);
|
MxU8 GetMood(LegoROI* p_roi);
|
||||||
LegoROI* CreateAutoROI(const char* p_name, const char* p_lodName, MxBool p_createEntity);
|
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);
|
MxResult UpdateBoundingSphereAndBox(LegoROI* p_roi);
|
||||||
LegoROI* FUN_10085a80(const char* p_name, const char* p_lodName, MxBool p_createEntity);
|
LegoROI* FUN_10085a80(const char* p_name, const char* p_lodName, MxBool p_createEntity);
|
||||||
|
|
||||||
static const char* GetCustomizeAnimFile() { return g_customizeAnimFile; }
|
static const char* GetCustomizeAnimFile() { return g_customizeAnimFile; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
friend class Multiplayer::CharacterCloner;
|
||||||
|
|
||||||
LegoROI* CreateActorROI(const char* p_key);
|
LegoROI* CreateActorROI(const char* p_key);
|
||||||
void RemoveROI(LegoROI* p_roi);
|
void RemoveROI(LegoROI* p_roi);
|
||||||
LegoROI* FindChildROI(LegoROI* p_roi, const char* p_name);
|
LegoROI* FindChildROI(LegoROI* p_roi, const char* p_name);
|
||||||
|
|||||||
@ -11,6 +11,10 @@ struct LegoPlantInfo;
|
|||||||
class LegoROI;
|
class LegoROI;
|
||||||
class LegoStorage;
|
class LegoStorage;
|
||||||
class LegoWorld;
|
class LegoWorld;
|
||||||
|
namespace Multiplayer
|
||||||
|
{
|
||||||
|
class NetworkManager;
|
||||||
|
}
|
||||||
|
|
||||||
// VTABLE: LEGO1 0x100d6758
|
// VTABLE: LEGO1 0x100d6758
|
||||||
// SIZE 0x2c
|
// SIZE 0x2c
|
||||||
@ -67,6 +71,8 @@ class LegoPlantManager : public MxCore {
|
|||||||
// LegoPlantManager::`scalar deleting destructor'
|
// LegoPlantManager::`scalar deleting destructor'
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
friend class Multiplayer::NetworkManager;
|
||||||
|
|
||||||
void RemovePlant(MxS32 p_index, LegoOmni::World p_worldId);
|
void RemovePlant(MxS32 p_index, LegoOmni::World p_worldId);
|
||||||
void AdjustHeight(MxS32 p_index);
|
void AdjustHeight(MxS32 p_index);
|
||||||
LegoPlantInfo* GetInfo(LegoEntity* p_entity);
|
LegoPlantInfo* GetInfo(LegoEntity* p_entity);
|
||||||
@ -74,6 +80,8 @@ class LegoPlantManager : public MxCore {
|
|||||||
void AdjustCounter(LegoEntity* p_entity, MxS32 p_adjust);
|
void AdjustCounter(LegoEntity* p_entity, MxS32 p_adjust);
|
||||||
|
|
||||||
static char* g_customizeAnimFile;
|
static char* g_customizeAnimFile;
|
||||||
|
static MxS32 g_maxMove[4];
|
||||||
|
static MxU32 g_maxSound;
|
||||||
|
|
||||||
LegoOmni::World m_worldId; // 0x08
|
LegoOmni::World m_worldId; // 0x08
|
||||||
MxBool m_boundariesDetermined; // 0x0c
|
MxBool m_boundariesDetermined; // 0x0c
|
||||||
|
|||||||
@ -197,7 +197,7 @@ LegoBuildingInfo g_buildingInfoInit[16] = {
|
|||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
// GLOBAL: LEGO1 0x100f3738
|
// GLOBAL: LEGO1 0x100f3738
|
||||||
MxU32 g_buildingMaxSound = 6;
|
MxU32 LegoBuildingManager::g_maxSound = 6;
|
||||||
|
|
||||||
// GLOBAL: LEGO1 0x100f373c
|
// GLOBAL: LEGO1 0x100f373c
|
||||||
MxU32 g_buildingSoundIdOffset = 0x3c;
|
MxU32 g_buildingSoundIdOffset = 0x3c;
|
||||||
@ -226,7 +226,7 @@ MxS32 g_buildingManagerConfig = 1;
|
|||||||
LegoBuildingInfo g_buildingInfo[16];
|
LegoBuildingInfo g_buildingInfo[16];
|
||||||
|
|
||||||
// GLOBAL: LEGO1 0x100f3748
|
// 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
|
#define HAUS1_INDEX 12
|
||||||
|
|
||||||
@ -493,7 +493,7 @@ MxBool LegoBuildingManager::SwitchSound(LegoEntity* p_entity)
|
|||||||
if (info != NULL && info->m_flags & LegoBuildingInfo::c_hasSounds) {
|
if (info != NULL && info->m_flags & LegoBuildingInfo::c_hasSounds) {
|
||||||
info->m_sound++;
|
info->m_sound++;
|
||||||
|
|
||||||
if (info->m_sound >= g_buildingMaxSound) {
|
if (info->m_sound >= g_maxSound) {
|
||||||
info->m_sound = 0;
|
info->m_sound = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -513,7 +513,7 @@ MxBool LegoBuildingManager::SwitchMove(LegoEntity* p_entity)
|
|||||||
if (info != NULL && info->m_flags & LegoBuildingInfo::c_hasMoves) {
|
if (info != NULL && info->m_flags & LegoBuildingInfo::c_hasMoves) {
|
||||||
info->m_move++;
|
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;
|
info->m_move = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1110,146 +1110,3 @@ void CustomizeAnimFileVariable::SetValue(const char* p_value)
|
|||||||
BuildingManager()->SetCustomizeAnimFile(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;
|
|
||||||
}
|
|
||||||
|
|||||||
@ -37,7 +37,7 @@ float g_heightPerCount[] = {0.1f, 0.7f, 0.5f, 0.9f};
|
|||||||
MxU8 g_counters[] = {1, 2, 2, 3};
|
MxU8 g_counters[] = {1, 2, 2, 3};
|
||||||
|
|
||||||
// GLOBAL: LEGO1 0x100f315c
|
// GLOBAL: LEGO1 0x100f315c
|
||||||
MxU32 g_plantMaxSound = 8;
|
MxU32 LegoPlantManager::g_maxSound = 8;
|
||||||
|
|
||||||
// GLOBAL: LEGO1 0x100f3160
|
// GLOBAL: LEGO1 0x100f3160
|
||||||
MxU32 g_plantSoundIdOffset = 56;
|
MxU32 g_plantSoundIdOffset = 56;
|
||||||
@ -46,7 +46,7 @@ MxU32 g_plantSoundIdOffset = 56;
|
|||||||
MxU32 g_plantSoundIdMoodOffset = 66;
|
MxU32 g_plantSoundIdMoodOffset = 66;
|
||||||
|
|
||||||
// GLOBAL: LEGO1 0x100f3168
|
// GLOBAL: LEGO1 0x100f3168
|
||||||
MxS32 g_plantMaxMove[4] = {3, 3, 3, 3};
|
MxS32 LegoPlantManager::g_maxMove[4] = {3, 3, 3, 3};
|
||||||
|
|
||||||
// GLOBAL: LEGO1 0x100f3178
|
// GLOBAL: LEGO1 0x100f3178
|
||||||
MxU32 g_plantAnimationId[4] = {30, 33, 36, 39};
|
MxU32 g_plantAnimationId[4] = {30, 33, 36, 39};
|
||||||
@ -433,8 +433,8 @@ MxBool LegoPlantManager::SwitchVariant(LegoEntity* p_entity)
|
|||||||
lodList->Release();
|
lodList->Release();
|
||||||
CharacterManager()->UpdateBoundingSphereAndBox(roi);
|
CharacterManager()->UpdateBoundingSphereAndBox(roi);
|
||||||
|
|
||||||
if (info->m_move != 0 && info->m_move >= g_plantMaxMove[info->m_variant]) {
|
if (info->m_move != 0 && info->m_move >= g_maxMove[info->m_variant]) {
|
||||||
info->m_move = g_plantMaxMove[info->m_variant] - 1;
|
info->m_move = g_maxMove[info->m_variant] - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -450,7 +450,7 @@ MxBool LegoPlantManager::SwitchSound(LegoEntity* p_entity)
|
|||||||
if (info != NULL) {
|
if (info != NULL) {
|
||||||
info->m_sound++;
|
info->m_sound++;
|
||||||
|
|
||||||
if (info->m_sound >= g_plantMaxSound) {
|
if (info->m_sound >= g_maxSound) {
|
||||||
info->m_sound = 0;
|
info->m_sound = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -470,7 +470,7 @@ MxBool LegoPlantManager::SwitchMove(LegoEntity* p_entity)
|
|||||||
if (info != NULL) {
|
if (info != NULL) {
|
||||||
info->m_move++;
|
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;
|
info->m_move = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
17
extensions/include/extensions/multiplayer/charactercloner.h
Normal file
17
extensions/include/extensions/multiplayer/charactercloner.h
Normal file
@ -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
|
||||||
156
extensions/src/multiplayer/charactercloner.cpp
Normal file
156
extensions/src/multiplayer/charactercloner.cpp
Normal file
@ -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 <SDL3/SDL_stdinc.h>
|
||||||
|
#include <vec.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
@ -18,11 +18,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
extern MxU8 g_counters[];
|
extern MxU8 g_counters[];
|
||||||
extern MxS32 g_plantMaxMove[];
|
|
||||||
extern MxU32 g_plantMaxSound;
|
|
||||||
extern MxU8 g_buildingInfoDownshift[];
|
extern MxU8 g_buildingInfoDownshift[];
|
||||||
extern MxS32 g_buildingMaxMove[];
|
|
||||||
extern MxU32 g_buildingMaxSound;
|
|
||||||
|
|
||||||
using namespace Multiplayer;
|
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)
|
// Clamp move to the new variant's max (mirrors SwitchVariant)
|
||||||
if (info->m_move != 0 && info->m_move >= (MxU32) g_plantMaxMove[info->m_variant]) {
|
if (info->m_move != 0 && info->m_move >= (MxU32) LegoPlantManager::g_maxMove[info->m_variant]) {
|
||||||
info->m_move = g_plantMaxMove[info->m_variant] - 1;
|
info->m_move = LegoPlantManager::g_maxMove[info->m_variant] - 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CHANGE_SOUND:
|
case CHANGE_SOUND:
|
||||||
info->m_sound++;
|
info->m_sound++;
|
||||||
if (info->m_sound >= g_plantMaxSound) {
|
if (info->m_sound >= LegoPlantManager::g_maxSound) {
|
||||||
info->m_sound = 0;
|
info->m_sound = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CHANGE_MOVE:
|
case CHANGE_MOVE:
|
||||||
info->m_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;
|
info->m_move = 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@ -747,7 +743,7 @@ void NetworkManager::ApplyWorldEvent(uint8_t p_entityType, uint8_t p_changeType,
|
|||||||
case CHANGE_SOUND:
|
case CHANGE_SOUND:
|
||||||
if (info->m_flags & LegoBuildingInfo::c_hasSounds) {
|
if (info->m_flags & LegoBuildingInfo::c_hasSounds) {
|
||||||
info->m_sound++;
|
info->m_sound++;
|
||||||
if (info->m_sound >= g_buildingMaxSound) {
|
if (info->m_sound >= LegoBuildingManager::g_maxSound) {
|
||||||
info->m_sound = 0;
|
info->m_sound = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -755,7 +751,7 @@ void NetworkManager::ApplyWorldEvent(uint8_t p_entityType, uint8_t p_changeType,
|
|||||||
case CHANGE_MOVE:
|
case CHANGE_MOVE:
|
||||||
if (info->m_flags & LegoBuildingInfo::c_hasMoves) {
|
if (info->m_flags & LegoBuildingInfo::c_hasMoves) {
|
||||||
info->m_move++;
|
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;
|
info->m_move = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -788,4 +784,3 @@ void NetworkManager::ApplyWorldEvent(uint8_t p_entityType, uint8_t p_changeType,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include "3dmanager/lego3dmanager.h"
|
#include "3dmanager/lego3dmanager.h"
|
||||||
#include "anim/legoanim.h"
|
#include "anim/legoanim.h"
|
||||||
|
#include "extensions/multiplayer/charactercloner.h"
|
||||||
#include "legoactor.h"
|
#include "legoactor.h"
|
||||||
#include "legoanimpresenter.h"
|
#include "legoanimpresenter.h"
|
||||||
#include "legocharactermanager.h"
|
#include "legocharactermanager.h"
|
||||||
@ -79,7 +80,7 @@ void RemotePlayer::Spawn(LegoWorld* p_isleWorld)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_roi = charMgr->CreateCharacterClone(m_uniqueName, actorName);
|
m_roi = CharacterCloner::Clone(charMgr, m_uniqueName, actorName);
|
||||||
if (!m_roi) {
|
if (!m_roi) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user