Table handling issue

Posted by Dyron on Wed 06 Feb 2013 03:06 PM — 21 posts, 79,152 views.

#0

function doattack()
	
	local venom = {}
	local tarafflictions = { "slickness" }
	local i = 1
	
	local venom_priority = {
	"slickness",
	"asthma",
	"deaf_strip",
	"sensitivity",
	"powersap",
	"blindness",
	"relapsing",
	"clumsiness",
	}
	
	
	for k, v in ipairs(venom_priority) do
		if not tarafflictions[v] and i <= 1 then
			Note ( "Venom 1: " .. v )
			i = i + 1
		elseif not tarafflictions[v] and i >= 2 then
			Note ( "Venom 2: " .. v )
			i = i + 1
			break
		end
	end
end


Could anyone tell me how to make it so that when slickness
is present it avoids it and goes to the next venom in venom priority? I've got no clue why it keeps picking the slickness.
Amended on Wed 06 Feb 2013 09:32 PM by Nick Gammon
Australia Forum Administrator #1

if not tarafflictions[v]


It looks like you are trying to key into tarafflictions. However the table as you set it up has numeric keys.

eg.


tarafflictions = { "slickness" }
tprint (tarafflictions )


Gives:


1="slickness"


You probably want to use slickness as the key, and a non-nil value, eg.


tarafflictions = { slickness = true }
tprint (tarafflictions )


Result:


"slickness"=true
#2
tarafflictions will be a constantly changing array. I set slickess in for testing but it can have up to 10-15 things in it at one time. At that rate, I don't see how to make that part work. Also, how can I move tarafflictions out of that function and make the function load it in for processing?
Australia Forum Administrator #3
Any time you want to add something:


tarafflictions ["asthma" ] = true


To remove it:


tarafflictions ["asthma" ] = nil


Quote:

Also, how can I move tarafflictions out of that function and make the function load it in for processing?


Just declare it globally (not inside the function).
#4
I've tried that.. Declaring it globally would be outside the function putting something like:


tarafflictions = { "slickness" }
function doattack()
  if not tarafflictions[v] and i <= 1 then
    Note ( "Hey, I'm not here" )
  end
end


Problem is.. soon as I do that it says it's trying to access a nil value in tarafflictions.
Amended on Thu 07 Feb 2013 09:15 PM by Dyron
USA Global Moderator #5
Probably because v is nil in your new function.
Amended on Thu 07 Feb 2013 02:15 PM by Fiendish
#6
It's the same function, I was just doing a shortcut version of it. If the tarafflictions is local in the function it works fine.. if I move it out.. All of a sudden it doesn't work.
#7

tarafflictions = { "slickness" }

venoms_priority = {
	"slickness",
	"asthma",
	"deaf_strip",
	"sensitivity",
	"powersap",
	"blindness",
	"relapsing",
	"clumsiness",
}

function doattack(...) -- When I do this I can now see the tarafflictions global variable.
	
	for k, v in ipairs(venoms_priority) do
		if tarafflictions[v] == false then
			Note( "Venom 1: " .. v )
		end
	end
end


Was curious, is there anyway to do something like this? Basically, a simple check against the tarafflictions variable. If slickness is part of that variable I want to make a note saying Venom 1 is asthma.
Amended on Thu 07 Feb 2013 02:39 PM by Dyron
Australia Forum Administrator #8
Didn't I answer that before?

Anyway, post the whole thing, I'm confused about where these functions are.

Template:copying
For advice on how to copy aliases, timers or triggers from within MUSHclient, and paste them into a forum message, please see Copying XML.
Australia Forum Administrator #9
Quote:

Was curious, is there anyway to do something like this? Basically, a simple check against the tarafflictions variable.


Yes, of course. There are lots of healing systems around.

Read about Lua tables here:

http://www.gammon.com.au/forum/?id=6036
#10

tarafflictions = { "slickness" }

venoms_priority = {
	"slickness",
	"asthma",
	"deaf_strip",
	"sensitivity",
	"powersap",
	"blindness",
	"relapsing",
	"clumsiness",
}

function doattack(...) -- When I do this I can now see the tarafflictions global variable.
	
	for k, v in ipairs(venoms_priority) do
		if tarafflictions[v] == false then
			Note( "Venom 1: " .. v )
		end
	end
end


That is the whole function. Not sure what else you are wanting.

function doattack(...) will now let it see a global variable.
function doattack() will not.

As for the tables help guide. I don't see where the heck it says a simple way to do it without having a ton of code. In CMUD all I've got to do is the following:


variable tarafflictions = { slickness | asthma }

#forall @venom_priority {
  #if (!%ismember( %v, @tarafflictions)) {
    venom1 = %v
    #break
  }
}


According to LUA helps I've been reading table.contain should do the same.


for k, v in ipairs(venom_priority) do
  Note ( "Checking if " .. v .. " is in the table." )
    if not table.contains(tarafflictions, v) then
      Note ( "Venom would be: " .. v )		
    end
end

Amended on Thu 07 Feb 2013 09:14 PM by Dyron
Australia Forum Administrator #11
Well, how is the function called? All variables are global unless you put the word "local" in front of them. Making a function would not affect that.


		if tarafflictions[v] == false then


You haven't addressed what I said above. That will never be true.

In your table:


tarafflictions = { "slickness" }


You have one item.

Key = 1
Value = slickness

Thus 1 will never be equal to an affliction name.

You need to key by the affliction name.
#12
What I have copied/pasted is the WHOLE script file. It's just trying to make this one item.

tarafflictions - Is a variable storing all my targets afflictions. This variable will change at will by their curing.

venom_priority - Holds the order in which I want to be hitting with venoms.

