mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2025-12-10 09:42:29 +00:00
[MIRROR] Cleans up the fallout from plane cube [MDB IGNORE] (#17003)
* Cleans up the fallout from plane cube (#70235) * Cleans up the fallout from plane cube Alright. Makes cleaning bubbles respect planes Adds support for updating overlays on move, fixing an issue with pointing at items Adds better error messages for failing to provide args for mutable_appearance() Fixes a bug where string overlays were not respecting insertion order * Adds documentation for offset spokesman and offset_const * Better stack trace * Removes some redundant uses of cached MAs At this scale, attempting to cache MAs like this has 0 impact on anything And just makes things more messy then they need to be * ensures fullscreen objects START offset, so things are always proper * ensures chatmessages always have the right offset * fixes compile * whoops, the above lighting plane should actually be ABOVE the lighting plane * fixes compile, also cleans up the fire overlay a tad * Adds a unit test for plane masters that are shrunk by multiz being double shrunk This is slightly hacky because of how I'm handing the plane master group, but it's not THAT bad, and gives me some real good coverage * Properly targets the seethrough plane at the game world plate. This fixes unit tests, and also just makes more sense * whoops * oh * adds datum support for allocate(), cleans up a harddel from testing * Makes camera chunks index at 1, and also makes them support non powers of two sizes, since that was unneeded * fixes runtime in allocate * Cleans up the fallout from plane cube * liquid tweaks * oop Co-authored-by: LemonInTheDark <58055496+LemonInTheDark@users.noreply.github.com> Co-authored-by: tastyfish <crazychris32@gmail.com>
This commit is contained in:
@@ -45,14 +45,14 @@
|
||||
#define O_LIGHTING_VISUAL_PLANE 11
|
||||
#define O_LIGHTING_VISUAL_RENDER_TARGET "O_LIGHT_VISUAL_PLANE"
|
||||
|
||||
///Things that should render ignoring lighting
|
||||
#define ABOVE_LIGHTING_PLANE 12
|
||||
|
||||
/// This plane masks out lighting to create an "emissive" effect, ie for glowing lights in otherwise dark areas.
|
||||
#define EMISSIVE_PLANE 14
|
||||
|
||||
#define RENDER_PLANE_LIGHTING 15
|
||||
|
||||
///Things that should render ignoring lighting
|
||||
#define ABOVE_LIGHTING_PLANE 16
|
||||
|
||||
///---------------- MISC -----------------------
|
||||
|
||||
///Pipecrawling images
|
||||
|
||||
@@ -14,6 +14,8 @@
|
||||
screen.update_for_view(client.view)
|
||||
client.screen += screen
|
||||
|
||||
SET_PLANE_EXPLICIT(screen, PLANE_TO_TRUE(screen.plane), src)
|
||||
|
||||
return screen
|
||||
|
||||
/mob/proc/clear_fullscreen(category, animated = 10)
|
||||
|
||||
@@ -153,7 +153,7 @@ INITIALIZE_IMMEDIATE(/atom/movable/screen/plane_master)
|
||||
/// This allows us to mirror any hidden sets from before we were created, no matter how low that chance is
|
||||
/atom/movable/screen/plane_master/proc/mirror_parent_hidden()
|
||||
var/mob/our_mob = home?.our_hud?.mymob
|
||||
var/atom/movable/screen/plane_master/true_plane = our_mob?.hud_used.get_plane_master(plane)
|
||||
var/atom/movable/screen/plane_master/true_plane = our_mob?.hud_used?.get_plane_master(plane)
|
||||
if(true_plane == src || !true_plane)
|
||||
return
|
||||
|
||||
@@ -301,7 +301,7 @@ INITIALIZE_IMMEDIATE(/atom/movable/screen/plane_master)
|
||||
documentation = "Holds the seethrough versions (done using image overrides) of large objects. Mouse transparent, so you can click through them."
|
||||
plane = SEETHROUGH_PLANE
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
render_relay_planes = list(GAME_PLANE)
|
||||
render_relay_planes = list(RENDER_PLANE_GAME_WORLD)
|
||||
start_hidden = TRUE
|
||||
|
||||
/atom/movable/screen/plane_master/game_world_above
|
||||
@@ -347,7 +347,7 @@ INITIALIZE_IMMEDIATE(/atom/movable/screen/plane_master)
|
||||
var/datum/hud/hud = home.our_hud
|
||||
if(hud)
|
||||
RegisterSignal(hud, COMSIG_HUD_OFFSET_CHANGED, .proc/on_offset_change)
|
||||
offset_change(0, hud.current_plane_offset)
|
||||
offset_change(0, hud?.current_plane_offset || 0)
|
||||
|
||||
/atom/movable/screen/plane_master/blackness/hide_from(mob/oldmob)
|
||||
. = ..()
|
||||
|
||||
@@ -151,3 +151,20 @@
|
||||
if(use_scale)
|
||||
return ..(source, new_offset, source.should_use_scale())
|
||||
return ..()
|
||||
|
||||
/// Hudless group. Exists for testing
|
||||
/datum/plane_master_group/hudless
|
||||
var/mob/our_mob
|
||||
|
||||
/datum/plane_master_group/hudless/Destroy()
|
||||
. = ..()
|
||||
our_mob = null
|
||||
|
||||
/datum/plane_master_group/hudless/hide_hud()
|
||||
for(var/thing in plane_masters)
|
||||
var/atom/movable/screen/plane_master/plane = plane_masters[thing]
|
||||
plane.hide_from(our_mob)
|
||||
|
||||
/// This is mostly a proc so it can be overriden by popups, since they have unique behavior they want to do
|
||||
/datum/plane_master_group/hudless/show_plane(atom/movable/screen/plane_master/plane)
|
||||
plane.show_to(our_mob)
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
var/datum/hud/hud = home.our_hud
|
||||
if(hud)
|
||||
RegisterSignal(hud, COMSIG_HUD_OFFSET_CHANGED, .proc/on_offset_change)
|
||||
offset_change(hud.current_plane_offset)
|
||||
offset_change(hud?.current_plane_offset || 0)
|
||||
|
||||
/atom/movable/screen/plane_master/rendering_plate/master/hide_from(mob/oldmob)
|
||||
. = ..()
|
||||
@@ -138,7 +138,7 @@
|
||||
var/datum/hud/hud = home.our_hud
|
||||
if(hud)
|
||||
RegisterSignal(hud, COMSIG_HUD_OFFSET_CHANGED, .proc/on_offset_change)
|
||||
offset_change(hud.current_plane_offset)
|
||||
offset_change(hud?.current_plane_offset || 0)
|
||||
set_alpha(mymob.lighting_alpha)
|
||||
|
||||
|
||||
@@ -278,10 +278,3 @@
|
||||
return relay
|
||||
|
||||
return null
|
||||
|
||||
/// Basically, trigger a full hud rebuild so our relays will be added to the screen
|
||||
/// I hate hud code
|
||||
/atom/movable/screen/plane_master/proc/rebuild_relays()
|
||||
relays = list()
|
||||
var/datum/hud/hud = home.our_hud
|
||||
hud.show_hud(hud.hud_version)
|
||||
|
||||
@@ -29,7 +29,6 @@ SUBSYSTEM_DEF(atoms)
|
||||
initialized = INITIALIZATION_INSSATOMS
|
||||
|
||||
/datum/controller/subsystem/atoms/Initialize()
|
||||
GLOB.fire_overlay.appearance_flags = RESET_COLOR
|
||||
setupGenetics() //to set the mutations' sequence
|
||||
|
||||
initialized = INITIALIZATION_INNEW_MAPLOAD
|
||||
|
||||
@@ -765,8 +765,6 @@ GLOBAL_LIST_EMPTY(the_station_areas)
|
||||
create_plane_offsets(gen_from, new_offset)
|
||||
for(var/offset in gen_from to new_offset)
|
||||
GLOB.fullbright_overlays += create_fullbright_overlay(offset)
|
||||
GLOB.cryo_overlays_cover_on += create_cryo_overlay(offset, "cover-on")
|
||||
GLOB.cryo_overlays_cover_off += create_cryo_overlay(offset, "cover-off")
|
||||
|
||||
for(var/datum/gas/gas_type as anything in GLOB.meta_gas_info)
|
||||
var/list/gas_info = GLOB.meta_gas_info[gas_type]
|
||||
|
||||
@@ -37,7 +37,7 @@ SUBSYSTEM_DEF(overlays)
|
||||
iconbro.icon = icon
|
||||
return iconbro.appearance
|
||||
|
||||
/atom/proc/build_appearance_list(build_overlays)
|
||||
/atom/proc/build_appearance_list(list/build_overlays)
|
||||
if (!islist(build_overlays))
|
||||
build_overlays = list(build_overlays)
|
||||
for (var/overlay in build_overlays)
|
||||
@@ -53,11 +53,11 @@ SUBSYSTEM_DEF(overlays)
|
||||
stack_trace("Invalid overlay: Icon object '[icon_file]' [REF(icon)] used in '[src]' [type] is missing icon state [overlay].")
|
||||
continue
|
||||
#endif
|
||||
build_overlays -= overlay
|
||||
build_overlays += iconstate2appearance(icon, overlay)
|
||||
var/index = build_overlays.Find(overlay)
|
||||
build_overlays[index] = iconstate2appearance(icon, overlay)
|
||||
else if(isicon(overlay))
|
||||
build_overlays -= overlay
|
||||
build_overlays += icon2appearance(overlay)
|
||||
var/index = build_overlays.Find(overlay)
|
||||
build_overlays[index] = icon2appearance(overlay)
|
||||
return build_overlays
|
||||
|
||||
/atom/proc/cut_overlays()
|
||||
|
||||
@@ -214,12 +214,12 @@
|
||||
|
||||
//speech bubble
|
||||
if(owner.client)
|
||||
var/mutable_appearance/MA = mutable_appearance('icons/mob/effects/talk.dmi', src, "default[say_test(message)]", FLY_LAYER)
|
||||
SET_PLANE_EXPLICIT(MA, ABOVE_GAME_PLANE, src)
|
||||
MA.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA
|
||||
INVOKE_ASYNC(GLOBAL_PROC, /proc/flick_overlay, MA, list(owner.client), 30)
|
||||
LAZYADD(update_on_z, MA)
|
||||
addtimer(CALLBACK(src, .proc/clear_saypopup, MA), 3.5 SECONDS)
|
||||
var/image/bubble = mutable_appearance('icons/mob/effects/talk.dmi', src, "default[say_test(message)]", FLY_LAYER)
|
||||
SET_PLANE_EXPLICIT(bubble, ABOVE_GAME_PLANE, src)
|
||||
bubble.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA
|
||||
INVOKE_ASYNC(GLOBAL_PROC, /proc/flick_overlay, bubble, list(owner.client), 30)
|
||||
LAZYADD(update_on_z, bubble)
|
||||
addtimer(CALLBACK(src, .proc/clear_saypopup, bubble), 3.5 SECONDS)
|
||||
|
||||
for(var/mob/M in GLOB.dead_mob_list)
|
||||
var/link = FOLLOW_LINK(M, owner)
|
||||
|
||||
@@ -212,7 +212,7 @@
|
||||
|
||||
// Build message image
|
||||
message = image(loc = message_loc, layer = CHAT_LAYER + CHAT_LAYER_Z_STEP * current_z_idx++)
|
||||
SET_PLANE(message, RUNECHAT_PLANE, message_loc)
|
||||
SET_PLANE_EXPLICIT(message, RUNECHAT_PLANE, message_loc)
|
||||
message.appearance_flags = APPEARANCE_UI_IGNORE_ALPHA | KEEP_APART
|
||||
message.alpha = 0
|
||||
message.pixel_y = target.maptext_height
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
GLOBAL_DATUM_INIT(cleaning_bubbles_lower, /mutable_appearance, mutable_appearance('icons/effects/effects.dmi', "bubbles", FLOOR_CLEAN_LAYER, GAME_PLANE)) //displays at the top of floor tiles, but under mobs
|
||||
GLOBAL_DATUM_INIT(cleaning_bubbles_higher, /mutable_appearance, mutable_appearance('icons/effects/effects.dmi', "bubbles", FLOOR_CLEAN_LAYER, ABOVE_GAME_PLANE)) //displays above mobs
|
||||
|
||||
/**
|
||||
* Component that can be used to clean things.
|
||||
* Takes care of duration, cleaning skill and special cleaning interactions.
|
||||
@@ -93,15 +90,20 @@ GLOBAL_DATUM_INIT(cleaning_bubbles_higher, /mutable_appearance, mutable_appearan
|
||||
/datum/component/cleaner/proc/clean(datum/source, atom/target, mob/living/user, clean_target = TRUE)
|
||||
if(!HAS_TRAIT(target, CURRENTLY_CLEANING)) //add the trait and overlay
|
||||
ADD_TRAIT(target, CURRENTLY_CLEANING, src)
|
||||
if(target.plane > GLOB.cleaning_bubbles_lower.plane) //check if the higher overlay is necessary
|
||||
target.add_overlay(GLOB.cleaning_bubbles_higher)
|
||||
else if(target.plane == GLOB.cleaning_bubbles_lower.plane)
|
||||
if(target.layer > GLOB.cleaning_bubbles_lower.layer)
|
||||
target.add_overlay(GLOB.cleaning_bubbles_higher)
|
||||
|
||||
// We need to update our planes on overlay changes
|
||||
RegisterSignal(target, COMSIG_MOVABLE_Z_CHANGED, .proc/cleaning_target_moved)
|
||||
var/mutable_appearance/low_bubble = mutable_appearance('icons/effects/effects.dmi', "bubbles", FLOOR_CLEAN_LAYER, target, GAME_PLANE)
|
||||
var/mutable_appearance/high_bubble = mutable_appearance('icons/effects/effects.dmi', "bubbles", FLOOR_CLEAN_LAYER, target, ABOVE_GAME_PLANE)
|
||||
if(target.plane > low_bubble.plane) //check if the higher overlay is necessary
|
||||
target.add_overlay(high_bubble)
|
||||
else if(target.plane == low_bubble.plane)
|
||||
if(target.layer > low_bubble.layer)
|
||||
target.add_overlay(high_bubble)
|
||||
else
|
||||
target.add_overlay(GLOB.cleaning_bubbles_lower)
|
||||
else //(target.plane < GLOB.cleaning_bubbles_lower.plane)
|
||||
target.add_overlay(GLOB.cleaning_bubbles_lower)
|
||||
target.add_overlay(low_bubble)
|
||||
else //(target.plane < low_bubble.plane)
|
||||
target.add_overlay(low_bubble)
|
||||
|
||||
//set the cleaning duration
|
||||
var/cleaning_duration = base_cleaning_duration
|
||||
@@ -121,6 +123,23 @@ GLOBAL_DATUM_INIT(cleaning_bubbles_higher, /mutable_appearance, mutable_appearan
|
||||
on_cleaned_callback?.Invoke(source, target, user)
|
||||
|
||||
//remove the cleaning overlay
|
||||
target.cut_overlay(GLOB.cleaning_bubbles_lower)
|
||||
target.cut_overlay(GLOB.cleaning_bubbles_higher)
|
||||
var/mutable_appearance/low_bubble = mutable_appearance('icons/effects/effects.dmi', "bubbles", FLOOR_CLEAN_LAYER, target, GAME_PLANE)
|
||||
var/mutable_appearance/high_bubble = mutable_appearance('icons/effects/effects.dmi', "bubbles", FLOOR_CLEAN_LAYER, target, ABOVE_GAME_PLANE)
|
||||
target.cut_overlay(low_bubble)
|
||||
target.cut_overlay(high_bubble)
|
||||
REMOVE_TRAIT(target, CURRENTLY_CLEANING, src)
|
||||
|
||||
/datum/component/cleaner/proc/cleaning_target_moved(atom/movable/source, turf/old_turf, turf/new_turf, same_z_layer)
|
||||
if(same_z_layer)
|
||||
return
|
||||
// First, get rid of the old overlay
|
||||
var/mutable_appearance/old_low_bubble = mutable_appearance('icons/effects/effects.dmi', "bubbles", FLOOR_CLEAN_LAYER, old_turf, GAME_PLANE)
|
||||
var/mutable_appearance/old_high_bubble = mutable_appearance('icons/effects/effects.dmi', "bubbles", FLOOR_CLEAN_LAYER, old_turf, ABOVE_GAME_PLANE)
|
||||
source.cut_overlay(old_low_bubble)
|
||||
source.cut_overlay(old_high_bubble)
|
||||
|
||||
// Now, add the new one
|
||||
var/mutable_appearance/new_low_bubble = mutable_appearance('icons/effects/effects.dmi', "bubbles", FLOOR_CLEAN_LAYER, new_turf, GAME_PLANE)
|
||||
var/mutable_appearance/new_high_bubble = mutable_appearance('icons/effects/effects.dmi', "bubbles", FLOOR_CLEAN_LAYER, new_turf, ABOVE_GAME_PLANE)
|
||||
source.add_overlay(new_low_bubble)
|
||||
source.add_overlay(new_high_bubble)
|
||||
|
||||
@@ -11,21 +11,35 @@
|
||||
if(!to_copy)
|
||||
plane = FLOAT_PLANE
|
||||
|
||||
/// Helper similar to image()
|
||||
/** Helper similar to image()
|
||||
*
|
||||
* icon - Our appearance's icon
|
||||
* icon_state - Our appearance's icon state
|
||||
* layer - Our appearance's layer
|
||||
* atom/offset_spokesman - An atom to use as reference for the z position of this appearance.
|
||||
* Only required if a plane is passed in. If this is not passed in we accept offset_const as a substitute
|
||||
* plane - The plane to use for the appearance. If this is not FLOAT_PLANE we require context for the offset to use
|
||||
* alpha - Our appearance's alpha
|
||||
* appearance_flags - Our appearance's appearance_flags
|
||||
* offset_const - A constant to offset our plane by, so it renders on the right "z layer"
|
||||
**/
|
||||
/proc/mutable_appearance(icon, icon_state = "", layer = FLOAT_LAYER, atom/offset_spokesman, plane = FLOAT_PLANE, alpha = 255, appearance_flags = NONE, offset_const)
|
||||
if(plane != FLOAT_PLANE)
|
||||
// Essentially, we allow users that only want one static offset to pass one in
|
||||
if(!isnull(offset_const))
|
||||
plane = GET_NEW_PLANE(plane, offset_const)
|
||||
// That, or you need to pass in some non null object to reference
|
||||
else if(!isnull(offset_spokesman))
|
||||
else if(isatom(offset_spokesman))
|
||||
// Note, we are ok with null turfs, that's not an error condition we'll just default to 0, the error would be
|
||||
// Not passing ANYTHING in, key difference
|
||||
var/turf/our_turf = get_turf(offset_spokesman)
|
||||
plane = MUTATE_PLANE(plane, our_turf)
|
||||
// otherwise if you're setting plane you better have the guts to back it up
|
||||
else
|
||||
stack_trace("No plane offset passed in as context for a non floating mutable appearance, ya done fucked up")
|
||||
stack_trace("No plane offset passed in as context for a non floating mutable appearance, things are gonna go to hell on multiz maps")
|
||||
else if(!isnull(offset_spokesman) && !isatom(offset_spokesman))
|
||||
stack_trace("Why did you pass in offset_spokesman as [offset_spokesman]? We need an atom to properly offset planes")
|
||||
|
||||
var/mutable_appearance/MA = new()
|
||||
MA.icon = icon
|
||||
MA.icon_state = icon_state
|
||||
|
||||
@@ -64,6 +64,11 @@
|
||||
/// You will need to manage adding/removing from this yourself, but I'll do the updating for you
|
||||
var/list/image/update_on_z
|
||||
|
||||
/// Lazylist of all overlays attached to us to update when we change z levels
|
||||
/// You will need to manage adding/removing from this yourself, but I'll do the updating for you
|
||||
/// Oh and note, if order of addition is important this WILL break that. so mind yourself
|
||||
var/list/image/update_overlays_on_z
|
||||
|
||||
///Cooldown tick timer for buckle messages
|
||||
var/buckle_message_cooldown = 0
|
||||
///Last fingerprints to touch this atom
|
||||
|
||||
@@ -1052,9 +1052,17 @@
|
||||
// so we do this. sucks to suck
|
||||
update_appearance()
|
||||
|
||||
if(update_on_z)
|
||||
// I so much wish this could be somewhere else. alas, no.
|
||||
for(var/image/update in update_on_z)
|
||||
SET_PLANE(update, PLANE_TO_TRUE(update.plane), new_turf)
|
||||
if(update_overlays_on_z)
|
||||
// This EVEN more so
|
||||
cut_overlay(update_overlays_on_z)
|
||||
// This even more so
|
||||
for(var/mutable_appearance/update in update_overlays_on_z)
|
||||
SET_PLANE(update, PLANE_TO_TRUE(update.plane), new_turf)
|
||||
add_overlay(update_overlays_on_z)
|
||||
|
||||
if(!notify_contents)
|
||||
return
|
||||
|
||||
@@ -135,6 +135,7 @@
|
||||
. = ..()
|
||||
if(same_z_layer)
|
||||
return
|
||||
if(warp)
|
||||
SET_PLANE(warp, PLANE_TO_TRUE(warp.plane), new_turf)
|
||||
|
||||
/obj/effect/anomaly/grav/anomalyEffect(delta_time)
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
GLOBAL_DATUM_INIT(fire_overlay, /mutable_appearance, mutable_appearance('icons/effects/fire.dmi', "fire"))
|
||||
GLOBAL_DATUM_INIT(welding_sparks, /mutable_appearance, mutable_appearance('icons/effects/welding_effect.dmi', "welding_sparks", GASFIRE_LAYER, ABOVE_LIGHTING_PLANE))
|
||||
GLOBAL_DATUM_INIT(fire_overlay, /mutable_appearance, mutable_appearance('icons/effects/fire.dmi', "fire", appearance_flags = RESET_COLOR))
|
||||
|
||||
/// Anything you can pick up and hold.
|
||||
/obj/item
|
||||
|
||||
@@ -120,9 +120,12 @@
|
||||
qdel(src)
|
||||
|
||||
/obj/item/weldingtool/use_tool(atom/target, mob/living/user, delay, amount, volume, datum/callback/extra_checks)
|
||||
target.add_overlay(GLOB.welding_sparks)
|
||||
var/mutable_appearance/sparks = mutable_appearance('icons/effects/welding_effect.dmi', "welding_sparks", GASFIRE_LAYER, src, ABOVE_LIGHTING_PLANE)
|
||||
target.add_overlay(sparks)
|
||||
target.update_overlays_on_z += sparks
|
||||
. = ..()
|
||||
target.cut_overlay(GLOB.welding_sparks)
|
||||
target.update_overlays_on_z -= sparks
|
||||
target.cut_overlay(sparks)
|
||||
|
||||
/obj/item/weldingtool/attack(mob/living/carbon/human/attacked_humanoid, mob/living/user)
|
||||
if(!istype(attacked_humanoid))
|
||||
|
||||
@@ -213,22 +213,16 @@
|
||||
. = ..()
|
||||
SET_PLANE_IMPLICIT(src, initial(plane))
|
||||
|
||||
GLOBAL_LIST_INIT_TYPED(cryo_overlays_cover_on, /mutable_appearance, list(create_cryo_overlay(0, "cover-on")))
|
||||
GLOBAL_LIST_INIT_TYPED(cryo_overlays_cover_off, /mutable_appearance, list(create_cryo_overlay(0, "cover-off")))
|
||||
|
||||
/proc/create_cryo_overlay(offset, icon_state)
|
||||
var/mutable_appearance/cryo_overlay = mutable_appearance('icons/obj/medical/cryogenics.dmi', icon_state, ABOVE_ALL_MOB_LAYER, plane = ABOVE_GAME_PLANE, offset_const = offset)
|
||||
return cryo_overlay
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/cryo_cell/update_overlays()
|
||||
. = ..()
|
||||
if(panel_open)
|
||||
. += "pod-panel"
|
||||
if(state_open)
|
||||
return
|
||||
var/turf/our_turf = get_turf(src)
|
||||
var/offset = GET_TURF_PLANE_OFFSET(our_turf) + 1
|
||||
. += (on && is_operational) ? GLOB.cryo_overlays_cover_on[offset] : GLOB.cryo_overlays_cover_off[offset]
|
||||
if(on && is_operational)
|
||||
. += mutable_appearance('icons/obj/medical/cryogenics.dmi', "cover-on", ABOVE_ALL_MOB_LAYER, src, plane = ABOVE_GAME_PLANE)
|
||||
else
|
||||
. += mutable_appearance('icons/obj/medical/cryogenics.dmi', "cover-on", ABOVE_ALL_MOB_LAYER, src, plane = ABOVE_GAME_PLANE)
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/cryo_cell/nap_violation(mob/violator)
|
||||
open_machine()
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
// The datum containing all the chunks.
|
||||
|
||||
#define CHUNK_SIZE 16 // Only chunk sizes that are to the power of 2. E.g: 2, 4, 8, 16, etc..
|
||||
|
||||
/// Takes a position, transforms it into a chunk bounded position. Indexes at 1 so it'll land on actual turfs always
|
||||
#define GET_CHUNK_COORD(v) (FLOOR(v, CHUNK_SIZE) + 1)
|
||||
GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new)
|
||||
|
||||
/datum/cameranet
|
||||
@@ -39,17 +40,17 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new)
|
||||
|
||||
/// Checks if a chunk has been Generated in x, y, z.
|
||||
/datum/cameranet/proc/chunkGenerated(x, y, z)
|
||||
var/turf/lowest = get_lowest_turf(locate(max(x, 1), max(y, 1), z))
|
||||
x &= ~(CHUNK_SIZE - 1)
|
||||
y &= ~(CHUNK_SIZE - 1)
|
||||
x = GET_CHUNK_COORD(x)
|
||||
y = GET_CHUNK_COORD(y)
|
||||
var/turf/lowest = get_lowest_turf(locate(x, y, z))
|
||||
return chunks["[x],[y],[lowest.z]"]
|
||||
|
||||
// Returns the chunk in the x, y, z.
|
||||
// If there is no chunk, it creates a new chunk and returns that.
|
||||
/datum/cameranet/proc/getCameraChunk(x, y, z)
|
||||
x = GET_CHUNK_COORD(x)
|
||||
y = GET_CHUNK_COORD(y)
|
||||
var/turf/lowest = get_lowest_turf(locate(x, y, z))
|
||||
x &= ~(CHUNK_SIZE - 1)
|
||||
y &= ~(CHUNK_SIZE - 1)
|
||||
var/key = "[x],[y],[lowest.z]"
|
||||
. = chunks[key]
|
||||
if(!.)
|
||||
@@ -67,12 +68,11 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new)
|
||||
for(var/mob/camera/ai_eye/eye as anything in moved_eyes)
|
||||
var/list/visibleChunks = list()
|
||||
if(eye.loc)
|
||||
// 0xf = 15
|
||||
var/static_range = eye.static_visibility_range
|
||||
var/x1 = max(0, eye.x - static_range) & ~(CHUNK_SIZE - 1)
|
||||
var/y1 = max(0, eye.y - static_range) & ~(CHUNK_SIZE - 1)
|
||||
var/x2 = min(world.maxx, eye.x + static_range) & ~(CHUNK_SIZE - 1)
|
||||
var/y2 = min(world.maxy, eye.y + static_range) & ~(CHUNK_SIZE - 1)
|
||||
var/x1 = max(1, eye.x - static_range)
|
||||
var/y1 = max(1, eye.y - static_range)
|
||||
var/x2 = min(world.maxx, eye.x + static_range)
|
||||
var/y2 = min(world.maxy, eye.y + static_range)
|
||||
|
||||
for(var/x = x1; x <= x2; x += CHUNK_SIZE)
|
||||
for(var/y = y1; y <= y2; y += CHUNK_SIZE)
|
||||
@@ -126,10 +126,10 @@ GLOBAL_DATUM_INIT(cameranet, /datum/cameranet, new)
|
||||
|
||||
var/turf/T = get_turf(c)
|
||||
if(T)
|
||||
var/x1 = max(0, T.x - (CHUNK_SIZE / 2)) & ~(CHUNK_SIZE - 1)
|
||||
var/y1 = max(0, T.y - (CHUNK_SIZE / 2)) & ~(CHUNK_SIZE - 1)
|
||||
var/x2 = min(world.maxx, T.x + (CHUNK_SIZE / 2)) & ~(CHUNK_SIZE - 1)
|
||||
var/y2 = min(world.maxy, T.y + (CHUNK_SIZE / 2)) & ~(CHUNK_SIZE - 1)
|
||||
var/x1 = max(1, T.x - (CHUNK_SIZE / 2))
|
||||
var/y1 = max(1, T.y - (CHUNK_SIZE / 2))
|
||||
var/x2 = min(world.maxx, T.x + (CHUNK_SIZE / 2))
|
||||
var/y2 = min(world.maxy, T.y + (CHUNK_SIZE / 2))
|
||||
for(var/x = x1; x <= x2; x += CHUNK_SIZE)
|
||||
for(var/y = y1; y <= y2; y += CHUNK_SIZE)
|
||||
var/datum/camerachunk/chunk = chunkGenerated(x, y, T.z)
|
||||
|
||||
@@ -126,8 +126,8 @@
|
||||
|
||||
/// Create a new camera chunk, since the chunks are made as they are needed.
|
||||
/datum/camerachunk/New(x, y, lower_z)
|
||||
x &= ~(CHUNK_SIZE - 1)
|
||||
y &= ~(CHUNK_SIZE - 1)
|
||||
x = GET_CHUNK_COORD(x)
|
||||
y = GET_CHUNK_COORD(y)
|
||||
|
||||
src.x = x
|
||||
src.y = y
|
||||
@@ -171,3 +171,4 @@
|
||||
|
||||
#undef UPDATE_BUFFER_TIME
|
||||
#undef CHUNK_SIZE
|
||||
#undef GET_CHUNK_COORD
|
||||
|
||||
@@ -57,11 +57,11 @@
|
||||
thought_bubble.overlays += point_visual
|
||||
|
||||
add_overlay(thought_bubble)
|
||||
LAZYADD(update_on_z, thought_bubble)
|
||||
LAZYADD(update_overlays_on_z, thought_bubble)
|
||||
addtimer(CALLBACK(src, .proc/clear_point_bubble, thought_bubble), POINT_TIME)
|
||||
|
||||
/atom/movable/proc/clear_point_bubble(mutable_appearance/thought_bubble)
|
||||
LAZYREMOVE(update_on_z, thought_bubble)
|
||||
LAZYREMOVE(update_overlays_on_z, thought_bubble)
|
||||
cut_overlay(thought_bubble)
|
||||
|
||||
/obj/effect/temp_visual/point
|
||||
|
||||
@@ -176,9 +176,12 @@
|
||||
/obj/item/gun/energy/plasmacutter/use_tool(atom/target, mob/living/user, delay, amount=1, volume=0, datum/callback/extra_checks)
|
||||
|
||||
if(amount)
|
||||
target.add_overlay(GLOB.welding_sparks)
|
||||
var/mutable_appearance/sparks = mutable_appearance('icons/effects/welding_effect.dmi', "welding_sparks", GASFIRE_LAYER, src, ABOVE_LIGHTING_PLANE)
|
||||
target.add_overlay(sparks)
|
||||
target.update_overlays_on_z += sparks
|
||||
. = ..()
|
||||
target.cut_overlay(GLOB.welding_sparks)
|
||||
target.update_overlays_on_z -= sparks
|
||||
target.cut_overlay(sparks)
|
||||
else
|
||||
. = ..(amount=1)
|
||||
|
||||
|
||||
@@ -140,6 +140,7 @@
|
||||
#include "outfit_sanity.dm"
|
||||
#include "paintings.dm"
|
||||
#include "pills.dm"
|
||||
#include "plane_double_transform.dm"
|
||||
#include "plane_dupe_detector.dm"
|
||||
#include "plantgrowth_tests.dm"
|
||||
#include "preference_species.dm"
|
||||
|
||||
44
code/modules/unit_tests/plane_double_transform.dm
Normal file
44
code/modules/unit_tests/plane_double_transform.dm
Normal file
@@ -0,0 +1,44 @@
|
||||
/// Ensures plane masters that get shrunk by multiz NEVER render into each other
|
||||
/datum/unit_test/plane_double_transform
|
||||
|
||||
/datum/unit_test/plane_double_transform/Run()
|
||||
// We're going to operate off the actual plane master setup of an actual mob
|
||||
// It's not perfect, but it'll help things a lot
|
||||
var/mob/living/carbon/human/judger = allocate(/mob/living/carbon/human)
|
||||
// Hack to account for not having an actual hud
|
||||
var/datum/plane_master_group/hudless/our_group = allocate(/datum/plane_master_group/hudless)
|
||||
our_group.our_mob = judger
|
||||
our_group.show_hud()
|
||||
// End hack
|
||||
|
||||
// Generates a list of render target -> PM for future use
|
||||
var/list/render_target_to_plane = list()
|
||||
for(var/plane_key as anything in our_group.plane_masters)
|
||||
var/atom/movable/screen/plane_master/plane = our_group.plane_masters[plane_key]
|
||||
if(plane.render_target)
|
||||
render_target_to_plane[plane.render_target] = plane
|
||||
|
||||
|
||||
for(var/plane_key as anything in our_group.plane_masters)
|
||||
var/atom/movable/screen/plane_master/plane = our_group.plane_masters[plane_key]
|
||||
|
||||
if(!plane.multiz_scaled)
|
||||
continue
|
||||
|
||||
// Walk the relay targets
|
||||
for(var/target_plane in plane.render_relay_planes)
|
||||
var/atom/movable/screen/plane_master/target = our_group.plane_masters["[target_plane]"]
|
||||
if(target.multiz_scaled)
|
||||
TEST_FAIL("[plane.type] draws a render relay into [target.type]. Both are scaled by multiz, so this will cause strange transforms.\n\
|
||||
consider making a new render plate that they can both draw to instead, or something of that nature.")
|
||||
|
||||
// Now we walk for filters that take from us
|
||||
for(var/filter_id in plane.filter_data)
|
||||
var/list/filter = plane.filter_data[filter_id]
|
||||
if(!filter["render_source"])
|
||||
continue
|
||||
var/atom/movable/screen/plane_master/target = render_target_to_plane[filter["render_source"]]
|
||||
if(target.multiz_scaled)
|
||||
TEST_FAIL("[plane.type] draws a render relay into [target.type]. Both are scaled by multiz, so this will cause strange transforms.\n\
|
||||
consider making a new render plate that they can both draw to instead, or something of that nature.")
|
||||
|
||||
@@ -76,11 +76,17 @@ GLOBAL_LIST_EMPTY(unit_test_mapping_logs)
|
||||
/// Instances allocated through this proc will be destroyed when the test is over
|
||||
/datum/unit_test/proc/allocate(type, ...)
|
||||
var/list/arguments = args.Copy(2)
|
||||
if(ispath(type, /atom))
|
||||
if (!arguments.len)
|
||||
arguments = list(run_loc_floor_bottom_left)
|
||||
else if (arguments[1] == null)
|
||||
arguments[1] = run_loc_floor_bottom_left
|
||||
var/instance = new type(arglist(arguments))
|
||||
var/instance
|
||||
// Byond will throw an index out of bounds if arguments is empty in that arglist call. Sigh
|
||||
if(length(arguments))
|
||||
instance = new type(arglist(arguments))
|
||||
else
|
||||
instance = new type()
|
||||
allocated += instance
|
||||
return instance
|
||||
|
||||
|
||||
@@ -193,6 +193,25 @@
|
||||
if(harderforce)
|
||||
. = ..()
|
||||
|
||||
/**
|
||||
* Add liquid effect overlay.
|
||||
*
|
||||
* Arguments:
|
||||
* * overlay_state - the icon state of the new overlay
|
||||
* * overlay_layer - the layer
|
||||
* * overlay_plane - the plane
|
||||
*/
|
||||
/obj/effect/abstract/liquid_turf/proc/add_liquid_overlay(overlay_state, overlay_layer, overlay_plane)
|
||||
PRIVATE_PROC(TRUE)
|
||||
|
||||
add_overlay(mutable_appearance(
|
||||
'modular_skyrat/modules/liquids/icons/obj/effects/liquid_overlays.dmi',
|
||||
overlay_state,
|
||||
overlay_layer,
|
||||
src,
|
||||
overlay_plane,
|
||||
))
|
||||
|
||||
/**
|
||||
* Add over and underlays for different liquid states.
|
||||
*
|
||||
@@ -201,24 +220,14 @@
|
||||
* * has_top - if this stage has a top.
|
||||
*/
|
||||
/obj/effect/abstract/liquid_turf/proc/add_state_layer(state, has_top)
|
||||
add_overlay(mutable_appearance(
|
||||
'modular_skyrat/modules/liquids/icons/obj/effects/liquid_overlays.dmi',
|
||||
"stage[state]_bottom",
|
||||
offset_spokesman = src,
|
||||
plane = GAME_PLANE,
|
||||
layer = ABOVE_MOB_LAYER,
|
||||
))
|
||||
PRIVATE_PROC(TRUE)
|
||||
|
||||
add_liquid_overlay("stage[state]_bottom", ABOVE_MOB_LAYER, GAME_PLANE_UPPER)
|
||||
|
||||
if(!has_top)
|
||||
return
|
||||
|
||||
add_overlay(mutable_appearance(
|
||||
'modular_skyrat/modules/liquids/icons/obj/effects/liquid_overlays.dmi',
|
||||
"stage[state]_top",
|
||||
offset_spokesman = src,
|
||||
plane = GAME_PLANE,
|
||||
layer = GATEWAY_UNDERLAY_LAYER
|
||||
))
|
||||
add_liquid_overlay("stage[state]_top", GATEWAY_UNDERLAY_LAYER, GAME_PLANE)
|
||||
|
||||
/obj/effect/abstract/liquid_turf/proc/set_new_liquid_state(new_state)
|
||||
liquid_state = new_state
|
||||
|
||||
@@ -15,18 +15,37 @@
|
||||
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
|
||||
anchored = TRUE
|
||||
layer = ABOVE_MOB_LAYER
|
||||
vis_flags = VIS_INHERIT_PLANE
|
||||
plane = GAME_PLANE_UPPER
|
||||
|
||||
/obj/effect/overlay/water/top
|
||||
icon_state = "top"
|
||||
layer = BELOW_MOB_LAYER
|
||||
plane = GAME_PLANE
|
||||
|
||||
/**
|
||||
* Planetside water, indestructible.
|
||||
*
|
||||
* Use this for indoors.
|
||||
*/
|
||||
/turf/open/water/overlay
|
||||
name = "shallow water"
|
||||
desc = "A natural body of shallow water."
|
||||
icon = 'modular_skyrat/modules/mapping/icons/unique/pool.dmi'
|
||||
icon_state = "rocky"
|
||||
baseturfs = /turf/open/water/overlay
|
||||
initial_gas_mix = OPENTURF_DEFAULT_ATMOS
|
||||
planetary_atmos = FALSE
|
||||
|
||||
/turf/open/water/overlay/Initialize(mapload)
|
||||
. = ..()
|
||||
var/obj/effect/overlay/water/water_overlay = new()
|
||||
var/obj/effect/overlay/water/top/water_top_overlay = new()
|
||||
vis_contents += water_overlay
|
||||
vis_contents += water_top_overlay
|
||||
|
||||
var/obj/effect/overlay/water/bottom = new()
|
||||
SET_PLANE(bottom, PLANE_TO_TRUE(bottom.plane), src)
|
||||
vis_contents += bottom
|
||||
|
||||
var/obj/effect/overlay/water/top/top = new()
|
||||
SET_PLANE(top, PLANE_TO_TRUE(top.plane), src)
|
||||
vis_contents += top
|
||||
|
||||
/turf/open/water/overlay/Entered(atom/movable/arrived)
|
||||
..()
|
||||
@@ -50,25 +69,18 @@
|
||||
mood_change = 4
|
||||
timeout = 20 MINUTES
|
||||
|
||||
// Planetside water, indestructible.
|
||||
/turf/open/water/overlay
|
||||
name = "shallow water"
|
||||
desc = "A natural body of shallow water."
|
||||
icon = 'modular_skyrat/modules/mapping/icons/unique/pool.dmi'
|
||||
icon_state = "rocky"
|
||||
baseturfs = /turf/open/water/overlay
|
||||
var/obj/effect/overlay/water/water_overlay
|
||||
var/obj/effect/overlay/water/top/water_top_overlay
|
||||
initial_gas_mix = OPENTURF_DEFAULT_ATMOS
|
||||
planetary_atmos = FALSE
|
||||
// Use this for indoors. It has a roof!
|
||||
|
||||
/**
|
||||
* Planetside water, indestructible.
|
||||
*
|
||||
* Use this for outdoors. It normalises to it's initial airmix over time!
|
||||
*/
|
||||
/turf/open/water/overlay/outdoors
|
||||
baseturfs = /turf/open/water/overlay/outdoors
|
||||
planetary_atmos = TRUE
|
||||
// Use this for outdoors. It normalises to it's initial airmix over time!
|
||||
|
||||
// Hotpsrings! They give a positive mood event.
|
||||
/**
|
||||
* Hotpsrings! They give a positive mood event.
|
||||
*/
|
||||
/turf/open/water/overlay/hotspring
|
||||
name = "hotspring"
|
||||
desc = "A warm, steamy swimming pool."
|
||||
|
||||
Reference in New Issue
Block a user