Stat Bar Overlays

by DarkCampainger
Quickly add overlay stat bars for health, mana, experience--anything!
ID:1388979
 
So, as DarkCampainger asked, I am making this post.

My save system saves the overlays so when people relog they stay with 2 bars, the one they had previously saved and a new one (full). I believe it creates a new overlay everytime people Log in.

I have this on the mob/Login()
health_bar = new(src, 'DemoHealthBar.dmi', 14, "health", "maxhealth", pixel_y = -8)
mana_bar = new/bar_overlay/mana_bar(src)
src.updatebars()
..()

mob
proc
updatebars()
mana_bar.Update()
health_bar.Update()
spawn(10)
src.updatebars()


And I even tried to do mana_bar.Hide() / health_bar.Hide() on the mob/Logout() and mana_bar.Show() / health_bar.Show() on the Load.

Nothing seems to work, Hope you can Help me =) Thanks!
Hi NSBR,

Thanks for making a separate post. Can you show me where you're saving your mob? That's where you need to add the Hide()/Show().

Also, keep in mind that you'll have to wipe your savefile (or at least strip the overlays from it) to remove the old saved overlay before the fix will appear to work.
Thanks for the reply.

I added the Hide on the Logout() and the Show on the Load proc.

The end of My Logout():
mana_bar.Hide()
health_bar.Hide()
src.SaveK()
del(src)

My Save:
mob
proc
SaveK()
if(src.cansave)
var/savefile/F = new("players/[src.key].sav")
Ranking(src)
src.xco = x
src.yco = y
src.zco = z
F["last_x"] << x
F["lasy_y"] << y
F["last_z"] << z
src.V = src.verbs
Write(F)


And I also have an autosave...

mob
proc
AutoSave()
if(src.cansave)
src.SaveK()
spawn(600)
src.AutoSave()

My Load:
mob
proc
LoadPlayer()
if(fexists("player/[src.key].sav"))
var/savefile/F= new("players/[src.key].sav")
F["last_x"] >> x
F["last_y"] >> y
F["last_z"] >> z
Read(F)
src.cansave=1
src.Frozen = 0
health_bar.Show()
mana_bar.Show()
src<<"Welcome"
world<<"[src] Logged In!"
src.loaded=1
else
isr<<"You don`t have a save file!"

What Should I do? I dont get why it is creating a new one all the time
You said that I would have to strip the bars overlays from the save files... I have many of them T.T do you know the best way I could do this?
You're not hiding them for AutoSave(). You should just do it in your SaveK() proc, so you don't have to worry about what might call it:
mob/proc/SaveK()
// ...
mana_bar.Hide()
health_bar.Hide()
Write(F)
mana_bar.Show()
health_bar.Show()


You'd probably be better off not saving overlays at all, but that gets a little tricky.

To remove the previously saved overlays, you can do overlays.Cut() in your LoadPlayer() proc after the call to Read(F). Keep in mind that will remove all saved overlays.
hm but even after hiding them, after a relog, a new bar is still created above the last one. I think it might have something to do with the mob/Login() wich creates a new bar even do you already have one... You can see my login code in my first post here, what do you think?

Isnt there a way to remove just these overlays? Cause i have many people playing / that have saves on my game. Thanks as always.
Well, there's two parts to each bar. There's the /bar_overlay object that manages the bar, and the image overlay that it generates and adds to the player. If you marked the mana_bar and health_bar variables as tmp (as has been suggested, and shown in the demo), then the /bar_overlay objects shouldn't be being saved. What you are likely seeing is just the leftover overlay that has been loaded and resaved since the first time you forgot to hide the bars.

From a design standpoint, you should avoid saving overlays. Saved overlays are hard to manage, and bloat your savefiles. However, if you're just interested in a temporary fix to strip out the extra pair of stat bars and don't want to redesign your system, this hack should work:
proc/removeSavedOverlay(atom/A, iconName)
for(var/appearance in A.overlays)
if("[appearance:icon]" == "[iconName]")
A.overlays -= appearance

mob
proc
LoadPlayer()
if(fexists("player/[src.key].sav"))
var/savefile/F= new("players/[src.key].sav")
F["last_x"] >> x
F["last_y"] >> y
F["last_z"] >> z
Read(F)

// Temporary fix to remove old stat bar overlays
removeSavedOverlay(src, "DemoHealthBar.dmi")
removeSavedOverlay(src, "DemoManaBar.dmi")

src.cansave=1
src.Frozen = 0
src<<"Welcome"
world<<"[src] Logged In!"
src.loaded=1
else
src<<"You don't have a save file!"
So if I do this with the SaveK() proc you sent earlier all will work just fine?
Yes, then it won't save the overlays anymore. However, it won't fix the savefiles that already have the stray bars in them. For that, you can temporarily use the removeSavedOverlay() proc I posted above.
In response to DarkCampainger
I did just as you told me and Im having these runtime errors when the SaveK() proc is used on people:

