mirror of
https://github.com/Aurorastation/Aurora.3.git
synced 2025-12-21 07:32:02 +00:00
changes: Overlays now creates less temporary lists. Falling no longer queues unsimulated atoms that wouldn't fall anyways (incl. LOs). Pixel-shifted AO is now cached too. Changed some references to get_map_cell() to macro equivalents in random maps. Added smoothing hinting to the icon smoother, allowing for major performance improvements in common cases. Space initialization no longer involves appearance churn (and is much faster as a result).
222 lines
5.9 KiB
Plaintext
222 lines
5.9 KiB
Plaintext
// Generates cave systems for the asteroid, and places ore tiles.
|
|
var/global/list/random_maps = list()
|
|
var/global/list/map_count = list()
|
|
|
|
/datum/random_map
|
|
|
|
// Strings.
|
|
var/name // Set in New()
|
|
var/descriptor = "random map" // Display name.
|
|
|
|
// Locator/value vars.
|
|
var/initial_wall_cell = 100 // % Chance that a cell will be seeded as a wall.
|
|
var/max_attempts = 5 // Fail if a sane map isn't generated by this point.
|
|
var/origin_x = 1 // Origin point, left.
|
|
var/origin_y = 1 // Origin point, bottom.
|
|
var/origin_z = 1 // Target Z-level.
|
|
var/limit_x = 128 // Default x size.
|
|
var/limit_y = 128 // Default y size.
|
|
var/auto_apply = 1
|
|
var/preserve_map = 1
|
|
|
|
// Turf paths.
|
|
var/wall_type = /turf/simulated/wall
|
|
var/floor_type = /turf/simulated/floor
|
|
var/target_turf_type
|
|
|
|
// Storage for the final iteration of the map.
|
|
var/list/map = list() // Actual map.
|
|
var/tmp/map_len = 0
|
|
|
|
// If set, all sleep(-1) calls will be skipped.
|
|
// Test to see if rand_seed() can be used reliably.
|
|
var/priority_process
|
|
|
|
/datum/random_map/New(var/seed, var/tx, var/ty, var/tz, var/tlx, var/tly, var/do_not_apply, var/do_not_announce)
|
|
|
|
// Store this for debugging.
|
|
if(!map_count[descriptor])
|
|
map_count[descriptor] = 1
|
|
else
|
|
map_count[descriptor]++
|
|
name = "[descriptor] #[map_count[descriptor]]"
|
|
if(preserve_map) random_maps[name] = src
|
|
|
|
// Get origins for applying the map later.
|
|
set_origins(tx, ty, tz)
|
|
if(tlx) limit_x = tlx
|
|
if(tly) limit_y = tly
|
|
|
|
if(do_not_apply)
|
|
auto_apply = null
|
|
|
|
// Initialize map.
|
|
set_map_size()
|
|
|
|
var/start_time = world.timeofday
|
|
if(!do_not_announce) admin_notice("<span class='danger'>Generating [name].</span>", R_DEBUG)
|
|
CHECK_TICK
|
|
|
|
// Testing needed to see how reliable this is (asynchronous calls, called during worldgen), DM ref is not optimistic
|
|
if(seed)
|
|
rand_seed(seed)
|
|
priority_process = 1
|
|
|
|
for(var/i = 0;i<max_attempts;i++)
|
|
if(generate())
|
|
if(!do_not_announce) admin_notice("<span class='danger'>[capitalize(name)] generation completed in [round(0.1*(world.timeofday-start_time),0.1)] seconds.</span>", R_DEBUG)
|
|
return
|
|
if(!do_not_announce) admin_notice("<span class='danger'>[capitalize(name)] failed to generate ([round(0.1*(world.timeofday-start_time),0.1)] seconds): could not produce sane map.</span>", R_DEBUG)
|
|
|
|
/datum/random_map/proc/get_map_cell(var/x,var/y)
|
|
if(!islist(map))
|
|
set_map_size()
|
|
var/cell = ((y-1)*limit_x)+x
|
|
if((cell < 1) || (cell > map.len))
|
|
return null
|
|
else
|
|
return cell
|
|
|
|
/datum/random_map/proc/get_map_char(var/value)
|
|
switch(value)
|
|
if(WALL_CHAR)
|
|
return "#"
|
|
if(FLOOR_CHAR)
|
|
return "."
|
|
if(DOOR_CHAR)
|
|
return "D"
|
|
if(ROOM_TEMP_CHAR)
|
|
return "+"
|
|
if(MONSTER_CHAR)
|
|
return "M"
|
|
if(ARTIFACT_TURF_CHAR)
|
|
return "_"
|
|
if(ARTIFACT_CHAR)
|
|
return "A"
|
|
else
|
|
return " "
|
|
|
|
/datum/random_map/proc/display_map(atom/user)
|
|
|
|
if(!user)
|
|
user = world
|
|
|
|
map_len = map.len
|
|
|
|
var/list/dat = "<code>+------+<br>"
|
|
for(var/x = 1, x <= limit_x, x++)
|
|
for(var/y = 1, y <= limit_y, y++)
|
|
var/tmp_cell
|
|
TRANSLATE_AND_VERIFY_COORD_MLEN(x, y, map_len)
|
|
if(tmp_cell)
|
|
dat += get_map_char(map[tmp_cell])
|
|
dat += "<br>"
|
|
dat += "+------+</code>"
|
|
user << dat.Join()
|
|
|
|
/datum/random_map/proc/set_map_size()
|
|
map = list()
|
|
map.len = limit_x * limit_y
|
|
|
|
/datum/random_map/proc/seed_map()
|
|
map_len = map.len
|
|
for(var/x = 1, x <= limit_x, x++)
|
|
for(var/y = 1, y <= limit_y, y++)
|
|
var/current_cell = TRANSLATE_COORD(x, y) // Coordinate cannot be invalid here, so use the faster no-validate one.
|
|
if(prob(initial_wall_cell))
|
|
map[current_cell] = WALL_CHAR
|
|
else
|
|
map[current_cell] = FLOOR_CHAR
|
|
|
|
/datum/random_map/proc/clear_map()
|
|
for(var/x = 1, x <= limit_x, x++)
|
|
for(var/y = 1, y <= limit_y, y++)
|
|
map[TRANSLATE_COORD(x, y)] = 0
|
|
|
|
/datum/random_map/proc/generate()
|
|
seed_map()
|
|
generate_map()
|
|
if(check_map_sanity())
|
|
cleanup()
|
|
if(auto_apply)
|
|
apply_to_map()
|
|
return 1
|
|
return 0
|
|
|
|
// Unused for basic map.
|
|
/datum/random_map/proc/generate_map()
|
|
return 1
|
|
|
|
/datum/random_map/proc/check_map_sanity()
|
|
return 1
|
|
|
|
/datum/random_map/proc/set_origins(var/tx, var/ty, var/tz)
|
|
origin_x = tx ? tx : 1
|
|
origin_y = ty ? ty : 1
|
|
origin_z = tz ? tz : 1
|
|
|
|
/datum/random_map/proc/apply_to_map()
|
|
if(!origin_x) origin_x = 1
|
|
if(!origin_y) origin_y = 1
|
|
if(!origin_z) origin_z = 1
|
|
|
|
map_len = map.len
|
|
|
|
for(var/x = 1, x <= limit_x, x++)
|
|
for(var/y = 1, y <= limit_y, y++)
|
|
if(!priority_process)
|
|
CHECK_TICK
|
|
apply_to_turf(x,y)
|
|
|
|
/datum/random_map/proc/apply_to_turf(var/x,var/y)
|
|
var/tmp_cell
|
|
TRANSLATE_AND_VERIFY_COORD_MLEN(x, y, map_len)
|
|
if(!tmp_cell)
|
|
return 0
|
|
var/turf/T = locate((origin_x-1)+x,(origin_y-1)+y,origin_z)
|
|
if(!T || (target_turf_type && !istype(T,target_turf_type)))
|
|
return 0
|
|
var/newpath = get_appropriate_path(map[tmp_cell])
|
|
if(newpath)
|
|
T.ChangeTurf(newpath)
|
|
get_additional_spawns(map[tmp_cell],T,get_spawn_dir(x, y))
|
|
return T
|
|
|
|
/datum/random_map/proc/get_spawn_dir()
|
|
return 0
|
|
|
|
/datum/random_map/proc/get_appropriate_path(var/value)
|
|
switch(value)
|
|
if(FLOOR_CHAR)
|
|
return floor_type
|
|
if(WALL_CHAR)
|
|
return wall_type
|
|
|
|
/datum/random_map/proc/get_additional_spawns(var/value, var/turf/T)
|
|
if(value == DOOR_CHAR)
|
|
new /obj/machinery/door/airlock(T)
|
|
|
|
/datum/random_map/proc/cleanup()
|
|
return
|
|
|
|
/datum/random_map/proc/overlay_with(var/datum/random_map/target_map, var/tx, var/ty)
|
|
if(!map.len || !istype(target_map))
|
|
return
|
|
tx-- // Update origin so that x/y index
|
|
ty-- // doesn't push it off-kilter by one.
|
|
for(var/x = 1, x <= limit_x, x++)
|
|
for(var/y = 1, y <= limit_y, y++)
|
|
var/current_cell = get_map_cell(x,y)
|
|
if(!current_cell)
|
|
continue
|
|
if(tx+x > target_map.limit_x)
|
|
continue
|
|
if(ty+y > target_map.limit_y)
|
|
continue
|
|
target_map.map[target_map.get_map_cell(tx+x,ty+y)] = map[current_cell]
|
|
handle_post_overlay_on(target_map,tx,ty)
|
|
|
|
|
|
/datum/random_map/proc/handle_post_overlay_on(var/datum/random_map/target_map, var/tx, var/ty)
|
|
return
|