1
0
Fork 0
mirror of https://github.com/ninjamuffin99/Funkin.git synced 2024-09-12 05:07:06 +00:00

Rewrote code for preferences to use Save data.

This commit is contained in:
EliteMasterEric 2023-10-04 11:40:55 -04:00
parent 490b2f18d0
commit 380d30d63f
14 changed files with 237 additions and 158 deletions

View file

@ -85,6 +85,13 @@ class Main extends Sprite
initHaxeUI();
fpsCounter = new FPS(10, 3, 0xFFFFFF);
// addChild(fpsCounter); // Handled by Preferences.init
#if !html5
memoryCounter = new MemoryCounter(10, 13, 0xFFFFFF);
// addChild(memoryCounter);
#end
// George recommends binding the save before FlxGame is created.
Save.load();
@ -93,15 +100,6 @@ class Main extends Sprite
#if hxcpp_debug_server
trace('hxcpp_debug_server is enabled! You can now connect to the game with a debugger.');
#end
#if debug
fpsCounter = new FPS(10, 3, 0xFFFFFF);
addChild(fpsCounter);
#if !html5
memoryCounter = new MemoryCounter(10, 13, 0xFFFFFF);
addChild(memoryCounter);
#end
#end
}
function initHaxeUI():Void

View file

@ -48,7 +48,7 @@ class InitState extends FlxState
// loadSaveData(); // Moved to Main.hx
// Load player options from save data.
PreferencesMenu.initPrefs();
Preferences.init();
// Load controls from save data.
PlayerSettings.init();

View file

@ -13,23 +13,13 @@ import flixel.input.touch.FlxTouch;
import flixel.text.FlxText;
import flixel.tweens.FlxEase;
import flixel.tweens.FlxTween;
import flixel.util.FlxColor;
import flixel.util.FlxTimer;
import funkin.NGio;
import funkin.modding.events.ScriptEvent.UpdateScriptEvent;
import funkin.modding.module.ModuleHandler;
import funkin.shaderslmfao.ScreenWipeShader;
import funkin.ui.AtlasMenuList;
import funkin.ui.MenuList.MenuItem;
import funkin.ui.MenuList;
import funkin.ui.title.TitleState;
import funkin.ui.story.StoryMenuState;
import funkin.ui.OptionsState;
import funkin.ui.PreferencesMenu;
import funkin.ui.Prompt;
import funkin.util.WindowUtil;
import lime.app.Application;
import openfl.filters.ShaderFilter;
#if discord_rpc
import Discord.DiscordClient;
#end
@ -82,8 +72,10 @@ class MainMenuState extends MusicBeatState
magenta.y = bg.y;
magenta.visible = false;
magenta.color = 0xFFfd719b;
if (PreferencesMenu.preferences.get('flashing-menu')) add(magenta);
// magenta.scrollFactor.set();
// TODO: Why doesn't this line compile I'm going fucking feral
if (Preferences.flashingLights) add(magenta);
menuItems = new MenuTypedList<AtlasMenuItem>();
add(menuItems);
@ -116,7 +108,7 @@ class MainMenuState extends MusicBeatState
#end
createMenuItem('options', 'mainmenu/options', function() {
startExitState(new OptionsState());
startExitState(new funkin.ui.OptionsState());
});
// Reset position of menu items.

View file

