ID:159199
 
what would be the format for using a variable that is contained in a mob that is in a list? lets say i want to use the variable health and i want to use the value that a mob within a list has for the variable health. what would that look like?

or alternatively just point me in the direction of some more information on lists, the stuff in the guide and etc to me arent going to help me much more
Pretty much all I can point you to about learning lists is through the DM guide, which has a whole chapter for it.

What you would need to do is access that mob in the list and refer to it's health variable.

var/list/mob_lists[0]  //  declaring a list and initializing it

mob
Login()
..()
if(!(src in mob_lists)) // If the mob isn't in the mob list
mob_lists += src

Logout()
if(src in mob_lists) // If the mob is in the list
mob_lists -= src
..()


mob/verb/Random_Kill()
var/mob/M = pick(mob_lists) // pick a random mob
world << "[M.name] had [M.hp] life... now [M.name] is dead!

M.damage(M.hp, "GhostAnime", "[M.name] is an unlucky fella") // format: damage, name of killer, reason why/how the person died
I think what you wanna do is look up the vars list. Every atom has a built-in list, like overlays and underlays, called vars. And it holds all of the atom's variables (go figure).

mob/var
health = 10
stamina = 1
mob/verb/Hi_NPC(mob/M)
if(!M) return
var/list/L = list("health","stamina")
for(var/v in L)
src<<"[M.vars[v]] - [M.vars[L[v]]]"


That should display...
health - 10
stamina - 1

...in your default output element :)

I hope that helps! ^-^
In response to Spunky_Girl
thanks for the posts, it kind of helps, i think i get the idea of how it works, but i just dont get how to apply that to get it to work, im getting errors for undefined variables (a common problem for me)

