210 lines
7.1 KiB
Lua
210 lines
7.1 KiB
Lua
|
if unsupported then return end
|
||
|
|
||
|
E_MODEL_FLOOD = smlua_model_util_get_id("flood_geo")
|
||
|
E_MODEL_CTT = smlua_model_util_get_id("ctt_geo") -- easter egg in the distance
|
||
|
E_MODEL_LAUNCHPAD = smlua_model_util_get_id("launchpad_geo")
|
||
|
|
||
|
local COL_LAUNCHPAD = smlua_collision_util_get("launchpad_collision")
|
||
|
|
||
|
-- localize functions to improve performance
|
||
|
local get_environment_region,set_environment_region,set_override_far,cur_obj_scale,cur_obj_init_animation,bhv_pole_base_loop,nearest_mario_state_to_object,play_mario_jump_sound,set_mario_action,spawn_non_sync_object,mario_set_forward_vel,vec3f_set,load_object_collision_model,obj_mark_for_deletion,network_is_server,obj_check_hitbox_overlap,obj_has_behavior_id = get_environment_region,set_environment_region,set_override_far,cur_obj_scale,cur_obj_init_animation,bhv_pole_base_loop,nearest_mario_state_to_object,play_mario_jump_sound,set_mario_action,spawn_non_sync_object,mario_set_forward_vel,vec3f_set,load_object_collision_model,obj_mark_for_deletion,network_is_server,obj_check_hitbox_overlap,obj_has_behavior_id
|
||
|
|
||
|
--- @param o Object
|
||
|
local function bhv_water_init(o)
|
||
|
o.oFlags = OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE
|
||
|
o.oAnimState = gLevels[gGlobalSyncTable.level].type
|
||
|
|
||
|
o.header.gfx.skipInViewCheck = true
|
||
|
|
||
|
o.oFaceAnglePitch = 0
|
||
|
o.oFaceAngleRoll = 0
|
||
|
end
|
||
|
|
||
|
--- @param o Object
|
||
|
local function bhv_water_loop(o)
|
||
|
o.oPosY = gGlobalSyncTable.waterLevel
|
||
|
|
||
|
if game == GAME_VANILLA and gGlobalSyncTable.level ~= LEVEL_SSL then
|
||
|
o.oFaceAngleYaw = o.oTimer * 5 * (gLevels[gNetworkPlayers[0].currLevelNum].speed or 1)
|
||
|
end
|
||
|
|
||
|
if game == GAME_VANILLA and gNetworkPlayers[0].currLevelNum ~= LEVEL_WDW and gNetworkPlayers[0].currLevelNum ~= LEVEL_HMC then
|
||
|
for i = 1, 3 do
|
||
|
if get_environment_region(i) < gGlobalSyncTable.waterLevel then
|
||
|
set_environment_region(i, -20000)
|
||
|
end
|
||
|
end
|
||
|
else
|
||
|
set_environment_region(1, -20000)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
id_bhvWater = hook_behavior(nil, OBJ_LIST_SURFACE, true, bhv_water_init, bhv_water_loop)
|
||
|
|
||
|
|
||
|
--- @param o Object
|
||
|
local function bhv_custom_static_object_init(o)
|
||
|
o.oFlags = OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE
|
||
|
o.header.gfx.skipInViewCheck = true
|
||
|
set_override_far(50000)
|
||
|
end
|
||
|
|
||
|
id_bhvCustomStaticObject = hook_behavior(nil, OBJ_LIST_LEVEL, true, bhv_custom_static_object_init, nil)
|
||
|
|
||
|
|
||
|
--- @param o Object
|
||
|
local function bhv_final_star_init(o)
|
||
|
o.oFlags = OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE
|
||
|
o.hitboxRadius = 160
|
||
|
o.hitboxHeight = 100
|
||
|
|
||
|
cur_obj_scale(2)
|
||
|
end
|
||
|
|
||
|
--- @param o Object
|
||
|
local function bhv_final_star_loop(o)
|
||
|
o.oFaceAngleYaw = o.oFaceAngleYaw + 0x800
|
||
|
end
|
||
|
|
||
|
id_bhvFinalStar = hook_behavior(nil, OBJ_LIST_GENACTOR, true, bhv_final_star_init, bhv_final_star_loop)
|
||
|
|
||
|
|
||
|
--- @param o Object
|
||
|
local function bhv_flood_flag_init(o)
|
||
|
o.oFlags = OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE
|
||
|
o.oInteractType = INTERACT_POLE
|
||
|
o.hitboxRadius = 80
|
||
|
o.hitboxHeight = 700
|
||
|
o.oIntangibleTimer = 0
|
||
|
o.oAnimations = gObjectAnimations.koopa_flag_seg6_anims_06001028
|
||
|
|
||
|
cur_obj_init_animation(0)
|
||
|
end
|
||
|
|
||
|
--- @param o Object
|
||
|
local function bhv_flood_flag_loop(o)
|
||
|
bhv_pole_base_loop()
|
||
|
end
|
||
|
|
||
|
id_bhvFloodFlag = hook_behavior(nil, OBJ_LIST_POLELIKE, true, bhv_flood_flag_init, bhv_flood_flag_loop)
|
||
|
|
||
|
|
||
|
local function bhv_launchpad_init(o)
|
||
|
o.oFlags = OBJ_FLAG_UPDATE_GFX_POS_AND_ANGLE
|
||
|
o.oCollisionDistance = 500
|
||
|
o.collisionData = COL_LAUNCHPAD
|
||
|
obj_scale(o, 0.85)
|
||
|
end
|
||
|
|
||
|
local function bhv_launchpad_loop(o)
|
||
|
local m = nearest_mario_state_to_object(o)
|
||
|
if m.marioObj.platform == o then
|
||
|
play_mario_jump_sound(m)
|
||
|
if o.oBehParams2ndByte ~= 255 then
|
||
|
set_mario_action(m, ACT_TWIRLING, 0)
|
||
|
m.vel.y = o.oBehParams2ndByte
|
||
|
else
|
||
|
spawn_non_sync_object(
|
||
|
id_bhvWingCap,
|
||
|
E_MODEL_NONE,
|
||
|
m.pos.x + m.vel.x, m.pos.y + m.vel.y, m.pos.z + m.vel.z,
|
||
|
nil
|
||
|
)
|
||
|
set_mario_action(m, ACT_FLYING_TRIPLE_JUMP, 0)
|
||
|
mario_set_forward_vel(m, 100)
|
||
|
vec3f_set(m.angleVel, 0, 0, 0)
|
||
|
vec3f_set(m.faceAngle, 0, 0x4500, 0)
|
||
|
m.vel.y = 55
|
||
|
end
|
||
|
end
|
||
|
load_object_collision_model()
|
||
|
end
|
||
|
|
||
|
id_bhvLaunchpad = hook_behavior(nil, OBJ_LIST_SURFACE, true, bhv_launchpad_init, bhv_launchpad_loop)
|
||
|
|
||
|
|
||
|
--- @param o Object
|
||
|
local function obj_hide(o)
|
||
|
o.header.gfx.node.flags = o.header.gfx.node.flags | GRAPH_RENDER_INVISIBLE
|
||
|
end
|
||
|
|
||
|
--- @param o Object
|
||
|
local function obj_mark_for_deletion_on_sync(o)
|
||
|
if gNetworkPlayers[0].currAreaSyncValid then obj_mark_for_deletion(o) end
|
||
|
end
|
||
|
|
||
|
hook_behavior(id_bhvStar, OBJ_LIST_UNIMPORTANT, true, obj_hide, obj_mark_for_deletion_on_sync)
|
||
|
hook_behavior(id_bhvHoot, OBJ_LIST_UNIMPORTANT, true, obj_hide, obj_mark_for_deletion_on_sync)
|
||
|
hook_behavior(id_bhvWarpPipe, OBJ_LIST_UNIMPORTANT, true, obj_hide, obj_mark_for_deletion_on_sync)
|
||
|
hook_behavior(id_bhvFadingWarp, OBJ_LIST_UNIMPORTANT, true, obj_hide, obj_mark_for_deletion_on_sync)
|
||
|
hook_behavior(id_bhvBalconyBigBoo, OBJ_LIST_UNIMPORTANT, true, obj_hide, obj_mark_for_deletion_on_sync)
|
||
|
hook_behavior(id_bhvExclamationBox, OBJ_LIST_UNIMPORTANT, true, obj_hide, obj_mark_for_deletion_on_sync)
|
||
|
hook_behavior(id_bhvWaterLevelDiamond, OBJ_LIST_UNIMPORTANT, true, obj_hide, obj_mark_for_deletion_on_sync)
|
||
|
hook_behavior(id_bhvKoopaRaceEndpoint, OBJ_LIST_UNIMPORTANT, true, obj_hide, obj_mark_for_deletion_on_sync)
|
||
|
|
||
|
--- @param m MarioState
|
||
|
local function before_phys_step(m)
|
||
|
if m.playerIndex ~= 0 then return end
|
||
|
|
||
|
if m.pos.y + 40 < gGlobalSyncTable.waterLevel and gNetworkPlayers[m.playerIndex].currLevelNum == gGlobalSyncTable.level then
|
||
|
m.vel.y = m.vel.y + 2
|
||
|
m.peakHeight = m.pos.y
|
||
|
end
|
||
|
end
|
||
|
|
||
|
--- @param m MarioState
|
||
|
--- @param o Object
|
||
|
local function allow_interact(m, o)
|
||
|
if m.action == ACT_SPECTATOR or
|
||
|
(o.header.gfx.node.flags & GRAPH_RENDER_ACTIVE) == 0 or
|
||
|
o.oInteractType == INTERACT_WARP_DOOR or
|
||
|
o.oInteractType == INTERACT_WARP then
|
||
|
return false
|
||
|
end
|
||
|
|
||
|
return true
|
||
|
end
|
||
|
|
||
|
local function on_death()
|
||
|
local m = gMarioStates[0]
|
||
|
if m.floor.type == SURFACE_DEATH_PLANE or m.floor.type == SURFACE_VERTICAL_WIND then
|
||
|
m.health = 0xff
|
||
|
end
|
||
|
return false
|
||
|
end
|
||
|
|
||
|
local function on_pause_exit()
|
||
|
if network_is_server() then
|
||
|
network_send(true, { restart = true })
|
||
|
level_restart()
|
||
|
end
|
||
|
return false
|
||
|
end
|
||
|
|
||
|
--- @param m MarioState
|
||
|
local function allow_hazard_surface(m)
|
||
|
if m.health <= 0xff then return false end
|
||
|
return true
|
||
|
end
|
||
|
|
||
|
-- thanks Peachy
|
||
|
--- @param o Object
|
||
|
local function on_object_unload(o)
|
||
|
local m = gMarioStates[0]
|
||
|
if (o.header.gfx.node.flags & GRAPH_RENDER_INVISIBLE) == 0 and obj_has_behavior_id(o, id_bhv1Up) == 1 and obj_check_hitbox_overlap(o, m.marioObj) then
|
||
|
m.healCounter = 31
|
||
|
m.hurtCounter = 0
|
||
|
end
|
||
|
end
|
||
|
|
||
|
local function on_packet_receive(dataTable)
|
||
|
if dataTable.restart then level_restart() end
|
||
|
end
|
||
|
|
||
|
hook_event(HOOK_BEFORE_PHYS_STEP, before_phys_step)
|
||
|
hook_event(HOOK_ALLOW_INTERACT, allow_interact)
|
||
|
hook_event(HOOK_ON_DEATH, on_death)
|
||
|
hook_event(HOOK_ON_PAUSE_EXIT, on_pause_exit)
|
||
|
hook_event(HOOK_ALLOW_HAZARD_SURFACE, allow_hazard_surface)
|
||
|
hook_event(HOOK_ON_OBJECT_UNLOAD, on_object_unload)
|
||
|
hook_event(HOOK_ON_PACKET_RECEIVE, on_packet_receive)
|