Curing

Post Reply
Rurik
Posts: 12
Joined: Thu Dec 16, 2010 8:21 pm

Curing

Post by Rurik »

I'm trying to write a script that will cure my affliction if my herbBAL = 1 and if herbBAL = 0 then add the affliction to a list of things that need to be cured.

So what I've done so far with no problems is curing the affliction if herbBAL = 1. But I don't know how to make a "list" of stuff to be cured. I don't even know if that's the easiest way to go about it or not. Any help or suggestions?

User avatar
Vadi
Posts: 5035
Joined: Sat Mar 14, 2009 3:13 pm

Re: Curing

Post by Vadi »

A good way to start would be to learn Lua tables, I suppose. That's one way you can store afflictions. That or make a variable for every single one and check them.

Iocun
Posts: 174
Joined: Wed Dec 02, 2009 1:45 am

Re: Curing

Post by Iocun »

Yeah. I'd say there are mostly three ways of storing your current afflictions:
- A table containing every affliction you currently have, e.g.:
{"stupidity", "anorexia", "recklessness"}
- A variable for every affliction that is either true or false, e.g.:
stupidity=true paralysis=false anorexia=true asleep=false etc.
- The same, but with all variables contained in a table, e.g.:
{stupidity=true, paralysis=false, anorexia=true, asleep=false, [etc.]}

Personally, I'd go with one of the table variants, since Lua is basically built around tables and works very nicely (and fast) with them. Plus, tables allow you to do things like looping through the entire set that you can't do with individual variables. I use the third variant, personally, with a true/false flag for every possible affliction within one table, but the first variant works just as well (with slightly different advantages and disadvantages).

But yeah, as Vadi said, I'd look up some Lua table tutorial. We could tell you here how to add a value to a table, but you'd soon come back asking the next thing about tables, so it might be better to simply look at the whole thing right now.

Rurik
Posts: 12
Joined: Thu Dec 16, 2010 8:21 pm

Re: Curing

Post by Rurik »

