Merge pull request #4860 from Citadel-Station-13/upstream-merge-34199

[MIRROR] Makes getFlatIcon slower. (Also more precise)
This commit is contained in:
LetterJay
2018-01-16 13:46:52 -06:00
committed by GitHub
4 changed files with 63 additions and 50 deletions

View File

@@ -72,3 +72,9 @@ GLOBAL_VAR_INIT(cmp_field, "name")
/proc/cmp_profile_count_dsc(list/A, list/B)
return B[PROFILE_ITEM_COUNT] - A[PROFILE_ITEM_COUNT]
/proc/cmp_atom_layer_asc(atom/A,atom/B)
if(A.plane != B.plane)
return A.plane - B.plane
else
return A.layer - B.layer

View File

@@ -714,7 +714,7 @@ The _flatIcons list is a cache for generated icon files.
*/
// Creates a single icon from a given /atom or /image. Only the first argument is required.
/proc/getFlatIcon(image/A, defdir=A.dir, deficon=A.icon, defstate=A.icon_state, defblend=A.blend_mode)
/proc/getFlatIcon(image/A, defdir, deficon, defstate, defblend, start = TRUE)
// We start with a blank canvas, otherwise some icon procs crash silently
var/icon/flat = icon('icons/effects/effects.dmi', "nothing") // Final flattened icon
if(!A)
@@ -723,6 +723,16 @@ The _flatIcons list is a cache for generated icon files.
return flat
var/noIcon = FALSE
if(start)
if(!defdir)
defdir = A.dir
if(!deficon)
deficon = A.icon
if(!defstate)
defstate = A.icon_state
if(!defblend)
defblend = A.blend_mode
var/curicon
if(A.icon)
curicon = A.icon
@@ -745,10 +755,31 @@ The _flatIcons list is a cache for generated icon files.
noIcon = TRUE // Do not render this object.
var/curdir
if(A.dir != 2)
curdir = A.dir
else
var/base_icon_dir //We'll use this to get the icon state to display if not null BUT NOT pass it to overlays as the dir we have
//These should use the parent's direction (most likely)
if(!A.dir || A.dir == SOUTH)
curdir = defdir
else
curdir = A.dir
//Let's check if the icon actually contains any diagonals, just skip if it's south to save (lot of) time
if(curdir != SOUTH)
var/icon/test_icon
var/directionals_exist = FALSE
var/list/dirs_to_check = GLOB.cardinals - SOUTH
outer:
for(var/possible_dir in dirs_to_check)
test_icon = icon(curicon,curstate,possible_dir,frame=1)
for(var/x in 1 to world.icon_size)
for(var/y in 1 to world.icon_size)
if(!isnull(test_icon.GetPixel(x,y)))
directionals_exist = TRUE
break outer
if(!directionals_exist)
base_icon_dir = SOUTH
if(!base_icon_dir)
base_icon_dir = curdir
var/curblend
if(A.blend_mode == BLEND_DEFAULT)
@@ -761,7 +792,7 @@ The _flatIcons list is a cache for generated icon files.
var/image/copy
// Add the atom's icon itself, without pixel_x/y offsets.
if(!noIcon)
copy = image(icon=curicon, icon_state=curstate, layer=A.layer, dir=curdir)
copy = image(icon=curicon, icon_state=curstate, layer=A.layer, dir=base_icon_dir)
copy.color = A.color
copy.alpha = A.alpha
copy.blend_mode = curblend
@@ -813,10 +844,16 @@ The _flatIcons list is a cache for generated icon files.
var/icon/add // Icon of overlay being added
// Current dimensions of flattened icon
var/{flatX1=1;flatX2=flat.Width();flatY1=1;flatY2=flat.Height()}
// Dimensions of overlay being added
var/{addX1;addX2;addY1;addY2}
// Current dimensions of flattened icon
var/flatX1=1
var/flatX2=flat.Width()
var/flatY1=1
var/flatY2=flat.Height()
// Dimensions of overlay being added
var/addX1
var/addX2
var/addY1
var/addY2
for(var/V in layers)
var/image/I = V
@@ -825,9 +862,9 @@ The _flatIcons list is a cache for generated icon files.
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)
add = icon(I.icon, I.icon_state, base_icon_dir)
else // 'I' is an appearance object.
add = getFlatIcon(new/image(I), curdir, curicon, curstate, curblend)
add = getFlatIcon(new/image(I), curdir, curicon, curstate, curblend, FALSE)
// Find the new dimensions of the flat icon to fit the added overlay
addX1 = min(flatX1, I.pixel_x+1)
@@ -849,7 +886,7 @@ The _flatIcons list is a cache for generated icon files.
if(A.alpha < 255)
flat.Blend(rgb(255, 255, 255, A.alpha), ICON_MULTIPLY)
return icon(flat, "", curdir)
return icon(flat, "", SOUTH)
/proc/getIconMask(atom/A)//By yours truly. Creates a dynamic mask for a mob/whatever. /N
var/icon/alpha_mask = new(A.icon,A.icon_state)//So we want the default icon and icon state of A.

