Unknown2007-01-02 18:50:29
I know the basics about coding in zmud, but I can't figure out how to use queues.
Say I have sensitivity and slickness, both needs herb to cure and say I get them both at the same time, how would I make them queue so first of all I eat one herb then when I get herbbalance back again I eat the next one in queue.
I figure you need variables and the trigger lines for each aff and a #additem thingy? I have no idea when it comes to queues... Any help is greatly appreciated, you've all been so helpful so far!
Say I have sensitivity and slickness, both needs herb to cure and say I get them both at the same time, how would I make them queue so first of all I eat one herb then when I get herbbalance back again I eat the next one in queue.
I figure you need variables and the trigger lines for each aff and a #additem thingy? I have no idea when it comes to queues... Any help is greatly appreciated, you've all been so helpful so far!
Unknown2007-01-02 19:09:52
QUOTE(Newplayer @ Jan 2 2007, 12:50 PM) 368678
I know the basics about coding in zmud, but I can't figure out how to use queues.
Say I have sensitivity and slickness, both needs herb to cure and say I get them both at the same time, how would I make them queue so first of all I eat one herb then when I get herbbalance back again I eat the next one in queue.
I figure you need variables and the trigger lines for each aff and a #additem thingy? I have no idea when it comes to queues... Any help is greatly appreciated, you've all been so helpful so far!
Mechanically, there are a few different ways people prefer to do this, using data records, stringlists, etc.
The idea is that, when you get an affliction, you store the fact that you have that affliction; you don't cure it right that instant (how you store it is up to you - flag variables, data records, etc.).
Then, you have a routine that checks all your herb-curable afflictions. Once again, the mechanics may differ, but the basic idea is that you use if... if/else... else logic to do your priority. So, when HERBCURES fires up, my logic looks through my variables and says, "Do I have AfflictionX? If yes, then cure that, if not, look for AfflictionY. Do I have AfflictionY? If so, cure it. If not, look for AfflictionZ...."
lydin2007-01-03 04:19:29
Yeah, exactly.
Example using a string list:
#TR {You blink for a moment, then instantly, all about you is darkness} {#IF @herbbalance {eat myrtle} {#additem herbqueue myrtle}}
#TR {^You feel a terrible thirst for elixirs grow within you.$} {#IF @herbbalance {eat galingale} {#additem herbqueue galingale}}
#TR {You may eat or smoke another herb} {#IF (@herbqueue != "") {eat %item(herbqueue, 1);#DELN herbqueue 1}}
So, when you get blinded, if you have herb balance you eat myrtle. If not, it gets added to the queue. When you can eat another herb, if there's something on the queue, it eats the first herb and then deletes it from the string list.
If you want something more robust, then do it this style.
#TR {You blink for a moment, then instantly, all about you is darkness} {#var blind 1;#IF @herbbalance {eat myrtle}}
#TR {^You feel a terrible thirst for elixirs grow within you.$} {#var addicted 1;#IF @herbbalance {eat galingale}}
#TR {You may eat or smoke another herb} {#IF @blind {eat myrtle} {#IF @addicted {eat galingale}}}
A little more complicated but two benefits: This way you can prioritize and add other conditions, so blindness gets cured before worrying about addiction and you might make it #IF @blind&!@sixthsense {eat myrtle}.
Disclaimer: these aren't actual systems and I didn't test them to make sure I didn't typo or anything stupid. You might want to remove the herb from the cure when you actually see yourself eat it, and myrtle might not be your best option for blindness, but it's just an example of how you might implement a queue. In my own system I actually queue affliction names and test a stringlist instead of variables.
Example using a string list:
CODE
#TR {You blink for a moment, then instantly, all about you is darkness} {#IF @herbbalance {eat myrtle} {#additem herbqueue myrtle}}
#TR {^You feel a terrible thirst for elixirs grow within you.$} {#IF @herbbalance {eat galingale} {#additem herbqueue galingale}}
#TR {You may eat or smoke another herb} {#IF (@herbqueue != "") {eat %item(herbqueue, 1);#DELN herbqueue 1}}
So, when you get blinded, if you have herb balance you eat myrtle. If not, it gets added to the queue. When you can eat another herb, if there's something on the queue, it eats the first herb and then deletes it from the string list.
If you want something more robust, then do it this style.
#TR {You blink for a moment, then instantly, all about you is darkness} {#var blind 1;#IF @herbbalance {eat myrtle}}
#TR {^You feel a terrible thirst for elixirs grow within you.$} {#var addicted 1;#IF @herbbalance {eat galingale}}
#TR {You may eat or smoke another herb} {#IF @blind {eat myrtle} {#IF @addicted {eat galingale}}}
A little more complicated but two benefits: This way you can prioritize and add other conditions, so blindness gets cured before worrying about addiction and you might make it #IF @blind&!@sixthsense {eat myrtle}.
Disclaimer: these aren't actual systems and I didn't test them to make sure I didn't typo or anything stupid. You might want to remove the herb from the cure when you actually see yourself eat it, and myrtle might not be your best option for blindness, but it's just an example of how you might implement a queue. In my own system I actually queue affliction names and test a stringlist instead of variables.
Unknown2007-01-03 12:39:41
Data record variables are the most efficient method of tracking afflictions and defenses, hands down.
lydin2007-01-04 06:09:17
QUOTE(Zarquan @ Jan 3 2007, 07:39 AM) 368968
Data record variables are the most efficient method of tracking afflictions and defenses, hands down.
Ooo good idea. Why didn't I think of trying that?
When you say more efficient do you mean processing wise? Mine runs fast with strings, but I've got plenty of processing power to burn.
At any rate it sounds more flexible and convenient to do it that way. I think I'll convert!
On a related note, I store my affliction and curing text and data in Excel spreadsheets that build my scripts using formulas, so making large scale changes like that is easy. I'll post it if I ever make it tidy. The formulas are ugly though.
Unknown2007-01-04 13:36:56
It's more efficient processing-wise, yes. It's also more flexible, and I think it's easier to read and code. For example, instead of resetting dozens of variables, as some systems do, I just set one or two variables to an empty string and all my afflictions/defenses are reset.
Laysus2007-01-04 22:24:59
Or you can do it my way, which confuses the hell out of me at times >.>
Databases for lookup tables with lists for storing prioritised cures (i.e. 012myr for the 12th highest priority which is in this example eating myrtle), and then some really fugly failsafes to make sure what I try to cure is curable.
Databases for lookup tables with lists for storing prioritised cures (i.e. 012myr for the 12th highest priority which is in this example eating myrtle), and then some really fugly failsafes to make sure what I try to cure is curable.
Unknown2007-01-07 18:20:35
I use data record variables for tracking, more data record variables for mapping afflictions to cures (grouped by balance type, of course), and string lists for priorities (also grouped by balance type). If you use string lists for priorities, you can use %ismember to return the numerical position in the list as the priority number, rather than using whacked out names like 001stupidity.
Laysus2007-01-08 16:13:48
My way just has one record var for each balance type. Key = affliction, val = cure, and position in the list = priority, so rather than adding say, 001stupidity to it, it would add 001pen (pen=pennyroyal alias). Minimum of fussing that way, as it just has to sort the list and try them until it finds a valid one.
Unknown2007-01-08 19:52:10
QUOTE(Zarquan @ Jan 7 2007, 10:20 AM) 370297
I use data record variables for tracking, more data record variables for mapping afflictions to cures (grouped by balance type, of course), and string lists for priorities (also grouped by balance type). If you use string lists for priorities, you can use %ismember to return the numerical position in the list as the priority number, rather than using whacked out names like 001stupidity.
So one data record would be like @myafflictions which stores the afflictions that have been triggered, another would be @herbafflictions which store the names of affliction and the alias used to cure anything cured by herbs, @elixirafflictions, which is the same, only for elixers, and so on. Then the string lists would be like @herblist and @elixirlist and so forth. Am I getting this right?
Kharaen2007-01-08 20:59:33
I'd like to use queues, but all this is giving me a headache :/ I've no idea what anyone's talking about :/
Unknown2007-01-08 23:03:04
QUOTE(Kharaen d'Attai @ Jan 8 2007, 12:59 PM) 370680
I'd like to use queues, but all this is giving me a headache :/ I've no idea what anyone's talking about :/
I'm somewhat of a newb when it comes to scripting myself (maybe an advanced newb), but I think the basic idea behind a queue is this (note, this is greatyly simplified, I use @cancure to represent a series of checks to see if you are able to use curing items, which would be different depending on what the cure is):
#trigger {your afflicted with something} {#addkey afflictions something;curealias}
#alias curealias {#if @afflictions and @cancure {some code that will cure the first item on the @afflictions list;#if successful {#delitem afflictions thisaffliction;curealias}{#alarm curewait +1;curealias}}}}
like I said, very simplified, but I think that shows at least the basic logic behind the idea.
Maybe even more simple is to say that curealias checks to see if any items have been added to your affliction lists, checks to see if you are able to use the right items, if you can, use and delete the affliction from the list, and run curealias to find the next affliction; if you can't use the item, run curealias again after a wait period to try again.
One of the more advanced coders tell me if I have the basic idea right?
Laysus2007-01-08 23:20:04
kinda
the affliction message is triggered to add the thingy to the relative list
the cure message is triggered to remove it
and you have an alias in between that works out which one to cure.
It's actually very similar to a nested if statement with the exception that the nests aren't always there.
the affliction message is triggered to add the thingy to the relative list
the cure message is triggered to remove it
and you have an alias in between that works out which one to cure.
It's actually very similar to a nested if statement with the exception that the nests aren't always there.
Daganev2007-01-09 01:04:02
AFAIK the only difference between String lists, Data records, and Boolean checks is how you handle the variables that you are working with, and at what speed the client you are using can access those variables.
Booleans are normally the easiest for new people to work with, however booleans can mess you up in group combat, then Stringlists, however stringlists are the most likely to mess up your system. Data records, and databases are generally best but also the hardest to wrap your head around, and use/read.
Booleans are normally the easiest for new people to work with, however booleans can mess you up in group combat, then Stringlists, however stringlists are the most likely to mess up your system. Data records, and databases are generally best but also the hardest to wrap your head around, and use/read.
Kharaen2007-01-09 05:40:39
Yeah, booleans I can do and understand the term.
But I don't understand any of the other terms. Maybe an example of each type could be put here?
But I don't understand any of the other terms. Maybe an example of each type could be put here?
Unknown2007-01-09 12:26:42
My system is designed to make it fairly simple to add new afflictions, mostly because that makes it easy for me to maintain. First, I have a data record variable for each balance type that holds the relevant cure information:
... and so on.
Then, I have a priority string list for each balance type, and each affliction's position on the string list is automatically it's priority value. If it's not on one of these lists, the system completely doesn't try to cure it, which means it's dynamically adjustable through aliases, triggers, etc.
Now, you need triggers to track afflictions being added or removed. First, let me explain the aliases to add/remove afflictions. My i_aff alias not only adds a single affliction to the data record variable, it can add a list of afflictions in a single call. I have the option of passing in a last argument as the value for the affliction, where the default is 1 (meaning True), but I could use 2 to represent the number of broken arms, for example. Also, it checks the priority lists to see which queue should be checked on the prompt for the curing of the affliction(s). Finally, it tracks the afflictions in a special "keys" string list in the data record variable itself, making it easier for me to display my current afflictions without having to iterate through the list of keys in a loop. (For purposes of this post, I'll simplify it to just tracking a single affliction and leave the rest up to those that want to figure it out.)
The triggers are fairly simple.
The queue is executed on the prompt, which is also fairly simple.
The tricky part is in the i_scan_herb alias, where it determines the highest priority affliction and eats the appropriate cure. (This will be simplified a little for the purposes of illustration, of course.)
The i_herbcure is the real trick, and I'm quite proud of that particular alias. Basically, it loops over your current list of afflictions, which is hopefully a shorter list than the possible list of all herb-cured afflictions (meaning it's a tighter loop that executes faster). It compares the priority of each affliction found in the herb priority list and only remembers the affliction with the highest priority. At the end of the loop, either you have no herb-cured afflictions to report or you have the name of the highest priority one that can now be cured.
(Note: I cut out a LOT of the code I use in these aliases. This isn't a complete herb curing solution that you can just copy, paste, and use. You have to fill in the blanks when building your own stuff. There aren't any balance triggers, timer failsafes, or other miscellaneous goodies in this example.)
CODE
#VAR herb_cures {}
#ADDKEY herb_cures blindness myrtle
#ADDKEY herb_cures lost_ear marjoram
#ADDKEY herb_cures stupidity pennyroyal
#ADDKEY herb_cures blindness myrtle
#ADDKEY herb_cures lost_ear marjoram
#ADDKEY herb_cures stupidity pennyroyal
... and so on.
Then, I have a priority string list for each balance type, and each affliction's position on the string list is automatically it's priority value. If it's not on one of these lists, the system completely doesn't try to cure it, which means it's dynamically adjustable through aliases, triggers, etc.
CODE
#VAR herb_affs {stupidity|blindness|lost_ear}
Now, you need triggers to track afflictions being added or removed. First, let me explain the aliases to add/remove afflictions. My i_aff alias not only adds a single affliction to the data record variable, it can add a list of afflictions in a single call. I have the option of passing in a last argument as the value for the affliction, where the default is 1 (meaning True), but I could use 2 to represent the number of broken arms, for example. Also, it checks the priority lists to see which queue should be checked on the prompt for the curing of the affliction(s). Finally, it tracks the afflictions in a special "keys" string list in the data record variable itself, making it easier for me to display my current afflictions without having to iterate through the list of keys in a loop. (For purposes of this post, I'll simplify it to just tracking a single affliction and leave the rest up to those that want to figure it out.)
CODE
#ALIAS i_aff {#ADDKEY afflictions %1 1;#IF (%ismember(%1, @herb_affs)) {#ADDKEY scan herb 1}}
#ALIAS i_cure {#DELKEY afflictions %1}
#ALIAS i_cure {#DELKEY afflictions %1}
The triggers are fairly simple.
CODE
#TRIGGER {^Someone gave you stupidity!$} {i_aff stupidity}
#TRIGGER {^You cured stupidity!$} {i_cure stupidity}
#TRIGGER {^You cured stupidity!$} {i_cure stupidity}
The queue is executed on the prompt, which is also fairly simple.
CODE
#TRIGGER {^%dh, %dm} {#IF (%iskey(@scan, herb)) {i_scan_herb}} "" {nocr|prompt}
The tricky part is in the i_scan_herb alias, where it determines the highest priority affliction and eats the appropriate cure. (This will be simplified a little for the purposes of illustration, of course.)
CODE
#ALIAS i_herb {outr %1;eat %1}
#ALIAS i_herbcure {
  herb_priority = 100
  #LOOPDB @afflictions {
    herb_pos = %ismember(%key, @herb_affs)
    #IF (@herb_pos > 0 and @herb_pos < @herb_priority) {
      herb_priority = @herb_pos
    }
  }
  #IF (@herb_priority < 100) {
    i_herb %db(@herb_cures, %item(@herb_affs, @herb_priority))
  }
}
#ALIAS i_scan_herb {
  #IF (@able_scan) {
    #DELKEY scan herb
    #IF (!%iskey(@lost_bals, herb)) {i_herbcure}
  }
}
#ALIAS i_herbcure {
  herb_priority = 100
  #LOOPDB @afflictions {
    herb_pos = %ismember(%key, @herb_affs)
    #IF (@herb_pos > 0 and @herb_pos < @herb_priority) {
      herb_priority = @herb_pos
    }
  }
  #IF (@herb_priority < 100) {
    i_herb %db(@herb_cures, %item(@herb_affs, @herb_priority))
  }
}
#ALIAS i_scan_herb {
  #IF (@able_scan) {
    #DELKEY scan herb
    #IF (!%iskey(@lost_bals, herb)) {i_herbcure}
  }
}
The i_herbcure is the real trick, and I'm quite proud of that particular alias. Basically, it loops over your current list of afflictions, which is hopefully a shorter list than the possible list of all herb-cured afflictions (meaning it's a tighter loop that executes faster). It compares the priority of each affliction found in the herb priority list and only remembers the affliction with the highest priority. At the end of the loop, either you have no herb-cured afflictions to report or you have the name of the highest priority one that can now be cured.
(Note: I cut out a LOT of the code I use in these aliases. This isn't a complete herb curing solution that you can just copy, paste, and use. You have to fill in the blanks when building your own stuff. There aren't any balance triggers, timer failsafes, or other miscellaneous goodies in this example.)
Kharaen2007-01-09 16:40:54
Thanks for spending the time to show how to do each, I understand a bit better now!
Laysus2007-01-09 18:42:05
I will just say you should avoid having #loopdbs and #foralls firing on a regular basis. As far as I'm aware, those statements make up the slowest parts of my system.
Daganev2007-01-09 18:49:02
Datarecords = excel
Stringlists = word
Boolean = powerpoint?
Stringlists = word
Boolean = powerpoint?
Unknown2007-01-09 22:50:28
Ok, I just started building my own system last night. It's nothing so fancy as Zarquan's it kinda works like this (I don't have my zmud box in front of me, so it's not going to match what I'm doing quite right):
#alias {pennyroyal} {outr pennyroyal;eat pennyroyal}
#trigger {^You have stupidity now!$} {#addkey herbqueue stupidity pennyroyal}
#trigger{^You're not stupid anymore!$} {#delkey herbqueue stupidity}
#trigger {%dh, %dm} {herbcure}
#alias {herbcure} {#if $numitems(@herbqueue)>1 and @herbbalance=1 and @anorexia=0 and @stun=0 and @asleep=0 {#loopdb herbqueue {%val;#alarm herbalarm +2}}
The %val is the system variable to pass the value of a key, IE if the stupidity trigger fires, @herbqueue will contain the key of stupidity, and the value of pennyroyal, which when called by #loopdb activates the alias pennyroyal.
Problem is I haven't totally figured out priority yet, I might just adopt Zarquan's method though.
CODE
#alias {pennyroyal} {outr pennyroyal;eat pennyroyal}
#trigger {^You have stupidity now!$} {#addkey herbqueue stupidity pennyroyal}
#trigger{^You're not stupid anymore!$} {#delkey herbqueue stupidity}
#trigger {%dh, %dm} {herbcure}
#alias {herbcure} {#if $numitems(@herbqueue)>1 and @herbbalance=1 and @anorexia=0 and @stun=0 and @asleep=0 {#loopdb herbqueue {%val;#alarm herbalarm +2}}
The %val is the system variable to pass the value of a key, IE if the stupidity trigger fires, @herbqueue will contain the key of stupidity, and the value of pennyroyal, which when called by #loopdb activates the alias pennyroyal.
Problem is I haven't totally figured out priority yet, I might just adopt Zarquan's method though.