ID:1850783
 
(See the best response by Lummox JR.)
Code:
mob
var
bagopened = 1
verb/bagopen()
if(bagopened==1)
bagopened = 0
winshow(src,"inventory",1)
else if(bagopened==0)
bagopened = 1
winshow(src, "inventory",0)
else
src<<"Unknown bag opening error bagopen !=1/0"

proc
equipstuff()
usr << output(usr.legs, "inventory.legs")
usr << output(usr.shoulder, "inventory.shoulder")
usr << output(usr.face, "inventory.face")
usr << output(usr.feet, "inventory.feet")
usr << output(usr.head, "inventory.head")
usr << output(usr.back, "inventory.back")
usr << output(usr.mainhand, "inventory.mainhand")
usr << output(usr.offhand, "inventory.offhand")
usr << output(usr.glove, "inventory.glove")
usr << output(usr.chest, "inventory.chest")

InvLayer()
mob
var
chest
legs
shoulder
face
feet
head
back
mainhand
offhand
glove

list/hiddenlist = list()




Entered(obj/Armor/A)
..()
if(istype(A))
var/obj/Armor/X=locate(A.type) in src.contents-A
if(X)
A.amount+=X.amount
del X
Inventory()

Exited()
..()
Inventory()

proc/Inventory()
var/i=1
winset(src,"inventory.invent",{"cells="2x[contents.len+1]""})
src<<output("<b>Item</b>","inventory.invent:1,1")
src<<output("<b>Amount</b>","inventory.invent:2,1")
for(var/obj/Armor/I in contents)
src<<output(I,"inventory.invent:1,[++i]")
src<<output(I.amount,"inventory.invent:2,[i]")

MouseDrag(src_object,over_object,src_location,over_location,src_control,over_control,params)
if(!(src in usr.contents)) return




proc/InvLayer()
var/list/new_overlays = list()
for(var/slot in list("legs","feet","chest","glove","back","offhand","mainhand","shoulder","face","head"))
var/obj/Armor/A = vars[slot]
if(A) new_overlays += A.overlay_icon

overlays = new_overlays

atom/proc/Bumped(atom/A) return 1


obj/Armor

MouseDrop(over_object=src,src_location,over_location,src_control,over_control,params)
if(src in usr.contents)
if(findtextEx(over_control,"inventory.")==1)
if(over_control == "inventory.[equiptype]")
Equip(usr)

else
usr << output(null,"inventory.about")
usr << output(equiptype ? "That doesn't go there!" : "That isn't an equippable item!", "inventory.about")
else if(over_control == "inventory.invent")
Unequip(usr)

density = 1
var/amount = 1


verb/Pickup()
set src in oview(1)
Pickup_proc(usr)


proc/Pickup_proc(mob/M)
if(!(M in oview(1,src))) return
.=Move(M)
M << "[(.)?"\green":"\red"] You[(.)?"":" did not"] pick up [src.name]."


var/equiptype
var/overlay_icon




obj/Armor/proc/Equip(mob/M)
var/obj/Armor/old = M.vars[equiptype]
if(old && old != src) old.Unequip(M, 1)
M << "Equipped [name]"
M << output(null,"inventory.about")
M << output("Equipped [name]","inventory.about")
M.vars[equiptype] = src
loc = M.hiddenlist
M << output(src, "inventory.[equiptype]")
overlay_icon = icon
M.InvLayer()
M.Inventory()

obj/Armor/proc/Unequip(mob/M, auto)
if(M.vars[equiptype] != src) return
M << "Removed [name]"
M << output(null,"inventory.about")
M << output("Removed [name]","inventory.about")
M.vars[equiptype] = null
loc = M
if(!auto)
M << output(null, "inventory.[equiptype]")
M.InvLayer()
M.Inventory()