View File

@@ -73,30 +73,6 @@
alarmed.burglaralert(src)
playsound(src, 'sound/effects/alert.ogg', 50, 1)
/*
*/
/obj/structure/displaycase/proc/is_directional(atom/A)
try
getFlatIcon(A,defdir=4)
catch
return 0
return 1
/obj/structure/displaycase/proc/get_flat_icon_directional(atom/A)
//Get flatIcon even if dir is mismatched for directionless icons
//SLOW
var/icon/I
if(is_directional(A))
I = getFlatIcon(A)
else
var/old_dir = A.dir
A.setDir(2)
I = getFlatIcon(A)
A.setDir(old_dir)
return I
/obj/structure/displaycase/update_icon()
var/icon/I
if(open)
@@ -106,7 +82,7 @@
if(broken)
I = icon('icons/obj/stationobjs.dmi',"glassboxb0")
if(showpiece)
var/icon/S = get_flat_icon_directional(showpiece)
var/icon/S = getFlatIcon(showpiece)
S.Scale(17,17)
I.Blend(S,ICON_UNDERLAY,8,8)
src.icon = I

View File

@@ -190,7 +190,7 @@
/obj/item/device/camera/proc/camera_get_icon(list/turfs, turf/center)
var/atoms[] = list()
var/list/atoms = list()
for(var/turf/T in turfs)
atoms.Add(T)
for(var/atom/movable/A in T)
@@ -203,15 +203,7 @@
continue
atoms.Add(A)
var/list/sorted = list()
var/j
for(var/i = 1 to atoms.len)
var/atom/c = atoms[i]
for(j = sorted.len, j > 0, --j)
var/atom/c2 = sorted[j]
if(c2.layer <= c.layer)
break
sorted.Insert(j+1, c)
var/list/sorted = sortTim(atoms,/proc/cmp_atom_layer_asc)
var/icon/res = icon('icons/effects/96x96.dmi', "")
@@ -222,8 +214,8 @@
if(L.lying)
img.Turn(L.lying)
var/offX = 32 * (A.x - center.x) + A.pixel_x + 33
var/offY = 32 * (A.y - center.y) + A.pixel_y + 33
var/offX = world.icon_size * (A.x - center.x) + A.pixel_x + 33
var/offY = world.icon_size * (A.y - center.y) + A.pixel_y + 33
if(ismovableatom(A))
var/atom/movable/AM = A
offX += AM.step_x
@@ -235,7 +227,9 @@
blueprints = 1
for(var/turf/T in turfs)
res.Blend(getFlatIcon(T.loc), blendMode2iconMode(T.blend_mode), 32 * (T.x - center.x) + 33, 32 * (T.y - center.y) + 33)
var/area/A = T.loc
if(A.icon_state)//There's actually something to blend in.
res.Blend(getFlatIcon(A), blendMode2iconMode(A.blend_mode), world.icon_size * (T.x - center.x) + 33, world.icon_size * (T.y - center.y) + 33)
return res