Paper Mario DX
Paper Mario (N64) modding
 
Loading...
Searching...
No Matches
Chest.c
Go to the documentation of this file.
1#include "common.h"
2#include "vars_access.h"
3#include "effects.h"
4#include "ld_addrs.h"
5#include "entity.h"
6#include "sprite/player.h"
7
8#if VERSION_JP // TODO remove once segments are split
9extern Addr entity_model_Chest_ROM_END;
10extern Addr entity_model_Chest_ROM_START;
11#endif
12
14
15extern Gfx Entity_Chest_RenderBox[];
16extern Gfx Entity_Chest_RenderLid[];
17extern Mtx Entity_Chest_LidMtx;
18
33
41
43 Thread
44 Call(AdjustCam, 0, Float(8.0), 0, Float(300.0), Float(17.5), Float(-9.5))
46 Return
47 End
48};
49
51 Thread
52 Call(AdjustCam, 0, Float(8.0), 0, Float(210.0), Float(21.0), Float(-16.0))
54 Return
55 End
56};
57
65
66//TODO hardcoded area IDs
68 s16 areaID;
69 EvtScript* script;
70
71 areaID = gGameStatusPtr->areaID;
72 script = NULL;
73 if (areaID == AREA_ISK) {
75 } else if (areaID == AREA_TIK) {
77 } else if (areaID == AREA_KZN) {
79 }
80 if (script != NULL) {
82 }
83}
84
85//TODO hardcoded area IDs
87 s16 areaID;
88 EvtScript* script;
89
90 areaID = gGameStatusPtr->areaID;
91 script = NULL;
92 if (areaID == AREA_ISK) {
94 } else {
96 }
98}
99
100void entity_Chest_setupGfx(s32 entityIndex) {
101 Gfx* gfxPos = gMainGfxPos;
102 Entity* entity = get_entity_by_index(entityIndex);
103 ChestData* data = entity->dataBuf.chest;
104 Matrix4f sp18;
105 Matrix4f sp58;
106 Gfx* gfx;
107
108 guRotateF(sp58, data->lidAngle, 1.0f, 0.0f, 0.0f);
109 guMtxL2F(sp18, ENTITY_ADDR(entity, Mtx*, &Entity_Chest_LidMtx));
110 guMtxCatF(sp58, sp18, sp18);
112 gSPMatrix(gfxPos++, &gDisplayContext->matrixStack[gMatrixListPos++], G_MTX_PUSH | G_MTX_MUL | G_MTX_MODELVIEW);
113 gfx = ENTITY_ADDR(entity, Gfx*, Entity_Chest_RenderLid);
114 gSPDisplayList(gfxPos++, gfx);
115 gSPPopMatrix(gfxPos++, G_MTX_MODELVIEW);
116 gMainGfxPos = gfxPos;
117}
118
120 ChestData* data = entity->dataBuf.chest;
121 if ((data->gameFlagIndex != 0xFFFF) && (get_global_flag(data->gameFlagIndex) != 0)) {
122 entity->flags |= ENTITY_FLAG_4000;
123 data->itemID = -1;
124 data->lidAngle = -28.7f;
126 }
127}
128
130 f32 rotation;
131 f32 angle; // angle from the Chest to the Player
132 ChestData* data;
133 PlayerStatus* playerStatus = &gPlayerStatus;
134
135 rotation = clamp_angle(180.0f - entity->rot.y);
136 angle = fabsf(rotation - clamp_angle(atan2(entity->pos.x, entity->pos.z, playerStatus->pos.x, playerStatus->pos.z)));
137 if ((!(playerStatus->animFlags & PA_FLAG_USING_WATT)) &&
139 ((angle <= 40.0f) || (angle >= 320.0f))) {
143 data = entity->dataBuf.chest;
144 data->state = 0;
145 entity->flags &= ~ENTITY_FLAG_SHOWS_INSPECT_PROMPT;
146 if (data->itemID != 0) {
148 }
150 }
151 } else {
152 entity->flags &= ~ENTITY_FLAG_SHOWS_INSPECT_PROMPT;
153 }
154}
155
157 ChestData* data = entity->dataBuf.chest;
158 data->postLidAnimDelay = 10;
159 data->lidAngle = 0.0f;
160 data->openState = 0;
161 data->giveItemTimer = 40;
163}
164
166 ChestData* data = entity->dataBuf.chest;
167 f32 temp;
168
169 switch (data->openState) {
170 case 0:
171 data->postLidAnimDelay--;
172 data->lidAngle -= 1.0f;
173 if (data->lidAngle < -2.0f) {
174 data->lidAngle = -2.0f;
175 }
176
177 if (data->postLidAnimDelay == 0) {
178 data->postLidAnimDelay = 8;
179 data->openState++;
180 }
181 break;
182 case 1:
183 data->postLidAnimDelay--;
184 if (data->postLidAnimDelay == 0) {
185 data->lidAnimInterpPhase = 0.0f;
186 data->openState++;
187 }
188 break;
189 case 2:
190 data->lidAnimInterpPhase += 4.0f;
191 if (data->lidAnimInterpPhase >= 180.0f) {
192 data->openState++;
193 }
194 temp = sin_rad(DEG_TO_RAD(data->lidAnimInterpPhase)) * 3.0f;
195 data->lidAngle -= temp;
196 break;
197 case 3:
198 data->lidAnimInterpPhase += 1.0f;
199 if (data->lidAnimInterpPhase >= 190.0f) {
200 data->postLidAnimDelay = 10;
201 data->openState++;
202 }
203 temp = sin_rad(DEG_TO_RAD(data->lidAnimInterpPhase)) * 2.0f;
204 data->lidAngle -= temp;
205 break;
206 case 4:
207 data->postLidAnimDelay--;
208 if (data->postLidAnimDelay == 0) {
209 if (data->unk_07 != 0) {
211 } else {
212 data->openState++;
213 }
214 }
215 break;
216 case 5:
217 break;
218
219 }
220}
221
223 ChestData* data = entity->dataBuf.chest;
224 f32 delta;
225
226 switch (data->state) {
227 case 0:
228 data->lidAnimInterpPhase = 0.0f;
229 data->state++;
230 // fallthrough
231 case 1:
232 data->lidAnimInterpPhase += 5.0f;
233 if (data->lidAnimInterpPhase >= 180.0f) {
234 data->lidAnimInterpPhase = 180.0f;
235 data->state++;
236 }
237 delta = 2.6f * sin_rad(DEG_TO_RAD(data->lidAnimInterpPhase));
238 data->lidAngle += delta;
239 break;
240 case 2:
241 data->lidAnimInterpPhase += 1.0f;
242 if (data->lidAnimInterpPhase >= 185.0f) {
243 data->lidAnimInterpPhase = 185.0f;
244 data->postLidAnimDelay = 10;
245 data->state++;
246 }
247 delta = 2.0f * sin_rad(DEG_TO_RAD(data->lidAnimInterpPhase));
248 data->lidAngle += delta;
249 break;
250 case 3:
251 data->postLidAnimDelay--;
252 if (data->postLidAnimDelay == 0) {
253 data->state++;
254 entity->flags |= ENTITY_FLAG_4000;
255 }
256 break;
257 case 4:
258 break;
259 }
260}
261
263 ChestData* chest = entity->dataBuf.chest;
264 EffectInstance* effect = chest->gotItemEffect;
265
266 if (effect != NULL) {
267 effect->data.gotItemOutline->timeLeft = 10;
268 }
269}
270
272 PlayerStatus* playerStatus = &gPlayerStatus;
273 ChestData* chest = entity->dataBuf.chest;
274 f32 cosFwd;
275 f32 sinFwd;
276 f32 cosRight;
277 f32 sinRight;
278 f32 theta;
279 f32 giveItemLerpAlpha;
280 f32 horizontalOffset;
281 f32 dy;
282 f32 depthOffset;
283 f32 intermediateTheta;
284 f32 radius;
285
286 if (chest->itemID != 0) {
288 }
289 entity_Chest_open(entity);
290
291 switch (chest->state) {
292 case 0:
293 chest->giveItemTimer--;
294 if (chest->giveItemTimer == 0) {
295 chest->giveItemRadiusInterpPhase = 0.0f;
296 chest->state++;
297 chest->giveItemHeightInterpPhase = 20.0f;
298 chest->itemVelY = 8.0f;
299 }
300 break;
301 case 1:
302 chest->itemEntityPos.y += chest->itemVelY;
303 chest->itemVelY -= 0.7;
304 if (chest->itemVelY <= 2.0f) {
305 chest->itemVelY = 6.0f;
306 chest->state++;
307 }
308 break;
309 case 2:
310 if (chest->giveItemHeightInterpPhase < 140.0f) {
312 } else {
313 dy = (chest->itemEntityPos.y - playerStatus->pos.y - 30.0f) * 0.25f;
314 if (dy <= 0.4) {
315 dy = 0.4f;
316 }
317 chest->itemEntityPos.y -= dy;
318 }
319 giveItemLerpAlpha = sin_rad(DEG_TO_RAD(chest->giveItemRadiusInterpPhase));
320 theta = intermediateTheta = clamp_angle(atan2(entity->pos.x, entity->pos.z, playerStatus->pos.x, playerStatus->pos.z));
321
322 // hardcoded areaID
324 radius = 3.0f;
325 } else {
326 radius = 4.0f;
327 }
328
329 theta *= TAU;
330 theta = theta / 360.0f;
331 chest->itemEntityPos.x += (radius * sin_rad(theta) * giveItemLerpAlpha);
332 chest->itemEntityPos.z -= (radius * cos_rad(theta) * giveItemLerpAlpha);
333 chest->giveItemRadiusInterpPhase += 8.0f;
334 if (chest->giveItemRadiusInterpPhase >= 180.0f) {
335 chest->giveItemRadiusInterpPhase = 180.0f;
336 }
337 chest->giveItemHeightInterpPhase += 13.0f;
338 if (chest->giveItemHeightInterpPhase >= 180.0f){
339 chest->giveItemTimer = 7;
340 chest->giveItemHeightInterpPhase = 180.0f;
341 chest->state++;
342 if (chest->itemID != 0) {
343 suggest_player_anim_always_forward(ANIM_MarioW1_Lift);
344 sin_cos_rad(DEG_TO_RAD(90.0f - gCameras[CAM_DEFAULT].curYaw), &sinRight, &cosRight);
345 sin_cos_rad(DEG_TO_RAD(180.0f - gCameras[CAM_DEFAULT].curYaw), &sinFwd, &cosFwd);
346 horizontalOffset = 0.0f;
347 depthOffset = 4.0f;
348 //RadialFlowOut
349 fx_radial_shimmer(0, chest->itemEntityPos.x + horizontalOffset * sinRight - depthOffset * sinFwd,
350 chest->itemEntityPos.y + 12.0f, chest->itemEntityPos.z - cosRight * horizontalOffset + cosFwd * depthOffset, 1.0f, 0x64);
351 //GotItemOutline
352 fx_got_item_outline(0, chest->itemEntityPos.x + horizontalOffset * sinRight - sinFwd * depthOffset,
353 chest->itemEntityPos.y + 12.0f, chest->itemEntityPos.z - cosRight * horizontalOffset + cosFwd * depthOffset, 1.0f, &chest->gotItemEffect);
354 }
355 }
356 break;
357 case 3:
358 chest->giveItemTimer--;
359 if (chest->giveItemTimer == 0) {
361 chest->state = 0;
362 }
363 break;
364 }
365}
366
368 ChestData* data = entity->dataBuf.chest;
369 f32 angle;
370 s32 flagIndex;
371
372 switch (data->itemID) {
373 case ITEM_BOOTS:
375 break;
376 case ITEM_SUPER_BOOTS:
378 break;
379 case ITEM_ULTRA_BOOTS:
381 break;
382 case ITEM_HAMMER:
384 break;
385 case ITEM_SUPER_HAMMER:
387 break;
388 case ITEM_ULTRA_HAMMER:
390 break;
391 }
392
393 if (data->itemID != 0) {
394 angle = DEG_TO_RAD(entity->rot.y);
395 data->itemEntityPos.x = entity->pos.x + (sin_rad(angle) * 10.0f);
396 data->itemEntityPos.y = entity->pos.y;
397 data->itemEntityPos.z = entity->pos.z + (cos_rad(angle) * 10.0f);
399 data->itemEntityPos.x, data->itemEntityPos.y, data->itemEntityPos.z,
401 }
402
403 flagIndex = data->gameFlagIndex;
404 if (flagIndex <= EVT_GAME_FLAG_CUTOFF) {
405 flagIndex = EVT_INDEX_OF_GAME_FLAG(flagIndex);
406 }
407 set_global_flag(flagIndex);
408}
409
413
415 ChestData* data = entity->dataBuf.chest;
416 if (data->itemID != 0) {
418 }
419}
420
422 ChestData* data = entity->dataBuf.chest;
423 if (data->itemID != 0) {
424 if (data->gotItemDone) {
427 suggest_player_anim_allow_backward(ANIM_Mario1_Idle);
429 data->itemID = -1;
430 }
431 return;
432 }
434}
435
437 ChestData* data = entity->dataBuf.chest;
438 data->itemID = -1;
439}
440
442 ChestData* data = entity->dataBuf.chest;
444 data->gameFlagIndex = 0xFFFF;
445}
446
451
453 ChestData* data = entity->dataBuf.chest;
454 data->unk_07 = 1;
455 entity_Chest_readargs(entity);
457 entity->scale.x = 0.56f;
458 entity->scale.y = 0.56f;
459 entity->scale.z = 0.56f;
460}
461
478
497
500 .typeDataSize = sizeof(ChestData),
501 .renderCommandList = Entity_Chest_RenderScript,
502 .modelAnimationNodes = 0,
503 .fpInit = entity_GiantChest_init,
504 .updateEntityScript = Entity_GiantChest_Script,
505 .fpHandleCollision = NULL,
506 { .dma = ENTITY_ROM(Chest) },
507 .entityType = ENTITY_TYPE_CHEST,
508 .aabbSize = { 50, 45, 46 }
509};
512 .typeDataSize = sizeof(ChestData),
513 .renderCommandList = Entity_Chest_RenderScript,
514 .modelAnimationNodes = 0,
515 .fpInit = entity_Chest_init,
516 .updateEntityScript = Entity_Chest_Script,
517 .fpHandleCollision = NULL,
518 { .dma = ENTITY_ROM(Chest) },
519 .entityType = ENTITY_TYPE_CHEST,
520 .aabbSize = { 28, 26, 23 }
521};
EvtScript Entity_Chest_AdjustCam_ISK
Definition Chest.c:19
EntityBlueprint Entity_Chest
Definition Chest.c:510
void entity_Chest_start_bound_script(Entity *entity)
Definition Chest.c:410
EntityModelScript Entity_Chest_RenderScript
Definition Chest.c:496
Gfx Entity_Chest_RenderBox[]
Definition Chest.c:150
EvtScript Entity_Chest_AdjustCam_TIK
Definition Chest.c:42
void entity_GiantChest_give_equipment(Entity *entity)
Definition Chest.c:367
void entity_GiantChest_hide_effect(Entity *entity)
Definition Chest.c:262
void entity_GiantChest_init(Entity *entity)
Definition Chest.c:447
void entity_Chest_begin_opening(Entity *entity)
Definition Chest.c:156
Mtx Entity_Chest_LidMtx
Definition Chest.c:58
EvtScript Entity_Chest_AdjustCam_KZN
Definition Chest.c:50
EvtScript Entity_Chest_ResetCam_Default
Definition Chest.c:58
EntityBlueprint Entity_GiantChest
Definition Chest.c:498
void entity_Chest_close(Entity *entity)
Definition Chest.c:222
void entity_Chest_clear_item_id(Entity *entity)
Definition Chest.c:436
void entity_Chest_readargs(Entity *entity)
Definition Chest.c:441
void entity_Chest_setupGfx(s32 entityIndex)
Definition Chest.c:100
void entity_Chest_init(Entity *entity)
Definition Chest.c:452
Gfx Entity_Chest_RenderLid[]
Definition Chest.c:110
void entity_GiantChest_await_got_item(Entity *entity)
Definition Chest.c:421
void entity_Chest_check_opened(Entity *entity)
Definition Chest.c:119
void entity_GiantChest_open(Entity *entity)
Definition Chest.c:271
EvtScript Entity_Chest_ResetCam_ISK
Definition Chest.c:34
EntityScript Entity_Chest_Script
Definition Chest.c:483
void entity_Chest_reset_camera(Entity *entity)
Definition Chest.c:86
EntityScript Entity_GiantChest_Script
Definition Chest.c:462
EntityScript Entity_Chest_ScriptOpened
Definition Chest.c:479
void entity_Chest_idle(Entity *entity)
Definition Chest.c:129
void entity_Chest_open(Entity *entity)
Definition Chest.c:165
void entity_Chest_enable_player_input(Entity *entity)
Definition Chest.c:414
void entity_Chest_adjust_camera(Entity *entity)
Definition Chest.c:67
Mtx matrixStack[0x200]
f32 Matrix4f[4][4]
Bytecode EvtScript[]
struct ChestData * chest
#define guRotateF
#define guMtxF2L
#define guMtxCatF
#define clamp_angle
#define atan2
struct GotItemOutlineFXData * gotItemOutline
Definition effects.h:2491
EffectData data
Definition effects.h:2605
s32 CreateEntityVarArgBuffer[]
Definition entity.c:35
s32 EntityModelScript[]
Definition entity.h:7
f32 giveItemRadiusInterpPhase
Definition entity.h:204
#define es_Call(func)
Definition entity.h:37
#define es_Restart
Definition entity.h:40
Vec3f itemEntityPos
Definition entity.h:203
#define STANDARD_ENTITY_MODEL_SCRIPT(gfx, renderMode)
Definition entity.h:56
s32 itemEntityIndex
Definition entity.h:202
#define ENTITY_ADDR(entity, type, data)
Definition entity.h:64
#define es_SetCallback(func, time)
Definition entity.h:38
s8 postLidAnimDelay
Definition entity.h:197
u8 state
Definition entity.h:195
s32 itemID
Definition entity.h:201
#define ENTITY_ROM(name)
Definition entity.h:65
s8 gotItemDone
Definition entity.h:207
f32 lidAngle
Definition entity.h:199
u16 gameFlagIndex
Definition entity.h:193
s8 unk_07
Definition entity.h:198
f32 lidAnimInterpPhase
Definition entity.h:200
struct EffectInstance * gotItemEffect
Definition entity.h:209
u8 openState
Definition entity.h:196
s32 EntityScript[]
Definition entity.h:6
#define es_End
Definition entity.h:35
s16 giveItemTimer
Definition entity.h:194
f32 giveItemHeightInterpPhase
Definition entity.h:205
f32 itemVelY
Definition entity.h:206
@ ITEM_SPAWN_MODE_DECORATION
Definition enums.h:2292
@ ENTITY_TYPE_CHEST
Definition enums.h:2587
@ AREA_KZN
Definition enums.h:2978
@ AREA_ISK
Definition enums.h:2971
@ AREA_TIK
Definition enums.h:2962
@ PA_FLAG_INTERACT_PROMPT_AVAILABLE
! prompt
Definition enums.h:3095
@ PA_FLAG_USING_WATT
Definition enums.h:3090
@ ENTITY_COLLISION_PLAYER_TOUCH_WALL
Definition enums.h:2651
@ ENTITY_COLLISION_PLAYER_TOUCH_FLOOR
Definition enums.h:2648
@ SOUND_OPEN_CHEST
Definition enums.h:867
@ RENDER_MODE_SURFACE_OPA
Definition enums.h:3264
@ ENTITY_FLAG_8000
Definition enums.h:2628
@ ENTITY_FLAG_SHOWS_INSPECT_PROMPT
Definition enums.h:2625
@ ENTITY_FLAG_4000
Definition enums.h:2627
@ CAM_DEFAULT
Definition enums.h:1800
@ EVT_PRIORITY_A
Definition evt.h:153
@ EVT_FLAG_RUN_IMMEDIATELY
don't wait for next update_scripts call
Definition evt.h:161
Entity * get_entity_by_index(s32 index)
Definition entity.c:530
f32 fabsf(f32 f)
void suggest_player_anim_always_forward(AnimID anim)
Definition 77480.c:913
s32 disable_player_input(void)
Definition 77480.c:990
s32 entity_start_script(Entity *entity)
Definition entity.c:560
f32 cos_rad(f32 x)
Definition 43F0.c:717
s32 make_item_entity_nodelay(s32 itemID, f32 x, f32 y, f32 z, s32 itemSpawnMode, s32 pickupVar)
s32 enable_player_input(void)
Definition 77480.c:998
Evt * start_script(EvtScript *source, s32 priority, s32 initialState)
void set_entity_commandlist(Entity *entity, s32 *entityScript)
Definition entity.c:235
void func_800EF3E4(void)
Definition partners.c:2418
void remove_item_entity_by_index(s32 index)
void suggest_player_anim_allow_backward(AnimID anim)
Definition 77480.c:894
void exec_entity_commandlist(Entity *entity)
Definition entity.c:313
f32 sin_rad(f32 x)
Definition 43F0.c:713
void sin_cos_rad(f32 rad, f32 *outSinTheta, f32 *outCosTheta)
Definition 43F0.c:706
void set_item_entity_position(s32 itemEntityIndex, f32 x, f32 y, f32 z)
void sfx_play_sound(s32 soundID)
Definition sfx.c:517
ApiStatus ResetCam(Evt *script, b32 isInitialCall)
ApiStatus SetCamPitch(Evt *script, b32 isInitialCall)
ApiStatus PanToTarget(Evt *script, b32 isInitialCall)
ApiStatus SetCamDistance(Evt *script, b32 isInitialCall)
ApiStatus AdjustCam(Evt *script, b32 isInitialCall)
ApiStatus WaitForCam(Evt *script, b32 isInitialCall)
ApiStatus GetPlayerPos(Evt *script, b32 isInitialCall)
ApiStatus UseSettingsFrom(Evt *script, b32 isInitialCall)
ApiStatus SetPanTarget(Evt *script, b32 isInitialCall)
ApiStatus SetCamSpeed(Evt *script, b32 isInitialCall)
#define End
Signals the end of EVT script data. A script missing this will likely crash on load.
Definition macros.h:213
#define TAU
Definition macros.h:128
#define Float(DOUBLE)
Definition macros.h:51
#define EVT_GAME_FLAG_CUTOFF
Definition macros.h:34
#define Thread
Marks the start of a thread block.
Definition macros.h:544
#define EndThread
Marks the end of a thread block.
Definition macros.h:547
#define LVar2
Definition macros.h:150
#define DEG_TO_RAD(deg)
Definition macros.h:134
#define LVar1
Definition macros.h:149
#define Call(FUNC, ARGS...)
Calls a given C EVT API function with any number of arguments.
Definition macros.h:576
#define EVT_INDEX_OF_GAME_FLAG(v)
Definition macros.h:142
#define LVar0
Definition macros.h:148
#define Return
Kills the current EVT thread.
Definition macros.h:217
void(* renderSetupFunc)(s32)
EntityData dataBuf
Vec3f scale
u8 collisionFlags
u8 Addr[]
Linker symbol address, as in ld_addrs.h.
Definition types.h:16
GameStatus * gGameStatusPtr
Definition main_loop.c:32
Camera gCameras[4]
Definition cam_main.c:17
Gfx * gMainGfxPos
Definition cam_main.c:15
PlayerData gPlayerData
Definition 77480.c:40
u16 gMatrixListPos
Definition main_loop.c:45
PlayerStatus gPlayerStatus
Definition 77480.c:39
DisplayContext * gDisplayContext
Definition cam_main.c:16
s32 set_global_flag(s32 index)
Definition vars_access.c:65
s32 get_global_flag(s32 index)
Definition vars_access.c:89