Skip to content

Instantly share code, notes, and snippets.

@itsMapleLeaf
Created September 20, 2016 00:25
Show Gist options
  • Save itsMapleLeaf/face9f2ffaddf21ecedd3d78f30ad9d2 to your computer and use it in GitHub Desktop.
Save itsMapleLeaf/face9f2ffaddf21ecedd3d78f30ad9d2 to your computer and use it in GitHub Desktop.
SM5 Mods
-- luacheck: globals Def GAMESTATE SCREENMAN
local DefaultMods = '4x, overhead, blind'
-- format: { <beat>, 'len' or 'end', <len or end time>, <mod string>, <player number (optional, if not here, applies to all players)> }
-- example: { 0, 'len', 9999, '*0.5 200% dizzy' }
local SongMods = {
-- ...
}
-- format: { <beat>, <command> }
local LuaMods = {
{78, 'Twirl'},
{96, 'ZoomOut'},
}
-- helper function to convert beats -> seconds
local function TimeInBeats(beats)
return 60 / 147 * beats
end
-- player for keeping tables for EZ access
local Players = {}
return Def.ActorFrame {
-- example commands
TwirlCommand = function (self)
Players[1]
:rotationy(-720)
:decelerate(TimeInBeats(2))
:addrotationy(720)
end,
ZoomOutCommand = function (self)
Players[1]:accelerate(TimeInBeats(23.5)):zoom(0):sleep(TimeInBeats(0.5)):zoom(1)
end,
-- DO NOT TOUCH ANY OF THIS UNLESS YOU KNOW WHAT YOU'RE DOING
InitCommand = function (self)
-- table to keep track of mods already finished
local completed = {}
-- for edit mode, go through and mark the ones already passed
-- if we don't do this, weird shit happens
for i, mod in ipairs(SongMods) do
local modbeat, paramtype, param, modstring = unpack(mod)
local modfinish = paramtype == 'end' and param
or paramtype == 'len' and modbeat + param
or error('invalid parameter type ' .. paramtype .. ' for mod #' .. i .. '(mod string: ' .. modstring .. ')')
if GAMESTATE:GetSongBeat() > modfinish then
completed[mod] = true
end
end
for _, mod in ipairs(LuaMods) do
local beat = unpack(mod)
if GAMESTATE:GetSongBeat() > beat then
completed[mod] = true
end
end
-- hOBOI
self:SetUpdateFunction(function()
local curbeat = GAMESTATE:GetSongBeat() + 0.08
local curmods = {}
for i=1, GAMESTATE:GetNumPlayersEnabled() do
curmods[i] = { DefaultMods }
end
for i, mod in ipairs(SongMods) do
if not completed[mod] then
local modbeat, paramtype, param, modstring, player = unpack(mod)
local modfinish = paramtype == 'end' and param
or paramtype == 'len' and modbeat + param
or error('invalid parameter type ' .. paramtype .. ' for mod #' .. i .. '(mod string: ' .. modstring .. ')') -- typos happen
if curbeat >= modbeat then
for p, playermods in ipairs(curmods) do
if player == nil or player == p then
table.insert(playermods, modstring)
end
end
if curbeat > modfinish then
completed[mod] = true
end
end
end
end
for p, playermods in ipairs(curmods) do
GAMESTATE:GetPlayerState('PlayerNumber_P' .. p):SetPlayerOptions('ModsLevel_Song', table.concat(playermods, ','))
end
-- this is significantly easier *sigh*
for _, mod in ipairs(LuaMods) do
local beat, command = unpack(mod)
if curbeat > beat and not completed[mod] then
self:playcommand(command, unpack(mod, 3))
completed[mod] = true
end
end
end)
end,
OnCommand = function (self)
table.insert(Players, SCREENMAN:GetTopScreen():GetChild('PlayerP1'))
table.insert(Players, SCREENMAN:GetTopScreen():GetChild('PlayerP2'))
-- because edit mode is so nice as to not name the playfields,
-- we have to grab them ourselves! ;)
for _, actor in ipairs(SCREENMAN:GetTopScreen():GetChild('')) do
if tostring(actor):find('Player') then
table.insert(Players, actor)
end
end
-- reset player state (for edit mode)
for _, player in ipairs(Players) do
player:stoptweening():zoom(1)
end
-- keep the FG change alive
self:sleep(9999)
end,
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment