mirror of
https://github.com/coop-deluxe/sm64coopdx.git
synced 2024-11-25 05:25:14 +00:00
788 lines
No EOL
33 KiB
Lua
788 lines
No EOL
33 KiB
Lua
-- name: Character Select
|
|
-- description: A Library / API made to make adding and\nusing Custom Characters as simple as possible!\n\nCreated by:\\#008800\\ Squishy6094\n\\#dcdcdc\\Concepts by:\\#4496f5\\ AngelicMiracles\\#AAAAFF\\\n\nGithub:\nSquishy6094/character-select-coop
|
|
|
|
|
|
menu = false
|
|
options = false
|
|
|
|
currChar = 1
|
|
local currOption = 1
|
|
|
|
|
|
local TEX_HEADER = get_texture_info("char-select-text")
|
|
|
|
local TEXT_PREF_LOAD = "Default"
|
|
|
|
local ommActive = _G.OmmApi ~= nil
|
|
|
|
--[[
|
|
Note: Do NOT add characters via the characterTable below,
|
|
We highly reccomend you create your own mod and use the
|
|
API to add characters, this ensures your pack is easy
|
|
to use for anyone and low on file space!
|
|
]]
|
|
characterTable = {
|
|
[1] = {
|
|
name = "Default",
|
|
description = {"The vanilla cast for sm64ex-coop!", "", "These Characters are swappable", "via the default Options Menu"},
|
|
credit = "Nintendo / Coop Team",
|
|
color = {r = 255, g = 50, b = 50},
|
|
model = nil,
|
|
forceChar = nil,
|
|
lifeIcon = gTextures.mario_head,
|
|
},
|
|
}
|
|
|
|
local optionTableRef = {
|
|
openInputs = 1,
|
|
menuColor = 2,
|
|
anims = 3,
|
|
inputLatency = 4,
|
|
localModels = 5,
|
|
prefToDefault = 6,
|
|
}
|
|
|
|
optionTable = {
|
|
[optionTableRef.openInputs] = {
|
|
name = "Open Binds",
|
|
toggle = tonumber(mod_storage_load("MenuInput")),
|
|
toggleSaveName = "MenuInput",
|
|
toggleDefault = 0,
|
|
toggleMax = 2,
|
|
toggleNames = {"None", ommActive and "D-pad Down + R" or "D-pad Down", "Z (Pause Menu)"},
|
|
},
|
|
[optionTableRef.menuColor] = {
|
|
name = "Menu Color",
|
|
toggle = tonumber(mod_storage_load("MenuColor")),
|
|
toggleSaveName = "MenuColor",
|
|
toggleDefault = 0,
|
|
toggleMax = 9,
|
|
toggleNames = {"Auto", "Red", "Orange", "Yellow", "Green", "Blue", "Pink", "Purple", "White", "Black"},
|
|
},
|
|
[optionTableRef.anims] = {
|
|
name = "Animations",
|
|
toggle = tonumber(mod_storage_load("Anims")),
|
|
toggleSaveName = "Anims",
|
|
toggleDefault = 1,
|
|
toggleMax = 1,
|
|
},
|
|
[optionTableRef.inputLatency] = {
|
|
name = "Scroll Speed",
|
|
toggle = tonumber(mod_storage_load("Latency")),
|
|
toggleSaveName = "Latency",
|
|
toggleDefault = 1,
|
|
toggleMax = 2,
|
|
toggleNames = {"Slow", "Normal", "Fast"},
|
|
},
|
|
[optionTableRef.localModels] = {
|
|
name = "Locally Display Models",
|
|
toggle = tonumber(mod_storage_load("localModels")),
|
|
toggleSaveName = "localModels",
|
|
toggleDefault = 1,
|
|
toggleMax = 1,
|
|
},
|
|
[optionTableRef.prefToDefault] = {
|
|
name = "Set Preference to Default",
|
|
toggle = 0,
|
|
toggleDefault = 0,
|
|
toggleMax = 1,
|
|
toggleNames = {"", ""},
|
|
},
|
|
}
|
|
|
|
local defaultPlayerColors = {
|
|
[CT_MARIO] = {r = 255, g = 50, b = 50},
|
|
[CT_LUIGI] = {r = 50, g = 255, b = 50},
|
|
[CT_TOAD] = {r = 100, g = 100, b = 255},
|
|
[CT_WALUIGI] = {r = 130, g = 25, b = 130},
|
|
[CT_WARIO] = {r = 255, g = 255, b = 50},
|
|
}
|
|
|
|
local defaultIcons = {
|
|
[CT_MARIO] = gTextures.mario_head,
|
|
[CT_LUIGI] = gTextures.luigi_head,
|
|
[CT_TOAD] = gTextures.toad_head,
|
|
[CT_WALUIGI] = gTextures.waluigi_head,
|
|
[CT_WARIO] = gTextures.wario_head,
|
|
}
|
|
|
|
local latencyValueTable = {15, 10, 5}
|
|
|
|
local camera_freeze = camera_freeze
|
|
local camera_unfreeze = camera_unfreeze
|
|
local network_local_index_from_global = network_local_index_from_global
|
|
local obj_set_model_extended = obj_set_model_extended
|
|
local hud_hide = hud_hide
|
|
local hud_show = hud_show
|
|
local djui_chat_message_create = djui_chat_message_create
|
|
local djui_hud_set_resolution = djui_hud_set_resolution
|
|
local djui_hud_set_font = djui_hud_set_font
|
|
local djui_hud_set_color = djui_hud_set_color
|
|
local djui_hud_get_screen_width = djui_hud_get_screen_width
|
|
local djui_hud_render_rect = djui_hud_render_rect
|
|
local djui_hud_print_text = djui_hud_print_text
|
|
local djui_hud_render_texture = djui_hud_render_texture
|
|
local math_max = math.max
|
|
local math_min = math.min
|
|
local math_sin = math.sin
|
|
local math_random = math.random
|
|
local play_sound = play_sound
|
|
local mod_storage_save = mod_storage_save
|
|
local mod_storage_load = mod_storage_load
|
|
local string_lower = string.lower
|
|
|
|
---@param m MarioState
|
|
local function nullify_inputs(m)
|
|
local c = m.controller
|
|
_G.charSelect.controller = {
|
|
buttonDown = c.buttonDown,
|
|
buttonPressed = c.buttonPressed & ~_G.charSelect.controller.buttonDown,
|
|
extStickX = c.extStickX,
|
|
extStickY = c.extStickY,
|
|
rawStickX = c.rawStickX,
|
|
rawStickY = c.rawStickY,
|
|
stickMag = c.stickMag,
|
|
stickX = c.stickX,
|
|
stickY = c.stickY
|
|
}
|
|
c.buttonDown = 0
|
|
c.buttonPressed = 0
|
|
c.extStickX = 0
|
|
c.extStickY = 0
|
|
c.rawStickX = 0
|
|
c.rawStickY = 0
|
|
c.stickMag = 0
|
|
c.stickX = 0
|
|
c.stickY = 0
|
|
end
|
|
|
|
local function load_preferred_char()
|
|
if mod_storage_load("PrefChar") ~= nil and mod_storage_load("PrefChar") ~= "Default" then
|
|
for i = 2, #characterTable do
|
|
if characterTable[i].name == mod_storage_load("PrefChar") then
|
|
currChar = i
|
|
djui_popup_create('Character Select:\nYour Preferred Character\n"'..string_underscore_to_space(characterTable[i].name)..'"\nwas applied successfully!', 4)
|
|
break
|
|
end
|
|
end
|
|
elseif mod_storage_load("PrefChar") == nil then
|
|
mod_storage_save("PrefChar", "Default")
|
|
end
|
|
if #characterTable == 1 then
|
|
djui_popup_create("Character Select:\nNo Characters were Found", 2)
|
|
end
|
|
TEXT_PREF_LOAD = mod_storage_load("PrefChar")
|
|
end
|
|
|
|
local function failsafe_options()
|
|
for i = 1, #optionTable do
|
|
if optionTable[i].toggle == nil then
|
|
optionTable[i].toggle = optionTable[i].toggleDefault
|
|
if optionTable[i].toggleSaveName ~= nil then
|
|
mod_storage_save(optionTable[i].toggleSaveName, tostring(optionTable[i].toggle))
|
|
end
|
|
end
|
|
if optionTable[i].toggleNames == nil then
|
|
optionTable[i].toggleNames = {"Off", "On"}
|
|
end
|
|
end
|
|
if optionTable[optionTableRef.openInputs].toggle == 1 and ommActive then
|
|
djui_popup_create('Character Select:\nYour Open bind has changed to:\nD-pad Down + R\nDue to OMM Rebirth being active!', 4)
|
|
end
|
|
end
|
|
|
|
local hasOpenedMenu = false
|
|
|
|
local function idiot_proof_note()
|
|
if mod_storage_load("openedmenu") == nil then
|
|
if #characterTable > 1 then
|
|
djui_chat_message_create("Character Select is active and has "..(#characterTable - 1).." characters available!\nYou can use \\#ffff00\\/char-select \\#ffffff\\to open the menu!")
|
|
else
|
|
djui_chat_message_create("Character Select is active!\nYou can use \\#ffff00\\/char-select \\#ffffff\\to open the menu!")
|
|
end
|
|
else
|
|
hasOpenedMenu = true
|
|
end
|
|
end
|
|
|
|
-------------------
|
|
-- Model Handler --
|
|
-------------------
|
|
|
|
local stallFrame = 0
|
|
local noLoop = false
|
|
|
|
-- Respecfully, GO FUCK YOURSELVES. I hate EVERY SINGLE ONE OF YOU. Your lives are NOTHING. You serve ZERO PURPOSE. You should kill yourselves, NOW!
|
|
local ignored_surfaces = {
|
|
SURFACE_BURNING, SURFACE_QUICKSAND, SURFACE_INSTANT_QUICKSAND, SURFACE_INSTANT_MOVING_QUICKSAND, SURFACE_DEEP_MOVING_QUICKSAND, SURFACE_INSTANT_QUICKSAND, SURFACE_DEEP_QUICKSAND, SURFACE_SHALLOW_MOVING_QUICKSAND,
|
|
SURFACE_SHALLOW_QUICKSAND, SURFACE_WARP, SURFACE_LOOK_UP_WARP, SURFACE_WOBBLING_WARP, SURFACE_INSTANT_WARP_1B, SURFACE_INSTANT_WARP_1C, SURFACE_INSTANT_WARP_1D, SURFACE_INSTANT_WARP_1E
|
|
}
|
|
-- Yes, floral gave me permission to use this table full of USELESS PIECES OF SHITS
|
|
|
|
--- @param m MarioState
|
|
local function mario_update(m)
|
|
if stallFrame == 1 then
|
|
load_preferred_char()
|
|
failsafe_options()
|
|
idiot_proof_note()
|
|
end
|
|
|
|
if stallFrame < 2 then
|
|
stallFrame = stallFrame + 1
|
|
end
|
|
|
|
if m.playerIndex == 0 and stallFrame > 1 then
|
|
characterTable[1].forceChar = gNetworkPlayers[m.playerIndex].modelIndex
|
|
if currChar == 1 then
|
|
characterTable[1].color = defaultPlayerColors[gNetworkPlayers[m.playerIndex].modelIndex]
|
|
characterTable[1].lifeIcon = defaultIcons[gNetworkPlayers[m.playerIndex].modelIndex]
|
|
end
|
|
if optionTable[optionTableRef.localModels].toggle > 0 then
|
|
gPlayerSyncTable[0].modelId = characterTable[currChar].model
|
|
gPlayerSyncTable[0].capModels = characterTable[currChar].capModels
|
|
if characterTable[currChar].forceChar ~= nil then
|
|
gNetworkPlayers[m.playerIndex].overrideModelIndex = characterTable[currChar].forceChar
|
|
end
|
|
else
|
|
gPlayerSyncTable[0].modelId = nil
|
|
gPlayerSyncTable[0].capModels = nil
|
|
gNetworkPlayers[m.playerIndex].overrideModelIndex = characterTable[1].forceChar
|
|
end
|
|
|
|
if menu then
|
|
for _, func in pairs(allowMenu) do
|
|
if not func() then
|
|
menu = false
|
|
return
|
|
end
|
|
end
|
|
camera_freeze()
|
|
hud_hide()
|
|
if _G.PersonalStarCounter then
|
|
_G.PersonalStarCounter.hide_star_counters(true)
|
|
end
|
|
local focusPos = {
|
|
x = m.pos.x,
|
|
y = m.pos.y + 120,
|
|
z = m.pos.z,
|
|
}
|
|
vec3f_copy(gLakituState.focus, focusPos)
|
|
gLakituState.pos.x = m.pos.x + sins(m.faceAngle.y) * 500
|
|
gLakituState.pos.y = m.pos.y + 100
|
|
gLakituState.pos.z = m.pos.z + coss(m.faceAngle.y) * 500
|
|
|
|
if m.forwardVel == 0 and m.pos.y == m.floorHeight and not ignored_surfaces[m.floor.type] and m.health > 255 then
|
|
set_mario_action(m, ACT_IDLE, 0)
|
|
set_mario_animation(m, MARIO_ANIM_STAR_DANCE)
|
|
end
|
|
noLoop = false
|
|
elseif not noLoop then
|
|
camera_unfreeze()
|
|
hud_show()
|
|
if _G.PersonalStarCounter then
|
|
_G.PersonalStarCounter.hide_star_counters(false)
|
|
end
|
|
noLoop = true
|
|
end
|
|
end
|
|
|
|
--Set Pref to Default Check
|
|
if optionTable[optionTableRef.prefToDefault].toggle > 0 then
|
|
mod_storage_save("PrefChar", "Default")
|
|
TEXT_PREF_LOAD = "Default"
|
|
optionTable[optionTableRef.prefToDefault].toggle = 0
|
|
end
|
|
end
|
|
|
|
function set_model(o, model)
|
|
if obj_has_behavior_id(o, id_bhvMario) ~= 0 then
|
|
local i = network_local_index_from_global(o.globalPlayerIndex)
|
|
if gPlayerSyncTable[i].modelId ~= nil and obj_has_model_extended(o, gPlayerSyncTable[i].modelId) == 0 then
|
|
obj_set_model_extended(o, gPlayerSyncTable[i].modelId)
|
|
return
|
|
end
|
|
end
|
|
if get_object_list_from_behavior(o.behavior) == OBJ_LIST_LEVEL then
|
|
local i = network_local_index_from_global(o.globalPlayerIndex)
|
|
local capModels = gPlayerSyncTable[i].capModels
|
|
local capModel = nil
|
|
if capModels ~= nil then
|
|
if model == gMarioStates[i].character.capModelId then
|
|
capModel = capModels.normal
|
|
elseif model == gMarioStates[i].character.capWingModelId then
|
|
capModel = capModels.wing
|
|
elseif model == gMarioStates[i].character.capMetalModelId then
|
|
capModel = capModels.metal
|
|
elseif model == gMarioStates[i].character.capMetalWingModelId then
|
|
capModel = capModels.metalWing
|
|
end
|
|
if capModel ~= nil and obj_has_model_extended(o, capModel) == 0 then
|
|
obj_set_model_extended(o, capModel)
|
|
return
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
hook_event(HOOK_MARIO_UPDATE, mario_update)
|
|
hook_event(HOOK_OBJECT_SET_MODEL, set_model)
|
|
|
|
------------------
|
|
-- Menu Handler --
|
|
------------------
|
|
|
|
local buttonAnimTimer = 0
|
|
local buttonScroll = 0
|
|
local buttonScrollCap = 30
|
|
|
|
local optionAnimTimer = -200
|
|
local optionAnimTimerCap = optionAnimTimer
|
|
|
|
local inputStallTimer = 0
|
|
local inputStallTo = 15
|
|
|
|
local TEXT_OPTIONS_HEADER = "Menu Options"
|
|
local TEXT_RATIO_UNSUPPORTED = "Your Current Aspect-Ratio isn't Supported!"
|
|
local TEXT_DESCRIPTION = "Character Description:"
|
|
local TEXT_PREF_SAVE = "Press A to Set as Preferred Character"
|
|
local TEXT_PAUSE_Z_OPEN = "Z Button - Character Select"
|
|
local TEXT_PAUSE_CURR_CHAR = "Current Character: "
|
|
if math_random(100) == 64 then -- Easter Egg if you get lucky loading the mod >v<
|
|
TEXT_PAUSE_Z_OPEN = "Z - DynOS" -- Referencing the original sm64ex DynOS options
|
|
TEXT_PAUSE_CURR_CHAR = "Model: "
|
|
end
|
|
local TEXT_OPTIONS_OPEN = "Press START to open Options"
|
|
local TEXT_MENU_CLOSE = "Press B to Exit Menu"
|
|
local TEXT_OPTIONS_SELECT = "A - Select | B - Exit "
|
|
local TEXT_LOCAL_MODEL_OFF = "Locally Display Models is Off"
|
|
local TEXT_LOCAL_MODEL_OFF_OPTIONS = "You can turn it back on in the Options Menu"
|
|
|
|
local menuColor = characterTable[currChar].color
|
|
|
|
local function on_hud_render()
|
|
djui_hud_set_resolution(RESOLUTION_N64)
|
|
djui_hud_set_font(FONT_NORMAL)
|
|
|
|
local width = djui_hud_get_screen_width() + 1.4
|
|
local height = 240
|
|
local widthHalf = width*0.5
|
|
local heightHalf = height*0.5
|
|
local widthScale = math_max(width, 321.4)*0.00311332503
|
|
|
|
if menu then
|
|
if optionTable[optionTableRef.menuColor].toggle ~= 0 then
|
|
menuColor = menuColorTable[optionTable[optionTableRef.menuColor].toggle]
|
|
else
|
|
menuColor = characterTable[currChar].color
|
|
end
|
|
|
|
if optionTable[optionTableRef.localModels].toggle == 0 then
|
|
djui_hud_set_color(0, 0, 0, 200)
|
|
djui_hud_render_rect(0, 0, width, height)
|
|
djui_hud_set_color(255, 255, 255, 255)
|
|
djui_hud_print_text(TEXT_LOCAL_MODEL_OFF, widthHalf - djui_hud_measure_text(TEXT_LOCAL_MODEL_OFF)*0.15*widthScale, heightHalf, 0.3 * widthScale)
|
|
djui_hud_print_text(TEXT_LOCAL_MODEL_OFF_OPTIONS, widthHalf - djui_hud_measure_text(TEXT_LOCAL_MODEL_OFF_OPTIONS)*0.1*widthScale, heightHalf + 10*widthScale, 0.2*widthScale)
|
|
end
|
|
|
|
--Character Buttons
|
|
local x = 135 * widthScale * 0.8
|
|
djui_hud_set_color(menuColor.r, menuColor.g, menuColor.b, 255)
|
|
djui_hud_render_rect(0, 0, x, height)
|
|
djui_hud_set_color(0, 0, 0, 255)
|
|
djui_hud_render_rect(2, 2, x - 4, height - 4)
|
|
|
|
if optionTable[optionTableRef.anims].toggle > 0 then
|
|
buttonAnimTimer = buttonAnimTimer + 1
|
|
end
|
|
if optionTable[optionTableRef.anims].toggle == 0 then
|
|
buttonScroll = 0
|
|
elseif buttonScroll > 0.1 or buttonScroll < -0.1 then
|
|
buttonScroll = buttonScroll*0.03*inputStallTo
|
|
end
|
|
|
|
local buttonColor = {}
|
|
for i = -1, 4 do
|
|
if characterTable[i + currChar] ~= nil then
|
|
buttonColor = characterTable[i + currChar].color
|
|
djui_hud_set_color(buttonColor.r, buttonColor.g, buttonColor.b, 255)
|
|
local buttonX = 20 * widthScale
|
|
if optionTable[optionTableRef.anims].toggle > 0 then
|
|
if i == 0 then buttonX = buttonX + math_sin(buttonAnimTimer*0.05)*2.5 + 5 end
|
|
else
|
|
if i == 0 then buttonX = buttonX + 10 end
|
|
end
|
|
local y = (i + 3) * 30 + buttonScroll
|
|
djui_hud_render_rect(buttonX, y, 70, 20)
|
|
djui_hud_set_color(0, 0, 0, 255)
|
|
djui_hud_render_rect(buttonX + 1, y + 1, 68, 18)
|
|
djui_hud_set_font(FONT_TINY)
|
|
djui_hud_set_color(buttonColor.r, buttonColor.g, buttonColor.b, 255)
|
|
djui_hud_print_text(string_underscore_to_space(characterTable[currChar + i].name), buttonX + 5, y + 5, 0.6)
|
|
end
|
|
end
|
|
djui_hud_set_color(menuColor.r, menuColor.g, menuColor.b, 255)
|
|
djui_hud_render_rect(0, height-2, x, 2)
|
|
|
|
-- Scroll Bar
|
|
djui_hud_set_color(menuColor.r, menuColor.g, menuColor.b, 255)
|
|
djui_hud_render_rect(7 * widthScale, 55, 7, 180)
|
|
djui_hud_set_color(0, 0, 0, 255)
|
|
djui_hud_render_rect(7 * widthScale + 1, 56, 5, 178)
|
|
djui_hud_set_color(menuColor.r, menuColor.g, menuColor.b, 255)
|
|
djui_hud_render_rect(7 * widthScale + 2, 57 + 176 * ((currChar - 1) / #characterTable) - (buttonScroll*0.03333333333)*(176/#characterTable), 3, 176/#characterTable)
|
|
|
|
|
|
--Character Description
|
|
djui_hud_set_color(menuColor.r, menuColor.g, menuColor.b, 255)
|
|
djui_hud_render_rect(width - x, 0, x, height)
|
|
djui_hud_set_color(0, 0, 0, 255)
|
|
djui_hud_render_rect(width - x + 2, 2, x - 4, height - 4)
|
|
djui_hud_set_color(menuColor.r, menuColor.g, menuColor.b, 255)
|
|
djui_hud_set_font(FONT_NORMAL)
|
|
|
|
local TEXT_NAME = string_underscore_to_space(characterTable[currChar].name)
|
|
local TEXT_CREDIT = "By: "..characterTable[currChar].credit
|
|
local TEXT_DESCRIPTION_TABLE = characterTable[currChar].description
|
|
local TEXT_PREF = 'Preferred Character: "'..string_underscore_to_space(TEXT_PREF_LOAD)..'"'
|
|
|
|
local textX = x * 0.5
|
|
djui_hud_print_text(TEXT_NAME, width - textX - djui_hud_measure_text(TEXT_NAME)*0.3, 55, 0.6)
|
|
djui_hud_set_font(FONT_TINY)
|
|
djui_hud_print_text(TEXT_CREDIT, width - textX - djui_hud_measure_text(TEXT_CREDIT)*0.3, 72, 0.6)
|
|
djui_hud_set_font(FONT_NORMAL)
|
|
djui_hud_print_text(TEXT_DESCRIPTION, width - textX - djui_hud_measure_text(TEXT_DESCRIPTION)*0.2, 85, 0.4)
|
|
for i = 1, #TEXT_DESCRIPTION_TABLE do
|
|
djui_hud_print_text(TEXT_DESCRIPTION_TABLE[i], width - textX - djui_hud_measure_text(TEXT_DESCRIPTION_TABLE[i])*0.15, 90 + i*9, 0.3)
|
|
end
|
|
djui_hud_print_text(TEXT_PREF, width - textX - djui_hud_measure_text(TEXT_PREF)*0.15, height - 20, 0.3)
|
|
djui_hud_print_text(TEXT_PREF_SAVE, width - textX - djui_hud_measure_text(TEXT_PREF_SAVE)*0.15, height - 30, 0.3)
|
|
|
|
--Character Select Header
|
|
djui_hud_set_color(menuColor.r, menuColor.g, menuColor.b, 255)
|
|
djui_hud_render_rect(0, 0, width, 50)
|
|
djui_hud_set_color(0, 0, 0, 255)
|
|
djui_hud_render_rect(2, 2, width - 4, 46)
|
|
djui_hud_set_color(menuColor.r * 0.5 + 127, menuColor.g * 0.5 + 127, menuColor.b * 0.5 + 127, 255)
|
|
djui_hud_render_texture(TEX_HEADER, widthHalf - 128, 10, 1, 1)
|
|
djui_hud_set_color(menuColor.r, menuColor.g, menuColor.b, 255)
|
|
djui_hud_set_font(FONT_TINY)
|
|
djui_hud_print_text("Version: "..modVersion, 5, 3, 0.5)
|
|
--Unsupported Res Warning
|
|
if width < 321.2 or width > 575 then
|
|
djui_hud_print_text(TEXT_RATIO_UNSUPPORTED, 5, 39, 0.5)
|
|
end
|
|
|
|
--Options display
|
|
if options or optionAnimTimer > optionAnimTimerCap then
|
|
djui_hud_set_color(menuColor.r * 0.25, menuColor.g * 0.25, menuColor.b * 0.25, 205 + math_max(-200, optionAnimTimer))
|
|
djui_hud_render_rect(0, 0, width, height)
|
|
djui_hud_set_color(menuColor.r, menuColor.g, menuColor.b, 255)
|
|
djui_hud_render_rect(width*0.5 - 50 * widthScale, math.min(55 - optionAnimTimer, height - 25 * widthScale), 100 * widthScale, 200)
|
|
djui_hud_set_color(0, 0, 0, 255)
|
|
djui_hud_render_rect(width*0.5 - 50 * widthScale + 2, math.min(55 - optionAnimTimer + 2, height - 25 * widthScale + 2), 100 * widthScale - 4, 196)
|
|
djui_hud_set_color(menuColor.r, menuColor.g, menuColor.b, 255)
|
|
djui_hud_render_rect(width*0.5 - 50 * widthScale, height - 2, 100 * widthScale, 2)
|
|
djui_hud_set_font(FONT_NORMAL)
|
|
djui_hud_set_color(menuColor.r * 0.5 + 127, menuColor.g * 0.5 + 127, menuColor.b * 0.5 + 127, 255)
|
|
djui_hud_print_text(TEXT_OPTIONS_HEADER, widthHalf - djui_hud_measure_text(TEXT_OPTIONS_HEADER)*0.3*widthScale, 65 + optionAnimTimer * -1, 0.6*widthScale)
|
|
|
|
djui_hud_set_color(menuColor.r, menuColor.g, menuColor.b, 255)
|
|
for i = 1, #optionTable do
|
|
local toggleName = optionTable[i].name
|
|
local scale = 0.5
|
|
local yOffset = 70 + 10 * math_min(widthScale, 1.8) + i * 9 * math_min(widthScale, 1.8) - optionAnimTimer
|
|
if i == currOption then
|
|
djui_hud_set_font(FONT_NORMAL)
|
|
scale = 0.3
|
|
yOffset = yOffset - 1
|
|
if optionTable[i].toggleNames[optionTable[i].toggle + 1] ~= "" then
|
|
toggleName = "> " .. toggleName .. " - " .. optionTable[i].toggleNames[optionTable[i].toggle + 1]
|
|
else
|
|
toggleName = "> " .. toggleName
|
|
end
|
|
else
|
|
djui_hud_set_font(FONT_TINY)
|
|
end
|
|
scale = scale * math_min(widthScale, 1.8)
|
|
djui_hud_print_text(toggleName, widthHalf - djui_hud_measure_text(toggleName)*scale*0.5, yOffset, scale)
|
|
end
|
|
|
|
djui_hud_set_font(FONT_TINY)
|
|
djui_hud_print_text(TEXT_OPTIONS_SELECT, widthHalf - djui_hud_measure_text(TEXT_OPTIONS_SELECT)*0.3, height - 20 - optionAnimTimer, 0.6)
|
|
else
|
|
-- How to open options display
|
|
local widthScaleUnlimited = widthScale
|
|
local widthScale = math_min(widthScale, 1.42)
|
|
djui_hud_set_color(menuColor.r, menuColor.g, menuColor.b, 255)
|
|
djui_hud_render_rect(widthHalf - 50 * widthScaleUnlimited, height - 25 * widthScale, 100 * widthScaleUnlimited, 26 * widthScale)
|
|
djui_hud_set_color(0, 0, 0, 255)
|
|
djui_hud_render_rect(widthHalf - 50 * widthScaleUnlimited + 2, height - 25 * widthScale + 2, 100 * widthScaleUnlimited - 4, 22 * widthScale)
|
|
djui_hud_set_color(menuColor.r, menuColor.g, menuColor.b, 255)
|
|
djui_hud_render_rect(widthHalf - 50 * widthScaleUnlimited, height - 2, 100 * widthScaleUnlimited, 2)
|
|
djui_hud_set_font(FONT_NORMAL)
|
|
djui_hud_print_text(TEXT_OPTIONS_OPEN, widthHalf - djui_hud_measure_text(TEXT_OPTIONS_OPEN)*0.175 * widthScale, height - 23 * widthScale + optionAnimTimer + 202, 0.35 * widthScale)
|
|
djui_hud_set_font(FONT_TINY)
|
|
djui_hud_print_text(TEXT_MENU_CLOSE, widthHalf - djui_hud_measure_text(TEXT_MENU_CLOSE)*0.25 * widthScale, height - 13 * widthScale + optionAnimTimer + 202, 0.5 * widthScale)
|
|
end
|
|
|
|
-- Anim logic
|
|
if options then
|
|
if optionTable[optionTableRef.anims].toggle > 0 then
|
|
if optionAnimTimer < -1 then
|
|
optionAnimTimer = optionAnimTimer/1.1
|
|
end
|
|
else
|
|
optionAnimTimer = -1
|
|
end
|
|
else
|
|
if optionTable[optionTableRef.anims].toggle > 0 then
|
|
if optionAnimTimer > optionAnimTimerCap then
|
|
optionAnimTimer = optionAnimTimer*1.2
|
|
end
|
|
else
|
|
optionAnimTimer = optionAnimTimerCap
|
|
end
|
|
end
|
|
optionAnimTimer = math_max(optionAnimTimer, -200)
|
|
else
|
|
options = false
|
|
optionAnimTimer = optionAnimTimerCap
|
|
end
|
|
|
|
-- Info / Z Open Bind on Pause Menu
|
|
if is_game_paused() and not djui_hud_is_pause_menu_created() and gMarioStates[0].action ~= ACT_EXIT_LAND_SAVE_DIALOG then
|
|
local currCharY = 0
|
|
djui_hud_set_resolution(RESOLUTION_DJUI)
|
|
if optionTable[optionTableRef.openInputs].toggle == 2 then
|
|
currCharY = 27
|
|
local width = djui_hud_get_screen_width() - djui_hud_measure_text(TEXT_PAUSE_Z_OPEN)
|
|
djui_hud_set_font(FONT_NORMAL)
|
|
djui_hud_set_color(0, 0, 0, 255)
|
|
djui_hud_print_text(TEXT_PAUSE_Z_OPEN, width - 19, 17, 1)
|
|
djui_hud_set_color(255, 255, 255, 255)
|
|
djui_hud_print_text(TEXT_PAUSE_Z_OPEN, width - 20, 16, 1)
|
|
end
|
|
|
|
if optionTable[optionTableRef.localModels].toggle == 1 then
|
|
local charName = string_underscore_to_space(characterTable[currChar].name)
|
|
local TEXT_PAUSE_CURR_CHAR_WITH_NAME = TEXT_PAUSE_CURR_CHAR..charName
|
|
local width = djui_hud_get_screen_width() - djui_hud_measure_text(TEXT_PAUSE_CURR_CHAR_WITH_NAME)
|
|
local charColor = characterTable[currChar].color
|
|
djui_hud_set_font(FONT_NORMAL)
|
|
djui_hud_set_color(0, 0, 0, 255)
|
|
djui_hud_print_text(TEXT_PAUSE_CURR_CHAR_WITH_NAME, width - 19, 17 + currCharY, 1)
|
|
djui_hud_set_color(255, 255, 255, 255)
|
|
djui_hud_print_text(TEXT_PAUSE_CURR_CHAR, width - 20, 16 + currCharY, 1)
|
|
djui_hud_set_color(charColor.r, charColor.g, charColor.b, 255)
|
|
djui_hud_print_text(charName, djui_hud_get_screen_width() - djui_hud_measure_text(charName) - 20, 16 + currCharY, 1)
|
|
else
|
|
local width = djui_hud_get_screen_width() - djui_hud_measure_text(TEXT_LOCAL_MODEL_OFF)
|
|
djui_hud_set_font(FONT_NORMAL)
|
|
djui_hud_set_color(0, 0, 0, 255)
|
|
djui_hud_print_text(TEXT_LOCAL_MODEL_OFF, width - 19, 17 + currCharY, 1)
|
|
djui_hud_set_color(255, 255, 255, 255)
|
|
djui_hud_print_text(TEXT_LOCAL_MODEL_OFF, width - 20, 16 + currCharY, 1)
|
|
end
|
|
end
|
|
end
|
|
|
|
-- Custom life icon rendering (Thanks LuigiGamer)
|
|
function on_life_counter_render()
|
|
if obj_get_first_with_behavior_id(id_bhvActSelector) ~= nil then return end
|
|
-- Rendering settings --
|
|
djui_hud_set_font(FONT_HUD)
|
|
djui_hud_set_resolution(RESOLUTION_N64)
|
|
djui_hud_set_color(255, 255, 255, 255);
|
|
|
|
-- Texture scale --
|
|
|
|
-- Texture position --
|
|
local x = 22
|
|
local y = 15
|
|
|
|
-- Texture Rendering --
|
|
if gNetworkPlayers[0].currActNum == 99 then return end
|
|
if not hud_is_hidden() then
|
|
local icon = characterTable[currChar].lifeIcon
|
|
djui_hud_render_texture(icon, x, y, 1/(icon.width/16), 1/(icon.height/16))
|
|
djui_hud_print_text("@", x + 16, y, 1)
|
|
djui_hud_print_text(tostring(gMarioStates[0].numLives), x + 32, y, 1)
|
|
hud_set_value(HUD_DISPLAY_FLAGS, hud_get_value(HUD_DISPLAY_FLAGS) &~ HUD_DISPLAY_FLAG_LIVES) -- Hides the lives counter
|
|
else
|
|
hud_set_value(HUD_DISPLAY_FLAGS, hud_get_value(HUD_DISPLAY_FLAGS) | HUD_DISPLAY_FLAG_LIVES) -- Shows the lives counter, use this when you're no longer using a custom character
|
|
end
|
|
end
|
|
|
|
local function before_mario_update(m)
|
|
if m.playerIndex ~= 0 then return end
|
|
if inputStallTimer > 0 then inputStallTimer = inputStallTimer - 1 end
|
|
|
|
if menu and inputStallTo ~= latencyValueTable[optionTable[optionTableRef.inputLatency].toggle + 1] then
|
|
inputStallTo = latencyValueTable[optionTable[optionTableRef.inputLatency].toggle + 1]
|
|
end
|
|
|
|
-- Menu Inputs
|
|
if not menu and (m.controller.buttonDown & D_JPAD) ~= 0 and m.action ~= ACT_EXIT_LAND_SAVE_DIALOG and optionTable[optionTableRef.openInputs].toggle == 1 then
|
|
if ommActive then
|
|
if (m.controller.buttonDown & R_TRIG) ~= 0 then
|
|
menu = true
|
|
end
|
|
else
|
|
menu = true
|
|
end
|
|
inputStallTimer = inputStallTo
|
|
end
|
|
if is_game_paused() and m.action ~= ACT_EXIT_LAND_SAVE_DIALOG and (m.controller.buttonPressed & Z_TRIG) ~= 0 and optionTable[optionTableRef.openInputs].toggle == 2 then
|
|
menu = true
|
|
end
|
|
|
|
local cameraToObject = gMarioStates[0].marioObj.header.gfx.cameraToObject
|
|
|
|
-- C-up Failsafe (Camera Softlocks)
|
|
if m.action == ACT_FIRST_PERSON or (m.prevAction == ACT_FIRST_PERSON and is_game_paused()) then
|
|
menu = false
|
|
elseif m.prevAction == ACT_FIRST_PERSON and not is_game_paused() then
|
|
m.prevAction = ACT_WALKING
|
|
end
|
|
|
|
if gNetworkPlayers[0].currActNum == 99 then
|
|
menu = false
|
|
end
|
|
|
|
if menu and not options then
|
|
if inputStallTimer == 0 then
|
|
if (m.controller.buttonPressed & D_JPAD) ~= 0 then
|
|
currChar = currChar + 1
|
|
inputStallTimer = inputStallTo
|
|
buttonScroll = buttonScrollCap
|
|
play_sound(SOUND_MENU_MESSAGE_NEXT_PAGE, cameraToObject)
|
|
end
|
|
if (m.controller.buttonPressed & U_JPAD) ~= 0 then
|
|
currChar = currChar - 1
|
|
inputStallTimer = inputStallTo
|
|
buttonScroll = -buttonScrollCap
|
|
play_sound(SOUND_MENU_MESSAGE_NEXT_PAGE, cameraToObject)
|
|
end
|
|
if (m.controller.buttonPressed & D_CBUTTONS) ~= 0 then
|
|
currChar = currChar + 1
|
|
inputStallTimer = inputStallTo*0.6
|
|
buttonScroll = buttonScrollCap
|
|
play_sound(SOUND_MENU_MESSAGE_NEXT_PAGE, cameraToObject)
|
|
end
|
|
if (m.controller.buttonPressed & U_CBUTTONS) ~= 0 then
|
|
currChar = currChar - 1
|
|
inputStallTimer = inputStallTo*0.6
|
|
buttonScroll = -buttonScrollCap
|
|
play_sound(SOUND_MENU_MESSAGE_NEXT_PAGE, cameraToObject)
|
|
end
|
|
if m.controller.stickY < -60 then
|
|
currChar = currChar + 1
|
|
inputStallTimer = inputStallTo
|
|
buttonScroll = buttonScrollCap
|
|
play_sound(SOUND_MENU_MESSAGE_NEXT_PAGE, cameraToObject)
|
|
end
|
|
if m.controller.stickY > 60 then
|
|
currChar = currChar - 1
|
|
inputStallTimer = inputStallTo
|
|
buttonScroll = -buttonScrollCap
|
|
play_sound(SOUND_MENU_MESSAGE_NEXT_PAGE, cameraToObject)
|
|
end
|
|
if (m.controller.buttonPressed & A_BUTTON) ~= 0 then
|
|
if characterTable[currChar] ~= nil then
|
|
TEXT_PREF_LOAD = characterTable[currChar].name
|
|
mod_storage_save("PrefChar", TEXT_PREF_LOAD)
|
|
inputStallTimer = inputStallTo
|
|
play_sound(SOUND_MENU_CLICK_FILE_SELECT, cameraToObject)
|
|
else
|
|
play_sound(SOUND_MENU_CAMERA_BUZZ, cameraToObject)
|
|
end
|
|
end
|
|
if (m.controller.buttonPressed & B_BUTTON) ~= 0 then
|
|
menu = false
|
|
end
|
|
if (m.controller.buttonPressed & START_BUTTON) ~= 0 then
|
|
options = true
|
|
end
|
|
end
|
|
if currChar > #characterTable then currChar = 1 end
|
|
if currChar < 1 then currChar = #characterTable end
|
|
nullify_inputs(m)
|
|
if is_game_paused() then
|
|
m.controller.buttonPressed = START_BUTTON
|
|
end
|
|
|
|
-- Idiot Proof Check
|
|
if not hasOpenedMenu then
|
|
mod_storage_save("openedmenu", "youdidit")
|
|
hasOpenedMenu = true
|
|
end
|
|
end
|
|
|
|
if options then
|
|
if inputStallTimer == 0 then
|
|
if (m.controller.buttonPressed & D_JPAD) ~= 0 then
|
|
currOption = currOption + 1
|
|
inputStallTimer = inputStallTo
|
|
play_sound(SOUND_MENU_MESSAGE_NEXT_PAGE, cameraToObject)
|
|
end
|
|
if (m.controller.buttonPressed & U_JPAD) ~= 0 then
|
|
currOption = currOption - 1
|
|
inputStallTimer = inputStallTo
|
|
play_sound(SOUND_MENU_MESSAGE_NEXT_PAGE, cameraToObject)
|
|
end
|
|
if m.controller.stickY < -60 then
|
|
currOption = currOption + 1
|
|
inputStallTimer = inputStallTo
|
|
play_sound(SOUND_MENU_MESSAGE_NEXT_PAGE, cameraToObject)
|
|
end
|
|
if m.controller.stickY > 60 then
|
|
currOption = currOption - 1
|
|
inputStallTimer = inputStallTo
|
|
play_sound(SOUND_MENU_MESSAGE_NEXT_PAGE, cameraToObject)
|
|
end
|
|
if (m.controller.buttonPressed & A_BUTTON) ~= 0 then
|
|
optionTable[currOption].toggle = optionTable[currOption].toggle + 1
|
|
if optionTable[currOption].toggle > optionTable[currOption].toggleMax then optionTable[currOption].toggle = 0 end
|
|
if optionTable[currOption].toggleSaveName ~= nil then
|
|
mod_storage_save(optionTable[currOption].toggleSaveName, tostring(optionTable[currOption].toggle))
|
|
end
|
|
inputStallTimer = inputStallTo
|
|
play_sound(SOUND_MENU_CHANGE_SELECT, cameraToObject)
|
|
end
|
|
if (m.controller.buttonPressed & B_BUTTON) ~= 0 then
|
|
options = false
|
|
inputStallTimer = inputStallTo
|
|
end
|
|
end
|
|
if currOption > #optionTable then currOption = 1 end
|
|
if currOption < 1 then currOption = #optionTable end
|
|
nullify_inputs(m)
|
|
end
|
|
end
|
|
|
|
hook_event(HOOK_BEFORE_MARIO_UPDATE, before_mario_update)
|
|
hook_event(HOOK_ON_HUD_RENDER, on_hud_render)
|
|
hook_event(HOOK_ON_HUD_RENDER_BEHIND, on_life_counter_render)
|
|
|
|
--------------
|
|
-- Commands --
|
|
--------------
|
|
|
|
local function chat_command(msg)
|
|
if msg ~= "" then
|
|
msg = string_lower(msg)
|
|
for i = 1, #characterTable do
|
|
if msg == string_underscore_to_space(string_lower(characterTable[i].name)) then
|
|
currChar = i
|
|
return true
|
|
end
|
|
end
|
|
djui_chat_message_create("Character Not Found")
|
|
return true
|
|
else
|
|
menu = not menu
|
|
return true
|
|
end
|
|
end
|
|
|
|
hook_chat_command("char-select", "- Opens the Character Select Menu", chat_command) |