Merge branch 'master' into final_shuttle_touches_and_stuff

# Conflicts:
#	icons/turf/shuttle.dmi
This commit is contained in:
alberyk
2022-01-17 22:20:15 -03:00
84 changed files with 2321 additions and 4654 deletions

View File

@@ -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"

View File

@@ -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)

View File

@@ -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"

View File

@@ -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))

View File

@@ -33,6 +33,7 @@
#define MATERIAL_RUST "rust"
#define MATERIAL_CARDBOARD "cardboard"
// Leathers and related.
#define MATERIAL_RESIN "resin"
#define MATERIAL_LEATHER "leather"

View File

@@ -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.

View 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

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -46,6 +46,8 @@
click_catchers = create_click_catcher()
current_map.build_exoplanets()
..(timeofday)
/proc/sorted_add_area(area/A)

View File

@@ -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

View File

@@ -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)

View 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)

View 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()

View 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
View 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)
..()

View File

@@ -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,

View File

@@ -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

View File

@@ -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())

View File

@@ -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
. = ..()

View File

@@ -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)

View 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

View File

@@ -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'

View File

@@ -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

View File

@@ -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

View File

@@ -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

View File

@@ -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,

View File

@@ -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)

View 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

View 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]!"))

View 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)

View 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

View 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

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View File

@@ -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"

View File

@@ -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)

View File

@@ -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!")

View File

@@ -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

View File

@@ -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

View File

@@ -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)

View 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

View 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()

View 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

View 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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -96,3 +96,8 @@
return "R"
else
return "D"
/datum/random_map/noise/ore/rich
deep_val = 0.7
rare_val = 0.5

View File

@@ -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()

View File

@@ -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]"

View File

@@ -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

View File

@@ -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")

View 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."

Binary file not shown.

Before

Width:  |  Height:  |  Size: 182 KiB

After

Width:  |  Height:  |  Size: 206 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.4 KiB

BIN
icons/obj/gravestone.dmi Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 451 B

BIN
icons/obj/pit.dmi Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

BIN
icons/obj/quicksand.dmi Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

BIN
icons/turf/jungle.dmi Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 82 KiB

After

Width:  |  Height:  |  Size: 76 KiB

View File

@@ -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()

View File

@@ -0,0 +1,3 @@
/datum/map_template/ruin/exoplanet
prefix = "maps/random_ruins/exoplanet_ruins/"
var/list/ruin_tags

View File

@@ -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)

File diff suppressed because it is too large Load Diff

View 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
"}

View File

@@ -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"

Binary file not shown.

Binary file not shown.

BIN
sound/ambience/jungle.ogg Normal file

Binary file not shown.

BIN
sound/ambience/magma.ogg Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.