Ventcrawl port from Bay12/VG (#852)

Original code from /vg/, port credit goes to Zuhayr.
This commit is contained in:
Bedshaped
2016-09-10 20:36:07 +01:00
committed by skull132
parent 804851f6f6
commit 1668df7f9c
21 changed files with 350 additions and 155 deletions
+3
View File
@@ -1734,6 +1734,9 @@
#include "code\modules\vehicles\cargo_train.dm"
#include "code\modules\vehicles\train.dm"
#include "code\modules\vehicles\vehicle.dm"
#include "code\modules\ventcrawl\ventcrawl.dm"
#include "code\modules\ventcrawl\ventcrawl_atmospherics.dm"
#include "code\modules\ventcrawl\ventcrawl_verb.dm"
#include "code\modules\virus2\admin.dm"
#include "code\modules\virus2\analyser.dm"
#include "code\modules\virus2\antibodies.dm"
+2
View File
@@ -29,6 +29,8 @@ Pipelines + Other Objects -> Pipe network
var/pipe_color
var/global/datum/pipe_icon_manager/icon_manager
var/obj/machinery/atmospherics/node1
var/obj/machinery/atmospherics/node2
/obj/machinery/atmospherics/New()
if(!icon_manager)
@@ -6,9 +6,6 @@ obj/machinery/atmospherics/binary
var/datum/gas_mixture/air1
var/datum/gas_mixture/air2
var/obj/machinery/atmospherics/node1
var/obj/machinery/atmospherics/node2
var/datum/pipe_network/network1
var/datum/pipe_network/network2
@@ -17,9 +17,6 @@
var/dP = 0
var/obj/machinery/atmospherics/node1
var/obj/machinery/atmospherics/node2
var/datum/pipe_network/network1
var/datum/pipe_network/network2
@@ -7,8 +7,6 @@ obj/machinery/atmospherics/trinary
var/datum/gas_mixture/air2
var/datum/gas_mixture/air3
var/obj/machinery/atmospherics/node1
var/obj/machinery/atmospherics/node2
var/obj/machinery/atmospherics/node3
var/datum/pipe_network/network1
-2
View File
@@ -12,8 +12,6 @@
var/state = 0 // 0 = go straight, 1 = go to side
// like a trinary component, node1 is input, node2 is side output, node3 is straight output
var/obj/machinery/atmospherics/node1
var/obj/machinery/atmospherics/node2
var/obj/machinery/atmospherics/node3
var/datum/pipe_network/network_node1
@@ -378,6 +378,11 @@
else
..()
/obj/machinery/atmospherics/unary/vent_pump/proc/is_welded()
if (welded > 0)
return 1
return 0
/obj/machinery/atmospherics/unary/vent_pump/examine(mob/user)
if(..(user, 1))
user << "A small gauge in the corner reads [round(last_flow_rate, 0.1)] L/s; [round(last_power_draw)] W"
-3
View File
@@ -12,9 +12,6 @@
var/open = 0
var/openDuringInit = 0
var/obj/machinery/atmospherics/node1
var/obj/machinery/atmospherics/node2
var/datum/pipe_network/network_node1
var/datum/pipe_network/network_node2
-11
View File
@@ -153,9 +153,6 @@
dir = SOUTH
initialize_directions = SOUTH|NORTH
var/obj/machinery/atmospherics/node1
var/obj/machinery/atmospherics/node2
var/minimum_temperature_difference = 300
var/thermal_conductivity = 0 //WALL_HEAT_TRANSFER_COEFFICIENT No
@@ -423,8 +420,6 @@
dir = SOUTH
initialize_directions = EAST|NORTH|WEST
var/obj/machinery/atmospherics/node1
var/obj/machinery/atmospherics/node2
var/obj/machinery/atmospherics/node3
level = 1
@@ -679,8 +674,6 @@
dir = SOUTH
initialize_directions = NORTH|SOUTH|EAST|WEST
var/obj/machinery/atmospherics/node1
var/obj/machinery/atmospherics/node2
var/obj/machinery/atmospherics/node3
var/obj/machinery/atmospherics/node4
@@ -1061,8 +1054,6 @@
initialize_directions = SOUTH
density = 1
var/obj/machinery/atmospherics/node1
/obj/machinery/atmospherics/pipe/tank/New()
icon_state = "air"
initialize_directions = dir
@@ -1237,8 +1228,6 @@
var/build_killswitch = 1
var/obj/machinery/atmospherics/node1
/obj/machinery/atmospherics/pipe/vent/New()
initialize_directions = dir
..()
-3
View File
@@ -13,9 +13,6 @@ obj/machinery/atmospherics/pipe/zpipe
dir = SOUTH
initialize_directions = SOUTH
var/obj/machinery/atmospherics/node1 //connection on the same Z
var/obj/machinery/atmospherics/node2 //connection on the other Z
var/minimum_temperature_difference = 300
var/thermal_conductivity = 0 //WALL_HEAT_TRANSFER_COEFFICIENT No
@@ -116,6 +116,9 @@
/mob/living/carbon/alien/proc/handle_regular_hud_updates()
if(is_ventcrawling == 0) // Stops sight returning to normal if inside a vent
sight = species.vision_flags
if (stat == 2 || (XRAY in src.mutations))
sight |= SEE_TURFS
sight |= SEE_MOBS
+4 -3
View File
@@ -1248,9 +1248,10 @@
*/
else
sight = species.vision_flags
see_in_dark = species.darksight
see_invisible = see_in_dark>2 ? SEE_INVISIBLE_LEVEL_ONE : SEE_INVISIBLE_LIVING
if(is_ventcrawling == 0) // Stops sight returning to normal if inside a vent
sight = species.vision_flags
see_in_dark = species.darksight
see_invisible = see_in_dark>2 ? SEE_INVISIBLE_LEVEL_ONE : SEE_INVISIBLE_LIVING
if(XRAY in mutations)
sight |= SEE_TURFS|SEE_MOBS|SEE_OBJS
@@ -11,6 +11,9 @@
handle_chemicals_in_body()
handle_nutrition()
if(is_ventcrawling == 0) // Stops sight returning to normal if inside a vent
sight = SEE_SELF
if (!client)
handle_targets()
if (!AIproc)
@@ -58,7 +61,7 @@
adjustToxLoss(200)
else
adjustToxLoss(30)
updatehealth()
return //TODO: DEFERRED
@@ -410,9 +410,4 @@
if(powerlevel > 10)
powerlevel = 10
adjustToxLoss(-10)
nutrition = max(nutrition, get_max_nutrition())
/mob/living/carbon/slime/cannot_use_vents()
if(Victim)
return "You cannot ventcrawl while feeding."
..()
nutrition = max(nutrition, get_max_nutrition())
-108
View File
@@ -664,114 +664,6 @@ default behaviour is:
resting = !resting
src << "<span class='notice'>You are now [resting ? "resting" : "getting up"]</span>"
/mob/living/proc/is_allowed_vent_crawl_item(var/obj/item/carried_item)
return isnull(get_inventory_slot(carried_item))
/mob/living/simple_animal/spiderbot/is_allowed_vent_crawl_item(var/obj/item/carried_item)
if(carried_item == held_item)
return 0
return ..()
/mob/living/proc/handle_ventcrawl(var/obj/machinery/atmospherics/unary/vent_pump/vent_found = null, var/ignore_items = 0) // -- TLE -- Merged by Carn
if(stat)
src << "You must be conscious to do this!"
return
if(lying)
src << "You can't vent crawl while you're stunned!"
return
var/special_fail_msg = cannot_use_vents()
if(special_fail_msg)
src << "<span class='warning'>[special_fail_msg]</span>"
return
if(vent_found) // one was passed in, probably from vent/AltClick()
if(vent_found.welded)
src << "That vent is welded shut."
return
if(!vent_found.Adjacent(src))
return // don't even acknowledge that
else
for(var/obj/machinery/atmospherics/unary/vent_pump/v in range(1,src))
if(!v.welded)
if(v.Adjacent(src))
vent_found = v
if(!vent_found)
src << "You'll need a non-welded vent to crawl into!"
return
if(!vent_found.network || !vent_found.network.normal_members.len)
src << "This vent is not connected to anything."
return
var/list/vents = list()
for(var/obj/machinery/atmospherics/unary/vent_pump/temp_vent in vent_found.network.normal_members)
if(temp_vent.welded)
continue
if(temp_vent in loc)
continue
var/turf/T = get_turf(temp_vent)
if(!T || T.z != loc.z)
continue
var/i = 1
var/index = "[T.loc.name]\[[i]\]"
while(index in vents)
i++
index = "[T.loc.name]\[[i]\]"
vents[index] = temp_vent
if(!vents.len)
src << "\red There are no available vents to travel to, they could be welded."
return
var/obj/selection = input("Select a destination.", "Duct System") as null|anything in sortAssoc(vents)
if(!selection) return
if(!vent_found.Adjacent(src))
src << "Never mind, you left."
return
if(!ignore_items)
for(var/obj/item/carried_item in contents)//If the monkey got on objects.
if(is_allowed_vent_crawl_item(carried_item))
continue
src << "<span class='warning'>You can't be carrying items or have items equipped when vent crawling!</span>"
return
if(isslime(src))
var/mob/living/carbon/slime/S = src
if(S.Victim)
src << "\red You'll have to let [S.Victim] go or finish eating \him first."
return
var/obj/machinery/atmospherics/unary/vent_pump/target_vent = vents[selection]
if(!target_vent)
return
for(var/mob/O in viewers(src, null))
O.show_message(text("<B>[src] scrambles into the ventillation ducts!</B>"), 1)
loc = target_vent
var/travel_time = round(get_dist(loc, target_vent.loc) / 2)
spawn(travel_time)
if(!target_vent) return
for(var/mob/O in hearers(target_vent,null))
O.show_message("You hear something squeezing through the ventilation ducts.",2)
sleep(travel_time)
if(!target_vent) return
if(target_vent.welded) //the vent can be welded while alien scrolled through the list or travelled.
target_vent = vent_found //travel back. No additional time required.
src << "\red The vent you were heading to appears to be welded."
loc = target_vent.loc
var/area/new_area = get_area(loc)
if(new_area)
new_area.Entered(src)
/mob/living/proc/cannot_use_vents()
return "You can't fit into that vent."
-10
View File
@@ -1,13 +1,3 @@
/mob/living/proc/ventcrawl()
set name = "Crawl through Vent"
set desc = "Enter an air vent and crawl through the pipe system."
set category = "Abilities"
if(stat == DEAD || paralysis || weakened || stunned || restrained())
return
handle_ventcrawl()
/mob/living/proc/hide()
set name = "Hide"
set desc = "Allows to hide beneath tables or certain items. Toggled on or off."
+223
View File
@@ -0,0 +1,223 @@
var/list/ventcrawl_machinery = list(
/obj/machinery/atmospherics/unary/vent_pump,
/obj/machinery/atmospherics/unary/vent_scrubber
)
// Vent crawling whitelisted items, whoo
/mob/living/var/list/can_enter_vent_with = list(
/obj/item/weapon/implant,
/obj/item/device/radio/borg,
/obj/item/weapon/holder,
/obj/machinery/camera,
/mob/living/simple_animal/borer
)
/mob/living/var/list/icon/pipes_shown = list()
/mob/living/var/last_played_vent
/mob/living/var/is_ventcrawling = 0
/mob/living/var/next_play_vent = 0
/mob/living/proc/can_ventcrawl()
return 0
/mob/living/Login()
. = ..()
//login during ventcrawl
if(is_ventcrawling && istype(loc, /obj/machinery/atmospherics)) //attach us back into the pipes
remove_ventcrawl()
add_ventcrawl(loc)
/mob/living/carbon/slime/can_ventcrawl()
if(Victim)
src << "<span class='warning'>You cannot ventcrawl while feeding.</span>"
return 0
return 1
/mob/living/proc/is_allowed_vent_crawl_item(var/obj/item/carried_item)
for(var/type in can_enter_vent_with)
if(istype(carried_item, can_enter_vent_with))
return get_inventory_slot(carried_item) == 0
return 0
/mob/living/carbon/is_allowed_vent_crawl_item(var/obj/item/carried_item)
if(carried_item in internal_organs)
return 1
return ..()
/mob/living/carbon/human/is_allowed_vent_crawl_item(var/obj/item/carried_item)
if(carried_item in organs)
return 1
return ..()
/mob/living/simple_animal/spiderbot/is_allowed_vent_crawl_item(var/obj/item/carried_item)
if(carried_item == held_item)
return 1
return ..()
/mob/living/proc/ventcrawl_carry()
for(var/atom/A in src.contents)
if(!is_allowed_vent_crawl_item(A))
src << "<span class='warning'>You can't be carrying that when vent crawling!</span>"
return 0
return 1
/obj/machinery/atmospherics/AltClick(mob/living/user)
if(is_type_in_list(src,ventcrawl_machinery) && user.can_ventcrawl())
user.handle_ventcrawl()
return 1
return ..()
/mob/living/carbon/human/can_ventcrawl()
return issmall(src)
/mob/proc/start_ventcrawl()
var/atom/pipe
var/list/pipes = list()
for(var/obj/machinery/atmospherics/unary/U in range(1))
if(is_type_in_list(U,ventcrawl_machinery) && Adjacent(U))
pipes |= U
if(!pipes || !pipes.len)
usr << "<span class='notice'>There are no pipes that you can ventcrawl into within range!</span>"
return
if(pipes.len == 1)
pipe = pipes[1]
else
pipe = input("Crawl Through Vent", "Pick a pipe") as null|anything in pipes
if(canmove && pipe)
return pipe
/mob/living/carbon/slime/can_ventcrawl()
return 1
/mob/living/simple_animal/borer/can_ventcrawl()
return 1
/mob/living/simple_animal/borer/ventcrawl_carry()
return 1
/mob/living/simple_animal/mouse/can_ventcrawl()
return 1
/mob/living/simple_animal/spiderbot/can_ventcrawl()
return 1
/mob/living/carbon/alien/can_ventcrawl()
return 1
/mob/living/carbon/alien/ventcrawl_carry()
return 1
/mob/living/proc/size_to_crawldelay(var/size)
var/delayticks = size * 3
return delayticks >= 3 ? delayticks : 3
/mob/living/var/ventcrawl_layer = 3
/mob/living/proc/handle_ventcrawl(var/atom/clicked_on)
if(!stat)
if(!lying)
var/obj/machinery/atmospherics/unary/vent_found
if(clicked_on && Adjacent(clicked_on))
vent_found = clicked_on
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_list(machine, ventcrawl_machinery))
vent_found = machine
if(!vent_found || !vent_found.can_crawl_through())
vent_found = null
if(vent_found)
break
if(istype(vent_found, /obj/machinery/atmospherics/unary/vent_pump/) && vent_found:is_welded()) // welded check
src << "<span class='warning'>You can't crawl into a welded vent!</span>"
return
if(vent_found)
if(vent_found.network && (vent_found.network.normal_members.len || vent_found.network.line_members.len))
visible_message("<span class='warning'>[src] begins to climb into the ventilation system!","<span class='notice'>You begin climbing into the ventilation system...</span>")
if(vent_found.air_contents && !issilicon(src))
switch(vent_found.air_contents.temperature)
if(0 to BODYTEMP_COLD_DAMAGE_LIMIT)
src << "<span class='danger'>You feel a painful freeze coming from the vent!</span>"
if(BODYTEMP_COLD_DAMAGE_LIMIT to T0C)
src << "<span class='warning'>You feel an icy chill coming from the vent.</span>"
if(T0C + 40 to BODYTEMP_HEAT_DAMAGE_LIMIT)
src << "<span class='warning'>You feel a hot wash coming from the vent.</span>"
if(BODYTEMP_HEAT_DAMAGE_LIMIT to INFINITY)
src << "<span class='danger'>You feel a searing heat coming from the vent!</span>"
switch(vent_found.air_contents.return_pressure())
if(0 to HAZARD_LOW_PRESSURE)
src << "<span class='danger'>You feel a rushing draw pulling you into the vent!</span>"
if(HAZARD_LOW_PRESSURE to WARNING_LOW_PRESSURE)
src << "<span class='warning'>You feel a strong drag pulling you into the vent.</span>"
if(WARNING_HIGH_PRESSURE to HAZARD_HIGH_PRESSURE)
src << "<span class='warning'>You feel a strong current pushing you away from the vent.</span>"
if(HAZARD_HIGH_PRESSURE to INFINITY)
src << "<span class='danger'>You feel a roaring wind pushing you away from the vent!</span>"
if(!do_mob(src, vent_found, mob_size ? size_to_crawldelay(mob_size) : size_to_crawldelay(15), 1, 1))
return
if(!client)
return
if(!ventcrawl_carry())
return
visible_message("<B>[src] scrambles into the ventilation ducts!</B>", "You climb into the ventilation system.")
forceMove(vent_found)
add_ventcrawl(vent_found)
sight = (SEE_TURFS|BLIND)
else
src << "<span class='notice'>This vent is not connected to anything."
else
src << "<span class='notice'>You must be standing on or beside an air vent to enter it."
else
src << "<span class='notice'>You can't vent crawl while you're stunned!"
else
src << "<span class='notice'>You must be conscious to do this!"
return
/mob/living/proc/add_ventcrawl(obj/machinery/atmospherics/starting_machine)
is_ventcrawling = 1
//candrop = 0
var/datum/pipe_network/network = starting_machine.return_network(starting_machine)
if(!network)
return
for(var/datum/pipeline/pipeline in network.line_members)
for(var/obj/machinery/atmospherics/A in (pipeline.members || pipeline.edges)) // Adds pipe and manifold images
if(!A.pipe_image)
A.pipe_image = image(A, A.loc, layer = 20, dir = A.dir)
pipes_shown += A.pipe_image
client.images += A.pipe_image
for (var/obj/machinery/atmospherics/V in network.normal_members) // Adds vent and scrubber images
if (!V.pipe_image || istype(V, /obj/machinery/atmospherics/unary/vent_pump/))
V.pipe_image = image(V, V.loc, layer = 20, dir = V.dir)
pipes_shown += V.pipe_image
client.images += V.pipe_image
/mob/living/proc/remove_ventcrawl()
is_ventcrawling = 0
//candrop = 1
if(client)
for(var/image/current_image in pipes_shown)
client.images -= current_image
client.eye = src
pipes_shown.len = 0
@@ -0,0 +1,90 @@
/obj/machinery/atmospherics/var/image/pipe_image
/obj/machinery/atmospherics/Destroy()
for(var/mob/living/M in src) //ventcrawling is serious business
M.remove_ventcrawl()
M.forceMove(get_turf(src))
if(pipe_image)
for(var/mob/living/M in player_list)
if(M.client)
M.client.images -= pipe_image
M.pipes_shown -= pipe_image
pipe_image = null
. = ..()
/obj/machinery/atmospherics/ex_act(severity)
for(var/atom/movable/A in src) //ventcrawling is serious business
A.ex_act(severity)
. = ..()
/obj/machinery/atmospherics/Entered(atom/movable/Obj)
if(istype(Obj, /mob/living))
var/mob/living/L = Obj
L.ventcrawl_layer = layer
. = ..()
/obj/machinery/atmospherics/relaymove(mob/living/user, direction)
if(!(direction & initialize_directions)) //can't go in a way we aren't connecting to
return
ventcrawl_to(user,findConnecting(direction, user.ventcrawl_layer),direction)
/obj/machinery/atmospherics/proc/ventcrawl_to(var/mob/living/user, var/obj/machinery/atmospherics/target_move, var/direction)
if(target_move)
if(is_type_in_list(target_move, ventcrawl_machinery) && target_move.can_crawl_through())
if(istype(target_move, /obj/machinery/atmospherics/unary/vent_pump/) && target_move:is_welded())
user.visible_message("<span class='warning'You hear something banging on \the [target_move.name]!</span>", "<span class='notice'>You can't escape from a welded vent.</span>")
else
user.remove_ventcrawl()
user.forceMove(target_move.loc) //handles entering and so on
user.sight &= ~(SEE_TURFS|BLIND)
user.visible_message("<span class='warning'>You hear something squeezing through the ducts.</span>", "You climb out the ventilation system.")
else if(target_move.can_crawl_through())
if(target_move.return_network(target_move) != return_network(src))
user.remove_ventcrawl()
user.add_ventcrawl(target_move)
user.forceMove(target_move)
user.client.eye = target_move //if we don't do this, Byond only updates the eye every tick - required for smooth movement
if(world.time > user.next_play_vent)
user.next_play_vent = world.time+30
playsound(src, 'sound/machines/ventcrawl.ogg', 50, 1, -3)
else
if((direction & initialize_directions) || is_type_in_list(src, ventcrawl_machinery) && src.can_crawl_through()) //if we move in a way the pipe can connect, but doesn't - or we're in a vent
user.remove_ventcrawl()
user.forceMove(src.loc)
user.visible_message("<span class='warning'>You hear something squeezing through the pipes.</span>", "You climb out the ventilation system.")
user.canmove = 0
spawn(1)
user.canmove = 1
/obj/machinery/atmospherics/proc/can_crawl_through()
return 1
/obj/machinery/atmospherics/proc/findConnecting(var/direction)
for(var/obj/machinery/atmospherics/target in get_step(src,direction))
if(target.initialize_directions & get_dir(target,src))
if(isConnectable(target) && target.isConnectable(src))
return target
/obj/machinery/atmospherics/proc/isConnectable(var/obj/machinery/atmospherics/target)
return (target == node1 || target == node2)
/obj/machinery/atmospherics/pipe/manifold/isConnectable(var/obj/machinery/atmospherics/target)
return (target == node3 || ..())
obj/machinery/atmospherics/trinary/isConnectable(var/obj/machinery/atmospherics/target)
return (target == node3 || ..())
/obj/machinery/atmospherics/pipe/manifold4w/isConnectable(var/obj/machinery/atmospherics/target)
return (target == node3 || target == node4 || ..())
/obj/machinery/atmospherics/tvalve/isConnectable(var/obj/machinery/atmospherics/target)
return (target == node3 || ..())
/obj/machinery/atmospherics/pipe/cap/isConnectable(var/obj/machinery/atmospherics/target)
return (target == node || ..())
/obj/machinery/atmospherics/portables_connector/isConnectable(var/obj/machinery/atmospherics/target)
return (target == node || ..())
/obj/machinery/atmospherics/unary/isConnectable(var/obj/machinery/atmospherics/target)
return (target == node || ..())
+9
View File
@@ -0,0 +1,9 @@
/mob/living/proc/ventcrawl()
set name = "Crawl through Vent"
set desc = "Enter an air vent and crawl through the pipe system."
set category = "Abilities"
if(paralysis || restrained())
return
var/pipe = start_ventcrawl()
if(pipe)
handle_ventcrawl()
+6
View File
@@ -0,0 +1,6 @@
author: Bedshaped
delete-after: True
changes:
- rscadd: "Ported Bay12's ventcrawling by Zuhayr, originally from vg."
Binary file not shown.