From e753c1ad1483e6329e057d273aac5c218b518ce7 Mon Sep 17 00:00:00 2001 From: Ghommie <42542238+Ghommie@users.noreply.github.com> Date: Tue, 14 Apr 2020 02:20:19 +0200 Subject: [PATCH 01/55] Fixed a little peeve with random bodies. --- code/__HELPERS/mobs.dm | 12 +++++++++--- code/datums/dna.dm | 2 +- code/modules/antagonists/bloodsucker/powers/veil.dm | 2 +- .../modules/mob/dead/new_player/preferences_setup.dm | 6 +----- 4 files changed, 12 insertions(+), 10 deletions(-) diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm index febd333578..48c7cab6dc 100644 --- a/code/__HELPERS/mobs.dm +++ b/code/__HELPERS/mobs.dm @@ -47,7 +47,7 @@ init_sprite_accessory_subtypes(/datum/sprite_accessory/underwear/socks, GLOB.socks_list) return pick(GLOB.socks_list) -/proc/random_features(intendedspecies) +/proc/random_features(intendedspecies, intended_gender) if(!GLOB.tails_list_human.len) init_sprite_accessory_subtypes(/datum/sprite_accessory/tails/human, GLOB.tails_list_human) if(!GLOB.tails_list_lizard.len) @@ -149,7 +149,13 @@ var/color2 = random_short_color() var/color3 = random_short_color() - //CIT CHANGE - changes this entire return to support cit's snowflake parts + var/body_model = MALE + switch(intended_gender) + if(MALE || FEMALE) + body_model = intended_gender + if(PLURAL) + body_model = pick(MALE,FEMALE) + return(list( "mcolor" = color1, "mcolor2" = color2, @@ -209,7 +215,7 @@ "ipc_antenna" = "None", "flavor_text" = "", "meat_type" = "Mammalian", - "body_model" = MALE + "body_model" = body_model )) /proc/random_hair_style(gender) diff --git a/code/datums/dna.dm b/code/datums/dna.dm index 95b45b6bc2..2fffde8271 100644 --- a/code/datums/dna.dm +++ b/code/datums/dna.dm @@ -302,7 +302,7 @@ unique_enzymes = generate_unique_enzymes() uni_identity = generate_uni_identity() generate_dna_blocks() - features = random_features(species?.id) + features = random_features(species?.id, holder?.gender) /datum/dna/stored //subtype used by brain mob's stored_dna diff --git a/code/modules/antagonists/bloodsucker/powers/veil.dm b/code/modules/antagonists/bloodsucker/powers/veil.dm index ecb0611940..3b722c50b5 100644 --- a/code/modules/antagonists/bloodsucker/powers/veil.dm +++ b/code/modules/antagonists/bloodsucker/powers/veil.dm @@ -92,7 +92,7 @@ H.socks = random_socks(H.gender) //H.eye_color = random_eye_color() REMOVE_TRAIT(H, TRAIT_DISFIGURED, null) // - H.dna.features = random_features(H.dna.species?.id) + H.dna.features = random_features(H.dna.species?.id, H.gender) // Apply Appearance H.update_body(TRUE) // Outfit and underwear, also body and privates. diff --git a/code/modules/mob/dead/new_player/preferences_setup.dm b/code/modules/mob/dead/new_player/preferences_setup.dm index a7fdf2d914..54921e9112 100644 --- a/code/modules/mob/dead/new_player/preferences_setup.dm +++ b/code/modules/mob/dead/new_player/preferences_setup.dm @@ -22,11 +22,7 @@ if(!pref_species) var/rando_race = pick(GLOB.roundstart_races) pref_species = new rando_race() - features = random_features(pref_species?.id) - if(gender == MALE || gender != FEMALE) - features["body_model"] = gender - else if(gender == PLURAL) - features["body_model"] = pick(MALE,FEMALE) + features = random_features(pref_species?.id, gender) age = rand(AGE_MIN,AGE_MAX) /datum/preferences/proc/update_preview_icon(equip_job = TRUE) From dabe56fea1012f9d815ee4f0c550e4920b56e3a0 Mon Sep 17 00:00:00 2001 From: Putnam Date: Mon, 13 Apr 2020 17:30:49 -0700 Subject: [PATCH 02/55] Experimental major optimization --- code/controllers/subsystem/icon_smooth.dm | 1 - code/controllers/subsystem/lighting.dm | 3 +-- code/controllers/subsystem/processing/flightpacks.dm | 2 +- 3 files changed, 2 insertions(+), 4 deletions(-) diff --git a/code/controllers/subsystem/icon_smooth.dm b/code/controllers/subsystem/icon_smooth.dm index 6f4040299a..bd676bacec 100644 --- a/code/controllers/subsystem/icon_smooth.dm +++ b/code/controllers/subsystem/icon_smooth.dm @@ -3,7 +3,6 @@ SUBSYSTEM_DEF(icon_smooth) init_order = INIT_ORDER_ICON_SMOOTHING wait = 1 priority = FIRE_PRIOTITY_SMOOTHING - flags = SS_TICKER var/list/smooth_queue = list() var/list/deferred = list() diff --git a/code/controllers/subsystem/lighting.dm b/code/controllers/subsystem/lighting.dm index 12b467b624..c6e6a84bcf 100644 --- a/code/controllers/subsystem/lighting.dm +++ b/code/controllers/subsystem/lighting.dm @@ -6,7 +6,6 @@ SUBSYSTEM_DEF(lighting) name = "Lighting" wait = 2 init_order = INIT_ORDER_LIGHTING - flags = SS_TICKER /datum/controller/subsystem/lighting/stat_entry() ..("L:[GLOB.lighting_update_lights.len]|C:[GLOB.lighting_update_corners.len]|O:[GLOB.lighting_update_objects.len]") @@ -85,4 +84,4 @@ SUBSYSTEM_DEF(lighting) /datum/controller/subsystem/lighting/Recover() initialized = SSlighting.initialized - ..() \ No newline at end of file + ..() diff --git a/code/controllers/subsystem/processing/flightpacks.dm b/code/controllers/subsystem/processing/flightpacks.dm index a462e2b645..fc994d5061 100644 --- a/code/controllers/subsystem/processing/flightpacks.dm +++ b/code/controllers/subsystem/processing/flightpacks.dm @@ -3,7 +3,7 @@ PROCESSING_SUBSYSTEM_DEF(flightpacks) priority = FIRE_PRIORITY_FLIGHTPACKS wait = 2 stat_tag = "FM" - flags = SS_NO_INIT|SS_TICKER|SS_KEEP_TIMING + flags = SS_NO_INIT|SS_KEEP_TIMING var/flightsuit_processing = FLIGHTSUIT_PROCESSING_FULL From 3543da036b8f963a7e9b70509e8c2ff23bbb1a56 Mon Sep 17 00:00:00 2001 From: Putnam Date: Mon, 13 Apr 2020 17:37:03 -0700 Subject: [PATCH 03/55] actually i don't know what this does --- code/controllers/subsystem/icon_smooth.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/controllers/subsystem/icon_smooth.dm b/code/controllers/subsystem/icon_smooth.dm index bd676bacec..6f4040299a 100644 --- a/code/controllers/subsystem/icon_smooth.dm +++ b/code/controllers/subsystem/icon_smooth.dm @@ -3,6 +3,7 @@ SUBSYSTEM_DEF(icon_smooth) init_order = INIT_ORDER_ICON_SMOOTHING wait = 1 priority = FIRE_PRIOTITY_SMOOTHING + flags = SS_TICKER var/list/smooth_queue = list() var/list/deferred = list() From a57828703ed2a5bdf3d55ef9091e85a96e4aa52d Mon Sep 17 00:00:00 2001 From: Ghom <42542238+Ghommie@users.noreply.github.com> Date: Tue, 14 Apr 2020 16:09:31 +0200 Subject: [PATCH 04/55] Update mobs.dm --- code/__HELPERS/mobs.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/__HELPERS/mobs.dm b/code/__HELPERS/mobs.dm index 48c7cab6dc..7a62d7ba1c 100644 --- a/code/__HELPERS/mobs.dm +++ b/code/__HELPERS/mobs.dm @@ -151,7 +151,7 @@ var/body_model = MALE switch(intended_gender) - if(MALE || FEMALE) + if(MALE, FEMALE) body_model = intended_gender if(PLURAL) body_model = pick(MALE,FEMALE) From 4703af111dd88aab40622ce4dabf2ad7f2e04f19 Mon Sep 17 00:00:00 2001 From: Putnam Date: Tue, 14 Apr 2020 10:12:17 -0700 Subject: [PATCH 05/55] actually let's just delete this file --- .../subsystem/processing/flightpacks.dm | 25 ------------------- 1 file changed, 25 deletions(-) delete mode 100644 code/controllers/subsystem/processing/flightpacks.dm diff --git a/code/controllers/subsystem/processing/flightpacks.dm b/code/controllers/subsystem/processing/flightpacks.dm deleted file mode 100644 index fc994d5061..0000000000 --- a/code/controllers/subsystem/processing/flightpacks.dm +++ /dev/null @@ -1,25 +0,0 @@ -PROCESSING_SUBSYSTEM_DEF(flightpacks) - name = "Flightpack Movement" - priority = FIRE_PRIORITY_FLIGHTPACKS - wait = 2 - stat_tag = "FM" - flags = SS_NO_INIT|SS_KEEP_TIMING - - var/flightsuit_processing = FLIGHTSUIT_PROCESSING_FULL - -/datum/controller/subsystem/processing/flightpacks/Initialize() - sync_flightsuit_processing() - -/datum/controller/subsystem/processing/flightpacks/vv_edit_var(var_name, var_value) - ..() - switch(var_name) - if("flightsuit_processing") - sync_flightsuit_processing() - -/datum/controller/subsystem/processing/flightpacks/proc/sync_flightsuit_processing() - for(var/obj/item/flightpack/FP in processing) - FP.sync_processing(src) - if(flightsuit_processing == FLIGHTSUIT_PROCESSING_NONE) //Don't even bother firing. - can_fire = FALSE - else - can_fire = TRUE From beb34321e7ebcfdd3165ec166eaa82687c8d57f2 Mon Sep 17 00:00:00 2001 From: Ghommie <42542238+Ghommie@users.noreply.github.com> Date: Sat, 18 Apr 2020 17:53:00 +0200 Subject: [PATCH 06/55] nerf to biogenerator upgrades and purge of inorganic glass bottles designs. --- .../food_and_drinks/drinks/drinks/bottle.dm | 10 +++ code/modules/hydroponics/biogenerator.dm | 29 ++++--- .../research/designs/biogenerator_designs.dm | 74 ++++++------------ icons/obj/drinks.dmi | Bin 102685 -> 102703 bytes 4 files changed, 49 insertions(+), 64 deletions(-) diff --git a/code/modules/food_and_drinks/drinks/drinks/bottle.dm b/code/modules/food_and_drinks/drinks/drinks/bottle.dm index 95b9f92873..ccce186304 100644 --- a/code/modules/food_and_drinks/drinks/drinks/bottle.dm +++ b/code/modules/food_and_drinks/drinks/drinks/bottle.dm @@ -396,6 +396,16 @@ list_reagents = list(/datum/reagent/consumable/orangejuice = 100) foodtype = FRUIT| BREAKFAST +/obj/item/reagent_containers/food/drinks/bottle/bio_carton + name = "small carton box" + desc = "A small biodegradable carton box made from plant biomatter." + icon_state = "eco_box" + item_state = "carton" + lefthand_file = 'icons/mob/inhands/equipment/kitchen_lefthand.dmi' + righthand_file = 'icons/mob/inhands/equipment/kitchen_righthand.dmi' + volume = 50 + isGlass = FALSE + /obj/item/reagent_containers/food/drinks/bottle/cream name = "milk cream" desc = "It's cream. Made from milk. What else did you think you'd find in there?" diff --git a/code/modules/hydroponics/biogenerator.dm b/code/modules/hydroponics/biogenerator.dm index 6a3fd56208..4edc0e8a13 100644 --- a/code/modules/hydroponics/biogenerator.dm +++ b/code/modules/hydroponics/biogenerator.dm @@ -40,14 +40,14 @@ updateUsrDialog() /obj/machinery/biogenerator/RefreshParts() - var/E = 0 - var/P = 0 - var/max_storage = 40 + var/E = 0.5 + var/P = 0.5 + var/max_storage = 20 for(var/obj/item/stock_parts/matter_bin/B in component_parts) - P += B.rating - max_storage = 40 * B.rating + P += B.rating * 0.5 + max_storage = max(20 * B.rating, max_storage) for(var/obj/item/stock_parts/manipulator/M in component_parts) - E += M.rating + E += M.rating * 0.5 efficiency = E productivity = P max_items = max_storage @@ -196,7 +196,7 @@ dat += "x5" if(ispath(D.build_path, /obj/item/stack)) dat += "x10" - dat += "([D.materials[SSmaterials.GetMaterialRef(/datum/material/biomass)]/efficiency])
" + dat += "([round(D.materials[SSmaterials.GetMaterialRef(/datum/material/biomass)]/efficiency)])
" dat += "" else dat += "
No container inside, please insert container.
" @@ -214,12 +214,16 @@ to_chat(usr, "The biogenerator is in the process of working.") return var/S = 0 + var/total = 0 for(var/obj/item/reagent_containers/food/snacks/grown/I in contents) S += 5 - if(I.reagents.get_reagent_amount(/datum/reagent/consumable/nutriment) < 0.1) - points += 1*productivity - else points += I.reagents.get_reagent_amount(/datum/reagent/consumable/nutriment)*10*productivity + var/nutri_amount = I.reagents.get_reagent_amount(/datum/reagent/consumable/nutriment) + if(nutri_amount < 0.1) + total += 1*productivity + else + total += nutri_amount*10*productivity qdel(I) + points += round(total) if(S) processing = TRUE update_icon() @@ -235,12 +239,13 @@ /obj/machinery/biogenerator/proc/check_cost(list/materials, multiplier = 1, remove_points = TRUE) if(materials.len != 1 || materials[1] != SSmaterials.GetMaterialRef(/datum/material/biomass)) return FALSE - if (materials[SSmaterials.GetMaterialRef(/datum/material/biomass)]*multiplier/efficiency > points) + var/cost = round(materials[SSmaterials.GetMaterialRef(/datum/material/biomass)]*multiplier/efficiency) + if (cost > points) menustat = "nopoints" return FALSE else if(remove_points) - points -= materials[SSmaterials.GetMaterialRef(/datum/material/biomass)]*multiplier/efficiency + points -= cost update_icon() updateUsrDialog() return TRUE diff --git a/code/modules/research/designs/biogenerator_designs.dm b/code/modules/research/designs/biogenerator_designs.dm index e82dffbe07..c4e95dbcbb 100644 --- a/code/modules/research/designs/biogenerator_designs.dm +++ b/code/modules/research/designs/biogenerator_designs.dm @@ -2,6 +2,9 @@ ///////Biogenerator Designs /////// /////////////////////////////////// +//Please be wary of not adding inorganic items to the results such as glass bottles and metal. +//since they kind of defeat the design of this feature. + /datum/design/milk name = "10u Milk" id = "milk" @@ -18,22 +21,6 @@ make_reagents = list(/datum/reagent/consumable/cream = 10) category = list("initial","Food") -/datum/design/milk_carton - name = "Milk Carton" - id = "milk_carton" - build_type = BIOGENERATOR - materials = list(/datum/material/biomass = 100) - build_path = /obj/item/reagent_containers/food/condiment/milk - category = list("initial","Food") - -/datum/design/cream_carton - name = "Cream Carton" - id = "cream_carton" - build_type = BIOGENERATOR - materials = list(/datum/material/biomass = 300) - build_path = /obj/item/reagent_containers/food/drinks/bottle/cream - category = list("initial","Food") - /datum/design/black_pepper name = "10u Black Pepper" id = "black_pepper" @@ -42,15 +29,6 @@ make_reagents = list(/datum/reagent/consumable/blackpepper = 10) category = list("initial","Food") -/datum/design/pepper_mill - name = "Pepper Mill" - id = "pepper_mill" - build_type = BIOGENERATOR - materials = list(/datum/material/biomass = 50) - build_path = /obj/item/reagent_containers/food/condiment/peppermill - make_reagents = list() - category = list("initial","Food") - /datum/design/enzyme name = "10u Universal Enzyme" id = "enzyme" @@ -59,14 +37,6 @@ make_reagents = list(/datum/reagent/consumable/enzyme = 10) category = list("initial","Food") -/datum/design/flour_sack - name = "Flour Sack" - id = "flour_sack" - build_type = BIOGENERATOR - materials = list(/datum/material/biomass = 150) - build_path = /obj/item/reagent_containers/food/condiment/flour - category = list("initial","Food") - /datum/design/monkey_cube name = "Monkey Cube" id = "mcube" @@ -84,43 +54,43 @@ category = list("initial", "Food") /datum/design/ez_nut - name = "E-Z Nutrient" + name = "10u E-Z Nutrient" id = "ez_nut" build_type = BIOGENERATOR - materials = list(/datum/material/biomass = 10) - build_path = /obj/item/reagent_containers/glass/bottle/nutrient/ez + materials = list(/datum/material/biomass = 2) + make_reagents = list(/datum/reagent/plantnutriment/eznutriment = 10) category = list("initial","Botany Chemicals") /datum/design/l4z_nut - name = "Left 4 Zed" + name = "10u Left 4 Zed" id = "l4z_nut" build_type = BIOGENERATOR - materials = list(/datum/material/biomass = 20) - build_path = /obj/item/reagent_containers/glass/bottle/nutrient/l4z + materials = list(/datum/material/biomass = 4) + make_reagents = list(/datum/reagent/plantnutriment/left4zednutriment = 10) category = list("initial","Botany Chemicals") /datum/design/rh_nut - name = "Robust Harvest" + name = "10u Robust Harvest" id = "rh_nut" build_type = BIOGENERATOR - materials = list(/datum/material/biomass = 25) - build_path = /obj/item/reagent_containers/glass/bottle/nutrient/rh + materials = list(/datum/material/biomass = 5) + make_reagents = list(/datum/reagent/plantnutriment/robustharvestnutriment = 10) category = list("initial","Botany Chemicals") /datum/design/weed_killer name = "Weed Killer" id = "weed_killer" build_type = BIOGENERATOR - materials = list(/datum/material/biomass = 50) - build_path = /obj/item/reagent_containers/glass/bottle/killer/weedkiller + materials = list(/datum/material/biomass = 10) + make_reagents = list(/datum/reagent/toxin/plantbgone/weedkiller = 10) category = list("initial","Botany Chemicals") /datum/design/pest_spray name = "Pest Killer" id = "pest_spray" build_type = BIOGENERATOR - materials = list(/datum/material/biomass = 50) - build_path = /obj/item/reagent_containers/glass/bottle/killer/pestkiller + materials = list(/datum/material/biomass = 10) + make_reagents = list(/datum/reagent/toxin/pestkiller = 10) category = list("initial","Botany Chemicals") /datum/design/ammonia @@ -139,13 +109,13 @@ make_reagents = list(/datum/reagent/saltpetre = 10) category = list("initial","Botany Chemicals") -/datum/design/botany_bottle - name = "Empty Bottle" - id = "botany_bottle" +/datum/design/empty_carton + name = "Small Empty Carton Box" + id = "empty_carton" build_type = BIOGENERATOR - materials = list(/datum/material/biomass = 5) - build_path = /obj/item/reagent_containers/glass/bottle/nutrient/empty - category = list("initial", "Botany Chemicals") + materials = list(/datum/material/biomass = 15) + build_path = /obj/item/reagent_containers/food/drinks/bottle/bio_carton + category = list("initial", "Organic Materials") /datum/design/cloth name = "Roll of Cloth" diff --git a/icons/obj/drinks.dmi b/icons/obj/drinks.dmi index 07e7bf1da88bb6c08316a613720f6ae3b1a9ef14..d0be75150a3970c5043c51f2567e6d30281c40d5 100644 GIT binary patch delta 82401 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 OPebLYa Date: Sat, 18 Apr 2020 17:55:34 +0200 Subject: [PATCH 07/55] Comment. --- code/modules/research/designs/biogenerator_designs.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/research/designs/biogenerator_designs.dm b/code/modules/research/designs/biogenerator_designs.dm index c4e95dbcbb..cb8934577b 100644 --- a/code/modules/research/designs/biogenerator_designs.dm +++ b/code/modules/research/designs/biogenerator_designs.dm @@ -2,8 +2,8 @@ ///////Biogenerator Designs /////// /////////////////////////////////// -//Please be wary of not adding inorganic items to the results such as glass bottles and metal. -//since they kind of defeat the design of this feature. +//Please be wary to not add inorganic items to the results such as glass bottles and metal. +//as they kind of defeat the design of this feature. /datum/design/milk name = "10u Milk" From 0663a3f01c64c5172bad320131315d368005e88c Mon Sep 17 00:00:00 2001 From: Ghommie <42542238+Ghommie@users.noreply.github.com> Date: Sat, 18 Apr 2020 18:18:22 +0200 Subject: [PATCH 08/55] ceiling to avoid infinity ez nutriment. --- code/modules/hydroponics/biogenerator.dm | 4 ++-- code/modules/research/designs/biogenerator_designs.dm | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/code/modules/hydroponics/biogenerator.dm b/code/modules/hydroponics/biogenerator.dm index 4edc0e8a13..52a050589f 100644 --- a/code/modules/hydroponics/biogenerator.dm +++ b/code/modules/hydroponics/biogenerator.dm @@ -196,7 +196,7 @@ dat += "x5" if(ispath(D.build_path, /obj/item/stack)) dat += "x10" - dat += "([round(D.materials[SSmaterials.GetMaterialRef(/datum/material/biomass)]/efficiency)])
" + dat += "([CEILING(D.materials[SSmaterials.GetMaterialRef(/datum/material/biomass)]/efficiency, 1)])
" dat += "" else dat += "
No container inside, please insert container.
" @@ -239,7 +239,7 @@ /obj/machinery/biogenerator/proc/check_cost(list/materials, multiplier = 1, remove_points = TRUE) if(materials.len != 1 || materials[1] != SSmaterials.GetMaterialRef(/datum/material/biomass)) return FALSE - var/cost = round(materials[SSmaterials.GetMaterialRef(/datum/material/biomass)]*multiplier/efficiency) + var/cost = CEILING(materials[SSmaterials.GetMaterialRef(/datum/material/biomass)]*multiplier/efficiency, 1) if (cost > points) menustat = "nopoints" return FALSE diff --git a/code/modules/research/designs/biogenerator_designs.dm b/code/modules/research/designs/biogenerator_designs.dm index cb8934577b..f6355074b9 100644 --- a/code/modules/research/designs/biogenerator_designs.dm +++ b/code/modules/research/designs/biogenerator_designs.dm @@ -2,7 +2,7 @@ ///////Biogenerator Designs /////// /////////////////////////////////// -//Please be wary to not add inorganic items to the results such as glass bottles and metal. +//Please be wary to not add inorganic items to the results such as generic glass bottles and metal. //as they kind of defeat the design of this feature. /datum/design/milk From f498fb106a54ed1e21de80c52d0c65ff6bd5db1b Mon Sep 17 00:00:00 2001 From: MrJWhit <48370570+MrJWhit@users.noreply.github.com> Date: Mon, 20 Apr 2020 05:25:20 -0400 Subject: [PATCH 09/55] Update BoxStation.dmm Aaaaah --- _maps/map_files/BoxStation/BoxStation.dmm | 1564 ++++++++++----------- 1 file changed, 722 insertions(+), 842 deletions(-) diff --git a/_maps/map_files/BoxStation/BoxStation.dmm b/_maps/map_files/BoxStation/BoxStation.dmm index e0dfa2ab74..2cff435296 100644 --- a/_maps/map_files/BoxStation/BoxStation.dmm +++ b/_maps/map_files/BoxStation/BoxStation.dmm @@ -3098,7 +3098,10 @@ /turf/open/floor/plating, /area/maintenance/fore/secondary) "agd" = ( -/obj/machinery/atmospherics/pipe/manifold4w/general/visible, +/obj/item/radio/intercom{ + name = "Station Intercom (General)"; + pixel_x = -30 + }, /turf/open/floor/plasteel, /area/engine/atmos) "age" = ( @@ -6032,7 +6035,7 @@ /turf/open/floor/plasteel, /area/security/brig) "alk" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/visible{ +/obj/structure/chair/office/dark{ dir = 1 }, /turf/open/floor/plasteel, @@ -6346,10 +6349,13 @@ /turf/closed/wall, /area/maintenance/port/fore) "alX" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/visible{ - dir = 4 +/obj/machinery/button/door{ + id = "atmos"; + name = "Atmospherics Lockdown"; + pixel_x = 24; + pixel_y = 4; + req_access_txt = "24" }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, /turf/open/floor/plasteel, /area/engine/atmos) "alY" = ( @@ -7469,10 +7475,10 @@ /turf/open/floor/plating, /area/security/warden) "apa" = ( -/obj/machinery/atmospherics/pipe/simple/green/visible{ +/obj/machinery/atmospherics/pipe/manifold/cyan/visible{ dir = 4 }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, +/obj/machinery/meter, /turf/open/floor/plasteel, /area/engine/atmos) "apc" = ( @@ -7700,7 +7706,9 @@ /area/maintenance/starboard/fore) "apF" = ( /obj/effect/spawner/structure/window/reinforced, -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, +/obj/machinery/atmospherics/pipe/simple/cyan/visible{ + dir = 5 + }, /turf/open/floor/plating, /area/engine/atmos) "apG" = ( @@ -7730,12 +7738,11 @@ /turf/open/floor/plasteel/showroomfloor, /area/security/warden) "apI" = ( -/obj/machinery/atmospherics/components/unary/relief_valve/atmos/atmos_waste{ - dir = 1 +/obj/structure/disposalpipe/segment{ + dir = 5 }, -/obj/structure/lattice/catwalk, -/turf/open/space, -/area/engine/atmos) +/turf/open/floor/plasteel, +/area/hallway/primary/aft) "apJ" = ( /turf/closed/wall, /area/construction/mining/aux_base) @@ -37755,33 +37762,32 @@ /obj/effect/turf_decal/tile/yellow{ dir = 4 }, -/turf/open/floor/plasteel/checker, +/turf/open/floor/plasteel, /area/hallway/primary/aft) "bLI" = ( /obj/structure/disposalpipe/segment, /turf/open/floor/plasteel, /area/hallway/primary/aft) "bLJ" = ( -/obj/machinery/portable_atmospherics/canister/air, -/obj/effect/turf_decal/bot, +/obj/machinery/computer/atmos_control, /turf/open/floor/plasteel, /area/engine/atmos) "bLK" = ( /turf/closed/wall/r_wall, /area/engine/atmos) "bLL" = ( -/obj/machinery/portable_atmospherics/canister/nitrogen, -/obj/effect/turf_decal/bot, +/obj/machinery/computer/station_alert, +/obj/machinery/airalarm{ + pixel_y = 23 + }, /turf/open/floor/plasteel, /area/engine/atmos) "bLM" = ( -/obj/machinery/portable_atmospherics/canister/oxygen, -/obj/effect/turf_decal/bot, +/obj/machinery/computer/atmos_alert, /turf/open/floor/plasteel, /area/engine/atmos) "bLN" = ( -/obj/machinery/portable_atmospherics/canister/nitrous_oxide, -/obj/effect/turf_decal/bot, +/obj/machinery/vending/wardrobe/atmos_wardrobe, /turf/open/floor/plasteel, /area/engine/atmos) "bLO" = ( @@ -38146,25 +38152,30 @@ /turf/closed/wall, /area/engine/atmos) "bML" = ( -/obj/machinery/atmospherics/components/unary/portables_connector/visible{ +/obj/structure/disposalpipe/segment{ dir = 4 }, -/obj/machinery/portable_atmospherics/canister/air, +/obj/structure/plasticflaps/opaque, +/obj/machinery/navbeacon{ + codes_txt = "delivery;dir=4"; + dir = 4; + freq = 1400; + location = "Atmospherics" + }, +/obj/effect/turf_decal/delivery, +/obj/machinery/door/window/northleft{ + dir = 4; + name = "Atmospherics Desk"; + req_access_txt = "24" + }, /turf/open/floor/plasteel, /area/engine/atmos) "bMM" = ( -/obj/machinery/atmospherics/components/unary/portables_connector/visible{ - dir = 8 - }, -/obj/machinery/airalarm{ - pixel_y = 23 - }, +/obj/machinery/atmospherics/components/unary/thermomachine/heater, /turf/open/floor/plasteel, /area/engine/atmos) "bMN" = ( -/obj/machinery/atmospherics/components/trinary/filter{ - dir = 4 - }, +/obj/machinery/atmospherics/components/unary/thermomachine/freezer, /turf/open/floor/plasteel, /area/engine/atmos) "bMO" = ( @@ -38522,18 +38533,20 @@ /obj/effect/turf_decal/tile/yellow{ dir = 4 }, -/obj/effect/turf_decal/tile/yellow{ +/obj/structure/disposalpipe/segment{ + dir = 4 + }, +/obj/effect/turf_decal/loading_area{ dir = 8 }, -/turf/open/floor/plasteel/dark/corner, +/turf/open/floor/plasteel, /area/hallway/primary/aft) "bNP" = ( /obj/structure/disposalpipe/segment{ - dir = 6 + dir = 4 }, -/obj/item/radio/intercom{ - name = "Station Intercom (General)"; - pixel_x = -30 +/obj/effect/turf_decal/loading_area{ + dir = 4 }, /turf/open/floor/plasteel, /area/engine/atmos) @@ -38548,9 +38561,6 @@ /obj/structure/disposalpipe/trunk{ dir = 8 }, -/obj/machinery/airalarm{ - pixel_y = 23 - }, /obj/machinery/camera{ c_tag = "Atmospherics Monitoring" }, @@ -38617,16 +38627,16 @@ /turf/open/floor/plasteel, /area/science/misc_lab) "bOa" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 8 +/obj/machinery/atmospherics/pipe/simple/cyan/visible{ + dir = 6 }, /turf/open/floor/plasteel, /area/engine/atmos) "bOb" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 8 }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, /turf/open/floor/plasteel, /area/engine/atmos) "bOc" = ( @@ -38634,16 +38644,17 @@ dir = 1; name = "Mix to Distro" }, +/obj/machinery/atmospherics/pipe/simple/cyan/visible{ + dir = 4 + }, /turf/open/floor/plasteel, /area/engine/atmos) "bOd" = ( /turf/open/floor/plasteel, /area/engine/atmos) "bOe" = ( -/obj/machinery/atmospherics/pipe/manifold/cyan/visible{ - dir = 8 - }, /obj/machinery/meter, +/obj/machinery/atmospherics/pipe/manifold4w/cyan/visible, /turf/open/floor/plasteel, /area/engine/atmos) "bOf" = ( @@ -38965,50 +38976,33 @@ /turf/open/floor/plasteel/white, /area/medical/virology) "bOQ" = ( -/obj/structure/disposalpipe/segment{ +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/loading_area{ - dir = 8 - }, +/obj/item/beacon, /turf/open/floor/plasteel, -/area/hallway/primary/aft) +/area/engine/atmos) "bOR" = ( -/obj/structure/disposalpipe/segment{ - dir = 5 +/obj/machinery/atmospherics/pipe/manifold/yellow/visible{ + dir = 1 }, +/obj/machinery/meter, /turf/open/floor/plasteel, -/area/hallway/primary/aft) +/area/engine/atmos) "bOS" = ( -/obj/structure/disposalpipe/segment{ - dir = 9 - }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 6 }, -/obj/effect/turf_decal/loading_area{ - dir = 4 - }, +/obj/structure/tank_dispenser, /turf/open/floor/plasteel, /area/engine/atmos) "bOT" = ( -/obj/structure/disposalpipe/segment{ - dir = 4 +/obj/machinery/door/poddoor/preopen{ + id = "atmos"; + name = "Atmospherics Blast Door" }, -/obj/structure/plasticflaps/opaque, -/obj/machinery/navbeacon{ - codes_txt = "delivery;dir=4"; - dir = 4; - freq = 1400; - location = "Atmospherics" - }, -/obj/effect/turf_decal/delivery, -/obj/machinery/door/window/northleft{ - dir = 4; - name = "Atmospherics Desk"; - req_access_txt = "24" - }, -/turf/open/floor/plasteel, +/obj/effect/spawner/structure/window/reinforced, +/turf/open/floor/plating, /area/engine/atmos) "bOU" = ( /obj/machinery/holopad, @@ -39024,9 +39018,6 @@ /turf/open/floor/plasteel, /area/engine/atmos) "bOW" = ( -/obj/machinery/computer/atmos_control{ - dir = 8 - }, /obj/machinery/requests_console{ department = "Atmospherics"; departmentType = 4; @@ -39036,8 +39027,8 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 }, -/obj/effect/turf_decal/tile/yellow{ - dir = 4 +/obj/machinery/computer/atmos_control{ + dir = 8 }, /turf/open/floor/plasteel/dark/corner, /area/engine/atmos) @@ -39086,17 +39077,19 @@ /turf/open/floor/plasteel/white, /area/science/circuit) "bPc" = ( -/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ - dir = 8 +/obj/machinery/atmospherics/components/binary/pump/on{ + dir = 8; + name = "Mix to Waste" }, +/obj/machinery/atmospherics/pipe/simple/cyan/visible, /turf/open/floor/plasteel, /area/engine/atmos) "bPd" = ( -/obj/machinery/atmospherics/components/binary/pump/on{ - name = "Waste In" +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 8 }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 +/obj/machinery/atmospherics/pipe/manifold/scrubbers/visible{ + dir = 8 }, /turf/open/floor/plasteel, /area/engine/atmos) @@ -39105,18 +39098,15 @@ /turf/open/floor/plasteel, /area/engine/atmos) "bPf" = ( -/obj/machinery/atmospherics/components/binary/pump{ - name = "Air to Mix" - }, /obj/machinery/atmospherics/pipe/simple/yellow/visible{ dir = 4 }, +/obj/machinery/atmospherics/pipe/simple/cyan/visible, /turf/open/floor/plasteel, /area/engine/atmos) "bPg" = ( -/obj/machinery/atmospherics/components/binary/pump{ - dir = 8; - name = "Mix Outlet Pump" +/obj/machinery/atmospherics/pipe/manifold/yellow/visible{ + dir = 1 }, /turf/open/floor/plasteel, /area/engine/atmos) @@ -39559,25 +39549,33 @@ /obj/effect/turf_decal/tile/yellow{ dir = 4 }, -/turf/open/floor/plasteel/checker, +/turf/open/floor/plasteel, /area/hallway/primary/aft) "bQg" = ( /turf/open/floor/plasteel, /area/hallway/primary/aft) "bQh" = ( -/obj/structure/tank_dispenser{ - pixel_x = -1 - }, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/structure/chair{ + dir = 8 + }, +/obj/effect/landmark/start/atmospheric_technician, /turf/open/floor/plasteel, /area/engine/atmos) "bQi" = ( +/obj/structure/table/reinforced, +/obj/machinery/door/firedoor/heavy, +/obj/machinery/door/window/northleft{ + dir = 4; + name = "Atmospherics Desk"; + req_access_txt = "24" + }, /obj/machinery/door/poddoor/preopen{ id = "atmos"; name = "Atmospherics Blast Door" }, -/obj/effect/spawner/structure/window/reinforced, -/turf/open/floor/plating, +/obj/effect/turf_decal/delivery, +/turf/open/floor/plasteel, /area/engine/atmos) "bQj" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ @@ -39592,15 +39590,15 @@ /turf/open/floor/plasteel, /area/engine/atmos) "bQl" = ( -/obj/machinery/computer/atmos_control{ - dir = 8 - }, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, /obj/effect/turf_decal/tile/yellow{ dir = 4 }, +/obj/machinery/computer/atmos_alert{ + dir = 8 + }, /turf/open/floor/plasteel/dark/corner, /area/engine/atmos) "bQm" = ( @@ -39617,10 +39615,14 @@ /turf/open/floor/plating, /area/engine/atmos) "bQo" = ( -/obj/machinery/atmospherics/components/unary/portables_connector/visible, /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, +/obj/structure/window/reinforced{ + dir = 1 + }, +/obj/effect/turf_decal/bot, +/obj/machinery/portable_atmospherics/canister/air, /turf/open/floor/plasteel, /area/engine/atmos) "bQp" = ( @@ -39659,37 +39661,56 @@ "bQs" = ( /obj/machinery/atmospherics/components/binary/pump/on{ dir = 8; - name = "Mix to Filter" + name = "Air to Waste" }, +/obj/machinery/atmospherics/pipe/simple/cyan/visible, /turf/open/floor/plasteel, /area/engine/atmos) "bQt" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/visible{ +/obj/item/crowbar, +/obj/item/wrench, +/obj/structure/window/reinforced, +/obj/effect/turf_decal/tile/yellow{ + dir = 4 + }, +/obj/effect/turf_decal/tile/yellow{ dir = 8 }, -/turf/open/floor/plasteel, -/area/engine/atmos) +/turf/open/floor/plasteel/dark/corner, +/area/hallway/primary/aft) "bQu" = ( -/obj/machinery/atmospherics/pipe/simple/green/visible{ - dir = 6 - }, +/obj/structure/rack, +/obj/item/clothing/suit/hazardvest, +/obj/item/clothing/suit/hazardvest, +/obj/item/clothing/suit/hazardvest, +/obj/item/clothing/suit/hazardvest, +/obj/item/clothing/gloves/color/black, +/obj/item/clothing/gloves/color/black, +/obj/item/clothing/gloves/color/black, +/obj/item/clothing/mask/gas, +/obj/item/clothing/mask/gas, /turf/open/floor/plasteel, /area/engine/atmos) "bQv" = ( -/obj/machinery/atmospherics/pipe/manifold/yellow/visible{ +/obj/machinery/atmospherics/pipe/simple/cyan/visible{ dir = 4 }, +/obj/machinery/atmospherics/pipe/simple/yellow/visible, /turf/open/floor/plasteel, /area/engine/atmos) "bQw" = ( -/obj/machinery/atmospherics/pipe/manifold/green/visible{ - dir = 4 +/obj/machinery/atmospherics/pipe/simple/cyan/visible{ + dir = 9 }, /turf/open/floor/plasteel, /area/engine/atmos) "bQx" = ( -/obj/machinery/atmospherics/pipe/manifold/green/visible{ - dir = 1 +/obj/machinery/atmospherics/pipe/simple/cyan/visible{ + dir = 4 + }, +/obj/machinery/atmospherics/components/binary/pump{ + dir = 1; + name = "Mix to Distro" }, /turf/open/floor/plasteel, /area/engine/atmos) @@ -39995,42 +40016,31 @@ /obj/effect/turf_decal/tile/yellow{ dir = 4 }, -/turf/open/floor/plasteel/dark/corner, +/turf/open/floor/plasteel, /area/hallway/primary/aft) "bRr" = ( -/obj/structure/chair{ - dir = 8 - }, -/obj/effect/landmark/start/atmospheric_technician, /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel, /area/engine/atmos) "bRs" = ( -/obj/structure/table/reinforced, -/obj/machinery/door/firedoor/heavy, -/obj/machinery/door/window/northleft{ - dir = 4; - name = "Atmospherics Desk"; - req_access_txt = "24" - }, +/obj/effect/spawner/structure/window/reinforced, /obj/machinery/door/poddoor/preopen{ id = "atmos"; name = "Atmospherics Blast Door" }, -/obj/effect/turf_decal/delivery, -/turf/open/floor/plasteel, +/turf/open/floor/plating, /area/engine/atmos) "bRt" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel, /area/engine/atmos) "bRu" = ( -/obj/machinery/computer/atmos_alert{ - dir = 8 - }, /obj/effect/turf_decal/tile/yellow{ dir = 4 }, +/obj/machinery/computer/atmos_alert{ + dir = 8 + }, /turf/open/floor/plasteel/dark/corner, /area/engine/atmos) "bRv" = ( @@ -40044,9 +40054,7 @@ /turf/open/floor/plasteel, /area/engine/atmos) "bRw" = ( -/obj/machinery/atmospherics/components/unary/portables_connector/visible{ - dir = 4 - }, +/obj/effect/turf_decal/bot, /obj/machinery/portable_atmospherics/canister/oxygen, /turf/open/floor/plasteel, /area/engine/atmos) @@ -40055,15 +40063,14 @@ /turf/open/floor/plating, /area/engine/atmos) "bRy" = ( -/obj/machinery/atmospherics/components/unary/portables_connector/visible{ - dir = 8 +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ + dir = 6 }, /turf/open/floor/plasteel, /area/engine/atmos) "bRz" = ( -/obj/machinery/atmospherics/components/trinary/mixer{ - dir = 8 - }, +/obj/effect/turf_decal/bot, +/obj/machinery/portable_atmospherics/canister/oxygen, /turf/open/floor/plasteel, /area/engine/atmos) "bRA" = ( @@ -40073,12 +40080,12 @@ /turf/open/floor/plasteel, /area/engine/atmos) "bRB" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ - dir = 6 - }, /obj/structure/cable{ icon_state = "1-2" }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ + dir = 4 + }, /turf/open/floor/plasteel, /area/engine/atmos) "bRC" = ( @@ -40093,38 +40100,34 @@ /turf/open/floor/plasteel, /area/engine/atmos) "bRD" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ - dir = 9 - }, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/visible, /turf/open/floor/plasteel, /area/engine/atmos) "bRE" = ( -/obj/machinery/atmospherics/components/binary/pump{ - dir = 1; - name = "Pure to Mix" +/obj/machinery/atmospherics/pipe/manifold/green/visible{ + dir = 1 }, +/obj/machinery/meter, /turf/open/floor/plasteel, /area/engine/atmos) "bRF" = ( -/obj/machinery/atmospherics/pipe/simple/yellow/visible{ - dir = 9 +/obj/machinery/atmospherics/pipe/simple/green/visible{ + dir = 4 }, +/obj/machinery/atmospherics/pipe/simple/yellow/visible, /turf/open/floor/plasteel, /area/engine/atmos) "bRG" = ( -/obj/machinery/atmospherics/components/binary/pump/on{ - dir = 1; - name = "Unfiltered to Mix" - }, -/obj/machinery/atmospherics/pipe/simple/green/visible{ - dir = 4 +/obj/machinery/atmospherics/pipe/manifold/green/visible{ + dir = 1 }, /turf/open/floor/plasteel, /area/engine/atmos) "bRH" = ( /obj/machinery/atmospherics/pipe/simple/green/visible{ - dir = 5 + dir = 4 }, +/obj/machinery/atmospherics/pipe/simple/yellow/visible, /turf/open/floor/plasteel, /area/engine/atmos) "bRI" = ( @@ -40136,15 +40139,9 @@ /turf/open/floor/plating, /area/engine/atmos) "bRJ" = ( -/obj/machinery/atmospherics/pipe/simple/green/visible{ - dir = 4 - }, -/obj/effect/turf_decal/tile/green, -/obj/effect/turf_decal/tile/green{ - dir = 4 - }, -/obj/effect/turf_decal/tile/green{ - dir = 8 +/obj/machinery/atmospherics/components/binary/pump/on{ + dir = 4; + name = "Unfiltered & Air to Mix" }, /turf/open/floor/plasteel, /area/engine/atmos) @@ -40449,143 +40446,82 @@ /turf/open/floor/plasteel, /area/hallway/primary/aft) "bSB" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, +/obj/machinery/door/airlock/atmos/glass{ + name = "Atmospherics Monitoring"; + req_access_txt = "24" + }, +/turf/open/floor/plasteel, +/area/engine/atmos) +"bSC" = ( +/obj/machinery/atmospherics/pipe/simple/orange/visible{ + dir = 10 + }, +/turf/closed/wall/r_wall, +/area/engine/atmos) +"bSD" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/closed/wall, +/area/engine/atmos) +"bSE" = ( /obj/machinery/firealarm{ dir = 1; pixel_y = -24 }, -/obj/structure/table, -/obj/item/tank/internals/emergency_oxygen{ - pixel_x = -8 - }, -/obj/item/tank/internals/emergency_oxygen{ - pixel_x = -8 - }, -/obj/item/clothing/mask/breath{ - pixel_x = 4 - }, -/obj/item/clothing/mask/breath{ - pixel_x = 4 - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel, /area/engine/atmos) -"bSC" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/machinery/door/poddoor/preopen{ - id = "atmos"; - name = "Atmospherics Blast Door" - }, -/turf/open/floor/plating, -/area/engine/atmos) -"bSD" = ( -/obj/structure/sign/plaques/atmos{ - pixel_y = -32 - }, -/obj/structure/table, -/obj/item/storage/box, -/obj/item/storage/box, -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/open/floor/plasteel, -/area/engine/atmos) -"bSE" = ( -/obj/machinery/computer/station_alert{ - dir = 8 - }, -/obj/machinery/light{ - dir = 4 - }, -/obj/machinery/button/door{ - id = "atmos"; - name = "Atmospherics Lockdown"; - pixel_x = 24; - pixel_y = 4; - req_access_txt = "24" - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 4 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, -/turf/open/floor/plasteel/dark/corner, -/area/engine/atmos) "bSF" = ( -/obj/structure/table, -/obj/item/clothing/head/welding{ - pixel_x = -3; - pixel_y = 7 - }, -/obj/item/clothing/head/welding{ - pixel_x = -5; - pixel_y = 3 - }, -/obj/machinery/light{ - dir = 8 - }, -/obj/item/multitool, -/obj/item/clothing/glasses/welding, +/obj/effect/turf_decal/bot, +/obj/machinery/portable_atmospherics/canister/nitrogen, /turf/open/floor/plasteel, /area/engine/atmos) "bSG" = ( -/obj/structure/table, -/obj/item/stack/sheet/metal/fifty, -/obj/item/stack/sheet/metal/fifty{ - pixel_x = 2; - pixel_y = 2 - }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, /turf/open/floor/plasteel, /area/engine/atmos) "bSH" = ( -/obj/structure/table, -/obj/item/stack/sheet/glass/fifty, -/obj/item/storage/belt/utility, -/obj/item/t_scanner, -/obj/item/t_scanner, -/obj/item/t_scanner, +/obj/effect/turf_decal/bot, +/obj/machinery/portable_atmospherics/canister/nitrogen, /turf/open/floor/plasteel, /area/engine/atmos) "bSI" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, /obj/structure/cable{ icon_state = "1-2" }, +/obj/machinery/atmospherics/pipe/simple/cyan/visible{ + dir = 6 + }, /turf/open/floor/plasteel, /area/engine/atmos) "bSJ" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/visible{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/yellow/visible, /obj/effect/spawner/structure/window/reinforced, +/obj/machinery/atmospherics/pipe/simple/cyan/visible{ + dir = 9 + }, /turf/open/floor/plating, /area/engine/atmos) "bSK" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/visible{ - dir = 6 - }, /obj/effect/spawner/structure/window/reinforced, +/obj/machinery/atmospherics/pipe/simple/cyan/visible{ + dir = 4 + }, /turf/open/floor/plating, /area/engine/atmos) "bSM" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/visible{ - dir = 4 - }, /obj/effect/spawner/structure/window/reinforced, +/obj/machinery/atmospherics/pipe/simple/yellow/visible, /turf/open/floor/plating, /area/engine/atmos) "bSN" = ( -/obj/machinery/atmospherics/pipe/simple/green/visible, -/obj/machinery/atmospherics/pipe/simple/cyan/visible{ - dir = 4 - }, /obj/effect/spawner/structure/window/reinforced, +/obj/machinery/atmospherics/pipe/simple/green/visible{ + dir = 5 + }, /turf/open/floor/plating, /area/engine/atmos) "bSP" = ( -/obj/machinery/atmospherics/pipe/manifold/cyan/visible{ - dir = 4 - }, /obj/effect/spawner/structure/window/reinforced, +/obj/machinery/atmospherics/pipe/simple/cyan/visible, /turf/open/floor/plating, /area/engine/atmos) "bSQ" = ( @@ -40972,36 +40908,42 @@ /turf/open/floor/plasteel, /area/hallway/primary/aft) "bTK" = ( -/obj/item/crowbar, -/obj/item/wrench, -/obj/structure/window/reinforced, -/obj/effect/turf_decal/tile/yellow{ +/obj/machinery/atmospherics/components/unary/portables_connector/visible{ dir = 4 }, /obj/effect/turf_decal/tile/yellow{ dir = 8 }, -/turf/open/floor/plasteel/dark/corner, -/area/hallway/primary/aft) +/turf/open/floor/plasteel/dark/corner{ + dir = 1 + }, +/area/engine/atmos) "bTL" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, -/turf/closed/wall, -/area/engine/atmos) -"bTM" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden, -/turf/closed/wall, -/area/engine/atmos) -"bTN" = ( -/obj/machinery/door/firedoor/heavy, -/obj/machinery/door/airlock/atmos/glass{ - name = "Atmospherics Monitoring"; - req_access_txt = "24" +/obj/machinery/atmospherics/pipe/simple/orange/visible{ + dir = 4 }, /turf/open/floor/plasteel, /area/engine/atmos) +"bTM" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/atmospherics/pipe/simple/orange/visible{ + dir = 4 + }, +/obj/effect/spawner/structure/window, +/turf/open/floor/plasteel, +/area/engine/atmos) +"bTN" = ( +/obj/machinery/atmospherics/pipe/simple/orange/visible{ + dir = 4 + }, +/obj/structure/closet/secure_closet/atmospherics, +/obj/item/cartridge/atmos, +/turf/open/floor/plasteel, +/area/engine/atmos) "bTO" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/visible{ - dir = 6 +/obj/machinery/atmospherics/pipe/simple/orange/visible{ + dir = 4 }, /turf/open/floor/plasteel, /area/engine/atmos) @@ -41012,34 +40954,33 @@ /turf/open/floor/plasteel, /area/engine/atmos) "bTQ" = ( -/obj/machinery/atmospherics/pipe/simple/yellow/visible, -/obj/machinery/meter, +/obj/machinery/atmospherics/components/binary/pump/on{ + dir = 8; + name = "Waste to Filter" + }, /turf/open/floor/plasteel, /area/engine/atmos) "bTR" = ( -/obj/machinery/atmospherics/pipe/manifold/cyan/visible{ - dir = 4 +/obj/machinery/atmospherics/components/binary/pump/on{ + dir = 8; + name = "Filter to Waste" }, -/obj/machinery/meter, +/obj/machinery/atmospherics/pipe/simple/cyan/visible, /turf/open/floor/plasteel, /area/engine/atmos) "bTS" = ( -/obj/machinery/atmospherics/pipe/simple/yellow/visible{ - dir = 6 - }, -/obj/machinery/meter, +/obj/machinery/atmospherics/pipe/simple/yellow/visible, /turf/open/floor/plasteel, /area/engine/atmos) "bTT" = ( -/obj/machinery/atmospherics/pipe/simple/green/visible, -/obj/machinery/atmospherics/pipe/simple/yellow/visible{ - dir = 4 +/obj/machinery/atmospherics/pipe/manifold/yellow/visible{ + dir = 1 }, /turf/open/floor/plasteel, /area/engine/atmos) "bTU" = ( -/obj/machinery/atmospherics/pipe/manifold/yellow/visible{ - dir = 1 +/obj/machinery/atmospherics/pipe/simple/yellow/visible{ + dir = 5 }, /turf/open/floor/plasteel, /area/engine/atmos) @@ -41051,6 +40992,7 @@ /obj/effect/turf_decal/tile/red{ dir = 4 }, +/obj/machinery/atmospherics/pipe/simple/green/visible, /turf/open/floor/plasteel/cafeteria, /area/engine/atmos) "bTW" = ( @@ -41374,6 +41316,10 @@ dir = 4 }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/door/airlock/atmos{ + name = "Atmospherics"; + req_access_txt = "24" + }, /turf/open/floor/plasteel, /area/engine/atmos) "bUI" = ( @@ -41383,6 +41329,9 @@ /obj/effect/turf_decal/tile/yellow{ dir = 4 }, +/obj/effect/decal/cleanable/oil{ + icon_state = "floor5" + }, /turf/open/floor/plasteel/dark/corner, /area/engine/atmos) "bUJ" = ( @@ -41397,56 +41346,64 @@ /turf/open/floor/plasteel, /area/engine/atmos) "bUK" = ( -/obj/machinery/atmospherics/components/binary/pump/on{ - dir = 8; - name = "Air to External" - }, -/turf/open/floor/plasteel, -/area/engine/atmos) -"bUL" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/visible{ - dir = 9 - }, -/turf/open/floor/plasteel, -/area/engine/atmos) -"bUM" = ( -/obj/structure/cable{ - icon_state = "1-2" - }, /obj/machinery/atmospherics/pipe/simple/scrubbers/visible, /obj/machinery/atmospherics/pipe/simple/cyan/visible{ dir = 4 }, /turf/open/floor/plasteel, /area/engine/atmos) -"bUN" = ( -/obj/item/beacon, +"bUL" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/atmospherics/pipe/simple/green/visible, +/turf/open/floor/plating, +/area/engine/atmos) +"bUM" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/cyan/visible{ + dir = 9 + }, /turf/open/floor/plasteel, /area/engine/atmos) +"bUN" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/atmospherics/pipe/simple/green/visible{ + dir = 10 + }, +/turf/open/floor/plating, +/area/engine/atmos) "bUO" = ( -/obj/machinery/atmospherics/components/binary/pump{ - name = "Mix to Port" - }, -/turf/open/floor/plasteel, +/obj/machinery/atmospherics/pipe/manifold/orange/visible, +/obj/machinery/meter, +/turf/closed/wall/r_wall, /area/engine/atmos) "bUP" = ( -/obj/machinery/atmospherics/components/binary/pump{ - name = "Air to Port" +/obj/machinery/atmospherics/pipe/simple/orange/visible{ + dir = 4 }, -/turf/open/floor/plasteel, +/turf/closed/wall, /area/engine/atmos) "bUQ" = ( -/obj/machinery/atmospherics/components/binary/pump{ - name = "Pure to Port" +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, +/obj/machinery/atmospherics/pipe/simple/orange/visible{ + dir = 4 }, /turf/open/floor/plasteel, /area/engine/atmos) "bUR" = ( -/obj/machinery/atmospherics/pipe/simple/green/visible, +/obj/machinery/atmospherics/pipe/simple/yellow/visible, /turf/open/floor/plasteel, /area/engine/atmos) "bUS" = ( -/obj/machinery/atmospherics/pipe/simple/yellow/visible, +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/machinery/atmospherics/pipe/simple/cyan/visible, +/obj/machinery/atmospherics/components/binary/pump/on{ + dir = 8; + name = "Mix to External" + }, /turf/open/floor/plasteel, /area/engine/atmos) "bUT" = ( @@ -41456,6 +41413,7 @@ /obj/effect/turf_decal/tile/red{ dir = 4 }, +/obj/machinery/atmospherics/pipe/simple/green/visible, /turf/open/floor/plasteel/white/corner, /area/engine/atmos) "bUU" = ( @@ -41805,12 +41763,15 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ dir = 6 }, +/obj/effect/turf_decal/stripes/line{ + dir = 9 + }, +/obj/machinery/suit_storage_unit/atmos, /turf/open/floor/plasteel, /area/engine/atmos) "bVQ" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 1 - }, +/obj/effect/spawner/structure/window, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel, /area/engine/atmos) "bVR" = ( @@ -41820,6 +41781,10 @@ /obj/effect/turf_decal/tile/yellow{ dir = 4 }, +/obj/effect/turf_decal/stripes/line{ + dir = 5 + }, +/obj/machinery/suit_storage_unit/atmos, /turf/open/floor/plasteel/dark/corner, /area/engine/atmos) "bVS" = ( @@ -41830,74 +41795,73 @@ /turf/closed/wall, /area/engine/atmos) "bVT" = ( +/obj/machinery/atmospherics/pipe/manifold/scrubbers/visible{ + dir = 4 + }, +/turf/open/floor/plasteel, +/area/engine/atmos) +"bVU" = ( +/obj/machinery/portable_atmospherics/pump, +/obj/machinery/atmospherics/components/unary/portables_connector/visible{ + dir = 4 + }, +/obj/effect/turf_decal/tile/blue{ + dir = 8 + }, +/turf/open/floor/plasteel/white/corner{ + dir = 1 + }, +/area/engine/atmos) +"bVV" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/turf/open/floor/plasteel, +/area/engine/atmos) +"bVW" = ( +/obj/machinery/atmospherics/components/binary/pump/on{ + dir = 8; + name = "Air to External" + }, +/turf/open/floor/plasteel, +/area/engine/atmos) +"bVX" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ + dir = 4 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 1 + }, +/obj/machinery/suit_storage_unit/atmos, +/turf/open/floor/plasteel, +/area/engine/atmos) +"bVY" = ( /obj/machinery/atmospherics/components/binary/pump/on{ dir = 4; name = "External to Filter" }, /turf/open/floor/plasteel, /area/engine/atmos) -"bVU" = ( -/obj/structure/reagent_dispensers/watertank/high, -/turf/open/floor/plasteel, -/area/engine/atmos) -"bVV" = ( -/obj/structure/cable{ - icon_state = "1-2" +"bVZ" = ( +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ + dir = 9 }, -/obj/machinery/atmospherics/pipe/manifold/scrubbers/visible{ - dir = 4 +/turf/closed/wall, +/area/engine/atmos) +"bWa" = ( +/obj/machinery/atmospherics/pipe/manifold/yellow/visible{ + dir = 8 }, -/turf/open/floor/plasteel, -/area/engine/atmos) -"bVW" = ( -/obj/structure/rack, -/obj/item/clothing/suit/hazardvest, -/obj/item/clothing/suit/hazardvest, -/obj/item/clothing/suit/hazardvest, -/obj/item/clothing/suit/hazardvest, -/obj/item/clothing/gloves/color/black, -/obj/item/clothing/gloves/color/black, -/obj/item/clothing/gloves/color/black, -/obj/item/clothing/mask/gas, -/obj/item/clothing/mask/gas, -/turf/open/floor/plasteel, -/area/engine/atmos) -"bVX" = ( -/obj/structure/reagent_dispensers/fueltank, -/turf/open/floor/plasteel, -/area/engine/atmos) -"bVY" = ( -/obj/machinery/atmospherics/pipe/manifold/general/visible, /obj/machinery/meter, /turf/open/floor/plasteel, /area/engine/atmos) -"bVZ" = ( -/obj/machinery/atmospherics/pipe/manifold/general/visible{ - dir = 8 - }, -/turf/open/floor/plasteel, -/area/engine/atmos) -"bWa" = ( -/obj/machinery/atmospherics/pipe/manifold/general/visible{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/engine/atmos) "bWb" = ( -/obj/machinery/atmospherics/components/trinary/filter/atmos/n2o{ - dir = 1 - }, +/obj/machinery/atmospherics/pipe/simple/yellow/visible, /turf/open/floor/plasteel, /area/engine/atmos) "bWc" = ( -/obj/machinery/atmospherics/pipe/simple/green/visible{ - dir = 4 - }, -/obj/effect/turf_decal/tile/red{ - dir = 4 - }, -/obj/effect/turf_decal/tile/red{ - dir = 8 +/obj/machinery/atmospherics/components/trinary/filter/atmos/n2o{ + dir = 1 }, /turf/open/floor/plasteel/white/corner, /area/engine/atmos) @@ -42175,33 +42139,20 @@ }, /area/engine/atmos) "bWN" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ +/obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 4 }, -/obj/machinery/door/poddoor/preopen{ - id = "atmos"; - name = "Atmospherics Blast Door" - }, -/obj/effect/turf_decal/delivery, /turf/open/floor/plasteel, /area/engine/atmos) "bWO" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/visible{ - dir = 1 +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ + dir = 10 }, -/obj/machinery/meter, /turf/closed/wall/r_wall, /area/engine/atmos) "bWP" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ - dir = 9 - }, -/obj/machinery/door/poddoor/preopen{ - id = "atmos"; - name = "Atmospherics Blast Door" - }, -/obj/effect/turf_decal/delivery, -/turf/open/floor/plasteel, +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, +/turf/closed/wall, /area/engine/atmos) "bWQ" = ( /turf/closed/wall/r_wall, @@ -42211,44 +42162,37 @@ name = "Station Intercom (General)"; pixel_x = -30 }, -/turf/open/floor/plasteel, -/area/engine/atmos) -"bWS" = ( -/obj/structure/extinguisher_cabinet{ - pixel_x = 27 - }, -/obj/machinery/camera{ - c_tag = "Atmospherics West"; - dir = 8 - }, -/obj/structure/cable{ - icon_state = "1-2" - }, /obj/machinery/atmospherics/pipe/simple/scrubbers/visible, -/obj/machinery/light{ +/obj/machinery/camera{ + c_tag = "Atmospherics Central"; dir = 4 }, /turf/open/floor/plasteel, /area/engine/atmos) -"bWT" = ( -/obj/structure/extinguisher_cabinet{ - pixel_x = -27 - }, -/obj/machinery/atmospherics/components/binary/pump{ - name = "Air to Port" - }, -/obj/machinery/light{ - dir = 8 +"bWS" = ( +/obj/structure/cable{ + icon_state = "1-2" }, /turf/open/floor/plasteel, /area/engine/atmos) +"bWT" = ( +/obj/structure/cable{ + icon_state = "1-2" + }, +/obj/structure/cable{ + icon_state = "1-4" + }, +/turf/open/floor/plating, +/area/engine/atmos) "bWU" = ( /obj/machinery/light{ dir = 4 }, -/obj/machinery/atmospherics/pipe/simple/orange/visible{ - dir = 4 +/obj/machinery/atmospherics/components/binary/pump{ + dir = 4; + name = "Mix to Engine" }, +/obj/machinery/atmospherics/pipe/simple/green/visible, /turf/open/floor/plasteel, /area/engine/atmos) "bWV" = ( @@ -42598,20 +42542,29 @@ }, /area/engine/atmos) "bXK" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ - dir = 9 - }, +/obj/machinery/meter, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/visible, /turf/closed/wall/r_wall, /area/engine/atmos) "bXL" = ( -/obj/structure/sign/warning/securearea, -/turf/closed/wall/r_wall, +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ + dir = 9 + }, +/obj/machinery/door/poddoor/preopen{ + id = "atmos"; + name = "Atmospherics Blast Door" + }, +/obj/effect/turf_decal/delivery, +/turf/open/floor/plasteel, /area/engine/atmos) "bXM" = ( -/obj/machinery/door/firedoor/heavy, -/obj/machinery/door/airlock/atmos{ - name = "Atmospherics"; - req_access_txt = "24" +/obj/machinery/door/poddoor/preopen{ + id = "atmos"; + name = "Atmospherics Blast Door" + }, +/obj/effect/turf_decal/delivery, +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ + dir = 4 }, /turf/open/floor/plasteel, /area/engine/atmos) @@ -42654,35 +42607,34 @@ /obj/structure/fireaxecabinet{ pixel_x = -32 }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, /turf/open/floor/plasteel, /area/engine/atmos) "bXR" = ( -/obj/structure/closet/secure_closet/atmospherics, -/obj/effect/turf_decal/stripes/line{ - dir = 8 +/obj/machinery/power/floodlight, +/obj/structure/cable{ + icon_state = "0-8" }, -/obj/item/cartridge/atmos, -/turf/open/floor/plasteel, +/turf/open/floor/plating, /area/engine/atmos) "bXS" = ( -/obj/machinery/atmospherics/components/unary/portables_connector/visible{ - dir = 4 +/obj/structure/cable{ + icon_state = "4-8" }, -/obj/machinery/portable_atmospherics/canister, -/obj/effect/turf_decal/bot, -/turf/open/floor/plasteel, +/turf/open/floor/plating, /area/engine/atmos) "bXT" = ( -/obj/machinery/atmospherics/components/unary/portables_connector/visible{ +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 8 + }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, +/obj/machinery/light{ dir = 8 }, -/obj/effect/turf_decal/bot, /turf/open/floor/plasteel, /area/engine/atmos) "bXU" = ( -/obj/machinery/atmospherics/pipe/manifold/yellow/visible{ - dir = 8 - }, +/obj/structure/reagent_dispensers/fueltank, /turf/open/floor/plasteel, /area/engine/atmos) "bXV" = ( @@ -42697,6 +42649,7 @@ /obj/effect/turf_decal/stripes/line{ dir = 5 }, +/obj/machinery/atmospherics/pipe/simple/green/visible, /turf/open/floor/plasteel, /area/engine/atmos) "bXW" = ( @@ -43002,27 +42955,28 @@ /obj/effect/turf_decal/tile/yellow{ dir = 4 }, -/obj/effect/turf_decal/tile/yellow{ +/obj/machinery/door/airlock/atmos{ + name = "Atmospherics"; + req_access_txt = "24" + }, +/obj/machinery/door/firedoor/heavy, +/turf/open/floor/plasteel/dark/corner{ + dir = 1 + }, +/area/engine/atmos) +"bYK" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, +/obj/structure/extinguisher_cabinet{ + pixel_x = -27 + }, +/turf/open/floor/plasteel, +/area/engine/atmos) +"bYL" = ( +/obj/machinery/atmospherics/pipe/manifold/yellow/visible{ dir = 8 }, -/turf/open/floor/plasteel/dark/corner{ - dir = 1 - }, -/area/engine/break_room) -"bYK" = ( -/obj/effect/turf_decal/tile/yellow{ - dir = 4 - }, -/turf/open/floor/plasteel/checker, -/area/engine/break_room) -"bYL" = ( -/obj/effect/turf_decal/tile/yellow{ - dir = 4 - }, -/turf/open/floor/plasteel/dark/corner{ - dir = 1 - }, -/area/engine/break_room) +/turf/open/floor/plasteel, +/area/engine/atmos) "bYM" = ( /obj/machinery/airalarm{ dir = 1; @@ -43054,22 +43008,22 @@ /turf/closed/wall, /area/crew_quarters/bar) "bYQ" = ( -/obj/machinery/suit_storage_unit/atmos, -/obj/effect/turf_decal/stripes/line{ - dir = 8 +/obj/structure/cable{ + icon_state = "4-8" }, -/turf/open/floor/plasteel, +/turf/open/floor/plating, /area/engine/atmos) "bYR" = ( -/obj/structure/sign/warning/nosmoking, -/turf/closed/wall, +/obj/structure/cable{ + icon_state = "4-8" + }, +/turf/open/floor/plating, /area/engine/atmos) "bYS" = ( -/obj/machinery/atmospherics/pipe/manifold/general/visible{ - dir = 4 +/obj/structure/cable{ + icon_state = "4-8" }, -/obj/machinery/meter, -/turf/open/floor/plasteel, +/turf/open/floor/plating, /area/engine/atmos) "bYT" = ( /obj/machinery/computer/atmos_control/tank/toxin_tank{ @@ -43078,6 +43032,7 @@ /obj/effect/turf_decal/stripes/line{ dir = 4 }, +/obj/machinery/atmospherics/pipe/simple/green/visible, /turf/open/floor/plasteel, /area/engine/atmos) "bYU" = ( @@ -43376,41 +43331,30 @@ /obj/structure/cable{ icon_state = "0-4" }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, /turf/open/floor/plasteel, /area/engine/atmos) "bZG" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, /obj/structure/cable{ icon_state = "1-8" }, /turf/open/floor/plasteel, /area/engine/atmos) "bZH" = ( -/obj/machinery/atmospherics/pipe/manifold/general/visible{ - dir = 4 - }, -/obj/item/wrench, +/obj/machinery/portable_atmospherics/canister, /turf/open/floor/plasteel, /area/engine/atmos) "bZI" = ( -/obj/machinery/atmospherics/pipe/manifold/general/visible{ - dir = 8 - }, -/obj/machinery/meter, +/obj/machinery/portable_atmospherics/scrubber, /turf/open/floor/plasteel, /area/engine/atmos) "bZJ" = ( -/obj/machinery/atmospherics/components/trinary/filter/atmos/plasma{ - dir = 1 - }, +/obj/machinery/atmospherics/pipe/simple/yellow/visible, /turf/open/floor/plasteel, /area/engine/atmos) "bZK" = ( -/obj/machinery/atmospherics/pipe/simple/green/visible{ - dir = 4 - }, -/obj/effect/turf_decal/stripes/line{ - dir = 6 +/obj/machinery/atmospherics/components/trinary/filter/atmos/plasma{ + dir = 1 }, /turf/open/floor/plasteel, /area/engine/atmos) @@ -43795,42 +43739,32 @@ /turf/closed/wall/r_wall, /area/security/checkpoint/engineering) "caE" = ( -/obj/machinery/requests_console{ - department = "Atmospherics"; - departmentType = 4; - name = "Atmos RC"; - pixel_x = 30 - }, -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, -/obj/machinery/light{ - dir = 4 - }, +/obj/structure/reagent_dispensers/watertank/high, /turf/open/floor/plasteel, /area/engine/atmos) "caF" = ( -/obj/machinery/light{ - dir = 8 - }, -/obj/machinery/camera{ - c_tag = "Atmospherics Central"; - dir = 4 - }, -/obj/machinery/atmospherics/components/binary/pump{ - name = "Port to Filter" +/obj/machinery/atmospherics/pipe/simple/green/visible{ + dir = 6 }, /turf/open/floor/plasteel, /area/engine/atmos) "caG" = ( -/obj/machinery/atmospherics/components/unary/thermomachine/heater{ - dir = 8 +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, +/obj/machinery/requests_console{ + department = "Atmospherics"; + departmentType = 4; + name = "Atmos RC"; + pixel_x = -30 }, /turf/open/floor/plasteel, /area/engine/atmos) "caH" = ( -/obj/machinery/atmospherics/pipe/manifold/general/visible{ - dir = 8 +/obj/machinery/atmospherics/pipe/simple/yellow/visible{ + dir = 5 + }, +/obj/effect/decal/cleanable/oil{ + icon_state = "floor6" }, -/obj/structure/chair/stool, /turf/open/floor/plasteel, /area/engine/atmos) "caI" = ( @@ -44277,43 +44211,46 @@ /turf/open/floor/plating, /area/maintenance/port/aft) "cbz" = ( -/obj/machinery/vending/wardrobe/atmos_wardrobe, +/obj/machinery/portable_atmospherics/pump, /turf/open/floor/plasteel, /area/engine/atmos) "cbA" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, +/obj/machinery/portable_atmospherics/pump, /turf/open/floor/plasteel, /area/engine/atmos) "cbB" = ( -/obj/machinery/space_heater, -/obj/effect/turf_decal/stripes/line{ - dir = 6 +/obj/machinery/atmospherics/pipe/simple/green/visible, +/obj/machinery/atmospherics/components/binary/pump{ + dir = 8; + name = "Air Outlet Pump" }, /turf/open/floor/plasteel, /area/engine/atmos) "cbC" = ( -/obj/machinery/space_heater, -/obj/effect/turf_decal/stripes/line{ - dir = 10 +/obj/machinery/atmospherics/pipe/manifold/cyan/visible{ + dir = 1 }, +/obj/machinery/meter, /turf/open/floor/plasteel, /area/engine/atmos) "cbD" = ( -/obj/machinery/atmospherics/components/binary/pump{ - dir = 8; - name = "Port to Filter" +/obj/machinery/atmospherics/pipe/manifold/cyan/visible{ + dir = 8 }, +/obj/machinery/meter, /turf/open/floor/plasteel, /area/engine/atmos) "cbE" = ( -/obj/machinery/atmospherics/components/unary/thermomachine/freezer{ - dir = 8 +/obj/machinery/atmospherics/pipe/simple/cyan/visible{ + dir = 10 }, +/obj/machinery/meter, /turf/open/floor/plasteel, /area/engine/atmos) "cbF" = ( -/obj/machinery/atmospherics/pipe/manifold/general/visible, -/obj/item/cigbutt, +/obj/machinery/atmospherics/pipe/manifold/scrubbers/visible{ + dir = 8 + }, /turf/open/floor/plasteel, /area/engine/atmos) "cbG" = ( @@ -44328,6 +44265,7 @@ /obj/effect/turf_decal/tile/yellow{ dir = 4 }, +/obj/machinery/atmospherics/pipe/simple/green/visible, /turf/open/floor/plasteel, /area/engine/atmos) "cbH" = ( @@ -44696,29 +44634,25 @@ dir = 4; pixel_x = -24 }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, /turf/open/floor/plasteel, /area/engine/atmos) "ccw" = ( /turf/closed/wall/r_wall, /area/engine/engineering) "ccx" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/visible{ - dir = 1 - }, -/obj/machinery/meter, +/obj/machinery/space_heater, /turf/open/floor/plasteel, /area/engine/atmos) "ccy" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ - dir = 5 - }, +/obj/machinery/space_heater, /turf/open/floor/plasteel, /area/engine/atmos) "ccz" = ( -/obj/machinery/atmospherics/components/binary/pump{ - dir = 4; - name = "N2 to Pure" +/obj/machinery/atmospherics/pipe/simple/green/visible{ + dir = 4 }, +/obj/machinery/atmospherics/pipe/simple/cyan/visible, /turf/open/floor/plasteel, /area/engine/atmos) "ccA" = ( @@ -44729,6 +44663,7 @@ /obj/effect/turf_decal/tile/yellow{ dir = 4 }, +/obj/machinery/atmospherics/pipe/simple/green/visible, /turf/open/floor/plasteel, /area/engine/atmos) "ccB" = ( @@ -45054,51 +44989,26 @@ dir = 4; pixel_x = -22 }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, /turf/open/floor/plasteel, /area/engine/atmos) "cdx" = ( -/obj/machinery/atmospherics/pipe/manifold/cyan/visible, -/turf/open/floor/plasteel, -/area/engine/atmos) -"cdy" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/visible{ - dir = 4 +/obj/structure/lattice, +/obj/machinery/atmospherics/components/unary/relief_valve/atmos/atmos_waste{ + dir = 1 }, -/obj/machinery/meter, -/turf/open/floor/plasteel, -/area/engine/atmos) -"cdz" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/visible{ - dir = 4 - }, -/obj/machinery/atmospherics/components/binary/pump{ - dir = 1; - name = "O2 to Pure" - }, -/turf/open/floor/plasteel, -/area/engine/atmos) -"cdA" = ( -/obj/machinery/atmospherics/components/trinary/mixer/airmix{ - dir = 4 - }, -/turf/open/floor/plasteel, +/obj/structure/lattice/catwalk, +/turf/open/space, /area/engine/atmos) "cdB" = ( -/obj/machinery/atmospherics/components/trinary/filter/atmos/co2{ - dir = 1 +/obj/machinery/atmospherics/pipe/simple/yellow/visible{ + dir = 9 }, /turf/open/floor/plasteel, /area/engine/atmos) "cdC" = ( -/obj/machinery/atmospherics/pipe/simple/green/visible{ - dir = 4 - }, -/obj/effect/turf_decal/tile/yellow, -/obj/effect/turf_decal/tile/yellow{ - dir = 4 - }, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 +/obj/machinery/atmospherics/components/trinary/filter/atmos/co2{ + dir = 1 }, /turf/open/floor/plasteel, /area/engine/atmos) @@ -45441,6 +45351,7 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 8 }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, /turf/open/floor/plasteel, /area/engine/atmos) "cey" = ( @@ -45455,17 +45366,15 @@ /area/engine/atmos) "ceA" = ( /obj/effect/spawner/structure/window/reinforced, -/obj/machinery/atmospherics/pipe/simple/cyan/visible{ - dir = 9 - }, +/obj/machinery/atmospherics/pipe/simple/cyan/visible, /turf/open/floor/plating, /area/engine/atmos) "ceB" = ( /obj/machinery/light{ dir = 4 }, -/obj/machinery/atmospherics/pipe/simple/cyan/visible{ - dir = 6 +/obj/machinery/atmospherics/pipe/simple/green/visible{ + dir = 9 }, /turf/open/floor/plasteel, /area/engine/atmos) @@ -45693,7 +45602,7 @@ /turf/open/floor/plasteel, /area/engine/break_room) "cfi" = ( -/obj/machinery/atmospherics/components/trinary/filter/atmos/n2, +/obj/machinery/portable_atmospherics/scrubber/huge, /turf/open/floor/plasteel, /area/engine/atmos) "cfj" = ( @@ -45923,37 +45832,23 @@ /turf/open/floor/plasteel, /area/engine/engineering) "cfN" = ( -/obj/machinery/portable_atmospherics/scrubber, -/turf/open/floor/plasteel, -/area/engine/atmos) -"cfO" = ( -/obj/machinery/atmospherics/pipe/simple/green/visible, -/obj/machinery/portable_atmospherics/pump, +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, /turf/open/floor/plasteel, /area/engine/atmos) "cfP" = ( -/obj/machinery/atmospherics/pipe/simple/green/visible{ +/obj/machinery/atmospherics/components/trinary/mixer/airmix{ dir = 4 }, /turf/open/floor/plasteel, /area/engine/atmos) "cfQ" = ( -/obj/machinery/atmospherics/pipe/simple/green/visible{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/cyan/visible, -/turf/open/floor/plasteel, -/area/engine/atmos) -"cfR" = ( -/obj/machinery/atmospherics/components/trinary/filter/atmos/o2{ - dir = 4 +/obj/machinery/atmospherics/pipe/simple/cyan/visible{ + dir = 6 }, /turf/open/floor/plasteel, /area/engine/atmos) "cfT" = ( -/obj/machinery/atmospherics/pipe/simple/green/visible{ - dir = 9 - }, +/obj/machinery/atmospherics/pipe/simple/green/visible, /turf/open/floor/plasteel, /area/engine/atmos) "cfU" = ( @@ -46335,11 +46230,12 @@ /obj/effect/turf_decal/tile/red{ dir = 8 }, +/obj/machinery/atmospherics/pipe/simple/green/visible{ + dir = 4 + }, /turf/open/floor/plasteel, /area/engine/atmos) "cgW" = ( -/obj/machinery/atmospherics/pipe/simple/green/visible, -/obj/machinery/portable_atmospherics/pump, /obj/effect/turf_decal/tile/red{ dir = 1 }, @@ -46347,11 +46243,17 @@ /obj/effect/turf_decal/tile/red{ dir = 8 }, +/obj/machinery/atmospherics/components/trinary/filter/atmos/n2{ + dir = 4 + }, /turf/open/floor/plasteel, /area/engine/atmos) "cgX" = ( /obj/machinery/light, -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, +/obj/machinery/atmospherics/pipe/simple/green/visible{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/cyan/visible, /turf/open/floor/plasteel, /area/engine/atmos) "cgY" = ( @@ -46366,6 +46268,9 @@ /obj/effect/turf_decal/tile/red{ dir = 8 }, +/obj/machinery/atmospherics/pipe/simple/green/visible{ + dir = 4 + }, /turf/open/floor/plasteel, /area/engine/atmos) "cgZ" = ( @@ -46376,16 +46281,14 @@ /obj/effect/turf_decal/tile/blue{ dir = 8 }, +/obj/machinery/atmospherics/pipe/simple/green/visible{ + dir = 4 + }, /turf/open/floor/plasteel, /area/engine/atmos) "cha" = ( -/obj/machinery/atmospherics/pipe/simple/green/visible, -/obj/effect/turf_decal/tile/blue{ - dir = 1 - }, -/obj/effect/turf_decal/tile/blue, -/obj/effect/turf_decal/tile/blue{ - dir = 8 +/obj/machinery/atmospherics/components/trinary/filter/atmos/o2{ + dir = 4 }, /turf/open/floor/plasteel, /area/engine/atmos) @@ -46401,6 +46304,9 @@ /obj/effect/turf_decal/tile/blue{ dir = 8 }, +/obj/machinery/atmospherics/pipe/simple/green/visible{ + dir = 4 + }, /turf/open/floor/plasteel, /area/engine/atmos) "chc" = ( @@ -46410,6 +46316,9 @@ /obj/effect/turf_decal/tile/blue{ dir = 8 }, +/obj/machinery/atmospherics/pipe/simple/green/visible{ + dir = 9 + }, /turf/open/floor/plasteel/white/corner, /area/engine/atmos) "chd" = ( @@ -46417,6 +46326,9 @@ /obj/effect/turf_decal/tile/blue{ dir = 8 }, +/obj/machinery/atmospherics/pipe/simple/green/visible{ + dir = 4 + }, /turf/open/floor/plasteel/cafeteria, /area/engine/atmos) "che" = ( @@ -46926,6 +46838,9 @@ "civ" = ( /obj/machinery/atmospherics/pipe/simple/green/visible, /obj/effect/spawner/structure/window/reinforced, +/obj/machinery/atmospherics/pipe/simple/cyan/visible{ + dir = 4 + }, /turf/open/floor/plating, /area/engine/atmos) "cix" = ( @@ -52483,9 +52398,6 @@ /turf/open/floor/plasteel, /area/security/checkpoint/engineering) "cBJ" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ - dir = 9 - }, /obj/effect/landmark/event_spawn, /turf/open/floor/plasteel, /area/engine/atmos) @@ -52659,28 +52571,8 @@ /obj/item/poster/random_official, /turf/open/floor/plating, /area/maintenance/starboard/aft) -"cCB" = ( -/obj/machinery/atmospherics/pipe/simple/general/visible{ - dir = 10 - }, -/turf/open/floor/plasteel, -/area/engine/atmos) -"cCC" = ( -/obj/machinery/atmospherics/pipe/simple/general/visible{ - dir = 5 - }, -/turf/open/floor/plasteel, -/area/engine/atmos) -"cCD" = ( -/obj/machinery/atmospherics/pipe/simple/yellow/visible, -/obj/machinery/atmospherics/components/binary/pump{ - dir = 4; - name = "Mix to Engine" - }, -/turf/open/floor/plasteel, -/area/engine/atmos) "cCE" = ( -/obj/machinery/atmospherics/pipe/simple/green/visible, +/obj/machinery/atmospherics/pipe/simple/yellow/visible, /obj/machinery/atmospherics/pipe/simple/orange/visible{ dir = 4 }, @@ -53870,18 +53762,12 @@ /turf/open/floor/plasteel, /area/security/brig) "daI" = ( -/obj/structure/reagent_dispensers/foamtank, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, -/obj/effect/turf_decal/tile/yellow{ +/obj/structure/window/reinforced, +/obj/effect/turf_decal/bot, +/obj/machinery/portable_atmospherics/canister/nitrous_oxide, +/obj/machinery/atmospherics/pipe/simple/orange/visible{ dir = 4 }, -/obj/effect/turf_decal/tile/blue, -/obj/effect/turf_decal/tile/blue{ - dir = 1 - }, -/obj/effect/turf_decal/stripes/box, /turf/open/floor/plasteel, /area/engine/atmos) "dbU" = ( @@ -57590,18 +57476,12 @@ /turf/open/floor/plasteel, /area/crew_quarters/fitness/pool) "plm" = ( -/obj/structure/reagent_dispensers/watertank/high, -/obj/effect/turf_decal/tile/yellow{ - dir = 8 - }, -/obj/effect/turf_decal/tile/yellow{ +/obj/structure/window/reinforced, +/obj/effect/turf_decal/bot, +/obj/machinery/portable_atmospherics/canister/nitrous_oxide, +/obj/machinery/atmospherics/pipe/simple/orange/visible{ dir = 4 }, -/obj/effect/turf_decal/tile/blue, -/obj/effect/turf_decal/tile/blue{ - dir = 1 - }, -/obj/effect/turf_decal/stripes/box, /turf/open/floor/plasteel, /area/engine/atmos) "plC" = ( @@ -89880,8 +89760,8 @@ bGO bHl bHS bLI -bLI -bOR +apI +bQg bQg bQg bQg @@ -90138,17 +90018,17 @@ bKw bLH bRq bNO -bOQ -bQf -bRq +bQg bRq +bQt bTK -bUE +bTK +bVU bUE bWM bXJ -bYH -bYH +bMK +bMK bYH bYH bVg @@ -90394,17 +90274,17 @@ bJs bKy bLK bLK -bLK +bML bOT bQi bRs bSC -bLK +bUO bUG bVO bWO bXK -bYH +bMK bZz caw bYH @@ -90650,7 +90530,7 @@ bCv bJs bKy bLJ -bLJ +agd bNP bOS bQh @@ -90660,7 +90540,7 @@ bTL bUF bVN bWN -bLK +bXM bYJ bRi bZy @@ -90907,7 +90787,7 @@ bCv bJs bKy bLM -bLM +alk bNQ bOV bQk @@ -90916,9 +90796,9 @@ bSD bTM bUH bVQ -bWN +bVZ bXM -bYL +bLK cew bTh cdt @@ -91164,18 +91044,18 @@ bCv bJs bKy bLL -bLL +bOd bNQ bOU bQj -bOd -bOd -bRx +bSE +bMK +bTN bTP bVP bWP bXL -bYK +bLK bRj bTg bUm @@ -91421,15 +91301,15 @@ bCy bGP bHn bLN -bLN +alX bNS bOX bQm bRv -bOd +bMK bTN bTP -bRA +bVX bWQ bWQ bYN @@ -91683,8 +91563,8 @@ bNR bOW bQl bRu -bSE -bRx +bMK +bTN bUI bVR bWQ @@ -91941,7 +91821,7 @@ bOY bQn bRx bMK -bMK +bUP bUJ bVS bWQ @@ -92192,13 +92072,13 @@ bCv bJs bKz bLK -bML +bOd bNT bOV -bQj -bRw -bSF -daI +bQo +bRz +bSH +plm bTP bRA bWQ @@ -92456,8 +92336,8 @@ bQo bRz bSH plm -bTP -bRA +bVW +bVY bWQ bWQ bWQ @@ -92707,28 +92587,28 @@ bJv bKB bLK bMM -bOd -bOV +bNV +bOQ bQj bRy -bSG -daI +cfN +bUQ bUK bVT bWR bXQ -bOd +cfN bZF -bPc -bOd +bXT +bYK ccv cdw cex -bOd +caG cfN -cfN -bLK -aaf +cbF +bLQ +cdx bOh bOh bOh @@ -92969,20 +92849,20 @@ bJB bKV bRB bSI -bSI +bUS bUM -bVV bWS -bSI -bSI +bWS +bWS +bWT bZG caE cbA ccy -bOd -bOd +bZH +bZI bQu -cfO +bOd cgW cit cph @@ -93225,21 +93105,21 @@ bIF bOZ bQp bRA -bOd +bTP bTO -bUL -bVU -bMK -bXR -bYQ -bXR -bMK -cbz -ccx -cbA +bOd +bOd +bOd +bOd +bYS +bOd +bXU cbA +ccy +bZH +bZI cfi -bRH +bOd cgV bMQ aaf @@ -93481,21 +93361,21 @@ bMR bIH bJF bQr -bRA -bOd +bTQ bTP bOd -bVX -bMK -bMK -bYR -bMK -bMK -cbC -bRA -bTO -cez -cez +bOd +bOd +bOd +bOd +bYS +bOd +bOd +bOd +bOd +bOd +bOd +bOd cfQ cgY ciu @@ -93739,24 +93619,24 @@ bNY bPa bMQ bRC -bMQ -bTP -bUN -bVW -bMK -bXS -bXS -bXS -bMK -cbB -alk -alX -cbA -bQt +bSK +bOd +bOd +bOd +bOd +bOd +bYS +bOd +bOd +bOd +bOd +bOd +bOd +bOd apa cgX apF -apI +aaf bOh bOh bOh @@ -93997,20 +93877,20 @@ bPd cBF bRD bSK -bTR -bUP -bVZ -bWT -bWa -bYS -bZH -caF -bQt -cBJ -cdy bOd -bRy -cfR +bOd +bOd +bOd +bOd +bYS +bOd +bOd +bOd +cBJ +bOd +bOd +bOd +bOd cha civ cph @@ -94249,27 +94129,27 @@ bvd bKH bLK bMS -bOa +cfQ bPc bQs -bMZ +bTR bSJ -bTQ -bUO -bVY bOd bOd bOd bOd bOd -cbD -bTO -cdx +bXR +bOd +bOd +bOd +bOd +bOd +bOd bOd bOd -cfP cgZ -bMQ +bSK aaf bQA ckX @@ -94506,27 +94386,27 @@ bvd bKJ bLR bMV -bOd -bMZ +bTP +bOR bQv -bRF +bRH bSM -bTS -bUQ -agd -bUO -bVZ -bVZ -bZI -caH -cbF -ccz -cdA -cez -bOe -cfQ +bZJ +bOd +bOd +bOd +bOd +bOd +bOd +bOd +bOd +bOd +bOd +bOd +bOd +cbD chb -ciu +bSK bVu ckb ckZ @@ -94765,25 +94645,25 @@ bLK bMU bOc bPe -bQu +bTP bRE -bSJ -bPe -bOd -cCB -cCC -bXT -bXT -bXT -caG -cbE -bTU -cdz -cez bUL -cfP +cfT bOd -bMQ +bOd +bOd +bOd +bOd +bOd +bOd +bOd +bOd +bOd +bOd +bOd +cfP +ccz +bSJ aaf bOh bOh @@ -95020,25 +94900,25 @@ bvd bKH bLK bMX -bOd -bPg +bTP +bTT bQx bRH bSM bTU -bUS -bUS -cCD -bXU -bUS -bUS -bUS -bXU -bRF -bMW -cez -cez -cfQ +bOd +bOd +bOd +bOd +bOd +bOd +bOd +bOd +bOd +bMZ +bZJ +caH +cbE chd bQy cpP @@ -95283,18 +95163,18 @@ bQw bRG bSN bTT -bUR -bWb -cCE -bTT -bUR bZJ -bUR -bTT -bUR +bZJ +cCE +bWa +bZJ +bZJ +bZJ +bYL +bZJ cdB -bUR -bUR +caF +cbB cfT chc bMQ @@ -95538,7 +95418,7 @@ bOg bPi bQz bRJ -bSM +bUN bTV bUT bWc @@ -95546,12 +95426,12 @@ bWU bXV bYT bZK -bOd +cfT cbG ccA cdC ceB -cez +cbC cez chf cix @@ -95795,7 +95675,7 @@ bOf bPh bQy bRI -bSP +ceA bPh bQy bRI @@ -95808,7 +95688,7 @@ bPh bQy bRI ceA -bLK +bVO bLK che bLK From e769d28a2da7315c08f241e0de8f4747fb9f264e Mon Sep 17 00:00:00 2001 From: Trilbyspaceclone <30435998+Trilbyspaceclone@users.noreply.github.com> Date: Mon, 20 Apr 2020 18:47:18 -0400 Subject: [PATCH 10/55] Update weaponry.dm --- code/game/objects/items/weaponry.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/game/objects/items/weaponry.dm b/code/game/objects/items/weaponry.dm index 8496a8a216..7870bd9a0f 100644 --- a/code/game/objects/items/weaponry.dm +++ b/code/game/objects/items/weaponry.dm @@ -303,7 +303,6 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 custom_materials = list(/datum/material/iron=500, /datum/material/glass=500) resistance_flags = FIRE_PROOF - /obj/item/switchblade name = "switchblade" icon_state = "switchblade" @@ -646,10 +645,11 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 /mob/living/simple_animal/hostile/poison/bees/, /mob/living/simple_animal/butterfly, /mob/living/simple_animal/cockroach, + /mob/living/simple_animal/banana_spider, + /mob/living/simple_animal/hostile/poison/giant_spider, /obj/item/queen_bee )) - /obj/item/melee/flyswatter/afterattack(atom/target, mob/user, proximity_flag) . = ..() if(proximity_flag) From 21c304c5adc0e13e5be157e5b760684d5b6488f9 Mon Sep 17 00:00:00 2001 From: Anonymous Date: Tue, 21 Apr 2020 22:10:19 +0300 Subject: [PATCH 11/55] Fixes cosmetic tactifool sprite not using digi Also adds " to the armor values --- code/modules/clothing/under/syndicate.dm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/code/modules/clothing/under/syndicate.dm b/code/modules/clothing/under/syndicate.dm index 4fc62893b5..fb79c7a8a7 100644 --- a/code/modules/clothing/under/syndicate.dm +++ b/code/modules/clothing/under/syndicate.dm @@ -57,8 +57,8 @@ icon_state = "tactifool" item_state = "bl_suit" has_sensor = TRUE - mutantrace_variation = NONE - armor = list(melee = 0, bullet = 0, laser = 0,energy = 0, bomb = 0, bio = 0, rad = 0, fire = 0, acid = 0) + mutantrace_variation = STYLE_DIGITIGRADE + armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) /obj/item/clothing/under/syndicate/sniper name = "Tactical turtleneck suit" From e6159b1a82a7affdcf9e34ea39708a09005c1e1c Mon Sep 17 00:00:00 2001 From: Anonymous Date: Tue, 21 Apr 2020 22:24:38 +0300 Subject: [PATCH 12/55] Actually, this is better. --- code/modules/clothing/under/syndicate.dm | 1 - 1 file changed, 1 deletion(-) diff --git a/code/modules/clothing/under/syndicate.dm b/code/modules/clothing/under/syndicate.dm index fb79c7a8a7..3f61c4b45f 100644 --- a/code/modules/clothing/under/syndicate.dm +++ b/code/modules/clothing/under/syndicate.dm @@ -57,7 +57,6 @@ icon_state = "tactifool" item_state = "bl_suit" has_sensor = TRUE - mutantrace_variation = STYLE_DIGITIGRADE armor = list("melee" = 0, "bullet" = 0, "laser" = 0,"energy" = 0, "bomb" = 0, "bio" = 0, "rad" = 0, "fire" = 0, "acid" = 0) /obj/item/clothing/under/syndicate/sniper From 4fc041d4f4b4ff2f236305225cbcba896cf31551 Mon Sep 17 00:00:00 2001 From: MrJWhit <48370570+MrJWhit@users.noreply.github.com> Date: Tue, 21 Apr 2020 19:43:38 -0400 Subject: [PATCH 13/55] teg hot no hot aaaaaaah --- _maps/RandomRuins/StationRuins/Box/Engine/engine_teg.dmm | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/_maps/RandomRuins/StationRuins/Box/Engine/engine_teg.dmm b/_maps/RandomRuins/StationRuins/Box/Engine/engine_teg.dmm index 37bc2a7dde..ba438eccb9 100644 --- a/_maps/RandomRuins/StationRuins/Box/Engine/engine_teg.dmm +++ b/_maps/RandomRuins/StationRuins/Box/Engine/engine_teg.dmm @@ -1170,7 +1170,8 @@ /obj/machinery/atmospherics/components/unary/outlet_injector/atmos/engine_waste{ dir = 1 }, -/turf/open/floor/plating/airless, +/obj/structure/lattice/catwalk, +/turf/open/space/basic, /area/engine/engineering) "Hp" = ( /obj/machinery/atmospherics/components/binary/pump{ @@ -1332,7 +1333,8 @@ /area/engine/engineering) "LS" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/visible, -/turf/open/floor/plating/airless, +/obj/structure/lattice/catwalk, +/turf/open/space/basic, /area/engine/engineering) "Mf" = ( /obj/structure/closet/secure_closet/engineering_personal, From 286d1298fd7e73b7b3ba62f9036e2760a58c2666 Mon Sep 17 00:00:00 2001 From: MrJWhit <48370570+MrJWhit@users.noreply.github.com> Date: Tue, 21 Apr 2020 22:44:07 -0400 Subject: [PATCH 14/55] Fixes for atmos Sure are some gosh dilly dang fixes --- _maps/map_files/BoxStation/BoxStation.dmm | 197 +++++++--------------- 1 file changed, 58 insertions(+), 139 deletions(-) diff --git a/_maps/map_files/BoxStation/BoxStation.dmm b/_maps/map_files/BoxStation/BoxStation.dmm index 2cff435296..68302519b1 100644 --- a/_maps/map_files/BoxStation/BoxStation.dmm +++ b/_maps/map_files/BoxStation/BoxStation.dmm @@ -38626,12 +38626,6 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on, /turf/open/floor/plasteel, /area/science/misc_lab) -"bOa" = ( -/obj/machinery/atmospherics/pipe/simple/cyan/visible{ - dir = 6 - }, -/turf/open/floor/plasteel, -/area/engine/atmos) "bOb" = ( /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 8 @@ -40012,12 +40006,6 @@ }, /turf/open/floor/plasteel, /area/hallway/primary/aft) -"bRq" = ( -/obj/effect/turf_decal/tile/yellow{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/hallway/primary/aft) "bRr" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel, @@ -40032,6 +40020,10 @@ /area/engine/atmos) "bRt" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden, +/obj/machinery/firealarm{ + dir = 1; + pixel_y = -24 + }, /turf/open/floor/plasteel, /area/engine/atmos) "bRu" = ( @@ -40068,11 +40060,6 @@ }, /turf/open/floor/plasteel, /area/engine/atmos) -"bRz" = ( -/obj/effect/turf_decal/bot, -/obj/machinery/portable_atmospherics/canister/oxygen, -/turf/open/floor/plasteel, -/area/engine/atmos) "bRA" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ dir = 4 @@ -40123,13 +40110,6 @@ }, /turf/open/floor/plasteel, /area/engine/atmos) -"bRH" = ( -/obj/machinery/atmospherics/pipe/simple/green/visible{ - dir = 4 - }, -/obj/machinery/atmospherics/pipe/simple/yellow/visible, -/turf/open/floor/plasteel, -/area/engine/atmos) "bRI" = ( /obj/machinery/atmospherics/pipe/simple/cyan/visible, /obj/machinery/atmospherics/pipe/simple/green/visible{ @@ -40464,10 +40444,7 @@ /turf/closed/wall, /area/engine/atmos) "bSE" = ( -/obj/machinery/firealarm{ - dir = 1; - pixel_y = -24 - }, +/obj/effect/spawner/structure/window, /turf/open/floor/plasteel, /area/engine/atmos) "bSF" = ( @@ -40475,15 +40452,6 @@ /obj/machinery/portable_atmospherics/canister/nitrogen, /turf/open/floor/plasteel, /area/engine/atmos) -"bSG" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, -/turf/open/floor/plasteel, -/area/engine/atmos) -"bSH" = ( -/obj/effect/turf_decal/bot, -/obj/machinery/portable_atmospherics/canister/nitrogen, -/turf/open/floor/plasteel, -/area/engine/atmos) "bSI" = ( /obj/structure/cable{ icon_state = "1-2" @@ -40519,11 +40487,6 @@ }, /turf/open/floor/plating, /area/engine/atmos) -"bSP" = ( -/obj/effect/spawner/structure/window/reinforced, -/obj/machinery/atmospherics/pipe/simple/cyan/visible, -/turf/open/floor/plating, -/area/engine/atmos) "bSQ" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -40972,12 +40935,6 @@ /obj/machinery/atmospherics/pipe/simple/yellow/visible, /turf/open/floor/plasteel, /area/engine/atmos) -"bTT" = ( -/obj/machinery/atmospherics/pipe/manifold/yellow/visible{ - dir = 1 - }, -/turf/open/floor/plasteel, -/area/engine/atmos) "bTU" = ( /obj/machinery/atmospherics/pipe/simple/yellow/visible{ dir = 5 @@ -41391,10 +41348,6 @@ }, /turf/open/floor/plasteel, /area/engine/atmos) -"bUR" = ( -/obj/machinery/atmospherics/pipe/simple/yellow/visible, -/turf/open/floor/plasteel, -/area/engine/atmos) "bUS" = ( /obj/structure/cable{ icon_state = "1-2" @@ -41855,10 +41808,6 @@ /obj/machinery/meter, /turf/open/floor/plasteel, /area/engine/atmos) -"bWb" = ( -/obj/machinery/atmospherics/pipe/simple/yellow/visible, -/turf/open/floor/plasteel, -/area/engine/atmos) "bWc" = ( /obj/machinery/atmospherics/components/trinary/filter/atmos/n2o{ dir = 1 @@ -42142,6 +42091,10 @@ /obj/machinery/atmospherics/components/unary/vent_pump/on{ dir = 4 }, +/obj/machinery/airalarm{ + dir = 4; + pixel_x = -22 + }, /turf/open/floor/plasteel, /area/engine/atmos) "bWO" = ( @@ -42169,12 +42122,6 @@ }, /turf/open/floor/plasteel, /area/engine/atmos) -"bWS" = ( -/obj/structure/cable{ - icon_state = "1-2" - }, -/turf/open/floor/plasteel, -/area/engine/atmos) "bWT" = ( /obj/structure/cable{ icon_state = "1-2" @@ -42550,12 +42497,9 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ dir = 9 }, -/obj/machinery/door/poddoor/preopen{ - id = "atmos"; - name = "Atmospherics Blast Door" - }, -/obj/effect/turf_decal/delivery, -/turf/open/floor/plasteel, +/obj/item/toy/figure/atmos, +/obj/effect/decal/cleanable/oil/streak, +/turf/open/floor/plating, /area/engine/atmos) "bXM" = ( /obj/machinery/door/poddoor/preopen{ @@ -43007,24 +42951,6 @@ /obj/effect/landmark/event_spawn, /turf/closed/wall, /area/crew_quarters/bar) -"bYQ" = ( -/obj/structure/cable{ - icon_state = "4-8" - }, -/turf/open/floor/plating, -/area/engine/atmos) -"bYR" = ( -/obj/structure/cable{ - icon_state = "4-8" - }, -/turf/open/floor/plating, -/area/engine/atmos) -"bYS" = ( -/obj/structure/cable{ - icon_state = "4-8" - }, -/turf/open/floor/plating, -/area/engine/atmos) "bYT" = ( /obj/machinery/computer/atmos_control/tank/toxin_tank{ dir = 8 @@ -43348,10 +43274,6 @@ /obj/machinery/portable_atmospherics/scrubber, /turf/open/floor/plasteel, /area/engine/atmos) -"bZJ" = ( -/obj/machinery/atmospherics/pipe/simple/yellow/visible, -/turf/open/floor/plasteel, -/area/engine/atmos) "bZK" = ( /obj/machinery/atmospherics/components/trinary/filter/atmos/plasma{ dir = 1 @@ -44210,10 +44132,6 @@ }, /turf/open/floor/plating, /area/maintenance/port/aft) -"cbz" = ( -/obj/machinery/portable_atmospherics/pump, -/turf/open/floor/plasteel, -/area/engine/atmos) "cbA" = ( /obj/machinery/portable_atmospherics/pump, /turf/open/floor/plasteel, @@ -44640,10 +44558,6 @@ "ccw" = ( /turf/closed/wall/r_wall, /area/engine/engineering) -"ccx" = ( -/obj/machinery/space_heater, -/turf/open/floor/plasteel, -/area/engine/atmos) "ccy" = ( /obj/machinery/space_heater, /turf/open/floor/plasteel, @@ -52721,6 +52635,12 @@ /obj/item/instrument/violin, /turf/open/floor/wood, /area/crew_quarters/theatre) +"cGG" = ( +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ + dir = 4 + }, +/turf/closed/wall, +/area/engine/atmos) "cHf" = ( /obj/structure/cable{ icon_state = "4-8" @@ -57475,15 +57395,6 @@ }, /turf/open/floor/plasteel, /area/crew_quarters/fitness/pool) -"plm" = ( -/obj/structure/window/reinforced, -/obj/effect/turf_decal/bot, -/obj/machinery/portable_atmospherics/canister/nitrous_oxide, -/obj/machinery/atmospherics/pipe/simple/orange/visible{ - dir = 4 - }, -/turf/open/floor/plasteel, -/area/engine/atmos) "plC" = ( /obj/machinery/door/airlock/maintenance{ req_access_txt = "12" @@ -59925,6 +59836,14 @@ }, /turf/open/floor/wood, /area/crew_quarters/bar) +"wzX" = ( +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/atmospherics/pipe/simple/cyan/visible{ + dir = 4 + }, +/obj/machinery/atmospherics/pipe/simple/yellow/visible, +/turf/open/floor/plating, +/area/engine/atmos) "wBd" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 6 @@ -90016,10 +89935,10 @@ bCv bJq bKw bLH -bRq +bQf bNO bQg -bRq +bQf bQt bTK bTK @@ -90797,7 +90716,7 @@ bTM bUH bVQ bVZ -bXM +cGG bLK cew bTh @@ -91048,8 +90967,8 @@ bOd bNQ bOU bQj +bOd bSE -bMK bTN bTP bVP @@ -91306,7 +91225,7 @@ bNS bOX bQm bRv -bMK +bSE bTN bTP bVX @@ -91563,7 +91482,7 @@ bNR bOW bQl bRu -bMK +bSE bTN bUI bVR @@ -92076,9 +91995,9 @@ bOd bNT bOV bQo -bRz -bSH -plm +bRw +bSF +daI bTP bRA bWQ @@ -92333,9 +92252,9 @@ bMN bNV bOV bQo -bRz -bSH -plm +bRw +bSF +daI bVW bVY bWQ @@ -92851,9 +92770,9 @@ bRB bSI bUS bUM -bWS -bWS -bWS +bVV +bVV +bVV bWT bZG caE @@ -93111,7 +93030,7 @@ bOd bOd bOd bOd -bYS +bXS bOd bXU cbA @@ -93368,7 +93287,7 @@ bOd bOd bOd bOd -bYS +bXS bOd bOd bOd @@ -93625,7 +93544,7 @@ bOd bOd bOd bOd -bYS +bXS bOd bOd bOd @@ -93882,7 +93801,7 @@ bOd bOd bOd bOd -bYS +bXS bOd bOd bOd @@ -94389,9 +94308,9 @@ bMV bTP bOR bQv -bRH +bRF bSM -bZJ +bTS bOd bOd bOd @@ -94406,7 +94325,7 @@ bOd bOd cbD chb -bSK +wzX bVu ckb ckZ @@ -94901,9 +94820,9 @@ bKH bLK bMX bTP -bTT +bPg bQx -bRH +bRF bSM bTU bOd @@ -94916,7 +94835,7 @@ bOd bOd bOd bMZ -bZJ +bTS caH cbE chd @@ -95162,16 +95081,16 @@ bPf bQw bRG bSN -bTT -bZJ -bZJ +bPg +bTS +bTS cCE bWa -bZJ -bZJ -bZJ +bTS +bTS +bTS bYL -bZJ +bTS cdB caF cbB From 44925da1d8fd327058e64bb9d57776c631defe63 Mon Sep 17 00:00:00 2001 From: Putnam Date: Tue, 21 Apr 2020 20:52:33 -0700 Subject: [PATCH 15/55] Various dynamic tweaks --- code/datums/action.dm | 2 +- code/game/gamemodes/dynamic/dynamic.dm | 13 +++++++++++-- code/game/gamemodes/dynamic/dynamic_storytellers.dm | 6 +++--- code/game/machinery/cryopod.dm | 2 +- code/modules/admin/admin_verbs.dm | 2 +- .../antagonists/wizard/equipment/artefact.dm | 2 +- .../antagonists/wizard/equipment/spellbook.dm | 4 ++-- .../mob/living/simple_animal/hostile/carp.dm | 2 +- code/modules/shuttle/special.dm | 2 +- 9 files changed, 22 insertions(+), 13 deletions(-) diff --git a/code/datums/action.dm b/code/datums/action.dm index f2f93ac40d..8862482dc2 100644 --- a/code/datums/action.dm +++ b/code/datums/action.dm @@ -171,7 +171,7 @@ if(!..()) return 0 var/mob/M = target - M.ghostize(1) + M.ghostize(can_reenter_corpse = TRUE, voluntary = TRUE) /datum/action/proc/OnUpdatedIcon() UpdateButtonIcon() diff --git a/code/game/gamemodes/dynamic/dynamic.dm b/code/game/gamemodes/dynamic/dynamic.dm index d548f373db..1fa3d9b30d 100644 --- a/code/game/gamemodes/dynamic/dynamic.dm +++ b/code/game/gamemodes/dynamic/dynamic.dm @@ -164,7 +164,7 @@ GLOBAL_VAR_INIT(dynamic_storyteller_type, /datum/dynamic_storyteller/classic) dat += "Current threat: [threat] \[Adjust\] \[View Log\]
" dat += "
" - dat += "Storyteller: [storyteller.name]
" + dat += "Storyteller: [storyteller.name]
" dat += "Parameters: centre = [GLOB.dynamic_curve_centre] ; width = [GLOB.dynamic_curve_width].
" dat += "On average, [peaceful_percentage]% of the rounds are more peaceful.
" dat += "Forced extended: [GLOB.dynamic_forced_extended ? "On" : "Off"]
" @@ -222,6 +222,14 @@ GLOBAL_VAR_INIT(dynamic_storyteller_type, /datum/dynamic_storyteller/classic) show_threatlog(usr) else if (href_list["stacking_limit"]) GLOB.dynamic_stacking_limit = input(usr,"Change the threat limit at which round-endings rulesets will start to stack.", "Change stacking limit", null) as num + else if (href_list["change_storyteller"]) + var/list/choices = list() + for(var/T in config.storyteller_cache) + var/datum/dynamic_storyteller/S = T + choices[initial(S.name)] = T + var/selected_storyteller = input("Select storyteller:", "Storyteller", storyteller.name) as null|anything in choices + storyteller = new selected_storyteller + storyteller.on_start() admin_panel() // Refreshes the window @@ -721,7 +729,8 @@ GLOBAL_VAR_INIT(dynamic_storyteller_type, /datum/dynamic_storyteller/classic) if (O.started_as_observer) // Observers current_players[CURRENT_OBSERVERS].Add(M) continue - current_players[CURRENT_DEAD_PLAYERS].Add(M) // Players who actually died (and admins who ghosted, would be nice to avoid counting them somehow) + if(!voluntary_ghosted) + current_players[CURRENT_DEAD_PLAYERS].Add(M) // Players who actually died (and admins who ghosted, would be nice to avoid counting them somehow) threat = storyteller.calculate_threat() + added_threat if(threat_average_weight) var/cur_sample_weight = world.time - last_threat_sample_time diff --git a/code/game/gamemodes/dynamic/dynamic_storytellers.dm b/code/game/gamemodes/dynamic/dynamic_storytellers.dm index c37eb9bc2a..a781ea62d0 100644 --- a/code/game/gamemodes/dynamic/dynamic_storytellers.dm +++ b/code/game/gamemodes/dynamic/dynamic_storytellers.dm @@ -115,7 +115,7 @@ Property weights are: return 100 var/threat_perc = mode.threat/mode.threat_level - return round(max(0,100*(1-(threat_perc*threat_perc*threat_perc)))) + return CLAMP(round(100*(1-(threat_perc*threat_perc))**2,1),0,100) /datum/dynamic_storyteller/proc/roundstart_draft() var/list/drafted_rules = list() @@ -152,7 +152,7 @@ Property weights are: is 2.26 times as likely to be picked, all other things considered. Of course, we don't want it to GUARANTEE the closest, that's no fun, so it's just a weight. */ - threat_weight = 1-abs(1-LOGISTIC_FUNCTION(2,0.05,cost_difference,0)) + threat_weight = abs(1-abs(1-LOGISTIC_FUNCTION(2,0.05,cost_difference,0))) if (rule.ready()) var/property_weight = 0 for(var/property in property_weights) @@ -331,7 +331,7 @@ Property weights are: /datum/dynamic_storyteller/story/calculate_threat() var/current_time = (world.time / SSautotransfer.targettime)*180 mode.threat_level = round(mode.initial_threat_level*(sin(current_time)+0.25),0.1) - ..() + return ..() /datum/dynamic_storyteller/classic name = "Classic" diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm index 118145ed88..07f95c17ff 100644 --- a/code/game/machinery/cryopod.dm +++ b/code/game/machinery/cryopod.dm @@ -405,7 +405,7 @@ // Ghost and delete the mob. if(!mob_occupant.get_ghost(1)) - mob_occupant.ghostize(FALSE, penalize = TRUE) + mob_occupant.ghostize(FALSE, penalize = TRUE, voluntary = TRUE) QDEL_NULL(occupant) for(var/I in cryo_items) //only "CRYO_DESTROY_LATER" atoms are left) diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index cbd429af5c..b040c88a49 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -364,7 +364,7 @@ GLOBAL_PROTECT(admin_verbs_hideable) log_admin("[key_name(usr)] admin ghosted.") message_admins("[key_name_admin(usr)] admin ghosted.") var/mob/body = mob - body.ghostize(1) + body.ghostize(1, voluntary = TRUE) if(body && !body.key) body.key = "@[key]" //Haaaaaaaack. But the people have spoken. If it breaks; blame adminbus SSblackbox.record_feedback("tally", "admin_verb", 1, "Admin Ghost") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! diff --git a/code/modules/antagonists/wizard/equipment/artefact.dm b/code/modules/antagonists/wizard/equipment/artefact.dm index 7c63266255..ff3d95598d 100644 --- a/code/modules/antagonists/wizard/equipment/artefact.dm +++ b/code/modules/antagonists/wizard/equipment/artefact.dm @@ -159,7 +159,7 @@ /obj/item/scrying/attack_self(mob/user) to_chat(user, "You can see...everything!") visible_message("[user] stares into [src], their eyes glazing over.") - user.ghostize(1) + user.ghostize(1, voluntary = TRUE) /////////////////////////////////////////Necromantic Stone/////////////////// diff --git a/code/modules/antagonists/wizard/equipment/spellbook.dm b/code/modules/antagonists/wizard/equipment/spellbook.dm index 2bcda1d400..f33a9a2d42 100644 --- a/code/modules/antagonists/wizard/equipment/spellbook.dm +++ b/code/modules/antagonists/wizard/equipment/spellbook.dm @@ -294,7 +294,7 @@ name = "Staff of Change" desc = "An artefact that spits bolts of coruscating energy which cause the target's very form to reshape itself." item_path = /obj/item/gun/magic/staff/change - dynamic_requirement = 60 + dynamic_requirement = 200 /datum/spellbook_entry/item/staffanimation name = "Staff of Animation" @@ -361,7 +361,7 @@ desc = "A collection of wands that allow for a wide variety of utility. Wands have a limited number of charges, so be conservative in use. Comes in a handy belt." item_path = /obj/item/storage/belt/wands/full category = "Defensive" - dynamic_requirement = 60 + dynamic_requirement = 200 /datum/spellbook_entry/item/armor name = "Mastercrafted Armor Set" diff --git a/code/modules/mob/living/simple_animal/hostile/carp.dm b/code/modules/mob/living/simple_animal/hostile/carp.dm index 9c89ff4a4f..ced56f0705 100644 --- a/code/modules/mob/living/simple_animal/hostile/carp.dm +++ b/code/modules/mob/living/simple_animal/hostile/carp.dm @@ -7,7 +7,7 @@ icon_living = "carp" icon_dead = "carp_dead" icon_gib = "carp_gib" - threat = 0.2 + threat = 0.1 mob_biotypes = MOB_ORGANIC|MOB_BEAST speak_chance = 0 turns_per_move = 5 diff --git a/code/modules/shuttle/special.dm b/code/modules/shuttle/special.dm index 033187e353..87f9b55aa9 100644 --- a/code/modules/shuttle/special.dm +++ b/code/modules/shuttle/special.dm @@ -122,7 +122,7 @@ /obj/structure/table/abductor/wabbajack/proc/sleeper_dreams(mob/living/sleeper) if(sleeper in sleepers) to_chat(sleeper, "While you slumber, you have the strangest dream, like you can see yourself from the outside.") - sleeper.ghostize(TRUE) + sleeper.ghostize(TRUE, voluntary = TRUE) /obj/structure/table/abductor/wabbajack/left desc = "You sleep so it may wake." From 2ac9c70763391b659a030073d0857e63abfe739b Mon Sep 17 00:00:00 2001 From: Putnam Date: Tue, 21 Apr 2020 21:33:03 -0700 Subject: [PATCH 16/55] Makes storyteller changing actually work. --- code/game/gamemodes/dynamic/dynamic.dm | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/code/game/gamemodes/dynamic/dynamic.dm b/code/game/gamemodes/dynamic/dynamic.dm index 1fa3d9b30d..0b52909a91 100644 --- a/code/game/gamemodes/dynamic/dynamic.dm +++ b/code/game/gamemodes/dynamic/dynamic.dm @@ -227,9 +227,10 @@ GLOBAL_VAR_INIT(dynamic_storyteller_type, /datum/dynamic_storyteller/classic) for(var/T in config.storyteller_cache) var/datum/dynamic_storyteller/S = T choices[initial(S.name)] = T - var/selected_storyteller = input("Select storyteller:", "Storyteller", storyteller.name) as null|anything in choices + var/selected_storyteller = choices[input("Select storyteller:", "Storyteller", storyteller.name) as null|anything in choices] storyteller = new selected_storyteller storyteller.on_start() + message_admins("[key_name(usr)] changed the storyteller to [storyteller].", 1) admin_panel() // Refreshes the window From e70eb60d959d00964971e86b2c94bf3b70c4bf15 Mon Sep 17 00:00:00 2001 From: Putnam Date: Tue, 21 Apr 2020 21:33:19 -0700 Subject: [PATCH 17/55] Nono, it's the MOB that voluntary ghosts. --- code/game/gamemodes/dynamic/dynamic.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/gamemodes/dynamic/dynamic.dm b/code/game/gamemodes/dynamic/dynamic.dm index 0b52909a91..702da90651 100644 --- a/code/game/gamemodes/dynamic/dynamic.dm +++ b/code/game/gamemodes/dynamic/dynamic.dm @@ -730,7 +730,7 @@ GLOBAL_VAR_INIT(dynamic_storyteller_type, /datum/dynamic_storyteller/classic) if (O.started_as_observer) // Observers current_players[CURRENT_OBSERVERS].Add(M) continue - if(!voluntary_ghosted) + if(!M.voluntary_ghosted) current_players[CURRENT_DEAD_PLAYERS].Add(M) // Players who actually died (and admins who ghosted, would be nice to avoid counting them somehow) threat = storyteller.calculate_threat() + added_threat if(threat_average_weight) From 1bd3d4ceab959d12261b46f6ad4e14d27f3a0ab2 Mon Sep 17 00:00:00 2001 From: Putnam Date: Tue, 21 Apr 2020 21:50:51 -0700 Subject: [PATCH 18/55] Some storyteller tweaks. --- code/game/gamemodes/dynamic/dynamic_storytellers.dm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/code/game/gamemodes/dynamic/dynamic_storytellers.dm b/code/game/gamemodes/dynamic/dynamic_storytellers.dm index a781ea62d0..ab30b344c9 100644 --- a/code/game/gamemodes/dynamic/dynamic_storytellers.dm +++ b/code/game/gamemodes/dynamic/dynamic_storytellers.dm @@ -209,8 +209,8 @@ Property weights are: weight = 1 event_frequency_lower = 2 MINUTES event_frequency_upper = 10 MINUTES - flags = WAROPS_ALWAYS_ALLOWED - min_players = 40 + flags = WAROPS_ALWAYS_ALLOWED | FORCE_IF_WON + min_players = 30 var/refund_cooldown = 0 /datum/dynamic_storyteller/chaotic/do_process() @@ -232,7 +232,7 @@ Property weights are: curve_centre = 2 curve_width = 1.5 weight = 2 - min_players = 30 + min_players = 20 flags = WAROPS_ALWAYS_ALLOWED | USE_PREV_ROUND_WEIGHTS property_weights = list("valid" = 3, "trust" = 5) @@ -358,7 +358,7 @@ Property weights are: flags = NO_ASSASSIN | FORCE_IF_WON weight = 1 dead_player_weight = 5 - property_weights = list("extended" = 2, "chaos" = -1, "valid" = -1, "story_potential" = 1, "conversion" = -10) + property_weights = list("extended" = 2, "chaos" = -1, "valid" = -1, "conversion" = -10) /datum/dynamic_storyteller/no_antag name = "Extended" From 54820f0ecb37e171d3c2c5656a9b35fe65db6b06 Mon Sep 17 00:00:00 2001 From: Putnam Date: Tue, 21 Apr 2020 21:54:28 -0700 Subject: [PATCH 19/55] Made midround/latejoin come faster if no roundstarts --- code/game/gamemodes/dynamic/dynamic.dm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/code/game/gamemodes/dynamic/dynamic.dm b/code/game/gamemodes/dynamic/dynamic.dm index 702da90651..32fb4498dd 100644 --- a/code/game/gamemodes/dynamic/dynamic.dm +++ b/code/game/gamemodes/dynamic/dynamic.dm @@ -450,6 +450,8 @@ GLOBAL_VAR_INIT(dynamic_storyteller_type, /datum/dynamic_storyteller/classic) if(!drafted_rules.len) message_admins("Not enough threat level for roundstart antags!") log_game("DYNAMIC: Not enough threat level for roundstart antags!") + midround_injection_cooldown = round((midround_injection_cooldown + world.time) / 2, 1) + latejoin_injection_cooldown = round((latejoin_injection_cooldown + world.time) / 2, 1) var/indice_pop = min(10,round(roundstart_pop_ready/pop_per_requirement)+1) extra_rulesets_amount = 0 if (GLOB.dynamic_classic_secret) From eafdae5e66be03323cc1995b777250f6b4857549 Mon Sep 17 00:00:00 2001 From: MrJWhit <48370570+MrJWhit@users.noreply.github.com> Date: Wed, 22 Apr 2020 14:01:11 -0400 Subject: [PATCH 20/55] Swaps out some catwalks for latices to make travis happy --- .../StationRuins/Box/Engine/engine_teg.dmm | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/_maps/RandomRuins/StationRuins/Box/Engine/engine_teg.dmm b/_maps/RandomRuins/StationRuins/Box/Engine/engine_teg.dmm index ba438eccb9..a9c5eab318 100644 --- a/_maps/RandomRuins/StationRuins/Box/Engine/engine_teg.dmm +++ b/_maps/RandomRuins/StationRuins/Box/Engine/engine_teg.dmm @@ -103,10 +103,6 @@ /obj/structure/window/reinforced, /turf/open/floor/plasteel, /area/engine/engineering) -"dw" = ( -/obj/structure/lattice/catwalk, -/turf/open/space, -/area/space/nearstation) "dZ" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -2631,7 +2627,7 @@ EN fq LS Hn -dw +tw yf Rh yf @@ -2657,9 +2653,9 @@ XW ST Ok MP -dw -dw -dw +tw +tw +tw Rh Rh Rh From 8e7728c216b84b873fbb8f70212fa1d183ba1a2a Mon Sep 17 00:00:00 2001 From: MrJWhit <48370570+MrJWhit@users.noreply.github.com> Date: Wed, 22 Apr 2020 14:18:00 -0400 Subject: [PATCH 21/55] Reduce atmos suits, add pump to waste from mix, turn off air to waste pump --- _maps/map_files/BoxStation/BoxStation.dmm | 158 ++++++++++++++-------- 1 file changed, 101 insertions(+), 57 deletions(-) diff --git a/_maps/map_files/BoxStation/BoxStation.dmm b/_maps/map_files/BoxStation/BoxStation.dmm index 68302519b1..3b7f733d4c 100644 --- a/_maps/map_files/BoxStation/BoxStation.dmm +++ b/_maps/map_files/BoxStation/BoxStation.dmm @@ -39000,8 +39000,8 @@ /area/engine/atmos) "bOU" = ( /obj/machinery/holopad, -/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ - dir = 4 +/obj/machinery/atmospherics/pipe/manifold/scrubbers/hidden{ + dir = 1 }, /turf/open/floor/plasteel, /area/engine/atmos) @@ -39584,15 +39584,15 @@ /turf/open/floor/plasteel, /area/engine/atmos) "bQl" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 4 - }, /obj/effect/turf_decal/tile/yellow{ dir = 4 }, /obj/machinery/computer/atmos_alert{ dir = 8 }, +/obj/machinery/atmospherics/pipe/manifold/supply/hidden{ + dir = 1 + }, /turf/open/floor/plasteel/dark/corner, /area/engine/atmos) "bQm" = ( @@ -39653,11 +39653,11 @@ /turf/open/floor/plasteel, /area/engine/atmos) "bQs" = ( -/obj/machinery/atmospherics/components/binary/pump/on{ +/obj/machinery/atmospherics/pipe/simple/cyan/visible, +/obj/machinery/atmospherics/components/binary/pump{ dir = 8; name = "Air to Waste" }, -/obj/machinery/atmospherics/pipe/simple/cyan/visible, /turf/open/floor/plasteel, /area/engine/atmos) "bQt" = ( @@ -40033,6 +40033,7 @@ /obj/machinery/computer/atmos_alert{ dir = 8 }, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel/dark/corner, /area/engine/atmos) "bRv" = ( @@ -40444,8 +40445,10 @@ /turf/closed/wall, /area/engine/atmos) "bSE" = ( -/obj/effect/spawner/structure/window, -/turf/open/floor/plasteel, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 5 + }, +/turf/closed/wall, /area/engine/atmos) "bSF" = ( /obj/effect/turf_decal/bot, @@ -40893,21 +40896,20 @@ /obj/machinery/atmospherics/pipe/simple/orange/visible{ dir = 4 }, -/obj/effect/spawner/structure/window, /turf/open/floor/plasteel, /area/engine/atmos) "bTN" = ( /obj/machinery/atmospherics/pipe/simple/orange/visible{ dir = 4 }, -/obj/structure/closet/secure_closet/atmospherics, -/obj/item/cartridge/atmos, +/obj/effect/spawner/structure/window, /turf/open/floor/plasteel, /area/engine/atmos) "bTO" = ( -/obj/machinery/atmospherics/pipe/simple/orange/visible{ +/obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden, /turf/open/floor/plasteel, /area/engine/atmos) "bTP" = ( @@ -40921,6 +40923,7 @@ dir = 8; name = "Waste to Filter" }, +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible, /turf/open/floor/plasteel, /area/engine/atmos) "bTR" = ( @@ -41273,10 +41276,6 @@ dir = 4 }, /obj/machinery/atmospherics/pipe/simple/supply/hidden, -/obj/machinery/door/airlock/atmos{ - name = "Atmospherics"; - req_access_txt = "24" - }, /turf/open/floor/plasteel, /area/engine/atmos) "bUI" = ( @@ -41716,14 +41715,10 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ dir = 6 }, -/obj/effect/turf_decal/stripes/line{ - dir = 9 - }, -/obj/machinery/suit_storage_unit/atmos, +/obj/effect/spawner/structure/window, /turf/open/floor/plasteel, /area/engine/atmos) "bVQ" = ( -/obj/effect/spawner/structure/window, /obj/machinery/atmospherics/pipe/simple/supply/hidden, /turf/open/floor/plasteel, /area/engine/atmos) @@ -41782,10 +41777,14 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ dir = 4 }, -/obj/effect/turf_decal/stripes/line{ - dir = 1 - }, /obj/machinery/suit_storage_unit/atmos, +/obj/machinery/airalarm{ + dir = 1; + pixel_y = -22 + }, +/obj/effect/turf_decal/stripes/line{ + dir = 9 + }, /turf/open/floor/plasteel, /area/engine/atmos) "bVY" = ( @@ -41796,10 +41795,10 @@ /turf/open/floor/plasteel, /area/engine/atmos) "bVZ" = ( -/obj/machinery/atmospherics/pipe/simple/supply/hidden{ - dir = 9 +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 1 }, -/turf/closed/wall, +/turf/open/floor/plasteel, /area/engine/atmos) "bWa" = ( /obj/machinery/atmospherics/pipe/manifold/yellow/visible{ @@ -42088,9 +42087,6 @@ }, /area/engine/atmos) "bWN" = ( -/obj/machinery/atmospherics/components/unary/vent_pump/on{ - dir = 4 - }, /obj/machinery/airalarm{ dir = 4; pixel_x = -22 @@ -42497,9 +42493,7 @@ /obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ dir = 9 }, -/obj/item/toy/figure/atmos, -/obj/effect/decal/cleanable/oil/streak, -/turf/open/floor/plating, +/turf/closed/wall, /area/engine/atmos) "bXM" = ( /obj/machinery/door/poddoor/preopen{ @@ -42939,8 +42933,12 @@ /turf/open/floor/plasteel, /area/hallway/primary/aft) "bYN" = ( -/turf/closed/wall, -/area/security/checkpoint/engineering) +/obj/effect/spawner/structure/window/reinforced, +/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ + dir = 4 + }, +/turf/open/floor/plating, +/area/engine/atmos) "bYO" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -52283,10 +52281,8 @@ /turf/open/floor/engine/vacuum, /area/science/mixing) "cBF" = ( -/obj/machinery/atmospherics/pipe/manifold/scrubbers/visible{ - dir = 8 - }, /obj/effect/landmark/event_spawn, +/obj/machinery/atmospherics/pipe/manifold4w/scrubbers/visible, /turf/open/floor/plasteel, /area/engine/atmos) "cBG" = ( @@ -52636,10 +52632,11 @@ /turf/open/floor/wood, /area/crew_quarters/theatre) "cGG" = ( -/obj/machinery/atmospherics/pipe/simple/scrubbers/visible{ - dir = 4 +/obj/effect/spawner/structure/window, +/obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ + dir = 10 }, -/turf/closed/wall, +/turf/open/floor/plasteel, /area/engine/atmos) "cHf" = ( /obj/structure/cable{ @@ -53964,6 +53961,16 @@ dir = 4 }, /area/crew_quarters/fitness/pool) +"ecE" = ( +/obj/machinery/atmospherics/pipe/simple/cyan/visible{ + dir = 4 + }, +/obj/machinery/atmospherics/components/binary/pump{ + dir = 1; + name = "Mix to Waste" + }, +/turf/open/floor/plasteel, +/area/engine/atmos) "edA" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 @@ -54699,6 +54706,16 @@ }, /turf/open/floor/carpet, /area/crew_quarters/cryopod) +"gfJ" = ( +/obj/machinery/atmospherics/pipe/simple/cyan/visible{ + dir = 4 + }, +/obj/machinery/door/airlock/atmos{ + name = "Atmospherics"; + req_access_txt = "24" + }, +/turf/open/floor/plasteel, +/area/engine/atmos) "ghq" = ( /obj/structure/lattice/catwalk, /obj/item/stack/marker_beacon{ @@ -54719,6 +54736,17 @@ "gjl" = ( /turf/closed/wall, /area/quartermaster/warehouse) +"glY" = ( +/obj/machinery/atmospherics/pipe/simple/orange/visible{ + dir = 4 + }, +/obj/structure/closet/secure_closet/atmospherics, +/obj/item/cartridge/atmos, +/obj/machinery/atmospherics/components/unary/vent_scrubber/on{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/engine/atmos) "gnf" = ( /obj/structure/disposalpipe/segment{ dir = 4 @@ -55442,6 +55470,11 @@ /obj/item/coin/silver, /turf/open/floor/plating, /area/maintenance/starboard/fore) +"iYC" = ( +/obj/effect/spawner/structure/window, +/obj/machinery/atmospherics/pipe/simple/supply/hidden, +/turf/open/floor/plasteel, +/area/engine/atmos) "iYE" = ( /obj/machinery/atmospherics/pipe/simple/supply/hidden{ dir = 4 @@ -57858,6 +57891,17 @@ /obj/structure/chair/sofa/left, /turf/open/floor/plasteel, /area/security/prison) +"rca" = ( +/obj/machinery/atmospherics/pipe/simple/orange/visible{ + dir = 4 + }, +/obj/structure/closet/secure_closet/atmospherics, +/obj/item/cartridge/atmos, +/obj/machinery/atmospherics/components/unary/vent_pump/on{ + dir = 1 + }, +/turf/open/floor/plasteel, +/area/engine/atmos) "rcD" = ( /obj/machinery/atmospherics/pipe/simple/scrubbers/hidden{ dir = 4 @@ -90203,7 +90247,7 @@ bUG bVO bWO bXK -bMK +bLK bZz caw bYH @@ -90716,7 +90760,7 @@ bTM bUH bVQ bVZ -cGG +bXM bLK cew bTh @@ -90966,11 +91010,11 @@ bLL bOd bNQ bOU -bQj -bOd +bTO +bRr bSE bTN -bTP +gfJ bVP bWP bXL @@ -91225,13 +91269,13 @@ bNS bOX bQm bRv -bSE -bTN +cGG +glY bTP bVX bWQ bWQ -bYN +bWQ bRm bTj caA @@ -91482,8 +91526,8 @@ bNR bOW bQl bRu -bSE -bTN +iYC +rca bUI bVR bWQ @@ -91991,7 +92035,7 @@ bCv bJs bKz bLK -bOd +bQr bNT bOV bQo @@ -93025,7 +93069,7 @@ bOZ bQp bRA bTP -bTO +bOd bOd bOd bOd @@ -93279,9 +93323,9 @@ bLK bMR bIH bJF -bQr +bRy bTQ -bTP +ecE bOd bOd bOd @@ -93536,7 +93580,7 @@ bLK bMQ bNY bPa -bMQ +bYN bRC bSK bOd From 63870cc9d1fce651cac364996655132440b078e1 Mon Sep 17 00:00:00 2001 From: Ghommie <42542238+Ghommie@users.noreply.github.com> Date: Wed, 22 Apr 2020 22:01:39 +0200 Subject: [PATCH 22/55] Movespeed modifiers refactor port. --- code/__DEFINES/combat.dm | 3 - code/__DEFINES/mobs.dm | 4 + code/__DEFINES/movespeed_modification.dm | 78 +------ code/__HELPERS/_lists.dm | 64 ++++-- .../configuration/entries/game_options.dm | 10 + code/controllers/subsystem/timer.dm | 4 +- code/datums/components/mood.dm | 12 +- code/datums/components/riding.dm | 4 +- code/datums/components/shrink.dm | 4 +- code/datums/dna.dm | 4 +- code/datums/status_effects/debuffs.dm | 19 +- code/game/objects/effects/mines.dm | 4 +- code/game/objects/items/tanks/jetpack.dm | 4 +- .../changeling/powers/strained_muscles.dm | 6 +- .../antagonists/slaughter/slaughter.dm | 4 +- code/modules/mob/living/carbon/carbon.dm | 5 +- code/modules/mob/living/carbon/human/human.dm | 14 +- .../mob/living/carbon/human/human_movement.dm | 12 +- .../mob/living/carbon/human/species.dm | 32 +-- .../mob/living/carbon/monkey/monkey.dm | 8 +- code/modules/mob/living/living_mobility.dm | 6 +- code/modules/mob/living/living_movement.dm | 24 +- code/modules/mob/living/silicon/pai/pai.dm | 4 +- .../simple_animal/hostile/giant_spider.dm | 4 +- .../mob/living/simple_animal/simple_animal.dm | 4 +- .../mob/living/simple_animal/slime/slime.dm | 13 +- code/modules/mob/living/status_procs.dm | 34 ++- code/modules/mob/mob.dm | 17 +- code/modules/mob/mob_defines.dm | 5 +- code/modules/mob/mob_movement.dm | 4 +- code/modules/mob/mob_movespeed.dm | 126 ---------- code/modules/movespeed/_movespeed_modifier.dm | 217 ++++++++++++++++++ .../modules/movespeed/modifiers/components.dm | 21 ++ code/modules/movespeed/modifiers/innate.dm | 20 ++ code/modules/movespeed/modifiers/items.dm | 12 + code/modules/movespeed/modifiers/misc.dm | 6 + code/modules/movespeed/modifiers/mobs.dm | 120 ++++++++++ code/modules/movespeed/modifiers/reagents.dm | 14 ++ .../movespeed/modifiers/status_effects.dm | 44 ++++ .../chemistry/reagents/drug_reagents.dm | 4 +- .../chemistry/reagents/medicine_reagents.dm | 16 +- .../chemistry/reagents/other_reagents.dm | 4 +- .../crossbreeding/_status_effects.dm | 24 +- code/modules/station_goals/dna_vault.dm | 2 +- code/modules/surgery/organs/augments_chest.dm | 4 +- code/modules/surgery/organs/liver.dm | 8 +- .../code/datums/status_effects/chems.dm | 18 +- tgstation.dme | 9 +- 48 files changed, 696 insertions(+), 383 deletions(-) delete mode 100644 code/modules/mob/mob_movespeed.dm create mode 100644 code/modules/movespeed/_movespeed_modifier.dm create mode 100644 code/modules/movespeed/modifiers/components.dm create mode 100644 code/modules/movespeed/modifiers/innate.dm create mode 100644 code/modules/movespeed/modifiers/items.dm create mode 100644 code/modules/movespeed/modifiers/misc.dm create mode 100644 code/modules/movespeed/modifiers/mobs.dm create mode 100644 code/modules/movespeed/modifiers/reagents.dm create mode 100644 code/modules/movespeed/modifiers/status_effects.dm diff --git a/code/__DEFINES/combat.dm b/code/__DEFINES/combat.dm index 14c78f90d0..b1664c5a7d 100644 --- a/code/__DEFINES/combat.dm +++ b/code/__DEFINES/combat.dm @@ -111,9 +111,6 @@ #define GRAB_NECK 2 #define GRAB_KILL 3 -//slowdown when in softcrit -#define SOFTCRIT_ADD_SLOWDOWN 6 - /// Attack types for check_block()/run_block(). Flags, combinable. /// Attack was melee, whether or not armed. #define ATTACK_TYPE_MELEE (1<<0) diff --git a/code/__DEFINES/mobs.dm b/code/__DEFINES/mobs.dm index e5f817614b..c89bd4843e 100644 --- a/code/__DEFINES/mobs.dm +++ b/code/__DEFINES/mobs.dm @@ -291,3 +291,7 @@ #define PULL_PRONE_SLOWDOWN 0.6 #define FIREMAN_CARRY_SLOWDOWN 0 #define PIGGYBACK_CARRY_SLOWDOWN 1 +//slowdown when in softcrit. Note that crawling slowdown will also apply at the same time! +#define SOFTCRIT_ADD_SLOWDOWN 2 +//slowdown when crawling +#define CRAWLING_ADD_SLOWDOWN 4 diff --git a/code/__DEFINES/movespeed_modification.dm b/code/__DEFINES/movespeed_modification.dm index 4d40474a3c..1f3ae63940 100644 --- a/code/__DEFINES/movespeed_modification.dm +++ b/code/__DEFINES/movespeed_modification.dm @@ -1,12 +1,3 @@ -#define MOVESPEED_DATA_INDEX_PRIORITY 1 -#define MOVESPEED_DATA_INDEX_FLAGS 2 -#define MOVESPEED_DATA_INDEX_MULTIPLICATIVE_SLOWDOWN 3 -#define MOVESPEED_DATA_INDEX_MOVETYPE 4 -#define MOVESPEED_DATA_INDEX_BL_MOVETYPE 5 -#define MOVESPEED_DATA_INDEX_CONFLICT 6 - -#define MOVESPEED_DATA_INDEX_MAX 6 - //flags #define IGNORE_NOSLOW (1 << 0) @@ -15,70 +6,7 @@ #define MOVE_CONFLICT_JETPACK "JETPACK" //ids +#define MOVESPEED_ID_SANITY "mood_sanity" -#define MOVESPEED_ID_MOB_WALK_RUN_CONFIG_SPEED "MOB_WALK_RUN" -#define MOVESPEED_ID_MOB_GRAB_STATE "MOB_GRAB_STATE" -#define MOVESPEED_ID_MOB_EQUIPMENT "MOB_EQUIPMENT" -#define MOVESPEED_ID_MOB_GRAVITY "MOB_GRAVITY" -#define MOVESPEED_ID_CONFIG_SPEEDMOD "MOB_CONFIG_MODIFIER" - -#define MOVESPEED_ID_SLIME_REAGENTMOD "SLIME_REAGENT_MODIFIER" -#define MOVESPEED_ID_SLIME_HEALTHMOD "SLIME_HEALTH_MODIFIER" -#define MOVESPEED_ID_SLIME_TEMPMOD "SLIME_TEMPERATURE_MODIFIER" - -#define MOVESPEED_ID_SLIME_STATUS "SLIME_STATUS" - -#define MOVESPEED_ID_TARANTULA_WEB "TARANTULA_WEB" - -#define MOVESPEED_ID_LIVING_TURF_SPEEDMOD "LIVING_TURF_SPEEDMOD" -#define MOVESPEED_ID_LIVING_LIMBLESS "LIVING_LIMBLESS" - -#define MOVESPEED_ID_CARBON_SOFTCRIT "CARBON_SOFTCRIT" -#define MOVESPEED_ID_CARBON_OLDSPEED "CARBON_DEPRECATED_SPEED" - -#define MOVESPEED_ID_DNA_VAULT "DNA_VAULT" - -#define MOVESPEED_ID_YELLOW_ORB "YELLOW_ORB" - -#define MOVESPEED_ID_TARFOOT "TARFOOT" - -#define MOVESPEED_ID_SEPIA "SEPIA" - -#define MOVESPEED_ID_MONKEY_REAGENT_SPEEDMOD "MONKEY_REAGENT_SPEEDMOD" -#define MOVESPEED_ID_MONKEY_TEMPERATURE_SPEEDMOD "MONKEY_TEMPERATURE_SPEEDMOD" -#define MOVESPEED_ID_MONKEY_HEALTH_SPEEDMOD "MONKEY_HEALTH_SPEEDMOD" - -#define MOVESPEED_ID_CHANGELING_MUSCLES "CHANGELING_MUSCLES" - -#define MOVESPEED_ID_SIMPLEMOB_VARSPEED "SIMPLEMOB_VARSPEED_MODIFIER" -#define MOVESPEED_ID_ADMIN_VAREDIT "ADMIN_VAREDIT_MODIFIER" - -#define MOVESPEED_ID_PAI_SPACEWALK_SPEEDMOD "PAI_SPACEWALK_MODIFIER" - -#define MOVESPEED_ID_SANITY "MOOD_SANITY" - -#define MOVESPEED_ID_SPECIES "SPECIES_SPEED_MOD" - -#define MOVESPEED_ID_SMALL_STRIDE "SMALL_STRIDE" -#define MOVESPEED_ID_PRONE_DRAGGING "PRONE_DRAG" -#define MOVESPEED_ID_HUMAN_CARRYING "HUMAN_CARRY" -#define MOVESPEED_ID_SHRINK_RAY "SHRUNKEN_SPEED_MODIFIER" - -#define MOVESPEED_ID_SLAUGHTER "SLAUGHTER" - -#define MOVESPEED_ID_CYBER_THRUSTER "CYBER_IMPLANT_THRUSTER" -#define MOVESPEED_ID_JETPACK "JETPACK" - -#define MOVESPEED_ID_MKULTRA "MKULTRA" - -#define MOVESPEED_ID_TASED_STATUS "TASED" -#define MOVESPEED_ID_ELECTROSTAFF "ELECTROSTAFF" - -#define MOVESPEED_ID_SHOVE "SHOVE" -#define MOVESPEED_ID_FAT "FAT" -#define MOVESPEED_ID_COLD "COLD" -#define MOVESPEED_ID_HUNGRY "HUNGRY" -#define MOVESPEED_ID_DAMAGE_SLOWDOWN "DAMAGE" -#define MOVESPEED_ID_DAMAGE_SLOWDOWN_FLYING "FLYING" - -#define MOVESPEED_ID_CIRRHOSIS "CIRRHOSIS" \ No newline at end of file +#define MOVESPEED_ID_MOB_GRAB_STATE "mob_grab_state" +#define MOVESPEED_ID_MOB_WALK_RUN "mob_walk_run" diff --git a/code/__HELPERS/_lists.dm b/code/__HELPERS/_lists.dm index a34b3ce67c..de7253c6a9 100644 --- a/code/__HELPERS/_lists.dm +++ b/code/__HELPERS/_lists.dm @@ -11,6 +11,7 @@ #define LAZYINITLIST(L) if (!L) L = list() #define UNSETEMPTY(L) if (L && !length(L)) L = null +#define LAZYCOPY(L) (L ? L.Copy() : list() ) #define LAZYREMOVE(L, I) if(L) { L -= I; if(!length(L)) { L = null; } } #define LAZYADD(L, I) if(!L) { L = list(); } L += I; #define LAZYOR(L, I) if(!L) { L = list(); } L |= I; @@ -21,34 +22,47 @@ #define LAZYCLEARLIST(L) if(L) L.Cut() #define SANITIZE_LIST(L) ( islist(L) ? L : list() ) #define reverseList(L) reverseRange(L.Copy()) +#define LAZYADDASSOC(L, K, V) if(!L) { L = list(); } L[K] += list(V); +#define LAZYREMOVEASSOC(L, K, V) if(L) { if(L[K]) { L[K] -= V; if(!length(L[K])) L -= K; } if(!length(L)) L = null; } -// binary search sorted insert -// IN: Object to be inserted -// LIST: List to insert object into -// TYPECONT: The typepath of the contents of the list -// COMPARE: The variable on the objects to compare -#define BINARY_INSERT(IN, LIST, TYPECONT, COMPARE) \ - var/__BIN_CTTL = length(LIST);\ - if(!__BIN_CTTL) {\ - LIST += IN;\ - } else {\ - var/__BIN_LEFT = 1;\ - var/__BIN_RIGHT = __BIN_CTTL;\ - var/__BIN_MID = (__BIN_LEFT + __BIN_RIGHT) >> 1;\ - var/##TYPECONT/__BIN_ITEM;\ - while(__BIN_LEFT < __BIN_RIGHT) {\ - __BIN_ITEM = LIST[__BIN_MID];\ - if(__BIN_ITEM.##COMPARE <= IN.##COMPARE) {\ - __BIN_LEFT = __BIN_MID + 1;\ - } else {\ - __BIN_RIGHT = __BIN_MID;\ +/// Passed into BINARY_INSERT to compare keys +#define COMPARE_KEY __BIN_LIST[__BIN_MID] +/// Passed into BINARY_INSERT to compare values +#define COMPARE_VALUE __BIN_LIST[__BIN_LIST[__BIN_MID]] + +/**** + * Binary search sorted insert + * INPUT: Object to be inserted + * LIST: List to insert object into + * TYPECONT: The typepath of the contents of the list + * COMPARE: The object to compare against, usualy the same as INPUT + * COMPARISON: The variable on the objects to compare + */ +#define BINARY_INSERT(INPUT, LIST, TYPECONT, COMPARE, COMPARISON, COMPTYPE) \ + do {\ + var/list/__BIN_LIST = LIST;\ + var/__BIN_CTTL = length(__BIN_LIST);\ + if(!__BIN_CTTL) {\ + __BIN_LIST += INPUT;\ + } else {\ + var/__BIN_LEFT = 1;\ + var/__BIN_RIGHT = __BIN_CTTL;\ + var/__BIN_MID = (__BIN_LEFT + __BIN_RIGHT) >> 1;\ + var/##TYPECONT/__BIN_ITEM;\ + while(__BIN_LEFT < __BIN_RIGHT) {\ + __BIN_ITEM = COMPTYPE;\ + if(__BIN_ITEM.##COMPARISON <= COMPARE.##COMPARISON) {\ + __BIN_LEFT = __BIN_MID + 1;\ + } else {\ + __BIN_RIGHT = __BIN_MID;\ + };\ + __BIN_MID = (__BIN_LEFT + __BIN_RIGHT) >> 1;\ };\ - __BIN_MID = (__BIN_LEFT + __BIN_RIGHT) >> 1;\ + __BIN_ITEM = COMPTYPE;\ + __BIN_MID = __BIN_ITEM.##COMPARISON > COMPARE.##COMPARISON ? __BIN_MID : __BIN_MID + 1;\ + __BIN_LIST.Insert(__BIN_MID, INPUT);\ };\ - __BIN_ITEM = LIST[__BIN_MID];\ - __BIN_MID = __BIN_ITEM.##COMPARE > IN.##COMPARE ? __BIN_MID : __BIN_MID + 1;\ - LIST.Insert(__BIN_MID, IN);\ - } + } while(FALSE) //Returns a list in plain english as a string /proc/english_list(list/input, nothing_text = "nothing", and_text = " and ", comma_text = ", ", final_comma_text = "" ) diff --git a/code/controllers/configuration/entries/game_options.dm b/code/controllers/configuration/entries/game_options.dm index 60eda61802..61d396a5af 100644 --- a/code/controllers/configuration/entries/game_options.dm +++ b/code/controllers/configuration/entries/game_options.dm @@ -248,8 +248,18 @@ /datum/config_entry/number/movedelay/run_delay +/datum/config_entry/number/movedelay/run_delay/ValidateAndSet() + . = ..() + var/datum/movespeed_modifier/config_walk_run/M = get_cached_movespeed_modifier(/datum/movespeed_modifier/config_walk_run/run) + M.sync() + /datum/config_entry/number/movedelay/walk_delay +/datum/config_entry/number/movedelay/walk_delay/ValidateAndSet() + . = ..() + var/datum/movespeed_modifier/config_walk_run/M = get_cached_movespeed_modifier(/datum/movespeed_modifier/config_walk_run/walk) + M.sync() + /datum/config_entry/number/movedelay/sprint_speed_increase config_entry_value = 1 diff --git a/code/controllers/subsystem/timer.dm b/code/controllers/subsystem/timer.dm index bd2fb854af..36bf992cfb 100644 --- a/code/controllers/subsystem/timer.dm +++ b/code/controllers/subsystem/timer.dm @@ -94,7 +94,7 @@ SUBSYSTEM_DEF(timer) if(ctime_timer.flags & TIMER_LOOP) ctime_timer.spent = 0 ctime_timer.timeToRun = REALTIMEOFDAY + ctime_timer.wait - BINARY_INSERT(ctime_timer, clienttime_timers, datum/timedevent, timeToRun) + BINARY_INSERT(ctime_timer, clienttime_timers, datum/timedevent, ctime_timer, timeToRun, COMPARE_KEY) else qdel(ctime_timer) @@ -423,7 +423,7 @@ SUBSYSTEM_DEF(timer) L = SStimer.second_queue if(L) - BINARY_INSERT(src, L, datum/timedevent, timeToRun) + BINARY_INSERT(src, L, datum/timedevent, src, timeToRun, COMPARE_KEY) return //get the list of buckets diff --git a/code/datums/components/mood.dm b/code/datums/components/mood.dm index 5e9382f88e..6938046e11 100644 --- a/code/datums/components/mood.dm +++ b/code/datums/components/mood.dm @@ -175,27 +175,27 @@ switch(sanity) if(-INFINITY to SANITY_CRAZY) setInsanityEffect(MAJOR_INSANITY_PEN) - master.add_movespeed_modifier(MOVESPEED_ID_SANITY, TRUE, 100, override=TRUE, multiplicative_slowdown=1.5) //Did we change something ? movetypes is runtiming, movetypes=(~FLYING)) + master.add_movespeed_modifier(/datum/movespeed_modifier/sanity/insane) sanity_level = 6 if(SANITY_CRAZY to SANITY_UNSTABLE) setInsanityEffect(MINOR_INSANITY_PEN) - master.add_movespeed_modifier(MOVESPEED_ID_SANITY, TRUE, 100, override=TRUE, multiplicative_slowdown=1)//, movetypes=(~FLYING)) + master.add_movespeed_modifier(/datum/movespeed_modifier/sanity/crazy) sanity_level = 5 if(SANITY_UNSTABLE to SANITY_DISTURBED) setInsanityEffect(0) - master.add_movespeed_modifier(MOVESPEED_ID_SANITY, TRUE, 100, override=TRUE, multiplicative_slowdown=0.5)//, movetypes=(~FLYING)) + master.add_movespeed_modifier(/datum/movespeed_modifier/sanity/disturbed) sanity_level = 4 if(SANITY_DISTURBED to SANITY_NEUTRAL) setInsanityEffect(0) - master.remove_movespeed_modifier(MOVESPEED_ID_SANITY, TRUE) + master.remove_movespeed_modifier(MOVESPEED_ID_SANITY) sanity_level = 3 if(SANITY_NEUTRAL+1 to SANITY_GREAT+1) //shitty hack but +1 to prevent it from responding to super small differences setInsanityEffect(0) - master.remove_movespeed_modifier(MOVESPEED_ID_SANITY, TRUE) + master.remove_movespeed_modifier(MOVESPEED_ID_SANITY) sanity_level = 2 if(SANITY_GREAT+1 to INFINITY) setInsanityEffect(0) - master.remove_movespeed_modifier(MOVESPEED_ID_SANITY, TRUE) + master.remove_movespeed_modifier(MOVESPEED_ID_SANITY) sanity_level = 1 //update_mood_icon() diff --git a/code/datums/components/riding.dm b/code/datums/components/riding.dm index 4d8cfc4412..9b7eaa49ca 100644 --- a/code/datums/components/riding.dm +++ b/code/datums/components/riding.dm @@ -204,7 +204,7 @@ . = ..() var/mob/living/carbon/human/H = parent if(!length(H.buckled_mobs)) - H.remove_movespeed_modifier(MOVESPEED_ID_HUMAN_CARRYING) + H.remove_movespeed_modifier(/datum/movespeed_modifier/human_carry) if(!fireman_carrying) M.Daze(25) REMOVE_TRAIT(M, TRAIT_MOBILITY_NOUSE, src) @@ -213,7 +213,7 @@ . = ..() var/mob/living/carbon/human/H = parent if(length(H.buckled_mobs)) - H.add_movespeed_modifier(MOVESPEED_ID_HUMAN_CARRYING, multiplicative_slowdown = fireman_carrying? FIREMAN_CARRY_SLOWDOWN : PIGGYBACK_CARRY_SLOWDOWN) + H.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/human_carry, TRUE, fireman_carrying? FIREMAN_CARRY_SLOWDOWN : PIGGYBACK_CARRY_SLOWDOWN) if(fireman_carrying) ADD_TRAIT(M, TRAIT_MOBILITY_NOUSE, src) diff --git a/code/datums/components/shrink.dm b/code/datums/components/shrink.dm index f070d9b22f..96807fe313 100644 --- a/code/datums/components/shrink.dm +++ b/code/datums/components/shrink.dm @@ -14,7 +14,7 @@ parent_atom.opacity = 0 if(isliving(parent_atom)) var/mob/living/L = parent_atom - L.add_movespeed_modifier(MOVESPEED_ID_SHRINK_RAY, update=TRUE, priority=100, multiplicative_slowdown=4) + L.add_movespeed_modifier(/datum/movespeed_modifier/shrink_ray) if(iscarbon(L)) var/mob/living/carbon/C = L C.unequip_everything() @@ -35,7 +35,7 @@ parent_atom.opacity = oldopac if(isliving(parent_atom)) var/mob/living/L = parent_atom - L.remove_movespeed_modifier(MOVESPEED_ID_SHRINK_RAY) + L.remove_movespeed_modifier(/datum/movespeed_modifier/shrink_ray) if(ishuman(L)) var/mob/living/carbon/human/H = L H.physiology.damage_resistance += 100 diff --git a/code/datums/dna.dm b/code/datums/dna.dm index e08d5c509c..f57fb70ca8 100644 --- a/code/datums/dna.dm +++ b/code/datums/dna.dm @@ -662,6 +662,6 @@ var/danger = CONFIG_GET(number/threshold_body_size_slowdown) if(features["body_size"] < danger) var/slowdown = 1 + round(danger/features["body_size"], 0.1) * CONFIG_GET(number/body_size_slowdown_multiplier) - holder.add_movespeed_modifier(MOVESPEED_ID_SMALL_STRIDE, TRUE, 100, NONE, TRUE, slowdown, ALL, FLOATING|CRAWLING) + holder.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/small_stride, TRUE, slowdown) else if(old_size < danger) - holder.remove_movespeed_modifier(MOVESPEED_ID_SMALL_STRIDE) + holder.remove_movespeed_modifier(/datum/movespeed_modifier/small_stride) diff --git a/code/datums/status_effects/debuffs.dm b/code/datums/status_effects/debuffs.dm index 69b74841df..e15ac65258 100644 --- a/code/datums/status_effects/debuffs.dm +++ b/code/datums/status_effects/debuffs.dm @@ -120,12 +120,12 @@ /datum/status_effect/mesmerize/on_creation(mob/living/new_owner, set_duration) . = ..() ADD_TRAIT(owner, TRAIT_MUTE, "mesmerize") - owner.add_movespeed_modifier("[STATUS_EFFECT_MESMERIZE]_[id]", TRUE, priority = 64, override = TRUE, multiplicative_slowdown = 5, blacklisted_movetypes = FALSE? NONE : CRAWLING) + owner.add_movespeed_modifier(/datum/movespeed_modifier/status_effect/mesmerize) /datum/status_effect/mesmerize/on_remove() . = ..() REMOVE_TRAIT(owner, TRAIT_MUTE, "mesmerize") - owner.remove_movespeed_modifier("[STATUS_EFFECT_MESMERIZE]_[id]") + owner.remove_movespeed_modifier(/datum/movespeed_modifier/status_effect/mesmerize) /datum/status_effect/mesmerize/on_creation(mob/living/new_owner, set_duration) if(isnum(set_duration)) @@ -141,9 +141,7 @@ /datum/status_effect/electrode id = "tased" alert_type = null - var/slowdown = 1.5 - var/slowdown_priority = 50 //to make sure the stronger effect overrides - var/affect_crawl = FALSE + var/movespeed_mod = /datum/movespeed_modifier/status_effect/tased var/nextmove_modifier = 1 var/stamdmg_per_ds = 0 //a 20 duration would do 20 stamdmg, disablers do 24 or something var/last_tick = 0 //fastprocess processing speed is a goddamn sham, don't trust it. @@ -155,12 +153,12 @@ last_tick = world.time if(iscarbon(owner)) var/mob/living/carbon/C = owner - C.add_movespeed_modifier("[MOVESPEED_ID_TASED_STATUS]_[id]", TRUE, priority = slowdown_priority, override = TRUE, multiplicative_slowdown = slowdown, blacklisted_movetypes = affect_crawl? NONE : CRAWLING) + C.add_movespeed_modifier(movespeed_mod) /datum/status_effect/electrode/on_remove() if(iscarbon(owner)) var/mob/living/carbon/C = owner - C.remove_movespeed_modifier("[MOVESPEED_ID_TASED_STATUS]_[id]") + C.remove_movespeed_modifier(movespeed_mod) . = ..() /datum/status_effect/electrode/tick() @@ -178,8 +176,7 @@ /datum/status_effect/electrode/no_combat_mode id = "tased_strong" - slowdown = 8 - slowdown_priority = 100 + movespeed_mod = /datum/movespeed_modifier/status_effect/tased/no_combat_mode nextmove_modifier = 2 blocks_combatmode = TRUE stamdmg_per_ds = 1 @@ -650,11 +647,11 @@ if(isnum(set_duration)) duration = set_duration . = ..() - owner.add_movespeed_modifier(MOVESPEED_ID_ELECTROSTAFF, multiplicative_slowdown = 1, movetypes = GROUND) + owner.add_movespeed_modifier(/datum/movespeed_modifier/status_effect/electrostaff) /datum/status_effect/electrostaff/on_remove() . = ..() - owner.remove_movespeed_modifier(MOVESPEED_ID_ELECTROSTAFF) + owner.remove_movespeed_modifier(/datum/movespeed_modifier/status_effect/electrostaff) //GOLEM GANG diff --git a/code/game/objects/effects/mines.dm b/code/game/objects/effects/mines.dm index 2fb068a29b..1fe5e46e25 100644 --- a/code/game/objects/effects/mines.dm +++ b/code/game/objects/effects/mines.dm @@ -170,7 +170,7 @@ if(!victim.client || !istype(victim)) return to_chat(victim, "You feel fast!") - victim.add_movespeed_modifier(MOVESPEED_ID_YELLOW_ORB, update=TRUE, priority=100, multiplicative_slowdown=-2, blacklisted_movetypes=(FLYING|FLOATING)) + victim.add_movespeed_modifier(/datum/movespeed_modifier/yellow_orb) sleep(duration) - victim.remove_movespeed_modifier(MOVESPEED_ID_YELLOW_ORB) + victim.remove_movespeed_modifier(/datum/movespeed_modifier/yellow_orb) to_chat(victim, "You slow down.") diff --git a/code/game/objects/items/tanks/jetpack.dm b/code/game/objects/items/tanks/jetpack.dm index f592055338..e81294ceea 100644 --- a/code/game/objects/items/tanks/jetpack.dm +++ b/code/game/objects/items/tanks/jetpack.dm @@ -52,7 +52,7 @@ ion_trail.start() RegisterSignal(user, COMSIG_MOVABLE_MOVED, .proc/move_react) if(full_speed) - user.add_movespeed_modifier(MOVESPEED_ID_JETPACK, priority=100, multiplicative_slowdown=-2, movetypes=FLOATING, conflict=MOVE_CONFLICT_JETPACK) + user.add_movespeed_modifier(/datum/movespeed_modifier/jetpack/fullspeed) /obj/item/tank/jetpack/proc/turn_off(mob/user) on = FALSE @@ -60,7 +60,7 @@ icon_state = initial(icon_state) ion_trail.stop() UnregisterSignal(user, COMSIG_MOVABLE_MOVED) - user.remove_movespeed_modifier(MOVESPEED_ID_JETPACK) + user.remove_movespeed_modifier(/datum/movespeed_modifier/jetpack/fullspeed) /obj/item/tank/jetpack/proc/move_react(mob/user) allow_thrust(0.01, user) diff --git a/code/modules/antagonists/changeling/powers/strained_muscles.dm b/code/modules/antagonists/changeling/powers/strained_muscles.dm index a98700683e..d8572f04cc 100644 --- a/code/modules/antagonists/changeling/powers/strained_muscles.dm +++ b/code/modules/antagonists/changeling/powers/strained_muscles.dm @@ -21,7 +21,7 @@ to_chat(user, "Our muscles tense and strengthen.") changeling.chem_recharge_slowdown += 0.5 else - user.remove_movespeed_modifier(MOVESPEED_ID_CHANGELING_MUSCLES) + user.remove_movespeed_modifier(/datum/movespeed_modifier/strained_muscles) to_chat(user, "Our muscles relax.") changeling.chem_recharge_slowdown -= 0.5 if(stacks >= 20) @@ -36,12 +36,12 @@ /obj/effect/proc_holder/changeling/strained_muscles/proc/muscle_loop(mob/living/carbon/user) var/datum/antagonist/changeling/changeling = user.mind.has_antag_datum(/datum/antagonist/changeling) while(active) - user.add_movespeed_modifier(MOVESPEED_ID_CHANGELING_MUSCLES, update=TRUE, priority=100, multiplicative_slowdown=-1, blacklisted_movetypes=(FLYING|FLOATING)) + user.add_movespeed_modifier(/datum/movespeed_modifier/strained_muscles) if(user.stat != CONSCIOUS || user.staminaloss >= 90) active = !active to_chat(user, "Our muscles relax without the energy to strengthen them.") user.DefaultCombatKnockdown(40) - user.remove_movespeed_modifier(MOVESPEED_ID_CHANGELING_MUSCLES) + user.remove_movespeed_modifier(/datum/movespeed_modifier/strained_muscles) changeling.chem_recharge_slowdown -= 0.5 break diff --git a/code/modules/antagonists/slaughter/slaughter.dm b/code/modules/antagonists/slaughter/slaughter.dm index 475438ba52..5d409a7fb9 100644 --- a/code/modules/antagonists/slaughter/slaughter.dm +++ b/code/modules/antagonists/slaughter/slaughter.dm @@ -64,8 +64,8 @@ /mob/living/simple_animal/slaughter/phasein() . = ..() - add_movespeed_modifier(MOVESPEED_ID_SLAUGHTER, update=TRUE, priority=100, multiplicative_slowdown=-1) - addtimer(CALLBACK(src, .proc/remove_movespeed_modifier, MOVESPEED_ID_SLAUGHTER, TRUE), 6 SECONDS, TIMER_UNIQUE | TIMER_OVERRIDE) + add_movespeed_modifier(/datum/movespeed_modifier/slaughter) + addtimer(CALLBACK(src, .proc/remove_movespeed_modifier, /datum/movespeed_modifier/slaughter), 6 SECONDS, TIMER_UNIQUE | TIMER_OVERRIDE) //The loot from killing a slaughter demon - can be consumed to allow the user to blood crawl diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 377540233f..cef445113b 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -7,6 +7,7 @@ update_body_parts() //to update the carbon's new bodyparts appearance GLOB.carbon_list += src blood_volume = (BLOOD_VOLUME_NORMAL * blood_ratio) + add_movespeed_modifier(/datum/movespeed_modifier/carbon_crawling) /mob/living/carbon/Destroy() //This must be done first, so the mob ghosts correctly before DNA etc is nulled @@ -574,9 +575,9 @@ become_husk("burn") med_hud_set_health() if(stat == SOFT_CRIT) - add_movespeed_modifier(MOVESPEED_ID_CARBON_SOFTCRIT, TRUE, multiplicative_slowdown = SOFTCRIT_ADD_SLOWDOWN) + add_movespeed_modifier(/datum/movespeed_modifier/carbon_softcrit) else - remove_movespeed_modifier(MOVESPEED_ID_CARBON_SOFTCRIT, TRUE) + remove_movespeed_modifier(/datum/movespeed_modifier/carbon_softcrit) /mob/living/carbon/update_stamina() var/stam = getStaminaLoss() diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 94aba6851a..b1d14f2e10 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -1041,7 +1041,7 @@ return FALSE /mob/living/carbon/human/proc/clear_shove_slowdown() - remove_movespeed_modifier(MOVESPEED_ID_SHOVE) + remove_movespeed_modifier(/datum/movespeed_modifier/shove) var/active_item = get_active_held_item() if(is_type_in_typecache(active_item, GLOB.shove_disarming_types)) visible_message("[src.name] regains their grip on \the [active_item]!", "You regain your grip on \the [active_item]", null, COMBAT_MESSAGE_RANGE) @@ -1050,17 +1050,17 @@ . = ..() if(HAS_TRAIT(src, TRAIT_IGNORESLOWDOWN)) - remove_movespeed_modifier(MOVESPEED_ID_DAMAGE_SLOWDOWN) - remove_movespeed_modifier(MOVESPEED_ID_DAMAGE_SLOWDOWN_FLYING) + remove_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown) + remove_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown_flying) return var/stambufferinfluence = (bufferedstam*(100/stambuffer))*0.2 //CIT CHANGE - makes stamina buffer influence movedelay var/health_deficiency = ((100 + stambufferinfluence) - health + (getStaminaLoss()*0.75))//CIT CHANGE - reduces the impact of staminaloss and makes stamina buffer influence it if(health_deficiency >= 40) - add_movespeed_modifier(MOVESPEED_ID_DAMAGE_SLOWDOWN, override = TRUE, multiplicative_slowdown = ((health_deficiency-39) / 75), blacklisted_movetypes = FLOATING|FLYING) - add_movespeed_modifier(MOVESPEED_ID_DAMAGE_SLOWDOWN_FLYING, override = TRUE, multiplicative_slowdown = ((health_deficiency-39) / 25), movetypes = FLYING, blacklisted_movetypes = FLOATING) + add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown, TRUE, (health_deficiency-39) / 75) + add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown_flying, TRUE, (health_deficiency-39) / 25) else - remove_movespeed_modifier(MOVESPEED_ID_DAMAGE_SLOWDOWN) - remove_movespeed_modifier(MOVESPEED_ID_DAMAGE_SLOWDOWN_FLYING) + remove_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown) + remove_movespeed_modifier(/datum/movespeed_modifier/damage_slowdown_flying) /mob/living/carbon/human/do_after_coefficent() . = ..() diff --git a/code/modules/mob/living/carbon/human/human_movement.dm b/code/modules/mob/living/carbon/human/human_movement.dm index a26bdd99cd..09dfa602e1 100644 --- a/code/modules/mob/living/carbon/human/human_movement.dm +++ b/code/modules/mob/living/carbon/human/human_movement.dm @@ -1,11 +1,13 @@ /mob/living/carbon/human/get_movespeed_modifiers() var/list/considering = ..() - . = considering if(HAS_TRAIT(src, TRAIT_IGNORESLOWDOWN)) - for(var/id in .) - var/list/data = .[id] - if(data[MOVESPEED_DATA_INDEX_FLAGS] & IGNORE_NOSLOW) - .[id] = data + . = list() + for(var/id in considering) + var/datum/movespeed_modifier/M = considering[id] + if(M.flags & IGNORE_NOSLOW || M.multiplicative_slowdown < 0) + .[id] = M + return + return considering /mob/living/carbon/human/movement_delay() . = ..() diff --git a/code/modules/mob/living/carbon/human/species.dm b/code/modules/mob/living/carbon/human/species.dm index 32e492f5fa..683c3e18fd 100644 --- a/code/modules/mob/living/carbon/human/species.dm +++ b/code/modules/mob/living/carbon/human/species.dm @@ -331,7 +331,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) if(mutant_bodyparts["meat_type"]) //I can't believe it's come to the meat H.type_of_meat = GLOB.meat_types[H.dna.features["meat_type"]] - C.add_movespeed_modifier(MOVESPEED_ID_SPECIES, TRUE, 100, override=TRUE, multiplicative_slowdown=speedmod, movetypes=(~FLYING)) + C.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/species, TRUE, multiplicative_slowdown = speedmod) SEND_SIGNAL(C, COMSIG_SPECIES_GAIN, src, old_species) @@ -349,7 +349,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) for(var/X in inherent_traits) REMOVE_TRAIT(C, X, SPECIES_TRAIT) - C.remove_movespeed_modifier(MOVESPEED_ID_SPECIES) + C.remove_movespeed_modifier(/datum/movespeed_modifier/species) if(mutant_bodyparts["meat_type"]) C.type_of_meat = GLOB.meat_types[C.dna.features["meat_type"]] @@ -1299,14 +1299,14 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) if(H.overeatduration < 100) to_chat(H, "You feel fit again!") REMOVE_TRAIT(H, TRAIT_FAT, OBESITY) - H.remove_movespeed_modifier(MOVESPEED_ID_FAT) + H.remove_movespeed_modifier(/datum/movespeed_modifier/obesity) H.update_inv_w_uniform() H.update_inv_wear_suit() else if(H.overeatduration >= 100) to_chat(H, "You suddenly feel blubbery!") ADD_TRAIT(H, TRAIT_FAT, OBESITY) - H.add_movespeed_modifier(MOVESPEED_ID_FAT, multiplicative_slowdown = 1.5) + H.add_movespeed_modifier(/datum/movespeed_modifier/obesity) H.update_inv_w_uniform() H.update_inv_wear_suit() @@ -1362,9 +1362,9 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) if(!HAS_TRAIT(H, TRAIT_NOHUNGER)) var/hungry = (500 - H.nutrition) / 5 //So overeat would be 100 and default level would be 80 if(hungry >= 70) - H.add_movespeed_modifier(MOVESPEED_ID_HUNGRY, override = TRUE, multiplicative_slowdown = (hungry / 50)) + H.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/hunger, multiplicative_slowdown = (hungry / 50)) else - H.remove_movespeed_modifier(MOVESPEED_ID_HUNGRY) + H.remove_movespeed_modifier(/datum/movespeed_modifier/hunger) switch(H.nutrition) if(NUTRITION_LEVEL_FULL to INFINITY) @@ -1615,7 +1615,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) "You hear a slap." ) return FALSE - + else user.do_attack_animation(target, ATTACK_EFFECT_DISARM) @@ -1623,10 +1623,10 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) user.adjustStaminaLossBuffered(1) else user.adjustStaminaLossBuffered(3) - + if(attacker_style && attacker_style.disarm_act(user,target)) return TRUE - + if(target.w_uniform) target.w_uniform.add_fingerprint(user) //var/randomized_zone = ran_zone(user.zone_selected) CIT CHANGE - comments out to prevent compiling errors @@ -1659,7 +1659,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) randn -= 25 //if you are a pugilist, you're slapping that item from them pretty reliably if(HAS_TRAIT(target, TRAIT_PUGILIST)) randn += 25 //meanwhile, pugilists are less likely to get disarmed - + if(randn <= 35)//CIT CHANGE - changes this back to a 35% chance to accomodate for the above being commented out in favor of right-click pushing var/obj/item/I = null if(target.pulling) @@ -1932,8 +1932,8 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) var/obj/item/target_held_item = target.get_active_held_item() if(!is_type_in_typecache(target_held_item, GLOB.shove_disarming_types)) target_held_item = null - if(!target.has_movespeed_modifier(MOVESPEED_ID_SHOVE)) - target.add_movespeed_modifier(MOVESPEED_ID_SHOVE, multiplicative_slowdown = SHOVE_SLOWDOWN_STRENGTH) + if(!target.has_movespeed_modifier(/datum/movespeed_modifier/shove)) + target.add_movespeed_modifier(/datum/movespeed_modifier/shove) if(target_held_item) if(!HAS_TRAIT(target_held_item, TRAIT_NODROP)) target.visible_message("[target.name]'s grip on \the [target_held_item] loosens!", @@ -2084,7 +2084,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) SEND_SIGNAL(H, COMSIG_CLEAR_MOOD_EVENT, "cold") SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "hot", /datum/mood_event/hot) - H.remove_movespeed_modifier(MOVESPEED_ID_COLD) + H.remove_movespeed_modifier(/datum/movespeed_modifier/cold) var/burn_damage var/firemodifier = H.fire_stacks / 50 @@ -2101,8 +2101,8 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) else if(H.bodytemperature < BODYTEMP_COLD_DAMAGE_LIMIT && !HAS_TRAIT(H, TRAIT_RESISTCOLD)) SEND_SIGNAL(H, COMSIG_CLEAR_MOOD_EVENT, "hot") SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "cold", /datum/mood_event/cold) - //Sorry for the nasty oneline but I don't want to assign a variable on something run pretty frequently - H.add_movespeed_modifier(MOVESPEED_ID_COLD, override = TRUE, multiplicative_slowdown = ((BODYTEMP_COLD_DAMAGE_LIMIT - H.bodytemperature) / COLD_SLOWDOWN_FACTOR), blacklisted_movetypes = FLOATING) + //Apply cold slowdown + H.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/cold, multiplicative_slowdown = ((BODYTEMP_COLD_DAMAGE_LIMIT - H.bodytemperature) / COLD_SLOWDOWN_FACTOR)) switch(H.bodytemperature) if(200 to BODYTEMP_COLD_DAMAGE_LIMIT) H.apply_damage(COLD_DAMAGE_LEVEL_1*coldmod*H.physiology.cold_mod, BURN) @@ -2112,7 +2112,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names) H.apply_damage(COLD_DAMAGE_LEVEL_3*coldmod*H.physiology.cold_mod, BURN) else - H.remove_movespeed_modifier(MOVESPEED_ID_COLD) + H.remove_movespeed_modifier(/datum/movespeed_modifier/cold) SEND_SIGNAL(H, COMSIG_CLEAR_MOOD_EVENT, "cold") SEND_SIGNAL(H, COMSIG_CLEAR_MOOD_EVENT, "hot") diff --git a/code/modules/mob/living/carbon/monkey/monkey.dm b/code/modules/mob/living/carbon/monkey/monkey.dm index d3e5941e4e..6242fa56be 100644 --- a/code/modules/mob/living/carbon/monkey/monkey.dm +++ b/code/modules/mob/living/carbon/monkey/monkey.dm @@ -65,12 +65,11 @@ /mob/living/carbon/monkey/on_reagent_change() . = ..() - remove_movespeed_modifier(MOVESPEED_ID_MONKEY_REAGENT_SPEEDMOD, TRUE) var/amount if(reagents.has_reagent(/datum/reagent/medicine/morphine)) amount = -1 if(amount) - add_movespeed_modifier(MOVESPEED_ID_MONKEY_REAGENT_SPEEDMOD, TRUE, 100, override = TRUE, multiplicative_slowdown = amount) + add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/monkey_reagent_speedmod, TRUE, amount) /mob/living/carbon/monkey/updatehealth() . = ..() @@ -78,7 +77,7 @@ var/health_deficiency = (100 - health) if(health_deficiency >= 45) slow += (health_deficiency / 25) - add_movespeed_modifier(MOVESPEED_ID_MONKEY_HEALTH_SPEEDMOD, TRUE, 100, override = TRUE, multiplicative_slowdown = slow) + add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/monkey_health_speedmod, TRUE, slow) /mob/living/carbon/monkey/adjust_bodytemperature(amount) . = ..() @@ -87,7 +86,7 @@ slow += (283.222 - bodytemperature) / 10 * 1.75 if(slow <= 0) return - add_movespeed_modifier(MOVESPEED_ID_MONKEY_TEMPERATURE_SPEEDMOD, TRUE, 100, override = TRUE, multiplicative_slowdown = amount) + add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/monkey_temperature_speedmod, TRUE, slow) /mob/living/carbon/monkey/Stat() ..() @@ -99,7 +98,6 @@ if(changeling) stat("Chemical Storage", "[changeling.chem_charges]/[changeling.chem_storage]") stat("Absorbed DNA", changeling.absorbedcount) - return /mob/living/carbon/monkey/verb/removeinternal() diff --git a/code/modules/mob/living/living_mobility.dm b/code/modules/mob/living/living_mobility.dm index 49d4a20887..32038a6102 100644 --- a/code/modules/mob/living/living_mobility.dm +++ b/code/modules/mob/living/living_mobility.dm @@ -94,11 +94,13 @@ if(should_be_lying) mobility_flags &= ~MOBILITY_STAND + setMovetype(movement_type | CRAWLING) if(!lying) //force them on the ground lying = pick(90, 270) if(has_gravity() && !buckled) playsound(src, "bodyfall", 20, 1) else + setMovetype(movement_type & ~CRAWLING) mobility_flags |= MOBILITY_STAND lying = 0 @@ -161,8 +163,8 @@ if(!has_legs && has_arms < 2) limbless_slowdown += 6 - (has_arms * 3) if(limbless_slowdown) - add_movespeed_modifier(MOVESPEED_ID_LIVING_LIMBLESS, update=TRUE, priority=100, override=TRUE, multiplicative_slowdown=limbless_slowdown, blacklisted_movetypes = FLYING|FLOATING) + add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/limbless, multiplicative_slowdown = limbless_slowdown) else - remove_movespeed_modifier(MOVESPEED_ID_LIVING_LIMBLESS, update=TRUE) + remove_movespeed_modifier(/datum/movespeed_modifier/limbless) return mobility_flags diff --git a/code/modules/mob/living/living_movement.dm b/code/modules/mob/living/living_movement.dm index ec291094fe..ddcf3e6292 100644 --- a/code/modules/mob/living/living_movement.dm +++ b/code/modules/mob/living/living_movement.dm @@ -36,38 +36,26 @@ sprint_stamina_cost = CONFIG_GET(number/movedelay/sprint_stamina_cost) return ..() -/mob/living/movement_delay(ignorewalk = 0) - . = ..() - if(!CHECK_MOBILITY(src, MOBILITY_STAND)) - . += 6 - /// whether or not we can slide under another living mob. defaults to if we're not dense. CanPass should check "overriding circumstances" like buckled mobs/having PASSMOB flag, etc. /mob/living/proc/can_move_under_living(mob/living/other) return !density /mob/living/proc/update_move_intent_slowdown() - var/mod = 0 - if(m_intent == MOVE_INTENT_WALK) - mod = CONFIG_GET(number/movedelay/walk_delay) - else - mod = CONFIG_GET(number/movedelay/run_delay) - if(!isnum(mod)) - mod = 1 - add_movespeed_modifier(MOVESPEED_ID_MOB_WALK_RUN_CONFIG_SPEED, TRUE, 100, override = TRUE, multiplicative_slowdown = mod) + add_movespeed_modifier((m_intent == MOVE_INTENT_WALK)? /datum/movespeed_modifier/config_walk_run/walk : /datum/movespeed_modifier/config_walk_run/run) /mob/living/proc/update_turf_movespeed(turf/open/T) - if(isopenturf(T) && !is_flying()) - add_movespeed_modifier(MOVESPEED_ID_LIVING_TURF_SPEEDMOD, TRUE, 100, override = TRUE, multiplicative_slowdown = T.slowdown) + if(isopenturf(T)) + add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/turf_slowdown, multiplicative_slowdown = T.slowdown) else - remove_movespeed_modifier(MOVESPEED_ID_LIVING_TURF_SPEEDMOD) + remove_movespeed_modifier(/datum/movespeed_modifier/turf_slowdown) /mob/living/proc/update_pull_movespeed() if(pulling && isliving(pulling)) var/mob/living/L = pulling if(drag_slowdown && L.lying && !L.buckled && grab_state < GRAB_AGGRESSIVE) - add_movespeed_modifier(MOVESPEED_ID_PRONE_DRAGGING, multiplicative_slowdown = PULL_PRONE_SLOWDOWN) + add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/bulky_drag, multiplicative_slowdown = PULL_PRONE_SLOWDOWN) return - remove_movespeed_modifier(MOVESPEED_ID_PRONE_DRAGGING) + remove_movespeed_modifier(/datum/movespeed_modifier/bulky_drag) /mob/living/canZMove(dir, turf/target) return can_zTravel(target, dir) && (movement_type & FLYING) diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm index 26fa3b505d..cdb5d421ae 100644 --- a/code/modules/mob/living/silicon/pai/pai.dm +++ b/code/modules/mob/living/silicon/pai/pai.dm @@ -273,9 +273,9 @@ /mob/living/silicon/pai/Process_Spacemove(movement_dir = 0) . = ..() if(!.) - add_movespeed_modifier(MOVESPEED_ID_PAI_SPACEWALK_SPEEDMOD, TRUE, 100, multiplicative_slowdown = 2) + add_movespeed_modifier(/datum/movespeed_modifier/pai_spacewalk) return TRUE - remove_movespeed_modifier(MOVESPEED_ID_PAI_SPACEWALK_SPEEDMOD, TRUE) + remove_movespeed_modifier(/datum/movespeed_modifier/pai_spacewalk) return TRUE /mob/living/silicon/pai/examine(mob/user) diff --git a/code/modules/mob/living/simple_animal/hostile/giant_spider.dm b/code/modules/mob/living/simple_animal/hostile/giant_spider.dm index 439bedf3cc..f19aa0a2a7 100644 --- a/code/modules/mob/living/simple_animal/hostile/giant_spider.dm +++ b/code/modules/mob/living/simple_animal/hostile/giant_spider.dm @@ -186,10 +186,10 @@ . = ..() if(slowed_by_webs) if(!(locate(/obj/structure/spider/stickyweb) in loc)) - remove_movespeed_modifier(MOVESPEED_ID_TARANTULA_WEB) + remove_movespeed_modifier(/datum/movespeed_modifier/tarantula_web) slowed_by_webs = FALSE else if(locate(/obj/structure/spider/stickyweb) in loc) - add_movespeed_modifier(MOVESPEED_ID_TARANTULA_WEB, priority=100, multiplicative_slowdown=3) + add_movespeed_modifier(/datum/movespeed_modifier/tarantula_web) slowed_by_webs = TRUE //midwives are the queen of the spiders, can send messages to all them and web faster. That rare round where you get a queen spider and turn your 'for honor' players into 'r6siege' players will be a fun one. diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm index 3feed2129b..a831dc6f16 100644 --- a/code/modules/mob/living/simple_animal/simple_animal.dm +++ b/code/modules/mob/living/simple_animal/simple_animal.dm @@ -292,8 +292,8 @@ /mob/living/simple_animal/proc/update_simplemob_varspeed() if(speed == 0) - remove_movespeed_modifier(MOVESPEED_ID_SIMPLEMOB_VARSPEED, TRUE) - add_movespeed_modifier(MOVESPEED_ID_SIMPLEMOB_VARSPEED, TRUE, 100, multiplicative_slowdown = speed, override = TRUE) + remove_movespeed_modifier(/datum/movespeed_modifier/simplemob_varspeed) + add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/simplemob_varspeed, multiplicative_slowdown = speed) /mob/living/simple_animal/Stat() ..() diff --git a/code/modules/mob/living/simple_animal/slime/slime.dm b/code/modules/mob/living/simple_animal/slime/slime.dm index 8594d53bd1..dd454c4243 100644 --- a/code/modules/mob/living/simple_animal/slime/slime.dm +++ b/code/modules/mob/living/simple_animal/slime/slime.dm @@ -147,25 +147,25 @@ /mob/living/simple_animal/slime/on_reagent_change() . = ..() - remove_movespeed_modifier(MOVESPEED_ID_SLIME_REAGENTMOD, TRUE) + remove_movespeed_modifier(/datum/movespeed_modifier/slime_reagentmod) var/amount = 0 if(reagents.has_reagent(/datum/reagent/medicine/morphine)) // morphine slows slimes down amount = 2 if(reagents.has_reagent(/datum/reagent/consumable/frostoil)) // Frostoil also makes them move VEEERRYYYYY slow amount = 5 if(amount) - add_movespeed_modifier(MOVESPEED_ID_SLIME_REAGENTMOD, TRUE, 100, override = TRUE, multiplicative_slowdown = amount) + add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/slime_reagentmod, multiplicative_slowdown = amount) /mob/living/simple_animal/slime/updatehealth() . = ..() - remove_movespeed_modifier(MOVESPEED_ID_SLIME_HEALTHMOD, FALSE) + remove_movespeed_modifier(/datum/movespeed_modifier/slime_healthmod) var/health_deficiency = (100 - health) var/mod = 0 if(health_deficiency >= 45) mod += (health_deficiency / 25) if(health <= 0) mod += 2 - add_movespeed_modifier(MOVESPEED_ID_SLIME_HEALTHMOD, TRUE, 100, multiplicative_slowdown = mod) + add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/slime_healthmod, multiplicative_slowdown = mod) /mob/living/simple_animal/slime/adjust_bodytemperature() . = ..() @@ -173,9 +173,8 @@ if(bodytemperature >= 330.23) // 135 F or 57.08 C mod = -1 // slimes become supercharged at high temperatures else if(bodytemperature < 183.222) - mod = (283.222 - bodytemperature) / 10 * 1.75 - if(mod) - add_movespeed_modifier(MOVESPEED_ID_SLIME_TEMPMOD, TRUE, 100, override = TRUE, multiplicative_slowdown = mod) + mod = min(15, (283.222 - bodytemperature) / 10 * 1.75) + add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/slime_tempmod, multiplicative_slowdown = mod) /mob/living/simple_animal/slime/ObjBump(obj/O) if(!client && powerlevel > 0) diff --git a/code/modules/mob/living/status_procs.dm b/code/modules/mob/living/status_procs.dm index 1375d88948..0d41347179 100644 --- a/code/modules/mob/living/status_procs.dm +++ b/code/modules/mob/living/status_procs.dm @@ -622,10 +622,40 @@ tod = STATION_TIME_TIMESTAMP("hh:mm:ss", world.time) update_stat() +///Unignores all slowdowns that lack the IGNORE_NOSLOW flag. /mob/living/proc/unignore_slowdown(source) REMOVE_TRAIT(src, TRAIT_IGNORESLOWDOWN, source) - update_movespeed(FALSE) + update_movespeed() +///Ignores all slowdowns that lack the IGNORE_NOSLOW flag. /mob/living/proc/ignore_slowdown(source) ADD_TRAIT(src, TRAIT_IGNORESLOWDOWN, source) - update_movespeed(FALSE) + update_movespeed() + +///Ignores specific slowdowns. Accepts a list of slowdowns. +/mob/living/proc/add_movespeed_mod_immunities(source, slowdown_type, update = TRUE) + if(islist(slowdown_type)) + for(var/listed_type in slowdown_type) + if(ispath(listed_type)) + listed_type = "[listed_type]" //Path2String + LAZYADDASSOC(movespeed_mod_immunities, listed_type, source) + else + if(ispath(slowdown_type)) + slowdown_type = "[slowdown_type]" //Path2String + LAZYADDASSOC(movespeed_mod_immunities, slowdown_type, source) + if(update) + update_movespeed() + +///Unignores specific slowdowns. Accepts a list of slowdowns. +/mob/living/proc/remove_movespeed_mod_immunities(source, slowdown_type, update = TRUE) + if(islist(slowdown_type)) + for(var/listed_type in slowdown_type) + if(ispath(listed_type)) + listed_type = "[listed_type]" //Path2String + LAZYREMOVEASSOC(movespeed_mod_immunities, listed_type, source) + else + if(ispath(slowdown_type)) + slowdown_type = "[slowdown_type]" //Path2String + LAZYREMOVEASSOC(movespeed_mod_immunities, slowdown_type, source) + if(update) + update_movespeed() diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index fd786c8631..088e758f06 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -1033,17 +1033,22 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0) /// Updates the grab state of the mob and updates movespeed /mob/setGrabState(newstate) . = ..() - if(grab_state == GRAB_PASSIVE) - remove_movespeed_modifier(MOVESPEED_ID_MOB_GRAB_STATE, update=TRUE) - else - add_movespeed_modifier(MOVESPEED_ID_MOB_GRAB_STATE, update=TRUE, priority=100, override=TRUE, multiplicative_slowdown=grab_state*3, blacklisted_movetypes=FLOATING) + switch(grab_state) + if(GRAB_PASSIVE) + remove_movespeed_modifier(MOVESPEED_ID_MOB_GRAB_STATE) + if(GRAB_AGGRESSIVE) + add_movespeed_modifier(/datum/movespeed_modifier/grab_slowdown/aggressive) + if(GRAB_NECK) + add_movespeed_modifier(/datum/movespeed_modifier/grab_slowdown/neck) + if(GRAB_KILL) + add_movespeed_modifier(/datum/movespeed_modifier/grab_slowdown/kill) /mob/proc/update_equipment_speed_mods() var/speedies = equipped_speed_mods() if(!speedies) - remove_movespeed_modifier(MOVESPEED_ID_MOB_EQUIPMENT, update=TRUE) + remove_movespeed_modifier(/datum/movespeed_modifier/equipment_speedmod, update=TRUE) else - add_movespeed_modifier(MOVESPEED_ID_MOB_EQUIPMENT, update=TRUE, priority=100, override=TRUE, multiplicative_slowdown=speedies, blacklisted_movetypes=FLOATING) + add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/equipment_speedmod, multiplicative_slowdown = speedies) /// Gets the combined speed modification of all worn items /// Except base mob type doesnt really wear items diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index bf9dad1bc7..7d177e7ac2 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -42,8 +42,11 @@ var/lying_prev = 0 var/is_shifted = FALSE - //MOVEMENT SPEED + /// List of movement speed modifiers applying to this mob var/list/movespeed_modification //Lazy list, see mob_movespeed.dm + /// List of movement speed modifiers ignored by this mob. List -> List (id) -> List (sources) + var/list/movespeed_mod_immunities //Lazy list, see mob_movespeed.dm + /// The calculated mob speed slowdown based on the modifiers list var/cached_multiplicative_slowdown ///////////////// diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index ffc0970bdf..9bef48320b 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -251,9 +251,9 @@ /mob/proc/update_gravity(has_gravity, override=FALSE) var/speed_change = max(0, has_gravity - STANDARD_GRAVITY) if(!speed_change) - remove_movespeed_modifier(MOVESPEED_ID_MOB_GRAVITY, update=TRUE) + remove_movespeed_modifier(/datum/movespeed_modifier/gravity) else - add_movespeed_modifier(MOVESPEED_ID_MOB_GRAVITY, update=TRUE, priority=100, override=TRUE, multiplicative_slowdown=speed_change, blacklisted_movetypes=FLOATING) + add_movespeed_modifier(/datum/movespeed_modifier/gravity, multiplicative_slowdown = speed_change) //bodypart selection - Cyberboss //8 toggles through head - eyes - mouth diff --git a/code/modules/mob/mob_movespeed.dm b/code/modules/mob/mob_movespeed.dm deleted file mode 100644 index a0be8ff7cb..0000000000 --- a/code/modules/mob/mob_movespeed.dm +++ /dev/null @@ -1,126 +0,0 @@ - -/*Current movespeed modification list format: list(id = list( - priority, - flags, - legacy slowdown/speedup amount, - movetype_flags, - blacklisted_movetypes, - conflict - )) -*/ - -//ANY ADD/REMOVE DONE IN UPDATE_MOVESPEED MUST HAVE THE UPDATE ARGUMENT SET AS FALSE! -/mob/proc/add_movespeed_modifier(id, update=TRUE, priority=0, flags=NONE, override=FALSE, multiplicative_slowdown=0, movetypes=ALL, blacklisted_movetypes=NONE, conflict=FALSE) - var/list/temp = list(priority, flags, multiplicative_slowdown, movetypes, blacklisted_movetypes, conflict) //build the modification list - var/resort = TRUE - if(LAZYACCESS(movespeed_modification, id)) - var/list/existing_data = movespeed_modification[id] - if(movespeed_modifier_identical_check(existing_data, temp)) - return FALSE - if(!override) - return FALSE - if(priority == existing_data[MOVESPEED_DATA_INDEX_PRIORITY]) - resort = FALSE // We don't need to re-sort if we're replacing something already there and it's the same priority - LAZYSET(movespeed_modification, id, temp) - if(update) - update_movespeed(resort) - return TRUE - -/mob/proc/remove_movespeed_modifier(id, update = TRUE) - if(!LAZYACCESS(movespeed_modification, id)) - return FALSE - LAZYREMOVE(movespeed_modification, id) - UNSETEMPTY(movespeed_modification) - if(update) - update_movespeed(FALSE) - return TRUE - -/mob/vv_edit_var(var_name, var_value) - var/slowdown_edit = (var_name == NAMEOF(src, cached_multiplicative_slowdown)) - var/diff - if(slowdown_edit && isnum(cached_multiplicative_slowdown) && isnum(var_value)) - remove_movespeed_modifier(MOVESPEED_ID_ADMIN_VAREDIT) - diff = var_value - cached_multiplicative_slowdown - . = ..() - if(. && slowdown_edit && isnum(diff)) - add_movespeed_modifier(MOVESPEED_ID_ADMIN_VAREDIT, TRUE, 100, override = TRUE, multiplicative_slowdown = diff) - -/mob/proc/has_movespeed_modifier(id) - return LAZYACCESS(movespeed_modification, id) - -/mob/proc/update_config_movespeed() - add_movespeed_modifier(MOVESPEED_ID_CONFIG_SPEEDMOD, FALSE, 100, override = TRUE, multiplicative_slowdown = get_config_multiplicative_speed()) - -/mob/proc/get_config_multiplicative_speed() - if(!islist(GLOB.mob_config_movespeed_type_lookup) || !GLOB.mob_config_movespeed_type_lookup[type]) - return 0 - else - return GLOB.mob_config_movespeed_type_lookup[type] - -/mob/proc/update_movespeed(resort = TRUE) - if(resort) - sort_movespeed_modlist() - . = 0 - var/list/conflict_tracker = list() - for(var/id in get_movespeed_modifiers()) - var/list/data = movespeed_modification[id] - if(!(data[MOVESPEED_DATA_INDEX_MOVETYPE] & movement_type)) // We don't affect any of these move types, skip - continue - if(data[MOVESPEED_DATA_INDEX_BL_MOVETYPE] & movement_type) // There's a movetype here that disables this modifier, skip - continue - var/conflict = data[MOVESPEED_DATA_INDEX_CONFLICT] - var/amt = data[MOVESPEED_DATA_INDEX_MULTIPLICATIVE_SLOWDOWN] - if(conflict) - // Conflicting modifiers prioritize the larger slowdown or the larger speedup - // We purposefuly don't handle mixing speedups and slowdowns on the same id - if(abs(conflict_tracker[conflict]) < abs(amt)) - conflict_tracker[conflict] = amt - else - continue - . += amt - cached_multiplicative_slowdown = . - -/mob/proc/get_movespeed_modifiers() - return movespeed_modification - -/mob/proc/movespeed_modifier_identical_check(list/mod1, list/mod2) - if(!islist(mod1) || !islist(mod2) || mod1.len < MOVESPEED_DATA_INDEX_MAX || mod2.len < MOVESPEED_DATA_INDEX_MAX) - return FALSE - for(var/i in 1 to MOVESPEED_DATA_INDEX_MAX) - if(mod1[i] != mod2[i]) - return FALSE - return TRUE - -/mob/proc/total_multiplicative_slowdown() - . = 0 - for(var/id in get_movespeed_modifiers()) - var/list/data = movespeed_modification[id] - . += data[MOVESPEED_DATA_INDEX_MULTIPLICATIVE_SLOWDOWN] - -/proc/movespeed_data_null_check(list/data) //Determines if a data list is not meaningful and should be discarded. - . = TRUE - if(data[MOVESPEED_DATA_INDEX_MULTIPLICATIVE_SLOWDOWN]) - . = FALSE - -/mob/proc/sort_movespeed_modlist() //Verifies it too. Sorts highest priority (first applied) to lowest priority (last applied) - if(!movespeed_modification) - return - var/list/assembled = list() - for(var/our_id in movespeed_modification) - var/list/our_data = movespeed_modification[our_id] - if(!islist(our_data) || (our_data.len < MOVESPEED_DATA_INDEX_PRIORITY) || movespeed_data_null_check(our_data)) - movespeed_modification -= our_id - continue - var/our_priority = our_data[MOVESPEED_DATA_INDEX_PRIORITY] - var/resolved = FALSE - for(var/their_id in assembled) - var/list/their_data = assembled[their_id] - if(their_data[MOVESPEED_DATA_INDEX_PRIORITY] < our_priority) - assembled.Insert(assembled.Find(their_id), our_id) - assembled[our_id] = our_data - resolved = TRUE - break - if(!resolved) - assembled[our_id] = our_data - movespeed_modification = assembled - UNSETEMPTY(movespeed_modification) \ No newline at end of file diff --git a/code/modules/movespeed/_movespeed_modifier.dm b/code/modules/movespeed/_movespeed_modifier.dm new file mode 100644 index 0000000000..0976f4d067 --- /dev/null +++ b/code/modules/movespeed/_movespeed_modifier.dm @@ -0,0 +1,217 @@ +/*! Movespeed modification datums. + + How move speed for mobs works + +Move speed is now calculated by using modifier datums which are added to mobs. Some of them (nonvariable ones) are globally cached, the variable ones are instanced and changed based on need. + +This gives us the ability to have multiple sources of movespeed, reliabily keep them applied and remove them when they should be + +THey can have unique sources and a bunch of extra fancy flags that control behaviour + +Previously trying to update move speed was a shot in the dark that usually meant mobs got stuck going faster or slower + +Movespeed modification list is a simple key = datum system. Key will be the datum's ID if it is overridden to not be null, or type if it is not. + +DO NOT override datum IDs unless you are going to have multiple types that must overwrite each other. It's more efficient to use types, ID functionality is only kept for cases where dynamic creation of modifiers need to be done. + +When update movespeed is called, the list of items is iterated, according to flags priority and a bunch of conditions +this spits out a final calculated value which is used as a modifer to last_move + modifier for calculating when a mob +can next move + +Key procs +* [add_movespeed_modifier](mob.html#proc/add_movespeed_modifier) +* [remove_movespeed_modifier](mob.html#proc/remove_movespeed_modifier) +* [has_movespeed_modifier](mob.html#proc/has_movespeed_modifier) +* [update_movespeed](mob.html#proc/update_movespeed) +*/ + +/datum/movespeed_modifier + /// Whether or not this is a variable modifier. Variable modifiers can NOT be ever auto-cached. ONLY CHECKED VIA INITIAL(), EFFECTIVELY READ ONLY (and for very good reason) + var/variable = FALSE + + /// Unique ID. You can never have different modifications with the same ID. By default, this SHOULD NOT be set. Only set it for cases where you're dynamically making modifiers/need to have two types overwrite each other. If unset, uses path (converted to text) as ID. + var/id + + /// Higher ones override lower priorities. This is NOT used for ID, ID must be unique, if it isn't unique the newer one overwrites automatically if overriding. + var/priority = 0 + var/flags = NONE + + /// Multiplicative slowdown + var/multiplicative_slowdown = 0 + + /// Movetypes this applies to + var/movetypes = ALL + + /// Movetypes this never applies to + var/blacklisted_movetypes = NONE + + /// Other modification datums this conflicts with. + var/conflicts_with + +/datum/movespeed_modifier/New() + . = ..() + if(!id) + id = "[type]" //We turn the path into a string. + +GLOBAL_LIST_EMPTY(movespeed_modification_cache) + +/// Grabs a STATIC MODIFIER datum from cache. YOU MUST NEVER EDIT THESE DATUMS, OR IT WILL AFFECT ANYTHING ELSE USING IT TOO! +/proc/get_cached_movespeed_modifier(modtype) + if(!ispath(modtype, /datum/movespeed_modifier)) + CRASH("[modtype] is not a movespeed modification typepath.") + var/datum/movespeed_modifier/M = modtype + if(initial(M.variable)) + CRASH("[modtype] is a variable modifier, and can never be cached.") + M = GLOB.movespeed_modification_cache[modtype] + if(!M) + M = GLOB.movespeed_modification_cache[modtype] = new modtype + return M + +///Add a move speed modifier to a mob. If a variable subtype is passed in as the first argument, it will make a new datum. If ID conflicts, it will overwrite the old ID. +/mob/proc/add_movespeed_modifier(datum/movespeed_modifier/type_or_datum, update = TRUE) + if(ispath(type_or_datum)) + if(!initial(type_or_datum.variable)) + type_or_datum = get_cached_movespeed_modifier(type_or_datum) + else + type_or_datum = new type_or_datum + var/datum/movespeed_modifier/existing = LAZYACCESS(movespeed_modification, type_or_datum.id) + if(existing) + if(existing == type_or_datum) //same thing don't need to touch + return TRUE + remove_movespeed_modifier(existing, FALSE) + if(length(movespeed_modification)) + BINARY_INSERT(type_or_datum.id, movespeed_modification, datum/movespeed_modifier, type_or_datum, priority, COMPARE_VALUE) + LAZYSET(movespeed_modification, type_or_datum.id, type_or_datum) + if(update) + update_movespeed() + return TRUE + +/// Remove a move speed modifier from a mob, whether static or variable. +/mob/proc/remove_movespeed_modifier(datum/movespeed_modifier/type_id_datum, update = TRUE) + var/key + if(ispath(type_id_datum)) + key = initial(type_id_datum.id) || "[type_id_datum]" //id if set, path set to string if not. + else if(!istext(type_id_datum)) //if it isn't text it has to be a datum, as it isn't a type. + key = type_id_datum.id + else //assume it's an id + key = type_id_datum + if(!LAZYACCESS(movespeed_modification, key)) + return FALSE + LAZYREMOVE(movespeed_modification, key) + if(update) + update_movespeed(FALSE) + return TRUE + +/*! Used for variable slowdowns like hunger/health loss/etc, works somewhat like the old list-based modification adds. Returns the modifier datum if successful + How this SHOULD work is: + 1. Ensures type_id_datum one way or another refers to a /variable datum. This makes sure it can't be cached. This includes if it's already in the modification list. + 2. Instantiate a new datum if type_id_datum isn't already instantiated + in the list, using the type. Obviously, wouldn't work for ID only. + 3. Add the datum if necessary using the regular add proc + 4. If any of the rest of the args are not null (see: multiplicative slowdown), modify the datum + 5. Update if necessary +*/ +/mob/proc/add_or_update_variable_movespeed_modifier(datum/movespeed_modifier/type_id_datum, update = TRUE, multiplicative_slowdown) + var/modified = FALSE + var/inject = FALSE + var/datum/movespeed_modifier/final + if(istext(type_id_datum)) + final = LAZYACCESS(movespeed_modification, type_id_datum) + if(!final) + CRASH("Couldn't find existing modification when provided a text ID.") + else if(ispath(type_id_datum)) + if(!initial(type_id_datum.variable)) + CRASH("Not a variable modifier") + final = LAZYACCESS(movespeed_modification, initial(type_id_datum.id) || "[type_id_datum]") + if(!final) + final = new type_id_datum + inject = TRUE + modified = TRUE + else + if(!initial(type_id_datum.variable)) + CRASH("Not a variable modifier") + final = type_id_datum + if(!LAZYACCESS(movespeed_modification, final.id)) + inject = TRUE + modified = TRUE + if(!isnull(multiplicative_slowdown)) + final.multiplicative_slowdown = multiplicative_slowdown + modified = TRUE + if(inject) + add_movespeed_modifier(final, FALSE) + if(update && modified) + update_movespeed(TRUE) + return final + +/// Handles the special case of editing the movement var +/mob/vv_edit_var(var_name, var_value) + var/slowdown_edit = (var_name == NAMEOF(src, cached_multiplicative_slowdown)) + var/diff + if(slowdown_edit && isnum(cached_multiplicative_slowdown) && isnum(var_value)) + remove_movespeed_modifier(/datum/movespeed_modifier/admin_varedit) + diff = var_value - cached_multiplicative_slowdown + . = ..() + if(. && slowdown_edit && isnum(diff)) + add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/admin_varedit, multiplicative_slowdown = diff) + +///Is there a movespeed modifier for this mob +/mob/proc/has_movespeed_modifier(datum/movespeed_modifier/datum_type_id) + var/key + if(ispath(datum_type_id)) + key = initial(datum_type_id.id) || "[datum_type_id]" + else if(istext(datum_type_id)) + key = datum_type_id + else + key = datum_type_id.id + return LAZYACCESS(movespeed_modification, key) + +/// Set or update the global movespeed config on a mob +/mob/proc/update_config_movespeed() + add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/mob_config_speedmod, multiplicative_slowdown = get_config_multiplicative_speed()) + +/// Get the global config movespeed of a mob by type +/mob/proc/get_config_multiplicative_speed() + if(!islist(GLOB.mob_config_movespeed_type_lookup) || !GLOB.mob_config_movespeed_type_lookup[type]) + return 0 + else + return GLOB.mob_config_movespeed_type_lookup[type] + +/// Go through the list of movespeed modifiers and calculate a final movespeed. ANY ADD/REMOVE DONE IN UPDATE_MOVESPEED MUST HAVE THE UPDATE ARGUMENT SET AS FALSE! +/mob/proc/update_movespeed() + . = 0 + var/list/conflict_tracker = list() + for(var/key in get_movespeed_modifiers()) + var/datum/movespeed_modifier/M = movespeed_modification[key] + if(!(M.movetypes & movement_type)) // We don't affect any of these move types, skip + continue + if(M.blacklisted_movetypes & movement_type) // There's a movetype here that disables this modifier, skip + continue + var/conflict = M.conflicts_with + var/amt = M.multiplicative_slowdown + if(conflict) + // Conflicting modifiers prioritize the larger slowdown or the larger speedup + // We purposefuly don't handle mixing speedups and slowdowns on the same id + if(abs(conflict_tracker[conflict]) < abs(amt)) + conflict_tracker[conflict] = amt + else + continue + . += amt + cached_multiplicative_slowdown = . + +/// Get the move speed modifiers list of the mob +/mob/proc/get_movespeed_modifiers() + . = LAZYCOPY(movespeed_modification) + for(var/id in movespeed_mod_immunities) + . -= id + +/// Calculate the total slowdown of all movespeed modifiers +/mob/proc/total_multiplicative_slowdown() + . = 0 + for(var/id in get_movespeed_modifiers()) + var/datum/movespeed_modifier/M = movespeed_modification[id] + . += M.multiplicative_slowdown + +/// Checks if a move speed modifier is valid and not missing any data +/proc/movespeed_data_null_check(datum/movespeed_modifier/M) //Determines if a data list is not meaningful and should be discarded. + . = TRUE + if(M.multiplicative_slowdown) + . = FALSE diff --git a/code/modules/movespeed/modifiers/components.dm b/code/modules/movespeed/modifiers/components.dm new file mode 100644 index 0000000000..436b85e2e1 --- /dev/null +++ b/code/modules/movespeed/modifiers/components.dm @@ -0,0 +1,21 @@ +/datum/movespeed_modifier/shrink_ray + movetypes = GROUND + multiplicative_slowdown = 4 + flags = IGNORE_NOSLOW + +/datum/movespeed_modifier/snail_crawl + multiplicative_slowdown = -7 + movetypes = GROUND + +/datum/movespeed_modifier/sanity + id = MOVESPEED_ID_SANITY + blacklisted_movetypes = FLYING + +/datum/movespeed_modifier/sanity/insane + multiplicative_slowdown = 1.5 + +/datum/movespeed_modifier/sanity/crazy + multiplicative_slowdown = 1 + +/datum/movespeed_modifier/sanity/disturbed + multiplicative_slowdown = 0.5 diff --git a/code/modules/movespeed/modifiers/innate.dm b/code/modules/movespeed/modifiers/innate.dm new file mode 100644 index 0000000000..a0357ddf0f --- /dev/null +++ b/code/modules/movespeed/modifiers/innate.dm @@ -0,0 +1,20 @@ +/datum/movespeed_modifier/strained_muscles + multiplicative_slowdown = -1 + blacklisted_movetypes = (FLYING|FLOATING) + +/datum/movespeed_modifier/pai_spacewalk + multiplicative_slowdown = 2 + flags = IGNORE_NOSLOW + +/datum/movespeed_modifier/species + movetypes = ~FLYING + variable = TRUE + +/datum/movespeed_modifier/dna_vault_speedup + blacklisted_movetypes = (FLYING|FLOATING) + multiplicative_slowdown = -1 + +/datum/movespeed_modifier/small_stride + blacklisted_movetypes = (FLOATING|CRAWLING) + variable = TRUE + flags = IGNORE_NOSLOW diff --git a/code/modules/movespeed/modifiers/items.dm b/code/modules/movespeed/modifiers/items.dm new file mode 100644 index 0000000000..94dc2a1553 --- /dev/null +++ b/code/modules/movespeed/modifiers/items.dm @@ -0,0 +1,12 @@ +/datum/movespeed_modifier/jetpack + conflicts_with = MOVE_CONFLICT_JETPACK + movetypes = FLOATING + +/datum/movespeed_modifier/jetpack/cybernetic + multiplicative_slowdown = -0.5 + +/datum/movespeed_modifier/jetpack/fullspeed + multiplicative_slowdown = -2 + +/datum/movespeed_modifier/die_of_fate + multiplicative_slowdown = 1 diff --git a/code/modules/movespeed/modifiers/misc.dm b/code/modules/movespeed/modifiers/misc.dm new file mode 100644 index 0000000000..55c1aef527 --- /dev/null +++ b/code/modules/movespeed/modifiers/misc.dm @@ -0,0 +1,6 @@ +/datum/movespeed_modifier/admin_varedit + variable = TRUE + +/datum/movespeed_modifier/yellow_orb + multiplicative_slowdown = -2 + blacklisted_movetypes = (FLYING|FLOATING) diff --git a/code/modules/movespeed/modifiers/mobs.dm b/code/modules/movespeed/modifiers/mobs.dm new file mode 100644 index 0000000000..aa60966591 --- /dev/null +++ b/code/modules/movespeed/modifiers/mobs.dm @@ -0,0 +1,120 @@ +/datum/movespeed_modifier/obesity + multiplicative_slowdown = 1.5 + +/datum/movespeed_modifier/monkey_reagent_speedmod + blacklisted_movetypes = FLOATING + variable = TRUE + +/datum/movespeed_modifier/monkey_health_speedmod + blacklisted_movetypes = FLOATING + variable = TRUE + +/datum/movespeed_modifier/monkey_temperature_speedmod + blacklisted_movetypes = FLOATING + variable = TRUE + +/datum/movespeed_modifier/hunger + variable = TRUE + +/datum/movespeed_modifier/slaughter + multiplicative_slowdown = -1 + +/datum/movespeed_modifier/damage_slowdown + blacklisted_movetypes = FLOATING|FLYING + variable = TRUE + +/datum/movespeed_modifier/damage_slowdown_flying + movetypes = FLOATING + variable = TRUE + +/datum/movespeed_modifier/equipment_speedmod + variable = TRUE + blacklisted_movetypes = FLOATING + +/datum/movespeed_modifier/grab_slowdown + id = MOVESPEED_ID_MOB_GRAB_STATE + blacklisted_movetypes = FLOATING + +/datum/movespeed_modifier/grab_slowdown/aggressive + multiplicative_slowdown = 3 + +/datum/movespeed_modifier/grab_slowdown/neck + multiplicative_slowdown = 6 + +/datum/movespeed_modifier/grab_slowdown/kill + multiplicative_slowdown = 9 + +/datum/movespeed_modifier/slime_reagentmod + variable = TRUE + +/datum/movespeed_modifier/slime_healthmod + variable = TRUE + +/datum/movespeed_modifier/config_walk_run + multiplicative_slowdown = 1 + id = MOVESPEED_ID_MOB_WALK_RUN + flags = IGNORE_NOSLOW + +/datum/movespeed_modifier/config_walk_run/proc/sync() + +/datum/movespeed_modifier/config_walk_run/walk/sync() + var/mod = CONFIG_GET(number/movedelay/walk_delay) + multiplicative_slowdown = isnum(mod)? mod : initial(multiplicative_slowdown) + +/datum/movespeed_modifier/config_walk_run/run/sync() + var/mod = CONFIG_GET(number/movedelay/run_delay) + multiplicative_slowdown = isnum(mod)? mod : initial(multiplicative_slowdown) + +/datum/movespeed_modifier/turf_slowdown + movetypes = GROUND + blacklisted_movetypes = (FLYING|FLOATING) + variable = TRUE + +/datum/movespeed_modifier/bulky_drag + variable = TRUE + +/datum/movespeed_modifier/cold + blacklisted_movetypes = FLOATING + variable = TRUE + +/datum/movespeed_modifier/shove + multiplicative_slowdown = SHOVE_SLOWDOWN_STRENGTH + +/datum/movespeed_modifier/human_carry + variable = TRUE + +/datum/movespeed_modifier/limbless + variable = TRUE + movetypes = GROUND + flags = IGNORE_NOSLOW + +/datum/movespeed_modifier/simplemob_varspeed + variable = TRUE + flags = IGNORE_NOSLOW + +/datum/movespeed_modifier/tarantula_web + multiplicative_slowdown = 3 + +/datum/movespeed_modifier/gravity + blacklisted_movetypes = FLOATING + variable = TRUE + flags = IGNORE_NOSLOW + +/datum/movespeed_modifier/carbon_softcrit + multiplicative_slowdown = SOFTCRIT_ADD_SLOWDOWN + +/datum/movespeed_modifier/slime_tempmod + variable = TRUE + +/datum/movespeed_modifier/carbon_crawling + multiplicative_slowdown = CRAWLING_ADD_SLOWDOWN + movetypes = CRAWLING + flags = IGNORE_NOSLOW + +/datum/movespeed_modifier/mob_config_speedmod + variable = TRUE + flags = IGNORE_NOSLOW + +/datum/movespeed_modifier/liver_cirrhosis + blacklisted_movetypes = FLOATING + variable = TRUE diff --git a/code/modules/movespeed/modifiers/reagents.dm b/code/modules/movespeed/modifiers/reagents.dm new file mode 100644 index 0000000000..b6c2458670 --- /dev/null +++ b/code/modules/movespeed/modifiers/reagents.dm @@ -0,0 +1,14 @@ +/datum/movespeed_modifier/reagent + blacklisted_movetypes = (FLYING|FLOATING) + +/datum/movespeed_modifier/reagent/stimulants + multiplicative_slowdown = -0.5 + +/datum/movespeed_modifier/reagent/changelinghaste + multiplicative_slowdown = -2 + +/datum/movespeed_modifier/reagent/skooma + multiplicative_slowdown = -1 + +/datum/movespeed_modifier/reagent/nitryl + multiplicative_slowdown = -1 diff --git a/code/modules/movespeed/modifiers/status_effects.dm b/code/modules/movespeed/modifiers/status_effects.dm new file mode 100644 index 0000000000..4c710cb483 --- /dev/null +++ b/code/modules/movespeed/modifiers/status_effects.dm @@ -0,0 +1,44 @@ +/datum/movespeed_modifier/status_effect/bloodchill + multiplicative_slowdown = 3 + +/datum/movespeed_modifier/status_effect/bonechill + multiplicative_slowdown = 3 + +/datum/movespeed_modifier/status_effect/tarfoot + multiplicative_slowdown = 0.5 + blacklisted_movetypes = (FLYING|FLOATING) + +/datum/movespeed_modifier/status_effect/sepia + variable = TRUE + blacklisted_movetypes = (FLYING|FLOATING) + +/datum/movespeed_modifier/status_effect/mesmerize + blacklisted_movetypes = CRAWLING + multiplicative_slowdown = 5 + priority = 64 + +/datum/movespeed_modifier/status_effect/tased + multiplicative_slowdown = 1.5 + priority = 50 + +/datum/movespeed_modifier/status_effect/tased/no_combat_mode + multiplicative_slowdown = 8 + priority = 100 + +/datum/movespeed_modifier/status_effect/electrostaff + multiplicative_slowdown = 1 + movetypes = GROUND + +//no comment. +/datum/movespeed_modifier/status_effect/breast_hypertrophy + blacklisted_movetypes = FLOATING + variable = TRUE + +//this shouldn't even exist. +/datum/movespeed_modifier/status_effect/penis_hypertrophy + blacklisted_movetypes = FLOATING + variable = TRUE + +/datum/movespeed_modifier/status_effect/mkultra + multiplicative_slowdown = -2 + blacklisted_movetypes= FLYING|FLOATING diff --git a/code/modules/reagents/chemistry/reagents/drug_reagents.dm b/code/modules/reagents/chemistry/reagents/drug_reagents.dm index c96feec4e2..50e8658215 100644 --- a/code/modules/reagents/chemistry/reagents/drug_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/drug_reagents.dm @@ -460,7 +460,7 @@ /datum/reagent/drug/skooma/on_mob_metabolize(mob/living/L) . = ..() - L.add_movespeed_modifier(type, update=TRUE, priority=100, multiplicative_slowdown=-1, blacklisted_movetypes=(FLYING|FLOATING)) + L.add_movespeed_modifier(/datum/movespeed_modifier/reagent/skooma) L.next_move_modifier *= 2 if(ishuman(L)) var/mob/living/carbon/human/H = L @@ -473,7 +473,7 @@ /datum/reagent/drug/skooma/on_mob_end_metabolize(mob/living/L) . = ..() - L.remove_movespeed_modifier(type) + L.remove_movespeed_modifier(/datum/movespeed_modifier/reagent/skooma) L.next_move_modifier *= 0.5 if(ishuman(L)) var/mob/living/carbon/human/H = L diff --git a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm index ecceb6e8bf..1cf1a65c75 100644 --- a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm @@ -708,10 +708,10 @@ datum/reagent/medicine/styptic_powder/overdose_start(mob/living/M) /datum/reagent/medicine/morphine/on_mob_metabolize(mob/living/L) ..() - L.ignore_slowdown(type) + L.add_movespeed_mod_immunities(type, list(/datum/movespeed_modifier/damage_slowdown, /datum/movespeed_modifier/damage_slowdown_flying, /datum/movespeed_modifier/monkey_health_speedmod)) /datum/reagent/medicine/morphine/on_mob_end_metabolize(mob/living/L) - L.unignore_slowdown(type) + L.remove_movespeed_mod_immunities(type, list(/datum/movespeed_modifier/damage_slowdown, /datum/movespeed_modifier/damage_slowdown_flying, /datum/movespeed_modifier/monkey_health_speedmod)) ..() /datum/reagent/medicine/morphine/on_mob_life(mob/living/carbon/M) @@ -993,11 +993,11 @@ datum/reagent/medicine/styptic_powder/overdose_start(mob/living/M) /datum/reagent/medicine/stimulants/on_mob_metabolize(mob/living/L) ..() - L.add_movespeed_modifier(type, update=TRUE, priority=100, multiplicative_slowdown=-0.5, blacklisted_movetypes=(FLYING|FLOATING)) + L.add_movespeed_modifier(/datum/movespeed_modifier/reagent/stimulants) ADD_TRAIT(L, TRAIT_TASED_RESISTANCE, type) /datum/reagent/medicine/stimulants/on_mob_end_metabolize(mob/living/L) - L.remove_movespeed_modifier(type) + L.remove_movespeed_modifier(/datum/movespeed_modifier/reagent/stimulants) REMOVE_TRAIT(L, TRAIT_TASED_RESISTANCE, type) ..() @@ -1332,10 +1332,10 @@ datum/reagent/medicine/styptic_powder/overdose_start(mob/living/M) /datum/reagent/medicine/changelinghaste/on_mob_metabolize(mob/living/L) ..() - L.add_movespeed_modifier(type, update=TRUE, priority=100, multiplicative_slowdown=-2, blacklisted_movetypes=(FLYING|FLOATING)) + L.add_movespeed_modifier(/datum/movespeed_modifier/reagent/changelinghaste) /datum/reagent/medicine/changelinghaste/on_mob_end_metabolize(mob/living/L) - L.remove_movespeed_modifier(type) + L.remove_movespeed_modifier(/datum/movespeed_modifier/reagent/changelinghaste) ..() /datum/reagent/medicine/changelinghaste/on_mob_life(mob/living/carbon/M) @@ -1368,11 +1368,11 @@ datum/reagent/medicine/styptic_powder/overdose_start(mob/living/M) /datum/reagent/medicine/muscle_stimulant/on_mob_metabolize(mob/living/M) . = ..() - M.ignore_slowdown(type) + M.add_movespeed_mod_immunities(type, list(/datum/movespeed_modifier/damage_slowdown, /datum/movespeed_modifier/damage_slowdown_flying, /datum/movespeed_modifier/monkey_health_speedmod)) /datum/reagent/medicine/muscle_stimulant/on_mob_end_metabolize(mob/living/M) . = ..() - M.unignore_slowdown(type) + M.remove_movespeed_mod_immunities(type, list(/datum/movespeed_modifier/damage_slowdown, /datum/movespeed_modifier/damage_slowdown_flying, /datum/movespeed_modifier/monkey_health_speedmod)) /datum/reagent/medicine/modafinil name = "Modafinil" diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm index e66ebc5f20..ff44416e42 100644 --- a/code/modules/reagents/chemistry/reagents/other_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm @@ -1445,10 +1445,10 @@ /datum/reagent/nitryl/on_mob_metabolize(mob/living/L) ..() - L.add_movespeed_modifier(type, update=TRUE, priority=100, multiplicative_slowdown=-1, blacklisted_movetypes=(FLYING|FLOATING)) + L.add_movespeed_modifier(/datum/movespeed_modifier/reagent/nitryl) /datum/reagent/nitryl/on_mob_end_metabolize(mob/living/L) - L.remove_movespeed_modifier(type) + L.remove_movespeed_modifier(/datum/movespeed_modifier/reagent/nitryl) ..() /////////////////////////Coloured Crayon Powder//////////////////////////// diff --git a/code/modules/research/xenobiology/crossbreeding/_status_effects.dm b/code/modules/research/xenobiology/crossbreeding/_status_effects.dm index 95d6c49529..4fd7c2105f 100644 --- a/code/modules/research/xenobiology/crossbreeding/_status_effects.dm +++ b/code/modules/research/xenobiology/crossbreeding/_status_effects.dm @@ -191,7 +191,7 @@ alert_type = /obj/screen/alert/status_effect/bloodchill /datum/status_effect/bloodchill/on_apply() - owner.add_movespeed_modifier("bloodchilled", TRUE, 100, NONE, override = TRUE, multiplicative_slowdown = 3) + owner.add_movespeed_modifier(/datum/movespeed_modifier/status_effect/bloodchill) return ..() /datum/status_effect/bloodchill/tick() @@ -199,7 +199,7 @@ owner.adjustFireLoss(2) /datum/status_effect/bloodchill/on_remove() - owner.remove_movespeed_modifier("bloodchilled") + owner.remove_movespeed_modifier(/datum/movespeed_modifier/status_effect/bloodchill) return ..() /obj/screen/alert/status_effect/bloodchill @@ -213,7 +213,7 @@ alert_type = /obj/screen/alert/status_effect/bonechill /datum/status_effect/bonechill/on_apply() - owner.add_movespeed_modifier("bonechilled", TRUE, 100, NONE, override = TRUE, multiplicative_slowdown = 3) + owner.add_movespeed_modifier(/datum/movespeed_modifier/status_effect/bonechill) return ..() /datum/status_effect/bonechill/tick() @@ -223,7 +223,7 @@ owner.adjust_bodytemperature(-10) /datum/status_effect/bonechill/on_remove() - owner.remove_movespeed_modifier("bonechilled") + owner.remove_movespeed_modifier(/datum/movespeed_modifier/status_effect/bonechill) return ..() /obj/screen/alert/status_effect/bonechill @@ -385,11 +385,11 @@ datum/status_effect/rebreathing/tick() duration = 30 /datum/status_effect/tarfoot/on_apply() - owner.add_movespeed_modifier(MOVESPEED_ID_TARFOOT, update=TRUE, priority=100, multiplicative_slowdown=0.5, blacklisted_movetypes=(FLYING|FLOATING)) + owner.add_movespeed_modifier(/datum/movespeed_modifier/status_effect/tarfoot) return ..() /datum/status_effect/tarfoot/on_remove() - owner.remove_movespeed_modifier(MOVESPEED_ID_TARFOOT) + owner.remove_movespeed_modifier(/datum/movespeed_modifier/status_effect/tarfoot) return ..() /datum/status_effect/spookcookie @@ -707,15 +707,15 @@ datum/status_effect/stabilized/blue/on_remove() /datum/status_effect/stabilized/sepia/tick() if(prob(50) && mod > -1) mod-- - owner.add_movespeed_modifier(MOVESPEED_ID_SEPIA, update=TRUE, priority=100, multiplicative_slowdown=-1, blacklisted_movetypes=(FLYING|FLOATING)) + owner.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/status_effect/sepia, multiplicative_slowdown = 1) else if(mod < 1) mod++ // yeah a value of 0 does nothing but replacing the trait in place is cheaper than removing and adding repeatedly - owner.add_movespeed_modifier(MOVESPEED_ID_SEPIA, update=TRUE, priority=100, multiplicative_slowdown=0, blacklisted_movetypes=(FLYING|FLOATING)) + owner.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/status_effect/sepia, multiplicative_slowdown = 0) return ..() /datum/status_effect/stabilized/sepia/on_remove() - owner.remove_movespeed_modifier(MOVESPEED_ID_SEPIA) + owner.remove_movespeed_modifier(/datum/movespeed_modifier/status_effect/sepia) return ..() /datum/status_effect/stabilized/cerulean @@ -777,11 +777,11 @@ datum/status_effect/stabilized/blue/on_remove() colour = "red" /datum/status_effect/stabilized/red/on_apply() - owner.ignore_slowdown("slimestatus") - return ..() + . = ..() + owner.add_movespeed_mod_immunities(type, /datum/movespeed_modifier/equipment_speedmod) /datum/status_effect/stabilized/red/on_remove() - owner.unignore_slowdown("slimestatus") + owner.remove_movespeed_mod_immunities(type, /datum/movespeed_modifier/equipment_speedmod) return ..() /datum/status_effect/stabilized/green diff --git a/code/modules/station_goals/dna_vault.dm b/code/modules/station_goals/dna_vault.dm index 2aae17b0f3..6c21456e63 100644 --- a/code/modules/station_goals/dna_vault.dm +++ b/code/modules/station_goals/dna_vault.dm @@ -276,7 +276,7 @@ ADD_TRAIT(H, TRAIT_PIERCEIMMUNE, "dna_vault") if(VAULT_SPEED) to_chat(H, "Your legs feel faster.") - H.add_movespeed_modifier(MOVESPEED_ID_DNA_VAULT, update=TRUE, priority=100, multiplicative_slowdown=-1, blacklisted_movetypes=(FLYING|FLOATING)) + H.add_movespeed_modifier(/datum/movespeed_modifier/dna_vault_speedup) if(VAULT_QUICK) to_chat(H, "Your arms move as fast as lightning.") H.next_move_modifier = 0.5 diff --git a/code/modules/surgery/organs/augments_chest.dm b/code/modules/surgery/organs/augments_chest.dm index 47a452cc76..eb42303060 100644 --- a/code/modules/surgery/organs/augments_chest.dm +++ b/code/modules/surgery/organs/augments_chest.dm @@ -165,14 +165,14 @@ if(allow_thrust(0.01)) ion_trail.start() RegisterSignal(owner, COMSIG_MOVABLE_MOVED, .proc/move_react) - owner.add_movespeed_modifier(MOVESPEED_ID_CYBER_THRUSTER, priority=100, multiplicative_slowdown=-2, movetypes=FLOATING, conflict=MOVE_CONFLICT_JETPACK) + owner.add_movespeed_modifier(/datum/movespeed_modifier/jetpack/cybernetic) if(!silent) to_chat(owner, "You turn your thrusters set on.") else ion_trail.stop() if(!QDELETED(owner)) UnregisterSignal(owner, COMSIG_MOVABLE_MOVED) - owner.remove_movespeed_modifier(MOVESPEED_ID_CYBER_THRUSTER) + owner.remove_movespeed_modifier(/datum/movespeed_modifier/jetpack/cybernetic) if(!silent) to_chat(owner, "You turn your thrusters set off.") on = FALSE diff --git a/code/modules/surgery/organs/liver.dm b/code/modules/surgery/organs/liver.dm index 6e5ea0e111..f4771de14f 100755 --- a/code/modules/surgery/organs/liver.dm +++ b/code/modules/surgery/organs/liver.dm @@ -56,22 +56,22 @@ return if(damage >= high_threshold) var/move_calc = 1+((round(damage) - high_threshold)/(high_threshold/3)) - owner.add_movespeed_modifier(MOVESPEED_ID_CIRRHOSIS, TRUE, 100, NONE, override = TRUE, multiplicative_slowdown = move_calc) + owner.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/liver_cirrhosis, multiplicative_slowdown = move_calc) sizeMoveMod(move_calc, owner) else - owner.remove_movespeed_modifier(MOVESPEED_ID_CIRRHOSIS) + owner.remove_movespeed_modifier(/datum/movespeed_modifier/liver_cirrhosis) sizeMoveMod(1, owner) /obj/item/organ/liver/Insert(mob/living/carbon/M, special = FALSE, drop_if_replaced = TRUE) . = ..() if(. && damage >= high_threshold) var/move_calc = 1+((round(damage) - high_threshold)/(high_threshold/3)) - M.add_movespeed_modifier(MOVESPEED_ID_CIRRHOSIS, TRUE, 100, NONE, override = TRUE, multiplicative_slowdown = move_calc) + M.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/liver_cirrhosis, multiplicative_slowdown = move_calc) sizeMoveMod(move_calc, owner) /obj/item/organ/liver/Remove(special = FALSE) if(!QDELETED(owner)) - owner.remove_movespeed_modifier(MOVESPEED_ID_CIRRHOSIS) + owner.remove_movespeed_modifier(/datum/movespeed_modifier/liver_cirrhosis) sizeMoveMod(1, owner) return ..() diff --git a/modular_citadel/code/datums/status_effects/chems.dm b/modular_citadel/code/datums/status_effects/chems.dm index 369fb377a5..9a9e846d5b 100644 --- a/modular_citadel/code/datums/status_effects/chems.dm +++ b/modular_citadel/code/datums/status_effects/chems.dm @@ -76,7 +76,7 @@ to_chat(H, "Your enormous breasts are way too large to fit anything over them!
") if(last_checked_size != B.cached_size) - H.add_movespeed_modifier(BREAST_MOVEMENT_SPEED, TRUE, 100, NONE, override = TRUE, multiplicative_slowdown = moveCalc) + H.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/status_effect/breast_hypertrophy, multiplicative_slowdown = moveCalc) sizeMoveMod(moveCalc) if (B.size == "huge") @@ -93,7 +93,7 @@ /datum/status_effect/chem/breast_enlarger/on_remove() log_game("FERMICHEM: [owner]'s breasts has reduced to an acceptable size. ID: [owner.key]") to_chat(owner, "Your expansive chest has become a more managable size, liberating your movements.
") - owner.remove_movespeed_modifier(BREAST_MOVEMENT_SPEED) + owner.remove_movespeed_modifier(/datum/movespeed_modifier/status_effect/breast_hypertrophy) sizeMoveMod(1) return ..() @@ -152,18 +152,18 @@ playsound(H.loc, 'sound/items/poster_ripped.ogg', 50, 1) to_chat(H, "Your enormous package is way to large to fit anything over!") - if(P.length < 22 && H.has_movespeed_modifier(DICK_MOVEMENT_SPEED)) + if(P.length < 22 && H.has_movespeed_modifier(/datum/movespeed_modifier/status_effect/penis_hypertrophy)) to_chat(owner, "Your rascally willy has become a more managable size, liberating your movements.") - H.remove_movespeed_modifier(DICK_MOVEMENT_SPEED) - else if(P.length >= 22 && !H.has_movespeed_modifier(DICK_MOVEMENT_SPEED)) + H.remove_movespeed_modifier(/datum/movespeed_modifier/status_effect/penis_hypertrophy) + else if(P.length >= 22 && !H.has_movespeed_modifier(/datum/movespeed_modifier/status_effect/penis_hypertrophy)) to_chat(H, "Your indulgent johnson is so substantial, it's taking all your blood and affecting your movements!") - H.add_movespeed_modifier(DICK_MOVEMENT_SPEED, TRUE, 100, NONE, override = TRUE, multiplicative_slowdown = moveCalc) + H.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/status_effect/penis_hypertrophy, multiplicative_slowdown = moveCalc) H.AdjustBloodVol(bloodCalc) ..() /datum/status_effect/chem/penis_enlarger/on_remove() log_game("FERMICHEM: [owner]'s dick has reduced to an acceptable size. ID: [owner.key]") - owner.remove_movespeed_modifier(DICK_MOVEMENT_SPEED) + owner.remove_movespeed_modifier(/datum/movespeed_modifier/status_effect/penis_hypertrophy) owner.ResetBloodVol() return ..() @@ -532,7 +532,7 @@ cooldown += 1 //Cooldown doesn't process till status is done else if(status == "charge") - owner.add_movespeed_modifier(MOVESPEED_ID_MKULTRA, update=TRUE, priority=100, multiplicative_slowdown=-2, blacklisted_movetypes=(FLYING|FLOATING)) + owner.add_movespeed_modifier(/datum/movespeed_modifier/status_effect/mkultra) status = "charged" if(lewd) to_chat(owner, "Your [enthrallGender]'s order fills you with a burst of speed!") @@ -542,7 +542,7 @@ else if (status == "charged") if (statusStrength < 0) status = null - owner.remove_movespeed_modifier(MOVESPEED_ID_MKULTRA) + owner.remove_movespeed_modifier(/datum/movespeed_modifier/status_effect/mkultra) owner.DefaultCombatKnockdown(50) to_chat(owner, "Your body gives out as the adrenaline in your system runs out.") else diff --git a/tgstation.dme b/tgstation.dme index 41708bc0bd..a52826feec 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -2198,7 +2198,6 @@ #include "code\modules\mob\mob_defines.dm" #include "code\modules\mob\mob_helpers.dm" #include "code\modules\mob\mob_movement.dm" -#include "code\modules\mob\mob_movespeed.dm" #include "code\modules\mob\mob_transformation_simple.dm" #include "code\modules\mob\say.dm" #include "code\modules\mob\say_vr.dm" @@ -2594,6 +2593,14 @@ #include "code\modules\modular_computers\hardware\printer.dm" #include "code\modules\modular_computers\hardware\recharger.dm" #include "code\modules\modular_computers\NTNet\NTNRC\conversation.dm" +#include "code\modules\movespeed\_movespeed_modifier.dm" +#include "code\modules\movespeed\modifiers\components.dm" +#include "code\modules\movespeed\modifiers\innate.dm" +#include "code\modules\movespeed\modifiers\items.dm" +#include "code\modules\movespeed\modifiers\misc.dm" +#include "code\modules\movespeed\modifiers\mobs.dm" +#include "code\modules\movespeed\modifiers\reagents.dm" +#include "code\modules\movespeed\modifiers\status_effects.dm" #include "code\modules\newscaster\_news.dm" #include "code\modules\newscaster\feed_channel.dm" #include "code\modules\newscaster\feed_comment.dm" From 3418fe154170dfce243bee7eda4912de085471b6 Mon Sep 17 00:00:00 2001 From: Trilbyspaceclone <30435998+Trilbyspaceclone@users.noreply.github.com> Date: Wed, 22 Apr 2020 17:32:35 -0400 Subject: [PATCH 23/55] Update weaponry.dm --- code/game/objects/items/weaponry.dm | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/code/game/objects/items/weaponry.dm b/code/game/objects/items/weaponry.dm index 7870bd9a0f..48f3bf5b36 100644 --- a/code/game/objects/items/weaponry.dm +++ b/code/game/objects/items/weaponry.dm @@ -638,6 +638,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 w_class = WEIGHT_CLASS_SMALL //Things in this list will be instantly splatted. Flyman weakness is handled in the flyman species weakness proc. var/list/strong_against + var/list/spider_panic /obj/item/melee/flyswatter/Initialize() . = ..() @@ -645,9 +646,11 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 /mob/living/simple_animal/hostile/poison/bees/, /mob/living/simple_animal/butterfly, /mob/living/simple_animal/cockroach, + /obj/item/queen_bee + ) + spider_panic = typecacheof(list( /mob/living/simple_animal/banana_spider, /mob/living/simple_animal/hostile/poison/giant_spider, - /obj/item/queen_bee )) /obj/item/melee/flyswatter/afterattack(atom/target, mob/user, proximity_flag) @@ -659,6 +662,11 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 if(istype(target, /mob/living/)) var/mob/living/bug = target bug.death(1) + if(is_type_in_typecache(target, spider_panic)) + to_chat(user, "You easily land a critical blow on the [target].") + if(istype(target, /mob/living/)) + var/mob/living/bug = target + bug.adjustBruteLoss(-80) else qdel(target) From 6a99c3b2c0fb86305e223e61aaa315a5ea125ae7 Mon Sep 17 00:00:00 2001 From: Trilbyspaceclone <30435998+Trilbyspaceclone@users.noreply.github.com> Date: Wed, 22 Apr 2020 18:07:13 -0400 Subject: [PATCH 24/55] oops all the ) --- code/game/objects/items/weaponry.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/objects/items/weaponry.dm b/code/game/objects/items/weaponry.dm index 48f3bf5b36..19a853406c 100644 --- a/code/game/objects/items/weaponry.dm +++ b/code/game/objects/items/weaponry.dm @@ -647,7 +647,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 /mob/living/simple_animal/butterfly, /mob/living/simple_animal/cockroach, /obj/item/queen_bee - ) + )) spider_panic = typecacheof(list( /mob/living/simple_animal/banana_spider, /mob/living/simple_animal/hostile/poison/giant_spider, From c686ed193bfbc2be650ea0fa19dd5be516d35b93 Mon Sep 17 00:00:00 2001 From: Hatterhat Date: Wed, 22 Apr 2020 17:55:11 -0500 Subject: [PATCH 25/55] a book about mashing Z and LMB --- code/__DEFINES/traits.dm | 2 ++ code/game/objects/items/granters.dm | 29 +++++++++++++++++++ .../projectiles/guns/ballistic/shotgun.dm | 5 +++- .../uplink/uplink_items/uplink_devices.dm | 10 +++++++ 4 files changed, 45 insertions(+), 1 deletion(-) diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index e1fc8fa001..b1696e6ed0 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -221,6 +221,7 @@ #define TRAIT_NO_INTERNALS "no-internals" #define TRAIT_NO_ALCOHOL "alcohol_intolerance" #define TRAIT_MUTATION_STASIS "mutation_stasis" //Prevents processed genetics mutations from processing. +#define TRAIT_FAST_PUMP "fast_pump" // common trait sources #define TRAIT_GENERIC "generic" @@ -246,6 +247,7 @@ #define BLOODSUCKER_TRAIT "bloodsucker" #define SHOES_TRAIT "shoes" //inherited from your sweet kicks #define GLOVE_TRAIT "glove" //inherited by your cool gloves +#define BOOK_TRAIT "granter (book)" // knowledge is power // unique trait sources, still defines #define STATUE_MUTE "statue" diff --git a/code/game/objects/items/granters.dm b/code/game/objects/items/granters.dm index 9749bae313..7f84b56914 100644 --- a/code/game/objects/items/granters.dm +++ b/code/game/objects/items/granters.dm @@ -57,6 +57,35 @@ on_reading_finished(user) reading = FALSE return TRUE +///TRAITS/// + +/obj/item/book/granter/trait + var/granted_trait + var/traitname = "being cool" + +/obj/item/book/granter/trait/already_known(mob/user) + if(!granted_trait) + return TRUE + if(HAS_TRAIT(user, granted_trait)) + to_chat(user, "You already have all the insight you need about [traitname].") + return TRUE + return FALSE + +/obj/item/book/granter/trait/on_reading_start(mob/user) + to_chat(user, "You start reading about [traitname]...") + +/obj/item/book/granter/trait/on_reading_finished(mob/user) + to_chat(user, "You feel like you've got a good handle on [traitname]!") + ADD_TRAIT(user, granted_trait, BOOK_TRAIT) + +/obj/item/book/granter/trait/rifleman + name = "\proper the Neo-Russian Rifleman\'s Primer" + desc = "A book with stains of vodka and...blood? The back is hard to read, but says something about bolt-actions. Or pump-actions. Both, maybe." + oneuse = FALSE + granted_trait = TRAIT_FAST_PUMP + traitname = "riflery" + icon_state = "book1" + remarks = list("One smooth motion...", "Palm the bolt...", "Push up, rotate back, push forward, down...", "Don't slap yourself with the bolt...", "Wait, what's this about pumping?") ///ACTION BUTTONS/// diff --git a/code/modules/projectiles/guns/ballistic/shotgun.dm b/code/modules/projectiles/guns/ballistic/shotgun.dm index 7fb17ced57..a4424d5e88 100644 --- a/code/modules/projectiles/guns/ballistic/shotgun.dm +++ b/code/modules/projectiles/guns/ballistic/shotgun.dm @@ -41,7 +41,10 @@ to_chat(user, "You're too exhausted for that.")//CIT CHANGE - ditto return//CIT CHANGE - ditto pump(user, TRUE) - recentpump = world.time + 10 + if(HAS_TRAIT(user, TRAIT_FAST_PUMP)) + recentpump = world.time + 2 + else + recentpump = world.time + 10 if(istype(user))//CIT CHANGE - makes pumping shotguns cost a lil bit of stamina. user.adjustStaminaLossBuffered(2) //CIT CHANGE - DITTO. make this scale inversely to the strength stat when stats/skills are added return diff --git a/code/modules/uplink/uplink_items/uplink_devices.dm b/code/modules/uplink/uplink_items/uplink_devices.dm index 194281ded6..cda83cf684 100644 --- a/code/modules/uplink/uplink_items/uplink_devices.dm +++ b/code/modules/uplink/uplink_items/uplink_devices.dm @@ -188,6 +188,16 @@ item = /obj/item/healthanalyzer/rad_laser cost = 3 +/datum/uplink_item/device_tools/riflery_primer + name = "Riflery Primer" + desc = "An old book with blood and vodka stains on it. Freshly pulled from a dusty crate in some old warehouse, \ + this primer of questionable worth and value is rumored to increase your rifle-bolt-working and/or shotgun \ + racking fivefold. Then again, the techniques here only work on bolt-actions and pump-actions..." + item = /obj/item/book/granter/trait/rifleman + cost = 3 + restricted_roles = list("Operative") // i want it to be surplusable but i also want it to be mostly nukie only, please advise + surplus = 90 + /datum/uplink_item/device_tools/stimpack name = "Stimpack" desc = "Stimpacks, the tool of many great heroes, make you nearly immune to stuns and knockdowns for about \ From 371e54e2e4979c1c2b6cebc9060deb037140abed Mon Sep 17 00:00:00 2001 From: Hatterhat Date: Wed, 22 Apr 2020 18:06:30 -0500 Subject: [PATCH 26/55] funny meme text --- code/game/objects/items/granters.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/objects/items/granters.dm b/code/game/objects/items/granters.dm index 7f84b56914..0a705df91c 100644 --- a/code/game/objects/items/granters.dm +++ b/code/game/objects/items/granters.dm @@ -85,7 +85,7 @@ granted_trait = TRAIT_FAST_PUMP traitname = "riflery" icon_state = "book1" - remarks = list("One smooth motion...", "Palm the bolt...", "Push up, rotate back, push forward, down...", "Don't slap yourself with the bolt...", "Wait, what's this about pumping?") + remarks = list("One smooth motion...", "Palm the bolt...", "Push up, rotate back, push forward, down...", "Don't slap yourself with the bolt...", "Wait, what's this about pumping?", "Who just scribbled \"Z\" and \"LMB\" on this page?") ///ACTION BUTTONS/// From 57eedfbe6360c07fa7558e49ea17edb24f6d6df2 Mon Sep 17 00:00:00 2001 From: Hatterhat Date: Wed, 22 Apr 2020 18:33:16 -0500 Subject: [PATCH 27/55] fastpumpers no longer lose stam from pumping --- code/modules/projectiles/guns/ballistic/shotgun.dm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/code/modules/projectiles/guns/ballistic/shotgun.dm b/code/modules/projectiles/guns/ballistic/shotgun.dm index a4424d5e88..4894a8d8eb 100644 --- a/code/modules/projectiles/guns/ballistic/shotgun.dm +++ b/code/modules/projectiles/guns/ballistic/shotgun.dm @@ -45,8 +45,8 @@ recentpump = world.time + 2 else recentpump = world.time + 10 - if(istype(user))//CIT CHANGE - makes pumping shotguns cost a lil bit of stamina. - user.adjustStaminaLossBuffered(2) //CIT CHANGE - DITTO. make this scale inversely to the strength stat when stats/skills are added + if(istype(user))//CIT CHANGE - makes pumping shotguns cost a lil bit of stamina. + user.adjustStaminaLossBuffered(2) //CIT CHANGE - DITTO. make this scale inversely to the strength stat when stats/skills are added return /obj/item/gun/ballistic/shotgun/blow_up(mob/user) @@ -93,7 +93,7 @@ fire_delay = 7 mag_type = /obj/item/ammo_box/magazine/internal/shot/riot sawn_desc = "Come with me if you want to live." - unique_reskin = list("Tatical" = "riotshotgun", + unique_reskin = list("Tactical" = "riotshotgun", "Wood Stock" = "wood_riotshotgun" ) @@ -215,7 +215,7 @@ fire_delay = 5 mag_type = /obj/item/ammo_box/magazine/internal/shot/com w_class = WEIGHT_CLASS_HUGE - unique_reskin = list("Tatical" = "cshotgun", + unique_reskin = list("Tactical" = "cshotgun", "Slick" = "cshotgun_slick" ) From b0e8c905312ce8f709b5bd6cac6f5c6eb6e7bfef Mon Sep 17 00:00:00 2001 From: Trilbyspaceclone <30435998+Trilbyspaceclone@users.noreply.github.com> Date: Thu, 23 Apr 2020 02:19:04 -0400 Subject: [PATCH 28/55] Update spacevine.dm --- code/modules/events/spacevine.dm | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/code/modules/events/spacevine.dm b/code/modules/events/spacevine.dm index 3b8f8de359..10c9092230 100644 --- a/code/modules/events/spacevine.dm +++ b/code/modules/events/spacevine.dm @@ -22,7 +22,9 @@ if(turfs.len) //Pick a turf to spawn at if we can var/turf/T = pick(turfs) - new /datum/spacevine_controller(T) //spawn a controller at turf + new /datum/spacevine_controller(T, pick(subtypesof(/datum/spacevine_mutation)), rand(30,100), rand(5,10), src) //spawn a controller at turf with randomized stats and a single random mutation + + /datum/spacevine_mutation From f1a5ba0754f7aad0b81480d24528ab2a16641443 Mon Sep 17 00:00:00 2001 From: Trilbyspaceclone <30435998+Trilbyspaceclone@users.noreply.github.com> Date: Thu, 23 Apr 2020 02:28:16 -0400 Subject: [PATCH 29/55] wew --- code/modules/events/spacevine.dm | 59 ++++++++++++++++---------------- 1 file changed, 30 insertions(+), 29 deletions(-) diff --git a/code/modules/events/spacevine.dm b/code/modules/events/spacevine.dm index 10c9092230..c94c1773e2 100644 --- a/code/modules/events/spacevine.dm +++ b/code/modules/events/spacevine.dm @@ -22,9 +22,7 @@ if(turfs.len) //Pick a turf to spawn at if we can var/turf/T = pick(turfs) - new /datum/spacevine_controller(T, pick(subtypesof(/datum/spacevine_mutation)), rand(30,100), rand(5,10), src) //spawn a controller at turf with randomized stats and a single random mutation - - + new /datum/spacevine_controller(T, pick(subtypesof(/datum/spacevine_mutation)), rand(10,100), rand(5,10), src) //spawn a controller at turf with randomized stats and a single random mutation /datum/spacevine_mutation @@ -174,8 +172,8 @@ var/datum/gas_mixture/GM = T.air if(!GM.gases[/datum/gas/oxygen]) return - GM.gases[/datum/gas/oxygen] = max(GM.gases[/datum/gas/oxygen] - severity * holder.energy, 0) - GAS_GARBAGE_COLLECT(GM.gases) + GM.gases[/datum/gas/oxygen][MOLES] = max(GM.gases[/datum/gas/oxygen][MOLES] - severity * holder.energy, 0) + GM.garbage_collect() /datum/spacevine_mutation/nitro_eater name = "nitrogen consuming" @@ -189,8 +187,8 @@ var/datum/gas_mixture/GM = T.air if(!GM.gases[/datum/gas/nitrogen]) return - GM.gases[/datum/gas/nitrogen] = max(GM.gases[/datum/gas/nitrogen] - severity * holder.energy, 0) - GAS_GARBAGE_COLLECT(GM.gases) + GM.gases[/datum/gas/nitrogen][MOLES] = max(GM.gases[/datum/gas/nitrogen][MOLES] - severity * holder.energy, 0) + GM.garbage_collect() /datum/spacevine_mutation/carbondioxide_eater name = "CO2 consuming" @@ -204,8 +202,8 @@ var/datum/gas_mixture/GM = T.air if(!GM.gases[/datum/gas/carbon_dioxide]) return - GM.gases[/datum/gas/carbon_dioxide] = max(GM.gases[/datum/gas/carbon_dioxide] - severity * holder.energy, 0) - GAS_GARBAGE_COLLECT(GM.gases) + GM.gases[/datum/gas/carbon_dioxide][MOLES] = max(GM.gases[/datum/gas/carbon_dioxide][MOLES] - severity * holder.energy, 0) + GM.garbage_collect() /datum/spacevine_mutation/plasma_eater name = "toxins consuming" @@ -219,8 +217,8 @@ var/datum/gas_mixture/GM = T.air if(!GM.gases[/datum/gas/plasma]) return - GM.gases[/datum/gas/plasma] = max(GM.gases[/datum/gas/plasma] - severity * holder.energy, 0) - GAS_GARBAGE_COLLECT(GM.gases) + GM.gases[/datum/gas/plasma][MOLES] = max(GM.gases[/datum/gas/plasma][MOLES] - severity * holder.energy, 0) + GM.garbage_collect() /datum/spacevine_mutation/thorns name = "thorny" @@ -229,13 +227,13 @@ quality = NEGATIVE /datum/spacevine_mutation/thorns/on_cross(obj/structure/spacevine/holder, mob/living/crosser) - if(prob(severity) && istype(crosser) && !isvineimmune(holder)) + if(prob(severity) && istype(crosser) && !isvineimmune(crosser)) var/mob/living/M = crosser M.adjustBruteLoss(5) to_chat(M, "You cut yourself on the thorny vines.") /datum/spacevine_mutation/thorns/on_hit(obj/structure/spacevine/holder, mob/living/hitter, obj/item/I, expected_damage) - if(prob(severity) && istype(hitter) && !isvineimmune(holder)) + if(prob(severity) && istype(hitter) && !isvineimmune(hitter)) var/mob/living/M = hitter M.adjustBruteLoss(5) to_chat(M, "You cut yourself on the thorny vines.") @@ -253,7 +251,7 @@ holder.obj_integrity = holder.max_integrity /datum/spacevine_mutation/woodening/on_hit(obj/structure/spacevine/holder, mob/living/hitter, obj/item/I, expected_damage) - if(I.get_sharpness()) + if(I?.get_sharpness()) . = expected_damage * 0.5 else . = expected_damage @@ -346,16 +344,17 @@ switch(damage_type) if(BRUTE) if(damage_amount) - playsound(src, 'sound/weapons/slash.ogg', 50, 1) + playsound(src, 'sound/weapons/slash.ogg', 50, TRUE) else - playsound(src, 'sound/weapons/tap.ogg', 50, 1) + playsound(src, 'sound/weapons/tap.ogg', 50, TRUE) if(BURN) - playsound(src.loc, 'sound/items/welder.ogg', 100, 1) + playsound(src.loc, 'sound/items/welder.ogg', 100, TRUE) -/obj/structure/spacevine/Crossed(mob/crosser) - if(isliving(crosser)) - for(var/datum/spacevine_mutation/SM in mutations) - SM.on_cross(src, crosser) +/obj/structure/spacevine/Crossed(atom/movable/AM) + if(!isliving(AM)) + return + for(var/datum/spacevine_mutation/SM in mutations) + SM.on_cross(src, AM) //ATTACK HAND IGNORING PARENT RETURN VALUE /obj/structure/spacevine/attack_hand(mob/user) @@ -380,10 +379,12 @@ var/list/vine_mutations_list var/mutativeness = 1 -/datum/spacevine_controller/New(turf/location, list/muts, potency, production) +/datum/spacevine_controller/New(turf/location, list/muts, potency, production, datum/round_event/event = null) vines = list() growth_queue = list() - spawn_spacevine_piece(location, null, muts) + var/obj/structure/spacevine/SV = spawn_spacevine_piece(location, null, muts) + if (event) + event.announce_to_ghosts(SV) START_PROCESSING(SSobj, src) vine_mutations_list = list() init_subtypes(/datum/spacevine_mutation/, vine_mutations_list) @@ -430,6 +431,7 @@ for(var/datum/spacevine_mutation/SM in SV.mutations) SM.on_birth(SV) location.Entered(SV) + return SV /datum/spacevine_controller/proc/VineDestroyed(obj/structure/spacevine/S) S.master = null @@ -532,15 +534,14 @@ if(!override) qdel(src) -/obj/structure/spacevine/CanPass(atom/movable/mover, turf/target) +/obj/structure/spacevine/CanAllowThrough(atom/movable/mover, turf/target) + . = ..() if(isvineimmune(mover)) - . = TRUE - else - . = ..() + return TRUE /proc/isvineimmune(atom/A) - . = FALSE if(isliving(A)) var/mob/living/M = A if(("vines" in M.faction) || ("plants" in M.faction)) - . = TRUE + return TRUE + return FALSE From 86abfefa1b7cfc250f5908b4533938decd2d8139 Mon Sep 17 00:00:00 2001 From: TrilbySpaceClone Date: Thu, 23 Apr 2020 02:52:07 -0400 Subject: [PATCH 30/55] still dosnt work --- code/modules/events/spacevine.dm | 18 +- .../simple_animal/hostile/venus_human_trap.dm | 190 ++++++++++++------ .../code/modules/language/sylvan.dm | 22 ++ tgstation.dme | 1 + 4 files changed, 158 insertions(+), 73 deletions(-) create mode 100644 modular_citadel/code/modules/language/sylvan.dm diff --git a/code/modules/events/spacevine.dm b/code/modules/events/spacevine.dm index c94c1773e2..3155642c4a 100644 --- a/code/modules/events/spacevine.dm +++ b/code/modules/events/spacevine.dm @@ -172,8 +172,8 @@ var/datum/gas_mixture/GM = T.air if(!GM.gases[/datum/gas/oxygen]) return - GM.gases[/datum/gas/oxygen][MOLES] = max(GM.gases[/datum/gas/oxygen][MOLES] - severity * holder.energy, 0) - GM.garbage_collect() + GM.gases[/datum/gas/oxygen] = max(GM.gases[/datum/gas/oxygen] - severity * holder.energy, 0) + GAS_GARBAGE_COLLECT(GM.gases) /datum/spacevine_mutation/nitro_eater name = "nitrogen consuming" @@ -187,8 +187,8 @@ var/datum/gas_mixture/GM = T.air if(!GM.gases[/datum/gas/nitrogen]) return - GM.gases[/datum/gas/nitrogen][MOLES] = max(GM.gases[/datum/gas/nitrogen][MOLES] - severity * holder.energy, 0) - GM.garbage_collect() + GM.gases[/datum/gas/nitrogen] = max(GM.gases[/datum/gas/nitrogen] - severity * holder.energy, 0) + GAS_GARBAGE_COLLECT(GM.gases) /datum/spacevine_mutation/carbondioxide_eater name = "CO2 consuming" @@ -202,8 +202,8 @@ var/datum/gas_mixture/GM = T.air if(!GM.gases[/datum/gas/carbon_dioxide]) return - GM.gases[/datum/gas/carbon_dioxide][MOLES] = max(GM.gases[/datum/gas/carbon_dioxide][MOLES] - severity * holder.energy, 0) - GM.garbage_collect() + GM.gases[/datum/gas/carbon_dioxide] = max(GM.gases[/datum/gas/carbon_dioxide] - severity * holder.energy, 0) + GAS_GARBAGE_COLLECT(GM.gases) /datum/spacevine_mutation/plasma_eater name = "toxins consuming" @@ -217,8 +217,8 @@ var/datum/gas_mixture/GM = T.air if(!GM.gases[/datum/gas/plasma]) return - GM.gases[/datum/gas/plasma][MOLES] = max(GM.gases[/datum/gas/plasma][MOLES] - severity * holder.energy, 0) - GM.garbage_collect() + GM.gases[/datum/gas/plasma] = max(GM.gases[/datum/gas/plasma] - severity * holder.energy, 0) + GAS_GARBAGE_COLLECT(GM.gases) /datum/spacevine_mutation/thorns name = "thorny" @@ -544,4 +544,4 @@ var/mob/living/M = A if(("vines" in M.faction) || ("plants" in M.faction)) return TRUE - return FALSE + return FALSE \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/hostile/venus_human_trap.dm b/code/modules/mob/living/simple_animal/hostile/venus_human_trap.dm index 13a4d1793e..4189e40a3d 100644 --- a/code/modules/mob/living/simple_animal/hostile/venus_human_trap.dm +++ b/code/modules/mob/living/simple_animal/hostile/venus_human_trap.dm @@ -1,5 +1,13 @@ - - +/** + * Kudzu Flower Bud + * + * A flower created by flowering kudzu which spawns a venus human trap after a certain amount of time has passed. + * + * A flower created by kudzu with the flowering mutation. Spawns a venus human trap after 2 minutes under normal circumstances. + * Also spawns 4 vines going out in diagonal directions from the bud. Any living creature not aligned with plants is damaged by these vines. + * Once it grows a venus human trap, the bud itself will destroy itself. + * + */ /obj/structure/alien/resin/flower_bud_enemy //inheriting basic attack/damage stuff from alien structures name = "flower bud" desc = "A large pulsating plant..." @@ -9,9 +17,9 @@ opacity = 0 canSmoothWith = list() smooth = SMOOTH_FALSE + /// The amount of time it takes to create a venus human trap, in deciseconds var/growth_time = 1200 - /obj/structure/alien/resin/flower_bud_enemy/Initialize() . = ..() var/list/anchors = list() @@ -25,36 +33,49 @@ B.sleep_time = 10 //these shouldn't move, so let's slow down updates to 1 second (any slower and the deletion of the vines would be too slow) addtimer(CALLBACK(src, .proc/bear_fruit), growth_time) +/** + * Spawns a venus human trap, then qdels itself. + * + * Displays a message, spawns a human venus trap, then qdels itself. + */ /obj/structure/alien/resin/flower_bud_enemy/proc/bear_fruit() - visible_message("the plant has borne fruit!") + visible_message("The plant has borne fruit!") new /mob/living/simple_animal/hostile/venus_human_trap(get_turf(src)) qdel(src) - /obj/effect/ebeam/vine name = "thick vine" mouse_opacity = MOUSE_OPACITY_ICON desc = "A thick vine, painful to the touch." - /obj/effect/ebeam/vine/Crossed(atom/movable/AM) + . = ..() if(isliving(AM)) var/mob/living/L = AM - if(!("vines" in L.faction)) + if(!isvineimmune(L)) L.adjustBruteLoss(5) to_chat(L, "You cut yourself on the thorny vines.") - - +/** + * Venus Human Trap + * + * The result of a kudzu flower bud, these enemies use vines to drag prey close to them for attack. + * + * A carnivorious plant which uses vines to catch and ensnare prey. Spawns from kudzu flower buds. + * Each one has a maximum of four vines, which can be attached to a variety of things. Carbons are stunned when a vine is attached to them, and movable entities are pulled closer over time. + * Attempting to attach a vine to something with a vine already attached to it will pull all movable targets closer on command. + * Once the prey is in melee range, melee attacks from the venus human trap heals itself for 10% of its max health, assuming the target is alive. + * Akin to certain spiders, venus human traps can also be possessed and controlled by ghosts. + * + */ /mob/living/simple_animal/hostile/venus_human_trap name = "venus human trap" desc = "Now you know how the fly feels." icon_state = "venus_human_trap" - threat = 1 layer = SPACEVINE_MOB_LAYER health = 50 maxHealth = 50 - ranged = 1 + ranged = TRUE harm_intent_damage = 5 obj_damage = 60 melee_damage_lower = 25 @@ -63,65 +84,106 @@ attack_sound = 'sound/weapons/bladeslice.ogg' atmos_requirements = list("min_oxy" = 0, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0) unsuitable_atmos_damage = 0 + lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE faction = list("hostile","vines","plants") - var/list/grasping = list() - var/max_grasps = 4 - var/grasp_chance = 20 - var/grasp_pull_chance = 85 - var/grasp_range = 4 - del_on_death = 1 + initial_language_holder = /datum/language_holder/venus + del_on_death = TRUE + /// A list of all the plant's vines + var/list/vines = list() + /// The maximum amount of vines a plant can have at one time + var/max_vines = 4 + /// How far away a plant can attach a vine to something + var/vine_grab_distance = 5 + /// Whether or not this plant is ghost possessable + var/playable_plant = TRUE -/mob/living/simple_animal/hostile/venus_human_trap/Destroy() - for(var/L in grasping) - var/datum/beam/B = grasping[L] - if(B) - qdel(B) - grasping = null - return ..() - -/mob/living/simple_animal/hostile/venus_human_trap/handle_automated_action() - if(..()) - for(var/mob/living/L in grasping) - if(L.stat == DEAD) - var/datum/beam/B = grasping[L] - if(B) - B.End() - grasping -= L - - //Can attack+pull multiple times per cycle - if(L.Adjacent(src)) - L.attack_animal(src) - else - if(prob(grasp_pull_chance)) - setDir(get_dir(src,L) )//staaaare - step(L,get_dir(L,src)) //reel them in - L.DefaultCombatKnockdown(60) //you can't get away now~ - - if(grasping.len < max_grasps) - grasping: - for(var/mob/living/L in view(grasp_range, src)) - if(L == src || faction_check_mob(L) || (L in grasping) || L == target) - continue - for(var/t in getline(src,L)) - for(var/a in t) - var/atom/A = a - if(A.density && A != L) - continue grasping - if(prob(grasp_chance)) - to_chat(L, "\The [src] has you entangled!") - grasping[L] = Beam(L, "vine", time=INFINITY, maxdistance=5, beam_type=/obj/effect/ebeam/vine) - - break //only take 1 new victim per cycle +/mob/living/simple_animal/hostile/venus_human_trap/Life() + . = ..() + pull_vines() +/mob/living/simple_animal/hostile/venus_human_trap/AttackingTarget() + . = ..() + if(isliving(target)) + var/mob/living/L = target + if(L.stat != DEAD) + adjustHealth(-maxHealth * 0.1) /mob/living/simple_animal/hostile/venus_human_trap/OpenFire(atom/the_target) - var/dist = get_dist(src,the_target) - Beam(the_target, "vine", time=dist*2, maxdistance=dist+2, beam_type=/obj/effect/ebeam/vine) - the_target.attack_animal(src) + for(var/datum/beam/B in vines) + if(B.target == the_target) + pull_vines() + ranged_cooldown = world.time + (ranged_cooldown_time * 0.5) + return + if(get_dist(src,the_target) > vine_grab_distance || vines.len == max_vines) + return + for(var/turf/T in getline(src,target)) + if (T.density) + return + for(var/obj/O in T) + if(O.density) + return + var/datum/beam/newVine = Beam(the_target, "vine", time=INFINITY, maxdistance = vine_grab_distance, beam_type=/obj/effect/ebeam/vine) + RegisterSignal(newVine, COMSIG_PARENT_QDELETING, .proc/remove_vine, newVine) + vines += newVine + if(isliving(the_target)) + var/mob/living/L = the_target + L.Paralyze(20) + ranged_cooldown = world.time + ranged_cooldown_time -/mob/living/simple_animal/hostile/venus_human_trap/CanAttack(atom/the_target) +/mob/living/simple_animal/hostile/venus_human_trap/Login() + . = ..() + to_chat(src, "You a venus human trap! Protect the kudzu at all costs, and feast on those who oppose you!") + +/mob/living/simple_animal/hostile/venus_human_trap/attack_ghost(mob/user) . = ..() if(.) - if(the_target in grasping) - return 0 + return + humanize_plant(user) + +/** + * Sets a ghost to control the plant if the plant is eligible + * + * Asks the interacting ghost if they would like to control the plant. + * If they answer yes, and another ghost hasn't taken control, sets the ghost to control the plant. + * Arguments: + * * mob/user - The ghost to possibly control the plant + */ +/mob/living/simple_animal/hostile/venus_human_trap/proc/humanize_plant(mob/user) + if(key || !playable_plant || stat) + return + var/plant_ask = alert("Become a venus human trap?", "Are you reverse vegan?", "Yes", "No") + if(plant_ask == "No" || QDELETED(src)) + return + if(key) + to_chat(user, "Someone else already took this plant!") + return + key = user.key + log_game("[key_name(src)] took control of [name].") + +/** + * Manages how the vines should affect the things they're attached to. + * + * Pulls all movable targets of the vines closer to the plant + * If the target is on the same tile as the plant, destroy the vine + * Removes any QDELETED vines from the vines list. + */ +/mob/living/simple_animal/hostile/venus_human_trap/proc/pull_vines() + for(var/datum/beam/B in vines) + if(istype(B.target, /atom/movable)) + var/atom/movable/AM = B.target + if(!AM.anchored) + step(AM,get_dir(AM,src)) + if(get_dist(src,B.target) == 0) + B.End() + +/** + * Removes a vine from the list. + * + * Removes the vine from our list. + * Called specifically when the vine is about to be destroyed, so we don't have any null references. + * Arguments: + * * datum/beam/vine - The vine to be removed from the list. + */ +mob/living/simple_animal/hostile/venus_human_trap/proc/remove_vine(datum/beam/vine, force) + vines -= vine \ No newline at end of file diff --git a/modular_citadel/code/modules/language/sylvan.dm b/modular_citadel/code/modules/language/sylvan.dm new file mode 100644 index 0000000000..8748a73083 --- /dev/null +++ b/modular_citadel/code/modules/language/sylvan.dm @@ -0,0 +1,22 @@ +// The language of the vinebings. Yes, it's a shameless ripoff of elvish. +/datum/language/sylvan + name = "Sylvan" + desc = "A complicated, ancient language spoken by vine like beings." + speech_verb = "expresses" + ask_verb = "inquires" + exclaim_verb = "declares" + key = "h" + space_chance = 20 + syllables = list( + "fii", "sii", "rii", "rel", "maa", "ala", "san", "tol", "tok", "dia", "eres", + "fal", "tis", "bis", "qel", "aras", "losk", "rasa", "eob", "hil", "tanl", "aere", + "fer", "bal", "pii", "dala", "ban", "foe", "doa", "cii", "uis", "mel", "wex", + "incas", "int", "elc", "ent", "aws", "qip", "nas", "vil", "jens", "dila", "fa", + "la", "re", "do", "ji", "ae", "so", "qe", "ce", "na", "mo", "ha", "yu" + ) + icon_state = "plant" + default_priority = 90 + +/datum/language_holder/venus + languages = list(/datum/language/common, /datum/language/sylvan, /datum/language/machine) + only_speaks_language = /datum/language/sylvan \ No newline at end of file diff --git a/tgstation.dme b/tgstation.dme index 7bfbd2dde2..7c362bcaa2 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -3303,6 +3303,7 @@ #include "modular_citadel\code\modules\custom_loadout\custom_items.dm" #include "modular_citadel\code\modules\custom_loadout\load_to_mob.dm" #include "modular_citadel\code\modules\custom_loadout\read_from_file.dm" +#include "modular_citadel\code\modules\language\sylvan.dm" #include "modular_citadel\code\modules\mentor\dementor.dm" #include "modular_citadel\code\modules\mentor\follow.dm" #include "modular_citadel\code\modules\mentor\mentor.dm" From 7761990919808f8e0094ebc73e701276b5edcfee Mon Sep 17 00:00:00 2001 From: TrilbySpaceClone Date: Thu, 23 Apr 2020 03:13:07 -0400 Subject: [PATCH 31/55] soooo this complies but does it work? --- code/modules/events/spacevine.dm | 7 ++----- .../mob/living/simple_animal/hostile/venus_human_trap.dm | 2 +- modular_citadel/code/game/machinery/wishgranter.dm | 3 +-- 3 files changed, 4 insertions(+), 8 deletions(-) diff --git a/code/modules/events/spacevine.dm b/code/modules/events/spacevine.dm index 3155642c4a..60f2aef629 100644 --- a/code/modules/events/spacevine.dm +++ b/code/modules/events/spacevine.dm @@ -22,7 +22,7 @@ if(turfs.len) //Pick a turf to spawn at if we can var/turf/T = pick(turfs) - new /datum/spacevine_controller(T, pick(subtypesof(/datum/spacevine_mutation)), rand(10,100), rand(5,10), src) //spawn a controller at turf with randomized stats and a single random mutation + new /datum/spacevine_controller(T, pick(subtypesof(/datum/spacevine_mutation)), rand(30,100), rand(5,10), src) //spawn a controller at turf with randomized stats and a single random mutation /datum/spacevine_mutation @@ -382,9 +382,6 @@ /datum/spacevine_controller/New(turf/location, list/muts, potency, production, datum/round_event/event = null) vines = list() growth_queue = list() - var/obj/structure/spacevine/SV = spawn_spacevine_piece(location, null, muts) - if (event) - event.announce_to_ghosts(SV) START_PROCESSING(SSobj, src) vine_mutations_list = list() init_subtypes(/datum/spacevine_mutation/, vine_mutations_list) @@ -534,7 +531,7 @@ if(!override) qdel(src) -/obj/structure/spacevine/CanAllowThrough(atom/movable/mover, turf/target) +/obj/structure/spacevine/CanPass(atom/movable/mover, turf/target) . = ..() if(isvineimmune(mover)) return TRUE diff --git a/code/modules/mob/living/simple_animal/hostile/venus_human_trap.dm b/code/modules/mob/living/simple_animal/hostile/venus_human_trap.dm index 4189e40a3d..cbfa7780da 100644 --- a/code/modules/mob/living/simple_animal/hostile/venus_human_trap.dm +++ b/code/modules/mob/living/simple_animal/hostile/venus_human_trap.dm @@ -186,4 +186,4 @@ * * datum/beam/vine - The vine to be removed from the list. */ mob/living/simple_animal/hostile/venus_human_trap/proc/remove_vine(datum/beam/vine, force) - vines -= vine \ No newline at end of file + vines -= vine diff --git a/modular_citadel/code/game/machinery/wishgranter.dm b/modular_citadel/code/game/machinery/wishgranter.dm index 7758c0d613..6cfe07b7a0 100644 --- a/modular_citadel/code/game/machinery/wishgranter.dm +++ b/modular_citadel/code/game/machinery/wishgranter.dm @@ -94,9 +94,8 @@ var/mob/living/simple_animal/hostile/venus_human_trap/killwish = new /mob/living/simple_animal/hostile/venus_human_trap(loc) killwish.maxHealth = 1500 killwish.health = killwish.maxHealth - killwish.grasp_range = 6 + killwish.vine_grab_distance = 6 killwish.melee_damage_upper = 30 - killwish.grasp_chance = 50 killwish.loot = list(/obj/item/twohanded/dualsaber/hypereutactic) charges-- insisting = FALSE From 8bcdbf5fc65514cbbd1805e1c861b1b7752719c1 Mon Sep 17 00:00:00 2001 From: Trilbyspaceclone <30435998+Trilbyspaceclone@users.noreply.github.com> Date: Thu, 23 Apr 2020 03:29:26 -0400 Subject: [PATCH 32/55] Update weaponry.dm --- code/game/objects/items/weaponry.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/game/objects/items/weaponry.dm b/code/game/objects/items/weaponry.dm index 19a853406c..2d132e4eef 100644 --- a/code/game/objects/items/weaponry.dm +++ b/code/game/objects/items/weaponry.dm @@ -666,7 +666,7 @@ for further reading, please see: https://github.com/tgstation/tgstation/pull/301 to_chat(user, "You easily land a critical blow on the [target].") if(istype(target, /mob/living/)) var/mob/living/bug = target - bug.adjustBruteLoss(-80) + bug.adjustBruteLoss(-35) //What kinda mad man would go into melee with a spider?! else qdel(target) From 3e0519455ae9d4126bd293e6d51285ce1d073be6 Mon Sep 17 00:00:00 2001 From: Trilbyspaceclone <30435998+Trilbyspaceclone@users.noreply.github.com> Date: Thu, 23 Apr 2020 03:34:38 -0400 Subject: [PATCH 33/55] Update sylvan.dm --- modular_citadel/code/modules/language/sylvan.dm | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/modular_citadel/code/modules/language/sylvan.dm b/modular_citadel/code/modules/language/sylvan.dm index 8748a73083..c9458bb4cf 100644 --- a/modular_citadel/code/modules/language/sylvan.dm +++ b/modular_citadel/code/modules/language/sylvan.dm @@ -14,9 +14,10 @@ "incas", "int", "elc", "ent", "aws", "qip", "nas", "vil", "jens", "dila", "fa", "la", "re", "do", "ji", "ae", "so", "qe", "ce", "na", "mo", "ha", "yu" ) - icon_state = "plant" + icon = 'icons/obj/hydroponics/harvest.dmi' + icon_state = "lily" default_priority = 90 /datum/language_holder/venus languages = list(/datum/language/common, /datum/language/sylvan, /datum/language/machine) - only_speaks_language = /datum/language/sylvan \ No newline at end of file + only_speaks_language = /datum/language/sylvan From b5abfd927312a8302bdb3a9508b43bb2f11a3ea1 Mon Sep 17 00:00:00 2001 From: Ghommie <42542238+Ghommie@users.noreply.github.com> Date: Thu, 23 Apr 2020 14:49:05 +0200 Subject: [PATCH 34/55] thank you dreamchecker. --- code/modules/mob/mob_movement.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/mob/mob_movement.dm b/code/modules/mob/mob_movement.dm index 9bef48320b..ddcebe9c0a 100644 --- a/code/modules/mob/mob_movement.dm +++ b/code/modules/mob/mob_movement.dm @@ -253,7 +253,7 @@ if(!speed_change) remove_movespeed_modifier(/datum/movespeed_modifier/gravity) else - add_movespeed_modifier(/datum/movespeed_modifier/gravity, multiplicative_slowdown = speed_change) + add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/gravity, multiplicative_slowdown = speed_change) //bodypart selection - Cyberboss //8 toggles through head - eyes - mouth From 1a6f5eb131f13c7b85245071773e490fba18dee8 Mon Sep 17 00:00:00 2001 From: DeltaFire Date: Thu, 23 Apr 2020 15:15:26 +0200 Subject: [PATCH 35/55] If it compiles it works Kidding, tested on local and it runs fine. Adds nanite protocols to the techweb, without BEPIS, aswell as adding one more protocol onto the ones ported from /tg --- code/__DEFINES/nanites.dm | 4 ++++ code/datums/components/nanites.dm | 2 +- code/modules/research/designs/nanite_designs.dm | 9 +++++++-- code/modules/research/nanites/nanite_program_hub.dm | 2 +- code/modules/research/nanites/nanite_programs.dm | 2 +- .../research/nanites/nanite_programs/protocols.dm | 11 +++++++++++ code/modules/research/techweb/all_nodes.dm | 8 ++++++++ tgstation.dme | 1 + 8 files changed, 34 insertions(+), 5 deletions(-) diff --git a/code/__DEFINES/nanites.dm b/code/__DEFINES/nanites.dm index ed15e972ab..05c3501609 100644 --- a/code/__DEFINES/nanites.dm +++ b/code/__DEFINES/nanites.dm @@ -12,6 +12,10 @@ #define NANITE_CLOUD_DISABLE 2 #define NANITE_CLOUD_ENABLE 3 +///Nanite Protocol types +#define NANITE_PROTOCOL_REPLICATION "nanite_replication" +#define NANITE_PROTOCOL_STORAGE "nanite_storage" + ///Nanite extra settings types: used to help uis know what type an extra setting is #define NESTYPE_TEXT "text" #define NESTYPE_NUMBER "number" diff --git a/code/datums/components/nanites.dm b/code/datums/components/nanites.dm index 8ba748dac7..29add286be 100644 --- a/code/datums/components/nanites.dm +++ b/code/datums/components/nanites.dm @@ -12,7 +12,7 @@ var/list/datum/nanite_program/programs = list() var/max_programs = NANITE_PROGRAM_LIMIT - var/list/datum/nanite_program/protocol/protocols = list() ///Separate list of protocol programs, to avoid looping through the whole programs list when cheking for conflicts + var/list/datum/nanite_program/protocol/protocols = list() ///Separate list of protocol programs, to avoid looping through the whole programs list when checking for conflicts var/start_time = 0 ///Timestamp to when the nanites were first inserted in the host var/stealth = FALSE //if TRUE, does not appear on HUDs and health scans var/diagnostics = TRUE //if TRUE, displays program list when scanned by nanite scanners diff --git a/code/modules/research/designs/nanite_designs.dm b/code/modules/research/designs/nanite_designs.dm index c72ee4fb8c..b157d0c349 100644 --- a/code/modules/research/designs/nanite_designs.dm +++ b/code/modules/research/designs/nanite_designs.dm @@ -529,7 +529,6 @@ ////////////////////NANITE PROTOCOLS////////////////////////////////////// //Note about the category name: The UI cuts the last 8 characters from the category name to remove the " Nanites" in the other categories //Because of this, Protocols was getting cut down to "P", so i had to add some padding -/* /datum/design/nanites/kickstart name = "Kickstart Protocol" desc = "Replication Protocol: the nanites focus on early growth, heavily boosting replication rate for a few minutes after the initial implantation." @@ -557,4 +556,10 @@ id = "offline_nanites" program_type = /datum/nanite_program/protocol/offline category = list("Protocols_Nanites") -*/ + +/datum/design/nanites/synergy + name = "Synergy Protocol" + desc = "Replication Protocol: the nanites syncronize their tasks and processes within a host, leading to an increase in replication speed proportional to the current nanite volume." + id = "synergy_nanites" + program_type = /datum/nanite_program/protocol/synergy + category = list("Protocols_Nanites") diff --git a/code/modules/research/nanites/nanite_program_hub.dm b/code/modules/research/nanites/nanite_program_hub.dm index ea4392f236..47ee2447d2 100644 --- a/code/modules/research/nanites/nanite_program_hub.dm +++ b/code/modules/research/nanites/nanite_program_hub.dm @@ -21,7 +21,7 @@ list(name = "Augmentation Nanites"), list(name = "Suppression Nanites"), list(name = "Weaponized Nanites"), - //list(name = "Protocols") B.E.P.I.S Content, which we dont have + list(name = "Protocols") //Moved to default techweb from B.E.P.I.S. research, for now ) /obj/machinery/nanite_program_hub/Initialize() diff --git a/code/modules/research/nanites/nanite_programs.dm b/code/modules/research/nanites/nanite_programs.dm index 72f969a77e..faa81be0a5 100644 --- a/code/modules/research/nanites/nanite_programs.dm +++ b/code/modules/research/nanites/nanite_programs.dm @@ -290,7 +290,7 @@ qdel(src) ///A nanite program containing a behaviour protocol. Only one protocol of each class can be active at once. -//Currently unused due to us lacking the B.E.P.I.S +//Moved to being 'normally' researched due to lack of B.E.P.I.S. /datum/nanite_program/protocol name = "Nanite Protocol" var/protocol_class = NONE diff --git a/code/modules/research/nanites/nanite_programs/protocols.dm b/code/modules/research/nanites/nanite_programs/protocols.dm index 73976abe09..3830e7c8ba 100644 --- a/code/modules/research/nanites/nanite_programs/protocols.dm +++ b/code/modules/research/nanites/nanite_programs/protocols.dm @@ -105,3 +105,14 @@ /datum/nanite_program/protocol/offline/active_effect() nanites.adjust_nanites(null, boost) + +/datum/nanite_program/protocol/synergy + name = "Synergy Protocol" + desc = "Replication Protocol: the nanites syncronize their tasks and processes within a host, leading to an increase in replication speed proportional to the current nanite volume." + use_rate = 0 + rogue_types = list(/datum/nanite_program/necrotic) + protocol_class = NANITE_PROTOCOL_REPLICATION + var/max_boost = 2 //The maximum boost this program applies to the nanite replication, multiplied with the current nanite 'saturation' percentage + +/datum/nanite_program/protocol/synergy/active_effect() + nanites.adjust_nanites(null, round(max_boost * (nanites.nanite_volume / nanites.max_nanites), 0.1)) diff --git a/code/modules/research/techweb/all_nodes.dm b/code/modules/research/techweb/all_nodes.dm index 24b9ccf81c..002bb3d64b 100644 --- a/code/modules/research/techweb/all_nodes.dm +++ b/code/modules/research/techweb/all_nodes.dm @@ -957,6 +957,14 @@ design_ids = list("spreading_nanites","mindcontrol_nanites","mitosis_nanites") research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 10000) +/datum/techweb_node/nanite_replication_protocols + id = "nanite_replication_protocols" + display_name = "Nanite Replication Protocols" + description = "Advanced behaviours that allow nanites to exploit certain circumstances to replicate faster." + prereq_ids = list("nanite_smart") + design_ids = list("kickstart_nanites","factory_nanites","tinker_nanites","offline_nanites","synergy_nanites") + research_costs = list(TECHWEB_POINT_TYPE_GENERIC = 5000) + ////////////////////////Alien technology//////////////////////// /datum/techweb_node/alientech //AYYYYYYYYLMAOO tech id = "alientech" diff --git a/tgstation.dme b/tgstation.dme index 7bfbd2dde2..39b963c432 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -2965,6 +2965,7 @@ #include "code\modules\research\nanites\extra_settings\type.dm" #include "code\modules\research\nanites\nanite_programs\buffing.dm" #include "code\modules\research\nanites\nanite_programs\healing.dm" +#include "code\modules\research\nanites\nanite_programs\protocols.dm" #include "code\modules\research\nanites\nanite_programs\rogue.dm" #include "code\modules\research\nanites\nanite_programs\sensor.dm" #include "code\modules\research\nanites\nanite_programs\suppression.dm" From 0beb28d3bb8ada2746917acfbfad8cd48aae66fa Mon Sep 17 00:00:00 2001 From: Ghommie <42542238+Ghommie@users.noreply.github.com> Date: Thu, 23 Apr 2020 19:52:22 +0200 Subject: [PATCH 36/55] reagents value nerf and standardization. --- code/__DEFINES/reagents.dm | 14 +- code/modules/reagents/chemistry/reagents.dm | 2 +- .../chemistry/reagents/alcohol_reagents.dm | 168 ++++-------------- .../chemistry/reagents/drink_reagents.dm | 29 ++- .../chemistry/reagents/drug_reagents.dm | 44 ++++- .../chemistry/reagents/food_reagents.dm | 47 +++-- .../chemistry/reagents/medicine_reagents.dm | 43 ++++- .../chemistry/reagents/other_reagents.dm | 40 ++++- .../reagents/pyrotechnic_reagents.dm | 21 ++- .../chemistry/reagents/toxin_reagents.dm | 44 +++++ .../code/datums/status_effects/chems.dm | 2 +- .../reagents/chemistry/reagents/MKUltra.dm | 15 +- .../reagents/chemistry/reagents/SDGF.dm | 2 + .../reagents/chemistry/reagents/astrogen.dm | 1 + .../chemistry/reagents/eigentstasium.dm | 1 + .../chemistry/reagents/enlargement.dm | 4 + .../reagents/chemistry/reagents/healing.dm | 2 + .../chemistry/reagents/other_reagents.dm | 32 ---- tgstation.dme | 1 - 19 files changed, 294 insertions(+), 218 deletions(-) delete mode 100644 modular_citadel/code/modules/reagents/chemistry/reagents/other_reagents.dm diff --git a/code/__DEFINES/reagents.dm b/code/__DEFINES/reagents.dm index 97ae7b8e95..f4beef7ee8 100644 --- a/code/__DEFINES/reagents.dm +++ b/code/__DEFINES/reagents.dm @@ -22,11 +22,23 @@ // Is an open container for all intents and purposes. #define OPENCONTAINER (REFILLABLE | DRAINABLE | TRANSPARENT) -//reagents_value defines, for cargo stuff. +//reagents_value defines, basically a multiplier used in reagent containers cargo selling. #define DEFAULT_REAGENTS_VALUE 1 #define NO_REAGENTS_VALUE 0 #define HARVEST_REAGENTS_VALUE 0.3 +/// Standard reagents value defines. +/// Take a grain of salt, only "rare" reagents should have a decent value here, for balance reasons. +/// TL;DR Think of it also like general market request price more than rarity. +#define REAGENT_VALUE_NONE 0 //all the stuff pretty much available in potentially unlimited quantities. +#define REAGENT_VALUE_VERY_COMMON 0.1 //same as above, just not so unlimited. +#define REAGENT_VALUE_COMMON 0.5 +#define REAGENT_VALUE_UNCOMMON 1 +#define REAGENT_VALUE_RARE 2.5 +#define REAGENT_VALUE_VERY_RARE 5 +#define REAGENT_VALUE_EXCEPTIONAL 10 //extremely rare or tedious to craft, possibly unsynthetizable, reagents. +#define REAGENT_VALUE_AMAZING 30 //reserved ONLY for non-mass produceable, unsynthetizable reagents. +#define REAGENT_VALUE_GLORIOUS 300 //reagents that shouldn't be possible to get or farm under normal conditions. e.g. Romerol, fungal TB, adminordrazine... #define TOUCH 1 // splashing #define INGEST 2 // ingestion diff --git a/code/modules/reagents/chemistry/reagents.dm b/code/modules/reagents/chemistry/reagents.dm index 725b967a63..a85ac8b085 100644 --- a/code/modules/reagents/chemistry/reagents.dm +++ b/code/modules/reagents/chemistry/reagents.dm @@ -51,7 +51,7 @@ GLOBAL_LIST_INIT(name2reagent, build_name2reagent()) var/inverse_chem // What chem is metabolised when purity is below inverse_chem_val, this shouldn't be made, but if it does, well, I guess I'll know about it. var/metabolizing = FALSE var/chemical_flags // See fermi/readme.dm REAGENT_DEAD_PROCESS, REAGENT_DONOTSPLIT, REAGENT_ONLYINVERSE, REAGENT_ONMOBMERGE, REAGENT_INVISIBLE, REAGENT_FORCEONNEW, REAGENT_SNEAKYNAME - var/value = 0 //How much does it sell for in cargo? + var/value = REAGENT_VALUE_NONE //How much does it sell for in cargo? /datum/reagent/Destroy() // This should only be called by the holder, so it's already handled clearing its references . = ..() diff --git a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm index 8194392871..464557f617 100644 --- a/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/alcohol_reagents.dm @@ -14,6 +14,7 @@ taste_description = "alcohol" var/boozepwr = 65 //Higher numbers equal higher hardness, higher hardness equals more intense alcohol poisoning pH = 7.33 + value = REAGENT_VALUE_VERY_COMMON //don't bother tweaking all drinks values, way too many can easily be done roundstart or with an upgraded dispenser. /* Boozepwr Chart @@ -88,7 +89,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_name = "glass of beer" glass_desc = "A freezing pint of beer." pH = 4 - value = 0.1 /datum/reagent/consumable/ethanol/beer/light name = "Light Beer" @@ -98,7 +98,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_name = "glass of light beer" glass_desc = "A freezing pint of watery light beer." pH = 5 - value = 0.3 /datum/reagent/consumable/ethanol/beer/green name = "Green Beer" @@ -109,7 +108,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_name = "glass of green beer" glass_desc = "A freezing pint of green beer. Festive." pH = 6 - value = 0.3 /datum/reagent/consumable/ethanol/beer/green/on_mob_life(mob/living/carbon/M) if(M.color != color) @@ -129,7 +127,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_desc = "DAMN, THIS THING LOOKS ROBUST!" shot_glass_icon_state = "shotglasscream" pH = 6 - value = 0.1 /datum/reagent/consumable/ethanol/kahlua/on_mob_life(mob/living/carbon/M) @@ -152,7 +149,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_desc = "The silky, smokey whiskey goodness inside the glass makes the drink look very classy." shot_glass_icon_state = "shotglassbrown" pH = 4.5 - value = 0.1 /datum/reagent/consumable/ethanol/thirteenloko name = "Thirteen Loko" @@ -167,7 +163,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "thirteen_loko_glass" glass_name = "glass of Thirteen Loko" glass_desc = "This is a glass of Thirteen Loko, it appears to be of the highest quality. The drink, not the glass." - value = 0.3 /datum/reagent/consumable/ethanol/thirteenloko/on_mob_life(mob/living/carbon/M) M.drowsyness = max(0,M.drowsyness-7) @@ -229,7 +224,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_desc = "The glass contain wodka. Xynta." shot_glass_icon_state = "shotglassclear" pH = 8.1 - value = 0.1 /datum/reagent/consumable/ethanol/vodka/on_mob_life(mob/living/carbon/M) M.radiation = max(M.radiation-2,0) @@ -245,7 +239,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "glass_brown" glass_name = "glass of bilk" glass_desc = "A brew of milk and beer. For those alcoholics who fear osteoporosis." - value = 0.5 /datum/reagent/consumable/ethanol/bilk/on_mob_life(mob/living/carbon/M) if(M.getBruteLoss() && prob(10)) @@ -264,7 +257,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_name = "Three Mile Island Ice Tea" glass_desc = "A glass of this is sure to prevent a meltdown." pH = 3.5 - value = 1 + value = REAGENT_VALUE_RARE /datum/reagent/consumable/ethanol/threemileisland/on_mob_life(mob/living/carbon/M) M.set_drugginess(50) @@ -280,7 +273,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_name = "glass of gin" glass_desc = "A crystal clear glass of Griffeater gin." pH = 6.9 - value = 0.1 /datum/reagent/consumable/ethanol/rum name = "Rum" @@ -293,7 +285,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_desc = "Now you want to Pray for a pirate suit, don't you?" shot_glass_icon_state = "shotglassbrown" pH = 6.5 - value = 0.1 /datum/reagent/consumable/ethanol/tequila name = "Tequila" @@ -306,7 +297,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_desc = "Now all that's missing is the weird colored shades!" shot_glass_icon_state = "shotglassgold" pH = 4 - value = 0.1 /datum/reagent/consumable/ethanol/vermouth name = "Vermouth" @@ -319,7 +309,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_desc = "You wonder why you're even drinking this straight." shot_glass_icon_state = "shotglassclear" pH = 3.25 - value = 0.1 /datum/reagent/consumable/ethanol/wine name = "Wine" @@ -332,7 +321,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_desc = "A very classy looking drink." shot_glass_icon_state = "shotglassred" pH = 3.45 - value = 0.1 /datum/reagent/consumable/ethanol/lizardwine name = "Lizard wine" @@ -342,7 +330,7 @@ All effects don't start immediately, but rather get worse over time; the rate is quality = DRINK_FANTASTIC taste_description = "scaley sweetness" pH = 3 - value = 2 + value = REAGENT_VALUE_VERY_RARE /datum/reagent/consumable/ethanol/grappa name = "Grappa" @@ -354,7 +342,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_name = "glass of grappa" glass_desc = "A fine drink originally made to prevent waste by using the leftovers from winemaking." pH = 3.5 - value = 0.1 /datum/reagent/consumable/ethanol/cognac name = "Cognac" @@ -367,7 +354,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_desc = "Damn, you feel like some kind of French aristocrat just by holding this." shot_glass_icon_state = "shotglassbrown" pH = 3.5 - value = 0.1 /datum/reagent/consumable/ethanol/absinthe name = "Absinthe" @@ -379,7 +365,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_name = "glass of absinthe" glass_desc = "It's as strong as it smells." shot_glass_icon_state = "shotglassgreen" - value = 0.1 /datum/reagent/consumable/ethanol/absinthe/on_mob_life(mob/living/carbon/M) if(prob(10) && !HAS_TRAIT(M, TRAIT_ALCOHOL_TOLERANCE)) @@ -395,6 +380,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "glass_brown2" glass_name = "Hooch" glass_desc = "You've really hit rock bottom now... your liver packed its bags and left last night." + value = REAGENT_VALUE_COMMON /datum/reagent/consumable/ethanol/hooch/on_mob_life(mob/living/carbon/M) if(M.mind && M.mind.assigned_role == "Assistant") @@ -412,7 +398,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_name = "glass of ale" glass_desc = "A freezing pint of delicious Ale." pH = 4.5 - value = 0.1 /datum/reagent/consumable/ethanol/goldschlager name = "Goldschlager" @@ -425,7 +410,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_name = "glass of goldschlager" glass_desc = "100% proof that teen girls will drink anything with gold in it." shot_glass_icon_state = "shotglassgold" - value = 0.5 + value = REAGENT_VALUE_COMMON /datum/reagent/consumable/ethanol/patron name = "Patron" @@ -439,7 +424,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_desc = "Drinking patron in the bar, with all the subpar ladies." shot_glass_icon_state = "shotglassclear" pH = 4.5 - value = 0.1 + value = REAGENT_VALUE_COMMON /datum/reagent/consumable/ethanol/gintonic name = "Gin and Tonic" @@ -452,7 +437,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_name = "Gin and Tonic" glass_desc = "A mild but still great cocktail. Drink up, like a true Englishman." pH = 3 - value = 0.5 /datum/reagent/consumable/ethanol/rum_coke name = "Rum and Coke" @@ -465,7 +449,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_name = "Rum and Coke" glass_desc = "The classic go-to of space-fratboys." pH = 4 - value = 1 /datum/reagent/consumable/ethanol/cuba_libre name = "Cuba Libre" @@ -477,8 +460,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "cubalibreglass" glass_name = "Cuba Libre" glass_desc = "A classic mix of rum, cola, and lime. A favorite of revolutionaries everywhere!" - value = 0.5 - /datum/reagent/consumable/ethanol/cuba_libre/on_mob_life(mob/living/carbon/M) if(M.mind && M.mind.has_antag_datum(/datum/antagonist/rev)) //Cuba Libre, the traditional drink of revolutions! Heals revolutionaries. @@ -499,7 +480,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "whiskeycolaglass" glass_name = "whiskey cola" glass_desc = "An innocent-looking mixture of cola and Whiskey. Delicious." - value = 0.5 /datum/reagent/consumable/ethanol/martini name = "Classic Martini" @@ -511,7 +491,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "martiniglass" glass_name = "Classic Martini" glass_desc = "Damn, the bartender even stirred it, not shook it." - value = 1 /datum/reagent/consumable/ethanol/vodkamartini name = "Vodka Martini" @@ -523,7 +502,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "martiniglass" glass_name = "Vodka martini" glass_desc ="A bastardisation of the classic martini. Still great." - value = 1 /datum/reagent/consumable/ethanol/white_russian @@ -536,7 +514,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "whiterussianglass" glass_name = "White Russian" glass_desc = "A very nice looking drink. But that's just, like, your opinion, man." - value = 1 /datum/reagent/consumable/ethanol/screwdrivercocktail name = "Screwdriver" @@ -548,7 +525,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "screwdriverglass" glass_name = "Screwdriver" glass_desc = "A simple, yet superb mixture of Vodka and orange juice. Just the thing for the tired engineer." - value = 1 /datum/reagent/consumable/ethanol/screwdrivercocktail/on_mob_life(mob/living/carbon/M) if(M.mind && (M.mind.assigned_role in list("Station Engineer", "Atmospheric Technician", "Chief Engineer"))) //Engineers lose radiation poisoning at a massive rate. @@ -564,7 +540,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "booger" glass_name = "Booger" glass_desc = "Ewww..." - value = 0.3 + value = REAGENT_VALUE_COMMON /datum/reagent/consumable/ethanol/bloody_mary name = "Bloody Mary" @@ -576,7 +552,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "bloodymaryglass" glass_name = "Bloody Mary" glass_desc = "Tomato juice, mixed with Vodka and a lil' bit of lime. Tastes like liquid murder." - value = 1.3 /datum/reagent/consumable/ethanol/bloody_mary/on_mob_life(mob/living/carbon/C) if(AmBloodsucker(C)) @@ -595,7 +570,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "bravebullglass" glass_name = "Brave Bull" glass_desc = "Tequila and Coffee liqueur, brought together in a mouthwatering mixture. Drink up." - value = 2 var/tough_text /datum/reagent/consumable/ethanol/brave_bull/on_mob_metabolize(mob/living/M) @@ -619,7 +593,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "tequilasunriseglass" glass_name = "tequila Sunrise" glass_desc = "Oh great, now you feel nostalgic about sunrises back on Terra..." - value = 2 var/obj/effect/light_holder /datum/reagent/consumable/ethanol/tequila_sunrise/on_mob_metabolize(mob/living/M) @@ -649,7 +622,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_name = "Toxins Special" glass_desc = "Whoah, this thing is on FIRE!" shot_glass_icon_state = "toxinsspecialglass" - value = 2 + value = REAGENT_VALUE_COMMON /datum/reagent/consumable/ethanol/toxins_special/on_mob_life(var/mob/living/M) M.adjust_bodytemperature(15 * TEMPERATURE_DAMAGE_COEFFICIENT, 0, BODYTEMP_NORMAL + 20) //310.15 is the normal bodytemp. @@ -668,7 +641,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_desc = "Heavy, hot and strong. Just like the Iron fist of the LAW." pH = 2 overdose_threshold = 40 - value = 3 var/datum/brain_trauma/special/beepsky/B /datum/reagent/consumable/ethanol/beepsky_smash/on_mob_metabolize(mob/living/carbon/M) @@ -709,7 +681,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "irishcreamglass" glass_name = "Irish Cream" glass_desc = "It's cream, mixed with whiskey. What else would you expect from the Irish?" - value = 1 /datum/reagent/consumable/ethanol/manly_dorf name = "The Manly Dorf" @@ -721,7 +692,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "manlydorfglass" glass_name = "The Manly Dorf" glass_desc = "A manly concoction made from Ale and Beer. Intended for true men only." - value = 2 var/dorf_mode /datum/reagent/consumable/ethanol/manly_dorf/on_mob_metabolize(mob/living/M) @@ -752,7 +722,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "longislandicedteaglass" glass_name = "Long Island Iced Tea" glass_desc = "The liquor cabinet, brought together in a delicious mix. Intended for middle-aged alcoholic women only." - value = 1 /datum/reagent/consumable/ethanol/moonshine name = "Moonshine" @@ -763,7 +732,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "glass_clear" glass_name = "Moonshine" glass_desc = "You've really hit rock bottom now... your liver packed its bags and left last night." - value = 2 + value = REAGENT_VALUE_COMMON /datum/reagent/consumable/ethanol/b52 name = "B-52" @@ -776,7 +745,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_name = "B-52" glass_desc = "Kahlua, Irish Cream, and cognac. You will get bombed." shot_glass_icon_state = "b52glass" - value = 5.2 /datum/reagent/consumable/ethanol/b52/on_mob_metabolize(mob/living/M) playsound(M, 'sound/effects/explosion_distant.ogg', 100, FALSE) @@ -791,7 +759,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "irishcoffeeglass" glass_name = "Irish Coffee" glass_desc = "Coffee and alcohol. More fun than a Mimosa to drink in the morning." - value = 2 /datum/reagent/consumable/ethanol/margarita name = "Margarita" @@ -803,7 +770,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "margaritaglass" glass_name = "Margarita" glass_desc = "On the rocks with salt on the rim. Arriba~!" - value = 2 /datum/reagent/consumable/ethanol/black_russian name = "Black Russian" @@ -815,7 +781,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "blackrussianglass" glass_name = "Black Russian" glass_desc = "For the lactose-intolerant. Still as classy as a White Russian." - value = 3 /datum/reagent/consumable/ethanol/manhattan @@ -828,7 +793,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "manhattanglass" glass_name = "Manhattan" glass_desc = "The Detective's undercover drink of choice. He never could stomach gin..." - value = 3 /datum/reagent/consumable/ethanol/manhattan_proj @@ -841,7 +805,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "proj_manhattanglass" glass_name = "Manhattan Project" glass_desc = "A scientist's drink of choice, for thinking how to blow up the station." - value = 6 + value = REAGENT_VALUE_RARE /datum/reagent/consumable/ethanol/manhattan_proj/on_mob_life(mob/living/carbon/M) @@ -858,7 +822,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "whiskeysodaglass2" glass_name = "whiskey soda" glass_desc = "Ultimate refreshment." - value = 1 /datum/reagent/consumable/ethanol/antifreeze name = "Anti-freeze" @@ -870,7 +833,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "antifreeze" glass_name = "Anti-freeze" glass_desc = "The ultimate refreshment." - value = 3 /datum/reagent/consumable/ethanol/antifreeze/on_mob_life(mob/living/carbon/M) M.adjust_bodytemperature(20 * TEMPERATURE_DAMAGE_COEFFICIENT, 0, BODYTEMP_NORMAL + 20) //310.15 is the normal bodytemp. @@ -886,7 +848,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "b&p" glass_name = "Barefoot" glass_desc = "Barefoot and pregnant." - value = 4 /datum/reagent/consumable/ethanol/barefoot/on_mob_life(mob/living/carbon/M) if(ishuman(M)) //Barefoot causes the imbiber to quickly regenerate brute trauma if they're not wearing shoes. @@ -906,7 +867,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "snowwhite" glass_name = "Snow White" glass_desc = "A cold refreshment." - value = 1 /datum/reagent/consumable/ethanol/demonsblood //Prevents the imbiber from being dragged into a pool of blood by a slaughter demon. name = "Demon's Blood" @@ -918,7 +878,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "demonsblood" glass_name = "Demons Blood" glass_desc = "Just looking at this thing makes the hair at the back of your neck stand up." - value = 2 /datum/reagent/consumable/ethanol/devilskiss //If eaten by a slaughter demon, the demon will regret it. name = "Devil's Kiss" @@ -930,7 +889,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "devilskiss" glass_name = "Devils Kiss" glass_desc = "Creepy time!" - value = 2 /datum/reagent/consumable/ethanol/vodkatonic name = "Vodka and Tonic" @@ -942,7 +900,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "vodkatonicglass" glass_name = "vodka and tonic" glass_desc = "For when a gin and tonic isn't Russian enough." - value = 1 /datum/reagent/consumable/ethanol/ginfizz name = "Gin Fizz" @@ -954,7 +911,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "ginfizzglass" glass_name = "gin fizz" glass_desc = "Refreshingly lemony, deliciously dry." - value = 1 /datum/reagent/consumable/ethanol/bahama_mama name = "Bahama Mama" @@ -966,7 +922,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "bahama_mama" glass_name = "Bahama Mama" glass_desc = "A tropical cocktail with a complex blend of flavors." - value = 2 /datum/reagent/consumable/ethanol/singulo name = "Singulo" @@ -978,7 +933,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "singulo" glass_name = "Singulo" glass_desc = "A blue-space beverage." - value = 4 /datum/reagent/consumable/ethanol/sbiten name = "Sbiten" @@ -990,7 +944,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "sbitenglass" glass_name = "Sbiten" glass_desc = "A spicy mix of Vodka and Spice. Very hot." - value = 2 /datum/reagent/consumable/ethanol/sbiten/on_mob_life(mob/living/carbon/M) M.adjust_bodytemperature(50 * TEMPERATURE_DAMAGE_COEFFICIENT, 0 ,BODYTEMP_HEAT_DAMAGE_LIMIT) //310.15 is the normal bodytemp. @@ -1006,7 +959,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "red_meadglass" glass_name = "Red Mead" glass_desc = "A True Viking's Beverage, though its color is strange." - value = 5 + value = REAGENT_VALUE_COMMON /datum/reagent/consumable/ethanol/mead name = "Mead" @@ -1019,7 +972,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "meadglass" glass_name = "Mead" glass_desc = "A Viking's Beverage, though a cheap one." - value = 1 /datum/reagent/consumable/ethanol/iced_beer name = "Iced Beer" @@ -1030,7 +982,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "iced_beerglass" glass_name = "iced beer" glass_desc = "A beer so frosty, the air around it freezes." - value = 1 /datum/reagent/consumable/ethanol/iced_beer/on_mob_life(mob/living/carbon/M) M.adjust_bodytemperature(-20 * TEMPERATURE_DAMAGE_COEFFICIENT, T0C) //310.15 is the normal bodytemp. @@ -1045,7 +996,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "grogglass" glass_name = "Grog" glass_desc = "A fine and cepa drink for Space." - value = 2.1 /datum/reagent/consumable/ethanol/aloe name = "Aloe" @@ -1057,7 +1007,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "aloe" glass_name = "Aloe" glass_desc = "Very, very, very good." - value = 1 + value = REAGENT_VALUE_COMMON /datum/reagent/consumable/ethanol/andalusia name = "Andalusia" @@ -1069,7 +1019,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "andalusia" glass_name = "Andalusia" glass_desc = "A nice, strangely named drink." - value = 1 /datum/reagent/consumable/ethanol/alliescocktail name = "Allies Cocktail" @@ -1081,7 +1030,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "alliescocktail" glass_name = "Allies cocktail" glass_desc = "A drink made from your allies." - value = 4 /datum/reagent/consumable/ethanol/acid_spit name = "Acid Spit" @@ -1093,7 +1041,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "acidspitglass" glass_name = "Acid Spit" glass_desc = "A drink from Nanotrasen. Made from live aliens." - value = 3 /datum/reagent/consumable/ethanol/amasec name = "Amasec" @@ -1105,7 +1052,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "amasecglass" glass_name = "Amasec" glass_desc = "Always handy before COMBAT!!!" - value = 2 /datum/reagent/consumable/ethanol/changelingsting name = "Changeling Sting" @@ -1117,7 +1063,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "changelingsting" glass_name = "Changeling Sting" glass_desc = "A stingy drink." - value = 1.5 /datum/reagent/consumable/ethanol/changelingsting/on_mob_life(mob/living/carbon/M) if(M.mind) //Changeling Sting assists in the recharging of changeling chemicals. @@ -1137,7 +1082,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "irishcarbomb" glass_name = "Irish Car Bomb" glass_desc = "An Irish car bomb." - value = 5 /datum/reagent/consumable/ethanol/syndicatebomb name = "Syndicate Bomb" @@ -1149,7 +1093,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "syndicatebomb" glass_name = "Syndicate Bomb" glass_desc = "A syndicate bomb." - value = 2 /datum/reagent/consumable/ethanol/syndicatebomb/on_mob_life(mob/living/carbon/M) if(prob(5)) @@ -1177,7 +1120,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "erikasurprise" glass_name = "Erika Surprise" glass_desc = "The surprise is, it's green!" - value = 4 /datum/reagent/consumable/ethanol/driestmartini name = "Driest Martini" @@ -1190,7 +1132,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "driestmartiniglass" glass_name = "Driest Martini" glass_desc = "Only for the experienced. You think you see sand floating in the glass." - value = 5 /datum/reagent/consumable/ethanol/bananahonk name = "Banana Honk" @@ -1203,7 +1144,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "bananahonkglass" glass_name = "Banana Honk" glass_desc = "A drink from Clown Heaven." - value = 8 /datum/reagent/consumable/ethanol/bananahonk/on_mob_life(mob/living/carbon/M) if((ishuman(M) && M.job == "Clown") || ismonkey(M)) @@ -1222,7 +1162,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "silencerglass" glass_name = "Silencer" glass_desc = "A drink from Mime Heaven." - value = 2 /datum/reagent/consumable/ethanol/silencer/on_mob_life(mob/living/carbon/M) if(ishuman(M) && M.job == "Mime") @@ -1240,7 +1179,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "drunkenblumpkin" glass_name = "Drunken Blumpkin" glass_desc = "A drink for the drunks." - value = 3 + value = REAGENT_VALUE_COMMON /datum/reagent/consumable/ethanol/whiskey_sour //Requested since we had whiskey cola and soda but not sour. name = "Whiskey Sour" @@ -1252,7 +1191,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "whiskey_sour" glass_name = "whiskey sour" glass_desc = "Lemon juice mixed with whiskey and a dash of sugar. Surprisingly satisfying." - value = 2 /datum/reagent/consumable/ethanol/hcider name = "Hard Cider" @@ -1265,7 +1203,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_name = "hard cider" glass_desc = "Tastes like autumn... no wait, fall!" shot_glass_icon_state = "shotglassbrown" - value = 3 /datum/reagent/consumable/ethanol/fetching_fizz //A reference to one of my favorite games of all time. Pulls nearby ores to the imbiber! name = "Fetching Fizz" @@ -1278,7 +1215,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "fetching_fizz" glass_name = "Fetching Fizz" glass_desc = "Induces magnetism in the imbiber. Started as a barroom prank but evolved to become popular with miners and scrappers. Metallic aftertaste." - value = 2 + value = REAGENT_VALUE_UNCOMMON /datum/reagent/consumable/ethanol/fetching_fizz/on_mob_life(mob/living/carbon/M) for(var/obj/item/stack/ore/O in orange(3, M)) @@ -1297,7 +1234,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "hearty_punch" glass_name = "Hearty Punch" glass_desc = "Aromatic beverage served piping hot. According to folk tales it can almost wake the dead." - value = 1 + value = REAGENT_VALUE_RARE //considering the low recipe yield. /datum/reagent/consumable/ethanol/hearty_punch/on_mob_life(mob/living/carbon/M) if(M.health <= 0) @@ -1318,8 +1255,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "glass_brown2" glass_name = "Bacchus' Blessing" glass_desc = "You didn't think it was possible for a liquid to be so utterly revolting. Are you sure about this...?" - value = 8 - + value = REAGENT_VALUE_RARE /datum/reagent/consumable/ethanol/atomicbomb name = "Atomic Bomb" @@ -1331,7 +1267,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "atomicbombglass" glass_name = "Atomic Bomb" glass_desc = "Nanotrasen cannot take legal responsibility for your actions after imbibing." - value = 3.56 + value = REAGENT_VALUE_RARE /datum/reagent/consumable/ethanol/atomicbomb/on_mob_life(mob/living/carbon/M) M.set_drugginess(50) @@ -1360,7 +1296,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "gargleblasterglass" glass_name = "Pan-Galactic Gargle Blaster" glass_desc = "Like having your brain smashed out by a slice of lemon wrapped around a large gold brick." - value = 5 /datum/reagent/consumable/ethanol/gargle_blaster/on_mob_life(mob/living/carbon/M) M.dizziness +=1.5 @@ -1393,7 +1328,7 @@ All effects don't start immediately, but rather get worse over time; the rate is impure_chem = /datum/reagent/consumable/ethanol/neuroweak inverse_chem_val = 0.5 //Clear conversion inverse_chem = /datum/reagent/consumable/ethanol/neuroweak - value = 4 + value = REAGENT_VALUE_UNCOMMON /datum/reagent/consumable/ethanol/neurotoxin/proc/pickt() return (pick(TRAIT_PARALYSIS_L_ARM,TRAIT_PARALYSIS_R_ARM,TRAIT_PARALYSIS_R_LEG,TRAIT_PARALYSIS_L_LEG)) @@ -1434,7 +1369,6 @@ All effects don't start immediately, but rather get worse over time; the rate is description = "A mostly safe alcoholic drink for the true daredevils. Counteracts Neurotoxins." boozepwr = 60 pH = 8 - value = 3 /datum/reagent/consumable/ethanol/neuroweak/on_mob_life(mob/living/carbon/M) if(holder.has_reagent(/datum/reagent/consumable/ethanol/neurotoxin)) @@ -1460,7 +1394,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "hippiesdelightglass" glass_name = "Hippie's Delight" glass_desc = "A drink enjoyed by people during the 1960's." - value = 1.96 + value = REAGENT_VALUE_RARE /datum/reagent/consumable/ethanol/hippies_delight/on_mob_life(mob/living/carbon/M) M.slurring = max(M.slurring,50) @@ -1504,8 +1438,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "nog3" glass_name = "eggnog" glass_desc = "The traditional way to get absolutely hammered at a Christmas party." - value = 4 - /datum/reagent/consumable/ethanol/narsour name = "Nar'Sour" @@ -1517,7 +1449,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "narsour" glass_name = "Nar'Sour" glass_desc = "A new hit cocktail inspired by THE ARM Breweries will have you shouting Fuu ma'jin in no time!" - value = 6.66 + value = REAGENT_VALUE_UNCOMMON /datum/reagent/consumable/ethanol/narsour/on_mob_life(mob/living/carbon/M) M.cultslurring = min(M.cultslurring + 3, 3) @@ -1534,7 +1466,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "cogchamp" glass_name = "CogChamp" glass_desc = "Not even Ratvar's Four Generals could withstand this! Qevax Jryy!" - value = 8.13 + value = REAGENT_VALUE_UNCOMMON /datum/reagent/consumable/ethanol/cogchamp/on_mob_life(mob/living/carbon/M) M.clockcultslurring = min(M.clockcultslurring + 3, 3) @@ -1550,7 +1482,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "glass_orange" glass_name = "Triple Sec" glass_desc = "A glass of straight Triple Sec." - value = 1.5 /datum/reagent/consumable/ethanol/creme_de_menthe name = "Creme de Menthe" @@ -1561,7 +1492,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "glass_green" glass_name = "Creme de Menthe" glass_desc = "You can almost feel the first breath of spring just looking at it." - value = 2 /datum/reagent/consumable/ethanol/creme_de_cacao name = "Creme de Cacao" @@ -1572,7 +1502,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "glass_brown" glass_name = "Creme de Cacao" glass_desc = "A million hazing lawsuits and alcohol poisonings have started with this humble ingredient." - value = 1 /datum/reagent/consumable/ethanol/creme_de_coconut name = "Creme de Coconut" @@ -1594,7 +1523,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "quadruple_sec" glass_name = "Quadruple Sec" glass_desc = "An intimidating and lawful beverage dares you to violate the law and make its day. Still can't drink it on duty, though." - value = 3.04 /datum/reagent/consumable/ethanol/quadruple_sec/on_mob_life(mob/living/carbon/M) if(M.mind && HAS_TRAIT(M.mind, TRAIT_LAW_ENFORCEMENT_METABOLISM)) //Securidrink in line with the screwderiver for engineers or nothing for mimes. @@ -1613,7 +1541,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "quintuple_sec" glass_name = "Quintuple Sec" glass_desc = "Now you are become law, destroyer of clowns." - value = 4.01 + value = REAGENT_VALUE_EXCEPTIONAL /datum/reagent/consumable/ethanol/quintuple_sec/on_mob_life(mob/living/carbon/M) if(M.mind && HAS_TRAIT(M.mind, TRAIT_LAW_ENFORCEMENT_METABOLISM)) //Securidrink in line with the screwderiver for engineers or nothing for mimes but STRONG.. @@ -1657,7 +1585,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "grasshopper" glass_name = "Grasshopper" glass_desc = "You weren't aware edible beverages could be that green." - value = 1 /datum/reagent/consumable/ethanol/stinger name = "Stinger" @@ -1669,7 +1596,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "stinger" glass_name = "Stinger" glass_desc = "You wonder what would happen if you pointed this at a heat source..." - value = 1 /datum/reagent/consumable/ethanol/bastion_bourbon name = "Bastion Bourbon" @@ -1684,7 +1610,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_desc = "If you're feeling low, count on the buttery flavor of our own bastion bourbon." shot_glass_icon_state = "shotglassgreen" pH = 4 - value = 8 + value = REAGENT_VALUE_UNCOMMON /datum/reagent/consumable/ethanol/bastion_bourbon/on_mob_metabolize(mob/living/L) var/heal_points = 10 @@ -1721,7 +1647,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_name = "Squirt Cider" glass_desc = "Squirt cider will toughen you right up. Too bad about the musty aftertaste." shot_glass_icon_state = "shotglassgreen" - value = 1 /datum/reagent/consumable/ethanol/squirt_cider/on_mob_life(mob/living/carbon/M) M.satiety += 5 //for context, vitamins give 30 satiety per tick @@ -1738,7 +1663,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "fringe_weaver" glass_name = "Fringe Weaver" glass_desc = "It's a wonder it doesn't spill out of the glass." - value = 1 /datum/reagent/consumable/ethanol/sugar_rush name = "Sugar Rush" @@ -1751,7 +1675,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "sugar_rush" glass_name = "Sugar Rush" glass_desc = "If you can't mix a Sugar Rush, you can't tend bar." - value = 1 /datum/reagent/consumable/ethanol/sugar_rush/on_mob_life(mob/living/carbon/M) M.satiety -= 10 //junky as hell! a whole glass will keep you from being able to eat junk food @@ -1768,7 +1691,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "crevice_spike" glass_name = "Crevice Spike" glass_desc = "It'll either knock the drunkenness out of you or knock you out cold. Both, probably." - value = 1 + value = REAGENT_VALUE_COMMON /datum/reagent/consumable/ethanol/crevice_spike/on_mob_metabolize(mob/living/L) //damage only applies when drink first enters system and won't again until drink metabolizes out L.adjustBruteLoss(3 * min(5,volume)) //minimum 3 brute damage on ingestion to limit non-drink means of injury - a full 5 unit gulp of the drink trucks you for the full 15 @@ -1782,7 +1705,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "sakecup" glass_name = "cup of sake" glass_desc = "A traditional cup of sake." - value = 0.1 /datum/reagent/consumable/ethanol/peppermint_patty name = "Peppermint Patty" @@ -1794,7 +1716,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "peppermint_patty" glass_name = "Peppermint Patty" glass_desc = "A boozy minty hot cocoa that warms your belly on a cold night." - value = 2 /datum/reagent/consumable/ethanol/peppermint_patty/on_mob_life(mob/living/carbon/M) M.apply_status_effect(/datum/status_effect/throat_soothed) @@ -1812,7 +1733,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_name = "Alexander" glass_desc = "A creamy, indulgent delight that is stronger than it seems." var/obj/item/shield/mighty_shield - value = 1 /datum/reagent/consumable/ethanol/alexander/on_mob_metabolize(mob/living/L) if(ishuman(L)) @@ -1844,7 +1764,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "sidecar" glass_name = "Sidecar" glass_desc = "The one ride you'll gladly give up the wheel for." - value = 1 /datum/reagent/consumable/ethanol/between_the_sheets name = "Between the Sheets" @@ -1856,7 +1775,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "between_the_sheets" glass_name = "Between the Sheets" glass_desc = "The only drink that comes with a label reminding you of Nanotrasen's zero-tolerance promiscuity policy." - value = 2 /datum/reagent/consumable/ethanol/between_the_sheets/on_mob_life(mob/living/L) ..() @@ -1881,7 +1799,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "kamikaze" glass_name = "Kamikaze" glass_desc = "Divinely windy." - value = 1 /datum/reagent/consumable/ethanol/mojito name = "Mojito" @@ -1893,7 +1810,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "mojito" glass_name = "Mojito" glass_desc = "A drink that looks as refreshing as it tastes." - value = 1 /datum/reagent/consumable/ethanol/moscow_mule name = "Moscow Mule" @@ -1914,7 +1830,6 @@ All effects don't start immediately, but rather get worse over time; the rate is taste_description = "utter bitterness" glass_name = "glass of fernet" glass_desc = "A glass of pure Fernet. Only an absolute madman would drink this alone." - value = 0.1 /datum/reagent/consumable/ethanol/fernet/on_mob_life(mob/living/carbon/M) if(M.nutrition <= NUTRITION_LEVEL_STARVING) @@ -1933,7 +1848,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "godlyblend" glass_name = "glass of fernet cola" glass_desc = "A sawed-off cola bottle filled with Fernet Cola. Nothing better after eating like a lardass." - value = 1 /datum/reagent/consumable/ethanol/fernet_cola/on_mob_life(mob/living/carbon/M) if(M.nutrition <= NUTRITION_LEVEL_STARVING) @@ -1943,7 +1857,6 @@ All effects don't start immediately, but rather get worse over time; the rate is return ..() /datum/reagent/consumable/ethanol/fanciulli - name = "Fanciulli" description = "What if the Manhattan coctail ACTUALLY used a bitter herb liquour? Helps you sobers up." //also causes a bit of stamina damage to symbolize the afterdrink lazyness color = "#CA933F" // rgb: 202, 147, 63 @@ -1953,7 +1866,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "fanciulli" glass_name = "glass of fanciulli" glass_desc = "A glass of Fanciulli. It's just Manhattan with Fernet." - value = 1 /datum/reagent/consumable/ethanol/fanciulli/on_mob_life(mob/living/carbon/M) M.nutrition = max(M.nutrition - 5, 0) @@ -1966,7 +1878,6 @@ All effects don't start immediately, but rather get worse over time; the rate is . = TRUE ..() - /datum/reagent/consumable/ethanol/branca_menta name = "Branca Menta" description = "A refreshing mixture of bitter Fernet with mint creme liquour." @@ -1977,7 +1888,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state= "minted_fernet" glass_name = "glass of branca menta" glass_desc = "A glass of Branca Menta, perfect for those lazy and hot sunday summer afternoons." //Get lazy literally by drinking this - value = 1 /datum/reagent/consumable/ethanol/branca_menta/on_mob_life(mob/living/carbon/M) M.adjust_bodytemperature(-20 * TEMPERATURE_DAMAGE_COEFFICIENT, T0C) @@ -2000,7 +1910,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "blank_paper" glass_name = "glass of blank paper" glass_desc = "A fizzy cocktail for those looking to start fresh." - value = 1 + value = REAGENT_VALUE_UNCOMMON /datum/reagent/consumable/ethanol/blank_paper/on_mob_life(mob/living/carbon/M) if(ishuman(M) && M.job == "Mime") @@ -2017,7 +1927,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "champagne_glass" glass_name = "Champagne" glass_desc = "The flute clearly displays the slowly rising bubbles." - value = 1 + value = REAGENT_VALUE_COMMON /datum/reagent/consumable/ethanol/wizz_fizz name = "Wizz Fizz" @@ -2029,7 +1939,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "wizz_fizz" glass_name = "Wizz Fizz" glass_desc = "The glass bubbles and froths with an almost magical intensity." - value = 1 + value = REAGENT_VALUE_COMMON /datum/reagent/consumable/ethanol/wizz_fizz/on_mob_life(mob/living/carbon/M) //A healing drink similar to Quadruple Sec, Ling Stings, and Screwdrivers for the Wizznerds; the check is consistent with the changeling sting @@ -2049,7 +1959,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "bug_spray" glass_name = "Bug Spray" glass_desc = "Your eyes begin to water as the sting of alcohol reaches them." - value = 1 /datum/reagent/consumable/ethanol/bug_spray/on_mob_life(mob/living/carbon/M) //Bugs should not drink Bug spray. @@ -2071,7 +1980,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "applejack_glass" glass_name = "Applejack" glass_desc = "You feel like you could drink this all neight." - value = 0.1 /datum/reagent/consumable/ethanol/jack_rose name = "Jack Rose" @@ -2083,7 +1991,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "jack_rose" glass_name = "Jack Rose" glass_desc = "Enough of these, and you really will start to suppose your toeses are roses." - value = 1 /datum/reagent/consumable/ethanol/turbo name = "Turbo" @@ -2095,7 +2002,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "turbo" glass_name = "Turbo" glass_desc = "A turbulent cocktail for outlaw hoverbikers." - value = 0.3 + value = REAGENT_VALUE_RARE /datum/reagent/consumable/ethanol/turbo/on_mob_life(mob/living/carbon/M) if(prob(4)) @@ -2113,7 +2020,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "old_timer" glass_name = "Old Timer" glass_desc = "WARNING! May cause premature aging!" - value = 2 + value = REAGENT_VALUE_UNCOMMON //Parsnip juice? Really? lol /datum/reagent/consumable/ethanol/old_timer/on_mob_life(mob/living/carbon/M) if(prob(20)) @@ -2146,7 +2053,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "rubberneck" glass_name = "Rubberneck" glass_desc = "A popular drink amongst those adhering to an all synthetic diet." - value = 1 + value = REAGENT_VALUE_COMMON /datum/reagent/consumable/ethanol/duplex name = "Duplex" @@ -2158,7 +2065,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "duplex" glass_name = "Duplex" glass_desc = "To imbibe one component separately from the other is consider a great faux pas." - value = 1 /datum/reagent/consumable/ethanol/trappist name = "Trappist Beer" @@ -2170,7 +2076,6 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "trappistglass" glass_name = "Trappist Beer" glass_desc = "boozy Catholicism in a glass." - value = 1 /datum/reagent/consumable/ethanol/trappist/on_mob_life(mob/living/carbon/M) if(M.mind.isholy) @@ -2188,8 +2093,8 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "blazaamglass" glass_name = "Blazaam" glass_desc = "The glass seems to be sliding between realities. Doubles as a Berenstain remover." + value = REAGENT_VALUE_UNCOMMON var/stored_teleports = 0 - value = 4 /datum/reagent/consumable/ethanol/blazaam/on_mob_life(mob/living/carbon/M) if(M.drunkenness > 40) @@ -2211,7 +2116,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "planet_cracker" glass_name = "Planet Cracker" glass_desc = "Although historians believe the drink was originally created to commemorate the end of an important conflict in man's past, its origins have largely been forgotten and it is today seen more as a general symbol of human supremacy." - value = 1 + value = REAGENT_VALUE_VERY_RARE /datum/reagent/consumable/ethanol/mauna_loa name = "Mauna Loa" @@ -2223,6 +2128,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "mauna_loa" glass_name = "Mauna Loa" glass_desc = "Lavaland in a drink... mug... volcano... thing." + value = REAGENT_VALUE_COMMON /datum/reagent/consumable/ethanol/mauna_loa/on_mob_life(mob/living/carbon/M) // Heats the user up while the reagent is in the body. Occasionally makes you burst into flames. @@ -2236,13 +2142,14 @@ All effects don't start immediately, but rather get worse over time; the rate is name = "Commander and Chief" description = "A cocktail for the captain on the go." color = "#ffffc9" + can_synth = FALSE boozepwr = 50 quality = DRINK_FANTASTIC taste_description = "duty and responsibility" glass_icon_state = "commander_and_chief" glass_name = "Commander and Chief" glass_desc = "The gems of this majestic chalice represent the departments and their Heads." - value = 10 + value = REAGENT_VALUE_AMAZING /datum/reagent/consumable/ethanol/commander_and_chief/on_mob_life(mob/living/carbon/M) if(M.mind && HAS_TRAIT(M.mind, TRAIT_CAPTAIN_METABOLISM)) @@ -2281,6 +2188,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "hellfire" glass_name = "Hellfire" glass_desc = "An amber colored drink that isn't quite as hot as it looks." + value = REAGENT_VALUE_UNCOMMON /datum/reagent/consumable/ethanol/hellfire/on_mob_life(mob/living/carbon/M) M.adjust_bodytemperature(30 * TEMPERATURE_DAMAGE_COEFFICIENT, 0, BODYTEMP_NORMAL + 30) @@ -2296,6 +2204,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "sins_delight" glass_name = "Sin's Delight" glass_desc = "You can smell the seven sins rolling off the top of the glass." + value = REAGENT_VALUE_RARE /datum/reagent/consumable/ethanol/strawberry_daiquiri name = "Strawberry Daiquiri" @@ -2328,6 +2237,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "miami_vice" glass_name = "Miami Vice" glass_desc = "Strawberries and coconut, like yin and yang." + value = REAGENT_VALUE_UNCOMMON /datum/reagent/consumable/ethanol/malibu_sunset name = "Malibu Sunset" @@ -2350,6 +2260,7 @@ All effects don't start immediately, but rather get worse over time; the rate is glass_icon_state = "hotlime_miami" glass_name = "Hotlime Miami" glass_desc = "This looks very aesthetically pleasing." + value = REAGENT_VALUE_COMMON /datum/reagent/consumable/ethanol/hotlime_miami/on_mob_life(mob/living/carbon/M) M.set_drugginess(50) @@ -2580,7 +2491,6 @@ All effects don't start immediately, but rather get worse over time; the rate is var/list/names = list("null fruit" = 1) //Names of the fruits used. Associative list where name is key, value is the percentage of that fruit. var/list/tastes = list("bad coding" = 1) //List of tastes. See above. pH = 4 - value = 4 /datum/reagent/consumable/ethanol/fruit_wine/on_new(list/data) names = data["names"] diff --git a/code/modules/reagents/chemistry/reagents/drink_reagents.dm b/code/modules/reagents/chemistry/reagents/drink_reagents.dm index 85f474920b..62aea28009 100644 --- a/code/modules/reagents/chemistry/reagents/drink_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/drink_reagents.dm @@ -165,6 +165,7 @@ metabolization_rate = INFINITY color = "#FF4DD2" taste_description = "laughter" + value = REAGENT_VALUE_VERY_COMMON /datum/reagent/consumable/laughter/on_mob_life(mob/living/carbon/M) M.emote("laugh") @@ -177,6 +178,7 @@ metabolization_rate = 1.5 * REAGENTS_METABOLISM color = "#FF4DD2" taste_description = "laughter" + value = REAGENT_VALUE_RARE /datum/reagent/consumable/superlaughter/on_mob_life(mob/living/carbon/M) if(prob(30)) @@ -210,6 +212,7 @@ glass_name = "glass of milk" glass_desc = "White and nutritious goodness!" pH = 6.5 + value = REAGENT_VALUE_VERY_COMMON /datum/reagent/consumable/milk/on_mob_life(mob/living/carbon/M) if(HAS_TRAIT(M, TRAIT_CALCIUM_HEALER)) @@ -231,6 +234,7 @@ glass_icon_state = "glass_white" glass_name = "glass of soy milk" glass_desc = "White and nutritious soy goodness!" + value = REAGENT_VALUE_VERY_COMMON /datum/reagent/consumable/soymilk/on_mob_life(mob/living/carbon/M) if(M.getBruteLoss() && prob(20)) @@ -324,6 +328,7 @@ glass_icon_state = "lemonpitcher" glass_name = "pitcher of lemonade" glass_desc = "This drink leaves you feeling nostalgic for some reason." + value = REAGENT_VALUE_VERY_COMMON /datum/reagent/consumable/tea/arnold_palmer name = "Arnold Palmer" @@ -334,6 +339,7 @@ glass_icon_state = "arnold_palmer" glass_name = "Arnold Palmer" glass_desc = "You feel like taking a few golf swings after a few swigs of this." + value = REAGENT_VALUE_VERY_COMMON /datum/reagent/consumable/tea/arnold_palmer/on_mob_life(mob/living/carbon/M) if(prob(5)) @@ -404,6 +410,7 @@ glass_icon_state = "nuka_colaglass" glass_name = "glass of Nuka Cola" glass_desc = "Don't cry, Don't raise your eye, It's only nuclear wasteland." + value = REAGENT_VALUE_COMMON /datum/reagent/consumable/nuka_cola/on_mob_life(mob/living/carbon/M) M.Jitter(20) @@ -559,6 +566,7 @@ glass_icon_state = "grey_bull_glass" glass_name = "glass of Grey Bull" glass_desc = "Surprisingly it isnt grey." + value = REAGENT_VALUE_COMMON /datum/reagent/consumable/grey_bull/on_mob_metabolize(mob/living/L) ..() @@ -633,6 +641,7 @@ glass_icon_state = "soy_latte" glass_name = "soy latte" glass_desc = "A nice and refreshing beverage while you're reading." + value = REAGENT_VALUE_VERY_COMMON /datum/reagent/consumable/soy_latte/on_mob_life(mob/living/carbon/M) M.dizziness = max(0,M.dizziness-5) @@ -654,6 +663,7 @@ glass_icon_state = "cafe_latte" glass_name = "cafe latte" glass_desc = "A nice, strong and refreshing beverage while you're reading." + value = REAGENT_VALUE_VERY_COMMON /datum/reagent/consumable/cafe_latte/on_mob_life(mob/living/carbon/M) M.dizziness = max(0,M.dizziness-5) @@ -675,6 +685,7 @@ glass_icon_state = "doctorsdelightglass" glass_name = "Doctor's Delight" glass_desc = "The space doctor's favorite. Guaranteed to restore bodily injury; side effects include cravings and hunger." + value = REAGENT_VALUE_COMMON /datum/reagent/consumable/doctor_delight/on_mob_life(mob/living/carbon/M) M.adjustBruteLoss(-0.5, 0) @@ -697,6 +708,7 @@ glass_icon_state = "chocolatepudding" glass_name = "chocolate pudding" glass_desc = "Tasty." + value = REAGENT_VALUE_COMMON /datum/reagent/consumable/vanillapudding name = "Vanilla Pudding" @@ -708,6 +720,7 @@ glass_icon_state = "vanillapudding" glass_name = "vanilla pudding" glass_desc = "Tasty." + value = REAGENT_VALUE_UNCOMMON //real vanilla. /datum/reagent/consumable/cherryshake name = "Cherry Shake" @@ -719,6 +732,7 @@ glass_icon_state = "cherryshake" glass_name = "cherry shake" glass_desc = "A cherry flavored milkshake." + value = REAGENT_VALUE_COMMON /datum/reagent/consumable/bluecherryshake name = "Blue Cherry Shake" @@ -730,6 +744,7 @@ glass_icon_state = "bluecherryshake" glass_name = "blue cherry shake" glass_desc = "An exotic blue milkshake." + value = REAGENT_VALUE_UNCOMMON /datum/reagent/consumable/pumpkin_latte name = "Pumpkin Latte" @@ -741,6 +756,7 @@ glass_icon_state = "pumpkin_latte" glass_name = "pumpkin latte" glass_desc = "A mix of coffee and pumpkin juice." + value = REAGENT_VALUE_COMMON /datum/reagent/consumable/gibbfloats name = "Gibb Floats" @@ -752,6 +768,7 @@ glass_icon_state = "gibbfloats" glass_name = "Gibbfloat" glass_desc = "Dr. Gibb with ice cream on top." + value = REAGENT_VALUE_VERY_COMMON /datum/reagent/consumable/pumpkinjuice name = "Pumpkin Juice" @@ -764,6 +781,7 @@ description = "Juiced from real blumpkin." color = "#00BFFF" taste_description = "a mouthful of pool water" + value = REAGENT_VALUE_VERY_COMMON /datum/reagent/consumable/triple_citrus name = "Triple Citrus" @@ -793,6 +811,7 @@ color = "#7D4E29" quality = DRINK_NICE taste_description = "chocolate milk" + value = REAGENT_VALUE_VERY_COMMON /datum/reagent/consumable/menthol name = "Menthol" @@ -821,6 +840,7 @@ color = "#FFA500" taste_description = "parsnip" glass_name = "glass of parsnip juice" + value = REAGENT_VALUE_COMMON /datum/reagent/consumable/peachjuice //Intended to be extremely rare due to being the limiting ingredients in the blazaam drink name = "Peach Juice" @@ -846,6 +866,7 @@ glass_icon_state = "cream_soda" glass_name = "Cream Soda" glass_desc = "A classic space-American vanilla flavored soft drink." + value = REAGENT_VALUE_VERY_COMMON //just a little vanilla /datum/reagent/consumable/cream_soda/on_mob_life(mob/living/carbon/M) M.adjust_bodytemperature(-5 * TEMPERATURE_DAMAGE_COEFFICIENT, BODYTEMP_NORMAL) @@ -874,6 +895,7 @@ glass_icon_state = "red_queen" glass_name = "Red Queen" glass_desc = "DRINK ME." + value = REAGENT_VALUE_COMMON //growth serum. var/current_size = RESIZE_DEFAULT_SIZE /datum/reagent/consumable/red_queen/on_mob_life(mob/living/carbon/H) @@ -899,10 +921,11 @@ description = "A drink of a bygone era of milk and artificial sweetener back on a rock." color = "#f76aeb"//rgb(247, 106, 235) glass_icon_state = "pinkmilk" - quality = DRINK_FANTASTIC + quality = DRINK_VERYGOOD taste_description = "sweet strawberry and milk cream" glass_name = "tall glass of strawberry milk" glass_desc = "Delicious flavored strawberry syrup mixed with milk." + value = REAGENT_VALUE_VERY_COMMON /datum/reagent/consumable/tea/pinkmilk/on_mob_life(mob/living/carbon/M) if(prob(15)) @@ -915,7 +938,7 @@ description = "A timeless classic!" color = "#f76aeb"//rgb(247, 106, 235) glass_icon_state = "pinktea" - quality = DRINK_FANTASTIC + quality = DRINK_VERYGOOD taste_description = "sweet tea with a hint of strawberry" glass_name = "mug of strawberry tea" glass_desc = "Delicious traditional tea flavored with strawberries." @@ -958,6 +981,7 @@ glass_icon_state = "monkey_energy_glass" glass_name = "glass of Monkey Energy" glass_desc = "You can unleash the ape, but without the pop of the can?" + value = REAGENT_VALUE_COMMON /datum/reagent/consumable/monkey_energy/on_mob_life(mob/living/carbon/M) M.Jitter(20) @@ -975,3 +999,4 @@ glass_icon_state = "glass_yellow" glass_name = "glass of bungo juice" glass_desc = "Exotic! You feel like you are on vacation already." + value = REAGENT_VALUE_COMMON diff --git a/code/modules/reagents/chemistry/reagents/drug_reagents.dm b/code/modules/reagents/chemistry/reagents/drug_reagents.dm index 086515d9dd..0e95b1f1ba 100644 --- a/code/modules/reagents/chemistry/reagents/drug_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/drug_reagents.dm @@ -1,6 +1,5 @@ /datum/reagent/drug name = "Drug" - value = 12 metabolization_rate = 0.5 * REAGENTS_METABOLISM taste_description = "bitterness" var/trippy = TRUE //Does this drug make you trip? @@ -11,7 +10,7 @@ /datum/reagent/drug/space_drugs name = "Space drugs" - value = 6 + value = REAGENT_VALUE_VERY_COMMON description = "An illegal chemical compound used as drug." color = "#60A584" // rgb: 96, 165, 132 overdose_threshold = 30 @@ -38,7 +37,6 @@ /datum/reagent/drug/nicotine name = "Nicotine" - value = 0 description = "Slightly reduces stun times. If overdosed it will deal toxin and oxygen damage." reagent_state = LIQUID color = "#60A584" // rgb: 96, 165, 132 @@ -66,6 +64,7 @@ overdose_threshold = 20 addiction_threshold = 10 pH = 10 + value = REAGENT_VALUE_UNCOMMON /datum/reagent/drug/crank/on_mob_life(mob/living/carbon/M) if(prob(5)) @@ -112,6 +111,7 @@ overdose_threshold = 20 addiction_threshold = 15 pH = 9 + value = REAGENT_VALUE_UNCOMMON /datum/reagent/drug/krokodil/on_mob_life(mob/living/carbon/M) @@ -167,6 +167,7 @@ var/jitter = TRUE var/confusion = TRUE pH = 5 + value = REAGENT_VALUE_UNCOMMON /datum/reagent/drug/methamphetamine/on_mob_metabolize(mob/living/L) ..() @@ -250,6 +251,7 @@ overdose_threshold = 35 jitter = FALSE brain_damage = FALSE + value = REAGENT_VALUE_RARE /datum/reagent/drug/bath_salts name = "Bath Salts" @@ -261,6 +263,7 @@ taste_description = "salt" // because they're bathsalts? var/datum/brain_trauma/special/psychotic_brawling/bath_salts/rage pH = 8.2 + value = REAGENT_VALUE_RARE /datum/reagent/drug/bath_salts/on_mob_metabolize(mob/living/L) ..() @@ -357,6 +360,7 @@ reagent_state = LIQUID color = "#78FFF0" pH = 9.2 + value = REAGENT_VALUE_RARE /datum/reagent/drug/aranesp/on_mob_life(mob/living/carbon/M) var/high_message = pick("You feel amped up.", "You feel ready.", "You feel like you can push it to the limit.") @@ -378,6 +382,7 @@ addiction_threshold = 10 overdose_threshold = 20 pH = 10.5 + value = REAGENT_VALUE_RARE /datum/reagent/drug/happiness/on_mob_add(mob/living/L) ..() @@ -457,6 +462,7 @@ addiction_stage3_end = 40 addiction_stage4_end = 240 pH = 12.5 + value = REAGENT_VALUE_EXCEPTIONAL /datum/reagent/drug/skooma/on_mob_metabolize(mob/living/L) . = ..() @@ -521,3 +527,35 @@ if(prob(40)) M.emote(pick("twitch","drool","moan")) ..() + +/datum/reagent/syndicateadrenals + name = "Syndicate Adrenaline" + description = "Regenerates your stamina and increases your reaction time." + color = "#E62111" + overdose_threshold = 6 + value = REAGENT_VALUE_VERY_RARE + +/datum/reagent/syndicateadrenals/on_mob_life(mob/living/M) + M.adjustStaminaLoss(-5*REM) + . = ..() + +/datum/reagent/syndicateadrenals/on_mob_metabolize(mob/living/M) + . = ..() + if(istype(M)) + M.next_move_modifier *= 0.5 + to_chat(M, "You feel an intense surge of energy rushing through your veins.") + +/datum/reagent/syndicateadrenals/on_mob_end_metabolize(mob/living/M) + . = ..() + if(istype(M)) + M.next_move_modifier *= 2 + to_chat(M, "You feel as though the world around you is going faster.") + +/datum/reagent/syndicateadrenals/overdose_start(mob/living/M) + to_chat(M, "You feel an intense pain in your chest...") + +/datum/reagent/syndicateadrenals/overdose_process(mob/living/M) + if(iscarbon(M)) + var/mob/living/carbon/C = M + if(!C.undergoing_cardiac_arrest()) + C.set_heartattack(TRUE) diff --git a/code/modules/reagents/chemistry/reagents/food_reagents.dm b/code/modules/reagents/chemistry/reagents/food_reagents.dm index 24c518b70b..c7ff3f01c9 100644 --- a/code/modules/reagents/chemistry/reagents/food_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/food_reagents.dm @@ -11,7 +11,7 @@ name = "Consumable" taste_description = "generic food" taste_mult = 4 - value = 0.1 + value = REAGENT_VALUE_VERY_COMMON var/nutriment_factor = 1 * REAGENTS_METABOLISM var/quality = 0 //affects mood, typically higher for mixed drinks with more complex recipes @@ -90,7 +90,7 @@ /datum/reagent/consumable/nutriment/vitamin name = "Vitamin" description = "All the best vitamins, minerals, and carbohydrates the body needs in pure form." - value = 0.5 + value = REAGENT_VALUE_COMMON nutriment_factor = 15 * REAGENTS_METABOLISM //The are the best food for you! brute_heal = 1 burn_heal = 1 @@ -105,7 +105,7 @@ description = "A variety of cooking oil derived from fat or plants. Used in food preparation and frying." color = "#EADD6B" //RGB: 234, 221, 107 (based off of canola oil) taste_mult = 0.8 - value = 1 + value = REAGENT_VALUE_COMMON taste_description = "oil" nutriment_factor = 5 * REAGENTS_METABOLISM //Not very healthy on its own metabolization_rate = 10 * REAGENTS_METABOLISM @@ -155,7 +155,7 @@ metabolization_rate = 2 * REAGENTS_METABOLISM overdose_threshold = 200 // Hyperglycaemic shock taste_description = "sweetness" - value = 1 + value = REAGENT_VALUE_NONE /datum/reagent/consumable/sugar/overdose_start(mob/living/M) to_chat(M, "You go into hyperglycaemic shock! Lay off the twinkies!") @@ -179,6 +179,7 @@ description = "A salty sauce made from the soy plant." color = "#792300" // rgb: 121, 35, 0 taste_description = "umami" + value = REAGENT_VALUE_COMMON /datum/reagent/consumable/ketchup name = "Ketchup" @@ -230,7 +231,7 @@ description = "A special oil that noticably chills the body. Extracted from Icepeppers and slimes." color = "#8BA6E9" // rgb: 139, 166, 233 taste_description = "mint" - value = 2 + value = REAGENT_VALUE_COMMON pH = 13 //HMM! I wonder /datum/reagent/consumable/frostoil/on_mob_life(mob/living/carbon/M) @@ -399,6 +400,7 @@ metabolization_rate = 0.2 * REAGENTS_METABOLISM taste_description = "mushroom" pH = 11 + value = REAGENT_VALUE_COMMON /datum/reagent/drug/mushroomhallucinogen/on_mob_life(mob/living/carbon/M) M.slurring = max(M.slurring,50) @@ -429,6 +431,7 @@ color = "#FEFEFE" taste_description = "garlic" metabolization_rate = 0.15 * REAGENTS_METABOLISM + value = REAGENT_VALUE_COMMON /datum/reagent/consumable/garlic/on_mob_life(mob/living/carbon/M) if(isvampire(M)) //incapacitating but not lethal. Unfortunately, vampires cannot vomit. @@ -459,7 +462,7 @@ M.emote("scream") if(prob(min(5, current_cycle)) && iscarbon(M)) var/mob/living/carbon/C - C.vomit() + C.vomit() if(INJECT) if(prob(min(20, current_cycle))) to_chat(M, "You feel like your veins are boiling!") @@ -468,10 +471,10 @@ ..() /datum/reagent/consumable/sprinkles name = "Sprinkles" - value = 3 description = "Multi-colored little bits of sugar, commonly found on donuts. Loved by cops." color = "#FF00FF" // rgb: 255, 0, 255 taste_description = "childhood whimsy" + value = REAGENT_VALUE_COMMON /datum/reagent/consumable/sprinkles/on_mob_life(mob/living/carbon/M) if(M.mind && HAS_TRAIT(M.mind, TRAIT_LAW_ENFORCEMENT_METABOLISM)) @@ -483,7 +486,7 @@ name = "Peanut Butter" description = "A popular food paste made from ground dry-roasted peanuts." color = "#C29261" - value = 3 + value = REAGENT_VALUE_UNCOMMON nutriment_factor = 10 * REAGENTS_METABOLISM taste_description = "peanuts" @@ -491,7 +494,7 @@ name = "Corn Oil" description = "An oil derived from various types of corn." nutriment_factor = 12 * REAGENTS_METABOLISM - value = 4 + value = REAGENT_VALUE_UNCOMMON color = "#302000" // rgb: 48, 32, 0 taste_description = "slime" @@ -509,7 +512,7 @@ /datum/reagent/consumable/enzyme name = "Universal Enzyme" - value = 1 + value = REAGENT_VALUE_COMMON description = "A universal enzyme used in the preperation of certain chemicals and foods." color = "#365E30" // rgb: 54, 94, 48 taste_description = "sweetness" @@ -545,7 +548,6 @@ /datum/reagent/consumable/flour name = "Flour" - value = 0.5 description = "This is what you rub all over yourself to pretend to be a ghost." reagent_state = SOLID color = "#FFFFFF" // rgb: 0, 0, 0 @@ -562,19 +564,18 @@ name = "Cherry Jelly" description = "Totally the best. Only to be spread on foods with excellent lateral symmetry." color = "#801E28" // rgb: 128, 30, 40 - value = 1 + value = REAGENT_VALUE_COMMON taste_description = "cherry" /datum/reagent/consumable/bluecherryjelly name = "Blue Cherry Jelly" description = "Blue and tastier kind of cherry jelly." color = "#00F0FF" - value = 12 + value = REAGENT_VALUE_UNCOMMON taste_description = "blue cherry" /datum/reagent/consumable/rice name = "Rice" - value = 0.5 description = "tiny nutritious grains" reagent_state = SOLID nutriment_factor = 3 * REAGENTS_METABOLISM @@ -583,7 +584,7 @@ /datum/reagent/consumable/vanilla name = "Vanilla Powder" - value = 1 + value = REAGENT_VALUE_UNCOMMON description = "A fatty, bitter paste made from vanilla pods." reagent_state = SOLID nutriment_factor = 5 * REAGENTS_METABOLISM @@ -592,7 +593,6 @@ /datum/reagent/consumable/eggyolk name = "Egg Yolk" - value = 1 description = "It's full of protein." nutriment_factor = 3 * REAGENTS_METABOLISM color = "#FFB500" @@ -600,14 +600,13 @@ /datum/reagent/consumable/corn_starch name = "Corn Starch" - value = 2 description = "A slippery solution." color = "#f7f6e4" taste_description = "slime" /datum/reagent/consumable/corn_syrup name = "Corn Syrup" - value = 1 + value = REAGENT_VALUE_UNCOMMON description = "Decays into sugar." color = "#fff882" metabolization_rate = 3 * REAGENTS_METABOLISM @@ -621,7 +620,7 @@ name = "honey" description = "Sweet sweet honey that decays into sugar. Has antibacterial and natural healing properties." color = "#d3a308" - value = 15 + value = REAGENT_VALUE_COMMON nutriment_factor = 10 * REAGENTS_METABOLISM metabolization_rate = 1 * REAGENTS_METABOLISM taste_description = "sweetness" @@ -649,6 +648,7 @@ color = "#DFDFDF" value = 5 taste_description = "mayonnaise" + value = REAGENT_VALUE_COMMON /datum/reagent/consumable/tearjuice name = "Tear Juice" @@ -656,6 +656,7 @@ color = "#c0c9a0" taste_description = "bitterness" pH = 5 + value = REAGENT_VALUE_COMMON /datum/reagent/consumable/tearjuice/reaction_mob(mob/living/M, method=TOUCH, reac_volume) if(!istype(M)) @@ -694,6 +695,7 @@ reagent_state = SOLID nutriment_factor = 12 * REAGENTS_METABOLISM color = "#664330" // rgb: 102, 67, 48 + value = REAGENT_VALUE_RARE /datum/reagent/consumable/nutriment/stabilized/on_mob_life(mob/living/carbon/M) if(M.nutrition > NUTRITION_LEVEL_FULL - 25) @@ -709,6 +711,7 @@ color = "#1d043d" taste_description = "bitter mushroom" pH = 12 + value = REAGENT_VALUE_RARE /datum/reagent/consumable/entpoly/on_mob_life(mob/living/carbon/M) if(current_cycle >= 10) @@ -729,6 +732,7 @@ color = "#b5a213" taste_description = "tingling mushroom" pH = 11.2 + value = REAGENT_VALUE_RARE /datum/reagent/consumable/tinlux/reaction_mob(mob/living/M) M.set_light(2) @@ -743,6 +747,7 @@ nutriment_factor = 3 * REAGENTS_METABOLISM taste_description = "fruity mushroom" pH = 10.4 + value = REAGENT_VALUE_RARE /datum/reagent/consumable/vitfro/on_mob_life(mob/living/carbon/M) if(prob(80)) @@ -808,6 +813,7 @@ taste_mult = 2 taste_description = "caramel" reagent_state = SOLID + value = REAGENT_VALUE_COMMON /datum/reagent/consumable/secretsauce name = "secret sauce" @@ -818,6 +824,7 @@ taste_mult = 100 can_synth = FALSE pH = 6.1 + value = REAGENT_VALUE_AMAZING /datum/reagent/consumable/secretsauce/reaction_obj(obj/O, reac_volume) //splashing any amount above or equal to 1u of secret sauce onto a piece of food turns its quality to 100 @@ -838,6 +845,7 @@ taste_mult = 6 taste_description = "smoke" overdose_threshold = 25 + value = REAGENT_VALUE_COMMON /datum/reagent/consumable/char/overdose_process(mob/living/carbon/M) if(prob(10)) @@ -850,3 +858,4 @@ color = "#78280A" // rgb: 120 40, 10 taste_mult = 2.5 //sugar's 1.5, capsacin's 1.5, so a good middle ground. taste_description = "smokey sweetness" + value = REAGENT_VALUE_COMMON diff --git a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm index ecceb6e8bf..bb7253c7eb 100644 --- a/code/modules/reagents/chemistry/reagents/medicine_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/medicine_reagents.dm @@ -7,8 +7,8 @@ /datum/reagent/medicine name = "Medicine" - value = 2 taste_description = "bitterness" + value = REAGENT_VALUE_VERY_COMMON //Low prices, spess medical companies are cheapstakes and products are taxed honk... /datum/reagent/medicine/on_mob_life(mob/living/carbon/M) current_cycle++ @@ -19,6 +19,7 @@ description = "Leporazine will effectively regulate a patient's body temperature, ensuring it never leaves safe levels." pH = 8.4 color = "#82b8aa" + value = REAGENT_VALUE_COMMON /datum/reagent/medicine/leporazine/on_mob_life(mob/living/carbon/M) if(M.bodytemperature > BODYTEMP_NORMAL) @@ -33,6 +34,7 @@ color = "#ffffff" can_synth = FALSE taste_description = "badmins" + value = REAGENT_VALUE_GLORIOUS /datum/reagent/medicine/adminordrazine/on_mob_life(mob/living/carbon/M) M.reagents.remove_all_type(/datum/reagent/toxin, 5*REM, 0, 1) @@ -101,6 +103,7 @@ description = "Reduces drowsiness, hallucinations, and Histamine from body." color = "#EC536D" // rgb: 236, 83, 109 pH = 5.2 + value = REAGENT_VALUE_COMMON /datum/reagent/medicine/synaphydramine/on_mob_life(mob/living/carbon/M) M.drowsyness = max(M.drowsyness-5, 0) @@ -131,6 +134,7 @@ color = "#0000C8" taste_description = "sludge" pH = 11 + value = REAGENT_VALUE_COMMON /datum/reagent/medicine/cryoxadone/on_mob_life(mob/living/carbon/M) var/power = -0.00003 * (M.bodytemperature ** 2) + 3 @@ -152,6 +156,7 @@ taste_description = "muscle" metabolization_rate = 1.5 * REAGENTS_METABOLISM pH = 13 + value = REAGENT_VALUE_COMMON /datum/reagent/medicine/clonexadone/on_mob_life(mob/living/carbon/M) if(M.bodytemperature < T0C) @@ -167,6 +172,7 @@ color = "#f7832a" taste_description = "spicy jelly" pH = 12 + value = REAGENT_VALUE_UNCOMMON /datum/reagent/medicine/pyroxadone/on_mob_life(mob/living/carbon/M) if(M.bodytemperature > BODYTEMP_HEAT_DAMAGE_LIMIT) @@ -198,7 +204,7 @@ overdose_threshold = 30 taste_description = "fish" pH = 12.2 - value = 20 + value = REAGENT_VALUE_RARE /datum/reagent/medicine/rezadone/on_mob_life(mob/living/carbon/M) M.setCloneLoss(0) //Rezadone is almost never used in favor of cryoxadone. Hopefully this will change that. @@ -239,7 +245,6 @@ color = "#ffeac9" metabolization_rate = 5 * REAGENTS_METABOLISM overdose_threshold = 50 - value = 3 /datum/reagent/medicine/silver_sulfadiazine/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message = 1) if(iscarbon(M) && M.stat != DEAD) @@ -277,7 +282,7 @@ metabolization_rate = 0.5 * REAGENTS_METABOLISM overdose_threshold = 25 pH = 10.7 - value = 4 + value = REAGENT_VALUE_COMMON /datum/reagent/medicine/oxandrolone/on_mob_life(mob/living/carbon/M) if(M.getFireLoss() > 25) @@ -301,7 +306,6 @@ pH = 6.7 metabolization_rate = 5 * REAGENTS_METABOLISM overdose_threshold = 50 - value = 3 /datum/reagent/medicine/styptic_powder/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message = 1) if(iscarbon(M) && M.stat != DEAD) @@ -343,7 +347,6 @@ datum/reagent/medicine/styptic_powder/overdose_start(mob/living/M) var/last_added = 0 var/maximum_reachable = BLOOD_VOLUME_NORMAL - 10 //So that normal blood regeneration can continue with salglu active pH = 5.5 - value = 1 /datum/reagent/medicine/salglu_solution/on_mob_life(mob/living/carbon/M) if((HAS_TRAIT(M, TRAIT_NOMARROW))) @@ -384,6 +387,7 @@ datum/reagent/medicine/styptic_powder/overdose_start(mob/living/M) color = "#6D6374" metabolization_rate = 0.4 * REAGENTS_METABOLISM pH = 2.6 + value = REAGENT_VALUE_COMMON /datum/reagent/medicine/mine_salve/on_mob_life(mob/living/carbon/C) C.hal_screwyhud = SCREWYHUD_HEALTHY @@ -424,7 +428,7 @@ datum/reagent/medicine/styptic_powder/overdose_start(mob/living/M) pH = 11.5 metabolization_rate = 5 * REAGENTS_METABOLISM overdose_threshold = 40 - value = 6 + value = REAGENT_VALUE_COMMON /datum/reagent/medicine/synthflesh/reaction_mob(mob/living/M, method=TOUCH, reac_volume, show_message = 1) if(iscarbon(M)) @@ -461,7 +465,6 @@ datum/reagent/medicine/styptic_powder/overdose_start(mob/living/M) metabolization_rate = 0.5 * REAGENTS_METABOLISM taste_description = "ash" pH = 5 - value = 1 /datum/reagent/medicine/charcoal/on_mob_life(mob/living/carbon/M) M.adjustToxLoss(-2*REM, 0) @@ -480,7 +483,7 @@ datum/reagent/medicine/styptic_powder/overdose_start(mob/living/M) metabolization_rate = 0.25 * REAGENTS_METABOLISM overdose_threshold = 30 pH = 2 - value = 5 + value = REAGENT_VALUE_UNCOMMON /datum/reagent/medicine/omnizine/on_mob_life(mob/living/carbon/M) M.adjustToxLoss(-0.5*REM, 0) @@ -537,6 +540,7 @@ datum/reagent/medicine/styptic_powder/overdose_start(mob/living/M) color = "#003153" // RGB 0, 49, 83 metabolization_rate = 0.5 * REAGENTS_METABOLISM pH = 8.9 + value = REAGENT_VALUE_COMMON //uncraftable /datum/reagent/medicine/prussian_blue/on_mob_life(mob/living/carbon/M) if(M.radiation > 0) @@ -550,6 +554,7 @@ datum/reagent/medicine/styptic_powder/overdose_start(mob/living/M) color = "#E6FFF0" metabolization_rate = 0.5 * REAGENTS_METABOLISM pH = 1 //One of the best buffers, NEVERMIND! + value = REAGENT_VALUE_UNCOMMON var/healtoxinlover = FALSE /datum/reagent/medicine/pen_acid/on_mob_life(mob/living/carbon/M) @@ -568,6 +573,7 @@ datum/reagent/medicine/styptic_powder/overdose_start(mob/living/M) color = "#91D865" healtoxinlover = TRUE pH = 12//invert + value = REAGENT_VALUE_RARE /datum/reagent/medicine/sal_acid name = "Salicyclic Acid" @@ -577,6 +583,7 @@ datum/reagent/medicine/styptic_powder/overdose_start(mob/living/M) metabolization_rate = 0.5 * REAGENTS_METABOLISM overdose_threshold = 25 pH = 2.1 + value = REAGENT_VALUE_COMMON /datum/reagent/medicine/sal_acid/on_mob_life(mob/living/carbon/M) @@ -688,6 +695,7 @@ datum/reagent/medicine/styptic_powder/overdose_start(mob/living/M) color = "#64FFE6" metabolization_rate = 0.5 * REAGENTS_METABOLISM pH = 11.5 + value = REAGENT_VALUE_COMMON /datum/reagent/medicine/diphenhydramine/on_mob_life(mob/living/carbon/M) if(prob(10)) @@ -803,6 +811,7 @@ datum/reagent/medicine/styptic_powder/overdose_start(mob/living/M) metabolization_rate = 0.25 * REAGENTS_METABOLISM overdose_threshold = 35 pH = 12 + value = REAGENT_VALUE_UNCOMMON /datum/reagent/medicine/atropine/on_mob_life(mob/living/carbon/M) if(M.health < 0) @@ -867,6 +876,7 @@ datum/reagent/medicine/styptic_powder/overdose_start(mob/living/M) metabolization_rate = 0.5 * REAGENTS_METABOLISM taste_description = "magnets" pH = 0 + value = REAGENT_VALUE_RARE /datum/reagent/medicine/strange_reagent/reaction_mob(mob/living/M, method=TOUCH, reac_volume) if(M.stat == DEAD) @@ -990,6 +1000,7 @@ datum/reagent/medicine/styptic_powder/overdose_start(mob/living/M) metabolization_rate = 0.5 * REAGENTS_METABOLISM overdose_threshold = 60 pH = 8.7 + value = REAGENT_VALUE_RARE /datum/reagent/medicine/stimulants/on_mob_metabolize(mob/living/L) ..() @@ -1154,6 +1165,7 @@ datum/reagent/medicine/styptic_powder/overdose_start(mob/living/M) reagent_state = LIQUID color = "#91D865" taste_description = "jelly" + value = REAGENT_VALUE_COMMON /datum/reagent/medicine/regen_jelly/on_mob_life(mob/living/carbon/M) M.adjustBruteLoss(-1.5*REM, FALSE) @@ -1169,6 +1181,7 @@ datum/reagent/medicine/styptic_powder/overdose_start(mob/living/M) reagent_state = SOLID color = "#555555" pH = 11 + value = REAGENT_VALUE_EXCEPTIONAL /datum/reagent/medicine/syndicate_nanites/on_mob_life(mob/living/carbon/M) M.adjustBruteLoss(-5*REM, FALSE) //A ton of healing - this is a 50 telecrystal investment. @@ -1189,6 +1202,7 @@ datum/reagent/medicine/styptic_powder/overdose_start(mob/living/M) reagent_state = SOLID color = "#555555" pH = 11 + value = REAGENT_VALUE_VERY_RARE /datum/reagent/medicine/lesser_syndicate_nanites/on_mob_life(mob/living/carbon/M) M.adjustBruteLoss(-3*REM, FALSE) // hidden gold shh @@ -1212,6 +1226,7 @@ datum/reagent/medicine/styptic_powder/overdose_start(mob/living/M) overdose_threshold = 30 taste_description = "jelly" pH = 11.8 + value = REAGENT_VALUE_UNCOMMON /datum/reagent/medicine/neo_jelly/on_mob_life(mob/living/carbon/M) M.adjustBruteLoss(-1.5*REM, FALSE) @@ -1234,6 +1249,7 @@ datum/reagent/medicine/styptic_powder/overdose_start(mob/living/M) color = rgb(255, 175, 0) overdose_threshold = 25 pH = 11 + value = REAGENT_VALUE_COMMON //not any higher. Ambrosia is a milestone for hydroponics already. /datum/reagent/medicine/earthsblood/on_mob_life(mob/living/carbon/M) M.adjustBruteLoss(-3 * REM, FALSE) @@ -1261,6 +1277,7 @@ datum/reagent/medicine/styptic_powder/overdose_start(mob/living/M) color = "#27870a" metabolization_rate = 0.4 * REAGENTS_METABOLISM pH = 4.3 + value = REAGENT_VALUE_UNCOMMON /datum/reagent/medicine/haloperidol/on_mob_life(mob/living/carbon/M) for(var/datum/reagent/drug/R in M.reagents.reagent_list) @@ -1283,6 +1300,7 @@ datum/reagent/medicine/styptic_powder/overdose_start(mob/living/M) overdose_threshold = 3 //To prevent people stacking massive amounts of a very strong healing reagent can_synth = FALSE pH = 14 + value = REAGENT_VALUE_AMAZING /datum/reagent/medicine/lavaland_extract/on_mob_life(mob/living/carbon/M) M.heal_bodypart_damage(5,5) @@ -1302,6 +1320,7 @@ datum/reagent/medicine/styptic_powder/overdose_start(mob/living/M) description = "Reduces the duration of unconciousness, knockdown and stuns. Restores stamina, but deals toxin damage when overdosed." color = "#918e53" overdose_threshold = 30 + value = REAGENT_VALUE_VERY_RARE /datum/reagent/medicine/changelingadrenaline/on_mob_metabolize(mob/living/L) ..() @@ -1329,6 +1348,7 @@ datum/reagent/medicine/styptic_powder/overdose_start(mob/living/M) description = "Drastically increases movement speed, but deals toxin damage." color = "#669153" metabolization_rate = 1 + value = REAGENT_VALUE_VERY_RARE /datum/reagent/medicine/changelinghaste/on_mob_metabolize(mob/living/L) ..() @@ -1365,6 +1385,7 @@ datum/reagent/medicine/styptic_powder/overdose_start(mob/living/M) /datum/reagent/medicine/muscle_stimulant name = "Muscle Stimulant" description = "A potent chemical that allows someone under its influence to be at full physical ability even when under massive amounts of pain." + value = REAGENT_VALUE_RARE /datum/reagent/medicine/muscle_stimulant/on_mob_metabolize(mob/living/M) . = ..() @@ -1382,6 +1403,7 @@ datum/reagent/medicine/styptic_powder/overdose_start(mob/living/M) metabolization_rate = 0.1 * REAGENTS_METABOLISM overdose_threshold = 20 // with the random effects this might be awesome or might kill you at less than 10u (extensively tested) taste_description = "salt" // it actually does taste salty + value = REAGENT_VALUE_RARE var/overdose_progress = 0 // to track overdose progress pH = 7.89 @@ -1448,6 +1470,7 @@ datum/reagent/medicine/styptic_powder/overdose_start(mob/living/M) metabolization_rate = 0.25 * REAGENTS_METABOLISM overdose_threshold = 30 pH = 9.12 + value = REAGENT_VALUE_COMMON /datum/reagent/medicine/psicodine/on_mob_add(mob/living/L) ..() @@ -1480,6 +1503,7 @@ datum/reagent/medicine/styptic_powder/overdose_start(mob/living/M) reagent_state = SOLID color = "#FFFFD0" metabolization_rate = 1.5 * REAGENTS_METABOLISM + value = REAGENT_VALUE_UNCOMMON /datum/reagent/medicine/silibinin/on_mob_life(mob/living/carbon/M) M.adjustOrganLoss(ORGAN_SLOT_LIVER, -2)//Add a chance to cure liver trauma once implemented. @@ -1494,6 +1518,7 @@ datum/reagent/medicine/styptic_powder/overdose_start(mob/living/M) metabolization_rate = 0.25 * REAGENTS_METABOLISM overdose_threshold = 50 taste_description = "numbing bitterness" + value = REAGENT_VALUE_RARE /datum/reagent/medicine/polypyr/on_mob_life(mob/living/carbon/M) //I wanted a collection of small positive effects, this is as hard to obtain as coniine after all. M.adjustOrganLoss(ORGAN_SLOT_LUNGS, -0.25) diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm index af335359c3..4410582054 100644 --- a/code/modules/reagents/chemistry/reagents/other_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm @@ -1,7 +1,7 @@ /datum/reagent/blood data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_HUMAN, "blood_type"= null,"resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null,"quirks"=null) name = "Blood" - value = 1 + value = REAGENT_VALUE_UNCOMMON // $$$ blood ""donations"" $$$ color = BLOOD_COLOR_HUMAN // rgb: 200, 0, 0 description = "Blood from some creature." metabolization_rate = 5 //fast rate so it disappears fast. @@ -142,6 +142,7 @@ description = "A synthetically produced imitation of blood." taste_description = "oily" color = BLOOD_COLOR_SYNTHETIC // rgb: 11, 7, 48 + value = REAGENT_VALUE_NONE /datum/reagent/blood/jellyblood data = list("donor"=null,"viruses"=null,"blood_DNA"=null, "bloodcolor" = BLOOD_COLOR_SLIME, "blood_type"="GEL","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null) @@ -158,6 +159,7 @@ description = "This highly resembles blood, but it doesnt actually function like it, resembling more ketchup, with a more blood-like consistency." taste_description = "sap" //Like tree sap? pH = 7.45 + value = REAGENT_VALUE_NONE /datum/reagent/blood/jellyblood/on_mob_life(mob/living/carbon/M) if(prob(10)) @@ -387,6 +389,7 @@ description = "Something that shouldn't exist on this plane of existence." taste_description = "suffering" pH = 6.5 + value = REAGENT_VALUE_RARE /datum/reagent/fuel/unholywater/reaction_mob(mob/living/M, method=TOUCH, reac_volume) if(method == TOUCH || method == VAPOR) @@ -423,6 +426,7 @@ name = "Hell Water" description = "YOUR FLESH! IT BURNS!" taste_description = "burning" + value = REAGENT_VALUE_VERY_RARE /datum/reagent/hellwater/on_mob_life(mob/living/carbon/M) M.fire_stacks = min(5,M.fire_stacks + 3) @@ -437,6 +441,7 @@ name = "Zelus Oil" description = "Oil blessed by a greater being." taste_description = "metallic oil" + value = REAGENT_VALUE_RARE /datum/reagent/fuel/holyoil/on_mob_life(mob/living/carbon/M) if(is_servant_of_ratvar(M)) @@ -475,6 +480,7 @@ name = "Godblood" description = "Slowly heals all damage types. Has a rather high overdose threshold. Glows with mysterious power." overdose_threshold = 150 + value = REAGENT_VALUE_RARE /datum/reagent/lube name = "Space Lube" @@ -591,6 +597,7 @@ color = "#5EFF3B" //RGB: 94, 255, 59 metabolization_rate = INFINITY //So it instantly removes all of itself taste_description = "slime" + value = REAGENT_VALUE_RARE var/datum/species/race = /datum/species/human var/mutationtext = "The pain subsides. You feel... human." @@ -750,6 +757,7 @@ color = "#5EFF3B" //RGB: 94, 255, 59 taste_description = "slime" metabolization_rate = 0.2 + value = REAGENT_VALUE_RARE /datum/reagent/slime_toxin/on_mob_life(mob/living/carbon/human/H) ..() @@ -786,6 +794,7 @@ color = "#5EFF3B" //RGB: 94, 255, 59 metabolization_rate = INFINITY taste_description = "slime" + value = REAGENT_VALUE_RARE /datum/reagent/mulligan/on_mob_life(mob/living/carbon/human/H) ..() @@ -800,6 +809,7 @@ description = "An advanced corruptive toxin produced by slimes." color = "#13BC5E" // rgb: 19, 188, 94 taste_description = "slime" + value = REAGENT_VALUE_VERY_RARE /datum/reagent/aslimetoxin/reaction_mob(mob/living/L, method=TOUCH, reac_volume) if(method != TOUCH) @@ -811,6 +821,7 @@ color = "#5EFF3B" //RGB: 94, 255, 59 can_synth = FALSE taste_description = "decay" + value = REAGENT_VALUE_GLORIOUS /datum/reagent/gluttonytoxin/reaction_mob(mob/living/L, method=TOUCH, reac_volume) L.ForceContractDisease(new /datum/disease/transformation/morph(), FALSE, TRUE) @@ -1113,6 +1124,7 @@ color = "#0000CC" taste_description = "fizzling blue" pH = 12 + value = REAGENT_VALUE_RARE /datum/reagent/bluespace/reaction_mob(mob/living/M, method=TOUCH, reac_volume) if(method == TOUCH || method == VAPOR) @@ -1239,6 +1251,7 @@ metabolization_rate = 1.5 * REAGENTS_METABOLISM taste_description = "acid" pH = 2 + value = REAGENT_VALUE_RARE /datum/reagent/space_cleaner/ez_clean/on_mob_life(mob/living/carbon/M) M.adjustBruteLoss(3.33) @@ -1290,6 +1303,7 @@ color = "#535E66" // rgb: 83, 94, 102 can_synth = FALSE taste_description = "sludge" + value = REAGENT_VALUE_GLORIOUS /datum/reagent/nanomachines/reaction_mob(mob/living/L, method=TOUCH, reac_volume, show_message = 1, touch_protection = 0) if(method==PATCH || method==INGEST || method==INJECT || (method == VAPOR && prob(min(reac_volume,100)*(1 - touch_protection)))) @@ -1301,6 +1315,7 @@ color = "#535E66" // rgb: 83, 94, 102 can_synth = FALSE taste_description = "sludge" + value = REAGENT_VALUE_GLORIOUS /datum/reagent/xenomicrobes/reaction_mob(mob/living/L, method=TOUCH, reac_volume, show_message = 1, touch_protection = 0) if(method==PATCH || method==INGEST || method==INJECT || (method == VAPOR && prob(min(reac_volume,100)*(1 - touch_protection)))) @@ -1313,6 +1328,7 @@ can_synth = FALSE taste_description = "slime" pH = 11 + value = REAGENT_VALUE_GLORIOUS /datum/reagent/fungalspores/reaction_mob(mob/living/L, method=TOUCH, reac_volume, show_message = 1, touch_protection = 0) if(method==PATCH || method==INGEST || method==INJECT || (method == VAPOR && prob(min(reac_volume,100)*(1 - touch_protection)))) @@ -1340,6 +1356,7 @@ color = "#664B63" // rgb: 102, 75, 99 taste_description = "metal" pH = 11.8 + value = REAGENT_VALUE_UNCOMMON /datum/reagent/ammonia name = "Ammonia" @@ -1417,6 +1434,7 @@ metabolization_rate = 1.5 * REAGENTS_METABOLISM color = "E1A116" taste_description = "sourness" + value = REAGENT_VALUE_EXCEPTIONAL /datum/reagent/stimulum/on_mob_metabolize(mob/living/L) ..() @@ -1442,6 +1460,7 @@ color = "90560B" taste_description = "burning" pH = 2 + value = REAGENT_VALUE_VERY_RARE /datum/reagent/nitryl/on_mob_metabolize(mob/living/L) ..() @@ -1463,6 +1482,7 @@ color = "#FFFFFF" // rgb: 207, 54, 0 taste_description = "the back of class" no_mob_color = TRUE + value = REAGENT_VALUE_NONE /datum/reagent/colorful_reagent/crayonpowder/New() description = "\an [colorname] powder made by grinding down crayons, good for colouring chemical reagents." @@ -1633,6 +1653,7 @@ color = "#FFFF00" var/list/random_color_list = list("#00aedb","#a200ff","#f47835","#d41243","#d11141","#00b159","#00aedb","#f37735","#ffc425","#008744","#0057e7","#d62d20","#ffa700") taste_description = "rainbows" + value = REAGENT_VALUE_RARE var/no_mob_color = FALSE /datum/reagent/colorful_reagent/on_mob_life(mob/living/carbon/M) @@ -1662,6 +1683,7 @@ color = "#ff00dd" var/list/potential_colors = list("0ad","a0f","f73","d14","d14","0b5","0ad","f73","fc2","084","05e","d22","fa0") // fucking hair code taste_description = "sourness" + value = REAGENT_VALUE_RARE /datum/reagent/hair_dye/reaction_mob(mob/living/M, method=TOUCH, reac_volume) if(method == TOUCH || method == VAPOR) @@ -1677,6 +1699,7 @@ reagent_state = LIQUID color = "#fac34b" taste_description = "sourness" + value = REAGENT_VALUE_UNCOMMON /datum/reagent/barbers_aid/reaction_mob(mob/living/M, method=TOUCH, reac_volume) if(method == TOUCH || method == VAPOR) @@ -1694,6 +1717,7 @@ reagent_state = LIQUID color = "#ffaf00" taste_description = "sourness" + value = REAGENT_VALUE_RARE /datum/reagent/concentrated_barbers_aid/reaction_mob(mob/living/M, method=TOUCH, reac_volume) if(method == TOUCH || method == VAPOR) @@ -1726,6 +1750,7 @@ color = "#A70FFF" taste_description = "dryness" pH = 10.7 + value = REAGENT_VALUE_UNCOMMON /datum/reagent/drying_agent/reaction_turf(turf/open/T, reac_volume) if(istype(T)) @@ -1863,6 +1888,7 @@ color = "#00ff80" taste_description = "strange honey" pH = 3 + value = REAGENT_VALUE_UNCOMMON /datum/reagent/royal_bee_jelly/on_mob_life(mob/living/carbon/M) if(prob(2)) @@ -1884,6 +1910,7 @@ can_synth = FALSE taste_description = "brains" pH = 0.5 + value = REAGENT_VALUE_GLORIOUS /datum/reagent/romerol/reaction_mob(mob/living/carbon/human/H, method=TOUCH, reac_volume) // Silently add the zombie infection organ to be activated upon death @@ -1897,6 +1924,7 @@ description = "An experimental serum which causes rapid muscular growth in Hominidae. Side-affects may include hypertrichosis, violent outbursts, and an unending affinity for bananas." reagent_state = LIQUID color = "#00f041" + value = REAGENT_VALUE_EXCEPTIONAL /datum/reagent/magillitis/on_mob_life(mob/living/carbon/M) ..() @@ -1908,6 +1936,7 @@ description = "A commercial chemical designed to help older men in the bedroom."//not really it just makes you a giant color = "#ff0000"//strong red. rgb 255, 0, 0 var/current_size = RESIZE_DEFAULT_SIZE + value = REAGENT_VALUE_COMMON taste_description = "bitterness" // apparently what viagra tastes like /datum/reagent/growthserum/on_mob_life(mob/living/carbon/H) @@ -1978,6 +2007,7 @@ color = "#AAAAAA55" taste_description = "water" metabolization_rate = 0.25 * REAGENTS_METABOLISM + value = REAGENT_VALUE_RARE pH = 15 /datum/reagent/pax/on_mob_metabolize(mob/living/L) @@ -1994,6 +2024,7 @@ color = "#FAFF00" taste_description = "acrid cinnamon" metabolization_rate = 0.2 * REAGENTS_METABOLISM + value = REAGENT_VALUE_UNCOMMON /datum/reagent/bz_metabolites/on_mob_metabolize(mob/living/L) ..() @@ -2014,12 +2045,14 @@ name = "synth-pax" description = "A colorless liquid that suppresses violence on the subjects. Cheaper to synthetize, but wears out faster than normal Pax." metabolization_rate = 1.5 * REAGENTS_METABOLISM + value = REAGENT_VALUE_COMMON /datum/reagent/peaceborg_confuse name = "Dizzying Solution" description = "Makes the target off balance and dizzy" metabolization_rate = 1.5 * REAGENTS_METABOLISM taste_description = "dizziness" + value = REAGENT_VALUE_COMMON /datum/reagent/peaceborg_confuse/on_mob_life(mob/living/carbon/M) if(M.confused < 6) @@ -2035,6 +2068,7 @@ description = "An extremely weak stamina-toxin that tires out the target. Completely harmless." metabolization_rate = 1.5 * REAGENTS_METABOLISM taste_description = "tiredness" + value = REAGENT_VALUE_COMMON /datum/reagent/peaceborg_tire/on_mob_life(mob/living/carbon/M) var/healthcomp = (100 - M.health) //DOES NOT ACCOUNT FOR ADMINBUS THINGS THAT MAKE YOU HAVE MORE THAN 200/210 HEALTH, OR SOMETHING OTHER THAN A HUMAN PROCESSING THIS. @@ -2050,6 +2084,7 @@ color = "#9A6750" //RGB: 154, 103, 80 taste_description = "inner peace" can_synth = FALSE + value = REAGENT_VALUE_GLORIOUS /datum/reagent/tranquility/reaction_mob(mob/living/L, method=TOUCH, reac_volume, show_message = 1, touch_protection = 0) if(method==PATCH || method==INGEST || method==INJECT || (method == VAPOR && prob(min(reac_volume,100)*(1 - touch_protection)))) @@ -2060,6 +2095,7 @@ description = "The primary precursor for an ancient feline delicacy known as skooma. While it has no notable effects on it's own, mixing it with morphine in a chilled container may yield interesting results." color = "#FAEAFF" taste_description = "synthetic catnip" + value = REAGENT_VALUE_UNCOMMON /datum/reagent/moonsugar/on_mob_life(mob/living/carbon/M) if(prob(20)) @@ -2076,6 +2112,7 @@ var/datum/dna/original_dna var/reagent_ticks = 0 chemical_flags = REAGENT_INVISIBLE + value = REAGENT_VALUE_GLORIOUS /datum/reagent/changeling_string/on_mob_metabolize(mob/living/carbon/C) if(ishuman(C) && C.dna && data["desired_dna"]) @@ -2111,6 +2148,7 @@ taste_description = "grass" description = "A colorless liquid that makes people more peaceful and felines more happy." metabolization_rate = 1.75 * REAGENTS_METABOLISM + value = REAGENT_VALUE_COMMON /datum/reagent/pax/catnip/on_mob_life(mob/living/carbon/M) if(prob(20)) diff --git a/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm b/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm index 939d5c9707..67ff61610d 100644 --- a/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/pyrotechnic_reagents.dm @@ -5,6 +5,7 @@ reagent_state = SOLID color = "#550000" taste_description = "sweet tasting metal" + value = REAGENT_VALUE_COMMON /datum/reagent/thermite/reaction_turf(turf/T, reac_volume) if(reac_volume >= 1) @@ -21,13 +22,14 @@ description = "Nitroglycerin is a heavy, colorless, oily, explosive liquid obtained by nitrating glycerol." color = "#808080" // rgb: 128, 128, 128 taste_description = "oil" + value = REAGENT_VALUE_EXCEPTIONAL /datum/reagent/stabilizing_agent name = "Stabilizing Agent" description = "Keeps unstable chemicals stable. This does not work on everything." reagent_state = LIQUID color = "#FFFF00" - value = 3 + value = REAGENT_VALUE_VERY_COMMON taste_description = "metal" /datum/reagent/clf3 @@ -37,6 +39,7 @@ color = "#FFC8C8" metabolization_rate = 4 taste_description = "burning" + value = REAGENT_VALUE_COMMON /datum/reagent/clf3/on_mob_life(mob/living/carbon/M) M.adjust_fire_stacks(2) @@ -79,13 +82,14 @@ reagent_state = LIQUID color = "#5A64C8" taste_description = "air and bitterness" + value = REAGENT_VALUE_UNCOMMON /datum/reagent/liquid_dark_matter name = "Liquid Dark Matter" description = "Sucks everything into the detonation point." reagent_state = LIQUID color = "#210021" - value = 10 + value = REAGENT_VALUE_UNCOMMON taste_description = "compressed bitterness" /datum/reagent/blackpowder @@ -93,9 +97,9 @@ description = "Explodes. Violently." reagent_state = LIQUID color = "#000000" - value = 5 metabolization_rate = 0.05 taste_description = "salt" + value = REAGENT_VALUE_RARE /datum/reagent/blackpowder/on_mob_life(mob/living/carbon/M) ..() @@ -115,6 +119,7 @@ reagent_state = LIQUID color = "#C8C8C8" taste_description = "salt" + value = REAGENT_VALUE_UNCOMMON /datum/reagent/smoke_powder name = "Smoke Powder" @@ -122,6 +127,7 @@ reagent_state = LIQUID color = "#C8C8C8" taste_description = "smoke" + value = REAGENT_VALUE_COMMON /datum/reagent/sonic_powder name = "Sonic Powder" @@ -129,6 +135,7 @@ reagent_state = LIQUID color = "#C8C8C8" taste_description = "loud noises" + value = REAGENT_VALUE_UNCOMMON /datum/reagent/phlogiston name = "Phlogiston" @@ -136,6 +143,7 @@ reagent_state = LIQUID color = "#FA00AF" taste_description = "burning" + value = REAGENT_VALUE_UNCOMMON /datum/reagent/phlogiston/reaction_mob(mob/living/M, method=TOUCH, reac_volume) M.adjust_fire_stacks(1) @@ -156,8 +164,8 @@ description = "Very flammable." reagent_state = LIQUID color = "#FA00AF" - value = 1 taste_description = "burning" + value = REAGENT_VALUE_COMMON /datum/reagent/napalm/on_mob_life(mob/living/carbon/M) M.adjust_fire_stacks(1) @@ -174,7 +182,7 @@ color = "#0000DC" metabolization_rate = 0.5 * REAGENTS_METABOLISM taste_description = "bitterness" - + value = REAGENT_VALUE_COMMON /datum/reagent/cryostylane/on_mob_life(mob/living/carbon/M) //TODO: code freezing into an ice cube if(M.reagents.has_reagent(/datum/reagent/oxygen)) @@ -193,6 +201,7 @@ color = "#64FAC8" metabolization_rate = 0.5 * REAGENTS_METABOLISM taste_description = "bitterness" + value = REAGENT_VALUE_COMMON /datum/reagent/pyrosium/on_mob_life(mob/living/carbon/M) if(M.reagents.has_reagent(/datum/reagent/oxygen)) @@ -208,6 +217,7 @@ metabolization_rate = 0.5 * REAGENTS_METABOLISM taste_description = "charged metal" var/shock_timer = 0 + value = REAGENT_VALUE_VERY_RARE /datum/reagent/teslium/on_mob_life(mob/living/carbon/M) shock_timer++ @@ -242,6 +252,7 @@ reagent_state = LIQUID color = "#A6FAFF55" taste_description = "the inside of a fire extinguisher" + value = REAGENT_VALUE_UNCOMMON /datum/reagent/firefighting_foam/reaction_turf(turf/open/T, reac_volume) if (!istype(T)) diff --git a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm index bd79ed5fb8..3169d2d3aa 100644 --- a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm @@ -7,6 +7,7 @@ color = "#CF3600" // rgb: 207, 54, 0 taste_description = "bitterness" taste_mult = 1.2 + value = REAGENT_VALUE_COMMON //Encouraging people to mix toxins for reasons beyond harming each other or mixing reagents such as pen acid. var/toxpwr = 1.5 /datum/reagent/toxin/on_mob_life(mob/living/carbon/M) @@ -21,6 +22,7 @@ color = "#792300" // rgb: 121, 35, 0 toxpwr = 2.5 taste_description = "mushroom" + value = REAGENT_VALUE_UNCOMMON pH = 13 /datum/reagent/toxin/mutagen @@ -30,6 +32,7 @@ toxpwr = 0 taste_description = "slime" taste_mult = 0.9 + value = REAGENT_VALUE_VERY_COMMON pH = 2.3 /datum/reagent/toxin/mutagen/reaction_mob(mob/living/carbon/M, method=TOUCH, reac_volume) @@ -60,6 +63,7 @@ color = "#8228A0" toxpwr = 3 pH = 4 + value = REAGENT_VALUE_RARE //sheets are worth more /datum/reagent/toxin/plasma/on_mob_life(mob/living/carbon/C) if(holder.has_reagent(/datum/reagent/medicine/epinephrine)) @@ -92,6 +96,7 @@ toxpwr = 0 taste_description = "acid" pH = 1.2 + value = REAGENT_VALUE_RARE /datum/reagent/toxin/lexorin/on_mob_life(mob/living/carbon/C) . = TRUE @@ -114,6 +119,7 @@ taste_description = "slime" taste_mult = 1.3 pH = 10 + value = REAGENT_VALUE_UNCOMMON /datum/reagent/toxin/slimejelly/on_mob_life(mob/living/carbon/M) if(prob(10)) @@ -132,6 +138,7 @@ toxpwr = 0 taste_description = "mint" pH = 8 + value = REAGENT_VALUE_UNCOMMON /datum/reagent/toxin/minttoxin/on_mob_life(mob/living/carbon/M) if(HAS_TRAIT(M, TRAIT_FAT)) @@ -145,6 +152,7 @@ toxpwr = 2 taste_description = "fish" pH = 12 + value = REAGENT_VALUE_RARE /datum/reagent/toxin/zombiepowder name = "Zombie Powder" @@ -155,6 +163,7 @@ taste_description = "death" var/fakedeath_active = FALSE pH = 13 + value = REAGENT_VALUE_EXCEPTIONAL /datum/reagent/toxin/zombiepowder/on_mob_metabolize(mob/living/L) ..() @@ -193,6 +202,7 @@ toxpwr = 0.8 taste_description = "death" pH = 14.5 + value = REAGENT_VALUE_EXCEPTIONAL /datum/reagent/toxin/ghoulpowder/on_mob_metabolize(mob/living/L) ..() @@ -214,6 +224,7 @@ toxpwr = 0 taste_description = "sourness" pH = 11 + value = REAGENT_VALUE_UNCOMMON /datum/reagent/toxin/mindbreaker/on_mob_life(mob/living/carbon/M) M.hallucination += 5 @@ -226,6 +237,7 @@ toxpwr = 1 taste_mult = 1 pH = 2.7 + value = REAGENT_VALUE_NONE /datum/reagent/toxin/plantbgone/reaction_obj(obj/O, reac_volume) if(istype(O, /obj/structure/alien/weeds)) @@ -250,6 +262,7 @@ description = "A harmful toxic mixture to kill weeds. Do not ingest!" color = "#4B004B" // rgb: 75, 0, 75 pH = 3 + value = REAGENT_VALUE_NONE /datum/reagent/toxin/pestkiller name = "Pest Killer" @@ -257,6 +270,7 @@ color = "#4B004B" // rgb: 75, 0, 75 toxpwr = 1 pH = 3.2 + value = REAGENT_VALUE_NONE /datum/reagent/toxin/pestkiller/reaction_mob(mob/living/M, method=TOUCH, reac_volume) ..() @@ -270,6 +284,7 @@ color = "#9ACD32" toxpwr = 1 pH = 11 + value = REAGENT_VALUE_RARE /datum/reagent/toxin/spore/on_mob_life(mob/living/carbon/C) C.damageoverlaytemp = 60 @@ -284,6 +299,7 @@ toxpwr = 0.5 taste_description = "burning" pH = 13 + value = REAGENT_VALUE_VERY_RARE /datum/reagent/toxin/spore_burning/on_mob_life(mob/living/carbon/M) M.adjust_fire_stacks(2) @@ -323,6 +339,7 @@ glass_name = "glass of beer" glass_desc = "A freezing pint of beer." pH = 2 + value = REAGENT_VALUE_VERY_RARE /datum/reagent/toxin/fakebeer/on_mob_life(mob/living/carbon/M) switch(current_cycle) @@ -340,6 +357,7 @@ color = "#5B2E0D" // rgb: 91, 46, 13 toxpwr = 0.5 pH = 4.2 + value = REAGENT_VALUE_VERY_COMMON /datum/reagent/toxin/teapowder name = "Ground Tea Leaves" @@ -348,6 +366,7 @@ color = "#7F8400" // rgb: 127, 132, 0 toxpwr = 0.5 pH = 4.9 + value = REAGENT_VALUE_VERY_COMMON /datum/reagent/toxin/mutetoxin //the new zombie powder. name = "Mute Toxin" @@ -367,6 +386,7 @@ color = "#6E2828" data = 15 toxpwr = 0 + value = REAGENT_VALUE_UNCOMMON /datum/reagent/toxin/staminatoxin/on_mob_life(mob/living/carbon/M) M.adjustStaminaLoss(REM * data, 0) @@ -381,6 +401,7 @@ color = "#787878" metabolization_rate = 0.125 * REAGENTS_METABOLISM toxpwr = 0 + value = REAGENT_VALUE_VERY_RARE /datum/reagent/toxin/polonium/on_mob_life(mob/living/carbon/M) M.radiation += 4 @@ -394,6 +415,7 @@ metabolization_rate = 0.25 * REAGENTS_METABOLISM overdose_threshold = 30 toxpwr = 0 + value = REAGENT_VALUE_UNCOMMON /datum/reagent/toxin/histamine/on_mob_life(mob/living/carbon/M) if(prob(50)) @@ -441,6 +463,7 @@ color = "#F0FFF0" metabolization_rate = 0.25 * REAGENTS_METABOLISM toxpwr = 0 + value = REAGENT_VALUE_VERY_RARE /datum/reagent/toxin/venom/on_mob_life(mob/living/carbon/M) toxpwr = 0.2*volume @@ -476,6 +499,7 @@ color = "#00B4FF" metabolization_rate = 0.125 * REAGENTS_METABOLISM toxpwr = 1.25 + value = REAGENT_VALUE_UNCOMMON /datum/reagent/toxin/cyanide/on_mob_life(mob/living/carbon/M) if(prob(5)) @@ -494,6 +518,7 @@ metabolization_rate = 0.25 * REAGENTS_METABOLISM toxpwr = 0.5 taste_description = "bad cooking" + value = REAGENT_VALUE_NONE /datum/reagent/toxin/condensed_cooking_oil name = "Condensed Cooking Oil" @@ -504,6 +529,7 @@ toxpwr = 0 taste_mult = -2 taste_description = "awful cooking" + value = REAGENT_VALUE_NONE /datum/reagent/toxin/condensed_cooking_oil/on_mob_life(mob/living/carbon/M) if(prob(5)) @@ -551,6 +577,7 @@ color = "#7F10C0" metabolization_rate = 0.5 * REAGENTS_METABOLISM toxpwr = 2.5 + value = REAGENT_VALUE_EXCEPTIONAL /datum/reagent/toxin/initropidril/on_mob_life(mob/living/carbon/C) if(prob(25)) @@ -582,6 +609,7 @@ metabolization_rate = 0.25 * REAGENTS_METABOLISM toxpwr = 0 taste_mult = 0 // undetectable, I guess? + value = REAGENT_VALUE_VERY_RARE /datum/reagent/toxin/pancuronium/on_mob_life(mob/living/carbon/M) if(current_cycle >= 10) @@ -598,6 +626,7 @@ color = "#6496FA" metabolization_rate = 0.75 * REAGENTS_METABOLISM toxpwr = 0 + value = REAGENT_VALUE_VERY_RARE /datum/reagent/toxin/sodium_thiopental/on_mob_life(mob/living/carbon/M) if(current_cycle >= 10) @@ -626,6 +655,7 @@ color = "#FFFFFF" toxpwr = 0 metabolization_rate = 0.5 * REAGENTS_METABOLISM + value = REAGENT_VALUE_RARE /datum/reagent/toxin/amanitin/on_mob_end_metabolize(mob/living/M) var/toxdamage = current_cycle*3*REM @@ -656,6 +686,7 @@ color = "#7DC3A0" metabolization_rate = 0.06 * REAGENTS_METABOLISM toxpwr = 1.75 + value = REAGENT_VALUE_EXCEPTIONAL /datum/reagent/toxin/coniine/on_mob_life(mob/living/carbon/M) M.losebreath += 5 @@ -670,6 +701,7 @@ overdose_threshold = 29 toxpwr = 0 taste_description = "vomit" + value = REAGENT_VALUE_VERY_RARE /datum/reagent/toxin/spewium/on_mob_life(mob/living/carbon/C) .=..() @@ -693,6 +725,7 @@ color = "#191919" metabolization_rate = 0.125 * REAGENTS_METABOLISM toxpwr = 1 + value = REAGENT_VALUE_VERY_RARE /datum/reagent/toxin/curare/on_mob_life(mob/living/carbon/M) if(current_cycle >= 11) @@ -708,6 +741,7 @@ color = "#C8C8C8" //RGB: 200, 200, 200 metabolization_rate = 0.2 * REAGENTS_METABOLISM toxpwr = 0 + value = REAGENT_VALUE_VERY_RARE /datum/reagent/toxin/heparin/on_mob_life(mob/living/carbon/M) if(ishuman(M)) @@ -726,6 +760,7 @@ metabolization_rate = 0.6 * REAGENTS_METABOLISM toxpwr = 0.5 taste_description = "spinning" + value = REAGENT_VALUE_VERY_RARE /datum/reagent/toxin/rotatium/on_mob_life(mob/living/carbon/M) if(M.hud_used) @@ -752,6 +787,7 @@ metabolization_rate = 0.8 * REAGENTS_METABOLISM toxpwr = 0.25 taste_description = "skewing" + value = REAGENT_VALUE_EXCEPTIONAL /datum/reagent/toxin/skewium/on_mob_life(mob/living/carbon/M) /* @@ -788,6 +824,7 @@ color = "#3C5133" metabolization_rate = 0.08 * REAGENTS_METABOLISM toxpwr = 0.15 + value = REAGENT_VALUE_VERY_RARE /datum/reagent/toxin/anacea/on_mob_life(mob/living/carbon/M) var/remove_amt = 5 @@ -809,6 +846,7 @@ taste_description = "acid" self_consuming = TRUE pH = 2.75 + value = REAGENT_VALUE_NONE /datum/reagent/toxin/acid/reaction_mob(mob/living/carbon/C, method=TOUCH, reac_volume) if(!istype(C)) @@ -840,6 +878,7 @@ color = "#5050FF" toxpwr = 2 acidpwr = 42.0 + value = REAGENT_VALUE_COMMON /datum/reagent/toxin/acid/fluacid/on_mob_life(mob/living/carbon/M) M.adjustFireLoss(current_cycle/10, 0) @@ -853,6 +892,7 @@ metabolization_rate = 0 //stays in the system until active. var/actual_metaboliztion_rate = REAGENTS_METABOLISM toxpwr = 0 + value = REAGENT_VALUE_VERY_RARE var/actual_toxpwr = 5 var/delay = 30 @@ -871,6 +911,7 @@ color = "#F0F8FF" // rgb: 240, 248, 255 toxpwr = 0 taste_description = "stillness" + value = REAGENT_VALUE_RARE /datum/reagent/toxin/mimesbane/on_mob_metabolize(mob/living/L) ADD_TRAIT(L, TRAIT_EMOTEMUTE, type) @@ -885,6 +926,7 @@ toxpwr = 0 taste_description = "bone hurting" overdose_threshold = 20 + value = REAGENT_VALUE_VERY_RARE //because it's very funny. /datum/reagent/toxin/bonehurtingjuice/on_mob_add(mob/living/carbon/M) M.say("oof ouch my bones", forced = /datum/reagent/toxin/bonehurtingjuice) @@ -944,6 +986,7 @@ toxpwr = 0 taste_description = "brain hurting" metabolization_rate = 5 + value = REAGENT_VALUE_EXCEPTIONAL /datum/reagent/toxin/brainhurtingjuice/on_mob_life(mob/living/carbon/M) if(prob(50)) @@ -962,6 +1005,7 @@ metabolization_rate = 0.5 * REAGENTS_METABOLISM toxpwr = 0 taste_description = "tannin" + value = REAGENT_VALUE_RARE /datum/reagent/toxin/bungotoxin/on_mob_life(mob/living/carbon/M) M.adjustOrganLoss(ORGAN_SLOT_HEART, 3) diff --git a/modular_citadel/code/datums/status_effects/chems.dm b/modular_citadel/code/datums/status_effects/chems.dm index 369fb377a5..99d4c2cd2f 100644 --- a/modular_citadel/code/datums/status_effects/chems.dm +++ b/modular_citadel/code/datums/status_effects/chems.dm @@ -280,7 +280,7 @@ var/mob/living/carbon/M = owner //chem calculations - if(!owner.reagents.has_reagent(/datum/chemical_reaction/fermi/enthrall) && !owner.reagents.has_reagent(/datum/reagent/fermi/enthrall/test)) + if(!owner.reagents.has_reagent(/datum/chemical_reaction/fermi/enthrall)) if (phase < 3 && phase != 0) deltaResist += 3//If you've no chem, then you break out quickly if(prob(5)) diff --git a/modular_citadel/code/modules/reagents/chemistry/reagents/MKUltra.dm b/modular_citadel/code/modules/reagents/chemistry/reagents/MKUltra.dm index 2364c617f0..89a7f58cee 100644 --- a/modular_citadel/code/modules/reagents/chemistry/reagents/MKUltra.dm +++ b/modular_citadel/code/modules/reagents/chemistry/reagents/MKUltra.dm @@ -144,20 +144,7 @@ Creating a chem with a low purity will make you permanently fall in love with so pH = 10 chemical_flags = REAGENT_ONMOBMERGE | REAGENT_DONOTSPLIT //Procs on_mob_add when merging into a human can_synth = FALSE - - -/datum/reagent/fermi/enthrall/test - name = "MKUltraTest" - description = "A forbidden deep red mixture that makes you like Fermis a little too much. Unobtainable and due to be removed from the wiki." - data = list("creatorID" = "honkatonkbramblesnatch", "creatorGender" = "Mistress", "creatorName" = "Fermis Yakumo") - creatorID = "honkatonkbramblesnatch"//ckey - creatorGender = "Mistress" - creatorName = "Fermis Yakumo" - purity = 1 - -/datum/reagent/fermi/enthrall/test/on_new() - ..() - creator = get_mob_by_key(creatorID) + value = REAGENT_VALUE_EXCEPTIONAL /datum/reagent/fermi/enthrall/on_new(list/data) creatorID = data["creatorID"] diff --git a/modular_citadel/code/modules/reagents/chemistry/reagents/SDGF.dm b/modular_citadel/code/modules/reagents/chemistry/reagents/SDGF.dm index 5f9ea5924d..894db1ee27 100644 --- a/modular_citadel/code/modules/reagents/chemistry/reagents/SDGF.dm +++ b/modular_citadel/code/modules/reagents/chemistry/reagents/SDGF.dm @@ -52,6 +52,7 @@ IMPORTANT FACTORS TO CONSIDER WHILE BALANCING inverse_chem_val = 0.5 inverse_chem = /datum/reagent/impure/SDZF can_synth = TRUE + value = REAGENT_VALUE_EXCEPTIONAL //Main SDGF chemical @@ -309,6 +310,7 @@ IMPORTANT FACTORS TO CONSIDER WHILE BALANCING can_synth = TRUE taste_description = "a weird chemical fleshy flavour" chemical_flags = REAGENT_SNEAKYNAME + value = REAGENT_VALUE_VERY_RARE /datum/reagent/impure/SDZF/on_mob_life(mob/living/carbon/M) //If you're bad at fermichem, turns your clone into a zombie instead. switch(current_cycle)//Pretends to be normal diff --git a/modular_citadel/code/modules/reagents/chemistry/reagents/astrogen.dm b/modular_citadel/code/modules/reagents/chemistry/reagents/astrogen.dm index a8ac66ef20..8348569fbb 100644 --- a/modular_citadel/code/modules/reagents/chemistry/reagents/astrogen.dm +++ b/modular_citadel/code/modules/reagents/chemistry/reagents/astrogen.dm @@ -30,6 +30,7 @@ I'd like to point out from my calculations it'll take about 60-80 minutes to die inverse_chem_val = 0.25 can_synth = FALSE var/datum/action/chem/astral/AS = new/datum/action/chem/astral() + value = REAGENT_VALUE_AMAZING /datum/action/chem/astral name = "Return to body" diff --git a/modular_citadel/code/modules/reagents/chemistry/reagents/eigentstasium.dm b/modular_citadel/code/modules/reagents/chemistry/reagents/eigentstasium.dm index e0b7a6fa14..28645cdc7b 100644 --- a/modular_citadel/code/modules/reagents/chemistry/reagents/eigentstasium.dm +++ b/modular_citadel/code/modules/reagents/chemistry/reagents/eigentstasium.dm @@ -29,6 +29,7 @@ var/teleBool = FALSE pH = 3.7 can_synth = TRUE + value = REAGENT_VALUE_EXCEPTIONAL /datum/reagent/fermi/eigenstate/on_new(list/data) location_created = data["location_created"] diff --git a/modular_citadel/code/modules/reagents/chemistry/reagents/enlargement.dm b/modular_citadel/code/modules/reagents/chemistry/reagents/enlargement.dm index 97261e07f2..7403de6215 100644 --- a/modular_citadel/code/modules/reagents/chemistry/reagents/enlargement.dm +++ b/modular_citadel/code/modules/reagents/chemistry/reagents/enlargement.dm @@ -29,6 +29,7 @@ inverse_chem_val = 0.35 inverse_chem = /datum/reagent/fermi/BEsmaller //At really impure vols, it just becomes 100% inverse can_synth = FALSE + value = REAGENT_VALUE_VERY_RARE var/message_spam = FALSE /datum/reagent/fermi/breast_enlarger/on_mob_metabolize(mob/living/M) @@ -126,6 +127,7 @@ taste_description = "a milky ice cream like flavour." metabolization_rate = 0.25 can_synth = FALSE + value = REAGENT_VALUE_RARE /datum/reagent/fermi/BEsmaller/on_mob_life(mob/living/carbon/M) var/obj/item/organ/genital/breasts/B = M.getorganslot(ORGAN_SLOT_BREASTS) @@ -186,6 +188,7 @@ inverse_chem_val = 0.35 inverse_chem = /datum/reagent/fermi/PEsmaller //At really impure vols, it just becomes 100% inverse and shrinks instead. can_synth = FALSE + value = REAGENT_VALUE_VERY_RARE var/message_spam = FALSE /datum/reagent/fermi/penis_enlarger/on_mob_metabolize(mob/living/M) @@ -273,6 +276,7 @@ taste_description = "chinese dragon powder" metabolization_rate = 0.5 can_synth = FALSE + value = REAGENT_VALUE_RARE /datum/reagent/fermi/PEsmaller/on_mob_life(mob/living/carbon/M) if(!ishuman(M)) diff --git a/modular_citadel/code/modules/reagents/chemistry/reagents/healing.dm b/modular_citadel/code/modules/reagents/chemistry/reagents/healing.dm index d98ec7059d..ac29f1a019 100644 --- a/modular_citadel/code/modules/reagents/chemistry/reagents/healing.dm +++ b/modular_citadel/code/modules/reagents/chemistry/reagents/healing.dm @@ -9,6 +9,7 @@ inverse_chem_val = 0.4 inverse_chem = /datum/reagent/impure/yamerol_tox can_synth = TRUE + value = REAGENT_VALUE_VERY_RARE /datum/reagent/fermi/yamerol/on_mob_life(mob/living/carbon/C) var/obj/item/organ/tongue/T = C.getorganslot(ORGAN_SLOT_TONGUE) @@ -100,6 +101,7 @@ data = list("grown_volume" = 0, "injected_vol" = 0) var/borrowed_health color = "#FFDADA" + value = REAGENT_VALUE_VERY_RARE /datum/reagent/synthtissue/reaction_mob(mob/living/M, method=TOUCH, reac_volume,show_message = 1) if(iscarbon(M)) diff --git a/modular_citadel/code/modules/reagents/chemistry/reagents/other_reagents.dm b/modular_citadel/code/modules/reagents/chemistry/reagents/other_reagents.dm deleted file mode 100644 index 87f9d71ce2..0000000000 --- a/modular_citadel/code/modules/reagents/chemistry/reagents/other_reagents.dm +++ /dev/null @@ -1,32 +0,0 @@ -/datum/reagent/syndicateadrenals - name = "Syndicate Adrenaline" - description = "Regenerates your stamina and increases your reaction time." - color = "#E62111" - overdose_threshold = 6 - -/datum/reagent/syndicateadrenals/on_mob_life(mob/living/M) - M.adjustStaminaLoss(-5*REM) - . = ..() - -/datum/reagent/syndicateadrenals/on_mob_metabolize(mob/living/M) - . = ..() - if(istype(M)) - M.next_move_modifier *= 0.5 - to_chat(M, "You feel an intense surge of energy rushing through your veins.") - -/datum/reagent/syndicateadrenals/on_mob_end_metabolize(mob/living/M) - . = ..() - if(istype(M)) - M.next_move_modifier *= 2 - to_chat(M, "You feel as though the world around you is going faster.") - -/datum/reagent/syndicateadrenals/overdose_start(mob/living/M) - to_chat(M, "You feel an intense pain in your chest...") - return - -/datum/reagent/syndicateadrenals/overdose_process(mob/living/M) - if(iscarbon(M)) - var/mob/living/carbon/C = M - if(!C.undergoing_cardiac_arrest()) - C.set_heartattack(TRUE) - return diff --git a/tgstation.dme b/tgstation.dme index 7bfbd2dde2..3791f2c024 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -3341,7 +3341,6 @@ #include "modular_citadel\code\modules\reagents\chemistry\reagents\fermi_reagents.dm" #include "modular_citadel\code\modules\reagents\chemistry\reagents\healing.dm" #include "modular_citadel\code\modules\reagents\chemistry\reagents\MKUltra.dm" -#include "modular_citadel\code\modules\reagents\chemistry\reagents\other_reagents.dm" #include "modular_citadel\code\modules\reagents\chemistry\reagents\SDGF.dm" #include "modular_citadel\code\modules\reagents\chemistry\recipes\fermi.dm" #include "modular_citadel\code\modules\reagents\objects\clothes.dm" From de531bd04703c85cf8125214df7b1ef1dc53b37a Mon Sep 17 00:00:00 2001 From: Ghommie <42542238+Ghommie@users.noreply.github.com> Date: Thu, 23 Apr 2020 21:47:54 +0200 Subject: [PATCH 37/55] porting CEV-Eris pickweight procs. --- code/__HELPERS/_lists.dm | 74 +++++++++++++++---- code/controllers/subsystem/vote.dm | 2 +- code/datums/ai_laws.dm | 2 +- code/game/gamemodes/game_mode.dm | 2 +- code/game/objects/effects/landmarks.dm | 2 +- .../antagonists/traitor/datum_traitor.dm | 2 +- 6 files changed, 64 insertions(+), 20 deletions(-) diff --git a/code/__HELPERS/_lists.dm b/code/__HELPERS/_lists.dm index a34b3ce67c..0acd00f1f9 100644 --- a/code/__HELPERS/_lists.dm +++ b/code/__HELPERS/_lists.dm @@ -231,40 +231,77 @@ //Picks a random element from a list based on a weighting system: //1. Adds up the total of weights for each element -//2. Gets a number between 1 and that total +//2. Gets the total from 0% to 100% of previous total value. //3. For each element in the list, subtracts its weighting from that number //4. If that makes the number 0 or less, return that element. -/proc/pickweight(list/L) +/proc/pickweight(list/L, base_weight = 1) var/total = 0 var/item for (item in L) if (!L[item]) - L[item] = 1 + L[item] = base_weight total += L[item] - total = rand(1, total) + total = rand() * total for (item in L) - total -=L [item] + total -= L[item] if (total <= 0) return item - return null - -/proc/pickweightAllowZero(list/L) //The original pickweight proc will sometimes pick entries with zero weight. I'm not sure if changing the original will break anything, so I left it be. +//Picks a number of elements from a list based on weight. +//This is highly optimised and good for things like grabbing 200 items from a list of 40,000 +//Much more efficient than many pickweight calls +/proc/pickweight_mult(list/L, quantity, base_weight = 1) + //First we total the list as normal var/total = 0 var/item for (item in L) if (!L[item]) - L[item] = 0 + L[item] = base_weight total += L[item] - total = rand(0, total) - for (item in L) - total -=L [item] - if (total <= 0 && L[item]) - return item + //Next we will make a list of randomly generated numbers, called Requests + //It is critical that this list be sorted in ascending order, so we will build it in that order + //First one is free, so we start counting at 2 + var/list/requests = list(rand(1, total)) + for (var/i in 2 to quantity) + //Each time we generate the next request + var/newreq = rand()* total + //We will loop through all existing requests + for (var/j in 1 to requests.len) + //We keep going through the list until we find an element which is bigger than the one we want to add + if (requests[j] > newreq) + //And then we insert the newqreq at that point, pushing everything else forward + requests.Insert(j, newreq) + break - return null + + + //Now when we get here, we have a list of random numbers sorted in ascending order. + //The length of that list is equal to Quantity passed into this function + //Next we make a list to store results + var/list/results = list() + + //Zero the total, we'll reuse it + total = 0 + + //Now we will iterate forward through the items list, adding each weight to the total + for (item in L) + total += L[item] + + //After each item we do a while loop + while (requests.len && total >= requests[1]) + //If the total is higher than the value of the first request + results += item //We add this item to the results list + requests.Cut(1,2) //And we cut off the top of the requests list + + //This while loop will repeat until the next request is higher than the total. + //The current item might be added to the results list many times, in this process + + //By the time we get here: + //Requests will be empty + //Results will have a length of quality + return results //Pick a random element from the list and remove it from the list. /proc/pick_n_take(list/L) @@ -274,6 +311,13 @@ . = L[picked] L.Cut(picked,picked+1) //Cut is far more efficient that Remove() +//Pick a random element from the list by weight and remove it from the list. +//Result is returned as a list in the format list(key, value) +/proc/pickweight_n_take(list/L, base_weight = 1) + if (L.len) + . = pickweight(L, base_weight) + L.Remove(.) + //Returns the top(last) element from the list and removes it from the list (typical stack function) /proc/pop(list/L) if(L.len) diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm index a202afd905..df3f24f0dc 100644 --- a/code/controllers/subsystem/vote.dm +++ b/code/controllers/subsystem/vote.dm @@ -361,7 +361,7 @@ SUBSYSTEM_DEF(vote) picked = S runnable_storytellers[S] *= round(stored_gamemode_votes[initial(S.name)]*100000,1) if(!picked) - picked = pickweightAllowZero(runnable_storytellers) + picked = pickweight(runnable_storytellers, 0) GLOB.dynamic_storyteller_type = picked if("map") var/datum/map_config/VM = config.maplist[.] diff --git a/code/datums/ai_laws.dm b/code/datums/ai_laws.dm index ebddc187ae..9c6bb2ebfd 100644 --- a/code/datums/ai_laws.dm +++ b/code/datums/ai_laws.dm @@ -253,7 +253,7 @@ var/datum/ai_laws/lawtype var/list/law_weights = CONFIG_GET(keyed_list/law_weight) while(!lawtype && law_weights.len) - var/possible_id = pickweightAllowZero(law_weights) + var/possible_id = pickweight(law_weights, 0) lawtype = lawid_to_type(possible_id) if(!lawtype) law_weights -= possible_id diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm index 5affeba6d6..57919863f2 100644 --- a/code/game/gamemodes/game_mode.dm +++ b/code/game/gamemodes/game_mode.dm @@ -272,7 +272,7 @@ reports += config.mode_reports[config_tag] Count++ for(var/i in Count to rand(3,5)) //Between three and five wrong entries on the list. - var/false_report_type = pickweightAllowZero(report_weights) + var/false_report_type = pickweight(report_weights, 0) report_weights[false_report_type] = 0 //Make it so the same false report won't be selected twice reports += config.mode_reports[false_report_type] diff --git a/code/game/objects/effects/landmarks.dm b/code/game/objects/effects/landmarks.dm index 04f14692e3..851a041aab 100644 --- a/code/game/objects/effects/landmarks.dm +++ b/code/game/objects/effects/landmarks.dm @@ -483,7 +483,7 @@ INITIALIZE_IMMEDIATE(/obj/effect/landmark/start/new_player) if(!SSmapping.station_room_templates[t]) log_world("Station room spawner placed at ([T.x], [T.y], [T.z]) has invalid ruin name of \"[t]\" in its list") templates -= t - template_name = pickweightAllowZero(templates) + template_name = pickweight(templates, 0) if(!template_name) GLOB.stationroom_landmarks -= src qdel(src) diff --git a/code/modules/antagonists/traitor/datum_traitor.dm b/code/modules/antagonists/traitor/datum_traitor.dm index cf10f87bf8..df5e6004ba 100644 --- a/code/modules/antagonists/traitor/datum_traitor.dm +++ b/code/modules/antagonists/traitor/datum_traitor.dm @@ -48,7 +48,7 @@ var/datum/traitor_class/class = GLOB.traitor_classes[C] var/weight = LOGISTIC_FUNCTION(1.5*class.weight,chaos_weight,class.chaos,0) weights[C] = weight * 1000 - var/choice = pickweightAllowZero(weights) + var/choice = pickweight(weights, 0) if(!choice) choice = TRAITOR_HUMAN // it's an "easter egg" var/datum/traitor_class/actual_class = GLOB.traitor_classes[choice] From 83ba5c1b9b1015faaf91f3b2745326f08b70cd12 Mon Sep 17 00:00:00 2001 From: Trilbyspaceclone <30435998+Trilbyspaceclone@users.noreply.github.com> Date: Thu, 23 Apr 2020 16:52:24 -0400 Subject: [PATCH 38/55] Update venus_human_trap.dm --- .../mob/living/simple_animal/hostile/venus_human_trap.dm | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/code/modules/mob/living/simple_animal/hostile/venus_human_trap.dm b/code/modules/mob/living/simple_animal/hostile/venus_human_trap.dm index cbfa7780da..5111b0b180 100644 --- a/code/modules/mob/living/simple_animal/hostile/venus_human_trap.dm +++ b/code/modules/mob/living/simple_animal/hostile/venus_human_trap.dm @@ -95,7 +95,10 @@ /// How far away a plant can attach a vine to something var/vine_grab_distance = 5 /// Whether or not this plant is ghost possessable - var/playable_plant = TRUE + var/playable_plant = FALSE //Normal plants can **not** have players. + +/mob/living/simple_animal/hostile/venus_human_trap/ghost_playable + playable_plant = TRUE //For admins that want to buss some harmless plants /mob/living/simple_animal/hostile/venus_human_trap/Life() . = ..() @@ -149,6 +152,7 @@ * Arguments: * * mob/user - The ghost to possibly control the plant */ + /mob/living/simple_animal/hostile/venus_human_trap/proc/humanize_plant(mob/user) if(key || !playable_plant || stat) return From e0a51903a1c32c7934e32a0b71f18df77078b6f3 Mon Sep 17 00:00:00 2001 From: Ghommie <42542238+Ghommie@users.noreply.github.com> Date: Fri, 24 Apr 2020 00:51:04 +0200 Subject: [PATCH 39/55] Not yet implemented design security level requirements. --- _maps/RandomRuins/SpaceRuins/oldstation.dmm | 6 +- code/__DEFINES/misc.dm | 8 --- code/__DEFINES/security_levels.dm | 10 ++++ code/controllers/subsystem/shuttle.dm | 8 +-- code/datums/world_topic.dm | 2 +- code/game/gamemodes/gangs/dominator.dm | 2 +- code/game/machinery/autolathe.dm | 5 -- .../game/machinery/computer/communications.dm | 12 ++-- code/game/mecha/mech_fabricator.dm | 32 +++++++++- code/game/objects/items.dm | 8 +++ .../circuitboards/machine_circuitboards.dm | 21 +++++++ code/game/objects/items/storage/boxes.dm | 4 +- code/game/world.dm | 4 +- code/modules/antagonists/cult/cult_items.dm | 2 +- .../nukeop/equipment/nuclearbomb.dm | 4 +- .../modules/mob/living/silicon/robot/robot.dm | 2 +- code/modules/research/designs.dm | 3 + .../modules/research/machinery/_production.dm | 25 +++++++- .../research/machinery/circuit_imprinter.dm | 6 ++ code/modules/research/machinery/protolathe.dm | 9 +++ code/modules/research/rdconsole.dm | 17 +++++- .../security_levels/keycard_authentication.dm | 2 +- .../security_levels/security_levels.dm | 60 +++---------------- code/modules/shuttle/emergency.dm | 2 +- tgstation.dme | 1 + 25 files changed, 157 insertions(+), 98 deletions(-) create mode 100644 code/__DEFINES/security_levels.dm diff --git a/_maps/RandomRuins/SpaceRuins/oldstation.dmm b/_maps/RandomRuins/SpaceRuins/oldstation.dmm index e820b06f61..89e2c553b9 100644 --- a/_maps/RandomRuins/SpaceRuins/oldstation.dmm +++ b/_maps/RandomRuins/SpaceRuins/oldstation.dmm @@ -1651,7 +1651,7 @@ /turf/open/floor/plasteel/white, /area/ruin/space/has_grav/ancientstation/rnd) "eD" = ( -/obj/machinery/mecha_part_fabricator, +/obj/machinery/mecha_part_fabricator/offstation, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel/white, /area/ruin/space/has_grav/ancientstation/rnd) @@ -2010,12 +2010,12 @@ /turf/open/floor/plasteel, /area/ruin/space/has_grav/ancientstation/deltacorridor) "fu" = ( -/obj/machinery/rnd/production/protolathe, +/obj/machinery/rnd/production/protolathe/offstation, /obj/effect/decal/cleanable/dirt, /turf/open/floor/plasteel/white, /area/ruin/space/has_grav/ancientstation/rnd) "fv" = ( -/obj/machinery/rnd/production/circuit_imprinter, +/obj/machinery/rnd/production/circuit_imprinter/offstation, /obj/effect/decal/cleanable/dirt, /obj/item/reagent_containers/dropper, /turf/open/floor/plasteel/white, diff --git a/code/__DEFINES/misc.dm b/code/__DEFINES/misc.dm index 3fb149d071..37633ae52f 100644 --- a/code/__DEFINES/misc.dm +++ b/code/__DEFINES/misc.dm @@ -71,14 +71,6 @@ Will print: "/mob/living/carbon/human/death" (you can optionally embed it in a s #define ABOVE_SHOES_LAYER (SHOES_LAYER-1) #define ABOVE_BODY_FRONT_LAYER (BODY_FRONT_LAYER-1) - -//Security levels -#define SEC_LEVEL_GREEN 0 -#define SEC_LEVEL_BLUE 1 -#define SEC_LEVEL_AMBER 2 -#define SEC_LEVEL_RED 3 -#define SEC_LEVEL_DELTA 4 - //some arbitrary defines to be used by self-pruning global lists. (see master_controller) #define PROCESS_KILL 26 //Used to trigger removal from a processing list diff --git a/code/__DEFINES/security_levels.dm b/code/__DEFINES/security_levels.dm new file mode 100644 index 0000000000..19c66d9125 --- /dev/null +++ b/code/__DEFINES/security_levels.dm @@ -0,0 +1,10 @@ +//Security levels +#define SEC_LEVEL_GREEN 1 +#define SEC_LEVEL_BLUE 2 +#define SEC_LEVEL_AMBER 3 +#define SEC_LEVEL_RED 4 +#define SEC_LEVEL_DELTA 5 + +//Macro helpers. +#define SECLEVEL2NUM(text) (GLOB.all_security_levels.Find(text)) +#define NUM2SECLEVEL(num) (ISINRANGE(num, 1, length(GLOB.all_security_levels)) ? GLOB.all_security_levels[num] : null) diff --git a/code/controllers/subsystem/shuttle.dm b/code/controllers/subsystem/shuttle.dm index e4a3ff1f9a..58d73ded68 100644 --- a/code/controllers/subsystem/shuttle.dm +++ b/code/controllers/subsystem/shuttle.dm @@ -217,13 +217,13 @@ SUBSYSTEM_DEF(shuttle) call_reason = trim(html_encode(call_reason)) - if(length(call_reason) < CALL_SHUTTLE_REASON_LENGTH && seclevel2num(get_security_level()) > SEC_LEVEL_GREEN) + if(length(call_reason) < CALL_SHUTTLE_REASON_LENGTH && SECLEVEL2NUM(NUM2SECLEVEL(GLOB.security_level)) > SEC_LEVEL_GREEN) to_chat(user, "You must provide a reason.") return var/area/signal_origin = get_area(user) var/emergency_reason = "\nNature of emergency:\n\n[call_reason]" - var/security_num = seclevel2num(get_security_level()) + var/security_num = SECLEVEL2NUM(NUM2SECLEVEL(GLOB.security_level)) switch(security_num) if(SEC_LEVEL_RED,SEC_LEVEL_DELTA) emergency.request(null, signal_origin, html_decode(emergency_reason), 1) //There is a serious threat we gotta move no time to give them five minutes. @@ -285,7 +285,7 @@ SUBSYSTEM_DEF(shuttle) /datum/controller/subsystem/shuttle/proc/canRecall() if(!emergency || emergency.mode != SHUTTLE_CALL || emergencyNoRecall || SSticker.mode.name == "meteor") return - var/security_num = seclevel2num(get_security_level()) + var/security_num = SECLEVEL2NUM(NUM2SECLEVEL(GLOB.security_level)) switch(security_num) if(SEC_LEVEL_GREEN) if(emergency.timeLeft(1) < emergencyCallTime) @@ -642,7 +642,7 @@ SUBSYSTEM_DEF(shuttle) /datum/controller/subsystem/shuttle/proc/autoEnd() //CIT CHANGE - allows shift to end without being a proper shuttle call? if(EMERGENCY_IDLE_OR_RECALLED) SSshuttle.emergency.request(silent = TRUE) - priority_announce("The shift has come to an end and the shuttle called. [seclevel2num(get_security_level()) == SEC_LEVEL_RED ? "Red Alert state confirmed: Dispatching priority shuttle. " : "" ]It will arrive in [emergency.timeLeft(600)] minutes.", null, "shuttlecalled", "Priority") + priority_announce("The shift has come to an end and the shuttle called. [SECLEVEL2NUM(NUM2SECLEVEL(GLOB.security_level)) == SEC_LEVEL_RED ? "Red Alert state confirmed: Dispatching priority shuttle. " : "" ]It will arrive in [emergency.timeLeft(600)] minutes.", null, "shuttlecalled", "Priority") log_game("Round end vote passed. Shuttle has been auto-called.") message_admins("Round end vote passed. Shuttle has been auto-called.") emergencyNoRecall = TRUE diff --git a/code/datums/world_topic.dm b/code/datums/world_topic.dm index c2855250f4..30699d36f4 100644 --- a/code/datums/world_topic.dm +++ b/code/datums/world_topic.dm @@ -169,7 +169,7 @@ .["real_mode"] = SSticker.mode.name // Key-authed callers may know the truth behind the "secret" - .["security_level"] = get_security_level() + .["security_level"] = NUM2SECLEVEL(GLOB.security_level) .["round_duration"] = SSticker ? round((world.time-SSticker.round_start_time)/10) : 0 // Amount of world's ticks in seconds, useful for calculating round duration diff --git a/code/game/gamemodes/gangs/dominator.dm b/code/game/gamemodes/gangs/dominator.dm index 858c10c46c..dca50be5b9 100644 --- a/code/game/gamemodes/gangs/dominator.dm +++ b/code/game/gamemodes/gangs/dominator.dm @@ -229,7 +229,7 @@ if(!was_stranded) priority_announce("All hostile activity within station systems has ceased.","Network Alert") - if(get_security_level() == "delta") + if(NUM2SECLEVEL(GLOB.security_level) == "delta") set_security_level("red") SSshuttle.clearHostileEnvironment(src) diff --git a/code/game/machinery/autolathe.dm b/code/game/machinery/autolathe.dm index 8b3958e606..64704d4771 100644 --- a/code/game/machinery/autolathe.dm +++ b/code/game/machinery/autolathe.dm @@ -439,8 +439,3 @@ desc = "An autolathe reprogrammed with security protocols to prevent hacking." hackable = FALSE circuit = /obj/item/circuitboard/machine/autolathe/secure - -//Called when the object is constructed by an autolathe -//Has a reference to the autolathe so you can do !!FUN!! things with hacked lathes -/obj/item/proc/autolathe_crafted(obj/machinery/autolathe/A) - return diff --git a/code/game/machinery/computer/communications.dm b/code/game/machinery/computer/communications.dm index 4c3d85a162..6eb06e3be4 100755 --- a/code/game/machinery/computer/communications.dm +++ b/code/game/machinery/computer/communications.dm @@ -111,7 +111,7 @@ to_chat(usr, "Authorization confirmed. Modifying security level.") playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) //Only notify people if an actual change happened - var/security_level = get_security_level() + var/security_level = NUM2SECLEVEL(GLOB.security_level) log_game("[key_name(usr)] has changed the security level to [security_level] with [src] at [AREACOORD(usr)].") message_admins("[ADMIN_LOOKUPFLW(usr)] has changed the security level to [security_level] with [src] at [AREACOORD(usr)].") deadchat_broadcast("[usr.real_name] has changed the security level to [security_level] with [src] at [get_area_name(usr, TRUE)].", usr) @@ -404,7 +404,7 @@ security_level_cd = world.time + 15 SECONDS if(GLOB.security_level != old_level) //Only notify people if an actual change happened - var/security_level = get_security_level() + var/security_level = NUM2SECLEVEL(GLOB.security_level) log_game("[key_name(usr)] has changed the security level to [security_level] from [src] at [AREACOORD(usr)].") message_admins("[ADMIN_LOOKUPFLW(usr)] has changed the security level to [security_level] from [src] at [AREACOORD(usr)].") deadchat_broadcast("[usr.real_name] has changed the security level to [security_level] from [src] at [get_area_name(usr, TRUE)].", usr) @@ -555,7 +555,7 @@ dat += " Biohazard \]

" playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) if(STATE_ALERT_LEVEL) - dat += "Current alert level: [get_security_level()]
" + dat += "Current alert level: [NUM2SECLEVEL(GLOB.security_level)]
" if(GLOB.security_level == SEC_LEVEL_DELTA) dat += "The self-destruct mechanism is active. Find a way to deactivate the mechanism to lower the alert level or evacuate." else @@ -563,8 +563,8 @@ dat += "Blue
" dat += "Green" if(STATE_CONFIRM_LEVEL) - dat += "Current alert level: [get_security_level()]
" - dat += "Confirm the change to: [num2seclevel(tmp_alertlevel)]
" + dat += "Current alert level: [NUM2SECLEVEL(GLOB.security_level)]
" + dat += "Confirm the change to: [NUM2SECLEVEL(tmp_alertlevel)]
" dat += "Swipe ID to confirm change.
" if(STATE_TOGGLE_EMERGENCY) playsound(src, 'sound/machines/terminal_prompt.ogg', 50, 0) @@ -696,7 +696,7 @@ dat += " Biohazard \]

" if(STATE_ALERT_LEVEL) - dat += "Current alert level: [get_security_level()]
" + dat += "Current alert level: [NUM2SECLEVEL(GLOB.security_level)]
" if(GLOB.security_level == SEC_LEVEL_DELTA) dat += "The self-destruct mechanism is active. Find a way to deactivate the mechanism to lower the alert level or evacuate." else diff --git a/code/game/mecha/mech_fabricator.dm b/code/game/mecha/mech_fabricator.dm index 9acc8921b9..fb321665bc 100644 --- a/code/game/mecha/mech_fabricator.dm +++ b/code/game/mecha/mech_fabricator.dm @@ -19,6 +19,7 @@ var/processing_queue = 0 var/screen = "main" var/temp + var/offstation_security_levels = TRUE var/list/part_sets = list( "Cyborg", "Ripley", @@ -72,6 +73,8 @@ for(var/obj/item/stock_parts/manipulator/Ml in component_parts) T += Ml.rating time_coeff = round(initial(time_coeff) - (initial(time_coeff)*(T))/5,0.01) + var/obj/item/circuitboard/machine/mechfab/C = circuit + offstation_security_levels = C.offstation_security_levels /obj/machinery/mecha_part_fabricator/examine(mob/user) . = ..() @@ -106,13 +109,27 @@ if(!(set_name in D.category)) continue output += "
[output_part_info(D)]
\[" - if(check_resources(D)) + if(check_clearance(D) && check_resources(D)) output += "Build | " output += "Add to queue\]\[?\]
" return output +/obj/machinery/mecha_part_fabricator/proc/check_clearance(datum/design/D) + if(!(obj_flags & EMAGGED) && (offstation_security_levels || is_station_level(z)) && !ISINRANGE(GLOB.security_level, D.min_security_level, D.max_security_level)) + return FALSE + return TRUE + /obj/machinery/mecha_part_fabricator/proc/output_part_info(datum/design/D) - var/output = "[initial(D.name)] (Cost: [output_part_cost(D)]) [get_construction_time_w_coeff(D)/10]sec" + var/clearance = !(obj_flags & EMAGGED) && (offstation_security_levels || is_station_level(z)) + var/sec_text = "" + if(clearance && (D.min_security_level > SEC_LEVEL_GREEN || D.max_security_level < SEC_LEVEL_DELTA)) + sec_text = " (Allowed security levels: " + for(var/n in D.min_security_level to D.max_security_level) + sec_text += NUM2SECLEVEL(n) + if(n + 1 <= D.max_security_level) + sec_text += ", " + sec_text += ") " + var/output = "[initial(D.name)] (Cost: [output_part_cost(D)]) [sec_text][get_construction_time_w_coeff(D)/10]sec" return output /obj/machinery/mecha_part_fabricator/proc/output_part_cost(datum/design/D) @@ -216,6 +233,11 @@ while(D) if(stat&(NOPOWER|BROKEN)) return FALSE + if(!check_clearance(D)) + say("Security level not met. Queue processing stopped.") + temp = {"Security level not met to build next part.
+ Try again | Return"} + return FALSE if(!check_resources(D)) say("Not enough resources. Queue processing stopped.") temp = {"Not enough resources to build next part.
@@ -236,7 +258,7 @@ for(var/datum/design/D in queue) i++ var/obj/part = D.build_path - output += "" + output += "" output += initial(part.name) + " - " output += "[i>1?"
":null] " output += "[i↓":null] " @@ -440,3 +462,7 @@ return FALSE return TRUE + +/obj/machinery/mecha_part_fabricator/offstation + offstation_security_levels = FALSE + circuit = /obj/item/circuitboard/machine/mechfab/offstation diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm index 5c80b81ba5..9778499aac 100644 --- a/code/game/objects/items.dm +++ b/code/game/objects/items.dm @@ -896,3 +896,11 @@ GLOBAL_VAR_INIT(rpg_loot_items, FALSE) . = ..() if(var_name == NAMEOF(src, slowdown)) set_slowdown(var_value) //don't care if it's a duplicate edit as slowdown'll be set, do it anyways to force normal behavior. + +//Called when the object is constructed by an autolathe +//Has a reference to the autolathe so you can do !!FUN!! things with hacked lathes +/obj/item/proc/autolathe_crafted(obj/machinery/autolathe/A) + return + +/obj/item/proc/rnd_crafted(obj/machinery/rnd/production/P) + return diff --git a/code/game/objects/items/circuitboards/machine_circuitboards.dm b/code/game/objects/items/circuitboards/machine_circuitboards.dm index ef0380fce0..57638060f3 100644 --- a/code/game/objects/items/circuitboards/machine_circuitboards.dm +++ b/code/game/objects/items/circuitboards/machine_circuitboards.dm @@ -308,6 +308,13 @@ /obj/item/stock_parts/manipulator = 1, /obj/item/stock_parts/micro_laser = 1, /obj/item/stack/sheet/glass = 1) + var/offstation_security_levels = TRUE + +/obj/item/circuitboard/machine/mechfab/offstation + offstation_security_levels = FALSE + +/obj/item/circuitboard/machine/mechfab/rnd_crafted(obj/machinery/rnd/production/P) + offstation_security_levels = P.offstation_security_levels /obj/item/circuitboard/machine/cryo_tube name = "Cryotube (Machine Board)" @@ -759,6 +766,13 @@ /obj/item/stock_parts/matter_bin = 1, /obj/item/stock_parts/manipulator = 1, /obj/item/reagent_containers/glass/beaker = 2) + var/offstation_security_levels = TRUE + +/obj/item/circuitboard/machine/circuit_imprinter/offstation + offstation_security_levels = FALSE + +/obj/item/circuitboard/machine/mechfab/rnd_crafted(obj/machinery/rnd/production/P) + offstation_security_levels = P.offstation_security_levels /obj/item/circuitboard/machine/circuit_imprinter/department name = "Departmental Circuit Imprinter (Machine Board)" @@ -832,6 +846,13 @@ /obj/item/stock_parts/matter_bin = 2, /obj/item/stock_parts/manipulator = 2, /obj/item/reagent_containers/glass/beaker = 2) + var/offstation_security_levels = TRUE + +/obj/item/circuitboard/machine/protolathe/offstation + offstation_security_levels = FALSE + +/obj/item/circuitboard/machine/protolathe/rnd_crafted(obj/machinery/rnd/production/P) + offstation_security_levels = P.offstation_security_levels /obj/item/circuitboard/machine/protolathe/department name = "Departmental Protolathe (Machine Board)" diff --git a/code/game/objects/items/storage/boxes.dm b/code/game/objects/items/storage/boxes.dm index 515c39ffcb..2d2e60cfbf 100644 --- a/code/game/objects/items/storage/boxes.dm +++ b/code/game/objects/items/storage/boxes.dm @@ -1117,9 +1117,9 @@ desc = "A box containing a gift for worthy golems." /obj/item/storage/box/rndboards/PopulateContents() - new /obj/item/circuitboard/machine/protolathe(src) + new /obj/item/circuitboard/machine/protolathe/offstation(src) new /obj/item/circuitboard/machine/destructive_analyzer(src) - new /obj/item/circuitboard/machine/circuit_imprinter(src) + new /obj/item/circuitboard/machine/circuit_imprinter/offstation(src) new /obj/item/circuitboard/computer/rdconsole(src) /obj/item/storage/box/silver_sulf diff --git a/code/game/world.dm b/code/game/world.dm index bee595047f..1d719ee138 100644 --- a/code/game/world.dm +++ b/code/game/world.dm @@ -298,8 +298,8 @@ GLOBAL_LIST(topic_status_cache) if(SSmapping.config) // this just stops the runtime, honk. features += "[SSmapping.config.map_name]" //CIT CHANGE - makes the hub entry display the current map - if(get_security_level())//CIT CHANGE - makes the hub entry show the security level - features += "[get_security_level()] alert" + if(NUM2SECLEVEL(GLOB.security_level))//CIT CHANGE - makes the hub entry show the security level + features += "[NUM2SECLEVEL(GLOB.security_level)] alert" if (n > 1) features += "~[n] players" diff --git a/code/modules/antagonists/cult/cult_items.dm b/code/modules/antagonists/cult/cult_items.dm index fcb57a5a2e..ffab8174e5 100644 --- a/code/modules/antagonists/cult/cult_items.dm +++ b/code/modules/antagonists/cult/cult_items.dm @@ -539,7 +539,7 @@ if(SSshuttle.emergency.mode == SHUTTLE_CALL) var/cursetime = 1800 var/timer = SSshuttle.emergency.timeLeft(1) + cursetime - var/security_num = seclevel2num(get_security_level()) + var/security_num = SECLEVEL2NUM(NUM2SECLEVEL(GLOB.security_level)) var/set_coefficient = 1 switch(security_num) if(SEC_LEVEL_GREEN) diff --git a/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm b/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm index 5552efef1f..dc44a3b2d8 100644 --- a/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm +++ b/code/modules/antagonists/nukeop/equipment/nuclearbomb.dm @@ -41,7 +41,7 @@ STOP_PROCESSING(SSobj, core) update_icon() GLOB.poi_list |= src - previous_level = get_security_level() + previous_level = NUM2SECLEVEL(GLOB.security_level) /obj/machinery/nuclearbomb/Destroy() safety = FALSE @@ -419,7 +419,7 @@ return timing = !timing if(timing) - previous_level = get_security_level() + previous_level = NUM2SECLEVEL(GLOB.security_level) detonation_timer = world.time + (timer_set * 10) for(var/obj/item/pinpointer/nuke/syndicate/S in GLOB.pinpointer_list) S.switch_mode_to(TRACK_INFILTRATOR) diff --git a/code/modules/mob/living/silicon/robot/robot.dm b/code/modules/mob/living/silicon/robot/robot.dm index 4ef5993d2d..b389e386d4 100644 --- a/code/modules/mob/living/silicon/robot/robot.dm +++ b/code/modules/mob/living/silicon/robot/robot.dm @@ -237,7 +237,7 @@ return if(!CONFIG_GET(flag/disable_secborg) && GLOB.security_level < CONFIG_GET(number/minimum_secborg_alert)) - to_chat(src, "NOTICE: Due to local station regulations, the security cyborg module and its variants are only available during [num2seclevel(CONFIG_GET(number/minimum_secborg_alert))] alert and greater.") + to_chat(src, "NOTICE: Due to local station regulations, the security cyborg module and its variants are only available during [NUM2SECLEVEL(CONFIG_GET(number/minimum_secborg_alert))] alert and greater.") var/list/modulelist = list("Standard" = /obj/item/robot_module/standard, \ "Engineering" = /obj/item/robot_module/engineering, \ diff --git a/code/modules/research/designs.dm b/code/modules/research/designs.dm index f3ac118134..f19ff767d2 100644 --- a/code/modules/research/designs.dm +++ b/code/modules/research/designs.dm @@ -36,6 +36,9 @@ other types of metals and chemistry for reagents). var/dangerous_construction = FALSE //notify and log for admin investigations if this is printed. var/departmental_flags = ALL //bitflags for deplathes. var/list/datum/techweb_node/unlocked_by = list() + ///minimum and security levels the design can be printed on. + var/min_security_level = SEC_LEVEL_GREEN + var/max_security_level = SEC_LEVEL_DELTA var/research_icon //Replaces the item icon in the research console var/research_icon_state var/icon_cache diff --git a/code/modules/research/machinery/_production.dm b/code/modules/research/machinery/_production.dm index bd571607d2..0550fa9334 100644 --- a/code/modules/research/machinery/_production.dm +++ b/code/modules/research/machinery/_production.dm @@ -3,6 +3,7 @@ desc = "Makes researched and prototype items with materials and energy." layer = BELOW_OBJ_LAYER var/consoleless_interface = TRUE //Whether it can be used without a console. + var/offstation_security_levels = TRUE var/efficiency_coeff = 1 //Materials needed / coeff = actual. var/list/categories = list() var/datum/component/remote_materials/materials @@ -98,6 +99,7 @@ var/obj/item/I = O I.material_flags |= MATERIAL_NO_EFFECTS //Find a better way to do this. I.set_custom_materials(matlist.Copy()) + I.rnd_crafted(src) SSblackbox.record_feedback("nested tally", "item_printed", amount, list("[type]", "[path]")) investigate_log("[key_name(user)] built [amount] of [path] at [src]([type]).", INVESTIGATE_RESEARCH) @@ -134,6 +136,12 @@ if(D.build_type && !(D.build_type & allowed_buildtypes)) say("This machine does not have the necessary manipulation systems for this design. Please contact Nanotrasen Support!") return FALSE + if(!(obj_flags & EMAGGED) && (offstation_security_levels || is_station_level(z))) + if(GLOB.security_level < D.min_security_level) + say("Minimum security alert level required to print this design not met, please contact the command staff.") + return FALSE + if(GLOB.security_level > D.max_security_level) + say("Exceeded maximum security alert level required to print this design, please contact the command staff.") if(!materials.mat_container) say("No connection to material storage, please contact the quartermaster.") return FALSE @@ -275,15 +283,26 @@ temp_material += " [all_materials[M]/coeff] [CallMaterialName(M)]" c = min(c,t) - if (c >= 1) + var/clearance = !(obj_flags & EMAGGED) && (offstation_security_levels || is_station_level(z)) + var/sec_text = "" + if(clearance && (D.min_security_level > SEC_LEVEL_GREEN || D.max_security_level < SEC_LEVEL_DELTA)) + sec_text = " (Allowed security levels: " + for(var/n in D.min_security_level to D.max_security_level) + sec_text += NUM2SECLEVEL(n) + if(n + 1 <= D.max_security_level) + sec_text += ", " + sec_text += ")" + + clearance = !clearance || ISINRANGE(GLOB.security_level, D.min_security_level, D.max_security_level) + if (c >= 1 && clearance) l += "[D.name][RDSCREEN_NOBREAK]" if(c >= 5) l += "x5[RDSCREEN_NOBREAK]" if(c >= 10) l += "x10[RDSCREEN_NOBREAK]" - l += "[temp_material][RDSCREEN_NOBREAK]" + l += "[temp_material][sec_text][RDSCREEN_NOBREAK]" else - l += "[D.name][temp_material][RDSCREEN_NOBREAK]" + l += "[D.name][temp_material][sec_text][RDSCREEN_NOBREAK]" l += "" return l diff --git a/code/modules/research/machinery/circuit_imprinter.dm b/code/modules/research/machinery/circuit_imprinter.dm index 948dad61db..661ebe31c0 100644 --- a/code/modules/research/machinery/circuit_imprinter.dm +++ b/code/modules/research/machinery/circuit_imprinter.dm @@ -30,3 +30,9 @@ total_rating += M.rating * 2 //There is only one. total_rating = max(1, total_rating) efficiency_coeff = total_rating + var/obj/item/circuitboard/machine/circuit_imprinter/C = circuit + offstation_security_levels = C.offstation_security_levels + +/obj/machinery/rnd/production/circuit_imprinter/offstation + offstation_security_levels = FALSE + circuit = /obj/item/circuitboard/machine/circuit_imprinter/offstation diff --git a/code/modules/research/machinery/protolathe.dm b/code/modules/research/machinery/protolathe.dm index 684f27ccad..b1b31a279c 100644 --- a/code/modules/research/machinery/protolathe.dm +++ b/code/modules/research/machinery/protolathe.dm @@ -23,3 +23,12 @@ /obj/machinery/rnd/production/protolathe/disconnect_console() linked_console.linked_lathe = null ..() + +/obj/machinery/rnd/production/protolathe/calculate_efficiency() + . = ..() + var/obj/item/circuitboard/machine/protolathe/C = circuit + offstation_security_levels = C.offstation_security_levels + +/obj/machinery/rnd/production/protolathe/offstation + offstation_security_levels = FALSE + circuit = /obj/item/circuitboard/machine/protolathe/offstation diff --git a/code/modules/research/rdconsole.dm b/code/modules/research/rdconsole.dm index be1b9460b0..19f6e3ffdb 100644 --- a/code/modules/research/rdconsole.dm +++ b/code/modules/research/rdconsole.dm @@ -301,15 +301,26 @@ Nothing else in the console has ID requirements. temp_material += " [all_materials[M]/coeff] [CallMaterialName(M)]" c = min(c,t) - if (c >= 1) + var/clearance = !(linked_lathe.obj_flags & EMAGGED) && (linked_lathe.offstation_security_levels || is_station_level(linked_lathe.z)) + var/sec_text = "" + if(clearance && (D.min_security_level > SEC_LEVEL_GREEN || D.max_security_level < SEC_LEVEL_DELTA)) + sec_text = " (Allowed security levels: " + for(var/n in D.min_security_level to D.max_security_level) + sec_text += NUM2SECLEVEL(n) + if(n + 1 <= D.max_security_level) + sec_text += ", " + sec_text += ")" + + clearance = !clearance || ISINRANGE(GLOB.security_level, D.min_security_level, D.max_security_level) + if (c >= 1 && clearance) l += "[D.name][RDSCREEN_NOBREAK]" if(c >= 5) l += "x5[RDSCREEN_NOBREAK]" if(c >= 10) l += "x10[RDSCREEN_NOBREAK]" - l += "[temp_material][RDSCREEN_NOBREAK]" + l += "[temp_material][sec_text][RDSCREEN_NOBREAK]" else - l += "[D.name][temp_material][RDSCREEN_NOBREAK]" + l += "[D.name][temp_material][sec_text][RDSCREEN_NOBREAK]" l += "" l += "" return l diff --git a/code/modules/security_levels/keycard_authentication.dm b/code/modules/security_levels/keycard_authentication.dm index 8a58563407..b9dc9b92d3 100644 --- a/code/modules/security_levels/keycard_authentication.dm +++ b/code/modules/security_levels/keycard_authentication.dm @@ -41,7 +41,7 @@ GLOBAL_DATUM_INIT(keycard_events, /datum/events, new) var/list/data = list() data["waiting"] = waiting data["auth_required"] = event_source ? event_source.event : 0 - data["red_alert"] = (seclevel2num(get_security_level()) >= SEC_LEVEL_RED) ? 1 : 0 + data["red_alert"] = (SECLEVEL2NUM(NUM2SECLEVEL(GLOB.security_level)) >= SEC_LEVEL_RED) ? 1 : 0 data["emergency_maint"] = GLOB.emergency_access data["bsa_unlock"] = GLOB.bsa_unlock return data diff --git a/code/modules/security_levels/security_levels.dm b/code/modules/security_levels/security_levels.dm index 887891ca16..52fafb81be 100644 --- a/code/modules/security_levels/security_levels.dm +++ b/code/modules/security_levels/security_levels.dm @@ -5,20 +5,17 @@ GLOBAL_VAR_INIT(security_level, SEC_LEVEL_GREEN) //SEC_LEVEL_RED = code red //SEC_LEVEL_DELTA = code delta + /* + * All security levels, per ascending alert. Nothing too fancy, really. + * Their positions should also match their numerical values. + */ +GLOBAL_LIST_INIT(all_security_levels, list("green", "blue", "amber", "red", "delta")) + //config.alert_desc_blue_downto /proc/set_security_level(level) - switch(level) - if("green") - level = SEC_LEVEL_GREEN - if("blue") - level = SEC_LEVEL_BLUE - if("amber") - level = SEC_LEVEL_AMBER - if("red") - level = SEC_LEVEL_RED - if("delta") - level = SEC_LEVEL_DELTA + if(!isnum(level)) + level = GLOB.all_security_levels.Find(level) //Will not be announced if you try to set to the same level as it already is if(level >= SEC_LEVEL_GREEN && level <= SEC_LEVEL_DELTA && level != GLOB.security_level) @@ -111,46 +108,7 @@ GLOBAL_VAR_INIT(security_level, SEC_LEVEL_GREEN) if(D.red_alert_access) D.visible_message("[D] whirrs as it automatically lifts access requirements!") playsound(D, 'sound/machines/boltsup.ogg', 50, TRUE) - SSblackbox.record_feedback("tally", "security_level_changes", 1, get_security_level()) + SSblackbox.record_feedback("tally", "security_level_changes", 1, NUM2SECLEVEL(GLOB.security_level)) SSnightshift.check_nightshift() else return - -/proc/get_security_level() - switch(GLOB.security_level) - if(SEC_LEVEL_GREEN) - return "green" - if(SEC_LEVEL_BLUE) - return "blue" - if(SEC_LEVEL_AMBER) - return "amber" - if(SEC_LEVEL_RED) - return "red" - if(SEC_LEVEL_DELTA) - return "delta" - -/proc/num2seclevel(num) - switch(num) - if(SEC_LEVEL_GREEN) - return "green" - if(SEC_LEVEL_BLUE) - return "blue" - if(SEC_LEVEL_AMBER) - return "amber" - if(SEC_LEVEL_RED) - return "red" - if(SEC_LEVEL_DELTA) - return "delta" - -/proc/seclevel2num(seclevel) - switch( lowertext(seclevel) ) - if("green") - return SEC_LEVEL_GREEN - if("blue") - return SEC_LEVEL_BLUE - if("amber") - return SEC_LEVEL_AMBER - if("red") - return SEC_LEVEL_RED - if("delta") - return SEC_LEVEL_DELTA diff --git a/code/modules/shuttle/emergency.dm b/code/modules/shuttle/emergency.dm index cd08b7290a..f3b4cbddc9 100644 --- a/code/modules/shuttle/emergency.dm +++ b/code/modules/shuttle/emergency.dm @@ -310,7 +310,7 @@ /obj/docking_port/mobile/emergency/request(obj/docking_port/stationary/S, area/signalOrigin, reason, redAlert, set_coefficient=null, silent = FALSE) if(!isnum(set_coefficient)) - var/security_num = seclevel2num(get_security_level()) + var/security_num = SECLEVEL2NUM(NUM2SECLEVEL(GLOB.security_level)) switch(security_num) if(SEC_LEVEL_GREEN) set_coefficient = 2 diff --git a/tgstation.dme b/tgstation.dme index 7bfbd2dde2..47ea34e6f5 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -96,6 +96,7 @@ #include "code\__DEFINES\rust_g.config.dm" #include "code\__DEFINES\rust_g.dm" #include "code\__DEFINES\say.dm" +#include "code\__DEFINES\security_levels.dm" #include "code\__DEFINES\shuttles.dm" #include "code\__DEFINES\sight.dm" #include "code\__DEFINES\sound.dm" From d1ec18a0ce7518747c40093d024db717f28589c2 Mon Sep 17 00:00:00 2001 From: Ghommie <42542238+Ghommie@users.noreply.github.com> Date: Fri, 24 Apr 2020 00:57:40 +0200 Subject: [PATCH 40/55] what the?! --- code/controllers/subsystem/shuttle.dm | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/code/controllers/subsystem/shuttle.dm b/code/controllers/subsystem/shuttle.dm index 58d73ded68..a3e804d541 100644 --- a/code/controllers/subsystem/shuttle.dm +++ b/code/controllers/subsystem/shuttle.dm @@ -217,13 +217,13 @@ SUBSYSTEM_DEF(shuttle) call_reason = trim(html_encode(call_reason)) - if(length(call_reason) < CALL_SHUTTLE_REASON_LENGTH && SECLEVEL2NUM(NUM2SECLEVEL(GLOB.security_level)) > SEC_LEVEL_GREEN) + if(length(call_reason) < CALL_SHUTTLE_REASON_LENGTH && GLOB.security_level > SEC_LEVEL_GREEN) to_chat(user, "You must provide a reason.") return var/area/signal_origin = get_area(user) var/emergency_reason = "\nNature of emergency:\n\n[call_reason]" - var/security_num = SECLEVEL2NUM(NUM2SECLEVEL(GLOB.security_level)) + var/security_num = GLOB.security_level switch(security_num) if(SEC_LEVEL_RED,SEC_LEVEL_DELTA) emergency.request(null, signal_origin, html_decode(emergency_reason), 1) //There is a serious threat we gotta move no time to give them five minutes. @@ -285,7 +285,7 @@ SUBSYSTEM_DEF(shuttle) /datum/controller/subsystem/shuttle/proc/canRecall() if(!emergency || emergency.mode != SHUTTLE_CALL || emergencyNoRecall || SSticker.mode.name == "meteor") return - var/security_num = SECLEVEL2NUM(NUM2SECLEVEL(GLOB.security_level)) + var/security_num = GLOB.security_level switch(security_num) if(SEC_LEVEL_GREEN) if(emergency.timeLeft(1) < emergencyCallTime) @@ -642,7 +642,7 @@ SUBSYSTEM_DEF(shuttle) /datum/controller/subsystem/shuttle/proc/autoEnd() //CIT CHANGE - allows shift to end without being a proper shuttle call? if(EMERGENCY_IDLE_OR_RECALLED) SSshuttle.emergency.request(silent = TRUE) - priority_announce("The shift has come to an end and the shuttle called. [SECLEVEL2NUM(NUM2SECLEVEL(GLOB.security_level)) == SEC_LEVEL_RED ? "Red Alert state confirmed: Dispatching priority shuttle. " : "" ]It will arrive in [emergency.timeLeft(600)] minutes.", null, "shuttlecalled", "Priority") + priority_announce("The shift has come to an end and the shuttle called. [GLOB.security_level == SEC_LEVEL_RED ? "Red Alert state confirmed: Dispatching priority shuttle. " : "" ]It will arrive in [emergency.timeLeft(600)] minutes.", null, "shuttlecalled", "Priority") log_game("Round end vote passed. Shuttle has been auto-called.") message_admins("Round end vote passed. Shuttle has been auto-called.") emergencyNoRecall = TRUE From a62f3f0d92d3af246175cfc0df4fcecf9a91fe10 Mon Sep 17 00:00:00 2001 From: Ghommie <42542238+Ghommie@users.noreply.github.com> Date: Fri, 24 Apr 2020 01:12:33 +0200 Subject: [PATCH 41/55] Clarifies a comment. --- code/modules/research/designs.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/research/designs.dm b/code/modules/research/designs.dm index f19ff767d2..cfb6d92723 100644 --- a/code/modules/research/designs.dm +++ b/code/modules/research/designs.dm @@ -36,7 +36,7 @@ other types of metals and chemistry for reagents). var/dangerous_construction = FALSE //notify and log for admin investigations if this is printed. var/departmental_flags = ALL //bitflags for deplathes. var/list/datum/techweb_node/unlocked_by = list() - ///minimum and security levels the design can be printed on. + ///minimum and security levels the design can be printed on. Currently only available for rnd production machinery and mechfab. var/min_security_level = SEC_LEVEL_GREEN var/max_security_level = SEC_LEVEL_DELTA var/research_icon //Replaces the item icon in the research console From b914f6f96d513899002a0205c6f5c23d437e1a2a Mon Sep 17 00:00:00 2001 From: Ghommie <42542238+Ghommie@users.noreply.github.com> Date: Fri, 24 Apr 2020 03:20:51 +0200 Subject: [PATCH 42/55] Still unimplemented security level firing pins. --- code/modules/projectiles/pins.dm | 84 +++++++++++++++++++++++++++++++ icons/obj/device.dmi | Bin 53345 -> 53110 bytes 2 files changed, 84 insertions(+) diff --git a/code/modules/projectiles/pins.dm b/code/modules/projectiles/pins.dm index e754a9c070..9fbe742d39 100644 --- a/code/modules/projectiles/pins.dm +++ b/code/modules/projectiles/pins.dm @@ -241,3 +241,87 @@ to_chat(user, "The pin beeps, refusing to fire.") return FALSE return TRUE + +/obj/item/firing_pin/security_level + name = "security level firing pin" + desc = "A sophisticated firing pin that authorizes operation based on its settings and current security level." + icon_state = "firing_pin_sec_level" + var/min_sec_level = SEC_LEVEL_GREEN + var/max_sec_level = SEC_LEVEL_DELTA + var/only_lethals = FALSE + var/can_toggle = TRUE + +/obj/item/firing_pin/security_level/Initialize() + . = ..() + fail_message = "INVALID SECURITY LEVEL. CURRENT: [uppertext(num2seclevel(GLOB.security_level))]. \ + MIN: [uppertext(num2seclevel(min_sec_level))]. MAX: [uppertext(num2seclevel(max_sec_level))]. \ + ONLY LETHALS: [only_lethals ? "YES" : "NO"]." + update_icon() + +/obj/item/firing_pin/security_level/examine(mob/user) + . = ..() + var/lethal = only_lethals ? "only lethal " : "" + if(min_sec_level != max_sec_level) + . += "It's currently set to disallow [lethal]operation when the security level isn't between [num2seclevel(min_sec_level)] and [num2seclevel(max_sec_level)]." + else + . += "It's currently set to disallow [lethal]operation when the security level isn't [num2seclevel(min_sec_level)]." + if(can_toggle) + . += "You can use a multitool to modify its settings." + +/obj/item/firing_pin/security_level/multitool_act(mob/living/user, obj/item/I) + . = TRUE + if(!can_toggle || !user.canUseTopic(src, BE_CLOSE)) + return + var/selection = alert(user, "Which setting would you want to modify?", "Firing Pin Settings", "Minimum Level Setting", "Maximum Level Setting", "Lethals Only Toggle") + if(QDELETED(src) || QDELETED(user) || !user.canUseTopic(src, BE_CLOSE)) + return + var/static/list/till_designs_pr_isnt_merged = list("green", "blue", "amber", "red", "delta") + switch(selection) + if("Minimum Level Setting") + var/input = input(user, "Input the new minimum level setting.", "Firing Pin Settings", num2seclevel(min_sec_level)) as null|anything in till_designs_pr_isnt_merged + if(!input) + return + min_sec_level = till_designs_pr_isnt_merged.Find(input) - 1 + if(min_sec_level > max_sec_level) + max_sec_level = SEC_LEVEL_DELTA + if("Maximum Level Setting") + var/input = input(user, "Input the new maximum level setting.", "Firing Pin Settings", num2seclevel(max_sec_level)) as null|anything in till_designs_pr_isnt_merged + if(!input) + return + max_sec_level = till_designs_pr_isnt_merged.Find(input) - 1 + if(max_sec_level < max_sec_level) + min_sec_level = SEC_LEVEL_GREEN + if("Lethals Only Toggle") + only_lethals = !only_lethals + + fail_message = "INVALID SECURITY LEVEL. CURRENT: [uppertext(num2seclevel(GLOB.security_level))]. \ + MIN: [uppertext(num2seclevel(min_sec_level))]. MAX: [uppertext(num2seclevel(max_sec_level))]. \ + ONLY LETHALS: [only_lethals ? "YES" : "NO"]." + update_icon() + +/obj/item/firing_pin/security_level/update_overlays() + . = ..() + var/offset = 0 + for(var/level in list(min_sec_level, max_sec_level)) + var/mutable_appearance/overlay = mutable_appearance(icon, "pin_sec_level_overlay") + overlay.pixel_x += offset + offset += 4 + switch(level) + if(SEC_LEVEL_GREEN) + overlay.color = "#b2ff59" //light green + if(SEC_LEVEL_BLUE) + overlay.color = "#99ccff" //light blue + if(SEC_LEVEL_AMBER) + overlay.color = "#ffae42" //light yellow/orange + if(SEC_LEVEL_RED) + overlay.color = "#ff3f34" //light red + else + overlay.color = "#fe59c2" //neon fuchsia + . += overlay + var/mutable_appearance/overlay = mutable_appearance(icon, "pin_sec_level_overlay") + overlay.pixel_x += offset + overlay.color = only_lethals ? "#b2ff59" : "#ff3f34" + . += overlay + +/obj/item/firing_pin/security_level/pin_auth(mob/living/user) + return (only_lethals && !(gun.chambered?.harmful)) || ISINRANGE(GLOB.security_level, min_sec_level, max_sec_level) diff --git a/icons/obj/device.dmi b/icons/obj/device.dmi index c58fb5d9406cbabdeed2f34783af484385c4759f..58c1cd921cca574a3ba61e247cc50bbdf770848c 100644 GIT binary patch delta 32812 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ℜ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 XS<3iX7wmxrLHBMyxK(=7I`n@5KJ!8i delta 33049 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 Date: Fri, 24 Apr 2020 03:44:12 +0200 Subject: [PATCH 43/55] Putnam's suggestions. --- code/modules/reagents/chemistry/reagents/other_reagents.dm | 2 +- .../code/modules/reagents/chemistry/reagents/SDGF.dm | 4 ++-- .../code/modules/reagents/chemistry/reagents/healing.dm | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/code/modules/reagents/chemistry/reagents/other_reagents.dm b/code/modules/reagents/chemistry/reagents/other_reagents.dm index 4410582054..682368f79f 100644 --- a/code/modules/reagents/chemistry/reagents/other_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/other_reagents.dm @@ -140,7 +140,7 @@ data = list("donor"=null,"viruses"=null,"blood_DNA"="REPLICATED", "bloodcolor" = BLOOD_COLOR_SYNTHETIC, "blood_type"="SY","resistances"=null,"trace_chem"=null,"mind"=null,"ckey"=null,"gender"=null,"real_name"=null,"cloneable"=null,"factions"=null) name = "Synthetic Blood" description = "A synthetically produced imitation of blood." - taste_description = "oily" + taste_description = "oil" color = BLOOD_COLOR_SYNTHETIC // rgb: 11, 7, 48 value = REAGENT_VALUE_NONE diff --git a/modular_citadel/code/modules/reagents/chemistry/reagents/SDGF.dm b/modular_citadel/code/modules/reagents/chemistry/reagents/SDGF.dm index 894db1ee27..319cad1714 100644 --- a/modular_citadel/code/modules/reagents/chemistry/reagents/SDGF.dm +++ b/modular_citadel/code/modules/reagents/chemistry/reagents/SDGF.dm @@ -52,7 +52,7 @@ IMPORTANT FACTORS TO CONSIDER WHILE BALANCING inverse_chem_val = 0.5 inverse_chem = /datum/reagent/impure/SDZF can_synth = TRUE - value = REAGENT_VALUE_EXCEPTIONAL + value = REAGENT_VALUE_RARE //Main SDGF chemical @@ -310,7 +310,7 @@ IMPORTANT FACTORS TO CONSIDER WHILE BALANCING can_synth = TRUE taste_description = "a weird chemical fleshy flavour" chemical_flags = REAGENT_SNEAKYNAME - value = REAGENT_VALUE_VERY_RARE + value = REAGENT_VALUE_RARE /datum/reagent/impure/SDZF/on_mob_life(mob/living/carbon/M) //If you're bad at fermichem, turns your clone into a zombie instead. switch(current_cycle)//Pretends to be normal diff --git a/modular_citadel/code/modules/reagents/chemistry/reagents/healing.dm b/modular_citadel/code/modules/reagents/chemistry/reagents/healing.dm index ac29f1a019..48c9ffb7e6 100644 --- a/modular_citadel/code/modules/reagents/chemistry/reagents/healing.dm +++ b/modular_citadel/code/modules/reagents/chemistry/reagents/healing.dm @@ -101,7 +101,7 @@ data = list("grown_volume" = 0, "injected_vol" = 0) var/borrowed_health color = "#FFDADA" - value = REAGENT_VALUE_VERY_RARE + value = REAGENT_VALUE_COMMON /datum/reagent/synthtissue/reaction_mob(mob/living/M, method=TOUCH, reac_volume,show_message = 1) if(iscarbon(M)) From cc9d3b485ac9131c6a4e751d0de13e2d998655e8 Mon Sep 17 00:00:00 2001 From: MrJWhit <48370570+MrJWhit@users.noreply.github.com> Date: Fri, 24 Apr 2020 00:47:11 -0400 Subject: [PATCH 44/55] Removes putnam upsetti mixer --- _maps/map_files/BoxStation/BoxStation.dmm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_maps/map_files/BoxStation/BoxStation.dmm b/_maps/map_files/BoxStation/BoxStation.dmm index 3b7f733d4c..9a28e2d1f4 100644 --- a/_maps/map_files/BoxStation/BoxStation.dmm +++ b/_maps/map_files/BoxStation/BoxStation.dmm @@ -45748,7 +45748,7 @@ /turf/open/floor/plasteel, /area/engine/atmos) "cfP" = ( -/obj/machinery/atmospherics/components/trinary/mixer/airmix{ +/obj/machinery/atmospherics/components/trinary/mixer/airmix/inverse{ dir = 4 }, /turf/open/floor/plasteel, From 89e5681593c7999c7ac2bd663b5587f6d2214eaf Mon Sep 17 00:00:00 2001 From: Ghom <42542238+Ghommie@users.noreply.github.com> Date: Fri, 24 Apr 2020 18:33:54 +0200 Subject: [PATCH 45/55] Fixing robo limb burn damage being unfixable. --- code/modules/power/cable.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/power/cable.dm b/code/modules/power/cable.dm index aab38c8754..eecc1394de 100644 --- a/code/modules/power/cable.dm +++ b/code/modules/power/cable.dm @@ -533,7 +533,7 @@ By design, d1 is the smallest direction and d2 is the highest if(affecting && affecting.status == BODYPART_ROBOTIC) if(user == H) user.visible_message("[user] starts to fix some of the wires in [H]'s [affecting.name].", "You start fixing some of the wires in [H]'s [affecting.name].") - if(!do_after(user, H, 50)) + if(!do_mob(user, H, 50)) return if(item_heal_robotic(H, user, 0, 15)) use(1) From 58fc679cce74cf75a118a2b235f5f679fbf5f488 Mon Sep 17 00:00:00 2001 From: Ghommie <42542238+Ghommie@users.noreply.github.com> Date: Fri, 24 Apr 2020 20:49:15 +0200 Subject: [PATCH 46/55] WIP --- .../{ => away_mission}/Academy.dmm | 0 .../{ => away_mission}/Cabin.dmm | 0 .../{ => away_mission}/TheBeach.dmm | 0 .../{ => away_mission}/caves.dmm | 0 .../{ => away_mission}/challenge.dmm | 0 .../{ => away_mission}/moonoutpost19.dmm | 0 .../{ => away_mission}/research.dmm | 0 .../{ => away_mission}/snowdin.dmm | 0 .../{ => away_mission}/spacebattle.dmm | 0 .../undergroundoutpost45.dmm | 0 .../{ => away_mission}/wildwest.dmm | 0 code/__DEFINES/maps.dm | 7 +- code/__HELPERS/level_traits.dm | 2 + code/_globalvars/lists/mapping.dm | 5 ++ code/controllers/subsystem/mapping.dm | 65 ++++++++++++------- code/modules/awaymissions/zlevel.dm | 16 ++--- code/modules/mapping/map_template.dm | 8 +-- config/awaymissionconfig.txt | 26 ++++---- config/vr_config.txt | 13 ++++ 19 files changed, 90 insertions(+), 52 deletions(-) rename _maps/RandomZLevels/{ => away_mission}/Academy.dmm (100%) rename _maps/RandomZLevels/{ => away_mission}/Cabin.dmm (100%) rename _maps/RandomZLevels/{ => away_mission}/TheBeach.dmm (100%) rename _maps/RandomZLevels/{ => away_mission}/caves.dmm (100%) rename _maps/RandomZLevels/{ => away_mission}/challenge.dmm (100%) rename _maps/RandomZLevels/{ => away_mission}/moonoutpost19.dmm (100%) rename _maps/RandomZLevels/{ => away_mission}/research.dmm (100%) rename _maps/RandomZLevels/{ => away_mission}/snowdin.dmm (100%) rename _maps/RandomZLevels/{ => away_mission}/spacebattle.dmm (100%) rename _maps/RandomZLevels/{ => away_mission}/undergroundoutpost45.dmm (100%) rename _maps/RandomZLevels/{ => away_mission}/wildwest.dmm (100%) create mode 100644 config/vr_config.txt diff --git a/_maps/RandomZLevels/Academy.dmm b/_maps/RandomZLevels/away_mission/Academy.dmm similarity index 100% rename from _maps/RandomZLevels/Academy.dmm rename to _maps/RandomZLevels/away_mission/Academy.dmm diff --git a/_maps/RandomZLevels/Cabin.dmm b/_maps/RandomZLevels/away_mission/Cabin.dmm similarity index 100% rename from _maps/RandomZLevels/Cabin.dmm rename to _maps/RandomZLevels/away_mission/Cabin.dmm diff --git a/_maps/RandomZLevels/TheBeach.dmm b/_maps/RandomZLevels/away_mission/TheBeach.dmm similarity index 100% rename from _maps/RandomZLevels/TheBeach.dmm rename to _maps/RandomZLevels/away_mission/TheBeach.dmm diff --git a/_maps/RandomZLevels/caves.dmm b/_maps/RandomZLevels/away_mission/caves.dmm similarity index 100% rename from _maps/RandomZLevels/caves.dmm rename to _maps/RandomZLevels/away_mission/caves.dmm diff --git a/_maps/RandomZLevels/challenge.dmm b/_maps/RandomZLevels/away_mission/challenge.dmm similarity index 100% rename from _maps/RandomZLevels/challenge.dmm rename to _maps/RandomZLevels/away_mission/challenge.dmm diff --git a/_maps/RandomZLevels/moonoutpost19.dmm b/_maps/RandomZLevels/away_mission/moonoutpost19.dmm similarity index 100% rename from _maps/RandomZLevels/moonoutpost19.dmm rename to _maps/RandomZLevels/away_mission/moonoutpost19.dmm diff --git a/_maps/RandomZLevels/research.dmm b/_maps/RandomZLevels/away_mission/research.dmm similarity index 100% rename from _maps/RandomZLevels/research.dmm rename to _maps/RandomZLevels/away_mission/research.dmm diff --git a/_maps/RandomZLevels/snowdin.dmm b/_maps/RandomZLevels/away_mission/snowdin.dmm similarity index 100% rename from _maps/RandomZLevels/snowdin.dmm rename to _maps/RandomZLevels/away_mission/snowdin.dmm diff --git a/_maps/RandomZLevels/spacebattle.dmm b/_maps/RandomZLevels/away_mission/spacebattle.dmm similarity index 100% rename from _maps/RandomZLevels/spacebattle.dmm rename to _maps/RandomZLevels/away_mission/spacebattle.dmm diff --git a/_maps/RandomZLevels/undergroundoutpost45.dmm b/_maps/RandomZLevels/away_mission/undergroundoutpost45.dmm similarity index 100% rename from _maps/RandomZLevels/undergroundoutpost45.dmm rename to _maps/RandomZLevels/away_mission/undergroundoutpost45.dmm diff --git a/_maps/RandomZLevels/wildwest.dmm b/_maps/RandomZLevels/away_mission/wildwest.dmm similarity index 100% rename from _maps/RandomZLevels/wildwest.dmm rename to _maps/RandomZLevels/away_mission/wildwest.dmm diff --git a/code/__DEFINES/maps.dm b/code/__DEFINES/maps.dm index 73e900226e..844fe2cb90 100644 --- a/code/__DEFINES/maps.dm +++ b/code/__DEFINES/maps.dm @@ -35,6 +35,7 @@ require only minor tweaks. #define ZTRAIT_REEBE "Reebe" #define ZTRAIT_RESERVED "Transit/Reserved" #define ZTRAIT_AWAY "Away Mission" +#define ZTRAIT_VR "Virtual Reality" #define ZTRAIT_SPACE_RUINS "Space Ruins" #define ZTRAIT_LAVA_RUINS "Lava Ruins" #define ZTRAIT_ISOLATED_RUINS "Isolated Ruins" //Placing ruins on z levels with this trait will use turf reservation instead of usual placement. @@ -101,4 +102,8 @@ require only minor tweaks. #define PLACE_BELOW "below" //On z levl below - centered on same tile #define PLACE_ISOLATED "isolated" //On isolated ruin z level //Map type stuff. -#define MAP_TYPE_STATION "station" \ No newline at end of file +#define MAP_TYPE_STATION "station" + +//Random z-levels name defines. +#define AWAY_MISSION_NAME "Away Mission" +#define VIRT_REALITY_NAME "Virtual Reality" diff --git a/code/__HELPERS/level_traits.dm b/code/__HELPERS/level_traits.dm index 3e6e88c8fa..030a324614 100644 --- a/code/__HELPERS/level_traits.dm +++ b/code/__HELPERS/level_traits.dm @@ -12,3 +12,5 @@ #define is_reserved_level(z) SSmapping.level_trait(z, ZTRAIT_RESERVED) #define is_away_level(z) SSmapping.level_trait(z, ZTRAIT_AWAY) + +#define is_vr_level(z) SSmapping.level_trait(z, ZTRAIT_VR) diff --git a/code/_globalvars/lists/mapping.dm b/code/_globalvars/lists/mapping.dm index fb8863ebe7..d214ec94ef 100644 --- a/code/_globalvars/lists/mapping.dm +++ b/code/_globalvars/lists/mapping.dm @@ -50,3 +50,8 @@ GLOBAL_LIST_EMPTY_TYPED(areas_by_type, /area) GLOBAL_LIST_EMPTY(all_abstract_markers) GLOBAL_LIST_EMPTY(stationroom_landmarks) //List of all spawns for stationrooms + +///Away missions, VR, random z levels stuff. +GLOBAL_LIST_EMPTY(random_zlevels_generated) +GLOBAL_LIST_INIT(potential_away_levels, generateMapList(filename = "[global.config.directory]/awaymissionconfig.txt")) +GLOBAL_LIST_INIT(potential_vr_levels, generateMapList(filename = "[global.config.directory]/vr_config.txt")) diff --git a/code/controllers/subsystem/mapping.dm b/code/controllers/subsystem/mapping.dm index f13d5a2779..34e7439c38 100644 --- a/code/controllers/subsystem/mapping.dm +++ b/code/controllers/subsystem/mapping.dm @@ -81,7 +81,9 @@ SUBSYSTEM_DEF(mapping) // Pick a random away mission. if(CONFIG_GET(flag/roundstart_away)) createRandomZlevel() - + // Pick a random VR level. + if(CONFIG_GET(flag/roundstart_vr)) + createRandomZlevel(VIRT_REALITY_NAME, list(ZTRAIT_AWAY = TRUE, ZTRAIT_VR = TRUE), GLOB.potential_vr_levels) // Generate mining ruins loading_ruins = TRUE @@ -410,52 +412,65 @@ GLOBAL_LIST_EMPTY(the_station_areas) //Manual loading of away missions. /client/proc/admin_away() - set name = "Load Away Mission" + set name = "Load Away Mission / Virtual Reality" set category = "Fun" if(!holder ||!check_rights(R_FUN)) return + var/choice = alert(src, "What kind of level would you like to load?", "Load Away/VR", AWAY_MISSION_NAME, VIRT_REALITY_NAME, "Cancel") - if(!GLOB.the_gateway) - if(alert("There's no home gateway on the station. You sure you want to continue ?", "Uh oh", "Yes", "No") != "Yes") + var/list/possible_options + var/list/ztraits + switch(choice) + if(VIRT_REALITY_NAME) + possible_options = GLOB.potential_vr_levels + ztraits = list(ZTRAIT_AWAY = TRUE, ZTRAIT_VR = TRUE) + if(AWAY_MISSION_NAME) + if(!GLOB.the_gateway) + if(alert("There's no home gateway on the station. You sure you want to continue ?", "Uh oh", "Yes", "No") != "Yes") + return + possible_options = GLOB.potential_away_levels + ztraits = list(ZTRAIT_AWAY = TRUE) + else return - var/list/possible_options = GLOB.potentialRandomZlevels + "Custom" - var/away_name - var/datum/space_level/away_level + possible_options += "Custom" + var/lvl_name + var/datum/space_level/level - var/answer = input("What kind ? ","Away") as null|anything in possible_options + var/answer = input("What kind ? ","Away/VR") as null|anything in possible_options switch(answer) + if(null) + return if("Custom") var/mapfile = input("Pick file:", "File") as null|file if(!mapfile) return - away_name = "[mapfile] custom" - to_chat(usr,"Loading [away_name]...") - var/datum/map_template/template = new(mapfile, "Away Mission") - away_level = template.load_new_z() + lvl_name = "[mapfile] custom" + to_chat(usr,"Loading [lvl_name]...") + var/datum/map_template/template = new(mapfile, choice, ztraits) + level = template.load_new_z() else - if(answer in GLOB.potentialRandomZlevels) - away_name = answer - to_chat(usr,"Loading [away_name]...") - var/datum/map_template/template = new(away_name, "Away Mission") - away_level = template.load_new_z() - else - return + lvl_name = answer + to_chat(usr,"Loading [lvl_name]...") + var/datum/map_template/template = new(lvl_name, choice, ztraits) + level = template.load_new_z() + else + return - message_admins("Admin [key_name_admin(usr)] has loaded [away_name] away mission.") - log_admin("Admin [key_name(usr)] has loaded [away_name] away mission.") - if(!away_level) - message_admins("Loading [away_name] failed!") + message_admins("Admin [key_name_admin(usr)] has loaded [lvl_name] [choice].") + log_admin("Admin [key_name(usr)] has loaded [lvl_name] [choice].") + if(!level) + message_admins("Loading [lvl_name] failed!") return - if(GLOB.the_gateway) + if(choice == AWAY_MISSION_NAME && GLOB.the_gateway) //Link any found away gate with station gate var/obj/machinery/gateway/centeraway/new_gate for(var/obj/machinery/gateway/centeraway/G in GLOB.machines) - if(G.z == away_level.z_value) //I'll have to refactor gateway shitcode before multi-away support. + if(G.z == level.z_value) //I'll have to refactor gateway shitcode before multi-away support. new_gate = G break //Link station gate with away gate and remove wait time. diff --git a/code/modules/awaymissions/zlevel.dm b/code/modules/awaymissions/zlevel.dm index d4c9fdbee7..55a1c9dcc4 100644 --- a/code/modules/awaymissions/zlevel.dm +++ b/code/modules/awaymissions/zlevel.dm @@ -1,15 +1,13 @@ -// How much "space" we give the edge of the map -GLOBAL_LIST_INIT(potentialRandomZlevels, generateMapList(filename = "[global.config.directory]/awaymissionconfig.txt")) -/proc/createRandomZlevel() - if(GLOB.awaydestinations.len) //crude, but it saves another var! +/proc/createRandomZlevel(name = AWAY_MISSION_NAME, list/traits = list(ZTRAIT_AWAY = TRUE), list/potential_levels = potential_away_levels) + if(GLOB.random_zlevels_generated[name] || !length(potential_levels)) return - if(GLOB.potentialRandomZlevels && GLOB.potentialRandomZlevels.len) - to_chat(world, "Loading away mission...") - var/map = pick(GLOB.potentialRandomZlevels) - load_new_z_level(map, "Away Mission") - to_chat(world, "Away mission loaded.") + to_chat(world, "Loading [name]...") + var/map = pick(potential_levels) + load_new_z_level(map, name, traits) + to_chat(world, "[name] loaded.") + random_zlevels_generated[name] = TRUE /proc/reset_gateway_spawns(reset = FALSE) for(var/obj/machinery/gateway/G in world) diff --git a/code/modules/mapping/map_template.dm b/code/modules/mapping/map_template.dm index 3e361179de..5d8acec7e8 100644 --- a/code/modules/mapping/map_template.dm +++ b/code/modules/mapping/map_template.dm @@ -55,11 +55,11 @@ SSmachines.setup_template_powernets(cables) SSair.setup_template_machinery(atmos_machines) -/datum/map_template/proc/load_new_z() +/datum/map_template/proc/load_new_z(list/traits = list(ZTRAIT_AWAY = TRUE)) var/x = round((world.maxx - width)/2) var/y = round((world.maxy - height)/2) - var/datum/space_level/level = SSmapping.add_new_zlevel(name, list(ZTRAIT_AWAY = TRUE)) + var/datum/space_level/level = SSmapping.add_new_zlevel(name, traits) var/datum/parsed_map/parsed = load_map(file(mappath), x, y, level.z_value, no_changeturf=(SSatoms.initialized == INITIALIZATION_INSSATOMS), placeOnTop=TRUE) var/list/bounds = parsed.bounds if(!bounds) @@ -121,6 +121,6 @@ //for your ever biggening badminnery kevinz000 //❤ - Cyberboss -/proc/load_new_z_level(var/file, var/name) +/proc/load_new_z_level(file, name, list/traits) var/datum/map_template/template = new(file, name) - template.load_new_z() + template.load_new_z(traits) diff --git a/config/awaymissionconfig.txt b/config/awaymissionconfig.txt index 545394f3e9..ae52b8be14 100644 --- a/config/awaymissionconfig.txt +++ b/config/awaymissionconfig.txt @@ -7,16 +7,16 @@ #Do NOT tick the maps during compile -- the game uses this list to decide which map to load. Ticking the maps will result in them ALL being loaded at once. #DO tick the associated code file for the away mission you are enabling. Otherwise, the map will be trying to reference objects which do not exist, which will cause runtime errors! -#_maps/RandomZLevels/blackmarketpackers.dmm -#_maps/RandomZLevels/spacebattle.dmm -#_maps/RandomZLevels/TheBeach.dmm -#_maps/RandomZLevels/Academy.dmm -#_maps/RandomZLevels/wildwest.dmm -#_maps/RandomZLevels/challenge.dmm -#_maps/RandomZLevels/centcomAway.dmm -#_maps/RandomZLevels/moonoutpost19.dmm -#_maps/RandomZLevels/undergroundoutpost45.dmm -#_maps/RandomZLevels/caves.dmm -#_maps/RandomZLevels/snowdin.dmm -#_maps/RandomZLevels/research.dmm -#_maps/RandomZLevels/Cabin.dmm +#_maps/RandomZLevels/away_mission/blackmarketpackers.dmm +#_maps/RandomZLevels/away_mission/spacebattle.dmm +_maps/RandomZLevels/away_mission/TheBeach.dmm +_maps/RandomZLevels/away_mission/Academy.dmm +_maps/RandomZLevels/away_mission/wildwest.dmm +#_maps/RandomZLevels/away_mission/challenge.dmm +#_maps/RandomZLevels/away_mission/centcomAway.dmm +#_maps/RandomZLevels/away_mission/moonoutpost19.dmm +#_maps/RandomZLevels/away_mission/undergroundoutpost45.dmm +#_maps/RandomZLevels/away_mission/caves.dmm +#_maps/RandomZLevels/away_mission/snowdin.dmm +#_maps/RandomZLevels/away_mission/research.dmm +#_maps/RandomZLevels/away_mission/Cabin.dmm diff --git a/config/vr_config.txt b/config/vr_config.txt new file mode 100644 index 0000000000..a68a75e654 --- /dev/null +++ b/config/vr_config.txt @@ -0,0 +1,13 @@ +#List the potential virtual reality Z-levels here. awaymissionconfig copypasta follows. + +#Maps must be the full path to them +#Maps should be 255x255 or smaller and be bounded. Falling off the edge of the map will result in undefined behavior. +#SPECIFYING AN INVALID MAP WILL RESULT IN RUNTIMES ON GAME START + +#!!IMPORTANT NOTES FOR HOSTING VR MAPS!!: +#Do NOT tick the maps during compile -- the game uses this list to decide which map to load. Ticking the maps will result in them ALL being loaded at once. +#DO tick the associated code file for the virtual reality levels you are enabling. Otherwise, the map will be trying to reference objects which do not exist, which will cause runtime errors! + +_maps/RandomZLevels/VR/murderdome.dmm +_maps/RandomZLevels/VR/snowdin_VR.dm +_maps/RandomZLevels/VR/syndicate_trainer.dm \ No newline at end of file From a9be1e06e219c76990e2dd48160b69365a76ccec Mon Sep 17 00:00:00 2001 From: Ghommie <42542238+Ghommie@users.noreply.github.com> Date: Fri, 24 Apr 2020 23:00:31 +0200 Subject: [PATCH 47/55] Fixing stuff, it now should be ready. --- .../configuration/entries/game_options.dm | 2 ++ code/controllers/subsystem/mapping.dm | 12 +++++------- code/modules/awaymissions/zlevel.dm | 18 ++++++++++++------ code/modules/mapping/map_template.dm | 2 +- config/game_options.txt | 3 +++ config/vr_config.txt | 4 ++-- 6 files changed, 25 insertions(+), 16 deletions(-) diff --git a/code/controllers/configuration/entries/game_options.dm b/code/controllers/configuration/entries/game_options.dm index 1312183750..3c2d18d69c 100644 --- a/code/controllers/configuration/entries/game_options.dm +++ b/code/controllers/configuration/entries/game_options.dm @@ -288,6 +288,8 @@ /datum/config_entry/flag/roundstart_away //Will random away mission be loaded. +/datum/config_entry/flag/roundstart_vr //Will virtual reality missions be loaded? + /datum/config_entry/number/gateway_delay //How long the gateway takes before it activates. Default is half an hour. Only matters if roundstart_away is enabled. config_entry_value = 18000 min_val = 0 diff --git a/code/controllers/subsystem/mapping.dm b/code/controllers/subsystem/mapping.dm index 34e7439c38..89155cefb3 100644 --- a/code/controllers/subsystem/mapping.dm +++ b/code/controllers/subsystem/mapping.dm @@ -1,3 +1,5 @@ +#define INIT_ANNOUNCE(X) to_chat(world, "[X]"); log_world(X) + SUBSYSTEM_DEF(mapping) name = "Mapping" init_order = INIT_ORDER_MAPPING @@ -183,7 +185,6 @@ SUBSYSTEM_DEF(mapping) z_list = SSmapping.z_list -#define INIT_ANNOUNCE(X) to_chat(world, "[X]"); log_world(X) /datum/controller/subsystem/mapping/proc/LoadGroup(list/errorList, name, path, files, list/traits, list/default_traits, silent = FALSE) . = list() var/start_time = REALTIMEOFDAY @@ -267,7 +268,6 @@ SUBSYSTEM_DEF(mapping) msg += ", [FailedZs[I]]" msg += ". Yell at your server host!" INIT_ANNOUNCE(msg) -#undef INIT_ANNOUNCE GLOBAL_LIST_EMPTY(the_station_areas) @@ -450,14 +450,12 @@ GLOBAL_LIST_EMPTY(the_station_areas) lvl_name = "[mapfile] custom" to_chat(usr,"Loading [lvl_name]...") var/datum/map_template/template = new(mapfile, choice, ztraits) - level = template.load_new_z() + level = template.load_new_z(ztraits) else lvl_name = answer to_chat(usr,"Loading [lvl_name]...") - var/datum/map_template/template = new(lvl_name, choice, ztraits) - level = template.load_new_z() - else - return + var/datum/map_template/template = new(lvl_name, choice) + level = template.load_new_z(ztraits) message_admins("Admin [key_name_admin(usr)] has loaded [lvl_name] [choice].") log_admin("Admin [key_name(usr)] has loaded [lvl_name] [choice].") diff --git a/code/modules/awaymissions/zlevel.dm b/code/modules/awaymissions/zlevel.dm index 55a1c9dcc4..6c8d8287d8 100644 --- a/code/modules/awaymissions/zlevel.dm +++ b/code/modules/awaymissions/zlevel.dm @@ -1,13 +1,19 @@ -/proc/createRandomZlevel(name = AWAY_MISSION_NAME, list/traits = list(ZTRAIT_AWAY = TRUE), list/potential_levels = potential_away_levels) - if(GLOB.random_zlevels_generated[name] || !length(potential_levels)) +/proc/createRandomZlevel(name = AWAY_MISSION_NAME, list/traits = list(ZTRAIT_AWAY = TRUE), list/potential_levels = GLOB.potential_away_levels) + if(GLOB.random_zlevels_generated[name]) + stack_trace("[name] level already generated.") + return + if(!length(potential_levels)) + stack_trace("No potential [name] level to load has been found.") return - to_chat(world, "Loading [name]...") + var/start_time = REALTIMEOFDAY var/map = pick(potential_levels) - load_new_z_level(map, name, traits) - to_chat(world, "[name] loaded.") - random_zlevels_generated[name] = TRUE + if(!load_new_z_level(map, name, traits)) + INIT_ANNOUNCE("Failed to load [name]! map filepath: [map]!") + return + INIT_ANNOUNCE("Loaded [name] in [(REALTIMEOFDAY - start_time)/10]s!") + GLOB.random_zlevels_generated[name] = TRUE /proc/reset_gateway_spawns(reset = FALSE) for(var/obj/machinery/gateway/G in world) diff --git a/code/modules/mapping/map_template.dm b/code/modules/mapping/map_template.dm index 5d8acec7e8..873c10fc02 100644 --- a/code/modules/mapping/map_template.dm +++ b/code/modules/mapping/map_template.dm @@ -123,4 +123,4 @@ //❤ - Cyberboss /proc/load_new_z_level(file, name, list/traits) var/datum/map_template/template = new(file, name) - template.load_new_z(traits) + return template.load_new_z(traits) diff --git a/config/game_options.txt b/config/game_options.txt index e1294f688a..781be6d5b1 100644 --- a/config/game_options.txt +++ b/config/game_options.txt @@ -288,6 +288,9 @@ MINIMUM_SECBORG_ALERT 3 ## Uncomment to load one of the missions from awaymissionconfig.txt at roundstart. #ROUNDSTART_AWAY +## Uncomment to load one of the virtual reality levels from vr_config at roundstart. +#ROUNDSTART_VR + ## How long the delay is before the Away Mission gate opens. Default is half an hour. ## 600 is one minute. GATEWAY_DELAY 18000 diff --git a/config/vr_config.txt b/config/vr_config.txt index a68a75e654..0e8532eba5 100644 --- a/config/vr_config.txt +++ b/config/vr_config.txt @@ -9,5 +9,5 @@ #DO tick the associated code file for the virtual reality levels you are enabling. Otherwise, the map will be trying to reference objects which do not exist, which will cause runtime errors! _maps/RandomZLevels/VR/murderdome.dmm -_maps/RandomZLevels/VR/snowdin_VR.dm -_maps/RandomZLevels/VR/syndicate_trainer.dm \ No newline at end of file +_maps/RandomZLevels/VR/snowdin_VR.dmm +_maps/RandomZLevels/VR/syndicate_trainer.dmm \ No newline at end of file From 2ff75d8c99d359118a014f1ea09b62a6567ce49d Mon Sep 17 00:00:00 2001 From: Ghommie <42542238+Ghommie@users.noreply.github.com> Date: Fri, 24 Apr 2020 23:20:05 +0200 Subject: [PATCH 48/55] commenting lines. --- config/awaymissionconfig.txt | 6 +++--- config/vr_config.txt | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/config/awaymissionconfig.txt b/config/awaymissionconfig.txt index ae52b8be14..c6a5d9ef8f 100644 --- a/config/awaymissionconfig.txt +++ b/config/awaymissionconfig.txt @@ -9,9 +9,9 @@ #_maps/RandomZLevels/away_mission/blackmarketpackers.dmm #_maps/RandomZLevels/away_mission/spacebattle.dmm -_maps/RandomZLevels/away_mission/TheBeach.dmm -_maps/RandomZLevels/away_mission/Academy.dmm -_maps/RandomZLevels/away_mission/wildwest.dmm +#_maps/RandomZLevels/away_mission/TheBeach.dmm +#_maps/RandomZLevels/away_mission/Academy.dmm +#_maps/RandomZLevels/away_mission/wildwest.dmm #_maps/RandomZLevels/away_mission/challenge.dmm #_maps/RandomZLevels/away_mission/centcomAway.dmm #_maps/RandomZLevels/away_mission/moonoutpost19.dmm diff --git a/config/vr_config.txt b/config/vr_config.txt index 0e8532eba5..0c6354f8fe 100644 --- a/config/vr_config.txt +++ b/config/vr_config.txt @@ -8,6 +8,6 @@ #Do NOT tick the maps during compile -- the game uses this list to decide which map to load. Ticking the maps will result in them ALL being loaded at once. #DO tick the associated code file for the virtual reality levels you are enabling. Otherwise, the map will be trying to reference objects which do not exist, which will cause runtime errors! -_maps/RandomZLevels/VR/murderdome.dmm -_maps/RandomZLevels/VR/snowdin_VR.dmm -_maps/RandomZLevels/VR/syndicate_trainer.dmm \ No newline at end of file +#_maps/RandomZLevels/VR/murderdome.dmm +#_maps/RandomZLevels/VR/snowdin_VR.dmm +#_maps/RandomZLevels/VR/syndicate_trainer.dmm \ No newline at end of file From ca2d4ae28f2eb780274dab50f054d0a8781994ea Mon Sep 17 00:00:00 2001 From: Ghommie <42542238+Ghommie@users.noreply.github.com> Date: Fri, 24 Apr 2020 23:44:07 +0200 Subject: [PATCH 49/55] Fixing empty new lines on circuit examines. --- code/modules/integrated_electronics/core/assemblies.dm | 4 +++- .../integrated_electronics/core/integrated_circuit.dm | 6 ++++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/code/modules/integrated_electronics/core/assemblies.dm b/code/modules/integrated_electronics/core/assemblies.dm index e144e4dbe6..ef63ba97f8 100644 --- a/code/modules/integrated_electronics/core/assemblies.dm +++ b/code/modules/integrated_electronics/core/assemblies.dm @@ -79,7 +79,9 @@ for(var/I in assembly_components) var/obj/item/integrated_circuit/IC = I - . += IC.external_examine(user) + var/text = IC.external_examine(user) + if(text) + . += text if(opened) interact(user) diff --git a/code/modules/integrated_electronics/core/integrated_circuit.dm b/code/modules/integrated_electronics/core/integrated_circuit.dm index 0709b179d2..f90b584d76 100644 --- a/code/modules/integrated_electronics/core/integrated_circuit.dm +++ b/code/modules/integrated_electronics/core/integrated_circuit.dm @@ -36,7 +36,9 @@ a creative player the means to solve many problems. Circuits are held inside an /obj/item/integrated_circuit/examine(mob/user) interact(user) . = ..() - . += external_examine(user) + var/text = external_examine(user) + if(text) + . += text // Can be called via electronic_assembly/attackby() /obj/item/integrated_circuit/proc/additem(var/obj/item/I, var/mob/living/user) @@ -57,7 +59,7 @@ a creative player the means to solve many problems. Circuits are held inside an var/datum/integrated_io/activate/A = activators[k] if(A.linked.len) to_chat(user, "The '[A]' is connected to [A.get_linked_to_desc()].") - any_examine(user) + to_chat(user, any_examine(user)) interact(user) // This should be used when someone is examining from an 'outside' perspective, e.g. reading a screen or LED. From e17c51a85dc0ce2ee34d49c4800ec3797a5c9f79 Mon Sep 17 00:00:00 2001 From: Ghommie <42542238+Ghommie@users.noreply.github.com> Date: Sat, 25 Apr 2020 00:49:51 +0200 Subject: [PATCH 50/55] Porting some VV updates from tg. --- code/__DEFINES/traits.dm | 72 +++++---- code/__DEFINES/vv.dm | 1 + code/_globalvars/traits.dm | 138 ++++++++++++++++++ code/datums/datumvars.dm | 7 +- code/modules/admin/verbs/randomverbs.dm | 44 ++++++ .../admin/view_variables/modify_variables.dm | 7 +- .../admin/view_variables/topic_basic.dm | 28 ++++ tgstation.dme | 1 + 8 files changed, 255 insertions(+), 43 deletions(-) create mode 100644 code/_globalvars/traits.dm diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index e1fc8fa001..90943fccf5 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -152,6 +152,41 @@ #define TRAIT_PASSTABLE "passtable" #define TRAIT_GIANT "giant" #define TRAIT_DWARF "dwarf" +#define TRAIT_ALCOHOL_TOLERANCE "alcohol_tolerance" +#define TRAIT_AGEUSIA "ageusia" +#define TRAIT_HEAVY_SLEEPER "heavy_sleeper" +#define TRAIT_NIGHT_VISION "night_vision" +#define TRAIT_LIGHT_STEP "light_step" +#define TRAIT_SILENT_STEP "silent_step" +#define TRAIT_SPEEDY_STEP "speedy_step" +#define TRAIT_SPIRITUAL "spiritual" +#define TRAIT_VORACIOUS "voracious" +#define TRAIT_SELF_AWARE "self_aware" +#define TRAIT_FREERUNNING "freerunning" +#define TRAIT_SKITTISH "skittish" +#define TRAIT_POOR_AIM "poor_aim" +#define TRAIT_PROSOPAGNOSIA "prosopagnosia" +#define TRAIT_DRUNK_HEALING "drunk_healing" +#define TRAIT_TAGGER "tagger" +#define TRAIT_PHOTOGRAPHER "photographer" +#define TRAIT_MUSICIAN "musician" +#define TRAIT_PERMABONER "permanent_arousal" +#define TRAIT_NEVERBONER "never_aroused" +#define TRAIT_MASO "masochism" +#define TRAIT_HIGH_BLOOD "high_blood" +#define TRAIT_PARA "paraplegic" +#define TRAIT_EMPATH "empath" +#define TRAIT_FRIENDLY "friendly" +#define TRAIT_CULT_EYES "cult_eyes" +#define TRAIT_AUTO_CATCH_ITEM "auto_catch_item" +#define TRAIT_CLOWN_MENTALITY "clown_mentality" // The future is now, clownman. +#define TRAIT_FREESPRINT "free_sprinting" +#define TRAIT_XRAY_VISION "xray_vision" +#define TRAIT_THERMAL_VISION "thermal_vision" +#define TRAIT_NO_TELEPORT "no-teleport" //you just can't +#define TRAIT_NO_INTERNALS "no-internals" +#define TRAIT_NO_ALCOHOL "alcohol_intolerance" +#define TRAIT_MUTATION_STASIS "mutation_stasis" //Prevents processed genetics mutations from processing. // mobility flag traits // IN THE FUTURE, IT WOULD BE NICE TO DO SOMETHING SIMILAR TO https://github.com/tgstation/tgstation/pull/48923/files (ofcourse not nearly the same because I have my.. thoughts on it) @@ -185,43 +220,6 @@ // item traits #define TRAIT_NODROP "nodrop" -#define TRAIT_ALCOHOL_TOLERANCE "alcohol_tolerance" -#define TRAIT_AGEUSIA "ageusia" -#define TRAIT_HEAVY_SLEEPER "heavy_sleeper" -#define TRAIT_NIGHT_VISION "night_vision" -#define TRAIT_LIGHT_STEP "light_step" -#define TRAIT_SILENT_STEP "silent_step" -#define TRAIT_SPEEDY_STEP "speedy_step" -#define TRAIT_SPIRITUAL "spiritual" -#define TRAIT_VORACIOUS "voracious" -#define TRAIT_SELF_AWARE "self_aware" -#define TRAIT_FREERUNNING "freerunning" -#define TRAIT_SKITTISH "skittish" -#define TRAIT_POOR_AIM "poor_aim" -#define TRAIT_PROSOPAGNOSIA "prosopagnosia" -#define TRAIT_DRUNK_HEALING "drunk_healing" -#define TRAIT_TAGGER "tagger" -#define TRAIT_PHOTOGRAPHER "photographer" -#define TRAIT_MUSICIAN "musician" -#define TRAIT_PERMABONER "permanent_arousal" -#define TRAIT_NEVERBONER "never_aroused" -#define TRAIT_NYMPHO "nymphomania" -#define TRAIT_MASO "masochism" -#define TRAIT_HIGH_BLOOD "high_blood" -#define TRAIT_PARA "paraplegic" -#define TRAIT_EMPATH "empath" -#define TRAIT_FRIENDLY "friendly" -#define TRAIT_CULT_EYES "cult_eyes" -#define TRAIT_AUTO_CATCH_ITEM "auto_catch_item" -#define TRAIT_CLOWN_MENTALITY "clown_mentality" // The future is now, clownman. -#define TRAIT_FREESPRINT "free_sprinting" -#define TRAIT_XRAY_VISION "xray_vision" -#define TRAIT_THERMAL_VISION "thermal_vision" -#define TRAIT_NO_TELEPORT "no-teleport" //you just can't -#define TRAIT_NO_INTERNALS "no-internals" -#define TRAIT_NO_ALCOHOL "alcohol_intolerance" -#define TRAIT_MUTATION_STASIS "mutation_stasis" //Prevents processed genetics mutations from processing. - // common trait sources #define TRAIT_GENERIC "generic" #define EYE_DAMAGE "eye_damage" diff --git a/code/__DEFINES/vv.dm b/code/__DEFINES/vv.dm index ec7a11085c..a364e0b93c 100644 --- a/code/__DEFINES/vv.dm +++ b/code/__DEFINES/vv.dm @@ -73,6 +73,7 @@ #define VV_HK_EXPOSE "expose" #define VV_HK_CALLPROC "proc_call" #define VV_HK_MARK "mark" +#define VV_HK_ADDCOMPONENT "addcomponent" #define VV_HK_MODIFY_TRAITS "modtraits" // /atom diff --git a/code/_globalvars/traits.dm b/code/_globalvars/traits.dm new file mode 100644 index 0000000000..dd8b9f0d94 --- /dev/null +++ b/code/_globalvars/traits.dm @@ -0,0 +1,138 @@ +/* + FUN ZONE OF ADMIN LISTINGS + Try to keep this in sync with __DEFINES/traits.dm + quirks have it's own panel so we don't need them here. +*/ + +GLOBAL_LIST_INIT(traits_by_type, list( + /mob = list( + "TRAIT_BLIND" = TRAIT_BLIND, + "TRAIT_MUTE" = TRAIT_MUTE, + "TRAIT_EMOTEMUTE " = TRAIT_EMOTEMUTE, + "TRAIT_DEAF" = TRAIT_DEAF, + "TRAIT_NEARSIGHT" = TRAIT_NEARSIGHT, + "TRAIT_FAT" = TRAIT_FAT, + "TRAIT_HUSK" = TRAIT_HUSK, + "TRAIT_NOCLONE" = TRAIT_NOCLONE, + "TRAIT_CLUMSY" = TRAIT_CLUMSY, + "TRAIT_CHUNKYFINGERS" = TRAIT_CHUNKYFINGERS, + "TRAIT_DUMB" = TRAIT_DUMB, + "TRAIT_MONKEYLIKE" = TRAIT_MONKEYLIKE, + "TRAIT_PACIFISM" = TRAIT_PACIFISM, + "TRAIT_IGNORESLOWDOWN" = TRAIT_IGNORESLOWDOWN, + "TRAIT_DEATHCOMA" = TRAIT_DEATHCOMA, + "TRAIT_FAKEDEATH" = TRAIT_FAKEDEATH, + "TRAIT_DISFIGURED" = TRAIT_DISFIGURED, + "TRAIT_XENO_HOST" = TRAIT_XENO_HOST, + "TRAIT_STUNIMMUNE" = TRAIT_STUNIMMUNE, + "TRAIT_TASED_RESISTANCE" = TRAIT_TASED_RESISTANCE, + "TRAIT_SLEEPIMMUNE" = TRAIT_SLEEPIMMUNE, + "TRAIT_PUSHIMMUNE" = TRAIT_PUSHIMMUNE, + "TRAIT_SHOCKIMMUNE" = TRAIT_SHOCKIMMUNE, + "TRAIT_STABLEHEART" = TRAIT_STABLEHEART, + "TRAIT_STABLELIVER" = TRAIT_STABLELIVER, + "TRAIT_RESISTHEAT" = TRAIT_RESISTHEAT, + "TRAIT_RESISTHEATHANDS" = TRAIT_RESISTHEATHANDS, + "TRAIT_RESISTCOLD" = TRAIT_RESISTCOLD, + "TRAIT_RESISTHIGHPRESSURE" = TRAIT_RESISTHIGHPRESSURE, + "TRAIT_RESISTLOWPRESSURE" = TRAIT_RESISTLOWPRESSURE, + "TRAIT_RADIMMUNE" = TRAIT_RADIMMUNE, + "TRAIT_VIRUSIMMUNE" = TRAIT_VIRUSIMMUNE, + "TRAIT_PIERCEIMMUNE" = TRAIT_PIERCEIMMUNE, + "TRAIT_NODISMEMBER" = TRAIT_NODISMEMBER, + "TRAIT_NOFIRE" = TRAIT_NOFIRE, + "TRAIT_NOGUNS" = TRAIT_NOGUNS, + "TRAIT_NOHUNGER" = TRAIT_NOHUNGER, + "TRAIT_EASYDISMEMBER" = TRAIT_EASYDISMEMBER, + "TRAIT_LIMBATTACHMENT" = TRAIT_LIMBATTACHMENT, + "TRAIT_NOLIMBDISABLE" = TRAIT_NOLIMBDISABLE, + "TRAIT_EASYLIMBDISABLE" = TRAIT_EASYLIMBDISABLE, + "TRAIT_TOXINLOVER" = TRAIT_TOXINLOVER, + "TRAIT_NOBREATH" = TRAIT_NOBREATH, + "TRAIT_ANTIMAGIC" = TRAIT_ANTIMAGIC, + "TRAIT_HOLY" = TRAIT_HOLY, + "TRAIT_DEPRESSION" = TRAIT_DEPRESSION, + "TRAIT_JOLLY" = TRAIT_JOLLY, + "TRAIT_NOCRITDAMAGE" = TRAIT_NOCRITDAMAGE, + "TRAIT_NOSLIPWATER" = TRAIT_NOSLIPWATER, + "TRAIT_NOSLIPALL" = TRAIT_NOSLIPALL, + "TRAIT_NODEATH" = TRAIT_NODEATH, + "TRAIT_NOHARDCRIT" = TRAIT_NOHARDCRIT, + "TRAIT_NOSOFTCRIT" = TRAIT_NOSOFTCRIT, + "TRAIT_MINDSHIELD" = TRAIT_MINDSHIELD, + "TRAIT_HIJACKER" = TRAIT_HIJACKER, + "TRAIT_DISSECTED" = TRAIT_DISSECTED, + "TRAIT_SIXTHSENSE" = TRAIT_SIXTHSENSE, + "TRAIT_FEARLESS" = TRAIT_FEARLESS, + "TRAIT_PARALYSIS_L_ARM" = TRAIT_PARALYSIS_L_ARM, + "TRAIT_PARALYSIS_R_ARM" = TRAIT_PARALYSIS_R_ARM, + "TRAIT_PARALYSIS_L_LEG" = TRAIT_PARALYSIS_L_LEG, + "TRAIT_PARALYSIS_R_LEG" = TRAIT_PARALYSIS_R_LEG, + "TRAIT_DISK_VERIFIER" = TRAIT_DISK_VERIFIER, + "TRAIT_XRAY_VISION" = TRAIT_XRAY_VISION, + "TRAIT_THERMAL_VISION" = TRAIT_THERMAL_VISION, + "TRAIT_ABDUCTOR_TRAINING" = TRAIT_ABDUCTOR_TRAINING, + "TRAIT_ABDUCTOR_SCIENTIST_TRAINING" = TRAIT_ABDUCTOR_SCIENTIST_TRAINING, + "TRAIT_SURGEON" = TRAIT_SURGEON, + "TRAIT_STRONG_GRABBER" = TRAIT_STRONG_GRABBER, + "TRAIT_MAGIC_CHOKE" = TRAIT_MAGIC_CHOKE, + "TRAIT_SOOTHED_THROAT" = TRAIT_SOOTHED_THROAT, + "TRAIT_LAW_ENFORCEMENT_METABOLISM" = TRAIT_LAW_ENFORCEMENT_METABOLISM, + "TRAIT_UNINTELLIGIBLE_SPEECH" = TRAIT_UNINTELLIGIBLE_SPEECH, + "TRAIT_UNSTABLE" = TRAIT_UNSTABLE, + "TRAIT_COLDBLOODED" = TRAIT_COLDBLOODED, + "TRAIT_NONATURALHEAL" = TRAIT_NONATURALHEAL, + "TRAIT_NORUNNING" = TRAIT_NORUNNING, + "TRAIT_NOMARROW" = TRAIT_NOMARROW, + "TRAIT_NOPULSE" = TRAIT_NOPULSE, + "TRAIT_EXEMPT_HEALTH_EVENTS" = TRAIT_EXEMPT_HEALTH_EVENTS, + "TRAIT_NO_MIDROUND_ANTAG" = TRAIT_NO_MIDROUND_ANTAG, + "TRAIT_PUGILIST" = TRAIT_PUGILIST, + "TRAIT_KI_VAMPIRE" = TRAIT_KI_VAMPIRE, + "TRAIT_PASSTABLE" = TRAIT_PASSTABLE, + "TRAIT_GIANT" = TRAIT_GIANT, + "TRAIT_DWARF" = TRAIT_DWARF, + "TRAIT_COMBAT_MODE_LOCKED" = TRAIT_COMBAT_MODE_LOCKED, + "TRAIT_SPRINT_LOCKED" = TRAIT_SPRINT_LOCKED, + "TRAIT_AUTO_CATCH_ITEM" = TRAIT_AUTO_CATCH_ITEM, + "TRAIT_FREESPRINT" = TRAIT_FREESPRINT, + "TRAIT_NO_INTERNALS" = TRAIT_NO_INTERNALS, + "TRAIT_NO_ALCOHOL" = TRAIT_NO_ALCOHOL, + "TRAIT_MUTATION_STASIS" = TRAIT_MUTATION_STASIS, + "TRAIT_HEAVY_SLEEPER" = TRAIT_HEAVY_SLEEPER, + "TRAIT_LIGHT_STEP" = TRAIT_LIGHT_STEP, + "TRAIT_SILENT_STEP" = TRAIT_SILENT_STEP, + "TRAIT_VORACIOUS" = TRAIT_VORACIOUS, + "TRAIT_SELF_AWARE" = TRAIT_SELF_AWARE, + "TRAIT_FREERUNNING" = TRAIT_FREERUNNING, + "TRAIT_SKITTISH" = TRAIT_SKITTISH, + "TRAIT_POOR_AIM" = TRAIT_POOR_AIM, + "TRAIT_PROSOPAGNOSIA" = TRAIT_PROSOPAGNOSIA, + "TRAIT_DRUNK_HEALING" = TRAIT_DRUNK_HEALING, + "TRAIT_TAGGER" = TRAIT_TAGGER, + "TRAIT_PHOTOGRAPHER" = TRAIT_PHOTOGRAPHER, + "TRAIT_MUSICIAN" = TRAIT_MUSICIAN, + "TRAIT_MASO" = TRAIT_MASO, + "TRAIT_HIGH_BLOOD" = TRAIT_HIGH_BLOOD, + "TRAIT_EMPATH" = TRAIT_EMPATH, + "TRAIT_FRIENDLY" = TRAIT_FRIENDLY + ), + /obj/item/bodypart = list( + "TRAIT_PARALYSIS" = TRAIT_PARALYSIS + ), + /obj/item = list( + "TRAIT_NODROP" = TRAIT_NODROP, + "TRAIT_NO_TELEPORT" = TRAIT_NO_TELEPORT + ) + )) + + +/// value -> trait name, generated on use from trait_by_type global +GLOBAL_LIST(trait_name_map) + +/proc/generate_trait_name_map() + . = list() + for(var/key in GLOB.traits_by_type) + for(var/tname in GLOB.traits_by_type[key]) + var/val = GLOB.traits_by_type[key][tname] + .[val] = tname diff --git a/code/datums/datumvars.dm b/code/datums/datumvars.dm index f97fde6f7e..348f9e6778 100644 --- a/code/datums/datumvars.dm +++ b/code/datums/datumvars.dm @@ -29,7 +29,8 @@ VV_DROPDOWN_OPTION(VV_HK_MARK, "Mark Object") VV_DROPDOWN_OPTION(VV_HK_DELETE, "Delete") VV_DROPDOWN_OPTION(VV_HK_EXPOSE, "Show VV To Player") -// VV_DROPDOWN_OPTION(VV_HK_MODIFY_TRAITS, "Modify Traits") + VV_DROPDOWN_OPTION(VV_HK_ADDCOMPONENT, "Add Component/Element") + VV_DROPDOWN_OPTION(VV_HK_MODIFY_TRAITS, "Modify Traits") //This proc is only called if everything topic-wise is verified. The only verifications that should happen here is things like permission checks! //href_list is a reference, modifying it in these procs WILL change the rest of the proc in topic.dm of admin/view_variables! @@ -37,8 +38,8 @@ /datum/proc/vv_do_topic(list/href_list) if(!usr || !usr.client || !usr.client.holder || !check_rights(NONE)) return FALSE //This is VV, not to be called by anything else. -// if(href_list[VV_HK_MODIFY_TRAITS]) -// usr.client.holder.modify_traits(src) + if(href_list[VV_HK_MODIFY_TRAITS]) + usr.client.holder.modify_traits(src) return TRUE /datum/proc/vv_get_header() diff --git a/code/modules/admin/verbs/randomverbs.dm b/code/modules/admin/verbs/randomverbs.dm index ef8a63a728..5530225130 100644 --- a/code/modules/admin/verbs/randomverbs.dm +++ b/code/modules/admin/verbs/randomverbs.dm @@ -1379,3 +1379,47 @@ GLOBAL_LIST_EMPTY(custom_outfits) //Admin created outfits else message_admins("[key_name_admin(usr)] has [newstate ? "activated" : "deactivated"] job exp exempt status on [key_name_admin(C)]") log_admin("[key_name(usr)] has [newstate ? "activated" : "deactivated"] job exp exempt status on [key_name(C)]") + +/// Allow admin to add or remove traits of datum +/datum/admins/proc/modify_traits(datum/D) + if(!D) + return + + var/add_or_remove = input("Remove/Add?", "Trait Remove/Add") as null|anything in list("Add","Remove") + if(!add_or_remove) + return + var/list/availible_traits = list() + + switch(add_or_remove) + if("Add") + for(var/key in GLOB.traits_by_type) + if(istype(D,key)) + availible_traits += GLOB.traits_by_type[key] + if("Remove") + if(!GLOB.trait_name_map) + GLOB.trait_name_map = generate_trait_name_map() + for(var/trait in D.status_traits) + var/name = GLOB.trait_name_map[trait] || trait + availible_traits[name] = trait + + var/chosen_trait = input("Select trait to modify", "Trait") as null|anything in sortList(availible_traits) + if(!chosen_trait) + return + chosen_trait = availible_traits[chosen_trait] + + var/source = "adminabuse" + switch(add_or_remove) + if("Add") //Not doing source choosing here intentionally to make this bit faster to use, you can always vv it. + ADD_TRAIT(D,chosen_trait,source) + if("Remove") + var/specific = input("All or specific source ?", "Trait Remove/Add") as null|anything in list("All","Specific") + if(!specific) + return + switch(specific) + if("All") + source = null + if("Specific") + source = input("Source to be removed","Trait Remove/Add") as null|anything in sortList(D.status_traits[chosen_trait]) + if(!source) + return + REMOVE_TRAIT(D,chosen_trait,source) diff --git a/code/modules/admin/view_variables/modify_variables.dm b/code/modules/admin/view_variables/modify_variables.dm index a4ed4d45bd..5f80b3a5e4 100644 --- a/code/modules/admin/view_variables/modify_variables.dm +++ b/code/modules/admin/view_variables/modify_variables.dm @@ -194,9 +194,10 @@ GLOBAL_PROTECT(VVpixelmovement) else variable = L[index] //EXPERIMENTAL - Keep old associated value while modifying key, if any - var/found = L[variable] - if(!isnull(found)) - old_assoc_value = found + if(IS_VALID_ASSOC_KEY(variable)) + var/found = L[variable] + if(!isnull(found)) + old_assoc_value = found // default = vv_get_class(objectvar, variable) diff --git a/code/modules/admin/view_variables/topic_basic.dm b/code/modules/admin/view_variables/topic_basic.dm index 2a0f3d7302..d6e4c2b944 100644 --- a/code/modules/admin/view_variables/topic_basic.dm +++ b/code/modules/admin/view_variables/topic_basic.dm @@ -47,5 +47,33 @@ usr.client.debug_variables(src) if(href_list[VV_HK_MARK]) usr.client.mark_datum(target) + if(href_list[VV_HK_ADDCOMPONENT]) + if(!check_rights(NONE)) + return + var/list/names = list() + var/list/componentsubtypes = subtypesof(/datum/component) + names += "---Components---" + names += componentsubtypes + names += "---Elements---" + names += subtypesof(/datum/element) + var/result = input(usr, "Choose a component/element to add","better know what ur fuckin doin pal") as null|anything in names + if(!usr || !result || result == "---Components---" || result == "---Elements---") + return + if(QDELETED(src)) + to_chat(usr, "That thing doesn't exist anymore!") + return + var/list/lst = get_callproc_args() + if(!lst) + return + var/datumname = "error" + lst.Insert(1, result) + if(result in componentsubtypes) + datumname = "component" + target._AddComponent(lst) + else + datumname = "element" + target._AddElement(lst) + log_admin("[key_name(usr)] has added [result] [datumname] to [key_name(src)].") + message_admins("[key_name_admin(usr)] has added [result] [datumname] to [key_name_admin(src)].") if(href_list[VV_HK_CALLPROC]) usr.client.callproc_datum(target) diff --git a/tgstation.dme b/tgstation.dme index 7bfbd2dde2..36436e93db 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -175,6 +175,7 @@ #include "code\_globalvars\logging.dm" #include "code\_globalvars\misc.dm" #include "code\_globalvars\regexes.dm" +#include "code\_globalvars\traits.dm" #include "code\_globalvars\lists\flavor_misc.dm" #include "code\_globalvars\lists\maintenance_loot.dm" #include "code\_globalvars\lists\mapping.dm" From 17f60990137ba36b98a0e51ad86751e73ea79d04 Mon Sep 17 00:00:00 2001 From: Putnam Date: Fri, 24 Apr 2020 16:18:34 -0700 Subject: [PATCH 51/55] new clamp --- code/game/gamemodes/dynamic/dynamic_storytellers.dm | 2 +- tgstation.dme | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/code/game/gamemodes/dynamic/dynamic_storytellers.dm b/code/game/gamemodes/dynamic/dynamic_storytellers.dm index 5fd8bdb3f5..561b38fde1 100644 --- a/code/game/gamemodes/dynamic/dynamic_storytellers.dm +++ b/code/game/gamemodes/dynamic/dynamic_storytellers.dm @@ -115,7 +115,7 @@ Property weights are: return 100 var/threat_perc = mode.threat/mode.threat_level - return CLAMP(round(100*(1-(threat_perc*threat_perc))**2,1),0,100) + return clamp(round(100*(1-(threat_perc*threat_perc))**2,1),0,100) /datum/dynamic_storyteller/proc/roundstart_draft() var/list/drafted_rules = list() diff --git a/tgstation.dme b/tgstation.dme index 7bfbd2dde2..23c652f3ef 100755 --- a/tgstation.dme +++ b/tgstation.dme @@ -518,6 +518,7 @@ #include "code\datums\elements\mob_holder.dm" #include "code\datums\elements\polychromic.dm" #include "code\datums\elements\spellcasting.dm" +#include "code\datums\elements\squish.dm" #include "code\datums\elements\swimming.dm" #include "code\datums\elements\sword_point.dm" #include "code\datums\elements\update_icon_blocker.dm" From 0f654d9f0e79016f2abf5801f96fe1dcc4e3a2b0 Mon Sep 17 00:00:00 2001 From: Ghommie <42542238+Ghommie@users.noreply.github.com> Date: Sat, 25 Apr 2020 02:23:13 +0200 Subject: [PATCH 52/55] Fixing dresses being invisible on digitigrades. --- code/modules/clothing/under/skirt_dress.dm | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/code/modules/clothing/under/skirt_dress.dm b/code/modules/clothing/under/skirt_dress.dm index a7e842282c..e1212cf337 100644 --- a/code/modules/clothing/under/skirt_dress.dm +++ b/code/modules/clothing/under/skirt_dress.dm @@ -1,4 +1,4 @@ -/obj/item/clothing/under/dress/skirt +/obj/item/clothing/under/dress mutantrace_variation = STYLE_DIGITIGRADE|STYLE_NO_ANTHRO_ICON /obj/item/clothing/under/dress/skirt @@ -182,7 +182,6 @@ icon_state = "bride_white" item_state = "bride_white" can_adjust = FALSE - mutantrace_variation = NONE /obj/item/clothing/under/dress/wedding/orange name = "orange wedding dress" @@ -213,7 +212,6 @@ desc = "A fancy skirt made with polychromic threads." icon_state = "polyskirt" item_state = "rainbow" - mutantrace_variation = NONE var/list/poly_colors = list("#FFFFFF", "#F08080", "#808080") /obj/item/clothing/under/dress/skirt/polychromic/ComponentInitialize() @@ -226,5 +224,4 @@ icon_state = "polypleat" item_state = "rainbow" body_parts_covered = CHEST|GROIN|ARMS - mutantrace_variation = NONE poly_colors = list("#8CC6FF", "#808080", "#FF3535") From cbe2daea94e29403d615c2b8f83e5ae586d81da8 Mon Sep 17 00:00:00 2001 From: kevinz000 <2003111+kevinz000@users.noreply.github.com> Date: Fri, 24 Apr 2020 23:52:49 -0700 Subject: [PATCH 53/55] Update callproc.dm --- code/modules/admin/callproc/callproc.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/admin/callproc/callproc.dm b/code/modules/admin/callproc/callproc.dm index 3de5e39ff4..c13353b7cd 100644 --- a/code/modules/admin/callproc/callproc.dm +++ b/code/modules/admin/callproc/callproc.dm @@ -120,7 +120,7 @@ GLOBAL_PROTECT(AdminProcCallSpamPrevention) //adv proc call this, ya nerds /world/proc/WrapAdminProcCall(datum/target, procname, list/arguments) if(target == GLOBAL_PROC) - return call(procname)(arglist(arguments)) + return call(text2path("/proc/[procname]"))(arglist(arguments)) else if(target != world) return call(target, procname)(arglist(arguments)) else From 5e750bd43dd325c2de71069dc7c2b6a21685c57f Mon Sep 17 00:00:00 2001 From: kevinz000 <2003111+kevinz000@users.noreply.github.com> Date: Sat, 25 Apr 2020 17:21:33 -0700 Subject: [PATCH 54/55] Update pins.dm --- code/modules/projectiles/pins.dm | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/code/modules/projectiles/pins.dm b/code/modules/projectiles/pins.dm index 9fbe742d39..51f1d6a337 100644 --- a/code/modules/projectiles/pins.dm +++ b/code/modules/projectiles/pins.dm @@ -253,8 +253,8 @@ /obj/item/firing_pin/security_level/Initialize() . = ..() - fail_message = "INVALID SECURITY LEVEL. CURRENT: [uppertext(num2seclevel(GLOB.security_level))]. \ - MIN: [uppertext(num2seclevel(min_sec_level))]. MAX: [uppertext(num2seclevel(max_sec_level))]. \ + fail_message = "INVALID SECURITY LEVEL. CURRENT: [uppertext(NUM2SECLEVLE(GLOB.security_level))]. \ + MIN: [uppertext(NUM2SECLEVEL(min_sec_level))]. MAX: [uppertext(NUM2SECLEVEL(max_sec_level))]. \ ONLY LETHALS: [only_lethals ? "YES" : "NO"]." update_icon() @@ -262,9 +262,9 @@ . = ..() var/lethal = only_lethals ? "only lethal " : "" if(min_sec_level != max_sec_level) - . += "It's currently set to disallow [lethal]operation when the security level isn't between [num2seclevel(min_sec_level)] and [num2seclevel(max_sec_level)]." + . += "It's currently set to disallow [lethal]operation when the security level isn't between [NUM2SECLEVEL(min_sec_level)] and [NUM2SECLEVEL(max_sec_level)]." else - . += "It's currently set to disallow [lethal]operation when the security level isn't [num2seclevel(min_sec_level)]." + . += "It's currently set to disallow [lethal]operation when the security level isn't [NUM2SECLEVEL(min_sec_level)]." if(can_toggle) . += "You can use a multitool to modify its settings." @@ -278,14 +278,14 @@ var/static/list/till_designs_pr_isnt_merged = list("green", "blue", "amber", "red", "delta") switch(selection) if("Minimum Level Setting") - var/input = input(user, "Input the new minimum level setting.", "Firing Pin Settings", num2seclevel(min_sec_level)) as null|anything in till_designs_pr_isnt_merged + var/input = input(user, "Input the new minimum level setting.", "Firing Pin Settings", NUM2SECLEVEL(min_sec_level)) as null|anything in till_designs_pr_isnt_merged if(!input) return min_sec_level = till_designs_pr_isnt_merged.Find(input) - 1 if(min_sec_level > max_sec_level) max_sec_level = SEC_LEVEL_DELTA if("Maximum Level Setting") - var/input = input(user, "Input the new maximum level setting.", "Firing Pin Settings", num2seclevel(max_sec_level)) as null|anything in till_designs_pr_isnt_merged + var/input = input(user, "Input the new maximum level setting.", "Firing Pin Settings", NUM2SECLEVEL(max_sec_level)) as null|anything in till_designs_pr_isnt_merged if(!input) return max_sec_level = till_designs_pr_isnt_merged.Find(input) - 1 @@ -294,8 +294,8 @@ if("Lethals Only Toggle") only_lethals = !only_lethals - fail_message = "INVALID SECURITY LEVEL. CURRENT: [uppertext(num2seclevel(GLOB.security_level))]. \ - MIN: [uppertext(num2seclevel(min_sec_level))]. MAX: [uppertext(num2seclevel(max_sec_level))]. \ + fail_message = "INVALID SECURITY LEVEL. CURRENT: [uppertext(NUM2SECLEVEL(GLOB.security_level))]. \ + MIN: [uppertext(NUM2SECLEVEL(min_sec_level))]. MAX: [uppertext(NUM2SECLEVEL(max_sec_level))]. \ ONLY LETHALS: [only_lethals ? "YES" : "NO"]." update_icon() From 8fc661ba14baa0da9db5fcc40883849f2ad9228e Mon Sep 17 00:00:00 2001 From: kevinz000 <2003111+kevinz000@users.noreply.github.com> Date: Sat, 25 Apr 2020 17:34:00 -0700 Subject: [PATCH 55/55] Update pins.dm --- code/modules/projectiles/pins.dm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/modules/projectiles/pins.dm b/code/modules/projectiles/pins.dm index 51f1d6a337..8a1db49762 100644 --- a/code/modules/projectiles/pins.dm +++ b/code/modules/projectiles/pins.dm @@ -253,7 +253,7 @@ /obj/item/firing_pin/security_level/Initialize() . = ..() - fail_message = "INVALID SECURITY LEVEL. CURRENT: [uppertext(NUM2SECLEVLE(GLOB.security_level))]. \ + fail_message = "INVALID SECURITY LEVEL. CURRENT: [uppertext(NUM2SECLEVEL(GLOB.security_level))]. \ MIN: [uppertext(NUM2SECLEVEL(min_sec_level))]. MAX: [uppertext(NUM2SECLEVEL(max_sec_level))]. \ ONLY LETHALS: [only_lethals ? "YES" : "NO"]." update_icon()