From de33d64c315ff5fb18afa59f5a57538ea40bdff3 Mon Sep 17 00:00:00 2001 From: LiquidPotroh Date: Sat, 21 Oct 2023 08:32:06 +0300 Subject: [PATCH] Contract system rework --- code/datums/diseases/_MobProcs.dm | 85 ++++++++++++++++++- code/datums/diseases/_disease.dm | 35 +++----- code/datums/diseases/critical.dm | 4 +- code/datums/diseases/viruses/_virus.dm | 62 +------------- .../diseases/viruses/advance/advance.dm | 6 +- code/datums/diseases/viruses/cold.dm | 2 +- .../diseases/viruses/loyalty_syndrome.dm | 4 +- .../datums/diseases/viruses/transformation.dm | 2 +- .../gamemodes/miniantags/abduction/gland.dm | 2 +- .../items/weapons/storage/artistic_toolbox.dm | 2 +- code/modules/admin/admin_verbs.dm | 2 +- .../goon_vampire/goon_vampire_powers.dm | 2 +- .../vampire/vampire_powers/bestia_powers.dm | 2 +- code/modules/awaymissions/corpse.dm | 2 +- .../awaymissions/mission_code/academy.dm | 2 +- code/modules/clothing/suits/labcoat.dm | 1 + code/modules/events/disease_outbreak.dm | 2 +- .../events/spontaneous_appendicitis.dm | 2 +- .../mob/living/carbon/carbon_defense.dm | 4 +- code/modules/mob/living/carbon/human/life.dm | 14 +-- .../living/carbon/human/species/_species.dm | 28 ++++-- code/modules/mob/mob_grab.dm | 10 +++ code/modules/paperwork/paper.dm | 7 +- .../reagents/chemistry/reagents/disease.dm | 18 ++-- .../reagents/chemistry/reagents/food.dm | 6 +- .../reagents/chemistry/reagents/toxins.dm | 4 +- .../reagents/chemistry/reagents/water.dm | 12 +-- code/modules/surgery/organs/blood.dm | 2 +- code/modules/surgery/organs/heart.dm | 4 +- paradise.dme | 2 +- 30 files changed, 184 insertions(+), 146 deletions(-) diff --git a/code/datums/diseases/_MobProcs.dm b/code/datums/diseases/_MobProcs.dm index d88fff6c824..3b2366bd679 100644 --- a/code/datums/diseases/_MobProcs.dm +++ b/code/datums/diseases/_MobProcs.dm @@ -14,7 +14,7 @@ /mob/proc/CureAllDiseases(need_immunity = TRUE) for(var/datum/disease/D in diseases) - D.cure(need_immunity) + D.cure(need_immunity = need_immunity) /** * A special checks for this type of mob @@ -33,3 +33,86 @@ if(!((locate(thing) in bodyparts) || (locate(thing) in internal_organs))) return FALSE return ..() + +/** + * Checking mob's protection against disease D by the chosen method in chosen zone + * Returns: + * * TRUE - mob has protected from the virus + * * FALSE - otherwise + */ +/mob/proc/CheckVirusProtection(datum/disease/virus/V, act_type = BITES|CONTACT|AIRBORNE, zone) + if(prob(15/V.permeability_mod)) + return TRUE + + if(satiety > 0 && prob(satiety/10)) + return TRUE + + if((act_type & BITES) && CheckBitesProtection(V, zone)) + return TRUE + + if((act_type & CONTACT) && CheckContactProtection(V, zone)) + return TRUE + + if((act_type & AIRBORNE) && CheckAirborneProtection(V, zone)) + return TRUE + + return FALSE + +//Returns TRUE, if mob protected +/mob/proc/CheckBitesProtection(datum/disease/virus/V, zone) + return FALSE + +/mob/proc/CheckContactProtection(datum/disease/virus/V, zone) + return FALSE + +/mob/proc/CheckAirborneProtection(datum/disease/virus/V, zone) + return FALSE + +/mob/living/CheckBitesProtection(datum/disease/virus/V, zone = BODY_ZONE_CHEST) + return ..() || prob(run_armor_check(zone, "melee") / V.permeability_mod) + +/mob/living/carbon/human/CheckContactProtection(datum/disease/virus/V, zone) + if(..()) + return TRUE + + var/zone_text + if(!zone) + zone_text = pick(40; "head", 40; "chest", 10; "l_arm", 10; "l_leg") + else + if(istype(zone, /obj/item/organ/external)) + var/obj/item/organ/external/E = zone + zone_text = E.limb_name + else + zone_text = zone + + switch(zone_text) + if("head", "eyes", "mouth") + if(ClothingVirusProtection(head) || ClothingVirusProtection(wear_mask)) + return TRUE + if("chest", "groin", "tail", "wing") + if(ClothingVirusProtection(wear_suit) || ClothingVirusProtection(slot_w_uniform)) + return TRUE + if("l_arm", "r_arm", "l_hand", "r_hand") + if(istype(wear_suit) && (wear_suit.body_parts_covered & HANDS) && ClothingVirusProtection(wear_suit)) + return TRUE + if(ClothingVirusProtection(gloves)) + return TRUE + if("l_leg", "r_leg", "l_foot", "r_foot") + if(istype(wear_suit) && (wear_suit.body_parts_covered & FEET) && ClothingVirusProtection(wear_suit)) + return TRUE + if(ClothingVirusProtection(shoes)) + return TRUE + + return FALSE + +/mob/living/CheckAirborneProtection(datum/disease/virus/V, zone) + //permeability_mod == 0 => 100% defense; permeability_mod == 2 => 0% defense + if(..() || internal || prob(50 * (2 - V.permeability_mod))) + return TRUE + return FALSE + +/mob/living/carbon/human/proc/ClothingVirusProtection(obj/item/Clothing) + //permeability_coefficient == 0.01 => 100% defense; permeability_coefficient == 1 => 1% defense + if(istype(Clothing) && prob(100 * (1.01 - Clothing.permeability_coefficient))) + return TRUE + return FALSE diff --git a/code/datums/diseases/_disease.dm b/code/datums/diseases/_disease.dm index 7e603c44e50..7d9300ef530 100644 --- a/code/datums/diseases/_disease.dm +++ b/code/datums/diseases/_disease.dm @@ -170,26 +170,11 @@ GLOBAL_LIST_INIT(diseases, subtypesof(/datum/disease)) /datum/disease/proc/spread() return -/** - * Checking mob's protection against this disease - */ -/datum/disease/proc/TryContract(mob/M) - return TRUE - -/** - * Attempt to infect a mob with a check of its protection - * Returns: - * * TRUE - mob successfully infected - * * FALSE - otherwise - */ -/datum/disease/proc/Contract(mob/M) - if(TryContract(M)) - . = ForceContract(M) - /** * Basic checks of the possibility of infecting a mob */ -/datum/disease/proc/CanContract(mob/M) +/datum/disease/proc/CanContract(mob/living/M, act_type, need_protection_check, zone) + . = FALSE if(!M.CanContractDisease(src)) return FALSE @@ -204,17 +189,21 @@ GLOBAL_LIST_INIT(diseases, subtypesof(/datum/disease)) for(var/mobtype in infectable_mobtypes + carrier_mobtypes) if(istype(M, mobtype)) - return TRUE - return FALSE + . = TRUE + + if(. && need_protection_check && M.CheckVirusProtection(src, act_type, zone)) + . = FALSE + + return /** - * Attempt to infect a mob without a check of its protection + * Attempt to infect a mob * Returns: * * /datum/disease/D - a new instance of the virus that contract the mob * * FALSE - otherwise */ -/datum/disease/proc/ForceContract(mob/M, is_carrier = FALSE) - if(!CanContract(M)) +/datum/disease/proc/Contract(mob/living/M, act_type, is_carrier = FALSE, need_protection_check = FALSE, zone) + if(!CanContract(M, act_type, need_protection_check, zone)) return FALSE var/datum/disease/D = Copy() @@ -261,7 +250,7 @@ GLOBAL_LIST_INIT(diseases, subtypesof(/datum/disease)) affected_mob.diseases -= src affected_mob.med_hud_set_status() var/datum/disease/new_disease = new type - new_disease.ForceContract(affected_mob) + new_disease.Contract(affected_mob) qdel(src) return TRUE diff --git a/code/datums/diseases/critical.dm b/code/datums/diseases/critical.dm index 2e05e9b6fd5..74831e95cc8 100644 --- a/code/datums/diseases/critical.dm +++ b/code/datums/diseases/critical.dm @@ -78,7 +78,7 @@ affected_mob.AdjustLoseBreath(2 SECONDS) if(prob(5)) var/datum/disease/D = new /datum/disease/critical/heart_failure - D.ForceContract(affected_mob) + D.Contract(affected_mob) /datum/disease/critical/heart_failure name = "Cardiac Failure" @@ -181,7 +181,7 @@ if(3) if(prob(1)) var/datum/disease/D = new /datum/disease/critical/shock - D.ForceContract(affected_mob) + D.Contract(affected_mob) if(prob(12)) affected_mob.Weaken(12 SECONDS) affected_mob.Stuttering(20 SECONDS) diff --git a/code/datums/diseases/viruses/_virus.dm b/code/datums/diseases/viruses/_virus.dm index 9e5799c944f..1057fc7a33b 100644 --- a/code/datums/diseases/viruses/_virus.dm +++ b/code/datums/diseases/viruses/_virus.dm @@ -54,10 +54,7 @@ if(affected_mob.reagents?.has_reagent("spaceacillin") || (affected_mob.satiety > 0 && prob(affected_mob.satiety/10))) return - var/spread_range = 1 - - if(force_spread) - spread_range = force_spread + var/spread_range = force_spread ? force_spread : 1 if(spread_flags & AIRBORNE) spread_range++ @@ -69,7 +66,8 @@ if(V) while(TRUE) if(V == T) - Contract(C) + var/a_type = (spread_range == 1) ? CONTACT : CONTACT|AIRBORNE + Contract(C, act_type = a_type, need_protection_check = TRUE) break var/turf/Temp = get_step_towards(V, T) if(!V.CanAtmosPass(Temp)) @@ -89,57 +87,3 @@ if(spread_flags & AIRBORNE) spread += "Воздушно-капельный" return english_list(spread, "Неизвестен", " и ") - -/datum/disease/virus/TryContract(mob/M) - if(!..()) - return FALSE - - var/obj/item/clothing/Cl = null - var/passed = TRUE - - if(prob(15/permeability_mod)) - return - - if(M.satiety > 0 && prob(M.satiety/10)) // positive satiety makes it harder to contract the disease. - return - - if(istype(M, /mob/living/carbon/human)) - var/mob/living/carbon/human/H = M - - switch(pick(40;"head", 40;"body", 10;"hands", 10;"feet")) - if("head") - if(isobj(H.head) && !istype(H.head, /obj/item/paper)) - Cl = H.head - passed = prob((Cl.permeability_coefficient*100) - 1) - if(passed && isobj(H.wear_mask)) - Cl = H.wear_mask - passed = prob((Cl.permeability_coefficient*100) - 1) - if("body") - if(isobj(H.wear_suit)) - Cl = H.wear_suit - passed = prob((Cl.permeability_coefficient*100) - 1) - if(passed && isobj(slot_w_uniform)) - Cl = slot_w_uniform - passed = prob((Cl.permeability_coefficient*100) - 1) - if("hands") - if(isobj(H.wear_suit) && H.wear_suit.body_parts_covered&HANDS) - Cl = H.wear_suit - passed = prob((Cl.permeability_coefficient*100) - 1) - - if(passed && isobj(H.gloves)) - Cl = H.gloves - passed = prob((Cl.permeability_coefficient*100) - 1) - if("feet") - if(isobj(H.wear_suit) && H.wear_suit.body_parts_covered&FEET) - Cl = H.wear_suit - passed = prob((Cl.permeability_coefficient*100) - 1) - - if(passed && isobj(H.shoes)) - Cl = H.shoes - passed = prob((Cl.permeability_coefficient*100) - 1) - - - if(!passed && (spread_flags & AIRBORNE) && !M.internal) - passed = (prob((50*permeability_mod) - 1)) - - return passed diff --git a/code/datums/diseases/viruses/advance/advance.dm b/code/datums/diseases/viruses/advance/advance.dm index e7895e55b21..2e85700833f 100644 --- a/code/datums/diseases/viruses/advance/advance.dm +++ b/code/datums/diseases/viruses/advance/advance.dm @@ -205,7 +205,7 @@ GLOBAL_LIST_EMPTY(archive_diseases) if(4 to INFINITY) spread_flags = AIRBORNE additional_info = spread_text() - permeability_mod = clamp((0.25 * properties["transmittable"]), 0.1, 2) + permeability_mod = clamp((0.25 * properties["transmittable"]), 0.2, 2) //stage speed stage_prob = clamp(max(1.3 * sqrtor0(properties["stage_speed"] + 11), properties["stage_speed"]), 1, 40) @@ -290,7 +290,7 @@ GLOBAL_LIST_EMPTY(archive_diseases) symptoms -= S return -/datum/disease/virus/advance/CanContract(mob/M) +/datum/disease/virus/advance/CanContract(mob/living/M, act_type, need_protection_check, zone) . = ..() if(count_by_type(M.diseases, /datum/disease/virus/advance) > 0) . = FALSE @@ -386,7 +386,7 @@ GLOBAL_LIST_EMPTY(archive_diseases) if(H.stat == DEAD || !is_station_level(H.z)) continue if(!H.HasDisease(D)) - D.ForceContract(H) + D.Contract(H) break var/list/name_symptoms = list() diff --git a/code/datums/diseases/viruses/cold.dm b/code/datums/diseases/viruses/cold.dm index 1d9df11a842..4501158108e 100644 --- a/code/datums/diseases/viruses/cold.dm +++ b/code/datums/diseases/viruses/cold.dm @@ -29,7 +29,7 @@ if(prob(1) && prob(50)) if(!affected_mob.resistances.Find(/datum/disease/virus/flu)) var/datum/disease/virus/flu/Flu = new - Flu.ForceContract(affected_mob) + Flu.Contract(affected_mob) cure() /datum/disease/virus/cold/has_cure() diff --git a/code/datums/diseases/viruses/loyalty_syndrome.dm b/code/datums/diseases/viruses/loyalty_syndrome.dm index f4f692aae61..b59afeed918 100644 --- a/code/datums/diseases/viruses/loyalty_syndrome.dm +++ b/code/datums/diseases/viruses/loyalty_syndrome.dm @@ -30,8 +30,8 @@ else is_master = TRUE -/datum/disease/virus/loyalty/ForceContract(mob/M, is_carrier = FALSE) - if(!CanContract(M)) +/datum/disease/virus/loyalty/Contract(mob/living/M, act_type, is_carrier = FALSE, need_protection_check = FALSE, zone) + if(!CanContract(M, act_type, need_protection_check, zone)) return FALSE var/mob/living/carbon/human/new_master = is_master ? affected_mob : master diff --git a/code/datums/diseases/viruses/transformation.dm b/code/datums/diseases/viruses/transformation.dm index 89db35bde18..4a80ffc4cb6 100644 --- a/code/datums/diseases/viruses/transformation.dm +++ b/code/datums/diseases/viruses/transformation.dm @@ -112,7 +112,7 @@ transformed = TRUE else var/mob/living/new_mob = ..() - var/datum/disease/virus/transformation/jungle_fever/D = ForceContract(new_mob) + var/datum/disease/virus/transformation/jungle_fever/D = Contract(new_mob) D?.stage = 5 D.transformed = TRUE else diff --git a/code/game/gamemodes/miniantags/abduction/gland.dm b/code/game/gamemodes/miniantags/abduction/gland.dm index e983b60ba7f..62b1ba62cb1 100644 --- a/code/game/gamemodes/miniantags/abduction/gland.dm +++ b/code/game/gamemodes/miniantags/abduction/gland.dm @@ -225,7 +225,7 @@ var/datum/disease/virus/advance/old_virus = locate() in owner.diseases if(old_virus) old_virus.cure(need_immunity = FALSE) - new_virus.ForceContract(owner, is_carrier = TRUE) + new_virus.Contract(owner, is_carrier = TRUE) /obj/item/organ/internal/heart/gland/emp //TODO : Replace with something more interesting origin_tech = "materials=4;biotech=4;magnets=6;abductor=3" diff --git a/code/game/objects/items/weapons/storage/artistic_toolbox.dm b/code/game/objects/items/weapons/storage/artistic_toolbox.dm index edaf5e5c1e8..65883392d66 100644 --- a/code/game/objects/items/weapons/storage/artistic_toolbox.dm +++ b/code/game/objects/items/weapons/storage/artistic_toolbox.dm @@ -44,7 +44,7 @@ if(ishuman(user) && !user.HasDisease(/datum/disease/memetic_madness)) activated = TRUE var/datum/disease/memetic_madness/D = new - D.ForceContract(user) + D.Contract(user) for(var/datum/disease/memetic_madness/DD in user.diseases) DD.progenitor = src servantlinks.Add(DD) diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index 5d1f8fdd629..2a9b76e5ef0 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -881,7 +881,7 @@ GLOBAL_LIST_INIT(admin_verbs_ticket, list( var/choosen_disease = input("Choose the disease to give to that guy", "ACHOO") as null|anything in GLOB.diseases if(!choosen_disease) return var/datum/disease/D = new choosen_disease() - D.ForceContract(T) + D.Contract(T) SSblackbox.record_feedback("tally", "admin_verb", 1, "Give Disease") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc! log_and_message_admins("gave [key_name_log(T)] the disease [D].") diff --git a/code/modules/antagonists/goon_vampire/goon_vampire_powers.dm b/code/modules/antagonists/goon_vampire/goon_vampire_powers.dm index 0336ea8c8ec..6a716392112 100644 --- a/code/modules/antagonists/goon_vampire/goon_vampire_powers.dm +++ b/code/modules/antagonists/goon_vampire/goon_vampire_powers.dm @@ -221,7 +221,7 @@ return var/datum/disease/vampire/virus = new - virus.ForceContract(target) + virus.Contract(target) /obj/effect/proc_holder/spell/goon_vampire/glare diff --git a/code/modules/antagonists/vampire/vampire_powers/bestia_powers.dm b/code/modules/antagonists/vampire/vampire_powers/bestia_powers.dm index 3da053a4f9d..5283f92c082 100644 --- a/code/modules/antagonists/vampire/vampire_powers/bestia_powers.dm +++ b/code/modules/antagonists/vampire/vampire_powers/bestia_powers.dm @@ -685,7 +685,7 @@ GLOBAL_LIST_INIT(vampire_dissect_organs, list( if(prob(10 + vampire.get_trophies("livers") * 3)) new /obj/effect/temp_visual/cult/sparks(get_turf(victim)) var/datum/disease/vampire/D = new - D.ForceContract(victim) // grave fever + D.Contract(victim) // grave fever /*======================================================================================================================================*\ diff --git a/code/modules/awaymissions/corpse.dm b/code/modules/awaymissions/corpse.dm index 569f2c077b0..a53d5a788c7 100644 --- a/code/modules/awaymissions/corpse.dm +++ b/code/modules/awaymissions/corpse.dm @@ -169,7 +169,7 @@ M.faction = list(faction) if(disease) var/datum/disease/D = new disease - D.ForceContract(M) + D.Contract(M) M.adjustOxyLoss(oxy_damage) M.adjustBruteLoss(brute_damage) M.adjustFireLoss(burn_damage) diff --git a/code/modules/awaymissions/mission_code/academy.dm b/code/modules/awaymissions/mission_code/academy.dm index c27e11aaed0..3d1e2c17e37 100644 --- a/code/modules/awaymissions/mission_code/academy.dm +++ b/code/modules/awaymissions/mission_code/academy.dm @@ -144,7 +144,7 @@ //Cold T.visible_message("[user] looks a little under the weather!") var/datum/disease/virus/cold/D = new - D.ForceContract(user) + D.Contract(user) if(10) //Nothing T.visible_message("Nothing seems to happen.") diff --git a/code/modules/clothing/suits/labcoat.dm b/code/modules/clothing/suits/labcoat.dm index ab1f4b348a8..c65289c4ac8 100644 --- a/code/modules/clothing/suits/labcoat.dm +++ b/code/modules/clothing/suits/labcoat.dm @@ -5,6 +5,7 @@ item_state = "labcoat_open" ignore_suitadjust = 0 suit_adjusted = 1 + permeability_coefficient = 0.5 blood_overlay_type = "coat" body_parts_covered = UPPER_TORSO|LOWER_TORSO|ARMS allowed = list(/obj/item/analyzer,/obj/item/stack/medical,/obj/item/dnainjector,/obj/item/reagent_containers/dropper,/obj/item/reagent_containers/syringe,/obj/item/reagent_containers/hypospray,/obj/item/reagent_containers/applicator,/obj/item/healthanalyzer,/obj/item/flashlight/pen,/obj/item/reagent_containers/glass/bottle,/obj/item/reagent_containers/glass/beaker,/obj/item/reagent_containers/food/pill,/obj/item/storage/pill_bottle,/obj/item/paper,/obj/item/rad_laser) diff --git a/code/modules/events/disease_outbreak.dm b/code/modules/events/disease_outbreak.dm index 32401d8ce0f..ddfa7e05d31 100644 --- a/code/modules/events/disease_outbreak.dm +++ b/code/modules/events/disease_outbreak.dm @@ -51,7 +51,7 @@ var/datum/disease/virus/advance/old_virus = locate() in H.diseases if(old_virus) old_virus.cure(need_immunity = FALSE) - if(!D.ForceContract(H, is_carrier = TRUE)) + if(!D.Contract(H, is_carrier = TRUE)) continue patient_zero = H break diff --git a/code/modules/events/spontaneous_appendicitis.dm b/code/modules/events/spontaneous_appendicitis.dm index f36942ced70..e7033c1fa7a 100644 --- a/code/modules/events/spontaneous_appendicitis.dm +++ b/code/modules/events/spontaneous_appendicitis.dm @@ -14,5 +14,5 @@ continue var/datum/disease/appendicitis/D = new - D.ForceContract(H) + D.Contract(H) break diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm index 365a6f2995a..a1291226224 100644 --- a/code/modules/mob/living/carbon/carbon_defense.dm +++ b/code/modules/mob/living/carbon/carbon_defense.dm @@ -34,11 +34,11 @@ for(var/datum/disease/virus/V in diseases) if(V.spread_flags & CONTACT) - V.Contract(user) + V.Contract(user, act_type = CONTACT, need_protection_check = TRUE, zone = user.hand ? "l_hand" : "r_hand") for(var/datum/disease/virus/V in user.diseases) if(V.spread_flags & CONTACT) - V.Contract(src) + V.Contract(src, act_type = CONTACT, need_protection_check = TRUE, zone = user.zone_selected) if(lying && surgeries.len) if(user.a_intent == INTENT_HELP) diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index e772042bbfd..33f8d29a585 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -381,7 +381,7 @@ if(mult>0) if(bodytemperature < dna.species.cold_level_2 && prob(1)) var/datum/disease/virus/cold/D = new - D.ForceContract(src) + D.Contract(src) if(bodytemperature >= dna.species.cold_level_2 && bodytemperature <= dna.species.cold_level_1) throw_alert("temp", /obj/screen/alert/cold, 1) take_overall_damage(burn=mult*COLD_DAMAGE_LEVEL_1, used_weapon = "Low Body Temperature") @@ -682,7 +682,7 @@ if(!ismachineperson(src) && !isLivingSSD(src) && nutrition < NUTRITION_LEVEL_HYPOGLYCEMIA) //Gosh damn snowflakey IPCs var/datum/disease/critical/hypoglycemia/D = new - D.ForceContract(src) + D.Contract(src) //metabolism change if(nutrition > NUTRITION_LEVEL_FAT) @@ -751,7 +751,7 @@ H.set_heartattack(TRUE) if(prob(health * -0.2)) var/datum/disease/critical/heart_failure/D = new - D.ForceContract(src) + D.Contract(src) Paralyse(10 SECONDS) if(-99 to -80) adjustOxyLoss(1) @@ -759,15 +759,15 @@ to_chat(src, "Your chest hurts...") Paralyse(4 SECONDS) var/datum/disease/critical/heart_failure/D = new - D.ForceContract(src) + D.Contract(src) if(-79 to -50) adjustOxyLoss(1) if(prob(10)) var/datum/disease/critical/shock/D = new - D.ForceContract(src) + D.Contract(src) if(prob(health * -0.08)) var/datum/disease/critical/heart_failure/D = new - D.ForceContract(src) + D.Contract(src) if(prob(6)) to_chat(src, "You feel [pick("horrible pain", "awful", "like shit", "absolutely awful", "like death", "like you are dying", "nothing", "warm", "sweaty", "tingly", "really, really bad", "horrible")]!") Weaken(6 SECONDS) @@ -777,7 +777,7 @@ adjustOxyLoss(1) if(prob(3)) var/datum/disease/critical/shock/D = new - D.ForceContract(src) + D.Contract(src) if(prob(5)) to_chat(src, "You feel [pick("terrible", "awful", "like shit", "sick", "numb", "cold", "sweaty", "tingly", "horrible")]!") Weaken(6 SECONDS) diff --git a/code/modules/mob/living/carbon/human/species/_species.dm b/code/modules/mob/living/carbon/human/species/_species.dm index 5e6825deb5b..7c19265fbf9 100644 --- a/code/modules/mob/living/carbon/human/species/_species.dm +++ b/code/modules/mob/living/carbon/human/species/_species.dm @@ -534,19 +534,29 @@ playsound(target.loc, attack.miss_sound, 25, 1, -1) target.visible_message("[user.declent_ru(NOMINATIVE)] [attack_species] [target.declent_ru(ACCUSATIVE)], но промахива[pluralize_ru(user.gender,"ется","ются")]!") return FALSE - else - // Contract diseases - for(var/datum/disease/virus/V in user.diseases) - if((V.spread_flags & CONTACT) || attack.is_bite && (V.spread_flags & BITES)) - V.Contract(target) - - for(var/datum/disease/virus/V in target.diseases) - if((V.spread_flags & CONTACT) || attack.is_bite && (V.spread_flags & BITES)) - V.Contract(user) var/obj/item/organ/external/affecting = target.get_organ(ran_zone(user.zone_selected)) var/armor_block = target.run_armor_check(affecting, "melee") + // Contract diseases + + //user beats target, check target's defense in selected zone + for(var/datum/disease/virus/V in user.diseases) + var/is_infected = FALSE + if(attack.is_bite && (V.spread_flags & BITES)) + is_infected = V.Contract(target, act_type = BITES|CONTACT, need_protection_check = TRUE, zone = affecting) + if(!is_infected && (V.spread_flags & CONTACT)) + V.Contract(target, act_type = CONTACT, need_protection_check = TRUE, zone = affecting) + + //check user's defense in attacking zone (hands or mouth) + for(var/datum/disease/virus/V in target.diseases) + var/is_infected = FALSE + if(attack.is_bite && (V.spread_flags > NON_CONTAGIOUS)) + //infected blood contacts with mouth, ignore protection & spread_flags + is_infected = V.Contract(user, need_protection_check = FALSE) + if(!is_infected && (V.spread_flags & CONTACT)) + V.Contract(user, act_type = CONTACT, need_protection_check = TRUE, zone = user.hand ? "l_hand" : "r_hand") + playsound(target.loc, attack.attack_sound, 25, 1, -1) target.visible_message("[user.declent_ru(NOMINATIVE)] [attack_species] [target.declent_ru(ACCUSATIVE)]!") diff --git a/code/modules/mob/mob_grab.dm b/code/modules/mob/mob_grab.dm index 32d4ebba41e..d31682694ab 100644 --- a/code/modules/mob/mob_grab.dm +++ b/code/modules/mob/mob_grab.dm @@ -432,13 +432,23 @@ return FALSE user.visible_message("[user.name] поглоща[pluralize_ru(user.gender,"ет","ют")] [affecting.name]!") + if(affecting.mind) add_attack_logs(attacker, affecting, "Devoured") + if(isvampire(user)) user.adjust_nutrition(affecting.blood_nutrients) else user.adjust_nutrition(10 * affecting.health) + for(var/datum/disease/virus/V in affecting.diseases) + if(V.spread_flags > NON_CONTAGIOUS) + V.Contract(user) + + for(var/datum/disease/virus/V in user.diseases) + if(V.spread_flags > NON_CONTAGIOUS) + V.Contract(affecting) + affecting.forceMove(user) LAZYADD(attacker.stomach_contents, affecting) qdel(src) diff --git a/code/modules/paperwork/paper.dm b/code/modules/paperwork/paper.dm index 7acd29008d6..6b93e7dc6dc 100644 --- a/code/modules/paperwork/paper.dm +++ b/code/modules/paperwork/paper.dm @@ -20,6 +20,7 @@ resistance_flags = FLAMMABLE max_integrity = 50 attack_verb = list("bapped") + permeability_coefficient = 0.01 dog_fashion = /datum/dog_fashion/head var/header //Above the main body, displayed at the top var/info //What's actually written on the paper. @@ -783,7 +784,7 @@ if(mytarget && !used) var/mob/living/carbon/target = mytarget var/datum/disease/virus/transformation/corgi/D = new - D.ForceContract(target) + D.Contract(target) return ..() @@ -808,11 +809,11 @@ if(myeffect == "Borgification") to_chat(target,"You seem to comprehend the AI a little better. Why are your muscles so stiff?") var/datum/disease/virus/transformation/robot/D = new - D.ForceContract(target) + D.Contract(target) else if(myeffect == "Corgification") to_chat(target,"You hear distant howling as the world seems to grow bigger around you. Boy, that itch sure is getting worse!") var/datum/disease/virus/transformation/corgi/D = new - D.ForceContract(target) + D.Contract(target) else if(myeffect == "Death By Fire") to_chat(target,"You feel hotter than usual. Maybe you should lowe-wait, is that your hand melting?") var/turf/simulated/T = get_turf(target) diff --git a/code/modules/reagents/chemistry/reagents/disease.dm b/code/modules/reagents/chemistry/reagents/disease.dm index 94c4fbd650d..dd14a22b989 100644 --- a/code/modules/reagents/chemistry/reagents/disease.dm +++ b/code/modules/reagents/chemistry/reagents/disease.dm @@ -26,7 +26,7 @@ /datum/reagent/nanomachines/on_mob_life(mob/living/carbon/M) if(volume > 1.5) var/datum/disease/virus/transformation/robot/D = new - D.ForceContract(M) + D.Contract(M) return ..() @@ -41,7 +41,7 @@ /datum/reagent/xenomicrobes/on_mob_life(mob/living/carbon/M) if(volume > 1.5) var/datum/disease/virus/transformation/xeno/D = new - D.ForceContract(M) + D.Contract(M) return ..() /datum/reagent/fungalspores @@ -55,7 +55,7 @@ /datum/reagent/fungalspores/on_mob_life(mob/living/carbon/M) if(volume > 2.5) var/datum/disease/virus/tuberculosis/D = new - D.ForceContract(M) + D.Contract(M) return ..() /datum/reagent/jagged_crystals @@ -69,7 +69,7 @@ /datum/reagent/jagged_crystals/on_mob_life(mob/living/carbon/M) var/datum/disease/berserker/D = new - D.ForceContract(M) + D.Contract(M) return ..() /datum/reagent/salmonella @@ -83,7 +83,7 @@ /datum/reagent/salmonella/on_mob_life(mob/living/carbon/M) var/datum/disease/food_poisoning/D = new - D.ForceContract(M) + D.Contract(M) return ..() /datum/reagent/gibbis @@ -98,7 +98,7 @@ /datum/reagent/gibbis/on_mob_life(mob/living/carbon/M) if(volume > 2.5) var/datum/disease/virus/gbs/non_con/D = new - D.ForceContract(M) + D.Contract(M) return ..() /datum/reagent/prions @@ -113,7 +113,7 @@ /datum/reagent/prions/on_mob_life(mob/living/carbon/M) if(volume > 4.5) var/datum/disease/kuru/D = new - D.ForceContract(M) + D.Contract(M) return ..() /datum/reagent/grave_dust @@ -128,7 +128,7 @@ /datum/reagent/grave_dust/on_mob_life(mob/living/carbon/M) if(volume > 4.5) var/datum/disease/vampire/D = new - D.ForceContract(M) + D.Contract(M) return ..() /datum/reagent/bacon_grease @@ -143,7 +143,7 @@ /datum/reagent/bacon_grease/on_mob_life(mob/living/carbon/M) if(volume > 4.5) var/datum/disease/critical/heart_failure/D = new - D.ForceContract(M) + D.Contract(M) return ..() /datum/reagent/heartworms diff --git a/code/modules/reagents/chemistry/reagents/food.dm b/code/modules/reagents/chemistry/reagents/food.dm index 39589fbd1cf..b523dd0faf8 100644 --- a/code/modules/reagents/chemistry/reagents/food.dm +++ b/code/modules/reagents/chemistry/reagents/food.dm @@ -886,7 +886,7 @@ if(NO_HUNGER in H.dna.species.species_traits) //If you don't eat, then you can't get food poisoning return var/datum/disease/food_poisoning/D = new - D.ForceContract(H) + D.Contract(H) /datum/reagent/msg name = "Monosodium glutamate" @@ -933,7 +933,7 @@ to_chat(M, "Your chest is burning with pain!") M.Weaken(2 SECONDS) var/datum/disease/critical/heart_failure/D = new - D.ForceContract(M) + D.Contract(M) return ..() | update_flags /datum/reagent/fungus @@ -953,7 +953,7 @@ else if(ranchance <= 5) to_chat(M, "That tasted absolutely FOUL.") var/datum/disease/food_poisoning/D = new - D.ForceContract(M) + D.Contract(M) else to_chat(M, "Yuck!") diff --git a/code/modules/reagents/chemistry/reagents/toxins.dm b/code/modules/reagents/chemistry/reagents/toxins.dm index 736d1c91b0a..9e6d9e7855a 100644 --- a/code/modules/reagents/chemistry/reagents/toxins.dm +++ b/code/modules/reagents/chemistry/reagents/toxins.dm @@ -155,7 +155,7 @@ /datum/reagent/aslimetoxin/reaction_mob(mob/living/M, method=REAGENT_TOUCH, volume) if(method != REAGENT_TOUCH) var/datum/disease/virus/transformation/slime/D = new - D.ForceContract(M) + D.Contract(M) /datum/reagent/mercury @@ -1303,7 +1303,7 @@ /datum/reagent/gluttonytoxin/reaction_mob(mob/living/L, method=REAGENT_TOUCH, reac_volume) var/datum/disease/virus/transformation/morph/D = new - D.ForceContract(L) + D.Contract(L) /datum/reagent/bungotoxin name = "Bungotoxin" diff --git a/code/modules/reagents/chemistry/reagents/water.dm b/code/modules/reagents/chemistry/reagents/water.dm index 04eaf26507c..84b1bd05779 100644 --- a/code/modules/reagents/chemistry/reagents/water.dm +++ b/code/modules/reagents/chemistry/reagents/water.dm @@ -111,9 +111,9 @@ continue if(method == REAGENT_TOUCH) - V.Contract(M) - else //ingest, patch or inject - V.ForceContract(M) + V.Contract(M, need_protection_check = TRUE, act_type = CONTACT) + else + V.Contract(M, need_protection_check = FALSE) if(method == REAGENT_INGEST && iscarbon(M)) var/mob/living/carbon/C = M @@ -192,9 +192,9 @@ continue if(method == REAGENT_TOUCH) - V.Contract(M) - else //ingest, patch or inject - V.ForceContract(M) + V.Contract(M, need_protection_check = TRUE, act_type = CONTACT) + else + V.Contract(M, need_protection_check = FALSE) /datum/reagent/blood/synthetic/vox name = "Synthetic Blood" diff --git a/code/modules/surgery/organs/blood.dm b/code/modules/surgery/organs/blood.dm index c16b877a8ec..65b374eabe2 100644 --- a/code/modules/surgery/organs/blood.dm +++ b/code/modules/surgery/organs/blood.dm @@ -174,7 +174,7 @@ var/datum/disease/virus/V = thing if(V.spread_flags < BLOOD) continue - V.ForceContract(C) + V.Contract(C) if(!(blood_data["blood_type"] in get_safe_blood(C.dna.blood_type)) || !(blood_data["blood_species"] == C.dna.species.blood_species)) C.reagents.add_reagent("toxin", amount * 0.5) return 1 diff --git a/code/modules/surgery/organs/heart.dm b/code/modules/surgery/organs/heart.dm index 84a77073697..2e11d176c1b 100644 --- a/code/modules/surgery/organs/heart.dm +++ b/code/modules/surgery/organs/heart.dm @@ -257,7 +257,7 @@ if(prob(numMid)) to_chat(owner, "Your [name] lurches awkwardly!") var/datum/disease/critical/heart_failure/D = new - D.ForceContract(owner) + D.Contract(owner) if(prob(numMid)) to_chat(owner, "Your [name] stops beating!") Stop() @@ -274,4 +274,4 @@ if(prob(numLow)) to_chat(owner, "Your [name] lurches awkwardly!") var/datum/disease/critical/heart_failure/D = new - D.ForceContract(owner) + D.Contract(owner) diff --git a/paradise.dme b/paradise.dme index 59de87b06e8..0ffd1aa7a9e 100644 --- a/paradise.dme +++ b/paradise.dme @@ -394,8 +394,8 @@ #include "code\datums\components\swarming.dm" #include "code\datums\components\twohanded.dm" #include "code\datums\diseases\_disease.dm" -#include "code\datums\diseases\_MobProcs.dm" #include "code\datums\diseases\viruses\_virus.dm" +#include "code\datums\diseases\_MobProcs.dm" #include "code\datums\diseases\viruses\anxiety.dm" #include "code\datums\diseases\appendicitis.dm" #include "code\datums\diseases\viruses\beesease.dm"