mirror of
https://github.com/yogstation13/Yogstation.git
synced 2025-02-26 09:04:50 +00:00
* why no work angy * weird errors shit sucks * fixved it I can spell good * fix? POSSIBLY * nope wasnt this * no more immutable thhanks koffee * ok ok * removes all the pref stuff ""removes"" * remove this idiot * this goes bye bye * these go too genius * bye bye * better night vision * tries to fix camera maybe * ok fuck it we ball we ball * ok lets go back go back go back go back * WORK DAMNIT * ha fuc kyou * this maybe * this doesnt work :( * maybe fix maybe * fucks everything why do i do this * test update test * Revert "tries to fix camera" This reverts commit2d14fbae66. * reverts everything I just did peko pain * bye bitch * oh yeah add this I guess * Fucks up the camera net + chunk why * test maybe revert * Revert "test maybe revert" This reverts commit98c5ef1b93. * Revert "Fucks up the camera net + chunk" This reverts commit0e421ebf5f. * this isnt going well uh oh * Attempts to rework out security camera and probably more * Revert "this isnt going well" This reverts commit1d8ceac867. * Revert "Revert "this isnt going well"" This reverts commite26fb61415. * ok ok * Revert "ok" This reverts commit7e7a7f8372. * Revert "Merge remote-tracking branch 'upstream/master' into NahI'dPortit" This reverts commit01094731c1, reversing changes made toc0cf69ebf1. * this doesn't need to be redefined I guess * no we need this totally * a familiar pain * 515 is L * yeah yeah * ok god fine * bye bye basemap :( doesnt work on runtime station * Fixes AI statis not working god im good * remove this oh god * Revert "Revert "Merge remote-tracking branch 'upstream/master' into NahI'dPortit"" This reverts commitb3fb3ba0db. * proves to god I exist and im pissed * yog exclusive feature (tm) plane master * bring this back from previous push * updates vendor emissives as well as firealarms * Updates barsign and fucks everything up * Fixes barsigns breaks all lights and updates barsigns to be machines and not structures We will address this in a later patch * not sure who changed that oh well * yeah this got moved * this needs updating yeah * turns off the carbon monoxide alarm duh * FIXES IT YES thank you biome * turns this off too yeah * Can't compile yet but ports a ton of shit * L * the game opens ig * extra shit * fixes * signals and smooth queue * look ma im going horribly out of scope * fixes chasms * this fixed nothing * ??? * more barsigns for later * forgive me cowboy. also fuck diagonals * oops we need this apparently * fuck it we ball * Update _lists.dm * Update icon_smoothing.dm * it now works kinda * Update atom_initializing_EXPENSIVE.dm * lighting don't work * we have light * sort turfs better * big fucking reorganize * like everything except templates * boy i sure hope nothing bad happens to these bar templates * we're back * no runtimes baby * no errors * shuttles are almost fixed i think * Revert "shuttles are almost fixed i think" This reverts commit046058827c. * Revert "Merge remote-tracking branch 'upstream/master' into icon_smoothing" This reverts commit863e1b776d, reversing changes made to884623e600. * Revert "no errors" This reverts commit884623e600. * too far back i think * midround smoothing runtimes fixed i think * comment cleanup * should fix the component runtimes * Revert "Revert "Merge remote-tracking branch 'upstream/master' into icon_smoothing"" This reverts commita8ff8d63aa. * NO RUNTIMES AND ICEMETA WORKS LET'S GOOOOOO * please stay fixed icemeta * organizing render dms * woops this too in the reorganizing * cryo fixed * nah, i'd win * parallax isn't my problem * pls don't break icemeta * runtime station gets a cam console * well it compiles * maybe fix the map * woops * man i hate maps * was that it? * PLEASE * missing focus tests * maybe that was it * maybe * let's take the batteries out of the carbon monoxide detector * fuck osha * i hate vending machines * that's not a computer * slot machine fix * PLEASE * that wasn't supposed to be there * fuck it i can't fix everything at once * BLUESPACE LOCKER? * literally why * hhh * does this fix chasms? * that should fix bad index * please? * turf_flags for reservations * haha oops * yolo (kill me) * fix wood walls and other walls * fix stairs * that might have fixed shittles * baseturfs are good now i think * should fix plasma windows * decals fixed * please fix changelog * shuttle lighting still fucky * lighting is stinky slow and doesn't finish updating by the time the server starts guh * lighting seemingly works * slipping works * shuttle sounds, slips, and windoors fixed * why am i here * fuck the changelog * of course someone touched smoothing as i'm almost done * we good? * updating ai_eye and rename * z updates and more ai cam updates * ice fixed * weather and ice fix * clockies can see and other clean up catches * windows fixed * cowbot forgive me i'm trying to update flashlights to tg because there's no light on lower multi-z z's like ice meta bottom floor * movable lighting works on multi-z * gps fix * item stacking from drag works * falsewall fix * job panel fixed * AI HANDLED * woops that comment should be gone * i hate ai i hate ai * brass glass visible again * vents on top of tiles now * sigdrobe sprite back * centcomm portals work * portals and see openspace mapping icons fixed * icemeta my behated * kill * is that it * lighting cutoff is old hat * angery overlay * not super necessary * also extra but whatever * ticker but thicker * job fix i hope * this isn't needed anymore * latejoin fix? * laserpointer, pipecrawl, and some consoles fixed * i hate fixing bugs as they're made * we're not ready for that * redef cleanup * gps arrows, gun flashlights, shuttle console placement, multi-z pulling fixed * goofy ah gun code * this was a good idea and necessary * should fix caltrop component * does this please the linter * linter please accept this async function * THERE * take the batteries out * make it stop * cowbot stopped me from letting ghosts dab * recycler loc fix * fix border firedoors not blocking movement * should fix screen fade out and fade in on round start and end * darker command tile trim and fixed bronze wall sprites * fuck you linter * railings actually stop you from leaving * probably fixes gibtonite overlay when struck * armaments dispenser and clockwork catwalk * turbine fix probably * pointing at inhand items should be fixed * fix overwatch app * should hopefully fix cable rotation on shuttle move * flashlights have better directionality logic * hopefully fixes shuttle atmos on move * grilles fixed * hopefully this fixes shuttle buttons, airolocks, and other machinery not working after moving * ice meta mining area finally not freezing * fix lightbulb icons not updating * lava mask and lighting dots * we actually have this * fuck glowshrooms GC * fix light fixture interactions and icon updates * hopefully catches all the updates * lava lighting good to go * seclite was missing inhands * smoothing in replays * light updates accurate in replays * biome's multi-z requests --------- Co-authored-by: cowbot92 <75333826+cowbot92@users.noreply.github.com> Co-authored-by: Molti <gamingjoelouis@gmail.com> Co-authored-by: Ringalong <53777086+JohnFulpWillard@users.noreply.github.com>
678 lines
23 KiB
Plaintext
678 lines
23 KiB
Plaintext
|
|
//generic (by snowflake) tile smoothing code; smooth your icons with this!
|
|
/*
|
|
Each tile is divided in 4 corners, each corner has an appearance associated to it; the tile is then overlayed by these 4 appearances
|
|
To use this, just set your atom's 'smoothing_flags' var to 1. If your atom can be moved/unanchored, set its 'can_be_unanchored' var to 1.
|
|
If you don't want your atom's icon to smooth with anything but atoms of the same type, set the list 'canSmoothWith' to null;
|
|
Otherwise, put all the smoothing groups you want the atom icon to smooth with in 'canSmoothWith', including the group of the atom itself.
|
|
Smoothing groups are just shared flags between objects. If one of the 'canSmoothWith' of A matches one of the `smoothing_groups` of B, then A will smooth with B.
|
|
|
|
Each atom has its own icon file with all the possible corner states. See 'smooth_wall.dmi' for a template.
|
|
|
|
DIAGONAL SMOOTHING INSTRUCTIONS
|
|
To make your atom smooth diagonally you need all the proper icon states (see 'smooth_wall.dmi' for a template) and
|
|
to add the 'SMOOTH_DIAGONAL_CORNERS' flag to the atom's smoothing_flags var (in addition to either SMOOTH_TRUE or SMOOTH_MORE).
|
|
|
|
For turfs, what appears under the diagonal corners depends on the turf that was in the same position previously: if you make a wall on
|
|
a plating floor, you will see plating under the diagonal wall corner, if it was space, you will see space.
|
|
|
|
If you wish to map a diagonal wall corner with a fixed underlay, you must configure the turf's 'fixed_underlay' list var, like so:
|
|
fixed_underlay = list("icon"='icon_file.dmi', "icon_state"="iconstatename")
|
|
A non null 'fixed_underlay' list var will skip copying the previous turf appearance and always use the list. If the list is
|
|
not set properly, the underlay will default to regular floor plating.
|
|
|
|
To see an example of a diagonal wall, see '/turf/closed/wall/mineral/titanium' and its subtypes.
|
|
*/
|
|
|
|
#define NO_ADJ_FOUND 0
|
|
#define ADJ_FOUND 1
|
|
#define NULLTURF_BORDER 2
|
|
|
|
GLOBAL_LIST_INIT(adjacent_direction_lookup, generate_adjacent_directions())
|
|
|
|
/* Attempting to mirror the below
|
|
* Each 3x3 grid is a tile, with each X representing a direction a border object could be in IN said grid
|
|
* Directions marked with A are acceptable smoothing targets, M is the example direction
|
|
* The example given here is of a northfacing border object
|
|
xxx AxA xxx
|
|
xxx AxA xxx
|
|
xxx AxA xxx
|
|
|
|
AAA MMM AAA
|
|
xxx AxA xxx
|
|
xxx AxA xxx
|
|
|
|
xxx xxx xxx
|
|
xxx xxx xxx
|
|
xxx xxx xxx
|
|
*/
|
|
/// Encodes connectivity between border objects
|
|
/// Returns a list accessable by a border object's dir, the direction between it and a target, and a target
|
|
/// Said list will return the direction the two objects connect, if any exists (if the target isn't a border object and the direction is fine, return the inverse of the direction in use)
|
|
/proc/generate_adjacent_directions()
|
|
// Have to hold all conventional dir pairs, so we size to the largest
|
|
// We don't HAVE diagonal border objects, so I'm gonna pretend they'll never exist
|
|
|
|
// You might be like, lemon, can't we use GLOB.cardinals/GLOB.alldirs here
|
|
// No, they aren't loaded yet. life is pain
|
|
var/list/cardinals = list(NORTH, SOUTH, EAST, WEST)
|
|
var/list/alldirs = cardinals + list(NORTH|EAST, SOUTH|EAST, NORTH|WEST, SOUTH|WEST)
|
|
var/largest_cardinal = max(cardinals)
|
|
var/largest_dir = max(alldirs)
|
|
|
|
var/list/direction_map = new /list(largest_cardinal)
|
|
for(var/dir in cardinals)
|
|
var/left = turn(dir, 90)
|
|
var/right = turn(dir, -90)
|
|
var/opposite = REVERSE_DIR(dir)
|
|
// Need to encode diagonals here because it's possible, even if it is always false
|
|
var/list/acceptable_adjacents = new /list(largest_dir)
|
|
// Alright, what directions are acceptable to us
|
|
for(var/connectable_dir in (cardinals + NONE))
|
|
// And what border objects INSIDE those directions are alright
|
|
var/list/smoothable_dirs = new /list(largest_cardinal + 1) // + 1 because we need to provide space for NONE to be a valid index
|
|
// None is fine, we want to smooth with things on our own turf
|
|
// We'll do the two dirs to our left and right
|
|
// They connect.. "below" us and on their side
|
|
if(connectable_dir == NONE)
|
|
smoothable_dirs[left] = dir_to_junction(opposite | left)
|
|
smoothable_dirs[right] = dir_to_junction(opposite | right)
|
|
// If it's to our right or left we'll include just the dir matching ours
|
|
// Left edge touches only our left side, and so on
|
|
else if (connectable_dir == left)
|
|
smoothable_dirs[dir] = left
|
|
else if (connectable_dir == right)
|
|
smoothable_dirs[dir] = right
|
|
// If it's straight on we'll include our direction as a link
|
|
// Then include the two edges on the other side as diagonals
|
|
else if(connectable_dir == dir)
|
|
smoothable_dirs[opposite] = dir
|
|
smoothable_dirs[left] = dir_to_junction(dir | left)
|
|
smoothable_dirs[right] = dir_to_junction(dir | right)
|
|
// otherwise, go HOME, I don't want to encode anything for you
|
|
else
|
|
continue
|
|
acceptable_adjacents[connectable_dir + 1] = smoothable_dirs
|
|
direction_map[dir] = acceptable_adjacents
|
|
return direction_map
|
|
|
|
/// Are two atoms border adjacent, takes a border object, something to compare against, and the direction between A and B
|
|
/// Returns the way in which the first thing is adjacent to the second
|
|
#define CAN_DIAGONAL_SMOOTH(border_obj, target, direction) (\
|
|
(target.smoothing_flags & SMOOTH_BORDER_OBJECT) ? \
|
|
GLOB.adjacent_direction_lookup[border_obj.dir][direction + 1]?[target.dir] : \
|
|
(GLOB.adjacent_direction_lookup[border_obj.dir][direction + 1]) ? REVERSE_DIR(direction) : NONE \
|
|
)
|
|
|
|
#define DEFAULT_UNDERLAY_ICON 'icons/turf/floors.dmi'
|
|
#define DEFAULT_UNDERLAY_ICON_STATE "plating"
|
|
|
|
|
|
///Scans all adjacent turfs to find targets to smooth with.
|
|
/atom/proc/calculate_adjacencies()
|
|
. = NONE
|
|
|
|
if(!loc)
|
|
return
|
|
|
|
for(var/direction in GLOB.cardinals)
|
|
switch(find_type_in_direction(direction))
|
|
if(NULLTURF_BORDER)
|
|
if((smoothing_flags & SMOOTH_BORDER))
|
|
. |= direction //BYOND and smooth dirs are the same for cardinals
|
|
if(ADJ_FOUND)
|
|
. |= direction //BYOND and smooth dirs are the same for cardinals
|
|
|
|
if(. & NORTH_JUNCTION)
|
|
if(. & WEST_JUNCTION)
|
|
switch(find_type_in_direction(NORTHWEST))
|
|
if(NULLTURF_BORDER)
|
|
if((smoothing_flags & SMOOTH_BORDER))
|
|
. |= NORTHWEST_JUNCTION
|
|
if(ADJ_FOUND)
|
|
. |= NORTHWEST_JUNCTION
|
|
|
|
if(. & EAST_JUNCTION)
|
|
switch(find_type_in_direction(NORTHEAST))
|
|
if(NULLTURF_BORDER)
|
|
if((smoothing_flags & SMOOTH_BORDER))
|
|
. |= NORTHEAST_JUNCTION
|
|
if(ADJ_FOUND)
|
|
. |= NORTHEAST_JUNCTION
|
|
|
|
if(. & SOUTH_JUNCTION)
|
|
if(. & WEST_JUNCTION)
|
|
switch(find_type_in_direction(SOUTHWEST))
|
|
if(NULLTURF_BORDER)
|
|
if((smoothing_flags & SMOOTH_BORDER))
|
|
. |= SOUTHWEST_JUNCTION
|
|
if(ADJ_FOUND)
|
|
. |= SOUTHWEST_JUNCTION
|
|
|
|
if(. & EAST_JUNCTION)
|
|
switch(find_type_in_direction(SOUTHEAST))
|
|
if(NULLTURF_BORDER)
|
|
if((smoothing_flags & SMOOTH_BORDER))
|
|
. |= SOUTHEAST_JUNCTION
|
|
if(ADJ_FOUND)
|
|
. |= SOUTHEAST_JUNCTION
|
|
|
|
|
|
/atom/movable/calculate_adjacencies()
|
|
if(can_be_unanchored && !anchored)
|
|
return NONE
|
|
return ..()
|
|
|
|
|
|
///do not use, use QUEUE_SMOOTH(atom)
|
|
/atom/proc/smooth_icon()
|
|
if(QDELETED(src))
|
|
return
|
|
smoothing_flags &= ~SMOOTH_QUEUED
|
|
flags_1 |= HTML_USE_INITAL_ICON_1
|
|
if (!z)
|
|
CRASH("[type] called smooth_icon() without being on a z-level")
|
|
if(smoothing_flags & SMOOTH_CORNERS)
|
|
if(smoothing_flags & SMOOTH_DIAGONAL_CORNERS)
|
|
corners_diagonal_smooth(calculate_adjacencies())
|
|
else
|
|
corners_cardinal_smooth(calculate_adjacencies())
|
|
else if(smoothing_flags & SMOOTH_BITMASK)
|
|
bitmask_smooth()
|
|
else
|
|
CRASH("smooth_icon called for [src] with smoothing_flags == [smoothing_flags]")
|
|
SEND_SIGNAL(src, COMSIG_ATOM_SMOOTHED_ICON)
|
|
|
|
/turf/smooth_icon()
|
|
. = ..()
|
|
SSdemo.mark_turf(src)
|
|
|
|
// As a rule, movables will most always care about smoothing changes
|
|
// Turfs on the other hand, don't, so we don't do the update for THEM unless they explicitly request it
|
|
/atom/movable/smooth_icon()
|
|
. = ..()
|
|
update_appearance(~UPDATE_SMOOTHING)
|
|
|
|
/atom/proc/corners_diagonal_smooth(adjacencies)
|
|
switch(adjacencies)
|
|
if(NORTH_JUNCTION|WEST_JUNCTION)
|
|
replace_smooth_overlays("d-se","d-se-0")
|
|
if(NORTH_JUNCTION|EAST_JUNCTION)
|
|
replace_smooth_overlays("d-sw","d-sw-0")
|
|
if(SOUTH_JUNCTION|WEST_JUNCTION)
|
|
replace_smooth_overlays("d-ne","d-ne-0")
|
|
if(SOUTH_JUNCTION|EAST_JUNCTION)
|
|
replace_smooth_overlays("d-nw","d-nw-0")
|
|
|
|
if(NORTH_JUNCTION|WEST_JUNCTION|NORTHWEST_JUNCTION)
|
|
replace_smooth_overlays("d-se","d-se-1")
|
|
if(NORTH_JUNCTION|EAST_JUNCTION|NORTHEAST_JUNCTION)
|
|
replace_smooth_overlays("d-sw","d-sw-1")
|
|
if(SOUTH_JUNCTION|WEST_JUNCTION|SOUTHWEST_JUNCTION)
|
|
replace_smooth_overlays("d-ne","d-ne-1")
|
|
if(SOUTH_JUNCTION|EAST_JUNCTION|SOUTHEAST_JUNCTION)
|
|
replace_smooth_overlays("d-nw","d-nw-1")
|
|
|
|
else
|
|
corners_cardinal_smooth(adjacencies)
|
|
return FALSE
|
|
|
|
icon_state = ""
|
|
return TRUE
|
|
|
|
|
|
/atom/proc/corners_cardinal_smooth(adjacencies)
|
|
var/mutable_appearance/temp_ma
|
|
|
|
//NW CORNER
|
|
var/nw = "1-i"
|
|
if((adjacencies & NORTH_JUNCTION) && (adjacencies & WEST_JUNCTION))
|
|
if(adjacencies & NORTHWEST_JUNCTION)
|
|
nw = "1-f"
|
|
else
|
|
nw = "1-nw"
|
|
else
|
|
if(adjacencies & NORTH_JUNCTION)
|
|
nw = "1-n"
|
|
else if(adjacencies & WEST_JUNCTION)
|
|
nw = "1-w"
|
|
temp_ma = mutable_appearance(icon, nw)
|
|
nw = temp_ma.appearance
|
|
|
|
//NE CORNER
|
|
var/ne = "2-i"
|
|
if((adjacencies & NORTH_JUNCTION) && (adjacencies & EAST_JUNCTION))
|
|
if(adjacencies & NORTHEAST_JUNCTION)
|
|
ne = "2-f"
|
|
else
|
|
ne = "2-ne"
|
|
else
|
|
if(adjacencies & NORTH_JUNCTION)
|
|
ne = "2-n"
|
|
else if(adjacencies & EAST_JUNCTION)
|
|
ne = "2-e"
|
|
temp_ma = mutable_appearance(icon, ne)
|
|
ne = temp_ma.appearance
|
|
|
|
//SW CORNER
|
|
var/sw = "3-i"
|
|
if((adjacencies & SOUTH_JUNCTION) && (adjacencies & WEST_JUNCTION))
|
|
if(adjacencies & SOUTHWEST_JUNCTION)
|
|
sw = "3-f"
|
|
else
|
|
sw = "3-sw"
|
|
else
|
|
if(adjacencies & SOUTH_JUNCTION)
|
|
sw = "3-s"
|
|
else if(adjacencies & WEST_JUNCTION)
|
|
sw = "3-w"
|
|
temp_ma = mutable_appearance(icon, sw)
|
|
sw = temp_ma.appearance
|
|
|
|
//SE CORNER
|
|
var/se = "4-i"
|
|
if((adjacencies & SOUTH_JUNCTION) && (adjacencies & EAST_JUNCTION))
|
|
if(adjacencies & SOUTHEAST_JUNCTION)
|
|
se = "4-f"
|
|
else
|
|
se = "4-se"
|
|
else
|
|
if(adjacencies & SOUTH_JUNCTION)
|
|
se = "4-s"
|
|
else if(adjacencies & EAST_JUNCTION)
|
|
se = "4-e"
|
|
temp_ma = mutable_appearance(icon, se)
|
|
se = temp_ma.appearance
|
|
|
|
var/list/new_overlays
|
|
|
|
if(top_left_corner != nw)
|
|
cut_overlay(top_left_corner)
|
|
top_left_corner = nw
|
|
LAZYADD(new_overlays, nw)
|
|
|
|
if(top_right_corner != ne)
|
|
cut_overlay(top_right_corner)
|
|
top_right_corner = ne
|
|
LAZYADD(new_overlays, ne)
|
|
|
|
if(bottom_right_corner != sw)
|
|
cut_overlay(bottom_right_corner)
|
|
bottom_right_corner = sw
|
|
LAZYADD(new_overlays, sw)
|
|
|
|
if(bottom_left_corner != se)
|
|
cut_overlay(bottom_left_corner)
|
|
bottom_left_corner = se
|
|
LAZYADD(new_overlays, se)
|
|
|
|
if(new_overlays)
|
|
add_overlay(new_overlays)
|
|
|
|
|
|
///Scans direction to find targets to smooth with.
|
|
/atom/proc/find_type_in_direction(direction)
|
|
var/turf/target_turf = get_step(src, direction)
|
|
if(!target_turf)
|
|
return NULLTURF_BORDER
|
|
|
|
var/area/target_area = get_area(target_turf)
|
|
var/area/source_area = get_area(src)
|
|
if((source_area.area_limited_icon_smoothing && !istype(target_area, source_area.area_limited_icon_smoothing)) || (target_area.area_limited_icon_smoothing && !istype(source_area, target_area.area_limited_icon_smoothing)))
|
|
return NO_ADJ_FOUND
|
|
|
|
if(isnull(canSmoothWith)) //special case in which it will only smooth with itself
|
|
if(isturf(src))
|
|
return (type == target_turf.type) ? ADJ_FOUND : NO_ADJ_FOUND
|
|
var/atom/matching_obj = locate(type) in target_turf
|
|
return (matching_obj && matching_obj.type == type) ? ADJ_FOUND : NO_ADJ_FOUND
|
|
|
|
if(!isnull(target_turf.smoothing_groups))
|
|
for(var/target in canSmoothWith)
|
|
if(!(canSmoothWith[target] & target_turf.smoothing_groups[target]))
|
|
continue
|
|
return ADJ_FOUND
|
|
|
|
if(smoothing_flags & SMOOTH_OBJ)
|
|
for(var/atom/movable/thing as anything in target_turf)
|
|
if(!thing.anchored || isnull(thing.smoothing_groups))
|
|
continue
|
|
for(var/target in canSmoothWith)
|
|
if(!(canSmoothWith[target] & thing.smoothing_groups[target]))
|
|
continue
|
|
return ADJ_FOUND
|
|
|
|
return NO_ADJ_FOUND
|
|
|
|
/**
|
|
* Basic smoothing proc. The atom checks for adjacent directions to smooth with and changes the icon_state based on that.
|
|
*
|
|
* Returns the previous smoothing_junction state so the previous state can be compared with the new one after the proc ends, and see the changes, if any.
|
|
*
|
|
*/
|
|
/atom/proc/bitmask_smooth()
|
|
var/new_junction = NONE
|
|
|
|
// cache for sanic speed
|
|
var/canSmoothWith = src.canSmoothWith
|
|
|
|
var/smooth_border = (smoothing_flags & SMOOTH_BORDER)
|
|
var/smooth_obj = (smoothing_flags & SMOOTH_OBJ)
|
|
var/border_object_smoothing = (smoothing_flags & SMOOTH_BORDER_OBJECT)
|
|
|
|
// Did you know you can pass defines into other defines? very handy, lets take advantage of it here to allow 0 cost variation
|
|
#define SEARCH_ADJ_IN_DIR(direction, direction_flag, ADJ_FOUND, WORLD_BORDER, BORDER_CHECK) \
|
|
do { \
|
|
var/turf/neighbor = get_step(src, direction); \
|
|
if(neighbor && ##BORDER_CHECK(neighbor, direction)) { \
|
|
var/neighbor_smoothing_groups = neighbor.smoothing_groups; \
|
|
if(neighbor_smoothing_groups) { \
|
|
for(var/target in canSmoothWith) { \
|
|
if(canSmoothWith[target] & neighbor_smoothing_groups[target]) { \
|
|
##ADJ_FOUND(neighbor, direction, direction_flag); \
|
|
} \
|
|
} \
|
|
} \
|
|
if(smooth_obj) { \
|
|
for(var/atom/movable/thing as anything in neighbor) { \
|
|
var/thing_smoothing_groups = thing.smoothing_groups; \
|
|
if(!thing.anchored || isnull(thing_smoothing_groups) || !##BORDER_CHECK(thing, direction)) { \
|
|
continue; \
|
|
}; \
|
|
for(var/target in canSmoothWith) { \
|
|
if(canSmoothWith[target] & thing_smoothing_groups[target]) { \
|
|
##ADJ_FOUND(thing, direction, direction_flag); \
|
|
} \
|
|
} \
|
|
} \
|
|
} \
|
|
} else if (smooth_border) { \
|
|
##WORLD_BORDER(null, direction, direction_flag); \
|
|
} \
|
|
} while(FALSE) \
|
|
|
|
#define BITMASK_FOUND(target, direction, direction_flag) \
|
|
new_junction |= direction_flag; \
|
|
break set_adj_in_dir; \
|
|
/// Check that non border objects use to smooth against border objects
|
|
/// Returns true if the smooth is acceptable, FALSE otherwise
|
|
#define BITMASK_ON_BORDER_CHECK(target, direction) (!(target.smoothing_flags & SMOOTH_BORDER_OBJECT) || CAN_DIAGONAL_SMOOTH(target, src, REVERSE_DIR(direction)))
|
|
|
|
#define BORDER_FOUND(target, direction, direction_flag) new_junction |= CAN_DIAGONAL_SMOOTH(src, target, direction)
|
|
// Border objects require an object as context, so we need a dummy. I'm sorry
|
|
#define WORLD_BORDER_FOUND(target, direction, direction_flag) \
|
|
var/static/atom/dummy; \
|
|
if(!dummy) { \
|
|
dummy = new(); \
|
|
dummy.smoothing_flags &= ~SMOOTH_BORDER_OBJECT; \
|
|
} \
|
|
BORDER_FOUND(dummy, direction, direction_flag);
|
|
// Handle handle border on border checks. no-op, we handle this check inside CAN_DIAGONAL_SMOOTH
|
|
#define BORDER_ON_BORDER_CHECK(target, direction) (TRUE)
|
|
|
|
// We're building 2 different types of smoothing searches here
|
|
// One for standard bitmask smoothing (We provide a label so our macro can eary exit, as it wants to do)
|
|
#define SET_ADJ_IN_DIR(direction, direction_flag) do { set_adj_in_dir: { SEARCH_ADJ_IN_DIR(direction, direction_flag, BITMASK_FOUND, BITMASK_FOUND, BITMASK_ON_BORDER_CHECK) }} while(FALSE)
|
|
// and another for border object work (Doesn't early exit because we can hit more then one direction by checking the same turf)
|
|
#define SET_BORDER_ADJ_IN_DIR(direction) SEARCH_ADJ_IN_DIR(direction, direction, BORDER_FOUND, WORLD_BORDER_FOUND, BORDER_ON_BORDER_CHECK)
|
|
|
|
// Let's go over all our cardinals
|
|
if(border_object_smoothing)
|
|
SET_BORDER_ADJ_IN_DIR(NORTH)
|
|
SET_BORDER_ADJ_IN_DIR(SOUTH)
|
|
SET_BORDER_ADJ_IN_DIR(EAST)
|
|
SET_BORDER_ADJ_IN_DIR(WEST)
|
|
// We want to check against stuff in our own turf
|
|
SET_BORDER_ADJ_IN_DIR(NONE)
|
|
// Border objects don't do diagonals, so GO HOME
|
|
set_smoothed_icon_state(new_junction)
|
|
return
|
|
|
|
SET_ADJ_IN_DIR(NORTH, NORTH)
|
|
SET_ADJ_IN_DIR(SOUTH, SOUTH)
|
|
SET_ADJ_IN_DIR(EAST, EAST)
|
|
SET_ADJ_IN_DIR(WEST, WEST)
|
|
|
|
// If there's nothing going on already
|
|
if(!(new_junction & (NORTH|SOUTH)) || !(new_junction & (EAST|WEST)))
|
|
set_smoothed_icon_state(new_junction)
|
|
return
|
|
|
|
if(new_junction & NORTH_JUNCTION)
|
|
if(new_junction & WEST_JUNCTION)
|
|
SET_ADJ_IN_DIR(NORTHWEST, NORTHWEST_JUNCTION)
|
|
|
|
if(new_junction & EAST_JUNCTION)
|
|
SET_ADJ_IN_DIR(NORTHEAST, NORTHEAST_JUNCTION)
|
|
|
|
if(new_junction & SOUTH_JUNCTION)
|
|
if(new_junction & WEST_JUNCTION)
|
|
SET_ADJ_IN_DIR(SOUTHWEST, SOUTHWEST_JUNCTION)
|
|
|
|
if(new_junction & EAST_JUNCTION)
|
|
SET_ADJ_IN_DIR(SOUTHEAST, SOUTHEAST_JUNCTION)
|
|
|
|
set_smoothed_icon_state(new_junction)
|
|
|
|
#undef SET_BORDER_ADJ_IN_DIR
|
|
#undef SET_ADJ_IN_DIR
|
|
#undef BORDER_ON_BORDER_CHECK
|
|
#undef WORLD_BORDER_FOUND
|
|
#undef BORDER_FOUND
|
|
#undef BITMASK_ON_BORDER_CHECK
|
|
#undef BITMASK_FOUND
|
|
#undef SEARCH_ADJ_IN_DIR
|
|
|
|
///Changes the icon state based on the new junction bitmask
|
|
/atom/proc/set_smoothed_icon_state(new_junction)
|
|
. = smoothing_junction
|
|
smoothing_junction = new_junction
|
|
icon_state = "[base_icon_state]-[smoothing_junction]"
|
|
|
|
|
|
/turf/closed/set_smoothed_icon_state(new_junction)
|
|
// Avoid calling ..() here to avoid setting icon_state twice, which is expensive given how hot this proc is
|
|
var/old_junction = smoothing_junction
|
|
smoothing_junction = new_junction
|
|
|
|
if (!(smoothing_flags & SMOOTH_DIAGONAL_CORNERS))
|
|
icon_state = "[base_icon_state]-[smoothing_junction]"
|
|
return
|
|
|
|
switch(new_junction)
|
|
if(
|
|
NORTH_JUNCTION|WEST_JUNCTION,
|
|
NORTH_JUNCTION|EAST_JUNCTION,
|
|
SOUTH_JUNCTION|WEST_JUNCTION,
|
|
SOUTH_JUNCTION|EAST_JUNCTION,
|
|
NORTH_JUNCTION|WEST_JUNCTION|NORTHWEST_JUNCTION,
|
|
NORTH_JUNCTION|EAST_JUNCTION|NORTHEAST_JUNCTION,
|
|
SOUTH_JUNCTION|WEST_JUNCTION|SOUTHWEST_JUNCTION,
|
|
SOUTH_JUNCTION|EAST_JUNCTION|SOUTHEAST_JUNCTION,
|
|
)
|
|
icon_state = "[base_icon_state]-[smoothing_junction]-d"
|
|
if(new_junction == old_junction || fixed_underlay) // Mutable underlays?
|
|
return
|
|
|
|
var/junction_dir = reverse_ndir(smoothing_junction)
|
|
var/turned_adjacency = REVERSE_DIR(junction_dir)
|
|
var/turf/neighbor_turf = get_step(src, turned_adjacency & (NORTH|SOUTH))
|
|
var/mutable_appearance/underlay_appearance = mutable_appearance(layer = TURF_LAYER, offset_spokesman = src, plane = FLOOR_PLANE)
|
|
if(!neighbor_turf.get_smooth_underlay_icon(underlay_appearance, src, turned_adjacency))
|
|
neighbor_turf = get_step(src, turned_adjacency & (EAST|WEST))
|
|
|
|
if(!neighbor_turf.get_smooth_underlay_icon(underlay_appearance, src, turned_adjacency))
|
|
neighbor_turf = get_step(src, turned_adjacency)
|
|
|
|
if(!neighbor_turf.get_smooth_underlay_icon(underlay_appearance, src, turned_adjacency))
|
|
if(!get_smooth_underlay_icon(underlay_appearance, src, turned_adjacency)) //if all else fails, ask our own turf
|
|
underlay_appearance.icon = DEFAULT_UNDERLAY_ICON
|
|
underlay_appearance.icon_state = DEFAULT_UNDERLAY_ICON_STATE
|
|
underlays += underlay_appearance
|
|
else
|
|
icon_state = "[base_icon_state]-[smoothing_junction]"
|
|
|
|
/turf/open/floor/set_smoothed_icon_state(new_junction)
|
|
if(broken || burnt)
|
|
return
|
|
return ..()
|
|
|
|
|
|
//Icon smoothing helpers
|
|
/proc/smooth_zlevel(zlevel, now = FALSE)
|
|
var/list/away_turfs = Z_TURFS(zlevel)
|
|
for(var/turf/turf_to_smooth as anything in away_turfs)
|
|
if(turf_to_smooth.smoothing_flags & (SMOOTH_CORNERS|SMOOTH_BITMASK))
|
|
if(now)
|
|
turf_to_smooth.smooth_icon()
|
|
else
|
|
QUEUE_SMOOTH(turf_to_smooth)
|
|
for(var/atom/movable/movable_to_smooth as anything in turf_to_smooth)
|
|
if(movable_to_smooth.smoothing_flags & (SMOOTH_CORNERS|SMOOTH_BITMASK))
|
|
if(now)
|
|
movable_to_smooth.smooth_icon()
|
|
else
|
|
QUEUE_SMOOTH(movable_to_smooth)
|
|
|
|
|
|
/atom/proc/clear_smooth_overlays()
|
|
cut_overlay(top_left_corner)
|
|
top_left_corner = null
|
|
cut_overlay(top_right_corner)
|
|
top_right_corner = null
|
|
cut_overlay(bottom_right_corner)
|
|
bottom_right_corner = null
|
|
cut_overlay(bottom_left_corner)
|
|
bottom_left_corner = null
|
|
|
|
/// Internal: Takes icon states as text to replace smoothing corner overlays
|
|
/atom/proc/replace_smooth_overlays(nw, ne, sw, se)
|
|
clear_smooth_overlays()
|
|
var/mutable_appearance/temp_ma
|
|
|
|
temp_ma = mutable_appearance(icon, nw)
|
|
nw = temp_ma.appearance
|
|
|
|
temp_ma = mutable_appearance(icon, ne)
|
|
ne = temp_ma.appearance
|
|
|
|
temp_ma = mutable_appearance(icon, sw)
|
|
sw = temp_ma.appearance
|
|
|
|
temp_ma = mutable_appearance(icon, se)
|
|
se = temp_ma.appearance
|
|
|
|
var/list/new_overlays = list()
|
|
|
|
top_left_corner = nw
|
|
new_overlays += nw
|
|
|
|
top_right_corner = ne
|
|
new_overlays += ne
|
|
|
|
bottom_left_corner = sw
|
|
new_overlays += sw
|
|
|
|
bottom_right_corner = se
|
|
new_overlays += se
|
|
|
|
add_overlay(new_overlays)
|
|
|
|
/// Takes a direction, turns it into all the junctions that contain it
|
|
/proc/dir_to_all_junctions(dir)
|
|
var/handback = NONE
|
|
if(dir & NORTH)
|
|
handback |= NORTH_JUNCTION | NORTHEAST_JUNCTION | NORTHWEST_JUNCTION
|
|
if(dir & SOUTH)
|
|
handback |= SOUTH_JUNCTION | SOUTHEAST_JUNCTION | SOUTHWEST_JUNCTION
|
|
if(dir & EAST)
|
|
handback |= EAST_JUNCTION | SOUTHEAST_JUNCTION | NORTHEAST_JUNCTION
|
|
if(dir & WEST)
|
|
handback |= WEST_JUNCTION | NORTHWEST_JUNCTION | SOUTHWEST_JUNCTION
|
|
return handback
|
|
|
|
/proc/dir_to_junction(dir)
|
|
switch(dir)
|
|
if(NORTH)
|
|
return NORTH_JUNCTION
|
|
if(SOUTH)
|
|
return SOUTH_JUNCTION
|
|
if(WEST)
|
|
return WEST_JUNCTION
|
|
if(EAST)
|
|
return EAST_JUNCTION
|
|
if(NORTHWEST)
|
|
return NORTHWEST_JUNCTION
|
|
if(NORTHEAST)
|
|
return NORTHEAST_JUNCTION
|
|
if(SOUTHEAST)
|
|
return SOUTHEAST_JUNCTION
|
|
if(SOUTHWEST)
|
|
return SOUTHWEST_JUNCTION
|
|
else
|
|
return NONE
|
|
|
|
/proc/reverse_ndir(ndir)
|
|
switch(ndir)
|
|
if(NORTH_JUNCTION)
|
|
return NORTH
|
|
if(SOUTH_JUNCTION)
|
|
return SOUTH
|
|
if(WEST_JUNCTION)
|
|
return WEST
|
|
if(EAST_JUNCTION)
|
|
return EAST
|
|
if(NORTHWEST_JUNCTION)
|
|
return NORTHWEST
|
|
if(NORTHEAST_JUNCTION)
|
|
return NORTHEAST
|
|
if(SOUTHEAST_JUNCTION)
|
|
return SOUTHEAST
|
|
if(SOUTHWEST_JUNCTION)
|
|
return SOUTHWEST
|
|
if(NORTH_JUNCTION | WEST_JUNCTION)
|
|
return NORTHWEST
|
|
if(NORTH_JUNCTION | EAST_JUNCTION)
|
|
return NORTHEAST
|
|
if(SOUTH_JUNCTION | WEST_JUNCTION)
|
|
return SOUTHWEST
|
|
if(SOUTH_JUNCTION | EAST_JUNCTION)
|
|
return SOUTHEAST
|
|
if(NORTH_JUNCTION | WEST_JUNCTION | NORTHWEST_JUNCTION)
|
|
return NORTHWEST
|
|
if(NORTH_JUNCTION | EAST_JUNCTION | NORTHEAST_JUNCTION)
|
|
return NORTHEAST
|
|
if(SOUTH_JUNCTION | WEST_JUNCTION | SOUTHWEST_JUNCTION)
|
|
return SOUTHWEST
|
|
if(SOUTH_JUNCTION | EAST_JUNCTION | SOUTHEAST_JUNCTION)
|
|
return SOUTHEAST
|
|
else
|
|
return NONE
|
|
|
|
|
|
//Example smooth wall
|
|
/turf/closed/wall/smooth
|
|
name = "smooth wall"
|
|
icon = 'icons/turf/smooth_wall.dmi'
|
|
icon_state = "smooth"
|
|
smoothing_flags = SMOOTH_CORNERS|SMOOTH_DIAGONAL_CORNERS|SMOOTH_BORDER
|
|
smoothing_groups = null
|
|
canSmoothWith = null
|
|
|
|
#undef NORTH_JUNCTION
|
|
#undef SOUTH_JUNCTION
|
|
#undef EAST_JUNCTION
|
|
#undef WEST_JUNCTION
|
|
#undef NORTHEAST_JUNCTION
|
|
#undef NORTHWEST_JUNCTION
|
|
#undef SOUTHEAST_JUNCTION
|
|
#undef SOUTHWEST_JUNCTION
|
|
|
|
#undef NO_ADJ_FOUND
|
|
#undef ADJ_FOUND
|
|
#undef NULLTURF_BORDER
|
|
|
|
#undef DEFAULT_UNDERLAY_ICON
|
|
#undef DEFAULT_UNDERLAY_ICON_STATE
|
|
#undef CAN_DIAGONAL_SMOOTH
|