mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2024-11-22 03:55:11 +00:00
Make default mods a little smaller by removing Flood
This commit is contained in:
parent
5fb6757382
commit
52fab98176
14 changed files with 0 additions and 1283 deletions
|
@ -1,102 +0,0 @@
|
|||
unsupported = false
|
||||
|
||||
FLOOD_WATER = 0
|
||||
FLOOD_LAVA = 1
|
||||
FLOOD_SAND = 2
|
||||
FLOOD_MUD = 3
|
||||
|
||||
FLOOD_BONUS_LEVELS = 0
|
||||
FLOOD_LEVEL_COUNT = 0
|
||||
|
||||
LEVEL_LOBBY = LEVEL_CASTLE_GROUNDS
|
||||
LEVEL_CTT = LEVEL_SA
|
||||
|
||||
GAME_VANILLA = 0
|
||||
GAME_STAR_ROAD = 1
|
||||
|
||||
game = GAME_VANILLA
|
||||
|
||||
--- @class FloodLevel
|
||||
--- @field public name string
|
||||
--- @field public goalPos Vec3f
|
||||
--- @field public speed number
|
||||
--- @field public area integer
|
||||
--- @field public type integer
|
||||
--- @field public time integer
|
||||
--- @field public customStartPos Vec3f
|
||||
|
||||
--- @type FloodLevel[]
|
||||
gLevels = {}
|
||||
gMapRotation = {}
|
||||
|
||||
-- localize functions to improve performance
|
||||
local table_insert,djui_popup_create = table.insert,djui_popup_create
|
||||
|
||||
local function flood_define_level(bonus, level, name, goalPos, speed, area, type, customStartPos)
|
||||
gLevels[level] = { name = name, goalPos = goalPos, speed = speed, area = area, type = type, time = 0, customStartPos = customStartPos }
|
||||
table_insert(gMapRotation, level)
|
||||
|
||||
if bonus then FLOOD_BONUS_LEVELS = FLOOD_BONUS_LEVELS + 1 end
|
||||
FLOOD_LEVEL_COUNT = FLOOD_LEVEL_COUNT + 1
|
||||
end
|
||||
_G.flood_define_level = flood_define_level
|
||||
|
||||
local function flood_load_vanilla_levels()
|
||||
game = GAME_VANILLA
|
||||
|
||||
-- bonus level name goal position speed area type custom start pos
|
||||
flood_define_level(false, LEVEL_BOB, "bob", { x = 3304, y = 4242, z = -4603, a = 0x0000 }, 2.5, 1, FLOOD_WATER, nil)
|
||||
flood_define_level(false, LEVEL_WF, "wf", { x = 414, y = 5325, z = -20, a = 0x0000 }, 4.0, 1, FLOOD_WATER, nil)
|
||||
flood_define_level(false, LEVEL_CCM, "ccm", { x = -478, y = 3471, z = -964, a = 0x0000 }, 5.0, 1, FLOOD_WATER, { x = 3336, y = -3800, z = 0, a = 0x0000 })
|
||||
flood_define_level(false, LEVEL_BITDW, "bitdw", { x = 6772, y = 2867, z = 0, a = -0x4000 }, 4.0, 1, FLOOD_WATER, nil)
|
||||
flood_define_level(false, LEVEL_BBH, "bbh", { x = 655, y = 3277, z = 244, a = 0x8000 }, 3.5, 1, FLOOD_WATER, nil)
|
||||
flood_define_level(false, LEVEL_HMC, "hmc", { x = -4163, y = 2355, z = -2544, a = 0x0000 }, 5.0, 1, FLOOD_WATER, { x = -3538, y = -3979, z = 3568, a = 0x8000 })
|
||||
flood_define_level(false, LEVEL_LLL, "lll", { x = 2523, y = 3591, z = -898, a = -0x8000 }, 3.5, 2, FLOOD_LAVA, nil)
|
||||
flood_define_level(false, LEVEL_SSL, "ssl", { x = 512, y = 4815, z = -551, a = 0x0000 }, 3.0, 2, FLOOD_SAND, nil)
|
||||
flood_define_level(false, LEVEL_WDW, "wdw", { x = 1467, y = 4096, z = 93, a = -0x4000 }, 4.0, 1, FLOOD_WATER, nil)
|
||||
flood_define_level(false, LEVEL_TTM, "ttm", { x = 1053, y = 2309, z = 305, a = 0x0000 }, 3.0, 1, FLOOD_WATER, nil)
|
||||
flood_define_level(false, LEVEL_THI, "thi", { x = 1037, y = 4060, z = -2091, a = 0x0000 }, 4.0, 1, FLOOD_WATER, nil)
|
||||
flood_define_level(false, LEVEL_TTC, "ttc", { x = 2208, y = 7051, z = 2217, a = 0x0000 }, 4.0, 1, FLOOD_WATER, nil)
|
||||
flood_define_level(false, LEVEL_BITS, "bits", { x = 369, y = 6552, z = -6000, a = 0x0000 }, 4.5, 1, FLOOD_LAVA, nil)
|
||||
flood_define_level(false, LEVEL_CTT, "ctt", { x = 0, y = 700, z = 0, a = 0x0000 }, 5.0, 1, FLOOD_LAVA, nil)
|
||||
flood_define_level(true, LEVEL_SL, "sl", { x = 40, y = 4864, z = 240, a = 0x0000 }, 3.0, 1, FLOOD_WATER, nil)
|
||||
flood_define_level(true, LEVEL_RR, "rr", { x = 0, y = 3468, z = -2335, a = 0x0000 }, 3.0, 1, FLOOD_WATER, nil)
|
||||
flood_define_level(true, LEVEL_CASTLE_GROUNDS, "castle_grounds", { x = 0, y = 7583, z = -4015, a = 0x0000 }, 7.0, 1, FLOOD_WATER, nil)
|
||||
end
|
||||
|
||||
local function flood_load_star_road_levels()
|
||||
game = GAME_STAR_ROAD
|
||||
|
||||
-- bonus level name goal position speed area type custom start pos
|
||||
flood_define_level(false, LEVEL_BOB, "bob", { x = 5364, y = 1875, z = 2251, a = 0x0000 }, 3.0, 1, FLOOD_WATER, nil)
|
||||
flood_define_level(false, LEVEL_WF, "wf", { x = 208, y = 2448, z = -2080, a = 0x4000 }, 5.0, 1, FLOOD_WATER, nil)
|
||||
flood_define_level(false, LEVEL_JRB, "jrb", { x = -4672, y = 3541, z = -3619, a = -0x4000 }, 4.0, 1, FLOOD_WATER, { x = 2316, y = -448, z = -5150, a = 0x0000 })
|
||||
flood_define_level(false, LEVEL_CCM, "ccm", { x = 5709, y = 3501, z = -2141, a = -0x4000 }, 3.0, 1, FLOOD_WATER, nil)
|
||||
flood_define_level(false, LEVEL_PSS, "pss", { x = -3415, y = 4573, z = 2678, a = 0x0000 }, 3.0, 1, FLOOD_WATER, nil)
|
||||
flood_define_level(false, LEVEL_BITDW, "bitdw", { x = 455, y = 2324, z = 0, a = -0x4000 }, 3.0, 1, FLOOD_MUD, nil)
|
||||
flood_define_level(false, LEVEL_BBH, "bbh", { x = 4376, y = 2632, z = -4542, a = 0x0000 }, 3.0, 1, FLOOD_WATER, nil)
|
||||
flood_define_level(false, LEVEL_LLL, "lll", { x = 4348, y = 4638, z = 3877, a = -0x4000 }, 7.0, 1, FLOOD_SAND, nil)
|
||||
flood_define_level(false, LEVEL_SL, "sl", { x = 4543, y = 3709, z = 3311, a = 0x8000 }, 2.5, 1, FLOOD_WATER, nil)
|
||||
flood_define_level(false, LEVEL_WDW, "wdw", { x = -3342, y = 2603, z = 845, a = 0x4000 }, 4.0, 1, FLOOD_WATER, nil)
|
||||
flood_define_level(false, LEVEL_TTM, "ttm", { x = 1033, y = 4813, z = -6320, a = 0x8000 }, 2.0, 1, FLOOD_WATER, nil)
|
||||
flood_define_level(false, LEVEL_TTC, "ttc", { x = 1405, y = 3425, z = -3463, a = 0x8000 }, 4.0, 1, FLOOD_LAVA, nil)
|
||||
flood_define_level(false, LEVEL_RR, "rr", { x = 5052, y = 11056, z = 413, a = -0x4000 }, 4.0, 1, FLOOD_WATER, { x = 3923, y = -3283, z = -1323, a = 0x8000 })
|
||||
flood_define_level(true, LEVEL_CASTLE_GROUNDS, "castle_grounds", { x = -8455, y = 2746, z = 2876, a = 0x8000 }, 15.0, 1, FLOOD_WATER, { x = -1644, y = -614, z = -1524, a = -0x4000 })
|
||||
end
|
||||
|
||||
-- load romhack levels
|
||||
for mod in pairs(gActiveMods) do
|
||||
if gActiveMods[mod].incompatible ~= nil and gActiveMods[mod].incompatible:find("romhack") then
|
||||
if gActiveMods[mod].relativePath == "star-road" then
|
||||
flood_load_star_road_levels()
|
||||
else
|
||||
unsupported = true
|
||||
djui_popup_create("\\#ff0000\\This rom hack is not supported with Flood.", 2)
|
||||
end
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if not unsupported and game == GAME_VANILLA then
|
||||
flood_load_vanilla_levels()
|
||||
end
|
|
@ -1,166 +0,0 @@
|
|||
moveset = false
|
||||
cheats = false
|
||||
|
||||
for mod in pairs(gActiveMods) do
|
||||
if gActiveMods[mod].name:find("Object Spawner") then
|
||||
cheats = true
|
||||
end
|
||||
end
|
||||
|
||||
if gServerSettings.enableCheats ~= 0 then
|
||||
cheats = true
|
||||
end
|
||||
|
||||
for i in pairs(gActiveMods) do
|
||||
if (gActiveMods[i].incompatible ~= nil and gActiveMods[i].incompatible:find("moveset")) or gActiveMods[i].name:find("Squishy's Server") or (gActiveMods[i].name:find("Pasta") and gActiveMods[i].name:find("Castle")) then
|
||||
moveset = true
|
||||
end
|
||||
end
|
||||
|
||||
-- localize functions to improve performance
|
||||
local math_floor,is_player_active,table_insert,is_game_paused,djui_hud_set_color = math.floor,is_player_active,table.insert,is_game_paused,djui_hud_set_color
|
||||
|
||||
rom_hack_cam_set_collisions(false)
|
||||
|
||||
-- Rounds up or down depending on the decimal position of `x`.
|
||||
--- @param x number
|
||||
--- @return integer
|
||||
function math_round(x)
|
||||
return if_then_else(x - math.floor(x) >= 0.5, math.ceil(x), math.floor(x))
|
||||
end
|
||||
|
||||
-- Recieves a value of any type and converts it into a boolean.
|
||||
function tobool(v)
|
||||
local type = type(v)
|
||||
if type == "boolean" then
|
||||
return v
|
||||
elseif type == "number" then
|
||||
return v == 1
|
||||
elseif type == "string" then
|
||||
return v == "true"
|
||||
elseif type == "table" or type == "function" or type == "thread" or type == "userdata" then
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function switch(param, case_table)
|
||||
local case = case_table[param]
|
||||
if case then return case() end
|
||||
local def = case_table['default']
|
||||
return def and def() or nil
|
||||
end
|
||||
|
||||
--- @param m MarioState
|
||||
function active_player(m)
|
||||
local np = gNetworkPlayers[m.playerIndex]
|
||||
if m.playerIndex == 0 then
|
||||
return 1
|
||||
end
|
||||
if not np.connected then
|
||||
return 0
|
||||
end
|
||||
if np.currCourseNum ~= gNetworkPlayers[0].currCourseNum then
|
||||
return 0
|
||||
end
|
||||
if np.currActNum ~= gNetworkPlayers[0].currActNum then
|
||||
return 0
|
||||
end
|
||||
if np.currLevelNum ~= gNetworkPlayers[0].currLevelNum then
|
||||
return 0
|
||||
end
|
||||
if np.currAreaIndex ~= gNetworkPlayers[0].currAreaIndex then
|
||||
return 0
|
||||
end
|
||||
return is_player_active(m)
|
||||
end
|
||||
|
||||
function if_then_else(cond, ifTrue, ifFalse)
|
||||
if cond then return ifTrue end
|
||||
return ifFalse
|
||||
end
|
||||
|
||||
function string_without_hex(name)
|
||||
local s = ''
|
||||
local inSlash = false
|
||||
for i = 1, #name do
|
||||
local c = name:sub(i,i)
|
||||
if c == '\\' then
|
||||
inSlash = not inSlash
|
||||
elseif not inSlash then
|
||||
s = s .. c
|
||||
end
|
||||
end
|
||||
return s
|
||||
end
|
||||
|
||||
function on_or_off(value)
|
||||
if value then return "\\#00ff00\\ON" end
|
||||
return "\\#ff0000\\OFF"
|
||||
end
|
||||
|
||||
function split(s)
|
||||
local result = {}
|
||||
for match in (s):gmatch(string.format("[^%s]+", " ")) do
|
||||
table.insert(result, match)
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
function djui_hud_set_adjusted_color(r, g, b, a)
|
||||
local multiplier = 1
|
||||
if is_game_paused() then multiplier = 0.5 end
|
||||
djui_hud_set_color(r * multiplier, g * multiplier, b * multiplier, a)
|
||||
end
|
||||
|
||||
function SEQUENCE_ARGS(priority, seqId)
|
||||
return ((priority << 8) | seqId)
|
||||
end
|
||||
|
||||
--- @param m MarioState
|
||||
function mario_set_full_health(m)
|
||||
m.health = 0x880
|
||||
m.healCounter = 0
|
||||
m.hurtCounter = 0
|
||||
end
|
||||
|
||||
local levelToCourse = {
|
||||
[LEVEL_NONE] = COURSE_NONE,
|
||||
[LEVEL_BOB] = COURSE_BOB,
|
||||
[LEVEL_WF] = COURSE_WF,
|
||||
[LEVEL_JRB] = COURSE_JRB,
|
||||
[LEVEL_CCM] = COURSE_CCM,
|
||||
[LEVEL_BBH] = COURSE_BBH,
|
||||
[LEVEL_HMC] = COURSE_HMC,
|
||||
[LEVEL_LLL] = COURSE_LLL,
|
||||
[LEVEL_SSL] = COURSE_SSL,
|
||||
[LEVEL_DDD] = COURSE_DDD,
|
||||
[LEVEL_SL] = COURSE_SL,
|
||||
[LEVEL_WDW] = COURSE_WDW,
|
||||
[LEVEL_TTM] = COURSE_TTM,
|
||||
[LEVEL_THI] = COURSE_THI,
|
||||
[LEVEL_TTC] = COURSE_TTC,
|
||||
[LEVEL_RR] = COURSE_RR,
|
||||
[LEVEL_BITDW] = COURSE_BITDW,
|
||||
[LEVEL_BITFS] = COURSE_BITFS,
|
||||
[LEVEL_BITS] = COURSE_BITS,
|
||||
[LEVEL_PSS] = COURSE_PSS,
|
||||
[LEVEL_COTMC] = COURSE_COTMC,
|
||||
[LEVEL_TOTWC] = COURSE_TOTWC,
|
||||
[LEVEL_VCUTM] = COURSE_VCUTM,
|
||||
[LEVEL_WMOTR] = COURSE_WMOTR,
|
||||
[LEVEL_SA] = COURSE_SA,
|
||||
[LEVEL_ENDING] = COURSE_CAKE_END,
|
||||
}
|
||||
|
||||
function level_to_course(level)
|
||||
return levelToCourse[level] or COURSE_NONE
|
||||
end
|
||||
|
||||
function timestamp(seconds)
|
||||
seconds = seconds / 30
|
||||
local minutes = math.floor(seconds / 60)
|
||||
local milliseconds = math.floor((seconds - math.floor(seconds)) * 1000)
|
||||
seconds = math.floor(seconds) % 60
|
||||
return string.format("%d:%02d:%03d", minutes, seconds, milliseconds)
|
||||
end
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,642 +0,0 @@
|
|||
-- name: Flood
|
||||
-- incompatible: gamemode
|
||||
-- description: Flood v2.4.5\nBy \\#ec7731\\Agent X\\#dcdcdc\\\n\nThis mod adds a flood escape gamemode\nto sm64ex-coop, you must escape the flood and reach the top of the level before everything is flooded.
|
||||
|
||||
if unsupported then return end
|
||||
|
||||
local ROUND_STATE_INACTIVE = 0
|
||||
ROUND_STATE_ACTIVE = 1
|
||||
local ROUND_COOLDOWN = 600
|
||||
|
||||
local SPEEDRUN_MODE_OFF = 0
|
||||
local SPEEDRUN_MODE_PROGRESS = 1
|
||||
local SPEEDRUN_MODE_RESTART = 2
|
||||
|
||||
local TEX_FLOOD_FLAG = get_texture_info("flood_flag")
|
||||
|
||||
gGlobalSyncTable.roundState = ROUND_STATE_INACTIVE
|
||||
gGlobalSyncTable.timer = ROUND_COOLDOWN
|
||||
gGlobalSyncTable.level = LEVEL_BOB
|
||||
gGlobalSyncTable.waterLevel = -20000
|
||||
gGlobalSyncTable.speedMultiplier = 1
|
||||
|
||||
local sFlagIconPrevPos = { x = 0, y = 0 }
|
||||
|
||||
local globalTimer = 0
|
||||
local listedSurvivors = false
|
||||
local speedrunner = 0
|
||||
|
||||
-- localize functions to improve performance
|
||||
local network_player_connected_count,init_single_mario,warp_to_level,play_sound,network_is_server,network_get_player_text_color_string,djui_chat_message_create,disable_time_stop,network_player_set_description,set_mario_action,obj_get_first_with_behavior_id,obj_check_hitbox_overlap,spawn_mist_particles,vec3f_dist,play_race_fanfare,play_music,djui_hud_set_resolution,djui_hud_get_screen_height,djui_hud_get_screen_width,djui_hud_render_rect,djui_hud_set_font,djui_hud_world_pos_to_screen_pos,clampf,math_floor,djui_hud_measure_text,djui_hud_print_text,hud_render_power_meter,hud_get_value,save_file_erase_current_backup_save,save_file_set_flags,save_file_set_using_backup_slot,find_floor_height,spawn_non_sync_object,set_environment_region,vec3f_set,vec3f_copy,math_random,set_ttc_speed_setting,get_level_name,hud_hide,smlua_text_utils_secret_star_replace,smlua_audio_utils_replace_sequence = network_player_connected_count,init_single_mario,warp_to_level,play_sound,network_is_server,network_get_player_text_color_string,djui_chat_message_create,disable_time_stop,network_player_set_description,set_mario_action,obj_get_first_with_behavior_id,obj_check_hitbox_overlap,spawn_mist_particles,vec3f_dist,play_race_fanfare,play_music,djui_hud_set_resolution,djui_hud_get_screen_height,djui_hud_get_screen_width,djui_hud_render_rect,djui_hud_set_font,djui_hud_world_pos_to_screen_pos,clampf,math.floor,djui_hud_measure_text,djui_hud_print_text,hud_render_power_meter,hud_get_value,save_file_erase_current_backup_save,save_file_set_flags,save_file_set_using_backup_slot,find_floor_height,spawn_non_sync_object,set_environment_region,vec3f_set,vec3f_copy,math.random,set_ttc_speed_setting,get_level_name,hud_hide,smlua_text_utils_secret_star_replace,smlua_audio_utils_replace_sequence
|
||||
|
||||
function speedrun_mode(mode)
|
||||
if mode == nil then
|
||||
return speedrunner > 0 and network_player_connected_count() == 1
|
||||
else
|
||||
return speedrunner == mode and network_player_connected_count() == 1
|
||||
end
|
||||
end
|
||||
|
||||
-- runs serverside
|
||||
local function round_start()
|
||||
gGlobalSyncTable.roundState = ROUND_STATE_ACTIVE
|
||||
gGlobalSyncTable.timer = if_then_else(gGlobalSyncTable.level == LEVEL_CTT or (gGlobalSyncTable.level == LEVEL_RR and game == GAME_STAR_ROAD), 730, 100)
|
||||
end
|
||||
|
||||
-- runs serverside
|
||||
local function round_end()
|
||||
gGlobalSyncTable.roundState = ROUND_STATE_INACTIVE
|
||||
gGlobalSyncTable.timer = ROUND_COOLDOWN
|
||||
gGlobalSyncTable.waterLevel = -20000
|
||||
end
|
||||
|
||||
local function get_dest_act()
|
||||
if game ~= GAME_STAR_ROAD then
|
||||
return if_then_else(gNetworkPlayers[0].currLevelNum == LEVEL_CASTLE_GROUNDS, 99, 6)
|
||||
else
|
||||
if gNetworkPlayers[0].currLevelNum == LEVEL_CASTLE_GROUNDS then
|
||||
return 99
|
||||
end
|
||||
return if_then_else(gNetworkPlayers[0].currLevelNum == LEVEL_BBH, 1, 6)
|
||||
end
|
||||
end
|
||||
|
||||
local function get_modifiers_string()
|
||||
if not cheats and not moveset then return "" end
|
||||
|
||||
local modifiers = " ("
|
||||
if moveset then
|
||||
modifiers = modifiers .. "Moveset"
|
||||
else
|
||||
modifiers = modifiers .. "No moveset"
|
||||
end
|
||||
if cheats then
|
||||
modifiers = modifiers .. ", cheats"
|
||||
end
|
||||
modifiers = modifiers .. ")"
|
||||
return modifiers
|
||||
end
|
||||
|
||||
function level_restart()
|
||||
round_start()
|
||||
init_single_mario(gMarioStates[0])
|
||||
mario_set_full_health(gMarioStates[0])
|
||||
gLevels[gGlobalSyncTable.level].time = 0
|
||||
warp_to_level(gGlobalSyncTable.level, gLevels[gGlobalSyncTable.level].area, get_dest_act())
|
||||
end
|
||||
|
||||
local function server_update()
|
||||
if gGlobalSyncTable.roundState == ROUND_STATE_ACTIVE then
|
||||
if gNetworkPlayers[0].currLevelNum == gGlobalSyncTable.level then
|
||||
gGlobalSyncTable.waterLevel = gGlobalSyncTable.waterLevel + gLevels[gGlobalSyncTable.level].speed * gGlobalSyncTable.speedMultiplier
|
||||
|
||||
local active = 0
|
||||
for i = 0, (MAX_PLAYERS - 1) do
|
||||
local m = gMarioStates[i]
|
||||
if active_player(m) ~= 0 and m.health > 0xFF and not gPlayerSyncTable[i].finished then
|
||||
active = active + 1
|
||||
end
|
||||
end
|
||||
|
||||
if active == 0 then
|
||||
local dead = 0
|
||||
for i = 0, (MAX_PLAYERS) - 1 do
|
||||
if active_player(gMarioStates[i]) ~= 0 and gMarioStates[i].health <= 0xFF then
|
||||
dead = dead + 1
|
||||
end
|
||||
end
|
||||
if dead == network_player_connected_count() or (speedrun_mode() and gNetworkPlayers[0].currLevelNum ~= LEVEL_CTT) then
|
||||
gGlobalSyncTable.timer = 0
|
||||
end
|
||||
|
||||
if gGlobalSyncTable.timer > 0 then
|
||||
gGlobalSyncTable.timer = gGlobalSyncTable.timer - 1
|
||||
else
|
||||
round_end()
|
||||
|
||||
if not speedrun_mode() or speedrun_mode(SPEEDRUN_MODE_PROGRESS) then
|
||||
-- move to the next level
|
||||
local finished = 0
|
||||
for i = 0, (MAX_PLAYERS - 1) do
|
||||
if active_player(gMarioStates[i]) ~= 0 and gPlayerSyncTable[i].finished then
|
||||
finished = finished + 1
|
||||
end
|
||||
end
|
||||
|
||||
if finished ~= 0 then
|
||||
-- calculate position
|
||||
local position = 1
|
||||
for k, v in pairs(gMapRotation) do
|
||||
if gGlobalSyncTable.level == v then
|
||||
position = k
|
||||
end
|
||||
end
|
||||
|
||||
position = position + 1
|
||||
if position > FLOOD_LEVEL_COUNT - FLOOD_BONUS_LEVELS then
|
||||
position = 1
|
||||
end
|
||||
|
||||
gGlobalSyncTable.level = gMapRotation[position]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
if network_player_connected_count() > 1 then
|
||||
if gGlobalSyncTable.timer > 0 then
|
||||
gGlobalSyncTable.timer = gGlobalSyncTable.timer - 1
|
||||
|
||||
if gGlobalSyncTable.timer == 30 or gGlobalSyncTable.timer == 60 or gGlobalSyncTable.timer == 90 then
|
||||
play_sound(SOUND_MENU_CHANGE_SELECT, gMarioStates[0].marioObj.header.gfx.cameraToObject)
|
||||
elseif gGlobalSyncTable.timer == 11 then
|
||||
play_sound(SOUND_GENERAL_RACE_GUN_SHOT, gMarioStates[0].marioObj.header.gfx.cameraToObject)
|
||||
end
|
||||
else
|
||||
round_start()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function update()
|
||||
if network_is_server() then server_update() end
|
||||
|
||||
gServerSettings.playerInteractions = PLAYER_INTERACTIONS_NONE
|
||||
|
||||
if gGlobalSyncTable.roundState == ROUND_STATE_INACTIVE then
|
||||
if gNetworkPlayers[0].currLevelNum ~= LEVEL_LOBBY or gNetworkPlayers[0].currActNum ~= 0 then
|
||||
if speedrun_mode() then
|
||||
level_restart()
|
||||
end
|
||||
|
||||
warp_to_level(LEVEL_LOBBY, 1, 0)
|
||||
|
||||
if not listedSurvivors and globalTimer > 5 then
|
||||
listedSurvivors = true
|
||||
local finished = 0
|
||||
local string = "Survivors:"
|
||||
for i = 0, (MAX_PLAYERS - 1) do
|
||||
if gNetworkPlayers[i].connected and gPlayerSyncTable[i].finished then
|
||||
string = string .. "\n" .. network_get_player_text_color_string(i) .. gNetworkPlayers[i].name
|
||||
finished = finished + 1
|
||||
end
|
||||
end
|
||||
if finished == 0 then
|
||||
string = string .. "\n\\#ff0000\\None"
|
||||
end
|
||||
djui_chat_message_create(string)
|
||||
end
|
||||
end
|
||||
elseif gGlobalSyncTable.roundState == ROUND_STATE_ACTIVE then
|
||||
local act = get_dest_act()
|
||||
if gNetworkPlayers[0].currLevelNum ~= gGlobalSyncTable.level or gNetworkPlayers[0].currActNum ~= act then
|
||||
listedSurvivors = false
|
||||
mario_set_full_health(gMarioStates[0])
|
||||
gLevels[gGlobalSyncTable.level].time = 0
|
||||
gPlayerSyncTable[0].finished = false
|
||||
warp_to_level(gGlobalSyncTable.level, gLevels[gGlobalSyncTable.level].area, act)
|
||||
end
|
||||
end
|
||||
|
||||
-- stops the star spawn cutscenes from happening
|
||||
local m = gMarioStates[0]
|
||||
if m.area ~= nil and m.area.camera ~= nil and (m.area.camera.cutscene == CUTSCENE_STAR_SPAWN or m.area.camera.cutscene == CUTSCENE_RED_COIN_STAR_SPAWN) then
|
||||
m.area.camera.cutscene = 0
|
||||
m.freeze = 0
|
||||
disable_time_stop()
|
||||
end
|
||||
|
||||
globalTimer = globalTimer + 1
|
||||
end
|
||||
|
||||
--- @param m MarioState
|
||||
local function mario_update(m)
|
||||
if not gNetworkPlayers[m.playerIndex].connected then return end
|
||||
|
||||
if m.health > 0xFF then
|
||||
network_player_set_description(gNetworkPlayers[m.playerIndex], "Alive", 75, 255, 75, 255)
|
||||
else
|
||||
network_player_set_description(gNetworkPlayers[m.playerIndex], "Dead", 255, 75, 75, 255)
|
||||
end
|
||||
|
||||
if m.playerIndex ~= 0 then return end
|
||||
|
||||
-- action specific modifications
|
||||
if m.action == ACT_STEEP_JUMP then
|
||||
m.action = ACT_JUMP
|
||||
elseif m.action == ACT_JUMBO_STAR_CUTSCENE then
|
||||
m.flags = m.flags | MARIO_WING_CAP
|
||||
end
|
||||
|
||||
-- disable instant warps
|
||||
if m.floor ~= nil and (m.floor.type == SURFACE_WARP or (m.floor.type >= SURFACE_PAINTING_WARP_D3 and m.floor.type <= SURFACE_PAINTING_WARP_FC) or (m.floor.type >= SURFACE_INSTANT_WARP_1B and m.floor.type <= SURFACE_INSTANT_WARP_1E)) then
|
||||
m.floor.type = SURFACE_DEFAULT
|
||||
end
|
||||
|
||||
-- disable insta kills
|
||||
if m.floor ~= nil and (m.floor.type == SURFACE_INSTANT_QUICKSAND or m.floor.type == SURFACE_INSTANT_MOVING_QUICKSAND) then
|
||||
m.floor.type = SURFACE_BURNING
|
||||
end
|
||||
|
||||
-- disable damage in lobby
|
||||
if gGlobalSyncTable.roundState == ROUND_STATE_INACTIVE then
|
||||
mario_set_full_health(m)
|
||||
m.peakHeight = m.pos.y
|
||||
return
|
||||
end
|
||||
|
||||
-- dialog boxes
|
||||
if (m.action == ACT_SPAWN_NO_SPIN_AIRBORNE or m.action == ACT_SPAWN_NO_SPIN_LANDING or m.action == ACT_SPAWN_SPIN_AIRBORNE or m.action == ACT_SPAWN_SPIN_LANDING) and m.pos.y < m.floorHeight + 10 then
|
||||
set_mario_action(m, ACT_FREEFALL, 0)
|
||||
end
|
||||
|
||||
-- manage CTT
|
||||
if gNetworkPlayers[0].currLevelNum == LEVEL_CTT then
|
||||
m.peakHeight = m.pos.y
|
||||
|
||||
local star = obj_get_first_with_behavior_id(id_bhvFinalStar)
|
||||
if star ~= nil and obj_check_hitbox_overlap(m.marioObj, star) and m.action ~= ACT_JUMBO_STAR_CUTSCENE then
|
||||
spawn_mist_particles()
|
||||
set_mario_action(m, ACT_JUMBO_STAR_CUTSCENE, 0)
|
||||
end
|
||||
|
||||
if m.action == ACT_JUMBO_STAR_CUTSCENE and m.actionTimer >= 499 then
|
||||
set_mario_spectator(m)
|
||||
end
|
||||
end
|
||||
|
||||
-- check if the player has reached the end of the level
|
||||
if gNetworkPlayers[0].currLevelNum == gGlobalSyncTable.level and not gPlayerSyncTable[0].finished and ((gNetworkPlayers[0].currLevelNum ~= LEVEL_CTT and m.pos.y == m.floorHeight)
|
||||
or (gNetworkPlayers[0].currLevelNum == LEVEL_CTT and m.action == ACT_JUMBO_STAR_CUTSCENE) or (m.action & ACT_FLAG_ON_POLE) ~= 0)
|
||||
and vec3f_dist(m.pos, gLevels[gGlobalSyncTable.level].goalPos) < 600 then
|
||||
gPlayerSyncTable[0].finished = true
|
||||
|
||||
local string = ""
|
||||
if gNetworkPlayers[0].currLevelNum ~= LEVEL_CTT and not (game == GAME_STAR_ROAD and gNetworkPlayers[0].currLevelNum == LEVEL_RR) then
|
||||
string = string .. "\\#00ff00\\You escaped the flood!\n"
|
||||
play_race_fanfare()
|
||||
else
|
||||
string = string .. "\\#00ff00\\You escaped the \\#ffff00\\final\\#00ff00\\ flood! Congratulations!\n"
|
||||
play_music(0, SEQUENCE_ARGS(8, SEQ_EVENT_CUTSCENE_VICTORY), 0)
|
||||
end
|
||||
string = string .. "\\#ffffff\\Time: " .. string.format("%.3f", gLevels[gGlobalSyncTable.level].time / 30) .. get_modifiers_string()
|
||||
|
||||
djui_chat_message_create(string)
|
||||
end
|
||||
|
||||
-- update spectator if finished, manage other things if not
|
||||
if gPlayerSyncTable[0].finished then
|
||||
mario_set_full_health(m)
|
||||
if network_player_connected_count() > 1 and m.action ~= ACT_JUMBO_STAR_CUTSCENE then
|
||||
set_mario_spectator(m)
|
||||
end
|
||||
else
|
||||
if m.pos.y + 40 < gGlobalSyncTable.waterLevel then
|
||||
m.health = m.health - 30
|
||||
end
|
||||
|
||||
if m.action == ACT_QUICKSAND_DEATH then
|
||||
m.health = 0xFF
|
||||
end
|
||||
|
||||
if m.health <= 0xFF then
|
||||
if network_player_connected_count() > 1 then
|
||||
m.area.camera.cutscene = 0
|
||||
set_mario_spectator(m)
|
||||
end
|
||||
else
|
||||
gLevels[gGlobalSyncTable.level].time = gLevels[gGlobalSyncTable.level].time + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function on_hud_render()
|
||||
local water = obj_get_first_with_behavior_id(id_bhvWater)
|
||||
if gNetworkPlayers[0].currLevelNum == gGlobalSyncTable.level and water ~= nil then
|
||||
djui_hud_set_resolution(RESOLUTION_DJUI)
|
||||
|
||||
if gLakituState.pos.y < gGlobalSyncTable.waterLevel - 10 then
|
||||
switch(water.oAnimState, {
|
||||
[FLOOD_WATER] = function()
|
||||
djui_hud_set_adjusted_color(0, 20, 200, 120)
|
||||
end,
|
||||
[FLOOD_LAVA] = function()
|
||||
djui_hud_set_adjusted_color(200, 0, 0, 220)
|
||||
end,
|
||||
[FLOOD_SAND] = function()
|
||||
djui_hud_set_adjusted_color(254, 193, 121, 220)
|
||||
end,
|
||||
[FLOOD_MUD] = function()
|
||||
djui_hud_set_adjusted_color(74, 123, 0, 220)
|
||||
end
|
||||
})
|
||||
djui_hud_render_rect(0, 0, djui_hud_get_screen_width(), djui_hud_get_screen_height())
|
||||
end
|
||||
end
|
||||
|
||||
djui_hud_set_resolution(RESOLUTION_N64)
|
||||
djui_hud_set_font(FONT_TINY)
|
||||
|
||||
local level = gLevels[gNetworkPlayers[0].currLevelNum]
|
||||
if level ~= nil and level.name ~= "ctt" then
|
||||
local out = { x = 0, y = 0, z = 0 }
|
||||
djui_hud_world_pos_to_screen_pos(level.goalPos, out)
|
||||
local dX = clampf(out.x - 5, 0, djui_hud_get_screen_width() - 19.2)
|
||||
local dY = clampf(out.y - 20, 0, djui_hud_get_screen_height() - 19.2)
|
||||
|
||||
djui_hud_set_adjusted_color(255, 255, 255, 200)
|
||||
djui_hud_render_texture_interpolated(TEX_FLOOD_FLAG, sFlagIconPrevPos.x, sFlagIconPrevPos.y, 0.15, 0.15, dX, dY, 0.15, 0.15)
|
||||
|
||||
sFlagIconPrevPos.x = dX
|
||||
sFlagIconPrevPos.y = dY
|
||||
end
|
||||
|
||||
local text = if_then_else(gGlobalSyncTable.roundState == ROUND_STATE_INACTIVE, "Type '/flood start' to start a round", "0.000 seconds" .. get_modifiers_string())
|
||||
if gNetworkPlayers[0].currAreaSyncValid then
|
||||
if gGlobalSyncTable.roundState == ROUND_STATE_INACTIVE then
|
||||
text = if_then_else(network_player_connected_count() > 1, "Round starts in " .. tostring(math_floor(gGlobalSyncTable.timer / 30)), "Type '/flood start' to start a round")
|
||||
elseif gNetworkPlayers[0].currLevelNum == gGlobalSyncTable.level then
|
||||
text = tostring(string.format("%.3f", gLevels[gGlobalSyncTable.level].time / 30)) .. " seconds" .. get_modifiers_string()
|
||||
end
|
||||
end
|
||||
|
||||
local scale = 1
|
||||
local width = djui_hud_measure_text(text) * scale
|
||||
local x = (djui_hud_get_screen_width() - width) * 0.5
|
||||
|
||||
djui_hud_set_adjusted_color(0, 0, 0, 128)
|
||||
djui_hud_render_rect(x - 6, 0, width + 12, 16)
|
||||
djui_hud_set_adjusted_color(255, 255, 255, 255)
|
||||
djui_hud_print_text(text, x, 0, scale)
|
||||
|
||||
hud_render_power_meter(gMarioStates[0].health, djui_hud_get_screen_width() - 64, 0, 64, 64)
|
||||
|
||||
djui_hud_set_font(FONT_HUD)
|
||||
|
||||
djui_hud_render_texture(gTextures.coin, 5, 5, 1, 1)
|
||||
djui_hud_print_text(">", 21, 5, 1)
|
||||
djui_hud_print_text(tostring(hud_get_value(HUD_DISPLAY_COINS)), 37, 5, 1)
|
||||
|
||||
if gGlobalSyncTable.speedMultiplier ~= 1 then
|
||||
djui_hud_print_text(string.format("%.2fx", gGlobalSyncTable.speedMultiplier), 5, 24, 1)
|
||||
end
|
||||
end
|
||||
|
||||
local function on_level_init()
|
||||
-- reset save
|
||||
save_file_erase_current_backup_save()
|
||||
if gNetworkPlayers[0].currLevelNum ~= LEVEL_CASTLE_GROUNDS then
|
||||
save_file_set_flags(SAVE_FLAG_HAVE_VANISH_CAP)
|
||||
save_file_set_flags(SAVE_FLAG_HAVE_WING_CAP)
|
||||
end
|
||||
save_file_set_using_backup_slot(true)
|
||||
|
||||
if gGlobalSyncTable.roundState == ROUND_STATE_ACTIVE then
|
||||
if network_is_server() then
|
||||
local start = gLevels[gGlobalSyncTable.level].customStartPos
|
||||
if start ~= nil then
|
||||
gGlobalSyncTable.waterLevel = find_floor_height(start.x, start.y, start.z) - 1200
|
||||
else
|
||||
-- only sub areas have a weird issue where this function appears to always return the floor lower limit on level init
|
||||
gGlobalSyncTable.waterLevel = if_then_else(gLevels[gGlobalSyncTable.level].area == 1, find_floor_height(gMarioStates[0].pos.x, gMarioStates[0].pos.y, gMarioStates[0].pos.z), gMarioStates[0].pos.y) - 1200
|
||||
end
|
||||
end
|
||||
|
||||
if game == GAME_VANILLA then
|
||||
if gNetworkPlayers[0].currLevelNum == LEVEL_BITS then
|
||||
spawn_non_sync_object(
|
||||
id_bhvCustomStaticObject,
|
||||
E_MODEL_CTT,
|
||||
10000, -2000, -40000,
|
||||
function(o) obj_scale(o, 0.5) end
|
||||
)
|
||||
elseif gNetworkPlayers[0].currLevelNum == LEVEL_WDW then
|
||||
set_environment_region(1, -20000)
|
||||
end
|
||||
end
|
||||
|
||||
spawn_non_sync_object(
|
||||
id_bhvWater,
|
||||
E_MODEL_FLOOD,
|
||||
0, gGlobalSyncTable.waterLevel, 0,
|
||||
nil
|
||||
)
|
||||
end
|
||||
|
||||
local pos = gLevels[gNetworkPlayers[0].currLevelNum].goalPos
|
||||
if pos == nil then return end
|
||||
|
||||
if gNetworkPlayers[0].currLevelNum == LEVEL_CTT then
|
||||
spawn_non_sync_object(
|
||||
id_bhvFinalStar,
|
||||
E_MODEL_STAR,
|
||||
pos.x, pos.y, pos.z,
|
||||
nil
|
||||
)
|
||||
else
|
||||
spawn_non_sync_object(
|
||||
id_bhvFloodFlag,
|
||||
E_MODEL_KOOPA_FLAG,
|
||||
pos.x, pos.y, pos.z,
|
||||
--- @param o Object
|
||||
function(o)
|
||||
o.oFaceAnglePitch = 0
|
||||
o.oFaceAngleYaw = pos.a
|
||||
o.oFaceAngleRoll = 0
|
||||
end
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
-- dynos warps mario back to castle grounds facing the wrong way, likely something from the title screen
|
||||
local function on_warp()
|
||||
--- @type MarioState
|
||||
local m = gMarioStates[0]
|
||||
if gNetworkPlayers[0].currLevelNum == LEVEL_CASTLE_GROUNDS then
|
||||
if game == GAME_VANILLA then
|
||||
m.faceAngle.y = m.faceAngle.y + 0x8000
|
||||
elseif game == GAME_STAR_ROAD then
|
||||
if gGlobalSyncTable.roundState == ROUND_STATE_INACTIVE then
|
||||
vec3f_set(m.pos, -6797, 1830, 2710)
|
||||
m.faceAngle.y = 0x6000
|
||||
else
|
||||
vec3f_set(m.pos, -1644, -614, -1524)
|
||||
m.faceAngle.y = -0x4000
|
||||
end
|
||||
end
|
||||
|
||||
if gGlobalSyncTable.roundState == ROUND_STATE_ACTIVE then
|
||||
play_music(0, SEQUENCE_ARGS(4, SEQ_LEVEL_BOSS_KOOPA_FINAL), 0)
|
||||
end
|
||||
elseif gLevels[gGlobalSyncTable.level].customStartPos ~= nil then
|
||||
local start = gLevels[gGlobalSyncTable.level].customStartPos
|
||||
vec3f_copy(m.pos, start)
|
||||
set_mario_action(m, ACT_SPAWN_SPIN_AIRBORNE, 0)
|
||||
m.faceAngle.y = start.a
|
||||
end
|
||||
end
|
||||
|
||||
local function on_player_connected()
|
||||
if network_is_server() and gGlobalSyncTable.roundState == ROUND_STATE_INACTIVE then gGlobalSyncTable.timer = ROUND_COOLDOWN end
|
||||
end
|
||||
|
||||
local function on_start_command(msg)
|
||||
if msg == "?" then
|
||||
djui_chat_message_create("/flood \\#00ffff\\start\\#ffff00\\ [random|1-" .. FLOOD_LEVEL_COUNT .. "]\\#ffffff\\\nSets the level to a random one or a specific one, you can also leave it empty for normal progression.")
|
||||
return true
|
||||
end
|
||||
|
||||
if msg == "random" then
|
||||
gGlobalSyncTable.level = gLevels[math_random(1, FLOOD_LEVEL_COUNT)]
|
||||
else
|
||||
local override = tonumber(msg)
|
||||
if override ~= nil then
|
||||
override = clamp(math_floor(override), 1, FLOOD_LEVEL_COUNT)
|
||||
gGlobalSyncTable.level = gMapRotation[override]
|
||||
else
|
||||
for k, v in pairs(gLevels) do
|
||||
if msg ~= nil and msg:lower() == v.name then
|
||||
gGlobalSyncTable.level = k
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if gGlobalSyncTable.roundState == ROUND_STATE_ACTIVE then
|
||||
network_send(true, { restart = true })
|
||||
level_restart()
|
||||
else
|
||||
round_start()
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
local function on_speed_command(msg)
|
||||
local speed = tonumber(msg)
|
||||
if speed ~= nil then
|
||||
speed = clampf(speed, 0, 10)
|
||||
djui_chat_message_create("Water speed set to " .. speed)
|
||||
gGlobalSyncTable.speedMultiplier = speed
|
||||
return true
|
||||
end
|
||||
|
||||
djui_chat_message_create("/flood \\#00ffff\\speed\\#ffff00\\ [number]\\#ffffff\\\nSets the speed multiplier of the flood")
|
||||
return true
|
||||
end
|
||||
|
||||
local function on_ttc_speed_command(msg)
|
||||
if gGlobalSyncTable.roundState ~= ROUND_STATE_INACTIVE then
|
||||
djui_chat_message_create("\\#ff0000\\You can only change the TTC speed before the round starts!")
|
||||
return true
|
||||
end
|
||||
|
||||
msg = msg:lower()
|
||||
if msg == "fast" then
|
||||
set_ttc_speed_setting(TTC_SPEED_FAST)
|
||||
djui_chat_message_create("TTC speed set to fast")
|
||||
return true
|
||||
elseif msg == "slow" then
|
||||
set_ttc_speed_setting(TTC_SPEED_SLOW)
|
||||
djui_chat_message_create("TTC speed set to slow")
|
||||
return true
|
||||
elseif msg == "random" then
|
||||
set_ttc_speed_setting(TTC_SPEED_RANDOM)
|
||||
djui_chat_message_create("TTC speed set to random")
|
||||
return true
|
||||
elseif msg == "stopped" then
|
||||
set_ttc_speed_setting(TTC_SPEED_STOPPED)
|
||||
djui_chat_message_create("TTC speed stopped")
|
||||
return true
|
||||
end
|
||||
|
||||
djui_chat_message_create("/flood \\#00ffff\\ttc-speed\\#ffff00\\ [fast|slow|random|stopped]\\#ffffff\\\nChanges the speed of TTC")
|
||||
return true
|
||||
end
|
||||
|
||||
local function on_speedrun_command(msg)
|
||||
msg = msg:lower()
|
||||
if msg == "off" then
|
||||
djui_chat_message_create("Speedrun mode status: \\#ff0000\\OFF")
|
||||
speedrunner = SPEEDRUN_MODE_OFF
|
||||
return true
|
||||
elseif msg == "progress" then
|
||||
djui_chat_message_create("Speedrun mode status: \\#00ff00\\Progress Level")
|
||||
speedrunner = SPEEDRUN_MODE_PROGRESS
|
||||
return true
|
||||
elseif msg == "restart" then
|
||||
djui_chat_message_create("Speedrun mode status: \\#00ff00\\Restart Level")
|
||||
speedrunner = SPEEDRUN_MODE_RESTART
|
||||
return true
|
||||
end
|
||||
|
||||
djui_chat_message_create("/flood \\#00ffff\\speedrun\\#ffff00\\ [off|progress|restart]\\#ffffff\\\nTo make adjustments to singleplayer Flood helpful for speedrunners")
|
||||
return true
|
||||
end
|
||||
|
||||
local function on_scoreboard_command()
|
||||
djui_chat_message_create("Times:")
|
||||
local modifiers = get_modifiers_string()
|
||||
local total = 0
|
||||
for i = 1, FLOOD_LEVEL_COUNT do
|
||||
local level = gMapRotation[i]
|
||||
djui_chat_message_create(get_level_name(level_to_course(level), level, 1) .. " - " .. timestamp(gLevels[level].time) .. modifiers)
|
||||
total = total + gLevels[level].time
|
||||
end
|
||||
|
||||
djui_chat_message_create("Total Time: " .. timestamp(total))
|
||||
return true
|
||||
end
|
||||
|
||||
local function on_flood_command(msg)
|
||||
local args = split(msg)
|
||||
if args[1] == "start" then
|
||||
return on_start_command(args[2])
|
||||
elseif args[1] == "speed" then
|
||||
return on_speed_command(args[2])
|
||||
elseif args[1] == "ttc-speed" then
|
||||
return on_ttc_speed_command(args[2])
|
||||
elseif args[1] == "speedrun" then
|
||||
return on_speedrun_command(args[2])
|
||||
elseif args[1] == "scoreboard" then
|
||||
return on_scoreboard_command()
|
||||
end
|
||||
|
||||
djui_chat_message_create("/flood \\#00ffff\\[start|speed|ttc-speed|speedrun|scoreboard]")
|
||||
return true
|
||||
end
|
||||
|
||||
gServerSettings.skipIntro = 1
|
||||
gServerSettings.stayInLevelAfterStar = 2
|
||||
|
||||
gLevelValues.entryLevel = LEVEL_LOBBY
|
||||
gLevelValues.floorLowerLimit = -20000
|
||||
gLevelValues.floorLowerLimitMisc = -20000 + 1000
|
||||
gLevelValues.floorLowerLimitShadow = -20000 + 1000.0
|
||||
gLevelValues.fixCollisionBugs = 1
|
||||
gLevelValues.fixCollisionBugsRoundedCorners = 0
|
||||
|
||||
hud_hide()
|
||||
|
||||
if game == GAME_VANILLA then
|
||||
set_ttc_speed_setting(TTC_SPEED_SLOW)
|
||||
|
||||
smlua_text_utils_secret_star_replace(COURSE_SA, " Climb The Tower Flood")
|
||||
|
||||
smlua_audio_utils_replace_sequence(SEQ_LEVEL_BOSS_KOOPA_FINAL, 37, 60, "00_pinball_custom")
|
||||
end
|
||||
|
||||
hook_event(HOOK_UPDATE, update)
|
||||
hook_event(HOOK_MARIO_UPDATE, mario_update)
|
||||
hook_event(HOOK_ON_HUD_RENDER, on_hud_render)
|
||||
hook_event(HOOK_ON_LEVEL_INIT, on_level_init)
|
||||
hook_event(HOOK_ON_WARP, on_warp)
|
||||
hook_event(HOOK_ON_PLAYER_CONNECTED, on_player_connected)
|
||||
|
||||
if network_is_server() then
|
||||
hook_chat_command("flood", "\\#00ffff\\[start|speed|ttc-speed|speedrun|scoreboard]", on_flood_command)
|
||||
end
|
||||
|
||||
for i = 0, (MAX_PLAYERS - 1) do
|
||||
gPlayerSyncTable[i].finished = false
|
||||
end
|
|
@ -1,210 +0,0 @@
|
|||
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)
|
Binary file not shown.
|
@ -1,163 +0,0 @@
|
|||
if unsupported then return end
|
||||
|
||||
local MARIO_HEAD_POS = 120
|
||||
|
||||
local sPlayerFirstPerson = {
|
||||
pos = { x = 0, y = 0, z = 0 },
|
||||
freecam = camera_config_is_free_cam_enabled(),
|
||||
pitch = 0,
|
||||
yaw = 0,
|
||||
fov = 70
|
||||
}
|
||||
|
||||
-- localize functions to improve performance - spectator.lua
|
||||
local camera_config_get_x_sensitivity,camera_config_get_y_sensitivity,camera_config_is_x_inverted,camera_config_is_y_inverted,is_game_paused,djui_hud_get_raw_mouse_y,clamp,djui_hud_get_raw_mouse_x,vec3f_copy,mario_drop_held_object,set_mario_animation,vec3f_set,vec3f_mul,djui_hud_set_mouse_locked,camera_freeze,maxf,camera_config_is_free_cam_enabled,set_override_near,set_override_fov,camera_unfreeze,camera_config_is_mouse_look_enabled,allocate_mario_action = camera_config_get_x_sensitivity,camera_config_get_y_sensitivity,camera_config_is_x_inverted,camera_config_is_y_inverted,is_game_paused,djui_hud_get_raw_mouse_y,clamp,djui_hud_get_raw_mouse_x,vec3f_copy,mario_drop_held_object,set_mario_animation,vec3f_set,vec3f_mul,djui_hud_set_mouse_locked,camera_freeze,maxf,camera_config_is_free_cam_enabled,set_override_near,set_override_fov,camera_unfreeze,camera_config_is_mouse_look_enabled,allocate_mario_action
|
||||
|
||||
--- @param m MarioState
|
||||
local function update_fp_camera(m)
|
||||
gLakituState.mode = CAMERA_MODE_FREE_ROAM
|
||||
gLakituState.defMode = CAMERA_MODE_FREE_ROAM
|
||||
|
||||
local sensX = 0.3 * camera_config_get_x_sensitivity()
|
||||
local sensY = 0.4 * camera_config_get_y_sensitivity()
|
||||
local invX = if_then_else(camera_config_is_x_inverted(), 1, -1)
|
||||
local invY = if_then_else(camera_config_is_y_inverted(), 1, -1)
|
||||
|
||||
if not is_game_paused() then
|
||||
-- update pitch
|
||||
sPlayerFirstPerson.pitch = sPlayerFirstPerson.pitch - sensY * (invY * m.controller.extStickY - 1.5 * djui_hud_get_raw_mouse_y())
|
||||
sPlayerFirstPerson.pitch = clamp(sPlayerFirstPerson.pitch, -0x3F00, 0x3F00)
|
||||
|
||||
-- update yaw
|
||||
if (m.controller.buttonPressed & L_TRIG) ~= 0 then
|
||||
sPlayerFirstPerson.yaw = m.faceAngle.y + 0x8000
|
||||
else
|
||||
sPlayerFirstPerson.yaw = sPlayerFirstPerson.yaw + sensX * (invX * m.controller.extStickX - 1.5 * djui_hud_get_raw_mouse_x())
|
||||
end
|
||||
sPlayerFirstPerson.yaw = (sPlayerFirstPerson.yaw + 0x10000) % 0x10000
|
||||
end
|
||||
|
||||
gLakituState.yaw = sPlayerFirstPerson.yaw
|
||||
m.area.camera.yaw = sPlayerFirstPerson.yaw
|
||||
|
||||
-- update pos
|
||||
gLakituState.pos.x = sPlayerFirstPerson.pos.x + coss(sPlayerFirstPerson.pitch) * sins(sPlayerFirstPerson.yaw)
|
||||
gLakituState.pos.y = sPlayerFirstPerson.pos.y + sins(sPlayerFirstPerson.pitch) + MARIO_HEAD_POS
|
||||
gLakituState.pos.z = sPlayerFirstPerson.pos.z + coss(sPlayerFirstPerson.pitch) * coss(sPlayerFirstPerson.yaw)
|
||||
vec3f_copy(m.area.camera.pos, gLakituState.pos)
|
||||
vec3f_copy(gLakituState.curPos, gLakituState.pos)
|
||||
vec3f_copy(gLakituState.goalPos, gLakituState.pos)
|
||||
|
||||
-- update focus
|
||||
gLakituState.focus.x = sPlayerFirstPerson.pos.x - 100 * coss(sPlayerFirstPerson.pitch) * sins(sPlayerFirstPerson.yaw)
|
||||
gLakituState.focus.y = sPlayerFirstPerson.pos.y - 100 * sins(sPlayerFirstPerson.pitch) + MARIO_HEAD_POS
|
||||
gLakituState.focus.z = sPlayerFirstPerson.pos.z - 100 * coss(sPlayerFirstPerson.pitch) * coss(sPlayerFirstPerson.yaw)
|
||||
vec3f_copy(m.area.camera.focus, gLakituState.focus)
|
||||
vec3f_copy(gLakituState.curFocus, gLakituState.focus)
|
||||
vec3f_copy(gLakituState.goalFocus, gLakituState.focus)
|
||||
|
||||
-- set other values
|
||||
gLakituState.posHSpeed = 0
|
||||
gLakituState.posVSpeed = 0
|
||||
gLakituState.focHSpeed = 0
|
||||
gLakituState.focVSpeed = 0
|
||||
end
|
||||
|
||||
--- @param m MarioState
|
||||
function set_mario_spectator(m)
|
||||
if m.action ~= ACT_SPECTATOR then
|
||||
sPlayerFirstPerson.pos = { x = m.pos.x, y = if_then_else(m.health > 0xFF, m.pos.y, gGlobalSyncTable.waterLevel), z = m.pos.z }
|
||||
end
|
||||
m.action = ACT_SPECTATOR
|
||||
end
|
||||
|
||||
--- @param m MarioState
|
||||
local function act_spectator(m)
|
||||
mario_drop_held_object(m)
|
||||
m.squishTimer = 0
|
||||
|
||||
set_mario_animation(m, MARIO_ANIM_DROWNING_PART2)
|
||||
m.marioBodyState.eyeState = MARIO_EYES_DEAD
|
||||
m.faceAngle.x = 0
|
||||
m.faceAngle.z = 0
|
||||
|
||||
if gPlayerSyncTable[m.playerIndex].finished then
|
||||
m.marioObj.header.gfx.node.flags = m.marioObj.header.gfx.node.flags & ~GRAPH_RENDER_ACTIVE
|
||||
local goalPos = gLevels[gGlobalSyncTable.level].goalPos
|
||||
vec3f_set(m.pos, goalPos.x, goalPos.y + 600, goalPos.z)
|
||||
mario_set_full_health(m)
|
||||
else
|
||||
m.pos.y = gGlobalSyncTable.waterLevel - 70
|
||||
vec3f_copy(m.marioObj.header.gfx.pos, m.pos)
|
||||
vec3f_copy(m.marioObj.header.gfx.angle, m.faceAngle)
|
||||
m.marioObj.header.gfx.angle.y = 0
|
||||
m.health = 0xFF
|
||||
m.healCounter = 0
|
||||
m.hurtCounter = 0
|
||||
end
|
||||
|
||||
if m.playerIndex ~= 0 then return end
|
||||
|
||||
if not is_game_paused() then
|
||||
local forward = { x = sins(m.faceAngle.y), y = 0, z = coss(m.faceAngle.y) }
|
||||
local right = { x = sins(m.faceAngle.y - 0x4000), y = 0, z = coss(m.faceAngle.y - 0x4000) }
|
||||
local dir = { x = forward.x * m.controller.stickY + right.x * m.controller.stickX, y = 0, z = forward.z * m.controller.stickY + right.z * m.controller.stickX }
|
||||
local speed = if_then_else((m.controller.buttonDown & B_BUTTON) ~= 0, 2, 1)
|
||||
dir = vec3f_mul(dir, speed)
|
||||
|
||||
sPlayerFirstPerson.pos.x = sPlayerFirstPerson.pos.x + dir.x
|
||||
sPlayerFirstPerson.pos.z = sPlayerFirstPerson.pos.z + dir.z
|
||||
|
||||
if (m.input & INPUT_A_DOWN) ~= 0 then
|
||||
sPlayerFirstPerson.pos.y = sPlayerFirstPerson.pos.y + (50 * speed)
|
||||
end
|
||||
if (m.input & INPUT_Z_DOWN) ~= 0 then
|
||||
sPlayerFirstPerson.pos.y = sPlayerFirstPerson.pos.y - (50 * speed)
|
||||
end
|
||||
end
|
||||
|
||||
m.faceAngle.y = m.area.camera.yaw + 0x8000
|
||||
|
||||
djui_hud_set_mouse_locked(not is_game_paused())
|
||||
|
||||
camera_freeze()
|
||||
update_fp_camera(m)
|
||||
end
|
||||
|
||||
--- @param m MarioState
|
||||
local function on_set_mario_action(m)
|
||||
if m.action == ACT_VERTICAL_WIND then
|
||||
m.vel.y = maxf(m.vel.y, 0)
|
||||
end
|
||||
|
||||
if m.playerIndex ~= 0 then return end
|
||||
|
||||
if m.action == ACT_SPECTATOR then
|
||||
sPlayerFirstPerson.freecam = camera_config_is_free_cam_enabled()
|
||||
camera_freeze()
|
||||
set_override_near(45)
|
||||
set_override_fov(sPlayerFirstPerson.fov)
|
||||
sPlayerFirstPerson.pitch = 0
|
||||
sPlayerFirstPerson.yaw = m.faceAngle.y + 0x8000
|
||||
else
|
||||
if sPlayerFirstPerson.freecam then
|
||||
gLakituState.mode = CAMERA_MODE_NEWCAM
|
||||
gLakituState.defMode = CAMERA_MODE_NEWCAM
|
||||
end
|
||||
camera_unfreeze()
|
||||
set_override_near(0)
|
||||
set_override_fov(0)
|
||||
sPlayerFirstPerson.pitch = 0
|
||||
sPlayerFirstPerson.yaw = 0
|
||||
if not camera_config_is_mouse_look_enabled() then
|
||||
djui_hud_set_mouse_locked(false)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
ACT_SPECTATOR = allocate_mario_action(ACT_GROUP_AIRBORNE | ACT_FLAG_INVULNERABLE)
|
||||
|
||||
hook_event(HOOK_ON_SET_MARIO_ACTION, on_set_mario_action)
|
||||
|
||||
---@diagnostic disable-next-line: missing-parameter
|
||||
hook_mario_action(ACT_SPECTATOR, act_spectator)
|
Binary file not shown.
Before Width: | Height: | Size: 952 B |
Binary file not shown.
Loading…
Reference in a new issue