ID:2130084
 
(See the best response by Nadrew.)
Code:
mob/var/tmp
Flame_Cooldown=0
mob/pyro/verb/Forest()
set category="Techniques"
set name="Flame Burst"
if(!usr.Flame_Cooldown)
if(usr.energy>200)
usr.energy-=200
usr.Flame_Cooldown = 1
usr<<"You begin expanding the untapped fire in your body..."
sleep(10)
view(5)<<"[usr.name]: Flame Burst!!!"
//var/damage = usr.edamage*1.25
var/obj/A = new/obj/Flame(usr.loc)
A.owner = usr
var/obj/B = new/obj/Flame(usr.loc)
B.owner = usr
var/obj/C = new/obj/Flame(usr.loc)
C.owner = usr
var/obj/D = new/obj/Flame(usr.loc)
D.owner = usr
var/obj/E = new/obj/Flame2(usr.loc)
E.owner = usr
var/obj/F = new/obj/Flame2(usr.loc)
F.owner = usr
var/obj/G = new/obj/Flame2(usr.loc)
G.owner = usr
var/obj/H = new/obj/Flame2(usr.loc)
H.owner = usr
//A.damage = damage
//B.damage = damage
//C.damage = damage
//D.damage = damage
//E.damage = damage
//F.damage = damage
//G.damage = damage
//H.damage = damage
A.dir = NORTHEAST
B.dir = NORTHWEST
C.dir = SOUTHEAST
D.dir = SOUTHWEST
E.dir = NORTH
F.dir = WEST
G.dir = EAST
H.dir = SOUTH
walk(A,A.dir)
walk(B,B.dir)
walk(C,C.dir)
walk(D,D.dir)
walk(E,E.dir)
walk(F,F.dir)
walk(G,G.dir)
walk(H,H.dir)
usr.move=0
sleep(5)
for(var/obj/Flame/T in world)
if(T.owner == usr)
walk(T,0)
T.density = 0
for(var/obj/Flame2/T in world)
if(T.owner == usr)
walk(T,0)
T.density = 0
sleep(60)
for(var/obj/Flame/T in world)
if(T.owner == usr)
del(T)
for(var/obj/Flame2/T in world)
if(T.owner == usr)
del(T)
for(var/obj/FlameTrail/T in world)
if(T.owner == usr)
del(T)
for(var/obj/FlameTrail2/T in world)
if(T.owner == usr)
del(T)
sleep(300)
usr<<"<b>You can now use Flame Burst again!</b>"
usr.Flame_Cooldown = 0

else
usr<<"Not enough energy! (Need 100)"

obj/Flame
icon = 'Flame.dmi'
layer = MOB_LAYER+1
density = 1
var/damage
New()
..()
pixel_y = rand(-5,5)
pixel_x = rand(-5,5)
// spawn(100)
// del(src)
Bump(A)
if(ismob(A))
var/mob/M = A
var/mob/O = src.owner
src.damage = O.edamage*1.5 - M.edefense
M.power-=src.damage
M.wound+=rand(2,5)
view(6,M)<<"<font color=red>[M] was hit by [O.name]'s Fire Blast for [src.damage] Damage!"
M.kocheck()
if(istype(A,/turf/))
var/turf/M = A
src.loc=M.loc
del(src)
if(istype(A,/obj/))
var/obj/M = A
src.loc=M.loc
Move()
var/mob/O = src.owner
var/C = new/obj/FlameTrail(src.loc)
C:dir = src.dir
C:owner = O
var/C2 = new/obj/FlameTrail2(src.loc)
C2:dir = src.dir
C2:owner = O
..()
var/A = new/obj/Flame2(src.loc)
var/B = new/obj/Flame2(src.loc)
A:owner=O
B:owner=O
A:damage = src.damage
B:damage = src.damage
if(src.dir==NORTHEAST)
A:dir = NORTH
B:dir = EAST
if(src.dir==SOUTHEAST)
A:dir = EAST
B:dir = SOUTH
if(src.dir==NORTHWEST)
A:dir = NORTH
B:dir = WEST
if(src.dir==SOUTHWEST)
A:dir = SOUTH
B:dir = WEST
walk(A,A:dir)
walk(B,B:dir)

obj/Flame2
icon = 'Flame.dmi'
layer = MOB_LAYER-1
density = 1
var/damage
New()
..()
pixel_y = rand(-5,5)
pixel_x = rand(-5,5)
// spawn(100)
// del(src)
Bump(A)
if(ismob(A))
var/mob/M = A
var/mob/O = src.owner
src.loc=M.loc
src.damage = O.edamage*1.2 - M.edefense
M.power -= damage
M.kocheck()
if(istype(A,/turf/))
var/turf/M = A
src.loc=M.loc
del(src)
if(istype(A,/obj/))
var/obj/M = A
src.loc=M.loc
Move()
var/mob/O = src.owner
var/C = new/obj/FlameTrail(src.loc)
C:dir = src.dir
C:owner = O
var/C2 = new/obj/FlameTrail2(src.loc)
C2:dir = src.dir
C2:owner = O
..()