mob
var
hairr
hairg
hairb
const/HAIR_LAYER = FLOAT_LAYER-3
haircolor
eyecolor
newHair
loadHair
loadEyes
verb
Hairemo1()
if(gnder==1 || gnder==2)
usr.overlays -= Hair
newHair = 'hair_emo.dmi'
haircolor = input("Please select your hair color") as color
newHair += haircolor
Hair = newHair
var/Hairred=4
var/Hairgreen=4
var/Hairblue=5
Hair += rgb(Hairred,Hairgreen,Hairblue)
HairR=Hairred
HairG=Hairgreen
HairB=Hairblue
whichair = 1
overlays += Hair


Problem description: For some reason when I equip anything, the hair goes -poof-. It just disappears o.o

overlays = new_overlays


In InvLayer(), you're setting the overlays to a new list, so the hair appearance you added gets overwritten.
FKI, that's correct behavior as established in his other thread; if he wants hair to be an overlay also it should be stored in a var and added in InvLayer().

Dark, this is still super rife with usr abuse. equipstuff() should be dealing entirely with src, not usr. If you only have usr in verbs, or pseudo-verbs like Click() and whatnot, then you'll save yourself a lot of headaches.
In response to Lummox JR
Lummox JR wrote:
it should be stored in a var and added in InvLayer().

I tried that. Hair is the variable that holds the finished Hair, but when I tried to add it..


        for(var/slot in list("legs","feet","chest","glove","back","offhand","mainhand","shoulder","face","head","Hair"))


It ended up keeping the hair and not showing any of the other overlays.
You've only posted part of the code you used, so I can't help you there without seeing more. It's impossible to tell why Hair took over the overlays without seeing not only all of InvLayer() with it, but also any code that impacts the overlays.

Basically because you have InvLayer() to rebuild your overlays each time, you shouldn't be modifying the overlays list manually anywhere else.
Well I was trying to only include the code I thought applied due to that one comment about posting too much code. The following is everything that applies to hair and overlays:
mob/var/Hair = null
mob/var/HairR = null
mob/var/HairG = null
mob/var/HairB = null
mob/var/whichair
mob/var/Eye = null


mob
var
hairr
hairg
hairb
const/HAIR_LAYER = FLOAT_LAYER-3
haircolor
eyecolor
newHair
loadHair
loadEyes
verb
Hairemo1()
if(gnder==1 || gnder==2)
src.overlays -= Hair
newHair = 'hair_emo.dmi'
haircolor = input("Please select your hair color") as color
newHair += haircolor
Hair = newHair
var/Hairred=4
var/Hairgreen=4
var/Hairblue=5
Hair += rgb(Hairred,Hairgreen,Hairblue)
HairR=Hairred
HairG=Hairgreen
HairB=Hairblue
whichair = 1
overlays += Hair
HairSpikey()
if(gnder==1 || gnder==2)
src.overlays -= Hair
newHair = 'Hair Spikey.dmi'
haircolor = input("Please select your hair color") as color
newHair += haircolor
Hair = newHair
var/Hairred=4
var/Hairgreen=4
var/Hairblue=5
Hair += rgb(Hairred,Hairgreen,Hairblue)
HairR=Hairred
HairG=Hairgreen
HairB=Hairblue
whichair = 2
overlays += Hair

Hairbald()
if(gnder==1 || gnder==2)
src.overlays -= Hair
src.Hair = null
whichair = 0

Eyecolor()
if(gnder==1 || gnder==2)
var/newEyes = 'Eye_Overlay.dmi'
eyecolor = input("Please select your eye color") as color
newEyes += eyecolor
Eye = newEyes
var/Eyered=4
var/Eyegreen=4
var/Eyeblue=5
Eye += rgb(Eyered,Eyegreen,Eyeblue)
overlays += Eye
overlays += Hair
proc
Hairr()
overlays += Eye
overlays += Hair
Hairlogin(var/savefile/F)
Read(F)
F["Hair2"]>>haircolor
F["Eyes"]>>eyecolor

