Merge branch 'master' into the-fuck-am-i-doing

This commit is contained in:
Fabian
2021-05-05 17:26:41 +02:00
641 changed files with 318305 additions and 311402 deletions
+40 -8
View File
@@ -52,14 +52,46 @@ GLOBAL_LIST_INIT(bitflags, list(1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 204
#define BLOCK_FACE_ATOM_1 (1<<17)
//turf-only flags
#define NOJAUNT_1 (1<<0)
#define UNUSED_RESERVATION_TURF_1 (1<<1)
///If a turf can be made dirty at roundstart. This is also used in areas.
#define CAN_BE_DIRTY_1 (1<<2)
///Blocks lava rivers being generated on the turf.
#define NO_LAVA_GEN_1 (1<<6)
///Blocks ruins spawning on the turf.
#define NO_RUINS_1 (1<<10)
#define NOJAUNT_1 (1<<0)
#define UNUSED_RESERVATION_TURF_1 (1<<1)
/// If a turf can be made dirty at roundstart. This is also used in areas.
#define CAN_BE_DIRTY_1 (1<<2)
/// If blood cultists can draw runes or build structures on this turf
#define CULT_PERMITTED_1 (1<<3)
/// Blocks lava rivers being generated on the turf
#define NO_LAVA_GEN_1 (1<<6)
/// Blocks ruins spawning on the turf
#define NO_RUINS_1 (1<<10)
/// Should this tile be cleaned up and reinserted into an excited group?
#define EXCITED_CLEANUP_1 (1 << 13)
////////////////Area flags\\\\\\\\\\\\\\
/// If it's a valid territory for cult summoning or the CRAB-17 phone to spawn
#define VALID_TERRITORY (1<<0)
/// If blobs can spawn there and if it counts towards their score.
#define BLOBS_ALLOWED (1<<1)
/// If mining tunnel generation is allowed in this area
#define CAVES_ALLOWED (1<<2)
/// If flora are allowed to spawn in this area randomly through tunnel generation
#define FLORA_ALLOWED (1<<3)
/// If mobs can be spawned by natural random generation
#define MOB_SPAWN_ALLOWED (1<<4)
/// If megafauna can be spawned by natural random generation
#define MEGAFAUNA_SPAWN_ALLOWED (1<<5)
/// Are you forbidden from teleporting to the area? (centcom, mobs, wizard, hand teleporter)
#define NOTELEPORT (1<<6)
/// Hides area from player Teleport function.
#define HIDDEN_AREA (1<<7)
/// If false, loading multiple maps with this area type will create multiple instances.
#define UNIQUE_AREA (1<<8)
/// If people are allowed to suicide in it. Mostly for OOC stuff like minigames
#define BLOCK_SUICIDE (1<<9)
/// Can the Xenobio management console transverse this area by default?
#define XENOBIOLOGY_COMPATIBLE (1<<10)
/// If Abductors are unable to teleport in with their observation console
#define ABDUCTOR_PROOF (1<<11)
/// If an area should be hidden from power consoles, power/atmosphere alerts, etc.
#define NO_ALERTS (1<<12)
/*
These defines are used specifically with the atom/pass_flags bitmask
+1
View File
@@ -51,3 +51,4 @@
#define ORGAN_NO_SPOIL (1<<5) //Do not spoil under any circumstances
#define ORGAN_NO_DISMEMBERMENT (1<<6) //Immune to disembowelment.
#define ORGAN_EDIBLE (1<<7) //is a snack? :D
#define ORGAN_SYNTHETIC_EMP (1<<6) //Synthetic organ affected by an EMP. Deteriorates over time.
+4 -3
View File
@@ -13,12 +13,13 @@
#define BLOCK_Z_OUT_UP (1<<10) // Should this object block z uprise from loc?
#define BLOCK_Z_IN_DOWN (1<<11) // Should this object block z falling from above?
#define BLOCK_Z_IN_UP (1<<12) // Should this object block z uprise from below?
#define SHOVABLE_ONTO (1<<13) //called on turf.shove_act() to consider whether an object should have a niche effect (defined in their own shove_act()) when someone is pushed onto it, or do a sanity CanPass() check.
#define SHOVABLE_ONTO (1<<13)//called on turf.shove_act() to consider whether an object should have a niche effect (defined in their own shove_act()) when someone is pushed onto it, or do a sanity CanPass() check.
#define EXAMINE_SKIP (1<<14) /// Makes the Examine proc not read out this item.
/// Integrity defines for clothing (not flags but close enough)
#define CLOTHING_PRISTINE 0 // We have no damage on the clothing
#define CLOTHING_DAMAGED 1 // There's some damage on the clothing but it still has at least one functioning bodypart and can be equipped
#define CLOTHING_SHREDDED 2 // The clothing is useless and cannot be equipped unless repaired first
#define CLOTHING_DAMAGED 1 // There's some damage on the clothing but it still has at least one functioning bodypart
#define CLOTHING_SHREDDED 2 // The clothing is near useless and has their sensors broken
// If you add new ones, be sure to add them to /obj/Initialize as well for complete mapping support
+24 -7
View File
@@ -1,18 +1,35 @@
/// Transparent, let beams pass
#define SHIELD_TRANSPARENT (1<<0)
/// Flammable, takes more damage from fire
#define SHIELD_ENERGY_WEAK (1<<1)
/// Fragile, takes more damage from brute
#define SHIELD_KINETIC_WEAK (1<<2)
/// Strong against kinetic, weak against energy
#define SHIELD_KINETIC_STRONG (1<<3)
/// Strong against energy, weak against kinetic
#define SHIELD_ENERGY_STRONG (1<<4)
/// Disabler and other stamina based energy weapons boost the damage done to the sheld
#define SHIELD_DISABLER_DISRUPTED (1<<5)
/// Doesn't block ranged attacks whatsoever
#define SHIELD_NO_RANGED (1<<6)
/// Doesn't block melee attacks whatsoever
#define SHIELD_NO_MELEE (1<<7)
/// Can shield bash
#define SHIELD_CAN_BASH (1<<1)
#define SHIELD_CAN_BASH (1<<8)
/// Shield bash knockdown on wall hit
#define SHIELD_BASH_WALL_KNOCKDOWN (1<<2)
#define SHIELD_BASH_WALL_KNOCKDOWN (1<<9)
/// Shield bash always knockdown
#define SHIELD_BASH_ALWAYS_KNOCKDOWN (1<<3)
#define SHIELD_BASH_ALWAYS_KNOCKDOWN (1<<10)
/// Shield bash disarm on wall hit
#define SHIELD_BASH_WALL_DISARM (1<<4)
#define SHIELD_BASH_WALL_DISARM (1<<11)
/// Shield bash always disarm
#define SHIELD_BASH_ALWAYS_DISARM (1<<5)
#define SHIELD_BASH_ALWAYS_DISARM (1<<12)
/// You can shieldbash target someone on the ground for ground slam
#define SHIELD_BASH_GROUND_SLAM (1<<6)
#define SHIELD_BASH_GROUND_SLAM (1<<13)
/// Shield bashing someone on the ground will disarm
#define SHIELD_BASH_GROUND_SLAM_DISARM (1<<7)
#define SHIELD_BASH_GROUND_SLAM_DISARM (1<<14)
#define SHIELD_FLAGS_DEFAULT (SHIELD_CAN_BASH | SHIELD_BASH_WALL_KNOCKDOWN | SHIELD_BASH_WALL_DISARM | SHIELD_BASH_GROUND_SLAM)
+1
View File
@@ -80,6 +80,7 @@ GLOBAL_LIST_EMPTY(living_heart_cache) //A list of all living hearts in existance
#define PATH_ASH "Ash"
#define PATH_RUST "Rust"
#define PATH_FLESH "Flesh"
#define PATH_VOID "Void"
//Overthrow time to update heads obj
#define OBJECTIVE_UPDATING_TIME 300
+3
View File
@@ -281,6 +281,9 @@ GLOBAL_LIST_INIT(atmos_adjacent_savings, list(0,0))
#define CALCULATE_ADJACENT_TURFS(T) SSadjacent_air.queue[T] = 1
#endif
//If you're doing spreading things related to atmos, DO NOT USE CANATMOSPASS, IT IS NOT CHEAP. use this instead, the info is cached after all. it's tweaked just a bit to allow for circular checks
#define TURFS_CAN_SHARE(T1, T2) (LAZYACCESS(T2.atmos_adjacent_turfs, T1) || LAZYLEN(T1.atmos_adjacent_turfs & T2.atmos_adjacent_turfs))
GLOBAL_VAR(atmos_extools_initialized) // this must be an uninitialized (null) one or init_monstermos will be called twice because reasons
#define ATMOS_EXTOOLS_CHECK if(!GLOB.atmos_extools_initialized){\
GLOB.atmos_extools_initialized=TRUE;\
+5
View File
@@ -0,0 +1,5 @@
// Shipping methods
#define SHIPPING_METHOD_LTSRBT "LTSRBT" // The BEST way of shipping items: accurate, "undetectable"
#define SHIPPING_METHOD_TELEPORT "Teleport" // Picks a random area to teleport the item to and gives you a minute to get there before it is sent.
#define SHIPPING_METHOD_LAUNCH "Launch" // Throws the item from somewhere at the station.
+2 -3
View File
@@ -60,6 +60,5 @@ GLOBAL_LIST_INIT(podstyles, list(\
))
//cit
#define PACK_GOODY_NONE 0
#define PACK_GOODY_PUBLIC 1 //can be bought by both privates and cargo
#define PACK_GOODY_PRIVATE 2 //can be bought only by privates
#define PACK_GOODY_NONE 0 // can be bought by cargo and privates
#define PACK_GOODY_PRIVATE 1 // can be bought only by privates
-3
View File
@@ -159,9 +159,6 @@
#define SHOVE_STAGGER_DURATION 35
/// how long they're off balance for
#define SHOVE_OFFBALANCE_DURATION 30
//Shove disarming item list
GLOBAL_LIST_INIT(shove_disarming_types, typecacheof(list(
/obj/item/gun)))
//Embedded objects
+25 -4
View File
@@ -24,6 +24,10 @@
// signals from globally accessible objects
/// from SSsun when the sun changes position : (primary_sun, suns)
#define COMSIG_SUN_MOVED "sun_moved"
/// from SSactivity for things that add threat but aren't "global" (e.g. phylacteries)
#define COMSIG_THREAT_CALC "threat_calculation"
//////////////////////////////////////////////////////////////////
// /datum signals
@@ -166,9 +170,15 @@
#define COMSIG_AREA_EXITED "area_exited" //from base of area/Exited(): (atom/movable/M)
// /turf signals
#define COMSIG_TURF_CHANGE "turf_change" //from base of turf/ChangeTurf(): (path, list/new_baseturfs, flags, list/transferring_comps)
#define COMSIG_TURF_HAS_GRAVITY "turf_has_gravity" //from base of atom/has_gravity(): (atom/asker, list/forced_gravities)
#define COMSIG_TURF_MULTIZ_NEW "turf_multiz_new" //from base of turf/New(): (turf/source, direction)
///from base of turf/ChangeTurf(): (path, list/new_baseturfs, flags, list/transferring_comps)
#define COMSIG_TURF_CHANGE "turf_change"
///from base of atom/has_gravity(): (atom/asker, list/forced_gravities)
#define COMSIG_TURF_HAS_GRAVITY "turf_has_gravity"
///from base of turf/multiz_turf_del(): (turf/source, direction)
#define COMSIG_TURF_MULTIZ_DEL "turf_multiz_del"
///from base of turf/multiz_turf_new: (turf/source, direction)
#define COMSIG_TURF_MULTIZ_NEW "turf_multiz_new"
// /atom/movable signals
#define COMSIG_MOVABLE_PRE_MOVE "movable_pre_move" ///from base of atom/movable/Moved(): (/atom)
@@ -256,6 +266,7 @@
#define COMSIG_MOB_GET_VISIBLE_MESSAGE "mob_get_visible_message" //from base of atom/visible_message(): (atom/A, msg, range, ignored_mobs)
#define COMPONENT_NO_VISIBLE_MESSAGE 1 //exactly what's said on the tin.
#define COMSIG_MOB_ANTAG_ON_GAIN "mob_antag_on_gain" //from base of /datum/antagonist/on_gain(): (antag_datum)
#define COMSIG_MOB_APPLY_DAMAGE "mob_apply_damage" //from base of /mob/living/proc/apply_damage(): (damage, damagetype, def_zone, wound_bonus, bare_wound_bonus, sharpness)
#define COMSIG_MOB_SPELL_CAN_CAST "mob_spell_can_cast" //from base of /obj/effect/proc_holder/spell/can_cast(): (spell)
#define COMSIG_MOB_SWAP_HANDS "mob_swap_hands" //from base of mob/swap_hand(): (obj/item)
@@ -293,6 +304,10 @@
#define COMSIG_LIVING_ACTIVE_PARRY_START "active_parry_start" //from base of mob/living/initiate_parry_sequence(): (parrying_method, datum/parrying_item_mob_or_art, list/backup_items, list/override)
#define COMPONENT_PREVENT_PARRY_START 1
#define COMSIG_LIVING_ATTACKER_SET "living_attacker_set" // from base of /mob/living/set_last_attacker(): (attacker)
#define COMSIG_LIVING_SET_AS_ATTACKER "living_set_as_attacker" // from base of /mob/living/set_last_attacker(): (target)
//ALL OF THESE DO NOT TAKE INTO ACCOUNT WHETHER AMOUNT IS 0 OR LOWER AND ARE SENT REGARDLESS!
#define COMSIG_LIVING_STATUS_STUN "living_stun" //from base of mob/living/Stun() (amount, update, ignore)
#define COMSIG_LIVING_STATUS_KNOCKDOWN "living_knockdown" //from base of mob/living/Knockdown() (amount, update, ignore)
@@ -347,7 +362,6 @@
// /obj/item signals
#define COMSIG_ITEM_ATTACK "item_attack" //from base of obj/item/attack(): (/mob/living/target, /mob/living/user)
#define COMSIG_MOB_APPLY_DAMGE "mob_apply_damage" //from base of /mob/living/proc/apply_damage(): (damage, damagetype, def_zone)
#define COMSIG_ITEM_ATTACK_SELF "item_attack_self" //from base of obj/item/attack_self(): (/mob)
#define COMPONENT_NO_INTERACT 1
#define COMSIG_ITEM_ATTACK_OBJ "item_attack_obj" //from base of obj/item/attack_obj(): (/obj, /mob)
@@ -445,6 +459,10 @@
// /datum/mutation signals
#define COMSIG_HUMAN_MUTATION_LOSS "human_mutation_loss" //from datum/mutation/human/on_losing(): (datum/mutation/human/lost_mutation)
///from base of mob/living/death(): (gibbed)
// Sent before any of the other death code has run, mob is still alive.
#define COMSIG_LIVING_PREDEATH "living_predeath"
/*******Component Specific Signals*******/
//Janitor
#define COMSIG_TURF_IS_WET "check_turf_wet" //(): Returns bitflags of wet values.
@@ -462,6 +480,9 @@
#define COMSIG_CLEAR_MOOD_EVENT "clear_mood" //Called when you clear a mood event from anywhere in the code.
#define COMSIG_MODIFY_SANITY "modify_sanity" //Called when you want to increase or decrease sanity from anywhere in the code.
///Mask of Madness
#define COMSIG_VOID_MASK_ACT "void_mask_act"
//NTnet
#define COMSIG_COMPONENT_NTNET_RECEIVE "ntnet_receive" //called on an object by its NTNET connection component on receive. (sending_id(number), sending_netname(text), data(datum/netdata))
+5 -2
View File
@@ -17,7 +17,7 @@ GLOBAL_LIST_INIT(turfs_without_ground, typecacheof(list(
/turf/open/chasm,
/turf/open/lava,
/turf/open/water,
/turf/open/transparent/openspace
/turf/open/openspace
)))
#define isgroundlessturf(A) (is_type_in_typecache(A, GLOB.turfs_without_ground))
@@ -44,7 +44,7 @@ GLOBAL_LIST_INIT(turfs_without_ground, typecacheof(list(
#define isplatingturf(A) (istype(A, /turf/open/floor/plating))
#define istransparentturf(A) (istype(A, /turf/open/transparent)||istype(A, /turf/open/space/transparent))
#define istransparentturf(A) (istype(A, /turf/open/openspace))
//Mobs
#define isliving(A) (istype(A, /mob/living))
@@ -59,6 +59,7 @@ GLOBAL_LIST_INIT(turfs_without_ground, typecacheof(list(
//Human sub-species
#define isabductor(A) (is_species(A, /datum/species/abductor))
#define isgolem(A) (is_species(A, /datum/species/golem))
#define isclockworkgolem(A) (is_species(A, /datum/species/golem/clockwork/no_scrap))
#define islizard(A) (is_species(A, /datum/species/lizard))
#define isplasmaman(A) (is_species(A, /datum/species/plasmaman))
#define ispodperson(A) (is_species(A, /datum/species/pod))
@@ -225,6 +226,8 @@ GLOBAL_LIST_INIT(turfs_without_ground, typecacheof(list(
#define isfood(A) (istype(A, /obj/item/reagent_containers/food/snacks))
#define iscontainer(A) (istype(A, /obj/structure/reagent_dispensers))
//Assemblies
#define isassembly(O) (istype(O, /obj/item/assembly))
+1
View File
@@ -77,6 +77,7 @@
#define PROJECTILE_HIT_THRESHHOLD_LAYER 2.75 //projectiles won't hit objects at or below this layer if possible
#define TABLE_LAYER 2.8
#define TRAY_LAYER 2.85
#define GATEWAY_UNDERLAY_LAYER 2.85
#define BELOW_OBJ_LAYER 2.9
#define LOW_ITEM_LAYER 2.95
//#define OBJ_LAYER 3 //For easy recordkeeping; this is a byond define
+9
View File
@@ -82,3 +82,12 @@
#define LOADOUT_CAN_NAME (1<<0) //renaming items
#define LOADOUT_CAN_DESCRIPTION (1<<1) //adding a custom description to items
#define LOADOUT_CAN_COLOR_POLYCHROMIC (1<<2)
//the names of the customization tabs
#define SETTINGS_TAB 0
#define GAME_PREFERENCES_TAB 1
#define APPEARANCE_TAB 2
#define SPEECH_TAB 3
#define LOADOUT_TAB 4
#define CONTENT_PREFERENCES_TAB 5
#define KEYBINDINGS_TAB 6
+18
View File
@@ -42,6 +42,7 @@ require only minor tweaks.
#define ZTRAIT_SNOWSTORM "Weather_Snowstorm"
#define ZTRAIT_ASHSTORM "Weather_Ashstorm"
#define ZTRAIT_ACIDRAIN "Weather_Acidrain"
#define ZTRAIT_VOIDSTORM "Weather_Voidstorm"
// number - bombcap is multiplied by this before being applied to bombs
#define ZTRAIT_BOMBCAP_MULTIPLIER "Bombcap Multiplier"
@@ -106,6 +107,23 @@ require only minor tweaks.
#define PLACE_LAVA_RUIN "lavaland" //On lavaland ruin z levels(s)
#define PLACE_BELOW "below" //On z levl below - centered on same tile
#define PLACE_ISOLATED "isolated" //On isolated ruin z level
///Map generation defines
#define PERLIN_LAYER_HEIGHT "perlin_height"
#define PERLIN_LAYER_HUMIDITY "perlin_humidity"
#define PERLIN_LAYER_HEAT "perlin_heat"
#define BIOME_LOW_HEAT "low_heat"
#define BIOME_LOWMEDIUM_HEAT "lowmedium_heat"
#define BIOME_HIGHMEDIUM_HEAT "highmedium_heat"
#define BIOME_HIGH_HEAT "high_heat"
#define BIOME_LOW_HUMIDITY "low_humidity"
#define BIOME_LOWMEDIUM_HUMIDITY "lowmedium_humidity"
#define BIOME_HIGHMEDIUM_HUMIDITY "highmedium_humidity"
#define BIOME_HIGH_HUMIDITY "high_humidity"
//Map type stuff.
#define MAP_TYPE_STATION "station"
+8
View File
@@ -205,6 +205,14 @@
#define RULE_OF_THREE(a, b, x) ((a*x)/b)
// )
/// Converts a probability/second chance to probability/delta_time chance
/// For example, if you want an event to happen with a 10% per second chance, but your proc only runs every 5 seconds, do `if(prob(100*DT_PROB_RATE(0.1, 5)))`
#define DT_PROB_RATE(prob_per_second, delta_time) (1 - (1 - (prob_per_second)) ** (delta_time))
/// Like DT_PROB_RATE but easier to use, simply put `if(DT_PROB(10, 5))`
#define DT_PROB(prob_per_second_percent, delta_time) (prob(100*DT_PROB_RATE((prob_per_second_percent)/100, (delta_time))))
// )
#define MANHATTAN_DISTANCE(a, b) (abs(a.x - b.x) + abs(a.y - b.y))
#define LOGISTIC_FUNCTION(L,k,x,x_0) (L/(1+(NUM_E**(-k*(x-x_0)))))
+16 -5
View File
@@ -30,7 +30,8 @@ Will print: "/mob/living/carbon/human/death" (you can optionally embed it in a s
//Human Overlays Indexes/////////
//LOTS OF CIT CHANGES HERE. BE CAREFUL WHEN UPSTREAM ADDS MORE LAYERS
#define MUTATIONS_LAYER 33 //mutations. Tk headglows, cold resistance glow, etc
#define MUTATIONS_LAYER 34 //mutations. Tk headglows, cold resistance glow, etc
#define ANTAG_LAYER 33 //stuff for things like cultism indicators (clock cult glow, cultist red halos, whatever else new that comes up)
#define GENITALS_BEHIND_LAYER 32 //Some genitalia needs to be behind everything, such as with taurs (Taurs use body_behind_layer
#define BODY_BEHIND_LAYER 31 //certain mutantrace features (tail when looking south) that must appear behind the body parts
#define BODYPARTS_LAYER 30 //Initially "AUGMENTS", this was repurposed to be a catch-all bodyparts flag
@@ -63,7 +64,7 @@ Will print: "/mob/living/carbon/human/death" (you can optionally embed it in a s
#define HANDS_LAYER 3
#define BODY_FRONT_LAYER 2
#define FIRE_LAYER 1 //If you're on fire
#define TOTAL_LAYERS 33 //KEEP THIS UP-TO-DATE OR SHIT WILL BREAK ;_;
#define TOTAL_LAYERS 34 //KEEP THIS UP-TO-DATE OR SHIT WILL BREAK ;_;
//Human Overlay Index Shortcuts for alternate_worn_layer, layers
//Because I *KNOW* somebody will think layer+1 means "above"
@@ -158,7 +159,7 @@ GLOBAL_LIST_EMPTY(bloody_footprints_cache)
#define BLOOD_COLOR_SLIME "#00ff90"
#define BLOOD_COLOR_LIZARD "#db004D"
#define BLOOD_COLOR_UNIVERSAL "#db3300"
#define BLOOD_COLOR_BUG "#a37c0f"
#define BLOOD_COLOR_BUG "#ffc933"
#define BLOOD_COLOR_PLANT "#3d610e"
@@ -173,8 +174,18 @@ GLOBAL_LIST_EMPTY(bloody_footprints_cache)
#define BROKEN_SENSORS -1
#define NO_SENSORS 0
#define HAS_SENSORS 1
#define LOCKED_SENSORS 2
#define DAMAGED_SENSORS_LIVING 1
#define DAMAGED_SENSORS_VITALS 2
#define HAS_SENSORS 3
//suit sensor flags: sensor_flag defines
#define SENSOR_RANDOM (1<<0)
#define SENSOR_LOCKED (1<<1)
//suit sensor integrity percentage threshold defines
#define SENSOR_INTEGRITY_COORDS 0.2
#define SENSOR_INTEGRITY_VITALS 0.6
#define SENSOR_INTEGRITY_BINARY 1
//Wet floor type flags. Stronger ones should be higher in number.
#define TURF_DRY (0)
+3
View File
@@ -340,3 +340,6 @@
#define EXAMINE_MORE_TIME 1 SECONDS
#define SILENCE_RANGED_MESSAGE (1<<0)
///Define for spawning megafauna instead of a mob for cave gen
#define SPAWN_MEGAFAUNA "bluh bluh huge boss"
+2 -2
View File
@@ -21,10 +21,10 @@
#define STIMULUM_FIRST_DROP 0.065
#define STIMULUM_SECOND_RISE 0.0009
#define STIMULUM_ABSOLUTE_DROP 0.00000335
#define REACTION_OPPRESSION_THRESHOLD 5
#define REACTION_OPPRESSION_THRESHOLD 10
#define NOBLIUM_FORMATION_ENERGY 2e9 //1 Mole of Noblium takes the planck energy to condense.
//Research point amounts
#define NOBLIUM_RESEARCH_AMOUNT 1000
#define NOBLIUM_RESEARCH_AMOUNT 25
#define BZ_RESEARCH_SCALE 4
#define BZ_RESEARCH_MAX_AMOUNT 400
#define MIASMA_RESEARCH_AMOUNT 6
+3
View File
@@ -41,10 +41,13 @@
#define ROLE_GHOSTCAFE "ghostcafe"
#define ROLE_MINOR_ANTAG "minorantag"
#define ROLE_RESPAWN "respawnsystem"
/// Not an actual antag. Lets players force all antags off.
#define ROLE_NO_ANTAGONISM "NO_ANTAGS"
//Missing assignment means it's not a gamemode specific role, IT'S NOT A BUG OR ERROR.
//The gamemode specific ones are just so the gamemodes can query whether a player is old enough
//(in game days played) to play that role
GLOBAL_LIST_INIT(special_roles, list(
ROLE_NO_ANTAGONISM,
ROLE_TRAITOR = /datum/game_mode/traitor,
ROLE_BROTHER = /datum/game_mode/traitor/bros,
ROLE_OPERATIVE = /datum/game_mode/nuclear,
+4 -1
View File
@@ -90,12 +90,15 @@
#define MAX_AMBITION_LEN 1024
//ambition end
#define MAX_MESSAGE_LEN 4096 //Citadel edit: What's the WORST that could happen?
#define MAX_FLAVOR_LEN 4096
#define MAX_FLAVOR_LEN 4096
#define MAX_TASTE_LEN 40 //lick... vore... ew...
#define MAX_NAME_LEN 42
#define MAX_BROADCAST_LEN 512
#define MAX_CHARTER_LEN 80
// Is something in the IC chat filter? This is config dependent.
#define CHAT_FILTER_CHECK(T) (config.ic_filter_regex && findtext(T, config.ic_filter_regex))
// Audio/Visual Flags. Used to determine what sense are required to notice a message.
#define MSG_VISUAL (1<<0)
#define MSG_AUDIBLE (1<<1)
+9
View File
@@ -106,6 +106,9 @@
#define STATUS_EFFECT_FAKE_VIRUS /datum/status_effect/fake_virus //gives you fluff messages for cough, sneeze, headache, etc but without an actual virus
#define STATUS_EFFECT_NO_COMBAT_MODE /datum/status_effect/no_combat_mode //Wont allow combat mode and will disable it
#define STATUS_EFFECT_STASIS /datum/status_effect/grouped/stasis //Halts biological functions like bleeding, chemical processing, blood regeneration, walking, etc
#define STATUS_EFFECT_MESMERIZE /datum/status_effect/mesmerize //Just reskinned no_combat_mode
#define STATUS_EFFECT_ELECTROSTAFF /datum/status_effect/electrostaff //slows down victim
@@ -138,3 +141,9 @@
#define STATUS_EFFECT_RAINBOWPROTECTION /datum/status_effect/rainbow_protection //Invulnerable and pacifistic
#define STATUS_EFFECT_SLIMESKIN /datum/status_effect/slimeskin //Increased armor
#define STATUS_EFFECT_DNA_MELT /datum/status_effect/dna_melt //usually does something horrible to you when you hit 100 genetic instability
/////////////
// GROUPED //
/////////////
#define STASIS_ASCENSION_EFFECT "heretic_ascension"
+1
View File
@@ -152,6 +152,7 @@
// If the subsystem isn't listed here it's either DEFAULT or PROCESS (if it's a processing subsystem child)
#define FIRE_PRIORITY_VORE 5
#define FIRE_PRIORITY_ACTIVITY 10
#define FIRE_PRIORITY_IDLE_NPC 10
#define FIRE_PRIORITY_SERVER_MAINT 10
#define FIRE_PRIORITY_RESEARCH 10
+5
View File
@@ -215,6 +215,7 @@
#define TRAIT_NO_STAMINA_BUFFER_REGENERATION "block_stamina_buffer_regen" /// Prevents stamina buffer regeneration
#define TRAIT_NO_STAMINA_REGENERATION "block_stamina_regen" /// Prevents stamina regeneration
#define TRAIT_ARMOR_BROKEN "armor_broken" //acts as if you are wearing no clothing when taking damage, does not affect non-clothing sources of protection
#define TRAIT_IWASBATONED "iwasbatoned" //some dastardly fellow has struck you with a baton and thought to use another to strike you again, the rogue
/// forces update_density to make us not dense
#define TRAIT_LIVING_NO_DENSITY "living_no_density"
/// forces us to not render our overlays
@@ -283,6 +284,7 @@
#define SHOES_TRAIT "shoes" //inherited from your sweet kicks
#define GLOVE_TRAIT "glove" //inherited by your cool gloves
#define BOOK_TRAIT "granter (book)" // knowledge is power
#define TURF_TRAIT "turf"
// unique trait sources, still defines
#define STATUE_TRAIT "statue"
@@ -323,12 +325,15 @@
#define ABDUCTOR_ANTAGONIST "abductor-antagonist"
#define MADE_UNCLONEABLE "made-uncloneable"
#define TIMESTOP_TRAIT "timestop"
#define DOMAIN_TRAIT "domain"
#define NUKEOP_TRAIT "nuke-op"
#define CLOWNOP_TRAIT "clown-op"
#define MEGAFAUNA_TRAIT "megafauna"
#define DEATHSQUAD_TRAIT "deathsquad"
#define SLIMEPUDDLE_TRAIT "slimepuddle"
#define CORRUPTED_SYSTEM "corrupted-system"
///Turf trait for when a turf is transparent
#define TURF_Z_TRANSPARENT_TRAIT "turf_z_transparent"
/// This trait is added by the active directional block system.
#define ACTIVE_BLOCK_TRAIT "active_block"
/// This trait is added by the parry system.
+3
View File
@@ -136,3 +136,6 @@
// paintings
#define VV_HK_REMOVE_PAINTING "remove_painting"
//outfits
#define VV_HK_TO_OUTFIT_EDITOR "outfit_editor"
+1 -1
View File
@@ -18,7 +18,7 @@
//ambition end
#define LAZYADD(L, I) if(!L) { L = list(); } L += I;
#define LAZYOR(L, I) if(!L) { L = list(); } L |= I;
#define LAZYFIND(L, V) L ? L.Find(V) : 0
#define LAZYFIND(L, V) (L ? L.Find(V) : 0)
#define LAZYACCESS(L, I) (L ? (isnum(I) ? (I > 0 && I <= length(L) ? L[I] : null) : L[I]) : null)
#define LAZYSET(L, K, V) if(!L) { L = list(); } L[K] = V;
#define LAZYLEN(L) length(L)
+14 -16
View File
@@ -1,8 +1,8 @@
#define BP_MAX_ROOM_SIZE 300
GLOBAL_LIST_INIT(typecache_powerfailure_safe_areas, typecacheof(/area/engine/engineering, \
/area/engine/supermatter, \
/area/engine/atmospherics_engine, \
GLOBAL_LIST_INIT(typecache_powerfailure_safe_areas, typecacheof(/area/engineering/main, \
/area/engineering/supermatter, \
/area/engineering/atmospherics_engine, \
/area/ai_monitored/turret_protected/ai))
//Repopulates sortedAreas list
@@ -85,13 +85,12 @@ GLOBAL_LIST_INIT(typecache_powerfailure_safe_areas, typecacheof(/area/engine/eng
if(target_z == 0 || target_z == T.z)
turfs += T
return turfs
// Gets an atmos isolated contained space
// Returns an associative list of turf|dirs pairs
// The dirs are connected turfs in the same space
// break_if_found is a typecache of turf/area types to return false if found
// Please keep this proc type agnostic. If you need to restrict it do it elsewhere or add an arg.
/proc/detect_room(turf/origin, list/break_if_found)
/proc/detect_room(turf/origin, list/break_if_found, max_size=INFINITY)
if(origin.blocks_air)
return list(origin)
@@ -103,6 +102,8 @@ GLOBAL_LIST_INIT(typecache_powerfailure_safe_areas, typecacheof(/area/engine/eng
found_turfs.Cut(1, 2)
var/dir_flags = checked_turfs[sourceT]
for(var/dir in GLOB.alldirs)
if(length(.) > max_size)
return
if(dir_flags & dir) // This means we've checked this dir before, probably from the other turf
continue
var/turf/checkT = get_step(sourceT, dir)
@@ -115,7 +116,7 @@ GLOBAL_LIST_INIT(typecache_powerfailure_safe_areas, typecacheof(/area/engine/eng
if(break_if_found[checkT.type] || break_if_found[checkT.loc.type])
return FALSE
var/static/list/cardinal_cache = list("[NORTH]"=TRUE, "[EAST]"=TRUE, "[SOUTH]"=TRUE, "[WEST]"=TRUE)
if(!cardinal_cache["[dir]"] || checkT.blocks_air || !CANATMOSPASS(sourceT, checkT))
if(!cardinal_cache["[dir]"] || checkT.blocks_air || !TURFS_CAN_SHARE(sourceT, checkT))
continue
found_turfs += checkT // Since checkT is connected, add it to the list to be processed
@@ -130,25 +131,24 @@ GLOBAL_LIST_INIT(typecache_powerfailure_safe_areas, typecacheof(/area/engine/eng
/area/space,
))
if(creator)
if(creator.create_area_cooldown >= world.time)
to_chat(creator, "<span class='warning'>You're trying to create a new area a little too fast.</span>")
return
creator.create_area_cooldown = world.time + 10
if(creator?.create_area_cooldown >= world.time)
to_chat(creator, "<span class='warning'>You're trying to create a new area a little too fast.</span>")
return
creator.create_area_cooldown = world.time + 10
var/list/turfs = detect_room(get_turf(creator), area_or_turf_fail_types)
var/list/turfs = detect_room(get_turf(creator), area_or_turf_fail_types, BP_MAX_ROOM_SIZE*2)
if(!turfs)
to_chat(creator, "<span class='warning'>The new area must be completely airtight and not a part of a shuttle.</span>")
return
if(turfs.len > BP_MAX_ROOM_SIZE)
to_chat(creator, "<span class='warning'>The room you're in is too big. It is [((turfs.len / BP_MAX_ROOM_SIZE)-1)*100]% larger than allowed.</span>")
to_chat(creator, "<span class='warning'>The room you're in is too big. It is [turfs.len >= BP_MAX_ROOM_SIZE *2 ? "more than 100" : ((turfs.len / BP_MAX_ROOM_SIZE)-1)*100]% larger than allowed.</span>")
return
var/list/areas = list("New Area" = /area)
for(var/i in 1 to turfs.len)
var/area/place = get_area(turfs[i])
if(blacklisted_areas[place.type])
continue
if(!place.requires_power || place.noteleport || place.hidden)
if(!place.requires_power || (place.area_flags & NOTELEPORT) || (place.area_flags & HIDDEN_AREA))
continue // No expanding powerless rooms etc
areas[place.name] = place
var/area_choice = input(creator, "Choose an area to expand or make a new area.", "Area Expansion") as null|anything in areas
@@ -170,7 +170,6 @@ GLOBAL_LIST_INIT(typecache_powerfailure_safe_areas, typecacheof(/area/engine/eng
newA.setup(str)
newA.set_dynamic_lighting()
newA.has_gravity = oldA.has_gravity
newA.noteleport = oldA.noteleport
else
newA = area_choice
@@ -190,7 +189,6 @@ GLOBAL_LIST_INIT(typecache_powerfailure_safe_areas, typecacheof(/area/engine/eng
to_chat(creator, "<span class='notice'>You have created a new area, named [newA.name]. It is now weather proof, and constructing an APC will allow it to be powered.</span>")
return TRUE
/**
* Returns the base area the target is located in if there is one.
* Alternatively, returns the area as is.
+1
View File
@@ -68,6 +68,7 @@
for(var/spath in subtypesof(/datum/species))
var/datum/species/S = new spath()
GLOB.species_list[S.id] = spath
GLOB.species_datums[S.id] = S
//Surgeries
for(var/path in subtypesof(/datum/surgery))
+3 -4
View File
@@ -1051,7 +1051,7 @@ GLOBAL_LIST_EMPTY(friendly_animal_types)
return 0
//For creating consistent icons for human looking simple animals
/proc/get_flat_human_icon(icon_id, datum/job/J, datum/preferences/prefs, dummy_key, showDirs = GLOB.cardinals, outfit_override = null)
/proc/get_flat_human_icon(icon_id, datum/job/J, datum/preferences/prefs, dummy_key, showDirs = GLOB.cardinals, outfit_override = null, no_anim = FALSE)
var/static/list/humanoid_icon_cache = list()
if(!icon_id || !humanoid_icon_cache[icon_id])
var/mob/living/carbon/human/dummy/body = generate_or_wait_for_human_dummy(dummy_key)
@@ -1065,10 +1065,9 @@ GLOBAL_LIST_EMPTY(friendly_animal_types)
var/icon/out_icon = icon('icons/effects/effects.dmi', "nothing")
COMPILE_OVERLAYS(body)
for(var/D in showDirs)
body.setDir(D)
COMPILE_OVERLAYS(body)
var/icon/partial = getFlatIcon(body)
var/icon/partial = getFlatIcon(body, defdir = D, no_anim = no_anim)
out_icon.Insert(partial,dir=D)
humanoid_icon_cache[icon_id] = out_icon
+2
View File
@@ -320,6 +320,8 @@ GLOBAL_LIST_INIT(nonstandard_skin_tones, list("orange"))
GLOBAL_LIST_EMPTY(species_list)
GLOBAL_LIST_EMPTY(species_datums)
/proc/age2agedescription(age)
switch(age)
if(0 to 1)
+6
View File
@@ -95,3 +95,9 @@
if("I'm feeling lucky")
chosen_id = pick(subtypesof(/datum/reagent))
return chosen_id
/proc/find_reagent_object_from_type(input)
if(GLOB.chemical_reagents_list[input]) //prefer IDs!
return GLOB.chemical_reagents_list[input]
else
return null
+10 -5
View File
@@ -386,12 +386,15 @@
//ignore this comment, it fixes the broken sytax parsing caused by the " above
else
parts += "[FOURSPACES]<i>Nobody died this shift!</i>"
var/avg_threat = SSactivity.get_average_threat()
var/max_threat = SSactivity.get_max_threat()
parts += "[FOURSPACES]Threat at round end: [SSactivity.current_threat]"
parts += "[FOURSPACES]Average threat: [avg_threat]"
parts += "[FOURSPACES]Max threat: [max_threat]"
if(istype(SSticker.mode, /datum/game_mode/dynamic))
var/datum/game_mode/dynamic/mode = SSticker.mode
mode.update_playercounts() // ?
parts += "[FOURSPACES]Threat level: [mode.threat_level]"
parts += "[FOURSPACES]Threat left: [mode.threat]"
parts += "[FOURSPACES]Average threat: [mode.threat_average]"
parts += "[FOURSPACES]Target threat: [mode.threat_level]"
parts += "[FOURSPACES]Executed rules:"
for(var/datum/dynamic_ruleset/rule in mode.executed_rules)
parts += "[FOURSPACES][FOURSPACES][rule.ruletype] - <b>[rule.name]</b>: -[rule.cost + rule.scaled_times * rule.scaling_cost] threat"
@@ -400,8 +403,10 @@
parts += "[FOURSPACES][FOURSPACES][str]"
for(var/entry in mode.threat_tallies)
parts += "[FOURSPACES][FOURSPACES][entry] added [mode.threat_tallies[entry]]"
SSblackbox.record_feedback("tally","dynamic_threat",mode.threat_level,"Final threat level")
SSblackbox.record_feedback("tally","dynamic_threat",mode.threat,"Final Threat")
SSblackbox.record_feedback("tally","threat",mode.threat_level,"Target threat")
SSblackbox.record_feedback("tally","threat",SSactivity.current_threat,"Final Threat")
SSblackbox.record_feedback("tally","threat",avg_threat,"Average Threat")
SSblackbox.record_feedback("tally","threat",max_threat,"Max Threat")
return parts.Join("<br>")
/client/proc/roundend_report_file()
+6 -4
View File
@@ -1030,17 +1030,19 @@ B --><-- A
A.cut_overlay(O)
/proc/get_random_station_turf()
return safepick(get_area_turfs(pick(GLOB.the_station_areas)))
var/list/turfs = get_area_turfs(pick(GLOB.the_station_areas))
if (length(turfs))
return pick(turfs)
/proc/get_safe_random_station_turf() //excludes dense turfs (like walls) and areas that have valid_territory set to FALSE
/proc/get_safe_random_station_turf(list/areas_to_pick_from = GLOB.the_station_areas) //excludes dense turfs (like walls) and areas that have valid_territory set to FALSE
for (var/i in 1 to 5)
var/list/L = get_area_turfs(pick(GLOB.the_station_areas))
var/list/L = get_area_turfs(pick(areas_to_pick_from))
var/turf/target
while (L.len && !target)
var/I = rand(1, L.len)
var/turf/T = L[I]
var/area/X = get_area(T)
if(!T.density && X.valid_territory)
if(!T.density && (X.area_flags & VALID_TERRITORY))
var/clear = TRUE
for(var/obj/O in T)
if(O.density)
+30 -1
View File
@@ -11,6 +11,23 @@ GLOBAL_LIST_INIT(bitfields, list(
"TILE_BOUND" = TILE_BOUND,
"PIXEL_SCALE" = PIXEL_SCALE
),
"area_flags" = list(
"ABDUCTOR_PROOF" = ABDUCTOR_PROOF,
"BLOBS_ALLOWED" = BLOBS_ALLOWED,
"BLOCK_SUICIDE" = BLOCK_SUICIDE,
// "CULT_PERMITTED" = CULT_PERMITTED,
"FLORA_ALLOWED" = FLORA_ALLOWED,
"HIDDEN_AREA" = HIDDEN_AREA,
"MEGAFAUNA_SPAWN_ALLOWED" = MEGAFAUNA_SPAWN_ALLOWED,
"MOB_SPAWN_ALLOWED" = MOB_SPAWN_ALLOWED,
"NO_ALERTS" = NO_ALERTS,
"NOTELEPORT" = NOTELEPORT,
"CAVES_ALLOWED" = CAVES_ALLOWED,
"UNIQUE_AREA" = UNIQUE_AREA,
"VALID_TERRITORY" = VALID_TERRITORY,
"XENOBIOLOGY_COMPATIBLE" = XENOBIOLOGY_COMPATIBLE,
"NO_ALERTS" = NO_ALERTS,
) ,
"sight" = list(
"SEE_INFRA" = SEE_INFRA,
"SEE_SELF" = SEE_SELF,
@@ -32,7 +49,12 @@ GLOBAL_LIST_INIT(bitfields, list(
"UNIQUE_RENAME" = UNIQUE_RENAME,
"USES_TGUI" = USES_TGUI,
"FROZEN" = FROZEN,
"SHOVABLE_ONTO" = SHOVABLE_ONTO
"SHOVABLE_ONTO" = SHOVABLE_ONTO,
"BLOCK_Z_OUT_DOWN" = BLOCK_Z_OUT_DOWN,
"BLOCK_Z_OUT_UP" = BLOCK_Z_OUT_UP,
"BLOCK_Z_IN_DOWN" = BLOCK_Z_IN_DOWN,
"BLOCK_Z_IN_UP" = BLOCK_Z_IN_UP,
"EXAMINE_SKIP" = EXAMINE_SKIP
),
"datum_flags" = list(
"DF_USE_TAG" = DF_USE_TAG,
@@ -259,6 +281,13 @@ GLOBAL_LIST_INIT(bitfields, list(
),
"shield_flags" = list(
"SHIELD_TRANSPARENT" = SHIELD_TRANSPARENT,
"SHIELD_ENERGY_WEAK" = SHIELD_ENERGY_WEAK,
"SHIELD_KINETIC_WEAK" = SHIELD_KINETIC_WEAK,
"SHIELD_KINETIC_STRONG" = SHIELD_KINETIC_STRONG,
"SHIELD_ENERGY_STRONG" = SHIELD_ENERGY_STRONG,
"SHIELD_DISABLER_DISRUPTED" = SHIELD_DISABLER_DISRUPTED,
"SHIELD_NO_RANGED" = SHIELD_NO_RANGED,
"SHIELD_NO_MELEE" = SHIELD_NO_MELEE,
"SHIELD_CAN_BASH" = SHIELD_CAN_BASH,
"SHIELD_BASH_WALL_KNOCKDOWN" = SHIELD_BASH_WALL_KNOCKDOWN,
"SHIELD_BASH_ALWAYS_KNOCKDOWN" = SHIELD_BASH_ALWAYS_KNOCKDOWN,
+11
View File
@@ -284,6 +284,17 @@ GLOBAL_LIST_INIT(wisdoms, world.file2list("strings/wisdoms.txt"))
GLOBAL_LIST_INIT(speech_verbs, list("default","says","gibbers", "states", "chitters", "chimpers", "declares", "bellows", "buzzes" ,"beeps", "chirps", "clicks", "hisses" ,"poofs" , "puffs", "rattles", "mewls" ,"barks", "blorbles", "squeaks", "squawks", "flutters", "warbles", "caws", "gekkers", "clucks"))
GLOBAL_LIST_INIT(roundstart_tongues, list("default","human tongue" = /obj/item/organ/tongue, "lizard tongue" = /obj/item/organ/tongue/lizard, "skeleton tongue" = /obj/item/organ/tongue/bone, "fly tongue" = /obj/item/organ/tongue/fly, "ipc tongue" = /obj/item/organ/tongue/robot/ipc, "xeno tongue" = /obj/item/organ/tongue/alien))
/proc/get_roundstart_languages()
var/list/languages = subtypesof(/datum/language)
var/list/roundstart_languages = list("None") //default option for the list
for(var/some_language in languages)
var/datum/language/language = some_language
if(initial(language.chooseable_roundstart))
roundstart_languages[initial(language.name)] = some_language
return roundstart_languages
GLOBAL_LIST_INIT(roundstart_languages, get_roundstart_languages())
//SPECIES BODYPART LISTS
//locked parts are those that your picked species requires to have
//unlocked parts are those that anyone can choose on customisation regardless
+3
View File
@@ -48,6 +48,9 @@ GLOBAL_LIST_EMPTY_TYPED(areas_by_type, /area)
GLOBAL_LIST_EMPTY(all_abstract_markers)
/// Global list of megafauna spawns on cave gen
GLOBAL_LIST_INIT(megafauna_spawn_list, list(/mob/living/simple_animal/hostile/megafauna/dragon = 4, /mob/living/simple_animal/hostile/megafauna/colossus = 2, /mob/living/simple_animal/hostile/megafauna/bubblegum = 6))
GLOBAL_LIST_EMPTY(stationroom_landmarks) //List of all spawns for stationrooms
///Away missions, VR, random z levels stuff.
+1 -1
View File
@@ -123,7 +123,7 @@ GLOBAL_LIST_INIT(traits_by_type, list(
"TRAIT_HIGH_BLOOD" = TRAIT_HIGH_BLOOD,
"TRAIT_EMPATH" = TRAIT_EMPATH,
"TRAIT_FRIENDLY" = TRAIT_FRIENDLY,
"TRAIT_NICE_SHOT" = TRAIT_NICE_SHOT
"TRAIT_IWASBATONED" = TRAIT_IWASBATONED
),
/obj/item/bodypart = list(
"TRAIT_PARALYSIS" = TRAIT_PARALYSIS
+4
View File
@@ -169,5 +169,9 @@
A.attack_robot(src)
/atom/proc/attack_robot(mob/user)
if((isturf(src) || istype(src, /obj/structure/table) || istype(src, /obj/machinery/conveyor)) && get_dist(user, src) <= 1)
user.Move_Pulled(src)
return
attack_ai(user)
return
+4 -4
View File
@@ -3,7 +3,7 @@
var/obj/screen/blockchance
var/obj/screen/counterchance
/datum/hud/marauder/New(mob/living/simple_animal/hostile/clockwork/marauder/guardian/owner)
/datum/hud/marauder/New(mob/living/simple_animal/hostile/clockwork/guardian/owner)
..()
var/obj/screen/using
@@ -24,7 +24,7 @@
hosthealth = null
return ..()
/mob/living/simple_animal/hostile/clockwork/marauder/guardian/create_mob_hud()
/mob/living/simple_animal/hostile/clockwork/guardian/create_mob_hud()
if(client && !hud_used)
hud_used = new /datum/hud/marauder(src, ui_style2icon(client.prefs.UI_style))
@@ -37,8 +37,8 @@
desc = "Emerge or Return."
/obj/screen/marauder/emerge/Click()
if(istype(usr, /mob/living/simple_animal/hostile/clockwork/marauder/guardian))
var/mob/living/simple_animal/hostile/clockwork/marauder/guardian/G = usr
if(istype(usr, /mob/living/simple_animal/hostile/clockwork/guardian))
var/mob/living/simple_animal/hostile/clockwork/guardian/G = usr
if(G.is_in_host())
G.try_emerge()
else
+1 -1
View File
@@ -361,7 +361,7 @@
/obj/screen/mov_intent/update_icon_state()
switch(hud?.mymob?.m_intent)
if(MOVE_INTENT_WALK)
icon_state = "walking"
icon_state = CONFIG_GET(flag/sprint_enabled)? "walking" : "walking_nosprint"
if(MOVE_INTENT_RUN)
icon_state = CONFIG_GET(flag/sprint_enabled)? "running" : "running_nosprint"
+47 -9
View File
@@ -85,21 +85,16 @@
makeItemInactive()
/obj/screen/storage/volumetric_box/proc/makeItemInactive()
if(!our_item)
return
our_item.layer = VOLUMETRIC_STORAGE_ITEM_LAYER
our_item.plane = VOLUMETRIC_STORAGE_ITEM_PLANE
return
/obj/screen/storage/volumetric_box/proc/makeItemActive()
if(!our_item)
return
our_item.layer = VOLUMETRIC_STORAGE_ACTIVE_ITEM_LAYER //make sure we display infront of the others!
our_item.plane = VOLUMETRIC_STORAGE_ACTIVE_ITEM_PLANE
return
/obj/screen/storage/volumetric_box/center
icon_state = "stored_continue"
var/obj/screen/storage/volumetric_edge/stored_left/left
var/obj/screen/storage/volumetric_edge/stored_right/right
var/obj/screen/storage/item_holder/holder
var/pixel_size
/obj/screen/storage/volumetric_box/center/Initialize(mapload, new_master, our_item)
@@ -110,6 +105,9 @@
/obj/screen/storage/volumetric_box/center/Destroy()
QDEL_NULL(left)
QDEL_NULL(right)
vis_contents.Cut()
if(holder)
QDEL_NULL(holder)
return ..()
/obj/screen/storage/volumetric_box/center/proc/on_screen_objects()
@@ -123,13 +121,36 @@
return
pixel_size = pixels
cut_overlays()
vis_contents.Cut()
//our icon size is 32 pixels.
transform = matrix((pixels - (VOLUMETRIC_STORAGE_BOX_BORDER_SIZE * 2)) / VOLUMETRIC_STORAGE_BOX_ICON_SIZE, 0, 0, 0, 1, 0)
var/multiplier = (pixels - (VOLUMETRIC_STORAGE_BOX_BORDER_SIZE * 2)) / VOLUMETRIC_STORAGE_BOX_ICON_SIZE
transform = matrix(multiplier, 0, 0, 0, 1, 0)
if(our_item)
if(holder)
qdel(holder)
holder = new(null, src, our_item)
holder.transform = matrix(1 / multiplier, 0, 0, 0, 1, 0)
holder.mouse_opacity = MOUSE_OPACITY_TRANSPARENT
holder.appearance_flags &= ~RESET_TRANSFORM
makeItemInactive()
vis_contents += holder
left.pixel_x = -((pixels - VOLUMETRIC_STORAGE_BOX_ICON_SIZE) * 0.5) - VOLUMETRIC_STORAGE_BOX_BORDER_SIZE
right.pixel_x = ((pixels - VOLUMETRIC_STORAGE_BOX_ICON_SIZE) * 0.5) + VOLUMETRIC_STORAGE_BOX_BORDER_SIZE
add_overlay(left)
add_overlay(right)
/obj/screen/storage/volumetric_box/center/makeItemInactive()
if(!holder)
return
holder.layer = VOLUMETRIC_STORAGE_ITEM_LAYER
holder.plane = VOLUMETRIC_STORAGE_ITEM_PLANE
/obj/screen/storage/volumetric_box/center/makeItemActive()
if(!holder)
return
holder.our_item.layer = VOLUMETRIC_STORAGE_ACTIVE_ITEM_LAYER //make sure we display infront of the others!
holder.our_item.plane = VOLUMETRIC_STORAGE_ACTIVE_ITEM_PLANE
/obj/screen/storage/volumetric_edge
layer = VOLUMETRIC_STORAGE_BOX_LAYER
plane = VOLUMETRIC_STORAGE_BOX_PLANE
@@ -157,3 +178,20 @@
/obj/screen/storage/volumetric_edge/stored_right
icon_state = "stored_end"
appearance_flags = APPEARANCE_UI | KEEP_APART | RESET_TRANSFORM
/obj/screen/storage/item_holder
var/obj/item/our_item
vis_flags = NONE
/obj/screen/storage/item_holder/Initialize(mapload, new_master, obj/item/I)
. = ..()
our_item = I
vis_contents += I
/obj/screen/storage/item_holder/Destroy()
vis_contents.Cut()
our_item = null
return ..()
/obj/screen/storage/item_holder/Click(location, control, params)
return our_item.Click(location, control, params)
+1 -2
View File
@@ -94,8 +94,7 @@
else if(hitsound)
playsound(loc, hitsound, get_clamped_volume(), 1, -1)
M.lastattacker = user.real_name
M.lastattackerckey = user.ckey
M.set_last_attacker(user)
if(force && M == user && user.client)
user.client.give_award(/datum/award/achievement/misc/selfouch, user)
@@ -22,7 +22,7 @@
var/motd
// var/policy
// var/static/regex/ic_filter_regex
var/static/regex/ic_filter_regex
/datum/controller/configuration/proc/admin_reload()
if(IsAdminAdvancedProcCall())
@@ -53,7 +53,7 @@
loadmaplist(CONFIG_MAPS_FILE)
LoadMOTD()
// LoadPolicy()
// LoadChatFilter()
LoadChatFilter()
if (Master)
Master.OnConfigLoad()
@@ -404,9 +404,9 @@ Example config:
if(!Get(/datum/config_entry/flag/no_storyteller_threat_removal))
var/min_chaos = (probabilities in storyteller_min_chaos) ? storyteller_min_chaos[config_tag] : initial(S.min_chaos)
var/max_chaos = (probabilities in storyteller_max_chaos) ? storyteller_max_chaos[config_tag] : initial(S.max_chaos)
if(SSpersistence.average_dynamic_threat < min_chaos)
if(SSpersistence.average_threat + 50 < min_chaos)
continue
if(SSpersistence.average_dynamic_threat > max_chaos)
if(SSpersistence.average_threat + 50 > max_chaos)
continue
if(SSpersistence.saved_storytellers.len == repeated_mode_adjust.len)
var/name = initial(S.name)
@@ -486,7 +486,7 @@ Example config:
continue
runnable_modes[M] = probabilities[M.config_tag]
return runnable_modes
/*
/datum/controller/configuration/proc/LoadChatFilter()
var/list/in_character_filter = list()
if(!fexists("[directory]/in_character_filter.txt"))
@@ -499,7 +499,7 @@ Example config:
continue
in_character_filter += REGEX_QUOTE(line)
ic_filter_regex = in_character_filter.len ? regex("\\b([jointext(in_character_filter, "|")])\\b", "i") : null
*/
//Message admins when you can.
/datum/controller/configuration/proc/DelayedMessageAdmins(text)
addtimer(CALLBACK(GLOBAL_PROC, /proc/message_admins, text), 0)
+75
View File
@@ -0,0 +1,75 @@
SUBSYSTEM_DEF(activity)
name = "Activity tracking"
flags = SS_BACKGROUND | SS_NO_TICK_CHECK
priority = FIRE_PRIORITY_ACTIVITY
wait = 1 MINUTES
var/list/deferred_threats = list()
var/current_threat = 0
var/list/threat_history = list()
var/list/threats = list()
/datum/controller/subsystem/activity/Initialize(timeofday)
RegisterSignal(SSdcs,COMSIG_GLOB_EXPLOSION,.proc/on_explosion)
RegisterSignal(SSdcs,COMSIG_GLOB_MOB_DEATH,.proc/on_death)
/datum/controller/subsystem/activity/fire(resumed = 0)
calculate_threat()
/datum/controller/subsystem/activity/proc/calculate_threat()
threats = deferred_threats.Copy()
deferred_threats.Cut()
threats["antagonists"] = 0
for(var/datum/antagonist/A in GLOB.antagonists)
if(A?.owner?.current && A.owner.current.stat != DEAD)
threats["antagonists"] += A.threat()
threats["events"] = 0
for(var/r in SSevents.running)
var/datum/round_event/R = r
threats["events"] += R.threat()
threats["players"] = 0
SEND_SIGNAL(src, COMSIG_THREAT_CALC, threats)
for(var/m in GLOB.player_list)
var/mob/M = m
if (M?.mind?.assigned_role && M.stat != DEAD)
var/datum/job/J = SSjob.GetJob(M.mind.assigned_role)
if(J)
if(length(M.mind.antag_datums))
threats["players"] += J.GetThreat()
else
threats["players"] -= J.GetThreat()
else if(M?.stat == DEAD && !M.voluntary_ghosted)
threats["dead_players"] += 1
current_threat = 0
for(var/threat_type in threats)
current_threat += threats[threat_type]
threat_history += "[world.time]"
threat_history["[world.time]"] = current_threat
/datum/controller/subsystem/activity/proc/get_average_threat()
if(!length(threat_history))
return 0
var/total_weight = 0
var/total_amt = 0
for(var/i in 1 to threat_history.len-1)
var/weight = (text2num(threat_history[i+1])-text2num(threat_history[i]))
total_weight += weight
total_amt += weight * (threat_history[threat_history[i]])
return round(total_amt / total_weight,0.1)
/datum/controller/subsystem/activity/proc/get_max_threat()
. = 0
for(var/threat in threat_history)
. = max(threat_history[threat], .)
/datum/controller/subsystem/activity/proc/on_explosion(datum/source, atom/epicenter, devastation_range, heavy_impact_range, light_impact_range, took, orig_dev_range, orig_heavy_range, orig_light_range)
if(!("explosions" in deferred_threats))
deferred_threats["explosions"] = 0
var/area/A = get_area(epicenter)
if(is_station_level(epicenter.z) && (A.area_flags & BLOBS_ALLOWED) && !istype(A, /area/asteroid))
deferred_threats["explosions"] += devastation_range**2 + heavy_impact_range**2 / 4 + light_impact_range**2 / 8 // 75 for a maxcap
/datum/controller/subsystem/activity/proc/on_death(datum/source, mob/M, gibbed)
if(!("crew_deaths" in deferred_threats))
deferred_threats["crew_deaths"] = 0
if(M?.mind && SSjob.GetJob(M.mind.assigned_role))
deferred_threats["crew_deaths"] += 1
+89
View File
@@ -0,0 +1,89 @@
SUBSYSTEM_DEF(blackmarket)
name = "Blackmarket"
flags = SS_BACKGROUND
init_order = INIT_ORDER_DEFAULT
// Descriptions for each shipping method.
var/shipping_method_descriptions = list(
SHIPPING_METHOD_LAUNCH="Launches the item at the station from space, cheap but you might not recieve your item at all.",
SHIPPING_METHOD_LTSRBT="Long-To-Short-Range-Bluespace-Transceiver, a machine that recieves items outside the station and then teleports them to the location of the uplink.",
SHIPPING_METHOD_TELEPORT="Teleports the item in a random area in the station, you get 60 seconds to get there first though."
)
var/list/datum/blackmarket_market/markets = list() // List of all existing markets.
var/list/obj/machinery/ltsrbt/telepads = list() // List of existing ltsrbts.
var/list/queued_purchases = list() // Currently queued purchases.
/datum/controller/subsystem/blackmarket/Initialize(timeofday)
for(var/market in subtypesof(/datum/blackmarket_market))
markets[market] += new market
for(var/item in subtypesof(/datum/blackmarket_item))
var/datum/blackmarket_item/I = new item()
if(!I.item)
continue
for(var/M in I.markets)
if(!markets[M])
stack_trace("SSblackmarket: Item [I] available in market that does not exist.")
continue
markets[M].add_item(item)
qdel(I)
. = ..()
/datum/controller/subsystem/blackmarket/fire(resumed)
while(length(queued_purchases))
var/datum/blackmarket_purchase/purchase = queued_purchases[1]
queued_purchases.Cut(1,2)
if(!purchase.uplink || QDELETED(purchase.uplink)) // Uh oh, uplink is gone. We will just keep the money and you will not get your order.
queued_purchases -= purchase
qdel(purchase)
continue
switch(purchase.method)
if(SHIPPING_METHOD_LTSRBT) // Find a ltsrbt pad and make it handle the shipping.
if(!telepads.len)
continue
var/free_pad_found = FALSE // Prioritize pads that don't have a cooldown active.
for(var/obj/machinery/ltsrbt/pad in telepads)
if(pad.recharge_cooldown)
continue
pad.add_to_queue(purchase)
queued_purchases -= purchase
free_pad_found = TRUE
break
if(free_pad_found)
continue
var/obj/machinery/ltsrbt/pad = pick(telepads)
to_chat(recursive_loc_check(purchase.uplink.loc, /mob), "<span class='notice'>[purchase.uplink] flashes a message noting that the order is being processed by [pad].</span>")
queued_purchases -= purchase
pad.add_to_queue(purchase)
if(SHIPPING_METHOD_TELEPORT) // Get random area, throw it somewhere there.
var/turf/targetturf = get_safe_random_station_turf()
if (!targetturf) // This shouldn't happen.
continue
to_chat(recursive_loc_check(purchase.uplink.loc, /mob), "<span class='notice'>[purchase.uplink] flashes a message noting that the order is being teleported to [get_area(targetturf)] in 60 seconds.</span>")
addtimer(CALLBACK(src, /datum/controller/subsystem/blackmarket/proc/fake_teleport, purchase.entry.spawn_item(), targetturf), 60 SECONDS) // do_teleport does not want to teleport items from nullspace, so it just forceMoves and does sparks.
queued_purchases -= purchase
qdel(purchase)
if(SHIPPING_METHOD_LAUNCH) // Get the current location of the uplink if it exists, then throws the item from space at the station from a random direction.
var/startSide = pick(GLOB.cardinals)
var/turf/T = get_turf(purchase.uplink)
var/pickedloc = spaceDebrisStartLoc(startSide, T.z)
var/atom/movable/item = purchase.entry.spawn_item(pickedloc)
item.throw_at(purchase.uplink, 3, 3, spin = FALSE)
to_chat(recursive_loc_check(purchase.uplink.loc, /mob), "<span class='notice'>[purchase.uplink] flashes a message noting the order is being launched at the station from [dir2text(startSide)].</span>")
queued_purchases -= purchase
qdel(purchase)
if(MC_TICK_CHECK)
break
/datum/controller/subsystem/blackmarket/proc/fake_teleport(atom/movable/item, turf/target) // Used to make a teleportation effect as do_teleport does not like moving items from nullspace.
item.forceMove(target)
var/datum/effect_system/spark_spread/sparks = new
sparks.set_up(5, 1, target)
sparks.attach(item)
sparks.start()
/datum/controller/subsystem/blackmarket/proc/queue_item(datum/blackmarket_purchase/P) // Used to add /datum/blackmarket_purchase to queued_purchases var. Returns TRUE when queued.
if(P.method == SHIPPING_METHOD_LTSRBT && !telepads.len)
return FALSE
queued_purchases += P
return TRUE
+21 -34
View File
@@ -490,42 +490,29 @@ SUBSYSTEM_DEF(job)
job.after_spawn(H, M, joined_late) // note: this happens before the mob has a key! M will always have a client, H might not.
equip_loadout(N, H, TRUE)//CIT CHANGE - makes players spawn with in-backpack loadout items properly. A little hacky but it works
if(ishuman(H) && H.client && N)
if(H.client && H.client.prefs && length(H.client.prefs.tcg_cards))
var/obj/item/tcgcard_binder/binder = new(get_turf(H))
H.equip_to_slot_if_possible(binder, SLOT_IN_BACKPACK, disable_warning = TRUE, bypass_equip_delay_self = TRUE)
for(var/card_type in H.client.prefs.tcg_cards)
if(card_type)
if(islist(H.client.prefs.tcg_cards[card_type]))
for(var/duplicate in H.client.prefs.tcg_cards[card_type])
var/obj/item/tcg_card/card = new(get_turf(H), card_type, duplicate)
card.forceMove(binder)
binder.cards.Add(card)
else
var/obj/item/tcg_card/card = new(get_turf(H), card_type, H.client.prefs.tcg_cards[card_type])
var/list/tcg_cards
if(ishuman(H))
if(length(H.client?.prefs?.tcg_cards))
tcg_cards = H.client.prefs.tcg_cards
else if(length(N?.client?.prefs?.tcg_cards))
tcg_cards = N.client.prefs.tcg_cards
if(tcg_cards)
var/obj/item/tcgcard_binder/binder = new(get_turf(H))
H.equip_to_slot_if_possible(binder, SLOT_IN_BACKPACK, disable_warning = TRUE, bypass_equip_delay_self = TRUE)
for(var/card_type in N.client.prefs.tcg_cards)
if(card_type)
if(islist(H.client.prefs.tcg_cards[card_type]))
for(var/duplicate in N.client.prefs.tcg_cards[card_type])
var/obj/item/tcg_card/card = new(get_turf(H), card_type, duplicate)
card.forceMove(binder)
binder.cards.Add(card)
binder.check_for_exodia()
if(length(H.client.prefs.tcg_decks))
binder.decks = H.client.prefs.tcg_decks
else
if(H && N.client.prefs && length(N.client.prefs.tcg_cards))
var/obj/item/tcgcard_binder/binder = new(get_turf(H))
H.equip_to_slot_if_possible(binder, SLOT_IN_BACKPACK, disable_warning = TRUE, bypass_equip_delay_self = TRUE)
for(var/card_type in N.client.prefs.tcg_cards)
if(card_type)
if(islist(H.client.prefs.tcg_cards[card_type]))
for(var/duplicate in N.client.prefs.tcg_cards[card_type])
var/obj/item/tcg_card/card = new(get_turf(H), card_type, duplicate)
card.forceMove(binder)
binder.cards.Add(card)
else
var/obj/item/tcg_card/card = new(get_turf(H), card_type, N.client.prefs.tcg_cards[card_type])
card.forceMove(binder)
binder.cards.Add(card)
binder.check_for_exodia()
if(length(N.client.prefs.tcg_decks))
binder.decks = N.client.prefs.tcg_decks
else
var/obj/item/tcg_card/card = new(get_turf(H), card_type, N.client.prefs.tcg_cards[card_type])
card.forceMove(binder)
binder.cards.Add(card)
binder.check_for_exodia()
if(length(N.client.prefs.tcg_decks))
binder.decks = N.client.prefs.tcg_decks
return H
/*
+26 -5
View File
@@ -34,6 +34,9 @@ SUBSYSTEM_DEF(mapping)
var/list/reservation_ready = list()
var/clearing_reserved_turfs = FALSE
///All possible biomes in assoc list as type || instance
var/list/biomes = list()
// Z-manager stuff
var/station_start // should only be used for maploading-related tasks
var/space_levels_so_far = 0
@@ -79,10 +82,12 @@ SUBSYSTEM_DEF(mapping)
config = old_config
GLOB.year_integer += config.year_offset
GLOB.announcertype = (config.announcertype == "standard" ? (prob(1) ? "medibot" : "classic") : config.announcertype)
initialize_biomes()
loadWorld()
repopulate_sorted_areas()
process_teleport_locs() //Sets up the wizard teleport locations
preloadTemplates()
#ifndef LOWMEMORYMODE
// Create space ruin levels
while (space_levels_so_far < config.space_ruin_levels)
@@ -92,15 +97,16 @@ SUBSYSTEM_DEF(mapping)
for (var/i in 1 to config.space_empty_levels)
++space_levels_so_far
empty_space = add_new_zlevel("Empty Area [space_levels_so_far]", list(ZTRAIT_LINKAGE = CROSSLINKED))
// and the transit level
transit = add_new_zlevel("Transit/Reserved", list(ZTRAIT_RESERVED = TRUE))
// Pick a random away mission.
if(CONFIG_GET(flag/roundstart_away))
createRandomZlevel()
// Pick a random VR level.
// Load the virtual reality hub
if(CONFIG_GET(flag/roundstart_vr))
to_chat(world, "<span class='boldannounce'>Loading virtual reality...</span>")
createRandomZlevel(VIRT_REALITY_NAME, list(ZTRAIT_AWAY = TRUE, ZTRAIT_VR = TRUE), GLOB.potential_vr_levels)
to_chat(world, "<span class='boldannounce'>Virtual reality loaded.</span>")
// Generate mining ruins
loading_ruins = TRUE
@@ -115,7 +121,7 @@ SUBSYSTEM_DEF(mapping)
// needs to be whitelisted for underground too so place_below ruins work
seedRuins(ice_ruins, CONFIG_GET(number/icemoon_budget), list(/area/icemoon/surface/outdoors/unexplored, /area/icemoon/underground/unexplored), ice_ruins_templates)
for (var/ice_z in ice_ruins)
spawn_rivers(ice_z, 4, /turf/open/transparent/openspace/icemoon, /area/icemoon/surface/outdoors/unexplored/rivers)
spawn_rivers(ice_z, 4, /turf/open/openspace/icemoon, /area/icemoon/surface/outdoors/unexplored/rivers)
var/list/ice_ruins_underground = levels_by_trait(ZTRAIT_ICE_RUINS_UNDERGROUND)
if (ice_ruins_underground.len)
@@ -133,8 +139,13 @@ SUBSYSTEM_DEF(mapping)
if (station_ruins.len)
seedRuins(station_ruins, (SSmapping.config.station_ruin_budget < 0) ? CONFIG_GET(number/station_space_budget) : SSmapping.config.station_ruin_budget, list(/area/space/station_ruins), station_ruins_templates)
SSmapping.seedStation()
loading_ruins = FALSE
#endif
// Run map generation after ruin generation to prevent issues
run_map_generation()
// Add the transit level
transit = add_new_zlevel("Transit/Reserved", list(ZTRAIT_RESERVED = TRUE))
repopulate_sorted_areas()
// Set up Z-level transitions.
setup_map_transitions()
@@ -320,7 +331,7 @@ GLOBAL_LIST_EMPTY(the_station_areas)
for(var/area/A in world)
if (is_type_in_typecache(A, station_areas_blacklist))
continue
if (!A.contents.len || !A.unique)
if (!A.contents.len || !(A.area_flags & UNIQUE_AREA))
continue
var/turf/picked = A.contents[1]
if (is_station_level(picked.z))
@@ -329,6 +340,10 @@ GLOBAL_LIST_EMPTY(the_station_areas)
if(!GLOB.the_station_areas.len)
log_world("ERROR: Station areas list failed to generate!")
/datum/controller/subsystem/mapping/proc/run_map_generation()
for(var/area/A in world)
A.RunGeneration()
/datum/controller/subsystem/mapping/proc/maprotate()
var/players = GLOB.clients.len
var/list/mapvotes = list()
@@ -584,6 +599,12 @@ GLOBAL_LIST_EMPTY(the_station_areas)
used_turfs.Cut()
reserve_turfs(clearing)
///Initialize all biomes, assoc as type || instance
/datum/controller/subsystem/mapping/proc/initialize_biomes()
for(var/biome_path in subtypesof(/datum/biome))
var/datum/biome/biome_instance = new biome_path()
biomes[biome_path] += biome_instance
/datum/controller/subsystem/mapping/proc/reg_in_areas_in_z(list/areas)
for(var/B in areas)
var/area/A = B
+1 -1
View File
@@ -1,7 +1,7 @@
SUBSYSTEM_DEF(min_spawns)
name = "Minimum Spawns" /// this hot steaming pile of garbage makes sure theres a minimum of tendrils scattered around
init_order = INIT_ORDER_DEFAULT
flags = SS_BACKGROUND | SS_NO_FIRE
flags = SS_NO_FIRE | SS_NO_INIT
wait = 2
var/where_we_droppin_boys_iterations = 0
var/snaxi_snowflake_check = FALSE
@@ -6,7 +6,7 @@
var/list/saved_chaos = list(5,5,5)
var/list/saved_dynamic_rules = list(list(),list(),list())
var/list/saved_storytellers = list("foo","bar","baz")
var/list/average_dynamic_threat = 50
var/average_threat = 50
var/list/saved_maps
/datum/controller/subsystem/persistence/SaveServerPersistence()
@@ -38,9 +38,10 @@
saved_chaos[3] = saved_chaos[2]
saved_chaos[2] = saved_chaos[1]
saved_chaos[1] = SSticker.mode.get_chaos()
average_threat = (SSactivity.get_average_threat() + average_threat) / 2
json_file = file("data/RecentChaos.json")
file_data = list()
file_data["data"] = saved_chaos
file_data["data"] = saved_chaos + average_threat
fdel(json_file)
WRITE_FILE(json_file, json_encode(file_data))
@@ -49,10 +50,9 @@
saved_storytellers[3] = saved_storytellers[2]
saved_storytellers[2] = saved_storytellers[1]
saved_storytellers[1] = mode.storyteller.name
average_dynamic_threat = (mode.max_threat + average_dynamic_threat) / 2
var/json_file = file("data/RecentStorytellers.json")
var/list/file_data = list()
file_data["data"] = saved_storytellers + average_dynamic_threat
file_data["data"] = saved_storytellers
fdel(json_file)
WRITE_FILE(json_file, json_encode(file_data))
@@ -94,6 +94,9 @@
if(!json)
return
saved_chaos = json["data"]
if(saved_chaos.len > 3)
average_threat = saved_chaos[4]
saved_chaos.len = 3
/datum/controller/subsystem/persistence/proc/LoadRecentRulesets()
var/json_file = file("data/RecentRulesets.json")
@@ -112,9 +115,6 @@
if(!json)
return
saved_storytellers = json["data"]
if(saved_storytellers.len > 3)
average_dynamic_threat = saved_storytellers[4]
saved_storytellers.len = 3
/datum/controller/subsystem/persistence/proc/LoadRecentMaps()
var/json_file = file("data/RecentMaps.json")
@@ -47,5 +47,5 @@ SUBSYSTEM_DEF(processing)
* If you override this do not call parent, as it will return PROCESS_KILL. This is done to prevent objects that dont override process() from staying in the processing list
*/
/datum/proc/process(delta_time)
set waitfor = FALSE
// SHOULD_NOT_SLEEP(TRUE)
return PROCESS_KILL
+2 -2
View File
@@ -609,9 +609,9 @@ SUBSYSTEM_DEF(ticker)
var/list/ded = SSblackbox.first_death
if(ded.len)
var/last_words = ded["last_words"] ? " Their last words were: \"[ded["last_words"]]\"" : ""
news_message += " NT Sanctioned Psykers picked up faint traces of someone near the station, allegedly having had died. Their name was: [ded["name"]], [ded["role"]], at [ded["area"]].[last_words]"
news_message += "\nNT Sanctioned Psykers picked up faint traces of someone near the station, allegedly having had died. Their name was: [ded["name"]], [ded["role"]], at [ded["area"]].[last_words]"
else
news_message += " NT Sanctioned Psykers proudly confirm reports that nobody died this shift!"
news_message += "\nNT Sanctioned Psykers proudly confirm reports that nobody died this shift!"
if(news_message)
send2otherserver(news_source, news_message,"News_Report")
+63
View File
@@ -0,0 +1,63 @@
/datum/component/activity
var/activity_level = 0
var/not_moved_counter = 0
var/list/historical_activity_levels = list()
/datum/component/activity/Initialize()
if(!isliving(parent))
return COMPONENT_INCOMPATIBLE
var/mob/living/L = parent
RegisterSignal(L, COMSIG_LIVING_SET_AS_ATTACKER, .proc/on_set_as_attacker)
RegisterSignal(L, COMSIG_LIVING_ATTACKER_SET, .proc/on_attacker_set)
RegisterSignal(L, COMSIG_MOB_DEATH, .proc/on_death)
RegisterSignal(L, COMSIG_EXIT_AREA, .proc/on_exit_area)
RegisterSignal(L, COMSIG_LIVING_LIFE, .proc/on_life)
RegisterSignal(L, list(COMSIG_MOB_ITEM_ATTACK, COMSIG_MOB_ATTACK_RANGED, COMSIG_HUMAN_MELEE_UNARMED_ATTACK, COMSIG_MOB_ATTACK_HAND, COMSIG_MOB_THROW, COMSIG_MOVABLE_TELEPORTED, COMSIG_LIVING_GUN_PROCESS_FIRE, COMSIG_MOB_APPLY_DAMAGE), .proc/minor_activity)
/datum/component/activity/proc/log_activity()
historical_activity_levels[world.time] = activity_level
/datum/component/activity/proc/minor_activity(datum/source)
activity_level += 1
/datum/component/activity/proc/on_attacker_set(datum/source, mob/attacker)
activity_level += 10
if(attacker?.mind)
activity_level += 10
log_activity()
/datum/component/activity/proc/on_set_as_attacker(datum/source, mob/target)
activity_level += 10
if(target?.mind)
activity_level += 20
log_activity()
/datum/component/activity/proc/on_death(datum/source)
activity_level += 100 // dying means you're doing SOMETHING
log_activity()
/datum/component/activity/proc/on_exit_area(datum/source)
activity_level += 1
not_moved_counter = 0
/datum/component/activity/proc/on_life(datum/source, seconds, times_fired)
var/mob/living/L = source
if(L.stat >= UNCONSCIOUS) // can't expect the unconscious to move
return
not_moved_counter += seconds
var/should_log = FALSE
switch(not_moved_counter)
if(60 to 120)
activity_level -= 1
if(120 to 600)
activity_level -= 5
if(600 to 1200)
activity_level -= 10
should_log = TRUE
if(1200 to INFINITY)
activity_level -= 20
should_log = TRUE
activity_level = max(activity_level, 0)
if(should_log)
log_activity()
+1 -1
View File
@@ -73,7 +73,7 @@
/datum/component/butchering/proc/Butcher(mob/living/butcher, mob/living/meat)
var/meat_quality = 50 + (bonus_modifier/10) //increases through quality of butchering tool, and through if it was butchered in the kitchen or not
if(istype(get_area(butcher), /area/crew_quarters/kitchen))
if(istype(get_area(butcher), /area/service/kitchen))
meat_quality = meat_quality + 10
var/turf/T = meat.drop_location()
var/final_effectiveness = effectiveness - meat.butcher_difficulty
@@ -336,6 +336,18 @@
subcategory = CAT_TOOL
category = CAT_MISC
/datum/crafting_recipe/blackmarket_uplink
name = "Black Market Uplink"
result = /obj/item/blackmarket_uplink
time = 20
tools = list(TOOL_SCREWDRIVER, TOOL_WIRECUTTER)
reqs = list(/obj/item/stock_parts/subspace/amplifier = 1,
/obj/item/stack/cable_coil = 15,
/obj/item/radio = 1,
/obj/item/analyzer = 1)
subcategory = CAT_MISCELLANEOUS
category = CAT_MISC
/datum/crafting_recipe/heretic/codex
name = "Codex Cicatrix"
result = /obj/item/forbidden_book
@@ -16,7 +16,7 @@
/datum/crafting_recipe/strobeshield
name = "Strobe Shield"
result = /obj/item/assembly/flash/shield
result = /obj/item/shield/riot/flash
reqs = list(/obj/item/wallframe/flasher = 1,
/obj/item/assembly/flash/handheld = 1,
/obj/item/shield/riot = 1)
+2 -2
View File
@@ -56,10 +56,10 @@
detonate()
/datum/component/explodable/proc/on_equip(datum/source, mob/equipper, slot)
RegisterSignal(equipper, COMSIG_MOB_APPLY_DAMGE, .proc/explodable_attack_zone, TRUE)
RegisterSignal(equipper, COMSIG_MOB_APPLY_DAMAGE, .proc/explodable_attack_zone, TRUE)
/datum/component/explodable/proc/on_drop(datum/source, mob/user)
UnregisterSignal(user, COMSIG_MOB_APPLY_DAMGE)
UnregisterSignal(user, COMSIG_MOB_APPLY_DAMAGE)
/// Checks if we're hitting the zone this component is covering
/datum/component/explodable/proc/is_hitting_zone(def_zone)
+6
View File
@@ -33,6 +33,8 @@
RegisterSignal(parent, COMSIG_LIVING_REVIVE, .proc/on_revive)
RegisterSignal(parent, COMSIG_MOB_HUD_CREATED, .proc/modify_hud)
RegisterSignal(parent, COMSIG_MOB_DEATH, .proc/stop_processing)
RegisterSignal(parent, COMSIG_VOID_MASK_ACT, .proc/direct_sanity_drain)
if(owner.hud_used)
modify_hud()
@@ -377,6 +379,10 @@
remove_temp_moods()
setSanity(initial(sanity))
///Causes direct drain of someone's sanity, call it with a numerical value corresponding how badly you want to hurt their sanity
/datum/component/mood/proc/direct_sanity_drain(datum/source, amount)
setSanity(sanity + amount)
#undef ECSTATIC_SANITY_PEN
#undef SLIGHT_INSANITY_PEN
#undef MINOR_INSANITY_PEN
+1 -1
View File
@@ -52,7 +52,7 @@
return
strength -= strength / hl3_release_date
if(strength <= RAD_BACKGROUND_RADIATION)
return PROCESS_KILL
qdel(src)
/datum/component/radioactive/proc/glow_loop(atom/movable/master)
@@ -97,3 +97,11 @@
. = ..()
can_hold = typecacheof(list(/obj/item/reagent_containers/glass/bottle,
/obj/item/ammo_box/a762))
/datum/component/storage/concrete/pockets/void_cloak
quickdraw = TRUE
max_items = 3
/datum/component/storage/concrete/pockets/void_cloak/Initialize()
. = ..()
var/static/list/exception_cache = typecacheof(list(/obj/item/living_heart,/obj/item/forbidden_book))
+12 -31
View File
@@ -47,18 +47,8 @@
var/display_numerical_stacking = FALSE //stack things of the same type and show as a single object with a number.
/// "legacy"/default view mode's storage "boxes"
var/obj/screen/storage/boxes/ui_boxes
/// New volumetric storage display mode's left side
var/obj/screen/storage/left/ui_left
/// New volumetric storage display mode's center 'blocks'
var/obj/screen/storage/continuous/ui_continuous
/// The close button, used in all modes. Frames right side in volumetric mode.
var/obj/screen/storage/close/ui_close
/// Associative list of list(item = screen object) for volumetric storage item screen blocks
var/list/ui_item_blocks
var/current_maxscreensize
/// Ui objects by person. mob = list(objects)
var/list/ui_by_mob = list()
var/allow_big_nesting = FALSE //allow storage objects of the same or greater size.
@@ -125,18 +115,16 @@
/datum/component/storage/Destroy()
close_all()
QDEL_NULL(ui_boxes)
QDEL_NULL(ui_close)
QDEL_NULL(ui_continuous)
QDEL_NULL(ui_left)
// DO NOT USE QDEL_LIST_ASSOC.
if(ui_item_blocks)
for(var/i in ui_item_blocks)
qdel(ui_item_blocks[i]) //qdel the screen object not the item
ui_item_blocks.Cut()
wipe_ui_objects()
LAZYCLEARLIST(is_using)
return ..()
/datum/component/storage/proc/wipe_ui_objects()
for(var/i in ui_by_mob)
var/list/objects = ui_by_mob[i]
QDEL_LIST(objects)
ui_by_mob.Cut()
/datum/component/storage/PreTransfer()
update_actions()
@@ -351,13 +339,6 @@
return master._removal_reset(thing)
/datum/component/storage/proc/_remove_and_refresh(datum/source, atom/movable/thing)
if(LAZYACCESS(ui_item_blocks, thing))
var/obj/screen/storage/volumetric_box/center/C = ui_item_blocks[thing]
for(var/i in can_see_contents()) //runtimes result if mobs can access post deletion.
var/mob/M = i
M.client?.screen -= C.on_screen_objects()
ui_item_blocks -= thing
qdel(C)
_removal_reset(thing) // THIS NEEDS TO HAPPEN AFTER SO LAYERING DOESN'T BREAK!
refresh_mob_views()
@@ -467,14 +448,14 @@
return
A.add_fingerprint(M)
/datum/component/storage/proc/user_show_to_mob(mob/M, force = FALSE, ghost = FALSE)
/datum/component/storage/proc/user_show_to_mob(mob/M, force = FALSE)
var/atom/A = parent
if(!istype(M))
return FALSE
A.add_fingerprint(M)
if(!force && (check_locked(null, M) || !M.CanReach(parent, view_only = TRUE)))
return FALSE
ui_show(M, !ghost)
ui_show(M)
/datum/component/storage/proc/mousedrop_receive(datum/source, atom/movable/O, mob/M)
if(isitem(O))
@@ -596,7 +577,7 @@
return can_be_inserted(I, silent, M)
/datum/component/storage/proc/show_to_ghost(datum/source, mob/dead/observer/M)
return user_show_to_mob(M, TRUE, TRUE)
return user_show_to_mob(M, TRUE)
/datum/component/storage/proc/signal_show_attempt(datum/source, mob/showto, force = FALSE)
return user_show_to_mob(showto, force)
+32 -53
View File
@@ -7,7 +7,7 @@
if(QDELETED(I))
continue
if(!.[I.type])
.[I.type] = new /datum/numbered_display(I, 1)
.[I.type] = new /datum/numbered_display(I, 1, src)
else
var/datum/numbered_display/ND = .[I.type]
ND.number++
@@ -20,6 +20,8 @@
. = list()
var/list/accessible_contents = accessible_items()
var/adjusted_contents = length(accessible_contents)
var/obj/screen/storage/close/ui_close
var/obj/screen/storage/boxes/ui_boxes
//Numbered contents display
var/list/datum/numbered_display/numbered_contents
@@ -60,12 +62,13 @@
for(var/obj/O in accessible_items())
if(QDELETED(O))
continue
O.mouse_opacity = MOUSE_OPACITY_OPAQUE //This is here so storage items that spawn with contents correctly have the "click around item to equip"
O.screen_loc = "[cx]:[screen_pixel_x],[cy]:[screen_pixel_y]"
var/obj/screen/storage/item_holder/D = new(null, src, O)
D.mouse_opacity = MOUSE_OPACITY_OPAQUE //This is here so storage items that spawn with contents correctly have the "click around item to equip"
D.screen_loc = "[cx]:[screen_pixel_x],[cy]:[screen_pixel_y]"
O.maptext = ""
O.layer = ABOVE_HUD_LAYER
O.plane = ABOVE_HUD_PLANE
. += O
. += D
cx++
if(cx - screen_start_x >= columns)
cx = screen_start_x
@@ -78,6 +81,9 @@
*/
/datum/component/storage/proc/orient2hud_volumetric(mob/user, maxcolumns)
. = list()
var/obj/screen/storage/left/ui_left
var/obj/screen/storage/continuous/ui_continuous
var/obj/screen/storage/close/ui_close
// Generate ui_item_blocks for missing ones and render+orient.
var/list/atom/contents = accessible_items()
@@ -128,14 +134,10 @@
var/first = TRUE
var/row = 1
LAZYINITLIST(ui_item_blocks)
for(var/i in percentage_by_item)
I = i
var/percent = percentage_by_item[I]
if(!ui_item_blocks[I])
ui_item_blocks[I] = new /obj/screen/storage/volumetric_box/center(null, src, I)
var/obj/screen/storage/volumetric_box/center/B = ui_item_blocks[I]
var/obj/screen/storage/volumetric_box/center/B = new /obj/screen/storage/volumetric_box/center(null, src, I)
var/pixels_to_use = overrun? MINIMUM_PIXELS_PER_ITEM : max(using_horizontal_pixels * percent, MINIMUM_PIXELS_PER_ITEM)
var/addrow = FALSE
if(CEILING(pixels_to_use, 1) >= FLOOR(horizontal_pixels - current_pixel - VOLUMETRIC_STORAGE_EDGE_PADDING, 1))
@@ -143,25 +145,17 @@
addrow = TRUE
// now that we have pixels_to_use, place our thing and add it to the returned list.
B.screen_loc = I.screen_loc = "[screen_start_x]:[round(current_pixel + (pixels_to_use * 0.5) + (first? 0 : VOLUMETRIC_STORAGE_ITEM_PADDING), 1)],[screen_start_y+row-1]:[screen_pixel_y]"
B.screen_loc = "[screen_start_x]:[round(current_pixel + (pixels_to_use * 0.5) + (first? 0 : VOLUMETRIC_STORAGE_ITEM_PADDING), 1)],[screen_start_y+row-1]:[screen_pixel_y]"
// add the used pixels to pixel after we place the object
current_pixel += pixels_to_use + (first? 0 : VOLUMETRIC_STORAGE_ITEM_PADDING)
first = FALSE //apply padding to everything after this
// set various things
B.set_pixel_size(pixels_to_use)
B.layer = VOLUMETRIC_STORAGE_BOX_LAYER
B.plane = VOLUMETRIC_STORAGE_BOX_PLANE
B.name = I.name
I.mouse_opacity = MOUSE_OPACITY_ICON
I.maptext = ""
I.layer = VOLUMETRIC_STORAGE_ITEM_LAYER
I.plane = VOLUMETRIC_STORAGE_ITEM_PLANE
// finally add our things.
. += B.on_screen_objects()
. += I
// go up a row if needed
if(addrow)
@@ -185,18 +179,19 @@
/**
* Shows our UI to a mob.
*/
/datum/component/storage/proc/ui_show(mob/M, set_screen_size = TRUE)
/datum/component/storage/proc/ui_show(mob/M)
if(!M.client)
return FALSE
if(ui_by_mob[M] || LAZYFIND(is_using, M))
// something went horribly wrong
// hide first
ui_hide(M)
var/list/cview = getviewsize(M.client.view)
// in tiles
var/maxallowedscreensize = cview[1]-8
if(set_screen_size)
current_maxscreensize = maxallowedscreensize
else if(current_maxscreensize)
maxallowedscreensize = current_maxscreensize
// we got screen size, register signal
RegisterSignal(M, COMSIG_MOB_CLIENT_LOGOUT, .proc/on_logout, override = TRUE)
RegisterSignal(M, COMSIG_PARENT_QDELETING, .proc/on_logout, override = TRUE)
if(M.active_storage != src)
if(M.active_storage)
M.active_storage.ui_hide(M)
@@ -204,10 +199,14 @@
LAZYOR(is_using, M)
if(!M.client?.prefs?.no_tetris_storage && volumetric_ui())
//new volumetric ui bay-style
M.client.screen |= orient2hud_volumetric(M, maxallowedscreensize)
var/list/objects = orient2hud_volumetric(M, maxallowedscreensize)
M.client.screen |= objects
ui_by_mob[M] = objects
else
//old ui
M.client.screen |= orient2hud_legacy(M, maxallowedscreensize)
var/list/objects = orient2hud_legacy(M, maxallowedscreensize)
M.client.screen |= objects
ui_by_mob[M] = objects
return TRUE
/**
@@ -236,8 +235,10 @@
/datum/component/storage/proc/ui_hide(mob/M)
if(!M.client)
return TRUE
UnregisterSignal(M, COMSIG_MOB_CLIENT_LOGOUT)
M.client.screen -= list(ui_boxes, ui_close, ui_left, ui_continuous) + get_ui_item_objects_hide(M)
UnregisterSignal(M, list(COMSIG_PARENT_QDELETING, COMSIG_MOB_CLIENT_LOGOUT))
M.client.screen -= ui_by_mob[M]
var/list/objects = ui_by_mob[M]
QDEL_LIST(objects)
if(M.active_storage == src)
M.active_storage = null
LAZYREMOVE(is_using, M)
@@ -250,48 +251,26 @@
var/atom/real_location = real_location()
return (storage_flags & STORAGE_LIMIT_VOLUME) && (length(real_location.contents) <= MAXIMUM_VOLUMETRIC_ITEMS) && !display_numerical_stacking
/**
* Gets the ui item objects to ui_hide.
*/
/datum/component/storage/proc/get_ui_item_objects_hide(mob/M)
if(!volumetric_ui() || M.client?.prefs?.no_tetris_storage)
var/atom/real_location = real_location()
return real_location.contents
else
. = list()
for(var/i in ui_item_blocks)
// get both the box and the item
. += ui_item_blocks[i]
. += i
/**
* Gets our ui_boxes, making it if it doesn't exist.
*/
/datum/component/storage/proc/get_ui_boxes()
if(!ui_boxes)
ui_boxes = new(null, src)
return ui_boxes
return new /obj/screen/storage/boxes(null, src)
/**
* Gets our ui_left, making it if it doesn't exist.
*/
/datum/component/storage/proc/get_ui_left()
if(!ui_left)
ui_left = new(null, src)
return ui_left
return new /obj/screen/storage/left(null, src)
/**
* Gets our ui_close, making it if it doesn't exist.
*/
/datum/component/storage/proc/get_ui_close()
if(!ui_close)
ui_close = new(null, src)
return ui_close
return new /obj/screen/storage/close(null, src)
/**
* Gets our ui_continuous, making it if it doesn't exist.
*/
/datum/component/storage/proc/get_ui_continuous()
if(!ui_continuous)
ui_continuous = new(null, src)
return ui_continuous
return new /obj/screen/storage/continuous(null, src)
@@ -384,7 +384,7 @@
var/temp_rate = 1
threshold_desc = list(
"Transmission 6" = "Additionally increases temperature adjustment rate and heals those who love toxins",
"Resistance 7" = "Increases healing speed.",
"Stage Speed 7" = "Increases healing speed.",
)
/datum/symptom/heal/plasma/Start(datum/disease/advance/A)
if(!..())
+3 -2
View File
@@ -329,12 +329,13 @@
uni_identity = generate_uni_identity()
unique_enzymes = generate_unique_enzymes()
/datum/dna/proc/initialize_dna(newblood_type)
/datum/dna/proc/initialize_dna(newblood_type, skip_index = FALSE)
if(newblood_type)
blood_type = newblood_type
unique_enzymes = generate_unique_enzymes()
uni_identity = generate_uni_identity()
generate_dna_blocks()
if(!skip_index) //I hate this
generate_dna_blocks()
features = random_features(species?.id, holder?.gender)
+15 -11
View File
@@ -1,22 +1,24 @@
/**
* A holder for simple behaviour that can be attached to many different types
*
* Only one element of each type is instanced during game init.
* Otherwise acts basically like a lightweight component.
*/
* A holder for simple behaviour that can be attached to many different types
*
* Only one element of each type is instanced during game init.
* Otherwise acts basically like a lightweight component.
*/
/datum/element
/// Option flags for element behaviour
var/element_flags = NONE
/**
* The index of the first attach argument to consider for duplicate elements
* Is only used when flags contains ELEMENT_BESPOKE
*
* Is only used when flags contains [ELEMENT_BESPOKE]
*
* This is infinity so you must explicitly set this
*/
var/id_arg_index = INFINITY
/// Activates the functionality defined by the element on the given target datum
/datum/element/proc/Attach(datum/target)
SHOULD_CALL_PARENT(1)
SHOULD_CALL_PARENT(TRUE)
if(type == /datum/element)
return ELEMENT_INCOMPATIBLE
SEND_SIGNAL(target, COMSIG_ELEMENT_ATTACH, src)
@@ -25,8 +27,10 @@
/// Deactivates the functionality defines by the element on the given datum
/datum/element/proc/Detach(datum/source, force)
SIGNAL_HANDLER
SEND_SIGNAL(source, COMSIG_ELEMENT_DETACH, src)
SHOULD_CALL_PARENT(1)
SHOULD_CALL_PARENT(TRUE)
UnregisterSignal(source, COMSIG_PARENT_QDELETING)
/datum/element/Destroy(force)
@@ -45,9 +49,9 @@
CRASH("Incompatible [arguments[1]] assigned to a [type]! args: [json_encode(args)]")
/**
* Finds the singleton for the element type given and detaches it from src
* You only need additional arguments beyond the type if you're using ELEMENT_BESPOKE
*/
* Finds the singleton for the element type given and detaches it from src
* You only need additional arguments beyond the type if you're using [ELEMENT_BESPOKE]
*/
/datum/proc/_RemoveElement(list/arguments)
var/datum/element/ele = SSdcs.GetElement(arguments)
ele.Detach(src)
+1 -1
View File
@@ -141,7 +141,7 @@
/obj/item/clothing/head/mob_holder/dropped(mob/user)
. = ..()
if(held_mob && !ismob(loc))//don't release on soft-drops
if(held_mob && !ismob(loc) && !istype(loc,/obj/item/storage))//don't release on soft-drops
release()
/obj/item/clothing/head/mob_holder/proc/release()
+75
View File
@@ -0,0 +1,75 @@
/datum/element/turf_z_transparency
var/show_bottom_level = FALSE
///This proc sets up the signals to handle updating viscontents when turfs above/below update. Handle plane and layer here too so that they don't cover other obs/turfs in Dream Maker
/datum/element/turf_z_transparency/Attach(datum/target, show_bottom_level = TRUE)
. = ..()
if(!isturf(target))
return ELEMENT_INCOMPATIBLE
var/turf/our_turf = target
src.show_bottom_level = show_bottom_level
our_turf.plane = OPENSPACE_PLANE
our_turf.layer = OPENSPACE_LAYER
RegisterSignal(target, COMSIG_TURF_MULTIZ_DEL, .proc/on_multiz_turf_del)
RegisterSignal(target, COMSIG_TURF_MULTIZ_NEW, .proc/on_multiz_turf_new)
ADD_TRAIT(our_turf, TURF_Z_TRANSPARENT_TRAIT, TURF_TRAIT)
update_multiz(our_turf, TRUE, TRUE)
/datum/element/turf_z_transparency/Detach(datum/source, force)
. = ..()
var/turf/our_turf = source
our_turf.vis_contents.len = 0
REMOVE_TRAIT(our_turf, TURF_Z_TRANSPARENT_TRAIT, TURF_TRAIT)
///Updates the viscontents or underlays below this tile.
/datum/element/turf_z_transparency/proc/update_multiz(turf/our_turf, prune_on_fail = FALSE, init = FALSE)
var/turf/below_turf = our_turf.below()
if(!below_turf)
our_turf.vis_contents.len = 0
if(!show_bottom_level(our_turf) && prune_on_fail) //If we cant show whats below, and we prune on fail, change the turf to plating as a fallback
our_turf.ChangeTurf(/turf/open/floor/plating, flags = CHANGETURF_INHERIT_AIR)
return FALSE
if(init)
our_turf.vis_contents += below_turf
if(isclosedturf(our_turf)) //Show girders below closed turfs
var/mutable_appearance/girder_underlay = mutable_appearance('icons/obj/structures.dmi', "girder", layer = TURF_LAYER-0.01)
girder_underlay.appearance_flags = RESET_ALPHA | RESET_COLOR
our_turf.underlays += girder_underlay
var/mutable_appearance/plating_underlay = mutable_appearance('icons/turf/floors.dmi', "plating", layer = TURF_LAYER-0.02)
plating_underlay = RESET_ALPHA | RESET_COLOR
our_turf.underlays += plating_underlay
return TRUE
/datum/element/turf_z_transparency/proc/on_multiz_turf_del(turf/our_turf, turf/T, dir)
SIGNAL_HANDLER
if(dir != DOWN)
return
update_multiz(our_turf)
/datum/element/turf_z_transparency/proc/on_multiz_turf_new(turf/our_turf, turf/T, dir)
SIGNAL_HANDLER
if(dir != DOWN)
return
update_multiz(our_turf)
///Called when there is no real turf below this turf
/datum/element/turf_z_transparency/proc/show_bottom_level(turf/our_turf)
if(!show_bottom_level)
return FALSE
var/turf/path = SSmapping.level_trait(our_turf.z, ZTRAIT_BASETURF) || /turf/open/space
if(!ispath(path))
path = text2path(path)
if(!ispath(path))
warning("Z-level [our_turf.z] has invalid baseturf '[SSmapping.level_trait(our_turf.z, ZTRAIT_BASETURF)]'")
path = /turf/open/space
var/mutable_appearance/underlay_appearance = mutable_appearance(initial(path.icon), initial(path.icon_state), layer = TURF_LAYER-0.02, plane = PLANE_SPACE)
underlay_appearance.appearance_flags = RESET_ALPHA | RESET_COLOR
our_turf.underlays += underlay_appearance
return TRUE
+2 -2
View File
@@ -34,13 +34,13 @@
. = ..()
UnregisterSignal(source, COMSIG_MOB_ATTACK_HAND)
/datum/element/wuv/proc/on_attack_hand(datum/source, mob/user)
/datum/element/wuv/proc/on_attack_hand(datum/source, mob/user, act_intent)
var/mob/living/L = source
if(L.stat == DEAD)
return
//we want to delay the effect to be displayed after the mob is petted, not before.
switch(user.a_intent)
switch(act_intent)
if(INTENT_HARM)
addtimer(CALLBACK(src, .proc/kick_the_dog, source, user), 1)
if(INTENT_HELP)
+2
View File
@@ -317,6 +317,8 @@ GLOBAL_LIST_EMPTY(explosions)
var/took = (REALTIMEOFDAY - started_at) / 10
SEND_GLOBAL_SIGNAL(COMSIG_GLOB_EXPLOSION,epicenter, devastation_range, heavy_impact_range, light_impact_range, took, orig_dev_range, orig_heavy_range, orig_light_range)
//You need to press the DebugGame verb to see these now....they were getting annoying and we've collected a fair bit of data. Just -test- changes to explosion code using this please so we can compare
if(GLOB.Debug2)
log_world("## DEBUG: Explosion([x0],[y0],[z0])(d[devastation_range],h[heavy_impact_range],l[light_impact_range]): Took [took] seconds.")
+27 -9
View File
@@ -5,8 +5,8 @@
// effectout: effect to show right after teleportation
// asoundin: soundfile to play before teleportation
// asoundout: soundfile to play after teleportation
// no_effects: disable the default effectin/effectout of sparks
// forceMove: if false, teleport will use Move() proc (dense objects will prevent teleportation)
// no_effects: disable the default effectin/effectout of sparks
// forced: whether or not to ignore no_teleport
/proc/do_teleport(atom/movable/teleatom, atom/destination, precision=null, forceMove = TRUE, datum/effect_system/effectin=null, datum/effect_system/effectout=null, asoundin=null, asoundout=null, no_effects=FALSE, channel=TELEPORT_CHANNEL_BLUESPACE, forced = FALSE)
// teleporting most effects just deletes them
@@ -15,7 +15,8 @@
)) - typecacheof(list(
/obj/effect/dummy/chameleon,
/obj/effect/wisp,
/obj/effect/mob_spawn
/obj/effect/mob_spawn,
/obj/effect/immovablerod,
))
if(delete_atoms[teleatom.type])
qdel(teleatom)
@@ -66,7 +67,7 @@
var/area/A = get_area(curturf)
var/area/B = get_area(destturf)
if(!forced && (HAS_TRAIT(teleatom, TRAIT_NO_TELEPORT) || A.noteleport || B.noteleport))
if(!forced && (HAS_TRAIT(teleatom, TRAIT_NO_TELEPORT) || (A.area_flags & NOTELEPORT) || (B.area_flags & NOTELEPORT)))
return FALSE
if(SEND_SIGNAL(destturf, COMSIG_ATOM_INTERCEPT_TELEPORT, channel, curturf, destturf))
@@ -99,13 +100,13 @@
/proc/tele_play_specials(atom/movable/teleatom, atom/location, datum/effect_system/effect, sound)
if (location && !isobserver(teleatom))
if (sound)
playsound(location, sound, 60, 1)
playsound(location, sound, 60, TRUE)
if (effect)
effect.attach(location)
effect.start()
// Safe location finder
/proc/find_safe_turf(zlevel, list/zlevels, extended_safety_checks = FALSE)
/proc/find_safe_turf(zlevel, list/zlevels, extended_safety_checks = FALSE, dense_atoms = TRUE)
if(!zlevels)
if (zlevel)
zlevels = list(zlevel)
@@ -122,12 +123,17 @@
if(!isfloorturf(random_location))
continue
var/turf/open/floor/F = random_location
var/area/destination_area = F.loc
if(cycle < 300 && destination_area.area_flags & NOTELEPORT)//if the area is mostly NOTELEPORT (centcom) we gotta give up on this fantasy at some point.
continue
if(!F.air)
continue
var/datum/gas_mixture/A = F.air
var/list/A_gases = A.get_gases()
var/trace_gases
for(var/id in A.get_gases())
for(var/id in A_gases)
if(id in GLOB.hardcoded_gases)
continue
trace_gases = TRUE
@@ -136,7 +142,7 @@
// Can most things breathe?
if(trace_gases)
continue
if(A.get_moles(/datum/gas/oxygen) < 16)
if(A.get_moles(/datum/gas/oxygen) >= 16)
continue
if(A.get_moles(/datum/gas/plasma))
continue
@@ -156,6 +162,16 @@
if(!L.is_safe())
continue
// Check that we're not warping onto a table or window
if(!dense_atoms)
var/density_found = FALSE
for(var/atom/movable/found_movable in F)
if(found_movable.density)
density_found = TRUE
break
if(density_found)
continue
// DING! You have passed the gauntlet, and are "probably" safe.
return F
@@ -167,9 +183,11 @@
if(T.is_transition_turf())
continue // Avoid picking these.
var/area/A = T.loc
if(!A.noteleport)
if(!(A.area_flags & NOTELEPORT))
posturfs.Add(T)
return posturfs
/proc/get_teleport_turf(turf/center, precision = 0)
return safepick(get_teleport_turfs(center, precision))
var/list/turfs = get_teleport_turfs(center, precision)
if (length(turfs))
return pick(turfs)
+9
View File
@@ -45,3 +45,12 @@
start_length = 130
end_sound = 'sound/weather/ashstorm/inside/weak_end.ogg'
volume = 30
/datum/looping_sound/void_loop
mid_sounds = list('sound/ambience/VoidsEmbrace.ogg'=1)
mid_length = 1669 // exact length of the music in ticks
volume = 100
extra_range = 30
/datum/looping_sound/void_loop/start(atom/add_thing)
. = ..()
+144
View File
@@ -0,0 +1,144 @@
/datum/map_generator/cave_generator
var/name = "Cave Generator"
///Weighted list of the types that spawns if the turf is open
var/open_turf_types = list(/turf/open/floor/plating/asteroid/airless = 1)
///Weighted list of the types that spawns if the turf is closed
var/closed_turf_types = list(/turf/closed/mineral/random = 1)
///Weighted list of mobs that can spawn in the area.
var/list/mob_spawn_list
// Weighted list of Megafauna that can spawn in the caves
var/list/megafauna_spawn_list
///Weighted list of flora that can spawn in the area.
var/list/flora_spawn_list
///Weighted list of extra features that can spawn in the area, such as geysers.
var/list/feature_spawn_list
///Base chance of spawning a mob
var/mob_spawn_chance = 6
///Base chance of spawning flora
var/flora_spawn_chance = 2
///Base chance of spawning features
var/feature_spawn_chance = 0.1
///Unique ID for this spawner
var/string_gen
///Chance of cells starting closed
var/initial_closed_chance = 45
///Amount of smoothing iterations
var/smoothing_iterations = 20
///How much neighbours does a dead cell need to become alive
var/birth_limit = 4
///How little neighbours does a alive cell need to die
var/death_limit = 3
/datum/map_generator/cave_generator/New()
. = ..()
if(!mob_spawn_list)
mob_spawn_list = list(/mob/living/simple_animal/hostile/asteroid/goldgrub = 1, /mob/living/simple_animal/hostile/asteroid/goliath = 5, /mob/living/simple_animal/hostile/asteroid/basilisk = 4, /mob/living/simple_animal/hostile/asteroid/hivelord = 3)
if(!megafauna_spawn_list)
megafauna_spawn_list = GLOB.megafauna_spawn_list
if(!flora_spawn_list)
flora_spawn_list = list(/obj/structure/flora/ash/leaf_shroom = 2 , /obj/structure/flora/ash/cap_shroom = 2 , /obj/structure/flora/ash/stem_shroom = 2 , /obj/structure/flora/ash/cacti = 1, /obj/structure/flora/ash/tall_shroom = 2)
if(!feature_spawn_list)
feature_spawn_list = list(/obj/structure/geyser/random = 1)
/datum/map_generator/cave_generator/generate_terrain(list/turfs)
. = ..()
var/start_time = REALTIMEOFDAY
string_gen = rustg_cnoise_generate("[initial_closed_chance]", "[smoothing_iterations]", "[birth_limit]", "[death_limit]", "[world.maxx]", "[world.maxy]") //Generate the raw CA data
for(var/i in turfs) //Go through all the turfs and generate them
var/turf/gen_turf = i
var/area/A = gen_turf.loc
if(!(A.area_flags & CAVES_ALLOWED))
continue
var/closed = text2num(string_gen[world.maxx * (gen_turf.y - 1) + gen_turf.x])
var/stored_flags
if(gen_turf.flags_1 & NO_RUINS_1)
stored_flags |= NO_RUINS_1
var/turf/new_turf = pickweight(closed ? closed_turf_types : open_turf_types)
new_turf = gen_turf.ChangeTurf(new_turf, initial(new_turf.baseturfs), CHANGETURF_DEFER_CHANGE)
new_turf.flags_1 |= stored_flags
if(!closed)//Open turfs have some special behavior related to spawning flora and mobs.
var/turf/open/new_open_turf = new_turf
///Spawning isn't done in procs to save on overhead on the 60k turfs we're going through.
//FLORA SPAWNING HERE
var/atom/spawned_flora
if(flora_spawn_list && prob(flora_spawn_chance))
var/can_spawn = TRUE
if(!(A.area_flags & FLORA_ALLOWED))
can_spawn = FALSE
if(can_spawn)
spawned_flora = pickweight(flora_spawn_list)
spawned_flora = new spawned_flora(new_open_turf)
//FEATURE SPAWNING HERE
var/atom/spawned_feature
if(feature_spawn_list && prob(feature_spawn_chance))
var/can_spawn = TRUE
if(!(A.area_flags & FLORA_ALLOWED)) //checks the same flag because lol dunno
can_spawn = FALSE
var/atom/picked_feature = pickweight(feature_spawn_list)
for(var/obj/structure/F in range(7, new_open_turf))
if(istype(F, picked_feature))
can_spawn = FALSE
if(can_spawn)
spawned_feature = new picked_feature(new_open_turf)
//MOB SPAWNING HERE
if(mob_spawn_list && !spawned_flora && !spawned_feature && prob(mob_spawn_chance))
var/can_spawn = TRUE
if(!(A.area_flags & MOB_SPAWN_ALLOWED))
can_spawn = FALSE
var/atom/picked_mob = pickweight(mob_spawn_list)
if(picked_mob == SPAWN_MEGAFAUNA) //
if((A.area_flags & MEGAFAUNA_SPAWN_ALLOWED) && megafauna_spawn_list?.len) //this is danger. it's boss time.
picked_mob = pickweight(megafauna_spawn_list)
else //this is not danger, don't spawn a boss, spawn something else
picked_mob = pickweight(mob_spawn_list - SPAWN_MEGAFAUNA) //What if we used 100% of the brain...and did something (slightly) less shit than a while loop?
for(var/thing in urange(12, new_open_turf)) //prevents mob clumps
if(!ishostile(thing) && !istype(thing, /obj/structure/spawner))
continue
if((ispath(picked_mob, /mob/living/simple_animal/hostile/megafauna) || ismegafauna(thing)) && get_dist(new_open_turf, thing) <= 7)
can_spawn = FALSE //if there's a megafauna within standard view don't spawn anything at all
break
if(ispath(picked_mob, /mob/living/simple_animal/hostile/asteroid) || istype(thing, /mob/living/simple_animal/hostile/asteroid))
can_spawn = FALSE //if the random is a standard mob, avoid spawning if there's another one within 12 tiles
break
if((ispath(picked_mob, /obj/structure/spawner/lavaland) || istype(thing, /obj/structure/spawner/lavaland)) && get_dist(new_open_turf, thing) <= 2)
can_spawn = FALSE //prevents tendrils spawning in each other's collapse range
break
if(can_spawn)
if(ispath(picked_mob, /mob/living/simple_animal/hostile/megafauna/bubblegum)) //there can be only one bubblegum, so don't waste spawns on it
megafauna_spawn_list.Remove(picked_mob)
new picked_mob(new_open_turf)
CHECK_TICK
var/message = "[name] finished in [(REALTIMEOFDAY - start_time)/10]s!"
to_chat(world, "<span class='boldannounce'>[message]</span>")
log_world(message)
@@ -0,0 +1,28 @@
/datum/map_generator/cave_generator/icemoon
open_turf_types = list(/turf/open/floor/plating/asteroid/snow/icemoon = 19, /turf/open/floor/plating/ice/icemoon = 1)
closed_turf_types = list(/turf/closed/mineral/random/snow = 1)
mob_spawn_list = list(/mob/living/simple_animal/hostile/asteroid/wolf = 50, /obj/structure/spawner/ice_moon = 3, \
/mob/living/simple_animal/hostile/asteroid/polarbear = 30, /obj/structure/spawner/ice_moon/polarbear = 3, \
/mob/living/simple_animal/hostile/asteroid/hivelord/legion/snow = 50, /mob/living/simple_animal/hostile/asteroid/goldgrub = 10, \
/mob/living/simple_animal/hostile/asteroid/lobstrosity = 15)
flora_spawn_list = list(/obj/structure/flora/tree/pine = 2, /obj/structure/flora/rock/icy = 2, /obj/structure/flora/rock/pile/icy = 2, /obj/structure/flora/grass/both = 6, /obj/structure/flora/ash = 2)
feature_spawn_list = list(/obj/structure/geyser/random = 1)
/datum/map_generator/cave_generator/icemoon/surface
flora_spawn_chance = 4
mob_spawn_list = null
initial_closed_chance = 53
birth_limit = 5
death_limit = 4
smoothing_iterations = 10
/datum/map_generator/cave_generator/icemoon/deep
closed_turf_types = list(/turf/closed/mineral/random/snow/underground = 1)
mob_spawn_list = list(/mob/living/simple_animal/hostile/asteroid/ice_demon = 50, /obj/structure/spawner/ice_moon/demonic_portal = 3, \
/mob/living/simple_animal/hostile/asteroid/ice_whelp = 30, /obj/structure/spawner/ice_moon/demonic_portal/ice_whelp = 3, \
/mob/living/simple_animal/hostile/asteroid/hivelord/legion/snow = 50, /obj/structure/spawner/ice_moon/demonic_portal/snowlegion = 3, \
SPAWN_MEGAFAUNA = 2)
megafauna_spawn_list = list(/mob/living/simple_animal/hostile/megafauna/colossus = 1)
flora_spawn_list = list(/obj/structure/flora/rock/icy = 6, /obj/structure/flora/rock/pile/icy = 6, /obj/structure/flora/ash = 1)
@@ -0,0 +1,16 @@
/datum/map_generator/cave_generator/lavaland
open_turf_types = list(/turf/open/floor/plating/asteroid/basalt/lava_land_surface = 1)
closed_turf_types = list(/turf/closed/mineral/random/volcanic = 1)
mob_spawn_list = list(/mob/living/simple_animal/hostile/asteroid/goliath/beast/random = 50, /obj/structure/spawner/lavaland/goliath = 3, \
/mob/living/simple_animal/hostile/asteroid/basilisk/watcher/random = 40, /obj/structure/spawner/lavaland = 2, \
/mob/living/simple_animal/hostile/asteroid/hivelord/legion/random = 30, /obj/structure/spawner/lavaland/legion = 3, \
SPAWN_MEGAFAUNA = 4, /mob/living/simple_animal/hostile/asteroid/goldgrub = 10)
flora_spawn_list = list(/obj/structure/flora/ash/leaf_shroom = 2 , /obj/structure/flora/ash/cap_shroom = 2 , /obj/structure/flora/ash/stem_shroom = 2 , /obj/structure/flora/ash/cacti = 1, /obj/structure/flora/ash/tall_shroom = 2)
feature_spawn_list = list(/obj/structure/geyser/random = 1)
initial_closed_chance = 45
smoothing_iterations = 50
birth_limit = 4
death_limit = 3
+91
View File
@@ -0,0 +1,91 @@
//the random offset applied to square coordinates, causes intermingling at biome borders
#define BIOME_RANDOM_SQUARE_DRIFT 2
/datum/map_generator/jungle_generator
///2D list of all biomes based on heat and humidity combos.
var/list/possible_biomes = list(
BIOME_LOW_HEAT = list(
BIOME_LOW_HUMIDITY = /datum/biome/plains,
BIOME_LOWMEDIUM_HUMIDITY = /datum/biome/mudlands,
BIOME_HIGHMEDIUM_HUMIDITY = /datum/biome/mudlands,
BIOME_HIGH_HUMIDITY = /datum/biome/water
),
BIOME_LOWMEDIUM_HEAT = list(
BIOME_LOW_HUMIDITY = /datum/biome/plains,
BIOME_LOWMEDIUM_HUMIDITY = /datum/biome/jungle,
BIOME_HIGHMEDIUM_HUMIDITY = /datum/biome/jungle,
BIOME_HIGH_HUMIDITY = /datum/biome/mudlands
),
BIOME_HIGHMEDIUM_HEAT = list(
BIOME_LOW_HUMIDITY = /datum/biome/plains,
BIOME_LOWMEDIUM_HUMIDITY = /datum/biome/plains,
BIOME_HIGHMEDIUM_HUMIDITY = /datum/biome/jungle/deep,
BIOME_HIGH_HUMIDITY = /datum/biome/jungle
),
BIOME_HIGH_HEAT = list(
BIOME_LOW_HUMIDITY = /datum/biome/wasteland,
BIOME_LOWMEDIUM_HUMIDITY = /datum/biome/plains,
BIOME_HIGHMEDIUM_HUMIDITY = /datum/biome/jungle,
BIOME_HIGH_HUMIDITY = /datum/biome/jungle/deep
)
)
///Used to select "zoom" level into the perlin noise, higher numbers result in slower transitions
var/perlin_zoom = 65
///Seeds the rust-g perlin noise with a random number.
/datum/map_generator/jungle_generator/generate_terrain(list/turfs)
. = ..()
var/height_seed = rand(0, 50000)
var/humidity_seed = rand(0, 50000)
var/heat_seed = rand(0, 50000)
for(var/t in turfs) //Go through all the turfs and generate them
var/turf/gen_turf = t
var/drift_x = (gen_turf.x + rand(-BIOME_RANDOM_SQUARE_DRIFT, BIOME_RANDOM_SQUARE_DRIFT)) / perlin_zoom
var/drift_y = (gen_turf.y + rand(-BIOME_RANDOM_SQUARE_DRIFT, BIOME_RANDOM_SQUARE_DRIFT)) / perlin_zoom
var/height = text2num(rustg_noise_get_at_coordinates("[height_seed]", "[drift_x]", "[drift_y]"))
var/datum/biome/selected_biome
if(height <= 0.85) //If height is less than 0.85, we generate biomes based on the heat and humidity of the area.
var/humidity = text2num(rustg_noise_get_at_coordinates("[humidity_seed]", "[drift_x]", "[drift_y]"))
var/heat = text2num(rustg_noise_get_at_coordinates("[heat_seed]", "[drift_x]", "[drift_y]"))
var/heat_level //Type of heat zone we're in LOW-MEDIUM-HIGH
var/humidity_level //Type of humidity zone we're in LOW-MEDIUM-HIGH
switch(heat)
if(0 to 0.25)
heat_level = BIOME_LOW_HEAT
if(0.25 to 0.5)
heat_level = BIOME_LOWMEDIUM_HEAT
if(0.5 to 0.75)
heat_level = BIOME_HIGHMEDIUM_HEAT
if(0.75 to 1)
heat_level = BIOME_HIGH_HEAT
switch(humidity)
if(0 to 0.25)
humidity_level = BIOME_LOW_HUMIDITY
if(0.25 to 0.5)
humidity_level = BIOME_LOWMEDIUM_HUMIDITY
if(0.5 to 0.75)
humidity_level = BIOME_HIGHMEDIUM_HUMIDITY
if(0.75 to 1)
humidity_level = BIOME_HIGH_HUMIDITY
selected_biome = possible_biomes[heat_level][humidity_level]
else //Over 0.85; It's a mountain
selected_biome = /datum/biome/mountain
selected_biome = SSmapping.biomes[selected_biome] //Get the instance of this biome from SSmapping
selected_biome.generate_turf(gen_turf)
CHECK_TICK
/turf/open/genturf
name = "ungenerated turf"
desc = "If you see this, and you're not a ghost, yell at coders"
icon = 'icons/turf/debug.dmi'
icon_state = "genturf"
/area/mine/planetgeneration
name = "planet generation area"
dynamic_lighting = DYNAMIC_LIGHTING_DISABLED
map_generator = /datum/map_generator/jungle_generator
+6
View File
@@ -0,0 +1,6 @@
///This type is responsible for any map generation behavior that is done in areas, override this to allow for area-specific map generation. This generation is ran by areas in initialize.
/datum/map_generator
///This proc will be ran by areas on Initialize, and provides the areas turfs as argument to allow for generation.
/datum/map_generator/proc/generate_terrain(list/turfs)
return
+53
View File
@@ -0,0 +1,53 @@
///This datum handles the transitioning from a turf to a specific biome, and handles spawning decorative structures and mobs.
/datum/biome
///Type of turf this biome creates
var/turf_type
///Chance of having a structure from the flora types list spawn
var/flora_density = 0
///Chance of having a mob from the fauna types list spawn
var/fauna_density = 0
///list of type paths of objects that can be spawned when the turf spawns flora
var/list/flora_types = list(/obj/structure/flora/grass/jungle)
///list of type paths of mobs that can be spawned when the turf spawns fauna
var/list/fauna_types = list()
///This proc handles the creation of a turf of a specific biome type
/datum/biome/proc/generate_turf(turf/gen_turf)
gen_turf.ChangeTurf(turf_type, null, CHANGETURF_DEFER_CHANGE)
if(length(fauna_types) && prob(fauna_density))
var/mob/fauna = pick(fauna_types)
new fauna(gen_turf)
if(length(flora_types) && prob(flora_density))
var/obj/structure/flora = pick(flora_types)
new flora(gen_turf)
/datum/biome/mudlands
// turf_type = /turf/open/floor/plating/dirt/jungle/dark
turf_type = /turf/open/floor/plating/dirt/jungle
flora_types = list(/obj/structure/flora/grass/jungle,/obj/structure/flora/grass/jungle/b, /obj/structure/flora/rock/jungle, /obj/structure/flora/rock/pile/largejungle)
flora_density = 3
/datum/biome/plains
// turf_type = /turf/open/floor/plating/grass/jungle
turf_type = /turf/open/floor/grass
flora_types = list(/obj/structure/flora/grass/jungle,/obj/structure/flora/grass/jungle/b, /obj/structure/flora/tree/jungle, /obj/structure/flora/rock/jungle, /obj/structure/flora/junglebush, /obj/structure/flora/junglebush/b, /obj/structure/flora/junglebush/c, /obj/structure/flora/junglebush/large, /obj/structure/flora/rock/pile/largejungle)
flora_density = 15
/datum/biome/jungle
// turf_type = /turf/open/floor/plating/grass/jungle
turf_type = /turf/open/floor/grass
flora_types = list(/obj/structure/flora/grass/jungle,/obj/structure/flora/grass/jungle/b, /obj/structure/flora/tree/jungle, /obj/structure/flora/rock/jungle, /obj/structure/flora/junglebush, /obj/structure/flora/junglebush/b, /obj/structure/flora/junglebush/c, /obj/structure/flora/junglebush/large, /obj/structure/flora/rock/pile/largejungle)
flora_density = 40
/datum/biome/jungle/deep
flora_density = 65
/datum/biome/wasteland
// turf_type = /turf/open/floor/plating/dirt/jungle/wasteland
turf_type = /turf/open/floor/plating/dirt/jungle
/datum/biome/water
turf_type = /turf/open/water/jungle
/datum/biome/mountain
turf_type = /turf/closed/mineral/random //jungle
+3 -2
View File
@@ -223,9 +223,10 @@
///Subtype of CQC. Only used for the chef.
/datum/martial_art/cqc/under_siege
name = "Close Quarters Cooking"
var/list/valid_areas = list(/area/service/kitchen)
///Prevents use if the cook is not in the kitchen.
/datum/martial_art/cqc/under_siege/can_use(mob/living/carbon/human/H) //this is used to make chef CQC only work in kitchen
if(!istype(get_area(H), /area/crew_quarters/kitchen))
/datum/martial_art/cqc/under_siege/can_use(mob/living/owner) //this is used to make chef CQC only work in kitchen
if(!is_type_in_list(get_area(owner), valid_areas))
return FALSE
return ..()
+2 -1
View File
@@ -52,7 +52,7 @@ Unless you know what you're doing, only use the first three numbers. They're in
name = "diamond"
desc = "Highly pressurized carbon"
color = list(48/255, 272/255, 301/255,0, 0,0,0,0, 0,0,0,0, 0,0,0,1, 0,0,0,0)
strength_modifier = 1.1
strength_modifier = 1.2
alpha = 132
categories = list(MAT_CATEGORY_ORE = TRUE, MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE)
sheet_type = /obj/item/stack/sheet/mineral/diamond
@@ -85,6 +85,7 @@ Unless you know what you're doing, only use the first three numbers. They're in
name = "plasma"
desc = "Isn't plasma a state of matter? Oh whatever."
color = list(298/255, 46/255, 352/255,0, 0,0,0,0, 0,0,0,0, 0,0,0,1, 0,0,0,0)
strength_modifier = 0.7
categories = list(MAT_CATEGORY_ORE = TRUE, MAT_CATEGORY_RIGID = TRUE, MAT_CATEGORY_BASE_RECIPES = TRUE)
sheet_type = /obj/item/stack/sheet/mineral/plasma
value_per_unit = 0.1
+7 -8
View File
@@ -129,7 +129,7 @@
/datum/mutation/human/proc/get_spans()
return list()
/mob/living/carbon/proc/update_mutations_overlay()
/mob/living/proc/update_mutations_overlay()
return
/mob/living/carbon/human/update_mutations_overlay()
@@ -142,13 +142,12 @@
if(overlays_standing[CM.layer_used])
mut_overlay = overlays_standing[CM.layer_used]
var/mutable_appearance/V = CM.get_visual_indicator()
if(!mut_overlay.Find(V)) //either we lack the visual indicator or we have the wrong one
remove_overlay(CM.layer_used)
for(var/mutable_appearance/MA in CM.visual_indicators[CM.type])
mut_overlay.Remove(MA)
mut_overlay |= V
overlays_standing[CM.layer_used] = mut_overlay
apply_overlay(CM.layer_used)
remove_overlay(CM.layer_used) //trying to find its existence defeats the point because if cut_overlays is called it doesn't bother reloading it.
for(var/mutable_appearance/MA in CM.visual_indicators[CM.type])
mut_overlay.Remove(MA)
mut_overlay |= V
overlays_standing[CM.layer_used] = mut_overlay
apply_overlay(CM.layer_used)
/datum/mutation/human/proc/modify() //called when a genome is applied so we can properly update some stats without having to remove and reapply the mutation from someone
if(modified || !power || !owner)
+2 -2
View File
@@ -283,7 +283,7 @@
desc = "Allows a creature to voluntary discard a random appendage."
quality = POSITIVE
text_gain_indication = "<span class='notice'>Your joints feel loose.</span>"
instability = 30
instability = 20
power = /obj/effect/proc_holder/spell/self/self_amputation
energy_coeff = 1
@@ -316,7 +316,7 @@
return
var/obj/item/bodypart/BP = pick(parts)
BP.dismember()
BP.dismember(harmless=TRUE)
//spider webs
/datum/mutation/human/webbing
+1 -1
View File
@@ -261,7 +261,7 @@
desc = "The user's chemical balance is more robust."
quality = POSITIVE
text_gain_indication = "<span class='notice'>You feel stimmed.</span>"
difficulty = 16
difficulty = 18
/datum/mutation/human/paranoia
name = "Paranoia"
+4
View File
@@ -30,3 +30,7 @@
/datum/generecipe/hulk
required = "/datum/mutation/human/strong; /datum/mutation/human/radioactive"
result = HULK
/datum/generecipe/thermal
required = "/datum/mutation/human/nearsight; /datum/mutation/human/stimmed"
result = THERMAL
+1 -1
View File
@@ -1,6 +1,6 @@
/datum/mutation/human/radioactive
name = "Radioactivity"
desc = "A volatile mutation that causes the host to sent out deadly beta radiation. This affects both the hosts and their surroundings."
desc = "A volatile mutation that causes the host to send out deadly beta radiation. This affects both the hosts and their surroundings."
quality = NEGATIVE
text_gain_indication = "<span class='warning'>You can feel it in your bones!</span>"
time_coeff = 5
+3 -2
View File
@@ -42,7 +42,8 @@
difficulty = 18
text_gain_indication = "<span class='notice'>You can see the heat rising off of your skin...</span>"
time_coeff = 2
instability = 25
instability = 40
locked = TRUE
var/visionflag = TRAIT_THERMAL_VISION
/datum/mutation/human/thermal/on_acquiring(mob/living/carbon/human/owner)
@@ -63,7 +64,7 @@
name = "X Ray Vision"
desc = "A strange genome that allows the user to see between the spaces of walls." //actual x-ray would mean you'd constantly be blasting rads, wich might be fun for later //hmb
text_gain_indication = "<span class='notice'>The walls suddenly disappear!</span>"
instability = 35
instability = 50
locked = TRUE
visionflag = TRAIT_XRAY_VISION
+2 -2
View File
@@ -1,7 +1,7 @@
//Cold Resistance gives your entire body an orange halo, and makes you immune to the effects of vacuum and cold.
/datum/mutation/human/space_adaptation
name = "Space Adaptation"
desc = "A strange mutation that renders the host immune to the vacuum if space. Will still need an oxygen supply."
desc = "A strange mutation that renders the host immune to the vacuum of space. Will still need an oxygen supply."
quality = POSITIVE
difficulty = 16
text_gain_indication = "<span class='notice'>Your body feels warm!</span>"
@@ -11,7 +11,7 @@
/datum/mutation/human/space_adaptation/New(class_ = MUT_OTHER, timer, datum/mutation/human/copymut)
..()
if(!(type in visual_indicators))
visual_indicators[type] = list(mutable_appearance('icons/effects/genetics.dmi', "fire", -MUTATIONS_LAYER))
visual_indicators[type] = list(mutable_appearance('icons/effects/genetics.dmi', "space_adapt", -MUTATIONS_LAYER))
/datum/mutation/human/space_adaptation/get_visual_indicator()
return visual_indicators[type][1]
+2 -2
View File
@@ -3,8 +3,8 @@
var/obj/item/sample_object
var/number
/datum/numbered_display/New(obj/item/sample, _number = 1)
/datum/numbered_display/New(obj/item/sample, _number = 1, datum/component/storage/parent)
if(!istype(sample))
qdel(src)
sample_object = sample
sample_object = new /obj/screen/storage/item_holder(null, parent, sample)
number = _number
+294 -57
View File
@@ -1,71 +1,185 @@
/**
* # Outfit datums
*
* This is a clean system of applying outfits to mobs, if you need to equip someone in a uniform
* this is the way to do it cleanly and properly.
*
* You can also specify an outfit datum on a job to have it auto equipped to the mob on join
*
* /mob/living/carbon/human/proc/equipOutfit(outfit) is the mob level proc to equip an outfit
* and you pass it the relevant datum outfit
*
* outfits can also be saved as json blobs downloadable by a client and then can be uploaded
* by that user to recreate the outfit, this is used by admins to allow for custom event outfits
* that can be restored at a later date
*/
/datum/outfit
///Name of the outfit (shows up in the equip admin verb)
var/name = "Naked"
var/uniform = null
var/suit = null
var/toggle_helmet = TRUE
var/back = null
var/belt = null
var/gloves = null
var/shoes = null
var/head = null
var/mask = null
var/neck = null
var/ears = null
var/glasses = null
/// Type path of item to go in the idcard slot
var/id = null
var/l_pocket = null
var/r_pocket = null
/// Type path of item to go in uniform slot
var/uniform = null
/// Type path of item to go in suit slot
var/suit = null
/**
* Type path of item to go in suit storage slot
*
* (make sure it's valid for that suit)
*/
var/suit_store = null
var/r_hand = null
/// Type path of item to go in back slot
var/back = null
/**
* list of items that should go in the backpack of the user
*
* Format of this list should be: list(path=count,otherpath=count)
*/
var/list/backpack_contents = null
/// Type path of item to go in belt slot
var/belt = null
/// Type path of item to go in ears slot
var/ears = null
/// Type path of item to go in the glasses slot
var/glasses = null
/// Type path of item to go in gloves slot
var/gloves = null
/// Type path of item to go in head slot
var/head = null
/// Type path of item to go in mask slot
var/mask = null
/// Type path of item to go in neck slot
var/neck = null
/// Type path of item to go in shoes slot
var/shoes = null
/// Type path of item for left pocket slot
var/l_pocket = null
/// Type path of item for right pocket slot
var/r_pocket = null
///Type path of item to go in the right hand
var/l_hand = null
var/internals_slot = null //ID of slot containing a gas tank
var/list/backpack_contents = null // In the list(path=count,otherpath=count) format
var/box // Internals box. Will be inserted at the start of backpack_contents
var/list/implants = null
//Type path of item to go in left hand
var/r_hand = null
/// Any clothing accessory item
var/accessory = null
var/can_be_admin_equipped = TRUE // Set to FALSE if your outfit requires runtime parameters
var/list/chameleon_extras //extra types for chameleon outfit changes, mostly guns
/// Internals box. Will be inserted at the start of backpack_contents
var/box
/**
* extra types for chameleon outfit changes, mostly guns
*
* Format of this list is (typepath, typepath, typepath)
*
* These are all added and returns in the list for get_chamelon_diguise_info proc
*/
var/list/chameleon_extras
/**
* Any implants the mob should start implanted with
*
* Format of this list is (typepath, typepath, typepath)
*/
var/list/implants = null
///ID of the slot containing a gas tank
var/internals_slot = null
/// Should the toggle helmet proc be called on the helmet during equip
var/toggle_helmet = TRUE
/// Any undershirt. While on humans it is a string, here we use paths to stay consistent with the rest of the equips.
var/datum/sprite_accessory/undershirt = null
/**
* Called at the start of the equip proc
*
* Override to change the value of the slots depending on client prefs, species and
* other such sources of change
*
* Extra Arguments
* * visualsOnly true if this is only for display (in the character setup screen)
*
* If visualsOnly is true, you can omit any work that doesn't visually appear on the character sprite
*/
/datum/outfit/proc/pre_equip(mob/living/carbon/human/H, visualsOnly = FALSE, client/preference_source)
//to be overridden for customization depending on client prefs,species etc
return
/**
* Called after the equip proc has finished
*
* All items are on the mob at this point, use this proc to toggle internals
* fiddle with id bindings and accesses etc
*
* Extra Arguments
* * visualsOnly true if this is only for display (in the character setup screen)
*
* If visualsOnly is true, you can omit any work that doesn't visually appear on the character sprite
*/
/datum/outfit/proc/post_equip(mob/living/carbon/human/H, visualsOnly = FALSE, client/preference_source)
//to be overridden for toggling internals, id binding, access etc
return
/**
* Equips all defined types and paths to the mob passed in
*
* Extra Arguments
* * visualsOnly true if this is only for display (in the character setup screen)
*
* If visualsOnly is true, you can omit any work that doesn't visually appear on the character sprite
*/
/datum/outfit/proc/equip(mob/living/carbon/human/H, visualsOnly = FALSE, client/preference_source)
pre_equip(H, visualsOnly, preference_source)
//Start with uniform,suit,backpack for additional slots
if(uniform)
H.equip_to_slot_or_del(new uniform(H),SLOT_W_UNIFORM)
H.equip_to_slot_or_del(new uniform(H), SLOT_W_UNIFORM, TRUE)
if(suit)
H.equip_to_slot_or_del(new suit(H),SLOT_WEAR_SUIT)
H.equip_to_slot_or_del(new suit(H), SLOT_WEAR_SUIT, TRUE)
if(back)
H.equip_to_slot_or_del(new back(H),SLOT_BACK)
H.equip_to_slot_or_del(new back(H), SLOT_BACK, TRUE)
if(belt)
H.equip_to_slot_or_del(new belt(H),SLOT_BELT)
H.equip_to_slot_or_del(new belt(H), SLOT_BELT, TRUE)
if(gloves)
H.equip_to_slot_or_del(new gloves(H),SLOT_GLOVES)
H.equip_to_slot_or_del(new gloves(H), SLOT_GLOVES, TRUE)
if(shoes)
H.equip_to_slot_or_del(new shoes(H),SLOT_SHOES)
H.equip_to_slot_or_del(new shoes(H), SLOT_SHOES, TRUE)
if(head)
H.equip_to_slot_or_del(new head(H),SLOT_HEAD)
H.equip_to_slot_or_del(new head(H), SLOT_HEAD, TRUE)
if(mask)
H.equip_to_slot_or_del(new mask(H),SLOT_WEAR_MASK)
H.equip_to_slot_or_del(new mask(H), SLOT_WEAR_MASK, TRUE)
if(neck)
H.equip_to_slot_or_del(new neck(H),SLOT_NECK)
H.equip_to_slot_or_del(new neck(H), SLOT_NECK, TRUE)
if(ears)
H.equip_to_slot_or_del(new ears(H),SLOT_EARS)
H.equip_to_slot_or_del(new ears(H), SLOT_EARS, TRUE)
if(glasses)
H.equip_to_slot_or_del(new glasses(H),SLOT_GLASSES)
H.equip_to_slot_or_del(new glasses(H), SLOT_GLASSES, TRUE)
if(id)
H.equip_to_slot_or_del(new id(H),SLOT_WEAR_ID)
H.equip_to_slot_or_del(new id(H), SLOT_WEAR_ID, TRUE)
if(suit_store)
H.equip_to_slot_or_del(new suit_store(H),SLOT_S_STORE)
H.equip_to_slot_or_del(new suit_store(H), SLOT_S_STORE, TRUE)
if(undershirt)
H.undershirt = initial(undershirt.name)
if(accessory)
var/obj/item/clothing/under/U = H.w_uniform
@@ -81,9 +195,9 @@
if(!visualsOnly) // Items in pockets or backpack don't show up on mob's icon.
if(l_pocket)
H.equip_to_slot_or_del(new l_pocket(H),SLOT_L_STORE)
H.equip_to_slot_or_del(new l_pocket(H), SLOT_L_STORE, TRUE)
if(r_pocket)
H.equip_to_slot_or_del(new r_pocket(H),SLOT_R_STORE)
H.equip_to_slot_or_del(new r_pocket(H), SLOT_R_STORE, TRUE)
if(box)
if(!backpack_contents)
@@ -97,7 +211,7 @@
if(!isnum(number))//Default to 1
number = 1
for(var/i in 1 to number)
H.equip_to_slot_or_del(new path(H),SLOT_IN_BACKPACK)
H.equip_to_slot_or_del(new path(H), SLOT_IN_BACKPACK, TRUE)
if(!H.head && toggle_helmet && istype(H.wear_suit, /obj/item/clothing/suit/space/hardsuit))
var/obj/item/clothing/suit/space/hardsuit/HS = H.wear_suit
@@ -112,55 +226,178 @@
H.update_action_buttons_icon()
if(implants)
for(var/implant_type in implants)
var/obj/item/implant/I = new implant_type
var/obj/item/implant/I = new implant_type(H)
I.implant(H, null, TRUE)
H.update_body()
return TRUE
/**
* Apply a fingerprint from the passed in human to all items in the outfit
*
* Used for forensics setup when the mob is first equipped at roundstart
* essentially calls add_fingerprint to every defined item on the human
*
*/
/datum/outfit/proc/apply_fingerprints(mob/living/carbon/human/H)
if(!istype(H))
return
if(H.back)
H.back.add_fingerprint(H,1) //The 1 sets a flag to ignore gloves
H.back.add_fingerprint(H, ignoregloves = TRUE)
for(var/obj/item/I in H.back.contents)
I.add_fingerprint(H,1)
I.add_fingerprint(H, ignoregloves = TRUE)
if(H.wear_id)
H.wear_id.add_fingerprint(H,1)
H.wear_id.add_fingerprint(H, ignoregloves = TRUE)
if(H.w_uniform)
H.w_uniform.add_fingerprint(H,1)
H.w_uniform.add_fingerprint(H, ignoregloves = TRUE)
if(H.wear_suit)
H.wear_suit.add_fingerprint(H,1)
H.wear_suit.add_fingerprint(H, ignoregloves = TRUE)
if(H.wear_mask)
H.wear_mask.add_fingerprint(H,1)
H.wear_mask.add_fingerprint(H, ignoregloves = TRUE)
if(H.wear_neck)
H.wear_neck.add_fingerprint(H,1)
H.wear_neck.add_fingerprint(H, ignoregloves = TRUE)
if(H.head)
H.head.add_fingerprint(H,1)
H.head.add_fingerprint(H, ignoregloves = TRUE)
if(H.shoes)
H.shoes.add_fingerprint(H,1)
H.shoes.add_fingerprint(H, ignoregloves = TRUE)
if(H.gloves)
H.gloves.add_fingerprint(H,1)
H.gloves.add_fingerprint(H, ignoregloves = TRUE)
if(H.ears)
H.ears.add_fingerprint(H,1)
H.ears.add_fingerprint(H, ignoregloves = TRUE)
if(H.glasses)
H.glasses.add_fingerprint(H,1)
H.glasses.add_fingerprint(H, ignoregloves = TRUE)
if(H.belt)
H.belt.add_fingerprint(H,1)
H.belt.add_fingerprint(H, ignoregloves = TRUE)
for(var/obj/item/I in H.belt.contents)
I.add_fingerprint(H,1)
I.add_fingerprint(H, ignoregloves = TRUE)
if(H.s_store)
H.s_store.add_fingerprint(H,1)
H.s_store.add_fingerprint(H, ignoregloves = TRUE)
if(H.l_store)
H.l_store.add_fingerprint(H,1)
H.l_store.add_fingerprint(H, ignoregloves = TRUE)
if(H.r_store)
H.r_store.add_fingerprint(H,1)
H.r_store.add_fingerprint(H, ignoregloves = TRUE)
for(var/obj/item/I in H.held_items)
I.add_fingerprint(H,1)
return 1
I.add_fingerprint(H, ignoregloves = TRUE)
return TRUE
/// Return a list of all the types that are required to disguise as this outfit type
/datum/outfit/proc/get_chameleon_disguise_info()
var/list/types = list(uniform, suit, back, belt, gloves, shoes, head, mask, neck, ears, glasses, id, l_pocket, r_pocket, suit_store, r_hand, l_hand)
types += chameleon_extras
listclearnulls(types)
return types
/// Return a json list of this outfit
/datum/outfit/proc/get_json_data()
. = list()
.["outfit_type"] = type
.["name"] = name
.["uniform"] = uniform
.["suit"] = suit
.["toggle_helmet"] = toggle_helmet
.["back"] = back
.["belt"] = belt
.["gloves"] = gloves
.["shoes"] = shoes
.["head"] = head
.["mask"] = mask
.["neck"] = neck
.["ears"] = ears
.["glasses"] = glasses
.["id"] = id
.["l_pocket"] = l_pocket
.["r_pocket"] = r_pocket
.["suit_store"] = suit_store
.["r_hand"] = r_hand
.["l_hand"] = l_hand
.["internals_slot"] = internals_slot
.["backpack_contents"] = backpack_contents
.["box"] = box
.["implants"] = implants
.["accessory"] = accessory
/// Copy most vars from another outfit to this one
/datum/outfit/proc/copy_from(datum/outfit/target)
name = target.name
uniform = target.uniform
suit = target.suit
toggle_helmet = target.toggle_helmet
back = target.back
belt = target.belt
gloves = target.gloves
shoes = target.shoes
head = target.head
mask = target.mask
neck = target.neck
ears = target.ears
glasses = target.glasses
id = target.id
l_pocket = target.l_pocket
r_pocket = target.r_pocket
suit_store = target.suit_store
r_hand = target.r_hand
l_hand = target.l_hand
internals_slot = target.internals_slot
backpack_contents = target.backpack_contents
box = target.box
implants = target.implants
accessory = target.accessory
/// Prompt the passed in mob client to download this outfit as a json blob
/datum/outfit/proc/save_to_file(mob/admin)
var/stored_data = get_json_data()
var/json = json_encode(stored_data)
//Kinda annoying but as far as i can tell you need to make actual file.
var/f = file("data/TempOutfitUpload")
fdel(f)
WRITE_FILE(f,json)
admin << ftp(f,"[name].json")
/// Create an outfit datum from a list of json data
/datum/outfit/proc/load_from(list/outfit_data)
//This could probably use more strict validation
name = outfit_data["name"]
uniform = text2path(outfit_data["uniform"])
suit = text2path(outfit_data["suit"])
toggle_helmet = outfit_data["toggle_helmet"]
back = text2path(outfit_data["back"])
belt = text2path(outfit_data["belt"])
gloves = text2path(outfit_data["gloves"])
shoes = text2path(outfit_data["shoes"])
head = text2path(outfit_data["head"])
mask = text2path(outfit_data["mask"])
neck = text2path(outfit_data["neck"])
ears = text2path(outfit_data["ears"])
glasses = text2path(outfit_data["glasses"])
id = text2path(outfit_data["id"])
l_pocket = text2path(outfit_data["l_pocket"])
r_pocket = text2path(outfit_data["r_pocket"])
suit_store = text2path(outfit_data["suit_store"])
r_hand = text2path(outfit_data["r_hand"])
l_hand = text2path(outfit_data["l_hand"])
internals_slot = outfit_data["internals_slot"]
var/list/backpack = outfit_data["backpack_contents"]
backpack_contents = list()
for(var/item in backpack)
var/itype = text2path(item)
if(itype)
backpack_contents[itype] = backpack[item]
box = text2path(outfit_data["box"])
var/list/impl = outfit_data["implants"]
implants = list()
for(var/I in impl)
var/imptype = text2path(I)
if(imptype)
implants += imptype
accessory = text2path(outfit_data["accessory"])
return TRUE
/datum/outfit/vv_get_dropdown()
. = ..()
VV_DROPDOWN_OPTION("", "---")
VV_DROPDOWN_OPTION(VV_HK_TO_OUTFIT_EDITOR, "Outfit Editor")
/datum/outfit/vv_do_topic(list/href_list)
. = ..()
if(href_list[VV_HK_TO_OUTFIT_EDITOR])
usr.client.open_outfit_editor(src)
+5 -6
View File
@@ -204,12 +204,11 @@
// first 10 minutes only
return world.time - SSticker.round_start_time < 6000
// this is broken and does not work. Thanks TG
// /datum/map_template/shuttle/emergency/airless/post_load()
// . = ..()
// //enable buying engines from cargo
// var/datum/supply_pack/P = SSshuttle.supply_packs[/datum/supply_pack/engineering/shuttle_engine]
// P.special_enabled = TRUE
/datum/map_template/shuttle/emergency/construction/post_load()
. = ..()
//enable buying engines from cargo
var/datum/supply_pack/P = SSshuttle.supply_packs[/datum/supply_pack/engineering/shuttle_engine]
P.special_enabled = TRUE
/datum/map_template/shuttle/emergency/asteroid
+3
View File
@@ -34,3 +34,6 @@
/datum/skill_modifier/job/level/wiring/basic
level_mod = JOB_SKILL_BASIC
/datum/skill_modifier/job/level/dwarfy/blacksmithing
target_skills = /datum/skill/level/dwarfy/blacksmithing
+95
View File
@@ -768,3 +768,98 @@
M.dna.species.punchdamagelow -= damageboost
M.dna.species.punchwoundbonus -= woundboost
to_chat(M, "<span class='notice'>You calm yourself, and your unnatural strength dissipates.</span>")
/datum/status_effect/crucible_soul
id = "Blessing of Crucible Soul"
status_type = STATUS_EFFECT_REFRESH
duration = 15 SECONDS
examine_text = "<span class='notice'>They don't seem to be all here.</span>"
alert_type = /obj/screen/alert/status_effect/crucible_soul
var/turf/location
/datum/status_effect/crucible_soul/on_apply()
. = ..()
to_chat(owner,"<span class='notice'>You phase through reality, nothing is out of bounds!</span>")
owner.alpha = 180
owner.pass_flags |= PASSCLOSEDTURF | PASSGLASS | PASSGRILLE | PASSTABLE | PASSMOB
location = get_turf(owner)
/datum/status_effect/crucible_soul/on_remove()
to_chat(owner,"<span class='notice'>You regain your physicality, returning you to your original location...</span>")
owner.alpha = initial(owner.alpha)
owner.pass_flags &= ~(PASSCLOSEDTURF | PASSGLASS | PASSGRILLE | PASSTABLE | PASSMOB)
owner.forceMove(location)
location = null
return ..()
/datum/status_effect/duskndawn
id = "Blessing of Dusk and Dawn"
status_type = STATUS_EFFECT_REFRESH
duration = 60 SECONDS
alert_type =/obj/screen/alert/status_effect/duskndawn
/datum/status_effect/duskndawn/on_apply()
. = ..()
ADD_TRAIT(owner,TRAIT_XRAY_VISION,type)
owner.update_sight()
/datum/status_effect/duskndawn/on_remove()
REMOVE_TRAIT(owner,TRAIT_XRAY_VISION,type)
owner.update_sight()
return ..()
/datum/status_effect/marshal
id = "Blessing of Wounded Soldier"
status_type = STATUS_EFFECT_REFRESH
duration = 60 SECONDS
tick_interval = 1 SECONDS
alert_type = /obj/screen/alert/status_effect/marshal
/datum/status_effect/marshal/on_apply()
. = ..()
ADD_TRAIT(owner,TRAIT_IGNOREDAMAGESLOWDOWN,type)
/datum/status_effect/marshal/on_remove()
. = ..()
REMOVE_TRAIT(owner,TRAIT_IGNOREDAMAGESLOWDOWN,type)
/datum/status_effect/marshal/tick()
. = ..()
if(!iscarbon(owner))
return
var/mob/living/carbon/carbie = owner
for(var/BP in carbie.bodyparts)
var/obj/item/bodypart/part = BP
for(var/W in part.wounds)
var/datum/wound/wound = W
var/heal_amt = 0
switch(wound.severity)
if(WOUND_SEVERITY_MODERATE)
heal_amt = 1
if(WOUND_SEVERITY_SEVERE)
heal_amt = 3
if(WOUND_SEVERITY_CRITICAL)
heal_amt = 6
if(wound.wound_type == WOUND_BURN)
carbie.adjustFireLoss(-heal_amt)
else
carbie.adjustBruteLoss(-heal_amt)
carbie.blood_volume += carbie.blood_volume >= BLOOD_VOLUME_NORMAL ? 0 : heal_amt*3
/obj/screen/alert/status_effect/crucible_soul
name = "Blessing of Crucible Soul"
desc = "You phased through the reality, you are halfway to your final destination..."
icon_state = "crucible"
/obj/screen/alert/status_effect/duskndawn
name = "Blessing of Dusk and Dawn"
desc = "Many things hide beyond the horizon, with Owl's help i managed to slip past sun's guard and moon's watch."
icon_state = "duskndawn"
/obj/screen/alert/status_effect/marshal
name = "Blessing of Wounded Soldier"
desc = "Some people seek power through redemption, one thing many people don't know is that battle is the ultimate redemption and wounds let you bask in eternal glory."
icon_state = "wounded_soldier"
+36 -4
View File
@@ -108,7 +108,7 @@
/datum/status_effect/off_balance/on_remove()
var/active_item = owner.get_active_held_item()
if(is_type_in_typecache(active_item, GLOB.shove_disarming_types))
if(active_item)
owner.visible_message("<span class='warning'>[owner.name] regains their grip on \the [active_item]!</span>", "<span class='warning'>You regain your grip on \the [active_item]</span>", null, COMBAT_MESSAGE_RANGE)
return ..()
@@ -117,6 +117,12 @@
desc = "You've fallen asleep. Wait a bit and you should wake up. Unless you don't, considering how helpless you are."
icon_state = "asleep"
/datum/status_effect/grouped/stasis
id = "stasis"
duration = -1
tick_interval = 10
var/last_dead_time
/datum/status_effect/no_combat_mode
id = "no_combat_mode"
alert_type = null
@@ -154,7 +160,7 @@
/obj/screen/alert/status_effect/mesmerized
name = "Mesmerized"
desc = "You cant tear your sight from who is in front of you... their gaze is simply too enthralling.."
desc = "You can't tear your sight from who is in front of you... their gaze is simply too enthralling.."
icon = 'icons/mob/actions/bloodsucker.dmi'
icon_state = "power_mez"
@@ -498,6 +504,32 @@
I.take_damage(100)
return ..()
/datum/status_effect/eldritch/void
id = "void_mark"
effect_sprite = "emark4"
/datum/status_effect/eldritch/void/on_effect()
var/turf/open/turfie = get_turf(owner)
turfie.TakeTemperature(-40)
owner.adjust_bodytemperature(-60)
return ..()
/datum/status_effect/domain
id = "domain"
alert_type = null
var/movespeed_mod = /datum/movespeed_modifier/status_effect/domain
/datum/status_effect/domain/on_creation(mob/living/new_owner, set_duration)
if(isliving(owner))
var/mob/living/carbon/C = owner
C.add_movespeed_modifier(movespeed_mod)
/datum/status_effect/electrode/on_remove()
if(isliving(owner))
var/mob/living/carbon/C = owner
C.remove_movespeed_modifier(movespeed_mod)
. = ..()
/datum/status_effect/corrosion_curse
id = "corrosion_curse"
status_type = STATUS_EFFECT_REPLACE
@@ -506,7 +538,7 @@
/datum/status_effect/corrosion_curse/on_creation(mob/living/new_owner, ...)
. = ..()
to_chat(owner, "<span class='danger'>Your feel your body starting to break apart...</span>")
to_chat(owner, "<span class='danger'>You feel your body starting to break apart...</span>")
/datum/status_effect/corrosion_curse/tick()
. = ..()
@@ -577,7 +609,7 @@
/datum/status_effect/amok/on_apply(mob/living/afflicted)
. = ..()
to_chat(owner, "<span class='boldwarning'>Your feel filled with a rage that is not your own!</span>")
to_chat(owner, "<span class='boldwarning'>You feel filled with a rage that is not your own!</span>")
/datum/status_effect/amok/tick()
. = ..()
-16
View File
@@ -219,19 +219,3 @@
/datum/quirk/night_vision/on_spawn()
var/mob/living/carbon/human/H = quirk_holder
H.update_sight()
/datum/quirk/multilingual
name = "Multi-Lingual"
desc = "You spent a portion of your life learning to understand an additional language. You may or may not be able to speak it based on your anatomy."
value = 1
mob_trait = TRAIT_MULTILINGUAL
gain_text = "You've learned an extra language!"
lose_text = "You've forgotten your extra language."
/datum/quirk/multilingual/post_add()
var/mob/living/carbon/human/H = quirk_holder
H.grant_language(H.client.prefs.language, TRUE, TRUE, LANGUAGE_MULTILINGUAL)
/datum/quirk/multilingual/remove()
var/mob/living/carbon/human/H = quirk_holder
H.remove_language(H.client.prefs.language, TRUE, TRUE, LANGUAGE_MULTILINGUAL)
+8 -5
View File
@@ -58,13 +58,13 @@
/// The list of z-levels that this weather is actively affecting
var/impacted_z_levels
/// Since it's above everything else, this is the layer used by default. TURF_LAYER is below mobs and walls if you need to use that.
var/overlay_layer = AREA_LAYER
/// Since it's above everything else, this is the layer used by default. TURF_LAYER is below mobs and walls if you need to use that.
var/overlay_layer = AREA_LAYER
/// Plane for the overlay
var/overlay_plane = BLACKNESS_PLANE
/// If the weather has no purpose but aesthetics.
/// If the weather has no purpose but aesthetics.
var/aesthetic = FALSE
/// Used by mobs to prevent them from being affected by the weather
/// Used by mobs to prevent them from being affected by the weather
var/immunity_type = "storm"
/// The stage of the weather, from 1-4
@@ -79,6 +79,8 @@
var/barometer_predictable = FALSE
/// For barometers to know when the next storm will hit
var/next_hit_time = 0
/// This causes the weather to only end if forced to
var/perpetual = FALSE
/datum/weather/New(z_levels)
..()
@@ -140,7 +142,8 @@
to_chat(M, weather_message)
if(weather_sound)
SEND_SOUND(M, sound(weather_sound))
addtimer(CALLBACK(src, .proc/wind_down), weather_duration)
if(!perpetual)
addtimer(CALLBACK(src, .proc/wind_down), weather_duration)
/**
* Weather enters the winding down phase, stops effects
@@ -18,7 +18,7 @@
area_type = /area
protected_areas = list(/area/maintenance, /area/ai_monitored/turret_protected/ai_upload, /area/ai_monitored/turret_protected/ai_upload_foyer,
/area/ai_monitored/turret_protected/ai, /area/storage/emergency/starboard, /area/storage/emergency/port, /area/shuttle, /area/security/prison, /area/ruin, /area/space/nearstation, /area/icemoon)
/area/ai_monitored/turret_protected/ai, /area/commons/storage/emergency/starboard, /area/commons/storage/emergency/port, /area/shuttle, /area/security/prison/safe, /area/security/prison/toilet)
target_trait = ZTRAIT_STATION
immunity_type = "rad"
@@ -0,0 +1,31 @@
/datum/weather/void_storm
name = "void storm"
desc = "A rare and highly anomalous event often accompanied by unknown entities shredding spacetime continouum. We'd advise you to start running."
telegraph_duration = 2 SECONDS
telegraph_overlay = "void"
weather_message = "<span class='danger'><i>You feel air around you getting colder... and void's sweet embrace...</i></span>"
weather_overlay = "void_storm"
weather_duration_lower = 60 SECONDS
weather_duration_upper = 120 SECONDS
end_duration = 10 SECONDS
area_type = /area
protect_indoors = FALSE
target_trait = ZTRAIT_VOIDSTORM
immunity_type = "void"
barometer_predictable = FALSE
perpetual = TRUE
/datum/weather/void_storm/weather_act(mob/living/L)
if(IS_HERETIC(L) || IS_HERETIC_MONSTER(L))
return
L.adjustOxyLoss(rand(1,3))
L.adjustFireLoss(rand(1,3))
L.adjust_blurriness(rand(0,1))
L.adjust_bodytemperature(-rand(5,15))
File diff suppressed because it is too large Load Diff
+4
View File
@@ -30,3 +30,7 @@
var/obj/machinery/camera/cam = X
cam.lostTargetRef(WEAKREF(O))
return
/area/ai_monitored/turret_protected/ai/Initialize()
. = ..()
src.area_flags |= ABDUCTOR_PROOF
+50 -52
View File
@@ -13,6 +13,8 @@
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
invisibility = INVISIBILITY_LIGHTING
var/area_flags = VALID_TERRITORY | BLOBS_ALLOWED | UNIQUE_AREA
var/fire = null
///Whether there is an atmos alarm in this area
var/atmosalm = FALSE
@@ -60,7 +62,7 @@
///This datum, if set, allows terrain generation behavior to be ran on Initialize()
// var/datum/map_generator/map_generator
var/datum/map_generator/map_generator
///Used to decide what kind of reverb the area makes sound have
var/sound_environment = SOUND_ENVIRONMENT_NONE
@@ -70,12 +72,8 @@
/// Set in New(); preserves the name set by the map maker, even if renamed by the Blueprints.
var/map_name
/// If it's valid territory for gangs/cults to summon
var/valid_territory = TRUE
/// malf ais can hack this
var/valid_malf_hack = TRUE
/// if blobs can spawn there and if it counts towards their score.
var/blob_allowed = TRUE
/// whether servants can warp into this area from Reebe
var/clockwork_warp_allowed = TRUE
/// Message to display when the clockwork warp fails
@@ -107,14 +105,10 @@
var/static_light = 0
var/static_environ
/// Are you forbidden from teleporting to the area? (centcom, mobs, wizard, hand teleporter)
var/noteleport = FALSE
/// Hides area from player Teleport function.
var/hidden = FALSE
/// Is the area teleport-safe: no space / radiation / aggresive mobs / other dangers
var/safe = FALSE
/// If false, loading multiple maps with this area type will create multiple instances.
var/unique = TRUE
var/no_air = null
@@ -157,7 +151,7 @@ GLOBAL_LIST_EMPTY(teleportlocs)
/proc/process_teleport_locs()
for(var/V in GLOB.sortedAreas)
var/area/AR = V
if(istype(AR, /area/shuttle) || AR.noteleport)
if(istype(AR, /area/shuttle) || (AR.area_flags & NOTELEPORT))
continue
if(GLOB.teleportlocs[AR.name])
continue
@@ -177,7 +171,7 @@ GLOBAL_LIST_EMPTY(teleportlocs)
/area/New()
// This interacts with the map loader, so it needs to be set immediately
// rather than waiting for atoms to initialize.
if (unique)
if (area_flags & UNIQUE_AREA)
GLOB.areas_by_type[type] = src
if(!minimap_color) // goes in New() because otherwise it doesn't fucking work
@@ -228,7 +222,7 @@ GLOBAL_LIST_EMPTY(teleportlocs)
reg_in_areas_in_z()
//so far I'm only implementing it on mapped unique areas, it's easier this way.
if(unique && sub_areas)
if((area_flags & UNIQUE_AREA) && sub_areas)
if(type in sub_areas)
WARNING("\"[src]\" typepath found inside its own sub-areas list, please make sure it doesn't share its parent type initial sub-areas value.")
sub_areas = null
@@ -261,21 +255,20 @@ GLOBAL_LIST_EMPTY(teleportlocs)
power_change() // all machines set to current power level, also updates icon
update_beauty()
/// Soon &trade;
/area/proc/RunGeneration()
// if(map_generator)
// map_generator = new map_generator()
// var/list/turfs = list()
// for(var/turf/T in contents)
// turfs += T
// map_generator.generate_terrain(turfs)
if(map_generator)
map_generator = new map_generator()
var/list/turfs = list()
for(var/turf/T in contents)
turfs += T
map_generator.generate_terrain(turfs)
/area/proc/test_gen()
// if(map_generator)
// var/list/turfs = list()
// for(var/turf/T in contents)
// turfs += T
// map_generator.generate_terrain(turfs)
if(map_generator)
var/list/turfs = list()
for(var/turf/T in contents)
turfs += T
map_generator.generate_terrain(turfs)
/**
* Register this area as belonging to a z level
@@ -327,6 +320,8 @@ GLOBAL_LIST_EMPTY(teleportlocs)
* Sends to all ai players, alert consoles, drones and alarm monitor programs in the world
*/
/area/proc/poweralert(state, obj/source)
if (area_flags & NO_ALERTS)
return
if (state != poweralm)
poweralm = state
if(istype(source)) //Only report power alarms on the z-level where the source is located.
@@ -358,6 +353,8 @@ GLOBAL_LIST_EMPTY(teleportlocs)
p.triggerAlarm("Power", src, cameras, source)
/area/proc/atmosalert(danger_level, obj/source)
if (area_flags & NO_ALERTS)
return
if(danger_level != atmosalm)
if (danger_level==2)
@@ -420,19 +417,19 @@ GLOBAL_LIST_EMPTY(teleportlocs)
if (!fire)
set_fire_alarm_effects(TRUE)
ModifyFiredoors(FALSE)
for (var/item in GLOB.alert_consoles)
var/obj/machinery/computer/station_alert/a = item
a.triggerAlarm("Fire", src, cameras, source)
for (var/item in GLOB.silicon_mobs)
var/mob/living/silicon/aiPlayer = item
aiPlayer.triggerAlarm("Fire", src, cameras, source)
for (var/item in GLOB.drones_list)
var/mob/living/simple_animal/drone/D = item
D.triggerAlarm("Fire", src, cameras, source)
for(var/item in GLOB.alarmdisplay)
var/datum/computer_file/program/alarm_monitor/p = item
p.triggerAlarm("Fire", src, cameras, source)
if (!(area_flags & NO_ALERTS)) //Check here instead at the start of the proc so that fire alarms can still work locally even in areas that don't send alerts
for (var/item in GLOB.alert_consoles)
var/obj/machinery/computer/station_alert/a = item
a.triggerAlarm("Fire", src, cameras, source)
for (var/item in GLOB.silicon_mobs)
var/mob/living/silicon/aiPlayer = item
aiPlayer.triggerAlarm("Fire", src, cameras, source)
for (var/item in GLOB.drones_list)
var/mob/living/simple_animal/drone/D = item
D.triggerAlarm("Fire", src, cameras, source)
for(var/item in GLOB.alarmdisplay)
var/datum/computer_file/program/alarm_monitor/p = item
p.triggerAlarm("Fire", src, cameras, source)
START_PROCESSING(SSobj, src)
@@ -441,18 +438,19 @@ GLOBAL_LIST_EMPTY(teleportlocs)
set_fire_alarm_effects(FALSE)
ModifyFiredoors(TRUE)
for (var/item in GLOB.silicon_mobs)
var/mob/living/silicon/aiPlayer = item
aiPlayer.cancelAlarm("Fire", src, source)
for (var/item in GLOB.alert_consoles)
var/obj/machinery/computer/station_alert/a = item
a.cancelAlarm("Fire", src, source)
for (var/item in GLOB.drones_list)
var/mob/living/simple_animal/drone/D = item
D.cancelAlarm("Fire", src, source)
for(var/item in GLOB.alarmdisplay)
var/datum/computer_file/program/alarm_monitor/p = item
p.cancelAlarm("Fire", src, source)
if (!(area_flags & NO_ALERTS)) //Check here instead at the start of the proc so that fire alarms can still work locally even in areas that don't send alerts
for (var/item in GLOB.silicon_mobs)
var/mob/living/silicon/aiPlayer = item
aiPlayer.cancelAlarm("Fire", src, source)
for (var/item in GLOB.alert_consoles)
var/obj/machinery/computer/station_alert/a = item
a.cancelAlarm("Fire", src, source)
for (var/item in GLOB.drones_list)
var/mob/living/simple_animal/drone/D = item
D.cancelAlarm("Fire", src, source)
for(var/item in GLOB.alarmdisplay)
var/datum/computer_file/program/alarm_monitor/p = item
p.cancelAlarm("Fire", src, source)
STOP_PROCESSING(SSobj, src)
@@ -467,7 +465,7 @@ GLOBAL_LIST_EMPTY(teleportlocs)
DOOR.lock()
/area/proc/burglaralert(obj/trigger)
if(always_unpowered) //no burglar alarms in space/asteroid
if (area_flags & NO_ALERTS)
return
//Trigger alarm effect
@@ -675,9 +673,9 @@ GLOBAL_LIST_EMPTY(teleportlocs)
power_light = FALSE
power_environ = FALSE
always_unpowered = FALSE
valid_territory = FALSE
valid_malf_hack = FALSE
blob_allowed = FALSE
area_flags &= ~VALID_TERRITORY
area_flags &= ~BLOBS_ALLOWED
addSorted()
/area/proc/update_areasize()
+6
View File
@@ -8,6 +8,7 @@ Unused icons for new areas are "awaycontent1" ~ "awaycontent30"
name = "Strange Location"
icon_state = "away"
has_gravity = STANDARD_GRAVITY
// ambience_index = AMBIENCE_AWAY
ambientsounds = AWAY_MISSION
sound_environment = SOUND_ENVIRONMENT_ROOM
@@ -27,3 +28,8 @@ Unused icons for new areas are "awaycontent1" ~ "awaycontent30"
/area/awaymission/vr
name = "Virtual Reality"
icon_state = "awaycontent1"
requires_power = FALSE
dynamic_lighting = DYNAMIC_LIGHTING_DISABLED
var/pacifist = TRUE // if when you enter this zone, you become a pacifist or not
var/death = FALSE // if when you enter this zone, you die
// network_root_id = "VR"
+20 -12
View File
@@ -1,14 +1,17 @@
// CENTCOM
// Side note, be sure to change the network_root_id of any areas that are not a part of centcom
// and just using the z space as safe harbor. It shouldn't matter much as centcom z is isolated
// from everything anyway
/area/centcom
name = "CentCom"
icon_state = "centcom"
dynamic_lighting = DYNAMIC_LIGHTING_FORCED
requires_power = FALSE
has_gravity = STANDARD_GRAVITY
noteleport = TRUE
blob_allowed = FALSE //Should go without saying, no blobs should take over centcom as a win condition.
area_flags = VALID_TERRITORY | UNIQUE_AREA | NOTELEPORT
flags_1 = NONE
/area/centcom/control
@@ -33,6 +36,7 @@
name = "VIP Zone"
dynamic_lighting = DYNAMIC_LIGHTING_DISABLED
// dear mappers who make winterball: THROW YOUR AREAS IN A DIFFERENT MAP, THIS IS DEFAULT GAME STUFF NOT EVENT STUFF
/area/centcom/winterball
name = "winterball Zone"
dynamic_lighting = DYNAMIC_LIGHTING_DISABLED
@@ -56,7 +60,7 @@
var/loading_id = ""
/area/centcom/supplypod/loading/Initialize()
. = ..()
. = ..()
if(!loading_id)
CRASH("[type] created without a loading_id")
if(GLOB.supplypod_loading_bays[loading_id])
@@ -128,17 +132,19 @@
dynamic_lighting = DYNAMIC_LIGHTING_FORCED
requires_power = FALSE
has_gravity = STANDARD_GRAVITY
noteleport = TRUE
area_flags = VALID_TERRITORY | UNIQUE_AREA | NOTELEPORT
flags_1 = NONE
// network_root_id = "MAGIC_NET"
//Abductors
/area/abductor_ship
name = "Abductor Ship"
icon_state = "yellow"
requires_power = FALSE
noteleport = TRUE
area_flags = VALID_TERRITORY | UNIQUE_AREA | NOTELEPORT
has_gravity = STANDARD_GRAVITY
flags_1 = NONE
// network_root_id = "ALIENS"
//Syndicates
/area/syndicate_mothership
@@ -146,26 +152,28 @@
icon_state = "syndie-ship"
requires_power = FALSE
has_gravity = STANDARD_GRAVITY
noteleport = TRUE
blob_allowed = FALSE //Not... entirely sure this will ever come up... but if the bus makes blobs AND ops, it shouldn't aim for the ops to win.
area_flags = VALID_TERRITORY | UNIQUE_AREA | NOTELEPORT
flags_1 = NONE
// ambience_index = AMBIENCE_DANGER
ambientsounds = HIGHSEC
// network_root_id = SYNDICATE_NETWORK_ROOT
/area/syndicate_mothership/control
name = "Syndicate Control Room"
icon_state = "syndie-control"
dynamic_lighting = DYNAMIC_LIGHTING_FORCED
// network_root_id = SYNDICATE_NETWORK_ROOT
/area/syndicate_mothership/elite_squad
name = "Syndicate Elite Squad"
icon_state = "syndie-elite"
// network_root_id = SYNDICATE_NETWORK_ROOT
/area/fabric_of_reality
name = "Tear in the Fabric of Reality"
requires_power = FALSE
has_gravity = TRUE
noteleport = TRUE
blob_allowed = FALSE
area_flags = UNIQUE_AREA | NOTELEPORT
//CAPTURE THE FLAG
@@ -174,6 +182,7 @@
icon_state = "yellow"
requires_power = FALSE
has_gravity = STANDARD_GRAVITY
flags_1 = NONE
/area/ctf/control_room
name = "Control Room A"
@@ -209,11 +218,10 @@
icon_state = "yellow"
requires_power = FALSE
has_gravity = STANDARD_GRAVITY
noteleport = TRUE
hidden = TRUE
area_flags = HIDDEN_AREA | NOTELEPORT | UNIQUE_AREA
ambientsounds = REEBE
/area/reebe/city_of_cogs
name = "City of Cogs"
icon_state = "purple"
hidden = FALSE
area_flags = NOTELEPORT | UNIQUE_AREA
+4 -3
View File
@@ -2,12 +2,13 @@
name = "Holodeck"
icon_state = "Holodeck"
dynamic_lighting = DYNAMIC_LIGHTING_DISABLED
flags_1 = 0
hidden = TRUE
flags_1 = NONE
area_flags = VALID_TERRITORY | UNIQUE_AREA
sound_environment = SOUND_ENVIRONMENT_PADDED_CELL
var/obj/machinery/computer/holodeck/linked
var/restricted = 0 // if true, program goes on emag list
var/restricted = FALSE // if true, program goes on emag list
// network_root_id = "HOLODECK"
/*
Power tracking: Use the holodeck computer's power grid

Some files were not shown because too many files have changed in this diff Show More