mob
var
race
selected = 0
select = 0
owner
admin = 0
inventory[0]
equipped[0]
list
L
name
health
mhealth
energy
menergy
damage
strength
agility
dexterity
defense
level
exp
expn
player
icon = 'player.dmi'
density = 0
var/mob/M in L
Stat()
statpanel("Stats")
stat("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
stat(v.name)
stat("Level: ",v.level)
stat("Experience: %",(v.exp/(level*100))*100)
stat("Health: %",(v.mhealth/health)*100)
stat("Energy: %",(v.menergy/energy)*100)
stat("Damage: ",v.damage)
stat("Strength: ",v.strength)
stat("Agility: ",v.agility)
stat("Dexterity: ",v.dexterity)
stat("Defense: ",v.defense)
stat("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")


thats pretty much what im trying to do, ive got a list of units and i want it to display the stats of those units, their variables are stored in those units, so im trying to go through the list and and take all the variables of each unit and display them on the same panel but im having trouble fixing my errors because i dont really understand what is wrong

Universia.dm:12:error:name :duplicate definition (conflicts with built-in variable)
Universia.dm:28:error:L:unexpected 'in' expression
Universia.dm:32:error:v.name:undefined var

and an undefined var for each of those variables
In response to Netmanx
name is a built-in variable, so you cannot create a variable named "name" ("Name" is safe though ;p DM is case-sensitive).

Universia.dm:28:error:L:unexpected 'in' expression
You cannot define a variable like that. You need to make it equal value. In this case, variable M would become a copy of the list L.
var/mob/M = L


Universia.dm:32:error:v.name:undefined var
Since "v" is not a datum, any reference to any variables through that object will turn up as undefined. I recommend changing that to "src", unless you have different plans for that.
I think I see where the confusion is here. In some other languages, you'd just assign the variable via listName[incrementNumber].variable - but BYOND's list syntax doesn't work that way, no . after the [].

That was my lead sticking point. For anything else, the Guide, Reference, and Dream Maker help clarify list use. Practice makes perfect, and remember that the first entry here is 1, not 0 as it will be in many other languages.

It's not much of an inhibition once you get used to it. In fact, it helps make sure you've got the right types of things before you do anything to the contents of the list. In any object oriented language, it's a good idea to get into the habit of creating interfaces to make sure variables (list or otherwise) are manipulated correctly, for example:

proc/SetHitpoints(var/playerName,var/newHitpointsAmt)

// various checks to make sure the args are good

var/tmp/successful = 0

// world is a list of everything in the game, this for (in list) will only find var/mob/player/ types.
for (var/mob/player/thisPlayer in world)
if (thisPlayer.name == playerName)
thisPlayer.hitpoints = newHitpointsAmt
successful = 1
break // Stop running through the for list, I found who I was looking for

if (successful == 1)
return(1)
else
// some kind of debug message suggesting the player wasn't found
return(0)

(Even better, of course, would be if SetHitpoints() were on the player mobs themselves, which has a much different way of manipulating it, but this is an example of how to manipulate a list.)
In response to Geldonyetich
Sorry, but your snippet could use some improvement ^-^

1. Since you're looping through "players only", you should loop through the clients, not the entire world.

2. And since you're not returning anything specific, or the proc isn't being called in an if(), you have no need to return a true or false value. Letting it return the default is sufficient enough.

3. That "successful" var isn't needed either >_>

4. It can be made "universal" by using the built-in list vars

proc/SetHitpoints(n,v,x) //n=player's name, v=var name, x=changed value
if(!n || !v || !x) return //sanity check
for(var/client/C)
if("[C.mob]" == n)
C.mob.vars[v] = x
src<<"Success!"
return
src<<"Fail!"
return


Now, you can pass 3 arguments into that proc, to edit any variable you'd like on a player.
n - The name of the player's mob
v - The name of the variable, you'd like to edit
x - The new value of the variable you'd like to edit
In response to Spunky_Girl
Spunky_Girl wrote:
Sorry, but your snippet could use some improvement ^-^

Certainly - it's the only way I'll learn.

1. Since you're looping through "players only", you should loop through the clients, not the entire world.

Good idea, much more efficient.

2. And since you're not returning anything specific, or the proc isn't being called in an if(), you have no need to return a true or false value. Letting it return the default is sufficient enough.
3. That "successful" var isn't needed either >_>

Here I'd say it depends on the implementation. It could very well be that you'd like to get a true or false returned, and it's probably no more inefficient than not returning anything because this it will always at least return null. The successful var is certainly optional, but chances are if you called the proc you wanted it to do something, and that's a good warning that nothing happened.

I'm a paranoid coder, but I've found a little paranoia can be a good habit in coding.

4. It can be made "universal" by using the built-in list vars

Good stuff and an excellent demo of the vars list in action.

Would I do that? Again, it depends on an implementation.

The nice thing about a SetHitpoints interface is that you can make sure the variable is being set under very specific circumstances pertaining to how you want hitpoints to be handled. Additional code could be added to make sure that the hitpoints assigned is a number, and that it does not exceed the maximum possible hitpoints for the character class, for example.

If you go for a completely universal proc to do all your reassigning, you abandon the security of dedicated handlers. It is a lot less work, but it can bite you later: if you set your hitpoints to some obscene value because you made a mistake when coding, the code won't stop you, and you're left with precious little clues where you put the faulty call in your code.
In response to Spunky_Girl
thanks, that fixed the errors i was getting before, only have a little problem with a line

mob
var
list
L
player
icon = 'player.dmi'
density = 0
var/mob/M = L


Universia.dm:28:error:L:invalid variable
Universia.dm:28:error:= :expected a constant expression

just those two errors after i changed the var/mob/M = L line
In response to Netmanx
for(var/mob/M in L)



Is this right?
In response to Geldonyetich
Geldonyetich wrote:
The nice thing about a SetHitpoints interface is that you can make sure the variable is being set under very specific circumstances pertaining to how you want hitpoints to be handled. Additional code could be added to make sure that the hitpoints assigned is a number, and that it does not exceed the maximum possible hitpoints for the character class, for example.

Yeah, that's good common sense and why you shouldn't set a lot of vars directly but leave it to dedicated functions which overall make your life easier. But for this reason exactly I would make a very straightforward mob/proc/SetHP() (or similar), I'm not sure why you've decided to post a global proc (less flexible/object-oriented), especially one that only takes the name, but you might have had a good reason.
(EDIT: Also, it probably wouldn't hurt to mention that, for similar reasons, you should refrain from just setting loc or x,y,z directly when moving an object, because Move() does more than just that. So when moving stuff, either use Move() or a similar proc of your own.)
In response to Kaioken
Kaioken wrote:
I'm not sure why you've decided to post a global proc (less flexible/object-oriented), especially one that only takes the name, but you might have had a good reason.

Not really a good reason, but (as I mentioned in parenthesis at the bottom of the message I had that code) I was just making an example of how to use a list.
In response to Geldonyetich
Well, it was more precisely an example of how to loop through a list (not so much what the OP initially requested), but alright. I was just posting that just in case, anyway. =)
In response to Amjh
maybe, im gettting indintation errors

    player
icon = 'player.dmi'
density = 0
for (var/mob/M = L)
Stat()
statpanel("Stats")
stat("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
stat(src.Name)
stat("Level: ",src.level)
stat("Experience: %",(src.exp/(level*100))*100)
stat("Health: %",(src.mhealth/health)*100)
stat("Energy: %",(src.menergy/energy)*100)
stat("Damage: ",src.damage)
stat("Strength: ",src.strength)
stat("Agility: ",src.agility)
stat("Dexterity: ",src.dexterity)
stat("Defense: ",src.defense)
stat("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")


Universia.dm:29:error::empty type name (indentation error?)
Universia.dm:28:error::empty type name (indentation error?)

ive also tried indenting the entire stat panels portion but made no difference
In response to Netmanx
Delete that for() loop >_>
In response to Netmanx
    player
icon = 'player.dmi'
density = 0
Stat()
statpanel("Stats")
for (var/mob/M in L)
stat("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")
stat(M.Name)
stat("Level: ",M.level)
stat("Experience: %",(M.exp/(level*100))*100)
stat("Health: %",(M.mhealth/health)*100)
stat("Energy: %",(M.menergy/energy)*100)
stat("Damage: ",M.damage)
stat("Strength: ",M.strength)
stat("Agility: ",M.agility)
stat("Dexterity: ",M.dexterity)
stat("Defense: ",M.defense)
stat("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~")


Does this work?
In response to Amjh
No, remove the damn for(), it's good for nothing. Make it a seperate proc, would increase effectiveness.
In response to Mysame
Mysame wrote:
No, remove the damn for(), it's good for nothing.


Netmanx wrote:
...ive got a list of units and i want it to display the stats of those units, their variables are stored in those units, so im trying to go through the list and and take all the variables of each unit and display them on the same panel...



In response to Amjh
Uhhh...no response for the loss? >_>
In response to Amjh
this piece gives me

Universia.dm:30:M :warning: variable defined but not used
Page: 1 2