Merge branch 'master' of https://github.com/Citadel-Station-13/Citadel-Station-13 into Ghommie-cit156
This commit is contained in:
@@ -30,5 +30,8 @@
|
||||
loc = destination
|
||||
Moved(oldloc, NONE, TRUE)
|
||||
|
||||
/mob/camera/canUseStorage()
|
||||
return FALSE
|
||||
|
||||
/mob/camera/emote(act, m_type=1, message = null, intentional = FALSE)
|
||||
return
|
||||
|
||||
@@ -20,6 +20,9 @@ INITIALIZE_IMMEDIATE(/mob/dead)
|
||||
set_focus(src)
|
||||
return INITIALIZE_HINT_NORMAL
|
||||
|
||||
/mob/dead/canUseStorage()
|
||||
return FALSE
|
||||
|
||||
/mob/dead/dust(just_ash, drop_items, force) //ghosts can't be vaporised.
|
||||
return
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -558,7 +558,7 @@
|
||||
|
||||
/datum/sprite_accessory/mam_tails_animated/horse
|
||||
name = "Horse"
|
||||
icon_state = "Horse"
|
||||
icon_state = "horse"
|
||||
color_src = HAIR
|
||||
|
||||
/datum/sprite_accessory/mam_tails/husky
|
||||
|
||||
@@ -27,6 +27,88 @@
|
||||
dimension_y = 34
|
||||
locked = TRUE
|
||||
|
||||
// Decorative wings
|
||||
/datum/sprite_accessory/deco_wings
|
||||
icon = 'icons/mob/wings.dmi'
|
||||
|
||||
/datum/sprite_accessory/deco_wings/plain
|
||||
name = "Plain"
|
||||
icon_state = "plain"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/monarch
|
||||
name = "Monarch"
|
||||
icon_state = "monarch"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/luna
|
||||
name = "Luna"
|
||||
icon_state = "luna"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/atlas
|
||||
name = "Atlas"
|
||||
icon_state = "atlas"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/reddish
|
||||
name = "Reddish"
|
||||
icon_state = "redish"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/royal
|
||||
name = "Royal"
|
||||
icon_state = "royal"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/gothic
|
||||
name = "Gothic"
|
||||
icon_state = "gothic"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/lovers
|
||||
name = "Lovers"
|
||||
icon_state = "lovers"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/whitefly
|
||||
name = "White Fly"
|
||||
icon_state = "whitefly"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/punished
|
||||
name = "Burnt Off"
|
||||
icon_state = "punished"
|
||||
locked = TRUE
|
||||
|
||||
/datum/sprite_accessory/deco_wings/firewatch
|
||||
name = "Firewatch"
|
||||
icon_state = "firewatch"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/deathhead
|
||||
name = "Deathshead"
|
||||
icon_state = "deathhead"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/poison
|
||||
name = "Poison"
|
||||
icon_state = "poison"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/ragged
|
||||
name = "Ragged"
|
||||
icon_state = "ragged"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/moonfly
|
||||
name = "Moon Fly"
|
||||
icon_state = "moonfly"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/snow
|
||||
name = "Snow"
|
||||
icon_state = "snow"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/angel
|
||||
name = "Angel"
|
||||
icon_state = "angel"
|
||||
color_src = 0
|
||||
dimension_x = 46
|
||||
center = TRUE
|
||||
dimension_y = 34
|
||||
|
||||
/datum/sprite_accessory/deco_wings/none
|
||||
name = "None"
|
||||
icon_state = "none"
|
||||
|
||||
|
||||
//INSECT WINGS
|
||||
|
||||
/datum/sprite_accessory/insect_wings
|
||||
@@ -76,7 +158,6 @@
|
||||
/datum/sprite_accessory/insect_wings/punished
|
||||
name = "Burnt Off"
|
||||
icon_state = "punished"
|
||||
locked = TRUE
|
||||
|
||||
/datum/sprite_accessory/insect_wings/firewatch
|
||||
name = "Firewatch"
|
||||
|
||||
@@ -260,16 +260,16 @@ Transfer_mind is there to check if mob is being deleted/not going to have a body
|
||||
Works together with spawning an observer, noted above.
|
||||
*/
|
||||
|
||||
/mob/proc/ghostize(can_reenter_corpse = 1)
|
||||
if(key)
|
||||
if(!cmptext(copytext(key,1,2),"@")) // Skip aghosts.
|
||||
stop_sound_channel(CHANNEL_HEARTBEAT) //Stop heartbeat sounds because You Are A Ghost Now
|
||||
var/mob/dead/observer/ghost = new(src) // Transfer safety to observer spawning proc.
|
||||
SStgui.on_transfer(src, ghost) // Transfer NanoUIs.
|
||||
ghost.can_reenter_corpse = can_reenter_corpse
|
||||
ghost.can_reenter_round = (can_reenter_corpse && !suiciding)
|
||||
ghost.key = key
|
||||
return ghost
|
||||
/mob/proc/ghostize(can_reenter_corpse = TRUE, special = FALSE)
|
||||
if(!key || cmptext(copytext(key,1,2),"@") || (!special && SEND_SIGNAL(src, COMSIG_MOB_GHOSTIZE, can_reenter_corpse, special) & COMPONENT_BLOCK_GHOSTING))
|
||||
return //mob has no key, is an aghost or some component hijacked.
|
||||
stop_sound_channel(CHANNEL_HEARTBEAT) //Stop heartbeat sounds because You Are A Ghost Now
|
||||
var/mob/dead/observer/ghost = new(src) // Transfer safety to observer spawning proc.
|
||||
SStgui.on_transfer(src, ghost) // Transfer NanoUIs.
|
||||
ghost.can_reenter_corpse = can_reenter_corpse
|
||||
ghost.can_reenter_round = (can_reenter_corpse && !suiciding)
|
||||
transfer_ckey(ghost, FALSE)
|
||||
return ghost
|
||||
|
||||
/*
|
||||
This is the proc mobs get to turn into a ghost. Forked from ghostize due to compatibility issues.
|
||||
@@ -280,6 +280,9 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
set name = "Ghost"
|
||||
set desc = "Relinquish your life and enter the land of the dead."
|
||||
|
||||
if(SEND_SIGNAL(src, COMSIG_MOB_GHOSTIZE, (stat == DEAD) ? TRUE : FALSE, FALSE) & COMPONENT_BLOCK_GHOSTING)
|
||||
return
|
||||
|
||||
// CITADEL EDIT
|
||||
if(istype(loc, /obj/machinery/cryopod))
|
||||
var/response = alert(src, "Are you -sure- you want to ghost?\n(You are alive. If you ghost whilst still alive you won't be able to re-enter this round! You can't change your mind so choose wisely!!)","Are you sure you want to ghost?","Ghost","Stay in body")
|
||||
@@ -306,6 +309,9 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
set name = "Ghost"
|
||||
set desc = "Relinquish your life and enter the land of the dead."
|
||||
|
||||
if(SEND_SIGNAL(src, COMSIG_MOB_GHOSTIZE, FALSE, FALSE) & COMPONENT_BLOCK_GHOSTING)
|
||||
return
|
||||
|
||||
var/response = alert(src, "Are you -sure- you want to ghost?\n(You are alive. If you ghost whilst still alive you won't be able to re-enter this round! You can't change your mind so choose wisely!!)","Are you sure you want to ghost?","Ghost","Stay in body")
|
||||
if(response != "Ghost")
|
||||
return
|
||||
@@ -348,7 +354,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
return
|
||||
client.change_view(CONFIG_GET(string/default_view))
|
||||
SStgui.on_transfer(src, mind.current) // Transfer NanoUIs.
|
||||
mind.current.key = key
|
||||
transfer_ckey(mind.current, FALSE)
|
||||
return 1
|
||||
|
||||
/mob/dead/observer/proc/notify_cloning(var/message, var/sound, var/atom/source, flashwindow = TRUE)
|
||||
@@ -628,7 +634,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
to_chat(src, "<span class='warning'>Someone has taken this body while you were choosing!</span>")
|
||||
return 0
|
||||
|
||||
target.key = key
|
||||
transfer_ckey(target, FALSE)
|
||||
target.faction = list("neutral")
|
||||
return 1
|
||||
|
||||
|
||||
@@ -158,7 +158,7 @@
|
||||
|
||||
//Returns if a certain item can be equipped to a certain slot.
|
||||
// Currently invalid for two-handed items - call obj/item/mob_can_equip() instead.
|
||||
/mob/proc/can_equip(obj/item/I, slot, disable_warning = 0)
|
||||
/mob/proc/can_equip(obj/item/I, slot, disable_warning = FALSE, bypass_equip_delay_self = FALSE)
|
||||
return FALSE
|
||||
|
||||
/mob/proc/can_put_in_hand(I, hand_index)
|
||||
|
||||
@@ -57,13 +57,14 @@
|
||||
newbrain.brainmob = null
|
||||
brainmob.forceMove(src)
|
||||
brainmob.container = src
|
||||
if(!newbrain.damaged_brain) // the brain organ hasn't been beaten to death.
|
||||
if(!(newbrain.organ_flags & ORGAN_FAILING)) // the brain organ hasn't been beaten to death.
|
||||
brainmob.stat = CONSCIOUS //we manually revive the brain mob
|
||||
GLOB.dead_mob_list -= brainmob
|
||||
GLOB.alive_mob_list += brainmob
|
||||
|
||||
brainmob.reset_perspective()
|
||||
brain = newbrain
|
||||
brain.organ_flags |= ORGAN_FROZEN
|
||||
|
||||
name = "Man-Machine Interface: [brainmob.real_name]"
|
||||
update_icon()
|
||||
@@ -100,6 +101,7 @@
|
||||
user.put_in_hands(brain) //puts brain in the user's hand or otherwise drops it on the user's turf
|
||||
else
|
||||
brain.forceMove(get_turf(src))
|
||||
brain.organ_flags &= ~ORGAN_FROZEN
|
||||
brain = null //No more brain in here
|
||||
|
||||
|
||||
|
||||
@@ -7,11 +7,20 @@
|
||||
layer = ABOVE_MOB_LAYER
|
||||
zone = BODY_ZONE_HEAD
|
||||
slot = ORGAN_SLOT_BRAIN
|
||||
vital = TRUE
|
||||
organ_flags = ORGAN_VITAL
|
||||
attack_verb = list("attacked", "slapped", "whacked")
|
||||
///The brain's organ variables are significantly more different than the other organs, with half the decay rate for balance reasons, and twice the maxHealth
|
||||
decay_factor = STANDARD_ORGAN_DECAY / 4 //30 minutes of decaying to result in a fully damaged brain, since a fast decay rate would be unfun gameplay-wise
|
||||
healing_factor = STANDARD_ORGAN_HEALING / 2
|
||||
|
||||
maxHealth = BRAIN_DAMAGE_DEATH
|
||||
low_threshold = 45
|
||||
high_threshold = 120
|
||||
var/mob/living/brain/brainmob = null
|
||||
var/damaged_brain = FALSE //whether the brain organ is damaged.
|
||||
var/brain_death = FALSE //if the brainmob was intentionally killed by attacking the brain after removal, or by severe braindamage
|
||||
var/decoy_override = FALSE //I apologize to the security players, and myself, who abused this, but this is going to go.
|
||||
//two variables necessary for calculating whether we get a brain trauma or not
|
||||
var/damage_delta = 0
|
||||
|
||||
var/list/datum/brain_trauma/traumas = list()
|
||||
|
||||
@@ -34,7 +43,7 @@
|
||||
if(brainmob.mind)
|
||||
brainmob.mind.transfer_to(C)
|
||||
else
|
||||
C.key = brainmob.key
|
||||
brainmob.transfer_ckey(C)
|
||||
|
||||
QDEL_NULL(brainmob)
|
||||
|
||||
@@ -90,22 +99,89 @@
|
||||
if(brainmob)
|
||||
O.attack(brainmob, user) //Oh noooeeeee
|
||||
|
||||
/obj/item/organ/brain/examine(mob/user)
|
||||
..()
|
||||
if(istype(O, /obj/item/organ_storage)) //BUG_PROBABLE_CAUSE
|
||||
return //Borg organ bags shouldn't be killing brains
|
||||
|
||||
if(brainmob)
|
||||
if(brainmob.client)
|
||||
if(brainmob.health <= HEALTH_THRESHOLD_DEAD)
|
||||
to_chat(user, "It's lifeless and severely damaged.")
|
||||
if((organ_flags & ORGAN_FAILING) && O.is_drainable() && O.reagents.has_reagent("neurine")) //Neurine fixes dead brains
|
||||
. = TRUE //don't do attack animation.
|
||||
var/cached_Bdamage = brainmob?.health
|
||||
var/datum/reagent/medicine/neurine/N = reagents.has_reagent("neurine")
|
||||
var/datum/reagent/medicine/mannitol/M1 = reagents.has_reagent("mannitol")
|
||||
|
||||
if(O.reagents.has_reagent("mannitol"))//Just a quick way to bolster the effects if someone mixes up a batch.
|
||||
N.volume *= (M1.volume*0.5)
|
||||
|
||||
if(!O.reagents.has_reagent("neurine", 10))
|
||||
to_chat(user, "<span class='warning'>There's not enough neurine in [O] to restore [src]!</span>")
|
||||
return
|
||||
|
||||
user.visible_message("<span class='notice'>[user] starts to pour the contents of [O] onto [src].</span>", "<span class='notice'>You start to slowly pour the contents of [O] onto [src].</span>")
|
||||
if(!do_after(user, 60, TRUE, src))
|
||||
to_chat(user, "<span class='warning'>You failed to pour [O] onto [src]!</span>")
|
||||
return
|
||||
|
||||
user.visible_message("<span class='notice'>[user] pours the contents of [O] onto [src], causing it to reform its original shape and turn a slightly brighter shade of pink.</span>", "<span class='notice'>You pour the contents of [O] onto [src], causing it to reform its original shape and turn a slightly brighter shade of pink.</span>")
|
||||
setOrganDamage((damage - (0.10 * maxHealth)*(N.volume/10))) //heals a small amount, and by using "setorgandamage", we clear the failing variable if that was up
|
||||
O.reagents.clear_reagents()
|
||||
|
||||
if(cached_Bdamage <= HEALTH_THRESHOLD_DEAD) //Fixing dead brains yeilds a trauma
|
||||
if((cached_Bdamage <= HEALTH_THRESHOLD_DEAD) && (brainmob.health > HEALTH_THRESHOLD_DEAD))
|
||||
if(prob(80))
|
||||
gain_trauma_type(BRAIN_TRAUMA_MILD)
|
||||
else if(prob(50))
|
||||
gain_trauma_type(BRAIN_TRAUMA_SEVERE)
|
||||
else
|
||||
gain_trauma_type(BRAIN_TRAUMA_SPECIAL)
|
||||
return
|
||||
|
||||
if((organ_flags & ORGAN_FAILING) && O.is_drainable() && O.reagents.has_reagent("mannitol")) //attempt to heal the brain
|
||||
. = TRUE //don't do attack animation.
|
||||
var/datum/reagent/medicine/mannitol/M = reagents.has_reagent("mannitol")
|
||||
if(brain_death || brainmob?.health <= HEALTH_THRESHOLD_DEAD) //if the brain is fucked anyway, do nothing
|
||||
to_chat(user, "<span class='warning'>[src] is far too damaged, you'll have to use neurine on it!</span>")
|
||||
return
|
||||
|
||||
if(!O.reagents.has_reagent("mannitol", 10))
|
||||
to_chat(user, "<span class='warning'>There's not enough mannitol in [O] to restore [src]!</span>")
|
||||
return
|
||||
|
||||
user.visible_message("<span class='notice'>[user] starts to pour the contents of [O] onto [src].</span>", "<span class='notice'>You start to slowly pour the contents of [O] onto [src].</span>")
|
||||
if(!do_after(user, 60, TRUE, src))
|
||||
to_chat(user, "<span class='warning'>You failed to pour [O] onto [src]!</span>")
|
||||
return
|
||||
|
||||
user.visible_message("<span class='notice'>[user] pours the contents of [O] onto [src], causing it to reform its original shape and turn a slightly brighter shade of pink.</span>", "<span class='notice'>You pour the contents of [O] onto [src], causing it to reform its original shape and turn a slightly brighter shade of pink.</span>")
|
||||
setOrganDamage((damage - (0.05 * maxHealth)*(M.volume/10))) //heals a small amount, and by using "setorgandamage", we clear the failing variable if that was up
|
||||
O.reagents.clear_reagents()
|
||||
return
|
||||
|
||||
|
||||
|
||||
/obj/item/organ/brain/examine(mob/user)//BUG_PROBABLE_CAUSE to_chats changed to . +=
|
||||
. = ..()
|
||||
|
||||
if(user.suiciding)
|
||||
. += "<span class='info'>It's started turning slightly grey. They must not have been able to handle the stress of it all.</span>"
|
||||
else if(brainmob)
|
||||
if(brainmob.get_ghost(FALSE, TRUE))
|
||||
if(brain_death || brainmob.health <= HEALTH_THRESHOLD_DEAD)
|
||||
. += "<span class='info'>It's lifeless and severely damaged, only the strongest of chems will save it.</span>"
|
||||
else if(organ_flags & ORGAN_FAILING)
|
||||
. += "<span class='info'>It seems to still have a bit of energy within it, but it's rather damaged... You may be able to restore it with some <b>mannitol</b>.</span>"
|
||||
else
|
||||
to_chat(user, "You can feel the small spark of life still left in this one.")
|
||||
. += "<span class='info'>You can feel the small spark of life still left in this one.</span>"
|
||||
else if(organ_flags & ORGAN_FAILING)
|
||||
. += "<span class='info'>It seems particularly lifeless and is rather damaged... You may be able to restore it with some <b>mannitol</b> incase it becomes functional again later.</span>"
|
||||
else
|
||||
to_chat(user, "This one seems particularly lifeless. Perhaps it will regain some of its luster later.")
|
||||
. += "<span class='info'>This one seems particularly lifeless. Perhaps it will regain some of its luster later.</span>"
|
||||
else
|
||||
if(decoy_override)
|
||||
to_chat(user, "This one seems particularly lifeless. Perhaps it will regain some of its luster later.")
|
||||
if(organ_flags & ORGAN_FAILING)
|
||||
. += "<span class='info'>It seems particularly lifeless and is rather damaged... You may be able to restore it with some <b>mannitol</b> incase it becomes functional again later.</span>"
|
||||
else
|
||||
. += "<span class='info'>This one seems particularly lifeless. Perhaps it will regain some of its luster later.</span>"
|
||||
else
|
||||
to_chat(user, "This one is completely devoid of life.")
|
||||
. += "<span class='info'>This one is completely devoid of life.</span>"
|
||||
|
||||
/obj/item/organ/brain/attack(mob/living/carbon/C, mob/user)
|
||||
if(!istype(C))
|
||||
@@ -141,7 +217,7 @@
|
||||
Insert(C)
|
||||
else
|
||||
..()
|
||||
|
||||
/* TO BE REMOVED, KEPT IN CASE OF BUGS
|
||||
/obj/item/organ/brain/proc/get_brain_damage()
|
||||
var/brain_damage_threshold = max_integrity * BRAIN_DAMAGE_INTEGRITY_MULTIPLIER
|
||||
var/offset_integrity = obj_integrity - (max_integrity - brain_damage_threshold)
|
||||
@@ -165,6 +241,56 @@
|
||||
else if(adjusted_amount <= -DAMAGE_PRECISION)
|
||||
obj_integrity = min(max_integrity, obj_integrity-adjusted_amount)
|
||||
. = adjusted_amount
|
||||
*/
|
||||
|
||||
/obj/item/organ/brain/on_life()
|
||||
if(damage >= BRAIN_DAMAGE_DEATH) //rip
|
||||
to_chat(owner, "<span class='userdanger'>The last spark of life in your brain fizzles out...</span>")
|
||||
owner.death()
|
||||
brain_death = TRUE
|
||||
return
|
||||
..()
|
||||
|
||||
/obj/item/organ/brain/on_death()
|
||||
if(damage <= BRAIN_DAMAGE_DEATH) //rip
|
||||
brain_death = FALSE
|
||||
..()
|
||||
|
||||
|
||||
/obj/item/organ/brain/applyOrganDamage(var/d, var/maximum = maxHealth)
|
||||
..()
|
||||
|
||||
|
||||
/obj/item/organ/brain/check_damage_thresholds(mob/M)
|
||||
. = ..()
|
||||
//if we're not more injured than before, return without gambling for a trauma
|
||||
if(damage <= prev_damage)
|
||||
return
|
||||
damage_delta = damage - prev_damage
|
||||
if(damage > BRAIN_DAMAGE_MILD)
|
||||
if(prob(damage_delta * (1 + max(0, (damage - BRAIN_DAMAGE_MILD)/100)))) //Base chance is the hit damage; for every point of damage past the threshold the chance is increased by 1% //learn how to do your bloody math properly goddamnit
|
||||
gain_trauma_type(BRAIN_TRAUMA_MILD)
|
||||
if(damage > BRAIN_DAMAGE_SEVERE)
|
||||
if(prob(damage_delta * (1 + max(0, (damage - BRAIN_DAMAGE_SEVERE)/100)))) //Base chance is the hit damage; for every point of damage past the threshold the chance is increased by 1%
|
||||
if(prob(20))
|
||||
gain_trauma_type(BRAIN_TRAUMA_SPECIAL)
|
||||
else
|
||||
gain_trauma_type(BRAIN_TRAUMA_SEVERE)
|
||||
|
||||
if (owner)
|
||||
if(owner.stat < UNCONSCIOUS) //conscious or soft-crit
|
||||
var/brain_message
|
||||
if(prev_damage < BRAIN_DAMAGE_MILD && damage >= BRAIN_DAMAGE_MILD)
|
||||
brain_message = "<span class='warning'>You feel lightheaded.</span>"
|
||||
else if(prev_damage < BRAIN_DAMAGE_SEVERE && damage >= BRAIN_DAMAGE_SEVERE)
|
||||
brain_message = "<span class='warning'>You feel less in control of your thoughts.</span>"
|
||||
else if(prev_damage < (BRAIN_DAMAGE_DEATH - 20) && damage >= (BRAIN_DAMAGE_DEATH - 20))
|
||||
brain_message = "<span class='warning'>You can feel your mind flickering on and off...</span>"
|
||||
|
||||
if(.)
|
||||
. += "\n[brain_message]"
|
||||
else
|
||||
return brain_message
|
||||
|
||||
/obj/item/organ/brain/Destroy() //copypasted from MMIs.
|
||||
if(brainmob)
|
||||
@@ -200,6 +326,10 @@
|
||||
return FALSE
|
||||
if(!resilience)
|
||||
resilience = initial(trauma.resilience)
|
||||
if(!owner)
|
||||
return FALSE
|
||||
if(owner.stat == DEAD)
|
||||
return FALSE
|
||||
|
||||
var/resilience_tier_count = 0
|
||||
for(var/X in traumas)
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
else if(istype(loc, /obj/item/organ/brain))
|
||||
BR = loc
|
||||
if(BR)
|
||||
BR.damaged_brain = 1 //beaten to a pulp
|
||||
BR.brain_death = TRUE
|
||||
|
||||
/mob/living/brain/proc/handle_emp_damage()
|
||||
if(emp_damage)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
/obj/item/organ/alien
|
||||
icon_state = "xgibmid2"
|
||||
var/list/alien_powers = list()
|
||||
organ_flags = ORGAN_NO_SPOIL
|
||||
|
||||
/obj/item/organ/alien/Initialize()
|
||||
. = ..()
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
return S
|
||||
|
||||
/obj/item/organ/body_egg/alien_embryo/on_life()
|
||||
. = ..()
|
||||
switch(stage)
|
||||
if(2, 3)
|
||||
if(prob(2))
|
||||
@@ -86,7 +87,7 @@
|
||||
|
||||
var/atom/xeno_loc = get_turf(owner)
|
||||
var/mob/living/carbon/alien/larva/new_xeno = new(xeno_loc)
|
||||
new_xeno.key = ghost.key
|
||||
ghost.transfer_ckey(new_xeno, FALSE)
|
||||
SEND_SOUND(new_xeno, sound('sound/voice/hiss5.ogg',0,0,0,100)) //To get the player's attention
|
||||
new_xeno.canmove = 0 //so we don't move during the bursting animation
|
||||
new_xeno.notransform = 1
|
||||
|
||||
@@ -819,7 +819,7 @@
|
||||
reagents.clear_reagents()
|
||||
var/obj/item/organ/brain/B = getorgan(/obj/item/organ/brain)
|
||||
if(B)
|
||||
B.damaged_brain = FALSE
|
||||
B.brain_death = FALSE
|
||||
for(var/thing in diseases)
|
||||
var/datum/disease/D = thing
|
||||
if(D.severity != DISEASE_SEVERITY_POSITIVE)
|
||||
|
||||
@@ -405,16 +405,16 @@
|
||||
|
||||
if(istype(ears) && (deafen_pwr || damage_pwr))
|
||||
var/ear_damage = damage_pwr * effect_amount
|
||||
var/deaf = max(ears.deaf, deafen_pwr * effect_amount)
|
||||
var/deaf = deafen_pwr * effect_amount
|
||||
adjustEarDamage(ear_damage,deaf)
|
||||
|
||||
if(ears.ear_damage >= 15)
|
||||
if(ears.damage >= 15)
|
||||
to_chat(src, "<span class='warning'>Your ears start to ring badly!</span>")
|
||||
if(prob(ears.ear_damage - 5))
|
||||
if(prob(ears.damage - 5))
|
||||
to_chat(src, "<span class='userdanger'>You can't hear anything!</span>")
|
||||
ears.ear_damage = min(ears.ear_damage, UNHEALING_EAR_DAMAGE)
|
||||
ears.damage = min(ears.damage, ears.maxHealth)
|
||||
// you need earmuffs, inacusiate, or replacement
|
||||
else if(ears.ear_damage >= 5)
|
||||
else if(ears.damage >= 5)
|
||||
to_chat(src, "<span class='warning'>Your ears start to ring!</span>")
|
||||
SEND_SOUND(src, sound('sound/weapons/flash_ring.ogg',0,1,0,250))
|
||||
return effect_amount //how soundbanged we are
|
||||
|
||||
@@ -40,14 +40,13 @@
|
||||
update_damage_overlays()
|
||||
else
|
||||
adjustStaminaLoss(damage * hit_percent)
|
||||
if(BRAIN)
|
||||
adjustBrainLoss(damage * hit_percent)
|
||||
//citadel code
|
||||
if(AROUSAL)
|
||||
adjustArousalLoss(damage * hit_percent)
|
||||
return TRUE
|
||||
|
||||
|
||||
|
||||
//These procs fetch a cumulative total damage from all bodyparts
|
||||
/mob/living/carbon/getBruteLoss()
|
||||
var/amount = 0
|
||||
@@ -113,6 +112,51 @@
|
||||
return
|
||||
adjustStaminaLoss(diff, updating, forced)
|
||||
|
||||
/** adjustOrganLoss
|
||||
* inputs: slot (organ slot, like ORGAN_SLOT_HEART), amount (damage to be done), and maximum (currently an arbitrarily large number, can be set so as to limit damage)
|
||||
* outputs:
|
||||
* description: If an organ exists in the slot requested, and we are capable of taking damage (we don't have GODMODE on), call the damage proc on that organ.
|
||||
*/
|
||||
/mob/living/carbon/adjustOrganLoss(slot, amount, maximum)
|
||||
var/obj/item/organ/O = getorganslot(slot)
|
||||
if(O && !(status_flags & GODMODE))
|
||||
if(!maximum)
|
||||
maximum = O.maxHealth
|
||||
O.applyOrganDamage(amount, maximum)
|
||||
O.onDamage(amount, maximum)
|
||||
|
||||
/** setOrganLoss
|
||||
* inputs: slot (organ slot, like ORGAN_SLOT_HEART), amount(damage to be set to)
|
||||
* outputs:
|
||||
* description: If an organ exists in the slot requested, and we are capable of taking damage (we don't have GODMODE on), call the set damage proc on that organ, which can
|
||||
* set or clear the failing variable on that organ, making it either cease or start functions again, unlike adjustOrganLoss.
|
||||
*/
|
||||
/mob/living/carbon/setOrganLoss(slot, amount)
|
||||
var/obj/item/organ/O = getorganslot(slot)
|
||||
if(O && !(status_flags & GODMODE))
|
||||
O.setOrganDamage(amount)
|
||||
O.onSetDamage(amount)
|
||||
|
||||
/** getOrganLoss
|
||||
* inputs: slot (organ slot, like ORGAN_SLOT_HEART)
|
||||
* outputs: organ damage
|
||||
* description: If an organ exists in the slot requested, return the amount of damage that organ has
|
||||
*/
|
||||
/mob/living/carbon/getOrganLoss(slot)
|
||||
var/obj/item/organ/O = getorganslot(slot)
|
||||
if(O)
|
||||
return O.damage
|
||||
|
||||
/mob/living/carbon/proc/adjustAllOrganLoss(amount, maximum)
|
||||
for(var/obj/item/organ/O in internal_organs)
|
||||
if(O && !(status_flags & GODMODE))
|
||||
continue
|
||||
if(!maximum)
|
||||
maximum = O.maxHealth
|
||||
O.applyOrganDamage(amount, maximum)
|
||||
O.onDamage(amount, maximum)
|
||||
|
||||
|
||||
////////////////////////////////////////////
|
||||
|
||||
//Returns a list of damaged bodyparts
|
||||
@@ -213,24 +257,25 @@
|
||||
update_damage_overlays()
|
||||
update_stamina()
|
||||
|
||||
/mob/living/carbon/getBrainLoss()
|
||||
/* TO_REMOVE
|
||||
/mob/living/carbon/getOrganLoss(ORGAN_SLOT_BRAIN)
|
||||
. = 0
|
||||
var/obj/item/organ/brain/B = getorganslot(ORGAN_SLOT_BRAIN)
|
||||
if(B)
|
||||
. = B.get_brain_damage()
|
||||
|
||||
//Some sources of brain damage shouldn't be deadly
|
||||
/mob/living/carbon/adjustBrainLoss(amount, maximum = BRAIN_DAMAGE_DEATH)
|
||||
/mob/living/carbon/adjustOrganLoss(ORGAN_SLOT_BRAIN, amount, maximum = BRAIN_DAMAGE_DEATH)
|
||||
if(status_flags & GODMODE)
|
||||
return FALSE
|
||||
var/prev_brainloss = getBrainLoss()
|
||||
var/prev_brainloss = getOrganLoss(ORGAN_SLOT_BRAIN)
|
||||
var/obj/item/organ/brain/B = getorganslot(ORGAN_SLOT_BRAIN)
|
||||
if(!B)
|
||||
return
|
||||
B.adjust_brain_damage(amount, maximum)
|
||||
if(amount <= 0) //cut this early
|
||||
return
|
||||
var/brainloss = getBrainLoss()
|
||||
var/brainloss = getOrganLoss(ORGAN_SLOT_BRAIN)
|
||||
if(brainloss > BRAIN_DAMAGE_MILD)
|
||||
if(prob(amount * ((2 * (100 + brainloss - BRAIN_DAMAGE_MILD)) / 100))) //Base chance is the hit damage; for every point of damage past the threshold the chance is increased by 2%
|
||||
gain_trauma_type(BRAIN_TRAUMA_MILD)
|
||||
@@ -253,3 +298,4 @@
|
||||
if(B)
|
||||
var/adjusted_amount = amount - B.get_brain_damage()
|
||||
B.adjust_brain_damage(adjusted_amount, null)
|
||||
*/
|
||||
|
||||
@@ -865,7 +865,7 @@
|
||||
piggyback(target)
|
||||
return
|
||||
//If you dragged them to you and you're aggressively grabbing try to fireman carry them
|
||||
else if(user != target && can_be_firemanned(target))
|
||||
else if(user != target)
|
||||
fireman_carry(target)
|
||||
return
|
||||
. = ..()
|
||||
|
||||
@@ -751,9 +751,54 @@
|
||||
if(0 to NUTRITION_LEVEL_STARVING)
|
||||
to_send += "<span class='danger'>You're starving!</span>\n"
|
||||
|
||||
|
||||
//TODO: Convert these messages into vague messages, thereby encouraging actual dignosis.
|
||||
//Compiles then shows the list of damaged organs and broken organs
|
||||
var/list/broken = list()
|
||||
var/list/damaged = list()
|
||||
var/broken_message
|
||||
var/damaged_message
|
||||
var/broken_plural
|
||||
var/damaged_plural
|
||||
//Sets organs into their proper list
|
||||
for(var/O in internal_organs)
|
||||
var/obj/item/organ/organ = O
|
||||
if(organ.organ_flags & ORGAN_FAILING)
|
||||
if(broken.len)
|
||||
broken += ", "
|
||||
broken += organ.name
|
||||
else if(organ.damage > organ.low_threshold)
|
||||
if(damaged.len)
|
||||
damaged += ", "
|
||||
damaged += organ.name
|
||||
//Checks to enforce proper grammar, inserts words as necessary into the list
|
||||
if(broken.len)
|
||||
if(broken.len > 1)
|
||||
broken.Insert(broken.len, "and ")
|
||||
broken_plural = TRUE
|
||||
else
|
||||
var/holder = broken[1] //our one and only element
|
||||
if(holder[lentext(holder)] == "s")
|
||||
broken_plural = TRUE
|
||||
//Put the items in that list into a string of text
|
||||
for(var/B in broken)
|
||||
broken_message += B
|
||||
to_chat(src, "<span class='warning'> Your [broken_message] [broken_plural ? "are" : "is"] non-functional!</span>")
|
||||
if(damaged.len)
|
||||
if(damaged.len > 1)
|
||||
damaged.Insert(damaged.len, "and ")
|
||||
damaged_plural = TRUE
|
||||
else
|
||||
var/holder = damaged[1]
|
||||
if(holder[lentext(holder)] == "s")
|
||||
damaged_plural = TRUE
|
||||
for(var/D in damaged)
|
||||
damaged_message += D
|
||||
to_chat(src, "<span class='info'>Your [damaged_message] [damaged_plural ? "are" : "is"] hurt.</span>")
|
||||
|
||||
if(roundstart_quirks.len)
|
||||
to_send += "<span class='notice'>You have these quirks: [get_trait_string()].</span>\n"
|
||||
|
||||
|
||||
to_chat(src, to_send)
|
||||
else
|
||||
if(wear_suit)
|
||||
|
||||
@@ -74,7 +74,7 @@
|
||||
else if(eye_blurry) //blurry eyes heal slowly
|
||||
adjust_blurriness(-1)
|
||||
|
||||
if (getBrainLoss() >= 30) //Citadel change to make memes more often.
|
||||
if (getOrganLoss(ORGAN_SLOT_BRAIN) >= 30) //Citadel change to make memes more often.
|
||||
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "brain_damage", /datum/mood_event/brain_damage)
|
||||
if(prob(3))
|
||||
if(prob(25))
|
||||
|
||||
@@ -9,9 +9,29 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
var/name // this is the fluff name. these will be left generic (such as 'Lizardperson' for the lizard race) so servers can change them to whatever
|
||||
var/default_color = "#FFF" // if alien colors are disabled, this is the color that will be used by that race
|
||||
|
||||
var/sexes = 1 // whether or not the race has sexual characteristics. at the moment this is only 0 for skeletons and shadows
|
||||
var/sexes = 1 // whether or not the race has sexual characteristics. at the moment this is only 0 for skeletons and shadows
|
||||
|
||||
var/list/offset_features = list(OFFSET_UNIFORM = list(0,0), OFFSET_ID = list(0,0), OFFSET_GLOVES = list(0,0), OFFSET_GLASSES = list(0,0), OFFSET_EARS = list(0,0), OFFSET_SHOES = list(0,0), OFFSET_S_STORE = list(0,0), OFFSET_FACEMASK = list(0,0), OFFSET_HEAD = list(0,0), OFFSET_FACE = list(0,0), OFFSET_BELT = list(0,0), OFFSET_BACK = list(0,0), OFFSET_SUIT = list(0,0), OFFSET_NECK = list(0,0))
|
||||
//Species Icon Drawing Offsets - Pixel X, Pixel Y, Aka X = Horizontal and Y = Vertical, from bottom left corner
|
||||
var/list/offset_features = list(
|
||||
OFFSET_UNIFORM = list(0,0),
|
||||
OFFSET_ID = list(0,0),
|
||||
OFFSET_GLOVES = list(0,0),
|
||||
OFFSET_GLASSES = list(0,0),
|
||||
OFFSET_EARS = list(0,0),
|
||||
OFFSET_SHOES = list(0,0),
|
||||
OFFSET_S_STORE = list(0,0),
|
||||
OFFSET_FACEMASK = list(0,0),
|
||||
OFFSET_HEAD = list(0,0),
|
||||
OFFSET_EYES = list(0,0),
|
||||
OFFSET_LIPS = list(0,0),
|
||||
OFFSET_BELT = list(0,0),
|
||||
OFFSET_BACK = list(0,0),
|
||||
OFFSET_HAIR = list(0,0),
|
||||
OFFSET_FHAIR = list(0,0),
|
||||
OFFSET_SUIT = list(0,0),
|
||||
OFFSET_NECK = list(0,0),
|
||||
OFFSET_MUTPARTS = list(0,0)
|
||||
)
|
||||
|
||||
var/hair_color // this allows races to have specific hair colors... if null, it uses the H's hair/facial hair colors. if "mutcolor", it uses the H's mutant_color
|
||||
var/hair_alpha = 255 // the alpha used by the hair. 255 is completely solid, 0 is transparent.
|
||||
@@ -401,6 +421,10 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
|
||||
facial_overlay.alpha = hair_alpha
|
||||
|
||||
if(OFFSET_FHAIR in H.dna.species.offset_features)
|
||||
facial_overlay.pixel_x += H.dna.species.offset_features[OFFSET_FHAIR][1]
|
||||
facial_overlay.pixel_y += H.dna.species.offset_features[OFFSET_FHAIR][2]
|
||||
|
||||
standing += facial_overlay
|
||||
|
||||
if(H.head)
|
||||
@@ -458,9 +482,11 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
else
|
||||
hair_overlay.color = forced_colour
|
||||
hair_overlay.alpha = hair_alpha
|
||||
if(OFFSET_FACE in H.dna.species.offset_features)
|
||||
hair_overlay.pixel_x += H.dna.species.offset_features[OFFSET_FACE][1]
|
||||
hair_overlay.pixel_y += H.dna.species.offset_features[OFFSET_FACE][2]
|
||||
|
||||
if(OFFSET_HAIR in H.dna.species.offset_features)
|
||||
hair_overlay.pixel_x += H.dna.species.offset_features[OFFSET_HAIR][1]
|
||||
hair_overlay.pixel_y += H.dna.species.offset_features[OFFSET_HAIR][2]
|
||||
|
||||
if(hair_overlay.icon)
|
||||
standing += hair_overlay
|
||||
|
||||
@@ -481,9 +507,11 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
if(H.lip_style && (LIPS in species_traits))
|
||||
var/mutable_appearance/lip_overlay = mutable_appearance('icons/mob/human_face.dmi', "lips_[H.lip_style]", -BODY_LAYER)
|
||||
lip_overlay.color = H.lip_color
|
||||
if(OFFSET_FACE in H.dna.species.offset_features)
|
||||
lip_overlay.pixel_x += H.dna.species.offset_features[OFFSET_FACE][1]
|
||||
lip_overlay.pixel_y += H.dna.species.offset_features[OFFSET_FACE][2]
|
||||
|
||||
if(OFFSET_LIPS in H.dna.species.offset_features)
|
||||
lip_overlay.pixel_x += H.dna.species.offset_features[OFFSET_LIPS][1]
|
||||
lip_overlay.pixel_y += H.dna.species.offset_features[OFFSET_LIPS][2]
|
||||
|
||||
standing += lip_overlay
|
||||
|
||||
// eyes
|
||||
@@ -496,9 +524,11 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
eye_overlay = mutable_appearance('icons/mob/human_face.dmi', "eyes", -BODY_LAYER)
|
||||
if((EYECOLOR in species_traits) && has_eyes)
|
||||
eye_overlay.color = "#" + H.eye_color
|
||||
if(OFFSET_FACE in H.dna.species.offset_features)
|
||||
eye_overlay.pixel_x += H.dna.species.offset_features[OFFSET_FACE][1]
|
||||
eye_overlay.pixel_y += H.dna.species.offset_features[OFFSET_FACE][2]
|
||||
|
||||
if(OFFSET_EYES in H.dna.species.offset_features)
|
||||
eye_overlay.pixel_x += H.dna.species.offset_features[OFFSET_EYES][1]
|
||||
eye_overlay.pixel_y += H.dna.species.offset_features[OFFSET_EYES][2]
|
||||
|
||||
standing += eye_overlay
|
||||
|
||||
//Underwear, Undershirts & Socks
|
||||
@@ -731,6 +761,8 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
S = GLOB.wings_list[H.dna.features["wings"]]
|
||||
if("wingsopen")
|
||||
S = GLOB.wings_open_list[H.dna.features["wings"]]
|
||||
if("deco_wings")
|
||||
S = GLOB.deco_wings_list[H.dna.features["deco_wings"]]
|
||||
if("legs")
|
||||
S = GLOB.legs_list[H.dna.features["legs"]]
|
||||
if("insect_wings")
|
||||
@@ -782,6 +814,8 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
bodypart = "snout"
|
||||
if(bodypart == "xenohead")
|
||||
bodypart = "xhead"
|
||||
if(bodypart == "insect_wings" || bodypart == "deco_wings")
|
||||
bodypart = "insect_wings"
|
||||
|
||||
if(S.gender_specific)
|
||||
accessory_overlay.icon_state = "[g]_[bodypart]_[S.icon_state]_[layertext]"
|
||||
@@ -851,6 +885,11 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
for(var/index=1, index<=husklist.len, index++)
|
||||
husklist[index] = husklist[index]/255
|
||||
accessory_overlay.color = husklist
|
||||
|
||||
if(OFFSET_MUTPARTS in H.dna.species.offset_features)
|
||||
accessory_overlay.pixel_x += H.dna.species.offset_features[OFFSET_MUTPARTS][1]
|
||||
accessory_overlay.pixel_y += H.dna.species.offset_features[OFFSET_MUTPARTS][2]
|
||||
|
||||
standing += accessory_overlay
|
||||
|
||||
if(S.hasinner)
|
||||
@@ -863,6 +902,10 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
if(S.center)
|
||||
inner_accessory_overlay = center_image(inner_accessory_overlay, S.dimension_x, S.dimension_y)
|
||||
|
||||
if(OFFSET_MUTPARTS in H.dna.species.offset_features)
|
||||
inner_accessory_overlay.pixel_x += H.dna.species.offset_features[OFFSET_MUTPARTS][1]
|
||||
inner_accessory_overlay.pixel_y += H.dna.species.offset_features[OFFSET_MUTPARTS][2]
|
||||
|
||||
standing += inner_accessory_overlay
|
||||
|
||||
if(S.extra) //apply the extra overlay, if there is one
|
||||
@@ -903,6 +946,11 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
|
||||
if(HORNCOLOR)
|
||||
extra_accessory_overlay.color = "#[H.horn_color]"
|
||||
|
||||
if(OFFSET_MUTPARTS in H.dna.species.offset_features)
|
||||
extra_accessory_overlay.pixel_x += H.dna.species.offset_features[OFFSET_MUTPARTS][1]
|
||||
extra_accessory_overlay.pixel_y += H.dna.species.offset_features[OFFSET_MUTPARTS][2]
|
||||
|
||||
standing += extra_accessory_overlay
|
||||
|
||||
if(S.extra2) //apply the extra overlay, if there is one
|
||||
@@ -937,6 +985,11 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
extra2_accessory_overlay.color = "#[H.hair_color]"
|
||||
if(HORNCOLOR)
|
||||
extra2_accessory_overlay.color = "#[H.horn_color]"
|
||||
|
||||
if(OFFSET_MUTPARTS in H.dna.species.offset_features)
|
||||
extra2_accessory_overlay.pixel_x += H.dna.species.offset_features[OFFSET_MUTPARTS][1]
|
||||
extra2_accessory_overlay.pixel_y += H.dna.species.offset_features[OFFSET_MUTPARTS][2]
|
||||
|
||||
standing += extra2_accessory_overlay
|
||||
|
||||
|
||||
@@ -1221,9 +1274,14 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
if(mood && mood.sanity > SANITY_DISTURBED)
|
||||
hunger_rate *= max(0.5, 1 - 0.002 * mood.sanity) //0.85 to 0.75
|
||||
|
||||
if(H.satiety > 0)
|
||||
// Whether we cap off our satiety or move it towards 0
|
||||
if(H.satiety > MAX_SATIETY)
|
||||
H.satiety = MAX_SATIETY
|
||||
else if(H.satiety > 0)
|
||||
H.satiety--
|
||||
if(H.satiety < 0)
|
||||
else if(H.satiety < -MAX_SATIETY)
|
||||
H.satiety = -MAX_SATIETY
|
||||
else if(H.satiety < 0)
|
||||
H.satiety++
|
||||
if(prob(round(-H.satiety/40)))
|
||||
H.Jitter(5)
|
||||
@@ -1338,9 +1396,9 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
var/obj/item/organ/cyberimp/chest/thrusters/T = H.getorganslot(ORGAN_SLOT_THRUSTERS)
|
||||
if(!istype(J) && istype(C))
|
||||
J = C.jetpack
|
||||
if(istype(J) && J.full_speed && J.allow_thrust(0.005, H)) //Prevents stacking
|
||||
if(istype(J) && J.full_speed && J.allow_thrust(0.01, H)) //Prevents stacking
|
||||
. -= 0.4
|
||||
else if(istype(T) && T.allow_thrust(0.005, H))
|
||||
else if(istype(T) && T.allow_thrust(0.01, H))
|
||||
. -= 0.4
|
||||
|
||||
if(!ignoreslow && gravity)
|
||||
@@ -1708,7 +1766,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
if(BODY_ZONE_HEAD)
|
||||
if(!I.is_sharp() && armor_block < 50)
|
||||
if(prob(I.force))
|
||||
H.adjustBrainLoss(20)
|
||||
H.adjustOrganLoss(ORGAN_SLOT_BRAIN, 20)
|
||||
if(H.stat == CONSCIOUS)
|
||||
H.visible_message("<span class='danger'>[H] has been knocked senseless!</span>", \
|
||||
"<span class='userdanger'>[H] has been knocked senseless!</span>")
|
||||
@@ -1717,7 +1775,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
if(prob(10))
|
||||
H.gain_trauma(/datum/brain_trauma/mild/concussion)
|
||||
else
|
||||
H.adjustBrainLoss(I.force * 0.2)
|
||||
H.adjustOrganLoss(ORGAN_SLOT_BRAIN, I.force * 0.2)
|
||||
|
||||
if(H.stat == CONSCIOUS && H != user && prob(I.force + ((100 - H.health) * 0.5))) // rev deconversion through blunt trauma.
|
||||
var/datum/antagonist/rev/rev = H.mind.has_antag_datum(/datum/antagonist/rev)
|
||||
@@ -1821,67 +1879,36 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
if(!target.resting)
|
||||
target.adjustStaminaLoss(5)
|
||||
|
||||
if(target.is_shove_knockdown_blocked())
|
||||
return
|
||||
|
||||
var/turf/target_oldturf = target.loc
|
||||
var/shove_dir = get_dir(user.loc, target_oldturf)
|
||||
var/turf/target_shove_turf = get_step(target.loc, shove_dir)
|
||||
var/mob/living/carbon/human/target_collateral_human
|
||||
var/obj/structure/table/target_table
|
||||
var/shove_blocked = FALSE //Used to check if a shove is blocked so that if it is knockdown logic can be applied
|
||||
|
||||
//Thank you based whoneedsspace
|
||||
target_collateral_human = locate(/mob/living/carbon/human) in target_shove_turf.contents
|
||||
if(target_collateral_human)
|
||||
if(target_collateral_human && !target_collateral_human.resting)
|
||||
shove_blocked = TRUE
|
||||
else
|
||||
target_collateral_human = null
|
||||
target.Move(target_shove_turf, shove_dir)
|
||||
if(get_turf(target) == target_oldturf)
|
||||
if(target_shove_turf.density)
|
||||
shove_blocked = TRUE
|
||||
else
|
||||
var/thoushallnotpass = FALSE
|
||||
for(var/obj/O in target_shove_turf)
|
||||
if(istype(O, /obj/structure/table))
|
||||
target_table = O
|
||||
else if(!O.CanPass(src, target_shove_turf))
|
||||
shove_blocked = TRUE
|
||||
thoushallnotpass = TRUE
|
||||
if(thoushallnotpass)
|
||||
target_table = null
|
||||
shove_blocked = TRUE
|
||||
|
||||
if(target.is_shove_knockdown_blocked())
|
||||
return
|
||||
|
||||
if(shove_blocked || target_table)
|
||||
var/directional_blocked = FALSE
|
||||
if(shove_dir in GLOB.cardinals) //Directional checks to make sure that we're not shoving through a windoor or something like that
|
||||
var/target_turf = get_turf(target)
|
||||
for(var/obj/O in target_turf)
|
||||
if(O.flags_1 & ON_BORDER_1 && O.dir == shove_dir && O.density)
|
||||
directional_blocked = TRUE
|
||||
break
|
||||
if(target_turf != target_shove_turf) //Make sure that we don't run the exact same check twice on the same tile
|
||||
for(var/obj/O in target_shove_turf)
|
||||
if(O.flags_1 & ON_BORDER_1 && O.dir == turn(shove_dir, 180) && O.density)
|
||||
directional_blocked = TRUE
|
||||
break
|
||||
if(shove_blocked && !target.buckled)
|
||||
var/directional_blocked = !target.Adjacent(target_shove_turf)
|
||||
var/targetatrest = target.resting
|
||||
if(((!target_table && !target_collateral_human) || directional_blocked) && !targetatrest)
|
||||
if((directional_blocked || !(target_collateral_human || target_shove_turf.shove_act(target, user))) && !targetatrest)
|
||||
target.Knockdown(SHOVE_KNOCKDOWN_SOLID)
|
||||
user.visible_message("<span class='danger'>[user.name] shoves [target.name], knocking them down!</span>",
|
||||
"<span class='danger'>You shove [target.name], knocking them down!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
log_combat(user, target, "shoved", "knocking them down")
|
||||
else if(target_table)
|
||||
if(!targetatrest)
|
||||
target.Knockdown(SHOVE_KNOCKDOWN_TABLE)
|
||||
user.visible_message("<span class='danger'>[user.name] shoves [target.name] onto \the [target_table]!</span>",
|
||||
"<span class='danger'>You shove [target.name] onto \the [target_table]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
target.forceMove(target_shove_turf)
|
||||
log_combat(user, target, "shoved", "onto [target_table]")
|
||||
else if(target_collateral_human && !targetatrest)
|
||||
target.Knockdown(SHOVE_KNOCKDOWN_HUMAN)
|
||||
if(!target_collateral_human.resting)
|
||||
target_collateral_human.Knockdown(SHOVE_KNOCKDOWN_COLLATERAL)
|
||||
target_collateral_human.Knockdown(SHOVE_KNOCKDOWN_COLLATERAL)
|
||||
user.visible_message("<span class='danger'>[user.name] shoves [target.name] into [target_collateral_human.name]!</span>",
|
||||
"<span class='danger'>You shove [target.name] into [target_collateral_human.name]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
log_combat(user, target, "shoved", "into [target_collateral_human.name]")
|
||||
@@ -1967,7 +1994,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
else
|
||||
H.adjustStaminaLoss(damage * hit_percent * H.physiology.stamina_mod)
|
||||
if(BRAIN)
|
||||
H.adjustBrainLoss(damage * hit_percent * H.physiology.brain_mod)
|
||||
H.adjustOrganLoss(ORGAN_SLOT_BRAIN, damage * hit_percent * H.physiology.brain_mod)
|
||||
if(AROUSAL) //Citadel edit - arousal
|
||||
H.adjustArousalLoss(damage * hit_percent)
|
||||
return 1
|
||||
|
||||
@@ -13,9 +13,12 @@
|
||||
blacklisted = TRUE
|
||||
limbs_id = "human"
|
||||
skinned_type = /obj/item/stack/sheet/animalhide/human
|
||||
var/pumpkin = FALSE
|
||||
|
||||
var/obj/item/dullahan_relay/myhead
|
||||
|
||||
/datum/species/dullahan/pumpkin
|
||||
pumpkin = TRUE
|
||||
|
||||
/datum/species/dullahan/check_roundstart_eligible()
|
||||
if(SSevents.holidays && SSevents.holidays[HALLOWEEN])
|
||||
@@ -27,11 +30,19 @@
|
||||
H.flags_1 &= ~HEAR_1
|
||||
var/obj/item/bodypart/head/head = H.get_bodypart(BODY_ZONE_HEAD)
|
||||
if(head)
|
||||
if(pumpkin)//Pumpkinhead!
|
||||
head.animal_origin = 100
|
||||
head.icon = 'icons/obj/clothing/hats.dmi'
|
||||
head.icon_state = "hardhat1_pumpkin_j"
|
||||
head.custom_head = TRUE
|
||||
head.drop_limb()
|
||||
head.flags_1 = HEAR_1
|
||||
head.throwforce = 25
|
||||
myhead = new /obj/item/dullahan_relay (head, H)
|
||||
H.put_in_hands(head)
|
||||
var/obj/item/organ/eyes/E = H.getorganslot(ORGAN_SLOT_EYES)
|
||||
for(var/datum/action/item_action/organ_action/OA in E.actions)
|
||||
OA.Trigger()
|
||||
|
||||
/datum/species/dullahan/on_species_loss(mob/living/carbon/human/H)
|
||||
H.flags_1 |= ~HEAR_1
|
||||
@@ -64,7 +75,7 @@
|
||||
|
||||
/obj/item/organ/brain/dullahan
|
||||
decoy_override = TRUE
|
||||
vital = FALSE
|
||||
organ_flags = ORGAN_NO_SPOIL//Do not decay
|
||||
|
||||
/obj/item/organ/tongue/dullahan
|
||||
zone = "abstract"
|
||||
@@ -138,4 +149,4 @@
|
||||
D.myhead = null
|
||||
owner.gib()
|
||||
owner = null
|
||||
..()
|
||||
..()
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
should_draw_citadel = TRUE
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,LIPS,HAIR,HORNCOLOR)
|
||||
inherent_biotypes = list(MOB_ORGANIC, MOB_HUMANOID)
|
||||
mutant_bodyparts = list("mam_tail", "mam_ears", "mam_body_markings", "mam_snouts", "taur", "horns", "legs")
|
||||
default_features = list("mcolor" = "FFF","mcolor2" = "FFF","mcolor3" = "FFF", "mam_snouts" = "Husky", "mam_tail" = "Husky", "mam_ears" = "Husky",
|
||||
mutant_bodyparts = list("mam_tail", "mam_ears", "mam_body_markings", "mam_snouts", "deco_wings", "taur", "horns", "legs")
|
||||
default_features = list("mcolor" = "FFF","mcolor2" = "FFF","mcolor3" = "FFF", "mam_snouts" = "Husky", "mam_tail" = "Husky", "mam_ears" = "Husky", "deco_wings" = "None",
|
||||
"mam_body_markings" = "Husky", "taur" = "None", "horns" = "None", "legs" = "Plantigrade", "meat_type" = "Mammalian")
|
||||
attack_verb = "claw"
|
||||
attack_sound = 'sound/weapons/slash.ogg'
|
||||
|
||||
@@ -581,7 +581,7 @@
|
||||
limbs_id = "cultgolem"
|
||||
sexes = FALSE
|
||||
info_text = "As a <span class='danger'>Runic Golem</span>, you possess eldritch powers granted by the Elder Goddess Nar'Sie."
|
||||
species_traits = list(NOBLOOD,NO_UNDERWEAR,NOEYES) //no mutcolors
|
||||
species_traits = list(NOBLOOD,NO_UNDERWEAR,NOEYES,NOGENITALS,NOAROUSAL) //no mutcolors
|
||||
prefix = "Runic"
|
||||
special_names = null
|
||||
|
||||
@@ -635,7 +635,7 @@
|
||||
say_mod = "clicks"
|
||||
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 golems. On death, you will break down into scrap.</span>"
|
||||
species_traits = list(NOBLOOD,NO_UNDERWEAR,NOEYES)
|
||||
species_traits = list(NOBLOOD,NO_UNDERWEAR,NOEYES,NOGENITALS,NOAROUSAL)
|
||||
inherent_biotypes = list(MOB_ROBOTIC, MOB_HUMANOID)
|
||||
armor = 20 //Reinforced, but much less so to allow for fast movement
|
||||
attack_verb = "smash"
|
||||
@@ -691,7 +691,7 @@
|
||||
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. \
|
||||
Being made of cloth, your body is magic resistant and faster than that of other golems, but weaker and less resilient."
|
||||
species_traits = list(NOBLOOD,NO_UNDERWEAR) //no mutcolors, and can burn
|
||||
species_traits = list(NOBLOOD,NO_UNDERWEAR,NOGENITALS,NOAROUSAL) //no mutcolors, and can burn
|
||||
inherent_traits = list(TRAIT_RESISTCOLD,TRAIT_NOBREATH,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER,TRAIT_NOGUNS)
|
||||
inherent_biotypes = list(MOB_UNDEAD, MOB_HUMANOID)
|
||||
armor = 15 //feels no pain, but not too resistant
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
burnmod = 1.5
|
||||
heatmod = 1.5
|
||||
breathid = "tox"
|
||||
speedmod = 1
|
||||
damage_overlay_type = ""//let's not show bloody wounds or burns over bones.
|
||||
var/internal_fire = FALSE //If the bones themselves are burning clothes won't help you much
|
||||
disliked_food = FRUIT
|
||||
@@ -55,19 +54,95 @@
|
||||
..()
|
||||
|
||||
/datum/species/plasmaman/before_equip_job(datum/job/J, mob/living/carbon/human/H, visualsOnly = FALSE)
|
||||
var/current_job = J.title
|
||||
var/datum/outfit/plasmaman/O = new /datum/outfit/plasmaman
|
||||
switch(current_job)
|
||||
if("Chaplain")
|
||||
O = new /datum/outfit/plasmaman/chaplain
|
||||
|
||||
if("Curator")
|
||||
O = new /datum/outfit/plasmaman/curator
|
||||
|
||||
if("Janitor")
|
||||
O = new /datum/outfit/plasmaman/janitor
|
||||
|
||||
if("Botanist")
|
||||
O = new /datum/outfit/plasmaman/botany
|
||||
|
||||
if("Bartender", "Lawyer")
|
||||
O = new /datum/outfit/plasmaman/bar
|
||||
|
||||
if("Cook")
|
||||
O = new /datum/outfit/plasmaman/chef
|
||||
|
||||
if("Security Officer")
|
||||
O = new /datum/outfit/plasmaman/security
|
||||
|
||||
if("Detective")
|
||||
O = new /datum/outfit/plasmaman/detective
|
||||
|
||||
if("Warden")
|
||||
O = new /datum/outfit/plasmaman/warden
|
||||
|
||||
if("Cargo Technician", "Quartermaster")
|
||||
O = new /datum/outfit/plasmaman/cargo
|
||||
|
||||
if("Shaft Miner")
|
||||
O = new /datum/outfit/plasmaman/mining
|
||||
|
||||
if("Medical Doctor")
|
||||
O = new /datum/outfit/plasmaman/medical
|
||||
|
||||
if("Chemist")
|
||||
O = new /datum/outfit/plasmaman/chemist
|
||||
|
||||
if("Geneticist")
|
||||
O = new /datum/outfit/plasmaman/genetics
|
||||
|
||||
if("Roboticist")
|
||||
O = new /datum/outfit/plasmaman/robotics
|
||||
|
||||
if("Virologist")
|
||||
O = new /datum/outfit/plasmaman/viro
|
||||
|
||||
if("Scientist")
|
||||
O = new /datum/outfit/plasmaman/science
|
||||
|
||||
if("Station Engineer")
|
||||
O = new /datum/outfit/plasmaman/engineering
|
||||
|
||||
if("Atmospheric Technician")
|
||||
O = new /datum/outfit/plasmaman/atmospherics
|
||||
|
||||
if("Captain")
|
||||
O = new /datum/outfit/plasmaman/captain
|
||||
|
||||
if("Head of Personnel")
|
||||
O = new /datum/outfit/plasmaman/hop
|
||||
|
||||
if("Head of Security")
|
||||
O = new /datum/outfit/plasmaman/hos
|
||||
|
||||
if("Chief Engineer")
|
||||
O = new /datum/outfit/plasmaman/ce
|
||||
|
||||
if("Chief Medical Officer")
|
||||
O = new /datum/outfit/plasmaman/cmo
|
||||
|
||||
if("Research Director")
|
||||
O = new /datum/outfit/plasmaman/rd
|
||||
|
||||
if("Mime")
|
||||
O = new /datum/outfit/plasmaman/mime
|
||||
|
||||
if("Clown")
|
||||
O = new /datum/outfit/plasmaman/clown
|
||||
|
||||
H.equipOutfit(O, visualsOnly)
|
||||
H.internal = H.get_item_for_held_index(2)
|
||||
H.update_internals_hud_icon(1)
|
||||
return 0
|
||||
|
||||
/datum/species/plasmaman/qualifies_for_rank(rank, list/features)
|
||||
if(rank in GLOB.security_positions)
|
||||
return 0
|
||||
if(rank == "Clown" || rank == "Mime")//No funny bussiness
|
||||
return 0
|
||||
return ..()
|
||||
|
||||
/datum/species/plasmaman/random_name(gender,unique,lastname)
|
||||
if(unique)
|
||||
return random_unique_plasmaman_name()
|
||||
|
||||
@@ -36,8 +36,8 @@
|
||||
var/turf/T = H.loc
|
||||
light_amount = min(1,T.get_lumcount()) - 0.5
|
||||
H.nutrition += light_amount * light_nutrition_gain_factor
|
||||
if(H.nutrition > NUTRITION_LEVEL_FULL)
|
||||
H.nutrition = NUTRITION_LEVEL_FULL
|
||||
if(H.nutrition >= NUTRITION_LEVEL_FULL)
|
||||
H.nutrition = NUTRITION_LEVEL_FULL - 1
|
||||
if(light_amount > 0.2) //if there's enough light, heal
|
||||
H.heal_overall_damage(light_bruteheal, light_burnheal)
|
||||
H.adjustToxLoss(-light_toxheal)
|
||||
|
||||
@@ -102,6 +102,7 @@
|
||||
color = "#1C1C1C"
|
||||
var/respawn_progress = 0
|
||||
var/obj/item/light_eater/blade
|
||||
decay_factor = 0
|
||||
|
||||
|
||||
/obj/item/organ/heart/nightmare/attack(mob/M, mob/living/carbon/user, obj/target)
|
||||
@@ -122,10 +123,8 @@
|
||||
if(special != HEART_SPECIAL_SHADOWIFY)
|
||||
blade = new/obj/item/light_eater
|
||||
M.put_in_hands(blade)
|
||||
START_PROCESSING(SSobj, src)
|
||||
|
||||
/obj/item/organ/heart/nightmare/Remove(mob/living/carbon/M, special = 0)
|
||||
STOP_PROCESSING(SSobj, src)
|
||||
respawn_progress = 0
|
||||
if(blade && special != HEART_SPECIAL_SHADOWIFY)
|
||||
QDEL_NULL(blade)
|
||||
@@ -138,9 +137,8 @@
|
||||
/obj/item/organ/heart/nightmare/update_icon()
|
||||
return //always beating visually
|
||||
|
||||
/obj/item/organ/heart/nightmare/process()
|
||||
if(QDELETED(owner) || owner.stat != DEAD)
|
||||
respawn_progress = 0
|
||||
/obj/item/organ/heart/nightmare/on_death()
|
||||
if(!owner)
|
||||
return
|
||||
var/turf/T = get_turf(owner)
|
||||
if(istype(T))
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
name = "Spooky Scary Skeleton"
|
||||
id = "skeleton"
|
||||
say_mod = "rattles"
|
||||
blacklisted = 1
|
||||
blacklisted = 0
|
||||
sexes = 0
|
||||
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/skeleton
|
||||
species_traits = list(NOBLOOD,NOGENITALS,NOAROUSAL)
|
||||
@@ -12,13 +12,18 @@
|
||||
mutanttongue = /obj/item/organ/tongue/bone
|
||||
damage_overlay_type = ""//let's not show bloody wounds or burns over bones.
|
||||
disliked_food = NONE
|
||||
liked_food = GROSS | MEAT | RAW
|
||||
liked_food = GROSS | MEAT | RAW | DAIRY
|
||||
|
||||
/datum/species/skeleton/check_roundstart_eligible()
|
||||
if(SSevents.holidays && SSevents.holidays[HALLOWEEN])
|
||||
return TRUE
|
||||
return ..()
|
||||
|
||||
/datum/species/skeleton/pirate
|
||||
name = "Space Queen's Skeleton"
|
||||
/datum/species/skeleton/space
|
||||
name = "Spooky Spacey Skeleton"
|
||||
id = "spaceskeleton"
|
||||
blacklisted = 1
|
||||
inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NOHUNGER,TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT,TRAIT_FAKEDEATH, TRAIT_CALCIUM_HEALER)
|
||||
|
||||
/datum/species/skeleton/pirate/check_roundstart_eligible()
|
||||
return FALSE
|
||||
@@ -16,7 +16,12 @@
|
||||
disliked_food = NONE
|
||||
liked_food = GROSS | MEAT | RAW
|
||||
|
||||
/datum/species/zombie/check_roundstart_eligible()
|
||||
/datum/species/zombie/notspaceproof
|
||||
id = "notspaceproofzombie"
|
||||
blacklisted = 0
|
||||
inherent_traits = list(TRAIT_RESISTCOLD,TRAIT_RADIMMUNE,TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT,TRAIT_NOBREATH,TRAIT_NODEATH,TRAIT_FAKEDEATH)
|
||||
|
||||
/datum/species/zombie/notspaceproof/check_roundstart_eligible()
|
||||
if(SSevents.holidays && SSevents.holidays[HALLOWEEN])
|
||||
return TRUE
|
||||
return ..()
|
||||
@@ -47,7 +52,7 @@
|
||||
/datum/species/zombie/infectious/spec_life(mob/living/carbon/C)
|
||||
. = ..()
|
||||
C.a_intent = INTENT_HARM // THE SUFFERING MUST FLOW
|
||||
|
||||
|
||||
//Zombies never actually die, they just fall down until they regenerate enough to rise back up.
|
||||
//They must be restrained, beheaded or gibbed to stop being a threat.
|
||||
if(regen_cooldown < world.time)
|
||||
@@ -58,7 +63,7 @@
|
||||
C.adjustToxLoss(-heal_amt)
|
||||
if(!C.InCritical() && prob(4))
|
||||
playsound(C, pick(spooks), 50, TRUE, 10)
|
||||
|
||||
|
||||
//Congrats you somehow died so hard you stopped being a zombie
|
||||
/datum/species/zombie/infectious/spec_death(mob/living/carbon/C)
|
||||
. = ..()
|
||||
|
||||
@@ -123,15 +123,16 @@ There are several things that need to be remembered:
|
||||
if(U.adjusted == ALT_STYLE)
|
||||
t_color = "[t_color]_d"
|
||||
|
||||
if(U.mutantrace_variation)
|
||||
if(U.suit_style == DIGITIGRADE_SUIT_STYLE)
|
||||
U.alternate_worn_icon = 'modular_citadel/icons/mob/uniform_digi.dmi'
|
||||
if(U.adjusted == ALT_STYLE)
|
||||
t_color = "[t_color]_d_l"
|
||||
else if(U.adjusted == NORMAL_STYLE)
|
||||
t_color = "[t_color]_l"
|
||||
else
|
||||
U.alternate_worn_icon = null
|
||||
if(!U.force_alternate_icon)
|
||||
if(U.mutantrace_variation)
|
||||
if(U.suit_style == DIGITIGRADE_SUIT_STYLE)
|
||||
U.alternate_worn_icon = 'modular_citadel/icons/mob/uniform_digi.dmi'
|
||||
if(U.adjusted == ALT_STYLE)
|
||||
t_color = "[t_color]_d_l"
|
||||
else if(U.adjusted == NORMAL_STYLE)
|
||||
t_color = "[t_color]_l"
|
||||
else
|
||||
U.alternate_worn_icon = null
|
||||
|
||||
var/mutable_appearance/uniform_overlay
|
||||
|
||||
@@ -388,22 +389,23 @@ There are several things that need to be remembered:
|
||||
client.screen += wear_suit
|
||||
update_observer_view(wear_suit,1)
|
||||
|
||||
if(!no_taur_thanks && S.mutantrace_variation) //Just make sure we've got this checked too
|
||||
if(S.taurmode == NOT_TAURIC && S.adjusted == ALT_STYLE) //are we not a taur, but we have Digitigrade legs? Run this check first, then.
|
||||
S.alternate_worn_icon = 'modular_citadel/icons/mob/suit_digi.dmi'
|
||||
else
|
||||
S.alternate_worn_icon = null
|
||||
|
||||
if(S.tauric == TRUE) //Are we a suit with tauric mode possible?
|
||||
if(S.taurmode == SNEK_TAURIC)
|
||||
S.alternate_worn_icon = 'modular_citadel/icons/mob/taur_naga.dmi'
|
||||
if(S.taurmode == PAW_TAURIC)
|
||||
S.alternate_worn_icon = 'modular_citadel/icons/mob/taur_canine.dmi'
|
||||
if(S.taurmode == NOT_TAURIC && S.adjusted == ALT_STYLE)
|
||||
if(!S.force_alternate_icon)
|
||||
if(!no_taur_thanks && S.mutantrace_variation) //Just make sure we've got this checked too
|
||||
if(S.taurmode == NOT_TAURIC && S.adjusted == ALT_STYLE) //are we not a taur, but we have Digitigrade legs? Run this check first, then.
|
||||
S.alternate_worn_icon = 'modular_citadel/icons/mob/suit_digi.dmi'
|
||||
else if(S.taurmode == NOT_TAURIC && S.adjusted == NORMAL_STYLE)
|
||||
else
|
||||
S.alternate_worn_icon = null
|
||||
|
||||
if(S.tauric == TRUE) //Are we a suit with tauric mode possible?
|
||||
if(S.taurmode == SNEK_TAURIC)
|
||||
S.alternate_worn_icon = 'modular_citadel/icons/mob/taur_naga.dmi'
|
||||
if(S.taurmode == PAW_TAURIC)
|
||||
S.alternate_worn_icon = 'modular_citadel/icons/mob/taur_canine.dmi'
|
||||
if(S.taurmode == NOT_TAURIC && S.adjusted == ALT_STYLE)
|
||||
S.alternate_worn_icon = 'modular_citadel/icons/mob/suit_digi.dmi'
|
||||
else if(S.taurmode == NOT_TAURIC && S.adjusted == NORMAL_STYLE)
|
||||
S.alternate_worn_icon = null
|
||||
|
||||
overlays_standing[SUIT_LAYER] = S.build_worn_icon(state = wear_suit.icon_state, default_layer = SUIT_LAYER, default_icon_file = ((wear_suit.alternate_worn_icon) ? S.alternate_worn_icon : 'icons/mob/suit.dmi'))
|
||||
var/mutable_appearance/suit_overlay = overlays_standing[SUIT_LAYER]
|
||||
if(OFFSET_SUIT in dna.species.offset_features)
|
||||
@@ -707,9 +709,9 @@ generate/load female uniform sprites matching all previously decided variables
|
||||
if(lip_style && (LIPS in dna.species.species_traits))
|
||||
var/mutable_appearance/lip_overlay = mutable_appearance('icons/mob/human_face.dmi', "lips_[lip_style]", -BODY_LAYER)
|
||||
lip_overlay.color = lip_color
|
||||
if(OFFSET_FACE in dna.species.offset_features)
|
||||
lip_overlay.pixel_x += dna.species.offset_features[OFFSET_FACE][1]
|
||||
lip_overlay.pixel_y += dna.species.offset_features[OFFSET_FACE][2]
|
||||
if(OFFSET_LIPS in dna.species.offset_features)
|
||||
lip_overlay.pixel_x += dna.species.offset_features[OFFSET_LIPS][1]
|
||||
lip_overlay.pixel_y += dna.species.offset_features[OFFSET_LIPS][2]
|
||||
add_overlay(lip_overlay)
|
||||
|
||||
// eyes
|
||||
@@ -722,9 +724,9 @@ generate/load female uniform sprites matching all previously decided variables
|
||||
eye_overlay = mutable_appearance('icons/mob/human_face.dmi', "eyes", -BODY_LAYER)
|
||||
if((EYECOLOR in dna.species.species_traits) && has_eyes)
|
||||
eye_overlay.color = "#" + eye_color
|
||||
if(OFFSET_FACE in dna.species.offset_features)
|
||||
eye_overlay.pixel_x += dna.species.offset_features[OFFSET_FACE][1]
|
||||
eye_overlay.pixel_y += dna.species.offset_features[OFFSET_FACE][2]
|
||||
if(OFFSET_EYES in dna.species.offset_features)
|
||||
eye_overlay.pixel_x += dna.species.offset_features[OFFSET_EYES][1]
|
||||
eye_overlay.pixel_y += dna.species.offset_features[OFFSET_EYES][2]
|
||||
add_overlay(eye_overlay)
|
||||
|
||||
dna.species.handle_hair(src)
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
damageoverlaytemp = 0
|
||||
update_damage_hud()
|
||||
|
||||
if(stat != DEAD) //Reagent processing needs to come before breathing, to prevent edge cases.
|
||||
handle_organs()
|
||||
//Reagent processing needs to come before breathing, to prevent edge cases.
|
||||
handle_organs()
|
||||
|
||||
. = ..()
|
||||
|
||||
@@ -28,11 +28,14 @@
|
||||
if(stat != DEAD)
|
||||
handle_brain_damage()
|
||||
|
||||
/* BUG_PROBABLE_CAUSE
|
||||
if(stat != DEAD)
|
||||
handle_liver()
|
||||
*/
|
||||
|
||||
if(stat == DEAD)
|
||||
stop_sound_channel(CHANNEL_HEARTBEAT)
|
||||
handle_death()
|
||||
rot()
|
||||
|
||||
//Updates the number of stored chemicals for powers
|
||||
@@ -41,14 +44,34 @@
|
||||
if(stat != DEAD)
|
||||
return 1
|
||||
|
||||
//Procs called while dead
|
||||
/mob/living/carbon/proc/handle_death()
|
||||
for(var/datum/reagent/R in reagents.reagent_list)
|
||||
if(R.chemical_flags & REAGENT_DEAD_PROCESS)
|
||||
R.on_mob_dead(src)
|
||||
|
||||
///////////////
|
||||
// BREATHING //
|
||||
///////////////
|
||||
|
||||
//Start of a breath chain, calls breathe()
|
||||
/mob/living/carbon/handle_breathing(times_fired)
|
||||
if((times_fired % 4) == 2 || failed_last_breath)
|
||||
breathe() //Breathe per 4 ticks, unless suffocating
|
||||
var/next_breath = 4
|
||||
var/obj/item/organ/lungs/L = getorganslot(ORGAN_SLOT_LUNGS)
|
||||
var/obj/item/organ/heart/H = getorganslot(ORGAN_SLOT_HEART)
|
||||
if(L)
|
||||
if(L.damage > L.high_threshold)
|
||||
next_breath--
|
||||
if(H)
|
||||
if(H.damage > H.high_threshold)
|
||||
next_breath--
|
||||
|
||||
if((times_fired % next_breath) == 0 || failed_last_breath)
|
||||
breathe() //Breathe per 4 ticks if healthy, down to 2 if our lungs or heart are damaged, unless suffocating
|
||||
if(failed_last_breath)
|
||||
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "suffocation", /datum/mood_event/suffocation)
|
||||
else
|
||||
SEND_SIGNAL(src, COMSIG_CLEAR_MOOD_EVENT, "suffocation")
|
||||
else
|
||||
if(istype(loc, /obj/))
|
||||
var/obj/location_as_object = loc
|
||||
@@ -56,6 +79,7 @@
|
||||
|
||||
//Second link in a breath chain, calls check_breath()
|
||||
/mob/living/carbon/proc/breathe()
|
||||
var/obj/item/organ/lungs = getorganslot(ORGAN_SLOT_LUNGS)
|
||||
if(reagents.has_reagent("lexorin"))
|
||||
return
|
||||
if(istype(loc, /obj/machinery/atmospherics/components/unary/cryo_cell))
|
||||
@@ -74,7 +98,7 @@
|
||||
var/datum/gas_mixture/breath
|
||||
|
||||
if(!getorganslot(ORGAN_SLOT_BREATHING_TUBE))
|
||||
if(health <= HEALTH_THRESHOLD_FULLCRIT || (pulledby && pulledby.grab_state >= GRAB_KILL))
|
||||
if(health <= HEALTH_THRESHOLD_FULLCRIT || (pulledby && pulledby.grab_state >= GRAB_KILL) || lungs.organ_flags & ORGAN_FAILING)
|
||||
losebreath++ //You can't breath at all when in critical or when being choked, so you're going to miss a breath
|
||||
|
||||
else if(health <= crit_threshold)
|
||||
@@ -126,7 +150,7 @@
|
||||
if((status_flags & GODMODE))
|
||||
return
|
||||
|
||||
var/lungs = getorganslot(ORGAN_SLOT_LUNGS)
|
||||
var/obj/item/organ/lungs = getorganslot(ORGAN_SLOT_LUNGS)
|
||||
if(!lungs)
|
||||
adjustOxyLoss(2)
|
||||
|
||||
@@ -366,9 +390,16 @@
|
||||
. |= BP.on_life()
|
||||
|
||||
/mob/living/carbon/proc/handle_organs()
|
||||
for(var/V in internal_organs)
|
||||
var/obj/item/organ/O = V
|
||||
O.on_life()
|
||||
if(stat != DEAD)
|
||||
for(var/V in internal_organs)
|
||||
var/obj/item/organ/O = V
|
||||
if(O)
|
||||
O.on_life()
|
||||
else
|
||||
for(var/V in internal_organs)
|
||||
var/obj/item/organ/O = V
|
||||
if(O)
|
||||
O.on_death() //Needed so organs decay while inside the body.
|
||||
|
||||
/mob/living/carbon/handle_diseases()
|
||||
for(var/thing in diseases)
|
||||
@@ -613,7 +644,7 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put
|
||||
to_chat(src, "<span class='warning'>Maybe you should lie down for a bit...</span>")
|
||||
|
||||
if(drunkenness >= 91)
|
||||
adjustBrainLoss(0.4, 60)
|
||||
adjustOrganLoss(ORGAN_SLOT_BRAIN, 0.4, 60)
|
||||
if(prob(20) && !stat)
|
||||
if(SSshuttle.emergency.mode == SHUTTLE_DOCKED && is_station_level(z)) //QoL mainly
|
||||
to_chat(src, "<span class='warning'>You're so tired... but you can't miss that shuttle...</span>")
|
||||
@@ -647,8 +678,8 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put
|
||||
if((!dna && !liver) || (NOLIVER in dna.species.species_traits))
|
||||
return
|
||||
if(liver)
|
||||
if(liver.damage >= liver.maxHealth)
|
||||
liver.failing = TRUE
|
||||
if(liver.damage < liver.maxHealth)
|
||||
liver.organ_flags |= ORGAN_FAILING
|
||||
liver_failure()
|
||||
else
|
||||
liver_failure()
|
||||
@@ -687,13 +718,6 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put
|
||||
var/datum/brain_trauma/BT = T
|
||||
BT.on_life()
|
||||
|
||||
if(getBrainLoss() >= BRAIN_DAMAGE_DEATH) //rip
|
||||
to_chat(src, "<span class='userdanger'>The last spark of life in your brain fizzles out...<span>")
|
||||
death()
|
||||
var/obj/item/organ/brain/B = getorganslot(ORGAN_SLOT_BRAIN)
|
||||
if(B)
|
||||
B.damaged_brain = TRUE
|
||||
|
||||
/////////////////////////////////////
|
||||
//MONKEYS WITH TOO MUCH CHOLOESTROL//
|
||||
/////////////////////////////////////
|
||||
@@ -702,7 +726,7 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put
|
||||
if(!needs_heart())
|
||||
return FALSE
|
||||
var/obj/item/organ/heart/heart = getorganslot(ORGAN_SLOT_HEART)
|
||||
if(!heart || heart.synthetic)
|
||||
if(!heart || (heart.organ_flags & ORGAN_SYNTHETIC))
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/mob/living/carbon/monkey/can_equip(obj/item/I, slot, disable_warning = 0)
|
||||
/mob/living/carbon/monkey/can_equip(obj/item/I, slot, disable_warning = FALSE, bypass_equip_delay_self = FALSE)
|
||||
switch(slot)
|
||||
if(SLOT_HANDS)
|
||||
if(get_empty_held_indexes())
|
||||
|
||||
@@ -25,8 +25,6 @@
|
||||
adjustCloneLoss(damage * hit_percent)
|
||||
if(STAMINA)
|
||||
adjustStaminaLoss(damage * hit_percent)
|
||||
if(BRAIN)
|
||||
adjustBrainLoss(damage * hit_percent)
|
||||
return 1
|
||||
|
||||
/mob/living/proc/apply_damage_type(damage = 0, damagetype = BRUTE) //like apply damage except it always uses the damage procs
|
||||
@@ -43,8 +41,6 @@
|
||||
return adjustCloneLoss(damage)
|
||||
if(STAMINA)
|
||||
return adjustStaminaLoss(damage)
|
||||
if(BRAIN)
|
||||
return adjustBrainLoss(damage)
|
||||
|
||||
/mob/living/proc/get_damage_amount(damagetype = BRUTE)
|
||||
switch(damagetype)
|
||||
@@ -60,8 +56,6 @@
|
||||
return getCloneLoss()
|
||||
if(STAMINA)
|
||||
return getStaminaLoss()
|
||||
if(BRAIN)
|
||||
return getBrainLoss()
|
||||
|
||||
|
||||
/mob/living/proc/apply_damages(brute = 0, burn = 0, tox = 0, oxy = 0, clone = 0, def_zone = null, blocked = FALSE, stamina = 0, brain = 0)
|
||||
@@ -218,13 +212,13 @@
|
||||
updatehealth()
|
||||
return amount
|
||||
|
||||
/mob/living/proc/getBrainLoss()
|
||||
. = 0
|
||||
|
||||
/mob/living/proc/adjustBrainLoss(amount, maximum = BRAIN_DAMAGE_DEATH)
|
||||
/mob/living/proc/adjustOrganLoss(slot, amount, maximum)
|
||||
return
|
||||
|
||||
/mob/living/proc/setBrainLoss(amount)
|
||||
/mob/living/proc/setOrganLoss(slot, amount, maximum)
|
||||
return
|
||||
|
||||
/mob/living/proc/getOrganLoss(slot)
|
||||
return
|
||||
|
||||
/mob/living/proc/getStaminaLoss()
|
||||
|
||||
@@ -13,6 +13,10 @@
|
||||
if(!no_bodyparts)
|
||||
spread_bodyparts(no_brain, no_organs)
|
||||
|
||||
for(var/X in implants)
|
||||
var/obj/item/implant/I = X
|
||||
qdel(I)
|
||||
|
||||
spawn_gibs(no_bodyparts)
|
||||
qdel(src)
|
||||
|
||||
|
||||
@@ -255,7 +255,7 @@
|
||||
H.Knockdown(20)
|
||||
else
|
||||
message_param = "<span class='userdanger'>bumps [user.p_their()] head on the ground</span> trying to motion towards %t."
|
||||
H.adjustBrainLoss(5)
|
||||
H.adjustOrganLoss(ORGAN_SLOT_BRAIN, 5)
|
||||
..()
|
||||
|
||||
/datum/emote/living/pout
|
||||
|
||||
@@ -346,6 +346,11 @@
|
||||
if(stat || IsUnconscious() || IsStun() || IsKnockdown() || recoveringstam || (!ignore_restraints && restrained(ignore_grab))) // CIT CHANGE - adds recoveringstam check here
|
||||
return TRUE
|
||||
|
||||
/mob/living/canUseStorage()
|
||||
if (get_num_arms() <= 0)
|
||||
return FALSE
|
||||
return TRUE
|
||||
|
||||
/mob/living/proc/InCritical()
|
||||
return (health <= crit_threshold && (stat == SOFT_CRIT || stat == UNCONSCIOUS))
|
||||
|
||||
@@ -476,7 +481,6 @@
|
||||
setToxLoss(0, 0) //zero as second argument not automatically call updatehealth().
|
||||
setOxyLoss(0, 0)
|
||||
setCloneLoss(0, 0)
|
||||
setBrainLoss(0)
|
||||
setStaminaLoss(0, 0)
|
||||
SetUnconscious(0, FALSE)
|
||||
set_disgust(0)
|
||||
@@ -503,6 +507,13 @@
|
||||
QDEL_LIST_ASSOC_VAL(mood.mood_events)
|
||||
mood.sanity = SANITY_GREAT
|
||||
mood.update_mood()
|
||||
//Heal all organs
|
||||
if(iscarbon(src))
|
||||
var/mob/living/carbon/C = src
|
||||
if(C.internal_organs)
|
||||
for(var/organ in C.internal_organs)
|
||||
var/obj/item/organ/O = organ
|
||||
O.setOrganDamage(0)
|
||||
|
||||
|
||||
//proc called by revive(), to check if we can actually ressuscitate the mob (we don't want to revive him and have him instantly die again)
|
||||
@@ -901,7 +912,7 @@
|
||||
if(mind)
|
||||
mind.transfer_to(new_mob)
|
||||
else
|
||||
new_mob.key = key
|
||||
transfer_ckey(new_mob)
|
||||
|
||||
for(var/para in hasparasites())
|
||||
var/mob/living/simple_animal/hostile/guardian/G = para
|
||||
|
||||
@@ -357,8 +357,8 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
|
||||
return message
|
||||
|
||||
/mob/living/proc/radio(message, message_mode, list/spans, language)
|
||||
var/obj/item/implant/radio/imp = locate() in src
|
||||
if(imp && imp.radio.on)
|
||||
var/obj/item/implant/radio/imp = locate() in implants
|
||||
if(imp?.radio.on)
|
||||
if(message_mode == MODE_HEADSET)
|
||||
imp.radio.talk_into(src, message, , spans, language)
|
||||
return ITALICS | REDUCE_RANGE
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
else
|
||||
padloc = "(UNKNOWN)"
|
||||
src.log_talk(message, LOG_SAY, tag="HOLOPAD in [padloc]")
|
||||
send_speech(message, 7, T, "robot", language = language)
|
||||
send_speech(message, 7, T, "robot", message_language = language)
|
||||
to_chat(src, "<i><span class='game say'>Holopad transmitted, <span class='name'>[real_name]</span> <span class='message robot'>\"[message]\"</span></span></i>")
|
||||
else
|
||||
to_chat(src, "No holopad connected.")
|
||||
|
||||
@@ -35,8 +35,8 @@
|
||||
/mob/living/silicon/setStaminaLoss(amount, updating_stamina = 1)
|
||||
return FALSE
|
||||
|
||||
/mob/living/silicon/adjustBrainLoss(amount)
|
||||
/mob/living/silicon/adjustOrganLoss(slot, amount, maximum = 500)
|
||||
return FALSE
|
||||
|
||||
/mob/living/silicon/setBrainLoss(amount)
|
||||
/mob/living/silicon/setOrganLoss(slot, amount)
|
||||
return FALSE
|
||||
|
||||
@@ -192,7 +192,7 @@
|
||||
/mob/proc/makePAI(delold)
|
||||
var/obj/item/paicard/card = new /obj/item/paicard(get_turf(src))
|
||||
var/mob/living/silicon/pai/pai = new /mob/living/silicon/pai(card)
|
||||
pai.key = key
|
||||
transfer_ckey(pai)
|
||||
pai.name = name
|
||||
card.setPersonality(pai)
|
||||
if(delold)
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
/mob/living/silicon/pai/adjustStaminaLoss(amount)
|
||||
take_holo_damage(amount & 0.25)
|
||||
|
||||
/mob/living/silicon/pai/adjustBrainLoss(amount)
|
||||
/mob/living/silicon/pai/adjustOrganLoss(slot, amount, maximum = 500) //I kept this in, unlike tg
|
||||
Knockdown(amount * 0.2)
|
||||
|
||||
/mob/living/silicon/pai/getBruteLoss()
|
||||
@@ -102,18 +102,12 @@
|
||||
/mob/living/silicon/pai/getCloneLoss()
|
||||
return FALSE
|
||||
|
||||
/mob/living/silicon/pai/getBrainLoss()
|
||||
return FALSE
|
||||
|
||||
/mob/living/silicon/pai/getStaminaLoss()
|
||||
return FALSE
|
||||
|
||||
/mob/living/silicon/pai/setCloneLoss()
|
||||
return FALSE
|
||||
|
||||
/mob/living/silicon/pai/setBrainLoss()
|
||||
return FALSE
|
||||
|
||||
/mob/living/silicon/pai/setStaminaLoss()
|
||||
return FALSE
|
||||
|
||||
|
||||
@@ -290,7 +290,7 @@
|
||||
to_chat(user, "<span class='warning'>Access denied.</span>")
|
||||
else if(istype(W, /obj/item/paicard))
|
||||
insertpai(user, W)
|
||||
else if(istype(W, /obj/item/hemostat) && paicard)
|
||||
else if(W.tool_behaviour == TOOL_HEMOSTAT && paicard)
|
||||
if(open)
|
||||
to_chat(user, "<span class='warning'>Close the access panel before manipulating the personality slot!</span>")
|
||||
else
|
||||
@@ -808,11 +808,18 @@ Pass a positive integer as an argument to override a bot's default speed.
|
||||
|
||||
switch(href_list["operation"])
|
||||
if("patrol")
|
||||
if(!issilicon(usr) && !IsAdminGhost(usr) && !(bot_core.allowed(usr) || !locked))
|
||||
return TRUE
|
||||
auto_patrol = !auto_patrol
|
||||
bot_reset()
|
||||
if("remote")
|
||||
remote_disabled = !remote_disabled
|
||||
if("hack")
|
||||
if(!issilicon(usr) && !IsAdminGhost(usr))
|
||||
var/msg = "[key_name(usr)] attempted to hack a bot with a href that shouldn't be available!"
|
||||
message_admins(msg)
|
||||
log_admin(msg)
|
||||
return TRUE
|
||||
if(emagged != 2)
|
||||
emagged = 2
|
||||
hacked = TRUE
|
||||
@@ -915,7 +922,7 @@ Pass a positive integer as an argument to override a bot's default speed.
|
||||
if(mind && paicard.pai)
|
||||
mind.transfer_to(paicard.pai)
|
||||
else if(paicard.pai)
|
||||
paicard.pai.key = key
|
||||
transfer_ckey(paicard.pai)
|
||||
else
|
||||
ghostize(0) // The pAI card that just got ejected was dead.
|
||||
key = null
|
||||
|
||||
@@ -131,7 +131,8 @@ Auto Patrol: []"},
|
||||
/mob/living/simple_animal/bot/secbot/Topic(href, href_list)
|
||||
if(..())
|
||||
return 1
|
||||
|
||||
if(!issilicon(usr) && !IsAdminGhost(usr) && !(bot_core.allowed(usr) || !locked))
|
||||
return TRUE
|
||||
switch(href_list["operation"])
|
||||
if("idcheck")
|
||||
idcheck = !idcheck
|
||||
|
||||
@@ -160,7 +160,7 @@
|
||||
if(mind)
|
||||
mind.transfer_to(R, 1)
|
||||
else
|
||||
R.key = key
|
||||
transfer_ckey(R)
|
||||
qdel(src)
|
||||
|
||||
|
||||
|
||||
@@ -61,5 +61,5 @@
|
||||
var/obj/item/new_hat = new hat_type(D)
|
||||
D.equip_to_slot_or_del(new_hat, SLOT_HEAD)
|
||||
D.flags_1 |= (flags_1 & ADMIN_SPAWNED_1)
|
||||
D.key = user.key
|
||||
user.transfer_ckey(D, FALSE)
|
||||
qdel(src)
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
. = ..()
|
||||
GET_COMPONENT_FROM(hidden_uplink, /datum/component/uplink, internal_storage)
|
||||
hidden_uplink.telecrystals = 30
|
||||
var/obj/item/implant/weapons_auth/W = new/obj/item/implant/weapons_auth(src)
|
||||
var/obj/item/implant/weapons_auth/W = new
|
||||
W.implant(src)
|
||||
|
||||
/mob/living/simple_animal/drone/snowflake
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
return 0
|
||||
|
||||
|
||||
/mob/living/simple_animal/drone/can_equip(obj/item/I, slot)
|
||||
/mob/living/simple_animal/drone/can_equip(obj/item/I, slot, disable_warning = FALSE, bypass_equip_delay_self = FALSE)
|
||||
switch(slot)
|
||||
if(SLOT_HEAD)
|
||||
if(head)
|
||||
|
||||
@@ -429,9 +429,9 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
|
||||
to_chat(G, "<span class='holoparasite'>Your user reset you, and your body was taken over by a ghost. Looks like they weren't happy with your performance.</span>")
|
||||
to_chat(src, "<span class='holoparasite bold'>Your <font color=\"[G.namedatum.colour]\">[G.real_name]</font> has been successfully reset.</span>")
|
||||
message_admins("[key_name_admin(C)] has taken control of ([key_name_admin(G)])")
|
||||
G.ghostize(0)
|
||||
G.ghostize(FALSE)
|
||||
G.setthemename(G.namedatum.theme) //give it a new color, to show it's a new person
|
||||
G.key = C.key
|
||||
C.transfer_ckey(G)
|
||||
G.reset = 1
|
||||
switch(G.namedatum.theme)
|
||||
if("tech")
|
||||
|
||||
@@ -52,7 +52,7 @@
|
||||
return 1
|
||||
return 0
|
||||
|
||||
/mob/living/simple_animal/hostile/guardian/dextrous/can_equip(obj/item/I, slot)
|
||||
/mob/living/simple_animal/hostile/guardian/dextrous/can_equip(obj/item/I, slot, disable_warning = FALSE, bypass_equip_delay_self = FALSE)
|
||||
switch(slot)
|
||||
if(SLOT_GENERC_DEXTROUS_STORAGE)
|
||||
if(internal_storage)
|
||||
|
||||
@@ -90,7 +90,7 @@
|
||||
if(key)
|
||||
to_chat(user, "<span class='notice'>Someone else already took this spider.</span>")
|
||||
return 1
|
||||
key = user.key
|
||||
user.transfer_ckey(src, FALSE)
|
||||
return 1
|
||||
|
||||
//nursemaids - these create webs and eggs
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
#define GOOSE_SATIATED 50
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/goose
|
||||
name = "goose"
|
||||
desc = "It's loose"
|
||||
icon_state = "goose" // sprites by cogwerks from goonstation, used with permission
|
||||
icon_living = "goose"
|
||||
icon_dead = "goose_dead"
|
||||
mob_biotypes = list(MOB_ORGANIC, MOB_BEAST)
|
||||
speak_chance = 0
|
||||
turns_per_move = 5
|
||||
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat = 2)
|
||||
response_help = "pets"
|
||||
response_disarm = "gently pushes aside"
|
||||
response_harm = "kicks"
|
||||
emote_taunt = list("hisses")
|
||||
taunt_chance = 30
|
||||
speed = 0
|
||||
maxHealth = 25
|
||||
health = 25
|
||||
harm_intent_damage = 5
|
||||
melee_damage_lower = 5
|
||||
melee_damage_upper = 5
|
||||
attacktext = "pecks"
|
||||
attack_sound = "goose"
|
||||
speak_emote = list("honks")
|
||||
faction = list("neutral")
|
||||
attack_same = TRUE
|
||||
gold_core_spawnable = HOSTILE_SPAWN
|
||||
var/random_retaliate = TRUE
|
||||
|
||||
/mob/living/simple_animal/hostile/retaliate/goose/handle_automated_movement()
|
||||
. = ..()
|
||||
if(prob(5) && random_retaliate == TRUE)
|
||||
Retaliate()
|
||||
@@ -585,7 +585,7 @@ Difficulty: Very Hard
|
||||
var/be_helper = alert("Become a Lightgeist? (Warning, You can no longer be cloned!)",,"Yes","No")
|
||||
if(be_helper == "Yes" && !QDELETED(src) && isobserver(user))
|
||||
var/mob/living/simple_animal/hostile/lightgeist/W = new /mob/living/simple_animal/hostile/lightgeist(get_turf(loc))
|
||||
W.key = user.key
|
||||
user.transfer_ckey(W, FALSE)
|
||||
|
||||
|
||||
/obj/machinery/anomalous_crystal/helpers/Topic(href, href_list)
|
||||
@@ -649,7 +649,7 @@ Difficulty: Very Hard
|
||||
L.heal_overall_damage(heal_power, heal_power)
|
||||
new /obj/effect/temp_visual/heal(get_turf(target), "#80F5FF")
|
||||
|
||||
/mob/living/simple_animal/hostile/lightgeist/ghostize()
|
||||
/mob/living/simple_animal/hostile/lightgeist/ghostize(can_reenter_corpse = TRUE, send_the_signal = TRUE)
|
||||
. = ..()
|
||||
if(.)
|
||||
death()
|
||||
|
||||
@@ -127,7 +127,7 @@
|
||||
var/client/C = L.client
|
||||
SSmedals.UnlockMedal("Boss [BOSS_KILL_MEDAL]", C)
|
||||
SSmedals.UnlockMedal("[medaltype] [BOSS_KILL_MEDAL]", C)
|
||||
if(crusher_kill && istype(L.get_active_held_item(), /obj/item/twohanded/required/kinetic_crusher))
|
||||
if(crusher_kill && istype(L.get_active_held_item(), /obj/item/twohanded/kinetic_crusher))
|
||||
SSmedals.UnlockMedal("[medaltype] [BOSS_KILL_MEDAL_CRUSHER]", C)
|
||||
SSmedals.SetScore(BOSS_SCORE, C, 1)
|
||||
SSmedals.SetScore(score_type, C, 1)
|
||||
|
||||
@@ -46,7 +46,8 @@
|
||||
fireball.human_req = 0
|
||||
fireball.player_lock = 0
|
||||
AddSpell(fireball)
|
||||
implants += new /obj/item/implant/exile(src)
|
||||
var/obj/item/implant/exile/I = new
|
||||
I.implant(src, null, TRUE)
|
||||
|
||||
mm = new /obj/effect/proc_holder/spell/targeted/projectile/magic_missile
|
||||
mm.clothes_req = 0
|
||||
|
||||
@@ -916,7 +916,7 @@
|
||||
if(mind)
|
||||
mind.transfer_to(G)
|
||||
else
|
||||
G.key = key
|
||||
transfer_ckey(G)
|
||||
..(gibbed)
|
||||
|
||||
/mob/living/simple_animal/parrot/Poly/proc/Read_Memory()
|
||||
|
||||
@@ -198,7 +198,7 @@
|
||||
if(src.mind)
|
||||
src.mind.transfer_to(new_slime)
|
||||
else
|
||||
new_slime.key = src.key
|
||||
transfer_ckey(new_slime)
|
||||
qdel(src)
|
||||
else
|
||||
to_chat(src, "<i>I am not ready to reproduce yet...</i>")
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
.=..()
|
||||
if ((from.pH > 12.5) || (from.pH < 1.5))
|
||||
to_chat(src, "<span class='warning'>You taste chemical burns!</span>")
|
||||
T.adjustTongueLoss(src, 4)
|
||||
T.applyOrganDamage(5)
|
||||
if(istype(T, /obj/item/organ/tongue/cybernetic))
|
||||
to_chat(src, "<span class='notice'>Your tongue moves on it's own in response to the liquid.</span>")
|
||||
say("The pH is appropriately [round(from.pH, 1)].")
|
||||
@@ -52,13 +52,11 @@
|
||||
switch(from.pH)
|
||||
if(11.5 to INFINITY)
|
||||
to_chat(src, "<span class='warning'>You taste a strong alkaline flavour!</span>")
|
||||
T.adjustTongueLoss(src, 1)
|
||||
if(8.5 to 11.5)
|
||||
to_chat(src, "<span class='notice'>You taste a sort of soapy tone in the mixture.</span>")
|
||||
if(2.5 to 5.5)
|
||||
to_chat(src, "<span class='notice'>You taste a sort of acid tone in the mixture.</span>")
|
||||
if(-INFINITY to 2.5)
|
||||
to_chat(src, "<span class='warning'>You taste a strong acidic flavour!</span>")
|
||||
T.adjustTongueLoss(src, 1)
|
||||
|
||||
#undef DEFAULT_TASTE_SENSITIVITY
|
||||
|
||||
+10
-1
@@ -444,7 +444,13 @@
|
||||
// M.Login() //wat
|
||||
return
|
||||
|
||||
|
||||
/mob/proc/transfer_ckey(mob/new_mob, send_signal = TRUE)
|
||||
if(!ckey)
|
||||
return FALSE
|
||||
if(send_signal)
|
||||
SEND_SIGNAL(src, COMSIG_MOB_KEY_CHANGE, new_mob, src)
|
||||
new_mob.ckey = ckey
|
||||
return TRUE
|
||||
|
||||
/mob/verb/cancel_camera()
|
||||
set name = "Cancel Camera View"
|
||||
@@ -810,6 +816,9 @@ GLOBAL_VAR_INIT(exploit_warn_spam_prevention, 0)
|
||||
/mob/proc/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE, no_tk=FALSE)
|
||||
return
|
||||
|
||||
/mob/proc/canUseStorage()
|
||||
return FALSE
|
||||
|
||||
/mob/proc/faction_check_mob(mob/target, exact_match)
|
||||
if(exact_match) //if we need an exact match, we need to do some bullfuckery.
|
||||
var/list/faction_src = faction.Copy()
|
||||
|
||||
@@ -429,8 +429,8 @@ It's fairly easy to fix if dealing with single letters but not so much with comp
|
||||
var/mob/dead/observer/C = pick(candidates)
|
||||
to_chat(M, "Your mob has been taken over by a ghost!")
|
||||
message_admins("[key_name_admin(C)] has taken control of ([key_name_admin(M)])")
|
||||
M.ghostize(0)
|
||||
M.key = C.key
|
||||
M.ghostize(FALSE, TRUE)
|
||||
C.transfer_ckey(M, FALSE)
|
||||
return TRUE
|
||||
else
|
||||
to_chat(M, "There were no ghosts willing to take control.")
|
||||
|
||||
@@ -53,7 +53,7 @@
|
||||
if(mind && isliving(M))
|
||||
mind.transfer_to(M, 1) // second argument to force key move to new mob
|
||||
else
|
||||
M.key = key
|
||||
transfer_ckey(M)
|
||||
|
||||
if(delete_old_mob)
|
||||
QDEL_IN(src, 1)
|
||||
|
||||
@@ -75,7 +75,7 @@
|
||||
O.setOxyLoss(getOxyLoss(), 0)
|
||||
O.setCloneLoss(getCloneLoss(), 0)
|
||||
O.adjustFireLoss(getFireLoss(), 0)
|
||||
O.setBrainLoss(getBrainLoss(), 0)
|
||||
O.setOrganLoss(ORGAN_SLOT_BRAIN, getOrganLoss(ORGAN_SLOT_BRAIN), 0)
|
||||
O.adjustStaminaLoss(getStaminaLoss(), 0)//CIT CHANGE - makes monkey transformations inherit stamina
|
||||
O.updatehealth()
|
||||
O.radiation = radiation
|
||||
@@ -236,7 +236,7 @@
|
||||
O.setOxyLoss(getOxyLoss(), 0)
|
||||
O.setCloneLoss(getCloneLoss(), 0)
|
||||
O.adjustFireLoss(getFireLoss(), 0)
|
||||
O.setBrainLoss(getBrainLoss(), 0)
|
||||
O.setOrganLoss(ORGAN_SLOT_BRAIN, getOrganLoss(ORGAN_SLOT_BRAIN), 0)
|
||||
O.adjustStaminaLoss(getStaminaLoss(), 0)//CIT CHANGE - makes monkey transformations inherit stamina
|
||||
O.updatehealth()
|
||||
O.radiation = radiation
|
||||
@@ -382,7 +382,7 @@
|
||||
mind.active = FALSE
|
||||
mind.transfer_to(R)
|
||||
else if(transfer_after)
|
||||
R.key = key
|
||||
transfer_ckey(R)
|
||||
|
||||
R.apply_pref_name("cyborg")
|
||||
|
||||
@@ -401,7 +401,7 @@
|
||||
qdel(src)
|
||||
|
||||
//human -> alien
|
||||
/mob/living/carbon/human/proc/Alienize()
|
||||
/mob/living/carbon/human/proc/Alienize(mind_transfer = TRUE)
|
||||
if (notransform)
|
||||
return
|
||||
for(var/obj/item/W in src)
|
||||
@@ -425,13 +425,16 @@
|
||||
new_xeno = new /mob/living/carbon/alien/humanoid/drone(loc)
|
||||
|
||||
new_xeno.a_intent = INTENT_HARM
|
||||
new_xeno.key = key
|
||||
if(mind && mind_transfer)
|
||||
mind.transfer_to(new_xeno)
|
||||
else
|
||||
transfer_ckey(new_xeno)
|
||||
|
||||
to_chat(new_xeno, "<B>You are now an alien.</B>")
|
||||
. = new_xeno
|
||||
qdel(src)
|
||||
|
||||
/mob/living/carbon/human/proc/slimeize(reproduce as num)
|
||||
/mob/living/carbon/human/proc/slimeize(reproduce, mind_transfer = TRUE)
|
||||
if (notransform)
|
||||
return
|
||||
for(var/obj/item/W in src)
|
||||
@@ -457,20 +460,26 @@
|
||||
else
|
||||
new_slime = new /mob/living/simple_animal/slime(loc)
|
||||
new_slime.a_intent = INTENT_HARM
|
||||
new_slime.key = key
|
||||
if(mind && mind_transfer)
|
||||
mind.transfer_to(new_slime)
|
||||
else
|
||||
transfer_ckey(new_slime)
|
||||
|
||||
to_chat(new_slime, "<B>You are now a slime. Skreee!</B>")
|
||||
. = new_slime
|
||||
qdel(src)
|
||||
|
||||
/mob/proc/become_overmind(starting_points = 60)
|
||||
/mob/proc/become_overmind(starting_points = 60, mind_transfer = FALSE)
|
||||
var/mob/camera/blob/B = new /mob/camera/blob(get_turf(src), starting_points)
|
||||
B.key = key
|
||||
if(mind && mind_transfer)
|
||||
mind.transfer_to(B)
|
||||
else
|
||||
transfer_ckey(B)
|
||||
. = B
|
||||
qdel(src)
|
||||
|
||||
|
||||
/mob/living/carbon/human/proc/corgize()
|
||||
/mob/living/carbon/human/proc/corgize(mind_transfer = TRUE)
|
||||
if (notransform)
|
||||
return
|
||||
for(var/obj/item/W in src)
|
||||
@@ -485,13 +494,16 @@
|
||||
|
||||
var/mob/living/simple_animal/pet/dog/corgi/new_corgi = new /mob/living/simple_animal/pet/dog/corgi (loc)
|
||||
new_corgi.a_intent = INTENT_HARM
|
||||
new_corgi.key = key
|
||||
if(mind && mind_transfer)
|
||||
mind.transfer_to(new_corgi)
|
||||
else
|
||||
transfer_ckey(new_corgi)
|
||||
|
||||
to_chat(new_corgi, "<B>You are now a Corgi. Yap Yap!</B>")
|
||||
. = new_corgi
|
||||
qdel(src)
|
||||
|
||||
/mob/living/carbon/proc/gorillize()
|
||||
/mob/living/carbon/proc/gorillize(mind_transfer = TRUE)
|
||||
if(notransform)
|
||||
return
|
||||
|
||||
@@ -509,22 +521,22 @@
|
||||
invisibility = INVISIBILITY_MAXIMUM
|
||||
var/mob/living/simple_animal/hostile/gorilla/new_gorilla = new (get_turf(src))
|
||||
new_gorilla.a_intent = INTENT_HARM
|
||||
if(mind)
|
||||
if(mind && mind_transfer)
|
||||
mind.transfer_to(new_gorilla)
|
||||
else
|
||||
new_gorilla.key = key
|
||||
transfer_ckey(new_gorilla)
|
||||
to_chat(new_gorilla, "<B>You are now a gorilla. Ooga ooga!</B>")
|
||||
. = new_gorilla
|
||||
qdel(src)
|
||||
|
||||
/mob/living/carbon/human/Animalize()
|
||||
/mob/living/carbon/human/Animalize(mind_transfer = TRUE)
|
||||
|
||||
var/list/mobtypes = typesof(/mob/living/simple_animal)
|
||||
var/mobpath = input("Which type of mob should [src] turn into?", "Choose a type") in mobtypes
|
||||
|
||||
if(!safe_animal(mobpath))
|
||||
to_chat(usr, "<span class='danger'>Sorry but this mob type is currently unavailable.</span>")
|
||||
var/mobpath = input("Which type of mob should [src] turn into?", "Choose a type") as null|anything in mobtypes
|
||||
if(!mobpath)
|
||||
return
|
||||
if(mind)
|
||||
mind_transfer = alert("Want to transfer their mind into the new mob", "Mind Transfer", "Yes", "No") == "Yes" ? TRUE : FALSE
|
||||
|
||||
if(notransform)
|
||||
return
|
||||
@@ -532,8 +544,8 @@
|
||||
dropItemToGround(W)
|
||||
|
||||
regenerate_icons()
|
||||
notransform = 1
|
||||
canmove = 0
|
||||
notransform = TRUE
|
||||
canmove = FALSE
|
||||
icon = null
|
||||
invisibility = INVISIBILITY_MAXIMUM
|
||||
|
||||
@@ -541,8 +553,10 @@
|
||||
qdel(t)
|
||||
|
||||
var/mob/new_mob = new mobpath(src.loc)
|
||||
|
||||
new_mob.key = key
|
||||
if(mind && mind_transfer)
|
||||
mind.transfer_to(new_mob)
|
||||
else
|
||||
transfer_ckey(new_mob)
|
||||
new_mob.a_intent = INTENT_HARM
|
||||
|
||||
|
||||
@@ -550,59 +564,23 @@
|
||||
. = new_mob
|
||||
qdel(src)
|
||||
|
||||
/mob/proc/Animalize()
|
||||
/mob/proc/Animalize(mind_transfer = TRUE)
|
||||
|
||||
var/list/mobtypes = typesof(/mob/living/simple_animal)
|
||||
var/mobpath = input("Which type of mob should [src] turn into?", "Choose a type") in mobtypes
|
||||
|
||||
if(!safe_animal(mobpath))
|
||||
to_chat(usr, "<span class='danger'>Sorry but this mob type is currently unavailable.</span>")
|
||||
var/mobpath = input("Which type of mob should [src] turn into?", "Choose a type") as null|anything in mobtypes
|
||||
if(!mobpath)
|
||||
return
|
||||
if(mind)
|
||||
mind_transfer = alert("Want to transfer their mind into the new mob", "Mind Transfer", "Yes", "No") == "Yes" ? TRUE : FALSE
|
||||
|
||||
var/mob/new_mob = new mobpath(src.loc)
|
||||
|
||||
new_mob.key = key
|
||||
if(mind && mind_transfer)
|
||||
mind.transfer_to(new_mob)
|
||||
else
|
||||
transfer_ckey(new_mob)
|
||||
new_mob.a_intent = INTENT_HARM
|
||||
to_chat(new_mob, "You feel more... animalistic")
|
||||
|
||||
. = new_mob
|
||||
qdel(src)
|
||||
|
||||
/* Certain mob types have problems and should not be allowed to be controlled by players.
|
||||
*
|
||||
* This proc is here to force coders to manually place their mob in this list, hopefully tested.
|
||||
* This also gives a place to explain -why- players shouldnt be turn into certain mobs and hopefully someone can fix them.
|
||||
*/
|
||||
/mob/proc/safe_animal(MP)
|
||||
|
||||
//Bad mobs! - Remember to add a comment explaining what's wrong with the mob
|
||||
if(!MP)
|
||||
return 0 //Sanity, this should never happen.
|
||||
|
||||
if(ispath(MP, /mob/living/simple_animal/hostile/construct))
|
||||
return 0 //Verbs do not appear for players.
|
||||
|
||||
//Good mobs!
|
||||
if(ispath(MP, /mob/living/simple_animal/pet/cat))
|
||||
return 1
|
||||
if(ispath(MP, /mob/living/simple_animal/pet/dog/corgi))
|
||||
return 1
|
||||
if(ispath(MP, /mob/living/simple_animal/crab))
|
||||
return 1
|
||||
if(ispath(MP, /mob/living/simple_animal/hostile/carp))
|
||||
return 1
|
||||
if(ispath(MP, /mob/living/simple_animal/hostile/mushroom))
|
||||
return 1
|
||||
if(ispath(MP, /mob/living/simple_animal/shade))
|
||||
return 1
|
||||
if(ispath(MP, /mob/living/simple_animal/hostile/killertomato))
|
||||
return 1
|
||||
if(ispath(MP, /mob/living/simple_animal/mouse))
|
||||
return 1 //It is impossible to pull up the player panel for mice (Fixed! - Nodrak)
|
||||
if(ispath(MP, /mob/living/simple_animal/hostile/bear))
|
||||
return 1 //Bears will auto-attack mobs, even if they're player controlled (Fixed! - Nodrak)
|
||||
if(ispath(MP, /mob/living/simple_animal/parrot))
|
||||
return 1 //Parrots are no longer unfinished! -Nodrak
|
||||
|
||||
//Not in here? Must be untested!
|
||||
return 0
|
||||
|
||||
Reference in New Issue
Block a user