@ -0,0 +1,138 @@
package funkin;
import funkin.save.Save;
/**
* A store of user-configurable, globally relevant values.
*/
class Preferences
{
/**
* Whether some particularly fowl language is displayed.
* @default `true`
*/
public static var naughtyness(get, set):Bool;
static function get_naughtyness():Bool
{
return Save.get().options.naughtyness;
}
static function set_naughtyness(value:Bool):Bool
{
return Save.get().options.naughtyness = value;
}
/**
* If enabled, the strumline is at the bottom of the screen rather than the top.
* @default `false`
*/
public static var downscroll(get, set):Bool;
static function get_downscroll():Bool
{
return Save.get().options.downscroll;
}
static function set_downscroll(value:Bool):Bool
{
return Save.get().options.downscroll = value;
}
/**
* If disabled, flashing lights in the main menu and other areas will be less intense.
* @default `true`
*/
public static var flashingLights(get, set):Bool;
static function get_flashingLights():Bool
{
return Save.get().options.flashingLights;
}
static function set_flashingLights(value:Bool):Bool
{
return Save.get().options.flashingLights = value;
}
/**
* If disabled, the camera bump synchronized to the beat.
* @default `false`
*/
public static var zoomCamera(get, set):Bool;
static function get_zoomCamera():Bool
{
return Save.get().options.zoomCamera;
}
static function set_zoomCamera(value:Bool):Bool
{
return Save.get().options.zoomCamera = value;
}
/**
* If enabled, an FPS and memory counter will be displayed even if this is not a debug build.
* @default `false`
*/
public static var debugDisplay(get, set):Bool;
static function get_debugDisplay():Bool
{
return Save.get().options.debugDisplay;
}
static function set_debugDisplay(value:Bool):Bool
{
if (value != Save.get().options.debugDisplay)
{
toggleDebugDisplay(value);
}
return Save.get().options.debugDisplay = value;
}
/**
* If enabled, the game will automatically pause when tabbing out.
* @default `true`
*/
public static var autoPause(get, set):Bool;
static function get_autoPause():Bool
{
return Save.get().options.autoPause;
}
static function set_autoPause(value:Bool):Bool
{
if (value != Save.get().options.autoPause) FlxG.autoPause = value;
return Save.get().options.autoPause = value;
}
public static function init():Void
{
FlxG.autoPause = Preferences.autoPause;
toggleDebugDisplay(Preferences.debugDisplay);
}
static function toggleDebugDisplay(show:Bool):Void
{
if (show)
{
// Enable the debug display.
FlxG.stage.addChild(Main.fpsCounter);
#if !html5
FlxG.stage.addChild(Main.memoryCounter);
#end
}
else
{
// Disable the debug display.
FlxG.stage.removeChild(Main.fpsCounter);
#if !html5
FlxG.stage.removeChild(Main.memoryCounter);
#end
}
}
}

View file

@ -7,7 +7,6 @@ import flixel.graphics.frames.FlxAtlasFrames;
import flixel.group.FlxSpriteGroup.FlxTypedSpriteGroup;
import flixel.math.FlxMath;
import flixel.sound.FlxSound;
import funkin.ui.PreferencesMenu.CheckboxThingie;
using Lambda;

View file

@ -4,6 +4,7 @@ package;
// Only import these when we aren't in a macro.
import funkin.util.Constants;
import funkin.Paths;
import funkin.Preferences;
import flixel.FlxG; // This one in particular causes a compile error if you're using macros.
// These are great.

View file

