mirror of
https://github.com/vgstation-coders/vgstation13.git
synced 2025-12-10 10:21:11 +00:00
fixes map rendering by sorting planes correctly (#17679)

This commit is contained in:
@@ -249,4 +249,18 @@ var/obj/abstract/screen/plane_master/clickmaster/clickmaster = new()
|
|||||||
appearance_flags = 0
|
appearance_flags = 0
|
||||||
plane = BASE_PLANE
|
plane = BASE_PLANE
|
||||||
|
|
||||||
var/obj/abstract/screen/plane_master/clickmaster_dummy/clickmaster_dummy = new()
|
var/obj/abstract/screen/plane_master/clickmaster_dummy/clickmaster_dummy = new()
|
||||||
|
|
||||||
|
// returns a list with the objects sorted depending on their layer, with the lowest objects being the first in the list and the highest objects being last
|
||||||
|
/proc/plane_layer_sort(var/list/to_sort)
|
||||||
|
var/list/sorted = list()
|
||||||
|
for(var/current_atom in to_sort)
|
||||||
|
var/compare_index
|
||||||
|
for(compare_index = sorted.len, compare_index > 0, --compare_index) // count down from the length of the list to zero.
|
||||||
|
var/atom/compare_atom = sorted[compare_index] // compare to the next object down the list.
|
||||||
|
if(compare_atom.plane < current_atom:plane) // is this object below our current atom?
|
||||||
|
break
|
||||||
|
else if((compare_atom.plane == current_atom:plane) && (compare_atom.layer <= current_atom:layer)) // is this object below our current atom?
|
||||||
|
break
|
||||||
|
sorted.Insert(compare_index+1, current_atom) // insert it just above the atom it was higher than - or at the bottom if it was higher than nothing.
|
||||||
|
return sorted // return the sorted list.
|
||||||
@@ -56,7 +56,6 @@ var/list/exception = list(
|
|||||||
proc/getFlatIcon(atom/A, dir, cache=1, exact=0) // 1 = use cache, 2 = override cache, 0 = ignore cache //exact = 1 means the atom won't be rotated if it's a lying mob/living/carbon
|
proc/getFlatIcon(atom/A, dir, cache=1, exact=0) // 1 = use cache, 2 = override cache, 0 = ignore cache //exact = 1 means the atom won't be rotated if it's a lying mob/living/carbon
|
||||||
|
|
||||||
|
|
||||||
var/list/layers = list() // Associative list of [overlay = layer]
|
|
||||||
var/hash = "" // Hash of overlay combination
|
var/hash = "" // Hash of overlay combination
|
||||||
|
|
||||||
if(is_type_in_list(A, directional)&&!is_type_in_list(A, exception))
|
if(is_type_in_list(A, directional)&&!is_type_in_list(A, exception))
|
||||||
@@ -82,65 +81,9 @@ proc/getFlatIcon(atom/A, dir, cache=1, exact=0) // 1 = use cache, 2 = override c
|
|||||||
var/image/copy = image(icon=A.icon,icon_state=A.icon_state,layer=A.layer,dir=dir)
|
var/image/copy = image(icon=A.icon,icon_state=A.icon_state,layer=A.layer,dir=dir)
|
||||||
initialimage[copy] = A.layer
|
initialimage[copy] = A.layer
|
||||||
|
|
||||||
|
var/list/layers = plane_layer_sort(A.underlays)
|
||||||
// Loop through the underlays, then overlays, sorting them into the layers list
|
|
||||||
var/list/process = A.underlays // Current list being processed
|
|
||||||
var/processSubset=0 // Which list is being processed: 0 = underlays, 1 = overlays
|
|
||||||
|
|
||||||
var/currentIndex=1 // index of 'current' in list being processed
|
|
||||||
var/currentOverlay // Current overlay being sorted
|
|
||||||
var/currentLayer // Calculated layer that overlay appears on (special case for FLOAT_LAYER)
|
|
||||||
|
|
||||||
var/compareOverlay // The overlay that the current overlay is being compared against
|
|
||||||
var/compareIndex // The index in the layers list of 'compare'
|
|
||||||
|
|
||||||
var/list/underlaysort = list()
|
|
||||||
var/list/overlaysort = list()
|
|
||||||
var/list/sorting = underlaysort
|
|
||||||
|
|
||||||
while(TRUE)
|
|
||||||
if(currentIndex<=process.len)
|
|
||||||
//All this does is find the appropriate layer and image
|
|
||||||
currentOverlay = process[currentIndex]
|
|
||||||
currentLayer = currentOverlay:layer
|
|
||||||
if(currentLayer<0) // Special case for FLY_LAYER
|
|
||||||
ASSERT(currentLayer > -1000)
|
|
||||||
if(processSubset == 0) // Underlay
|
|
||||||
currentLayer = A.layer+currentLayer/1000
|
|
||||||
else // Overlay
|
|
||||||
currentLayer = A.layer+(1000+currentLayer)/1000
|
|
||||||
|
|
||||||
//Next is a simple sort algorithm to place the overlay by layer
|
|
||||||
if(!sorting.len)
|
|
||||||
sorting[currentOverlay] = currentLayer
|
|
||||||
currentIndex++
|
|
||||||
continue
|
|
||||||
|
|
||||||
for(compareIndex=1,compareIndex<=sorting.len,compareIndex++)
|
|
||||||
compareOverlay = sorting[compareIndex]
|
|
||||||
if(currentLayer < sorting[compareOverlay]) // Associated value is the calculated layer
|
|
||||||
sorting.Insert(compareIndex,currentOverlay)
|
|
||||||
sorting[currentOverlay] = currentLayer
|
|
||||||
break
|
|
||||||
if(compareIndex>sorting.len) // Reached end of list without inserting
|
|
||||||
sorting[currentOverlay]=currentLayer // Place at end
|
|
||||||
|
|
||||||
currentIndex++
|
|
||||||
|
|
||||||
if(currentIndex>process.len)
|
|
||||||
if(processSubset == 0) // Switch to overlays
|
|
||||||
currentIndex = 1
|
|
||||||
processSubset = 1
|
|
||||||
process = A.overlays
|
|
||||||
sorting = overlaysort
|
|
||||||
else // All done
|
|
||||||
break
|
|
||||||
|
|
||||||
//Get flat icon previously understood layers as interspersing
|
|
||||||
//and could render overlays above the atom's icon before this following modification
|
|
||||||
layers = underlaysort
|
|
||||||
layers += initialimage
|
layers += initialimage
|
||||||
layers += overlaysort
|
layers += plane_layer_sort(A.overlays)
|
||||||
|
|
||||||
if(cache!=0) // If cache is NOT disabled
|
if(cache!=0) // If cache is NOT disabled
|
||||||
// Create a hash value to represent this specific flattened icon
|
// Create a hash value to represent this specific flattened icon
|
||||||
|
|||||||
@@ -32,7 +32,7 @@
|
|||||||
var/icon/img //Big photo image
|
var/icon/img //Big photo image
|
||||||
var/scribble //Scribble on the back.
|
var/scribble //Scribble on the back.
|
||||||
var/blueprints = FALSE //Does it include the blueprints?
|
var/blueprints = FALSE //Does it include the blueprints?
|
||||||
var/info //Info on the camera about mobs or some shit
|
var/info //Info on the camera about mobs or some shit
|
||||||
|
|
||||||
autoignition_temperature = 530 // Kelvin
|
autoignition_temperature = 530 // Kelvin
|
||||||
fire_fuel = TRUE
|
fire_fuel = TRUE
|
||||||
@@ -259,21 +259,9 @@
|
|||||||
continue
|
continue
|
||||||
atoms.Add(A)
|
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.plane < c.plane)
|
|
||||||
break
|
|
||||||
else if((c2.plane == c.plane) && (c2.layer <= c.layer))
|
|
||||||
break
|
|
||||||
sorted.Insert(j+1, c)
|
|
||||||
|
|
||||||
var/icon/res = get_base_photo_icon()
|
var/icon/res = get_base_photo_icon()
|
||||||
|
|
||||||
for(var/atom/A in sorted)
|
for(var/atom/A in plane_layer_sort(atoms))
|
||||||
var/icon/img = getFlatIcon(A,A.dir,0)
|
var/icon/img = getFlatIcon(A,A.dir,0)
|
||||||
if(istype(A, /mob/living) && A:lying)
|
if(istype(A, /mob/living) && A:lying)
|
||||||
img.Turn(A:lying)
|
img.Turn(A:lying)
|
||||||
@@ -310,21 +298,9 @@
|
|||||||
else
|
else
|
||||||
atoms.Add(A)
|
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.plane < c.plane)
|
|
||||||
break
|
|
||||||
else if((c2.plane == c.plane) && (c2.layer <= c.layer))
|
|
||||||
break
|
|
||||||
sorted.Insert(j+1, c)
|
|
||||||
|
|
||||||
var/icon/res = get_base_photo_icon()
|
var/icon/res = get_base_photo_icon()
|
||||||
|
|
||||||
for(var/atom/A in sorted)
|
for(var/atom/A in plane_layer_sort(atoms))
|
||||||
var/icon/img = getFlatIcon(A,A.dir,0)
|
var/icon/img = getFlatIcon(A,A.dir,0)
|
||||||
if(istype(A, /mob/living) && A:lying)
|
if(istype(A, /mob/living) && A:lying)
|
||||||
img.Turn(A:lying)
|
img.Turn(A:lying)
|
||||||
|
|||||||
@@ -69,41 +69,16 @@
|
|||||||
if(!allturfcontents.len)
|
if(!allturfcontents.len)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
//Initializing our layer sorting variables
|
|
||||||
var/list/sorting = list()
|
|
||||||
var/atom/currentAtom = allturfcontents[1]
|
|
||||||
var/currentLayer
|
|
||||||
sorting[allturfcontents[1]] = currentAtom.layer
|
|
||||||
allturfcontents -= currentAtom
|
|
||||||
var/currentIndex = 1
|
|
||||||
var/compareIndex = 1
|
|
||||||
|
|
||||||
if(allturfcontents.len)
|
|
||||||
//Simple insertion sort, simple variant of the form in getflaticon
|
|
||||||
while(currentIndex <= allturfcontents.len)
|
|
||||||
currentAtom = allturfcontents[currentIndex]
|
|
||||||
currentLayer = currentAtom.layer
|
|
||||||
|
|
||||||
for(compareIndex=1,compareIndex<=sorting.len,compareIndex++)
|
|
||||||
if(currentLayer < sorting[sorting[compareIndex]])
|
|
||||||
sorting.Insert(compareIndex,currentAtom)
|
|
||||||
sorting[currentAtom] = currentLayer
|
|
||||||
break
|
|
||||||
if(compareIndex>sorting.len)
|
|
||||||
sorting[currentAtom]=currentLayer
|
|
||||||
|
|
||||||
currentIndex++
|
|
||||||
|
|
||||||
//Preparing to blend get flat icon of
|
//Preparing to blend get flat icon of
|
||||||
for(var/atom/A in sorting)
|
for(var/A in plane_layer_sort(allturfcontents))
|
||||||
var/icon/icontoblend = getFlatIcon(A = A, dir = A.dir, cache = 0)
|
var/icon/icontoblend = getFlatIcon(A,A:dir, cache = 0)
|
||||||
map_icon.Blend(icontoblend, ICON_OVERLAY, ((a-1)*WORLD_ICON_SIZE)+1, ((b-1)*WORLD_ICON_SIZE)+1)
|
map_icon.Blend(icontoblend, ICON_OVERLAY, ((a-1)*WORLD_ICON_SIZE)+1, ((b-1)*WORLD_ICON_SIZE)+1)
|
||||||
sleep(-1)
|
sleep(-1)
|
||||||
|
|
||||||
for(var/atom/A in pixel_shift_objects)
|
for(var/A in pixel_shift_objects)
|
||||||
var/icon/icontoblend = getFlatIcon(A = A, dir = A.dir, cache = 0)
|
var/icon/icontoblend = getFlatIcon(A, A:dir, cache = 0)
|
||||||
//This part is tricky since we've skipped a and b, since these are map objects they have valid x,y. a and b should be the modulo'd value of x,y with icon_size
|
//This part is tricky since we've skipped a and b, since these are map objects they have valid x,y. a and b should be the modulo'd value of x,y with icon_size
|
||||||
map_icon.Blend(icontoblend, ICON_OVERLAY, (((A.x % icon_size)-1)*WORLD_ICON_SIZE)+1+A.pixel_x, (((A.y % icon_size)-1)*WORLD_ICON_SIZE)+1+A.pixel_y)
|
map_icon.Blend(icontoblend, ICON_OVERLAY, (((A:x % icon_size)-1)*WORLD_ICON_SIZE)+1+A:pixel_x, (((A:y % icon_size)-1)*WORLD_ICON_SIZE)+1+A:pixel_y)
|
||||||
|
|
||||||
if(y >= world.maxy)
|
if(y >= world.maxy)
|
||||||
map_icon.DrawBox(rgb(255,255,255,255), x1 = 1, y1 = 1, x2 = WORLD_ICON_SIZE*icon_size, y2 = WORLD_ICON_SIZE*(icon_size-world.maxy % icon_size))
|
map_icon.DrawBox(rgb(255,255,255,255), x1 = 1, y1 = 1, x2 = WORLD_ICON_SIZE*icon_size, y2 = WORLD_ICON_SIZE*(icon_size-world.maxy % icon_size))
|
||||||
@@ -119,3 +94,5 @@
|
|||||||
if(fexists(resultpath))
|
if(fexists(resultpath))
|
||||||
fdel(resultpath)
|
fdel(resultpath)
|
||||||
fcopy(result_icon, resultpath)
|
fcopy(result_icon, resultpath)
|
||||||
|
to_chat(world, "<b>The map has been rendered successfully<b>")
|
||||||
|
src << sound('sound/effects/maprendercomplete.ogg')
|
||||||
|
|||||||
BIN
sound/effects/maprendercomplete.ogg
Normal file
BIN
sound/effects/maprendercomplete.ogg
Normal file
Binary file not shown.
Reference in New Issue
Block a user