#include #include struct LevelSpecial { u32 id; // 0x00 u32 settings; // 0x04 u16 name; // 0x08 u8 _0A[6]; // 0x0A u8 _10[0x9C]; // 0x10 float x; // 0xAC float y; // 0xB0 float z; // 0xB4 u8 _B8[0x318]; // 0xB8 // Any variables you add to the class go here; starting at offset 0x3D0 u64 eventFlag; // 0x3D0 u8 type; // 0x3D4 u8 effect; // 0x3D5 u8 lastEvState; // 0x3D6 u8 func; // 0x3D7 }; struct EventTable_t { u64 events; // ... }; extern EventTable_t *EventTable; extern u16 TimeStopFlag; extern u32 TimerBranch; extern float MarioDescentRate; extern float MarioJumpMax; extern float MarioJumpArc; extern float MiniMarioJumpArc; extern float MarioSize; extern "C" void GetSpecificPlayerActor(int number); void LevelSpecial_Update(LevelSpecial *self); bool ResetAfterLevel(); #define ACTIVATE 1 #define DEACTIVATE 0 fBase_c *FindActorByID(u32 id); bool ResetAfterLevel(void) { TimeStopFlag = 0; TimerBranch = 0x3403FFA4; MarioDescentRate = -4; MarioJumpMax = 3.628; MarioJumpArc = 2.5; MiniMarioJumpArc = 2.5; MarioSize = 1.0; return true; } bool LevelSpecial_Create(LevelSpecial *self) { char eventNum = (self->settings >> 24) & 0xFF; self->eventFlag = (u64)1 << (eventNum - 1); OSReport("Special Event created @%p event %d\n", self, eventNum); OSReport("Eventnum: %d. Event flag: %08x %08x\n", eventNum, self->eventFlag >> 32, self->eventFlag & 0xFFFFFFFF); self->type = (self->settings) & 15; self->effect = (self->settings >> 4) & 15; self->lastEvState = 0xFF; LevelSpecial_Update(self); return true; } bool LevelSpecial_Execute(LevelSpecial *self) { LevelSpecial_Update(self); return true; } void LevelSpecial_Update(LevelSpecial *self) { //OSReport("%08x%08x", EventTable->events >> 32, EventTable->events & 0xFFFFFFFF); u8 newEvState = 0; if (EventTable->events & self->eventFlag) newEvState = 1; if (newEvState == self->lastEvState) return; OSReport("Event state changed from %d to %d\n", self->lastEvState, newEvState); u8 offState; if (newEvState == ACTIVATE) { offState = (newEvState == 1) ? 1 : 0; OSReport("Activate Special Event!", offState); switch (self->type) { case 1: // Time Freeze TimeStopFlag = self->effect * 0x100; break; case 2: // Stop Timer TimerBranch = 0x7C601B78; break; case 3: // Mario Gravity if (self->effect == 0) { //Low grav MarioDescentRate = -2; MarioJumpArc = 0.5; MiniMarioJumpArc = 0.5; MarioJumpMax = 4.5; } else { //Anti-grav MarioDescentRate = 0.5; MarioJumpArc = 4.0; MiniMarioJumpArc = 4.0; MarioJumpMax = 0.0; } break; case 4: // Mario Size if (self->effect == 0) //Super Size MarioSize = 4.0; else //Half-Pint MarioSize = 0.25; break; default: break; } } else { offState = (newEvState == 1) ? 0 : 1; OSReport("Deactivate Special Event", offState); switch (self->type) { case 1: // Time Freeze TimeStopFlag = 0; break; case 2: // Stop Timer TimerBranch = 0x3403FFA4; break; case 3: // Mario Gravity MarioDescentRate = -4; MarioJumpArc = 2.5; MiniMarioJumpArc = 2.5; MarioJumpMax = 3.628; break; case 4: // Mario Size MarioSize = 1.0; break; default: break; } } OSReport("Special Event is %d\n", offState); OSReport("Success!\n"); self->lastEvState = newEvState; }