ID:2065076
 
BYOND Version:509
Operating System:Windows 10 Pro 64-bit
Web Browser:Chrome 49.0.2623.110
Applies to:Dream Daemon
Status: Open

Issue hasn't been assigned a status value.
Descriptive Problem Summary:
icon() is returning all 4 dirs when used to extract 1 dir from another /icon.

Numbered Steps to Reproduce Problem:
People weren't able to reproduce this in a small test case, but I can definitely reproduce it on my repo.

The very specific line which is breaking is icon(A.icon, A.icon_state, SOUTH, 1). It works, except when A is a human, whose icon undergoes a ton of icon operations to build it.

  • 1. Download https://github.com/PJB3005/vgstation13/tree/Lummox-debug as zip
  • 2. Copy /config-example/admins.txt and admin_ranks.txt into /config, add '[ckey] - Host' to the copied admins.txt to make yourself admin.
  • 3. Compile, run in DD and join.
  • 4. Use the "Start Now" verb (server tab)
  • 5. Examine yourself (shift click or right click -> examine)
  • 6. Due to a debug line I placed in that branch the icons outputted to the chat now get outputted to /data/icon-debug-[state], all icons are 1 dir, except mysteriously the icon humans use.

Repeating step 5 for other objects does work.

Code Snippet (if applicable) to Reproduce Problem:
See above

Expected Results:
icon() to consistently extract 1 dir.

Actual Results:
icon() returns all 4 dirs on specific icons. The only thing I can think of that could cause this is the tons of icon operations such as blending and mapColors done on the icons this happens for.

Does the problem occur:
Every time? Or how often? Every time.
In other games? No idea
In other user accounts? Yes
On other computers? Yes

When does the problem NOT occur?
All icons except the specific ones that it does occur on.

Did the problem NOT occur in any earlier versions? If so, what was the last version that worked?
Untested

Workarounds:
No idea, really.
workaround is to icon.Insert it onto a blank icon()
Alright once I'm back home I'll try that, thanks!
If you can isolate the exact icon operations done on this icon, then logically it should be possible to make this happen in a smaller test case. Debugging icon operations live within a game the size of SS13 is probably not feasible.
Alright I'll make a full list of operations that get done to achieve the resulting icon.
This should be all the icon operations the code goes through to make the base icon of a male, non-fat human with a skin tone of 0 and no underwear.
// icon gotten from chest organ:
stand_icon = icon('icons/mob/human_races/r_human.dmi', "torsom")
// All organs are blended ontop:
stand_icon.Blend(icon('icons/mob/human_races/r_human.dmi', "groinm"), ICON_OVERLAY)
stand_icon.Blend(icon('icons/mob/human_races/r_human.dmi', "headm"), ICON_OVERLAY)
stand_icon.Blend(icon('icons/mob/human_races/r_human.dmi', "l_arm"), ICON_OVERLAY)
stand_icon.Blend(icon('icons/mob/human_races/r_human.dmi', "r_arm"), ICON_OVERLAY)
// r_leg gets blended on, see below.
// l_leg gets blended on, see below.
stand_icon.Blend(icon('icons/mob/human_races/r_human.dmi', "l_hand"), ICON_OVERLAY)
stand_icon.Blend(icon('icons/mob/human_races/r_human.dmi', "r_hand"), ICON_OVERLAY)
// l_foot gets blended on, see below.
// r_foot gets blended on, see below.
stand_icon.Blend(rgb(s_tone, s_tone, s_tone), ICON_ADD) // s_tone is 0 since the skin tone for this example is 0
// Eyes get blended on:
var/icon/eyes = new/icon('icons/mob/human_face.dmi', "eyes_s")
eyes.Blend(Blend(rgb(r_eyes, g_eyes, b_eyes), ICON_ADD)) // r_eyes, g_eyes, b_eyes are the RGB values of the eyes.
stand_icon.Blend(eyes, ICON_OVERLAY)

// And finally make stand_icon our icon.
icon = stand_icon

// This is the block of code used to blend on the legs and feet.
// [left_organ] and [right_organ] are true if the body part is left or right, respectively.
var/icon/temp = icon('icons/mob/human_races/r_human.dmi', "[ORGAN_NAME]")
var/icon/temp2 = new('icons/mob/human.dmi',"blank") // Note: "blank" is literally completely blank.
temp2.Insert(new/icon(temp,dir=NORTH),dir=NORTH)
temp2.Insert(new/icon(temp,dir=SOUTH),dir=SOUTH)
if(![left_organ])
temp2.Insert(new/icon(temp,dir=EAST),dir=EAST)
if(![right_organ])
temp2.Insert(new/icon(temp,dir=WEST),dir=WEST)
stand_icon.Blend(temp2, ICON_OVERLAY)
temp2 = new('icons/mob/human.dmi',"blank")
if([left_organ])
temp2.Insert(new/icon(temp,dir=EAST),dir=EAST)
if([right_organ])
temp2.Insert(new/icon(temp,dir=WEST),dir=WEST)
stand_icon.Blend(temp2, ICON_UNDERLAY)


File with the actual code for reference: https://github.com/PJB3005/vgstation13/blob/Lummox-debug/ code/modules/mob/living/carbon/human/update_icons.dm#L176
In response to MrStonedOne
MrStonedOne wrote:
workaround is to icon.Insert it onto a blank icon()

Didn't work, sadly.

Code I used, no difference:
var/icon/temp = I
I = icon()
I.Insert(temp)
var/icon/temp = I
I = icon()
I.Insert(temp, icon_state, SOUTH, 1)