ID:154563
 
I am currently building a revolutionized skills system (never seen anyone do it yet) that will let you fish, cook, hunt, eat, drink, steal, catch, trap, etc., but Darkness tells me that using if statements to do it is not a very good way at all. What i mean is say, something like this;

if(usr.fire == 0)
usr << "You do not have a fire burining to cook."
if(usr.fire == 1)
usr << "You attempt to cook the food..."
if(usr.cookskill == 1)
var/cook = rand(1,5)
if(cook == 1)
usr << "You cooked the fish!"
usr.contents += new /obj/Fishcooked
if(cook == 2)
usr << "You failed to cook the fish!"
if(cook == 3)
usr << "You failed to cook the fish!"
if(cook == 4)
usr << "You failed to cook the fish!"
if(cook == 5)
usr << "You cooked the fish!"
usr.contents += new /obj/Fishcooked
if(usr.cookskill == 2)
var/cook = rand(1,2)
if(cook == 1)
usr << "You cooked the fish!"
usr.contents += new /obj/Fishcooked
if(cook == 2)
usr << "You failed to cook the fish..."
blah blah blah


as you can basically see, as the skill level goes higher, the random choices will get smaller, and better your choice of cooking the fish. im not using this exact system, but something like it, could you tell me, is this ok, to use if statements, because darkness says there is a better way but i do not know what that way is....?????/
darkness says there is a better way but i do not know what that way is....?????/

Well, one way to do it would be to roll against the user's current cookskill. Let's say the skill can range from 1 to 4 and the die roll can be 1 to 5, and rolling the skill value or less is a success:

verb/cook(obj/food/O as obj in usr)
if(!istype(O))
usr << "You can't cook that!"
return

if(rand(1, 5) <= usr.cookskill)
usr << "Success!"
else
usr << "Failure."
On 5/9/01 10:16 am FIREking wrote:
but Darkness tells me that using if statements to do it is not a very good way at all.

He's right. The way you have it, the computer does a lot of extra work needlessly evaluating if statements that it doesn't have to. For example, when your var "cook" is 1, your code still goes through and checks <nobr>if (cook == 2)</nobr>, <nobr>if (cook == 3)</nobr>, and so on. It doesn't need to.

The answer is the switch statement. It's actually very similar to what you already have, but instead of evaluating every single if, it jumps directly to the one that's relevant, skipping all the other ones (although to be honest, I don't know if BYOND does this internally). Here's the same thing rewritten with switch:

switch (usr.fire)
if (0)
usr << "You do not have a fire burining to cook."
if (1)
usr << "You attempt to cook the food..."
switch (usr.cookskill)
if (1)
var/cook = rand(1,5)
switch (cook)
if(1)
usr << "You cooked the fish!"
usr.contents += new /obj/Fishcooked
if(2)
usr << "You failed to cook the fish!"
if(3)
usr << "You failed to cook the fish!"
if(4)
usr << "You failed to cook the fish!"
if(5)
usr << "You cooked the fish!"
usr.contents += new /obj/Fishcooked
if(2)
var/cook = rand(1,2)
switch (cook)
if(1)
usr << "You cooked the fish!"
usr.contents += new /obj/Fishcooked
if(2)
usr << "You failed to cook the fish..."
blah blah blah

You can also use a well placed "else" statement to get rid of some of the redundant code in there, but I'll leave that as an exercise for the reader. ;-) Guy also had a good idea for a different way to implement the same basic effect, which may ultimately be better.
In response to Air Mapster
if(2)
usr << "You failed to cook the fish!"
if(3)
usr << "You failed to cook the fish!"
if(4)
usr << "You failed to cook the fish!"

Also, if memory serves, DM will let you handle this with a single case:

if(2 to 4)
In response to Air Mapster
thank you, your comment helped the most, thanks alot, ill try it as soon as i get home, im at school right now... =)
In response to Gughunter
On 5/9/01 10:49 am Gughunter wrote:
if(2)
usr << "You failed to cook the fish!"
if(3)
usr << "You failed to cook the fish!"
if(4)
usr << "You failed to cook the fish!"

Also, if memory serves, DM will let you handle this with a single case:

if(2 to 4)

Indeed you are correct! I haven't had a need for that kind of notation, so I wasn't aware of it. The reference says you can also do <nobr>if (1,5)</nobr> which I believe would be handy in FIREking's code as well. Cool.
In response to Air Mapster
thank you man, this code will help lots, and will save me some room