Skip to content
This repository was archived by the owner on May 22, 2025. It is now read-only.

Commit 49f10c1

Browse files
committed
atoms_movable (spatial)
1 parent 565f461 commit 49f10c1

File tree

11 files changed

+1603
-243
lines changed

11 files changed

+1603
-243
lines changed

code/__DEFINES/dcs/signals/signals_global.dm

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,3 +82,4 @@
8282
#define COMSIG_DARKSPAWN_ASCENSION "!darkspawn_ascension"
8383
/// Global signal sent when the backrooms finishes initailizing: (No arguments)
8484
#define COMSIG_BACKROOMS_INITIALIZE "!backrooms_initialize"
85+
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
//spatial grid signals
2+
3+
///Called from base of /datum/controller/subsystem/spatial_grid/proc/enter_cell: (/atom/movable)
4+
#define SPATIAL_GRID_CELL_ENTERED(contents_type) "spatial_grid_cell_entered_[contents_type]"
5+
///Called from base of /datum/controller/subsystem/spatial_grid/proc/exit_cell: (/atom/movable)
6+
#define SPATIAL_GRID_CELL_EXITED(contents_type) "spatial_grid_cell_exited_[contents_type]"
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
///the area channel of the important_recursive_contents list, everything in here will be sent a signal when their last holding object changes areas
2+
#define RECURSIVE_CONTENTS_AREA_SENSITIVE "recursive_contents_area_sensitive"
3+
///the hearing channel of the important_recursive_contents list, everything in here will count as a hearing atom
4+
#define RECURSIVE_CONTENTS_HEARING_SENSITIVE "recursive_contents_hearing_sensitive"
5+
///the client mobs channel of the important_recursive_contents list, everything in here will be a mob with an attached client
6+
///this is given to both a clients mob, and a clients eye, both point to the clients mob
7+
#define RECURSIVE_CONTENTS_CLIENT_MOBS "recursive_contents_client_mobs"
8+
///the parent of storage components currently shown to some client mob get this. gets removed when nothing is viewing the parent
9+
#define RECURSIVE_CONTENTS_ACTIVE_STORAGE "recursive_contents_active_storage"

code/__DEFINES/spatial_gridmap.dm

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
/// each cell in a spatial_grid is this many turfs in length and width (with world.max(x or y) being 255, 15 of these fit on each side of a z level)
2+
#define SPATIAL_GRID_CELLSIZE 17
3+
/// Takes a coordinate, and spits out the spatial grid index (x or y) it's inside
4+
#define GET_SPATIAL_INDEX(coord) ROUND_UP((coord) / SPATIAL_GRID_CELLSIZE)
5+
/// changes the cell_(x or y) vars on /datum/spatial_grid_cell to the x or y coordinate on the map for the LOWER LEFT CORNER of the grid cell.
6+
/// index is from 1 to SPATIAL_GRID_CELLS_PER_SIDE
7+
#define GRID_INDEX_TO_COORDS(index) ((((index) - 1) * SPATIAL_GRID_CELLSIZE) + 1)
8+
/// number of grid cells per x or y side of all z levels. pass in world.maxx or world.maxy
9+
#define SPATIAL_GRID_CELLS_PER_SIDE(world_bounds) GET_SPATIAL_INDEX(world_bounds)
10+
11+
//grid contents channels
12+
13+
///everything that is hearing sensitive is stored in this channel
14+
#define SPATIAL_GRID_CONTENTS_TYPE_HEARING RECURSIVE_CONTENTS_HEARING_SENSITIVE
15+
///every movable that has a client in it is stored in this channel
16+
#define SPATIAL_GRID_CONTENTS_TYPE_CLIENTS RECURSIVE_CONTENTS_CLIENT_MOBS
17+
///all atmos machines are stored in this channel (I'm sorry kyler)
18+
#define SPATIAL_GRID_CONTENTS_TYPE_ATMOS "spatial_grid_contents_type_atmos"
19+
20+
#define ALL_CONTENTS_OF_CELL(cell) (cell.hearing_contents | cell.client_contents | cell.atmos_contents)
21+
22+
///whether movable is itself or containing something which should be in one of the spatial grid channels.
23+
#define HAS_SPATIAL_GRID_CONTENTS(movable) (movable.spatial_grid_key)
24+
25+
// macros meant specifically to add/remove movables from the internal lists of /datum/spatial_grid_cell,
26+
// when empty they become references to a single list in SSspatial_grid and when filled they become their own list
27+
// this is to save memory without making them lazylists as that slows down iteration through them
28+
#define GRID_CELL_ADD(cell_contents_list, movable_or_list) \
29+
if(!length(cell_contents_list)) { \
30+
cell_contents_list = list(); \
31+
cell_contents_list += movable_or_list; \
32+
} else { \
33+
cell_contents_list += movable_or_list; \
34+
};
35+
36+
#define GRID_CELL_SET(cell_contents_list, movable_or_list) \
37+
if(!length(cell_contents_list)) { \
38+
cell_contents_list = list(); \
39+
cell_contents_list += movable_or_list; \
40+
} else { \
41+
cell_contents_list |= movable_or_list; \
42+
};
43+
44+
//dont use these outside of SSspatial_grid's scope use the procs it has for this purpose
45+
#define GRID_CELL_REMOVE(cell_contents_list, movable_or_list) \
46+
cell_contents_list -= movable_or_list; \
47+
if(!length(cell_contents_list)) {\
48+
cell_contents_list = dummy_list; \
49+
};
50+
51+
///remove from every list
52+
#define GRID_CELL_REMOVE_ALL(cell, movable) \
53+
GRID_CELL_REMOVE(cell.hearing_contents, movable) \
54+
GRID_CELL_REMOVE(cell.client_contents, movable) \
55+
GRID_CELL_REMOVE(cell.atmos_contents, movable)

