Multiz and isolated ruins support. (#47336)

Two new always_load_with options for ruins.
Use PLACE_ISOLATED to load the secondary ruin part in separate z level.
Use PLACE_BELOW to load it on the z level below.
This commit is contained in:
AnturK
2019-10-26 21:06:05 +13:00
committed by oranges
parent 372189aad8
commit bec3e60880
3 changed files with 92 additions and 41 deletions
+59 -23
View File
@@ -1,10 +1,12 @@
/datum/map_template/ruin/proc/try_to_place(z,allowed_areas)
var/sanity = PLACEMENT_TRIES
/datum/map_template/ruin/proc/try_to_place(z,allowed_areas,turf/forced_turf)
var/sanity = forced_turf ? 1 : PLACEMENT_TRIES
if(SSmapping.level_trait(z,ZTRAIT_ISOLATED_RUINS))
return place_on_isolated_level(z)
while(sanity > 0)
sanity--
var/width_border = TRANSITIONEDGE + SPACERUIN_MAP_EDGE_PAD + round(width / 2)
var/height_border = TRANSITIONEDGE + SPACERUIN_MAP_EDGE_PAD + round(height / 2)
var/turf/central_turf = locate(rand(width_border, world.maxx - width_border), rand(height_border, world.maxy - height_border), z)
var/turf/central_turf = forced_turf ? forced_turf : locate(rand(width_border, world.maxx - width_border), rand(height_border, world.maxy - height_border), z)
var/valid = TRUE
for(var/turf/check in get_affected_turfs(central_turf,1))
@@ -34,8 +36,20 @@
T.flags_1 |= NO_RUINS_1
new /obj/effect/landmark/ruin(central_turf, src)
return TRUE
return FALSE
return central_turf
/datum/map_template/ruin/proc/place_on_isolated_level(z)
var/datum/turf_reservation/reservation = SSmapping.RequestBlockReservation(width, height, z) //Make the new level creation work with different traits.
if(!reservation)
return
var/turf/placement = locate(reservation.bottom_left_coords[1],reservation.bottom_left_coords[2],reservation.bottom_left_coords[3])
load(placement)
loaded++
for(var/turf/T in get_affected_turfs(placement))
T.flags_1 |= NO_RUINS_1
var/turf/center = locate(placement.x + round(width/2),placement.y + round(height/2),placement.z)
new /obj/effect/landmark/ruin(center, src)
return center
/proc/seedRuins(list/z_levels = null, budget = 0, whitelist = /area/space, list/potentialRuins)
@@ -51,9 +65,8 @@
var/list/ruins = potentialRuins.Copy()
var/list/forced_ruins = list() //These go first on the z level associated (same random one by default)
var/list/forced_ruins = list() //These go first on the z level associated (same random one by default) or if the assoc value is a turf to the specified turf.
var/list/ruins_availible = list() //we can try these in the current pass
var/forced_z //If set we won't pick z level and use this one instead.
//Set up the starting ruin list
for(var/key in ruins)
@@ -65,31 +78,51 @@
if(R.unpickable)
continue
ruins_availible[R] = R.placement_weight
while(budget > 0 && (ruins_availible.len || forced_ruins.len))
var/datum/map_template/ruin/current_pick
var/forced = FALSE
var/forced_z //If set we won't pick z level and use this one instead.
var/forced_turf //If set we place the ruin centered on the given turf
if(forced_ruins.len) //We have something we need to load right now, so just pick it
for(var/ruin in forced_ruins)
current_pick = ruin
if(forced_ruins[ruin] > 0) //Load into designated z
if(isturf(forced_ruins[ruin]))
var/turf/T = forced_ruins[ruin]
forced_z = T.z //In case of chained ruins
forced_turf = T
else if(forced_ruins[ruin] > 0) //Load into designated z
forced_z = forced_ruins[ruin]
forced = TRUE
break
else //Otherwise just pick random one
current_pick = pickweight(ruins_availible)
var/placement_tries = PLACEMENT_TRIES
var/placement_tries = forced_turf ? 1 : PLACEMENT_TRIES //Only try once if we target specific turf
var/failed_to_place = TRUE
var/z_placed = 0
while(placement_tries > 0)
placement_tries--
z_placed = pick(z_levels)
if(!current_pick.try_to_place(forced_z ? forced_z : z_placed,whitelist))
continue
else
failed_to_place = FALSE
break
var/target_z = 0
var/turf/placed_turf //Where the ruin ended up if we succeeded
outer:
while(placement_tries > 0)
placement_tries--
target_z = pick(z_levels)
if(forced_z)
target_z = forced_z
if(current_pick.always_spawn_with) //If the ruin has part below, make sure that z exists.
for(var/v in current_pick.always_spawn_with)
if(current_pick.always_spawn_with[v] == PLACE_BELOW)
var/turf/T = locate(1,1,target_z)
if(!SSmapping.get_turf_below(T))
if(forced_z)
continue outer
else
break outer
placed_turf = current_pick.try_to_place(target_z,whitelist,forced_turf)
if(!placed_turf)
continue
else
failed_to_place = FALSE
break
//That's done remove from priority even if it failed
if(forced)
@@ -120,18 +153,21 @@
if(istype(linked,v))
switch(current_pick.always_spawn_with[v])
if(PLACE_SAME_Z)
forced_ruins[linked] = forced_z ? forced_z : z_placed //I guess you might want a chain somehow
forced_ruins[linked] = target_z //I guess you might want a chain somehow
if(PLACE_LAVA_RUIN)
forced_ruins[linked] = pick(SSmapping.levels_by_trait(ZTRAIT_LAVA_RUINS))
if(PLACE_SPACE_RUIN)
forced_ruins[linked] = pick(SSmapping.levels_by_trait(ZTRAIT_SPACE_RUINS))
if(PLACE_DEFAULT)
forced_ruins[linked] = -1
forced_z = 0
if(PLACE_BELOW)
forced_ruins[linked] = SSmapping.get_turf_below(placed_turf)
if(PLACE_ISOLATED)
forced_ruins[linked] = SSmapping.get_isolated_ruin_z()
//Update the availible list
for(var/datum/map_template/ruin/R in ruins_availible)
if(R.cost > budget)
ruins_availible -= R
log_world("Ruin loader finished with [budget] left to spend.")