mirror of
https://github.com/ninjamuffin99/Funkin.git
synced 2025-09-03 20:28:04 +00:00
Compare commits
20 commits
6e8decf830
...
6fb7252101
Author | SHA1 | Date | |
---|---|---|---|
|
6fb7252101 | ||
|
d0f0974d1e | ||
|
369b936056 | ||
|
c40e1e3958 | ||
|
0ade24bac4 | ||
|
7370ef3249 | ||
|
b2f162a8ae | ||
|
11fa9b4050 | ||
|
89bd7a3f43 | ||
|
942fb5efc9 | ||
|
c2eff142bd | ||
|
47815cff2e | ||
|
2784fa18c0 | ||
|
ad07fddf89 | ||
|
4768eedd5b | ||
|
f1c3e99a11 | ||
|
eefe8927c4 | ||
|
3ff4f14510 | ||
|
955b0db542 | ||
|
d2df4f0832 |
2
.github/ISSUE_TEMPLATE/bug.yml
vendored
2
.github/ISSUE_TEMPLATE/bug.yml
vendored
|
@ -59,7 +59,7 @@ body:
|
|||
attributes:
|
||||
label: Version
|
||||
description: Which version are you playing on? The game version is in the bottom left corner of the main menu.
|
||||
placeholder: ex. 0.7.3
|
||||
placeholder: ex. 0.7.4
|
||||
validations:
|
||||
required: true
|
||||
|
||||
|
|
2
.github/ISSUE_TEMPLATE/charting.yml
vendored
2
.github/ISSUE_TEMPLATE/charting.yml
vendored
|
@ -36,7 +36,7 @@ body:
|
|||
attributes:
|
||||
label: Version
|
||||
description: Which version are you playing on? The game version is in the bottom left corner of the main menu.
|
||||
placeholder: ex. 0.7.3
|
||||
placeholder: ex. 0.7.4
|
||||
validations:
|
||||
required: true
|
||||
|
||||
|
|
2
.github/ISSUE_TEMPLATE/compiling.yml
vendored
2
.github/ISSUE_TEMPLATE/compiling.yml
vendored
|
@ -36,7 +36,7 @@ body:
|
|||
attributes:
|
||||
label: Version
|
||||
description: Which version are you compiling? The game version is in the bottom left corner of the main menu or in the project.hxp file.
|
||||
placeholder: ex. 0.7.3
|
||||
placeholder: ex. 0.7.4
|
||||
validations:
|
||||
required: true
|
||||
|
||||
|
|
2
.github/ISSUE_TEMPLATE/crash.yml
vendored
2
.github/ISSUE_TEMPLATE/crash.yml
vendored
|
@ -60,7 +60,7 @@ body:
|
|||
attributes:
|
||||
label: Version
|
||||
description: Which version are you playing on? The game version is in the bottom left corner of the main menu.
|
||||
placeholder: ex. 0.7.3
|
||||
placeholder: ex. 0.7.4
|
||||
validations:
|
||||
required: true
|
||||
|
||||
|
|
|
@ -60,7 +60,7 @@ This section provides guidelines to follow when [opening an issue](https://githu
|
|||
|
||||
## Requirements
|
||||
Make sure you're playing:
|
||||
- the latest version of the game (currently v0.7.3)
|
||||
- the latest version of the game (currently v0.7.4)
|
||||
- without any mods
|
||||
- on [Newgrounds](https://www.newgrounds.com/portal/view/770371) or downloaded from [itch.io](https://ninja-muffin24.itch.io/funkin)
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
"name": "EliteMasterEric"
|
||||
}
|
||||
],
|
||||
"api_version": "0.5.0",
|
||||
"api_version": "0.7.0",
|
||||
"mod_version": "1.0.0",
|
||||
"license": "Apache-2.0"
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
"name": "EliteMasterEric"
|
||||
}
|
||||
],
|
||||
"api_version": "0.5.0",
|
||||
"api_version": "0.7.0",
|
||||
"mod_version": "1.0.0",
|
||||
"license": "Apache-2.0"
|
||||
}
|
||||
|
|
|
@ -341,7 +341,7 @@ class InitState extends FlxState
|
|||
}));
|
||||
#elseif ANIMDEBUG
|
||||
// -DANIMDEBUG
|
||||
FlxG.switchState(() -> new funkin.ui.debug.anim.DebugBoundingState());
|
||||
FlxG.switchState(() -> new funkin.ui.debug.anim.AnimationEditorState());
|
||||
#elseif LATENCY
|
||||
// -DLATENCY
|
||||
FlxG.switchState(() -> new funkin.LatencyState());
|
||||
|
|
156
source/funkin/api/newgrounds/NGSaveSlot.hx
Normal file
156
source/funkin/api/newgrounds/NGSaveSlot.hx
Normal file
|
@ -0,0 +1,156 @@
|
|||
package funkin.api.newgrounds;
|
||||
|
||||
#if FEATURE_NEWGROUNDS
|
||||
import io.newgrounds.utils.SaveSlotList;
|
||||
import io.newgrounds.objects.SaveSlot;
|
||||
import io.newgrounds.Call.CallError;
|
||||
import io.newgrounds.objects.events.Outcome;
|
||||
import funkin.save.Save;
|
||||
|
||||
@:nullSafety
|
||||
@:access(funkin.save.Save)
|
||||
class NGSaveSlot
|
||||
{
|
||||
public static var instance(get, never):NGSaveSlot;
|
||||
static var _instance:Null<NGSaveSlot> = null;
|
||||
|
||||
static function get_instance():NGSaveSlot
|
||||
{
|
||||
if (_instance == null)
|
||||
{
|
||||
return loadInstance();
|
||||
}
|
||||
return _instance;
|
||||
}
|
||||
|
||||
public static function loadInstance():NGSaveSlot
|
||||
{
|
||||
var loadedSave:NGSaveSlot = loadSlot(Save.BASE_SAVE_SLOT);
|
||||
if (_instance == null) _instance = loadedSave;
|
||||
|
||||
return loadedSave;
|
||||
}
|
||||
|
||||
static function loadSlot(slot:Int):NGSaveSlot
|
||||
{
|
||||
trace('[NEWGROUNDS] Getting save slot from ID $slot');
|
||||
|
||||
var saveSlot:Null<SaveSlot> = NewgroundsClient.instance.saveSlots?.getById(slot);
|
||||
|
||||
var saveSlotObj:NGSaveSlot = new NGSaveSlot(saveSlot);
|
||||
return saveSlotObj;
|
||||
}
|
||||
|
||||
public var ngSaveSlot:Null<SaveSlot> = null;
|
||||
|
||||
public function new(?ngSaveSlot:Null<SaveSlot>)
|
||||
{
|
||||
this.ngSaveSlot = ngSaveSlot;
|
||||
|
||||
#if FLX_DEBUG
|
||||
FlxG.console.registerClass(NGSaveSlot);
|
||||
FlxG.console.registerClass(Save);
|
||||
#end
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves `data` to the newgrounds save slot.
|
||||
* @param data The raw save data.
|
||||
*/
|
||||
public function save(data:RawSaveData):Void
|
||||
{
|
||||
var encodedData:String = haxe.Serializer.run(data);
|
||||
|
||||
try
|
||||
{
|
||||
ngSaveSlot?.save(encodedData, function(outcome:Outcome<CallError>) {
|
||||
switch (outcome)
|
||||
{
|
||||
case SUCCESS:
|
||||
trace('[NEWGROUNDS] Successfully saved save data to save slot!');
|
||||
case FAIL(error):
|
||||
trace('[NEWGROUNDS] Failed to save data to save slot!');
|
||||
trace(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (error:String)
|
||||
{
|
||||
trace('[NEWGROUNDS] Failed to save data to save slot!');
|
||||
trace(error);
|
||||
}
|
||||
}
|
||||
|
||||
public function load(?onComplete:Null<Dynamic->Void>, ?onError:Null<CallError->Void>):Void
|
||||
{
|
||||
try
|
||||
{
|
||||
ngSaveSlot?.load(function(outcome:SaveSlotOutcome):Void {
|
||||
switch (outcome)
|
||||
{
|
||||
case SUCCESS(value):
|
||||
trace('[NEWGROUNDS] Loaded save slot with the ID of ${ngSaveSlot?.id}!');
|
||||
#if FEATURE_DEBUG_FUNCTIONS
|
||||
trace('Save Slot Data:');
|
||||
trace(value);
|
||||
#end
|
||||
|
||||
if (onComplete != null && value != null)
|
||||
{
|
||||
var decodedData:Dynamic = haxe.Unserializer.run(value);
|
||||
onComplete(decodedData);
|
||||
}
|
||||
case FAIL(error):
|
||||
trace('[NEWGROUNDS] Failed to load save slot with the ID of ${ngSaveSlot?.id}!');
|
||||
trace(error);
|
||||
|
||||
if (onError != null)
|
||||
{
|
||||
onError(error);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (error:String)
|
||||
{
|
||||
trace('[NEWGROUNDS] Failed to load save slot with the ID of ${ngSaveSlot?.id}!');
|
||||
trace(error);
|
||||
|
||||
if (onError != null)
|
||||
{
|
||||
onError(RESPONSE({message: error, code: 500}));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function clear():Void
|
||||
{
|
||||
try
|
||||
{
|
||||
ngSaveSlot?.clear(function(outcome:Outcome<CallError>) {
|
||||
switch (outcome)
|
||||
{
|
||||
case SUCCESS:
|
||||
trace('[NEWGROUNDS] Successfully cleared save slot!');
|
||||
case FAIL(error):
|
||||
trace('[NEWGROUNDS] Failed to clear save slot!');
|
||||
trace(error);
|
||||
}
|
||||
});
|
||||
}
|
||||
catch (error:String)
|
||||
{
|
||||
trace('[NEWGROUNDS] Failed to clear save slot!');
|
||||
trace(error);
|
||||
}
|
||||
}
|
||||
|
||||
public function checkSlot():Void
|
||||
{
|
||||
trace('[NEWGROUNDS] Checking save slot with the ID of ${ngSaveSlot?.id}...');
|
||||
|
||||
trace(' Is null? ${ngSaveSlot == null}');
|
||||
trace(' Is empty? ${ngSaveSlot?.isEmpty() ?? false}');
|
||||
}
|
||||
}
|
||||
#end
|
|
@ -10,6 +10,7 @@ import io.newgrounds.NGLite.LoginOutcome;
|
|||
import io.newgrounds.NGLite.LoginFail;
|
||||
import io.newgrounds.objects.events.Outcome;
|
||||
import io.newgrounds.utils.MedalList;
|
||||
import io.newgrounds.utils.SaveSlotList;
|
||||
import io.newgrounds.utils.ScoreBoardList;
|
||||
import io.newgrounds.objects.User;
|
||||
|
||||
|
@ -29,6 +30,7 @@ class NewgroundsClient
|
|||
public var user(get, never):Null<User>;
|
||||
public var medals(get, never):Null<MedalList>;
|
||||
public var leaderboards(get, never):Null<ScoreBoardList>;
|
||||
public var saveSlots(get, never):Null<SaveSlotList>;
|
||||
|
||||
private function new()
|
||||
{
|
||||
|
@ -236,6 +238,8 @@ class NewgroundsClient
|
|||
|
||||
trace('[NEWGROUNDS] Submitting leaderboard request...');
|
||||
NG.core.scoreBoards.loadList(onFetchedLeaderboards);
|
||||
trace('[NEWGROUNDS] Submitting save slot request...');
|
||||
NG.core.saveSlots.loadList(onFetchedSaveSlots);
|
||||
}
|
||||
|
||||
function onLoginFailed(result:LoginFail):Void
|
||||
|
@ -301,6 +305,13 @@ class NewgroundsClient
|
|||
// trace(funkin.api.newgrounds.Leaderboards.listLeaderboardData());
|
||||
}
|
||||
|
||||
function onFetchedSaveSlots(outcome:Outcome<CallError>):Void
|
||||
{
|
||||
trace('[NEWGROUNDS] Fetched save slots!');
|
||||
|
||||
NGSaveSlot.instance.checkSlot();
|
||||
}
|
||||
|
||||
function get_user():Null<User>
|
||||
{
|
||||
if (NG.core == null || !this.isLoggedIn()) return null;
|
||||
|
@ -319,6 +330,12 @@ class NewgroundsClient
|
|||
return NG.core.scoreBoards;
|
||||
}
|
||||
|
||||
function get_saveSlots():Null<SaveSlotList>
|
||||
{
|
||||
if (NG.core == null || !this.isLoggedIn()) return null;
|
||||
return NG.core.saveSlots;
|
||||
}
|
||||
|
||||
static function getSessionId():Null<String>
|
||||
{
|
||||
#if js
|
||||
|
|
|
@ -58,7 +58,7 @@ class BaseCharacter extends Bopper
|
|||
*/
|
||||
public var dropNoteCounts(default, null):Array<Int>;
|
||||
|
||||
@:allow(funkin.ui.debug.anim.DebugBoundingState)
|
||||
@:allow(funkin.ui.debug.anim.AnimationEditorState)
|
||||
final _data:CharacterData;
|
||||
final singTimeSteps:Float;
|
||||
|
||||
|
|
|
@ -81,7 +81,7 @@ class Bopper extends StageProp implements IPlayStateScriptedClass
|
|||
return globalOffsets = value;
|
||||
}
|
||||
|
||||
@:allow(funkin.ui.debug.anim.DebugBoundingState)
|
||||
@:allow(funkin.ui.debug.anim.AnimationEditorState)
|
||||
var animOffsets(default, set):Array<Float> = [0, 0];
|
||||
|
||||
public var originalPosition:FlxPoint = new FlxPoint(0, 0);
|
||||
|
|
|
@ -1356,6 +1356,45 @@ class Save
|
|||
{
|
||||
FileUtil.saveFile(haxe.io.Bytes.ofString(this.serialize()), [FileUtil.FILE_FILTER_JSON], null, null, './save.json', 'Write save data as JSON...');
|
||||
}
|
||||
|
||||
#if FEATURE_NEWGROUNDS
|
||||
public static function saveToNewgrounds():Void
|
||||
{
|
||||
if (_instance == null) return;
|
||||
trace('[SAVE] Saving Save Data to Newgrounds...');
|
||||
funkin.api.newgrounds.NGSaveSlot.instance.save(_instance.data);
|
||||
}
|
||||
|
||||
public static function loadFromNewgrounds(onFinish:Void->Void):Void
|
||||
{
|
||||
trace('[SAVE] Loading Save Data from Newgrounds...');
|
||||
funkin.api.newgrounds.NGSaveSlot.instance.load(function(data:Dynamic) {
|
||||
FlxG.save.bind('$SAVE_NAME${BASE_SAVE_SLOT}', SAVE_PATH);
|
||||
|
||||
if (FlxG.save.status != EMPTY)
|
||||
{
|
||||
// best i can do in case the NG file is corrupted or something along those lines
|
||||
var backupSlot:Int = Save.archiveBadSaveData(FlxG.save.data);
|
||||
trace('[SAVE] Backed up current save data in case of emergency to $backupSlot!');
|
||||
}
|
||||
|
||||
FlxG.save.erase();
|
||||
FlxG.save.bind('$SAVE_NAME${BASE_SAVE_SLOT}', SAVE_PATH); // forces regeneration of the file as erase deletes it
|
||||
|
||||
var gameSave = SaveDataMigrator.migrate(data);
|
||||
FlxG.save.mergeData(gameSave.data, true);
|
||||
_instance = gameSave;
|
||||
onFinish();
|
||||
}, function(error:io.newgrounds.Call.CallError) {
|
||||
var errorMsg:String = io.newgrounds.Call.CallErrorTools.toString(error);
|
||||
|
||||
var msg = 'There was an error loading your save data from Newgrounds.';
|
||||
msg += '\n${errorMsg}';
|
||||
msg += '\nAre you sure you are connected to the internet?';
|
||||
lime.app.Application.current.window.alert(msg, "Newgrounds Save Slot Failure");
|
||||
});
|
||||
}
|
||||
#end
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -113,7 +113,7 @@ class DebugMenuSubState extends MusicBeatSubState
|
|||
|
||||
function openAnimationEditor():Void
|
||||
{
|
||||
FlxG.switchState(() -> new funkin.ui.debug.anim.DebugBoundingState());
|
||||
FlxG.switchState(() -> new funkin.ui.debug.anim.AnimationEditorState());
|
||||
trace('Animation Editor');
|
||||
}
|
||||
|
||||
|
|
|
@ -31,30 +31,27 @@ import openfl.net.FileReference;
|
|||
|
||||
using flixel.util.FlxSpriteUtil;
|
||||
|
||||
class DebugBoundingState extends FlxState
|
||||
@:nullSafety
|
||||
class AnimationEditorState extends MusicBeatState
|
||||
{
|
||||
/*
|
||||
TODAY'S TO-DO
|
||||
- Cleaner UI
|
||||
*/
|
||||
var bg:FlxBackdrop;
|
||||
var fileInfo:FlxText;
|
||||
var bg:Null<FlxBackdrop>;
|
||||
var fileInfo:Null<FlxText>;
|
||||
|
||||
var txtGrp:FlxTypedGroup<FlxText>;
|
||||
var txtGrp:Null<FlxTypedGroup<FlxText>>;
|
||||
|
||||
var hudCam:FlxCamera;
|
||||
var hudCam:Null<FlxCamera>;
|
||||
|
||||
var curView:ANIMDEBUGVIEW = SPRITESHEET;
|
||||
|
||||
var spriteSheetView:FlxGroup;
|
||||
var offsetView:FlxGroup;
|
||||
var spriteSheetView:Null<FlxGroup>;
|
||||
var offsetView:Null<FlxGroup>;
|
||||
var dropDownSetup:Bool = false;
|
||||
|
||||
var onionSkinChar:FlxSprite;
|
||||
var txtOffsetShit:FlxText;
|
||||
var onionSkinChar:Null<FlxSprite>;
|
||||
var txtOffsetShit:Null<FlxText>;
|
||||
|
||||
var offsetEditorDialog:CollapsibleDialog;
|
||||
var offsetAnimationDropdown:DropDown;
|
||||
var offsetEditorDialog:Null<CollapsibleDialog>;
|
||||
var offsetAnimationDropdown:Null<DropDown>;
|
||||
|
||||
var haxeUIFocused(get, default):Bool = false;
|
||||
|
||||
|
@ -89,8 +86,10 @@ class DebugBoundingState extends FlxState
|
|||
offsetEditorDialog = cast RuntimeComponentBuilder.fromAsset(str);
|
||||
|
||||
// offsetEditorDialog.findComponent("btnViewSpriteSheet").onClick = _ -> curView = SPRITESHEET;
|
||||
var viewDropdown:DropDown = offsetEditorDialog.findComponent("swapper", DropDown);
|
||||
viewDropdown.onChange = function(e:UIEvent) {
|
||||
var viewDropdown:Null<DropDown> = offsetEditorDialog.findComponent("swapper", DropDown);
|
||||
|
||||
|
||||
if (viewDropdown != null) viewDropdown.onChange = function(e:UIEvent) {
|
||||
trace(e.type);
|
||||
curView = cast e.data.curView;
|
||||
trace(e.data);
|
||||
|
@ -120,8 +119,8 @@ class DebugBoundingState extends FlxState
|
|||
super.create();
|
||||
}
|
||||
|
||||
var bf:FlxSprite;
|
||||
var swagOutlines:FlxSprite;
|
||||
var bf:Null<FlxSprite>;
|
||||
var swagOutlines:Null<FlxSprite>;
|
||||
|
||||
function initSpritesheetView():Void
|
||||
{
|
||||
|
@ -140,7 +139,7 @@ class DebugBoundingState extends FlxState
|
|||
generateOutlines(tex.frames);
|
||||
|
||||
txtGrp = new FlxTypedGroup<FlxText>();
|
||||
txtGrp.cameras = [hudCam];
|
||||
if (hudCam != null) txtGrp.cameras = [hudCam];
|
||||
spriteSheetView.add(txtGrp);
|
||||
|
||||
addInfo('boyfriend.xml', "");
|
||||
|
@ -154,7 +153,7 @@ class DebugBoundingState extends FlxState
|
|||
{
|
||||
// swagOutlines.width = frameShit[0].parent.width;
|
||||
// swagOutlines.height = frameShit[0].parent.height;
|
||||
swagOutlines.pixels.fillRect(new Rectangle(0, 0, swagOutlines.width, swagOutlines.height), 0x00000000);
|
||||
if (swagOutlines != null) swagOutlines.pixels.fillRect(new Rectangle(0, 0, swagOutlines.width, swagOutlines.height), 0x00000000);
|
||||
|
||||
for (i in frameShit)
|
||||
{
|
||||
|
@ -164,7 +163,7 @@ class DebugBoundingState extends FlxState
|
|||
var uvH:Float = (i.uv.height * i.parent.height) - (i.uv.y * i.parent.height);
|
||||
|
||||
// trace(Std.int(i.uv.width * i.parent.width));
|
||||
swagOutlines.drawRect(i.uv.x * i.parent.width, i.uv.y * i.parent.height, uvW, uvH, FlxColor.TRANSPARENT, lineStyle);
|
||||
if (swagOutlines != null) swagOutlines.drawRect(i.uv.x * i.parent.width, i.uv.y * i.parent.height, uvW, uvH, FlxColor.TRANSPARENT, lineStyle);
|
||||
// swagGraphic.setPosition(, );
|
||||
// trace(uvH);
|
||||
}
|
||||
|
@ -181,26 +180,31 @@ class DebugBoundingState extends FlxState
|
|||
|
||||
txtOffsetShit = new FlxText(20, 20, 0, "", 20);
|
||||
txtOffsetShit.setFormat(Paths.font("vcr.ttf"), 26, FlxColor.WHITE, LEFT, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK);
|
||||
txtOffsetShit.cameras = [hudCam];
|
||||
if (hudCam != null) txtOffsetShit.cameras = [hudCam];
|
||||
txtOffsetShit.y = FlxG.height - 20 - txtOffsetShit.height;
|
||||
offsetView.add(txtOffsetShit);
|
||||
|
||||
var characters:Array<String> = CharacterDataParser.listCharacterIds();
|
||||
characters = characters.filter(function(charId:String) {
|
||||
var char = CharacterDataParser.fetchCharacterData(charId);
|
||||
@:nullSafety(Off)
|
||||
return char.renderType != AnimateAtlas;
|
||||
});
|
||||
characters.sort(SortUtil.alphabetically);
|
||||
|
||||
var charDropdown:DropDown = offsetEditorDialog.findComponent('characterDropdown', DropDown);
|
||||
for (char in characters)
|
||||
{
|
||||
charDropdown.dataSource.add({text: char});
|
||||
}
|
||||
var charDropdown:Null<DropDown> = null;
|
||||
if (offsetEditorDialog != null) charDropdown = offsetEditorDialog.findComponent('characterDropdown', DropDown);
|
||||
|
||||
charDropdown.onChange = function(e:UIEvent) {
|
||||
loadAnimShit(e.data.text);
|
||||
};
|
||||
if (charDropdown != null){
|
||||
for (char in characters)
|
||||
{
|
||||
charDropdown.dataSource.add({text: char});
|
||||
}
|
||||
|
||||
charDropdown.onChange = function(e:UIEvent) {
|
||||
loadAnimShit(e.data.text);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
public var mouseOffset:FlxPoint = FlxPoint.get(0, 0);
|
||||
|
@ -223,10 +227,12 @@ class DebugBoundingState extends FlxState
|
|||
{
|
||||
swagChar.animOffsets = [(FlxG.mouse.x - mouseOffset.x) * -1, (FlxG.mouse.y - mouseOffset.y) * -1];
|
||||
|
||||
swagChar.animationOffsets.set(offsetAnimationDropdown.value.id, swagChar.animOffsets);
|
||||
if (offsetAnimationDropdown != null) swagChar.animationOffsets.set(offsetAnimationDropdown.value.id, swagChar.animOffsets);
|
||||
|
||||
txtOffsetShit.text = 'Offset: ' + swagChar.animOffsets;
|
||||
txtOffsetShit.y = FlxG.height - 20 - txtOffsetShit.height;
|
||||
if (txtOffsetShit != null) {
|
||||
txtOffsetShit.text = 'Offset: ' + swagChar?.animOffsets;
|
||||
txtOffsetShit.y = FlxG.height - 20 - txtOffsetShit.height;
|
||||
}
|
||||
}
|
||||
|
||||
if (FlxG.mouse.justReleased)
|
||||
|
@ -247,18 +253,22 @@ class DebugBoundingState extends FlxState
|
|||
swagText.setFormat(Paths.font("vcr.ttf"), 26, FlxColor.WHITE, LEFT, FlxTextBorderStyle.OUTLINE, FlxColor.BLACK);
|
||||
swagText.scrollFactor.set();
|
||||
|
||||
for (text in txtGrp.members)
|
||||
{
|
||||
text.y -= swagText.height;
|
||||
if (txtGrp != null){
|
||||
var texts = txtGrp.members;
|
||||
if (texts != null)
|
||||
for (text in texts)
|
||||
{
|
||||
text.y -= swagText.height;
|
||||
}
|
||||
txtGrp.add(swagText);
|
||||
}
|
||||
txtGrp.add(swagText);
|
||||
|
||||
swagText.text = str + ": " + Std.string(value);
|
||||
}
|
||||
|
||||
function clearInfo()
|
||||
{
|
||||
txtGrp.clear();
|
||||
if (txtGrp != null) txtGrp.clear();
|
||||
}
|
||||
|
||||
function checkLibrary(library:String)
|
||||
|
@ -281,15 +291,17 @@ class DebugBoundingState extends FlxState
|
|||
{
|
||||
if (FlxG.keys.justPressed.ONE)
|
||||
{
|
||||
var lv:DropDown = offsetEditorDialog.findComponent("swapper", DropDown);
|
||||
lv.selectedIndex = 0;
|
||||
var lv:Null<DropDown> = null;
|
||||
if (offsetEditorDialog != null) lv = offsetEditorDialog.findComponent("swapper", DropDown);
|
||||
if (lv != null) lv.selectedIndex = 0;
|
||||
curView = SPRITESHEET;
|
||||
}
|
||||
|
||||
if (FlxG.keys.justReleased.TWO)
|
||||
{
|
||||
var lv:DropDown = offsetEditorDialog.findComponent("swapper", DropDown);
|
||||
lv.selectedIndex = 1;
|
||||
var lv:Null<DropDown> = null;
|
||||
if (offsetEditorDialog != null) lv = offsetEditorDialog.findComponent("swapper", DropDown);
|
||||
if (lv != null) lv.selectedIndex = 1;
|
||||
curView = ANIMATIONS;
|
||||
if (swagChar != null)
|
||||
{
|
||||
|
@ -298,33 +310,36 @@ class DebugBoundingState extends FlxState
|
|||
}
|
||||
}
|
||||
|
||||
switch (curView)
|
||||
if (spriteSheetView != null && offsetView != null && offsetAnimationDropdown != null)
|
||||
{
|
||||
case SPRITESHEET:
|
||||
spriteSheetView.visible = true;
|
||||
offsetView.visible = false;
|
||||
offsetView.active = false;
|
||||
offsetAnimationDropdown.visible = false;
|
||||
case ANIMATIONS:
|
||||
spriteSheetView.visible = false;
|
||||
offsetView.visible = true;
|
||||
offsetView.active = true;
|
||||
offsetAnimationDropdown.visible = true;
|
||||
offsetControls();
|
||||
mouseOffsetMovement();
|
||||
switch (curView)
|
||||
{
|
||||
case SPRITESHEET:
|
||||
spriteSheetView.visible = true;
|
||||
offsetView.visible = false;
|
||||
offsetView.active = false;
|
||||
offsetAnimationDropdown.visible = false;
|
||||
case ANIMATIONS:
|
||||
spriteSheetView.visible = false;
|
||||
offsetView.visible = true;
|
||||
offsetView.active = true;
|
||||
offsetAnimationDropdown.visible = true;
|
||||
offsetControls();
|
||||
mouseOffsetMovement();
|
||||
}
|
||||
}
|
||||
|
||||
if (FlxG.keys.justPressed.H) hudCam.visible = !hudCam.visible;
|
||||
if (FlxG.keys.justPressed.H && hudCam != null) hudCam.visible = !hudCam.visible;
|
||||
|
||||
if (FlxG.keys.justPressed.F4) FlxG.switchState(() -> new MainMenuState());
|
||||
|
||||
MouseUtil.mouseCamDrag();
|
||||
MouseUtil.mouseCamDrag(FlxG.camera.scroll);
|
||||
if (!haxeUIFocused) MouseUtil.mouseWheelZoom();
|
||||
|
||||
// bg.scale.x = FlxG.camera.zoom;
|
||||
// bg.scale.y = FlxG.camera.zoom;
|
||||
|
||||
bg.setGraphicSize(Std.int(bg.width / FlxG.camera.zoom));
|
||||
if (bg != null) bg.setGraphicSize(Std.int(bg.width / FlxG.camera.zoom));
|
||||
|
||||
super.update(elapsed);
|
||||
}
|
||||
|
@ -333,29 +348,31 @@ class DebugBoundingState extends FlxState
|
|||
{
|
||||
if (FlxG.keys.justPressed.RBRACKET || FlxG.keys.justPressed.E)
|
||||
{
|
||||
if (offsetAnimationDropdown.selectedIndex + 1 <= offsetAnimationDropdown.dataSource.size)
|
||||
if (offsetAnimationDropdown != null && offsetAnimationDropdown.selectedIndex + 1 <= offsetAnimationDropdown.dataSource.size)
|
||||
{
|
||||
offsetAnimationDropdown.selectedIndex += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
offsetAnimationDropdown.selectedIndex = 0;
|
||||
if (offsetAnimationDropdown != null) offsetAnimationDropdown.selectedIndex = 0;
|
||||
}
|
||||
trace(offsetAnimationDropdown.selectedIndex);
|
||||
trace(offsetAnimationDropdown.dataSource.size);
|
||||
trace(offsetAnimationDropdown.value);
|
||||
if (offsetAnimationDropdown != null){
|
||||
trace(offsetAnimationDropdown.selectedIndex);
|
||||
trace(offsetAnimationDropdown.dataSource.size);
|
||||
trace(offsetAnimationDropdown.value);
|
||||
}
|
||||
trace(currentAnimationName);
|
||||
playCharacterAnimation(currentAnimationName, true);
|
||||
}
|
||||
if (FlxG.keys.justPressed.LBRACKET || FlxG.keys.justPressed.Q)
|
||||
{
|
||||
if (offsetAnimationDropdown.selectedIndex - 1 >= 0)
|
||||
if (offsetAnimationDropdown != null && offsetAnimationDropdown.selectedIndex - 1 >= 0)
|
||||
{
|
||||
offsetAnimationDropdown.selectedIndex -= 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
offsetAnimationDropdown.selectedIndex = offsetAnimationDropdown.dataSource.size - 1;
|
||||
if (offsetAnimationDropdown != null) offsetAnimationDropdown.selectedIndex = offsetAnimationDropdown.dataSource.size - 1;
|
||||
}
|
||||
playCharacterAnimation(currentAnimationName, true);
|
||||
}
|
||||
|
@ -377,7 +394,7 @@ class DebugBoundingState extends FlxState
|
|||
|
||||
if (targetLabel != currentAnimationName)
|
||||
{
|
||||
offsetAnimationDropdown.value = {id: targetLabel, text: targetLabel};
|
||||
if (offsetAnimationDropdown != null) offsetAnimationDropdown.value = {id: targetLabel, text: targetLabel};
|
||||
|
||||
// Play the new animation if the IDs are the different.
|
||||
// Override the onion skin.
|
||||
|
@ -393,18 +410,18 @@ class DebugBoundingState extends FlxState
|
|||
|
||||
if (FlxG.keys.justPressed.F)
|
||||
{
|
||||
onionSkinChar.visible = !onionSkinChar.visible;
|
||||
if (onionSkinChar != null) onionSkinChar.visible = !onionSkinChar.visible;
|
||||
}
|
||||
|
||||
if (FlxG.keys.justPressed.G)
|
||||
{
|
||||
swagChar.flipX = !swagChar.flipX;
|
||||
if (swagChar != null) swagChar.flipX = !swagChar.flipX;
|
||||
}
|
||||
|
||||
// Plays the idle animation
|
||||
if (FlxG.keys.justPressed.SPACE)
|
||||
{
|
||||
offsetAnimationDropdown.value = {id: 'idle', text: 'idle'};
|
||||
if (offsetAnimationDropdown != null) offsetAnimationDropdown.value = {id: 'idle', text: 'idle'};
|
||||
|
||||
playCharacterAnimation(currentAnimationName, true);
|
||||
}
|
||||
|
@ -417,33 +434,39 @@ class DebugBoundingState extends FlxState
|
|||
|
||||
if (FlxG.keys.justPressed.RIGHT || FlxG.keys.justPressed.LEFT || FlxG.keys.justPressed.UP || FlxG.keys.justPressed.DOWN)
|
||||
{
|
||||
var animName = currentAnimationName;
|
||||
var coolValues:Array<Float> = swagChar.animationOffsets.get(animName).copy();
|
||||
if (swagChar != null)
|
||||
{
|
||||
var animName = currentAnimationName;
|
||||
@:nullSafety(Off)
|
||||
var coolValues:Array<Float> = swagChar.animationOffsets.get(animName).copy();
|
||||
|
||||
var multiplier:Int = 5;
|
||||
var multiplier:Int = 5;
|
||||
|
||||
if (FlxG.keys.pressed.CONTROL) multiplier = 1;
|
||||
if (FlxG.keys.pressed.CONTROL) multiplier = 1;
|
||||
|
||||
if (FlxG.keys.pressed.SHIFT) multiplier = 10;
|
||||
if (FlxG.keys.pressed.SHIFT) multiplier = 10;
|
||||
|
||||
if (FlxG.keys.justPressed.RIGHT) coolValues[0] -= 1 * multiplier;
|
||||
else if (FlxG.keys.justPressed.LEFT) coolValues[0] += 1 * multiplier;
|
||||
else if (FlxG.keys.justPressed.UP) coolValues[1] += 1 * multiplier;
|
||||
else if (FlxG.keys.justPressed.DOWN) coolValues[1] -= 1 * multiplier;
|
||||
if (FlxG.keys.justPressed.RIGHT) coolValues[0] -= 1 * multiplier;
|
||||
else if (FlxG.keys.justPressed.LEFT) coolValues[0] += 1 * multiplier;
|
||||
else if (FlxG.keys.justPressed.UP) coolValues[1] += 1 * multiplier;
|
||||
else if (FlxG.keys.justPressed.DOWN) coolValues[1] -= 1 * multiplier;
|
||||
|
||||
swagChar.animationOffsets.set(currentAnimationName, coolValues);
|
||||
swagChar.playAnimation(animName);
|
||||
swagChar.animationOffsets.set(currentAnimationName, coolValues);
|
||||
swagChar.playAnimation(animName);
|
||||
|
||||
txtOffsetShit.text = 'Offset: ' + coolValues;
|
||||
txtOffsetShit.y = FlxG.height - 20 - txtOffsetShit.height;
|
||||
if (txtOffsetShit != null){
|
||||
txtOffsetShit.text = 'Offset: ' + coolValues;
|
||||
txtOffsetShit.y = FlxG.height - 20 - txtOffsetShit.height;
|
||||
}
|
||||
|
||||
trace(animName);
|
||||
trace(animName);
|
||||
}
|
||||
}
|
||||
|
||||
if (FlxG.keys.justPressed.ESCAPE)
|
||||
{
|
||||
var outputString = FlxG.keys.pressed.CONTROL ? buildOutputStringOld() : buildOutputStringNew();
|
||||
saveOffsets(outputString, FlxG.keys.pressed.CONTROL ? swagChar.characterId + "Offsets.txt" : swagChar.characterId + ".json");
|
||||
if (swagChar != null) saveOffsets(outputString, FlxG.keys.pressed.CONTROL ? swagChar.characterId + "Offsets.txt" : swagChar.characterId + ".json");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -451,9 +474,15 @@ class DebugBoundingState extends FlxState
|
|||
{
|
||||
var outputString:String = "";
|
||||
|
||||
for (i in swagChar.animationOffsets.keys())
|
||||
if (swagChar != null)
|
||||
{
|
||||
outputString += i + " " + swagChar.animationOffsets.get(i)[0] + " " + swagChar.animationOffsets.get(i)[1] + "\n";
|
||||
var keys = swagChar.animationOffsets.keys();
|
||||
if (keys != null)
|
||||
for (i in keys)
|
||||
{
|
||||
@:nullSafety(Off) // This bug is fixed in haxe 5.0 or something
|
||||
outputString += '${i} ${swagChar.animationOffsets.get(i)[0]} ${swagChar.animationOffsets.get(i)[1]}\n';
|
||||
}
|
||||
}
|
||||
|
||||
outputString.trim();
|
||||
|
@ -463,18 +492,21 @@ class DebugBoundingState extends FlxState
|
|||
|
||||
function buildOutputStringNew():String
|
||||
{
|
||||
var charData:CharacterData = Reflect.copy(swagChar._data);
|
||||
var charData:Null<CharacterData> = Reflect.copy(swagChar?._data);
|
||||
|
||||
for (charDataAnim in charData.animations)
|
||||
var animations = charData?.animations;
|
||||
if (animations != null)
|
||||
{
|
||||
var animName:String = charDataAnim.name;
|
||||
charDataAnim.offsets = swagChar.animationOffsets.get(animName);
|
||||
for (charDataAnim in animations)
|
||||
{
|
||||
var animName:String = charDataAnim.name;
|
||||
charDataAnim.offsets = swagChar?.animationOffsets.get(animName);
|
||||
}
|
||||
}
|
||||
|
||||
return SerializerUtil.toJSON(charData, true);
|
||||
}
|
||||
|
||||
var swagChar:BaseCharacter;
|
||||
var swagChar:Null<BaseCharacter>;
|
||||
|
||||
/*
|
||||
Called when animation dropdown is changed!
|
||||
|
@ -483,86 +515,97 @@ class DebugBoundingState extends FlxState
|
|||
{
|
||||
if (swagChar != null)
|
||||
{
|
||||
offsetView.remove(swagChar);
|
||||
if (offsetView != null) offsetView.remove(swagChar);
|
||||
swagChar.destroy();
|
||||
}
|
||||
|
||||
swagChar = CharacterDataParser.fetchCharacter(char);
|
||||
swagChar.x = 100;
|
||||
swagChar.y = 100;
|
||||
swagChar.debug = true;
|
||||
offsetView.add(swagChar);
|
||||
|
||||
if (swagChar == null || swagChar.frames == null)
|
||||
{
|
||||
trace('ERROR: Failed to load character ${char}!');
|
||||
}
|
||||
else if (swagChar != null)
|
||||
{
|
||||
swagChar.x = 100;
|
||||
swagChar.y = 100;
|
||||
swagChar.debug = true;
|
||||
if (offsetView != null) offsetView.add(swagChar);
|
||||
|
||||
generateOutlines(swagChar.frames.frames);
|
||||
bf.pixels = swagChar.pixels;
|
||||
if (bf != null) bf.pixels = swagChar.pixels;
|
||||
|
||||
clearInfo();
|
||||
addInfo(swagChar._data.assetPath, "");
|
||||
addInfo('Width', bf.width);
|
||||
addInfo('Height', bf.height);
|
||||
if (bf != null) addInfo('Width', bf.width);
|
||||
if (bf != null) addInfo('Height', bf.height);
|
||||
|
||||
characterAnimNames = [];
|
||||
|
||||
for (i in swagChar.animationOffsets.keys())
|
||||
var keys = swagChar.animationOffsets?.keys();
|
||||
if (keys != null)
|
||||
for (i in keys)
|
||||
{
|
||||
characterAnimNames.push(i);
|
||||
trace(i);
|
||||
trace(swagChar.animationOffsets[i]);
|
||||
trace(swagChar?.animationOffsets[i]);
|
||||
}
|
||||
|
||||
offsetAnimationDropdown.dataSource.clear();
|
||||
if (offsetAnimationDropdown != null){
|
||||
offsetAnimationDropdown.dataSource.clear();
|
||||
|
||||
for (charAnim in characterAnimNames)
|
||||
{
|
||||
trace('Adding ${charAnim} to HaxeUI dropdown');
|
||||
offsetAnimationDropdown.dataSource.add({id: charAnim, text: charAnim});
|
||||
}
|
||||
|
||||
offsetAnimationDropdown.selectedIndex = 0;
|
||||
|
||||
trace('Added ${offsetAnimationDropdown.dataSource.size} to HaxeUI dropdown');
|
||||
|
||||
offsetAnimationDropdown.onChange = function(event:UIEvent) {
|
||||
if (event.data != null)
|
||||
for (charAnim in characterAnimNames)
|
||||
{
|
||||
trace('Selected animation ${event.data.id}');
|
||||
trace('Adding ${charAnim} to HaxeUI dropdown');
|
||||
offsetAnimationDropdown.dataSource.add({id: charAnim, text: charAnim});
|
||||
}
|
||||
|
||||
offsetAnimationDropdown.selectedIndex = 0;
|
||||
|
||||
trace('Added ${offsetAnimationDropdown.dataSource.size} to HaxeUI dropdown');
|
||||
|
||||
offsetAnimationDropdown.onChange = function(event:UIEvent) {
|
||||
if (event?.data?.id == null) return;
|
||||
trace('Selected animation ${event?.data?.id}');
|
||||
playCharacterAnimation(event.data.id, true);
|
||||
}
|
||||
}
|
||||
|
||||
txtOffsetShit.text = 'Offset: ' + swagChar.animOffsets;
|
||||
txtOffsetShit.y = FlxG.height - 20 - txtOffsetShit.height;
|
||||
if (txtOffsetShit != null)
|
||||
{
|
||||
txtOffsetShit.text = 'Offset: ' + swagChar?.animOffsets;
|
||||
txtOffsetShit.y = FlxG.height - 20 - txtOffsetShit.height;
|
||||
}
|
||||
dropDownSetup = true;
|
||||
}
|
||||
}
|
||||
|
||||
private var characterAnimNames:Array<String>;
|
||||
private var characterAnimNames:Null<Array<String>>;
|
||||
|
||||
function playCharacterAnimation(str:String, setOnionSkin:Bool = true)
|
||||
{
|
||||
if (setOnionSkin)
|
||||
if (setOnionSkin && onionSkinChar != null)
|
||||
{
|
||||
// clears the canvas
|
||||
onionSkinChar.pixels.fillRect(new Rectangle(0, 0, FlxG.width * 2, FlxG.height * 2), 0x00000000);
|
||||
|
||||
onionSkinChar.stamp(swagChar, Std.int(swagChar.x), Std.int(swagChar.y));
|
||||
if (swagChar != null) onionSkinChar.stamp(swagChar, Std.int(swagChar.x), Std.int(swagChar.y));
|
||||
onionSkinChar.alpha = 0.6;
|
||||
}
|
||||
|
||||
// var animName = characterAnimNames[Std.parseInt(str)];
|
||||
var animName = str;
|
||||
swagChar.playAnimation(animName, true); // trace();
|
||||
trace(swagChar.animationOffsets.get(animName));
|
||||
if (swagChar != null) swagChar.playAnimation(animName, true);
|
||||
trace(swagChar?.animationOffsets.get(animName));
|
||||
|
||||
txtOffsetShit.text = 'Offset: ' + swagChar.animOffsets;
|
||||
txtOffsetShit.y = FlxG.height - 20 - txtOffsetShit.height;
|
||||
if (txtOffsetShit != null)
|
||||
{
|
||||
txtOffsetShit.text = 'Offset: ' + swagChar?.animOffsets;
|
||||
txtOffsetShit.y = FlxG.height - 20 - txtOffsetShit.height;
|
||||
}
|
||||
}
|
||||
|
||||
var _file:FileReference;
|
||||
var _file:Null<FileReference>;
|
||||
|
||||
function saveOffsets(saveString:String, fileName:String)
|
||||
{
|
||||
|
@ -578,11 +621,13 @@ class DebugBoundingState extends FlxState
|
|||
|
||||
function onSaveComplete(_):Void
|
||||
{
|
||||
if (_file != null){
|
||||
_file.removeEventListener(Event.COMPLETE, onSaveComplete);
|
||||
_file.removeEventListener(Event.CANCEL, onSaveCancel);
|
||||
_file.removeEventListener(IOErrorEvent.IO_ERROR, onSaveError);
|
||||
_file = null;
|
||||
FlxG.log.notice("Successfully saved LEVEL DATA.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -590,10 +635,13 @@ class DebugBoundingState extends FlxState
|
|||
*/
|
||||
function onSaveCancel(_):Void
|
||||
{
|
||||
if (_file != null)
|
||||
{
|
||||
_file.removeEventListener(Event.COMPLETE, onSaveComplete);
|
||||
_file.removeEventListener(Event.CANCEL, onSaveCancel);
|
||||
_file.removeEventListener(IOErrorEvent.IO_ERROR, onSaveError);
|
||||
_file = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -601,11 +649,14 @@ class DebugBoundingState extends FlxState
|
|||
*/
|
||||
function onSaveError(_):Void
|
||||
{
|
||||
if (_file != null)
|
||||
{
|
||||
_file.removeEventListener(Event.COMPLETE, onSaveComplete);
|
||||
_file.removeEventListener(Event.CANCEL, onSaveCancel);
|
||||
_file.removeEventListener(IOErrorEvent.IO_ERROR, onSaveError);
|
||||
_file = null;
|
||||
FlxG.log.error("Problem saving Level data");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -69,7 +69,8 @@ class OptionsState extends MusicBeatState
|
|||
optionsCodex = new Codex<OptionsMenuPageName>(Options);
|
||||
add(optionsCodex);
|
||||
|
||||
var options:OptionsMenu = optionsCodex.addPage(Options, new OptionsMenu());
|
||||
var saveData:SaveDataMenu = optionsCodex.addPage(SaveData, new SaveDataMenu());
|
||||
var options:OptionsMenu = optionsCodex.addPage(Options, new OptionsMenu(saveData));
|
||||
var preferences:PreferencesMenu = optionsCodex.addPage(Preferences, new PreferencesMenu());
|
||||
var controls:ControlsMenu = optionsCodex.addPage(Controls, new ControlsMenu());
|
||||
#if FEATURE_INPUT_OFFSETS
|
||||
|
@ -84,6 +85,7 @@ class OptionsState extends MusicBeatState
|
|||
#if FEATURE_INPUT_OFFSETS
|
||||
offsets.onExit.add(exitOffsets);
|
||||
#end
|
||||
saveData.onExit.add(optionsCodex.switchPage.bind(Options));
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -159,7 +161,7 @@ class OptionsMenu extends Page<OptionsMenuPageName>
|
|||
|
||||
final CAMERA_MARGIN:Int = 150;
|
||||
|
||||
public function new()
|
||||
public function new(saveDataMenu:SaveDataMenu)
|
||||
{
|
||||
super();
|
||||
add(items = new TextMenuList());
|
||||
|
@ -227,9 +229,19 @@ class OptionsMenu extends Page<OptionsMenuPageName>
|
|||
});
|
||||
}
|
||||
#end
|
||||
createItem("CLEAR SAVE DATA", function() {
|
||||
promptClearSaveData();
|
||||
});
|
||||
|
||||
// no need to show an entire new menu for just one option
|
||||
if (saveDataMenu.hasMultipleOptions())
|
||||
{
|
||||
createItem("SAVE DATA OPTIONS", function() {
|
||||
codex.switchPage(SaveData);
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
createItem("CLEAR SAVE DATA", saveDataMenu.openSaveDataPrompt);
|
||||
}
|
||||
|
||||
#if NO_FEATURE_TOUCH_CONTROLS
|
||||
createItem("EXIT", exit);
|
||||
#else
|
||||
|
@ -277,7 +289,6 @@ class OptionsMenu extends Page<OptionsMenuPageName>
|
|||
|
||||
override function update(elapsed:Float):Void
|
||||
{
|
||||
enabled = (prompt == null);
|
||||
#if FEATURE_TOUCH_CONTROLS
|
||||
backButton.active = (!goingBack) ? !items.busy : true;
|
||||
#end
|
||||
|
@ -298,31 +309,6 @@ class OptionsMenu extends Page<OptionsMenuPageName>
|
|||
{
|
||||
return items.length > 2;
|
||||
}
|
||||
|
||||
var prompt:Prompt;
|
||||
|
||||
function promptClearSaveData():Void
|
||||
{
|
||||
if (prompt != null) return;
|
||||
prompt = new Prompt("This will delete
|
||||
\nALL your save data.
|
||||
\nAre you sure?
|
||||
", Custom("Delete", "Cancel"));
|
||||
prompt.create();
|
||||
prompt.createBgFromMargin(100, 0xFFFAFD6D);
|
||||
prompt.back.scrollFactor.set(0, 0);
|
||||
add(prompt);
|
||||
prompt.onYes = function() {
|
||||
// Clear the save data.
|
||||
funkin.save.Save.clearData();
|
||||
FlxG.switchState(() -> new funkin.InitState());
|
||||
};
|
||||
prompt.onNo = function() {
|
||||
prompt.close();
|
||||
prompt.destroy();
|
||||
prompt = null;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
enum abstract OptionsMenuPageName(String) to PageName
|
||||
|
@ -333,4 +319,5 @@ enum abstract OptionsMenuPageName(String) to PageName
|
|||
var Mods = "mods";
|
||||
var Preferences = "preferences";
|
||||
var Offsets = "offsets";
|
||||
var SaveData = "saveData";
|
||||
}
|
||||
|
|
125
source/funkin/ui/options/SaveDataMenu.hx
Normal file
125
source/funkin/ui/options/SaveDataMenu.hx
Normal file
|
@ -0,0 +1,125 @@
|
|||
package funkin.ui.options;
|
||||
|
||||
#if FEATURE_NEWGROUNDS
|
||||
import funkin.api.newgrounds.NewgroundsClient;
|
||||
#end
|
||||
import funkin.save.Save;
|
||||
|
||||
class SaveDataMenu extends Page<OptionsState.OptionsMenuPageName>
|
||||
{
|
||||
var items:TextMenuList;
|
||||
|
||||
public function new()
|
||||
{
|
||||
super();
|
||||
|
||||
add(items = new TextMenuList());
|
||||
|
||||
createItem("CLEAR SAVE DATA", openSaveDataPrompt);
|
||||
|
||||
#if FEATURE_NEWGROUNDS
|
||||
if (NewgroundsClient.instance.isLoggedIn())
|
||||
{
|
||||
createItem("LOAD FROM NG", function() {
|
||||
openConfirmPrompt("This will overwrite
|
||||
\nALL your save data.
|
||||
\nAre you sure?
|
||||
", "Overwrite", function() {
|
||||
Save.loadFromNewgrounds(function() {
|
||||
FlxG.switchState(() -> new funkin.InitState());
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
createItem("SAVE TO NG", function() {
|
||||
openConfirmPrompt("This will overwrite
|
||||
\nALL save data saved
|
||||
\non NG. Are you sure?", "Overwrite", function() {
|
||||
Save.saveToNewgrounds();
|
||||
});
|
||||
});
|
||||
|
||||
createItem("CLEAR NG SAVE DATA", function() {
|
||||
openConfirmPrompt("This will delete
|
||||
\nALL save data saved
|
||||
\non NG. Are you sure?", "Delete", function() {
|
||||
funkin.api.newgrounds.NGSaveSlot.instance.clear();
|
||||
});
|
||||
});
|
||||
}
|
||||
#end
|
||||
|
||||
createItem("EXIT", exit);
|
||||
}
|
||||
|
||||
function createItem(name:String, callback:Void->Void, fireInstantly = false)
|
||||
{
|
||||
var item = items.createItem(0, 100 + items.length * 100, name, BOLD, callback);
|
||||
item.fireInstantly = fireInstantly;
|
||||
item.screenCenter(X);
|
||||
return item;
|
||||
}
|
||||
|
||||
override function update(elapsed:Float)
|
||||
{
|
||||
enabled = (prompt == null);
|
||||
super.update(elapsed);
|
||||
}
|
||||
|
||||
override function set_enabled(value:Bool)
|
||||
{
|
||||
items.enabled = value;
|
||||
return super.set_enabled(value);
|
||||
}
|
||||
|
||||
var prompt:Prompt;
|
||||
|
||||
function openConfirmPrompt(text:String, yesText:String, onYes:Void->Void, ?groupToOpenOn:Null<flixel.group.FlxGroup>):Void
|
||||
{
|
||||
if (prompt != null) return;
|
||||
|
||||
prompt = new Prompt(text, Custom(yesText, "Cancel"));
|
||||
prompt.create();
|
||||
prompt.createBgFromMargin(100, 0xFFFAFD6D);
|
||||
prompt.back.scrollFactor.set(0, 0);
|
||||
FlxG.state.add(prompt);
|
||||
|
||||
prompt.onYes = function() {
|
||||
onYes();
|
||||
|
||||
if (prompt != null)
|
||||
{
|
||||
prompt.close();
|
||||
prompt.destroy();
|
||||
prompt = null;
|
||||
}
|
||||
};
|
||||
|
||||
prompt.onNo = function() {
|
||||
prompt.close();
|
||||
prompt.destroy();
|
||||
prompt = null;
|
||||
}
|
||||
}
|
||||
public function openSaveDataPrompt()
|
||||
{
|
||||
openConfirmPrompt("This will delete
|
||||
\nALL your save data.
|
||||
\nAre you sure?
|
||||
", "Delete", function() {
|
||||
// Clear the save data.
|
||||
Save.clearData();
|
||||
|
||||
FlxG.switchState(() -> new funkin.InitState());
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* True if this page has multiple options, excluding the exit option.
|
||||
* If false, there's no reason to ever show this page.
|
||||
*/
|
||||
public function hasMultipleOptions():Bool
|
||||
{
|
||||
return items.length > 2;
|
||||
}
|
||||
}
|
|
@ -102,12 +102,19 @@ class WindowUtil
|
|||
*/
|
||||
public static final windowExit:FlxTypedSignal<Int->Void> = new FlxTypedSignal<Int->Void>();
|
||||
|
||||
/**
|
||||
* Has `initWindowEvents()` been called already?
|
||||
* This is to prevent multiple instances of the same function.
|
||||
*/
|
||||
private static var _initializedWindowEvents:Bool = false;
|
||||
|
||||
/**
|
||||
* Wires up FlxSignals that happen based on window activity.
|
||||
* For example, we can run a callback when the window is closed.
|
||||
*/
|
||||
public static function initWindowEvents():Void
|
||||
{
|
||||
if (_initializedWindowEvents) return; // Fix that annoying
|
||||
// onUpdate is called every frame just before rendering.
|
||||
|
||||
// onExit is called when the game window is closed.
|
||||
|
@ -137,6 +144,7 @@ class WindowUtil
|
|||
}
|
||||
});
|
||||
#end
|
||||
_initializedWindowEvents = true;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in a new issue