var old_health = 0;Then we need a function that takes our vitals from GMCP, looks at the new health number, compares it to our old health, and displays the difference. This function will see if the health changed, and if it did it will print out the amount of change in red.
var health_change = function (char_vitals) { var new_health = char_vitals.hp;Now we need some way to call this function every time we get a GMCP message with our health in it. Normally in Nexus, this would mean making an onGMCP function and running "if (args.gmcp_method === "Char.Vitals") health_change(args.gmcp_args)". And for every function we want to run on Char.Vitals, we need to pile it all under one "if (args.gmcp_method === "Char.Vitals")" or we have to do a separate test on every GMCP message for every script.
var health_difference = new_health - old_health;
if (health_difference !== 0) {
client.display_notice("Health change: " + health_difference, "red");
old_health = new_health;
}
};
var health_change_listener = gmcp_events.subscribe("Char.Vitals", health_change);
Now every time the client receives a Char.Vitals GMCP message, it will run our health_change function (automatically passing it the gmcp_args).
If we want to turn this off, we can just remove the listener:
health_change_listener.remove();
Summary:
To add a listener, use:
gmcp_events.subscribe("GMCP Method Name", myFunction);
This passes args.gmcp_args as the first argument to myFunction and it returns a handle that can be used to remove the listener.
Adding a listener and saving the handle so we can remove the listener later:
handle = gmcp_events.subscribe("GMCP Method Name", myFunction);
To remove a listener, use:
handle.remove();
Comments
One usability and one feature suggestion:
- Make the gmcp messages all lower case all the time. This will help people who are new-ish to gmcp and coding.
- Allow the subscription to "event groups" in one go. Say I want to catch all Char.Items messages (Char.Items.Add, Char.Items.Remove, Char.Items.List, Char.Items.Update) in one function and branch out from there. Then I'd like to subscribe to Char.Items instead of all messages individually. In that event, you may want to hand the actual gmcp message as a second argument to the function.
GMCP documentation: https://github.com/keneanung/GMCPAdditions
svof github site: https://github.com/svof/svof and documentation at https://svof.github.io/svof
And I'm not really sure I understand the second request. Char.Items.Add and Char.Items.Remove, for instance, have the same syntax for their data, so you have to use the name to distinguish between them. Passing the whole GMCP message as the second argument just so someone can subscribe to both of them at once, then just end up using that second argument to test the event name seems like it defeats a lot of the purpose of the whole thing. I don't think it's very easy to do given the way Nexus is written either - getting the "gmcp_method" and the parsed "gmcp_args" is easy. But to get the actual message I think I'd have to monkey-patch the internal GMCP-handling code and it's pretty ugly.
In the hypothetical situation where you want to do the same thing when you receive Char.Items.Remove and Char.Items.Add without distinguishing between them, it seems a lot clearer to me to have two subscriptions with the same function. And if you want to do something that differs between the two, it seems a lot clearer to me to have two subscriptions there too.