mirror of
https://github.com/ninjamuffin99/Funkin.git
synced 2025-04-01 15:25:25 +00:00
Merge remote-tracking branch 'secret/rewrite/master' into lemz1/substate-event-dispatch
This commit is contained in:
commit
7d6fa19ff4
44
.github/label-actions.yml
vendored
Normal file
44
.github/label-actions.yml
vendored
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
# Configuration for Label Actions - https://github.com/dessant/label-actions
|
||||||
|
|
||||||
|
# Automatically close issues and pull requests when the `status: duplicate` label is applied
|
||||||
|
'status: duplicate':
|
||||||
|
issues:
|
||||||
|
# Post a comment
|
||||||
|
comment: >
|
||||||
|
This issue is a duplicate. Please direct all discussion to the original issue.
|
||||||
|
# Close the issue
|
||||||
|
close: true
|
||||||
|
# Remove other status labels
|
||||||
|
unlabel:
|
||||||
|
- 'status: pending triage'
|
||||||
|
# Set a close reason
|
||||||
|
close-reason: 'not planned'
|
||||||
|
prs:
|
||||||
|
# Post a comment
|
||||||
|
comment: >
|
||||||
|
This pull request is a duplicate. Please direct all discussion to the original pull request.
|
||||||
|
# Remove other status labels
|
||||||
|
unlabel:
|
||||||
|
- 'status: pending triage'
|
||||||
|
# Close the pull request
|
||||||
|
close: true
|
||||||
|
# Set a close reason
|
||||||
|
close-reason: 'not planned'
|
||||||
|
|
||||||
|
'status: rejected':
|
||||||
|
issues:
|
||||||
|
# Close the issue
|
||||||
|
close: true
|
||||||
|
# Remove other status labels
|
||||||
|
unlabel:
|
||||||
|
- 'status: pending triage'
|
||||||
|
# Set a close reason
|
||||||
|
close-reason: 'not planned'
|
||||||
|
prs:
|
||||||
|
# Close the pull request
|
||||||
|
close: true
|
||||||
|
# Remove other status labels
|
||||||
|
unlabel:
|
||||||
|
- 'status: pending triage'
|
||||||
|
# Set a close reason
|
||||||
|
close-reason: 'not planned'
|
29
.github/workflows/label-actions.yml
vendored
Normal file
29
.github/workflows/label-actions.yml
vendored
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
# Perform actions when labels are applied to issues, discussions, or pull requests
|
||||||
|
# See .github/label-actions.yml
|
||||||
|
name: 'Label Actions'
|
||||||
|
|
||||||
|
on:
|
||||||
|
issues:
|
||||||
|
types:
|
||||||
|
- labeled
|
||||||
|
- unlabeled
|
||||||
|
pull_request_target:
|
||||||
|
types:
|
||||||
|
- labeled
|
||||||
|
- unlabeled
|
||||||
|
discussion:
|
||||||
|
types:
|
||||||
|
- labeled
|
||||||
|
- unlabeled
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
issues: write
|
||||||
|
pull-requests: write
|
||||||
|
discussions: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
action:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: dessant/label-actions@v4
|
52
.github/workflows/label-issue.yml
vendored
Normal file
52
.github/workflows/label-issue.yml
vendored
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
name: "Issue Labeler"
|
||||||
|
on:
|
||||||
|
issues:
|
||||||
|
types:
|
||||||
|
- opened
|
||||||
|
- reopened
|
||||||
|
- edited
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
# When an issue is opened, perform a similarity check for potential duplicates.
|
||||||
|
# If some are found, add a label and comment listing the potential duplicate issues.
|
||||||
|
potential-duplicate:
|
||||||
|
name: Detect potential duplicate issues
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: wow-actions/potential-duplicates@v1
|
||||||
|
with:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
# Issue title filter work with anymatch https://www.npmjs.com/package/anymatch.
|
||||||
|
# Any matched issue will stop detection immediately.
|
||||||
|
# You can specify multi filters in each line.
|
||||||
|
filter: ''
|
||||||
|
# Exclude keywords in title before detecting.
|
||||||
|
exclude: ''
|
||||||
|
# Label to set, when potential duplicates are detected.
|
||||||
|
label: 'potential duplicate'
|
||||||
|
# Get issues with state to compare. Supported state: 'all', 'closed', 'open'.
|
||||||
|
state: all
|
||||||
|
# If similarity is higher than this threshold([0,1]), issue will be marked as duplicate.
|
||||||
|
# Turn this up if the detection is too sensitive
|
||||||
|
threshold: 0.6
|
||||||
|
# Reactions to be add to comment when potential duplicates are detected.
|
||||||
|
# Available reactions: "-1", "+1", "confused", "laugh", "heart", "hooray", "rocket", "eyes"
|
||||||
|
# reactions: '-1'
|
||||||
|
# Comment to post when potential duplicates are detected.
|
||||||
|
comment: >
|
||||||
|
Potential duplicates: {{#issues}}
|
||||||
|
- [#{{ number }}] {{ title }} ({{ accuracy }}%)
|
||||||
|
{{/issues}}
|
||||||
|
# When an issue is opened, detect if it has an empty body or incomplete issue form.
|
||||||
|
# If it does, close the issue immediately.
|
||||||
|
empty-issues:
|
||||||
|
name: Close empty issues
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Run empty issues closer action
|
||||||
|
uses: rickstaa/empty-issues-closer-action@v1
|
||||||
|
env:
|
||||||
|
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
with:
|
||||||
|
close_comment: Closing this issue because it appears to be empty. Please update the issue for it to be reopened.
|
||||||
|
open_comment: Reopening this issue because the author provided more information.
|
|
@ -3,6 +3,7 @@ on:
|
||||||
- pull_request_target
|
- pull_request_target
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
# Apply labels to pull requests based on which files were edited
|
||||||
labeler:
|
labeler:
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
|
@ -13,6 +14,7 @@ jobs:
|
||||||
uses: actions/labeler@v5
|
uses: actions/labeler@v5
|
||||||
with:
|
with:
|
||||||
sync-labels: true
|
sync-labels: true
|
||||||
|
# Apply labels to pull requests based on how many lines were edited
|
||||||
changed-lines-count-labeler:
|
changed-lines-count-labeler:
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
4
.gitmodules
vendored
4
.gitmodules
vendored
|
@ -1,6 +1,6 @@
|
||||||
[submodule "assets"]
|
[submodule "assets"]
|
||||||
path = assets
|
path = assets
|
||||||
url = https://github.com/FunkinCrew/funkin.assets
|
url = https://github.com/FunkinCrew/Funkin-assets-secret
|
||||||
[submodule "art"]
|
[submodule "art"]
|
||||||
path = art
|
path = art
|
||||||
url = https://github.com/FunkinCrew/funkin.art
|
url = https://github.com/FunkinCrew/Funkin-art-secret
|
||||||
|
|
2
assets
2
assets
|
@ -1 +1 @@
|
||||||
Subproject commit bc7009b4242691faa5c4552f7ca8a2f28e8cb1d2
|
Subproject commit 252d48f4c996d5832cb981fb2f3ed945c020f289
|
|
@ -6,7 +6,7 @@
|
||||||
"name": "EliteMasterEric"
|
"name": "EliteMasterEric"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"api_version": "0.1.0",
|
"api_version": "0.5.0",
|
||||||
"mod_version": "1.0.0",
|
"mod_version": "1.0.0",
|
||||||
"license": "Apache-2.0"
|
"license": "Apache-2.0"
|
||||||
}
|
}
|
||||||
|
|
4
hmm.json
4
hmm.json
|
@ -70,14 +70,14 @@
|
||||||
"name": "haxeui-core",
|
"name": "haxeui-core",
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"dir": null,
|
"dir": null,
|
||||||
"ref": "22f7c5a8ffca90d4677cffd6e570f53761709fbc",
|
"ref": "c9d96b168ea2a19274ad7c766ab1a34b57baa793",
|
||||||
"url": "https://github.com/haxeui/haxeui-core"
|
"url": "https://github.com/haxeui/haxeui-core"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "haxeui-flixel",
|
"name": "haxeui-flixel",
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"dir": null,
|
"dir": null,
|
||||||
"ref": "28bb710d0ae5d94b5108787593052165be43b980",
|
"ref": "013b9d4e56bfe9a034e028a8d685f0b274cb73c4",
|
||||||
"url": "https://github.com/haxeui/haxeui-flixel"
|
"url": "https://github.com/haxeui/haxeui-flixel"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|
|
@ -270,6 +270,7 @@ typedef PlayerResultsData =
|
||||||
{
|
{
|
||||||
var music:PlayerResultsMusicData;
|
var music:PlayerResultsMusicData;
|
||||||
|
|
||||||
|
var perfectGold:Array<PlayerResultsAnimationData>;
|
||||||
var perfect:Array<PlayerResultsAnimationData>;
|
var perfect:Array<PlayerResultsAnimationData>;
|
||||||
var excellent:Array<PlayerResultsAnimationData>;
|
var excellent:Array<PlayerResultsAnimationData>;
|
||||||
var great:Array<PlayerResultsAnimationData>;
|
var great:Array<PlayerResultsAnimationData>;
|
||||||
|
|
|
@ -184,7 +184,7 @@ class FlxAtlasSprite extends FlxAnimate
|
||||||
|
|
||||||
// Move to the first frame of the animation.
|
// Move to the first frame of the animation.
|
||||||
// goToFrameLabel(id);
|
// goToFrameLabel(id);
|
||||||
trace('Playing animation $id');
|
// trace('Playing animation $id');
|
||||||
if ((id == null || id == "") || this.anim.symbolDictionary.exists(id) || (this.anim.getByName(id) != null))
|
if ((id == null || id == "") || this.anim.symbolDictionary.exists(id) || (this.anim.getByName(id) != null))
|
||||||
{
|
{
|
||||||
this.anim.play(id, restart, false, startFrame);
|
this.anim.play(id, restart, false, startFrame);
|
||||||
|
|
|
@ -258,7 +258,7 @@ class PolymodHandler
|
||||||
Polymod.blacklistImport('cpp.Lib');
|
Polymod.blacklistImport('cpp.Lib');
|
||||||
|
|
||||||
// `Unserializer`
|
// `Unserializer`
|
||||||
// Unserializerr.DEFAULT_RESOLVER.resolveClass() can access blacklisted packages
|
// Unserializer.DEFAULT_RESOLVER.resolveClass() can access blacklisted packages
|
||||||
Polymod.blacklistImport('Unserializer');
|
Polymod.blacklistImport('Unserializer');
|
||||||
|
|
||||||
// `lime.system.CFFI`
|
// `lime.system.CFFI`
|
||||||
|
|
|
@ -472,9 +472,12 @@ class ResultState extends MusicBeatSubState
|
||||||
{
|
{
|
||||||
ease: FlxEase.quartOut,
|
ease: FlxEase.quartOut,
|
||||||
onUpdate: _ -> {
|
onUpdate: _ -> {
|
||||||
|
clearPercentLerp = Math.round(clearPercentLerp);
|
||||||
|
clearPercentCounter.curNumber = Math.round(clearPercentCounter.curNumber);
|
||||||
// Only play the tick sound if the number increased.
|
// Only play the tick sound if the number increased.
|
||||||
if (clearPercentLerp != clearPercentCounter.curNumber)
|
if (clearPercentLerp != clearPercentCounter.curNumber)
|
||||||
{
|
{
|
||||||
|
trace('$clearPercentLerp and ${clearPercentCounter.curNumber}');
|
||||||
clearPercentLerp = clearPercentCounter.curNumber;
|
clearPercentLerp = clearPercentCounter.curNumber;
|
||||||
FunkinSound.playOnce(Paths.sound('scrollMenu'));
|
FunkinSound.playOnce(Paths.sound('scrollMenu'));
|
||||||
}
|
}
|
||||||
|
|
|
@ -575,7 +575,7 @@ class NoteStyle implements IRegistryEntry<NoteStyleData>
|
||||||
var result = _data.assets.judgementBad?.isPixel;
|
var result = _data.assets.judgementBad?.isPixel;
|
||||||
if (result == null && fallback != null) result = fallback.isJudgementSpritePixel(rating);
|
if (result == null && fallback != null) result = fallback.isJudgementSpritePixel(rating);
|
||||||
return result ?? false;
|
return result ?? false;
|
||||||
case "GO":
|
case "shit":
|
||||||
var result = _data.assets.judgementShit?.isPixel;
|
var result = _data.assets.judgementShit?.isPixel;
|
||||||
if (result == null && fallback != null) result = fallback.isJudgementSpritePixel(rating);
|
if (result == null && fallback != null) result = fallback.isJudgementSpritePixel(rating);
|
||||||
return result ?? false;
|
return result ?? false;
|
||||||
|
|
|
@ -17,7 +17,7 @@ import thx.semver.Version;
|
||||||
@:nullSafety
|
@:nullSafety
|
||||||
class Save
|
class Save
|
||||||
{
|
{
|
||||||
public static final SAVE_DATA_VERSION:thx.semver.Version = "2.0.5";
|
public static final SAVE_DATA_VERSION:thx.semver.Version = "2.0.4";
|
||||||
public static final SAVE_DATA_VERSION_RULE:thx.semver.VersionRule = "2.0.x";
|
public static final SAVE_DATA_VERSION_RULE:thx.semver.VersionRule = "2.0.x";
|
||||||
|
|
||||||
// We load this version's saves from a new save path, to maintain SOME level of backwards compatibility.
|
// We load this version's saves from a new save path, to maintain SOME level of backwards compatibility.
|
||||||
|
@ -34,19 +34,19 @@ class Save
|
||||||
{
|
{
|
||||||
if (_instance == null)
|
if (_instance == null)
|
||||||
{
|
{
|
||||||
_instance = new Save(FlxG.save.data);
|
return _instance = load();
|
||||||
}
|
}
|
||||||
return _instance;
|
return _instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
var data:RawSaveData;
|
var data:RawSaveData;
|
||||||
|
|
||||||
public static function load():Void
|
public static function load():Save
|
||||||
{
|
{
|
||||||
trace("[SAVE] Loading save...");
|
trace("[SAVE] Loading save...");
|
||||||
|
|
||||||
// Bind save data.
|
// Bind save data.
|
||||||
loadFromSlot(1);
|
return loadFromSlot(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -65,7 +65,9 @@ class Save
|
||||||
public static function getDefault():RawSaveData
|
public static function getDefault():RawSaveData
|
||||||
{
|
{
|
||||||
return {
|
return {
|
||||||
version: Save.SAVE_DATA_VERSION,
|
// Version number is an abstract(Array) internally.
|
||||||
|
// This means it copies by reference, so merging save data overides the version number lol.
|
||||||
|
version: thx.Dynamics.clone(Save.SAVE_DATA_VERSION),
|
||||||
|
|
||||||
volume: 1.0,
|
volume: 1.0,
|
||||||
mute: false,
|
mute: false,
|
||||||
|
@ -433,7 +435,9 @@ class Save
|
||||||
{
|
{
|
||||||
if (!data.unlocks.charactersSeen.contains(character))
|
if (!data.unlocks.charactersSeen.contains(character))
|
||||||
{
|
{
|
||||||
|
trace('Character seen: ' + character);
|
||||||
data.unlocks.charactersSeen.push(character);
|
data.unlocks.charactersSeen.push(character);
|
||||||
|
trace('New characters seen list: ' + data.unlocks.charactersSeen);
|
||||||
flush();
|
flush();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -832,7 +836,7 @@ class Save
|
||||||
* If you set slot to `2`, it will load an independe
|
* If you set slot to `2`, it will load an independe
|
||||||
* @param slot
|
* @param slot
|
||||||
*/
|
*/
|
||||||
static function loadFromSlot(slot:Int):Void
|
static function loadFromSlot(slot:Int):Save
|
||||||
{
|
{
|
||||||
trace("[SAVE] Loading save from slot " + slot + "...");
|
trace("[SAVE] Loading save from slot " + slot + "...");
|
||||||
|
|
||||||
|
@ -850,12 +854,14 @@ class Save
|
||||||
trace('[SAVE] Found legacy save data, converting...');
|
trace('[SAVE] Found legacy save data, converting...');
|
||||||
var gameSave = SaveDataMigrator.migrateFromLegacy(legacySaveData);
|
var gameSave = SaveDataMigrator.migrateFromLegacy(legacySaveData);
|
||||||
FlxG.save.mergeData(gameSave.data, true);
|
FlxG.save.mergeData(gameSave.data, true);
|
||||||
|
return gameSave;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
trace('[SAVE] No legacy save data found.');
|
trace('[SAVE] No legacy save data found.');
|
||||||
var gameSave = new Save();
|
var gameSave = new Save();
|
||||||
FlxG.save.mergeData(gameSave.data, true);
|
FlxG.save.mergeData(gameSave.data, true);
|
||||||
|
return gameSave;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -863,6 +869,8 @@ class Save
|
||||||
trace('[SAVE] Found existing save data.');
|
trace('[SAVE] Found existing save data.');
|
||||||
var gameSave = SaveDataMigrator.migrate(FlxG.save.data);
|
var gameSave = SaveDataMigrator.migrate(FlxG.save.data);
|
||||||
FlxG.save.mergeData(gameSave.data, true);
|
FlxG.save.mergeData(gameSave.data, true);
|
||||||
|
|
||||||
|
return gameSave;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file.
|
||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
## [2.0.4] - 2024-09-12
|
||||||
|
Note to self: Only update to 2.1.0 when migration is needed.
|
||||||
|
### Added
|
||||||
|
- `unlocks.charactersSeen:Array<String>` to `Save`
|
||||||
|
- `unlocks.oldChar:Bool` to `Save`
|
||||||
|
|
||||||
## [2.0.5] - 2024-05-21
|
## [2.0.5] - 2024-05-21
|
||||||
### Fixed
|
### Fixed
|
||||||
- Resolved an issue where HTML5 wouldn't store the semantic version properly, causing the game to fail to load the save.
|
- Resolved an issue where HTML5 wouldn't store the semantic version properly, causing the game to fail to load the save.
|
||||||
|
|
|
@ -47,7 +47,6 @@ class CharSelectPlayer extends FlxAtlasSprite implements IBPMSyncedScriptedClass
|
||||||
//
|
//
|
||||||
if (getCurrentAnimation() == "idle")
|
if (getCurrentAnimation() == "idle")
|
||||||
{
|
{
|
||||||
trace('Player beat hit');
|
|
||||||
playAnimation("idle", true, false, false);
|
playAnimation("idle", true, false, false);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -700,7 +700,7 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
|
||||||
|
|
||||||
function get_isCursorOverHaxeUI():Bool
|
function get_isCursorOverHaxeUI():Bool
|
||||||
{
|
{
|
||||||
return Screen.instance.hasSolidComponentUnderPoint(FlxG.mouse.screenX, FlxG.mouse.screenY);
|
return Screen.instance.hasSolidComponentUnderPoint(FlxG.mouse.viewX, FlxG.mouse.viewY);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -3840,7 +3840,7 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
|
||||||
// Handle scroll anchor
|
// Handle scroll anchor
|
||||||
if (scrollAnchorScreenPos != null)
|
if (scrollAnchorScreenPos != null)
|
||||||
{
|
{
|
||||||
var currentScreenPos = new FlxPoint(FlxG.mouse.screenX, FlxG.mouse.screenY);
|
var currentScreenPos = new FlxPoint(FlxG.mouse.viewX, FlxG.mouse.viewX);
|
||||||
var distance = currentScreenPos - scrollAnchorScreenPos;
|
var distance = currentScreenPos - scrollAnchorScreenPos;
|
||||||
|
|
||||||
var verticalDistance = distance.y;
|
var verticalDistance = distance.y;
|
||||||
|
@ -4121,8 +4121,8 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
|
||||||
var overlapsRenderedEvents:Bool = FlxG.mouse.overlaps(renderedEvents);
|
var overlapsRenderedEvents:Bool = FlxG.mouse.overlaps(renderedEvents);
|
||||||
|
|
||||||
// Cursor position relative to the grid.
|
// Cursor position relative to the grid.
|
||||||
var cursorX:Float = FlxG.mouse.screenX - gridTiledSprite.x;
|
var cursorX:Float = FlxG.mouse.viewX - gridTiledSprite.x;
|
||||||
var cursorY:Float = FlxG.mouse.screenY - gridTiledSprite.y;
|
var cursorY:Float = FlxG.mouse.viewY - gridTiledSprite.y;
|
||||||
|
|
||||||
var overlapsSelectionBorder:Bool = overlapsGrid
|
var overlapsSelectionBorder:Bool = overlapsGrid
|
||||||
&& ((cursorX % 40) < (GRID_SELECTION_BORDER_WIDTH / 2)
|
&& ((cursorX % 40) < (GRID_SELECTION_BORDER_WIDTH / 2)
|
||||||
|
@ -4137,7 +4137,7 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
|
||||||
{
|
{
|
||||||
if (scrollAnchorScreenPos == null)
|
if (scrollAnchorScreenPos == null)
|
||||||
{
|
{
|
||||||
scrollAnchorScreenPos = new FlxPoint(FlxG.mouse.screenX, FlxG.mouse.screenY);
|
scrollAnchorScreenPos = new FlxPoint(FlxG.mouse.viewX, FlxG.mouse.viewY);
|
||||||
selectionBoxStartPos = null;
|
selectionBoxStartPos = null;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -4159,11 +4159,11 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
|
||||||
else if (notePreview != null && FlxG.mouse.overlaps(notePreview) && !isCursorOverHaxeUI)
|
else if (notePreview != null && FlxG.mouse.overlaps(notePreview) && !isCursorOverHaxeUI)
|
||||||
{
|
{
|
||||||
// Clicked note preview
|
// Clicked note preview
|
||||||
notePreviewScrollAreaStartPos = new FlxPoint(FlxG.mouse.screenX, FlxG.mouse.screenY);
|
notePreviewScrollAreaStartPos = new FlxPoint(FlxG.mouse.viewX, FlxG.mouse.viewY);
|
||||||
}
|
}
|
||||||
else if (!isCursorOverHaxeUI && (!overlapsGrid || overlapsSelectionBorder))
|
else if (!isCursorOverHaxeUI && (!overlapsGrid || overlapsSelectionBorder))
|
||||||
{
|
{
|
||||||
selectionBoxStartPos = new FlxPoint(FlxG.mouse.screenX, FlxG.mouse.screenY);
|
selectionBoxStartPos = new FlxPoint(FlxG.mouse.viewX, FlxG.mouse.viewY);
|
||||||
// Drawing selection box.
|
// Drawing selection box.
|
||||||
targetCursorMode = Crosshair;
|
targetCursorMode = Crosshair;
|
||||||
}
|
}
|
||||||
|
@ -4188,7 +4188,7 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
|
||||||
{
|
{
|
||||||
// Clicked on the playhead scroll area.
|
// Clicked on the playhead scroll area.
|
||||||
// Move the playhead to the cursor position.
|
// Move the playhead to the cursor position.
|
||||||
this.playheadPositionInPixels = FlxG.mouse.screenY - (GRID_INITIAL_Y_POS);
|
this.playheadPositionInPixels = FlxG.mouse.viewY - (GRID_INITIAL_Y_POS);
|
||||||
moveSongToScrollPosition();
|
moveSongToScrollPosition();
|
||||||
|
|
||||||
// Cursor should be a grabby hand.
|
// Cursor should be a grabby hand.
|
||||||
|
@ -4313,27 +4313,27 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
|
||||||
// Clicking and dragging.
|
// Clicking and dragging.
|
||||||
|
|
||||||
// Scroll the screen if the mouse is above or below the grid.
|
// Scroll the screen if the mouse is above or below the grid.
|
||||||
if (FlxG.mouse.screenY < MENU_BAR_HEIGHT)
|
if (FlxG.mouse.viewY < MENU_BAR_HEIGHT)
|
||||||
{
|
{
|
||||||
// Scroll up.
|
// Scroll up.
|
||||||
var diff:Float = MENU_BAR_HEIGHT - FlxG.mouse.screenY;
|
var diff:Float = MENU_BAR_HEIGHT - FlxG.mouse.viewY;
|
||||||
scrollPositionInPixels -= diff * 0.5; // Too fast!
|
scrollPositionInPixels -= diff * 0.5; // Too fast!
|
||||||
moveSongToScrollPosition();
|
moveSongToScrollPosition();
|
||||||
}
|
}
|
||||||
else if (FlxG.mouse.screenY > (playbarHeadLayout?.y ?? 0.0))
|
else if (FlxG.mouse.viewY > (playbarHeadLayout?.y ?? 0.0))
|
||||||
{
|
{
|
||||||
// Scroll down.
|
// Scroll down.
|
||||||
var diff:Float = FlxG.mouse.screenY - (playbarHeadLayout?.y ?? 0.0);
|
var diff:Float = FlxG.mouse.viewY - (playbarHeadLayout?.y ?? 0.0);
|
||||||
scrollPositionInPixels += diff * 0.5; // Too fast!
|
scrollPositionInPixels += diff * 0.5; // Too fast!
|
||||||
moveSongToScrollPosition();
|
moveSongToScrollPosition();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Render the selection box.
|
// Render the selection box.
|
||||||
var selectionRect:FlxRect = new FlxRect();
|
var selectionRect:FlxRect = new FlxRect();
|
||||||
selectionRect.x = Math.min(FlxG.mouse.screenX, selectionBoxStartPos.x);
|
selectionRect.x = Math.min(FlxG.mouse.viewX, selectionBoxStartPos.x);
|
||||||
selectionRect.y = Math.min(FlxG.mouse.screenY, selectionBoxStartPos.y);
|
selectionRect.y = Math.min(FlxG.mouse.viewY, selectionBoxStartPos.y);
|
||||||
selectionRect.width = Math.abs(FlxG.mouse.screenX - selectionBoxStartPos.x);
|
selectionRect.width = Math.abs(FlxG.mouse.viewX - selectionBoxStartPos.x);
|
||||||
selectionRect.height = Math.abs(FlxG.mouse.screenY - selectionBoxStartPos.y);
|
selectionRect.height = Math.abs(FlxG.mouse.viewY - selectionBoxStartPos.y);
|
||||||
setSelectionBoxBounds(selectionRect);
|
setSelectionBoxBounds(selectionRect);
|
||||||
|
|
||||||
targetCursorMode = Crosshair;
|
targetCursorMode = Crosshair;
|
||||||
|
@ -4461,8 +4461,8 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
|
||||||
// Player is clicking and holding on note preview to scrub around.
|
// Player is clicking and holding on note preview to scrub around.
|
||||||
targetCursorMode = Grabbing;
|
targetCursorMode = Grabbing;
|
||||||
|
|
||||||
var clickedPosInPixels:Float = FlxMath.remapToRange(FlxG.mouse.screenY, (notePreview?.y ?? 0.0),
|
var clickedPosInPixels:Float = FlxMath.remapToRange(FlxG.mouse.viewY, (notePreview?.y ?? 0.0), (notePreview?.y ?? 0.0) + (notePreview?.height ?? 0.0),
|
||||||
(notePreview?.y ?? 0.0) + (notePreview?.height ?? 0.0), 0, songLengthInPixels);
|
0, songLengthInPixels);
|
||||||
|
|
||||||
scrollPositionInPixels = clickedPosInPixels;
|
scrollPositionInPixels = clickedPosInPixels;
|
||||||
moveSongToScrollPosition();
|
moveSongToScrollPosition();
|
||||||
|
@ -4520,17 +4520,17 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
|
||||||
targetCursorMode = Grabbing;
|
targetCursorMode = Grabbing;
|
||||||
|
|
||||||
// Scroll the screen if the mouse is above or below the grid.
|
// Scroll the screen if the mouse is above or below the grid.
|
||||||
if (FlxG.mouse.screenY < MENU_BAR_HEIGHT)
|
if (FlxG.mouse.viewY < MENU_BAR_HEIGHT)
|
||||||
{
|
{
|
||||||
// Scroll up.
|
// Scroll up.
|
||||||
var diff:Float = MENU_BAR_HEIGHT - FlxG.mouse.screenY;
|
var diff:Float = MENU_BAR_HEIGHT - FlxG.mouse.viewY;
|
||||||
scrollPositionInPixels -= diff * 0.5; // Too fast!
|
scrollPositionInPixels -= diff * 0.5; // Too fast!
|
||||||
moveSongToScrollPosition();
|
moveSongToScrollPosition();
|
||||||
}
|
}
|
||||||
else if (FlxG.mouse.screenY > (playbarHeadLayout?.y ?? 0.0))
|
else if (FlxG.mouse.viewY > (playbarHeadLayout?.y ?? 0.0))
|
||||||
{
|
{
|
||||||
// Scroll down.
|
// Scroll down.
|
||||||
var diff:Float = FlxG.mouse.screenY - (playbarHeadLayout?.y ?? 0.0);
|
var diff:Float = FlxG.mouse.viewY - (playbarHeadLayout?.y ?? 0.0);
|
||||||
scrollPositionInPixels += diff * 0.5; // Too fast!
|
scrollPositionInPixels += diff * 0.5; // Too fast!
|
||||||
moveSongToScrollPosition();
|
moveSongToScrollPosition();
|
||||||
}
|
}
|
||||||
|
@ -4811,11 +4811,11 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
|
||||||
// Show the context menu connected to the note.
|
// Show the context menu connected to the note.
|
||||||
if (useSingleNoteContextMenu)
|
if (useSingleNoteContextMenu)
|
||||||
{
|
{
|
||||||
this.openNoteContextMenu(FlxG.mouse.screenX, FlxG.mouse.screenY, highlightedNote.noteData);
|
this.openNoteContextMenu(FlxG.mouse.viewX, FlxG.mouse.viewY, highlightedNote.noteData);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
this.openSelectionContextMenu(FlxG.mouse.screenX, FlxG.mouse.screenY);
|
this.openSelectionContextMenu(FlxG.mouse.viewX, FlxG.mouse.viewY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -4835,11 +4835,11 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
|
||||||
|| (isHighlightedEventSelected && currentEventSelection.length == 1);
|
|| (isHighlightedEventSelected && currentEventSelection.length == 1);
|
||||||
if (useSingleEventContextMenu)
|
if (useSingleEventContextMenu)
|
||||||
{
|
{
|
||||||
this.openEventContextMenu(FlxG.mouse.screenX, FlxG.mouse.screenY, highlightedEvent.eventData);
|
this.openEventContextMenu(FlxG.mouse.viewX, FlxG.mouse.viewY, highlightedEvent.eventData);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
this.openSelectionContextMenu(FlxG.mouse.screenX, FlxG.mouse.screenY);
|
this.openSelectionContextMenu(FlxG.mouse.viewX, FlxG.mouse.viewY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -4860,11 +4860,11 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
|
||||||
// Show the context menu connected to the note.
|
// Show the context menu connected to the note.
|
||||||
if (useSingleNoteContextMenu)
|
if (useSingleNoteContextMenu)
|
||||||
{
|
{
|
||||||
this.openHoldNoteContextMenu(FlxG.mouse.screenX, FlxG.mouse.screenY, highlightedHoldNote.noteData);
|
this.openHoldNoteContextMenu(FlxG.mouse.viewX, FlxG.mouse.viewY, highlightedHoldNote.noteData);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
this.openSelectionContextMenu(FlxG.mouse.screenX, FlxG.mouse.screenY);
|
this.openSelectionContextMenu(FlxG.mouse.viewX, FlxG.mouse.viewY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -5139,10 +5139,11 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
|
||||||
}
|
}
|
||||||
|
|
||||||
var songPos:Float = Conductor.instance.songPosition + Conductor.instance.instrumentalOffset;
|
var songPos:Float = Conductor.instance.songPosition + Conductor.instance.instrumentalOffset;
|
||||||
|
var songPosMilliseconds:String = Std.string(Math.floor(Math.abs(songPos) % 1000)).lpad('0', 2).substr(0, 2);
|
||||||
var songPosSeconds:String = Std.string(Math.floor((Math.abs(songPos) / 1000) % 60)).lpad('0', 2);
|
var songPosSeconds:String = Std.string(Math.floor((Math.abs(songPos) / 1000) % 60)).lpad('0', 2);
|
||||||
var songPosMinutes:String = Std.string(Math.floor((Math.abs(songPos) / 1000) / 60)).lpad('0', 2);
|
var songPosMinutes:String = Std.string(Math.floor((Math.abs(songPos) / 1000) / 60)).lpad('0', 2);
|
||||||
if (songPos < 0) songPosMinutes = '-' + songPosMinutes;
|
if (songPos < 0) songPosMinutes = '-' + songPosMinutes;
|
||||||
var songPosString:String = '${songPosMinutes}:${songPosSeconds}';
|
var songPosString:String = '${songPosMinutes}:${songPosSeconds}:${songPosMilliseconds}';
|
||||||
|
|
||||||
if (playbarSongPos.value != songPosString) playbarSongPos.value = songPosString;
|
if (playbarSongPos.value != songPosString) playbarSongPos.value = songPosString;
|
||||||
|
|
||||||
|
@ -5614,7 +5615,7 @@ class ChartEditorState extends UIState // UIState derives from MusicBeatState
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
trace('Ignoring keybinds for View menu items because we are in live input mode (${currentLiveInputStyle}).');
|
// trace('Ignoring keybinds for View menu items because we are in live input mode (${currentLiveInputStyle}).');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -586,13 +586,13 @@ class FreeplayState extends MusicBeatSubState
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
exitMovers.set([fp, txtCompletion, fnfHighscoreSpr, txtCompletion, clearBoxSprite],
|
exitMovers.set([fp, txtCompletion, fnfHighscoreSpr, clearBoxSprite],
|
||||||
{
|
{
|
||||||
x: FlxG.width,
|
x: FlxG.width,
|
||||||
speed: 0.3
|
speed: 0.3
|
||||||
});
|
});
|
||||||
|
|
||||||
exitMoversCharSel.set([fp, txtCompletion, fnfHighscoreSpr, txtCompletion, clearBoxSprite],
|
exitMoversCharSel.set([fp, txtCompletion, fnfHighscoreSpr, clearBoxSprite],
|
||||||
{
|
{
|
||||||
y: -270,
|
y: -270,
|
||||||
speed: 0.8,
|
speed: 0.8,
|
||||||
|
@ -1376,7 +1376,7 @@ class FreeplayState extends MusicBeatSubState
|
||||||
#if FEATURE_DEBUG_FUNCTIONS
|
#if FEATURE_DEBUG_FUNCTIONS
|
||||||
if (FlxG.keys.justPressed.P)
|
if (FlxG.keys.justPressed.P)
|
||||||
{
|
{
|
||||||
FlxG.switchState(FreeplayState.build(
|
FlxG.switchState(() -> FreeplayState.build(
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
character: currentCharacterId == "pico" ? Constants.DEFAULT_CHARACTER : "pico",
|
character: currentCharacterId == "pico" ? Constants.DEFAULT_CHARACTER : "pico",
|
||||||
|
@ -1777,12 +1777,13 @@ class FreeplayState extends MusicBeatSubState
|
||||||
FlxG.log.warn('WARN: could not find song with id (${daSong.songId})');
|
FlxG.log.warn('WARN: could not find song with id (${daSong.songId})');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var targetVariation:String = targetSong.getFirstValidVariation(currentDifficulty) ?? '';
|
var targetVariation:String = targetSong.getFirstValidVariation(currentDifficulty, currentCharacter) ?? '';
|
||||||
|
|
||||||
// TODO: This line of code makes me sad, but you can't really fix it without a breaking migration.
|
// TODO: This line of code makes me sad, but you can't really fix it without a breaking migration.
|
||||||
var suffixedDifficulty = (targetVariation != Constants.DEFAULT_VARIATION
|
var suffixedDifficulty = (targetVariation != Constants.DEFAULT_VARIATION
|
||||||
&& targetVariation != 'erect') ? '$currentDifficulty-${targetVariation}' : currentDifficulty;
|
&& targetVariation != 'erect') ? '$currentDifficulty-${targetVariation}' : currentDifficulty;
|
||||||
var songScore:Null<SaveScoreData> = Save.instance.getSongScore(daSong.songId, suffixedDifficulty);
|
var songScore:Null<SaveScoreData> = Save.instance.getSongScore(daSong.songId, suffixedDifficulty);
|
||||||
|
trace(songScore);
|
||||||
intendedScore = songScore?.score ?? 0;
|
intendedScore = songScore?.score ?? 0;
|
||||||
intendedCompletion = songScore == null ? 0.0 : ((songScore.tallies.sick + songScore.tallies.good) / songScore.tallies.totalNotes);
|
intendedCompletion = songScore == null ? 0.0 : ((songScore.tallies.sick + songScore.tallies.good) / songScore.tallies.totalNotes);
|
||||||
rememberedDifficulty = suffixedDifficulty;
|
rememberedDifficulty = suffixedDifficulty;
|
||||||
|
|
|
@ -113,7 +113,9 @@ class PlayableCharacter implements IRegistryEntry<PlayerData>
|
||||||
|
|
||||||
switch (rank)
|
switch (rank)
|
||||||
{
|
{
|
||||||
case PERFECT | PERFECT_GOLD:
|
case PERFECT_GOLD:
|
||||||
|
return _data.results.perfectGold;
|
||||||
|
case PERFECT:
|
||||||
return _data.results.perfect;
|
return _data.results.perfect;
|
||||||
case EXCELLENT:
|
case EXCELLENT:
|
||||||
return _data.results.excellent;
|
return _data.results.excellent;
|
||||||
|
|
|
@ -356,7 +356,7 @@ class MainMenuState extends MusicBeatState
|
||||||
#if FEATURE_DEBUG_FUNCTIONS
|
#if FEATURE_DEBUG_FUNCTIONS
|
||||||
// Ctrl+Alt+Shift+P = Character Unlock screen
|
// Ctrl+Alt+Shift+P = Character Unlock screen
|
||||||
// Ctrl+Alt+Shift+W = Meet requirements for Pico Unlock
|
// Ctrl+Alt+Shift+W = Meet requirements for Pico Unlock
|
||||||
// Ctrl+Alt+Shift+L = Revoke requirements for Pico Unlock
|
// Ctrl+Alt+Shift+M = Revoke requirements for Pico Unlock
|
||||||
// Ctrl+Alt+Shift+R = Score/Rank conflict test
|
// Ctrl+Alt+Shift+R = Score/Rank conflict test
|
||||||
// Ctrl+Alt+Shift+N = Mark all characters as not seen
|
// Ctrl+Alt+Shift+N = Mark all characters as not seen
|
||||||
// Ctrl+Alt+Shift+E = Dump save data
|
// Ctrl+Alt+Shift+E = Dump save data
|
||||||
|
@ -369,7 +369,7 @@ class MainMenuState extends MusicBeatState
|
||||||
if (FlxG.keys.pressed.CONTROL && FlxG.keys.pressed.ALT && FlxG.keys.pressed.SHIFT && FlxG.keys.justPressed.W)
|
if (FlxG.keys.pressed.CONTROL && FlxG.keys.pressed.ALT && FlxG.keys.pressed.SHIFT && FlxG.keys.justPressed.W)
|
||||||
{
|
{
|
||||||
FunkinSound.playOnce(Paths.sound('confirmMenu'));
|
FunkinSound.playOnce(Paths.sound('confirmMenu'));
|
||||||
// Give the user a score of 1 point on Weekend 1 story mode.
|
// Give the user a score of 1 point on Weekend 1 story mode (Easy difficulty).
|
||||||
// This makes the level count as cleared and displays the songs in Freeplay.
|
// This makes the level count as cleared and displays the songs in Freeplay.
|
||||||
funkin.save.Save.instance.setLevelScore('weekend1', 'easy',
|
funkin.save.Save.instance.setLevelScore('weekend1', 'easy',
|
||||||
{
|
{
|
||||||
|
@ -389,14 +389,16 @@ class MainMenuState extends MusicBeatState
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FlxG.keys.pressed.CONTROL && FlxG.keys.pressed.ALT && FlxG.keys.pressed.SHIFT && FlxG.keys.justPressed.L)
|
if (FlxG.keys.pressed.CONTROL && FlxG.keys.pressed.ALT && FlxG.keys.pressed.SHIFT && FlxG.keys.justPressed.M)
|
||||||
{
|
{
|
||||||
FunkinSound.playOnce(Paths.sound('confirmMenu'));
|
FunkinSound.playOnce(Paths.sound('confirmMenu'));
|
||||||
// Give the user a score of 0 points on Weekend 1 story mode.
|
// Give the user a score of 0 points on Weekend 1 story mode (all difficulties).
|
||||||
// This makes the level count as uncleared and no longer displays the songs in Freeplay.
|
// This makes the level count as uncleared and no longer displays the songs in Freeplay.
|
||||||
funkin.save.Save.instance.setLevelScore('weekend1', 'easy',
|
for (diff in ['easy', 'normal', 'hard'])
|
||||||
{
|
{
|
||||||
score: 1,
|
funkin.save.Save.instance.setLevelScore('weekend1', diff,
|
||||||
|
{
|
||||||
|
score: 0,
|
||||||
tallies:
|
tallies:
|
||||||
{
|
{
|
||||||
sick: 0,
|
sick: 0,
|
||||||
|
@ -411,6 +413,7 @@ class MainMenuState extends MusicBeatState
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (FlxG.keys.pressed.CONTROL && FlxG.keys.pressed.ALT && FlxG.keys.pressed.SHIFT && FlxG.keys.justPressed.R)
|
if (FlxG.keys.pressed.CONTROL && FlxG.keys.pressed.ALT && FlxG.keys.pressed.SHIFT && FlxG.keys.justPressed.R)
|
||||||
{
|
{
|
||||||
|
|
|
@ -273,11 +273,6 @@ class TitleState extends MusicBeatState
|
||||||
}
|
}
|
||||||
#end
|
#end
|
||||||
|
|
||||||
if (Save.instance.charactersSeen.contains("pico"))
|
|
||||||
{
|
|
||||||
Save.instance.charactersSeen.remove("pico");
|
|
||||||
Save.instance.oldChar = false;
|
|
||||||
}
|
|
||||||
Conductor.instance.update();
|
Conductor.instance.update();
|
||||||
|
|
||||||
/* if (FlxG.onMobile)
|
/* if (FlxG.onMobile)
|
||||||
|
|
|
@ -481,10 +481,6 @@ class Constants
|
||||||
public static final JUDGEMENT_BAD_COMBO_BREAK:Bool = true;
|
public static final JUDGEMENT_BAD_COMBO_BREAK:Bool = true;
|
||||||
public static final JUDGEMENT_SHIT_COMBO_BREAK:Bool = true;
|
public static final JUDGEMENT_SHIT_COMBO_BREAK:Bool = true;
|
||||||
|
|
||||||
// % Sick
|
|
||||||
public static final RANK_PERFECT_PLAT_THRESHOLD:Float = 1.0; // % Sick
|
|
||||||
public static final RANK_PERFECT_GOLD_THRESHOLD:Float = 0.85; // % Sick
|
|
||||||
|
|
||||||
// % Hit
|
// % Hit
|
||||||
public static final RANK_PERFECT_THRESHOLD:Float = 1.00;
|
public static final RANK_PERFECT_THRESHOLD:Float = 1.00;
|
||||||
public static final RANK_EXCELLENT_THRESHOLD:Float = 0.90;
|
public static final RANK_EXCELLENT_THRESHOLD:Float = 0.90;
|
||||||
|
|
Loading…
Reference in a new issue