code/__DEFINES/subsystems.dm

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@
137137
#define INIT_ORDER_INPUT 85
138138
#define INIT_ORDER_SOUNDS 83
139139
#define INIT_ORDER_INSTRUMENTS 82
140-
#define INIT_ORDER_GREYSCALE 81
140+
#define INIT_ORDER_GREYSCALE 81
141141
#define INIT_ORDER_VIS 80
142142
#define INIT_ORDER_SECURITY_LEVEL 79
143143
#define INIT_ORDER_MATERIALS 76
@@ -149,6 +149,7 @@
149149
#define INIT_ORDER_TICKER 55
150150
#define INIT_ORDER_MAPPING 50
151151
#define INIT_ORDER_EARLY_ASSETS 48
152+
#define INIT_ORDER_SPATIAL_GRID 43
152153
#define INIT_ORDER_ECONOMY 40
153154
#define INIT_ORDER_OUTPUTS 35
154155
#define INIT_ORDER_ATOMS 30

code/__HELPERS/game.dm

Lines changed: 3 additions & 236 deletions
Original file line numberDiff line numberDiff line change
@@ -1,115 +1,12 @@
1+
// moved some logic to a different folder
2+
// check spatial_info.dm
3+
14
///Time before being allowed to select a new cult leader again
25
#define CULT_POLL_WAIT (240 SECONDS)
36

47
/// Returns either the error landmark or the location of the room. Needless to say, if this is used, it means things have gone awry.
58
#define GET_ERROR_ROOM ((locate(/obj/effect/landmark/error) in GLOB.landmarks_list) || locate(4,4,1))
69

