ID:1306698
 
(See the best response by Kaiochao.)
Code:
var/NPC_HUD/NH = new()
var/extended_text = ""
var/obj/extended_NPC

mob
var/tmp/list/hud_screen = list()

proc
add_screen(x)
src.hud_screen += x
src.update_screen()

remove_screen(x, all)

if (all)

for (x in src.hud_screen)
src.hud_screen -= x
else
src.hud_screen -= x

src.update_screen()

update_screen()
src.client.screen = null

for (var/obj/t in src.hud_screen)
src.client.screen.Add(t)

NPC_HUD
proc

Chat(obj/NPC, words)

if (istype(NPC, /obj/shops))
words = "test - 1234567891011121314151617181920218547456735673"
NH.Small_Box(NPC, words)


Shop()


Small_Box(obj/NPC, words)

if (length(extended_text))
extended_text = ""

usr.remove_screen(/obj/Hud_Face/face, 1)
usr.remove_screen(/obj/Hud_Controls/blank, 1)
usr.remove_screen(/obj/Hud_Boxes/Hud_Box_1, 1)
usr.remove_screen(/obj/Hud_Boxes/Hud_Box_2, 1)
usr.remove_screen(/obj/Hud_Boxes/Hud_Box_3, 1)
usr.remove_screen(/obj/Hud_Boxes/Hud_Box_4, 1)
usr.remove_screen(/obj/Hud_Boxes/Hud_Box_5, 1)
usr.remove_screen(/obj/Hud_Boxes/Hud_Box_6, 1)
usr.remove_screen(/obj/Hud_Boxes/Hud_Box_7, 1)
usr.remove_screen(/obj/Hud_Boxes/Hud_Box_8, 1)
usr.remove_screen(/obj/Hud_Boxes/Hud_Box_9, 1)

if (!words) return

var/new_words = copytext(words, 1, 35)

var/obj/Hud_Boxes/Hud_Box_1/H1 = new()
usr.add_screen(H1)
H1.screen_loc = "1,1"

for (var/a = 2, a < 11, a ++)
var/obj/Hud_Boxes/Hud_Box_2/H2 = new()
usr.add_screen(H2)
H2.screen_loc = "[a],1"

var/obj/Hud_Boxes/Hud_Box_3/H3 = new()
usr.add_screen(H3)
H3.screen_loc = "11,1"


var/obj/Hud_Boxes/Hud_Box_4/H4 = new()
usr.add_screen(H4)
H4.screen_loc = "1,2"

for (var/a = 2, a < 11, a ++)
var/obj/Hud_Boxes/Hud_Box_5/H5 = new()
usr.add_screen(H5)
H5.screen_loc = "[a],2"

var/obj/Hud_Boxes/Hud_Box_6/H6 = new()
usr.add_screen(H6)
H6.screen_loc = "11,2"

var/obj/Hud_Face/face/npc_face = new()
npc_face.screen_loc = "1,2"
npc_face.layer = MOB_LAYER + 30
npc_face.icon = 'Icons/faces.dmi'
npc_face.icon_state = "[NPC.name]"
usr.add_screen(npc_face)

var/obj/mt = new()
mt.screen_loc = "2,2"
mt.layer = MOB_LAYER + 16
mt.maptext = "<font color = white><font face = Comic Sans MS><b>[new_words]</b>"
usr.add_screen(mt)

if (length(words) > 35)
extended_text = copytext(words, 35, length(words) + 1)
extended_NPC = NPC
var/obj/Hud_Controls/blank/b = new()
var/obj/Hud_Controls/blank/t = new()
b.screen_loc = "11:-6,1:5"
t.screen_loc = "11,1:7"
b.layer = MOB_LAYER + 16
t.layer = MOB_LAYER + 16
t.icon_state = "nothing"
t.maptext = "<font size = \"1\"><font color = white><font face = Comic Sans MS>Next"
usr.add_screen(b)
usr.add_screen(t)

obj
Hud_Face
face
icon = 'Icons/faces.dmi'

Hud_Controls
blank
icon = 'Icons/textboxstuff.dmi'
icon_state ="blank"
Click()
NH.Small_Box(extended_NPC ,extended_text)
Hud_Boxes
Hud_Box_1
icon = 'Icons/textboxstuff.dmi'
icon_state = "1"
layer = MOB_LAYER + 15

Hud_Box_2
icon = 'Icons/textboxstuff.dmi'
icon_state = "2"
layer = MOB_LAYER + 15

Hud_Box_3
icon = 'Icons/textboxstuff.dmi'
icon_state = "3"
layer = MOB_LAYER + 15

