Added HOOK_ALLOW_HAZARD_SURFACE and various fixes (#209)

* Fixed naming from ceil to cell

* Added HOOK_ON_QUICKSAND

* Modified hook and removed weird newlines

* Renamed hook and increased usage

HOOK_ALLOW_QUICKSAND -> HOOK_ALLOW_HAZARD_SURFACE
Now also works on lavaboost.
Suggestion by Agent X. May add this hook to the death barrier check.

* Autogen

* Fixed downwarping to quicksand upon popping

As a side effect though, Mario will no longer snap to the floor upon being popped.
This commit is contained in:
Sunk 2022-10-30 20:25:56 -04:00 committed by GitHub
parent dbff766af0
commit 97090abf28
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 68 additions and 27 deletions

View File

@ -8119,7 +8119,10 @@ HOOK_ON_CHANGE_CAMERA_ANGLE = 24
HOOK_ON_SCREEN_TRANSITION = 25
--- @type LuaHookedEventType
HOOK_MAX = 26
HOOK_ALLOW_HAZARD_SURFACE = 26
--- @type LuaHookedEventType
HOOK_MAX = 27
--- @class HudDisplayFlags

View File

@ -623,7 +623,7 @@
--- @field public yaw integer
--- @class LevelValues
--- @field public ceilHeightLimit integer
--- @field public cellHeightLimit integer
--- @field public coinsRequiredForCoinStar integer
--- @field public entryLevel LevelNum
--- @field public exitCastleArea integer

View File

@ -2875,7 +2875,8 @@
| HOOK_USE_ACT_SELECT | 23 |
| HOOK_ON_CHANGE_CAMERA_ANGLE | 24 |
| HOOK_ON_SCREEN_TRANSITION | 25 |
| HOOK_MAX | 26 |
| HOOK_ALLOW_HAZARD_SURFACE | 26 |
| HOOK_MAX | 27 |
[:arrow_up_small:](#)

View File

@ -918,7 +918,7 @@
| Field | Type | Access |
| ----- | ---- | ------ |
| ceilHeightLimit | `integer` | |
| cellHeightLimit | `integer` | |
| coinsRequiredForCoinStar | `integer` | |
| entryLevel | [enum LevelNum](constants.md#enum-LevelNum) | |
| exitCastleArea | `integer` | |

View File

@ -380,7 +380,7 @@ static struct Surface *find_ceil_from_list(struct SurfaceNode *surfaceNode, s32
// set pheight to highest value
if (gLevelValues.fixCollisionBugs) {
*pheight = gLevelValues.ceilHeightLimit;
*pheight = gLevelValues.cellHeightLimit;
}
// Stay in this loop until out of ceilings.
@ -468,8 +468,8 @@ f32 find_ceil(f32 posX, f32 posY, f32 posZ, struct Surface **pceil) {
s16 cellZ, cellX;
struct Surface *ceil, *dynamicCeil;
struct SurfaceNode *surfaceList;
f32 height = gLevelValues.ceilHeightLimit;
f32 dynamicHeight = gLevelValues.ceilHeightLimit;
f32 height = gLevelValues.cellHeightLimit;
f32 dynamicHeight = gLevelValues.cellHeightLimit;
s16 x, y, z;
//! (Parallel Universes) Because position is casted to an s16, reaching higher

View File

@ -8,7 +8,7 @@
#include "engine/extended_bounds.h"
#define CEIL_HEIGHT_LIMIT 20000
#define CELL_HEIGHT_LIMIT 20000
#define FLOOR_LOWER_LIMIT -11000
#define FLOOR_LOWER_LIMIT_MISC (FLOOR_LOWER_LIMIT + 1000)
// same as FLOOR_LOWER_LIMIT_MISC, explicitly for shadow.c

View File

@ -806,10 +806,10 @@ void set_camera_height(struct Camera *c, f32 goalHeight) {
}
}
approach_camera_height(c, goalHeight, 20.f);
if (camCeilHeight != gLevelValues.ceilHeightLimit) {
if (camCeilHeight != gLevelValues.cellHeightLimit) {
camCeilHeight -= baseOff;
if ((c->pos[1] > camCeilHeight && sMarioGeometry.currFloorHeight + baseOff < camCeilHeight)
|| (sMarioGeometry.currCeilHeight != gLevelValues.ceilHeightLimit
|| (sMarioGeometry.currCeilHeight != gLevelValues.cellHeightLimit
&& sMarioGeometry.currCeilHeight > camCeilHeight && c->pos[1] > camCeilHeight)) {
c->pos[1] = camCeilHeight;
}
@ -1515,7 +1515,7 @@ s32 update_fixed_camera(struct Camera *c, Vec3f focus, UNUSED Vec3f pos) {
}
ceilHeight = find_ceil(c->pos[0], goalHeight - 100.f, c->pos[2], &ceiling);
if (ceilHeight != gLevelValues.ceilHeightLimit) {
if (ceilHeight != gLevelValues.cellHeightLimit) {
if (goalHeight > (ceilHeight -= 125.f)) {
goalHeight = ceilHeight;
}
@ -1614,7 +1614,7 @@ s32 update_boss_fight_camera(struct Camera *c, Vec3f focus, Vec3f pos) {
// When C-Down is not active, this
vec3f_set_dist_and_angle(focus, pos, focusDistance, 0x1000, yaw);
// Find the floor of the arena
pos[1] = find_floor(c->areaCenX, gLevelValues.ceilHeightLimit, c->areaCenZ, &floor);
pos[1] = find_floor(c->areaCenX, gLevelValues.cellHeightLimit, c->areaCenZ, &floor);
if (floor != NULL) {
nx = floor->normal.x;
ny = floor->normal.y;
@ -2351,7 +2351,7 @@ s16 update_default_camera(struct Camera *c) {
if (c->mode == CAMERA_MODE_FREE_ROAM) {
camFloorHeight -= 100.f;
}
ceilHeight = gLevelValues.ceilHeightLimit;
ceilHeight = gLevelValues.cellHeightLimit;
vec3f_copy(c->focus, sMarioCamState->pos);
}
@ -2360,7 +2360,7 @@ s16 update_default_camera(struct Camera *c) {
if (sMarioCamState->pos[1] - 100.f > camFloorHeight) {
camFloorHeight = sMarioCamState->pos[1] - 100.f;
}
ceilHeight = gLevelValues.ceilHeightLimit;
ceilHeight = gLevelValues.cellHeightLimit;
vec3f_copy(c->focus, sMarioCamState->pos);
}
if (camFloorHeight != gLevelValues.floorLowerLimit) {
@ -2385,7 +2385,7 @@ s16 update_default_camera(struct Camera *c) {
vec3f_set_dist_and_angle(c->focus, c->pos, dist, tempPitch, tempYaw);
}
}
if (ceilHeight != gLevelValues.ceilHeightLimit) {
if (ceilHeight != gLevelValues.cellHeightLimit) {
if (c->pos[1] > (ceilHeight -= 150.f)
&& (avoidStatus = is_range_behind_surface(c->pos, sMarioCamState->pos, ceil, 0, -1)) == 1) {
c->pos[1] = ceilHeight;
@ -6826,19 +6826,19 @@ void resolve_geometry_collisions(Vec3f pos, UNUSED Vec3f lastGood) {
floorY = find_floor(pos[0], pos[1] + 50.f, pos[2], &surf);
ceilY = find_ceil(pos[0], pos[1] - 50.f, pos[2], &surf);
if ((gLevelValues.floorLowerLimit != floorY) && (gLevelValues.ceilHeightLimit == ceilY)) {
if ((gLevelValues.floorLowerLimit != floorY) && (gLevelValues.cellHeightLimit == ceilY)) {
if (pos[1] < (floorY += 125.f)) {
pos[1] = floorY;
}
}
if ((gLevelValues.floorLowerLimit == floorY) && (gLevelValues.ceilHeightLimit != ceilY)) {
if ((gLevelValues.floorLowerLimit == floorY) && (gLevelValues.cellHeightLimit != ceilY)) {
if (pos[1] > (ceilY -= 125.f)) {
pos[1] = ceilY;
}
}
if ((gLevelValues.floorLowerLimit != floorY) && (gLevelValues.ceilHeightLimit != ceilY)) {
if ((gLevelValues.floorLowerLimit != floorY) && (gLevelValues.cellHeightLimit != ceilY)) {
floorY += 125.f;
ceilY -= 125.f;
@ -6972,7 +6972,7 @@ void find_mario_floor_and_ceil(struct PlayerGeometry *pg) {
}
if (find_ceil(sMarioCamState->pos[0], sMarioCamState->pos[1] - 10.f,
sMarioCamState->pos[2], &surf) != gLevelValues.ceilHeightLimit) {
sMarioCamState->pos[2], &surf) != gLevelValues.cellHeightLimit) {
pg->currCeilType = surf->type;
} else {
pg->currCeilType = 0;

View File

@ -89,7 +89,7 @@ struct LevelValues gDefaultLevelValues = {
.UnagiStarPos = { 6833.0f, -3654.0f, 2230.0f },
.JetstreamRingStarPos = { 3400.0f, -3200.0f, -500.0f },
},
.ceilHeightLimit = CEIL_HEIGHT_LIMIT,
.cellHeightLimit = CELL_HEIGHT_LIMIT,
.floorLowerLimit = FLOOR_LOWER_LIMIT,
.floorLowerLimitMisc = FLOOR_LOWER_LIMIT_MISC,
.floorLowerLimitShadow = FLOOR_LOWER_LIMIT_SHADOW,

View File

@ -53,7 +53,7 @@ struct LevelValues {
u16 metalCapDurationCotmc;
u16 vanishCapDurationVcutm;
struct StarPositions starPositions;
s16 ceilHeightLimit;
s16 cellHeightLimit;
s16 floorLowerLimit;
s16 floorLowerLimitMisc;
s16 floorLowerLimitShadow;

View File

@ -2261,7 +2261,9 @@ void check_death_barrier(struct MarioState *m) {
}
void check_lava_boost(struct MarioState *m) {
if (m->action == ACT_BUBBLED || (Cheats.enabled && Cheats.godMode)) { return; }
bool allow = true;
smlua_call_event_hooks_mario_param_ret_bool(HOOK_ALLOW_HAZARD_SURFACE, m, &allow);
if (m->action == ACT_BUBBLED || (Cheats.enabled && Cheats.godMode) || (!allow)) { return; }
if (!(m->action & ACT_FLAG_RIDING_SHELL) && m->pos[1] < m->floorHeight + 10.0f) {
if (!(m->flags & MARIO_METAL_CAP)) {
m->hurtCounter += (m->flags & MARIO_CAP_ON_HEAD) ? 12 : 18;

View File

@ -53,7 +53,9 @@ void play_knockback_sound(struct MarioState *m) {
#endif
s32 lava_boost_on_wall(struct MarioState *m) {
if (Cheats.enabled && Cheats.godMode) { return FALSE; }
bool allow = true;
smlua_call_event_hooks_mario_param_ret_bool(HOOK_ALLOW_HAZARD_SURFACE, m, &allow);
if ((Cheats.enabled && Cheats.godMode) || (!allow)) { return FALSE; }
m->faceAngle[1] = atan2s(m->wallNormal[2], m->wallNormal[0]);
if (m->forwardVel < 24.0f) {

View File

@ -1049,7 +1049,8 @@ s32 act_bubbled(struct MarioState* m) {
if (m->playerIndex == 0) {
soft_reset_camera(m->area->camera);
}
return force_idle_state(m);
u8 underWater = (m->pos[1] < ((f32)m->waterLevel));
return set_mario_action(m, underWater ? ACT_WATER_IDLE : ACT_FREEFALL, 0);
}
return FALSE;

View File

@ -109,7 +109,9 @@ void mario_bonk_reflection(struct MarioState *m, u32 negateSpeed) {
}
u32 mario_update_quicksand(struct MarioState *m, f32 sinkingSpeed) {
if (m->action & ACT_FLAG_RIDING_SHELL || (Cheats.enabled && Cheats.godMode)) {
bool allow = true;
smlua_call_event_hooks_mario_param_ret_bool(HOOK_ALLOW_HAZARD_SURFACE, m, &allow);
if (m->action & ACT_FLAG_RIDING_SHELL || (Cheats.enabled && Cheats.godMode) || (!allow)) {
m->quicksandDepth = 0.0f;
} else {
if (m->quicksandDepth < 1.1f) {

View File

@ -728,7 +728,7 @@ static struct LuaObjectField sLakituStateFields[LUA_LAKITU_STATE_FIELD_COUNT] =
#define LUA_LEVEL_VALUES_FIELD_COUNT 20
static struct LuaObjectField sLevelValuesFields[LUA_LEVEL_VALUES_FIELD_COUNT] = {
{ "ceilHeightLimit", LVT_S16, offsetof(struct LevelValues, ceilHeightLimit), false, LOT_NONE },
{ "cellHeightLimit", LVT_S16, offsetof(struct LevelValues, cellHeightLimit), false, LOT_NONE },
{ "coinsRequiredForCoinStar", LVT_S16, offsetof(struct LevelValues, coinsRequiredForCoinStar), false, LOT_NONE },
{ "entryLevel", LVT_S32, offsetof(struct LevelValues, entryLevel), false, LOT_NONE },
{ "exitCastleArea", LVT_S16, offsetof(struct LevelValues, exitCastleArea), false, LOT_NONE },

View File

@ -2882,7 +2882,8 @@ char gSmluaConstants[] = ""
"HOOK_USE_ACT_SELECT = 23\n"
"HOOK_ON_CHANGE_CAMERA_ANGLE = 24\n"
"HOOK_ON_SCREEN_TRANSITION = 25\n"
"HOOK_MAX = 26\n"
"HOOK_ALLOW_HAZARD_SURFACE = 26\n"
"HOOK_MAX = 27\n"
"ACTION_HOOK_EVERY_FRAME = 0\n"
"ACTION_HOOK_GRAVITY = 1\n"
"ACTION_HOOK_MAX = 2\n"

View File

@ -424,6 +424,32 @@ bool smlua_call_event_hooks_ret_int(enum LuaHookedEventType hookType, s32* retur
return false;
}
void smlua_call_event_hooks_ret_bool(enum LuaHookedEventType hookType, bool* returnValue) {
lua_State* L = gLuaState;
if (L == NULL) { return; }
*returnValue = true;
struct LuaHookedEvent* hook = &sHookedEvents[hookType];
for (int i = 0; i < hook->count; i++) {
s32 prevTop = lua_gettop(L);
// push the callback onto the stack
lua_rawgeti(L, LUA_REGISTRYINDEX, hook->reference[i]);
// call the callback
if (0 != smlua_call_hook(L, 0, 1, 0, hook->mod[i])) {
LOG_LUA("Failed to call the callback: %u", hookType);
continue;
}
// output the return value
if (lua_type(L, -1) == LUA_TBOOLEAN && *returnValue) {
*returnValue = smlua_to_boolean(L, -1);
}
lua_settop(L, prevTop);
}
}
void smlua_call_event_hooks_network_player_param(enum LuaHookedEventType hookType, struct NetworkPlayer* np) {
lua_State* L = gLuaState;
if (L == NULL) { return; }

View File

@ -37,6 +37,7 @@ enum LuaHookedEventType {
HOOK_USE_ACT_SELECT,
HOOK_ON_CHANGE_CAMERA_ANGLE,
HOOK_ON_SCREEN_TRANSITION,
HOOK_ALLOW_HAZARD_SURFACE,
HOOK_MAX,
};
@ -67,6 +68,7 @@ static const char* LuaHookedEventTypeName[] = {
"HOOK_USE_ACT_SELECT",
"HOOK_ON_CHANGE_CAMERA_ANGLE",
"HOOK_ON_SCREEN_TRANSITION",
"HOOK_ALLOW_HAZARD_SURFACE",
"HOOK_MAX"
};
@ -101,6 +103,7 @@ void smlua_call_event_hooks_set_camera_mode_params(enum LuaHookedEventType hookT
void smlua_call_event_hooks_int_params_ret_bool(enum LuaHookedEventType hookType, s16 param, bool* returnValue);
void smlua_call_event_hooks_value_param(enum LuaHookedEventType hookType, int modIndex, int valueIndex);
void smlua_call_event_hooks_use_act_select(enum LuaHookedEventType hookType, int value, bool* foundHook, bool* returnValue);
void smlua_call_event_hooks_ret_bool(enum LuaHookedEventType hookType, bool* returnValue);
enum BehaviorId smlua_get_original_behavior_id(const BehaviorScript* behavior);
const BehaviorScript* smlua_override_behavior(const BehaviorScript* behavior);