Well here it goes, most of this stuff is copy/pasted from my Megaman source and I commented out the lines so it'll make it easier to understand and modify for you own purpose.
Overlay code:
//This is defined for atom/movable, but it could be changed based on what you need it for.
atom/movable
//The Overlays list, that will have our overlays in readable datums.
var/list/Overlays
proc
//This proc only accepts only /image arguments
overlayAdd()
//Checks if the list is initialized, and if not, the list gets initialized
if(!Overlays)Overlays=new
//Loops through all the /image objects in the arguments
for(var/image/I in args)
//Adds each one to the Overlays list
Overlays.Add(I)
//Call the update proc
overlayUpdate()
//All the arguments can either be text strings
//that correspond to the tag on a /image object in the Overlays list
//or /image objects that are equivalent to objects already existing in the list.
overlayRem()
//Loops through the arguments
for(var/o in args)
//Checks to make sure there's something in the Overlays list
if(Overlays && Overlays.len)
//Variable I that is of type /image
var/image/I
//The following if checks if the argument is a tag,
//and if so, it will use locate() to retrieve an image with that tag.
if(istext(o))
I=locate(o)
//The following else if checks if the argument is an image
//and if so it set's I equal to the argument
else if(istype(o,/image))
I=o
//Removes I from the Overlays list and checks if the Overlays list should
//be cleaned up.
Overlays.Remove(I)
if(!Overlays.len)Overlays=null
else
//Breaks if there is nothing in the Overlays list to remove
break
//Call the update proc
overlayUpdate()
//This proc should be called whenever the Overlays list is updated,
//or if anything inside the Overlays list is updated.
overlayUpdate()
//Nulls overlays list
overlays=null
//Searches for all the /image objects in the Overlays list,
//and adds it to the overlays list.
for(var/image/I in Overlays)
overlays.Add(I)
//This proc is pretty self-explanatory, it returns a /image given certain arguments
proc/Image(icon/icon,icon_state,atom/loc,pixel_x=0,pixel_y=0,layer=FLY_LAYER,tag)
var/image/I=new
I.icon=icon
I.icon_state=icon_state
I.loc=loc
I.pixel_x=pixel_x
I.pixel_y=pixel_y
I.layer=layer
I.tag=tag
return I
Some simple examples of use:
overlayAdd(Image('sword.dmi'))
//with icon_state
overlayAdd(Image('sword.dmi',"wield"))
This method of handling overlays is foolproof and works every time given that you use it correctly. (It has worked for me every time, but this code is altered from the actual code I use in my game, so it'd be great if someone tested it and let me know if it works well.)