Merge branch 'master' into final_shuttle_touches_and_stuff
# Conflicts: # icons/turf/shuttle.dmi
@@ -61,6 +61,7 @@
|
||||
#include "code\__defines\radio.dm"
|
||||
#include "code\__defines\regex.dm"
|
||||
#include "code\__defines\research.dm"
|
||||
#include "code\__defines\ruin_tags.dm"
|
||||
#include "code\__defines\rust_g.dm"
|
||||
#include "code\__defines\shuttle.dm"
|
||||
#include "code\__defines\space_sectors.dm"
|
||||
@@ -297,6 +298,7 @@
|
||||
#include "code\datums\position_point_vector.dm"
|
||||
#include "code\datums\progressbar.dm"
|
||||
#include "code\datums\records.dm"
|
||||
#include "code\datums\ruins.dm"
|
||||
#include "code\datums\statistic.dm"
|
||||
#include "code\datums\weakref.dm"
|
||||
#include "code\datums\components\_component.dm"
|
||||
@@ -323,6 +325,7 @@
|
||||
#include "code\datums\looping_sounds\revenant_rift.dm"
|
||||
#include "code\datums\looping_sounds\thermal_drill.dm"
|
||||
#include "code\datums\observation\_debug.dm"
|
||||
#include "code\datums\observation\death.dm"
|
||||
#include "code\datums\observation\destroyed.dm"
|
||||
#include "code\datums\observation\dir_set.dm"
|
||||
#include "code\datums\observation\entered.dm"
|
||||
@@ -333,6 +336,7 @@
|
||||
#include "code\datums\observation\observation.dm"
|
||||
#include "code\datums\observation\see_in_dark_set.dm"
|
||||
#include "code\datums\observation\see_invisible_set.dm"
|
||||
#include "code\datums\observation\shuttle_moved.dm"
|
||||
#include "code\datums\observation\sight_set.dm"
|
||||
#include "code\datums\outfits\outfit.dm"
|
||||
#include "code\datums\outfits\outfit_admin.dm"
|
||||
@@ -360,6 +364,7 @@
|
||||
#include "code\datums\repositories\crew.dm"
|
||||
#include "code\datums\repositories\decls.dm"
|
||||
#include "code\datums\repositories\repository.dm"
|
||||
#include "code\datums\repositories\unique.dm"
|
||||
#include "code\datums\trading\_trading_defines.dm"
|
||||
#include "code\datums\trading\ai.dm"
|
||||
#include "code\datums\trading\food.dm"
|
||||
@@ -1128,6 +1133,7 @@
|
||||
#include "code\game\objects\structures\morgue.dm"
|
||||
#include "code\game\objects\structures\musician.dm"
|
||||
#include "code\game\objects\structures\noticeboard.dm"
|
||||
#include "code\game\objects\structures\pit.dm"
|
||||
#include "code\game\objects\structures\plasticflaps.dm"
|
||||
#include "code\game\objects\structures\railing.dm"
|
||||
#include "code\game\objects\structures\safe.dm"
|
||||
@@ -1969,7 +1975,12 @@
|
||||
#include "code\modules\maps\dmm_suite.dm"
|
||||
#include "code\modules\maps\map_template.dm"
|
||||
#include "code\modules\maps\reader.dm"
|
||||
#include "code\modules\maps\ruins.dm"
|
||||
#include "code\modules\maps\swapmaps.dm"
|
||||
#include "code\modules\maps\planet_types\barren.dm"
|
||||
#include "code\modules\maps\planet_types\desert.dm"
|
||||
#include "code\modules\maps\planet_types\grass.dm"
|
||||
#include "code\modules\maps\planet_types\snow.dm"
|
||||
#include "code\modules\martial_arts\gunkata.dm"
|
||||
#include "code\modules\martial_arts\martial.dm"
|
||||
#include "code\modules\martial_arts\plasma_fist.dm"
|
||||
@@ -2336,6 +2347,7 @@
|
||||
#include "code\modules\mob\living\simple_animal\hostile\hivebots\hivebot_projectiles.dm"
|
||||
#include "code\modules\mob\living\simple_animal\hostile\retaliate\cavern.dm"
|
||||
#include "code\modules\mob\living\simple_animal\hostile\retaliate\clown.dm"
|
||||
#include "code\modules\mob\living\simple_animal\hostile\retaliate\exoplanet.dm"
|
||||
#include "code\modules\mob\living\simple_animal\hostile\retaliate\retaliate.dm"
|
||||
#include "code\modules\mob\living\simple_animal\mechanical\mechanical.dm"
|
||||
#include "code\modules\modular_computers\laptop_vendor.dm"
|
||||
@@ -2516,6 +2528,10 @@
|
||||
#include "code\modules\overmap\sectors.dm"
|
||||
#include "code\modules\overmap\spacetravel.dm"
|
||||
#include "code\modules\overmap\events\event.dm"
|
||||
#include "code\modules\overmap\exoplanets\exoplanet.dm"
|
||||
#include "code\modules\overmap\exoplanets\random_map.dm"
|
||||
#include "code\modules\overmap\exoplanets\theme.dm"
|
||||
#include "code\modules\overmap\exoplanets\turfs.dm"
|
||||
#include "code\modules\overmap\ships\landable.dm"
|
||||
#include "code\modules\overmap\ships\ship.dm"
|
||||
#include "code\modules\overmap\ships\computers\engine_control.dm"
|
||||
@@ -3052,6 +3068,7 @@
|
||||
#include "maps\exodus\code\exodus_holodeck.dm"
|
||||
#include "maps\exodus\code\exodus_shuttles.dm"
|
||||
#include "maps\exodus\code\exodus_unittest.dm"
|
||||
#include "maps\random_ruins\exoplanets\exoplanet_ruins.dm"
|
||||
#include "maps\runtime\runtime_overmap.dm"
|
||||
#include "maps\runtime\code\runtime.dm"
|
||||
#include "maps\runtime\code\runtime_lifts.dm"
|
||||
|
||||
@@ -35,6 +35,8 @@
|
||||
|
||||
#define UNDERSCORE_OR_NULL(target) "[target ? "[target]_" : ""]"
|
||||
|
||||
#define sequential_id(key) uniqueness_repository.Generate(/datum/uniqueness_generator/id_sequential, key)
|
||||
|
||||
#define isAI(A) istype(A, /mob/living/silicon/ai)
|
||||
#define isDrone(A) istype(A, /mob/living/silicon/robot/drone)
|
||||
#define isMatriarchDrone(A) istype(A, /mob/living/silicon/robot/drone/construction/matriarch)
|
||||
|
||||
@@ -110,4 +110,6 @@
|
||||
#define GAS_NITROGEN "nitrogen"
|
||||
#define GAS_NO2 "nitrodioxide"
|
||||
#define GAS_PHORON "phoron"
|
||||
#define GAS_HYDROGEN "hydrogen"
|
||||
#define GAS_HYDROGEN "hydrogen"
|
||||
#define GAS_ALIEN "aliether"
|
||||
#define GAS_STEAM "water"
|
||||
@@ -131,3 +131,5 @@
|
||||
#define BLOB_COLOR_SHIELD "#9ed659"
|
||||
#define BLOB_COLOR_RAV "#d65f42"
|
||||
#define BLOB_COLOR_PULS "#b5ff5b"
|
||||
|
||||
#define RANDOM_RGB rgb(rand(0,255), rand(0,255), rand(0,255))
|
||||
@@ -33,6 +33,7 @@
|
||||
#define MATERIAL_RUST "rust"
|
||||
#define MATERIAL_CARDBOARD "cardboard"
|
||||
|
||||
|
||||
// Leathers and related.
|
||||
#define MATERIAL_RESIN "resin"
|
||||
#define MATERIAL_LEATHER "leather"
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#define MIMIC_NO_AO 16 // If the turf shouldn't apply regular turf AO and only do Z-mimic AO.
|
||||
|
||||
#define TRANSITIONEDGE 7 // Distance from edge to move to another z-level.
|
||||
#define RUIN_MAP_EDGE_PAD 15
|
||||
|
||||
// Invisibility constants.
|
||||
#define INVISIBILITY_LIGHTING 20
|
||||
@@ -479,3 +480,17 @@ Define for getting a bitfield of adjacent turfs that meet a condition.
|
||||
#define COOK_CHECK_EXACT 1
|
||||
|
||||
#define STATION_TAG "Aurora"
|
||||
|
||||
//Planet habitability class
|
||||
#define HABITABILITY_IDEAL 1
|
||||
#define HABITABILITY_OKAY 2
|
||||
#define HABITABILITY_BAD 3
|
||||
|
||||
//Map template flags
|
||||
#define TEMPLATE_FLAG_ALLOW_DUPLICATES 1 // Lets multiple copies of the template to be spawned
|
||||
#define TEMPLATE_FLAG_SPAWN_GUARANTEED 2 // Makes it ignore away site budget and just spawn (only for away sites)
|
||||
#define TEMPLATE_FLAG_CLEAR_CONTENTS 4 // if it should destroy objects it spawns on top of
|
||||
#define TEMPLATE_FLAG_NO_RUINS 8 // if it should forbid ruins from spawning on top of it
|
||||
#define TEMPLATE_FLAG_NO_RADS 16// Removes all radiation from the template after spawning.
|
||||
|
||||
|
||||
|
||||
8
code/__defines/ruin_tags.dm
Normal file
@@ -0,0 +1,8 @@
|
||||
//Flags for exoplanet ruin picking
|
||||
|
||||
#define RUIN_HABITAT 1 //long term habitat
|
||||
#define RUIN_HUMAN 2 //human-made structure
|
||||
#define RUIN_ALIEN 4 //artificial structure of an unknown origin
|
||||
#define RUIN_WRECK 8 //crashed vessel
|
||||
#define RUIN_NATURAL 16 //naturally occuring structure
|
||||
#define RUIN_WATER 32 //ruin depending on planet having water accessible
|
||||
@@ -9,6 +9,7 @@
|
||||
#define TURF_HAS_CORNERS 256
|
||||
#define TURF_IS_FRAGILE 512
|
||||
#define TURF_ACID_IMMUNE 1024
|
||||
#define TURF_NORUINS 2048
|
||||
|
||||
// Roof related flags
|
||||
#define ROOF_FORCE_SPAWN 1
|
||||
|
||||
@@ -201,6 +201,7 @@ Proc for attack log creation, because really why not
|
||||
// Returns true if the mob was in neither the dead or living list
|
||||
/mob/proc/add_to_dead_mob_list()
|
||||
return FALSE
|
||||
|
||||
/mob/living/add_to_dead_mob_list()
|
||||
if((src in living_mob_list) || (src in dead_mob_list))
|
||||
return FALSE
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
continue
|
||||
//Check if we have a spawnpoint on the current map
|
||||
if(!G.select_spawnlocation(FALSE) && G.loc_type == GS_LOC_POS)
|
||||
log_debug("ghostroles","Spawner [G.type] got removed from selection because of missing spawnpoint")
|
||||
log_ss("ghostroles","Spawner [G.type] got removed from selection because of missing spawnpoint")
|
||||
continue
|
||||
spawners[G.short_name] = G
|
||||
|
||||
|
||||
@@ -46,6 +46,8 @@
|
||||
|
||||
click_catchers = create_click_catcher()
|
||||
|
||||
current_map.build_exoplanets()
|
||||
|
||||
..(timeofday)
|
||||
|
||||
/proc/sorted_add_area(area/A)
|
||||
|
||||
@@ -26,7 +26,7 @@ var/datum/controller/subsystem/processing/SSprocessing
|
||||
var/datum/thing = current_run[current_run.len]
|
||||
current_run.len--
|
||||
if(!QDELETED(thing))
|
||||
if (thing.process() == PROCESS_KILL)
|
||||
if (thing.process(wait, times_fired) == PROCESS_KILL)
|
||||
stop_processing(thing)
|
||||
else
|
||||
processing -= thing
|
||||
|
||||
@@ -22,6 +22,7 @@ var/datum/controller/subsystem/processing/shuttle/SSshuttle
|
||||
var/list/landmarks_still_needed = list() //Stores landmark_tags that need to be assigned to the sector (landmark_tag = sector) when registered.
|
||||
var/list/shuttles_to_initialize = list() //A queue for shuttles to initialize at the appropriate time.
|
||||
var/list/sectors_to_initialize //Used to find all sector objects at the appropriate time.
|
||||
var/list/initialized_sectors = list()
|
||||
var/block_queue = TRUE
|
||||
|
||||
var/tmp/list/working_shuttles
|
||||
@@ -116,6 +117,8 @@ var/datum/controller/subsystem/processing/shuttle/SSshuttle
|
||||
given_sector.add_landmark(landmark, landmark.shuttle_restricted)
|
||||
landmarks_awaiting_sector -= landmark
|
||||
|
||||
initialized_sectors |= given_sector
|
||||
|
||||
/datum/controller/subsystem/processing/shuttle/proc/try_add_landmark_tag(landmark_tag, obj/effect/overmap/visitable/given_sector)
|
||||
var/obj/effect/shuttle_landmark/landmark = get_landmark(landmark_tag)
|
||||
if(!landmark)
|
||||
|
||||
22
code/datums/observation/death.dm
Normal file
@@ -0,0 +1,22 @@
|
||||
// Observer Pattern Implementation: Death
|
||||
// Registration type: /mob
|
||||
//
|
||||
// Raised when: A mob is added to the dead_mob_list
|
||||
//
|
||||
// Arguments that the called proc should expect:
|
||||
// /mob/dead: The mob that was added to the dead_mob_list
|
||||
|
||||
var/datum/observ/death/death_event = new()
|
||||
|
||||
/datum/observ/death
|
||||
name = "Death"
|
||||
expected_type = /mob
|
||||
|
||||
/*****************
|
||||
* Death Handling *
|
||||
*****************/
|
||||
|
||||
/mob/living/add_to_dead_mob_list()
|
||||
. = ..()
|
||||
if(.)
|
||||
death_event.raise_event(src)
|
||||
38
code/datums/observation/shuttle_moved.dm
Normal file
@@ -0,0 +1,38 @@
|
||||
// Observer Pattern Implementation: Shuttle Moved
|
||||
// Registration type: /datum/shuttle/autodock
|
||||
//
|
||||
// Raised when: A shuttle has moved to a new landmark.
|
||||
//
|
||||
// Arguments that the called proc should expect:
|
||||
// /datum/shuttle/shuttle: the shuttle moving
|
||||
// /obj/effect/shuttle_landmark/old_location: the old location's shuttle landmark
|
||||
// /obj/effect/shuttle_landmark/new_location: the new location's shuttle landmark
|
||||
|
||||
// Observer Pattern Implementation: Shuttle Pre Move
|
||||
// Registration type: /datum/shuttle/autodock
|
||||
//
|
||||
// Raised when: A shuttle is about to move to a new landmark.
|
||||
//
|
||||
// Arguments that the called proc should expect:
|
||||
// /datum/shuttle/shuttle: the shuttle moving
|
||||
// /obj/effect/shuttle_landmark/old_location: the old location's shuttle landmark
|
||||
// /obj/effect/shuttle_landmark/new_location: the new location's shuttle landmark
|
||||
|
||||
var/datum/observ/shuttle_moved/shuttle_moved_event = new()
|
||||
|
||||
/datum/observ/shuttle_moved
|
||||
name = "Shuttle Moved"
|
||||
expected_type = /datum/shuttle
|
||||
|
||||
var/datum/observ/shuttle_pre_move/shuttle_pre_move_event = new()
|
||||
|
||||
/datum/observ/shuttle_pre_move
|
||||
name = "Shuttle Pre Move"
|
||||
expected_type = /datum/shuttle
|
||||
|
||||
/*****************
|
||||
* Shuttle Moved/Pre Move Handling *
|
||||
*****************/
|
||||
|
||||
// Located in modules/shuttle/shuttle.dm
|
||||
// Proc: /datum/shuttle/proc/attempt_move()
|
||||
70
code/datums/repositories/unique.dm
Normal file
@@ -0,0 +1,70 @@
|
||||
var/repository/unique/uniqueness_repository = new()
|
||||
|
||||
/repository/unique
|
||||
var/list/generators
|
||||
|
||||
/repository/unique/New()
|
||||
..()
|
||||
generators = list()
|
||||
|
||||
/repository/unique/proc/Generate()
|
||||
var/generator_type = args[1]
|
||||
var/datum/uniqueness_generator/generator = generators[generator_type]
|
||||
if(!generator)
|
||||
generator = new generator_type()
|
||||
generators[generator_type] = generator
|
||||
var/list/generator_args = args.Copy() // Cannot cut args directly, BYOND complains about it being readonly.
|
||||
generator_args -= generator_type
|
||||
return generator.Generate(arglist(generator_args))
|
||||
|
||||
/datum/uniqueness_generator/proc/Generate()
|
||||
return
|
||||
|
||||
/datum/uniqueness_generator/id_sequential
|
||||
var/list/ids_by_key
|
||||
|
||||
/datum/uniqueness_generator/id_sequential/New()
|
||||
..()
|
||||
ids_by_key = list()
|
||||
|
||||
/datum/uniqueness_generator/id_sequential/Generate(var/key, var/default_id = 100)
|
||||
var/id = ids_by_key[key]
|
||||
if(id)
|
||||
id++
|
||||
else
|
||||
id = default_id
|
||||
|
||||
ids_by_key[key] = id
|
||||
. = id
|
||||
|
||||
/datum/uniqueness_generator/id_random
|
||||
var/list/ids_by_key
|
||||
|
||||
/datum/uniqueness_generator/id_random/New()
|
||||
..()
|
||||
ids_by_key = list()
|
||||
|
||||
/datum/uniqueness_generator/id_random/Generate(var/key, var/min, var/max)
|
||||
var/list/ids = ids_by_key[key]
|
||||
if(!ids)
|
||||
ids = list()
|
||||
ids_by_key[key] = ids
|
||||
|
||||
if(ids.len >= (max - min) + 1)
|
||||
error("Random ID limit reached for key [key].")
|
||||
ids.Cut()
|
||||
|
||||
if(ids.len >= 0.6 * ((max-min) + 1)) // if more than 60% of possible ids used
|
||||
. = list()
|
||||
for(var/i = min to max)
|
||||
if(i in ids)
|
||||
continue
|
||||
. += i
|
||||
var/id = pick(.)
|
||||
ids += id
|
||||
return id
|
||||
else
|
||||
do
|
||||
. = rand(min, max)
|
||||
while(. in ids)
|
||||
ids += .
|
||||
20
code/datums/ruins.dm
Normal file
@@ -0,0 +1,20 @@
|
||||
/datum/map_template/ruin
|
||||
//name = "A Chest of Doubloons"
|
||||
name = null
|
||||
var/description = "In the middle of a clearing in the rockface, there's a chest filled with gold coins with Spanish engravings. \
|
||||
How is there a wooden container filled with 18th century coinage in the middle of a lavawracked hellscape? \
|
||||
It is clearly a mystery."
|
||||
|
||||
var/spawn_weight = 1
|
||||
var/cost = null
|
||||
var/list/sectors = list() //This ruin can only spawn in the sectors in this list.
|
||||
|
||||
var/prefix = null
|
||||
var/suffix = null
|
||||
template_flags = 0 // No duplicates by default
|
||||
|
||||
/datum/map_template/ruin/New()
|
||||
if (suffix)
|
||||
mappath += (prefix + suffix)
|
||||
|
||||
..()
|
||||
@@ -26,9 +26,9 @@
|
||||
/mob/living/simple_animal/mushroom = TRADER_THIS_TYPE,
|
||||
/mob/living/simple_animal/tomato = TRADER_THIS_TYPE,
|
||||
/mob/living/simple_animal/rat/king = TRADER_THIS_TYPE,
|
||||
/mob/living/simple_animal/hostile/diyaab = TRADER_THIS_TYPE,
|
||||
/mob/living/simple_animal/hostile/shantak = TRADER_THIS_TYPE,
|
||||
/mob/living/simple_animal/hostile/samak = TRADER_THIS_TYPE,
|
||||
/mob/living/simple_animal/hostile/retaliate/diyaab = TRADER_THIS_TYPE,
|
||||
/mob/living/simple_animal/hostile/retaliate/shantak = TRADER_THIS_TYPE,
|
||||
/mob/living/simple_animal/hostile/retaliate/samak = TRADER_THIS_TYPE,
|
||||
/mob/living/simple_animal/hostile/bear = TRADER_ALL,
|
||||
/mob/living/simple_animal/hostile/carp = TRADER_ALL,
|
||||
/mob/living/simple_animal/hostile/biglizard = TRADER_THIS_TYPE,
|
||||
|
||||
@@ -50,3 +50,31 @@
|
||||
tile_overlay = "sleeping_agent"
|
||||
overlay_limit = 1
|
||||
flags = XGM_GAS_OXIDIZER
|
||||
|
||||
/decl/xgm_gas/alium
|
||||
id = GAS_ALIEN
|
||||
name = "Aliether"
|
||||
|
||||
/decl/xgm_gas/alium/New()
|
||||
var/num = rand(100,999)
|
||||
name = "Compound #[num]"
|
||||
specific_heat = rand(1, 400) // J/(mol*K)
|
||||
molar_mass = rand(20,800)/1000 // kg/mol
|
||||
if(prob(40))
|
||||
flags |= XGM_GAS_FUEL
|
||||
else if(prob(40)) //it's prooobably a bad idea for gas being oxidizer to itself.
|
||||
flags |= XGM_GAS_OXIDIZER
|
||||
if(prob(40))
|
||||
flags |= XGM_GAS_CONTAMINANT
|
||||
|
||||
if(prob(50))
|
||||
tile_color = RANDOM_RGB
|
||||
overlay_limit = 0.5
|
||||
|
||||
/decl/xgm_gas/vapor
|
||||
id = GAS_STEAM
|
||||
name = "Steam"
|
||||
tile_overlay = "generic"
|
||||
overlay_limit = 0.5
|
||||
specific_heat = 30 // J/(mol*K)
|
||||
molar_mass = 0.020 // kg/mol
|
||||
@@ -295,7 +295,7 @@
|
||||
// This should only be used for EXTERNAL sources of instability, such as from someone or something glowing.
|
||||
/mob/living/proc/receive_radiated_instability(amount)
|
||||
// Energy armor like from the AMI RIG can protect from this.
|
||||
var/armor_ratio = get_blocked_ratio(BP_CHEST, BURN, damage = 40) //todomatt: look over this again
|
||||
var/armor_ratio = get_blocked_ratio(BP_CHEST, BURN, damage = 40)
|
||||
amount = amount * armor_ratio
|
||||
if(amount && prob(10))
|
||||
if(isSynthetic())
|
||||
|
||||
@@ -269,4 +269,20 @@
|
||||
|
||||
/obj/effect/landmark/force_spawnpoint/do_landmark_effect()
|
||||
LAZYINITLIST(force_spawnpoints)
|
||||
LAZYADD(force_spawnpoints[job_tag], loc)
|
||||
LAZYADD(force_spawnpoints[job_tag], loc)
|
||||
|
||||
var/list/ruin_landmarks = list()
|
||||
|
||||
/obj/effect/landmark/ruin
|
||||
var/datum/map_template/ruin/ruin_template
|
||||
|
||||
/obj/effect/landmark/ruin/New(loc, my_ruin_template)
|
||||
name = "ruin_[sequential_id(/obj/effect/landmark/ruin)]"
|
||||
..(loc)
|
||||
ruin_template = my_ruin_template
|
||||
ruin_landmarks |= src
|
||||
|
||||
/obj/effect/landmark/ruin/Destroy()
|
||||
ruin_landmarks -= src
|
||||
ruin_template = null
|
||||
. = ..()
|
||||
|
||||
@@ -523,7 +523,7 @@
|
||||
/obj/item/trap/animal/medium/Initialize()
|
||||
. = ..()
|
||||
allowed_mobs = list(
|
||||
/mob/living/simple_animal/cat, /mob/living/simple_animal/corgi, /mob/living/simple_animal/hostile/diyaab, /mob/living/carbon/human/monkey, /mob/living/simple_animal/penguin, /mob/living/simple_animal/crab,
|
||||
/mob/living/simple_animal/cat, /mob/living/simple_animal/corgi, /mob/living/simple_animal/hostile/retaliate/diyaab, /mob/living/carbon/human/monkey, /mob/living/simple_animal/penguin, /mob/living/simple_animal/crab,
|
||||
/mob/living/simple_animal/chicken, /mob/living/simple_animal/yithian, /mob/living/carbon/alien/diona, /mob/living/silicon/robot/drone, /mob/living/silicon/pai,
|
||||
/mob/living/simple_animal/spiderbot, /mob/living/simple_animal/hostile/tree)
|
||||
|
||||
|
||||
166
code/game/objects/structures/pit.dm
Normal file
@@ -0,0 +1,166 @@
|
||||
/obj/structure/pit
|
||||
name = "pit"
|
||||
desc = "Watch your step, partner."
|
||||
icon = 'icons/obj/pit.dmi'
|
||||
icon_state = "pit1"
|
||||
blend_mode = BLEND_MULTIPLY
|
||||
density = FALSE
|
||||
anchored = TRUE
|
||||
var/open = 1
|
||||
|
||||
/obj/structure/pit/attackby(obj/item/W, mob/user)
|
||||
if(istype(W,/obj/item/shovel))
|
||||
visible_message("<span class='notice'>\The [user] starts [open ? "filling" : "digging open"] \the [src]</span>")
|
||||
if(do_after(user, 50))
|
||||
visible_message("<span class='notice'>\The [user] [open ? "fills" : "digs open"] \the [src]!</span>")
|
||||
if(open)
|
||||
close(user)
|
||||
else
|
||||
open()
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You stop shoveling.</span>")
|
||||
return
|
||||
if (!open && istype(W,/obj/item/stack/material/wood))
|
||||
if(locate(/obj/structure/gravemarker) in src.loc)
|
||||
to_chat(user, "<span class='notice'>There's already a grave marker here.</span>")
|
||||
else
|
||||
visible_message("<span class='notice'>\The [user] starts making a grave marker on top of \the [src]</span>")
|
||||
if( do_after(user, 50) )
|
||||
visible_message("<span class='notice'>\The [user] finishes the grave marker</span>")
|
||||
var/obj/item/stack/material/wood/plank = W
|
||||
plank.use(1)
|
||||
new/obj/structure/gravemarker(src.loc)
|
||||
else
|
||||
to_chat(user, "<span class='notice'>You stop making a grave marker.</span>")
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/structure/pit/update_icon()
|
||||
icon_state = "pit[open]"
|
||||
if(istype(loc,/turf/simulated/floor/exoplanet))
|
||||
var/turf/simulated/floor/exoplanet/E = loc
|
||||
if(E.dirt_color)
|
||||
color = E.dirt_color
|
||||
|
||||
/obj/structure/pit/proc/open()
|
||||
name = "pit"
|
||||
desc = "Watch your step, partner."
|
||||
open = 1
|
||||
for(var/atom/movable/A in src)
|
||||
A.forceMove(src.loc)
|
||||
update_icon()
|
||||
|
||||
/obj/structure/pit/proc/close(var/user)
|
||||
name = "mound"
|
||||
desc = "Some things are better left buried."
|
||||
open = 0
|
||||
for(var/atom/movable/A in src.loc)
|
||||
if(!A.anchored && A != user)
|
||||
A.forceMove(src)
|
||||
update_icon()
|
||||
|
||||
/obj/structure/pit/return_air()
|
||||
if(open && loc)
|
||||
return loc.return_air()
|
||||
else
|
||||
return null
|
||||
|
||||
/obj/structure/pit/proc/digout(mob/escapee)
|
||||
var/breakout_time = 1 //2 minutes by default
|
||||
|
||||
if(open)
|
||||
return
|
||||
|
||||
if(escapee.stat || escapee.restrained())
|
||||
return
|
||||
|
||||
escapee.setClickCooldown(100)
|
||||
to_chat(escapee, "<span class='warning'>You start digging your way out of \the [src] (this will take about [breakout_time] minute\s)</span>")
|
||||
visible_message("<span class='danger'>Something is scratching its way out of \the [src]!</span>")
|
||||
|
||||
for(var/i in 1 to (6*breakout_time * 2)) //minutes * 6 * 5seconds * 2
|
||||
playsound(src.loc, 'sound/weapons/bite.ogg', 100, 1)
|
||||
|
||||
if(!do_after(escapee, 50))
|
||||
to_chat(escapee, "<span class='warning'>You have stopped digging.</span>")
|
||||
return
|
||||
if(open)
|
||||
return
|
||||
|
||||
if(i == 6*breakout_time)
|
||||
to_chat(escapee, "<span class='warning'>Halfway there...</span>")
|
||||
|
||||
to_chat(escapee, "<span class='warning'>You successfuly dig yourself out!</span>")
|
||||
visible_message("<span class='danger'>\the [escapee] emerges from \the [src]!</span>")
|
||||
playsound(src.loc, 'sound/effects/squelch1.ogg', 100, 1)
|
||||
open()
|
||||
|
||||
/obj/structure/pit/closed
|
||||
name = "mound"
|
||||
desc = "Some things are better left buried."
|
||||
open = 0
|
||||
|
||||
/obj/structure/pit/closed/Initialize()
|
||||
. = ..()
|
||||
close()
|
||||
|
||||
//invisible until unearthed first
|
||||
/obj/structure/pit/closed/hidden
|
||||
invisibility = INVISIBILITY_OBSERVER
|
||||
|
||||
/obj/structure/pit/closed/hidden/open()
|
||||
..()
|
||||
invisibility = INVISIBILITY_LEVEL_ONE
|
||||
|
||||
//spoooky
|
||||
/obj/structure/pit/closed/grave
|
||||
name = "grave"
|
||||
icon_state = "pit0"
|
||||
|
||||
/obj/structure/pit/closed/grave/Initialize()
|
||||
var/obj/structure/closet/coffin/C = new(src.loc)
|
||||
var/obj/effect/decal/remains/human/bones = new(C)
|
||||
bones.layer = BELOW_MOB_LAYER
|
||||
var/obj/structure/gravemarker/random/R = new(src.loc)
|
||||
R.generate()
|
||||
. = ..()
|
||||
|
||||
/obj/structure/gravemarker
|
||||
name = "grave marker"
|
||||
desc = "You're not the first."
|
||||
icon = 'icons/obj/gravestone.dmi'
|
||||
icon_state = "wood"
|
||||
pixel_x = 15
|
||||
pixel_y = 8
|
||||
anchored = TRUE
|
||||
var/message = "Unknown."
|
||||
|
||||
/obj/structure/gravemarker/cross
|
||||
icon_state = "cross"
|
||||
|
||||
/obj/structure/gravemarker/examine(mob/user)
|
||||
. = ..()
|
||||
to_chat(user, "It says: '[message]'")
|
||||
|
||||
/obj/structure/gravemarker/random/Initialize()
|
||||
generate()
|
||||
. = ..()
|
||||
|
||||
/obj/structure/gravemarker/random/proc/generate()
|
||||
icon_state = pick("wood","cross")
|
||||
|
||||
|
||||
var/nam = random_name(MALE, SPECIES_HUMAN)
|
||||
message = "Here lies [nam]."
|
||||
|
||||
/obj/structure/gravemarker/attackby(obj/item/W, mob/user)
|
||||
if(istype(W,/obj/item/material/hatchet))
|
||||
visible_message("<span class = 'warning'>\The [user] starts hacking away at \the [src] with \the [W].</span>")
|
||||
if(!do_after(user, 30))
|
||||
visible_message("<span class = 'warning'>\The [user] hacks \the [src] apart.</span>")
|
||||
new /obj/item/stack/material/wood(src)
|
||||
qdel(src)
|
||||
if(istype(W,/obj/item/pen))
|
||||
var/msg = sanitize(input(user, "What should it say?", "Grave marker", message) as text|null)
|
||||
if(msg)
|
||||
message = msg
|
||||
@@ -92,6 +92,9 @@
|
||||
for(var/obj/O in src)
|
||||
O.hide(O.hides_under_flooring() && src.flooring)
|
||||
|
||||
/turf/simulated/floor/is_floor()
|
||||
return TRUE
|
||||
|
||||
/turf/simulated/floor/shuttle_ceiling
|
||||
name = "hull plating"
|
||||
icon = 'icons/turf/flooring/tiles.dmi'
|
||||
|
||||
@@ -258,3 +258,6 @@
|
||||
W.burn((temperature/4))
|
||||
for(var/obj/machinery/door/airlock/phoron/D in range(3,src))
|
||||
D.ignite(temperature/4)
|
||||
|
||||
/turf/simulated/wall/is_wall()
|
||||
return TRUE
|
||||
|
||||
@@ -542,3 +542,12 @@ var/const/enterloopsanity = 100
|
||||
return 15
|
||||
else
|
||||
return 0
|
||||
|
||||
/turf/proc/is_wall()
|
||||
return FALSE
|
||||
|
||||
/turf/proc/is_open()
|
||||
return FALSE
|
||||
|
||||
/turf/proc/is_floor()
|
||||
return FALSE
|
||||
|
||||
@@ -2,5 +2,6 @@
|
||||
var/name
|
||||
var/description
|
||||
var/list/possible_erts = list()
|
||||
var/list/possible_exoplanets = list()
|
||||
var/list/cargo_price_coef = list("nt" = 1, "hpi" = 1, "zhu" = 1, "een" = 1, "get" = 1, "arz" = 1, "blm" = 1,
|
||||
"iac" = 1, "zsc" = 1, "vfc" = 1, "bis" = 1, "xmg" = 1, "npi" = 1) //how much the space sector afffects how expensive is ordering from that cargo supplier
|
||||
|
||||
@@ -106,13 +106,13 @@ var/list/global/random_stock_large = list()
|
||||
|
||||
var/list/infest_mobs_moderate = list(
|
||||
/mob/living/simple_animal/bee/standalone = 1,
|
||||
/mob/living/simple_animal/hostile/diyaab = 1,
|
||||
/mob/living/simple_animal/hostile/retaliate/diyaab = 1,
|
||||
/mob/living/simple_animal/hostile/viscerator = 1,
|
||||
/mob/living/simple_animal/hostile/scarybat = 1)
|
||||
|
||||
var/list/infest_mobs_severe = list(
|
||||
/mob/living/simple_animal/hostile/giant_spider/hunter = 1,
|
||||
/mob/living/simple_animal/hostile/shantak = 0.7,
|
||||
/mob/living/simple_animal/hostile/retaliate/shantak = 0.7,
|
||||
/mob/living/simple_animal/hostile/bear = 0.5,
|
||||
/mob/living/simple_animal/hostile/carp = 1.5,
|
||||
/mob/living/simple_animal/hostile/carp/russian = 0.3,
|
||||
|
||||
@@ -1,10 +1,16 @@
|
||||
/datum/map_template
|
||||
var/name = "Default Template Name"
|
||||
var/id = null // All maps that should be loadable during runtime need an id
|
||||
var/width = 0
|
||||
var/height = 0
|
||||
var/mappath = null
|
||||
var/loaded = 0 // Times loaded this round
|
||||
var/static/dmm_suite/maploader = new
|
||||
var/list/shuttles_to_initialise = list()
|
||||
var/list/subtemplates_to_spawn
|
||||
var/base_turf_for_zs = null
|
||||
var/accessibility_weight = 0
|
||||
var/template_flags = TEMPLATE_FLAG_ALLOW_DUPLICATES
|
||||
|
||||
/datum/map_template/New(path = null, rename = null)
|
||||
if(path)
|
||||
|
||||
51
code/modules/maps/planet_types/barren.dm
Normal file
@@ -0,0 +1,51 @@
|
||||
/obj/effect/overmap/visitable/sector/exoplanet/barren
|
||||
name = "barren exoplanet"
|
||||
desc = "An exoplanet that couldn't hold its atmosphere."
|
||||
color = "#6c6c6c"
|
||||
planetary_area = /area/exoplanet/barren
|
||||
rock_colors = list(COLOR_BEIGE, COLOR_GRAY80, COLOR_BROWN)
|
||||
possible_themes = list(/datum/exoplanet_theme/mountains)
|
||||
map_generators = list(/datum/random_map/noise/exoplanet/barren, /datum/random_map/noise/ore/rich)
|
||||
ruin_tags_blacklist = RUIN_HABITAT|RUIN_WATER
|
||||
features_budget = 6
|
||||
surface_color = "#807d7a"
|
||||
water_color = null
|
||||
|
||||
/obj/effect/overmap/visitable/sector/exoplanet/barren/generate_habitability()
|
||||
return HABITABILITY_BAD
|
||||
|
||||
/obj/effect/overmap/visitable/sector/exoplanet/barren/generate_atmosphere()
|
||||
..()
|
||||
atmosphere.remove_ratio(0.9)
|
||||
|
||||
/datum/random_map/noise/exoplanet/barren
|
||||
descriptor = "barren exoplanet"
|
||||
smoothing_iterations = 4
|
||||
land_type = /turf/simulated/floor/exoplanet/barren
|
||||
flora_prob = 0.1
|
||||
flora_diversity = 0
|
||||
fauna_prob = 0
|
||||
|
||||
/datum/random_map/noise/exoplanet/barren/New()
|
||||
if(prob(10))
|
||||
flora_diversity = 1
|
||||
..()
|
||||
|
||||
/turf/simulated/floor/exoplanet/barren
|
||||
name = "ground"
|
||||
icon = 'icons/turf/flooring/asteroid.dmi'
|
||||
icon_state = "asteroid"
|
||||
|
||||
/turf/simulated/floor/exoplanet/barren/update_icon()
|
||||
overlays.Cut()
|
||||
if(prob(20))
|
||||
overlays += image('icons/turf/flooring/decals.dmi', "asteroid[rand(0,9)]")
|
||||
|
||||
/turf/simulated/floor/exoplanet/barren/Initialize()
|
||||
. = ..()
|
||||
update_icon()
|
||||
|
||||
/area/exoplanet/barren
|
||||
name = "\improper Planetary surface"
|
||||
ambience = list('sound/effects/wind/wind_2_1.ogg','sound/effects/wind/wind_2_2.ogg','sound/effects/wind/wind_3_1.ogg','sound/effects/wind/wind_4_1.ogg','sound/effects/wind/wind_4_2.ogg','sound/effects/wind/wind_5_1.ogg')
|
||||
base_turf = /turf/simulated/floor/exoplanet/barren
|
||||
155
code/modules/maps/planet_types/desert.dm
Normal file
@@ -0,0 +1,155 @@
|
||||
/obj/effect/overmap/visitable/sector/exoplanet/desert
|
||||
name = "desert exoplanet"
|
||||
desc = "An arid exoplanet with sparse biological resources but rich mineral deposits underground."
|
||||
color = "#a08444"
|
||||
planetary_area = /area/exoplanet/desert
|
||||
rock_colors = list(COLOR_BEIGE, COLOR_PALE_YELLOW, COLOR_GRAY80, COLOR_BROWN)
|
||||
plant_colors = list("#efdd6f","#7b4a12","#e49135","#ba6222","#5c755e","#420d22")
|
||||
map_generators = list(/datum/random_map/noise/exoplanet/desert)
|
||||
surface_color = "#d6cca4"
|
||||
water_color = null
|
||||
|
||||
/obj/effect/overmap/visitable/sector/exoplanet/desert/generate_map()
|
||||
if(prob(70))
|
||||
lightlevel = rand(5,10)/10 //deserts are usually :lit:
|
||||
..()
|
||||
|
||||
/obj/effect/overmap/visitable/sector/exoplanet/desert/generate_atmosphere()
|
||||
..()
|
||||
if(atmosphere)
|
||||
var/limit = 1000
|
||||
if(habitability_class <= HABITABILITY_OKAY)
|
||||
var/datum/species/human/H = /datum/species/human
|
||||
limit = initial(H.heat_level_1) - rand(1,10)
|
||||
atmosphere.temperature = min(T20C + rand(20, 100), limit)
|
||||
atmosphere.update_values()
|
||||
|
||||
/obj/effect/overmap/visitable/sector/exoplanet/desert/adapt_seed(var/datum/seed/S)
|
||||
..()
|
||||
if(prob(90))
|
||||
S.set_trait(TRAIT_REQUIRES_WATER,0)
|
||||
else
|
||||
S.set_trait(TRAIT_REQUIRES_WATER,1)
|
||||
S.set_trait(TRAIT_WATER_CONSUMPTION,1)
|
||||
if(prob(75))
|
||||
S.set_trait(TRAIT_STINGS,1)
|
||||
if(prob(75))
|
||||
S.set_trait(TRAIT_CARNIVOROUS,2)
|
||||
S.set_trait(TRAIT_SPREAD,0)
|
||||
|
||||
/datum/random_map/noise/exoplanet/desert
|
||||
descriptor = "desert exoplanet"
|
||||
smoothing_iterations = 4
|
||||
land_type = /turf/simulated/floor/exoplanet/desert
|
||||
|
||||
flora_prob = 5
|
||||
flora_diversity = 4
|
||||
fauna_types = list(/mob/living/simple_animal/thinbug, /mob/living/simple_animal/tindalos)
|
||||
|
||||
/datum/random_map/noise/exoplanet/desert/get_additional_spawns(var/value, var/turf/T)
|
||||
..()
|
||||
if(is_edge_turf(T))
|
||||
return
|
||||
var/v = noise2value(value)
|
||||
if(v > 6)
|
||||
T.icon_state = "desert[v-1]"
|
||||
if(prob(10))
|
||||
new/obj/structure/quicksand(T)
|
||||
|
||||
/area/exoplanet/desert
|
||||
ambience = list('sound/effects/wind/desert0.ogg','sound/effects/wind/desert1.ogg','sound/effects/wind/desert2.ogg','sound/effects/wind/desert3.ogg','sound/effects/wind/desert4.ogg','sound/effects/wind/desert5.ogg')
|
||||
base_turf = /turf/simulated/floor/exoplanet/desert
|
||||
|
||||
/obj/structure/quicksand
|
||||
name = "sand"
|
||||
icon = 'icons/obj/quicksand.dmi'
|
||||
icon_state = "intact0"
|
||||
density = 0
|
||||
anchored = 1
|
||||
can_buckle = 1
|
||||
buckle_dir = SOUTH
|
||||
var/exposed = 0
|
||||
var/busy
|
||||
|
||||
/obj/structure/quicksand/New()
|
||||
icon_state = "intact[rand(0,2)]"
|
||||
..()
|
||||
|
||||
/obj/structure/quicksand/user_unbuckle(mob/user)
|
||||
if(buckled && !user.stat && !user.restrained())
|
||||
if(busy)
|
||||
to_chat(user, "<span class='wanoticerning'>[buckled] is already getting out, be patient.</span>")
|
||||
return
|
||||
var/delay = 60
|
||||
if(user == buckled)
|
||||
delay *=2
|
||||
user.visible_message(
|
||||
"<span class='notice'>\The [user] tries to climb out of \the [src].</span>",
|
||||
"<span class='notice'>You begin to pull yourself out of \the [src].</span>",
|
||||
"<span class='notice'>You hear water sloushing.</span>"
|
||||
)
|
||||
else
|
||||
user.visible_message(
|
||||
"<span class='notice'>\The [user] begins pulling \the [buckled] out of \the [src].</span>",
|
||||
"<span class='notice'>You begin to pull \the [buckled] out of \the [src].</span>",
|
||||
"<span class='notice'>You hear water sloushing.</span>"
|
||||
)
|
||||
busy = 1
|
||||
if(do_after(user, delay, src))
|
||||
busy = 0
|
||||
if(user == buckled)
|
||||
if(prob(80))
|
||||
to_chat(user, "<span class='warning'>You slip and fail to get out!</span>")
|
||||
return
|
||||
user.visible_message("<span class='notice'>\The [buckled] pulls himself out of \the [src].</span>")
|
||||
else
|
||||
user.visible_message("<span class='notice'>\The [buckled] has been freed from \the [src] by \the [user].</span>")
|
||||
unbuckle()
|
||||
else
|
||||
busy = 0
|
||||
to_chat(user, "<span class='warning'>You slip and fail to get out!</span>")
|
||||
return
|
||||
|
||||
/obj/structure/quicksand/unbuckle()
|
||||
..()
|
||||
update_icon()
|
||||
|
||||
/obj/structure/quicksand/buckle(var/mob/L)
|
||||
..()
|
||||
update_icon()
|
||||
|
||||
/obj/structure/quicksand/update_icon()
|
||||
if(!exposed)
|
||||
return
|
||||
icon_state = "open"
|
||||
overlays.Cut()
|
||||
if(buckled)
|
||||
overlays += buckled
|
||||
var/image/I = image(icon,icon_state="overlay")
|
||||
I.layer = ABOVE_MOB_LAYER
|
||||
overlays += I
|
||||
|
||||
/obj/structure/quicksand/proc/expose()
|
||||
if(exposed)
|
||||
return
|
||||
visible_message("<span class='warning'>The upper crust breaks, exposing treacherous quicksands underneath!</span>")
|
||||
name = "quicksand"
|
||||
desc = "There is no candy at the bottom."
|
||||
exposed = 1
|
||||
update_icon()
|
||||
|
||||
/obj/structure/quicksand/attackby(obj/item/W, mob/user)
|
||||
if(!exposed && W.force)
|
||||
expose()
|
||||
else
|
||||
..()
|
||||
|
||||
/obj/structure/quicksand/Crossed(var/atom/movable/AM)
|
||||
if(isliving(AM))
|
||||
var/mob/living/L = AM
|
||||
if(L.throwing)
|
||||
return
|
||||
buckle(L)
|
||||
if(!exposed)
|
||||
expose()
|
||||
to_chat(L, SPAN_DANGER("You fall into \the [src]!"))
|
||||
60
code/modules/maps/planet_types/grass.dm
Normal file
@@ -0,0 +1,60 @@
|
||||
/obj/effect/overmap/visitable/sector/exoplanet/grass
|
||||
name = "lush exoplanet"
|
||||
desc = "Planet with abundant flora and fauna."
|
||||
color = "#407c40"
|
||||
planetary_area = /area/exoplanet/grass
|
||||
rock_colors = list(COLOR_ASTEROID_ROCK, COLOR_GRAY80, COLOR_BROWN)
|
||||
plant_colors = list("#0e1e14","#1a3e38","#5a7467","#9eab88","#6e7248", "RANDOM")
|
||||
map_generators = list(/datum/random_map/noise/exoplanet/grass)
|
||||
|
||||
/obj/effect/overmap/visitable/sector/exoplanet/grass/generate_map()
|
||||
if(prob(40))
|
||||
lightlevel = rand(1,7)/10 //give a chance of twilight jungle
|
||||
..()
|
||||
|
||||
/obj/effect/overmap/visitable/sector/exoplanet/grass/generate_atmosphere()
|
||||
..()
|
||||
if(atmosphere)
|
||||
atmosphere.temperature = T20C + rand(10, 30)
|
||||
atmosphere.update_values()
|
||||
|
||||
/obj/effect/overmap/visitable/sector/exoplanet/grass/get_surface_color()
|
||||
return grass_color
|
||||
|
||||
/obj/effect/overmap/visitable/sector/exoplanet/grass/adapt_seed(var/datum/seed/S)
|
||||
..()
|
||||
var/carnivore_prob = rand(100)
|
||||
if(carnivore_prob < 30)
|
||||
S.set_trait(TRAIT_CARNIVOROUS,2)
|
||||
if(prob(75))
|
||||
S.get_trait(TRAIT_STINGS, 1)
|
||||
else if(carnivore_prob < 60)
|
||||
S.set_trait(TRAIT_CARNIVOROUS,1)
|
||||
if(prob(50))
|
||||
S.get_trait(TRAIT_STINGS)
|
||||
if(prob(15) || (S.get_trait(TRAIT_CARNIVOROUS) && prob(40)))
|
||||
S.set_trait(TRAIT_BIOLUM,1)
|
||||
S.set_trait(TRAIT_BIOLUM_COLOUR,get_random_colour(0,75,190))
|
||||
|
||||
if(prob(30))
|
||||
S.set_trait(TRAIT_PARASITE,1)
|
||||
|
||||
/area/exoplanet/grass
|
||||
base_turf = /turf/simulated/floor/exoplanet/grass
|
||||
ambience = list('sound/effects/wind/wind_2_1.ogg','sound/effects/wind/wind_2_2.ogg','sound/effects/wind/wind_3_1.ogg','sound/effects/wind/wind_4_1.ogg','sound/ambience/eeriejungle2.ogg','sound/ambience/eeriejungle1.ogg')
|
||||
|
||||
/area/exoplanet/grass/play_ambience(var/mob/living/L)
|
||||
..()
|
||||
if(!L.ear_deaf && L.client && !L.client.ambience_playing)
|
||||
L.client.ambience_playing = 1
|
||||
L.playsound_to(get_turf(L),sound('sound/ambience/jungle.ogg', repeat = 1, wait = 0, volume = 25))
|
||||
|
||||
/datum/random_map/noise/exoplanet/grass
|
||||
descriptor = "grass exoplanet"
|
||||
smoothing_iterations = 2
|
||||
land_type = /turf/simulated/floor/exoplanet/grass
|
||||
water_type = /turf/simulated/floor/exoplanet/water/shallow
|
||||
|
||||
flora_prob = 10
|
||||
flora_diversity = 6
|
||||
fauna_types = list(/mob/living/simple_animal/yithian, /mob/living/simple_animal/tindalos, /mob/living/simple_animal/cosmozoan)
|
||||
33
code/modules/maps/planet_types/snow.dm
Normal file
@@ -0,0 +1,33 @@
|
||||
/obj/effect/overmap/visitable/sector/exoplanet/snow
|
||||
name = "snow exoplanet"
|
||||
desc = "Cold planet with limited plant life."
|
||||
color = "#dcdcdc"
|
||||
planetary_area = /area/exoplanet/snow
|
||||
rock_colors = list(COLOR_DARK_BLUE_GRAY, COLOR_GUNMETAL, COLOR_GRAY80, COLOR_DARK_GRAY)
|
||||
plant_colors = list("#d0fef5","#93e1d8","#93e1d8", "#b2abbf", "#3590f3", "#4b4e6d")
|
||||
map_generators = list(/datum/random_map/noise/exoplanet/snow)
|
||||
surface_color = "#e8faff"
|
||||
water_color = "#b5dfeb"
|
||||
|
||||
/obj/effect/overmap/visitable/sector/exoplanet/snow/generate_atmosphere()
|
||||
..()
|
||||
if(atmosphere)
|
||||
var/limit = 0
|
||||
if(habitability_class <= HABITABILITY_OKAY)
|
||||
var/datum/species/human/H = /datum/species/human
|
||||
limit = initial(H.cold_level_1) + rand(1,10)
|
||||
atmosphere.temperature = max(T0C - rand(10, 100), limit)
|
||||
atmosphere.update_values()
|
||||
|
||||
/datum/random_map/noise/exoplanet/snow
|
||||
descriptor = "snow exoplanet"
|
||||
smoothing_iterations = 1
|
||||
flora_prob = 5
|
||||
water_level_max = 3
|
||||
land_type = /turf/simulated/floor/exoplanet/snow
|
||||
water_type = /turf/simulated/floor/exoplanet/ice
|
||||
fauna_types = list(/mob/living/simple_animal/hostile/retaliate/samak, /mob/living/simple_animal/hostile/retaliate/diyaab, /mob/living/simple_animal/hostile/retaliate/shantak)
|
||||
|
||||
/area/exoplanet/snow
|
||||
ambience = list('sound/effects/wind/tundra0.ogg','sound/effects/wind/tundra1.ogg','sound/effects/wind/tundra2.ogg','sound/effects/wind/spooky0.ogg','sound/effects/wind/spooky1.ogg')
|
||||
base_turf = /turf/simulated/floor/exoplanet/snow
|
||||
85
code/modules/maps/ruins.dm
Normal file
@@ -0,0 +1,85 @@
|
||||
var/list/banned_ruin_ids = list()
|
||||
|
||||
/proc/seedRuins(list/zlevels, budget, list/potentialRuins, allowed_area = /area/space, var/maxx = world.maxx, var/maxy = world.maxy)
|
||||
if (!length(zlevels))
|
||||
UNLINT(WARNING("No Z levels provided - Not generating ruins"))
|
||||
return
|
||||
|
||||
for (var/z in zlevels)
|
||||
var/turf/check = locate(1, 1, z)
|
||||
if (!check)
|
||||
UNLINT(WARNING("Z level [z] does not exist - Not generating ruins"))
|
||||
return
|
||||
|
||||
var/list/available = list()
|
||||
var/list/selected = list()
|
||||
var/remaining = budget
|
||||
|
||||
for(var/datum/map_template/ruin/ruin in potentialRuins)
|
||||
if (ruin.id in banned_ruin_ids)
|
||||
continue
|
||||
if(!(SSatlas.current_sector.name in ruin.sectors) && !length(ruin.sectors))
|
||||
continue
|
||||
available[ruin] = ruin.spawn_weight
|
||||
|
||||
if (!length(available))
|
||||
UNLINT(WARNING("No ruins available - Not generating ruins"))
|
||||
|
||||
while (remaining > 0 && length(available))
|
||||
var/datum/map_template/ruin/ruin = pickweight(available)
|
||||
if (ruin.cost > budget)
|
||||
available -= ruin
|
||||
continue
|
||||
|
||||
var/width = TRANSITIONEDGE + RUIN_MAP_EDGE_PAD + round(ruin.width / 2)
|
||||
var/height = TRANSITIONEDGE + RUIN_MAP_EDGE_PAD + round(ruin.height / 2)
|
||||
if (width > maxx - width || height > maxy - height)
|
||||
available -= ruin
|
||||
continue
|
||||
|
||||
for (var/attempts = 20, attempts > 0, --attempts)
|
||||
var/z = pick(zlevels)
|
||||
var/turf/choice = locate(rand(width, maxx - width), rand(height, maxy - height), z)
|
||||
|
||||
var/valid = TRUE
|
||||
for (var/turf/check in ruin.get_affected_turfs(choice, 1))
|
||||
var/area/check_area = get_area(check)
|
||||
if (!istype(check_area, allowed_area) || check.flags & TURF_NORUINS)
|
||||
if (attempts == 1)
|
||||
available -= ruin
|
||||
valid = FALSE
|
||||
break
|
||||
if (!valid)
|
||||
continue
|
||||
|
||||
log_admin("Ruin \"[ruin.name]\" placed at ([choice.x], [choice.y], [choice.z])")
|
||||
|
||||
load_ruin(choice, ruin)
|
||||
selected += ruin
|
||||
if (ruin.cost > 0)
|
||||
remaining -= ruin.cost
|
||||
if (!(ruin.template_flags & TEMPLATE_FLAG_ALLOW_DUPLICATES))
|
||||
banned_ruin_ids += ruin.id
|
||||
available -= ruin
|
||||
break
|
||||
|
||||
if (remaining)
|
||||
log_admin("Ruin loader had no ruins to pick from with [budget] left to spend.")
|
||||
|
||||
if (length(selected))
|
||||
log_debug("Finished selecting planet ruins ([english_list(selected)]) for [budget - remaining] cost of [budget] budget.")
|
||||
|
||||
return selected
|
||||
|
||||
/proc/load_ruin(turf/central_turf, datum/map_template/template)
|
||||
if(!template)
|
||||
return FALSE
|
||||
for(var/i in template.get_affected_turfs(central_turf, 1))
|
||||
var/turf/T = i
|
||||
for(var/mob/living/simple_animal/monster in T)
|
||||
qdel(monster)
|
||||
template.load(central_turf,centered = TRUE)
|
||||
var/datum/map_template/ruin = template
|
||||
if(istype(ruin))
|
||||
new /obj/effect/landmark/ruin(central_turf, ruin)
|
||||
return TRUE
|
||||
@@ -265,13 +265,6 @@ var/list/holder_mob_icon_cache = list()
|
||||
var/list/generate_for_slots = list(slot_l_hand_str, slot_r_hand_str, slot_back_str)
|
||||
slot_flags = SLOT_BACK
|
||||
|
||||
|
||||
/obj/item/holder/proc/sync(var/mob/living/M)
|
||||
src.name = M.name
|
||||
src.overlays = M.overlays
|
||||
dir = M.dir
|
||||
reagents = M.reagents
|
||||
|
||||
/obj/item/holder/human/sync(var/mob/living/M)
|
||||
cut_overlays()
|
||||
// Generate appropriate on-mob icons.
|
||||
@@ -354,6 +347,19 @@ var/list/holder_mob_icon_cache = list()
|
||||
H.change_animal_name(usr)
|
||||
sync(contained)
|
||||
|
||||
/obj/item/holder/proc/sync(var/mob/living/M)
|
||||
dir = SOUTH
|
||||
cut_overlays()
|
||||
icon = M.icon
|
||||
icon_state = M.icon_state
|
||||
item_state = M.item_state
|
||||
color = M.color
|
||||
name = M.name
|
||||
desc = M.desc
|
||||
overlays |= M.overlays
|
||||
|
||||
update_held_icon()
|
||||
|
||||
//#TODO-MERGE
|
||||
//Port the reduced-duplication holder method from baystation upstream:
|
||||
//https://github.com/Baystation12/Baystation12/blob/master/code/modules/mob/holder.dm
|
||||
|
||||
@@ -409,9 +409,9 @@ var/list/slot_equipment_priority = list( \
|
||||
return FALSE
|
||||
|
||||
/mob/proc/delete_inventory(var/include_carried = FALSE)
|
||||
for(var/entry in get_equipped_items(include_carried))
|
||||
drop_from_inventory(entry)
|
||||
qdel(entry)
|
||||
for(var/obj/item/I as anything in get_equipped_items(include_carried))
|
||||
drop_from_inventory(I)
|
||||
qdel(I)
|
||||
|
||||
/mob/proc/get_covering_equipped_items(var/body_parts)
|
||||
. = list()
|
||||
@@ -447,3 +447,10 @@ var/list/slot_equipment_priority = list( \
|
||||
return FALSE
|
||||
|
||||
return O.pre_equip(src, visualsOnly)
|
||||
|
||||
// Returns the first item which covers any given body part
|
||||
/mob/proc/get_covering_equipped_item(var/body_parts)
|
||||
for(var/entry in get_equipped_items())
|
||||
var/obj/item/I = entry
|
||||
if(I.body_parts_covered & body_parts)
|
||||
return I
|
||||
|
||||
@@ -484,3 +484,8 @@ This saves us from having to call add_fingerprint() any time something is put in
|
||||
return
|
||||
|
||||
is_noisy = TRUE
|
||||
|
||||
/mob/living/carbon/human/proc/get_covering_equipped_item_by_zone(var/zone)
|
||||
var/obj/item/organ/external/O = get_organ(zone)
|
||||
if(O)
|
||||
return get_covering_equipped_item(O.body_part)
|
||||
|
||||
@@ -98,7 +98,7 @@
|
||||
icon_state = "toxin"
|
||||
|
||||
// Xenoarch aliens.
|
||||
/mob/living/simple_animal/hostile/samak
|
||||
/mob/living/simple_animal/hostile/retaliate/samak
|
||||
name = "samak"
|
||||
desc = "A fast, armored predator accustomed to hiding and ambushing in cold terrain."
|
||||
faction = "samak"
|
||||
@@ -120,7 +120,7 @@
|
||||
emote_hear = list("snuffles")
|
||||
mob_size = 10
|
||||
|
||||
/mob/living/simple_animal/hostile/diyaab
|
||||
/mob/living/simple_animal/hostile/retaliate/diyaab
|
||||
name = "diyaab"
|
||||
desc = "A small pack animal. Although omnivorous, it will hunt meat on occasion."
|
||||
faction = "diyaab"
|
||||
@@ -144,7 +144,7 @@
|
||||
density = 0
|
||||
mob_size = 3
|
||||
|
||||
/mob/living/simple_animal/hostile/shantak
|
||||
/mob/living/simple_animal/hostile/retaliate/shantak
|
||||
name = "shantak"
|
||||
desc = "A piglike creature with a bright iridiscent mane that sparkles as though lit by an inner light. Don't be fooled by its beauty though."
|
||||
faction = "shantak"
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
var/list/targets = list()
|
||||
var/attacked_times = 0
|
||||
var/list/target_type_validator_map = list()
|
||||
var/list/tolerated_types = list()
|
||||
var/attack_emote = "stares menacingly at"
|
||||
|
||||
var/smart_melee = TRUE // This makes melee mobs try to stay two tiles away from their target in combat, lunging in to attack only
|
||||
@@ -171,6 +172,9 @@ mob/living/simple_animal/hostile/hitby(atom/movable/AM as mob|obj,var/speed = TH
|
||||
else
|
||||
return 0
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/on_attack_mob(var/mob/hit_mob)
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/AttackingTarget()
|
||||
setClickCooldown(attack_delay)
|
||||
if(!Adjacent(target_mob))
|
||||
@@ -189,6 +193,7 @@ mob/living/simple_animal/hostile/hitby(atom/movable/AM as mob|obj,var/speed = TH
|
||||
if(isliving(target_mob))
|
||||
var/mob/living/L = target_mob
|
||||
L.attack_generic(src, rand(melee_damage_lower, melee_damage_upper), attacktext)
|
||||
on_attack_mob(L)
|
||||
target = L
|
||||
else if(istype(target_mob, /obj/machinery/bot))
|
||||
var/obj/machinery/bot/B = target_mob
|
||||
@@ -409,6 +414,8 @@ mob/living/simple_animal/hostile/hitby(atom/movable/AM as mob|obj,var/speed = TH
|
||||
current_health = M.health
|
||||
if(L.health < current_health)
|
||||
return TRUE
|
||||
if(tolerated_types[L.type] == TRUE)
|
||||
return FALSE
|
||||
return FALSE
|
||||
|
||||
/mob/living/simple_animal/hostile/proc/validator_bot(var/obj/machinery/bot/B, var/atom/current)
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
/mob/living/simple_animal/thinbug
|
||||
name = "taki"
|
||||
desc = "It looks like a bunch of legs."
|
||||
icon_state = "thinbug"
|
||||
icon_living = "thinbug"
|
||||
icon_dead = "thinbug_dead"
|
||||
mob_size = MOB_MINISCULE
|
||||
density = FALSE
|
||||
|
||||
emote_hear = list("scratches the ground", "rubs its legs together", "chitters")
|
||||
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/royalcrab
|
||||
name = "cragenoy"
|
||||
desc = "It looks like a crustacean with an exceedingly hard carapace. Watch the pinchers!"
|
||||
faction = "crab"
|
||||
icon_state = "royalcrab"
|
||||
icon_living = "royalcrab"
|
||||
icon_dead = "royalcrab_dead"
|
||||
move_to_delay = 3
|
||||
maxHealth = 150
|
||||
health = 150
|
||||
speed = 1
|
||||
melee_damage_lower = 10
|
||||
melee_damage_upper = 15
|
||||
natural_armor = list(
|
||||
melee = ARMOR_MELEE_RESISTANT
|
||||
)
|
||||
|
||||
emote_see = list("skitters","oozes liquid from its mouth", "scratches at the ground", "clicks its claws")
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/beast/charbaby
|
||||
name = "charbaby"
|
||||
desc = "A huge grubby creature."
|
||||
icon_state = "char"
|
||||
icon_living = "char"
|
||||
icon_dead = "char_dead"
|
||||
mob_size = MOB_LARGE
|
||||
health = 45
|
||||
maxHealth = 45
|
||||
speed = 2
|
||||
response_help = "pats briefly"
|
||||
response_disarm = "gently pushes"
|
||||
response_harm = "strikes"
|
||||
harm_intent_damage = 1
|
||||
melee_damage_lower = 5
|
||||
melee_damage_upper = 10
|
||||
blood_color = COLOR_RED
|
||||
natural_armor = list(
|
||||
laser = ARMOR_LASER_PISTOL
|
||||
)
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/beast/charbaby/on_attack_mob(var/mob/hit_mob)
|
||||
. = ..()
|
||||
if(isliving(hit_mob) && prob(25))
|
||||
var/mob/living/L = hit_mob
|
||||
if(prob(10))
|
||||
L.adjust_fire_stacks(1)
|
||||
L.IgniteMob()
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/beast/charbaby/attack_hand(mob/living/carbon/human/H)
|
||||
. = ..()
|
||||
reflect_unarmed_damage(H, BURN, "amorphous mass")
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/beast/shantak/lava
|
||||
desc = "A vaguely canine looking beast. It looks as though its fur is made of stone wool."
|
||||
icon_state = "lavadog"
|
||||
icon_living = "lavadog"
|
||||
icon_dead = "lavadog_dead"
|
||||
|
||||
speak = list("Karuph!", "Karump!")
|
||||
@@ -27,4 +27,26 @@
|
||||
|
||||
for(var/mob/living/simple_animal/hostile/retaliate/H in view(world.view, get_turf(src)))
|
||||
if(H.faction == faction)
|
||||
H.enemies |= M
|
||||
H.enemies |= M
|
||||
|
||||
/mob/living/simple_animal/proc/name_species()
|
||||
set name = "Name Alien Species"
|
||||
set category = "Object"
|
||||
set src in view()
|
||||
|
||||
if(!current_map.use_overmap)
|
||||
return
|
||||
|
||||
if(use_check_and_message(usr))
|
||||
return
|
||||
|
||||
for(var/obj/effect/overmap/visitable/sector/exoplanet/E in SSshuttle.initialized_sectors)
|
||||
if(src in E.animals)
|
||||
var/newname = input("What do you want to name this species?", "Species naming", E.get_random_species_name()) as text|null
|
||||
newname = sanitizeName(newname, allow_numbers = TRUE)
|
||||
if(newname && !use_check_and_message(usr))
|
||||
if(E.rename_species(type, newname))
|
||||
to_chat(usr,"<span class='notice'>This species will be known from now on as '[newname]'.</span>")
|
||||
else
|
||||
to_chat(usr,"<span class='warning'>This species has already been named!</span>")
|
||||
return
|
||||
@@ -136,6 +136,13 @@
|
||||
|
||||
var/psi_pingable = TRUE
|
||||
|
||||
var/armor_type = /datum/component/armor
|
||||
var/list/natural_armor //what armor animal has
|
||||
|
||||
//for simple animals that reflect damage when attacked in melee
|
||||
var/return_damage_min
|
||||
var/return_damage_max
|
||||
|
||||
|
||||
/mob/living/simple_animal/proc/update_nutrition_stats()
|
||||
nutrition_step = mob_size * 0.03 * metabolic_factor
|
||||
@@ -160,6 +167,9 @@
|
||||
udder = new(50)
|
||||
udder.my_atom = src
|
||||
|
||||
if(LAZYLEN(natural_armor))
|
||||
AddComponent(armor_type, natural_armor)
|
||||
|
||||
/mob/living/simple_animal/Move(NewLoc, direct)
|
||||
. = ..()
|
||||
if(.)
|
||||
@@ -940,6 +950,17 @@
|
||||
else
|
||||
return FALSE
|
||||
|
||||
/mob/living/simple_animal/proc/reflect_unarmed_damage(var/mob/living/carbon/human/attacker, var/damage_type, var/description)
|
||||
if(attacker.a_intent == I_HURT)
|
||||
var/hand_hurtie
|
||||
if(attacker.hand)
|
||||
hand_hurtie = BP_L_HAND
|
||||
else
|
||||
hand_hurtie = BP_R_HAND
|
||||
attacker.apply_damage(rand(return_damage_min, return_damage_max), damage_type, hand_hurtie, used_weapon = description)
|
||||
if(rand(25))
|
||||
to_chat(attacker, SPAN_WARNING("Your attack has no obvious effect on \the [src]'s [description]!"))
|
||||
|
||||
#undef BLOOD_NONE
|
||||
#undef BLOOD_LIGHT
|
||||
#undef BLOOD_MEDIUM
|
||||
|
||||
@@ -37,9 +37,9 @@
|
||||
/proc/GetConnectedZlevels(z)
|
||||
. = list(z)
|
||||
for(var/level = z, HAS_BELOW(level), level--)
|
||||
. += level-1
|
||||
. |= level-1
|
||||
for(var/level = z, HAS_ABOVE(level), level++)
|
||||
. += level+1
|
||||
. |= level+1
|
||||
|
||||
/proc/AreConnectedZLevels(var/zA, var/zB)
|
||||
if (zA == zB)
|
||||
|
||||
419
code/modules/overmap/exoplanets/exoplanet.dm
Normal file
@@ -0,0 +1,419 @@
|
||||
/obj/effect/overmap/visitable/sector/exoplanet
|
||||
name = "exoplanet"
|
||||
icon_state = "globe"
|
||||
in_space = 0
|
||||
var/area/planetary_area
|
||||
var/list/seeds = list()
|
||||
var/list/animals = list()
|
||||
var/max_animal_count
|
||||
var/datum/gas_mixture/atmosphere
|
||||
var/list/breathgas = list() //list of gases animals/plants require to survive
|
||||
var/badgas //id of gas that is toxic to life here
|
||||
|
||||
var/lightlevel = 0 //This default makes turfs not generate light. Adjust to have exoplanents be lit.
|
||||
var/night = TRUE
|
||||
var/daycycle //How often do we change day and night
|
||||
var/daycolumn = 0 //Which column's light needs to be updated next?
|
||||
var/daycycle_column_delay = 10 SECONDS
|
||||
|
||||
var/maxx
|
||||
var/maxy
|
||||
var/landmark_type = /obj/effect/shuttle_landmark/automatic
|
||||
|
||||
var/list/rock_colors = list(COLOR_ASTEROID_ROCK)
|
||||
var/list/plant_colors = list("RANDOM")
|
||||
var/grass_color
|
||||
var/surface_color = COLOR_ASTEROID_ROCK
|
||||
var/water_color = "#436499"
|
||||
var/image/skybox_image
|
||||
|
||||
var/list/actors = list() //things that appear in engravings on xenoarch finds.
|
||||
var/list/species = list() //list of names to use for simple animals
|
||||
|
||||
var/repopulating = 0
|
||||
var/repopulate_types = list() // animals which have died that may come back
|
||||
|
||||
var/list/possible_themes = list(/datum/exoplanet_theme)
|
||||
var/list/themes = list()
|
||||
|
||||
var/list/map_generators = list()
|
||||
|
||||
//Flags deciding what features to pick
|
||||
var/ruin_tags_whitelist
|
||||
var/ruin_tags_blacklist
|
||||
var/features_budget = 4
|
||||
var/list/possible_features = list()
|
||||
var/list/spawned_features
|
||||
|
||||
var/habitability_class
|
||||
|
||||
var/list/mobs_to_tolerate = list()
|
||||
|
||||
/obj/effect/overmap/visitable/sector/exoplanet/proc/generate_habitability()
|
||||
var/roll = rand(1,100)
|
||||
switch(roll)
|
||||
if(1 to 10)
|
||||
habitability_class = HABITABILITY_IDEAL
|
||||
if(11 to 50)
|
||||
habitability_class = HABITABILITY_OKAY
|
||||
else
|
||||
habitability_class = HABITABILITY_BAD
|
||||
|
||||
/obj/effect/overmap/visitable/sector/exoplanet/New(nloc, max_x, max_y)
|
||||
if(!current_map.use_overmap)
|
||||
return
|
||||
|
||||
maxx = max_x ? max_x : world.maxx
|
||||
maxy = max_y ? max_y : world.maxy
|
||||
planetary_area = new planetary_area()
|
||||
|
||||
name = "[generate_planet_name()], \a [name]"
|
||||
|
||||
world.maxz++
|
||||
forceMove(locate(1,1,world.maxz))
|
||||
|
||||
if(LAZYLEN(possible_themes))
|
||||
var/datum/exoplanet_theme/T = pick(possible_themes)
|
||||
themes += new T
|
||||
|
||||
for(var/T in subtypesof(/datum/map_template/ruin/exoplanet))
|
||||
var/datum/map_template/ruin/exoplanet/ruin = T
|
||||
if(ruin_tags_whitelist && !(ruin_tags_whitelist & initial(ruin.ruin_tags)))
|
||||
continue
|
||||
if(ruin_tags_blacklist & initial(ruin.ruin_tags))
|
||||
continue
|
||||
possible_features += new ruin
|
||||
..()
|
||||
|
||||
/obj/effect/overmap/visitable/sector/exoplanet/proc/build_level()
|
||||
generate_habitability()
|
||||
generate_atmosphere()
|
||||
generate_map()
|
||||
generate_features()
|
||||
generate_landing(2)
|
||||
update_biome()
|
||||
generate_daycycle()
|
||||
START_PROCESSING(SSprocessing, src)
|
||||
|
||||
//attempt at more consistent history generation for xenoarch finds.
|
||||
/obj/effect/overmap/visitable/sector/exoplanet/proc/get_engravings()
|
||||
if(!actors.len)
|
||||
actors += pick("alien humanoid","an amorphic blob","a short, hairy being","a rodent-like creature","a robot","a primate","a reptilian alien","an unidentifiable object","a statue","a starship","unusual devices","a structure")
|
||||
actors += pick("alien humanoids","amorphic blobs","short, hairy beings","rodent-like creatures","robots","primates","reptilian aliens")
|
||||
|
||||
var/engravings = "[actors[1]] \
|
||||
[pick("surrounded by","being held aloft by","being struck by","being examined by","communicating with")] \
|
||||
[actors[2]]"
|
||||
if(prob(50))
|
||||
engravings += ", [pick("they seem to be enjoying themselves","they seem extremely angry","they look pensive","they are making gestures of supplication","the scene is one of subtle horror","the scene conveys a sense of desperation","the scene is completely bizarre")]"
|
||||
engravings += "."
|
||||
return engravings
|
||||
|
||||
/obj/effect/overmap/visitable/sector/exoplanet/process(wait, tick)
|
||||
if(animals.len < 0.5*max_animal_count && !repopulating)
|
||||
repopulating = 1
|
||||
max_animal_count = round(max_animal_count * 0.5)
|
||||
for(var/zlevel in map_z)
|
||||
if(repopulating)
|
||||
for(var/i = 1 to round(max_animal_count - animals.len))
|
||||
if(prob(10))
|
||||
var/turf/simulated/T = pick_area_turf(planetary_area, list(/proc/not_turf_contains_dense_objects))
|
||||
var/mob_type = pick(repopulate_types)
|
||||
var/mob/S = new mob_type(T)
|
||||
animals += S
|
||||
death_event.register(S, src, /obj/effect/overmap/visitable/sector/exoplanet/proc/remove_animal)
|
||||
destroyed_event.register(S, src, /obj/effect/overmap/visitable/sector/exoplanet/proc/remove_animal)
|
||||
adapt_animal(S)
|
||||
if(animals.len >= max_animal_count)
|
||||
repopulating = 0
|
||||
|
||||
if(!atmosphere)
|
||||
continue
|
||||
var/zone/Z
|
||||
for(var/i = 1 to maxx)
|
||||
var/turf/simulated/T = locate(i, 2, zlevel)
|
||||
if(istype(T) && T.zone && T.zone.contents.len > (maxx*maxy*0.25)) //if it's a zone quarter of zlevel, good enough odds it's planetary main one
|
||||
Z = T.zone
|
||||
break
|
||||
if(Z && !Z.fire_tiles.len && !atmosphere.compare(Z.air)) //let fire die out first if there is one
|
||||
var/datum/gas_mixture/daddy = new() //make a fake 'planet' zone gas
|
||||
daddy.copy_from(atmosphere)
|
||||
daddy.group_multiplier = Z.air.group_multiplier
|
||||
Z.air.equalize(daddy)
|
||||
|
||||
if(daycycle)
|
||||
if(tick % round(daycycle / wait) == 0)
|
||||
night = !night
|
||||
daycolumn = 1
|
||||
if(daycolumn && tick % round(daycycle_column_delay / wait) == 0)
|
||||
update_daynight()
|
||||
|
||||
/obj/effect/overmap/visitable/sector/exoplanet/proc/update_daynight()
|
||||
var/light = 0.1
|
||||
if(!night)
|
||||
light = lightlevel
|
||||
for(var/turf/simulated/floor/exoplanet/T in block(locate(daycolumn,1,min(map_z)),locate(daycolumn,maxy,max(map_z))))
|
||||
T.set_light(light, 0.1, 2)
|
||||
daycolumn++
|
||||
if(daycolumn > maxx)
|
||||
daycolumn = 0
|
||||
|
||||
/obj/effect/overmap/visitable/sector/exoplanet/proc/remove_animal(var/mob/M)
|
||||
animals -= M
|
||||
death_event.unregister(M, src)
|
||||
destroyed_event.unregister(M, src)
|
||||
repopulate_types |= M.type
|
||||
|
||||
/obj/effect/overmap/visitable/sector/exoplanet/proc/generate_map()
|
||||
var/list/grasscolors = plant_colors.Copy()
|
||||
grasscolors -= "RANDOM"
|
||||
if(length(grasscolors))
|
||||
grass_color = pick(grasscolors)
|
||||
|
||||
for(var/datum/exoplanet_theme/T as anything in themes)
|
||||
T.before_map_generation(src)
|
||||
for(var/zlevel in map_z)
|
||||
for(var/map_type in map_generators)
|
||||
if(ispath(map_type, /datum/random_map/noise/exoplanet))
|
||||
var/datum/random_map/noise/exoplanet/RM = new map_type(null,1,1,zlevel,maxx,maxy,0,1,1,planetary_area, plant_colors)
|
||||
get_biostuff(RM)
|
||||
else
|
||||
new map_type(null,1,1,zlevel,maxx,maxy,0,1,1,planetary_area)
|
||||
|
||||
var/list/edges
|
||||
edges += block(locate(1, 1, zlevel), locate(TRANSITIONEDGE, maxy, zlevel))
|
||||
edges |= block(locate(maxx-TRANSITIONEDGE+1, 1, zlevel),locate(maxx, maxy, zlevel))
|
||||
edges |= block(locate(1, 1, zlevel), locate(maxx, TRANSITIONEDGE, zlevel))
|
||||
edges |= block(locate(1, maxy-TRANSITIONEDGE+1, zlevel),locate(maxx, maxy, zlevel))
|
||||
for(var/turf/T in edges)
|
||||
T.ChangeTurf(/turf/simulated/planet_edge)
|
||||
|
||||
/obj/effect/overmap/visitable/sector/exoplanet/proc/generate_features()
|
||||
spawned_features = seedRuins(map_z, features_budget, possible_features, /area/exoplanet, maxx, maxy)
|
||||
|
||||
/obj/effect/overmap/visitable/sector/exoplanet/proc/get_biostuff(var/datum/random_map/noise/exoplanet/random_map)
|
||||
if(!istype(random_map))
|
||||
return
|
||||
seeds += random_map.small_flora_types
|
||||
if(random_map.big_flora_types)
|
||||
seeds += random_map.big_flora_types
|
||||
for(var/mob/living/simple_animal/A in living_mob_list)
|
||||
if(A.z in map_z)
|
||||
animals += A
|
||||
death_event.register(A, src, /obj/effect/overmap/visitable/sector/exoplanet/proc/remove_animal)
|
||||
destroyed_event.register(A, src, /obj/effect/overmap/visitable/sector/exoplanet/proc/remove_animal)
|
||||
max_animal_count = animals.len
|
||||
for(var/type in random_map.fauna_types)
|
||||
mobs_to_tolerate[type] = TRUE
|
||||
|
||||
/obj/effect/overmap/visitable/sector/exoplanet/proc/update_biome()
|
||||
for(var/datum/seed/S as anything in seeds)
|
||||
adapt_seed(S)
|
||||
|
||||
for(var/mob/living/simple_animal/A as anything in animals)
|
||||
adapt_animal(A)
|
||||
|
||||
/obj/effect/overmap/visitable/sector/exoplanet/proc/generate_daycycle()
|
||||
if(lightlevel)
|
||||
night = FALSE //we start with a day if we have light.
|
||||
|
||||
//When you set daycycle ensure that the minimum is larger than [maxx * daycycle_column_delay].
|
||||
//Otherwise the right side of the exoplanet can get stuck in a forever day.
|
||||
daycycle = rand(10 MINUTES, 40 MINUTES)
|
||||
|
||||
/obj/effect/overmap/visitable/sector/exoplanet/proc/adapt_seed(var/datum/seed/S)
|
||||
S.set_trait(TRAIT_IDEAL_HEAT, atmosphere.temperature + rand(-5,5),800,70)
|
||||
S.set_trait(TRAIT_HEAT_TOLERANCE, S.get_trait(TRAIT_HEAT_TOLERANCE) + rand(-5,5),800,70)
|
||||
S.set_trait(TRAIT_LOWKPA_TOLERANCE, atmosphere.return_pressure() + rand(-5,-50),80,0)
|
||||
S.set_trait(TRAIT_HIGHKPA_TOLERANCE, atmosphere.return_pressure() + rand(5,50),500,110)
|
||||
if(S.exude_gasses)
|
||||
S.exude_gasses -= badgas
|
||||
if(atmosphere)
|
||||
if(S.consume_gasses)
|
||||
S.consume_gasses = list(pick(atmosphere.gas)) // ensure that if the plant consumes a gas, the atmosphere will have it
|
||||
for(var/g in atmosphere.gas)
|
||||
if(gas_data.flags[g] & XGM_GAS_CONTAMINANT)
|
||||
S.set_trait(TRAIT_TOXINS_TOLERANCE, rand(10,15))
|
||||
|
||||
/obj/effect/overmap/visitable/sector/exoplanet/proc/adapt_animal(var/mob/living/simple_animal/A)
|
||||
if(species[A.type])
|
||||
A.name = species[A.type]
|
||||
A.real_name = species[A.type]
|
||||
else
|
||||
A.name = "alien creature"
|
||||
A.real_name = "alien creature"
|
||||
A.verbs |= /mob/living/simple_animal/proc/name_species
|
||||
if(istype(A, /mob/living/simple_animal/hostile))
|
||||
var/mob/living/simple_animal/hostile/AH = A
|
||||
AH.tolerated_types = mobs_to_tolerate.Copy()
|
||||
if(atmosphere)
|
||||
//Set up gases for living things
|
||||
if(!LAZYLEN(breathgas))
|
||||
var/list/goodgases = gas_data.gases.Copy()
|
||||
var/gasnum = min(rand(1,3), goodgases.len)
|
||||
for(var/i = 1 to gasnum)
|
||||
var/gas = pick(goodgases)
|
||||
breathgas[gas] = round(0.4*goodgases[gas], 0.1)
|
||||
goodgases -= gas
|
||||
if(!badgas)
|
||||
var/list/badgases = gas_data.gases.Copy()
|
||||
badgases -= atmosphere.gas
|
||||
badgas = pick(badgases)
|
||||
|
||||
A.minbodytemp = atmosphere.temperature - 20
|
||||
A.maxbodytemp = atmosphere.temperature + 30
|
||||
A.bodytemperature = (A.maxbodytemp+A.minbodytemp)/2
|
||||
|
||||
/obj/effect/overmap/visitable/sector/exoplanet/proc/get_random_species_name()
|
||||
return pick("nol","shan","can","fel","xor")+pick("a","e","o","t","ar")+pick("ian","oid","ac","ese","inian","rd")
|
||||
|
||||
/obj/effect/overmap/visitable/sector/exoplanet/proc/rename_species(var/species_type, var/newname, var/force = FALSE)
|
||||
if(species[species_type] && !force)
|
||||
return FALSE
|
||||
|
||||
species[species_type] = newname
|
||||
log_and_message_admins("renamed [species_type] to [newname]")
|
||||
for(var/mob/living/simple_animal/A in animals)
|
||||
if(istype(A,species_type))
|
||||
A.name = newname
|
||||
A.real_name = newname
|
||||
A.verbs -= /mob/living/simple_animal/proc/name_species
|
||||
return TRUE
|
||||
|
||||
//This tries to generate "num" landing spots on the map.
|
||||
// A landing spot is a 20x20 zone where the shuttle can land where each tile has a area of /area/exoplanet and no ruins on top of it
|
||||
// It makes num*20 attempts to pick a landing spot, during which it attempts to find a area which meets the above criteria.
|
||||
// If it that does not work, it tries to clear the area
|
||||
//There is also a sanity check to ensure that the map isnt too small to handle the landing spot
|
||||
/obj/effect/overmap/visitable/sector/exoplanet/proc/generate_landing(num = 1)
|
||||
var/places = list()
|
||||
var/attempts = 20*num
|
||||
var/new_type = landmark_type
|
||||
|
||||
//sanity-check map size
|
||||
var/lm_min_x = TRANSITIONEDGE+10
|
||||
var/lm_max_x = maxx-TRANSITIONEDGE-10
|
||||
var/lm_min_y = TRANSITIONEDGE+10
|
||||
var/lm_max_y = maxy-TRANSITIONEDGE-10
|
||||
if (lm_max_x < lm_min_x || lm_max_y < lm_min_y)
|
||||
log_and_message_admins("Map Size is too small to Support Away Mission Shuttle Landmark. [lm_min_x] [lm_max_x] [lm_min_y] [lm_max_y]")
|
||||
return
|
||||
|
||||
while(num)
|
||||
attempts--
|
||||
var/turf/T = locate(rand(lm_min_x, lm_max_x), rand(lm_min_y, lm_max_y),map_z[map_z.len])
|
||||
if(!T || (T in places)) // Two landmarks on one turf is forbidden as the landmark code doesn't work with it.
|
||||
continue
|
||||
if(attempts >= 0) // While we have the patience, try to find better spawn points. If out of patience, put them down wherever, so long as there are no repeats.
|
||||
var/valid = 1
|
||||
var/list/block_to_check = block(locate(T.x - 10, T.y - 10, T.z), locate(T.x + 10, T.y + 10, T.z))
|
||||
for(var/turf/check in block_to_check)
|
||||
if(!istype(get_area(check), /area/exoplanet) || check.flags & TURF_NORUINS)
|
||||
valid = 0
|
||||
break
|
||||
if(attempts >= 10)
|
||||
if(check_collision(T.loc, block_to_check)) //While we have lots of patience, ensure landability
|
||||
valid = 0
|
||||
else //Running out of patience, but would rather not clear ruins, so switch to clearing landmarks and bypass landability check
|
||||
new_type = /obj/effect/shuttle_landmark/automatic/clearing
|
||||
|
||||
if(!valid)
|
||||
continue
|
||||
|
||||
num--
|
||||
places += T
|
||||
new new_type(T)
|
||||
|
||||
/obj/effect/overmap/visitable/sector/exoplanet/proc/generate_atmosphere()
|
||||
atmosphere = new
|
||||
if(habitability_class == HABITABILITY_IDEAL)
|
||||
atmosphere.adjust_gas(GAS_OXYGEN, MOLES_O2STANDARD, 0)
|
||||
atmosphere.adjust_gas(GAS_NITROGEN, MOLES_N2STANDARD)
|
||||
else //let the fuckery commence
|
||||
var/list/newgases = gas_data.gases.Copy()
|
||||
if(prob(90)) //all phoron planet should be rare
|
||||
newgases -= GAS_PHORON
|
||||
if(prob(50)) //alium gas should be slightly less common than mundane shit
|
||||
newgases -= GAS_ALIEN
|
||||
newgases -= GAS_STEAM
|
||||
|
||||
var/total_moles = MOLES_CELLSTANDARD * rand(80,120)/100
|
||||
var/badflag = 0
|
||||
|
||||
//Breathable planet
|
||||
if(habitability_class == HABITABILITY_OKAY)
|
||||
atmosphere.gas[GAS_OXYGEN] += MOLES_O2STANDARD
|
||||
total_moles -= MOLES_O2STANDARD
|
||||
badflag = XGM_GAS_FUEL|XGM_GAS_CONTAMINANT
|
||||
|
||||
var/gasnum = rand(1,4)
|
||||
var/i = 1
|
||||
var/sanity = prob(99.9)
|
||||
while(i <= gasnum && total_moles && newgases.len)
|
||||
if(badflag && sanity)
|
||||
for(var/g in newgases)
|
||||
if(gas_data.flags[g] & badflag)
|
||||
newgases -= g
|
||||
var/ng = pick_n_take(newgases) //pick a gas
|
||||
if(sanity) //make sure atmosphere is not flammable... always
|
||||
if(gas_data.flags[ng] & XGM_GAS_OXIDIZER)
|
||||
badflag |= XGM_GAS_FUEL
|
||||
if(gas_data.flags[ng] & XGM_GAS_FUEL)
|
||||
badflag |= XGM_GAS_OXIDIZER
|
||||
sanity = 0
|
||||
|
||||
var/part = total_moles * rand(3,80)/100 //allocate percentage to it
|
||||
if(i == gasnum || !newgases.len) //if it's last gas, let it have all remaining moles
|
||||
part = total_moles
|
||||
atmosphere.gas[ng] += part
|
||||
total_moles = max(total_moles - part, 0)
|
||||
i++
|
||||
|
||||
/obj/effect/overmap/visitable/sector/exoplanet/get_scan_data(mob/user)
|
||||
. = ..()
|
||||
var/list/extra_data = list("<hr>")
|
||||
if(atmosphere)
|
||||
var/list/gases = list()
|
||||
for(var/g in atmosphere.gas)
|
||||
if(atmosphere.gas[g] > atmosphere.total_moles * 0.05)
|
||||
gases += gas_data.name[g]
|
||||
extra_data += "Atmosphere composition: [english_list(gases)]"
|
||||
var/inaccuracy = rand(8,12)/10
|
||||
extra_data += "Atmosphere pressure [atmosphere.return_pressure()*inaccuracy] kPa, temperature [atmosphere.temperature*inaccuracy] K"
|
||||
extra_data += "<hr>"
|
||||
|
||||
if(seeds.len)
|
||||
extra_data += "Xenoflora detected"
|
||||
|
||||
if(animals.len)
|
||||
extra_data += "Life traces detected"
|
||||
|
||||
if(LAZYLEN(spawned_features))
|
||||
var/ruin_num = 0
|
||||
for(var/datum/map_template/ruin/exoplanet/R in spawned_features)
|
||||
if(!(R.ruin_tags & RUIN_NATURAL))
|
||||
ruin_num++
|
||||
if(ruin_num)
|
||||
extra_data += "<hr>[ruin_num] possible artificial structure\s detected."
|
||||
|
||||
. += jointext(extra_data, "<br>")
|
||||
|
||||
/obj/effect/overmap/visitable/sector/exoplanet/get_skybox_representation()
|
||||
return skybox_image
|
||||
|
||||
|
||||
/obj/effect/overmap/visitable/sector/exoplanet/proc/get_surface_color()
|
||||
return surface_color
|
||||
|
||||
/obj/effect/overmap/visitable/sector/exoplanet/proc/get_atmosphere_color()
|
||||
var/list/colors = list()
|
||||
for(var/g in atmosphere.gas)
|
||||
if(gas_data.tile_overlay_color[g])
|
||||
colors += gas_data.tile_overlay_color[g]
|
||||
if(colors.len)
|
||||
return MixColors(colors)
|
||||
|
||||
/area/exoplanet
|
||||
name = "\improper Planetary surface"
|
||||
ambience = list('sound/effects/wind/wind_2_1.ogg','sound/effects/wind/wind_2_2.ogg','sound/effects/wind/wind_3_1.ogg','sound/effects/wind/wind_4_1.ogg','sound/effects/wind/wind_4_2.ogg','sound/effects/wind/wind_5_1.ogg')
|
||||
always_unpowered = 1
|
||||
127
code/modules/overmap/exoplanets/random_map.dm
Normal file
@@ -0,0 +1,127 @@
|
||||
/datum/random_map/noise/exoplanet
|
||||
descriptor = "exoplanet"
|
||||
smoothing_iterations = 1
|
||||
|
||||
var/water_level
|
||||
var/water_level_min = 0
|
||||
var/water_level_max = 5
|
||||
var/land_type = /turf/simulated/floor
|
||||
var/water_type
|
||||
|
||||
//intended x*y size, used to adjust spawn probs
|
||||
var/intended_x = 150
|
||||
var/intended_y = 150
|
||||
var/flora_prob = 10
|
||||
var/flora_diversity = 4
|
||||
var/fauna_prob = 2
|
||||
var/megafauna_spawn_prob = 0.5 //chance that a given fauna mob will instead be a megafauna
|
||||
|
||||
var/list/fauna_types = list()
|
||||
var/list/small_flora_types = list()
|
||||
var/list/big_flora_types = list()
|
||||
var/list/plantcolors = list("RANDOM")
|
||||
var/list/grass_cache
|
||||
|
||||
/datum/random_map/noise/exoplanet/New(var/seed, var/tx, var/ty, var/tz, var/tlx, var/tly, var/do_not_apply, var/do_not_announce, var/never_be_priority = 0, var/used_area, var/list/_plant_colors)
|
||||
log_debug("Generating Random Exoplanet Map with tx: [tx], ty: [ty], tz: [tz], tlx: [tlx], tly: [tly]")
|
||||
target_turf_type = world.turf
|
||||
water_level = rand(water_level_min,water_level_max)
|
||||
//automagically adjust probs for bigger maps to help with lag
|
||||
var/size_mod = intended_x / tlx * intended_y / tly
|
||||
flora_prob *= size_mod
|
||||
fauna_prob *= size_mod
|
||||
if(_plant_colors)
|
||||
plantcolors = _plant_colors
|
||||
generate_flora()
|
||||
..()
|
||||
|
||||
current_map.base_turf_by_z[num2text(tz)] = land_type
|
||||
|
||||
/datum/random_map/noise/exoplanet/proc/is_edge_turf(turf/T)
|
||||
return T.x <= TRANSITIONEDGE || T.x >= (limit_x - TRANSITIONEDGE + 1) || T.y <= TRANSITIONEDGE || T.y >= (limit_y - TRANSITIONEDGE + 1)
|
||||
|
||||
/datum/random_map/noise/exoplanet/get_map_char(var/value)
|
||||
if(water_type && noise2value(value) < water_level)
|
||||
return "~"
|
||||
return "[noise2value(value)]"
|
||||
|
||||
/datum/random_map/noise/exoplanet/get_appropriate_path(var/value)
|
||||
if(water_type && noise2value(value) < water_level)
|
||||
return water_type
|
||||
else
|
||||
return land_type
|
||||
|
||||
/datum/random_map/noise/exoplanet/get_additional_spawns(var/value, var/turf/T)
|
||||
if(is_edge_turf(T))
|
||||
return
|
||||
if(T.is_wall())
|
||||
return
|
||||
var/parsed_value = noise2value(value)
|
||||
switch(parsed_value)
|
||||
if(2 to 3)
|
||||
if(prob(fauna_prob))
|
||||
spawn_fauna(T)
|
||||
if(5 to 6)
|
||||
if(flora_prob > 5 && prob(flora_prob * 5))
|
||||
spawn_grass(T)
|
||||
if(prob(flora_prob/3))
|
||||
spawn_flora(T)
|
||||
if(7 to 9)
|
||||
if(flora_prob > 1 && prob(flora_prob * 10))
|
||||
spawn_grass(T)
|
||||
if(prob(flora_prob))
|
||||
spawn_flora(T)
|
||||
|
||||
/datum/random_map/noise/exoplanet/proc/spawn_fauna(var/turf/T)
|
||||
if(LAZYLEN(fauna_types))
|
||||
var/beastie = pick(fauna_types)
|
||||
new beastie(T)
|
||||
|
||||
/datum/random_map/noise/exoplanet/proc/generate_flora()
|
||||
for(var/i = 1 to flora_diversity)
|
||||
var/datum/seed/S = new()
|
||||
S.randomize()
|
||||
var/planticon = "alien[rand(1,4)]"
|
||||
S.set_trait(TRAIT_PRODUCT_ICON,planticon)
|
||||
S.set_trait(TRAIT_PLANT_ICON,planticon)
|
||||
var/color = pick(plantcolors)
|
||||
if(color == "RANDOM")
|
||||
color = get_random_colour(0,75,190)
|
||||
S.set_trait(TRAIT_PLANT_COLOUR,color)
|
||||
var/carnivore_prob = rand(100)
|
||||
if(carnivore_prob < 10)
|
||||
S.set_trait(TRAIT_CARNIVOROUS,2)
|
||||
S.set_trait(TRAIT_SPREAD,1)
|
||||
else if(carnivore_prob < 20)
|
||||
S.set_trait(TRAIT_CARNIVOROUS,1)
|
||||
small_flora_types += S
|
||||
|
||||
/datum/random_map/noise/exoplanet/proc/get_grass_overlay()
|
||||
var/grass_num = "[rand(1,6)]"
|
||||
if(!LAZYACCESS(grass_cache, grass_num))
|
||||
var/color = pick(plantcolors)
|
||||
if(color == "RANDOM")
|
||||
color = get_random_colour(0,75,190)
|
||||
var/image/grass = overlay_image('icons/obj/flora/greygrass.dmi', "grass_[grass_num]", color, RESET_COLOR)
|
||||
grass.underlays += overlay_image('icons/obj/flora/greygrass.dmi', "grass_[grass_num]_shadow", null, RESET_COLOR)
|
||||
LAZYSET(grass_cache, grass_num, grass)
|
||||
return grass_cache[grass_num]
|
||||
|
||||
/datum/random_map/noise/exoplanet/proc/spawn_flora(var/turf/T, var/big)
|
||||
if(big)
|
||||
if(LAZYLEN(big_flora_types))
|
||||
new /obj/machinery/portable_atmospherics/hydroponics/soil/invisible(T, pick(big_flora_types), 1)
|
||||
for(var/turf/neighbor as anything in RANGE_TURFS(1,T))
|
||||
spawn_grass(neighbor)
|
||||
else
|
||||
if(LAZYLEN(small_flora_types))
|
||||
new /obj/machinery/portable_atmospherics/hydroponics/soil/invisible(T, pick(small_flora_types), 1)
|
||||
spawn_grass(T)
|
||||
|
||||
/datum/random_map/noise/exoplanet/proc/spawn_grass(var/turf/T)
|
||||
if(istype(T, water_type))
|
||||
return
|
||||
if(locate(/obj/effect/floor_decal) in T)
|
||||
return
|
||||
var/obj/effect/floor_decal/FD = new /obj/effect/floor_decal(T)
|
||||
FD.appearance = get_grass_overlay()
|
||||
36
code/modules/overmap/exoplanets/theme.dm
Normal file
@@ -0,0 +1,36 @@
|
||||
/datum/exoplanet_theme
|
||||
var/name = "Nothing Special"
|
||||
|
||||
/datum/exoplanet_theme/proc/before_map_generation(obj/effect/overmap/visitable/sector/exoplanet/E)
|
||||
|
||||
/datum/exoplanet_theme/proc/get_planet_image_extra()
|
||||
|
||||
/datum/exoplanet_theme/mountains
|
||||
name = "Mountains"
|
||||
var/rock_color
|
||||
|
||||
/datum/exoplanet_theme/mountains/before_map_generation(obj/effect/overmap/visitable/sector/exoplanet/E)
|
||||
rock_color = pick(E.rock_colors)
|
||||
for(var/zlevel in E.map_z)
|
||||
new /datum/random_map/automata/cave_system/mountains(null,TRANSITIONEDGE,TRANSITIONEDGE,zlevel,E.maxx-TRANSITIONEDGE,E.maxy-TRANSITIONEDGE,0,1,1, E.planetary_area, rock_color)
|
||||
|
||||
/datum/random_map/automata/cave_system/mountains
|
||||
iterations = 2
|
||||
descriptor = "space mountains"
|
||||
wall_type = /turf/simulated/mineral
|
||||
cell_threshold = 6
|
||||
var/rock_color
|
||||
|
||||
/datum/random_map/automata/cave_system/mountains/New(var/seed, var/tx, var/ty, var/tz, var/tlx, var/tly, var/do_not_apply, var/do_not_announce, var/never_be_priority = 0, var/used_area, var/_rock_color)
|
||||
if(_rock_color)
|
||||
rock_color = _rock_color
|
||||
target_turf_type = world.turf
|
||||
floor_type = world.turf
|
||||
..()
|
||||
|
||||
/datum/random_map/automata/cave_system/mountains/get_additional_spawns(value, var/turf/simulated/mineral/T)
|
||||
T.color = rock_color
|
||||
if(use_area)
|
||||
if(istype(T))
|
||||
T.mined_turf = use_area.base_turf
|
||||
|
||||
228
code/modules/overmap/exoplanets/turfs.dm
Normal file
@@ -0,0 +1,228 @@
|
||||
/turf/simulated/floor/exoplanet
|
||||
name = "space land"
|
||||
icon = 'icons/turf/desert.dmi'
|
||||
icon_state = "desert"
|
||||
has_resources = 1
|
||||
footstep_sound = /decl/sound_category/asteroid_footstep
|
||||
var/diggable = 1
|
||||
var/dirt_color = "#7c5e42"
|
||||
|
||||
/turf/simulated/floor/exoplanet/New()
|
||||
if(current_map.use_overmap)
|
||||
var/obj/effect/overmap/visitable/sector/exoplanet/E = map_sectors["[z]"]
|
||||
if(istype(E))
|
||||
if(E.atmosphere)
|
||||
temperature = E.atmosphere.temperature
|
||||
else
|
||||
temperature = T0C
|
||||
//Must be done here, as light data is not fully carried over by ChangeTurf (but overlays are).
|
||||
set_light(E.lightlevel, 0.1, 2)
|
||||
if(E.planetary_area && istype(loc, world.area))
|
||||
ChangeArea(src, E.planetary_area)
|
||||
..()
|
||||
|
||||
/turf/simulated/floor/exoplanet/attackby(obj/item/C, mob/user)
|
||||
if(diggable && istype(C,/obj/item/shovel))
|
||||
visible_message("<span class='notice'>\The [user] starts digging \the [src]</span>")
|
||||
if(do_after(user, 50))
|
||||
to_chat(user,"<span class='notice'>You dig a deep pit.</span>")
|
||||
new /obj/structure/pit(src)
|
||||
diggable = 0
|
||||
else
|
||||
to_chat(user,"<span class='notice'>You stop shoveling.</span>")
|
||||
else if(istype(C, /obj/item/stack/tile))
|
||||
var/obj/item/stack/tile/T = C
|
||||
if(T.use(1))
|
||||
playsound(src, 'sound/items/Deconstruct.ogg', 80, 1)
|
||||
ChangeTurf(/turf/simulated/floor, FALSE, FALSE, TRUE)
|
||||
else
|
||||
..()
|
||||
|
||||
/turf/simulated/floor/exoplanet/ex_act(severity)
|
||||
switch(severity)
|
||||
if(1)
|
||||
ChangeTurf(get_base_turf_by_area(src))
|
||||
if(2)
|
||||
if(prob(40))
|
||||
ChangeTurf(get_base_turf_by_area(src))
|
||||
|
||||
/turf/simulated/floor/exoplanet/Initialize()
|
||||
. = ..()
|
||||
update_icon(1)
|
||||
|
||||
/turf/simulated/floor/exoplanet/update_icon(var/update_neighbors)
|
||||
cut_overlays()
|
||||
if(LAZYLEN(decals))
|
||||
add_overlay(decals)
|
||||
for(var/direction in cardinal)
|
||||
var/turf/turf_to_check = get_step(src,direction)
|
||||
if(!istype(turf_to_check, type))
|
||||
var/image/rock_side = image(icon, "edge[pick(0,1,2)]", dir = turn(direction, 180))
|
||||
switch(direction)
|
||||
if(NORTH)
|
||||
rock_side.pixel_y += world.icon_size
|
||||
if(SOUTH)
|
||||
rock_side.pixel_y -= world.icon_size
|
||||
if(EAST)
|
||||
rock_side.pixel_x += world.icon_size
|
||||
if(WEST)
|
||||
rock_side.pixel_x -= world.icon_size
|
||||
overlays += rock_side
|
||||
else if(update_neighbors)
|
||||
turf_to_check.update_icon()
|
||||
|
||||
//Water
|
||||
/turf/simulated/floor/exoplanet/water/update_icon()
|
||||
return
|
||||
|
||||
/turf/simulated/floor/exoplanet/water/shallow
|
||||
name = "shallow water"
|
||||
icon = 'icons/misc/beach.dmi'
|
||||
icon_state = "seashallow"
|
||||
footstep_sound = /decl/sound_category/water_footstep
|
||||
var/reagent_type = /decl/reagent/water
|
||||
|
||||
/turf/simulated/floor/exoplanet/water/shallow/attackby(obj/item/O, var/mob/living/user)
|
||||
var/obj/item/reagent_containers/RG = O
|
||||
if (reagent_type && istype(RG) && RG.is_open_container() && RG.reagents)
|
||||
RG.reagents.add_reagent(reagent_type, min(RG.volume - RG.reagents.total_volume, RG.amount_per_transfer_from_this))
|
||||
user.visible_message("<span class='notice'>[user] fills \the [RG] from \the [src].</span>","<span class='notice'>You fill \the [RG] from \the [src].</span>")
|
||||
else
|
||||
return ..()
|
||||
|
||||
/turf/simulated/floor/exoplanet/water/update_dirt()
|
||||
return // Water doesn't become dirty
|
||||
|
||||
//Ice
|
||||
/turf/simulated/floor/exoplanet/ice
|
||||
name = "ice"
|
||||
icon = 'icons/turf/snow.dmi'
|
||||
icon_state = "ice"
|
||||
|
||||
/turf/simulated/floor/exoplanet/ice/update_icon()
|
||||
return
|
||||
|
||||
//Snow
|
||||
/turf/simulated/floor/exoplanet/snow
|
||||
name = "snow"
|
||||
icon = 'icons/turf/snow.dmi'
|
||||
icon_state = "snow"
|
||||
dirt_color = "#e3e7e8"
|
||||
footstep_sound = /decl/sound_category/snow_footstep
|
||||
|
||||
/turf/simulated/floor/exoplanet/snow/Initialize()
|
||||
. = ..()
|
||||
icon_state = pick("snow[rand(1,12)]","snow0")
|
||||
|
||||
/turf/simulated/floor/exoplanet/snow/fire_act(datum/gas_mixture/air, exposed_temperature, exposed_volume)
|
||||
melt()
|
||||
|
||||
/turf/simulated/floor/exoplanet/snow/melt()
|
||||
name = "permafrost"
|
||||
icon_state = "permafrost"
|
||||
footstep_sound = /decl/sound_category/asteroid_footstep
|
||||
|
||||
//Grass
|
||||
/turf/simulated/floor/exoplanet/grass
|
||||
name = "grass"
|
||||
icon = 'icons/turf/jungle.dmi'
|
||||
icon_state = "greygrass"
|
||||
color = "#799c4b"
|
||||
footstep_sound = /decl/sound_category/grass_footstep
|
||||
|
||||
/turf/simulated/floor/exoplanet/grass/Initialize()
|
||||
. = ..()
|
||||
if(current_map.use_overmap)
|
||||
var/obj/effect/overmap/visitable/sector/exoplanet/E = map_sectors["[z]"]
|
||||
if(istype(E) && E.grass_color)
|
||||
color = E.grass_color
|
||||
if(!resources)
|
||||
resources = list()
|
||||
if(prob(5))
|
||||
resources[MATERIAL_URANIUM] = rand(1,3)
|
||||
if(prob(2))
|
||||
resources[MATERIAL_DIAMOND] = 1
|
||||
|
||||
//Sand
|
||||
/turf/simulated/floor/exoplanet/desert
|
||||
name = "sand"
|
||||
desc = "It's coarse and gets everywhere."
|
||||
dirt_color = "#ae9e66"
|
||||
footstep_sound = /decl/sound_category/sand_footstep
|
||||
|
||||
/turf/simulated/floor/exoplanet/desert/Initialize()
|
||||
. = ..()
|
||||
icon_state = "desert[rand(0,5)]"
|
||||
|
||||
//Concrete
|
||||
/turf/simulated/floor/exoplanet/concrete
|
||||
name = "concrete"
|
||||
desc = "Stone-like artificial material."
|
||||
icon = 'icons/turf/flooring/misc.dmi'
|
||||
icon_state = "concrete"
|
||||
|
||||
//Special world edge turf
|
||||
|
||||
/turf/simulated/planet_edge
|
||||
name = "world's edge"
|
||||
desc = "Government didn't want you to see this!"
|
||||
density = TRUE
|
||||
blocks_air = TRUE
|
||||
dynamic_lighting = FALSE
|
||||
icon = null
|
||||
icon_state = null
|
||||
|
||||
/turf/simulated/planet_edge/Initialize()
|
||||
. = ..()
|
||||
var/obj/effect/overmap/visitable/sector/exoplanet/E = map_sectors["[z]"]
|
||||
if(!istype(E))
|
||||
return
|
||||
|
||||
var/nx = x
|
||||
if (x <= TRANSITIONEDGE)
|
||||
nx = x + (E.maxx - 2*TRANSITIONEDGE)
|
||||
else if (x >= (E.maxx - TRANSITIONEDGE + 1))
|
||||
nx = x - (E.maxx - 2*TRANSITIONEDGE)
|
||||
|
||||
var/ny = y
|
||||
if(y <= TRANSITIONEDGE)
|
||||
ny = y + (E.maxy - 2*TRANSITIONEDGE)
|
||||
else if (y >= (E.maxy - TRANSITIONEDGE + 1))
|
||||
ny = y - (E.maxy - 2*TRANSITIONEDGE)
|
||||
|
||||
var/turf/NT = locate(nx, ny, z)
|
||||
if(NT)
|
||||
vis_contents = list(NT)
|
||||
|
||||
//Need to put a mouse-opaque overlay there to prevent people turning/shooting towards ACTUAL location of vis_content things
|
||||
var/obj/effect/overlay/O = new(src)
|
||||
O.mouse_opacity = 2
|
||||
O.name = "distant terrain"
|
||||
O.desc = "You need to come over there to take a better look."
|
||||
|
||||
/turf/simulated/planet_edge/CollidedWith(atom/movable/A)
|
||||
. = ..()
|
||||
var/obj/effect/overmap/visitable/sector/exoplanet/E = map_sectors["[z]"]
|
||||
if(!istype(E))
|
||||
return
|
||||
if(E.planetary_area && istype(loc, world.area))
|
||||
ChangeArea(src, E.planetary_area)
|
||||
var/new_x = A.x
|
||||
var/new_y = A.y
|
||||
if(x <= TRANSITIONEDGE)
|
||||
new_x = E.maxx - TRANSITIONEDGE
|
||||
else if (x >= (E.maxx - TRANSITIONEDGE + 1))
|
||||
new_x = TRANSITIONEDGE + 1
|
||||
else if (y <= TRANSITIONEDGE)
|
||||
new_y = E.maxy - TRANSITIONEDGE
|
||||
else if (y >= (E.maxy - TRANSITIONEDGE + 1))
|
||||
new_y = TRANSITIONEDGE + 1
|
||||
|
||||
var/turf/T = locate(new_x, new_y, A.z)
|
||||
if(T && !T.density)
|
||||
A.forceMove(T)
|
||||
if(isliving(A))
|
||||
var/mob/living/L = A
|
||||
if(L.pulling)
|
||||
var/atom/movable/AM = L.pulling
|
||||
AM.forceMove(T)
|
||||
@@ -107,13 +107,13 @@
|
||||
controller = new(src)
|
||||
update_nearby_tiles(need_rebuild=1)
|
||||
|
||||
for(var/ship in SSshuttle.ships)
|
||||
var/obj/effect/overmap/visitable/ship/S = ship
|
||||
if(S.check_ownership(src))
|
||||
S.engines |= controller
|
||||
if(dir != S.fore_dir)
|
||||
stat |= BROKEN
|
||||
break
|
||||
if(length(SSshuttle.shuttle_areas) && !length(SSshuttle.shuttles_to_initialize) && SSshuttle.init_state == SS_INITSTATE_DONE)
|
||||
for(var/obj/effect/overmap/visitable/ship/S as anything in SSshuttle.ships)
|
||||
if(S.check_ownership(src))
|
||||
S.engines |= controller
|
||||
if(dir != S.fore_dir)
|
||||
stat |= BROKEN
|
||||
break
|
||||
|
||||
/obj/machinery/atmospherics/unary/engine/Destroy()
|
||||
QDEL_NULL(controller)
|
||||
|
||||
@@ -10,6 +10,10 @@
|
||||
icon_state = "shuttle"
|
||||
moving_state = "shuttle_moving"
|
||||
|
||||
/obj/effect/overmap/visitable/ship/landable/Destroy()
|
||||
shuttle_moved_event.unregister(SSshuttle.shuttles[shuttle], src)
|
||||
return ..()
|
||||
|
||||
/obj/effect/overmap/visitable/ship/landable/can_burn()
|
||||
if(status != SHIP_STATUS_OVERMAP)
|
||||
return 0
|
||||
@@ -57,6 +61,7 @@
|
||||
/obj/effect/overmap/visitable/ship/landable/populate_sector_objects()
|
||||
..()
|
||||
var/datum/shuttle/shuttle_datum = SSshuttle.shuttles[shuttle]
|
||||
shuttle_moved_event.register(shuttle_datum, src, .proc/on_shuttle_jump)
|
||||
on_landing(landmark, shuttle_datum.current_location) // We "land" at round start to properly place ourselves on the overmap.
|
||||
|
||||
/obj/effect/shuttle_landmark/ship
|
||||
@@ -110,9 +115,11 @@
|
||||
|
||||
/obj/effect/shuttle_landmark/visiting_shuttle/shuttle_arrived(datum/shuttle/shuttle)
|
||||
LAZYSET(core_landmark.visitors, src, shuttle)
|
||||
shuttle_moved_event.register(shuttle, src, .proc/shuttle_left)
|
||||
|
||||
/obj/effect/shuttle_landmark/visiting_shuttle/proc/shuttle_left(datum/shuttle/shuttle, obj/effect/shuttle_landmark/old_landmark, obj/effect/shuttle_landmark/new_landmark)
|
||||
if(old_landmark == src)
|
||||
shuttle_moved_event.unregister(shuttle, src)
|
||||
LAZYREMOVE(core_landmark.visitors, src)
|
||||
|
||||
/obj/effect/overmap/visitable/ship/landable/proc/on_shuttle_jump(datum/shuttle/given_shuttle, obj/effect/shuttle_landmark/from, obj/effect/shuttle_landmark/into)
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
var/cell_base // Set in New()
|
||||
var/initial_cell_range // Set in New()
|
||||
var/smoothing_iterations = 0
|
||||
var/smooth_single_tiles // Single turfs of different value are not allowed
|
||||
|
||||
/datum/random_map/noise/New()
|
||||
initial_cell_range = cell_range/5
|
||||
@@ -28,13 +29,15 @@
|
||||
limit_y = limit_x
|
||||
else if(limit_y > limit_x)
|
||||
limit_x = limit_y
|
||||
log_debug("Generating Noise map with limits: [limit_x], [limit_y]")
|
||||
..()
|
||||
|
||||
// Diamond-square algorithm.
|
||||
/datum/random_map/noise/seed_map()
|
||||
// Instantiate the grid.
|
||||
for (var/i = 1 to (limit_x * limit_y))
|
||||
map[i] = 0
|
||||
for(var/x = 1, x <= limit_x, x++)
|
||||
for(var/y = 1, y <= limit_y, y++)
|
||||
map[TRANSLATE_COORD(x,y)] = 0
|
||||
|
||||
// Now dump in the actual random data.
|
||||
map[TRANSLATE_COORD(1,1)] = cell_base+rand(initial_cell_range)
|
||||
@@ -51,6 +54,9 @@
|
||||
if(isnull(val)) val = 0
|
||||
return "[val]"
|
||||
|
||||
/datum/random_map/noise/proc/noise2value(var/value)
|
||||
return min(9,max(0,round((value/cell_range)*10)))
|
||||
|
||||
/datum/random_map/noise/proc/subdivide(var/iteration,var/x,var/y,var/input_size)
|
||||
|
||||
var/isize = input_size
|
||||
@@ -78,7 +84,7 @@
|
||||
map[TRANSLATE_COORD(x+isize,y)] \
|
||||
)/2)
|
||||
|
||||
map[TRANSLATE_COORD(x,y+hsize)] = round(( \
|
||||
map[get_map_cell(x,y+hsize)] = round(( \
|
||||
map[TRANSLATE_COORD(x,y+isize)] + \
|
||||
map[TRANSLATE_COORD(x,y)] \
|
||||
)/2)
|
||||
@@ -103,7 +109,7 @@
|
||||
|
||||
// Recurse until size is too small to subdivide.
|
||||
if(isize>3)
|
||||
if(!priority_process)
|
||||
if(!priority_process)
|
||||
CHECK_TICK
|
||||
iteration++
|
||||
subdivide(iteration, x, y, hsize)
|
||||
@@ -164,3 +170,32 @@
|
||||
map[current_cell]-=cell_smooth_amt
|
||||
map[current_cell] = max(0,min(cell_range,map[current_cell]))
|
||||
map = next_map
|
||||
|
||||
if(smooth_single_tiles)
|
||||
var/list/buddies = list()
|
||||
for(var/x in 1 to limit_x - 1)
|
||||
for(var/y in 1 to limit_y - 1)
|
||||
var/mapcell = get_map_cell(x,y)
|
||||
var/list/neighbors = get_neighbors(x, y)
|
||||
buddies.Cut()
|
||||
for(var/cell in neighbors)
|
||||
if(noise2value(map[cell]) == noise2value(map[mapcell]))
|
||||
buddies |= cell
|
||||
if(!length(buddies))
|
||||
map[mapcell] = map[pick(neighbors)]
|
||||
|
||||
/datum/random_map/noise/proc/get_neighbors(x, y, include_diagonals)
|
||||
. = list()
|
||||
if(!include_diagonals)
|
||||
var/static/list/ortho_offsets = list(list(-1, 0), list(1, 0), list(0, 1), list(0,-1))
|
||||
for(var/list/offset in ortho_offsets)
|
||||
var/tmp_cell = get_map_cell(x+offset[1],y+offset[2])
|
||||
if(tmp_cell)
|
||||
. += tmp_cell
|
||||
else
|
||||
for(var/dx in -1 to 1)
|
||||
for(var/dy in -1 to 1)
|
||||
var/tmp_cell = get_map_cell(x+dx,y+dy)
|
||||
if(tmp_cell)
|
||||
. += tmp_cell
|
||||
. -= get_map_cell(x,y)
|
||||
|
||||
@@ -96,3 +96,8 @@
|
||||
return "R"
|
||||
else
|
||||
return "D"
|
||||
|
||||
/datum/random_map/noise/ore/rich
|
||||
deep_val = 0.7
|
||||
rare_val = 0.5
|
||||
|
||||
@@ -25,6 +25,8 @@ var/global/list/map_count = list()
|
||||
var/target_turf_type
|
||||
var/spawn_roof = FALSE //Set to TRUE if a roof should be spawned based.
|
||||
|
||||
var/area/use_area // If set, turfs will be put in this area. If set to type, new instance will be spawned for the map
|
||||
|
||||
// Storage for the final iteration of the map.
|
||||
var/list/map = list() // Actual map.
|
||||
var/tmp/map_len = 0
|
||||
@@ -33,7 +35,7 @@ var/global/list/map_count = list()
|
||||
// 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)
|
||||
/datum/random_map/New(var/seed, var/tx, var/ty, var/tz, var/tlx, var/tly, var/do_not_apply, var/do_not_announce, var/never_be_priority = 0, var/used_area)
|
||||
|
||||
// Store this for debugging.
|
||||
if(!map_count[descriptor])
|
||||
@@ -48,6 +50,12 @@ var/global/list/map_count = list()
|
||||
if(tlx) limit_x = tlx
|
||||
if(tly) limit_y = tly
|
||||
|
||||
if(used_area)
|
||||
if(ispath(used_area))
|
||||
use_area = new(used_area)
|
||||
else
|
||||
use_area = used_area
|
||||
|
||||
if(do_not_apply)
|
||||
auto_apply = null
|
||||
|
||||
@@ -61,7 +69,7 @@ var/global/list/map_count = list()
|
||||
// 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
|
||||
priority_process = !never_be_priority
|
||||
|
||||
for(var/i = 0;i<max_attempts;i++)
|
||||
if(generate())
|
||||
@@ -183,6 +191,8 @@ var/global/list/map_count = list()
|
||||
if(spawn_roof)
|
||||
T.spawn_roof()
|
||||
get_additional_spawns(map[tmp_cell],T,get_spawn_dir(x, y))
|
||||
if(use_area)
|
||||
ChangeArea(T, use_area)
|
||||
return T
|
||||
|
||||
/datum/random_map/proc/get_spawn_dir()
|
||||
|
||||
@@ -95,7 +95,7 @@
|
||||
/obj/effect/shuttle_landmark/automatic
|
||||
name = "Navpoint"
|
||||
landmark_tag = "navpoint"
|
||||
flags = SLANDMARK_FLAG_AUTOSET
|
||||
landmark_flags = SLANDMARK_FLAG_AUTOSET
|
||||
|
||||
/obj/effect/shuttle_landmark/automatic/Initialize()
|
||||
landmark_tag += "-[x]-[y]-[z]"
|
||||
|
||||
@@ -86,7 +86,7 @@
|
||||
moving_status = SHUTTLE_WARMUP
|
||||
callHook("shuttle_moved", list(start_location,destination))
|
||||
if(sound_takeoff)
|
||||
playsound(current_location, sound_takeoff, 50, 20, is_global = TRUE)
|
||||
playsound(current_location, sound_takeoff, 25, 20, is_global = TRUE)
|
||||
spawn(warmup_time*10)
|
||||
if(moving_status == SHUTTLE_IDLE)
|
||||
return FALSE //someone cancelled the launch
|
||||
@@ -110,7 +110,7 @@
|
||||
moving_status = SHUTTLE_WARMUP
|
||||
callHook("shuttle_moved", list(start_location, destination))
|
||||
if(sound_takeoff)
|
||||
playsound(current_location, sound_takeoff, 100, 20, is_global = TRUE)
|
||||
playsound(current_location, sound_takeoff, 50, 20, is_global = TRUE)
|
||||
spawn(warmup_time*10)
|
||||
if(moving_status == SHUTTLE_IDLE)
|
||||
return //someone cancelled the launch
|
||||
@@ -128,7 +128,7 @@
|
||||
while (world.time < arrive_time)
|
||||
if(!fwooshed && (arrive_time - world.time) < 100)
|
||||
fwooshed = 1
|
||||
playsound(destination, sound_landing, 100, 20, is_global = TRUE)
|
||||
playsound(destination, sound_landing, 50, 20, is_global = TRUE)
|
||||
sleep(5)
|
||||
if(!attempt_move(destination))
|
||||
attempt_move(start_location) //try to go back to where we started. If that fails, I guess we're stuck in the interim location
|
||||
@@ -156,7 +156,10 @@
|
||||
for(var/area/A in shuttle_area)
|
||||
testing("Moving [A]")
|
||||
translation += get_turf_translation(get_turf(current_location), get_turf(destination), A.contents)
|
||||
var/old_location = current_location
|
||||
shuttle_pre_move_event.raise_event(src, old_location, destination)
|
||||
shuttle_moved(destination, translation)
|
||||
shuttle_moved_event.raise_event(src, old_location, destination)
|
||||
destination.shuttle_arrived(src)
|
||||
return TRUE
|
||||
|
||||
|
||||
@@ -10,5 +10,20 @@ var/list/last_names = file2list("config/names/last.txt")
|
||||
|
||||
var/list/verbs = file2list("config/names/verbs.txt")
|
||||
var/list/adjectives = file2list("config/names/adjectives.txt")
|
||||
|
||||
//loaded on startup because of "
|
||||
//would include in rsc if ' was used
|
||||
//would include in rsc if ' was used
|
||||
|
||||
var/list/greek_letters = list("Alpha", "Beta", "Gamma", "Delta",
|
||||
"Epsilon", "Zeta", "Eta", "Theta", "Iota", "Kappa", "Lambda", "Mu",
|
||||
"Nu", "Xi", "Omicron", "Pi", "Rho", "Sigma", "Tau", "Upsilon", "Phi",
|
||||
"Chi", "Psi", "Omega")
|
||||
|
||||
/proc/generate_system_name()
|
||||
return "[pick("CRZ", "BNM", "Xavier", "GJ", "HD", "TC")][prob(10) ? " Eridani" : ""] [rand(100,999)]"
|
||||
|
||||
/proc/generate_planet_name()
|
||||
return "[capitalize(pick(last_names))]-[pick(greek_letters)]"
|
||||
|
||||
/proc/generate_planet_type()
|
||||
return pick("terrestial planet", "ice planet", "dwarf planet", "desert planet", "ocean planet", "lava planet", "gas giant", "forest planet")
|
||||
45
html/changelogs/mattatlas-providence.yml
Normal file
@@ -0,0 +1,45 @@
|
||||
################################
|
||||
# Example Changelog File
|
||||
#
|
||||
# Note: This file, and files beginning with ".", and files that don't end in ".yml" will not be read. If you change this file, you will look really dumb.
|
||||
#
|
||||
# Your changelog will be merged with a master changelog. (New stuff added only, and only on the date entry for the day it was merged.)
|
||||
# When it is, any changes listed below will disappear.
|
||||
#
|
||||
# Valid Prefixes:
|
||||
# bugfix
|
||||
# wip (For works in progress)
|
||||
# tweak
|
||||
# soundadd
|
||||
# sounddel
|
||||
# rscadd (general adding of nice things)
|
||||
# rscdel (general deleting of nice things)
|
||||
# imageadd
|
||||
# imagedel
|
||||
# maptweak
|
||||
# spellcheck (typo fixes)
|
||||
# experiment
|
||||
# balance
|
||||
# admin
|
||||
# backend
|
||||
# security
|
||||
# refactor
|
||||
#################################
|
||||
|
||||
# Your name.
|
||||
author: MattAtlas
|
||||
|
||||
# Optional: Remove this file after generating master changelog. Useful for PR changelogs that won't get used again.
|
||||
delete-after: True
|
||||
|
||||
# Any changes you've made. See valid prefix list above.
|
||||
# INDENT WITH TWO SPACES. NOT TABS. SPACES.
|
||||
# SCREW THIS UP AND IT WON'T WORK.
|
||||
# Also, all entries are changed into a single [] after a master changelog generation. Just remove the brackets when you add new entries.
|
||||
# Please surround your changes in double quotes ("), as certain characters otherwise screws up compiling. The quotes will not show up in the changelog.
|
||||
changes:
|
||||
- rscadd: "Added a new planet generation system ported from Bay."
|
||||
- bugfix: "Fixed some overmap bugs."
|
||||
- tweak: "Diyaabs, shantaks and samaks are now retaliate mobs."
|
||||
- rscadd: "Ported a bunch of flavour mobs from Bay."
|
||||
- rscadd: "Animals can now have natural armor."
|
||||
|
Before Width: | Height: | Size: 182 KiB After Width: | Height: | Size: 206 KiB |
BIN
icons/obj/flora/greygrass.dmi
Normal file
|
After Width: | Height: | Size: 9.4 KiB |
BIN
icons/obj/gravestone.dmi
Normal file
|
After Width: | Height: | Size: 451 B |
BIN
icons/obj/pit.dmi
Normal file
|
After Width: | Height: | Size: 1.1 KiB |
BIN
icons/obj/quicksand.dmi
Normal file
|
After Width: | Height: | Size: 7.2 KiB |
BIN
icons/turf/jungle.dmi
Normal file
|
After Width: | Height: | Size: 10 KiB |
|
Before Width: | Height: | Size: 82 KiB After Width: | Height: | Size: 76 KiB |
@@ -104,6 +104,9 @@
|
||||
"Unidentified hackers have targetted a combat drone wing deployed from the NDV Icarus. If any are sighted in the area, approach with caution.")
|
||||
var/rogue_drone_end_message = "Icarus drone control reports the malfunctioning wing has been recovered safely."
|
||||
var/rogue_drone_destroyed_message = "Icarus drone control registers disappointment at the loss of the drones, but the survivors have been recovered."
|
||||
|
||||
var/num_exoplanets = 0
|
||||
var/list/planet_size //dimensions of planet zlevel, defaults to world size. Due to how maps are generated, must be (2^n+1) e.g. 17,33,65,129 etc. Map will just round up to those if set to anything other.
|
||||
|
||||
/datum/map/New()
|
||||
if(!map_levels)
|
||||
@@ -112,6 +115,8 @@
|
||||
allowed_jobs = subtypesof(/datum/job)
|
||||
if (!spawn_types)
|
||||
spawn_types = subtypesof(/datum/spawnpoint)
|
||||
if(!LAZYLEN(planet_size))
|
||||
planet_size = list(world.maxx, world.maxy)
|
||||
|
||||
/datum/map/proc/generate_asteroid()
|
||||
return
|
||||
@@ -139,3 +144,20 @@
|
||||
|
||||
// Called right after SSatlas finishes loading the map & multiz is setup.
|
||||
/datum/map/proc/finalize_load()
|
||||
|
||||
/datum/map/proc/build_exoplanets()
|
||||
if(!use_overmap)
|
||||
return
|
||||
|
||||
var/datum/space_sector/sector = SSatlas.current_sector
|
||||
var/list/possible_exoplanets = sector.possible_exoplanets
|
||||
|
||||
if(!length(possible_exoplanets))
|
||||
log_debug("No valid exoplanets found!")
|
||||
return
|
||||
|
||||
for(var/i = 0, i < num_exoplanets, i++)
|
||||
var/exoplanet_type = pick(possible_exoplanets)
|
||||
log_debug("Building new exoplanet with type: [exoplanet_type] and size: [planet_size[1]] [planet_size[2]]")
|
||||
var/obj/effect/overmap/visitable/sector/exoplanet/new_planet = new exoplanet_type(null, planet_size[1], planet_size[2])
|
||||
new_planet.build_level()
|
||||
|
||||
3
maps/random_ruins/exoplanets/exoplanet_ruins.dm
Normal file
@@ -0,0 +1,3 @@
|
||||
/datum/map_template/ruin/exoplanet
|
||||
prefix = "maps/random_ruins/exoplanet_ruins/"
|
||||
var/list/ruin_tags
|
||||
@@ -9,7 +9,7 @@
|
||||
lobby_transitions = 10 SECONDS
|
||||
|
||||
station_levels = list(1, 2, 3)
|
||||
admin_levels = list()
|
||||
admin_levels = list(9)
|
||||
contact_levels = list(1, 2, 3)
|
||||
player_levels = list(1, 2, 3)
|
||||
accessible_z_levels = list(1, 2, 3)
|
||||
@@ -26,6 +26,7 @@
|
||||
company_short = "BT"
|
||||
|
||||
use_overmap = TRUE
|
||||
overmap_size = 35
|
||||
|
||||
shuttle_docked_message = "Attention all hands: Jump preparation complete. The bluespace drive is now spooling up, secure all stations for departure. Time to jump: approximately %ETA%."
|
||||
shuttle_leaving_dock = "Attention all hands: Jump initiated, exiting bluespace in %ETA%."
|
||||
@@ -39,3 +40,8 @@
|
||||
NETWORK_COMMAND,
|
||||
NETWORK_ENGINEERING,
|
||||
)
|
||||
|
||||
num_exoplanets = 3
|
||||
planet_size = list(50,50)
|
||||
|
||||
map_shuttles = list(/datum/shuttle/autodock/overmap/runtime)
|
||||
|
||||
15
maps/runtime/runtime-9.dmm
Normal file
@@ -0,0 +1,15 @@
|
||||
"a" = (/turf/space,/area/space)
|
||||
"b" = (/obj/effect/shuttle_landmark/runtime/transit,/turf/space,/area/space)
|
||||
|
||||
(1,1,1) = {"
|
||||
aaaaaaaaaa
|
||||
aaaaaaaaaa
|
||||
aaaaaaaaaa
|
||||
aaaaaaaaaa
|
||||
aaaaaaaaaa
|
||||
aaaabaaaaa
|
||||
aaaaaaaaaa
|
||||
aaaaaaaaaa
|
||||
aaaaaaaaaa
|
||||
aaaaaaaaaa
|
||||
"}
|
||||
@@ -3,4 +3,44 @@
|
||||
desc = "A large cube-shaped station, a penal colony of sorts for the likes of video game developers."
|
||||
vessel_mass = 100000
|
||||
burn_delay = 2 SECONDS
|
||||
base = TRUE
|
||||
base = TRUE
|
||||
|
||||
/obj/effect/overmap/visitable/ship/landable/runtime
|
||||
name = "NSV While True"
|
||||
desc = "A RUN-T1M3 long range shuttle."
|
||||
shuttle = "WhileTrue"
|
||||
max_speed = 1/(2 SECONDS)
|
||||
burn_delay = 1 SECONDS
|
||||
vessel_mass = 5000
|
||||
fore_dir = WEST
|
||||
vessel_size = SHIP_SIZE_SMALL
|
||||
|
||||
/obj/machinery/computer/shuttle_control/explore/runtime
|
||||
name = "whiletrue control console"
|
||||
shuttle_tag = "WhileTrue"
|
||||
req_access = list()
|
||||
|
||||
/area/shuttle/runtime
|
||||
name = "While True"
|
||||
base_turf = /turf/simulated/floor/shuttle/black
|
||||
|
||||
/datum/shuttle/autodock/overmap/runtime
|
||||
name = "WhileTrue"
|
||||
move_time = 90
|
||||
shuttle_area = list(/area/shuttle/runtime)
|
||||
dock_target = "runtime_shuttle"
|
||||
current_location = "nav_runtime_hangar"
|
||||
landmark_transition = "nav_transit_runtime"
|
||||
range = 1
|
||||
fuel_consumption = 4
|
||||
ceiling_type = /turf/simulated/floor/shuttle_ceiling
|
||||
|
||||
/obj/effect/shuttle_landmark/runtime/hangar
|
||||
name = "Runtime Hangar"
|
||||
landmark_tag = "nav_runtime_hangar"
|
||||
base_area = /area/construction
|
||||
base_turf = /turf/simulated/floor/plating
|
||||
|
||||
/obj/effect/shuttle_landmark/runtime/transit
|
||||
name = "In transit"
|
||||
landmark_tag = "nav_transit_runtime"
|
||||