I need to highlight a skill on this gain list, but I do not want to highlight the entire line.
My class is a thief. I need to beable to highlight certain skills i need to gain as I level up. I need 'smooth talk 3 58' But I do not want to highlight Spelunking, it does me no good.
I searched for highlighting and it was FAR FAR too complicated, and time consuming for me to setup for each indivual classes and what not.
Please add this capability, your client is the best, has been the best for me since, only god who knows when, I started using it, 2.15 now that I think about it, or somewhere around there.
What might work better than highlighting the skills you want is gagging the skills you dont want. Granted, its almost as ugly to code but then again, anything that manipulates output from the mud is more difficult than simple triggers to react to that same output. Highlighting isnt a simple process because it essentially gags the original output, processes whatever changes you want for easier reading, and outputs the modified text.
Not really that hard. Use a regular expression like:
^(master dagger|appraisal|smooth talk) \d+ \d+
Then just add new things into the () section as needed. This would hilight any one of the matching names and the two values after them.
You could also create a few aliases to add, remove and list them that call these subs (the trigger edit field gets crowded with more than a handful of match possibilities. lol):
sub Addskill(aname, output, wilds)
dim tcolor = 1 'Change this to the custom color you use.
dim Temp
Temp = GetTriggerInfo("SkillHlt", 1) 'Get match text.
dim p1, p2, T1, T2, T3
p1 = instr(Temp, "(")
p2 = instr(Temp, ")")
T1 = left(Temp, p1) 'Get the first bit.
T2 = mid(Temp, p1 + 1, p2 - p1 - 1) 'Get our list of skills.
T3 = right(Temp, len(Temp) - p2 + 1) 'Get the last bit.
dim fnd
fnd = 0
if T2 = "" then 'No skills, so just add it.
T2 = wilds(1)
else
dim Skills, count
Skills = split(T2,"|") 'Split into an array then check if already in list.
for count = 0 to ubound(Skills) 'Loop through all the skills we have in the list.
if Skills(count) = wilds(1) then
fnd = 1
end if
next
if fnd = 0 then
T2 = T2 + "|" + wilds(1)
else
world.colournote "red", "black", "That skill is already being tested for."
world.note " "
end if
end if
if fnd = 0 then
world.addtrigger "SkillHlt", T1 & T2 & T3, "", 1065, tcolor, 0, "", "", 0, 100
world.note wilds(1) & " added to hilight list."
world.note " "
end if
end sub
sub Remskill(aname, output, wilds)
dim tcolor = 1 'Change this to the custom color you use.
dim Temp
Temp = GetTriggerInfo("SkillHlt", 1)
dim p1, p2, T1, T2, T3
p1 = instr(Temp, "(")
p2 = instr(Temp, ")")
T1 = left(Temp, p1)
T2 = mid(Temp, p1 + 1, p2 - p1 - 1)
T3 = right(Temp, len(Temp) - p2 + 1)
if T2 > "" then
dim Skills, count, fnd
Skills = split(T2,"|")
fnd = 0
for count = 0 to ubound(Skills)
if Skills(count) <> wilds(1) then
if count > 0 then
T2 = T2 + "|" + Skills(count)
else
T2 = Skills(count)
end if
else
fnd = 1
end if
next
if fnd = 1 then
world.addtrigger "SkillHlt", T1 & T2 & T3, "", 1065, tcolor, 0, "", "", 0, 100
world.note wilds(1) & " successfully removed."
world.note " "
else
world.colournote "red", "black", wilds(1) & " not found in list."
world.note " "
end if
else
world.colournote "red", "black", "There are no skills to remove."
world.note " "
end if
end sub
sub ListHlt (aname, output, wilds)
Temp = GetTriggerInfo("SkillHlt", 1)
dim p1, p2, T1, T2, T3
p1 = instr(Temp, "(")
p2 = instr(Temp, ")")
T2 = mid(Temp, p1 + 1, p2 - p1 - 1)
if T2 = "" then
world.note "Nothing to list."
else
dim count, Skills
Skills = split(T2, "|")
for count = 0 to ubound(Skills)
world.tell Skills(count) & space(20 - len(Skills)
if (count + 1)/3 = int((count + 1)/3) then 'This gives us 3 skills per line when displayed.
world.note " "
end if
next
world.note " "
end sub
I haven't testing this, so there could be bugs in them. ;) They need to have the trigger added 'before' they will work, since they rely on T1 and T3 being taken from the trigger text. If you replaced those lines with T1 = "^(" and T3 = ") \d+ \d+" in the first sub then it 'may' in theory be able to create the trigger even if not already present, but I am not entirely certain.
In any case, you can match more than one possibility in a single trigger, having aliases to manage it is just a bit easier. ;)
Its been a while, I'm seriously rusty with my vbscript.
Your post about the code I semi-understand what that code does is allows me to add or remove skills from the regular expression trigger that you mentioned. I was under the impression that even if I didn't do that code, the way you setup that trigger it should work.
The trigger didn't seem to work for me...
I might be doing something wrong with the trigger.
match on:^(master dagger|appraisal|smooth talk) \d+ \d+
checked: Enabled, regular expression.
all else unchecked
Colour: custom colour 1
First, not all of the skills start the line so we can drop the ^. :)
(master dagger|appraisal|smooth talk) \d+ \d+
Secondly, I don't freaking know what the \d+ \d+ is
do I dropped that too. :)
(master dagger|appraisal|smooth talk)
This highlighted the skill names, but not the cost or the level. so I added this:
(master dagger|appraisal|smooth talk) (.*) (.*)
Ding ding ding, we have a winner!!!
Of course 3 minutes later, I find out that it still highlights the entire line behing it. because of the wild cards... Ok so wildcards won't work.... I just need some help in figuring out how to make it match on those numbers withuot it being a wild card, because everything after the first wilcard then becomes a wild card
\d+ means, "one or more digits". Using them instead of the normal .* wildcard means it should only match where the result is 'skill_name cost level' In other words it would hilight the skill and numbers in a sentence like 'My skill is - appraisal 3 5' but not in 'Do you have appraisal or not?'. You should have left those in there. ;) lol
Well... Once you get a skill, its removed from the list.
With the \d+ the trigger does not work.
Without it, it does. The cost, and level for the skill is not necessary, but it'd be nice, I can live without it.
I just wanna highlight the skills I need to gain, without the higligh its a pain in the arse to search for the skills you want. with it highlighted against the rest, they pop out easy and I can find the ones i want much more quickly.
If you can think of something other than \d+ Perhaps [d]+ would work better? I don't know.
Hmm. Wait... In your examples all the names and values where crammed together. Is it more like:
appraisal 3 10
If so then it is obvious why it doesn't work. It only checks for a 'single' space between the name and the digits. You need it to be:
(master dagger|appraisal|smooth talk)\s+\d+\s+\d+
that way it will be the name, followed by 'one or more' spaces, then followed by one or more digits and so on. I didn't even consider that.
There are times that the forum's assumption that it knows better how I intended to format a line than I do is a bit annoying. ;) Imho, programs should never intefere with intentional user formating unless the line is in an actually paragraph and can thus be assumed to be incorrect, but most things don't do this, so I gotta live with it. You should try to remember when posting 'anything' direct from a mud to check the 'forum codes' box and include it in a [code] block. It cuts down on a lot of confusion. ;)
In any case the codes you are most likely to use for matching are:
\w - any thing that can be in a word.
\s - white space (especially spaces themselves, but also tabs)
\S - anything that isn't a white space character.
\d - numbers
You can then use all the other stuff to modify them like:
? - it will match, but doesn't need to be there to do so.
+ - one or more.
{x, y} - x is the minimum number to match, y is the maximum. Doing {x,} is the same as +, but with a minimum that you specify.
My only real gripe is that () is used to define both a 'sub pattern', like we use here, and also the text to return as a wildcard. This is annoying when you have to break a line up into groups, but you don't really care if that part of the matched line is actually passed to a sub.
Anyway. The above is 'most' of what you are likely to need for 99% of stuff you create triggers for, but at some point it is a good idea to read the document that comes with mushclient about regular expressions. Unfortunately it seems to have been written more like a diagram of the syntax, than something intended to help you figure out how to use it. lol Probably got copied directly from some Unix system where everyone was a tech head. ;)
I need to highlight a skill on this gain list, but I do not want to highlight the entire line.
My class is a thief. I need to beable to highlight certain skills i need to gain as I level up. I need 'smooth talk 3 58' But I do not want to highlight Spelunking, it does me no good.
I searched for highlighting and it was FAR FAR too complicated, and time consuming for me to setup for each indivual classes and what not.
I gather from all these complex-looking posts that the simple solution is no good?
To simply highlight one word, but not the entire line, set up a trigger that is a regular expression, that just matches that word (or group of words). eg.
Umm. That is what he is using now, but he 'also' wanted to color the values that followed it. But since he didn't provide an accurate version (i.e. the forum compressed all the extra spaces out of his example) I gave him something that wouldn't work as expected. My last post was the suggested fix and a descriptions of some common regex codes that are likely to be the most useful. ;)
I also provided tools to modify the content of the trigger easilly without having to go into the editor. Had I realized he needed it to match on multiple spaces, the issue would have already been solved. ;)
I figure sk{command} is likely easier to remember and it doesn't matter if the alias you type differs from the script name, however they work just like triggers, so you need that wildcard there for it to do anything. The code itself goes into the script file I think I remember you being told to create in another thread. Unless you turn your scripts, triggers, timers and aliases into plugins, the file you created and specified in the scripting settings is 'always' where code goes.
Ya, I was really tired and I missed the wildcard in the alias. My knowledge of vbscript is really weak, I'm getting errors all over the place, with the code you put up earlier... I don't even have the slightest idea what might be wrong.
It has to do with:
dim tcolor = 1 'Color you want put ehre or something
Its telling me its an expected end of statement/line I believe.
If you would like to help me work out these bugs(meanign you get to do all the work and I get the benefits :P), we could work it out through email.
dim tcolor
tcolor = 1 'Change this to the custom color you use.
VBScript for some idiot reason doesn't allow you to declare a variable and assign it a value on the same line. Hopefully that ends up being the only bug. ;) The code should be fairly straight forward and not likely to have too many bugs. However, since that one slipped through.. lol
Fixed some of the obvious problems... a missing end if statement in the last sub
A missing ) in one of the subs.
Get a couple of different errors when trying to use the aliases
Alias: askill *
label: askill
Script: Addskill
Alias: rskill *
Label: rskill
Script: Remskill
Alias: lskill
label: Lskill
Script: ListHlt
Trigger:(knife fighting)\s+\d+\s+\d+
checked: ignore case, regular expression
no change in colour as of yet.
unchecked: all(I have a script to enable and disable the trigger when I type gain list, else it highlights the words even in normal channel use.)
Label: skilllist1
When I type:
askill dancing
I get this:
Error number: -2146828283
Event: Execution of line 39 column 3
Description: Invalid procedure call or argument: 'mid'
Called by: Function/Sub: Addskill called by alias
Reason: processing alias "askill"
When I type
rskill knife fighting
I get this:
Error number: -2146828283
Event: Execution of line 76 column 3
Description: Invalid procedure call or argument: 'mid'
Called by: Function/Sub: Remskill called by alias
Reason: processing alias "rskill"
When I type:
lskill
I get this:
Error number: -2146828283
Event: Execution of line 112 column 3
Description: Invalid procedure call or argument: 'mid'
Called by: Function/Sub: ListHlt called by alias
Reason: processing alias "lskill"
I'm thinking maybe the trigger may be a bit on the flubby side because of the added \s+ because of the spacing. If I'm assuming correctly then the first error cause by line 39
T2 = mid(Temp, p1 + 1, p2 - p1 - 1) 'Get our list of skills.
Is the T2 is the space. and it should be changed to T3... because of the added \s+
I could be wrong on this however.
Same goes for the following 2 errors, its looking for information that is not present at the moment in the trigger because the spot its looking for is a space.
which will correctly return the 'Some Skill' part. Hmmm...
Ok. Quick fix for the first problem would be:
if p2 - p1 - 1 > 0 then
T2 = mid(Temp, p1 + 1, p2 - p1 - 1) 'Get our list of skills.
else
T2 = ""
end if
Replace the existing T2 = mid... lines with the above and it won't ever try to grab data from a blank list. Now as to why it would cause an error when the trigger actually contains data.. You did give the trigger the name 'SkillHlt'? Unless the initial trigger has that exact name it won't return the trigger, but instead returns "", because the script will be getting data on a non-existant trigger.
Kool froobies.
Got Addskill, and Remskill working... There was a slight error in the world.addtrigger... a buncha stuff on the end that wasn't needed... I couldn't figure out what it was for(compared to the help file, Yah yah, I RTFM a lot ok? Sue me :P ), so I took it out. I'm gathering it was for timing reasons, no biggity, the timing isn't really needed.
When I lskill to get my list of skills, I get this error
Error number: -2146828275
Event: Execution of line 119 column 7
Description: Type mismatch: 'Skills'
Called by: Function/Sub: ListHlt called by alias
Reason: processing alias "lskill"
The line in question is:
world.tell Skills(count) & space(20 - len(Skills))
Not sure whats wrong with that. I don't see any obvious errors. Your using the split command to split the array and world.tell to show it on the screen.
I'd like to try and set it up so that when I gain a skill on my list, it automatically removes it from the trigger.
I have a decent idea about how to do this but I was hoping you'd help me refine it a bit.
Alias: gain *
Label: whatever
script Removehlt
sub Removehlt (aname, line, wilds)
blah blah blah blah no idea what goes here yet
setup a split to split up the trigger,
if t2= wilds (1) then
somehow remove it from the list
else
end sub
Or something like that... It jsut occured to me that by combining some of the addskill and remskill and skillhlt subs I could probably figure it out, as soon as I get skillhlt subroutine working i'll look into it with more detail. I know what needs to be done, and I got a pretty gosh darn good idea of how its gonna look, but its all the little things.
Like setting up pre-split, using dim and what not, that I don't know, things like that whole p1, p2 thing, no idea what that does yet, you tossed out the script without me fully understanding what it does.
Not that, that bothers me, but Its a bit of a pain to figure it out on your own just by looking at it and reading help files(which I do often).
My autocombo script I partially wrote with Nick started out as a trigger that copied the wild card into the clipboard and the alias just pasted that into the send. and it evolved from there, I knew variables were a better way to go, but I didn't know how to get there from where I was.
Needless to say, one thing led to another, and pretty soon, Nick and I were working on the script you see blow this, in my sig. I gotta hand it to Nick, he has a great Program, and unlike... well unlike anything I've ever seen, he takes the time to cruise the forums and reply to people, I don't know if there are any other client programs out there that are better than This one, but even if there were.
1. I highly doubt they have the coustmer support that MUclient(I LOVE the new name) does.
2. Simple.. Simple.. Simple.. I can not stress how user friendly MUclient is, Sorry as I digress, but props must go where they belong, Simple and user friendly is the way to go, And lemme tell you I've watched mushclient evolve into a more and more user friendly gui, the only thing that I can see as making it even better than it is, is a short tutorial about the basics of setting up a world. Also perhaps an introductory walk through on how to setup a world, perhaps an interactive gui that assists newbs in setting up their first world, explaing what some of the features are... Just an Idea mind you.
3. Scripting... This is so powerful, its unbelievable, it allows a user with some patience, and a head on their shoulders, to customize their MU* experience completely. It allows you to do things with information at speeds your mind, not reflexes can even begin to compare to.
Ok... I've rambled enough, its now 11:30am, I'm still awake and tired... You can usually tell by my ramblings, but thats another story..
I hope you all have a good day, thanks for putting up with my excessivly long post.
Gah.. It was supposed to be 'world.addtriggerex', for an extended set of options. However, those last two options are only for defining SendTo and Sequence number (where it appears in the trigger list). They really aren't needed as you noticed. ;)
As for the last item. I had kind of assumed that skills worked a bit like on mine, where you get the skill, but then have to train it a bit after. Or that it used something a bit like the Shadowrun rules where each level of the skill cost (current level + 1) to get the next. I take it that instead you just pay the cost for it and 'bingo' you now have it?
Then things are quite simple. Scripts for aliases don't really care what aliases (or even trigger) calls then. You can use some interesting tricks that involves checking the 'name' parameter that gets passed to them in cases where you want the script to do something different depending on the trigger or alias that called it. In one setup I have, there are about 20 triggers that match on protection and booster spells that all call the same sub and fire off announcements to party members based on which trigger called it.
What this means is that you can simply do this:
Alias: gain *
Label: GainIt
script: Remskill
Send: gain %1
The alias can send text 'and' call scripting at the same time, so you can reuse the same script for both cases. ;)
As for some explaination of how things actually work:
DIM and REDIM - The first of these is used to declare variables. Back in the sane pre-VBScript days you would use something like STATIC, COMMON or SHARED. However this was back when Basic actually knew the difference between a String and an Integer. VBScript however uses what is known as a Variant. This means that every variable is initially declared something like a = V123, where V means variant. If you then do something like a = a + 1, then VBScript looks at the contents and changes it to a = I124 or something like that. This is confusing as hell in some cases, because if you accidentally do something that changes it to S123 (string), and then do a = a + 1, get a = S1231 instead. VBScript basically 'guesses' based on the code you give it what the actually variable type is supposed to be. This can cause some odd bugs... More on REDIM later.
What all of this means is that since VB doesn't know the difference between a string or a number until you use them as such, they removed all the convenient options of doing COMMON a AS INTEGER and replaced it with DIM (this makes no sense to me, but.. it is Microsoft we are talking about. lol) The 'only' type you can declare with DIM that acts like it should are arrays, i.e. DIM a(10), but even then it doesn't have a clue if it should be integers, strings or flying pigs, until you place something into it. The only real advantage being that you can probably place anything you want into each seperate element and the script will only complain if you later try to use it some way that isn't allowed. How this is an advantage I leave to someone else to decide. ;)
In most cases you don't even need DIM, you can simply use a variable when you need it and have VBScript automatically declare it. However, plugins that Mushclient generates include a statement 'OPTION EXPLICIT', which forces the script to reject any variables you try to use that you didn't create using DIM first, so it is a good thing to remember to do, or you will spend a lot of time asking why the script you just placed in a plugin doesn't work right. ;) The joke being that 'option explicit' only checks to make sure a variable is pre-declared. It can't/won't warn you that you failed to give it a value before using it. Exactly why this is useful in a language that doesn't care if the variable has been declared, what it contains, the type you wanted it to be, etc. is something I am still trying to figure out. The only case I can see where it 'may' be helpful is with global variables and since you can't use 'common' or the like to 'explicitly' (note the correct use here) declare the variable as global this is pretty worthless imho.
Now p1 and p2 use a function called 'instr'. This finds the first instance of a string 'in' another string and returns the location it was found. If it finds nothing, then it returns 0. I use these positions to basically save everything before and after the part I am interested in changing in T1 and T3 using 'right' and 'left'. I think you can figure out what they do. ;) I also use these numbers to figure out where in the middle of the original string the actual list is and place that into T2 using 'mid'.
Which brings us to 'split'. This command takes a string, searches it for the string you request and splits the result into and array, while dumping the character(s) you had it look for. One very important thing to note here, it for some reason I don't get (Ask MS about bugs some time) it will create an array that can be resized, but acts like one that has been created with DIM otherwise. What do I mean? DIM variable(number of places) creates a non-resizable array. REDIM creates a 'dynamic' array, which means you can go back later and use REDIM it to a size that is bigger or smaller than it currenty is. I.e. REDIM a(10), then later do REDIM Preserve a(20). The 'Preserve' command is where split arrays fail, if you do a = split("a,b,c,d",",") you get:
a(0) = "a", a(1) = "b", a(2) = "c", a(3) = "d"
However, if you then tell it 'redim preserve a(10), you 'should' get:
a(0) = "a", a(1) = "b" ... a(9) = ""
Instead it ignores 'preserve' and gives a(0) = "" ...
I definitely think that this is a bug that MS just hasn't gotten fixed, but it is something to watch out for, not to mention quite irritating if, unlike with your script, you want to add something to an array that is in alphabetical order. And of course, to make life even more impossible, VBScript has no built in sort command.
Some things in Java and Perl definitely make life easier, but VB is a bit easier to understand, so it tends to be a trade of between sometimes doing things the hard way, but being able to understand someone elses code, or being able to do things the easy way and never touching someone elses code. ;) lol
Making this new alias:
alias: gain *
label: Gainit
Script: Remskill
send: gain %1
Works like a charm... except...
In order to get the gain list.
You need to type:
Gain list
Furthermore, you can change practices into train by typing:
gain train
Is there an easy way to check the wildcard, and if it's equal to gain train or gain list, it ignores the script?
Else it does the remskill sub?
I would imagine that just adding a simple line to the remskill sub you could put this check into it. I have an idea as to how to do it, but I'm not sure where to put it in, or would I need a whole entire new script?
Also, I was hoping maybe you could help me figure out how to do something else.
I have a trigger that helps me practice my spells by pamming it 10 times, then sleeping to regen mana, then standing and casting it 10 more times.
What I'd like to do is beable to change that spell that is spammed 10 times with an alias.
My trigger is: you wake and stand up
send: c 'impart str' ring(repeated 10 times)
sleep pillow
Then that triggers:
world.doafter 20, "stand"(might I add doafter is much better than world.addtimer)
spam strength ring
spam agility necklace
and so on and so forth.
If you do not want to spam the suggestion board with this, we could take this to email if you like.
Further more, I setup a timer for every 2 minutes, to autosave my world that is active.
It runs AutoSave script
The script is:
sub AutoSave (line, name, wilds)
world.worldsave ""
world.colour note "white", "black", "Saving...."
end sub
I get this error saying that it expects an arugument, Well after reading the help file(on that subject) on the website
and playing with it for 10 minutes, I still got the, world.save "" expects an addition argument.
if wilds(1) = "list" or wilds(1) = "train" then
exit sub
end if
to the very beginning of the Remskill sub.
Hmm. For the spell casting thing.. You need to move the stuff the trigger does into a script, then make your alias call a sub to set two variables.
sub Cast10(name, output, wilds)
dim count
for count = 1 to 10
world.send "c " & world.getvariable("SpellName")
next
world.send world.getvariable("Sleeper")
end sub
sub SetCast(name, output, wilds)
world.setvariable "SpellName", wilds(1)
world.setvariable "Sleeper", wilds(2)
end sub
As for the world.save issue... I thought that had been fixed. In older versions it would incorrectly fail if you didn't give the actually name at least once, but Nick was supposed to have corrected it... However you can probably use this to fix it:
Oh.. Then world.save "" will work. The problem is that Timers don't match on anything that would show up in 'output' or pass anything in wild cards, so the only parameter they do pass to scripting is 'name' like:
sub TimerScript (name)
...
end sub
I am guessing you tried to use the same set of parameters as for triggers and aliases? ;)
After much wailing and gnashing of teeth I worked my way through how to setup that script for counting spells and what not. In the end the machine payed homage to its master...
Works like a charm now... I even have used that counting thingy script for something else *cheers*
As an added thought, I'd like to make the script count down each casting, or perhaps every time it goes through the count
Not entirely certain how to do that really. To make things more difficult I'd like to try and Center the numbers in the middle of the screen instead of on the left side.
Thanks a bunch...
I'm just chock full of idea's.... On this mud we have this thing called hero points, once you go 1 level after 100, you start hero levels, based on your experience per level, you get x amount of points per hero level
They do not have a prompt letter for the amount of hero points you have, I would like to add a trigger that sets up a variable that keeps track of the amount of hero points that I have, and world.note it to me. every single line. sort of like a clientside prompt.