mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-31 00:58:26 +01:00
[MIRROR] Small ventcrawling refactor (#4183)
* Small ventcrawling refactor (#57707) Co-authored-by: Mothblocks <35135081+Mothblocks@ users.noreply.github.com> * Small ventcrawling refactor Co-authored-by: vincentiusvin <54709710+vincentiusvin@users.noreply.github.com> Co-authored-by: Mothblocks <35135081+Mothblocks@ users.noreply.github.com>
This commit is contained in:
co-authored by
Mothblocks
vincentiusvin
parent
2077bd9c5e
commit
e4d1772f1b
@@ -544,3 +544,11 @@ GLOBAL_LIST_INIT(pipe_paint_colors, sortList(list(
|
||||
#define EUPHORIA_INACTIVE 0
|
||||
#define EUPHORIA_ACTIVE 1
|
||||
#define EUPHORIA_LAST_FLAG 2
|
||||
|
||||
// Ventcrawling bitflags, handled in var/vent_movement
|
||||
///Allows for ventcrawling to occur. All atmospheric machines have this flag on by default. Cryo is the exception
|
||||
#define VENTCRAWL_ALLOWED (1<<0)
|
||||
///Allows mobs to enter or leave from atmospheric machines. On for passive, unary, and scrubber vents.
|
||||
#define VENTCRAWL_ENTRANCE_ALLOWED (1<<1)
|
||||
///Used to check if a machinery is visible. Called by update_pipe_vision(). On by default for all except cryo.
|
||||
#define VENTCRAWL_CAN_SEE (1<<2)
|
||||
|
||||
@@ -56,12 +56,15 @@
|
||||
///Whether it can be painted
|
||||
var/paintable = FALSE
|
||||
|
||||
///Is the thing being rebuilt by SSair or not. Prevents list blaot
|
||||
///Is the thing being rebuilt by SSair or not. Prevents list bloat
|
||||
var/rebuilding = FALSE
|
||||
|
||||
///The bitflag that's being checked on ventcrawling. Default is to allow ventcrawling and seeing pipes.
|
||||
var/vent_movement = VENTCRAWL_ALLOWED | VENTCRAWL_CAN_SEE
|
||||
|
||||
/obj/machinery/atmospherics/examine(mob/user)
|
||||
. = ..()
|
||||
if(is_type_in_list(src, GLOB.ventcrawl_machinery) && isliving(user))
|
||||
if((vent_movement & VENTCRAWL_ENTRANCE_ALLOWED) && isliving(user))
|
||||
var/mob/living/L = user
|
||||
if(HAS_TRAIT(L, TRAIT_VENTCRAWLER_NUDE) || HAS_TRAIT(L, TRAIT_VENTCRAWLER_ALWAYS))
|
||||
. += "<span class='notice'>Alt-click to crawl through it.</span>"
|
||||
@@ -429,6 +432,7 @@
|
||||
|
||||
#define VENT_SOUND_DELAY 30
|
||||
|
||||
// Handles mob movement inside a pipenet
|
||||
/obj/machinery/atmospherics/relaymove(mob/living/user, direction)
|
||||
direction &= initialize_directions
|
||||
if(!direction || !(direction in GLOB.cardinals)) //cant go this way.
|
||||
@@ -439,40 +443,29 @@
|
||||
|
||||
var/obj/machinery/atmospherics/target_move = findConnecting(direction, user.ventcrawl_layer)
|
||||
if(target_move)
|
||||
if(target_move.can_crawl_through())
|
||||
if(is_type_in_typecache(target_move, GLOB.ventcrawl_machinery))
|
||||
user.forceMove(target_move.loc) //handle entering and so on.
|
||||
user.visible_message("<span class='notice'>You hear something squeezing through the ducts...</span>", "<span class='notice'>You climb out the ventilation system.</span>")
|
||||
else
|
||||
var/list/pipenetdiff = returnPipenets() ^ target_move.returnPipenets()
|
||||
if(pipenetdiff.len)
|
||||
user.update_pipe_vision(target_move)
|
||||
user.forceMove(target_move)
|
||||
user.client.eye = target_move //Byond only updates the eye every tick, This smooths out the movement
|
||||
if(world.time - user.last_played_vent > VENT_SOUND_DELAY)
|
||||
user.last_played_vent = world.time
|
||||
playsound(src, 'sound/machines/ventcrawl.ogg', 50, TRUE, -3)
|
||||
else if(is_type_in_typecache(src, GLOB.ventcrawl_machinery) && can_crawl_through()) //if we move in a way the pipe can connect, but doesn't - or we're in a vent
|
||||
user.forceMove(loc)
|
||||
user.visible_message("<span class='notice'>You hear something squeezing through the ducts...</span>", "<span class='notice'>You climb out the ventilation system.</span>")
|
||||
if(target_move.vent_movement & VENTCRAWL_ALLOWED)
|
||||
user.forceMove(target_move)
|
||||
user.client.eye = target_move //Byond only updates the eye every tick, This smooths out the movement
|
||||
var/list/pipenetdiff = returnPipenets() ^ target_move.returnPipenets()
|
||||
if(pipenetdiff.len)
|
||||
user.update_pipe_vision()
|
||||
if(world.time - user.last_played_vent > VENT_SOUND_DELAY)
|
||||
user.last_played_vent = world.time
|
||||
playsound(src, 'sound/machines/ventcrawl.ogg', 50, TRUE, -3)
|
||||
|
||||
//Would be great if this could be implemented when someone alt-clicks the image.
|
||||
if (target_move.vent_movement & VENTCRAWL_ENTRANCE_ALLOWED)
|
||||
user.handle_ventcrawl(target_move)
|
||||
//PLACEHOLDER COMMENT FOR ME TO READD THE 1 (?) DS DELAY THAT WAS IMPLEMENTED WITH A... TIMER?
|
||||
|
||||
/obj/machinery/atmospherics/AltClick(mob/living/L)
|
||||
if(istype(L) && is_type_in_list(src, GLOB.ventcrawl_machinery))
|
||||
if(!(vent_movement & VENTCRAWL_ALLOWED)) // Early return for machines which does not allow ventcrawling at all.
|
||||
return
|
||||
if(istype(L))
|
||||
L.handle_ventcrawl(src)
|
||||
return
|
||||
..()
|
||||
|
||||
/**
|
||||
* Getter for vent crawling
|
||||
*
|
||||
* returns TRUE or FALSE, many devices overrides this (like cryo, or vents)
|
||||
* called by relaymove()
|
||||
*/
|
||||
/obj/machinery/atmospherics/proc/can_crawl_through()
|
||||
return TRUE
|
||||
|
||||
/**
|
||||
* Getter of a list of pipenets
|
||||
*
|
||||
|
||||
@@ -94,6 +94,7 @@
|
||||
var/obj/item/radio/radio
|
||||
var/radio_key = /obj/item/encryptionkey/headset_med
|
||||
var/radio_channel = RADIO_CHANNEL_MEDICAL
|
||||
vent_movement = NONE
|
||||
|
||||
/// Visual content - Occupant
|
||||
var/atom/movable/visual/cryo_occupant/occupant_vis
|
||||
@@ -510,9 +511,6 @@ GLOBAL_VAR_INIT(cryo_overlay_cover_off, mutable_appearance('icons/obj/cryogenics
|
||||
/obj/machinery/atmospherics/components/unary/cryo_cell/get_remote_view_fullscreens(mob/user)
|
||||
user.overlay_fullscreen("remote_view", /atom/movable/screen/fullscreen/impaired, 1)
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/cryo_cell/can_crawl_through()
|
||||
return // can't ventcrawl in or out of cryo.
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/cryo_cell/can_see_pipes()
|
||||
return FALSE // you can't see the pipe network when inside a cryo cell.
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
shift_underlay_only = FALSE
|
||||
|
||||
pipe_state = "pvent"
|
||||
vent_movement = VENTCRAWL_ALLOWED | VENTCRAWL_CAN_SEE | VENTCRAWL_ENTRANCE_ALLOWED
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/passive_vent/update_icon_nopipes()
|
||||
cut_overlays()
|
||||
@@ -28,9 +29,6 @@
|
||||
air_update_turf(FALSE, FALSE)
|
||||
update_parents()
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/passive_vent/can_crawl_through()
|
||||
return TRUE
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/passive_vent/layer2
|
||||
piping_layer = 2
|
||||
icon_state = "passive_vent_map-2"
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
var/radio_filter_in
|
||||
|
||||
pipe_state = "uvent"
|
||||
vent_movement = VENTCRAWL_ALLOWED | VENTCRAWL_CAN_SEE | VENTCRAWL_ENTRANCE_ALLOWED
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/vent_pump/New()
|
||||
if(!id_tag)
|
||||
@@ -286,9 +287,6 @@
|
||||
. = ..()
|
||||
update_icon_nopipes()
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/vent_pump/can_crawl_through()
|
||||
return !welded
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/vent_pump/attack_alien(mob/user, list/modifiers)
|
||||
if(!welded || !(do_after(user, 20, target = src)))
|
||||
return
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
var/radio_filter_in
|
||||
|
||||
pipe_state = "scrubber"
|
||||
vent_movement = VENTCRAWL_ALLOWED | VENTCRAWL_CAN_SEE | VENTCRAWL_ENTRANCE_ALLOWED
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/vent_scrubber/New()
|
||||
if(!id_tag)
|
||||
@@ -295,9 +296,6 @@
|
||||
if(welded)
|
||||
. += "It seems welded shut."
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/vent_scrubber/can_crawl_through()
|
||||
return !welded
|
||||
|
||||
/obj/machinery/atmospherics/components/unary/vent_scrubber/attack_alien(mob/user, list/modifiers)
|
||||
if(!welded || !(do_after(user, 20, target = src)))
|
||||
return
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
// VENTCRAWLING
|
||||
// Handles the entrance and exit on ventcrawling
|
||||
/mob/living/proc/handle_ventcrawl(obj/machinery/atmospherics/components/ventcrawl_target)
|
||||
// Being able to always ventcrawl trumps being only able to ventcrawl when wearing nothing
|
||||
var/required_nudity = HAS_TRAIT(src, TRAIT_VENTCRAWLER_NUDE) && !HAS_TRAIT(src, TRAIT_VENTCRAWLER_ALWAYS)
|
||||
// Cache the vent_movement bitflag var from atmos machineries
|
||||
var/vent_movement = ventcrawl_target.vent_movement
|
||||
|
||||
GLOBAL_LIST_INIT(ventcrawl_machinery, typecacheof(list(
|
||||
/obj/machinery/atmospherics/components/unary/vent_pump,
|
||||
/obj/machinery/atmospherics/components/unary/vent_scrubber)))
|
||||
|
||||
//VENTCRAWLING
|
||||
|
||||
/mob/living/proc/handle_ventcrawl(atom/A)
|
||||
if(!Adjacent(A))
|
||||
if(!Adjacent(ventcrawl_target))
|
||||
return
|
||||
if(!HAS_TRAIT(src, TRAIT_VENTCRAWLER_NUDE) && !HAS_TRAIT(src, TRAIT_VENTCRAWLER_ALWAYS))
|
||||
return
|
||||
@@ -14,7 +14,7 @@ GLOBAL_LIST_INIT(ventcrawl_machinery, typecacheof(list(
|
||||
to_chat(src, "<span class='warning'>You must be conscious to do this!</span>")
|
||||
return
|
||||
if(HAS_TRAIT(src, TRAIT_IMMOBILIZED))
|
||||
to_chat(src, "<span class='warning'>You can't move into the vent!</span>")
|
||||
to_chat(src, "<span class='warning'>You currently can't move into the vent!</span>")
|
||||
return
|
||||
if(HAS_TRAIT(src, TRAIT_HANDS_BLOCKED))
|
||||
to_chat(src, "<span class='warning'>You need to be able to use your hands to ventcrawl!</span>")
|
||||
@@ -25,49 +25,41 @@ GLOBAL_LIST_INIT(ventcrawl_machinery, typecacheof(list(
|
||||
if(buckled)
|
||||
to_chat(src, "<span class='warning'>You can't vent crawl while buckled!</span>")
|
||||
return
|
||||
if(iscarbon(src) && required_nudity)
|
||||
if(length(get_equipped_items(include_pockets = TRUE)) || get_num_held_items())
|
||||
to_chat(src, "<span class='warning'>You can't crawl around in the ventilation ducts with items!</span>")
|
||||
return
|
||||
if(ventcrawl_target.welded)
|
||||
to_chat(src, "<span class='warning'>You can't crawl around a welded vent!</span>")
|
||||
return
|
||||
|
||||
var/obj/machinery/atmospherics/components/unary/vent_found
|
||||
|
||||
|
||||
if(A)
|
||||
vent_found = A
|
||||
if(!istype(vent_found) || !vent_found.can_crawl_through())
|
||||
vent_found = null
|
||||
|
||||
if(!vent_found)
|
||||
for(var/obj/machinery/atmospherics/machine in range(1,src))
|
||||
if(is_type_in_typecache(machine, GLOB.ventcrawl_machinery))
|
||||
vent_found = machine
|
||||
|
||||
if(!vent_found.can_crawl_through())
|
||||
vent_found = null
|
||||
|
||||
if(vent_found)
|
||||
break
|
||||
|
||||
// Being able to always ventcrawl trumps being only able to ventcrawl when wearing nothing
|
||||
var/required_nudity = HAS_TRAIT(src, TRAIT_VENTCRAWLER_NUDE) && !HAS_TRAIT(src, TRAIT_VENTCRAWLER_ALWAYS)
|
||||
|
||||
if(vent_found)
|
||||
var/datum/pipeline/vent_found_parent = vent_found.parents[1]
|
||||
if(vent_found_parent && (vent_found_parent.members.len || vent_found_parent.other_atmosmch))
|
||||
visible_message("<span class='notice'>[src] begins climbing into the ventilation system...</span>" ,"<span class='notice'>You begin climbing into the ventilation system...</span>")
|
||||
|
||||
if(!do_after(src, 25, target = vent_found))
|
||||
return
|
||||
|
||||
if(vent_movement & VENTCRAWL_ENTRANCE_ALLOWED)
|
||||
//Handle the exit here
|
||||
if(HAS_TRAIT(src, TRAIT_MOVE_VENTCRAWLING) && istype(loc, /obj/machinery/atmospherics) && movement_type & VENTCRAWLING)
|
||||
visible_message("<span class='notice'>[src] begins climbing out from the ventilation system...</span>" ,"<span class='notice'>You begin climbing out from the ventilation system...</span>")
|
||||
if(!client)
|
||||
return
|
||||
visible_message("<span class='notice'>[src] scrambles out from the ventilation ducts!</span>","<span class='notice'>You out from the ventilation ducts.</span>")
|
||||
forceMove(ventcrawl_target.loc)
|
||||
REMOVE_TRAIT(src, TRAIT_MOVE_VENTCRAWLING, VENTCRAWLING_TRAIT)
|
||||
update_pipe_vision()
|
||||
|
||||
if(iscarbon(src) && required_nudity)
|
||||
if(length(get_equipped_items(include_pockets = TRUE)) || get_num_held_items())
|
||||
to_chat(src, "<span class='warning'>You can't crawl around in the ventilation ducts with items!</span>")
|
||||
//Entrance here
|
||||
else
|
||||
var/datum/pipeline/vent_parent = ventcrawl_target.parents[1]
|
||||
if(vent_parent && (vent_parent.members.len || vent_parent.other_atmosmch))
|
||||
visible_message("<span class='notice'>[src] begins climbing into the ventilation system...</span>" ,"<span class='notice'>You begin climbing into the ventilation system...</span>")
|
||||
if(!do_after(src, 2.5 SECONDS, target = ventcrawl_target))
|
||||
return
|
||||
if(!client)
|
||||
return
|
||||
visible_message("<span class='notice'>[src] scrambles into the ventilation ducts!</span>","<span class='notice'>You climb into the ventilation ducts.</span>")
|
||||
forceMove(ventcrawl_target)
|
||||
ADD_TRAIT(src, TRAIT_MOVE_VENTCRAWLING, VENTCRAWLING_TRAIT)
|
||||
update_pipe_vision()
|
||||
else
|
||||
to_chat(src, "<span class='warning'>This ventilation duct is not connected to anything!</span>")
|
||||
|
||||
visible_message("<span class='notice'>[src] scrambles into the ventilation ducts!</span>","<span class='notice'>You climb into the ventilation ducts.</span>")
|
||||
forceMove(vent_found)
|
||||
else
|
||||
to_chat(src, "<span class='warning'>This ventilation duct is not connected to anything!</span>")
|
||||
|
||||
/mob/living/simple_animal/slime/handle_ventcrawl(atom/A)
|
||||
if(buckled)
|
||||
@@ -75,47 +67,40 @@ GLOBAL_LIST_INIT(ventcrawl_machinery, typecacheof(list(
|
||||
return
|
||||
return ..()
|
||||
|
||||
|
||||
/mob/living/proc/add_ventcrawl(obj/machinery/atmospherics/starting_machine)
|
||||
if(!istype(starting_machine) || !starting_machine.can_see_pipes())
|
||||
return
|
||||
var/list/totalMembers = list()
|
||||
|
||||
for(var/datum/pipeline/P in starting_machine.returnPipenets())
|
||||
totalMembers += P.members
|
||||
totalMembers += P.other_atmosmch
|
||||
|
||||
if(!totalMembers.len)
|
||||
return
|
||||
|
||||
if(client)
|
||||
for(var/X in totalMembers)
|
||||
var/obj/machinery/atmospherics/A = X //all elements in totalMembers are necessarily of this type.
|
||||
if(in_view_range(client.mob, A))
|
||||
if(!A.pipe_vision_img)
|
||||
A.pipe_vision_img = image(A, A.loc, layer = ABOVE_HUD_LAYER, dir = A.dir)
|
||||
A.pipe_vision_img.plane = ABOVE_HUD_PLANE
|
||||
client.images += A.pipe_vision_img
|
||||
pipes_shown += A.pipe_vision_img
|
||||
ADD_TRAIT(src, TRAIT_MOVE_VENTCRAWLING, VENTCRAWLING_TRAIT)
|
||||
|
||||
/mob/living/proc/remove_ventcrawl()
|
||||
if(client)
|
||||
/**
|
||||
* Everything related to pipe vision on ventcrawling is handled by update_pipe_vision().
|
||||
* Called on exit, entrance, and pipenet differences (e.g. moving to a new pipenet).
|
||||
* One important thing to note however is that the movement of the client's eye is handled by the relaymove() proc in /obj/machinery/atmospherics.
|
||||
* We move first and then call update. Dont flip this around
|
||||
*/
|
||||
/mob/living/proc/update_pipe_vision()
|
||||
// Take the pipe images from the client
|
||||
if (!isnull(client))
|
||||
for(var/image/current_image in pipes_shown)
|
||||
client.images -= current_image
|
||||
pipes_shown.len = 0
|
||||
REMOVE_TRAIT(src, TRAIT_MOVE_VENTCRAWLING, VENTCRAWLING_TRAIT)
|
||||
pipes_shown.len = 0
|
||||
|
||||
// Give the pipe images to the client
|
||||
if(HAS_TRAIT(src, TRAIT_MOVE_VENTCRAWLING) && istype(loc, /obj/machinery/atmospherics) && movement_type & VENTCRAWLING)
|
||||
var/list/total_members = list()
|
||||
var/obj/machinery/atmospherics/current_location = loc
|
||||
for(var/datum/pipeline/location_pipeline in current_location.returnPipenets())
|
||||
total_members += location_pipeline.members
|
||||
total_members += location_pipeline.other_atmosmch
|
||||
|
||||
if(!total_members.len)
|
||||
return
|
||||
|
||||
if(client)
|
||||
for(var/obj/machinery/atmospherics/pipenet_part in total_members)
|
||||
// If the machinery is not in view or is not meant to be seen, continue
|
||||
if(!in_view_range(client.mob, pipenet_part))
|
||||
continue
|
||||
if(!pipenet_part.vent_movement & VENTCRAWL_CAN_SEE)
|
||||
continue
|
||||
|
||||
//OOP
|
||||
/atom/proc/update_pipe_vision(atom/new_loc = null)
|
||||
return
|
||||
|
||||
/mob/living/update_pipe_vision(atom/new_loc = null)
|
||||
. = loc
|
||||
if(new_loc)
|
||||
. = new_loc
|
||||
remove_ventcrawl()
|
||||
add_ventcrawl(.)
|
||||
if(!pipenet_part.pipe_vision_img)
|
||||
pipenet_part.pipe_vision_img = image(pipenet_part, pipenet_part.loc, layer = ABOVE_HUD_LAYER, dir = pipenet_part.dir)
|
||||
pipenet_part.pipe_vision_img.plane = ABOVE_HUD_PLANE
|
||||
client.images += pipenet_part.pipe_vision_img
|
||||
pipes_shown += pipenet_part.pipe_vision_img
|
||||
|
||||
Reference in New Issue
Block a user