From 727eb2d26171de2225abfd11eb15f3d21bf474be Mon Sep 17 00:00:00 2001 From: Fluffy <65877598+FluffyGhoster@users.noreply.github.com> Date: Tue, 24 Dec 2024 17:05:30 +0100 Subject: [PATCH] Flags and adjacency work (#20259) 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. --- code/_onclick/adjacent.dm | 124 ++++++++---------- code/game/atom/_atom.dm | 1 - code/game/atoms_movable.dm | 2 +- .../objects/items/weapons/storage/internal.dm | 2 +- code/game/objects/structures.dm | 1 + .../structures/barricades/_barricade.dm | 1 - .../structures/crates_lockers/closets.dm | 2 +- code/game/objects/structures/grille.dm | 1 + code/game/objects/structures/morgue.dm | 2 +- code/game/objects/structures/plasticflaps.dm | 5 +- code/game/objects/structures/railing.dm | 1 - code/game/objects/structures/urban.dm | 8 +- code/game/objects/structures/window.dm | 1 + code/game/turfs/simulated/walls.dm | 1 + code/game/turfs/unsimulated/walls.dm | 1 + .../items/furniture/dueling_area.dm | 6 +- code/modules/holodeck/HolodeckObjects.dm | 6 +- code/modules/makeshift/makeshift_reagents.dm | 7 +- code/modules/mob/mob_defines.dm | 1 + code/modules/tables/tables.dm | 7 +- .../fluffyghost-flagandadjacencywork.yml | 61 +++++++++ 21 files changed, 147 insertions(+), 94 deletions(-) create mode 100644 html/changelogs/fluffyghost-flagandadjacencywork.yml diff --git a/code/_onclick/adjacent.dm b/code/_onclick/adjacent.dm index 583c879cff0..f6bbef0c825 100644 --- a/code/_onclick/adjacent.dm +++ b/code/_onclick/adjacent.dm @@ -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") @@ -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): @@ -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 diff --git a/code/game/atom/_atom.dm b/code/game/atom/_atom.dm index 347602fe68c..c30006cc799 100644 --- a/code/game/atom/_atom.dm +++ b/code/game/atom/_atom.dm @@ -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. diff --git a/code/game/atoms_movable.dm b/code/game/atoms_movable.dm index bc5772d50ed..3705a27006b 100644 --- a/code/game/atoms_movable.dm +++ b/code/game/atoms_movable.dm @@ -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 diff --git a/code/game/objects/items/weapons/storage/internal.dm b/code/game/objects/items/weapons/storage/internal.dm index dddb7b4133f..e44a364e8b7 100644 --- a/code/game/objects/items/weapons/storage/internal.dm +++ b/code/game/objects/items/weapons/storage/internal.dm @@ -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) diff --git a/code/game/objects/structures.dm b/code/game/objects/structures.dm index e7b90e88b8a..862f0d0f58c 100644 --- a/code/game/objects/structures.dm +++ b/code/game/objects/structures.dm @@ -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 diff --git a/code/game/objects/structures/barricades/_barricade.dm b/code/game/objects/structures/barricades/_barricade.dm index 83681ab171e..4797e03880b 100644 --- a/code/game/objects/structures/barricades/_barricade.dm +++ b/code/game/objects/structures/barricades/_barricade.dm @@ -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. diff --git a/code/game/objects/structures/crates_lockers/closets.dm b/code/game/objects/structures/crates_lockers/closets.dm index ac3aa42a52f..6655094a9e6 100644 --- a/code/game/objects/structures/crates_lockers/closets.dm +++ b/code/game/objects/structures/crates_lockers/closets.dm @@ -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 diff --git a/code/game/objects/structures/grille.dm b/code/game/objects/structures/grille.dm index 2edea7ce4d7..d75d63acd8c 100644 --- a/code/game/objects/structures/grille.dm +++ b/code/game/objects/structures/grille.dm @@ -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 diff --git a/code/game/objects/structures/morgue.dm b/code/game/objects/structures/morgue.dm index 1e8e4ff2faf..1afe4d597c0 100644 --- a/code/game/objects/structures/morgue.dm +++ b/code/game/objects/structures/morgue.dm @@ -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 diff --git a/code/game/objects/structures/plasticflaps.dm b/code/game/objects/structures/plasticflaps.dm index 3e74ae96d10..7fff6db9a8f 100644 --- a/code/game/objects/structures/plasticflaps.dm +++ b/code/game/objects/structures/plasticflaps.dm @@ -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 diff --git a/code/game/objects/structures/railing.dm b/code/game/objects/structures/railing.dm index cc1bc0c3b2f..4ef6fd8a8aa 100644 --- a/code/game/objects/structures/railing.dm +++ b/code/game/objects/structures/railing.dm @@ -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 diff --git a/code/game/objects/structures/urban.dm b/code/game/objects/structures/urban.dm index 6c5052694bb..8eb21e4efc3 100644 --- a/code/game/objects/structures/urban.dm +++ b/code/game/objects/structures/urban.dm @@ -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) @@ -463,8 +463,8 @@ 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" @@ -472,7 +472,7 @@ ABSTRACT_TYPE(/obj/structure/stairs/urban/road_ramp) icon = 'icons/obj/structure/urban/road_edges.dmi' icon_state = "guard" density = TRUE - throwpass = TRUE + pass_flags_self = PASSSTRUCTURE | LETPASSTHROW climbable = TRUE anchored = TRUE diff --git a/code/game/objects/structures/window.dm b/code/game/objects/structures/window.dm index 5386f9818ab..5fa8c9c74b5 100644 --- a/code/game/objects/structures/window.dm +++ b/code/game/objects/structures/window.dm @@ -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 diff --git a/code/game/turfs/simulated/walls.dm b/code/game/turfs/simulated/walls.dm index e75897eb7a3..d3b25c98e26 100644 --- a/code/game/turfs/simulated/walls.dm +++ b/code/game/turfs/simulated/walls.dm @@ -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( diff --git a/code/game/turfs/unsimulated/walls.dm b/code/game/turfs/unsimulated/walls.dm index 35d38a51e05..1b071c02357 100644 --- a/code/game/turfs/unsimulated/walls.dm +++ b/code/game/turfs/unsimulated/walls.dm @@ -5,6 +5,7 @@ opacity = TRUE density = TRUE blocks_air = TRUE + pass_flags_self = PASSCLOSEDTURF /turf/unsimulated/wall/fakeglass name = "window" diff --git a/code/modules/battlemonsters/items/furniture/dueling_area.dm b/code/modules/battlemonsters/items/furniture/dueling_area.dm index fca3ebd95d0..f62fd4f1da5 100644 --- a/code/modules/battlemonsters/items/furniture/dueling_area.dm +++ b/code/modules/battlemonsters/items/furniture/dueling_area.dm @@ -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 diff --git a/code/modules/holodeck/HolodeckObjects.dm b/code/modules/holodeck/HolodeckObjects.dm index 6bd540d0216..32ff7e52fdd 100644 --- a/code/modules/holodeck/HolodeckObjects.dm +++ b/code/modules/holodeck/HolodeckObjects.dm @@ -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) diff --git a/code/modules/makeshift/makeshift_reagents.dm b/code/modules/makeshift/makeshift_reagents.dm index 9338845e787..2b3a456badd 100644 --- a/code/modules/makeshift/makeshift_reagents.dm +++ b/code/modules/makeshift/makeshift_reagents.dm @@ -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 diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index 7c49b1fbf25..098cb6b5c36 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -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 diff --git a/code/modules/tables/tables.dm b/code/modules/tables/tables.dm index b9b48a3e4b7..5b0f622dac2 100644 --- a/code/modules/tables/tables.dm +++ b/code/modules/tables/tables.dm @@ -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 diff --git a/html/changelogs/fluffyghost-flagandadjacencywork.yml b/html/changelogs/fluffyghost-flagandadjacencywork.yml new file mode 100644 index 00000000000..c8bfcbcae97 --- /dev/null +++ b/html/changelogs/fluffyghost-flagandadjacencywork.yml @@ -0,0 +1,61 @@ +################################ +# Example Changelog File +# +# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb. +# +# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.) +# When it is, any changes listed below will disappear. +# +# Valid Prefixes: +# bugfix +# - (fixes bugs) +# wip +# - (work in progress) +# qol +# - (quality of life) +# soundadd +# - (adds a sound) +# sounddel +# - (removes a sound) +# rscadd +# - (adds a feature) +# rscdel +# - (removes a feature) +# imageadd +# - (adds an image or sprite) +# imagedel +# - (removes an image or sprite) +# spellcheck +# - (fixes spelling or grammar) +# experiment +# - (experimental change) +# balance +# - (balance changes) +# code_imp +# - (misc internal code change) +# refactor +# - (refactors code) +# config +# - (makes a change to the config files) +# admin +# - (makes changes to administrator tools) +# server +# - (miscellaneous changes to server) +################################# + +# Your name. +author: FluffyGhost + +# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again. +delete-after: True + +# Any changes you've made. See valid prefix list above. +# INDENT WITH TWO SPACES. NOT TABS. SPACES. +# SCREW THIS UP AND IT WON'T WORK. +# Also, this gets changed to [] after reading. Just remove the brackets when you add new shit. +# Please surround your changes in double quotes ("). It works without them, but if you use certain characters it screws up compiling. The quotes will not show up in the changelog. +changes: + - code_imp: "Added a bunch of flags for passflags on things that were previously missing them." + - refactor: "Removed snowflake passthrow var, it's a passflag now." + - refactor: "Updated ClickCross and Adjacency code." + - rscadd: "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."