Merge branch 'master' of https://github.com/tgstation/tgstation into upstream-23-10-2025

This commit is contained in:
Roxy
2025-10-23 17:38:23 -04:00
453 changed files with 20635 additions and 15897 deletions
@@ -1256,7 +1256,7 @@ Basically, we fill the time between now and 2s from now with hands based off the
var/picked_color = pick(random_color_list)
var/color_filter = color_transition_filter(picked_color, SATURATION_OVERRIDE)
if (can_color_clothing && (methods & (TOUCH|VAPOR|INHALE)))
var/include_flags = INCLUDE_HELD|INCLUDE_ACCESSORIES
var/include_flags = INCLUDE_HELD|INCLUDE_ACCESSORIES|INCLUDE_PROSTHETICS|INCLUDE_ABSTRACT
if (methods & (VAPOR|INHALE) || touch_protection >= 1)
include_flags |= INCLUDE_POCKETS
for (var/obj/item/to_color in exposed_mob.get_equipped_items(include_flags))
@@ -829,7 +829,7 @@
if(eyes.apply_organ_damage(-2 * REM * seconds_per_tick * normalise_creation_purity(), required_organ_flag = affected_organ_flags))
. = UPDATE_MOB_HEALTH
// If our eyes are seriously damaged, we have a probability of causing eye blur while healing depending on purity
if(eyes.damaged && IS_ORGANIC_ORGAN(eyes) && SPT_PROB(16 - min(normalized_purity * 6, 12), seconds_per_tick))
if(eyes.damage >= eyes.low_threshold && IS_ORGANIC_ORGAN(eyes) && SPT_PROB(16 - min(normalized_purity * 6, 12), seconds_per_tick))
// While healing, gives some eye blur
if(affected_mob.is_blind_from(EYE_DAMAGE))
to_chat(affected_mob, span_warning("Your vision slowly returns..."))
@@ -929,7 +929,9 @@
var/obj/item/organ/ears/ears = affected_mob.get_organ_slot(ORGAN_SLOT_EARS)
if(!ears)
return
ears.adjustEarDamage(-4 * REM * seconds_per_tick * normalise_creation_purity(), -4 * REM * seconds_per_tick * normalise_creation_purity())
var/multiplier = REM * seconds_per_tick * normalise_creation_purity()
ears.apply_organ_damage(-4 * multiplier)
ears.adjust_temporary_deafness(-8 * multiplier)
return UPDATE_MOB_HEALTH
/datum/reagent/medicine/inacusiate/on_mob_delete(mob/living/affected_mob)
@@ -1779,6 +1781,7 @@
overdose_threshold = 50
metabolization_rate = 0.5 * REAGENTS_METABOLISM //same as C2s
chemical_flags = REAGENT_CAN_BE_SYNTHESIZED
metabolized_traits = list(TRAIT_ANALGESIA)
/datum/reagent/medicine/granibitaluri/on_mob_life(mob/living/carbon/affected_mob, seconds_per_tick, times_fired)
. = ..()
@@ -3277,8 +3277,7 @@
RegisterSignal(affected_human, COMSIG_CARBON_LOSE_ORGAN, PROC_REF(on_organ_removed))
var/obj/item/organ/eyes/eyes = affected_human.get_organ_slot(ORGAN_SLOT_EYES)
if (eyes && !IS_ROBOTIC_ORGAN(eyes))
prev_ignore_lighting = eyes.overlay_ignore_lighting
eyes.overlay_ignore_lighting = TRUE
ADD_TRAIT(affected_human, TRAIT_LUMINESCENT_EYES, REF(src))
/datum/reagent/luminescent_fluid/on_mob_end_metabolize(mob/living/affected_mob)
. = ..()
@@ -3290,7 +3289,7 @@
affected_human.remove_eye_color(EYE_COLOR_LUMINESCENT_PRIORITY)
var/obj/item/organ/eyes/eyes = affected_human.get_organ_slot(ORGAN_SLOT_EYES)
if (eyes && !IS_ROBOTIC_ORGAN(eyes) && !overdosed)
eyes.overlay_ignore_lighting = prev_ignore_lighting
REMOVE_TRAIT(affected_human, TRAIT_LUMINESCENT_EYES, REF(src))
/datum/reagent/luminescent_fluid/on_mob_life(mob/living/affected_mob, seconds_per_tick, times_fired)
. = ..()
@@ -3309,14 +3308,13 @@
SIGNAL_HANDLER
if (istype(new_eyes) && !IS_ROBOTIC_ORGAN(new_eyes))
prev_ignore_lighting = new_eyes.overlay_ignore_lighting
new_eyes.overlay_ignore_lighting = TRUE
ADD_TRAIT(source, TRAIT_LUMINESCENT_EYES, REF(src))
/datum/reagent/luminescent_fluid/proc/on_organ_removed(mob/living/source, obj/item/organ/eyes/old_eyes)
SIGNAL_HANDLER
if (istype(old_eyes) && !IS_ROBOTIC_ORGAN(old_eyes) && !overdosed)
old_eyes.overlay_ignore_lighting = prev_ignore_lighting
REMOVE_TRAIT(source, TRAIT_LUMINESCENT_EYES, REF(src))
/datum/reagent/luminescent_fluid/overdose_start(mob/living/affected_mob)
. = ..()
@@ -144,3 +144,31 @@
holder.update_total()
#undef SPEED_REAGENT_STRENGTH
/datum/reagent/reaction_agent/inversing_buffer
name = "Chiral Inversing Buffer"
description = "This reagent will consume itself and convert impure reagents into their inversed counterparts. Amount varies based on volume of added buffer."
ph = 7
color = "#b60046"
/datum/reagent/reaction_agent/inversing_buffer/intercept_reagents_transfer(datum/reagents/target, amount, copy_only)
. = ..()
if(!.)
return
for(var/_reagent in target.reagent_list)
var/datum/reagent/reaction_agent/reagent = _reagent
if(reagent.purity <= reagent.inverse_chem_val)
target.my_atom.audible_message(span_warning("The beaker goes into a rolling boil as the contents begin inversing!"))
playsound(target.my_atom, 'sound/effects/chemistry/catalyst.ogg', 50, TRUE)
var/converted = min(reagent.volume, amount * 10)//Converts up to 10 units of reagent per 1 unit of inversing buffer.
if(converted > 0)
target.remove_reagent(reagent.type, converted, safety = FALSE)
target.add_reagent(reagent.inverse_chem, converted, FALSE, added_purity = reagent.get_inverse_purity(reagent.purity))
volume -= amount
holder.update_total()
break
else
target.my_atom.audible_message(span_warning("The buffer quietly fizzles away with no effect."))
volume -= amount
holder.update_total()
@@ -78,6 +78,7 @@
holder.clear_reagents()
/datum/chemical_reaction/meth_crystal //Since the meth is a cooled pharmaceutical solvent, this precipitates it into a solid.
results = list(/datum/reagent/consumable/ethanol = 1) //we don't care what this reagent is. We only need to record its purity
required_reagents = list(/datum/reagent/drug/methamphetamine = 10, /datum/reagent/toxin/acid = 2)
mob_react = FALSE
reaction_flags = REACTION_INSTANT
@@ -86,36 +87,21 @@
/datum/chemical_reaction/meth_crystal/on_reaction(datum/reagents/holder, datum/equilibrium/reaction, created_volume)
var/location = get_turf(holder.my_atom)
// Calculate purity ignoring sulfuric acid
var/total_nonacid = 0
var/meth_amt_in_mix = 0
for(var/datum/reagent/R in holder.reagent_list)
if(istype(R, /datum/reagent/toxin/acid))
continue // acid doesn't count against purity
total_nonacid += R.volume
if(istype(R, /datum/reagent/drug/methamphetamine))
meth_amt_in_mix += R.volume
var/purity = (total_nonacid > 0) ? (meth_amt_in_mix / total_nonacid) : 0.5 //All this tints the crystal above blue purity.
var/datum/reagent/consumable/ethanol/dummy_reagent = holder.has_reagent(/datum/reagent/consumable/ethanol)
for(var/i in 1 to round(created_volume, CHEMICAL_VOLUME_ROUNDING))
var/obj/item/food/drug/meth_crystal/new_crystal = new(location)
new_crystal.pixel_x = rand(-6, 6)
new_crystal.pixel_y = rand(-6, 6)
new_crystal.color = gradient("#FAFAFA", "#78C8FA", dummy_reagent.creation_purity)
var/effective_purity = 0
if(purity > 0.9)
effective_purity = (purity - 0.9) / 0.1
var/meth_amt = 10
new_crystal.reagents.add_reagent(/datum/reagent/drug/methamphetamine, meth_amt)
var/imp_amt = round(meth_amt * (1 - dummy_reagent.creation_purity) * 0.25, 0.1)
if(imp_amt > 0)
new_crystal.reagents.add_reagent(/datum/reagent/consumable/failed_reaction, imp_amt)
new_crystal.color = BlendRGB("#FAFAFA", "#78C8FA", effective_purity)
if(new_crystal.reagents)
new_crystal.reagents.clear_reagents()
var/meth_amt = 10
new_crystal.reagents.add_reagent(/datum/reagent/drug/methamphetamine, meth_amt)
var/imp_amt = round(meth_amt * (1 - purity) * 0.25, 0.1)
if(imp_amt > 0)
new_crystal.reagents.add_reagent(/datum/reagent/consumable/failed_reaction, imp_amt)
dummy_reagent.volume = 0
holder.update_total()
/datum/chemical_reaction/bath_salts
results = list(/datum/reagent/drug/bath_salts = 7)
@@ -9,6 +9,11 @@
required_reagents = list(/datum/reagent/water = 1, /datum/reagent/silicon = 1, /datum/reagent/oxygen = 1)
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_UNIQUE | REACTION_TAG_OTHER
/datum/chemical_reaction/lube/superlube
results = list(/datum/reagent/lube/superlube = 3)
required_reagents = list(/datum/reagent/lube = 1, /datum/reagent/medicine/strange_reagent = 1, /datum/reagent/consumable/banana = 1)
reaction_tags = REACTION_TAG_EASY | REACTION_TAG_UNIQUE | REACTION_TAG_OTHER
/datum/chemical_reaction/spraytan
results = list(/datum/reagent/spraytan = 2)
required_reagents = list(/datum/reagent/consumable/orangejuice = 1, /datum/reagent/fuel/oil = 1)
@@ -65,6 +65,16 @@
required_reagents = list(/datum/reagent/uranium/radium = 1)
required_container = /obj/item/slime_extract/green
/datum/chemical_reaction/slime/slimefelinid
results = list(/datum/reagent/mutationtoxin/felinid = 1)
required_reagents = list(/datum/reagent/consumable/milk = 1)
required_container = /obj/item/slime_extract/green
/datum/chemical_reaction/slime/slimemoth
results = list(/datum/reagent/mutationtoxin/moth = 1)
required_reagents = list(/datum/reagent/cellulose = 1)
required_container = /obj/item/slime_extract/green
//Metal
/datum/chemical_reaction/slime/slimemetal
required_reagents = list(/datum/reagent/toxin/plasma = 1)
@@ -5,8 +5,9 @@
icon_state = "bloodpack"
volume = 200
fill_icon_thresholds = list(10, 20, 30, 40, 50, 60, 70, 80, 90, 100)
obj_flags = UNIQUE_RENAME | RENAME_NO_DESC
var/blood_type = null
var/labelled = FALSE
var/labeled = FALSE
/obj/item/reagent_containers/blood/Initialize(mapload, vol)
. = ..()
@@ -21,7 +22,7 @@
/obj/item/reagent_containers/blood/update_name(updates)
. = ..()
if(!labelled)
if(!labeled)
name = "blood pack[blood_type ? " - [blood_type]" : ""]"
/obj/item/reagent_containers/blood/random
@@ -81,27 +82,7 @@
/obj/item/reagent_containers/blood/universal
blood_type = BLOOD_TYPE_UNIVERSAL
/obj/item/reagent_containers/blood/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
if(!IS_WRITING_UTENSIL(tool))
return NONE
if(!user.can_write(tool))
return ITEM_INTERACT_BLOCKING
var/custom_label = tgui_input_text(user, "What would you like to label the blood pack?", "Blood Pack", name, max_length = MAX_NAME_LEN)
if(!user.can_perform_action(src))
return ITEM_INTERACT_BLOCKING
if(user.get_active_held_item() != tool)
return ITEM_INTERACT_BLOCKING
if(!custom_label)
labelled = FALSE
update_name()
return ITEM_INTERACT_SUCCESS
labelled = TRUE
name = "blood pack - [custom_label]"
/obj/item/reagent_containers/blood/nameformat(input, user)
playsound(src, SFX_WRITING_PEN, 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE, SOUND_FALLOFF_EXPONENT + 3, ignore_walls = FALSE)
balloon_alert(user, "new label set")
return ITEM_INTERACT_SUCCESS
labeled = TRUE
return "blood pack[input? " - [input]" : null]"
@@ -7,6 +7,7 @@
fill_icon_state = "bottle"
inhand_icon_state = "atoxinbottle"
worn_icon_state = "bottle"
obj_flags = UNIQUE_RENAME | RENAME_NO_DESC
possible_transfer_amounts = list(5, 10, 15, 25, 50)
volume = 50
fill_icon_thresholds = list(0, 1, 20, 40, 60, 80, 100)
@@ -260,6 +261,11 @@
desc = "A small bottle of basic buffer."
list_reagents = list(/datum/reagent/reaction_agent/basic_buffer = 30)
/obj/item/reagent_containers/cup/bottle/inversing_buffer
name = "Chiral inversing buffer bottle"
desc = "A small bottle of chiral inversing buffer."
list_reagents = list(/datum/reagent/reaction_agent/inversing_buffer = 30)
/obj/item/reagent_containers/cup/bottle/romerol
name = "romerol bottle"
desc = "A small bottle of Romerol. The REAL zombie powder."
@@ -524,26 +530,14 @@
//when you attack the syrup bottle with a container it refills it
/obj/item/reagent_containers/cup/bottle/syrup_bottle/item_interaction(mob/living/user, obj/item/tool, list/modifiers)
if(IS_WRITING_UTENSIL(tool))
return writing_utensil_act(user, tool)
if(is_open_container() && tool.is_refillable())
return refillable_act(user, tool)
return ..()
/obj/item/reagent_containers/cup/bottle/syrup_bottle/proc/writing_utensil_act(mob/user, obj/item/tool)
if(!user.can_write(tool))
return ITEM_INTERACT_BLOCKING
var/input_name = tgui_input_text(user, "What would you like to label the syrup bottle?", "Syrup Bottle Labelling", max_length = MAX_NAME_LEN)
if(!user.can_perform_action(src))
return ITEM_INTERACT_BLOCKING
/obj/item/reagent_containers/cup/bottle/syrup_bottle/nameformat(input, user)
playsound(src, SFX_WRITING_PEN, 50, TRUE, SHORT_RANGE_SOUND_EXTRARANGE, SOUND_FALLOFF_EXPONENT + 3, ignore_walls = FALSE)
if(input_name)
name = "[input_name] bottle"
else
name = initial(name)
return ITEM_INTERACT_SUCCESS
return "[input? "[input] " : null]bottle"
/obj/item/reagent_containers/cup/bottle/syrup_bottle/proc/refillable_act(mob/user, obj/item/tool)
if(!reagents.total_volume)
+4 -2
View File
@@ -369,7 +369,8 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/reagent_dispensers/wall/peppertank, 3
. = ..()
if(prob(1))
desc = "IT'S PEPPER TIME, BITCH!"
find_and_hang_on_wall()
if(mapload)
find_and_hang_on_wall()
/obj/structure/reagent_dispensers/water_cooler
name = "water cooler"
@@ -627,7 +628,8 @@ MAPPING_DIRECTIONAL_HELPERS(/obj/structure/reagent_dispensers/wall/virusfood, 30
/obj/structure/reagent_dispensers/wall/virusfood/Initialize(mapload)
. = ..()
find_and_hang_on_wall()
if(mapload)
find_and_hang_on_wall()
/obj/structure/reagent_dispensers/cooking_oil
name = "vat of cooking oil"