Hi folks,
I'm tied to the new client as it's the only one I can use from work, and I'm trying to start some basic scripting. I'll probably have a bunch of idiot questions, but I fell at the final hurdle when trying to script my first thing. I can't seem to access gmcp variables properly. To test it out, I made a test thing which did this: client.send_direct(print(gmcp.Char.Afflictions.List))
But when I do that, I get "ReferenceError: 'gmcp' is undefined" so I'm guessing I'm not using the right syntax to call gmcp variables. What am I doing wrong?
Thanks!
0
Comments
gmcp.Char.Vitals
You'll specifically receive gmcp events in the "onGMCP" script that is already in there I believe. So I would do my GMCP organising in that script, and then put all the args into variables that you will use in other scripts.
-
One of the symptoms of an approaching nervous breakdown is the belief that one's work is terribly important
- Send GMCP requests via send_GMCP(request); like send_GMCP("Char.Skills.Get");
- Review GMCP messages sent to you by looking at args.gmcp_method and args.gmcp_args
client.send_direct(print(gmcp.Char.Afflictions.List)); doesn't make any sense - first, Char.Afflictions.List isn't a thing you can send, it's a thing the server sends you when you diagnose.But, more importantly, client.send_direct(print(anything)); will never work, for anything, ever. I'm not really sure what you're trying to do with that. print(string); outputs text to the client, while client.send_direct(string); sends commands to the game server. And since print(string); doesn't return anything, there's nothing to send. It looks like you're trying to do two opposing things at once and I'm not really sure what your intention is.
As for how to do GMCP:
First, Keneanung has a lovely github page that documents all the GMCP stuff: https://github.com/keneanung/GMCPAdditions
If you want to send a GMCP request, you need to use send_GMCP(request); like send_GMCP("Char.SKills.Get"); and this will only work for the things in that github page marked "Sent by Client".
If you want to look at the GMCP messages the game is sending to you, you need to put a script into an onGMCP "function" (this is a special "function" that runs every time the client receives a GMCP message from the game server). Whenever the client receives a GMCP message, it saves the type of the message (e.g., "Char.Afflictions.List") in args.gmcp_method, and saves the details of the GMCP message as an array of (potentially nested) objects in args.gmcp_args.
Since Char.Afflictions.List is longer, it's not a great example since you'll have to loop through it to print everything, so for the sake of simplicity, let's first look at Char.Afflictions.Add, the GMCP message you'll get when you get an affliction. If you want to print all the details from every Char.Afflictions.Add GMCP message, your onGMCP would look like this:
We have to wrap it in that if because onGMCP runs on every GMCP message, but we're only interested in the data in Char.Afflictions.Add - if you want to look at another GMCP message too, you just slap another else if clause onto the end, so you can run something when args.gmcp_method is equal to whatever other GMCP message you care about.
If you wanted to print the whole Char.Afflictions.List thing, instead of an object with name, cure, and desc properties, that gives you an array of those objects, one for each affliction, so if you want to print the whole thing you need to iterate through the array with some sort of loop. So that could look something like this:
Here I'm using forEach, but if you aren't familiar with that array method, you could also use a for-in loop, or even an explicit for loop using args.gmcp_args.length (i = 0, n = args.gmcp_args.length; i < n; i++), though then you have to actually look up the elements by index with something like print("Name: " + args.gmcp_args[i].name);
Hope that helps.
I think I can do this by checking for each affliction in turn, and then doing a bespoke line for each affliction, like:
1. for (var x in afflictions) {
2. if (afflictions.name[x] === "agoraphobia" {
3. client.send_direct("heal me " + afflictions.name[x])
4. }
5. }
Kind of thing, and then just repeating that code for every healable affliction with else ifs and whatever. (Carmain helped me set up the afflictions variable in onGMCP so that it is a copy of Char.Afflictions.List). That seems super inefficient though, and ideally what I'd do is something that checked if afflictions.name[x] was on a list of healable affliction names, and if it was, then it would do "client.send_direct("heal me " + afflictions.name[x])".
I'm coming up blank though on how to do that. There's other wrinkles, of course, like not curing insomnia/blindness/deafness and I should be fine with that, but can anyone help with the list searching?
Really appreciate the help!
Edited to fix a stupid error above
GMCP documentation: https://github.com/keneanung/GMCPAdditions
svof github site: https://github.com/svof/svof and documentation at https://svof.github.io/svof
Thanks - this is super helpful. I tweaked your suggestion @Keneanung, so now my code looks like this:
1. var curableAffs = ["paralysis", "confusion", "slickness", "stuttering", "paranoia", "shyness", "hallucinations", "generosity", "loneliness", "impatience", "lapsingconsciousness", "claustrophobia", "vertigo", "sensitivity", "dizziness", "brokenarms", "dementia", "clumsiness", "burning", "recklessness", "anorexia", "agoraphobia", "disloyalty", "hypersomnia", "darkshade", "masochism", "epilepsy", "asthma", "stupidity", "vomiting", "weariness", "haemophilia", "brokenleftarm", "brokenrightarm", "brokenleftleg", "brokenrightleg", "hypochondria"];
2. client.send_direct("diag me");
3. for (var x in afflictions) {
4. if(curableAffs.indexOf(afflictions[x].name)) > -1){
5. if (curableAffs.indexOf(afflictions[x].name)) === "brokenleftleg") || (curableAffs.indexOf(afflictions[x].name)) === "brokenrightleg") {
6. client.send_direct("heal me brokenlegs");
7. }
8. else if (curableAffs.indexOf(afflictions[x].name)) === "brokenleftarm") || (curableAffs.indexOf(afflictions[x].name)) === "brokenrightarm") {
9. client.send_direct("heal me brokenarms");
10. }
11. else {
12. client.send_direct("heal me " + afflictions[x].name);
13. }
14. }
15. }
But I'm getting a syntax error. Anyone want to help me with where I went wrong?
GMCP documentation: https://github.com/keneanung/GMCPAdditions
svof github site: https://github.com/svof/svof and documentation at https://svof.github.io/svof
There are quite a few syntax errors in your code (mostly involving extra parentheses). Here it is all cleaned up and formatted in a more conventional style. If you diff this and your code, I imagine you can probably figure out how the parentheses are supposed to work in javascript, but if you have any questions, feel free to ask.
What you're probably going to want to do is put that loop into your onGMCP function behind a toggle variable.
So initialize a variable like var curingAll = false; in your onLoad function (this is like onGMCP, but only gets run once, when you load your settings, so it's an ideal place to put variables - I doubt you'll see any difference in performance, but you probably want to define your curableAffs there too so you can avoid rebuilding the array every time you run this - and it wouldn't be a terrible idea to throw in var afflictions = []; either).
Then you have an alias that just does client.send_direct("diag me"); and curingAll = true;
Then you have your onGMCP function, which looks for Char.Afflictions.List and creates your afflictions array, and then also has your for-loop here right after that, but wrapped in if (curingAll) {}. And either before or after the loop (but inside the if block) you have curingAll = false;
So what ends up happening is: onLoad sets curingAll to false when you load your reflexes (and also initializes your curableAffs array and declares your afflictions array), your alias to fully cure yourself sets curingAll to true and sends a diag request to the game, then your onGMCP function triggers off of the Char.Afflictions.List message, which fills your afflictions array with your current afflictions from the GMCP message, then since curingAll is true, you loop through afflictions and send a cure command for each one and also set curingAll back to false (so it doesn't auto-cure everything the next time you do a normal diagnose without using the alias).
Also, in general http://www.jslint.com/ is a useful tool for diagnosing the source of syntax errors. Though it'll throw some weird errors for things you probably don't care about too (it doesn't like that for-loop for instance because it would rather you use something like forEach).
That is so helpful, it really is. You don't have to take time out your days to make my terrible scripts better and teach me as well - hugely appreciated. No doubt, I'll be back later when I screw it up some more