Isle
Loading...
Searching...
No Matches
act3ammo.cpp
Go to the documentation of this file.
1#include "act3ammo.h"
2
3#include "act3.h"
4#include "act3actors.h"
7#include "legopathboundary.h"
9#include "legosoundmanager.h"
10#include "misc.h"
11#include "roi/legoroi.h"
12
13#include <assert.h>
14#include <stdio.h>
15
17
18// Initialized at LEGO1 0x100537c0
19// GLOBAL: LEGO1 0x10104f08
20Mx3DPointFloat Act3Ammo::g_unk0x10104f08 = Mx3DPointFloat(0.0, 5.0, 0.0);
21
22// FUNCTION: LEGO1 0x100537f0
23// FUNCTION: BETA10 0x1001d648
25{
26 m_ammoFlag = 0;
27 m_world = NULL;
28}
29
30// FUNCTION: LEGO1 0x100538a0
31// FUNCTION: BETA10 0x1001d6e7
33{
35}
36
37// FUNCTION: LEGO1 0x10053900
38// FUNCTION: BETA10 0x1001d759
39void Act3Ammo::Destroy(MxBool p_fromDestructor)
40{
41 if (!p_fromDestructor) {
42 assert(0);
43 }
44 else if (m_roi != NULL) {
46 m_roi = NULL;
47 }
48}
49
50// FUNCTION: LEGO1 0x10053930
51// FUNCTION: BETA10 0x1001d7d0
53{
54 assert(IsValid());
55 assert(m_roi && m_pathController);
56
58 m_roi = NULL;
59
60 if (m_boundary != NULL) {
62 }
63
65 m_ammoFlag = 0;
66 return SUCCESS;
67}
68
69// FUNCTION: LEGO1 0x10053980
70// FUNCTION: BETA10 0x1001d8b3
71MxResult Act3Ammo::Create(Act3* p_world, MxU32 p_isPizza, MxS32 p_index)
72{
73 assert(m_ammoFlag);
74 char name[12];
75
76 if (p_isPizza) {
77 sprintf(name, "pammo%d", p_index);
78 m_roi = CharacterManager()->CreateAutoROI(name, "pizpie", FALSE);
80
81 BoundingSphere sphere;
82
83 sphere.Center()[0] = sphere.Center()[1] = sphere.Center()[2] = 0.0f;
84 sphere.Radius() = m_roi->GetBoundingSphere().Radius() * 2.0f;
85 m_roi->SetBoundingSphere(sphere);
86
87 m_ammoFlag = c_pizza;
88 assert(m_roi);
89 }
90 else {
91 sprintf(name, "dammo%d", p_index);
92 m_roi = CharacterManager()->CreateAutoROI(name, "donut", FALSE);
94
95 BoundingSphere sphere;
96
97 sphere.Center()[0] = sphere.Center()[1] = sphere.Center()[2] = 0.0f;
98 sphere.Radius() = m_roi->GetBoundingSphere().Radius() * 5.0f;
99 m_roi->SetBoundingSphere(sphere);
100
101 m_ammoFlag = c_donut;
102 assert(m_roi);
103 }
104
105 m_world = p_world;
106 SetValid(TRUE);
107 return SUCCESS;
108}
109
110// FUNCTION: LEGO1 0x10053b40
111// FUNCTION: BETA10 0x1001db2a
112MxResult Act3Ammo::FUN_10053b40(const Vector3& p_srcLoc, const Vector3& p_srcDir, const Vector3& p_srcUp)
113{
114 assert(p_srcDir[1] != 0);
115
116 MxFloat local1c = -(p_srcLoc[1] / p_srcDir[1]);
117 Mx3DPointFloat local18(p_srcDir);
118 Mx3DPointFloat local34;
119
120 local18 *= local1c;
121 local18 += p_srcLoc;
122
123 local34[0] = local34[2] = 0.0f;
124 local34[1] = -1.0f;
125
126 m_eq[1] = p_srcUp;
127 m_eq[2] = p_srcLoc;
128
129 Mx3DPointFloat local48(local34);
130 local48 -= m_eq[1];
131
132 for (MxS32 i = 0; i < 3; i++) {
133 if (local18[0] == p_srcLoc[0]) {
134 return FAILURE;
135 }
136
137 m_eq[0][i] = (local48[i] * local48[i] + local48[i] * m_eq[1][i] * 2.0f) / ((local18[i] - p_srcLoc[i]) * 4.0f);
138 }
139
140 assert(m_eq[0][0] > 0.000001 || m_eq[0][0] < -0.000001);
141
142 m_unk0x19c = local48[0] / (m_eq[0][0] * 2.0f);
143 return SUCCESS;
144}
145
146// FUNCTION: LEGO1 0x10053cb0
147// FUNCTION: BETA10 0x1001ddf4
149{
150 assert(p_p);
151 assert(IsValid());
152
153 if (IsPizza()) {
154 assert(SoundManager()->GetCacheSoundManager());
156 }
157 else {
158 assert(SoundManager()->GetCacheSoundManager());
160 }
161
162 m_pathController = p_p;
163 m_boundary = p_boundary;
164 m_BADuration = 10000.0f;
165 m_unk0x19c = p_unk0x19c;
166 m_unk0x7c = 0.0f;
167 m_lastTime = -1.0f;
169 return SUCCESS;
170}
171
172// FUNCTION: LEGO1 0x10053d30
173// FUNCTION: BETA10 0x1001df73
175{
176 assert(p_p);
177 assert(IsValid());
178
179 SetBit4(TRUE);
180
181 if (IsPizza()) {
182 assert(SoundManager()->GetCacheSoundManager());
184 }
185 else {
186 assert(SoundManager()->GetCacheSoundManager());
188 }
189
190 m_pathController = p_p;
191 m_BADuration = 10000.0f;
192 m_unk0x19c = p_unk0x19c;
193 m_unk0x7c = 0.0f;
194 m_lastTime = -1.0f;
196 return SUCCESS;
197}
198
199// FUNCTION: LEGO1 0x10053db0
200// FUNCTION: BETA10 0x1001e0f0
201MxResult Act3Ammo::FUN_10053db0(float p_param1, const Matrix4& p_param2)
202{
203 float local34 = p_param1 * p_param1;
204
205 Vector3 local14(p_param2[0]);
206 Vector3 local3c(p_param2[1]);
207 Vector3 localc(p_param2[2]);
208 Vector3 local30(p_param2[3]);
209 Mx3DPointFloat local28;
210
211 local28 = m_eq[1];
212 local28 *= p_param1;
213 local30 = m_eq[0];
214 local30 *= local34;
215 local30 += local28;
216 local30 += m_eq[2];
217 localc = m_eq[0];
218 localc *= 2.0f;
219 localc *= p_param1;
220 localc += m_eq[1];
221 localc *= -1.0f;
222
223 if (localc.Unitize() != 0) {
224 assert(0);
225 return FAILURE;
226 }
227
228 local14[1] = local14[2] = 0.0f;
229 local14[0] = 1.0f;
230 local3c.EqualsCross(localc, local14);
231
232 if (local3c.Unitize() != 0) {
233 local14[0] = local14[1] = 0.0f;
234 local14[2] = 1.0f;
235 local3c.EqualsCross(localc, local14);
236
237 if (local3c.Unitize() != 0) {
238 assert(0);
239 return FAILURE;
240 }
241 }
242
243 local14.EqualsCross(local3c, localc);
244 return SUCCESS;
245}
246
247// FUNCTION: LEGO1 0x10054050
248// FUNCTION: BETA10 0x1001e362
249void Act3Ammo::Animate(float p_time)
250{
251 assert(IsValid());
252
253 switch (m_actorState & c_maxState) {
254 case c_initial:
255 case c_one:
256 break;
257 case c_two:
258 m_unk0x158 = p_time + 2000.0f;
260 return;
261 case c_three:
262 MxMatrix transform;
263 Vector3 positionRef(transform[3]);
264
265 transform = m_roi->GetLocal2World();
266
267 if (m_unk0x158 > p_time) {
268 Mx3DPointFloat position;
269
270 position = positionRef;
271 positionRef.Clear();
272 transform.RotateX(0.6);
273 positionRef = position;
274 m_roi->FUN_100a58f0(transform);
275 m_roi->VTable0x14();
276 return;
277 }
278 else {
280 m_unk0x158 = 0;
281
282 positionRef -= g_unk0x10104f08;
283 m_roi->FUN_100a58f0(transform);
284 m_roi->VTable0x14();
285 return;
286 }
287 }
288
289 if (m_worldSpeed <= 0.0f) {
290 return;
291 }
292
293 if (m_lastTime < 0.0f) {
294 m_lastTime = p_time;
295 m_unk0x7c = 0.0f;
296 }
297
298 MxMatrix local104;
299 MxMatrix local60;
300
302
303 undefined4 localb4 = 0;
304 undefined4 localbc = 0;
305 MxU32 local14 = FALSE;
306 MxU32 localb8 = FALSE;
307
308 if (f >= p_time) {
311 m_lastTime = p_time;
312 }
313 else {
314 localb8 = TRUE;
316 m_lastTime = p_time;
317 }
318
319 local104.SetIdentity();
320
321 MxResult r = FUN_10053db0((m_unk0x7c / m_BADuration) * m_unk0x19c, local104);
322 assert(r == 0); // SUCCESS
323
324 local60.SetIdentity();
325
326 if (IsPizza()) {
327 local60.Scale(2.0f, 2.0f, 2.0f);
328 }
329 else {
330 local60.Scale(5.0f, 5.0f, 5.0f);
331 }
332
333 if (localb8) {
334 if (m_boundary != NULL) {
335 Vector3 local17c(local104[0]);
336 Vector3 local184(local104[1]);
337 Vector3 local174(local104[2]);
338
339 if (IsPizza()) {
340 local184 = *m_boundary->GetUnknown0x14();
341 local17c[0] = 1.0f;
342 local17c[1] = local17c[2] = 0.0f;
343 local174.EqualsCross(local17c, local184);
344 local174.Unitize();
345 local17c.EqualsCross(local184, local174);
346 }
347 else {
348 local17c = *m_boundary->GetUnknown0x14();
349 local184[0] = 1.0f;
350 local184[1] = local184[2] = 0.0f;
351 local174.EqualsCross(local17c, local184);
352 local174.Unitize();
353 local184.EqualsCross(local174, local17c);
354 }
355 }
356
358 }
359 else {
360 local60.RotateX(m_actorTime / 10.0f);
361 local60.RotateY(m_actorTime / 6.0f);
362 }
363
364 MxMatrix localb0(local104);
365 local104.Product(local60, localb0);
366 m_roi->FUN_100a58f0(local104);
367 m_roi->VTable0x14();
368
369 if (m_BADuration <= m_unk0x7c) {
370 m_worldSpeed = 0.0f;
371 }
372
373 Vector3 local68(local104[3]);
374
375 if (localb8) {
376 if (IsBit4()) {
377 if (IsPizza()) {
378 m_world->RemovePizza(*this);
379 m_world->FUN_10072ad0(2);
380 }
381 else {
382 m_world->RemoveDonut(*this);
383 m_world->FUN_10072ad0(4);
384 }
385 }
386 else {
387 if (IsPizza()) {
388 assert(SoundManager()->GetCacheSoundManager());
390 }
391 else {
392 assert(SoundManager()->GetCacheSoundManager());
394 }
395
397 LegoPathActorSet lpas(plpas);
398
399 for (LegoPathActorSet::iterator itpa = lpas.begin(); itpa != lpas.end(); itpa++) {
400 if (plpas.find(*itpa) != plpas.end() && this != *itpa) {
401 LegoROI* r = (*itpa)->GetROI();
402 assert(r);
403
404 if (!strncmp(r->GetName(), "pammo", 5)) {
405 Mx3DPointFloat local1c8;
406 Mx3DPointFloat local1b4;
407
408 local1c8 = r->GetLocal2World()[3];
409 local1b4 = m_roi->GetLocal2World()[3];
410
411 local1b4 -= local1c8;
412
413 float radius = r->GetWorldBoundingSphere().Radius();
414 if (local1b4.LenSquared() <= radius * radius) {
415 MxS32 index = -1;
416 if (sscanf(r->GetName(), "pammo%d", &index) != 1) {
417 assert(0);
418 }
419
420 assert(m_world);
421
422 if (m_world->m_pizzas[index].IsValid() && !m_world->m_pizzas[index].IsSharkFood()) {
423 m_world->EatPizza(index);
424 m_world->m_brickster->FUN_100417c0();
425 }
426
427 if (IsDonut()) {
428 assert(SoundManager()->GetCacheSoundManager());
430 m_world->RemoveDonut(*this);
431 local14 = TRUE;
432 break;
433 }
434 }
435 }
436 else if (!strncmp(r->GetName(), "dammo", 5)) {
437 Mx3DPointFloat local1f8;
438 Mx3DPointFloat local1e4;
439
440 local1f8 = r->GetLocal2World()[3];
441 local1e4 = m_roi->GetLocal2World()[3];
442
443 local1e4 -= local1f8;
444
445 float radius = r->GetWorldBoundingSphere().Radius();
446 if (local1e4.LenSquared() <= radius * radius) {
447 MxS32 index = -1;
448 if (sscanf(r->GetName(), "dammo%d", &index) != 1) {
449 assert(0);
450 }
451
452 assert(m_world);
453
454 m_world->EatDonut(index);
455
456 if (IsPizza()) {
457 assert(SoundManager()->GetCacheSoundManager());
459 m_world->RemovePizza(*this);
460 local14 = TRUE;
461 break;
462 }
463 }
464 }
465 }
466 }
467
468 if (!local14) {
469 if (IsPizza()) {
470 m_world->FUN_10073360(*this, local68);
471 }
472 else {
473 m_world->FUN_10073390(*this, local68);
474 }
475
476 m_worldSpeed = -1.0f;
477 }
478 }
479 }
480}
Represents an ammo object (pizza or donut) used in Act 3 gameplay sequence.
Definition: act3ammo.h:15
void SetBit4(MxBool p_bit4)
Set or clear the bit4 flag, used internally for special state/behavior (e.g.
Definition: act3ammo.h:93
MxU32 IsPizza()
Returns true if the ammo is a pizza projectile.
Definition: act3ammo.h:82
MxU32 IsBit4()
Returns true if the internal bit4 flag is set (special usage, e.g.
Definition: act3ammo.h:106
@ c_donut
[AI] The ammo is a donut projectile. [AI]
Definition: act3ammo.h:20
@ c_pizza
[AI] The ammo is a pizza projectile. [AI]
Definition: act3ammo.h:19
void Animate(float p_time) override
Updates position, animation, and handles collision or end-of-trajectory logic for this ammo.
Definition: act3ammo.cpp:249
MxResult Create(Act3 *p_world, MxU32 p_isPizza, MxS32 p_index)
Creates an ammo (pizza or donut), initializes its ROI, bounding volumes, and enables it in the world.
Definition: act3ammo.cpp:71
MxU32 IsDonut()
Returns true if the ammo is a donut projectile.
Definition: act3ammo.h:87
MxResult FUN_10053cb0(LegoPathController *p_p, LegoPathBoundary *p_boundary, MxFloat p_unk0x19c)
Initializes the path controller/boundary and sets up animation and sound when ammo is fired.
Definition: act3ammo.cpp:148
MxU32 IsSharkFood()
Returns true if the ammo became "shark food".
Definition: act3ammo.h:125
void Destroy(MxBool p_fromDestructor) override
Completely removes this ammo object from all managers.
Definition: act3ammo.cpp:39
MxResult FUN_10053b40(const Vector3 &p_srcLoc, const Vector3 &p_srcDir, const Vector3 &p_srcUp)
Sets up trajectory control points for the projectile, calculating a quadratic curve based on origin/d...
Definition: act3ammo.cpp:112
MxU32 IsValid()
Returns true if the ammo is valid (active in game/world).
Definition: act3ammo.h:51
~Act3Ammo() override
Destructor.
Definition: act3ammo.cpp:32
MxResult Remove()
Removes this ammo instance from the world, cleans up path controller/boundary and notifies managers.
Definition: act3ammo.cpp:52
void SetValid(MxBool p_valid)
Set or clear the valid flag for the object, making it active or inactive in the world.
Definition: act3ammo.h:69
MxResult FUN_10053d30(LegoPathController *p_p, MxFloat p_unk0x19c)
Variant of firing logic (uses only controller and param, also sets bit4).
Definition: act3ammo.cpp:174
MxResult FUN_100417c0()
[AI] Recalculates Brickster's navigation to a new plant/building/target as dictated by AI logic.
Definition: act3actors.cpp:788
[AI] Controls all main logic and progression of Act 3 in LEGO Island, including objects,...
Definition: act3.h:182
void EatPizza(MxS32 p_index)
[AI] Simulates eating (removing) a pizza from the world at the given index.
Definition: act3.cpp:255
Act3Ammo m_pizzas[MAX_PIZZAS]
[AI] All possible pizza projectiles/instances in flight for this sequence.
Definition: act3.h:432
MxResult FUN_10073390(Act3Ammo &p_ammo, const Vector3 &p_param2)
[AI] Triggers script/animation effects on cops for donuts that impact them.
Definition: act3.cpp:710
Act3Brickster * m_brickster
[AI] Main antagonist.
Definition: act3.h:437
void FUN_10072ad0(undefined4 p_param1)
[AI] Triggers special sequence actions or sounds depending on the provided param; cycles through queu...
Definition: act3.cpp:406
MxResult FUN_10073360(Act3Ammo &p_ammo, const Vector3 &p_param2)
[AI] Triggers script/animation effects on the brickster for pizzas that impact him.
Definition: act3.cpp:700
void EatDonut(MxS32 p_index)
[AI] Simulates eating (removing) a donut from the world at the given index.
Definition: act3.cpp:263
void RemoveDonut(Act3Ammo &p_p)
[AI] Removes given donut actor and performs associated logic.
Definition: act3.cpp:290
void RemovePizza(Act3Ammo &p_p)
[AI] Removes given pizza actor and performs associated logic.
Definition: act3.cpp:271
[AI] Represents a bounding sphere in 3D space with center and radius.
Definition: roi.h:56
const float & Radius() const
[AI] Const accessor for the sphere radius.
Definition: roi.h:72
const Vector3 & Center() const
[AI] Const accessor for the center of the sphere.
Definition: roi.h:62
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.
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.
void ReleaseActor(const char *p_name)
[AI] Releases a character/ROI by name, decrementing its reference count and deleting if zero.
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
MxFloat m_actorTime
[AI] Animation time for current path segment. [AI]
LegoPathBoundary * m_boundary
[AI] Current boundary the actor is navigating on. [AI]
MxU32 m_actorState
[AI] State and flags bitfield for path following logic. [AI]
MxFloat m_unk0x7c
[AI] Interpolator/progress state along curve segment. [AI]
LegoPathController * m_pathController
[AI] Path controller/manages permitted boundaries for transitions. [AI]
@ c_maxState
[AI] Max actor state (reserved for logic). [AI]
Definition: legopathactor.h:42
@ c_initial
[AI] Default state upon creation or reset. [AI]
Definition: legopathactor.h:37
MxFloat m_BADuration
[AI] Duration of current Bezier arc (distance along path/current edge). [AI]
MxFloat m_lastTime
[AI] Time of last update (used for delta calculations). [AI]
[AI] Represents a path segment or boundary in the navigation network for actors (vehicles,...
LegoPathActorSet & GetActors()
[AI] Direct access to the actor set for this boundary.
MxResult RemoveActor(LegoPathActor *p_actor)
[AI] Removes the actor from this boundary's actor set.
[AI] Manager for controlling actors' movement along predefined geometric paths.
MxResult RemoveActor(LegoPathActor *p_actor)
[AI] Removes an actor from the controller, detaches it from controlled boundaries,...
[AI] Represents a Real-time Object Instance enriched with LEGO-specific functionality.
Definition: legoroi.h:43
void SetBoundingSphere(const BoundingSphere &p_sphere)
[AI] Sets the local and world bounding spheres.
Definition: legoroi.h:317
const LegoChar * GetName() const
[AI] Gets this ROI's name.
Definition: legoroi.h:287
BoundingSphere & GetBoundingSphere()
[AI] Accesses the local bounding sphere object.
Definition: legoroi.h:299
LegoCacheSoundManager * GetCacheSoundManager()
[AI] Returns the cache sound manager used to cache and reuse sound effects.
Mx4DPointFloat * GetUnknown0x14()
[AI] Returns a pointer to the cached 4D normal or reference plane for the edge.
Definition: legowegedge.h:70
4x4 Matrix class with virtual interface for manipulation and transformation.
Definition: matrix.h:24
void RotateY(const float &p_angle)
Applies a rotation (in radians or degrees, depending on implementation) about the Y axis.
void RotateX(const float &p_angle)
Applies a rotation (in radians or degrees, depending on implementation) about the X axis.
void Scale(const float &p_x, const float &p_y, const float &p_z)
Applies scaling factors along X, Y, and Z axes.
virtual void Product(float(*p_a)[4], float(*p_b)[4])
Multiplies two 4x4 float matrices, storing result in this.
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
const BoundingSphere & GetWorldBoundingSphere() const override
Returns the object's bounding sphere in world coordinates.
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 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
void Clear() override
[AI] Sets every coordinate (x, y, z) to zero.
float LenSquared() const override
[AI] Computes the squared magnitude (x^2 + y^2 + z^2) of this vector.
virtual void EqualsCross(const Vector3 &p_a, const Vector3 &p_b)
[AI] Sets this vector to be the cross product of p_a and p_b.
#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
set< LegoPathActor *, LegoPathActorSetCompare > LegoPathActorSet
[AI] Defines a set of LegoPathActor pointers, ordered by pointer value using LegoPathActorSetCompare.
#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
LegoCharacterManager * CharacterManager()
[AI] Accessor for the character manager, which manages in-game characters/NPCs. [AI]
Definition: misc.cpp:101
LegoSoundManager * SoundManager()
[AI] Accessor for the game's LegoSoundManager subsystem from the global LegoOmni instance....
Definition: misc.cpp:22
MxU8 MxBool
[AI]
Definition: mxtypes.h:124
MxLong MxResult
[AI]
Definition: mxtypes.h:106
float MxFloat
[AI]
Definition: mxtypes.h:68
signed int MxS32
[AI]
Definition: mxtypes.h:38
unsigned int MxU32
[AI]
Definition: mxtypes.h:32