mirror of
https://github.com/vgstation-coders/vgstation13.git
synced 2025-12-10 10:21:11 +00:00
* basic work on this * more * now need to unbreak this * now need to unbreak this * looks like we have to do a little rewriting of the whole thing to make it support this * intervening in the xy grid part seems too hard * intervening in the xy grid part seems too hard * finally something that actually works, now to make it look less bad * now much cleaner looking * ...it works. IT WORKS! now to find out how to make it less laggy at some point * well that definitely helps. also added some help for it * here too cause why not. lot of copypaste code here could cut it down at some point * faster loop * more of that * more Co-authored-by: SECBATON GRIFFON <sage>
102 lines
4.0 KiB
Plaintext
102 lines
4.0 KiB
Plaintext
//DUNGEONS
|
|
//Map elements that can be loaded into the game with a single proc, without specifying coordinates or any arguments at all.
|
|
//They're loaded to z-level 2, and the code places them so that they don't overlap with each other
|
|
|
|
var/list/existing_dungeons = list()
|
|
var/turf/dungeon_area = null
|
|
|
|
/datum/map_element/dungeon
|
|
//If TRUE, don't load any duplicates (subtypes are fine)
|
|
//Note: When trying to load a duplicate, load_dungeon() will return a reference to the "original" dungeon datum, instead of a list of its objects
|
|
var/unique = 0
|
|
|
|
//If not null, spawn these objects at the border of the dungeon
|
|
//By default, random teleporters are created (making escaping to Z-2 impossible)
|
|
var/border_type = /obj/effect/step_trigger/teleporter/random/shuttle_transit
|
|
|
|
/datum/map_element/dungeon/load(x,y,z)
|
|
.=..()
|
|
|
|
if(border_type)
|
|
for(var/turf/T in block_borders(location, locate(location.x + width, location.y + height, location.z)))
|
|
if(ispath(border_type, /turf))
|
|
T.ChangeTurf(border_type)
|
|
else
|
|
new border_type(T)
|
|
|
|
|
|
//MARKER: put this on z-2, with plenty of space to the right and north
|
|
/obj/effect/landmark/dungeon_area
|
|
name = "Dungeon marker - make sure there's nothing to the right or above this"
|
|
desc = "All \"dungeons\" start spawning here."
|
|
|
|
/obj/effect/landmark/dungeon_area/New()
|
|
dungeon_area = get_turf(src)
|
|
|
|
..()
|
|
|
|
//Load a map element into a special area on z-2
|
|
//You can pass a map element object, or a map element path (like /datum/map_element/meme)
|
|
|
|
//NOTE: first dungeon spawns in the lower left corner. Next dungeons spawn to the right until there's no more space there.
|
|
//Then spawn above the first dungeon and continue to the right...
|
|
|
|
//Returns list of loaded objects. If trying to load a duplicate dungeon (and it's forbidden), returns a reference to the "original" dungeon instead
|
|
|
|
#define MAXIMUM_DUNGEON_WIDTH 80
|
|
|
|
/proc/load_dungeon(dungeon_type, var/rotate = 0, var/override_can_rotate = FALSE, var/clipmin_x=0, var/clipmax_x=INFINITY, var/clipmin_y=0, var/clipmax_y=INFINITY, var/clipmin_z=0, var/clipmax_z=INFINITY)
|
|
if(!dungeon_area)
|
|
return 0
|
|
|
|
var/datum/map_element/ME
|
|
if(ispath(dungeon_type, /datum/map_element))
|
|
ME = new dungeon_type
|
|
else if(istype(dungeon_type, /datum/map_element))
|
|
ME = dungeon_type
|
|
else
|
|
return 0
|
|
|
|
var/datum/map_element/dungeon/D = ME
|
|
if(istype(D) && D.unique)
|
|
//Check if this exact dungeon already exists
|
|
for(var/datum/map_element/dungeon/dungeon in existing_dungeons)
|
|
if(dungeon.type == ME.type)
|
|
return dungeon
|
|
|
|
var/spawn_x = dungeon_area.x
|
|
var/spawn_y = dungeon_area.y
|
|
//Where to spawn the dungeon
|
|
|
|
var/tallest_dungeon_height = 0
|
|
//Highest dungeon in the current row
|
|
|
|
for(var/datum/map_element/dungeon in existing_dungeons) //Go through all dungeons in the order they were created
|
|
//if(!dungeon.location)
|
|
// continue
|
|
|
|
if(dungeon.height > tallest_dungeon_height)
|
|
tallest_dungeon_height = dungeon.height
|
|
|
|
if(dungeon.location.y > spawn_y) //Start of the new row
|
|
spawn_y = dungeon.location.y
|
|
spawn_x = dungeon_area.x //Go to the beginning of the row
|
|
tallest_dungeon_height = 0
|
|
else //Still in our row
|
|
if(dungeon.location.x + dungeon.width > spawn_x)
|
|
spawn_x = dungeon.location.x + dungeon.width + 1
|
|
|
|
if(spawn_x > world.maxx - MAXIMUM_DUNGEON_WIDTH) //No space for a new dungeon here!
|
|
//Go to the next row
|
|
spawn_y = spawn_y + tallest_dungeon_height + 1 //So that nothing in the new row overlaps with the previous one
|
|
spawn_x = dungeon_area.x
|
|
|
|
if(!ME.width) //If the map element doesn't have its width/height calculated yet, do it now and add the map element to the dungeon list
|
|
ME.assign_dimensions()
|
|
existing_dungeons.Add(ME) //Add it now, to prevent issues occuring when two dungeons are loaded at once
|
|
|
|
//Reduce X and Y by 1 because these arguments are actually offsets, and they're added to 1;1 in the map loader. Without this, spawning something at 1;1 would result in it getting spawned at 2;2
|
|
var/result = ME.load(spawn_x - 1, spawn_y - 1, dungeon_area.z, rotate, FALSE, override_can_rotate, clipmin_x, clipmax_x, clipmin_y, clipmax_y, clipmin_z, clipmax_z)
|
|
|
|
return result
|