Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generalizes the ruin loader. #3657

Merged
merged 1 commit into from
Feb 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions code/__defines/misc.dm
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
#define DEBUG
// Turf-only flags.
#define TURF_FLAG_NOJAUNT BITFLAG(0) // This is used in literally one place, turf.dm, to block ethereal jaunt.
#define TURF_FLAG_NORUINS BITFLAG(1) // Used by the ruin generator to skip placing loaded ruins on this turf.
#define TURF_FLAG_BACKGROUND BITFLAG(2) // Used by shuttle movement to determine if it should be ignored by turf translation.
#define TURF_IS_HOLOMAP_OBSTACLE BITFLAG(3)
#define TURF_IS_HOLOMAP_PATH BITFLAG(4)
#define TURF_IS_HOLOMAP_ROCK BITFLAG(5)
#define TURF_FLAG_NOJAUNT BITFLAG(0) // This is used in literally one place, turf.dm, to block ethereal jaunt.
#define TURF_FLAG_NO_POINTS_OF_INTEREST BITFLAG(1) // Used by the level subtemplate generator to skip placing loaded templates on this turf.
#define TURF_FLAG_BACKGROUND BITFLAG(2) // Used by shuttle movement to determine if it should be ignored by turf translation.
#define TURF_IS_HOLOMAP_OBSTACLE BITFLAG(3)
#define TURF_IS_HOLOMAP_PATH BITFLAG(4)
#define TURF_IS_HOLOMAP_ROCK BITFLAG(5)

///Width or height of a transition edge area along the map's borders where transition edge turfs are placed to connect levels together.
#define TRANSITIONEDGE 7
///Extra spacing needed between any random ruins and the transition edge of a level.
#define RUIN_MAP_EDGE_PAD 15
///Extra spacing needed between any random level templates and the transition edge of a level.
#define TEMPLATE_TAG_MAP_EDGE_PAD 15

///Enum value for a level edge that's to be untouched
#define LEVEL_EDGE_NONE 0
Expand Down
9 changes: 0 additions & 9 deletions code/__defines/ruin_tags.dm

This file was deleted.

9 changes: 9 additions & 0 deletions code/__defines/template_tags.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
//Flags for exoplanet ruin picking

#define TEMPLATE_TAG_HABITAT BITFLAG(0) //long term habitat
#define TEMPLATE_TAG_HUMAN BITFLAG(1) //human-made structure
#define TEMPLATE_TAG_ALIEN BITFLAG(2) //artificial structure of an unknown origin
#define TEMPLATE_TAG_WRECK BITFLAG(3) //crashed vessel
#define TEMPLATE_TAG_NATURAL BITFLAG(4) //naturally occuring structure
#define TEMPLATE_TAG_WATER BITFLAG(5) //ruin depending on planet having water accessible
#define TEMPLATE_TAG_HABITABLE BITFLAG(6) //ruin depending on planet being habitable
2 changes: 1 addition & 1 deletion code/controllers/subsystems/mapping.dm
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ SUBSYSTEM_DEF(mapping)
var/list/map_templates_by_category = list()
var/list/map_templates_by_type = list()
var/list/banned_maps = list()
var/list/banned_ruin_names = list()
var/list/banned_template_names = list()

// Listing .dmm filenames in the file at this location will blacklist any templates that include them from being used.
// Maps must be the full file path to be properly included. ex. "maps/random_ruins/away_sites/example.dmm"
Expand Down
8 changes: 5 additions & 3 deletions code/modules/maps/_map_template.dm
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
var/template_parent_type = /datum/map_template
///The initial type of level_data to instantiate new z-level with initially. (Is replaced by whatever is in the map file.) If null, will use default.
var/level_data_type
/// Various tags used for selecting templates for placement on a map.
var/template_tags = 0

/datum/map_template/New(var/created_ad_hoc)
if(created_ad_hoc != SSmapping.type)
Expand All @@ -43,8 +45,8 @@
/datum/map_template/proc/get_template_cost()
return 0

