ID:1874633
 
Code:
#define DamageText(target,damage) new/effect/damage(target.loc,target,damage)

effect
parent_type = /atom/movable
damage
maptext_width = 128
maptext_height = 16
mouse_opacity = 0
layer = EFFECT_LAYER

New(Loc,mob/ref,damage,mob/source)
..()
//loc = ref.loc
step_x = ref.step_x
step_y = ref.step_y
maptext = {"<span class="damage">[damage]</span>"}
pixel_x = -(128-ref.icon_width)/2

var/image/i1
var/image/i2
if(ismob(ref)&&ref.client)
i1 = new()
i1.override = 1
i1.maptext = {"<span class="incomingdamage">[damage]</span>"}
i1.loc = src
ref.client << i1
if(ismob(source)&&source.client)
i2 = new()
i2.override = 1
i2.maptext = {"<span class="outgoingdamage">[damage]</span>"}
i2.loc = src
source.client << i2

var/ox = rand(-16,16)
animate(src,pixel_x=pixel_x,pixel_y=0,alpha=255,time=0)
animate(pixel_x=pixel_x+ox*0.25,pixel_y=16,alpha=255,time=2.5)
animate(pixel_x=pixel_x+ox*0.5,pixel_y=32,alpha=196,time=2.5)
animate(pixel_x=pixel_x+ox,pixel_y=48,alpha=128,time=2.5)
animate(pixel_x=pixel_x+ox*2,pixel_y=64,alpha=0,time=2.5)
spawn(10)
loc = null
if(i1&&ref.client)
ref.client.images -= i1
if(i2&&source.client)
source.client.images -= i2


Problem description:

When I apply this animation to the damage object, the object disappears for several frames and then reappears. Something is going wrong with animate(), and I'm not sure what's causing it. Anyone got any tips before I bug report this one?
Does the object disappear or does the maptext on the object disappear?
The object actually doesn't appear at all for several frames after the object is initialized. I can't tell exactly how many frames it is, but it's at least 5.
I'm pretty sure what's going on is animate() isn't using the right appearance because there's an appearance change in the queue. Or worse yet, the object doesn't yet have a communicated appearance at the time of creation.
Is the commented out "loc = ref.loc" supposed to be there?

I'm trying to see what loc the images are set to, the effect's loc isn't being set and then the images are being set to be the effect which isn't really located anywhere?
If I comment out the animation() the object shows up correctly and at the correct time.

By default, the first argument of a new invocation assigns a location prior to New() being called. Meaning the loc is ref.loc prior to New() even being called.

This is definitely a BYOND bug. I'm just trying to call Lummox's attention to it before I put it in bug reports. If he says it's not behaving desirably, I'll be cross-posting this to the bug reports forum.

I first discovered this bug back in March, along with several others that seem to be linked to calling animate() on objects that have just been created during the same frame that animate() is called. I hadn't been able to fully reproduce it until just now, though.
Interestingly, if I take out alpha, it works like it should.

#define DamageText(target,damage) new/effect/damage(target.loc,target,damage)

effect
parent_type = /atom/movable
damage
maptext_width = 128
maptext_height = 16
mouse_opacity = 0
layer = EFFECT_LAYER

New(Loc,mob/ref,damage,mob/source)
..()
step_x = ref.step_x
step_y = ref.step_y
maptext = {"<span class="damage">[damage]</span>"}
pixel_x = -(128-ref.icon_width)/2

var/image/i1
var/image/i2
if(ismob(ref)&&ref.client)
i1 = new()
i1.override = 1
i1.maptext = {"<span class="incomingdamage">[damage]</span>"}
i1.loc = src
ref.client << i1
if(ismob(source)&&source.client)
i2 = new()
i2.override = 1
i2.maptext = {"<span class="outgoingdamage">[damage]</span>"}
i2.loc = src
source.client << i2

