mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-28 07:38:05 +01:00
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:
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user