Paper Mario DX
Paper Mario (N64) modding
 
Loading...
Searching...
No Matches
BombableRock.c
Go to the documentation of this file.
1#include "common.h"
2#include "effects.h"
3#include "entity.h"
4#include "ld_addrs.h"
5
6extern Gfx Entity_RenderNone[];
9
11
12void entity_BombableRock_init_fragments(Entity* entity, Gfx** dlists, Mtx* matrices) {
14 Matrix4f mtxFragment;
15 Matrix4f mtxTrans;
16 s32 i;
17 s32 rotationSpeed;
18 s32 moveAngle = 0;
19 s32 lateralSpeed = 0;
20
21 data->fragmentsGfx = ENTITY_ADDR(entity, Gfx**, dlists);
23 entity->alpha = 255;
24 entity->pos.y = data->inititalY;
25 guTranslateF(mtxTrans, entity->pos.x, entity->pos.y, entity->pos.z);
26
27 for (i = 0; i < 5; i++) {
28 guMtxL2F(mtxFragment, ENTITY_ADDR(entity, Mtx*, matrices++));
29 guMtxCatF(mtxTrans, mtxFragment, mtxFragment);
30 data->fragmentPosX[i] = mtxFragment[3][0];
31 data->fragmentPosY[i] = mtxFragment[3][1];
32 data->fragmentPosZ[i] = mtxFragment[3][2];
33 switch (i) {
34 case 0:
35 moveAngle = 192;
36 lateralSpeed = 0;
37 break;
38 case 1:
39 moveAngle = 96;
40 lateralSpeed = 20;
41 break;
42 case 2:
43 moveAngle = 32;
44 lateralSpeed = 20;
45 break;
46 case 3:
47 moveAngle = 160;
48 lateralSpeed = 20;
49 break;
50 case 4:
51 moveAngle = 224;
52 lateralSpeed = 20;
53 break;
54 }
55 data->fragmentMoveAngle[i] = moveAngle;
56 data->fragmentLateralSpeed[i] = lateralSpeed;
57
58 rotationSpeed = rand_int(5);
59 if (i % 2 != 0) {
60 data->fragmentRotSpeed[i] = rotationSpeed + 10;
61 } else {
62 data->fragmentRotSpeed[i] = -10 - rotationSpeed;
63 }
64
65 data->fragmentFallSpeed[i] = 10.0f;
66 data->fragmentRebounds[i] = 0;
67 data->fragmentRotX[i] = 0;
68 data->fragmentRotY[i] = 0;
69 }
70}
71
76
79 f32 rotSpeed, lateralSpeed, reboundSpeed;
80 f32 moveAngle, yawRad;
81 s32 i;
82 s32 numFragmentsDisappeared;
83 f32 hitX, hitY, hitZ, hitDepth;
84
85 numFragmentsDisappeared = 0;
86 rotSpeed = 0.0f;
87 reboundSpeed = 0.0f;
88 lateralSpeed = 0.0f;
89
90 for (i = 0; i < 5; i++) {
91 switch (data->fragmentRebounds[i]) {
92 case 0:
93 reboundSpeed = 2.0f;
94 rotSpeed = data->fragmentRotSpeed[i];
95 lateralSpeed = data->fragmentLateralSpeed[i] / 10.0f;
96 if (rotSpeed >= 0.0f) {
97 data->fragmentRotSpeed[i] = rotSpeed - 0.4;
98 } else {
99 data->fragmentRotSpeed[i] = rotSpeed + 0.5;
100 }
101 break;
102 case 1:
103 lateralSpeed = 1.0f;
104 reboundSpeed = 0.0f;
105 rotSpeed = data->fragmentRotSpeed[i] * 0.25f;
106 break;
107 case 2:
108 data->fragmentRotSpeed[i] += 1.0f;
109 if (data->fragmentRotSpeed[i] > 20.0f) {
110 data->fragmentRotSpeed[i] = 20.0f;
111 }
112
113 data->fragmentPosY[i] -= data->fragmentRotSpeed[i] / 70.0f;
114
115 data->fragmentMoveAngle[i] -= 5;
116 if (data->fragmentMoveAngle[i] <= 5) {
117 data->fragmentMoveAngle[i] = 0;
118 data->fragmentRebounds[i]++;
119 }
120 break;
121 case 3:
122 numFragmentsDisappeared++;
123 break;
124 }
125
126 if (data->fragmentRebounds[i] < 2) {
127 if (data->fragmentFallSpeed[i] >= 0.0f) {
128 data->fragmentFallSpeed[i] -= 0.8;
129 if (data->fragmentFallSpeed[i] < -10.2) {
130 data->fragmentFallSpeed[i] = -10.2f;
131 }
132 } else {
133 data->fragmentFallSpeed[i] -= 1.6;
134 if (data->fragmentFallSpeed[i] < -10.2) {
135 data->fragmentFallSpeed[i] = -10.2f;
136 }
137 }
138
139 data->fragmentPosY[i] += data->fragmentFallSpeed[i];
140 yawRad = data->fragmentMoveAngle[i] * 360.0f / 256;
141 moveAngle = DEG_TO_RAD(yawRad);
142 data->fragmentPosX[i] += lateralSpeed * sin_rad(moveAngle);
143 data->fragmentPosZ[i] += lateralSpeed * cos_rad(moveAngle);
144
145 hitX = data->fragmentPosX[i];
146 hitY = data->fragmentPosY[i];
147 hitZ = data->fragmentPosZ[i];
148 if (npc_test_move_taller_with_slipping(COLLISION_IGNORE_ENTITIES, &hitX, &hitY, &hitZ, lateralSpeed, yawRad, 8.0f, 8.0f)) {
149 data->fragmentPosX[i] = hitX;
150 data->fragmentPosY[i] = hitY;
151 data->fragmentPosZ[i] = hitZ;
152 data->fragmentMoveAngle[i] += 0x80; // inverse yaw
153
154 moveAngle = DEG_TO_RAD(data->fragmentMoveAngle[i] * 360.0f / 256);
155 lateralSpeed = 8.0f;
156 data->fragmentPosX[i] += lateralSpeed * sin_rad(moveAngle);
157 data->fragmentPosZ[i] += lateralSpeed * cos_rad(moveAngle);
158
159 }
160
161 hitX = data->fragmentPosX[i];
162 hitY = data->fragmentPosY[i];
163 hitZ = data->fragmentPosZ[i];
164 hitDepth = fabsf(data->fragmentFallSpeed[i]);
165 if (npc_raycast_down_sides(COLLISION_IGNORE_ENTITIES, &hitX, &hitY, &hitZ, &hitDepth) || hitY < data->inititalY - 200.0f) {
166 data->fragmentRebounds[i]++;
167 data->fragmentPosY[i] = hitY + fabsf(data->fragmentFallSpeed[i]);
168 data->fragmentFallSpeed[i] = reboundSpeed;
169 if (data->fragmentRebounds[i] == 2) {
170 data->fragmentMoveAngle[i] = 254;
171 data->fragmentRotSpeed[i] = 0.0f;
172 }
173 }
174
175 data->fragmentRotX[i] += rotSpeed;
176 data->fragmentRotY[i] -= rotSpeed;
177 }
178 }
179
180 if (numFragmentsDisappeared >= 5) {
182 }
183}
184
185void entity_BombableRock_setupGfx(s32 entityIndex) {
186 s32 i;
187 Matrix4f mtxTransInv;
188 Matrix4f mtx;
189 Matrix4f mtxRotX;
190 Matrix4f mtxRotY;
191 f32 x_inv;
192 f32 y_inv;
193 f32 z_inv;
194 Gfx* gfxPos = gMainGfxPos;
195 Entity* entity = get_entity_by_index(entityIndex);
196 BombableRockData* data = entity->dataBuf.bombableRock;
197 Gfx* fragmentDlist;
198 Gfx** gfx = data->fragmentsGfx;
199
200 x_inv = -entity->pos.x;
201 y_inv = -entity->pos.y;
202 z_inv = -entity->pos.z;
203
204 for (i = 0; i < 5; i++) {
205 if (data->fragmentRebounds[i] < 2) {
206 gDPSetRenderMode(gfxPos++, G_RM_AA_ZB_OPA_SURF, G_RM_AA_ZB_OPA_SURF2);
207 gDPSetCombineMode(gfxPos++, G_CC_MODULATEIA, G_CC_MODULATEIA);
208 } else {
209 gDPSetCombineMode(gfxPos++, PM_CC_11, PM_CC_12);
210 gDPSetPrimColor(gfxPos++, 0, 0, 0, 0, 0, data->fragmentMoveAngle[i]);
211 }
212
213 guTranslateF(mtxTransInv, x_inv, y_inv, z_inv);
214 guRotateF(mtxRotX, data->fragmentRotX[i] * 360.0f / 256, 1.0f, 0.0f, 0.0f);
215 guRotateF(mtxRotY, data->fragmentRotY[i] * 360.0f / 256, 0.0f, 1.0f, 0.0f);
216 guMtxCatF(mtxRotX, mtxRotY, mtxRotY);
217 guMtxCatF(mtxRotY, mtxTransInv, mtxTransInv);
218 guTranslateF(mtx, data->fragmentPosX[i], data->fragmentPosY[i], data->fragmentPosZ[i]);
219 guMtxCatF(mtxTransInv, mtx, mtx);
221
222 gSPMatrix(gfxPos++, &gDisplayContext->matrixStack[gMatrixListPos++], G_MTX_PUSH | G_MTX_MUL | G_MTX_MODELVIEW);
223 fragmentDlist = ENTITY_ADDR(entity, Gfx*, *gfx++);
224 gSPDisplayList(gfxPos++, fragmentDlist);
225 gSPPopMatrix(gfxPos++, G_MTX_MODELVIEW);
226 }
227
228 gMainGfxPos = gfxPos;
229}
230
233 entity_start_script(entity);
235 fx_big_smoke_puff(entity->pos.x, entity->pos.y + 25.0f, entity->pos.z);
236 }
237}
238
240
249
251 .flags = 0,
252 .typeDataSize = sizeof(BombableRockData),
253 .renderCommandList = Entity_BombableRock_RenderScript,
254 .modelAnimationNodes = 0,
255 .fpInit = entity_BombableRock_init,
256 .updateEntityScript = Entity_BombableRock_Script,
257 .fpHandleCollision = NULL,
258 { .dma = ENTITY_ROM(BombableRock) },
259 .entityType = ENTITY_TYPE_BOMBABLE_ROCK,
260 .aabbSize = { 50, 50, 50 }
261};
262
264 .flags = 0,
265 .typeDataSize = sizeof(BombableRockData),
266 .renderCommandList = Entity_BombableRock_RenderScript,
267 .modelAnimationNodes = 0,
268 .fpInit = entity_BombableRock_init,
269 .updateEntityScript = Entity_BombableRock_Script,
270 .fpHandleCollision = NULL,
271 { .dma = ENTITY_ROM(BombableRock) },
272 .entityType = ENTITY_TYPE_BOMBABLE_ROCK,
273 .aabbSize = { 50, 50, 100 }
274};
struct BombableRockData * bombableRock
Mtx matrixStack[0x200]
f32 Matrix4f[4][4]
EntityBlueprint Entity_BombableRock
EntityModelScript Entity_BombableRock_RenderScript
void entity_BombableRock_setupGfx(s32)
Mtx Entity_BombableRock_FragmentMatrices[]
Gfx * Entity_BombableRock_FragmentsRender[]
void entity_BombableRock_init_fragments(Entity *entity, Gfx **dlists, Mtx *matrices)
void entity_BombableRock_init(Entity *entity)
void entity_BombableRock_update_fragments(Entity *entity)
EntityScript Entity_BombableRock_Script
EntityBlueprint Entity_BombableRockWide
Gfx Entity_RenderNone[]
Definition Shadow.c:69
void entity_BombableRock_idle(Entity *entity)
#define guRotateF
#define npc_raycast_down_sides
#define guMtxF2L
#define guTranslateF
#define guMtxCatF
#define rand_int
s32 EntityModelScript[]
Definition entity.h:7
#define STANDARD_ENTITY_MODEL_SCRIPT(gfx, renderMode)
Definition entity.h:56
f32 fragmentPosZ[6]
Definition entity.h:294
#define ENTITY_ADDR(entity, type, data)
Definition entity.h:64
#define es_SetCallback(func, time)
Definition entity.h:38
f32 fragmentRotSpeed[6]
Definition entity.h:291
#define es_SetFlags(flags)
Definition entity.h:43
u8 fragmentRotY[6]
Definition entity.h:289
#define ENTITY_ROM(name)
Definition entity.h:65
f32 fragmentPosX[6]
Definition entity.h:292
s32 EntityScript[]
Definition entity.h:6
u8 fragmentMoveAngle[6]
Definition entity.h:287
#define es_End
Definition entity.h:35
s8 fragmentRebounds[6]
Definition entity.h:286
f32 fragmentFallSpeed[6]
Definition entity.h:295
u8 fragmentLateralSpeed[6]
Definition entity.h:290
u8 fragmentRotX[6]
Definition entity.h:288
Gfx ** fragmentsGfx
Definition entity.h:284
f32 fragmentPosY[6]
Definition entity.h:293
@ COLLISION_IGNORE_ENTITIES
Definition enums.h:4698
@ ENTITY_TYPE_BOMBABLE_ROCK
Definition enums.h:2581
@ ENTITY_COLLISION_PARTNER
Definition enums.h:2655
@ RENDER_MODE_SURFACE_XLU_LAYER1
Definition enums.h:3282
@ ENTITY_FLAG_HIDDEN
Definition enums.h:2613
@ ENTITY_FLAG_PENDING_INSTANCE_DELETE
Definition enums.h:2642
@ ENTITY_FLAG_DISABLE_COLLISION
Definition enums.h:2618
Entity * get_entity_by_index(s32 index)
Definition entity.c:530
f32 fabsf(f32 f)
s32 entity_start_script(Entity *entity)
Definition entity.c:560
f32 cos_rad(f32 x)
Definition 43F0.c:717
b32 npc_test_move_taller_with_slipping(s32, f32 *, f32 *, f32 *, f32, f32, f32, f32)
void exec_entity_commandlist(Entity *entity)
Definition entity.c:313
f32 sin_rad(f32 x)
Definition 43F0.c:713
#define PM_CC_11
Definition macros.h:294
#define DEG_TO_RAD(deg)
Definition macros.h:134
#define PM_CC_12
Definition macros.h:295
void(* renderSetupFunc)(s32)
EntityData dataBuf
u8 collisionFlags
Gfx * gMainGfxPos
Definition cam_main.c:15
u16 gMatrixListPos
Definition main_loop.c:45
DisplayContext * gDisplayContext
Definition cam_main.c:16