mirror of
https://github.com/yogstation13/Yogstation.git
synced 2025-02-26 09:04:50 +00:00
You can no longer stack machines on one tile (#19683)
* Ports climbable & blocked turf Adds the climbable element to replace the copy paste code between machines and structures Ports the code improvements to blocked turf checks, commenting back in its uses that tattax had added but couldnt get functional (fixes ethereal jaunt & hierophant teleporting) Ports over LADYADDASSOCLIST code improvements, this has no effect in-game and mostly in the codebase, it's only ever used in two other locations total. Fixes being able to stack several machines on one tile * fixes climbing on crates * Update climbable.dm * merge conflicts r awesome
This commit is contained in:
13
code/__DEFINES/directional.dm
Normal file
13
code/__DEFINES/directional.dm
Normal file
@@ -0,0 +1,13 @@
|
||||
// Byond direction defines, because I want to put them somewhere.
|
||||
// #define NORTH 1
|
||||
// #define SOUTH 2
|
||||
// #define EAST 4
|
||||
// #define WEST 8
|
||||
|
||||
#define TEXT_NORTH "[NORTH]"
|
||||
#define TEXT_SOUTH "[SOUTH]"
|
||||
#define TEXT_EAST "[EAST]"
|
||||
#define TEXT_WEST "[WEST]"
|
||||
|
||||
/// Inverse direction, taking into account UP|DOWN if necessary.
|
||||
#define REVERSE_DIR(dir) ( ((dir & 85) << 1) | ((dir & 170) >> 1) )
|
||||
@@ -1,15 +1,3 @@
|
||||
// Byond direction defines, because I want to put them somewhere.
|
||||
// #define NORTH 1
|
||||
// #define SOUTH 2
|
||||
// #define EAST 4
|
||||
// #define WEST 8
|
||||
|
||||
#define TEXT_NORTH "[NORTH]"
|
||||
#define TEXT_SOUTH "[SOUTH]"
|
||||
#define TEXT_EAST "[EAST]"
|
||||
#define TEXT_WEST "[WEST]"
|
||||
|
||||
|
||||
//Human Overlays Indexes/////////
|
||||
#define MUTATIONS_LAYER 28 //mutations. Tk headglows, cold resistance glow, etc
|
||||
#define BODY_BEHIND_LAYER 27 //certain mutantrace features (tail when looking south) that must appear behind the body parts
|
||||
|
||||
@@ -359,6 +359,8 @@
|
||||
/// trait associated to being held in a chokehold
|
||||
#define CHOKEHOLD_TRAIT "chokehold"
|
||||
#define CRYO_TRAIT "cryo_trait"
|
||||
/// Trait applied by element
|
||||
#define ELEMENT_TRAIT(source) "element_trait_[source]"
|
||||
|
||||
// unique trait sources, still defines
|
||||
#define CLONING_POD_TRAIT "cloning-pod"
|
||||
@@ -439,5 +441,8 @@
|
||||
///every object that is currently the active storage of some client mob has this trait
|
||||
#define TRAIT_ACTIVE_STORAGE "active_storage"
|
||||
|
||||
/// Climbable trait, given and taken by the climbable element when added or removed. Exists to be easily checked via HAS_TRAIT().
|
||||
#define TRAIT_CLIMBABLE "trait_climbable"
|
||||
|
||||
///Organ traits
|
||||
#define TRAIT_BALLMER_SCIENTIST "ballmer_scientist"
|
||||
|
||||
@@ -32,7 +32,11 @@
|
||||
///Returns the list if it's actually a valid list, otherwise will initialize it
|
||||
#define SANITIZE_LIST(L) ( islist(L) ? L : list() )
|
||||
#define reverseList(L) reverseRange(L.Copy())
|
||||
#define LAZYADDASSOC(L, K, V) if(!L) { L = list(); } L[K] += list(V);
|
||||
///Adds to the item K the value V, if the list is null it will initialize it
|
||||
#define LAZYADDASSOC(L, K, V) if(!L) { L = list(); } L[K] += V;
|
||||
///This is used to add onto lazy assoc list when the value you're adding is a /list/. This one has extra safety over lazyaddassoc because the value could be null (and thus cant be used to += objects)
|
||||
#define LAZYADDASSOCLIST(L, K, V) if(!L) { L = list(); } L[K] += list(V);
|
||||
///Removes the value V from the item K, if the item K is empty will remove it from the list, if the list is empty will set the list to null
|
||||
#define LAZYREMOVEASSOC(L, K, V) if(L) { if(L[K]) { L[K] -= V; if(!length(L[K])) L -= K; } if(!length(L)) L = null; }
|
||||
|
||||
/// Passed into BINARY_INSERT to compare keys
|
||||
|
||||
@@ -736,7 +736,7 @@
|
||||
continue
|
||||
|
||||
if (!isspaceturf(found_turf))
|
||||
if (!is_blocked_turf(found_turf))
|
||||
if (!found_turf.is_blocked_turf())
|
||||
possible_loc.Add(found_turf)
|
||||
|
||||
// Need at least one free location.
|
||||
|
||||
@@ -504,15 +504,6 @@ Turf and target are separate in case you want to teleport some distance from a t
|
||||
|
||||
return 1
|
||||
|
||||
/proc/is_blocked_turf(turf/T, exclude_mobs)
|
||||
if(T.density)
|
||||
return 1
|
||||
for(var/i in T)
|
||||
var/atom/A = i
|
||||
if(A.density && (!exclude_mobs || !ismob(A)))
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/proc/is_anchored_dense_turf(turf/T) //like the older version of the above, fails only if also anchored
|
||||
if(T.density)
|
||||
return 1
|
||||
@@ -526,7 +517,7 @@ Turf and target are separate in case you want to teleport some distance from a t
|
||||
var/base_dir = get_dir(ref, get_step_towards(ref,trg))
|
||||
var/turf/temp = get_step_towards(ref,trg)
|
||||
|
||||
if(is_blocked_turf(temp))
|
||||
if(temp.is_blocked_turf())
|
||||
var/dir_alt1 = turn(base_dir, 90)
|
||||
var/dir_alt2 = turn(base_dir, -90)
|
||||
var/turf/turf_last1 = temp
|
||||
@@ -535,10 +526,10 @@ Turf and target are separate in case you want to teleport some distance from a t
|
||||
var/breakpoint = 0
|
||||
|
||||
while(!free_tile && breakpoint < 10)
|
||||
if(!is_blocked_turf(turf_last1))
|
||||
if(!turf_last1.is_blocked_turf())
|
||||
free_tile = turf_last1
|
||||
break
|
||||
if(!is_blocked_turf(turf_last2))
|
||||
if(!turf_last2.is_blocked_turf())
|
||||
free_tile = turf_last2
|
||||
break
|
||||
turf_last1 = get_step(turf_last1,dir_alt1)
|
||||
|
||||
@@ -836,7 +836,7 @@ SUBSYSTEM_DEF(job)
|
||||
//last hurrah
|
||||
var/list/avail = list()
|
||||
for(var/turf/T in A)
|
||||
if(!is_blocked_turf(T, TRUE))
|
||||
if(!T.is_blocked_turf(TRUE))
|
||||
avail += T
|
||||
if(avail.len)
|
||||
destination = pick(avail)
|
||||
@@ -847,7 +847,7 @@ SUBSYSTEM_DEF(job)
|
||||
var/list/arrivals_turfs = shuffle(get_area_turfs(/area/shuttle/arrival))
|
||||
if(arrivals_turfs.len)
|
||||
for(var/turf/T in arrivals_turfs)
|
||||
if(!is_blocked_turf(T, TRUE))
|
||||
if(!T.is_blocked_turf(TRUE))
|
||||
T.JoinPlayerHere(M, FALSE)
|
||||
return
|
||||
//last chance, pick ANY spot on arrivals and dump em
|
||||
|
||||
@@ -54,7 +54,7 @@ SUBSYSTEM_DEF(minor_mapping)
|
||||
for(var/z in SSmapping.levels_by_trait(ZTRAIT_STATION))
|
||||
all_turfs += block(locate(1,1,z), locate(world.maxx,world.maxy,z))
|
||||
for(var/turf/open/floor/plating/T in all_turfs)
|
||||
if(is_blocked_turf(T))
|
||||
if(T.is_blocked_turf())
|
||||
continue
|
||||
if(locate(/obj/structure/cable) in T)
|
||||
exposed_wires += T
|
||||
|
||||
@@ -196,7 +196,7 @@
|
||||
message.maptext = complete_text
|
||||
|
||||
// View the message
|
||||
LAZYADDASSOC(owned_by.seen_messages, message_loc, src)
|
||||
LAZYADDASSOCLIST(owned_by.seen_messages, message_loc, src)
|
||||
owned_by.images |= message
|
||||
animate(message, alpha = 255, time = CHAT_MESSAGE_SPAWN_TIME)
|
||||
|
||||
|
||||
130
code/datums/elements/climbable.dm
Normal file
130
code/datums/elements/climbable.dm
Normal file
@@ -0,0 +1,130 @@
|
||||
/datum/element/climbable
|
||||
element_flags = ELEMENT_BESPOKE | ELEMENT_DETACH_ON_HOST_DESTROY // Detach for turfs
|
||||
argument_hash_start_idx = 2
|
||||
///Time it takes to climb onto the object
|
||||
var/climb_time
|
||||
///Stun duration for when you get onto the object
|
||||
var/climb_stun
|
||||
///Assoc list of object being climbed on - climbers. This allows us to check who needs to be shoved off a climbable object when its clicked on.
|
||||
var/list/current_climbers
|
||||
|
||||
/datum/element/climbable/Attach(
|
||||
datum/target,
|
||||
climb_time = 2 SECONDS,
|
||||
climb_stun = 2 SECONDS,
|
||||
)
|
||||
. = ..()
|
||||
|
||||
if(!isatom(target) || isarea(target))
|
||||
return ELEMENT_INCOMPATIBLE
|
||||
src.climb_time = climb_time
|
||||
src.climb_stun = climb_stun
|
||||
|
||||
RegisterSignal(target, COMSIG_ATOM_ATTACK_HAND, PROC_REF(attack_hand))
|
||||
RegisterSignal(target, COMSIG_PARENT_EXAMINE, PROC_REF(on_examine))
|
||||
RegisterSignal(target, COMSIG_MOUSEDROPPED_ONTO, PROC_REF(mousedrop_receive))
|
||||
RegisterSignal(target, COMSIG_ATOM_BUMPED, PROC_REF(try_speedrun))
|
||||
ADD_TRAIT(target, TRAIT_CLIMBABLE, ELEMENT_TRAIT(type))
|
||||
|
||||
/datum/element/climbable/Detach(datum/target)
|
||||
UnregisterSignal(target, list(COMSIG_ATOM_ATTACK_HAND, COMSIG_PARENT_EXAMINE, COMSIG_MOUSEDROPPED_ONTO, COMSIG_ATOM_BUMPED))
|
||||
REMOVE_TRAIT(target, TRAIT_CLIMBABLE, ELEMENT_TRAIT(type))
|
||||
return ..()
|
||||
|
||||
/datum/element/climbable/proc/on_examine(atom/source, mob/user, list/examine_texts)
|
||||
SIGNAL_HANDLER
|
||||
examine_texts += span_notice("[source] looks climbable.")
|
||||
|
||||
/datum/element/climbable/proc/can_climb(atom/source, mob/user)
|
||||
var/dir_step = get_dir(user, source.loc)
|
||||
//To jump over a railing you have to be standing next to it, not far behind it.
|
||||
if(source.flags_1 & ON_BORDER_1 && user.loc != source.loc && (dir_step & source.dir) == source.dir)
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/datum/element/climbable/proc/attack_hand(atom/climbed_thing, mob/user)
|
||||
SIGNAL_HANDLER
|
||||
var/list/climbers = LAZYACCESS(current_climbers, climbed_thing)
|
||||
for(var/i in climbers)
|
||||
var/mob/living/structure_climber = i
|
||||
if(structure_climber == user)
|
||||
return
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
user.do_attack_animation(climbed_thing)
|
||||
structure_climber.Paralyze(40)
|
||||
structure_climber.visible_message(span_warning("[structure_climber] is knocked off [climbed_thing]."), span_warning("You're knocked off [climbed_thing]!"), span_hear("You hear a cry from [structure_climber], followed by a slam."))
|
||||
|
||||
|
||||
/datum/element/climbable/proc/climb_structure(atom/climbed_thing, mob/living/user, params)
|
||||
if(!can_climb(climbed_thing, user))
|
||||
return
|
||||
climbed_thing.add_fingerprint(user)
|
||||
user.visible_message(span_warning("[user] starts climbing onto [climbed_thing]."), \
|
||||
span_notice("You start climbing onto [climbed_thing]..."))
|
||||
var/adjusted_climb_time = climb_time
|
||||
var/adjusted_climb_stun = climb_stun
|
||||
if(HAS_TRAIT(user, TRAIT_HANDS_BLOCKED)) //climbing takes twice as long without help from the hands.
|
||||
adjusted_climb_time *= 2
|
||||
if(isalien(user))
|
||||
adjusted_climb_time *= 0.25 //aliens are terrifyingly fast
|
||||
if(HAS_TRAIT(user, TRAIT_FREERUNNING)) //do you have any idea how fast I am???
|
||||
adjusted_climb_time *= 0.8
|
||||
adjusted_climb_stun *= 0.8
|
||||
LAZYADDASSOCLIST(current_climbers, climbed_thing, user)
|
||||
if(do_after(user, adjusted_climb_time, climbed_thing))
|
||||
if(QDELETED(climbed_thing)) //Checking if structure has been destroyed
|
||||
return
|
||||
if(do_climb(climbed_thing, user, params))
|
||||
user.visible_message(span_warning("[user] climbs onto [climbed_thing]."), \
|
||||
span_notice("You climb onto [climbed_thing]."))
|
||||
log_combat(user, climbed_thing, "climbed onto")
|
||||
if(adjusted_climb_stun)
|
||||
user.Stun(adjusted_climb_stun)
|
||||
else
|
||||
to_chat(user, span_warning("You fail to climb onto [climbed_thing]."))
|
||||
LAZYREMOVEASSOC(current_climbers, climbed_thing, user)
|
||||
|
||||
|
||||
/datum/element/climbable/proc/do_climb(atom/climbed_thing, mob/living/user, params)
|
||||
if(!can_climb(climbed_thing, user))
|
||||
return
|
||||
climbed_thing.set_density(FALSE)
|
||||
var/dir_step = get_dir(user, climbed_thing.loc)
|
||||
var/same_loc = climbed_thing.loc == user.loc
|
||||
// on-border objects can be vaulted over and into the next turf.
|
||||
// The reverse dir check is for when normal behavior should apply instead (e.g. John Doe hops east of a railing facing west, ending on the same turf as it).
|
||||
if(climbed_thing.flags_1 & ON_BORDER_1 && (same_loc || !(dir_step & REVERSE_DIR(climbed_thing.dir))))
|
||||
//it can be vaulted over in two different cardinal directions. we choose one.
|
||||
if(ISDIAGONALDIR(climbed_thing.dir) && same_loc)
|
||||
if(params) //we check the icon x and y parameters of the click-drag to determine step_dir.
|
||||
var/list/modifiers = params2list(params)
|
||||
var/x_dist = (text2num(LAZYACCESS(modifiers, ICON_X)) - world.icon_size/2) * (climbed_thing.dir & WEST ? -1 : 1)
|
||||
var/y_dist = (text2num(LAZYACCESS(modifiers, ICON_Y)) - world.icon_size/2) * (climbed_thing.dir & SOUTH ? -1 : 1)
|
||||
dir_step = (x_dist >= y_dist ? (EAST|WEST) : (NORTH|SOUTH)) & climbed_thing.dir
|
||||
else //user is being moved by a forced_movement datum. dir_step will be the direction to the forced movement target.
|
||||
dir_step = get_dir(user, user.force_moving.target)
|
||||
else
|
||||
dir_step = get_dir(user, get_step(climbed_thing, climbed_thing.dir))
|
||||
. = step(user, dir_step)
|
||||
climbed_thing.set_density(TRUE)
|
||||
|
||||
///Handles climbing onto the atom when you click-drag
|
||||
/datum/element/climbable/proc/mousedrop_receive(atom/climbed_thing, atom/movable/dropped_atom, mob/user, params)
|
||||
SIGNAL_HANDLER
|
||||
if(user == dropped_atom && isliving(dropped_atom))
|
||||
var/mob/living/living_target = dropped_atom
|
||||
if(isanimal(living_target))
|
||||
var/mob/living/simple_animal/animal = dropped_atom
|
||||
if (!animal.dextrous)
|
||||
return
|
||||
if(living_target.mobility_flags & MOBILITY_MOVE)
|
||||
INVOKE_ASYNC(src, PROC_REF(climb_structure), climbed_thing, living_target, params)
|
||||
return
|
||||
|
||||
///Tries to climb onto the target if the forced movement of the mob allows it
|
||||
/datum/element/climbable/proc/try_speedrun(datum/source, mob/bumpee)
|
||||
SIGNAL_HANDLER
|
||||
if(!istype(bumpee))
|
||||
return
|
||||
if(bumpee.force_moving?.allow_climbing)
|
||||
do_climb(source, bumpee)
|
||||
@@ -84,10 +84,3 @@
|
||||
. = TryMove(TRUE)
|
||||
|
||||
. = . && (vic.loc != tar.loc)
|
||||
|
||||
/mob/Bump(atom/A)
|
||||
. = ..()
|
||||
if(force_moving && force_moving.allow_climbing && isstructure(A))
|
||||
var/obj/structure/S = A
|
||||
if(S.climbable)
|
||||
S.do_climb(src)
|
||||
|
||||
@@ -131,7 +131,6 @@ Class Procs:
|
||||
|
||||
/// For storing and overriding ui id
|
||||
var/tgui_id // ID of TGUI interface
|
||||
var/climbable = FALSE
|
||||
var/climb_time = 20
|
||||
var/climb_stun = 20
|
||||
var/mob/living/machineclimber
|
||||
@@ -409,25 +408,37 @@ Class Procs:
|
||||
deconstruct(TRUE)
|
||||
|
||||
/obj/machinery/deconstruct(disassembled = TRUE, force = FALSE)
|
||||
if(!(flags_1 & NODECONSTRUCT_1))
|
||||
on_deconstruction()
|
||||
if(component_parts && component_parts.len)
|
||||
if(!force)
|
||||
spawn_frame(disassembled)
|
||||
for(var/obj/item/I in component_parts)
|
||||
I.forceMove(loc)
|
||||
component_parts.Cut()
|
||||
qdel(src)
|
||||
if(flags_1 & NODECONSTRUCT_1)
|
||||
return ..()
|
||||
|
||||
on_deconstruction()
|
||||
if(!LAZYLEN(component_parts))
|
||||
return ..()
|
||||
spawn_frame(disassembled)
|
||||
for(var/obj/item/I in component_parts)
|
||||
I.forceMove(loc)
|
||||
component_parts.Cut()
|
||||
return ..()
|
||||
|
||||
/obj/machinery/proc/spawn_frame(disassembled)
|
||||
var/obj/structure/frame/machine/M = new /obj/structure/frame/machine(loc)
|
||||
. = M
|
||||
M.setAnchored(anchored)
|
||||
var/obj/structure/frame/machine/new_frame = new /obj/structure/frame/machine(loc)
|
||||
|
||||
new_frame.state = 2
|
||||
|
||||
// If the new frame shouldn't be able to fit here due to the turf being blocked, spawn the frame deconstructed.
|
||||
if(isturf(loc))
|
||||
var/turf/machine_turf = loc
|
||||
// We're spawning a frame before this machine is qdeleted, so we want to ignore it. We've also just spawned a new frame, so ignore that too.
|
||||
if(machine_turf.is_blocked_turf(TRUE, source_atom = new_frame, ignore_atoms = list(src)))
|
||||
new_frame.deconstruct(disassembled)
|
||||
return
|
||||
|
||||
new_frame.icon_state = "box_1"
|
||||
. = new_frame
|
||||
new_frame.setAnchored(anchored)
|
||||
if(!disassembled)
|
||||
M.obj_integrity = M.max_integrity * 0.5 //the frame is already half broken
|
||||
transfer_fingerprints_to(M)
|
||||
M.state = 2
|
||||
M.icon_state = "box_1"
|
||||
new_frame.obj_integrity = (new_frame.max_integrity * 0.5) //the frame is already half broken
|
||||
transfer_fingerprints_to(new_frame)
|
||||
|
||||
/obj/machinery/obj_break(damage_flag)
|
||||
if(!(stat & BROKEN) && !(flags_1 & NODECONSTRUCT_1))
|
||||
@@ -475,23 +486,28 @@ Class Procs:
|
||||
return FAILED_UNFASTEN
|
||||
return SUCCESSFUL_UNFASTEN
|
||||
|
||||
/obj/proc/default_unfasten_wrench(mob/user, obj/item/I, time = 20) //try to unwrench an object in a WONDERFUL DYNAMIC WAY
|
||||
if(!(flags_1 & NODECONSTRUCT_1) && I.tool_behaviour == TOOL_WRENCH)
|
||||
var/can_be_unfasten = can_be_unfasten_wrench(user)
|
||||
if(!can_be_unfasten || can_be_unfasten == FAILED_UNFASTEN)
|
||||
return can_be_unfasten
|
||||
if(time)
|
||||
to_chat(user, span_notice("You begin [anchored ? "un" : ""]securing [src]..."))
|
||||
I.play_tool_sound(src, 50)
|
||||
var/prev_anchored = anchored
|
||||
//as long as we're the same anchored state and we're either on a floor or are anchored, toggle our anchored state
|
||||
if(I.use_tool(src, user, time, extra_checks = CALLBACK(src, PROC_REF(unfasten_wrench_check), prev_anchored, user)))
|
||||
to_chat(user, span_notice("You [anchored ? "un" : ""]secure [src]."))
|
||||
setAnchored(!anchored)
|
||||
playsound(src, 'sound/items/deconstruct.ogg', 50, 1)
|
||||
return SUCCESSFUL_UNFASTEN
|
||||
return FAILED_UNFASTEN
|
||||
return CANT_UNFASTEN
|
||||
/obj/proc/default_unfasten_wrench(mob/user, obj/item/wrench, time = 20) //try to unwrench an object in a WONDERFUL DYNAMIC WAY
|
||||
if((flags_1 & NODECONSTRUCT_1) || wrench.tool_behaviour != TOOL_WRENCH)
|
||||
return CANT_UNFASTEN
|
||||
|
||||
var/turf/ground = get_turf(src)
|
||||
if(!anchored && ground.is_blocked_turf(exclude_mobs = TRUE, source_atom = src))
|
||||
to_chat(user, span_notice("You fail to secure [src]."))
|
||||
return CANT_UNFASTEN
|
||||
var/can_be_unfasten = can_be_unfasten_wrench(user)
|
||||
if(!can_be_unfasten || can_be_unfasten == FAILED_UNFASTEN)
|
||||
return can_be_unfasten
|
||||
if(time)
|
||||
to_chat(user, span_notice("You begin [anchored ? "un" : ""]securing [src]..."))
|
||||
wrench.play_tool_sound(src, 50)
|
||||
var/prev_anchored = anchored
|
||||
//as long as we're the same anchored state and we're either on a floor or are anchored, toggle our anchored state
|
||||
if(wrench.use_tool(src, user, time, extra_checks = CALLBACK(src, PROC_REF(unfasten_wrench_check), prev_anchored, user)))
|
||||
to_chat(user, span_notice("You [anchored ? "un" : ""]secure [src]."))
|
||||
setAnchored(!anchored)
|
||||
playsound(src, 'sound/items/deconstruct.ogg', 50, 1)
|
||||
return SUCCESSFUL_UNFASTEN
|
||||
return FAILED_UNFASTEN
|
||||
|
||||
/obj/proc/unfasten_wrench_check(prev_anchored, mob/user) //for the do_after, this checks if unfastening conditions are still valid
|
||||
if(anchored != prev_anchored)
|
||||
@@ -636,67 +652,3 @@ Class Procs:
|
||||
|
||||
/obj/machinery/rust_heretic_act()
|
||||
take_damage(500, BRUTE, MELEE, 1)
|
||||
|
||||
/obj/machinery/MouseDrop_T(atom/movable/O, mob/user)
|
||||
. = ..()
|
||||
if(!climbable)
|
||||
return
|
||||
if(user == O && iscarbon(O))
|
||||
var/mob/living/carbon/C = O
|
||||
if(C.mobility_flags & MOBILITY_MOVE)
|
||||
climb_machine(user)
|
||||
return
|
||||
if(!istype(O, /obj/item) || user.get_active_held_item() != O)
|
||||
return
|
||||
if(iscyborg(user))
|
||||
return
|
||||
if(!user.dropItemToGround(O))
|
||||
return
|
||||
if (O.loc != src.loc)
|
||||
step(O, get_dir(O, src))
|
||||
|
||||
/obj/machinery/proc/do_climb(atom/movable/A)
|
||||
if(climbable)
|
||||
density = FALSE
|
||||
. = step(A,get_dir(A,src.loc))
|
||||
density = TRUE
|
||||
|
||||
/obj/machinery/proc/climb_machine(mob/living/user)
|
||||
src.add_fingerprint(user)
|
||||
user.visible_message("<span class='warning'>[user] starts climbing onto [src].</span>", \
|
||||
"<span class='notice'>You start climbing onto [src]...</span>")
|
||||
var/adjusted_climb_time = climb_time
|
||||
if(user.restrained()) //climbing takes twice as long when restrained.
|
||||
adjusted_climb_time *= 2
|
||||
if(isalien(user))
|
||||
adjusted_climb_time *= 0.25 //aliens are terrifyingly fast
|
||||
if(HAS_TRAIT(user, TRAIT_FREERUNNING)) //do you have any idea how fast I am???
|
||||
adjusted_climb_time *= 0.8
|
||||
machineclimber = user
|
||||
if(do_mob(user, user, adjusted_climb_time))
|
||||
if(src.loc) //Checking if structure has been destroyed
|
||||
if(do_climb(user))
|
||||
user.visible_message("<span class='warning'>[user] climbs onto [src].</span>", \
|
||||
"<span class='notice'>You climb onto [src].</span>")
|
||||
log_combat(user, src, "climbed onto")
|
||||
if(climb_stun)
|
||||
var/mob/living/carbon/human/H = user
|
||||
var/wagging = FALSE
|
||||
if(H && H.dna.species.is_wagging_tail())
|
||||
wagging = TRUE
|
||||
user.Stun(climb_stun)
|
||||
if(wagging)
|
||||
H.dna.species.start_wagging_tail(H)
|
||||
. = 1
|
||||
else
|
||||
to_chat(user, "<span class='warning'>You fail to climb onto [src].</span>")
|
||||
machineclimber = null
|
||||
|
||||
/obj/machinery/CanAStarPass(ID, dir, caller)
|
||||
. = ..()
|
||||
if(climbable)
|
||||
return TRUE
|
||||
if(can_be_occupant(caller))
|
||||
return TRUE
|
||||
|
||||
|
||||
|
||||
@@ -123,10 +123,13 @@
|
||||
proj_pass_rate = 20
|
||||
pass_flags = LETPASSTHROW
|
||||
bar_material = SAND
|
||||
climbable = TRUE
|
||||
smooth = SMOOTH_TRUE
|
||||
canSmoothWith = list(/obj/structure/barricade/sandbags, /turf/closed/wall, /turf/closed/wall/r_wall, /obj/structure/falsewall, /obj/structure/falsewall/reinforced, /turf/closed/wall/rust, /turf/closed/wall/r_wall/rust, /obj/structure/barricade/security)
|
||||
|
||||
/obj/structure/barricade/sandbags/Initialize(mapload)
|
||||
. = ..()
|
||||
AddElement(/datum/element/climbable)
|
||||
|
||||
/obj/structure/barricade/security
|
||||
name = "security barrier"
|
||||
desc = "A deployable barrier. Provides good cover in fire fights."
|
||||
@@ -187,20 +190,20 @@
|
||||
new /obj/structure/barricade/security(get_turf(src.loc))
|
||||
switch(mode)
|
||||
if(VERTICAL)
|
||||
var/target_turf = get_step(src, NORTH)
|
||||
if(!(is_blocked_turf(target_turf)))
|
||||
var/turf/target_turf = get_step(src, NORTH)
|
||||
if(!(target_turf.is_blocked_turf()))
|
||||
new /obj/structure/barricade/security(target_turf)
|
||||
|
||||
var/target_turf2 = get_step(src, SOUTH)
|
||||
if(!(is_blocked_turf(target_turf2)))
|
||||
var/turf/target_turf2 = get_step(src, SOUTH)
|
||||
if(!(target_turf2.is_blocked_turf()))
|
||||
new /obj/structure/barricade/security(target_turf2)
|
||||
if(HORIZONTAL)
|
||||
var/target_turf = get_step(src, EAST)
|
||||
if(!(is_blocked_turf(target_turf)))
|
||||
var/turf/target_turf = get_step(src, EAST)
|
||||
if(!(target_turf.is_blocked_turf()))
|
||||
new /obj/structure/barricade/security(target_turf)
|
||||
|
||||
var/target_turf2 = get_step(src, WEST)
|
||||
if(!(is_blocked_turf(target_turf2)))
|
||||
var/turf/target_turf2 = get_step(src, WEST)
|
||||
if(!(target_turf2.is_blocked_turf()))
|
||||
new /obj/structure/barricade/security(target_turf2)
|
||||
qdel(src)
|
||||
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
idle_power_usage = 2
|
||||
resistance_flags = LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
|
||||
layer = OPEN_DOOR_LAYER
|
||||
climbable = TRUE
|
||||
|
||||
/obj/machinery/ministile/hop
|
||||
name = "HOP line turnstile"
|
||||
@@ -23,6 +22,7 @@
|
||||
/obj/machinery/ministile/Initialize(mapload)
|
||||
. = ..()
|
||||
icon_state = "ministile"
|
||||
AddElement(/datum/element/climbable)
|
||||
|
||||
/obj/machinery/ministile/CanAtmosPass(turf/T)
|
||||
return TRUE
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
idle_power_usage = 2
|
||||
resistance_flags = LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
|
||||
layer = OPEN_DOOR_LAYER
|
||||
climbable = FALSE
|
||||
|
||||
/obj/machinery/turnstile/brig
|
||||
name = "Brig turnstile"
|
||||
|
||||
@@ -529,13 +529,13 @@
|
||||
if(T.density)
|
||||
if(wall_turret_direction)
|
||||
var/turf/closer = get_step(T,wall_turret_direction)
|
||||
if(istype(closer) && !is_blocked_turf(closer) && T.Adjacent(closer))
|
||||
if(istype(closer) && !closer.is_blocked_turf() && T.Adjacent(closer))
|
||||
T = closer
|
||||
else
|
||||
var/target_dir = get_dir(T,target)
|
||||
for(var/d in list(0,-45,45))
|
||||
var/turf/closer = get_step(T,turn(target_dir,d))
|
||||
if(istype(closer) && !is_blocked_turf(closer) && T.Adjacent(closer))
|
||||
if(istype(closer) && !closer.is_blocked_turf() && T.Adjacent(closer))
|
||||
T = closer
|
||||
break
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark)
|
||||
. = ..()
|
||||
GLOB.start_landmarks_list += src
|
||||
if(jobspawn_override)
|
||||
LAZYADDASSOC(GLOB.jobspawn_overrides, name, src)
|
||||
LAZYADDASSOCLIST(GLOB.jobspawn_overrides, name, src)
|
||||
if(name != "start")
|
||||
tag = "start*[name]"
|
||||
|
||||
|
||||
@@ -476,8 +476,8 @@ GLOBAL_LIST_INIT(fluid_duct_recipes, list(
|
||||
if(DISPOSALS_CATEGORY) //Making disposals pipes
|
||||
if(!can_make_pipe)
|
||||
return ..()
|
||||
A = get_turf(A)
|
||||
if(is_blocked_turf(A))
|
||||
var/turf/attempting_turf = get_turf(A)
|
||||
if(attempting_turf.is_blocked_turf())
|
||||
to_chat(user, span_warning("[src]'s error light flickers; there's something in the way!"))
|
||||
return
|
||||
to_chat(user, span_notice("You start building a disposals pipe..."))
|
||||
@@ -501,8 +501,8 @@ GLOBAL_LIST_INIT(fluid_duct_recipes, list(
|
||||
if(TRANSIT_CATEGORY) //Making transit tubes
|
||||
if(!can_make_pipe)
|
||||
return ..()
|
||||
A = get_turf(A)
|
||||
if(is_blocked_turf(A))
|
||||
var/turf/attempting_turf = get_turf(A)
|
||||
if(attempting_turf.is_blocked_turf())
|
||||
to_chat(user, span_warning("[src]'s error light flickers; there's something in the way!"))
|
||||
return
|
||||
to_chat(user, span_notice("You start building a transit tube..."))
|
||||
@@ -530,8 +530,8 @@ GLOBAL_LIST_INIT(fluid_duct_recipes, list(
|
||||
if(PLUMBING_CATEGORY) //Making pancakes
|
||||
if(!can_make_pipe)
|
||||
return ..()
|
||||
A = get_turf(A)
|
||||
if(is_blocked_turf(A))
|
||||
var/turf/attempting_turf = get_turf(A)
|
||||
if(attempting_turf.is_blocked_turf())
|
||||
to_chat(user, span_warning("[src]'s error light flickers; there's something in the way!"))
|
||||
return
|
||||
to_chat(user, span_notice("You start building a fluid duct..."))
|
||||
|
||||
@@ -97,7 +97,7 @@
|
||||
P.icon_state = "[P.icon_base]_[dir]"
|
||||
P.tape_dir = dir
|
||||
cur = get_step_towards(cur,end)
|
||||
//is_blocked_turf(turf/T)
|
||||
//T.is_blocked_turf()
|
||||
to_chat(usr, span_notice("You finish placing the [src].")) //Git Test
|
||||
|
||||
/obj/item/barrier_taperoll/afterattack(atom/A, mob/user, proximity)
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
to_chat(user, span_notice("You use [src] to deactivate [H]."))
|
||||
qdel(H)
|
||||
else
|
||||
if(!is_blocked_turf(T, TRUE)) //can't put hard light on a tile that has dense stuff
|
||||
if(!T.is_blocked_turf(TRUE)) //can't put hard light on a tile that has dense stuff
|
||||
if(holocreator_busy)
|
||||
to_chat(user, span_notice("[src] is busy creating a hard light barrier."))
|
||||
return
|
||||
@@ -45,7 +45,7 @@
|
||||
holocreator_busy = FALSE
|
||||
if(signs.len >= max_signs)
|
||||
return
|
||||
if(is_blocked_turf(T, TRUE)) //don't try to sneak dense stuff on our tile during the wait.
|
||||
if(T.is_blocked_turf(TRUE)) //don't try to sneak dense stuff on our tile during the wait.
|
||||
return
|
||||
H = new holosign_type(get_turf(target), src)
|
||||
to_chat(user, span_notice("You create \a [H] with [src]."))
|
||||
|
||||
@@ -3,13 +3,10 @@
|
||||
pressure_resistance = 8
|
||||
max_integrity = 300
|
||||
interaction_flags_atom = INTERACT_ATOM_ATTACK_HAND | INTERACT_ATOM_UI_INTERACT
|
||||
var/climb_time = 20
|
||||
var/climb_stun = 20
|
||||
var/climbable = FALSE
|
||||
var/mob/living/structureclimber
|
||||
var/broken = 0 //similar to machinery's stat BROKEN
|
||||
layer = BELOW_OBJ_LAYER
|
||||
|
||||
var/broken = 0 //similar to machinery's stat BROKEN
|
||||
|
||||
|
||||
/obj/structure/Initialize(mapload)
|
||||
if (!armor)
|
||||
@@ -32,75 +29,10 @@
|
||||
if(istype(mover) && (mover.pass_flags & PASSSTRUCTURE))
|
||||
return TRUE
|
||||
|
||||
/obj/structure/attack_hand(mob/user)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
if(structureclimber && structureclimber != user)
|
||||
user.changeNext_move(CLICK_CD_MELEE)
|
||||
user.do_attack_animation(src)
|
||||
structureclimber.Paralyze(40)
|
||||
structureclimber.visible_message(span_warning("[structureclimber] has been knocked off [src]."), span_warning("You're knocked off [src]!"), span_warning("You see [structureclimber] get knocked off [src]."))
|
||||
|
||||
/obj/structure/ui_act(action, params)
|
||||
add_fingerprint(usr)
|
||||
return ..()
|
||||
|
||||
/obj/structure/MouseDrop_T(atom/movable/O, mob/user)
|
||||
. = ..()
|
||||
if(!climbable)
|
||||
return
|
||||
if(user == O && iscarbon(O))
|
||||
var/mob/living/carbon/C = O
|
||||
if(C.mobility_flags & MOBILITY_MOVE)
|
||||
climb_structure(user)
|
||||
return
|
||||
if(!istype(O, /obj/item) || user.get_active_held_item() != O)
|
||||
return
|
||||
if(iscyborg(user))
|
||||
return
|
||||
if(!user.dropItemToGround(O))
|
||||
return
|
||||
if (O.loc != src.loc)
|
||||
step(O, get_dir(O, src))
|
||||
|
||||
/obj/structure/proc/do_climb(atom/movable/A)
|
||||
if(climbable)
|
||||
density = FALSE
|
||||
. = step(A,get_dir(A,src.loc))
|
||||
density = TRUE
|
||||
|
||||
/obj/structure/proc/climb_structure(mob/living/user)
|
||||
src.add_fingerprint(user)
|
||||
user.visible_message(span_warning("[user] starts climbing onto [src]."), \
|
||||
span_notice("You start climbing onto [src]..."))
|
||||
var/adjusted_climb_time = climb_time
|
||||
if(HAS_TRAIT(user, TRAIT_HANDS_BLOCKED)) //climbing takes twice as long without help from the hands.
|
||||
adjusted_climb_time *= 2
|
||||
if(isalien(user))
|
||||
adjusted_climb_time *= 0.25 //aliens are terrifyingly fast
|
||||
if(HAS_TRAIT(user, TRAIT_FREERUNNING)) //do you have any idea how fast I am???
|
||||
adjusted_climb_time *= 0.8
|
||||
structureclimber = user
|
||||
if(do_mob(user, user, adjusted_climb_time))
|
||||
if(src.loc) //Checking if structure has been destroyed
|
||||
if(do_climb(user))
|
||||
user.visible_message(span_warning("[user] climbs onto [src]."), \
|
||||
span_notice("You climb onto [src]."))
|
||||
log_combat(user, src, "climbed onto")
|
||||
if(climb_stun)
|
||||
var/mob/living/carbon/human/H = user
|
||||
var/wagging = FALSE
|
||||
if(H && H.dna.species.is_wagging_tail())
|
||||
wagging = TRUE
|
||||
user.Stun(climb_stun)
|
||||
if(wagging)
|
||||
H.dna.species.start_wagging_tail(H)
|
||||
. = 1
|
||||
else
|
||||
to_chat(user, span_warning("You fail to climb onto [src]."))
|
||||
structureclimber = null
|
||||
|
||||
/obj/structure/examine(mob/user)
|
||||
. = ..()
|
||||
if(!(resistance_flags & INDESTRUCTIBLE))
|
||||
|
||||
@@ -209,7 +209,6 @@ GLOBAL_LIST_EMPTY(lockers)
|
||||
opened = TRUE
|
||||
if(!dense_when_open)
|
||||
density = FALSE
|
||||
climb_time *= 0.5 //it's faster to climb onto an open thing
|
||||
dump_contents()
|
||||
animate_door(FALSE)
|
||||
update_appearance(UPDATE_ICON)
|
||||
@@ -262,7 +261,6 @@ GLOBAL_LIST_EMPTY(lockers)
|
||||
return FALSE
|
||||
take_contents()
|
||||
playsound(loc, close_sound, 15, 1, -3)
|
||||
climb_time = initial(climb_time)
|
||||
opened = FALSE
|
||||
density = TRUE
|
||||
animate_door(TRUE)
|
||||
|
||||
@@ -7,13 +7,11 @@
|
||||
can_weld_shut = FALSE
|
||||
open_flags = HORIZONTAL_HOLD | HORIZONTAL_LID | ALLOW_OBJECTS | ALLOW_DENSE
|
||||
dense_when_open = TRUE
|
||||
climbable = TRUE
|
||||
climb_time = 10 //real fast, because let's be honest stepping into or onto a crate is easy
|
||||
climb_stun = 0 //climbing onto crates isn't hard, guys
|
||||
delivery_icon = "deliverycrate"
|
||||
door_anim_time = 0 // no animation
|
||||
var/obj/item/paper/fluff/jobs/cargo/manifest/manifest
|
||||
breakout_time = 20 SECONDS
|
||||
var/crate_climb_time = 20
|
||||
var/obj/item/paper/fluff/jobs/cargo/manifest/manifest
|
||||
///The resident (owner) of this crate/coffin.
|
||||
var/mob/living/resident
|
||||
///The time it takes to pry this open with a crowbar.
|
||||
@@ -21,6 +19,7 @@
|
||||
|
||||
/obj/structure/closet/crate/Initialize(mapload)
|
||||
. = ..()
|
||||
AddElement(/datum/element/climbable, climb_time = crate_climb_time, climb_stun = 0) //add element in closed state before parent init opens it(if it does)
|
||||
if(icon_state == "[initial(icon_state)]open")
|
||||
opened = TRUE
|
||||
update_appearance(UPDATE_ICON)
|
||||
@@ -53,6 +52,8 @@
|
||||
|
||||
/obj/structure/closet/crate/open(mob/living/user)
|
||||
. = ..()
|
||||
RemoveElement(/datum/element/climbable, climb_time = crate_climb_time, climb_stun = 0)
|
||||
AddElement(/datum/element/climbable, climb_time = crate_climb_time * 0.5, climb_stun = 0)
|
||||
if(. && manifest)
|
||||
to_chat(user, span_notice("The manifest is torn off [src]."))
|
||||
playsound(src, 'sound/items/poster_ripped.ogg', 75, 1)
|
||||
@@ -60,6 +61,11 @@
|
||||
manifest = null
|
||||
update_appearance(UPDATE_ICON)
|
||||
|
||||
/obj/structure/closet/crate/close(mob/living/user)
|
||||
. = ..()
|
||||
RemoveElement(/datum/element/climbable, climb_time = crate_climb_time * 0.5, climb_stun = 0)
|
||||
AddElement(/datum/element/climbable, climb_time = crate_climb_time, climb_stun = 0)
|
||||
|
||||
/obj/structure/closet/crate/proc/tear_manifest(mob/user)
|
||||
to_chat(user, span_notice("You tear the manifest off of [src]."))
|
||||
playsound(src, 'sound/items/poster_ripped.ogg', 75, 1)
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
|
||||
#define CUT_TIME 100
|
||||
#define CLIMB_TIME 150
|
||||
|
||||
#define NO_HOLE 0 //section is intact
|
||||
#define MEDIUM_HOLE 1 //medium hole in the section - can climb through
|
||||
@@ -79,11 +78,11 @@
|
||||
if(MEDIUM_HOLE)
|
||||
visible_message(span_notice("\The [user] cuts into \the [src] some more."))
|
||||
to_chat(user, span_info("You could probably fit yourself through that hole now. Although climbing through would be much faster if you made it even bigger."))
|
||||
climbable = TRUE
|
||||
AddElement(/datum/element/climbable)
|
||||
if(LARGE_HOLE)
|
||||
visible_message(span_notice("\The [user] completely cuts through \the [src]."))
|
||||
to_chat(user, span_info("The hole in \the [src] is now big enough to walk through."))
|
||||
climbable = FALSE
|
||||
RemoveElement(/datum/element/climbable)
|
||||
|
||||
update_cut_status()
|
||||
|
||||
@@ -152,7 +151,6 @@
|
||||
return TRUE
|
||||
|
||||
#undef CUT_TIME
|
||||
#undef CLIMB_TIME
|
||||
|
||||
#undef NO_HOLE
|
||||
#undef MEDIUM_HOLE
|
||||
|
||||
@@ -5,21 +5,24 @@
|
||||
icon_state = "railing"
|
||||
density = TRUE
|
||||
anchored = TRUE
|
||||
climbable = TRUE
|
||||
pixel_y = -16
|
||||
climb_time = 10 // not that hard to jump a rail
|
||||
climb_stun = 0 // if you dont fall
|
||||
|
||||
///Boolean on whether the railing should be cimable.
|
||||
var/climbable = TRUE
|
||||
///Initial direction of the railing.
|
||||
var/ini_dir
|
||||
|
||||
/obj/structure/railing/corner //aesthetic corner sharp edges hurt oof ouch
|
||||
icon_state = "railing_corner"
|
||||
density = FALSE
|
||||
|
||||
climbable = FALSE
|
||||
|
||||
/obj/structure/railing/Initialize(mapload)
|
||||
. = ..()
|
||||
ini_dir = dir
|
||||
if(climbable)
|
||||
AddElement(/datum/element/climbable)
|
||||
AddComponent(/datum/component/simple_rotation,ROTATION_ALTCLICK | ROTATION_CLOCKWISE | ROTATION_COUNTERCLOCKWISE | ROTATION_VERBS ,null,CALLBACK(src, PROC_REF(can_be_rotated)),CALLBACK(src, PROC_REF(after_rotation)))
|
||||
|
||||
/obj/structure/railing/attackby(obj/item/I, mob/living/user, params)
|
||||
|
||||
@@ -20,7 +20,6 @@
|
||||
density = TRUE
|
||||
anchored = TRUE
|
||||
layer = TABLE_LAYER
|
||||
climbable = TRUE
|
||||
pass_flags = LETPASSTHROW //You can throw objects over this, despite it's density.")
|
||||
var/frame = /obj/structure/table_frame
|
||||
var/framestack = /obj/item/stack/rods
|
||||
@@ -36,6 +35,7 @@
|
||||
|
||||
/obj/structure/table/Initialize(mapload)
|
||||
. = ..()
|
||||
AddElement(/datum/element/climbable)
|
||||
AddComponent(/datum/component/surgery_bed, \
|
||||
success_chance = 0.8, \
|
||||
)
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
density = TRUE
|
||||
layer = LOW_ITEM_LAYER
|
||||
anchored = TRUE
|
||||
climbable = 1
|
||||
var/tube_construction = /obj/structure/c_transit_tube
|
||||
var/list/tube_dirs //list of directions this tube section can connect to.
|
||||
var/exit_delay = 1
|
||||
@@ -15,6 +14,10 @@
|
||||
var/const/time_to_unwrench = 2 SECONDS
|
||||
max_integrity = 75
|
||||
|
||||
/obj/structure/transit_tube/Initialize(mapload)
|
||||
. = ..()
|
||||
AddElement(/datum/element/climbable)
|
||||
|
||||
/obj/structure/transit_tube/CanAllowThrough(atom/movable/mover, turf/target)
|
||||
. = ..()
|
||||
if(istype(mover) && (mover.pass_flags & PASSGLASS))
|
||||
|
||||
@@ -380,6 +380,57 @@ GLOBAL_LIST_EMPTY(station_turfs)
|
||||
|
||||
return TRUE
|
||||
|
||||
/**
|
||||
* Check whether the specified turf is blocked by something dense inside it with respect to a specific atom.
|
||||
*
|
||||
* Returns truthy value TURF_BLOCKED_TURF_DENSE if the turf is blocked because the turf itself is dense.
|
||||
* Returns truthy value TURF_BLOCKED_CONTENT_DENSE if one of the turf's contents is dense and would block
|
||||
* a source atom's movement.
|
||||
* Returns falsey value TURF_NOT_BLOCKED if the turf is not blocked.
|
||||
*
|
||||
* Arguments:
|
||||
* * exclude_mobs - If TRUE, ignores dense mobs on the turf.
|
||||
* * source_atom - If this is not null, will check whether any contents on the turf can block this atom specifically. Also ignores itself on the turf.
|
||||
* * ignore_atoms - Check will ignore any atoms in this list. Useful to prevent an atom from blocking itself on the turf.
|
||||
* * type_list - are we checking for types of atoms to ignore and not physical atoms
|
||||
*/
|
||||
/turf/proc/is_blocked_turf(exclude_mobs = FALSE, source_atom = null, list/ignore_atoms, type_list = FALSE)
|
||||
if(density)
|
||||
return TRUE
|
||||
|
||||
for(var/atom/movable/movable_content as anything in contents)
|
||||
// We don't want to block ourselves
|
||||
if((movable_content == source_atom))
|
||||
continue
|
||||
// dont consider ignored atoms or their types
|
||||
if(length(ignore_atoms))
|
||||
if(!type_list && (movable_content in ignore_atoms))
|
||||
continue
|
||||
else if(type_list && is_type_in_list(movable_content, ignore_atoms))
|
||||
continue
|
||||
|
||||
// If the thing is dense AND we're including mobs or the thing isn't a mob AND if there's a source atom and
|
||||
// it cannot pass through the thing on the turf, we consider the turf blocked.
|
||||
if(movable_content.density && (!exclude_mobs || !ismob(movable_content)))
|
||||
if(source_atom && movable_content.CanPass(source_atom, get_dir(src, source_atom)))
|
||||
continue
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/**
|
||||
* Checks whether the specified turf is blocked by something dense inside it, but ignores anything with the climbable trait
|
||||
*
|
||||
* Works similar to is_blocked_turf(), but ignores climbables and has less options. Primarily added for jaunting checks
|
||||
*/
|
||||
/turf/proc/is_blocked_turf_ignore_climbable()
|
||||
if(density)
|
||||
return TRUE
|
||||
|
||||
for(var/atom/movable/atom_content as anything in contents)
|
||||
if(atom_content.density && !(atom_content.flags_1 & ON_BORDER_1) && !HAS_TRAIT(atom_content, TRAIT_CLIMBABLE))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
//////////////////////////////
|
||||
//Distance procs
|
||||
//////////////////////////////
|
||||
|
||||
@@ -97,7 +97,6 @@
|
||||
icon_state = "bloodaltar"
|
||||
density = TRUE
|
||||
anchored = FALSE
|
||||
climbable = TRUE
|
||||
pass_flags = LETPASSTHROW
|
||||
can_buckle = FALSE
|
||||
var/sacrifices = 0
|
||||
@@ -116,6 +115,10 @@
|
||||
They normally sacrifice hearts or blood in exchange for these ranks, forcing them to move out of their lair.\n\
|
||||
It can only be used twice per night and it needs to be interacted it to be claimed, making bloodsuckers come back twice a night."
|
||||
|
||||
/obj/structure/bloodsucker/bloodaltar/Initialize(mapload)
|
||||
. = ..()
|
||||
AddElement(/datum/element/climbable)
|
||||
|
||||
/obj/structure/bloodsucker/bloodaltar/bolt()
|
||||
. = ..()
|
||||
anchored = TRUE
|
||||
|
||||
@@ -55,7 +55,7 @@
|
||||
if(locate(/obj/structure/falsewall) in contents)
|
||||
to_chat(user, span_warning("There is a false wall in the way, preventing you from fabricating a clockwork wall on [src]."))
|
||||
return
|
||||
if(is_blocked_turf(src, TRUE))
|
||||
if(is_blocked_turf(TRUE))
|
||||
to_chat(user, span_warning("Something is in the way, preventing you from fabricating a clockwork wall on [src]."))
|
||||
return TRUE
|
||||
var/operation_time = 100
|
||||
|
||||
@@ -113,7 +113,7 @@
|
||||
var/turf/T = get_turf(src)
|
||||
var/list/open_turfs = list()
|
||||
for(var/turf/open/OT in orange(1, T))
|
||||
if(!is_blocked_turf(OT, TRUE))
|
||||
if(!OT.is_blocked_turf(TRUE))
|
||||
open_turfs |= OT
|
||||
if(open_turfs.len)
|
||||
for(var/mob/living/L in T)
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
name = "massive gear"
|
||||
icon_state = "wall_gear"
|
||||
unanchored_icon = "wall_gear"
|
||||
climbable = TRUE
|
||||
max_integrity = 100
|
||||
construction_value = 3
|
||||
desc = "A massive brass gear. You could probably secure or unsecure it with a wrench, or just climb over it."
|
||||
@@ -12,6 +11,10 @@
|
||||
/obj/item/clockwork/alloy_shards/medium = 4, \
|
||||
/obj/item/clockwork/alloy_shards/small = 2) //slightly more debris than the default, totals 26 alloy
|
||||
|
||||
/obj/structure/destructible/clockwork/wall_gear/Initialize(mapload)
|
||||
. = ..()
|
||||
AddElement(/datum/element/climbable)
|
||||
|
||||
/obj/structure/destructible/clockwork/wall_gear/displaced
|
||||
anchored = FALSE
|
||||
|
||||
|
||||
@@ -525,7 +525,7 @@
|
||||
if(QDELETED(src) || !user || !user.is_holding(src) || user.incapacitated() || !actual_selected_rune || !proximity)
|
||||
return
|
||||
var/turf/dest = get_turf(actual_selected_rune)
|
||||
if(is_blocked_turf(dest, TRUE))
|
||||
if(dest.is_blocked_turf(TRUE))
|
||||
to_chat(user, span_warning("The target rune is blocked. You cannot teleport there."))
|
||||
return
|
||||
uses--
|
||||
|
||||
@@ -162,7 +162,7 @@
|
||||
chant(i)
|
||||
var/list/destinations = list()
|
||||
for(var/turf/T in orange(1, owner))
|
||||
if(!is_blocked_turf(T, TRUE))
|
||||
if(!T.is_blocked_turf(TRUE))
|
||||
destinations += T
|
||||
if(!LAZYLEN(destinations))
|
||||
to_chat(owner, span_warning("You need more space to summon your cult!"))
|
||||
|
||||
@@ -426,7 +426,7 @@ structure_check() searches for nearby cultist structures required for the invoca
|
||||
return
|
||||
|
||||
var/turf/target = get_turf(actual_selected_rune)
|
||||
if(is_blocked_turf(target, TRUE))
|
||||
if(target.is_blocked_turf(TRUE))
|
||||
to_chat(user, span_warning("The target rune is blocked. Attempting to teleport to it would be massively unwise."))
|
||||
fail_invoke()
|
||||
return
|
||||
|
||||
@@ -191,7 +191,7 @@
|
||||
|
||||
for (var/turf/possible_drop in contract.dropoff.contents)
|
||||
if (!isspaceturf(possible_drop) && !isclosedturf(possible_drop))
|
||||
if (!is_blocked_turf(possible_drop))
|
||||
if (!possible_drop.is_blocked_turf())
|
||||
possible_drop_loc.Add(possible_drop)
|
||||
|
||||
if (possible_drop_loc.len > 0)
|
||||
|
||||
@@ -180,7 +180,7 @@
|
||||
WARNING("[src] couldnt find a Quartermaster/Storage (aka cargobay) area on the station, and as such it has set the supplypod landingzone to the area it resides in.")
|
||||
landingzone = get_area(src)
|
||||
for(var/turf/open/floor/T in landingzone.get_contained_turfs())//uses default landing zone
|
||||
if(is_blocked_turf(T))
|
||||
if(T.is_blocked_turf())
|
||||
continue
|
||||
LAZYADD(empty_turfs, T)
|
||||
CHECK_TICK
|
||||
@@ -197,7 +197,7 @@
|
||||
if(SO.pack.get_cost() * (0.72*MAX_EMAG_ROCKETS) <= points_to_check) // bulk discount :^)
|
||||
landingzone = GLOB.areas_by_type[pick(GLOB.the_station_areas)] //override default landing zone
|
||||
for(var/turf/open/floor/T in landingzone.get_contained_turfs())
|
||||
if(is_blocked_turf(T))
|
||||
if(T.is_blocked_turf())
|
||||
continue
|
||||
LAZYADD(empty_turfs, T)
|
||||
CHECK_TICK
|
||||
|
||||
@@ -108,7 +108,7 @@
|
||||
for(var/place in shuttle_areas)
|
||||
var/area/shuttle/shuttle_area = place
|
||||
for(var/turf/open/floor/T in shuttle_area)
|
||||
if(is_blocked_turf(T))
|
||||
if(T.is_blocked_turf())
|
||||
continue
|
||||
empty_shuttle_turfs += T
|
||||
if(!empty_shuttle_turfs.len)
|
||||
|
||||
@@ -263,7 +263,7 @@ datum/action/innate/aux_base/install_turret/Activate()
|
||||
|
||||
var/turf/turret_turf = get_turf(remote_eye)
|
||||
|
||||
if(is_blocked_turf(turret_turf))
|
||||
if(turret_turf.is_blocked_turf())
|
||||
to_chat(owner, span_warning("Location is obstructed by something. Please clear the location and try again."))
|
||||
return
|
||||
|
||||
|
||||
@@ -1560,7 +1560,8 @@ GLOBAL_LIST_EMPTY(aide_list)
|
||||
if(get_dist(user, beacon) <= 2) //beacon too close abort
|
||||
to_chat(user, span_warning("You are too close to the beacon to teleport to it!"))
|
||||
return
|
||||
if(is_blocked_turf(get_turf(beacon), TRUE))
|
||||
var/turf/beacon_turf = get_turf(beacon)
|
||||
if(beacon_turf.is_blocked_turf(TRUE))
|
||||
to_chat(user, span_warning("The beacon is blocked by something, preventing teleportation!"))
|
||||
return
|
||||
if(!isturf(user.loc))
|
||||
@@ -1577,7 +1578,7 @@ GLOBAL_LIST_EMPTY(aide_list)
|
||||
if(do_after(user, 4 SECONDS, user) && user && beacon)
|
||||
var/turf/T = get_turf(beacon)
|
||||
var/turf/source = get_turf(user)
|
||||
if(is_blocked_turf(T, TRUE))
|
||||
if(T.is_blocked_turf(TRUE))
|
||||
teleporting = FALSE
|
||||
to_chat(user, span_warning("The beacon is blocked by something, preventing teleportation!"))
|
||||
user.update_mob_action_buttons()
|
||||
@@ -1598,7 +1599,7 @@ GLOBAL_LIST_EMPTY(aide_list)
|
||||
if(beacon)
|
||||
beacon.icon_state = "hierophant_tele_off"
|
||||
return
|
||||
if(is_blocked_turf(T, TRUE))
|
||||
if(T.is_blocked_turf(TRUE))
|
||||
teleporting = FALSE
|
||||
to_chat(user, span_warning("The beacon is blocked by something, preventing teleportation!"))
|
||||
user.update_mob_action_buttons()
|
||||
@@ -1633,7 +1634,7 @@ GLOBAL_LIST_EMPTY(aide_list)
|
||||
|
||||
/obj/item/hierophant_club/proc/teleport_mob(turf/source, mob/M, turf/target, mob/user)
|
||||
var/turf/turf_to_teleport_to = get_step(target, get_dir(source, M)) //get position relative to caster
|
||||
if(!turf_to_teleport_to || is_blocked_turf(turf_to_teleport_to, TRUE))
|
||||
if(!turf_to_teleport_to || turf_to_teleport_to.is_blocked_turf_ignore_climbable())
|
||||
return
|
||||
animate(M, alpha = 0, time = 0.2 SECONDS, easing = EASE_OUT) //fade out
|
||||
sleep(0.1 SECONDS)
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
density = TRUE
|
||||
anchored = TRUE
|
||||
layer = TABLE_LAYER
|
||||
climbable = TRUE
|
||||
pass_flags = LETPASSTHROW
|
||||
resistance_flags = INDESTRUCTIBLE | LAVA_PROOF | FIRE_PROOF | UNACIDABLE | ACID_PROOF
|
||||
|
||||
@@ -22,6 +21,7 @@
|
||||
/obj/structure/world_anvil/Initialize(mapload)
|
||||
. = ..()
|
||||
internal = new /obj/item/gps/internal/world_anvil(src)
|
||||
AddElement(/datum/element/climbable)
|
||||
|
||||
/obj/structure/world_anvil/Destroy()
|
||||
QDEL_NULL(internal)
|
||||
|
||||
@@ -1028,7 +1028,7 @@
|
||||
if(T)
|
||||
T.add_vomit_floor(src, vomit_type, purge_ratio) //toxic barf looks different || call purge when doing detoxicfication to pump more chems out of the stomach.
|
||||
T = get_step(T, dir)
|
||||
if (is_blocked_turf(T))
|
||||
if (T.is_blocked_turf())
|
||||
break
|
||||
return TRUE
|
||||
|
||||
|
||||
@@ -208,7 +208,7 @@ Difficulty: Medium
|
||||
if(get_dist(src, O) >= MINER_DASH_RANGE && turf_dist_to_target <= self_dist_to_target && !islava(O) && !ischasm(O))
|
||||
var/valid = TRUE
|
||||
for(var/turf/T in getline(own_turf, O))
|
||||
if(is_blocked_turf(T, TRUE))
|
||||
if(T.is_blocked_turf(TRUE))
|
||||
valid = FALSE
|
||||
continue
|
||||
if(valid)
|
||||
|
||||
@@ -541,7 +541,7 @@ Difficulty: Very Hard
|
||||
var/turf/T = Stuff
|
||||
if((isspaceturf(T) || isfloorturf(T)) && NewTerrainFloors)
|
||||
var/turf/open/O = T.ChangeTurf(NewTerrainFloors, flags = CHANGETURF_INHERIT_AIR)
|
||||
if(prob(florachance) && NewFlora.len && !is_blocked_turf(O, TRUE))
|
||||
if(prob(florachance) && NewFlora.len && !O.is_blocked_turf(TRUE))
|
||||
var/atom/Picked = pick(NewFlora)
|
||||
new Picked(O)
|
||||
continue
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
var/mob/living/L = parent
|
||||
if(!L.can_interact_with(clicked_turf))
|
||||
return
|
||||
if(is_blocked_turf(clicked_turf))
|
||||
if(clicked_turf.is_blocked_turf())
|
||||
return
|
||||
if(istype(clicked_turf, /turf/open/indestructible/sound/pool))
|
||||
return
|
||||
|
||||
@@ -124,7 +124,7 @@
|
||||
if(get_dist(A,B) != required_distance)
|
||||
return FALSE
|
||||
for(var/turf/T in getline(get_turf(A),get_turf(B)))
|
||||
if(is_blocked_turf(T,TRUE))
|
||||
if(T.is_blocked_turf(TRUE))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
|
||||
@@ -6,7 +6,6 @@
|
||||
density = TRUE
|
||||
anchored = TRUE
|
||||
layer = TABLE_LAYER
|
||||
climbable = TRUE
|
||||
pass_flags = LETPASSTHROW
|
||||
can_buckle = TRUE
|
||||
buckle_lying = 90 //we turn to you!
|
||||
@@ -16,6 +15,7 @@
|
||||
/obj/structure/altar_of_gods/Initialize(mapload)
|
||||
. = ..()
|
||||
reflect_sect_in_icons()
|
||||
AddElement(/datum/element/climbable)
|
||||
AddComponent(/datum/component/religious_tool, ALL, FALSE, CALLBACK(src, PROC_REF(reflect_sect_in_icons)))
|
||||
|
||||
/obj/structure/altar_of_gods/attack_hand(mob/living/user)
|
||||
|
||||
@@ -367,7 +367,7 @@ GLOBAL_LIST_EMPTY(bluespace_slime_crystals)
|
||||
|
||||
/obj/structure/slime_crystal/cerulean/process()
|
||||
for(var/turf/T in range(2,src))
|
||||
if(is_blocked_turf(T) || isspaceturf(T) || T == get_turf(src) || prob(50))
|
||||
if(T.is_blocked_turf() || isspaceturf(T) || T == get_turf(src) || prob(50))
|
||||
continue
|
||||
var/obj/structure/cerulean_slime_crystal/CSC = locate() in range(1,T)
|
||||
if(CSC)
|
||||
|
||||
@@ -91,7 +91,7 @@ GLOBAL_LIST_INIT(blacklisted_cargo_types, typecacheof(list(
|
||||
for(var/place in shuttle_areas)
|
||||
var/area/shuttle/shuttle_area = place
|
||||
for(var/turf/open/floor/T in shuttle_area)
|
||||
if(is_blocked_turf(T))
|
||||
if(T.is_blocked_turf())
|
||||
continue
|
||||
empty_turfs += T
|
||||
|
||||
@@ -227,7 +227,7 @@ GLOBAL_LIST_INIT(blacklisted_cargo_types, typecacheof(list(
|
||||
for(var/place as anything in shuttle_areas)
|
||||
var/area/shuttle/shuttle_area = place
|
||||
for(var/turf/open/floor/shuttle_floor in shuttle_area)
|
||||
if(is_blocked_turf(shuttle_floor))
|
||||
if(shuttle_floor.is_blocked_turf())
|
||||
continue
|
||||
empty_turfs += shuttle_floor
|
||||
|
||||
|
||||
@@ -112,8 +112,8 @@
|
||||
// Pick an exit turf to deposit the jaunter
|
||||
var/turf/found_exit
|
||||
for(var/turf/possible_exit as anything in exit_point_list)
|
||||
// if(possible_exit.is_blocked_turf_ignore_climbable())
|
||||
// continue
|
||||
if(possible_exit.is_blocked_turf_ignore_climbable())
|
||||
continue
|
||||
found_exit = possible_exit
|
||||
break
|
||||
|
||||
@@ -190,8 +190,8 @@
|
||||
SIGNAL_HANDLER
|
||||
|
||||
var/turf/location = get_turf(source)
|
||||
// if(location.is_blocked_turf_ignore_climbable())
|
||||
// return
|
||||
if(location.is_blocked_turf_ignore_climbable())
|
||||
return
|
||||
exit_point_list.Insert(1, location)
|
||||
if(length(exit_point_list) >= 5)
|
||||
exit_point_list.Cut(5)
|
||||
|
||||
@@ -36,8 +36,8 @@
|
||||
return FALSE
|
||||
if(selected.density && (destination_flags & TELEPORT_SPELL_SKIP_DENSE))
|
||||
return FALSE
|
||||
// if(selected.is_blocked_turf(exclude_mobs = TRUE) && (destination_flags & TELEPORT_SPELL_SKIP_BLOCKED))
|
||||
// return FALSE
|
||||
if(selected.is_blocked_turf(exclude_mobs = TRUE) && (destination_flags & TELEPORT_SPELL_SKIP_BLOCKED))
|
||||
return FALSE
|
||||
|
||||
return TRUE
|
||||
|
||||
|
||||
@@ -47,6 +47,7 @@
|
||||
#include "code\__DEFINES\contracts.dm"
|
||||
#include "code\__DEFINES\cooldowns.dm"
|
||||
#include "code\__DEFINES\cult.dm"
|
||||
#include "code\__DEFINES\directional.dm"
|
||||
#include "code\__DEFINES\diseases.dm"
|
||||
#include "code\__DEFINES\DNA.dm"
|
||||
#include "code\__DEFINES\dye_keys.dm"
|
||||
@@ -644,6 +645,7 @@
|
||||
#include "code\datums\diseases\advance\symptoms\youth.dm"
|
||||
#include "code\datums\elements\_element.dm"
|
||||
#include "code\datums\elements\cleaning.dm"
|
||||
#include "code\datums\elements\climbable.dm"
|
||||
#include "code\datums\elements\connect_loc.dm"
|
||||
#include "code\datums\elements\content_barfer.dm"
|
||||
#include "code\datums\elements\earhealing.dm"
|
||||
|
||||
@@ -31,9 +31,11 @@
|
||||
playsound(src, 'sound/items/jaws_pry.ogg', 100)
|
||||
|
||||
/obj/machinery/door/airlock/proc/dir_to_cardinal(dir)
|
||||
if((dir & NORTH) && (!is_blocked_turf(get_step(src, NORTH), TRUE)))
|
||||
var/turf/north_turf = get_step(src, NORTH)
|
||||
if((dir & NORTH) && (!north_turf.is_blocked_turf(TRUE)))
|
||||
return NORTH
|
||||
if((dir & SOUTH) && (!is_blocked_turf(get_step(src, SOUTH), TRUE)))
|
||||
var/turf/south_turf = get_step(src, SOUTH)
|
||||
if((dir & SOUTH) && (!south_turf.is_blocked_turf(TRUE)))
|
||||
return SOUTH
|
||||
if(dir & EAST)
|
||||
return EAST
|
||||
@@ -43,4 +45,4 @@
|
||||
/obj/machinery/door/airlock/Moved()
|
||||
if(brace)
|
||||
brace.remove()
|
||||
return ..()
|
||||
return ..()
|
||||
|
||||
Reference in New Issue
Block a user