/datum/map_template/proc/get_ruin_tags()
return 0
/datum/map_template/proc/get_template_tags()
return template_tags

/datum/map_template/proc/preload_size()
var/list/bounds = list(1.#INF, 1.#INF, 1.#INF, -1.#INF, -1.#INF, -1.#INF)
Expand Down Expand Up @@ -99,7 +101,7 @@

for (var/turf/T as anything in turfs)
if(template_flags & TEMPLATE_FLAG_NO_RUINS)
T.turf_flags |= TURF_FLAG_NORUINS
T.turf_flags |= TURF_FLAG_NO_POINTS_OF_INTEREST
if(template_flags & TEMPLATE_FLAG_NO_RADS)
qdel(SSradiation.sources_assoc[T])
if(istype(T,/turf/simulated))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@

/datum/exoplanet_theme/proc/adapt_animal(var/datum/planetoid_data/E, var/mob/A)

/datum/exoplanet_theme/proc/modify_ruin_whitelist(var/whitelist_flags)
/datum/exoplanet_theme/proc/modify_template_whitelist(var/whitelist_flags)

/datum/exoplanet_theme/proc/modify_ruin_blacklist(var/blacklist_flags)
/datum/exoplanet_theme/proc/modify_template_blacklist(var/blacklist_flags)

/datum/exoplanet_theme/proc/get_extra_fauna()

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
/mob/living/simple_animal/hostile/hivebot/mega
)

/datum/exoplanet_theme/robotic_guardians/modify_ruin_whitelist(whitelist_flags)
return whitelist_flags | RUIN_ALIEN
/datum/exoplanet_theme/robotic_guardians/modify_template_whitelist(whitelist_flags)
return whitelist_flags | TEMPLATE_TAG_ALIEN

/datum/exoplanet_theme/robotic_guardians/get_extra_fauna()
return guardian_types
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@
'sound/ambience/ominous3.ogg'
)

/datum/exoplanet_theme/robotic_guardians/modify_ruin_whitelist(whitelist_flags)
return whitelist_flags | RUIN_ALIEN
/datum/exoplanet_theme/robotic_guardians/modify_template_whitelist(whitelist_flags)
return whitelist_flags | TEMPLATE_TAG_ALIEN

