Merge remote-tracking branch 'upstream/master' into nanites

This commit is contained in:
Archie
2021-06-13 02:02:07 -03:00
39 changed files with 4463 additions and 3561 deletions
+1
View File
@@ -195,6 +195,7 @@
#define TRAIT_VIRILE "virile" //you have 20% more chance of impreg
#define TRAIT_MACROPHILE "macrophile" //likes the big
#define TRAIT_MICROPHILE "microphile" //likes the small
#define TRAIT_APATHETIC "apathetic" //doesn't care
#define TRAIT_TOUGH "tough" //you have 10% more maxhealth
#define TRAIT_AUTO_CATCH_ITEM "auto_catch_item"
+1 -2
View File
@@ -6,7 +6,6 @@ SUBSYSTEM_DEF(lighting)
name = "Lighting"
wait = 2
init_order = INIT_ORDER_LIGHTING
flags = SS_TICKER
var/static/list/sources_queue = list() // List of lighting sources queued for update.
var/static/list/corners_queue = list() // List of lighting corners queued for update.
var/static/list/objects_queue = list() // List of lighting objects queued for update.
@@ -88,4 +87,4 @@ SUBSYSTEM_DEF(lighting)
/datum/controller/subsystem/lighting/Recover()
initialized = SSlighting.initialized
..()
..()
@@ -1,25 +1 @@
PROCESSING_SUBSYSTEM_DEF(flightpacks)
name = "Flightpack Movement"
priority = FIRE_PRIORITY_FLIGHTPACKS
wait = 2
stat_tag = "FM"
flags = SS_NO_INIT|SS_TICKER|SS_KEEP_TIMING
var/flightsuit_processing = FLIGHTSUIT_PROCESSING_FULL
/datum/controller/subsystem/processing/flightpacks/Initialize()
sync_flightsuit_processing()
/datum/controller/subsystem/processing/flightpacks/vv_edit_var(var_name, var_value)
..()
switch(var_name)
if("flightsuit_processing")
sync_flightsuit_processing()
/datum/controller/subsystem/processing/flightpacks/proc/sync_flightsuit_processing()
for(var/obj/item/flightpack/FP in processing)
FP.sync_processing(src)
if(flightsuit_processing == FLIGHTSUIT_PROCESSING_NONE) //Don't even bother firing.
can_fire = FALSE
else
can_fire = TRUE
//Dead subsystem is dead
+2
View File
@@ -123,6 +123,8 @@
signal_enabled = TRUE
/datum/proc/UnregisterSignal(datum/target, sig_type_or_types)
if(!target)
CRASH("[src] tried to unregister a signal without having a target.")
var/list/lookup = target.comp_lookup
if(!signal_procs || !signal_procs[target] || !lookup)
return
+3 -1
View File
@@ -17,11 +17,13 @@
/obj/effect/hotspot,
/obj/effect/landmark,
/obj/effect/temp_visual,
/obj/effect/particle_effect,
/obj/effect/light_emitter/tendril,
/obj/effect/collapse,
/obj/effect/particle_effect/ion_trails,
/obj/effect/dummy/phased_mob,
/obj/effect/immovablerod
/obj/effect/immovablerod,
/obj/effect/crystalline_reentry
))
/datum/component/chasm/Initialize(turf/target)
@@ -46,6 +46,16 @@
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/datum/looping_sound/microwave_easteregg
start_sound = 'sound/machines/microwave/microwave-start.ogg'
start_length = 10
mid_sounds = list('sound/machines/microwave/microwave-eastereggmid1.ogg'=10, 'sound/machines/microwave/microwave-eastereggmid2.ogg'=1)
mid_length = 10
end_sound = 'sound/machines/microwave/microwave-eastereggend.ogg'
volume = 100
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/datum/looping_sound/grill
mid_length = 2
mid_sounds = list('sound/machines/fryer/deep_fryer_1.ogg' = 1, 'sound/machines/fryer/deep_fryer_2.ogg' = 1)
+5 -4
View File
@@ -16,6 +16,7 @@
desc = "You just don't care as much as other people. That's nice to have in a place like this, I guess."
value = 1
category = CATEGORY_MOODS
mob_trait = TRAIT_APATHETIC
mood_quirk = TRUE
medical_record_text = "Patient was administered the Apathy Evaluation Scale but did not bother to complete it."
@@ -300,7 +301,7 @@
/datum/quirk/draconicspeaker/remove()
var/mob/living/M = quirk_holder
M.remove_language(/datum/language/draconic)
M?.remove_language(/datum/language/draconic)
/datum/quirk/slimespeaker
name = "Slime speaker"
@@ -316,7 +317,7 @@
/datum/quirk/slimespeaker/remove()
var/mob/living/M = quirk_holder
M.remove_language(/datum/language/slime)
M?.remove_language(/datum/language/slime)
/datum/quirk/tajaspeaker
name = "Siik-Tajr speaker"
@@ -332,7 +333,7 @@
/datum/quirk/tajaspeaker/remove()
var/mob/living/M = quirk_holder
M.remove_language(/datum/language/tajara)
M?.remove_language(/datum/language/tajara)
/datum/quirk/russianspeaker
name = "Neo-Russkiya speaker"
@@ -348,4 +349,4 @@
/datum/quirk/russianspeaker/remove()
var/mob/living/M = quirk_holder
M.remove_language(/datum/language/spacerussian)
M?.remove_language(/datum/language/spacerussian)
+5 -2
View File
@@ -429,8 +429,11 @@ GLOBAL_LIST_EMPTY(family_heirlooms)
/datum/quirk/mute/add()
var/mob/living/carbon/human/H = quirk_holder
mute = new
H.gain_trauma(mute, TRAUMA_RESILIENCE_SURGERY)
H.gain_trauma(TRAIT_MUTE, TRAUMA_RESILIENCE_SURGERY)
H.gain_trauma(mute, TRAUMA_RESILIENCE_ABSOLUTE)
/datum/quirk/mute/remove()
var/mob/living/carbon/human/H = quirk_holder
H?.cure_trauma_type(mute, TRAUMA_RESILIENCE_ABSOLUTE)
/datum/quirk/mute/on_process()
if(quirk_holder.mind && LAZYLEN(quirk_holder.mind.antag_datums))
@@ -147,6 +147,25 @@
occurances_max = 2
chaos_min = 1.5
//////////////////////////////////////////////
// //
// MIMICS //
// //
//////////////////////////////////////////////
/datum/dynamic_ruleset/event/mimics
name = "Mimic Infestation"
typepath = /datum/round_event/mimic_infestation
enemy_roles = list("AI","Security Officer","Head of Security","Captain")
required_enemies = list(3,2,2,2,2,1,1,1,0,0)
weight = 2
cost = 5
requirements = list(101,20,15,10,10,10,10,10,10,10)
high_population_requirement = 15
earliest_start = 30 MINUTES
occurances_max = 2
chaos_min = 2
//////////////////////////////////////////////
// //
// CLOGGED VENTS //
@@ -612,6 +631,22 @@
var/atom/special_target
map_blacklist = list("LayeniaStation.dmm")
/datum/dynamic_ruleset/event/crystalline_reentry
name = "Crystalline Asteroid"
controller = /datum/round_event_control/crystalline_reentry
typepath = /datum/round_event/crystalline_reentry
enemy_roles = list("Research Director","Chief Engineer","Station Engineer","Captain","Chaplain","AI")
required_enemies = list(2,2,2,2,2,2,1,1,1,0)
requirements = list(101,101,20,18,16,14,12,10,8,6)
high_population_requirement = 15
cost = 0
occurances_max = 2
weight = 3
repeatable_weight_decrease = 2
chaos_min = 1.5
var/atom/special_target
map_whitelist = list("LayeniaStation.dmm")
/*
/datum/dynamic_ruleset/event/immovable_rod/execute() //I do not know why this is necessary
var/datum/round_event_control/E = locate(/datum/round_event_control/immovable_rod) in SSevents.control
@@ -210,6 +210,8 @@
restricted_roles = list("AI", "Cyborg", "Positronic Brain")
protected_roles = list("Rookie", "Security Officer", "Warden", "Detective", "Head of Security", "Captain", "Head of Personnel", "Chief Engineer", "Chief Medical Officer", "Research Director", "Quartermaster")
required_candidates = 1
enemy_roles = list("Security Officer", "Detective", "Head of Security", "Captain")
required_enemies = list(2,2,1,1,1,1,1,0,0,0)
weight = 4
cost = 10
requirements = list(101,101,30,25,20,20,15,15,15,10)
+1 -1
View File
@@ -35,7 +35,7 @@
return
inuse = TRUE
flick("posialertflash",src)
visible_message("There are positronic personalities available!", runechat_popup = TRUE)
visible_message("There are positronic personalities available!")
radio.talk_into(src, "There are positronic personalities available!", science_channel)
playsound(loc, 'sound/machines/ping.ogg', 50)
addtimer(CALLBACK(src, .proc/liftcooldown), 300)
+7 -7
View File
@@ -113,13 +113,12 @@
if(materials)
for(var/mat_id in materials.materials)
var/datum/material/M = mat_id
var/amount = materials.materials[mat_id]
var/datum/material/M = materials.materials[mat_id]
var/ref = REF(M)
output += "<span class=\"res_name\">[M.name]: </span>[amount] cm&sup3;"
if(amount >= MINERAL_MATERIAL_AMOUNT)
output += "<span class=\"res_name\">[M.name]: </span>[M.amount] cm&sup3;"
if(M.amount >= MINERAL_MATERIAL_AMOUNT)
output += "<span style='font-size:80%;'>- Remove \[<a href='?src=[REF(src)];remove_mat=1;material=[ref]'>1</a>\]"
if(amount >= (MINERAL_MATERIAL_AMOUNT * 10))
if(M.amount >= (MINERAL_MATERIAL_AMOUNT * 10))
output += " | \[<a href='?src=[REF(src)];remove_mat=10;material=[ref]'>10</a>\]"
output += " | \[<a href='?src=[REF(src)];remove_mat=50;material=[ref]'>50</a>\]</span>"
output += "<br>"
@@ -290,8 +289,9 @@
left_part += output_parts_list(part_set)
left_part += "<hr><a href='?src=[REF(src)];screen=main'>Return</a>"
dat = {"<html>
<head>
<title>[name]</title>
<head>
<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>
<title>[name]</title>
<style>
.res_name {font-weight: bold; text-transform: capitalize;}
.red {color: #f00;}
@@ -135,7 +135,7 @@
var/voracious = hound ? TRUE : FALSE
var/list/targets = target && hound ? list(target) : contents
if(hound)
hound.setClickCooldown(50)
//hound.setClickCooldown(50) Not needed?
if(!hound.client || !(hound.client.prefs.cit_toggles & MEDIHOUND_SLEEPER))
voracious = FALSE
else
@@ -445,10 +445,10 @@
var/mob/living/silicon/robot/hound = get_host()
if(!hound || !istype(target) || !proximity || target.anchored)
return
if (!target.devourable)
to_chat(user, "The target registers an error code. Unable to insert into [src].")
if(!target.devourable)
to_chat(user, "The target registers an error code. Unable to insert into [src]. ((This means the target has devourable prefs disabled.))")
return
if(target)
if(patient)
to_chat(user,"<span class='warning'>Your [src] is already occupied.</span>")
return
if(target.buckled)
+1 -1
View File
@@ -232,7 +232,7 @@ GENE SCANNER
msg += "\t<span class='info'>Subject has abnormal brain fuctions.</span>\n"
//Astrogen shenanigans
if(M.reagents.has_reagent(/datum/reagent/fermi/astral))
if(M.reagents?.has_reagent(/datum/reagent/fermi/astral))
if(M.mind)
msg += "\t<span class='danger'>Warning: subject may be possesed.</span>\n"
else
+1 -1
View File
@@ -487,7 +487,7 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention)
if(alert("This mob is being controlled by [M.key]. Are you sure you wish to assume control of it? [M.key] will be made a ghost.",,"Yes","No") != "Yes")
return
else
var/mob/dead/observer/ghost = new/mob/dead/observer(M,1)
var/mob/dead/observer/ghost = new/mob/dead/observer(get_turf(M), M)
ghost.ckey = M.ckey
message_admins("<span class='adminnotice'>[key_name_admin(usr)] assumed direct control of [M].</span>")
log_admin("[key_name(usr)] assumed direct control of [M].")
@@ -28,15 +28,15 @@
to_chat(target, "You feel as if you are being watched.")
return
draining = TRUE
essence_drained += rand(15, 20)
essence_drained += rand(30, 40)
to_chat(src, "<span class='revennotice'>You search for the soul of [target].</span>")
if(do_after(src, rand(10, 20), 0, target)) //did they get deleted in that second?
if(target.ckey)
to_chat(src, "<span class='revennotice'>[target.p_their(TRUE)] soul burns with intelligence.</span>")
essence_drained += rand(20, 30)
essence_drained += rand(40, 60)
if(target.stat != DEAD)
to_chat(src, "<span class='revennotice'>[target.p_their(TRUE)] soul blazes with life!</span>")
essence_drained += rand(40, 50)
essence_drained += rand(80, 100)
else
to_chat(src, "<span class='revennotice'>[target.p_their(TRUE)] soul is weak and faltering.</span>")
if(do_after(src, rand(15, 20), 0, target)) //did they get deleted NOW?
@@ -1,4 +1,4 @@
#define REVENANT_SPAWN_THRESHOLD 15
#define REVENANT_SPAWN_THRESHOLD 12
/datum/round_event_control/revenant
name = "Spawn Revenant" // Did you mean 'griefghost'?
@@ -20,7 +20,8 @@
if(!ignore_mobcheck)
var/deadMobs = 0
for(var/mob/living/carbon/M in GLOB.dead_mob_list)
deadMobs++
if(is_station_level(M.z))
deadMobs++
if(deadMobs < REVENANT_SPAWN_THRESHOLD)
message_admins("Event attempted to spawn a revenant, but there were only [deadMobs]/[REVENANT_SPAWN_THRESHOLD] dead mobs.")
return WAITING_FOR_SOMETHING
@@ -20,6 +20,8 @@
var/max_n_of_items = 10
var/efficiency = 0
var/datum/looping_sound/microwave/soundloop
var/datum/looping_sound/microwave_easteregg/eastereggloop
var/easteregg = FALSE
var/list/ingredients = list() // may only contain /atom/movables
var/static/radial_examine = image(icon = 'icons/mob/radial.dmi', icon_state = "radial_examine")
@@ -35,6 +37,7 @@
wires = new /datum/wires/microwave(src)
create_reagents(100)
soundloop = new(list(src), FALSE)
eastereggloop = new(list(src), FALSE)
/obj/machinery/microwave/Destroy()
eject()
@@ -257,7 +260,12 @@
operating = TRUE
set_light(1.5)
soundloop.start()
switch(rand(1,500))
if(1)
eastereggloop.start()
easteregg = TRUE
if(2 to 500)
soundloop.start()
update_icon()
/obj/machinery/microwave/proc/spark()
@@ -348,9 +356,13 @@
/obj/machinery/microwave/proc/after_finish_loop()
set_light(0)
soundloop.stop()
if(easteregg)
eastereggloop.stop()
easteregg = FALSE
else
soundloop.stop()
update_icon()
#undef MICROWAVE_NORMAL
#undef MICROWAVE_MUCK
#undef MICROWAVE_PRE
#undef MICROWAVE_PRE
+4 -4
View File
@@ -78,7 +78,7 @@ Medical Doctor
outfit = /datum/outfit/job/doctor
access = list(ACCESS_MEDICAL, ACCESS_MORGUE, ACCESS_SURGERY, ACCESS_CHEMISTRY, ACCESS_GENETICS, ACCESS_CLONING, ACCESS_MINERAL_STOREROOM)
access = list(ACCESS_MEDICAL, ACCESS_MORGUE, ACCESS_SURGERY, ACCESS_CHEMISTRY, ACCESS_GENETICS, ACCESS_CLONING, ACCESS_VIROLOGY, ACCESS_MINERAL_STOREROOM)
minimal_access = list(ACCESS_MEDICAL, ACCESS_MORGUE, ACCESS_SURGERY, ACCESS_CLONING, ACCESS_MINERAL_STOREROOM)
/datum/outfit/job/doctor
@@ -122,8 +122,8 @@ Chemist
outfit = /datum/outfit/job/chemist
access = list(ACCESS_MEDICAL, ACCESS_MORGUE, ACCESS_SURGERY, ACCESS_CHEMISTRY, ACCESS_GENETICS, ACCESS_CLONING, ACCESS_MINERAL_STOREROOM)
minimal_access = list(ACCESS_MEDICAL, ACCESS_CHEMISTRY, ACCESS_MINERAL_STOREROOM)
access = list(ACCESS_MEDICAL, ACCESS_MORGUE, ACCESS_SURGERY, ACCESS_CHEMISTRY, ACCESS_VIROLOGY, ACCESS_GENETICS, ACCESS_CLONING, ACCESS_MINERAL_STOREROOM)
minimal_access = list(ACCESS_MEDICAL, ACCESS_CHEMISTRY, ACCESS_CLONING, ACCESS_MINERAL_STOREROOM)
/datum/outfit/job/chemist
name = "Chemist"
@@ -203,7 +203,7 @@ Virologist
outfit = /datum/outfit/job/virologist
access = list(ACCESS_MEDICAL, ACCESS_MORGUE, ACCESS_SURGERY, ACCESS_CHEMISTRY, ACCESS_VIROLOGY, ACCESS_GENETICS, ACCESS_CLONING, ACCESS_MINERAL_STOREROOM)
minimal_access = list(ACCESS_MEDICAL, ACCESS_VIROLOGY, ACCESS_MINERAL_STOREROOM)
minimal_access = list(ACCESS_MEDICAL, ACCESS_MORGUE, ACCESS_VIROLOGY, ACCESS_CLONING, ACCESS_MINERAL_STOREROOM)
/datum/outfit/job/virologist
name = "Virologist"
+4 -1
View File
@@ -5,7 +5,7 @@
icon = LIGHTING_ICON
icon_state = "transparent"
color = LIGHTING_BASE_MATRIX
color = null //we manually set color in init instead
plane = LIGHTING_PLANE
mouse_opacity = MOUSE_OPACITY_TRANSPARENT
layer = LIGHTING_LAYER
@@ -17,6 +17,9 @@
/atom/movable/lighting_object/Initialize(mapload)
. = ..()
verbs.Cut()
//We avoid setting this in the base as if we do then the parent atom handling will add_atom_color it and that
//is totally unsuitable for this object, as we are always changing its colour manually
color = LIGHTING_BASE_MATRIX
myturf = loc
if (myturf.lighting_object)
+6 -9
View File
@@ -56,7 +56,7 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
var/deadchat_name
var/datum/spawners_menu/spawners_menu
/mob/dead/observer/Initialize()
/mob/dead/observer/Initialize(mapload, mob/body)
set_invisibility(GLOB.observer_default_invisibility)
add_verb(src, list(
@@ -77,11 +77,7 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
updateallghostimages()
var/turf/T
var/mob/body = loc
if(ismob(body))
T = get_turf(body) //Where is the body located?
if(body)
gender = body.gender
if(body.mind && body.mind.name)
name = body.mind.name
@@ -106,14 +102,15 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
update_icon()
if(!T)
if(!isturf(loc))
var/turf/T
var/list/turfs = get_area_turfs(/area/shuttle/arrival)
if(turfs.len)
T = pick(turfs)
else
T = SSmapping.get_station_center()
forceMove(T)
forceMove(T)
if(!name) //To prevent nameless ghosts
name = random_unique_name(gender)
@@ -268,7 +265,7 @@ Works together with spawning an observer, noted above.
if(!key || key[1] == "@" || (SEND_SIGNAL(src, COMSIG_MOB_GHOSTIZE, can_reenter_corpse, special, penalize) & COMPONENT_BLOCK_GHOSTING))
return //mob has no key, is an aghost or some component hijacked.
stop_sound_channel(CHANNEL_HEARTBEAT) //Stop heartbeat sounds because You Are A Ghost Now
var/mob/dead/observer/ghost = new(src) // Transfer safety to observer spawning proc.
var/mob/dead/observer/ghost = new(get_turf(src), src) // Transfer safety to observer spawning proc.
SStgui.on_transfer(src, ghost) // Transfer NanoUIs.
ghost.can_reenter_corpse = can_reenter_corpse
if (client && client.prefs && client.prefs.auto_ooc)
-6
View File
@@ -19,12 +19,6 @@
if(SSticker.mode)
SSticker.mode.check_win() //Calls the rounds wincheck, mainly for wizard, malf, and changeling now
//watching someone die is traumatic
for(var/mob/living/carbon/human/H in oview(5, src))
SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "death", /datum/mood_event/deathsaw)
if(prob(10)) //10% chance to pump adrenaline into their body
H.jitteriness += 5
/mob/living/carbon/gib(no_brain, no_organs, no_bodyparts)
var/atom/Tsec = drop_location()
for(var/mob/M in src)
@@ -52,6 +52,14 @@
if(is_devil(src))
INVOKE_ASYNC(is_devil(src), /datum/antagonist/devil.proc/beginResurrectionCheck, src)
//watching someone die is traumatic
for(var/mob/living/carbon/human/C in oview(5, src))
if(C.mind) //We don't need to give this to anything that doesn't have a mind. That's wasted processing.
if(!HAS_TRAIT(C, TRAIT_APATHETIC) || !C.mind.assigned_role == "Medical Doctor") //Shamelessly stolen from the Doctor's Delight
SEND_SIGNAL(C, COMSIG_ADD_MOOD_EVENT, "death", /datum/mood_event/deathsaw)
if(prob(10)) //10% chance to pump adrenaline into their body
C.jitteriness += 5
/mob/living/carbon/human/proc/makeSkeleton()
ADD_TRAIT(src, TRAIT_DISFIGURED, TRAIT_GENERIC)
set_species(/datum/species/skeleton)
@@ -12,6 +12,10 @@
battery = new battery_type(src)
..()
/obj/item/computer_hardware/battery/Destroy()
. = ..()
QDEL_NULL(battery)
/obj/item/computer_hardware/battery/try_insert(obj/item/I, mob/living/user = null)
if(!holder)
return FALSE
@@ -50,7 +54,6 @@
holder.shutdown_computer()
return TRUE
return FALSE
@@ -91,4 +94,4 @@
name = "nano battery"
desc = "A tiny power cell, commonly seen in low-end portable microcomputers."
icon_state = "cell_micro"
maxcharge = 300
maxcharge = 300
+1 -1
View File
@@ -74,7 +74,7 @@
stat |= BROKEN
unset_control()
/obj/machinery/power/solar/deconstruct(disassembled = TRUE)
/obj/machinery/power/tracker/deconstruct(disassembled = TRUE)
if(!(flags_1 & NODECONSTRUCT_1))
if(disassembled)
if(assembly)
@@ -25,6 +25,7 @@
var/now_fixed
var/high_threshold_cleared
var/low_threshold_cleared
rad_flags = RAD_NO_CONTAMINATE
/obj/item/organ/proc/Insert(mob/living/carbon/M, special = 0, drop_if_replaced = TRUE)
if(!iscarbon(M) || owner == M)
@@ -134,7 +135,8 @@
///Damage decrements by a percent of its maxhealth
var/healing_amount = -(maxHealth * healing_factor)
///Damage decrements again by a percent of its maxhealth, up to a total of 4 extra times depending on the owner's health
healing_amount -= owner.satiety > 0 ? 4 * healing_factor * owner.satiety / MAX_SATIETY : 0
if(owner)
healing_amount -= owner.satiety > 0 ? 4 * healing_factor * owner.satiety / MAX_SATIETY : 0
applyOrganDamage(healing_amount) //to FERMI_TWEAK
//Make it so each threshold is stuck.