Porting multi-z support updates.

This commit is contained in:
Ghommie
2019-10-27 16:32:32 +01:00
parent b9bf7b726d
commit 4aa1d55abb
44 changed files with 11050 additions and 142 deletions
@@ -1,4 +1,6 @@
/atom/var/CanAtmosPass = ATMOS_PASS_YES
/atom/var/CanAtmosPassVertical = ATMOS_PASS_YES
/atom/proc/CanAtmosPass(turf/T)
switch (CanAtmosPass)
if (ATMOS_PASS_PROC)
@@ -8,42 +10,47 @@
else
return CanAtmosPass
/turf/closed/CanAtmosPass = ATMOS_PASS_NO
/turf/CanAtmosPass = ATMOS_PASS_NO
/turf/CanAtmosPassVertical = ATMOS_PASS_NO
/turf/open/CanAtmosPass = ATMOS_PASS_PROC
/turf/open/CanAtmosPass(turf/T)
var/R
if(blocks_air || T.blocks_air)
R = 1
/turf/open/CanAtmosPassVertical = ATMOS_PASS_PROC
/turf/open/CanAtmosPass(turf/T, vertical = FALSE)
var/dir = vertical? get_dir_multiz(src, T) : get_dir(src, T)
var/opp = dir_inverse_multiz(dir)
var/R = FALSE
if(vertical && !(zAirOut(dir, T) && T.zAirIn(dir, src)))
R = TRUE
if(blocks_air || T.blocks_air)
R = TRUE
if (T == src)
return !R
for(var/obj/O in contents+T.contents)
var/turf/other = (O.loc == src ? T : src)
if(!CANATMOSPASS(O, other))
R = 1
if(!(vertical? (CANVERTICALATMOSPASS(O, other)) : (CANATMOSPASS(O, other))))
R = TRUE
if(O.BlockSuperconductivity()) //the direction and open/closed are already checked on CanAtmosPass() so there are no arguments
var/D = get_dir(src, T)
atmos_supeconductivity |= D
D = get_dir(T, src)
T.atmos_supeconductivity |= D
return 0 //no need to keep going, we got all we asked
atmos_supeconductivity |= dir
T.atmos_supeconductivity |= opp
return FALSE //no need to keep going, we got all we asked
atmos_supeconductivity &= ~get_dir(src, T)
T.atmos_supeconductivity &= ~get_dir(T, src)
atmos_supeconductivity &= ~dir
T.atmos_supeconductivity &= ~opp
return !R
/atom/movable/proc/BlockSuperconductivity() // objects that block air and don't let superconductivity act. Only firelocks atm.
return 0
return FALSE
/turf/proc/CalculateAdjacentTurfs()
var/list/atmos_adjacent_turfs = src.atmos_adjacent_turfs
for(var/direction in GLOB.cardinals)
var/turf/T = get_step(src, direction)
if(!T)
var/canpass = CANATMOSPASS(src, src)
var/canvpass = CANVERTICALATMOSPASS(src, src)
for(var/direction in GLOB.cardinals_multiz)
var/turf/T = get_step_multiz(src, direction)
if(!isopenturf(T))
continue
if( !(blocks_air || T.blocks_air) && CANATMOSPASS(T, src) )
if(!(blocks_air || T.blocks_air) && ((direction & (UP|DOWN))? (canvpass && CANVERTICALATMOSPASS(T, src)) : (canpass && CANATMOSPASS(T, src))) )
LAZYINITLIST(atmos_adjacent_turfs)
LAZYINITLIST(T.atmos_adjacent_turfs)
atmos_adjacent_turfs[T] = TRUE
@@ -72,11 +79,13 @@
var/turf/curloc = src
for (var/direction in GLOB.diagonals)
for (var/direction in GLOB.diagonals_multiz)
var/matchingDirections = 0
var/turf/S = get_step(curloc, direction)
var/turf/S = get_step_multiz(curloc, direction)
if(!S)
continue
for (var/checkDirection in GLOB.cardinals)
for (var/checkDirection in GLOB.cardinals_multiz)
var/turf/checkTurf = get_step(S, checkDirection)
if(!S.atmos_adjacent_turfs || !S.atmos_adjacent_turfs[checkTurf])
continue
@@ -42,8 +42,7 @@
/turf/open/Destroy()
if(active_hotspot)
qdel(active_hotspot)
active_hotspot = null
QDEL_NULL(active_hotspot)
// Adds the adjacent turfs to the current atmos processing
for(var/T in atmos_adjacent_turfs)
SSair.add_to_active(T)
+29
View File
@@ -0,0 +1,29 @@
obj/machinery/atmospherics/pipe/simple/multiz ///This is an atmospherics pipe which can relay air up a deck (Z+1). It currently only supports being on pipe layer 1
name = "multi deck pipe adapter"
desc = "An adapter which allows pipes to connect to other pipenets on different decks."
icon_state = "multiz_pipe"
icon = 'icons/obj/atmos.dmi'
/obj/machinery/atmospherics/pipe/simple/multiz/update_icon()
. = ..()
cut_overlays() //This adds the overlay showing it's a multiz pipe. This should go above turfs and such
var/image/multiz_overlay_node = new(src) //If we have a firing state, light em up!
multiz_overlay_node.icon = 'icons/obj/atmos.dmi'
multiz_overlay_node.icon_state = "multiz_pipe"
multiz_overlay_node.layer = HIGH_OBJ_LAYER
add_overlay(multiz_overlay_node)
///Attempts to locate a multiz pipe that's above us, if it finds one it merges us into its pipenet
/obj/machinery/atmospherics/pipe/simple/multiz/pipeline_expansion()
icon = 'icons/obj/atmos.dmi' //Just to refresh.
var/turf/T = get_turf(src)
var/obj/machinery/atmospherics/pipe/simple/multiz/above = locate(/obj/machinery/atmospherics/pipe/simple/multiz) in(SSmapping.get_turf_above(T))
var/obj/machinery/atmospherics/pipe/simple/multiz/below = locate(/obj/machinery/atmospherics/pipe/simple/multiz) in(SSmapping.get_turf_below(T))
if(below)
below.pipeline_expansion() //If we've got one below us, force it to add us on facebook
if(above)
nodes += above
above.nodes += src //Two way travel :)
return ..()
else
return ..()
+59 -23
View File
@@ -1,10 +1,12 @@
/datum/map_template/ruin/proc/try_to_place(z,allowed_areas)
var/sanity = PLACEMENT_TRIES
/datum/map_template/ruin/proc/try_to_place(z,allowed_areas,turf/forced_turf)
var/sanity = forced_turf ? 1 : PLACEMENT_TRIES
if(SSmapping.level_trait(z,ZTRAIT_ISOLATED_RUINS))
return place_on_isolated_level(z)
while(sanity > 0)
sanity--
var/width_border = TRANSITIONEDGE + SPACERUIN_MAP_EDGE_PAD + round(width / 2)
var/height_border = TRANSITIONEDGE + SPACERUIN_MAP_EDGE_PAD + round(height / 2)
var/turf/central_turf = locate(rand(width_border, world.maxx - width_border), rand(height_border, world.maxy - height_border), z)
var/turf/central_turf = forced_turf ? forced_turf : locate(rand(width_border, world.maxx - width_border), rand(height_border, world.maxy - height_border), z)
var/valid = TRUE
for(var/turf/check in get_affected_turfs(central_turf,1))
@@ -24,7 +26,7 @@
qdel(monster)
for(var/obj/structure/flora/ash/plant in T)
qdel(plant)
load(central_turf,centered = TRUE)
loaded++
@@ -32,9 +34,20 @@
T.flags_1 |= NO_RUINS_1
new /obj/effect/landmark/ruin(central_turf, src)
return TRUE
return FALSE
return central_turf
/datum/map_template/ruin/proc/place_on_isolated_level(z)
var/datum/turf_reservation/reservation = SSmapping.RequestBlockReservation(width, height, z) //Make the new level creation work with different traits.
if(!reservation)
return
var/turf/placement = locate(reservation.bottom_left_coords[1],reservation.bottom_left_coords[2],reservation.bottom_left_coords[3])
load(placement)
loaded++
for(var/turf/T in get_affected_turfs(placement))
T.flags_1 |= NO_RUINS_1
var/turf/center = locate(placement.x + round(width/2),placement.y + round(height/2),placement.z)
new /obj/effect/landmark/ruin(center, src)
return center
/proc/seedRuins(list/z_levels = null, budget = 0, whitelist = /area/space, list/potentialRuins)
if(!z_levels || !z_levels.len)
@@ -49,9 +62,8 @@
var/list/ruins = potentialRuins.Copy()
var/list/forced_ruins = list() //These go first on the z level associated (same random one by default)
var/list/forced_ruins = list() //These go first on the z level associated (same random one by default) or if the assoc value is a turf to the specified turf.
var/list/ruins_availible = list() //we can try these in the current pass
var/forced_z //If set we won't pick z level and use this one instead.
//Set up the starting ruin list
for(var/key in ruins)
@@ -67,34 +79,55 @@
while(budget > 0 && (ruins_availible.len || forced_ruins.len))
var/datum/map_template/ruin/current_pick
var/forced = FALSE
var/forced_z //If set we won't pick z level and use this one instead.
var/forced_turf //If set we place the ruin centered on the given turf
if(forced_ruins.len) //We have something we need to load right now, so just pick it
for(var/ruin in forced_ruins)
current_pick = ruin
if(forced_ruins[ruin] > 0) //Load into designated z
if(isturf(forced_ruins[ruin]))
var/turf/T = forced_ruins[ruin]
forced_z = T.z //In case of chained ruins
forced_turf = T
else if(forced_ruins[ruin] > 0) //Load into designated z
forced_z = forced_ruins[ruin]
forced = TRUE
break
else //Otherwise just pick random one
current_pick = pickweight(ruins_availible)
var/placement_tries = PLACEMENT_TRIES
var/placement_tries = forced_turf ? 1 : PLACEMENT_TRIES //Only try once if we target specific turf
var/failed_to_place = TRUE
var/z_placed = 0
while(placement_tries > 0)
placement_tries--
z_placed = pick(z_levels)
if(!current_pick.try_to_place(forced_z ? forced_z : z_placed,whitelist))
continue
else
failed_to_place = FALSE
break
var/target_z = 0
var/turf/placed_turf //Where the ruin ended up if we succeeded
outer:
while(placement_tries > 0)
placement_tries--
target_z = pick(z_levels)
if(forced_z)
target_z = forced_z
if(current_pick.always_spawn_with) //If the ruin has part below, make sure that z exists.
for(var/v in current_pick.always_spawn_with)
if(current_pick.always_spawn_with[v] == PLACE_BELOW)
var/turf/T = locate(1,1,target_z)
if(!SSmapping.get_turf_below(T))
if(forced_z)
continue outer
else
break outer
placed_turf = current_pick.try_to_place(target_z,whitelist,forced_turf)
if(!placed_turf)
continue
else
failed_to_place = FALSE
break
//That's done remove from priority even if it failed
if(forced)
//TODO : handle forced ruins with multiple variants
forced_ruins -= current_pick
forced = FALSE
if(failed_to_place)
for(var/datum/map_template/ruin/R in ruins_availible)
if(R.id == current_pick.id)
@@ -118,18 +151,21 @@
if(istype(linked,v))
switch(current_pick.always_spawn_with[v])
if(PLACE_SAME_Z)
forced_ruins[linked] = forced_z ? forced_z : z_placed //I guess you might want a chain somehow
forced_ruins[linked] = target_z //I guess you might want a chain somehow
if(PLACE_LAVA_RUIN)
forced_ruins[linked] = pick(SSmapping.levels_by_trait(ZTRAIT_LAVA_RUINS))
if(PLACE_SPACE_RUIN)
forced_ruins[linked] = pick(SSmapping.levels_by_trait(ZTRAIT_SPACE_RUINS))
if(PLACE_DEFAULT)
forced_ruins[linked] = -1
forced_z = 0
if(PLACE_BELOW)
forced_ruins[linked] = SSmapping.get_turf_below(placed_turf)
if(PLACE_ISOLATED)
forced_ruins[linked] = SSmapping.get_isolated_ruin_z()
//Update the availible list
for(var/datum/map_template/ruin/R in ruins_availible)
if(R.cost > budget)
ruins_availible -= R
log_world("Ruin loader finished with [budget] left to spend.")
@@ -0,0 +1,47 @@
/proc/get_step_multiz(ref, dir)
if(dir & UP)
dir &= ~UP
return get_step(SSmapping.get_turf_above(get_turf(ref)), dir)
if(dir & DOWN)
dir &= ~DOWN
return get_step(SSmapping.get_turf_below(get_turf(ref)), dir)
return get_step(ref, dir)
/proc/get_dir_multiz(turf/us, turf/them)
us = get_turf(us)
them = get_turf(them)
if(!us || !them)
return NONE
if(us.z == them.z)
return get_dir(us, them)
else
var/turf/T = us.above()
var/dir = NONE
if(T && (T.z == them.z))
dir = UP
else
T = us.below()
if(T && (T.z == them.z))
dir = DOWN
else
return get_dir(us, them)
return (dir | get_dir(us, them))
/turf/proc/above()
return get_step_multiz(src, UP)
/turf/proc/below()
return get_step_multiz(src, DOWN)
/proc/dir_inverse_multiz(dir)
var/holder = dir & (UP|DOWN)
if((holder == NONE) || (holder == (UP|DOWN)))
return turn(dir, 180)
dir &= ~(UP|DOWN)
dir = turn(dir, 180)
if(holder == UP)
holder = DOWN
else
holder = UP
dir |= holder
return dir
@@ -17,6 +17,7 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
see_in_dark = 100
invisibility = INVISIBILITY_OBSERVER
hud_type = /datum/hud/ghost
movement_type = GROUND | FLYING
var/can_reenter_corpse
var/can_reenter_round = TRUE
var/datum/hud/living/carbon/hud = null // hud
@@ -0,0 +1,2 @@
/mob/dead/observer/canZMove(direction, turf/target)
return TRUE
+10
View File
@@ -40,6 +40,16 @@
QDEL_LIST(diseases)
return ..()
/mob/living/onZImpact(turf/T, levels)
if(!isgroundlessturf(T))
ZImpactDamage(T, levels)
return ..()
/mob/living/proc/ZImpactDamage(turf/T, levels)
visible_message("<span class='danger'>[src] crashes into [T] with a sickening noise!</span>")
adjustBruteLoss((levels * 5) ** 1.5)
Knockdown(levels * 50)
/mob/living/proc/OpenCraftingMenu()
return
+4 -1
View File
@@ -32,4 +32,7 @@
if(drag_slowdown && L.lying && !L.buckled && grab_state < GRAB_AGGRESSIVE)
add_movespeed_modifier(MOVESPEED_ID_PRONE_DRAGGING, multiplicative_slowdown = PULL_PRONE_SLOWDOWN)
return
remove_movespeed_modifier(MOVESPEED_ID_PRONE_DRAGGING)
remove_movespeed_modifier(MOVESPEED_ID_PRONE_DRAGGING)
/mob/living/canZMove(dir, turf/target)
return can_zTravel(target, dir) && (movement_type & FLYING)
+32
View File
@@ -370,3 +370,35 @@
if(hud_used && hud_used.static_inventory)
for(var/obj/screen/mov_intent/selector in hud_used.static_inventory)
selector.update_icon(src)
/mob/verb/up()
set name = "Move Upwards"
set category = "IC"
if(zMove(UP, TRUE))
to_chat(src, "<span class='notice'>You move upwards.</span>")
/mob/verb/down()
set name = "Move Down"
set category = "IC"
if(zMove(DOWN, TRUE))
to_chat(src, "<span class='notice'>You move down.</span>")
/mob/proc/zMove(dir, feedback = FALSE)
if(dir != UP && dir != DOWN)
return FALSE
var/turf/target = get_step_multiz(src, dir)
if(!target)
if(feedback)
to_chat(src, "<span class='warning'>There's nothing in that direction!</span>")
return FALSE
if(!canZMove(dir, target))
if(feedback)
to_chat(src, "<span class='warning'>You couldn't move there!</span>")
return FALSE
forceMove(target)
return TRUE
/mob/proc/canZMove(direction, turf/target)
return FALSE
+26 -18
View File
@@ -117,7 +117,7 @@ GLOBAL_LIST_EMPTY(gravity_generators) // We will keep track of this by adding ne
use_power = IDLE_POWER_USE
interaction_flags_machine = INTERACT_MACHINE_ALLOW_SILICON | INTERACT_MACHINE_OFFLINE
var/on = TRUE
var/breaker = 1
var/breaker = TRUE
var/list/parts = list()
var/obj/middle = null
var/charging_state = POWER_IDLE
@@ -166,7 +166,7 @@ GLOBAL_LIST_EMPTY(gravity_generators) // We will keep track of this by adding ne
M.set_broken()
middle.cut_overlays()
charge_count = 0
breaker = 0
breaker = FALSE
set_power()
set_state(0)
investigate_log("has broken down.", INVESTIGATE_GRAVITY)
@@ -176,7 +176,7 @@ GLOBAL_LIST_EMPTY(gravity_generators) // We will keep track of this by adding ne
for(var/obj/machinery/gravity_generator/M in parts)
if(M.stat & BROKEN)
M.set_fix()
broken_state = 0
broken_state = FALSE
update_icon()
set_power()
@@ -273,11 +273,11 @@ GLOBAL_LIST_EMPTY(gravity_generators) // We will keep track of this by adding ne
// Set the charging state based on power/breaker.
/obj/machinery/gravity_generator/main/proc/set_power()
var/new_state = 0
var/new_state = FALSE
if(stat & (NOPOWER|BROKEN) || !breaker)
new_state = 0
new_state = FALSE
else if(breaker)
new_state = 1
new_state = TRUE
charging_state = new_state ? POWER_UP : POWER_DOWN // Startup sequence animation.
investigate_log("is now [charging_state == POWER_UP ? "charging" : "discharging"].", INVESTIGATE_GRAVITY)
@@ -292,13 +292,13 @@ GLOBAL_LIST_EMPTY(gravity_generators) // We will keep track of this by adding ne
var/alert = FALSE
if(SSticker.IsRoundInProgress())
if(on) // If we turned on and the game is live.
if(gravity_in_level() == 0)
alert = 1
if(gravity_in_level() == FALSE)
alert = TRUE
investigate_log("was brought online and is now producing gravity for this level.", INVESTIGATE_GRAVITY)
message_admins("The gravity generator was brought online [ADMIN_VERBOSEJMP(src)]")
else
if(gravity_in_level() == 1)
alert = 1
if(gravity_in_level() == TRUE)
alert = TRUE
investigate_log("was brought offline and there is now no gravity for this level.", INVESTIGATE_GRAVITY)
message_admins("The gravity generator was brought offline with no backup generator. [ADMIN_VERBOSEJMP(src)]")
@@ -361,7 +361,7 @@ GLOBAL_LIST_EMPTY(gravity_generators) // We will keep track of this by adding ne
var/sound/alert_sound = sound('sound/effects/alert.ogg')
for(var/i in GLOB.mob_list)
var/mob/M = i
if(M.z != z)
if(M.z != z && !(SSmapping.level_trait(z, ZTRAITS_STATION) && SSmapping.level_trait(M.z, ZTRAITS_STATION)))
continue
M.update_gravity(M.mob_has_gravity())
if(M.client)
@@ -371,20 +371,28 @@ GLOBAL_LIST_EMPTY(gravity_generators) // We will keep track of this by adding ne
/obj/machinery/gravity_generator/main/proc/gravity_in_level()
var/turf/T = get_turf(src)
if(!T)
return 0
return FALSE
if(GLOB.gravity_generators["[T.z]"])
return length(GLOB.gravity_generators["[T.z]"])
return 0
return FALSE
/obj/machinery/gravity_generator/main/proc/update_list()
var/turf/T = get_turf(src.loc)
if(T)
if(!GLOB.gravity_generators["[T.z]"])
GLOB.gravity_generators["[T.z]"] = list()
if(on)
GLOB.gravity_generators["[T.z]"] |= src
var/list/z_list = list()
// Multi-Z, station gravity generator generates gravity on all ZTRAIT_STATION z-levels.
if(SSmapping.level_trait(T.z, ZTRAIT_STATION))
for(var/z in SSmapping.levels_by_trait(ZTRAIT_STATION))
z_list += z
else
GLOB.gravity_generators["[T.z]"] -= src
z_list += T.z
for(var/z in z_list)
if(!GLOB.gravity_generators["[z]"])
GLOB.gravity_generators["[z]"] = list()
if(on)
GLOB.gravity_generators["[z]"] |= src
else
GLOB.gravity_generators["[z]"] -= src
/obj/machinery/gravity_generator/main/proc/change_setting(value)
if(value != setting)
+80
View File
@@ -0,0 +1,80 @@
/obj/machinery/power/deck_relay //This bridges powernets
name = "Multi-deck power adapter"
desc = "A huge bundle of double insulated cabling which seems to run up into the ceiling."
icon = 'icons/obj/power.dmi'
icon_state = "cablerelay-off"
var/obj/machinery/power/deck_relay/below ///The relay that's below us (for bridging powernets)
var/obj/machinery/power/deck_relay/above ///The relay that's above us (for bridging powernets)
anchored = TRUE
density = FALSE
/obj/machinery/power/deck_relay/attackby(obj/item/I,mob/user)
if(default_unfasten_wrench(user, I))
return FALSE
. = ..()
/obj/machinery/power/deck_relay/process()
if(!anchored)
icon_state = "cablerelay-off"
if(above) //Lose connections
above.below = null
if(below)
below.above = null
return
refresh() //Sometimes the powernets get lost, so we need to keep checking.
if(powernet && (powernet.avail <= 0)) // is it powered?
icon_state = "cablerelay-off"
else
icon_state = "cablerelay-on"
if(!below || QDELETED(below) || !above || QDELETED(above))
icon_state = "cablerelay-off"
find_relays()
///Allows you to scan the relay with a multitool to see stats.
/obj/machinery/power/deck_relay/multitool_act(mob/user, obj/item/I)
if(powernet && (powernet.avail > 0)) // is it powered?
to_chat(user, "<span class='danger'>Total power: [DisplayPower(powernet.avail)]\nLoad: [DisplayPower(powernet.load)]\nExcess power: [DisplayPower(surplus())]</span>")
if(!powernet || below.powernet != powernet)
icon_state = "cablerelay-off"
to_chat(user, "<span class='danger'>Powernet connection lost. Attempting to re-establish. Ensure the relays below this one are connected too.</span>")
find_relays()
addtimer(CALLBACK(src, .proc/refresh), 20) //Wait a bit so we can find the one below, then get powering
return TRUE
/obj/machinery/power/deck_relay/Initialize()
. = ..()
addtimer(CALLBACK(src, .proc/find_relays), 30)
addtimer(CALLBACK(src, .proc/refresh), 50) //Wait a bit so we can find the one below, then get powering
///Handles re-acquiring + merging powernets found by find_relays()
/obj/machinery/power/deck_relay/proc/refresh()
if(above)
above.merge(src)
if(below)
below.merge(src)
/obj/machinery/power/deck_relay/proc/merge(var/obj/machinery/power/deck_relay/DR)
if(!DR)
return
var/turf/merge_from = get_turf(DR)
var/turf/merge_to = get_turf(src)
var/obj/structure/cable/C = merge_from.get_cable_node()
var/obj/structure/cable/XR = merge_to.get_cable_node()
if(C && XR)
merge_powernets(XR.powernet,C.powernet)//Bridge the powernets.
///Locates relays that are above and below this object
/obj/machinery/power/deck_relay/proc/find_relays()
var/turf/T = get_turf(src)
if(!T || !istype(T))
return FALSE
below = null //in case we're re-establishing
var/obj/structure/cable/C = T.get_cable_node() //check if we have a node cable on the machine turf, the first found is picked
if(C && C.powernet)
C.powernet.add_machine(src) //Nice we're in.
powernet = C.powernet
below = locate(/obj/machinery/power/deck_relay) in(SSmapping.get_turf_below(T))
above = locate(/obj/machinery/power/deck_relay) in(SSmapping.get_turf_above(T))
if(below || above)
icon_state = "cablerelay-on"
return TRUE
@@ -650,6 +650,9 @@ GLOBAL_DATUM(main_supermatter_engine, /obj/machinery/power/supermatter_crystal)
Consume(AM)
/obj/machinery/power/supermatter_crystal/intercept_zImpact(atom/movable/AM, levels)
Bumped(AM)
/obj/machinery/power/supermatter_crystal/proc/Consume(atom/movable/AM)
if(isliving(AM))
var/mob/living/user = AM
@@ -138,7 +138,7 @@
return TRUE
/datum/reagent/consumable/cooking_oil/reaction_turf(turf/open/T, reac_volume)
if(!istype(T))
if(!istype(T) || isgroundlessturf(T))
return
if(reac_volume >= 5)
T.MakeSlippery(TURF_WET_LUBE, min_wet_time = 10 SECONDS, wet_time_to_add = reac_volume * 1.5 SECONDS)
+49
View File
@@ -0,0 +1,49 @@
#define MULTIZ_PIPE_UP 1 ///Defines for determining which way a multiz disposal element should travel
#define MULTIZ_PIPE_DOWN 2 ///Defines for determining which way a multiz disposal element should travel
/obj/structure/disposalpipe/trunk/multiz
name = "Disposal trunk that goes up"
icon_state = "pipe-up"
var/multiz_dir = MULTIZ_PIPE_UP ///Set the multiz direction of your trunk. 1 = up, 2 = down
/obj/structure/disposalpipe/trunk/multiz/down
name = "Disposal trunk that goes down"
icon_state = "pipe-down"
multiz_dir = MULTIZ_PIPE_DOWN
/obj/structure/disposalpipe/trunk/multiz/transfer(obj/structure/disposalholder/H)
if(H.dir == DOWN) //Since we're a trunk, you can still place a chute / bin over us. If theyve entered from there, treat this as a normal trunk
return ..()
// otherwise, go to the linked object
if(multiz_dir) //Are we a trunk that goes up? Or down?
var/turf/T = null
if(multiz_dir == MULTIZ_PIPE_UP)
T = SSmapping.get_turf_above(get_turf(src)) //Get the turf above us
if(multiz_dir == MULTIZ_PIPE_DOWN)
T = SSmapping.get_turf_below(get_turf(src))
if(!T)
expel(H)
return //Nothing located.
var/obj/structure/disposalpipe/trunk/multiz/pipe = locate(/obj/structure/disposalpipe/trunk/multiz) in T
if(pipe)
var/obj/structure/disposalholder/destination = new(pipe) //For future reference, the disposal holder is the thing that carries mobs
destination.init(pipe) //This instantiates it
destination.merge(H) //This takes the contents of H (Our disposal holder that's travelling into us) and puts them into the destination holder
destination.active = TRUE //Active allows it to process and move
destination.setDir(DOWN) //This tells the trunk above us NOT to loop it back down to us, or else you get an infinite loop
destination.move()
return null //Which removes the disposalholder
else
var/obj/structure/disposaloutlet/O = linked
if(istype(O))
O.expel(H) // expel at outlet
else
var/obj/machinery/disposal/D = linked
D.expel(H) // expel at disposal
// Returning null without expelling holder makes the holder expell itself
return null
#undef MULTIZ_PIPE_UP
#undef MULTIZ_PIPE_DOWN
+3
View File
@@ -33,6 +33,9 @@
else
return QDEL_HINT_LETMELIVE
/obj/docking_port/has_gravity(turf/T)
return FALSE
/obj/docking_port/take_damage()
return