var/ox = rand(-16,16)
animate(src,pixel_x=pixel_x+ox*0.25,pixel_y=16,time=2.5)
animate(pixel_x=pixel_x+ox*0.5,pixel_y=32,time=2.5)
animate(pixel_x=pixel_x+ox,pixel_y=48,time=2.5)
animate(pixel_x=pixel_x+ox*2,pixel_y=64,time=2.5)
spawn(10)
loc = null
if(i1&&ref.client)
ref.client.images -= i1
if(i2&&source.client)
source.client.images -= i2
I just copy pasted the animate part into a verb and used it.

On first click, what you described happens.
On second click and forward it seems to work as expected.

I'm thinking it basically first displays alpha of 0 since it's the last state of the animation then it moves to display the actual animation. Unsure where that extra delay comes from.

Nice animation by the way, I love it.
Here's where it gets interesting.

The first step doesn't play:

animate(src,pixel_x=pixel_x+ox*0.25,pixel_y=16,alpha=255,time=2.5)
animate(pixel_x=pixel_x+ox*0.5,pixel_y=32,alpha=192,time=2.5)
animate(pixel_x=pixel_x+ox,pixel_y=48,alpha=128,time=2.5)
animate(pixel_x=pixel_x+ox*2,pixel_y=64,alpha=0,time=2.5)


animate(src,pixel_x=pixel_x+ox*0.25,pixel_y=16,time=2.5)
animate(pixel_x=pixel_x+ox*0.5,pixel_y=32,alpha=192,time=2.5)
animate(pixel_x=pixel_x+ox,pixel_y=48,alpha=128,time=2.5)
animate(pixel_x=pixel_x+ox*2,pixel_y=64,alpha=0,time=2.5)


The first step plays correctly:

animate(src,pixel_x=pixel_x+ox*0.25,pixel_y=16,alpha=254,time=2.5)
animate(pixel_x=pixel_x+ox*0.5,pixel_y=32,alpha=192,time=2.5)
animate(pixel_x=pixel_x+ox,pixel_y=48,alpha=128,time=2.5)
animate(pixel_x=pixel_x+ox*2,pixel_y=64,alpha=0,time=2.5)


animate(src,pixel_x=pixel_x+ox*0.25,pixel_y=16,time=2.5)
animate(pixel_x=pixel_x+ox*0.5,pixel_y=32,alpha=192,time=2.5)
animate(pixel_x=pixel_x+ox,pixel_y=48,alpha=128,time=2.5)
animate(pixel_x=pixel_x+ox*2,pixel_y=64,alpha=0,time=2.5)
animate(alpha=255,time=0)


alpha = 254
animate(src,pixel_x=pixel_x+ox*0.25,pixel_y=16,alpha=255,time=2.5)
animate(pixel_x=pixel_x+ox*0.5,pixel_y=32,alpha=192,time=2.5)
animate(pixel_x=pixel_x+ox,pixel_y=48,alpha=128,time=2.5)
animate(pixel_x=pixel_x+ox*2,pixel_y=64,alpha=0,time=2.5)


So, apparently an animate() step fails if the value of alpha in that step is equal to the current alpha of the object.
And it happens twice which is basically 2.5 + 2.5 which is the 5 you guessed, how neat.

I suppose you can just omit alpha=255 from the animate as a workaround. But yay problem found.
Actually, I just tried that. Omitting the alpha from the first step also causes the first step to fail to play.

Interestingly, it does work if the last step ends on an alpha of 255. This means that animate() is trying to treat non-looping animations as though they should loop by using values from the end of the animation as the initial state of the animation rather than the initial state of the object's current appearance.

This makes multi-step animated fades impossible with animate() without resorting to hacks.
In response to Ter13
I noticed the same thing awhile ago as well. I made a post about this a few days ago. Hopefully this bug gets fixed so that we can utilize animate() to make some awesome effects.
I noticed the same thing awhile ago as well. I made a post about this a few days ago. Hopefully this bug gets fixed so that we can utilize animate() to make some awesome effects.

Lummox already fixed it.
In response to Ter13
Alright cool, thanks for telling me.