Add some sanity checks to prevent bugs and exploits. (#767)

* Add some sanity checks to prevent bugs and exploits.

* Improve sanity check for Koopa Shell Riding.

* Sort and optimize MarioState structure.
This commit is contained in:
Prince Frizzy 2025-04-27 17:02:15 -04:00 committed by GitHub
parent 0e00fe7ad3
commit 15d6f6ae07
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
16 changed files with 2078 additions and 1972 deletions

View file

@ -4706,6 +4706,13 @@ function does_mario_have_normal_cap_on_head(m)
-- ... -- ...
end end
--- @param m MarioState
--- @return boolean
--- Checks if Mario has already had a cap blown off of his head in the current level, Returns true if a blown cap can be found for Mario, false if not. Useful to check if a blown cap exists in the level currently.
function does_mario_have_blown_cap(m)
-- ...
end
--- @param m MarioState --- @param m MarioState
--- @param capSpeed number --- @param capSpeed number
--- Makes Mario blow off his normal cap at a given speed. Removes the normal cap from Mario's head and spawns it as a collectible object in the game world. Useful for simulating events where Mario loses his cap due to enemy attacks or environmental forces --- Makes Mario blow off his normal cap at a given speed. Removes the normal cap from Mario's head and spawns it as a collectible object in the game world. Useful for simulating events where Mario loses his cap due to enemy attacks or environmental forces

View file

@ -1071,6 +1071,7 @@
--- @field public fixCollisionBugsGroundPoundBonks integer --- @field public fixCollisionBugsGroundPoundBonks integer
--- @field public fixCollisionBugsPickBestWall integer --- @field public fixCollisionBugsPickBestWall integer
--- @field public fixCollisionBugsRoundedCorners integer --- @field public fixCollisionBugsRoundedCorners integer
--- @field public fixInvalidShellRides integer
--- @field public fixVanishFloors integer --- @field public fixVanishFloors integer
--- @field public floatingStarDance integer --- @field public floatingStarDance integer
--- @field public floorLowerLimit integer --- @field public floorLowerLimit integer

View file

@ -5640,6 +5640,29 @@ Checks if Mario is currently wearing his normal cap on his head. Returns true if
<br /> <br />
## [does_mario_have_blown_cap](#does_mario_have_blown_cap)
### Description
Checks if Mario has already had a cap blown off of his head in the current level, Returns true if a blown cap can be found for Mario, false if not. Useful to check if a blown cap exists in the level currently.
### Lua Example
`local booleanValue = does_mario_have_blown_cap(m)`
### Parameters
| Field | Type |
| ----- | ---- |
| m | [MarioState](structs.md#MarioState) |
### Returns
- `boolean`
### C Prototype
`bool does_mario_have_blown_cap(struct MarioState *m);`
[:arrow_up_small:](#)
<br />
## [mario_blow_off_cap](#mario_blow_off_cap) ## [mario_blow_off_cap](#mario_blow_off_cap)
### Description ### Description

View file

@ -911,6 +911,7 @@
- [mario_throw_held_object](functions-3.md#mario_throw_held_object) - [mario_throw_held_object](functions-3.md#mario_throw_held_object)
- [mario_stop_riding_and_holding](functions-3.md#mario_stop_riding_and_holding) - [mario_stop_riding_and_holding](functions-3.md#mario_stop_riding_and_holding)
- [does_mario_have_normal_cap_on_head](functions-3.md#does_mario_have_normal_cap_on_head) - [does_mario_have_normal_cap_on_head](functions-3.md#does_mario_have_normal_cap_on_head)
- [does_mario_have_blown_cap](functions-3.md#does_mario_have_blown_cap)
- [mario_blow_off_cap](functions-3.md#mario_blow_off_cap) - [mario_blow_off_cap](functions-3.md#mario_blow_off_cap)
- [mario_lose_cap_to_enemy](functions-3.md#mario_lose_cap_to_enemy) - [mario_lose_cap_to_enemy](functions-3.md#mario_lose_cap_to_enemy)
- [mario_retrieve_cap](functions-3.md#mario_retrieve_cap) - [mario_retrieve_cap](functions-3.md#mario_retrieve_cap)

View file

@ -1642,6 +1642,7 @@
| fixCollisionBugsGroundPoundBonks | `integer` | | | fixCollisionBugsGroundPoundBonks | `integer` | |
| fixCollisionBugsPickBestWall | `integer` | | | fixCollisionBugsPickBestWall | `integer` | |
| fixCollisionBugsRoundedCorners | `integer` | | | fixCollisionBugsRoundedCorners | `integer` | |
| fixInvalidShellRides | `integer` | |
| fixVanishFloors | `integer` | | | fixVanishFloors | `integer` | |
| floatingStarDance | `integer` | | | floatingStarDance | `integer` | |
| floorLowerLimit | `integer` | | | floorLowerLimit | `integer` | |

File diff suppressed because it is too large Load diff

View file

@ -355,90 +355,119 @@ struct MarioAnimation
struct MarioState struct MarioState
{ {
/*0x00*/ u16 playerIndex; // Please try to keep this 32/64 bit aligned.
/*0x02*/ u16 input; // Bit alignment can increase perforamance and
/*0x04*/ u32 flags; // reduce the memory footprint.
/*0x08*/ u32 particleFlags; //
/*0x0C*/ u32 action; // Structure size was reduced by 32 bytes and fields
/*0x10*/ u32 prevAction; // and been moved for performance and size.
/*0x14*/ u32 terrainSoundAddend; // https://en.wikipedia.org/wiki/Data_structure_alignment
/*0x18*/ u16 actionState; //
/*0x1A*/ u16 actionTimer; // I personally also find it easier to read now.
/*0x1C*/ u32 actionArg; // - Prince Frizzy
/*0x20*/ f32 intendedMag;
/*0x24*/ s16 intendedYaw;
/*0x26*/ s16 invincTimer;
/*0x28*/ u8 framesSinceA;
/*0x29*/ u8 framesSinceB;
/*0x2A*/ u8 wallKickTimer;
/*0x2B*/ u8 doubleJumpTimer;
/*0x2C*/ Vec3s faceAngle;
/*0x32*/ Vec3s angleVel;
/*0x38*/ s16 slideYaw;
/*0x3A*/ s16 twirlYaw;
/*0x3C*/ Vec3f pos;
/*0x48*/ Vec3f vel;
/*0x54*/ f32 forwardVel;
/*0x58*/ f32 slideVelX;
/*0x5C*/ f32 slideVelZ;
/*0x60*/ struct Surface *wall;
/*0x64*/ struct Surface *ceil;
/*0x68*/ struct Surface *floor;
/*0x6C*/ f32 ceilHeight;
/*0x70*/ f32 floorHeight;
/*0x74*/ s16 floorAngle;
/*0x76*/ s16 waterLevel;
/*0x78*/ struct Object *interactObj;
/*0x7C*/ struct Object *heldObj;
/*0x80*/ struct Object *usedObj;
/*0x84*/ struct Object *riddenObj;
/*0x88*/ struct Object *marioObj;
/*0x8C*/ struct SpawnInfo *spawnInfo;
/*0x90*/ struct Area *area;
/*0x94*/ struct PlayerCameraState *statusForCamera;
/*0x98*/ struct MarioBodyState *marioBodyState;
/*0x9C*/ struct Controller *controller;
/*0xA0*/ struct MarioAnimation *animation;
/*0xA4*/ u32 collidedObjInteractTypes;
/*0xA8*/ s16 numCoins;
/*0xAA*/ s16 numStars;
/*0xAC*/ s8 numKeys; // Unused key mechanic
/*0xAD*/ s8 numLives;
/*0xAE*/ s16 health;
/*0xB0*/ s16 unkB0;
/*0xB2*/ u8 hurtCounter;
/*0xB3*/ u8 healCounter;
/*0xB4*/ u8 squishTimer;
/*0xB5*/ u8 fadeWarpOpacity;
/*0xB6*/ u16 capTimer;
/*0xB8*/ s16 prevNumStarsForDialog;
/*0xBC*/ f32 peakHeight;
/*0xC0*/ f32 quicksandDepth;
/*0xC4*/ f32 unkC4;
/*0xC8*/ s16 currentRoom;
/*0xCA*/ struct Object* heldByObj;
/*????*/ u8 isSnoring;
/*????*/ struct Object* bubbleObj;
/*????*/ u8 freeze;
u16 playerIndex;
u16 input;
s16 numCoins;
s16 numStars;
s8 numLives;
s8 numKeys; // Unused key mechanic
s16 health;
u8 hurtCounter;
u8 healCounter;
u8 isSnoring;
u8 freeze;
u32 cap;
u16 capTimer;
s16 invincTimer;
u8 skipWarpInteractionsTimer;
u8 squishTimer;
u8 bounceSquishTimer;
s8 knockbackTimer;
u8 wallKickTimer;
u8 doubleJumpTimer;
u8 specialTripleJump;
u8 fadeWarpOpacity;
u8 visibleToEnemies;
u8 wasNetworkVisible;
s16 dialogId;
s16 prevNumStarsForDialog;
s16 unkB0;
u32 action;
u32 prevAction;
u32 actionArg;
u16 actionTimer;
u16 actionState;
u32 flags;
f32 quicksandDepth;
struct Controller *controller;
struct MarioBodyState *marioBodyState;
struct Character *character;
u32 terrainSoundAddend;
Vec3f pos;
Vec3f nonInstantWarpPos;
Vec3f vel;
f32 slideVelX;
f32 slideVelZ;
f32 forwardVel;
f32 peakHeight;
f32 intendedMag;
s16 intendedYaw;
u8 framesSinceA;
u8 framesSinceB;
Vec3s faceAngle;
Vec3s angleVel;
s16 slideYaw;
s16 twirlYaw;
struct Object *heldObj;
struct Object *heldByObj;
struct Object *interactObj;
struct Object *riddenObj;
struct Object *usedObj;
struct Object *marioObj;
struct Object *bubbleObj;
u32 collidedObjInteractTypes;
u32 particleFlags;
struct MarioAnimation *animation;
// Variables for a spline curve animation (used for the flight path in the grand star cutscene) // Variables for a spline curve animation (used for the flight path in the grand star cutscene)
/*????*/ Vec4s* splineKeyframe; Vec4s *splineKeyframe;
/*????*/ f32 splineKeyframeFraction; f32 splineKeyframeFraction;
/*????*/ s32 splineState; s32 splineState;
f32 curAnimOffset;
/*????*/ Vec3f nonInstantWarpPos; f32 minimumBoneY;
/*????*/ struct Character* character;
/*????*/ u8 wasNetworkVisible; struct Surface *wall;
/*????*/ f32 minimumBoneY; struct Surface *ceil;
/*????*/ f32 curAnimOffset; struct Surface *floor;
/*????*/ s8 knockbackTimer; struct SpawnInfo *spawnInfo;
/*????*/ u8 specialTripleJump; struct Area *area;
/*????*/ Vec3f wallNormal; struct PlayerCameraState *statusForCamera;
/*????*/ u8 visibleToEnemies;
/*????*/ u32 cap; f32 ceilHeight;
/*????*/ u8 bounceSquishTimer; f32 floorHeight;
/*????*/ u8 skipWarpInteractionsTimer;
/*????*/ s16 dialogId; Vec3f wallNormal;
f32 unkC4;
s16 floorAngle;
s16 waterLevel;
s16 currentRoom;
}; };
struct TextureInfo struct TextureInfo

View file

@ -50,6 +50,7 @@ struct LevelValues gDefaultLevelValues = {
.fixCollisionBugsGroundPoundBonks = TRUE, .fixCollisionBugsGroundPoundBonks = TRUE,
.fixCollisionBugsPickBestWall = TRUE, .fixCollisionBugsPickBestWall = TRUE,
.fixVanishFloors = FALSE, .fixVanishFloors = FALSE,
.fixInvalidShellRides = TRUE,
.hudCapTimer = FALSE, .hudCapTimer = FALSE,
.hudRedCoinsRadar = FALSE, .hudRedCoinsRadar = FALSE,
.hudSecretsRadar = FALSE, .hudSecretsRadar = FALSE,

View file

@ -48,6 +48,7 @@ struct LevelValues {
u8 fixCollisionBugsGroundPoundBonks; u8 fixCollisionBugsGroundPoundBonks;
u8 fixCollisionBugsPickBestWall; u8 fixCollisionBugsPickBestWall;
u8 fixVanishFloors; u8 fixVanishFloors;
u8 fixInvalidShellRides;
u8 hudCapTimer; u8 hudCapTimer;
u8 hudRedCoinsRadar; u8 hudRedCoinsRadar;
u8 hudSecretsRadar; u8 hudSecretsRadar;

View file

@ -25,12 +25,14 @@
#include "sound_init.h" #include "sound_init.h"
#include "rumble_init.h" #include "rumble_init.h"
#include "object_collision.h" #include "object_collision.h"
#include "object_list_processor.h"
#include "hardcoded.h" #include "hardcoded.h"
#include "pc/configfile.h" #include "pc/configfile.h"
#include "pc/network/network.h" #include "pc/network/network.h"
#include "pc/network/lag_compensation.h" #include "pc/network/lag_compensation.h"
#include "pc/lua/smlua_hooks.h" #include "pc/lua/smlua_hooks.h"
#include "pc/lua/utils/smlua_obj_utils.h"
u8 sDelayInvincTimer; u8 sDelayInvincTimer;
s16 gInteractionInvulnerable; s16 gInteractionInvulnerable;
@ -279,8 +281,8 @@ u32 attack_object(struct MarioState* m, struct Object *o, s32 interaction) {
} }
void mario_stop_riding_object(struct MarioState *m) { void mario_stop_riding_object(struct MarioState *m) {
if (!m) { return; } if (!m || m->riddenObj == NULL || m->playerIndex != 0) { return; }
if (m->riddenObj != NULL && m->playerIndex == 0) {
m->riddenObj->oInteractStatus = INT_STATUS_STOP_RIDING; m->riddenObj->oInteractStatus = INT_STATUS_STOP_RIDING;
if (m->riddenObj->oSyncID != 0) { if (m->riddenObj->oSyncID != 0) {
network_send_object_reliability(m->riddenObj, TRUE); network_send_object_reliability(m->riddenObj, TRUE);
@ -288,7 +290,6 @@ void mario_stop_riding_object(struct MarioState *m) {
stop_shell_music(); stop_shell_music();
m->riddenObj = NULL; m->riddenObj = NULL;
} }
}
void mario_grab_used_object(struct MarioState *m) { void mario_grab_used_object(struct MarioState *m) {
if (!m) { return; } if (!m) { return; }
@ -375,18 +376,22 @@ u32 does_mario_have_normal_cap_on_head(struct MarioState *m) {
return (m->flags & (MARIO_CAPS | MARIO_CAP_ON_HEAD)) == (MARIO_NORMAL_CAP | MARIO_CAP_ON_HEAD); return (m->flags & (MARIO_CAPS | MARIO_CAP_ON_HEAD)) == (MARIO_NORMAL_CAP | MARIO_CAP_ON_HEAD);
} }
bool does_mario_have_blown_cap(struct MarioState *m) {
if (!m) { return FALSE; }
return obj_get_first_with_behavior_id_and_field_s32(id_bhvNormalCap, 0x40, m->playerIndex + 1) != NULL;
}
void mario_blow_off_cap(struct MarioState *m, f32 capSpeed) { void mario_blow_off_cap(struct MarioState *m, f32 capSpeed) {
if (!m) { return; } if (!m) { return; }
if (m->playerIndex != 0) { return; } if (m->playerIndex != 0) { return; }
struct Object *capObject; if (!does_mario_have_normal_cap_on_head(m) || does_mario_have_blown_cap(m)) { return; }
if (does_mario_have_normal_cap_on_head(m)) {
m->cap = SAVE_FLAG_CAP_ON_MR_BLIZZARD; m->cap = SAVE_FLAG_CAP_ON_MR_BLIZZARD;
m->flags &= ~(MARIO_NORMAL_CAP | MARIO_CAP_ON_HEAD); m->flags &= ~(MARIO_NORMAL_CAP | MARIO_CAP_ON_HEAD);
u8 capModel = m->character->capModelId; u8 capModel = m->character->capModelId;
capObject = spawn_object(m->marioObj, capModel, bhvNormalCap); struct Object *capObject = spawn_object(m->marioObj, capModel, bhvNormalCap);
if (capObject == NULL) { return; } if (capObject == NULL) { return; }
capObject->globalPlayerIndex = gNetworkPlayers[m->playerIndex].globalIndex; capObject->globalPlayerIndex = gNetworkPlayers[m->playerIndex].globalIndex;
capObject->oBehParams = m->playerIndex + 1; capObject->oBehParams = m->playerIndex + 1;
@ -406,7 +411,6 @@ void mario_blow_off_cap(struct MarioState *m, f32 capSpeed) {
u32 models[] = { capModel }; u32 models[] = { capModel };
network_send_spawn_objects(spawn_objects, models, 1); network_send_spawn_objects(spawn_objects, models, 1);
} }
}
u32 mario_lose_cap_to_enemy(struct MarioState* m, u32 arg) { u32 mario_lose_cap_to_enemy(struct MarioState* m, u32 arg) {
if (!m) { return FALSE; } if (!m) { return FALSE; }

View file

@ -352,6 +352,13 @@ Useful for determining Mario's cap status
|descriptionEnd| */ |descriptionEnd| */
u32 does_mario_have_normal_cap_on_head(struct MarioState *m); u32 does_mario_have_normal_cap_on_head(struct MarioState *m);
/* |description|
Checks if Mario has already had a cap blown off of his head in the current level,
Returns true if a blown cap can be found for Mario, false if not.
Useful to check if a blown cap exists in the level currently.
|descriptionEnd| */
bool does_mario_have_blown_cap(struct MarioState *m);
/* |description| /* |description|
Makes Mario blow off his normal cap at a given speed. Makes Mario blow off his normal cap at a given speed.
Removes the normal cap from Mario's head and spawns it as a collectible object in the game world. Removes the normal cap from Mario's head and spawns it as a collectible object in the game world.

View file

@ -1611,10 +1611,6 @@ void update_mario_inputs(struct MarioState *m) {
#endif #endif
/* End of developer stuff */ /* End of developer stuff */
if ((m->action == ACT_END_PEACH_CUTSCENE || m->action == ACT_CREDITS_CUTSCENE) && m->controller->buttonPressed & START_BUTTON) {
lvl_skip_credits();
}
if (m->playerIndex == 0) { if (m->playerIndex == 0) {
if (!localIsPaused && (gCameraMovementFlags & CAM_MOVE_C_UP_MODE)) { if (!localIsPaused && (gCameraMovementFlags & CAM_MOVE_C_UP_MODE)) {
if (m->action & ACT_FLAG_ALLOW_FIRST_PERSON) { if (m->action & ACT_FLAG_ALLOW_FIRST_PERSON) {

View file

@ -3003,6 +3003,10 @@ static s32 act_end_peach_cutscene(struct MarioState *m) {
m->actionTimer++; m->actionTimer++;
if (m->playerIndex == 0) { if (m->playerIndex == 0) {
if (m->controller->buttonPressed & START_BUTTON) {
lvl_skip_credits();
}
sEndCutsceneVp.vp.vscale[0] = 640; sEndCutsceneVp.vp.vscale[0] = 640;
sEndCutsceneVp.vp.vscale[1] = 360; sEndCutsceneVp.vp.vscale[1] = 360;
sEndCutsceneVp.vp.vtrans[0] = 640; sEndCutsceneVp.vp.vtrans[0] = 640;
@ -3050,6 +3054,10 @@ static s32 act_credits_cutscene(struct MarioState *m) {
} }
} }
if (m->playerIndex == 0 && m->controller->buttonPressed & START_BUTTON) {
lvl_skip_credits();
}
if (m->actionTimer >= TIMER_CREDITS_SHOW) { if (m->actionTimer >= TIMER_CREDITS_SHOW) {
if (m->actionState < 40) { if (m->actionState < 40) {
m->actionState += 2; m->actionState += 2;

View file

@ -12,6 +12,7 @@
#include "memory.h" #include "memory.h"
#include "behavior_data.h" #include "behavior_data.h"
#include "rumble_init.h" #include "rumble_init.h"
#include "hardcoded.h"
#include "pc/debuglog.h" #include "pc/debuglog.h"
#include "pc/configfile.h" #include "pc/configfile.h"
#include "pc/network/network.h" #include "pc/network/network.h"
@ -1344,7 +1345,12 @@ s32 act_hold_decelerating(struct MarioState *m) {
s32 act_riding_shell_ground(struct MarioState *m) { s32 act_riding_shell_ground(struct MarioState *m) {
if (!m) { return FALSE; } if (!m) { return FALSE; }
s16 startYaw = m->faceAngle[1];
// If we don't have an object we're riding or if the interaction was with something
// not a Koopa Shell-Then we abort the riding state.
if (gLevelValues.fixInvalidShellRides && (m->riddenObj == NULL || m->riddenObj->oInteractType != INTERACT_KOOPA_SHELL)) {
return set_mario_action(m, ACT_IDLE, 0);
}
if (m->input & INPUT_A_PRESSED) { if (m->input & INPUT_A_PRESSED) {
return set_mario_action(m, ACT_RIDING_SHELL_JUMP, 0); return set_mario_action(m, ACT_RIDING_SHELL_JUMP, 0);
@ -1358,6 +1364,7 @@ s32 act_riding_shell_ground(struct MarioState *m) {
return set_mario_action(m, ACT_CROUCH_SLIDE, 0); return set_mario_action(m, ACT_CROUCH_SLIDE, 0);
} }
s16 startYaw = m->faceAngle[1];
update_shell_speed(m); update_shell_speed(m);
set_character_animation(m, m->actionArg == 0 ? CHAR_ANIM_START_RIDING_SHELL : CHAR_ANIM_RIDING_SHELL); set_character_animation(m, m->actionArg == 0 ? CHAR_ANIM_START_RIDING_SHELL : CHAR_ANIM_RIDING_SHELL);

View file

@ -1327,7 +1327,7 @@ static struct LuaObjectField sLakituStateFields[LUA_LAKITU_STATE_FIELD_COUNT] =
{ "yaw", LVT_S16, offsetof(struct LakituState, yaw), false, LOT_NONE, 1, sizeof(s16) }, { "yaw", LVT_S16, offsetof(struct LakituState, yaw), false, LOT_NONE, 1, sizeof(s16) },
}; };
#define LUA_LEVEL_VALUES_FIELD_COUNT 51 #define LUA_LEVEL_VALUES_FIELD_COUNT 52
static struct LuaObjectField sLevelValuesFields[LUA_LEVEL_VALUES_FIELD_COUNT] = { static struct LuaObjectField sLevelValuesFields[LUA_LEVEL_VALUES_FIELD_COUNT] = {
{ "bubbleOnDeathBarrierInCapStages", LVT_U8, offsetof(struct LevelValues, bubbleOnDeathBarrierInCapStages), false, LOT_NONE, 1, sizeof(u8) }, { "bubbleOnDeathBarrierInCapStages", LVT_U8, offsetof(struct LevelValues, bubbleOnDeathBarrierInCapStages), false, LOT_NONE, 1, sizeof(u8) },
{ "cellHeightLimit", LVT_S16, offsetof(struct LevelValues, cellHeightLimit), false, LOT_NONE, 1, sizeof(s16) }, { "cellHeightLimit", LVT_S16, offsetof(struct LevelValues, cellHeightLimit), false, LOT_NONE, 1, sizeof(s16) },
@ -1343,6 +1343,7 @@ static struct LuaObjectField sLevelValuesFields[LUA_LEVEL_VALUES_FIELD_COUNT] =
{ "fixCollisionBugsGroundPoundBonks", LVT_U8, offsetof(struct LevelValues, fixCollisionBugsGroundPoundBonks), false, LOT_NONE, 1, sizeof(u8) }, { "fixCollisionBugsGroundPoundBonks", LVT_U8, offsetof(struct LevelValues, fixCollisionBugsGroundPoundBonks), false, LOT_NONE, 1, sizeof(u8) },
{ "fixCollisionBugsPickBestWall", LVT_U8, offsetof(struct LevelValues, fixCollisionBugsPickBestWall), false, LOT_NONE, 1, sizeof(u8) }, { "fixCollisionBugsPickBestWall", LVT_U8, offsetof(struct LevelValues, fixCollisionBugsPickBestWall), false, LOT_NONE, 1, sizeof(u8) },
{ "fixCollisionBugsRoundedCorners", LVT_U8, offsetof(struct LevelValues, fixCollisionBugsRoundedCorners), false, LOT_NONE, 1, sizeof(u8) }, { "fixCollisionBugsRoundedCorners", LVT_U8, offsetof(struct LevelValues, fixCollisionBugsRoundedCorners), false, LOT_NONE, 1, sizeof(u8) },
{ "fixInvalidShellRides", LVT_U8, offsetof(struct LevelValues, fixInvalidShellRides), false, LOT_NONE, 1, sizeof(u8) },
{ "fixVanishFloors", LVT_U8, offsetof(struct LevelValues, fixVanishFloors), false, LOT_NONE, 1, sizeof(u8) }, { "fixVanishFloors", LVT_U8, offsetof(struct LevelValues, fixVanishFloors), false, LOT_NONE, 1, sizeof(u8) },
{ "floatingStarDance", LVT_U8, offsetof(struct LevelValues, floatingStarDance), false, LOT_NONE, 1, sizeof(u8) }, { "floatingStarDance", LVT_U8, offsetof(struct LevelValues, floatingStarDance), false, LOT_NONE, 1, sizeof(u8) },
{ "floorLowerLimit", LVT_S16, offsetof(struct LevelValues, floorLowerLimit), false, LOT_NONE, 1, sizeof(s16) }, { "floorLowerLimit", LVT_S16, offsetof(struct LevelValues, floorLowerLimit), false, LOT_NONE, 1, sizeof(s16) },

View file

@ -14716,6 +14716,24 @@ int smlua_func_does_mario_have_normal_cap_on_head(lua_State* L) {
return 1; return 1;
} }
int smlua_func_does_mario_have_blown_cap(lua_State* L) {
if (L == NULL) { return 0; }
int top = lua_gettop(L);
if (top != 1) {
LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "does_mario_have_blown_cap", 1, top);
return 0;
}
if (lua_isnil(L, 1)) { return 0; }
struct MarioState* m = (struct MarioState*)smlua_to_cobject(L, 1, LOT_MARIOSTATE);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 1, "does_mario_have_blown_cap"); return 0; }
lua_pushboolean(L, does_mario_have_blown_cap(m));
return 1;
}
int smlua_func_mario_blow_off_cap(lua_State* L) { int smlua_func_mario_blow_off_cap(lua_State* L) {
if (L == NULL) { return 0; } if (L == NULL) { return 0; }
@ -35024,6 +35042,7 @@ void smlua_bind_functions_autogen(void) {
smlua_bind_function(L, "mario_throw_held_object", smlua_func_mario_throw_held_object); smlua_bind_function(L, "mario_throw_held_object", smlua_func_mario_throw_held_object);
smlua_bind_function(L, "mario_stop_riding_and_holding", smlua_func_mario_stop_riding_and_holding); smlua_bind_function(L, "mario_stop_riding_and_holding", smlua_func_mario_stop_riding_and_holding);
smlua_bind_function(L, "does_mario_have_normal_cap_on_head", smlua_func_does_mario_have_normal_cap_on_head); smlua_bind_function(L, "does_mario_have_normal_cap_on_head", smlua_func_does_mario_have_normal_cap_on_head);
smlua_bind_function(L, "does_mario_have_blown_cap", smlua_func_does_mario_have_blown_cap);
smlua_bind_function(L, "mario_blow_off_cap", smlua_func_mario_blow_off_cap); smlua_bind_function(L, "mario_blow_off_cap", smlua_func_mario_blow_off_cap);
smlua_bind_function(L, "mario_lose_cap_to_enemy", smlua_func_mario_lose_cap_to_enemy); smlua_bind_function(L, "mario_lose_cap_to_enemy", smlua_func_mario_lose_cap_to_enemy);
smlua_bind_function(L, "mario_retrieve_cap", smlua_func_mario_retrieve_cap); smlua_bind_function(L, "mario_retrieve_cap", smlua_func_mario_retrieve_cap);