Skip to content

Commit

Permalink
adds in base forest and mushroom forest generation
Browse files Browse the repository at this point in the history
  • Loading branch information
dwasint committed Jun 28, 2024
1 parent 0806a20 commit 8cd5586
Show file tree
Hide file tree
Showing 40 changed files with 1,111 additions and 40 deletions.
3 changes: 3 additions & 0 deletions code/__DEFINES/flags.dm
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,9 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204
#define NO_CLEARING (1<<7)

#define TURF_WEATHER (1<<8) //monkestation edit
/// This atom is a pseudo-floor that blocks map generation's checkPlaceAtom() from placing things like trees ontop of it.
#define TURF_BLOCKS_POPULATE_TERRAIN_FLORAFEATURES (1<<9)

////////////////Area flags\\\\\\\\\\\\\\
/// If it's a valid territory for cult summoning or the CRAB-17 phone to spawn
#define VALID_TERRITORY (1<<0)
Expand Down
4 changes: 3 additions & 1 deletion code/__DEFINES/icon_smoothing.dm
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,9 @@ DEFINE_BITFIELD(smoothing_flags, list(
#define SMOOTH_GROUP_LOWERED_PLASTEEL S_TURF(61)
#define SMOOTH_GROUP_FISSURE S_TURF(62)

#define MAX_S_TURF 62 //Always match this value with the one above it.
#define SMOOTH_GROUP_MUSHROOM S_TURF(63)

#define MAX_S_TURF 63 //Always match this value with the one above it.

#define S_OBJ(num) ("-" + #num + ",")
/* /obj included */
Expand Down
2 changes: 2 additions & 0 deletions code/__DEFINES/~monkestation/atmospherics.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
//ATMOS MIX IDS
#define FOREST_DEFAULT_ATMOS "FOREST_ATMOS"
27 changes: 27 additions & 0 deletions code/__DEFINES/~monkestation/blackboard.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@

// Hiding AI blackboard keys

/// Whether or not the mob is currently hiding.
#define BB_HIDING_HIDDEN "BB_hiding_hidden"
/// The typecache (populated on `Initialize()` with the first argument of
/// `/datum/element/can_hide/basic/New()`) of turfs that our mob can hide onto.
#define BB_HIDING_CAN_HIDE_ON "BB_hiding_can_hide_on"
/// The aggro range the mob has when hiding.
#define BB_HIDING_AGGRO_RANGE "BB_hiding_aggro_range"
/// The aggro range the mob has when NOT hiding (set dynamically).
#define BB_HIDING_AGGRO_RANGE_NOT_HIDING "BB_hiding_aggro_range_not_hiding"
/// The cooldown before the mob can hide again (set dynamically).
#define BB_HIDING_COOLDOWN_BEFORE_HIDING "BB_hiding_cooldown_before_hiding"
/// The cooldown before the mob can stop hiding (set dynamically).
#define BB_HIDING_COOLDOWN_BEFORE_STOP_HIDING "BB_hiding_cooldown_before_stop_hiding"
/// The minimum value for the cooldown before the mob can hide / come out of hiding again.
#define BB_HIDING_COOLDOWN_MINIMUM "BB_hiding_cooldown_minimum"
/// The maximum value for the cooldown before the mob can hide / come out of hiding again.
#define BB_HIDING_COOLDOWN_MAXIMUM "BB_hiding_cooldown_maximum"
/// The probability (in %) that the mob will stop hiding randomly every process.
#define BB_HIDING_RANDOM_STOP_HIDING_CHANCE "BB_hiding_random_stop_hiding_chance"

/// The default vision range when hiding, if none is specified.
#define DEFAULT_HIDING_AGGRO_RANGE 2
/// The default chance to get out of hiding for every random hiding subtree process.
#define DEFAULT_RANDOM_STOP_HIDING_CHANCE 2
12 changes: 12 additions & 0 deletions code/__DEFINES/~monkestation/colors.dm
Original file line number Diff line number Diff line change
@@ -1 +1,13 @@
#define LIGHT_COLOR_CLOCKWORK "#BE8700"

//Colors for Bioluminescence plant traits.
#define COLOR_BIOLUMINESCENCE_STANDARD "#C3E381"
#define COLOR_BIOLUMINESCENCE_SHADOW "#AAD84B"
#define COLOR_BIOLUMINESCENCE_YELLOW "#FFFF66"
#define COLOR_BIOLUMINESCENCE_GREEN "#99FF99"
#define COLOR_BIOLUMINESCENCE_BLUE "#6699FF"
#define COLOR_BIOLUMINESCENCE_PURPLE "#D966FF"
#define COLOR_BIOLUMINESCENCE_PINK "#FFB3DA"

#define LIGHT_RANGE_FIRE_BLOSSOM_HARVESTED 2.7
#define LIGHT_POWER_FIRE_BLOSSOM_HARVESTED 1.5
7 changes: 7 additions & 0 deletions code/__DEFINES/~monkestation/dcs/signals/signals_atom.dm
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,10 @@
/// Mob is trying to open the hacking menu of a target [/atom], from /datum/hacking/interactable(): (mob/user)
#define COMSIG_TRY_HACKING_INTERACT "try_hacking_interact"
#define COMPONENT_CANT_INTERACT_HACKING (1<<0)


/// The signal sent when an atom/movable should try to toggle their hiding.
/// Gets called on the target, with (hiding, play_feedback = TRUE) as its args.
/// Used for `/datum/element/can_hide`
#define COMSIG_MOVABLE_TOGGLE_HIDING "movable_toggle_hiding"

2 changes: 1 addition & 1 deletion code/datums/ai/basic_mobs/basic_ai_behaviors/targeting.dm
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ GLOBAL_LIST_INIT(target_interested_atoms, typecacheof(list(/mob, /obj/machinery/
/datum/ai_behavior/find_potential_targets/proc/failed_to_find_anyone(datum/ai_controller/controller, target_key, targeting_strategy_key, hiding_location_key)
var/aggro_range = controller.blackboard[aggro_range_key] || vision_range
// takes the larger between our range() input and our implicit hearers() input (world.view)
aggro_range = max(aggro_range, ROUND_UP(max(getviewsize(world.view)) / 2))
// aggro_range = max(aggro_range, ROUND_UP(max(getviewsize(world.view)) / 2)) MAPEXPANSION CHANGE: Stillcaps
// Alright, here's the interesting bit
// We're gonna use this max range to hook into a proximity field so we can just await someone interesting to come along
// Rather then trying to check every few seconds
Expand Down
80 changes: 45 additions & 35 deletions code/datums/mapgen/CaveGenerator.dm
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@
///Base chance of spawning flora
var/flora_spawn_chance = 2
///Base chance of spawning features
var/feature_spawn_chance = 0.15
var/feature_spawn_chance = 0.25
///Unique ID for this spawner
var/string_gen

Expand Down Expand Up @@ -83,10 +83,19 @@
weighted_megafauna_spawn_list = GLOB.megafauna_spawn_list
megafauna_spawn_list = expand_weights(weighted_megafauna_spawn_list)
if(!weighted_flora_spawn_list)
weighted_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, /obj/structure/flora/ash/seraka = 2)
weighted_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,
/obj/structure/flora/ash/seraka = 2,
)
flora_spawn_list = expand_weights(weighted_flora_spawn_list)
if(!weighted_feature_spawn_list)
weighted_feature_spawn_list = list(/obj/structure/geyser/random = 1)
weighted_feature_spawn_list = list(
/obj/structure/geyser/random = 1,
)
feature_spawn_list = expand_weights(weighted_feature_spawn_list)
open_turf_types = expand_weights(weighted_open_turf_types)
closed_turf_types = expand_weights(weighted_closed_turf_types)
Expand All @@ -103,14 +112,7 @@
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

// Area var pullouts to make accessing in the loop faster
var/flora_allowed = (generate_in.area_flags & FLORA_ALLOWED) && length(flora_spawn_list)
var/feature_allowed = (generate_in.area_flags & FLORA_ALLOWED) && length(feature_spawn_list)
var/mobs_allowed = (generate_in.area_flags & MOB_SPAWN_ALLOWED) && length(mob_spawn_list)
var/megas_allowed = (generate_in.area_flags & MEGAFAUNA_SPAWN_ALLOWED) && length(megafauna_spawn_list)

for(var/i in turfs) //Go through all the turfs and generate them
var/turf/gen_turf = i
for(var/turf/gen_turf as anything in turfs) //Go through all the turfs and generate them

var/closed = string_gen[world.maxx * (gen_turf.y - 1) + gen_turf.x] != "0"
var/turf/new_turf = pick(closed ? closed_turf_types : open_turf_types)
Expand Down Expand Up @@ -162,8 +164,8 @@
var/datum/biome/selected_biome

// Here comes the meat of the biome code.
var/drift_x = clamp((gen_turf.x + rand(-BIOME_RANDOM_SQUARE_DRIFT, BIOME_RANDOM_SQUARE_DRIFT)), 1, world.maxx) // / perlin_zoom
var/drift_y = clamp((gen_turf.y + rand(-BIOME_RANDOM_SQUARE_DRIFT, BIOME_RANDOM_SQUARE_DRIFT)), 2, world.maxy) // / perlin_zoom
var/drift_x = clamp(((gen_turf.x + rand(-BIOME_RANDOM_SQUARE_DRIFT, BIOME_RANDOM_SQUARE_DRIFT)) / perlin_zoom), 1, world.maxx)
var/drift_y = clamp(((gen_turf.y + rand(-BIOME_RANDOM_SQUARE_DRIFT, BIOME_RANDOM_SQUARE_DRIFT)) / perlin_zoom), 2, world.maxy)

// Where we go in the generated string (generated outside of the loop for s p e e d)
var/coordinate = world.maxx * (drift_y - 1) + drift_x
Expand Down Expand Up @@ -223,55 +225,63 @@
// If we've spawned something yet
var/spawned_something = FALSE

///Spawning isn't done in procs to save on overhead on the 60k turfs we're going through.
//FLORA SPAWNING HERE
if(flora_allowed && prob(flora_spawn_chance))
var/flora_type = pick(flora_spawn_list)
new flora_type(new_turf)
spawned_something = TRUE
if(!(target_turf.turf_flags & TURF_BLOCKS_POPULATE_TERRAIN_FLORAFEATURES))
///Spawning isn't done in procs to save on overhead on the 60k turfs we're going through.
//FLORA SPAWNING HERE
if(flora_allowed && prob(flora_spawn_chance))
var/flora_type = pick(flora_spawn_list)
new flora_type(target_turf)
spawned_something = TRUE

//FEATURE SPAWNING HERE
if(feature_allowed && prob(feature_spawn_chance))
var/can_spawn = TRUE
//FEATURE SPAWNING HERE
//we may have generated something from the flora list on the target turf, so let's not place
//a feature here if that's the case (because it would look stupid)
if(feature_allowed && !spawned_something && prob(feature_spawn_chance))
var/can_spawn = TRUE

var/atom/picked_feature = pick(feature_spawn_list)
var/atom/picked_feature = pick(feature_spawn_list)

for(var/obj/structure/existing_feature in range(7, new_turf))
if(istype(existing_feature, picked_feature))
can_spawn = FALSE
break
for(var/obj/structure/existing_feature in range(7, target_turf))
if(istype(existing_feature, picked_feature))
can_spawn = FALSE
break

if(can_spawn)
new picked_feature(new_turf)
spawned_something = TRUE
if(can_spawn)
new picked_feature(target_turf)
spawned_something = TRUE

//MOB SPAWNING HERE
if(mobs_allowed && !spawned_something && prob(mob_spawn_chance))
var/atom/picked_mob = pick(mob_spawn_list)
var/is_megafauna = FALSE

if(picked_mob == SPAWN_MEGAFAUNA)
if(megas_allowed) //this is danger. it's boss time.
picked_mob = pick(megafauna_spawn_list)
is_megafauna = TRUE
else //this is not danger, don't spawn a boss, spawn something else
picked_mob = pick(mob_spawn_no_mega_list) //What if we used 100% of the brain...and did something (slightly) less shit than a while loop?

var/can_spawn = TRUE

// prevents tendrils spawning in each other's collapse range
if(ispath(picked_mob, /obj/structure/spawner/lavaland))
for(var/obj/structure/spawner/lavaland/spawn_blocker in range(2, new_turf))
for(var/obj/structure/spawner/lavaland/spawn_blocker in range(2, target_turf))
can_spawn = FALSE
break
// if the random is not a tendril (hopefully meaning it is a mob), avoid spawning if there's another one within 12 tiles
else
var/list/things_in_range = range(12, new_turf)
var/list/things_in_range = range(12, target_turf)
for(var/mob/living/mob_blocker in things_in_range)
if(ismining(mob_blocker))
can_spawn = FALSE
break
// Also block spawns if there's a random lavaland mob spawner nearby and it's not a mega
if(!is_megafauna)
can_spawn = can_spawn && !(locate(/obj/effect/spawner/random/lavaland_mob) in things_in_range)
//if there's a megafauna within standard view don't spawn anything at all (This isn't really consistent, I don't know why we do this. you do you tho)
if(can_spawn)
for(var/mob/living/simple_animal/hostile/megafauna/found_fauna in range(7, new_turf))
for(var/mob/living/simple_animal/hostile/megafauna/found_fauna in range(7, target_turf))
can_spawn = FALSE
break

Expand All @@ -280,11 +290,11 @@
weighted_megafauna_spawn_list.Remove(picked_mob)
megafauna_spawn_list = expand_weights(weighted_megafauna_spawn_list)
megas_allowed = megas_allowed && length(megafauna_spawn_list)
new picked_mob(new_turf)
new picked_mob(target_turf)
spawned_something = TRUE
CHECK_TICK

var/message = "[name] finished in [(REALTIMEOFDAY - start_time)/10]s!"
var/message = "[name] terrain population finished in [(REALTIMEOFDAY - start_time)/10]s!"
to_chat(world, span_boldannounce("[message]"))
log_world(message)

Expand Down
2 changes: 1 addition & 1 deletion code/game/objects/structures/flora.dm
Original file line number Diff line number Diff line change
Expand Up @@ -299,7 +299,7 @@
. = ..()
var/turf/my_turf = get_turf(src)
playsound(my_turf, 'sound/effects/meteorimpact.ogg', 100 , FALSE, FALSE)
var/obj/structure/flora/tree/stump/new_stump = new(my_turf)
var/obj/structure/flora/tree/stump/new_stump = new stump_type(my_turf)
new_stump.name = "[name] stump"

/obj/structure/flora/tree/uproot(mob/living/user)
Expand Down
4 changes: 4 additions & 0 deletions code/modules/procedural_mapping/mapGenerator.dm
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@
buildmode_name = copytext_char("[type]", 20) // / d a t u m / m a p g e n e r a t o r / = 20 characters.
initialiseModules()

/// Populate terrain with flora, fauna, features and basically everything that isn't a turf.
/datum/map_generator/proc/populate_terrain(list/turfs, area/generate_in)
return

//Defines the region the map represents, sets map
//Returns the map
/datum/map_generator/proc/defineRegion(turf/Start, turf/End, replace = 0)
Expand Down
4 changes: 2 additions & 2 deletions monkestation/code/modules/liquids/ocean_generator.dm
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@
flora_spawn_list = null

///2D list of all biomes based on heat and humidity combos.
var/list/possible_biomes = list(
possible_biomes = list(
BIOME_LOW_HEAT = list(
BIOME_LOW_HUMIDITY = /datum/biome/ocean_sand/above,
BIOME_LOWMEDIUM_HUMIDITY = /datum/biome/ocean_sand_flora/above,
Expand All @@ -134,7 +134,7 @@
)
)
///Used to select "zoom" level into the perlin noise, higher numbers result in slower transitions
var/perlin_zoom = 65
perlin_zoom = 65


/datum/map_generator/cave_generator/trench/generate_terrain(list/turfs, area/generate_in)
Expand Down
8 changes: 8 additions & 0 deletions monkestation/code/modules/map_gen_expansions/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
## Title: MapGen Expansions

MODULE ID: MAPEXPANSIONS

### Credits:

Credits to SableSteel (sable.steel on Discord, thlumyn on Github) for the sprites
Credits to GoldenAlpharex for the biome generation and other code
8 changes: 8 additions & 0 deletions monkestation/code/modules/map_gen_expansions/_basemapping.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
/// Returns true if the map we're playing on is on a planet, but it DOES have space access.
/datum/controller/subsystem/mapping/proc/is_planetary_with_space()
return config.planetary && config.allow_space_when_planetary


/datum/map_config
/// Are we allowing space even if we're planetary?
var/allow_space_when_planetary = FALSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/// This behavior is to run any code that needs to be ran when the mob is going
/// into hiding, or coming out from hiding.
/datum/ai_behavior/toggle_hiding
/// The blackboard cooldown key to check before we can hide. Only here
/// to avoid copy-paste in other subtrees/behaviors, should only be SET,
/// not READ here.
var/cooldown_before_hiding_key = BB_HIDING_COOLDOWN_BEFORE_HIDING


/datum/ai_behavior/toggle_hiding/setup(datum/ai_controller/controller, ...)
. = ..()

if(!controller.blackboard[BB_HIDING_AGGRO_RANGE_NOT_HIDING])
controller.set_blackboard_key(BB_HIDING_AGGRO_RANGE_NOT_HIDING, controller.blackboard[BB_AGGRO_RANGE])


/datum/ai_behavior/toggle_hiding/perform(seconds_per_tick, datum/ai_controller/controller, now_hiding)
var/mob/living/basic/hiding_pawn = controller.pawn

if(!istype(hiding_pawn))
finish_action(controller, FALSE)
return

var/mob/living/living_pawn = controller.pawn

// Let's add some checks if we're trying to hide.
if(now_hiding)
// We can't hide if we can't move properly, or if we don't have any valid hiding locations.
if(!(living_pawn.mobility_flags & MOBILITY_MOVE) || !isturf(living_pawn.loc) || living_pawn.pulledby || !islist(controller.blackboard[BB_HIDING_CAN_HIDE_ON]))
finish_action(controller, FALSE)
return

// We can't hide if we don't match the proper turf type we need to hide onto.
if(!controller.blackboard[BB_HIDING_CAN_HIDE_ON][living_pawn.loc.type])
finish_action(controller, FALSE)
return

var/hiding_status_changed = controller.blackboard[BB_HIDING_HIDDEN] != now_hiding

if(!hiding_status_changed)
finish_action(controller, TRUE)
return

controller.set_blackboard_key(BB_HIDING_HIDDEN, now_hiding)
SEND_SIGNAL(living_pawn, COMSIG_MOVABLE_TOGGLE_HIDING, now_hiding, TRUE)

var/new_vision_range = now_hiding ? controller.blackboard[BB_HIDING_AGGRO_RANGE] || DEFAULT_HIDING_AGGRO_RANGE : controller.blackboard[BB_HIDING_AGGRO_RANGE_NOT_HIDING]

if(!now_hiding)
var/cooldown_minimum = controller.blackboard[BB_HIDING_COOLDOWN_MINIMUM] || 1 MINUTES
var/cooldown_maximum = controller.blackboard[BB_HIDING_COOLDOWN_MAXIMUM] || 3 MINUTES
var/new_cooldown = world.time + rand(cooldown_minimum, cooldown_maximum)
controller.set_blackboard_key(cooldown_before_hiding_key, new_cooldown)

controller.set_blackboard_key(BB_AGGRO_RANGE, new_vision_range)

finish_action(controller, TRUE)
return

Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
/datum/idle_behavior/idle_random_walk/hide


/datum/idle_behavior/idle_random_walk/hide/perform_idle_behavior(seconds_per_tick, datum/ai_controller/controller)
// You can't move when you're hidden.
if(controller.blackboard[BB_HIDING_HIDDEN])
return FALSE

return ..()
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Prevents finding a target if hiding.
/datum/ai_planning_subtree/simple_find_target/not_while_hiding
operational_datums = list(/datum/element/can_hide)

/datum/ai_planning_subtree/simple_find_target/not_while_hiding/SelectBehaviors(datum/ai_controller/controller, seconds_per_tick)
if(controller.blackboard[BB_HIDING_HIDDEN])
return

return ..()
Loading

0 comments on commit 8cd5586

Please sign in to comment.