Paper Mario DX
Paper Mario (N64) modding
 
Loading...
Searching...
No Matches
entity.c
Go to the documentation of this file.
1#include "common.h"
2#include "vars_access.h"
3#include "ld_addrs.h"
4#include "entity.h"
5#include "model.h"
6#include "sprite/player.h"
7
8#ifdef SHIFT
9extern Addr WorldEntityHeapBottom;
11#define WORLD_ENTITY_HEAP_BOTTOM (s32) WorldEntityHeapBottom
12#define WORLD_ENTITY_HEAP_BASE (s32) WorldEntityHeapBase
13#define entity_jan_iwa_VRAM (void*) entity_jan_iwa_VRAM
14#define entity_sbk_omo_VRAM (void*) entity_sbk_omo_VRAM
15#define entity_default_VRAM (void*) entity_default_VRAM
16#else
17#define WORLD_ENTITY_HEAP_BOTTOM 0x80250000
18#define WORLD_ENTITY_HEAP_BASE 0x80267FF0
19#define entity_jan_iwa_VRAM (void*) 0x802BAE00
20#define entity_sbk_omo_VRAM (void*) 0x802BAE00
21#define entity_default_VRAM (void*) 0x802BAE00
22#endif
23
24#if VERSION_JP // TODO remove once segments are split
25extern Addr entity_default_ROM_END;
26extern Addr entity_default_ROM_START;
27extern Addr entity_jan_iwa_ROM_END;
28extern Addr entity_jan_iwa_ROM_START;
29extern Addr entity_sbk_omo_ROM_END;
30extern Addr entity_sbk_omo_ROM_START;
31#endif
32
33s32 D_8014AFB0 = 255;
34
38
45
50
57
60
64
65extern Addr BattleEntityHeapBottom; // todo ???
66
67void update_shadows(void);
69void entity_swizzle_anim_pointers(EntityBlueprint* entityData, void* baseAnim, void* baseGfx);
70void render_shadows(void);
74void delete_entity(s32 entityIndex);
75void delete_entity_and_unload_data(s32 entityIndex);
79s32 create_entity_shadow(Entity* entity, f32 x, f32 y, f32 z);
81
82void update_entities(void) {
83 s32 i;
84
85 D_801512BC = 0;
88
89 for (i = 0; i < MAX_ENTITIES; i++) {
90 Entity* entity = get_entity_by_index(i);
91
92 if (entity != NULL) {
94
95 if (!(entity->flags & ENTITY_FLAG_SKIP_UPDATE)) {
97 entity->flags &= ~ENTITY_FLAG_BOUND_SCRIPT_DIRTY;
98 if (!(entity->flags & ENTITY_FLAG_8000)) {
99 entity->flags |= ENTITY_FLAG_2000000;
100 }
102 }
103
104 if (entity->flags & ENTITY_FLAG_2000000) {
105 if (does_script_exist(entity->boundScript->id)) {
108 } else {
110 }
111
114 }
115
118 }
119 continue;
120 } else {
121 entity->flags &= ~ENTITY_FLAG_2000000;
122 }
123 }
124
125 if (entity->collisionTimer == 0) {
127
128 if (entity->collisionFlags) {
129 EntityCallback handleCollision = entity->blueprint->fpHandleCollision;
130
131 if (handleCollision != NULL && handleCollision(entity) != 0) {
132 entity->collisionTimer = 10;
134 }
135 }
136 } else {
137 entity->collisionTimer--;
139 if (entity->collisionTimer == 0) {
141 } else {
143 }
144 } else if (entity->collisionTimer == 0) {
145 entity->flags &= ~ENTITY_FLAG_DETECTED_COLLISION;
146 entity->flags &= ~ENTITY_FLAG_PARTNER_COLLISION;
147 entity->collisionFlags = 0;
148 }
149 }
150
153 }
154
156 if (entity->updateScriptCallback != NULL) {
157 entity->updateScriptCallback(entity);
158 }
159
160 if (entity->scriptReadPos != NULL) {
161 if (entity->scriptDelay != 0) {
162 entity->scriptDelay--;
163 if (entity->scriptDelay == 0) {
164 while (step_entity_commandlist(entity));
165 }
166 }
167 }
168 }
169
172 }
173
174 if (!(entity->flags & ENTITY_FLAG_DISABLE_COLLISION)) {
176 }
177
180 } else {
182 }
183
184 if (entity->shadowIndex >= 0) {
186 }
187
189 delete_entity(entity->listIndex);
190 }
191
194 }
195 }
196 }
197 }
198
201}
202
203void update_shadows(void) {
204 s32 i;
205
207
208 for (i = 0; i < MAX_SHADOWS; i++) {
209 Shadow* shadow = get_shadow_by_index(i);
210
211 if (shadow != NULL) {
213
214 if (!(shadow->flags & ENTITY_FLAG_SKIP_UPDATE)) {
217 }
218
220
223 } else {
225 }
226
228 delete_shadow(shadow->listIndex);
229 }
230 }
231 }
232 }
233}
234
235void set_entity_commandlist(Entity* entity, s32* entityScript) {
236 entity->scriptReadPos = entityScript;
237 entity->scriptDelay = 1;
238 entity->savedReadPos[0] = entity->scriptReadPos;
239}
240
242 s32* args = entity->scriptReadPos;
243 s32 ret;
244 s32 labelId;
245 void (*tempfunc)(Entity*);
246
247 switch (*args++) {
249 entity->scriptDelay = -1;
250 entity->updateScriptCallback = NULL;
251 entity->scriptReadPos = NULL;
252 ret = FALSE;
253 break;
255 entity->scriptReadPos = (s32*)*args;
256 entity->scriptDelay = 1;
257 entity->savedReadPos[0] = entity->scriptReadPos;
258 ret = TRUE;
259 break;
261 tempfunc = (void (*)(Entity*))(*args++);
262 entity->scriptReadPos = args;
263 (tempfunc)(entity);
264 ret = TRUE;
265 break;
267 entity->scriptDelay = *args++;
268 entity->updateScriptCallback = (s32 (*)(Entity*)) *args++;
269 entity->scriptReadPos = args++;
270 ret = FALSE;
271 break;
273 entity->scriptReadPos = entity->savedReadPos[*args];
274 ret = TRUE;
275 break;
277 labelId = *args++;
278 entity->savedReadPos[labelId] = args;
279 entity->scriptReadPos = args;
280 ret = TRUE;
281 break;
283 if (entity->boundScriptBytecode != NULL) {
285 }
286 entity->scriptReadPos = args++;
287 ret = TRUE;
288 break;
290 entity->flags |= *args++;
291 entity->scriptReadPos = args++;
292 ret = TRUE;
293 break;
295 entity->flags &= ~*args++;
296 entity->scriptReadPos = args++;
297 ret = TRUE;
298 break;
300 sfx_play_sound(*args++);
301 entity->scriptReadPos = args++;
302 ret = TRUE;
303 break;
304 default:
305 args++;
306 entity->scriptReadPos = args++;
307 ret = TRUE;
308 break;
309 }
310 return ret;
311}
312
314 while (step_entity_commandlist(entity));
315}
316
317void func_8010FD98(void* arg0, s32 alpha) {
318 if (alpha >= 255) {
319 gDPSetRenderMode(gMainGfxPos++, G_RM_AA_ZB_OPA_SURF, G_RM_AA_ZB_OPA_SURF2);
320 gDPSetCombineMode(gMainGfxPos++, G_CC_MODULATEIA, G_CC_MODULATEIA);
321 } else {
322 gDPSetCombineMode(gMainGfxPos++, PM_CC_01, PM_CC_02);
323 gDPSetPrimColor(gMainGfxPos++, 0, 0, 0, 0, 0, alpha);
324 }
325}
326
327void func_8010FE44(void* arg0) {
329}
330
332 s32 alpha = (s32)data;
333
334 gDPSetCombineMode(gMainGfxPos++, PM_CC1_SHADOW, PM_CC2_SHADOW);
335 gDPSetPrimColor(gMainGfxPos++, 0, 0, 0, 0, 0, alpha);
336}
337
338void render_entities(void) {
339 s32 i;
340
341 for (i = 0; i < MAX_ENTITIES; i++) {
342 Entity* entity = get_entity_by_index(i);
343
344 if (entity != NULL) {
350 entity->pos.x,
351 entity->pos.z) > 200.0f
352 ) {
353 continue;
354 }
355
358 continue;
359 }
360 } else if (gEntityHideMode == ENTITY_HIDE_MODE_2) {
362 continue;
363 }
364 }
365 }
366
367 if (!(entity->flags & ENTITY_FLAG_HIDDEN)) {
369 if (D_8014AFB0 == 255) {
370 if (entity->renderSetupFunc != NULL) {
372 entity->virtualModelIndex,
373 (void*)(u32) entity->listIndex,
374 (void (*)(void*)) entity->renderSetupFunc
375 );
376 }
377 } else {
379 entity->virtualModelIndex,
380 (void*)(u32) entity->listIndex,
382 );
383 }
384
385 if (entity->gfxBaseAddr == NULL) {
387 } else {
389 &entity->transformMatrix,
390 entity->vertexSegment,
391 entity->gfxBaseAddr);
392 }
393 } else {
394 if (D_8014AFB0 == 255) {
395 if (entity->renderSetupFunc != NULL) {
397 entity->virtualModelIndex,
398 (void*)(u32) entity->listIndex,
399 (void (*)(void*)) entity->renderSetupFunc
400 );
401 } else {
403 }
404 } else {
406 }
407
408 if (entity->gfxBaseAddr == NULL) {
410 } else {
412 &entity->transformMatrix,
413 entity->vertexSegment,
414 entity->gfxBaseAddr);
415 }
416 }
417 }
418 }
419 }
420
422}
423
424void render_shadows(void) {
425 s32 i;
426
427 for (i = 0; i < MAX_SHADOWS; i++) {
428 Shadow* shadow = get_shadow_by_index(i);
429
430 if (shadow != NULL) {
431 if (shadow->flags & ENTITY_FLAG_HIDDEN) {
432 if (shadow->flags & ENTITY_FLAG_FADING_AWAY) {
433 shadow->alpha -= 20;
434 if (shadow->alpha <= 20) {
436 }
437 }
438 } else if (shadow->flags & ENTITY_FLAG_HAS_ANIMATED_MODEL) {
439 if (shadow->vertexArray == NULL) {
441 } else {
443 &shadow->transformMatrix,
444 shadow->vertexSegment,
445 shadow->vertexArray);
446 }
447 } else {
448 if (shadow->flags & ENTITY_FLAG_FADING_AWAY) {
449 shadow->alpha -= 20;
450 if (shadow->alpha <= 20) {
452 }
453 }
454
456
457 if (shadow->vertexArray == NULL) {
459 } else {
461 &shadow->transformMatrix,
462 shadow->vertexSegment,
463 shadow->vertexArray);
464 }
465 }
466 }
467 }
468}
469
471 Matrix4f sp18;
472 Matrix4f sp58;
473 Matrix4f sp98;
474 Matrix4f spD8;
475 Matrix4f sp118;
476 Matrix4f sp158;
477 Matrix4f sp198;
478
479 if (entity->updateMatrixOverride != NULL) {
480 entity->updateMatrixOverride(entity);
481 return;
482 }
483
484 guTranslateF(sp58, entity->pos.x, entity->pos.y, entity->pos.z);
485 guRotateF(spD8, entity->rot.x, 1.0f, 0.0f, 0.0f);
486 guRotateF(sp118, entity->rot.y, 0.0f, 1.0f, 0.0f);
487 guRotateF(sp158, entity->rot.z, 0.0f, 0.0f, 1.0f);
488 guMtxCatF(sp158, spD8, sp18);
489 guMtxCatF(sp18, sp118, sp98);
490 guScaleF(sp198, entity->scale.x, entity->scale.y, entity->scale.z);
491 guMtxCatF(sp198, sp98, sp18);
492 guMtxCatF(sp18, sp58, sp98);
493 guMtxF2L(sp98, &entity->transformMatrix);
494}
495
497 Matrix4f sp18;
498 Matrix4f sp58;
499 Matrix4f sp98;
500 Matrix4f spD8;
501 Matrix4f sp118;
502 Matrix4f sp158;
503 Matrix4f sp198;
504
505 guTranslateF(sp58, shadow->pos.x, shadow->pos.y, shadow->pos.z);
506 guRotateF(sp118, shadow->rot.x, 1.0f, 0.0f, 0.0f);
507 guRotateF(spD8, shadow->rot.y, 0.0f, 1.0f, 0.0f);
508 guRotateF(sp158, shadow->rot.z, 0.0f, 0.0f, 1.0f);
509 guMtxCatF(sp158, sp118, sp98);
510 guMtxCatF(spD8, sp98, sp98);
511 guScaleF(sp198, shadow->scale.x, shadow->scale.y, shadow->scale.z);
512 guMtxCatF(sp198, sp98, sp18);
513 guMtxCatF(sp18, sp58, sp98);
514 guMtxF2L(sp98, &shadow->transformMatrix);
515}
516
518 Matrix4f sp18;
519 Matrix4f sp58;
520
521 guRotateF(sp18, -entity->rot.y, 0.0f, 1.0f, 0.0f);
522 guRotateF(sp58, -entity->rot.z, 0.0f, 0.0f, 1.0f);
523 guMtxCatF(sp18, sp58, sp18);
524 guRotateF(sp58, -entity->rot.x, 1.0f, 0.0f, 0.0f);
525 guMtxCatF(sp18, sp58, entity->inverseTransformMatrix);
526
527 entity->effectiveSize = sqrtf(((SQ(entity->aabb.x) + SQ(entity->aabb.z)) * 0.25f) + SQ(entity->aabb.y));
528}
529
531 return (*gCurrentEntityListPtr)[index & 0xFFF];
532}
533
535 return (*gCurrentShadowListPtr)[index & 0xFFF];
536}
537
539 EntityList* ret;
540
542 ret = &gWorldEntityList;
543 } else {
544 ret = &gBattleEntityList;
545 }
546 return ret;
547}
548
550 ShadowList* ret;
551
553 ret = &gWorldShadowList;
554 } else {
555 ret = &gBattleShadowList;
556 }
557 return ret;
558}
559
561 if (entity->boundScriptBytecode != NULL) {
563 return 1;
564 }
565 return 0;
566}
567
568u32 get_entity_type(s32 index) {
569 Entity* entity = get_entity_by_index(index);
570
571 if (entity == NULL) {
572 return -1;
573 } else {
574 return entity->blueprint->entityType;
575 }
576}
577
578void delete_entity(s32 entityIndex) {
579 Entity* entity = get_entity_by_index(entityIndex);
580
581 if (entity->dataBuf.any != NULL) {
582 heap_free(entity->dataBuf.any);
583 }
584
585 if (!(entity->flags & ENTITY_FLAG_HAS_ANIMATED_MODEL)) {
587 } else {
589 }
590
591 if (entity->shadowIndex >= 0) {
592 Shadow* shadow = get_shadow_by_index(entity->shadowIndex);
593
595 }
596
597 heap_free((*gCurrentEntityListPtr)[entityIndex]);
598 (*gCurrentEntityListPtr)[entityIndex] = NULL;
599}
600
601void delete_entity_and_unload_data(s32 entityIndex) {
602 Entity* entity = get_entity_by_index(entityIndex);
603
604 if (entity->dataBuf.any != NULL) {
605 heap_free(entity->dataBuf.any);
606 }
607
608 if (!(entity->flags & ENTITY_FLAG_HAS_ANIMATED_MODEL)) {
610 } else {
612 }
613
615
616 if (entity->shadowIndex >= 0) {
617 Shadow* shadow = get_shadow_by_index(entity->shadowIndex);
618
620 }
621
622 heap_free((*gCurrentEntityListPtr)[entityIndex]);
623 (*gCurrentEntityListPtr)[entityIndex] = NULL;
624}
625
626void delete_shadow(s32 shadowIndex) {
627 Shadow* shadow = get_shadow_by_index(shadowIndex);
628
630 heap_free((*gCurrentShadowListPtr)[shadowIndex]);
631 (*gCurrentShadowListPtr)[shadowIndex] = NULL;
632}
633
635 u32 listIndex = entity->listIndex;
636 s32 entityFlags = 0;
637 u32 flag;
638
639 if (entity->flags & ENTITY_FLAG_PARTNER_COLLISION) {
640 entityFlags = ENTITY_COLLISION_PARTNER;
641 entity->flags &= ~ENTITY_FLAG_PARTNER_COLLISION;
642 }
643
645 if (flag != -1 && (flag & COLLISION_WITH_ENTITY_BIT) && listIndex == (u8)flag) {
647 }
648
650 if (flag != -1 && (flag & COLLISION_WITH_ENTITY_BIT) && listIndex == (u8)flag) {
652 }
653
655 if (flag != -1 && (flag & COLLISION_WITH_ENTITY_BIT) && listIndex == (u8)flag) {
657 }
658
660 if (flag != -1 && (flag & COLLISION_WITH_ENTITY_BIT) && listIndex == (u8)flag) {
662 }
663
665 if (flag != -1 && (flag & COLLISION_WITH_ENTITY_BIT) && listIndex == (u8)flag) {
666 entityFlags |= ENTITY_COLLISION_PLAYER_HAMMER;
667 }
668
670 if (flag != -1 && (flag & COLLISION_WITH_ENTITY_BIT) && listIndex == (u8)flag && gPlayerStatusPtr->pressedButtons & BUTTON_A) {
672 }
673
674 return entityFlags;
675}
676
678 s32 interacted = FALSE;
679 u32 entityType = get_entity_type(entityIdx);
680 s32 partnerID = get_current_partner_id();
681 Entity* entity;
682
683 switch (partnerID) {
684 case PARTNER_BOMBETTE:
685 switch (entityType) {
686 default:
687 return FALSE;
702 entity = get_entity_by_index(entityIdx);
704 interacted = TRUE;
705 }
706 break;
707 case PARTNER_KOOPER:
708 switch (entityType) {
709 default:
710 return FALSE;
722 case ENTITY_TYPE_1C:
725 entity = get_entity_by_index(entityIdx);
727 interacted = TRUE;
728 }
729 break;
730 }
731 return interacted;
732}
733
735 f32 yTemp = entity->pos.y - (gPlayerStatus.pos.y + gPlayerStatus.colliderHeight);
736 f32 xCollRadius;
737 f32 zCollRadius;
738 f32 xDist;
739 f32 zDist;
740
741 if (yTemp > 0.0f || gPlayerStatus.colliderHeight + entity->aabb.y < fabsf(yTemp)) {
742 return 0;
743 }
744
745 xCollRadius = (gPlayerStatus.colliderDiameter + entity->aabb.x) * 0.5;
746 xDist = fabsf(gPlayerStatus.pos.x - entity->pos.x);
747 zCollRadius = ((gPlayerStatus.colliderDiameter + entity->aabb.z) * 0.5);
748 zDist = fabsf(gPlayerStatus.pos.z - entity->pos.z);
749
750 if (xCollRadius < xDist || zCollRadius < zDist) {
751 return 0;
752 }
753
754 return 1;
755}
756
757s32 is_player_action_state(s8 actionState) {
758 return actionState == gPlayerStatus.actionState;
759}
760
766
768 entity->collisionTimer = 0;
769 entity->flags &= ~ENTITY_FLAG_DETECTED_COLLISION;
770}
771
773 //TODO hardcoded map and area IDs, connect these to MapTable.xml eventually
776 DMA_COPY_SEGMENT(entity_jan_iwa);
778 DMA_COPY_SEGMENT(entity_sbk_omo);
779 } else {
780 DMA_COPY_SEGMENT(entity_default);
781 }
782
784 }
785}
786
788 s32 i;
789
790 D_801516FC = 1;
794 D_80151304 = 0;
795
798 }
799
803 if (!arg0) {
804 D_80151344 = 0;
805 }
806 D_8014AFB0 = 255;
807
810 for (i = 0; i < MAX_ENTITIES; i++) {
811 wEntityBlueprint[i] = NULL;
812 }
813 } else {
815 for (i = 0; i < ARRAY_COUNT(bEntityBlueprint); i++) {
816 bEntityBlueprint[i] = NULL;
817 }
818 }
819
823 } else {
826 }
827
830
831 for (i = 0; i < MAX_ENTITIES; i++) {
832 (*gCurrentEntityListPtr)[i] = NULL;
833 }
834
835 for (i = 0; i < MAX_SHADOWS; i++) {
836 (*gCurrentShadowListPtr)[i] = NULL;
837 }
838}
839
859
861 s32 i;
862 s32 totalSize = 0;
863 s32 temp1;
864 s32 dataLength;
865 void* gfxData;
866 void* animData;
867
868 for (i = 0; i < MAX_ENTITIES; i++) {
870 if (bp == NULL) {
871 break;
872 }
873
875 void* gfxData;
876
877 dataLength = ((bp->dma.end - bp->dma.start) >> 2);
878 gfxData = (void*)(gEntityHeapBase - totalSize * 4 - dataLength * 4);
879 totalSize += dma_copy(bp->dma.start, bp->dma.end, gfxData) >> 2;
880 } else {
881 DmaEntry* dmaList = bp->dmaList;
882
884 gfxData = (void*)gEntityHeapBottom;
885 temp1 = dma_copy(dmaList[0].start, dmaList[0].end, gfxData) >> 2;
886 dma_copy(dmaList[1].start, dmaList[1].end, (void*)(gEntityHeapBottom + temp1 * 4)) >> 2;
887 animData = (void*)(gEntityHeapBottom + temp1 * 4);
888 entity_swizzle_anim_pointers(bp, animData, gfxData);
889 } else {
890 s32 temp5;
891 s32 q;
892
893 dataLength = ((dmaList[0].end - dmaList[0].start) >> 2);
894 q = gEntityHeapBase - totalSize * 4;
895 gfxData = (void*)(q - dataLength * 4);
896 totalSize += dma_copy(dmaList[0].start, dmaList[0].end, gfxData) >> 2;
897
898 dataLength = ((dmaList[1].end - dmaList[1].start) >> 2);
899 q = gEntityHeapBase - totalSize * 4;
900 animData = (void*)(q - dataLength * 4);
901 totalSize += dma_copy(dmaList[1].start, dmaList[1].end, animData) >> 2;
902
903 entity_swizzle_anim_pointers(bp, animData, gfxData);
904 }
905 }
906 }
907}
908
909void entity_swizzle_anim_pointers(EntityBlueprint* entityData, void* baseAnim, void* baseGfx) {
910 StaticAnimatorNode* node;
911 s32* ptr = (s32*)((s32)baseAnim + (s32)entityData->modelAnimationNodes);
912
913 while (TRUE) {
914 if (*ptr == -1) {
915 *ptr = 0;
916 return;
917 }
918 node = (StaticAnimatorNode*)((s32)baseAnim + ((*ptr) & 0xFFFF));
919 *ptr++ = (s32)node;
920
921 if ((s32)node->displayList != -1) {
922 node->displayList = (Gfx*)((s32)baseGfx + ((s32)(node->displayList) & 0xFFFF));
923 } else {
924 node->displayList = NULL;
925 }
926
927 if ((s32)node->sibling != -1) {
928 node->sibling = (StaticAnimatorNode*)((s32)baseAnim + ((s32)(node->sibling) & 0xFFFF));
929 } else {
930 node->sibling = NULL;
931 }
932
933 if ((s32)node->child != -1) {
934 node->child = (StaticAnimatorNode*)((s32)baseAnim + ((s32)(node->child) & 0xFFFF));
935 } else {
936 node->child = NULL;
937 }
938
939 if ((s32)node->vtxList != -1) {
940 node->vtxList = (Vtx*)((s32)baseGfx + ((s32)(node->vtxList) & 0xFFFFF));
941 } else {
942 node->vtxList = NULL;
943 }
944 }
945}
946
947s32 is_entity_data_loaded(Entity* entity, EntityBlueprint* blueprint, s32* loadedStart, s32* loadedEnd) {
948 EntityBlueprint** blueprints;
949 s32 i;
950 s32 ret;
951 s32 size;
952 DmaEntry* entDmaList;
953
954 *loadedStart = 0;
955 *loadedEnd = 0;
956 ret = FALSE;
957
959 blueprints = wEntityBlueprint;
960 } else {
961 blueprints = bEntityBlueprint;
962 }
963
964 for (i = 0; i < MAX_ENTITIES; i++, blueprints++) {
965 EntityBlueprint* bp = *blueprints;
966 if (bp == NULL) {
967 blueprints[0] = blueprint;
968 blueprints[1] = NULL;
969 ret = TRUE;
970 if (blueprint->flags & ENTITY_FLAG_HAS_ANIMATED_MODEL) {
971 s32 size;
972 entDmaList = blueprint->dmaList;
973 size = (entDmaList[0].end - entDmaList[0].start) >> 2;
974 *loadedEnd = *loadedStart + size;
975 }
976 break;
977 } else {
978 DmaEntry* bpDmaList = bp->dmaList;
979 entDmaList = blueprint->dmaList;
980 if (bpDmaList == entDmaList) {
981 if (blueprint->flags & ENTITY_FLAG_HAS_ANIMATED_MODEL) {
982 s32 size = (bpDmaList[0].end - bpDmaList[0].start) >> 2;
983 *loadedEnd = *loadedStart + size;
984 }
985 break;
986 } else if (bp == blueprint) {
988 s32 size = (entDmaList[0].end - entDmaList[0].start) >> 2;
989 *loadedEnd = *loadedStart + size;
990 }
991 break;
992 } else {
994 s32 size = (bpDmaList[0].end - bpDmaList[0].start) >> 2;
995 *loadedEnd = *loadedStart = *loadedStart + size;
996 size = (bpDmaList[1].end - bpDmaList[1].start) >> 2;
997 *loadedStart = *loadedStart + size;
998 } else {
999 *loadedStart += (bp->dma.end - bp->dma.start) >> 2;
1000 }
1001 }
1002 }
1003 }
1004
1005 return ret;
1006}
1007
1008void load_simple_entity_data(Entity* entity, EntityBlueprint* bp, s32 listIndex) {
1009 s32 loadedStart;
1010 s32 loadedEnd;
1011 s32 entitySize;
1012 u32 temp;
1013 s32 totalSize;
1014
1015 entity->vertexSegment = 0xA;
1017 totalSize = wEntityDataLoadedSize;
1018 } else {
1019 totalSize = bEntityDataLoadedSize;
1020 }
1021
1022 if (is_entity_data_loaded(entity, bp, &loadedStart, &loadedEnd)) {
1023 if (totalSize + ((bp->dma.end - bp->dma.start) >> 2) > 0x5FFCU) {
1024 get_entity_type(entity->listIndex);
1025 get_entity_type(entity->listIndex);
1026 PANIC();
1027 }
1028 entitySize = (bp->dma.end - bp->dma.start) >> 2;
1029 entity->gfxBaseAddr = (void*)(gEntityHeapBase - totalSize * 4 - entitySize * 4);
1030 totalSize += dma_copy(bp->dma.start, bp->dma.end, entity->gfxBaseAddr) >> 2;
1031 get_entity_type(entity->listIndex);
1032 } else {
1033 entitySize = (bp->dma.end - bp->dma.start) >> 2;
1034 entity->gfxBaseAddr = (void*)(gEntityHeapBase - loadedStart * 4 - entitySize * 4);
1035 get_entity_type(entity->listIndex);
1036 }
1037
1039 wEntityDataLoadedSize = totalSize;
1040 } else {
1041 bEntityDataLoadedSize = totalSize;
1042 }
1043}
1044
1045void load_split_entity_data(Entity* entity, EntityBlueprint* entityData, s32 listIndex) {
1046 s32 swizzlePointers = FALSE;
1047 s32 loadedStart, loadedEnd;
1048 void* animBaseAddr;
1049 s16* animationScript;
1050 StaticAnimatorNode** animationNodes;
1051 s32 specialSize;
1052 s32 dma1size;
1053 s32 dma2size_1;
1054 s32 dma2size_2;
1055 s32 totalLoaded;
1056
1057 if (entityData->flags & ENTITY_FLAG_HAS_ANIMATED_MODEL) {
1058 DmaEntry* dmaList = entityData->dmaList;
1059 entity->vertexSegment = 0xA;
1060
1061 switch (entityData->entityType) {
1066 specialSize = 0x1000;
1067 break;
1072 specialSize = 0x2BC0;
1073 break;
1074 default:
1075 specialSize = 0;
1076 break;
1077 }
1078
1079 if (specialSize != 0) {
1080 if (entityData->entityType == ENTITY_TYPE_RESET_MUNCHLESIA) {
1081 is_entity_data_loaded(entity, entityData, &loadedStart, &loadedEnd);
1082 }
1083 specialSize -= 0x1000;
1084
1085 dma1size = dma_copy(dmaList[0].start, dmaList[0].end, (void*)(gEntityHeapBottom + specialSize * 4)) / 4;
1086 entity->gfxBaseAddr = (void*)(gEntityHeapBottom + specialSize * 4);
1087 dma_copy(dmaList[1].start, dmaList[1].end, (void*)(gEntityHeapBottom + specialSize * 4 + dma1size * 4));
1088 animBaseAddr = (void*)(gEntityHeapBottom + specialSize * 4 + dma1size * 4);
1089 swizzlePointers = TRUE;
1090 } else if (is_entity_data_loaded(entity, entityData, &loadedStart, &loadedEnd)) {
1092 totalLoaded = wEntityDataLoadedSize;
1093 } else {
1094 totalLoaded = bEntityDataLoadedSize;
1095 }
1096
1097 if ((totalLoaded + ((dmaList[0].end - dmaList[0].start) >> 2)) > 0x5FFCU) {
1098 get_entity_type(entity->listIndex);
1099 PANIC();
1100 }
1101
1102 if ((totalLoaded + ((dmaList[1].end - dmaList[1].start) >> 2)) > 0x5FFCU) {
1103 get_entity_type(entity->listIndex);
1104 PANIC();
1105 }
1106
1107 dma2size_1 = dma_copy(dmaList[0].start, dmaList[0].end, dmaList[0].start + ((gEntityHeapBase - totalLoaded * 4 - (s32)dmaList[0].end) >> 2) * 4) >> 2;
1108 entity->gfxBaseAddr = (void*)(gEntityHeapBase - totalLoaded * 4 - dma2size_1 * 4);
1109 totalLoaded += dma2size_1;
1110
1111 dma2size_2 = dma_copy(dmaList[1].start, dmaList[1].end, dmaList[1].start + ((gEntityHeapBase - totalLoaded * 4 - (s32)dmaList[1].end) >> 2) * 4) >> 2;
1112 animBaseAddr = (void*)(gEntityHeapBase - totalLoaded * 4 - dma2size_2 * 4);
1113 totalLoaded += dma2size_2;
1114 get_entity_type(entity->listIndex);
1115
1117 wEntityDataLoadedSize = totalLoaded;
1118 } else {
1119 bEntityDataLoadedSize = totalLoaded;
1120 }
1121 swizzlePointers = TRUE;
1122 } else {
1123 u32 temp = (dmaList[0].end - dmaList[0].start) >> 2;
1124 entity->gfxBaseAddr = (void*)(gEntityHeapBase - loadedStart * 4 - temp * 4);
1125 temp = (dmaList[1].end - dmaList[1].start) >> 2;
1126 animBaseAddr = (void*)(gEntityHeapBase - loadedEnd * 4 - temp * 4);
1127 get_entity_type(entity->listIndex);
1128 }
1129 } else {
1133 return;
1134 }
1135 animationScript = entityData->renderCommandList;
1136 animationNodes = (StaticAnimatorNode**)((s32)animBaseAddr + (s32)entityData->modelAnimationNodes);
1137 if (swizzlePointers) {
1138 entity_swizzle_anim_pointers(entityData, animBaseAddr, entity->gfxBaseAddr);
1139 }
1140 entity->virtualModelIndex = create_mesh_animator(animationScript, animBaseAddr);
1141 load_mesh_animator_tree(entity->virtualModelIndex, animationNodes);
1144}
1145
1147 s32 i;
1148
1149 for (i = 0; i < ARRAY_COUNT(*gCurrentEntityListPtr); i++) {
1150 Entity* entity = (*gCurrentEntityListPtr)[i];
1151
1152 if (entity != NULL && entity->blueprint->dma.start != NULL) {
1153 if (entity->blueprint->dma.start == entity->blueprint) {
1154 return TRUE;
1155 }
1156 }
1157 }
1158 return FALSE;
1159}
1160
1162 s32 freeSlot;
1163 s32 size;
1164 EntityBlueprint* bp;
1165
1166 for (freeSlot = 0; freeSlot < MAX_ENTITIES; freeSlot++) {
1167 bp = wEntityBlueprint[freeSlot];
1168 if (bp == NULL) {
1169 break;
1170 }
1171 }
1172
1173 if (freeSlot < MAX_ENTITIES) {
1174 bp = wEntityBlueprint[freeSlot - 1];
1175 if (bp == data) {
1177 DmaEntry* dmaList = bp->dmaList;
1178 size = ((dmaList[0].end - dmaList[0].start) >> 2);
1179 size += ((dmaList[1].end - dmaList[1].start) >> 2);
1180 if (!func_80111790(bp)) {
1181 wEntityBlueprint[freeSlot - 1] = NULL;
1182 wEntityDataLoadedSize -= size;
1183 }
1184 } else {
1185 size = (bp->dma.end - bp->dma.start) >> 2;
1186 if (!func_80111790(bp)) {
1187 wEntityBlueprint[freeSlot - 1] = NULL;
1188 wEntityDataLoadedSize -= size;
1189 }
1190 }
1191 }
1192 }
1193}
1194
1196 va_list ap;
1197 f32 x, y, z;
1198 f32 rotY;
1199 s32 listIndex;
1200 Entity* entity;
1201 s32 idx;
1202
1203 va_start(ap, bp);
1204
1206
1207 x = va_arg(ap, s32);
1208 y = va_arg(ap, s32);
1209 z = va_arg(ap, s32);
1210 rotY = va_arg(ap, s32);
1211
1212 for (idx = 0; idx < ARRAY_COUNT(CreateEntityVarArgBuffer); idx++) {
1213 CreateEntityVarArgBuffer[idx] = 0;
1214 }
1215
1216 for (idx = 0; idx < ARRAY_COUNT(CreateEntityVarArgBuffer); idx++) {
1217 s32 arg = va_arg(ap, s32);
1218
1219 if (arg == MAKE_ENTITY_END) {
1220 break;
1221 }
1222 CreateEntityVarArgBuffer[idx] = arg;
1223 }
1224
1225 va_end(ap);
1226
1227 for (listIndex = 0; listIndex < ARRAY_COUNT(*gCurrentEntityListPtr); listIndex++) {
1228 if ((*gCurrentEntityListPtr)[listIndex] == NULL) {
1229 break;
1230 }
1231 }
1232
1233 if (listIndex >= MAX_ENTITIES) {
1234 return -1;
1235 }
1236
1237 (*gCurrentEntityListPtr)[listIndex] = entity = heap_malloc(sizeof(*entity));
1238 mem_clear(entity, sizeof(*entity));
1239 entity->dataBuf.any = NULL;
1240 if (bp->typeDataSize != 0) {
1241 entity->dataBuf.any = heap_malloc(bp->typeDataSize);
1242 mem_clear(entity->dataBuf.any, bp->typeDataSize);
1243 }
1244 entity->type = bp->entityType;
1245 entity->listIndex = listIndex;
1246 entity->boundScript = NULL;
1247 entity->updateMatrixOverride = NULL;
1248 entity->blueprint = bp;
1249 entity->scriptReadPos = bp->updateEntityScript;
1250 entity->scriptDelay = entity->scriptReadPos != NULL ? 1 : 0;
1251 entity->savedReadPos[0] = bp->updateEntityScript;
1252 entity->updateScriptCallback = NULL;
1253 entity->flags = bp->flags | ENTITY_FLAG_CREATED;
1254 entity->collisionFlags = 0;
1255 entity->collisionTimer = 0;
1256 entity->renderSetupFunc = NULL;
1257 entity->pos.x = x;
1258 entity->pos.y = y;
1259 entity->pos.z = z;
1260 entity->rot.x = 0.0f;
1261 entity->rot.y = rotY;
1262 entity->rot.z = 0.0f;
1263 entity->scale.x = 1.0f;
1264 entity->scale.y = 1.0f;
1265 entity->scale.z = 1.0f;
1266 entity->aabb.x = bp->aabbSize[0];
1267 entity->aabb.y = bp->aabbSize[1];
1268 entity->aabb.z = bp->aabbSize[2];
1269 entity->unk_05 = 1;
1270 entity->unk_08 = -1;
1271 entity->alpha = 255;
1272 entity->virtualModelIndex = -1;
1273 entity->shadowIndex = -1;
1274 entity->gfxBaseAddr = NULL;
1275
1277 if (bp->dma.start != 0) {
1278 load_simple_entity_data(entity, bp, listIndex);
1279 }
1280 if (bp->renderCommandList != NULL) {
1283 }
1284 } else {
1285 load_split_entity_data(entity, bp, listIndex);
1286 }
1287
1289 create_entity_shadow(entity, x, y, z);
1290 }
1291
1292 switch (bp->entityType) {
1298 entity->flags |= ENTITY_FLAG_4000;
1299 break;
1300 }
1301
1302 if (bp->fpInit != NULL) {
1303 bp->fpInit(entity);
1304 }
1305
1307 return entity->listIndex;
1308}
1309
1310s32 create_shadow_from_data(ShadowBlueprint* bp, f32 x, f32 y, f32 z) {
1311 Shadow* shadow;
1312 s32 i;
1313
1314 for (i = 0; i < ARRAY_COUNT(*gCurrentShadowListPtr); i++) {
1315 if ((*gCurrentShadowListPtr)[i] == NULL) {
1316 break;
1317 }
1318 }
1319
1321
1322 shadow = heap_malloc(sizeof(*shadow));
1323 (*gCurrentShadowListPtr)[i] = shadow;
1324 mem_clear(shadow, sizeof(*shadow));
1325 shadow->listIndex = i;
1326 shadow->flags = bp->flags | ENTITY_FLAG_CREATED;
1327 shadow->alpha = 128;
1328 shadow->unk_06 = 0x80;
1329 shadow->pos.x = x;
1330 shadow->pos.y = y;
1331 shadow->pos.z = z;
1332 shadow->scale.x = 1.0f;
1333 shadow->scale.y = 1.0f;
1334 shadow->scale.z = 1.0f;
1335
1336 if (bp->animModelNode != NULL) {
1340 } else {
1342 }
1343
1344 if (bp->onCreateCallback != NULL) {
1345 bp->onCreateCallback(shadow);
1346 }
1348 return shadow->listIndex;
1349}
1350
1351API_CALLABLE(MakeEntity) {
1352 Bytecode* args = script->ptrReadPos;
1353 EntityBlueprint* entityData;
1354 s32 x, y, z;
1355 s32 flags;
1356 s32 nextArg;
1357 s32 entityIndex;
1358 s32 idx;
1359
1360 if (isInitialCall != TRUE) {
1361 return ApiStatus_DONE2;
1362 }
1363
1364 entityData = (EntityBlueprint*)evt_get_variable(script, *args++);
1365 x = evt_get_variable(script, *args++);
1366 y = evt_get_variable(script, *args++);
1367 z = evt_get_variable(script, *args++);
1368 flags = evt_get_variable(script, *args++);
1369
1370 for (idx = 0; idx < ARRAY_COUNT(CreateEntityVarArgBuffer); idx++) {
1371 CreateEntityVarArgBuffer[idx] = 0;
1372 }
1373
1374 for (idx = 0;; idx++) {
1375 nextArg = evt_get_variable(script, *args++);
1376 if (nextArg == MAKE_ENTITY_END) {
1377 break;
1378 }
1379 CreateEntityVarArgBuffer[idx] = nextArg;
1380 }
1381
1382 entityIndex = create_entity(entityData, x, y, z, flags,
1384 gLastCreatedEntityIndex = entityIndex;
1385 script->varTable[0] = entityIndex;
1386 return ApiStatus_DONE2;
1387}
1388
1389API_CALLABLE(SetEntityCullMode) {
1391 Bytecode* args = script->ptrReadPos;
1392 s32 mode = evt_get_variable(script, *args++);
1393
1394 if (mode == 0) {
1396 } else if (mode == 1) {
1398 } else if (mode == 2) {
1400 } else {
1403 }
1404 return ApiStatus_DONE2;
1405}
1406
1407API_CALLABLE(UseDynamicShadow) {
1409 Bytecode* args = script->ptrReadPos;
1410
1411 if (evt_get_variable(script, *args++)) {
1412 Shadow* shadow;
1413
1415 shadow = get_shadow_by_index(entity->shadowIndex);
1417 } else {
1418 entity->flags &= ~ENTITY_FLAG_HAS_DYNAMIC_SHADOW;
1419 }
1420
1421 return ApiStatus_DONE2;
1422}
1423
1424API_CALLABLE(AssignScript) {
1425 Bytecode* args = script->ptrReadPos;
1426
1427 if (isInitialCall == TRUE) {
1428 EvtScript* toBind = (EvtScript*)evt_get_variable(script, *args++);
1429
1431 return ApiStatus_DONE2;
1432 }
1433
1434 return ApiStatus_DONE1;
1435}
1436
1437API_CALLABLE(AssignSwitchFlag) {
1438 Bytecode* args = script->ptrReadPos;
1439
1440 if (isInitialCall == TRUE) {
1441 s32 areaFlag = evt_get_variable(script, *args++);
1443 SwitchData* data = entity->dataBuf.swtch;
1444
1445 data->areaFlagIndex = areaFlag;
1446 if (get_area_flag(areaFlag)) {
1448 }
1449 return ApiStatus_DONE2;
1450 }
1451
1452 return ApiStatus_DONE1;
1453}
1454
1455API_CALLABLE(AssignBlockFlag) {
1456 Bytecode* args = script->ptrReadPos;
1457
1458 if (isInitialCall == TRUE) {
1459 s32 index = evt_get_variable_index(script, *args++);
1460
1462 data->gameFlagIndex = index;
1463
1464 return ApiStatus_DONE2;
1465 }
1466
1467 return ApiStatus_DONE1;
1468}
1469
1470API_CALLABLE(AssignChestFlag) {
1471 Bytecode* args = script->ptrReadPos;
1472
1473 if (isInitialCall == TRUE) {
1475 data->gameFlagIndex = evt_get_variable_index(script, *args);
1476
1477 return ApiStatus_DONE2;
1478 }
1479
1480 return ApiStatus_DONE1;
1481}
1482
1483API_CALLABLE(AssignPanelFlag) {
1484 Bytecode* args = script->ptrReadPos;
1485
1486 if (isInitialCall == TRUE) {
1488
1489 data->pickupVar = evt_get_variable_index(script, *args++);
1490 return ApiStatus_DONE2;
1491 }
1492
1493 return ApiStatus_DONE1;
1494}
1495
1496API_CALLABLE(AssignCrateFlag) {
1497 Bytecode* args = script->ptrReadPos;
1498
1499 if (isInitialCall == TRUE) {
1501
1502 data->globalFlagIndex = evt_get_variable_index(script, *args++);
1503 return ApiStatus_DONE2;
1504 }
1505
1506 return ApiStatus_DONE1;
1507}
1508
1509s32 create_entity_shadow(Entity* entity, f32 x, f32 y, f32 z) {
1510 u16 bpFlags = entity->blueprint->flags;
1511 s32 type;
1512 s16 shadowIndex;
1513
1514 if (bpFlags & ENTITY_FLAG_FIXED_SHADOW_SIZE) {
1516 } else {
1518 }
1519
1520 shadowIndex = create_shadow_type(type, x, y, z);
1521 entity->shadowIndex = shadowIndex;
1522
1524
1525 return entity->shadowIndex;
1526}
1527
1528s32 create_shadow_type(s32 type, f32 x, f32 y, f32 z) {
1529 s32 isFixedSize = FALSE;
1531 s32 shadowIndex;
1532
1533 switch (type) {
1535 isFixedSize = TRUE;
1537 bp = &CircularShadowA;
1538 break;
1540 isFixedSize = TRUE;
1542 bp = &SquareShadow;
1543 break;
1545 isFixedSize = TRUE;
1547 bp = &CircularShadowB;
1548 break;
1549 }
1550
1551 shadowIndex = create_shadow_from_data(bp, x, y, z);
1552
1553 if (isFixedSize) {
1555 }
1556
1557 return shadowIndex;
1558}
1559
1561 Shadow* shadow = get_shadow_by_index(entity->shadowIndex);
1562
1563 if (shadow != NULL) {
1564 f32 rayX;
1565 f32 rayY;
1566 f32 rayZ;
1567 f32 hitYaw;
1568 f32 hitPitch;
1569 f32 hitLength;
1570 f32 origHitLength;
1571
1572 if (entity->alpha < 255) {
1573 shadow->alpha = entity->alpha / 2;
1574 } else {
1575 u8 alphaTemp;
1576
1577 if (shadow->flags & ENTITY_FLAG_DARK_SHADOW) {
1578 alphaTemp = 160;
1579 } else {
1580 alphaTemp = 128;
1581 }
1582 shadow->alpha = alphaTemp;
1583 }
1584
1585 if (!(entity->flags & ENTITY_FLAG_HAS_DYNAMIC_SHADOW)) {
1586 if (shadow->flags & ENTITY_FLAG_SHADOW_POS_DIRTY) {
1587 shadow->flags &= ~ENTITY_FLAG_SHADOW_POS_DIRTY;
1588 } else {
1589 return;
1590 }
1591 }
1592
1593 rayX = entity->pos.x;
1594 rayY = entity->pos.y;
1595 rayZ = entity->pos.z;
1596
1597 if (!entity_raycast_down(&rayX, &rayY, &rayZ, &hitYaw, &hitPitch, &hitLength) && hitLength == 32767.0f) {
1598 hitLength = 0.0f;
1599 }
1600
1601 origHitLength = hitLength;
1602
1603 if (shadow->flags & ENTITY_FLAG_FIXED_SHADOW_SIZE) {
1604 hitLength = 212.5f;
1605 shadow->scale.x = entity->aabb.x / hitLength;
1606 shadow->scale.z = entity->aabb.z / hitLength;
1607 } else {
1608 hitLength = ((hitLength / 150.0f) + 0.95) * 250.0;
1609 shadow->scale.x = (entity->aabb.x / hitLength) * entity->scale.x;
1610 shadow->scale.z = (entity->aabb.z / hitLength) * entity->scale.z;
1611 }
1612
1613 shadow->pos.x = entity->pos.x;
1614 shadow->pos.z = entity->pos.z;
1615 shadow->pos.y = rayY;
1616 entity->shadowPosY = rayY;
1617 shadow->rot.x = hitYaw;
1618 shadow->rot.z = hitPitch;
1619 shadow->rot.y = entity->rot.y;
1620
1621 if (entity->pos.y < rayY) {
1622 shadow->flags |= ENTITY_FLAG_SKIP_UPDATE;
1623 entity->pos.y = rayY + 10.0f;
1624 } else {
1625 shadow->flags &= ~ENTITY_FLAG_SKIP_UPDATE;
1626 }
1627
1628 shadow->flags = (shadow->flags & ~ENTITY_FLAG_HIDDEN) | ((u16)entity->flags & ENTITY_FLAG_HIDDEN);
1629 if (!(entity->flags & ENTITY_FLAG_400) && origHitLength == 0.0f) {
1630 shadow->flags |= ENTITY_FLAG_HIDDEN;
1631 }
1632 } else {
1633 entity->shadowPosY = 0.0f;
1634 }
1635}
1636
1637b32 entity_raycast_down(f32* x, f32* y, f32* z, f32* hitYaw, f32* hitPitch, f32* hitLength) {
1638 f32 hitX, hitY, hitZ;
1639 f32 hitDepth;
1640 f32 hitNx, hitNy, hitNz;
1641 s32 entityID;
1642 s32 colliderID;
1643 s32 hitID;
1644
1645 hitDepth = 32767.0f;
1646 hitID = NO_COLLIDER;
1647
1648 entityID = test_ray_entities(*x, *y, *z, 0.0f, -1.0f, 0.0f, &hitX, &hitY, &hitZ, &hitDepth, &hitNx, &hitNy, &hitNz);
1649
1650 if ((entityID > NO_COLLIDER) && ((get_entity_type(entityID) != ENTITY_TYPE_PUSH_BLOCK) || (hitNx == 0.0f && hitNz == 0.0f && hitNy == 1.0))) {
1651 hitID = entityID | COLLISION_WITH_ENTITY_BIT;
1652 }
1653
1654 colliderID = test_ray_colliders(COLLIDER_FLAG_IGNORE_PLAYER, *x, *y, *z, 0.0f, -1.0f, 0.0f, &hitX, &hitY, &hitZ, &hitDepth, &hitNx,
1655 &hitNy, &hitNz);
1656 if (colliderID > NO_COLLIDER) {
1657 hitID = colliderID;
1658 }
1659
1660 if (hitID > NO_COLLIDER) {
1661 *y = hitY;
1662 *hitLength = hitDepth;
1663 *hitYaw = -atan2(0.0f, 0.0f, hitNz * 100.0f, hitNy * 100.0f);
1664 *hitPitch = -atan2(0.0f, 0.0f, hitNx * 100.0f, hitNy * 100.0f);
1665 return TRUE;
1666 } else {
1667 *hitLength = 32767.0f;
1668 *hitYaw = 0.0f;
1669 *hitPitch = 0.0f;
1670 return FALSE;
1671 }
1672}
1673
1674void set_standard_shadow_scale(Shadow* shadow, f32 height) {
1676 shadow->scale.x = 0.13 - (height / 2600.0f);
1677 } else {
1678 shadow->scale.x = 0.12 - (height / 3600.0f);
1679 }
1680
1681 if (shadow->scale.x < 0.01) {
1682 shadow->scale.x = 0.01f;
1683 }
1684 shadow->scale.z = shadow->scale.x;
1685}
1686
1687void set_npc_shadow_scale(Shadow* shadow, f32 height, f32 npcRadius) {
1689 shadow->scale.x = 0.13 - (height / 2600.0f);
1690 } else {
1691 shadow->scale.x = 0.12 - (height / 3600.0f);
1692 }
1693
1694 if (shadow->scale.x < 0.01) {
1695 shadow->scale.x = 0.01f;
1696 }
1697
1698 if (npcRadius > 60.0f) {
1699 shadow->scale.z = shadow->scale.x * 2.0f;
1700 } else {
1701 shadow->scale.z = shadow->scale.x;
1702 }
1703}
1704
1705void set_peach_shadow_scale(Shadow* shadow, f32 scale) {
1706 PlayerStatus* playerStatus = &gPlayerStatus;
1707 f32 phi_f2 = 0.12f;
1708
1710 switch (playerStatus->anim) {
1711 case ANIM_Peach2_Carried:
1712 case ANIM_Peach2_Thrown:
1713 case ANIM_Peach2_Land:
1714 case ANIM_Peach3_TiedSideways:
1715 shadow->scale.x = 0.26f - (scale / 2600.0f);
1716 if (shadow->scale.x < 0.01) {
1717 shadow->scale.x = 0.01f;
1718 }
1719 shadow->scale.z = 0.13f - (scale / 2600.0f);
1720 if (shadow->scale.z < 0.01) {
1721 shadow->scale.z = 0.01f;
1722 }
1723 return;
1724 }
1725
1726 phi_f2 = 0.16f;
1727 }
1728
1729 shadow->scale.x = phi_f2 - (scale / 3600.0f);
1730 if (shadow->scale.x < 0.01) {
1731 shadow->scale.x = 0.01f;
1732 }
1733 shadow->scale.z = shadow->scale.x;
1734}
1735
1737 f32 x = block->pos.x;
1738 f32 y = block->pos.y;
1739 f32 z = block->pos.z;
1740 f32 hitYaw;
1741 f32 hitPitch;
1742 f32 hitLength;
1743 s32 ret;
1744
1745 entity_raycast_down(&x, &y, &z, &hitYaw, &hitPitch, &hitLength);
1746
1747 ret = hitLength;
1748 if (ret == 32767) {
1749 ret = FALSE;
1750 }
1751
1752 return ret;
1753}
Entity * EntityList[30]
struct StaticAnimatorNode * child
struct WoodenCrateData * crate
struct StaticAnimatorNode * sibling
Mtx transformMatrix
struct SwitchData * swtch
s16 entityModelID
Shadow * ShadowList[60]
s32(* EntityCallback)(struct Entity *)
struct BlockData * block
struct HiddenPanelData * hiddenPanel
s32 b32
f32 Matrix4f[4][4]
Vec3s * vertexArray
Vec3f scale
Bytecode EvtScript[]
struct ChestData * chest
s16 vertexSegment
s8 flags
Definition demo_api.c:15
#define guRotateF
#define sqrtf
#define guMtxF2L
#define guTranslateF
#define guMtxCatF
#define atan2
#define mem_clear
#define guScaleF
#define ASSERT(condition)
s32 gEntityHideMode
Definition entity.c:37
BSS ShadowList gBattleShadowList
Definition entity.c:55
Entity * get_entity_by_index(s32 index)
Definition entity.c:530
void render_shadows(void)
Definition entity.c:424
void update_entity_shadow_position(Entity *entity)
Definition entity.c:1560
void update_shadows(void)
Definition entity.c:203
void render_entities(void)
Definition entity.c:338
BSS ShadowList * gCurrentShadowListPtr
Definition entity.c:56
s32 gLastCreatedEntityIndex
Definition entity.c:44
EntityList * get_entity_list(void)
Definition entity.c:538
void init_entity_data(void)
Definition entity.c:840
s32 create_entity_shadow(Entity *entity, f32 x, f32 y, f32 z)
Definition entity.c:1509
BSS EntityList gBattleEntityList
Definition entity.c:52
BSS ShadowList gWorldShadowList
Definition entity.c:54
BSS EntityList * gCurrentEntityListPtr
Definition entity.c:53
void entity_reset_collision(Entity *entity)
Definition entity.c:767
s32 test_player_entity_aabb(Entity *entity)
Definition entity.c:734
void delete_entity(s32 entityIndex)
Definition entity.c:578
BSS s32 bEntityDataLoadedSize
Definition entity.c:59
#define WORLD_ENTITY_HEAP_BOTTOM
Definition entity.c:17
Shadow * get_shadow_by_index(s32 index)
Definition entity.c:534
void entity_free_static_data(EntityBlueprint *data)
Definition entity.c:1161
s32 isAreaSpecificEntityDataLoaded
Definition entity.c:48
BSS EntityBlueprint * bEntityBlueprint[4]
Definition entity.c:62
s32 D_8014AFB0
Definition entity.c:33
s32 gEntityHeapBottom
Definition entity.c:46
s32 gEntityHeapBase
Definition entity.c:43
s32 entity_start_script(Entity *entity)
Definition entity.c:560
void func_8010FD98(void *arg0, s32 alpha)
Definition entity.c:317
void update_entity_transform_matrix(Entity *entity)
Definition entity.c:470
void load_simple_entity_data(Entity *entity, EntityBlueprint *bp, s32 listIndex)
Definition entity.c:1008
void clear_entity_data(b32 arg0)
Definition entity.c:787
void entity_swizzle_anim_pointers(EntityBlueprint *entityData, void *baseAnim, void *baseGfx)
Definition entity.c:909
s32 D_80151304
Definition entity.c:40
void update_entities(void)
Definition entity.c:82
void update_entity_inverse_rotation_matrix(Entity *entity)
Definition entity.c:517
s32 entity_try_partner_interaction_trigger(s32 entityIdx)
Definition entity.c:677
#define WORLD_ENTITY_HEAP_BASE
Definition entity.c:18
s32 entity_numShadows
Definition entity.c:47
void load_area_specific_entity_data(void)
Definition entity.c:772
s32 D_80151344
Definition entity.c:41
s32 CreateEntityVarArgBuffer[4]
Definition entity.c:35
void entity_model_set_shadow_color(void *data)
Definition entity.c:331
void set_entity_commandlist(Entity *entity, s32 *entityScript)
Definition entity.c:235
b32 entity_raycast_down(f32 *x, f32 *y, f32 *z, f32 *hitYaw, f32 *hitPitch, f32 *hitLength)
Mostly used for shadows.
Definition entity.c:1637
BSS s32 wEntityDataLoadedSize
Definition entity.c:58
s32 step_entity_commandlist(Entity *entity)
Definition entity.c:241
s32 entity_get_collision_flags(Entity *entity)
Definition entity.c:634
void exec_entity_commandlist(Entity *entity)
Definition entity.c:313
void set_peach_shadow_scale(Shadow *shadow, f32 scale)
Definition entity.c:1705
s32 create_shadow_type(s32 type, f32 x, f32 y, f32 z)
Definition entity.c:1528
void delete_entity_and_unload_data(s32 entityIndex)
Definition entity.c:601
BSS s32 D_801516FC
Definition entity.c:63
void reload_world_entity_data(void)
Definition entity.c:860
void update_shadow_transform_matrix(Shadow *shadow)
Definition entity.c:496
void delete_shadow(s32 shadowIndex)
Definition entity.c:626
BSS EntityList gWorldEntityList
Definition entity.c:51
s32 entity_updateCounter
Definition entity.c:49
void load_split_entity_data(Entity *entity, EntityBlueprint *entityData, s32 listIndex)
Definition entity.c:1045
s32 func_80111790(EntityBlueprint *data)
Definition entity.c:1146
s32 create_shadow_from_data(ShadowBlueprint *bp, f32 x, f32 y, f32 z)
Definition entity.c:1310
s32 D_801512BC
Definition entity.c:39
Addr BattleEntityHeapBottom
BSS EntityBlueprint * wEntityBlueprint[MAX_ENTITIES+2]
Definition entity.c:61
void func_8010FE44(void *arg0)
Definition entity.c:327
void entity_set_render_script(Entity *entity, EntityModelScript *cmdList)
Definition entity.c:761
u32 get_entity_type(s32 index)
Definition entity.c:568
void set_npc_shadow_scale(Shadow *shadow, f32 height, f32 npcRadius)
Definition entity.c:1687
s32 create_entity(EntityBlueprint *bp,...)
Definition entity.c:1195
s32 is_entity_data_loaded(Entity *entity, EntityBlueprint *blueprint, s32 *loadedStart, s32 *loadedEnd)
Definition entity.c:947
s32 is_block_on_ground(Entity *block)
Definition entity.c:1736
s32 is_player_action_state(s8 actionState)
Definition entity.c:757
HiddenPanelsData gCurrentHiddenPanels
Definition entity.c:36
void set_standard_shadow_scale(Shadow *shadow, f32 height)
Definition entity.c:1674
ShadowList * get_shadow_list(void)
Definition entity.c:549
s32 entity_numEntities
Definition entity.c:42
s32 EntityModelScript[]
Definition entity.h:7
s32 load_entity_model(EntityModelScript *cmdList)
ShadowBlueprint SquareShadow
Definition Shadow.c:124
u16 areaFlagIndex
Definition entity.h:86
ShadowBlueprint CircularShadowB
Definition Shadow.c:115
void set_entity_model_render_command_list(s32 idx, EntityModelScript *cmdList)
u16 gameFlagIndex
Definition entity.h:193
EntityModel * get_entity_model(s32 idx)
ShadowBlueprint CircularShadowA
Definition Shadow.c:106
u16 globalFlagIndex
Definition entity.h:175
@ ENTITY_SCRIPT_OP_End
Definition entity.h:12
@ ENTITY_SCRIPT_OP_Label
Definition entity.h:17
@ ENTITY_SCRIPT_OP_Jump
Definition entity.h:13
@ ENTITY_SCRIPT_OP_PlaySound
Definition entity.h:21
@ ENTITY_SCRIPT_OP_RestartBoundScript
Definition entity.h:18
@ ENTITY_SCRIPT_OP_ClearFlags
Definition entity.h:20
@ ENTITY_SCRIPT_OP_Goto
Definition entity.h:16
@ ENTITY_SCRIPT_OP_SetFlags
Definition entity.h:19
@ ENTITY_SCRIPT_OP_Call
Definition entity.h:14
@ ENTITY_SCRIPT_OP_SetCallback
Definition entity.h:15
u16 gameFlagIndex
Definition entity.h:116
@ DEBUG_SCRIPTS_NONE
Definition enums.h:4275
@ BUTTON_A
Definition enums.h:2790
@ ENTITY_HIDE_MODE_1
Definition enums.h:2661
@ ENTITY_HIDE_MODE_0
Definition enums.h:2660
@ ENTITY_HIDE_MODE_2
Definition enums.h:2662
@ SHADOW_FIXED_ALT_CIRCLE
Definition enums.h:2540
@ SHADOW_VARYING_CIRCLE
Definition enums.h:2535
@ SHADOW_FIXED_CIRCLE
Definition enums.h:2537
@ SHADOW_VARYING_SQUARE
Definition enums.h:2536
@ SHADOW_FIXED_SQUARE
Definition enums.h:2538
@ SHADOW_VARYING_ALT_CIRCLE
Definition enums.h:2539
@ COLLIDER_FLAG_IGNORE_PLAYER
Definition enums.h:4696
@ ENTITY_TYPE_HAMMER1_BLOCK
Definition enums.h:2564
@ ENTITY_TYPE_MUNCHLESIA_ENVELOP
Definition enums.h:2603
@ ENTITY_TYPE_SINGLE_TRIGGER_BLOCK
Definition enums.h:2559
@ ENTITY_TYPE_SCRIPT_SPRING
Definition enums.h:2584
@ ENTITY_TYPE_MUNCHLESIA_CHEWING
Definition enums.h:2605
@ ENTITY_TYPE_MUNCHLESIA_BEGIN_CHEW
Definition enums.h:2604
@ ENTITY_TYPE_MUNCHLESIA_RESET2
Definition enums.h:2608
@ ENTITY_TYPE_BOMBABLE_ROCK
Definition enums.h:2581
@ ENTITY_TYPE_PUSH_BLOCK
Definition enums.h:2555
@ ENTITY_TYPE_HIDDEN_RED_BLOCK
Definition enums.h:2561
@ ENTITY_TYPE_1C
Definition enums.h:2571
@ ENTITY_TYPE_SUPER_BLOCK
Definition enums.h:2577
@ ENTITY_TYPE_HEALING_BLOCK
Definition enums.h:2570
@ ENTITY_TYPE_BLUE_SWITCH
Definition enums.h:2550
@ ENTITY_TYPE_MUNCHLESIA_GRAB
Definition enums.h:2602
@ ENTITY_TYPE_MUNCHLESIA_SPIT_OUT
Definition enums.h:2606
@ ENTITY_TYPE_MULTI_COIN_BRICK
Definition enums.h:2557
@ ENTITY_TYPE_RED_SWITCH
Definition enums.h:2551
@ ENTITY_TYPE_SIMPLE_SPRING
Definition enums.h:2583
@ ENTITY_TYPE_RESET_MUNCHLESIA
Definition enums.h:2601
@ ENTITY_TYPE_BRICK_BLOCK
Definition enums.h:2556
@ ENTITY_TYPE_HIDDEN_YELLOW_BLOCK
Definition enums.h:2560
@ ENTITY_TYPE_RED_BLOCK
Definition enums.h:2563
@ ENTITY_TYPE_SAVE_POINT
Definition enums.h:2575
@ ENTITY_TYPE_MULTI_TRIGGER_BLOCK
Definition enums.h:2554
@ ENTITY_TYPE_HAMMER1_BLOCK_TINY
Definition enums.h:2567
@ ENTITY_TYPE_MUNCHLESIA_RESET1
Definition enums.h:2607
@ ENTITY_TYPE_YELLOW_BLOCK
Definition enums.h:2558
@ ENTITY_TYPE_STAR_BOX_LAUNCHER
Definition enums.h:2586
@ ENTITY_TYPE_SHADOW
Definition enums.h:2544
@ AREA_SBK
Definition enums.h:2970
@ AREA_OMO
Definition enums.h:2976
@ AREA_JAN
Definition enums.h:2977
@ AREA_IWA
Definition enums.h:2968
@ ENTITY_COLLISION_PARTNER
Definition enums.h:2655
@ ENTITY_COLLISION_PLAYER_HAMMER
Definition enums.h:2654
@ ENTITY_COLLISION_PLAYER_TOUCH_WALL
Definition enums.h:2651
@ ENTITY_COLLISION_PLAYER_TOUCH_FLOOR
Definition enums.h:2648
@ ENTITY_COLLISION_PLAYER_TOUCH_CEILING
Definition enums.h:2650
@ ENTITY_COLLISION_PLAYER_PUSHING_AGAINST
Definition enums.h:2652
@ ENTITY_COLLISION_PLAYER_LAST_FLOOR
Definition enums.h:2656
@ CONTEXT_WORLD
Definition enums.h:3529
@ ENTITY_FLAG_8000
Definition enums.h:2628
@ ENTITY_FLAG_DETECTED_COLLISION
Definition enums.h:2629
@ ENTITY_FLAG_CONTINUOUS_COLLISION
Definition enums.h:2619
@ ENTITY_FLAG_HAS_SHADOW
Definition enums.h:2621
@ ENTITY_FLAG_IGNORE_DISTANCE_CULLING
Definition enums.h:2632
@ ENTITY_FLAG_HAS_ANIMATED_MODEL
Definition enums.h:2616
@ ENTITY_FLAG_DARK_SHADOW
Definition enums.h:2636
@ ENTITY_FLAG_SHADOW_POS_DIRTY
Definition enums.h:2635
@ ENTITY_FLAG_400
Definition enums.h:2623
@ ENTITY_FLAG_DRAW_IF_CLOSE_HIDE_MODE2
Definition enums.h:2631
@ ENTITY_FLAG_DRAW_IF_CLOSE_HIDE_MODE1
Definition enums.h:2614
@ ENTITY_FLAG_HAS_DYNAMIC_SHADOW
Definition enums.h:2615
@ ENTITY_FLAG_PARTNER_COLLISION
Definition enums.h:2630
@ ENTITY_FLAG_CREATED
Definition enums.h:2644
@ ENTITY_FLAG_FIXED_SHADOW_SIZE
Definition enums.h:2622
@ ENTITY_FLAG_HIDDEN
Definition enums.h:2613
@ ENTITY_FLAG_2000000
Definition enums.h:2638
@ ENTITY_FLAG_BOUND_SCRIPT_DIRTY
Definition enums.h:2637
@ ENTITY_FLAG_4000
Definition enums.h:2627
@ ENTITY_FLAG_SKIP_UPDATE_TRANSFORM_MATRIX
Definition enums.h:2617
@ ENTITY_FLAG_SKIP_UPDATE
Definition enums.h:2643
@ ENTITY_FLAG_PENDING_INSTANCE_DELETE
Definition enums.h:2642
@ ENTITY_FLAG_DISABLE_COLLISION
Definition enums.h:2618
@ ENTITY_FLAG_ALWAYS_FACE_CAMERA
Definition enums.h:2626
@ ENTITY_FLAG_FADING_AWAY
Definition enums.h:2641
@ ENTITY_FLAG_PENDING_FULL_DELETE
Definition enums.h:2639
@ ENTITY_FLAG_CIRCULAR_SHADOW
Definition enums.h:2624
@ PARTNER_BOMBETTE
Definition enums.h:2888
@ PARTNER_KOOPER
Definition enums.h:2887
@ EVT_PRIORITY_A
Definition evt.h:153
#define ApiStatus_DONE2
Definition evt.h:118
#define MAKE_ENTITY_END
Definition evt.h:107
s32 Bytecode
Definition evt.h:7
#define ApiStatus_DONE1
Definition evt.h:117
@ EVT_FLAG_RUN_IMMEDIATELY
don't wait for next update_scripts call
Definition evt.h:161
s32 evt_get_variable_index(Evt *script, s32 var)
Definition evt.c:1761
s32 evt_get_variable(Evt *script, Bytecode var)
Definition evt.c:1690
f32 fabsf(f32 f)
void draw_entity_model_A(s32, Mtx *)
void draw_entity_model_B(s32, Mtx *, s32, Vec3s *)
u32 dma_copy(Addr romStart, Addr romEnd, void *vramDest)
Definition 43F0.c:444
void exec_entity_model_commandlist(s32 idx)
f32 dist2D(f32 ax, f32 ay, f32 bx, f32 by)
Definition 43F0.c:670
s32 heap_free(void *ptr)
Definition heap.c:42
Evt * start_script(EvtScript *source, s32 priority, s32 initialState)
void load_mesh_animator_tree(s32 index, StaticAnimatorNode **tree)
Definition animator.c:1198
s32 create_model_animator(s16 *animPos)
Definition animator.c:318
s32 test_ray_entities(f32 startX, f32 startY, f32 startZ, f32 dirX, f32 dirY, f32 dirZ, f32 *hitX, f32 *hitY, f32 *hitZ, f32 *hitDepth, f32 *hitNx, f32 *hitNy, f32 *hitNz)
Test a general ray from a given starting position and direction against all entities.
Definition collision.c:947
void bind_entity_model_setupGfx(s32 idx, void *setupGfxCallbackArg0, void(*fpSetupGfxCallback)(void *))
s32 test_ray_colliders(s32 ignoreFlags, f32 startX, f32 startY, f32 startZ, f32 dirX, f32 dirY, f32 dirZ, f32 *hitX, f32 *hitY, f32 *hitZ, f32 *hitDepth, f32 *hitNx, f32 *hitNy, f32 *hitNz)
Definition collision.c:768
s32 does_script_exist(s32 id)
s32 create_mesh_animator(s16 *animPos, s16 *animBuffer)
Definition animator.c:366
s8 get_current_partner_id(void)
Definition 7BB60.c:1101
void free_entity_model_by_index(s32 idx)
void load_model_animator_tree(s32, StaticAnimatorNode **)
Definition animator.c:1171
void * heap_malloc(s32 size)
Definition heap.c:34
BSS u8 WorldEntityHeapBase[0x10]
Definition heaps2.c:6
void render_animated_model_with_vertices(s32 animatorID, Mtx *rootTransform, s32 segment, void *baseAddr)
Definition animator.c:795
ModelAnimator * set_animator_render_callback(s32 animModelID, void *callbackArg, void(*callbackFunc)(void *))
Definition animator.c:1045
void render_animated_model(s32 animatorID, Mtx *rootTransform)
Definition animator.c:765
void delete_model_animator(ModelAnimator *animator)
Definition animator.c:297
ModelAnimator * get_animator_by_index(s32 animModelID)
Definition animator.c:1041
void update_model_animator(s32)
Definition animator.c:482
void sfx_play_sound(s32 soundID)
Definition sfx.c:517
ApiStatus AssignCrateFlag(Evt *script, b32 isInitialCall)
ApiStatus AssignChestFlag(Evt *script, b32 isInitialCall)
ApiStatus SetEntityCullMode(Evt *script, b32 isInitialCall)
ApiStatus UseDynamicShadow(Evt *script, b32 isInitialCall)
ApiStatus AssignBlockFlag(Evt *script, b32 isInitialCall)
ApiStatus AssignSwitchFlag(Evt *script, b32 isInitialCall)
ApiStatus AssignPanelFlag(Evt *script, b32 isInitialCall)
ApiStatus AssignScript(Evt *script, b32 isInitialCall)
ApiStatus MakeEntity(Evt *script, b32 isInitialCall)
Creates an entity.
#define DMA_COPY_SEGMENT(segment)
Definition macros.h:525
#define MAX_ENTITIES
Definition macros.h:94
#define COLLISION_WITH_ENTITY_BIT
Definition macros.h:152
#define BSS
Definition macros.h:7
#define ARRAY_COUNT(arr)
Definition macros.h:40
#define PM_CC1_SHADOW
Definition macros.h:434
#define PM_CC_01
Definition macros.h:276
#define PANIC()
Definition macros.h:55
#define PM_CC2_SHADOW
Definition macros.h:435
#define MAX_SHADOWS
Definition macros.h:93
#define SQ(x)
Definition macros.h:166
#define NO_COLLIDER
Definition macros.h:156
#define PM_CC_02
Definition macros.h:277
EntityCallback fpHandleCollision
void(* fpInit)(struct Entity *)
void(* fpSetupGfxCallback)(void *)
Definition entity.h:463
EntityCallback updateMatrixOverride
Matrix4f inverseTransformMatrix
s16 virtualModelIndex
f32 effectiveSize
s8 collisionTimer
EntityCallback updateScriptCallback
void(* renderSetupFunc)(s32)
Evt * boundScript
EntityData dataBuf
EntityBlueprint * blueprint
EvtScript * boundScriptBytecode
s32 * scriptReadPos
s16 vertexSegment
void * gfxBaseAddr
Mtx transformMatrix
Vec3f scale
s32 * savedReadPos[3]
u8 collisionFlags
s16 shadowIndex
struct StaticAnimatorNode ** animModelNode
u8 Addr[]
Linker symbol address, as in ld_addrs.h.
Definition types.h:16
PlayerStatus * gPlayerStatusPtr
CollisionStatus gCollisionStatus
Definition 7BB60.c:6
GameStatus * gGameStatusPtr
Definition main_loop.c:32
Camera gCameras[4]
Definition cam_main.c:17
Gfx * gMainGfxPos
Definition cam_main.c:15
PlayerStatus gPlayerStatus
Definition 77480.c:39
s32 gCurrentCameraID
Definition cam_math.c:4
s32 get_area_flag(s32 index)