loadEyes = 'Eye_Overlay.dmi'
loadEyes += eyecolor
Eye = loadEyes
var/Eyered=4
var/Eyegreen=4
var/Eyeblue=5
Eye += rgb(Eyered,Eyegreen,Eyeblue)
overlays += Eye
if(F["Hair"]==0)
src.overlays -= Hair
src.Hair = null
whichair = 0
if(F["Hair"]==1)
loadHair = 'hair_emo.dmi'
loadHair += haircolor
Hair = loadHair
var/Hairred=4
var/Hairgreen=4
var/Hairblue=5
Hair += rgb(Hairred,Hairgreen,Hairblue)
overlays += Hair
whichair = 1
if(F["Hair"]==2)
loadHair = 'Hair Spikey.dmi'
loadHair += haircolor
Hair = loadHair
var/Hairred=4
var/Hairgreen=4
var/Hairblue=5
Hair += rgb(Hairred,Hairgreen,Hairblue)
overlays += Hair
whichair = 2


mob
var
bagopened = 1
verb/bagopen()
if(bagopened==1)
bagopened = 0
winshow(src,"inventory",1)
else if(bagopened==0)
bagopened = 1
winshow(src, "inventory",0)
else
src<<"Unknown bag opening error bagopen !=1/0"

proc
equipstuff()
usr << output(src.legs, "inventory.legs")
usr << output(src.shoulder, "inventory.shoulder")
usr << output(src.face, "inventory.face")
usr << output(src.feet, "inventory.feet")
usr << output(src.head, "inventory.head")
usr << output(src.back, "inventory.back")
usr << output(src.mainhand, "inventory.mainhand")
usr << output(src.offhand, "inventory.offhand")
usr << output(src.glove, "inventory.glove")
usr << output(src.chest, "inventory.chest")

InvLayer()
mob
var
chest
legs
shoulder
face
feet
head
back
mainhand
offhand
glove

list/hiddenlist = list()




Entered(obj/Armor/A)
..()
if(istype(A))
var/obj/Armor/X=locate(A.type) in src.contents-A
if(X)
A.amount+=X.amount
del X
Inventory()

Exited()
..()
Inventory()

proc/Inventory()
var/i=1
winset(src,"inventory.invent",{"cells="2x[contents.len+1]""})
src<<output("<b>Item</b>","inventory.invent:1,1")
src<<output("<b>Amount</b>","inventory.invent:2,1")
for(var/obj/Armor/I in contents)
src<<output(I,"inventory.invent:1,[++i]")
src<<output(I.amount,"inventory.invent:2,[i]")

MouseDrag(src_object,over_object,src_location,over_location,src_control,over_control,params)
if(!(src in usr.contents)) return




proc/InvLayer()
var/list/new_overlays = list()
for(var/slot in list("legs","feet","chest","glove","back","offhand","mainhand","shoulder","face","head"))
var/obj/Armor/A = vars[slot]
if(A) new_overlays += A.overlay_icon

overlays = new_overlays

atom/proc/Bumped(atom/A) return 1


obj/Armor

MouseDrop(over_object=src,src_location,over_location,src_control,over_control,params)
if(src in usr.contents)
if(findtextEx(over_control,"inventory.")==1)
if(over_control == "inventory.[equiptype]")
Equip(usr)

else
usr << output(null,"inventory.about")
usr << output(equiptype ? "That doesn't go there!" : "That isn't an equippable item!", "inventory.about")
else if(over_control == "inventory.invent")
Unequip(usr)

density = 1
var/amount = 1


verb/Pickup()
set src in oview(1)
Pickup_proc(usr)


proc/Pickup_proc(mob/M)
if(!(M in oview(1,src))) return
.=Move(M)
M << "[(.)?"\green":"\red"] You[(.)?"":" did not"] pick up [src.name]."


var/equiptype
var/overlay_icon

