Skip to content

Commit 9ed5b8f

Browse files
committed
Merge branch 'Archipelago' of https://github.com/Z11Coding/Mixtape-Engine-Rework into Archipelago
2 parents 1fe92e2 + 0e5fa6c commit 9ed5b8f

File tree

9 files changed

+146
-13
lines changed

9 files changed

+146
-13
lines changed

source/backend/MusicBeatState.hx

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package backend;
22

3+
import haxe.ds.HashMap;
34
import backend.window.CppAPI;
45
import flixel.FlxState;
56
import backend.PsychCamera;
@@ -310,6 +311,63 @@ class MusicBeatState extends FlxState
310311

311312
}
312313
}
314+
var preloadFunctions:Map<String, (FlxState)->Void> = [
315+
"PlayState" => function(state:FlxState) {
316+
if (state is PlayState) {
317+
@:privateAccess
318+
(cast state:PlayState).generateSong();
319+
}
320+
}
321+
];
322+
323+
public function hashCode():Int
324+
{
325+
return Type.getClassName(Type.getClass(this)).hashcode();
326+
}
327+
328+
public function preloadState(switchState:Bool = false, state:FlxState, ?proceedOnError:Bool = true)
329+
{
330+
var stateClassName = Type.getClassName(Type.getClass(state)).split(".")[Lambda.count(Type.getClassName(Type.getClass(state)).split(".")) - 1];
331+
var preloadFunction = preloadFunctions.get(stateClassName);
332+
var errored = false;
333+
if (preloadFunction == null)
334+
{
335+
trace('No preload function for state: ' + stateClassName);
336+
}
337+
var preloader = function()
338+
{
339+
if (preloadFunction != null)
340+
{
341+
trace('Preloading state: ' + stateClassName);
342+
try {
343+
preloadFunction(state);
344+
} catch (e:Dynamic) {
345+
trace('Error during state preloading: ' + e);
346+
}
347+
preloadFunction = null;
348+
}
349+
if (switchState && (!errored || proceedOnError))
350+
return MusicBeatState.switchState(this);
351+
};
352+
353+
var stateName = Type.getClassName(Type.getClass(state));
354+
355+
yutautil.Threader.runInThread(preloader(), 1, 'State Preloader');
356+
}
357+
358+
359+
public static function preloadAndSwitchState(state:MusicBeatState)
360+
{
361+
if (state == null)
362+
state = cast(FlxG.state, MusicBeatState);
363+
if (state == FlxG.state)
364+
{
365+
resetState();
366+
return;
367+
}
368+
369+
state.preloadState(true, state);
370+
}
313371

314372
public static function switchState(nextState:FlxState = null)
315373
{

source/objects/Note.hx

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ class Note extends NoteObject
8484
mustPress: this.mustPress,
8585
canBeHit: this.canBeHit,
8686
tooLate: this.tooLate,
87+
botNote: this.botNote,
8788
wasGoodHit: this.wasGoodHit,
8889
missed: this.missed,
8990
ignoreNote: this.ignoreNote,
@@ -457,6 +458,8 @@ class Note extends NoteObject
457458
],
458459
];
459460

461+
public var botNote:Bool = false;
462+
460463
public static var pixelScales:Array<Float> = [
461464
1.2, //1k
462465
1.15, //2k
@@ -488,7 +491,8 @@ class Note extends NoteObject
488491
'Hey!',
489492
'Hurt Note',
490493
'GF Sing',
491-
'No Animation'
494+
'No Animation',
495+
'Botplay Note'
492496
];
493497
public var strumTime:Float = 0;
494498

@@ -762,6 +766,9 @@ class Note extends NoteObject
762766
noMissAnimation = true;
763767
case 'GF Sing':
764768
gfNote = true;
769+
case 'Botplay Note':
770+
botNote = true;
771+
hitsoundChartEditor = false;
765772
}
766773
if (value != null && value.length > 1) NoteTypesConfig.applyNoteTypeData(this, value);
767774
if (hitsound != 'hitsound' && hitsoundVolume > 0) Paths.sound(hitsound); //precache new sound for being idiot-proof