Hud_Box_4
icon = 'Icons/textboxstuff.dmi'
icon_state = "4"
layer = MOB_LAYER + 15

Hud_Box_5
icon = 'Icons/textboxstuff.dmi'
icon_state = "5"
layer = MOB_LAYER + 15

Hud_Box_6
icon = 'Icons/textboxstuff.dmi'
icon_state = "6"
layer = MOB_LAYER + 15

Hud_Box_7
icon = 'Icons/textboxstuff.dmi'
icon_state = "7"
layer = MOB_LAYER + 15

Hud_Box_8
icon = 'Icons/textboxstuff.dmi'
icon_state = "8"
layer = MOB_LAYER + 15

Hud_Box_9
icon = 'Icons/textboxstuff.dmi'
icon_state = "9"
layer = MOB_LAYER + 15


Problem description:
For some reason /obj/overlays/HPGlobe, /obj/overlays/ManaGlobe, /obj/overlays/EXPGlobe are being removed from the hud_screen list.
Best response
        remove_screen(x, all)

if (all)
// for() does not work like this.
// since x isn't defined with a type,
// this loops through everything in the list
for (x in src.hud_screen)
src.hud_screen -= x
else
src.hud_screen -= x

src.update_screen()

// What you'd want is probably this:
for(var/atom/o in hud_screen)
if(o.type == x)
hud_screen -= o

// and when 'all' isn't true,
hud_screen -= locate(x) in hud_screen
var/NPC_HUD/NH = new()

var/extended_text = ""

var/obj/extended_NPC

var/const/tmp/MapText_Font = "<font color = white><font face = Comic Sans MS><b>"

var/const/tmp/HUD_LAYER = MOB_LAYER + 15


mob

var/tmp/list/hud_screen = list()

proc
add_screen(x)
src.hud_screen += x
src.update_screen()

remove_screen(x, all)

if (all)

for (var/atom/a in src.hud_screen)

if (a.type == x)
src.hud_screen -= a

else
src.hud_screen -= locate(x) in hud_screen

src.update_screen()

update_screen()
src.client.screen = null

for (var/obj/t in src.hud_screen)
src.client.screen.Add(t)

NPC_HUD
proc

Chat(obj/NPC, words)

if (istype(NPC, /obj/shops))
NH.Small_Box(NPC, words)


Shop()


Small_Box(obj/NPC, words)

if (length(extended_text))
extended_text = ""

usr.remove_screen(/obj/Hud_Controls/next, 1)
usr.remove_screen(/obj/Hud_Controls/text, 1)
usr.remove_screen(/obj/Hud_Face/face, 1)
usr.remove_screen(/obj/Hud_Boxes/Hud_Box_1, 1)
usr.remove_screen(/obj/Hud_Boxes/Hud_Box_2, 1)
usr.remove_screen(/obj/Hud_Boxes/Hud_Box_3, 1)
usr.remove_screen(/obj/Hud_Boxes/Hud_Box_4, 1)
usr.remove_screen(/obj/Hud_Boxes/Hud_Box_5, 1)
usr.remove_screen(/obj/Hud_Boxes/Hud_Box_6, 1)
usr.remove_screen(/obj/Hud_Boxes/Hud_Box_7, 1)
usr.remove_screen(/obj/Hud_Boxes/Hud_Box_8, 1)
usr.remove_screen(/obj/Hud_Boxes/Hud_Box_9, 1)

if (!words) return

var/new_words = copytext(words, 1, 35)
var/obj/Hud_Boxes/Hud_Box_1/H1 = new()
usr.add_screen(H1)
H1.screen_loc = "1,1"

for (var/a = 2, a < 11, a ++)
var/obj/Hud_Boxes/Hud_Box_2/H2 = new()
usr.add_screen(H2)
H2.screen_loc = "[a],1"

var/obj/Hud_Boxes/Hud_Box_3/H3 = new()
usr.add_screen(H3)
H3.screen_loc = "11,1"


var/obj/Hud_Boxes/Hud_Box_4/H4 = new()
usr.add_screen(H4)
H4.screen_loc = "1,2"

for (var/a = 2, a < 11, a ++)
var/obj/Hud_Boxes/Hud_Box_5/H5 = new()
usr.add_screen(H5)
H5.screen_loc = "[a],2"

var/obj/Hud_Boxes/Hud_Box_6/H6 = new()
usr.add_screen(H6)
H6.screen_loc = "11,2"

var/obj/Hud_Face/face/npc_face = new()
npc_face.screen_loc = "1,2"
npc_face.layer = HUD_LAYER + 1
npc_face.icon = 'Icons/faces.dmi'
npc_face.icon_state = "[NPC.name]"
usr.add_screen(npc_face)

