Skip to content

Commit 9ae6bfa

Browse files
committed
Stuff in Progress.
1 parent a44b920 commit 9ae6bfa

File tree

10 files changed

+4937
-22
lines changed

10 files changed

+4937
-22
lines changed

source/archipelago/APYaml.hx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,7 @@ class APYaml {
7676
return settings.mods_enabled;
7777
}
7878

79+
7980
// Add more methods to access other settings as needed.
8081
}
8182

source/import.hx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,4 +99,6 @@ using yutautil.CollectionUtils;
9999
using yutautil.MetaData;
100100
using yutautil.PointerTools;
101101
using yutautil.CUMacroTools; // Careful. Using C++ Lables in Haxe may act strangely.
102+
using yutautil.KonamiTracker;
103+
using yutautil.GenericObject;
102104
#end

source/yutautil/CUMacroTools.hx

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -575,4 +575,73 @@ class CUMacroTools
575575
return macro untyped __cpp__($v{"std::cout << "}, msgExpr, $v{" << std::endl;"});
576576
}
577577
}
578+
579+
// Easy way to check multiple keys with FlxKey.
580+
581+
/**
582+
* Generates a function that checks if any of the specified keys match the given FlxKey status.
583+
* Example usage:
584+
* CUMacroTools.generateKeyCheckFunction(["A", "B"], "justPressed")
585+
* // Generates: function():Bool { if (FlxG.keys.justPressed.A || FlxG.keys.justPressed.B) return true; return false; }
586+
*/
587+
public static macro function generateKeyCheckFunction(keys:Array<String>, status:String):Expr {
588+
// Validate input
589+
if (keys == null || keys.length == 0) {
590+
Context.error("CUMacroTools.generateKeyCheckFunction: Keys cannot be null or empty.", Context.currentPos());
591+
}
592+
if (status == null || StringTools.trim(status) == "") {
593+
Context.error("CUMacroTools.generateKeyCheckFunction: Status cannot be null or empty.", Context.currentPos());
594+
}
595+
596+
// List of valid statuses (add more if needed)
597+
var validStatuses = [
598+
"justPressed", "pressed", "anyJustPressed", "released", "justReleased",
599+
"anyJustReleased", "anyPressed"
600+
];
601+
if (validStatuses.indexOf(status) == -1) {
602+
Context.warning('CUMacroTools.generateKeyCheckFunction: Status "' + status + '" is not a standard FlxKey status. Proceeding anyway.', Context.currentPos());
603+
}
604+
605+
// Build the check expression: FlxG.keys.<status>[FlxKey.toString(KEY)]
606+
var checks = [];
607+
for (key in keys) {
608+
// Convert key to FlxKey if not already a string
609+
checks.push(macro Reflect.field(Reflect.field(FlxG.keys, $v{status}), FlxKey.toString($v{key})));
610+
}
611+
// Combine all checks with ||
612+
var expr:Expr = checks.shift();
613+
for (c in checks) expr = macro $expr || $c;
614+
615+
// Return a function that checks and returns true if any key matches
616+
return macro function():Bool {
617+
if ($expr) return true;
618+
return false;
619+
}
620+
}
621+
622+
/**
623+
* Helper macros for common FlxKey checks.
624+
* Usage: CUMacroTools.checkKeysJustPressed(["A", "B"])
625+
*/
626+
public static macro function checkKeysJustPressed(keys:Array<Dynamic>):Expr {
627+
return macro CUMacroTools.generateKeyCheckFunction($a{[for (k in keys) macro $v{k}]}, "justPressed")();
628+
}
629+
public static macro function checkKeysPressed(keys:Array<Dynamic>):Expr {
630+
return macro CUMacroTools.generateKeyCheckFunction($a{[for (k in keys) macro $v{k}]}, "pressed")();
631+
}
632+
public static macro function checkKeysAnyJustPressed(keys:Array<Dynamic>):Expr {
633+
return macro CUMacroTools.generateKeyCheckFunction($a{[for (k in keys) macro $v{k}]}, "anyJustPressed")();
634+
}
635+
public static macro function checkKeysReleased(keys:Array<Dynamic>):Expr {
636+
return macro CUMacroTools.generateKeyCheckFunction($a{[for (k in keys) macro $v{k}]}, "released")();
637+
}
638+
public static macro function checkKeysJustReleased(keys:Array<Dynamic>):Expr {
639+
return macro CUMacroTools.generateKeyCheckFunction($a{[for (k in keys) macro $v{k}]}, "justReleased")();
640+
}
641+
public static macro function checkKeysAnyJustReleased(keys:Array<Dynamic>):Expr {
642+
return macro CUMacroTools.generateKeyCheckFunction($a{[for (k in keys) macro $v{k}]}, "anyJustReleased")();
643+
}
644+
public static macro function checkKeysAnyPressed(keys:Array<Dynamic>):Expr {
645+
return macro CUMacroTools.generateKeyCheckFunction($a{[for (k in keys) macro $v{k}]}, "anyPressed")();
646+
}
578647
}

