ID:1316811
 
(See the best response by DarkCampainger.)
Problem description:

So in my combat system, I have a Damage proc which is designed to handle various methods of damaging, whether it be through melee or ranged attacks. Now the damaging itself works, no matter the method. However, the combat text doesn't show up on ranged attacks when I test it for whatever reason. I have been scouring this code for the longest time trying to figure out why, but nothing is popping out to me.

Here is the code for a ranged energy attack:
//Blast Skill
obj/energy/blast

icon = 'Blast.dmi'
density = 1
var/mob/shooter
New(loc, S)
shooter = S

Bump(var/mob/obstacle)
if(istype(obstacle,/mob))
var/dmg = (((shooter.lf / shooter.baself) * shooter.spr)* (shooter.blastmast/100)) / ((obstacle.lf / obstacle.baself) * obstacle.end)
obstacle.Damage(dmg, obstacle, shooter, ranged = 1)
del(src)




mob/var
blastmast = 100

mob
verb
blast()
set name = "Blast"

//Eligibility Check
if(!busy && !immobilized && chi >= 2 && health > 0)

//Facing target
if(client && target)
src:Face_Target()
icon_state = "Energy Attack"
immobilized = 1

//Firing
var/obj/energy/blast/B = new(usr.loc,usr)
walk(B,usr.dir,0,30)

//Close up
spawn(1)
icon_state = ""; immobilized = 0


And then here is the extensive damage proc:
//Handles the damaging of mobs
Damage(D,var/mob/V,var/mob/A, ranged = null)

if(D<0)
D = 0

if(!V.blocking)
A.combo ++
if(A.combo < 3)
V.health -= D
Combat_Text("Hit",null,V)

if(A.combo >= 3 && A.combo < 10)
Combat_Text("Combo","+[A.combo]",A)
Combat_Text("Hit",null,V)
V.health -= (D + 0.1) * ((A.combo / 10) + 1)
if(A.kbchain && !ranged)
Knockback(V,A)
else if(prob(A.combo) && !ranged)
Knockback(V,A)

if(A.combo >= 10)
Combat_Text("Combo","Max",A)
Combat_Text("Hit",null,V)
V.health -= (D + 0.1) * 2

if(A.kbchain && !ranged)
Knockback(V,A)

else if(prob(A.combo *2) && !ranged)
Knockback(V,A)

V.Factor_LF()
A.Factor_LF()

if(V.health<= 0)
V.health= 0
if(istype(src, /mob/player))
if(istype(A,/mob/player))
A:Drop_Target()
spawn(1)
Die()
if(istype(src, /mob/npc))
if(istype(A,/mob/player))
A:Drop_Target()
spawn(1)
del(src)

if(V.blocking)
if(prob((V.dex/A.dex)*10)) //Gives a chance to counter based on dexterity
if(!ranged)
Combat_Text("Counter",null,V)
var/dmg = ((V.lf / V.baself) * V.str) / ((A.lf / A.baself) * A.end)
A.combo = 0
A.kbchain = 0
return Damage(dmg,A,V)

else
Combat_Text("Blocked",null,V)
A.combo = 0
A.kbchain = 0
return


And lastly, here is the proc that handles combat text itself:
Combat_Text(type,type2,person,time = 6)
var/image/CT = image('Combat Text.dmi',person,type)
var/image/CT2 = image('Combat Text.dmi',person,type2)
for(var/mob/player/M in view(40))
M.client.images+= CT
if(CT2.type)
M.client.images+= CT2
spawn(time)
del(CT)
if(CT2)
del(CT2)


I realize this is a rather large mess to sift through, but I've been looking for the reason for hours at this point. If anyone can see anything that might be causing this, I'd greatly appreciate if you can point it out. To reiterate, it still properly damages victims of this energy attack, but does not populate the combat text on the screen as a hit or block.

Best response
The only thing I see that might be causing your issue is that the view() call in Combat_Text() is implicitly using usr as its center. It would probably be better to use person:
for(var/mob/player/M in view(40, person))


If performance is a concern, you could probably also swap that view() with a hearers(), which only returns mobs.

Also, that if(CT2.type) doesn't do anything. You should only be creating CT2 if type2 is set, and then doing if(CT2) to add it (like you are for deleting it)

I'm kinda curious why you're using images at all, since it looks like you want to display them to everyone. You could just use overlays.
Ahhhhhh. Thank you. I recently changed the proc from a mob/proc to a global one, so I can't call on view() in that case. And hearers() does sound more appealing, thank you. I wasn't aware of that one.

Also, that (CT2.type)was somehow working, though I'm not entirely sure how at this point. I have however modified my Combat Text proc to look like such:

//Handles Combat Text
Combat_Text(type,type2,person,time = 6)
var/image/CT = image('Combat Text.dmi',person,type)
var/image/CT2
if(type2)
CT2 = image('Combat Text.dmi',person,type2)
for(var/mob/player/M in hearers(20,person))
M.client.images+= CT
if(CT2)
M.client.images+= CT2
spawn(time)
del(CT)
if(CT2)
del(CT2)


As for using images rather than overlays, I find the images to be a lot more dynamic. It has a really nice scrolling effect to it that I don't think I'd be able to achieve as well with overlays, and also overlays will have the same icon_state as the base icon I believe.

I really appreciate your help. ^ ^ Noob move on my part, but thanks for taking the time to look through it.