var/obj/Hud_Controls/text/mt = new()
mt.screen_loc = "2,2"
mt.layer = HUD_LAYER + 1
mt.maptext = "[MapText_Font][new_words]</b>"
usr.add_screen(mt)

if (length(words) > 35)
extended_text = copytext(words, 35, length(words) + 1)
extended_NPC = NPC

var/obj/Hud_Controls/next/b = new()
var/obj/Hud_Controls/next/t = new()
b.screen_loc = "11:-6,1:5"
t.screen_loc = "11,1:7"
b.layer = HUD_LAYER + 1
t.layer = HUD_LAYER + 1
t.icon_state = "nothing"
t.maptext = "<font size = \"1\">[MapText_Font]Next"
usr.add_screen(b)
usr.add_screen(t)

obj
Hud_Face
face
icon = 'Icons/faces.dmi'

Hud_Controls

text

next
icon = 'Icons/textboxstuff.dmi'
icon_state ="blank"
Click()
NH.Small_Box(extended_NPC ,extended_text)

Hud_Boxes
Hud_Box_1
icon = 'Icons/textboxstuff.dmi'
icon_state = "1"
layer = HUD_LAYER

Hud_Box_2
icon = 'Icons/textboxstuff.dmi'
icon_state = "2"
layer = HUD_LAYER
Hud_Box_3
icon = 'Icons/textboxstuff.dmi'
icon_state = "3"
layer = HUD_LAYER

Hud_Box_4
icon = 'Icons/textboxstuff.dmi'
icon_state = "4"
layer = HUD_LAYER

Hud_Box_5
icon = 'Icons/textboxstuff.dmi'
icon_state = "5"
layer = HUD_LAYER

Hud_Box_6
icon = 'Icons/textboxstuff.dmi'
icon_state = "6"
layer = HUD_LAYER

Hud_Box_7
icon = 'Icons/textboxstuff.dmi'
icon_state = "7"
layer = HUD_LAYER

Hud_Box_8
icon = 'Icons/textboxstuff.dmi'
icon_state = "8"
layer = HUD_LAYER

Hud_Box_9
icon = 'Icons/textboxstuff.dmi'
icon_state = "9"
layer = HUD_LAYER


This is how I concluded it. Any comments or concerns to improve?
Small_Box() is a proc. Don't use usr in it. Pass a reference to the mob whose screen you want to modify.

Your remove_screen()'s behaviour is behaviour I don't like - doing something different based on whether a second parameter is true or not doesn't sit well with me. It'd be like if ckey() took a second parameter, and if it was true it worked like ckeyEx(). You should probably split that into two functions. Actually, maybe you should just have the all behaviour - the non-all behaviour doesn't really need to be a function, it's a single self-explanatory line.

Why is extended_text a global? Is it used anywhere else?

I don't like 'src.' in front of things - src is assumed if you don't specify a source. But I think some people differ on that bit of style.

Screen locs can be "x1, y1 to x2,y2". Puts one of those objects at every spot in that range. Can save yourself some H2's and H5's

All of those Hud_Box types are code smell to me. Are you sure there's no better approach here - like a single object with a large icon? Or programmatically setting icon_state?

Even if you don't do that, I think a function to do the "make a new object of type X, set screen loc, set layer, add to screen" thing would be good.
I do not want one big image because this will switch from full screen to 1/3rd of the screen. extended_text should not be global, it should be a atom variable. I prefer src because of how messy my other parts of the game are.

Edit: whatever I did just broke everything. ^_^


var/NPC_HUD/NH = new()

var/const/tmp/MapText_Font = "<font color = white><font face = Comic Sans MS><b>"

var/const/tmp/HUD_LAYER = MOB_LAYER + 15

mob
var/tmp/extended_text = ""
var/obj/extended_NPC

mob

var/tmp/list/hud_screen = list()

proc
add_screen(x)
src.hud_screen += x
src.update_screen()

remove_all_from_screen(x)


for (var/atom/a in src.hud_screen)

if (a.type == x)
src.hud_screen -= a

src.update_screen()

remove_one_from_screen(x)

src.hud_screen -= locate(x) in hud_screen
src.update_screen()

update_screen()
src.client.screen = null

for (var/obj/t in src.hud_screen)
src.client.screen.Add(t)

NPC_HUD
proc

NPC_Talk(atom/m, obj/NPC, words)

if (!istype(m, /mob/players))
return

if (istype(NPC, /obj/shops))
Small_Box(m, NPC, words)


Small_Box(atom/at, obj/NPC, words)

if (!istype(at, /mob/players))
return

var/mob/m = at

if (length(m.extended_text))
m.extended_text = ""

