--Howdy there, Zenius-i-Vanisher! It's me, 48, that weirdo that made the stepfile!
--It's my first time releasing a modfile to the public, so I hope you enjoy!
--So Taronuke/WinDEU/probably others made this sick lua template file for Stepmania 3.9. I wanted to use SM 5, so I ported it with another dude, and the result of that is what you see now.
--Please PM me any bugs/issues with this file. Honestly I'm pretty new to SM lua in general and I probably still suck at it to some extent.
--I dunno what I'll end up doing with this file but I'll probably clean it up a bit and go throw it on the internet eventually for others to use as a template.
--That'd be pretty neat, wouldn't it?

--Well for now, I just wanna go enjoy some mods. Have fun!

--p.s. go join the UKSRT Discord server at http://discord.gg/Zt3DTb6, they're the guys that actually know what they're doing lmao


--Player Modifiers Table: Applies and removes modifiers to players at certain points in the song
local mods = { 
	{0, 9999, '*50 2.5x', 'end'},
	{0, 24, '25% Drunk, *50 No Beat', 'end'},
	{7.5, 8.5, '*50 -50% Beat', 'end'},
	{15.5, 16.5, '*50 -50% Beat', 'end'},
	{23.5, 24.5, '*50 -50% Beat', 'end'},
	{24.5, 27, '*50 15% Beat', 'end'},
	{28, 30, '*50 75% Square', 'end'},
	{30, 31, '*50 No Square', 'end'},
	{32, 60, '*50 50% Beat, *10 No Space, *50 No Sawtooth', 'end'},
	{38, 39, '*5 50% Space', 'end'},
	{39, 40, '*5 75% Space', 'end'},
	{46, 47, '*50 60% Sawtooth', 'end'},
	{47, 48, '*50 -60% Sawtooth', 'end'},
	{54, 55, '*5 50% Space', 'end'},
	{55, 56, '*5 75% Space', 'end'},
	{59.5, 64, '*50 No Beat, *10 No Invert, *10 No Drunk', 'end'},
	{60, 60.5, '*10 15% Invert', 'end'},
	{61, 61.5, '*10 -15% Invert', 'end'},
	{62, 63, '*2 Drunk', 'end'},
	{64, 92, '*10 50% Beat, *10 No Space, *50 No Sawtooth', 'end'},
	{70, 71, '*5 50% Space', 'end'},
	{71, 72, '*5 75% Space', 'end'},
	{78, 79, '*50 75% Sawtooth', 'end'},
	{79, 80, '*50 -75% Sawtooth', 'end'},
	{86, 87, '*5 50% Space', 'end'},
	{87, 88, '*5 75% Space', 'end'},
	{91.5, 95, '*50 No Beat, *10 No Invert, *10 No Drunk', 'end'},
	{92, 92.5, '*10 25% Invert', 'end'},
	{93, 93.5, '*10 -25% Invert', 'end'},
	{94, 95, '*3 Drunk', 'end'},
	{96, 108, '*5 50% Drunk, *5 10% Tipsy', 'end'},
	{111.5, 124, '*50 25% Beat', 'end'},
	{123.75, 124.25, '*5 15% BumpyX', 'end'},
	{124.25, 124.75, '*5 -15% BumpyX', 'end'},
	{124.75, 125.25, '*5 15% BumpyX', 'end'},
	{125.25, 125.75, '*5 -15% BumpyX', 'end'},
	{126, 127, '*5 -15% -35% BumpyX, *0.25 20% Reverse', 'end'},
	{126.5, 126.75, 'No Reverse', 'end'},
	{126.75, 127, '-10% Reverse', 'end'},
	{127, 127.25, 'No Reverse', 'end'},
	{127.25, 127.5, '-10% Reverse', 'end'},
	{127.5, 156, '*5 15% Beat', 'end'},
	{150.5, 150.75, '*5 30% MoveY4', 'end'},
	{150.75, 151, '*5 -30% MoveY4', 'end'},
	{151, 151.5, '*5 30% MoveY4', 'end'},
	{151.5, 152, '*5 No MoveY4', 'end'},
	{156, 156.75, '*5 20% XMode', 'end'},
	{156.75, 157.25, '*5 -20% XMode', 'end'},
	{157.5, 160, '*5 No XMode, *5 50% Drunk, *5 DrunkPeriod', 'end'},
	{160, 176, '*5 50% Drunk, *5 -50% DrunkPeriod', 'end'},
	{176, 190, '*5 15% Drunk, *5 No DrunkPeriod, *5 50% Beat', 'end'},
	{188, 191, '*0.3 -15% Reverse', 'end'},
	{191, 191.25, '*50 Beat, *5 No Reverse', 'end'},
	{192, 220, '*5 15% Drunk, *5 75% Beat, *8 No Space, *50 No XMode', 'end'},
	{198, 199, '*5 60% Space', 'end'},
	{199, 200, '*5 85% Space', 'end'},
	{206, 207, '*5 25% XMode', 'end'},
	{207, 208, '*5 -25% XMode', 'end'},
	{54, 55, '*5 50% Space', 'end'},
	{55, 56, '*5 75% Space', 'end'},
	{224, 228, '*5 50% Drunk, *5 -50% DrunkPeriod', 'end'},
}

