This commit is contained in:
Cooliokid956 2026-07-03 02:04:51 -05:00 committed by GitHub
commit 0ef1a425b5
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 52 additions and 63 deletions

View file

@ -5663,8 +5663,9 @@ function mario_can_bubble(m)
end
--- @param m MarioState
--- Transitions Mario into a bubbled state (if available in multiplayer), decrementing lives and preventing normal movement
function mario_set_bubbled(m)
--- @param stayAlive? boolean
--- Transitions Mario into a bubbled state (if available in multiplayer), decrementing lives by default and preventing normal movement
function mario_set_bubbled(m, stayAlive)
-- ...
end

View file

@ -1228,21 +1228,22 @@ Checks whether Mario can become bubbled under certain game conditions (multiplay
## [mario_set_bubbled](#mario_set_bubbled)
### Description
Transitions Mario into a bubbled state (if available in multiplayer), decrementing lives and preventing normal movement
Transitions Mario into a bubbled state (if available in multiplayer), decrementing lives by default and preventing normal movement
### Lua Example
`mario_set_bubbled(m)`
`mario_set_bubbled(m, stayAlive)`
### Parameters
| Field | Type |
| ----- | ---- |
| m | [MarioState](structs.md#MarioState) |
| stayAlive | `boolean` |
### Returns
- None
### C Prototype
`void mario_set_bubbled(struct MarioState* m);`
`void mario_set_bubbled(struct MarioState* m, OPTIONAL bool stayAlive);`
[:arrow_up_small:](#)

View file

@ -2455,7 +2455,7 @@ void check_death_barrier(struct MarioState *m) {
break;
}
default:
mario_set_bubbled(m);
mario_set_bubbled(m, false);
return;
}
}

View file

@ -449,7 +449,7 @@ void init_mario_after_warp(void) {
// enforce bubble on area change
if (gServerSettings.bubbleDeath) {
if (i == 0 && gMarioStates[i].numLives == -1) {
mario_set_bubbled(&gMarioStates[i]);
mario_set_bubbled(&gMarioStates[i], false);
gMarioStates[i].health = 0xFF;
}
}

View file

@ -47,10 +47,6 @@
#define MAX_HANG_PREVENTION 64
u32 unused80339F10;
s8 filler80339F1C[20];
u16 gLocalBubbleCounter = 0;
/**************************************************
* ANIMATIONS *
@ -426,32 +422,30 @@ bool mario_can_bubble(struct MarioState* m) {
if (m->action == ACT_BUBBLED) { return false; }
if (!m->visibleToObjects) { return false; }
u8 allInBubble = TRUE;
for (s32 i = 1; i < MAX_PLAYERS; i++) {
if (!is_player_active(&gMarioStates[i])) { continue; }
if (!gMarioStates[i].visibleToObjects) { continue; }
if (gMarioStates[i].action != ACT_BUBBLED && gMarioStates[i].health >= 0x100) {
allInBubble = FALSE;
break;
return true;
}
}
if (allInBubble) { return false; }
return true;
return false;
}
void mario_set_bubbled(struct MarioState* m) {
void mario_set_bubbled(struct MarioState* m, OPTIONAL bool stayAlive) {
if (!m) { return; }
if (m->playerIndex != 0) { return; }
if (m->action == ACT_BUBBLED) { return; }
gLocalBubbleCounter = 20;
drop_and_set_mario_action(m, ACT_BUBBLED, 0);
if (m->numLives > 0) {
m->numLives--;
drop_and_set_mario_action(m, ACT_BUBBLED, stayAlive);
if (!stayAlive) {
if (m->numLives > 0) {
m->numLives--;
}
m->healCounter = 0;
m->hurtCounter = 31;
}
m->healCounter = 0;
m->hurtCounter = 31;
gCamera->cutscene = 0;
m->statusForCamera->action = m->action;
m->statusForCamera->cameraEvent = 0;
@ -2193,7 +2187,6 @@ void init_single_mario(struct MarioState* m) {
u16 playerIndex = m->playerIndex;
struct SpawnInfo* spawnInfo = &gPlayerSpawnInfos[playerIndex];
unused80339F10 = 0;
m->freeze = 0;

View file

@ -6,7 +6,6 @@
#include "macros.h"
#include "types.h"
extern u16 gLocalBubbleCounter;
struct WallCollisionData;
/* |description|
@ -140,9 +139,9 @@ Checks whether Mario can become bubbled under certain game conditions (multiplay
bool mario_can_bubble(struct MarioState* m);
/* |description|
Transitions Mario into a bubbled state (if available in multiplayer), decrementing lives and preventing normal movement
Transitions Mario into a bubbled state (if available in multiplayer), decrementing lives by default and preventing normal movement
|descriptionEnd| */
void mario_set_bubbled(struct MarioState* m);
void mario_set_bubbled(struct MarioState* m, OPTIONAL bool stayAlive);
/* |description|
Sets Mario's forward velocity (`m.forwardVel`) and updates `slideVelX/Z` and `m.vel` accordingly, based on `m.faceAngle.y`.

View file

@ -1741,7 +1741,7 @@ s32 act_lava_boost(struct MarioState *m) {
if ((mario_can_bubble(m) && m->numLives > 0)) {
m->health = 0xFF;
mario_set_bubbled(m);
mario_set_bubbled(m, false);
} else {
level_trigger_warp(m, WARP_OP_DEATH);
}

View file

@ -1032,9 +1032,11 @@ Makes Mario act like he was popped from a bubble. Useful for custom bubble poppi
void mario_pop_bubble(struct MarioState* m) {
if (!m) { return; }
m->marioObj->activeFlags &= ~ACTIVE_FLAG_MOVE_THROUGH_GRATE;
m->hurtCounter = 0;
m->healCounter = 31;
m->health = 0x100;
if (!m->actionArg) {
m->hurtCounter = 0;
m->healCounter = 31;
m->health = 0x100;
}
m->marioObj->oIntangibleTimer = 0;
m->peakHeight = m->pos[1];
mario_set_forward_vel(m, 0.0f);
@ -1064,21 +1066,22 @@ s32 act_bubbled(struct MarioState* m) {
s32 pitchToPlayer = obj_pitch_to_object(m->marioObj, target);
s32 distanceToPlayer = dist_between_objects(m->marioObj, target);
// trigger warp if all are bubbled
// trigger warp if all are bubbled long enough
if (m->playerIndex == 0) {
u8 allInBubble = TRUE;
for (s32 i = 0; i < MAX_PLAYERS; i++) {
if (!is_player_active(&gMarioStates[i])) { continue; }
if (!gMarioStates[i].visibleToObjects) { continue; }
if (gMarioStates[i].action != ACT_BUBBLED && gMarioStates[i].health >= 0x100) {
if (gMarioStates[i].action != ACT_BUBBLED) {
allInBubble = FALSE;
break;
}
}
if (allInBubble) {
level_trigger_warp(m, WARP_OP_DEATH);
return set_mario_action(m, ACT_SOFT_BONK, 0);
}
if (m->actionState++ == 60) {
level_trigger_warp(m, WARP_OP_EXIT);
}
} else { m->actionState = 0; }
}
// create bubble
@ -1144,21 +1147,8 @@ s32 act_bubbled(struct MarioState* m) {
// offset the player model to be in the center of the bubble
bubbled_offset_visual(m);
// make invisible on -1 lives
if (m->playerIndex == 0) {
if (m->numLives <= -1) {
m->marioObj->header.gfx.node.flags |= GRAPH_RENDER_INVISIBLE;
level_trigger_warp(m, WARP_OP_DEATH);
return set_mario_action(m, ACT_SOFT_BONK, 0);
} else {
m->marioObj->header.gfx.node.flags &= ~GRAPH_RENDER_INVISIBLE;
}
}
if (gLocalBubbleCounter > 0) { gLocalBubbleCounter--; }
// pop bubble
if (m->playerIndex == 0 && distanceToPlayer < 120 && is_player_active(targetMarioState) && m->numLives != -1 && gLocalBubbleCounter == 0) {
if (m->playerIndex == 0 && ++m->actionTimer > 20 && distanceToPlayer < 120 && is_player_active(targetMarioState)) {
mario_pop_bubble(m);
return TRUE;
}

View file

@ -843,7 +843,7 @@ s32 common_death_handler(struct MarioState *m, s32 animation, s32 frameToDeathWa
if (!allowDeath) { return animFrame; }
if ((mario_can_bubble(m) && m->numLives > 0)) {
mario_set_bubbled(m);
mario_set_bubbled(m, false);
} else {
level_trigger_warp(m, WARP_OP_DEATH);
}
@ -916,7 +916,7 @@ s32 act_quicksand_death(struct MarioState *m) {
smlua_call_event_hooks(HOOK_ON_DEATH, m, &allowDeath);
if (!allowDeath) { return FALSE; }
if ((mario_can_bubble(m) && m->numLives > 0)) {
mario_set_bubbled(m);
mario_set_bubbled(m, false);
} else {
level_trigger_warp(m, WARP_OP_DEATH);
}
@ -941,7 +941,7 @@ s32 act_eaten_by_bubba(struct MarioState *m) {
if ((mario_can_bubble(m) && m->numLives > 0)) {
m->health = 0xFF;
mario_set_bubbled(m);
mario_set_bubbled(m, false);
} else {
level_trigger_warp(m, WARP_OP_DEATH);
}
@ -1832,7 +1832,7 @@ s32 act_squished(struct MarioState *m) {
if (!allowDeath) { return FALSE; }
if ((mario_can_bubble(m) && m->numLives > 0)) {
mario_set_bubbled(m);
mario_set_bubbled(m, false);
} else {
level_trigger_warp(m, WARP_OP_DEATH);
// woosh, he's gone!
@ -1883,7 +1883,7 @@ s32 act_squished(struct MarioState *m) {
if (!allowDeath) { return FALSE; }
if ((mario_can_bubble(m) && m->numLives > 0)) {
mario_set_bubbled(m);
mario_set_bubbled(m, false);
} else {
// 0 units of health
m->health = 0x00FF;

View file

@ -1004,7 +1004,7 @@ static s32 act_drowning(struct MarioState *m) {
if (!allowDeath) { return FALSE; }
if ((mario_can_bubble(m) && m->numLives > 0)) {
mario_set_bubbled(m);
mario_set_bubbled(m, false);
} else {
level_trigger_warp(m, WARP_OP_DEATH);
}
@ -1039,7 +1039,7 @@ static s32 act_water_death(struct MarioState *m) {
if (!allowDeath) { return FALSE; }
if ((mario_can_bubble(m) && m->numLives > 0)) {
mario_set_bubbled(m);
mario_set_bubbled(m, false);
} else {
level_trigger_warp(m, WARP_OP_DEATH);
}
@ -1165,7 +1165,7 @@ static s32 act_caught_in_whirlpool(struct MarioState *m) {
if (!allowDeath) { reset_rumble_timers(m); return FALSE; }
if ((mario_can_bubble(m) && m->numLives > 0)) {
mario_set_bubbled(m);
mario_set_bubbled(m, false);
} else {
level_trigger_warp(m, WARP_OP_DEATH);
}

View file

@ -16536,15 +16536,20 @@ int smlua_func_mario_set_bubbled(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", "mario_set_bubbled", 1, top);
if (top < 1 || top > 2) {
LOG_LUA_LINE("Improper param count for '%s': Expected between %u and %u, Received %u", "mario_set_bubbled", 1, 2, top);
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, "mario_set_bubbled"); return 0; }
bool stayAlive = (bool) 0;
if (top >= 2) {
stayAlive = smlua_to_boolean(L, 2);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "mario_set_bubbled"); return 0; }
}
mario_set_bubbled(m);
mario_set_bubbled(m, stayAlive);
return 1;
}

View file

@ -398,7 +398,7 @@ void network_receive_player(struct Packet* p) {
}
// inform of player death
if (oldData.action != ACT_BUBBLED && data.action == ACT_BUBBLED) {
if (oldData.action != ACT_BUBBLED && data.action == ACT_BUBBLED && !data.actionArg) {
construct_player_popup(np, DLANG(NOTIF, DIED), NULL);
}