Isle
Loading...
Searching...
No Matches
legoplantmanager.cpp
Go to the documentation of this file.
1#include "legoplantmanager.h"
2
5#include "legoentity.h"
6#include "legoplants.h"
7#include "legovideomanager.h"
8#include "legoworld.h"
9#include "misc.h"
10#include "misc/legostorage.h"
11#include "mxdebug.h"
12#include "mxmisc.h"
13#include "mxticklemanager.h"
14#include "mxtimer.h"
15#include "scripts.h"
16#include "sndanim_actions.h"
18
19#include <stdio.h>
20#include <vec.h>
21
24
25// GLOBAL: LEGO1 0x100f1660
26const char* g_plantLodNames[4][5] = {
27 {"flwrwht", "flwrblk", "flwryel", "flwrred", "flwrgrn"},
28 {"treewht", "treeblk", "treeyel", "treered", "tree"},
29 {"bushwht", "bushblk", "bushyel", "bushred", "bush"},
30 {"palmwht", "palmblk", "palmyel", "palmred", "palm"}
31};
32
33// GLOBAL: LEGO1 0x100f16b0
34float g_unk0x100f16b0[] = {0.1f, 0.7f, 0.5f, 0.9f};
35
36// GLOBAL: LEGO1 0x100f16c0
37MxU8 g_unk0x100f16c0[] = {1, 2, 2, 3};
38
39// GLOBAL: LEGO1 0x100f315c
40MxU32 LegoPlantManager::g_maxSound = 8;
41
42// GLOBAL: LEGO1 0x100f3160
44
45// GLOBAL: LEGO1 0x100f3164
47
48// GLOBAL: LEGO1 0x100f3168
49MxS32 LegoPlantManager::g_maxMove[4] = {3, 3, 3, 3};
50
51// GLOBAL: LEGO1 0x100f3178
52MxU32 g_plantAnimationId[4] = {30, 33, 36, 39};
53
54// GLOBAL: LEGO1 0x100f3188
55// GLOBAL: BETA10 0x101f4e70
56char* LegoPlantManager::g_customizeAnimFile = NULL;
57
58// GLOBAL: LEGO1 0x10103180
59// GLOBAL: BETA10 0x1020f4c0
61
62// FUNCTION: LEGO1 0x10026220
64{
65 Init();
66}
67
68// FUNCTION: LEGO1 0x100262c0
69// FUNCTION: BETA10 0x100c5002
71{
72 delete[] g_customizeAnimFile;
73}
74
75// FUNCTION: LEGO1 0x10026330
76// FUNCTION: BETA10 0x100c4f90
78{
79 // In BETA10 this appears to be LegoPlantManager::LegoPlantManager()
80
81 for (MxS32 i = 0; i < sizeOfArray(g_plantInfo); i++) {
83 }
84
85 m_worldId = LegoOmni::e_undefined;
86 m_unk0x0c = 0;
87 m_numEntries = 0;
88}
89
90// FUNCTION: LEGO1 0x10026360
91// FUNCTION: BETA10 0x100c5032
93{
94 m_worldId = p_worldId;
95 LegoWorld* world = CurrentWorld();
96
97 for (MxS32 i = 0; i < sizeOfArray(g_plantInfo); i++) {
98 CreatePlant(i, world, p_worldId);
99 }
100
101 m_unk0x0c = 0;
102}
103
104// FUNCTION: LEGO1 0x100263a0
105// FUNCTION: BETA10 0x100c5093
107{
108 MxU32 i;
110
111 for (i = 0; i < m_numEntries; i++) {
112 delete m_entries[i];
113 }
114
115 m_numEntries = 0;
116
117 for (i = 0; i < sizeOfArray(g_plantInfo); i++) {
118 RemovePlant(i, p_worldId);
119 }
120
121 m_worldId = LegoOmni::e_undefined;
122 m_unk0x0c = 0;
123}
124
125// FUNCTION: LEGO1 0x10026410
126// FUNCTION: BETA10 0x100c50e9
128{
129 // similar to LegoBuildingManager::FUN_10030630()
130
131 LegoWorld* world = CurrentWorld();
132
133 if (world == NULL) {
134 return FAILURE;
135 }
136
137 for (MxS32 i = 0; i < sizeOfArray(g_plantInfo); i++) {
138 if (g_plantInfo[i].m_entity != NULL && g_plantInfo[i].m_name != NULL) {
139 g_plantInfo[i].m_boundary = world->FindPathBoundary(g_plantInfo[i].m_name);
140
141 if (g_plantInfo[i].m_boundary != NULL) {
142 Mx3DPointFloat position(g_plantInfo[i].m_x, g_plantInfo[i].m_y, g_plantInfo[i].m_z);
144
145 for (MxS32 j = 0; j < boundary->GetNumEdges(); j++) {
146 Mx4DPointFloat* normal = boundary->GetEdgeNormal(j);
147
148 if (position.Dot(*normal, position) + (*normal).index_operator(3) < -0.001) {
149 MxTrace(
150 "Plant %d shot location (%g, %g, %g) is not in boundary %s.\n",
151 i,
152 position[0],
153 position[1],
154 position[2],
155 boundary->GetName()
156 );
158 break;
159 }
160 }
161
162 if (g_plantInfo[i].m_boundary != NULL) {
164
165 if (position.Dot(position, unk0x14) + unk0x14.index_operator(3) > 0.001 ||
166 position.Dot(position, unk0x14) + unk0x14.index_operator(3) < -0.001) {
167
168 g_plantInfo[i].m_y =
169 -((position[0] * unk0x14.index_operator(0) + unk0x14.index_operator(3) +
170 position[2] * unk0x14.index_operator(2)) /
171 unk0x14.index_operator(1));
172
173 MxTrace(
174 "Plant %d shot location (%g, %g, %g) is not on plane of boundary %s...adjusting to (%g, "
175 "%g, "
176 "%g)\n",
177 i,
178 position[0],
179 position[1],
180 position[2],
181 g_plantInfo[i].m_boundary->GetName(),
182 position[0],
183 g_plantInfo[i].m_y,
184 position[2]
185 );
186 }
187 }
188 }
189 else {
190 MxTrace("Plant %d is in boundary %s that does not exist.\n", i, g_plantInfo[i].m_name);
191 }
192 }
193 }
194
195 m_unk0x0c = TRUE;
196 return SUCCESS;
197}
198
199// FUNCTION: LEGO1 0x10026570
200// FUNCTION: BETA10 0x100c55e0
202{
203 if (!m_unk0x0c) {
204 FUN_10026410();
205 }
206
207 p_length = sizeOfArray(g_plantInfo);
208 return g_plantInfo;
209}
210
211// FUNCTION: LEGO1 0x10026590
212// FUNCTION: BETA10 0x100c561e
214{
215 LegoEntity* entity = NULL;
216
217 if (p_index < sizeOfArray(g_plantInfo)) {
218 MxU32 world = 1 << (MxU8) p_worldId;
219
220 if (g_plantInfo[p_index].m_worlds & world && g_plantInfo[p_index].m_unk0x16 != 0) {
221 if (g_plantInfo[p_index].m_entity == NULL) {
222 char name[256];
223 char lodName[256];
224
225 sprintf(name, "plant%d", p_index);
226 sprintf(lodName, "%s", g_plantLodNames[g_plantInfo[p_index].m_variant][g_plantInfo[p_index].m_color]);
227
228 LegoROI* roi = CharacterManager()->CreateAutoROI(name, lodName, TRUE);
229 roi->SetVisibility(TRUE);
230
231 entity = roi->GetEntity();
232 entity->SetLocation(
233 g_plantInfo[p_index].m_position,
234 g_plantInfo[p_index].m_direction,
235 g_plantInfo[p_index].m_up,
236 FALSE
237 );
239 g_plantInfo[p_index].m_entity = entity;
240 }
241 else {
242 entity = g_plantInfo[p_index].m_entity;
243 }
244 }
245 }
246
247 return entity;
248}
249
250// FUNCTION: LEGO1 0x100266c0
251// FUNCTION: BETA10 0x100c5859
252void LegoPlantManager::RemovePlant(MxS32 p_index, LegoOmni::World p_worldId)
253{
254 if (p_index < sizeOfArray(g_plantInfo)) {
255 MxU32 world = 1 << (MxU8) p_worldId;
256
257 if (g_plantInfo[p_index].m_worlds & world && g_plantInfo[p_index].m_entity != NULL) {
258 CharacterManager()->ReleaseAutoROI(g_plantInfo[p_index].m_entity->GetROI());
259 g_plantInfo[p_index].m_entity = NULL;
260 }
261 }
262}
263
264// FUNCTION: LEGO1 0x10026720
265// FUNCTION: BETA10 0x100c5918
267{
268 MxResult result = FAILURE;
269
270 for (MxS32 i = 0; i < sizeOfArray(g_plantInfo); i++) {
271 LegoPlantInfo* info = &g_plantInfo[i];
272
273 if (p_storage->Write(&info->m_variant, sizeof(info->m_variant)) != SUCCESS) {
274 goto done;
275 }
276 if (p_storage->Write(&info->m_sound, sizeof(info->m_sound)) != SUCCESS) {
277 goto done;
278 }
279 if (p_storage->Write(&info->m_move, sizeof(info->m_move)) != SUCCESS) {
280 goto done;
281 }
282 if (p_storage->Write(&info->m_mood, sizeof(info->m_mood)) != SUCCESS) {
283 goto done;
284 }
285 if (p_storage->Write(&info->m_color, sizeof(info->m_color)) != SUCCESS) {
286 goto done;
287 }
288 if (p_storage->Write(&info->m_initialUnk0x16, sizeof(info->m_initialUnk0x16)) != SUCCESS) {
289 goto done;
290 }
291 }
292
293 result = SUCCESS;
294
295done:
296 return result;
297}
298
299// FUNCTION: LEGO1 0x100267b0
300// FUNCTION: BETA10 0x100c5a76
302{
303 MxResult result = FAILURE;
304
305 for (MxS32 i = 0; i < sizeOfArray(g_plantInfo); i++) {
306 LegoPlantInfo* info = &g_plantInfo[i];
307
308 if (p_storage->Read(&info->m_variant, sizeof(info->m_variant)) != SUCCESS) {
309 goto done;
310 }
311 if (p_storage->Read(&info->m_sound, sizeof(info->m_sound)) != SUCCESS) {
312 goto done;
313 }
314 if (p_storage->Read(&info->m_move, sizeof(info->m_move)) != SUCCESS) {
315 goto done;
316 }
317 if (p_storage->Read(&info->m_mood, sizeof(info->m_mood)) != SUCCESS) {
318 goto done;
319 }
320 if (p_storage->Read(&info->m_color, sizeof(info->m_color)) != SUCCESS) {
321 goto done;
322 }
323 if (p_storage->Read(&info->m_unk0x16, sizeof(info->m_unk0x16)) != SUCCESS) {
324 goto done;
325 }
326
327 info->m_initialUnk0x16 = info->m_unk0x16;
328 FUN_10026860(i);
329 }
330
331 result = SUCCESS;
332
333done:
334 return result;
335}
336
337// FUNCTION: LEGO1 0x10026860
338// FUNCTION: BETA10 0x100c5be0
339void LegoPlantManager::FUN_10026860(MxS32 p_index)
340{
341 MxU8 variant = g_plantInfo[p_index].m_variant;
342
343 if (g_plantInfo[p_index].m_unk0x16 >= 0) {
344 float value = g_unk0x100f16c0[variant] - g_plantInfo[p_index].m_unk0x16;
345 g_plantInfo[p_index].m_position[1] = g_plantInfoInit[p_index].m_position[1] - value * g_unk0x100f16b0[variant];
346 }
347 else {
348 g_plantInfo[p_index].m_position[1] = g_plantInfoInit[p_index].m_position[1];
349 }
350}
351
352// FUNCTION: LEGO1 0x100268d0
353// FUNCTION: BETA10 0x100c5c7a
355{
356 return sizeOfArray(g_plantInfo);
357}
358
359// FUNCTION: LEGO1 0x100268e0
360// FUNCTION: BETA10 0x100c5c95
361LegoPlantInfo* LegoPlantManager::GetInfo(LegoEntity* p_entity)
362{
363 MxS32 i;
364
365 for (i = 0; i < sizeOfArray(g_plantInfo); i++) {
366 if (g_plantInfo[i].m_entity == p_entity) {
367 break;
368 }
369 }
370
371 if (i < sizeOfArray(g_plantInfo)) {
372 return &g_plantInfo[i];
373 }
374
375 return NULL;
376}
377
378// FUNCTION: LEGO1 0x10026920
379// FUNCTION: BETA10 0x100c5dc9
381{
382 LegoPlantInfo* info = GetInfo(p_entity);
383
384 if (info == NULL) {
385 return FALSE;
386 }
387
388 LegoROI* roi = p_entity->GetROI();
389 info->m_color++;
390
391 if (info->m_color > LegoPlantInfo::e_green) {
393 }
394
396
397 if (roi->GetUnknown0xe0() >= 0) {
399 }
400
401 roi->SetLODList(lodList);
402 lodList->Release();
404 return TRUE;
405}
406
407// FUNCTION: LEGO1 0x100269e0
408// FUNCTION: BETA10 0x100c5ee2
410{
411 LegoPlantInfo* info = GetInfo(p_entity);
412
413 if (info == NULL || info->m_unk0x16 != -1) {
414 return FALSE;
415 }
416
417 LegoROI* roi = p_entity->GetROI();
418 info->m_variant++;
419
420 if (info->m_variant > LegoPlantInfo::e_palm) {
422 }
423
425
426 if (roi->GetUnknown0xe0() >= 0) {
428 }
429
430 roi->SetLODList(lodList);
431 lodList->Release();
433
434 if (info->m_move != 0 && info->m_move >= g_maxMove[info->m_variant]) {
435 info->m_move = g_maxMove[info->m_variant] - 1;
436 }
437
438 return TRUE;
439}
440
441// FUNCTION: LEGO1 0x10026ad0
442// FUNCTION: BETA10 0x100c6049
444{
445 MxBool result = FALSE;
446 LegoPlantInfo* info = GetInfo(p_entity);
447
448 if (info != NULL) {
449 info->m_sound++;
450
451 if (info->m_sound >= g_maxSound) {
452 info->m_sound = 0;
453 }
454
455 result = TRUE;
456 }
457
458 return result;
459}
460
461// FUNCTION: LEGO1 0x10026b00
462// FUNCTION: BETA10 0x100c60a7
464{
465 MxBool result = FALSE;
466 LegoPlantInfo* info = GetInfo(p_entity);
467
468 if (info != NULL) {
469 info->m_move++;
470
471 if (info->m_move >= g_maxMove[info->m_variant]) {
472 info->m_move = 0;
473 }
474
475 result = TRUE;
476 }
477
478 return result;
479}
480
481// FUNCTION: LEGO1 0x10026b40
482// FUNCTION: BETA10 0x100c610e
484{
485 MxBool result = FALSE;
486 LegoPlantInfo* info = GetInfo(p_entity);
487
488 if (info != NULL) {
489 info->m_mood++;
490
491 if (info->m_mood > 3) {
492 info->m_mood = 0;
493 }
494
495 result = TRUE;
496 }
497
498 return result;
499}
500
501// FUNCTION: LEGO1 0x10026b70
502// FUNCTION: BETA10 0x100c6168
504{
505 LegoPlantInfo* info = GetInfo(p_entity);
506
507 if (info != NULL) {
508 return g_plantAnimationId[info->m_variant] + info->m_move;
509 }
510
511 return 0;
512}
513
514// FUNCTION: LEGO1 0x10026ba0
515// FUNCTION: BETA10 0x100c61ba
517{
518 LegoPlantInfo* info = GetInfo(p_entity);
519
520 if (p_state) {
521 return (info->m_mood & 1) + g_unk0x100f3164;
522 }
523
524 if (info != NULL) {
525 return info->m_sound + g_unk0x100f3160;
526 }
527
528 return 0;
529}
530
531// FUNCTION: LEGO1 0x10026be0
532// FUNCTION: BETA10 0x100c62bc
534{
535 if (g_customizeAnimFile != NULL) {
536 delete[] g_customizeAnimFile;
537 }
538
539 if (p_value != NULL) {
540 g_customizeAnimFile = new char[strlen(p_value) + 1];
541
542 if (g_customizeAnimFile != NULL) {
543 strcpy(g_customizeAnimFile, p_value);
544 }
545 }
546 else {
547 g_customizeAnimFile = NULL;
548 }
549}
550
551// FUNCTION: LEGO1 0x10026c50
552// FUNCTION: BETA10 0x100c6349
554{
555 LegoPlantInfo* info = GetInfo(p_entity);
556
557 if (info == NULL) {
558 return FALSE;
559 }
560
561 return FUN_10026c80(info - g_plantInfo);
562}
563
564// FUNCTION: LEGO1 0x10026c80
565// FUNCTION: BETA10 0x100c63eb
566MxBool LegoPlantManager::FUN_10026c80(MxS32 p_index)
567{
568 if (p_index >= sizeOfArray(g_plantInfo)) {
569 return FALSE;
570 }
571
572 LegoPlantInfo* info = &g_plantInfo[p_index];
573
574 if (info == NULL) {
575 return FALSE;
576 }
577
578 MxBool result = TRUE;
579
580 if (info->m_unk0x16 < 0) {
581 info->m_unk0x16 = g_unk0x100f16c0[info->m_variant];
582 }
583
584 if (info->m_unk0x16 > 0) {
585 LegoROI* roi = info->m_entity->GetROI();
586 info->m_unk0x16--;
587
588 if (info->m_unk0x16 == 1) {
589 info->m_unk0x16 = 0;
590 }
591
592 if (info->m_unk0x16 == 0) {
593 roi->SetVisibility(FALSE);
594 }
595 else {
596 FUN_10026860(info - g_plantInfo);
597 info->m_entity->SetLocation(info->m_position, info->m_direction, info->m_up, FALSE);
598 }
599 }
600 else {
601 result = FALSE;
602 }
603
604 return result;
605}
606
607// FUNCTION: LEGO1 0x10026d70
609{
610 m_world = CurrentWorld();
611
612 if (m_numEntries == 0) {
613 TickleManager()->RegisterClient(this, 50);
614 }
615
616 AnimEntry* entry = m_entries[m_numEntries] = new AnimEntry;
617 m_numEntries++;
618
619 entry->m_entity = p_entity;
620 entry->m_roi = p_entity->GetROI();
621
622 MxLong time = Timer()->GetTime();
623 time += p_length;
624 entry->m_time = time + 1000;
625
626 FUN_100271b0(p_entity, -1);
627}
628
629// FUNCTION: LEGO1 0x10026e00
631{
632 MxLong time = Timer()->GetTime();
633
634 if (m_numEntries != 0) {
635 for (MxS32 i = 0; i < m_numEntries; i++) {
636 AnimEntry** ppEntry = &m_entries[i];
637 AnimEntry* entry = *ppEntry;
638
639 if (m_world != CurrentWorld() || !entry->m_entity) {
640 delete entry;
641 m_numEntries--;
642
643 if (m_numEntries != i) {
644 m_entries[i] = m_entries[m_numEntries];
645 m_entries[m_numEntries] = NULL;
646 }
647
648 break;
649 }
650
651 if (entry->m_time - time > 1000) {
652 break;
653 }
654
655 MxMatrix local90;
656 MxMatrix local48;
657
658 MxMatrix locald8(entry->m_roi->GetLocal2World());
659 Mx3DPointFloat localec(locald8[3]);
660
661 ZEROVEC3(locald8[3]);
662
663 locald8[1][0] = sin(((entry->m_time - time) * 2) * 0.0062832f) * 0.2;
664 locald8[1][2] = sin(((entry->m_time - time) * 4) * 0.0062832f) * 0.2;
665 locald8.Scale(1.03f, 0.95f, 1.03f);
666
667 SET3(locald8[3], localec);
668
669 entry->m_roi->FUN_100a58f0(locald8);
670 entry->m_roi->VTable0x14();
671
672 if (entry->m_time < time) {
673 LegoPlantInfo* info = GetInfo(entry->m_entity);
674
675 if (info->m_unk0x16 == 0) {
676 entry->m_roi->SetVisibility(FALSE);
677 }
678 else {
679 FUN_10026860(info - g_plantInfo);
680 info->m_entity->SetLocation(info->m_position, info->m_direction, info->m_up, FALSE);
681 }
682
683 delete entry;
684 m_numEntries--;
685
686 if (m_numEntries != i) {
687 i--;
688 *ppEntry = m_entries[m_numEntries];
689 m_entries[m_numEntries] = NULL;
690 }
691 }
692 }
693 }
694 else {
696 }
697
698 return SUCCESS;
699}
700
701// FUNCTION: LEGO1 0x10027120
703{
704 LegoWorld* world = CurrentWorld();
705
706 for (MxS32 i = 0; i < sizeOfArray(g_plantInfo); i++) {
707 g_plantInfo[i].m_unk0x16 = -1;
709 FUN_10026860(i);
710
711 if (g_plantInfo[i].m_entity != NULL) {
713 g_plantInfo[i].m_position,
714 g_plantInfo[i].m_direction,
715 g_plantInfo[i].m_up,
716 FALSE
717 );
718 }
719 }
720}
721
722// FUNCTION: LEGO1 0x100271b0
723void LegoPlantManager::FUN_100271b0(LegoEntity* p_entity, MxS32 p_adjust)
724{
725 LegoPlantInfo* info = GetInfo(p_entity);
726
727 if (info != NULL) {
728 if (info->m_unk0x16 < 0) {
729 info->m_unk0x16 = g_unk0x100f16c0[info->m_variant];
730 }
731
732 if (info->m_unk0x16 > 0) {
733 info->m_unk0x16 += p_adjust;
734 if (info->m_unk0x16 <= 1 && p_adjust < 0) {
735 info->m_unk0x16 = 0;
736 }
737 }
738 }
739}
740
741// FUNCTION: LEGO1 0x10027200
743{
744 for (MxU32 i = 0; i < sizeOfArray(g_plantInfo); i++) {
746 }
747}
Lego3DView * GetLego3DView()
[AI] Returns the encapsulated Lego3DView instance.
ViewManager * GetViewManager()
[AI] Returns the ViewManager responsible for managing scene objects and transformations.
Definition: lego3dview.h:154
LegoROI * CreateAutoROI(const char *p_name, const char *p_lodName, MxBool p_createEntity)
[AI] Creates an "auto" ROI object with the given name, LOD name, and optional entity creation.
MxResult FUN_10085870(LegoROI *p_roi)
[AI] Initializes auto-ROI with bounding volume and transformation.
void ReleaseAutoROI(LegoROI *p_roi)
[AI] Releases an "auto" ROI, used for dynamically created ROI objects by this manager.
[AI] Represents an entity that can be placed and managed in the LEGO Island world.
Definition: legoentity.h:16
void SetLocation(const Vector3 &p_location, const Vector3 &p_direction, const Vector3 &p_up, MxBool p_und)
[AI] Sets the world-space location, direction, and up, applying normalization and transformation.
Definition: legoentity.cpp:158
LegoROI * GetROI()
[AI] Gets the ROI (Realtime Object Instance) associated with this entity. [AI]
Definition: legoentity.h:161
void SetType(MxU8 p_type)
[AI] Sets the entity's type (actor/plant/building/etc.) [AI]
Definition: legoentity.cpp:459
@ e_plant
[AI] Plant objects in the game (e.g., trees or bushes) [AI]
Definition: legoentity.h:22
World
[AI] Identifiers for all unique, script-driven world environments in LEGO Island.
Definition: legomain.h:57
@ e_undefined
[AI] No world specified. [AI]
Definition: legomain.h:58
[AI] Represents a path segment or boundary in the navigation network for actors (vehicles,...
[AI] Manages the lifecycle, state, and properties for all plant objects (flowers, trees,...
void ScheduleAnimation(LegoEntity *p_entity, MxLong p_length)
[AI] Schedules an animation for the given plant, adding an entry to the internal tickle array.
~LegoPlantManager() override
[AI] Destructor.
MxBool SwitchSound(LegoEntity *p_entity)
[AI] Cycles the sound effect variant for a plant.
LegoEntity * CreatePlant(MxS32 p_index, LegoWorld *p_world, LegoOmni::World p_worldId)
[AI] Instantiates an entity and ROI for the plant at given index in world (if appropriate).
MxResult Read(LegoStorage *p_storage)
[AI] Rehydrates plant state from storage, restoring color/variant/mood/move properties.
void FUN_10027120()
[AI] Resets all growth/activity/animation state for all plants in the manager.
MxResult Write(LegoStorage *p_storage)
[AI] Serializes persistent plant state (color, variant, mood, animation, etc) to storage for save gam...
MxBool SwitchColor(LegoEntity *p_entity)
[AI] Cycles the color attribute for the plant and updates its LOD/appearance.
MxResult FUN_10026410()
[AI] Repairs/updates all plant boundary references and vertical position to match world boundaries/pl...
MxResult Tickle() override
[AI] Tickle handler for processing scheduled plant animation entries.
MxBool SwitchVariant(LegoEntity *p_entity)
[AI] Cycles the variant/type for a plant (flower, tree, bush, palm) and updates appearance.
MxU32 GetSoundId(LegoEntity *p_entity, MxBool p_state)
[AI] Returns the sound ID for a plant, used for localized SFX depending on mood/state.
void LoadWorldInfo(LegoOmni::World p_worldId)
[AI] Loads all plant objects/entities for the requested world, instantiates requisite ROIs and entiti...
MxBool FUN_10026c50(LegoEntity *p_entity)
[AI] Triggers a growth decrement or similar on a plant entity, and updates accordingly if possible.
LegoPlantManager()
[AI] Constructs the plant manager and initializes its bookkeeping to match the plant info array.
LegoPlantInfo * GetInfoArray(MxS32 &p_length)
[AI] Returns pointer to plant info array and populates its size.
void Init()
[AI] Zeroes out state, resets world ID, and copies default plant info to runtime plant info array.
MxBool SwitchMood(LegoEntity *p_entity)
[AI] Cycles the plant's "mood" state property (e.g., for appearance/hidden states) [AI]
void FUN_10027200()
[AI] Propagates all plants' current growth/activity state to their restore points.
MxS32 GetNumPlants()
[AI] Returns the total number of plant records referenced by this manager.
void Reset(LegoOmni::World p_worldId)
[AI] Completely resets (removes) all plant objects for the supplied world.
MxU32 GetAnimationId(LegoEntity *p_entity)
[AI] Returns the current animation ID for the given plant, based on its variant and move type.
static void SetCustomizeAnimFile(const char *p_value)
[AI] Sets the global file path or name to use for plant customization animations.
MxBool SwitchMove(LegoEntity *p_entity)
[AI] Cycles the movement/animation type for a plant.
[AI] Represents a Real-time Object Instance enriched with LEGO-specific functionality.
Definition: legoroi.h:43
LegoEntity * GetEntity()
[AI] Gets the entity associated with this ROI (or NULL).
Definition: legoroi.h:293
Abstract base class providing an interface for file-like storage with binary and text read/write oper...
Definition: legostorage.h:16
virtual LegoResult Write(const void *p_buffer, LegoU32 p_size)=0
Write bytes from buffer into storage.
virtual LegoResult Read(void *p_buffer, LegoU32 p_size)=0
Read bytes from storage into buffer.
Lego3DManager * Get3DManager()
[AI] Returns the Lego3DManager for this manager, which owns all 3D scene representations and view con...
LegoU8 GetNumEdges()
[AI] Returns the number of edge elements assigned to this face.
Definition: legoweedge.h:43
const LegoChar * GetName()
[AI] Returns the name string of this edge, typically used for debugging and lookup.
Definition: legowegedge.h:79
Mx4DPointFloat * GetEdgeNormal(int index)
[AI] Returns a pointer to the 4D edge normal at the given sub-edge index.
Definition: legowegedge.h:75
Mx4DPointFloat * GetUnknown0x14()
[AI] Returns a pointer to the cached 4D normal or reference plane for the edge.
Definition: legowegedge.h:70
Represents the active 3D world, holding all entity, animation, sound, path, and ROI objects.
Definition: legoworld.h:49
LegoPathBoundary * FindPathBoundary(const char *p_name)
Finds a path boundary in all path controllers by name.
Definition: legoworld.cpp:385
void Scale(const float &p_x, const float &p_y, const float &p_z)
Applies scaling factors along X, Y, and Z axes.
[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
float & index_operator(int idx)
[AI] Explicit indexed access wrapper (alias for operator[]).
Definition: mxgeometry4d.h:73
[AI] Represents a 4x4 transformation matrix, specialized for the LEGO Island engine and derived from ...
Definition: mxmatrix.h:16
virtual void UnregisterClient(MxCore *p_client)
[AI] Unregisters (marks for destruction) a previously registered client.
virtual void RegisterClient(MxCore *p_client, MxTime p_interval)
[AI] Registers an MxCore object to receive periodic tickles.
MxLong GetTime()
Returns the current timer value in ms, depending on running state.
Definition: mxtimer.h:50
const Matrix4 & GetLocal2World() const
Accessor for the current local-to-world transformation matrix.
virtual void VTable0x14()
[AI] Calls VTable0x1c().
Definition: orientableroi.h:64
void FUN_100a58f0(const Matrix4 &p_transform)
Assigns the given matrix as the local-to-world transformation and enables some internal flags.
void SetVisibility(unsigned char p_visible)
[AI] Sets the visibility flag to the provided value.
Definition: roi.h:235
virtual float Dot(const float *p_a, const float *p_b) const
[AI] Compute the dot product of the two float arrays interpreted as vectors of 2 elements.
ViewLODList * Lookup(const ROIName &) const
[AI] Looks up an existing ViewLODList by ROI name, incrementing its reference count.
[AI] Reference-counted list of Level-of-Detail (LOD) objects associated with a single ROI (Realtime O...
Definition: viewlodlist.h:30
int Release()
[AI] Decrements the reference count.
void RemoveROIDetailFromScene(ViewROI *p_roi)
[AI] Removes the currently active LOD detail from the rendering scene for the given ROI and detaches ...
int GetUnknown0xe0()
[AI] Gets the value of an internal state field at offset 0xe0.
Definition: viewroi.h:108
void SetLODList(ViewLODList *lodList)
[AI] Sets the ViewLODList for this ROI, managing reference counting.
Definition: viewroi.h:44
#define TRUE
Definition: d3drmdef.h:28
#define FALSE
Definition: d3drmdef.h:27
#define DECOMP_SIZE_ASSERT(T, S)
Definition: decomp.h:19
#define sizeOfArray(arr)
Definition: decomp.h:23
MxU8 g_unk0x100f16c0[]
const char * g_plantLodNames[4][5]
MxU32 g_plantAnimationId[4]
LegoPlantInfo g_plantInfo[81]
MxU32 g_unk0x100f3160
MxU32 g_unk0x100f3164
float g_unk0x100f16b0[]
LegoPlantInfo g_plantInfoInit[81]
[AI] Static global array of all initial plant data for the island (81 entries).
Definition: legoplants.cpp:6
#define NULL
[AI] Null pointer value (C/C++ semantics).
Definition: legotypes.h:26
#define FAILURE
[AI] Used to indicate a failed operation in result codes.
Definition: legotypes.h:34
#define SUCCESS
[AI] Used to indicate a successful operation in result codes.
Definition: legotypes.h:30
LegoVideoManager * VideoManager()
[AI] Accessor for the game's LegoVideoManager subsystem. Used for managing 3D/video hardware....
Definition: misc.cpp:29
LegoCharacterManager * CharacterManager()
[AI] Accessor for the character manager, which manages in-game characters/NPCs. [AI]
Definition: misc.cpp:101
void DeleteObjects(MxAtomId *p_id, MxS32 p_first, MxS32 p_last)
[AI] Batch deletes objects, given by atom id, and within the entity id range [p_first,...
Definition: misc.cpp:237
ViewLODListManager * GetViewLODListManager()
[AI] Returns the global ViewLODListManager for view LOD (Level of Detail) resources....
Definition: misc.cpp:136
LegoWorld * CurrentWorld()
[AI] Accessor for the currently active LegoWorld instance. [AI]
Definition: misc.cpp:93
#define MxTrace(args)
[AI] Macro for trace logging (non-variadic version, MSVC compatibility), expands to nothing.
Definition: mxdebug.h:55
MxTimer * Timer()
[AI] Returns the global simulation timer.
Definition: mxmisc.cpp:33
MxTickleManager * TickleManager()
[AI] Provides access to the global tickle manager.
Definition: mxmisc.cpp:25
MxU8 MxBool
[AI]
Definition: mxtypes.h:124
MxLong MxResult
[AI]
Definition: mxtypes.h:106
int MxLong
[AI]
Definition: mxtypes.h:83
unsigned char MxU8
[AI]
Definition: mxtypes.h:8
signed int MxS32
[AI]
Definition: mxtypes.h:38
unsigned int MxU32
[AI]
Definition: mxtypes.h:32
@ c_AnimBld18
[AI] Building animation 18. [AI]
@ c_AnimC1
[AI] Animation block C1. [AI]
[AI] Contains global script AtomId pointers and utility functions for managing script AtomIds in LEGO...
MxAtomId * g_sndAnimScript
[AI] Script AtomId for sound animation or related cutscenes.
Definition: scripts.cpp:85
[AI] Struct representing a single plant's static configuration on LEGO Island, including placement,...
Definition: legoplants.h:18
MxS8 m_initialUnk0x16
[AI] Initial value to be loaded into m_unk0x16 (reset/restore behavior) [AI]
Definition: legoplants.h:59
@ e_white
[AI] White
Definition: legoplants.h:44
@ e_green
[AI] Green
Definition: legoplants.h:48
MxU32 m_sound
[AI] Sound ID or sound group associated with this plant (e.g. upon interaction or environment event) ...
Definition: legoplants.h:54
MxU8 m_color
[AI] Color enum value, determines plant's rendering color [AI]
Definition: legoplants.h:57
MxS8 m_unk0x16
[AI] Unknown; appears to be a state variable, possibly animation frame or LOD index [AI]
Definition: legoplants.h:58
float m_direction[3]
[AI] Orientation direction vector, typically for forward orientation of plant (for animation/transfor...
Definition: legoplants.h:67
float m_up[3]
[AI] Up direction vector, typically (0,1,0) but can be used for skew or special display [AI]
Definition: legoplants.h:68
MxU8 m_variant
[AI] Variant enum value specifying geometry/model [AI]
Definition: legoplants.h:53
MxU32 m_move
[AI] Movement/action type (for animation, swaying, interactive move, etc.) [AI]
Definition: legoplants.h:55
LegoPathBoundary * m_boundary
[AI] Pointer to a collision or path boundary for this plant, if any [AI]
Definition: legoplants.h:65
float m_y
[AI] World Y position (vertical/elevation) [AI]
Definition: legoplants.h:63
@ e_palm
[AI] Palm tree
Definition: legoplants.h:38
@ e_flower
[AI] Standard flower
Definition: legoplants.h:35
MxU8 m_mood
[AI] Mood state; used for animation, facial expression, etc. [AI]
Definition: legoplants.h:56
LegoEntity * m_entity
[AI] Pointer to the associated entity instance (initialized later at runtime) [AI]
Definition: legoplants.h:51
float m_position[3]
[AI] Alternate position array (likely for display, reference, or bounding computations) [AI]
Definition: legoplants.h:66
[AI] Structure for scheduling plant ROI/entity animations (i.e.
MxLong m_time
[AI] When the animation should end (absolute time) [AI]
LegoROI * m_roi
[AI] ROI of the animated plant entity [AI]
LegoEntity * m_entity
[AI] Pointer to the plant entity being animated [AI]
#define SET3(to, from)
Definition: vec.h:310
#define ZEROVEC3(v)
Definition: vec.h:334