Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions lib/libpm-jp.a
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ pm_gHudElementSizes = 0x8015406C;
pm_MusicCurrentVolume = 0x8015EA66;
pm_gActionCommandStatus = 0x8029FED0;
pm_battle_move_power_bounce_BaseHitChance = 0x802A2730;
pm_HammerHit = 0x802B6E90;
pm_gNumScripts = 0x802DA488;
pm_gCurrentScriptListPtr = 0x802DA890;
pm_gScriptIndexList = 0x802DA898;
Expand Down
1 change: 1 addition & 0 deletions lib/libpm-us.a
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ pm_gHudElementSizes = 0x8014EFCC;
pm_MusicCurrentVolume = 0x80159AE6;
pm_gActionCommandStatus = 0x8029FBE0;
pm_battle_move_power_bounce_BaseHitChance = 0x802A2730;
pm_HammerHit = 0x802B6E90;
pm_gNumScripts = 0x802DA488;
pm_gCurrentScriptListPtr = 0x802DA890;
pm_gScriptIndexList = 0x802DA898;
Expand Down
55 changes: 55 additions & 0 deletions src/enums.h
Original file line number Diff line number Diff line change
Expand Up @@ -826,4 +826,59 @@ enum EvtOps {
/* 0x5E */ EVT_OP_94,
};

enum PlayerStatusFlags {
PS_FLAG_AIRBORNE = 0x0000000E,
PS_FLAG_HAS_REFLECTION = 0x00000001,
PS_FLAG_JUMPING = 0x00000002,
PS_FLAG_FALLING = 0x00000004,
PS_FLAG_FLYING = 0x00000008,
PS_FLAG_SLIDING = 0x00000010,
/* Paused either via the start menu, or through another menu that causes a pause (like the item menu) */
PS_FLAG_PAUSED = 0x00000020,
PS_FLAG_NO_CHANGE_PARTNER = 0x00000040,
PS_FLAG_NO_PARTNER_USAGE = 0x00000080,
/* Prevents opening menus that would require a game-time pause (start menu, item menu, etc) */
PS_FLAG_PAUSE_DISABLED = 0x00000100,
/* Doing either a spin jump or a tornado jump */
PS_FLAG_SPECIAL_JUMP = 0x00000200,
/* Landing from either a spin jump or a tornado jump */
PS_FLAG_SPECIAL_LAND = 0x00000400,
/* Burning from touching a fire hazard of some kind */
PS_FLAG_HIT_FIRE = 0x00000800,
PS_FLAG_NO_STATIC_COLLISION = 0x00001000,
PS_FLAG_INPUT_DISABLED = 0x00002000,
/* Indicates that Mario's lateral movement is currently commandeered by a cutscene or script */
PS_FLAG_CUTSCENE_MOVEMENT = 0x00004000,
/* Either outta sight with Bow, or temporarily damage boosted - makes Mario ignore fire bars */
PS_FLAG_HAZARD_INVINCIBILITY = 0x00008000,
/* Spinning either through pressing Z or the tornado jump - causes a ghost trail to render */
PS_FLAG_SPINNING = 0x00020000,
/* Slows Mario's physics and animations to half speed - responsible for the dramatic slowdown when starting an
encounter by jumping on an enemy. Also stops Mario from successfully completing a hammer. */
PS_FLAG_ENTERING_BATTLE = 0x00040000,
/* Occurs after hitting a heart block - temporarily prevents encounters from starting */
PS_FLAG_ARMS_RAISED = 0x00080000,
/* Stops Mario's sprite yaw from being adjusted, usually so a cutscene can do it instead. */
PS_FLAG_ROTATION_LOCKED = 0x00100000,
/* Forces Mario's sprite to either face exactly left or right, without transitioning. */
PS_FLAG_NO_FLIPPING = 0x00200000,
/* Prevents Mario from moving laterally */
PS_FLAG_MOVEMENT_LOCKED = 0x00400000, // TODO misnamed
/* Stops Mario from air steering or using a special jump during a scripted fall */
PS_FLAG_SCRIPTED_FALL = 0x00800000,
/* Not fully sure about this one, but appears to mark the frame that the check for what to hammer occurs */
PS_FLAG_HAMMER_CHECK = 0x01000000,
PS_FLAG_HAS_CONVERSATION_NPC = 0x02000000,
PS_FLAG_CAMERA_DOESNT_FOLLOW = 0x04000000,
/* Mario just interacted with something (usually cleared on the same frame) */
PS_FLAG_INTERACTED = 0x08000000,
/* Makes Mario face forwards, used when talking to NPCs, or when on Lakilester */
PS_FLAG_FACE_FORWARD = 0x10000000,
/* Freezes physics and animations - is usually reset at the start of a frame so often does nothing */
PS_FLAG_TIME_STOPPED = 0x20000000,
/* Indicates that Mario needs his sprite redrawn */
PS_FLAG_SPRITE_REDRAW = 0x40000000,
PS_FLAG_ACTION_STATE_CHANGED = 0x80000000,
};

