ID:149368
 
I am adding poison to Infantry Wars, but the code won't work.
mob/verb/Fire_poison_gun(mob/M as mob in oview(20))
if (src.poisonbullets >= 1)
usr << "You shoot your poison gun at [M]"
oview() << "[usr] engages [M]!"
M << "You were poisoned!"
var/damage = 1
world << "[damage] damage!"
M:HP -= damage
M:DeathCheck()
src.poisonbullets -= 1
usr.Experience += 1
M:Experience()
M:poison = 1
M:PoisonCheck()
else
usr << "Not enough poison"

proc/PoisonCheck()
check
if (src.poison == 1)
var/damage = rand(5,10)
usr << "The poison does [damage] damage!"
usr.HP -= damage
var/resist = rand(1,25)
if (resist == 25)
usr.poison = 0
else
goto check
Drafonis wrote:
I am adding poison to Infantry Wars, but the code won't work.

Since you didn't tell us what's going wrong, I'll just have to take a guess.
The first thing I can suggest is to get rid of the : operator. It's a rare thing that you'd ever need it. Change your code however you have to, but don't use :. I've used it myself, but only in a situation where it's semi-sensible to do so.

proc/PoisonCheck()
check
if (src.poison == 1)
var/damage = rand(5,10)
usr << "The poison does [damage] damage!"
usr.HP -= damage
var/resist = rand(1,25)
if (resist == 25)
usr.poison = 0
else
goto check

This entire loop is a hopeless mess. You should reprogram it fron scratch. Here's a list of what's wrong:

  • You're using goto when clearly a while or do-while loop is more appropriate.
  • You use src.poison in one part, usr.poison in another. You've got usr littered all over the proc--get rid of it, because it's not part of a verb. Those should all be src.
  • You compare src.poison to 1; it's probably best to use if(poison), where the code is executed if it's non-zero. But better still would be while(poison), so you could get rid of the goto.
  • Your if(resist==25) bit could be simplified by just replacing it and the line before it with if(prob(4)); a 4% chance. (That poison will do a tremendous amount of damage before it neutralizes, you should realize; most people will probably always die from it.)
  • Your loop doesn't appear to do any sleeping, so it's not doing damage periodically but all in an instant. If that's what you really want, then you should eliminate the message sent every time about damage. Instead, set a var to 0, add damage to it each time, then print out the message of total damage after you leave the while loop. You should break out of the loop if the total damage is greater than the user's HP. (But if periodic damage was what you wanted, put a sleep() in there somewhere.)

    Lummox JR
In response to Lummox JR
Hey LummoxJR, this is a bit off the topic at hand, but i'd like to absolve some of my ignorance if you will :)

I was wondering, what's wrong with using the the operator : instead of . ?

I always have to use : because it won't ever point to variables in any object instances above the root entry point ( /mob /obj /turf ) for some odd reason.

What really makes using the : instead . so bad?

There's no sarcasm of any form in this post by the way, I'm just really wondering :)
In response to ShadowWolf
ShadowWolf wrote:
Hey LummoxJR, this is a bit off the topic at hand, but i'd like to absolve some of my ignorance if you will :)

I was wondering, what's wrong with using the the operator : instead of . ?

Aside from taking longer, it's not safe. It's a very good place for bugs to pop up in your game--if not immediately then later.

I always have to use : because it won't ever point to variables in any object instances above the root entry point ( /mob /obj /turf ) for some odd reason.

I'm not sure what you mean by that. By correctly defining your vars (putting them in the right root) and type casting, you shouldn't have any such problems.

What really makes using the : instead . so bad?

It's sloppy. Most of the time it indicates that bad decisions have been made and need to be fixed. The place I use it in Incursion is actually the result of a bad decision, too: I have a few obj types, disparate enough that I didn't think (at the time) they warranted giving them a common subclass, but they all have var/obj/section/parent and proc/GetTerr() (which returns the territory of the parent /obj/section). I use hascall() and : to find out if an object is the right type, and if so to call GetTerr(). As mistakes go there have been worse ones, so I've let it go. I may eventually get around to changing that.

In situations like yours, however, casting the var to another type is always better. For example:
turf/kablam
Entered(atom/movable/A)
if(ismob(A))
var/mob/M=A
if(M.client) M.BlowUp()

You could do all that with :, but it's not a great idea. Casting A over to a mob tells DM it's working with a more specific type.

Lummox JR
In response to Lummox JR
Ok, just so I understand it better ( The speed thing is really important to me because of all the procs & stuff going on at once ) here is a bit of sample code:

DoAttack(A as mob,D as mob)
if(rand(1,100) > D:Defense)
var/tmp/damage = 0
damage = round(rand(A:MinDmg,A:MaxDmg))
D:HitPoints -= damage
A << "<font color=#028F02>You hit [D] for [damage] damage"
D << "<font color=#028F02>[A] hit you for [damage] damage"
A:Experience += D:ExpHitWorth
else
A << "<font color=#028F02>You miss [D]"
D << "<font color=#028F02>[A] misses you"
return

Should probably be rewritten as:
DoAttack(A as mob,D as mob)
var/tmp/mob/Atk = A
var/tmp/mob/Def = D
..() with : replaced with .

( By the way, I use rand instead of prob because the prob thing wasn't giving me the results I wanted )

But anyways, that should be faster eh?
In response to ShadowWolf
ShadowWolf wrote:
Ok, just so I understand it better ( The speed thing is really important to me because of all the procs & stuff going on at once ) here is a bit of sample code:

DoAttack(A as mob,D as mob)
if(rand(1,100) > D:Defense)
var/tmp/damage = 0
damage = round(rand(A:MinDmg,A:MaxDmg))
D:HitPoints -= damage
A << "<font color=#028F02>You hit [D] for [damage] damage</font>"
D << "<font color=#028F02>[A] hit you for [damage] damage</font>"
A:Experience += D:ExpHitWorth
else
A << "<font color=#028F02>You miss [D]</font>"
D << "<font color=#028F02>[A] misses you</font>"
return

Should probably be rewritten as:
DoAttack(A as mob,D as mob)
var/tmp/mob/Atk = A
var/tmp/mob/Def = D
..() with : replaced with .

No, not at all. Because you can give A and D a type within the proc definition, you don't need to do casting in this case. Your use of "as mob" is out of place, and shouldn't be in there; it's used in verbs, and input(), and that's pretty much it. (You also forgot to close your <font> tags, as you'll see if you read your post. I think this is legal in DM's output but when you post such code on the forum you should either put it all in <DM> tags or else make sure you close all those tags.)
// notice this doesn't say "A as mob"
DoAttack(mob/A,mob/D)
if(rand(1,100) > D.Defense)
// you don't need var/tmp for a proc var
var/damage = round(rand(A.MinDmg,A.MaxDmg))
D.HitPoints = max(D.HitPoints-damage,0) // to avoid negative numbers
A << "<font color=#028F02>You hit [D] for [damage] damage.</font>"
D << "<font color=#028F02>[A] hit you for [damage] damage.</font>"
A.Experience += D.ExpHitWorth
else
A << "<font color=#028F02>You miss [D].</font>"
D << "<font color=#028F02>[A] misses you.</font>"
// return is redundant at the end of the proc,
// since you're not returning a value

The "mob/A" and "as mob" syntaxes aren't mutually exclusive, so for verbs where you'd actually be using "as mob", this would be a better way to go:
mob
verb/Private(mob/M as mob in world)
...

The "as mob" part tells it that for verb arguments, this should be restricted to mobs. mob/M tells the compiler to treat this as type /mob, so you can use any vars (like key) that belong to mobs.

Lummox JR