HUD Groups

by Forum_account
An easy way to manage screen objects.
ID:678618
 
Okay, so currently i have something set up to give me three stat boxes, and update your variables in them. If your stat boxes are showing they will stay visible, else they will be hidden. The problem is the ammount of work it has to go through for this. I wanted to know if there was a way to make it lag less, or if i should attempt to convert it to map_text? If so, how would i do the said path.

Backgrounds:
StatHud1
parent_type = /HudGroup
icon = 'chatboxicons.dmi'
layer = MOB_LAYER + 50
font = new /Font/TrebuchetMS()
var/width = 6
var/height = 14

var/width_limit
var
list/lines = list()
next_line =1
New(mob/m, line_count)
..(m)

add(2, 2,
icon_state = "center",
width = width,
height = height,
layer = MOB_LAYER + 59)
width_limit = (width*32)

for(var/tmp/i = 1 to line_count)

var/py = (line_count - i) * 16

lines += add(0, py)

add(-30, 2, "L", width = 1, height = height, layer = MOB_LAYER + 59)

add(2, -30, "B", width = width, height = 1, layer = MOB_LAYER + 59)

add(2,height*32+2, "T", width = width, height = 1, layer = MOB_LAYER + 59)

add(width*32+2, 2, "R", width = 1, height = height, layer = MOB_LAYER + 59)

add(-30, -30, "BL", layer = MOB_LAYER + 59)

add(width*32+2, -30, "BR", layer = MOB_LAYER + 59)

add(-30, height*32+2, "TL", layer = MOB_LAYER + 59)

add(width*32+2, height*32+2, "TR", layer = MOB_LAYER + 59)

pos(45, 40)

hide()

StatHud2
parent_type = /HudGroup
icon = 'chatboxicons.dmi'
layer = MOB_LAYER + 50
font = new /Font/TrebuchetMS()
var/width = 6
var/height = 14

var/width_limit
var
list/lines = list()
next_line =1
New(mob/m, line_count)
..(m)

add(2, 2,
icon_state = "center",
width = width,
height = height,
layer = MOB_LAYER + 59)
width_limit = (width*32)

for(var/tmp/i = 1 to line_count)

var/py = (line_count - i) * 16

lines += add(0, py)

add(-30, 2, "L", width = 1, height = height, layer = MOB_LAYER + 59)

add(2, -30, "B", width = width, height = 1, layer = MOB_LAYER + 59)

add(2,height*32+2, "T", width = width, height = 1, layer = MOB_LAYER + 59)

add(width*32+2, 2, "R", width = 1, height = height, layer = MOB_LAYER + 59)

add(-30, -30, "BL", layer = MOB_LAYER + 59)

add(width*32+2, -30, "BR", layer = MOB_LAYER + 59)

add(-30, height*32+2, "TL", layer = MOB_LAYER + 59)

add(width*32+2, height*32+2, "TR", layer = MOB_LAYER + 59)

pos(270, 40)

hide()

StatHud3
parent_type = /HudGroup
icon = 'chatboxicons.dmi'
layer = MOB_LAYER + 50
font = new /Font/TrebuchetMS()
var/width = 6
var/height = 14

var/width_limit
var
list/lines = list()
next_line =1
New(mob/m, line_count)
..(m)

add(2, 2,
icon_state = "center",
width = width,
height = height,
layer = MOB_LAYER + 59)
width_limit = (width*32)

for(var/tmp/i = 1 to line_count)

var/py = (line_count - i) * 16

lines += add(0, py)

add(-30, 2, "L", width = 1, height = height, layer = MOB_LAYER + 59)

add(2, -30, "B", width = width, height = 1, layer = MOB_LAYER + 59)

add(2,height*32+2, "T", width = width, height = 1, layer = MOB_LAYER + 59)

add(width*32+2, 2, "R", width = 1, height = height, layer = MOB_LAYER + 59)

add(-30, -30, "BL", layer = MOB_LAYER + 59)

add(width*32+2, -30, "BR", layer = MOB_LAYER + 59)

add(-30, height*32+2, "TL", layer = MOB_LAYER + 59)

add(width*32+2, height*32+2, "TR", layer = MOB_LAYER + 59)

pos(495, 40)

hide()


on-screen labels:
StatMessage
parent_type = /HudGroup
icon = 'inventory.dmi'
layer = MOB_LAYER + 60
font = new /Font/TrebuchetMS()
var
HudObject/StatCollumHeader
HudObject/StatHolder

HudObject/EquipmentAndSkillsCollumHeader
HudObject/EquipAndSkillHolder

HudObject/QuestAndInformationCollumHeader
HudObject/QuestAndInfoHolder

list/StatHolders = list()
New()
..()
var/message = font.wrap_text("Loading...", 180)
StatCollumHeader = add(115, 500, text = "Stats")
StatHolder = add(45, 490, text = message)
StatHolder.name = "StatHolder"

EquipmentAndSkillsCollumHeader = add(315, 500, text = "Skills And Equipment")
EquipAndSkillHolder = add(270, 490, text = message)
EquipAndSkillHolder.name = "EquipAndSkillHolder"

