This commit is contained in:
Ghommie
2019-10-17 00:50:30 +02:00
539 changed files with 63595 additions and 58228 deletions
+3
View File
@@ -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
+3
View File
@@ -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"
+18 -12
View File
@@ -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
+1 -1
View File
@@ -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)
+3 -1
View File
@@ -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
+144 -14
View File
@@ -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)
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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
+52 -6
View File
@@ -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)
+1 -1
View File
@@ -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))
+85 -58
View File
@@ -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)
+44 -20
View File
@@ -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())
+5 -11
View File
@@ -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()
+4
View File
@@ -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)
+1 -1
View File
@@ -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
+13 -2
View File
@@ -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
+2 -2
View File
@@ -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
+1 -1
View File
@@ -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
+1 -1
View File
@@ -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>")
+1 -3
View File
@@ -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
View File
@@ -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()
+2 -2
View File
@@ -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)
+46 -68
View File
@@ -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