Paper Mario DX
Paper Mario (N64) modding
 
Loading...
Searching...
No Matches
WoodenCrate.c
Go to the documentation of this file.
1#include "common.h"
2#include "vars_access.h"
3#include "npc.h"
4#include "ld_addrs.h"
5#include "entity.h"
6
7#if VERSION_JP // TODO remove once segments are split
8extern Addr entity_model_WoodenCrate_ROM_END;
9extern Addr entity_model_WoodenCrate_ROM_START;
10#endif
11
12extern Gfx Entity_RenderNone[];
13extern Gfx Entity_WoodenCrate_Render[];
17
19
20void entity_WoodenCrate_init_fragments(Entity* entity, Gfx** dlists, Mtx* matrices) {
21 WoodenCrateData* data = entity->dataBuf.crate;
22 Matrix4f mtxFragment;
23 Matrix4f mtxTrans;
24 s32 i;
25 s32 rotationSpeed;
26
27 data->fragmentsGfx = ENTITY_ADDR(entity, Gfx**, dlists);
29 entity->alpha = 255;
30 entity->pos.y = data->basePosY;
31 guTranslateF(mtxTrans, entity->pos.x, entity->pos.y, entity->pos.z);
32
33 for (i = 0; i < 35; i++) {
34 guMtxL2F(mtxFragment, ENTITY_ADDR(entity, Mtx*, matrices++));
35 guMtxCatF(mtxTrans, mtxFragment, mtxFragment);
36 data->fragmentPosX[i] = mtxFragment[3][0];
37 data->fragmentPosY[i] = mtxFragment[3][1];
38 data->fragmentPosZ[i] = mtxFragment[3][2];
39 data->fragmentMoveAngle[i] = -rand_int(255);
40 data->fragmentLateralSpeed[i] = 20;
41
42 rotationSpeed = rand_int(5);
43 if (i % 2 != 0) {
44 data->fragmentRotSpeed[i] = rotationSpeed + 10;
45 } else {
46 data->fragmentRotSpeed[i] = -10 - rotationSpeed;
47 }
48
49 data->fragmentFallSpeed[i] = 10.0f;
50 data->fragmentRebounds[i] = 0;
51 data->fragmentRotX[i] = 0;
52 data->fragmentRotY[i] = 0;
53 }
54}
55
57 WoodenCrateData* data = entity->dataBuf.crate;
58
59 entity->scale.y = 0.85714287f;
61 data->globalFlagIndex = 0xFFFF;
62}
63
70
72 WoodenCrateData* data = entity->dataBuf.crate;
73 f32 rotSpeed, lateralSpeed, reboundSpeed;
74 f32 moveAngle, yawRad;
75 s32 i;
76 s32 numFragmentsDisappeared;
77 f32 hitX, hitY, hitZ, hitDepth;
78
79 numFragmentsDisappeared = 0;
80 rotSpeed = 0.0f;
81 reboundSpeed = 0.0f;
82 lateralSpeed = 0.0f;
83
84 for (i = 0; i < 35; i++) {
85 switch (data->fragmentRebounds[i]) {
86 case 0:
87 reboundSpeed = 2.0f;
88 rotSpeed = data->fragmentRotSpeed[i];
89 lateralSpeed = data->fragmentLateralSpeed[i] / 10.0f;
90 if (rotSpeed >= 0.0f) {
91 data->fragmentRotSpeed[i] = rotSpeed - 0.4;
92 } else {
93 data->fragmentRotSpeed[i] = rotSpeed + 0.5;
94 }
95 break;
96 case 1:
97 lateralSpeed = 1.0f;
98 reboundSpeed = 0.0f;
99 rotSpeed = data->fragmentRotSpeed[i] * 0.25f;
100 break;
101 case 2:
102 data->fragmentRotSpeed[i] += 1.0f;
103 if (data->fragmentRotSpeed[i] > 20.0f) {
104 data->fragmentRotSpeed[i] = 20.0f;
105 }
106
107 data->fragmentPosY[i] -= data->fragmentRotSpeed[i] / 70.0f;
108
109 data->fragmentMoveAngle[i] -= 5;
110 if (data->fragmentMoveAngle[i] <= 5) {
111 data->fragmentMoveAngle[i] = 0;
112 data->fragmentRebounds[i]++;
113 }
114 break;
115 case 3:
116 numFragmentsDisappeared++;
117 break;
118 }
119
120 if (data->fragmentRebounds[i] < 2) {
121 if (data->fragmentFallSpeed[i] >= 0.0f) {
122 data->fragmentFallSpeed[i] -= 0.8;
123 if (data->fragmentFallSpeed[i] < -10.2) {
124 data->fragmentFallSpeed[i] = -10.2f;
125 }
126 } else {
127 data->fragmentFallSpeed[i] -= 1.6;
128 if (data->fragmentFallSpeed[i] < -10.2) {
129 data->fragmentFallSpeed[i] = -10.2f;
130 }
131 }
132
133 data->fragmentPosY[i] += data->fragmentFallSpeed[i];
134 yawRad = data->fragmentMoveAngle[i] * 360.0f / 256;
135 moveAngle = DEG_TO_RAD(yawRad);
136 data->fragmentPosX[i] += lateralSpeed * sin_rad(moveAngle);
137 data->fragmentPosZ[i] += lateralSpeed * cos_rad(moveAngle);
138
139 hitX = data->fragmentPosX[i];
140 hitY = data->fragmentPosY[i];
141 hitZ = data->fragmentPosZ[i];
142 if (npc_test_move_taller_with_slipping(COLLISION_IGNORE_ENTITIES, &hitX, &hitY, &hitZ, lateralSpeed, yawRad, 8.0f, 8.0f)) {
143 data->fragmentPosX[i] = hitX;
144 data->fragmentPosY[i] = hitY;
145 data->fragmentPosZ[i] = hitZ;
146 data->fragmentMoveAngle[i] += 0x80; // inverse yaw
147
148 moveAngle = DEG_TO_RAD(data->fragmentMoveAngle[i] * 360.0f / 256);
149 lateralSpeed = 8.0f;
150 data->fragmentPosX[i] += lateralSpeed * sin_rad(moveAngle);
151 data->fragmentPosZ[i] += lateralSpeed * cos_rad(moveAngle);
152
153 }
154
155 hitX = data->fragmentPosX[i];
156 hitY = data->fragmentPosY[i] + 8.0f;
157 hitZ = data->fragmentPosZ[i];
158 hitDepth = fabsf(data->fragmentFallSpeed[i]);
159 if (npc_raycast_down_sides(COLLISION_IGNORE_ENTITIES, &hitX, &hitY, &hitZ, &hitDepth) || hitY < data->basePosY - 200.0f) {
160 data->fragmentRebounds[i]++;
161 data->fragmentPosY[i] = hitY + fabsf(data->fragmentFallSpeed[i]);
162 data->fragmentFallSpeed[i] = reboundSpeed;
163 if (data->fragmentRebounds[i] == 2) {
164 data->fragmentMoveAngle[i] = 254;
165 data->fragmentRotSpeed[i] = 0.0f;
166 }
167 }
168
169 data->fragmentRotX[i] += rotSpeed;
170 data->fragmentRotY[i] -= rotSpeed;
171 }
172 }
173
174 if (numFragmentsDisappeared >= 35) {
176 }
177}
178
179void entity_WoodenCrate_setupGfx(s32 entityIndex) {
180 s32 i;
181 Matrix4f mtxTransInv;
182 Matrix4f mtx;
183 Matrix4f mtxRotX;
184 Matrix4f mtxRotY;
185 f32 x_inv;
186 f32 y_inv;
187 f32 z_inv;
188 Gfx* gfxPos = gMainGfxPos;
189 Entity* entity = get_entity_by_index(entityIndex);
190 WoodenCrateData* data = entity->dataBuf.crate;
191 Gfx* fragmentDlist;
192 Gfx** gfx = data->fragmentsGfx;
193
194 x_inv = -entity->pos.x;
195 y_inv = -entity->pos.y;
196 z_inv = -entity->pos.z;
197
198 for (i = 0; i < 35; i++) {
199 if (data->fragmentRebounds[i] < 2) {
200 gDPSetRenderMode(gfxPos++, G_RM_AA_ZB_OPA_SURF, G_RM_AA_ZB_OPA_SURF2);
201 gDPSetCombineMode(gfxPos++, G_CC_MODULATEIA, G_CC_MODULATEIA);
202 } else {
203 gDPSetCombineMode(gfxPos++, PM_CC_11, PM_CC_12);
204 gDPSetPrimColor(gfxPos++, 0, 0, 0, 0, 0, data->fragmentMoveAngle[i]);
205 }
206
207 guTranslateF(mtxTransInv, x_inv, y_inv, z_inv);
208 guRotateF(mtxRotX, data->fragmentRotX[i] * 360.0f / 256, 1.0f, 0.0f, 0.0f);
209 guRotateF(mtxRotY, data->fragmentRotY[i] * 360.0f / 256, 0.0f, 1.0f, 0.0f);
210 guMtxCatF(mtxRotX, mtxRotY, mtxRotY);
211 guMtxCatF(mtxRotY, mtxTransInv, mtxTransInv);
212 guTranslateF(mtx, data->fragmentPosX[i], data->fragmentPosY[i], data->fragmentPosZ[i]);
213 guMtxCatF(mtxTransInv, mtx, mtx);
215
216 gSPMatrix(gfxPos++, &gDisplayContext->matrixStack[gMatrixListPos++], G_MTX_PUSH | G_MTX_MUL | G_MTX_MODELVIEW);
217 fragmentDlist = ENTITY_ADDR(entity, Gfx*, *gfx++);
218 gSPDisplayList(gfxPos++, fragmentDlist);
219 gSPPopMatrix(gfxPos++, G_MTX_MODELVIEW);
220 }
221
222 gMainGfxPos = gfxPos;
223}
224
226 PlayerStatus* playerStatus = &gPlayerStatus;
227 s32 shouldBreak = FALSE;
228
230 if ((playerStatus->actionState == ACTION_STATE_SPIN_POUND)
231 || (playerStatus->actionState == ACTION_STATE_TORNADO_POUND)) {
233 shouldBreak = TRUE;
234 }
235 }
236
237 if (shouldBreak) {
240 entity_start_script(entity);
243 }
244}
245
247
248void entity_WoodenCrate_shatter(Entity* entity, f32 arg1) {
249 WoodenCrateData* data = entity->dataBuf.crate;
250
251 if (data->itemID != -1) {
252 s32 flag = FALSE;
253
254 if (data->globalFlagIndex == 0xFFFF) {
255 flag = TRUE;
256 } else if (!get_global_flag(data->globalFlagIndex)) {
257 flag = TRUE;
258 }
259
260 if (flag) {
261 make_item_entity(data->itemID, entity->pos.x, entity->pos.y + 33.0, entity->pos.z,
263 }
264 }
265}
266
269
279
282 .typeDataSize = sizeof(WoodenCrateData),
283 .renderCommandList = Entity_WoodenCrate_RenderScript,
284 .modelAnimationNodes = 0,
285 .fpInit = entity_WoodenCrate_init,
286 .updateEntityScript = Entity_WoodenCrate_Script,
287 .fpHandleCollision = NULL,
288 { .dma = ENTITY_ROM(WoodenCrate) },
289 .entityType = ENTITY_TYPE_WOODEN_CRATE,
290 .aabbSize = { 35, 30, 35 }
291};
f32 player_get_camera_facing_angle(void)
Definition 7BB60.c:1191
void entity_WoodenCrate_reset_fragments(Entity *entity)
Definition WoodenCrate.c:64
EntityBlueprint Entity_WoodenCrate
Gfx Entity_WoodenCrate_Render[]
EntityModelScript Entity_WoodenCrate_RenderScript
Mtx Entity_WoodenCrate_FragmentsMatrices[]
Definition WoodenCrate.c:36
void entity_WoodenCrate_setupGfx(s32)
Gfx * Entity_WoodenCrate_FragmentsRender[]
void entity_WoodenCrate_shatter(Entity *entity, f32 arg1)
void entity_WoodenCrate_init_fragments(Entity *entity, Gfx **dlists, Mtx *matrices)
Definition WoodenCrate.c:20
s32 Entity_WoodenCrate_RenderShatteredScript[]
EntityScript Entity_WoodenCrate_Script
void entity_WoodenCrate_init(Entity *entity)
Definition WoodenCrate.c:56
Gfx Entity_RenderNone[]
Definition Shadow.c:69
s32 entity_WoodenCrate_idle(Entity *entity)
void entity_WoodenCrate_update_fragments(Entity *entity)
Definition WoodenCrate.c:71
struct WoodenCrateData * crate
Mtx matrixStack[0x200]
f32 Matrix4f[4][4]
#define guRotateF
#define npc_raycast_down_sides
#define guMtxF2L
#define guTranslateF
#define guMtxCatF
#define rand_int
s32 CreateEntityVarArgBuffer[]
Definition entity.c:35
u8 fragmentRotY[36]
Definition entity.h:182
s32 EntityModelScript[]
Definition entity.h:7
#define es_Call(func)
Definition entity.h:37
#define STANDARD_ENTITY_MODEL_SCRIPT(gfx, renderMode)
Definition entity.h:56
#define ENTITY_ADDR(entity, type, data)
Definition entity.h:64
#define es_SetCallback(func, time)
Definition entity.h:38
#define es_SetFlags(flags)
Definition entity.h:43
s8 fragmentRebounds[36]
Definition entity.h:179
f32 fragmentFallSpeed[36]
Definition entity.h:188
#define ENTITY_ROM(name)
Definition entity.h:65
f32 fragmentPosY[36]
Definition entity.h:186
f32 fragmentPosZ[36]
Definition entity.h:187
f32 fragmentPosX[36]
Definition entity.h:185
u8 fragmentMoveAngle[36]
Definition entity.h:180
Gfx ** fragmentsGfx
Definition entity.h:177
s32 EntityScript[]
Definition entity.h:6
u8 fragmentLateralSpeed[36]
Definition entity.h:183
#define es_End
Definition entity.h:35
f32 fragmentRotSpeed[36]
Definition entity.h:184
u8 fragmentRotX[36]
Definition entity.h:181
void entity_set_render_script(Entity *entity, EntityModelScript *cmdList)
Definition entity.c:761
u16 globalFlagIndex
Definition entity.h:175
@ ITEM_SPAWN_MODE_ITEM_BLOCK_ITEM
Definition enums.h:2301
@ COLLISION_IGNORE_ENTITIES
Definition enums.h:4698
@ ENTITY_TYPE_WOODEN_CRATE
Definition enums.h:2579
@ ENTITY_COLLISION_PLAYER_TOUCH_FLOOR
Definition enums.h:2648
@ SOUND_BREAK_CRATE
Definition enums.h:1463
@ RENDER_MODE_SURFACE_OPA
Definition enums.h:3264
@ RENDER_MODE_SURFACE_XLU_LAYER1
Definition enums.h:3282
@ ENTITY_FLAG_FIXED_SHADOW_SIZE
Definition enums.h:2622
@ ENTITY_FLAG_HIDDEN
Definition enums.h:2613
@ ENTITY_FLAG_4000
Definition enums.h:2627
@ ENTITY_FLAG_PENDING_INSTANCE_DELETE
Definition enums.h:2642
@ ENTITY_FLAG_DISABLE_COLLISION
Definition enums.h:2618
@ ACTION_STATE_SPIN_POUND
Definition enums.h:2442
@ ACTION_STATE_TORNADO_POUND
Definition enums.h:2444
@ ACTION_STATE_FALLING
Definition enums.h:2435
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
s32 make_item_entity(s32 itemID, f32 x, f32 y, f32 z, s32 itemSpawnMode, s32 pickupDelay, s32 angle, s32 pickupVar)
void set_action_state(s32 actionState)
Definition 7E9D0.c:209
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
void sfx_play_sound(s32 soundID)
Definition sfx.c:517
#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
Vec3f scale
u8 collisionFlags
u8 Addr[]
Linker symbol address, as in ld_addrs.h.
Definition types.h:16
Gfx * gMainGfxPos
Definition cam_main.c:15
u16 gMatrixListPos
Definition main_loop.c:45
PlayerStatus gPlayerStatus
Definition 77480.c:39
DisplayContext * gDisplayContext
Definition cam_main.c:16
s32 get_global_flag(s32 index)
Definition vars_access.c:89