QuestAndInformationCollumHeader = add(550, 500, text = "Quest Information")
QuestAndInfoHolder = add(495, 490, text = message)
QuestAndInfoHolder.name = "QuestAndInfoHolder"


StatHolders += StatCollumHeader
StatHolders += StatHolder

StatHolders += EquipmentAndSkillsCollumHeader
StatHolders += EquipAndSkillHolder

StatHolders += QuestAndInformationCollumHeader
StatHolders += QuestAndInfoHolder


Update Procs:
mob/proc
StatHolderUpdate()
StatChanged = 0
for(var/HudObject/R in StatMsg.StatHolders)
var/tmp/message
if(R.name == "StatHolder")
var/tmp/messagename
var/tmp/messagelevel
var/tmp/messagehealth
var/tmp/messagemana
var/tmp/messagestamina
var/tmp/messageexp
if(src.name)
messagename = "Name: [src.name]"
else
messagename = "Error with name -- please contact an admin."
if(src.level >= 0)
messagelevel = "Level: [src.level]"
else
messagelevel = "Error with level -- please contact an admin."
if(src.health >= 0 && src.max_health >= 0)
messagehealth = "Health: [src.health]/[src.max_health]([(round(src.health/src.max_health*100,1))]%)"
else
messagehealth = "Error with health -- please contact an admin."
if(src.mana >= 0 && src.max_mana >= 0)
messagemana = "Mana: [src.mana]/[src.max_mana]([(round(src.mana/src.max_mana*100,1))]%)"
else
messagemana = "Error with mana -- please contact an admin."
if(src.stam >= 0 && src.max_stam >= 0)
messagestamina = "Stamina: [src.stam]/[src.max_stam]([(round(src.stam/src.max_stam*100,1))]%)"
else
messagestamina = "Error with stamina -- please contact an admin."
if(src.experience >= 0 && src.max_experience >= 0)
messageexp = "Experience: [src.experience]/[src.max_experience]([(round(src.experience/src.max_experience*100,1))]%)"
else
messageexp = "Error with experience -- please contact an admin."
message = Stat_display1.font.wrap_text(" " + messagename + "\n" + \
messagelevel + "\n" + messagehealth + \
"\n" + messagemana + "\n" + messagestamina + "\n" + messageexp, 180)
R.set_text(message)
if(!src.stat_open)
Part_hide(R)

EquipAndSkillholderUpdate()
EquipAndSkillholderChange = 0
for(var/HudObject/R in StatMsg.StatHolders)
var/tmp/message
if(R.name == "EquipAndSkillHolder")
var/tmp/msgmagic
var/tmp/msgunarmed
var/tmp/msgspeed
var/tmp/msgarmorrating
var/tmp/msghead
var/tmp/msgarmor
var/tmp/msghands
var/tmp/msglhand
var/tmp/msgrhand
var/tmp/msgboots
var/tmp/ItemName
if(src.magic >= 0 && src.magic_exp >= 0 && src.magic_max_exp >= 0)
msgmagic = "Magic Level: [src.magic]([(round(src.magic_exp/src.magic_max_exp*100,1))]%)"
else
msgmagic = "Error with magic -- Please contact an admin."
if(src.unarmed >= 0 && src.unarmed_exp >= 0 && src.unarmed_max_exp >= 0)
msgunarmed = "Unarmed Level: [src.unarmed]([(round(src.unarmed_exp/src.unarmed_max_exp*100,1))]%)"
else
msgunarmed = "Error with unarmed -- Please contact an admin."
if(src.speed >= 0 && src.speed_exp >= 0 && src.speed_max_exp >= 0)
msgspeed = "Speed Level: [src.speed]([(round(src.speed_exp/src.speed_max_exp*100,1))]%)"
else
msgspeed = "Error with speed -- Please contact an admin."
if(src.Armor_rating >= 0)
msgarmorrating = "Armor Rating: [src.Armor_rating]"
else
msgarmorrating = "Error with armor rating -- Please contact an admin."
ItemName = "Head"
if(!src.equipped[ItemName])
msghead = "Head: Nothing"
else if(src.equipped[ItemName])
msghead = "Head: [src.equipped[ItemName]]"
else
msghead = "Error with head equip -- Please contact an admin."
ItemName = "Armor"
if(!src.equipped[ItemName])
msgarmor = "Armor: Nothing"
else if(src.equipped[ItemName])
msgarmor = "Armor: [src.equipped[ItemName]]"
else
msgarmor = "Error with armor equip -- Please contact an admin."
ItemName = "Hands"
if(!src.equipped[ItemName])
msghands = "Hands: Nothing"
else if(src.equipped[ItemName])
msghands = "Hands: [src.equipped[ItemName]]"
else
msghands = "Error with hands equip -- Please contact an admin."
ItemName = "Lhand"
if(!src.equipped[ItemName])
msglhand = "Left Hand Equip: Nothing"
else if(src.equipped[ItemName])
msglhand = "Left Hand Equip: [src.equipped[ItemName]]"
else
msglhand = "Error with left hand equip -- Please contact an admin."
ItemName = "Rhand"
if(!src.equipped[ItemName])
msgrhand = "Right Hand Equip: Nothing"
else if(src.equipped[ItemName])
msgrhand = "Right Hand Equip: [src.equipped[ItemName]]"
else
msgrhand = "Error with right hand equip -- Please contact an admin."
ItemName = "Boots"
if(!src.equipped[ItemName])
msgboots = "Boots: Nothing"
else if(src.equipped[ItemName])
msgboots = "Boots: [src.equipped[ItemName]]"
else
msgboots = "Error with boots equip -- Please contact an admin."
message = Stat_display2.font.wrap_text(" " + msgmagic + "\n" + msgunarmed + "\n" + msgspeed + "\n" + msgarmorrating \
+ "\n" + msghead + "\n" + msgarmor + "\n" + msghands + "\n" + msglhand + "\n" + msgrhand + "\n" + \
msgboots, 180)
R.set_text(message)
if(!src.stat_open)
Part_hide(R)

