Open mriswithe opened 1 year ago
Ostw has almost zero restrictions when casting. This means that you can cast anything to anything, even if they are completely incompatible causing an exception when compiling. There isn't much of a reason for this anymore so I'll need to tighten up the casting restrictions, especially for structs. Casting is done very rarely, which is probably why I haven't run into this issue.
Additionally, instead of using the workshop functions (IsTrueForAll(array, condition)
, IsTrueForAny(array, condition)
, CountOf(array)
, etc.) instead use the methods inside an array type by doing: array.IsTrueForAll(v => condition)
, array.IsTrueForAny(v => condition)
, array.Length
, etc. I will elaborate on why this is later.
Lets fix the code.
First, lets look at triggerHeld
:
Boolean triggerHeld(Any t): IsTrueForAll((<Trigger>t).toHold, IsButtonHeld(Button: ArrayElement())) ;
// to
Boolean triggerHeld(Trigger t): t.toHold.IsTrueForAll(b => IsButtonHeld(EventPlayer(), b));
The t
parameter is given the type Trigger
instead of Any
, removing the need for casting. Now the compiler won't crash, yay!
Second, anyTriggersHeld
. The workshop has a limitation where you can't use an array filter/sort/map inside a filter/sort/map like this: x.FilteredArray(value => value.Inner.FilteredArray(...))
. Luckily in this case there are only a few values at most so we can explicitly check each index manually. This won't cause too much of a performance hit because the workshop will short-circuit once a button is detected, so we are pretty much implementing IsTrueForAny
manually. I did this by adding these definitions to the Trigger
struct:
struct Trigger
{
public Button[] toHold;
public ()=>void toUse;
public Player player;
// If you expect the number of values in toHold to exceed 3, add another ', b(x)' right after the '2'.
public Boolean isTriggerHeld(): b(0, b(1, b(2)));
Boolean b(Number i, Boolean next = true): (i >= toHold.Length || (IsButtonHeld(EventPlayer(), toHold[i]) && next));
}
// ...
// then the new anyTriggersHeld looks like this:
Boolean anyTriggersHeld(Trigger[] triggers): triggers.IsTrueForAny(t => t.isTriggerHeld());
These changes are enough to make the project compile. Something to note is this line:
p._watch_triggers.ModAppend(t);
There is a bit of a trap here, because of the way that workshop handles appending values, you will want to change this to:
p._watch_triggers.ModAppend([t]);
// or this, which does the same thing. I think it looks nicer
p._watch_triggers += [t];
This is only required if a struct has an array type or lambda type inside it, and yours has both. OSTW will need to automatically wrap it without user intervention, so that's on me.
With all of this done, it now works correctly. Pressing crouch + interact will display "You did it! You pressed buttons!". Here is the fixed code:
As for why you should use x.FilteredArray(...)
instead of FilteredArray(x, ...)
, the latter is automatically generated from the workshop metadata and can't handle special cases required with structs. It still exists because the decompiler can't detect how workshop variables are used when decompiling workshop code, so it uses the legacy functions. Hopefully one day :)
Using ostw for so long made me subconsciously avoid a couple pitfalls that new users will run into. This has given me a few things I'll need to do.
This is awesome feedback, I will see what I can do about trying to help with the doc side, I did a lot of going back and forth, documenting an entire language is not a one person task. I will verify this tonight once I get a chance, and see what I can try and spruce up in the wiki.
As for my goal, mildly flexible triggers like this, does this seem like a mildly performant path ? I don't know the "best" way to poll inputs as far as Overwatch is concerned. This just seemed like a simple starter task to start rolling up into more easy mode functions for my goals, make better/easier training/practice levels hehe.
I am trying to write a library for triggers (Causing a callback to get triggered if the player hits a/some button(s)). I think I am doing something wrong like unscrewing something with a carrot.
The error I get from the compiler (running in VSCode with OSTW (v3.5.1) is
The code that produces the error:
If I comment out the call to
if(anyTriggersHeld(_watch_triggers))
, the error goes away, so it seems my problem is theanyTriggersHeld
macro calling thetriggerHeld
macro?Also, if my programming pattern is sad and wrong, please let me know. What I would like is to be able to create a rule when I create a class, but that doesn't seem to be a thing?
Thanks! Mriswithe