[MIRROR] Disease antagonist (#5815)
* Disease antagonist * Update mobs.dm * can I go to sleep yet
This commit is contained in:
committed by
Poojawa
parent
766b85908e
commit
a2e6253f00
@@ -589,14 +589,17 @@ GLOBAL_LIST_INIT(admin_verbs_hideable, list(
|
||||
message_admins("<span class='adminnotice'>[key_name_admin(usr)] removed the spell [S] from [key_name(T)].</span>")
|
||||
SSblackbox.record_feedback("tally", "admin_verb", 1, "Remove Spell") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
/client/proc/give_disease(mob/T in GLOB.mob_list)
|
||||
/client/proc/give_disease(mob/living/T in GLOB.mob_living_list)
|
||||
set category = "Fun"
|
||||
set name = "Give Disease"
|
||||
set desc = "Gives a Disease to a mob."
|
||||
if(!istype(T))
|
||||
to_chat(src, "<span class='notice'>You can only give a disease to a mob of type /mob/living.</span>")
|
||||
return
|
||||
var/datum/disease/D = input("Choose the disease to give to that guy", "ACHOO") as null|anything in SSdisease.diseases
|
||||
if(!D)
|
||||
return
|
||||
T.ForceContractDisease(new D)
|
||||
T.ForceContractDisease(new D, FALSE, TRUE)
|
||||
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_admin("[key_name(usr)] gave [key_name(T)] the disease [D].")
|
||||
message_admins("<span class='adminnotice'>[key_name_admin(usr)] gave [key_name(T)] the disease [D].</span>")
|
||||
|
||||
@@ -194,15 +194,12 @@
|
||||
to_chat(owner, "<span class='warning'>You feel sick.</span>")
|
||||
var/datum/disease/advance/A = random_virus(pick(2,6),6)
|
||||
A.carrier = TRUE
|
||||
owner.viruses += A
|
||||
A.affected_mob = owner
|
||||
owner.med_hud_set_status()
|
||||
owner.ForceContractDisease(A, FALSE, TRUE)
|
||||
|
||||
/obj/item/organ/heart/gland/viral/proc/random_virus(max_symptoms, max_level)
|
||||
if(max_symptoms > SYMPTOM_LIMIT)
|
||||
max_symptoms = SYMPTOM_LIMIT
|
||||
var/datum/disease/advance/A = new(FALSE, null)
|
||||
A.symptoms = list()
|
||||
if(max_symptoms > VIRUS_SYMPTOM_LIMIT)
|
||||
max_symptoms = VIRUS_SYMPTOM_LIMIT
|
||||
var/datum/disease/advance/A = new /datum/disease/advance()
|
||||
var/list/datum/symptom/possible_symptoms = list()
|
||||
for(var/symptom in subtypesof(/datum/symptom))
|
||||
var/datum/symptom/S = symptom
|
||||
|
||||
@@ -20,6 +20,7 @@ GLOBAL_LIST_EMPTY(blob_nodes)
|
||||
pass_flags = PASSBLOB
|
||||
faction = list(ROLE_BLOB)
|
||||
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
|
||||
call_life = TRUE
|
||||
var/obj/structure/blob/core/blob_core = null // The blob overmind's core
|
||||
var/blob_points = 0
|
||||
var/max_blob_points = 100
|
||||
@@ -67,7 +68,7 @@ GLOBAL_LIST_EMPTY(blob_nodes)
|
||||
if(!T)
|
||||
CRASH("No blobspawnpoints and blob spawned in nullspace.")
|
||||
forceMove(T)
|
||||
|
||||
|
||||
/mob/camera/blob/proc/is_valid_turf(turf/T)
|
||||
var/area/A = get_area(T)
|
||||
if((A && !A.blob_allowed) || !T || !is_station_level(T.z) || isspaceturf(T))
|
||||
@@ -217,9 +218,6 @@ GLOBAL_LIST_EMPTY(blob_nodes)
|
||||
var/link = FOLLOW_LINK(M, src)
|
||||
to_chat(M, "[link] [rendered]")
|
||||
|
||||
/mob/camera/blob/emote(act,m_type=1,message = null)
|
||||
return
|
||||
|
||||
/mob/camera/blob/blob_act(obj/structure/blob/B)
|
||||
return
|
||||
|
||||
|
||||
@@ -30,9 +30,11 @@
|
||||
user.reagents.add_reagent("antihol", 10)
|
||||
user.reagents.add_reagent("mannitol", 25)
|
||||
|
||||
for(var/thing in user.viruses)
|
||||
var/datum/disease/D = thing
|
||||
if(D.severity == VIRUS_SEVERITY_POSITIVE)
|
||||
continue
|
||||
D.cure()
|
||||
if(isliving(user))
|
||||
var/mob/living/L = user
|
||||
for(var/thing in L.diseases)
|
||||
var/datum/disease/D = thing
|
||||
if(D.severity == DISEASE_SEVERITY_POSITIVE)
|
||||
continue
|
||||
D.cure()
|
||||
return TRUE
|
||||
|
||||
@@ -0,0 +1,347 @@
|
||||
/*
|
||||
Abilities that can be purchased by disease mobs. Most are just passive symptoms that will be
|
||||
added to their disease, but some are active abilites that affect only the target the overmind
|
||||
is currently following.
|
||||
*/
|
||||
|
||||
GLOBAL_LIST_INIT(disease_ability_singletons, list(
|
||||
new /datum/disease_ability/action/cough(),
|
||||
new /datum/disease_ability/action/sneeze(),
|
||||
new /datum/disease_ability/symptom/cough(),
|
||||
new /datum/disease_ability/symptom/sneeze(),\
|
||||
new /datum/disease_ability/symptom/hallucigen(),
|
||||
new /datum/disease_ability/symptom/choking(),
|
||||
new /datum/disease_ability/symptom/confusion(),
|
||||
new /datum/disease_ability/symptom/youth(),
|
||||
new /datum/disease_ability/symptom/vomit(),
|
||||
new /datum/disease_ability/symptom/voice_change(),
|
||||
new /datum/disease_ability/symptom/visionloss(),
|
||||
new /datum/disease_ability/symptom/viraladaptation(),
|
||||
new /datum/disease_ability/symptom/vitiligo(),
|
||||
new /datum/disease_ability/symptom/sensory_restoration(),
|
||||
new /datum/disease_ability/symptom/itching(),
|
||||
new /datum/disease_ability/symptom/weight_loss(),
|
||||
new /datum/disease_ability/symptom/metabolism_heal(),
|
||||
new /datum/disease_ability/symptom/coma_heal()
|
||||
))
|
||||
|
||||
/datum/disease_ability
|
||||
var/name
|
||||
var/cost = 0
|
||||
var/required_total_points = 0
|
||||
var/start_with = FALSE
|
||||
var/short_desc = ""
|
||||
var/long_desc = ""
|
||||
var/stat_block = ""
|
||||
var/threshold_block = ""
|
||||
var/category = ""
|
||||
|
||||
var/list/symptoms
|
||||
var/list/actions
|
||||
|
||||
/datum/disease_ability/New()
|
||||
..()
|
||||
if(symptoms)
|
||||
var/stealth = 0
|
||||
var/resistance = 0
|
||||
var/stage_speed = 0
|
||||
var/transmittable = 0
|
||||
for(var/T in symptoms)
|
||||
var/datum/symptom/S = T
|
||||
stealth += initial(S.stealth)
|
||||
resistance += initial(S.resistance)
|
||||
stage_speed += initial(S.stage_speed)
|
||||
transmittable += initial(S.transmittable)
|
||||
threshold_block += "<br><br>[initial(S.threshold_desc)]"
|
||||
stat_block = "Resistance: [resistance]<br>Stealth: [stealth]<br>Stage Speed: [stage_speed]<br>Transmittability: [transmittable]<br><br>"
|
||||
|
||||
/datum/disease_ability/proc/CanBuy(mob/camera/disease/D)
|
||||
if(world.time < D.next_adaptation_time)
|
||||
return FALSE
|
||||
if(!D.unpurchased_abilities[src])
|
||||
return FALSE
|
||||
return (D.points >= cost) && (D.total_points >= required_total_points)
|
||||
|
||||
/datum/disease_ability/proc/Buy(mob/camera/disease/D, silent = FALSE, trigger_cooldown = TRUE)
|
||||
if(!silent)
|
||||
to_chat(D, "<span class='notice'>Purchased [name].</span>")
|
||||
D.points -= cost
|
||||
D.unpurchased_abilities -= src
|
||||
if(trigger_cooldown)
|
||||
D.adapt_cooldown()
|
||||
D.purchased_abilities[src] = TRUE
|
||||
for(var/V in (D.disease_instances+D.disease_template))
|
||||
var/datum/disease/advance/sentient_disease/SD = V
|
||||
if(symptoms)
|
||||
for(var/T in symptoms)
|
||||
var/datum/symptom/S = new T()
|
||||
SD.symptoms += S
|
||||
if(SD.processing)
|
||||
S.Start(SD)
|
||||
SD.Refresh()
|
||||
for(var/T in actions)
|
||||
var/datum/action/A = new T()
|
||||
A.Grant(D)
|
||||
|
||||
|
||||
/datum/disease_ability/proc/CanRefund(mob/camera/disease/D)
|
||||
if(world.time < D.next_adaptation_time)
|
||||
return FALSE
|
||||
return D.purchased_abilities[src]
|
||||
|
||||
/datum/disease_ability/proc/Refund(mob/camera/disease/D, silent = FALSE, trigger_cooldown = TRUE)
|
||||
if(!silent)
|
||||
to_chat(D, "<span class='notice'>Refunded [name].</span>")
|
||||
D.points += cost
|
||||
D.unpurchased_abilities[src] = TRUE
|
||||
if(trigger_cooldown)
|
||||
D.adapt_cooldown()
|
||||
D.purchased_abilities -= src
|
||||
for(var/V in (D.disease_instances+D.disease_template))
|
||||
var/datum/disease/advance/sentient_disease/SD = V
|
||||
if(symptoms)
|
||||
for(var/T in symptoms)
|
||||
var/datum/symptom/S = locate(T) in SD.symptoms
|
||||
if(S)
|
||||
SD.symptoms -= S
|
||||
if(SD.processing)
|
||||
S.End(SD)
|
||||
qdel(S)
|
||||
SD.Refresh()
|
||||
for(var/T in actions)
|
||||
var/datum/action/A = locate(T) in D.actions
|
||||
qdel(A)
|
||||
|
||||
//these sybtypes are for conveniently separating the different categories, they have no unique code.
|
||||
|
||||
/datum/disease_ability/action
|
||||
category = "Active"
|
||||
|
||||
/datum/disease_ability/symptom
|
||||
category = "Symptom"
|
||||
|
||||
//active abilities and their associated actions
|
||||
|
||||
/datum/disease_ability/action/cough
|
||||
name = "Voluntary Coughing"
|
||||
actions = list(/datum/action/cooldown/disease_cough)
|
||||
cost = 0
|
||||
required_total_points = 0
|
||||
start_with = TRUE
|
||||
short_desc = "Force the host you are following to cough, spreading your infection to those nearby."
|
||||
long_desc = "Force the host you are following to cough with extra force, spreading your infection to those within two meters of your host even if your transmitability is low.<br>Cooldown: 10 seconds"
|
||||
|
||||
|
||||
/datum/action/cooldown/disease_cough
|
||||
name = "Cough"
|
||||
icon_icon = 'icons/mob/actions/actions_minor_antag.dmi'
|
||||
button_icon_state = "cough"
|
||||
desc = "Force the host you are following to cough with extra force, spreading your infection to those within two meters of your host even if your transmitability is low.<br>Cooldown: 10 seconds"
|
||||
cooldown_time = 100
|
||||
|
||||
/datum/action/cooldown/disease_cough/Trigger()
|
||||
if(!..())
|
||||
return FALSE
|
||||
var/mob/camera/disease/D = owner
|
||||
var/mob/living/L = D.following_host
|
||||
if(!L)
|
||||
return FALSE
|
||||
if(L.stat != CONSCIOUS)
|
||||
to_chat(D, "<span class='warning'>Your host must be concious to cough.</span>")
|
||||
return FALSE
|
||||
to_chat(D, "<span class='notice'>You force [L.real_name] to cough.</span>")
|
||||
L.emote("cough")
|
||||
var/datum/disease/advance/sentient_disease/SD = D.hosts[L]
|
||||
SD.spread(2)
|
||||
StartCooldown()
|
||||
return TRUE
|
||||
|
||||
|
||||
/datum/disease_ability/action/sneeze
|
||||
name = "Voluntary Sneezing"
|
||||
actions = list(/datum/action/cooldown/disease_sneeze)
|
||||
cost = 2
|
||||
required_total_points = 3
|
||||
short_desc = "Force the host you are following to sneeze, spreading your infection to those in front of them."
|
||||
long_desc = "Force the host you are following to sneeze with extra force, spreading your infection to any victims in a 4 meter cone in front of your host.<br>Cooldown: 20 seconds"
|
||||
|
||||
|
||||
/datum/action/cooldown/disease_sneeze
|
||||
name = "Sneeze"
|
||||
icon_icon = 'icons/mob/actions/actions_minor_antag.dmi'
|
||||
button_icon_state = "sneeze"
|
||||
desc = "Force the host you are following to sneeze with extra force, spreading your infection to any victims in a 4 meter cone in front of your host even if your transmitability is low.<br>Cooldown: 20 seconds"
|
||||
cooldown_time = 200
|
||||
|
||||
/datum/action/cooldown/disease_sneeze/Trigger()
|
||||
if(!..())
|
||||
return FALSE
|
||||
var/mob/camera/disease/D = owner
|
||||
var/mob/living/L = D.following_host
|
||||
if(!L)
|
||||
return FALSE
|
||||
if(L.stat != CONSCIOUS)
|
||||
to_chat(D, "<span class='warning'>Your host must be concious to sneeze.</span>")
|
||||
return FALSE
|
||||
to_chat(D, "<span class='notice'>You force [L.real_name] to sneeze.</span>")
|
||||
L.emote("sneeze")
|
||||
var/datum/disease/advance/sentient_disease/SD = D.hosts[L]
|
||||
|
||||
for(var/mob/living/M in oview(4, SD.affected_mob))
|
||||
if(is_A_facing_B(SD.affected_mob, M) && disease_air_spread_walk(get_turf(SD.affected_mob), get_turf(M)))
|
||||
M.AirborneContractDisease(SD, TRUE)
|
||||
|
||||
StartCooldown()
|
||||
return TRUE
|
||||
|
||||
//passive symptom abilities
|
||||
|
||||
/datum/disease_ability/symptom/cough
|
||||
name = "Involuntary Coughing"
|
||||
symptoms = list(/datum/symptom/cough)
|
||||
cost = 2
|
||||
required_total_points = 4
|
||||
short_desc = "Cause victims to cough intermittently."
|
||||
long_desc = "Cause victims to cough intermittently, spreading your infection if your transmitability is high."
|
||||
|
||||
/datum/disease_ability/symptom/sneeze
|
||||
name = "Involuntary Sneezing"
|
||||
symptoms = list(/datum/symptom/sneeze)
|
||||
cost = 2
|
||||
required_total_points = 4
|
||||
short_desc = "Cause victims to sneeze intermittently."
|
||||
long_desc = "Cause victims to sneeze intermittently, spreading your infection and also increasing transmitability and resistance, at the cost of stealth."
|
||||
|
||||
/datum/disease_ability/symptom/beard
|
||||
//I don't think I need to justify the fact that this is the best symptom
|
||||
name = "Beard Growth"
|
||||
symptoms = list(/datum/symptom/beard)
|
||||
cost = 1
|
||||
required_total_points = 8
|
||||
short_desc = "Cause all victims to grow a luscious beard."
|
||||
long_desc = "Cause all victims to grow a luscious beard. Decreases stats slightly. Ineffective against Santa Claus."
|
||||
|
||||
/datum/disease_ability/symptom/hallucigen
|
||||
name = "Hallucinations"
|
||||
symptoms = list(/datum/symptom/hallucigen)
|
||||
cost = 4
|
||||
required_total_points = 8
|
||||
short_desc = "Cause victims to hallucinate."
|
||||
long_desc = "Cause victims to hallucinate. Decreases stats, especially resistance."
|
||||
|
||||
|
||||
/datum/disease_ability/symptom/choking
|
||||
name = "Choking"
|
||||
symptoms = list(/datum/symptom/choking)
|
||||
cost = 4
|
||||
required_total_points = 8
|
||||
short_desc = "Cause victims to choke."
|
||||
long_desc = "Cause victims to choke, threatening asphyxiation. Decreases stats, especially transmittability."
|
||||
|
||||
|
||||
/datum/disease_ability/symptom/confusion
|
||||
name = "Confusion"
|
||||
symptoms = list(/datum/symptom/confusion)
|
||||
cost = 4
|
||||
required_total_points = 8
|
||||
short_desc = "Cause victims to become confused."
|
||||
long_desc = "Cause victims to become confused intermittently."
|
||||
|
||||
|
||||
/datum/disease_ability/symptom/youth
|
||||
name = "Eternal Youth"
|
||||
symptoms = list(/datum/symptom/youth)
|
||||
cost = 4
|
||||
required_total_points = 8
|
||||
short_desc = "Cause victims to become eternally young."
|
||||
long_desc = "Cause victims to become eternally young. Provides boosts to all stats except transmittability."
|
||||
|
||||
|
||||
/datum/disease_ability/symptom/vomit
|
||||
name = "Vomiting"
|
||||
symptoms = list(/datum/symptom/vomit)
|
||||
cost = 4
|
||||
required_total_points = 8
|
||||
short_desc = "Cause victims to vomit."
|
||||
long_desc = "Cause victims to vomit. Slightly increases transmittability. Vomiting also also causes the victims to lose nutrition and removes some toxin damage."
|
||||
|
||||
|
||||
/datum/disease_ability/symptom/voice_change
|
||||
name = "Voice Changing"
|
||||
symptoms = list(/datum/symptom/voice_change)
|
||||
cost = 4
|
||||
required_total_points = 8
|
||||
short_desc = "Change the voice of victims."
|
||||
long_desc = "Change the voice of victims, causing confusion in communications."
|
||||
|
||||
|
||||
/datum/disease_ability/symptom/visionloss
|
||||
name = "Vision Loss"
|
||||
symptoms = list(/datum/symptom/visionloss)
|
||||
cost = 4
|
||||
required_total_points = 8
|
||||
short_desc = "Damage the eyes of victims, eventually causing blindness."
|
||||
long_desc = "Damage the eyes of victims, eventually causing blindness. Decreases all stats."
|
||||
|
||||
|
||||
/datum/disease_ability/symptom/viraladaptation
|
||||
name = "Self-Adaptation"
|
||||
symptoms = list(/datum/symptom/viraladaptation)
|
||||
cost = 4
|
||||
required_total_points = 8
|
||||
short_desc = "Cause your infection to become more resistant to detection and eradication."
|
||||
long_desc = "Cause your infection to mimic the function of normal body cells, becoming much harder to spot and to eradicate, but reducing its speed."
|
||||
|
||||
|
||||
/datum/disease_ability/symptom/vitiligo
|
||||
name = "Skin Paleness"
|
||||
symptoms = list(/datum/symptom/vitiligo)
|
||||
cost = 1
|
||||
required_total_points = 8
|
||||
short_desc = "Cause victims to become pale."
|
||||
long_desc = "Cause victims to become pale. Decreases all stats."
|
||||
|
||||
|
||||
/datum/disease_ability/symptom/sensory_restoration
|
||||
name = "Sensory Restoration"
|
||||
symptoms = list(/datum/symptom/sensory_restoration)
|
||||
cost = 4
|
||||
required_total_points = 8
|
||||
short_desc = "Regenerate eye and ear damage of victims."
|
||||
long_desc = "Regenerate eye and ear damage of victims."
|
||||
|
||||
|
||||
/datum/disease_ability/symptom/itching
|
||||
name = "Itching"
|
||||
symptoms = list(/datum/symptom/itching)
|
||||
cost = 4
|
||||
required_total_points = 8
|
||||
short_desc = "Cause victims to itch."
|
||||
long_desc = "Cause victims to itch, increasing all stats except stealth."
|
||||
|
||||
|
||||
/datum/disease_ability/symptom/weight_loss
|
||||
name = "Weight Loss"
|
||||
symptoms = list(/datum/symptom/weight_loss)
|
||||
cost = 4
|
||||
required_total_points = 8
|
||||
short_desc = "Cause victims to lose weight."
|
||||
long_desc = "Cause victims to lose weight, and make it almost immpossible for them to gain nutrition from food. Reduced nutrition allows your infection to spread more easily from hosts, especially by sneezing."
|
||||
|
||||
|
||||
/datum/disease_ability/symptom/metabolism_heal
|
||||
name = "Metabolic Boost"
|
||||
symptoms = list(/datum/symptom/heal/metabolism)
|
||||
cost = 4
|
||||
required_total_points = 16
|
||||
short_desc = "Increase the metabolism of victims, causing them to process chemicals and grow hungry faster."
|
||||
long_desc = "Increase the metabolism of victims, causing them to process chemicals twice as fast and grow hungry more quickly."
|
||||
|
||||
|
||||
/datum/disease_ability/symptom/coma_heal
|
||||
name = "Regenerative Coma"
|
||||
symptoms = list(/datum/symptom/heal/coma)
|
||||
cost = 8
|
||||
required_total_points = 16
|
||||
short_desc = "Cause victims to fall into a healing coma when hurt."
|
||||
long_desc = "Cause victims to fall into a healing coma when hurt."
|
||||
@@ -0,0 +1,100 @@
|
||||
/datum/antagonist/disease
|
||||
name = "Sentient Disease"
|
||||
roundend_category = "diseases"
|
||||
antagpanel_category = "Disease"
|
||||
var/disease_name = ""
|
||||
|
||||
/datum/antagonist/disease/on_gain()
|
||||
owner.special_role = "Sentient Disease"
|
||||
owner.assigned_role = "Sentient Disease"
|
||||
var/datum/objective/O = new /datum/objective/disease_infect()
|
||||
O.owner = owner
|
||||
objectives += O
|
||||
owner.objectives += O
|
||||
|
||||
O = new /datum/objective/disease_infect_centcom()
|
||||
O.owner = owner
|
||||
objectives += O
|
||||
owner.objectives += O
|
||||
|
||||
. = ..()
|
||||
|
||||
/datum/antagonist/disease/greet()
|
||||
to_chat(owner.current, "<span class='notice'>You are the [owner.special_role]!</span>")
|
||||
to_chat(owner.current, "<span class='notice'>Infect members of the crew to gain adaptation points, and spread your infection further.</span>")
|
||||
owner.announce_objectives()
|
||||
|
||||
/datum/antagonist/disease/apply_innate_effects(mob/living/mob_override)
|
||||
if(!istype(owner.current, /mob/camera/disease))
|
||||
var/turf/T = get_turf(owner.current)
|
||||
T = T ? T : locate(1, 1, 1)
|
||||
var/mob/camera/disease/D = new /mob/camera/disease(T)
|
||||
owner.transfer_to(D)
|
||||
|
||||
/datum/antagonist/disease/admin_add(datum/mind/new_owner,mob/admin)
|
||||
..()
|
||||
var/mob/camera/disease/D = new_owner.current
|
||||
D.infect_patient_zero()
|
||||
D.pick_name()
|
||||
|
||||
/datum/antagonist/disease/roundend_report()
|
||||
var/list/result = list()
|
||||
|
||||
result += "<b>Disease name:</b> [disease_name]"
|
||||
result += printplayer(owner)
|
||||
|
||||
var/win = TRUE
|
||||
var/objectives_text = ""
|
||||
var/count = 1
|
||||
for(var/datum/objective/objective in objectives)
|
||||
if(objective.check_completion())
|
||||
objectives_text += "<br><B>Objective #[count]</B>: [objective.explanation_text] <span class='greentext'>Success!</span>"
|
||||
else
|
||||
objectives_text += "<br><B>Objective #[count]</B>: [objective.explanation_text] <span class='redtext'>Fail.</span>"
|
||||
win = FALSE
|
||||
count++
|
||||
|
||||
result += objectives_text
|
||||
|
||||
var/special_role_text = lowertext(name)
|
||||
|
||||
if(win)
|
||||
result += "<span class='greentext'>The [special_role_text] was successful!</span>"
|
||||
else
|
||||
result += "<span class='redtext'>The [special_role_text] has failed!</span>"
|
||||
|
||||
if(istype(owner.current, /mob/camera/disease))
|
||||
var/mob/camera/disease/D = owner.current
|
||||
result += "<B>[disease_name] completed the round with [D.hosts.len] infected hosts, and reached a maximum of [D.total_points] concurrent infections.</B>"
|
||||
result += "<B>[disease_name] completed the round with the following adaptations:</B>"
|
||||
var/list/adaptations = list()
|
||||
for(var/V in D.purchased_abilities)
|
||||
var/datum/disease_ability/A = V
|
||||
adaptations += A.name
|
||||
result += adaptations.Join(", ")
|
||||
|
||||
return result.Join("<br>")
|
||||
|
||||
|
||||
/datum/objective/disease_infect
|
||||
explanation_text = "Survive and infect as many people as possible."
|
||||
|
||||
/datum/objective/disease_infect/check_completion()
|
||||
var/mob/camera/disease/D = owner.current
|
||||
if(istype(D) && D.hosts.len) //theoretically it should not exist if it has no hosts, but better safe than sorry.
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
|
||||
/datum/objective/disease_infect_centcom
|
||||
explanation_text = "Ensure that at least one infected host escapes on the shuttle or an escape pod."
|
||||
|
||||
/datum/objective/disease_infect_centcom/check_completion()
|
||||
var/mob/camera/disease/D = owner.current
|
||||
if(!istype(D))
|
||||
return FALSE
|
||||
for(var/V in D.hosts)
|
||||
var/mob/living/L = V
|
||||
if(L.onCentCom() || L.onSyndieBase())
|
||||
return TRUE
|
||||
return FALSE
|
||||
@@ -0,0 +1,59 @@
|
||||
/datum/disease/advance/sentient_disease
|
||||
form = "Virus"
|
||||
name = "Sentient Virus"
|
||||
desc = "An apparently sentient virus, extremely adaptable and resistant to outside sources of mutation."
|
||||
viable_mobtypes = list(/mob/living/carbon/human)
|
||||
mutable = FALSE
|
||||
var/mob/camera/disease/overmind
|
||||
|
||||
/datum/disease/advance/sentient_disease/New()
|
||||
..()
|
||||
GLOB.sentient_disease_instances += src
|
||||
|
||||
/datum/disease/advance/sentient_disease/Destroy()
|
||||
. = ..()
|
||||
GLOB.sentient_disease_instances -= src
|
||||
|
||||
/datum/disease/advance/sentient_disease/remove_disease()
|
||||
if(overmind)
|
||||
overmind.remove_infection(src)
|
||||
..()
|
||||
|
||||
/datum/disease/advance/sentient_disease/infect(var/mob/living/infectee, make_copy = TRUE)
|
||||
if(make_copy && overmind && (overmind.disease_template != src))
|
||||
overmind.disease_template.infect(infectee, TRUE) //get an updated version of the virus
|
||||
else
|
||||
..()
|
||||
|
||||
|
||||
/datum/disease/advance/sentient_disease/IsSame(datum/disease/D)
|
||||
if(istype(src, D.type))
|
||||
var/datum/disease/advance/sentient_disease/V = D
|
||||
if(V.overmind == overmind)
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
|
||||
/datum/disease/advance/sentient_disease/Copy()
|
||||
var/datum/disease/advance/sentient_disease/D = ..()
|
||||
D.overmind = overmind
|
||||
return D
|
||||
|
||||
/datum/disease/advance/sentient_disease/after_add()
|
||||
if(overmind)
|
||||
overmind.add_infection(src)
|
||||
|
||||
|
||||
/datum/disease/advance/sentient_disease/GetDiseaseID()
|
||||
return "[type]|[overmind ? overmind.tag : null]"
|
||||
|
||||
/datum/disease/advance/sentient_disease/GenerateCure()
|
||||
if(cures.len)
|
||||
return
|
||||
var/list/not_used = advance_cures.Copy()
|
||||
cures = list(pick_n_take(not_used), pick_n_take(not_used))
|
||||
|
||||
// Get the cure name from the cure_id
|
||||
var/datum/reagent/D1 = GLOB.chemical_reagents_list[cures[1]]
|
||||
var/datum/reagent/D2 = GLOB.chemical_reagents_list[cures[2]]
|
||||
cure_text = "[D1.name] and [D2.name]"
|
||||
@@ -0,0 +1,30 @@
|
||||
|
||||
/datum/round_event_control/sentient_disease
|
||||
name = "Spawn Sentient Disease"
|
||||
typepath = /datum/round_event/ghost_role/sentient_disease
|
||||
weight = 7
|
||||
max_occurrences = 1
|
||||
min_players = 5
|
||||
|
||||
|
||||
/datum/round_event/ghost_role/sentient_disease
|
||||
role_name = "sentient disease"
|
||||
|
||||
/datum/round_event/ghost_role/sentient_disease/spawn_role()
|
||||
var/list/candidates = get_candidates(ROLE_ALIEN, null, ROLE_ALIEN)
|
||||
if(!candidates.len)
|
||||
return NOT_ENOUGH_PLAYERS
|
||||
|
||||
var/mob/dead/observer/selected = pick_n_take(candidates)
|
||||
|
||||
var/mob/camera/disease/virus = new /mob/camera/disease(locate(1, 1, 1))
|
||||
if(!virus.infect_patient_zero())
|
||||
message_admins("Event attempted to spawn a sentient disease, but infection of patient zero failed.")
|
||||
qdel(virus)
|
||||
return WAITING_FOR_SOMETHING
|
||||
virus.key = selected.key
|
||||
INVOKE_ASYNC(virus, /mob/camera/disease/proc/pick_name)
|
||||
message_admins("[key_name_admin(virus)] has been made into a sentient disease by an event.")
|
||||
log_game("[key_name(virus)] was spawned as a sentient disease by an event.")
|
||||
spawned_mobs += virus
|
||||
return SUCCESSFUL_SPAWN
|
||||
@@ -0,0 +1,318 @@
|
||||
/*
|
||||
A mob of type /mob/camera/disease is an overmind coordinating at least one instance of /datum/disease/advance/sentient_disease
|
||||
that has infected a host. All instances in a host will be synchronized with the stats of the overmind's disease_template. Any
|
||||
samples outside of a host will retain the stats they had when they left the host, but infecting a new host will cause
|
||||
the new instance inside the host to be updated to the template's stats.
|
||||
*/
|
||||
|
||||
/mob/camera/disease
|
||||
name = ""
|
||||
real_name = ""
|
||||
desc = ""
|
||||
icon = 'icons/mob/blob.dmi'
|
||||
icon_state = "marker"
|
||||
mouse_opacity = MOUSE_OPACITY_ICON
|
||||
move_on_shuttle = 1
|
||||
see_in_dark = 8
|
||||
invisibility = INVISIBILITY_OBSERVER
|
||||
layer = BELOW_MOB_LAYER
|
||||
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
|
||||
sight = SEE_SELF
|
||||
initial_language_holder = /datum/language_holder/empty
|
||||
|
||||
var/datum/action/innate/disease_adapt/adaptation_menu_action
|
||||
var/datum/disease_ability/examining_ability
|
||||
var/datum/browser/browser
|
||||
var/browser_open = FALSE
|
||||
|
||||
var/mob/living/following_host
|
||||
var/datum/component/redirect/move_listener
|
||||
var/list/disease_instances
|
||||
var/list/hosts //this list is associative, affected_mob -> disease_instance
|
||||
var/datum/disease/advance/sentient_disease/disease_template
|
||||
|
||||
var/total_points = 0
|
||||
var/points = 0
|
||||
|
||||
var/last_move_tick = 0
|
||||
var/move_delay = 1
|
||||
|
||||
var/next_adaptation_time = 0
|
||||
var/adaptation_cooldown = 1200
|
||||
|
||||
var/list/purchased_abilities
|
||||
var/list/unpurchased_abilities
|
||||
|
||||
/mob/camera/disease/Initialize(mapload)
|
||||
.= ..()
|
||||
adaptation_menu_action = new /datum/action/innate/disease_adapt()
|
||||
adaptation_menu_action.Grant(src)
|
||||
|
||||
disease_instances = list()
|
||||
hosts = list()
|
||||
|
||||
purchased_abilities = list()
|
||||
unpurchased_abilities = list()
|
||||
for(var/V in GLOB.disease_ability_singletons)
|
||||
unpurchased_abilities[V] = TRUE
|
||||
var/datum/disease_ability/A = V
|
||||
if(A.start_with && A.CanBuy(src))
|
||||
A.Buy(src, TRUE, FALSE)
|
||||
|
||||
disease_template = new /datum/disease/advance/sentient_disease()
|
||||
disease_template.overmind = src
|
||||
qdel(SSdisease.archive_diseases[disease_template.GetDiseaseID()])
|
||||
SSdisease.archive_diseases[disease_template.GetDiseaseID()] = disease_template //important for stuff that uses disease IDs
|
||||
|
||||
var/datum/atom_hud/my_hud = GLOB.huds[DATA_HUD_SENTIENT_DISEASE]
|
||||
my_hud.add_hud_to(src)
|
||||
|
||||
browser = new /datum/browser(src, "disease_menu", "Adaptation Menu", 1000, 770, src)
|
||||
|
||||
/mob/camera/disease/Destroy()
|
||||
. = ..()
|
||||
for(var/V in GLOB.sentient_disease_instances)
|
||||
var/datum/disease/advance/sentient_disease/S = V
|
||||
if(S.overmind == src)
|
||||
S.overmind = null
|
||||
|
||||
/mob/camera/disease/Stat()
|
||||
..()
|
||||
if(statpanel("Status"))
|
||||
stat("Adaptation Points: [points]/[total_points]")
|
||||
stat("Hosts: [disease_instances.len]")
|
||||
var/adapt_ready = next_adaptation_time - world.time
|
||||
if(adapt_ready > 0)
|
||||
stat("Adaptation Ready: [round(adapt_ready/10, 0.1)]s")
|
||||
|
||||
/mob/camera/disease/say(message)
|
||||
return
|
||||
|
||||
/mob/camera/disease/Move(NewLoc, Dir = 0)
|
||||
if(world.time > (last_move_tick + move_delay))
|
||||
follow_next(Dir & NORTHWEST)
|
||||
last_move_tick = world.time
|
||||
|
||||
/mob/camera/disease/mind_initialize()
|
||||
. = ..()
|
||||
if(!mind.has_antag_datum(/datum/antagonist/disease))
|
||||
mind.add_antag_datum(/datum/antagonist/disease)
|
||||
|
||||
/mob/camera/disease/proc/pick_name()
|
||||
var/static/list/taken_names
|
||||
if(!taken_names)
|
||||
taken_names = list("Unknown" = TRUE)
|
||||
for(var/T in (subtypesof(/datum/disease) - /datum/disease/advance))
|
||||
var/datum/disease/D = T
|
||||
taken_names[initial(D.name)] = TRUE
|
||||
var/set_name
|
||||
while(!set_name)
|
||||
var/input = stripped_input(src, "Select a name for your disease", "Select Name", "", MAX_NAME_LEN)
|
||||
if(!input)
|
||||
set_name = "Sentient Virus"
|
||||
break
|
||||
if(taken_names[input])
|
||||
to_chat(src, "<span class='notice'>You cannot use the name of such a well-known disease!</span>")
|
||||
else
|
||||
set_name = input
|
||||
real_name = "[set_name] (Sentient Disease)"
|
||||
name = "[set_name] (Sentient Disease)"
|
||||
disease_template.AssignName(set_name)
|
||||
var/datum/antagonist/disease/A = mind.has_antag_datum(/datum/antagonist/disease)
|
||||
if(A)
|
||||
A.disease_name = set_name
|
||||
|
||||
/mob/camera/disease/proc/infect_patient_zero()
|
||||
var/list/possible_hosts = list()
|
||||
var/datum/disease/advance/sentient_disease/V = disease_template.Copy()
|
||||
for(var/mob/living/carbon/human/H in GLOB.carbon_list)
|
||||
if((H.stat != DEAD) && H.CanContractDisease(V))
|
||||
possible_hosts += H
|
||||
if(!possible_hosts.len)
|
||||
return FALSE
|
||||
var/mob/living/carbon/human/H = pick(possible_hosts)
|
||||
if(H.ForceContractDisease(V, FALSE, TRUE))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/mob/camera/disease/proc/force_infect(mob/living/L)
|
||||
var/datum/disease/advance/sentient_disease/V = disease_template.Copy()
|
||||
return L.ForceContractDisease(V, FALSE, TRUE)
|
||||
|
||||
/mob/camera/disease/proc/add_infection(datum/disease/advance/sentient_disease/V)
|
||||
disease_instances += V
|
||||
hosts[V.affected_mob] = V
|
||||
total_points = max(total_points, disease_instances.len)
|
||||
points += 1
|
||||
|
||||
var/image/holder = V.affected_mob.hud_list[SENTIENT_DISEASE_HUD]
|
||||
var/mutable_appearance/MA = new /mutable_appearance(holder)
|
||||
MA.icon_state = "virus_infected"
|
||||
MA.layer = BELOW_MOB_LAYER
|
||||
MA.color = COLOR_GREEN_GRAY
|
||||
MA.alpha = 200
|
||||
holder.appearance = MA
|
||||
var/datum/atom_hud/my_hud = GLOB.huds[DATA_HUD_SENTIENT_DISEASE]
|
||||
my_hud.add_to_hud(V.affected_mob)
|
||||
|
||||
to_chat(src, "<span class='notice'>A new host, <b>[V.affected_mob.real_name]</b>, has been infected.</span>")
|
||||
|
||||
if(!following_host)
|
||||
set_following(V.affected_mob)
|
||||
refresh_adaptation_menu()
|
||||
|
||||
/mob/camera/disease/proc/remove_infection(datum/disease/advance/sentient_disease/V)
|
||||
if(QDELETED(src))
|
||||
disease_instances -= V
|
||||
hosts -= V.affected_mob
|
||||
else
|
||||
points -= 1
|
||||
to_chat(src, "<span class='notice'>One of your hosts, <b>[V.affected_mob.real_name]</b>, has been purged of your infection.</span>")
|
||||
|
||||
var/datum/atom_hud/my_hud = GLOB.huds[DATA_HUD_SENTIENT_DISEASE]
|
||||
my_hud.remove_from_hud(V.affected_mob)
|
||||
|
||||
if(following_host == V.affected_mob)
|
||||
follow_next()
|
||||
|
||||
disease_instances -= V
|
||||
hosts -= V.affected_mob
|
||||
|
||||
if(!disease_instances.len)
|
||||
to_chat(src, "<span class='userdanger'>The last of your infection has disappeared.</span>")
|
||||
set_following(null)
|
||||
qdel(src)
|
||||
refresh_adaptation_menu()
|
||||
|
||||
/mob/camera/disease/proc/set_following(mob/living/L)
|
||||
following_host = L
|
||||
if(!move_listener)
|
||||
move_listener = L.AddComponent(/datum/component/redirect, COMSIG_MOVABLE_MOVED, CALLBACK(src, .proc/follow_mob))
|
||||
else
|
||||
L.TakeComponent(move_listener)
|
||||
if(QDELING(move_listener))
|
||||
move_listener = null
|
||||
follow_mob()
|
||||
|
||||
/mob/camera/disease/proc/follow_next(reverse = FALSE)
|
||||
var/index = hosts.Find(following_host)
|
||||
if(index)
|
||||
if(reverse)
|
||||
index = index == 1 ? hosts.len : index - 1
|
||||
else
|
||||
index = index == hosts.len ? 1 : index + 1
|
||||
set_following(hosts[index])
|
||||
|
||||
/mob/camera/disease/proc/follow_mob(newloc, dir)
|
||||
var/turf/T = get_turf(following_host)
|
||||
if(T)
|
||||
forceMove(T)
|
||||
|
||||
/mob/camera/disease/DblClickOn(var/atom/A, params)
|
||||
if(hosts[A])
|
||||
set_following(A)
|
||||
else
|
||||
..()
|
||||
|
||||
/mob/camera/disease/proc/adapt_cooldown()
|
||||
to_chat(src, "<span class='notice'>You have altered your genetic structure. You will be unable to adapt again for [adaptation_cooldown/10] seconds.</span>")
|
||||
next_adaptation_time = world.time + adaptation_cooldown
|
||||
addtimer(CALLBACK(src, .proc/notify_adapt_ready), adaptation_cooldown)
|
||||
|
||||
/mob/camera/disease/proc/notify_adapt_ready()
|
||||
to_chat(src, "<span class='notice'>You are now ready to adapt again.</span>")
|
||||
refresh_adaptation_menu()
|
||||
|
||||
/mob/camera/disease/proc/refresh_adaptation_menu()
|
||||
if(browser_open)
|
||||
adaptation_menu()
|
||||
|
||||
/mob/camera/disease/proc/adaptation_menu()
|
||||
var/datum/disease/advance/sentient_disease/DT = disease_template
|
||||
if(!DT)
|
||||
return
|
||||
var/list/dat = list()
|
||||
|
||||
if(examining_ability)
|
||||
dat += "<a href='byond://?src=[REF(src)];main_menu=1'>Back</a><br><h1>[examining_ability.name]</h1>[examining_ability.stat_block][examining_ability.long_desc][examining_ability.threshold_block]"
|
||||
else
|
||||
dat += "<h1>Disease Statistics</h1><br>\
|
||||
Resistance: [DT.totalResistance()]<br>\
|
||||
Stealth: [DT.totalStealth()]<br>\
|
||||
Stage Speed: [DT.totalStageSpeed()]<br>\
|
||||
Transmittability: [DT.totalTransmittable()]<hr>\
|
||||
Cure: [DT.cure_text]"
|
||||
dat += "<hr><h1>Adaptations</h1>\
|
||||
Points: [points] / [total_points]\
|
||||
<table border=1>\
|
||||
<tr><td>Cost</td><td></td><td>Unlock</td><td width='180px'>Name</td><td>Type</td><td>Description</td></tr>"
|
||||
for(var/V in GLOB.disease_ability_singletons)
|
||||
var/datum/disease_ability/A = V
|
||||
var/purchase_text
|
||||
if(unpurchased_abilities[A])
|
||||
if(A.CanBuy(src))
|
||||
purchase_text = "<a href='byond://?src=[REF(src)];buy_ability=[REF(A)]'>Purchase</a>"
|
||||
else
|
||||
purchase_text = "<span class='linkOff'>Purchase</span>"
|
||||
else
|
||||
if(A.CanRefund(src))
|
||||
purchase_text = "<a href='byond://?src=[REF(src)];refund_ability=[REF(A)]'>Refund</a>"
|
||||
else
|
||||
purchase_text = "<span class='linkOff'>Refund</span>"
|
||||
dat += "<tr><td>[A.cost]</td><td>[purchase_text]</td><td>[A.required_total_points]</td><td><a href='byond://?src=[REF(src)];examine_ability=[REF(A)]'>[A.name]</a></td><td>[A.category]</td><td>[A.short_desc]</td></tr>"
|
||||
|
||||
dat += "</table><br>Infect many hosts at once to gain adaptation points.<hr><h1>Infected Hosts</h1>"
|
||||
for(var/V in hosts)
|
||||
var/mob/living/L = V
|
||||
dat += "<br><a href='byond://?src=[REF(src)];follow_instance=[REF(L)]'>[L.real_name]</a>"
|
||||
|
||||
browser.set_content(dat.Join())
|
||||
browser.open()
|
||||
browser_open = TRUE
|
||||
|
||||
/mob/camera/disease/Topic(href, list/href_list)
|
||||
..()
|
||||
if(href_list["close"])
|
||||
browser_open = FALSE
|
||||
if(usr != src)
|
||||
return
|
||||
if(href_list["follow_instance"])
|
||||
var/mob/living/L = locate(href_list["follow_instance"]) in hosts
|
||||
set_following(L)
|
||||
|
||||
if(href_list["buy_ability"])
|
||||
var/datum/disease_ability/A = locate(href_list["buy_ability"])
|
||||
if(!istype(A))
|
||||
return
|
||||
if(A.CanBuy(src))
|
||||
A.Buy(src)
|
||||
adaptation_menu()
|
||||
|
||||
if(href_list["refund_ability"])
|
||||
var/datum/disease_ability/A = locate(href_list["refund_ability"])
|
||||
if(!istype(A))
|
||||
return
|
||||
if(A.CanRefund(src))
|
||||
A.Refund(src)
|
||||
adaptation_menu()
|
||||
|
||||
if(href_list["examine_ability"])
|
||||
var/datum/disease_ability/A = locate(href_list["examine_ability"])
|
||||
if(!istype(A))
|
||||
return
|
||||
examining_ability = A
|
||||
adaptation_menu()
|
||||
|
||||
if(href_list["main_menu"])
|
||||
examining_ability = null
|
||||
adaptation_menu()
|
||||
|
||||
|
||||
/datum/action/innate/disease_adapt
|
||||
name = "Adaptation Menu"
|
||||
icon_icon = 'icons/mob/actions/actions_minor_antag.dmi'
|
||||
button_icon_state = "disease_menu"
|
||||
|
||||
/datum/action/innate/disease_adapt/Activate()
|
||||
var/mob/camera/disease/D = owner
|
||||
D.adaptation_menu()
|
||||
@@ -40,11 +40,10 @@
|
||||
owner.special_role = null
|
||||
SSticker.mode.ape_infectees -= owner
|
||||
|
||||
var/datum/disease/transformation/jungle_fever/D = locate() in owner.current.viruses
|
||||
var/datum/disease/transformation/jungle_fever/D = locate() in owner.current.diseases
|
||||
if(D)
|
||||
D.remove_virus()
|
||||
qdel(D)
|
||||
|
||||
|
||||
. = ..()
|
||||
|
||||
/datum/antagonist/monkey/create_team(datum/team/monkey/new_team)
|
||||
|
||||
@@ -354,12 +354,12 @@
|
||||
if(H.dna && H.dna.species)
|
||||
H.dna.species.handle_hair(H,"#1d2953") //will be reset when blight is cured
|
||||
var/blightfound = FALSE
|
||||
for(var/datum/disease/revblight/blight in H.viruses)
|
||||
for(var/datum/disease/revblight/blight in H.diseases)
|
||||
blightfound = TRUE
|
||||
if(blight.stage < 5)
|
||||
blight.stage++
|
||||
if(!blightfound)
|
||||
H.AddDisease(new /datum/disease/revblight)
|
||||
H.ForceContractDisease(new /datum/disease/revblight(), FALSE, TRUE)
|
||||
to_chat(H, "<span class='revenminor'>You feel [pick("suddenly sick", "a surge of nausea", "like your skin is <i>wrong</i>")].</span>")
|
||||
else
|
||||
if(mob.reagents)
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
name = "Unnatural Wasting"
|
||||
max_stages = 5
|
||||
stage_prob = 10
|
||||
spread_flags = VIRUS_SPREAD_NON_CONTAGIOUS
|
||||
spread_flags = DISEASE_SPREAD_NON_CONTAGIOUS
|
||||
cure_text = "Holy water or extensive rest."
|
||||
spread_text = "A burst of unholy energy"
|
||||
cures = list("holywater")
|
||||
@@ -11,7 +11,7 @@
|
||||
viable_mobtypes = list(/mob/living/carbon/human)
|
||||
disease_flags = CURABLE
|
||||
permeability_mod = 1
|
||||
severity = VIRUS_SEVERITY_HARMFUL
|
||||
severity = DISEASE_SEVERITY_HARMFUL
|
||||
var/stagedamage = 0 //Highest stage reached.
|
||||
var/finalstage = 0 //Because we're spawning off the cure in the final stage, we need to check if we've done the final stage's effects.
|
||||
|
||||
|
||||
@@ -232,8 +232,8 @@
|
||||
explosion(loc,-1,0,2, flame_range = 2)
|
||||
if(9)
|
||||
//Cold
|
||||
var/datum/disease/D = new /datum/disease/cold
|
||||
user.ForceContractDisease(D)
|
||||
var/datum/disease/D = new /datum/disease/cold()
|
||||
user.ForceContractDisease(D, FALSE, TRUE)
|
||||
if(10)
|
||||
//Nothing
|
||||
visible_message("<span class='notice'>[src] roll perfectly.</span>")
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
if(H.has_trait(TRAIT_VIRUSIMMUNE)) //Don't pick someone who's virus immune, only for it to not do anything.
|
||||
continue
|
||||
var/foundAlready = FALSE // don't infect someone that already has a disease
|
||||
for(var/thing in H.viruses)
|
||||
for(var/thing in H.diseases)
|
||||
foundAlready = TRUE
|
||||
break
|
||||
if(foundAlready)
|
||||
@@ -63,7 +63,7 @@
|
||||
else
|
||||
D = make_virus(max_severity, max_severity)
|
||||
D.carrier = TRUE
|
||||
H.AddDisease(D)
|
||||
H.ForceContractDisease(D, FALSE, TRUE)
|
||||
|
||||
if(advanced_virus)
|
||||
var/datum/disease/advance/A = D
|
||||
@@ -75,10 +75,9 @@
|
||||
break
|
||||
|
||||
/datum/round_event/disease_outbreak/proc/make_virus(max_symptoms, max_level)
|
||||
if(max_symptoms > SYMPTOM_LIMIT)
|
||||
max_symptoms = SYMPTOM_LIMIT
|
||||
var/datum/disease/advance/A = new(FALSE, null)
|
||||
A.symptoms = list()
|
||||
if(max_symptoms > VIRUS_SYMPTOM_LIMIT)
|
||||
max_symptoms = VIRUS_SYMPTOM_LIMIT
|
||||
var/datum/disease/advance/A = new /datum/disease/advance()
|
||||
var/list/datum/symptom/possible_symptoms = list()
|
||||
for(var/symptom in subtypesof(/datum/symptom))
|
||||
var/datum/symptom/S = symptom
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
/datum/round_event/heart_attack/start()
|
||||
var/list/heart_attack_contestants = list()
|
||||
for(var/mob/living/carbon/human/H in shuffle(GLOB.player_list))
|
||||
if(!H.client || H.stat == DEAD || H.InCritical() || !H.can_heartattack() || H.has_status_effect(STATUS_EFFECT_EXERCISED) || (/datum/disease/heart_failure in H.viruses) || H.undergoing_cardiac_arrest())
|
||||
if(!H.client || H.stat == DEAD || H.InCritical() || !H.can_heartattack() || H.has_status_effect(STATUS_EFFECT_EXERCISED) || (/datum/disease/heart_failure in H.diseases) || H.undergoing_cardiac_arrest())
|
||||
continue
|
||||
if(H.satiety <= -60) //Multiple junk food items recently
|
||||
heart_attack_contestants[H] = 3
|
||||
@@ -17,6 +17,6 @@
|
||||
|
||||
if(LAZYLEN(heart_attack_contestants))
|
||||
var/mob/living/carbon/human/winner = pickweight(heart_attack_contestants)
|
||||
var/datum/disease/D = new /datum/disease/heart_failure
|
||||
winner.ForceContractDisease(D)
|
||||
notify_ghosts("[winner] is beginning to have a heart attack!", enter_link="<a href=?src=[REF(src)];orbit=1>(Click to orbit)</a>", source=winner, action=NOTIFY_ORBIT)
|
||||
var/datum/disease/D = new /datum/disease/heart_failure()
|
||||
winner.ForceContractDisease(D, FALSE, TRUE)
|
||||
notify_ghosts("[winner] is beginning to have a heart attack!", enter_link="<a href=?src=[REF(src)];orbit=1>(Click to orbit)</a>", source=winner, action=NOTIFY_ORBIT)
|
||||
|
||||
@@ -18,12 +18,12 @@
|
||||
if(!H.getorgan(/obj/item/organ/appendix)) //Don't give the disease to some who lacks it, only for it to be auto-cured
|
||||
continue
|
||||
var/foundAlready = FALSE //don't infect someone that already has appendicitis
|
||||
for(var/datum/disease/appendicitis/A in H.viruses)
|
||||
for(var/datum/disease/appendicitis/A in H.diseases)
|
||||
foundAlready = TRUE
|
||||
break
|
||||
if(foundAlready)
|
||||
continue
|
||||
|
||||
var/datum/disease/D = new /datum/disease/appendicitis
|
||||
H.ForceContractDisease(D)
|
||||
var/datum/disease/D = new /datum/disease/appendicitis()
|
||||
H.ForceContractDisease(D, FALSE, TRUE)
|
||||
break
|
||||
@@ -136,6 +136,10 @@
|
||||
languages = list(/datum/language/common)
|
||||
shadow_languages = list(/datum/language/common, /datum/language/machine, /datum/language/draconic)
|
||||
|
||||
/datum/language_holder/empty
|
||||
languages = list()
|
||||
shadow_languages = list()
|
||||
|
||||
/datum/language_holder/universal/New()
|
||||
..()
|
||||
grant_all_languages(omnitongue=TRUE)
|
||||
|
||||
@@ -789,7 +789,7 @@
|
||||
agent = "dragon's blood"
|
||||
desc = "What do dragons have to do with Space Station 13?"
|
||||
stage_prob = 20
|
||||
severity = VIRUS_SEVERITY_BIOHAZARD
|
||||
severity = DISEASE_SEVERITY_BIOHAZARD
|
||||
visibility_flags = 0
|
||||
stage1 = list("Your bones ache.")
|
||||
stage2 = list("Your skin feels scaly.")
|
||||
|
||||
@@ -9,10 +9,24 @@
|
||||
see_in_dark = 7
|
||||
invisibility = INVISIBILITY_ABSTRACT // No one can see us
|
||||
sight = SEE_SELF
|
||||
move_on_shuttle = 0
|
||||
move_on_shuttle = FALSE
|
||||
var/call_life = FALSE //TRUE if Life() should be called on this camera every tick of the mobs subystem, as if it were a living mob
|
||||
|
||||
/mob/camera/Initialize()
|
||||
. = ..()
|
||||
if(call_life)
|
||||
GLOB.living_cameras += src
|
||||
|
||||
/mob/camera/Destroy()
|
||||
. = ..()
|
||||
if(call_life)
|
||||
GLOB.living_cameras -= src
|
||||
|
||||
/mob/camera/experience_pressure_difference()
|
||||
return
|
||||
|
||||
/mob/camera/forceMove(atom/destination)
|
||||
loc = destination
|
||||
|
||||
/mob/camera/emote(act, m_type=1, message = null)
|
||||
return
|
||||
|
||||
@@ -140,7 +140,7 @@
|
||||
if(blood_data["viruses"])
|
||||
for(var/thing in blood_data["viruses"])
|
||||
var/datum/disease/D = thing
|
||||
if((D.spread_flags & VIRUS_SPREAD_SPECIAL) || (D.spread_flags & VIRUS_SPREAD_NON_CONTAGIOUS))
|
||||
if((D.spread_flags & DISEASE_SPREAD_SPECIAL) || (D.spread_flags & DISEASE_SPREAD_NON_CONTAGIOUS))
|
||||
continue
|
||||
C.ForceContractDisease(D)
|
||||
if(!(blood_data["blood_type"] in get_safe_blood(C.dna.blood_type)))
|
||||
@@ -164,13 +164,13 @@
|
||||
blood_data["donor"] = src
|
||||
blood_data["viruses"] = list()
|
||||
|
||||
for(var/thing in viruses)
|
||||
for(var/thing in diseases)
|
||||
var/datum/disease/D = thing
|
||||
blood_data["viruses"] += D.Copy()
|
||||
|
||||
blood_data["blood_DNA"] = copytext(dna.unique_enzymes,1,0)
|
||||
if(resistances && resistances.len)
|
||||
blood_data["resistances"] = resistances.Copy()
|
||||
if(disease_resistances && disease_resistances.len)
|
||||
blood_data["resistances"] = disease_resistances.Copy()
|
||||
var/list/temp_chem = list()
|
||||
for(var/datum/reagent/R in reagents.reagent_list)
|
||||
temp_chem[R.id] = R.volume
|
||||
|
||||
@@ -202,7 +202,6 @@
|
||||
return
|
||||
|
||||
if(!sterile)
|
||||
//target.contract_disease(new /datum/disease/alien_embryo(0)) //so infection chance is same as virus infection chance
|
||||
target.visible_message("<span class='danger'>[src] falls limp after violating [target]'s face!</span>", \
|
||||
"<span class='userdanger'>[src] falls limp after violating [target]'s face!</span>")
|
||||
|
||||
|
||||
@@ -754,9 +754,9 @@
|
||||
var/obj/item/organ/brain/B = getorgan(/obj/item/organ/brain)
|
||||
if(B)
|
||||
B.damaged_brain = FALSE
|
||||
for(var/thing in viruses)
|
||||
for(var/thing in diseases)
|
||||
var/datum/disease/D = thing
|
||||
if(D.severity != VIRUS_SEVERITY_POSITIVE)
|
||||
if(D.severity != DISEASE_SEVERITY_POSITIVE)
|
||||
D.cure(FALSE)
|
||||
if(admin_revive)
|
||||
regenerate_limbs()
|
||||
|
||||
@@ -110,14 +110,14 @@
|
||||
|
||||
/mob/living/carbon/attack_hand(mob/living/carbon/human/user)
|
||||
|
||||
for(var/thing in viruses)
|
||||
for(var/thing in diseases)
|
||||
var/datum/disease/D = thing
|
||||
if(D.spread_flags & VIRUS_SPREAD_CONTACT_SKIN)
|
||||
if(D.spread_flags & DISEASE_SPREAD_CONTACT_SKIN)
|
||||
user.ContactContractDisease(D)
|
||||
|
||||
for(var/thing in user.viruses)
|
||||
for(var/thing in user.diseases)
|
||||
var/datum/disease/D = thing
|
||||
if(D.spread_flags & VIRUS_SPREAD_CONTACT_SKIN)
|
||||
if(D.spread_flags & DISEASE_SPREAD_CONTACT_SKIN)
|
||||
ContactContractDisease(D)
|
||||
|
||||
if(lying && surgeries.len)
|
||||
@@ -131,14 +131,14 @@
|
||||
/mob/living/carbon/attack_paw(mob/living/carbon/monkey/M)
|
||||
|
||||
if(can_inject(M, TRUE))
|
||||
for(var/thing in viruses)
|
||||
for(var/thing in diseases)
|
||||
var/datum/disease/D = thing
|
||||
if((D.spread_flags & VIRUS_SPREAD_CONTACT_SKIN) && prob(85))
|
||||
if((D.spread_flags & DISEASE_SPREAD_CONTACT_SKIN) && prob(85))
|
||||
M.ContactContractDisease(D)
|
||||
|
||||
for(var/thing in M.viruses)
|
||||
for(var/thing in M.diseases)
|
||||
var/datum/disease/D = thing
|
||||
if(D.spread_flags & VIRUS_SPREAD_CONTACT_SKIN)
|
||||
if(D.spread_flags & DISEASE_SPREAD_CONTACT_SKIN)
|
||||
ContactContractDisease(D)
|
||||
|
||||
if(M.a_intent == INTENT_HELP)
|
||||
@@ -146,7 +146,7 @@
|
||||
return 0
|
||||
|
||||
if(..()) //successful monkey bite.
|
||||
for(var/thing in M.viruses)
|
||||
for(var/thing in M.diseases)
|
||||
var/datum/disease/D = thing
|
||||
ForceContractDisease(D)
|
||||
return 1
|
||||
|
||||
@@ -90,10 +90,10 @@
|
||||
stat("Radiation Levels:","[radiation] rad")
|
||||
stat("Body Temperature:","[bodytemperature-T0C] degrees C ([bodytemperature*1.8-459.67] degrees F)")
|
||||
|
||||
//Virsuses
|
||||
if(viruses.len)
|
||||
//Diseases
|
||||
if(diseases.len)
|
||||
stat("Viruses:", null)
|
||||
for(var/thing in viruses)
|
||||
for(var/thing in diseases)
|
||||
var/datum/disease/D = thing
|
||||
stat("*", "[D.name], Type: [D.spread_text], Stage: [D.stage]/[D.max_stages], Possible Cure: [D.cure_text]")
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/mob/living/carbon/human
|
||||
hud_possible = list(HEALTH_HUD,STATUS_HUD,ID_HUD,WANTED_HUD,IMPLOYAL_HUD,IMPCHEM_HUD,IMPTRACK_HUD,ANTAG_HUD,GLAND_HUD)
|
||||
hud_possible = list(HEALTH_HUD,STATUS_HUD,ID_HUD,WANTED_HUD,IMPLOYAL_HUD,IMPCHEM_HUD,IMPTRACK_HUD,ANTAG_HUD,GLAND_HUD,SENTIENT_DISEASE_HUD)
|
||||
possible_a_intents = list(INTENT_HELP, INTENT_DISARM, INTENT_GRAB, INTENT_HARM)
|
||||
pressure_resistance = 25
|
||||
can_buckle = TRUE
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
|
||||
/mob/living/carbon/human/treat_message(message)
|
||||
message = dna.species.handle_speech(message,src)
|
||||
if(viruses.len)
|
||||
for(var/datum/disease/pierrot_throat/D in viruses)
|
||||
if(diseases.len)
|
||||
for(var/datum/disease/pierrot_throat/D in diseases)
|
||||
var/list/temp_message = splittext(message, " ") //List each word in the message
|
||||
var/list/pick_list = list()
|
||||
for(var/i = 1, i <= temp_message.len, i++) //Create a second list for excluding words down the line
|
||||
|
||||
@@ -293,7 +293,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
|
||||
C.add_trait(X, SPECIES_TRAIT)
|
||||
|
||||
if(TRAIT_VIRUSIMMUNE in inherent_traits)
|
||||
for(var/datum/disease/A in C.viruses)
|
||||
for(var/datum/disease/A in C.diseases)
|
||||
A.cure(FALSE)
|
||||
|
||||
//CITADEL EDIT
|
||||
|
||||
@@ -251,7 +251,7 @@
|
||||
O.on_life()
|
||||
|
||||
/mob/living/carbon/handle_diseases()
|
||||
for(var/thing in viruses)
|
||||
for(var/thing in diseases)
|
||||
var/datum/disease/D = thing
|
||||
if(prob(D.infectivity))
|
||||
D.spread()
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
staticOverlays.len = 0
|
||||
remove_from_all_data_huds()
|
||||
GLOB.mob_living_list -= src
|
||||
|
||||
QDEL_LIST(diseases)
|
||||
return ..()
|
||||
|
||||
/mob/living/ghostize(can_reenter_corpse = 1)
|
||||
@@ -108,24 +108,24 @@
|
||||
/mob/living/proc/MobCollide(mob/M)
|
||||
//Even if we don't push/swap places, we "touched" them, so spread fire
|
||||
spreadFire(M)
|
||||
//Also diseases
|
||||
for(var/thing in viruses)
|
||||
var/datum/disease/D = thing
|
||||
if(D.spread_flags & VIRUS_SPREAD_CONTACT_SKIN)
|
||||
M.ContactContractDisease(D)
|
||||
|
||||
for(var/thing in M.viruses)
|
||||
var/datum/disease/D = thing
|
||||
if(D.spread_flags & VIRUS_SPREAD_CONTACT_SKIN)
|
||||
ContactContractDisease(D)
|
||||
|
||||
if(now_pushing)
|
||||
return TRUE
|
||||
|
||||
|
||||
//Should stop you pushing a restrained person out of the way
|
||||
if(isliving(M))
|
||||
var/mob/living/L = M
|
||||
//Also spread diseases
|
||||
for(var/thing in diseases)
|
||||
var/datum/disease/D = thing
|
||||
if(D.spread_flags & DISEASE_SPREAD_CONTACT_SKIN)
|
||||
L.ContactContractDisease(D)
|
||||
|
||||
for(var/thing in L.diseases)
|
||||
var/datum/disease/D = thing
|
||||
if(D.spread_flags & DISEASE_SPREAD_CONTACT_SKIN)
|
||||
ContactContractDisease(D)
|
||||
|
||||
//Should stop you pushing a restrained person out of the way
|
||||
if(L.pulledby && L.pulledby != src && L.restrained())
|
||||
if(!(world.time % 5))
|
||||
to_chat(src, "<span class='warning'>[L] is restrained, you cannot push past.</span>")
|
||||
@@ -224,6 +224,60 @@
|
||||
AM.setDir(current_dir)
|
||||
now_pushing = 0
|
||||
|
||||
/mob/living/start_pulling(atom/movable/AM, supress_message = 0)
|
||||
if(!AM || !src)
|
||||
return FALSE
|
||||
if(!(AM.can_be_pulled(src)))
|
||||
return FALSE
|
||||
if(throwing || incapacitated())
|
||||
return FALSE
|
||||
|
||||
AM.add_fingerprint(src)
|
||||
|
||||
// If we're pulling something then drop what we're currently pulling and pull this instead.
|
||||
if(pulling)
|
||||
// Are we trying to pull something we are already pulling? Then just stop here, no need to continue.
|
||||
if(AM == pulling)
|
||||
return
|
||||
stop_pulling()
|
||||
|
||||
changeNext_move(CLICK_CD_GRABBING)
|
||||
|
||||
if(AM.pulledby)
|
||||
if(!supress_message)
|
||||
visible_message("<span class='danger'>[src] has pulled [AM] from [AM.pulledby]'s grip.</span>")
|
||||
add_logs(AM, AM.pulledby, "pulled from", src)
|
||||
AM.pulledby.stop_pulling() //an object can't be pulled by two mobs at once.
|
||||
|
||||
pulling = AM
|
||||
AM.pulledby = src
|
||||
if(!supress_message)
|
||||
playsound(src.loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
|
||||
update_pull_hud_icon()
|
||||
|
||||
if(ismob(AM))
|
||||
var/mob/M = AM
|
||||
|
||||
add_logs(src, M, "grabbed", addition="passive grab")
|
||||
if(!supress_message)
|
||||
visible_message("<span class='warning'>[src] has grabbed [M] passively!</span>")
|
||||
if(!iscarbon(src))
|
||||
M.LAssailant = null
|
||||
else
|
||||
M.LAssailant = usr
|
||||
if(isliving(M))
|
||||
var/mob/living/L = M
|
||||
//Share diseases that are spread by touch
|
||||
for(var/thing in diseases)
|
||||
var/datum/disease/D = thing
|
||||
if(D.spread_flags & DISEASE_SPREAD_CONTACT_SKIN)
|
||||
L.ContactContractDisease(D)
|
||||
|
||||
for(var/thing in L.diseases)
|
||||
var/datum/disease/D = thing
|
||||
if(D.spread_flags & DISEASE_SPREAD_CONTACT_SKIN)
|
||||
ContactContractDisease(D)
|
||||
|
||||
//mob verbs are a lot faster than object verbs
|
||||
//for more info on why this is not atom/pull, see examinate() in mob.dm
|
||||
/mob/living/verb/pulled(atom/movable/AM as mob|obj in oview(1))
|
||||
@@ -235,6 +289,15 @@
|
||||
else
|
||||
stop_pulling()
|
||||
|
||||
/mob/living/stop_pulling()
|
||||
..()
|
||||
update_pull_hud_icon()
|
||||
|
||||
/mob/living/verb/stop_pulling1()
|
||||
set name = "Stop Pulling"
|
||||
set category = "IC"
|
||||
stop_pulling()
|
||||
|
||||
//same as above
|
||||
/mob/living/pointed(atom/A as mob|obj|turf in view())
|
||||
if(incapacitated())
|
||||
@@ -1074,3 +1137,54 @@
|
||||
return FALSE
|
||||
mob_pickup(user)
|
||||
return TRUE
|
||||
|
||||
/mob/living/proc/get_static_viruses() //used when creating blood and other infective objects
|
||||
if(!LAZYLEN(diseases))
|
||||
return
|
||||
var/list/datum/disease/result = list()
|
||||
for(var/datum/disease/D in diseases)
|
||||
var/static_virus = D.Copy()
|
||||
result += static_virus
|
||||
return result
|
||||
|
||||
/mob/living/reset_perspective(atom/A)
|
||||
if(..())
|
||||
update_sight()
|
||||
if(client.eye && client.eye != src)
|
||||
var/atom/AT = client.eye
|
||||
AT.get_remote_view_fullscreens(src)
|
||||
else
|
||||
clear_fullscreen("remote_view", 0)
|
||||
update_pipe_vision()
|
||||
|
||||
/mob/living/vv_edit_var(var_name, var_value)
|
||||
switch(var_name)
|
||||
if("stat")
|
||||
if((stat == DEAD) && (var_value < DEAD))//Bringing the dead back to life
|
||||
GLOB.dead_mob_list -= src
|
||||
GLOB.alive_mob_list += src
|
||||
if((stat < DEAD) && (var_value == DEAD))//Kill he
|
||||
GLOB.alive_mob_list -= src
|
||||
GLOB.dead_mob_list += src
|
||||
. = ..()
|
||||
switch(var_name)
|
||||
if("knockdown")
|
||||
SetKnockdown(var_value)
|
||||
if("stun")
|
||||
SetStun(var_value)
|
||||
if("unconscious")
|
||||
SetUnconscious(var_value)
|
||||
if("sleeping")
|
||||
SetSleeping(var_value)
|
||||
if("eye_blind")
|
||||
set_blindness(var_value)
|
||||
if("eye_damage")
|
||||
set_eye_damage(var_value)
|
||||
if("eye_blurry")
|
||||
set_blurriness(var_value)
|
||||
if("maxHealth")
|
||||
updatehealth()
|
||||
if("resize")
|
||||
update_transform()
|
||||
if("lighting_alpha")
|
||||
sync_lighting_plane_alpha()
|
||||
|
||||
@@ -107,3 +107,7 @@
|
||||
var/radiation = 0 //If the mob is irradiated.
|
||||
var/ventcrawl_layer = PIPING_LAYER_DEFAULT
|
||||
var/losebreath = 0
|
||||
|
||||
//List of active diseases
|
||||
var/list/diseases = list() // list of all diseases in a mob
|
||||
var/list/disease_resistances = list()
|
||||
|
||||
@@ -511,7 +511,7 @@
|
||||
Structural Integrity: [M.getBruteLoss() > 50 ? "<font color=#FF5555>" : "<font color=#55FF55>"][M.getBruteLoss()]</font><br>
|
||||
Body Temperature: [M.bodytemperature-T0C]°C ([M.bodytemperature*1.8-459.67]°F)<br>
|
||||
"}
|
||||
for(var/thing in M.viruses)
|
||||
for(var/thing in M.diseases)
|
||||
var/datum/disease/D = thing
|
||||
dat += {"<h4>Infection Detected.</h4><br>
|
||||
Name: [D.name]<br>
|
||||
|
||||
@@ -383,12 +383,12 @@
|
||||
return TRUE
|
||||
|
||||
if(treat_virus && !C.reagents.has_reagent(treatment_virus_avoid) && !C.reagents.has_reagent(treatment_virus))
|
||||
for(var/thing in C.viruses)
|
||||
for(var/thing in C.diseases)
|
||||
var/datum/disease/D = thing
|
||||
//the medibot can't detect viruses that are undetectable to Health Analyzers or Pandemic machines.
|
||||
if(!(D.visibility_flags & HIDDEN_SCANNER || D.visibility_flags & HIDDEN_PANDEMIC) \
|
||||
&& D.severity != VIRUS_SEVERITY_POSITIVE \
|
||||
&& (D.stage > 1 || (D.spread_flags & VIRUS_SPREAD_AIRBORNE))) // medibot can't detect a virus in its initial stage unless it spreads airborne.
|
||||
&& D.severity != DISEASE_SEVERITY_POSITIVE \
|
||||
&& (D.stage > 1 || (D.spread_flags & DISEASE_SPREAD_AIRBORNE))) // medibot can't detect a virus in its initial stage unless it spreads airborne.
|
||||
return TRUE //STOP DISEASE FOREVER
|
||||
|
||||
return FALSE
|
||||
@@ -435,12 +435,12 @@
|
||||
else
|
||||
if(treat_virus)
|
||||
var/virus = 0
|
||||
for(var/thing in C.viruses)
|
||||
for(var/thing in C.diseases)
|
||||
var/datum/disease/D = thing
|
||||
//detectable virus
|
||||
if((!(D.visibility_flags & HIDDEN_SCANNER)) || (!(D.visibility_flags & HIDDEN_PANDEMIC)))
|
||||
if(D.severity != VIRUS_SEVERITY_POSITIVE) //virus is harmful
|
||||
if((D.stage > 1) || (D.spread_flags & VIRUS_SPREAD_AIRBORNE))
|
||||
if(D.severity != DISEASE_SEVERITY_POSITIVE) //virus is harmful
|
||||
if((D.stage > 1) || (D.spread_flags & DISEASE_SPREAD_AIRBORNE))
|
||||
virus = 1
|
||||
|
||||
if(!reagent_id && (virus))
|
||||
|
||||
@@ -11,7 +11,6 @@
|
||||
var/mob/dead/observe = M
|
||||
observe.reset_perspective(null)
|
||||
qdel(hud_used)
|
||||
QDEL_LIST(viruses)
|
||||
for(var/cc in client_colours)
|
||||
qdel(cc)
|
||||
client_colours = null
|
||||
@@ -287,16 +286,6 @@
|
||||
client.eye = loc
|
||||
return 1
|
||||
|
||||
/mob/living/reset_perspective(atom/A)
|
||||
if(..())
|
||||
update_sight()
|
||||
if(client.eye && client.eye != src)
|
||||
var/atom/AT = client.eye
|
||||
AT.get_remote_view_fullscreens(src)
|
||||
else
|
||||
clear_fullscreen("remote_view", 0)
|
||||
update_pipe_vision()
|
||||
|
||||
/mob/proc/show_inv(mob/user)
|
||||
return
|
||||
|
||||
@@ -333,60 +322,6 @@
|
||||
|
||||
return 1
|
||||
|
||||
//this and stop_pulling really ought to be /mob/living procs
|
||||
/mob/start_pulling(atom/movable/AM, supress_message = 0)
|
||||
if(!AM || !src)
|
||||
return FALSE
|
||||
if(!(AM.can_be_pulled(src)))
|
||||
return FALSE
|
||||
if(throwing || incapacitated())
|
||||
return FALSE
|
||||
|
||||
AM.add_fingerprint(src)
|
||||
|
||||
// If we're pulling something then drop what we're currently pulling and pull this instead.
|
||||
if(pulling)
|
||||
// Are we trying to pull something we are already pulling? Then just stop here, no need to continue.
|
||||
if(AM == pulling)
|
||||
return
|
||||
stop_pulling()
|
||||
|
||||
changeNext_move(CLICK_CD_GRABBING)
|
||||
|
||||
if(AM.pulledby)
|
||||
if(!supress_message)
|
||||
visible_message("<span class='danger'>[src] has pulled [AM] from [AM.pulledby]'s grip.</span>")
|
||||
add_logs(AM, AM.pulledby, "pulled from", src)
|
||||
AM.pulledby.stop_pulling() //an object can't be pulled by two mobs at once.
|
||||
|
||||
pulling = AM
|
||||
AM.pulledby = src
|
||||
if(!supress_message)
|
||||
playsound(src.loc, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
|
||||
update_pull_hud_icon()
|
||||
|
||||
if(ismob(AM))
|
||||
var/mob/M = AM
|
||||
|
||||
//Share diseases that are spread by touch
|
||||
for(var/thing in viruses)
|
||||
var/datum/disease/D = thing
|
||||
if(D.spread_flags & VIRUS_SPREAD_CONTACT_SKIN)
|
||||
M.ContactContractDisease(D)
|
||||
|
||||
for(var/thing in M.viruses)
|
||||
var/datum/disease/D = thing
|
||||
if(D.spread_flags & VIRUS_SPREAD_CONTACT_SKIN)
|
||||
ContactContractDisease(D)
|
||||
|
||||
add_logs(src, M, "grabbed", addition="passive grab")
|
||||
if(!supress_message)
|
||||
visible_message("<span class='warning'>[src] has grabbed [M][(zone_selected == "l_arm" || zone_selected == "r_arm")? " by their hands":" passively"]!</span>")
|
||||
if(!iscarbon(src))
|
||||
M.LAssailant = null
|
||||
else
|
||||
M.LAssailant = usr
|
||||
|
||||
/mob/proc/can_resist()
|
||||
return FALSE //overridden in living.dm
|
||||
|
||||
@@ -409,15 +344,6 @@
|
||||
setDir(D)
|
||||
spintime -= speed
|
||||
|
||||
/mob/stop_pulling()
|
||||
..()
|
||||
update_pull_hud_icon()
|
||||
|
||||
/mob/verb/stop_pulling1()
|
||||
set name = "Stop Pulling"
|
||||
set category = "IC"
|
||||
stop_pulling()
|
||||
|
||||
/mob/proc/update_pull_hud_icon()
|
||||
if(hud_used)
|
||||
if(hud_used.pull_icon)
|
||||
@@ -927,39 +853,6 @@
|
||||
if (L)
|
||||
L.alpha = lighting_alpha
|
||||
|
||||
/mob/living/vv_edit_var(var_name, var_value)
|
||||
switch(var_name)
|
||||
if("stat")
|
||||
if((stat == DEAD) && (var_value < DEAD))//Bringing the dead back to life
|
||||
GLOB.dead_mob_list -= src
|
||||
GLOB.alive_mob_list += src
|
||||
if((stat < DEAD) && (var_value == DEAD))//Kill he
|
||||
GLOB.alive_mob_list -= src
|
||||
GLOB.dead_mob_list += src
|
||||
. = ..()
|
||||
switch(var_name)
|
||||
if("knockdown")
|
||||
SetKnockdown(var_value)
|
||||
if("stun")
|
||||
SetStun(var_value)
|
||||
if("unconscious")
|
||||
SetUnconscious(var_value)
|
||||
if("sleeping")
|
||||
SetSleeping(var_value)
|
||||
if("eye_blind")
|
||||
set_blindness(var_value)
|
||||
if("eye_damage")
|
||||
set_eye_damage(var_value)
|
||||
if("eye_blurry")
|
||||
set_blurriness(var_value)
|
||||
if("maxHealth")
|
||||
updatehealth()
|
||||
if("resize")
|
||||
update_transform()
|
||||
if("lighting_alpha")
|
||||
sync_lighting_plane_alpha()
|
||||
|
||||
|
||||
/mob/proc/is_literate()
|
||||
return 0
|
||||
|
||||
@@ -969,15 +862,6 @@
|
||||
/mob/proc/get_idcard()
|
||||
return
|
||||
|
||||
/mob/proc/get_static_viruses() //used when creating blood and other infective objects
|
||||
if(!LAZYLEN(viruses))
|
||||
return
|
||||
var/list/datum/disease/diseases = list()
|
||||
for(var/datum/disease/D in viruses)
|
||||
var/static_virus = D.Copy()
|
||||
diseases += static_virus
|
||||
return diseases
|
||||
|
||||
|
||||
/mob/vv_get_dropdown()
|
||||
. = ..()
|
||||
|
||||
@@ -82,10 +82,6 @@
|
||||
|
||||
var/list/mob_spell_list = list() //construct spells and mime spells. Spells that do not transfer from one mob to another and can not be lost in mindswap.
|
||||
|
||||
//List of active diseases
|
||||
|
||||
var/list/viruses = list() // list of all diseases in a mob
|
||||
var/list/resistances = list()
|
||||
|
||||
var/status_flags = CANSTUN|CANKNOCKDOWN|CANUNCONSCIOUS|CANPUSH //bitflags defining which status effects can be inflicted (replaces canknockdown, canstun, etc)
|
||||
|
||||
|
||||
@@ -363,8 +363,10 @@ It's fairly easy to fix if dealing with single letters but not so much with comp
|
||||
if(M.mind in SSticker.mode.apprentices)
|
||||
return 2
|
||||
if("monkey")
|
||||
if(M.viruses && (locate(/datum/disease/transformation/jungle_fever) in M.viruses))
|
||||
return 2
|
||||
if(isliving(M))
|
||||
var/mob/living/L = M
|
||||
if(L.diseases && (locate(/datum/disease/transformation/jungle_fever) in L.diseases))
|
||||
return 2
|
||||
return TRUE
|
||||
if(M.mind && LAZYLEN(M.mind.antag_datums)) //they have an antag datum!
|
||||
return TRUE
|
||||
|
||||
@@ -62,9 +62,9 @@
|
||||
|
||||
//keep viruses?
|
||||
if (tr_flags & TR_KEEPVIRUS)
|
||||
O.viruses = viruses
|
||||
viruses = list()
|
||||
for(var/thing in O.viruses)
|
||||
O.diseases = diseases
|
||||
diseases = list()
|
||||
for(var/thing in O.diseases)
|
||||
var/datum/disease/D = thing
|
||||
D.affected_mob = O
|
||||
|
||||
@@ -218,9 +218,9 @@
|
||||
|
||||
//keep viruses?
|
||||
if (tr_flags & TR_KEEPVIRUS)
|
||||
O.viruses = viruses
|
||||
viruses = list()
|
||||
for(var/thing in O.viruses)
|
||||
O.diseases = diseases
|
||||
diseases = list()
|
||||
for(var/thing in O.diseases)
|
||||
var/datum/disease/D = thing
|
||||
D.affected_mob = O
|
||||
O.med_hud_set_status()
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
if(istype(D, /datum/disease/advance))
|
||||
var/datum/disease/advance/A = D
|
||||
var/disease_name = SSdisease.get_disease_name(A.GetDiseaseID())
|
||||
if(disease_name == "Unknown")
|
||||
if(disease_name == "Unknown" && A.mutable)
|
||||
this["can_rename"] = TRUE
|
||||
this["name"] = disease_name
|
||||
this["is_adv"] = TRUE
|
||||
@@ -180,17 +180,21 @@
|
||||
if("rename_disease")
|
||||
var/id = get_virus_id_by_index(text2num(params["index"]))
|
||||
var/datum/disease/advance/A = SSdisease.archive_diseases[id]
|
||||
if(!A.mutable)
|
||||
return
|
||||
if(A)
|
||||
var/new_name = stripped_input(usr, "Name the disease", "New name", "", MAX_NAME_LEN)
|
||||
if(!new_name || ..())
|
||||
return
|
||||
A.AssignName(new_name)
|
||||
for(var/datum/disease/advance/AD in SSdisease.active_diseases)
|
||||
AD.Refresh()
|
||||
. = TRUE
|
||||
if("create_culture_bottle")
|
||||
var/id = get_virus_id_by_index(text2num(params["index"]))
|
||||
var/datum/disease/advance/A = new(FALSE, SSdisease.archive_diseases[id])
|
||||
var/datum/disease/advance/A = SSdisease.archive_diseases[id]
|
||||
if(!A.mutable)
|
||||
to_chat(usr, "<span class='warning'>ERROR: Cannot replicate virus strain.</span>")
|
||||
return
|
||||
A = A.Copy()
|
||||
var/list/data = list("viruses" = list(A))
|
||||
var/obj/item/reagent_containers/glass/bottle/B = new(drop_location())
|
||||
B.name = "[A.name] culture bottle"
|
||||
|
||||
@@ -60,9 +60,9 @@
|
||||
M.SetSleeping(0, 0)
|
||||
M.jitteriness = 0
|
||||
M.cure_all_traumas(TRUE, TRAUMA_RESILIENCE_MAGIC)
|
||||
for(var/thing in M.viruses)
|
||||
for(var/thing in M.diseases)
|
||||
var/datum/disease/D = thing
|
||||
if(D.severity == VIRUS_SEVERITY_POSITIVE)
|
||||
if(D.severity == DISEASE_SEVERITY_POSITIVE)
|
||||
continue
|
||||
D.cure()
|
||||
..()
|
||||
|
||||
@@ -16,13 +16,15 @@
|
||||
for(var/thing in data["viruses"])
|
||||
var/datum/disease/D = thing
|
||||
|
||||
if((D.spread_flags & VIRUS_SPREAD_SPECIAL) || (D.spread_flags & VIRUS_SPREAD_NON_CONTAGIOUS))
|
||||
if((D.spread_flags & DISEASE_SPREAD_SPECIAL) || (D.spread_flags & DISEASE_SPREAD_NON_CONTAGIOUS))
|
||||
continue
|
||||
|
||||
if((method == TOUCH || method == VAPOR) && (D.spread_flags & VIRUS_SPREAD_CONTACT_FLUIDS))
|
||||
M.ContactContractDisease(D)
|
||||
else //ingest, patch or inject
|
||||
M.ForceContractDisease(D)
|
||||
if(isliving(M))
|
||||
var/mob/living/L = M
|
||||
if((method == TOUCH || method == VAPOR) && (D.spread_flags & DISEASE_SPREAD_CONTACT_FLUIDS))
|
||||
L.ContactContractDisease(D)
|
||||
else //ingest, patch or inject
|
||||
L.ForceContractDisease(D)
|
||||
|
||||
if(iscarbon(M))
|
||||
var/mob/living/carbon/C = M
|
||||
@@ -97,12 +99,15 @@
|
||||
taste_description = "slime"
|
||||
|
||||
/datum/reagent/vaccine/reaction_mob(mob/M, method=TOUCH, reac_volume)
|
||||
if(!isliving(M))
|
||||
return
|
||||
var/mob/living/L = M
|
||||
if(islist(data) && (method == INGEST || method == INJECT))
|
||||
for(var/thing in M.viruses)
|
||||
for(var/thing in L.diseases)
|
||||
var/datum/disease/D = thing
|
||||
if(D.GetDiseaseID() in data)
|
||||
D.cure()
|
||||
M.resistances |= data
|
||||
L.disease_resistances |= data
|
||||
|
||||
/datum/reagent/vaccine/on_merge(list/data)
|
||||
if(istype(data))
|
||||
@@ -623,8 +628,11 @@
|
||||
taste_description = "slime"
|
||||
|
||||
/datum/reagent/aslimetoxin/reaction_mob(mob/M, method=TOUCH, reac_volume)
|
||||
if(!isliving(M))
|
||||
return
|
||||
var/mob/living/L = M
|
||||
if(method != TOUCH)
|
||||
M.ForceContractDisease(new /datum/disease/transformation/slime(0))
|
||||
L.ForceContractDisease(new /datum/disease/transformation/slime(), FALSE, TRUE)
|
||||
|
||||
/datum/reagent/gluttonytoxin
|
||||
name = "Gluttony's Blessing"
|
||||
@@ -635,7 +643,10 @@
|
||||
taste_description = "decay"
|
||||
|
||||
/datum/reagent/gluttonytoxin/reaction_mob(mob/M, method=TOUCH, reac_volume)
|
||||
M.ForceContractDisease(new /datum/disease/transformation/morph(0))
|
||||
if(!isliving(M))
|
||||
return
|
||||
var/mob/living/L = M
|
||||
L.ForceContractDisease(new /datum/disease/transformation/morph(), FALSE, TRUE)
|
||||
|
||||
/datum/reagent/serotrotium
|
||||
name = "Serotrotium"
|
||||
@@ -1103,8 +1114,11 @@
|
||||
taste_description = "sludge"
|
||||
|
||||
/datum/reagent/nanites/reaction_mob(mob/M, method=TOUCH, reac_volume, show_message = 1, touch_protection = 0)
|
||||
if(!isliving(M))
|
||||
return
|
||||
var/mob/living/L = M
|
||||
if(method==PATCH || method==INGEST || method==INJECT || (method == VAPOR && prob(min(reac_volume,100)*(1 - touch_protection))))
|
||||
M.ForceContractDisease(new /datum/disease/transformation/robot(0))
|
||||
L.ForceContractDisease(new /datum/disease/transformation/robot(), FALSE, TRUE)
|
||||
|
||||
/datum/reagent/xenomicrobes
|
||||
name = "Xenomicrobes"
|
||||
@@ -1115,8 +1129,11 @@
|
||||
taste_description = "sludge"
|
||||
|
||||
/datum/reagent/xenomicrobes/reaction_mob(mob/M, method=TOUCH, reac_volume, show_message = 1, touch_protection = 0)
|
||||
if(!isliving(M))
|
||||
return
|
||||
var/mob/living/L = M
|
||||
if(method==PATCH || method==INGEST || method==INJECT || (method == VAPOR && prob(min(reac_volume,100)*(1 - touch_protection))))
|
||||
M.ForceContractDisease(new /datum/disease/transformation/xeno(0))
|
||||
L.ForceContractDisease(new /datum/disease/transformation/xeno(), FALSE, TRUE)
|
||||
|
||||
/datum/reagent/fungalspores
|
||||
name = "Tubercle bacillus Cosmosis microbes"
|
||||
@@ -1127,8 +1144,11 @@
|
||||
taste_description = "slime"
|
||||
|
||||
/datum/reagent/fungalspores/reaction_mob(mob/M, method=TOUCH, reac_volume, show_message = 1, touch_protection = 0)
|
||||
if(!isliving(M))
|
||||
return
|
||||
var/mob/living/L = M
|
||||
if(method==PATCH || method==INGEST || method==INJECT || (method == VAPOR && prob(min(reac_volume,100)*(1 - touch_protection))))
|
||||
M.ForceContractDisease(new /datum/disease/tuberculosis(0))
|
||||
L.ForceContractDisease(new /datum/disease/tuberculosis(), FALSE, TRUE)
|
||||
|
||||
/datum/reagent/fluorosurfactant//foam precursor
|
||||
name = "Fluorosurfactant"
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
volume = vol
|
||||
create_reagents(volume)
|
||||
if(spawned_disease)
|
||||
var/datum/disease/F = new spawned_disease(0)
|
||||
var/datum/disease/F = new spawned_disease()
|
||||
var/list/data = list("viruses"= list(F))
|
||||
reagents.add_reagent("blood", disease_amount, data)
|
||||
|
||||
|
||||
@@ -350,7 +350,7 @@
|
||||
switch(activation_type)
|
||||
if(SLIME_ACTIVATE_MINOR)
|
||||
to_chat(user, "<span class='userdanger'>You feel something <i>wrong</i> inside you...</span>")
|
||||
user.ForceContractDisease(new /datum/disease/transformation/slime(0))
|
||||
user.ForceContractDisease(new /datum/disease/transformation/slime(), FALSE, TRUE)
|
||||
return 100
|
||||
|
||||
if(SLIME_ACTIVATE_MAJOR)
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
/datum/surgery/advanced/viral_bonding/can_start(mob/user, mob/living/carbon/target)
|
||||
if(!..())
|
||||
return FALSE
|
||||
if(!LAZYLEN(target.viruses))
|
||||
if(!LAZYLEN(target.diseases))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
@@ -38,7 +38,7 @@
|
||||
|
||||
/datum/surgery_step/viral_bond/success(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
|
||||
user.visible_message("[target]'s bone marrow begins pulsing slowly.", "<span class='notice'>[target]'s bone marrow begins pulsing slowly. The viral bonding is complete.</span>")
|
||||
for(var/X in target.viruses)
|
||||
for(var/X in target.diseases)
|
||||
var/datum/disease/D = X
|
||||
D.carrier = TRUE
|
||||
return TRUE
|
||||
@@ -14,7 +14,7 @@
|
||||
name = "appendix"
|
||||
|
||||
/obj/item/organ/appendix/Remove(mob/living/carbon/M, special = 0)
|
||||
for(var/datum/disease/appendicitis/A in M.viruses)
|
||||
for(var/datum/disease/appendicitis/A in M.diseases)
|
||||
A.cure()
|
||||
inflamed = 1
|
||||
update_icon()
|
||||
@@ -23,7 +23,7 @@
|
||||
/obj/item/organ/appendix/Insert(mob/living/carbon/M, special = 0)
|
||||
..()
|
||||
if(inflamed)
|
||||
M.AddDisease(new /datum/disease/appendicitis)
|
||||
M.ForceContractDisease(new /datum/disease/appendicitis(), FALSE, TRUE)
|
||||
|
||||
/obj/item/organ/appendix/prepare_eat()
|
||||
var/obj/S = ..()
|
||||
|
||||
Reference in New Issue
Block a user