ID:1464664
 
(See the best response by DarkCampainger.)
Code:
        Equip()
set src in usr.contents
usr.icon_state = "playersword"
src.icon_state = "swordequip"
usr.overlays += src
..()

UnEquip(var/mob/User)
User.icon_state = "player"
src.icon_state = "sword"
User.overlays -= src
..()


Problem description:
Either I'm missing something about the way overlays work or BYOND is glitching. The overlay doesn't go away. The icon in the player's inventory changes, but the overlay remains, so I tried using my overlay class

Overlays
icon = 'Overlays.dmi'
parent_type = /obj

RedBox
icon_state = "redbox"

Sword_Overlay
icon = 'Equipment.dmi'
icon_state = "swordequip"
layer = 5


And adding it by type, but that also failed to remove the overlay.
Are you calling the unequip proc properly? If it's a verb then that argument means nothing, if it's a proc you need to make sure you're calling it with the proper argument.
UnEquip is a proc, and I know the arguments are being passed properly because I've used debugging statements to check.
Can you post the UnEquip proc?
It is posted, but the parent proc is

    proc
UnEquip(var/mob/User, var/slot) // This should never be called by the player, only the object
User << "You unequip the [src.name]."
switch(slot)
if(1)
User.HeadEquipObj = null
if(2)
User.ChestEquipObj = null
if(3)
User.HandEquipObj = null
if(4)
User.LegsEquipObj = null
return


Yes, both are being called, as I have used debugging statements to check this.
Best response
Lugia319 wrote:
Code:
        UnEquip(var/mob/User)
// ...
src.icon_state = "sword"
User.overlays -= src
// ...


You're changing the icon_state of the object before removing it, causing the appearance not to match what you originally added to the player's overlays. You added it as "swordequip" but now you're trying to remove "sword".
In response to DarkCampainger
DarkCampainger wrote:
Lugia319 wrote:
Code:
>       UnEquip(var/mob/User)
> // ...
> src.icon_state = "sword"
> User.overlays -= src
> // ...
>

You're changing the icon_state of the object before removing it, causing the appearance not to match what you originally added to the player's overlays. You added it as "swordequip" but now you're trying to remove "sword".

I thought of that myself when I tested it, and it didn't work. Even if that were the case, why would add by type not resolve the issue?

        UnEquip(var/mob/User)
User.icon_state = "player"
User.overlays -= src
src.icon_state = "sword"
..()
Adding and removing by type should have worked. Is it possible that you're adding a duplicate overlay in the Equip() parent proc?
Impossible. The equip verb doesn't add overlays except in the child.

        Equip()
set src in usr.contents
var/msg = "You equip the [src.name]."
switch(src.Slot)
if(1) // Head slot
if(isnull(usr.HeadEquipObj))
usr.HeadEquipObj = src ; usr << msg
else if(usr.HeadEquipObj != src)
usr.HeadEquipObj.UnEquip(usr, 1)
usr.HeadEquipObj = src ; usr << msg
else
src.UnEquip(usr, 1)
if(2)
if(isnull(usr.ChestEquipObj))
usr.ChestEquipObj = src ; usr << msg
else if(usr.ChestEquipObj != src)
usr.ChestEquipObj.UnEquip(usr, 2)
usr.ChestEquipObj = src ; usr << msg
else
src.UnEquip(usr, 2)
if(3)
if(isnull(usr.HandEquipObj))
usr.HandEquipObj = src ; usr << msg
else if(usr.HandEquipObj != src)
usr.HandEquipObj.UnEquip(usr, 3)
usr.HandEquipObj = src ; usr << msg
else
src.UnEquip(usr, 3)
if(4)
if(isnull(usr.LegsEquipObj))
usr.LegsEquipObj = src ; usr << msg
else if(usr.LegsEquipObj != src)
usr.LegsEquipObj.UnEquip(usr, 4)
usr.LegsEquipObj = src ; usr << msg
else
src.UnEquip(usr, 4)
return
Do you have saving implemented? Is it possible the overlays you are seeing are left over from a loaded save? Or are you starting with a fresh mob each time?

If you print out the overlays at different points, do you see anything unusual?

Here's a debug verb to print overlays, in case you don't have one:
mob/verb/PrintOverlays()
src << "<hr>"
src << "overlays.len = [overlays.len]"
var/i = 1
for(var/a in overlays)
src << "overlays\[[i]] = {"
if(!a)
src << " <null>"
else
src << " \icon[a]"
src << " icon = '[a:icon]' (\ref[a:icon])"
src << " icon_state = \"[a:icon_state]\""
src << " dir = [a:dir]"
src << " layer = [a:layer]"
src << " suffix = \"[a:suffix]\""
src << " name = \"[a:name]\""
src << " text = \"[a:text]\""
src << " pixel_x = [a:pixel_x]"
src << " pixel_y = [a:pixel_y]"
src << " pixel_z = [a:pixel_z]"
src << " maptext = \"[a:maptext]\""
src << " maptext_width = [a:maptext_width]"
src << " maptext_height = [a:maptext_height]"
src << " blend_mode = [a:blend_mode]"
src << " alpha = [a:alpha]"
src << " color = \"[a:color]\""
src << " override = [a:override]"
var/matrix/m = a:transform
if(m)
if(m.a == 1 && m.d == 0 && m.b == 0 && m.e == 1 && m.c == 0 && m.f == 0)
src << " transform = [m] (\ref[m]) (identity)"
else
src << " transform = [m] (\ref[m])"
src << " \t\[ \[ [m.a]\t[m.d]\t0 \]"
src << " \t \[ [m.b]\t[m.e]\t0 \]"
src << " \t \[ [m.c]\t[m.f]\t1 \] \]"
src << "}"
i++
src << "<hr>"
My saving proc removes all overlays before saving, literally the first thing. I do start with a fresh mob.

I don't have a print overlays verb, but yours shows me that the overlay just isn't being removed upon unequip. I just can't find the syntax or logical error.

I modified Unequip() to this
        UnEquip(var/mob/User)
User.icon_state = "player"
User.overlays -= /Overlays/SwordEquip
src.icon_state = "sword"
src.suffix = null
var/list/L = src.overlays
L.Cut(1)
..()

I'm pretty sure lists are references, so the overlays should've been cleared, but still broken.
In response to Lugia319
So, if you repeatedly equip and unequip and sword, are you seeing the overlays build up in the debug printout?

Also, you're clearing the sword's overlays. Don't you want to be clearing the User's?

To be clear, you are now both adding by type and removing by type? If so, I can't imagine why they aren't matching up properly. This is gonna end up being something really silly, I just know it :P
I've tested it both ways.

Replacing the src with usr for the cut test worked (usr abuse OP), but I really don't know why adding/removing by type isn't working.

EDIT: And yes the overlay length is building.
Quite honestly, your whole equipment system is terrible. Why not just use an associated list to hold equipment in?
mob/var/list/equipment = list("head","chest","hands","legs","feet")

item
parent_type = /obj
var/slot
proc/equipHandler(var/mob/m)
var/item/i = m.equipment[src.slot]
if(!i) //if nothing's already equipped
//run src.equip(m)
else if(i && i == src) //if this item is already equipped
//run src.unequip(m)
else if(i && i != src) //if something else is already equipped
//run i.unequip(m) and then src.equip(m)


I just took your whole equipment system and shortened it by like 50 lines, and it still functions the same.