source/yutautil/CollectionUtils.hx

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1557,6 +1557,57 @@ class CollectionUtils
15571557
return null;
15581558
}
15591559

1560+
public static inline function fields<T>(input:Dynamic):Array<Dynamic>
1561+
{
1562+
if (Std.is(input, Array))
1563+
{
1564+
var arr:Array<Dynamic> = cast input;
1565+
var result = [];
1566+
for (i in 0...arr.length)
1567+
result.push(i);
1568+
return result;
1569+
}
1570+
else if (Std.is(input, IMap))
1571+
{
1572+
var keys = [];
1573+
for (key in (input : IMap<Dynamic, Dynamic>).keys())
1574+
keys.push(key);
1575+
return keys;
1576+
}
1577+
else if (Reflect.hasField(input, "iterator") || (Reflect.hasField(input, "hasNext") && Reflect.hasField(input, "next")))
1578+
{
1579+
// For iterables, try to enumerate indices
1580+
var result = [];
1581+
var idx = 0;
1582+
for (_ in (input : Iterable<Dynamic>))
1583+
{
1584+
result.push(idx);
1585+
idx++;
1586+
}
1587+
return result;
1588+
}
1589+
else
1590+
{
1591+
var fields = Reflect.fields(input);
1592+
if (fields.length > 0)
1593+
return fields;
1594+
var cl = Type.getClass(input);
1595+
if (cl != null)
1596+
return Type.getInstanceFields(cl);
1597+
return [];
1598+
}
1599+
}
1600+
1601+
public static inline function pressedKeys():Array<flixel.input.keyboard.FlxKey>
1602+
{
1603+
var keys = [];
1604+
for (key in FlxG.keys.pressed.fields())
1605+
{
1606+
keys.push(key);
1607+
}
1608+
return keys;
1609+
}
1610+
15601611
public static inline function callOnGeneric<T>(CLASS:Class<T>, func:T->Dynamic):Dynamic
15611612
{
15621613
return func(Type.createEmptyInstance(CLASS));

source/yutautil/GenericObject.hx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ class TypedField<T> {
3838
}
3939
}
4040

