532 lines
13 KiB
Haxe
532 lines
13 KiB
Haxe
package options;
|
|
|
|
import Controls;
|
|
import flixel.addons.ui.FlxUIInputText; // These are both for the search bars
|
|
import flixel.graphics.FlxGraphic;
|
|
import flixel.input.keyboard.FlxKey;
|
|
import flixel.ui.FlxButton;
|
|
|
|
class BaseOptionsMenu extends MusicBeatSubstate
|
|
{
|
|
private var curOption:Option = null;
|
|
private var curSelected:Int = 0;
|
|
private var optionsArray:Array<Option>;
|
|
|
|
private var grpOptions:FlxTypedGroup<Alphabet>;
|
|
private var checkboxGroup:FlxTypedGroup<CheckboxThingie>;
|
|
private var grpTexts:FlxTypedGroup<AttachedText>;
|
|
|
|
private var boyfriend:Character = null;
|
|
private var descBox:FlxSprite;
|
|
private var descText:FlxText;
|
|
|
|
var optionSearchText:FlxUIInputText;
|
|
var searchText:FlxText;
|
|
|
|
public var title:String;
|
|
public var rpcTitle:String;
|
|
|
|
public function new()
|
|
{
|
|
super();
|
|
|
|
if (title == null)
|
|
title = 'Options';
|
|
if (rpcTitle == null)
|
|
rpcTitle = 'Options Menu';
|
|
|
|
#if desktop
|
|
DiscordClient.changePresence(rpcTitle, null);
|
|
#end
|
|
|
|
var bg:FlxSprite = new FlxSprite().loadGraphic(Paths.image('menuDesat'));
|
|
bg.color = 0xFFea71fd;
|
|
bg.screenCenter();
|
|
bg.antialiasing = ClientPrefs.globalAntialiasing;
|
|
add(bg);
|
|
|
|
// avoids lagspikes while scrolling through menus!
|
|
grpOptions = new FlxTypedGroup<Alphabet>();
|
|
add(grpOptions);
|
|
|
|
grpTexts = new FlxTypedGroup<AttachedText>();
|
|
add(grpTexts);
|
|
|
|
checkboxGroup = new FlxTypedGroup<CheckboxThingie>();
|
|
add(checkboxGroup);
|
|
|
|
descBox = new FlxSprite().makeGraphic(1, 1, FlxColor.BLACK);
|
|
descBox.alpha = 0.6;
|
|
add(descBox);
|
|
|
|
var titleText:Alphabet = new Alphabet(75, 40, title, true);
|
|
titleText.scaleX = 0.6;
|
|
titleText.scaleY = 0.6;
|
|
titleText.alpha = 0.4;
|
|
add(titleText);
|
|
|
|
descText = new FlxText(50, 600, 1180, "", 32);
|
|
descText.setFormat(Paths.font("vcr.ttf"), 32, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK);
|
|
descText.scrollFactor.set();
|
|
descText.borderSize = 2.4;
|
|
add(descText);
|
|
|
|
for (i in 0...optionsArray.length)
|
|
{
|
|
var optionText:Alphabet = new Alphabet(290, 260, optionsArray[i].name, false);
|
|
optionText.isMenuItem = true;
|
|
/*optionText.forceX = 300;
|
|
optionText.yMult = 90; */
|
|
optionText.targetY = i;
|
|
grpOptions.add(optionText);
|
|
|
|
if (optionsArray[i].type == 'bool')
|
|
{
|
|
var checkbox:CheckboxThingie = new CheckboxThingie(optionText.x - 105, optionText.y, optionsArray[i].getValue() == true);
|
|
checkbox.sprTracker = optionText;
|
|
checkbox.ID = i;
|
|
checkboxGroup.add(checkbox);
|
|
}
|
|
else if (optionsArray[i].type != 'link')
|
|
{
|
|
optionText.x -= 80;
|
|
optionText.startPosition.x -= 80;
|
|
// optionText.xAdd -= 80;
|
|
var valueText:AttachedText = new AttachedText('' + optionsArray[i].getValue(), optionText.width + 80);
|
|
valueText.sprTracker = optionText;
|
|
valueText.copyAlpha = true;
|
|
valueText.ID = i;
|
|
grpTexts.add(valueText);
|
|
optionsArray[i].setChild(valueText);
|
|
}
|
|
// optionText.snapToPosition(); //Don't ignore me when i ask for not making a fucking pull request to uncomment this line ok
|
|
|
|
if (optionsArray[i].showBoyfriend && boyfriend == null)
|
|
{
|
|
reloadBoyfriend();
|
|
}
|
|
updateTextFrom(optionsArray[i]);
|
|
}
|
|
|
|
changeSelection();
|
|
reloadCheckboxes();
|
|
|
|
originalOptionsArray = optionsArray.copy();
|
|
|
|
optionSearchText = new FlxUIInputText(0, 0, 500, '', 16);
|
|
optionSearchText.x = FlxG.width - optionSearchText.width;
|
|
add(optionSearchText);
|
|
|
|
var buttonTop:FlxButton = new FlxButton(0, optionSearchText.y + optionSearchText.height + 5, "", function()
|
|
{
|
|
optionsSearch(optionSearchText.text);
|
|
});
|
|
buttonTop.setGraphicSize(Std.int(optionSearchText.width), 50);
|
|
buttonTop.updateHitbox();
|
|
buttonTop.label.setFormat(Paths.font("vcr.ttf"), 24, FlxColor.BLACK, RIGHT);
|
|
buttonTop.x = FlxG.width - buttonTop.width;
|
|
add(buttonTop);
|
|
|
|
searchText = new FlxText(975, buttonTop.y + 20, 100, "Search", 24);
|
|
searchText.setFormat(Paths.font("vcr.ttf"), 24, FlxColor.BLACK);
|
|
add(searchText);
|
|
FlxG.mouse.visible = true;
|
|
}
|
|
|
|
public function addOption(option:Option)
|
|
{
|
|
if (optionsArray == null || optionsArray.length < 1)
|
|
optionsArray = [];
|
|
optionsArray.push(option);
|
|
}
|
|
|
|
var originalOptionsArray:Array<Option> = [];
|
|
var optionsFound:Array<Option> = [];
|
|
|
|
function optionsSearch(?query:String = '')
|
|
{
|
|
optionsFound = [];
|
|
var foundOptions:Int = 0;
|
|
final txt:FlxText = new FlxText(0, 0, 0, 'No options found matching your query', 16);
|
|
txt.setFormat(Paths.font("vcr.ttf"), 16, FlxColor.WHITE, CENTER, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK);
|
|
txt.scrollFactor.set();
|
|
txt.screenCenter(XY);
|
|
for (i in 0...originalOptionsArray.length)
|
|
{
|
|
if (query != null && query.length > 0)
|
|
{
|
|
var optionName = originalOptionsArray[i].name.toLowerCase();
|
|
var q = query.toLowerCase();
|
|
if (optionName.indexOf(q) != -1)
|
|
{
|
|
optionsFound.push(originalOptionsArray[i]);
|
|
foundOptions++;
|
|
}
|
|
}
|
|
}
|
|
if (foundOptions > 0 || query.length <= 0)
|
|
{
|
|
if (txt != null)
|
|
remove(txt); // don't do destroy/kill on this btw
|
|
regenerateOptions(query);
|
|
}
|
|
else if (foundOptions <= 0)
|
|
{
|
|
add(txt);
|
|
new FlxTimer().start(3, function(timer)
|
|
{
|
|
if (txt != null)
|
|
remove(txt);
|
|
});
|
|
return;
|
|
}
|
|
}
|
|
|
|
function regenerateOptions(?query:String = '')
|
|
{
|
|
if (query.length > 0)
|
|
optionsArray = optionsFound;
|
|
else if (optionsArray != originalOptionsArray)
|
|
optionsArray = originalOptionsArray.copy();
|
|
regenList();
|
|
}
|
|
|
|
function regenList()
|
|
{
|
|
grpOptions.forEach(option ->
|
|
{
|
|
grpOptions.remove(option, true);
|
|
option.destroy();
|
|
});
|
|
grpTexts.forEach(text ->
|
|
{
|
|
grpTexts.remove(text, true);
|
|
text.destroy();
|
|
});
|
|
checkboxGroup.forEach(check ->
|
|
{
|
|
checkboxGroup.remove(check, true);
|
|
check.destroy();
|
|
});
|
|
|
|
// we clear the remaining ones
|
|
grpOptions.clear();
|
|
grpTexts.clear();
|
|
checkboxGroup.clear();
|
|
|
|
for (i in 0...optionsArray.length)
|
|
{
|
|
var optionText:Alphabet = new Alphabet(290, 260, optionsArray[i].name, false);
|
|
optionText.isMenuItem = true;
|
|
/*optionText.forceX = 300;
|
|
optionText.yMult = 90; */
|
|
optionText.targetY = i;
|
|
grpOptions.add(optionText);
|
|
|
|
if (optionsArray[i].type == 'bool')
|
|
{
|
|
var checkbox:CheckboxThingie = new CheckboxThingie(optionText.x - 105, optionText.y, optionsArray[i].getValue() == true);
|
|
checkbox.sprTracker = optionText;
|
|
checkbox.ID = i;
|
|
checkboxGroup.add(checkbox);
|
|
}
|
|
else if (optionsArray[i].type != 'link')
|
|
{
|
|
optionText.x -= 80;
|
|
optionText.startPosition.x -= 80;
|
|
// optionText.xAdd -= 80;
|
|
var valueText:AttachedText = new AttachedText('' + optionsArray[i].getValue(), optionText.width + 80);
|
|
valueText.sprTracker = optionText;
|
|
valueText.copyAlpha = true;
|
|
valueText.ID = i;
|
|
grpTexts.add(valueText);
|
|
optionsArray[i].setChild(valueText);
|
|
}
|
|
// optionText.snapToPosition(); //Don't ignore me when i ask for not making a fucking pull request to uncomment this line ok
|
|
|
|
if (optionsArray[i].showBoyfriend && boyfriend == null)
|
|
{
|
|
reloadBoyfriend();
|
|
}
|
|
updateTextFrom(optionsArray[i]);
|
|
}
|
|
|
|
changeSelection();
|
|
reloadCheckboxes();
|
|
}
|
|
|
|
var nextAccept:Int = 5;
|
|
var holdTime:Float = 0;
|
|
var holdValue:Float = 0;
|
|
|
|
override function update(elapsed:Float)
|
|
{
|
|
if (!optionSearchText.hasFocus)
|
|
{
|
|
if (controls.UI_UP_P)
|
|
{
|
|
changeSelection(-1);
|
|
}
|
|
if (controls.UI_DOWN_P)
|
|
{
|
|
changeSelection(1);
|
|
}
|
|
|
|
if (controls.BACK)
|
|
{
|
|
close();
|
|
FlxG.sound.play(Paths.sound('cancelMenu'));
|
|
}
|
|
|
|
if (nextAccept <= 0)
|
|
{
|
|
var usesCheckbox = true;
|
|
if (curOption.type != 'bool')
|
|
{
|
|
usesCheckbox = false;
|
|
}
|
|
|
|
if (usesCheckbox)
|
|
{
|
|
if (controls.ACCEPT)
|
|
{
|
|
FlxG.sound.play(Paths.sound((curOption.type == 'link' ? 'confirmMenu' : 'scrollMenu')));
|
|
if (curOption.type == 'bool')
|
|
curOption.setValue((curOption.getValue() == true) ? false : true);
|
|
curOption.change();
|
|
reloadCheckboxes();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (controls.UI_LEFT || controls.UI_RIGHT)
|
|
{
|
|
var pressed = (controls.UI_LEFT_P || controls.UI_RIGHT_P);
|
|
if (holdTime > 0.5 || pressed)
|
|
{
|
|
if (pressed)
|
|
{
|
|
var add:Dynamic = null;
|
|
if (curOption.type != 'string')
|
|
{
|
|
add = controls.UI_LEFT ? -curOption.changeValue : curOption.changeValue;
|
|
}
|
|
|
|
switch (curOption.type)
|
|
{
|
|
case 'int' | 'float' | 'percent':
|
|
holdValue = curOption.getValue() + add;
|
|
if (holdValue < curOption.minValue)
|
|
holdValue = curOption.minValue;
|
|
else if (holdValue > curOption.maxValue)
|
|
holdValue = curOption.maxValue;
|
|
|
|
switch (curOption.type)
|
|
{
|
|
case 'int':
|
|
holdValue = Math.round(holdValue);
|
|
curOption.setValue(holdValue);
|
|
|
|
case 'float' | 'percent':
|
|
holdValue = FlxMath.roundDecimal(holdValue, curOption.decimals);
|
|
curOption.setValue(holdValue);
|
|
}
|
|
|
|
case 'string':
|
|
var num:Int = curOption.curOption; // lol
|
|
if (controls.UI_LEFT_P)
|
|
--num;
|
|
else
|
|
num++;
|
|
|
|
if (num < 0)
|
|
{
|
|
num = curOption.options.length - 1;
|
|
}
|
|
else if (num >= curOption.options.length)
|
|
{
|
|
num = 0;
|
|
}
|
|
|
|
curOption.curOption = num;
|
|
curOption.setValue(curOption.options[num]); // lol
|
|
// trace(curOption.options[num]);
|
|
}
|
|
updateTextFrom(curOption);
|
|
curOption.change();
|
|
FlxG.sound.play(Paths.sound('scrollMenu'));
|
|
}
|
|
else if (curOption.type != 'string')
|
|
{
|
|
holdValue += curOption.scrollSpeed * elapsed * (controls.UI_LEFT ? -1 : 1);
|
|
if (holdValue < curOption.minValue)
|
|
holdValue = curOption.minValue;
|
|
else if (holdValue > curOption.maxValue)
|
|
holdValue = curOption.maxValue;
|
|
|
|
switch (curOption.type)
|
|
{
|
|
case 'int':
|
|
curOption.setValue(Math.round(holdValue));
|
|
|
|
case 'float' | 'percent':
|
|
curOption.setValue(FlxMath.roundDecimal(holdValue, curOption.decimals));
|
|
}
|
|
updateTextFrom(curOption);
|
|
curOption.change();
|
|
}
|
|
}
|
|
|
|
if (curOption.type != 'string')
|
|
{
|
|
holdTime += elapsed;
|
|
}
|
|
}
|
|
else if (controls.UI_LEFT_R || controls.UI_RIGHT_R)
|
|
{
|
|
clearHold();
|
|
}
|
|
}
|
|
|
|
if (controls.RESET)
|
|
{
|
|
if (!FlxG.keys.pressed.SHIFT)
|
|
{
|
|
var leOption:Option = optionsArray[curSelected];
|
|
leOption.setValue(leOption.defaultValue);
|
|
if (leOption.type != 'bool')
|
|
{
|
|
if (leOption.type == 'string')
|
|
{
|
|
leOption.curOption = leOption.options.indexOf(leOption.getValue());
|
|
}
|
|
updateTextFrom(leOption);
|
|
}
|
|
leOption.change();
|
|
}
|
|
else
|
|
for (i in 0...optionsArray.length)
|
|
{
|
|
var leOption:Option = optionsArray[i];
|
|
leOption.setValue(leOption.defaultValue);
|
|
if (leOption.type != 'bool')
|
|
{
|
|
if (leOption.type == 'string')
|
|
{
|
|
leOption.curOption = leOption.options.indexOf(leOption.getValue());
|
|
}
|
|
updateTextFrom(leOption);
|
|
}
|
|
leOption.change();
|
|
}
|
|
FlxG.sound.play(Paths.sound('cancelMenu'));
|
|
reloadCheckboxes();
|
|
}
|
|
}
|
|
}
|
|
|
|
if (boyfriend != null && boyfriend.animation.curAnim.finished)
|
|
{
|
|
boyfriend.dance();
|
|
}
|
|
|
|
if (nextAccept > 0)
|
|
{
|
|
nextAccept -= 1;
|
|
}
|
|
super.update(elapsed);
|
|
}
|
|
|
|
function updateTextFrom(option:Option)
|
|
{
|
|
var text:String = option.displayFormat;
|
|
var val:Dynamic = option.getValue();
|
|
if (option.type == 'percent')
|
|
val *= 100;
|
|
var def:Dynamic = option.defaultValue;
|
|
option.text = text.replace('%v', val).replace('%d', def);
|
|
}
|
|
|
|
function clearHold()
|
|
{
|
|
if (holdTime > 0.5)
|
|
{
|
|
FlxG.sound.play(Paths.sound('scrollMenu'));
|
|
}
|
|
holdTime = 0;
|
|
}
|
|
|
|
function changeSelection(change:Int = 0)
|
|
{
|
|
curSelected += change;
|
|
if (curSelected < 0)
|
|
curSelected = optionsArray.length - 1;
|
|
if (curSelected >= optionsArray.length)
|
|
curSelected = 0;
|
|
|
|
descText.text = optionsArray[curSelected].description;
|
|
descText.screenCenter(Y);
|
|
descText.y += 270;
|
|
|
|
var bullShit:Int = 0;
|
|
|
|
for (item in grpOptions.members)
|
|
{
|
|
item.targetY = bullShit - curSelected;
|
|
bullShit++;
|
|
|
|
item.alpha = 0.6;
|
|
if (item.targetY == 0)
|
|
{
|
|
item.alpha = 1;
|
|
}
|
|
}
|
|
for (text in grpTexts)
|
|
{
|
|
text.alpha = 0.6;
|
|
if (text.ID == curSelected)
|
|
{
|
|
text.alpha = 1;
|
|
}
|
|
}
|
|
|
|
descBox.setPosition(descText.x - 10, descText.y - 10);
|
|
descBox.setGraphicSize(Std.int(descText.width + 20), Std.int(descText.height + 25));
|
|
descBox.updateHitbox();
|
|
|
|
if (boyfriend != null)
|
|
{
|
|
boyfriend.visible = optionsArray[curSelected].showBoyfriend;
|
|
}
|
|
curOption = optionsArray[curSelected]; // shorter lol
|
|
FlxG.sound.play(Paths.sound('scrollMenu'));
|
|
}
|
|
|
|
public function reloadBoyfriend()
|
|
{
|
|
var wasVisible:Bool = false;
|
|
if (boyfriend != null)
|
|
{
|
|
wasVisible = boyfriend.visible;
|
|
boyfriend.kill();
|
|
remove(boyfriend);
|
|
boyfriend.destroy();
|
|
}
|
|
|
|
boyfriend = new Character(840, 170, 'bf', true);
|
|
boyfriend.setGraphicSize(Std.int(boyfriend.width * 0.75));
|
|
boyfriend.updateHitbox();
|
|
boyfriend.dance();
|
|
insert(1, boyfriend);
|
|
boyfriend.visible = wasVisible;
|
|
}
|
|
|
|
function reloadCheckboxes()
|
|
{
|
|
for (checkbox in checkboxGroup)
|
|
{
|
|
checkbox.daValue = (optionsArray[checkbox.ID].getValue() == true);
|
|
}
|
|
}
|
|
}
|