7-
/proc/get_area_name(atom/X, format_text = FALSE, is_sensor = FALSE)
8-
var/area/A = isarea(X) ? X : get_area(X)
9-
if(!A)
10-
return null
11-
var/name = A.name
12-
if (is_sensor && !A.show_on_sensors)
13-
name = Gibberish(name, TRUE, 90)
14-
return format_text ? format_text(name) : name
15-
16-
/proc/get_areas_in_range(dist=0, atom/center=usr)
17-
if(!dist)
18-
var/turf/T = get_turf(center)
19-
return T ? list(T.loc) : list()
20-
if(!center)
21-
return list()
22-
23-
var/list/turfs = RANGE_TURFS(dist, center)
24-
var/list/areas = list()
25-
for(var/V in turfs)
26-
var/turf/T = V
27-
areas |= T.loc
28-
return areas
29-
30-
/proc/get_adjacent_areas(atom/center)
31-
. = list(get_area(get_ranged_target_turf(center, NORTH, 1)),
32-
get_area(get_ranged_target_turf(center, SOUTH, 1)),
33-
get_area(get_ranged_target_turf(center, EAST, 1)),
34-
get_area(get_ranged_target_turf(center, WEST, 1)))
35-
listclearnulls(.)
36-
37-
///Returns the open turf next to the center in a specific direction
38-
/proc/get_open_turf_in_dir(atom/center, dir)
39-
var/turf/open/get_turf = get_step(center, dir)
40-
if(istype(get_turf))
41-
return get_turf
42-
43-
///Returns a list with all the adjacent open turfs. Clears the list of nulls in the end.
44-
/proc/get_adjacent_open_turfs(atom/center)
45-
var/list/hand_back = list()
46-
// Inlined get_open_turf_in_dir, just to be fast
47-
var/turf/open/new_turf = get_step(center, NORTH)
48-
if(istype(new_turf))
49-
hand_back += new_turf
50-
new_turf = get_step(center, SOUTH)
51-
if(istype(new_turf))
52-
hand_back += new_turf
53-
new_turf = get_step(center, EAST)
54-
if(istype(new_turf))
55-
hand_back += new_turf
56-
new_turf = get_step(center, WEST)
57-
if(istype(new_turf))
58-
hand_back += new_turf
59-
return hand_back
60-
61-
62-
/proc/get_adjacent_open_areas(atom/center)
63-
. = list()
64-
var/list/adjacent_turfs = get_adjacent_open_turfs(center)
65-
for(var/I in adjacent_turfs)
66-
. |= get_area(I)
67-
68-
/**
69-
* Get a bounding box of a list of atoms.
70-
*
71-
* Arguments:
72-
* - atoms - List of atoms. Can accept output of view() and range() procs.
73-
*
74-
* Returns: list(x1, y1, x2, y2)
75-
*/
76-
/proc/get_bbox_of_atoms(list/atoms)
77-
var/list/list_x = list()
78-
var/list/list_y = list()
79-
for(var/_a in atoms)
80-
var/atom/a = _a
81-
list_x += a.x
82-
list_y += a.y
83-
return list(
84-
min(list_x),
85-
min(list_y),
86-
max(list_x),
87-
max(list_y))
88-
89-
90-
// Like view but bypasses luminosity check
91-
92-
/proc/get_hear(range, atom/source)
93-
94-
var/lum = source.luminosity
95-
source.luminosity = 6
96-
97-
var/list/heard = view(range, source)
98-
source.luminosity = lum
99-
100-
return heard
101-
102-
/proc/alone_in_area(area/the_area, mob/must_be_alone, check_type = /mob/living/carbon)
103-
var/area/our_area = get_area(the_area)
104-
for(var/C in GLOB.alive_mob_list)
105-
if(!istype(C, check_type))
106-
continue
107-
if(C == must_be_alone)
108-
continue
109-
if(our_area == get_area(C))
110-
return 0
111-
return 1
112-
11310
//We used to use linear regression to approximate the answer, but Mloc realized this was actually faster.
11411
//And lo and behold, it is, and it's more accurate to boot.
11512
/proc/cheap_hypotenuse(Ax,Ay,Bx,By)
@@ -130,55 +27,6 @@
13027
//turfs += centerturf
13128
return turfs
13229

133-
/proc/circleview(center=usr,radius=3)
134-
135-
var/turf/centerturf = get_turf(center)
136-
var/list/atoms = new/list()
137-
var/rsq = radius * (radius+0.5)
138-
139-
for(var/atom/A in view(radius, centerturf))
140-
var/dx = A.x - centerturf.x
141-
var/dy = A.y - centerturf.y
142-
if(dx*dx + dy*dy <= rsq)
143-
atoms += A
144-
145-
//turfs += centerturf
146-
return atoms
147-
148-
/proc/get_dist_euclidian(atom/Loc1 as turf|mob|obj,atom/Loc2 as turf|mob|obj)
149-
var/dx = Loc1.x - Loc2.x
150-
var/dy = Loc1.y - Loc2.y
151-
152-
var/dist = sqrt(dx**2 + dy**2)
153-
154-
return dist
155-
156-
///Returns a list of turfs around a center based on RANGE_TURFS()
157-
/proc/circle_range_turfs(center = usr, radius = 3)
158-
159-
var/turf/center_turf = get_turf(center)
160-
var/list/turfs = new/list()
161-
var/rsq = radius * (radius + 0.5)
162-
163-
for(var/turf/checked_turf as anything in RANGE_TURFS(radius, center_turf))
164-
var/dx = checked_turf.x - center_turf.x
165-
var/dy = checked_turf.y - center_turf.y
166-
if(dx * dx + dy * dy <= rsq)
167-
turfs += checked_turf
168-
return turfs
169-
170-
/proc/circleviewturfs(center=usr,radius=3) //Is there even a diffrence between this proc and circle_range_turfs()? // Yes
171-
172-
var/turf/centerturf = get_turf(center)
173-
var/list/turfs = new/list()
174-
var/rsq = radius * (radius+0.5)
175-
176-
for(var/turf/T in view(radius, centerturf))
177-
var/dx = T.x - centerturf.x
178-
var/dy = T.y - centerturf.y
179-
if(dx*dx + dy*dy <= rsq)
180-
turfs += T
181-
return turfs
18230