The ONE(1) function doattack is trying to find the affliction I want to hit with. It's checking tarafflictions to see if the affliction is there. If it is not there, it will pick the first available affliction in venom_priority. If it is there, it will go to the next in the list.

tarafflictions needs to be a global variable due to many triggers will affect it in the future. If somebody cures slickness, I will then want to update tarafflictions to delete it from that list.


for k, v in ipairs(venoms_priority) do
  if tarafflictions[v] == false then
    Note( "Venom 1: " .. v )
  end
end


The v in tarafflictions should be looping through the venoms_priority variables, as far as I understand. So thus should be doing key by affliction..

Should first be tarafflictions[slickness] then tarafflictions[asthma] then tarafflictions[deaf_strip].. etc.. Am I understanding this wrong?
Amended on Thu 07 Feb 2013 10:41 PM by Dyron
USA #13
Let's do this step by step.

venoms_priority = {
"slickness",
"asthma",
"deaf_strip",
"sensitivity",
"powersap",
"blindness",
"relapsing",
"clumsiness",
}

Is creating a table named venoms_priority, with keys and values. The first key, as an example, is 1. The value is "slickness".

You're essentially doing this:

venoms_priority = {}
venoms_priority[1] = "slickness"
venoms_priority[2] = "asthma"

etc... the other table is the exact same.

tarafflictions = { "slickness" }

is the EXACT same result as
tarafflictions = {[1]="slickness"}

or

tarafflictions = {}
tarafflictions[1]= "slickness"


now let's step into the function.

for k, v in ipairs(venoms_priority) do

is initially setting k to 1 and v to 'slickness'.

Now your if statement.

if tarafflictions[v] == false then

is translating to...

if tarafflictions["slickness"] == false then

which, since all we have is tarafflictions[1], will return nil.

nil is not false. so what Nick is saying, is that you will ALWAYS get a false return. what he also said, 'tarafflictions = { slickness = true }' will cause this.

tarafflictions = {}
tarafflictions["slickness"]= true

which in the...

for k, v in ipairs(venoms_priority) do

will put k as "slickness" and v as true. next step!

if tarafflictions[v] == false then

will turn into...

if tarafflictions["slickness"] == false then

which evaluates to FALSE and will cause the function to step to the next affliction!
Amended on Fri 08 Feb 2013 02:05 AM by Fadedparadox
USA #14
Dyron said:


for k, v in ipairs(venoms_priority) do
  if tarafflictions[v] == false then
    Note( "Venom 1: " .. v )
  end
end


The v in tarafflictions should be looping through the venoms_priority variables, as far as I understand. So thus should be doing key by affliction..

Should first be tarafflictions[slickness] then tarafflictions[asthma] then tarafflictions[deaf_strip].. etc.. Am I understanding this wrong?

Not quite.

the V in 'venoms_priority' is used. when you use tarafflictions[v] in your if statement, you are looking for a KEY in tarafflictions with the same name as the VALUE in venoms_priority. The key you made is 1. The value is "slickness". What you need to do is change the tarafflictions table, as per Nick and my post above. It needs to have KEYs of the venom name, and VALUES of true.
Amended on Fri 08 Feb 2013 02:06 AM by Fadedparadox
USA #15
There is one last issue I didn't address. You have several options. The problem is that any missing key will evaluate to nil, not false. nil == false evaluates to false. Several options include...

1) Set taraaffliction to contain every affliction, set to false. Set them to true as you afflict, false as you know they're cured.

2) use NOT. NOT changes true to false and false to true. it also changes 'nil' to true. You would do that like so:

if tarafflictions[v] == false then

changed to:

if not tarafflictions[v] then

Either option works!
USA #16
This is just one possible result:

venom_priority = {
  "slickness",
  "asthma",
  "deaf_strip",
  "sensitivity",
  "powersap",
  "blindness",
  "relapsing",
  "clumsiness",
  }

tarafflictions = {}

tarafflictions.slickness = true



function doattack()

  for k, v in ipairs(venom_priority) do
    if not tarafflictions[v] then
      Note ( "Venom: " .. v )
      break
    end -- if
  end -- for

end -- func


Another possbility!


venom_priority = {
  "slickness",
  "asthma",
  "deaf_strip",
  "sensitivity",
  "powersap",
  "blindness",
  "relapsing",
  "clumsiness",
  }

tarafflictions = {}

for k, v in pairs(venom_priority) do
  tarafflictions[v] = false
end -- for


tarafflictions.slickness = true



function doattack()

  for k, v in ipairs(venom_priority) do
    if tarafflictions[v] == false then
      Note ( "Venom: " .. v )
      break
    end -- if
  end -- for

end -- func


In fact, you can put

for k, v in pairs(venom_priority) do
  tarafflictions[v] = false
end -- for

In a function to reset the table.

For the first example, you can reset it by simply doing:


tarafflictions = {}
Amended on Fri 08 Feb 2013 02:23 AM by Fadedparadox
#17
Thank you so much for the examples Fadedparadox. I at least understand more of what you are saying, As for your examples, I've tried them.. without the:

doattack(...)

It refuses to call the tarafflictions variable. How do I make it call that variable that's called globally?
USA #18
Dyron said:

Thank you so much for the examples Fadedparadox. I at least understand more of what you are saying, As for your examples, I've tried them.. without the:

doattack(...)

It refuses to call the tarafflictions variable. How do I make it call that variable that's called globally?


I'm not certain what you mean. tarafflictions is, in the example, global so can be called from within another function/etc, or globally.

Can you give an example of what will not work?
Australia Forum Administrator #19
Dyron said:

It refuses to call the tarafflictions variable. How do I make it call that variable that's called globally?


Your use of language is confusing me. You don't "call" variables. Are you saying the variable has a different value to what you expect?
#20
I got it figured out, thanks guys. Now on to the next problem of not being able to process gmcp.