mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2025-10-30 08:01:01 +00:00
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:
parent
0e00fe7ad3
commit
15d6f6ae07
16 changed files with 2078 additions and 1972 deletions
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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
195
include/types.h
195
include/types.h
|
|
@ -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;
|
u16 playerIndex;
|
||||||
/*0x26*/ s16 invincTimer;
|
u16 input;
|
||||||
/*0x28*/ u8 framesSinceA;
|
s16 numCoins;
|
||||||
/*0x29*/ u8 framesSinceB;
|
s16 numStars;
|
||||||
/*0x2A*/ u8 wallKickTimer;
|
|
||||||
/*0x2B*/ u8 doubleJumpTimer;
|
s8 numLives;
|
||||||
/*0x2C*/ Vec3s faceAngle;
|
s8 numKeys; // Unused key mechanic
|
||||||
/*0x32*/ Vec3s angleVel;
|
s16 health;
|
||||||
/*0x38*/ s16 slideYaw;
|
u8 hurtCounter;
|
||||||
/*0x3A*/ s16 twirlYaw;
|
u8 healCounter;
|
||||||
/*0x3C*/ Vec3f pos;
|
u8 isSnoring;
|
||||||
/*0x48*/ Vec3f vel;
|
u8 freeze;
|
||||||
/*0x54*/ f32 forwardVel;
|
|
||||||
/*0x58*/ f32 slideVelX;
|
u32 cap;
|
||||||
/*0x5C*/ f32 slideVelZ;
|
u16 capTimer;
|
||||||
/*0x60*/ struct Surface *wall;
|
s16 invincTimer;
|
||||||
/*0x64*/ struct Surface *ceil;
|
|
||||||
/*0x68*/ struct Surface *floor;
|
u8 skipWarpInteractionsTimer;
|
||||||
/*0x6C*/ f32 ceilHeight;
|
u8 squishTimer;
|
||||||
/*0x70*/ f32 floorHeight;
|
u8 bounceSquishTimer;
|
||||||
/*0x74*/ s16 floorAngle;
|
s8 knockbackTimer;
|
||||||
/*0x76*/ s16 waterLevel;
|
u8 wallKickTimer;
|
||||||
/*0x78*/ struct Object *interactObj;
|
u8 doubleJumpTimer;
|
||||||
/*0x7C*/ struct Object *heldObj;
|
u8 specialTripleJump;
|
||||||
/*0x80*/ struct Object *usedObj;
|
u8 fadeWarpOpacity;
|
||||||
/*0x84*/ struct Object *riddenObj;
|
|
||||||
/*0x88*/ struct Object *marioObj;
|
u8 visibleToEnemies;
|
||||||
/*0x8C*/ struct SpawnInfo *spawnInfo;
|
u8 wasNetworkVisible;
|
||||||
/*0x90*/ struct Area *area;
|
s16 dialogId;
|
||||||
/*0x94*/ struct PlayerCameraState *statusForCamera;
|
s16 prevNumStarsForDialog;
|
||||||
/*0x98*/ struct MarioBodyState *marioBodyState;
|
s16 unkB0;
|
||||||
/*0x9C*/ struct Controller *controller;
|
|
||||||
/*0xA0*/ struct MarioAnimation *animation;
|
u32 action;
|
||||||
/*0xA4*/ u32 collidedObjInteractTypes;
|
u32 prevAction;
|
||||||
/*0xA8*/ s16 numCoins;
|
|
||||||
/*0xAA*/ s16 numStars;
|
u32 actionArg;
|
||||||
/*0xAC*/ s8 numKeys; // Unused key mechanic
|
u16 actionTimer;
|
||||||
/*0xAD*/ s8 numLives;
|
u16 actionState;
|
||||||
/*0xAE*/ s16 health;
|
|
||||||
/*0xB0*/ s16 unkB0;
|
u32 flags;
|
||||||
/*0xB2*/ u8 hurtCounter;
|
f32 quicksandDepth;
|
||||||
/*0xB3*/ u8 healCounter;
|
|
||||||
/*0xB4*/ u8 squishTimer;
|
struct Controller *controller;
|
||||||
/*0xB5*/ u8 fadeWarpOpacity;
|
struct MarioBodyState *marioBodyState;
|
||||||
/*0xB6*/ u16 capTimer;
|
struct Character *character;
|
||||||
/*0xB8*/ s16 prevNumStarsForDialog;
|
|
||||||
/*0xBC*/ f32 peakHeight;
|
u32 terrainSoundAddend;
|
||||||
/*0xC0*/ f32 quicksandDepth;
|
|
||||||
/*0xC4*/ f32 unkC4;
|
Vec3f pos;
|
||||||
/*0xC8*/ s16 currentRoom;
|
Vec3f nonInstantWarpPos;
|
||||||
/*0xCA*/ struct Object* heldByObj;
|
Vec3f vel;
|
||||||
/*????*/ u8 isSnoring;
|
f32 slideVelX;
|
||||||
/*????*/ struct Object* bubbleObj;
|
f32 slideVelZ;
|
||||||
/*????*/ u8 freeze;
|
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;
|
|
||||||
/*????*/ struct Character* character;
|
f32 minimumBoneY;
|
||||||
/*????*/ u8 wasNetworkVisible;
|
|
||||||
/*????*/ f32 minimumBoneY;
|
struct Surface *wall;
|
||||||
/*????*/ f32 curAnimOffset;
|
struct Surface *ceil;
|
||||||
/*????*/ s8 knockbackTimer;
|
struct Surface *floor;
|
||||||
/*????*/ u8 specialTripleJump;
|
struct SpawnInfo *spawnInfo;
|
||||||
/*????*/ Vec3f wallNormal;
|
struct Area *area;
|
||||||
/*????*/ u8 visibleToEnemies;
|
struct PlayerCameraState *statusForCamera;
|
||||||
/*????*/ u32 cap;
|
|
||||||
/*????*/ u8 bounceSquishTimer;
|
f32 ceilHeight;
|
||||||
/*????*/ u8 skipWarpInteractionsTimer;
|
f32 floorHeight;
|
||||||
/*????*/ s16 dialogId;
|
|
||||||
|
Vec3f wallNormal;
|
||||||
|
f32 unkC4;
|
||||||
|
|
||||||
|
s16 floorAngle;
|
||||||
|
s16 waterLevel;
|
||||||
|
s16 currentRoom;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TextureInfo
|
struct TextureInfo
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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,15 +281,14 @@ 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);
|
||||||
}
|
|
||||||
stop_shell_music();
|
|
||||||
m->riddenObj = NULL;
|
|
||||||
}
|
}
|
||||||
|
stop_shell_music();
|
||||||
|
m->riddenObj = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mario_grab_used_object(struct MarioState *m) {
|
void mario_grab_used_object(struct MarioState *m) {
|
||||||
|
|
@ -375,37 +376,40 @@ 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; }
|
||||||
|
|
||||||
|
m->cap = SAVE_FLAG_CAP_ON_MR_BLIZZARD;
|
||||||
|
|
||||||
if (does_mario_have_normal_cap_on_head(m)) {
|
m->flags &= ~(MARIO_NORMAL_CAP | MARIO_CAP_ON_HEAD);
|
||||||
m->cap = SAVE_FLAG_CAP_ON_MR_BLIZZARD;
|
|
||||||
|
|
||||||
m->flags &= ~(MARIO_NORMAL_CAP | MARIO_CAP_ON_HEAD);
|
u8 capModel = m->character->capModelId;
|
||||||
|
struct Object *capObject = spawn_object(m->marioObj, capModel, bhvNormalCap);
|
||||||
|
if (capObject == NULL) { return; }
|
||||||
|
capObject->globalPlayerIndex = gNetworkPlayers[m->playerIndex].globalIndex;
|
||||||
|
capObject->oBehParams = m->playerIndex + 1;
|
||||||
|
|
||||||
u8 capModel = m->character->capModelId;
|
capObject->oPosY += (m->action & ACT_FLAG_SHORT_HITBOX) ? 120.0f : 180.0f;
|
||||||
capObject = spawn_object(m->marioObj, capModel, bhvNormalCap);
|
capObject->oForwardVel = capSpeed;
|
||||||
if (capObject == NULL) { return; }
|
capObject->oMoveAngleYaw = (s16)(m->faceAngle[1] + 0x400);
|
||||||
capObject->globalPlayerIndex = gNetworkPlayers[m->playerIndex].globalIndex;
|
|
||||||
capObject->oBehParams = m->playerIndex + 1;
|
|
||||||
|
|
||||||
capObject->oPosY += (m->action & ACT_FLAG_SHORT_HITBOX) ? 120.0f : 180.0f;
|
if (m->forwardVel < 0.0f) {
|
||||||
capObject->oForwardVel = capSpeed;
|
capObject->oMoveAngleYaw = (s16)(capObject->oMoveAngleYaw + 0x8000);
|
||||||
capObject->oMoveAngleYaw = (s16)(m->faceAngle[1] + 0x400);
|
|
||||||
|
|
||||||
if (m->forwardVel < 0.0f) {
|
|
||||||
capObject->oMoveAngleYaw = (s16)(capObject->oMoveAngleYaw + 0x8000);
|
|
||||||
}
|
|
||||||
|
|
||||||
// set as it's own parent so we can spawn it over the network
|
|
||||||
capObject->parentObj = capObject;
|
|
||||||
|
|
||||||
struct Object* spawn_objects[] = { capObject };
|
|
||||||
u32 models[] = { capModel };
|
|
||||||
network_send_spawn_objects(spawn_objects, models, 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// set as it's own parent so we can spawn it over the network
|
||||||
|
capObject->parentObj = capObject;
|
||||||
|
|
||||||
|
struct Object* spawn_objects[] = { capObject };
|
||||||
|
u32 models[] = { capModel };
|
||||||
|
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) {
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
|
||||||
|
|
@ -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) {
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
@ -3049,6 +3053,10 @@ static s32 act_credits_cutscene(struct MarioState *m) {
|
||||||
stop_and_set_height_to_floor(m);
|
stop_and_set_height_to_floor(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) {
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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) },
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue