mirror of
https://github.com/pmret/papermario.git
synced 2024-11-18 17:02:46 +01:00
a865cbdf17
* remove old tools, fix warnings * almost match si_handle_print_debug_var * si_goto_end_loop and warnings * is_trigger_bound and create_trigger * Cleanup + matching 2 non-matchings * update_triggers (trigger.c complete) * fix warnings * PR comments, m2ctx.py fix
294 lines
8.0 KiB
C
294 lines
8.0 KiB
C
#include "common.h"
|
|
|
|
void default_trigger_delegate(Trigger* self) {
|
|
self->flags.flags |= 2;
|
|
}
|
|
|
|
void clear_trigger_data(void) {
|
|
CollisionStatus* collisionStatus = &gCollisionStatus;
|
|
s32 i;
|
|
|
|
if (!gGameStatusPtr->isBattle) {
|
|
gCurrentTriggerListPtr = &wTriggerList;
|
|
} else {
|
|
gCurrentTriggerListPtr = &bTriggerList;
|
|
}
|
|
|
|
for (i = 0; i < ARRAY_COUNT(*gCurrentTriggerListPtr); i++) {
|
|
(*gCurrentTriggerListPtr)[i] = NULL;
|
|
}
|
|
|
|
gTriggerCount = 0;
|
|
collisionStatus->pushingAgainstWall = -1;
|
|
collisionStatus->currentFloor = -1;
|
|
collisionStatus->lastTouchedFloor = -1;
|
|
collisionStatus->currentCeiling = -1;
|
|
collisionStatus->unk_0A = -1;
|
|
collisionStatus->unk_0C = -1;
|
|
collisionStatus->unk_0E = -1;
|
|
collisionStatus->unk_10 = -1;
|
|
collisionStatus->currentWall = -1;
|
|
collisionStatus->lastWallHammered = -1;
|
|
collisionStatus->touchingWallTrigger = 0;
|
|
collisionStatus->bombetteExploded = -1;
|
|
collisionStatus->bombetteExplosionPos.x = 0.0f;
|
|
collisionStatus->bombetteExplosionPos.y = 0.0f;
|
|
collisionStatus->bombetteExplosionPos.z = 0.0f;
|
|
}
|
|
|
|
void init_trigger_list(void) {
|
|
if (!gGameStatusPtr->isBattle) {
|
|
gCurrentTriggerListPtr = &wTriggerList;
|
|
} else {
|
|
gCurrentTriggerListPtr = &bTriggerList;
|
|
}
|
|
|
|
gTriggerCount = 0;
|
|
}
|
|
|
|
Trigger* create_trigger(TriggerDefinition* def) {
|
|
Trigger* ret;
|
|
s32 i;
|
|
|
|
for (i = 0; i < ARRAY_COUNT(*gCurrentTriggerListPtr); i++) {
|
|
Trigger* listTrigger = (*gCurrentTriggerListPtr)[i];
|
|
|
|
if (listTrigger == NULL) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
ASSERT(i < ARRAY_COUNT(*gCurrentTriggerListPtr));
|
|
|
|
(*gCurrentTriggerListPtr)[i] = ret = heap_malloc(sizeof(*ret));
|
|
gTriggerCount++;
|
|
|
|
ASSERT(ret != NULL);
|
|
|
|
ret->flags.flags = def->flags | 1;
|
|
ret->params1 = def->colliderIndex;
|
|
ret->params2 = def->flagIndex;
|
|
ret->unk_28 = def->unk_1C;
|
|
ret->unk_2C = def->unk_14;
|
|
ret->unk_30 = def->inputArg3;
|
|
|
|
ret->functionHandler = def->function;
|
|
if (ret->functionHandler == NULL) {
|
|
ret->functionHandler = default_trigger_delegate;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
void update_triggers(void) {
|
|
CollisionStatus* collisionStatus = &gCollisionStatus;
|
|
Trigger* listTrigger;
|
|
s32 i;
|
|
|
|
collisionStatus->touchingWallTrigger = 0;
|
|
|
|
for (i = 0; i < ARRAY_COUNT(*gCurrentTriggerListPtr); i++) {
|
|
listTrigger = (*gCurrentTriggerListPtr)[i];
|
|
|
|
if (listTrigger == NULL) {
|
|
continue;
|
|
}
|
|
|
|
if (!(listTrigger->flags.flags & 1)) {
|
|
continue;
|
|
}
|
|
|
|
if (listTrigger->flags.flags & 0x10) {
|
|
listTrigger->flags.flags |= 2;
|
|
continue;
|
|
}
|
|
|
|
if (listTrigger->flags.flags & 0x40) {
|
|
if (listTrigger->params2 == collisionStatus->currentWall) {
|
|
func_800E06C0(1);
|
|
}
|
|
if (listTrigger->params2 == collisionStatus->pushingAgainstWall) {
|
|
func_800E06C0(0);
|
|
} else {
|
|
continue;
|
|
}
|
|
}
|
|
|
|
if (listTrigger->flags.flags & 0x80) {
|
|
if (listTrigger->params2 != collisionStatus->currentFloor) {
|
|
continue;
|
|
}
|
|
}
|
|
|
|
if (listTrigger->flags.flags & 0x80000) {
|
|
if (listTrigger->params2 != collisionStatus->floorBelow) {
|
|
continue;
|
|
}
|
|
}
|
|
|
|
if (listTrigger->flags.flags & 0x100) {
|
|
if (listTrigger->params2 == collisionStatus->currentWall) {
|
|
collisionStatus->touchingWallTrigger = 1;
|
|
}
|
|
if ((listTrigger->params2 != collisionStatus->unk_0A) || !phys_can_player_interact()) {
|
|
continue;
|
|
}
|
|
}
|
|
|
|
if (listTrigger->flags.flags & 0x400) {
|
|
if (listTrigger->params2 != collisionStatus->currentWall) {
|
|
continue;
|
|
}
|
|
}
|
|
|
|
if (listTrigger->flags.flags & 0x200) {
|
|
if (listTrigger->params2 != collisionStatus->lastTouchedFloor) {
|
|
continue;
|
|
}
|
|
}
|
|
|
|
if (listTrigger->flags.flags & 0x800) {
|
|
if ((listTrigger->params2 != collisionStatus->currentFloor) ||
|
|
!(gGameStatusPtr->pressedButtons & 0x8000) || (gPlayerStatus.flags & 0x2000)) {
|
|
continue;
|
|
}
|
|
}
|
|
|
|
if (listTrigger->flags.flags & 0x1000) {
|
|
if (listTrigger->params2 != collisionStatus->lastWallHammered) {
|
|
continue;
|
|
}
|
|
}
|
|
|
|
if (listTrigger->flags.flags & 0x40000) {
|
|
if (listTrigger->params2 != collisionStatus->currentCeiling) {
|
|
continue;
|
|
}
|
|
}
|
|
|
|
if (listTrigger->flags.flags & 0x2000) {
|
|
if (listTrigger->params2 != collisionStatus->unk_0C) {
|
|
continue;
|
|
}
|
|
}
|
|
|
|
if (listTrigger->flags.flags & 0x4000) {
|
|
if (listTrigger->params2 != collisionStatus->unk_0E) {
|
|
continue;
|
|
}
|
|
}
|
|
|
|
if (listTrigger->flags.flags & 0x8000) {
|
|
if (listTrigger->params2 != collisionStatus->unk_10) {
|
|
continue;
|
|
}
|
|
}
|
|
|
|
if (listTrigger->flags.flags & 0x100000) {
|
|
f32* floats;
|
|
f32 dist;
|
|
|
|
if (collisionStatus->bombetteExploded < 0) {
|
|
continue;
|
|
}
|
|
|
|
floats = (f32*)listTrigger->params2;
|
|
dist = dist3D(floats[0], floats[1], floats[2],
|
|
collisionStatus->bombetteExplosionPos.x, collisionStatus->bombetteExplosionPos.y,
|
|
collisionStatus->bombetteExplosionPos.z);
|
|
|
|
if ((floats[3] * 0.5f) + 50.0f < dist) {
|
|
continue;
|
|
}
|
|
}
|
|
|
|
if (listTrigger->flags.flags & 0x10000 && get_global_flag(listTrigger->params1) == 0) {
|
|
continue;
|
|
}
|
|
|
|
if (listTrigger->flags.flags & 0x20000 && get_area_flag(listTrigger->params1) == 0) {
|
|
continue;
|
|
}
|
|
|
|
listTrigger->flags.flags |= 2;
|
|
}
|
|
|
|
for (i = 0; i < ARRAY_COUNT(*gCurrentTriggerListPtr); i++) {
|
|
listTrigger = (*gCurrentTriggerListPtr)[i];
|
|
|
|
if (listTrigger == NULL) {
|
|
continue;
|
|
}
|
|
|
|
if (listTrigger->flags.flags & 1) {
|
|
if (listTrigger->flags.flags & 2) {
|
|
if (listTrigger->functionHandler(listTrigger) == 0) {
|
|
listTrigger->flags.flags &= ~2;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void delete_trigger(Trigger* toDelete) {
|
|
s32 i;
|
|
|
|
for (i = 0; i < ARRAY_COUNT(*gCurrentTriggerListPtr); i++) {
|
|
if ((*gCurrentTriggerListPtr)[i] == toDelete) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (i < ARRAY_COUNT(*gCurrentTriggerListPtr)) {
|
|
heap_free((*gCurrentTriggerListPtr)[i]);
|
|
(*gCurrentTriggerListPtr)[i] = NULL;
|
|
}
|
|
}
|
|
|
|
s32 is_trigger_bound(Trigger* trigger, EvtSource* script) {
|
|
s32 i;
|
|
|
|
for (i = 0; i < ARRAY_COUNT(*gCurrentTriggerListPtr); i++) {
|
|
Trigger* listTrigger = (*gCurrentTriggerListPtr)[i];
|
|
|
|
if (listTrigger == NULL || listTrigger == trigger) {
|
|
continue;
|
|
}
|
|
|
|
if (listTrigger->flags.flags & 1) {
|
|
if (listTrigger->flags.flags & 2) {
|
|
if (listTrigger->scriptSource == script) {
|
|
return TRUE;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
Trigger* get_trigger_by_id(s32 triggerID) {
|
|
return (*gCurrentTriggerListPtr)[triggerID];
|
|
}
|
|
|
|
/// @returns TRUE if colliderID is bound to an interaction trigger (press A) and the player can use it.
|
|
s32 should_collider_allow_interact(s32 colliderID) {
|
|
s32 i;
|
|
|
|
if (!phys_can_player_interact()) {
|
|
return FALSE;
|
|
}
|
|
|
|
for (i = 0; i < ARRAY_COUNT(*gCurrentTriggerListPtr); i++) {
|
|
Trigger* trigger = (*gCurrentTriggerListPtr)[i];
|
|
|
|
if (trigger != NULL &&
|
|
trigger->unk_30 != 0 &&
|
|
trigger->params2 == colliderID &&
|
|
trigger->flags.flags & 0x100) {
|
|
return TRUE;
|
|
}
|
|
}
|
|
return FALSE;
|
|
}
|