#Player stop using binoculars detection
46 messages · Page 1 of 1 (latest)
uhh would you mind explaining what are you trying to implement?
are you trying to implement a bino bind?
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.
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
How then should I detect if a player is stopped using the bino?
Detecting certain conditions same as bino camera effects ig
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
https://github.com/EverestAPI/Resources/wiki/Making-Code-Mods#hooking-coroutines
this section briefly covers how to mess with this methods
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
IDetours are internal
ExampleMod/Examples/Hooks.cs at master · EverestAPI/ExampleMod · GitHub
https://github.com/EverestAPI/ExampleMod/blob/master/Examples/Hooks.cs
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?
oh that mod is absolutely outdated sorry
you can reference the mod template instead, or the wikis
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.
i mentioned earlier i made a foxeline modification which hooks the bino to let the tail render while the player is invisible
yeah you do have to il hook lookroutine
Alright I’ll give it another go, what do I use instead of IDetours (I also don’t know what that line is doing)
https://github.com/EverestAPI/Resources/wiki/Making-Code-Mods this is more up to date
and this https://github.com/PurredCoffee/Foxeline/blob/master/Source/FoxelineModule.cs would be a much better (working) sample :P
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
ths section here briefly covers what ilhooks are and how to use them https://github.com/EverestAPI/Resources/wiki/Making-Code-Mods#ilceleste-hooks, lower down it expands on how to use ilhooks with coroutines specifically
uhh so its not actually in the repo
i just have the change locally
also i love my LookRountine
oh i sent that as a general "how to hook" sample :P
ah
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?
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) 
i could send my sample after i get home
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
ah no problem. Would anyone know why I'm now getting this error log when from my knowledge I've made no changes
uhh restart your pc, that should fix it
yeah that fixed it. I'm not certain, but it looks like if I keep the 'while' loop, I get this Celeste error above. Even if I compile new code without the 'while' i will still get then error until i reset my pc and then it fixes.
ill test it again later