runtime error: bar_overlay: owner for 'chakra/Mchakra' bar no longer exists!
proc name: Hide (/bar_overlay/proc/Hide)
source file: Stat Bar Overlays.dm,128
usr: null
src: /bar_overlay/mana_bar (/bar_overlay/mana_bar)
call stack:
/bar_overlay/mana_bar (/bar_overlay/mana_bar): Hide()
/bar_overlay/mana_bar (/bar_overlay/mana_bar): Show(12)

and

runtime error: Cannot execute null.Hide().
proc name: SaveK (/mob/proc/SaveK)

mob
proc
SaveK()
if(src.cansave)
var/savefile/F = new("players/[src.key].sav")
Ranking(src)
src.xco = x
src.yco = y
src.zco = z
F["last_x"] << x
F["last_y"] << y
F["last_z"] << z
src.V = src.verbs
mana_bar.Hide()
health_bar.Hide()
Write(F)
mana_bar.Show()
health_bar.Show()

mob
proc
LoadPlayer()
if(fexists("players/[src.key].sav"))
var/savefile/F = new("players/[src.key].sav")
F["last_x"] >> x
F["last_y"] >> y
F["last_z"] >> z
Read(F)
//////////////// Temporary fix to remove old stat bar overlays
removeSavedOverlay(src, "HealthBar.dmi")
removeSavedOverlay(src, "ManaBar.dmi")
/////////////////////////////////////////////////////////////
src.cansave=1
src.Frozen = 0
src.logincrap()
usr<<"Seja Bem Vindo!"
world<<"Info: <font color = yellow>[usr] logou no jogo"
src.loaded=1
else
usr<<"Você não tem um Save!"
The first error looks unrelated to saving. If a stat bar was shown with a timeout to automatically hide itself, and the player logged out, it would try to hide the bar and complain that the owner was missing. I just released version 0.5 of the library that should fix that, so thanks for reporting it.

The second error means that (some of?) your players don't have stat bars for some reason. Does it always throw that error, or only occasionally? You can throw an if()-check around them if it happens often:
                if(mana_bar) mana_bar.Hide()
if(health_bar) health_bar.Hide()
Write(F)
if(mana_bar) mana_bar.Show()
if(health_bar) health_bar.Show()
It solved my problem, thank you very much for replying me for so long and creating this awesome library! =) Keep up the Good Work!
New bug found... In this update even if your bar has a timeout, it wont time out...
In response to NSBR
Are you sure it's the update the broke it? The timeout seems to work fine in the demo. Are you getting any runtime errors? Can you show me how you're calling Show()?

I did find another bug with Show(), where it wouldn't work at all until after you had called Update() at least once. The fix for that is in version 0.6
I dont know if it is the update that broke it because I had mana_bar.Update() on the updatebars proc and just remove it for the timeout to work (and it didnt).
mob
proc
updatebars()
health_bar.Update()
spawn(10)
src.updatebars()

And I am calling the mana_bar.Update() only where people lose mana and the Bar never fade out...

Well my Show is juts like you posted

                if(mana_bar) mana_bar.Hide()
if(health_bar) health_bar.Hide()
Write(F)
if(mana_bar) mana_bar.Show()
if(health_bar) health_bar.Show()


Not having any runtime errors. Thanks as always.
What does your /bar_overlay/mana_bar type look like? Did you set its timeout variable like in the demo? Are you passing any arguments to mana_bar.Update()?
mob
var
tmp
bar_overlay
health_bar
mana_bar

bar_overlay
// You can also define a stat bar's properties directly in its own child type
mana_bar
// Uses the 'ManaBar.dmi' icon
icon = 'ManaBar.dmi'
// The icon_state names are prefixed with "Mana"
state_prefix = "Mana"
// It tracks the variable "mana" out of "mana_max"
var_stat = "chakra"
var_max = "Mchakra"
// Offset the pixel_y of the overlay by -16 pixels
pixel_y = -16
// We set the bar to "timeout" and auto-hide if it hasn't been updated in 12 ticks
timeout = 12

// We don't define the number of states (10), but instead let the system figure it out
// This is technically less efficient, but allows us to fiddle with the icons without
// having to update the definition for the stat bar all the time.


Not passing any arguments to mana_bar.Update()
I can't find anything that would explain the behavior you are seeing. Can you think of anything else that might be interacting with the mana bar?
Well I really dont know why this is happening. The Mana bar just dont seem to fade out even do Im not calling Update.

Maybe when you call Show() or Hide() it has the same effect then Update()... What do you think?
any idea of what might be happening?
No, nothing has come to mind. I fiddled around in the demo to see if I could recreate the issue by calling various combinations of Show, Hide, and Update... but no luck so far.
Page: 1 2