Skip to content

Commit

Permalink
Contract system rework
Browse files Browse the repository at this point in the history
  • Loading branch information
LiquidPotroh committed Oct 21, 2023
1 parent 331819e commit de33d64
Show file tree
Hide file tree
Showing 30 changed files with 184 additions and 146 deletions.
85 changes: 84 additions & 1 deletion code/datums/diseases/_MobProcs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
35 changes: 12 additions & 23 deletions code/datums/diseases/_disease.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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()
Expand Down Expand Up @@ -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

4 changes: 2 additions & 2 deletions code/datums/diseases/critical.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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)
Expand Down
62 changes: 3 additions & 59 deletions code/datums/diseases/viruses/_virus.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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++
Expand All @@ -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))
Expand All @@ -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
6 changes: 3 additions & 3 deletions code/datums/diseases/viruses/advance/advance.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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()
Expand Down
2 changes: 1 addition & 1 deletion code/datums/diseases/viruses/cold.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
4 changes: 2 additions & 2 deletions code/datums/diseases/viruses/loyalty_syndrome.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion code/datums/diseases/viruses/transformation.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion code/game/gamemodes/miniantags/abduction/gland.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion code/modules/admin/admin_verbs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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].")

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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


/*======================================================================================================================================*\
Expand Down
2 changes: 1 addition & 1 deletion code/modules/awaymissions/corpse.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion code/modules/awaymissions/mission_code/academy.dm
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@
//Cold
T.visible_message("<span class='userdanger'>[user] looks a little under the weather!</span>")
var/datum/disease/virus/cold/D = new
D.ForceContract(user)
D.Contract(user)
if(10)
//Nothing
T.visible_message("<span class='userdanger'>Nothing seems to happen.</span>")
Expand Down
1 change: 1 addition & 0 deletions code/modules/clothing/suits/labcoat.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion code/modules/events/disease_outbreak.dm
Original file line number Diff line number Diff line change
Expand Up @@ -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
Loading

0 comments on commit de33d64

Please sign in to comment.