ID:2225068
 
(See the best response by Flick.)
Code:
obj
House_Cards
var
House = ""
Strength = 0
Swords = 0
Shields = 0
mob/Player/Owner
obj/SNSIcon

swordsNShields(var/obj/House_Cards/card)
var/count = 0
var/obj/Sword = new()
var/obj/Shield = new()
Sword.icon = icon('HUD.dmi',"Sword")
Shield.icon = icon('HUD.dmi',"Shield")
for(var/i = 1; i<=card.Swords; i++)
world<<"[card] has [i] swords."
Sword.step_x = 8 * count
card.SNSIcon.overlays+= Sword
count++
for(var/i = 1; i<=card.Shields; i++)
world<<"[card] has [i] Shields."
Shield.pixel_x += 8 * count
card.SNSIcon.overlays+=Shield
count++



Problem description:
AIM: If a House_Card has Swords = 3, I'd like three swords next to each other in one icon. If they have Swords = 1 and Shields = 1 I'd like a sword next to a shield.

Current state: Will add one sword and one shield, though they are placed directly on top of each other.

Question: How do I add the same object to overlays repeatedly? How do I shift an overlay to the right 8 pixels?

I'm a little sleep deprived (got a two week old daughter keeping me up :) ) so please pardon the idiocy of this query.
Your issue is that you're only creating one object (outside of the loops), you're also using step_x instead of pixel_x for your sword loop.

Instead of using objects you can use /image objects as well, to save a bit of overhead, they act about the same when used as overlays without all of the non-visual stuff attached to objects.
In response to Nadrew
It's fine to use the same object instance. Since only the appearance is added to overlays, changing the object won't affect the appearances already in overlays.

I agree that the main problem here was the usage of step_x instead of pixel_x.
step_x is a "physical" offset that only affects the physical position of something on the map.
pixel_x is a "visual" offset that only affects how the icon is displayed when on the map or in under/overlays (but not in the HUD because DM likes to be inconsistent).
In response to Kaiochao
Kaiochao wrote:
It's fine to use the same object instance. Since only the appearance is added to overlays, changing the object won't affect the appearances already in overlays.


True, but then you lose a reliable pointer to that appearance and have to do ugly looping and whatnot to remove it, but since they're not really keeping track anyways it's going to end up with the same result whether you use an image or an obj. Either way you do it you should probably be keeping track of whatever you do end up adding to overlays in case you need to use it again.
I only tried step_x because pixel_x didn't work. I've changed it back to pixel_x and still no dice.

I've previously tried exactly the same with images, and that didn't work either.

I also tried doing it with icons and icon arithmetic, and that resulted in nothing being displayed at all.

I fricking hate image/icon manipulation :P

And Nadrew, you're right: it would be best to keep track of them, but I only plan on running this proc once per game per card.
Make sure you're setting the layer of the objects appropriately as well.
In response to Nadrew
There's one vital piece of information I missed that I've just noticed: this object is being output to a grid. Don't know if that would affect anything but thought it worth mentioning.

I haven't done anything to the layers yet, but the icons are small enough that with the offset they shouldn't even overlap.

Also, if you have an overlay 32 pixels wide and it's offset by a pixel, does that make the icon for the entire object 33 pixels? If so, can a grid handle that?
In response to Ease
Grids don't support pixel offsets. I didn't think they even supported overlays at all. You would have to use icon.Blend with the sword and shield icons to make them appear. DarkCampainger has a "Get Flat Icon" library that is able to flatten overlays to a single icon object.
I'm going to try the library next, but I feel like that's overkill for what should be just a couple lines of code.

Here's where I'm at now:
proc
swordsNShields(var/obj/House_Cards/card)
var/count = 0
var/icon/Sword = new /icon('HUD.dmi',"Sword")
var/icon/Shield = new /icon('HUD.dmi',"Shield")
for(var/i = 1; i<=card.Swords; i++)
world<<"[card] has [i] swords."
card.SNSIcon.Blend(Sword,ICON_OVERLAY,8 * count)
count++
for(var/i = 1; i<=card.Shields; i++)
world<<"[card] has [i] Shields."
card.SNSIcon.Blend(Shield,ICON_OVERLAY,8 * count)
count++

usr << output("\icon[card.SNSIcon]", "myHouse:2,2")


obj
House_Cards
var
House = ""
Strength = 0
Swords = 0
Shields = 0
mob/Player/Owner
icon/SNSIcon
proc
effect()
New()
..()
SNSIcon = new()


And nothing appears at all :(
There's nothing wrong with using libraries
Best response
I'm at work so cant really test any of this...
var/list/card_cost_icons

proc/swordsNShields(obj/House_Cards/card)
if(!card_cost_icons) card_cost_icons = new
if(!card_cost_icons["[card.type]"])
var/icon/I = icon('blank.dmi') // Just a blank .dmi file with one blank icon in it.
var/num_Swords = card.Swords
var/num_Shields = card.Shields
var/icon/Sword = icon('Hud.dmi',"Sword")
var/icon/Shield = icon('Hud.dmi',"Shield")
var/width = num_Swords*Sword.Width()+num_Shields*Shield.Width())
var/height = max(Sword.Height(), Shield.Height())
I.Scale(width,height)
for(var/i in 1 to num_Swords)
I.Blend(Sword, ICON_OVERLAY)
if((i<num_Swords) || num_Shields)
I.Shift(EAST, Sword.Width())
for(var/i in 1 to num_Shields)
I.Blend(Shield, ICON_OVERLAY)
if(i<num_Shields)
I.Shift(EAST, Shield.Width())
card_cost_icons["[card.type]"] = I

usr << output("\icon[card_cost_icons["[card.type]"]", "myHouse:2,2")
Flick, you wonderful beast! Even more impressive considering you didn't even compile it to check! Thank you so much.

Here's how it looks thanks to you (they're in the third column of each grid):