Frame stacking fix and unit test addition. (#56287)

* Reverts #56205

* Allow things without density to bypass checks

* The rest of the owl

* The rest of the owl

* Doc and tweak

* More feex

* RCD machine frame unit test

* I suck

* AAAAA

* Bad at unit tests

* Revert unit tests (for including in another PR)

* Fix windoor_assembly return logic

* Comment /mob/living/proc/PushAM logic

* Windoor assembley logic tweak

* Fix frame stacking

* Unit test

* Better wording from macros?
This commit is contained in:
Timberpoes
2021-01-22 21:18:05 +08:00
committed by GitHub
parent 294a2518fb
commit 1989497576
17 changed files with 242 additions and 194 deletions
+10 -3
View File
@@ -69,6 +69,9 @@
///Highest-intensity light affecting us, which determines our visibility.
var/affecting_dynamic_lumi = 0
/// Whether this atom should have its dir automatically changed when it moves. Setting this to FALSE allows for things such as directional windows to retain dir on moving without snowflake code all of the place.
var/set_dir_on_move = TRUE
/atom/movable/Initialize(mapload)
. = ..()
@@ -343,7 +346,9 @@
if(!direct)
direct = get_dir(src, newloc)
setDir(direct)
if(set_dir_on_move)
setDir(direct)
if(!loc.Exit(src, newloc))
return
@@ -443,7 +448,7 @@
moving_diagonally = SECOND_DIAG_STEP
. = step(src, SOUTH)
if(moving_diagonally == SECOND_DIAG_STEP)
if(!.)
if(!. && set_dir_on_move)
setDir(first_step_dir)
else if (!inertia_moving)
inertia_next_move = world.time + inertia_move_delay
@@ -476,7 +481,9 @@
set_glide_size(glide_size_override)
last_move = direct
setDir(direct)
if(set_dir_on_move)
setDir(direct)
if(. && has_buckled_mobs() && !handle_buckled_mob_movement(loc, direct, glide_size_override)) //movement failed due to buckled mob(s)
return FALSE
+27 -13
View File
@@ -495,15 +495,33 @@
LAZYCLEARLIST(component_parts)
return ..()
/**
* Spawns a frame where this machine is. If the machine was not disassmbled, the
* frame is spawned damaged. If the frame couldn't exist on this turf, it's smashed
* down to metal sheets.
*
* Arguments:
* * disassembled - If FALSE, the machine was destroyed instead of disassembled and the frame spawns at reduced integrity.
*/
/obj/machinery/proc/spawn_frame(disassembled)
var/obj/structure/frame/machine/M = new /obj/structure/frame/machine(loc)
. = M
M.set_anchored(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
if(machine_turf.is_blocked_turf(TRUE, source_atom = new_frame))
new_frame.deconstruct(disassembled)
return
new_frame.icon_state = "box_1"
. = new_frame
new_frame.set_anchored(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)
SHOULD_CALL_PARENT(TRUE)
@@ -564,10 +582,7 @@
/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/turf/ground = get_turf(src)
var/list/excluded_objects = list(type)
if(anchorables)
excluded_objects += anchorables
if(!anchored && ground.is_blocked_turf(exclude_mobs = TRUE, excluded_objects = excluded_objects))
if(!anchored && ground.is_blocked_turf(exclude_mobs = TRUE, source_atom = src))
to_chat(user, "<span class='notice'>You fail to secure [src].</span>")
return CANT_UNFASTEN
var/can_be_unfasten = can_be_unfasten_wrench(user)
@@ -579,7 +594,7 @@
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/unfasten_wrench_check, prev_anchored, user)))
if(!anchored && ground.is_blocked_turf(exclude_mobs = TRUE, excluded_objects = excluded_objects))//i know what you tryin to sneak in
if(!anchored && ground.is_blocked_turf(exclude_mobs = TRUE, source_atom = src))//i know what you tryin to sneak in
to_chat(user, "<span class='notice'>You fail to secure [src].</span>")
return CANT_UNFASTEN
to_chat(user, "<span class='notice'>You [anchored ? "un" : ""]secure [src].</span>")
@@ -733,4 +748,3 @@
var/alertstr = "<span class='userdanger'>Network Alert: Hacking attempt detected[get_area(src)?" in [get_area_name(src, TRUE)]":". Unable to pinpoint location"].</span>"
for(var/mob/living/silicon/ai/AI in GLOB.player_list)
to_chat(AI, alertstr)
-1
View File
@@ -9,7 +9,6 @@
power_channel = AREA_USAGE_EQUIP
circuit = /obj/item/circuitboard/machine/cell_charger
pass_flags = PASSTABLE
anchorables = list(/obj/structure/table)
var/obj/item/stock_parts/cell/charging = null
var/charge_rate = 250
+12 -14
View File
@@ -17,6 +17,7 @@
CanAtmosPass = ATMOS_PASS_PROC
interaction_flags_machine = INTERACT_MACHINE_WIRES_IF_OPEN | INTERACT_MACHINE_ALLOW_SILICON | INTERACT_MACHINE_OPEN_SILICON | INTERACT_MACHINE_REQUIRES_SILICON | INTERACT_MACHINE_OPEN
network_id = NETWORK_DOOR_AIRLOCKS
set_dir_on_move = FALSE
var/obj/item/electronics/airlock/electronics = null
var/reinf = 0
var/shards = 2
@@ -110,20 +111,18 @@
. = ..()
if(.)
return
if(get_dir(loc, target) == dir) //Make sure looking at appropriate border
return
if(istype(mover, /obj/structure/window))
var/obj/structure/window/W = mover
if(!valid_window_location(loc, W.ini_dir))
return FALSE
else if(istype(mover, /obj/structure/windoor_assembly))
var/obj/structure/windoor_assembly/W = mover
if(!valid_window_location(loc, W.ini_dir))
return FALSE
else if(istype(mover, /obj/machinery/door/window) && !valid_window_location(loc, mover.dir))
if(get_dir(loc, target) == dir)
return FALSE
else
return TRUE
if(istype(mover, /obj/structure/window))
var/obj/structure/window/moved_window = mover
return valid_window_location(loc, moved_window.dir, is_fulltile = moved_window.fulltile)
if(istype(mover, /obj/structure/windoor_assembly) || istype(mover, /obj/machinery/door/window))
return valid_window_location(loc, mover.dir, is_fulltile = FALSE)
return TRUE
/obj/machinery/door/window/CanAtmosPass(turf/T)
if(get_dir(loc, T) == dir)
@@ -261,7 +260,6 @@
WA.set_anchored(TRUE)
WA.state= "02"
WA.setDir(dir)
WA.ini_dir = dir
WA.update_icon()
WA.created_name = name
+54 -60
View File
@@ -233,53 +233,46 @@
if(get_amount() < 1 && !is_cyborg)
qdel(src)
return
var/datum/stack_recipe/R = locate(params["ref"])
if(!is_valid_recipe(R, recipes)) //href exploit protection
var/datum/stack_recipe/recipe = locate(params["ref"])
if(!is_valid_recipe(recipe, recipes)) //href exploit protection
return
var/multiplier = text2num(params["multiplier"])
if(!multiplier || (multiplier <= 0)) //href exploit protection
return
if(!building_checks(R, multiplier))
if(!building_checks(recipe, multiplier))
return
if(R.time)
if(recipe.time)
var/adjusted_time = 0
usr.visible_message("<span class='notice'>[usr] starts building \a [R.title].</span>", "<span class='notice'>You start building \a [R.title]...</span>")
if(HAS_TRAIT(usr, R.trait_booster))
adjusted_time = (R.time * R.trait_modifier)
usr.visible_message("<span class='notice'>[usr] starts building \a [recipe.title].</span>", "<span class='notice'>You start building \a [recipe.title]...</span>")
if(HAS_TRAIT(usr, recipe.trait_booster))
adjusted_time = (recipe.time * recipe.trait_modifier)
else
adjusted_time = R.time
adjusted_time = recipe.time
if(!do_after(usr, adjusted_time, target = usr))
return
if(!building_checks(R, multiplier))
if(!building_checks(recipe, multiplier))
return
var/obj/O
if(R.max_res_amount > 1) //Is it a stack?
O = new R.result_type(usr.drop_location(), R.res_amount * multiplier)
else if(ispath(R.result_type, /turf))
if(recipe.max_res_amount > 1) //Is it a stack?
O = new recipe.result_type(usr.drop_location(), recipe.res_amount * multiplier)
else if(ispath(recipe.result_type, /turf))
var/turf/T = usr.drop_location()
if(!isturf(T))
return
T.PlaceOnTop(R.result_type, flags = CHANGETURF_INHERIT_AIR)
T.PlaceOnTop(recipe.result_type, flags = CHANGETURF_INHERIT_AIR)
else
O = new R.result_type(usr.drop_location())
O = new recipe.result_type(usr.drop_location())
if(O)
O.setDir(usr.dir)
use(R.req_amount * multiplier)
use(recipe.req_amount * multiplier)
if(R.applies_mats && LAZYLEN(mats_per_unit))
if(recipe.applies_mats && LAZYLEN(mats_per_unit))
if(isstack(O))
var/obj/item/stack/crafted_stack = O
crafted_stack.set_mats_per_unit(mats_per_unit, R.req_amount / R.res_amount)
crafted_stack.set_mats_per_unit(mats_per_unit, recipe.req_amount / recipe.res_amount)
else
O.set_custom_materials(mats_per_unit, R.req_amount / R.res_amount)
if(istype(O, /obj/structure/windoor_assembly))
var/obj/structure/windoor_assembly/W = O
W.ini_dir = W.dir
else if(istype(O, /obj/structure/window))
var/obj/structure/window/W = O
W.ini_dir = W.dir
O.set_custom_materials(mats_per_unit, recipe.req_amount / recipe.res_amount)
if(QDELETED(O))
return //It's a stack and has already been merged
@@ -305,50 +298,55 @@
return TRUE
return ..()
/obj/item/stack/proc/building_checks(datum/stack_recipe/R, multiplier)
if (get_amount() < R.req_amount*multiplier)
if (R.req_amount*multiplier>1)
to_chat(usr, "<span class='warning'>You haven't got enough [src] to build \the [R.req_amount*multiplier] [R.title]\s!</span>")
/obj/item/stack/proc/building_checks(datum/stack_recipe/recipe, multiplier)
if (get_amount() < recipe.req_amount*multiplier)
if (recipe.req_amount*multiplier>1)
to_chat(usr, "<span class='warning'>You haven't got enough [src] to build \the [recipe.req_amount*multiplier] [recipe.title]\s!</span>")
else
to_chat(usr, "<span class='warning'>You haven't got enough [src] to build \the [R.title]!</span>")
to_chat(usr, "<span class='warning'>You haven't got enough [src] to build \the [recipe.title]!</span>")
return FALSE
var/turf/T = get_turf(usr)
var/turf/dest_turf = get_turf(usr)
var/obj/D = R.result_type
if(R.window_checks && !valid_window_location(T, initial(D.dir) == FULLTILE_WINDOW_DIR ? FULLTILE_WINDOW_DIR : usr.dir))
to_chat(usr, "<span class='warning'>The [R.title] won't fit here!</span>")
return FALSE
if(R.one_per_turf && (locate(R.result_type) in T))
to_chat(usr, "<span class='warning'>There is another [R.title] here!</span>")
return FALSE
if(R.on_floor)
if(!isfloorturf(T))
to_chat(usr, "<span class='warning'>\The [R.title] must be constructed on the floor!</span>")
// If we're making a window, we have some special snowflake window checks to do.
if(ispath(recipe.result_type, /obj/structure/window))
var/obj/structure/window/result_path = recipe.result_type
if(!valid_window_location(dest_turf, usr.dir, is_fulltile = initial(result_path.fulltile)))
to_chat(usr, "<span class='warning'>The [recipe.title] won't fit here!</span>")
return FALSE
for(var/obj/AM in T)
if(istype(AM,/obj/structure/grille))
if(recipe.one_per_turf && (locate(recipe.result_type) in dest_turf))
to_chat(usr, "<span class='warning'>There is another [recipe.title] here!</span>")
return FALSE
if(recipe.on_floor)
if(!isfloorturf(dest_turf))
to_chat(usr, "<span class='warning'>\The [recipe.title] must be constructed on the floor!</span>")
return FALSE
for(var/obj/object in dest_turf)
if(istype(object, /obj/structure/grille))
continue
if(istype(AM,/obj/structure/table))
if(istype(object, /obj/structure/table))
continue
if(istype(AM,/obj/structure/window))
var/obj/structure/window/W = AM
if(!W.fulltile)
if(istype(object, /obj/structure/window))
var/obj/structure/window/window_structure = object
if(!window_structure.fulltile)
continue
if(AM.density)
to_chat(usr, "<span class='warning'>Theres a [AM.name] here. You cant make a [R.title] here!</span>")
if(object.density)
to_chat(usr, "<span class='warning'>There is \a [object.name] here. You cant make \a [recipe.title] here!</span>")
return FALSE
if(R.placement_checks)
switch(R.placement_checks)
if(recipe.placement_checks)
switch(recipe.placement_checks)
if(STACK_CHECK_CARDINALS)
var/turf/step
for(var/direction in GLOB.cardinals)
step = get_step(T, direction)
if(locate(R.result_type) in step)
to_chat(usr, "<span class='warning'>\The [R.title] must not be built directly adjacent to another!</span>")
step = get_step(dest_turf, direction)
if(locate(recipe.result_type) in step)
to_chat(usr, "<span class='warning'>\The [recipe.title] must not be built directly adjacent to another!</span>")
return FALSE
if(STACK_CHECK_ADJACENT)
if(locate(R.result_type) in range(1, T))
to_chat(usr, "<span class='warning'>\The [R.title] must be constructed at least one tile away from others of its type!</span>")
if(locate(recipe.result_type) in range(1, dest_turf))
to_chat(usr, "<span class='warning'>\The [recipe.title] must be constructed at least one tile away from others of its type!</span>")
return FALSE
return TRUE
@@ -520,15 +518,12 @@
var/time = 0
var/one_per_turf = FALSE
var/on_floor = FALSE
var/window_checks = FALSE
var/placement_checks = FALSE
var/applies_mats = FALSE
var/trait_booster = null
var/trait_modifier = 1
/datum/stack_recipe/New(title, result_type, req_amount = 1, res_amount = 1, max_res_amount = 1,time = 0, one_per_turf = FALSE, on_floor = FALSE, window_checks = FALSE, placement_checks = FALSE, applies_mats = FALSE, trait_booster = null, trait_modifier = 1)
src.title = title
src.result_type = result_type
src.req_amount = req_amount
@@ -537,7 +532,6 @@
src.time = time
src.one_per_turf = one_per_turf
src.on_floor = on_floor
src.window_checks = window_checks
src.placement_checks = placement_checks
src.applies_mats = applies_mats
src.trait_booster = trait_booster
-5
View File
@@ -46,9 +46,6 @@
/// broadcasted to as long as the other guys network is on the same branch or above.
var/network_id = null
///List of object types that the item can be anchored on top of, such as a table
var/list/anchorables = null
/obj/vv_edit_var(vname, vval)
if(vname == NAMEOF(src, obj_flags))
if ((obj_flags & DANGEROUS_POSSESSION) && !(vval & DANGEROUS_POSSESSION))
@@ -64,8 +61,6 @@
stack_trace("Invalid type [armor.type] found in .armor during /obj Initialize()")
if(obj_integrity == null)
obj_integrity = max_integrity
if(anchorables)
anchorables = string_list(anchorables)
. = ..() //Do this after, else mat datums is mad.
+5 -4
View File
@@ -70,11 +70,13 @@
if(!isturf(loc))
return FALSE
var/turf/T = loc
var/window_dir = the_rcd.window_size == RCD_WINDOW_FULLTILE ? FULLTILE_WINDOW_DIR : user.dir
if(!valid_window_location(T, window_dir))
if(!ispath(the_rcd.window_type, /obj/structure/window))
CRASH("Invalid window path type in RCD: [the_rcd.window_type]")
var/obj/structure/window/window_path = the_rcd.window_type
if(!valid_window_location(T, user.dir, is_fulltile = initial(window_path.fulltile)))
return FALSE
to_chat(user, "<span class='notice'>You construct the window.</span>")
var/obj/structure/window/WD = new the_rcd.window_type(T, window_dir)
var/obj/structure/window/WD = new the_rcd.window_type(T, user.dir)
WD.set_anchored(TRUE)
return TRUE
return FALSE
@@ -190,7 +192,6 @@
else
WD = new/obj/structure/window/fulltile(drop_location()) //normal window
WD.setDir(dir_to_set)
WD.ini_dir = dir_to_set
WD.set_anchored(FALSE)
WD.state = 0
ST.use(2)
+1 -8
View File
@@ -6,8 +6,6 @@
density = TRUE
anchored = TRUE
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"
@@ -18,10 +16,6 @@
. = ..()
AddComponent(/datum/component/simple_rotation,ROTATION_ALTCLICK | ROTATION_CLOCKWISE | ROTATION_COUNTERCLOCKWISE | ROTATION_VERBS ,null,CALLBACK(src, .proc/can_be_rotated),CALLBACK(src,.proc/after_rotation))
/obj/structure/railing/Initialize()
. = ..()
ini_dir = dir
/obj/structure/railing/attackby(obj/item/I, mob/living/user, params)
..()
add_fingerprint(user)
@@ -94,7 +88,7 @@
var/target_dir = turn(dir, rotation_type == ROTATION_CLOCKWISE ? -90 : 90)
if(!valid_window_location(loc, target_dir)) //Expanded to include rails, as well!
if(!valid_window_location(loc, target_dir, is_fulltile = FALSE)) //Expanded to include rails, as well!
to_chat(user, "<span class='warning'>[src] cannot be rotated in that direction!</span>")
return FALSE
return TRUE
@@ -104,5 +98,4 @@
return TRUE
/obj/structure/railing/proc/after_rotation(mob/user,rotation_type)
ini_dir = dir
add_fingerprint(user)
@@ -18,8 +18,8 @@
anchored = FALSE
density = FALSE
dir = NORTH
set_dir_on_move = FALSE
var/ini_dir
var/obj/item/electronics/airlock/electronics = null
var/created_name = null
@@ -33,7 +33,6 @@
..()
if(set_dir)
setDir(set_dir)
ini_dir = dir
air_update_turf(TRUE, TRUE)
/obj/structure/windoor_assembly/Destroy()
@@ -44,7 +43,6 @@
/obj/structure/windoor_assembly/Move()
var/turf/T = loc
. = ..()
setDir(ini_dir)
move_update_air(T)
/obj/structure/windoor_assembly/update_icon_state()
@@ -52,18 +50,16 @@
/obj/structure/windoor_assembly/CanAllowThrough(atom/movable/mover, turf/target)
. = ..()
if(get_dir(loc, target) == dir) //Make sure looking at appropriate border
if(get_dir(loc, target) == dir)
return
if(istype(mover, /obj/structure/window))
var/obj/structure/window/W = mover
if(!valid_window_location(loc, W.ini_dir))
return FALSE
else if(istype(mover, /obj/structure/windoor_assembly))
var/obj/structure/windoor_assembly/W = mover
if(!valid_window_location(loc, W.ini_dir))
return FALSE
else if(istype(mover, /obj/machinery/door/window) && !valid_window_location(loc, mover.dir))
return FALSE
var/obj/structure/window/moved_window = mover
return valid_window_location(loc, moved_window.dir, is_fulltile = moved_window.fulltile)
if(istype(mover, /obj/structure/windoor_assembly) || istype(mover, /obj/machinery/door/window))
return valid_window_location(loc, mover.dir, is_fulltile = FALSE)
/obj/structure/windoor_assembly/CanAtmosPass(turf/T)
if(get_dir(loc, T) == dir)
@@ -321,13 +317,12 @@
return FALSE
var/target_dir = turn(dir, rotation_type == ROTATION_CLOCKWISE ? -90 : 90)
if(!valid_window_location(loc, target_dir))
if(!valid_window_location(loc, target_dir, is_fulltile = FALSE))
to_chat(user, "<span class='warning'>[src] cannot be rotated in that direction!</span>")
return FALSE
return TRUE
/obj/structure/windoor_assembly/proc/after_rotation(mob/user)
ini_dir = dir
update_icon()
//Flips the windoor assembly, determines whather the door opens to the left or the right
+18 -39
View File
@@ -14,7 +14,7 @@
CanAtmosPass = ATMOS_PASS_PROC
rad_insulation = RAD_VERY_LIGHT_INSULATION
pass_flags_self = PASSGLASS
var/ini_dir = null
set_dir_on_move = FALSE
var/state = WINDOW_OUT_OF_FRAME
var/reinf = FALSE
var/heat_resistance = 800
@@ -32,7 +32,6 @@
flags_ricochet = RICOCHET_HARD
receive_ricochet_chance_mod = 0.5
/obj/structure/window/examine(mob/user)
. = ..()
if(reinf)
@@ -57,7 +56,6 @@
if(reinf && anchored)
state = RWINDOW_SECURE
ini_dir = dir
air_update_turf(TRUE, TRUE)
if(fulltile)
@@ -99,33 +97,25 @@
if(current_size >= STAGE_FIVE)
deconstruct(FALSE)
/obj/structure/window/setDir(direct)
if(!fulltile)
..()
else
..(FULLTILE_WINDOW_DIR)
/obj/structure/window/CanAllowThrough(atom/movable/mover, turf/target)
. = ..()
if(.)
return
if(dir == FULLTILE_WINDOW_DIR)
return FALSE //full tile window, you can't move into it!
var/attempted_dir = get_dir(loc, target)
if(attempted_dir == dir)
return
if(istype(mover, /obj/structure/window))
var/obj/structure/window/W = mover
if(!valid_window_location(loc, W.ini_dir))
return FALSE
else if(istype(mover, /obj/structure/windoor_assembly))
var/obj/structure/windoor_assembly/W = mover
if(!valid_window_location(loc, W.ini_dir))
return FALSE
else if(istype(mover, /obj/machinery/door/window) && !valid_window_location(loc, mover.dir))
if(fulltile)
return FALSE
else if(attempted_dir != dir)
return TRUE
if(get_dir(loc, target) == dir)
return FALSE
if(istype(mover, /obj/structure/window))
var/obj/structure/window/moved_window = mover
return valid_window_location(loc, moved_window.dir, is_fulltile = moved_window.fulltile)
if(istype(mover, /obj/structure/windoor_assembly) || istype(mover, /obj/machinery/door/window))
return valid_window_location(loc, mover.dir, is_fulltile = FALSE)
return TRUE
/obj/structure/window/CheckExit(atom/movable/O, turf/target)
if(istype(O) && (O.pass_flags & PASSGLASS))
@@ -285,14 +275,13 @@
var/target_dir = turn(dir, rotation_type == ROTATION_CLOCKWISE ? -90 : 90)
if(!valid_window_location(loc, target_dir))
if(!valid_window_location(loc, target_dir, is_fulltile = fulltile))
to_chat(user, "<span class='warning'>[src] cannot be rotated in that direction!</span>")
return FALSE
return TRUE
/obj/structure/window/proc/after_rotation(mob/user,rotation_type)
air_update_turf(TRUE, FALSE)
ini_dir = dir
add_fingerprint(user)
/obj/structure/window/proc/on_painted(is_dark_color)
@@ -313,14 +302,13 @@
/obj/structure/window/Move()
var/turf/T = loc
. = ..()
setDir(ini_dir)
if(anchored)
move_update_air(T)
/obj/structure/window/CanAtmosPass(turf/T)
if(!anchored || !density)
return TRUE
return !(FULLTILE_WINDOW_DIR == dir || dir == get_dir(loc, T))
return !(fulltile || dir == get_dir(loc, T))
//This proc is used to update the icons of nearby windows.
/obj/structure/window/proc/update_nearby_icons()
@@ -359,7 +347,7 @@
/obj/structure/window/CanAStarPass(ID, to_dir)
if(!density)
return TRUE
if((dir == FULLTILE_WINDOW_DIR) || (dir == to_dir))
if(fulltile || (dir == to_dir))
return FALSE
return TRUE
@@ -612,7 +600,6 @@
icon = 'icons/obj/smooth_structures/window.dmi'
icon_state = "window-0"
base_icon_state = "window"
dir = FULLTILE_WINDOW_DIR
max_integrity = 50
fulltile = TRUE
flags_1 = PREVENT_CLICK_UNDER_1
@@ -628,7 +615,6 @@
icon = 'icons/obj/smooth_structures/plasma_window.dmi'
icon_state = "plasma_window-0"
base_icon_state = "plasma_window"
dir = FULLTILE_WINDOW_DIR
max_integrity = 300
fulltile = TRUE
flags_1 = PREVENT_CLICK_UNDER_1
@@ -644,7 +630,6 @@
icon = 'icons/obj/smooth_structures/rplasma_window.dmi'
icon_state = "rplasma_window-0"
base_icon_state = "rplasma_window"
dir = FULLTILE_WINDOW_DIR
state = RWINDOW_SECURE
max_integrity = 1000
fulltile = TRUE
@@ -662,7 +647,6 @@
icon = 'icons/obj/smooth_structures/reinforced_window.dmi'
icon_state = "reinforced_window-0"
base_icon_state = "reinforced_window"
dir = FULLTILE_WINDOW_DIR
max_integrity = 150
fulltile = TRUE
flags_1 = PREVENT_CLICK_UNDER_1
@@ -680,7 +664,6 @@
icon = 'icons/obj/smooth_structures/tinted_window.dmi'
icon_state = "tinted_window-0"
base_icon_state = "tinted_window"
dir = FULLTILE_WINDOW_DIR
fulltile = TRUE
flags_1 = PREVENT_CLICK_UNDER_1
smoothing_flags = SMOOTH_BITMASK
@@ -701,7 +684,6 @@
icon = 'icons/obj/smooth_structures/shuttle_window.dmi'
icon_state = "shuttle_window-0"
base_icon_state = "shuttle_window"
dir = FULLTILE_WINDOW_DIR
max_integrity = 150
wtype = "shuttle"
fulltile = TRUE
@@ -732,7 +714,6 @@
icon = 'icons/obj/smooth_structures/plastitanium_window.dmi'
icon_state = "plastitanium_window-0"
base_icon_state = "plastitanium_window"
dir = FULLTILE_WINDOW_DIR
max_integrity = 1200
wtype = "shuttle"
fulltile = TRUE
@@ -758,7 +739,6 @@
icon = 'icons/obj/smooth_structures/paperframes.dmi'
icon_state = "paperframes-0"
base_icon_state = "paperframes"
dir = FULLTILE_WINDOW_DIR
opacity = TRUE
max_integrity = 15
fulltile = TRUE
@@ -852,7 +832,6 @@
canSmoothWith = list(SMOOTH_GROUP_WINDOW_FULLTILE_BRONZE)
fulltile = TRUE
flags_1 = PREVENT_CLICK_UNDER_1
dir = FULLTILE_WINDOW_DIR
max_integrity = 50
glass_amount = 2
+15 -7
View File
@@ -166,17 +166,25 @@ GLOBAL_LIST_EMPTY(station_turfs)
/turf/proc/multiz_turf_new(turf/T, dir)
SEND_SIGNAL(src, COMSIG_TURF_MULTIZ_NEW, T, dir)
///returns if the turf has something dense inside it. if exclude_mobs is true, skips dense mobs like fat yoshi. if exclude_object is true, it will exclude the excluded_object you sent through
/turf/proc/is_blocked_turf(exclude_mobs, list/excluded_objects = list())
/**
* Check whether the specified turf is blocked by something dense inside it.
*
* Returns TRUE if the turf is blocked, FALSE otherwise.
*
* Arguments:
* * exclude_mobs - If TRUE, ignores dense mobs on the turf.
* * source_atom - If you're checking if the turf an atom is on is blocked, this will let you exclude the atom from this check so it doesn't block itself with its own density.
*/
/turf/proc/is_blocked_turf(exclude_mobs, source_atom)
if(density)
return TRUE
for(var/i in contents)
var/atom/movable/thing = i
var/excuded = FALSE
for(var/excluded in excluded_objects)
if(istype(thing, excluded))
excuded = TRUE
if(!excuded && thing.density && (!exclude_mobs || !ismob(thing)))
if(thing == source_atom)
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(thing.density && (!exclude_mobs || !ismob(thing)) && (source_atom && !thing.CanPass(source_atom, src)))
return TRUE
return FALSE