Isle
Loading...
Searching...
No Matches
legocarbuildpresenter.cpp
Go to the documentation of this file.
2
4#include "legocarbuild.h"
5#include "legoentity.h"
6#include "legogamestate.h"
7#include "legomain.h"
8#include "legoutils.h"
9#include "legovideomanager.h"
10#include "legoworld.h"
11#include "misc.h"
12#include "misc/legoutil.h"
13#include "mxautolock.h"
15#include "mxmisc.h"
16#include "mxtimer.h"
17#include "realtime/realtime.h"
18
21
22// FUNCTION: LEGO1 0x10078400
23// FUNCTION: BETA10 0x100707c0
25{
26 m_unk0xbc = 0;
27 m_numberOfParts = 0;
28 m_placedPartCount = 0;
29 m_parts = NULL;
30 m_unk0xc4 = NULL;
31 m_unk0x130 = 0;
32 m_unk0x12c = 0;
33 m_unk0x134 = 0;
34 m_unk0x138 = 0;
35 m_unk0x13c = 0;
36 m_unk0x140 = NULL;
37 m_unk0x144 = -1;
38 m_unk0x148 = -1;
39 m_mainSourceId = NULL;
40}
41
42// FUNCTION: LEGO1 0x10078680
43// FUNCTION: BETA10 0x1007091e
45{
46 if (m_parts) {
47 for (MxS16 i = 0; i < m_numberOfParts; i++) {
48 delete m_parts[i].m_name;
49 delete m_parts[i].m_wiredName;
50 }
51 delete[] m_parts;
52 }
53
54 m_unk0xc8.GetRoot()->SetNumChildren(0);
55 *m_unk0xc8.GetRoot()->GetChildren() = NULL;
56
57 if (m_mainSourceId) {
58 delete[] m_mainSourceId;
59 }
60}
61
62// FUNCTION: BETA10 0x100733d0
63inline void LegoCarBuildAnimPresenter::Beta10Inline0x100733d0()
64{
65 MxLong time = Timer()->GetTime();
66 MxLong bvar5;
67
68 if (m_unk0x13c < time) {
69 bvar5 = FALSE;
70
71 // I have no idea why this conditional is so convoluted
72 if (m_unk0x13c & c_bit1) {
73 bvar5 = TRUE;
74 m_unk0x13c = time + 400;
75 }
76 else {
77 m_unk0x13c = time + 200;
78 }
79
80 if (bvar5) {
81 m_unk0x13c &= ~c_bit1;
82 }
83 else {
84 m_unk0x13c |= c_bit1;
85 }
86
87 if (m_placedPartCount < m_numberOfParts) {
88
89 const LegoChar* wiredName = m_parts[m_placedPartCount].m_wiredName;
90
91 if (wiredName) {
92 for (MxS32 i = 1; i <= m_roiMapSize; i++) {
93 LegoROI* roi = m_roiMap[i];
94
95 if (roi) {
96 const LegoChar* name = roi->GetName();
97
98 if (name && stricmp(wiredName, name) == 0) {
99 if (bvar5) {
100 roi->SetVisibility(TRUE);
101 }
102 else {
103 roi->SetVisibility(FALSE);
104 }
105 }
106 }
107 }
108 }
109 }
110 }
111}
112
113// FUNCTION: LEGO1 0x10078790
114// FUNCTION: BETA10 0x10070ab1
116{
117 switch (m_unk0xbc) {
118 case 0:
119 break;
120 case 2:
121 FUN_10079a90();
122 case 1:
123 if (m_unk0x140->GetROI()) {
124 FUN_1006b9a0(m_anim, m_unk0x12c, NULL);
125 }
126 default:
127 break;
128 }
129
130 Beta10Inline0x100733d0();
131}
132
133// FUNCTION: LEGO1 0x100788c0
134// FUNCTION: BETA10 0x10070b56
136{
137 if (!m_anim) {
139
140 if (!m_currentWorld) {
141 return;
142 }
143
144#ifndef BETA10
145 if (!m_anim) {
146 return;
147 }
148#else
149 assert(m_anim);
150#endif
151 }
152
153 m_unk0x140 = (LegoEntity*) m_currentWorld->Find("MxEntity", "Dunebld");
154
155 if (!m_unk0x140) {
156 m_unk0x140 = (LegoEntity*) m_currentWorld->Find("MxEntity", "Chptrbld");
157 }
158
159 if (!m_unk0x140) {
160 m_unk0x140 = (LegoEntity*) m_currentWorld->Find("MxEntity", "Jetbld");
161 }
162
163 if (!m_unk0x140) {
164 m_unk0x140 = (LegoEntity*) m_currentWorld->Find("MxEntity", "bldrace");
165 }
166
167 if (m_unk0x140) {
168 ((LegoCarBuild*) m_currentWorld)->SetUnknown0x258(this);
169 m_placedPartCount = ((LegoCarBuild*) m_currentWorld)->GetPlacedPartCount();
174 }
175 else {
178 }
179}
180
181// FUNCTION: LEGO1 0x100789e0
182// FUNCTION: BETA10 0x10070cdd
184{
185 if (!m_unk0x140->GetROI()) {
186 return;
187 }
188
189 m_mainSourceId = new LegoChar[strlen(m_action->GetAtomId().GetInternal()) + 1];
190 assert(m_mainSourceId);
191
192 strcpy(m_mainSourceId, m_action->GetAtomId().GetInternal());
193 m_mainSourceId[strlen(m_mainSourceId) - 1] = 'M';
194
195 FUN_10079160();
196
197 if (GameState()->GetCurrentAct() == LegoGameState::e_act2) {
198 m_placedPartCount = 10;
199 }
200
201 MxS16 i;
202
203 for (i = 0; i < m_numberOfParts; i++) {
204 if (m_placedPartCount == i) {
205 FUN_10079680(m_parts[i].m_wiredName);
206 }
207 else {
208 FUN_100795d0(m_parts[i].m_wiredName);
209 }
210
211 if (i < m_placedPartCount) {
212 FUN_10079050(i);
213 FUN_10079680(m_parts[i].m_name);
214 }
215
216 LegoChar* name = m_parts[i].m_wiredName;
217
218 if (name) {
219 for (MxS32 j = 0; j <= m_roiMapSize; j++) {
220 LegoROI* roi = m_roiMap[j];
221
222 if (roi && roi->GetName() && (strcmpi(name, roi->GetName()) == 0)) {
223 roi->ClearMeshOffset();
224 roi->SetLodColor("lego red");
225 }
226 }
227 }
228 }
229
230 LegoVideoManager* videoManager = VideoManager();
231 assert(videoManager); // verifies variable name 'videoManager'
232
233 Lego3DView* lego3dview = videoManager->Get3DManager()->GetLego3DView();
234 LegoROI* videoManagerROI = videoManager->GetViewROI();
235 LegoROI* local60 = m_unk0x140->GetROI();
236 LegoROI* camera = NULL;
237 MxFloat fov;
238
239 MxS16 totalNodes = CountTotalTreeNodes(m_anim->GetRoot());
240
241 for (i = 0; i < totalNodes; i++) {
242 LegoAnimNodeData* animNodeData = (LegoAnimNodeData*) GetTreeNode(m_anim->GetRoot(), i)->GetData();
243
244 if (strnicmp(animNodeData->GetName(), "CAM", strlen("CAM")) == 0) {
245 camera = local60->FindChildROI(animNodeData->GetName(), local60);
246 fov = atof(&animNodeData->GetName()[strlen(animNodeData->GetName()) - 2]);
247 break;
248 }
249 }
250
251 assert(camera); // verifies variable name 'camera'
252
253 LegoROI* targetROI = local60->FindChildROI("TARGET", local60);
254
255 Mx3DPointFloat dirVec;
256
257 const Vector3 cameraPosition(camera->GetWorldPosition());
258 const Vector3 upVec(camera->GetWorldUp());
259 const Vector3 targetPosition(targetROI->GetWorldPosition());
260
261 MxMatrix localTransform;
262
263 dirVec[0] = targetPosition[0] - cameraPosition[0];
264 dirVec[1] = targetPosition[1] - cameraPosition[1];
265 dirVec[2] = targetPosition[2] - cameraPosition[2];
266 dirVec.Unitize();
267
268 CalcLocalTransform(cameraPosition, dirVec, upVec, localTransform);
269
270 videoManagerROI->WrappedSetLocalTransform(localTransform);
271 lego3dview->Moved(*videoManagerROI);
272 videoManager->Get3DManager()->SetFrustrum(fov, 0.1, 250.0);
273
274 m_unk0xe0 = local60->FindChildROI("VIEW", local60)->GetLocal2World();
275
278}
279
280// FUNCTION: LEGO1 0x10078db0
281// FUNCTION: BETA10 0x100712f3
283{
284 if (m_action) {
287 m_unk0xbc = 0;
288 }
289}
290
291// FUNCTION: LEGO1 0x10078e30
292// FUNCTION: BETA10 0x10071387
294{
295 if (p_storage->IsReadMode()) {
296 p_storage->ReadS16(m_placedPartCount);
297 p_storage->ReadFloat(m_unk0x130);
298 for (MxS16 i = 0; i < m_numberOfParts; i++) {
299 p_storage->ReadString(m_parts[i].m_name);
300 p_storage->ReadString(m_parts[i].m_wiredName);
301 p_storage->ReadS16(m_parts[i].m_objectId);
302 }
303 }
304 else if (p_storage->IsWriteMode()) {
305 p_storage->WriteS16(m_placedPartCount);
306 p_storage->WriteFloat(m_unk0x130);
307 for (MxS16 i = 0; i < m_numberOfParts; i++) {
308 p_storage->WriteString(m_parts[i].m_name);
309 p_storage->WriteString(m_parts[i].m_wiredName);
310 p_storage->WriteS16(m_parts[i].m_objectId);
311 }
312 }
313
314 return SUCCESS;
315}
316
317// FUNCTION: LEGO1 0x10079050
318// FUNCTION: BETA10 0x1007151e
320{
321 SwapNodesByName(m_parts[p_index].m_wiredName, m_parts[p_index].m_name);
322 FUN_100795d0(m_parts[p_index].m_wiredName);
323}
324
325// FUNCTION: LEGO1 0x10079090
326// FUNCTION: BETA10 0x10071584
328{
329 char buffer[40];
330
331 if (stricmp(p_name1, p_name2) != 0) {
334
335 strcpy(buffer, node1->GetName());
336 strcpy(node1->GetName(), node2->GetName());
337 strcpy(node2->GetName(), buffer);
338
339 LegoU16 val1 = node1->GetUnknown0x20();
340 node1->SetUnknown0x20(node2->GetUnknown0x20());
341 node2->SetUnknown0x20(val1);
342 }
343}
344
345// FUNCTION: LEGO1 0x10079160
346// FUNCTION: BETA10 0x1007165d
348{
349 LegoTreeNode* root;
350 LegoAnimNodeData* data2;
351 MxS16 i;
352 MxS16 totalNodes = CountTotalTreeNodes(m_anim->GetRoot());
353 LegoChar* name;
354 LegoTreeNode* destNode;
355 LegoAnimNodeData* destData;
356 LegoTreeNode** children;
357
358 for (i = 0; i < totalNodes; i++) {
359 LegoAnimNodeData* data = (LegoAnimNodeData*) GetTreeNode(m_anim->GetRoot(), i)->GetData();
360 name = data->GetName();
361
362 if (StringEqualsPlatform(name)) {
363 m_unk0xc4 = data;
364 if (m_unk0xc4->GetNumRotationKeys() == 0) {
365 LegoRotationKey* key = new LegoRotationKey();
366 m_unk0xc4->SetNumRotationKeys(1);
367 m_unk0xc4->SetRotationKeys(key);
368 }
369 }
370 else {
371 if (StringEndsOnYOrN(name)) {
372 m_numberOfParts++;
373 }
374 else {
375 if (m_unk0x134 == 0.0f && StringEqualsShelf(name)) {
376 m_unk0x134 = m_anim->GetDuration();
377 m_unk0x138 = m_unk0x134 / (data->GetNumTranslationKeys() - 1);
378 }
379 }
380 }
381 }
382
383 assert(m_numberOfParts);
384 m_parts = new UnknownListEntry[m_numberOfParts];
385 assert(m_parts);
386
387 for (i = 0; i < totalNodes; i++) {
388 name = ((LegoAnimNodeData*) GetTreeNode(m_anim->GetRoot(), i)->GetData())->GetName();
389
390 strupr(name);
391
392 if (StringEndsOnW(name)) {
393 m_parts[name[strlen(name) - 1] - 'A'].m_wiredName = new LegoChar[strlen(name) + 1];
394
395 // clang-format off
396 assert(m_parts[name[strlen(name)-1] - 'A'].m_wiredName);
397 // clang-format on
398
399 strcpy(m_parts[name[strlen(name) - 1] - 'A'].m_wiredName, name);
400 }
401 }
402
403 MxS16 counter = 0;
404
405 for (i = 0; i < totalNodes; i++) {
406 name = ((LegoAnimNodeData*) GetTreeNode(m_anim->GetRoot(), i)->GetData())->GetName();
407 if (StringEndsOnYOrN(name)) {
408 for (MxS16 ii = 0; ii < m_numberOfParts; ii++) {
409 if (strnicmp(m_parts[ii].m_wiredName, name, strlen(name) - 2) == 0) {
410 m_parts[ii].m_name = new LegoChar[strlen(name) + 1];
411 assert(m_parts[ii].m_name);
412 strcpy(m_parts[ii].m_name, name);
413
414 counter++;
415 if (m_numberOfParts == counter) {
416 break;
417 }
418 }
419 }
420 }
421 }
422
423 destNode = new LegoTreeNode();
424 assert(destNode);
425 destData = new LegoAnimNodeData();
426 assert(destData);
427 destNode->SetData(destData);
428
429 root = m_anim->GetRoot();
430 data2 = (LegoAnimNodeData*) root->GetData();
431 destData->SetName(data2->GetName());
432
433 destNode->SetNumChildren(1);
434 children = new LegoTreeNode*;
435 assert(children);
436 *children = FindNodeByName(m_anim->GetRoot(), "PLATFORM");
437
438 destNode->SetChildren(children);
439 m_unk0xc8.SetRoot(destNode);
440}
441
442// FUNCTION: LEGO1 0x100795d0
443// FUNCTION: BETA10 0x10071d96
445{
447
448 if (data) {
449 LegoMorphKey* oldMorphKeys = data->GetMorphKeys();
450
451 LegoMorphKey* newHideKey = new LegoMorphKey();
452 assert(newHideKey);
453
454 newHideKey->SetTime(0);
455 newHideKey->SetUnknown0x08(FALSE);
456
457 data->SetNumMorphKeys(1);
458 data->SetMorphKeys(newHideKey);
459
460 delete oldMorphKeys;
461 }
462}
463
464// FUNCTION: LEGO1 0x10079680
465// FUNCTION: BETA10 0x10071ec5
467{
469
470 if (data) {
471 LegoMorphKey* oldMorphKeys = data->GetMorphKeys();
472
473 data->SetNumMorphKeys(0);
474 data->SetMorphKeys(NULL);
475
476 delete oldMorphKeys;
477 }
478}
479
480// FUNCTION: LEGO1 0x100796b0
481// FUNCTION: BETA10 0x10071f3c
483{
484 LegoAnimNodeData* data = NULL;
485
486 if (p_treeNode) {
487 data = (LegoAnimNodeData*) p_treeNode->GetData();
488
489 if (stricmp(data->GetName(), p_name) == 0) {
490 return data;
491 }
492
493 for (MxS32 i = 0; i < p_treeNode->GetNumChildren(); i++) {
494 data = FindNodeDataByName(p_treeNode->GetChildren()[i], p_name);
495
496 if (data) {
497 return data;
498 }
499 }
500 }
501
502 return NULL;
503}
504
505// FUNCTION: LEGO1 0x10079720
506// FUNCTION: BETA10 0x10071fec
508{
509 LegoAnimNodeData* data = NULL;
510 LegoTreeNode* node = NULL;
511
512 if (p_treeNode) {
513 data = (LegoAnimNodeData*) p_treeNode->GetData();
514
515 if (stricmp(data->GetName(), p_name) == 0) {
516 return p_treeNode;
517 }
518
519 for (MxS32 i = 0; i < p_treeNode->GetNumChildren(); i++) {
520 node = FindNodeByName(p_treeNode->GetChildren()[i], p_name);
521
522 if (node) {
523 return node;
524 }
525 }
526 }
527
528 return NULL;
529}
530
531// FUNCTION: LEGO1 0x10079790
532// FUNCTION: BETA10 0x100720a3
534{
535 MxS16 i;
536 LegoChar buffer[40];
537
538 if (strcmpi(m_parts[m_placedPartCount].m_name, p_name) != 0) {
539 for (i = m_placedPartCount + 1; i < m_numberOfParts; i++) {
540 if (stricmp(m_parts[i].m_name, p_name) == 0) {
541 break;
542 }
543 }
544
545 strcpy(buffer, m_parts[m_placedPartCount].m_name);
546 strcpy(m_parts[m_placedPartCount].m_name, m_parts[i].m_name);
547 strcpy(m_parts[i].m_name, buffer);
548 Swap(m_parts[m_placedPartCount].m_objectId, m_parts[i].m_objectId);
549 }
550 FUN_10079050(m_placedPartCount);
551 m_placedPartCount++;
552
553 ((LegoCarBuild*) m_currentWorld)->SetPlacedPartCount(m_placedPartCount);
554
555 if (m_placedPartCount < m_numberOfParts) {
556 FUN_10079680(m_parts[m_placedPartCount].m_wiredName);
557 }
558}
559
560// FUNCTION: LEGO1 0x10079920
561// FUNCTION: BETA10 0x1007225d
563{
564 if (m_unk0xc4) {
565 LegoRotationKey* rotationKey = m_unk0xc4->GetRotationKey(0);
566
568 currentRotation(rotationKey->GetX(), rotationKey->GetY(), rotationKey->GetZ(), rotationKey->GetAngle());
569 Mx4DPointFloat additionalRotation(0.0f, 1.0f, 0.0f, -p_angle);
570 Mx4DPointFloat newRotation;
571
572 additionalRotation.NormalizeQuaternion();
573 newRotation.EqualsHamiltonProduct(currentRotation, additionalRotation);
574
575 if (newRotation[3] < 0.9999) {
576 rotationKey->FUN_100739a0(TRUE);
577 }
578 else {
579 rotationKey->FUN_100739a0(FALSE);
580 }
581
582 m_unk0xc4->GetRotationKey(0)->SetX(newRotation[0]);
583 m_unk0xc4->GetRotationKey(0)->SetY(newRotation[1]);
584 m_unk0xc4->GetRotationKey(0)->SetZ(newRotation[2]);
585 m_unk0xc4->GetRotationKey(0)->SetAngle(newRotation[3]);
586
587 if (m_unk0x140->GetROI()) {
588 FUN_1006b9a0(&m_unk0xc8, m_unk0x12c, NULL);
589 }
590 }
591}
592
593// FUNCTION: LEGO1 0x10079a90
594// FUNCTION: BETA10 0x10072412
596{
597 if (m_unk0x12c >= m_unk0x134) {
598 m_unk0x130 = 0.0;
599 m_unk0x12c = m_unk0x130;
600 m_unk0xbc = 1;
601 }
602 else if (m_unk0x12c >= m_unk0x138 + m_unk0x130) {
603 m_unk0x130 = m_unk0x138 + m_unk0x130;
604 m_unk0x12c = m_unk0x130;
605 m_unk0xbc = 1;
606 }
607 else {
608 m_unk0x12c = m_unk0x138 / 10.0f + m_unk0x12c;
609 }
610}
611
612// FUNCTION: LEGO1 0x10079b20
613// FUNCTION: BETA10 0x100724fa
615{
616 return stricmp(p_string, "PLATFORM") == 0;
617}
618
619// FUNCTION: LEGO1 0x10079b40
620// FUNCTION: BETA10 0x10072534
622{
623 return (p_param[strlen(p_param) - 2] == 'W') || (p_param[strlen(p_param) - 2] == 'w');
624}
625
626// FUNCTION: LEGO1 0x10079b80
627// FUNCTION: BETA10 0x1007258f
629{
630 return (p_string[strlen(p_string) - 2] == 'N') || (p_string[strlen(p_string) - 2] == 'n') ||
631 (p_string[strlen(p_string) - 2] == 'Y') || (p_string[strlen(p_string) - 2] == 'y');
632}
633
634// FUNCTION: LEGO1 0x10079bf0
635// FUNCTION: BETA10 0x10072624
637{
638 return strnicmp(p_string, "SHELF", strlen("SHELF")) == 0;
639}
640
641// FUNCTION: LEGO1 0x10079c30
642// FUNCTION: BETA10 0x100726a6
644{
645 if (PartIsPlaced(p_name)) {
646 return FALSE;
647 }
648
649 return m_placedPartCount < m_numberOfParts &&
650 strnicmp(p_name, m_parts[m_placedPartCount].m_name, strlen(p_name) - 3) == 0;
651}
652
653// FUNCTION: LEGO1 0x10079ca0
654// FUNCTION: BETA10 0x10072740
656{
657 for (MxS16 i = 0; i < m_placedPartCount; i++) {
658 if (strcmpi(p_name, m_parts[i].m_name) == 0) {
659 return TRUE;
660 }
661 }
662
663 return FALSE;
664}
665
666// FUNCTION: LEGO1 0x10079cf0
667// FUNCTION: BETA10 0x100727b3
669{
670 return (p_string[strlen(p_string) - 2] == 'Y') || (p_string[strlen(p_string) - 2] == 'y');
671}
672
673// FUNCTION: LEGO1 0x10079d30
674// FUNCTION: BETA10 0x1007280e
676{
677 return (p_string[strlen(p_string) - 1] != '0');
678}
679
680// FUNCTION: LEGO1 0x10079d60
681// FUNCTION: BETA10 0x1007284c
683{
684 for (MxS16 i = 0; i < m_numberOfParts; i++) {
685 if (strcmpi(p_name, m_parts[i].m_name) == 0) {
686 return m_parts[i].m_wiredName;
687 }
688 }
689
690 return NULL;
691}
692
693// FUNCTION: LEGO1 0x10079dc0
694// FUNCTION: BETA10 0x100728d1
696{
697 for (MxS16 i = 0; i < m_numberOfParts; i++) {
698 if (strcmpi(p_name, m_parts[i].m_name) == 0) {
699 m_parts[i].m_objectId = p_objectId;
700 return;
701 }
702 }
703}
704
705// FUNCTION: LEGO1 0x10079e20
706// FUNCTION: BETA10 0x10072959
708{
709 LegoROI* roi = m_unk0x140->GetROI();
710 return roi->FindChildROI(m_parts[m_placedPartCount].m_wiredName, roi)->GetWorldBoundingSphere();
711}
[AI] Represents a bounding sphere in 3D space with center and radius.
Definition: roi.h:56
int SetFrustrum(float p_fov, float p_front, float p_back)
[AI] Sets the 3D perspective frustum parameters for camera and view.
Lego3DView * GetLego3DView()
[AI] Returns the encapsulated Lego3DView instance.
[AI] Represents a 3D view for rendering and managing LEGO game objects in a 3D scene.
Definition: lego3dview.h:20
BOOL Moved(ViewROI &rROI)
[AI] Notifies the view that a ViewROI has moved.
Definition: lego3dview.cpp:126
void FUN_100739a0(MxS32 p_param)
[AI] Sets or clears bit1 depending on the parameter.
Definition: legoanim.h:34
void SetTime(MxS32 p_time)
[AI] Sets the key's time (from an integer value, used during deserialization or legacy data).
Definition: legoanim.h:27
[AI] Holds per-node animation data for a model's animation tree.
Definition: legoanim.h:144
void SetNumMorphKeys(LegoU16 p_numMorphKeys)
[AI] Sets morph key count.
Definition: legoanim.h:199
void SetRotationKeys(LegoRotationKey *p_keys)
[AI] Sets the node's rotation keys array, resets rotation index.
Definition: legoanim.h:169
LegoRotationKey * GetRotationKey(MxS32 index)
[AI] Access a pointer to the i-th rotation key.
Definition: legoanim.h:185
void SetUnknown0x20(LegoU16 p_unk0x20)
[AI] Sets unknown parameter (possibly camera/scene state).
Definition: legoanim.h:200
void SetMorphKeys(LegoMorphKey *p_morphKeys)
Definition: legoanim.h:193
void SetName(LegoChar *p_name)
[AI] Sets the node's name (deep-copies string).
Definition: legoanim.cpp:717
LegoMorphKey * GetMorphKeys()
[AI] Returns pointer to morph keyframes array.
Definition: legoanim.h:192
LegoU16 GetUnknown0x20()
[AI] Unknown, used in scene/camera calculations (purpose unclear).
Definition: legoanim.h:180
LegoU16 GetNumRotationKeys()
[AI] Number of rotation keys for this node.
Definition: legoanim.h:165
LegoU16 GetNumTranslationKeys()
[AI] Number of translation keys for this node.
Definition: legoanim.h:164
LegoChar * GetName()
[AI] Name of this animation node (used for lookup/mapping to scene graph).
Definition: legoanim.h:163
void SetNumRotationKeys(LegoU16 p_numRotationKeys)
[AI] Sets the number of rotation keys for this node.
Definition: legoanim.h:166
LegoAnim * m_anim
[AI] Animation resource currently being played back.
void ReadyTickle() override
[AI] Called when the presenter is in the "Ready" tickle state.
MxU32 m_roiMapSize
[AI] Number of valid entries in m_roiMap (excluding 0th index).
LegoROI ** m_roiMap
[AI] Lookup array to map animation node indices to scene ROIs (1-based index).
void FUN_1006b9a0(LegoAnim *p_anim, MxLong p_time, Matrix4 *p_matrix)
[AI] Like FUN_1006b900, but also processes associated camera animation if present.
LegoWorld * m_currentWorld
[AI] Reference to the world in which this presenter is currently placed/active.
LegoTime GetDuration()
[AI] Duration (in time units) of the animation.
Definition: legoanim.h:361
[AI] Handles the logic and animation presentation for the LEGO Island car-building activity,...
virtual MxResult Serialize(LegoStorage *p_storage)
[AI] Serializes or deserializes the assembly state of the car build.
MxBool StringEqualsShelf(const LegoChar *p_string)
[AI] Checks if the supplied string matches "SHELF" prefix (case-insensitive).
void StreamingTickle() override
[AI] Handles streaming phase:
void FUN_10079160()
[AI] (Re-)initializes internal state from animation root, prepares morph keys for "platform" node and...
void SetUnknown0xbc(undefined2 p_unk0xbc)
[AI] Sets the internal unknown word at offset 0xbc.
MxBool StringEndsOnW(LegoChar *p_param)
[AI] Returns TRUE if the given part's name ends with 'W' or 'w' as the second-to-last character.
@ c_bit1
[AI] Internal bitmask used for blinking animation state and timers.
void SwapNodesByName(LegoChar *p_param1, LegoChar *p_param2)
[AI] Swaps two animation nodes in the scene tree, exchanging their display names and internal indices...
void PutFrame() override
[AI] Called once per displayed animation frame.
MxBool StringEqualsPlatform(const LegoChar *p_string)
[AI] Checks if the supplied string matches "PLATFORM" (case-insensitive).
void EndAction() override
[AI] Ends the current build action safely, stops blinking and unlocks critical section.
void SetPartObjectIdByName(const LegoChar *p_name, MxS16 p_objectId)
[AI] Sets the object id for the given part name in the assembly state.
void FUN_10079790(const LegoChar *p_name)
[AI] Advances current placed part, handles swaps, and updates morph/visibility.
MxBool PartIsPlaced(const LegoChar *p_name)
[AI] Returns whether a part (by name) has already been placed in the sequence.
void ReadyTickle() override
[AI] "Ready" tickle for car-building: initializes main entity pointer, updates placed part count,...
~LegoCarBuildAnimPresenter() override
[AI] Destroys the presenter, deletes all allocated part information, strings, and detaches nodes from...
LegoAnimNodeData * FindNodeDataByName(LegoTreeNode *p_treeNode, const LegoChar *p_name)
[AI] Recursively searches for a node with the given name and returns its node data.
MxBool StringEndsOnY(const LegoChar *p_string)
[AI] Checks if the supplied string ends with "Y" or "y" in the second-to-last character.
void RotateAroundYAxis(MxFloat p_angle)
[AI] Rotates the assembly platform (root part) around the Y axis by the given angle (quaternion math)...
void FUN_100795d0(LegoChar *p_param)
[AI] Hides the referenced animation node by setting its morph key to invisible.
void FUN_10079050(MxS16 p_index)
[AI] Swaps the nodes representing the part at the given index, then hides the 3D node for main (wired...
MxBool StringDoesNotEndOnZero(const LegoChar *p_string)
[AI] Checks if string does not end on the character '0'.
MxBool FUN_10079c30(const LegoChar *p_name)
[AI] Returns true if the part with the given name is not yet placed, but is the current to-be-placed ...
LegoTreeNode * FindNodeByName(LegoTreeNode *p_treeNode, const LegoChar *p_name)
[AI] Recursively searches for a node with the given name and returns the node itself.
void FUN_10079680(LegoChar *p_param)
[AI] Resets the node's morph key count to zero, restoring/showing the node.
const LegoChar * GetWiredNameByPartName(const LegoChar *p_name)
[AI] Retrieves the wireframe/scene-graph name associated with the player-facing part name.
const BoundingSphere & FUN_10079e20()
[AI] Returns the world bounding sphere of the next part to be placed.
MxBool StringEndsOnYOrN(const LegoChar *p_string)
[AI] Returns TRUE if the given part's name ends with 'Y', 'y', 'N', or 'n' as the second-to-last char...
void FUN_10079a90()
[AI] Advances the internal state for the assembly animation (step advancement).
[AI] World implementation for the LEGO vehicle builder (Racecar, Copter, Dune Car,...
Definition: legocarbuild.h:97
[AI] Represents an entity that can be placed and managed in the LEGO Island world.
Definition: legoentity.h:16
LegoROI * GetROI()
[AI] Gets the ROI (Realtime Object Instance) associated with this entity. [AI]
Definition: legoentity.h:161
@ e_act2
Act 2: main story segment two. [AI].
Definition: legogamestate.h:85
[AI] Animation key for morphing states or mesh morphing.
Definition: legoanim.h:115
void SetUnknown0x08(LegoBool p_unk0x08)
[AI] Sets the morph Boolean value (meaning unknown).
Definition: legoanim.h:121
[AI] Represents a Real-time Object Instance enriched with LEGO-specific functionality.
Definition: legoroi.h:43
LegoROI * FindChildROI(const LegoChar *p_name, LegoROI *p_roi)
[AI] Recursively searches for a child ROI by name, starting at the given ROI.
Definition: legoroi.cpp:349
void ClearMeshOffset()
[AI] Resets mesh offset for all LODs in this ROI.
Definition: legoroi.cpp:832
LegoResult SetLodColor(LegoFloat p_red, LegoFloat p_green, LegoFloat p_blue, LegoFloat p_alpha)
[AI] Sets the RGBA color for all LODs and recursively for all children.
Definition: legoroi.cpp:484
const LegoChar * GetName() const
[AI] Gets this ROI's name.
Definition: legoroi.h:287
[AI] Animation key class for rotations (axis-angle format).
Definition: legoanim.h:71
void SetX(LegoFloat p_x)
[AI] Sets the X-axis of the rotation.
Definition: legoanim.h:80
LegoFloat GetY()
[AI] Gets the Y-axis of the rotation.
Definition: legoanim.h:81
LegoFloat GetZ()
[AI] Gets the Z-axis of the rotation.
Definition: legoanim.h:83
LegoFloat GetX()
[AI] Gets the X-axis of the rotation.
Definition: legoanim.h:79
void SetY(LegoFloat p_y)
[AI] Sets the Y-axis of the rotation.
Definition: legoanim.h:82
LegoFloat GetAngle()
[AI] Gets the rotation angle (around the axis).
Definition: legoanim.h:77
void SetAngle(LegoFloat p_angle)
[AI] Sets the rotation angle.
Definition: legoanim.h:78
void SetZ(LegoFloat p_z)
[AI] Sets the Z-axis of the rotation.
Definition: legoanim.h:84
Abstract base class providing an interface for file-like storage with binary and text read/write oper...
Definition: legostorage.h:16
LegoStorage * ReadFloat(LegoFloat &p_data)
Reads a floating-point (single-precision) value from storage.
Definition: legostorage.h:263
virtual LegoBool IsWriteMode()
Returns TRUE if object was opened in write mode.
Definition: legostorage.h:72
LegoStorage * WriteS16(LegoS16 p_data)
Writes a 16-bit signed value to storage.
Definition: legostorage.h:110
LegoStorage * ReadS16(LegoS16 &p_data)
Reads a 16-bit signed value from storage.
Definition: legostorage.h:217
virtual LegoBool IsReadMode()
Returns TRUE if object was opened in read mode.
Definition: legostorage.h:78
LegoStorage * WriteString(const char *p_data)
Writes a length-prefixed string to storage.
Definition: legostorage.h:86
LegoStorage * ReadString(char *p_data)
Reads a length-prefixed string from storage.
Definition: legostorage.h:192
LegoStorage * WriteFloat(LegoFloat p_data)
Writes a floating-point (single-precision) value to storage.
Definition: legostorage.h:156
[AI] Represents a node within a general, N-ary tree structure.
Definition: legotree.h:44
void SetData(LegoTreeNodeData *p_data)
[AI] Associates a data payload with this node.
Definition: legotree.h:59
LegoTreeNodeData * GetData()
[AI] Returns the data payload stored at this node (may be nullptr). [AI]
Definition: legotree.h:54
LegoU32 GetNumChildren()
[AI] Returns the number of direct children of this node. [AI]
Definition: legotree.h:63
void SetChildren(LegoTreeNode **p_children)
[AI] Assigns the entire children pointer array.
Definition: legotree.h:86
void SetNumChildren(LegoU32 p_numChildren)
[AI] Sets the number of children for this node (does not resize pointer array).
Definition: legotree.h:68
LegoTreeNode ** GetChildren()
[AI] Returns the pointer to the children array. [AI]
Definition: legotree.h:81
LegoTreeNode * GetRoot()
[AI] Returns a pointer to the root node of the tree. [AI]
Definition: legotree.h:112
void SetRoot(LegoTreeNode *p_root)
[AI] Assigns the root node pointer for the tree (takes ownership).
Definition: legotree.h:117
[AI] Extends the functionality of MxVideoManager to provide LEGO Island–specific video and 3D graphic...
Lego3DManager * Get3DManager()
[AI] Returns the Lego3DManager for this manager, which owns all 3D scene representations and view con...
LegoROI * GetViewROI()
[AI] Returns the viewpoint ROI for the current view/camera.
MxCore * Find(const char *p_class, const char *p_name)
Finds an object of a given class and name in the world.
Definition: legoworld.cpp:573
[AI] Represents a 3D point with floating-point precision, inheriting from Vector3.
Definition: mxgeometry3d.h:14
[AI] 4D point class for floating point values.
Definition: mxgeometry4d.h:18
const char * GetInternal() const
[AI] Returns a pointer to the internal string, or nullptr if not set.
Definition: mxatom.h:194
const MxAtomId & GetAtomId()
[AI] Returns a const-reference to the object's atom identifier.
Definition: mxdsobject.h:133
[AI] Represents a 4x4 transformation matrix, specialized for the LEGO Island engine and derived from ...
Definition: mxmatrix.h:16
MxU32 m_previousTickleStates
[AI] Bitfield representing all tickle states that have already occurred during this lifetime.
Definition: mxpresenter.h:202
MxDSAction * m_action
[AI] The associated action currently being presented by this presenter.
Definition: mxpresenter.h:211
TickleState m_currentTickleState
[AI] Current state in the tickle lifecycle.
Definition: mxpresenter.h:199
@ e_repeating
[AI] Presentation is repeating (e.g., looping media).
Definition: mxpresenter.h:28
@ e_ready
[AI] Prepared to start processing an action.
Definition: mxpresenter.h:25
@ e_starting
[AI] In the process of starting playback/presentation.
Definition: mxpresenter.h:26
MxCriticalSection m_criticalSection
[AI] Thread synchronization for presenter state and data.
Definition: mxpresenter.h:214
MxCompositePresenter * m_compositePresenter
[AI] Owner composite presenter, if any.
Definition: mxpresenter.h:217
void SendToCompositePresenter(MxOmni *p_omni)
[AI] Notifies a composite presenter (if one exists) that this presenter wishes to join a group.
MxLong GetTime()
Returns the current timer value in ms, depending on running state.
Definition: mxtimer.h:50
void EndAction() override
Signals the end of the current playback action.
const BoundingSphere & GetWorldBoundingSphere() const override
Returns the object's bounding sphere in world coordinates.
const float * GetWorldUp() const
Returns a pointer to the world up vector from the transformation matrix.
const float * GetWorldPosition() const
Returns a pointer to the world position from the transformation matrix (translation row).
const Matrix4 & GetLocal2World() const
Accessor for the current local-to-world transformation matrix.
void WrappedSetLocalTransform(const Matrix4 &p_transform)
Wraps SetLocalTransform, for possible override or interface uniformity.
void SetVisibility(unsigned char p_visible)
[AI] Sets the visibility flag to the provided value.
Definition: roi.h:235
virtual int Unitize()
[AI] Scales the vector so its norm is 1 (unit vector).
[AI] 3D vector class, providing vector and cross-product operations in 3D space.
Definition: vector.h:249
virtual int EqualsHamiltonProduct(const Vector4 &p_a, const Vector4 &p_b)
[AI] Set this vector to the Hamilton product of two quaternion Vector4s.
virtual int NormalizeQuaternion()
[AI] Normalize this quaternion (interpreted as vector) in place.
#define TRUE
Definition: d3drmdef.h:28
#define FALSE
Definition: d3drmdef.h:27
#define DECOMP_SIZE_ASSERT(T, S)
Definition: decomp.h:19
#define NULL
[AI] Null pointer value (C/C++ semantics).
Definition: legotypes.h:26
char LegoChar
[AI] Alias for char, for use in character/byte data and string handling.
Definition: legotypes.h:83
#define SUCCESS
[AI] Used to indicate a successful operation in result codes.
Definition: legotypes.h:30
unsigned short LegoU16
[AI] Unsigned 16-bit integer type for cross-platform compatibility.
Definition: legotypes.h:59
void Swap(T &p_t1, T &p_t2)
[AI] Swaps the values of two variables of the same type.
Definition: legoutil.h:77
LegoTreeNode * GetTreeNode(LegoTreeNode *p_node, MxU32 p_index)
[AI] Retrieves the nth node in tree traversal order (preorder) from a LegoTreeNode root.
Definition: legoutils.cpp:151
MxS16 CountTotalTreeNodes(LegoTreeNode *p_node)
[AI] Recursively counts the number of nodes (including the root) in a tree hierarchy rooted at the sp...
Definition: legoutils.cpp:138
LegoGameState * GameState()
[AI] Accessor for the game's central game state controller. [AI]
Definition: misc.cpp:61
LegoVideoManager * VideoManager()
[AI] Accessor for the game's LegoVideoManager subsystem. Used for managing 3D/video hardware....
Definition: misc.cpp:29
LegoOmni * Lego()
[AI] Retrieves the global LegoOmni singleton instance, providing access to core subsystems.
Definition: misc.cpp:16
#define AUTOLOCK(CS)
[AI] Macro for automatic locking using the MxAutoLock class. This macro instantiates an MxAutoLock ob...
Definition: mxautolock.h:5
MxTimer * Timer()
[AI] Returns the global simulation timer.
Definition: mxmisc.cpp:33
MxU8 MxBool
[AI]
Definition: mxtypes.h:124
MxLong MxResult
[AI]
Definition: mxtypes.h:106
int MxLong
[AI]
Definition: mxtypes.h:83
signed short MxS16
[AI]
Definition: mxtypes.h:26
float MxFloat
[AI]
Definition: mxtypes.h:68
signed int MxS32
[AI]
Definition: mxtypes.h:38
void CalcLocalTransform(const Vector3 &p_posVec, const Vector3 &p_dirVec, const Vector3 &p_upVec, Matrix4 &p_outMatrix)
[AI] Computes a transformation matrix based on a position, direction, and up vector.
Definition: realtime.cpp:7
[AI] Represents a single entry in the car assembly sequence ("part list"), providing mapping between ...
LegoChar * m_name
[AI] Player-facing name or identifier for the part.
MxS16 m_objectId
[AI] Internal object id (likely 3D node id or mapping for placement).
LegoChar * m_wiredName
[AI] Internal/scene-graph name for the 3D mesh node.