Fix interactions again (#795)

This commit is contained in:
PeachyPeach 2025-05-08 00:51:44 +02:00 committed by GitHub
parent 441fa36701
commit 0d4fd39a00
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
17 changed files with 210 additions and 81 deletions

View file

@ -2941,7 +2941,6 @@ INT_HIT_FROM_ABOVE = (1 << 6) --- @type Interaction
INT_HIT_FROM_BELOW = (1 << 7) --- @type InteractionFlag
INT_TWIRL = (1 << 8) --- @type InteractionFlag
INT_GROUND_POUND_OR_TWIRL = (INT_GROUND_POUND | INT_TWIRL) --- @type InteractionFlag
INT_LUA = (1 << 31) --- @type InteractionFlag
--- @alias InteractionFlag
--- | `INT_GROUND_POUND`
@ -2954,7 +2953,6 @@ INT_LUA = (1 << 31) --- @type Interaction
--- | `INT_HIT_FROM_BELOW`
--- | `INT_TWIRL`
--- | `INT_GROUND_POUND_OR_TWIRL`
--- | `INT_LUA`
--- @type integer
INT_ATTACK_NOT_FROM_BELOW = (INT_GROUND_POUND_OR_TWIRL | INT_PUNCH | INT_KICK | INT_TRIP | INT_SLIDE_KICK | INT_FAST_ATTACK_OR_SHELL | INT_HIT_FROM_ABOVE)

View file

@ -5197,6 +5197,13 @@ function mario_is_crouching(m)
-- ...
end
--- @param m MarioState
--- @return boolean
--- Returns true if Mario is in a ground pound landing state (`ACT_GROUND_POUND_LAND` or any ground action with `INT_GROUND_POUND` interaction)
function mario_is_ground_pound_landing(m)
-- ...
end
--- @param m MarioState
--- @return boolean
--- Checks whether Mario can become bubbled under certain game conditions (multiplayer bubble mechanic). Returns false if already bubbled or if not allowed by settings
@ -8576,6 +8583,13 @@ function cur_obj_is_mario_ground_pounding_platform()
-- ...
end
--- @param m MarioState
--- @param obj Object
--- @return integer
function obj_is_mario_ground_pounding_platform(m, obj)
-- ...
end
function spawn_mist_particles()
-- ...
end

View file

@ -1408,7 +1408,6 @@
| INT_HIT_FROM_BELOW | (1 << 7) |
| INT_TWIRL | (1 << 8) |
| INT_GROUND_POUND_OR_TWIRL | (INT_GROUND_POUND | INT_TWIRL) |
| INT_LUA | (1 << 31) |
- INT_ATTACK_NOT_FROM_BELOW
- INT_ANY_ATTACK
- INT_ATTACK_NOT_WEAK_FROM_ABOVE

View file

@ -539,6 +539,29 @@ Returns true if Mario is in any of the crouching or crawling states, checking hi
<br />
## [mario_is_ground_pound_landing](#mario_is_ground_pound_landing)
### Description
Returns true if Mario is in a ground pound landing state (`ACT_GROUND_POUND_LAND` or any ground action with `INT_GROUND_POUND` interaction)
### Lua Example
`local booleanValue = mario_is_ground_pound_landing(m)`
### Parameters
| Field | Type |
| ----- | ---- |
| m | [MarioState](structs.md#MarioState) |
### Returns
- `boolean`
### C Prototype
`bool mario_is_ground_pound_landing(struct MarioState *m);`
[:arrow_up_small:](#)
<br />
## [mario_can_bubble](#mario_can_bubble)
### Description

View file

@ -5450,6 +5450,27 @@ Transforms the vector at `localTranslateIndex` into the object's local coordinat
<br />
## [obj_is_mario_ground_pounding_platform](#obj_is_mario_ground_pounding_platform)
### Lua Example
`local integerValue = obj_is_mario_ground_pounding_platform(m, obj)`
### Parameters
| Field | Type |
| ----- | ---- |
| m | [MarioState](structs.md#MarioState) |
| obj | [Object](structs.md#Object) |
### Returns
- `integer`
### C Prototype
`s32 obj_is_mario_ground_pounding_platform(struct MarioState *m, struct Object *obj);`
[:arrow_up_small:](#)
<br />
## [spawn_mist_particles](#spawn_mist_particles)
### Lua Example

View file

@ -998,6 +998,7 @@
- [play_mario_heavy_landing_sound_once](functions-4.md#play_mario_heavy_landing_sound_once)
- [play_mario_sound](functions-4.md#play_mario_sound)
- [mario_is_crouching](functions-4.md#mario_is_crouching)
- [mario_is_ground_pound_landing](functions-4.md#mario_is_ground_pound_landing)
- [mario_can_bubble](functions-4.md#mario_can_bubble)
- [mario_set_bubbled](functions-4.md#mario_set_bubbled)
- [mario_set_forward_vel](functions-4.md#mario_set_forward_vel)
@ -1550,6 +1551,7 @@
- [signum_positive](functions-5.md#signum_positive)
- [cur_obj_wait_then_blink](functions-5.md#cur_obj_wait_then_blink)
- [cur_obj_is_mario_ground_pounding_platform](functions-5.md#cur_obj_is_mario_ground_pounding_platform)
- [obj_is_mario_ground_pounding_platform](functions-5.md#obj_is_mario_ground_pounding_platform)
- [spawn_mist_particles](functions-5.md#spawn_mist_particles)
- [spawn_mist_particles_with_sound](functions-5.md#spawn_mist_particles_with_sound)
- [cur_obj_push_mario_away](functions-5.md#cur_obj_push_mario_away)

View file

@ -135,8 +135,7 @@ void bhv_blue_coin_switch_loop(void) {
case BLUE_COIN_SWITCH_ACT_IDLE:
// If Mario is on the switch and has ground-pounded,
// recede and get ready to start ticking.
if (gMarioObject && gMarioObject->platform == o) {
if ((determine_interaction(&gMarioStates[0], o) & INT_GROUND_POUND) || (gMarioStates[0].action == ACT_GROUND_POUND_LAND)) {
if (obj_is_mario_ground_pounding_platform(&gMarioStates[0], o)) {
// Set to BLUE_COIN_SWITCH_ACT_RECEDING
o->oAction++;
@ -148,7 +147,6 @@ void bhv_blue_coin_switch_loop(void) {
cur_obj_play_sound_2(SOUND_GENERAL_SWITCH_DOOR_OPEN);
network_send_object(o);
}
}
// Have collision
load_object_collision_model();

View file

@ -31,8 +31,7 @@ void bhv_thi_tiny_island_top_loop(void) {
if (!(gTHIWaterDrained & 1)) {
if (o->oAction == 0) {
if (distanceToPlayer < 500.0f)
if (marioState && !(marioState->action & ACT_FLAG_AIR) && ((determine_interaction(marioState, o) & INT_GROUND_POUND) || (marioState->action == ACT_GROUND_POUND_LAND))) {
if (distanceToPlayer < 500.0f && mario_is_ground_pound_landing(marioState)) {
o->oAction++;
cur_obj_spawn_particles(&D_8032F134);
spawn_triangle_break_particles(20, 138, 0.3f, 3);

View file

@ -153,92 +153,117 @@ u32 determine_interaction(struct MarioState *m, struct Object *o) {
interaction = smlua_get_action_interaction_type(m);
// hack: make water punch actually do something
if (interaction == 0 && m->action == ACT_WATER_PUNCH && o->oInteractType & INTERACT_PLAYER) {
// Interaction already set
if (interaction != 0) {
return interaction;
}
// PvP water punch
if (action == ACT_WATER_PUNCH && o->oInteractType & INTERACT_PLAYER) {
f32 cossPitch = coss(m->faceAngle[0]);
Vec3f facing = { sins(m->faceAngle[1])*cossPitch, sins(m->faceAngle[0]), coss(m->faceAngle[1])*cossPitch };
Vec3f dif = { o->oPosX - m->pos[0], (o->oPosY + o->hitboxHeight * 0.5) - (m->pos[1] + m->marioObj->hitboxHeight * 0.5), o->oPosZ - m->pos[2] };
vec3f_normalize(dif);
f32 angle = vec3f_dot(facing, dif);
// Unknown angle (60 degrees in each direction?)
if (angle >= 0.6f) {
interaction = INT_PUNCH;
f32 dot = vec3f_dot(facing, dif);
if (dot >= 0.6f) { // ~53 degrees
return INT_PUNCH;
}
}
if ((interaction == 0 || interaction & INT_LUA) && action & ACT_FLAG_ATTACKING) {
u32 flags = (MARIO_PUNCHING | MARIO_KICKING | MARIO_TRIPPING);
if ((action == ACT_PUNCHING || action == ACT_MOVE_PUNCHING || action == ACT_JUMP_KICK) ||
((m->flags & flags) && (interaction & INT_LUA))) {
// Attacks
if (action & ACT_FLAG_ATTACKING) {
s16 dYawToObject = mario_obj_angle_to_object(m, o) - m->faceAngle[1];
// Punch
if (m->flags & MARIO_PUNCHING) {
// 120 degrees total, or 60 each way
if (-0x2AAA <= dYawToObject && dYawToObject <= 0x2AAA) {
interaction = INT_PUNCH;
return INT_PUNCH;
}
}
// Kick
if (m->flags & MARIO_KICKING) {
// 120 degrees total, or 60 each way
if (-0x2AAA <= dYawToObject && dYawToObject <= 0x2AAA) {
interaction = INT_KICK;
return INT_KICK;
}
}
// Trip
if (m->flags & MARIO_TRIPPING) {
// 180 degrees total, or 90 each way
if (-0x4000 <= dYawToObject && dYawToObject <= 0x4000) {
interaction = INT_TRIP;
}
}
} else if (action == ACT_GROUND_POUND) {
if (m->vel[1] < 0.0f) {
interaction = INT_GROUND_POUND;
}
} else if (action == ACT_TWIRLING) {
if (m->vel[1] < 0.0f) {
interaction = INT_TWIRL;
}
} else if (action == ACT_GROUND_POUND_LAND) {
// Neither ground pounding nor twirling change Mario's vertical speed on landing.,
// so the speed check is nearly always true (perhaps not if you land while going upwards?)
// Additionally, actionState it set on each first thing in their action, so this is
// only true prior to the very first frame (i.e. active 1 frame prior to it run).
if (m->vel[1] < 0.0f && m->actionState == 0) {
interaction = INT_GROUND_POUND;
}
} else if (action == ACT_TWIRL_LAND) {
// Neither ground pounding nor twirling change Mario's vertical speed on landing.,
// so the speed check is nearly always true (perhaps not if you land while going upwards?)
// Additionally, actionState it set on each first thing in their action, so this is
// only true prior to the very first frame (i.e. active 1 frame prior to it run).
if (m->vel[1] < 0.0f && m->actionState == 0) {
interaction = INT_TWIRL;
}
} else if (action == ACT_SLIDE_KICK || action == ACT_SLIDE_KICK_SLIDE) {
interaction = INT_SLIDE_KICK;
} else if (action & ACT_FLAG_RIDING_SHELL) {
interaction = INT_FAST_ATTACK_OR_SHELL;
} else if (m->forwardVel <= -26.0f || 26.0f <= m->forwardVel) {
interaction = INT_FAST_ATTACK_OR_SHELL;
return INT_TRIP;
}
}
// Prior to this, the interaction type could be overwritten. This requires, however,
// that the interaction not be set prior. This specifically overrides turning a ground
// pound into just a bounce.
if (interaction == 0 && (action & ACT_FLAG_AIR)) {
// Ground pound
if (action == ACT_GROUND_POUND) {
if (m->vel[1] < 0.0f) {
return INT_GROUND_POUND;
}
}
// Twirl
if (action == ACT_TWIRLING) {
if (m->vel[1] < 0.0f) {
return INT_TWIRL;
}
}
// Ground pound land
if (action == ACT_GROUND_POUND_LAND) {
// Neither ground pounding nor twirling change Mario's vertical speed on landing.,
// so the speed check is nearly always true (perhaps not if you land while going upwards?)
// Additionally, actionState it set on each first thing in their action, so this is
// only true prior to the very first frame (i.e. active 1 frame prior to it run).
if (m->vel[1] < 0.0f && m->actionState == 0) {
return INT_GROUND_POUND;
}
}
// Twirl land
if (action == ACT_TWIRL_LAND) {
// Neither ground pounding nor twirling change Mario's vertical speed on landing.,
// so the speed check is nearly always true (perhaps not if you land while going upwards?)
// Additionally, actionState it set on each first thing in their action, so this is
// only true prior to the very first frame (i.e. active 1 frame prior to it run).
if (m->vel[1] < 0.0f && m->actionState == 0) {
return INT_TWIRL;
}
}
// Slide kick
if (action == ACT_SLIDE_KICK || action == ACT_SLIDE_KICK_SLIDE) {
return INT_SLIDE_KICK;
}
// Shell riding
if (action & ACT_FLAG_RIDING_SHELL) {
return INT_FAST_ATTACK_OR_SHELL;
}
// Fast attack
if (m->forwardVel <= -26.0f || 26.0f <= m->forwardVel) {
return INT_FAST_ATTACK_OR_SHELL;
}
}
// Air actions
if (action & ACT_FLAG_AIR) {
if (m->vel[1] < 0.0f) {
if (m->pos[1] > o->oPosY) {
interaction = INT_HIT_FROM_ABOVE;
return INT_HIT_FROM_ABOVE;
}
} else {
if (m->pos[1] < o->oPosY) {
interaction = INT_HIT_FROM_BELOW;
return INT_HIT_FROM_BELOW;
}
}
}
return interaction;
return 0;
}
/**
@ -247,7 +272,6 @@ u32 determine_interaction(struct MarioState *m, struct Object *o) {
u32 attack_object(struct MarioState* m, struct Object *o, s32 interaction) {
if (!o) { return 0; }
u32 attackType = 0;
interaction &= ~INT_LUA;
switch (interaction) {
case INT_GROUND_POUND:
@ -1941,7 +1965,7 @@ u32 interact_breakable(struct MarioState *m, UNUSED u32 interactType, struct Obj
m->interactObj = o;
switch (interaction & ~INT_LUA) {
switch (interaction) {
case INT_HIT_FROM_ABOVE:
bounce_off_object(m, o, 30.0f); //! Not in the 0x8F mask
break;

View file

@ -53,7 +53,6 @@ enum InteractionFlag {
INT_HIT_FROM_BELOW = /* 0x00000080 */ (1 << 7),
INT_TWIRL = /* 0x00000100 */ (1 << 8),
INT_GROUND_POUND_OR_TWIRL = (INT_GROUND_POUND | INT_TWIRL),
INT_LUA = /* 0x10000000 */ (1 << 31) ,
};
#define INT_ATTACK_NOT_FROM_BELOW (INT_GROUND_POUND_OR_TWIRL | INT_PUNCH | INT_KICK | INT_TRIP | INT_SLIDE_KICK | INT_FAST_ATTACK_OR_SHELL | INT_HIT_FROM_ABOVE)

View file

@ -412,6 +412,13 @@ bool mario_is_crouching(struct MarioState *m) {
m->action == ACT_CROUCH_SLIDE;
}
bool mario_is_ground_pound_landing(struct MarioState *m) {
if (!m) { return false; }
return m->action == ACT_GROUND_POUND_LAND ||
(!(m->action & ACT_FLAG_AIR) && (determine_interaction(m, m->marioObj) & INT_GROUND_POUND));
}
bool mario_can_bubble(struct MarioState* m) {
if (!m) { return false; }
if (!gServerSettings.bubbleDeath) { return false; }

View file

@ -129,6 +129,11 @@ Returns true if Mario is in any of the crouching or crawling states, checking hi
|descriptionEnd| */
bool mario_is_crouching(struct MarioState *m);
/* |description|
Returns true if Mario is in a ground pound landing state (`ACT_GROUND_POUND_LAND` or any ground action with `INT_GROUND_POUND` interaction)
|descriptionEnd| */
bool mario_is_ground_pound_landing(struct MarioState *m);
/* |description|
Checks whether Mario can become bubbled under certain game conditions (multiplayer bubble mechanic). Returns false if already bubbled or if not allowed by settings
|descriptionEnd| */

View file

@ -2641,18 +2641,20 @@ s32 cur_obj_wait_then_blink(s32 timeUntilBlinking, s32 numBlinks) {
s32 cur_obj_is_mario_ground_pounding_platform(void) {
for (s32 i = 0; i < MAX_PLAYERS; i++) {
if (!is_player_active(&gMarioStates[i])) { continue; }
if (!gMarioStates[i].marioObj) { continue; }
if (gMarioStates[i].marioObj->platform == o) {
u32 interaction = determine_interaction(&gMarioStates[i], o);
if ((gMarioStates[i].action == ACT_GROUND_POUND_LAND) || (interaction & INT_GROUND_POUND && interaction & INT_LUA)) {
if (obj_is_mario_ground_pounding_platform(&gMarioStates[i], o)) {
return TRUE;
}
}
}
return FALSE;
}
s32 obj_is_mario_ground_pounding_platform(struct MarioState *m, struct Object *obj) {
if (!m || !obj || !m->marioObj) { return FALSE; }
if (m->marioObj->platform != obj) { return FALSE; }
return mario_is_ground_pound_landing(m);
}
void spawn_mist_particles(void) {
spawn_mist_particles_variable(0, 0, 46.0f);
}

View file

@ -256,6 +256,7 @@ f32 absf(f32 x);
s32 absi(s32 a0);
s32 cur_obj_wait_then_blink(s32 timeUntilBlinking, s32 numBlinks);
s32 cur_obj_is_mario_ground_pounding_platform(void);
s32 obj_is_mario_ground_pounding_platform(struct MarioState *m, struct Object *obj);
void spawn_mist_particles(void);
void spawn_mist_particles_with_sound(u32 sp18);
void cur_obj_push_mario_away(f32 radius);

View file

@ -1434,7 +1434,6 @@ char gSmluaConstants[] = ""
"INT_HIT_FROM_BELOW=(1 << 7)\n"
"INT_TWIRL=(1 << 8)\n"
"INT_GROUND_POUND_OR_TWIRL=(INT_GROUND_POUND | INT_TWIRL)\n"
"INT_LUA=(1 << 31)\n"
"INT_ATTACK_NOT_FROM_BELOW=(INT_GROUND_POUND_OR_TWIRL | INT_PUNCH | INT_KICK | INT_TRIP | INT_SLIDE_KICK | INT_FAST_ATTACK_OR_SHELL | INT_HIT_FROM_ABOVE)\n"
"INT_ANY_ATTACK=(INT_GROUND_POUND_OR_TWIRL | INT_PUNCH | INT_KICK | INT_TRIP | INT_SLIDE_KICK | INT_FAST_ATTACK_OR_SHELL | INT_HIT_FROM_ABOVE | INT_HIT_FROM_BELOW)\n"
"INT_ATTACK_NOT_WEAK_FROM_ABOVE=(INT_GROUND_POUND_OR_TWIRL | INT_PUNCH | INT_KICK | INT_TRIP | INT_HIT_FROM_BELOW)\n"

View file

@ -15837,6 +15837,23 @@ int smlua_func_mario_is_crouching(lua_State* L) {
return 1;
}
int smlua_func_mario_is_ground_pound_landing(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_is_ground_pound_landing", 1, 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_is_ground_pound_landing"); return 0; }
lua_pushboolean(L, mario_is_ground_pound_landing(m));
return 1;
}
int smlua_func_mario_can_bubble(lua_State* L) {
if (L == NULL) { return 0; }
@ -26059,6 +26076,26 @@ int smlua_func_cur_obj_is_mario_ground_pounding_platform(UNUSED lua_State* L) {
return 1;
}
int smlua_func_obj_is_mario_ground_pounding_platform(lua_State* L) {
if (L == NULL) { return 0; }
int top = lua_gettop(L);
if (top != 2) {
LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "obj_is_mario_ground_pounding_platform", 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, "obj_is_mario_ground_pounding_platform"); return 0; }
struct Object* obj = (struct Object*)smlua_to_cobject(L, 2, LOT_OBJECT);
if (!gSmLuaConvertSuccess) { LOG_LUA("Failed to convert parameter %u for function '%s'", 2, "obj_is_mario_ground_pounding_platform"); return 0; }
extern s32 obj_is_mario_ground_pounding_platform(struct MarioState *m, struct Object *obj);
lua_pushinteger(L, obj_is_mario_ground_pounding_platform(m, obj));
return 1;
}
int smlua_func_spawn_mist_particles(UNUSED lua_State* L) {
if (L == NULL) { return 0; }
@ -34648,6 +34685,7 @@ void smlua_bind_functions_autogen(void) {
smlua_bind_function(L, "play_mario_heavy_landing_sound_once", smlua_func_play_mario_heavy_landing_sound_once);
smlua_bind_function(L, "play_mario_sound", smlua_func_play_mario_sound);
smlua_bind_function(L, "mario_is_crouching", smlua_func_mario_is_crouching);
smlua_bind_function(L, "mario_is_ground_pound_landing", smlua_func_mario_is_ground_pound_landing);
smlua_bind_function(L, "mario_can_bubble", smlua_func_mario_can_bubble);
smlua_bind_function(L, "mario_set_bubbled", smlua_func_mario_set_bubbled);
smlua_bind_function(L, "mario_set_forward_vel", smlua_func_mario_set_forward_vel);
@ -35181,6 +35219,7 @@ void smlua_bind_functions_autogen(void) {
smlua_bind_function(L, "signum_positive", smlua_func_signum_positive);
smlua_bind_function(L, "cur_obj_wait_then_blink", smlua_func_cur_obj_wait_then_blink);
smlua_bind_function(L, "cur_obj_is_mario_ground_pounding_platform", smlua_func_cur_obj_is_mario_ground_pounding_platform);
smlua_bind_function(L, "obj_is_mario_ground_pounding_platform", smlua_func_obj_is_mario_ground_pounding_platform);
smlua_bind_function(L, "spawn_mist_particles", smlua_func_spawn_mist_particles);
smlua_bind_function(L, "spawn_mist_particles_with_sound", smlua_func_spawn_mist_particles_with_sound);
smlua_bind_function(L, "cur_obj_push_mario_away", smlua_func_cur_obj_push_mario_away);

View file

@ -1330,7 +1330,6 @@ int smlua_hook_mario_action(lua_State* L) {
return 0;
}
}
interactionType |= (1 << 31); /* INT_LUA */
struct LuaHookedMarioAction* hooked = &sHookedMarioActions[sHookedMarioActionsCount];