Modding:Events: Difference between revisions

1,568 bytes added ,  22:38, 10 February 2023
m
Reverted edits by Glass zebra (talk) to last revision by Egocarib
(Add explanation for AllowStaticRegistration method)
m (Reverted edits by Glass zebra (talk) to last revision by Egocarib)
Tag: Rollback
 
(6 intermediate revisions by 3 users not shown)
Line 1: Line 1:
[[Category:Modding]]{{Modding Info}}
{{Modding Info}}{{Modding Topic Prerequisites | Modding:C Sharp Scripting}}[[Category:Script Modding]]


Events are the basic building block that most of [[{{gamename}}]]'s mechanics are built upon.<br/>
Events are the basic building block that most of [[{{gamename}}]]'s mechanics are built upon.<br/>
Line 7: Line 7:
=Standard Events=
=Standard Events=
Events are typically listened for in generic Parts or Effects, which is what implements more advanced functionality of an object.<br/>
Events are typically listened for in generic Parts or Effects, which is what implements more advanced functionality of an object.<br/>
[[Mutations]] ([[Modding:Creating_New_Mutations|Creation]]) and [[Skills_and_Powers|Skills]] are both Parts. Effects such as sleep, prone or poison are handled separately from Parts as they are usually temporary.
[[Mutations]] ([[Modding:Creating_New_Mutations|Creation]]) and [[Skills]] are both Parts. Effects such as sleep, prone or poison are handled separately from Parts as they are usually temporary.
<!-- Listen? Register? Subscribe? Ah whatever. -Arm -->
<!-- Listen? Register? Subscribe? Ah whatever. -Arm -->
===Listening===
===Listening===
Line 100: Line 100:
</syntaxhighlight>
</syntaxhighlight>
===Firing===
===Firing===
<!-- TODO: Expand this section to include the common static MinEvent.Send() method, GiveDramsEvent doesn't have it so either a second method or switch events for the section -->
To fire a min event you call the '''HandleEvent''' method on the relevant GameObject and pass it a specific MinEvent.<br/>
To fire a min event you call the '''HandleEvent''' method on the relevant GameObject and pass it a specific MinEvent.<br/>
Setting parameters on a MinEvent is a lot more intuitive compared to the old system as they are now properties of their own type.
Setting parameters on a MinEvent is a lot more intuitive compared to the old system as they are now properties of their own type.
Line 124: Line 125:
</syntaxhighlight>
</syntaxhighlight>
===Handling===
===Handling===
The handling of min events is the most drastic change from the old system, as you can overload the base '''HandleEvent''' method instead of overriding it.<br/>
The handling of min events is the most drastic change from the old system, as you can now override one separate method for each type of MinEvent which is much simpler to organize.<br/>
Your overloaded method is then retrieved through [https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/reflection reflection] based on the parameter type and cached in a dictionary.<br/>
What all that jargon means is that you can write separate methods for each event type which is much simpler to organize.
<syntaxhighlight lang="c#">
<syntaxhighlight lang="c#">
// A volume/container of liquid, like a puddle or flagon.
// A volume/container of liquid, like a puddle or flagon.
Line 132: Line 131:


// This method handles the GiveDramsEvent.
// This method handles the GiveDramsEvent.
public bool HandleEvent(GiveDramsEvent E) {
public override bool HandleEvent(GiveDramsEvent E) {
liquid.GiveDrams(E.Liquid, ref E.Drams, E.Auto);
liquid.GiveDrams(E.Liquid, ref E.Drams, E.Auto);


Line 144: Line 143:


// This method handles the FrozeEvent.
// This method handles the FrozeEvent.
public bool HandleEvent(FrozeEvent E) {
public override bool HandleEvent(FrozeEvent E) {
E.Object.DisplayName = "&CFrozen Object";
E.Object.DisplayName = "&CFrozen Object";
return true;
return true;
}
}


// It's still possible to override HandleEvent and compare the ID or type like old events.
// It's still possible to override the base HandleEvent and compare the ID or type like old events.
// This is more useful for when you're cascading events carte blanche to sub-objects, see the Cascading section below.
// This is more useful for when you're cascading events carte blanche to sub-objects, see the Cascading section below.
public override bool HandleEvent(MinEvent E) {
public override bool HandleEvent(MinEvent E) {
if (!base.HandleEvent(E)) {
return false;
}
if (E.ID == GiveDramsEvent.ID) {
if (E.ID == GiveDramsEvent.ID) {
return HandleEvent(E as GiveDramsEvent);
return HandleEvent(E as GiveDramsEvent);
Line 158: Line 161:
}
}


return true;
}
</syntaxhighlight>
===Custom===
Prior to patch 200.43 it was possible to simply overload the handling methods, where it was then retrieved & invoked through [https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/concepts/reflection reflection] based on the parameter type and cached in a dictionary.<br/>
If you are creating your own custom MinEvent, there's nothing for you to override so you will still have to do this. To mark your custom MinEvent for invocation, override the '''WantInvokeDispatch''' method to return true.
<syntaxhighlight lang="c#>
public class MyCustomMinEvent : MinEvent
{
public new static readonly int ID = MinEvent.AllocateID();
public MyCustomMinEvent() {
base.ID = MyCustomMinEvent.ID;
}
// This is necessary for custom events that need the HandleEvent to be reflected.
public override bool WantInvokeDispatch() {
return true;
}
// A static helper method to fire our event on a GameObject.
// If it's a high-frequency event this should implement event pooling, rather than create a new MyCustomMinEvent each time.
public static void Send(GameObject Object) {
if (Object.WantEvent(MyCustomMinEvent.ID, MinEvent.CascadeLevel)) {
Object.HandleEvent(new MyCustomMinEvent());
}
// If you want to use an old event as a fallback, this is a good place to do so.
if (obj.HasRegisteredEvent("MyCustomEvent")) {
obj.FireEvent(Event.New("MyCustomEvent"));
}
}
}
// The reflected overload method that will handle our event in a part or effect.
public bool HandleEvent(MyCustomMinEvent E) {
return true;
return true;
}
}