From bdbc404d07867a5b83f598f60c2d5dc7cbabc5cb Mon Sep 17 00:00:00 2001 From: JimTheCactus Date: Mon, 28 Jul 2014 01:04:52 -0600 Subject: [PATCH] Added workaround for non-directional icons with dir!=2 Several items in the map are set with a dir other than 2 but the icon associated with the item doesn't have directions. As such they misrender. This resolves that specific issue, for the most part. Due to an odd behavior of Byond, when this circumstance occurs the icon proc produces a 32x32 image that is all alpha 0. At least that's what my testing suggests; it may be possible with large icons to encounter this as an issue and cause it to ignore an icon that should be reloaded from the default. However, this can't do any worse than the current software. --- code/__HELPERS/icons.dm | 31 ++++++++++++++++++++++++++- code/modules/paperwork/photography.dm | 15 +++++++------ 2 files changed, 38 insertions(+), 8 deletions(-) diff --git a/code/__HELPERS/icons.dm b/code/__HELPERS/icons.dm index 65807c0575..b0bc3091e6 100644 --- a/code/__HELPERS/icons.dm +++ b/code/__HELPERS/icons.dm @@ -684,6 +684,10 @@ proc // Creates a single icon from a given /atom or /image. Only the first argu if(!noIcon) world.log << "***Rendering Icon [A.type] in state '[curstate]' on layer [A.layer] in direction [curdir]" // #JMO copy = image(icon=curicon, icon_state=curstate, layer=A.layer, dir=curdir) + if (isnull(copy)) // #JMO + world.log << "****Created a null!" // #JMO + else // #JMO + world.log << "****Created a thing of type [copy.type]" // #JMO copy.color = A.color copy.alpha = A.alpha copy.blend_mode = curblend @@ -744,6 +748,31 @@ proc // Creates a single icon from a given /atom or /image. Only the first argu if(I == copy) // 'I' is an /image based on the object being flattened. curblend = BLEND_OVERLAY add = icon(I:icon, I:icon_state, I:dir) + // This checks for a silent failure mode of the icon routine. If the requested dir + // doesn't exist in this icon state it returns a 32x32 icon with 0 alpha. + if (I:dir != SOUTH && add.Width() == 32 && add.Height() == 32) + // Since checking every pixel for blank isn't trivial, we make some assumptions about + // the content of the image to determine if it actually is blank. On a rare occassions + // this will cause the software to return a non-directional icon for when a + // directionalized one would be more appropriate. This is rare enough that this + // will suffice in place of a map rework that properly normalizes directions. + var/blankpixel=1; + // Check the four corners... + blankpixel &= isnull(add.GetPixel(1,1)) + blankpixel &= isnull(add.GetPixel(32,1)) + blankpixel &= isnull(add.GetPixel(32,32)) + blankpixel &= isnull(add.GetPixel(32,1)) + // The thirds... + blankpixel &= isnull(add.GetPixel(11,11)) + blankpixel &= isnull(add.GetPixel(11,22)) + blankpixel &= isnull(add.GetPixel(22,22)) + blankpixel &= isnull(add.GetPixel(22,11)) + // and the center... + blankpixel &= isnull(add.GetPixel(16,16)) + // If we ALWAYS returned a null (which happens when GetPixel encounters something with alpha 0) + if (blankpixel) + // Pull the default direction. + add = icon(I:icon, I:icon_state) else // 'I' is an appearance object. world.log << "***Recursing to render Icon [I:type] in state '[curstate]' in direction [curdir]" // #JMO add = getFlatIcon(new/image(I), curdir, curicon, curstate, curblend) @@ -819,4 +848,4 @@ proc/adjust_brightness(var/color, var/value) RGB[1] = Clamp(RGB[1]+value,0,255) RGB[2] = Clamp(RGB[2]+value,0,255) RGB[3] = Clamp(RGB[3]+value,0,255) - return rgb(RGB[1],RGB[2],RGB[3]) \ No newline at end of file + return rgb(RGB[1],RGB[2],RGB[3]) diff --git a/code/modules/paperwork/photography.dm b/code/modules/paperwork/photography.dm index c2399a3f04..67e5eb76e8 100644 --- a/code/modules/paperwork/photography.dm +++ b/code/modules/paperwork/photography.dm @@ -152,7 +152,7 @@ ..() -/obj/item/device/camera/proc/get_icon(turf/the_turf as turf) +/obj/item/device/camera/proc/get_icon(turf/the_turf as turf,mob/user as mob) //#JMO Added mob/user for debug for debug //Bigger icon base to capture those icons that were shifted to the next tile //i.e. pretty much all wall-mounted machinery var/icon/res = icon('icons/effects/96x96.dmi', "") @@ -184,14 +184,16 @@ for(var/i; i <= sorted.len; i++) var/atom/A = sorted[i] if(A) - world.log << "**Calling getFlatIcon to render [A.type]" //#JMO + world.log << "**Calling getFlatIcon to render [A]" //#JMO var/icon/img = getFlatIcon(A)//build_composite_icon(A) + // Check if we're looking at a mob that's lying down if(istype(A, /mob/living) && A:lying) - world.log << "[A.type] is lying down. Making it look as such..." // #JMO; + world.log << "[A] is lying down. Making it look as such..." // #JMO; + // If they are, apply that effect to their picture. img.BecomeLying() - //if(istype(img, /icon)) - res.Blend(img, blendMode2iconMode(A.blend_mode), 33 + A.pixel_x, 33 + A.pixel_y) + if(istype(img, /icon)) + res.Blend(img, blendMode2iconMode(A.blend_mode), 33 + A.pixel_x, 33 + A.pixel_y) return res @@ -225,7 +227,6 @@ var/icon/temp = icon('icons/effects/96x96.dmi',"") var/icon/black = icon('icons/turf/space.dmi', "black") var/mobs = "" - world << "Proof that this thing is alive! 1.0" // #JMO for(var/i = 1; i <= 3; i++) for(var/j = 1; j <= 3; j++) var/turf/T = locate(x_c, y_c, z_c) @@ -234,7 +235,7 @@ if(user.client) //To make shooting through security cameras possible viewer = user.client.eye if(dummy in viewers(world.view, viewer)) - temp.Blend(get_icon(T), ICON_OVERLAY, 32 * (j-1-1), 32 - 32 * (i-1)) + temp.Blend(get_icon(T,user), ICON_OVERLAY, 32 * (j-1-1), 32 - 32 * (i-1)) else temp.Blend(black, ICON_OVERLAY, 32 * (j-1), 64 - 32 * (i-1)) mobs += get_mobs(T)