obj
FlameTrail2
icon = 'Flame.dmi'
layer = MOB_LAYER-1
New()
..()
pixel_y = rand(-5,5)
pixel_x = rand(-5,5)

obj
FlameTrail
icon = 'Flame.dmi'
layer = MOB_LAYER+1
New()
..()
pixel_y = rand(-5,5)
pixel_x = rand(-5,5)
// spawn(100)
// del(src)

//KO Check right here (yes I know I should use /mob/whatever type of monster it is but honestly it doesn't matter
mob
proc
deathcheck()
if(wound >= 100 && Dead == 0 && client)
view() << "[src] has fallen!"
power = maxpower
loc = (locate(12,9,2))
strength += 1
defense += 1
wound = 0
overlays += 'halo.dmi'
Dead = 1
else
return




mob
proc
kocheck()
if(src.power <= 0 && src.client)
view(6) << "<b>[src] has been knocked out!!</b>"
ko = 1
usr.overlays+='KO.dmi'
src.move_allowed=0
wound += 20
deathcheck()
sleep(50)
usr.overlays-='KO.dmi'
view(6) << "<b>[src] has woken up!!</b>"
src.ko = 0
src.move_allowed = 1
else
if(src.name=="Starter Demon" && src.power <= 0)
view()<<"<b><font color=red>[src] has been killed by [usr]!</font>"
GlobalRepopWithDelay()
/*line 65*/usr.exp += rand(15000,20000)
usr.Levelup()
if(usr.onquest)
usr.questkilled+=1
usr.questcomplete()
del(src)
if(src.name=="Hydra" && src.power <= 0)
view()<<"<b><font color=red>[src] has been killed by [usr]!</font>"
GlobalRepopWithDelay()
usr.exp += rand(50000,100000)
usr.Levelup()
if(usr.onquest2)
usr.questkilled+=1
usr.questcomplete()
del(src)


proc/GlobalRepopWithDelay()
spawn(1000)
world.Repop()


Problem description:
So I get this runtime error.
runtime error: Cannot read 0.exp
proc name: kocheck (/mob/proc/kocheck)
source file: battle.dm,65
usr: 0
src: Starter Demon (/mob/monster/demon)
src.loc: the dirt (39,101,2) (/turf/dirt)
call stack:
Starter Demon (/mob/monster/demon): kocheck()
Flame (/obj/Flame): Bump(Starter Demon (/mob/monster/demon))
Flame (/obj/Flame): Move(the dirt (39,101,2) (/turf/dirt), 9)

Any help would be appreciated thnx :)
Best response
You're gonna have to give some more details, like which line 65 is. From the looks of it, you're trying to use the number 0 instead of the letter O somewhere, but the code is pretty bad overall so I only skimmed.
In response to Nadrew
Well yeah I know the code is pretty bad I made this about 4-5 years ago as a test to improve my skill but I scrapped it and now I'm reviving it. For the record I didn't get any runtime error whenever I changed the kocheck in proc ro O.kocheck(M) but it wouldn't activate the KO check on the mob so :/

Edit: Oh yeah I forgot to tell you I updated line 65 which is where you gain exp from the kill.
You should be passing and using a reference to the attacker instead of relying on usr, which isn't exactly valid there, hence your errors. You cannot rely on usr to be the attacker in every instance.
In response to FKI
I already tried that and I got a whole bunch of errors both runtime and debugging which I didn't want to have to go through and learn to fix(yeah I'm lazy :) )
In response to Dragonpearl123
Dragonpearl123 wrote:
I already tried that and I got a whole bunch of errors both runtime and debugging which I didn't want to have to go through and learn to fix(yeah I'm lazy :) )

