[G.display_name] | "
// [/SIERRA-EDIT]
entry += "[G.cost] | "
- entry += "[FONT_NORMAL(G.get_description(get_gear_metadata(G,1)))]"
+ entry += " | [FONT_NORMAL(G.get_description(get_gear_metadata(G,1), ticked))]"
var/allowed = 1
if(allowed && G.allowed_roles)
var/good_job = 0
@@ -387,10 +387,10 @@ var/global/list/gear_datums = list()
if(custom_setup_proc)
gear_tweaks += new/datum/gear_tweak/custom_setup(custom_setup_proc)
-/datum/gear/proc/get_description(metadata)
+/datum/gear/proc/get_description(metadata, include_extended_description)
. = description
for(var/datum/gear_tweak/gt in gear_tweaks)
- . = gt.tweak_description(., metadata["[gt]"])
+ . = gt.tweak_description(., metadata["[gt]"], include_extended_description && (flags & GEAR_HAS_EXTENDED_DESCRIPTION))
/datum/gear_data
var/path
diff --git a/code/modules/client/preference_setup/occupation/occupation.dm b/code/modules/client/preference_setup/occupation/occupation.dm
index f4f0b37effdcd..dfe9b8aec6fa1 100644
--- a/code/modules/client/preference_setup/occupation/occupation.dm
+++ b/code/modules/client/preference_setup/occupation/occupation.dm
@@ -167,6 +167,9 @@
bad_message = "\[SPECIES RESTRICTED]"
else if(!S.check_background(job, user.client.prefs))
bad_message = "\[BACKGROUND RESTRICTED]"
+ else if(GAME_STATE == RUNLEVEL_GAME)
+ if(job.late_joinable == FALSE)
+ bad_message = "\[LATEJOIN RESTRICTED]"
var/current_level = JOB_LEVEL_NEVER
if(pref.job_high == job.title)
diff --git a/code/modules/clothing/spacesuits/void/wizard.dm b/code/modules/clothing/spacesuits/void/wizard.dm
index 61a39aa2c7d71..de245713dd736 100644
--- a/code/modules/clothing/spacesuits/void/wizard.dm
+++ b/code/modules/clothing/spacesuits/void/wizard.dm
@@ -52,7 +52,7 @@
body_parts_covered = HANDS
cold_protection = HANDS
min_cold_protection_temperature = SPACE_SUIT_MIN_COLD_PROTECTION_TEMPERATURE
- species_restricted = null
+ species_restricted = list("exclude",SPECIES_NABBER)
gender = PLURAL
gas_transfer_coefficient = 0.01
permeability_coefficient = 0.02
diff --git a/code/modules/clothing/suits/jobs.dm b/code/modules/clothing/suits/jobs.dm
index df877f8b8610f..fe999c9796434 100644
--- a/code/modules/clothing/suits/jobs.dm
+++ b/code/modules/clothing/suits/jobs.dm
@@ -50,6 +50,13 @@
desc = "This suit says to you 'hush'!"
icon_state = "chaplain_hoodie"
body_parts_covered = UPPER_TORSO|ARMS
+ allowed = list (
+ /obj/item/nullrod,
+ /obj/item/storage/bible,
+ /obj/item/reagent_containers/food/drinks/bottle/holywater,
+ /obj/item/material/cross
+ )
+ valid_accessory_slots = list(ACCESSORY_SLOT_INSIGNIA, ACCESSORY_SLOT_DECOR)
//Chaplain
/obj/item/clothing/suit/nun
diff --git a/code/modules/clothing/suits/miscellaneous.dm b/code/modules/clothing/suits/miscellaneous.dm
index 9dfdb6c33d4a3..5bfafe5c1f4ff 100644
--- a/code/modules/clothing/suits/miscellaneous.dm
+++ b/code/modules/clothing/suits/miscellaneous.dm
@@ -96,6 +96,7 @@
icon_state = "overalls"
item_state = "overalls"
body_parts_covered = UPPER_TORSO|LOWER_TORSO|LEGS
+ species_restricted = list("exclude",SPECIES_NABBER)
/obj/item/clothing/suit/syndicatefake
@@ -277,34 +278,30 @@
icon_state = "swim_red"
siemens_coefficient = 1
-/obj/item/clothing/suit/poncho/colored
+/obj/item/clothing/suit/poncho
name = "poncho"
desc = "A simple, comfortable poncho."
species_restricted = null
icon_state = "classicponcho"
-/obj/item/clothing/suit/poncho/colored/green
+/obj/item/clothing/suit/poncho/green
name = "green poncho"
desc = "A simple, comfortable cloak without sleeves. This one is green."
- species_restricted = null
icon_state = "greenponcho"
-/obj/item/clothing/suit/poncho/colored/red
+/obj/item/clothing/suit/poncho/red
name = "red poncho"
desc = "A simple, comfortable cloak without sleeves. This one is red."
- species_restricted = null
icon_state = "redponcho"
-/obj/item/clothing/suit/poncho/colored/purple
+/obj/item/clothing/suit/poncho/purple
name = "purple poncho"
desc = "A simple, comfortable cloak without sleeves. This one is purple."
- species_restricted = null
icon_state = "purpleponcho"
-/obj/item/clothing/suit/poncho/colored/blue
+/obj/item/clothing/suit/poncho/blue
name = "blue poncho"
desc = "A simple, comfortable cloak without sleeves. This one is blue."
- species_restricted = null
icon_state = "blueponcho"
/obj/item/clothing/suit/storage/toggle/bomber
@@ -346,12 +343,17 @@
icon_state = "brown_jacket_nt"
/obj/item/clothing/suit/storage/toggle/agent_jacket
- name = "agent jacket"
+ name = "\improper SFP jacket"
desc = "A black leather jacket belonging to an agent of the Sol Federal Police."
icon_state = "agent_jacket"
valid_accessory_slots = list(ACCESSORY_SLOT_INSIGNIA)
body_parts_covered = UPPER_TORSO|ARMS
+/obj/item/clothing/suit/storage/toggle/agent_jacket/formal
+ name = "formal SFP coat"
+ desc = "A black suit jacket belonging to an agent of the Sol Federal Police. It is of exceptional quality."
+ icon_state = "agent_formal"
+
/obj/item/clothing/suit/storage/toggle/hoodie
name = "hoodie"
desc = "A warm sweatshirt."
@@ -384,44 +386,46 @@
desc = "A warm, black sweatshirt."
color = COLOR_DARK_GRAY
+/obj/item/clothing/suit/storage/agent_rain
+ name = "\improper SFP patrol cloak"
+ desc = "A black raincloak belonging to an agent of the Sol Federal Police. It is almost certainly wind and waterproof."
+ icon_state = "agent_raincloak"
+ valid_accessory_slots = list(ACCESSORY_SLOT_INSIGNIA)
+ blood_overlay_type = "coat"
+
/obj/item/clothing/suit/storage/mbill
name = "shipping jacket"
desc = "A green jacket bearing the logo of Major Bill's Shipping."
icon_state = "mbill"
-/obj/item/clothing/suit/poncho/roles/security
+/obj/item/clothing/suit/poncho/security
name = "security poncho"
desc = "A simple, comfortable cloak without sleeves. This one is black and red, which are standard Security colors."
- species_restricted = null
icon_state = "secponcho"
-/obj/item/clothing/suit/poncho/roles/medical
+/obj/item/clothing/suit/poncho/medical
name = "medical poncho"
desc = "A simple, comfortable cloak without sleeves. This one is white with a blue tint, which are standard Medical colors."
- species_restricted = null
icon_state = "medponcho"
-/obj/item/clothing/suit/poncho/roles/engineering
+/obj/item/clothing/suit/poncho/engineering
name = "engineering poncho"
desc = "A simple, comfortable cloak without sleeves. This one is yellow and orange, which are standard Engineering colors."
- species_restricted = null
icon_state = "engiponcho"
-/obj/item/clothing/suit/poncho/roles/science
+/obj/item/clothing/suit/poncho/science
name = "science poncho"
desc = "A simple, comfortable cloak without sleeves. This one is white with a few bottle green stripes, corporate colors."
- species_restricted = null
icon_state = "sciponcho"
-/obj/item/clothing/suit/poncho/roles/science/nanotrasen
+/obj/item/clothing/suit/poncho/nanotrasen
name = "\improper NanoTrasen poncho"
desc = "A simple, comfortable cloak without sleeves. This one is white with a few red stripes, colors of NanoTrasen. Go NanoTrasen!"
icon_state = "sciponcho_nt"
-/obj/item/clothing/suit/poncho/roles/cargo
+/obj/item/clothing/suit/poncho/cargo
name = "cargo poncho"
desc = "A simple, comfortable cloak without sleeves. This one is tan and grey, which are standard Cargo colors."
- species_restricted = null
icon_state = "cargoponcho"
/*
diff --git a/code/modules/clothing/under/accessories/armor_tag.dm b/code/modules/clothing/under/accessories/armor_tag.dm
index 7a30bf4265db1..79b8858526e3f 100644
--- a/code/modules/clothing/under/accessories/armor_tag.dm
+++ b/code/modules/clothing/under/accessories/armor_tag.dm
@@ -33,6 +33,11 @@
desc = "An armor tag with the acronym SAARE printed in olive-green lettering on it."
icon_state = "saaretag"
+/obj/item/clothing/accessory/armor_tag/sfp
+ name = "\improper SFP tags"
+ desc = "A set of high-visibility armor tags made of reflective materials. The pale blue rectangle is a hallmark of the Sol Federal Police."
+ icon_state = "sfptag"
+
/obj/item/clothing/accessory/armor_tag/press
name = "\improper PRESS tag"
diff --git a/code/modules/clothing/under/accessories/chaplain.dm b/code/modules/clothing/under/accessories/chaplain.dm
index abc78d33c87dc..36d6c34bf4c08 100644
--- a/code/modules/clothing/under/accessories/chaplain.dm
+++ b/code/modules/clothing/under/accessories/chaplain.dm
@@ -60,3 +60,10 @@
name = "chaplain insignia (taoism)"
desc = "An insignia worn by chaplains. The yin yang represents Taoism."
icon_state = "taoinsignia"
+
+
+/obj/item/clothing/accessory/stole
+ name = "stole"
+ desc = "A long, colourful liturgical vestment used by Christian clergy."
+ icon_state = "stole"
+ w_class = ITEM_SIZE_SMALL
diff --git a/code/modules/clothing/under/accessories/pronouns.dm b/code/modules/clothing/under/accessories/pronouns.dm
index 91693989f5fbb..c7a9d6d65a525 100644
--- a/code/modules/clothing/under/accessories/pronouns.dm
+++ b/code/modules/clothing/under/accessories/pronouns.dm
@@ -1,47 +1,8 @@
/obj/item/clothing/accessory/pronouns
- abstract_type = /obj/item/clothing/accessory/pronouns
- name = "base pronouns badge"
+ name = "customisable pronouns badge"
+ desc = "A badge showing the wearer's pronouns. Customisable!"
icon_state = "pronounpin"
item_state = "pronouns"
on_rolled_down = ACCESSORY_ROLLED_NONE
slot = ACCESSORY_SLOT_INSIGNIA
accessory_flags = ACCESSORY_REMOVABLE | ACCESSORY_HIGH_VISIBILITY
-
-
-/obj/item/clothing/accessory/pronouns/they
- name = "they/them pronouns badge"
- desc = "A badge showing the wearer's pronouns: they, them and theirs."
-
-
-/obj/item/clothing/accessory/pronouns/hehim
- name = "he/him pronouns badge"
- desc = "A badge showing the wearer's pronouns: he, him and his."
-
-
-/obj/item/clothing/accessory/pronouns/sheher
- name = "she/her pronouns badge"
- desc = "A badge showing the wearer's pronouns: she, her and hers."
-
-
-/obj/item/clothing/accessory/pronouns/hethey
- name = "he/they pronouns badge"
- desc = "A badge showing the wearer's pronouns: he, him and his or they, them and theirs."
-
-
-/obj/item/clothing/accessory/pronouns/shethey
- name = "she/they pronouns badge"
- desc = "A badge showing the wearer's pronouns: she, her and hers or they, them and theirs."
-
-/obj/item/clothing/accessory/pronouns/heshe
- name = "he/she pronouns badge"
- desc = "A badge showing the wearer's pronouns: he, him and his or she, her and hers."
-
-
-/obj/item/clothing/accessory/pronouns/zehir
- name = "ze/hir pronouns badge"
- desc = "A badge showing the wearer's pronouns: ze, hir and hirs."
-
-
-/obj/item/clothing/accessory/pronouns/ask
- name = "ask my pronouns badge"
- desc = "A badge asking others to ask for the wearer's pronouns."
diff --git a/code/modules/clothing/under/accessories/wristwatches.dm b/code/modules/clothing/under/accessories/wristwatches.dm
index d3cdd25ef14a5..b3885e6086f0a 100644
--- a/code/modules/clothing/under/accessories/wristwatches.dm
+++ b/code/modules/clothing/under/accessories/wristwatches.dm
@@ -5,6 +5,25 @@
body_location = HANDS
+/obj/item/clothing/accessory/wristwatch/examine(mob/user, distance)
+ . = ..()
+ if (distance > 1)
+ return
+ var/list/date = text2numlist(stationdate2text(), "-")
+ var/year = date[1]
+ var/month = GLOB.month_names[date[2]]
+ var/day = date[3]
+ var/time = stationtime2text()
+ to_chat(user, "You check \the [src]. It is [time] on the [day]\th of [month], [year].")
+
+
+/obj/item/clothing/accessory/wristwatch/OnTopic(mob/user, list/href_list)
+ if (href_list["check_watch"])
+ if (istype(user))
+ examinate(user, src)
+ return TOPIC_HANDLED
+
+
/obj/item/clothing/accessory/wristwatch/leather
name = "leather wrist watch"
desc = "A rugged timekeeping device. Its leather strap is quite fashionable."
@@ -15,22 +34,3 @@
name = "fancy wrist watch"
desc = "A gaudy timekeeping device. It probably cost more than your education."
icon_state = "wristwatch_fancy"
-
-
-/obj/item/clothing/accessory/wristwatch/examine(mob/user, distance)
- . = ..()
- if (distance <= 1)
- CheckTime(user)
-
-
-/obj/item/clothing/accessory/wristwatch/proc/CheckTime(mob/user)
- var/extra_days = round(station_time_in_ticks / (1 DAY)) DAYS
- var/timeofday = world.timeofday + extra_days
- to_chat(user, "You check \the [src]. The time is [stationtime2text()] on the [time2text(timeofday, "DD")]\th of [time2text(timeofday, "Month")], [GLOB.using_map.game_year].")
-
-
-/obj/item/clothing/accessory/wristwatch/OnTopic(mob/user, list/href_list)
- if(href_list["check_watch"])
- if(istype(user))
- examinate(user, src)
- return TOPIC_HANDLED
diff --git a/code/modules/economy/Accounts.dm b/code/modules/economy/Accounts.dm
index 3091e4abd4e3f..4dd82ca47dbd2 100644
--- a/code/modules/economy/Accounts.dm
+++ b/code/modules/economy/Accounts.dm
@@ -4,6 +4,7 @@
var/account_number = 0
var/remote_access_pin = 0
var/money = 0
+ var/opening_balance = 0
var/list/transaction_log = list()
var/suspended = 0
var/security_level = 0 //0 - auto-identify from worn ID, require only account number
@@ -22,6 +23,9 @@
/datum/money_account/proc/get_balance()
return money
+/datum/money_account/proc/get_profit()
+ return money - opening_balance
+
/datum/money_account/proc/log_msg(msg, machine_id)
var/datum/transaction/log/T = new(src, msg, machine_id)
return T.perform()
@@ -54,7 +58,7 @@
var/datum/transaction/singular/T = new(M, (source_db ? source_db.machine_id : "NTGalaxyNet Terminal #[rand(111,1111)]"), starting_funds, "Account creation")
if(!source_db)
//set a random date, time and location some time over the past few decades
- T.date = "[num2text(rand(1, 31))] [pick("January","February","March","April","May","June","July","August","September","October","November","December")], [GLOB.using_map.game_year-rand(8, 18)]"
+ T.date = "[num2text(rand(1, 31))] [pick(GLOB.month_names)], [GLOB.using_map.game_year-rand(8, 18)]"
T.time = "[rand(0,24)]:[rand(11,59)]"
M.account_number = random_id("station_account_number", 111111, 999999)
@@ -88,6 +92,7 @@
//add the account
T.perform()
+ M.opening_balance = M.money
all_money_accounts.Add(M)
return M
diff --git a/code/modules/events/money_hacker.dm b/code/modules/events/money_hacker.dm
index 65bd97c7db25e..a5400286358b8 100644
--- a/code/modules/events/money_hacker.dm
+++ b/code/modules/events/money_hacker.dm
@@ -45,7 +45,7 @@ var/global/account_hack_attempted = 0
var/purpose = pick("Ne$ ---ount fu%ds init*&lisat@*n","PAY BACK YOUR MUM","Funds withdrawal","pWnAgE","l33t hax","liberationez")
var/datum/transaction/singular/T = new(affected_account, name, -amount, purpose)
var/date1 = "31 December, 1999"
- var/date2 = "[num2text(rand(1,31))] [pick("January","February","March","April","May","June","July","August","September","October","November","December")], [rand(1000,3000)]"
+ var/date2 = "[num2text(rand(1,31))] [pick(GLOB.month_names)], [rand(1000,3000)]"
T.date = pick("", stationdate2text(), date1, date2)
var/time1 = rand(0, 99999999)
var/time2 = "[round(time1 / 36000)+12]:[pad_left(time1 / 600 % 60, 2, "0")]"
diff --git a/code/modules/events/shipping_error.dm b/code/modules/events/shipping_error.dm
index 3579f773c6546..242a8c08dbf35 100644
--- a/code/modules/events/shipping_error.dm
+++ b/code/modules/events/shipping_error.dm
@@ -1,6 +1,9 @@
/datum/event/shipping_error/start()
var/datum/supply_order/O = new /datum/supply_order()
- O.ordernum = SSsupply.ordernum
+ O.ordernum = rand(1, 9000)
+ var/randomtimeofday = rand(0, 864000) // 24 hours in deciseconds
+ O.timestamp = time2text(randomtimeofday, "hh:mm")
O.object = pick(SSsupply.master_supply_list)
O.orderedby = random_name(pick(MALE,FEMALE), species = SPECIES_HUMAN)
SSsupply.shoppinglist += O
+ SSsupply.points = max(0, SSsupply.points - O.object.cost)
diff --git a/code/modules/goonchat/browserassets/css/browserOutput.css b/code/modules/goonchat/browserassets/css/browserOutput.css
index 8f728ec365813..e7365929c3ac6 100644
--- a/code/modules/goonchat/browserassets/css/browserOutput.css
+++ b/code/modules/goonchat/browserassets/css/browserOutput.css
@@ -329,14 +329,14 @@ h1.alert, h2.alert {color: #a4bad6;}
.disarm {color: #990000;}
.passive {color: #660000;}
-.danger {color: #c51e1e;}
-.warning {color: #c51e1e; font-style: italic;}
-.subtle {color: #4343ca; font-size: 75%; font-style: italic;}
+.danger {color: #f73e50; font-weight: bold;}
+.warning {color: #f58e09; font-weight: bold; font-style: italic;}
+.subtle {color: #808991; font-style: italic;}
.boldannounce {color: #c51e1e; font-weight: bold;}
.rose {color: #ff5050;}
-.info {color: #6685f5;}
+.info {color: #b13ef3; font-style: italic;}
.debug {color: #ff66ff;}
-.notice {color: #6685f5;}
+.notice {color: #327fd1;}
.alium {color: #00ff00;}
.cult {color: #aa1c1c;}
.legion {color: #e09000; font-weight: bold; font-family: 'Courier New', Courier, monospace}
diff --git a/code/modules/goonchat/browserassets/css/browserOutput_white.css b/code/modules/goonchat/browserassets/css/browserOutput_white.css
index 1d9a4424d9814..2db550c3cbfaf 100644
--- a/code/modules/goonchat/browserassets/css/browserOutput_white.css
+++ b/code/modules/goonchat/browserassets/css/browserOutput_white.css
@@ -326,14 +326,14 @@ h1.alert, h2.alert {color: #000080;}
.disarm {color: #990000;}
.passive {color: #660000;}
-.danger {color: #ff0000;}
-.warning {color: #ff0000; font-style: italic;}
-.subtle {color: #000099; font-size: 75%; font-style: italic;}
+.danger {color: #dc3545; font-weight: bold;}
+.warning {color: #cc7606; font-weight: bold; font-style: italic;}
+.subtle {color: #919ca7; font-style: italic;}
.boldannounce {color: #ff0000; font-weight: bold;}
.rose {color: #ff5050;}
-.info {color: #0000CC;}
+.info {color: #9b53c4; font-style: italic;}
.debug {color: #ff00ff;}
-.notice {color: #000099;}
+.notice {color: #0d5ef3;}
.alium {color: #00ff00;}
.cult {color: #800080; font-weight: bold; font-style: italic;}
.legion {color: #e09000; font-weight: bold; font-family: 'Courier New', Courier, monospace}
diff --git a/code/modules/hydroponics/seed_datums.dm b/code/modules/hydroponics/seed_datums.dm
index 3deaf875b6edc..b5ea465884ac8 100644
--- a/code/modules/hydroponics/seed_datums.dm
+++ b/code/modules/hydroponics/seed_datums.dm
@@ -188,7 +188,7 @@
name = "bloodtomato"
seed_name = "blood tomato"
display_name = "blood tomato plant"
- mutants = list("killer")
+ mutants = list("killertomato")
chems = list(/datum/reagent/nutriment = list(1,10), /datum/reagent/blood = list(1,5))
splat_type = /obj/decal/cleanable/blood/splatter
diff --git a/code/modules/lighting/lighting_corner.dm b/code/modules/lighting/lighting_corner.dm
index 45d1eb3045a5d..6cc1c05a83613 100644
--- a/code/modules/lighting/lighting_corner.dm
+++ b/code/modules/lighting/lighting_corner.dm
@@ -87,6 +87,9 @@ var/global/list/REVERSE_LIGHTING_CORNER_DIAGONAL = list(0, 0, 0, 0, 3, 4, 0, 0,
// So we'll have this hardcode instead.
var/turf/T
+ // This is to resolve the proper diagonal direction relative to the corner position for mimiced turfs.
+ var/Tc
+
// Diagonal one is easy.
T = get_step(new_turf, diagonal)
@@ -102,24 +105,26 @@ var/global/list/REVERSE_LIGHTING_CORNER_DIAGONAL = list(0, 0, 0, 0, 3, 4, 0, 0,
// Now the horizontal one.
T = get_step(new_turf, horizontal)
+ Tc = t1.x + (horizontal == EAST ? 1 : -1)
if (T) // Ditto.
if (!T.corners)
T.corners = new(4)
t3 = T
- t3i = REVERSE_LIGHTING_CORNER_DIAGONAL[((T.x > x) ? EAST : WEST) | ((T.y > y) ? NORTH : SOUTH)] // Get the dir based on coordinates.
+ t3i = REVERSE_LIGHTING_CORNER_DIAGONAL[((Tc > x) ? EAST : WEST) | ((t1.y > y) ? NORTH : SOUTH)] // Get the dir based on coordinates.
T.corners[t3i] = src
if (TURF_IS_AMBIENT_LIT_UNSAFE(T))
has_ambience = TRUE
// And finally the vertical one.
T = get_step(new_turf, vertical)
+ Tc = t1.y + (vertical == NORTH ? 1 : -1)
if (T)
if (!T.corners)
T.corners = new(4)
t4 = T
- t4i = REVERSE_LIGHTING_CORNER_DIAGONAL[((T.x > x) ? EAST : WEST) | ((T.y > y) ? NORTH : SOUTH)] // Get the dir based on coordinates.
+ t4i = REVERSE_LIGHTING_CORNER_DIAGONAL[((t1.x > x) ? EAST : WEST) | ((Tc > y) ? NORTH : SOUTH)] // Get the dir based on coordinates.
T.corners[t4i] = src
if (TURF_IS_AMBIENT_LIT_UNSAFE(T))
has_ambience = TRUE
@@ -308,28 +313,33 @@ var/global/list/REVERSE_LIGHTING_CORNER_DIAGONAL = list(0, 0, 0, 0, 3, 4, 0, 0,
var/turf/T
var/Ti
- if (t1)
+ if (t1 && (t1.below || HasBelow(t1.z)) && (t1.z_flags & ZM_ALLOW_LIGHTING) && TURF_IS_DYNAMICALLY_LIT_UNSAFE(t1))
T = t1
Ti = t1i
- else if (t2)
+ else if (t2 && (t2.below || HasBelow(t2.z)) && (t2.z_flags & ZM_ALLOW_LIGHTING) && TURF_IS_DYNAMICALLY_LIT_UNSAFE(t2))
T = t2
Ti = t2i
- else if (t3)
+ else if (t3 && (t3.below || HasBelow(t3.z)) && (t3.z_flags & ZM_ALLOW_LIGHTING) && TURF_IS_DYNAMICALLY_LIT_UNSAFE(t3))
T = t3
Ti = t3i
- else if (t4)
+ else if (t4 && (t4.below || HasBelow(t4.z)) && (t4.z_flags & ZM_ALLOW_LIGHTING) && TURF_IS_DYNAMICALLY_LIT_UNSAFE(t4))
T = t4
Ti = t4i
+ // No MZ candidates below, just update.
+ else if (needs_update || skip_update)
+ return
+
else
- // This should be impossible to reach -- how do we exist without at least one master turf?
- CRASH("Corner has no masters!")
+ // Always queue for this, not important enough to hit the synchronous path.
+ needs_update = TRUE
+ SSlighting.corner_queue += src
+ return
var/datum/lighting_corner/below = src
- var/turf/lasT
// We init before Z-Mimic, cannot rely on above/below.
- while ((lasT = T) && (T = T.below || GET_BELOW(T)) && (lasT.z_flags & ZM_ALLOW_LIGHTING) && TURF_IS_DYNAMICALLY_LIT_UNSAFE(T))
+ while ((T = GET_BELOW(T)) && ((below.t1?.z_flags | below.t2?.z_flags | below.t3?.z_flags | below.t4?.z_flags) & ZM_ALLOW_LIGHTING) && TURF_IS_DYNAMICALLY_LIT_UNSAFE(T))
T.ambient_has_indirect = TRUE
if (!T.corners || !T.corners[Ti])
diff --git a/code/modules/materials/material_recipes.dm b/code/modules/materials/material_recipes.dm
index 9965aec7116fb..5813cfdf9e3d3 100644
--- a/code/modules/materials/material_recipes.dm
+++ b/code/modules/materials/material_recipes.dm
@@ -175,6 +175,7 @@
. += create_recipe_list(/datum/stack_recipe/box)
. += new/datum/stack_recipe/cardborg_suit(src)
. += new/datum/stack_recipe/cardborg_helmet(src)
+ . += new/datum/stack_recipe/envelope(src)
. += new/datum/stack_recipe_list("folders", create_recipe_list(/datum/stack_recipe/folder))
/material/aluminium/generate_recipes(reinforce_material)
diff --git a/code/modules/materials/recipes_furniture.dm b/code/modules/materials/recipes_furniture.dm
index 1ea81db12049e..e0b2007c54ffd 100644
--- a/code/modules/materials/recipes_furniture.dm
+++ b/code/modules/materials/recipes_furniture.dm
@@ -15,8 +15,6 @@
/datum/stack_recipe/furniture/chair/display_name()
return modifiers ? jointext(modifiers + ..(), " ") : ..()
-/datum/stack_recipe/furniture/chair/padded
- req_amount = 2
#define PADDED_CHAIR(color) /datum/stack_recipe/furniture/chair/padded/##color{\
result_type = /obj/structure/bed/chair/padded/##color;\
diff --git a/code/modules/materials/recipes_storage.dm b/code/modules/materials/recipes_storage.dm
index 236691f66f448..b250051c5f188 100644
--- a/code/modules/materials/recipes_storage.dm
+++ b/code/modules/materials/recipes_storage.dm
@@ -38,6 +38,10 @@
req_amount = 3
on_floor = 1
+/datum/stack_recipe/envelope
+ title = "envelope"
+ result_type = /obj/item/folder/envelope
+
/datum/stack_recipe/folder
title = "folder"
result_type = /obj/item/folder
diff --git a/code/modules/mechs/equipment/combat.dm b/code/modules/mechs/equipment/combat.dm
index 89da797082398..18a97293b1697 100644
--- a/code/modules/mechs/equipment/combat.dm
+++ b/code/modules/mechs/equipment/combat.dm
@@ -92,7 +92,7 @@
toggle()
playsound(owner.loc,'sound/mecha/internaldmgalarm.ogg',35,1)
*/
- owner.add_heat(difference)
+ owner.add_heat(difference * 2)
if(difference >= 0)
toggle()
OVERHEAT = TRUE
diff --git a/code/modules/mining/mine_turfs.dm b/code/modules/mining/mine_turfs.dm
index 7a41280f9c118..41a946580e23b 100644
--- a/code/modules/mining/mine_turfs.dm
+++ b/code/modules/mining/mine_turfs.dm
@@ -41,16 +41,13 @@ var/global/list/mining_floors = list()
/turf/simulated/mineral/Initialize()
. = ..()
- if (!mining_walls["[src.z]"])
- mining_walls["[src.z]"] = list()
- mining_walls["[src.z]"] += src
+ LAZYADDASSOCLIST(mining_walls, "[z]", src)
MineralSpread()
update_icon(1)
/turf/simulated/mineral/Destroy()
- if (mining_walls["[src.z]"])
- mining_walls["[src.z]"] -= src
- GLOB.xeno_artifact_turfs -= src
+ LAZYREMOVEASSOC(mining_walls, "[z]", src)
+ SSxenoarch.xeno_artifact_turfs -= src
return ..()
/turf/simulated/mineral/can_build_cable()
@@ -423,15 +420,12 @@ var/global/list/mining_floors = list()
/turf/simulated/floor/asteroid/Initialize()
. = ..()
- if (!mining_floors["[src.z]"])
- mining_floors["[src.z]"] = list()
- mining_floors["[src.z]"] += src
+ LAZYADDASSOCLIST(mining_floors, "[z]", src)
if(prob(20))
overlay_detail = "asteroid[rand(0,9)]"
/turf/simulated/floor/asteroid/Destroy()
- if (mining_floors["[src.z]"])
- mining_floors["[src.z]"] -= src
+ LAZYREMOVEASSOC(mining_floors, "[z]", src)
return ..()
/turf/simulated/floor/asteroid/ex_act(severity)
diff --git a/code/modules/mob/grab/normal/grab_normal.dm b/code/modules/mob/grab/normal/grab_normal.dm
index 81e6541935cf1..08b87163bcd2e 100644
--- a/code/modules/mob/grab/normal/grab_normal.dm
+++ b/code/modules/mob/grab/normal/grab_normal.dm
@@ -257,11 +257,12 @@
return 0 //unsuitable weapon
user.visible_message(SPAN_DANGER("\The [user] begins to slit \the [affecting]'s throat with \the [W]!"))
- user.next_move = world.time + 20 //also should prevent user from triggering this repeatedly
- if(!do_after(user, 2 SECONDS * user.skill_delay_mult(SKILL_COMBAT), affecting, DO_DEFAULT | DO_USER_UNIQUE_ACT | DO_PUBLIC_PROGRESS))
+ var/attack_time = 3 SECONDS * user.skill_delay_mult(SKILL_COMBAT, 0.125) // 3.75 ~ 2.25 seconds
+ if(!do_after(user, attack_time, affecting, DO_DEFAULT | DO_USER_UNIQUE_ACT | DO_PUBLIC_PROGRESS))
return 0
- if(!(G && G.affecting == affecting)) //check that we still have a grab
+ if(!(G && G.affecting == affecting))
return 0
+ user.next_move = world.time + 1 SECOND
var/damage_mod = 1
var/damage_flags = W.damage_flags()
diff --git a/code/modules/mob/living/bot/medibot.dm b/code/modules/mob/living/bot/medibot.dm
index 8797246c3a319..b4c120879a6e5 100644
--- a/code/modules/mob/living/bot/medibot.dm
+++ b/code/modules/mob/living/bot/medibot.dm
@@ -20,6 +20,7 @@
var/treatment_oxy = /datum/reagent/tricordrazine
var/treatment_fire = /datum/reagent/tricordrazine
var/treatment_tox = /datum/reagent/tricordrazine
+ var/treatment_virus = /datum/reagent/spaceacillin
var/treatment_emag = /datum/reagent/toxin
var/declare_treatment = 0 //When attempting to treat a patient, should it notify everyone wearing medhuds?
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index 451db3156ef38..723584fd49958 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -386,6 +386,10 @@
if(now_pushing || !yes)
return
..()
+ //[SIERRA-ADD] VIRUSOLOGY
+ if(istype(AM, /mob/living/carbon) && prob(10))
+ src.spread_disease_to(AM, "Contact")
+ //[/SIERRA-ADD] VIRUSOLOGY
/mob/living/carbon/slip(slipped_on, stun_duration = 8)
if(!has_gravity())
diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm
index dfb72a5639484..35317c9bab2ef 100644
--- a/code/modules/mob/living/carbon/human/examine.dm
+++ b/code/modules/mob/living/carbon/human/examine.dm
@@ -174,14 +174,14 @@
if (src.stat)
msg += "[SPAN_WARNING("[P.He] [P.is]n't responding to anything around [P.him] and seems to be unconscious.")]\n"
if((stat == DEAD || is_asystole() || losebreath || status_flags & FAKEDEATH) && distance <= 3)
- msg += "[SPAN_WARNING("[P.He] [P.does] not appear to be breathing.")]\n"
+ msg += "[SPAN_DANGER("[P.He] [P.does] not appear to be breathing.")]\n"
if (fire_stacks > 0)
msg += "[P.He] looks flammable.\n"
else if (fire_stacks < 0)
msg += "[P.He] looks wet.\n"
if(on_fire)
- msg += "[SPAN_WARNING("[P.He] [P.is] on fire!.")]\n"
+ msg += "[SPAN_DANGER("[P.He] [P.is] on fire!.")]\n"
var/ssd_msg = species.get_ssd(src)
if(ssd_msg && (!should_have_organ(BP_BRAIN) || has_brain()) && stat != DEAD)
@@ -223,7 +223,7 @@
var/obj/item/organ/external/E = organs_by_name[organ_tag]
if(!E)
- wound_flavor_text[organ_descriptor] = "[P.He] [P.is] missing [P.his] [organ_descriptor].\n"
+ wound_flavor_text[organ_descriptor] = SPAN_WARNING("[P.He] [P.is] missing [P.his] [organ_descriptor].\n")
continue
wound_flavor_text[E.name] = ""
@@ -245,20 +245,20 @@
hidden_bleeders[hidden] += E.name
else
if(E.is_stump())
- wound_flavor_text[E.name] += "[P.He] [P.has] a stump where [P.his] [organ_descriptor] should be.\n"
+ wound_flavor_text[E.name] += SPAN_DANGER("[P.He] [P.has] a stump where [P.his] [organ_descriptor] should be.\n")
if(LAZYLEN(E.wounds) && E.parent)
- wound_flavor_text[E.name] += "[P.He] [P.has] [E.get_wounds_desc()] on [P.his] [E.parent.name]. "
+ wound_flavor_text[E.name] += SPAN_DANGER("[P.He] [P.has] [E.get_wounds_desc()] on [P.his] [E.parent.name]. ")
else
if(!is_synth && BP_IS_ROBOTIC(E) && (E.parent && !BP_IS_ROBOTIC(E.parent) && !BP_IS_ASSISTED(E.parent)))
- wound_flavor_text[E.name] = "[P.He] [P.has] a [E.name].\n"
+ wound_flavor_text[E.name] = SPAN_INFO("[P.He] [P.has] a [E.name].\n")
var/wounddesc = E.get_wounds_desc()
if(wounddesc != "nothing")
- wound_flavor_text[E.name] += "[P.He] [P.has] [wounddesc] on [P.his] [E.name]. "
+ wound_flavor_text[E.name] += SPAN_DANGER("[P.He] [P.has] [wounddesc] on [P.his] [E.name]. ")
if(!hidden || distance <=1)
if(E.dislocated > 0)
- wound_flavor_text[E.name] += "[P.His] [E.joint] is dislocated! "
+ wound_flavor_text[E.name] += SPAN_WARNING("[P.His] [E.joint] is dislocated! ")
if(((E.status & ORGAN_BROKEN) && E.brute_dam > E.min_broken_damage) || (E.status & ORGAN_MUTATED))
- wound_flavor_text[E.name] += "[P.His] [E.name] is dented and swollen! "
+ wound_flavor_text[E.name] += SPAN_DANGER("[P.His] [E.name] is dented and swollen! ")
for(var/datum/wound/wound in E.wounds)
var/list/embedlist = wound.embedded_objects
@@ -271,14 +271,12 @@
else if(!parsedembed.Find("multiple [embedded.name]"))
parsedembed.Remove(embedded.name)
parsedembed.Add("multiple "+embedded.name)
- wound_flavor_text["[E.name]"] += "The [wound.desc] on [P.his] [E.name] has \a [english_list(parsedembed, and_text = " and a ", comma_text = ", a ")] sticking out of it! "
+ wound_flavor_text["[E.name]"] += SPAN_DANGER("The [wound.desc] on [P.his] [E.name] has \a [english_list(parsedembed, and_text = " and a ", comma_text = ", a ")] sticking out of it! ")
for(var/hidden in hidden_bleeders)
- wound_flavor_text[hidden] = "[P.He] [P.has] blood soaking through [hidden] around [P.his] [english_list(hidden_bleeders[hidden])]! "
+ wound_flavor_text[hidden] = SPAN_DANGER("[P.He] [P.has] blood soaking through [hidden] around [P.his] [english_list(hidden_bleeders[hidden])]! ")
- var/wound_msg = ""
for(var/limb in wound_flavor_text)
- wound_msg += wound_flavor_text[limb]
- msg += SPAN_WARNING(wound_msg)
+ msg += wound_flavor_text[limb]
for(var/obj/implant in get_visible_implants(0))
if(implant in shown_objects)
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index 9ff7c549fabc5..8d44287a24820 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -943,6 +943,11 @@
if(H.brainmob.mind)
H.brainmob.mind.transfer_to(src)
qdel(H)
+ //[SIERRA-ADD] VIRUSOLOGY
+ for (var/ID in virus2)
+ var/datum/disease2/disease/V = virus2[ID]
+ V.cure(src)
+ //[/SIERRA-ADD]
losebreath = 0
diff --git a/code/modules/mob/living/carbon/human/human_attackhand.dm b/code/modules/mob/living/carbon/human/human_attackhand.dm
index 03317ede2e982..c9d7ee2f069fd 100644
--- a/code/modules/mob/living/carbon/human/human_attackhand.dm
+++ b/code/modules/mob/living/carbon/human/human_attackhand.dm
@@ -61,6 +61,11 @@
apply_effect(4, EFFECT_WEAKEN, armor_block)
return
+//[SIERRA-ADD] VIRUSOLOGY
+ if(istype(M,/mob/living/carbon))
+ M.spread_disease_to(src, "Contact")
+//[/SIERRA-ADD] VIRUSOLOGY
+
for (var/obj/item/grab/G in H)
if (G.assailant == H && G.affecting == src)
if(G.resolve_openhand_attack())
diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm
index 1c4da4029e33b..b5dbd48eb60b1 100644
--- a/code/modules/mob/living/carbon/human/life.dm
+++ b/code/modules/mob/living/carbon/human/life.dm
@@ -964,8 +964,16 @@
/mob/living/carbon/human/proc/handle_hud_list()
+ var/foundVirus = 0 //SIERRA-ADD
if (GET_BIT(hud_updateflag, HEALTH_HUD) && hud_list[HEALTH_HUD])
var/image/holder = hud_list[HEALTH_HUD]
+//SIERRA-ADD VIRUSOLOGY
+ for (var/ID in virus2)
+ if (ID in virusDB)
+ foundVirus = 1
+ break
+
+//SIERRA-ADD
if(stat == DEAD || status_flags & FAKEDEATH)
holder.icon_state = "0" // X_X
else if(is_asystole())
@@ -978,6 +986,10 @@
var/image/holder = hud_list[LIFE_HUD]
if(stat == DEAD || status_flags & FAKEDEATH)
holder.icon_state = "huddead"
+//SIERRA-ADD VIRUSOLOGY
+ else if(foundVirus)
+ holder.icon_state = "hudill"
+//SIERRA-ADD
else
holder.icon_state = "hudhealthy"
hud_list[LIFE_HUD] = holder
@@ -1001,6 +1013,10 @@
holder2.icon_state = "huddead"
else if(has_brain_worms())
holder2.icon_state = "hudbrainworm"
+//SIERRA-ADD VIRUSOLOGY
+ else if(foundVirus)
+ holder.icon_state = "hudill"
+//SIERRA-ADD
else
holder2.icon_state = "hudhealthy"
diff --git a/code/modules/mob/living/carbon/viruses.dm b/code/modules/mob/living/carbon/viruses.dm
index 9f657c52aa5cf..ca6a3b1a0fb09 100644
--- a/code/modules/mob/living/carbon/viruses.dm
+++ b/code/modules/mob/living/carbon/viruses.dm
@@ -1,16 +1,69 @@
/mob/living/carbon
var/immunity = 100 //current immune system strength
+//[SIERRA-ADD] VIRUSOLOGY
var/immunity_norm = 100 //it will regenerate to this value
/mob/living/carbon/proc/handle_viruses()
if(status_flags & GODMODE) return 0 //godmode
+ if(bodytemperature > 406)
+ for (var/ID in virus2)
+ var/datum/disease2/disease/V = virus2[ID]
+ V.cure(src)
+ if(life_tick % 3) //don't spam checks over all objects in view every tick.
+ for(var/obj/decal/cleanable/O in view(1,src))
+ if(istype(O,/obj/decal/cleanable/blood))
+ var/obj/decal/cleanable/blood/B = O
+ if(isnull(B.virus2))
+ B.virus2 = list()
+ if(LAZYLEN(B.virus2))
+ for (var/ID in B.virus2)
+ var/datum/disease2/disease/V = B.virus2[ID]
+ infect_virus2(src,V)
+
+ else if(istype(O,/obj/decal/cleanable/mucus))
+ var/obj/decal/cleanable/mucus/M = O
+ if(isnull(M.virus2))
+ M.virus2 = list()
+ if(LAZYLEN(M.virus2))
+ for (var/ID in M.virus2)
+ var/datum/disease2/disease/V = M.virus2[ID]
+ infect_virus2(src,V)
+
+ if(LAZYLEN(virus2))
+ for (var/ID in virus2)
+ var/datum/disease2/disease/V = virus2[ID]
+ if(isnull(V)) // Trying to figure out a runtime error that keeps repeating
+ CRASH("virus2 nulled before calling activate()")
+ else
+ V.process(src)
+ // activate may have deleted the virus
+ if(!V) continue
+
+ // check if we're immune
+ var/list/common_antibodies = V.antigen & src.antibodies
+ if(LAZYLEN(common_antibodies))
+ V.dead = 1
+//[/SIERRA-ADD] VIRUSOLOGY
if(immunity > 0.2 * immunity_norm && immunity < immunity_norm)
immunity = min(immunity + 0.25, immunity_norm)
+//[SIERRA-ADD] VIRUSOLOGY
+ if(life_tick % 5 && immunity < 15 && chem_effects[CE_ANTIVIRAL] < VIRUS_COMMON && !LAZYLEN(virus2))
+ var/infection_prob = 5 - immunity
+ var/turf/simulated/T = loc
+ if(istype(T))
+ infection_prob += T.dirt
+ if(T.dirt >= 50)
+ if(prob(infection_prob))
+ infect_mob_random_greater(src)
+ else
+ if(prob(infection_prob))
+ infect_mob_random_lesser(src)
+//[/SIERRA-ADD] VIRUSOLOGY
/mob/living/carbon/proc/virus_immunity()
var/antibiotic_boost = reagents.get_reagent_amount(/datum/reagent/spaceacillin) / (REAGENTS_OVERDOSE/2)
return max(immunity/100 * (1+antibiotic_boost), antibiotic_boost)
/mob/living/carbon/proc/immunity_weakness()
- return max(2-virus_immunity(), 0)
\ No newline at end of file
+ return max(2-virus_immunity(), 0)
diff --git a/code/modules/mob/living/silicon/ai/ai.dm b/code/modules/mob/living/silicon/ai/ai.dm
index fa38f46b4221f..6a4095f65c5eb 100644
--- a/code/modules/mob/living/silicon/ai/ai.dm
+++ b/code/modules/mob/living/silicon/ai/ai.dm
@@ -114,6 +114,8 @@ var/global/list/ai_verbs_default = list(
var/default_ai_icon = /singleton/ai_icon/blue
var/static/list/custom_ai_icons_by_ckey_and_name
+ idcard = /obj/item/card/id/synthetic/ai
+
/mob/living/silicon/ai/proc/add_ai_verbs()
src.verbs |= ai_verbs_default
src.verbs -= /mob/living/verb/ghost
diff --git a/code/modules/mob/living/simple_animal/hostile/vagrant.dm b/code/modules/mob/living/simple_animal/hostile/vagrant.dm
index d0b94a707501d..42c2e35bd82f0 100644
--- a/code/modules/mob/living/simple_animal/hostile/vagrant.dm
+++ b/code/modules/mob/living/simple_animal/hostile/vagrant.dm
@@ -28,13 +28,22 @@
var/blood_per_tick = 3
var/health_per_tick = 0.8
pass_flags = PASS_FLAG_TABLE
-
+ var/datum/disease2/disease/carried //[SIERRA-ADD] VIRUSOLOGY
bleed_colour = "#aad9de"
ai_holder = /datum/ai_holder/hostile/melee/vagrant
/datum/ai_holder/hostile/melee/vagrant
+
+//[SIERRA-ADD] VIRUSOLOGY
+/mob/living/simple_animal/hostile/vagrant/Initialize()
+ . = ..()
+ if(prob(25))
+ carried = new/datum/disease2/disease()
+ carried.makerandom(rand(2, 4))
+//[/SIERRA-ADD] VIRUSOLOGY
+
/datum/ai_holder/hostile/melee/vagrant/engage_target()
if(ishuman(target))
var/mob/living/carbon/human/H = target
@@ -53,7 +62,10 @@
H.Stun(1)
H.visible_message(SPAN_DANGER("\the [holder] latches onto \the [H], pulsating!"))
V.forceMove(V.gripping.loc)
-
+ //[SIERRA-ADD] VIRUSOLOGY
+ if(V.carried && length(V.gripping.virus2) == 0)
+ infect_virus2(V.gripping, V.carried, 1)
+ //[/SIERRA-ADD] VIRUSOLOGY
/mob/living/simple_animal/hostile/vagrant/Process_Spacemove()
return 1
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index 60932e7b78177..1b02c7ca507e6 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -610,7 +610,9 @@
else //Otherwise we're probably just holding their arm to lead them somewhere
var/grabtype
- if(H.has_organ(BP_L_ARM) || H.has_organ(BP_R_ARM)) //If they have at least one arm
+ if ((H.has_organ(BP_L_HAND) || H.has_organ(BP_R_HAND)) && (zone_sel.selecting == BP_L_HAND || zone_sel.selecting == BP_R_HAND))
+ grabtype = "hand"
+ else if(H.has_organ(BP_L_ARM) || H.has_organ(BP_R_ARM)) //If they have at least one arm
grabtype = "arm"
else //If they have no arms
grabtype = "shoulder"
diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm
index 7de3edeeac4e8..72ef605ecb7a7 100644
--- a/code/modules/mob/mob_movement.dm
+++ b/code/modules/mob/mob_movement.dm
@@ -360,27 +360,47 @@
to_chat(src, "You will now default to [default_run_intent] when moving quickly.")
/client/verb/setmovingslowly()
- set hidden = 1
- if(mob)
+ set hidden = TRUE
+ if (!mob)
+ return
+ if (mob.get_preference_value(/datum/client_preference/toggle_run) == GLOB.PREF_NO)
mob.set_moving_slowly()
+
/mob/proc/set_moving_slowly()
- if(!default_walk_intent)
+ if (!default_walk_intent)
default_walk_intent = get_movement_datum_by_missing_flag(MOVE_INTENT_QUICK)
- if(default_walk_intent && move_intent != default_walk_intent)
+ if (default_walk_intent && move_intent != default_walk_intent)
set_move_intent(default_walk_intent)
+
/client/verb/setmovingquickly()
- set hidden = 1
- if(mob)
+ set hidden = TRUE
+ if (!mob)
+ return
+ if (mob.get_preference_value(/datum/client_preference/toggle_run) == GLOB.PREF_NO)
mob.set_moving_quickly()
+ else
+ mob.toggle_moving_quickly()
+
/mob/proc/set_moving_quickly()
- if(!default_run_intent)
+ if (!default_run_intent)
default_run_intent = get_movement_datum_by_flag(MOVE_INTENT_QUICK)
- if(default_run_intent && move_intent != default_run_intent)
+ if (default_run_intent && move_intent != default_run_intent)
set_move_intent(default_run_intent)
+
+/mob/proc/toggle_moving_quickly()
+ var/quick = get_movement_datum_by_flag(MOVE_INTENT_QUICK)
+ if (move_intent == quick)
+ var/slow = get_movement_datum_by_missing_flag(MOVE_INTENT_QUICK)
+ if (slow && move_intent != slow)
+ set_move_intent(slow)
+ else if (quick)
+ set_move_intent(quick)
+
+
/mob/proc/can_sprint()
return FALSE
diff --git a/code/modules/mob/new_player/new_player.dm b/code/modules/mob/new_player/new_player.dm
index 13d64e4fe1d8c..ea18cf42b6ceb 100644
--- a/code/modules/mob/new_player/new_player.dm
+++ b/code/modules/mob/new_player/new_player.dm
@@ -229,6 +229,10 @@
/mob/new_player/proc/AttemptLateSpawn(datum/job/job, spawning_at)
+ if(GAME_STATE == RUNLEVEL_GAME)
+ if(job.late_joinable == FALSE)
+ to_chat(usr, SPAN_WARNING("Вы не можете зайти за эту роль во время раунда."))
+ return 0
if(src != usr)
return 0
if(GAME_STATE != RUNLEVEL_GAME)
diff --git a/code/modules/mob/skills/skill.dm b/code/modules/mob/skills/skill.dm
index 307407d401360..cf9b7a63ed44d 100644
--- a/code/modules/mob/skills/skill.dm
+++ b/code/modules/mob/skills/skill.dm
@@ -336,3 +336,13 @@ GLOBAL_LIST_EMPTY(skills)
"Trained" = "You can accurately measure out reagents, grind powders, and perform chemical reactions. You may still lose some product on occasion, but are unlikely to endanger yourself or those around you. - You can fully operate the chem dispenser.",
"Experienced" = "You work as a chemist, or else you are a doctor with training in chemistry. If you are a research chemist, you can create most useful chemicals; if you are a pharmacist, you can make most medications. At this stage, you're working mostly by-the-book. You can weaponize your chemicals by making grenades, smoke bombs, and similar devices. - You can examine held containers for scannable reagents.",
"Master" = "You specialized in chemistry or pharmaceuticals; you are either a medical researcher or professional chemist. You can create custom mixes and make even the trickiest of medications easily. You understand how your pharmaceuticals interact with the bodies of your patients. You are probably the originator of at least one new chemical innovation. - You can examine held containers for all reagents.")
+
+/singleton/hierarchy/skill/medical/chemistry/virology
+ ID = "virology"
+ name = "Virology"
+ desc = "Virology requires a specialist to have not only a deep knowledge of viruses, but also the ability to work with them, similar to how a chemist works with chemicals. This means not only understanding chemical reactions and their effects, but also knowing how these reactions will affect the human body. Thus, a virologist must have not only knowledge of virology, but also medical skills. An analogy can be drawn with a medical chemist, who must have experience working with chemicals and understand what effect they will have in order to use them safely in medicine."
+ levels = list( "Unskilled" = "You know that virologist work with viruses; you know that they can be very dangerous. You probably know basic defence against viruses..",
+ "Trained" = "You can engeener viruses. You have some training in safety and you won't infect yourself while work... probably. You can almost safely use the virologist equipment.")
+ prerequisites = list(SKILL_CHEMISTRY = SKILL_TRAINED)
+ default_max = SKILL_BASIC
+ difficulty = SKILL_AVERAGE
diff --git a/code/modules/modular_computers/file_system/programs/generic/supply.dm b/code/modules/modular_computers/file_system/programs/generic/supply.dm
index eb57b68aa22f3..34491246d9062 100644
--- a/code/modules/modular_computers/file_system/programs/generic/supply.dm
+++ b/code/modules/modular_computers/file_system/programs/generic/supply.dm
@@ -171,6 +171,7 @@
var/datum/supply_order/O = new /datum/supply_order()
O.ordernum = SSsupply.ordernum
+ O.timestamp = stationtime2text()
O.object = P
O.orderedby = idname
O.reason = reason
@@ -230,9 +231,24 @@
return 1
+ if(href_list["order_back_to_pending"])
+ var/id = text2num(href_list["order_back_to_pending"])
+ var/datum/supply_order/SO = find_order_by_id(id, SSsupply.shoppinglist)
+ if(SO)
+ SSsupply.requestlist += SO
+ SSsupply.shoppinglist -= SO
+ SSsupply.points += SO.object.cost
+
+ else
+ to_chat(user, SPAN_WARNING("Could not find order number [id] to move back to pending."))
+
+ return 1
+
if(href_list["deny_order"])
var/id = text2num(href_list["deny_order"])
var/datum/supply_order/SO = find_order_by_id(id, SSsupply.requestlist)
+ if(alert(user, "Are you sure?", "Deny Order", "Yes", "No") != "Yes")
+ return 1
if(SO)
SSsupply.requestlist -= SO
else
@@ -243,6 +259,8 @@
if(href_list["cancel_order"])
var/id = text2num(href_list["cancel_order"])
var/datum/supply_order/SO = find_order_by_id(id, SSsupply.shoppinglist)
+ if(alert(user, "Are you sure?", "Cancel Order", "Yes", "No") != "Yes")
+ return 1
if(SO)
SSsupply.shoppinglist -= SO
SSsupply.points += SO.object.cost
@@ -254,6 +272,8 @@
if(href_list["delete_order"])
var/id = text2num(href_list["delete_order"])
var/datum/supply_order/SO = find_order_by_id(id, SSsupply.donelist)
+ if(alert(user, "Are you sure?", "Delete Order", "Yes", "No") != "Yes")
+ return 1
if(SO)
SSsupply.donelist -= SO
else
@@ -358,6 +378,7 @@
/datum/nano_module/supply/proc/order_to_nanoui(datum/supply_order/SO, list_id)
return list(list(
"id" = SO.ordernum,
+ "time" = SO.timestamp,
"object" = SO.object.name,
"orderer" = SO.orderedby,
"cost" = SO.object.cost,
@@ -378,6 +399,7 @@
var/t = ""
t += "[GLOB.using_map.station_name] Supply Requisition Reciept "
t += "INDEX: #[O.ordernum] "
+ t += "TIME: [O.timestamp] "
t += "REQUESTED BY: [O.orderedby] "
t += "RANK: [O.orderedrank] "
t += "REASON: [O.reason] "
diff --git a/code/modules/modular_computers/terminal/terminal.dm b/code/modules/modular_computers/terminal/terminal.dm
index b92a8813f7e2b..01b58a0ec0a2b 100644
--- a/code/modules/modular_computers/terminal/terminal.dm
+++ b/code/modules/modular_computers/terminal/terminal.dm
@@ -67,6 +67,8 @@
var/input = sanitize(href_list["input"])
history += "> [input]"
var/output = parse(input, usr)
+ log_computer_command("[key_name(usr)]: [input]")
+ computer_log_repository.store_computer_log(usr, get_turf(computer.holder), input)
if(QDELETED(src)) // Check for exit.
return TOPIC_HANDLED
history += output
diff --git a/code/modules/organs/blood.dm b/code/modules/organs/blood.dm
index daf8a3fd3e345..f928671171217 100644
--- a/code/modules/organs/blood.dm
+++ b/code/modules/organs/blood.dm
@@ -28,7 +28,12 @@
"blood_DNA" = dna.unique_enzymes,
"blood_colour" = species.get_blood_colour(src),
"blood_type" = dna.b_type,
- "trace_chem" = null
+ "trace_chem" = null,
+//SIERRA-ADD VIRUSOLOGY
+ "virus2" = list(),
+ "antibodies" = list()
+//SIERRA-ADD
+
)
B.color = B.data["blood_colour"]
@@ -208,6 +213,12 @@
data["trace_chem"] = temp_chem
data["dose_chem"] = chem_doses.Copy()
data["blood_colour"] = species.get_blood_colour(src)
+//SIERRA-ADD VIRUSOLOGY
+ if (!data["virus2"])
+ data["virus2"] = list()
+ data["virus2"] |= virus_copylist(virus2)
+ data["antibodies"] = antibodies
+//SIERRA-ADD
return data
/proc/blood_splatter(target,datum/reagent/blood/source,large,spray_dir)
@@ -264,6 +275,11 @@
B.blood_DNA[source.data["blood_DNA"]] = source.data["blood_type"]
else
B.blood_DNA[source.data["blood_DNA"]] = "O+"
+//SIERRA-ADD VIRUSOLOGY
+ // Update virus information.
+ if(source.data["virus2"])
+ B.virus2 = virus_copylist(source.data["virus2"])
+//SIERRA-ADD
B.fluorescent = ATOM_FLOURESCENCE_NONE
B.set_invisibility(0)
diff --git a/code/modules/organs/internal/appendix.dm b/code/modules/organs/internal/appendix.dm
index 38495e7c9a84d..a51b0c903340e 100644
--- a/code/modules/organs/internal/appendix.dm
+++ b/code/modules/organs/internal/appendix.dm
@@ -13,7 +13,12 @@
/obj/item/organ/internal/appendix/Process()
..()
- if(inflamed && owner)
+//[SIERRA-EDIT]
+ if(!owner)
+ return
+ owner.immunity = min(owner.immunity + 0.025, owner.immunity_norm)
+ if(inflamed)
+//[SIERRA-EDIT]
inflamed++
if(prob(5))
if(owner.can_feel_pain())
@@ -42,3 +47,19 @@
owner.adjustToxLoss(25)
removed()
qdel(src)
+
+//[SIERRA-ADD]
+/obj/item/organ/internal/appendix/removed(mob/living/user, drop_organ=1, detach=1)
+ if(owner)
+ owner.immunity_norm -= 10
+ ..()
+
+/obj/item/organ/internal/appendix/replaced(mob/living/carbon/human/target, obj/item/organ/external/affected)
+ ..()
+ if(owner)
+ owner.immunity_norm += 10
+
+/obj/item/organ/internal/appendix/New(mob/living/carbon/holder)
+ ..()
+ if(owner)
+ owner.immunity_norm += 10
diff --git a/code/modules/organs/internal/species/ipc.dm b/code/modules/organs/internal/species/ipc.dm
index 2b5bd2aa57ab1..be0478341ea42 100644
--- a/code/modules/organs/internal/species/ipc.dm
+++ b/code/modules/organs/internal/species/ipc.dm
@@ -79,6 +79,40 @@
return
start_search(user)
+
+/obj/item/organ/internal/posibrain/use_tool(obj/item/item, mob/living/user, list/click_params)
+ if (istype(item, /obj/item/stack/nanopaste))
+ if (!damage)
+ to_chat(user, SPAN_WARNING("\The [src] has no damage to repair."))
+ return TRUE
+
+ if (HAS_FLAGS(status, ORGAN_DEAD))
+ to_chat(user, SPAN_WARNING("\The [src] is damaged beyond repair."))
+ return TRUE
+
+ if (!user.skill_check(SKILL_DEVICES, SKILL_EXPERIENCED))
+ to_chat(user, SPAN_WARNING("You don't know how to fix \the [src]."))
+ return TRUE
+
+ var/obj/item/stack/paste = item
+
+ if (!paste.use(1))
+ USE_FEEDBACK_STACK_NOT_ENOUGH(paste, 1, "to repair \the [src]")
+ return TRUE
+
+ to_chat(user, SPAN_NOTICE("You begin to repair \the [src]."))
+ if (!do_after(user, 2 SECOND, src, DO_REPAIR_CONSTRUCT) || !user.use_sanity_check(src, item))
+ return TRUE
+
+ damage -= 10
+ visible_message(
+ SPAN_NOTICE("\The [user] repairs some of \the [src]'s damage with \a [item]."),
+ SPAN_NOTICE("You repair some of \the [src]'s damage with \the [item].")
+ )
+ return TRUE
+ . = ..()
+
+
/obj/item/organ/internal/posibrain/proc/start_search(mob/user)
if (!brainmob)
return
diff --git a/code/modules/overmap/exoplanets/_exoplanet.dm b/code/modules/overmap/exoplanets/_exoplanet.dm
index e45f1bd1161d7..53fed779d90e3 100644
--- a/code/modules/overmap/exoplanets/_exoplanet.dm
+++ b/code/modules/overmap/exoplanets/_exoplanet.dm
@@ -134,10 +134,6 @@ GLOBAL_VAR(planet_repopulation_disabled)
generate_features()
for (var/datum/exoplanet_theme/T in themes)
T.after_map_generation(src)
- //[SIERRA-ADD] - ANOMALIES
- if(can_spawn_anomalies)
- generate_anomalies()
- //[SIERRA-ADD]
generate_landing(2)
update_biome()
generate_daycycle()
diff --git a/code/modules/overmap/exoplanets/planet_types/chlorine.dm b/code/modules/overmap/exoplanets/planet_types/chlorine.dm
index f43503fc86f80..b0386b61c91d5 100644
--- a/code/modules/overmap/exoplanets/planet_types/chlorine.dm
+++ b/code/modules/overmap/exoplanets/planet_types/chlorine.dm
@@ -18,7 +18,7 @@
/obj/overmap/visitable/sector/exoplanet/chlorine/get_atmosphere_color()
var/air_color = ..()
- return MixColors("#e5f2bd", air_color)
+ return MixColors(list("#e5f2bd", air_color))
/obj/overmap/visitable/sector/exoplanet/chlorine/generate_atmosphere()
..()
diff --git a/code/modules/overmap/exoplanets/planet_types/shrouded.dm b/code/modules/overmap/exoplanets/planet_types/shrouded.dm
index 56acd2cc86c8b..42f143bc826e1 100644
--- a/code/modules/overmap/exoplanets/planet_types/shrouded.dm
+++ b/code/modules/overmap/exoplanets/planet_types/shrouded.dm
@@ -26,7 +26,7 @@
/obj/overmap/visitable/sector/exoplanet/shrouded/get_atmosphere_color()
var/air_color = ..()
- return MixColors(COLOR_BLACK, air_color)
+ return MixColors(list(COLOR_BLACK, air_color))
/datum/random_map/noise/exoplanet/shrouded
descriptor = "shrouded exoplanet"
diff --git a/code/modules/overmap/exoplanets/planet_types/volcanic.dm b/code/modules/overmap/exoplanets/planet_types/volcanic.dm
index 861cb3c473fcf..159c74b37748e 100644
--- a/code/modules/overmap/exoplanets/planet_types/volcanic.dm
+++ b/code/modules/overmap/exoplanets/planet_types/volcanic.dm
@@ -17,7 +17,7 @@
/obj/overmap/visitable/sector/exoplanet/volcanic/get_atmosphere_color()
var/air_color = ..()
- return MixColors(COLOR_GRAY20, air_color)
+ return MixColors(list(COLOR_GRAY20, air_color))
/obj/overmap/visitable/sector/exoplanet/volcanic/generate_atmosphere()
..()
diff --git a/code/modules/overmap/exoplanets/random_map.dm b/code/modules/overmap/exoplanets/random_map.dm
index 77b9f07f7db7a..75e5f44eeb9b2 100644
--- a/code/modules/overmap/exoplanets/random_map.dm
+++ b/code/modules/overmap/exoplanets/random_map.dm
@@ -93,7 +93,7 @@
/datum/random_map/noise/exoplanet/proc/spawn_flora(turf/T, big)
if (big)
new /obj/landmark/exoplanet_spawn/large_plant(T)
- for(var/turf/neighbor in RANGE_TURFS(T, 1))
+ for(var/turf/neighbor as anything in RANGE_TURFS(T, 1))
spawn_grass(neighbor)
else
new /obj/landmark/exoplanet_spawn/plant(T)
diff --git a/code/modules/overmap/ships/computers/helm.dm b/code/modules/overmap/ships/computers/helm.dm
index 211417b90dc1a..9e64788ef77c9 100644
--- a/code/modules/overmap/ships/computers/helm.dm
+++ b/code/modules/overmap/ships/computers/helm.dm
@@ -44,12 +44,14 @@ GLOBAL_LIST_EMPTY(overmap_helm_computers)
/obj/machinery/computer/ship/helm/Process()
..()
- if (current_operator)
- if (!linked)
+ if (!linked)
+ if (current_operator)
to_chat(current_operator, SPAN_DANGER("\The [src]'s controls lock up with an error flashing across the screen: Connection to vessel lost!"))
set_operator(null, TRUE)
- else if (!Adjacent(current_operator) || CanUseTopic(current_operator) != STATUS_INTERACTIVE || !viewing_overmap(current_operator))
- set_operator(null)
+ return
+
+ if (current_operator && (!Adjacent(current_operator) || CanUseTopic(current_operator) != STATUS_INTERACTIVE || !viewing_overmap(current_operator)))
+ set_operator(null)
if (autopilot && dx && dy)
var/turf/T = locate(dx,dy,GLOB.using_map.overmap_z)
diff --git a/code/modules/overmap/ships/computers/ship.dm b/code/modules/overmap/ships/computers/ship.dm
index 26aa9af73b794..debe3596b5ea7 100644
--- a/code/modules/overmap/ships/computers/ship.dm
+++ b/code/modules/overmap/ships/computers/ship.dm
@@ -126,5 +126,5 @@ somewhere on that shuttle. Subtypes of these can be then used to perform ship ov
for(var/weakref/W in viewers)
var/M = W.resolve()
if (M)
- unlook(M)
+ invoke_async(PROC_REF(unlook), M)
. = ..()
diff --git a/code/modules/overmap/ships/computers/shuttle.dm b/code/modules/overmap/ships/computers/shuttle.dm
index 8cccaa32de6f9..d71b2a2998bf9 100644
--- a/code/modules/overmap/ships/computers/shuttle.dm
+++ b/code/modules/overmap/ships/computers/shuttle.dm
@@ -6,6 +6,11 @@
machine_name = "long range shuttle console"
machine_desc = "Used to control spacecraft that are designed to move between local sectors in open space."
+
+/obj/machinery/computer/shuttle_control/explore/is_valid_shuttle(datum/shuttle/shuttle)
+ return istype(shuttle, /datum/shuttle/autodock/overmap)
+
+
/obj/machinery/computer/shuttle_control/explore/get_ui_data(datum/shuttle/autodock/overmap/shuttle)
. = ..()
if(istype(shuttle))
diff --git a/code/modules/paperwork/folders.dm b/code/modules/paperwork/folders.dm
index 83c740f7d7b66..a05936a1fc034 100644
--- a/code/modules/paperwork/folders.dm
+++ b/code/modules/paperwork/folders.dm
@@ -114,9 +114,16 @@
/obj/item/folder/envelope
name = "envelope"
- desc = "A thick envelope. You can't see what's inside."
+ desc = "A thick envelope."
+ icon_state = "envelope0"
+ var/sealed = FALSE
+ var/seal_stamp = ""
+
+/obj/item/folder/envelope/preset
icon_state = "envelope_sealed"
- var/sealed = 1
+ sealed = TRUE
+ //seal_stamp = "\improper SCG Expeditionary Command rubber stamp"
+ seal_stamp = "\improper NanoTrasen Central Command rubber stamp"
/obj/item/folder/envelope/on_update_icon()
if(sealed)
@@ -126,15 +133,18 @@
/obj/item/folder/envelope/examine(mob/user)
. = ..()
- to_chat(user, "The seal is [sealed ? "intact" : "broken"].")
+ if (sealed || seal_stamp)
+ to_chat(user, "It [sealed ? "is" : "was"] sealed with \the [seal_stamp]. The seal is [sealed ? "intact" : "broken"].")
+ else
+ to_chat(user, "It is not sealed.")
/obj/item/folder/envelope/proc/sealcheck(user)
var/ripperoni = alert("Are you sure you want to break the seal on \the [src]?", "Confirmation","Yes", "No")
if(ripperoni == "Yes")
visible_message("[user] breaks the seal on \the [src], and opens it.")
- sealed = 0
+ sealed = FALSE
update_icon()
- return 1
+ return TRUE
/obj/item/folder/envelope/attack_self(mob/user as mob)
if(sealed)
@@ -147,5 +157,12 @@
if(sealed)
sealcheck(user)
return TRUE
+ else if (istype(item, /obj/item/stamp) && !sealed)
+ seal_stamp = item.name
+ visible_message("[user] seals \the [src] with [item].")
+ sealed = TRUE
+ playsound(src, 'sound/effects/stamp.ogg', 50, 1)
+ update_icon()
+ return TRUE
else
return ..()
diff --git a/code/modules/power/cable_structure.dm b/code/modules/power/cable_structure.dm
index ad3a4327b9d07..a7da6f4e0f0c2 100644
--- a/code/modules/power/cable_structure.dm
+++ b/code/modules/power/cable_structure.dm
@@ -361,7 +361,7 @@ By design, d1 is the smallest direction and d2 is the highest
//////////////////////////////////////////////
//if powernetless_only = 1, will only get connections without powernet
-/obj/structure/cable/proc/get_connections(powernetless_only = 0)
+/obj/structure/cable/proc/get_cable_connections(skip_assigned_powernets = FALSE)
. = list() // this will be a list of all connected power objects
var/turf/T
@@ -389,17 +389,23 @@ By design, d1 is the smallest direction and d2 is the highest
if(C.d1 == d1 || C.d2 == d1 || C.d1 == d2 || C.d2 == d2) // if either of C's d1 and d2 match either of ours
. += C
+ // if asked, skip any cables with powernts
+ if(skip_assigned_powernets)
+ for(var/obj/structure/cable/C in .)
+ if(C.powernet)
+ . -= C
+
+/obj/structure/cable/proc/get_machine_connections(skip_assigned_powernets = FALSE)
+ . = list() // this will be a list of all connected power objects
+
if(d1 == 0)
for(var/obj/machinery/power/P in loc)
if(P.powernet == 0) continue // exclude APCs with powernet=0
- if(!powernetless_only || !P.powernet)
+ if(!skip_assigned_powernets || !P.powernet)
. += P
- // if the caller asked for powernetless cables only, dump the ones with powernets
- if(powernetless_only)
- for(var/obj/structure/cable/C in .)
- if(C.powernet)
- . -= C
+/obj/structure/cable/proc/get_connections(skip_assigned_powernets = FALSE)
+ return get_cable_connections(skip_assigned_powernets) + get_machine_connections(skip_assigned_powernets)
//should be called after placing a cable which extends another cable, creating a "smooth" cable that no longer terminates in the centre of a turf.
//needed as this can, unlike other placements, disconnect cables
diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm
index 2ea8e97817235..cd3c8df4c1252 100644
--- a/code/modules/power/lighting.dm
+++ b/code/modules/power/lighting.dm
@@ -508,7 +508,7 @@
update_icon(FALSE)
sleep(rand(5, 15))
on = (get_status() == LIGHT_OK)
- update_icon(0)
+ queue_icon_update(0)
flickering = FALSE
// ai attack - make lights flicker, because why not
diff --git a/code/modules/power/power.dm b/code/modules/power/power.dm
index 5627b7129e43e..7fd8c10eed3be 100644
--- a/code/modules/power/power.dm
+++ b/code/modules/power/power.dm
@@ -196,31 +196,25 @@
return .
//remove the old powernet and replace it with a new one throughout the network.
-/proc/propagate_network(obj/O, datum/powernet/PN)
+/proc/propagate_network(obj/structure/cable/cable, datum/powernet/PN)
//to_world_log("propagating new network")
- var/list/worklist = list()
+ var/list/cables = list()
var/list/found_machines = list()
var/index = 1
- var/obj/P = null
+ var/obj/structure/cable/working_cable = null
- worklist+=O //start propagating from the passed object
-
- while(index<=length(worklist)) //until we've exhausted all power objects
- P = worklist[index] //get the next power object found
+ // add the first cable to the list
+ cables[cable] = TRUE // associative list for speedy deduplication
+ while(index <= length(cables)) //until we've exhausted all power objects
+ working_cable = cables[index] //get the next power object found
index++
- if( istype(P,/obj/structure/cable))
- var/obj/structure/cable/C = P
- if(C.powernet != PN) //add it to the powernet, if it isn't already there
- PN.add_cable(C)
- worklist |= C.get_connections() //get adjacents power objects, with or without a powernet
-
- else if(P.anchored && istype(P,/obj/machinery/power))
- var/obj/machinery/power/M = P
- found_machines |= M //we wait until the powernet is fully propagates to connect the machines
+ for(var/new_cable in working_cable.get_cable_connections()) //get adjacent cables, with or without a powernet
+ cables[new_cable] = TRUE
- else
- continue
+ for(var/obj/structure/cable/cable_entry in cables)
+ PN.add_cable(cable_entry)
+ found_machines += cable_entry.get_machine_connections()
//now that the powernet is set, connect found machines to it
for(var/obj/machinery/power/PM in found_machines)
diff --git a/code/modules/power/terminal.dm b/code/modules/power/terminal.dm
index 9fa1367a7144a..addf4d81e3a95 100644
--- a/code/modules/power/terminal.dm
+++ b/code/modules/power/terminal.dm
@@ -9,7 +9,7 @@
icon_state = "term"
desc = "It's an underfloor wiring terminal for power equipment."
level = ATOM_LEVEL_UNDER_TILE
- layer = EXPOSED_WIRE_TERMINAL_LAYER
+ layer = ABOVE_EXPOSED_WIRE_LAYER
var/obj/item/stock_parts/power/terminal/master
anchored = TRUE
diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm
index f02aba7877412..fe797006d15e2 100644
--- a/code/modules/projectiles/gun.dm
+++ b/code/modules/projectiles/gun.dm
@@ -139,11 +139,6 @@
if(scope_zoom)
verbs += /obj/item/gun/proc/scope
-/obj/item/gun/update_twohanding()
- if(one_hand_penalty)
- update_icon() // In case item_state is set somewhere else.
- ..()
-
/obj/item/gun/on_update_icon()
var/mob/living/M = loc
ClearOverlays()
@@ -234,11 +229,8 @@
else
Fire(target, user, pointblank = TRUE)
return TRUE
-
// Point blank shooting
if (user.a_intent == I_HURT && !user.isEquipped(target))
- if (safety()) // Pistol whip instead of unsafety+fire
- return ..()
Fire(target, user, pointblank = TRUE)
return TRUE
@@ -338,7 +330,7 @@
flick(fire_anim, src)
if (user)
- var/user_message = SPAN_WARNING("You fire \the [src][pointblank ? " point blank":""] at \the [target][reflex ? " by reflex" : ""]!")
+ var/user_message = SPAN_DANGER("You fire \the [src][pointblank ? " point blank":""] at \the [target][reflex ? " by reflex" : ""]!")
if (silenced)
to_chat(user, user_message)
else
diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm
index 5130aab4d790e..a2177b021e23a 100644
--- a/code/modules/projectiles/guns/energy.dm
+++ b/code/modules/projectiles/guns/energy.dm
@@ -94,7 +94,6 @@
icon_state = "[modifystate][ratio]"
else
icon_state = "[initial(icon_state)][ratio]"
- update_held_icon()
/obj/item/gun/energy/handle_post_fire(mob/user, atom/target, pointblank, reflex, obj/projectile)
..()
diff --git a/code/modules/projectiles/guns/launcher/pneumatic.dm b/code/modules/projectiles/guns/launcher/pneumatic.dm
index 23d913aec227a..f2b0f0cce4051 100644
--- a/code/modules/projectiles/guns/launcher/pneumatic.dm
+++ b/code/modules/projectiles/guns/launcher/pneumatic.dm
@@ -152,8 +152,6 @@
icon_state = "pneumatic"
item_state = "pneumatic"
- update_held_icon()
-
/obj/item/gun/launcher/pneumatic/small
name = "small pneumatic cannon"
desc = "It looks smaller than your garden variety cannon."
diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm
index b5d833f685e1b..4fabeb561a7f0 100644
--- a/code/modules/projectiles/projectile.dm
+++ b/code/modules/projectiles/projectile.dm
@@ -60,7 +60,7 @@
var/space_knockback = 0 //whether or not it will knock things back in space
var/hitscan = FALSE // whether the projectile should be hitscan
- var/step_delay = 1 // the delay between iterations if not a hitscan projectile
+ var/step_delay = 0.65 // the delay between iterations if not a hitscan projectile
// effect types to be used
var/muzzle_type
diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm
index 54d14dab730b7..83f05e88d368b 100644
--- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm
+++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Core.dm
@@ -7,6 +7,10 @@
"blood_colour" = COLOR_BLOOD_HUMAN,
"trace_chem" = null,
"dose_chem" = null,
+ //[SIERRA-ADD] VIRUSOLOGY
+ "virus2" = list(),
+ "antibodies" = list(),
+ //[/SIERRA-ADD] VIRUSOLOGY
"has_oxy" = 1
)
name = "Blood"
@@ -41,6 +45,15 @@
/datum/reagent/blood/get_data() // Just in case you have a reagent that handles data differently.
var/t = data.Copy()
+//SIERRA ADD VIRUSOLOGY
+ if(t["virus2"])
+ var/list/v = t["virus2"]
+ t["virus2"] = v.Copy()
+
+ if(t["antibodies"])//... and curing
+ var/list/v = t["antibodies"]
+ t["antibodies"] |= v.Copy()
+//SIERRA ADD
return t
/datum/reagent/blood/touch_turf(turf/simulated/T)
diff --git a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm
index 53cee3af9f918..f874f0d22ed7c 100644
--- a/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm
+++ b/code/modules/reagents/Chemistry-Reagents/Chemistry-Reagents-Medicine.dm
@@ -299,6 +299,9 @@
if(boozed)
M.add_chemical_effect(CE_ALCOHOL_TOXIC, 1)
M.add_chemical_effect(CE_BREATHLOSS, 0.1 * boozed) //drinking and opiating makes breathing kinda hard
+ if(isfast(M))
+ M.add_chemical_effect(CE_BREATHLOSS, 0.5)
+ M.add_chemical_effect(CE_SLOWDOWN, 2) //hyperzine reacts negatively with opiates
/datum/reagent/tramadol/overdose(mob/living/carbon/M)
..()
@@ -308,6 +311,10 @@
M.add_chemical_effect(CE_BREATHLOSS, 0.6) //Have trouble breathing, need more air
if(isboozed(M))
M.add_chemical_effect(CE_BREATHLOSS, 0.2) //Don't drink and OD on opiates folks
+ if(isfast(M))
+ M.add_chemical_effect(CE_NOPULSE, 1)
+ var/obj/item/organ/internal/heart = M.internal_organs_by_name[BP_HEART] //heart damage + arrest
+ heart.take_internal_damage(heart.max_damage * 0.045)
/datum/reagent/tramadol/proc/isboozed(mob/living/carbon/M)
. = 0
@@ -321,6 +328,16 @@
if(booze.strength < 40) //liquor stuff hits harder
return 2
+/datum/reagent/tramadol/proc/isfast(mob/living/carbon/M)
+ . = FALSE
+ var/datum/reagents/ingested = M.get_ingested_reagents()
+ if(!ingested)
+ return FALSE
+ var/list/pool = M.reagents.reagent_list | ingested.reagent_list
+ for(var/datum/reagent/hyperzine/fast in pool)
+ if(M.chem_doses[fast.type])
+ return TRUE
+
/datum/reagent/tramadol/oxycodone
name = "Oxycodone"
description = "An effective and very addictive painkiller. Don't mix with alcohol."
@@ -488,7 +505,7 @@
/datum/reagent/hyperzine
name = "Hyperzine"
- description = "Hyperzine is a highly effective, long lasting, muscle stimulant."
+ description = "Hyperzine is a highly effective, long lasting, muscle stimulant. Do not mix with opiates!"
taste_description = "acid"
reagent_state = LIQUID
color = "#ff3300"
diff --git a/code/modules/reagents/reagent_containers/food/snacks.dm b/code/modules/reagents/reagent_containers/food/snacks.dm
index fcb3c076a9c99..d818de5a1f863 100644
--- a/code/modules/reagents/reagent_containers/food/snacks.dm
+++ b/code/modules/reagents/reagent_containers/food/snacks.dm
@@ -501,7 +501,7 @@
filling_color = "#e0d7c5"
center_of_mass = "x=17;y=16"
nutriment_amt = 3
- nutriment_desc = list("raw" = 2, "mushroom" = 2)
+ nutriment_desc = list("fleshy mushroom" = 2)
bitesize = 6
/obj/item/reagent_containers/food/snacks/hugemushroomslice/Initialize()
.=..()
@@ -514,7 +514,7 @@
filling_color = "#db0000"
center_of_mass = "x=17;y=16"
nutriment_amt = 3
- nutriment_desc = list("raw" = 2, "tomato" = 3)
+ nutriment_desc = list("fleshy tomato" = 3)
bitesize = 6
/obj/item/reagent_containers/food/snacks/bearmeat
diff --git a/code/modules/reagents/reagent_containers/ivbag.dm b/code/modules/reagents/reagent_containers/ivbag.dm
index 4b705abd14d02..8ec51db5120b0 100644
--- a/code/modules/reagents/reagent_containers/ivbag.dm
+++ b/code/modules/reagents/reagent_containers/ivbag.dm
@@ -281,7 +281,11 @@
"blood_type" = blood_type,
"trace_chem" = null,
"blood_species" = blood_species,
- "blood_colour" = species.blood_color
+ "blood_colour" = species.blood_color,
+//SIERRA-ADD MODPACK VIRUSOLOGY
+ "virus2" = list(),
+ "antibodies" = list()
+//SIERRA-ADD MODPACK VIRUSOLOGY
))
AddLabel("[blood_species] [blood_type]")
UpdateItemSize()
diff --git a/code/modules/recycling/conveyor2.dm b/code/modules/recycling/conveyor2.dm
index 429a0698d58db..c7158d2d0fc8a 100644
--- a/code/modules/recycling/conveyor2.dm
+++ b/code/modules/recycling/conveyor2.dm
@@ -220,10 +220,12 @@
update_icon()
// find any switches with same id as this one, and set their positions to match us
- for(var/obj/machinery/conveyor_switch/S in world)
- if(S.id == src.id)
- S.position = position
- S.update_icon()
+ for(var/obj/machinery/conveyor_switch/other_switch as anything in SSmachines.get_machinery_of_type(/obj/machinery/conveyor_switch))
+ if(other_switch.id != id)
+ continue
+
+ other_switch.position = position
+ other_switch.update_icon()
return TRUE
/obj/machinery/conveyor_switch/proc/do_switch(mob/user)
diff --git a/code/modules/shuttles/shuttle_console.dm b/code/modules/shuttles/shuttle_console.dm
index 752bbd43336f3..427cc1be27630 100644
--- a/code/modules/shuttles/shuttle_console.dm
+++ b/code/modules/shuttles/shuttle_console.dm
@@ -7,12 +7,44 @@
machine_name = "basic shuttle console"
machine_desc = "A simple control system for small spacecraft, allowing automated movement from one navigation point to another."
- var/shuttle_tag // Used to coordinate data in shuttle controller.
+ /// Used to coordinate data in shuttle controller. Set by `sync_shuttle()`.
+ var/shuttle_tag
var/hacked = 0 // Has been emagged, no access restrictions.
var/ui_template = "shuttle_control_console.tmpl"
+
+/obj/machinery/computer/shuttle_control/Initialize(mapload)
+ . = ..()
+ if (!shuttle_tag)
+ sync_shuttle()
+
+
+/obj/machinery/computer/shuttle_control/on_update_icon()
+ icon_screen = shuttle_tag ? initial(icon_screen) : "shuttle_error"
+ ..()
+
+
+/// Sets `shuttle_tag` to a new value based on the computer's current area, or to `null` if the area is not a valid shuttle.
+/obj/machinery/computer/shuttle_control/proc/sync_shuttle()
+ shuttle_tag = null
+ var/area/current_area = get_area(src)
+ for (var/shuttle_name in SSshuttle.shuttles)
+ var/datum/shuttle/shuttle = SSshuttle.shuttles[shuttle_name]
+ if (!(current_area in shuttle.shuttle_area))
+ continue
+ if (!is_valid_shuttle(SSshuttle.shuttles[shuttle_name]))
+ break
+ shuttle_tag = shuttle_name
+ break
+
+
+/// Determines whether the given shuttle datum is valid for this computer.
+/obj/machinery/computer/shuttle_control/proc/is_valid_shuttle(datum/shuttle/shuttle)
+ return !istype(shuttle, /datum/shuttle/autodock/overmap)
+
+
/obj/machinery/computer/shuttle_control/interface_interact(mob/user)
ui_interact(user)
return TRUE
diff --git a/code/modules/species/species.dm b/code/modules/species/species.dm
index 56ff8b9b31f1f..0a31337de38cd 100644
--- a/code/modules/species/species.dm
+++ b/code/modules/species/species.dm
@@ -431,8 +431,8 @@ The slots that you can use are found in items_clothing.dm and are the inventory
post_organ_rejuvenate(O, H)
H.sync_organ_dna()
-/* ------------------------> code\modules\emotes\definitions\_species.dm
-/datum/species/proc/hug(mob/living/carbon/human/H,mob/living/target)
+/* ------------------------> code\modules\emotes\definitions\_species.dm (У нас всё в моде в mods\emote_panel\code\species.dm)
+/datum/species/proc/hug(mob/living/carbon/human/H, mob/living/target)
var/t_him = "them"
switch(target.gender)
@@ -441,8 +441,15 @@ The slots that you can use are found in items_clothing.dm and are the inventory
if(FEMALE)
t_him = "her"
- H.visible_message(SPAN_NOTICE("[H] hugs [target] to make [t_him] feel better!"), \
- SPAN_NOTICE("You hug [target] to make [t_him] feel better!"))
+ // If aiming for the head, try a headpat
+ if (ishuman(target))
+ var/target_zone = check_zone(H.zone_sel.selecting)
+ var/mob/living/carbon/human/h_target = target
+ if (target_zone == BP_HEAD && h_target.get_organ(target_zone))
+ H.visible_message(SPAN_NOTICE("[H] pats [h_target]'s head to make [t_him] feel better!"), SPAN_NOTICE("You pat [h_target]'s head to make [t_him] feel better!"))
+ return
+
+ H.visible_message(SPAN_NOTICE("[H] hugs [target] to make [t_him] feel better!"), SPAN_NOTICE("You hug [target] to make [t_him] feel better!"))
if(H != target)
H.update_personal_goal(/datum/goal/achievement/givehug, TRUE)
diff --git a/code/modules/supermatter/supermatter.dm b/code/modules/supermatter/supermatter.dm
index d00981509bf06..06e4f52302b73 100644
--- a/code/modules/supermatter/supermatter.dm
+++ b/code/modules/supermatter/supermatter.dm
@@ -581,7 +581,7 @@
return
/obj/machinery/power/supermatter/ex_act(severity)
- ..()
+ // not calling parent ex_act as it has a chance to qdel the supermatter
switch(severity)
if(EX_ACT_DEVASTATING)
power *= 4
diff --git a/code/modules/xenoarcheaology/sampling.dm b/code/modules/xenoarcheaology/sampling.dm
index 1c03574c19599..6f012352fdb22 100644
--- a/code/modules/xenoarcheaology/sampling.dm
+++ b/code/modules/xenoarcheaology/sampling.dm
@@ -70,14 +70,14 @@
artifact_distance = rand()
artifact_id = container.artifact_find.artifact_id
else
- for (var/turf/simulated/mineral/T as anything in GLOB.xeno_artifact_turfs)
+ for (var/turf/simulated/mineral/T as anything in SSxenoarch.xeno_artifact_turfs)
if(T.artifact_find)
var/cur_dist = get_dist(container, T) * 2
if( (artifact_distance < 0 || cur_dist < artifact_distance))
artifact_distance = cur_dist + rand() * 2 - 1
artifact_id = T.artifact_find.artifact_id
else
- GLOB.xeno_artifact_turfs -= T
+ SSxenoarch.xeno_artifact_turfs -= T
/obj/item/device/core_sampler
name = "core sampler"
diff --git a/code/modules/xenoarcheaology/tools/tools.dm b/code/modules/xenoarcheaology/tools/tools.dm
index 8d2a4a1dedc79..e8e3a335728e8 100644
--- a/code/modules/xenoarcheaology/tools/tools.dm
+++ b/code/modules/xenoarcheaology/tools/tools.dm
@@ -57,7 +57,7 @@
var/nearestSimpleTargetDist = -1
var/turf/cur_turf = get_turf(src)
- for (var/turf/simulated/mineral/T as anything in GLOB.xeno_artifact_turfs)
+ for (var/turf/simulated/mineral/T as anything in SSxenoarch.xeno_artifact_turfs)
if(T.density && T.artifact_find)
if(T.z == cur_turf.z)
var/cur_dist = get_dist(cur_turf, T) * 2
@@ -65,16 +65,16 @@
nearestTargetDist = cur_dist + rand() * 2 - 1
nearestTargetId = T.artifact_find.artifact_id
else
- GLOB.xeno_artifact_turfs -= T
+ SSxenoarch.xeno_artifact_turfs -= T
- for(var/turf/simulated/mineral/T as anything in GLOB.xeno_digsite_turfs)
+ for(var/turf/simulated/mineral/T as anything in SSxenoarch.xeno_artifact_turfs)
if(T.density && T.finds && length(T.finds))
if(T.z == cur_turf.z)
var/cur_dist = get_dist(cur_turf, T) * 2
if(nearestSimpleTargetDist < 0 || cur_dist < nearestSimpleTargetDist)
nearestSimpleTargetDist = cur_dist + rand() * 2 - 1
else
- GLOB.xeno_digsite_turfs -= T
+ SSxenoarch.xeno_digsite_turfs -= T
if(nearestTargetDist >= 0)
to_chat(user, SPAN_NOTICE("Exotic energy detected on wavelength '[nearestTargetId]' in a radius of [nearestTargetDist]m[nearestSimpleTargetDist > 0 ? "; small anomaly detected in a radius of [nearestSimpleTargetDist]m" : ""]"))
diff --git a/code/modules/xgm/xgm_gas_data.dm b/code/modules/xgm/xgm_gas_data.dm
index 85dd1adffd7db..dd08dd01e2e51 100644
--- a/code/modules/xgm/xgm_gas_data.dm
+++ b/code/modules/xgm/xgm_gas_data.dm
@@ -54,7 +54,7 @@ var/global/datum/xgm_gas_data/gas_data
/hook/startup/proc/generateGasData()
gas_data = new
- for(var/p in (typesof(/singleton/xgm_gas) - /singleton/xgm_gas))
+ for(var/p in (subtypesof(/singleton/xgm_gas)))
var/singleton/xgm_gas/gas = new p //avoid initial() because of potential New() actions
if(gas.id in gas_data.gases)
diff --git a/code/modules/xgm/xgm_gas_mixture.dm b/code/modules/xgm/xgm_gas_mixture.dm
index 62435d5cb39db..20d08ffb604e7 100644
--- a/code/modules/xgm/xgm_gas_mixture.dm
+++ b/code/modules/xgm/xgm_gas_mixture.dm
@@ -91,12 +91,12 @@
if(!giver)
return
- if(abs(temperature-giver.temperature)>MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
+ if(abs(temperature-giver.temperature) > MINIMUM_TEMPERATURE_DELTA_TO_CONSIDER)
var/self_heat_capacity = heat_capacity()
var/giver_heat_capacity = giver.heat_capacity()
var/combined_heat_capacity = giver_heat_capacity + self_heat_capacity
if(combined_heat_capacity != 0)
- temperature = (giver.temperature*giver_heat_capacity + temperature*self_heat_capacity)/combined_heat_capacity
+ temperature = (giver.temperature * giver_heat_capacity + temperature*self_heat_capacity) / combined_heat_capacity
if((group_multiplier != 1)||(giver.group_multiplier != 1))
for(var/g in giver.gas)
@@ -346,60 +346,73 @@
//Rechecks the gas_mixture and adjusts the graphic list if needed.
//Two lists can be passed by reference if you need know specifically which graphics were added and removed.
/datum/gas_mixture/proc/check_tile_graphic(list/graphic_add = null, list/graphic_remove = null)
- for(var/obj/gas_overlay/O in graphic)
- if(istype(O, /obj/gas_overlay/heat))
+ for(var/obj/gas_overlay/gas_overlay in graphic)
+ if(istype(gas_overlay, /obj/gas_overlay/heat))
continue
- if(istype(O, /obj/gas_overlay/cold))
+
+ if(istype(gas_overlay, /obj/gas_overlay/cold))
continue
- if(gas[O.gas_id] <= gas_data.overlay_limit[O.gas_id])
- LAZYADD(graphic_remove, O)
- for(var/g in gas_data.overlay_limit)
+
+ if(gas[gas_overlay.gas_id] <= gas_data.overlay_limit[gas_overlay.gas_id])
+ LAZYADD(graphic_remove, gas_overlay)
+
+ var/should_generate_temp_overlay = FALSE
+ for(var/gas_id in gas_data.overlay_limit)
//Overlay isn't applied for this gas, check if it's valid and needs to be added.
- if(gas[g] > gas_data.overlay_limit[g])
- var/tile_overlay = get_tile_overlay(g)
+ if(gas[gas_id] > gas_data.overlay_limit[gas_id])
+ should_generate_temp_overlay = TRUE
+ var/tile_overlay = get_tile_overlay(gas_id)
if(!(tile_overlay in graphic))
LAZYADD(graphic_add, tile_overlay)
- . = 0
-
- var/heat_overlay = get_tile_overlay(GAS_HEAT)
- //If it's hot add something
- if(temperature >= CARBON_LIFEFORM_FIRE_RESISTANCE)
- if(!(heat_overlay in graphic))
- LAZYADD(graphic_add, heat_overlay)
- else if (heat_overlay in graphic)
- LAZYADD(graphic_remove, heat_overlay)
-
- var/cold_overlay = get_tile_overlay(GAS_COLD)
- if(temperature <= FOGGING_TEMPERATURE && (return_pressure() >= (ONE_ATMOSPHERE / 4)))
- if(!(cold_overlay in graphic))
- LAZYADD(graphic_add, cold_overlay)
- else if (cold_overlay in graphic)
- LAZYADD(graphic_remove, cold_overlay)
+ . = FALSE
+
+ if(should_generate_temp_overlay)
+ var/heat_overlay = get_tile_overlay(GAS_HEAT)
+ //If it's hot add something
+ if(temperature >= CARBON_LIFEFORM_FIRE_RESISTANCE)
+ if(!(heat_overlay in graphic))
+ LAZYADD(graphic_add, heat_overlay)
+ else if (heat_overlay in graphic)
+ LAZYADD(graphic_remove, heat_overlay)
+
+ var/cold_overlay = get_tile_overlay(GAS_COLD)
+ if(temperature <= FOGGING_TEMPERATURE && (return_pressure() >= (ONE_ATMOSPHERE / 4)))
+ if(!(cold_overlay in graphic))
+ LAZYADD(graphic_add, cold_overlay)
+ else if (cold_overlay in graphic)
+ LAZYADD(graphic_remove, cold_overlay)
//Apply changes
if(graphic_add && length(graphic_add))
graphic |= graphic_add
- . = 1
+ . = TRUE
+
if(graphic_remove && length(graphic_remove))
graphic -= graphic_remove
- . = 1
- if(length(graphic))
- var/pressure_mod = clamp(return_pressure() / ONE_ATMOSPHERE, 0, 2)
- for(var/obj/gas_overlay/O in graphic)
- if(istype(O, /obj/gas_overlay/heat)) //Heat based
- var/new_alpha = clamp(max(125, 255 * ((temperature - CARBON_LIFEFORM_FIRE_RESISTANCE) / CARBON_LIFEFORM_FIRE_RESISTANCE * 4)), 125, 255)
- if(new_alpha != O.alpha)
- O.update_alpha_animation(new_alpha)
- continue
- if(istype(O, /obj/gas_overlay/cold))
- var/new_alpha = clamp(max(125, 200 * (1 - ((temperature - MAX_FOG_TEMPERATURE) / (FOGGING_TEMPERATURE - MAX_FOG_TEMPERATURE)))), 125, 200)
- if(new_alpha != O.alpha)
- O.update_alpha_animation(new_alpha)
- continue
- var/concentration_mod = clamp(gas[O.gas_id] / total_moles, 0.1, 1)
- var/new_alpha = min(230, round(pressure_mod * concentration_mod * 180, 5))
- if(new_alpha != O.alpha)
- O.update_alpha_animation(new_alpha)
+ . = TRUE
+
+ if(!length(graphic))
+ return .
+
+ var/pressure_mod = clamp(return_pressure() / ONE_ATMOSPHERE, 0, 2)
+ for(var/obj/gas_overlay/overlay in graphic)
+ if(istype(overlay, /obj/gas_overlay/heat)) //Heat based
+ var/new_alpha = clamp(max(125, 255 * ((temperature - CARBON_LIFEFORM_FIRE_RESISTANCE) / CARBON_LIFEFORM_FIRE_RESISTANCE * 4)), 125, 255)
+ if(new_alpha != overlay.alpha)
+ overlay.update_alpha_animation(new_alpha)
+ continue
+
+ if(istype(overlay, /obj/gas_overlay/cold))
+ var/new_alpha = clamp(max(125, 200 * (1 - ((temperature - MAX_FOG_TEMPERATURE) / (FOGGING_TEMPERATURE - MAX_FOG_TEMPERATURE)))), 125, 200)
+ if(new_alpha != overlay.alpha)
+ overlay.update_alpha_animation(new_alpha)
+ continue
+
+ var/concentration_mod = clamp(gas[overlay.gas_id] / total_moles, 0.1, 1)
+ var/new_alpha = min(230, round(pressure_mod * concentration_mod * 180, 5))
+ if(new_alpha != overlay.alpha)
+ overlay.update_alpha_animation(new_alpha)
+
/datum/gas_mixture/proc/get_tile_overlay(gas_id)
if(!LAZYACCESS(tile_overlay_cache, gas_id))
diff --git a/code/stylesheet.dm b/code/stylesheet.dm
index 7bef0d3eab603..0631d2852231c 100644
--- a/code/stylesheet.dm
+++ b/code/stylesheet.dm
@@ -85,16 +85,16 @@ h1.alert, h2.alert {color: #000080;}
.italic {font-style: italic;}
.bold {font-weight: bold;}
-.danger {color: #ff0000; font-weight: bold;}
-.bigdanger {color: #ff0000; font-weight: bold; font-size: 115%;}
-.warning {color: #ff0000; font-style: italic;}
-.bigwarning {color: #ff0000; font-style: italic; font-size: 115%;}
+.danger {color: #dc3545; font-weight: bold;}
+.bigdanger {color: #dc3545; font-weight: bold; font-size: 115%;}
+.warning {color: #cc7606; font-weight: bold; font-style: italic;}
+.bigwarning {color: #cc7606; font-weight: bold; font-style: italic; font-size: 115%;}
.boldannounce {color: #ff0000; font-weight: bold;}
.rose {color: #ff5050;}
-.info {color: #0000cc;}
+.info {color: #9b53c4; font-style: italic;}
.debug {color: #ff00ff;}
-.notice {color: #000099;}
-.subtle {color: #000099; font-size: 75%; font-style: italic;}
+.notice {color: #0d5ef3;}
+.subtle {color: #919ca7; font-style: italic;}
.alium {color: #00ff00;}
.cult {color: #800080; font-weight: bold; font-style: italic;}
.cultannounce {color: #800080; font-style: italic; font-size: 175%;}
diff --git a/config/example/config.txt b/config/example/config.txt
index b670f8379a40e..6d1edc4963eeb 100644
--- a/config/example/config.txt
+++ b/config/example/config.txt
@@ -76,6 +76,9 @@ LOG_ATTACK
## log admin warning messages
##LOG_ADMINWARN ## Also duplicates a bunch of other messages.
+## log computer commands
+# LOG_COMPUTER_COMMANDS
+
## Log all timers on timer auto reset
# LOG_TIMERS_ON_BUCKET_RESET
diff --git a/html/changelog.html b/html/changelog.html
index 2fe85c73d9a37..33b2e4c6cf3d7 100644
--- a/html/changelog.html
+++ b/html/changelog.html
@@ -28,6 +28,317 @@ Sierra SS13
-->
+ 23.11 - 2024
+ Обновления ВашНикнейм:
+
+ Аномалии на тайле облак больше не дают им раскрываться (Больше не выйдет спрятаться от всасывающей аномалии в пучинах облак)
+ Переписана работа всасывающей гравитационной аномалии
+ Мех больше не неуявзим для обак
+ Теперь везде в коде не Zjarka, а Zharka
+ Добавил дикий самопальный детектор Гюрза для ГКК
+ Облака излучают персиковый свет
+ Трава излучает приятные зеленоватый свет
+ Переписана работа облаков
+ Выдал на склад ГКК 1 гюрзу и 3 пачки болтиков. Спасибо местному инженеру.
+ Добавил иконки Гюрзы
+
+
+ 22.11 - 2024
+ Обновления Lexanx:
+
+ Изменена форма снабжения 32
+ Добавил зарядник боргов на ГУП
+
+ Обновления Mucker:
+
+ Simple mobs will not longer endlessly attack doors when they lose their target.
+
+ Обновления PurplePineapple:
+
+ Clicking a victim with an item on disarm intent calls use_weapon(). Disarm intent/Dislocation combat for melee works again.
+
+ Обновления Spookerton:
+
+ Added a preference option for toggling run on shift.
+
+
+ 19.11 - 2024
+ Обновления Baneuus:
+
+ Теперь введение крови в золотое ядро спаунит злого моба.
+ Теперь введение крови в лазурное ядро спаунит зелье возрождения слизня.
+
+
+ 16.11 - 2024
+ Обновления Lexanx & Gfitkiit:
+
+
+ 14.11 - 2024
+ Обновления Lexanx:
+
+ Неотстыковка некоторых подов
+ Невозможность синхронизировать консоли, после их пересборки
+ Проблема с Advanced Landing в лававой экзопланете
+ Возвращена Вирусология.
+ Добавлена подпрофессия Химика - Вирусолог
+ Возвращены Вирусы
+
+ Обновления LordNest:
+
+ Добавил отображение заблокированного хранилища скафандров
+
+ Обновления awkardlyconfusedneuralnetwork:
+
+ Добавил звуки для аирлоков
+ Increases large map loading speed
+ Добавил face direction по нажатию иконки интента движения с зажатым ctrl
+
+
+ 13.11 - 2024
+ Обновления KandJX:
+
+ Добавил лестницу между бригом и мостиком.
+ Убрал шлюз в теха из комнаты капитана.
+
+
+ 12.11 - 2024
+ Обновления Builder13:
+
+ Больше нельзя получить галлюцинации от суперматерии при активных мезонных очках
+
+
+ 11.11 - 2024
+ Обновления BOT Eeshee:
+
+ Добавила перчатки, маски и изоли ЭК
+
+ Обновления Lexanx:
+
+ Баг взаимодействия синтетов
+ Некорректная зона меркшипа
+ Пофикшена кража тюрфов при взлете
+
+ Обновления Shegar:
+
+ Задник космоса не становится серым из-за летающих островов
+ Текст эндраунда мода аномалий не жирный
+
+ Обновления Teteshnik:
+
+ Переименовал спавнеры безбилетников
+
+
+ 10.11 - 2024
+ Обновления Builder13:
+
+ Радио при событии пси сигнала больше не должно воздействовать через стены
+
+ Обновления Mucker:
+
+ You can now "hold" a humanoid mobs' hand when pulling them and targeting one of their hands.
+ Antag latespawn scaling no longer considers players that aren't alive or are offship when deciding maximum antags.
+
+ Обновления Shegar:
+
+ Трамплин теперь не всегда кидает на 5 тайтлов.
+ Генератору аномок теперь не мешает railings
+ Лава больше не может сжигать артефакты
+ БСД пролив теперь не спавнит аномки в космосе
+ БСД теперь удаляет аномки после окончания ивента (Должен по крайней мере)
+ Мех при таране цели тоже делает шаг, от чего меха теперь невозможно заблочить не мехом/адхерантом/гбсом
+ Добавил глыбы на планету лёд. Красиво!
+ Детектор не какает обработкой без нужды, теперь его нужно включать.(Контрол + ЛКМ)
+ Теперь аномалии при осмотре детектером обнаруживаются полностью, а не частично (От чего шансы обнаружения довольно таки упали)
+ Полность переписана система влияния артефактов на определённые события с персонажами, добавлены новые эффекты. Усилена важность и польза контейнеров артефактов из-за этого.
+ Добавлена анимация уворота при паррировании.
+ Переписана система процессинга артефактов на персонажа. Она должна при любых взаимодействиях понимать, кто текущий носитель и влиять на него.
+ Добавил СНЕГ на ледяную планету с эффектом на экране и звуком.
+ Добавлен Z скан уровня для детектора
+ Добавил скалолазанье на планету ЛЁД. Помогайте друг другу, используйте кирки, готовьтесь физически и преодолевайте горы.
+ Добавлен установщик маячков для более комфортного построения пути на планетах.
+ Всасывающая гравианомалия изменена сопротивляться им стало сложнее, так как и задумывал разработчик, но в то же время, вы можете помогать своим друзьям выбираться из неё. Файнд аут ин гейм!
+ Логика электр подтипа Тесла переписана, теперь вся планета не сможет одновременно бахать
+ Достаточно высокий уровень науки позволит определять тип аномалии
+ Спавн аномалий от больших артефактов выведен из ротации.
+ Спрайты для артефактов, погода
+ Выдал Деплоер на склад ЭК. Детектор, мешочек и деплоер на склад шахтёров.
+ Исправлено описание детектора аномалий
+ Погода Буран, может подлагивать клиент. Пишите чё каво.
+ Сильно увеличен размер планет. Спавнит так же, как и от админки.
+ Добавлена аномальная планета: Летающие острова.
+ Сильно увеличил расстояния насёра аномалиями при БСД проливе, увеличено количество аномок.
+ Ослаблено СТАН влияние электры на жертву
+ Добавлена возможность от атлетики сопротивляться влиянию электры
+ Нёрф энергощитов меха, генерация тепла при получении урона увеличена в 2 раза
+ Добавил трамплин в билдер админов.
+
+ Обновления Spookerton:
+
+ Corrected Masculinity.
+
+ Обновления The_Spanish_1nquisition:
+
+ Tornakov took a marker to his poster.
+
+
+ 09.11 - 2024
+ Обновления Shegar:
+
+ Минификсик для гитхаба
+
+
+ 08.11 - 2024
+ Обновления Lexanx:
+
+ Теперь челноки/шаттлы способные летать в космосе и совершать посадки,
+
+ Обновления RocheHendson:
+
+ Seedship теперь имеет должности для захода
+ Seedship командование теперь может поставить имя своему наследию
+
+
+ 07.11 - 2024
+ Обновления Mucker:
+
+ Adjusted the spawn target for merc and raider to 3, and traitor to 1.
+
+ Обновления PsiOmegaDelta:
+
+ Select loadout items again display an extended description when selected for use.
+
+ Обновления Ryan180602:
+
+ Wristwatches show the date correctly.
+ Posibrains can be fixed outside chassis.
+ Removes the preset pronoun badge types, people can now customise them to their wish.
+ Adds another entry for the pride pins. Letting people take two now.
+ Throat-slit timer changed from 3.24 ~ 0.8! seconds to 3.75 ~ 2.25. On success, the user cannot act again for an extra second.
+
+ Обновления sdtwbaj:
+
+ Flora can be cut away with a hatchet.
+ Trees can be destroyed, and drop wood!
+ woodcutting.ogg from Polaris
+ tree stumps from Polaris
+
+ Обновления sick trigger:
+
+ Orders from supply now record what time the requst was made
+
+ Обновления sick-trigger:
+
+ Fixed being unable to spawn on landed colony ship.
+
+
+ 06.11 - 2024
+ Обновления Baneuus:
+
+ Резоми хихикают как резоми, а не как люди.
+ Вернул звук вздоха резоми.
+ Повысил температуру, которая для резоми считается "комфортной" до 21.6 С*
+ Усилил найтвижн резоми.
+ Удалил мерков из спауна при режиме революции
+ Теперь sechud lenses резоми работают нормально
+
+ Обновления Builder13:
+
+ Откат трех секунд подсистемы машин
+
+ Обновления SierraKomodo:
+
+ Shuttle control consoles can no longer be synced to shuttles if not actually on the shuttle.
+ Regular non-overmap shuttle control consoles will no longer function on overmap shuttles, and vice-versa.
+ Shuttle control consoles now automatically sync to the shuttle they're built on when created, instead of needing to be set by multitooling the board before creation.
+ Shuttle control consoles that are not properly connected to a shuttle now have a new error screen sprite.
+
+ Обновления Teteshnik:
+
+ Добавил некоторым расам возможность стать безбилетником
+ Поменял название безбилетника на неизвестного сделано угоду айди
+
+ Обновления rootoo807:
+
+ Fixes broken sprites / adds missing sprites for armbands, insulated gloves, soft caps, blood masks on GAS. GAS can no longer wear overalls or wizard voidsuit [snakes don't have legs for pants :( ].
+ Adds missing sprite for flipped veteran's cap.
+
+
+ 05.11 - 2024
+ Обновления awkardlyconfusedneuralnetwork:
+
+
+ 04.11 - 2024
+ Обновления Builder13:
+
+ Добавлена кнопка add trait в создание персонажа. Сейчас там есть опции только для регенерации Унати.
+
+ Обновления NinjaPikachushka:
+
+ Худ-Кнопки мага перестали сбегать.
+
+ Обновления totalynotglist:
+
+ Экспериментальная оптимизация подсистемы Machines на 33.3%.
+
+ Обновления ВашНикнейм:
+
+ Экран меха обновляется при переключении Power, выключении от перегрева, при выбивании сенсора.
+ Если у меха выбита грудь, то раз в 20-40 секунд мех получает полный перегрев.
+
+
+ 03.11 - 2024
+ Обновления Builder13:
+
+ Добавлена единственная возможность чинить переломы для Адхерантов - через минеральные ванны. Процедура может быть длительной.
+ Генокрад больше не утрачивает навыки от профессии при получении роли
+ Возвращены шансы на пси латентность при заходе в раунд
+ Пси сигнал возвращен в ротацию событий
+ Возвращена переменная stop_sight_update для мобов, чтобы исключить обновление зрения при ее включении
+
+ Обновления Gaaxer, awkardlyconfusedneuralnetwork:
+
+ Инит ксеноархиологии теперь быстрее
+
+ Обновления Gaxeer, awkardlyconfusedneuralnetwork:
+
+ Починил обновление оверлея газов
+ Починил то, что рычаг на конвейере проходит все объекты в мире
+
+ Обновления KOJIECO:
+
+ Добавил скрелльскую одежду для всех каст от Failu.
+
+ Обновления Lexanx:
+
+ Новые фуллскрин оверлеи повреждений ИПС и Адхерентов и ППТ
+ Предмет(Explosion Wather) для получения научных очков из взрывов снова работает
+ Джетпаки в ветке исследований РнД
+ Кинетический сборщик в производстве РнД
+ Платы мусоропереработчиков в ветке исследований РнД
+ Компот (water = 2, berry = 1, apple = 1, pear = 1)
+ Возвращены рецепты отвердевания золота и серебра.
+ Плата консоли трафика в ветке исследований РнД.
+
+ Обновления Neonvolt:
+
+ Исправлены дополнительные пропавшие спрайты Восхождения и недоработки связанные с их расами
+
+ Обновления Teteshnik:
+
+ Поставил возможность изменения/добавления хоткея для фейс дира.
+ Новый флаг для профессий позволяющий делать профессию только возможным раундстартом
+ Добавил безбилетников
+
+ Обновления awkardlyconfusedneuralnetwork:
+
+ Инпут теперь обрабатывается раньше других сабсистем, должно повысить плавность игры.
+ Ускорил инит, да.
+
+
23.10 - 2024
Обновления Builder13:
@@ -216,78 +527,6 @@ Обновления Vipo24:
Кислота вновь очень больно обжигает, как было раньше
-
- 19.09 - 2024
- Обновления Teteshnik:
-
- Пофиксил лодаут ниндзи, так-же удалил костыль.
- Портировал букеты в билд
-
-
- 16.09 - 2024
- Обновления Builder13:
-
- Портировано отображение для скана контактов у сенсоров
- Портирована экстренная кнопка бедствия
-
-
- 15.09 - 2024
- Обновления ВашНикнейм:
-
- Выдал детекторы для ЭК
-
-
- 14.09 - 2024
- Обновления Builder13:
-
- Добавлена возможность вставки и вытаскивания предмета из интегральной платы без ее удаления из корпуса
- Добавлены интегральные платы list pick, image comparsion scanner, floor magnet.
- Сделаны дополнения для плат intelligence control circuit и examiner
-
- Обновления ВашНикнейм:
-
- Сбор артефактов в мехе запрещён
- Генерация артефактов и аномалий жёстко ограничена математикой.
- Сбор артефактов теперь работает так, как я и задумывал
- Добавил планетарную генерацию аномалий (по всей планете), зависящая от типа планеты
- URM (Universal Research Machine) - новое устройство на петрове для анализа артов(мелких).
- Добавлена ледяная планета
- Добавил спрайты маячков, детектора, URM
- Выдал ЭК коллекторы,маячки и новые детекторы. Колония, воксы, мусорщики - получили болтики.
- Изменил русский на английский в аномалиях там, где это неуместно
- Дал билдер аномалий в билдер с возможностью тонкой настройки
-
-
- 11.09 - 2024
- Обновления Teteshnik:
-
- Удалил трэйси
- Портирован халат робототехника с инфинити.
-
-
- 06.09 - 2024
- Обновления ВашНикнейм:
-
- Ремап карты ниндзи, он получил сауну, додзе, озерцо и пару комнат. В целом, перенос с инфинити.
-
-
- 04.09 - 2024
- Обновления Builder13:
-
- Wizard retains all the spells in the hud upon changing/getting body.
- It is now possible to spawn wizard packages (examples: scrying orb, mastercrafted armor).
- Fixes for some of the spells, so they are castable again.
-
- Обновления Gy1ta23:
-
- you can now select photographs in loadout with changeable descriptions
-
-
- 01.09 - 2024
- Обновления Shegar:
-
- Возвращает map_upload
-
|