Okay. I've read through a few Lua tables tutorials and I've managed to create a table with the variable "t". It lists each affliction as either true or false like so: (please note that this is a system in the making, so I haven't listed every affliction there is yet)
t = {
["paralysis"] = false,
["stupidity"] = false,
["ablaze"] = false,
["prone"] = false,
["insomnia"] = false,
["brokenlimb"] = false,
["crippled"] = false,
["speed"] = false,
["confusion"] = false,
["paranoia"] = false,
["hallucination"] = false,
["hypersomnia"] = false,
["deadening"] = false,
["dizziness"] = false,
["impatience"] = false,
["recklessness"] = false,
["asthma"] = false,
["anorexia"] = false,
["dissonance"] = false,
["weakness"] = false,
["clumsiness"] = false,
["claustrophobia"] = false,
["vertigo"] = false,
["agoraphobia"] = false,
["masochism"] = false,
["lonliness"] = false,
["hellsight"] = false,
["addiction"] = false,
["nausea"] = false,
["haemophilia"] = false,
["peace"] = false,
}

Then on each affliction message I recieve, I set up a trigger to set the chosen item to true. For example, when a paralysis affliction occurs:
t.paralysis = true

So my big question is: How do I check this table for items set to "true" so I can cure them when my balance is restored?

User avatar
Jules
Posts: 118
Joined: Sun Oct 11, 2009 5:41 pm
Location: Plymouth State University - Sophomore

Re: Curing

Post by Jules »

What I would do instead is make two tables: one to hold your list of current afflictions, and another to hold the associated cures. You may even want a third, to hold the afflictions in the order that you want them to be cured; a queue, if you were.

Firstly, what I would do is create a function to iterate over the table of current afflictions. Next, iterate over the third table that holds the afflictions in the curing queue. Finally, check if the current affliction you have is equal to the affliction in the queue. If the current affliction doesn't equal the affliction in the queue, check the next current affliction. If none of the current afflictions equal, repeat the process for the next affliction in the queue. If by chance the current affliction equals the affliction in the queue, send the curing command found in the second table.

Make sense?

Rurik
Posts: 12
Joined: Thu Dec 16, 2010 8:21 pm

Re: Curing

Post by Rurik »

Okay. So I think I've figured out a way, even though it's probably not the most efficient. I created a table that lists every affliction = false. Then I made a function that goes through each affliction in the table and checks whether or not they're true. If true, cures the affliction. Then, once the proper balance is regained, it runs the function again.

I know this might not be exactly what you guys were telling me to do, but with my limited scripting knowledge, I found that this worked.

Oh, and is there an easy way to post the scripts I've made instead of copying them? I've seen others doing so.

User avatar
tsuujin
Posts: 695
Joined: Fri Feb 26, 2010 12:59 am
Location: California
Contact:

Re: Curing

Post by tsuujin »

I've never seen the point of storing every affliction. It's easier to just create a table. If you get the affliction, you add it to the table. If you lose the affliction, then you remove it from the table. This means that you're parsing through fewer entries every time you scan it.
Code: [show] | [select all] lua
affs = {}  -- Table created
affs["paralyzed"] = true  -- Affliction added
affs["paralyzed"] = nil  -- setting nil removes it from the table entirely

Iocun
Posts: 174
Joined: Wed Dec 02, 2009 1:45 am

Re: Curing

Post by Iocun »

Hm, yeah, that's actually what I do as well. Should have mentioned that instead of the true/false variant in my post. The advantage of using a table that already contains all afflictions set to false is merely that it can help yourself visually to see what afflictions you have accounted for etc. But performance-wise, the method tsuujin recommended is more efficient (not that it really matters much in Mudlet/Lua of course. Both should easily be fast enough).

I won't go into how exactly I do my curing, since that's too complex to cover quickly here, but I'll just mention the main tables I use:

All my curing system is stored in one big table called "paracelsus" (I like having a famous physician to look after my health :P). In this table I store all my variables, functions, etc. Then I have certain tables in that, particularly:

paracelsus.afflictions = {}

This one works exactly like tsuujin mentioned. I add afflictions by doing something like:
paracelsus.afflictions["stupidity"] = true
And remove them by doing:
paracelsus.afflictions["stupidity"] = nil

Then I have a table containing all cures. Here's an excerpt:
Code: [show] | [select all] lua
paracelsus.affliction_cures = {
	aeon = {{"smoke", "elm"}, {"tree"}},
	ablaze =	{{"apply", "mending"}, {"tree"}},
	addiction = {{"eat", "ginseng"}, {"tree"}},
	agoraphobia = {{"eat", "lobelia"}, {"focus"}, {"tree"}},
	anorexia =	{{"apply", "epidermal", "torso"}, {"focus"}, {"tree"}},
	asleep = {{"wake"}}
        [etc.]
	}
As you see, it's built in the following order: Every affliction is stored as a table item that is itself a table containing entries for every possible cure. Those cures are themselves -again- subtables, which is mostly for those cures that consist both of a cure type (such as "smoke", "eat", "apply") and one or two arguments ("elm", "ginseng", "epidermal, torso").

Third, I have a table containing all my cure types and their current status. Again an excerpt:
Code: [show] | [select all] lua
	paracelsus.cures =	{
	eat = {balance = true, tempbalance=true, processing=false, herb=nil},
	apply = {balance = true, tempbalance=true, processing=false, salve=nil},
	smoke = {queue={}},
	focus = {balance = true, tempbalance=true, processing=false},
	tree = {balance = true, tempbalance=true, processing=false},
	wake = {processing=false, executed = false},
	writhe = {balance = true, tempbalance=true, processing=false},
	compose = {processing=false}
        [etc.]
        }
These contain information on whether I have a certain balance, and other temporary balances etc. that are mostly used for failsafes etc. and are used internally by my system. (For instance, paracelsus.cures.eat.processing is set to true when my system sends an "eat" command to Achaea and is set to false again when either the eating fails for some reason, or when I get confirmation that it worked.)

Furthermore I have a table that contains all afflictions and a "value" assigned to them that designates how important it is to cure them. An excerpt:
Code: [show] | [select all] lua
paracelsus.valuetable = {
			aeon = 9.5,
			ablaze = 5,
			addiction = 6,
			agoraphobia = 6.7,
			anorexia = 9,
			asleep = 10,
			asthma = 9.1,
			blackout = 5,
			bound = 8,
			clumsiness = 7,
			}
This is rather specific to how my system works. The more "traditional" approach would be one, or several lists that simply list all afflictions in the order you wish to prioritize them.

There are various other variables/tables, but they're not so important for demonstrative purposes. As I said, I won't go into how my system actually selects a cure in a given circumstance, since that's somewhat complex. But the basic idea is always to first check what afflictions you -can- cure right now (based on the balances in my paracelsus.cures table, as well as on what other afflictions I have: I can't eat when I have anorexia, for instance). Then it's simply a task of finding the cure or group of cures that gives me the greatest benefit right now, out of the remaining cures.

