ID:1150976
 
Keywords: ai, death, proc, proper
(See the best response by Boubi.)
Problem description:
I had a a Death(mob/M) proc that would be called anytime someone damaged someone else. It would check to see whether someone died, or (if an enemy) fight the attacker.
/mob/proc/Death 50.251(self cpu)/ 53.936(total cpu)/ 6697.031(realtime)/ 13145(calls)
Is it normal for a Death proc to use that much cpu. If not, what is another way of letting npcs fight back players
Can you show the code snippet please.
It's a very long proc
mob
proc
Death(mob/M)
if(!src)
return
if(!M)
return
if(src.ispedal||src.safe||src.npc||src.story)
src.health = src.mhealth
src.wound=0
if(src.zab)
if(src.health<=0)
var/mob/G=src.owner
view(src)<<"[M] destroyed [G.swordname]!"
del src
if(src.enemy)
M.hollowprotection = 0
if(src.issmoke)
return
if(M.partner==src||src.partner==M)
return
if(M.myclone)
M=M.myclone
if(src.kawa)
M.Untarget()
var/obj/afterImage = new /obj()
afterImage.layer = MOB_LAYER
afterImage.icon=src.icon
afterImage.icon_state=src.icon_state
afterImage.overlays=src.overlays
afterImage.underlays = src.underlays
afterImage.dir=src.dir
afterImage.loc = src.loc
afterImage.zer = 1
afterImage.density=1
afterImage.overlays+=/obj/ko
for(var/mob/m in world)
if(m.etarget==src)
m.Untarget()
var/image/I=image('tgt.dmi',afterImage,"",30)
I.name="TargetUnder";src.client<<I
spawn(30) del(afterImage)
sleep(1)
src.x=src.kx
src.y=src.ky
src.z=src.kz
src.invisibility=30
src.see_invisible=30
spawn(30)
src.invisibility=0
src.see_invisible=0
if(src.protective)src.health+=round(src.mhealth/10,1)
if(src.health <= 0&&!src.ko||src.wound >= 200&&!src.ko)
M.cheapstuff=1
M.canattack=1
if(src.saved)
for(var/mob/H in oview(10))
if(H!=src&&H!=M)
var/mob/x1 = pick(H)
x1 = pick(H)
x1.loc=src.loc
step_away(src,x1)
src=x1
if(src.shopping)
src.frozen=0
for(var/obj/Buy/b in src.client.screen)
del b
if(M.shopping)
M.frozen=0
for(var/obj/Buy/d in M.client.screen)
del d
spawn()src.Aggro(M)
for(var/mob/Dr in M.clones)
spawn()Dr.Aggro(src)
for(var/mob/Dra in src.clones)
spawn()Dra.Aggro(M)
if(src.ressurectiontype=="Nnoitra"&&src.ressurection&&src.wound>=75)
src.Load_Overlays()
if(!src.overwound&&src.wound>=75)
src.overwound=1
src.Load_Overlays()
if(src.overwound&&src.wound<75)
src.overwound=0
src.Load_Overlays()
if(M.flashmelee)
if(src.loc!=null)
if(!src.safe)
M.loc=src.loc
M.moving=0
var/s=pick(NORTH,SOUTH,EAST,WEST,NORTHEAST,NORTHWEST,SOUTHEAST,SOUTHWEST)
step(M,s)
M.Facedir(src)
src.gothit=1
if(M.owner)
M=M.owner
if(src.mission==7&&M.missiontarget==src)
src.FailMish(view(20))
if(M.mission==12&&M.missiontarget==src)
M.timed=30
M<<"You got the item now hold onto it for 30 seconds without getting damaged"
if(src.mission==12&&src.timed)
src.FailMish(view(20))
if(M.inbankai&&M.stype=="Ikkaku")
M.rage+=1
if(src.health<=0&&src.wound<100)M.rage+=4
if(src.health<=0&&src.wound>100)M.rage+=9
if(M.inbankai&&M.stype=="Unohana"||M.ressurection&&M.ressurectiontype=="Del Toro")
if(src.health<0)
M.moving=0
if(!src.toochep&&src.health>0&&src.wound<200&&!src.aizentag)return
//actual death proc for wen each boss(14 bosses) is koed, killed, or kills a player
//also includes a ko system for players and and a respawn for when they die
//also includes killing players during events like ctf, they respawn in ctf not hosp
//also includes storyline for when player defeats a certain boss(4 types of those bosse)

I also have all /obj/projectiles/ that hit people go through Death() and an atk verb that Edit:Now only uses Death() under certain circumstances
                                    if(M.toochep||M.health<0||M.wound>200||M.aizentag)
M.Death(src)
Best response
I only started it for you, you have a lot of redundant things in there. You also need to compress code, split up certain checks instead of hauling it all under the Death() proc.

mob/var/list/clone_list = new

mob/proc/Death(var/mob/m)
if(!m || src.issmoke || m.partner == src || src.partner == m)
return

if(src.clone_list.len)
for(var/mob/a in src.clone_list) // delete all clones in your list
del(a)
src.clone_list.Cut() // remove all entries

// learn to compress all of your ifs() that do similar things
if(src.ressurectiontype == "Nnoitra" && src.ressurection && src.wound >= 75 || ...)
src.overwound = src.wound >= 75 ? 1 : 0
src.Load_Overlays()
Does more lines=more lag or is that not always true?
In response to Critical172
I don't think that more lines will cause extra lag, but it's the proper way to do it. Compressing it, that is.
As boubi says its alot easier to compress things like overlays or exp gains into another procedure and just call the procedure, its better for readability and for efficiency instead of writing those lines each time you wish to use them you can call the proc saves alot of time.
About your cpu issue, theres a few things it could be, how many loops you have constantly running, how bigs the map? These are issues i have had in the past on low specced pcs.
After I compressed it and combined similar things it used more CPU. At first it was using 12 cpu for 123 calls but after compressing it even further it's been using 14 cpu for 123 calls, so why would that be?