#Player stop using binoculars detection

46 messages · Page 1 of 1 (latest)

graceful compass
#

i successfully get a log text whenever the player uses the bino, but not when they stop :/

slow parcel
#

are you trying to implement a bino bind?

graceful compass
#

The end goal is having some spinners/spikes/blocks that are only visible when seen through the bino. For now I just wanted to see if I could get the bino detection to work.

fringe basin
#

so apparently i lied and StopInteracting() only gets called if the player actually dies while using the bino

#

that is the only situation in which it gets called

graceful compass
#

How then should I detect if a player is stopped using the bino?

halcyon ridge
#

Detecting certain conditions same as bino camera effects ig

heavy blade
#

it looks like all the logic is actually in LookRoutine, so you would have to potentially hook that instead, be aware that this is a Coroutine method (a State Machine method if you know what those are) and you will be forced to ilhook into it either at its actual end or just after the bino is canceled in that method

graceful compass
#

i have very little clue what I'm doing. Any help to get the code to run is much appreciated, or tell me if this is even close to how i would detect if the player is using the bino :/

#

i am also unsure whever i shoud be using an on-hook or an il-hook for my case

slow parcel
#

IDetours are internal

graceful compass
#

I don’t really know what internal is meaning, I’ve just based it off the example mod. Why does mine and the example differ?

heavy blade
#

oh that mod is absolutely outdated sorry

#

you can reference the mod template instead, or the wikis

graceful compass
#

For context I have little to no coding experience so I don’t have a good understanding for how the code works or what each but means too well

#

This example mod was referred to from the wiki.

slow parcel
graceful compass
#

Alright I’ll give it another go, what do I use instead of IDetours (I also don’t know what that line is doing)

heavy blade
#

but as a quick summary what you want to do is modify the behavior when you exit a bino, and to get some callback once that happens you need to modify the LookRountine because it happens inside it, not after it ends and not before it starts
so you cannot really use On Hooks because those work by letting you do stuff before something is called or after it is called, thus il hooks (as already mentioned) are required in this case, but theres also another problem, and it is that this method is "special" in some way and it is a Coroutine, this methods arent compiled in a traditional manner and it is not as trivial to modify them with il hooks

slow parcel
#

i just have the change locally

#

also i love my LookRountine

heavy blade
#

oh i sent that as a general "how to hook" sample :P

graceful compass
#

i think i'm very close to getting it. I've now successfully got the bino start interaction to work.

I wanted to detect for a ret to exit the bino, but that didn't work because there are multiple in the LookRoutine. I've then made a while loop for each ret but I think I'm creating an infinite loop which crashes celeste. What should I try, should I just manually add to inject for for every ret section that exits the LookRoutine?

heavy blade
#

okay, lets leave clear what a Coroutine method is (a method that returns an IEnumerable through yields)
see this example, i will reference it https://sharplab.io/#v2:CYLg1APgAgDABFAjAOgMIHsA2mCmBjAFwEt0A7AZwG4BYAKCgGYEAmOVOAbzrh4SagAscALIAKAJSduvAL7Se8vgkRMASugCuxUjglTavQ3CKkCcAIZwAvHBg0DRnkkQIA7HET3HPc2DBfvZzcLAMdFQyIAMzhRSysbREkuB29eIIAjACcccwBrUKM5FKNwtMQXKHdzAsNFIpkgA
methods of this kind are compiled in a peculiar fashion, most remarkably, their code is moved somewhere else (into a compiler generated class, in this case called <Routine>d__1), and the original method only returns a new instance of an object, that object is an IEnumerable which is a class that supports two operations, Current and MoveNext, so what are those?
IEnumerable is a class whose goal is to return values sequentially, once those values are asked for, the current value is stored in Current and the way to request for a new value is through a call to MoveNext, this last method will also return true or false depending on whether any more values can be provided
so, finally, on how does that affect our Coroutine method: the MoveNext for that method will be compiled as a big switch statement, where it will also have an internal field called the state, and it is with that that it chops down the body where there are any yields and assigns each section with a state, as you can see in the sample provided (also local variables are moved into field on the compiler generated class)
thus it is important to understand this in order to know where to inject what

#

if in you case you only want to inject right before the last yield return null (which would be the normal exit point of the method if the bino interaction succeeded in the first place) you will have to inject into the section of the last state, and right before it returns null, which would be where the first red line is
the second red line would be after it has returned null

#

note that theres another way for the Coroutine method to exit, higher up, so you maybe interested in that as well, and if you are, theres a neat trick to inject into all actual exits of the method safely (all yield breaks and any path where the control flow would exit the method):
inject right before every pair of ldc.i4.0 and ret (in that order and contiguous)

#

and as a final note after this huge dump of info, everest has a feature where mods can swap coroutines immediately, you cannot really do much about that though so its nothing to worry about now (see SwapImmediately) laugheline

slow parcel
graceful compass
#

Thank you so much for the detailed explanations. I really appreciate it! It'll sure be even more helpful after I've read over it a few more times. :p

#

i would love to see the sample Snip :D

slow parcel
#

ah fuck i forgot

#

i just realized and it's 1 am

graceful compass
#

ah no problem. Would anyone know why I'm now getting this error log when from my knowledge I've made no changes

heavy blade
#

uhh restart your pc, that should fix it

graceful compass
#

ill test it again later

slow parcel
#

@graceful compass okay i'm finally able to send the hook

#

everything before and including Unload() is in FoxelineModule, the rest is in FoxelineHooks