#endif
106 changes: 106 additions & 0 deletions src/fp/practice/trainer.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "trainer.h"
#include "fp.h"
#include "menu/menu.h"
#include "sys/input.h"
#include "sys/resource.h"
#include "sys/settings.h"
#include <math.h>
Expand Down Expand Up @@ -570,11 +571,110 @@ static void updateClippyTrainer(void) {
}
}

static void updateQuickJumpTrainer(void) {
static s8 jumpFrame;
static u8 crouchFrame;
static u8 frame;
static bool waitForNextTurn;
static u8 frameWindow;

if (settings->trainerQuickJumpsEnabled && pm_gGameStatus.isBattle && pm_gBattleStatus.playerActor) {
if (pm_gBattleStatus.playerActor->partsTable->curAnimation == 0x10004) {
waitForNextTurn = FALSE;
jumpFrame = -1;
crouchFrame = 0;
frame = 0;
frameWindow = 0;
return;
}

if (waitForNextTurn) {
return;
}

if (pm_gBattleStatus.playerActor->partsTable->curAnimation == 0x10005 && frame <= 13) {
if (frameWindow == 0) {
if (pm_gBattleStatus.playerActor->state.moveTime < 13) {
frameWindow = 5;
} else {
frameWindow = pm_gBattleStatus.playerActor->state.moveTime - 9;
}
}
if (inputPressed().a && jumpFrame == -1) {
jumpFrame = frame;
}
frame++;
} else if (pm_gBattleStatus.playerActor->partsTable->curAnimation == 0x10008) {
waitForNextTurn = TRUE;
} else if (frame > 0) {
if (jumpFrame != -1) {
u8 framesSinceJump = frame - jumpFrame;
if (framesSinceJump == 1) {
fpLog("jumped frame 1 out of %d", frameWindow);
} else {
fpLog("jumped %d frame%s early", framesSinceJump - 1, framesSinceJump - 1 == 1 ? "" : "s");
}
waitForNextTurn = TRUE;
return;
}

if (crouchFrame == 0) {
crouchFrame = frame;
}

if (inputPressed().a) {
u8 framesAfterCrouch = frame - crouchFrame + 2;
if (framesAfterCrouch <= frameWindow) {
fpLog("jumped frame %d out of %d", framesAfterCrouch, frameWindow);
} else {
fpLog("jumped %d frame%s late", framesAfterCrouch - frameWindow,
framesAfterCrouch - frameWindow == 1 ? "" : "s");
}
waitForNextTurn = TRUE;
}

frame++;
}
}
}