/datum/exoplanet_theme/ruined_city/get_map_generators(/datum/planetoid_data/E)
return list(/datum/random_map/city)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@
name = "barren exoplanet"
planetoid_data_type = /datum/planetoid_data/random/barren
overmap_marker_type = /obj/effect/overmap/visitable/sector/planetoid/exoplanet/barren
ruin_tags_blacklist = RUIN_HABITAT|RUIN_WATER
template_tags_blacklist = TEMPLATE_TAG_HABITAT|TEMPLATE_TAG_WATER
subtemplate_budget = 6
template_parent_type = /datum/map_template/planetoid/random/exoplanet
level_data_type = /datum/level_data/planetoid/exoplanet/barren
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@
name = "chlorine exoplanet"
planetoid_data_type = /datum/planetoid_data/random/chlorine
overmap_marker_type = /obj/effect/overmap/visitable/sector/planetoid/exoplanet/chlorine
ruin_tags_blacklist = RUIN_HABITAT|RUIN_WATER
template_tags_blacklist = TEMPLATE_TAG_HABITAT|TEMPLATE_TAG_WATER
template_parent_type = /datum/map_template/planetoid/random/exoplanet
level_data_type = /datum/level_data/planetoid/exoplanet/chlorine
prefered_level_data_per_z = list(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@
name = "organic exoplanet"
planetoid_data_type = /datum/planetoid_data/random/meat
overmap_marker_type = /obj/effect/overmap/visitable/sector/planetoid/exoplanet/meat
ruin_tags_blacklist = RUIN_HABITAT|RUIN_HUMAN|RUIN_WATER
template_tags_blacklist = TEMPLATE_TAG_HABITAT|TEMPLATE_TAG_HUMAN|TEMPLATE_TAG_WATER
template_parent_type = /datum/map_template/planetoid/random/exoplanet
level_data_type = /datum/level_data/planetoid/exoplanet/meat
prefered_level_data_per_z = null
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@
name = "shrouded exoplanet"
planetoid_data_type = /datum/planetoid_data/random/shrouded
overmap_marker_type = /obj/effect/overmap/visitable/sector/planetoid/exoplanet/shrouded
ruin_tags_blacklist = RUIN_HABITAT
template_tags_blacklist = TEMPLATE_TAG_HABITAT
template_parent_type = /datum/map_template/planetoid/random/exoplanet
level_data_type = /datum/level_data/planetoid/exoplanet/shrouded
prefered_level_data_per_z = list(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@
planetoid_data_type = /datum/planetoid_data/random/volcanic
overmap_marker_type = /obj/effect/overmap/visitable/sector/planetoid/exoplanet/volcanic
max_themes = 1
ruin_tags_blacklist = RUIN_HABITAT|RUIN_WATER
template_tags_blacklist = TEMPLATE_TAG_HABITAT|TEMPLATE_TAG_WATER
template_parent_type = /datum/map_template/planetoid/random/exoplanet
level_data_type = /datum/level_data/planetoid/exoplanet/volcanic
prefered_level_data_per_z = list(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
abstract_type = /datum/map_template/planetoid/random/exoplanet
template_parent_type = /datum/map_template/planetoid/random/exoplanet
template_categories = list(MAP_TEMPLATE_CATEGORY_EXOPLANET)
ruin_category = MAP_TEMPLATE_CATEGORY_EXOPLANET_SITE
template_category = MAP_TEMPLATE_CATEGORY_EXOPLANET_SITE
tallness = 1
level_data_type = /datum/level_data/planetoid/exoplanet
prefered_level_data_per_z = list(
Expand Down
20 changes: 10 additions & 10 deletions code/modules/maps/template_types/random_exoplanet/random_planet.dm
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,13 @@
///List of theme types that can be picked by this planet when generating.
var/list/possible_themes
///Bit flag of the only ruin tags that may be picked by this planet.
var/ruin_tags_whitelist
var/template_tags_whitelist
///Bit flag of the ruin tags that may never be picked for this planet.
var/ruin_tags_blacklist
var/template_tags_blacklist
///Maximume amount of subtemplates/ruins/sites that may be picked and spawned on the planet.
var/subtemplate_budget = 4
///Ruin sites map template category to use for creating ruins on this planet.
var/ruin_category = MAP_TEMPLATE_CATEGORY_PLANET_SITE
var/template_category = MAP_TEMPLATE_CATEGORY_PLANET_SITE

/datum/map_template/planetoid/random/is_runtime_generated()
return TRUE
Expand Down Expand Up @@ -156,18 +156,18 @@

// Update our blacklist for habitability
if(gen_data.habitability_class >= HABITABILITY_BAD)
ruin_tags_blacklist |= RUIN_HABITABLE
template_tags_blacklist |= TEMPLATE_TAG_HABITABLE

//Generate some of the background stuff for our new planet
before_planet_gen(gen_data)

//Prepare themes, and apply ruin overrides
var/new_ruin_whitelist = ruin_tags_whitelist
var/new_ruin_blacklist = ruin_tags_blacklist
var/new_template_whitelist = template_tags_whitelist
var/new_template_blacklist = template_tags_blacklist
var/list/theme_map_generators
for(var/datum/exoplanet_theme/T in gen_data.themes)
new_ruin_whitelist = T.modify_ruin_whitelist(new_ruin_whitelist)
new_ruin_blacklist = T.modify_ruin_blacklist(new_ruin_blacklist)
new_template_whitelist = T.modify_template_whitelist(new_template_whitelist)
new_template_blacklist = T.modify_template_blacklist(new_template_blacklist)
T.before_map_generation(gen_data)

var/list/gennies = T.get_map_generators()
Expand All @@ -192,7 +192,7 @@
///Create all needed z-levels, tell each of them to generate themselves
new_level_data = generate_levels(gen_data, theme_map_generators)
//Spawn the ruins and sites on the planet
generate_features(gen_data, new_level_data, new_ruin_whitelist, new_ruin_blacklist)
generate_features(gen_data, new_level_data, new_template_whitelist, new_template_blacklist)

//Notify themes we finished gen. Since some themes may not change level gen, we run it for either random or mapped planets
for(var/datum/exoplanet_theme/T in gen_data.themes)
Expand Down Expand Up @@ -263,7 +263,7 @@
var/valid = 1
var/list/block_to_check = block(locate(T.x - landing_radius, T.y - landing_radius, T.z), locate(T.x + landing_radius, T.y + landing_radius, T.z))
for(var/turf/check in block_to_check)
if(!istype(get_area(check), gen_data.surface_area) || check.turf_flags & TURF_FLAG_NORUINS)
if(!istype(get_area(check), gen_data.surface_area) || check.turf_flags & TURF_FLAG_NO_POINTS_OF_INTEREST)
valid = 0
break
if(attempts >= 10)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -102,74 +102,3 @@
if(!istype(A, world.area))
global.using_map.area_purity_test_exempt_areas |= A.type //Make sure we add any of those, so unit tests calm down when we rename
A.SetName("[location_name]")

///Try to spawn the given amount of ruins onto our level. Returns the template types that were spawned
/datum/level_data/planetoid/proc/seed_ruins(var/budget = 0, var/list/potentialRuins)
if(!length(potentialRuins))
log_world("Ruin loader was given no ruins to pick from.")
return list()
//#TODO: Fill in allowed area from a proc or something
var/list/areas_whitelist = list(base_area)
var/list/candidates_ruins = potentialRuins.Copy()
var/list/spawned_ruins = list()

//Each iteration needs to either place a ruin or strictly decrease either the budget or ruins.len (or break).
while(length(candidates_ruins) && (budget > 0))
var/datum/map_template/R = pick(candidates_ruins)
if((R.get_template_cost() <= budget) && !LAZYISIN(SSmapping.banned_ruin_names, R.name) && try_place_ruin(R, areas_whitelist))
spawned_ruins += R
budget -= R.get_template_cost()
//Mark spawned no-duplicate ruins globally
if(!(R.template_flags & TEMPLATE_FLAG_ALLOW_DUPLICATES))
LAZYDISTINCTADD(SSmapping.banned_ruin_names, R.name)
candidates_ruins -= R

if(budget > 0)
log_world("Ruin loader had no ruins to pick from with [budget] left to spend.")
return spawned_ruins

///Attempts several times to find turfs where a ruin can be placed.
/datum/level_data/planetoid/proc/try_place_ruin(var/datum/map_template/ruin, var/list/area_whitelist)
//#FIXME: Isn't trying to fit in a ruin by rolling randomly a bit inneficient?
// Try to place it
var/sanity = 20
var/ruin_half_width = RUIN_MAP_EDGE_PAD + round(ruin.width/2) //Half the ruin size plus the map edge spacing, for testing from the centerpoint
var/ruin_half_height = RUIN_MAP_EDGE_PAD + round(ruin.height/2)
var/ruin_full_width = (2 * RUIN_MAP_EDGE_PAD) + ruin.width
var/ruin_full_height = (2 * RUIN_MAP_EDGE_PAD) + ruin.height
if((ruin_full_width > level_inner_width) || (ruin_full_height > level_inner_height)) // Too big and will never fit.
return //Return if it won't even fit on the entire level

//Try to fit it in somehwere a few times, then give up if we can't
while(sanity > 0)
sanity--
//Pick coordinates inside the level's border within which the ruin will fit. Including the extra ruin spacing from the level's borders.
var/cturf_x = rand(level_inner_min_x + ruin_half_width, level_inner_max_x - ruin_half_width)
var/cturf_y = rand(level_inner_min_y + ruin_half_height, level_inner_max_y - ruin_half_height)
var/turf/T = locate(cturf_x, cturf_y, level_z)
var/valid = TRUE

//#TODO: There's definitely a way to cache what turfs use an area, to avoid doing this for every single ruins!
// Could also probably cache TURF_FLAG_NORUINS turfs globally.
var/list/affected_turfs = ruin.get_affected_turfs(T, TRUE)
for(var/turf/test_turf in affected_turfs)
var/area/A = get_area(test_turf)
if(!is_type_in_list(A, area_whitelist) || (test_turf.turf_flags & TURF_FLAG_NORUINS))
valid = FALSE
break //Break out of the turf check loop, and grab a new set of coordinates
if(!valid)
continue

log_world("Spawned ruin \"[ruin.name]\", center: ([T.x], [T.y], [T.z]), min: ([T.x - ruin_half_width], [T.y - ruin_half_height]), max: ([T.x + ruin_half_width], [T.y + ruin_half_height])")
load_ruin(T, ruin)
return ruin

///Actually handles loading a ruin template at the given turf.
/datum/level_data/planetoid/proc/load_ruin(turf/central_turf, datum/map_template/template)
if(!template)
return FALSE
for(var/turf/T in template.get_affected_turfs(central_turf, TRUE))
for(var/mob/living/simple_animal/monster in T)
qdel(monster)
template.load(central_turf, centered = TRUE)
return TRUE
Original file line number Diff line number Diff line change
@@ -1,24 +1,6 @@
///Picks all ruins and tries to spawn them on the levels that make up the planet.
/datum/map_template/planetoid/random/proc/generate_features(var/datum/planetoid_data/gen_data, var/list/created_level_data, var/whitelist = ruin_tags_whitelist, var/blacklist = ruin_tags_blacklist)
var/my_budget = gen_data._budget_override || subtemplate_budget
if(my_budget <= 0)
return

var/list/possible_subtemplates = list()
var/list/ruins = SSmapping.get_templates_by_category(ruin_category)
for(var/ruin_name in ruins)
var/datum/map_template/ruin = ruins[ruin_name]
var/ruin_tags = ruin.get_ruin_tags()
if(whitelist && !(whitelist & ruin_tags))
continue
if(blacklist & ruin_tags)
continue
possible_subtemplates += ruin

if(!length(possible_subtemplates))
return //If we don't have any ruins, don't bother

/datum/map_template/planetoid/random/proc/generate_features(var/datum/planetoid_data/gen_data, var/list/created_level_data, var/whitelist = template_tags_whitelist, var/blacklist = template_tags_blacklist)
//#TODO: Properly handle generating ruins and sites on the various levels of the planet.
var/datum/level_data/planetoid/surface_level = SSmapping.levels_by_id[gen_data.surface_level_id]
//#TODO: dimensions and area have to be handled on a per level_data basis!!
LAZYADD(gen_data.subtemplates, surface_level.seed_ruins(my_budget, possible_subtemplates))
LAZYADD(gen_data.subtemplates, surface_level.spawn_subtemplates((gen_data._budget_override || subtemplate_budget), template_category, blacklist, whitelist))
4 changes: 0 additions & 4 deletions code/modules/maps/template_types/ruins_exoplanet.dm
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,3 @@
prefix = "maps/random_ruins/exoplanet_ruins/"
template_categories = list(MAP_TEMPLATE_CATEGORY_EXOPLANET_SITE)
template_parent_type = /datum/map_template/ruin/exoplanet
var/list/ruin_tags

/datum/map_template/ruin/exoplanet/get_ruin_tags()
return ruin_tags
Loading
Loading