KasablancRobeMale
icon = 'Kasablanc Robe Male.dmi'
icon_state = ""
name = "Kasablanc Robe (M)"
equiptype = "chest"
KasablancRobeFemale
icon = 'Kasablanc Robe female.dmi'
icon_state = ""
name = "Kasablanc Robe (F)"
equiptype = "chest"
KasablancPants
icon = 'Kasablanc pants.dmi'
icon_state = ""
name = "Kasablanc Pants"
equiptype = "legs"
KasablancCloak
icon = 'Kasablanc Cloak.dmi'
icon_state = ""
name = "Kasablanc Cloak"
equiptype = "back"
KreptkinPantsMale
icon = 'Kreptkin Pants Male.dmi'
icon_state = ""
name = "Kreptkin Pants"
equiptype = "legs"
KreptkinShirtFemale
icon = 'Kreptkin shirt female.dmi'
icon_state = ""
name = "Kreptkin Blouse (F)"
equiptype = "chest"
KreptkinSkirt
icon = 'Kreptkin skirt.dmi'
icon_state = ""
name = "Kreptkin Skirt"
equiptype = "legs"
KreptkinSuitMale
icon = 'Kreptkin Suit Male.dmi'
icon_state = ""
name = "Kreptkin Suit (M)"
equiptype = "chest"
NutoriRobeFemale
icon = 'Nutori Robe female.dmi'
icon_state = ""
name = "Nutori Robes (F)"
equiptype = "chest"
NutoriRobeMale
icon = 'Nutori Robe Male.dmi'
icon_state = ""
name = "Nutori Robes (M)"
equiptype = "chest"
PuraelicChest
icon = 'Puraelic chest m.dmi'
icon_state = ""
name = "Puraelic Chestpiece"
equiptype = "chest"
PuraelicGauntlets
icon = 'Puraelic gauntlets.dmi'
icon_state = ""
name = "Puraelic Gauntlets"
equiptype = "glove"
PuraelicPantsMale
icon = 'Puraelic pants male.dmi'
icon_state = ""
name = "Puraelic Greaves (M)"
equiptype = "legs"
PuraelicPantsFemale
icon = 'Puraelic pants female.dmi'
icon_state = ""
name = "Puraelic Greaves (F)"
equiptype = "legs"
ShaedralGoggles
icon = 'Shaedral Goggles.dmi'
icon_state = ""
name = "Shaedral Goggles"
equiptype = "head"
ShaedralMask
icon = 'Shaedral Mask.dmi'
icon_state = ""
name = "Shaedral Facemask"
equiptype = "face"
ShaedralPants
icon = 'Shaedral Pants.dmi'
icon_state = ""
name = "Shaedral Pants"
equiptype = "legs"
ShaedralShirtFemale
icon = 'Shaedral shirt female.dmi'
icon_state = ""
name = "Shaedral Shirt (F)"
equiptype = "chest"
ShaedralShirtMale
icon = 'Shaedral shirt male.dmi'
icon_state = ""
name = "Shaedral Shirt (M)"
equiptype = "chest"


obj/Armor/proc/Equip(mob/M)
var/obj/Armor/old = M.vars[equiptype]
if(old && old != src) old.Unequip(M, 1)
M << "Equipped [name]"
M << output(null,"inventory.about")
M << output("Equipped [name]","inventory.about")
M.vars[equiptype] = src
loc = M.hiddenlist
M << output(src, "inventory.[equiptype]")
overlay_icon = icon
M.InvLayer()
M.Inventory()

obj/Armor/proc/Unequip(mob/M, auto)
if(M.vars[equiptype] != src) return
M << "Removed [name]"
M << output(null,"inventory.about")
M << output("Removed [name]","inventory.about")
M.vars[equiptype] = null
loc = M
if(!auto)
M << output(null, "inventory.[equiptype]")
M.InvLayer()
M.Inventory()