User avatar
Jules
Posts: 118
Joined: Sun Oct 11, 2009 5:41 pm
Location: Plymouth State University - Sophomore

Re: Curing

Post by Jules »

Another option that you have in keeping afflictions ordered is to use the phpTable() function. By default, Lua does not keep the order in key/value tables, unless the key is a number. Therefor, you can cut down on the number of table you have by storing the cure balances in order, along with the afflictions in order, and each with their associated cure. Allow me to expand.

FIrst, make a new script called... PHPTable, or something like that. Here's the script:
Code: [show] | [select all] lua
function phpTable(...) -- abuse to: http://richard.warburton.it
  local newTable,keys,values={},{},{}
  newTable.pairs=function(self) -- pairs iterator
    local count=0
    return function() 
      count=count+1
      return keys[count],values[keys[count]]
    end
  end
  setmetatable(newTable,{
    __newindex=function(self,key,value)
      if not self[key] then table.insert(keys,key)
      elseif value==nil then -- Handle item delete
        local count=1
        while keys[count]~=key do count = count + 1 end
        table.remove(keys,count)
      end
      values[key]=value -- replace/create
    end,
    __index=function(self,key) return values[key] end
  })
  for x=1,table.getn(arg) do
    for k,v in pairs(arg[x]) do newTable[k]=v end
  end
  return newTable
end
Now, in order to make a table using the phpTable() function, you'd declare a table like this:
Code: [show] | [select all] lua
dragonfly.cures = phpTable()
  dragonfly.cures["purgative"] = phpTable()
    dragonfly.cures.purgative["aeon"] = "drink phlegmatic"
    dragonfly.cures.purgative["crotamine"] = "drink antidote"
    dragonfly.cures.purgative["dysentery"] = "drink choleric"
    dragonfly.cures.purgative["healthleech"] = "drink sanguine"
(Dragonfly is simply the new name for my system; going with the bug theme after Mantis)

Let's look through this. First, we designate the overarching table, cures, and make that a phpTable, which will automatically create a new table. Next, I put my purgative cures within that table, also another phpTable. And within the purgative table, I put in each affliction in that table, ordered in the way I want it cured, like so.

To iterate through that, you use phpTable()'s built in pairs() function, like so:
Code: [show] | [select all] lua
for balance in dragonfly.cures:pairs() do
  -- do stuff
end
Notice the ":pairs()" at the end. That function operates the exact same as the pairs iterative function that you should be used to right now.

If you decide to go with something like this, it will combine two or three tables into one large one, keeping all of the functionality: order the balances in the order you want them cured, order the afflictions in the order you want them cured, and keep all of the curing commands together based on affliction.

Post Reply