m.remove_all_from_screen(/obj/Hud_Controls/blank, 1)
m.remove_all_from_screen(/obj/Hud_Controls/text, 1)
m.remove_all_from_screen(/obj/Hud_Face/face, 1)
m.remove_all_from_screen(/obj/Hud_Boxes/Hud_Box_1, 1)
m.remove_all_from_screen(/obj/Hud_Boxes/Hud_Box_2, 1)
m.remove_all_from_screen(/obj/Hud_Boxes/Hud_Box_3, 1)
m.remove_all_from_screen(/obj/Hud_Boxes/Hud_Box_4, 1)
m.remove_all_from_screen(/obj/Hud_Boxes/Hud_Box_5, 1)
m.remove_all_from_screen(/obj/Hud_Boxes/Hud_Box_6, 1)
m.remove_all_from_screen(/obj/Hud_Boxes/Hud_Box_7, 1)
m.remove_all_from_screen(/obj/Hud_Boxes/Hud_Box_8, 1)
m.remove_all_from_screen(/obj/Hud_Boxes/Hud_Box_9, 1)

if (!words) return

var/new_words = copytext(words, 1, 35)
var/obj/Hud_Boxes/Hud_Box_1/H1 = new()
m.add_screen(H1)
H1.screen_loc = "1,1"

for (var/a = 2, a < 11, a ++)

var/obj/Hud_Boxes/Hud_Box_2/H2 = new()
m.add_screen(H2)
H2.screen_loc = "[a],1"

var/obj/Hud_Boxes/Hud_Box_5/H5 = new()
m.add_screen(H5)
H5.screen_loc = "[a],2"

var/obj/Hud_Boxes/Hud_Box_3/H3 = new()
m.add_screen(H3)
H3.screen_loc = "11,1"


var/obj/Hud_Boxes/Hud_Box_4/H4 = new()
m.add_screen(H4)
H4.screen_loc = "1,2"

var/obj/Hud_Boxes/Hud_Box_6/H6 = new()
m.add_screen(H6)
H6.screen_loc = "11,2"

var/obj/Hud_Face/face/npc_face = new()
npc_face.screen_loc = "1,2"
npc_face.layer = HUD_LAYER + 1
npc_face.icon = 'Icons/faces.dmi'
npc_face.icon_state = "[NPC.name]"
m.add_screen(npc_face)

var/obj/Hud_Controls/text/mt = new()
mt.screen_loc = "2,2"
mt.layer = HUD_LAYER + 1
mt.maptext = "[MapText_Font][new_words]</b>"
m.add_screen(mt)

if (length(words) > 35)
m.extended_text = copytext(words, 35, length(words) + 1)
m.extended_NPC = NPC

var/obj/Hud_Controls/blank/b = new()
var/obj/Hud_Controls/blank/t = new()
b.screen_loc = "11:-6,1:5"
t.screen_loc = "11,1:7"
b.layer = HUD_LAYER + 1
t.layer = HUD_LAYER + 1
t.icon_state = "nothing"
t.maptext = "<font size = \"1\">[MapText_Font]Next"
m.add_screen(b)
m.add_screen(t)

obj
Hud_Face
face
icon = 'Icons/faces.dmi'

Hud_Controls

text

blank
icon = 'Icons/textboxstuff.dmi'
icon_state = "blank"
Click(atom/a)

if (!istype(a, /mob/players))
return

var/mob/m = a

NH.Small_Box(m.extended_NPC ,m.extended_text)

Hud_Boxes
Hud_Box_1
icon = 'Icons/textboxstuff.dmi'
icon_state = "1"
layer = HUD_LAYER

Hud_Box_2
icon = 'Icons/textboxstuff.dmi'
icon_state = "2"
layer = HUD_LAYER
Hud_Box_3
icon = 'Icons/textboxstuff.dmi'
icon_state = "3"
layer = HUD_LAYER

Hud_Box_4
icon = 'Icons/textboxstuff.dmi'
icon_state = "4"
layer = HUD_LAYER

Hud_Box_5
icon = 'Icons/textboxstuff.dmi'
icon_state = "5"
layer = HUD_LAYER

Hud_Box_6
icon = 'Icons/textboxstuff.dmi'
icon_state = "6"
layer = HUD_LAYER

Hud_Box_7
icon = 'Icons/textboxstuff.dmi'
icon_state = "7"
layer = HUD_LAYER

Hud_Box_8
icon = 'Icons/textboxstuff.dmi'
icon_state = "8"
layer = HUD_LAYER

Hud_Box_9
icon = 'Icons/textboxstuff.dmi'
icon_state = "9"
layer = HUD_LAYER