Aside from the Save/Load code which shouldn't affect anything here at the moment
Best response
Okay, a couple of problems:

1) You're still modifying the overlays list outside of InvLayer(). Don't do that. InvLayer() should handle everything.

2) The hair icon really shouldn't be part of that list; it should be added separately, before or after the armor (depending on which makes the most sense). Remember, all of the strings in that list correspond to vars that are obj/Armor objects--the Hair icon is only an icon. I only suggested implementing it as a list of vars because that was the simplest way to handle all of that without a lot of repeat code.

3) You still have usr abuse in equipstuff(). Change that to src, which is correct in this case; usr is not guaranteed to be correct at all.
Ah, I figured it out too. I had tried before to add it in InvLayer() but I did overlays += Hair before overlays = new_overlays. I switched it to immediatly after and it works now. Thanks again. Also fixed all the usr.--- to src, although could you please tell me exactly why it would have brought future problems? Just curious, like an example. Thanks again for all the help :)
I think this code has a vendetta against me. A new problem now. When I log out, we're back to the bald on login. Aside from the mentioned changes, nothing else has been changed or added. Before this inventory code, hair saved just fine. I tried removing overlay += Hair from all spots on the HairLogin() proc with no change. This is my save/load code

mob

var/created = FALSE
var/ingame = FALSE


Login()
world << "[key] has just joined the world~"
randommidi()
Logout()
if(created==TRUE)
if(ingame==TRUE)
world << "[key] has logged off!"
var/savefile/F=new("Save/[ckey].sav")
F["Hair"]<<src.whichair
F["Hair2"]<<src.haircolor
F["Eyes"]<<src.eyecolor
F["Race"]<<src.race
F["name"]<<usr.name
F["g"]<<src.icon
F["x"]<<src.x
F["y"]<<src.y
F["z"]<<src.z
F["verbs"]<<src.verbs
F["factionmidi"]<<src.factionmidi
F["Inventory"]<<src.contents

F["chestsave"]<<src.chest
F["legsave"]<<src.legs
F["shouldersave"]<<src.shoulder
F["facesave"]<<src.face
F["feetsave"]<<src.feet
F["headsave"]<<src.head
F["backsave"]<<src.back
F["mhsave"]<<src.mainhand
F["ohsave"]<<src.offhand
F["glovesave"]<<src.glove
sleep(2)
Write(F)
del(src)
..()
proc
Load()
if(client)
if(fexists("Save/[src.ckey].sav"))
var/savefile/F=new("Save/[src.ckey].sav")
Read(F)
sleep(2)
F["Inventory"]>>src.contents
F["chestsave"]>>src.chest
F["legsave"]>>src.legs
F["shouldersave"]>>src.shoulder
F["facesave"]>>src.face
F["feetsave"]>>src.feet
F["headsave"]>>src.head
F["backsave"]>>src.back
F["mhsave"]>>src.mainhand
F["ohsave"]>>src.offhand
F["glovesave"]>>src.glove
Inventory()
usr.name = F["name"]
icon=F["g"]
factionmidi=F["factionmidi"]
Hairlogin(F)
equipstuff()
if(F["x"]&&F["y"]&&F["z"]) src.Move(locate(F["x"], F["y"], F["z"]))
else src.loc = locate(1,1,1)
if(!isnull(F["verbs"])) src.verbs.Add(F["verbs"])
src.verbs+=typesof(/mob/verb/)
world << output("~**[key] has returned!**~","TAZgame.oocoutput")
winshow(src, "TAZgame", 1)
winset(src, "charactercreate.map2", "is-default=false")
winset(src, "TAZgame.map1", "is-default=true")
winset(src, "loginwindow", "is-default=false")
winset(src, "TAZgame", "is-default=true")
winshow(src, "loginwindow", 0)
winshow(src, "OptionsWindow", 0)
ingame = TRUE
created = TRUE
src << sound('Menu theme.mid',repeat=1,channel=1,volume=0)
src << sound('Menu_theme_2.mid',repeat=1,channel=1,volume=0)
src << factionmidi
fcmidi()
else
alert("You do not have any characters on this server.")
return
In response to Darklady5
Here is a post addressing that by the guy himself. :)

