Files
itgmania212121/Themes/_themekit-piu/BGAnimations/ScreenCustomOptionsList overlay/default.lua
T
2011-04-29 14:58:59 -04:00

384 lines
11 KiB
Lua

local PlayerIndexes = { PlayerNumber_P1 = 1, PlayerNumber_P2 = 1 }
-- Reads mods from a file
-- keywords: Speed, Noteskins, None, Clear
local function ReadMods()
local file = THEME:GetCurrentThemeDirectory() .. "mods.txt"
local mods = File.Read( file )
if not mods
or mods == ""
then
local buff = ";Set mods here, one per line or various in one separated with commas\r\n;Keywords: 'Speed', 'Noteskins', 'None', 'Clear'\r\nSpeeds\r\nNoteskins"
File.Write(file,buff)
return {
ReadSpeedMods();
NOTESKIN:GetNoteSkinNames();
"Clear";
}
end
mods = string.gsub(mods,"\r","")
mods = split("\n",mods)
local ret = {}
local clear = false
for k,v in ipairs(mods) do
if string.sub(v,1,1) == ";"
or v == ""
then
--skip
elseif v == "Speeds" then
table.insert(ret, ReadSpeedMods())
elseif v == "Noteskins" then
table.insert(ret, NOTESKIN:GetNoteSkinNames())
else
local ModToAdd = string.gsub(v,"%s","")
if string.find(ModToAdd, ",") ~= nil then
ModToAdd = split(",", ModToAdd)
if ModToAdd[1] ~= "None" then
table.insert(ModToAdd,1,"None")
end
table.insert(ret,ModToAdd)
else
if ModToAdd == "Clear" then
if not clear then table.insert(ret,ModToAdd) end
clear = true
end
end
end
end
-- This will happen...
if not clear then table.insert(ret,"Clear") end
return ret
end
local modslist = ReadMods()
-- Displays the mods with actorscrollers
local function OptionsListDisplay(player)
local function GetPlayerMods()
local playerstate = GAMESTATE:GetPlayerState(player)
local playermods = playerstate:GetPlayerOptionsArray('ModsLevel_Preferred')
return playermods
end
local make = {}
-- iterate modslist entries
for k,v in ipairs(modslist) do
-- not kinopio
local RowToAdd
if type(v) == "table" then
-- it's a table, make it a scroller
local choices = {}
-- build the choices
for i,j in ipairs(v) do
choices[i] = LoadFont()..{ Text=j };
end
RowToAdd = Def.ActorScroller {
NumItemsToDraw=3;
SecondsPerItem=0.075;
-- init indexes here
-- I like how InitCommand is not allowed to be played or queued
-- (HURR TOO MUCH COMMANDS ARG!)
SetChoicesCommand=function(self)
local found = false
--SCREENMAN:SystemMessage(join(",", defmods))
for idx,Mod in ipairs(GetPlayerMods()) do
-- In before I forgot what's this: those are the nod entries
for jdx,Nod in ipairs(v) do
if Mod == Nod then
found = true
self:SetCurrentAndDestinationItem(jdx-1);
break
end
end
end
-- oops, no defaults, set them
if not found then
for idx,Mod in ipairs(v) do
if Mod == "1x"
or Mod == "default"
or Mod == "None"
then
self:SetCurrentAndDestinationItem(idx-1);
break
else
self:SetCurrentAndDestinationItem(0);
end
end
end
end;
CleanModsMessageCommand=function(self,params)
if player ~= params.PlayerNumber then return end
self:playcommand("SetChoices");
end;
InitCommand=function(self)
self:SetLoop(true);
self:playcommand("SetChoices");
end;
TransformFunction=function(self, offset, itemIndex, numItems)
self:x(offset * 100);
local focus = math.abs(offset)
focus = scale(focus,0,1,1,0.75)
self:zoom(focus)
end;
ChoiceSwapMessageCommand=function(self,params)
if params.PlayerNumber ~= player then return end
if params.Row ~= k then return end
local index = params.Index
--SCREENMAN:SystemMessage(ToEnumShortString(player).." row mods index: "..index);
if params.bHasLooped then
self:SetCurrentAndDestinationItem(-1)
end
self:SetDestinationItem(index-1)
end;
-- actors are wrapped here:
children = choices;
};
elseif type(v) == "string" then
-- it's not, make single switchable choice
RowToAdd = Def.ActorFrame {
LoadFont()..{
Text=v;
-- init highlights here
SetChoicesCommand=function(self)
local cc = color("#000000")
for idx,Mod in ipairs(GetPlayerMods()) do
if Mod == v then
cc = color("#ffffff")
break
end
end
if v == "Clear" then
cc = color("#0000ff")
end
self:diffuse(cc);
end;
InitCommand=function(self)
self:playcommand("SetChoices");
end;
-- Following commands you'll understand (I've heard that somewhere...)
CleanModsMessageCommand=function(self,params)
--if v == "Clear" then return end
if player ~= params.PlayerNumber then return end
self:playcommand("SetChoices");
--self:diffuse(color("#000000"));
end;
-- cmd(diffuse,color("#000000"));
ChoiceToggleMessageCommand=function(self,params)
if params.PlayerNumber ~= player then return end
if params.Row ~= k then return end
local cc = color("#ffffff")
if not params.Activated then
cc = color("#000000")
end
--self:visible(params.Activated)
-- why the fuck is not coloring itself? oh I think I got it... duh!
self:diffuse(cc)
end;
}
}
else
--table.remove(modslist,k)
--Def.Actor { };
end
make[k] = RowToAdd
end
return Def.ActorFrame {
Draw.RoundBox(300,320,50,50,color("1,0,1,0.5"));
Draw.RoundBox(300,50,25,25,color("1,0,0,0.5"));
Def.ActorScroller {
Name="OptionsListScroller";
NumItemsToDraw=5;
SecondsPerItem=0.075;
InitCommand=function(self)
self:SetLoop(true);
end;
TransformFunction=function(self, offset, itemIndex, numItems)
self:y(offset * 50);
end;
children = make;
};
}
end
-- Internals
return Def.ActorFrame {
OptionsListDisplay(PLAYER_1)..{
Name="OptionsListDisplay"..PLAYER_1;
Condition=GAMESTATE:IsHumanPlayer(PLAYER_1);
InitCommand=function(self)
if #GAMESTATE:GetHumanPlayers() == 1
and PREFSMAN:GetPreference("Center1Player")
then
self:CenterX()
else
self:FromLeft(160)
end
self:CenterY();
end;
};
OptionsListDisplay(PLAYER_2)..{
Name="OptionsListDisplay"..PLAYER_2;
Condition=GAMESTATE:IsHumanPlayer(PLAYER_2);
InitCommand=function(self)
if #GAMESTATE:GetHumanPlayers() == 1
and PREFSMAN:GetPreference("Center1Player")
then
self:CenterX()
else
self:FromRight(-160)
end
self:CenterY();
end;
};
-- Everything here and beyond is pure magic
CodeMessageCommand=function(self,params)
-- I'm reusing code from CustomCodeDetector
local code = params.Name
local player = params.PlayerNumber
local movement = "none"
local modscleared = false
if not GAMESTATE:IsHumanPlayer(player) then return end;
if code == "Back" then
--SCREENMAN:SystemMessage(ToEnumShortString(player).." closed the oplist")
SCREENMAN:GetTopScreen():Cancel();
elseif code == "Prev" then
PlayerIndexes[player] = PlayerIndexes[player]-1
if PlayerIndexes[player] < 1 then
PlayerIndexes[player] = #modslist
movement = "first"
end
--SCREENMAN:SystemMessage(ToEnumShortString(player).." index: "..PlayerIndexes[player]);
elseif code == "Next" then
PlayerIndexes[player] = PlayerIndexes[player]+1
if PlayerIndexes[player] > #modslist then
PlayerIndexes[player] = 1
movement = "last"
end
--SCREENMAN:SystemMessage(ToEnumShortString(player).." index: "..PlayerIndexes[player]);
elseif code == "Toggle" then
-- changes will be done here
-- get playerstate and playermods
local playerstate = GAMESTATE:GetPlayerState(player)
local playermods = playerstate:GetPlayerOptionsArray('ModsLevel_Preferred')
-- let's check in what index we are
local ModToAdd = modslist[PlayerIndexes[player]]
--the mod is a table, scroll those
if type(ModToAdd) == "table" then
-- iteration, once again, like in the custom code detector I made :x
local index = 1
local found = false
local looped = false
for i,j in ipairs(playermods) do
for k,l in ipairs(ModToAdd) do
if j == l then
found = true
index = k+1
if index > #ModToAdd then
index = 1
looped = true
end
--replace
playermods[i] = ModToAdd[index]
break
end
end
end
-- looks like nothing was found, we can assume those are the default mods
-- (1x and default noteskin) they are not listed for some reason...
if not found then
-- set the first on the list (nono, better list 1x and default)
for k,v in ipairs(ModToAdd) do
if v == "1x"
or v == "default"
then
index = k+1
if index > #ModToAdd then
index = 1
looped = true
end
table.insert(playermods, ModToAdd[index])
break
elseif v == "None" then
table.insert(playermods, ModToAdd[2])
index = 2
end
end
end
-- send message broadcasts to be able to move things on the oplist displays
MESSAGEMAN:Broadcast("ChoiceSwap",{ Row = PlayerIndexes[player]; Index = index; PlayerNumber = player; bHasLooped = looped })
elseif ModToAdd == "Clear" then
local defaultmods = PREFSMAN:GetPreference("DefaultModifiers")
playermods = split(",", defaultmods)
modscleared = true
--MESSAGEMAN:Broadcast("CleanMods",{ PlayerNumber = player });
else
-- if type(ModToAdd) == "string" then end
-- we know it's a string...
local found = false
for i,j in ipairs(playermods) do
if j == ModToAdd then
-- remove it
found = true
table.remove(playermods, i)
break
end
end
if not found then
table.insert(playermods, ModToAdd)
end
MESSAGEMAN:Broadcast("ChoiceToggle",{ Row = PlayerIndexes[player]; Activated = not found; PlayerNumber = player })
end
-- let's check if noteskins aren't missing (we're avoiding crashes here...)
local found = false
-- iterate again uh
for i,j in ipairs(playermods) do
-- yes because noteskins are stored in the second slot...
for k,l in ipairs(modslist[2]) do
if j == l then
found = true
break
end
end
end
-- apparently there aren't any noteskins...
if not found then
table.insert(playermods, "default")
end
-- everything is ready to be set
playermods = join(", ",playermods)
playerstate:SetPlayerOptions('ModsLevel_Preferred',playermods)
-- and thats pretty much it :D
end
if modscleared then
MESSAGEMAN:Broadcast("CleanMods",{ PlayerNumber = player });
end
--this moves the scroller...
local scroller = self:GetChild("OptionsListDisplay"..player):GetChild("OptionsListScroller")
if movement ~= "none" then
local tomove
if movement == "first" then
tomove = PlayerIndexes[player]
elseif movement == "last" then
tomove = PlayerIndexes[player]-2
end
scroller:SetCurrentAndDestinationItem(tomove);
end
scroller:SetDestinationItem(PlayerIndexes[player]-1);
end;
};