18331

18432
//This is the new version of recursive_mob_check, used for say().
@@ -273,87 +121,6 @@
273121
return found_mobs
274122

275123

276-
/proc/get_hearers_in_view(R, atom/source)
277-
// Returns a list of hearers in view(R) from source (ignoring luminosity). Used in saycode.
278-
var/turf/T = get_turf(source)
279-
. = list()
280-
if(!T)
281-
return
282-
var/list/processing_list = list()
283-
if (R == 0) // if the range is zero, we know exactly where to look for, we can skip view
284-
processing_list += T.contents // We can shave off one iteration by assuming turfs cannot hear
285-
else // A variation of get_hear inlined here to take advantage of the compiler's fastpath for obj/mob in view
286-
var/lum = T.luminosity
287-
T.luminosity = 6 // This is the maximum luminosity
288-
for(var/mob/M in view(R, T))
289-
processing_list += M
290-
for(var/obj/O in view(R, T))
291-
processing_list += O
292-
T.luminosity = lum
293-
294-
var/i = 0
295-
while(i < length(processing_list)) // recursive_hear_check inlined here
296-
var/atom/A = processing_list[++i]
297-
if(A.flags_1 & HEAR_1)
298-
. += A
299-
processing_list += A.contents
300-
301-
/proc/get_mobs_in_radio_ranges(list/obj/item/radio/radios)
302-
. = list()
303-
// Returns a list of mobs who can hear any of the radios given in @radios
304-
for(var/obj/item/radio/R in radios)
305-
if(R)
306-
. |= get_hearers_in_view(R.canhear_range, R)
307-
308-
309-
#define SIGNV(X) ((X<0)?-1:1)
310-
311-
/proc/inLineOfSight(X1,Y1,X2,Y2,Z=1,PX1=16.5,PY1=16.5,PX2=16.5,PY2=16.5)
312-
var/turf/T
313-
if(X1==X2)
314-
if(Y1==Y2)
315-
return 1 //Light cannot be blocked on same tile
316-
else
317-
var/s = SIGN(Y2-Y1)
318-
Y1+=s
319-
while(Y1!=Y2)
320-
T=locate(X1,Y1,Z)
321-
if(IS_OPAQUE_TURF(T))
322-
return 0
323-
Y1+=s
324-
else
325-
var/m=(32*(Y2-Y1)+(PY2-PY1))/(32*(X2-X1)+(PX2-PX1))
326-
var/b=(Y1+PY1/32-0.015625)-m*(X1+PX1/32-0.015625) //In tiles
327-
var/signX = SIGN(X2-X1)
328-
var/signY = SIGN(Y2-Y1)
329-
if(X1<X2)
330-
b+=m
331-
while(X1!=X2 || Y1!=Y2)
332-
if(round(m*X1+b-Y1))
333-
Y1+=signY //Line exits tile vertically
334-
else
335-
X1+=signX //Line exits tile horizontally
336-
T=locate(X1,Y1,Z)
337-
if(IS_OPAQUE_TURF(T))
338-
return 0
339-
return 1
340-
#undef SIGNV
341-
342-
343-
/proc/isInSight(atom/A, atom/B)
344-
var/turf/Aturf = get_turf(A)
345-
var/turf/Bturf = get_turf(B)
346-
347-
if(!Aturf || !Bturf)
348-
return 0
349-
350-
if(inLineOfSight(Aturf.x,Aturf.y, Bturf.x,Bturf.y,Aturf.z))
351-
return 1
352-
353-
else
354-
return 0
355-
356-
357124
/proc/get_cardinal_step_away(atom/start, atom/finish) //returns the position of a step from start away from finish, in one of the cardinal directions
358125
//returns only NORTH, SOUTH, EAST, or WEST
359126
var/dx = finish.x - start.x

0 commit comments

Comments
 (0)