mirror of
https://github.com/goonstation/goonstation-2016.git
synced 2026-05-18 06:29:01 +01:00
298 lines
11 KiB
Plaintext
298 lines
11 KiB
Plaintext
#define RANDOM_Z_LEVEL_TARGET 7 //Z level that should recieve randomized station
|
|
#define RANDOM_Z_LEVEL_SOURCE 6 //Z level that contains source rooms with room_props objects.
|
|
#define RANDOM_Z_LEVEL_MAXROOMS 35 //How many rooms max should we use.
|
|
|
|
//Make sure that no duplicates can exist in unconnected list.
|
|
//Write something that runs at the end and plugs up holes to space. either with walls or airlocks
|
|
//Add something to room props that tells us if only one instance of that room is allowed.
|
|
|
|
/proc/jumptoseed()
|
|
usr.x = 112
|
|
usr.y = 112
|
|
usr.z = 7
|
|
|
|
/area/random_source //Used to clean up after we're done.
|
|
name = "Random station source tiles"
|
|
icon_state = "yellow"
|
|
|
|
/area/random_station
|
|
name = "Mysterious Station"
|
|
icon_state = "yellow"
|
|
requires_power = 0
|
|
luminosity = 1
|
|
RL_Lighting = 0
|
|
|
|
var/list/rnd_rooms = new/list()
|
|
var/list/rnd_cons = new/list()
|
|
|
|
/datum/source_room
|
|
var/list/tiles = new/list()
|
|
var/area
|
|
|
|
/obj/room_monsterspawn //Used to mark spawns for monsters.
|
|
name = "room monster spawn"
|
|
anchored = 1
|
|
invisibility = 100
|
|
var/probability = 100 //probability that we actually spawn something here.
|
|
icon = 'icons/misc/mark.dmi'
|
|
icon_state = "rdn"
|
|
|
|
/obj/room_rewardspawn //Used to mark spawns for rewards.
|
|
name = "room reward spawn"
|
|
anchored = 1
|
|
invisibility = 100
|
|
var/probability = 100 //probability that we actually spawn something here.
|
|
icon = 'icons/misc/mark.dmi'
|
|
icon_state = "ydn"
|
|
|
|
/obj/room_props //These need to be placed in the center of the room
|
|
name = "room props"
|
|
anchored = 1
|
|
invisibility = 100
|
|
var/room_range = 1 //Range of the room (see range proc for how the numbers work)
|
|
var/room_unique = 0 //Is this an unique room that should only be placed once? 0=no, 1=yes
|
|
var/list/connections = new/list()
|
|
icon = 'icons/misc/mark.dmi'
|
|
icon_state = "props"
|
|
|
|
/obj/room_connection //These are placed north east south and west from the center at the edge of the room if that tile is not solid
|
|
name = "room connection" //Or otherwise blocked. These are used to connect rooms to each other.
|
|
anchored = 1
|
|
invisibility = 100
|
|
var/open_dir = -1 //These vars are automatically set. Dont need to mess with them.
|
|
var/obj/room_props/room = null
|
|
|
|
proc/copy_vars(var/atom/from, var/atom/target)
|
|
if (!target || !from) return
|
|
for(var/V in from.vars)
|
|
if (!issaved(from.vars[V]))
|
|
continue
|
|
|
|
//The following are commented out because they are already tmp, so issaved() is false for them.
|
|
//if(V == "x") continue
|
|
//if(V == "y") continue
|
|
//if(V == "z") continue
|
|
//if(V == "loc") continue
|
|
if(V == "locs") continue
|
|
if(V == "contents") continue
|
|
//if(V == "type") continue
|
|
//if(V == "parent_type") continue
|
|
//if(V == "vars") continue
|
|
//if(V == "verbs") continue
|
|
target.vars[V] = from.vars[V]
|
|
|
|
proc/should_copy_room(var/obj/room_props/source, var/turf/target)
|
|
for(var/turf/T in range(source.room_range, target))
|
|
var/diff_x = T.x - target.x
|
|
var/diff_y = T.y - target.y
|
|
var/turf/source_turf = locate(source.loc.x + diff_x, source.loc.y + diff_y, RANDOM_Z_LEVEL_SOURCE)
|
|
if(istype(source_turf, /turf/space) && !source_turf.contents.len) continue
|
|
if(!istype(T, /turf/space))
|
|
return 0
|
|
if(T.contents.len)
|
|
return 0
|
|
return 1
|
|
|
|
proc/copy_room_to(var/obj/room_props/source, var/turf/target)
|
|
for(var/turf/T in range(source.room_range, source.loc))
|
|
if(istype(T, /turf/space) && !T.contents.len) continue //No need to copy this. This is the default state.
|
|
var/diff_x = T.x - source.x
|
|
var/diff_y = T.y - source.y
|
|
var/turf/target_turf = locate(target.x + diff_x, target.y + diff_y, RANDOM_Z_LEVEL_TARGET)
|
|
if(!target_turf) continue //Outside map.
|
|
new T.type(target_turf)
|
|
copy_vars(T, target_turf)
|
|
new/area/random_station(target_turf)
|
|
for(var/atom/A in T)
|
|
var/atom/newAtom = new A.type(target_turf)
|
|
copy_vars(A, newAtom)
|
|
return
|
|
|
|
/proc/has_dense_objects(var/turf/T)
|
|
for(var/atom/A in T)
|
|
if(A.density) return 1
|
|
return 0
|
|
|
|
/proc/cleanuprnd()
|
|
for(var/obj/room_props/p in world)
|
|
qdel(p)
|
|
for(var/obj/room_connection/c in world)
|
|
qdel(c)
|
|
var/area/A = locate(/area/random_source)
|
|
for(var/obj/toDel in A)
|
|
qdel(toDel)
|
|
|
|
proc/spawnmonsters()
|
|
var/theme = pick("undead", "plantsnanimals", "aliens", "demonsnmutants")
|
|
for(var/obj/room_monsterspawn/S in world)
|
|
if(S.z != RANDOM_Z_LEVEL_TARGET)
|
|
continue
|
|
if(prob(S.probability))
|
|
switch(theme)
|
|
if("undead")
|
|
var/selected = pick(/obj/critter/spirit, /obj/critter/zombie, /obj/critter/zombie/scientist, /obj/critter/zombie/security)
|
|
new selected(S.loc)
|
|
qdel(S)
|
|
if("plantsnanimals")
|
|
var/selected = pick(/obj/critter/bear, /obj/critter/spacebee, /obj/critter/lion, /obj/critter/killertomato, /obj/critter/maneater)
|
|
new selected(S.loc)
|
|
qdel(S)
|
|
if("aliens")
|
|
var/selected = pick(/obj/critter/martian/soldier, /obj/critter/martian/warrior, /obj/critter/martian/psychic)
|
|
new selected(S.loc)
|
|
qdel(S)
|
|
if("demonsnmutants")
|
|
var/selected = pick(/obj/critter/bloodling, /obj/critter/blobman, /obj/critter/mimic)
|
|
new selected(S.loc)
|
|
qdel(S)
|
|
|
|
proc/spawnrewards()
|
|
for(var/obj/room_rewardspawn/S in world)
|
|
if(S.z != RANDOM_Z_LEVEL_TARGET)
|
|
continue
|
|
if(prob(S.probability))
|
|
var/selected = pick(/obj/storage/crate/loot) //No idea what the rewards should be
|
|
new selected(S.loc)
|
|
qdel(S)
|
|
|
|
proc/spawndeco()
|
|
var/theme = pick("bloody", "messy", "dirty", "clean")
|
|
for(var/turf/T in locate(/area/random_station))
|
|
if(T.z != RANDOM_Z_LEVEL_TARGET)
|
|
continue
|
|
switch(theme)
|
|
if("bloody")
|
|
if(T.density)
|
|
if(prob(11) && prob(50))
|
|
var/selected = pick(/obj/decal/cleanable/blood, /obj/decal/cleanable/blood/splatter)
|
|
new selected(T)
|
|
else
|
|
if(prob(11) && prob(55))
|
|
var/selected = pick(/obj/decal/cleanable/blood, /obj/decal/cleanable/blood/splatter, /obj/decal/cleanable/blood/gibs, /obj/decal/cleanable/blood/gibs/core, /obj/decal/cleanable/blood/gibs/body)
|
|
new selected(T)
|
|
if("messy")
|
|
if(T.density)
|
|
if(prob(11) && prob(50))
|
|
var/selected = pick(/obj/decal/cleanable/eggsplat, /obj/decal/cleanable/tomatosplat)
|
|
new selected(T)
|
|
else
|
|
if(prob(11) && prob(55))
|
|
var/selected = pick(/obj/decal/cleanable/generic, /obj/deskclutter, /obj/decal/cleanable/robot_debris, /obj/decal/cleanable/robot_debris/limb, /obj/decal/cleanable/robot_debris/gib, /obj/decal/cleanable/molten_item)
|
|
new selected(T)
|
|
if("dirty")
|
|
if(T.density)
|
|
if(prob(11) && prob(50))
|
|
var/selected = pick(/obj/decal/cleanable/eggsplat, /obj/decal/cleanable/tomatosplat, /obj/decal/cleanable/oil, /obj/decal/cleanable/oil/streak, /obj/decal/cleanable/fungus)
|
|
new selected(T)
|
|
else
|
|
if(prob(11) && prob(55))
|
|
var/selected = pick(/obj/decal/cleanable/dirt, /obj/decal/cleanable/oil, /obj/decal/cleanable/oil/streak, /obj/decal/cleanable/vomit, /obj/decal/cleanable/urine)
|
|
new selected(T)
|
|
if("clean")
|
|
continue
|
|
|
|
proc/create_random_station()
|
|
var/mid_x = round(world.maxx / 2)
|
|
var/mid_y = round(world.maxy / 2)
|
|
|
|
var/turf/origin = locate(mid_x, mid_y, RANDOM_Z_LEVEL_TARGET)
|
|
|
|
for(var/obj/room_props/p in world)
|
|
if(p.z != RANDOM_Z_LEVEL_SOURCE) continue
|
|
rnd_rooms.Add(p)
|
|
var/turf/north = locate(p.x, p.y + p.room_range, RANDOM_Z_LEVEL_SOURCE)
|
|
var/turf/south = locate(p.x, p.y - p.room_range, RANDOM_Z_LEVEL_SOURCE)
|
|
var/turf/east = locate(p.x + p.room_range, p.y, RANDOM_Z_LEVEL_SOURCE)
|
|
var/turf/west = locate(p.x - p.room_range, p.y, RANDOM_Z_LEVEL_SOURCE)
|
|
if(north)
|
|
if(!north.density && !istype(north, /turf/space) && !has_dense_objects(north))
|
|
var/obj/room_connection/c = new/obj/room_connection(north)
|
|
c.open_dir = NORTH
|
|
c.room = p
|
|
rnd_cons.Add(c)
|
|
p.connections.Add(c)
|
|
if(south)
|
|
if(!south.density && !istype(south, /turf/space) && !has_dense_objects(south))
|
|
var/obj/room_connection/c = new/obj/room_connection(south)
|
|
c.open_dir = SOUTH
|
|
c.room = p
|
|
rnd_cons.Add(c)
|
|
p.connections.Add(c)
|
|
if(east)
|
|
if(!east.density && !istype(east, /turf/space) && !has_dense_objects(east))
|
|
var/obj/room_connection/c = new/obj/room_connection(east)
|
|
c.open_dir = EAST
|
|
c.room = p
|
|
rnd_cons.Add(c)
|
|
p.connections.Add(c)
|
|
if(west)
|
|
if(!west.density && !istype(west, /turf/space) && !has_dense_objects(west))
|
|
var/obj/room_connection/c = new/obj/room_connection(west)
|
|
c.open_dir = WEST
|
|
c.room = p
|
|
rnd_cons.Add(c)
|
|
p.connections.Add(c)
|
|
|
|
var/list/multi_rooms = new/list()
|
|
for(var/obj/room_props/p_seed in rnd_rooms)
|
|
if(p_seed.connections.len >= 2) multi_rooms.Add(p_seed)
|
|
|
|
var/obj/room_props/selected = pick(multi_rooms)
|
|
copy_room_to(selected, origin)
|
|
|
|
var/list/unconnected = new/list()
|
|
for(var/obj/room_connection/R in range(selected.room_range, origin))
|
|
unconnected.Add(R)
|
|
|
|
var/rooms_left = RANDOM_Z_LEVEL_MAXROOMS
|
|
|
|
while(rooms_left > 0 && unconnected.len && multi_rooms.len)
|
|
var/obj/room_connection/newcon = pick(unconnected)
|
|
unconnected.Remove(newcon)
|
|
var/list/valid_rooms = new/list()
|
|
for(var/obj/room_props/valid in multi_rooms)
|
|
for(var/obj/room_connection/chk_con in valid.connections)
|
|
if(chk_con.open_dir == turn(newcon.open_dir, 180))
|
|
valid_rooms.Add(valid)
|
|
valid_rooms[valid] = chk_con
|
|
var/obj/room_props/selected_new = pick(valid_rooms)
|
|
var/turf/target_origin = newcon.loc
|
|
for(var/i=0, i <= selected_new.room_range, i++)
|
|
target_origin = get_step(target_origin, newcon.open_dir)
|
|
if(target_origin)
|
|
if(should_copy_room(selected_new, target_origin))
|
|
if(selected_new.room_unique)
|
|
multi_rooms.Remove(selected_new)
|
|
copy_room_to(selected_new, target_origin)
|
|
var/turf/conremturf = get_step(newcon.loc, newcon.open_dir)
|
|
var/obj/room_connection/todel = locate(/obj/room_connection) in conremturf
|
|
qdel(todel)
|
|
for(var/obj/room_connection/R1 in range(selected_new.room_range, target_origin))
|
|
if(!unconnected.Find(R1))
|
|
unconnected.Add(R1)
|
|
rooms_left--
|
|
qdel(newcon)
|
|
else
|
|
unconnected.Add(newcon) //Didnt fit, readd to open connections.
|
|
|
|
filling_holes:
|
|
for(var/obj/room_connection/C in unconnected)
|
|
var/turf/con_next = get_step(C.loc, C.open_dir)
|
|
if(istype(con_next, /turf/space))
|
|
if(prob(50))
|
|
for(var/turf/T in range(C, 1))
|
|
if(T.density)
|
|
new T.type(C.loc)
|
|
continue filling_holes
|
|
new/turf/simulated/wall(C.loc)
|
|
else
|
|
new/obj/machinery/door/airlock/external(C.loc)
|
|
else
|
|
if(prob(33))
|
|
new/obj/machinery/door/airlock/glass(C.loc)
|
|
|
|
cleanuprnd()
|
|
spawnmonsters()
|
|
spawndeco()
|
|
spawnrewards()
|
|
return |