41-
abstract DefinedField<T>(TypedField<T>) from TypedField<T> to T {
41+
abstract DefinedField<T>(TypedField<T>) from TypedField<T> to Dynamic {
4242
public function new(value:T) {
4343
this = new TypedField<T>(value);
4444
}
@@ -175,7 +175,7 @@ class GenericObject {
175175
}
176176

177177
public function keys():Iterator<String> {
178-
return fields.keys();
178+
return fields.keys().iterator();
179179
}
180180

181181
public function values():Iterator<Dynamic> {
@@ -274,8 +274,8 @@ class GenericObject {
274274
}
275275

276276
enum HxObjType {
277-
Safe,
278-
Unsafe
277+
Safe;
278+
Unsafe;
279279
}
280280

281281
abstract HxObject(GenericObject) from GenericObject to Dynamic {

source/yutautil/KonamiTracker.hx

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import flixel.FlxG;
44
import flixel.input.keyboard.FlxKey;
55
import flixel.FlxBasic;
66

7-
typedef CheatCallback = Void->Void;
7+
typedef CheatCallback = Cheat->Void;
88

99
typedef Cheat = {
1010
var code:Array<FlxKey>;
@@ -23,11 +23,13 @@ class KonamiTracker extends FlxBasic {
2323
var inputBuffer:Array<FlxKey> = [];
2424
var maxLength:Int = 0;
2525

26-
public function new(?cheatTable:KeyIndexedArray<Array<FlxKey>, CheatCallback>) {
26+
public function new(?cheatTable:KeyIndexedArray<Array<FlxKey>, CheatCallback>, ?KonamiCallback:CheatCallback) {
2727
super();
2828
cheats = [];
29-
addCheat(KONAMI_CODE_1, function() {});
30-
addCheat(KONAMI_CODE_2, function() {});
29+
if (KonamiCallback != null) {
30+
addCheat(KONAMI_CODE_1, KonamiCallback);
31+
addCheat(KONAMI_CODE_2, KonamiCallback);
32+
}
3133
if (cheatTable != null) {
3234
for (entry in cheatTable) {
3335
addCheat(entry.key, entry.value);
@@ -42,7 +44,7 @@ class KonamiTracker extends FlxBasic {
4244

4345
override public function update(elapsed:Float):Void {
4446
super.update(elapsed);
45-
var pressed:FlxKey = getPressedKey();
47+
var pressed:Null<FlxKey> = getPressedKey();
4648
if (pressed != null) {
4749
inputBuffer.push(pressed);
4850
if (inputBuffer.length > maxLength)
@@ -55,7 +57,7 @@ class KonamiTracker extends FlxBasic {
5557
var matched = false;
5658
for (cheat in cheats) {
5759
if (matches(cheat.code)) {
58-
cheat.callback();
60+
cheat.callback(cheat);
5961
inputBuffer = [];
6062
matched = true;
6163
break;
@@ -91,17 +93,21 @@ class KonamiTracker extends FlxBasic {
9193
return true;
9294
}
9395

94-
public var allowAllKeys:Bool = false;
96+
public var allowAllKeys:Bool = true;
9597

9698
function getPressedKey():Null<FlxKey> {
97-
if (allowAllKeys) {
98-
// Check all keys if allowed
99-
for (key in FlxKey.createAll()) {
100-
if (FlxG.keys.justPressed.check(key)) return key;
101-
}
102-
} else {
103-
for (key in [FlxKey.UP, FlxKey.DOWN, FlxKey.LEFT, FlxKey.RIGHT, FlxKey.A, FlxKey.B, FlxKey.C, FlxKey.X, FlxKey.Y, FlxKey.Z, FlxKey.ENTER, FlxKey.SPACE]) {
104-
if (FlxG.keys.justPressed.check(key)) return key;
99+
var keys = allowAllKeys
100+
? [for (key in FlxKey.toStringMap.keys()) key]
101+
: [
102+
FlxKey.UP, FlxKey.DOWN, FlxKey.LEFT, FlxKey.RIGHT,
103+
FlxKey.A, FlxKey.B, FlxKey.C, FlxKey.X, FlxKey.Y,
104+
FlxKey.Z, FlxKey.ENTER, FlxKey.SPACE
105+
];
106+
for (key in keys) {
107+
// Use Reflect to access the justPressed property dynamically
108+
var justPressed = Reflect.field(FlxG.keys, "justPressed");
109+
if (justPressed != null && Reflect.callMethod(FlxG.keys, justPressed, [key])) {
110+
return key;
105111
}
106112
}
107113
return null;

source/yutautil/Valid.hx

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
package yutautil;
2+
3+
// Abstract for a "Valid" type that can be used as a boolean or as a conditional tree
4+
5+
abstract Valid(Bool) from Bool to Bool to Dynamic {
6+
public var expr:() -> Bool;
7+
8+
// Construct from a function (expression)
9+
public inline function new(expr:() -> Bool) {
10+
this.expr = expr;
11+
}
12+
13+
// Construct from a Bool value
14+
@:from
15+
public static inline function fromBool(b:Bool):Valid {
16+
return new Valid(() -> b);
17+
}
18+
19+
// Allow using as Bool (always evaluates the expression)
20+
@:to
21+
public inline function toBool():Bool {
22+
return expr();
23+
}
24+
25+
// Allow chaining if-else logic (if tree)
26+
@:to
27+
public function ifElse<T>(ifTrue:Dynamic, ifFalse:Dynamic):T {
28+
return expr() ? ifTrue : ifFalse;
29+
}
30+
31+
// Static helper for building from an expression
32+
public static inline function fromExpr(expr:() -> Bool):Valid {
33+
return new Valid(expr);
34+
}
35+
}

0 commit comments

Comments
 (0)