@ -11,7 +11,6 @@ import funkin.modding.events.ScriptEvent;
import funkin.modding.events.ScriptEventDispatcher;
import funkin.play.PlayState;
import funkin.play.character.BaseCharacter;
import funkin.ui.PreferencesMenu;
/**
* A substate which renders over the PlayState when the player dies.
@ -292,7 +291,7 @@ class GameOverSubState extends MusicBeatSubState
{
var randomCensor:Array<Int> = [];
if (PreferencesMenu.getPref('censor-naughty')) randomCensor = [1, 3, 8, 13, 17, 21];
if (!Preferences.naughtyness) randomCensor = [1, 3, 8, 13, 17, 21];
FlxG.sound.play(Paths.sound('jeffGameover/jeffGameover-' + FlxG.random.int(1, 25, randomCensor)), 1, false, null, true, function() {
// Once the quote ends, fade in the game over music.

View file

@ -1257,7 +1257,7 @@ class PlayState extends MusicBeatSubState
*/
function initHealthBar():Void
{
var healthBarYPos:Float = PreferencesMenu.getPref('downscroll') ? FlxG.height * 0.1 : FlxG.height * 0.9;
var healthBarYPos:Float = Preferences.downscroll ? FlxG.height * 0.1 : FlxG.height * 0.9;
healthBarBG = new FlxSprite(0, healthBarYPos).loadGraphic(Paths.image('healthBar'));
healthBarBG.screenCenter(X);
healthBarBG.scrollFactor.set(0, 0);
@ -1480,13 +1480,13 @@ class PlayState extends MusicBeatSubState
// Position the player strumline on the right half of the screen
playerStrumline.x = FlxG.width / 2 + Constants.STRUMLINE_X_OFFSET; // Classic style
// playerStrumline.x = FlxG.width - playerStrumline.width - Constants.STRUMLINE_X_OFFSET; // Centered style
playerStrumline.y = PreferencesMenu.getPref('downscroll') ? FlxG.height - playerStrumline.height - Constants.STRUMLINE_Y_OFFSET : Constants.STRUMLINE_Y_OFFSET;
playerStrumline.y = Preferences.downscroll ? FlxG.height - playerStrumline.height - Constants.STRUMLINE_Y_OFFSET : Constants.STRUMLINE_Y_OFFSET;
playerStrumline.zIndex = 200;
playerStrumline.cameras = [camHUD];
// Position the opponent strumline on the left half of the screen
opponentStrumline.x = Constants.STRUMLINE_X_OFFSET;
opponentStrumline.y = PreferencesMenu.getPref('downscroll') ? FlxG.height - opponentStrumline.height - Constants.STRUMLINE_Y_OFFSET : Constants.STRUMLINE_Y_OFFSET;
opponentStrumline.y = Preferences.downscroll ? FlxG.height - opponentStrumline.height - Constants.STRUMLINE_Y_OFFSET : Constants.STRUMLINE_Y_OFFSET;
opponentStrumline.zIndex = 100;
opponentStrumline.cameras = [camHUD];

View file

@ -231,7 +231,7 @@ class Strumline extends FlxSpriteGroup
notesVwoosh.add(note);
var targetY:Float = FlxG.height + note.y;
if (PreferencesMenu.getPref('downscroll')) targetY = 0 - note.height;
if (Preferences.downscroll) targetY = 0 - note.height;
FlxTween.tween(note, {y: targetY}, 0.5,
{
ease: FlxEase.expoIn,
@ -252,7 +252,7 @@ class Strumline extends FlxSpriteGroup
holdNotesVwoosh.add(holdNote);
var targetY:Float = FlxG.height + holdNote.y;
if (PreferencesMenu.getPref('downscroll')) targetY = 0 - holdNote.height;
if (Preferences.downscroll) targetY = 0 - holdNote.height;
FlxTween.tween(holdNote, {y: targetY}, 0.5,
{
ease: FlxEase.expoIn,
@ -277,7 +277,7 @@ class Strumline extends FlxSpriteGroup
var vwoosh:Float = (strumTime < Conductor.songPosition) && vwoosh ? 2.0 : 1.0;
var scrollSpeed:Float = PlayState.instance?.currentChart?.scrollSpeed ?? 1.0;
return Constants.PIXELS_PER_MS * (Conductor.songPosition - strumTime) * scrollSpeed * vwoosh * (PreferencesMenu.getPref('downscroll') ? 1 : -1);
return Constants.PIXELS_PER_MS * (Conductor.songPosition - strumTime) * scrollSpeed * vwoosh * (Preferences.downscroll ? 1 : -1);
}
function updateNotes():Void
@ -321,7 +321,7 @@ class Strumline extends FlxSpriteGroup
note.y = this.y - INITIAL_OFFSET + calculateNoteYPos(note.strumTime, vwoosh);
// If the note is miss
var isOffscreen = PreferencesMenu.getPref('downscroll') ? note.y > FlxG.height : note.y < -note.height;
var isOffscreen = Preferences.downscroll ? note.y > FlxG.height : note.y < -note.height;
if (note.handledMiss && isOffscreen)
{
killNote(note);
@ -388,7 +388,7 @@ class Strumline extends FlxSpriteGroup
var vwoosh:Bool = false;
if (PreferencesMenu.getPref('downscroll'))
if (Preferences.downscroll)
{
holdNote.y = this.y + calculateNoteYPos(holdNote.strumTime, vwoosh) - holdNote.height + STRUMLINE_SIZE / 2;
}
@ -410,7 +410,7 @@ class Strumline extends FlxSpriteGroup
holdNote.visible = false;
}
if (PreferencesMenu.getPref('downscroll'))
if (Preferences.downscroll)
{
holdNote.y = this.y - holdNote.height + STRUMLINE_SIZE / 2;
}
@ -425,7 +425,7 @@ class Strumline extends FlxSpriteGroup
holdNote.visible = true;
var vwoosh:Bool = false;
if (PreferencesMenu.getPref('downscroll'))
if (Preferences.downscroll)
{
holdNote.y = this.y + calculateNoteYPos(holdNote.strumTime, vwoosh) - holdNote.height + STRUMLINE_SIZE / 2;
}

View file

@ -114,7 +114,7 @@ class SustainTrail extends FlxSprite
height = sustainHeight(sustainLength, getScrollSpeed());
// instead of scrollSpeed, PlayState.SONG.speed
flipY = PreferencesMenu.getPref('downscroll');
flipY = Preferences.downscroll;
// alpha = 0.6;
alpha = 1.0;

View file

@ -63,10 +63,10 @@ abstract Save(RawSaveData)
// Reasonable defaults.
naughtyness: true,
downscroll: false,
flashingMenu: true,
flashingLights: true,
zoomCamera: true,
debugDisplay: false,
pauseOnTabOut: true,
autoPause: true,
controls:
{
@ -88,7 +88,7 @@ abstract Save(RawSaveData)
{
// No mods enabled.
enabledMods: [],
modSettings: [],
modOptions: [],
},
optionsChartEditor:
@ -98,6 +98,20 @@ abstract Save(RawSaveData)
};
}
public var options(get, never):SaveDataOptions;
function get_options():SaveDataOptions
{
return this.options;
}
public var modOptions(get, never):Map<String, Dynamic>;
function get_modOptions():Map<String, Dynamic>
{
return this.mods.modOptions;
}
/**
* The current session ID for the logged-in Newgrounds user, or null if the user is cringe.
*/
@ -458,7 +472,7 @@ typedef SaveHighScoresData =
typedef SaveDataMods =
{
var enabledMods:Array<String>;
var modSettings:Map<String, Dynamic>;
var modOptions:Map<String, Dynamic>;
}
/**
@ -530,10 +544,10 @@ typedef SaveDataOptions =
var downscroll:Bool;
/**
* If disabled, the main menu won't flash when entering a submenu.
* If disabled, flashing lights in the main menu and other areas will be less intense.
* @default `true`
*/
var flashingMenu:Bool;
var flashingLights:Bool;
/**
* If disabled, the camera bump synchronized to the beat.
@ -551,7 +565,7 @@ typedef SaveDataOptions =
* If enabled, the game will automatically pause when tabbing out.
* @default `true`
*/
var pauseOnTabOut:Bool;
var autoPause:Bool;
var controls:
{

View file

@ -3,17 +3,16 @@ package funkin.ui;
import flixel.FlxCamera;
import flixel.FlxObject;
import flixel.FlxSprite;
import flixel.group.FlxSpriteGroup.FlxTypedSpriteGroup;
import funkin.ui.AtlasText.AtlasFont;
import funkin.ui.OptionsState.Page;
import funkin.ui.TextMenuList.TextMenuItem;
class PreferencesMenu extends Page
{
public static var preferences:Map<String, Dynamic> = new Map();
var items:TextMenuList;
var preferenceItems:FlxTypedSpriteGroup<FlxSprite>;
var checkboxes:Array<CheckboxThingie> = [];
var menuCamera:FlxCamera;
var camFollow:FlxObject;
@ -27,13 +26,9 @@ class PreferencesMenu extends Page
camera = menuCamera;
add(items = new TextMenuList());
add(preferenceItems = new FlxTypedSpriteGroup<FlxSprite>());
createPrefItem('naughtyness', 'censor-naughty', true);
createPrefItem('downscroll', 'downscroll', false);
createPrefItem('flashing menu', 'flashing-menu', true);
createPrefItem('Camera Zooming on Beat', 'camera-zoom', true);
createPrefItem('FPS Counter', 'fps-counter', true);
createPrefItem('Auto Pause', 'auto-pause', false);
createPrefItems();
camFollow = new FlxObject(FlxG.width / 2, 0, 140, 70);
if (items != null) camFollow.y = items.selectedItem.y;
@ -48,128 +43,63 @@ class PreferencesMenu extends Page
});
}
public static function getPref(pref:String):Dynamic
/**
* Create the menu items for each of the preferences.
*/
function createPrefItems():Void
{
return preferences.get(pref);
createPrefItemCheckbox('Naughtyness', 'Toggle displaying raunchy content', function(value:Bool):Void {
Preferences.naughtyness = value;
}, Preferences.naughtyness);
createPrefItemCheckbox('Downscroll', 'Enable to make notes move downwards', function(value:Bool):Void {
Preferences.downscroll = value;
}, Preferences.downscroll);
createPrefItemCheckbox('Flashing Lights', 'Disable to dampen flashing effects', function(value:Bool):Void {
Preferences.flashingLights = value;
}, Preferences.flashingLights);
createPrefItemCheckbox('Camera Zooming on Beat', 'Disable to stop the camera bouncing to the song', function(value:Bool):Void {
Preferences.zoomCamera = value;
}, Preferences.zoomCamera);
createPrefItemCheckbox('Debug Display', 'Enable to show FPS and other debug stats', function(value:Bool):Void {
Preferences.debugDisplay = value;
}, Preferences.debugDisplay);
createPrefItemCheckbox('Auto Pause', 'Automatically pause the game when it loses focus', function(value:Bool):Void {
Preferences.autoPause = value;
}, Preferences.autoPause);
}
// easy shorthand?
public static function setPref(pref:String, value:Dynamic):Void
function createPrefItemCheckbox(prefName:String, prefDesc:String, onChange:Bool->Void, defaultValue:Bool):Void
{
preferences.set(pref, value);
}
var checkbox:CheckboxPreferenceItem = new CheckboxPreferenceItem(0, 120 * (items.length - 1 + 1), defaultValue);
public static function initPrefs():Void
{
preferenceCheck('censor-naughty', true);
preferenceCheck('downscroll', false);
preferenceCheck('flashing-menu', true);
preferenceCheck('camera-zoom', true);
preferenceCheck('fps-counter', true);
preferenceCheck('auto-pause', false);
preferenceCheck('master-volume', 1);
#if muted
setPref('master-volume', 0);
FlxG.sound.muted = true;
#end
if (!getPref('fps-counter')) FlxG.stage.removeChild(Main.fpsCounter);
FlxG.autoPause = getPref('auto-pause');
}
function createPrefItem(prefName:String, prefString:String, prefValue:Dynamic):Void
{
items.createItem(120, (120 * items.length) + 30, prefName, AtlasFont.BOLD, function() {
preferenceCheck(prefString, prefValue);
switch (Type.typeof(prefValue).getName())
{
case 'TBool':
prefToggle(prefString);
default:
trace('swag');
}
var value = !checkbox.currentValue;
onChange(value);
checkbox.currentValue = value;
});
switch (Type.typeof(prefValue).getName())
{
case 'TBool':
createCheckbox(prefString);
default:
trace('swag');
}
trace(Type.typeof(prefValue).getName());
}
function createCheckbox(prefString:String)
{
var checkbox:CheckboxThingie = new CheckboxThingie(0, 120 * (items.length - 1), preferences.get(prefString));
checkboxes.push(checkbox);
add(checkbox);
}
/**
* Assumes that the preference has already been checked/set?
*/
function prefToggle(prefName:String)
{
var daSwap:Bool = preferences.get(prefName);
daSwap = !daSwap;
preferences.set(prefName, daSwap);
checkboxes[items.selectedIndex].daValue = daSwap;
trace('toggled? ' + preferences.get(prefName));
switch (prefName)
{
case 'fps-counter':
if (getPref('fps-counter')) FlxG.stage.addChild(Main.fpsCounter);
else
FlxG.stage.removeChild(Main.fpsCounter);
case 'auto-pause':
FlxG.autoPause = getPref('auto-pause');
}
if (prefName == 'fps-counter') {}
preferenceItems.add(checkbox);
}
override function update(elapsed:Float)
{
super.update(elapsed);
// menuCamera.followLerp = CoolUtil.camLerpShit(0.05);
// Indent the selected item.
// TODO: Only do this on menu change?
items.forEach(function(daItem:TextMenuItem) {
if (items.selectedItem == daItem) daItem.x = 150;
else
daItem.x = 120;
});
}
static function preferenceCheck(prefString:String, defaultValue:Dynamic):Void
{
if (preferences.get(prefString) == null)
{
// Set the value to default.
preferences.set(prefString, defaultValue);
trace('Set preference to default: ${prefString} = ${defaultValue}');
}
else
{
trace('Found preference: ${prefString} = ${preferences.get(prefString)}');
}
}
}
class CheckboxThingie extends FlxSprite
class CheckboxPreferenceItem extends FlxSprite
{
public var daValue(default, set):Bool;
public var currentValue(default, set):Bool;
public function new(x:Float, y:Float, daValue:Bool = false)
public function new(x:Float, y:Float, defaultValue:Bool = false)
{
super(x, y);
@ -180,7 +110,7 @@ class CheckboxThingie extends FlxSprite
setGraphicSize(Std.int(width * 0.7));
updateHitbox();
this.daValue = daValue;
this.currentValue = defaultValue;
}
override function update(elapsed:Float)
@ -196,12 +126,17 @@ class CheckboxThingie extends FlxSprite
}
}
function set_daValue(value:Bool):Bool
function set_currentValue(value:Bool):Bool
{
if (value) animation.play('checked', true);
if (value)
{
animation.play('checked', true);
}
else
{
animation.play('static');
}
return value;
return currentValue = value;
}
}

