Overlays

by Forum_account
Overlays
An easy way to manage and manipulate overlays.
ID:221908
 
BYOND Version:493
Operating System:Windows 7 Ultimate
Web Browser:Chrome 16.0.912.77
Applies to:Property Procs
Status: Open

Issue hasn't been assigned a status value.
Descriptive Problem Summary:
Overlay visibility is not considered in the property procedures: Icon, IconState, PixelX, PixelY, PixelZ, Layer. Maybe not Flick.

Numbered Steps to Reproduce Problem:
1. Add the verbs below.
2. Run the game, click Hide Coat.
3. Click Red Coat.

Code Snippet (if applicable) to Reproduce Problem:
mob
verb
Hide_Coat()
coat.Hide()

Show_Coat()
coat.Show()


Expected Results:
The coat changes to the red coat, while remaining invisible.

Actual Results:
The coat appears.

Does the problem occur:
Every time? Or how often? Every time.
In other games? N/A
In other user accounts? Sure.
On other computers? Sure.

When does the problem NOT occur?
N/A

Did the problem NOT occur in any earlier versions? If so, what was the last version that worked? (Visit http://www.byond.com/download/build to download old versions for testing.)
N/a

Workarounds:
Fix it?

Man, bug reports forums need to not be exactly the same as the one for BYOND.
Easy enough to fix. Thanks for pointing this out.

I'm not sure how well this will work, but I'd like to add support for client-specific overlays. This would let you use the same /Overlay object to manage them but internally they'd be handled as images or overlays. This bug fix will be in the next update but it might take a few days.
I hope it won't complicate how to use the library. I'm using this in a game because it does what I normally do, in a more readable format.

I'm currently trying to figure out a bug that is probably my fault. A shield and sword are equipped, I flick both of them, but only the shield does the animation. I had to spawn the flicks because they sleep, but I don't think that's the problem. Anyway, it's probably nothing you need to care about.
In response to Kaiochao
Kaiochao wrote:
I hope it won't complicate how to use the library. I'm using this in a game because it does what I normally do, in a more readable format.

The bug fix or the image support?

I'm not sure if this will be sufficient, but my plan is to add two procs to the Overlay object: ShowTo() and HideFrom(). ShowTo() lets you add clients to a list of players who are the only ones allowed to see the overlay. HideFrom() removes clients from that list. If you never use these procs the library will always use overlays and won't behave any differently.

The benefit here is that you could easily create health meters over units:

mob.health_meter = overlay("10")
mob.health_meter.PixelY(-4)
mob.health_meter.ShowTo(mob.owner)

// to update it when their health changes:
mob.health_meter.IconState("[health]")


I'm currently trying to figure out a bug that is probably my fault. A shield and sword are equipped, I flick both of them, but only the shield does the animation. I had to spawn the flicks because they sleep, but I don't think that's the problem. Anyway, it's probably nothing you need to care about.

I haven't tried flicking two overlays at the same time so I wouldn't be surprised if this was a bug.

I just realized today that it might be confusing that the Flick proc sleeps. But, by having it sleep (instead of putting a spawn() inside of it) it gives you the option of putting spawn() before calling it (if that's the behavior you want).
The problem isn't multiple flicks. Somehow, while both the shield and sword have a "stab" state, even normal flick()ing the mob's "stab" state only shows the shield's animation. Calling IconState("stab") for the sword works, too.

// The sword and shield have their own reference
// to their /Overlay, yet the overlay is created
// for the mob and is displayed on the mob.
sword.overlay = src.overlay(sword.icon )
shield.overlay = src.overlay(shield.icon)

spawn sword.overlay.Flick( "stab", 4) // This doesn't happen
spawn shield.overlay.Flick("stab", 4) // This happens

sleep(4)

flick("stab", src) // The shield and the player are animated (not sword)

// This works, but it's not an acceptable workaround.
sword.overlay.IconState( "stab")
shield.overlay.IconState("stab")


I don't understand it.
Are the icon states directional?

I put a test case together and it seems to work for me. I noticed that some initialization might be missing the first time it's called. It creates the objects used to flick individual overlays the first time you call Flick, so their location and direction can be a little off. I wouldn't expect this to cause a lack of animation though.
The shield and sword are completely identical. How they are equipped, how/what they Flick(), their icon state name and length.

In a simple test case environment, everything works how it should.

After further testing, using sword.overlay.IconState("stab") actually takes 4 ticks (the duration of the state) before the animation even shows up (to loop).
sword.overlay.IconState("stab")
sleep(8) // First 4 ticks is uneventful. Second 4 ticks shows the animation.
sword.overlay.IconState("")


Could it be a BYOND bug?
In response to Kaiochao
Kaiochao wrote:
After further testing, using sword.overlay.IconState("stab") actually takes 4 ticks (the duration of the state) before the animation even shows up (to loop).
> sword.overlay.IconState("stab")
> sleep(8) // First 4 ticks is uneventful. Second 4 ticks shows the animation.
> sword.overlay.IconState("")
>


Could it be a BYOND bug?

I wouldn't be surprised.

Do the any of the animation frames have delays set? Is the game's framerate different from default?

Are the animations in the same icon file? I don't know why this would make a difference but in my test case they weren't.
There are two frames, both with a 0.2 second delay. 4-directional.
The FPS is 30.
The animations are in different icon files.
I was thinking it could be a bug with rounding frame delays to match the framerate, but it doesn't sound like that's the problem.

If this is a BYOND bug there should be a much more direct way to reproduce the glitch. If you don't mind sending me a demo with this glitch I can try to figure out what's causing this too.
So far, I haven't been able to replicate it.

However, I have managed to find another (completely unrelated) glitch: the flicked overlays don't update their step_ position or direction. Pixel movers beware.
In response to Kaiochao
Kaiochao wrote:
However, I have managed to find another (completely unrelated) glitch: the flicked overlays don't update their step_ position or direction. Pixel movers beware.

I was thinking about adding an alternate mode to this library that replaces BYOND's built-in overlays entirely when you're using pixel movement. The only reason you really need to use BYOND's overlays is because of gliding when you use tile-based movement. When you're using pixel movement you can easily implement overlays yourself:

mob
var
list/my_overlays

Move()
. = ..()
if(.)
for(var/obj/o in my_overlays)
o.loc = loc
o.dir = dir
o.step_x = step_x
o.step_y = step_y

I almost have the update ready that includes support for client-specific overlays using image objects. The update will also include some bug fixes. I'm trying to figure out if there's a way to flick image objects but I'm pretty sure there isn't (I don't think they even show animations when the object they're attached to is flicked).
I've found the problem. The sword's Overlay was initialized with its icon_state set to something other than blank (a state that is no longer in the icon), and somehow that caused it to be glitched.

source

I'm guessing that client-specific "overlay" support will be a mix between Visibility Groups and that snippet (overlays will no longer use the built-in overlays list?). If that's the case, what happens to FLOAT_LAYER? I'd just have to change my layers a tiny bit.
I'm not sure what'll happen to things if I make a pixel movement compatible version of the library.

Currently, the client-specific overlay support doesn't use the overlays list (though I don't think I've tried to see what happens when you put an image object in the overlays list). I'm not sure what FLOAT_LAYER is or how it works, so I'm not sure what'd happen to it.
Oh, I always used images in overlays. They don't have their per-client function, they only serve as a pure overlay. I feel they might be easier to create than /objs since they serve no physical purpose, only visual. And less functional, as overlays.

FLOAT_LAYER is a special layer which only interacts with other overlays on a single object. Technically, any layer below 0 has this function, and still, the greater the number, the higher it's layer.