Skip to content

Commit

Permalink
Flags and adjacency work (#20259)
Browse files Browse the repository at this point in the history
Added a bunch of flags for passflags on things that were previously
missing them.
Removed snowflake passthrow var, it's a passflag now.
Updated ClickCross and Adjacency code.
It's now possible to interact with things that are adjacent but
otherwise have a machine (or other appropriate items) blocking them, eg.
think of an APC on the wall with a machine in front of it.
  • Loading branch information
FluffyGhoster authored Dec 24, 2024
1 parent 67360a9 commit 727eb2d
Show file tree
Hide file tree
Showing 21 changed files with 147 additions and 94 deletions.
124 changes: 57 additions & 67 deletions code/_onclick/adjacent.dm
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@
Note that in all cases the neighbor is handled simply; this is usually the user's mob, in which case it is up to you
to check that the mob is not inside of something
*/
/atom/proc/Adjacent(var/atom/neighbor) // basic inheritance, unused
return 0
/atom/proc/Adjacent(atom/neighbor, atom/target, atom/movable/mover) // basic inheritance, unused
return

// Not a sane use of the function and (for now) indicative of an error elsewhere
/area/Adjacent(var/atom/neighbor)
/area/Adjacent(atom/neighbor, atom/target, atom/movable/mover)
CRASH("Call to /area/Adjacent(), unimplemented proc")


Expand All @@ -25,37 +25,41 @@
* If you are diagonally adjacent, ensure you can pass through at least one of the mutually adjacent square.
* Passing through in this case ignores anything with the throwpass flag, such as tables, racks, and morgue trays.
*/
/turf/Adjacent(var/atom/neighbor, var/atom/target = null)
/turf/Adjacent(atom/neighbor, atom/target, atom/movable/mover)
var/turf/T0 = get_turf(neighbor)
if(T0 == src)
return 1
if(!T0 || T0.z != z)
return 0
if(get_dist(src,T0) > 1)
return 0

if(T0 == src) //same turf
return TRUE

if(get_dist(src, T0) > 1 || z != T0.z) //too far
return FALSE

// Non diagonal case
if(T0.x == x || T0.y == y)
// Check for border blockages
return T0.ClickCross(get_dir(T0,src), border_only = 1) && src.ClickCross(get_dir(src,T0), border_only = 1, target_atom = target)
return T0.ClickCross(get_dir(T0, src), TRUE, target, mover) && ClickCross(get_dir(src, T0), TRUE, target, mover)

// Not orthagonal
var/in_dir = get_dir(neighbor,src) // eg. northwest (1+8)
var/d1 = in_dir&(in_dir-1) // eg west (1+8)&(8) = 8
var/d2 = in_dir - d1 // eg north (1+8) - 8 = 1
// Diagonal case
var/in_dir = get_dir(T0,src) // eg. northwest (1+8) = 9 (00001001)
var/d1 = in_dir&3 // eg. north (1+8)&3 (0000 0011) = 1 (0000 0001)
var/d2 = in_dir&12 // eg. west (1+8)&12 (0000 1100) = 8 (0000 1000)

for(var/d in list(d1,d2))
if(!T0.ClickCross(d, border_only = 1))
if(!T0.ClickCross(d, TRUE, target, mover))
continue // could not leave T0 in that direction

var/turf/T1 = get_step(T0,d)
if(!T1 || T1.density || !T1.ClickCross(get_dir(T1,T0) | get_dir(T1,src), border_only = 0))
if(!T1 || T1.density)
continue
if(!T1.ClickCross(get_dir(T1, src), FALSE, target, mover) || !T1.ClickCross(get_dir(T1, T0), FALSE, target, mover))
continue // couldn't enter or couldn't leave T1

if(!src.ClickCross(get_dir(src,T1), border_only = 1, target_atom = target))
if(!ClickCross(get_dir(src, T1), TRUE, target, mover))
continue // could not enter src

return 1 // we don't care about our own density
return 0
return TRUE // we don't care about our own density

return FALSE

/*
Quick adjacency (to turf):
Expand All @@ -75,73 +79,59 @@ Quick adjacency (to turf):
/*
Adjacency (to anything else):
* Must be on a turf
* In the case of a multiple-tile object, all valid locations are checked for adjacency.
Note: Multiple-tile objects are created when the bound_width and bound_height are creater than the tile size.
This is not used in stock /tg/station currently.
*/
/atom/movable/Adjacent(var/atom/neighbor)
if(neighbor == loc) return 1
if(!isturf(loc)) return 0
for(var/turf/T in locs)
if(isnull(T)) continue
if(T.Adjacent(neighbor,src)) return 1
return 0
/atom/movable/Adjacent(atom/neighbor, atom/target, atom/movable/mover)
if(neighbor == loc)
return TRUE
if(neighbor?.loc == src)
return TRUE
var/turf/T = loc
if(!istype(T))
return FALSE
if(T.Adjacent(neighbor,target = neighbor, mover = src))
return TRUE
return FALSE

// This is necessary for storage items not on your person.
/obj/item/Adjacent(var/atom/neighbor, var/recurse = 1)
if(neighbor == loc) return 1
if(istype(loc,/obj/item))
/obj/item/Adjacent(atom/neighbor, atom/target, atom/movable/mover, recurse = 1)
if(neighbor == loc)
return TRUE
if(neighbor?.loc == src)
return TRUE
if(isitem(loc))
if(recurse > 0)
return loc.Adjacent(neighbor,recurse - 1)
return 0
return loc.Adjacent(neighbor, target, mover, recurse - 1)
return FALSE
return ..()
/*
Special case: This allows you to reach a door when it is visally on top of,
but technically behind, a fire door
You could try to rewrite this to be faster, but I'm not sure anything would be.
This can be safely removed if border firedoors are ever moved to be on top of doors
so they can be interacted with without opening the door.
*/
/*/obj/machinery/door/Adjacent(var/atom/neighbor)
var/obj/machinery/door/firedoor/border_only/BOD = locate() in loc
if(BOD)
BOD.throwpass = 1 // allow click to pass
. = ..()
BOD.throwpass = 0
return .
return ..()*/


/*
This checks if you there is uninterrupted airspace between that turf and this one.
This is defined as any dense ATOM_FLAG_CHECKS_BORDER object, or any dense object without throwpass.
The border_only flag allows you to not objects (for source and destination squares)
*/
/turf/proc/ClickCross(var/target_dir, var/border_only, var/target_atom = null)
/turf/proc/ClickCross(target_dir, border_only, target, atom/movable/mover)
for(var/obj/O in src)
if(!O.density || O == target_atom || O.throwpass)
continue // throwpass is used for anything you can click through
if((mover && O.CanPass(mover, target_dir)) || (!mover && !O.density))
continue

//If there's a dense object on the turf, only allow the click to pass if you can throw items over it or it has a special flag.
if(O == target || O == mover || (O.pass_flags_self & (LETPASSTHROW|LETPASSCLICKS)))
continue

if(O.atom_flags & ATOM_FLAG_CHECKS_BORDER) // windows have throwpass but are on border, check them first
if(O.dir & target_dir || O.dir & (O.dir - 1)) // full tile windows are just diagonals mechanically
if(istype(target_atom, /obj/structure/window))
var/obj/structure/window/W = target_atom

/*** START AURORA SNOWFLAKE CODE ***/
if(istype(target, /obj/structure/window))
var/obj/structure/window/W = target
if(!W.is_fulltile()) //exception for breaking full tile windows on top of single pane windows
return FALSE
if(O.atom_flags & ATOM_FLAG_ALWAYS_ALLOW_PICKUP)
return TRUE
return FALSE
/*** END AURORA SNOWFLAKE CODE ***/

else if(!border_only) // dense, not on border, cannot pass over
return FALSE
return TRUE
/*
Aside: throwpass does not do what I thought it did originally, and is only used for checking whether or not
a thrown object should stop after already successfully entering a square. Currently the throw code involved
only seems to affect hitting mobs, because the checks performed against objects are already performed when
entering or leaving the square. Since throwpass isn't used on mobs, but only on objects, it is effectively
useless. Throwpass may later need to be removed and replaced with a passcheck (bitfield on movable atom passflags).

Since I don't want to complicate the click code rework by messing with unrelated systems it won't be changed here.
*/
return TRUE
1 change: 0 additions & 1 deletion code/game/atom/_atom.dm
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@
var/blood_color
var/last_bumped = 0
var/pass_flags = 0
var/throwpass = 0
var/germ_level = GERM_LEVEL_AMBIENT // The higher the germ level, the more germ on the atom.
var/simulated = 1 // Filter for actions. Used by lighting overlays.
var/fluorescent // Shows up under a UV light.
Expand Down
2 changes: 1 addition & 1 deletion code/game/atoms_movable.dm
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@
continue
throw_impact(A, speed)
if(isobj(A))
if(A.density && !A.throwpass && !A.CanPass(src, target))
if(A.density && !A.CanPass(src, target))
src.throw_impact(A,speed)

// Prevents robots dropping their modules
Expand Down
2 changes: 1 addition & 1 deletion code/game/objects/items/weapons/storage/internal.dm
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@
src.close(M)
return 1

/obj/item/storage/internal/Adjacent(var/atom/neighbor)
/obj/item/storage/internal/Adjacent(atom/neighbor, atom/target, atom/movable/mover)
var/obj/item/real_master_item = special_master_item_handling ? get_master_item() : master_item
return real_master_item.Adjacent(neighbor)

Expand Down
1 change: 1 addition & 0 deletions code/game/objects/structures.dm
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
w_class = WEIGHT_CLASS_GIGANTIC
layer = STRUCTURE_LAYER
blocks_emissive = EMISSIVE_BLOCK_GENERIC
pass_flags_self = PASSSTRUCTURE

var/material_alteration = MATERIAL_ALTERATION_ALL // Overrides for material shit. Set them manually if you don't want colors etc. See wood chairs/office chairs.
var/climbable
Expand Down
1 change: 0 additions & 1 deletion code/game/objects/structures/barricades/_barricade.dm
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
climbable = TRUE
anchored = TRUE
density = TRUE
throwpass = TRUE //You can throw objects over this, despite its density.
atom_flags = ATOM_FLAG_CHECKS_BORDER

var/stack_type //The type of stack the barricade dropped when disassembled if any.
Expand Down
2 changes: 1 addition & 1 deletion code/game/objects/structures/crates_lockers/closets.dm
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
density = TRUE
build_amt = 2
slowdown = 5
pass_flags_self = PASSTRACE
pass_flags_self = PASSSTRUCTURE | LETPASSCLICKS | PASSTRACE

var/icon_door = null
/// Override to have open overlay use icon different to its base's
Expand Down
1 change: 1 addition & 0 deletions code/game/objects/structures/grille.dm
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
icon_state = "grille"
density = TRUE
anchored = TRUE
pass_flags_self = PASSGRILLE
obj_flags = OBJ_FLAG_CONDUCTABLE | OBJ_FLAG_MOVES_UNSUPPORTED
explosion_resistance = 1
layer = BELOW_WINDOW_LAYER
Expand Down
2 changes: 1 addition & 1 deletion code/game/objects/structures/morgue.dm
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@
icon_state = "morguet"
density = TRUE
anchored = TRUE
throwpass = TRUE
pass_flags_self = PASSSTRUCTURE | LETPASSTHROW
layer = BELOW_OBJ_LAYER
obj_flags = OBJ_FLAG_MOVES_UNSUPPORTED
var/obj/structure/morgue/connected = null
Expand Down
5 changes: 3 additions & 2 deletions code/game/objects/structures/plasticflaps.dm
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
desc = "Completely impassable - or are they?"
icon = 'icons/obj/structure/plasticflaps.dmi'
icon_state = "plasticflaps_preview"
density = 0
anchored = 1
density = FALSE
anchored = TRUE
pass_flags_self = PASSSTRUCTURE | PASSFLAPS
layer = UNDERDOOR
explosion_resistance = 5
build_amt = 4
Expand Down
1 change: 0 additions & 1 deletion code/game/objects/structures/railing.dm
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
icon = 'icons/obj/structure/blocker/railing_basic.dmi'
icon_state = "railing0-1"
density = TRUE
throwpass = TRUE
climbable = TRUE
layer = OBJ_LAYER
anchored = FALSE
Expand Down
8 changes: 4 additions & 4 deletions code/game/objects/structures/urban.dm
Original file line number Diff line number Diff line change
Expand Up @@ -431,9 +431,9 @@ ABSTRACT_TYPE(/obj/structure/stairs/urban/road_ramp)
icon = 'icons/obj/structure/urban/blockers.dmi'
icon_state = "rod_railing"
density = TRUE
throwpass = TRUE
climbable = TRUE
anchored = TRUE
pass_flags_self = PASSSTRUCTURE | LETPASSTHROW
climbable = TRUE

/obj/structure/rod_railing/CanPass(atom/movable/mover, turf/target, height=0, air_group=0)
if(mover?.movement_type & PHASING)
Expand Down Expand Up @@ -463,16 +463,16 @@ ABSTRACT_TYPE(/obj/structure/stairs/urban/road_ramp)
icon = 'icons/obj/structure/urban/blockers.dmi'
icon_state = "dam1"
density = TRUE
throwpass = TRUE
anchored = TRUE
pass_flags_self = PASSSTRUCTURE | LETPASSTHROW

/obj/structure/road_barrier
name = "roadway barrier"
desc = "A set of expendable plates meant to deflect the impact of vehicles, lest they intend to go into more dangerous areas off the road."
icon = 'icons/obj/structure/urban/road_edges.dmi'
icon_state = "guard"
density = TRUE
throwpass = TRUE
pass_flags_self = PASSSTRUCTURE | LETPASSTHROW
climbable = TRUE
anchored = TRUE

Expand Down
1 change: 1 addition & 0 deletions code/game/objects/structures/window.dm
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
icon_state = "window"
alpha = 196
density = TRUE
pass_flags_self = PASSWINDOW
w_class = WEIGHT_CLASS_NORMAL
layer = SIDE_WINDOW_LAYER
anchored = TRUE
Expand Down
1 change: 1 addition & 0 deletions code/game/turfs/simulated/walls.dm
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
opacity = TRUE
density = TRUE
blocks_air = TRUE
pass_flags_self = PASSCLOSEDTURF
thermal_conductivity = WALL_HEAT_TRANSFER_COEFFICIENT
heat_capacity = 312500 //a little over 5 cm thick , 312500 for 1 m by 2.5 m by 0.25 m plasteel wall
canSmoothWith = list(
Expand Down
1 change: 1 addition & 0 deletions code/game/turfs/unsimulated/walls.dm
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
opacity = TRUE
density = TRUE
blocks_air = TRUE
pass_flags_self = PASSCLOSEDTURF

/turf/unsimulated/wall/fakeglass
name = "window"
Expand Down
6 changes: 3 additions & 3 deletions code/modules/battlemonsters/items/furniture/dueling_area.dm
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
/obj/structure/dueling_table
name = "dueling table"
icon = 'icons/obj/battle_monsters/furniture.dmi'
anchored = 1
density = 1
anchored = TRUE
density = TRUE
climbable = TRUE
throwpass = 1
pass_flags_self = PASSSTRUCTURE | LETPASSTHROW

/obj/structure/dueling_table/no_collide
density = 0
Expand Down
6 changes: 3 additions & 3 deletions code/modules/holodeck/HolodeckObjects.dm
Original file line number Diff line number Diff line change
Expand Up @@ -331,9 +331,9 @@
desc = "Boom, Shakalaka!"
icon = 'icons/obj/basketball.dmi'
icon_state = "hoop"
anchored = 1
density = 1
throwpass = 1
anchored = TRUE
density = TRUE
pass_flags_self = PASSSTRUCTURE | LETPASSTHROW

/obj/structure/holohoop/attackby(obj/item/attacking_item, mob/user)
if (istype(attacking_item, /obj/item/grab) && get_dist(src,user)<2)
Expand Down
7 changes: 3 additions & 4 deletions code/modules/makeshift/makeshift_reagents.dm
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@
icon = 'icons/obj/makeshift_workstation.dmi'
icon_state = "workstation"
desc = "It's a makeshift workstation for grinding, chopping, and heating."
density = 1

anchored = 1
throwpass = 1
density = TRUE
anchored = TRUE
pass_flags_self = PASSSTRUCTURE | LETPASSTHROW

var/obj/item/device/analyzer/analyzer
var/transfer_out = 0
Expand Down
1 change: 1 addition & 0 deletions code/modules/mob/mob_defines.dm
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
movable_flags = MOVABLE_FLAG_PROXMOVE
sight = DEFAULT_SIGHT
blocks_emissive = EMISSIVE_BLOCK_GENERIC
pass_flags_self = PASSMOB
var/datum/mind/mind
var/static/next_mob_id = 0

Expand Down
7 changes: 3 additions & 4 deletions code/modules/tables/tables.dm
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,13 @@
icon = 'icons/obj/structure/tables/table.dmi'
icon_state = "frame"
desc = "It's a table, for putting things on. Or standing on, if you really want to."
density = 1
anchored = 1
density = TRUE
anchored = TRUE
pass_flags_self = PASSTABLE | LETPASSTHROW
climbable = TRUE
layer = TABLE_LAYER
throwpass = 1
breakable = TRUE
build_amt = 1
pass_flags_self = PASSTABLE | LETPASSTHROW

//Preset shit
var/table_mat
Expand Down
Loading

0 comments on commit 727eb2d

Please sign in to comment.