The Mapping Update
Cleans up the map (again) Makes mining code more better
This commit is contained in:
@@ -73,7 +73,7 @@
|
||||
|
||||
/datum/component/butchering/proc/Butcher(mob/living/butcher, mob/living/meat)
|
||||
var/meat_quality = 50 + (bonus_modifier/10) //increases through quality of butchering tool, and through if it was butchered in the kitchen or not
|
||||
if(istype(get_area(butcher), /area/crew_quarters/kitchen))
|
||||
if(istype(get_area(butcher), /area/service/kitchen))
|
||||
meat_quality = meat_quality + 10
|
||||
var/turf/T = meat.drop_location()
|
||||
var/final_effectiveness = effectiveness - meat.butcher_difficulty
|
||||
|
||||
@@ -1,22 +1,24 @@
|
||||
/**
|
||||
* A holder for simple behaviour that can be attached to many different types
|
||||
*
|
||||
* Only one element of each type is instanced during game init.
|
||||
* Otherwise acts basically like a lightweight component.
|
||||
*/
|
||||
* A holder for simple behaviour that can be attached to many different types
|
||||
*
|
||||
* Only one element of each type is instanced during game init.
|
||||
* Otherwise acts basically like a lightweight component.
|
||||
*/
|
||||
/datum/element
|
||||
/// Option flags for element behaviour
|
||||
var/element_flags = NONE
|
||||
/**
|
||||
* The index of the first attach argument to consider for duplicate elements
|
||||
* Is only used when flags contains ELEMENT_BESPOKE
|
||||
*
|
||||
* Is only used when flags contains [ELEMENT_BESPOKE]
|
||||
*
|
||||
* This is infinity so you must explicitly set this
|
||||
*/
|
||||
var/id_arg_index = INFINITY
|
||||
|
||||
/// Activates the functionality defined by the element on the given target datum
|
||||
/datum/element/proc/Attach(datum/target)
|
||||
SHOULD_CALL_PARENT(1)
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
if(type == /datum/element)
|
||||
return ELEMENT_INCOMPATIBLE
|
||||
SEND_SIGNAL(target, COMSIG_ELEMENT_ATTACH, src)
|
||||
@@ -25,8 +27,10 @@
|
||||
|
||||
/// Deactivates the functionality defines by the element on the given datum
|
||||
/datum/element/proc/Detach(datum/source, force)
|
||||
SIGNAL_HANDLER
|
||||
|
||||
SEND_SIGNAL(source, COMSIG_ELEMENT_DETACH, src)
|
||||
SHOULD_CALL_PARENT(1)
|
||||
SHOULD_CALL_PARENT(TRUE)
|
||||
UnregisterSignal(source, COMSIG_PARENT_QDELETING)
|
||||
|
||||
/datum/element/Destroy(force)
|
||||
@@ -45,9 +49,9 @@
|
||||
CRASH("Incompatible [arguments[1]] assigned to a [type]! args: [json_encode(args)]")
|
||||
|
||||
/**
|
||||
* Finds the singleton for the element type given and detaches it from src
|
||||
* You only need additional arguments beyond the type if you're using ELEMENT_BESPOKE
|
||||
*/
|
||||
* Finds the singleton for the element type given and detaches it from src
|
||||
* You only need additional arguments beyond the type if you're using [ELEMENT_BESPOKE]
|
||||
*/
|
||||
/datum/proc/_RemoveElement(list/arguments)
|
||||
var/datum/element/ele = SSdcs.GetElement(arguments)
|
||||
ele.Detach(src)
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
/datum/element/turf_z_transparency
|
||||
var/show_bottom_level = FALSE
|
||||
|
||||
///This proc sets up the signals to handle updating viscontents when turfs above/below update. Handle plane and layer here too so that they don't cover other obs/turfs in Dream Maker
|
||||
/datum/element/turf_z_transparency/Attach(datum/target, show_bottom_level = TRUE)
|
||||
. = ..()
|
||||
if(!isturf(target))
|
||||
return ELEMENT_INCOMPATIBLE
|
||||
|
||||
var/turf/our_turf = target
|
||||
|
||||
src.show_bottom_level = show_bottom_level
|
||||
|
||||
our_turf.plane = OPENSPACE_PLANE
|
||||
our_turf.layer = OPENSPACE_LAYER
|
||||
|
||||
RegisterSignal(target, COMSIG_TURF_MULTIZ_DEL, .proc/on_multiz_turf_del)
|
||||
RegisterSignal(target, COMSIG_TURF_MULTIZ_NEW, .proc/on_multiz_turf_new)
|
||||
|
||||
ADD_TRAIT(our_turf, TURF_Z_TRANSPARENT_TRAIT, TURF_TRAIT)
|
||||
|
||||
|
||||
update_multiz(our_turf, TRUE, TRUE)
|
||||
|
||||
/datum/element/turf_z_transparency/Detach(datum/source, force)
|
||||
. = ..()
|
||||
var/turf/our_turf = source
|
||||
our_turf.vis_contents.len = 0
|
||||
REMOVE_TRAIT(our_turf, TURF_Z_TRANSPARENT_TRAIT, TURF_TRAIT)
|
||||
|
||||
///Updates the viscontents or underlays below this tile.
|
||||
/datum/element/turf_z_transparency/proc/update_multiz(turf/our_turf, prune_on_fail = FALSE, init = FALSE)
|
||||
var/turf/below_turf = our_turf.below()
|
||||
if(!below_turf)
|
||||
our_turf.vis_contents.len = 0
|
||||
if(!show_bottom_level(our_turf) && prune_on_fail) //If we cant show whats below, and we prune on fail, change the turf to plating as a fallback
|
||||
our_turf.ChangeTurf(/turf/open/floor/plating, flags = CHANGETURF_INHERIT_AIR)
|
||||
return FALSE
|
||||
if(init)
|
||||
our_turf.vis_contents += below_turf
|
||||
if(isclosedturf(our_turf)) //Show girders below closed turfs
|
||||
var/mutable_appearance/girder_underlay = mutable_appearance('icons/obj/structures.dmi', "girder", layer = TURF_LAYER-0.01)
|
||||
girder_underlay.appearance_flags = RESET_ALPHA | RESET_COLOR
|
||||
our_turf.underlays += girder_underlay
|
||||
var/mutable_appearance/plating_underlay = mutable_appearance('icons/turf/floors.dmi', "plating", layer = TURF_LAYER-0.02)
|
||||
plating_underlay = RESET_ALPHA | RESET_COLOR
|
||||
our_turf.underlays += plating_underlay
|
||||
return TRUE
|
||||
|
||||
/datum/element/turf_z_transparency/proc/on_multiz_turf_del(turf/our_turf, turf/T, dir)
|
||||
SIGNAL_HANDLER
|
||||
if(dir != DOWN)
|
||||
return
|
||||
update_multiz(our_turf)
|
||||
|
||||
/datum/element/turf_z_transparency/proc/on_multiz_turf_new(turf/our_turf, turf/T, dir)
|
||||
SIGNAL_HANDLER
|
||||
if(dir != DOWN)
|
||||
return
|
||||
update_multiz(our_turf)
|
||||
|
||||
///Called when there is no real turf below this turf
|
||||
/datum/element/turf_z_transparency/proc/show_bottom_level(turf/our_turf)
|
||||
if(!show_bottom_level)
|
||||
return FALSE
|
||||
var/turf/path = SSmapping.level_trait(our_turf.z, ZTRAIT_BASETURF) || /turf/open/space
|
||||
if(!ispath(path))
|
||||
path = text2path(path)
|
||||
if(!ispath(path))
|
||||
warning("Z-level [our_turf.z] has invalid baseturf '[SSmapping.level_trait(our_turf.z, ZTRAIT_BASETURF)]'")
|
||||
path = /turf/open/space
|
||||
var/mutable_appearance/underlay_appearance = mutable_appearance(initial(path.icon), initial(path.icon_state), layer = TURF_LAYER-0.02, plane = PLANE_SPACE)
|
||||
underlay_appearance.appearance_flags = RESET_ALPHA | RESET_COLOR
|
||||
our_turf.underlays += underlay_appearance
|
||||
return TRUE
|
||||
@@ -5,8 +5,8 @@
|
||||
// effectout: effect to show right after teleportation
|
||||
// asoundin: soundfile to play before teleportation
|
||||
// asoundout: soundfile to play after teleportation
|
||||
// no_effects: disable the default effectin/effectout of sparks
|
||||
// forceMove: if false, teleport will use Move() proc (dense objects will prevent teleportation)
|
||||
// no_effects: disable the default effectin/effectout of sparks
|
||||
// forced: whether or not to ignore no_teleport
|
||||
/proc/do_teleport(atom/movable/teleatom, atom/destination, precision=null, forceMove = TRUE, datum/effect_system/effectin=null, datum/effect_system/effectout=null, asoundin=null, asoundout=null, no_effects=FALSE, channel=TELEPORT_CHANNEL_BLUESPACE, forced = FALSE)
|
||||
// teleporting most effects just deletes them
|
||||
@@ -15,7 +15,8 @@
|
||||
)) - typecacheof(list(
|
||||
/obj/effect/dummy/chameleon,
|
||||
/obj/effect/wisp,
|
||||
/obj/effect/mob_spawn
|
||||
/obj/effect/mob_spawn,
|
||||
/obj/effect/immovablerod,
|
||||
))
|
||||
if(delete_atoms[teleatom.type])
|
||||
qdel(teleatom)
|
||||
@@ -66,7 +67,7 @@
|
||||
|
||||
var/area/A = get_area(curturf)
|
||||
var/area/B = get_area(destturf)
|
||||
if(!forced && (HAS_TRAIT(teleatom, TRAIT_NO_TELEPORT) || A.noteleport || B.noteleport))
|
||||
if(!forced && (HAS_TRAIT(teleatom, TRAIT_NO_TELEPORT) || (A.area_flags & NOTELEPORT) || (B.area_flags & NOTELEPORT)))
|
||||
return FALSE
|
||||
|
||||
if(SEND_SIGNAL(destturf, COMSIG_ATOM_INTERCEPT_TELEPORT, channel, curturf, destturf))
|
||||
@@ -99,13 +100,13 @@
|
||||
/proc/tele_play_specials(atom/movable/teleatom, atom/location, datum/effect_system/effect, sound)
|
||||
if (location && !isobserver(teleatom))
|
||||
if (sound)
|
||||
playsound(location, sound, 60, 1)
|
||||
playsound(location, sound, 60, TRUE)
|
||||
if (effect)
|
||||
effect.attach(location)
|
||||
effect.start()
|
||||
|
||||
// Safe location finder
|
||||
/proc/find_safe_turf(zlevel, list/zlevels, extended_safety_checks = FALSE)
|
||||
/proc/find_safe_turf(zlevel, list/zlevels, extended_safety_checks = FALSE, dense_atoms = TRUE)
|
||||
if(!zlevels)
|
||||
if (zlevel)
|
||||
zlevels = list(zlevel)
|
||||
@@ -122,12 +123,17 @@
|
||||
if(!isfloorturf(random_location))
|
||||
continue
|
||||
var/turf/open/floor/F = random_location
|
||||
var/area/destination_area = F.loc
|
||||
|
||||
if(cycle < 300 && destination_area.area_flags & NOTELEPORT)//if the area is mostly NOTELEPORT (centcom) we gotta give up on this fantasy at some point.
|
||||
continue
|
||||
if(!F.air)
|
||||
continue
|
||||
|
||||
var/datum/gas_mixture/A = F.air
|
||||
var/list/A_gases = A.get_gases()
|
||||
var/trace_gases
|
||||
for(var/id in A.get_gases())
|
||||
for(var/id in A_gases)
|
||||
if(id in GLOB.hardcoded_gases)
|
||||
continue
|
||||
trace_gases = TRUE
|
||||
@@ -136,7 +142,7 @@
|
||||
// Can most things breathe?
|
||||
if(trace_gases)
|
||||
continue
|
||||
if(A.get_moles(/datum/gas/oxygen) < 16)
|
||||
if(A.get_moles(/datum/gas/oxygen) >= 16)
|
||||
continue
|
||||
if(A.get_moles(/datum/gas/plasma))
|
||||
continue
|
||||
@@ -156,6 +162,16 @@
|
||||
if(!L.is_safe())
|
||||
continue
|
||||
|
||||
// Check that we're not warping onto a table or window
|
||||
if(!dense_atoms)
|
||||
var/density_found = FALSE
|
||||
for(var/atom/movable/found_movable in F)
|
||||
if(found_movable.density)
|
||||
density_found = TRUE
|
||||
break
|
||||
if(density_found)
|
||||
continue
|
||||
|
||||
// DING! You have passed the gauntlet, and are "probably" safe.
|
||||
return F
|
||||
|
||||
@@ -167,9 +183,11 @@
|
||||
if(T.is_transition_turf())
|
||||
continue // Avoid picking these.
|
||||
var/area/A = T.loc
|
||||
if(!A.noteleport)
|
||||
if(!(A.area_flags & NOTELEPORT))
|
||||
posturfs.Add(T)
|
||||
return posturfs
|
||||
|
||||
/proc/get_teleport_turf(turf/center, precision = 0)
|
||||
return safepick(get_teleport_turfs(center, precision))
|
||||
var/list/turfs = get_teleport_turfs(center, precision)
|
||||
if (length(turfs))
|
||||
return pick(turfs)
|
||||
|
||||
@@ -0,0 +1,144 @@
|
||||
/datum/map_generator/cave_generator
|
||||
var/name = "Cave Generator"
|
||||
///Weighted list of the types that spawns if the turf is open
|
||||
var/open_turf_types = list(/turf/open/floor/plating/asteroid/airless = 1)
|
||||
///Weighted list of the types that spawns if the turf is closed
|
||||
var/closed_turf_types = list(/turf/closed/mineral/random = 1)
|
||||
|
||||
|
||||
///Weighted list of mobs that can spawn in the area.
|
||||
var/list/mob_spawn_list
|
||||
// Weighted list of Megafauna that can spawn in the caves
|
||||
var/list/megafauna_spawn_list
|
||||
///Weighted list of flora that can spawn in the area.
|
||||
var/list/flora_spawn_list
|
||||
///Weighted list of extra features that can spawn in the area, such as geysers.
|
||||
var/list/feature_spawn_list
|
||||
|
||||
|
||||
///Base chance of spawning a mob
|
||||
var/mob_spawn_chance = 6
|
||||
///Base chance of spawning flora
|
||||
var/flora_spawn_chance = 2
|
||||
///Base chance of spawning features
|
||||
var/feature_spawn_chance = 0.1
|
||||
///Unique ID for this spawner
|
||||
var/string_gen
|
||||
|
||||
///Chance of cells starting closed
|
||||
var/initial_closed_chance = 45
|
||||
///Amount of smoothing iterations
|
||||
var/smoothing_iterations = 20
|
||||
///How much neighbours does a dead cell need to become alive
|
||||
var/birth_limit = 4
|
||||
///How little neighbours does a alive cell need to die
|
||||
var/death_limit = 3
|
||||
|
||||
/datum/map_generator/cave_generator/New()
|
||||
. = ..()
|
||||
if(!mob_spawn_list)
|
||||
mob_spawn_list = list(/mob/living/simple_animal/hostile/asteroid/goldgrub = 1, /mob/living/simple_animal/hostile/asteroid/goliath = 5, /mob/living/simple_animal/hostile/asteroid/basilisk = 4, /mob/living/simple_animal/hostile/asteroid/hivelord = 3)
|
||||
if(!megafauna_spawn_list)
|
||||
megafauna_spawn_list = GLOB.megafauna_spawn_list
|
||||
if(!flora_spawn_list)
|
||||
flora_spawn_list = list(/obj/structure/flora/ash/leaf_shroom = 2 , /obj/structure/flora/ash/cap_shroom = 2 , /obj/structure/flora/ash/stem_shroom = 2 , /obj/structure/flora/ash/cacti = 1, /obj/structure/flora/ash/tall_shroom = 2)
|
||||
if(!feature_spawn_list)
|
||||
feature_spawn_list = list(/obj/structure/geyser/random = 1)
|
||||
|
||||
/datum/map_generator/cave_generator/generate_terrain(list/turfs)
|
||||
. = ..()
|
||||
var/start_time = REALTIMEOFDAY
|
||||
string_gen = rustg_cnoise_generate("[initial_closed_chance]", "[smoothing_iterations]", "[birth_limit]", "[death_limit]", "[world.maxx]", "[world.maxy]") //Generate the raw CA data
|
||||
|
||||
for(var/i in turfs) //Go through all the turfs and generate them
|
||||
var/turf/gen_turf = i
|
||||
|
||||
var/area/A = gen_turf.loc
|
||||
if(!(A.area_flags & CAVES_ALLOWED))
|
||||
continue
|
||||
|
||||
var/closed = text2num(string_gen[world.maxx * (gen_turf.y - 1) + gen_turf.x])
|
||||
|
||||
var/stored_flags
|
||||
if(gen_turf.flags_1 & NO_RUINS_1)
|
||||
stored_flags |= NO_RUINS_1
|
||||
|
||||
var/turf/new_turf = pickweight(closed ? closed_turf_types : open_turf_types)
|
||||
|
||||
new_turf = gen_turf.ChangeTurf(new_turf, initial(new_turf.baseturfs), CHANGETURF_DEFER_CHANGE)
|
||||
|
||||
new_turf.flags_1 |= stored_flags
|
||||
|
||||
if(!closed)//Open turfs have some special behavior related to spawning flora and mobs.
|
||||
|
||||
var/turf/open/new_open_turf = new_turf
|
||||
|
||||
///Spawning isn't done in procs to save on overhead on the 60k turfs we're going through.
|
||||
|
||||
//FLORA SPAWNING HERE
|
||||
var/atom/spawned_flora
|
||||
if(flora_spawn_list && prob(flora_spawn_chance))
|
||||
var/can_spawn = TRUE
|
||||
|
||||
if(!(A.area_flags & FLORA_ALLOWED))
|
||||
can_spawn = FALSE
|
||||
if(can_spawn)
|
||||
spawned_flora = pickweight(flora_spawn_list)
|
||||
spawned_flora = new spawned_flora(new_open_turf)
|
||||
|
||||
//FEATURE SPAWNING HERE
|
||||
var/atom/spawned_feature
|
||||
if(feature_spawn_list && prob(feature_spawn_chance))
|
||||
var/can_spawn = TRUE
|
||||
|
||||
if(!(A.area_flags & FLORA_ALLOWED)) //checks the same flag because lol dunno
|
||||
can_spawn = FALSE
|
||||
|
||||
var/atom/picked_feature = pickweight(feature_spawn_list)
|
||||
|
||||
for(var/obj/structure/F in range(7, new_open_turf))
|
||||
if(istype(F, picked_feature))
|
||||
can_spawn = FALSE
|
||||
|
||||
if(can_spawn)
|
||||
spawned_feature = new picked_feature(new_open_turf)
|
||||
|
||||
//MOB SPAWNING HERE
|
||||
|
||||
if(mob_spawn_list && !spawned_flora && !spawned_feature && prob(mob_spawn_chance))
|
||||
var/can_spawn = TRUE
|
||||
|
||||
if(!(A.area_flags & MOB_SPAWN_ALLOWED))
|
||||
can_spawn = FALSE
|
||||
|
||||
var/atom/picked_mob = pickweight(mob_spawn_list)
|
||||
|
||||
if(picked_mob == SPAWN_MEGAFAUNA) //
|
||||
if((A.area_flags & MEGAFAUNA_SPAWN_ALLOWED) && megafauna_spawn_list?.len) //this is danger. it's boss time.
|
||||
picked_mob = pickweight(megafauna_spawn_list)
|
||||
else //this is not danger, don't spawn a boss, spawn something else
|
||||
picked_mob = pickweight(mob_spawn_list - SPAWN_MEGAFAUNA) //What if we used 100% of the brain...and did something (slightly) less shit than a while loop?
|
||||
|
||||
for(var/thing in urange(12, new_open_turf)) //prevents mob clumps
|
||||
if(!ishostile(thing) && !istype(thing, /obj/structure/spawner))
|
||||
continue
|
||||
if((ispath(picked_mob, /mob/living/simple_animal/hostile/megafauna) || ismegafauna(thing)) && get_dist(new_open_turf, thing) <= 7)
|
||||
can_spawn = FALSE //if there's a megafauna within standard view don't spawn anything at all
|
||||
break
|
||||
if(ispath(picked_mob, /mob/living/simple_animal/hostile/asteroid) || istype(thing, /mob/living/simple_animal/hostile/asteroid))
|
||||
can_spawn = FALSE //if the random is a standard mob, avoid spawning if there's another one within 12 tiles
|
||||
break
|
||||
if((ispath(picked_mob, /obj/structure/spawner/lavaland) || istype(thing, /obj/structure/spawner/lavaland)) && get_dist(new_open_turf, thing) <= 2)
|
||||
can_spawn = FALSE //prevents tendrils spawning in each other's collapse range
|
||||
break
|
||||
|
||||
if(can_spawn)
|
||||
if(ispath(picked_mob, /mob/living/simple_animal/hostile/megafauna/bubblegum)) //there can be only one bubblegum, so don't waste spawns on it
|
||||
megafauna_spawn_list.Remove(picked_mob)
|
||||
|
||||
new picked_mob(new_open_turf)
|
||||
CHECK_TICK
|
||||
|
||||
var/message = "[name] finished in [(REALTIMEOFDAY - start_time)/10]s!"
|
||||
to_chat(world, "<span class='boldannounce'>[message]</span>")
|
||||
log_world(message)
|
||||
@@ -0,0 +1,28 @@
|
||||
/datum/map_generator/cave_generator/icemoon
|
||||
open_turf_types = list(/turf/open/floor/plating/asteroid/snow/icemoon = 19, /turf/open/floor/plating/ice/icemoon = 1)
|
||||
closed_turf_types = list(/turf/closed/mineral/random/snow = 1)
|
||||
|
||||
|
||||
mob_spawn_list = list(/mob/living/simple_animal/hostile/asteroid/wolf = 50, /obj/structure/spawner/ice_moon = 3, \
|
||||
/mob/living/simple_animal/hostile/asteroid/polarbear = 30, /obj/structure/spawner/ice_moon/polarbear = 3, \
|
||||
/mob/living/simple_animal/hostile/asteroid/hivelord/legion/snow = 50, /mob/living/simple_animal/hostile/asteroid/goldgrub = 10, \
|
||||
/mob/living/simple_animal/hostile/asteroid/lobstrosity = 15)
|
||||
flora_spawn_list = list(/obj/structure/flora/tree/pine = 2, /obj/structure/flora/rock/icy = 2, /obj/structure/flora/rock/pile/icy = 2, /obj/structure/flora/grass/both = 6, /obj/structure/flora/ash = 2)
|
||||
feature_spawn_list = list(/obj/structure/geyser/random = 1)
|
||||
|
||||
/datum/map_generator/cave_generator/icemoon/surface
|
||||
flora_spawn_chance = 4
|
||||
mob_spawn_list = null
|
||||
initial_closed_chance = 53
|
||||
birth_limit = 5
|
||||
death_limit = 4
|
||||
smoothing_iterations = 10
|
||||
|
||||
/datum/map_generator/cave_generator/icemoon/deep
|
||||
closed_turf_types = list(/turf/closed/mineral/random/snow/underground = 1)
|
||||
mob_spawn_list = list(/mob/living/simple_animal/hostile/asteroid/ice_demon = 50, /obj/structure/spawner/ice_moon/demonic_portal = 3, \
|
||||
/mob/living/simple_animal/hostile/asteroid/ice_whelp = 30, /obj/structure/spawner/ice_moon/demonic_portal/ice_whelp = 3, \
|
||||
/mob/living/simple_animal/hostile/asteroid/hivelord/legion/snow = 50, /obj/structure/spawner/ice_moon/demonic_portal/snowlegion = 3, \
|
||||
SPAWN_MEGAFAUNA = 2)
|
||||
megafauna_spawn_list = list(/mob/living/simple_animal/hostile/megafauna/colossus = 1)
|
||||
flora_spawn_list = list(/obj/structure/flora/rock/icy = 6, /obj/structure/flora/rock/pile/icy = 6, /obj/structure/flora/ash = 1)
|
||||
@@ -0,0 +1,16 @@
|
||||
/datum/map_generator/cave_generator/lavaland
|
||||
open_turf_types = list(/turf/open/floor/plating/asteroid/basalt/lava_land_surface = 1)
|
||||
closed_turf_types = list(/turf/closed/mineral/random/volcanic = 1)
|
||||
|
||||
|
||||
mob_spawn_list = list(/mob/living/simple_animal/hostile/asteroid/goliath/beast/random = 50, /obj/structure/spawner/lavaland/goliath = 3, \
|
||||
/mob/living/simple_animal/hostile/asteroid/basilisk/watcher/random = 40, /obj/structure/spawner/lavaland = 2, \
|
||||
/mob/living/simple_animal/hostile/asteroid/hivelord/legion/random = 30, /obj/structure/spawner/lavaland/legion = 3, \
|
||||
SPAWN_MEGAFAUNA = 4, /mob/living/simple_animal/hostile/asteroid/goldgrub = 10)
|
||||
flora_spawn_list = list(/obj/structure/flora/ash/leaf_shroom = 2 , /obj/structure/flora/ash/cap_shroom = 2 , /obj/structure/flora/ash/stem_shroom = 2 , /obj/structure/flora/ash/cacti = 1, /obj/structure/flora/ash/tall_shroom = 2)
|
||||
feature_spawn_list = list(/obj/structure/geyser/random = 1)
|
||||
|
||||
initial_closed_chance = 45
|
||||
smoothing_iterations = 50
|
||||
birth_limit = 4
|
||||
death_limit = 3
|
||||
@@ -0,0 +1,91 @@
|
||||
//the random offset applied to square coordinates, causes intermingling at biome borders
|
||||
#define BIOME_RANDOM_SQUARE_DRIFT 2
|
||||
|
||||
/datum/map_generator/jungle_generator
|
||||
///2D list of all biomes based on heat and humidity combos.
|
||||
var/list/possible_biomes = list(
|
||||
BIOME_LOW_HEAT = list(
|
||||
BIOME_LOW_HUMIDITY = /datum/biome/plains,
|
||||
BIOME_LOWMEDIUM_HUMIDITY = /datum/biome/mudlands,
|
||||
BIOME_HIGHMEDIUM_HUMIDITY = /datum/biome/mudlands,
|
||||
BIOME_HIGH_HUMIDITY = /datum/biome/water
|
||||
),
|
||||
BIOME_LOWMEDIUM_HEAT = list(
|
||||
BIOME_LOW_HUMIDITY = /datum/biome/plains,
|
||||
BIOME_LOWMEDIUM_HUMIDITY = /datum/biome/jungle,
|
||||
BIOME_HIGHMEDIUM_HUMIDITY = /datum/biome/jungle,
|
||||
BIOME_HIGH_HUMIDITY = /datum/biome/mudlands
|
||||
),
|
||||
BIOME_HIGHMEDIUM_HEAT = list(
|
||||
BIOME_LOW_HUMIDITY = /datum/biome/plains,
|
||||
BIOME_LOWMEDIUM_HUMIDITY = /datum/biome/plains,
|
||||
BIOME_HIGHMEDIUM_HUMIDITY = /datum/biome/jungle/deep,
|
||||
BIOME_HIGH_HUMIDITY = /datum/biome/jungle
|
||||
),
|
||||
BIOME_HIGH_HEAT = list(
|
||||
BIOME_LOW_HUMIDITY = /datum/biome/wasteland,
|
||||
BIOME_LOWMEDIUM_HUMIDITY = /datum/biome/plains,
|
||||
BIOME_HIGHMEDIUM_HUMIDITY = /datum/biome/jungle,
|
||||
BIOME_HIGH_HUMIDITY = /datum/biome/jungle/deep
|
||||
)
|
||||
)
|
||||
///Used to select "zoom" level into the perlin noise, higher numbers result in slower transitions
|
||||
var/perlin_zoom = 65
|
||||
|
||||
///Seeds the rust-g perlin noise with a random number.
|
||||
/datum/map_generator/jungle_generator/generate_terrain(list/turfs)
|
||||
. = ..()
|
||||
var/height_seed = rand(0, 50000)
|
||||
var/humidity_seed = rand(0, 50000)
|
||||
var/heat_seed = rand(0, 50000)
|
||||
|
||||
for(var/t in turfs) //Go through all the turfs and generate them
|
||||
var/turf/gen_turf = t
|
||||
var/drift_x = (gen_turf.x + rand(-BIOME_RANDOM_SQUARE_DRIFT, BIOME_RANDOM_SQUARE_DRIFT)) / perlin_zoom
|
||||
var/drift_y = (gen_turf.y + rand(-BIOME_RANDOM_SQUARE_DRIFT, BIOME_RANDOM_SQUARE_DRIFT)) / perlin_zoom
|
||||
|
||||
var/height = text2num(rustg_noise_get_at_coordinates("[height_seed]", "[drift_x]", "[drift_y]"))
|
||||
|
||||
|
||||
var/datum/biome/selected_biome
|
||||
if(height <= 0.85) //If height is less than 0.85, we generate biomes based on the heat and humidity of the area.
|
||||
var/humidity = text2num(rustg_noise_get_at_coordinates("[humidity_seed]", "[drift_x]", "[drift_y]"))
|
||||
var/heat = text2num(rustg_noise_get_at_coordinates("[heat_seed]", "[drift_x]", "[drift_y]"))
|
||||
var/heat_level //Type of heat zone we're in LOW-MEDIUM-HIGH
|
||||
var/humidity_level //Type of humidity zone we're in LOW-MEDIUM-HIGH
|
||||
|
||||
switch(heat)
|
||||
if(0 to 0.25)
|
||||
heat_level = BIOME_LOW_HEAT
|
||||
if(0.25 to 0.5)
|
||||
heat_level = BIOME_LOWMEDIUM_HEAT
|
||||
if(0.5 to 0.75)
|
||||
heat_level = BIOME_HIGHMEDIUM_HEAT
|
||||
if(0.75 to 1)
|
||||
heat_level = BIOME_HIGH_HEAT
|
||||
switch(humidity)
|
||||
if(0 to 0.25)
|
||||
humidity_level = BIOME_LOW_HUMIDITY
|
||||
if(0.25 to 0.5)
|
||||
humidity_level = BIOME_LOWMEDIUM_HUMIDITY
|
||||
if(0.5 to 0.75)
|
||||
humidity_level = BIOME_HIGHMEDIUM_HUMIDITY
|
||||
if(0.75 to 1)
|
||||
humidity_level = BIOME_HIGH_HUMIDITY
|
||||
selected_biome = possible_biomes[heat_level][humidity_level]
|
||||
else //Over 0.85; It's a mountain
|
||||
selected_biome = /datum/biome/mountain
|
||||
selected_biome = SSmapping.biomes[selected_biome] //Get the instance of this biome from SSmapping
|
||||
selected_biome.generate_turf(gen_turf)
|
||||
CHECK_TICK
|
||||
|
||||
/turf/open/genturf
|
||||
name = "ungenerated turf"
|
||||
desc = "If you see this, and you're not a ghost, yell at coders"
|
||||
icon = 'icons/turf/debug.dmi'
|
||||
icon_state = "genturf"
|
||||
|
||||
/area/mine/planetgeneration
|
||||
name = "planet generation area"
|
||||
dynamic_lighting = DYNAMIC_LIGHTING_DISABLED
|
||||
map_generator = /datum/map_generator/jungle_generator
|
||||
@@ -0,0 +1,6 @@
|
||||
///This type is responsible for any map generation behavior that is done in areas, override this to allow for area-specific map generation. This generation is ran by areas in initialize.
|
||||
/datum/map_generator
|
||||
|
||||
///This proc will be ran by areas on Initialize, and provides the areas turfs as argument to allow for generation.
|
||||
/datum/map_generator/proc/generate_terrain(list/turfs)
|
||||
return
|
||||
@@ -0,0 +1,53 @@
|
||||
///This datum handles the transitioning from a turf to a specific biome, and handles spawning decorative structures and mobs.
|
||||
/datum/biome
|
||||
///Type of turf this biome creates
|
||||
var/turf_type
|
||||
///Chance of having a structure from the flora types list spawn
|
||||
var/flora_density = 0
|
||||
///Chance of having a mob from the fauna types list spawn
|
||||
var/fauna_density = 0
|
||||
///list of type paths of objects that can be spawned when the turf spawns flora
|
||||
var/list/flora_types = list(/obj/structure/flora/grass/jungle)
|
||||
///list of type paths of mobs that can be spawned when the turf spawns fauna
|
||||
var/list/fauna_types = list()
|
||||
|
||||
///This proc handles the creation of a turf of a specific biome type
|
||||
/datum/biome/proc/generate_turf(turf/gen_turf)
|
||||
gen_turf.ChangeTurf(turf_type, null, CHANGETURF_DEFER_CHANGE)
|
||||
if(length(fauna_types) && prob(fauna_density))
|
||||
var/mob/fauna = pick(fauna_types)
|
||||
new fauna(gen_turf)
|
||||
|
||||
if(length(flora_types) && prob(flora_density))
|
||||
var/obj/structure/flora = pick(flora_types)
|
||||
new flora(gen_turf)
|
||||
|
||||
/datum/biome/mudlands
|
||||
// turf_type = /turf/open/floor/plating/dirt/jungle/dark
|
||||
turf_type = /turf/open/floor/plating/dirt/jungle
|
||||
flora_types = list(/obj/structure/flora/grass/jungle,/obj/structure/flora/grass/jungle/b, /obj/structure/flora/rock/jungle, /obj/structure/flora/rock/pile/largejungle)
|
||||
flora_density = 3
|
||||
|
||||
/datum/biome/plains
|
||||
// turf_type = /turf/open/floor/plating/grass/jungle
|
||||
turf_type = /turf/open/floor/grass
|
||||
flora_types = list(/obj/structure/flora/grass/jungle,/obj/structure/flora/grass/jungle/b, /obj/structure/flora/tree/jungle, /obj/structure/flora/rock/jungle, /obj/structure/flora/junglebush, /obj/structure/flora/junglebush/b, /obj/structure/flora/junglebush/c, /obj/structure/flora/junglebush/large, /obj/structure/flora/rock/pile/largejungle)
|
||||
flora_density = 15
|
||||
|
||||
/datum/biome/jungle
|
||||
// turf_type = /turf/open/floor/plating/grass/jungle
|
||||
turf_type = /turf/open/floor/grass
|
||||
flora_types = list(/obj/structure/flora/grass/jungle,/obj/structure/flora/grass/jungle/b, /obj/structure/flora/tree/jungle, /obj/structure/flora/rock/jungle, /obj/structure/flora/junglebush, /obj/structure/flora/junglebush/b, /obj/structure/flora/junglebush/c, /obj/structure/flora/junglebush/large, /obj/structure/flora/rock/pile/largejungle)
|
||||
flora_density = 40
|
||||
|
||||
/datum/biome/jungle/deep
|
||||
flora_density = 65
|
||||
|
||||
/datum/biome/wasteland
|
||||
// turf_type = /turf/open/floor/plating/dirt/jungle/wasteland
|
||||
turf_type = /turf/open/floor/plating/dirt/jungle
|
||||
/datum/biome/water
|
||||
turf_type = /turf/open/water/jungle
|
||||
|
||||
/datum/biome/mountain
|
||||
turf_type = /turf/closed/mineral/random //jungle
|
||||
@@ -175,7 +175,7 @@
|
||||
return TRUE
|
||||
if(CHECK_MOBILITY(D, MOBILITY_MOVE) || !restraining)
|
||||
A.do_attack_animation(D, ATTACK_EFFECT_PUNCH)
|
||||
if(damage >= stunthreshold)
|
||||
if(damage >= stunthreshold)
|
||||
I = D.get_active_held_item()
|
||||
D.visible_message("<span class='warning'>[A] strikes [D]'s jaw with their hand!</span>", \
|
||||
"<span class='userdanger'>[A] strikes your jaw, disorienting you!</span>")
|
||||
@@ -222,9 +222,10 @@
|
||||
///Subtype of CQC. Only used for the chef.
|
||||
/datum/martial_art/cqc/under_siege
|
||||
name = "Close Quarters Cooking"
|
||||
var/list/valid_areas = list(/area/service/kitchen)
|
||||
|
||||
///Prevents use if the cook is not in the kitchen.
|
||||
/datum/martial_art/cqc/under_siege/can_use(mob/living/carbon/human/H) //this is used to make chef CQC only work in kitchen
|
||||
if(!istype(get_area(H), /area/crew_quarters/kitchen))
|
||||
/datum/martial_art/cqc/under_siege/can_use(mob/living/owner) //this is used to make chef CQC only work in kitchen
|
||||
if(!is_type_in_list(get_area(owner), valid_areas))
|
||||
return FALSE
|
||||
return ..()
|
||||
|
||||
@@ -18,11 +18,11 @@
|
||||
|
||||
area_type = /area
|
||||
protected_areas = list(/area/maintenance, /area/ai_monitored/turret_protected/ai_upload, /area/ai_monitored/turret_protected/ai_upload_foyer,
|
||||
/area/ai_monitored/turret_protected/ai, /area/storage/emergency/starboard, /area/storage/emergency/port, /area/shuttle, /area/security/prison, /area/ruin, /area/space/nearstation, /area/icemoon)
|
||||
/area/ai_monitored/turret_protected/ai, /area/commons/storage/emergency/starboard, /area/commons/storage/emergency/port, /area/shuttle, /area/security/prison/safe, /area/security/prison/toilet)
|
||||
target_trait = ZTRAIT_STATION
|
||||
|
||||
immunity_type = "rad"
|
||||
|
||||
|
||||
var/radiation_intensity = 100
|
||||
|
||||
/datum/weather/rad_storm/telegraph()
|
||||
|
||||
Reference in New Issue
Block a user