--Mod Actions Table: Runs lua code and broadcasts messages at certain points in the song
local mod_actions = {
	{0,function() -- This first function just shows a system message 
		--SCREENMAN:SystemMessage('This is a message. Ignore this if you want to get a AAA.');
		end,true},
}


-- Track whether or not we want to make player 1/2 go insane (i.e. apply mods)
local modsEnabled = {false, false}

--Only apply mods if a player has joined and is playing the challenge chart
modsEnabled[1] = GAMESTATE:IsSideJoined(PLAYER_1) and GAMESTATE:GetCurrentSteps(PLAYER_1):GetDifficulty() == 'Difficulty_Challenge';
modsEnabled[2] = GAMESTATE:IsSideJoined(PLAYER_2) and GAMESTATE:GetCurrentSteps(PLAYER_2):GetDifficulty() == 'Difficulty_Challenge';

 --This function applies mods in modStr to the player number specified in plr (example: 1 or 2)
local function applyModsPlr(modStr, plr)
	--GAMESTATE:ApplyStageModifiers('PlayerNumber_P'..plr, modStr)
	local playerState= GAMESTATE:GetPlayerState('PlayerNumber_P' .. plr)
    local playerMods= playerState:GetPlayerOptionsString('ModsLevel_Song')
	--SCREENMAN:SystemMessage('Opt:' .. playerMods)
	playerMods = playerMods .. ', ' .. modStr
    playerState:SetPlayerOptions('ModsLevel_Song', playerMods)
	--SCREENMAN:SystemMessage('Opt:' .. playerMods) --DEBUG: Show currently active mods
end


--This function applies mods to both players by running the above function once for both players.
local function applyMods(modStr)
    for i=1,2 do
		if modsEnabled[i] then
			applyModsPlr(modStr, i)
		end
	end
end

return Def.ActorFrame{
	Name= "MainActorFrame",
	Def.Quad{ --KeepAliveActor: It's purpose is to sleep (if there aren't any actors doing stuff the script is killed). Sounds lovely, doesn't it?
		Name= "KeepAliveActor",
		InitCommand= cmd(visible,false),
		OnCommand= cmd(sleep,1000),
	},
	Def.Quad{ --MainActor: Most of the logic in this file is in this actor
		Name= "MainActor",
		InitCommand= function(self) --InitCommand: Run once
			mod_firstSeenBeat = GAMESTATE:GetSongBeat();
			curaction = 1; -- current action # from mod_actions
			function modtable_compare(a,b)
				return a[1] < b[1]
			end
			if table.getn(mod_actions) > 1 then
				table.sort(mod_actions, modtable_compare)
			end
			self:queuecommand('Update');
		end,
		OnCommand= cmd(visible,false),
		UpdateCommand= function(self) --UpdateCommand: Runs over and over again
			local beat = GAMESTATE:GetSongBeat()
			disable = false;
			if disable ~= true then
				if beat > mod_firstSeenBeat+0.1 then -- performance coding!!		
					applyMods('clearall') -- Player mod resets
					for i,v in pairs(mods) do --Iterate through all the mods in the mods table
						if v and table.getn(v) > 3 and v[1] and v[2] and v[3] and v[4] then --Check if all of the arguments for a mod were provided
							if beat >=v[1] then --It's after the start time for this mod!
								if (v[4] == 'len' and beat <=v[1]+v[2]) or (v[4] == 'end' and beat <=v[2]) then --The mod is still in effect, apply it!
									if table.getn(v) == 5 then --The argument for which player to set the mod for was specified, apply it to that player
										applyModsPlr(v[3], v[5])
									else --Otherwise just apply the mod to all players
										applyMods(v[3])
									end
								end
							end
						else --Didn't provide all of the arguments for a mod, clear it and throw an error
							v[1] = 0;
							v[2] = 0;
							v[3] = '';
							v[4] = 'error';
							SCREENMAN:SystemMessage('Bad mod in beat-based table (line '..i..')');
						end
					end
				while curaction<=table.getn(mod_actions) and GAMESTATE:GetSongBeat()>=mod_actions[curaction][1] do --Iterate through all the actions in the actions table
					if mod_actions[curaction][3] or GAMESTATE:GetSongBeat() < mod_actions[curaction][1]+2 then --It's time to apply an action!
						if type(mod_actions[curaction][2]) == 'function' then -- The action we're applying is a function, run it
							mod_actions[curaction][2]()
						elseif type(mod_actions[curaction][2]) == 'string' then --The action is a string, so broacast it as a message
							MESSAGEMAN:Broadcast(mod_actions[curaction][2]);
						end
					end
					curaction = curaction+1;
				end
			end
				
		end
		self:sleep(0.02);
		self:queuecommand('Update');
	end,
	},
}