Isle
Loading...
Searching...
No Matches
legoracers.cpp
Go to the documentation of this file.
1#include "legoracers.h"
2
3#include "anim/legoanim.h"
4#include "carrace.h"
5#include "define.h"
6#include "jetskirace.h"
9#include "legonavcontroller.h"
10#include "legorace.h"
11#include "legoracers.h"
12#include "legosoundmanager.h"
13#include "misc.h"
14#include "mxdebug.h"
15#include "mxmisc.h"
17#include "mxtimer.h"
18#include "mxutilities.h"
19#include "mxvariabletable.h"
20#include "raceskel.h"
21
26
27// name verified by BETA10 0x100cbee6
28// GLOBAL: LEGO1 0x100f0a20
29// GLOBAL: BETA10 0x101f5e30
31 {// STRING: LEGO1 0x100f0a10
32 "EDG03_772",
33 NULL
34 },
35 {// STRING: LEGO1 0x100f0a04
36 "EDG03_773",
37 NULL
38 },
39 {// STRING: LEGO1 0x100f09f8
40 "EDG03_774",
41 NULL
42 },
43 {// STRING: LEGO1 0x100f09ec
44 "EDG03_775",
45 NULL
46 },
47 {// STRING: LEGO1 0x100f09e0
48 "EDG03_776",
49 NULL
50 },
51 {// STRING: LEGO1 0x100f09d4
52 "EDG03_777",
53 NULL
54 }
55};
56
57// GLOBAL: LEGO1 0x100f0a50
58// GLOBAL: BETA10 0x101f5e60
60 {&g_skBMap[0], 0.1, 0.2, LEGORACECAR_KICK2},
61 {&g_skBMap[1], 0.2, 0.3, LEGORACECAR_KICK2},
62 {&g_skBMap[2], 0.3, 0.4, LEGORACECAR_KICK2},
63 {&g_skBMap[2], 0.6, 0.7, LEGORACECAR_KICK1},
64 {&g_skBMap[1], 0.7, 0.8, LEGORACECAR_KICK1},
65 {&g_skBMap[0], 0.8, 0.9, LEGORACECAR_KICK1},
66 {&g_skBMap[3], 0.1, 0.2, LEGORACECAR_KICK1},
67 {&g_skBMap[4], 0.2, 0.3, LEGORACECAR_KICK1},
68 {&g_skBMap[5], 0.3, 0.4, LEGORACECAR_KICK1},
69 {&g_skBMap[5], 0.6, 0.7, LEGORACECAR_KICK2},
70 {&g_skBMap[4], 0.7, 0.8, LEGORACECAR_KICK2},
71 {&g_skBMap[3], 0.8, 0.9, LEGORACECAR_KICK2},
72};
73
74// the STRING is already declared at LEGO1 0x101020b8
75// GLOBAL: LEGO1 0x100f0b10
76const char* g_strSpeed = "SPEED";
77
78// GLOBAL: LEGO1 0x100f0b14
79const char* g_strJetSpeed = "jetSPEED";
80
81// GLOBAL: LEGO1 0x100f0b18
82// GLOBAL: BETA10 0x101f5f28
83const char* g_playerHitStudsSounds[] = {
84 "srt018sl",
85 "srt019sl",
86 "srt020sl",
87 "srt021sl",
88 "srt022sl",
89 "srt023sl",
90 "srt024sl",
91 "srt025sl",
92 "srt026sl",
93 "srt027sl",
94 "srt028sl",
95 "srt029sl"
96};
97
98// GLOBAL: LEGO1 0x100f0b48
99// GLOBAL: BETA10 0x101f5f58
100const char* g_studsHitPlayerSounds[] = {"srt006sl", "srt007sl", "srt008sl", "srt009sl", "srt010sl"};
101
102// GLOBAL: LEGO1 0x100f0b5c
103// GLOBAL: BETA10 0x101f5f6c
104const char* g_playerHitRhodaSounds[] = {NULL};
105
106// GLOBAL: LEGO1 0x100f0b60
107// GLOBAL: BETA10 0x101f5f70
108const char* g_rhodaHitPlayerSounds[] = {"srt004rh", "srt005rh", "srt006rh"};
109
110// GLOBAL: LEGO1 0x100f0b6c
111// STRING: LEGO1 0x100f08c4
112const char* g_youCantStopSound = "srt001ra";
113
114// GLOBAL: LEGO1 0x100f0b70
115// STRING: LEGO1 0x100f08bc
116const char* g_soundSkel3 = "skel3";
117
118// GLOBAL: LEGO1 0x100f0b74
119// GLOBAL: BETA10 0x101f5f80
121
122// GLOBAL: LEGO1 0x100f0b78
123// GLOBAL: BETA10 0x101f5f84
125
126// GLOBAL: LEGO1 0x100f0b7c
127// GLOBAL: BETA10 0x101f5f88
129
130// GLOBAL: LEGO1 0x100f0b80
131// GLOBAL: BETA10 0x101f5f8c
133
134// GLOBAL: LEGO1 0x100f0b84
135// GLOBAL: BETA10 0x101f5f90
137
138// GLOBAL: LEGO1 0x100f0b88
139// GLOBAL: BETA10 0x101f5f94
141
142// GLOBAL: LEGO1 0x100f0b8c
143// GLOBAL: BETA10 0x101f5f98
145
146// GLOBAL: LEGO1 0x100f0b90
147const char* g_hitSnapSounds[] = {
148 "Svo001Sn",
149 "Svo002Sn",
150 "Svo004Sn",
151 "Svo005Sn",
152};
153
154// GLOBAL: LEGO1 0x100f0ba0
155const char* g_hitValerieSounds[] = {
156 "Svo001Va",
157 "Svo003Va",
158 "Svo004Va",
159};
160
161// GLOBAL: LEGO1 0x100f0bac
163
164// GLOBAL: LEGO1 0x100f0bb0
166
167// GLOBAL: LEGO1 0x100f0bb4
169
170// FUNCTION: LEGO1 0x10012950
171// FUNCTION: BETA10 0x100cad10
173{
174 m_userState = 0;
175 m_skelKick1Anim = 0;
176 m_skelKick2Anim = 0;
177 m_unk0x5c.Clear();
178 m_unk0x58 = 0;
179 m_kick1B = 0;
180 m_kick2B = 0;
182}
183
184// FUNCTION: LEGO1 0x10012c80
185// FUNCTION: BETA10 0x100caf67
187{
189}
190
191// FUNCTION: LEGO1 0x10012d90
192// FUNCTION: BETA10 0x100cb0bd
194{
195 return LegoRaceMap::Notify(p_param);
196}
197
198// Initialized at LEGO1 0x10012db0
199// GLOBAL: LEGO1 0x10102af0
200// GLOBAL: BETA10 0x102114c0
202
203// FUNCTION: LEGO1 0x10012de0
205{
206 // Init to TRUE so we don't play "you can't stop in the middle of the race!" before the player ever moves
210}
211
212// FUNCTION: LEGO1 0x10012e00
213// FUNCTION: BETA10 0x100cb129
215{
216 // Note the (likely unintentional) order of operations: `%` is executed before `/`,
217 // so the division is performed at runtime.
222}
223
224// FUNCTION: LEGO1 0x10012e60
225// FUNCTION: BETA10 0x100cb191
227{
228 if (!m_userNavFlag) {
230 m_maxLinearVel = p_worldSpeed;
231 }
232 LegoAnimActor::SetWorldSpeed(p_worldSpeed);
233 }
234 else {
235 LegoEntity::SetWorldSpeed(p_worldSpeed);
236 }
237}
238
239// FUNCTION: LEGO1 0x10012ea0
240// FUNCTION: BETA10 0x100cb220
241void LegoRaceCar::SetMaxLinearVelocity(float p_maxLinearVelocity)
242{
243 if (p_maxLinearVelocity < 0) {
245 m_maxLinearVel = 0;
246 SetWorldSpeed(0);
247 }
248 else {
249 m_maxLinearVel = p_maxLinearVelocity;
250 }
251}
252
253// FUNCTION: LEGO1 0x10012ef0
254// FUNCTION: BETA10 0x100cb2aa
255void LegoRaceCar::ParseAction(char* p_extra)
256{
257 char buffer[256];
258
261 LegoRace* currentWorld = (LegoRace*) CurrentWorld();
262
263 if (KeyValueStringParse(buffer, g_strCOMP, p_extra) && currentWorld) {
264 currentWorld->VTable0x7c(this, atoi(buffer));
265 }
266
267 if (m_userNavFlag) {
268 MxS32 i;
269
270 for (i = 0; i < m_animMaps.size(); i++) {
271 if (m_animMaps[i]->GetUnknown0x00() == -1.0f) {
272 m_skelKick1Anim = m_animMaps[i];
273 }
274 else if (m_animMaps[i]->GetUnknown0x00() == -2.0f) {
275 m_skelKick2Anim = m_animMaps[i];
276 }
277 }
278
279 assert(m_skelKick1Anim && m_skelKick2Anim);
280
281 // STRING: LEGO1 0x100f0bc4
282 m_kick1B = currentWorld->FindPathBoundary("EDG03_44");
283 assert(m_kick1B);
284
285 // STRING: LEGO1 0x100f0bb8
286 m_kick2B = currentWorld->FindPathBoundary("EDG03_54");
287 assert(m_kick2B);
288
289 for (i = 0; i < sizeOfArray(g_skBMap); i++) {
290 assert(g_skBMap[i].m_name);
291 g_skBMap[i].m_b = currentWorld->FindPathBoundary(g_skBMap[i].m_name);
292 assert(g_skBMap[i].m_b);
293 }
294 }
295}
296
297// FUNCTION: LEGO1 0x10012ff0
298// FUNCTION: BETA10 0x100cb60e
299void LegoRaceCar::FUN_10012ff0(float p_param)
300{
301 LegoAnimActorStruct* a; // called `a` in BETA10
302 float deltaTime;
303
304 if (m_userState == LEGORACECAR_KICK1) {
305 a = m_skelKick1Anim;
306 }
307 else {
308 assert(m_userState == LEGORACECAR_KICK2);
309 a = m_skelKick2Anim;
310 }
311
312 assert(a && a->GetAnimTreePtr() && a->GetAnimTreePtr()->GetCamAnim());
313
314 if (a->GetAnimTreePtr()) {
315 deltaTime = p_param - m_unk0x58;
316
317 if (a->GetDuration() <= deltaTime || deltaTime < 0.0) {
318 if (m_userState == LEGORACECAR_KICK1) {
319 LegoUnknown100db7f4** edges = m_kick1B->GetEdges();
320 m_destEdge = edges[2];
321 m_boundary = m_kick1B;
322 }
323 else {
324 LegoUnknown100db7f4** edges = m_kick1B->GetEdges();
325 m_destEdge = edges[1];
326 m_boundary = m_kick2B;
327 }
328
329 m_userState = LEGORACECAR_UNKNOWN_0;
330 }
331 else if (a->GetAnimTreePtr()->GetCamAnim()) {
332 MxMatrix transformationMatrix;
333
334 LegoWorld* r = CurrentWorld(); // called `r` in BETA10
335 assert(r);
336
337 transformationMatrix.SetIdentity();
338
339 // Possible bug in the original code: The first argument is not initialized
340 a->GetAnimTreePtr()->GetCamAnim()->FUN_1009f490(deltaTime, transformationMatrix);
341
342 if (r->GetCameraController()) {
343 r->GetCameraController()->FUN_100123e0(transformationMatrix, 0);
344 }
345
346 m_roi->FUN_100a58f0(transformationMatrix);
347 }
348 }
349}
350
351// FUNCTION: LEGO1 0x10013130
352// FUNCTION: BETA10 0x100cce50
354{
356
357 CarRace* r = (CarRace*) CurrentWorld(); // called `r` in BETA10
358 assert(r);
359
360 RaceSkel* s = r->GetSkeleton(); // called `s` in BETA10
361 assert(s);
362
363 float skeletonCurAnimPosition;
364 float skeletonCurAnimDuration;
365
366 s->GetCurrentAnimData(&skeletonCurAnimPosition, &skeletonCurAnimDuration);
367
368 float skeletonCurAnimPhase = skeletonCurAnimPosition / skeletonCurAnimDuration;
369
370 for (MxS32 i = 0; i < sizeOfArray(g_skeletonKickPhases); i++) {
371 if (m_boundary == current->m_edgeRef->m_b && current->m_lower <= skeletonCurAnimPhase &&
372 skeletonCurAnimPhase <= current->m_upper) {
373 m_userState = current->m_userState;
374 }
375 current = &current[1];
376 }
377
378 if (m_userState != LEGORACECAR_KICK1 && m_userState != LEGORACECAR_KICK2) {
379 MxTrace(
380 // STRING: BETA10 0x101f64c8
381 "Got kicked in boundary %s %d %g:%g %g\n",
383 skeletonCurAnimPosition,
384 skeletonCurAnimDuration,
385 skeletonCurAnimPhase
386 );
387 return FALSE;
388 }
389
390 m_unk0x58 = p_param1;
392
393 return TRUE;
394}
395
396// FUNCTION: LEGO1 0x100131f0
397// FUNCTION: BETA10 0x100cb88a
398void LegoRaceCar::Animate(float p_time)
399{
400 if (m_userNavFlag && (m_userState == LEGORACECAR_KICK1 || m_userState == LEGORACECAR_KICK2)) {
401 FUN_10012ff0(p_time);
402 return;
403 }
404
406
407 if (m_userNavFlag && m_userState == LEGORACECAR_UNKNOWN_1) {
408 if (HandleSkeletonKicks(p_time)) {
409 return;
410 }
411 }
412
414 FUN_1005d4b0();
415
416 if (!m_userNavFlag) {
417 FUN_10080590(p_time);
418 return;
419 }
420
421 float absoluteSpeed = abs(m_worldSpeed);
422 float maximumSpeed = NavController()->GetMaxLinearVel();
423 char buffer[200];
424
425 sprintf(buffer, "%g", absoluteSpeed / maximumSpeed);
426
428
429 if (m_sound) {
430 // pitches up the engine sound based on the velocity
431 if (absoluteSpeed > 0.83 * maximumSpeed) {
432 m_frequencyFactor = 1.9f;
433 }
434 else {
435 // this value seems to simulate RPM based on the gear
436 MxS32 gearRpmFactor = (MxS32) (6.0 * absoluteSpeed) % 100;
437 m_frequencyFactor = gearRpmFactor / 80.0 + 0.7;
438 }
439 }
440
441 // If the player is moving forwards or backwards
442 if (absoluteSpeed != 0.0f) {
443 g_timePlayerLastMoved = p_time;
445 }
446
447 // If the player hasn't moved in 5 seconds, play the "you can't stop in the middle of the race!" sound once
448 if (p_time - g_timePlayerLastMoved > 5000.0f && !g_playedYouCantStopSound) {
451 }
452 }
453}
454
455// FUNCTION: LEGO1 0x100133c0
456// FUNCTION: BETA10 0x100cbb84
458{
459 // Note: Code duplication with LegoRaceActor::HitActor
460 if (!p_actor->GetUserNavFlag()) {
461 if (p_actor->GetActorState() != c_initial) {
462 return FAILURE;
463 }
464
465 if (p_bool) {
466 MxMatrix matr;
467 LegoROI* roi = p_actor->GetROI(); // name verified by BETA10 0x100cbbf5
468 assert(roi);
469 matr = roi->GetLocal2World();
470
471 Vector3(matr[3]) += g_unk0x10102af0;
472 roi->FUN_100a58f0(matr);
473
474 p_actor->SetActorState(c_two);
475 }
476
477 if (m_userNavFlag) {
478 MxBool actorIsStuds = strcmpi(p_actor->GetROI()->GetName(), "studs") == 0;
479 MxBool actorIsRhoda = strcmpi(p_actor->GetROI()->GetName(), "rhoda") == 0;
480 MxLong time = Timer()->GetTime();
481
482 const char* soundKey = NULL;
483
484 if (time - g_timeLastRaceCarSoundPlayed > 3000) {
485 if (p_bool) {
486 if (actorIsStuds) {
490 }
491 }
492 else if (actorIsRhoda) {
496 }
497 }
498 }
499 else {
500 if (actorIsStuds) {
504 }
505 }
506 else if (actorIsRhoda) {
510 }
511 }
512 }
513
514 if (soundKey) {
517 }
518 }
519
520 if (p_bool) {
521 return m_worldSpeed != 0 ? SUCCESS : FAILURE;
522 }
523 else {
524 return FAILURE;
525 }
526 }
527 }
528
529 return SUCCESS;
530}
531
532// FUNCTION: LEGO1 0x10013600
533// FUNCTION: BETA10 0x100cbe60
535{
536 MxResult result;
537
538 if (m_userNavFlag) {
540
541 if (m_boundary) {
542 MxS32 bVar2 = 0;
543
544 for (MxS32 i = 0; i < sizeOfArray(g_skBMap); i++) {
545 assert(g_skBMap[i].m_b);
546 if (m_boundary == g_skBMap[i].m_b) {
547 bVar2 = 1;
548 break;
549 }
550 }
551
552 if (m_userState == LEGORACECAR_UNKNOWN_1) {
553 if (!bVar2) {
554 m_userState = LEGORACECAR_UNKNOWN_0;
555 }
556 }
557 else {
558 m_userState = LEGORACECAR_UNKNOWN_1;
559 }
560 }
561 }
562 else {
564 }
565
566 return result;
567}
568
569// FUNCTION: LEGO1 0x10013670
571{
572 // See note in LegoRaceCar::InitSoundIndices
573 g_hitSnapSoundsIndex = rand() % sizeof(g_hitSnapSounds) / sizeof(g_hitSnapSounds[0]);
574 g_hitValerieSoundsIndex = rand() % sizeof(g_hitValerieSounds) / sizeof(g_hitValerieSounds[0]);
575}
576
577// FUNCTION: LEGO1 0x100136a0
578// FUNCTION: BETA10 0x100cbf7e
580{
581 if (!m_userNavFlag) {
583 m_maxLinearVel = p_worldSpeed;
584 }
585 LegoAnimActor::SetWorldSpeed(p_worldSpeed);
586 }
587 else {
588 LegoEntity::SetWorldSpeed(p_worldSpeed);
589 }
590}
591
592// FUNCTION: LEGO1 0x100136f0
593// FUNCTION: BETA10 0x100cc01a
594void LegoJetski::FUN_100136f0(float p_worldSpeed)
595{
596 if (p_worldSpeed < 0) {
598 m_maxLinearVel = 0;
599 SetWorldSpeed(0);
600 }
601 else {
602 m_maxLinearVel = p_worldSpeed;
603 }
604}
605
606// FUNCTION: LEGO1 0x10013740
607// FUNCTION: BETA10 0x100cc0ae
608void LegoJetski::Animate(float p_time)
609{
611
613 FUN_1005d4b0();
614
615 if (!m_userNavFlag) {
616 FUN_10080590(p_time);
617 return;
618 }
619
620 float absoluteSpeed = abs(m_worldSpeed);
621 float speedRatio = absoluteSpeed / NavController()->GetMaxLinearVel();
622 char buffer[200];
623
624 sprintf(buffer, "%g", speedRatio);
625
627
628 if (m_sound) {
629 m_frequencyFactor = speedRatio * 1.2 + 0.7;
630 }
631 }
632}
633
634// FUNCTION: LEGO1 0x10013820
635// FUNCTION: BETA10 0x100cc335
637{
639}
640
641// FUNCTION: LEGO1 0x10013aa0
642// FUNCTION: BETA10 0x100cc58e
644{
646}
647
648// FUNCTION: LEGO1 0x10013bb0
649// FUNCTION: BETA10 0x100cc6df
650void LegoJetski::ParseAction(char* p_extra)
651{
652 char buffer[256];
653
656 JetskiRace* currentWorld = (JetskiRace*) CurrentWorld();
657
658 if (KeyValueStringParse(buffer, g_strCOMP, p_extra) && currentWorld) {
659 currentWorld->VTable0x7c(this, atoi(buffer));
660 }
661}
662
663// FUNCTION: LEGO1 0x10013c30
664// FUNCTION: BETA10 0x100cc76a
666{
667 return LegoRaceMap::Notify(p_param);
668}
669
670// FUNCTION: LEGO1 0x10013c40
672{
673 // Note: very similar to LegoRaceCar::HitActor
674
675 if (!p_actor->GetUserNavFlag()) {
676 if (p_actor->GetActorState() != c_initial) {
677 return FAILURE;
678 }
679
680 if (p_bool) {
681 MxMatrix matr;
682 LegoROI* roi = p_actor->GetROI();
683 matr = roi->GetLocal2World();
684
685 Vector3(matr[3]) += g_unk0x10102af0;
686 roi->FUN_100a58f0(matr);
687
688 p_actor->SetActorState(c_two);
689 }
690
691 if (m_userNavFlag) {
692 MxBool actorIsSnap = strcmpi(p_actor->GetROI()->GetName(), "snap") == 0;
693 MxBool actorIsValerie = strcmpi(p_actor->GetROI()->GetName(), "valerie") == 0;
694 MxLong time = Timer()->GetTime();
695
696 const char* soundKey = NULL;
697
698 if (time - g_timeLastJetskiSoundPlayed > 3000) {
699 if (actorIsSnap) {
703 }
704 }
705 else if (actorIsValerie) {
709 }
710 }
711
712 if (soundKey) {
715 }
716 }
717
718 if (p_bool) {
719 return m_worldSpeed != 0 ? SUCCESS : FAILURE;
720 }
721 else {
722 return FAILURE;
723 }
724 }
725 }
726
727 return SUCCESS;
728}
Implements the LEGO Island car race game mode.
Definition: carrace.h:53
RaceSkel * GetSkeleton()
Provides access to the RaceSkel (race skeleton) object managing actor animations or kinematics.
Definition: carrace.h:138
[AI] LEGO Island's "Jetski" racing game logic and presenter class, derived from LegoRace.
Definition: jetskirace.h:13
LegoCacheSound * m_sound
[AI] Pointer to a currently active sound instance played by the actor, if any.
Definition: legoactor.h:95
MxFloat m_frequencyFactor
[AI] The frequency/pitch scaling factor for the actor's sound (default 0 == normal).
Definition: legoactor.h:94
void ParseAction(char *p_extra) override
[AI] Handles extra action strings, looks for animation assignments and delegates to presenters (overr...
void SetWorldSpeed(MxFloat p_worldSpeed) override
[AI] Sets the current world speed and chooses which animation (from the animation map list) should be...
vector< LegoAnimActorStruct * > m_animMaps
[AI] List of animation structures, each representing a valid animation for different speed/phase rang...
LegoResult FUN_1009f490(LegoFloat p_time, Matrix4 &p_matrix)
[AI] Evaluates this scene's animation at the given time, updating the passed matrix.
Definition: legoanim.cpp:202
LegoAnimScene * GetCamAnim()
[AI] Gets the optional camera/scene animation track.
Definition: legoanim.h:378
LegoCacheSound * Play(const char *p_key, const char *p_name, MxBool p_looping)
[AI] Plays a sound identified by key, with the given playback name and looping flag.
void FUN_100123e0(const Matrix4 &p_transform, MxU32 p_und)
Sets the camera's transformation matrix in the 3D view, optionally applying a blend with the internal...
MxResult VTable0x9c() override
[AI] Handles the transition at key animation logic points, such as the end/start of edges and boundar...
virtual void FUN_10080590(float p_time)
[AI] Adjusts the target and acceleration for the car based on path, player position,...
MxU8 m_unk0x0c
[AI] State variable/fsm controlling the actor's current animation/logic state. [AI]
void Animate(float p_time) override
[AI] Main per-frame update for the car racer, controls activation of animation and state switching ba...
virtual void SetWorldSpeed(MxFloat p_worldSpeed)
[AI] Sets the current world speed value for this entity (used to control motion/animation rate).
Definition: legoentity.h:98
LegoROI * GetROI()
[AI] Gets the ROI (Realtime Object Instance) associated with this entity. [AI]
Definition: legoentity.h:161
MxFloat m_worldSpeed
[AI] World-relative speed (can affect animation/movement logic). [AI]
Definition: legoentity.h:212
LegoROI * m_roi
[AI] Pointer to this entity's currently assigned ROI (3D instance in the world). [AI]
Definition: legoentity.h:215
void Animate(float p_time) override
[AI] Per-frame logic and animation for jetski racing - enables racing state and syncs with variables....
[AI] Represents a Jetski actor in the race, combining behavior from LegoJetskiRaceActor and LegoRaceM...
Definition: legoracers.h:60
static void InitSoundIndices()
[AI] Initializes static indices for jetski-specific sound arrays to randomized starting positions.
Definition: legoracers.cpp:570
void ParseAction(char *p_extra) override
[AI] Parses an action string to configure or trigger Jetski behaviors such as switching race boundari...
Definition: legoracers.cpp:650
void SetWorldSpeed(MxFloat p_worldSpeed) override
[AI] Sets world speed for the jetski, influencing both physics and animation logic.
Definition: legoracers.cpp:579
MxLong Notify(MxParam &p_param) override
[AI] Processes notifications/events for the LegoJetski instance (see MxCore).
Definition: legoracers.cpp:665
virtual void FUN_100136f0(float p_worldSpeed)
[AI] Custom world speed handler for clamping or setting maximum velocity for the jetski.
Definition: legoracers.cpp:594
~LegoJetski() override
Definition: legoracers.cpp:643
MxResult HitActor(LegoPathActor *p_actor, MxBool p_bool) override
[AI] Handles collision/hit logic between this jetski and another race actor.
Definition: legoracers.cpp:671
void Animate(float p_time) override
[AI] Updates jetski animation for the current frame.
Definition: legoracers.cpp:608
MxFloat GetMaxLinearVel()
[AI] Returns the current maximum linear velocity (units per sec).
[AI] An actor that moves along a predefined path, supporting boundary transitions,...
Definition: legopathactor.h:32
MxFloat m_maxLinearVel
[AI] Maximum speed of actor while moving along path. [AI]
MxU32 GetActorState()
[AI] Gets the current navigation/animation state of the actor.
LegoUnknown100db7f4 * m_destEdge
[AI] Current or target edge for path traversal. [AI]
virtual MxBool GetUserNavFlag()
[AI] Returns user navigation state (whether actor follows player input).
LegoPathBoundary * m_boundary
[AI] Current boundary the actor is navigating on. [AI]
@ c_initial
[AI] Default state upon creation or reset. [AI]
Definition: legopathactor.h:37
MxBool m_userNavFlag
[AI] TRUE if this actor is currently user/player controlled. [AI]
void SetActorState(MxU32 p_actorState)
[AI] Sets the navigation/path state of the actor.
[AI] Represents a Real-time Object Instance enriched with LEGO-specific functionality.
Definition: legoroi.h:43
const LegoChar * GetName() const
[AI] Gets this ROI's name.
Definition: legoroi.h:287
[AI] Represents a Race Car actor in the game, combining advanced pathing, skeleton kick logic,...
Definition: legoracers.h:167
void ParseAction(char *p_extra) override
[AI] Parses an action string to configure or trigger car behaviors (e.g., updates kick animation refe...
Definition: legoracers.cpp:255
MxResult HitActor(LegoPathActor *p_actor, MxBool p_bool) override
[AI] Handles player/AI actor collision—score, animation, and sound effects, as well as respawn logic ...
Definition: legoracers.cpp:457
static void InitSoundIndices()
[AI] Initializes sound playback array indices for collision sounds to randomized values.
Definition: legoracers.cpp:214
~LegoRaceCar() override
Definition: legoracers.cpp:186
MxLong Notify(MxParam &p_param) override
[AI] Processes notifications/events for the LegoRaceCar (see MxCore).
Definition: legoracers.cpp:193
void Animate(float p_time) override
[AI] Main animation tick function; handles skeleton kick special states when user-controlled.
Definition: legoracers.cpp:398
void SetWorldSpeed(MxFloat p_worldSpeed) override
[AI] Sets world speed for the race car, either for user nav or animation context.
Definition: legoracers.cpp:226
virtual MxU32 HandleSkeletonKicks(float p_param1)
[AI] Handles transition between skeleton kick phases based on animation time and current boundary.
Definition: legoracers.cpp:353
virtual void SetMaxLinearVelocity(float p_maxLinearVelocity)
[AI] Sets the maximum linear velocity the car is allowed to attain (and can force 0 for "despawn" eff...
Definition: legoracers.cpp:241
static void FUN_10012de0()
[AI] Resets static sound state variables for the car (last sound time, stopped flag,...
Definition: legoracers.cpp:204
MxResult VTable0x9c() override
[AI] Finalizes animation phase/post-kick state machine.
Definition: legoracers.cpp:534
virtual void FUN_10012ff0(float p_param)
[AI] Handles skeleton kick transition logic for given time; switches state as needed.
Definition: legoracers.cpp:299
virtual void FUN_1005d4b0()
[AI] Updates the minimap overlay position and enables/disables the overlay image as needed.
MxLong Notify(MxParam &p_param) override
[AI] Handles notifications, especially for UI control interactions (e.g., clicking the map control to...
void ParseAction(char *p_extra) override
[AI] Parses action strings for map locator and geometry mapping and links control and map geometry to...
Definition: legoracemap.cpp:41
[AI] Base class for all race-type LegoWorlds.
Definition: legorace.h:149
virtual void VTable0x7c(LegoRaceMap *p_map, MxU32 p_index)
[AI] Associates a race map instance to the maps array at the given index.
Definition: legorace.h:243
LegoCacheSoundManager * GetCacheSoundManager()
[AI] Returns the cache sound manager used to cache and reuse sound effects.
LegoUnknown100db7f4 ** GetEdges()
[AI] Gets the array of pointers to the edge objects that form this face.
Definition: legoweedge.h:49
const LegoChar * GetName()
[AI] Returns the name string of this edge, typically used for debugging and lookup.
Definition: legowegedge.h:79
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
LegoCameraController * GetCameraController()
Returns the current camera controller for the world.
Definition: legoworld.h:277
virtual void SetIdentity()
Sets this matrix to identity (diagonal 1, others 0).
[AI] Represents a 3D point with floating-point precision, inheriting from Vector3.
Definition: mxgeometry3d.h:14
[AI] Represents a 4x4 transformation matrix, specialized for the LEGO Island engine and derived from ...
Definition: mxmatrix.h:16
void Unregister(MxCore *p_listener)
[AI] Removes a previously registered listener and flushes any pending notifications for it.
void Register(MxCore *p_listener)
[AI] Registers a listener object to receive notifications.
[AI] MxParam serves as a polymorphic base class for parameter passing in event and notification syste...
Definition: mxparam.h:7
MxLong GetTime()
Returns the current timer value in ms, depending on running state.
Definition: mxtimer.h:50
void SetVariable(const char *p_key, const char *p_value)
Sets a variable by key and value, replacing or updating if it exists.
const Matrix4 & GetLocal2World() const
Accessor for the current local-to-world transformation matrix.
void FUN_100a58f0(const Matrix4 &p_transform)
Assigns the given matrix as the local-to-world transformation and enables some internal flags.
[AI] Specialized skeleton animation actor for LEGO Island car racing sequences.
Definition: raceskel.h:24
void GetCurrentAnimData(float *p_outCurAnimPosition, float *p_outCurAnimDuration)
[AI] Retrieves the current animation position and its duration.
Definition: raceskel.cpp:64
[AI] 3D vector class, providing vector and cross-product operations in 3D space.
Definition: vector.h:249
void Clear() override
[AI] Sets every coordinate (x, y, z) to zero.
#define TRUE
Definition: d3drmdef.h:28
#define FALSE
Definition: d3drmdef.h:27
#define DECOMP_SIZE_ASSERT(T, S)
Definition: decomp.h:19
unsigned int undefined4
Definition: decomp.h:28
#define sizeOfArray(arr)
Definition: decomp.h:23
const char * g_strCOMP
[AI] Used to identify comparison operations, likely for variable or trigger checks in scripts.
Definition: define.cpp:133
MxLong g_unk0x100f3308
[AI] Timer for wall hit sound playback throttling in navigation [AI]
undefined4 g_hitSnapSoundsIndex
Definition: legoracers.cpp:162
MxLong g_timeLastJetskiSoundPlayed
Definition: legoracers.cpp:168
const SkeletonKickPhase g_skeletonKickPhases[]
Definition: legoracers.cpp:59
const char * g_strJetSpeed
Definition: legoracers.cpp:79
const char * g_rhodaHitPlayerSounds[]
Definition: legoracers.cpp:108
MxU32 g_playerHitRhodaSoundsIndex
Definition: legoracers.cpp:128
const char * g_youCantStopSound
Definition: legoracers.cpp:112
MxBool g_playedYouCantStopSound
Definition: legoracers.cpp:144
const char * g_hitSnapSounds[]
Definition: legoracers.cpp:147
MxU32 g_playerHitStudsSoundsIndex
Definition: legoracers.cpp:120
EdgeReference g_skBMap[]
Definition: legoracers.cpp:30
const char * g_studsHitPlayerSounds[]
Definition: legoracers.cpp:100
MxU32 g_rhodaHitPlayerSoundsIndex
Definition: legoracers.cpp:132
const char * g_strSpeed
Definition: legoracers.cpp:76
const char * g_hitValerieSounds[]
Definition: legoracers.cpp:155
undefined4 g_hitValerieSoundsIndex
Definition: legoracers.cpp:165
MxU32 g_studsHitPlayerSoundsIndex
Definition: legoracers.cpp:124
const char * g_playerHitStudsSounds[]
Definition: legoracers.cpp:83
const char * g_playerHitRhodaSounds[]
Definition: legoracers.cpp:104
MxLong g_timeLastRaceCarSoundPlayed
Definition: legoracers.cpp:136
Mx3DPointFloat g_unk0x10102af0
Definition: legoracers.cpp:201
MxS32 g_timePlayerLastMoved
Definition: legoracers.cpp:140
const char * g_soundSkel3
Definition: legoracers.cpp:116
#define LEGORACECAR_KICK2
[AI] User state identifier for LegoRaceCar in "kick2" action/animation state.
Definition: legoracers.h:31
#define LEGORACECAR_KICK1
[AI] User state identifier for LegoRaceCar in "kick1" action/animation state.
Definition: legoracers.h:25
#define LEGORACECAR_UNKNOWN_0
[AI] User state identifier for LegoRaceCar (unknown purpose—likely "neutral/idle").
Definition: legoracers.h:13
#define LEGORACECAR_UNKNOWN_1
[AI] User state identifier for LegoRaceCar (unknown purpose—likely "in kick/transition state").
Definition: legoracers.h:19
#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
LegoSoundManager * SoundManager()
[AI] Accessor for the game's LegoSoundManager subsystem from the global LegoOmni instance....
Definition: misc.cpp:22
LegoWorld * CurrentWorld()
[AI] Accessor for the currently active LegoWorld instance. [AI]
Definition: misc.cpp:93
LegoNavController * NavController()
[AI] Accessor for the navigation controller, managing player/camera navigation. [AI]
Definition: misc.cpp:77
#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
MxVariableTable * VariableTable()
[AI] Returns the variable table used for script variables and global key/value state.
Definition: mxmisc.cpp:73
MxNotificationManager * NotificationManager()
[AI] Returns the notification manager for system-wide state/update notifications.
Definition: mxmisc.cpp:17
MxU8 MxBool
[AI]
Definition: mxtypes.h:124
MxLong MxResult
[AI]
Definition: mxtypes.h:106
int MxLong
[AI]
Definition: mxtypes.h:83
float MxFloat
[AI]
Definition: mxtypes.h:68
signed int MxS32
[AI]
Definition: mxtypes.h:38
unsigned int MxU32
[AI]
Definition: mxtypes.h:32
MxBool KeyValueStringParse(char *, const char *, const char *)
Searches p_string for a key command and copies its associated value to p_output.
Definition: mxutilities.cpp:85
[AI] Associates a named edge (string) to a LegoPathBoundary, used within skeleton kick phases to assi...
Definition: legoracers.h:38
LegoPathBoundary * m_b
[AI] Boundary pointer; set to NULL until mapped by ParseAction or similar initialization.
Definition: legoracers.h:40
[AI] Holds per-animation instance data for a LegoAnimActor.
Definition: legoanimactor.h:13
float GetDuration()
[AI] Gets the length, in seconds, of the animation (delegates to anim tree).
LegoAnim * GetAnimTreePtr()
[AI] Returns the root animation tree node for this mapping.
Definition: legoanimactor.h:32
[AI] Represents an advanced edge in the LEGO Island geometry system, with direction,...
[AI] Represents a phase of the skeleton kick animation/action, delimiting animation intervals along a...
Definition: legoracers.h:48
MxU8 m_userState
[AI] State to switch to if currently within this phase. LEGORACECAR_KICK1 or LEGORACECAR_KICK2.
Definition: legoracers.h:52
float m_lower
[AI] Lower normalized bound of animation phase where this skeleton kick is applicable....
Definition: legoracers.h:50
EdgeReference * m_edgeRef
[AI] Pointer to the EdgeReference describing which boundary this phase is associated with.
Definition: legoracers.h:49