ID:272961
 
Code:
Fireball()
if(src.mp <4)
world<<"[src] casts Fireball...but [src] does not have enough MP!"
return
var/list/monsters=list()
for(var/mob/Monster/b in oview(5))
if(b.team!=src.team) monsters += b
var/mob/target =input("Which would you like to cast Fireball on?") in monsters
world<<"[src] casts Fireball on [target]"
src.overlays +='Cast.dmi'
sleep(30)
src.overlays -='Cast.dmi'
src.mp -=4
var/damage =src.magic -target.magic
target.overlays +='Fireball.dmi'
world<<"[target] suffers [damage] points of damage!"
sleep(50)
target.overlays -='Fireball.dmi'
target.hp -=damage
world<<"[target] suffers [damage] points of damage!"
target.DeathCheck1(target)


Problem description: When I use the skill, there are a few problems. This is a monster game where you control monsters and give them commands to fight, so the actual player doesen't use the spells, only the NPC monsters do. Even when there are no targets, it still casts it anyway and I get one of those long red error things. Also, if I use a spell, and the monster dies before the spell is finished, I get another long red error message.

I'd like to know why it still casts the spell even when there are no targets available, and how to prevent it from casting when there are no targets. Also I'd like to know how to handle this procedure to work even if the mob thats being targeted gets killed.


Fireball()
if(src.mp <4)
world<<"[src] casts Fireball...but [src] does not have enough MP!"
return
var/list/monsters=list()
for(var/mob/Monster/b in oview(5))
if(b.team!=src.team) monsters += b
var/mob/target =input("Which would you like to cast Fireball on?") in monsters
if(target) //Not checking if there is actually a target to use it on!
world<<"[src] casts Fireball on [target]"
src.overlays +='Cast.dmi'
sleep(30)
src.overlays -='Cast.dmi'
src.mp -=4
var/damage =src.magic -target.magic
target.overlays +='Fireball.dmi'
world<<"[target] suffers [damage] points of damage!"
sleep(50)
target.overlays -='Fireball.dmi'
target.hp -=damage
world<<"[target] suffers [damage] points of damage!"
target.DeathCheck1(target)


That would fix your second problem.
Ninja_Roy wrote:
Also I'd like to know how to handle this procedure to work even if the mob thats being targeted gets killed.

Whenever you sleep() or spawn() or input(), it must be assumed that ANY external condition could have changed change, with the one exception being that src still exists (unless if you've changed it, in which case you're really silly or already know what you're doing). So, you need to re-check any conditions that may have been altered. Basically, this means repeatedly putting if(target in oview(src, 5)) after every sleep() and after the input(). This also implicitly covers the case that the target is deleted, because if it has, then it'd be null, which is never in oview().

Oh, while we're at it: change oview(5) to oview(src,5), otherwise it defaults to oview(usr,5), which from your description is very much not what you want.

Additionally, you seem to be calling your DeathCheck1() proc wrong. It should probably be target.DeathCheck1(src), unless you've written the proc itself very wrongly, in which case it should still be what I said but then you should fix the DeathCheck1() proc as well.

Also, on a very minor point: your first message has [src] in it twice... you should probably just change that second one to be \he, which will insert an appropriate pronoun instead. And I suppose saying "casts Fireball" when they do not actually cast Fireball is silly... shouldn't it be "tries to cast Fireball"?
In response to Oasiscircle (#1)
Thanks. That "if(target)" line did the trick. Also I had a problem where it wouldn't cast unless there were at least two targets, but now thats fixed too. Now I'll get the other part to work.

But the text isn't really important at this stage. I'm more concerned about having a working game. What good is grammar if the game has bugs and errors that ruins all the fun? Besides, the monsters won't have genders. It will save me from some extra work when I program monster breeding.
In response to Ninja_Roy (#3)
Code:
    Heal()
if(src.mp <4)
world<<"[src] casts Heal...but [src] does not have enough MP!"
return
var/list/monsters=list()
for(var/mob/Monster/t in oview(src,5))//search for all mobs within 5 spaces
if(t.team==src.team) monsters += t//if the mob is on the same team, add it
var/mob/target =input("Which would you like to heal") in monsters
if(target)
world<<"[src] casts Heal on [target]"
src.overlays +=new/obj/overlays/cast
sleep(30)
if(target)
src.overlays -=new/obj/overlays/cast
src.mp -=4
target.hp +=5
HPCheck1(target)
target.overlays +=new/obj/overlays/heal
sleep(50)
if(target)
target.overlays -=new/obj/overlays/heal


I have one more question. I'm wondering why the caster cant cast heal on himself, only his allies. It only works if the src has another monster on its team. Shouldn't it add itself to the list too?
In response to Ninja_Roy (#4)
Code:
Heal()
if(src.mp <4)
world<<"[src] casts Heal...but [src] does not have enough MP!"
return
var/list/monsters=list()
for(var/mob/Monster/t in oview(src,5))//search for all mobs within 5 spaces
if(t.team==src.team) monsters += t//if the mob is on the same team, add it
var/mob/target =input("Which would you like to heal") in monsters
if(!target) target=src
if(target)
world<<"[src] casts Heal on [target]"
src.overlays +=new/obj/overlays/cast
sleep(30)
if(target)
src.overlays -=new/obj/overlays/cast
src.mp -=4
target.hp +=5
HPCheck1(target)
target.overlays +=new/obj/overlays/heal
sleep(50)
if(target)
target.overlays -=new/obj/overlays/heal


I tried fixing it with (!target) target=src, but when there are two targets, I still never get a input box and it automatically heals the ally.
In response to Ninja_Roy (#4)
Because oview() excludes the center. Use view() instead.