View file

@ -10,7 +10,7 @@ class TextMenuList extends MenuTypedList<TextMenuItem>
super(navControls, wrapMode);
}
public function createItem(x = 0.0, y = 0.0, name:String, font:AtlasFont = BOLD, callback, fireInstantly = false)
public function createItem(x = 0.0, y = 0.0, name:String, font:AtlasFont = BOLD, ?callback:Void->Void, fireInstantly = false)
{
var item = new TextMenuItem(x, y, name, font, callback);
item.fireInstantly = fireInstantly;
@ -20,7 +20,7 @@ class TextMenuList extends MenuTypedList<TextMenuItem>
class TextMenuItem extends TextTypedMenuItem<AtlasText>
{
public function new(x = 0.0, y = 0.0, name:String, font:AtlasFont = BOLD, callback)
public function new(x = 0.0, y = 0.0, name:String, font:AtlasFont = BOLD, ?callback:Void->Void)
{
super(x, y, new AtlasText(0, 0, name, font), name, callback);
setEmptyBackground();
@ -29,7 +29,7 @@ class TextMenuItem extends TextTypedMenuItem<AtlasText>
class TextTypedMenuItem<T:AtlasText> extends MenuTypedItem<T>
{
public function new(x = 0.0, y = 0.0, label:T, name:String, callback)
public function new(x = 0.0, y = 0.0, label:T, name:String, ?callback:Void->Void)
{
super(x, y, label, name, callback);
}

View file

@ -3,6 +3,9 @@ package funkin.util;
import flixel.util.FlxColor;
import lime.app.Application;
/**
* A store of unchanging, globally relevant values.
*/
class Constants
{
/**