Merge branch 'master' into Filet-o-fish
This commit is contained in:
@@ -42,9 +42,6 @@ GLOBAL_PROTECT(admin_ranks)
|
||||
/datum/admin_rank/vv_edit_var(var_name, var_value)
|
||||
return FALSE
|
||||
|
||||
#if DM_VERSION > 512
|
||||
#error remove the rejuv keyword from this proc
|
||||
#endif
|
||||
/proc/admin_keyword_to_flag(word, previous_rights=0)
|
||||
var/flag = 0
|
||||
switch(ckey(word))
|
||||
@@ -80,9 +77,6 @@ GLOBAL_PROTECT(admin_ranks)
|
||||
flag = R_AUTOLOGIN
|
||||
if("@","prev")
|
||||
flag = previous_rights
|
||||
if("rejuv","rejuvinate")
|
||||
stack_trace("Legacy keyword rejuvinate used defaulting to R_ADMIN")
|
||||
flag = R_ADMIN
|
||||
return flag
|
||||
|
||||
/proc/admin_keyword_to_path(word) //use this with verb keywords eg +/client/proc/blah
|
||||
|
||||
@@ -100,7 +100,7 @@ GLOBAL_LIST_INIT(admin_verbs_fun, list(
|
||||
/client/proc/smite
|
||||
))
|
||||
GLOBAL_PROTECT(admin_verbs_spawn)
|
||||
GLOBAL_LIST_INIT(admin_verbs_spawn, list(/datum/admins/proc/spawn_atom, /datum/admins/proc/spawn_cargo, /client/proc/respawn_character))
|
||||
GLOBAL_LIST_INIT(admin_verbs_spawn, list(/datum/admins/proc/spawn_atom, /datum/admins/proc/spawn_cargo, /datum/admins/proc/spawn_objasmob, /client/proc/respawn_character))
|
||||
GLOBAL_PROTECT(admin_verbs_server)
|
||||
GLOBAL_LIST_INIT(admin_verbs_server, world.AVerbsServer())
|
||||
/world/proc/AVerbsServer()
|
||||
@@ -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>")
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
/datum/admins/proc/spawn_objasmob(object as text)
|
||||
set category = "Debug"
|
||||
set desc = "(obj path) Spawn object-mob"
|
||||
set name = "Spawn object-mob"
|
||||
|
||||
if(!check_rights(R_SPAWN))
|
||||
return
|
||||
|
||||
var/chosen = pick_closest_path(object, make_types_fancy(subtypesof(/obj)))
|
||||
|
||||
if (!chosen)
|
||||
return
|
||||
|
||||
var/mob/living/simple_animal/hostile/mimic/copy/basemob = /mob/living/simple_animal/hostile/mimic/copy
|
||||
|
||||
var/obj/chosen_obj = text2path(chosen)
|
||||
|
||||
var/list/settings = list(
|
||||
"mainsettings" = list(
|
||||
"name" = list("desc" = "Name", "type" = "string", "value" = "Bob"),
|
||||
"maxhealth" = list("desc" = "Max. health", "type" = "number", "value" = 100),
|
||||
"access" = list("desc" = "Access ID", "type" = "datum", "path" = "/obj/item/card/id", "value" = "Default"),
|
||||
"objtype" = list("desc" = "Base obj type", "type" = "datum", "path" = "/obj", "value" = "[chosen]"),
|
||||
"googlyeyes" = list("desc" = "Googly eyes", "type" = "boolean", "value" = "No"),
|
||||
"disableai" = list("desc" = "Disable AI", "type" = "boolean", "value" = "Yes"),
|
||||
"idledamage" = list("desc" = "Damaged while idle", "type" = "boolean", "value" = "No"),
|
||||
"dropitem" = list("desc" = "Drop obj on death", "type" = "boolean", "value" = "Yes"),
|
||||
"mobtype" = list("desc" = "Base mob type", "type" = "datum", "path" = "/mob/living/simple_animal/hostile/mimic/copy", "value" = "/mob/living/simple_animal/hostile/mimic/copy"),
|
||||
"ckey" = list("desc" = "ckey", "type" = "ckey", "value" = "none"),
|
||||
)
|
||||
)
|
||||
|
||||
var/list/prefreturn = presentpreflikepicker(usr,"Customize mob", "Customize mob", Button1="Ok", width = 450, StealFocus = 1,Timeout = 0, settings=settings)
|
||||
if (prefreturn["button"] == 1)
|
||||
settings = prefreturn["settings"]
|
||||
var/mainsettings = settings["mainsettings"]
|
||||
chosen_obj = text2path(mainsettings["objtype"]["value"])
|
||||
|
||||
basemob = text2path(mainsettings["mobtype"]["value"])
|
||||
if (!ispath(basemob, /mob/living/simple_animal/hostile/mimic/copy) || !ispath(chosen_obj, /obj))
|
||||
to_chat(usr, "Mob or object path invalid")
|
||||
|
||||
basemob = new basemob(get_turf(usr), new chosen_obj(get_turf(usr)), usr, mainsettings["dropitem"]["value"] == "Yes" ? FALSE : TRUE, (mainsettings["googlyeyes"]["value"] == "Yes" ? FALSE : TRUE))
|
||||
|
||||
if (mainsettings["disableai"]["value"] == "Yes")
|
||||
basemob.toggle_ai(AI_OFF)
|
||||
|
||||
if (mainsettings["idledamage"]["value"] == "No")
|
||||
basemob.idledamage = FALSE
|
||||
|
||||
if (mainsettings["access"])
|
||||
var/newaccess = text2path(mainsettings["access"]["value"])
|
||||
if (ispath(newaccess))
|
||||
basemob.access_card = new newaccess
|
||||
|
||||
if (mainsettings["maxhealth"]["value"])
|
||||
if (!isnum(mainsettings["maxhealth"]["value"]))
|
||||
mainsettings["maxhealth"]["value"] = text2num(mainsettings["maxhealth"]["value"])
|
||||
if (mainsettings["maxhealth"]["value"] > 0)
|
||||
basemob.maxHealth = basemob.maxHealth = mainsettings["maxhealth"]["value"]
|
||||
|
||||
if (mainsettings["name"]["value"])
|
||||
basemob.name = basemob.real_name = html_decode(mainsettings["name"]["value"])
|
||||
|
||||
if (mainsettings["ckey"]["value"] != "none")
|
||||
basemob.ckey = mainsettings["ckey"]["value"]
|
||||
|
||||
|
||||
log_admin("[key_name(usr)] spawned a sentient object-mob [basemob] from [chosen_obj] at ([usr.x],[usr.y],[usr.z])")
|
||||
SSblackbox.record_feedback("tally", "admin_verb", 1, "Spawn object-mob") //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
@@ -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
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
// Contains cult communion, guide, and cult master abilities
|
||||
#define MARK_COOLDOWN
|
||||
|
||||
/datum/action/innate/cult
|
||||
icon_icon = 'icons/mob/actions/actions_cult.dmi'
|
||||
|
||||
@@ -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()
|
||||
@@ -5,16 +5,12 @@
|
||||
show_name_in_check_antagonists = TRUE
|
||||
|
||||
/datum/antagonist/highlander/apply_innate_effects(mob/living/mob_override)
|
||||
var/mob/living/carbon/human/H = owner.current || mob_override
|
||||
if(!istype(H))
|
||||
return
|
||||
H.dna.species.species_traits |= NOGUNS //nice try jackass
|
||||
var/mob/living/L = owner.current || mob_override
|
||||
L.add_trait(TRAIT_NOGUNS, "highlander")
|
||||
|
||||
/datum/antagonist/highlander/remove_innate_effects(mob/living/mob_override)
|
||||
var/mob/living/carbon/human/H = owner.current || mob_override
|
||||
if(!istype(H))
|
||||
return
|
||||
H.dna.species.species_traits &= ~NOGUNS
|
||||
var/mob/living/L = owner.current || mob_override
|
||||
L.remove_trait(TRAIT_NOGUNS, "highlander")
|
||||
|
||||
/datum/antagonist/highlander/on_removal()
|
||||
owner.objectives -= objectives
|
||||
@@ -76,7 +72,7 @@
|
||||
sword.admin_spawned = TRUE //To prevent announcing
|
||||
sword.pickup(H) //For the stun shielding
|
||||
H.put_in_hands(sword)
|
||||
|
||||
|
||||
|
||||
var/obj/item/bloodcrawl/antiwelder = new(H)
|
||||
antiwelder.name = "compulsion of honor"
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
var/obj/item/bodypart/affecting = null
|
||||
if(ishuman(target))
|
||||
var/mob/living/carbon/human/H = target
|
||||
if(PIERCEIMMUNE in H.dna.species.species_traits)
|
||||
if(H.has_trait(TRAIT_PIERCEIMMUNE))
|
||||
playsound(src.loc, 'sound/effects/snap.ogg', 50, 1)
|
||||
armed = 0
|
||||
update_icon()
|
||||
|
||||
@@ -1,36 +0,0 @@
|
||||
/obj/machinery/zvent
|
||||
name = "interfloor air transfer system"
|
||||
|
||||
icon = 'icons/obj/atmospherics/components/unary_devices.dmi'
|
||||
icon_state = "vent_map"
|
||||
density = FALSE
|
||||
anchored=1
|
||||
desc = "This may be needed some day."
|
||||
|
||||
var/on = FALSE
|
||||
var/volume_rate = 800
|
||||
|
||||
/obj/machinery/zvent/New()
|
||||
..()
|
||||
SSair.atmos_machinery += src
|
||||
|
||||
/obj/machinery/zvent/Destroy()
|
||||
SSair.atmos_machinery -= src
|
||||
return ..()
|
||||
|
||||
/obj/machinery/zvent/process_atmos()
|
||||
|
||||
//all this object does, is make its turf share air with the ones above and below it, if they have a vent too.
|
||||
if(isturf(loc)) //if we're not on a valid turf, forget it
|
||||
for (var/new_z in list(-1,1)) //change this list if a fancier system of z-levels gets implemented
|
||||
var/turf/open/zturf_conn = locate(x,y,z+new_z)
|
||||
if (istype(zturf_conn))
|
||||
var/obj/machinery/zvent/zvent_conn= locate(/obj/machinery/zvent) in zturf_conn
|
||||
if (istype(zvent_conn))
|
||||
//both floors have simulated turfs, share()
|
||||
var/turf/open/myturf = loc
|
||||
var/datum/gas_mixture/conn_air = zturf_conn.air //TODO: pop culture reference
|
||||
var/datum/gas_mixture/my_air = myturf.air
|
||||
if (istype(conn_air) && istype(my_air))
|
||||
my_air.share(conn_air)
|
||||
air_update_turf()
|
||||
@@ -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>")
|
||||
|
||||
@@ -409,7 +409,21 @@ GLOBAL_LIST_EMPTY(external_rsc_urls)
|
||||
"Someone come hold me :(",\
|
||||
"I need someone on me :(",\
|
||||
"What happened? Where has everyone gone?",\
|
||||
"Forever alone :("\
|
||||
"Forever alone :(",\
|
||||
"My nipples are so stiff, but Zelda ain't here. :(",\
|
||||
"Leon senpai, play more Spessmans. :(",\
|
||||
"If only Serdy were here...",\
|
||||
"Panic bunker can't keep my love for you out.",\
|
||||
"Cebu needs to Awoo herself back into my heart.",\
|
||||
"I don't even have a Turry to snuggle viciously here.",\
|
||||
"MOM, WHERE ARE YOU??? D:",\
|
||||
"It's a beautiful day outside. Birds are singing, flowers are blooming. On days like this...kids like you...SHOULD BE BURNING IN HELL.",\
|
||||
"Sometimes when I have sex, I think about putting an entire peanut butter and jelly sandwich in the VCR.",\
|
||||
"Oh good, no-one around to watch me lick Goofball's nipples. :D",\
|
||||
"I've replaced Beepsky with a fidget spinner, glory be autism abuse.",\
|
||||
"i shure hop dere are no PRED arund!!!!",\
|
||||
"NO PRED CAN eVER CATCH MI",\
|
||||
"help, the clown is honking his horn in front of dorms and its interrupting everyones erp"\
|
||||
)
|
||||
|
||||
send2irc("Server", "[cheesy_message] (No admins online)")
|
||||
@@ -716,6 +730,12 @@ GLOBAL_LIST_EMPTY(external_rsc_urls)
|
||||
if (isnull(new_size))
|
||||
CRASH("change_view called without argument.")
|
||||
|
||||
//CIT CHANGES START HERE - makes change_view change DEFAULT_VIEW to 15x15 depending on preferences
|
||||
if(prefs && CONFIG_GET(string/default_view))
|
||||
if(!prefs.widescreenpref && new_size == CONFIG_GET(string/default_view))
|
||||
new_size = "15x15"
|
||||
//END OF CIT CHANGES
|
||||
|
||||
view = new_size
|
||||
apply_clickcatcher()
|
||||
if (isliving(mob))
|
||||
|
||||
@@ -316,6 +316,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
dat += "<b>Window Flashing:</b> <a href='?_src_=prefs;preference=winflash'>[(windowflashing) ? "Yes" : "No"]</a><br>"
|
||||
dat += "<b>Play admin midis:</b> <a href='?_src_=prefs;preference=hear_midis'>[(toggles & SOUND_MIDI) ? "Yes" : "No"]</a><br>"
|
||||
dat += "<b>Play lobby music:</b> <a href='?_src_=prefs;preference=lobby_music'>[(toggles & SOUND_LOBBY) ? "Yes" : "No"]</a><br>"
|
||||
dat += "<b>Allow MediHound sleeper:</b> <a href='?_src_=prefs;preference=hound_sleeper'>[(toggles & MEDIHOUND_SLEEPER) ? "Yes" : "No"]</a><br>"
|
||||
dat += "<b>Ghost ears:</b> <a href='?_src_=prefs;preference=ghost_ears'>[(chat_toggles & CHAT_GHOSTEARS) ? "All Speech" : "Nearest Creatures"]</a><br>"
|
||||
dat += "<b>Ghost sight:</b> <a href='?_src_=prefs;preference=ghost_sight'>[(chat_toggles & CHAT_GHOSTSIGHT) ? "All Emotes" : "Nearest Creatures"]</a><br>"
|
||||
dat += "<b>Ghost whispers:</b> <a href='?_src_=prefs;preference=ghost_whispers'>[(chat_toggles & CHAT_GHOSTWHISPER) ? "All Speech" : "Nearest Creatures"]</a><br>"
|
||||
@@ -323,6 +324,9 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
dat += "<b>Ghost pda:</b> <a href='?_src_=prefs;preference=ghost_pda'>[(chat_toggles & CHAT_GHOSTPDA) ? "All Messages" : "Nearest Creatures"]</a><br>"
|
||||
dat += "<b>Pull requests:</b> <a href='?_src_=prefs;preference=pull_requests'>[(chat_toggles & CHAT_PULLR) ? "Yes" : "No"]</a><br>"
|
||||
dat += "<b>Midround Antagonist:</b> <a href='?_src_=prefs;preference=allow_midround_antag'>[(toggles & MIDROUND_ANTAG) ? "Yes" : "No"]</a><br>"
|
||||
//VORE SOUNDS
|
||||
dat += "<b>Hear Vore Sounds:</b> <a href='?_src_=prefs;preference=toggleeatingnoise'>[(toggles & EATING_NOISES) ? "Yes" : "No"]</a><br>"
|
||||
dat += "<b>Hear Vore Digestion Sounds:</b> <a href='?_src_=prefs;preference=toggledigestionnoise'>[(toggles & DIGESTION_NOISES) ? "Yes" : "No"]</a><br>"
|
||||
if(CONFIG_GET(flag/allow_metadata))
|
||||
dat += "<b>OOC Notes:</b> <a href='?_src_=prefs;preference=metadata;task=input'>Edit </a><br>"
|
||||
|
||||
@@ -1764,6 +1768,12 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
user.client.playtitlemusic()
|
||||
else
|
||||
user.stop_sound_channel(CHANNEL_LOBBYMUSIC)
|
||||
// VORE SOUND TOGGLES
|
||||
if("toggleeatingnoise")
|
||||
toggles ^= EATING_NOISES
|
||||
|
||||
if("toggledigestionnoise")
|
||||
toggles ^= DIGESTION_NOISES
|
||||
|
||||
if("ghost_ears")
|
||||
chat_toggles ^= CHAT_GHOSTEARS
|
||||
@@ -1783,6 +1793,9 @@ GLOBAL_LIST_EMPTY(preferences_datums)
|
||||
if("pull_requests")
|
||||
chat_toggles ^= CHAT_PULLR
|
||||
|
||||
if("hound_sleeper")
|
||||
toggles ^= MEDIHOUND_SLEEPER
|
||||
|
||||
if("allow_midround_antag")
|
||||
toggles ^= MIDROUND_ANTAG
|
||||
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
//This is the lowest supported version, anything below this is completely obsolete and the entire savefile will be wiped.
|
||||
#define SAVEFILE_VERSION_MIN 15
|
||||
#define SAVEFILE_VERSION_MIN 18
|
||||
|
||||
//This is the current version, anything below this will attempt to update (if it's not obsolete)
|
||||
// You do not need to raise this if you are adding new values that have sane defaults.
|
||||
// Only raise this value when changing the meaning/format/name/layout of an existing value
|
||||
// where you would want the updater procs below to run
|
||||
#define SAVEFILE_VERSION_MAX 20
|
||||
|
||||
/*
|
||||
SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Carn
|
||||
This proc checks if the current directory of the savefile S needs updating
|
||||
@@ -30,83 +34,17 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
return savefile_version
|
||||
return -1
|
||||
|
||||
|
||||
/datum/preferences/proc/update_antagchoices(current_version, savefile/S)
|
||||
if((!islist(be_special) || old_be_special ) && current_version < 12)
|
||||
//Archived values of when antag pref defines were a bitfield+fitflags
|
||||
var/B_traitor = 1
|
||||
var/B_operative = 2
|
||||
var/B_changeling = 4
|
||||
var/B_wizard = 8
|
||||
var/B_malf = 16
|
||||
var/B_rev = 32
|
||||
var/B_alien = 64
|
||||
var/B_pai = 128
|
||||
var/B_cultist = 256
|
||||
var/B_blob = 512
|
||||
var/B_ninja = 1024
|
||||
var/B_monkey = 2048
|
||||
var/B_gang = 4096
|
||||
var/B_abductor = 16384
|
||||
var/B_brother = 32768
|
||||
|
||||
var/list/archived = list(B_traitor,B_operative,B_changeling,B_wizard,B_malf,B_rev,B_alien,B_pai,B_cultist,B_blob,B_ninja,B_monkey,B_gang,B_abductor,B_brother)
|
||||
|
||||
be_special = list()
|
||||
|
||||
for(var/flag in archived)
|
||||
if(old_be_special & flag)
|
||||
//this is shitty, but this proc should only be run once per player and then never again for the rest of eternity,
|
||||
switch(flag)
|
||||
if(1) //why aren't these the variables above? Good question, it's because byond complains the expression isn't constant, when it is.
|
||||
be_special += ROLE_TRAITOR
|
||||
if(2)
|
||||
be_special += ROLE_OPERATIVE
|
||||
if(4)
|
||||
be_special += ROLE_CHANGELING
|
||||
if(8)
|
||||
be_special += ROLE_WIZARD
|
||||
if(16)
|
||||
be_special += ROLE_MALF
|
||||
if(32)
|
||||
be_special += ROLE_REV
|
||||
if(64)
|
||||
be_special += ROLE_ALIEN
|
||||
if(128)
|
||||
be_special += ROLE_PAI
|
||||
if(256)
|
||||
be_special += ROLE_CULTIST
|
||||
if(512)
|
||||
be_special += ROLE_BLOB
|
||||
if(1024)
|
||||
be_special += ROLE_NINJA
|
||||
if(2048)
|
||||
be_special += ROLE_MONKEY
|
||||
if(16384)
|
||||
be_special += ROLE_ABDUCTOR
|
||||
if(32768)
|
||||
be_special += ROLE_BROTHER
|
||||
|
||||
|
||||
/datum/preferences/proc/update_preferences(current_version, savefile/S)
|
||||
|
||||
|
||||
//should this proc get fairly long (say 3 versions long),
|
||||
//should these procs get fairly long
|
||||
//just increase SAVEFILE_VERSION_MIN so it's not as far behind
|
||||
//SAVEFILE_VERSION_MAX and then delete any obsolete if clauses
|
||||
//from this proc.
|
||||
//It's only really meant to avoid annoying frequent players
|
||||
//from these procs.
|
||||
//This only really meant to avoid annoying frequent players
|
||||
//if your savefile is 3 months out of date, then 'tough shit'.
|
||||
|
||||
/datum/preferences/proc/update_preferences(current_version, savefile/S)
|
||||
return
|
||||
|
||||
/datum/preferences/proc/update_character(current_version, savefile/S)
|
||||
if(current_version < 16)
|
||||
var/berandom
|
||||
S["userandomjob"] >> berandom
|
||||
if (berandom)
|
||||
joblessrole = BERANDOMJOB
|
||||
else
|
||||
joblessrole = BEASSISTANT
|
||||
if(current_version < 17)
|
||||
features["legs"] = "Normal Legs"
|
||||
if(current_version < 20)//Raise this to the max savefile version every time we change something so we don't sanitize this whole list every time you save.
|
||||
features["mam_body_markings"] = sanitize_inlist(features["mam_body_markings"], GLOB.mam_body_markings_list)
|
||||
features["mam_ears"] = sanitize_inlist(features["mam_ears"], GLOB.mam_ears_list)
|
||||
@@ -139,6 +77,7 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
features["vag_color"] = sanitize_hexcolor(features["vag_color"], 3, 0)
|
||||
//womb features
|
||||
features["has_womb"] = sanitize_integer(features["has_womb"], 0, 1, 0)
|
||||
|
||||
if(current_version < 19)
|
||||
pda_style = "mono"
|
||||
if(current_version < 20)
|
||||
@@ -206,7 +145,6 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
|
||||
//try to fix any outdated data if necessary
|
||||
if(needs_update >= 0)
|
||||
update_preferences(needs_update, S) //needs_update = savefile_version if we need an update (positive integer)
|
||||
update_antagchoices(needs_update, S)
|
||||
|
||||
//Sanitize
|
||||
ooccolor = sanitize_ooccolor(sanitize_hexcolor(ooccolor, 6, 1, initial(ooccolor)))
|
||||
|
||||
@@ -250,6 +250,20 @@ TOGGLE_CHECKBOX(/datum/verbs/menu/Settings, listen_ooc)()
|
||||
/datum/verbs/menu/Settings/listen_ooc/Get_checked(client/C)
|
||||
return C.prefs.chat_toggles & CHAT_OOC
|
||||
|
||||
TOGGLE_CHECKBOX(/datum/verbs/menu/Settings/Sound, togglehoundsleeper)()
|
||||
set name = "Allow/Deny Hound Sleeper"
|
||||
set category = "Preferences"
|
||||
set desc = "Allow MediHound Sleepers"
|
||||
usr.client.prefs.toggles ^= MEDIHOUND_SLEEPER
|
||||
usr.client.prefs.save_preferences()
|
||||
if(usr.client.prefs.toggles & MEDIHOUND_SLEEPER)
|
||||
to_chat(usr, "You will now allow MediHounds to place you in their sleeper.")
|
||||
else
|
||||
to_chat(usr, "You will no longer allow MediHounds to place you in their sleeper.")
|
||||
SSblackbox.record_feedback("nested tally", "preferences_verb", 1, list("Toggle MediHound Sleeper", "[usr.client.prefs.toggles & MEDIHOUND_SLEEPER ? "Enabled" : "Disabled"]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
/datum/verbs/menu/Settings/Sound/togglehoundsleeper/Get_checked(client/C)
|
||||
return C.prefs.toggles & MEDIHOUND_SLEEPER
|
||||
|
||||
|
||||
GLOBAL_LIST_INIT(ghost_forms, list("ghost","ghostking","ghostian2","skeleghost","ghost_red","ghost_black", \
|
||||
"ghost_blue","ghost_yellow","ghost_green","ghost_pink", \
|
||||
@@ -415,3 +429,4 @@ GLOBAL_LIST_INIT(ghost_orbits, list(GHOST_ORBIT_CIRCLE,GHOST_ORBIT_TRIANGLE,GHOS
|
||||
prefs.save_preferences()
|
||||
to_chat(src, "You will [(prefs.chat_toggles & CHAT_PRAYER) ? "now" : "no longer"] see prayerchat.")
|
||||
SSblackbox.record_feedback("nested tally", "admin_toggle", 1, list("Toggle Prayer Visibility", "[prefs.chat_toggles & CHAT_PRAYER ? "Enabled" : "Disabled"]")) //If you are copy-pasting this, ensure the 2nd parameter is unique to the new proc!
|
||||
|
||||
|
||||
@@ -5,4 +5,7 @@
|
||||
|
||||
/datum/preferences/proc/set_biological_gender(var/gender)
|
||||
biological_gender = gender
|
||||
identifying_gender = gender
|
||||
identifying_gender = gender
|
||||
|
||||
|
||||
/obj/item/clothing/var/hides_bulges = FALSE // OwO wats this?
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
/client/verb/sethotkeys(from_pref = 0 as num)
|
||||
set name = "Set Hotkeys"
|
||||
set hidden = TRUE
|
||||
set waitfor = FALSE
|
||||
set desc = "Used to set mob-specific hotkeys or load hoykey mode from preferences"
|
||||
|
||||
var/hotkey_default = "default"
|
||||
var/hotkey_macro = "hotkeys"
|
||||
var/current_setting
|
||||
|
||||
var/list/default_macros = list("default", "robot-default")
|
||||
|
||||
if(from_pref)
|
||||
current_setting = (prefs.hotkeys ? hotkey_macro : hotkey_default)
|
||||
else
|
||||
current_setting = winget(src, "mainwindow", "macro")
|
||||
|
||||
if(mob)
|
||||
hotkey_macro = mob.macro_hotkeys
|
||||
hotkey_default = mob.macro_default
|
||||
|
||||
if(current_setting in default_macros)
|
||||
winset(src, null, "mainwindow.macro=[hotkey_default] input.focus=true input.background-color=#d3b5b5")
|
||||
else
|
||||
winset(src, null, "mainwindow.macro=[hotkey_macro] mapwindow.map.focus=true input.background-color=#e0e0e0")
|
||||
@@ -2,6 +2,9 @@ GLOBAL_VAR_INIT(total_runtimes, GLOB.total_runtimes || 0)
|
||||
GLOBAL_VAR_INIT(total_runtimes_skipped, 0)
|
||||
|
||||
#ifdef DEBUG
|
||||
|
||||
#define ERROR_USEFUL_LEN 2
|
||||
|
||||
/world/Error(exception/E, datum/e_src)
|
||||
GLOB.total_runtimes++
|
||||
|
||||
|
||||
@@ -39,10 +39,10 @@
|
||||
continue
|
||||
if(H.stat == DEAD)
|
||||
continue
|
||||
if(VIRUSIMMUNE in H.dna.species.species_traits) //Don't pick someone who's virus immune, only for it to not do anything.
|
||||
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)
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
/datum/round_event_control/solar_flare
|
||||
name = "Solar Flare"
|
||||
typepath = /datum/round_event/solar_flare
|
||||
max_occurrences = 1
|
||||
|
||||
/datum/round_event/solar_flare
|
||||
|
||||
/datum/round_event/solar_flare/setup()
|
||||
startWhen = 3
|
||||
endWhen = startWhen + 1
|
||||
announceWhen = 1
|
||||
|
||||
/datum/round_event/solar_flare/announce()
|
||||
priority_announce("Incoming solar flare detected near the station. Expect power outages in all exposed areas for a short duration.", "Anomaly Alert", 'sound/effects/alert.ogg')
|
||||
|
||||
/datum/round_event/solar_flare/start()
|
||||
SSweather.run_weather("solar flare",1)
|
||||
@@ -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
|
||||
@@ -74,4 +74,4 @@
|
||||
return FIELD_EDGE
|
||||
if(O.parent == F)
|
||||
return FIELD_TURF
|
||||
return NO_FIELD
|
||||
return FALSE
|
||||
|
||||
@@ -1,111 +0,0 @@
|
||||
/obj/machinery/computer/holodeck/attack_hand(var/mob/user as mob)
|
||||
user.set_machine(src)
|
||||
|
||||
var/dat = "<h3>Current Loaded Programs</h3>"
|
||||
dat += "<a href='?src=\ref[src];loadarea=[offline_program.type]'>Power Off</a><br>"
|
||||
for(var/area/A in program_cache)
|
||||
dat += "<a href='?src=\ref[src];loadarea=[A.type]'>[A.name]</a><br>"
|
||||
if(emagged && emag_programs.len)
|
||||
dat += "<span class='warning'>SUPERVISOR ACCESS - SAFETY PROTOCOLS DISABLED - CAUTION: EMITTER ANOMALY</span><br>"
|
||||
for(var/area/A in emag_programs)
|
||||
dat += "<a href='?src=\ref[src];loadarea=[A.type]'>[A.name]</a><br>"
|
||||
|
||||
var/datum/browser/popup = new(user, "computer", name, 400, 500)
|
||||
popup.set_content(dat)
|
||||
popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
|
||||
popup.open()
|
||||
return
|
||||
|
||||
/obj/machinery/computer/holodeck/attack_ai(var/mob/user as mob)
|
||||
var/dat = "<h3>Current Loaded Programs</h3>"
|
||||
|
||||
dat += "<a href='?src=\ref[src];loadarea=[offline_program.type]'>Power Off</a><br>"
|
||||
for(var/area/A in program_cache)
|
||||
dat += "<a href='?src=\ref[src];loadarea=[A.type]'>[A.name]</a><br>"
|
||||
|
||||
if(emag_programs.len)
|
||||
dat += "<br>"
|
||||
if(emagged)
|
||||
dat += "Safety protocol: <span class='bad'>Offline</span> <a href='?\ref[src];safety=1'>Engage</a><br>"
|
||||
for(var/area/A in emag_programs)
|
||||
dat += "<a href='?src=\ref[src];loadarea=[A.type]'>[A.name]</a><br>"
|
||||
else
|
||||
dat += "Safety protocol: <span class='good'>Online</span> <a href='?\ref[src];safety=0'>Disengage</a><br>"
|
||||
|
||||
var/datum/browser/popup = new(user, "computer", name, 400, 500)
|
||||
popup.set_content(dat)
|
||||
popup.set_title_image(user.browse_rsc_icon(src.icon, src.icon_state))
|
||||
popup.open()
|
||||
|
||||
|
||||
/obj/machinery/computer/holodeck/proc/load_program(var/area/A, var/force = 0, var/delay = 0)
|
||||
if(stat)
|
||||
A = offline_program
|
||||
force = 1
|
||||
delay = 0
|
||||
if(program == A)
|
||||
return
|
||||
if(world.time < (last_change + 25 + (damaged?500:0)) && !force)
|
||||
if(delay)
|
||||
sleep(25)
|
||||
else
|
||||
if(world.time < (last_change + 15))//To prevent super-spam clicking, reduced process size and annoyance -Sieve
|
||||
return
|
||||
if(get_dist(usr,src) <= 3)
|
||||
to_chat(usr, "<span class='warning'>ERROR. Recalibrating projection apparatus.</span>")
|
||||
return
|
||||
|
||||
last_change = world.time
|
||||
active = (A != offline_program)
|
||||
use_power = active ? ACTIVE_POWER_USE : IDLE_POWER_USE
|
||||
|
||||
for(var/obj/effect/holodeck_effect/HE in effects)
|
||||
HE.deactivate(src)
|
||||
|
||||
for(var/item in spawned)
|
||||
derez(item, forced=force)
|
||||
|
||||
program = A
|
||||
// note nerfing does not yet work on guns, should
|
||||
// should also remove/limit/filter reagents?
|
||||
// this is an exercise left to others I'm afraid. -Sayu
|
||||
spawned = A.copy_contents_to(linked, 1, nerf_weapons = !emagged)
|
||||
for(var/obj/machinery/M in spawned)
|
||||
M.flags_1 |= NODECONSTRUCT_1
|
||||
for(var/obj/structure/S in spawned)
|
||||
S.flags_1 |= NODECONSTRUCT_1
|
||||
effects = list()
|
||||
|
||||
spawn(30)
|
||||
var/list/added = list()
|
||||
for(var/obj/effect/holodeck_effect/HE in spawned)
|
||||
effects += HE
|
||||
spawned -= HE
|
||||
var/atom/x = HE.activate(src)
|
||||
if(istype(x) || islist(x))
|
||||
spawned += x // holocarp are not forever
|
||||
added += x
|
||||
for(var/obj/machinery/M in added)
|
||||
M.flags_1 |= NODECONSTRUCT_1
|
||||
for(var/obj/structure/S in added)
|
||||
S.flags_1 |= NODECONSTRUCT_1
|
||||
|
||||
/obj/machinery/computer/holodeck/proc/derez(var/obj/obj, var/silent = 1, var/forced = 0)
|
||||
// Emagging a machine creates an anomaly in the derez systems.
|
||||
if(obj && src.emagged && !src.stat && !forced)
|
||||
if((ismob(obj) || istype(obj.loc,/mob)) && prob(50))
|
||||
spawn(50) .(obj,silent) // may last a disturbingly long time
|
||||
return
|
||||
spawned.Remove(obj)
|
||||
|
||||
if(!obj)
|
||||
return
|
||||
var/turf/T = get_turf(obj)
|
||||
for(var/atom/movable/AM in obj.contents) // these should be derezed if they were generated
|
||||
AM.loc = T
|
||||
if(ismob(AM))
|
||||
silent = FALSE // otherwise make sure they are dropped
|
||||
|
||||
if(!silent)
|
||||
visible_message("The [obj.name] fades away!")
|
||||
qdel(obj)
|
||||
@@ -56,11 +56,8 @@
|
||||
var/mob/living/carbon/C = user
|
||||
if(C.gloves)
|
||||
return FALSE
|
||||
if(ishuman(C))
|
||||
var/mob/living/carbon/human/H = C
|
||||
if(H.dna && H.dna.species)
|
||||
if(PIERCEIMMUNE in H.dna.species.species_traits)
|
||||
return FALSE
|
||||
if(C.has_trait(TRAIT_PIERCEIMMUNE))
|
||||
return FALSE
|
||||
var/hit_zone = (C.held_index_to_dir(C.active_hand_index) == "l" ? "l_":"r_") + "arm"
|
||||
var/obj/item/bodypart/affecting = C.get_bodypart(hit_zone)
|
||||
if(affecting)
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -173,18 +173,13 @@
|
||||
if(!check_spot())
|
||||
return
|
||||
|
||||
|
||||
var/atom/movable/rcd_target
|
||||
var/turf/target_turf = get_turf(remote_eye)
|
||||
var/atom/rcd_target = target_turf
|
||||
|
||||
//Find airlocks
|
||||
rcd_target = locate(/obj/machinery/door/airlock) in target_turf
|
||||
|
||||
if(!rcd_target)
|
||||
rcd_target = locate (/obj/structure) in target_turf
|
||||
|
||||
if(!rcd_target || !rcd_target.anchored)
|
||||
rcd_target = target_turf
|
||||
//Find airlocks and other shite
|
||||
for(var/obj/S in target_turf)
|
||||
if(LAZYLEN(S.rcd_vals(owner,B.RCD)))
|
||||
rcd_target = S //If we don't break out of this loop we'll get the last placed thing
|
||||
|
||||
owner.changeNext_move(CLICK_CD_RANGE)
|
||||
B.RCD.afterattack(rcd_target, owner, TRUE) //Activate the RCD and force it to work remotely!
|
||||
@@ -276,4 +271,4 @@ datum/action/innate/aux_base/install_turret/Activate()
|
||||
|
||||
B.turret_stock--
|
||||
to_chat(owner, "<span class='notice'>Turret installation complete!</span>")
|
||||
playsound(turret_turf, 'sound/items/drill_use.ogg', 65, 1)
|
||||
playsound(turret_turf, 'sound/items/drill_use.ogg', 65, 1)
|
||||
|
||||
@@ -203,7 +203,6 @@
|
||||
desc = "A large machine releasing a constant gust of air."
|
||||
anchored = TRUE
|
||||
density = TRUE
|
||||
var/arbitraryatmosblockingvar = TRUE
|
||||
var/buildstacktype = /obj/item/stack/sheet/metal
|
||||
var/buildstackamount = 5
|
||||
CanAtmosPass = ATMOS_PASS_NO
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
if(bodytemperature >= TCRYO && !(has_trait(TRAIT_NOCLONE))) //cryosleep or husked people do not pump the blood.
|
||||
|
||||
//Blood regeneration if there is some space
|
||||
if(blood_volume < BLOOD_VOLUME_NORMAL && !(NOHUNGER in dna.species.species_traits))
|
||||
if(blood_volume < BLOOD_VOLUME_NORMAL && !has_trait(TRAIT_NOHUNGER))
|
||||
var/nutrition_ratio = 0
|
||||
switch(nutrition)
|
||||
if(0 to NUTRITION_LEVEL_STARVING)
|
||||
@@ -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>")
|
||||
|
||||
|
||||
@@ -440,7 +440,7 @@
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/proc/vomit(lost_nutrition = 10, blood = FALSE, stun = TRUE, distance = 1, message = TRUE, toxic = FALSE)
|
||||
if(dna && dna.species && NOHUNGER in dna.species.species_traits)
|
||||
if(has_trait(TRAIT_NOHUNGER))
|
||||
return 1
|
||||
|
||||
if(nutrition < 100 && !blood)
|
||||
@@ -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
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
/mob/living/carbon/Move(NewLoc, direct)
|
||||
. = ..()
|
||||
if(. && mob_has_gravity()) //floating is easy
|
||||
if(dna && dna.species && (NOHUNGER in dna.species.species_traits))
|
||||
if(has_trait(TRAIT_NOHUNGER))
|
||||
nutrition = NUTRITION_LEVEL_FED - 1 //just less than feeling vigorous
|
||||
else if(nutrition && stat != DEAD)
|
||||
nutrition -= HUNGER_FACTOR/10
|
||||
|
||||
@@ -80,7 +80,7 @@
|
||||
|
||||
|
||||
/mob/living/carbon/adjustToxLoss(amount, updating_health = TRUE, forced = FALSE)
|
||||
if(!forced && has_dna() && TOXINLOVER in dna.species.species_traits) //damage becomes healing and healing becomes damage
|
||||
if(!forced && has_trait(TRAIT_TOXINLOVER)) //damage becomes healing and healing becomes damage
|
||||
amount = -amount
|
||||
if(amount > 0)
|
||||
blood_volume -= 5*amount
|
||||
|
||||
@@ -252,10 +252,6 @@
|
||||
if(91.01 to INFINITY)
|
||||
msg += "[t_He] [t_is] a shitfaced, slobbering wreck.\n"
|
||||
|
||||
for (var/I in src.vore_organs)
|
||||
var/datum/belly/B = vore_organs[I]
|
||||
msg += B.get_examine_msg()
|
||||
|
||||
msg += "</span>"
|
||||
|
||||
if(!appears_dead)
|
||||
@@ -329,7 +325,7 @@
|
||||
|
||||
if(print_flavor_text() && get_visible_name() != "Unknown")//Are we sure we know who this is? Don't show flavor text unless we can recognize them. Prevents certain metagaming with impersonation.
|
||||
msg += "[print_flavor_text()]\n"
|
||||
|
||||
|
||||
msg += "*---------*</span>"
|
||||
|
||||
to_chat(user, msg)
|
||||
|
||||
@@ -42,13 +42,4 @@
|
||||
message = "<span class='warning'>[t_His] stomach is firmly packed with digesting slop. [t_He] must have eaten at least a few times worth their body weight! It looks hard for them to stand, and [t_his] gut jiggles when they move.</span>\n"
|
||||
if(4075 to 10000) // Four or more people.
|
||||
message = "<span class='warning'>[t_He] [t_is] so absolutely stuffed that you aren't sure how it's possible to move. [t_He] can't seem to swell any bigger. The surface of [t_his] belly looks sorely strained!</span>\n"
|
||||
return message
|
||||
|
||||
/mob/living/carbon/human/proc/examine_bellies()
|
||||
var/message = ""
|
||||
|
||||
for (var/I in src.vore_organs)
|
||||
var/datum/belly/B = vore_organs[I]
|
||||
message += B.get_examine_msg()
|
||||
|
||||
return message
|
||||
@@ -32,6 +32,7 @@
|
||||
|
||||
/mob/living/carbon/human/Destroy()
|
||||
QDEL_NULL(physiology)
|
||||
QDEL_NULL_LIST(vore_organs) // CITADEL EDIT belly stuff
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/human/OpenCraftingMenu()
|
||||
@@ -90,10 +91,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]")
|
||||
|
||||
@@ -482,7 +483,7 @@
|
||||
. = 1 // Default to returning true.
|
||||
if(user && !target_zone)
|
||||
target_zone = user.zone_selected
|
||||
if(dna && (PIERCEIMMUNE in dna.species.species_traits))
|
||||
if(has_trait(TRAIT_PIERCEIMMUNE))
|
||||
. = 0
|
||||
// If targeting the head, see if the head item is thin enough.
|
||||
// If targeting anything else, see if the wear suit is thin enough.
|
||||
@@ -643,7 +644,7 @@
|
||||
to_chat(src, "<span class='warning'>You fail to perform CPR on [C]!</span>")
|
||||
return 0
|
||||
|
||||
var/they_breathe = (!(NOBREATH in C.dna.species.species_traits))
|
||||
var/they_breathe = !C.has_trait(TRAIT_NOBREATH)
|
||||
var/they_lung = C.getorganslot(ORGAN_SLOT_LUNGS)
|
||||
|
||||
if(C.health > HEALTH_THRESHOLD_CRIT)
|
||||
|
||||
@@ -136,7 +136,7 @@
|
||||
else if(I)
|
||||
if(I.throw_speed >= EMBED_THROWSPEED_THRESHOLD)
|
||||
if(can_embed(I))
|
||||
if(prob(I.embedding.embed_chance) && !(dna && (PIERCEIMMUNE in dna.species.species_traits)))
|
||||
if(prob(I.embedding.embed_chance) && !has_trait(TRAIT_PIERCEIMMUNE))
|
||||
throw_alert("embeddedobject", /obj/screen/alert/embeddedobject)
|
||||
var/obj/item/bodypart/L = pick(bodyparts)
|
||||
L.embedded_objects |= I
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -138,7 +138,7 @@
|
||||
if(src.dna.check_mutation(HULK))
|
||||
to_chat(src, "<span class='warning'>Your meaty finger is much too large for the trigger guard!</span>")
|
||||
return FALSE
|
||||
if(NOGUNS in src.dna.species.species_traits)
|
||||
if(has_trait(TRAIT_NOGUNS))
|
||||
to_chat(src, "<span class='warning'>Your fingers don't fit in the trigger guard!</span>")
|
||||
return FALSE
|
||||
if(mind)
|
||||
|
||||
@@ -20,6 +20,22 @@
|
||||
#define COLD_GAS_DAMAGE_LEVEL_2 1.5 //Amount of damage applied when the current breath's temperature passes the 200K point
|
||||
#define COLD_GAS_DAMAGE_LEVEL_3 3 //Amount of damage applied when the current breath's temperature passes the 120K point
|
||||
|
||||
// bitflags for the percentual amount of protection a piece of clothing which covers the body part offers.
|
||||
// Used with human/proc/get_heat_protection() and human/proc/get_cold_protection()
|
||||
// The values here should add up to 1.
|
||||
// Hands and feet have 2.5%, arms and legs 7.5%, each of the torso parts has 15% and the head has 30%
|
||||
#define THERMAL_PROTECTION_HEAD 0.3
|
||||
#define THERMAL_PROTECTION_CHEST 0.15
|
||||
#define THERMAL_PROTECTION_GROIN 0.15
|
||||
#define THERMAL_PROTECTION_LEG_LEFT 0.075
|
||||
#define THERMAL_PROTECTION_LEG_RIGHT 0.075
|
||||
#define THERMAL_PROTECTION_FOOT_LEFT 0.025
|
||||
#define THERMAL_PROTECTION_FOOT_RIGHT 0.025
|
||||
#define THERMAL_PROTECTION_ARM_LEFT 0.075
|
||||
#define THERMAL_PROTECTION_ARM_RIGHT 0.075
|
||||
#define THERMAL_PROTECTION_HAND_LEFT 0.025
|
||||
#define THERMAL_PROTECTION_HAND_RIGHT 0.025
|
||||
|
||||
/mob/living/carbon/human/Life()
|
||||
set invisibility = 0
|
||||
if (notransform)
|
||||
@@ -48,6 +64,10 @@
|
||||
/mob/living/carbon/human/calculate_affecting_pressure(pressure)
|
||||
if((wear_suit && (wear_suit.flags_1 & STOPSPRESSUREDMAGE_1)) && (head && (head.flags_1 & STOPSPRESSUREDMAGE_1)))
|
||||
return ONE_ATMOSPHERE
|
||||
if(istype(loc, /obj/belly))
|
||||
return ONE_ATMOSPHERE
|
||||
if(istype(loc, /obj/item/device/dogborg/sleeper))
|
||||
return ONE_ATMOSPHERE
|
||||
else
|
||||
return pressure
|
||||
|
||||
@@ -81,7 +101,7 @@
|
||||
if(!L)
|
||||
if(health >= HEALTH_THRESHOLD_CRIT)
|
||||
adjustOxyLoss(HUMAN_MAX_OXYLOSS + 1)
|
||||
else if(!(NOCRITDAMAGE in dna.species.species_traits))
|
||||
else if(!has_trait(TRAIT_NOCRITDAMAGE))
|
||||
adjustOxyLoss(HUMAN_CRIT_MAX_OXYLOSS)
|
||||
|
||||
failed_last_breath = 1
|
||||
@@ -122,6 +142,8 @@
|
||||
return FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT
|
||||
if(ismob(loc))
|
||||
return FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT
|
||||
if(istype(loc, /obj/belly))
|
||||
return FIRE_IMMUNITY_SUIT_MAX_TEMP_PROTECT
|
||||
//END EDIT
|
||||
if(wear_suit)
|
||||
if(wear_suit.max_heat_protection_temperature >= FIRE_SUIT_MAX_TEMP_PROTECT)
|
||||
@@ -228,16 +250,14 @@
|
||||
return thermal_protection_flags
|
||||
|
||||
/mob/living/carbon/human/proc/get_cold_protection(temperature)
|
||||
|
||||
if(dna.check_mutation(COLDRES))
|
||||
return TRUE //Fully protected from the cold.
|
||||
|
||||
if(RESISTCOLD in dna.species.species_traits)
|
||||
if(has_trait(TRAIT_RESISTCOLD))
|
||||
return TRUE
|
||||
|
||||
|
||||
//CITADEL EDIT Mandatory for vore code.
|
||||
if(istype(loc, /obj/item/device/dogborg/sleeper))
|
||||
return 1 //freezing to death in sleepers ruins fun.
|
||||
if(istype(loc, /obj/belly))
|
||||
return 1
|
||||
if(ismob(loc))
|
||||
return 1 //because lazy and being inside somemone insulates you from space
|
||||
//END EDIT
|
||||
@@ -285,16 +305,14 @@
|
||||
/mob/living/carbon/human/has_smoke_protection()
|
||||
if(wear_mask)
|
||||
if(wear_mask.flags_1 & BLOCK_GAS_SMOKE_EFFECT_1)
|
||||
. = 1
|
||||
return TRUE
|
||||
if(glasses)
|
||||
if(glasses.flags_1 & BLOCK_GAS_SMOKE_EFFECT_1)
|
||||
. = 1
|
||||
return TRUE
|
||||
if(head)
|
||||
if(head.flags_1 & BLOCK_GAS_SMOKE_EFFECT_1)
|
||||
. = 1
|
||||
if(NOBREATH in dna.species.species_traits)
|
||||
. = 1
|
||||
return .
|
||||
return TRUE
|
||||
return ..()
|
||||
|
||||
|
||||
/mob/living/carbon/human/proc/handle_embedded_objects()
|
||||
@@ -321,14 +339,14 @@
|
||||
if(!can_heartattack())
|
||||
return
|
||||
|
||||
var/we_breath = (!(NOBREATH in dna.species.species_traits))
|
||||
var/we_breath = !has_trait(TRAIT_NOBREATH, SPECIES_TRAIT)
|
||||
|
||||
|
||||
if(!undergoing_cardiac_arrest())
|
||||
return
|
||||
|
||||
// Cardiac arrest, unless corazone
|
||||
if(reagents.get_reagent_amount("corazone"))
|
||||
// Cardiac arrest, unless heart is stabilized
|
||||
if(has_trait(TRAIT_STABLEHEART))
|
||||
return
|
||||
|
||||
if(we_breath)
|
||||
@@ -430,3 +448,14 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put
|
||||
adjustToxLoss(4) //Let's be honest you shouldn't be alive by now
|
||||
|
||||
#undef HUMAN_MAX_OXYLOSS
|
||||
#undef THERMAL_PROTECTION_HEAD
|
||||
#undef THERMAL_PROTECTION_CHEST
|
||||
#undef THERMAL_PROTECTION_GROIN
|
||||
#undef THERMAL_PROTECTION_LEG_LEFT
|
||||
#undef THERMAL_PROTECTION_LEG_RIGHT
|
||||
#undef THERMAL_PROTECTION_FOOT_LEFT
|
||||
#undef THERMAL_PROTECTION_FOOT_RIGHT
|
||||
#undef THERMAL_PROTECTION_ARM_LEFT
|
||||
#undef THERMAL_PROTECTION_ARM_RIGHT
|
||||
#undef THERMAL_PROTECTION_HAND_LEFT
|
||||
#undef THERMAL_PROTECTION_HAND_RIGHT
|
||||
@@ -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
|
||||
@@ -48,14 +48,12 @@
|
||||
return real_name
|
||||
|
||||
/mob/living/carbon/human/IsVocal()
|
||||
CHECK_DNA_AND_SPECIES(src)
|
||||
|
||||
// how do species that don't breathe talk? magic, that's what.
|
||||
if(!(NOBREATH in dna.species.species_traits) && !getorganslot(ORGAN_SLOT_LUNGS))
|
||||
return 0
|
||||
if(!has_trait(TRAIT_NOBREATH, SPECIES_TRAIT) && !getorganslot(ORGAN_SLOT_LUNGS))
|
||||
return FALSE
|
||||
if(mind)
|
||||
return !mind.miming
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/mob/living/carbon/human/proc/SetSpecialVoice(new_voice)
|
||||
if(new_voice)
|
||||
|
||||
@@ -53,8 +53,10 @@ GLOBAL_LIST_EMPTY(roundstart_races)
|
||||
var/damage_overlay_type = "human" //what kind of damage overlays (if any) appear on our species when wounded?
|
||||
var/fixed_mut_color = "" //to use MUTCOLOR with a fixed color that's independent of dna.feature["mcolor"]
|
||||
|
||||
// species flags. these can be found in flags.dm
|
||||
// species-only traits. Can be found in DNA.dm
|
||||
var/list/species_traits = list()
|
||||
// generic traits tied to having the species
|
||||
var/list/inherent_traits = list()
|
||||
|
||||
var/attack_verb = "punch" // punch-specific attack verb
|
||||
var/sound/attack_sound = 'sound/weapons/punch1.ogg'
|
||||
@@ -151,8 +153,8 @@ GLOBAL_LIST_EMPTY(roundstart_races)
|
||||
|
||||
var/should_have_brain = TRUE
|
||||
var/should_have_heart = !(NOBLOOD in species_traits)
|
||||
var/should_have_lungs = !(NOBREATH in species_traits)
|
||||
var/should_have_appendix = !(NOHUNGER in species_traits)
|
||||
var/should_have_lungs = !(TRAIT_NOBREATH in inherent_traits)
|
||||
var/should_have_appendix = !(TRAIT_NOHUNGER in inherent_traits)
|
||||
var/should_have_eyes = TRUE
|
||||
var/should_have_ears = TRUE
|
||||
var/should_have_tongue = TRUE
|
||||
@@ -287,8 +289,11 @@ GLOBAL_LIST_EMPTY(roundstart_races)
|
||||
else //Entries in the list should only ever be items or null, so if it's not an item, we can assume it's an empty hand
|
||||
C.put_in_hands(new mutanthands())
|
||||
|
||||
if(VIRUSIMMUNE in species_traits)
|
||||
for(var/datum/disease/A in C.viruses)
|
||||
for(var/X in inherent_traits)
|
||||
C.add_trait(X, SPECIES_TRAIT)
|
||||
|
||||
if(TRAIT_VIRUSIMMUNE in inherent_traits)
|
||||
for(var/datum/disease/A in C.diseases)
|
||||
A.cure(FALSE)
|
||||
|
||||
//CITADEL EDIT
|
||||
@@ -304,6 +309,8 @@ GLOBAL_LIST_EMPTY(roundstart_races)
|
||||
C.dna.blood_type = random_blood_type()
|
||||
if(DIGITIGRADE in species_traits)
|
||||
C.Digitigrade_Leg_Swap(TRUE)
|
||||
for(var/X in inherent_traits)
|
||||
C.remove_trait(X, SPECIES_TRAIT)
|
||||
|
||||
/datum/species/proc/handle_hair(mob/living/carbon/human/H, forced_colour)
|
||||
H.remove_overlay(HAIR_LAYER)
|
||||
@@ -855,11 +862,11 @@ GLOBAL_LIST_EMPTY(roundstart_races)
|
||||
//END EDIT
|
||||
|
||||
/datum/species/proc/spec_life(mob/living/carbon/human/H)
|
||||
if(NOBREATH in species_traits)
|
||||
if(H.has_trait(TRAIT_NOBREATH))
|
||||
H.setOxyLoss(0)
|
||||
H.losebreath = 0
|
||||
|
||||
var/takes_crit_damage = (!(NOCRITDAMAGE in species_traits))
|
||||
var/takes_crit_damage = (!H.has_trait(TRAIT_NOCRITDAMAGE))
|
||||
if((H.health < HEALTH_THRESHOLD_CRIT) && takes_crit_damage)
|
||||
H.adjustBruteLoss(1)
|
||||
|
||||
@@ -1111,8 +1118,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
|
||||
H.update_inv_wear_suit()
|
||||
|
||||
// nutrition decrease and satiety
|
||||
if (H.nutrition > 0 && H.stat != DEAD && \
|
||||
H.dna && H.dna.species && (!(NOHUNGER in H.dna.species.species_traits)))
|
||||
if (H.nutrition > 0 && H.stat != DEAD && !H.has_trait(TRAIT_NOHUNGER))
|
||||
// THEY HUNGER
|
||||
var/hunger_rate = HUNGER_FACTOR
|
||||
if(H.satiety > 0)
|
||||
@@ -1136,7 +1142,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
|
||||
if(H.nutrition > NUTRITION_LEVEL_FAT)
|
||||
H.metabolism_efficiency = 1
|
||||
else if(H.nutrition > NUTRITION_LEVEL_FED && H.satiety > 80)
|
||||
if(H.metabolism_efficiency != 1.25 && (H.dna && H.dna.species && !(NOHUNGER in H.dna.species.species_traits)))
|
||||
if(H.metabolism_efficiency != 1.25 && !H.has_trait(TRAIT_NOHUNGER))
|
||||
to_chat(H, "<span class='notice'>You feel vigorous.</span>")
|
||||
H.metabolism_efficiency = 1.25
|
||||
else if(H.nutrition < NUTRITION_LEVEL_STARVING + 50)
|
||||
@@ -1165,7 +1171,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
|
||||
. = FALSE
|
||||
var/radiation = H.radiation
|
||||
|
||||
if(RADIMMUNE in species_traits)
|
||||
if(H.has_trait(TRAIT_RADIMMUNE))
|
||||
radiation = 0
|
||||
return TRUE
|
||||
|
||||
@@ -1285,7 +1291,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
|
||||
add_logs(user, target, "shaked")
|
||||
return 1
|
||||
else
|
||||
var/we_breathe = (!(NOBREATH in user.dna.species.species_traits))
|
||||
var/we_breathe = !user.has_trait(TRAIT_NOBREATH)
|
||||
var/we_lung = user.getorganslot(ORGAN_SLOT_LUNGS)
|
||||
|
||||
if(we_breathe && we_lung)
|
||||
@@ -1483,7 +1489,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
|
||||
|
||||
//dismemberment
|
||||
var/probability = I.get_dismemberment_chance(affecting)
|
||||
if(prob(probability) || ((EASYDISMEMBER in species_traits) && prob(2*probability)))
|
||||
if(prob(probability) || (H.has_trait(TRAIT_EASYDISMEMBER) && prob(2*probability)))
|
||||
if(affecting.dismember(I.damtype))
|
||||
I.add_mob_blood(H)
|
||||
playsound(get_turf(H), I.get_dismember_sound(), 80, 1)
|
||||
@@ -1612,7 +1618,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
|
||||
/////////////
|
||||
|
||||
/datum/species/proc/breathe(mob/living/carbon/human/H)
|
||||
if(NOBREATH in species_traits)
|
||||
if(H.has_trait(TRAIT_NOBREATH))
|
||||
return TRUE
|
||||
|
||||
/datum/species/proc/handle_environment(datum/gas_mixture/environment, mob/living/carbon/human/H)
|
||||
@@ -1644,7 +1650,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
|
||||
H.adjust_bodytemperature(natural*(1/(thermal_protection+1)) + min(thermal_protection * (loc_temp - H.bodytemperature) / BODYTEMP_HEAT_DIVISOR, BODYTEMP_HEATING_MAX))
|
||||
|
||||
// +/- 50 degrees from 310K is the 'safe' zone, where no damage is dealt.
|
||||
if(H.bodytemperature > BODYTEMP_HEAT_DAMAGE_LIMIT && !(RESISTHOT in species_traits))
|
||||
if(H.bodytemperature > BODYTEMP_HEAT_DAMAGE_LIMIT && !H.has_trait(TRAIT_RESISTHEAT))
|
||||
//Body temperature is too hot.
|
||||
var/burn_damage
|
||||
switch(H.bodytemperature)
|
||||
@@ -1683,7 +1689,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
|
||||
var/adjusted_pressure = H.calculate_affecting_pressure(pressure) //Returns how much pressure actually affects the mob.
|
||||
switch(adjusted_pressure)
|
||||
if(HAZARD_HIGH_PRESSURE to INFINITY)
|
||||
if(!(RESISTPRESSURE in species_traits))
|
||||
if(!H.has_trait(TRAIT_RESISTHIGHPRESSURE))
|
||||
H.adjustBruteLoss(min(((adjusted_pressure / HAZARD_HIGH_PRESSURE) -1 ) * PRESSURE_DAMAGE_COEFFICIENT, MAX_HIGH_PRESSURE_DAMAGE) * H.physiology.pressure_mod)
|
||||
H.throw_alert("pressure", /obj/screen/alert/highpressure, 2)
|
||||
else
|
||||
@@ -1695,7 +1701,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
|
||||
if(HAZARD_LOW_PRESSURE to WARNING_LOW_PRESSURE)
|
||||
H.throw_alert("pressure", /obj/screen/alert/lowpressure, 1)
|
||||
else
|
||||
if(H.dna.check_mutation(COLDRES) || (RESISTPRESSURE in species_traits))
|
||||
if(H.has_trait(TRAIT_RESISTLOWPRESSURE))
|
||||
H.clear_alert("pressure")
|
||||
else
|
||||
H.adjustBruteLoss(LOW_PRESSURE_DAMAGE * H.physiology.pressure_mod)
|
||||
@@ -1706,7 +1712,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
|
||||
//////////
|
||||
|
||||
/datum/species/proc/handle_fire(mob/living/carbon/human/H, no_protection = FALSE)
|
||||
if(NOFIRE in species_traits)
|
||||
if(H.has_trait(TRAIT_NOFIRE))
|
||||
return
|
||||
if(H.on_fire)
|
||||
//the fire tries to damage the exposed clothes and items
|
||||
@@ -1773,7 +1779,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
|
||||
H.adjust_bodytemperature(BODYTEMP_HEATING_MAX + (H.fire_stacks * 12))
|
||||
|
||||
/datum/species/proc/CanIgniteMob(mob/living/carbon/human/H)
|
||||
if(NOFIRE in species_traits)
|
||||
if(H.has_trait(TRAIT_NOFIRE))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
|
||||
@@ -3,7 +3,8 @@
|
||||
id = "abductor"
|
||||
say_mod = "gibbers"
|
||||
sexes = FALSE
|
||||
species_traits = list(SPECIES_ORGANIC,NOBLOOD,NOBREATH,VIRUSIMMUNE,NOGUNS,NOHUNGER,NOEYES)
|
||||
species_traits = list(SPECIES_ORGANIC,NOBLOOD,NOEYES)
|
||||
inherent_traits = list(TRAIT_VIRUSIMMUNE,TRAIT_NOGUNS,TRAIT_NOHUNGER,TRAIT_NOBREATH)
|
||||
mutanttongue = /obj/item/organ/tongue/abductor
|
||||
var/scientist = FALSE // vars to not pollute spieces list with castes
|
||||
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
name = "Android"
|
||||
id = "android"
|
||||
say_mod = "states"
|
||||
species_traits = list(SPECIES_ROBOTIC,NOBREATH,RESISTHOT,RESISTCOLD,RESISTPRESSURE,NOFIRE,NOBLOOD,PIERCEIMMUNE,NOHUNGER,EASYLIMBATTACHMENT)
|
||||
species_traits = list(SPECIES_ROBOTIC,NOBLOOD)
|
||||
inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOFIRE,TRAIT_PIERCEIMMUNE,TRAIT_NOHUNGER,TRAIT_LIMBATTACHMENT)
|
||||
meat = null
|
||||
damage_overlay_type = "synth"
|
||||
mutanttongue = /obj/item/organ/tongue/robot
|
||||
|
||||
@@ -15,5 +15,6 @@
|
||||
attack_sound = 'sound/weapons/resonator_blast.ogg'
|
||||
blacklisted = 1
|
||||
use_skintones = 0
|
||||
species_traits = list(SPECIES_ORGANIC,RADIMMUNE,VIRUSIMMUNE,NOBLOOD,PIERCEIMMUNE,EYECOLOR,NODISMEMBER,NOHUNGER)
|
||||
sexes = 0
|
||||
species_traits = list(SPECIES_ORGANIC,NOBLOOD,EYECOLOR)
|
||||
inherent_traits = list(TRAIT_RADIMMUNE,TRAIT_VIRUSIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER,TRAIT_NOHUNGER)
|
||||
sexes = 0
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
name = "dullahan"
|
||||
id = "dullahan"
|
||||
default_color = "FFFFFF"
|
||||
species_traits = list(SPECIES_ORGANIC,EYECOLOR,HAIR,FACEHAIR,LIPS,NOBREATH,NOHUNGER)
|
||||
species_traits = list(SPECIES_ORGANIC,EYECOLOR,HAIR,FACEHAIR,LIPS)
|
||||
inherent_traits = list(TRAIT_NOHUNGER,TRAIT_NOBREATH)
|
||||
mutant_bodyparts = list("tail_human", "ears", "wings")
|
||||
default_features = list("mcolor" = "FFF", "tail_human" = "None", "ears" = "None", "wings" = "None")
|
||||
use_skintones = TRUE
|
||||
|
||||
@@ -248,7 +248,8 @@
|
||||
name = "Slimeperson"
|
||||
id = "slimeperson"
|
||||
default_color = "00FFFF"
|
||||
species_traits = list(SPECIES_ORGANIC,MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,NOBLOOD,TOXINLOVER)
|
||||
species_traits = list(SPECIES_ORGANIC,MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,NOBLOOD)
|
||||
inherent_traits = list(TRAIT_TOXINLOVER)
|
||||
mutant_bodyparts = list("mam_tail", "mam_ears", "taur")
|
||||
default_features = list("mcolor" = "FFF", "mam_tail" = "None", "mam_ears" = "None")
|
||||
say_mod = "says"
|
||||
@@ -351,3 +352,10 @@
|
||||
H.update_body()
|
||||
else
|
||||
return
|
||||
|
||||
//misc
|
||||
/mob/living/carbon/human/dummy
|
||||
no_vore = TRUE
|
||||
|
||||
/mob/living/carbon/human/vore
|
||||
devourable = TRUE
|
||||
@@ -2,7 +2,8 @@
|
||||
// Animated beings of stone. They have increased defenses, and do not need to breathe. They're also slow as fuuuck.
|
||||
name = "Golem"
|
||||
id = "iron golem"
|
||||
species_traits = list(SPECIES_INORGANIC,NOBREATH,RESISTHOT,RESISTCOLD,RESISTPRESSURE,NOFIRE,NOGUNS,NOBLOOD,RADIMMUNE,PIERCEIMMUNE,NODISMEMBER,MUTCOLORS,NO_UNDERWEAR)
|
||||
species_traits = list(SPECIES_INORGANIC,NOBLOOD,MUTCOLORS,NO_UNDERWEAR)
|
||||
inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOFIRE,TRAIT_NOGUNS,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER)
|
||||
mutant_organs = list(/obj/item/organ/adamantine_resonator)
|
||||
speedmod = 2
|
||||
armor = 55
|
||||
@@ -84,7 +85,7 @@
|
||||
fixed_mut_color = "a3d"
|
||||
meat = /obj/item/stack/ore/plasma
|
||||
//Can burn and takes damage from heat
|
||||
species_traits = list(SPECIES_INORGANIC,NOBREATH,RESISTCOLD,RESISTPRESSURE,NOGUNS,NOBLOOD,RADIMMUNE,PIERCEIMMUNE,NODISMEMBER,MUTCOLORS,NO_UNDERWEAR)
|
||||
inherent_traits = list(TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOGUNS,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER)
|
||||
info_text = "As a <span class='danger'>Plasma Golem</span>, you burn easily. Be careful, if you get hot enough while burning, you'll blow up!"
|
||||
heatmod = 0 //fine until they blow up
|
||||
prefix = "Plasma"
|
||||
@@ -258,7 +259,7 @@
|
||||
fixed_mut_color = "49311c"
|
||||
meat = /obj/item/stack/sheet/mineral/wood
|
||||
//Can burn and take damage from heat
|
||||
species_traits = list(SPECIES_ORGANIC,NOBREATH,RESISTCOLD,RESISTPRESSURE,NOGUNS,NOBLOOD,RADIMMUNE,PIERCEIMMUNE,NODISMEMBER,MUTCOLORS,NO_UNDERWEAR)
|
||||
inherent_traits = list(TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOGUNS,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER)
|
||||
armor = 30
|
||||
burnmod = 1.25
|
||||
heatmod = 1.5
|
||||
@@ -565,7 +566,7 @@
|
||||
limbs_id = "cultgolem"
|
||||
sexes = FALSE
|
||||
info_text = "As a <span class='danger'>Runic Golem</span>, you possess eldritch powers granted by the Elder God Nar'Sie."
|
||||
species_traits = list(SPECIES_INORGANIC,NOBREATH,RESISTHOT,RESISTCOLD,RESISTPRESSURE,NOFIRE,NOGUNS,NOBLOOD,RADIMMUNE,PIERCEIMMUNE,NODISMEMBER,NO_UNDERWEAR,NOEYES) //no mutcolors
|
||||
species_traits = list(SPECIES_INORGANIC,NOBLOOD,NO_UNDERWEAR,NOEYES) //no mutcolors
|
||||
prefix = "Runic"
|
||||
|
||||
var/obj/effect/proc_holder/spell/targeted/ethereal_jaunt/shift/golem/phase_shift
|
||||
@@ -619,7 +620,7 @@
|
||||
limbs_id = "clockgolem"
|
||||
info_text = "<span class='bold alloy'>As a </span><span class='bold brass'>clockwork golem</span><span class='bold alloy'>, you are faster than \
|
||||
other types of golem (being a machine), and are immune to electric shocks.</span>"
|
||||
species_traits = list(SPECIES_INORGANIC,NO_UNDERWEAR, NOTRANSSTING, NOBREATH, NOZOMBIE, RADIMMUNE, NOBLOOD, RESISTCOLD, RESISTPRESSURE, PIERCEIMMUNE, NOEYES)
|
||||
species_traits = list(SPECIES_ROBOTIC,NOBLOOD,NO_UNDERWEAR,NOEYES)
|
||||
armor = 20 //Reinforced, but much less so to allow for fast movement
|
||||
attack_verb = "smash"
|
||||
attack_sound = 'sound/magic/clockwork/anima_fragment_attack.ogg'
|
||||
@@ -671,7 +672,8 @@
|
||||
limbs_id = "clothgolem"
|
||||
sexes = FALSE
|
||||
info_text = "As a <span class='danger'>Cloth Golem</span>, you are able to reform yourself after death, provided your remains aren't burned or destroyed. You are, of course, very flammable."
|
||||
species_traits = list(SPECIES_UNDEAD,NOBREATH,RESISTCOLD,RESISTPRESSURE,NOGUNS,NOBLOOD,RADIMMUNE,PIERCEIMMUNE,NODISMEMBER,NO_UNDERWEAR) //no mutcolors, and can burn
|
||||
species_traits = list(SPECIES_UNDEAD,NOBLOOD,NO_UNDERWEAR) //no mutcolors, and can burn
|
||||
inherent_traits = list(TRAIT_RESISTCOLD,TRAIT_NOBREATH,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER,TRAIT_NOGUNS)
|
||||
armor = 15 //feels no pain, but not too resistant
|
||||
burnmod = 2 // don't get burned
|
||||
speedmod = 1 // not as heavy as stone
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
id = "jelly"
|
||||
default_color = "00FF90"
|
||||
say_mod = "chirps"
|
||||
species_traits = list(SPECIES_ORGANIC,MUTCOLORS,EYECOLOR,NOBLOOD,VIRUSIMMUNE,HAIR,FACEHAIR,TOXINLOVER) //CIT CHANGE - adds HAIR and FACEHAIR to species traits
|
||||
species_traits = list(SPECIES_ORGANIC,MUTCOLORS,EYECOLOR,,HAIR,FACEHAIR,NOBLOOD)
|
||||
inherent_traits = list(TRAIT_TOXINLOVER)
|
||||
mutant_bodyparts = list("mam_tail", "mam_ears", "taur") //CIT CHANGE
|
||||
default_features = list("mcolor" = "FFF", "mam_tail" = "None", "mam_ears" = "None") //CIT CHANGE
|
||||
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/slime
|
||||
@@ -118,6 +119,7 @@
|
||||
name = "Slimeperson"
|
||||
id = "slime"
|
||||
default_color = "00FFFF"
|
||||
species_traits = list(SPECIES_ORGANIC,MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,NOBLOOD)
|
||||
say_mod = "says"
|
||||
hair_color = "mutcolor"
|
||||
hair_alpha = 150
|
||||
|
||||
@@ -54,4 +54,5 @@
|
||||
name = "Ash Walker"
|
||||
id = "ashlizard"
|
||||
limbs_id = "lizard"
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,LIPS,NOBREATH,NOGUNS,DIGITIGRADE)
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,LIPS,DIGITIGRADE)
|
||||
inherent_traits = list(TRAIT_NOGUNS,TRAIT_NOBREATH)
|
||||
|
||||
@@ -4,7 +4,8 @@
|
||||
say_mod = "rattles"
|
||||
sexes = 0
|
||||
meat = /obj/item/stack/sheet/mineral/plasma
|
||||
species_traits = list(SPECIES_INORGANIC,NOBLOOD,RESISTCOLD,RADIMMUNE,NOTRANSSTING,NOHUNGER)
|
||||
species_traits = list(SPECIES_INORGANIC,NOBLOOD,NOTRANSSTING)
|
||||
inherent_traits = list(TRAIT_RESISTCOLD,TRAIT_RADIMMUNE,TRAIT_NOHUNGER)
|
||||
mutantlungs = /obj/item/organ/lungs/plasmaman
|
||||
mutanttongue = /obj/item/organ/tongue/bone/plasmaman
|
||||
mutantliver = /obj/item/organ/liver/plasmaman
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
blacklisted = 1
|
||||
ignored_by = list(/mob/living/simple_animal/hostile/faithless)
|
||||
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/shadow
|
||||
species_traits = list(SPECIES_ORGANIC,NOBREATH,NOBLOOD,RADIMMUNE,VIRUSIMMUNE,NOEYES)
|
||||
species_traits = list(SPECIES_ORGANIC,NOBLOOD,NOEYES)
|
||||
inherent_traits = list(TRAIT_RADIMMUNE,TRAIT_VIRUSIMMUNE,TRAIT_NOBREATH)
|
||||
|
||||
dangerous_existence = 1
|
||||
mutanteyes = /obj/item/organ/eyes/night_vision
|
||||
@@ -37,7 +38,8 @@
|
||||
burnmod = 1.5
|
||||
blacklisted = TRUE
|
||||
no_equip = list(slot_wear_mask, slot_wear_suit, slot_gloves, slot_shoes, slot_w_uniform, slot_s_store)
|
||||
species_traits = list(NOBREATH,RESISTCOLD,RESISTPRESSURE,NOGUNS,NOBLOOD,RADIMMUNE,VIRUSIMMUNE,PIERCEIMMUNE,NODISMEMBER,NO_UNDERWEAR,NOHUNGER,NO_DNA_COPY,NOTRANSSTING,NOEYES)
|
||||
species_traits = list(NOBLOOD,NO_UNDERWEAR,NO_DNA_COPY,NOTRANSSTING,NOEYES)
|
||||
inherent_traits = list(TRAIT_RESISTCOLD,TRAIT_NOBREATH,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOGUNS,TRAIT_RADIMMUNE,TRAIT_VIRUSIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER,TRAIT_NOHUNGER)
|
||||
mutanteyes = /obj/item/organ/eyes/night_vision/nightmare
|
||||
mutant_organs = list(/obj/item/organ/heart/nightmare)
|
||||
mutant_brain = /obj/item/organ/brain/nightmare
|
||||
|
||||
@@ -6,7 +6,8 @@
|
||||
blacklisted = 1
|
||||
sexes = 0
|
||||
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/skeleton
|
||||
species_traits = list(SPECIES_UNDEAD,NOBREATH,RESISTHOT,RESISTCOLD,RESISTPRESSURE,NOBLOOD,RADIMMUNE,PIERCEIMMUNE,NOHUNGER,EASYDISMEMBER,EASYLIMBATTACHMENT)
|
||||
species_traits = list(SPECIES_UNDEAD,NOBLOOD)
|
||||
inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NOHUNGER,TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT)
|
||||
mutanttongue = /obj/item/organ/tongue/bone
|
||||
damage_overlay_type = ""//let's not show bloody wounds or burns over bones.
|
||||
disliked_food = NONE
|
||||
|
||||
@@ -3,13 +3,15 @@
|
||||
id = "synth"
|
||||
say_mod = "beep boops" //inherited from a user's real species
|
||||
sexes = 0
|
||||
species_traits = list(SPECIES_ROBOTIC,NOTRANSSTING,NOBREATH,VIRUSIMMUNE,NODISMEMBER,NOHUNGER) //all of these + whatever we inherit from the real species
|
||||
species_traits = list(SPECIES_ROBOTIC,NOTRANSSTING) //all of these + whatever we inherit from the real species
|
||||
inherent_traits = list(TRAIT_VIRUSIMMUNE,TRAIT_NODISMEMBER,TRAIT_NOHUNGER,TRAIT_NOBREATH)
|
||||
dangerous_existence = 1
|
||||
blacklisted = 1
|
||||
meat = null
|
||||
damage_overlay_type = "synth"
|
||||
limbs_id = "synth"
|
||||
var/list/initial_species_traits = list(SPECIES_ROBOTIC,NOTRANSSTING,NOBREATH,VIRUSIMMUNE,NODISMEMBER,NOHUNGER,NO_DNA_COPY) //for getting these values back for assume_disguise()
|
||||
var/list/initial_species_traits = list(SPECIES_ROBOTIC,NOTRANSSTING) //for getting these values back for assume_disguise()
|
||||
var/list/initial_inherent_traits = list(TRAIT_VIRUSIMMUNE,TRAIT_NODISMEMBER,TRAIT_NOHUNGER,TRAIT_NOBREATH)
|
||||
var/disguise_fail_health = 75 //When their health gets to this level their synthflesh partially falls off
|
||||
var/datum/species/fake_species = null //a species to do most of our work for us, unless we're damaged
|
||||
|
||||
@@ -41,7 +43,9 @@
|
||||
say_mod = S.say_mod
|
||||
sexes = S.sexes
|
||||
species_traits = initial_species_traits.Copy()
|
||||
inherent_traits = initial_inherent_traits.Copy()
|
||||
species_traits |= S.species_traits
|
||||
inherent_traits |= S.inherent_traits
|
||||
species_traits -= list(SPECIES_ORGANIC, SPECIES_INORGANIC, SPECIES_UNDEAD)
|
||||
attack_verb = S.attack_verb
|
||||
attack_sound = S.attack_sound
|
||||
@@ -61,6 +65,7 @@
|
||||
name = initial(name)
|
||||
say_mod = initial(say_mod)
|
||||
species_traits = initial_species_traits.Copy()
|
||||
inherent_traits = initial_inherent_traits.Copy()
|
||||
attack_verb = initial(attack_verb)
|
||||
attack_sound = initial(attack_sound)
|
||||
miss_sound = initial(miss_sound)
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
name = "vampire"
|
||||
id = "vampire"
|
||||
default_color = "FFFFFF"
|
||||
species_traits = list(SPECIES_UNDEAD,EYECOLOR,HAIR,FACEHAIR,LIPS,NOHUNGER,NOBREATH,DRINKSBLOOD)
|
||||
species_traits = list(SPECIES_UNDEAD,EYECOLOR,HAIR,FACEHAIR,LIPS,DRINKSBLOOD)
|
||||
inherent_traits = list(TRAIT_NOHUNGER,TRAIT_NOBREATH)
|
||||
mutant_bodyparts = list("tail_human", "ears", "wings")
|
||||
default_features = list("mcolor" = "FFF", "tail_human" = "None", "ears" = "None", "wings" = "None")
|
||||
exotic_bloodtype = "U"
|
||||
|
||||
@@ -8,7 +8,8 @@
|
||||
sexes = 0
|
||||
blacklisted = 1
|
||||
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/zombie
|
||||
species_traits = list(SPECIES_UNDEAD,NOBREATH,RESISTCOLD,RESISTPRESSURE,NOBLOOD,RADIMMUNE,NOZOMBIE,EASYDISMEMBER,EASYLIMBATTACHMENT,NOTRANSSTING)
|
||||
species_traits = list(SPECIES_UNDEAD,NOBLOOD,NOZOMBIE,NOTRANSSTING)
|
||||
inherent_traits = list(TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_RADIMMUNE,TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT,TRAIT_NOBREATH)
|
||||
mutanttongue = /obj/item/organ/tongue/zombie
|
||||
var/static/list/spooks = list('sound/hallucinations/growl1.ogg','sound/hallucinations/growl2.ogg','sound/hallucinations/growl3.ogg','sound/hallucinations/veryfar_noise.ogg','sound/hallucinations/wail.ogg')
|
||||
disliked_food = NONE
|
||||
|
||||
@@ -52,6 +52,8 @@
|
||||
return
|
||||
if(ismob(loc))
|
||||
return
|
||||
if(istype(loc, /obj/belly))
|
||||
return
|
||||
|
||||
var/datum/gas_mixture/environment
|
||||
if(loc)
|
||||
@@ -102,7 +104,9 @@
|
||||
air_update_turf()
|
||||
|
||||
/mob/living/carbon/proc/has_smoke_protection()
|
||||
return 0
|
||||
if(has_trait(TRAIT_NOBREATH))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
|
||||
//Third link in a breath chain, calls handle_breath_temperature()
|
||||
@@ -249,7 +253,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()
|
||||
@@ -434,10 +438,10 @@
|
||||
L.damage += d
|
||||
|
||||
/mob/living/carbon/proc/liver_failure()
|
||||
if(reagents.get_reagent_amount("corazone"))//corazone is processed here an not in the liver because a failing liver can't metabolize reagents
|
||||
reagents.remove_reagent("corazone", 0.4) //corazone slowly deletes itself.
|
||||
reagents.metabolize(src, can_overdose=FALSE, liverless = TRUE)
|
||||
if(has_trait(TRAIT_STABLEHEART))
|
||||
return
|
||||
adjustToxLoss(8, TRUE, TRUE)
|
||||
adjustToxLoss(8, TRUE, TRUE)
|
||||
if(prob(30))
|
||||
to_chat(src, "<span class='notice'>You feel confused and nauseous...</span>")//actual symptoms of liver failure
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#define MAX_RANGE_FIND 32
|
||||
|
||||
/mob/living/carbon/monkey
|
||||
var/aggressive=0 // set to 1 using VV for an angry monkey
|
||||
@@ -475,3 +476,5 @@
|
||||
if(A)
|
||||
dropItemToGround(A, TRUE)
|
||||
update_icons()
|
||||
|
||||
#undef MAX_RANGE_FIND
|
||||
|
||||
@@ -54,9 +54,6 @@
|
||||
|
||||
handle_fire()
|
||||
|
||||
// Citadel Vore code for belly processes
|
||||
handle_internal_contents()
|
||||
|
||||
//stuff in the stomach
|
||||
handle_stomach()
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -50,7 +50,7 @@
|
||||
var/turf/T = get_turf(src)
|
||||
var/area/A = get_area(src)
|
||||
switch(requires_power)
|
||||
if(POWER_REQ_NONE)
|
||||
if(NONE)
|
||||
return FALSE
|
||||
if(POWER_REQ_ALL)
|
||||
return !T || !A || ((!A.power_equip || isspaceturf(T)) && !is_type_in_list(loc, list(/obj/item, /obj/mecha)))
|
||||
|
||||
@@ -154,6 +154,7 @@
|
||||
return 1
|
||||
return 0
|
||||
|
||||
#undef VOX_DELAY
|
||||
#endif
|
||||
|
||||
/mob/living/silicon/ai/could_speak_in_language(datum/language/dt)
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -340,12 +340,9 @@
|
||||
|
||||
/mob/living/simple_animal/hostile/construct/harvester/AttackingTarget()
|
||||
if(iscarbon(target))
|
||||
if(ishuman(target))
|
||||
var/mob/living/carbon/human/H = target
|
||||
if(H.dna && H.dna.species)
|
||||
if(NODISMEMBER in H.dna.species.species_traits)
|
||||
return ..() //ATTACK!
|
||||
var/mob/living/carbon/C = target
|
||||
if(C.has_trait(TRAIT_NODISMEMBER))
|
||||
return ..() //ATTACK!
|
||||
var/list/parts = list()
|
||||
var/undismembermerable_limbs = 0
|
||||
for(var/X in C.bodyparts)
|
||||
|
||||
@@ -106,7 +106,7 @@
|
||||
if(!search_objects)
|
||||
. = hearers(vision_range, targets_from) - src //Remove self, so we don't suicide
|
||||
|
||||
var/static/hostile_machines = typecacheof(list(/obj/machinery/porta_turret, /obj/mecha, /obj/structure/destructible/clockwork/ocular_warden))
|
||||
var/static/hostile_machines = typecacheof(list(/obj/machinery/porta_turret, /obj/mecha, /obj/structure/destructible/clockwork/ocular_warden,/obj/item/device/electronic_assembly))
|
||||
|
||||
for(var/HM in typecache_filter_list(range(vision_range, targets_from), hostile_machines))
|
||||
if(can_see(targets_from, HM, vision_range))
|
||||
@@ -209,6 +209,11 @@
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
if(istype(the_target, /obj/item/device/electronic_assembly))
|
||||
var/obj/item/device/electronic_assembly/O = the_target
|
||||
if(O.combat_circuits)
|
||||
return TRUE
|
||||
|
||||
if(istype(the_target, /obj/structure/destructible/clockwork/ocular_warden))
|
||||
var/obj/structure/destructible/clockwork/ocular_warden/OW = the_target
|
||||
if(OW.target != src)
|
||||
|
||||
@@ -1,26 +1,27 @@
|
||||
/mob/living/simple_animal/hostile/megafauna/dragon
|
||||
vore_active = TRUE
|
||||
no_vore = FALSE
|
||||
|
||||
/mob/living/simple_animal/hostile/megafauna/dragon/Initialize()
|
||||
// Create and register 'stomachs'
|
||||
var/datum/belly/megafauna/dragon/maw/maw = new(src)
|
||||
var/datum/belly/megafauna/dragon/gullet/gullet = new(src)
|
||||
var/datum/belly/megafauna/dragon/gut/gut = new(src)
|
||||
for(var/datum/belly/X in list(maw, gullet, gut))
|
||||
vore_organs[X.name] = X
|
||||
var/obj/belly/megafauna/dragon/maw/maw = new(src)
|
||||
var/obj/belly/megafauna/dragon/gullet/gullet = new(src)
|
||||
var/obj/belly/megafauna/dragon/gut/gut = new(src)
|
||||
// for(var/obj/belly/X in list(maw, gullet, gut))
|
||||
// vore_organs[X.name] = X
|
||||
// Connect 'stomachs' together
|
||||
maw.transferlocation = gullet
|
||||
gullet.transferlocation = gut
|
||||
vore_selected = maw.name // NPC eats into maw
|
||||
vore_selected = maw // NPC eats into maw
|
||||
return ..()
|
||||
|
||||
/datum/belly/megafauna/dragon
|
||||
/obj/belly/megafauna/dragon
|
||||
human_prey_swallow_time = 50 // maybe enough to switch targets if distracted
|
||||
nonhuman_prey_swallow_time = 50
|
||||
|
||||
/datum/belly/megafauna/dragon/maw
|
||||
/obj/belly/megafauna/dragon/maw
|
||||
name = "maw"
|
||||
inside_flavor = "The maw of the dreaded Ash drake closes around you, engulfing you into a swelteringly hot, disgusting enviroment. The acidic saliva tingles over your form while that tongue pushes you further back...towards the dark gullet beyond."
|
||||
desc = "The maw of the dreaded Ash drake closes around you, engulfing you into a swelteringly hot, disgusting enviroment. The acidic saliva tingles over your form while that tongue pushes you further back...towards the dark gullet beyond."
|
||||
vore_verb = "scoop"
|
||||
vore_sound = 'sound/vore/pred/taurswallow.ogg'
|
||||
swallow_time = 20
|
||||
@@ -30,9 +31,9 @@
|
||||
autotransferchance = 66
|
||||
autotransferwait = 200
|
||||
|
||||
/datum/belly/megafauna/dragon/gullet
|
||||
/obj/belly/megafauna/dragon/gullet
|
||||
name = "gullet"
|
||||
inside_flavor = "A ripple of muscle and arching of the tongue pushes you down like any other food. No choice in the matter, you're simply consumed. The dark ambiance of the outside world is replaced with working, wet flesh. Your only light being what you brought with you."
|
||||
desc = "A ripple of muscle and arching of the tongue pushes you down like any other food. No choice in the matter, you're simply consumed. The dark ambiance of the outside world is replaced with working, wet flesh. Your only light being what you brought with you."
|
||||
swallow_time = 60 // costs extra time to eat directly to here
|
||||
escapechance = 5
|
||||
// From above, will transfer into gut
|
||||
@@ -40,10 +41,10 @@
|
||||
autotransferchance = 50
|
||||
autotransferwait = 200
|
||||
|
||||
/datum/belly/megafauna/dragon/gut
|
||||
/obj/belly/megafauna/dragon/gut
|
||||
name = "stomach"
|
||||
vore_capacity = 5 //I doubt this many people will actually last in the gut, but...
|
||||
inside_flavor = "With a rush of burning ichor greeting you, you're introduced to the Drake's stomach. Wrinkled walls greedily grind against you, acidic slimes working into your body as you become fuel and nutriton for a superior predator. All that's left is your body's willingness to resist your destiny."
|
||||
desc = "With a rush of burning ichor greeting you, you're introduced to the Drake's stomach. Wrinkled walls greedily grind against you, acidic slimes working into your body as you become fuel and nutriton for a superior predator. All that's left is your body's willingness to resist your destiny."
|
||||
digest_mode = DM_DRAGON
|
||||
digest_burn = 5
|
||||
swallow_time = 100 // costs extra time to eat directly to here
|
||||
|
||||
@@ -101,15 +101,19 @@ GLOBAL_LIST_INIT(protected_objects, list(/obj/structure/table, /obj/structure/ca
|
||||
var/destroy_objects = 0
|
||||
var/knockdown_people = 0
|
||||
var/static/mutable_appearance/googly_eyes = mutable_appearance('icons/mob/mob.dmi', "googly_eyes")
|
||||
var/overlay_googly_eyes = TRUE
|
||||
var/idledamage = TRUE
|
||||
gold_core_spawnable = NO_SPAWN
|
||||
|
||||
/mob/living/simple_animal/hostile/mimic/copy/Initialize(mapload, obj/copy, mob/living/creator, destroy_original = 0)
|
||||
/mob/living/simple_animal/hostile/mimic/copy/Initialize(mapload, obj/copy, mob/living/creator, destroy_original = 0, no_googlies = FALSE)
|
||||
. = ..()
|
||||
if (no_googlies)
|
||||
overlay_googly_eyes = FALSE
|
||||
CopyObject(copy, creator, destroy_original)
|
||||
|
||||
/mob/living/simple_animal/hostile/mimic/copy/Life()
|
||||
..()
|
||||
if(!target && !ckey) //Objects eventually revert to normal if no one is around to terrorize
|
||||
if(idledamage && !target && !ckey) //Objects eventually revert to normal if no one is around to terrorize
|
||||
adjustBruteLoss(1)
|
||||
for(var/mob/living/M in contents) //a fix for animated statues from the flesh to stone spell
|
||||
death()
|
||||
@@ -143,7 +147,8 @@ GLOBAL_LIST_INIT(protected_objects, list(/obj/structure/table, /obj/structure/ca
|
||||
icon_state = O.icon_state
|
||||
icon_living = icon_state
|
||||
copy_overlays(O)
|
||||
add_overlay(googly_eyes)
|
||||
if (overlay_googly_eyes)
|
||||
add_overlay(googly_eyes)
|
||||
if(isstructure(O) || ismachinery(O))
|
||||
health = (anchored * 50) + 50
|
||||
destroy_objects = 1
|
||||
|
||||
@@ -103,7 +103,8 @@
|
||||
stack_trace("Simple animal being instantiated in nullspace")
|
||||
if(vore_active)
|
||||
init_belly()
|
||||
verbs |= /mob/living/proc/animal_nom
|
||||
if(!IsAdvancedToolUser())
|
||||
verbs |= /mob/living/simple_animal/proc/animal_nom
|
||||
|
||||
/mob/living/simple_animal/Destroy()
|
||||
GLOB.simple_animals[AIStatus] -= src
|
||||
|
||||
@@ -7,18 +7,18 @@
|
||||
var/vore_default_mode = DM_DIGEST // Default bellymode (DM_DIGEST, DM_HOLD, DM_ABSORB)
|
||||
var/vore_digest_chance = 25 // Chance to switch to digest mode if resisted
|
||||
var/vore_escape_chance = 25 // Chance of resisting out of mob
|
||||
var/vore_absorb_chance = 0 // chance of absorbtion by mob
|
||||
|
||||
var/vore_stomach_name // The name for the first belly if not "stomach"
|
||||
var/vore_stomach_flavor // The flavortext for the first belly if not the default
|
||||
|
||||
var/vore_fullness = 0 // How "full" the belly is (controls icons)
|
||||
var/list/living_mobs = list()
|
||||
|
||||
|
||||
// Release belly contents beforey being gc'd!
|
||||
/mob/living/simple_animal/Destroy()
|
||||
for(var/I in vore_organs)
|
||||
var/datum/belly/B = vore_organs[I]
|
||||
B.release_all_contents() // When your stomach is empty
|
||||
release_vore_contents()
|
||||
prey_excludes.Cut()
|
||||
. = ..()
|
||||
|
||||
@@ -34,10 +34,10 @@
|
||||
|
||||
vore_fullness = new_fullness
|
||||
|
||||
|
||||
/*
|
||||
/mob/living/simple_animal/proc/swallow_check()
|
||||
for(var/I in vore_organs)
|
||||
var/datum/belly/B = vore_organs[I]
|
||||
var/obj/belly/B = vore_organs[I]
|
||||
if(vore_active)
|
||||
update_fullness()
|
||||
if(!vore_fullness)
|
||||
@@ -48,16 +48,14 @@
|
||||
|
||||
/mob/living/simple_animal/proc/swallow_mob()
|
||||
for(var/I in vore_organs)
|
||||
var/datum/belly/B = vore_organs[I]
|
||||
for(var/mob/living/M in B.internal_contents)
|
||||
B.transfer_contents(M, B.transferlocation)
|
||||
|
||||
var/obj/belly/B = vore_organs[I]
|
||||
for(var/mob/living/M in B.contents)
|
||||
B.transfer_contents(M, transferlocation)
|
||||
*/
|
||||
|
||||
/mob/living/simple_animal/death()
|
||||
for(var/I in vore_organs)
|
||||
var/datum/belly/B = vore_organs[I]
|
||||
B.release_all_contents() // When your stomach is empty
|
||||
..() // then you have my permission to die.
|
||||
release_vore_contents()
|
||||
. = ..()
|
||||
|
||||
// Simple animals have only one belly. This creates it (if it isn't already set up)
|
||||
/mob/living/simple_animal/proc/init_belly()
|
||||
@@ -66,18 +64,19 @@
|
||||
if(no_vore) //If it can't vore, let's not give it a stomach.
|
||||
return
|
||||
|
||||
var/datum/belly/B = new /datum/belly(src)
|
||||
B.immutable = TRUE
|
||||
var/obj/belly/B = new /obj/belly(src)
|
||||
vore_selected = B
|
||||
B.immutable = 1
|
||||
B.name = vore_stomach_name ? vore_stomach_name : "stomach"
|
||||
B.inside_flavor = vore_stomach_flavor ? vore_stomach_flavor : "Your surroundings are warm, soft, and slimy. Makes sense, considering you're inside \the [name]."
|
||||
B.desc = vore_stomach_flavor ? vore_stomach_flavor : "Your surroundings are warm, soft, and slimy. Makes sense, considering you're inside \the [name]."
|
||||
B.digest_mode = vore_default_mode
|
||||
B.escapable = vore_escape_chance > 0
|
||||
B.escapechance = vore_escape_chance
|
||||
B.digestchance = vore_digest_chance
|
||||
B.absorbchance = vore_absorb_chance
|
||||
B.human_prey_swallow_time = swallowTime
|
||||
B.nonhuman_prey_swallow_time = swallowTime
|
||||
B.vore_verb = "swallow"
|
||||
// TODO - Customizable per mob
|
||||
B.emote_lists[DM_HOLD] = list( // We need more that aren't repetitive. I suck at endo. -Ace
|
||||
"The insides knead at you gently for a moment.",
|
||||
"The guts glorp wetly around you as some air shifts.",
|
||||
@@ -98,5 +97,21 @@
|
||||
"The juices pooling beneath you sizzle against your sore skin.",
|
||||
"The churning walls slowly pulverize you into meaty nutrients.",
|
||||
"The stomach glorps and gurgles as it tries to work you into slop.")
|
||||
src.vore_organs[B.name] = B
|
||||
src.vore_selected = B.name
|
||||
/* B.emote_lists[DM_ITEMWEAK] = list(
|
||||
"The burning acids eat away at your form.",
|
||||
"The muscular stomach flesh grinds harshly against you.",
|
||||
"The caustic air stings your chest when you try to breathe.",
|
||||
"The slimy guts squeeze inward to help the digestive juices soften you up.",
|
||||
"The onslaught against your body doesn't seem to be letting up; you're food now.",
|
||||
"The predator's body ripples and crushes against you as digestive enzymes pull you apart.",
|
||||
"The juices pooling beneath you sizzle against your sore skin.",
|
||||
"The churning walls slowly pulverize you into meaty nutrients.",
|
||||
"The stomach glorps and gurgles as it tries to work you into slop.")*/
|
||||
|
||||
//Grab = Nomf
|
||||
/*
|
||||
/mob/living/simple_animal/UnarmedAttack(var/atom/A, var/proximity)
|
||||
. = ..()
|
||||
|
||||
if(a_intent == I_GRAB && isliving(A) && !has_hands)
|
||||
animal_nom(A)*/
|
||||
@@ -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
|
||||
|
||||
@@ -98,7 +98,7 @@ proc/get_top_level_mob(var/mob/S)
|
||||
return FALSE
|
||||
|
||||
user.log_message(message, INDIVIDUAL_EMOTE_LOG)
|
||||
message = "<b>[user]</b> " + message
|
||||
message = "<b>[user]</b> " + "<i>[message]</i>"
|
||||
|
||||
for(var/mob/M in GLOB.dead_mob_list)
|
||||
if(!M.client || isnewplayer(M))
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -18,7 +18,6 @@ Contents:
|
||||
|
||||
#define INVALID_DRAIN "INVALID" //This one is if the drain proc needs to cancel, eg missing variables, etc, it's important.
|
||||
|
||||
#define DRAIN_RD_HACKED "RDHACK"
|
||||
#define DRAIN_RD_HACK_FAILED "RDHACKFAIL"
|
||||
#define DRAIN_MOB_SHOCK "MOBSHOCK"
|
||||
#define DRAIN_MOB_SHOCK_FAILED "MOBSHOCKFAIL"
|
||||
@@ -18,6 +18,11 @@ field_generator power level display
|
||||
#define FG_CHARGING 1
|
||||
#define FG_ONLINE 2
|
||||
|
||||
//field generator construction defines
|
||||
#define FG_UNSECURED 0
|
||||
#define FG_SECURED 1
|
||||
#define FG_WELDED 2
|
||||
|
||||
/obj/machinery/field/generator
|
||||
name = "field generator"
|
||||
desc = "A large thermal battery that projects a high amount of energy when powered."
|
||||
|
||||
@@ -25,7 +25,7 @@
|
||||
|
||||
/obj/machinery/power/tesla_coil/Initialize()
|
||||
. = ..()
|
||||
wires = new /datum/wires/tesla_coil(src)
|
||||
// wires = new /datum/wires/tesla_coil(src) //CITADEL EDIT, Kevinz you cheaty fuccboi.
|
||||
linked_techweb = SSresearch.science_tech
|
||||
|
||||
/obj/machinery/power/tesla_coil/RefreshParts()
|
||||
@@ -79,8 +79,6 @@
|
||||
/obj/machinery/power/tesla_coil/tesla_act(var/power)
|
||||
if(anchored && !panel_open)
|
||||
obj_flags |= BEING_SHOCKED
|
||||
//don't lose arc power when it's not connected to anything
|
||||
//please place tesla coils all around the station to maximize effectiveness
|
||||
var/power_produced = powernet ? power / power_loss : power
|
||||
add_avail(power_produced*input_power_multiplier)
|
||||
flick("coilhit", src)
|
||||
|
||||
@@ -81,14 +81,8 @@
|
||||
|
||||
|
||||
#define COMPFRICTION 5e5
|
||||
#define COMPSTARTERLOAD 2800
|
||||
|
||||
|
||||
// Crucial to make things work!!!!
|
||||
// OLD FIX - explanation given down below.
|
||||
// /obj/machinery/power/compressor/CanPass(atom/movable/mover, turf/target)
|
||||
// return !density
|
||||
|
||||
/obj/machinery/power/compressor/locate_machinery()
|
||||
if(turbine)
|
||||
return
|
||||
@@ -169,7 +163,6 @@
|
||||
// These are crucial to working of a turbine - the stats modify the power output. TurbGenQ modifies how much raw energy can you get from
|
||||
// rpms, TurbGenG modifies the shape of the curve - the lower the value the less straight the curve is.
|
||||
|
||||
#define TURBPRES 9000000
|
||||
#define TURBGENQ 100000
|
||||
#define TURBGENG 0.5
|
||||
|
||||
@@ -370,3 +363,7 @@
|
||||
if("reconnect")
|
||||
locate_machinery()
|
||||
. = TRUE
|
||||
|
||||
#undef COMPFRICTION
|
||||
#undef TURBGENQ
|
||||
#undef TURBGENG
|
||||
@@ -1,314 +0,0 @@
|
||||
// .357 (Syndie Revolver)
|
||||
|
||||
/obj/item/ammo_casing/a357
|
||||
name = ".357 bullet casing"
|
||||
desc = "A .357 bullet casing."
|
||||
caliber = "357"
|
||||
projectile_type = /obj/item/projectile/bullet/a357
|
||||
|
||||
// 7.62 (Nagant Rifle)
|
||||
|
||||
/obj/item/ammo_casing/a762
|
||||
name = "7.62 bullet casing"
|
||||
desc = "A 7.62 bullet casing."
|
||||
icon_state = "762-casing"
|
||||
caliber = "a762"
|
||||
projectile_type = /obj/item/projectile/bullet/a762
|
||||
|
||||
/obj/item/ammo_casing/a762/enchanted
|
||||
projectile_type = /obj/item/projectile/bullet/a762_enchanted
|
||||
|
||||
// 7.62x38mmR (Nagant Revolver)
|
||||
|
||||
/obj/item/ammo_casing/n762
|
||||
name = "7.62x38mmR bullet casing"
|
||||
desc = "A 7.62x38mmR bullet casing."
|
||||
caliber = "n762"
|
||||
projectile_type = /obj/item/projectile/bullet/n762
|
||||
|
||||
// .50AE (Desert Eagle)
|
||||
|
||||
/obj/item/ammo_casing/a50AE
|
||||
name = ".50AE bullet casing"
|
||||
desc = "A .50AE bullet casing."
|
||||
caliber = ".50"
|
||||
projectile_type = /obj/item/projectile/bullet/a50AE
|
||||
|
||||
// .38 (Detective's Gun)
|
||||
|
||||
/obj/item/ammo_casing/c38
|
||||
name = ".38 bullet casing"
|
||||
desc = "A .38 bullet casing."
|
||||
caliber = "38"
|
||||
projectile_type = /obj/item/projectile/bullet/c38
|
||||
|
||||
// 10mm (Stechkin)
|
||||
|
||||
/obj/item/ammo_casing/c10mm
|
||||
name = ".10mm bullet casing"
|
||||
desc = "A 10mm bullet casing."
|
||||
caliber = "10mm"
|
||||
projectile_type = /obj/item/projectile/bullet/c10mm
|
||||
|
||||
/obj/item/ammo_casing/c10mm/ap
|
||||
name = ".10mm armor-piercing bullet casing"
|
||||
desc = "A 10mm armor-piercing bullet casing."
|
||||
projectile_type = /obj/item/projectile/bullet/c10mm_ap
|
||||
|
||||
/obj/item/ammo_casing/c10mm/hp
|
||||
name = ".10mm hollow-point bullet casing"
|
||||
desc = "A 10mm hollow-point bullet casing."
|
||||
projectile_type = /obj/item/projectile/bullet/c10mm_hp
|
||||
|
||||
/obj/item/ammo_casing/c10mm/fire
|
||||
name = ".10mm incendiary bullet casing"
|
||||
desc = "A 10mm incendiary bullet casing."
|
||||
projectile_type = /obj/item/projectile/bullet/incendiary/c10mm
|
||||
|
||||
// 9mm (Stechkin APS)
|
||||
|
||||
/obj/item/ammo_casing/c9mm
|
||||
name = "9mm bullet casing"
|
||||
desc = "A 9mm bullet casing."
|
||||
caliber = "9mm"
|
||||
projectile_type = /obj/item/projectile/bullet/c9mm
|
||||
|
||||
/obj/item/ammo_casing/c9mm/ap
|
||||
name = "9mm armor-piercing bullet casing"
|
||||
desc = "A 9mm armor-piercing bullet casing."
|
||||
projectile_type =/obj/item/projectile/bullet/c9mm_ap
|
||||
|
||||
/obj/item/ammo_casing/c9mm/inc
|
||||
name = "9mm incendiary bullet casing"
|
||||
desc = "A 9mm incendiary bullet casing."
|
||||
projectile_type = /obj/item/projectile/bullet/incendiary/c9mm
|
||||
|
||||
// 4.6x30mm (Autorifles)
|
||||
|
||||
/obj/item/ammo_casing/c46x30mm
|
||||
name = "4.6x30mm bullet casing"
|
||||
desc = "A 4.6x30mm bullet casing."
|
||||
caliber = "4.6x30mm"
|
||||
projectile_type = /obj/item/projectile/bullet/c46x30mm
|
||||
|
||||
/obj/item/ammo_casing/c46x30mm/ap
|
||||
name = "4.6x30mm armor-piercing bullet casing"
|
||||
desc = "A 4.6x30mm armor-piercing bullet casing."
|
||||
projectile_type = /obj/item/projectile/bullet/c46x30mm_ap
|
||||
|
||||
/obj/item/ammo_casing/c46x30mm/inc
|
||||
name = "4.6x30mm incendiary bullet casing"
|
||||
desc = "A 4.6x30mm incendiary bullet casing."
|
||||
projectile_type = /obj/item/projectile/bullet/incendiary/c46x30mm
|
||||
|
||||
// .45 (M1911 + C20r)
|
||||
|
||||
/obj/item/ammo_casing/c45
|
||||
name = ".45 bullet casing"
|
||||
desc = "A .45 bullet casing."
|
||||
caliber = ".45"
|
||||
projectile_type = /obj/item/projectile/bullet/c45
|
||||
|
||||
/obj/item/ammo_casing/c45/nostamina
|
||||
projectile_type = /obj/item/projectile/bullet/c45_nostamina
|
||||
|
||||
// 5.56mm (M-90gl Carbine)
|
||||
|
||||
/obj/item/ammo_casing/a556
|
||||
name = "5.56mm bullet casing"
|
||||
desc = "A 5.56mm bullet casing."
|
||||
caliber = "a556"
|
||||
projectile_type = /obj/item/projectile/bullet/a556
|
||||
|
||||
// 40mm (Grenade Launcher)
|
||||
|
||||
/obj/item/ammo_casing/a40mm
|
||||
name = "40mm HE shell"
|
||||
desc = "A cased high explosive grenade that can only be activated once fired out of a grenade launcher."
|
||||
caliber = "40mm"
|
||||
icon_state = "40mmHE"
|
||||
projectile_type = /obj/item/projectile/bullet/a40mm
|
||||
|
||||
// .50 (Sniper)
|
||||
|
||||
/obj/item/ammo_casing/p50
|
||||
name = ".50 bullet casing"
|
||||
desc = "A .50 bullet casing."
|
||||
caliber = ".50"
|
||||
projectile_type = /obj/item/projectile/bullet/p50
|
||||
icon_state = ".50"
|
||||
|
||||
/obj/item/ammo_casing/p50/soporific
|
||||
name = ".50 soporific bullet casing"
|
||||
desc = "A .50 bullet casing, specialised in sending the target to sleep, instead of hell."
|
||||
projectile_type = /obj/item/projectile/bullet/p50/soporific
|
||||
icon_state = "sleeper"
|
||||
|
||||
/obj/item/ammo_casing/p50/penetrator
|
||||
name = ".50 penetrator round bullet casing"
|
||||
desc = "A .50 caliber penetrator round casing."
|
||||
projectile_type = /obj/item/projectile/bullet/p50/penetrator
|
||||
|
||||
// 1.95x129mm (SAW)
|
||||
|
||||
/obj/item/ammo_casing/mm195x129
|
||||
name = "1.95x129mm bullet casing"
|
||||
desc = "A 1.95x129mm bullet casing."
|
||||
icon_state = "762-casing"
|
||||
caliber = "mm195129"
|
||||
projectile_type = /obj/item/projectile/bullet/mm195x129
|
||||
|
||||
/obj/item/ammo_casing/mm195x129/ap
|
||||
name = "1.95x129mm armor-piercing bullet casing"
|
||||
desc = "A 1.95x129mm bullet casing designed with a hardened-tipped core to help penetrate armored targets."
|
||||
projectile_type = /obj/item/projectile/bullet/mm195x129_ap
|
||||
|
||||
/obj/item/ammo_casing/mm195x129/hollow
|
||||
name = "1.95x129mm hollow-point bullet casing"
|
||||
desc = "A 1.95x129mm bullet casing designed to cause more damage to unarmored targets."
|
||||
projectile_type = /obj/item/projectile/bullet/mm195x129_hp
|
||||
|
||||
/obj/item/ammo_casing/mm195x129/incen
|
||||
name = "1.95x129mm incendiary bullet casing"
|
||||
desc = "A 1.95x129mm bullet casing designed with a chemical-filled capsule on the tip that when bursted, reacts with the atmosphere to produce a fireball, engulfing the target in flames."
|
||||
projectile_type = /obj/item/projectile/bullet/incendiary/mm195x129
|
||||
|
||||
// Shotgun
|
||||
|
||||
/obj/item/ammo_casing/shotgun
|
||||
name = "shotgun slug"
|
||||
desc = "A 12 gauge lead slug."
|
||||
icon_state = "blshell"
|
||||
caliber = "shotgun"
|
||||
projectile_type = /obj/item/projectile/bullet/shotgun_slug
|
||||
materials = list(MAT_METAL=4000)
|
||||
|
||||
/obj/item/ammo_casing/shotgun/beanbag
|
||||
name = "beanbag slug"
|
||||
desc = "A weak beanbag slug for riot control."
|
||||
icon_state = "bshell"
|
||||
projectile_type = /obj/item/projectile/bullet/shotgun_beanbag
|
||||
materials = list(MAT_METAL=250)
|
||||
|
||||
/obj/item/ammo_casing/shotgun/incendiary
|
||||
name = "incendiary slug"
|
||||
desc = "An incendiary-coated shotgun slug."
|
||||
icon_state = "ishell"
|
||||
projectile_type = /obj/item/projectile/bullet/incendiary/shotgun
|
||||
|
||||
/obj/item/ammo_casing/shotgun/dragonsbreath
|
||||
name = "dragonsbreath shell"
|
||||
desc = "A shotgun shell which fires a spread of incendiary pellets."
|
||||
icon_state = "ishell2"
|
||||
projectile_type = /obj/item/projectile/bullet/incendiary/shotgun/dragonsbreath
|
||||
pellets = 4
|
||||
variance = 35
|
||||
|
||||
/obj/item/ammo_casing/shotgun/stunslug
|
||||
name = "taser slug"
|
||||
desc = "A stunning taser slug."
|
||||
icon_state = "stunshell"
|
||||
projectile_type = /obj/item/projectile/bullet/shotgun_stunslug
|
||||
materials = list(MAT_METAL=250)
|
||||
|
||||
/obj/item/ammo_casing/shotgun/meteorslug
|
||||
name = "meteorslug shell"
|
||||
desc = "A shotgun shell rigged with CMC technology, which launches a massive slug when fired."
|
||||
icon_state = "mshell"
|
||||
projectile_type = /obj/item/projectile/bullet/shotgun_meteorslug
|
||||
|
||||
/obj/item/ammo_casing/shotgun/pulseslug
|
||||
name = "pulse slug"
|
||||
desc = "A delicate device which can be loaded into a shotgun. The primer acts as a button which triggers the gain medium and fires a powerful \
|
||||
energy blast. While the heat and power drain limit it to one use, it can still allow an operator to engage targets that ballistic ammunition \
|
||||
would have difficulty with."
|
||||
icon_state = "pshell"
|
||||
projectile_type = /obj/item/projectile/beam/pulse/shotgun
|
||||
|
||||
/obj/item/ammo_casing/shotgun/frag12
|
||||
name = "FRAG-12 slug"
|
||||
desc = "A high explosive breaching round for a 12 gauge shotgun."
|
||||
icon_state = "heshell"
|
||||
projectile_type = /obj/item/projectile/bullet/shotgun_frag12
|
||||
|
||||
/obj/item/ammo_casing/shotgun/buckshot
|
||||
name = "buckshot shell"
|
||||
desc = "A 12 gauge buckshot shell."
|
||||
icon_state = "gshell"
|
||||
projectile_type = /obj/item/projectile/bullet/pellet/shotgun_buckshot
|
||||
pellets = 6
|
||||
variance = 25
|
||||
|
||||
/obj/item/ammo_casing/shotgun/rubbershot
|
||||
name = "rubber shot"
|
||||
desc = "A shotgun casing filled with densely-packed rubber balls, used to incapacitate crowds from a distance."
|
||||
icon_state = "bshell"
|
||||
projectile_type = /obj/item/projectile/bullet/pellet/shotgun_rubbershot
|
||||
pellets = 6
|
||||
variance = 25
|
||||
materials = list(MAT_METAL=4000)
|
||||
|
||||
/obj/item/ammo_casing/shotgun/improvised
|
||||
name = "improvised shell"
|
||||
desc = "An extremely weak shotgun shell with multiple small pellets made out of metal shards."
|
||||
icon_state = "improvshell"
|
||||
projectile_type = /obj/item/projectile/bullet/pellet/shotgun_improvised
|
||||
materials = list(MAT_METAL=250)
|
||||
pellets = 10
|
||||
variance = 25
|
||||
|
||||
/obj/item/ammo_casing/shotgun/ion
|
||||
name = "ion shell"
|
||||
desc = "An advanced shotgun shell which uses a subspace ansible crystal to produce an effect similar to a standard ion rifle. \
|
||||
The unique properties of the crystal split the pulse into a spread of individually weaker bolts."
|
||||
icon_state = "ionshell"
|
||||
projectile_type = /obj/item/projectile/ion/weak
|
||||
pellets = 4
|
||||
variance = 35
|
||||
|
||||
/obj/item/ammo_casing/shotgun/laserslug
|
||||
name = "laser slug"
|
||||
desc = "An advanced shotgun shell that uses a micro laser to replicate the effects of a laser weapon in a ballistic package."
|
||||
icon_state = "lshell"
|
||||
projectile_type = /obj/item/projectile/beam/laser
|
||||
|
||||
/obj/item/ammo_casing/shotgun/techshell
|
||||
name = "unloaded technological shell"
|
||||
desc = "A high-tech shotgun shell which can be loaded with materials to produce unique effects."
|
||||
icon_state = "cshell"
|
||||
projectile_type = null
|
||||
|
||||
/obj/item/ammo_casing/shotgun/dart
|
||||
name = "shotgun dart"
|
||||
desc = "A dart for use in shotguns. Can be injected with up to 30 units of any chemical."
|
||||
icon_state = "cshell"
|
||||
projectile_type = /obj/item/projectile/bullet/dart
|
||||
var/reagent_amount = 30
|
||||
var/reagent_react = TRUE
|
||||
|
||||
/obj/item/ammo_casing/shotgun/dart/noreact
|
||||
name = "cryostasis shotgun dart"
|
||||
desc = "A dart for use in shotguns, using similar technolgoy as cryostatis beakers to keep internal reagents from reacting. Can be injected with up to 10 units of any chemical."
|
||||
icon_state = "cnrshell"
|
||||
reagent_amount = 10
|
||||
reagent_react = FALSE
|
||||
|
||||
/obj/item/ammo_casing/shotgun/dart/Initialize()
|
||||
. = ..()
|
||||
container_type |= OPENCONTAINER
|
||||
create_reagents(reagent_amount)
|
||||
reagents.set_reacting(reagent_react)
|
||||
|
||||
/obj/item/ammo_casing/shotgun/dart/attackby()
|
||||
return
|
||||
|
||||
/obj/item/ammo_casing/shotgun/dart/bioterror
|
||||
desc = "A shotgun dart filled with deadly toxins."
|
||||
|
||||
/obj/item/ammo_casing/shotgun/dart/bioterror/Initialize()
|
||||
. = ..()
|
||||
reagents.add_reagent("neurotoxin", 6)
|
||||
reagents.add_reagent("spore", 6)
|
||||
reagents.add_reagent("mutetoxin", 6) //;HELP OPS IN MAINT
|
||||
reagents.add_reagent("coniine", 6)
|
||||
reagents.add_reagent("sodium_thiopental", 6)
|
||||
@@ -0,0 +1,23 @@
|
||||
// 1.95x129mm (SAW)
|
||||
|
||||
/obj/item/ammo_casing/mm195x129
|
||||
name = "1.95x129mm bullet casing"
|
||||
desc = "A 1.95x129mm bullet casing."
|
||||
icon_state = "762-casing"
|
||||
caliber = "mm195129"
|
||||
projectile_type = /obj/item/projectile/bullet/mm195x129
|
||||
|
||||
/obj/item/ammo_casing/mm195x129/ap
|
||||
name = "1.95x129mm armor-piercing bullet casing"
|
||||
desc = "A 1.95x129mm bullet casing designed with a hardened-tipped core to help penetrate armored targets."
|
||||
projectile_type = /obj/item/projectile/bullet/mm195x129_ap
|
||||
|
||||
/obj/item/ammo_casing/mm195x129/hollow
|
||||
name = "1.95x129mm hollow-point bullet casing"
|
||||
desc = "A 1.95x129mm bullet casing designed to cause more damage to unarmored targets."
|
||||
projectile_type = /obj/item/projectile/bullet/mm195x129_hp
|
||||
|
||||
/obj/item/ammo_casing/mm195x129/incen
|
||||
name = "1.95x129mm incendiary bullet casing"
|
||||
desc = "A 1.95x129mm bullet casing designed with a chemical-filled capsule on the tip that when bursted, reacts with the atmosphere to produce a fireball, engulfing the target in flames."
|
||||
projectile_type = /obj/item/projectile/bullet/incendiary/mm195x129
|
||||
@@ -0,0 +1,50 @@
|
||||
// 10mm (Stechkin)
|
||||
|
||||
/obj/item/ammo_casing/c10mm
|
||||
name = ".10mm bullet casing"
|
||||
desc = "A 10mm bullet casing."
|
||||
caliber = "10mm"
|
||||
projectile_type = /obj/item/projectile/bullet/c10mm
|
||||
|
||||
/obj/item/ammo_casing/c10mm/ap
|
||||
name = ".10mm armor-piercing bullet casing"
|
||||
desc = "A 10mm armor-piercing bullet casing."
|
||||
projectile_type = /obj/item/projectile/bullet/c10mm_ap
|
||||
|
||||
/obj/item/ammo_casing/c10mm/hp
|
||||
name = ".10mm hollow-point bullet casing"
|
||||
desc = "A 10mm hollow-point bullet casing."
|
||||
projectile_type = /obj/item/projectile/bullet/c10mm_hp
|
||||
|
||||
/obj/item/ammo_casing/c10mm/fire
|
||||
name = ".10mm incendiary bullet casing"
|
||||
desc = "A 10mm incendiary bullet casing."
|
||||
projectile_type = /obj/item/projectile/bullet/incendiary/c10mm
|
||||
|
||||
// 9mm (Stechkin APS)
|
||||
|
||||
/obj/item/ammo_casing/c9mm
|
||||
name = "9mm bullet casing"
|
||||
desc = "A 9mm bullet casing."
|
||||
caliber = "9mm"
|
||||
projectile_type = /obj/item/projectile/bullet/c9mm
|
||||
|
||||
/obj/item/ammo_casing/c9mm/ap
|
||||
name = "9mm armor-piercing bullet casing"
|
||||
desc = "A 9mm armor-piercing bullet casing."
|
||||
projectile_type =/obj/item/projectile/bullet/c9mm_ap
|
||||
|
||||
/obj/item/ammo_casing/c9mm/inc
|
||||
name = "9mm incendiary bullet casing"
|
||||
desc = "A 9mm incendiary bullet casing."
|
||||
projectile_type = /obj/item/projectile/bullet/incendiary/c9mm
|
||||
|
||||
|
||||
// .50AE (Desert Eagle)
|
||||
|
||||
/obj/item/ammo_casing/a50AE
|
||||
name = ".50AE bullet casing"
|
||||
desc = "A .50AE bullet casing."
|
||||
caliber = ".50"
|
||||
projectile_type = /obj/item/projectile/bullet/a50AE
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
// .357 (Syndie Revolver)
|
||||
|
||||
/obj/item/ammo_casing/a357
|
||||
name = ".357 bullet casing"
|
||||
desc = "A .357 bullet casing."
|
||||
caliber = "357"
|
||||
projectile_type = /obj/item/projectile/bullet/a357
|
||||
|
||||
// 7.62x38mmR (Nagant Revolver)
|
||||
|
||||
/obj/item/ammo_casing/n762
|
||||
name = "7.62x38mmR bullet casing"
|
||||
desc = "A 7.62x38mmR bullet casing."
|
||||
caliber = "n762"
|
||||
projectile_type = /obj/item/projectile/bullet/n762
|
||||
|
||||
// .38 (Detective's Gun)
|
||||
|
||||
/obj/item/ammo_casing/c38
|
||||
name = ".38 bullet casing"
|
||||
desc = "A .38 bullet casing."
|
||||
caliber = "38"
|
||||
projectile_type = /obj/item/projectile/bullet/c38
|
||||
@@ -0,0 +1,28 @@
|
||||
// 7.62 (Nagant Rifle)
|
||||
|
||||
/obj/item/ammo_casing/a762
|
||||
name = "7.62 bullet casing"
|
||||
desc = "A 7.62 bullet casing."
|
||||
icon_state = "762-casing"
|
||||
caliber = "a762"
|
||||
projectile_type = /obj/item/projectile/bullet/a762
|
||||
|
||||
/obj/item/ammo_casing/a762/enchanted
|
||||
projectile_type = /obj/item/projectile/bullet/a762_enchanted
|
||||
|
||||
// 5.56mm (M-90gl Carbine)
|
||||
|
||||
/obj/item/ammo_casing/a556
|
||||
name = "5.56mm bullet casing"
|
||||
desc = "A 5.56mm bullet casing."
|
||||
caliber = "a556"
|
||||
projectile_type = /obj/item/projectile/bullet/a556
|
||||
|
||||
// 40mm (Grenade Launcher)
|
||||
|
||||
/obj/item/ammo_casing/a40mm
|
||||
name = "40mm HE shell"
|
||||
desc = "A cased high explosive grenade that can only be activated once fired out of a grenade launcher."
|
||||
caliber = "40mm"
|
||||
icon_state = "40mmHE"
|
||||
projectile_type = /obj/item/projectile/bullet/a40mm
|
||||
@@ -0,0 +1,139 @@
|
||||
// Shotgun
|
||||
|
||||
/obj/item/ammo_casing/shotgun
|
||||
name = "shotgun slug"
|
||||
desc = "A 12 gauge lead slug."
|
||||
icon_state = "blshell"
|
||||
caliber = "shotgun"
|
||||
projectile_type = /obj/item/projectile/bullet/shotgun_slug
|
||||
materials = list(MAT_METAL=4000)
|
||||
|
||||
/obj/item/ammo_casing/shotgun/beanbag
|
||||
name = "beanbag slug"
|
||||
desc = "A weak beanbag slug for riot control."
|
||||
icon_state = "bshell"
|
||||
projectile_type = /obj/item/projectile/bullet/shotgun_beanbag
|
||||
materials = list(MAT_METAL=250)
|
||||
|
||||
/obj/item/ammo_casing/shotgun/incendiary
|
||||
name = "incendiary slug"
|
||||
desc = "An incendiary-coated shotgun slug."
|
||||
icon_state = "ishell"
|
||||
projectile_type = /obj/item/projectile/bullet/incendiary/shotgun
|
||||
|
||||
/obj/item/ammo_casing/shotgun/dragonsbreath
|
||||
name = "dragonsbreath shell"
|
||||
desc = "A shotgun shell which fires a spread of incendiary pellets."
|
||||
icon_state = "ishell2"
|
||||
projectile_type = /obj/item/projectile/bullet/incendiary/shotgun/dragonsbreath
|
||||
pellets = 4
|
||||
variance = 35
|
||||
|
||||
/obj/item/ammo_casing/shotgun/stunslug
|
||||
name = "taser slug"
|
||||
desc = "A stunning taser slug."
|
||||
icon_state = "stunshell"
|
||||
projectile_type = /obj/item/projectile/bullet/shotgun_stunslug
|
||||
materials = list(MAT_METAL=250)
|
||||
|
||||
/obj/item/ammo_casing/shotgun/meteorslug
|
||||
name = "meteorslug shell"
|
||||
desc = "A shotgun shell rigged with CMC technology, which launches a massive slug when fired."
|
||||
icon_state = "mshell"
|
||||
projectile_type = /obj/item/projectile/bullet/shotgun_meteorslug
|
||||
|
||||
/obj/item/ammo_casing/shotgun/pulseslug
|
||||
name = "pulse slug"
|
||||
desc = "A delicate device which can be loaded into a shotgun. The primer acts as a button which triggers the gain medium and fires a powerful \
|
||||
energy blast. While the heat and power drain limit it to one use, it can still allow an operator to engage targets that ballistic ammunition \
|
||||
would have difficulty with."
|
||||
icon_state = "pshell"
|
||||
projectile_type = /obj/item/projectile/beam/pulse/shotgun
|
||||
|
||||
/obj/item/ammo_casing/shotgun/frag12
|
||||
name = "FRAG-12 slug"
|
||||
desc = "A high explosive breaching round for a 12 gauge shotgun."
|
||||
icon_state = "heshell"
|
||||
projectile_type = /obj/item/projectile/bullet/shotgun_frag12
|
||||
|
||||
/obj/item/ammo_casing/shotgun/buckshot
|
||||
name = "buckshot shell"
|
||||
desc = "A 12 gauge buckshot shell."
|
||||
icon_state = "gshell"
|
||||
projectile_type = /obj/item/projectile/bullet/pellet/shotgun_buckshot
|
||||
pellets = 6
|
||||
variance = 25
|
||||
|
||||
/obj/item/ammo_casing/shotgun/rubbershot
|
||||
name = "rubber shot"
|
||||
desc = "A shotgun casing filled with densely-packed rubber balls, used to incapacitate crowds from a distance."
|
||||
icon_state = "bshell"
|
||||
projectile_type = /obj/item/projectile/bullet/pellet/shotgun_rubbershot
|
||||
pellets = 6
|
||||
variance = 25
|
||||
materials = list(MAT_METAL=4000)
|
||||
|
||||
/obj/item/ammo_casing/shotgun/improvised
|
||||
name = "improvised shell"
|
||||
desc = "An extremely weak shotgun shell with multiple small pellets made out of metal shards."
|
||||
icon_state = "improvshell"
|
||||
projectile_type = /obj/item/projectile/bullet/pellet/shotgun_improvised
|
||||
materials = list(MAT_METAL=250)
|
||||
pellets = 10
|
||||
variance = 25
|
||||
|
||||
/obj/item/ammo_casing/shotgun/ion
|
||||
name = "ion shell"
|
||||
desc = "An advanced shotgun shell which uses a subspace ansible crystal to produce an effect similar to a standard ion rifle. \
|
||||
The unique properties of the crystal split the pulse into a spread of individually weaker bolts."
|
||||
icon_state = "ionshell"
|
||||
projectile_type = /obj/item/projectile/ion/weak
|
||||
pellets = 4
|
||||
variance = 35
|
||||
|
||||
/obj/item/ammo_casing/shotgun/laserslug
|
||||
name = "laser slug"
|
||||
desc = "An advanced shotgun shell that uses a micro laser to replicate the effects of a laser weapon in a ballistic package."
|
||||
icon_state = "lshell"
|
||||
projectile_type = /obj/item/projectile/beam/laser
|
||||
|
||||
/obj/item/ammo_casing/shotgun/techshell
|
||||
name = "unloaded technological shell"
|
||||
desc = "A high-tech shotgun shell which can be loaded with materials to produce unique effects."
|
||||
icon_state = "cshell"
|
||||
projectile_type = null
|
||||
|
||||
/obj/item/ammo_casing/shotgun/dart
|
||||
name = "shotgun dart"
|
||||
desc = "A dart for use in shotguns. Can be injected with up to 30 units of any chemical."
|
||||
icon_state = "cshell"
|
||||
projectile_type = /obj/item/projectile/bullet/dart
|
||||
var/reagent_amount = 30
|
||||
var/reagent_react = TRUE
|
||||
|
||||
/obj/item/ammo_casing/shotgun/dart/noreact
|
||||
name = "cryostasis shotgun dart"
|
||||
desc = "A dart for use in shotguns, using similar technolgoy as cryostatis beakers to keep internal reagents from reacting. Can be injected with up to 10 units of any chemical."
|
||||
icon_state = "cnrshell"
|
||||
reagent_amount = 10
|
||||
reagent_react = FALSE
|
||||
|
||||
/obj/item/ammo_casing/shotgun/dart/Initialize()
|
||||
. = ..()
|
||||
container_type |= OPENCONTAINER
|
||||
create_reagents(reagent_amount)
|
||||
reagents.set_reacting(reagent_react)
|
||||
|
||||
/obj/item/ammo_casing/shotgun/dart/attackby()
|
||||
return
|
||||
|
||||
/obj/item/ammo_casing/shotgun/dart/bioterror
|
||||
desc = "A shotgun dart filled with deadly toxins."
|
||||
|
||||
/obj/item/ammo_casing/shotgun/dart/bioterror/Initialize()
|
||||
. = ..()
|
||||
reagents.add_reagent("neurotoxin", 6)
|
||||
reagents.add_reagent("spore", 6)
|
||||
reagents.add_reagent("mutetoxin", 6) //;HELP OPS IN MAINT
|
||||
reagents.add_reagent("coniine", 6)
|
||||
reagents.add_reagent("sodium_thiopental", 6)
|
||||
@@ -0,0 +1,28 @@
|
||||
// 4.6x30mm (Autorifles)
|
||||
|
||||
/obj/item/ammo_casing/c46x30mm
|
||||
name = "4.6x30mm bullet casing"
|
||||
desc = "A 4.6x30mm bullet casing."
|
||||
caliber = "4.6x30mm"
|
||||
projectile_type = /obj/item/projectile/bullet/c46x30mm
|
||||
|
||||
/obj/item/ammo_casing/c46x30mm/ap
|
||||
name = "4.6x30mm armor-piercing bullet casing"
|
||||
desc = "A 4.6x30mm armor-piercing bullet casing."
|
||||
projectile_type = /obj/item/projectile/bullet/c46x30mm_ap
|
||||
|
||||
/obj/item/ammo_casing/c46x30mm/inc
|
||||
name = "4.6x30mm incendiary bullet casing"
|
||||
desc = "A 4.6x30mm incendiary bullet casing."
|
||||
projectile_type = /obj/item/projectile/bullet/incendiary/c46x30mm
|
||||
|
||||
// .45 (M1911 + C20r)
|
||||
|
||||
/obj/item/ammo_casing/c45
|
||||
name = ".45 bullet casing"
|
||||
desc = "A .45 bullet casing."
|
||||
caliber = ".45"
|
||||
projectile_type = /obj/item/projectile/bullet/c45
|
||||
|
||||
/obj/item/ammo_casing/c45/nostamina
|
||||
projectile_type = /obj/item/projectile/bullet/c45_nostamina
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user