Artur
2021-06-16 00:44:32 +03:00
parent 9376ec0d04
commit 724b34f55d
15 changed files with 343 additions and 158 deletions
@@ -64,7 +64,7 @@
/obj/item/organ/heart/gland/heal/proc/reject_implant(obj/item/organ/cyberimp/implant)
owner.visible_message("<span class='warning'>[owner] vomits up his [implant.name]!</span>", "<span class='userdanger'>You suddenly vomit up your [implant.name]!</span>")
owner.vomit(0, TRUE, TRUE, 1, FALSE, FALSE, FALSE, TRUE)
owner.vomit(0, TRUE, TRUE, 1, FALSE, FALSE, FAL SE, TRUE)
implant.Remove()
implant.forceMove(owner.drop_location())
+7 -3
View File
@@ -502,9 +502,9 @@
return 0
return ..()
/mob/living/carbon/proc/vomit(lost_nutrition = 10, blood = FALSE, stun = TRUE, distance = 1, message = TRUE, toxic = FALSE)
if(HAS_TRAIT(src, TRAIT_NOHUNGER))
return 1
/mob/living/carbon/proc/vomit(lost_nutrition = 10, blood = FALSE, stun = TRUE, distance = 1, message = TRUE, vomit_type = VOMIT_TOXIC, purge_ratio = 0.1)
if((HAS_TRAIT(src, TRAIT_NOHUNGER) || HAS_TRAIT(src, TRAIT_TOXINLOVER)) && !force)
return TRUE
if(nutrition < 100 && !blood)
if(message)
@@ -533,12 +533,16 @@
if(!blood)
adjust_nutrition(-lost_nutrition)
adjustToxLoss(-3)
for(var/i=0 to distance)
if(blood)
if(T)
add_splatter_floor(T)
if(stun)
adjustBruteLoss(3)
else
if(T)
T.add_vomit_floor(src, vomit_type, purge_ratio) //toxic barf looks different || call purge when doing detoxicfication to pump more chems out of the stomach.
else if(src.reagents.has_reagent(/datum/reagent/consumable/ethanol/blazaam))
if(T)
T.add_vomit_floor(src, VOMIT_PURPLE)
@@ -840,7 +840,8 @@
override = dna.species.override_float
..()
/mob/living/carbon/human/vomit(lost_nutrition = 10, blood = 0, stun = 1, distance = 0, message = 1, toxic = 0)
/mob/living/carbon/human/vomit(lost_nutrition = 10, blood = FALSE, stun = TRUE, distance = 1, message = TRUE, vomit_type = VOMIT_TOXIC, harm = TRUE, force = FALSE, purge_ratio = 0.1)
if(blood && (NOBLOOD in dna.species.species_traits) && !HAS_TRAIT(src, TRAIT_TOXINLOVER))
if(blood && dna?.species && (NOBLOOD in dna.species.species_traits))
if(message)
visible_message("<span class='warning'>[src] dry heaves!</span>", \
@@ -1095,7 +1096,7 @@
* * Rock / Brownish if a golem
* * Green if none of the others apply (aka, generic organic)
*/
/mob/living/carbon/human/proc/spec_trait_examine_font()
/mob/living/carbon/human/proc/spec_trait_examine_font()
if(HAS_TRAIT(src, TRAIT_ROBOTIC_ORGANISM))
return "<font color='#aaa9ad'>"
if(HAS_TRAIT(src, TRAIT_TOXINLOVER))
+1 -1
View File
@@ -273,7 +273,7 @@
if(getToxLoss() >= 45 && nutrition > 20 && !HAS_TRAIT(src, TRAIT_ROBOTIC_ORGANISM))
lastpuke += prob(50)
if(lastpuke >= 50) // about 25 second delay I guess
vomit(20, toxic = TRUE)
vomit(20)
lastpuke = 0
@@ -2196,7 +2196,7 @@ All effects don't start immediately, but rather get worse over time; the rate is
if(prob(10))
stored_teleports += rand(2,6)
if(prob(70))
M.vomit()
M.vomit(vomit_type = VOMIT_PURPLE)
return ..()
/datum/reagent/consumable/ethanol/planet_cracker
@@ -2516,101 +2516,19 @@ All effects don't start immediately, but rather get worse over time; the rate is
color = "#FFFFFF"
boozepwr = 35
quality = DRINK_GOOD
taste_description = "bad coding"
can_synth = FALSE
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
taste_description = "a delightful softened punch"
glass_icon_state = "godfather"
glass_name = "Godfather"
glass_desc = "A classic from old Italy and enjoyed by gangsters, pray the orange peel doesnt end up in your mouth."
/datum/reagent/consumable/ethanol/fruit_wine/on_new(list/data)
names = data["names"]
tastes = data["tastes"]
boozepwr = data["boozepwr"]
color = data["color"]
generate_data_info(data)
/datum/reagent/consumable/ethanol/godmother
name = "Godmother"
description = "A twist on a classic, liked more by mature women."
boozepwr = 50
color = "#E68F00"
quality = DRINK_GOOD
taste_description = "sweetness and a zesty twist"
glass_icon_state = "godmother"
glass_name = "Godmother"
glass_desc = "A lovely fresh smelling cocktail, a true Sicilian delight."
/datum/reagent/consumable/ethanol/fruit_wine/on_merge(list/data, amount)
var/diff = (amount/volume)
if(diff < 1)
color = BlendRGB(color, data["color"], diff/2) //The percentage difference over two, so that they take average if equal.
else
color = BlendRGB(color, data["color"], (1/diff)/2) //Adjust so it's always blending properly.
var/oldvolume = volume-amount
var/list/cachednames = data["names"]
for(var/name in names | cachednames)
names[name] = ((names[name] * oldvolume) + (cachednames[name] * amount)) / volume
var/list/cachedtastes = data["tastes"]
for(var/taste in tastes | cachedtastes)
tastes[taste] = ((tastes[taste] * oldvolume) + (cachedtastes[taste] * amount)) / volume
boozepwr *= oldvolume
var/newzepwr = data["boozepwr"] * amount
boozepwr += newzepwr
boozepwr /= volume //Blending boozepwr to volume.
generate_data_info(data)
/datum/reagent/consumable/ethanol/fruit_wine/proc/generate_data_info(list/data)
var/minimum_percent = 0.15 //Percentages measured between 0 and 1.
var/list/primary_tastes = list()
var/list/secondary_tastes = list()
glass_name = "glass of [name]"
glass_desc = description
for(var/taste in tastes)
switch(tastes[taste])
if(minimum_percent*2 to INFINITY)
primary_tastes += taste
if(minimum_percent to minimum_percent*2)
secondary_tastes += taste
var/minimum_name_percent = 0.35
name = ""
var/list/names_in_order = sortTim(names, /proc/cmp_numeric_dsc, TRUE)
var/named = FALSE
for(var/fruit_name in names)
if(names[fruit_name] >= minimum_name_percent)
name += "[fruit_name] "
named = TRUE
if(named)
name += "wine"
else
name = "mixed [names_in_order[1]] wine"
var/alcohol_description
switch(boozepwr)
if(120 to INFINITY)
alcohol_description = "suicidally strong"
if(90 to 120)
alcohol_description = "rather strong"
if(70 to 90)
alcohol_description = "strong"
if(40 to 70)
alcohol_description = "rich"
if(20 to 40)
alcohol_description = "mild"
if(0 to 20)
alcohol_description = "sweet"
else
alcohol_description = "watery" //How the hell did you get negative boozepwr?
var/list/fruits = list()
if(names_in_order.len <= 3)
fruits = names_in_order
else
for(var/i in 1 to 3)
fruits += names_in_order[i]
fruits += "other plants"
var/fruit_list = english_list(fruits)
description = "A [alcohol_description] wine brewed from [fruit_list]."
var/flavor = ""
if(!primary_tastes.len)
primary_tastes = list("[alcohol_description] alcohol")
flavor += english_list(primary_tastes)
if(secondary_tastes.len)
flavor += ", with a hint of "
flavor += english_list(secondary_tastes)
taste_description = flavor
if(holder.my_atom)
holder.my_atom.on_reagent_change()
@@ -735,7 +735,7 @@
/datum/reagent/toxin/spewium/on_mob_life(mob/living/carbon/C)
.=..()
if(current_cycle >=11 && prob(min(50,current_cycle)))
C.vomit(10, prob(10), prob(50), rand(0,4), TRUE, prob(30))
C.vomit(10, prob(10), prob(50), rand(0,4), TRUE)
for(var/datum/reagent/toxin/R in C.reagents.reagent_list)
if(R != src)
C.reagents.remove_reagent(R.type,1)
@@ -558,15 +558,15 @@
program_type = /datum/nanite_program/protocol/factory
category = list("Protocols_Nanites")
/datum/design/nanites/tinker
name = "Tinker Protocol"
desc = "Replication Protocol: the nanites learn to use metallic material in the host's bloodstream to speed up the replication process."
id = "tinker_nanites"
program_type = /datum/nanite_program/protocol/tinker
/datum/design/nanites/pyramid
name = "Pyramid Protocol"
desc = "Replication Protocol: the nanites implement an alternate cooperative replication protocol that is more efficient as long as the saturation level is above 80%."
id = "pyramid_nanites"
program_type = /datum/nanite_program/protocol/pyramid
category = list("Protocols_Nanites")
/datum/design/nanites/offline
name = "Offline Production Protocol"
name = "Eclipse Protocol"
desc = "Replication Protocol: while the host is asleep or otherwise unconcious, the nanites exploit the reduced interference to replicate more quickly."
id = "offline_nanites"
program_type = /datum/nanite_program/protocol/offline
@@ -578,3 +578,32 @@
id = "synergy_nanites"
program_type = /datum/nanite_program/protocol/synergy
category = list("Protocols_Nanites")
/datum/design/nanites/hive
name = "Hive Protocol"
desc = "Storage Protocol: the nanites use a more efficient grid arrangment for volume storage, increasing maximum volume in a host."
id = "hive_nanites"
program_type = /datum/nanite_program/protocol/hive
category = list("Protocols_Nanites")
/datum/design/nanites/zip
name = "Zip Protocol"
desc = "Storage Protocol: the nanites are disassembled and compacted when unused, greatly increasing the maximum volume while in a host. However, the process slows down the replication rate slightly."
id = "zip_nanites"
program_type = /datum/nanite_program/protocol/zip
category = list("Protocols_Nanites")
/datum/design/nanites/free_range
name = "Free-range Protocol"
desc = "Storage Protocol: the nanites discard their default storage protocols in favour of a cheaper and more organic approach. Reduces maximum volume, but increases the replication rate."
id = "free_range_nanites"
program_type = /datum/nanite_program/protocol/free_range
category = list("Protocols_Nanites")
/datum/design/nanites/unsafe_storage
name = "S.L.O. Protocol"
desc = "Storage Protocol: 'S.L.O.P.', or Storage Level Override Protocol, completely disables the safety measures normally present in nanites,\
allowing them to reach much higher saturation levels, but at the risk of causing internal damage to the host."
id = "unsafe_storage_nanites"
program_type = /datum/nanite_program/protocol/unsafe_storage
category = list("Protocols_Nanites")
@@ -46,43 +46,25 @@
factory_efficiency = min(factory_efficiency + 1, max_efficiency)
nanites.adjust_nanites(null, round(0.002 * factory_efficiency, 0.1))
/datum/nanite_program/protocol/tinker
name = "Tinker Protocol"
desc = "Replication Protocol: the nanites learn to use metallic material in the host's bloodstream to speed up the replication process."
/datum/nanite_program/protocol/pyramid
name = "Pyramid Protocol"
desc = "Replication Protocol: the nanites implement an alternate cooperative replication protocol that is more efficient as long as the saturation level is above 80%."
use_rate = 0
rogue_types = list(/datum/nanite_program/necrotic)
protocol_class = NANITE_PROTOCOL_REPLICATION
var/boost = 2
var/list/valid_reagents = list(
/datum/reagent/iron,
/datum/reagent/copper,
/datum/reagent/gold,
/datum/reagent/silver,
/datum/reagent/mercury,
/datum/reagent/aluminium,
/datum/reagent/silicon)
var/boost = 1.2
/datum/nanite_program/protocol/tinker/check_conditions()
if(!nanites.host_mob.reagents)
/datum/nanite_program/protocol/pyramid/check_conditions()
if((nanites.nanite_volume / nanites.max_nanites) < 0.8)
return FALSE
var/found_reagent = FALSE
var/datum/reagents/R = nanites.host_mob.reagents
for(var/VR in valid_reagents)
if(R.has_reagent(VR, 0.5))
R.remove_reagent(VR, 0.5)
found_reagent = TRUE
break
if(!found_reagent)
return FALSE
return ..()
/datum/nanite_program/protocol/tinker/active_effect()
/datum/nanite_program/protocol/pyramid/active_effect()
nanites.adjust_nanites(null, boost)
/datum/nanite_program/protocol/offline
name = "Offline Production Protocol"
name = "Eclipse Protocol"
desc = "Replication Protocol: while the host is asleep or otherwise unconcious, the nanites exploit the reduced interference to replicate more quickly."
use_rate = 0
rogue_types = list(/datum/nanite_program/necrotic)
@@ -106,13 +88,194 @@
/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."
/datum/nanite_program/protocol/hive
name = "Hive Protocol"
desc = "Storage Protocol: the nanites use a more efficient grid arrangment for volume storage, increasing maximum volume in a host."
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
protocol_class = NANITE_PROTOCOL_STORAGE
var/extra_volume = 250
/datum/nanite_program/protocol/synergy/active_effect()
nanites.adjust_nanites(null, round(max_boost * (nanites.nanite_volume / nanites.max_nanites), 0.1))
/datum/nanite_program/protocol/hive/enable_passive_effect()
. = ..()
nanites.set_max_volume(null, nanites.max_nanites + extra_volume)
/datum/nanite_program/protocol/hive/disable_passive_effect()
. = ..()
nanites.set_max_volume(null, nanites.max_nanites - extra_volume)
/datum/nanite_program/protocol/zip
name = "Zip Protocol"
desc = "Storage Protocol: the nanites are disassembled and compacted when unused, greatly increasing the maximum volume while in a host. However, the process slows down the replication rate slightly."
use_rate = 0.2
rogue_types = list(/datum/nanite_program/necrotic)
protocol_class = NANITE_PROTOCOL_STORAGE
var/extra_volume = 500
/datum/nanite_program/protocol/zip/enable_passive_effect()
. = ..()
nanites.set_max_volume(null, nanites.max_nanites + extra_volume)
/datum/nanite_program/protocol/zip/disable_passive_effect()
. = ..()
nanites.set_max_volume(null, nanites.max_nanites - extra_volume)
/datum/nanite_program/protocol/free_range
name = "Free-range Protocol"
desc = "Storage Protocol: the nanites discard their default storage protocols in favour of a cheaper and more organic approach. Reduces maximum volume, but increases the replication rate."
use_rate = 0
rogue_types = list(/datum/nanite_program/necrotic)
protocol_class = NANITE_PROTOCOL_STORAGE
var/boost = 0.5
var/extra_volume = -250
/datum/nanite_program/protocol/free_range/enable_passive_effect()
. = ..()
nanites.set_max_volume(null, nanites.max_nanites + extra_volume)
/datum/nanite_program/protocol/free_range/disable_passive_effect()
. = ..()
nanites.set_max_volume(null, nanites.max_nanites - extra_volume)
/datum/nanite_program/protocol/free_range/active_effect()
nanites.adjust_nanites(null, boost)
/datum/nanite_program/protocol/unsafe_storage
name = "S.L.O. Protocol"
desc = "Storage Protocol: 'S.L.O.P.', or Storage Level Override Protocol, completely disables the safety measures normally present in nanites,\
allowing them to reach much higher saturation levels, but at the risk of causing internal damage to the host."
use_rate = 0
rogue_types = list(/datum/nanite_program/necrotic)
protocol_class = NANITE_PROTOCOL_STORAGE
var/extra_volume = 1500
var/next_warning = 0
var/min_warning_cooldown = 120
var/max_warning_cooldown = 350
var/volume_warnings_stage_1 = list("You feel a dull pain in your abdomen.",
"You feel a tickling sensation in your abdomen.")
var/volume_warnings_stage_2 = list("You feel a dull pain in your stomach.",
"You feel a dull pain when breathing.",
"Your stomach grumbles.",
"You feel a tickling sensation in your throat.",
"You feel a tickling sensation in your lungs.",
"You feel a tickling sensation in your stomach.",
"Your lungs feel stiff.")
var/volume_warnings_stage_3 = list("You feel a dull pain in your chest.",
"You hear a faint buzzing coming from nowhere.",
"You hear a faint buzzing inside your head.",
"Your head aches.")
var/volume_warnings_stage_4 = list("You feel a dull pain in your ears.",
"You feel a dull pain behind your eyes.",
"You hear a loud, echoing buzz inside your ears.",
"You feel dizzy.",
"You feel an itch coming from behind your eyes.",
"Your eardrums itch.",
"You see tiny grey motes drifting in your field of view.")
var/volume_warnings_stage_5 = list("You feel sick.",
"You feel a dull pain from every part of your body.",
"You feel nauseous.")
var/volume_warnings_stage_6 = list("Your skin itches and burns.",
"Your muscles ache.",
"You feel tired.",
"You feel something skittering under your skin.",)
/datum/nanite_program/protocol/unsafe_storage/enable_passive_effect()
. = ..()
nanites.set_max_volume(null, nanites.max_nanites + extra_volume)
/datum/nanite_program/protocol/unsafe_storage/disable_passive_effect()
. = ..()
nanites.set_max_volume(null, nanites.max_nanites - extra_volume)
/datum/nanite_program/protocol/unsafe_storage/active_effect()
if(!iscarbon(host_mob))
if(prob(10))
host_mob.adjustBruteLoss(((max(nanites.nanite_volume - 450, 0) / 450) ** 2 ) * 0.5) // 0.5 -> 2 -> 4.5 -> 8 damage per successful tick
return
var/mob/living/carbon/C = host_mob
if(nanites.nanite_volume < 500)
return
var/current_stage = 0
if(nanites.nanite_volume > 500) //Liver is the main hub of nanite replication and the first to be threatened by excess volume
if(prob(10))
var/obj/item/organ/liver/liver = C.getorganslot(ORGAN_SLOT_LIVER)
if(liver)
liver.applyOrganDamage(0.6)
current_stage++
if(nanites.nanite_volume > 750) //Extra volume spills out in other central organs
if(prob(10))
var/obj/item/organ/stomach/stomach = C.getorganslot(ORGAN_SLOT_STOMACH)
if(stomach)
stomach.applyOrganDamage(0.75)
if(prob(10))
var/obj/item/organ/lungs/lungs = C.getorganslot(ORGAN_SLOT_LUNGS)
if(lungs)
lungs.applyOrganDamage(0.75)
current_stage++
if(nanites.nanite_volume > 1000) //Extra volume spills out in more critical organs
if(prob(10))
var/obj/item/organ/heart/heart = C.getorganslot(ORGAN_SLOT_HEART)
if(heart)
heart.applyOrganDamage(0.75)
if(prob(10))
var/obj/item/organ/brain/brain = C.getorganslot(ORGAN_SLOT_BRAIN)
if(brain)
brain.applyOrganDamage(0.75)
current_stage++
if(nanites.nanite_volume > 1250) //Excess nanites start invading smaller organs for more space, including sensory organs
if(prob(13))
var/obj/item/organ/eyes/eyes = C.getorganslot(ORGAN_SLOT_EYES)
if(eyes)
eyes.applyOrganDamage(0.75)
if(prob(13))
var/obj/item/organ/ears/ears = C.getorganslot(ORGAN_SLOT_EARS)
if(ears)
ears.applyOrganDamage(0.75)
current_stage++
if(nanites.nanite_volume > 1500) //Nanites start spilling into the bloodstream, causing toxicity
if(prob(15))
C.adjustToxLoss(0.5, TRUE, forced = TRUE) //Not healthy for slimepeople either
current_stage++
if(nanites.nanite_volume > 1750) //Nanites have almost reached their physical limit, and the pressure itself starts causing tissue damage
if(prob(15))
C.adjustBruteLoss(0.75, TRUE)
current_stage++
volume_warning(current_stage)
/datum/nanite_program/protocol/unsafe_storage/proc/volume_warning(tier)
if(world.time < next_warning)
return
var/list/main_warnings
var/list/extra_warnings
switch(tier)
if(1)
main_warnings = volume_warnings_stage_1
extra_warnings = null
if(2)
main_warnings = volume_warnings_stage_2
extra_warnings = volume_warnings_stage_1
if(3)
main_warnings = volume_warnings_stage_3
extra_warnings = volume_warnings_stage_1 + volume_warnings_stage_2
if(4)
main_warnings = volume_warnings_stage_4
extra_warnings = volume_warnings_stage_1 + volume_warnings_stage_2 + volume_warnings_stage_3
if(5)
main_warnings = volume_warnings_stage_5
extra_warnings = volume_warnings_stage_1 + volume_warnings_stage_2 + volume_warnings_stage_3 + volume_warnings_stage_4
if(6)
main_warnings = volume_warnings_stage_6
extra_warnings = volume_warnings_stage_1 + volume_warnings_stage_2 + volume_warnings_stage_3 + volume_warnings_stage_4 + volume_warnings_stage_5
if(prob(35))
to_chat(host_mob, "<span class='warning'>[pick(main_warnings)]</span>")
next_warning = world.time + rand(min_warning_cooldown, max_warning_cooldown)
else if(islist(extra_warnings))
to_chat(host_mob, "<span class='warning'>[pick(extra_warnings)]</span>")
next_warning = world.time + rand(min_warning_cooldown, max_warning_cooldown)
@@ -87,11 +87,8 @@
addtimer(CALLBACK(src, .proc/boom), clamp((nanites.nanite_volume * 0.35), 25, 150))
/datum/nanite_program/explosive/proc/boom()
var/nanite_amount = nanites.nanite_volume
var/heavy_range = FLOOR(nanite_amount/100, 1) - 1
var/light_range = FLOOR(nanite_amount/50, 1) - 1
explosion(host_mob, 0, heavy_range, light_range)
nanites.delete_nanites()
dyn_explosion(get_turf(host_mob), nanites.nanite_volume / 50)
qdel(nanites)
//TODO make it defuse if triggered again