ID:151003
 
Darke Dungeon gives mobs a list called hands[] to keep track of what they have in each hand. (Some items have different affects depending on what item you have in the other hand.)

For some reason my code works perfectly when I grab one item, but when I grab a second item, I always get the following error:

type mismatch
proc name: use (/obj/item/hand/use)
source file: item.dm,62
usr: Shadowdarke (/mob/player/master)
src: the empty hand (/obj/item/hand)
call stack:
the empty hand (/obj/item/hand): use()
Shadowdarke (/mob/player/master): ActionCycle()
Shadowdarke (/mob/player/master): ActionCycle()

Here is the declaration of hands[]
mob
var
hands[] // list of things in the user's hands


Here is my code for hand.use(): (hand is an obj representing an empty hand)
use()
var/turf/T = get_step(usr, usr.dir)
var/X = null
if (T) X = T.contents[T.contents.len] // X is the topmost obj or mob in T
if (!X) // nothing in the target space
view() << "[usr] shakes \his fist."
return
if (ismob(X))
usr << "TODO: attack [X] with fist"
else if (istype(X,/obj/item))
var/obj/item/I = X
I.Move(usr)
if (usr.action == "left")
usr.left = I
else
usr.right = I
usr.hands += I

The line in bold is the one producing the error. Why would it produce a type mismatch the second time it is used, when it doesn't the first time?

usr.hands += I

The line in bold is the one producing the error. Why would it produce a type mismatch the second time it is used, when it doesn't the first time?

It must be the case that usr.hands is not initialized to an empty list. If it is null by default, then when you add ot it the first time, it just gets assigned to the value and the second time, it complains because you are trying to add an obj to an obj, or something like that.

To initialize a list to be empty (rather than null), you can declare it like this:

mob/var/hands[0]

But that will create an empty list on every single mob, so if only a small number of mobs are going to actually use this list, you might want to make it null by default and just check for that case before you add anything to it:

if(!hands) hands = list()
...
In response to Dan
On 6/6/01 8:15 pm Dan wrote:
To initialize a list to be empty (rather than null), you can declare it like this:

mob/var/hands[0]

You know, over the years everytime I try to use the [] syntax for lists, I end up with strange bugs. So I just stay away from it and explicity declare them in New().
In response to Dan
On 6/6/01 8:15 pm Dan wrote:
But that will create an empty list on every single mob, so if only a small number of mobs are going to actually use this list, you might want to make it null by default and just check for that case before you add anything to it:

You have a point. I realize now that this will be the third reference to the same object that a mob is carrying around and that is horribly inefficient.

I'm going to scrap the list altogether, replacing it with a hands() proc that will return the list of items in the mobs hands in the few cases that I need the list.
In response to Deadron

You know, over the years everytime I try to use the [] syntax for lists, I end up with strange bugs. So I just stay away from it and explicity declare them in New().

I have noticed a certain reluctance to use []. I use it exclusively and have had no problems for quite some time, so I think all of the bugs connected with it are history. I'm sorry you had bad experience in the past!

--Dan
In response to Dan
On 6/7/01 8:12 am Dan wrote:
I have noticed a certain reluctance to use []. I use it exclusively and have had no problems for quite some time, so I think all of the bugs connected with it are history. I'm sorry you had bad experience in the past!

Ultimately I don't really understand the model for this, so when strange things happened I didn't know if it was a bug in BYOND or in my brain. I'll probably just be a troglodyte and stick to explicitly declaring things, so I can understand what's going on...