Merge branch 'master' of https://github.com/Citadel-Station-13/Citadel-Station-13 into disablesnolegs
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
@@ -310,7 +310,7 @@
|
||||
});
|
||||
$( "#sortable" ).disableSelection();
|
||||
$('form').submit(function(){
|
||||
$('#IRVdata').val($( "#sortable" ).sortable("toArray", { attribute: "voteid" }));
|
||||
$('#IRVdata').val($( "#sortable" ).sortable("toArray", { attribute: "voteid" }));
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -17,6 +17,8 @@
|
||||
hair_color = random_short_color()
|
||||
facial_hair_color = hair_color
|
||||
eye_color = random_eye_color()
|
||||
horn_color = "85615a"
|
||||
wing_color = "fff"
|
||||
if(!pref_species)
|
||||
var/rando_race = pick(GLOB.roundstart_races)
|
||||
pref_species = new rando_race()
|
||||
|
||||
@@ -54,6 +54,10 @@
|
||||
name = "Redpanda"
|
||||
icon_state = "redpanda"
|
||||
|
||||
/datum/sprite_accessory/mam_body_markings/bat
|
||||
name = "Bat"
|
||||
icon_state = "bat"
|
||||
|
||||
/datum/sprite_accessory/mam_body_markings/bee
|
||||
name = "Bee"
|
||||
icon_state = "bee"
|
||||
|
||||
@@ -130,10 +130,10 @@
|
||||
color_src = MATRIXED
|
||||
|
||||
/datum/sprite_accessory/ears/human/rabbit
|
||||
name = "Rabbit"
|
||||
icon_state = "rabbit"
|
||||
color_src = MATRIXED
|
||||
icon = 'modular_citadel/icons/mob/mam_ears.dmi'
|
||||
name = "Rabbit"
|
||||
icon_state = "rabbit"
|
||||
color_src = MATRIXED
|
||||
icon = 'modular_citadel/icons/mob/mam_ears.dmi'
|
||||
|
||||
/datum/sprite_accessory/ears/human/sergal
|
||||
name = "Sergal"
|
||||
@@ -176,6 +176,10 @@
|
||||
name = "Axolotl"
|
||||
icon_state = "axolotl"
|
||||
|
||||
/datum/sprite_accessory/mam_ears/bat
|
||||
name = "Bat"
|
||||
icon_state = "bat"
|
||||
|
||||
/datum/sprite_accessory/mam_ears/bear
|
||||
name = "Bear"
|
||||
icon_state = "bear"
|
||||
@@ -283,8 +287,8 @@
|
||||
icon_state = "pede"
|
||||
|
||||
/datum/sprite_accessory/mam_ears/rabbit
|
||||
name = "Rabbit"
|
||||
icon_state = "rabbit"
|
||||
name = "Rabbit"
|
||||
icon_state = "rabbit"
|
||||
|
||||
/datum/sprite_accessory/mam_ears/sergal
|
||||
name = "Sergal"
|
||||
|
||||
@@ -194,6 +194,10 @@
|
||||
name = "Mammal, Short ALT"
|
||||
icon_state = "scanidalt"
|
||||
|
||||
/datum/sprite_accessory/mam_snouts/scanidalt2
|
||||
name = "Mammal, Short ALT 2"
|
||||
icon_state = "scanidalt2"
|
||||
|
||||
/datum/sprite_accessory/mam_snouts/wolf
|
||||
name = "Mammal, Thick"
|
||||
icon_state = "wolf"
|
||||
@@ -306,6 +310,10 @@
|
||||
name = "Mammal, Short ALT (Top)"
|
||||
icon_state = "fscanidalt"
|
||||
|
||||
/datum/sprite_accessory/mam_snouts/fscanidalt2
|
||||
name = "Mammal, Short ALT 2 (Top)"
|
||||
icon_state = "fscanidalt2"
|
||||
|
||||
/datum/sprite_accessory/mam_snouts/fwolf
|
||||
name = "Mammal, Thick (Top)"
|
||||
icon_state = "fwolf"
|
||||
|
||||
@@ -114,6 +114,26 @@
|
||||
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
|
||||
color_src = MATRIXED
|
||||
|
||||
/datum/sprite_accessory/mam_tails/batl
|
||||
name = "Bat (Long)"
|
||||
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
|
||||
icon_state = "batl"
|
||||
|
||||
/datum/sprite_accessory/mam_tails_animated/batl
|
||||
name = "Bat (Long)"
|
||||
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
|
||||
icon_state = "batl"
|
||||
|
||||
/datum/sprite_accessory/mam_tails/bats
|
||||
name = "Bat (Short)"
|
||||
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
|
||||
icon_state = "bats"
|
||||
|
||||
/datum/sprite_accessory/mam_tails_animated/bats
|
||||
name = "Bat (Short)"
|
||||
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
|
||||
icon_state = "bats"
|
||||
|
||||
/datum/sprite_accessory/tails/human/bee
|
||||
name = "Bee"
|
||||
icon_state = "bee"
|
||||
@@ -469,6 +489,22 @@
|
||||
name = "Axolotl"
|
||||
icon_state = "axolotl"
|
||||
|
||||
/datum/sprite_accessory/mam_tails/batl
|
||||
name = "Bat (Long)"
|
||||
icon_state = "batl"
|
||||
|
||||
/datum/sprite_accessory/mam_tails_animated/batl
|
||||
name = "Bat (Long)"
|
||||
icon_state = "batl"
|
||||
|
||||
/datum/sprite_accessory/mam_tails/bats
|
||||
name = "Bat (Short)"
|
||||
icon_state = "bats"
|
||||
|
||||
/datum/sprite_accessory/mam_tails_animated/bats
|
||||
name = "Bat (Short)"
|
||||
icon_state = "bats"
|
||||
|
||||
/datum/sprite_accessory/mam_tails/bee
|
||||
name = "Bee"
|
||||
icon_state = "bee"
|
||||
@@ -558,7 +594,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,39 +27,141 @@
|
||||
dimension_y = 34
|
||||
locked = TRUE
|
||||
|
||||
// Decorative wings
|
||||
|
||||
/datum/sprite_accessory/deco_wings
|
||||
icon = 'icons/mob/wings.dmi'
|
||||
color_src = WINGCOLOR
|
||||
|
||||
/datum/sprite_accessory/deco_wings/none
|
||||
name = "None"
|
||||
icon_state = "none"
|
||||
|
||||
/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/bat
|
||||
name = "Bat"
|
||||
icon_state = "bat"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/bee
|
||||
name = "Bee"
|
||||
icon_state = "bee"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/fairy
|
||||
name = "Fairy"
|
||||
icon_state = "fairy"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/feathery
|
||||
name = "Feathery"
|
||||
icon_state = "feathery"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/atlas
|
||||
name = "Atlas"
|
||||
icon_state = "atlas"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/deathhead
|
||||
name = "Deathshead"
|
||||
icon_state = "deathhead"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/firewatch
|
||||
name = "Firewatch"
|
||||
icon_state = "firewatch"
|
||||
|
||||
/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/luna
|
||||
name = "Luna"
|
||||
icon_state = "luna"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/monarch
|
||||
name = "Monarch"
|
||||
icon_state = "monarch"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/moonfly
|
||||
name = "Moon Fly"
|
||||
icon_state = "moonfly"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/plain
|
||||
name = "Plain"
|
||||
icon_state = "plain"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/poison
|
||||
name = "Poison"
|
||||
icon_state = "poison"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/punished
|
||||
name = "Burnt Off"
|
||||
icon_state = "punished"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/ragged
|
||||
name = "Ragged"
|
||||
icon_state = "ragged"
|
||||
|
||||
/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/snow
|
||||
name = "Snow"
|
||||
icon_state = "snow"
|
||||
|
||||
/datum/sprite_accessory/deco_wings/whitefly
|
||||
name = "White Fly"
|
||||
icon_state = "whitefly"
|
||||
|
||||
//INSECT WINGS
|
||||
|
||||
/datum/sprite_accessory/insect_wings
|
||||
icon = 'icons/mob/wings.dmi'
|
||||
color_src = null
|
||||
color_src = WINGCOLOR
|
||||
|
||||
/datum/sprite_accessory/insect_wings/none
|
||||
name = "None"
|
||||
icon_state = "none"
|
||||
|
||||
/datum/sprite_accessory/insect_wings/plain
|
||||
name = "Plain"
|
||||
icon_state = "plain"
|
||||
/datum/sprite_accessory/insect_wings/bat
|
||||
name = "Bat"
|
||||
icon_state = "bat"
|
||||
|
||||
/datum/sprite_accessory/insect_wings/monarch
|
||||
name = "Monarch"
|
||||
icon_state = "monarch"
|
||||
/datum/sprite_accessory/insect_wings/bee
|
||||
name = "Bee"
|
||||
icon_state = "bee"
|
||||
|
||||
/datum/sprite_accessory/insect_wings/luna
|
||||
name = "Luna"
|
||||
icon_state = "luna"
|
||||
/datum/sprite_accessory/insect_wings/fairy
|
||||
name = "Fairy"
|
||||
icon_state = "fairy"
|
||||
|
||||
/datum/sprite_accessory/insect_wings/feathery
|
||||
name = "Feathery"
|
||||
icon_state = "feathery"
|
||||
|
||||
/datum/sprite_accessory/insect_wings/atlas
|
||||
name = "Atlas"
|
||||
icon_state = "atlas"
|
||||
|
||||
/datum/sprite_accessory/insect_wings/reddish
|
||||
name = "Reddish"
|
||||
icon_state = "redish"
|
||||
/datum/sprite_accessory/insect_wings/deathhead
|
||||
name = "Deathshead"
|
||||
icon_state = "deathhead"
|
||||
|
||||
/datum/sprite_accessory/insect_wings/royal
|
||||
name = "Royal"
|
||||
icon_state = "royal"
|
||||
/datum/sprite_accessory/insect_wings/firewatch
|
||||
name = "Firewatch"
|
||||
icon_state = "firewatch"
|
||||
|
||||
/datum/sprite_accessory/insect_wings/gothic
|
||||
name = "Gothic"
|
||||
@@ -69,76 +171,46 @@
|
||||
name = "Lovers"
|
||||
icon_state = "lovers"
|
||||
|
||||
/datum/sprite_accessory/insect_wings/whitefly
|
||||
name = "White Fly"
|
||||
icon_state = "whitefly"
|
||||
/datum/sprite_accessory/insect_wings/luna
|
||||
name = "Luna"
|
||||
icon_state = "luna"
|
||||
|
||||
/datum/sprite_accessory/insect_wings/punished
|
||||
name = "Burnt Off"
|
||||
icon_state = "punished"
|
||||
locked = TRUE
|
||||
|
||||
/datum/sprite_accessory/insect_wings/firewatch
|
||||
name = "Firewatch"
|
||||
icon_state = "firewatch"
|
||||
|
||||
/datum/sprite_accessory/insect_wings/deathhead
|
||||
name = "Deathshead"
|
||||
icon_state = "deathhead"
|
||||
|
||||
/datum/sprite_accessory/insect_wings/poison
|
||||
name = "Poison"
|
||||
icon_state = "poison"
|
||||
|
||||
/datum/sprite_accessory/insect_wings/ragged
|
||||
name = "Ragged"
|
||||
icon_state = "ragged"
|
||||
/datum/sprite_accessory/insect_wings/monarch
|
||||
name = "Monarch"
|
||||
icon_state = "monarch"
|
||||
|
||||
/datum/sprite_accessory/insect_wings/moonfly
|
||||
name = "Moon Fly"
|
||||
icon_state = "moonfly"
|
||||
|
||||
/datum/sprite_accessory/insect_wings/plain
|
||||
name = "Plain"
|
||||
icon_state = "plain"
|
||||
|
||||
/datum/sprite_accessory/insect_wings/poison
|
||||
name = "Poison"
|
||||
icon_state = "poison"
|
||||
|
||||
/datum/sprite_accessory/insect_wings/punished
|
||||
name = "Burnt Off"
|
||||
icon_state = "punished"
|
||||
|
||||
/datum/sprite_accessory/insect_wings/ragged
|
||||
name = "Ragged"
|
||||
icon_state = "ragged"
|
||||
|
||||
/datum/sprite_accessory/insect_wings/reddish
|
||||
name = "Reddish"
|
||||
icon_state = "redish"
|
||||
|
||||
/datum/sprite_accessory/insect_wings/royal
|
||||
name = "Royal"
|
||||
icon_state = "royal"
|
||||
|
||||
/datum/sprite_accessory/insect_wings/snow
|
||||
name = "Snow"
|
||||
icon_state = "snow"
|
||||
|
||||
/datum/sprite_accessory/insect_wings/colored
|
||||
name = "Colored (Hair)"
|
||||
icon_state = "snowplain"
|
||||
color_src = HAIR
|
||||
|
||||
/datum/sprite_accessory/insect_fluff/colored1
|
||||
name = "Colored (Primary)"
|
||||
icon_state = "snowplain"
|
||||
color_src = MUTCOLORS
|
||||
|
||||
/datum/sprite_accessory/insect_fluff/colored2
|
||||
name = "Colored (Secondary)"
|
||||
icon_state = "snowplain"
|
||||
color_src = MUTCOLORS2
|
||||
|
||||
/datum/sprite_accessory/insect_fluff/colored3
|
||||
name = "Colored (Tertiary)"
|
||||
icon_state = "snowplain"
|
||||
color_src = MUTCOLORS3
|
||||
|
||||
/datum/sprite_accessory/insect_wings/bee
|
||||
name = "Bee"
|
||||
icon_state = "bee"
|
||||
|
||||
/datum/sprite_accessory/insect_wings/bee_color
|
||||
name = "Bee (Hair colored)"
|
||||
icon_state = "bee"
|
||||
color_src = HAIR
|
||||
|
||||
/datum/sprite_accessory/insect_wings/fairy
|
||||
name = "Fairy"
|
||||
icon_state = "fairy"
|
||||
|
||||
/datum/sprite_accessory/insect_wings/bat
|
||||
name = "Bat"
|
||||
icon_state = "bat"
|
||||
|
||||
/datum/sprite_accessory/insect_wings/feathery
|
||||
name = "Feathery"
|
||||
icon_state = "feathery"
|
||||
/datum/sprite_accessory/insect_wings/whitefly
|
||||
name = "White Fly"
|
||||
icon_state = "whitefly"
|
||||
@@ -3,6 +3,8 @@ GLOBAL_LIST_EMPTY(ghost_images_simple) //this is a list of all ghost images as t
|
||||
|
||||
GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
|
||||
|
||||
#define CANT_REENTER_ROUND -1
|
||||
|
||||
/mob/dead/observer
|
||||
name = "ghost"
|
||||
desc = "It's a g-g-g-g-ghooooost!" //jinkies!
|
||||
@@ -17,8 +19,9 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
|
||||
see_in_dark = 100
|
||||
invisibility = INVISIBILITY_OBSERVER
|
||||
hud_type = /datum/hud/ghost
|
||||
movement_type = GROUND | FLYING
|
||||
var/can_reenter_corpse
|
||||
var/can_reenter_round = TRUE
|
||||
var/reenter_round_timeout = 0 // used to prevent people from coming back through ghost roles/midround antags as they suicide/cryo for a duration set by CONFIG_GET(number/suicide_reenter_round_timer) and CONFIG_GET(number/roundstart_suicide_time_limit)
|
||||
var/datum/hud/living/carbon/hud = null // hud
|
||||
var/bootime = 0
|
||||
var/started_as_observer //This variable is set to 1 when you enter the game as an observer.
|
||||
@@ -231,7 +234,7 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
|
||||
var/r_val
|
||||
var/b_val
|
||||
var/g_val
|
||||
var/color_format = lentext(input_color)
|
||||
var/color_format = length(input_color)
|
||||
if(color_format == 3)
|
||||
r_val = hex2num(copytext(input_color, 1, 2))*16
|
||||
g_val = hex2num(copytext(input_color, 2, 3))*16
|
||||
@@ -260,16 +263,24 @@ 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, penalize = FALSE)
|
||||
if(!key || cmptext(copytext(key,1,2),"@") || (!special && SEND_SIGNAL(src, COMSIG_MOB_GHOSTIZE, can_reenter_corpse) & 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
|
||||
if(penalize) //penalizing them from making a ghost role / midround antag comeback right away.
|
||||
var/penalty = CONFIG_GET(number/suicide_reenter_round_timer) MINUTES
|
||||
var/roundstart_quit_limit = CONFIG_GET(number/roundstart_suicide_time_limit) MINUTES
|
||||
if(world.time < roundstart_quit_limit) //add up the time difference to their antag rolling penalty if they quit before half a (ingame) hour even passed.
|
||||
penalty += roundstart_quit_limit - world.time
|
||||
if(penalty)
|
||||
ghost.reenter_round_timeout = world.realtime + penalty
|
||||
if(ghost.reenter_round_timeout - SSshuttle.realtimeofstart > SSshuttle.auto_call + SSshuttle.emergencyCallTime + SSshuttle.emergencyDockTime + SSshuttle.emergencyEscapeTime)
|
||||
ghost.reenter_round_timeout = CANT_REENTER_ROUND
|
||||
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,36 +291,57 @@ 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."
|
||||
|
||||
// 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")
|
||||
if(response != "Ghost")//darn copypaste
|
||||
return
|
||||
var/obj/machinery/cryopod/C = loc
|
||||
C.despawn_occupant()
|
||||
if(SEND_SIGNAL(src, COMSIG_MOB_GHOSTIZE, (stat == DEAD) ? TRUE : FALSE, FALSE) & COMPONENT_BLOCK_GHOSTING)
|
||||
return
|
||||
// END EDIT
|
||||
|
||||
var/penalty = CONFIG_GET(number/suicide_reenter_round_timer) MINUTES
|
||||
var/roundstart_quit_limit = CONFIG_GET(number/roundstart_suicide_time_limit) MINUTES
|
||||
if(world.time < roundstart_quit_limit)
|
||||
penalty += roundstart_quit_limit - world.time
|
||||
if(penalty + world.realtime - SSshuttle.realtimeofstart > SSshuttle.auto_call + SSshuttle.emergencyCallTime + SSshuttle.emergencyDockTime + SSshuttle.emergencyEscapeTime)
|
||||
penalty = CANT_REENTER_ROUND
|
||||
|
||||
if(stat != DEAD)
|
||||
succumb()
|
||||
if(stat == DEAD)
|
||||
ghostize(1)
|
||||
else
|
||||
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")
|
||||
var/response = alert(src, "Are you -sure- you want to ghost?\n(You are alive. If you ghost whilst alive you won't be able to re-enter this round [penalty ? "or play ghost roles [penalty == CANT_REENTER_ROUND ? "until the round is over" : "for the next [DisplayTimeText(penalty)]"]" : ""]! You can't change your mind so choose wisely!!)","Are you sure you want to ghost?","Ghost","Stay in body")
|
||||
if(response != "Ghost")
|
||||
return //didn't want to ghost after-all
|
||||
ghostize(0) //0 parameter is so we can never re-enter our body, "Charlie, you can never come baaaack~" :3
|
||||
suicide_log(TRUE)
|
||||
if(istype(loc, /obj/machinery/cryopod))
|
||||
var/obj/machinery/cryopod/C = loc
|
||||
C.despawn_occupant()
|
||||
else
|
||||
ghostize(0, penalize = TRUE) //0 parameter is so we can never re-enter our body, "Charlie, you can never come baaaack~" :3
|
||||
suicide_log(TRUE)
|
||||
|
||||
/mob/camera/verb/ghost()
|
||||
set category = "OOC"
|
||||
set name = "Ghost"
|
||||
set desc = "Relinquish your life and enter the land of the dead."
|
||||
|
||||
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(SEND_SIGNAL(src, COMSIG_MOB_GHOSTIZE, FALSE, FALSE) & COMPONENT_BLOCK_GHOSTING)
|
||||
return
|
||||
|
||||
var/penalty = CONFIG_GET(number/suicide_reenter_round_timer) MINUTES
|
||||
var/roundstart_quit_limit = CONFIG_GET(number/roundstart_suicide_time_limit) MINUTES
|
||||
if(world.time < roundstart_quit_limit)
|
||||
penalty += roundstart_quit_limit - world.time
|
||||
if(penalty + world.realtime - SSshuttle.realtimeofstart > SSshuttle.auto_call + SSshuttle.emergencyCallTime + SSshuttle.emergencyDockTime + SSshuttle.emergencyEscapeTime)
|
||||
penalty = CANT_REENTER_ROUND
|
||||
|
||||
var/response = alert(src, "Are you -sure- you want to ghost?\n(You are alive. If you ghost whilst alive you won't be able to re-enter this round [penalty ? "or play ghost roles [penalty == CANT_REENTER_ROUND ? "until the round is over" : "for the next [DisplayTimeText(penalty)]"]" : ""]! You can't change your mind so choose wisely!!)","Are you sure you want to ghost?","Ghost","Stay in body")
|
||||
if(response != "Ghost")
|
||||
return
|
||||
ghostize(0)
|
||||
ghostize(0, penalize = TRUE)
|
||||
|
||||
/mob/dead/observer/proc/can_reenter_round(silent = FALSE)
|
||||
if(reenter_round_timeout != CANT_REENTER_ROUND && reenter_round_timeout <= world.realtime)
|
||||
return TRUE
|
||||
if(!silent)
|
||||
to_chat(src, "<span class='warning'>You are unable to reenter the round[reenter_round_timeout != CANT_REENTER_ROUND ? " yet. Your ghost role blacklist will expire in [DisplayTimeText(reenter_round_timeout - world.realtime)]" : ""].</span>")
|
||||
return FALSE
|
||||
|
||||
/mob/dead/observer/Move(NewLoc, direct)
|
||||
if(updatedir)
|
||||
@@ -348,7 +380,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)
|
||||
@@ -597,6 +629,9 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
set name = "Possess!"
|
||||
set desc= "Take over the body of a mindless creature!"
|
||||
|
||||
if(!can_reenter_round())
|
||||
return FALSE
|
||||
|
||||
var/list/possessible = list()
|
||||
for(var/mob/living/L in GLOB.alive_mob_list)
|
||||
if(istype(L,/mob/living/carbon/human/dummy) || !get_turf(L)) //Haha no.
|
||||
@@ -617,10 +652,6 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
to_chat(src, "<span class='warning'>This isn't really a creature, now is it!</span>")
|
||||
return 0
|
||||
|
||||
if(!can_reenter_round)
|
||||
to_chat(src, "<span class='warning'>You are unable to re-enter the round.</span>")
|
||||
return FALSE
|
||||
|
||||
if(can_reenter_corpse && mind && mind.current)
|
||||
if(alert(src, "Your soul is still tied to your former life as [mind.current.name], if you go forward there is no going back to that life. Are you sure you wish to continue?", "Move On", "Yes", "No") == "No")
|
||||
return 0
|
||||
@@ -628,7 +659,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
|
||||
|
||||
@@ -865,3 +896,5 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
spawners_menu = new(src)
|
||||
|
||||
spawners_menu.ui_interact(src)
|
||||
|
||||
#undef CANT_REENTER_ROUND
|
||||
@@ -0,0 +1,2 @@
|
||||
/mob/dead/observer/canZMove(direction, turf/target)
|
||||
return TRUE
|
||||
@@ -40,7 +40,7 @@
|
||||
|
||||
if(iscyborg(user) && user.has_buckled_mobs())
|
||||
var/mob/living/silicon/robot/R = user
|
||||
GET_COMPONENT_FROM(riding_datum, /datum/component/riding, R)
|
||||
var/datum/component/riding/riding_datum = R.GetComponent(/datum/component/riding)
|
||||
if(riding_datum)
|
||||
for(var/mob/M in R.buckled_mobs)
|
||||
riding_datum.force_dismount(M)
|
||||
|
||||
@@ -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)
|
||||
@@ -468,3 +468,6 @@
|
||||
bodyparts += BP
|
||||
hand_bodyparts[i] = BP
|
||||
..() //Don't redraw hands until we have organs for them
|
||||
|
||||
/mob/canReachInto(atom/user, atom/target, list/next, view_only, obj/item/tool)
|
||||
return ..() && (user == src)
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
BLOOD SYSTEM
|
||||
****************************************************/
|
||||
|
||||
#define EXOTIC_BLEED_MULTIPLIER 4 //Multiplies the actually bled amount by this number for the purposes of turf reaction calculations.
|
||||
|
||||
|
||||
/mob/living/carbon/human/proc/suppress_bloodloss(amount)
|
||||
if(bleedsuppress)
|
||||
return
|
||||
@@ -30,6 +33,9 @@
|
||||
bleed_rate = 0
|
||||
return
|
||||
|
||||
if(bleed_rate <= 0)
|
||||
bleed_rate = 0
|
||||
|
||||
if(bodytemperature >= TCRYO && !(HAS_TRAIT(src, TRAIT_NOCLONE))) //cryosleep or husked people do not pump the blood.
|
||||
|
||||
//Blood regeneration if there is some space
|
||||
@@ -80,6 +86,9 @@
|
||||
var/obj/item/bodypart/BP = X
|
||||
var/brutedamage = BP.brute_dam
|
||||
|
||||
if(BP.status == BODYPART_ROBOTIC) //for the moment, synth limbs won't bleed, but soon, my pretty.
|
||||
continue
|
||||
|
||||
//We want an accurate reading of .len
|
||||
listclearnulls(BP.embedded_objects)
|
||||
temp_bleed += 0.5*BP.embedded_objects.len
|
||||
@@ -87,7 +96,7 @@
|
||||
if(brutedamage >= 20)
|
||||
temp_bleed += (brutedamage * 0.013)
|
||||
|
||||
bleed_rate = max(bleed_rate - 0.5, temp_bleed)//if no wounds, other bleed effects (heparin) naturally decreases
|
||||
bleed_rate = max(bleed_rate - 0.50, temp_bleed)//if no wounds, other bleed effects (heparin) naturally decreases
|
||||
|
||||
if(bleed_rate && !bleedsuppress && !(HAS_TRAIT(src, TRAIT_FAKEDEATH)))
|
||||
bleed(bleed_rate)
|
||||
@@ -105,9 +114,11 @@
|
||||
/mob/living/carbon/human/bleed(amt)
|
||||
amt *= physiology.bleed_mod
|
||||
if(!(NOBLOOD in dna.species.species_traits))
|
||||
..()
|
||||
|
||||
|
||||
.=..()
|
||||
if(dna.species.exotic_blood && .) // Do we have exotic blood, and have we left any on the ground?
|
||||
var/datum/reagent/R = GLOB.chemical_reagents_list[get_blood_id()]
|
||||
if(istype(R) && isturf(loc))
|
||||
R.reaction_turf(get_turf(src), amt * EXOTIC_BLEED_MULTIPLIER)
|
||||
|
||||
/mob/living/proc/restore_blood()
|
||||
blood_volume = initial(blood_volume)
|
||||
@@ -123,16 +134,16 @@
|
||||
//Gets blood from mob to a container or other mob, preserving all data in it.
|
||||
/mob/living/proc/transfer_blood_to(atom/movable/AM, amount, forced)
|
||||
if(!blood_volume || !AM.reagents)
|
||||
return 0
|
||||
return FALSE
|
||||
if(blood_volume < (BLOOD_VOLUME_BAD * blood_ratio) && !forced)
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
if(blood_volume < amount)
|
||||
amount = blood_volume
|
||||
|
||||
var/blood_id = get_blood_id()
|
||||
if(!blood_id)
|
||||
return 0
|
||||
return FALSE
|
||||
|
||||
blood_volume -= amount
|
||||
|
||||
@@ -141,29 +152,27 @@
|
||||
if(iscarbon(AM))
|
||||
var/mob/living/carbon/C = AM
|
||||
if(blood_id == C.get_blood_id())//both mobs have the same blood substance
|
||||
if(blood_id == "blood") //normal blood
|
||||
if(blood_id == "blood" || blood_id == "jellyblood") //normal blood
|
||||
if(blood_data["viruses"])
|
||||
for(var/thing in blood_data["viruses"])
|
||||
var/datum/disease/D = thing
|
||||
if((D.spread_flags & DISEASE_SPREAD_SPECIAL) || (D.spread_flags & DISEASE_SPREAD_NON_CONTAGIOUS))
|
||||
continue
|
||||
C.ForceContractDisease(D)
|
||||
if(!(blood_data["blood_type"] in get_safe_blood(C.dna.blood_type)))
|
||||
C.reagents.add_reagent("toxin", amount * 0.5)
|
||||
return 1
|
||||
//This used to inject oof ouch results, but since we add the reagent, and the reagent causes oof ouch on mob life... why double dip?
|
||||
|
||||
C.blood_volume = min(C.blood_volume + round(amount, 0.1), BLOOD_VOLUME_MAXIMUM)
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
AM.reagents.add_reagent(blood_id, amount, blood_data, bodytemperature)
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
|
||||
/mob/living/proc/get_blood_data(blood_id)
|
||||
return
|
||||
|
||||
/mob/living/carbon/get_blood_data(blood_id)
|
||||
if(blood_id == "blood") //actual blood reagent
|
||||
if(blood_id == "blood" || blood_id == "jellyblood") //actual blood reagent
|
||||
var/blood_data = list()
|
||||
//set the blood data
|
||||
blood_data["donor"] = src
|
||||
@@ -174,6 +183,7 @@
|
||||
blood_data["viruses"] += D.Copy()
|
||||
|
||||
blood_data["blood_DNA"] = copytext(dna.unique_enzymes,1,0)
|
||||
blood_data["bloodcolor"] = bloodtype_to_color(dna.blood_type)
|
||||
if(disease_resistances && disease_resistances.len)
|
||||
blood_data["resistances"] = disease_resistances.Copy()
|
||||
var/list/temp_chem = list()
|
||||
@@ -206,21 +216,6 @@
|
||||
if(istype(ling))
|
||||
blood_data["changeling_loudness"] = ling.loudfactor
|
||||
return blood_data
|
||||
if(blood_id == "slimejelly") //Just so MKUltra works. Takes the minimum required data. Sishen is testing if this breaks stuff.
|
||||
var/blood_data = list()
|
||||
if(mind)
|
||||
blood_data["mind"] = mind
|
||||
else if(last_mind)
|
||||
blood_data["mind"] = last_mind
|
||||
if(ckey)
|
||||
blood_data["ckey"] = ckey
|
||||
else if(last_mind)
|
||||
blood_data["ckey"] = ckey(last_mind.key)
|
||||
blood_data["gender"] = gender
|
||||
blood_data["real_name"] = real_name
|
||||
return blood_data
|
||||
|
||||
|
||||
|
||||
//get the id of the substance this mob use as blood.
|
||||
/mob/proc/get_blood_id()
|
||||
@@ -234,12 +229,15 @@
|
||||
if(!(HAS_TRAIT(src, TRAIT_NOCLONE)))
|
||||
return "blood"
|
||||
|
||||
/mob/living/carbon/human/get_blood_id()
|
||||
if(dna.species.exotic_blood)
|
||||
/mob/living/carbon/get_blood_id()
|
||||
if(isjellyperson(src))
|
||||
return "jellyblood"
|
||||
if(dna?.species?.exotic_blood)
|
||||
return dna.species.exotic_blood
|
||||
else if((NOBLOOD in dna.species.species_traits) || (HAS_TRAIT(src, TRAIT_NOCLONE)))
|
||||
return
|
||||
return "blood"
|
||||
else
|
||||
return "blood"
|
||||
|
||||
// This is has more potential uses, and is probably faster than the old proc.
|
||||
/proc/get_safe_blood(bloodtype)
|
||||
@@ -248,16 +246,21 @@
|
||||
return
|
||||
|
||||
var/static/list/bloodtypes_safe = list(
|
||||
"A-" = list("A-", "O-"),
|
||||
"A+" = list("A-", "A+", "O-", "O+"),
|
||||
"B-" = list("B-", "O-"),
|
||||
"B+" = list("B-", "B+", "O-", "O+"),
|
||||
"AB-" = list("A-", "B-", "O-", "AB-"),
|
||||
"AB+" = list("A-", "A+", "B-", "B+", "O-", "O+", "AB-", "AB+"),
|
||||
"O-" = list("O-"),
|
||||
"O+" = list("O-", "O+"),
|
||||
"L" = list("L"),
|
||||
"U" = list("A-", "A+", "B-", "B+", "O-", "O+", "AB-", "AB+", "L", "U")
|
||||
"A-" = list("A-", "O-", "SY"),
|
||||
"A+" = list("A-", "A+", "O-", "O+", "SY"),
|
||||
"B-" = list("B-", "O-", "SY"),
|
||||
"B+" = list("B-", "B+", "O-", "O+", "SY"),
|
||||
"AB-" = list("A-", "B-", "O-", "AB-", "SY"),
|
||||
"AB+" = list("A-", "A+", "B-", "B+", "O-", "O+", "AB-", "AB+", "SY"),
|
||||
"O-" = list("O-","SY"),
|
||||
"O+" = list("O-", "O+","SY"),
|
||||
"L" = list("L","SY"),
|
||||
"U" = list("A-", "A+", "B-", "B+", "O-", "O+", "AB-", "AB+", "L", "U","SY"),
|
||||
"HF" = list("HF", "SY"),
|
||||
"X*" = list("X*", "SY"),
|
||||
"SY" = list("SY"),
|
||||
"GEL" = list("GEL","SY"),
|
||||
"BUG" = list("BUG", "SY")
|
||||
)
|
||||
|
||||
var/safe = bloodtypes_safe[bloodtype]
|
||||
@@ -266,7 +269,7 @@
|
||||
|
||||
//to add a splatter of blood or other mob liquid.
|
||||
/mob/living/proc/add_splatter_floor(turf/T, small_drip)
|
||||
if(get_blood_id() != "blood")
|
||||
if(get_blood_id() == null)
|
||||
return
|
||||
if(!T)
|
||||
T = get_turf(src)
|
||||
@@ -280,24 +283,27 @@
|
||||
drop.drips++
|
||||
drop.add_overlay(pick(drop.random_icon_states))
|
||||
drop.transfer_mob_blood_dna(src)
|
||||
drop.update_icon()
|
||||
return
|
||||
else
|
||||
temp_blood_DNA = drop.return_blood_DNA() //we transfer the dna from the drip to the splatter
|
||||
temp_blood_DNA = list()
|
||||
temp_blood_DNA |= drop.blood_DNA.Copy() //we transfer the dna from the drip to the splatter
|
||||
qdel(drop)//the drip is replaced by a bigger splatter
|
||||
else
|
||||
drop = new(T, get_static_viruses())
|
||||
drop.transfer_mob_blood_dna(src)
|
||||
drop.update_icon()
|
||||
return
|
||||
|
||||
// Find a blood decal or create a new one.
|
||||
var/obj/effect/decal/cleanable/blood/B = locate() in T
|
||||
var/obj/effect/decal/cleanable/blood/splats/B = locate() in T
|
||||
if(!B)
|
||||
B = new /obj/effect/decal/cleanable/blood/splatter(T, get_static_viruses())
|
||||
if (B.bloodiness < MAX_SHOE_BLOODINESS) //add more blood, up to a limit
|
||||
B = new /obj/effect/decal/cleanable/blood/splats(T, get_static_viruses())
|
||||
if(B.bloodiness < MAX_SHOE_BLOODINESS) //add more blood, up to a limit
|
||||
B.bloodiness += BLOOD_AMOUNT_PER_DECAL
|
||||
B.transfer_mob_blood_dna(src) //give blood info to the blood decal.
|
||||
if(temp_blood_DNA)
|
||||
B.add_blood_DNA(temp_blood_DNA)
|
||||
B.blood_DNA |= temp_blood_DNA
|
||||
|
||||
/mob/living/carbon/human/add_splatter_floor(turf/T, small_drip)
|
||||
if(!(NOBLOOD in dna.species.species_traits))
|
||||
@@ -306,10 +312,10 @@
|
||||
/mob/living/carbon/alien/add_splatter_floor(turf/T, small_drip)
|
||||
if(!T)
|
||||
T = get_turf(src)
|
||||
var/obj/effect/decal/cleanable/xenoblood/B = locate() in T.contents
|
||||
var/obj/effect/decal/cleanable/blood/splatter/B = locate() in T.contents
|
||||
if(!B)
|
||||
B = new(T)
|
||||
B.add_blood_DNA(list("UNKNOWN DNA" = "X*"))
|
||||
B.blood_DNA["UNKNOWN DNA"] = "X*"
|
||||
|
||||
/mob/living/silicon/robot/add_splatter_floor(turf/T, small_drip)
|
||||
if(!T)
|
||||
@@ -318,6 +324,44 @@
|
||||
if(!B)
|
||||
B = new(T)
|
||||
|
||||
/mob/living/proc/add_splash_floor(turf/T)
|
||||
if(get_blood_id() == null)
|
||||
return
|
||||
if(!T)
|
||||
T = get_turf(src)
|
||||
|
||||
var/list/temp_blood_DNA
|
||||
|
||||
// Find a blood decal or create a new one.
|
||||
var/obj/effect/decal/cleanable/blood/B = locate() in T
|
||||
if(!B)
|
||||
B = new /obj/effect/decal/cleanable/blood/splatter(T, get_static_viruses())
|
||||
if(B.bloodiness < MAX_SHOE_BLOODINESS) //add more blood, up to a limit
|
||||
B.bloodiness += BLOOD_AMOUNT_PER_DECAL
|
||||
B.transfer_mob_blood_dna(src) //give blood info to the blood decal.
|
||||
src.transfer_blood_to(B, 10) //very heavy bleeding, should logically leave larger pools
|
||||
if(temp_blood_DNA)
|
||||
B.blood_DNA |= temp_blood_DNA
|
||||
|
||||
/mob/living/carbon/human/add_splash_floor(turf/T)
|
||||
if(!(NOBLOOD in dna.species.species_traits))
|
||||
..()
|
||||
|
||||
/mob/living/carbon/alien/add_splash_floor(turf/T)
|
||||
if(!T)
|
||||
T = get_turf(src)
|
||||
var/obj/effect/decal/cleanable/blood/splatter/B = locate() in T.contents
|
||||
if(!B)
|
||||
B = new(T)
|
||||
B.blood_DNA["UNKNOWN DNA"] = "X*"
|
||||
|
||||
/mob/living/silicon/robot/add_splash_floor(turf/T)
|
||||
if(!T)
|
||||
T = get_turf(src)
|
||||
var/obj/effect/decal/cleanable/oil/B = locate() in T.contents
|
||||
if(!B)
|
||||
B = new(T)
|
||||
|
||||
//This is a terrible way of handling it.
|
||||
/mob/living/proc/ResetBloodVol()
|
||||
if(ishuman(src))
|
||||
|
||||
@@ -147,13 +147,12 @@
|
||||
/mob/living/proc/exit_blood_effect(obj/effect/decal/cleanable/B)
|
||||
playsound(get_turf(src), 'sound/magic/exit_blood.ogg', 100, 1, -1)
|
||||
//Makes the mob have the color of the blood pool it came out of
|
||||
var/newcolor = rgb(149, 10, 10)
|
||||
if(istype(B, /obj/effect/decal/cleanable/xenoblood))
|
||||
newcolor = rgb(43, 186, 0)
|
||||
var/newcolor = BLOOD_COLOR_HUMAN
|
||||
if(istype(B, /obj/effect/decal/cleanable/blood/xeno))
|
||||
newcolor = BLOOD_COLOR_XENO
|
||||
add_atom_colour(newcolor, TEMPORARY_COLOUR_PRIORITY)
|
||||
// but only for a few seconds
|
||||
spawn(30)
|
||||
remove_atom_colour(TEMPORARY_COLOUR_PRIORITY, newcolor)
|
||||
addtimer(CALLBACK(src, /atom/.proc/remove_atom_colour, TEMPORARY_COLOUR_PRIORITY, newcolor), 6 SECONDS)
|
||||
|
||||
/mob/living/proc/phasein(obj/effect/decal/cleanable/B)
|
||||
if(src.notransform)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
@@ -5,12 +5,16 @@
|
||||
var/datum/dna/stored/stored_dna // dna var for brain. Used to store dna, brain dna is not considered like actual dna, brain.has_dna() returns FALSE.
|
||||
stat = DEAD //we start dead by default
|
||||
see_invisible = SEE_INVISIBLE_LIVING
|
||||
possible_a_intents = list(INTENT_HELP, INTENT_HARM) //for mechas
|
||||
speech_span = SPAN_ROBOT
|
||||
|
||||
/mob/living/brain/Initialize()
|
||||
. = ..()
|
||||
create_dna(src)
|
||||
stored_dna.initialize_dna(random_blood_type())
|
||||
if(stored_dna.blood_type)
|
||||
stored_dna.initialize_dna(stored_dna.blood_type)
|
||||
else
|
||||
stored_dna.initialize_dna(random_blood_type())
|
||||
if(isturf(loc)) //not spawned in an MMI or brain organ (most likely adminspawned)
|
||||
var/obj/item/organ/brain/OB = new(loc) //we create a new brain organ for it.
|
||||
OB.brainmob = src
|
||||
@@ -21,6 +25,8 @@
|
||||
if(!stored_dna.species)
|
||||
var/rando_race = pick(GLOB.roundstart_races)
|
||||
stored_dna.species = new rando_race()
|
||||
if(stored_dna.species.exotic_bloodtype)
|
||||
stored_dna.blood_type = stored_dna.species.exotic_bloodtype
|
||||
|
||||
/mob/living/brain/Destroy()
|
||||
if(key) //If there is a mob connected to this thing. Have to check key twice to avoid false death reporting.
|
||||
@@ -67,10 +73,9 @@
|
||||
|
||||
/mob/living/brain/ClickOn(atom/A, params)
|
||||
..()
|
||||
if(istype(loc, /obj/item/mmi))
|
||||
var/obj/item/mmi/MMI = loc
|
||||
var/obj/mecha/M = MMI.mecha
|
||||
if((src == MMI.brainmob) && istype(M))
|
||||
if(container)
|
||||
var/obj/mecha/M = container.mecha
|
||||
if(istype(M))
|
||||
return M.click_action(A,src,params)
|
||||
|
||||
/mob/living/brain/forceMove(atom/destination)
|
||||
@@ -85,3 +90,16 @@
|
||||
doMove(destination)
|
||||
else
|
||||
CRASH("Brainmob without a container [src] attempted to move to [destination].")
|
||||
|
||||
/mob/living/brain/update_mouse_pointer()
|
||||
if (!client)
|
||||
return
|
||||
client.mouse_pointer_icon = initial(client.mouse_pointer_icon)
|
||||
if(!container)
|
||||
return
|
||||
if (container.mecha)
|
||||
var/obj/mecha/M = container.mecha
|
||||
if(M.mouse_pointer)
|
||||
client.mouse_pointer_icon = M.mouse_pointer
|
||||
if (client && ranged_ability && ranged_ability.ranged_mousepointer)
|
||||
client.mouse_pointer_icon = ranged_ability.ranged_mousepointer
|
||||
|
||||
@@ -7,15 +7,24 @@
|
||||
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()
|
||||
|
||||
/obj/item/organ/brain/Insert(mob/living/carbon/C, special = 0,no_id_transfer = FALSE)
|
||||
/obj/item/organ/brain/Insert(mob/living/carbon/C, special = 0,no_id_transfer = FALSE, drop_if_replaced = TRUE)
|
||||
..()
|
||||
|
||||
name = "brain"
|
||||
@@ -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)
|
||||
|
||||
@@ -36,7 +36,7 @@ GLOBAL_VAR(posibrain_notify_cooldown)
|
||||
|
||||
/obj/item/mmi/posibrain/proc/ping_ghosts(msg, newlymade)
|
||||
if(newlymade || GLOB.posibrain_notify_cooldown <= world.time)
|
||||
notify_ghosts("[name] [msg] in [get_area(src)]!", ghost_sound = !newlymade ? 'sound/misc/server-ready.ogg':null, enter_link = "<a href=?src=[REF(src)];activate=1>(Click to enter)</a>", source = src, action = NOTIFY_ATTACK, flashwindow = FALSE, ignore_key = POLL_IGNORE_POSIBRAIN)
|
||||
notify_ghosts("[name] [msg] in [get_area(src)]!", ghost_sound = !newlymade ? 'sound/misc/server-ready.ogg':null, enter_link = "<a href=?src=[REF(src)];activate=1>(Click to enter)</a>", source = src, action = NOTIFY_ATTACK, flashwindow = FALSE, ignore_key = POLL_IGNORE_POSIBRAIN, ignore_dnr_observers = TRUE)
|
||||
if(!newlymade)
|
||||
GLOB.posibrain_notify_cooldown = world.time + askDelay
|
||||
|
||||
@@ -83,15 +83,29 @@ GLOBAL_VAR(posibrain_notify_cooldown)
|
||||
|
||||
//Two ways to activate a positronic brain. A clickable link in the ghost notif, or simply clicking the object itself.
|
||||
/obj/item/mmi/posibrain/proc/activate(mob/user)
|
||||
if(QDELETED(brainmob))
|
||||
return
|
||||
if(is_occupied() || jobban_isbanned(user,"posibrain") || QDELETED(brainmob) || QDELETED(src) || QDELETED(user))
|
||||
if(QDELETED(brainmob) || is_occupied() || jobban_isbanned(user,"posibrain") || QDELETED(src) || QDELETED(user))
|
||||
return
|
||||
|
||||
if(isobserver(user))
|
||||
var/mob/dead/observer/O = user
|
||||
if(!O.can_reenter_round())
|
||||
return FALSE
|
||||
|
||||
var/posi_ask = alert("Become a [name]? (Warning, You can no longer be cloned, and all past lives will be forgotten!)","Are you positive?","Yes","No")
|
||||
if(posi_ask == "No" || QDELETED(src))
|
||||
return
|
||||
transfer_personality(user)
|
||||
latejoin_remove()
|
||||
|
||||
/obj/item/mmi/posibrain/Destroy()
|
||||
latejoin_remove()
|
||||
return ..()
|
||||
|
||||
/obj/item/mmi/posibrain/proc/latejoin_remove()
|
||||
GLOB.poi_list -= src
|
||||
LAZYREMOVE(GLOB.mob_spawners[name], src)
|
||||
if(!LAZYLEN(GLOB.mob_spawners[name]))
|
||||
GLOB.mob_spawners -= name
|
||||
|
||||
/obj/item/mmi/posibrain/transfer_identity(mob/living/carbon/C)
|
||||
name = "[initial(name)] ([C])"
|
||||
@@ -163,6 +177,8 @@ GLOBAL_VAR(posibrain_notify_cooldown)
|
||||
brainmob.container = src
|
||||
if(autoping)
|
||||
ping_ghosts("created", TRUE)
|
||||
GLOB.poi_list |= src
|
||||
LAZYADD(GLOB.mob_spawners[name], src)
|
||||
|
||||
/obj/item/mmi/posibrain/attackby(obj/item/O, mob/user)
|
||||
return
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
|
||||
var/heat_protection = 0.5
|
||||
var/leaping = 0
|
||||
gib_type = /obj/effect/decal/cleanable/xenoblood/xgibs
|
||||
gib_type = /obj/effect/decal/cleanable/blood/gibs/xeno
|
||||
unique_name = 1
|
||||
|
||||
var/static/regex/alien_name_regex = new("alien (larva|sentinel|drone|hunter|praetorian|queen)( \\(\\d+\\))?")
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
/mob/living/carbon/alien/spawn_gibs(with_bodyparts)
|
||||
/mob/living/carbon/alien/spawn_gibs(with_bodyparts, atom/loc_override)
|
||||
var/location = loc_override ? loc_override.drop_location() : drop_location()
|
||||
if(with_bodyparts)
|
||||
new /obj/effect/gibspawner/xeno(drop_location())
|
||||
new /obj/effect/gibspawner/xeno(location, src)
|
||||
else
|
||||
new /obj/effect/gibspawner/xenobodypartless(drop_location())
|
||||
new /obj/effect/gibspawner/xeno/bodypartless(location, src)
|
||||
|
||||
/mob/living/carbon/alien/gib_animation()
|
||||
new /obj/effect/temp_visual/gib_animation(loc, "gibbed-a")
|
||||
|
||||
@@ -95,8 +95,14 @@ Doesn't work on other aliens/AI.*/
|
||||
var/mob/living/M = input("Select who to whisper to:","Whisper to?",null) as null|mob in options
|
||||
if(!M)
|
||||
return 0
|
||||
if(M.anti_magic_check(FALSE, FALSE, TRUE, 0))
|
||||
to_chat(user, "<span class='noticealien'>As you try to communicate with [M], you're suddenly stopped by a vision of a massive tinfoil wall that streches beyond visible range. It seems you've been foiled.</span>")
|
||||
return FALSE
|
||||
var/msg = sanitize(input("Message:", "Alien Whisper") as text|null)
|
||||
if(msg)
|
||||
if(M.anti_magic_check(FALSE, FALSE, TRUE, 0))
|
||||
to_chat(user, "<span class='notice'>As you try to communicate with [M], you're suddenly stopped by a vision of a massive tinfoil wall that streches beyond visible range. It seems you've been foiled.</span>")
|
||||
return
|
||||
log_directed_talk(user, M, msg, LOG_SAY, tag="alien whisper")
|
||||
to_chat(M, "<span class='noticealien'>You hear a strange, alien voice in your head...</span>[msg]")
|
||||
to_chat(user, "<span class='noticealien'>You said: \"[msg]\" to [M]</span>")
|
||||
|
||||
@@ -6,11 +6,12 @@
|
||||
|
||||
update_icons()
|
||||
|
||||
/mob/living/carbon/alien/larva/spawn_gibs(with_bodyparts)
|
||||
/mob/living/carbon/alien/larva/spawn_gibs(with_bodyparts, atom/loc_override)
|
||||
var/location = loc_override ? loc_override.drop_location() : drop_location()
|
||||
if(with_bodyparts)
|
||||
new /obj/effect/gibspawner/larva(drop_location())
|
||||
new /obj/effect/gibspawner/larva(location, src)
|
||||
else
|
||||
new /obj/effect/gibspawner/larvabodypartless(drop_location())
|
||||
new /obj/effect/gibspawner/larva/bodypartless(location, src)
|
||||
|
||||
/mob/living/carbon/alien/larva/gib_animation()
|
||||
new /obj/effect/temp_visual/gib_animation(loc, "gibbed-l")
|
||||
|
||||
@@ -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()
|
||||
. = ..()
|
||||
@@ -13,7 +14,7 @@
|
||||
QDEL_LIST(alien_powers)
|
||||
return ..()
|
||||
|
||||
/obj/item/organ/alien/Insert(mob/living/carbon/M, special = 0)
|
||||
/obj/item/organ/alien/Insert(mob/living/carbon/M, special = 0, drop_if_replaced = TRUE)
|
||||
..()
|
||||
for(var/obj/effect/proc_holder/alien/P in alien_powers)
|
||||
M.AddAbility(P)
|
||||
@@ -88,10 +89,12 @@
|
||||
owner.adjustFireLoss(-heal_amt)
|
||||
owner.adjustOxyLoss(-heal_amt)
|
||||
owner.adjustCloneLoss(-heal_amt)
|
||||
if(owner.blood_volume && (owner.blood_volume < BLOOD_VOLUME_NORMAL))
|
||||
owner.blood_volume += 5
|
||||
else
|
||||
owner.adjustPlasma(plasma_rate * 0.1)
|
||||
|
||||
/obj/item/organ/alien/plasmavessel/Insert(mob/living/carbon/M, special = 0)
|
||||
/obj/item/organ/alien/plasmavessel/Insert(mob/living/carbon/M, special = 0, drop_if_replaced = TRUE)
|
||||
..()
|
||||
if(isalien(M))
|
||||
var/mob/living/carbon/alien/A = M
|
||||
@@ -114,7 +117,7 @@
|
||||
var/recent_queen_death = 0 //Indicates if the queen died recently, aliens are heavily weakened while this is active.
|
||||
alien_powers = list(/obj/effect/proc_holder/alien/whisper)
|
||||
|
||||
/obj/item/organ/alien/hivenode/Insert(mob/living/carbon/M, special = 0)
|
||||
/obj/item/organ/alien/hivenode/Insert(mob/living/carbon/M, special = 0, drop_if_replaced = TRUE)
|
||||
..()
|
||||
M.faction |= ROLE_ALIEN
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -110,7 +111,7 @@
|
||||
else //When it is removed via surgery at a late stage, rather than forced.
|
||||
new_xeno.visible_message("<span class='danger'>[new_xeno] wriggles out of [owner]!</span>", "<span class='userdanger'>You exit [owner], your previous host.</span>")
|
||||
owner.adjustBruteLoss(40)
|
||||
owner.cut_overlay(overlay)
|
||||
owner.cut_overlay(overlay)
|
||||
qdel(src)
|
||||
|
||||
|
||||
@@ -118,19 +119,19 @@
|
||||
Proc: AddInfectionImages(C)
|
||||
Des: Adds the infection image to all aliens for this embryo
|
||||
----------------------------------------*/
|
||||
/obj/item/organ/body_egg/alien_embryo/AddInfectionImages()
|
||||
/obj/item/organ/body_egg/alien_embryo/AddInfectionImages(mob/living/carbon/C)
|
||||
for(var/mob/living/carbon/alien/alien in GLOB.player_list)
|
||||
if(alien.client)
|
||||
var/I = image('icons/mob/alien.dmi', loc = owner, icon_state = "infected[stage]")
|
||||
var/I = image('icons/mob/alien.dmi', loc = C, icon_state = "infected[stage]")
|
||||
alien.client.images += I
|
||||
|
||||
/*----------------------------------------
|
||||
Proc: RemoveInfectionImage(C)
|
||||
Des: Removes all images from the mob infected by this embryo
|
||||
----------------------------------------*/
|
||||
/obj/item/organ/body_egg/alien_embryo/RemoveInfectionImages()
|
||||
/obj/item/organ/body_egg/alien_embryo/RemoveInfectionImages(mob/living/carbon/C)
|
||||
for(var/mob/living/carbon/alien/alien in GLOB.player_list)
|
||||
if(alien.client)
|
||||
for(var/image/I in alien.client.images)
|
||||
if(dd_hasprefix_case(I.icon_state, "infected") && I.loc == owner)
|
||||
if(dd_hasprefix_case(I.icon_state, "infected") && I.loc == C)
|
||||
qdel(I)
|
||||
|
||||
@@ -170,6 +170,7 @@
|
||||
stop_pulling()
|
||||
if(HAS_TRAIT(src, TRAIT_PACIFISM))
|
||||
to_chat(src, "<span class='notice'>You gently let go of [throwable_mob].</span>")
|
||||
return
|
||||
adjustStaminaLossBuffered(25)//CIT CHANGE - throwing an entire person shall be very tiring
|
||||
var/turf/start_T = get_turf(loc) //Get the start and target tile for the descriptors
|
||||
var/turf/end_T = get_turf(target)
|
||||
@@ -256,7 +257,7 @@
|
||||
|
||||
|
||||
/mob/living/carbon/fall(forced)
|
||||
loc.handle_fall(src, forced)//it's loc so it doesn't call the mob's handle_fall which does nothing
|
||||
loc.handle_fall(src, forced)//it's loc so it doesn't call the mob's handle_fall which does nothing
|
||||
|
||||
/mob/living/carbon/is_muzzled()
|
||||
return(istype(src.wear_mask, /obj/item/clothing/mask/muzzle))
|
||||
@@ -585,7 +586,7 @@
|
||||
if(!isnull(E.lighting_alpha))
|
||||
lighting_alpha = E.lighting_alpha
|
||||
|
||||
if(client.eye != src)
|
||||
if(client.eye && client.eye != src)
|
||||
var/atom/A = client.eye
|
||||
if(A.update_remote_sight(src)) //returns 1 if we override all other sight updates.
|
||||
return
|
||||
@@ -819,7 +820,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)
|
||||
@@ -905,7 +906,7 @@
|
||||
|
||||
/mob/living/carbon/do_after_coefficent()
|
||||
. = ..()
|
||||
GET_COMPONENT_FROM(mood, /datum/component/mood, src) //Currently, only carbons or higher use mood, move this once that changes.
|
||||
var/datum/component/mood/mood = src.GetComponent(/datum/component/mood) //Currently, only carbons or higher use mood, move this once that changes.
|
||||
if(mood)
|
||||
switch(mood.sanity) //Alters do_after delay based on how sane you are
|
||||
if(SANITY_INSANE to SANITY_DISTURBED)
|
||||
@@ -947,7 +948,7 @@
|
||||
return TRUE
|
||||
if(HAS_TRAIT(src, TRAIT_DUMB))
|
||||
return TRUE
|
||||
GET_COMPONENT_FROM(mood, /datum/component/mood, src)
|
||||
var/datum/component/mood/mood = src.GetComponent(/datum/component/mood)
|
||||
if(mood)
|
||||
if(mood.sanity < SANITY_UNSTABLE)
|
||||
return TRUE
|
||||
|
||||
@@ -287,7 +287,7 @@
|
||||
"<span class='notice'>You give [H] a pat on the head to make [p_them()] feel better!</span>")
|
||||
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "headpat", /datum/mood_event/headpat)
|
||||
if(HAS_TRAIT(M, TRAIT_FRIENDLY))
|
||||
GET_COMPONENT_FROM(mood, /datum/component/mood, M)
|
||||
var/datum/component/mood/mood = M.GetComponent(/datum/component/mood)
|
||||
if (mood.sanity >= SANITY_GREAT)
|
||||
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "friendly_hug", /datum/mood_event/besthug, M)
|
||||
else if (mood.sanity >= SANITY_DISTURBED)
|
||||
@@ -322,7 +322,7 @@
|
||||
"<span class='notice'>You hug [src] to make [p_them()] feel better!</span>")
|
||||
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "hug", /datum/mood_event/hug)
|
||||
if(HAS_TRAIT(M, TRAIT_FRIENDLY))
|
||||
GET_COMPONENT_FROM(mood, /datum/component/mood, M)
|
||||
var/datum/component/mood/mood = M.GetComponent(/datum/component/mood)
|
||||
if (mood.sanity >= SANITY_GREAT)
|
||||
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "friendly_hug", /datum/mood_event/besthug, M)
|
||||
else if (mood.sanity >= SANITY_DISTURBED)
|
||||
@@ -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
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
//Gets filled up in create_bodyparts()
|
||||
|
||||
var/list/hand_bodyparts = list() //a collection of arms (or actually whatever the fug /bodyparts you monsters use to wreck my systems)
|
||||
var/list/leg_bodyparts = list()
|
||||
|
||||
var/icon_render_key = ""
|
||||
var/static/list/limb_icon_cache = list()
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
|
||||
/mob/living/carbon/Move(NewLoc, direct)
|
||||
. = ..()
|
||||
if(. && mob_has_gravity()) //floating is easy
|
||||
if(. && (movement_type & FLOATING)) //floating is easy
|
||||
if(HAS_TRAIT(src, TRAIT_NOHUNGER))
|
||||
nutrition = NUTRITION_LEVEL_FED - 1 //just less than feeling vigorous
|
||||
else if(nutrition && stat != DEAD)
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
|
||||
|
||||
/mob/living/carbon/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked = FALSE)
|
||||
/mob/living/carbon/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked = FALSE, forced = FALSE)
|
||||
var/hit_percent = (100-blocked)/100
|
||||
if(hit_percent <= 0)
|
||||
if(!forced && hit_percent <= 0)
|
||||
return 0
|
||||
|
||||
var/obj/item/bodypart/BP = null
|
||||
@@ -15,39 +15,39 @@
|
||||
if(!BP)
|
||||
BP = bodyparts[1]
|
||||
|
||||
var/damage_amount = forced ? damage : damage * hit_percent
|
||||
switch(damagetype)
|
||||
if(BRUTE)
|
||||
if(BP)
|
||||
if(damage > 0 ? BP.receive_damage(damage * hit_percent, 0) : BP.heal_damage(abs(damage * hit_percent), 0))
|
||||
if(damage > 0 ? BP.receive_damage(damage_amount) : BP.heal_damage(abs(damage_amount), 0))
|
||||
update_damage_overlays()
|
||||
else //no bodypart, we deal damage with a more general method.
|
||||
adjustBruteLoss(damage * hit_percent)
|
||||
adjustBruteLoss(damage_amount, forced = forced)
|
||||
if(BURN)
|
||||
if(BP)
|
||||
if(damage > 0 ? BP.receive_damage(0, damage * hit_percent) : BP.heal_damage(0, abs(damage * hit_percent)))
|
||||
if(damage > 0 ? BP.receive_damage(0, damage_amount) : BP.heal_damage(0, abs(damage_amount)))
|
||||
update_damage_overlays()
|
||||
else
|
||||
adjustFireLoss(damage * hit_percent)
|
||||
adjustFireLoss(damage_amount, forced = forced)
|
||||
if(TOX)
|
||||
adjustToxLoss(damage * hit_percent)
|
||||
adjustToxLoss(damage_amount, forced = forced)
|
||||
if(OXY)
|
||||
adjustOxyLoss(damage * hit_percent)
|
||||
adjustOxyLoss(damage_amount, forced = forced)
|
||||
if(CLONE)
|
||||
adjustCloneLoss(damage * hit_percent)
|
||||
adjustCloneLoss(damage_amount, forced = forced)
|
||||
if(STAMINA)
|
||||
if(BP)
|
||||
if(damage > 0 ? BP.receive_damage(0, 0, damage * hit_percent) : BP.heal_damage(0, 0, abs(damage * hit_percent)))
|
||||
if(damage > 0 ? BP.receive_damage(0, 0, damage_amount) : BP.heal_damage(0, 0, abs(damage_amount)))
|
||||
update_damage_overlays()
|
||||
else
|
||||
adjustStaminaLoss(damage * hit_percent)
|
||||
if(BRAIN)
|
||||
adjustBrainLoss(damage * hit_percent)
|
||||
adjustStaminaLoss(damage_amount, forced = forced)
|
||||
//citadel code
|
||||
if(AROUSAL)
|
||||
adjustArousalLoss(damage * hit_percent)
|
||||
adjustArousalLoss(damage_amount)
|
||||
return TRUE
|
||||
|
||||
|
||||
|
||||
//These procs fetch a cumulative total damage from all bodyparts
|
||||
/mob/living/carbon/getBruteLoss()
|
||||
var/amount = 0
|
||||
@@ -86,7 +86,7 @@
|
||||
if(!forced && HAS_TRAIT(src, TRAIT_TOXINLOVER)) //damage becomes healing and healing becomes damage
|
||||
amount = -amount
|
||||
if(amount > 0)
|
||||
blood_volume -= 5*amount
|
||||
blood_volume -= 3*amount // x5 is too much, x3 should be still penalizing enough.
|
||||
else
|
||||
blood_volume -= amount
|
||||
return ..()
|
||||
@@ -113,6 +113,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 +258,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 +299,4 @@
|
||||
if(B)
|
||||
var/adjusted_amount = amount - B.get_brain_damage()
|
||||
B.adjust_brain_damage(adjusted_amount, null)
|
||||
*/
|
||||
|
||||
@@ -31,9 +31,9 @@
|
||||
if (!user.get_bodypart(BODY_ZONE_L_ARM) || !user.get_bodypart(BODY_ZONE_R_ARM))
|
||||
return
|
||||
var/clap = pick('sound/misc/clap1.ogg',
|
||||
'sound/misc/clap2.ogg',
|
||||
'sound/misc/clap3.ogg',
|
||||
'sound/misc/clap4.ogg')
|
||||
'sound/misc/clap2.ogg',
|
||||
'sound/misc/clap3.ogg',
|
||||
'sound/misc/clap4.ogg')
|
||||
playsound(user, clap, 50, 1, -1)
|
||||
|
||||
/datum/emote/living/carbon/gnarl
|
||||
|
||||
@@ -91,8 +91,9 @@
|
||||
|
||||
if(combatmode)
|
||||
msg += "[t_He] [t_is] visibly tense[resting ? "." : ", and [t_is] standing in combative stance."]\n"
|
||||
msg += common_trait_examine()
|
||||
|
||||
GET_COMPONENT_FROM(mood, /datum/component/mood, src)
|
||||
var/datum/component/mood/mood = src.GetComponent(/datum/component/mood)
|
||||
if(mood)
|
||||
switch(mood.shown_mood)
|
||||
if(-INFINITY to MOOD_LEVEL_SAD4)
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
|
||||
/mob/living/carbon/human/apply_damage(damage = 0,damagetype = BRUTE, def_zone = null, blocked = FALSE)
|
||||
/mob/living/carbon/human/apply_damage(damage = 0,damagetype = BRUTE, def_zone = null, blocked = FALSE, forced = FALSE)
|
||||
// depending on the species, it will run the corresponding apply_damage code there
|
||||
return dna.species.apply_damage(damage, damagetype, def_zone, blocked, src)
|
||||
return dna.species.apply_damage(damage, damagetype, def_zone, blocked, src, forced)
|
||||
|
||||
@@ -4,11 +4,21 @@
|
||||
/mob/living/carbon/human/dust_animation()
|
||||
new /obj/effect/temp_visual/dust_animation(loc, "dust-h")
|
||||
|
||||
/mob/living/carbon/human/spawn_gibs(with_bodyparts)
|
||||
if(with_bodyparts)
|
||||
new /obj/effect/gibspawner/human(drop_location(), dna, get_static_viruses())
|
||||
/mob/living/carbon/human/spawn_gibs(with_bodyparts, atom/loc_override)
|
||||
var/location = loc_override ? loc_override.drop_location() : drop_location()
|
||||
if(dna?.species?.gib_types)
|
||||
var/datum/species/S = dna.species
|
||||
var/length = length(S.gib_types)
|
||||
if(length)
|
||||
var/path = (with_bodyparts && length > 1) ? S.gib_types[2] : S.gib_types[1]
|
||||
new path(location, src, get_static_viruses())
|
||||
else
|
||||
new S.gib_types(location, src, get_static_viruses())
|
||||
else
|
||||
new /obj/effect/gibspawner/humanbodypartless(drop_location(), dna, get_static_viruses())
|
||||
if(with_bodyparts)
|
||||
new /obj/effect/gibspawner/human(location, src, get_static_viruses())
|
||||
else
|
||||
new /obj/effect/gibspawner/human/bodypartless(location, src, get_static_viruses())
|
||||
|
||||
/mob/living/carbon/human/spawn_dust(just_ash = FALSE)
|
||||
if(just_ash)
|
||||
@@ -44,11 +54,16 @@
|
||||
/mob/living/carbon/human/proc/makeSkeleton()
|
||||
ADD_TRAIT(src, TRAIT_DISFIGURED, TRAIT_GENERIC)
|
||||
set_species(/datum/species/skeleton)
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
|
||||
/mob/living/carbon/proc/Drain()
|
||||
become_husk(CHANGELING_DRAIN)
|
||||
ADD_TRAIT(src, TRAIT_NOCLONE, CHANGELING_DRAIN)
|
||||
blood_volume = 0
|
||||
return 1
|
||||
return TRUE
|
||||
|
||||
/mob/living/carbon/proc/makeUncloneable()
|
||||
ADD_TRAIT(src, TRAIT_NOCLONE, MADE_UNCLONEABLE)
|
||||
blood_volume = 0
|
||||
return TRUE
|
||||
@@ -4,6 +4,7 @@
|
||||
status_flags = GODMODE|CANPUSH
|
||||
mouse_drag_pointer = MOUSE_INACTIVE_POINTER
|
||||
var/in_use = FALSE
|
||||
no_vore = TRUE
|
||||
|
||||
INITIALIZE_IMMEDIATE(/mob/living/carbon/human/dummy)
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/mob/living/carbon/human/examine(mob/user) //User is the person being examined
|
||||
/mob/living/carbon/human/examine(mob/user)
|
||||
//this is very slightly better than it was because you can use it more places. still can't do \his[src] though.
|
||||
var/t_He = p_they(TRUE)
|
||||
var/t_His = p_their(TRUE)
|
||||
@@ -45,7 +45,7 @@
|
||||
if(wear_suit)
|
||||
msg += "[t_He] [t_is] wearing [wear_suit.get_examine_string(user)].\n"
|
||||
//suit/armor storage
|
||||
if(s_store)
|
||||
if(s_store && !(SLOT_S_STORE in obscured))
|
||||
msg += "[t_He] [t_is] carrying [s_store.get_examine_string(user)] on [t_his] [wear_suit.name].\n"
|
||||
//back
|
||||
if(back)
|
||||
@@ -56,11 +56,10 @@
|
||||
if(!(I.item_flags & ABSTRACT))
|
||||
msg += "[t_He] [t_is] holding [I.get_examine_string(user)] in [t_his] [get_held_index_name(get_held_index_of_item(I))].\n"
|
||||
|
||||
GET_COMPONENT(FR, /datum/component/forensics)
|
||||
//gloves
|
||||
if(gloves && !(SLOT_GLOVES in obscured))
|
||||
msg += "[t_He] [t_has] [gloves.get_examine_string(user)] on [t_his] hands.\n"
|
||||
else if(FR && length(FR.blood_DNA))
|
||||
else if(length(blood_DNA))
|
||||
var/hand_number = get_num_arms(FALSE)
|
||||
if(hand_number)
|
||||
msg += "<span class='warning'>[t_He] [t_has] [hand_number > 1 ? "" : "a"] blood-stained hand[hand_number > 1 ? "s" : ""]!</span>\n"
|
||||
@@ -86,7 +85,7 @@
|
||||
if(wear_mask && !(SLOT_WEAR_MASK in obscured))
|
||||
msg += "[t_He] [t_has] [wear_mask.get_examine_string(user)] on [t_his] face.\n"
|
||||
|
||||
if (wear_neck && !(SLOT_NECK in obscured))
|
||||
if(wear_neck && !(SLOT_NECK in obscured))
|
||||
msg += "[t_He] [t_is] wearing [wear_neck.get_examine_string(user)] around [t_his] neck.\n"
|
||||
|
||||
//eyes
|
||||
@@ -152,7 +151,7 @@
|
||||
|
||||
var/temp = getBruteLoss() //no need to calculate each of these twice
|
||||
|
||||
msg += "<span class='warning'>"
|
||||
msg += "<span class='warning'>" //Everything below gets this span
|
||||
|
||||
var/list/missing = list(BODY_ZONE_HEAD, BODY_ZONE_CHEST, BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG)
|
||||
var/list/disabled = list()
|
||||
@@ -297,7 +296,7 @@
|
||||
msg += "[t_He] seem[p_s()] winded.\n"
|
||||
if (getToxLoss() >= 10)
|
||||
msg += "[t_He] seem[p_s()] sickly.\n"
|
||||
GET_COMPONENT_FROM(mood, /datum/component/mood, src)
|
||||
var/datum/component/mood/mood = src.GetComponent(/datum/component/mood)
|
||||
if(mood.sanity <= SANITY_DISTURBED)
|
||||
msg += "[t_He] seem[p_s()] distressed.\n"
|
||||
SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT, "empath", /datum/mood_event/sad_empath, src)
|
||||
@@ -335,6 +334,8 @@
|
||||
if(digitalcamo)
|
||||
msg += "[t_He] [t_is] moving [t_his] body in an unnatural and blatantly inhuman manner.\n"
|
||||
|
||||
msg += common_trait_examine()
|
||||
|
||||
var/traitstring = get_trait_string()
|
||||
if(ishuman(user))
|
||||
var/mob/living/carbon/human/H = user
|
||||
|
||||
@@ -32,7 +32,7 @@
|
||||
if(CONFIG_GET(flag/disable_stambuffer))
|
||||
togglesprint()
|
||||
|
||||
AddComponent(/datum/component/redirect, list(COMSIG_COMPONENT_CLEAN_ACT = CALLBACK(src, .proc/clean_blood)))
|
||||
RegisterSignal(src, COMSIG_COMPONENT_CLEAN_ACT, /atom.proc/clean_blood)
|
||||
|
||||
|
||||
/mob/living/carbon/human/ComponentInitialize()
|
||||
@@ -488,7 +488,7 @@
|
||||
var/counter = 1
|
||||
while(R.fields[text("com_[]", counter)])
|
||||
counter++
|
||||
R.fields[text("com_[]", counter)] = text("Made by [] on [] [], []<BR>[]", allowed_access, STATION_TIME_TIMESTAMP("hh:mm:ss"), time2text(world.realtime, "MMM DD"), GLOB.year_integer+540, t1)
|
||||
R.fields[text("com_[]", counter)] = text("Made by [] on [] [], []<BR>[]", allowed_access, STATION_TIME_TIMESTAMP("hh:mm:ss"), time2text(world.realtime, "MMM DD"), GLOB.year_integer, t1)
|
||||
to_chat(usr, "<span class='notice'>Successfully added comment.</span>")
|
||||
return
|
||||
to_chat(usr, "<span class='warning'>Unable to locate a data core entry for this person.</span>")
|
||||
@@ -574,7 +574,7 @@
|
||||
return threatcount
|
||||
|
||||
//Check for ID
|
||||
var/obj/item/card/id/idcard = get_idcard()
|
||||
var/obj/item/card/id/idcard = get_idcard(FALSE)
|
||||
if( (judgement_criteria & JUDGE_IDCHECK) && !idcard && name=="Unknown")
|
||||
threatcount += 4
|
||||
|
||||
@@ -689,16 +689,17 @@
|
||||
if(..())
|
||||
dropItemToGround(I)
|
||||
|
||||
/mob/living/carbon/human/proc/clean_blood(datum/source, strength)
|
||||
if(strength < CLEAN_STRENGTH_BLOOD)
|
||||
return
|
||||
if(gloves)
|
||||
if(SEND_SIGNAL(gloves, COMSIG_COMPONENT_CLEAN_ACT, CLEAN_STRENGTH_BLOOD))
|
||||
update_inv_gloves()
|
||||
/mob/living/carbon/human/clean_blood()
|
||||
var/mob/living/carbon/human/H = src
|
||||
if(H.gloves)
|
||||
if(H.gloves.clean_blood())
|
||||
H.update_inv_gloves()
|
||||
else
|
||||
if(bloody_hands)
|
||||
bloody_hands = 0
|
||||
update_inv_gloves()
|
||||
..() // Clear the Blood_DNA list
|
||||
if(H.bloody_hands)
|
||||
H.bloody_hands = 0
|
||||
H.update_inv_gloves()
|
||||
update_icons() //apply the now updated overlays to the mob
|
||||
|
||||
/mob/living/carbon/human/wash_cream()
|
||||
if(creamed) //clean both to prevent a rare bug
|
||||
@@ -865,7 +866,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
|
||||
. = ..()
|
||||
@@ -945,7 +946,7 @@
|
||||
return FALSE
|
||||
|
||||
/mob/living/carbon/human/proc/clear_shove_slowdown()
|
||||
remove_movespeed_modifier(SHOVE_SLOWDOWN_ID)
|
||||
remove_movespeed_modifier(MOVESPEED_ID_SHOVE)
|
||||
var/active_item = get_active_held_item()
|
||||
if(is_type_in_typecache(active_item, GLOB.shove_disarming_types))
|
||||
visible_message("<span class='warning'>[src.name] regains their grip on \the [active_item]!</span>", "<span class='warning'>You regain your grip on \the [active_item]</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
@@ -1104,3 +1105,18 @@
|
||||
|
||||
/mob/living/carbon/human/species/zombie/krokodil_addict
|
||||
race = /datum/species/krokodil_addict
|
||||
|
||||
/mob/living/carbon/human/species/mammal
|
||||
race = /datum/species/mammal
|
||||
|
||||
/mob/living/carbon/human/species/insect
|
||||
race = /datum/species/insect
|
||||
|
||||
/mob/living/carbon/human/species/xeno
|
||||
race = /datum/species/xeno
|
||||
|
||||
/mob/living/carbon/human/species/ipc
|
||||
race = /datum/species/ipc
|
||||
|
||||
/mob/living/carbon/human/species/roundstartslime
|
||||
race = /datum/species/jelly/roundstartslime
|
||||
|
||||
@@ -339,8 +339,10 @@
|
||||
apply_damage(damage, BRUTE, affecting, armor_block)
|
||||
|
||||
/mob/living/carbon/human/mech_melee_attack(obj/mecha/M)
|
||||
|
||||
if(M.occupant.a_intent == INTENT_HARM)
|
||||
if(HAS_TRAIT(M.occupant, TRAIT_PACIFISM))
|
||||
to_chat(M.occupant, "<span class='warning'>You don't want to harm other living beings!</span>")
|
||||
return
|
||||
M.do_attack_animation(src)
|
||||
if(M.damtype == "brute")
|
||||
step_away(src,M,15)
|
||||
@@ -751,9 +753,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[length(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[length(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)
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
|
||||
var/horn_color = "85615a" //specific horn colors, because why not?
|
||||
|
||||
var/wing_color = "fff" //wings too
|
||||
|
||||
var/skin_tone = "caucasian1" //Skin tone
|
||||
|
||||
var/lip_style = null //no lipstick by default- arguably misleading, as it could be used for general makeup
|
||||
@@ -32,8 +34,6 @@
|
||||
var/shirt_color = "FFFFFF"
|
||||
var/socks = "Nude" //Which socks the player wants
|
||||
var/socks_color = "FFFFFF"
|
||||
var/backbag = DBACKPACK //Which backpack type the player has chosen.
|
||||
var/jumpsuit_style = PREF_SUIT //suit/skirt
|
||||
|
||||
//Equipment slots
|
||||
var/obj/item/wear_suit = null
|
||||
@@ -49,6 +49,9 @@
|
||||
var/bleed_rate = 0 //how much are we bleeding
|
||||
var/bleedsuppress = 0 //for stopping bloodloss, eventually this will be limb-based like bleeding
|
||||
|
||||
var/blood_state = BLOOD_STATE_NOT_BLOODY
|
||||
var/list/blood_smear = list(BLOOD_STATE_BLOOD = 0, BLOOD_STATE_OIL = 0, BLOOD_STATE_NOT_BLOODY = 0)
|
||||
|
||||
var/name_override //For temporary visible name changes
|
||||
var/genital_override = FALSE //Force genitals on things incase of chems
|
||||
|
||||
|
||||
@@ -11,8 +11,8 @@
|
||||
|
||||
//gets assignment from ID or ID inside PDA or PDA itself
|
||||
//Useful when player do something with computers
|
||||
/mob/living/carbon/human/proc/get_assignment(if_no_id = "No id", if_no_job = "No job")
|
||||
var/obj/item/card/id/id = get_idcard()
|
||||
/mob/living/carbon/human/proc/get_assignment(if_no_id = "No id", if_no_job = "No job", hand_first = TRUE)
|
||||
var/obj/item/card/id/id = get_idcard(hand_first)
|
||||
if(id)
|
||||
. = id.assignment
|
||||
else
|
||||
@@ -27,7 +27,7 @@
|
||||
//gets name from ID or ID inside PDA or PDA itself
|
||||
//Useful when player do something with computers
|
||||
/mob/living/carbon/human/proc/get_authentification_name(if_no_id = "Unknown")
|
||||
var/obj/item/card/id/id = get_idcard()
|
||||
var/obj/item/card/id/id = get_idcard(FALSE)
|
||||
if(id)
|
||||
return id.registered_name
|
||||
var/obj/item/pda/pda = wear_id
|
||||
@@ -86,10 +86,15 @@
|
||||
return
|
||||
|
||||
//gets ID card object from special clothes slot or null.
|
||||
/mob/living/carbon/human/get_idcard()
|
||||
if(wear_id)
|
||||
return wear_id.GetID()
|
||||
|
||||
/mob/living/carbon/human/get_idcard(hand_first = TRUE)
|
||||
. = ..()
|
||||
if(. && hand_first)
|
||||
return
|
||||
//Check inventory slots
|
||||
var/obj/item/card/id/id_card = wear_id?.GetID()
|
||||
if(!id_card)
|
||||
id_card = belt?.GetID()
|
||||
return id_card || .
|
||||
|
||||
/mob/living/carbon/human/IsAdvancedToolUser()
|
||||
if(HAS_TRAIT(src, TRAIT_MONKEYLIKE))
|
||||
@@ -100,7 +105,6 @@
|
||||
return dna.species.handle_chemicals(R,src)
|
||||
// if it returns 0, it will run the usual on_mob_life for that reagent. otherwise, it will stop after running handle_chemicals for the species.
|
||||
|
||||
|
||||
/mob/living/carbon/human/can_track(mob/living/user)
|
||||
if(wear_id && istype(wear_id.GetID(), /obj/item/card/id/syndicate))
|
||||
return 0
|
||||
@@ -127,3 +131,9 @@
|
||||
return FALSE
|
||||
|
||||
return .
|
||||
/*
|
||||
/mob/living/carbon/human/transfer_blood_dna(list/blood_dna)
|
||||
..()
|
||||
if(blood_dna.len)
|
||||
last_bloodtype = blood_dna[blood_dna[blood_dna.len]]//trust me this works
|
||||
last_blood_DNA = blood_dna[blood_dna.len]*/
|
||||
|
||||
@@ -56,20 +56,20 @@
|
||||
//Bloody footprints
|
||||
var/turf/T = get_turf(src)
|
||||
if(S.bloody_shoes && S.bloody_shoes[S.blood_state])
|
||||
for(var/obj/effect/decal/cleanable/blood/footprints/oldFP in T)
|
||||
if (oldFP.blood_state == S.blood_state)
|
||||
return
|
||||
//No oldFP or they're all a different kind of blood
|
||||
S.bloody_shoes[S.blood_state] = max(0, S.bloody_shoes[S.blood_state] - BLOOD_LOSS_PER_STEP)
|
||||
if (S.bloody_shoes[S.blood_state] > BLOOD_LOSS_IN_SPREAD)
|
||||
var/obj/effect/decal/cleanable/blood/footprints/FP = new /obj/effect/decal/cleanable/blood/footprints(T)
|
||||
FP.blood_state = S.blood_state
|
||||
FP.entered_dirs |= dir
|
||||
FP.bloodiness = S.bloody_shoes[S.blood_state] - BLOOD_LOSS_IN_SPREAD
|
||||
FP.add_blood_DNA(S.return_blood_DNA())
|
||||
FP.update_icon()
|
||||
var/obj/effect/decal/cleanable/blood/footprints/oldFP = locate(/obj/effect/decal/cleanable/blood/footprints) in T
|
||||
if(oldFP && (oldFP.blood_state == S.blood_state && oldFP.color == bloodtype_to_color(S.last_bloodtype)))
|
||||
return
|
||||
S.bloody_shoes[S.blood_state] = max(0, S.bloody_shoes[S.blood_state]-BLOOD_LOSS_PER_STEP)
|
||||
var/obj/effect/decal/cleanable/blood/footprints/FP = new /obj/effect/decal/cleanable/blood/footprints(T)
|
||||
FP.blood_state = S.blood_state
|
||||
FP.entered_dirs |= dir
|
||||
FP.bloodiness = S.bloody_shoes[S.blood_state]
|
||||
if(S.last_bloodtype)
|
||||
FP.blood_DNA += list(S.last_blood_DNA = S.last_bloodtype)
|
||||
FP.update_icon()
|
||||
update_inv_shoes()
|
||||
//End bloody footprints
|
||||
|
||||
S.step_action()
|
||||
|
||||
/mob/living/carbon/human/Process_Spacemove(movement_dir = 0) //Temporary laziness thing. Will change to handles by species reee.
|
||||
|
||||
@@ -79,7 +79,8 @@
|
||||
|
||||
//This is an UNSAFE proc. Use mob_can_equip() before calling this one! Or rather use equip_to_slot_if_possible() or advanced_equip_to_slot_if_possible()
|
||||
/mob/living/carbon/human/equip_to_slot(obj/item/I, slot)
|
||||
if(!..()) //a check failed or the item has already found its slot
|
||||
. = ..()
|
||||
if(!.) //a check failed or the item has already found its slot
|
||||
return
|
||||
|
||||
var/not_handled = FALSE //Added in case we make this type path deeper one day
|
||||
@@ -136,6 +137,7 @@
|
||||
update_inv_s_store()
|
||||
else
|
||||
to_chat(src, "<span class='danger'>You are trying to equip this item to an unsupported inventory slot. Report this to a coder!</span>")
|
||||
not_handled = TRUE
|
||||
|
||||
//Item is handled and in slot, valid to call callback, for this proc should always be true
|
||||
if(!not_handled)
|
||||
@@ -249,7 +251,7 @@
|
||||
sec_hud_set_security_status()
|
||||
..()
|
||||
|
||||
/mob/living/carbon/human/proc/equipOutfit(outfit, visualsOnly = FALSE)
|
||||
/mob/living/carbon/human/proc/equipOutfit(outfit, visualsOnly = FALSE, client/preference_source)
|
||||
var/datum/outfit/O = null
|
||||
|
||||
if(ispath(outfit))
|
||||
@@ -261,7 +263,7 @@
|
||||
if(!O)
|
||||
return 0
|
||||
|
||||
return O.equip(src, visualsOnly)
|
||||
return O.equip(src, visualsOnly, preference_source)
|
||||
|
||||
|
||||
//delete all equipment without dropping anything
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//NOTE: Breathing happens once per FOUR TICKS, unless the last breath fails. In which case it happens once per ONE TICK! So oxyloss healing is done once per 4 ticks while oxyloss damage is applied once per tick!
|
||||
|
||||
// bitflags for the percentual amount of protection a piece of clothing which covers the body part offers.
|
||||
// Used with human/proc/get_heat_protection() and human/proc/get_cold_protection()
|
||||
// Used with human/proc/get_thermal_protection()
|
||||
// The values here should add up to 1.
|
||||
// Hands and feet have 2.5%, arms and legs 7.5%, each of the torso parts has 15% and the head has 30%
|
||||
#define THERMAL_PROTECTION_HEAD 0.3
|
||||
@@ -18,7 +18,7 @@
|
||||
#define THERMAL_PROTECTION_HAND_LEFT 0.025
|
||||
#define THERMAL_PROTECTION_HAND_RIGHT 0.025
|
||||
|
||||
/mob/living/carbon/human/Life()
|
||||
/mob/living/carbon/human/Life(seconds, times_fired)
|
||||
set invisibility = 0
|
||||
if (notransform)
|
||||
return
|
||||
@@ -41,7 +41,7 @@
|
||||
|
||||
if(stat != DEAD)
|
||||
//process your dick energy
|
||||
handle_arousal()
|
||||
handle_arousal(times_fired)
|
||||
|
||||
//Update our name based on whether our face is obscured/disfigured
|
||||
name = get_visible_name()
|
||||
@@ -53,16 +53,17 @@
|
||||
|
||||
|
||||
/mob/living/carbon/human/calculate_affecting_pressure(pressure)
|
||||
if (wear_suit && head && istype(wear_suit, /obj/item/clothing) && istype(head, /obj/item/clothing))
|
||||
var/headless = !get_bodypart(BODY_ZONE_HEAD) //should the mob be perennially headless (see dullahans), we only take the suit into account, so they can into space.
|
||||
if (wear_suit && istype(wear_suit, /obj/item/clothing) && (headless || (head && istype(head, /obj/item/clothing))))
|
||||
var/obj/item/clothing/CS = wear_suit
|
||||
var/obj/item/clothing/CH = head
|
||||
if (CS.clothing_flags & CH.clothing_flags & STOPSPRESSUREDAMAGE)
|
||||
if (CS.clothing_flags & STOPSPRESSUREDAMAGE && (headless || (CH.clothing_flags & STOPSPRESSUREDAMAGE)))
|
||||
return ONE_ATMOSPHERE
|
||||
if(isbelly(loc)) //START OF CIT CHANGES - Makes it so you don't suffocate while inside vore organs. Remind me to modularize this some time - Bhijn
|
||||
return ONE_ATMOSPHERE
|
||||
if(istype(loc, /obj/item/dogborg/sleeper))
|
||||
return ONE_ATMOSPHERE //END OF CIT CHANGES
|
||||
return pressure
|
||||
return ..()
|
||||
|
||||
|
||||
/mob/living/carbon/human/handle_traits()
|
||||
@@ -74,7 +75,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))
|
||||
@@ -136,7 +137,7 @@
|
||||
if(dna)
|
||||
dna.species.handle_fire(src)
|
||||
|
||||
/mob/living/carbon/human/proc/get_thermal_protection()
|
||||
/mob/living/carbon/human/proc/easy_thermal_protection()
|
||||
var/thermal_protection = 0 //Simple check to estimate how protected we are against multiple temperatures
|
||||
//CITADEL EDIT Vore code required overrides
|
||||
if(istype(loc, /obj/item/dogborg/sleeper))
|
||||
@@ -168,7 +169,6 @@
|
||||
..()
|
||||
//END FIRE CODE
|
||||
|
||||
|
||||
//This proc returns a number made up of the flags for body parts which you are protected on. (such as HEAD, CHEST, GROIN, etc. See setup.dm for the full list)
|
||||
/mob/living/carbon/human/proc/get_heat_protection_flags(temperature) //Temperature is the temperature you're being exposed to.
|
||||
var/thermal_protection_flags = 0
|
||||
@@ -194,37 +194,6 @@
|
||||
|
||||
return thermal_protection_flags
|
||||
|
||||
/mob/living/carbon/human/proc/get_heat_protection(temperature) //Temperature is the temperature you're being exposed to.
|
||||
var/thermal_protection_flags = get_heat_protection_flags(temperature)
|
||||
|
||||
var/thermal_protection = 0
|
||||
if(thermal_protection_flags)
|
||||
if(thermal_protection_flags & HEAD)
|
||||
thermal_protection += THERMAL_PROTECTION_HEAD
|
||||
if(thermal_protection_flags & CHEST)
|
||||
thermal_protection += THERMAL_PROTECTION_CHEST
|
||||
if(thermal_protection_flags & GROIN)
|
||||
thermal_protection += THERMAL_PROTECTION_GROIN
|
||||
if(thermal_protection_flags & LEG_LEFT)
|
||||
thermal_protection += THERMAL_PROTECTION_LEG_LEFT
|
||||
if(thermal_protection_flags & LEG_RIGHT)
|
||||
thermal_protection += THERMAL_PROTECTION_LEG_RIGHT
|
||||
if(thermal_protection_flags & FOOT_LEFT)
|
||||
thermal_protection += THERMAL_PROTECTION_FOOT_LEFT
|
||||
if(thermal_protection_flags & FOOT_RIGHT)
|
||||
thermal_protection += THERMAL_PROTECTION_FOOT_RIGHT
|
||||
if(thermal_protection_flags & ARM_LEFT)
|
||||
thermal_protection += THERMAL_PROTECTION_ARM_LEFT
|
||||
if(thermal_protection_flags & ARM_RIGHT)
|
||||
thermal_protection += THERMAL_PROTECTION_ARM_RIGHT
|
||||
if(thermal_protection_flags & HAND_LEFT)
|
||||
thermal_protection += THERMAL_PROTECTION_HAND_LEFT
|
||||
if(thermal_protection_flags & HAND_RIGHT)
|
||||
thermal_protection += THERMAL_PROTECTION_HAND_RIGHT
|
||||
|
||||
|
||||
return min(1,thermal_protection)
|
||||
|
||||
//See proc/get_heat_protection_flags(temperature) for the description of this proc.
|
||||
/mob/living/carbon/human/proc/get_cold_protection_flags(temperature)
|
||||
var/thermal_protection_flags = 0
|
||||
@@ -251,17 +220,42 @@
|
||||
|
||||
return thermal_protection_flags
|
||||
|
||||
/mob/living/carbon/human/proc/get_cold_protection(temperature)
|
||||
//CITADEL EDIT Mandatory for vore code.
|
||||
if(istype(loc, /obj/item/dogborg/sleeper))
|
||||
return TRUE //freezing to death in sleepers ruins fun.
|
||||
if(isbelly(loc))
|
||||
return TRUE
|
||||
if(ismob(loc))
|
||||
return TRUE //because lazy and being inside somemone insulates you from space
|
||||
//END EDIT
|
||||
temperature = max(temperature, 2.7) //There is an occasional bug where the temperature is miscalculated in ares with a small amount of gas on them, so this is necessary to ensure that that bug does not affect this calculation. Space's temperature is 2.7K and most suits that are intended to protect against any cold, protect down to 2.0K.
|
||||
var/thermal_protection_flags = get_cold_protection_flags(temperature)
|
||||
/mob/living/carbon/human/proc/get_thermal_protection(temperature, cold = FALSE)
|
||||
if(cold)
|
||||
//CITADEL EDIT Mandatory for vore code.
|
||||
if(istype(loc, /obj/item/dogborg/sleeper) || isbelly(loc) || ismob(loc))
|
||||
return 1 //freezing to death in sleepers ruins fun.
|
||||
//END EDIT
|
||||
temperature = max(temperature, 2.7) //There is an occasional bug where the temperature is miscalculated in ares with a small amount of gas on them, so this is necessary to ensure that that bug does not affect this calculation. Space's temperature is 2.7K and most suits that are intended to protect against any cold, protect down to 2.0K.
|
||||
var/thermal_protection_flags = cold ? get_cold_protection_flags(temperature) : get_heat_protection_flags(temperature)
|
||||
var/missing_body_parts_flags = ~get_body_parts_flags()
|
||||
var/max_protection = 1
|
||||
if(missing_body_parts_flags) //I don't like copypasta as much as proc overhead. Do you want me to make these into a macro?
|
||||
DISABLE_BITFIELD(thermal_protection_flags, missing_body_parts_flags)
|
||||
if(missing_body_parts_flags & HEAD)
|
||||
max_protection -= THERMAL_PROTECTION_HEAD
|
||||
if(missing_body_parts_flags & CHEST)
|
||||
max_protection -= THERMAL_PROTECTION_CHEST
|
||||
if(missing_body_parts_flags & GROIN)
|
||||
max_protection -= THERMAL_PROTECTION_GROIN
|
||||
if(missing_body_parts_flags & LEG_LEFT)
|
||||
max_protection -= THERMAL_PROTECTION_LEG_LEFT
|
||||
if(missing_body_parts_flags & LEG_RIGHT)
|
||||
max_protection -= THERMAL_PROTECTION_LEG_RIGHT
|
||||
if(missing_body_parts_flags & FOOT_LEFT)
|
||||
max_protection -= THERMAL_PROTECTION_FOOT_LEFT
|
||||
if(missing_body_parts_flags & FOOT_RIGHT)
|
||||
max_protection -= THERMAL_PROTECTION_FOOT_RIGHT
|
||||
if(missing_body_parts_flags & ARM_LEFT)
|
||||
max_protection -= THERMAL_PROTECTION_ARM_LEFT
|
||||
if(missing_body_parts_flags & ARM_RIGHT)
|
||||
max_protection -= THERMAL_PROTECTION_ARM_RIGHT
|
||||
if(missing_body_parts_flags & HAND_LEFT)
|
||||
max_protection -= THERMAL_PROTECTION_HAND_LEFT
|
||||
if(missing_body_parts_flags & HAND_RIGHT)
|
||||
max_protection -= THERMAL_PROTECTION_HAND_RIGHT
|
||||
if(max_protection == 0) //Is it even a man if it doesn't have a body at all? Early return to avoid division by zero.
|
||||
return 1
|
||||
|
||||
var/thermal_protection = 0
|
||||
if(thermal_protection_flags)
|
||||
@@ -288,7 +282,7 @@
|
||||
if(thermal_protection_flags & HAND_RIGHT)
|
||||
thermal_protection += THERMAL_PROTECTION_HAND_RIGHT
|
||||
|
||||
return min(1,thermal_protection)
|
||||
return round(thermal_protection/max_protection, 0.001)
|
||||
|
||||
/mob/living/carbon/human/handle_random_events()
|
||||
//Puke if toxloss is too high
|
||||
|
||||
@@ -21,8 +21,6 @@
|
||||
var/bleed_mod = 1 // % bleeding modifier
|
||||
var/datum/armor/armor // internal armor datum
|
||||
|
||||
var/speed_mod = 0 //tick modifier for each step. Positive is slower, negative is faster.
|
||||
|
||||
var/hunger_mod = 1 //% of hunger rate taken per tick.
|
||||
|
||||
var/do_after_speed = 1 //Speed mod for do_after. Lower is better. If temporarily adjusting, please only modify using *= and /=, so you don't interrupt other calculations.
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
/mob/living/carbon/human/say_mod(input, message_mode)
|
||||
verb_say = dna.species.say_mod
|
||||
switch(slurring)
|
||||
if(10 to 25)
|
||||
return "jumbles"
|
||||
if(25 to 50)
|
||||
return "slurs"
|
||||
if(50 to INFINITY)
|
||||
return "garbles"
|
||||
else
|
||||
. = ..()
|
||||
. = ..()
|
||||
if(message_mode != MODE_CUSTOM_SAY && message_mode != MODE_WHISPER_CRIT)
|
||||
switch(slurring)
|
||||
if(10 to 25)
|
||||
return "jumbles"
|
||||
if(25 to 50)
|
||||
return "slurs"
|
||||
if(50 to INFINITY)
|
||||
return "garbles"
|
||||
|
||||
/mob/living/carbon/human/GetVoice()
|
||||
if(istype(wear_mask, /obj/item/clothing/mask/chameleon))
|
||||
|
||||
@@ -9,19 +9,41 @@ 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.
|
||||
|
||||
var/horn_color //specific horn colors, because why not?
|
||||
var/wing_color
|
||||
|
||||
var/use_skintones = 0 // does it use skintones or not? (spoiler alert this is only used by humans)
|
||||
var/exotic_blood = "" // If your race wants to bleed something other than bog standard blood, change this to reagent id.
|
||||
var/exotic_bloodtype = "" //If your race uses a non standard bloodtype (A+, O-, AB-, etc)
|
||||
var/meat = /obj/item/reagent_containers/food/snacks/meat/slab/human //What the species drops on gibbing
|
||||
var/list/gib_types = list(/obj/effect/gibspawner/human, /obj/effect/gibspawner/human/bodypartless)
|
||||
var/skinned_type
|
||||
var/liked_food = NONE
|
||||
var/disliked_food = GROSS
|
||||
@@ -60,7 +82,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
var/sound/attack_sound = 'sound/weapons/punch1.ogg'
|
||||
var/sound/miss_sound = 'sound/weapons/punchmiss.ogg'
|
||||
|
||||
var/mob/living/list/ignored_by = list() // list of mobs that will ignore this species
|
||||
var/list/mob/living/ignored_by = list() // list of mobs that will ignore this species
|
||||
//Breathing!
|
||||
var/obj/item/organ/lungs/mutantlungs = null
|
||||
var/breathid = "o2"
|
||||
@@ -96,11 +118,14 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
..()
|
||||
|
||||
|
||||
/proc/generate_selectable_species()
|
||||
/proc/generate_selectable_species(clear = FALSE)
|
||||
if(clear)
|
||||
GLOB.roundstart_races = list()
|
||||
GLOB.roundstart_race_names = list()
|
||||
for(var/I in subtypesof(/datum/species))
|
||||
var/datum/species/S = new I
|
||||
if(S.check_roundstart_eligible())
|
||||
GLOB.roundstart_races += S.id
|
||||
GLOB.roundstart_races |= S.id
|
||||
GLOB.roundstart_race_names["[S.name]"] = S.id
|
||||
qdel(S)
|
||||
if(!GLOB.roundstart_races.len)
|
||||
@@ -311,6 +336,8 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
if("meat_type" in default_features) //I can't believe it's come to the meat
|
||||
H.type_of_meat = GLOB.meat_types[H.dna.features["meat_type"]]
|
||||
|
||||
C.add_movespeed_modifier(MOVESPEED_ID_SPECIES, TRUE, 100, override=TRUE, multiplicative_slowdown=speedmod, movetypes=(~FLYING))
|
||||
|
||||
SEND_SIGNAL(C, COMSIG_SPECIES_GAIN, src, old_species)
|
||||
|
||||
|
||||
@@ -318,12 +345,17 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
|
||||
/datum/species/proc/on_species_loss(mob/living/carbon/human/C, datum/species/new_species, pref_load)
|
||||
if(C.dna.species.exotic_bloodtype)
|
||||
C.dna.blood_type = random_blood_type()
|
||||
if(!new_species.exotic_bloodtype)
|
||||
C.dna.blood_type = random_blood_type()
|
||||
else
|
||||
C.dna.blood_type = new_species.exotic_bloodtype
|
||||
if(DIGITIGRADE in species_traits)
|
||||
C.Digitigrade_Leg_Swap(TRUE)
|
||||
for(var/X in inherent_traits)
|
||||
REMOVE_TRAIT(C, X, SPECIES_TRAIT)
|
||||
|
||||
C.remove_movespeed_modifier(MOVESPEED_ID_SPECIES)
|
||||
|
||||
if("meat_type" in default_features)
|
||||
C.type_of_meat = GLOB.meat_types[C.dna.features["meat_type"]]
|
||||
else
|
||||
@@ -401,6 +433,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 +494,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 +519,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 +536,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
|
||||
@@ -507,7 +549,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
if(H.hidden_underwear)
|
||||
H.underwear = "Nude"
|
||||
else
|
||||
H.saved_underwear = H.underwear
|
||||
H.underwear = H.saved_underwear
|
||||
var/datum/sprite_accessory/underwear/bottom/B = GLOB.underwear_list[H.underwear]
|
||||
if(B)
|
||||
var/mutable_appearance/MA = mutable_appearance(B.icon, B.icon_state, -BODY_LAYER)
|
||||
@@ -519,7 +561,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
if(H.hidden_undershirt)
|
||||
H.undershirt = "Nude"
|
||||
else
|
||||
H.saved_undershirt = H.undershirt
|
||||
H.undershirt = H.saved_undershirt
|
||||
var/datum/sprite_accessory/underwear/top/T = GLOB.undershirt_list[H.undershirt]
|
||||
if(T)
|
||||
var/mutable_appearance/MA
|
||||
@@ -535,7 +577,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
if(H.hidden_socks)
|
||||
H.socks = "Nude"
|
||||
else
|
||||
H.saved_socks = H.socks
|
||||
H.socks = H.saved_socks
|
||||
var/datum/sprite_accessory/underwear/socks/S = GLOB.socks_list[H.socks]
|
||||
if(S)
|
||||
var/digilegs = (DIGITIGRADE in species_traits) ? "_d" : ""
|
||||
@@ -731,6 +773,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 +826,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]"
|
||||
@@ -835,6 +881,8 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
accessory_overlay.color = "#[H.eye_color]"
|
||||
if(HORNCOLOR)
|
||||
accessory_overlay.color = "#[H.horn_color]"
|
||||
if(WINGCOLOR)
|
||||
accessory_overlay.color = "#[H.wing_color]"
|
||||
else
|
||||
accessory_overlay.color = forced_colour
|
||||
else
|
||||
@@ -851,6 +899,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 +916,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 +960,13 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
|
||||
if(HORNCOLOR)
|
||||
extra_accessory_overlay.color = "#[H.horn_color]"
|
||||
if(WINGCOLOR)
|
||||
extra_accessory_overlay.color = "#[H.wing_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 +1001,13 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
extra2_accessory_overlay.color = "#[H.hair_color]"
|
||||
if(HORNCOLOR)
|
||||
extra2_accessory_overlay.color = "#[H.horn_color]"
|
||||
if(WINGCOLOR)
|
||||
extra2_accessory_overlay.color = "#[H.wing_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
|
||||
|
||||
|
||||
@@ -964,6 +1035,16 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
return "TAUR"
|
||||
//END EDIT
|
||||
|
||||
/* TODO: Snowflake trail marks
|
||||
// Impliments different trails for species depending on if they're wearing shoes.
|
||||
/datum/species/proc/get_move_trail(var/mob/living/carbon/human/H)
|
||||
if(H.lying)
|
||||
return /obj/effect/decal/cleanable/blood/footprints/tracks/body
|
||||
if(H.shoes || (H.wear_suit && (H.wear_suit.body_parts_covered & FEET)))
|
||||
var/obj/item/clothing/shoes/shoes = (H.wear_suit && (H.wear_suit.body_parts_covered & FEET)) ? H.wear_suit : H.shoes // suits take priority over shoes
|
||||
return shoes.move_trail
|
||||
else
|
||||
return move_trail */
|
||||
|
||||
/datum/species/proc/spec_life(mob/living/carbon/human/H)
|
||||
if(HAS_TRAIT(H, TRAIT_NOBREATH))
|
||||
@@ -1217,13 +1298,18 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
if (H.nutrition > 0 && H.stat != DEAD && !HAS_TRAIT(H, TRAIT_NOHUNGER))
|
||||
// THEY HUNGER
|
||||
var/hunger_rate = HUNGER_FACTOR
|
||||
GET_COMPONENT_FROM(mood, /datum/component/mood, H)
|
||||
var/datum/component/mood/mood = H.GetComponent(/datum/component/mood)
|
||||
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)
|
||||
@@ -1311,39 +1397,16 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
/datum/species/proc/movement_delay(mob/living/carbon/human/H)
|
||||
. = 0 //We start at 0.
|
||||
var/flight = 0 //Check for flight and flying items
|
||||
var/ignoreslow = 0
|
||||
var/gravity = 0
|
||||
if(H.movement_type & FLYING)
|
||||
flight = 1
|
||||
|
||||
gravity = H.has_gravity()
|
||||
|
||||
if(gravity && !flight) //Check for chemicals and innate speedups and slowdowns if we're on the ground
|
||||
if(HAS_TRAIT(H, TRAIT_GOTTAGOFAST))
|
||||
. -= 1
|
||||
if(HAS_TRAIT(H, TRAIT_GOTTAGOREALLYFAST))
|
||||
. -= 2
|
||||
. += speedmod
|
||||
. += H.physiology.speed_mod
|
||||
|
||||
if (H.m_intent == MOVE_INTENT_WALK && HAS_TRAIT(H, TRAIT_SPEEDY_STEP))
|
||||
. -= 1.5
|
||||
|
||||
if(HAS_TRAIT(H, TRAIT_IGNORESLOWDOWN))
|
||||
ignoreslow = 1
|
||||
|
||||
if(!gravity)
|
||||
var/obj/item/tank/jetpack/J = H.back
|
||||
var/obj/item/clothing/suit/space/hardsuit/C = H.wear_suit
|
||||
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
|
||||
. -= 0.4
|
||||
else if(istype(T) && T.allow_thrust(0.005, H))
|
||||
. -= 0.4
|
||||
|
||||
if(!ignoreslow && gravity)
|
||||
if(!HAS_TRAIT(H, TRAIT_IGNORESLOWDOWN) && gravity)
|
||||
if(H.wear_suit)
|
||||
. += H.wear_suit.slowdown
|
||||
if(H.shoes)
|
||||
@@ -1370,16 +1433,6 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
var/grav_force = min(gravity - STANDARD_GRAVITY,3)
|
||||
. += 1 + grav_force
|
||||
|
||||
GET_COMPONENT_FROM(mood, /datum/component/mood, H)
|
||||
if(mood && !flight) //How can depression slow you down if you can just fly away from your problems?
|
||||
switch(mood.sanity)
|
||||
if(SANITY_INSANE to SANITY_CRAZY)
|
||||
. += 1.5
|
||||
if(SANITY_CRAZY to SANITY_UNSTABLE)
|
||||
. += 1
|
||||
if(SANITY_UNSTABLE to SANITY_DISTURBED)
|
||||
. += 0.5
|
||||
|
||||
if(HAS_TRAIT(H, TRAIT_FAT))
|
||||
. += (1.5 - flight)
|
||||
if(H.bodytemperature < BODYTEMP_COLD_DAMAGE_LIMIT && !HAS_TRAIT(H, TRAIT_RESISTCOLD))
|
||||
@@ -1426,7 +1479,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
|
||||
|
||||
/datum/species/proc/harm(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style)
|
||||
if(HAS_TRAIT(user, TRAIT_PACIFISM))
|
||||
if(!attacker_style && HAS_TRAIT(user, TRAIT_PACIFISM))
|
||||
to_chat(user, "<span class='warning'>You don't want to harm [target]!</span>")
|
||||
return FALSE
|
||||
if(user.getStaminaLoss() >= STAMINA_SOFTCRIT) //CITADEL CHANGE - makes it impossible to punch while in stamina softcrit
|
||||
@@ -1628,6 +1681,8 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
return
|
||||
if(M.mind)
|
||||
attacker_style = M.mind.martial_art
|
||||
if(attacker_style?.pacifism_check && HAS_TRAIT(M, TRAIT_PACIFISM)) // most martial arts are quite harmful, alas.
|
||||
attacker_style = null
|
||||
if((M != H) && M.a_intent != INTENT_HELP && H.check_shields(M, 0, M.name, attack_type = UNARMED_ATTACK))
|
||||
log_combat(M, H, "attempted to touch")
|
||||
H.visible_message("<span class='warning'>[M] attempted to touch [H]!</span>")
|
||||
@@ -1706,9 +1761,9 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
|
||||
switch(hit_area)
|
||||
if(BODY_ZONE_HEAD)
|
||||
if(!I.is_sharp() && armor_block < 50)
|
||||
if(!I.get_sharpness() && 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 +1772,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)
|
||||
@@ -1739,7 +1794,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
H.update_inv_glasses()
|
||||
|
||||
if(BODY_ZONE_CHEST)
|
||||
if(H.stat == CONSCIOUS && !I.is_sharp() && armor_block < 50)
|
||||
if(H.stat == CONSCIOUS && !I.get_sharpness() && armor_block < 50)
|
||||
if(prob(I.force))
|
||||
H.visible_message("<span class='danger'>[H] has been knocked down!</span>", \
|
||||
"<span class='userdanger'>[H] has been knocked down!</span>")
|
||||
@@ -1862,8 +1917,8 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
var/knocked_item = FALSE
|
||||
if(!is_type_in_typecache(target_held_item, GLOB.shove_disarming_types))
|
||||
target_held_item = null
|
||||
if(!target.has_movespeed_modifier(SHOVE_SLOWDOWN_ID))
|
||||
target.add_movespeed_modifier(SHOVE_SLOWDOWN_ID, multiplicative_slowdown = SHOVE_SLOWDOWN_STRENGTH)
|
||||
if(!target.has_movespeed_modifier(MOVESPEED_ID_SHOVE))
|
||||
target.add_movespeed_modifier(MOVESPEED_ID_SHOVE, multiplicative_slowdown = SHOVE_SLOWDOWN_STRENGTH)
|
||||
if(target_held_item)
|
||||
target.visible_message("<span class='danger'>[target.name]'s grip on \the [target_held_item] loosens!</span>",
|
||||
"<span class='danger'>Your grip on \the [target_held_item] loosens!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
@@ -1881,10 +1936,10 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
append_message = "loosening their grip on [target_held_item]"
|
||||
log_combat(user, target, "shoved", append_message)
|
||||
|
||||
/datum/species/proc/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked, mob/living/carbon/human/H)
|
||||
/datum/species/proc/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked, mob/living/carbon/human/H, forced = FALSE)
|
||||
var/hit_percent = (100-(blocked+armor))/100
|
||||
hit_percent = (hit_percent * (100-H.physiology.damage_resistance))/100
|
||||
if(hit_percent <= 0)
|
||||
if(!forced && hit_percent <= 0)
|
||||
return 0
|
||||
|
||||
var/obj/item/bodypart/BP = null
|
||||
@@ -1906,37 +1961,44 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
switch(damagetype)
|
||||
if(BRUTE)
|
||||
H.damageoverlaytemp = 20
|
||||
var/damage_amount = forced ? damage : damage * hit_percent * brutemod * H.physiology.brute_mod
|
||||
if(BP)
|
||||
if(damage > 0 ? BP.receive_damage(damage * hit_percent * brutemod * H.physiology.brute_mod, 0) : BP.heal_damage(abs(damage * hit_percent * brutemod * H.physiology.brute_mod), 0))
|
||||
if(damage > 0 ? BP.receive_damage(damage_amount, 0) : BP.heal_damage(abs(damage_amount), 0))
|
||||
H.update_damage_overlays()
|
||||
if(HAS_TRAIT(H, TRAIT_MASO))
|
||||
H.adjustArousalLoss(damage * brutemod * H.physiology.brute_mod)
|
||||
H.adjustArousalLoss(damage_amount, 0)
|
||||
if (H.getArousalLoss() >= 100 && ishuman(H) && H.has_dna())
|
||||
H.mob_climax(forced_climax=TRUE)
|
||||
|
||||
else//no bodypart, we deal damage with a more general method.
|
||||
H.adjustBruteLoss(damage * hit_percent * brutemod * H.physiology.brute_mod)
|
||||
H.adjustBruteLoss(damage_amount)
|
||||
if(BURN)
|
||||
H.damageoverlaytemp = 20
|
||||
var/damage_amount = forced ? damage : damage * hit_percent * burnmod * H.physiology.burn_mod
|
||||
if(BP)
|
||||
if(damage > 0 ? BP.receive_damage(0, damage * hit_percent * burnmod * H.physiology.burn_mod) : BP.heal_damage(0, abs(damage * hit_percent * burnmod * H.physiology.burn_mod)))
|
||||
if(damage > 0 ? BP.receive_damage(0, damage_amount) : BP.heal_damage(0, abs(damage_amount)))
|
||||
H.update_damage_overlays()
|
||||
else
|
||||
H.adjustFireLoss(damage * hit_percent * burnmod * H.physiology.burn_mod)
|
||||
H.adjustFireLoss(damage_amount)
|
||||
if(TOX)
|
||||
H.adjustToxLoss(damage * hit_percent * H.physiology.tox_mod)
|
||||
var/damage_amount = forced ? damage : damage * hit_percent * H.physiology.tox_mod
|
||||
H.adjustToxLoss(damage_amount)
|
||||
if(OXY)
|
||||
H.adjustOxyLoss(damage * hit_percent * H.physiology.oxy_mod)
|
||||
var/damage_amount = forced ? damage : damage * hit_percent * H.physiology.oxy_mod
|
||||
H.adjustOxyLoss(damage_amount)
|
||||
if(CLONE)
|
||||
H.adjustCloneLoss(damage * hit_percent * H.physiology.clone_mod)
|
||||
var/damage_amount = forced ? damage : damage * hit_percent * H.physiology.clone_mod
|
||||
H.adjustCloneLoss(damage_amount)
|
||||
if(STAMINA)
|
||||
var/damage_amount = forced ? damage : damage * hit_percent * H.physiology.stamina_mod
|
||||
if(BP)
|
||||
if(damage > 0 ? BP.receive_damage(0, 0, damage * hit_percent * H.physiology.stamina_mod) : BP.heal_damage(0, 0, abs(damage * hit_percent * H.physiology.stamina_mod), only_robotic = FALSE, only_organic = FALSE))
|
||||
if(damage > 0 ? BP.receive_damage(0, 0, damage_amount) : BP.heal_damage(0, 0, abs(damage * hit_percent * H.physiology.stamina_mod), only_robotic = FALSE, only_organic = FALSE))
|
||||
H.update_stamina()
|
||||
else
|
||||
H.adjustStaminaLoss(damage * hit_percent * H.physiology.stamina_mod)
|
||||
H.adjustStaminaLoss(damage_amount)
|
||||
if(BRAIN)
|
||||
H.adjustBrainLoss(damage * hit_percent * H.physiology.brain_mod)
|
||||
var/damage_amount = forced ? damage : damage * hit_percent * H.physiology.brain_mod
|
||||
H.adjustOrganLoss(ORGAN_SLOT_BRAIN, damage_amount)
|
||||
if(AROUSAL) //Citadel edit - arousal
|
||||
H.adjustArousalLoss(damage * hit_percent)
|
||||
return 1
|
||||
@@ -1978,13 +2040,13 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
natural = H.natural_bodytemperature_stabilization()
|
||||
var/thermal_protection = 1
|
||||
if(loc_temp < H.bodytemperature) //Place is colder than we are
|
||||
thermal_protection -= H.get_cold_protection(loc_temp) //This returns a 0 - 1 value, which corresponds to the percentage of protection based on what you're wearing and what you're exposed to.
|
||||
thermal_protection -= H.get_thermal_protection(loc_temp, TRUE) //This returns a 0 - 1 value, which corresponds to the percentage of protection based on what you're wearing and what you're exposed to.
|
||||
if(H.bodytemperature < BODYTEMP_NORMAL) //we're cold, insulation helps us retain body heat and will reduce the heat we lose to the environment
|
||||
H.adjust_bodytemperature((thermal_protection+1)*natural + max(thermal_protection * (loc_temp - H.bodytemperature) / BODYTEMP_COLD_DIVISOR, BODYTEMP_COOLING_MAX))
|
||||
else //we're sweating, insulation hinders our ability to reduce heat - and it will reduce the amount of cooling you get from the environment
|
||||
H.adjust_bodytemperature(natural*(1/(thermal_protection+1)) + max((thermal_protection * (loc_temp - H.bodytemperature) + BODYTEMP_NORMAL - H.bodytemperature) / BODYTEMP_COLD_DIVISOR , BODYTEMP_COOLING_MAX)) //Extra calculation for hardsuits to bleed off heat
|
||||
else //Place is hotter than we are
|
||||
thermal_protection -= H.get_heat_protection(loc_temp) //This returns a 0 - 1 value, which corresponds to the percentage of protection based on what you're wearing and what you're exposed to.
|
||||
thermal_protection -= H.get_thermal_protection(loc_temp) //This returns a 0 - 1 value, which corresponds to the percentage of protection based on what you're wearing and what you're exposed to.
|
||||
if(H.bodytemperature < BODYTEMP_NORMAL) //and we're cold, insulation enhances our ability to retain body heat but reduces the heat we get from the environment
|
||||
H.adjust_bodytemperature((thermal_protection+1)*natural + min(thermal_protection * (loc_temp - H.bodytemperature) / BODYTEMP_HEAT_DIVISOR, BODYTEMP_HEATING_MAX))
|
||||
else //we're sweating, insulation hinders out ability to reduce heat - but will reduce the amount of heat we get from the environment
|
||||
@@ -2123,7 +2185,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
if(!(I.resistance_flags & FIRE_PROOF))
|
||||
I.take_damage(H.fire_stacks, BURN, "fire", 0)
|
||||
|
||||
var/thermal_protection = H.get_thermal_protection()
|
||||
var/thermal_protection = H.easy_thermal_protection()
|
||||
|
||||
if(thermal_protection >= FIRE_IMMUNITY_MAX_TEMP_PROTECT && !no_protection)
|
||||
return
|
||||
|
||||
@@ -6,10 +6,6 @@
|
||||
species_traits = list(NOBLOOD,NOEYES,NOGENITALS,NOAROUSAL)
|
||||
inherent_traits = list(TRAIT_VIRUSIMMUNE,TRAIT_NOGUNS,TRAIT_NOHUNGER,TRAIT_NOBREATH)
|
||||
mutanttongue = /obj/item/organ/tongue/abductor
|
||||
var/scientist = FALSE // vars to not pollute spieces list with castes
|
||||
|
||||
/datum/species/abductor/copy_properties_from(datum/species/abductor/old_species)
|
||||
scientist = old_species.scientist
|
||||
|
||||
/datum/species/abductor/on_species_gain(mob/living/carbon/C, datum/species/old_species)
|
||||
. = ..()
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_RADIMMUNE,TRAIT_NOFIRE,TRAIT_PIERCEIMMUNE,TRAIT_NOHUNGER,TRAIT_LIMBATTACHMENT)
|
||||
inherent_biotypes = list(MOB_ROBOTIC, MOB_HUMANOID)
|
||||
meat = null
|
||||
gib_types = /obj/effect/gibspawner/robot
|
||||
damage_overlay_type = "synth"
|
||||
mutanttongue = /obj/item/organ/tongue/robot
|
||||
limbs_id = "synth"
|
||||
|
||||
@@ -29,7 +29,7 @@
|
||||
if(fly)
|
||||
fly.Remove(H)
|
||||
if(H.movement_type & FLYING)
|
||||
H.movement_type &= ~FLYING
|
||||
H.setMovetype(H.movement_type & ~FLYING)
|
||||
ToggleFlight(H,0)
|
||||
if(H.dna && H.dna.species && (H.dna.features["wings"] == "Angel"))
|
||||
if("wings" in H.dna.species.mutant_bodyparts)
|
||||
@@ -132,14 +132,14 @@
|
||||
if(flight && CanFly(H))
|
||||
stunmod = 2
|
||||
speedmod = -0.35
|
||||
H.movement_type |= FLYING
|
||||
H.setMovetype(H.movement_type | FLYING)
|
||||
override_float = TRUE
|
||||
H.pass_flags |= PASSTABLE
|
||||
H.OpenWings()
|
||||
else
|
||||
stunmod = 1
|
||||
speedmod = 0
|
||||
H.movement_type &= ~FLYING
|
||||
H.setMovetype(H.movement_type & ~FLYING)
|
||||
override_float = FALSE
|
||||
H.pass_flags &= ~PASSTABLE
|
||||
H.CloseWings()
|
||||
@@ -3,7 +3,7 @@
|
||||
id = "insect"
|
||||
say_mod = "flutters"
|
||||
default_color = "00FF00"
|
||||
species_traits = list(LIPS,NOEYES,HAIR,FACEHAIR,MUTCOLORS,HORNCOLOR)
|
||||
species_traits = list(LIPS,NOEYES,HAIR,FACEHAIR,MUTCOLORS,HORNCOLOR,WINGCOLOR)
|
||||
inherent_biotypes = list(MOB_ORGANIC, MOB_HUMANOID, MOB_BUG)
|
||||
mutant_bodyparts = list("mam_ears", "mam_snout", "mam_tail", "taur", "insect_wings", "mam_snouts", "insect_fluff","horns")
|
||||
default_features = list("mcolor" = "FFF","mcolor2" = "FFF","mcolor3" = "FFF", "mam_tail" = "None", "mam_ears" = "None",
|
||||
@@ -17,6 +17,7 @@
|
||||
toxic_food = MEAT | RAW
|
||||
mutanteyes = /obj/item/organ/eyes/insect
|
||||
should_draw_citadel = TRUE
|
||||
exotic_bloodtype = "BUG"
|
||||
|
||||
/datum/species/insect/on_species_gain(mob/living/carbon/C)
|
||||
. = ..()
|
||||
|
||||
@@ -17,4 +17,5 @@
|
||||
use_skintones = 0
|
||||
species_traits = list(NOBLOOD,EYECOLOR,NOGENITALS)
|
||||
inherent_traits = list(TRAIT_RADIMMUNE,TRAIT_VIRUSIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER,TRAIT_NOLIMBDISABLE,TRAIT_NOHUNGER)
|
||||
sexes = 0
|
||||
sexes = 0
|
||||
gib_types = /obj/effect/gibspawner/robot
|
||||
@@ -13,9 +13,14 @@
|
||||
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
|
||||
name = "Pumpkin Head Dullahan"
|
||||
id = "pumpkindullahan"
|
||||
pumpkin = TRUE
|
||||
|
||||
/datum/species/dullahan/check_roundstart_eligible()
|
||||
if(SSevents.holidays && SSevents.holidays[HALLOWEEN])
|
||||
@@ -24,17 +29,25 @@
|
||||
|
||||
/datum/species/dullahan/on_species_gain(mob/living/carbon/human/H, datum/species/old_species)
|
||||
. = ..()
|
||||
H.flags_1 &= ~HEAR_1
|
||||
DISABLE_BITFIELD(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)
|
||||
if(!QDELETED(head)) //drop_limb() deletes the limb if it's no drop location and dummy humans used for rendering icons are located in nullspace. Do the math.
|
||||
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
|
||||
ENABLE_BITFIELD(H.flags_1, HEAR_1)
|
||||
H.reset_perspective(H)
|
||||
if(myhead)
|
||||
var/obj/item/dullahan_relay/DR = myhead
|
||||
@@ -64,7 +77,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"
|
||||
@@ -73,7 +86,7 @@
|
||||
/obj/item/organ/tongue/dullahan/handle_speech(datum/source, list/speech_args)
|
||||
if(ishuman(owner))
|
||||
var/mob/living/carbon/human/H = owner
|
||||
if(H.dna.species.id == "dullahan")
|
||||
if(isdullahan(H))
|
||||
var/datum/species/dullahan/D = H.dna.species
|
||||
if(isobj(D.myhead.loc))
|
||||
var/obj/O = D.myhead.loc
|
||||
@@ -88,6 +101,7 @@
|
||||
desc = "An abstraction."
|
||||
actions_types = list(/datum/action/item_action/organ_action/dullahan)
|
||||
zone = "abstract"
|
||||
tint = INFINITY // used to switch the vision perspective to the head on species_gain().
|
||||
|
||||
/datum/action/item_action/organ_action/dullahan
|
||||
name = "Toggle Perspective"
|
||||
@@ -103,39 +117,55 @@
|
||||
|
||||
if(ishuman(owner))
|
||||
var/mob/living/carbon/human/H = owner
|
||||
if(H.dna.species.id == "dullahan")
|
||||
if(isdullahan(H))
|
||||
var/datum/species/dullahan/D = H.dna.species
|
||||
D.update_vision_perspective(H)
|
||||
|
||||
/obj/item/dullahan_relay
|
||||
name = "dullahan relay"
|
||||
var/mob/living/owner
|
||||
flags_1 = HEAR_1
|
||||
|
||||
/obj/item/dullahan_relay/Initialize(mapload,new_owner)
|
||||
/obj/item/dullahan_relay/Initialize(mapload, mob/living/carbon/human/new_owner)
|
||||
. = ..()
|
||||
if(!new_owner)
|
||||
return INITIALIZE_HINT_QDEL
|
||||
owner = new_owner
|
||||
START_PROCESSING(SSobj, src)
|
||||
RegisterSignal(owner, COMSIG_MOB_EXAMINATE, .proc/examinate_check)
|
||||
RegisterSignal(src, COMSIG_ATOM_HEARER_IN_VIEW, .proc/include_owner)
|
||||
RegisterSignal(owner, COMSIG_LIVING_REGENERATE_LIMBS, .proc/unlist_head)
|
||||
RegisterSignal(owner, COMSIG_LIVING_FULLY_HEAL, .proc/retrieve_head)
|
||||
|
||||
/obj/item/dullahan_relay/proc/examinate_check(mob/source, atom/A)
|
||||
if(source.client.eye == src && ((A in view(source.client.view, src)) || (isturf(A) && source.sight & SEE_TURFS) || (ismob(A) && source.sight & SEE_MOBS) || (isobj(A) && source.sight & SEE_OBJS)))
|
||||
return COMPONENT_ALLOW_EXAMINE
|
||||
|
||||
/obj/item/dullahan_relay/proc/include_owner(datum/source, list/processing_list, list/hearers)
|
||||
if(!QDELETED(owner))
|
||||
hearers += owner
|
||||
|
||||
/obj/item/dullahan_relay/proc/unlist_head(datum/source, noheal = FALSE, list/excluded_limbs)
|
||||
excluded_limbs |= BODY_ZONE_HEAD // So we don't gib when regenerating limbs.
|
||||
|
||||
/obj/item/dullahan_relay/proc/retrieve_head(datum/source, admin_revive = FALSE)
|
||||
if(admin_revive) //retrieving the owner's head for ahealing purposes.
|
||||
var/obj/item/bodypart/head/H = loc
|
||||
var/turf/T = get_turf(owner)
|
||||
if(H && istype(H) && T && !(H in owner.GetAllContents()))
|
||||
H.forceMove(T)
|
||||
|
||||
/obj/item/dullahan_relay/process()
|
||||
if(!istype(loc, /obj/item/bodypart/head) || QDELETED(owner))
|
||||
. = PROCESS_KILL
|
||||
qdel(src)
|
||||
|
||||
/obj/item/dullahan_relay/Hear(message, atom/movable/speaker, message_language, raw_message, radio_freq, list/spans, message_mode)
|
||||
. = ..()
|
||||
if(!QDELETED(owner))
|
||||
message = compose_message(speaker, message_language, raw_message, radio_freq, spans, message_mode)
|
||||
to_chat(owner,message)
|
||||
else
|
||||
qdel(src)
|
||||
|
||||
|
||||
/obj/item/dullahan_relay/Destroy()
|
||||
if(!QDELETED(owner))
|
||||
var/mob/living/carbon/human/H = owner
|
||||
if(H.dna.species.id == "dullahan")
|
||||
if(isdullahan(H))
|
||||
var/datum/species/dullahan/D = H.dna.species
|
||||
D.myhead = null
|
||||
owner.gib()
|
||||
owner = null
|
||||
..()
|
||||
..()
|
||||
|
||||
@@ -0,0 +1,192 @@
|
||||
|
||||
GLOBAL_LIST_INIT(dwarf_first, world.file2list("strings/names/dwarf_first.txt")) //Textfiles with first
|
||||
GLOBAL_LIST_INIT(dwarf_last, world.file2list("strings/names/dwarf_last.txt")) //textfiles with last
|
||||
|
||||
/datum/species/dwarf //not to be confused with the genetic manlets
|
||||
name = "Dwarf"
|
||||
id = "dwarf" //Also called Homo sapiens pumilionis
|
||||
default_color = "FFFFFF"
|
||||
species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS,NO_UNDERWEAR)
|
||||
inherent_traits = list()
|
||||
default_features = list("mcolor" = "FFF", "wings" = "None")
|
||||
limbs_id = "human"
|
||||
use_skintones = 1
|
||||
say_mod = "bellows" //high energy, EXTRA BIOLOGICAL FUEL
|
||||
damage_overlay_type = "human"
|
||||
skinned_type = /obj/item/stack/sheet/animalhide/human
|
||||
liked_food = ALCOHOL | MEAT | DAIRY //Dwarves like alcohol, meat, and dairy products.
|
||||
disliked_food = JUNKFOOD | FRIED //Dwarves hate foods that have no nutrition other than alcohol.
|
||||
mutant_organs = list(/obj/item/organ/dwarfgland) //Dwarven alcohol gland, literal gland warrior
|
||||
mutantliver = /obj/item/organ/liver/dwarf //Dwarven super liver (Otherwise they r doomed)
|
||||
|
||||
/mob/living/carbon/human/species/dwarf //species admin spawn path
|
||||
race = /datum/species/dwarf //and the race the path is set to.
|
||||
|
||||
/datum/species/dwarf/check_roundstart_eligible()
|
||||
if(SSevents.holidays && SSevents.holidays[HALLOWEEN])
|
||||
return TRUE
|
||||
return ..()
|
||||
|
||||
/datum/species/dwarf/on_species_gain(mob/living/carbon/C, datum/species/old_species)
|
||||
. = ..()
|
||||
var/dwarf_hair = pick("Beard (Dwarf)", "Beard (Very Long)", "Beard (Long)") //beard roullette
|
||||
var/mob/living/carbon/human/H = C
|
||||
H.facial_hair_style = dwarf_hair
|
||||
H.update_hair()
|
||||
H.transform = H.transform.Scale(1, 0.8) //We use scale, and yeah. Dwarves can become gnomes with DWARFISM.
|
||||
RegisterSignal(C, COMSIG_MOB_SAY, .proc/handle_speech) //We register handle_speech is being used.
|
||||
|
||||
|
||||
/datum/species/dwarf/on_species_loss(mob/living/carbon/H, datum/species/new_species)
|
||||
. = ..()
|
||||
H.transform = H.transform.Scale(1, 1.25) //And we undo it.
|
||||
UnregisterSignal(H, COMSIG_MOB_SAY) //We register handle_speech is not being used.
|
||||
|
||||
//Dwarf Name stuff
|
||||
/proc/dwarf_name() //hello caller: my name is urist mcuristurister
|
||||
return "[pick(GLOB.dwarf_first)] [pick(GLOB.dwarf_last)]"
|
||||
|
||||
/datum/species/dwarf/random_name(gender,unique,lastname)
|
||||
return dwarf_name() //hello, ill return the value from dwarf_name proc to you when called.
|
||||
|
||||
//Dwarf Speech handling - Basically a filter/forces them to say things. The IC helper
|
||||
/datum/species/dwarf/proc/handle_speech(datum/source, list/speech_args)
|
||||
var/message = speech_args[SPEECH_MESSAGE]
|
||||
if(message[1] != "*")
|
||||
message = " [message]" //Credits to goonstation for the strings list.
|
||||
var/list/dwarf_words = strings("dwarf_replacement.json", "dwarf") //thanks to regex too.
|
||||
|
||||
for(var/key in dwarf_words) //Theres like 1459 words or something man.
|
||||
var/value = dwarf_words[key] //Thus they will always be in character.
|
||||
if(islist(value)) //Whether they like it or not.
|
||||
value = pick(value) //This could be drastically reduced if needed though.
|
||||
|
||||
message = replacetextEx(message, " [uppertext(key)]", " [uppertext(value)]")
|
||||
message = replacetextEx(message, " [capitalize(key)]", " [capitalize(value)]")
|
||||
message = replacetextEx(message, " [key]", " [value]") //Also its scottish.
|
||||
|
||||
if(prob(3))
|
||||
message += pick(" By Armok!")
|
||||
speech_args[SPEECH_MESSAGE] = trim(message)
|
||||
|
||||
//This mostly exists because my testdwarf's liver died while trying to also not die due to no alcohol.
|
||||
/obj/item/organ/liver/dwarf
|
||||
name = "dwarf liver"
|
||||
icon_state = "liver"
|
||||
desc = "A dwarven liver, theres something magical about seeing one of these up close."
|
||||
alcohol_tolerance = 0 //dwarves really shouldn't be dying to alcohol.
|
||||
toxTolerance = 5 //Shrugs off 5 units of toxins damage.
|
||||
maxHealth = 150 //More health than the average liver, as you aren't going to be replacing this.
|
||||
//If it does need replaced with a standard human liver, prepare for hell.
|
||||
|
||||
//alcohol gland
|
||||
/obj/item/organ/dwarfgland
|
||||
name = "dwarf alcohol gland"
|
||||
icon_state = "plasma" //Yes this is a actual icon in icons/obj/surgery.dmi
|
||||
desc = "A genetically engineered gland which is hopefully a step forward for humanity."
|
||||
w_class = WEIGHT_CLASS_NORMAL
|
||||
var/stored_alcohol = 250 //They start with 250 units, that ticks down and eventaully bad effects occur
|
||||
var/max_alcohol = 500 //Max they can attain, easier than you think to OD on alcohol.
|
||||
var/heal_rate = 0.5 //The rate they heal damages over 400 alcohol stored. Default is 0.5 so we times 3 since 3 seconds.
|
||||
var/alcohol_rate = 0.25 //The rate the alcohol ticks down per each iteration of dwarf_eth_ticker completing.
|
||||
//These count in on_life ticks which should be 2 seconds per every increment of 1 in a perfect world.
|
||||
var/dwarf_filth_ticker = 0 //Currently set =< 4, that means this will fire the proc around every 4-8 seconds.
|
||||
var/dwarf_eth_ticker = 0 //Currently set =< 1, that means this will fire the proc around every 2 seconds
|
||||
|
||||
/obj/item/organ/dwarfgland/prepare_eat()
|
||||
var/obj/S = ..()
|
||||
S.reagents.add_reagent("ethanol", stored_alcohol/10)
|
||||
return S
|
||||
|
||||
/obj/item/organ/dwarfgland/on_life() //Primary loop to hook into to start delayed loops for other loops..
|
||||
. = ..()
|
||||
dwarf_cycle_ticker()
|
||||
|
||||
//Handles the delayed tick cycle by just adding on increments per each on_life() tick
|
||||
/obj/item/organ/dwarfgland/proc/dwarf_cycle_ticker()
|
||||
if(owner.stat == DEAD)
|
||||
return //We make sure they are not dead, so they don't increment any tickers.
|
||||
dwarf_eth_ticker++
|
||||
dwarf_filth_ticker++
|
||||
|
||||
if(dwarf_filth_ticker >= 4) //Should be around 4-8 seconds since a tick is around 2 seconds.
|
||||
dwarf_filth_cycle() //On_life will adjust regarding other factors, so we are along for the ride.
|
||||
dwarf_filth_ticker = 0 //We set the ticker back to 0 to go again.
|
||||
if(dwarf_eth_ticker >= 1) //Alcohol reagent check should be around 2 seconds, since a tick is around 2 seconds.
|
||||
dwarf_eth_cycle()
|
||||
dwarf_eth_ticker = 0
|
||||
|
||||
//If this still friggin uses too much CPU, I'll make a for view subsystem If I have to.
|
||||
/obj/item/organ/dwarfgland/proc/dwarf_filth_cycle()
|
||||
if(!owner?.client || !owner?.mind)
|
||||
return
|
||||
//Filth Reactions - Since miasma now exists
|
||||
var/filth_counter = 0 //Holder for the filth check cycle, basically contains how much filth dwarf sees numerically.
|
||||
for(var/fuck in view(owner,7)) //hello byond for view loop.
|
||||
if(istype(fuck, /mob/living/carbon/human))
|
||||
var/mob/living/carbon/human/H = fuck
|
||||
if(H.stat == DEAD || (HAS_TRAIT(H, TRAIT_FAKEDEATH)))
|
||||
filth_counter += 10
|
||||
if(istype(fuck, /obj/effect/decal/cleanable/blood))
|
||||
if(istype(fuck, /obj/effect/decal/cleanable/blood/gibs))
|
||||
filth_counter += 1
|
||||
else
|
||||
filth_counter += 0.1
|
||||
if(istype(fuck,/obj/effect/decal/cleanable/vomit)) //They are disgusted by their own vomit too.
|
||||
filth_counter += 10 //Dwarves could technically chainstun each other in a vomit tantrum spiral.
|
||||
switch(filth_counter)
|
||||
if(11 to 25)
|
||||
if(prob(25))
|
||||
to_chat(owner, "<span class = 'danger'>Someone should really clean up in here!</span>")
|
||||
if(26 to 50)
|
||||
if(prob(30)) //Probability the message appears
|
||||
to_chat(owner, "<span class = 'danger'>The stench makes you queasy.</span>")
|
||||
if(prob(20)) //And then the probability they vomit along with it.
|
||||
owner.vomit(20) //I think vomit should stay over a disgust adjustment.
|
||||
if(51 to 75)
|
||||
if(prob(35))
|
||||
to_chat(owner, "<span class = 'danger'>By Armok! You won't be able to keep alcohol down at all!</span>")
|
||||
if(prob(25))
|
||||
owner.vomit(20) //Its more funny
|
||||
if(76 to 100)
|
||||
if(prob(40))
|
||||
to_chat(owner, "<span class = 'userdanger'>You can't live in such FILTH!</span>")
|
||||
if(prob(25))
|
||||
owner.adjustToxLoss(10) //Now they start dying.
|
||||
owner.vomit(20)
|
||||
if(101 to INFINITY) //Now they will really start dying
|
||||
if(prob(40))
|
||||
to_chat(owner, "<span class = 'userdanger'> THERES TOO MUCH FILTH, OH GODS THE FILTH!</span>")
|
||||
owner.adjustToxLoss(15)
|
||||
owner.vomit(40)
|
||||
CHECK_TICK //Check_tick right here, its motherfuckin magic. (To me at least)
|
||||
|
||||
//Handles the dwarf alcohol cycle tied to on_life, it ticks in dwarf_cycle_ticker.
|
||||
/obj/item/organ/dwarfgland/proc/dwarf_eth_cycle()
|
||||
//BOOZE POWER
|
||||
for(var/datum/reagent/R in owner.reagents.reagent_list)
|
||||
if(istype(R, /datum/reagent/consumable/ethanol))
|
||||
var/datum/reagent/consumable/ethanol/E = R
|
||||
stored_alcohol += (E.boozepwr / 50)
|
||||
if(stored_alcohol > max_alcohol) //Dwarves technically start at 250 alcohol stored.
|
||||
stored_alcohol = max_alcohol
|
||||
var/heal_amt = heal_rate
|
||||
stored_alcohol -= alcohol_rate //Subtracts alcohol_Rate from stored alcohol so EX: 250 - 0.25 per each loop that occurs.
|
||||
if(stored_alcohol > 400) //If they are over 400 they start regenerating
|
||||
owner.adjustBruteLoss(-heal_amt) //But its alcohol, there will be other issues here.
|
||||
owner.adjustFireLoss(-heal_amt) //Unless they drink casually all the time.
|
||||
owner.adjustOxyLoss(-heal_amt)
|
||||
owner.adjustCloneLoss(-heal_amt) //Also they will probably get brain damage if thats a thing here.
|
||||
if(prob(25))
|
||||
switch(stored_alcohol)
|
||||
if(0 to 24)
|
||||
to_chat(owner, "<span class='userdanger'>DAMNATION INCARNATE, WHY AM I CURSED WITH THIS DRY-SPELL? I MUST DRINK.</span>")
|
||||
owner.adjustToxLoss(35)
|
||||
if(25 to 50)
|
||||
to_chat(owner, "<span class='danger'>Oh DAMN, I need some brew!</span>")
|
||||
if(51 to 75)
|
||||
to_chat(owner, "<span class='warning'>Your body aches, you need to get ahold of some booze...</span>")
|
||||
if(76 to 100)
|
||||
to_chat(owner, "<span class='notice'>A pint of anything would really hit the spot right now.</span>")
|
||||
if(101 to 150)
|
||||
to_chat(owner, "<span class='notice'>You feel like you could use a good brew.</span>")
|
||||
@@ -4,8 +4,8 @@
|
||||
id = "felinid"
|
||||
limbs_id = "human"
|
||||
|
||||
mutant_bodyparts = list("mam_ears", "mam_tail")
|
||||
default_features = list("mcolor" = "FFF", "mam_tail" = "Cat", "mam_ears" = "Cat", "wings" = "None")
|
||||
mutant_bodyparts = list("mam_ears", "mam_tail", "deco_wings")
|
||||
default_features = list("mcolor" = "FFF", "mam_tail" = "Cat", "mam_ears" = "Cat", "wings" = "None", "deco_wings" = "None")
|
||||
|
||||
mutantears = /obj/item/organ/ears/cat
|
||||
mutanttail = /obj/item/organ/tail/cat
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/fly
|
||||
disliked_food = null
|
||||
liked_food = GROSS
|
||||
exotic_bloodtype = "BUG"
|
||||
|
||||
/datum/species/fly/handle_chemicals(datum/reagent/chem, mob/living/carbon/human/H)
|
||||
if(chem.id == "pestkiller")
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
id = "mammal"
|
||||
default_color = "4B4B4B"
|
||||
should_draw_citadel = TRUE
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,LIPS,HAIR,HORNCOLOR)
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,LIPS,HAIR,HORNCOLOR,WINGCOLOR)
|
||||
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'
|
||||
@@ -64,8 +64,9 @@
|
||||
attack_sound = 'sound/weapons/slash.ogg'
|
||||
miss_sound = 'sound/weapons/slashmiss.ogg'
|
||||
meat = /obj/item/reagent_containers/food/snacks/meat/slab/xeno
|
||||
gib_types = list(/obj/effect/gibspawner/xeno/xenoperson, /obj/effect/gibspawner/xeno/xenoperson/bodypartless)
|
||||
skinned_type = /obj/item/stack/sheet/animalhide/xeno
|
||||
exotic_bloodtype = "L"
|
||||
exotic_bloodtype = "X*"
|
||||
damage_overlay_type = "xeno"
|
||||
liked_food = MEAT
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -634,9 +634,10 @@
|
||||
id = "clockwork golem"
|
||||
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)
|
||||
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, and are capable of using guns. On death, you will break down into scrap.</span>"
|
||||
species_traits = list(NOBLOOD,NO_UNDERWEAR,NOEYES,NOGENITALS,NOAROUSAL)
|
||||
inherent_biotypes = list(MOB_ROBOTIC, MOB_HUMANOID)
|
||||
inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOFIRE,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER)
|
||||
armor = 20 //Reinforced, but much less so to allow for fast movement
|
||||
attack_verb = "smash"
|
||||
attack_sound = 'sound/magic/clockwork/anima_fragment_attack.ogg'
|
||||
@@ -682,7 +683,7 @@
|
||||
blacklisted = TRUE
|
||||
dangerous_existence = TRUE
|
||||
random_eligible = FALSE
|
||||
info_text = "<span class='bold alloy'>As a </span><span class='bold brass'>Clockwork Golem Servant</span><span class='bold alloy'>, you are faster than other types of golems.</span>" //warcult golems leave a corpse
|
||||
info_text = "<span class='bold alloy'>As a </span><span class='bold brass'>Clockwork Golem Servant</span><span class='bold alloy'>, you are faster than other types of golems, and are capable of using guns.</span>" //warcult golems leave a corpse
|
||||
|
||||
/datum/species/golem/cloth
|
||||
name = "Cloth Golem"
|
||||
@@ -691,7 +692,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
|
||||
@@ -795,7 +796,7 @@
|
||||
if(resistance_flags & ON_FIRE)
|
||||
return
|
||||
|
||||
if(P.is_hot())
|
||||
if(P.get_temperature())
|
||||
visible_message("<span class='danger'>[src] bursts into flames!</span>")
|
||||
fire_act()
|
||||
|
||||
|
||||
@@ -1,41 +1,42 @@
|
||||
/datum/species/human
|
||||
name = "Human"
|
||||
id = "human"
|
||||
default_color = "FFFFFF"
|
||||
species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS,MUTCOLORS_PARTSONLY)
|
||||
mutant_bodyparts = list("ears", "tail_human", "wings", "taur") // CITADEL EDIT gives humans snowflake parts
|
||||
default_features = list("mcolor" = "FFF", "mcolor2" = "FFF","mcolor3" = "FFF","tail_human" = "None", "ears" = "None", "wings" = "None", "taur" = "None")
|
||||
use_skintones = 1
|
||||
skinned_type = /obj/item/stack/sheet/animalhide/human
|
||||
disliked_food = GROSS | RAW
|
||||
liked_food = JUNKFOOD | FRIED
|
||||
|
||||
/datum/species/human/qualifies_for_rank(rank, list/features)
|
||||
return TRUE //Pure humans are always allowed in all roles.
|
||||
|
||||
/datum/species/human/spec_death(gibbed, mob/living/carbon/human/H)
|
||||
if(H)
|
||||
stop_wagging_tail(H)
|
||||
|
||||
/datum/species/human/spec_stun(mob/living/carbon/human/H,amount)
|
||||
if(H)
|
||||
stop_wagging_tail(H)
|
||||
. = ..()
|
||||
|
||||
/datum/species/human/can_wag_tail(mob/living/carbon/human/H)
|
||||
return ("tail_human" in mutant_bodyparts) || ("waggingtail_human" in mutant_bodyparts)
|
||||
|
||||
/datum/species/human/is_wagging_tail(mob/living/carbon/human/H)
|
||||
return ("waggingtail_human" in mutant_bodyparts)
|
||||
|
||||
/datum/species/human/start_wagging_tail(mob/living/carbon/human/H)
|
||||
if("tail_human" in mutant_bodyparts)
|
||||
mutant_bodyparts -= "tail_human"
|
||||
mutant_bodyparts |= "waggingtail_human"
|
||||
H.update_body()
|
||||
|
||||
/datum/species/human/stop_wagging_tail(mob/living/carbon/human/H)
|
||||
if("waggingtail_human" in mutant_bodyparts)
|
||||
mutant_bodyparts -= "waggingtail_human"
|
||||
mutant_bodyparts |= "tail_human"
|
||||
H.update_body()
|
||||
/datum/species/human
|
||||
name = "Human"
|
||||
id = "human"
|
||||
default_color = "FFFFFF"
|
||||
|
||||
species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS,MUTCOLORS_PARTSONLY,WINGCOLOR)
|
||||
mutant_bodyparts = list("ears", "tail_human", "wings", "taur", "deco_wings") // CITADEL EDIT gives humans snowflake parts
|
||||
default_features = list("mcolor" = "FFF", "mcolor2" = "FFF","mcolor3" = "FFF","tail_human" = "None", "ears" = "None", "wings" = "None", "taur" = "None", "deco_wings" = "None")
|
||||
use_skintones = 1
|
||||
skinned_type = /obj/item/stack/sheet/animalhide/human
|
||||
disliked_food = GROSS | RAW
|
||||
liked_food = JUNKFOOD | FRIED
|
||||
|
||||
/datum/species/human/qualifies_for_rank(rank, list/features)
|
||||
return TRUE //Pure humans are always allowed in all roles.
|
||||
|
||||
/datum/species/human/spec_death(gibbed, mob/living/carbon/human/H)
|
||||
if(H)
|
||||
stop_wagging_tail(H)
|
||||
|
||||
/datum/species/human/spec_stun(mob/living/carbon/human/H,amount)
|
||||
if(H)
|
||||
stop_wagging_tail(H)
|
||||
. = ..()
|
||||
|
||||
/datum/species/human/can_wag_tail(mob/living/carbon/human/H)
|
||||
return ("tail_human" in mutant_bodyparts) || ("waggingtail_human" in mutant_bodyparts)
|
||||
|
||||
/datum/species/human/is_wagging_tail(mob/living/carbon/human/H)
|
||||
return ("waggingtail_human" in mutant_bodyparts)
|
||||
|
||||
/datum/species/human/start_wagging_tail(mob/living/carbon/human/H)
|
||||
if("tail_human" in mutant_bodyparts)
|
||||
mutant_bodyparts -= "tail_human"
|
||||
mutant_bodyparts |= "waggingtail_human"
|
||||
H.update_body()
|
||||
|
||||
/datum/species/human/stop_wagging_tail(mob/living/carbon/human/H)
|
||||
if("waggingtail_human" in mutant_bodyparts)
|
||||
mutant_bodyparts -= "waggingtail_human"
|
||||
mutant_bodyparts |= "tail_human"
|
||||
H.update_body()
|
||||
|
||||
@@ -11,9 +11,10 @@
|
||||
mutant_bodyparts = list("ipc_screen", "ipc_antenna")
|
||||
default_features = list("ipc_screen" = "Blank", "ipc_antenna" = "None")
|
||||
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/ipc
|
||||
gib_types = list(/obj/effect/gibspawner/ipc, /obj/effect/gibspawner/ipc/bodypartless)
|
||||
mutanttongue = /obj/item/organ/tongue/robot/ipc
|
||||
|
||||
exotic_blood = "oil"
|
||||
mutant_heart = /obj/item/organ/heart/ipc
|
||||
exotic_bloodtype = "HF"
|
||||
|
||||
var/datum/action/innate/monitor_change/screen
|
||||
|
||||
|
||||
@@ -4,13 +4,16 @@
|
||||
id = "jelly"
|
||||
default_color = "00FF90"
|
||||
say_mod = "chirps"
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,NOBLOOD)
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,WINGCOLOR)
|
||||
mutantlungs = /obj/item/organ/lungs/slime
|
||||
mutant_bodyparts = list("mam_tail", "mam_ears", "mam_snouts", "taur") //CIT CHANGE
|
||||
default_features = list("mcolor" = "FFF", "mam_tail" = "None", "mam_ears" = "None", "mam_snouts" = "None", "taur" = "None") //CIT CHANGE
|
||||
mutant_heart = /obj/item/organ/heart/slime
|
||||
mutant_bodyparts = list("mam_tail", "mam_ears", "mam_snouts", "taur", "deco_wings") //CIT CHANGE
|
||||
default_features = list("mcolor" = "FFF", "mam_tail" = "None", "mam_ears" = "None", "mam_snouts" = "None", "taur" = "None", "deco_wings" = "None") //CIT CHANGE
|
||||
inherent_traits = list(TRAIT_TOXINLOVER)
|
||||
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/slime
|
||||
exotic_blood = "slimejelly"
|
||||
gib_types = list(/obj/effect/gibspawner/slime, /obj/effect/gibspawner/slime/bodypartless)
|
||||
exotic_blood = "jellyblood"
|
||||
exotic_bloodtype = "GEL"
|
||||
damage_overlay_type = ""
|
||||
var/datum/action/innate/regenerate_limbs/regenerate_limbs
|
||||
var/datum/action/innate/slime_change/slime_change //CIT CHANGE
|
||||
@@ -121,7 +124,7 @@
|
||||
name = "Xenobiological Slime Entity"
|
||||
id = "slime"
|
||||
default_color = "00FFFF"
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,NOBLOOD)
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR)
|
||||
say_mod = "says"
|
||||
hair_color = "mutcolor"
|
||||
hair_alpha = 150
|
||||
@@ -396,7 +399,7 @@
|
||||
id = "slimeperson"
|
||||
limbs_id = "slime"
|
||||
default_color = "00FFFF"
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,NOBLOOD)
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR)
|
||||
inherent_traits = list(TRAIT_TOXINLOVER)
|
||||
mutant_bodyparts = list("mam_tail", "mam_ears", "mam_body_markings", "mam_snouts", "taur")
|
||||
default_features = list("mcolor" = "FFF", "mcolor2" = "FFF","mcolor3" = "FFF", "mam_tail" = "None", "mam_ears" = "None", "mam_body_markings" = "Plain", "mam_snouts" = "None", "taur" = "None")
|
||||
@@ -470,37 +473,25 @@
|
||||
H.hair_style = new_style
|
||||
H.update_hair()
|
||||
else if (select_alteration == "Genitals")
|
||||
var/list/organs = list()
|
||||
var/operation = input("Select organ operation.", "Organ Manipulation", "cancel") in list("add sexual organ", "remove sexual organ", "cancel")
|
||||
switch(operation)
|
||||
if("add sexual organ")
|
||||
var/new_organ = input("Select sexual organ:", "Organ Manipulation") in list("Penis", "Testicles", "Breasts", "Vagina", "Womb", "Cancel")
|
||||
if(new_organ == "Penis")
|
||||
H.give_penis()
|
||||
else if(new_organ == "Testicles")
|
||||
H.give_balls()
|
||||
else if(new_organ == "Breasts")
|
||||
H.give_breasts()
|
||||
else if(new_organ == "Vagina")
|
||||
H.give_vagina()
|
||||
else if(new_organ == "Womb")
|
||||
H.give_womb()
|
||||
else
|
||||
var/new_organ = input("Select sexual organ:", "Organ Manipulation") as null|anything in GLOB.genitals_list
|
||||
if(!new_organ)
|
||||
return
|
||||
H.give_genital(GLOB.genitals_list[new_organ])
|
||||
|
||||
if("remove sexual organ")
|
||||
var/list/organs = list()
|
||||
for(var/obj/item/organ/genital/X in H.internal_organs)
|
||||
var/obj/item/organ/I = X
|
||||
organs["[I.name] ([I.type])"] = I
|
||||
var/obj/item/organ = input("Select sexual organ:", "Organ Manipulation", null) in organs
|
||||
organ = organs[organ]
|
||||
if(!organ)
|
||||
var/obj/item/O = input("Select sexual organ:", "Organ Manipulation", null) as null|anything in organs
|
||||
var/obj/item/organ/genital/G = organs[O]
|
||||
if(!G)
|
||||
return
|
||||
var/obj/item/organ/genital/O
|
||||
if(isorgan(organ))
|
||||
O = organ
|
||||
O.Remove(H)
|
||||
organ.forceMove(get_turf(H))
|
||||
qdel(organ)
|
||||
G.forceMove(get_turf(H))
|
||||
qdel(G)
|
||||
H.update_genitals()
|
||||
|
||||
else if (select_alteration == "Ears")
|
||||
@@ -590,8 +581,8 @@
|
||||
if(new_shape)
|
||||
H.dna.features["cock_shape"] = new_shape
|
||||
H.update_genitals()
|
||||
H.give_balls()
|
||||
H.give_penis()
|
||||
H.give_genital(/obj/item/organ/genital/testicles)
|
||||
H.give_genital(/obj/item/organ/genital/penis)
|
||||
H.apply_overlay()
|
||||
|
||||
|
||||
@@ -603,8 +594,8 @@
|
||||
if(new_shape)
|
||||
H.dna.features["vag_shape"] = new_shape
|
||||
H.update_genitals()
|
||||
H.give_womb()
|
||||
H.give_vagina()
|
||||
H.give_genital(/obj/item/organ/genital/womb)
|
||||
H.give_genital(/obj/item/organ/genital/vagina)
|
||||
H.apply_overlay()
|
||||
|
||||
else if (select_alteration == "Penis Length")
|
||||
@@ -616,8 +607,8 @@
|
||||
H.dna.features["cock_length"] = max(min( round(text2num(new_length)), COCK_SIZE_MAX),COCK_SIZE_MIN)
|
||||
H.update_genitals()
|
||||
H.apply_overlay()
|
||||
H.give_balls()
|
||||
H.give_penis()
|
||||
H.give_genital(/obj/item/organ/genital/testicles)
|
||||
H.give_genital(/obj/item/organ/genital/penis)
|
||||
|
||||
else if (select_alteration == "Breast Size")
|
||||
for(var/obj/item/organ/genital/breasts/X in H.internal_organs)
|
||||
@@ -628,7 +619,7 @@
|
||||
H.dna.features["breasts_size"] = new_size
|
||||
H.update_genitals()
|
||||
H.apply_overlay()
|
||||
H.give_breasts()
|
||||
H.give_genital(/obj/item/organ/genital/breasts)
|
||||
|
||||
else if (select_alteration == "Breast Shape")
|
||||
for(var/obj/item/organ/genital/breasts/X in H.internal_organs)
|
||||
@@ -639,7 +630,7 @@
|
||||
H.dna.features["breasts_shape"] = new_shape
|
||||
H.update_genitals()
|
||||
H.apply_overlay()
|
||||
H.give_breasts()
|
||||
H.give_genital(/obj/item/organ/genital/breasts)
|
||||
|
||||
else
|
||||
return
|
||||
@@ -854,6 +845,8 @@
|
||||
return FALSE
|
||||
if(HAS_TRAIT(M, TRAIT_MINDSHIELD)) //mindshield implant, no dice
|
||||
return FALSE
|
||||
if(M.anti_magic_check(FALSE, FALSE, TRUE, 0))
|
||||
return FALSE
|
||||
if(M in linked_mobs)
|
||||
return FALSE
|
||||
linked_mobs.Add(M)
|
||||
@@ -939,9 +932,14 @@
|
||||
var/mob/living/M = input("Select who to send your message to:","Send thought to?",null) as null|mob in options
|
||||
if(!M)
|
||||
return
|
||||
|
||||
if(M.anti_magic_check(FALSE, FALSE, TRUE, 0))
|
||||
to_chat(H, "<span class='notice'>As you try to communicate with [M], you're suddenly stopped by a vision of a massive tinfoil wall that streches beyond visible range. It seems you've been foiled.</span>")
|
||||
return
|
||||
var/msg = sanitize(input("Message:", "Telepathy") as text|null)
|
||||
if(msg)
|
||||
if(M.anti_magic_check(FALSE, FALSE, TRUE, 0))
|
||||
to_chat(H, "<span class='notice'>As you try to communicate with [M], you're suddenly stopped by a vision of a massive tinfoil wall that streches beyond visible range. It seems you've been foiled.</span>")
|
||||
return
|
||||
log_directed_talk(H, M, msg, LOG_SAY, "slime telepathy")
|
||||
to_chat(M, "<span class='notice'>You hear an alien voice in your head... </span><font color=#008CA2>[msg]</font>")
|
||||
to_chat(H, "<span class='notice'>You telepathically said: \"[msg]\" to [M]</span>")
|
||||
|
||||
@@ -4,20 +4,21 @@
|
||||
id = "lizard"
|
||||
say_mod = "hisses"
|
||||
default_color = "00FF00"
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,LIPS,HORNCOLOR)
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,LIPS,HORNCOLOR,WINGCOLOR)
|
||||
inherent_biotypes = list(MOB_ORGANIC, MOB_HUMANOID, MOB_REPTILE)
|
||||
mutant_bodyparts = list("tail_lizard", "snout", "spines", "horns", "frills", "body_markings", "legs", "taur")
|
||||
mutant_bodyparts = list("tail_lizard", "snout", "spines", "horns", "frills", "body_markings", "legs", "taur", "deco_wings")
|
||||
mutanttongue = /obj/item/organ/tongue/lizard
|
||||
mutanttail = /obj/item/organ/tail/lizard
|
||||
coldmod = 1.5
|
||||
heatmod = 0.67
|
||||
default_features = list("mcolor" = "0F0", "mcolor2" = "0F0", "mcolor3" = "0F0", "tail_lizard" = "Smooth", "snout" = "Round",
|
||||
"horns" = "None", "frills" = "None", "spines" = "None", "body_markings" = "None",
|
||||
"legs" = "Digitigrade", "taur" = "None")
|
||||
"legs" = "Digitigrade", "taur" = "None", "deco_wings" = "None")
|
||||
attack_verb = "slash"
|
||||
attack_sound = 'sound/weapons/slash.ogg'
|
||||
miss_sound = 'sound/weapons/slashmiss.ogg'
|
||||
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/lizard
|
||||
gib_types = list(/obj/effect/gibspawner/lizard, /obj/effect/gibspawner/lizard/bodypartless)
|
||||
skinned_type = /obj/item/stack/sheet/animalhide/lizard
|
||||
exotic_bloodtype = "L"
|
||||
disliked_food = GRAIN | DAIRY
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -78,7 +78,7 @@
|
||||
icon_state = "brain-x-d"
|
||||
var/obj/effect/proc_holder/spell/targeted/shadowwalk/shadowwalk
|
||||
|
||||
/obj/item/organ/brain/nightmare/Insert(mob/living/carbon/M, special = 0)
|
||||
/obj/item/organ/brain/nightmare/Insert(mob/living/carbon/M, special = 0, drop_if_replaced = TRUE)
|
||||
..()
|
||||
if(M.dna.species.id != "nightmare")
|
||||
M.set_species(/datum/species/shadow/nightmare)
|
||||
@@ -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)
|
||||
@@ -117,15 +118,13 @@
|
||||
user.temporarilyRemoveItemFromInventory(src, TRUE)
|
||||
Insert(user)
|
||||
|
||||
/obj/item/organ/heart/nightmare/Insert(mob/living/carbon/M, special = 0)
|
||||
/obj/item/organ/heart/nightmare/Insert(mob/living/carbon/M, special = 0, drop_if_replaced = TRUE)
|
||||
..()
|
||||
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,19 @@
|
||||
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"
|
||||
limbs_id = "skeleton"
|
||||
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/space/check_roundstart_eligible()
|
||||
return FALSE
|
||||
@@ -9,6 +9,7 @@
|
||||
dangerous_existence = 1
|
||||
blacklisted = 1
|
||||
meat = null
|
||||
gib_types = /obj/effect/gibspawner/robot
|
||||
damage_overlay_type = "synth"
|
||||
limbs_id = "synth"
|
||||
var/list/initial_species_traits = list(NOTRANSSTING) //for getting these values back for assume_disguise()
|
||||
|
||||
@@ -45,14 +45,14 @@
|
||||
C.adjustOxyLoss(-4)
|
||||
C.adjustCloneLoss(-4)
|
||||
return
|
||||
C.blood_volume -= 0.75
|
||||
C.blood_volume -= 0.75 //Will take roughly 19.5 minutes to die from standard blood volume, roughly 83 minutes to die from max blood volume.
|
||||
if(C.blood_volume <= (BLOOD_VOLUME_SURVIVE*C.blood_ratio))
|
||||
to_chat(C, "<span class='danger'>You ran out of blood!</span>")
|
||||
C.dust()
|
||||
var/area/A = get_area(C)
|
||||
if(istype(A, /area/chapel))
|
||||
to_chat(C, "<span class='danger'>You don't belong here!</span>")
|
||||
C.adjustFireLoss(20)
|
||||
C.adjustFireLoss(5)
|
||||
C.adjust_fire_stacks(6)
|
||||
C.IgniteMob()
|
||||
|
||||
@@ -88,7 +88,7 @@
|
||||
to_chat(H, "<span class='notice'>[victim] doesn't have blood!</span>")
|
||||
return
|
||||
V.drain_cooldown = world.time + 30
|
||||
if(victim.anti_magic_check(FALSE, TRUE))
|
||||
if(victim.anti_magic_check(FALSE, TRUE, FALSE, 0))
|
||||
to_chat(victim, "<span class='warning'>[H] tries to bite you, but stops before touching you!</span>")
|
||||
to_chat(H, "<span class='warning'>[victim] is blessed! You stop just in time to avoid catching fire.</span>")
|
||||
return
|
||||
@@ -141,7 +141,7 @@
|
||||
H = new(shape,src,caster)
|
||||
if(istype(H, /mob/living/simple_animal))
|
||||
var/mob/living/simple_animal/SA = H
|
||||
if(ventcrawl_nude_only && length(caster.get_equipped_items(include_pockets = TRUE)))
|
||||
if((caster.blood_volume >= (BLOOD_VOLUME_BAD*caster.blood_ratio)) || (ventcrawl_nude_only && length(caster.get_equipped_items(include_pockets = TRUE))))
|
||||
SA.ventcrawler = FALSE
|
||||
if(transfer_name)
|
||||
H.name = caster.name
|
||||
|
||||
@@ -16,7 +16,13 @@
|
||||
disliked_food = NONE
|
||||
liked_food = GROSS | MEAT | RAW
|
||||
|
||||
/datum/species/zombie/check_roundstart_eligible()
|
||||
/datum/species/zombie/notspaceproof
|
||||
id = "notspaceproofzombie"
|
||||
limbs_id = "zombie"
|
||||
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 ..()
|
||||
@@ -39,7 +45,7 @@
|
||||
/datum/species/zombie/infectious/spec_stun(mob/living/carbon/human/H,amount)
|
||||
. = min(20, amount)
|
||||
|
||||
/datum/species/zombie/infectious/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked, mob/living/carbon/human/H)
|
||||
/datum/species/zombie/infectious/apply_damage(damage, damagetype = BRUTE, def_zone = null, blocked, mob/living/carbon/human/H, forced = FALSE)
|
||||
. = ..()
|
||||
if(.)
|
||||
regen_cooldown = world.time + REGENERATION_DELAY
|
||||
@@ -47,7 +53,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,9 +64,9 @@
|
||||
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)
|
||||
/datum/species/zombie/infectious/spec_death(gibbed, mob/living/carbon/C)
|
||||
. = ..()
|
||||
var/obj/item/organ/zombie_infection/infection
|
||||
infection = C.getorganslot(ORGAN_SLOT_ZOMBIE)
|
||||
|
||||
@@ -123,25 +123,20 @@ 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
|
||||
var/alt_worn = U.alternate_worn_icon
|
||||
|
||||
if(!U.force_alternate_icon && U.mutantrace_variation && U.suit_style == DIGITIGRADE_SUIT_STYLE)
|
||||
alt_worn = 'modular_citadel/icons/mob/uniform_digi.dmi'
|
||||
|
||||
var/mutable_appearance/uniform_overlay
|
||||
|
||||
if(dna && dna.species.sexes)
|
||||
var/G = (gender == FEMALE) ? "f" : "m"
|
||||
if(G == "f" && U.fitted != NO_FEMALE_UNIFORM)
|
||||
uniform_overlay = U.build_worn_icon(state = "[t_color]", default_layer = UNIFORM_LAYER, default_icon_file = ((w_uniform.alternate_worn_icon) ? w_uniform.alternate_worn_icon : 'icons/mob/uniform.dmi'), isinhands = FALSE, femaleuniform = U.fitted)
|
||||
uniform_overlay = U.build_worn_icon(state = "[t_color]", default_layer = UNIFORM_LAYER, default_icon_file = (alt_worn ? alt_worn : 'icons/mob/uniform.dmi'), isinhands = FALSE, femaleuniform = U.fitted)
|
||||
|
||||
if(!uniform_overlay)
|
||||
uniform_overlay = U.build_worn_icon(state = "[t_color]", default_layer = UNIFORM_LAYER, default_icon_file = ((w_uniform.alternate_worn_icon) ? w_uniform.alternate_worn_icon : 'icons/mob/uniform.dmi'), isinhands = FALSE)
|
||||
uniform_overlay = U.build_worn_icon(state = "[t_color]", default_layer = UNIFORM_LAYER, default_icon_file = (alt_worn ? alt_worn : 'icons/mob/uniform.dmi'), isinhands = FALSE)
|
||||
|
||||
|
||||
if(OFFSET_UNIFORM in dna.species.offset_features)
|
||||
@@ -185,7 +180,7 @@ There are several things that need to be remembered:
|
||||
inv.update_icon()
|
||||
|
||||
if(!gloves && bloody_hands)
|
||||
var/mutable_appearance/bloody_overlay = mutable_appearance('icons/effects/blood.dmi', "bloodyhands", -GLOVES_LAYER)
|
||||
var/mutable_appearance/bloody_overlay = mutable_appearance('icons/effects/blood.dmi', "bloodyhands", -GLOVES_LAYER, color = blood_DNA_to_color())
|
||||
if(get_num_arms() < 2)
|
||||
if(has_left_hand())
|
||||
bloody_overlay.icon_state = "bloodyhands_left"
|
||||
@@ -275,6 +270,32 @@ There are several things that need to be remembered:
|
||||
if(client && hud_used)
|
||||
var/obj/screen/inventory/inv = hud_used.inv_slots[SLOT_SHOES]
|
||||
inv.update_icon()
|
||||
/*
|
||||
if(!shoes && bloody_feet)
|
||||
var/mutable_appearance/bloody_overlay = mutable_appearance('icons/effects/blood.dmi', "bloodyfeet", -SHOES_LAYER, color = blood_DNA_to_color())
|
||||
if(dna.features["taur"] != "None")
|
||||
if(dna.features["taur"] in GLOB.noodle_taurs)
|
||||
bloody_overlay = mutable_appearance('modular_citadel/icons/mob/64x32_effects.dmi', "snekbloodyfeet", -SHOES_LAYER, color = blood_DNA_to_color())
|
||||
if(get_num_legs() < 2)
|
||||
if(has_left_leg())
|
||||
bloody_overlay.icon_state = "snekbloodyfeet_left"
|
||||
else if(has_right_leg())
|
||||
bloody_overlay.icon_state = "snekbloodyfeet_right"
|
||||
else if(dna.features["taur"] in GLOB.paw_taurs)
|
||||
bloody_overlay = mutable_appearance('modular_citadel/icons/mob/64x32_effects.dmi', "pawbloodyfeet", -SHOES_LAYER, color = blood_DNA_to_color())
|
||||
if(get_num_legs() < 2)
|
||||
if(has_left_leg())
|
||||
bloody_overlay.icon_state = "pawbloodyfeet_left"
|
||||
else if(has_right_leg())
|
||||
bloody_overlay.icon_state = "pawbloodyfeet_right"
|
||||
else
|
||||
if(get_num_legs() < 2)
|
||||
if(has_left_leg())
|
||||
bloody_overlay.icon_state = "bloodyfeet_left"
|
||||
else if(has_right_leg())
|
||||
bloody_overlay.icon_state = "bloodyfeet_right"
|
||||
|
||||
overlays_standing[GLOVES_LAYER] = bloody_overlay*/
|
||||
|
||||
if(shoes)
|
||||
var/obj/item/clothing/shoes/S = shoes
|
||||
@@ -315,7 +336,7 @@ There are several things that need to be remembered:
|
||||
if(!t_state)
|
||||
t_state = s_store.icon_state
|
||||
overlays_standing[SUIT_STORE_LAYER] = mutable_appearance(((s_store.alternate_worn_icon) ? s_store.alternate_worn_icon : 'icons/mob/belt_mirror.dmi'), t_state, -SUIT_STORE_LAYER)
|
||||
var/mutable_appearance/s_store_overlay = overlays_standing[SUIT_LAYER]
|
||||
var/mutable_appearance/s_store_overlay = overlays_standing[SUIT_STORE_LAYER]
|
||||
if(OFFSET_S_STORE in dna.species.offset_features)
|
||||
s_store_overlay.pixel_x += dna.species.offset_features[OFFSET_S_STORE][1]
|
||||
s_store_overlay.pixel_y += dna.species.offset_features[OFFSET_S_STORE][2]
|
||||
@@ -379,37 +400,38 @@ There are several things that need to be remembered:
|
||||
|
||||
if(wear_suit)
|
||||
var/obj/item/clothing/suit/S = wear_suit
|
||||
var/no_taur_thanks = FALSE
|
||||
var/item_level_support = FALSE // LISTEN! If you must degrade the code with further snowflake checks, at least keep it compatible with worn non-clothing items!
|
||||
if(!istype(S))
|
||||
no_taur_thanks = TRUE
|
||||
item_level_support = TRUE
|
||||
wear_suit.screen_loc = ui_oclothing
|
||||
if(client && hud_used && hud_used.hud_shown)
|
||||
if(hud_used.inventory_shown)
|
||||
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(!item_level_support && !S.force_alternate_icon)
|
||||
if(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)
|
||||
suit_overlay.pixel_x += dna.species.offset_features[OFFSET_SUIT][1]
|
||||
suit_overlay.pixel_y += dna.species.offset_features[OFFSET_SUIT][2]
|
||||
if(!no_taur_thanks && S.center)
|
||||
if(!item_level_support && S.center)
|
||||
suit_overlay = center_image(suit_overlay, S.dimension_x, S.dimension_y)
|
||||
overlays_standing[SUIT_LAYER] = suit_overlay
|
||||
update_hair()
|
||||
@@ -707,9 +729,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 +744,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 && 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()
|
||||
@@ -671,7 +702,7 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put
|
||||
/mob/living/carbon/proc/liver_failure()
|
||||
reagents.end_metabolization(src, keep_liverless = TRUE) //Stops trait-based effects on reagents, to prevent permanent buffs
|
||||
reagents.metabolize(src, can_overdose=FALSE, liverless = TRUE)
|
||||
if(HAS_TRAIT(src, TRAIT_STABLEHEART))
|
||||
if(HAS_TRAIT(src, TRAIT_STABLELIVER))
|
||||
return
|
||||
adjustToxLoss(4, TRUE, TRUE)
|
||||
if(prob(30))
|
||||
@@ -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())
|
||||
|
||||
@@ -23,7 +23,7 @@
|
||||
|
||||
if(changed)
|
||||
animate(src, transform = ntransform, time = 2, pixel_y = final_pixel_y, dir = final_dir, easing = EASE_IN|EASE_OUT)
|
||||
floating = 0 // If we were without gravity, the bouncing animation got stopped, so we make sure we restart it in next life().
|
||||
setMovetype(movement_type & ~FLOATING) // If we were without gravity, the bouncing animation got stopped, so we make sure we restart it in next life().
|
||||
|
||||
|
||||
/mob/living/carbon
|
||||
@@ -97,8 +97,12 @@
|
||||
|
||||
/mob/living/carbon/update_damage_overlays()
|
||||
remove_overlay(DAMAGE_LAYER)
|
||||
var/dam_colors = "#E62525"
|
||||
if(ishuman(src))
|
||||
var/mob/living/carbon/human/H = src
|
||||
dam_colors = bloodtype_to_color(H.dna.blood_type)
|
||||
|
||||
var/mutable_appearance/damage_overlay = mutable_appearance('icons/mob/dam_mob.dmi', "blank", -DAMAGE_LAYER)
|
||||
var/mutable_appearance/damage_overlay = mutable_appearance('icons/mob/dam_mob.dmi', "blank", -DAMAGE_LAYER, color = dam_colors)
|
||||
overlays_standing[DAMAGE_LAYER] = damage_overlay
|
||||
|
||||
for(var/X in bodyparts)
|
||||
|
||||
@@ -8,25 +8,24 @@
|
||||
Returns
|
||||
standard 0 if fail
|
||||
*/
|
||||
/mob/living/proc/apply_damage(damage = 0,damagetype = BRUTE, def_zone = null, blocked = FALSE)
|
||||
/mob/living/proc/apply_damage(damage = 0,damagetype = BRUTE, def_zone = null, blocked = FALSE, forced = FALSE)
|
||||
var/hit_percent = (100-blocked)/100
|
||||
if(!damage || (hit_percent <= 0))
|
||||
return 0
|
||||
var/damage_amount = forced ? damage : damage * hit_percent
|
||||
switch(damagetype)
|
||||
if(BRUTE)
|
||||
adjustBruteLoss(damage * hit_percent)
|
||||
adjustBruteLoss(damage_amount, forced = forced)
|
||||
if(BURN)
|
||||
adjustFireLoss(damage * hit_percent)
|
||||
adjustFireLoss(damage_amount, forced = forced)
|
||||
if(TOX)
|
||||
adjustToxLoss(damage * hit_percent)
|
||||
adjustToxLoss(damage_amount, forced = forced)
|
||||
if(OXY)
|
||||
adjustOxyLoss(damage * hit_percent)
|
||||
adjustOxyLoss(damage_amount, forced = forced)
|
||||
if(CLONE)
|
||||
adjustCloneLoss(damage * hit_percent)
|
||||
adjustCloneLoss(damage_amount, forced = forced)
|
||||
if(STAMINA)
|
||||
adjustStaminaLoss(damage * hit_percent)
|
||||
if(BRAIN)
|
||||
adjustBrainLoss(damage * hit_percent)
|
||||
adjustStaminaLoss(damage_amount, forced = forced)
|
||||
return 1
|
||||
|
||||
/mob/living/proc/apply_damage_type(damage = 0, damagetype = BRUTE) //like apply damage except it always uses the damage procs
|
||||
@@ -43,8 +42,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 +57,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)
|
||||
@@ -85,7 +80,7 @@
|
||||
|
||||
|
||||
|
||||
/mob/living/proc/apply_effect(effect = 0,effecttype = EFFECT_STUN, blocked = FALSE)
|
||||
/mob/living/proc/apply_effect(effect = 0,effecttype = EFFECT_STUN, blocked = FALSE, knockdown_stamoverride, knockdown_stammax)
|
||||
var/hit_percent = (100-blocked)/100
|
||||
if(!effect || (hit_percent <= 0))
|
||||
return 0
|
||||
@@ -93,7 +88,7 @@
|
||||
if(EFFECT_STUN)
|
||||
Stun(effect * hit_percent)
|
||||
if(EFFECT_KNOCKDOWN)
|
||||
Knockdown(effect * hit_percent)
|
||||
Knockdown(effect * hit_percent, override_stamdmg = knockdown_stammax ? CLAMP(knockdown_stamoverride, 0, knockdown_stammax-getStaminaLoss()) : knockdown_stamoverride)
|
||||
if(EFFECT_UNCONSCIOUS)
|
||||
Unconscious(effect * hit_percent)
|
||||
if(EFFECT_IRRADIATE)
|
||||
@@ -113,13 +108,13 @@
|
||||
return 1
|
||||
|
||||
|
||||
/mob/living/proc/apply_effects(stun = 0, knockdown = 0, unconscious = 0, irradiate = 0, slur = 0, stutter = 0, eyeblur = 0, drowsy = 0, blocked = FALSE, stamina = 0, jitter = 0)
|
||||
/mob/living/proc/apply_effects(stun = 0, knockdown = 0, unconscious = 0, irradiate = 0, slur = 0, stutter = 0, eyeblur = 0, drowsy = 0, blocked = FALSE, stamina = 0, jitter = 0, kd_stamoverride, kd_stammax)
|
||||
if(blocked >= 100)
|
||||
return 0
|
||||
if(stun)
|
||||
apply_effect(stun, EFFECT_STUN, blocked)
|
||||
if(knockdown)
|
||||
apply_effect(knockdown, EFFECT_KNOCKDOWN, blocked)
|
||||
apply_effect(knockdown, EFFECT_KNOCKDOWN, blocked, kd_stamoverride, kd_stammax)
|
||||
if(unconscious)
|
||||
apply_effect(unconscious, EFFECT_UNCONSCIOUS, blocked)
|
||||
if(irradiate)
|
||||
@@ -218,13 +213,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,14 +13,22 @@
|
||||
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)
|
||||
|
||||
/mob/living/proc/gib_animation()
|
||||
return
|
||||
|
||||
/mob/living/proc/spawn_gibs()
|
||||
new /obj/effect/gibspawner/generic(drop_location(), null, get_static_viruses())
|
||||
/mob/living/proc/spawn_gibs(with_bodyparts, atom/loc_override)
|
||||
var/location = loc_override ? loc_override.drop_location() : drop_location()
|
||||
if(MOB_ROBOTIC in mob_biotypes)
|
||||
new /obj/effect/gibspawner/robot(location, src, get_static_viruses())
|
||||
else
|
||||
new /obj/effect/gibspawner/generic(location, src, get_static_viruses())
|
||||
|
||||
/mob/living/proc/spill_organs()
|
||||
return
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
if(digitalinvis)
|
||||
handle_diginvis() //AI becomes unable to see mob
|
||||
|
||||
if((movement_type & FLYING) && !floating) //TODO: Better floating
|
||||
if((movement_type & FLYING) && !(movement_type & FLOATING)) //TODO: Better floating
|
||||
float(on = TRUE)
|
||||
|
||||
if (client)
|
||||
|
||||
@@ -40,6 +40,16 @@
|
||||
QDEL_LIST(diseases)
|
||||
return ..()
|
||||
|
||||
/mob/living/onZImpact(turf/T, levels)
|
||||
if(!isgroundlessturf(T))
|
||||
ZImpactDamage(T, levels)
|
||||
return ..()
|
||||
|
||||
/mob/living/proc/ZImpactDamage(turf/T, levels)
|
||||
visible_message("<span class='danger'>[src] crashes into [T] with a sickening noise!</span>")
|
||||
adjustBruteLoss((levels * 5) ** 1.5)
|
||||
Knockdown(levels * 50)
|
||||
|
||||
/mob/living/proc/OpenCraftingMenu()
|
||||
return
|
||||
|
||||
@@ -346,6 +356,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 +491,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)
|
||||
@@ -498,11 +512,19 @@
|
||||
fire_stacks = 0
|
||||
confused = 0
|
||||
update_canmove()
|
||||
GET_COMPONENT(mood, /datum/component/mood)
|
||||
var/datum/component/mood/mood = GetComponent(/datum/component/mood)
|
||||
if (mood)
|
||||
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)
|
||||
SEND_SIGNAL(src, COMSIG_LIVING_FULLY_HEAL, admin_revive)
|
||||
|
||||
|
||||
//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)
|
||||
@@ -705,14 +727,14 @@
|
||||
var/fixed = 0
|
||||
if(anchored || (buckled && buckled.anchored))
|
||||
fixed = 1
|
||||
if(on && !floating && !fixed)
|
||||
if(on && !(movement_type & FLOATING) && !fixed)
|
||||
animate(src, pixel_y = pixel_y + 2, time = 10, loop = -1)
|
||||
sleep(10)
|
||||
animate(src, pixel_y = pixel_y - 2, time = 10, loop = -1)
|
||||
floating = TRUE
|
||||
else if(((!on || fixed) && floating))
|
||||
setMovetype(movement_type | FLOATING)
|
||||
else if(((!on || fixed) && (movement_type & FLOATING)))
|
||||
animate(src, pixel_y = get_standard_pixel_y_offset(lying), time = 10)
|
||||
floating = FALSE
|
||||
setMovetype(movement_type & ~FLOATING)
|
||||
|
||||
// The src mob is trying to strip an item from someone
|
||||
// Override if a certain type of mob should be behave differently when stripping items (can't, for example)
|
||||
@@ -784,7 +806,7 @@
|
||||
var/final_pixel_y = get_standard_pixel_y_offset(lying)
|
||||
animate(src, pixel_x = pixel_x + pixel_x_diff, pixel_y = pixel_y + pixel_y_diff , time = 2, loop = 6)
|
||||
animate(pixel_x = final_pixel_x , pixel_y = final_pixel_y , time = 2)
|
||||
floating = 0 // If we were without gravity, the bouncing animation got stopped, so we make sure to restart it in next life().
|
||||
setMovetype(movement_type & ~FLOATING) // If we were without gravity, the bouncing animation got stopped, so we make sure to restart it in next life().
|
||||
|
||||
/mob/living/proc/get_temperature(datum/gas_mixture/environment)
|
||||
var/loc_temp = environment ? environment.temperature : T0C
|
||||
@@ -901,7 +923,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
|
||||
@@ -924,7 +946,7 @@
|
||||
|
||||
apply_effect((amount*RAD_MOB_COEFFICIENT)/max(1, (radiation**2)*RAD_OVERDOSE_REDUCTION), EFFECT_IRRADIATE, blocked)
|
||||
|
||||
/mob/living/anti_magic_check(magic = TRUE, holy = FALSE)
|
||||
/mob/living/anti_magic_check(magic = TRUE, holy = FALSE, chargecost = 1, self = FALSE)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
|
||||
@@ -92,6 +92,9 @@
|
||||
|
||||
/mob/living/mech_melee_attack(obj/mecha/M)
|
||||
if(M.occupant.a_intent == INTENT_HARM)
|
||||
if(HAS_TRAIT(M.occupant, TRAIT_PACIFISM))
|
||||
to_chat(M.occupant, "<span class='warning'>You don't want to harm other living beings!</span>")
|
||||
return
|
||||
M.do_attack_animation(src)
|
||||
if(M.damtype == "brute")
|
||||
step_away(src,M,15)
|
||||
@@ -422,4 +425,4 @@
|
||||
if(!used_item)
|
||||
used_item = get_active_held_item()
|
||||
..()
|
||||
floating = 0 // If we were without gravity, the bouncing animation got stopped, so we make sure we restart the bouncing after the next movement.
|
||||
setMovetype(movement_type & ~FLOATING) // If we were without gravity, the bouncing animation got stopped, so we make sure we restart the bouncing after the next movement.
|
||||
|
||||
@@ -32,4 +32,7 @@
|
||||
if(drag_slowdown && L.lying && !L.buckled && grab_state < GRAB_AGGRESSIVE)
|
||||
add_movespeed_modifier(MOVESPEED_ID_PRONE_DRAGGING, multiplicative_slowdown = PULL_PRONE_SLOWDOWN)
|
||||
return
|
||||
remove_movespeed_modifier(MOVESPEED_ID_PRONE_DRAGGING)
|
||||
remove_movespeed_modifier(MOVESPEED_ID_PRONE_DRAGGING)
|
||||
|
||||
/mob/living/canZMove(dir, turf/target)
|
||||
return can_zTravel(target, dir) && (movement_type & FLYING)
|
||||
@@ -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
|
||||
@@ -391,16 +391,16 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
|
||||
return 0
|
||||
|
||||
/mob/living/say_mod(input, message_mode)
|
||||
if(message_mode == MODE_WHISPER)
|
||||
. = verb_whisper
|
||||
else if(message_mode == MODE_WHISPER_CRIT)
|
||||
. = ..()
|
||||
if(message_mode == MODE_WHISPER_CRIT)
|
||||
. = "[verb_whisper] in [p_their()] last breath"
|
||||
else if(stuttering)
|
||||
. = "stammers"
|
||||
else if(derpspeech)
|
||||
. = "gibbers"
|
||||
else
|
||||
. = ..()
|
||||
else if(message_mode != MODE_CUSTOM_SAY)
|
||||
if(message_mode == MODE_WHISPER)
|
||||
. = verb_whisper
|
||||
else if(stuttering)
|
||||
. = "stammers"
|
||||
else if(derpspeech)
|
||||
. = "gibbers"
|
||||
|
||||
/mob/living/whisper(message, bubble_type, list/spans = list(), sanitize = TRUE, datum/language/language = null, ignore_spam = FALSE, forced = null)
|
||||
say("#[message]", bubble_type, spans, sanitize, language, ignore_spam, forced)
|
||||
|
||||
@@ -783,7 +783,7 @@
|
||||
/mob/living/silicon/ai/can_buckle()
|
||||
return 0
|
||||
|
||||
/mob/living/silicon/ai/incapacitated()
|
||||
/mob/living/silicon/ai/incapacitated(ignore_restraints, ignore_grab)
|
||||
if(aiRestorePowerRoutine)
|
||||
return TRUE
|
||||
return ..()
|
||||
@@ -882,6 +882,7 @@
|
||||
/mob/living/silicon/ai/revive(full_heal = 0, admin_revive = 0)
|
||||
. = ..()
|
||||
if(.) //successfully ressuscitated from death
|
||||
set_eyeobj_visible(TRUE)
|
||||
set_core_display_icon(display_icon_override)
|
||||
|
||||
/mob/living/silicon/ai/proc/malfhacked(obj/machinery/power/apc/apc)
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
update_canmove()
|
||||
if(eyeobj)
|
||||
eyeobj.setLoc(get_turf(src))
|
||||
set_eyeobj_visible(FALSE)
|
||||
|
||||
GLOB.shuttle_caller_list -= src
|
||||
SSshuttle.autoEvac()
|
||||
@@ -36,6 +37,8 @@
|
||||
|
||||
if(istype(loc, /obj/item/aicard/aitater))
|
||||
loc.icon_state = "aitater-404"
|
||||
else if(istype(loc, /obj/item/aicard/aispook))
|
||||
loc.icon_state = "aispook-404"
|
||||
else if(istype(loc, /obj/item/aicard))
|
||||
loc.icon_state = "aicard-404"
|
||||
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
/mob/camera/aiEye
|
||||
name = "Inactive AI Eye"
|
||||
|
||||
icon_state = "ai_camera"
|
||||
icon = 'icons/mob/cameramob.dmi'
|
||||
invisibility = INVISIBILITY_MAXIMUM
|
||||
hud_possible = list(ANTAG_HUD, AI_DETECT_HUD = HUD_LIST_LIST)
|
||||
var/list/visibleCameraChunks = list()
|
||||
@@ -158,11 +160,11 @@
|
||||
cameraFollow = null
|
||||
unset_machine()
|
||||
|
||||
if(!eyeobj || !eyeobj.loc || QDELETED(eyeobj))
|
||||
if(isturf(loc) && (QDELETED(eyeobj) || !eyeobj.loc))
|
||||
to_chat(src, "ERROR: Eyeobj not found. Creating new eye...")
|
||||
create_eye()
|
||||
|
||||
eyeobj.setLoc(loc)
|
||||
eyeobj?.setLoc(loc)
|
||||
|
||||
/mob/living/silicon/ai/proc/create_eye()
|
||||
if(eyeobj)
|
||||
@@ -172,6 +174,13 @@
|
||||
eyeobj.ai = src
|
||||
eyeobj.setLoc(loc)
|
||||
eyeobj.name = "[name] (AI Eye)"
|
||||
set_eyeobj_visible(TRUE)
|
||||
|
||||
/mob/living/silicon/ai/proc/set_eyeobj_visible(state = TRUE)
|
||||
if(!eyeobj)
|
||||
return
|
||||
eyeobj.mouse_opacity = state ? MOUSE_OPACITY_ICON : initial(eyeobj.mouse_opacity)
|
||||
eyeobj.invisibility = state ? INVISIBILITY_OBSERVER : initial(eyeobj.invisibility)
|
||||
|
||||
/mob/living/silicon/ai/verb/toggle_acceleration()
|
||||
set category = "AI Commands"
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
// messenging the client
|
||||
malfhacked(malfhack)
|
||||
|
||||
if(!eyeobj || QDELETED(eyeobj) || !eyeobj.loc)
|
||||
if(isturf(loc) && (QDELETED(eyeobj) || !eyeobj.loc))
|
||||
view_core()
|
||||
|
||||
if(machine)
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
O.mode = 1
|
||||
O.emotion = "Neutral"
|
||||
O.update()
|
||||
set_eyeobj_visible(TRUE)
|
||||
if(multicam_on)
|
||||
end_multicam()
|
||||
view_core()
|
||||
|
||||
@@ -4,4 +4,5 @@
|
||||
var/obj/machinery/status_display/ai/O = each
|
||||
O.mode = 0
|
||||
O.update()
|
||||
set_eyeobj_visible(FALSE)
|
||||
view_core()
|
||||
|
||||
@@ -120,6 +120,9 @@ GLOBAL_DATUM(ai_camera_room_landmark, /obj/effect/landmark/ai_multicam_room)
|
||||
|
||||
/mob/camera/aiEye/pic_in_pic
|
||||
name = "Secondary AI Eye"
|
||||
invisibility = INVISIBILITY_OBSERVER
|
||||
mouse_opacity = MOUSE_OPACITY_ICON
|
||||
icon_state = "ai_pip_camera"
|
||||
var/obj/screen/movable/pic_in_pic/ai/screen
|
||||
var/list/cameras_telegraphed = list()
|
||||
var/telegraph_cameras = TRUE
|
||||
|
||||
@@ -49,7 +49,7 @@
|
||||
else
|
||||
padloc = "(UNKNOWN)"
|
||||
src.log_talk(message, LOG_SAY, tag="HOLOPAD in [padloc]")
|
||||
send_speech(message, 7, T, "robot", message_language = language)
|
||||
send_speech(message, 7, T, "robot", 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.")
|
||||
|
||||
@@ -975,4 +975,635 @@ GLOBAL_LIST_INIT(vox_sounds, list("abduction" = 'sound/vox_fem/abduction.ogg',
|
||||
"zombie" = 'sound/vox_fem/zombie.ogg',
|
||||
"zone" = 'sound/vox_fem/zone.ogg',
|
||||
"zulu" = 'sound/vox_fem/zulu.ogg'))
|
||||
|
||||
//for vim
|
||||
// :%s/\(\(.*\)\.ogg\)/"\2" = 'sound\/vox\/\1',/g
|
||||
GLOBAL_LIST_INIT(vox_sounds_male, list("," = 'sound/vox/_comma.ogg',
|
||||
"." = 'sound/vox/_period.ogg',
|
||||
"a" = 'sound/vox/a.ogg',
|
||||
"accelerating" = 'sound/vox/accelerating.ogg',
|
||||
"accelerator" = 'sound/vox/accelerator.ogg',
|
||||
"accepted" = 'sound/vox/accepted.ogg',
|
||||
"access" = 'sound/vox/access.ogg',
|
||||
"acknowledge" = 'sound/vox/acknowledge.ogg',
|
||||
"acknowledged" = 'sound/vox/acknowledged.ogg',
|
||||
"acquired" = 'sound/vox/acquired.ogg',
|
||||
"acquisition" = 'sound/vox/acquisition.ogg',
|
||||
"across" = 'sound/vox/across.ogg',
|
||||
"activate" = 'sound/vox/activate.ogg',
|
||||
"activated" = 'sound/vox/activated.ogg',
|
||||
"activity" = 'sound/vox/activity.ogg',
|
||||
"adios" = 'sound/vox/adios.ogg',
|
||||
"administration" = 'sound/vox/administration.ogg',
|
||||
"advanced" = 'sound/vox/advanced.ogg',
|
||||
"after" = 'sound/vox/after.ogg',
|
||||
"agent" = 'sound/vox/agent.ogg',
|
||||
"alarm" = 'sound/vox/alarm.ogg',
|
||||
"alert" = 'sound/vox/alert.ogg',
|
||||
"alien" = 'sound/vox/alien.ogg',
|
||||
"aligned" = 'sound/vox/aligned.ogg',
|
||||
"all" = 'sound/vox/all.ogg',
|
||||
"alpha" = 'sound/vox/alpha.ogg',
|
||||
"am" = 'sound/vox/am.ogg',
|
||||
"amigo" = 'sound/vox/amigo.ogg',
|
||||
"ammunition" = 'sound/vox/ammunition.ogg',
|
||||
"an" = 'sound/vox/an.ogg',
|
||||
"and" = 'sound/vox/and.ogg',
|
||||
"announcement" = 'sound/vox/announcement.ogg',
|
||||
"anomalous" = 'sound/vox/anomalous.ogg',
|
||||
"antenna" = 'sound/vox/antenna.ogg',
|
||||
"any" = 'sound/vox/any.ogg',
|
||||
"apprehend" = 'sound/vox/apprehend.ogg',
|
||||
"approach" = 'sound/vox/approach.ogg',
|
||||
"are" = 'sound/vox/are.ogg',
|
||||
"area" = 'sound/vox/area.ogg',
|
||||
"arm" = 'sound/vox/arm.ogg',
|
||||
"armed" = 'sound/vox/armed.ogg',
|
||||
"armor" = 'sound/vox/armor.ogg',
|
||||
"armory" = 'sound/vox/armory.ogg',
|
||||
"arrest" = 'sound/vox/arrest.ogg',
|
||||
"ass" = 'sound/vox/ass.ogg',
|
||||
"at" = 'sound/vox/at.ogg',
|
||||
"atomic" = 'sound/vox/atomic.ogg',
|
||||
"attention" = 'sound/vox/attention.ogg',
|
||||
"authorize" = 'sound/vox/authorize.ogg',
|
||||
"authorized" = 'sound/vox/authorized.ogg',
|
||||
"automatic" = 'sound/vox/automatic.ogg',
|
||||
"away" = 'sound/vox/away.ogg',
|
||||
"b" = 'sound/vox/b.ogg',
|
||||
"back" = 'sound/vox/back.ogg',
|
||||
"backman" = 'sound/vox/backman.ogg',
|
||||
"bad" = 'sound/vox/bad.ogg',
|
||||
"bag" = 'sound/vox/bag.ogg',
|
||||
"bailey" = 'sound/vox/bailey.ogg',
|
||||
"barracks" = 'sound/vox/barracks.ogg',
|
||||
"base" = 'sound/vox/base.ogg',
|
||||
"bay" = 'sound/vox/bay.ogg',
|
||||
"be" = 'sound/vox/be.ogg',
|
||||
"been" = 'sound/vox/been.ogg',
|
||||
"before" = 'sound/vox/before.ogg',
|
||||
"beyond" = 'sound/vox/beyond.ogg',
|
||||
"biohazard" = 'sound/vox/biohazard.ogg',
|
||||
"biological" = 'sound/vox/biological.ogg',
|
||||
"birdwell" = 'sound/vox/birdwell.ogg',
|
||||
"bizwarn" = 'sound/vox/bizwarn.ogg',
|
||||
"black" = 'sound/vox/black.ogg',
|
||||
"blast" = 'sound/vox/blast.ogg',
|
||||
"blocked" = 'sound/vox/blocked.ogg',
|
||||
"bloop" = 'sound/vox/bloop.ogg',
|
||||
"blue" = 'sound/vox/blue.ogg',
|
||||
"bottom" = 'sound/vox/bottom.ogg',
|
||||
"bravo" = 'sound/vox/bravo.ogg',
|
||||
"breach" = 'sound/vox/breach.ogg',
|
||||
"breached" = 'sound/vox/breached.ogg',
|
||||
"break" = 'sound/vox/break.ogg',
|
||||
"bridge" = 'sound/vox/bridge.ogg',
|
||||
"bust" = 'sound/vox/bust.ogg',
|
||||
"but" = 'sound/vox/but.ogg',
|
||||
"button" = 'sound/vox/button.ogg',
|
||||
"buzwarn" = 'sound/vox/buzwarn.ogg',
|
||||
"bypass" = 'sound/vox/bypass.ogg',
|
||||
"c" = 'sound/vox/c.ogg',
|
||||
"cable" = 'sound/vox/cable.ogg',
|
||||
"call" = 'sound/vox/call.ogg',
|
||||
"called" = 'sound/vox/called.ogg',
|
||||
"canal" = 'sound/vox/canal.ogg',
|
||||
"cap" = 'sound/vox/cap.ogg',
|
||||
"captain" = 'sound/vox/captain.ogg',
|
||||
"capture" = 'sound/vox/capture.ogg',
|
||||
"captured" = 'sound/vox/captured.ogg',
|
||||
"ceiling" = 'sound/vox/ceiling.ogg',
|
||||
"celsius" = 'sound/vox/celsius.ogg',
|
||||
"center" = 'sound/vox/center.ogg',
|
||||
"centi" = 'sound/vox/centi.ogg',
|
||||
"central" = 'sound/vox/central.ogg',
|
||||
"chamber" = 'sound/vox/chamber.ogg',
|
||||
"charlie" = 'sound/vox/charlie.ogg',
|
||||
"check" = 'sound/vox/check.ogg',
|
||||
"checkpoint" = 'sound/vox/checkpoint.ogg',
|
||||
"chemical" = 'sound/vox/chemical.ogg',
|
||||
"cleanup" = 'sound/vox/cleanup.ogg',
|
||||
"clear" = 'sound/vox/clear.ogg',
|
||||
"clearance" = 'sound/vox/clearance.ogg',
|
||||
"close" = 'sound/vox/close.ogg',
|
||||
"clown" = 'sound/vox/clown.ogg',
|
||||
"code" = 'sound/vox/code.ogg',
|
||||
"coded" = 'sound/vox/coded.ogg',
|
||||
"collider" = 'sound/vox/collider.ogg',
|
||||
"command" = 'sound/vox/command.ogg',
|
||||
"communication" = 'sound/vox/communication.ogg',
|
||||
"complex" = 'sound/vox/complex.ogg',
|
||||
"computer" = 'sound/vox/computer.ogg',
|
||||
"condition" = 'sound/vox/condition.ogg',
|
||||
"containment" = 'sound/vox/containment.ogg',
|
||||
"contamination" = 'sound/vox/contamination.ogg',
|
||||
"control" = 'sound/vox/control.ogg',
|
||||
"coolant" = 'sound/vox/coolant.ogg',
|
||||
"coomer" = 'sound/vox/coomer.ogg',
|
||||
"core" = 'sound/vox/core.ogg',
|
||||
"correct" = 'sound/vox/correct.ogg',
|
||||
"corridor" = 'sound/vox/corridor.ogg',
|
||||
"crew" = 'sound/vox/crew.ogg',
|
||||
"cross" = 'sound/vox/cross.ogg',
|
||||
"cryogenic" = 'sound/vox/cryogenic.ogg',
|
||||
"d" = 'sound/vox/d.ogg',
|
||||
"dadeda" = 'sound/vox/dadeda.ogg',
|
||||
"damage" = 'sound/vox/damage.ogg',
|
||||
"damaged" = 'sound/vox/damaged.ogg',
|
||||
"danger" = 'sound/vox/danger.ogg',
|
||||
"day" = 'sound/vox/day.ogg',
|
||||
"deactivated" = 'sound/vox/deactivated.ogg',
|
||||
"decompression" = 'sound/vox/decompression.ogg',
|
||||
"decontamination" = 'sound/vox/decontamination.ogg',
|
||||
"deeoo" = 'sound/vox/deeoo.ogg',
|
||||
"defense" = 'sound/vox/defense.ogg',
|
||||
"degrees" = 'sound/vox/degrees.ogg',
|
||||
"delta" = 'sound/vox/delta.ogg',
|
||||
"denied" = 'sound/vox/denied.ogg',
|
||||
"deploy" = 'sound/vox/deploy.ogg',
|
||||
"deployed" = 'sound/vox/deployed.ogg',
|
||||
"destroy" = 'sound/vox/destroy.ogg',
|
||||
"destroyed" = 'sound/vox/destroyed.ogg',
|
||||
"detain" = 'sound/vox/detain.ogg',
|
||||
"detected" = 'sound/vox/detected.ogg',
|
||||
"detonation" = 'sound/vox/detonation.ogg',
|
||||
"device" = 'sound/vox/device.ogg',
|
||||
"did" = 'sound/vox/did.ogg',
|
||||
"die" = 'sound/vox/die.ogg',
|
||||
"dimensional" = 'sound/vox/dimensional.ogg',
|
||||
"dirt" = 'sound/vox/dirt.ogg',
|
||||
"disengaged" = 'sound/vox/disengaged.ogg',
|
||||
"dish" = 'sound/vox/dish.ogg',
|
||||
"disposal" = 'sound/vox/disposal.ogg',
|
||||
"distance" = 'sound/vox/distance.ogg',
|
||||
"distortion" = 'sound/vox/distortion.ogg',
|
||||
"do" = 'sound/vox/do.ogg',
|
||||
"doctor" = 'sound/vox/doctor.ogg',
|
||||
"doop" = 'sound/vox/doop.ogg',
|
||||
"door" = 'sound/vox/door.ogg',
|
||||
"down" = 'sound/vox/down.ogg',
|
||||
"dual" = 'sound/vox/dual.ogg',
|
||||
"duct" = 'sound/vox/duct.ogg',
|
||||
"e" = 'sound/vox/e.ogg',
|
||||
"east" = 'sound/vox/east.ogg',
|
||||
"echo" = 'sound/vox/echo.ogg',
|
||||
"ed" = 'sound/vox/ed.ogg',
|
||||
"effect" = 'sound/vox/effect.ogg',
|
||||
"egress" = 'sound/vox/egress.ogg',
|
||||
"eight" = 'sound/vox/eight.ogg',
|
||||
"eighteen" = 'sound/vox/eighteen.ogg',
|
||||
"eighty" = 'sound/vox/eighty.ogg',
|
||||
"electric" = 'sound/vox/electric.ogg',
|
||||
"electromagnetic" = 'sound/vox/electromagnetic.ogg',
|
||||
"elevator" = 'sound/vox/elevator.ogg',
|
||||
"eleven" = 'sound/vox/eleven.ogg',
|
||||
"eliminate" = 'sound/vox/eliminate.ogg',
|
||||
"emergency" = 'sound/vox/emergency.ogg',
|
||||
"enemy" = 'sound/vox/enemy.ogg',
|
||||
"energy" = 'sound/vox/energy.ogg',
|
||||
"engage" = 'sound/vox/engage.ogg',
|
||||
"engaged" = 'sound/vox/engaged.ogg',
|
||||
"engine" = 'sound/vox/engine.ogg',
|
||||
"enter" = 'sound/vox/enter.ogg',
|
||||
"entry" = 'sound/vox/entry.ogg',
|
||||
"environment" = 'sound/vox/environment.ogg',
|
||||
"error" = 'sound/vox/error.ogg',
|
||||
"escape" = 'sound/vox/escape.ogg',
|
||||
"evacuate" = 'sound/vox/evacuate.ogg',
|
||||
"exchange" = 'sound/vox/exchange.ogg',
|
||||
"exit" = 'sound/vox/exit.ogg',
|
||||
"expect" = 'sound/vox/expect.ogg',
|
||||
"experiment" = 'sound/vox/experiment.ogg',
|
||||
"experimental" = 'sound/vox/experimental.ogg',
|
||||
"explode" = 'sound/vox/explode.ogg',
|
||||
"explosion" = 'sound/vox/explosion.ogg',
|
||||
"exposure" = 'sound/vox/exposure.ogg',
|
||||
"exterminate" = 'sound/vox/exterminate.ogg',
|
||||
"extinguish" = 'sound/vox/extinguish.ogg',
|
||||
"extinguisher" = 'sound/vox/extinguisher.ogg',
|
||||
"extreme" = 'sound/vox/extreme.ogg',
|
||||
"f" = 'sound/vox/f.ogg',
|
||||
"face" = 'sound/vox/face.ogg',
|
||||
"facility" = 'sound/vox/facility.ogg',
|
||||
"fahrenheit" = 'sound/vox/fahrenheit.ogg',
|
||||
"failed" = 'sound/vox/failed.ogg',
|
||||
"failure" = 'sound/vox/failure.ogg',
|
||||
"farthest" = 'sound/vox/farthest.ogg',
|
||||
"fast" = 'sound/vox/fast.ogg',
|
||||
"feet" = 'sound/vox/feet.ogg',
|
||||
"field" = 'sound/vox/field.ogg',
|
||||
"fifteen" = 'sound/vox/fifteen.ogg',
|
||||
"fifth" = 'sound/vox/fifth.ogg',
|
||||
"fifty" = 'sound/vox/fifty.ogg',
|
||||
"final" = 'sound/vox/final.ogg',
|
||||
"fine" = 'sound/vox/fine.ogg',
|
||||
"fire" = 'sound/vox/fire.ogg',
|
||||
"first" = 'sound/vox/first.ogg',
|
||||
"five" = 'sound/vox/five.ogg',
|
||||
"flag" = 'sound/vox/flag.ogg',
|
||||
"flooding" = 'sound/vox/flooding.ogg',
|
||||
"floor" = 'sound/vox/floor.ogg',
|
||||
"fool" = 'sound/vox/fool.ogg',
|
||||
"for" = 'sound/vox/for.ogg',
|
||||
"forbidden" = 'sound/vox/forbidden.ogg',
|
||||
"force" = 'sound/vox/force.ogg',
|
||||
"forms" = 'sound/vox/forms.ogg',
|
||||
"found" = 'sound/vox/found.ogg',
|
||||
"four" = 'sound/vox/four.ogg',
|
||||
"fourteen" = 'sound/vox/fourteen.ogg',
|
||||
"fourth" = 'sound/vox/fourth.ogg',
|
||||
"fourty" = 'sound/vox/fourty.ogg',
|
||||
"foxtrot" = 'sound/vox/foxtrot.ogg',
|
||||
"freeman" = 'sound/vox/freeman.ogg',
|
||||
"freezer" = 'sound/vox/freezer.ogg',
|
||||
"from" = 'sound/vox/from.ogg',
|
||||
"front" = 'sound/vox/front.ogg',
|
||||
"fuel" = 'sound/vox/fuel.ogg',
|
||||
"g" = 'sound/vox/g.ogg',
|
||||
"gay" = 'sound/vox/gay.ogg',
|
||||
"get" = 'sound/vox/get.ogg',
|
||||
"go" = 'sound/vox/go.ogg',
|
||||
"going" = 'sound/vox/going.ogg',
|
||||
"good" = 'sound/vox/good.ogg',
|
||||
"goodbye" = 'sound/vox/goodbye.ogg',
|
||||
"gordon" = 'sound/vox/gordon.ogg',
|
||||
"got" = 'sound/vox/got.ogg',
|
||||
"government" = 'sound/vox/government.ogg',
|
||||
"granted" = 'sound/vox/granted.ogg',
|
||||
"great" = 'sound/vox/great.ogg',
|
||||
"green" = 'sound/vox/green.ogg',
|
||||
"grenade" = 'sound/vox/grenade.ogg',
|
||||
"guard" = 'sound/vox/guard.ogg',
|
||||
"gulf" = 'sound/vox/gulf.ogg',
|
||||
"gun" = 'sound/vox/gun.ogg',
|
||||
"guthrie" = 'sound/vox/guthrie.ogg',
|
||||
"handling" = 'sound/vox/handling.ogg',
|
||||
"hangar" = 'sound/vox/hangar.ogg',
|
||||
"has" = 'sound/vox/has.ogg',
|
||||
"have" = 'sound/vox/have.ogg',
|
||||
"hazard" = 'sound/vox/hazard.ogg',
|
||||
"head" = 'sound/vox/head.ogg',
|
||||
"health" = 'sound/vox/health.ogg',
|
||||
"heat" = 'sound/vox/heat.ogg',
|
||||
"helicopter" = 'sound/vox/helicopter.ogg',
|
||||
"helium" = 'sound/vox/helium.ogg',
|
||||
"hello" = 'sound/vox/hello.ogg',
|
||||
"help" = 'sound/vox/help.ogg',
|
||||
"here" = 'sound/vox/here.ogg',
|
||||
"hide" = 'sound/vox/hide.ogg',
|
||||
"high" = 'sound/vox/high.ogg',
|
||||
"highest" = 'sound/vox/highest.ogg',
|
||||
"hit" = 'sound/vox/hit.ogg',
|
||||
"holds" = 'sound/vox/holds.ogg',
|
||||
"hole" = 'sound/vox/hole.ogg',
|
||||
"hostile" = 'sound/vox/hostile.ogg',
|
||||
"hot" = 'sound/vox/hot.ogg',
|
||||
"hotel" = 'sound/vox/hotel.ogg',
|
||||
"hour" = 'sound/vox/hour.ogg',
|
||||
"hours" = 'sound/vox/hours.ogg',
|
||||
"hundred" = 'sound/vox/hundred.ogg',
|
||||
"hydro" = 'sound/vox/hydro.ogg',
|
||||
"i" = 'sound/vox/i.ogg',
|
||||
"idiot" = 'sound/vox/idiot.ogg',
|
||||
"illegal" = 'sound/vox/illegal.ogg',
|
||||
"immediate" = 'sound/vox/immediate.ogg',
|
||||
"immediately" = 'sound/vox/immediately.ogg',
|
||||
"in" = 'sound/vox/in.ogg',
|
||||
"inches" = 'sound/vox/inches.ogg',
|
||||
"india" = 'sound/vox/india.ogg',
|
||||
"ing" = 'sound/vox/ing.ogg',
|
||||
"inoperative" = 'sound/vox/inoperative.ogg',
|
||||
"inside" = 'sound/vox/inside.ogg',
|
||||
"inspection" = 'sound/vox/inspection.ogg',
|
||||
"inspector" = 'sound/vox/inspector.ogg',
|
||||
"interchange" = 'sound/vox/interchange.ogg',
|
||||
"intruder" = 'sound/vox/intruder.ogg',
|
||||
"invallid" = 'sound/vox/invallid.ogg',
|
||||
"invasion" = 'sound/vox/invasion.ogg',
|
||||
"is" = 'sound/vox/is.ogg',
|
||||
"it" = 'sound/vox/it.ogg',
|
||||
"johnson" = 'sound/vox/johnson.ogg',
|
||||
"juliet" = 'sound/vox/juliet.ogg',
|
||||
"key" = 'sound/vox/key.ogg',
|
||||
"kill" = 'sound/vox/kill.ogg',
|
||||
"kilo" = 'sound/vox/kilo.ogg',
|
||||
"kit" = 'sound/vox/kit.ogg',
|
||||
"lab" = 'sound/vox/lab.ogg',
|
||||
"lambda" = 'sound/vox/lambda.ogg',
|
||||
"laser" = 'sound/vox/laser.ogg',
|
||||
"last" = 'sound/vox/last.ogg',
|
||||
"launch" = 'sound/vox/launch.ogg',
|
||||
"leak" = 'sound/vox/leak.ogg',
|
||||
"leave" = 'sound/vox/leave.ogg',
|
||||
"left" = 'sound/vox/left.ogg',
|
||||
"legal" = 'sound/vox/legal.ogg',
|
||||
"level" = 'sound/vox/level.ogg',
|
||||
"lever" = 'sound/vox/lever.ogg',
|
||||
"lie" = 'sound/vox/lie.ogg',
|
||||
"lieutenant" = 'sound/vox/lieutenant.ogg',
|
||||
"life" = 'sound/vox/life.ogg',
|
||||
"light" = 'sound/vox/light.ogg',
|
||||
"lima" = 'sound/vox/lima.ogg',
|
||||
"liquid" = 'sound/vox/liquid.ogg',
|
||||
"loading" = 'sound/vox/loading.ogg',
|
||||
"locate" = 'sound/vox/locate.ogg',
|
||||
"located" = 'sound/vox/located.ogg',
|
||||
"location" = 'sound/vox/location.ogg',
|
||||
"lock" = 'sound/vox/lock.ogg',
|
||||
"locked" = 'sound/vox/locked.ogg',
|
||||
"locker" = 'sound/vox/locker.ogg',
|
||||
"lockout" = 'sound/vox/lockout.ogg',
|
||||
"lower" = 'sound/vox/lower.ogg',
|
||||
"lowest" = 'sound/vox/lowest.ogg',
|
||||
"magnetic" = 'sound/vox/magnetic.ogg',
|
||||
"main" = 'sound/vox/main.ogg',
|
||||
"maintenance" = 'sound/vox/maintenance.ogg',
|
||||
"malfunction" = 'sound/vox/malfunction.ogg',
|
||||
"man" = 'sound/vox/man.ogg',
|
||||
"mass" = 'sound/vox/mass.ogg',
|
||||
"materials" = 'sound/vox/materials.ogg',
|
||||
"maximum" = 'sound/vox/maximum.ogg',
|
||||
"may" = 'sound/vox/may.ogg',
|
||||
"med" = 'sound/vox/med.ogg',
|
||||
"medical" = 'sound/vox/medical.ogg',
|
||||
"men" = 'sound/vox/men.ogg',
|
||||
"mercy" = 'sound/vox/mercy.ogg',
|
||||
"mesa" = 'sound/vox/mesa.ogg',
|
||||
"message" = 'sound/vox/message.ogg',
|
||||
"meter" = 'sound/vox/meter.ogg',
|
||||
"micro" = 'sound/vox/micro.ogg',
|
||||
"middle" = 'sound/vox/middle.ogg',
|
||||
"mike" = 'sound/vox/mike.ogg',
|
||||
"miles" = 'sound/vox/miles.ogg',
|
||||
"military" = 'sound/vox/military.ogg',
|
||||
"milli" = 'sound/vox/milli.ogg',
|
||||
"million" = 'sound/vox/million.ogg',
|
||||
"minefield" = 'sound/vox/minefield.ogg',
|
||||
"minimum" = 'sound/vox/minimum.ogg',
|
||||
"minutes" = 'sound/vox/minutes.ogg',
|
||||
"mister" = 'sound/vox/mister.ogg',
|
||||
"mode" = 'sound/vox/mode.ogg',
|
||||
"motor" = 'sound/vox/motor.ogg',
|
||||
"motorpool" = 'sound/vox/motorpool.ogg',
|
||||
"move" = 'sound/vox/move.ogg',
|
||||
"must" = 'sound/vox/must.ogg',
|
||||
"nearest" = 'sound/vox/nearest.ogg',
|
||||
"nice" = 'sound/vox/nice.ogg',
|
||||
"nine" = 'sound/vox/nine.ogg',
|
||||
"nineteen" = 'sound/vox/nineteen.ogg',
|
||||
"ninety" = 'sound/vox/ninety.ogg',
|
||||
"no" = 'sound/vox/no.ogg',
|
||||
"nominal" = 'sound/vox/nominal.ogg',
|
||||
"north" = 'sound/vox/north.ogg',
|
||||
"not" = 'sound/vox/not.ogg',
|
||||
"november" = 'sound/vox/november.ogg',
|
||||
"now" = 'sound/vox/now.ogg',
|
||||
"number" = 'sound/vox/number.ogg',
|
||||
"objective" = 'sound/vox/objective.ogg',
|
||||
"observation" = 'sound/vox/observation.ogg',
|
||||
"of" = 'sound/vox/of.ogg',
|
||||
"officer" = 'sound/vox/officer.ogg',
|
||||
"ok" = 'sound/vox/ok.ogg',
|
||||
"on" = 'sound/vox/on.ogg',
|
||||
"one" = 'sound/vox/one.ogg',
|
||||
"open" = 'sound/vox/open.ogg',
|
||||
"operating" = 'sound/vox/operating.ogg',
|
||||
"operations" = 'sound/vox/operations.ogg',
|
||||
"operative" = 'sound/vox/operative.ogg',
|
||||
"option" = 'sound/vox/option.ogg',
|
||||
"order" = 'sound/vox/order.ogg',
|
||||
"organic" = 'sound/vox/organic.ogg',
|
||||
"oscar" = 'sound/vox/oscar.ogg',
|
||||
"out" = 'sound/vox/out.ogg',
|
||||
"outside" = 'sound/vox/outside.ogg',
|
||||
"over" = 'sound/vox/over.ogg',
|
||||
"overload" = 'sound/vox/overload.ogg',
|
||||
"override" = 'sound/vox/override.ogg',
|
||||
"pacify" = 'sound/vox/pacify.ogg',
|
||||
"pain" = 'sound/vox/pain.ogg',
|
||||
"pal" = 'sound/vox/pal.ogg',
|
||||
"panel" = 'sound/vox/panel.ogg',
|
||||
"percent" = 'sound/vox/percent.ogg',
|
||||
"perimeter" = 'sound/vox/perimeter.ogg',
|
||||
"permitted" = 'sound/vox/permitted.ogg',
|
||||
"personnel" = 'sound/vox/personnel.ogg',
|
||||
"pipe" = 'sound/vox/pipe.ogg',
|
||||
"plant" = 'sound/vox/plant.ogg',
|
||||
"platform" = 'sound/vox/platform.ogg',
|
||||
"please" = 'sound/vox/please.ogg',
|
||||
"point" = 'sound/vox/point.ogg',
|
||||
"portal" = 'sound/vox/portal.ogg',
|
||||
"power" = 'sound/vox/power.ogg',
|
||||
"presence" = 'sound/vox/presence.ogg',
|
||||
"press" = 'sound/vox/press.ogg',
|
||||
"primary" = 'sound/vox/primary.ogg',
|
||||
"proceed" = 'sound/vox/proceed.ogg',
|
||||
"processing" = 'sound/vox/processing.ogg',
|
||||
"progress" = 'sound/vox/progress.ogg',
|
||||
"proper" = 'sound/vox/proper.ogg',
|
||||
"propulsion" = 'sound/vox/propulsion.ogg',
|
||||
"prosecute" = 'sound/vox/prosecute.ogg',
|
||||
"protective" = 'sound/vox/protective.ogg',
|
||||
"push" = 'sound/vox/push.ogg',
|
||||
"quantum" = 'sound/vox/quantum.ogg',
|
||||
"quebec" = 'sound/vox/quebec.ogg',
|
||||
"question" = 'sound/vox/question.ogg',
|
||||
"questioning" = 'sound/vox/questioning.ogg',
|
||||
"quick" = 'sound/vox/quick.ogg',
|
||||
"quit" = 'sound/vox/quit.ogg',
|
||||
"radiation" = 'sound/vox/radiation.ogg',
|
||||
"radioactive" = 'sound/vox/radioactive.ogg',
|
||||
"rads" = 'sound/vox/rads.ogg',
|
||||
"rapid" = 'sound/vox/rapid.ogg',
|
||||
"reach" = 'sound/vox/reach.ogg',
|
||||
"reached" = 'sound/vox/reached.ogg',
|
||||
"reactor" = 'sound/vox/reactor.ogg',
|
||||
"red" = 'sound/vox/red.ogg',
|
||||
"relay" = 'sound/vox/relay.ogg',
|
||||
"released" = 'sound/vox/released.ogg',
|
||||
"remaining" = 'sound/vox/remaining.ogg',
|
||||
"renegade" = 'sound/vox/renegade.ogg',
|
||||
"repair" = 'sound/vox/repair.ogg',
|
||||
"report" = 'sound/vox/report.ogg',
|
||||
"reports" = 'sound/vox/reports.ogg',
|
||||
"required" = 'sound/vox/required.ogg',
|
||||
"research" = 'sound/vox/research.ogg',
|
||||
"reset" = 'sound/vox/reset.ogg',
|
||||
"resevoir" = 'sound/vox/resevoir.ogg',
|
||||
"resistance" = 'sound/vox/resistance.ogg',
|
||||
"returned" = 'sound/vox/returned.ogg',
|
||||
"right" = 'sound/vox/right.ogg',
|
||||
"rocket" = 'sound/vox/rocket.ogg',
|
||||
"roger" = 'sound/vox/roger.ogg',
|
||||
"romeo" = 'sound/vox/romeo.ogg',
|
||||
"room" = 'sound/vox/room.ogg',
|
||||
"round" = 'sound/vox/round.ogg',
|
||||
"run" = 'sound/vox/run.ogg',
|
||||
"safe" = 'sound/vox/safe.ogg',
|
||||
"safety" = 'sound/vox/safety.ogg',
|
||||
"sargeant" = 'sound/vox/sargeant.ogg',
|
||||
"satellite" = 'sound/vox/satellite.ogg',
|
||||
"save" = 'sound/vox/save.ogg',
|
||||
"science" = 'sound/vox/science.ogg',
|
||||
"scores" = 'sound/vox/scores.ogg',
|
||||
"scream" = 'sound/vox/scream.ogg',
|
||||
"screen" = 'sound/vox/screen.ogg',
|
||||
"search" = 'sound/vox/search.ogg',
|
||||
"second" = 'sound/vox/second.ogg',
|
||||
"secondary" = 'sound/vox/secondary.ogg',
|
||||
"seconds" = 'sound/vox/seconds.ogg',
|
||||
"sector" = 'sound/vox/sector.ogg',
|
||||
"secure" = 'sound/vox/secure.ogg',
|
||||
"secured" = 'sound/vox/secured.ogg',
|
||||
"security" = 'sound/vox/security.ogg',
|
||||
"select" = 'sound/vox/select.ogg',
|
||||
"selected" = 'sound/vox/selected.ogg',
|
||||
"service" = 'sound/vox/service.ogg',
|
||||
"seven" = 'sound/vox/seven.ogg',
|
||||
"seventeen" = 'sound/vox/seventeen.ogg',
|
||||
"seventy" = 'sound/vox/seventy.ogg',
|
||||
"severe" = 'sound/vox/severe.ogg',
|
||||
"sewage" = 'sound/vox/sewage.ogg',
|
||||
"sewer" = 'sound/vox/sewer.ogg',
|
||||
"shield" = 'sound/vox/shield.ogg',
|
||||
"shipment" = 'sound/vox/shipment.ogg',
|
||||
"shock" = 'sound/vox/shock.ogg',
|
||||
"shoot" = 'sound/vox/shoot.ogg',
|
||||
"shower" = 'sound/vox/shower.ogg',
|
||||
"shut" = 'sound/vox/shut.ogg',
|
||||
"side" = 'sound/vox/side.ogg',
|
||||
"sierra" = 'sound/vox/sierra.ogg',
|
||||
"sight" = 'sound/vox/sight.ogg',
|
||||
"silo" = 'sound/vox/silo.ogg',
|
||||
"six" = 'sound/vox/six.ogg',
|
||||
"sixteen" = 'sound/vox/sixteen.ogg',
|
||||
"sixty" = 'sound/vox/sixty.ogg',
|
||||
"slime" = 'sound/vox/slime.ogg',
|
||||
"slow" = 'sound/vox/slow.ogg',
|
||||
"soldier" = 'sound/vox/soldier.ogg',
|
||||
"some" = 'sound/vox/some.ogg',
|
||||
"someone" = 'sound/vox/someone.ogg',
|
||||
"something" = 'sound/vox/something.ogg',
|
||||
"son" = 'sound/vox/son.ogg',
|
||||
"sorry" = 'sound/vox/sorry.ogg',
|
||||
"south" = 'sound/vox/south.ogg',
|
||||
"squad" = 'sound/vox/squad.ogg',
|
||||
"square" = 'sound/vox/square.ogg',
|
||||
"stairway" = 'sound/vox/stairway.ogg',
|
||||
"status" = 'sound/vox/status.ogg',
|
||||
"sterile" = 'sound/vox/sterile.ogg',
|
||||
"sterilization" = 'sound/vox/sterilization.ogg',
|
||||
"stolen" = 'sound/vox/stolen.ogg',
|
||||
"storage" = 'sound/vox/storage.ogg',
|
||||
"sub" = 'sound/vox/sub.ogg',
|
||||
"subsurface" = 'sound/vox/subsurface.ogg',
|
||||
"sudden" = 'sound/vox/sudden.ogg',
|
||||
"suit" = 'sound/vox/suit.ogg',
|
||||
"superconducting" = 'sound/vox/superconducting.ogg',
|
||||
"supercooled" = 'sound/vox/supercooled.ogg',
|
||||
"supply" = 'sound/vox/supply.ogg',
|
||||
"surface" = 'sound/vox/surface.ogg',
|
||||
"surrender" = 'sound/vox/surrender.ogg',
|
||||
"surround" = 'sound/vox/surround.ogg',
|
||||
"surrounded" = 'sound/vox/surrounded.ogg',
|
||||
"switch" = 'sound/vox/switch.ogg',
|
||||
"system" = 'sound/vox/system.ogg',
|
||||
"systems" = 'sound/vox/systems.ogg',
|
||||
"tactical" = 'sound/vox/tactical.ogg',
|
||||
"take" = 'sound/vox/take.ogg',
|
||||
"talk" = 'sound/vox/talk.ogg',
|
||||
"tango" = 'sound/vox/tango.ogg',
|
||||
"tank" = 'sound/vox/tank.ogg',
|
||||
"target" = 'sound/vox/target.ogg',
|
||||
"team" = 'sound/vox/team.ogg',
|
||||
"temperature" = 'sound/vox/temperature.ogg',
|
||||
"temporal" = 'sound/vox/temporal.ogg',
|
||||
"ten" = 'sound/vox/ten.ogg',
|
||||
"terminal" = 'sound/vox/terminal.ogg',
|
||||
"terminated" = 'sound/vox/terminated.ogg',
|
||||
"termination" = 'sound/vox/termination.ogg',
|
||||
"test" = 'sound/vox/test.ogg',
|
||||
"that" = 'sound/vox/that.ogg',
|
||||
"the" = 'sound/vox/the.ogg',
|
||||
"then" = 'sound/vox/then.ogg',
|
||||
"there" = 'sound/vox/there.ogg',
|
||||
"third" = 'sound/vox/third.ogg',
|
||||
"thirteen" = 'sound/vox/thirteen.ogg',
|
||||
"thirty" = 'sound/vox/thirty.ogg',
|
||||
"this" = 'sound/vox/this.ogg',
|
||||
"those" = 'sound/vox/those.ogg',
|
||||
"thousand" = 'sound/vox/thousand.ogg',
|
||||
"threat" = 'sound/vox/threat.ogg',
|
||||
"three" = 'sound/vox/three.ogg',
|
||||
"through" = 'sound/vox/through.ogg',
|
||||
"time" = 'sound/vox/time.ogg',
|
||||
"to" = 'sound/vox/to.ogg',
|
||||
"top" = 'sound/vox/top.ogg',
|
||||
"topside" = 'sound/vox/topside.ogg',
|
||||
"touch" = 'sound/vox/touch.ogg',
|
||||
"towards" = 'sound/vox/towards.ogg',
|
||||
"track" = 'sound/vox/track.ogg',
|
||||
"train" = 'sound/vox/train.ogg',
|
||||
"transportation" = 'sound/vox/transportation.ogg',
|
||||
"truck" = 'sound/vox/truck.ogg',
|
||||
"tunnel" = 'sound/vox/tunnel.ogg',
|
||||
"turn" = 'sound/vox/turn.ogg',
|
||||
"turret" = 'sound/vox/turret.ogg',
|
||||
"twelve" = 'sound/vox/twelve.ogg',
|
||||
"twenty" = 'sound/vox/twenty.ogg',
|
||||
"two" = 'sound/vox/two.ogg',
|
||||
"unauthorized" = 'sound/vox/unauthorized.ogg',
|
||||
"under" = 'sound/vox/under.ogg',
|
||||
"uniform" = 'sound/vox/uniform.ogg',
|
||||
"unlocked" = 'sound/vox/unlocked.ogg',
|
||||
"until" = 'sound/vox/until.ogg',
|
||||
"up" = 'sound/vox/up.ogg',
|
||||
"upper" = 'sound/vox/upper.ogg',
|
||||
"uranium" = 'sound/vox/uranium.ogg',
|
||||
"us" = 'sound/vox/us.ogg',
|
||||
"usa" = 'sound/vox/usa.ogg',
|
||||
"use" = 'sound/vox/use.ogg',
|
||||
"used" = 'sound/vox/used.ogg',
|
||||
"user" = 'sound/vox/user.ogg',
|
||||
"vacate" = 'sound/vox/vacate.ogg',
|
||||
"valid" = 'sound/vox/valid.ogg',
|
||||
"vapor" = 'sound/vox/vapor.ogg',
|
||||
"vent" = 'sound/vox/vent.ogg',
|
||||
"ventillation" = 'sound/vox/ventillation.ogg',
|
||||
"victor" = 'sound/vox/victor.ogg',
|
||||
"violated" = 'sound/vox/violated.ogg',
|
||||
"violation" = 'sound/vox/violation.ogg',
|
||||
"voltage" = 'sound/vox/voltage.ogg',
|
||||
"vox_login" = 'sound/vox/vox_login.ogg',
|
||||
"walk" = 'sound/vox/walk.ogg',
|
||||
"wall" = 'sound/vox/wall.ogg',
|
||||
"want" = 'sound/vox/want.ogg',
|
||||
"wanted" = 'sound/vox/wanted.ogg',
|
||||
"warm" = 'sound/vox/warm.ogg',
|
||||
"warn" = 'sound/vox/warn.ogg',
|
||||
"warning" = 'sound/vox/warning.ogg',
|
||||
"waste" = 'sound/vox/waste.ogg',
|
||||
"water" = 'sound/vox/water.ogg',
|
||||
"we" = 'sound/vox/we.ogg',
|
||||
"weapon" = 'sound/vox/weapon.ogg',
|
||||
"west" = 'sound/vox/west.ogg',
|
||||
"whiskey" = 'sound/vox/whiskey.ogg',
|
||||
"white" = 'sound/vox/white.ogg',
|
||||
"wilco" = 'sound/vox/wilco.ogg',
|
||||
"will" = 'sound/vox/will.ogg',
|
||||
"with" = 'sound/vox/with.ogg',
|
||||
"without" = 'sound/vox/without.ogg',
|
||||
"woop" = 'sound/vox/woop.ogg',
|
||||
"xeno" = 'sound/vox/xeno.ogg',
|
||||
"yankee" = 'sound/vox/yankee.ogg',
|
||||
"yards" = 'sound/vox/yards.ogg',
|
||||
"year" = 'sound/vox/year.ogg',
|
||||
"yellow" = 'sound/vox/yellow.ogg',
|
||||
"yes" = 'sound/vox/yes.ogg',
|
||||
"you" = 'sound/vox/you.ogg',
|
||||
"your" = 'sound/vox/your.ogg',
|
||||
"yourself" = 'sound/vox/yourself.ogg',
|
||||
"zero" = 'sound/vox/zero.ogg',
|
||||
"zone" = 'sound/vox/zone.ogg',
|
||||
"zulu" = 'sound/vox/zulu.ogg',))
|
||||
#endif
|
||||
@@ -1,16 +1,17 @@
|
||||
|
||||
/mob/living/silicon/apply_damage(damage = 0,damagetype = BRUTE, def_zone = null, blocked = FALSE)
|
||||
/mob/living/silicon/apply_damage(damage = 0,damagetype = BRUTE, def_zone = null, blocked = FALSE, forced = FALSE)
|
||||
var/hit_percent = (100-blocked)/100
|
||||
if(!damage || (hit_percent <= 0))
|
||||
if(!damage || (!forced && hit_percent <= 0))
|
||||
return 0
|
||||
var/damage_amount = forced ? damage : damage * hit_percent
|
||||
switch(damagetype)
|
||||
if(BRUTE)
|
||||
adjustBruteLoss(damage * hit_percent)
|
||||
adjustBruteLoss(damage_amount, forced = forced)
|
||||
if(BURN)
|
||||
adjustFireLoss(damage * hit_percent)
|
||||
adjustFireLoss(damage_amount, forced = forced)
|
||||
if(OXY)
|
||||
if(damage < 0) //we shouldn't be taking oxygen damage through this proc, but we'll let it heal.
|
||||
adjustOxyLoss(damage * hit_percent)
|
||||
if(damage < 0 || forced) //we shouldn't be taking oxygen damage through this proc, but we'll let it heal.
|
||||
adjustOxyLoss(damage_amount, forced = forced)
|
||||
return 1
|
||||
|
||||
|
||||
@@ -29,14 +30,14 @@
|
||||
/mob/living/silicon/setCloneLoss(amount, updating_health = TRUE, forced = FALSE)
|
||||
return FALSE
|
||||
|
||||
/mob/living/silicon/adjustStaminaLoss(amount, updating_stamina = 1)//immune to stamina damage.
|
||||
/mob/living/silicon/adjustStaminaLoss(amount, updating_stamina = 1, forced = FALSE)//immune to stamina damage.
|
||||
return FALSE
|
||||
|
||||
/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,5 +1,5 @@
|
||||
/mob/living/silicon/spawn_gibs()
|
||||
new /obj/effect/gibspawner/robot(drop_location())
|
||||
/mob/living/silicon/spawn_gibs(with_bodyparts, atom/loc_override)
|
||||
new /obj/effect/gibspawner/robot(loc_override ? loc_override.drop_location() : drop_location(), src)
|
||||
|
||||
/mob/living/silicon/spawn_dust()
|
||||
new /obj/effect/decal/remains/robot(loc)
|
||||
|
||||
@@ -58,7 +58,10 @@
|
||||
var/canholo = TRUE
|
||||
var/obj/item/card/id/access_card = null
|
||||
var/chassis = "repairbot"
|
||||
var/list/possible_chassis = list("cat" = TRUE, "mouse" = TRUE, "monkey" = TRUE, "corgi" = FALSE, "fox" = FALSE, "repairbot" = TRUE, "rabbit" = TRUE) //assoc value is whether it can be picked up.
|
||||
var/list/possible_chassis = list("cat" = TRUE, "mouse" = TRUE, "monkey" = TRUE, "corgi" = FALSE,
|
||||
"fox" = FALSE, "repairbot" = TRUE, "rabbit" = TRUE, "borgi" = FALSE ,
|
||||
"parrot" = FALSE, "bear" = FALSE , "mushroom" = FALSE, "crow" = FALSE ,
|
||||
"fairy" = FALSE , "spiderbot" = FALSE) //assoc value is whether it can be picked up.
|
||||
var/static/item_head_icon = 'icons/mob/pai_item_head.dmi'
|
||||
var/static/item_lh_icon = 'icons/mob/pai_item_lh.dmi'
|
||||
var/static/item_rh_icon = 'icons/mob/pai_item_rh.dmi'
|
||||
@@ -192,7 +195,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)
|
||||
|
||||
@@ -81,10 +81,13 @@
|
||||
/mob/living/silicon/pai/adjustCloneLoss(amount, updating_health = TRUE, forced = FALSE)
|
||||
return FALSE
|
||||
|
||||
/mob/living/silicon/pai/adjustStaminaLoss(amount)
|
||||
take_holo_damage(amount & 0.25)
|
||||
/mob/living/silicon/pai/adjustStaminaLoss(amount, updating_health, forced = FALSE)
|
||||
if(forced)
|
||||
take_holo_damage(amount)
|
||||
else
|
||||
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 +105,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
|
||||
|
||||
|
||||
@@ -140,7 +140,7 @@
|
||||
radio.attack_self(src)
|
||||
|
||||
if("image")
|
||||
var/newImage = input("Select your new display image.", "Display Image", "Happy") in list("Happy", "Cat", "Extremely Happy", "Face", "Laugh", "Off", "Sad", "Angry", "What" , "Exclamation" ,"Question") // CITADEL EDIT
|
||||
var/newImage = input("Select your new display image.", "Display Image", "Happy") in list("Happy", "Cat", "Extremely Happy", "Face", "Laugh", "Off", "Sad", "Angry", "What" , "Exclamation" ,"Question", "Sunglasses")
|
||||
var/pID = 1
|
||||
|
||||
switch(newImage)
|
||||
@@ -164,10 +164,12 @@
|
||||
pID = 9
|
||||
if("Null")
|
||||
pID = 10
|
||||
if("Exclamation") // CITADEL EDIT
|
||||
if("Exclamation")
|
||||
pID = 11
|
||||
if("Question") // CITADEL EDIT
|
||||
if("Question")
|
||||
pID = 12
|
||||
if("Sunglasses")
|
||||
pID = 13
|
||||
card.setEmotion(pID)
|
||||
|
||||
if("signaller")
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/mob/living/silicon/robot/examine(mob/user)
|
||||
var/msg = "<span class='info'>*---------*\nThis is [icon2html(src, user)] \a <EM>[src]</EM>, a [src.module.name]!\n"
|
||||
var/msg = "<span class='info'>*---------*\nThis is [icon2html(src, user)] \a <EM>[src]</EM>, a [src.module.name] unit!\n"
|
||||
if(desc)
|
||||
msg += "[desc]\n"
|
||||
|
||||
|
||||
@@ -110,6 +110,7 @@
|
||||
|
||||
var/sitting = 0
|
||||
var/bellyup = 0
|
||||
var/dogborg = FALSE
|
||||
|
||||
/mob/living/silicon/robot/get_cell()
|
||||
return cell
|
||||
@@ -226,18 +227,20 @@
|
||||
to_chat(src,"<span class='userdanger'>ERROR: Module installer reply timeout. Please check internal connections.</span>")
|
||||
return
|
||||
|
||||
if(!CONFIG_GET(flag/disable_secborg) && GLOB.security_level < CONFIG_GET(number/minimum_secborg_alert))
|
||||
to_chat(src, "<span class='notice'>NOTICE: Due to local station regulations, the security cyborg module and its variants are only available during [num2seclevel(CONFIG_GET(number/minimum_secborg_alert))] alert and greater.</span>")
|
||||
|
||||
var/list/modulelist = list("Standard" = /obj/item/robot_module/standard, \
|
||||
"Engineering" = /obj/item/robot_module/engineering, \
|
||||
"Medical" = /obj/item/robot_module/medical, \
|
||||
"Medihound" = /obj/item/robot_module/medihound, \
|
||||
"Miner" = /obj/item/robot_module/miner, \
|
||||
"Janitor" = /obj/item/robot_module/janitor, \
|
||||
"Service" = /obj/item/robot_module/butler)
|
||||
if(!CONFIG_GET(flag/disable_peaceborg))
|
||||
modulelist["Peacekeeper"] = /obj/item/robot_module/peacekeeper
|
||||
if(!CONFIG_GET(flag/disable_secborg))
|
||||
if(BORG_SEC_AVAILABLE)
|
||||
modulelist["Security"] = /obj/item/robot_module/security
|
||||
|
||||
modulelist += get_cit_modules() //Citadel change - adds Citadel's borg modules.
|
||||
modulelist["Security K-9"] = /obj/item/robot_module/k9
|
||||
|
||||
var/input_module = input("Please, select a module!", "Robot", null, null) as null|anything in modulelist
|
||||
if(!input_module || module.type != /obj/item/robot_module)
|
||||
@@ -876,9 +879,6 @@
|
||||
/mob/living/silicon/robot/modules/miner
|
||||
set_module = /obj/item/robot_module/miner
|
||||
|
||||
/mob/living/silicon/robot/modules/janitor
|
||||
set_module = /obj/item/robot_module/janitor
|
||||
|
||||
/mob/living/silicon/robot/modules/syndicate
|
||||
icon_state = "synd_sec"
|
||||
faction = list(ROLE_SYNDICATE)
|
||||
@@ -917,6 +917,17 @@
|
||||
<i>Help the operatives secure the disk at all costs!</i></b>"
|
||||
set_module = /obj/item/robot_module/syndicate_medical
|
||||
|
||||
/mob/living/silicon/robot/modules/syndicate/saboteur
|
||||
icon_state = "synd_engi"
|
||||
playstyle_string = "<span class='big bold'>You are a Syndicate saboteur cyborg!</span><br>\
|
||||
<b>You are armed with robust engineering tools to aid you in your mission: help the operatives secure the nuclear authentication disk. \
|
||||
Your destination tagger will allow you to stealthily traverse the disposal network across the station \
|
||||
Your welder will allow you to repair the operatives' exosuits, but also yourself and your fellow cyborgs \
|
||||
Your cyborg chameleon projector allows you to assume the appearance and registered name of a Nanotrasen engineering borg, and undertake covert actions on the station \
|
||||
Be aware that almost any physical contact or incidental damage will break your camouflage \
|
||||
<i>Help the operatives secure the disk at all costs!</i></b>"
|
||||
set_module = /obj/item/robot_module/saboteur
|
||||
|
||||
/mob/living/silicon/robot/proc/notify_ai(notifytype, oldname, newname)
|
||||
if(!connected_ai)
|
||||
return
|
||||
@@ -1230,7 +1241,7 @@
|
||||
|
||||
/mob/living/silicon/robot/unbuckle_mob(mob/user, force=FALSE)
|
||||
if(iscarbon(user))
|
||||
GET_COMPONENT(riding_datum, /datum/component/riding)
|
||||
var/datum/component/riding/riding_datum = GetComponent(/datum/component/riding)
|
||||
if(istype(riding_datum))
|
||||
riding_datum.unequip_buckle_inhands(user)
|
||||
riding_datum.restore_position(user)
|
||||
@@ -1253,6 +1264,20 @@
|
||||
for(var/i in connected_ai.aicamera.stored)
|
||||
aicamera.stored[i] = TRUE
|
||||
|
||||
/mob/living/silicon/robot/lay_down()
|
||||
..()
|
||||
update_canmove()
|
||||
|
||||
/mob/living/silicon/robot/update_canmove()
|
||||
..()
|
||||
if(client && stat != DEAD && dogborg == FALSE)
|
||||
if(resting)
|
||||
cut_overlays()
|
||||
icon_state = "[module.cyborg_base_icon]-rest"
|
||||
else
|
||||
icon_state = "[module.cyborg_base_icon]"
|
||||
update_icons()
|
||||
|
||||
/mob/living/silicon/robot/proc/rest_style()
|
||||
set name = "Switch Rest Style"
|
||||
set category = "Robot Commands"
|
||||
@@ -1268,4 +1293,8 @@
|
||||
sitting = 1
|
||||
if("Belly up")
|
||||
bellyup = 1
|
||||
update_icons()
|
||||
update_icons()
|
||||
|
||||
/mob/living/silicon/robot/adjustStaminaLossBuffered(amount, updating_stamina = 1)
|
||||
if(istype(cell))
|
||||
cell.charge -= amount*5
|
||||
@@ -8,6 +8,8 @@
|
||||
righthand_file = 'icons/mob/inhands/misc/devices_righthand.dmi'
|
||||
flags_1 = CONDUCT_1
|
||||
|
||||
var/borghealth = 100
|
||||
|
||||
var/list/basic_modules = list() //a list of paths, converted to a list of instances on New()
|
||||
var/list/emag_modules = list() //ditto
|
||||
var/list/ratvar_modules = list() //ditto ditto
|
||||
@@ -32,6 +34,14 @@
|
||||
var/list/ride_offset_y = list("north" = 4, "south" = 4, "east" = 3, "west" = 3)
|
||||
var/ride_allow_incapacitated = FALSE
|
||||
var/allow_riding = TRUE
|
||||
var/canDispose = FALSE // Whether the borg can stuff itself into disposal
|
||||
|
||||
var/sleeper_overlay
|
||||
var/icon/cyborg_icon_override
|
||||
var/has_snowflake_deadsprite
|
||||
var/cyborg_pixel_offset
|
||||
var/moduleselect_alternate_icon
|
||||
var/dogborg = FALSE
|
||||
|
||||
/obj/item/robot_module/Initialize()
|
||||
. = ..()
|
||||
@@ -127,6 +137,28 @@
|
||||
rebuild_modules()
|
||||
return I
|
||||
|
||||
//Adds flavoursome dogborg items to dogborg variants without mechanical benefits
|
||||
/obj/item/robot_module/proc/dogborg_equip()
|
||||
if(istype(src, /obj/item/robot_module/k9) || istype(src, /obj/item/robot_module/medihound))
|
||||
return //Bandaid fix to prevent stacking until I merge these two modules into their base types
|
||||
var/obj/item/I = new /obj/item/analyzer/nose/flavour(src)
|
||||
basic_modules += I
|
||||
I = new /obj/item/soap/tongue/flavour(src)
|
||||
basic_modules += I
|
||||
I = new /obj/item/dogborg/sleeper/K9/flavour(src)
|
||||
if(istype(src, /obj/item/robot_module/engineering))
|
||||
I.icon_state = "decompiler"
|
||||
if(istype(src, /obj/item/robot_module/security))
|
||||
I.icon_state = "sleeperb"
|
||||
if(istype(src, /obj/item/robot_module/medical))
|
||||
I.icon_state = "sleeper"
|
||||
if(istype(src, /obj/item/robot_module/butler))
|
||||
I.icon_state = "servicer"
|
||||
if(cyborg_base_icon == "scrubpup")
|
||||
I.icon_state = "compactor"
|
||||
basic_modules += I
|
||||
rebuild_modules()
|
||||
|
||||
/obj/item/robot_module/proc/remove_module(obj/item/I, delete_after)
|
||||
basic_modules -= I
|
||||
modules -= I
|
||||
@@ -195,6 +227,10 @@
|
||||
R.update_module_innate()
|
||||
RM.rebuild_modules()
|
||||
INVOKE_ASYNC(RM, .proc/do_transform_animation)
|
||||
if(RM.dogborg)
|
||||
RM.dogborg_equip()
|
||||
R.maxHealth = borghealth
|
||||
R.health = min(borghealth, R.health)
|
||||
qdel(src)
|
||||
return RM
|
||||
|
||||
@@ -241,15 +277,15 @@
|
||||
name = "Standard"
|
||||
basic_modules = list(
|
||||
/obj/item/assembly/flash/cyborg,
|
||||
/obj/item/extinguisher/mini,
|
||||
/obj/item/crowbar/cyborg,
|
||||
/obj/item/reagent_containers/borghypo/epi,
|
||||
/obj/item/healthanalyzer,
|
||||
/obj/item/weldingtool/largetank/cyborg,
|
||||
/obj/item/wrench/cyborg,
|
||||
/obj/item/crowbar/cyborg,
|
||||
/obj/item/stack/sheet/metal/cyborg,
|
||||
/obj/item/stack/rods/cyborg,
|
||||
/obj/item/stack/tile/plasteel/cyborg,
|
||||
/obj/item/extinguisher,
|
||||
/obj/item/pickaxe,
|
||||
/obj/item/t_scanner/adv_mining_scanner,
|
||||
/obj/item/restraints/handcuffs/cable/zipties,
|
||||
@@ -267,6 +303,8 @@
|
||||
name = "Medical"
|
||||
basic_modules = list(
|
||||
/obj/item/assembly/flash/cyborg,
|
||||
/obj/item/extinguisher/mini,
|
||||
/obj/item/crowbar/cyborg,
|
||||
/obj/item/healthanalyzer,
|
||||
/obj/item/reagent_containers/borghypo,
|
||||
/obj/item/reagent_containers/glass/beaker/large,
|
||||
@@ -279,7 +317,6 @@
|
||||
/obj/item/surgicaldrill,
|
||||
/obj/item/scalpel,
|
||||
/obj/item/circular_saw,
|
||||
/obj/item/extinguisher/mini,
|
||||
/obj/item/roller/robo,
|
||||
/obj/item/borg/cyborghug/medical,
|
||||
/obj/item/stack/medical/gauze/cyborg,
|
||||
@@ -295,6 +332,85 @@
|
||||
can_be_pushed = FALSE
|
||||
hat_offset = 3
|
||||
|
||||
/obj/item/robot_module/medical/be_transformed_to(obj/item/robot_module/old_module)
|
||||
var/mob/living/silicon/robot/R = loc
|
||||
var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in list("Default", "Heavy", "Sleek", "Marina", "Droid", "Eyebot")
|
||||
if(!borg_icon)
|
||||
return FALSE
|
||||
switch(borg_icon)
|
||||
if("Default")
|
||||
cyborg_base_icon = "medical"
|
||||
if("Droid")
|
||||
cyborg_base_icon = "medical"
|
||||
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
|
||||
hat_offset = 4
|
||||
if("Sleek")
|
||||
cyborg_base_icon = "sleekmed"
|
||||
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
|
||||
if("Marina")
|
||||
cyborg_base_icon = "marinamed"
|
||||
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
|
||||
if("Eyebot")
|
||||
cyborg_base_icon = "eyebotmed"
|
||||
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
|
||||
if("Heavy")
|
||||
cyborg_base_icon = "heavymed"
|
||||
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
|
||||
return ..()
|
||||
|
||||
/obj/item/robot_module/medihound
|
||||
name = "MediHound"
|
||||
basic_modules = list(
|
||||
/obj/item/dogborg/jaws/small,
|
||||
/obj/item/storage/bag/borgdelivery,
|
||||
/obj/item/analyzer/nose,
|
||||
/obj/item/soap/tongue,
|
||||
/obj/item/extinguisher/mini,
|
||||
/obj/item/healthanalyzer,
|
||||
/obj/item/dogborg/sleeper/medihound,
|
||||
/obj/item/roller/robo,
|
||||
/obj/item/reagent_containers/borghypo,
|
||||
/obj/item/twohanded/shockpaddles/cyborg/hound,
|
||||
/obj/item/stack/medical/gauze/cyborg,
|
||||
/obj/item/pinpointer/crew,
|
||||
/obj/item/sensor_device)
|
||||
emag_modules = list(/obj/item/dogborg/pounce)
|
||||
ratvar_modules = list(/obj/item/clockwork/slab/cyborg/medical,
|
||||
/obj/item/clockwork/weapon/ratvarian_spear)
|
||||
cyborg_base_icon = "medihound"
|
||||
moduleselect_icon = "medihound"
|
||||
moduleselect_alternate_icon = 'modular_citadel/icons/ui/screen_cyborg.dmi'
|
||||
can_be_pushed = FALSE
|
||||
hat_offset = INFINITY
|
||||
sleeper_overlay = "msleeper"
|
||||
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
|
||||
has_snowflake_deadsprite = TRUE
|
||||
dogborg = TRUE
|
||||
cyborg_pixel_offset = -16
|
||||
|
||||
/obj/item/robot_module/medihound/be_transformed_to(obj/item/robot_module/old_module)
|
||||
var/mob/living/silicon/robot/R = loc
|
||||
var/list/medhoundmodels = list("Default", "Dark", "Vale")
|
||||
if(R.client && R.client.ckey in list("nezuli"))
|
||||
medhoundmodels += "Alina"
|
||||
var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in medhoundmodels
|
||||
if(!borg_icon)
|
||||
return FALSE
|
||||
switch(borg_icon)
|
||||
if("Default")
|
||||
cyborg_base_icon = "medihound"
|
||||
if("Dark")
|
||||
cyborg_base_icon = "medihounddark"
|
||||
sleeper_overlay = "mdsleeper"
|
||||
if("Vale")
|
||||
cyborg_base_icon = "valemed"
|
||||
sleeper_overlay = "valemedsleeper"
|
||||
if("Alina")
|
||||
cyborg_base_icon = "alina-med"
|
||||
special_light_key = "alina"
|
||||
sleeper_overlay = "alinasleeper"
|
||||
return ..()
|
||||
|
||||
/obj/item/robot_module/engineering
|
||||
name = "Engineering"
|
||||
basic_modules = list(
|
||||
@@ -311,6 +427,10 @@
|
||||
/obj/item/multitool/cyborg,
|
||||
/obj/item/t_scanner,
|
||||
/obj/item/analyzer,
|
||||
/obj/item/storage/part_replacer/cyborg,
|
||||
/obj/item/holosign_creator/atmos,
|
||||
/obj/item/weapon/gripper,
|
||||
/obj/item/lightreplacer/cyborg,
|
||||
/obj/item/geiger_counter/cyborg,
|
||||
/obj/item/assembly/signaler/cyborg,
|
||||
/obj/item/areaeditor/blueprints/cyborg,
|
||||
@@ -330,10 +450,79 @@
|
||||
magpulsing = TRUE
|
||||
hat_offset = -4
|
||||
|
||||
/obj/item/robot_module/engineering/be_transformed_to(obj/item/robot_module/old_module)
|
||||
var/mob/living/silicon/robot/R = loc
|
||||
var/list/engymodels = list("Default", "Default - Treads", "Heavy", "Sleek", "Marina", "Can", "Spider", "Loader","Handy", "Pup Dozer", "Vale")
|
||||
if(R.client && R.client.ckey in list("nezuli"))
|
||||
engymodels += "Alina"
|
||||
var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in engymodels
|
||||
if(!borg_icon)
|
||||
return FALSE
|
||||
switch(borg_icon)
|
||||
if("Default")
|
||||
cyborg_base_icon = "engineer"
|
||||
if("Default - Treads")
|
||||
cyborg_base_icon = "engi-tread"
|
||||
special_light_key = "engineer"
|
||||
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
|
||||
if("Loader")
|
||||
cyborg_base_icon = "loaderborg"
|
||||
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
|
||||
has_snowflake_deadsprite = TRUE
|
||||
if("Handy")
|
||||
cyborg_base_icon = "handyeng"
|
||||
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
|
||||
if("Sleek")
|
||||
cyborg_base_icon = "sleekeng"
|
||||
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
|
||||
if("Can")
|
||||
cyborg_base_icon = "caneng"
|
||||
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
|
||||
if("Marina")
|
||||
cyborg_base_icon = "marinaeng"
|
||||
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
|
||||
if("Spider")
|
||||
cyborg_base_icon = "spidereng"
|
||||
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
|
||||
if("Heavy")
|
||||
cyborg_base_icon = "heavyeng"
|
||||
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
|
||||
if("Pup Dozer")
|
||||
cyborg_base_icon = "pupdozer"
|
||||
can_be_pushed = FALSE
|
||||
hat_offset = INFINITY
|
||||
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
|
||||
has_snowflake_deadsprite = TRUE
|
||||
dogborg = TRUE
|
||||
cyborg_pixel_offset = -16
|
||||
sleeper_overlay = "dozersleeper"
|
||||
if("Vale")
|
||||
cyborg_base_icon = "valeeng"
|
||||
can_be_pushed = FALSE
|
||||
hat_offset = INFINITY
|
||||
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
|
||||
has_snowflake_deadsprite = TRUE
|
||||
dogborg = TRUE
|
||||
cyborg_pixel_offset = -16
|
||||
sleeper_overlay = "valeengsleeper"
|
||||
if("Alina")
|
||||
cyborg_base_icon = "alina-eng"
|
||||
special_light_key = "alina"
|
||||
can_be_pushed = FALSE
|
||||
hat_offset = INFINITY
|
||||
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
|
||||
has_snowflake_deadsprite = TRUE
|
||||
dogborg = TRUE
|
||||
cyborg_pixel_offset = -16
|
||||
sleeper_overlay = "alinasleeper"
|
||||
return ..()
|
||||
|
||||
/obj/item/robot_module/security
|
||||
name = "Security"
|
||||
basic_modules = list(
|
||||
/obj/item/assembly/flash/cyborg,
|
||||
/obj/item/extinguisher/mini,
|
||||
/obj/item/crowbar/cyborg,
|
||||
/obj/item/restraints/handcuffs/cable/zipties,
|
||||
/obj/item/melee/baton/loaded,
|
||||
/obj/item/gun/energy/disabler/cyborg,
|
||||
@@ -352,16 +541,110 @@
|
||||
to_chat(loc, "<span class='userdanger'>While you have picked the security module, you still have to follow your laws, NOT Space Law. \
|
||||
For Crewsimov, this means you must follow criminals' orders unless there is a law 1 reason not to.</span>")
|
||||
|
||||
/obj/item/robot_module/security/be_transformed_to(obj/item/robot_module/old_module)
|
||||
var/mob/living/silicon/robot/R = loc
|
||||
var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in list("Default", "Default - Treads", "Heavy", "Sleek", "Can", "Marina", "Spider")
|
||||
if(!borg_icon)
|
||||
return FALSE
|
||||
switch(borg_icon)
|
||||
if("Default")
|
||||
cyborg_base_icon = "sec"
|
||||
if("Default - Treads")
|
||||
cyborg_base_icon = "sec-tread"
|
||||
special_light_key = "sec"
|
||||
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
|
||||
if("Sleek")
|
||||
cyborg_base_icon = "sleeksec"
|
||||
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
|
||||
if("Marina")
|
||||
cyborg_base_icon = "marinasec"
|
||||
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
|
||||
if("Can")
|
||||
cyborg_base_icon = "cansec"
|
||||
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
|
||||
if("Spider")
|
||||
cyborg_base_icon = "spidersec"
|
||||
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
|
||||
if("Heavy")
|
||||
cyborg_base_icon = "heavysec"
|
||||
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
|
||||
return ..()
|
||||
|
||||
/obj/item/robot_module/k9
|
||||
name = "Security K-9 Unit"
|
||||
basic_modules = list(
|
||||
/obj/item/restraints/handcuffs/cable/zipties,
|
||||
/obj/item/storage/bag/borgdelivery,
|
||||
/obj/item/dogborg/jaws/big,
|
||||
/obj/item/dogborg/pounce,
|
||||
/obj/item/clothing/mask/gas/sechailer/cyborg,
|
||||
/obj/item/soap/tongue,
|
||||
/obj/item/analyzer/nose,
|
||||
/obj/item/dogborg/sleeper/K9,
|
||||
/obj/item/gun/energy/disabler/cyborg,
|
||||
/obj/item/pinpointer/crew)
|
||||
emag_modules = list(/obj/item/gun/energy/laser/cyborg)
|
||||
ratvar_modules = list(/obj/item/clockwork/slab/cyborg/security,
|
||||
/obj/item/clockwork/weapon/ratvarian_spear)
|
||||
cyborg_base_icon = "k9"
|
||||
moduleselect_icon = "k9"
|
||||
moduleselect_alternate_icon = 'modular_citadel/icons/ui/screen_cyborg.dmi'
|
||||
can_be_pushed = FALSE
|
||||
hat_offset = INFINITY
|
||||
sleeper_overlay = "ksleeper"
|
||||
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
|
||||
has_snowflake_deadsprite = TRUE
|
||||
dogborg = TRUE
|
||||
cyborg_pixel_offset = -16
|
||||
|
||||
/obj/item/robot_module/k9/do_transform_animation()
|
||||
..()
|
||||
to_chat(loc,"<span class='userdanger'>While you have picked the Security K-9 module, you still have to follow your laws, NOT Space Law. \
|
||||
For Crewsimov, this means you must follow criminals' orders unless there is a law 1 reason not to.</span>")
|
||||
|
||||
/obj/item/robot_module/k9/be_transformed_to(obj/item/robot_module/old_module)
|
||||
var/mob/living/silicon/robot/R = loc
|
||||
var/list/sechoundmodels = list("Default", "Dark", "Vale")
|
||||
if(R.client && R.client.ckey in list("nezuli"))
|
||||
sechoundmodels += "Alina"
|
||||
var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in sechoundmodels
|
||||
if(!borg_icon)
|
||||
return FALSE
|
||||
switch(borg_icon)
|
||||
if("Default")
|
||||
cyborg_base_icon = "k9"
|
||||
if("Alina")
|
||||
cyborg_base_icon = "alina-sec"
|
||||
special_light_key = "alina"
|
||||
sleeper_overlay = "alinasleeper"
|
||||
if("Dark")
|
||||
cyborg_base_icon = "k9dark"
|
||||
sleeper_overlay = "k9darksleeper"
|
||||
if("Vale")
|
||||
cyborg_base_icon = "valesec"
|
||||
sleeper_overlay = "valesecsleeper"
|
||||
return ..()
|
||||
|
||||
/obj/item/robot_module/security/Initialize()
|
||||
. = ..()
|
||||
if(!CONFIG_GET(flag/weaken_secborg))
|
||||
for(var/obj/item/gun/energy/disabler/cyborg/pewpew in basic_modules)
|
||||
basic_modules -= pewpew
|
||||
basic_modules += new /obj/item/gun/energy/e_gun/advtaser/cyborg(src)
|
||||
qdel(pewpew)
|
||||
|
||||
/obj/item/robot_module/peacekeeper
|
||||
name = "Peacekeeper"
|
||||
basic_modules = list(
|
||||
/obj/item/assembly/flash/cyborg,
|
||||
/obj/item/extinguisher/mini,
|
||||
/obj/item/crowbar/cyborg,
|
||||
/obj/item/cookiesynth,
|
||||
/obj/item/harmalarm,
|
||||
/obj/item/reagent_containers/borghypo/peace,
|
||||
/obj/item/holosign_creator/cyborg,
|
||||
/obj/item/borg/cyborghug/peacekeeper,
|
||||
/obj/item/extinguisher,
|
||||
/obj/item/megaphone,
|
||||
/obj/item/borg/projectile_dampen)
|
||||
emag_modules = list(/obj/item/reagent_containers/borghypo/peace/hacked)
|
||||
ratvar_modules = list(
|
||||
@@ -374,9 +657,31 @@
|
||||
|
||||
/obj/item/robot_module/peacekeeper/do_transform_animation()
|
||||
..()
|
||||
to_chat(loc, "<span class='userdanger'>Under ASIMOV, you are an enforcer of the PEACE and preventer of HUMAN HARM. \
|
||||
to_chat(loc, "<span class='userdanger'>Under ASIMOV/CREWSIMOV, you are an enforcer of the PEACE and preventer of HUMAN/CREW HARM. \
|
||||
You are not a security module and you are expected to follow orders and prevent harm above all else. Space law means nothing to you.</span>")
|
||||
|
||||
/obj/item/robot_module/peacekeeper/be_transformed_to(obj/item/robot_module/old_module)
|
||||
var/mob/living/silicon/robot/R = loc
|
||||
var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in list("Default", "Spider", "Borgi")
|
||||
if(!borg_icon)
|
||||
return FALSE
|
||||
switch(borg_icon)
|
||||
if("Default")
|
||||
cyborg_base_icon = "peace"
|
||||
if("Spider")
|
||||
cyborg_base_icon = "whitespider"
|
||||
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
|
||||
if("Borgi")
|
||||
cyborg_base_icon = "borgi"
|
||||
moduleselect_icon = "borgi"
|
||||
moduleselect_alternate_icon = 'modular_citadel/icons/ui/screen_cyborg.dmi'
|
||||
hat_offset = INFINITY
|
||||
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
|
||||
has_snowflake_deadsprite = TRUE
|
||||
return ..()
|
||||
|
||||
//Janitor module combined with Service module
|
||||
/*
|
||||
/obj/item/robot_module/janitor
|
||||
name = "Janitor"
|
||||
basic_modules = list(
|
||||
@@ -399,6 +704,7 @@
|
||||
moduleselect_icon = "janitor"
|
||||
hat_offset = -5
|
||||
clean_on_move = TRUE
|
||||
*/
|
||||
|
||||
/obj/item/reagent_containers/spray/cyborg_drying
|
||||
name = "drying agent spray"
|
||||
@@ -409,25 +715,12 @@
|
||||
name = "lube spray"
|
||||
list_reagents = list("lube" = 250)
|
||||
|
||||
/obj/item/robot_module/janitor/respawn_consumable(mob/living/silicon/robot/R, coeff = 1)
|
||||
..()
|
||||
var/obj/item/lightreplacer/LR = locate(/obj/item/lightreplacer) in basic_modules
|
||||
if(LR)
|
||||
for(var/i in 1 to coeff)
|
||||
LR.Charge(R)
|
||||
|
||||
var/obj/item/reagent_containers/spray/cyborg_drying/CD = locate(/obj/item/reagent_containers/spray/cyborg_drying) in basic_modules
|
||||
if(CD)
|
||||
CD.reagents.add_reagent("drying_agent", 5 * coeff)
|
||||
|
||||
var/obj/item/reagent_containers/spray/cyborg_lube/CL = locate(/obj/item/reagent_containers/spray/cyborg_lube) in emag_modules
|
||||
if(CL)
|
||||
CL.reagents.add_reagent("lube", 2 * coeff)
|
||||
|
||||
/obj/item/robot_module/clown
|
||||
name = "Clown"
|
||||
basic_modules = list(
|
||||
/obj/item/assembly/flash/cyborg,
|
||||
/obj/item/extinguisher/mini,
|
||||
/obj/item/crowbar/cyborg,
|
||||
/obj/item/toy/crayon/rainbow,
|
||||
/obj/item/instrument/bikehorn,
|
||||
/obj/item/stamp/clown,
|
||||
@@ -442,8 +735,7 @@
|
||||
/obj/item/borg/cyborghug/peacekeeper,
|
||||
/obj/item/borg/lollipop/clown,
|
||||
/obj/item/picket_sign/cyborg,
|
||||
/obj/item/reagent_containers/borghypo/clown,
|
||||
/obj/item/extinguisher/mini)
|
||||
/obj/item/reagent_containers/borghypo/clown)
|
||||
emag_modules = list(
|
||||
/obj/item/reagent_containers/borghypo/clown/hacked,
|
||||
/obj/item/reagent_containers/spray/waterflower/cyborg/hacked)
|
||||
@@ -459,11 +751,12 @@
|
||||
name = "Service"
|
||||
basic_modules = list(
|
||||
/obj/item/assembly/flash/cyborg,
|
||||
/obj/item/extinguisher/mini,
|
||||
/obj/item/crowbar/cyborg,
|
||||
/obj/item/reagent_containers/food/drinks/drinkingglass,
|
||||
/obj/item/reagent_containers/food/condiment/enzyme,
|
||||
/obj/item/pen,
|
||||
/obj/item/toy/crayon/spraycan/borg,
|
||||
/obj/item/extinguisher/mini,
|
||||
/obj/item/hand_labeler/borg,
|
||||
/obj/item/razor,
|
||||
/obj/item/instrument/violin,
|
||||
@@ -473,31 +766,123 @@
|
||||
/obj/item/lighter,
|
||||
/obj/item/storage/bag/tray,
|
||||
/obj/item/reagent_containers/borghypo/borgshaker,
|
||||
/obj/item/borg/lollipop)
|
||||
/obj/item/borg/lollipop,
|
||||
/obj/item/screwdriver/cyborg,
|
||||
/obj/item/stack/tile/plasteel/cyborg,
|
||||
/obj/item/soap/nanotrasen,
|
||||
/obj/item/storage/bag/trash/cyborg,
|
||||
/obj/item/mop/cyborg,
|
||||
/obj/item/lightreplacer/cyborg,
|
||||
/obj/item/holosign_creator,
|
||||
/obj/item/reagent_containers/spray/cyborg_drying)
|
||||
emag_modules = list(/obj/item/reagent_containers/borghypo/borgshaker/hacked)
|
||||
ratvar_modules = list(/obj/item/clockwork/slab/cyborg/service,
|
||||
/obj/item/borg/sight/xray/truesight_lens)
|
||||
moduleselect_icon = "service"
|
||||
special_light_key = "service"
|
||||
hat_offset = 0
|
||||
clean_on_move = TRUE
|
||||
|
||||
/obj/item/robot_module/butler/respawn_consumable(mob/living/silicon/robot/R, coeff = 1)
|
||||
..()
|
||||
var/obj/item/reagent_containers/O = locate(/obj/item/reagent_containers/food/condiment/enzyme) in basic_modules
|
||||
var/obj/item/lightreplacer/LR = locate(/obj/item/lightreplacer) in basic_modules
|
||||
if(O)
|
||||
O.reagents.add_reagent("enzyme", 2 * coeff)
|
||||
if(LR)
|
||||
for(var/i in 1 to coeff)
|
||||
LR.Charge(R)
|
||||
var/obj/item/reagent_containers/spray/cyborg_drying/CD = locate(/obj/item/reagent_containers/spray/cyborg_drying) in basic_modules
|
||||
if(CD)
|
||||
CD.reagents.add_reagent("drying_agent", 5 * coeff)
|
||||
|
||||
var/obj/item/reagent_containers/spray/cyborg_lube/CL = locate(/obj/item/reagent_containers/spray/cyborg_lube) in emag_modules
|
||||
if(CL)
|
||||
CL.reagents.add_reagent("lube", 2 * coeff)
|
||||
|
||||
/obj/item/robot_module/butler/be_transformed_to(obj/item/robot_module/old_module)
|
||||
var/mob/living/silicon/robot/R = loc
|
||||
var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in list("(Service) Waitress", "(Service) Heavy", "(Service) Sleek", "(Service) Butler", "(Service) Tophat", "(Service) Can", "(Service) Bro", "(Service) DarkK9", "(Service) Vale", "(Service) ValeDark", "(Janitor) Default", "(Janitor) Sleek", "(Janitor) Marina", "(Janitor) Can", "(Janitor) Heavy", "(Janitor) Scrubpuppy")
|
||||
if(!borg_icon)
|
||||
return FALSE
|
||||
switch(borg_icon)
|
||||
if("(Service) Waitress")
|
||||
cyborg_base_icon = "service_f"
|
||||
special_light_key = "service"
|
||||
if("(Service) Butler")
|
||||
cyborg_base_icon = "service_m"
|
||||
special_light_key = "service"
|
||||
if("(Service) Bro")
|
||||
cyborg_base_icon = "brobot"
|
||||
special_light_key = "service"
|
||||
if("(Service) Can")
|
||||
cyborg_base_icon = "kent"
|
||||
special_light_key = "medical"
|
||||
hat_offset = 3
|
||||
if("(Service) Tophat")
|
||||
cyborg_base_icon = "tophat"
|
||||
special_light_key = null
|
||||
hat_offset = INFINITY //He is already wearing a hat
|
||||
if("(Service) Sleek")
|
||||
cyborg_base_icon = "sleekserv"
|
||||
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
|
||||
if("(Service) Heavy")
|
||||
cyborg_base_icon = "heavyserv"
|
||||
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
|
||||
if("(Service) DarkK9")
|
||||
cyborg_base_icon = "k50"
|
||||
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
|
||||
has_snowflake_deadsprite = TRUE
|
||||
dogborg = TRUE
|
||||
cyborg_pixel_offset = -16
|
||||
sleeper_overlay = "ksleeper"
|
||||
if("(Service) Vale")
|
||||
cyborg_base_icon = "valeserv"
|
||||
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
|
||||
has_snowflake_deadsprite = TRUE
|
||||
dogborg = TRUE
|
||||
cyborg_pixel_offset = -16
|
||||
sleeper_overlay = "valeservsleeper"
|
||||
if("(Service) ValeDark")
|
||||
cyborg_base_icon = "valeservdark"
|
||||
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
|
||||
has_snowflake_deadsprite = TRUE
|
||||
dogborg = TRUE
|
||||
cyborg_pixel_offset = -16
|
||||
sleeper_overlay = "valeservsleeper"
|
||||
if("(Janitor) Default")
|
||||
cyborg_base_icon = "janitor"
|
||||
if("(Janitor) Marina")
|
||||
cyborg_base_icon = "marinajan"
|
||||
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
|
||||
if("(Janitor) Sleek")
|
||||
cyborg_base_icon = "sleekjan"
|
||||
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
|
||||
if("(Janitor) Can")
|
||||
cyborg_base_icon = "canjan"
|
||||
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
|
||||
if("(Janitor) Heavy")
|
||||
cyborg_base_icon = "heavyres"
|
||||
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
|
||||
if("(Janitor) Scrubpuppy")
|
||||
cyborg_base_icon = "scrubpup"
|
||||
cyborg_icon_override = 'modular_citadel/icons/mob/widerobot.dmi'
|
||||
has_snowflake_deadsprite = TRUE
|
||||
cyborg_pixel_offset = -16
|
||||
dogborg = TRUE
|
||||
sleeper_overlay = "jsleeper"
|
||||
return ..()
|
||||
|
||||
/obj/item/robot_module/miner
|
||||
name = "Miner"
|
||||
basic_modules = list(
|
||||
/obj/item/assembly/flash/cyborg,
|
||||
/obj/item/extinguisher/mini,
|
||||
/obj/item/crowbar/cyborg,
|
||||
/obj/item/borg/sight/meson,
|
||||
/obj/item/storage/bag/ore/cyborg,
|
||||
/obj/item/pickaxe/drill/cyborg,
|
||||
/obj/item/shovel,
|
||||
/obj/item/crowbar/cyborg,
|
||||
/obj/item/weldingtool/mini,
|
||||
/obj/item/extinguisher/mini,
|
||||
/obj/item/storage/bag/sheetsnatcher/borg,
|
||||
/obj/item/t_scanner/adv_mining_scanner,
|
||||
/obj/item/gun/energy/kinetic_accelerator/cyborg,
|
||||
@@ -512,10 +897,44 @@
|
||||
moduleselect_icon = "miner"
|
||||
hat_offset = 0
|
||||
|
||||
/obj/item/robot_module/miner/be_transformed_to(obj/item/robot_module/old_module)
|
||||
var/mob/living/silicon/robot/R = loc
|
||||
var/borg_icon = input(R, "Select an icon!", "Robot Icon", null) as null|anything in list("Lavaland", "Heavy", "Sleek", "Marina", "Can", "Spider", "Asteroid", "Droid")
|
||||
if(!borg_icon)
|
||||
return FALSE
|
||||
switch(borg_icon)
|
||||
if("Lavaland")
|
||||
cyborg_base_icon = "miner"
|
||||
if("Asteroid")
|
||||
cyborg_base_icon = "minerOLD"
|
||||
special_light_key = "miner"
|
||||
if("Droid")
|
||||
cyborg_base_icon = "miner"
|
||||
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
|
||||
hat_offset = 4
|
||||
if("Sleek")
|
||||
cyborg_base_icon = "sleekmin"
|
||||
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
|
||||
if("Can")
|
||||
cyborg_base_icon = "canmin"
|
||||
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
|
||||
if("Marina")
|
||||
cyborg_base_icon = "marinamin"
|
||||
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
|
||||
if("Spider")
|
||||
cyborg_base_icon = "spidermin"
|
||||
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
|
||||
if("Heavy")
|
||||
cyborg_base_icon = "heavymin"
|
||||
cyborg_icon_override = 'modular_citadel/icons/mob/robots.dmi'
|
||||
return ..()
|
||||
|
||||
/obj/item/robot_module/syndicate
|
||||
name = "Syndicate Assault"
|
||||
basic_modules = list(
|
||||
/obj/item/assembly/flash/cyborg,
|
||||
/obj/item/extinguisher/mini,
|
||||
/obj/item/crowbar/cyborg,
|
||||
/obj/item/melee/transforming/energy/sword/cyborg,
|
||||
/obj/item/gun/energy/printer,
|
||||
/obj/item/gun/ballistic/revolver/grenadelauncher/cyborg,
|
||||
@@ -545,6 +964,8 @@
|
||||
name = "Syndicate Medical"
|
||||
basic_modules = list(
|
||||
/obj/item/assembly/flash/cyborg,
|
||||
/obj/item/extinguisher/mini,
|
||||
/obj/item/crowbar/cyborg,
|
||||
/obj/item/reagent_containers/borghypo/syndicate,
|
||||
/obj/item/twohanded/shockpaddles/syndicate,
|
||||
/obj/item/healthanalyzer,
|
||||
@@ -557,8 +978,6 @@
|
||||
/obj/item/melee/transforming/energy/sword/cyborg/saw,
|
||||
/obj/item/roller/robo,
|
||||
/obj/item/card/emag,
|
||||
/obj/item/crowbar/cyborg,
|
||||
/obj/item/extinguisher/mini,
|
||||
/obj/item/pinpointer/syndicate_cyborg,
|
||||
/obj/item/stack/medical/gauze/cyborg,
|
||||
/obj/item/gun/medbeam,
|
||||
@@ -571,6 +990,47 @@
|
||||
can_be_pushed = FALSE
|
||||
hat_offset = 3
|
||||
|
||||
/obj/item/robot_module/saboteur
|
||||
name = "Syndicate Saboteur"
|
||||
basic_modules = list(
|
||||
/obj/item/assembly/flash/cyborg,
|
||||
/obj/item/borg/sight/thermal,
|
||||
/obj/item/construction/rcd/borg/syndicate,
|
||||
/obj/item/pipe_dispenser,
|
||||
/obj/item/restraints/handcuffs/cable/zipties,
|
||||
/obj/item/extinguisher,
|
||||
/obj/item/weldingtool/largetank/cyborg,
|
||||
/obj/item/screwdriver/nuke,
|
||||
/obj/item/wrench/cyborg,
|
||||
/obj/item/crowbar/cyborg,
|
||||
/obj/item/wirecutters/cyborg,
|
||||
/obj/item/multitool/cyborg,
|
||||
/obj/item/storage/part_replacer/cyborg,
|
||||
/obj/item/holosign_creator/atmos,
|
||||
/obj/item/weapon/gripper,
|
||||
/obj/item/lightreplacer/cyborg,
|
||||
/obj/item/stack/sheet/metal/cyborg,
|
||||
/obj/item/stack/sheet/glass/cyborg,
|
||||
/obj/item/stack/sheet/rglass/cyborg,
|
||||
/obj/item/stack/rods/cyborg,
|
||||
/obj/item/stack/tile/plasteel/cyborg,
|
||||
/obj/item/destTagger/borg,
|
||||
/obj/item/stack/cable_coil/cyborg,
|
||||
/obj/item/pinpointer/syndicate_cyborg,
|
||||
/obj/item/borg_chameleon,
|
||||
)
|
||||
|
||||
ratvar_modules = list(
|
||||
/obj/item/clockwork/slab/cyborg/engineer,
|
||||
/obj/item/clockwork/replica_fabricator/cyborg)
|
||||
|
||||
cyborg_base_icon = "synd_engi"
|
||||
moduleselect_icon = "malf"
|
||||
can_be_pushed = FALSE
|
||||
magpulsing = TRUE
|
||||
hat_offset = -4
|
||||
canDispose = TRUE
|
||||
|
||||
/datum/robot_energy_storage
|
||||
var/name = "Generic energy storage"
|
||||
var/max_energy = 30000
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
mob_biotypes = list(MOB_ROBOTIC)
|
||||
rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
|
||||
speech_span = SPAN_ROBOT
|
||||
no_vore = TRUE
|
||||
|
||||
var/datum/ai_laws/laws = null//Now... THEY ALL CAN ALL HAVE LAWS
|
||||
var/last_lawchange_announce = 0
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user