There is no big, red "fix it" button in life; take the time to fix your bad habits, or accept your poor results.
In response to FKI
Well bad habits can still lead to good results, I know I have bad habits but they have led me to results before I am just wondering how to fix the problem at hand I fully intend on solving my bad habits, however there are more than one ways to do things and because it isn't your way doesn't necessarily mean its bad(although this is pretty bad). Soo I am just trying to get results with these habits atm thanx :)
You've still done nothing to help us help you, the code you posted doesn't indicate where the issue is, just saying "it's on line [line]" isn't gonna do us much good, we're sure as heck not going to count the lines out.
In response to Nadrew
I updated it and put where line 65 was but incase you didn't see it
if(src.name=="Starter Demon" && src.power <= 0)
view()<<"<b><font color=red>[src] has been killed by [usr]!</font>"
GlobalRepopWithDelay()
/*line 65*/usr.exp += rand(15000,20000)
usr.Levelup()
if(usr.onquest)
usr.questkilled+=1
usr.questcomplete()
del(src)
In response to Dragonpearl123
Dragonpearl123 wrote:
Well bad habits can still lead to good results, I know I have bad habits but they have led me to results before I am just wondering how to fix the problem at hand I fully intend on solving my bad habits, however there are more than one ways to do things and because it isn't your way doesn't necessarily mean its bad(although this is pretty bad). Soo I am just trying to get results with these habits atm thanx :)

You asked about a runtime error, correct? I gave you the reason why it's happening. Do not misunderstand this at all.
Yep, definitely something you'd fix by passing references as FKI noted, the issue is that you're expecting 'usr' to be something it is not. In fact, usr is never safe to use in a proc, the only place it's really safe is in verbs and things like atom/Click().

In this case usr is being set to '0' somewhere, and thus giving you an error. Instead you should have an argument for the various procs that is passed through when you call said procs, then you reference that argument instead of usr.

If this is above your head, you don't really have enough of a grasp of the basics to help much, I recommend reading the DM guide and reference.
In response to Nadrew
OKAY ME AGAIN
SO I took your advice and changed usr to killer however I still get runtime errors but now it says that the value of killer is null. (The runtime error is null.exp line 79 which is the same line)
mob
proc
kocheck(killer)
var/mob/K
if(ismob(killer)) K=killer
if(src.power <= 0 && src.client)
view(6) << "<b>[src] has been knocked out!!</b>"
ko = 1
src.overlays+='KO.dmi'
src.move_allowed=0
wound += 20
deathcheck()
sleep(50)
src.overlays-='KO.dmi'
view(6) << "<b>[src] has woken up!!</b>"
src.ko = 0
src.move_allowed = 1
else
if(src.name=="Starter Demon" && src.power <= 0)
view()<<"<b><font color=red>[src] has been killed by [killer]!</font>"
GlobalRepopWithDelay()
K.exp += rand(15000,20000)
K.Levelup()
if(K.onquest)
K.questkilled+=1
K.questcomplete()
del(src)
if(src.name=="Hydra" && src.power <= 0)
view()<<"<b><font color=red>[src] has been killed by [killer]!</font>"
GlobalRepopWithDelay()
K.exp += rand(50000,100000)
K.Levelup()
if(K.onquest2)
K.questkilled+=1
K.questcomplete()
del(src)


proc/GlobalRepopWithDelay()
spawn(1000)
world.Repop()

I tried calling killer when I called the kocheck proc but killer isn't defined outside the kocheck proc. So I'm completely lost now.

P.S: Yes I see the Killer in the brackets that is supposed to be a K ill change it later :3

P.P.S: Please don't tell me this was the worst piece of coding you've ever seen its 2:30 am here and I had to just drag through this.
Well, how are you calling kocheck() now?
In response to Nadrew
Well you see I tried calling it M.kocheck(K), M.kocheck(killer) and M.kocheck() by itself the first two each give killer is an undefined var(Note: This only happens on objects that should bump and hurt user, when I call M.kocheck(usr) it works beautifully.) and the M.kocheck() gives runtime errors probably because I didn't call killer along with mob. Also even with the attack when I call M.kocheck(killer) it still says null.exp so killer is null :/.
Also whenever I set var/mob/K=usr that just brings me back to square 1. Where only the attack verb works but not projectiles.
The only call to kocheck() I see in your snippet should be passing O as the killer.

You should be reading the guide if you couldn't figure that bit out.

Also the K variable is unnecessary. Simply do this:

mob/proc/kocheck(mob/killer)
// ...
In response to FKI
I didn't really feel like typing Killer. in front of everything K was much simpler, and whenever I call M.kocheck(O) it doesn't kill the npc. That was the very first thing I tried, and for the attack verb I only use usr and src I don't have an owner. so I use M.kocheck(usr) which again puts me back in square one :c.
In Bump():

var/mob/O = src.owner
// ...
M.kocheck()


Every instance of kocheck() must be updated to fit the new criteria, passing the attacker in every case. In the case of this Bump(), the attacker is apparently O, the projectile's owner.

In turn, any thing related to this system also needs to be updated to not use usr. You can use usr in verbs and procs such as Click() without much worry (so your use of usr in the Forest() verb is not bad, but you could also use src to achieve the same thing and eliminate risk) -- anywhere else, it should be avoided less you want problems as seen here.