QuestandInfoHolderUpdate()
QuestandIntoHolderChange = 0
for(var/HudObject/R in StatMsg.StatHolders)
var/tmp/message
if(R.name == "QuestAndInfoHolder")
var/tmp/msgquest
var/tmp/msgqueststanding
var/tmp/msgquestinformation
var/tmp/QuestPlace = "Quest"
var/tmp/QuestK = "QuestKills"
var/tmp/QuestNK = "NeededQuestKills"
if(!src.Quest[QuestPlace])
msgquest = "Quest: None"
else if(src.Quest[QuestPlace])
msgquest = "Quest: [src.Quest[QuestPlace]]"
else
msgquest = "Error with Quest -- Please contact an admin"
QuestPlace = "QuestStanding"
if(!src.Quest[QuestPlace])
msgqueststanding = "Quest Standing: No Quest Accepted"
else if(src.Quest[QuestPlace])
if(Quest[QuestK] && Quest[QuestNK])
Quest[QuestPlace] = "[src.Quest[QuestK]]/[src.Quest[QuestNK]]"
msgqueststanding = "Quest Standing: [src.Quest[QuestPlace]]"
else
msgqueststanding = "Error with Quest Standings -- Please contact an admin."
QuestPlace = "QuestInformation"
if(!src.Quest[QuestPlace])
msgquestinformation = "Quest Information: No Quest Accepted"
else if(src.Quest[QuestPlace])
msgquestinformation = "Quest Information: [src.Quest[QuestPlace]]"
else
msgquestinformation = "Error with Quest Information -- Please contact an admin."
message = Stat_display3.font.wrap_text(" " + msgquest + "\n" + msgqueststanding + "\n" + \
msgquestinformation, 180)
R.set_text(message)
if(!src.stat_open)
Part_hide(R)



any help would be aprreciated.
Sorry it took so long to get back to you on this. I saw the post when you made it, but I haven't had a block of time large enough to look it over until now.

The first thing I noticed is that the only difference between StatHud1, StatHud2, and StatHud3 appears to be their position. You can make them all inherit from the same base object:

StatHud
// put all the code here

// in the child types you only specify what's
// different about each one.
StatHud1
New()
..()
pos(45, 40)

StatHud2
New()
..()
pos(270, 40)

StatHud3
New()
..()
pos(495, 40)

This won't improve performance, but it makes it a lot easier to work with the code. Also, if there is a performace change you make, it'll automatically be applied to StatHud1, StatHud2, and StatHud3.

Also, it looks like your update procs (mob.StatHolderUpdate, mob.EquipAndSkillholderUpdate, and mob.QuestandInfoHolderUpdate) are updating all of the text - if your level changes, in StatHolderUpdate, you're regenerating all of the text. I'd do something like this:

StatHud
var
HudObject/level
HudObject/health
HudObject/mana
HudObject/stamina
HudObject/exp

New()
..()

level = add(0, 80)
health = add(0, 60)
mana = add(0, 40)
stamina = add(0, 20)
exp = add(0, 0)

proc
update_level(l)
level.text("Level: [l]")

update_health(current, max)
health.text("Health: [current] / [max]")

update_mana(current, max)
mana.text("Mana: [current] / [max]")

// these are similar to the other ones
update_stamina(s)
update_exp(e)

mob
var
StatHud/stat_hud
health = 100
health_max = 100

Login()
..()
stat_hud = new(src)

proc
set_health(h)
health = h
stat_hud.update_health(health, health_max)

set_health_max(h)
health_max = h
stat_hud.update_health(health, health_max)

// you'd create similar procs for setting mana, stamina, level, and experience.

This way you're only updating values when they change. But, since the StatHud object is specific to displaying stats, you have to create similar objects for displaying quest and equipment info.

I do plan to look into maptext to see if it's possible to make the library use that. There are reasons to not use it, but it should certainly be an option available to developers. My biggest concern is how it positions text - if the library does add maptext support you may have to change the positions of the screen objects you're attaching text to to have the text appear in the same place.
I see, also thanks for the help. This is something thats been bogging down the game for quite a while and i never thought to make it like that. =3
I posted an update earlier today that adds support for maptext. HudObjects now have a set_maptext() proc you can use instead of set_text().