mirror of
https://github.com/Bubberstation/Bubberstation.git
synced 2026-08-31 09:08:30 +01:00
Add CI map linter for window and electrified grille spawners (#91090)
## About The Pull Request Remake of: - #79867 This adds a new map linter that checks that there are no walls spawning inside of windows and vice versa. This also checks to make sure there are no grilles spawning twice due to a mapper using the electrified grille spawner with windows. I had to modify the python files to handle new linter rules for an `ignore` section that has been included in the README. There were about two dozen mapping issues where these lints fail that have now been fixed. ## Why It's Good For The Game Better mapping and consistent mapping. ## Changelog 🆑 qol: Add CI map linter for window and electrified grille spawners map: Fix many duplicate windows, walls, and grilles spawning together or inside each other on a bunch of maps. /🆑 --------- Co-authored-by: Jeremiah <42397676+jlsnow301@users.noreply.github.com>
This commit is contained in:
@@ -286,7 +286,6 @@
|
||||
/area/ruin/space/has_grav/allamericandiner)
|
||||
"ob" = (
|
||||
/obj/effect/spawner/structure/window,
|
||||
/obj/structure/grille,
|
||||
/turf/open/floor/plating,
|
||||
/area/ruin/space/has_grav/allamericandiner)
|
||||
"og" = (
|
||||
|
||||
@@ -455,7 +455,6 @@
|
||||
/area/ruin/space/has_grav/dangerous_research/maint)
|
||||
"gl" = (
|
||||
/obj/effect/spawner/structure/window/reinforced/plasma,
|
||||
/obj/effect/spawner/structure/window/reinforced/plasma,
|
||||
/obj/machinery/atmospherics/pipe/layer_manifold/scrubbers/visible,
|
||||
/turf/open/floor/plating,
|
||||
/area/ruin/space/has_grav/dangerous_research/maint)
|
||||
|
||||
@@ -114,10 +114,6 @@
|
||||
/obj/machinery/light/dim/directional/east,
|
||||
/turf/open/floor/wood,
|
||||
/area/ruin/space/has_grav/film_studio/stage)
|
||||
"cx" = (
|
||||
/obj/effect/spawner/structure/window/reinforced,
|
||||
/turf/closed/wall,
|
||||
/area/ruin/space/has_grav/film_studio/solars)
|
||||
"cC" = (
|
||||
/obj/machinery/door/window/right/directional/west,
|
||||
/turf/open/floor/pod/light,
|
||||
@@ -5250,7 +5246,7 @@ dd
|
||||
dd
|
||||
BK
|
||||
BK
|
||||
cx
|
||||
BK
|
||||
fu
|
||||
uc
|
||||
Ei
|
||||
|
||||
@@ -1691,10 +1691,6 @@
|
||||
},
|
||||
/turf/open/floor/iron/white,
|
||||
/area/ruin/space/ancientstation/delta/rnd)
|
||||
"hF" = (
|
||||
/obj/effect/spawner/structure/window/reinforced,
|
||||
/turf/closed/wall,
|
||||
/area/ruin/space/ancientstation/delta/hall)
|
||||
"hI" = (
|
||||
/obj/effect/decal/cleanable/dirt,
|
||||
/obj/effect/decal/cleanable/dirt,
|
||||
@@ -13881,7 +13877,7 @@ bE
|
||||
Po
|
||||
bE
|
||||
bE
|
||||
hF
|
||||
LK
|
||||
LK
|
||||
bE
|
||||
bE
|
||||
|
||||
@@ -10,10 +10,6 @@
|
||||
/obj/structure/girder/reinforced,
|
||||
/turf/open/misc/asteroid/airless,
|
||||
/area/ruin/space/prison_shuttle)
|
||||
"d" = (
|
||||
/obj/effect/spawner/structure/window/reinforced/shuttle,
|
||||
/turf/closed/mineral/random/stationside/asteroid,
|
||||
/area/ruin/space/prison_shuttle)
|
||||
"e" = (
|
||||
/obj/structure/table/reinforced,
|
||||
/turf/open/floor/carpet/red/airless,
|
||||
@@ -261,7 +257,7 @@ F
|
||||
E
|
||||
Y
|
||||
Y
|
||||
d
|
||||
Y
|
||||
E
|
||||
j
|
||||
q
|
||||
@@ -280,7 +276,7 @@ a
|
||||
E
|
||||
Y
|
||||
Y
|
||||
d
|
||||
Y
|
||||
K
|
||||
m
|
||||
r
|
||||
|
||||
@@ -4839,7 +4839,7 @@
|
||||
"rx" = (
|
||||
/obj/machinery/door/firedoor,
|
||||
/obj/structure/window/reinforced/fulltile/ice,
|
||||
/obj/effect/spawner/structure/electrified_grille,
|
||||
/obj/structure/cable,
|
||||
/turf/open/floor/plating,
|
||||
/area/awaymission/snowdin/post/cavern2)
|
||||
"ry" = (
|
||||
@@ -5549,7 +5549,7 @@
|
||||
"uO" = (
|
||||
/obj/machinery/door/firedoor,
|
||||
/obj/structure/window/reinforced/fulltile/ice,
|
||||
/obj/effect/spawner/structure/electrified_grille,
|
||||
/obj/structure/cable,
|
||||
/turf/open/floor/plating,
|
||||
/area/awaymission/snowdin/post/cavern1)
|
||||
"uQ" = (
|
||||
@@ -6703,7 +6703,7 @@
|
||||
"zR" = (
|
||||
/obj/machinery/door/firedoor,
|
||||
/obj/structure/window/reinforced/fulltile/ice,
|
||||
/obj/effect/spawner/structure/electrified_grille,
|
||||
/obj/structure/cable,
|
||||
/turf/open/floor/plating,
|
||||
/area/awaymission/snowdin/post/mining_dock)
|
||||
"zS" = (
|
||||
|
||||
@@ -6450,10 +6450,6 @@
|
||||
/obj/machinery/light/cold/directional/north,
|
||||
/turf/open/floor/iron,
|
||||
/area/station/security/prison/rec)
|
||||
"cuw" = (
|
||||
/obj/effect/spawner/structure/window/reinforced,
|
||||
/turf/closed/wall,
|
||||
/area/station/command/corporate_showroom)
|
||||
"cuZ" = (
|
||||
/obj/structure/cable,
|
||||
/obj/machinery/atmospherics/pipe/smart/manifold4w/supply/hidden/layer4,
|
||||
@@ -12306,10 +12302,6 @@
|
||||
/obj/structure/cable,
|
||||
/turf/open/floor/iron,
|
||||
/area/station/security)
|
||||
"euz" = (
|
||||
/obj/effect/spawner/structure/window/reinforced,
|
||||
/turf/closed/wall,
|
||||
/area/station/hallway/primary/central/aft)
|
||||
"euO" = (
|
||||
/obj/effect/decal/cleanable/dirt,
|
||||
/obj/effect/turf_decal/stripes/white/line{
|
||||
@@ -96591,7 +96583,7 @@ trB
|
||||
saz
|
||||
lcD
|
||||
gCl
|
||||
euz
|
||||
tYX
|
||||
dDB
|
||||
dDB
|
||||
dDB
|
||||
@@ -97058,7 +97050,7 @@ jdJ
|
||||
xMk
|
||||
jYQ
|
||||
hcc
|
||||
cuw
|
||||
xGJ
|
||||
bBN
|
||||
jwi
|
||||
qtd
|
||||
@@ -98086,7 +98078,7 @@ hoN
|
||||
cKV
|
||||
dHL
|
||||
giU
|
||||
cuw
|
||||
xGJ
|
||||
mID
|
||||
jwi
|
||||
jwi
|
||||
|
||||
@@ -38471,17 +38471,6 @@
|
||||
},
|
||||
/turf/open/floor/iron/dark/smooth_large,
|
||||
/area/station/ai_monitored/turret_protected/ai_upload_foyer)
|
||||
"lyK" = (
|
||||
/obj/effect/spawner/structure/window/reinforced,
|
||||
/obj/machinery/door/poddoor/shutters/preopen{
|
||||
id = "aicorewindow";
|
||||
name = "AI Core Shutters"
|
||||
},
|
||||
/obj/structure/railing/corner/end{
|
||||
dir = 4
|
||||
},
|
||||
/turf/open/floor/plating,
|
||||
/area/station/ai_monitored/turret_protected/ai)
|
||||
"lyP" = (
|
||||
/obj/structure/railing/corner,
|
||||
/obj/structure/cable,
|
||||
@@ -63167,10 +63156,6 @@
|
||||
dir = 8
|
||||
},
|
||||
/area/station/science/ordnance/storage)
|
||||
"sUp" = (
|
||||
/obj/effect/spawner/structure/window,
|
||||
/turf/closed/wall,
|
||||
/area/station/maintenance/starboard/fore)
|
||||
"sUu" = (
|
||||
/obj/effect/turf_decal/weather/dirt{
|
||||
dir = 1
|
||||
@@ -116291,7 +116276,7 @@ dTL
|
||||
dCm
|
||||
dCm
|
||||
dCm
|
||||
sUp
|
||||
voV
|
||||
rnp
|
||||
oUO
|
||||
toM
|
||||
@@ -207525,7 +207510,7 @@ ibI
|
||||
kNf
|
||||
kNf
|
||||
mfi
|
||||
lyK
|
||||
mfi
|
||||
kFi
|
||||
qSf
|
||||
mfi
|
||||
|
||||
@@ -16242,7 +16242,7 @@
|
||||
/area/station/maintenance/port/fore)
|
||||
"eAg" = (
|
||||
/obj/effect/spawner/structure/window/reinforced/tinted,
|
||||
/turf/closed/wall,
|
||||
/turf/open/floor/plating,
|
||||
/area/station/security/prison/toilet)
|
||||
"eAh" = (
|
||||
/obj/machinery/power/smes,
|
||||
|
||||
@@ -1114,10 +1114,6 @@
|
||||
/obj/item/paper/guides/jobs/security/labor_camp,
|
||||
/turf/open/floor/iron,
|
||||
/area/station/security/brig)
|
||||
"gW" = (
|
||||
/obj/effect/spawner/structure/window/reinforced,
|
||||
/turf/closed/wall/r_wall,
|
||||
/area/station/engineering/gravity_generator)
|
||||
"hm" = (
|
||||
/obj/machinery/airalarm/directional/west,
|
||||
/obj/effect/mapping_helpers/airalarm/unlocked,
|
||||
@@ -7945,7 +7941,7 @@ aa
|
||||
aa
|
||||
aa
|
||||
ak
|
||||
gW
|
||||
ak
|
||||
Lb
|
||||
aX
|
||||
Qi
|
||||
|
||||
@@ -56,11 +56,6 @@
|
||||
/obj/item/ctf_flag/green,
|
||||
/turf/open/floor/circuit/green/anim,
|
||||
/area/centcom/ctf)
|
||||
"dq" = (
|
||||
/obj/effect/spawner/structure/window/reinforced/shuttle/indestructible,
|
||||
/obj/effect/spawner/structure/window/reinforced/shuttle/indestructible,
|
||||
/turf/open/floor/plating,
|
||||
/area/centcom/ctf)
|
||||
"ds" = (
|
||||
/obj/effect/turf_decal/tile/red{
|
||||
dir = 8
|
||||
@@ -3062,7 +3057,7 @@ hc
|
||||
fU
|
||||
cK
|
||||
cK
|
||||
dq
|
||||
cK
|
||||
cK
|
||||
cK
|
||||
cK
|
||||
|
||||
@@ -9,10 +9,6 @@
|
||||
/obj/effect/landmark/mafia,
|
||||
/turf/open/floor/plating/abductor,
|
||||
/area/centcom/mafia)
|
||||
"f" = (
|
||||
/obj/effect/spawner/structure/window/reinforced/plasma/plastitanium,
|
||||
/turf/closed/indestructible/alien,
|
||||
/area/centcom/mafia)
|
||||
"g" = (
|
||||
/obj/mafia_game_board,
|
||||
/obj/effect/mapping_helpers/broken_floor,
|
||||
@@ -573,7 +569,7 @@ q
|
||||
b
|
||||
b
|
||||
r
|
||||
f
|
||||
b
|
||||
q
|
||||
b
|
||||
b
|
||||
|
||||
@@ -46,10 +46,6 @@
|
||||
},
|
||||
/turf/open/floor/iron/dark,
|
||||
/area/shuttle/escape)
|
||||
"aR" = (
|
||||
/obj/effect/spawner/structure/window/reinforced,
|
||||
/turf/closed/wall,
|
||||
/area/shuttle/escape)
|
||||
"bb" = (
|
||||
/obj/machinery/power/apc/auto_name/directional/east,
|
||||
/obj/structure/cable,
|
||||
@@ -449,10 +445,6 @@
|
||||
},
|
||||
/turf/open/floor/iron/dark,
|
||||
/area/shuttle/escape)
|
||||
"ib" = (
|
||||
/obj/effect/spawner/structure/window/reinforced,
|
||||
/turf/closed/mineral,
|
||||
/area/shuttle/escape)
|
||||
"ig" = (
|
||||
/obj/machinery/light/small/directional/west,
|
||||
/obj/effect/turf_decal/tile/red/half/contrasted,
|
||||
@@ -4594,8 +4586,8 @@ JG
|
||||
qA
|
||||
zE
|
||||
Ho
|
||||
ib
|
||||
ib
|
||||
Ho
|
||||
Ho
|
||||
Ho
|
||||
Ho
|
||||
nr
|
||||
@@ -5480,7 +5472,7 @@ JG
|
||||
(22,1,1) = {"
|
||||
zE
|
||||
zE
|
||||
aR
|
||||
zE
|
||||
LK
|
||||
LK
|
||||
LK
|
||||
|
||||
@@ -122,6 +122,19 @@ Similar to [banned_neighbors](#banned_neighbors), you can specify a regular expr
|
||||
allow: { pattern: '^[A-Z].*$' }
|
||||
```
|
||||
|
||||
### `ignore`
|
||||
If you want to exclude certain objects and subtypes from `banned_neighbors`, you can specify objects in `ignore` that will get skipped from triggering `banned_neighbors`.
|
||||
|
||||
```yml
|
||||
/turf/wall:
|
||||
banned_neighbors:
|
||||
- /obj/structure
|
||||
ignore:
|
||||
- /obj/structure/sign
|
||||
```
|
||||
|
||||
This lint stops structures from being put inside solid walls but we make an exception to ignore any signs and all their subtypes like `/obj/structure/sign/poster`.
|
||||
|
||||
### `help`
|
||||
If you want a custom message to go with your lint, you can specify "help" in the root.
|
||||
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
/obj/effect/spawner/structure/electrified_grille:
|
||||
banned_neighbors:
|
||||
- /obj/effect/spawner/structure/window
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
/obj/effect/spawner/structure/window:
|
||||
banned_neighbors:
|
||||
/turf/closed:
|
||||
STRUCTURE:
|
||||
pattern: ^/obj/structure/(?!.*/directional).*$
|
||||
STRUCTURE_SPAWNER:
|
||||
pattern: ^/obj/effect/spawner/structure/(?!.*/hollow)(?!.*/directional).*$
|
||||
ignore:
|
||||
- /obj/structure/cable
|
||||
- /obj/structure/transit_tube
|
||||
- /obj/structure/disposalpipe
|
||||
- /obj/structure/flora
|
||||
- /obj/structure/sign
|
||||
- /obj/structure/barricade
|
||||
- /obj/structure/curtain
|
||||
- /obj/effect/spawner/structure/electrified_grille
|
||||
- /obj/structure/railing
|
||||
- /obj/structure/lattice
|
||||
- /obj/structure/fans
|
||||
- /obj/structure/spacevine
|
||||
- /obj/structure/girder
|
||||
@@ -45,6 +45,7 @@ class AtomNeighbor:
|
||||
identical: bool = False
|
||||
typepath: Optional[TypepathExtra] = None
|
||||
pattern: Optional[re.Pattern] = None
|
||||
ignore: list[TypepathExtra] = []
|
||||
|
||||
def __init__(self, typepath, data = {}):
|
||||
if typepath.upper() != typepath:
|
||||
@@ -62,6 +63,11 @@ class AtomNeighbor:
|
||||
if "pattern" in data:
|
||||
self.pattern = re.compile(data.pop("pattern"))
|
||||
|
||||
if "ignore" in data:
|
||||
ignore_data = data.pop("ignore")
|
||||
expect(isinstance(ignore_data, list), "ignore must be a list of typepaths.")
|
||||
self.ignore = [TypepathExtra(tp) for tp in ignore_data]
|
||||
|
||||
expect(len(data) == 0, f"Unknown key in banned neighbor: {', '.join(data.keys())}.")
|
||||
|
||||
def matches(self, identified: Content, neighbor: Content):
|
||||
@@ -303,11 +309,17 @@ class Rules:
|
||||
banned_neighbors: list[AtomNeighbor] = []
|
||||
banned_variables: bool | list[BannedVariable] = []
|
||||
required_neighbors: list[AtomNeighbor] = []
|
||||
ignored_neighbors: list[AtomNeighbor] = []
|
||||
when: Optional[When] = None
|
||||
|
||||
def __init__(self, data):
|
||||
expect(isinstance(data, dict), "Lint rules must be a dictionary.")
|
||||
|
||||
if "ignore" in data:
|
||||
ignored_neighbors_data = data.pop("ignore")
|
||||
expect(isinstance(ignored_neighbors_data, list), "'ignore' must be a list of typepaths.")
|
||||
self.ignored_neighbors = [TypepathExtra(tp) for tp in ignored_neighbors_data]
|
||||
|
||||
if "banned" in data:
|
||||
self.banned = data.pop("banned")
|
||||
expect(isinstance(self.banned, bool), "banned must be a boolean.")
|
||||
@@ -361,6 +373,14 @@ class Rules:
|
||||
failures.append(fail_content(identified, f"Typepath {identified.path} is banned{when_text}."))
|
||||
|
||||
for banned_neighbor in self.banned_neighbors:
|
||||
ignored = False
|
||||
for neighbor in contents[:identified_index] + contents[identified_index + 1:]:
|
||||
if any(ignore.matches_path(neighbor.path) for ignore in self.ignored_neighbors):
|
||||
ignored = True
|
||||
break
|
||||
if ignored:
|
||||
continue
|
||||
|
||||
for neighbor in contents[:identified_index] + contents[identified_index + 1:]:
|
||||
if not banned_neighbor.matches(identified, neighbor):
|
||||
continue
|
||||
|
||||
Reference in New Issue
Block a user