source/objects/playfields/PlayField.hx

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -938,7 +938,7 @@ class PlayField extends FlxTypedGroup<FlxBasic>
938938
if(daNote.holdingTime < daNote.sustainLength && inControl && !daNote.blockHit){
939939
if(!daNote.tooLate && daNote.wasGoodHit){
940940
trace("hitting tail hold");
941-
var isHeld:Bool = autoPlayed || keysPressed[daNote.column];
941+
var isHeld:Bool = autoPlayed || keysPressed[daNote.column] || daNote.botNote;
942942
var wasHeld:Bool = daNote.isHeld;
943943
daNote.isHeld = isHeld;
944944
isHolding[daNote.column] = true;
@@ -1068,6 +1068,19 @@ class PlayField extends FlxTypedGroup<FlxBasic>
10681068
}
10691069
}
10701070
}else{
1071+
1072+
// Check for Bot Notes.
1073+
for(i in 0...keyCount){
1074+
for (daNote in getNotes(i, (note:Note) -> !note.tooLate && !note.wasGoodHit && !note.ignoreNote && !note.hitCausesMiss && note.botNote)){
1075+
var hitDiff = Conductor.songPosition - daNote.strumTime;
1076+
if (!daNote.isSustainNote && hitDiff >= 0 || daNote.isSustainNote && hitDiff + 80 >= 0){
1077+
noteHitCallback(daNote, this);
1078+
}
1079+
}
1080+
}
1081+
1082+
1083+
10711084
for(data in 0...keyCount){
10721085
if (keysPressed[data]){
10731086
var noteList = getNotesWithEnd(data, Conductor.songPosition, (note:Note) -> (note.isSustainNote || note.istail) && (note.prevNote != null || note.unhitTail.length > -1));

source/states/PlayState.hx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,10 @@ class PlayState extends MusicBeatState
137137

138138
public var comboOffsetCustom:Null<Array<Int>> = null;
139139

140+
// override function preloadFunction():Void {
141+
// generateSong();
142+
// }
143+
140144
public var BF_X:Float = 770;
141145
public var BF_Y:Float = 100;
142146
public var BF2_X:Float = 770;
@@ -456,6 +460,12 @@ class PlayState extends MusicBeatState
456460

457461
override public function create()
458462
{
463+
464+
// if (SONG != null)
465+
// {
466+
// preloadFunction = generateSong;
467+
// }
468+
459469
if (SONG == null) {
460470
var songLowercase:String = Paths.formatToSongPath('tutorial');
461471
var poop:String = Highscore.formatSong(songLowercase, storyDifficulty);
@@ -2288,6 +2298,7 @@ class PlayState extends MusicBeatState
22882298

22892299
private function generateSong():Void
22902300
{
2301+
trace('Generating Song: ${SONG.song}');
22912302
// FlxG.log.add(ChartParser.parse());
22922303
songSpeed = PlayState.SONG.speed;
22932304
songSpeedType = ClientPrefs.getGameplaySetting('scrolltype');

source/states/editors/ChartingStateOG.hx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,10 @@ class ChartingStateOG extends backend.MusicBeatChartingState
6464
}
6565
}
6666

67-
public static var noteTypeList:Array<String> = // Used for backwards compatibility with 0.1 - 0.3.2 charts, though, you should add your hardcoded custom note types here too.
68-
[
67+
public static var noteTypeList:Array<String> = getNoteTypeList();
68+
69+
private static function getNoteTypeList():Array<String> {
70+
var notes = [
6971
'',
7072
'Alt Animation',
7173
'Hey!',
@@ -78,6 +80,8 @@ class ChartingStateOG extends backend.MusicBeatChartingState
7880
'Both Note',
7981
'Both Alt Note'
8082
];
83+
return notes.concat(Note.defaultNoteTypes.filter(type -> !notes.contains(type)));
84+
}
8185

8286
private var didAThing = false;
8387

source/states/freeplay/FreeplayState.hx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1015,7 +1015,7 @@ class FreeplayState extends MusicBeatState
10151015
alreadyClicked = true;
10161016
MusicBeatState.reopen = false; //Fix a sticker bug
10171017
LoadingState.prepareToSong();
1018-
LoadingState.loadAndSwitchState(APEntryState.inArchipelagoMode ? new archipelago.APPlayState() : new states.PlayState());
1018+
MusicBeatState.preloadAndSwitchState(APEntryState.inArchipelagoMode ? new archipelago.APPlayState() : new states.PlayState());
10191019
}
10201020
#if !SHOW_LOADING_SCREEN FlxG.sound.music.stop(); #end
10211021
stopMusicPlay = true;

source/yutautil/CollectionUtils.hx

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,35 @@ class CollectionUtils
520520
return Type.createInstance(CLASS, args != null ? args : []);
521521
}
522522

523+
public static inline function hashcode(input:Dynamic):Int
524+
{
525+
if (Std.is(input, String))
526+
{
527+
var hash = 0;
528+
for (i in 0...input.length) {
529+
var char = input.charCodeAt(i);
530+
hash = (hash * 31 + char) & 0xffffffff;
531+
}
532+
return hash;
533+
}
534+
else if (Std.is(input, Int) || Std.is(input, Float))
535+
{
536+
return Std.int(input);
537+
}
538+
else if (Std.is(input, Array))
539+
{
540+
return input.hashCode();
541+
}
542+
else if (Std.is(input, IMap))
543+
{
544+
return input.hashCode();
545+
}
546+
else
547+
{
548+
return 0;
549+
}
550+
}
551+
523552
public static inline function callOn<T>(item:T, func:T->Dynamic):Dynamic
524553
{
525554
return func(item);

source/yutautil/YScript.hx

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -479,10 +479,7 @@ class YScript
479479
{
480480
private var keywords:Map<String, EReg> = [
481481
// ———————— Type & Block Definitions ————————
482-
"class" => ~/\bclass\s+\w+
483-
(?:\s+extends\s+[\w\.]+)?
484-
(?:\s+implements\s+[\w\.]+(?:\s*,\s*[\w\.]+)*)?
485-
\s*\{(?:[^{}]|\{[^{}]*\})*\}/s,
482+
"class" => ~/\bclass\s+\w+(?:\s+extends\s+[\w\.]+)?(?:\s+implements\s+[\w\.]+(?:\s*,\s*[\w\.]+)*)?\s*\{(?:[^{}]|\{[^{}]*\})*\}/s,
486483
// Matches a class definition, optionally with 'extends' and/or 'implements' clauses, and its body.
487484

488485
"enum" => ~/\benum\s+\w+\s*\{(?:[^{}]|\{[^{}]*\})*\}/s,
@@ -500,8 +497,7 @@ class YScript
500497
"var" => ~/\bvar\s+\w+\s*:\s*[\w\.<>\[\]]+\s*=\s*[\s\S]*?;/s,
501498
// Matches a variable definition with a type and an initializer.
502499

503-
"function" => ~/\bfunction\s+\w+\s*\([^)]*\)\s*:\s*[\w\.<>\[\]]+
504-
\s*(?:haxe|lua)?\s*\{(?:[^{}]|\{[^{}]*\})*\}/s,
500+
"function" => ~/\bfunction\s+\w+\s*\([^)]*\)\s*:\s*[\w\.<>\[\]]+\s*(?:haxe|lua)?\s*\{(?:[^{}]|\{[^{}]*\})*\}/s,
505501
// Matches a function definition with parameters, return type, and body.
506502

507503
"if" => ~/\bif\s*\([\s\S]*?\)\s*\{(?:[^{}]|\{[^{}]*\})*\}/s,

source/yutautil/YScriptParser.hx

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
// YScriptParser.hx
21
package yutautil;
32

43
import haxe.Json;
@@ -168,7 +167,7 @@ class YScriptParser {
168167

169168
private function readWord():String {
170169
var start = pos;
171-
while (pos < input.length && (isAlpha(input.charAt(pos)) || isDigit(input.charAt(pos))) {
170+
while (pos < input.length && (isAlpha(input.charAt(pos)) || isDigit(input.charAt(pos)))) {
172171
pos++;
173172
}
174173
return input.substr(start, pos - start);
@@ -225,6 +224,17 @@ class YScriptParser {
225224
].contains(word);
226225
}
227226

227+
private function parseExpression(t:Token):Dynamic {
228+
// Placeholder implementation for parsing an expression
229+
switch t {
230+
case TNumberLiteral(n): return n;
231+
case TStringLiteral(s): return s;
232+
case TIdentifier(name): return { type: "identifier", name: name };
233+
case TOperator(op): return { type: "operator", operator: op };
234+
default: throw 'Unsupported token in expression: $t';
235+
}
236+
}
237+
228238
private function parseVariable(tokens:Array<Token>):YVar {
229239
var isConst = match(TKeyword("const"), tokens);
230240
expect(isConst ? TKeyword("const") : TKeyword("var"), tokens);
@@ -439,6 +449,10 @@ class YScriptParser {
439449
return null;
440450
}
441451

452+
private function getCurrentToken():Token {
453+
return currentToken;
454+
}
455+
442456
private function parseClass(tokens:Array<Token>):YClass<Dynamic> {
443457
expect(TKeyword("class"), tokens);
444458
var className = expectIdentifier(tokens);
@@ -504,6 +518,7 @@ class YScriptParser {
504518
var output = [];
505519

506520
for (cls in program.classes) {
521+
var cls:Dynamic = cls;
507522
output.push('// YScript class: ${cls.name}');
508523
if (cls.extending.length > 0) {
509524
var ext = cls.extending.map(e -> e.name).join(", ");

0 commit comments

Comments
 (0)