ID:2176094
 
Code:
var/list/stats = list("str", "dur", "res", "off", "def", "spd", "frc", "energy")
mob
verb
Train()
set waitfor = FALSE
set category = "Skills"
usr << output("You have attempted to train.","chat")
if(stopState())
return FALSE
if(state != STATE_TRAINING)
state = STATE_TRAINING
state2 = NULL_STATE
icon_state = "Training"
else
nullState()
training = FALSE
while(state == STATE_TRAINING)
if(energy <= 5)
training = FALSE
usr << output("You have run out of energy.","chat")
nullState()
else
usr << output("You are training and have [energy] energy.","chat")
training = TRUE
energy -= 5
var/stat = pick(stats)
if(stat == "energy")
maxEnergy += (maxEnergy / 100) * energyGain
else
// Add to other stat.
sleep(50)


Problem description:
Currently, I have the above code. I'd like a user's stat to be added to depending on which was picked from the list. How would I do so? Originally, I thought [stat] += 1 would work, but it does not.


Ignore the sloppy state code, I'll be changing that so that it just calls a proc (similar to Ter13's method) and changes based on passed variables.
The list items in stats would have to be named exactly the same as the mob's variables. Then the following would be an option:

vars[stat] += amount


The other way would involve associating the list items in stats with the actual var name of the stat and using that.

var/list/stats = list("energy" = "maxEnergy")

//...

vars[stats[stat]] += amount


Personally, I'd avoid both of these methods because they both involve using the vars list, which can be slow to access. A better option would be to organize mob stats using a list as opposed to using separate variables.
I would use a more object-oriented approach:
// I think "stat" sometimes collides with the stat() proc,
// so I'm calling this "skill_level" instead.
skill_level
var
name
value
maximum

New(Name, Value, Maximum = 1#INF)
name = Name
value = Value
maximum = Maximum

proc
Increase(Amount)
value = min(max(value + Amount, 0), maximum)

Decrease(Amount)
Increase(-Amount)

LevelUp()
Increase(1)

Spend(Amount)
if(value < Amount) return FALSE
Decrease(Amount)
return TRUE

// Instead of the value, on level up, the maximum changes.
energy
LevelUp()
maximum *= 1 + energyGain / 100 // simplified your math for you

mob
var
skill_level
str
dur
res
// ...
energy/energy

list/skill_levels

proc
// Call this during character creation or something
InitializeStats()
// "new" without the type uses the type of the variable, /skill_level
// change the 0's to your desired starting values
str = new ("str", 0)
dur = new ("dur", 0)
// ...

// energy is defined as a /skill_level/energy, so that's used here
// change the 10 to your desired starting maximum energy
energy = new ("energy", 0, 10)

skill_levels = list(str, dur, res, /* ... */)

Then, picking a random stat to increase looks like this:
if(energy.Spend(5))
src << "Training! [energy.value] energy left!"
var skill_level/skill_level = pick(skill_levels)
skill_level.LevelUp()
else
src << "Ran out of energy!"