static void updateHammerCancelTrainer(void) {
static bool canCancel;

if (settings->trainerHammerCancelsEnabled) {
if (pm_HammerHit.timer == 3) {
canCancel = TRUE;
}

if (pm_HammerHit.timer > 10) {
canCancel = FALSE;
}

if (inputPressed().b && canCancel) {
canCancel = FALSE;

if (pm_gPlayerStatus.flags & PS_FLAG_ENTERING_BATTLE) {
return;
}

if (pm_HammerHit.timer < 7) {
fpLog("hammered %d frame%s early", 7 - pm_HammerHit.timer, 7 - pm_HammerHit.timer == 1 ? "" : "s");
} else if (pm_HammerHit.timer > 7) {
fpLog("hammered %d frame%s late", pm_HammerHit.timer - 7, pm_HammerHit.timer - 7 == 1 ? "" : "s");
} else {
fpLog("hammered correct frame");
}
}
}
}

void trainerUpdate(void) {
updateBowserBlockTrainer();
updateLzsTrainer();
updateBlockTrainer();
updateClippyTrainer();
updateQuickJumpTrainer();
updateHammerCancelTrainer();
}

void trainerDrawPinned(s32 x, s32 y, struct GfxFont *font, s32 chWidth, s32 chHeight, u32 color, u8 alpha) {
Expand Down Expand Up @@ -624,6 +724,12 @@ void createTrainerMenu(struct Menu *menu) {
menuAddStatic(menu, 0, y, "action commands", 0xC0C0C0);
menuAddCheckbox(menu, xOffset, y++, menuByteCheckboxProc, &settings->trainerAcEnabled);

menuAddStatic(menu, 0, y, "quick jumps", 0xC0C0C0);
menuAddCheckbox(menu, xOffset, y++, menuByteCheckboxProc, &settings->trainerQuickJumpsEnabled);

menuAddStatic(menu, 0, y, "hammer cancels", 0xC0C0C0);
menuAddCheckbox(menu, xOffset, y++, menuByteCheckboxProc, &settings->trainerHammerCancelsEnabled);

menuAddStatic(menu, 0, y, "clippy", 0xC0C0C0);
struct MenuItem *lastOption =
menuAddCheckbox(menu, xOffset, y++, menuByteCheckboxProc, &settings->trainerClippyEnabled);
Expand Down
52 changes: 51 additions & 1 deletion src/pm64.h
Original file line number Diff line number Diff line change
Expand Up @@ -545,6 +545,46 @@ typedef struct pm_ActorMovement {
/* 0x4C */ f32 distance;
} pm_ActorMovement; // size = 0x50;

typedef struct pm_ActorPart {
/* 0x00 */ s32 flags;
/* 0x04 */ s32 targetFlags; /* initialized to 0 */
/* 0x08 */ void *staticData; // ActorPartBlueprint*
/* 0x0C */ struct pm_ActorPart *nextPart;
/* 0x10 */ void *movement; // ActorPartMovement*
/* 0x14 */ Vec3s partOffset;
/* 0x1A */ Vec3s visualOffset;
/* 0x20 */ Vec3f partOffsetFloat;
/* 0x2C */ Vec3f absolutePos;
/* 0x38 */ Vec3f rot;
/* 0x44 */ Vec3s rotPivotOffset;
/* 0x4A */ char unk_4A[2];
/* 0x4C */ Vec3f scale;
/* 0x58 */ Vec3f curPos;
/* 0x64 */ f32 yaw;
/* 0x68 */ s16 palAnimPosOffset[2]; // used by some palette animations to slightly adjust the screen position
/* 0x6C */ Vec2s targetOffset;
/* 0x70 */ s16 targetPriorityOffset;
/* 0x72 */ Vec2bu size;
/* 0x74 */ s8 verticalStretch;
/* 0x75 */ Vec2b projectileTargetOffset;
/* 0x77 */ char unk_77[1];
/* 0x78 */ u32 *defenseTable;
/* 0x7C */ s32 eventFlags;
/* 0x80 */ s32 elementalImmunities; // bits from Elements, i.e., ELEMENT_FIRE | ELEMENT_QUAKE
/* 0x84 */ s32 spriteInstanceID;
/* 0x88 */ u32 curAnimation;
/* 0x8C */ s32 animNotifyValue;
/* 0x90 */ f32 animationRate;
/* 0x94 */ u32 *idleAnimations;
/* 0x98 */ s16 opacity;
/* 0x9A */ char unk_9A[2];
/* 0x9C */ s32 shadowIndex;
/* 0xA0 */ f32 shadowScale;
/* 0xA4 */ s32 partTypeData[6];
/* 0xBC */ s16 actorTypeData2b[2];
/* 0xC0 */ void *decorationTable; // struct DecorationTable*, initialized to 0
} pm_ActorPart; // size = 0xC4

typedef struct pm_Actor {
/* 0x000 */ s32 flags;
/* 0x004 */ s32 flags2;
Expand Down Expand Up @@ -603,7 +643,7 @@ typedef struct pm_Actor {
/* 0x1F1 */ s8 turnPriority;
/* 0x1F2 */ s8 enemyIndex; /* actorID = this | 200 */
/* 0x1F3 */ s8 numParts;
/* 0x1F4 */ void *partsTable; // ActorPart
/* 0x1F4 */ pm_ActorPart *partsTable;
/* 0x1F8 */ s16 lastDamageTaken;
/* 0x1FA */ s16 hpChangeCounter;
/* 0x1FC */ u16 damageCounter;
Expand Down Expand Up @@ -1296,6 +1336,15 @@ typedef struct pm_Action {
/* 0x0C */ s8 flag;
} pm_Action; // size = 0x10

typedef struct pm_HammerHitData {
/* 0x00 */ Vec3f hitPos;
/* 0x0C */ s32 unk_0C;
/* 0x10 */ s32 hitID;
/* 0x14 */ s32 unk_14;
/* 0x18 */ s32 timer;
/* 0x1C */ s32 unk_1C;
} pm_HammerHitData;

typedef void *(*PrintCallback)(void *, const char *, u32);
typedef pm_Evt *pm_ScriptList[128];

Expand Down Expand Up @@ -1336,6 +1385,7 @@ extern_data pm_HudElementSize pm_gHudElementSizes[26];
extern_data s16 pm_MusicCurrentVolume;
extern_data pm_ActionCommandStatus pm_gActionCommandStatus;
extern_data s32 pm_battle_move_power_bounce_BaseHitChance;
extern_data pm_HammerHitData pm_HammerHit;
extern_data s32 pm_gNumScripts;
extern_data pm_ScriptList *pm_gCurrentScriptListPtr;
extern_data s32 pm_gScriptIndexList[128];
Expand Down
4 changes: 3 additions & 1 deletion src/sys/settings.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

#define SETTINGS_SAVE_FILE_SIZE 0x1380
#define SETTINGS_PROFILE_MAX 4
#define SETTINGS_VERSION 7
#define SETTINGS_VERSION 8
#define SETTINGS_FIO_PAGE 7

#define SETTINGS_WATCHES_MAX 18
Expand Down Expand Up @@ -74,6 +74,8 @@ struct SettingsData {
u8 trainerLzsEnabled;
u8 trainerAcEnabled;
u8 trainerClippyEnabled;
u8 trainerQuickJumpsEnabled;
u8 trainerHammerCancelsEnabled;
u8 trainerDisplayPinned;
u8 battleDebug;
u8 quickLaunch;
Expand Down
5 changes: 5 additions & 0 deletions src/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,11 @@ typedef struct {
/* 0x04 */ f32 z;
} Vec2XZf; // size = 0x08

typedef struct Vec2s {
/* 0x00 */ s16 x;
/* 0x02 */ s16 y;
} Vec2s; // size = 0x04

typedef struct {
/* 0x00 */ f32 x;
/* 0x04 */ f32 y;
Expand Down