Lummox JR - Dream Tutor: Usr Unfriendly
WElp that's one part answered thankyou :)
There is a lot of logic that should be broken down into smaller portions. If the regular adding hair works, and you're saving/loading correctly, then there shouldn't be a reason you would not be able to load the hair correctly.

If you look at the code below, the code is built to work in small steps that allow for a great amount of reuse. Changing hair, Changing Color, and Loading should all funnel up though the same chain of procedures, allowing you to be certain the issue is not at the core, but instead is at the start (in this case, it would be the loading).

The reason we can be sure is that we've already tested the previous areas. I would recommend that you restructure the load and other procedures in this format to allow for the single test and reuse with confidence, as all the issues you've been having here are because of lack of performing the actions in a centralized way.

mob
var mobGender = 1
var hairIcon
var hairColor

proc/AddHair(iconfile, colorselection) //add hair - all goes through here
hairIcon = iconfile
hairColor = colorselection
ApplyOverlays()

proc/ApplyOverlays() //add overlays - all goes through here
//hair
var/icon/hair = new(hairIcon)
hair += hairColor
//armor

//other

//apply them
overlays = list() + hair

proc/Save() //save the things we wish to save
var/savefile/f = new("saves/[src.ckey].sav")
f["HairIcon"] << src.hairIcon
f["HairColor"] << src.hairColor

proc/Load() //load the things we saved
if(!client || !fexists("saves/[src.ckey].sav")) return 0
var/savefile/f = new("saves/[src.ckey].sav")
AddHair(f["HairIcon"],f["HairColor"])

verb/HairSpikey()
if(mobGender in 1 to 2)
var hair = "test.dmi" //our new icon
var selection = ColorSelection() //reuseable color selection
AddHair(hair, selection) //reuse the add hair logic

proc/ColorSelection()
return input(src, "Please select your hair color") as color

Login()
..()
Load()

Logout()
Save()
..()
Righto. While I'm working on that, I forgot to mentionn I'm also recieving a runtime error that's unfortunately familiar:

runtime error: bad icon operation
proc name: Hairlogin (/mob/proc/Hairlogin)
usr: Sdgf (/mob)
src: Sdgf (/mob)
call stack:
Sdgf (/mob): Hairlogin(Save/666l3l3.sav (/savefile))
Sdgf (/mob): Load()
Sdgf (/mob): gogogo2()
5

I ran into that before, but I'd had it fixed, so whatevers causing it this time is slightly different..

In the Hairlogin proc I removed the lines referring to eyecolor, and it suddenly works. Now if I can just figure out how to fix the eyecolor overlay loading issue that seems to be crashing this proc
FIXED! I only needed to add overlays += Eye to InvLayer() proc lol! Sorry about all of that ><
You really should turn debugging info on for your project. Then you'll get line numbers with runtime errors, which should save you a lot of grief when trying to hunt them down.
I didn't even know that was a thing till now. I found and turned it on, thankyou.
In response to Lummox JR
While it's on the topic of debugging, under what circumstances do you recommend someone have it on?

Such as during normal hosting, only during actual testing, after having runtime errors generated you want to track and fix?

And does having it on affect either size of the file or speed of the code in any significant way?
The effect on code speed is really insignificant. In a super-tight loop that ran a zillion times it'd be noticeable, but otherwise not so much. It does add to the proc size, but not by much. Basically there's an instruction that says "I'm in this file now", and one that says "I'm on this line now"; the former only appears once in a proc.

I would leave this on all the time for your own peace of mind, except if you made it available for download. In the packaged version you probably don't want all that.