Merge branch 'master' into batch-check-injuries

# Conflicts:
#	code/modules/mob/living/carbon/human/human_defense.dm
This commit is contained in:
Carlen White
2019-07-14 20:46:11 -04:00
1265 changed files with 32219 additions and 18801 deletions
+2
View File
@@ -26,7 +26,9 @@
return
/mob/camera/forceMove(atom/destination)
var/oldloc = loc
loc = destination
Moved(oldloc, NONE, TRUE)
/mob/camera/emote(act, m_type=1, message = null, intentional = FALSE)
return
+2
View File
@@ -34,7 +34,9 @@ INITIALIZE_IMMEDIATE(/mob/dead)
var/turf/new_turf = get_turf(destination)
if (old_turf?.z != new_turf?.z)
onTransitZ(old_turf?.z, new_turf?.z)
var/oldloc = loc
loc = destination
Moved(oldloc, NONE, TRUE)
/mob/dead/Stat()
..()
+11 -1
View File
@@ -164,7 +164,7 @@
return
var/obj/effect/mob_spawn/MS = pick(GLOB.mob_spawners[href_list["JoinAsGhostRole"]])
if(istype(MS) && MS.attack_ghost(src, latejoinercalling = TRUE))
if(MS.attack_ghost(src, latejoinercalling = TRUE))
SSticker.queued_players -= src
SSticker.queue_delay = 4
qdel(src)
@@ -444,6 +444,11 @@
if(job && IsJobUnavailable(job.title, TRUE) == JOB_AVAILABLE)
available_job_count++
for(var/spawner in GLOB.mob_spawners)
if(!LAZYLEN(spawner))
continue
var/obj/effect/mob_spawn/S = pick(GLOB.mob_spawners[spawner])
if(!istype(S) || !S.can_latejoin())
continue
available_job_count++
break
@@ -465,6 +470,11 @@
"Security" = list(jobs = list(), titles = GLOB.security_positions, color = "#ff9999"),
)
for(var/spawner in GLOB.mob_spawners)
if(!LAZYLEN(spawner))
continue
var/obj/effect/mob_spawn/S = pick(GLOB.mob_spawners[spawner])
if(!istype(S) || !S.can_latejoin())
continue
categorizedJobs["Ghost Role"]["jobs"] += spawner
for(var/datum/job/job in SSjob.occupations)
@@ -6,8 +6,11 @@
else
gender = pick(MALE,FEMALE)
underwear = random_underwear(gender)
undie_color = random_color()
undershirt = random_undershirt(gender)
shirt_color = random_color()
socks = random_socks()
socks_color = random_color()
skin_tone = random_skin_tone()
hair_style = random_hair_style(gender)
facial_hair_style = random_facial_hair_style(gender)
@@ -28,7 +31,7 @@
if(job_engsec_high)
switch(job_engsec_high)
if(AI_JF)
parent.show_character_previews(image('icons/mob/ai.dmi', icon_state = "AI", dir = SOUTH))
parent.show_character_previews(image('icons/mob/ai.dmi', resolve_ai_icon(preferred_ai_core_display), dir = SOUTH))
return
if(CYBORG)
parent.show_character_previews(image('icons/mob/robots.dmi', icon_state = "robot", dir = SOUTH))
@@ -59,4 +59,8 @@
var/locked = FALSE //Is this part locked from roundstart selection? Used for parts that apply effects
var/dimension_x = 32
var/dimension_y = 32
var/center = FALSE //Should we center the sprite?
var/center = FALSE //Should we center the sprite?
/datum/sprite_accessory/underwear
icon = 'icons/mob/underwear.dmi'
var/has_color = FALSE
@@ -439,6 +439,10 @@
name = "Tress Shoulder"
icon_state = "hair_tressshoulder"
/datum/sprite_accessory/hair/longtwintails
name = "Twintails (Long)"
icon_state = "hair_longstraighttwintails"
/datum/sprite_accessory/hair/updo
name = "Updo"
icon_state = "hair_updo"
@@ -2,95 +2,132 @@
// Socks Definitions //
///////////////////////
/datum/sprite_accessory/socks
icon = 'icons/mob/underwear.dmi'
/datum/sprite_accessory/socks/nude
/datum/sprite_accessory/underwear/socks/nude
name = "Nude"
icon_state = null
// please make sure they're sorted alphabetically and categorized
/datum/sprite_accessory/socks/black_knee
name = "Knee-high (Black)"
icon_state = "black_knee"
/datum/sprite_accessory/underwear/socks/socks_knee
name = "Knee-high"
icon_state = "socks_knee"
has_color = TRUE
/datum/sprite_accessory/socks/commie_knee
name = "Knee-High (Commie)"
/datum/sprite_accessory/underwear/socks/bee_knee
name = "Knee-high - Bee"
icon_state = "bee_knee"
/datum/sprite_accessory/underwear/socks/commie_knee
name = "Knee-High - Commie"
icon_state = "commie_knee"
/datum/sprite_accessory/socks/usa_knee
name = "Knee-High (Freedom)"
/datum/sprite_accessory/underwear/socks/usa_knee
name = "Knee-High - Freedom"
icon_state = "assblastusa_knee"
/datum/sprite_accessory/socks/rainbow_knee
name = "Knee-high (Rainbow)"
/datum/sprite_accessory/underwear/socks/rainbow_knee
name = "Knee-high - Rainbow"
icon_state = "rainbow_knee"
/datum/sprite_accessory/socks/striped_knee
name = "Knee-high (Striped)"
/datum/sprite_accessory/underwear/socks/striped_knee
name = "Knee-high - Striped"
icon_state = "striped_knee"
has_color = TRUE
/datum/sprite_accessory/socks/thin_knee
name = "Knee-high (Thin)"
/datum/sprite_accessory/underwear/socks/thin_knee
name = "Knee-high - Thin"
icon_state = "thin_knee"
has_color = TRUE
/datum/sprite_accessory/socks/uk_knee
name = "Knee-High (UK)"
/datum/sprite_accessory/underwear/socks/uk_knee
name = "Knee-High - UK"
icon_state = "uk_knee"
/datum/sprite_accessory/socks/white_knee
name = "Knee-high (White)"
icon_state = "white_knee"
/datum/sprite_accessory/underwear/socks/socks_norm
name = "Normal"
icon_state = "socks_norm"
has_color = TRUE
/datum/sprite_accessory/socks/black_norm
name = "Normal (Black)"
icon_state = "black_norm"
/datum/sprite_accessory/underwear/socks/bee_norm
name = "Normal - Bee"
icon_state = "bee_norm"
/datum/sprite_accessory/socks/white_norm
name = "Normal (White)"
icon_state = "white_norm"
/datum/sprite_accessory/socks/pantyhose
/datum/sprite_accessory/underwear/socks/pantyhose
name = "Pantyhose"
icon_state = "pantyhose"
/datum/sprite_accessory/socks/black_short
name = "Short (Black)"
icon_state = "black_short"
/datum/sprite_accessory/underwear/socks/socks_short
name = "Short"
icon_state = "socks_short"
has_color = TRUE
/datum/sprite_accessory/socks/white_short
name = "Short (White)"
icon_state = "white_short"
/datum/sprite_accessory/underwear/socks/stockings_blue
name = "Stockings - Blue"
icon_state = "stockings_blue"
/datum/sprite_accessory/socks/black_thigh
name = "Thigh-high (Black)"
icon_state = "black_thigh"
/datum/sprite_accessory/underwear/socks/stockings_cyan
name = "Stockings - Cyan"
icon_state = "stockings_cyan"
/datum/sprite_accessory/socks/commie_thigh
name = "Thigh-high (Commie)"
/datum/sprite_accessory/underwear/socks/stockings_dpink
name = "Stockings - Dark Pink"
icon_state = "stockings_dpink"
/datum/sprite_accessory/underwear/socks/stockings_green
name = "Stockings - Green"
icon_state = "stockings_black"
/datum/sprite_accessory/underwear/socks/stockings_orange
name = "Stockings - Orange"
icon_state = "stockings_orange"
/datum/sprite_accessory/underwear/socks/stockings_programmer
name = "Stockings - Programmer"
icon_state = "stockings_lpink"
/datum/sprite_accessory/underwear/socks/stockings_purple
name = "Stockings - Purple"
icon_state = "stockings_purple"
/datum/sprite_accessory/underwear/socks/stockings_yellow
name = "Stockings - Yellow"
icon_state = "stockings_yellow"
/datum/sprite_accessory/underwear/socks/socks_thigh
name = "Thigh-high"
icon_state = "socks_thigh"
has_color = TRUE
/datum/sprite_accessory/underwear/socks/bee_thigh
name = "Thigh-high - Bee"
icon_state = "bee_thigh"
/datum/sprite_accessory/underwear/socks/commie_thigh
name = "Thigh-high - Commie"
icon_state = "commie_thigh"
/datum/sprite_accessory/socks/usa_thigh
name = "Thigh-high (Freedom)"
/datum/sprite_accessory/underwear/socks/usa_thigh
name = "Thigh-high - Freedom"
icon_state = "assblastusa_thigh"
/datum/sprite_accessory/socks/rainbow_thigh
name = "Thigh-high (Rainbow)"
/datum/sprite_accessory/underwear/socks/fishnet
name = "Thigh-high - Fishnet"
icon_state = "fishnet"
/datum/sprite_accessory/underwear/socks/rainbow_thigh
name = "Thigh-high - Rainbow"
icon_state = "rainbow_thigh"
/datum/sprite_accessory/socks/striped_thigh
name = "Thigh-high (Striped)"
/datum/sprite_accessory/underwear/socks/striped_thigh
name = "Thigh-high - Striped"
icon_state = "striped_thigh"
has_color = TRUE
/datum/sprite_accessory/socks/thin_thigh
name = "Thigh-high (Thin)"
/datum/sprite_accessory/underwear/socks/thin_thigh
name = "Thigh-high - Thin"
icon_state = "thin_thigh"
has_color = TRUE
/datum/sprite_accessory/socks/uk_thigh
name = "Thigh-high (UK)"
/datum/sprite_accessory/underwear/socks/uk_thigh
name = "Thigh-high - UK"
icon_state = "uk_thigh"
/datum/sprite_accessory/socks/white_thigh
name = "Thigh-high (White)"
icon_state = "white_thigh"
@@ -2,307 +2,288 @@
// Undershirt Definitions //
////////////////////////////
/datum/sprite_accessory/undershirt
icon = 'icons/mob/underwear.dmi'
gender = NEUTER
/datum/sprite_accessory/undershirt/nude
/datum/sprite_accessory/underwear/top/nude
name = "Nude"
icon_state = null
// please make sure they're sorted alphabetically and categorized
/datum/sprite_accessory/undershirt/bluejersey
/datum/sprite_accessory/underwear/top/longjon
name = "Long John Shirt"
icon_state = "ljont"
has_color = TRUE
/datum/sprite_accessory/underwear/top/longstripe_black
name = "Longsleeve Striped Shirt - Black"
icon_state = "longstripe"
/datum/sprite_accessory/underwear/top/longstripe_blue
name = "Longsleeve Striped Shirt - Blue"
icon_state = "longstripe_blue"
/datum/sprite_accessory/underwear/top/shirt
name = "Shirt"
icon_state = "undershirt"
has_color = TRUE
/datum/sprite_accessory/underwear/top/bowlingw
name = "Shirt - Bowling"
icon_state = "bowlingw"
has_color = TRUE
/datum/sprite_accessory/underwear/top/bowling
name = "Shirt, Bowling - Red"
icon_state = "bowling"
/datum/sprite_accessory/underwear/top/bowlingp
name = "Shirt, Bowling - Pink"
icon_state = "bowlingp"
/datum/sprite_accessory/underwear/top/bowlinga
name = "Shirt, Bowling - Aqua"
icon_state = "bowlinga"
/datum/sprite_accessory/underwear/top/bluejersey
name = "Shirt, Jersey - Blue"
icon_state = "shirt_bluejersey"
/datum/sprite_accessory/undershirt/redjersey
/datum/sprite_accessory/underwear/top/redjersey
name = "Shirt, Jersey - Red"
icon_state = "shirt_redjersey"
/datum/sprite_accessory/undershirt/bluepolo
name = "Shirt, Polo - Blue"
icon_state = "bluepolo"
/datum/sprite_accessory/underwear/top/polo
name = "Shirt - Polo"
icon_state = "polo"
has_color = TRUE
/datum/sprite_accessory/undershirt/grayyellowpolo
name = "Shirt, Polo - Gray, Yellow"
icon_state = "grayyellowpolo"
/datum/sprite_accessory/undershirt/redpolo
name = "Shirt, Polo - Red"
icon_state = "redpolo"
/datum/sprite_accessory/undershirt/whitepolo
name = "Shirt, Polo - White"
icon_state = "whitepolo"
/datum/sprite_accessory/undershirt/alienshirt
/datum/sprite_accessory/underwear/top/alienshirt
name = "Shirt - Alien"
icon_state = "shirt_alien"
/datum/sprite_accessory/undershirt/mondmondjaja
/datum/sprite_accessory/underwear/top/mondmondjaja
name = "Shirt - Band"
icon_state = "band"
/datum/sprite_accessory/undershirt/shirt_black
name = "Shirt - Black"
icon_state = "shirt_black"
/datum/sprite_accessory/underwear/top/shirt_bee
name = "Shirt - Bee"
icon_state = "bee_shirt"
/datum/sprite_accessory/undershirt/blueshirt
name = "Shirt - Blue"
icon_state = "shirt_blue"
/datum/sprite_accessory/undershirt/clownshirt
/datum/sprite_accessory/underwear/top/clownshirt
name = "Shirt - Clown"
icon_state = "shirt_clown"
/datum/sprite_accessory/undershirt/commie
/datum/sprite_accessory/underwear/top/commie
name = "Shirt - Commie"
icon_state = "shirt_commie"
/datum/sprite_accessory/undershirt/greenshirt
name = "Shirt - Green"
icon_state = "shirt_green"
/datum/sprite_accessory/undershirt/shirt_grey
name = "Shirt - Grey"
icon_state = "shirt_grey"
/datum/sprite_accessory/undershirt/ian
/datum/sprite_accessory/underwear/top/ian
name = "Shirt - Ian"
icon_state = "ian"
/datum/sprite_accessory/undershirt/ilovent
/datum/sprite_accessory/underwear/top/ilovent
name = "Shirt - I Love NT"
icon_state = "ilovent"
/datum/sprite_accessory/undershirt/lover
/datum/sprite_accessory/underwear/top/lover
name = "Shirt - Lover"
icon_state = "lover"
/datum/sprite_accessory/undershirt/matroska
/datum/sprite_accessory/underwear/top/matroska
name = "Shirt - Matroska"
icon_state = "matroska"
/datum/sprite_accessory/undershirt/meat
/datum/sprite_accessory/underwear/top/meat
name = "Shirt - Meat"
icon_state = "shirt_meat"
/datum/sprite_accessory/undershirt/nano
/datum/sprite_accessory/underwear/top/nano
name = "Shirt - Nanotrasen"
icon_state = "shirt_nano"
/datum/sprite_accessory/undershirt/peace
/datum/sprite_accessory/underwear/top/peace
name = "Shirt - Peace"
icon_state = "peace"
/datum/sprite_accessory/undershirt/pacman
/datum/sprite_accessory/underwear/top/pacman
name = "Shirt - Pogoman"
icon_state = "pogoman"
/datum/sprite_accessory/undershirt/question
/datum/sprite_accessory/underwear/top/question
name = "Shirt - Question"
icon_state = "shirt_question"
/datum/sprite_accessory/undershirt/redshirt
name = "Shirt - Red"
icon_state = "shirt_red"
/datum/sprite_accessory/undershirt/skull
/datum/sprite_accessory/underwear/top/skull
name = "Shirt - Skull"
icon_state = "shirt_skull"
/datum/sprite_accessory/undershirt/ss13
/datum/sprite_accessory/underwear/top/ss13
name = "Shirt - SS13"
icon_state = "shirt_ss13"
has_color = TRUE
/datum/sprite_accessory/undershirt/stripe
/datum/sprite_accessory/underwear/top/stripe
name = "Shirt - Striped"
icon_state = "shirt_stripes"
/datum/sprite_accessory/undershirt/tiedye
/datum/sprite_accessory/underwear/top/tiedye
name = "Shirt - Tie-dye"
icon_state = "shirt_tiedye"
/datum/sprite_accessory/undershirt/uk
/datum/sprite_accessory/underwear/top/uk
name = "Shirt - UK"
icon_state = "uk"
/datum/sprite_accessory/undershirt/usa
/datum/sprite_accessory/underwear/top/usa
name = "Shirt - USA"
icon_state = "shirt_assblastusa"
/datum/sprite_accessory/undershirt/shirt_white
name = "Shirt - White"
icon_state = "shirt_white"
/datum/sprite_accessory/underwear/top/shortsleeve
name = "Shirt - Short Sleeved"
icon_state = "shortsleeve"
has_color = TRUE
/datum/sprite_accessory/undershirt/blackshortsleeve
name = "Shirt, Short Sleeved - Black"
icon_state = "blackshortsleeve"
/datum/sprite_accessory/undershirt/blueshortsleeve
name = "Shirt, Short Sleeved - Blue"
icon_state = "blueshortsleeve"
/datum/sprite_accessory/undershirt/greenshortsleeve
name = "Shirt, Short Sleeved - Green"
icon_state = "greenshortsleeve"
/datum/sprite_accessory/undershirt/purpleshortsleeve
name = "Shirt, Short Sleeved - Purple"
icon_state = "purpleshortsleeve"
/datum/sprite_accessory/undershirt/whiteshortsleeve
name = "Shirt, Short Sleeved - White"
icon_state = "whiteshortsleeve"
/datum/sprite_accessory/undershirt/blueshirtsport
/datum/sprite_accessory/underwear/top/blueshirtsport
name = "Shirt, Sports - Blue"
icon_state = "blueshirtsport"
gender = NEUTER
/datum/sprite_accessory/undershirt/greenshirtsport
/datum/sprite_accessory/underwear/top/greenshirtsport
name = "Shirt, Sports - Green"
icon_state = "greenshirtsport"
gender = NEUTER
/datum/sprite_accessory/undershirt/redshirtsport
/datum/sprite_accessory/underwear/top/redshirtsport
name = "Shirt, Sports - Red"
icon_state = "redshirtsport"
gender = NEUTER
/datum/sprite_accessory/undershirt/redtop
name = "Shirt, Short - Red"
icon_state = "redtop"
/datum/sprite_accessory/undershirt/whitetop
name = "Shirt, Short - White"
icon_state = "whitetop"
/datum/sprite_accessory/undershirt/tshirt_blue
name = "T-Shirt - Blue"
icon_state = "blueshirt"
/datum/sprite_accessory/undershirt/tshirt_green
name = "T-Shirt - Green"
icon_state = "greenshirt"
/datum/sprite_accessory/undershirt/tshirt_red
name = "T-Shirt - Red"
icon_state = "redshirt"
/datum/sprite_accessory/undershirt/yellowshirt
name = "T-Shirt - Yellow"
icon_state = "yellowshirt"
/datum/sprite_accessory/undershirt/tank_black
name = "Tank Top - Black"
icon_state = "tank_black"
/datum/sprite_accessory/undershirt/tankfire
/datum/sprite_accessory/underwear/top/tankfire
name = "Tank Top - Fire"
icon_state = "tank_fire"
/datum/sprite_accessory/undershirt/tank_grey
name = "Tank Top - Grey"
icon_state = "tank_grey"
/datum/sprite_accessory/underwear/top/tanktop
name = "Tank Top"
icon_state = "tanktop"
has_color = TRUE
/datum/sprite_accessory/undershirt/female_midriff
/datum/sprite_accessory/underwear/top/tanktop_alt
name = "Tank Top - Alt"
icon_state = "tanktop_alt"
has_color = TRUE
/datum/sprite_accessory/underwear/top/tanktop_midriff
name = "Tank Top - Midriff"
icon_state = "tank_midriff"
has_color = TRUE
/datum/sprite_accessory/undershirt/tank_red
name = "Tank Top - Red"
icon_state = "tank_red"
/datum/sprite_accessory/underwear/top/tanktop_midriff_alt
name = "Tank Top - Midriff Halterneck"
icon_state = "tank_midriff_alt"
has_color = TRUE
/datum/sprite_accessory/undershirt/tankstripe
/datum/sprite_accessory/underwear/top/tankstripe
name = "Tank Top - Striped"
icon_state = "tank_stripes"
/datum/sprite_accessory/undershirt/tank_white
name = "Tank Top - White"
icon_state = "tank_white"
/datum/sprite_accessory/underwear/top/tank_top_sun
name = "Tank top - Sun"
icon_state = "tank_sun"
/datum/sprite_accessory/undershirt/female_red
name = "Bra - Red"
icon_state = "bra_red"
/datum/sprite_accessory/underwear/top/babydoll
name = "Baby-Doll"
icon_state = "babydoll"
has_color = TRUE
/datum/sprite_accessory/undershirt/female_pink
name = "Bra - Pink"
icon_state = "bra_pink"
/datum/sprite_accessory/underwear/top/bra
name = "Bra"
icon_state = "bra"
has_color = TRUE
/datum/sprite_accessory/undershirt/female_kinky
/datum/sprite_accessory/underwear/top/bra_alt
name = "Bra - Alt"
icon_state = "bra_alt"
has_color = TRUE
/datum/sprite_accessory/underwear/top/bra_thin
name = "Bra - Thin"
icon_state = "bra_thin"
has_color = TRUE
/datum/sprite_accessory/underwear/top/bra_kinky
name = "Bra - Kinky Black"
icon_state = "bra_kinky"
/datum/sprite_accessory/undershirt/female_green
name = "Bra - Green"
icon_state = "bra_green"
/datum/sprite_accessory/undershirt/female_commie
/datum/sprite_accessory/underwear/top/bra_freedom
name = "Bra - Freedom"
icon_state = "bra_assblastusa"
/datum/sprite_accessory/undershirt/female_commie
/datum/sprite_accessory/underwear/top/bra_commie
name = "Bra - Commie"
icon_state = "bra_commie"
/datum/sprite_accessory/undershirt/female_babyblue
name = "Bra, Baby Blue"
icon_state = "bra_babyblue"
/datum/sprite_accessory/underwear/top/bra_beekini
name = "Bra - Bee-kini"
icon_state = "bra_bee-kini"
/datum/sprite_accessory/undershirt/female_black
name = "Bra - Black"
icon_state = "bra_black"
/datum/sprite_accessory/undershirt/female_uk
/datum/sprite_accessory/underwear/top/bra_uk
name = "Bra - UK"
icon_state = "bra_uk"
/datum/sprite_accessory/undershirt/female_white
name = "Bra - White"
icon_state = "bra_white"
/datum/sprite_accessory/underwear/top/bra_neko
name = "Bra - Neko"
icon_state = "bra_neko"
has_color = TRUE
/datum/sprite_accessory/undershirt/female_white_neko
name = "Bra, Neko - white"
icon_state = "bra_neko_white"
/datum/sprite_accessory/underwear/top/halterneck_bra
name = "Bra - Halterneck"
icon_state = "halterneck_bra"
has_color = TRUE
/datum/sprite_accessory/undershirt/female_black_neko
name = "Bra, Neko - Black"
icon_state = "bra_neko_black"
/datum/sprite_accessory/undershirt/female_blackalt
name = "Bra, Sports - Black"
icon_state = "bra_sports_black"
/datum/sprite_accessory/undershirt/sports_bra
name = "Bra, Sports 1 - White"
/datum/sprite_accessory/underwear/top/sports_bra
name = "Bra, Sports"
icon_state = "sports_bra"
has_color = TRUE
/datum/sprite_accessory/undershirt/female_whitealt
name = "Bra, Sports 2 - White"
icon_state = "bra_sports_white"
/datum/sprite_accessory/undershirt/sports_bra2
name = "Bra, Sports 3 - White"
/datum/sprite_accessory/underwear/top/sports_bra_alt
name = "Bra, Sports - Alt"
icon_state = "sports_bra_alt"
has_color = TRUE
/datum/sprite_accessory/undershirt/female_yellow
name = "Bra - Yellow"
icon_state = "bra_yellow"
/datum/sprite_accessory/underwear/top/bra_strapless
name = "Bra, Strapless"
icon_state = "bra_strapless"
has_color = TRUE
/datum/sprite_accessory/undershirt/female_thong
name = "Bra, Strapless - Pink"
icon_state = "bra_strapless_pink"
/datum/sprite_accessory/undershirt/female_blue
name = "Bra, Strapless - Blue"
/datum/sprite_accessory/underwear/top/bra_strapless_alt
name = "Bra, Strapless - Alt"
icon_state = "bra_blue"
has_color = TRUE
/datum/sprite_accessory/undershirt/swimsuit_green
name = "Swimsuit, Top - Green"
icon_state = "bra_swimming_green"
/datum/sprite_accessory/underwear/top/striped_bra
name = "Bra - Striped"
icon_state = "striped_bra"
has_color = TRUE
/datum/sprite_accessory/undershirt/swimsuit_purple
name = "Swimsuit, Top - Purple"
icon_state = "bra_swimming_purple"
/datum/sprite_accessory/underwear/top/fishnet_sleeves
name = "Fishnet - sleeves"
icon_state = "fishnet_sleeves"
/datum/sprite_accessory/underwear/top/fishnet_gloves
name = "Fishnet - gloves"
icon_state = "fishnet_gloves"
/datum/sprite_accessory/underwear/top/fishnet_base
name = "Fishnet - top"
icon_state = "fishnet_body"
/datum/sprite_accessory/underwear/top/swimsuit
name = "Swimsuit Top"
icon_state = "bra_swimming"
has_color = TRUE
/datum/sprite_accessory/underwear/top/swimsuit_alt
name = "Swimsuit Top - Strapless"
icon_state = "bra_swimming_alt"
has_color = TRUE
/datum/sprite_accessory/underwear/top/tubetop
name = "Tube Top"
icon_state = "tubetop"
has_color = TRUE
@@ -1,171 +1,144 @@
///////////////////////////
// Underwear Definitions //
///////////////////////////
/datum/sprite_accessory/underwear
icon = 'icons/mob/underwear.dmi'
gender = NEUTER
/datum/sprite_accessory/underwear/nude
/datum/sprite_accessory/underwear/bottom/nude
name = "Nude"
icon_state = null
/datum/sprite_accessory/underwear/mankini
name = "Mankini - Green"
icon_state = "mankini_green"
/datum/sprite_accessory/underwear/bottom/mankini
name = "Mankini"
icon_state = "mankini"
has_color = TRUE
/datum/sprite_accessory/underwear/male_kinky
name = "Jockstrap - White"
icon_state = "jockstrap_white"
/datum/sprite_accessory/underwear/bottom/male_kinky
name = "Jockstrap"
icon_state = "jockstrap"
has_color = TRUE
/datum/sprite_accessory/underwear/male_white
name = "Briefs - White"
icon_state = "briefs_white"
/datum/sprite_accessory/underwear/bottom/briefs
name = "Briefs"
icon_state = "briefs"
has_color = TRUE
/datum/sprite_accessory/underwear/male_black
name = "Briefs - Black"
icon_state = "briefs_black"
/datum/sprite_accessory/underwear/bottom/boxers
name = "Boxers"
icon_state = "boxers"
has_color = TRUE
/datum/sprite_accessory/underwear/male_grey
name = "Briefs - Grey"
icon_state = "briefs_grey"
/datum/sprite_accessory/underwear/bottom/male_bee
name = "Boxers - Bee"
icon_state = "bee_shorts"
/datum/sprite_accessory/underwear/male_red
name = "Briefs - Red"
icon_state = "briefs_red"
/datum/sprite_accessory/underwear/male_green
name = "Briefs - Green"
icon_state = "briefs_green"
/datum/sprite_accessory/underwear/male_blue
name = "Briefs - Blue"
icon_state = "briefs_blue"
/datum/sprite_accessory/underwear/male_blackalt
name = "Boxers - Black"
icon_state = "boxers_black"
/datum/sprite_accessory/underwear/male_greyalt
name = "Boxers - Grey"
icon_state = "boxers_grey"
/datum/sprite_accessory/underwear/male_hearts
/datum/sprite_accessory/underwear/bottom/male_hearts
name = "Boxers - Heart"
icon_state = "boxers_heart"
/datum/sprite_accessory/underwear/male_stripe
/datum/sprite_accessory/underwear/bottom/male_stripe
name = "Boxers - Striped"
icon_state = "boxers_striped"
/datum/sprite_accessory/underwear/male_commie
/datum/sprite_accessory/underwear/bottom/male_commie
name = "Boxers - Striped Communist"
icon_state = "boxers_commie"
/datum/sprite_accessory/underwear/male_usastripe
/datum/sprite_accessory/underwear/bottom/male_usastripe
name = "Boxers - Striped Freedom"
icon_state = "boxers_assblastusa"
/datum/sprite_accessory/underwear/male_uk
/datum/sprite_accessory/underwear/bottom/male_uk
name = "Boxers - Striped UK"
icon_state = "boxers_uk"
/datum/sprite_accessory/underwear/bottom/boxer_briefs
name = "Boxer Briefs"
icon_state = "boxer_briefs"
has_color = TRUE
/datum/sprite_accessory/underwear/female_whitealt
name = "Boxer Briefs - White"
icon_state = "boxer_briefs_white"
/datum/sprite_accessory/underwear/bottom/panties
name = "Panties"
icon_state = "panties"
has_color = TRUE
/datum/sprite_accessory/underwear/female_blackalt
name = "Boxer Briefs - Black"
icon_state = "boxer_briefs_black"
/datum/sprite_accessory/underwear/bottom/panties_alt
name = "Panties - Alt"
icon_state = "panties_alt"
has_color = TRUE
/datum/sprite_accessory/underwear/female_pink
name = "Boxer Briefs - Pink"
icon_state = "boxer_briefs_pink"
/datum/sprite_accessory/underwear/bottom/fishnet_lower
name = "Panties - Fishnet"
icon_state = "fishnet_lower"
/datum/sprite_accessory/underwear/female_babyblue
name = "Boxer Briefs - Baby Blue"
icon_state = "boxer_briefs_babyblue"
/datum/sprite_accessory/underwear/bottom/female_beekini
name = "Panties - Bee-kini"
icon_state = "panties_bee-kini"
/datum/sprite_accessory/underwear/female_yellow
name = "Boxer Briefs - Yellow"
icon_state = "boxer_briefs_yellow"
/datum/sprite_accessory/underwear/female_black
name = "Panties - Black"
icon_state = "panties_black"
/datum/sprite_accessory/underwear/female_blue
name = "Panties - Blue"
icon_state = "panties_blue"
/datum/sprite_accessory/underwear/female_commie
/datum/sprite_accessory/underwear/bottom/female_commie
name = "Panties - Commie"
icon_state = "panties_commie"
/datum/sprite_accessory/underwear/female_usastripe
/datum/sprite_accessory/underwear/bottom/female_usastripe
name = "Panties - Freedom"
icon_state = "panties_assblastusa"
/datum/sprite_accessory/underwear/female_green
name = "Panties - Green"
icon_state = "panties_green"
/datum/sprite_accessory/underwear/female_kinky
/datum/sprite_accessory/underwear/bottom/female_kinky
name = "Panties - Kinky Black"
icon_state = "panties_kinky"
/datum/sprite_accessory/underwear/female_red
name = "Panties - Red"
icon_state = "panties_red"
/datum/sprite_accessory/underwear/female_uk
/datum/sprite_accessory/underwear/bottom/panties_uk
name = "Panties - UK"
icon_state = "panties_uk"
/datum/sprite_accessory/underwear/female_white
name = "Panties - White"
icon_state = "panties_white"
/datum/sprite_accessory/underwear/bottom/panties_neko
name = "Panties - Neko"
icon_state = "panties_neko"
has_color = TRUE
/datum/sprite_accessory/underwear/female_white_neko
name = "Panties, Neko - White"
icon_state = "panties_neko_white"
/datum/sprite_accessory/underwear/bottom/panties_slim
name = "Panties - Slim"
icon_state = "panties_slim"
has_color = TRUE
/datum/sprite_accessory/underwear/female_black_neko
name = "Panties, Neko - Black"
icon_state = "panties_neko_black"
/datum/sprite_accessory/underwear/bottom/striped_panties
name = "Panties - Striped"
icon_state = "striped_panties"
has_color = TRUE
/datum/sprite_accessory/underwear/bottom/panties_swimsuit
name = "Panties - Swimsuit"
icon_state = "panties_swimming"
has_color = TRUE
/datum/sprite_accessory/underwear/swimsuit_red
/datum/sprite_accessory/underwear/bottom/panties_thin
name = "Panties - Thin"
icon_state = "panties_thin"
has_color = TRUE
/datum/sprite_accessory/underwear/bottom/longjon
name = "Long John Bottoms"
icon_state = "ljonb"
has_color = TRUE
/datum/sprite_accessory/underwear/bottom/swimsuit_red
name = "Swimsuit, One Piece - Red"
icon_state = "swimming_red"
/datum/sprite_accessory/underwear/swimsuit
/datum/sprite_accessory/underwear/bottom/swimsuit
name = "Swimsuit, One Piece - Black"
icon_state = "swimming_black"
/datum/sprite_accessory/underwear/swimsuit_blue
/datum/sprite_accessory/underwear/bottom/swimsuit_blue
name = "Swimsuit, One Piece - Striped Blue"
icon_state = "swimming_blue"
/datum/sprite_accessory/underwear/swimsuit_green
name = "Swimsuit, Bottom - Green"
icon_state = "panties_swimming_green"
/datum/sprite_accessory/underwear/bottom/thong
name = "Thong"
icon_state = "thong"
has_color = TRUE
/datum/sprite_accessory/underwear/swimsuit_purple
name = "Swimsuit, Bottom - Purple"
icon_state = "panties_swimming_purple"
/datum/sprite_accessory/underwear/female_thong_black
name = "Thong - Black"
icon_state = "thong_black"
/datum/sprite_accessory/underwear/female_thong
name = "Thong - Pink"
icon_state = "thong_pink"
/datum/sprite_accessory/underwear/female_babydoll
name = "Babydoll - Black"
icon_state = "babydoll"
/datum/sprite_accessory/underwear/bottom/thong_babydoll
name = "Thong - Alt"
icon_state = "thong_babydoll"
has_color = TRUE
+4 -7
View File
@@ -429,9 +429,6 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
var/orbitsize = (I.Width()+I.Height())*0.5
orbitsize -= (orbitsize/world.icon_size)*(world.icon_size*0.25)
if(orbiting && orbiting.orbiting != target)
to_chat(src, "<span class='notice'>Now orbiting [target].</span>")
var/rot_seg
switch(ghost_orbit)
@@ -450,10 +447,10 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
/mob/dead/observer/orbit()
setDir(2)//reset dir so the right directional sprites show up
..()
return ..()
/mob/dead/observer/stop_orbit()
..()
/mob/dead/observer/stop_orbit(datum/component/orbiter/orbits)
. = ..()
//restart our floating animation after orbit is done.
pixel_y = 0
animate(src, pixel_y = 2, time = 10, loop = -1)
@@ -753,7 +750,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
update_icon()
/mob/dead/observer/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE)
/mob/dead/observer/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE, no_tk=FALSE)
return IsAdminGhost(usr)
/mob/dead/observer/is_literate()
+4 -4
View File
@@ -275,7 +275,7 @@
/mob/proc/canUnEquip(obj/item/I, force)
if(!I)
return TRUE
if((I.item_flags & NODROP) && !force)
if(HAS_TRAIT(I, TRAIT_NODROP) && !force)
return FALSE
return TRUE
@@ -309,13 +309,13 @@
//DO NOT CALL THIS PROC
//use one of the above 3 helper procs
//you may override it, but do not modify the args
/mob/proc/doUnEquip(obj/item/I, force, newloc, no_move, invdrop = TRUE) //Force overrides NODROP_1 for things like wizarditis and admin undress.
/mob/proc/doUnEquip(obj/item/I, force, newloc, no_move, invdrop = TRUE) //Force overrides TRAIT_NODROP for things like wizarditis and admin undress.
//Use no_move if the item is just gonna be immediately moved afterward
//Invdrop is used to prevent stuff in pockets dropping. only set to false if it's going to immediately be replaced
if(!I) //If there's nothing to drop, the drop is automatically succesfull. If(unEquip) should generally be used to check for NODROP_1.
if(!I) //If there's nothing to drop, the drop is automatically succesfull. If(unEquip) should generally be used to check for TRAIT_NODROP.
return TRUE
if((I.item_flags & NODROP) && !force)
if(HAS_TRAIT(I, TRAIT_NODROP) && !force)
return FALSE
var/hand_index = get_held_index_of_item(I)
+7 -7
View File
@@ -16,7 +16,7 @@
/mob/living/carbon/monkey/handle_blood()
if(bodytemperature >= TCRYO && !(has_trait(TRAIT_NOCLONE))) //cryosleep or husked people do not pump the blood.
if(bodytemperature >= TCRYO && !(HAS_TRAIT(src, TRAIT_NOCLONE))) //cryosleep or husked people do not pump the blood.
//Blood regeneration if there is some space
if(blood_volume < BLOOD_VOLUME_NORMAL)
blood_volume += 0.1 // regenerate blood VERY slowly
@@ -30,10 +30,10 @@
bleed_rate = 0
return
if(bodytemperature >= TCRYO && !(has_trait(TRAIT_NOCLONE))) //cryosleep or husked people do not pump the blood.
if(bodytemperature >= TCRYO && !(HAS_TRAIT(src, TRAIT_NOCLONE))) //cryosleep or husked people do not pump the blood.
//Blood regeneration if there is some space
if(blood_volume < BLOOD_VOLUME_NORMAL && !has_trait(TRAIT_NOHUNGER))
if(blood_volume < BLOOD_VOLUME_NORMAL && !HAS_TRAIT(src, TRAIT_NOHUNGER))
var/nutrition_ratio = 0
switch(nutrition)
if(0 to NUTRITION_LEVEL_STARVING)
@@ -69,7 +69,7 @@
Unconscious(rand(20,60))
to_chat(src, "<span class='warning'>You feel extremely [word].</span>")
if(-INFINITY to BLOOD_VOLUME_SURVIVE)
if(!has_trait(TRAIT_NODEATH))
if(!HAS_TRAIT(src, TRAIT_NODEATH))
death()
var/temp_bleed = 0
@@ -87,7 +87,7 @@
bleed_rate = max(bleed_rate - 0.5, temp_bleed)//if no wounds, other bleed effects (heparin) naturally decreases
if(bleed_rate && !bleedsuppress && !(has_trait(TRAIT_FAKEDEATH)))
if(bleed_rate && !bleedsuppress && !(HAS_TRAIT(src, TRAIT_FAKEDEATH)))
bleed(bleed_rate)
//Makes a blood drop, leaking amt units of blood from the mob
@@ -214,13 +214,13 @@
return "blood"
/mob/living/carbon/monkey/get_blood_id()
if(!(has_trait(TRAIT_NOCLONE)))
if(!(HAS_TRAIT(src, TRAIT_NOCLONE)))
return "blood"
/mob/living/carbon/human/get_blood_id()
if(dna.species.exotic_blood)
return dna.species.exotic_blood
else if((NOBLOOD in dna.species.species_traits) || (has_trait(TRAIT_NOCLONE)))
else if((NOBLOOD in dna.species.species_traits) || (HAS_TRAIT(src, TRAIT_NOCLONE)))
return
return "blood"
+5 -1
View File
@@ -138,7 +138,11 @@
name = "blood crawl"
desc = "You are unable to hold anything while in this form."
icon = 'icons/effects/blood.dmi'
item_flags = NODROP | ABSTRACT
item_flags = ABSTRACT
/obj/item/bloodcrawl/Initialize()
. = ..()
ADD_TRAIT(src, TRAIT_NODROP, ABSTRACT_ITEM_TRAIT)
/mob/living/proc/exit_blood_effect(obj/effect/decal/cleanable/B)
playsound(get_turf(src), 'sound/magic/exit_blood.ogg', 100, 1, -1)
+1
View File
@@ -5,6 +5,7 @@
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
speech_span = SPAN_ROBOT
/mob/living/brain/Initialize()
. = ..()
+4 -4
View File
@@ -21,7 +21,7 @@
name = "brain"
if(C.mind && C.mind.has_antag_datum(/datum/antagonist/changeling) && !no_id_transfer) //congrats, you're trapped in a body you don't control
if(brainmob && !(C.stat == DEAD || (C.has_trait(TRAIT_DEATHCOMA))))
if(brainmob && !(C.stat == DEAD || (HAS_TRAIT(C, TRAIT_DEATHCOMA))))
to_chat(brainmob, "<span class = danger>You can't feel your body! You're still just a brain!</span>")
forceMove(C)
C.update_hair()
@@ -64,7 +64,7 @@
name = "[L.name]'s brain"
if(brainmob)
return
if(!L.mind)
return
brainmob = new(src)
@@ -76,7 +76,7 @@
if(!brainmob.stored_dna)
brainmob.stored_dna = new /datum/dna/stored(brainmob)
C.dna.copy_dna(brainmob.stored_dna)
if(L.has_trait(TRAIT_NOCLONE))
if(HAS_TRAIT(L, TRAIT_NOCLONE))
brainmob.status_traits[TRAIT_NOCLONE] = L.status_traits[TRAIT_NOCLONE]
var/obj/item/organ/zombie_infection/ZI = L.getorganslot(ORGAN_SLOT_ZOMBIE)
if(ZI)
@@ -265,7 +265,7 @@
var/list/datum/brain_trauma/possible_traumas = list()
for(var/T in subtypesof(brain_trauma_type))
var/datum/brain_trauma/BT = T
if(can_gain_trauma(BT, resilience))
if(can_gain_trauma(BT, resilience) && initial(BT.random_gain))
possible_traumas += BT
if(!LAZYLEN(possible_traumas))
+1 -4
View File
@@ -10,14 +10,11 @@
..()
/mob/living/brain/get_spans()
return ..() | SPAN_ROBOT
/mob/living/brain/radio(message, message_mode, list/spans, language)
if(message_mode == MODE_HEADSET && istype(container, /obj/item/mmi))
var/obj/item/mmi/R = container
if(R.radio)
R.radio.talk_into(src, message, , get_spans(), language)
R.radio.talk_into(src, message, language = language)
return ITALICS | REDUCE_RANGE
else
return ..()
@@ -105,7 +105,7 @@ Des: Gives the client of the alien an image on each infected mob.
if (client)
for (var/i in GLOB.mob_living_list)
var/mob/living/L = i
if(L.has_trait(TRAIT_XENO_HOST))
if(HAS_TRAIT(L, TRAIT_XENO_HOST))
var/obj/item/organ/body_egg/alien_embryo/A = L.getorgan(/obj/item/organ/body_egg/alien_embryo)
if(A)
var/I = image('icons/mob/alien.dmi', loc = L, icon_state = "infected[A.stage]")
@@ -103,9 +103,13 @@
name = "\improper royal parasite"
desc = "Inject this into one of your grown children to promote her to a Praetorian!"
icon_state = "alien_medal"
item_flags = ABSTRACT | NODROP | DROPDEL
item_flags = ABSTRACT | DROPDEL
icon = 'icons/mob/alien.dmi'
/obj/item/queenpromote/Initialize()
. = ..()
ADD_TRAIT(src, TRAIT_NODROP, ABSTRACT_ITEM_TRAIT)
/obj/item/queenpromote/attack(mob/living/M, mob/living/carbon/alien/humanoid/user)
if(!isalienadult(M) || isalienroyal(M))
to_chat(user, "<span class='noticealien'>You may only use this with your adult, non-royal children!</span>")
@@ -18,7 +18,7 @@
if(health<= -maxHealth || !getorgan(/obj/item/organ/brain))
death()
return
if(IsUnconscious() || IsSleeping() || getOxyLoss() > 50 || (has_trait(TRAIT_DEATHCOMA)) || health <= crit_threshold)
if(IsUnconscious() || IsSleeping() || getOxyLoss() > 50 || (HAS_TRAIT(src, TRAIT_DEATHCOMA)) || health <= crit_threshold)
if(stat == CONSCIOUS)
stat = UNCONSCIOUS
blind_eyes(1)
+6 -8
View File
@@ -15,25 +15,23 @@
var/breath_pressure = (breath.total_moles()*R_IDEAL_GAS_EQUATION*breath.temperature)/BREATH_VOLUME
var/list/breath_gases = breath.gases
breath.assert_gases(/datum/gas/plasma, /datum/gas/oxygen)
//Partial pressure of the toxins in our breath
var/Toxins_pp = (breath_gases[/datum/gas/plasma][MOLES]/breath.total_moles())*breath_pressure
var/Toxins_pp = (breath_gases[/datum/gas/plasma]/breath.total_moles())*breath_pressure
if(Toxins_pp > tox_detect_threshold) // Detect toxins in air
adjustPlasma(breath_gases[/datum/gas/plasma][MOLES]*250)
adjustPlasma(breath_gases[/datum/gas/plasma]*250)
throw_alert("alien_tox", /obj/screen/alert/alien_tox)
toxins_used = breath_gases[/datum/gas/plasma][MOLES]
toxins_used = breath_gases[/datum/gas/plasma]
else
clear_alert("alien_tox")
//Breathe in toxins and out oxygen
breath_gases[/datum/gas/plasma][MOLES] -= toxins_used
breath_gases[/datum/gas/oxygen][MOLES] += toxins_used
breath_gases[/datum/gas/plasma] -= toxins_used
breath_gases[/datum/gas/oxygen] += toxins_used
breath.garbage_collect()
GAS_GARBAGE_COLLECT(breath.gases)
//BREATH TEMPERATURE
handle_breath_temperature(breath)
+1 -1
View File
@@ -4,7 +4,7 @@
if(!message)
return
var/message_a = say_quote(message, get_spans())
var/message_a = say_quote(message)
var/rendered = "<i><span class='alien'>Hivemind, <span class='name'>[shown_name]</span> <span class='message'>[message_a]</span></span></i>"
for(var/mob/S in GLOB.player_list)
if(!S.stat && S.hivecheck())
+18 -10
View File
@@ -167,7 +167,7 @@
if(!throwable_mob.buckled)
thrown_thing = throwable_mob
stop_pulling()
if(has_trait(TRAIT_PACIFISM))
if(HAS_TRAIT(src, TRAIT_PACIFISM))
to_chat(src, "<span class='notice'>You gently let go of [throwable_mob].</span>")
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
@@ -175,11 +175,11 @@
if(start_T && end_T)
log_combat(src, throwable_mob, "thrown", addition="grab from tile in [AREACOORD(start_T)] towards tile at [AREACOORD(end_T)]")
else if(!(I.item_flags & (NODROP | ABSTRACT)))
else if(!CHECK_BITFIELD(I.item_flags, ABSTRACT) && !HAS_TRAIT(I, TRAIT_NODROP))
thrown_thing = I
dropItemToGround(I)
if(has_trait(TRAIT_PACIFISM) && I.throwforce)
if(HAS_TRAIT(src, TRAIT_PACIFISM) && I.throwforce)
to_chat(src, "<span class='notice'>You set [I] down gently on the ground.</span>")
return
@@ -409,14 +409,14 @@
return initial(pixel_y)
/mob/living/carbon/proc/accident(obj/item/I)
if(!I || (I.item_flags & (NODROP | ABSTRACT)))
if(!I || (I.item_flags & ABSTRACT) || HAS_TRAIT(I, TRAIT_NODROP))
return
//dropItemToGround(I) CIT CHANGE - makes it so the item doesn't drop if the modifier rolls above 100
var/modifier = 0
if(has_trait(TRAIT_CLUMSY))
if(HAS_TRAIT(src, TRAIT_CLUMSY))
modifier -= 40 //Clumsy people are more likely to hit themselves -Honk!
//CIT CHANGES START HERE
@@ -462,7 +462,7 @@
return ..()
/mob/living/carbon/proc/vomit(lost_nutrition = 10, blood = FALSE, stun = TRUE, distance = 1, message = TRUE, toxic = FALSE)
if(has_trait(TRAIT_NOHUNGER))
if(HAS_TRAIT(src, TRAIT_NOHUNGER))
return 1
if(nutrition < 100 && !blood)
@@ -496,9 +496,12 @@
add_splatter_floor(T)
if(stun)
adjustBruteLoss(3)
else if(src.reagents.has_reagent("blazaam"))
if(T)
T.add_vomit_floor(src, VOMIT_PURPLE)
else
if(T)
T.add_vomit_floor(src, toxic)//toxic barf looks different
T.add_vomit_floor(src, VOMIT_TOXIC)//toxic barf looks different
T = get_step(T, dir)
if (is_blocked_turf(T))
break
@@ -759,14 +762,14 @@
if(status_flags & GODMODE)
return
if(stat != DEAD)
if(health <= HEALTH_THRESHOLD_DEAD && !has_trait(TRAIT_NODEATH))
if(health <= HEALTH_THRESHOLD_DEAD && !HAS_TRAIT(src, TRAIT_NODEATH))
death()
return
if(IsUnconscious() || IsSleeping() || getOxyLoss() > 50 || (has_trait(TRAIT_DEATHCOMA)) || (health <= HEALTH_THRESHOLD_FULLCRIT && !has_trait(TRAIT_NOHARDCRIT)))
if(IsUnconscious() || IsSleeping() || getOxyLoss() > 50 || (HAS_TRAIT(src, TRAIT_DEATHCOMA)) || (health <= HEALTH_THRESHOLD_FULLCRIT && !HAS_TRAIT(src, TRAIT_NOHARDCRIT)))
stat = UNCONSCIOUS
blind_eyes(1)
else
if(health <= crit_threshold && !has_trait(TRAIT_NOSOFTCRIT))
if(health <= crit_threshold && !HAS_TRAIT(src, TRAIT_NOSOFTCRIT))
stat = SOFT_CRIT
else
stat = CONSCIOUS
@@ -895,6 +898,11 @@
var/obj/item/organ/I = X
I.Insert(src)
/mob/living/carbon/proc/update_disabled_bodyparts()
for(var/B in bodyparts)
var/obj/item/bodypart/BP = B
BP.update_disabled()
/mob/living/carbon/vv_get_dropdown()
. = ..()
. += "---"
@@ -48,18 +48,27 @@
if(affecting && affecting.dismemberable && affecting.get_damage() >= (affecting.max_damage - P.dismemberment))
affecting.dismember(P.damtype)
/mob/living/carbon/proc/can_catch_item(skip_throw_mode_check)
. = FALSE
if(!skip_throw_mode_check && !in_throw_mode)
return
if(get_active_held_item())
return
if(restrained())
return
return TRUE
/mob/living/carbon/hitby(atom/movable/AM, skipcatch, hitpush = TRUE, blocked = FALSE)
if(!skipcatch) //ugly, but easy
if(in_throw_mode && !get_active_held_item()) //empty active hand and we're in throw mode
if(canmove && !restrained())
if(istype(AM, /obj/item))
var/obj/item/I = AM
if(isturf(I.loc))
I.attack_hand(src)
if(get_active_held_item() == I) //if our attack_hand() picks up the item...
visible_message("<span class='warning'>[src] catches [I]!</span>") //catch that sucker!
throw_mode_off()
return 1
if(can_catch_item())
if(istype(AM, /obj/item))
var/obj/item/I = AM
if(isturf(I.loc))
I.attack_hand(src)
if(get_active_held_item() == I) //if our attack_hand() picks up the item...
visible_message("<span class='warning'>[src] catches [I]!</span>") //catch that sucker!
throw_mode_off()
return 1
..()
@@ -224,7 +233,7 @@
/mob/living/carbon/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = 0, override = 0, tesla_shock = 0, illusion = 0, stun = TRUE)
if(tesla_shock && (flags_1 & TESLA_IGNORE_1))
return FALSE
if(has_trait(TRAIT_SHOCKIMMUNE))
if(HAS_TRAIT(src, TRAIT_SHOCKIMMUNE))
return FALSE
shock_damage *= siemens_coeff
if(dna && dna.species)
@@ -261,7 +270,7 @@
to_chat(M, "<span class='warning'>You can't put [p_them()] out with just your bare hands!</span>")
return
if(health >= 0 && !(has_trait(TRAIT_FAKEDEATH)))
if(health >= 0 && !(HAS_TRAIT(src, TRAIT_FAKEDEATH)))
if(lying)
if(buckled)
@@ -277,6 +286,12 @@
M.visible_message("<span class='notice'>[M] gives [H] a pat on the head to make [p_them()] feel better!</span>", \
"<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)
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)
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "friendly_hug", /datum/mood_event/betterhug, M)
if(H.dna.species.can_wag_tail(H))
if("tail_human" in pref_species.default_features)
if(H.dna.features["tail_human"] == "None")
@@ -306,6 +321,12 @@
M.visible_message("<span class='notice'>[M] hugs [src] to make [p_them()] feel better!</span>", \
"<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)
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)
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "friendly_hug", /datum/mood_event/betterhug, M)
AdjustStun(-60)
AdjustKnockdown(-60)
@@ -350,12 +371,12 @@
if(eyes.eye_damage > 20)
if(prob(eyes.eye_damage - 20))
if(!has_trait(TRAIT_NEARSIGHT))
if(!HAS_TRAIT(src, TRAIT_NEARSIGHT))
to_chat(src, "<span class='warning'>Your eyes start to burn badly!</span>")
become_nearsighted(EYE_DAMAGE)
else if(prob(eyes.eye_damage - 25))
if(!has_trait(TRAIT_BLIND))
if(!HAS_TRAIT(src, TRAIT_BLIND))
to_chat(src, "<span class='warning'>You can't see anything!</span>")
become_blind(EYE_DAMAGE)
@@ -37,7 +37,7 @@
/mob/living/carbon/Move(NewLoc, direct)
. = ..()
if(. && mob_has_gravity()) //floating is easy
if(has_trait(TRAIT_NOHUNGER))
if(HAS_TRAIT(src, TRAIT_NOHUNGER))
nutrition = NUTRITION_LEVEL_FED - 1 //just less than feeling vigorous
else if(nutrition && stat != DEAD)
nutrition -= HUNGER_FACTOR/10
@@ -83,7 +83,7 @@
return amount
/mob/living/carbon/adjustToxLoss(amount, updating_health = TRUE, forced = FALSE)
if(!forced && has_trait(TRAIT_TOXINLOVER)) //damage becomes healing and healing becomes damage
if(!forced && HAS_TRAIT(src, TRAIT_TOXINLOVER)) //damage becomes healing and healing becomes damage
amount = -amount
if(amount > 0)
blood_volume -= 5*amount
+2 -2
View File
@@ -67,7 +67,7 @@
else
msg += "<b>[t_He] [t_is] severely deformed!</b>\n"
if(has_trait(TRAIT_DUMB))
if(HAS_TRAIT(src, TRAIT_DUMB))
msg += "[t_He] seem[p_s()] to be clumsy and unable to think.\n"
if(fire_stacks > 0)
@@ -88,7 +88,7 @@
if(digitalcamo)
msg += "[t_He] [t_is] moving [t_his] body in an unnatural and blatantly unsimian manner.\n"
if(combatmode)
msg += "[t_He] [t_is] visibly tense[resting ? "." : ", and [t_is] standing in combative stance."]\n"
@@ -42,13 +42,13 @@
INVOKE_ASYNC(is_devil(src), /datum/antagonist/devil.proc/beginResurrectionCheck, src)
/mob/living/carbon/human/proc/makeSkeleton()
add_trait(TRAIT_DISFIGURED, TRAIT_GENERIC)
ADD_TRAIT(src, TRAIT_DISFIGURED, TRAIT_GENERIC)
set_species(/datum/species/skeleton)
return 1
/mob/living/carbon/proc/Drain()
become_husk(CHANGELING_DRAIN)
add_trait(TRAIT_NOCLONE, CHANGELING_DRAIN)
ADD_TRAIT(src, TRAIT_NOCLONE, CHANGELING_DRAIN)
blood_volume = 0
return 1
@@ -10,7 +10,7 @@
if(isliving(user))
var/mob/living/L = user
if(L.has_trait(TRAIT_PROSOPAGNOSIA))
if(HAS_TRAIT(L, TRAIT_PROSOPAGNOSIA))
obscure_name = TRUE
var/msg = "<span class='info'>*---------*\nThis is <EM>[!obscure_name ? name : "Unknown"]</EM>!\n"
@@ -93,7 +93,7 @@
if(!(SLOT_GLASSES in obscured))
if(glasses)
msg += "[t_He] [t_has] [glasses.get_examine_string(user)] covering [t_his] eyes.\n"
else if(eye_color == BLOODCULT_EYE && iscultist(src) && has_trait(CULT_EYES))
else if(eye_color == BLOODCULT_EYE && iscultist(src) && HAS_TRAIT(src, TRAIT_CULT_EYES))
msg += "<span class='warning'><B>[t_His] eyes are glowing an unnatural red!</B></span>\n"
//ears
@@ -126,7 +126,7 @@
msg += "<span class='warning'>[t_He] [t_is] twitching ever so slightly.</span>\n"
var/appears_dead = 0
if(stat == DEAD || (has_trait(TRAIT_FAKEDEATH)))
if(stat == DEAD || (HAS_TRAIT(src, TRAIT_FAKEDEATH)))
appears_dead = 1
if(suiciding)
msg += "<span class='warning'>[t_He] appear[p_s()] to have committed suicide... there is no hope of recovery.</span>\n"
@@ -281,13 +281,34 @@
if(91.01 to INFINITY)
msg += "[t_He] [t_is] a shitfaced, slobbering wreck.\n"
if(isliving(user))
var/mob/living/L = user
if(src != user && HAS_TRAIT(L, TRAIT_EMPATH) && !appears_dead)
if (a_intent != INTENT_HELP)
msg += "[t_He] seem[p_s()] to be on guard.\n"
if (getOxyLoss() >= 10)
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)
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)
if(mood.shown_mood >= 6) //So roundstart people aren't all "happy" and that antags don't show their true happiness.
msg += "[t_He] seem[p_s()] to have had something nice happen to them recently.\n"
SEND_SIGNAL(user, COMSIG_ADD_MOOD_EVENT, "empathH", /datum/mood_event/happy_empath, src)
if (HAS_TRAIT(src, TRAIT_BLIND))
msg += "[t_He] appear[p_s()] to be staring off into space.\n"
if (HAS_TRAIT(src, TRAIT_DEAF))
msg += "[t_He] appear[p_s()] to not be responding to noises.\n"
msg += "</span>"
if(!appears_dead)
if(stat == UNCONSCIOUS)
msg += "[t_He] [t_is]n't responding to anything around [t_him] and seem[p_s()] to be asleep.\n"
else
if(has_trait(TRAIT_DUMB))
if(HAS_TRAIT(src, TRAIT_DUMB))
msg += "[t_He] [t_has] a stupid expression on [t_his] face.\n"
if(InCritical())
msg += "[t_He] [t_is] barely conscious.\n"
+17 -11
View File
@@ -8,6 +8,7 @@
/mob/living/carbon/human/Initialize()
verbs += /mob/living/proc/mob_sleep
verbs += /mob/living/proc/lay_down
verbs += /mob/living/carbon/human/proc/underwear_toggle //fwee
//initialize limbs first
create_bodyparts()
@@ -251,7 +252,7 @@
var/delay_denominator = 1
if(pocket_item && !(pocket_item.item_flags & ABSTRACT))
if(pocket_item.item_flags & NODROP)
if(HAS_TRAIT(pocket_item, TRAIT_NODROP))
to_chat(usr, "<span class='warning'>You try to empty [src]'s [pocket_side] pocket, it seems to be stuck!</span>")
to_chat(usr, "<span class='notice'>You try to empty [src]'s [pocket_side] pocket.</span>")
else if(place_item && place_item.mob_can_equip(src, usr, pocket_id, 1) && !(place_item.item_flags & ABSTRACT))
@@ -260,7 +261,7 @@
else
return
if(do_mob(usr, src, POCKET_STRIP_DELAY/delay_denominator)) //placing an item into the pocket is 4 times faster
if(do_mob(usr, src, POCKET_STRIP_DELAY/delay_denominator, ignorehelditem = TRUE)) //placing an item into the pocket is 4 times faster
if(pocket_item)
if(pocket_item == (pocket_id == SLOT_R_STORE ? r_store : l_store)) //item still in the pocket we search
dropItemToGround(pocket_item)
@@ -499,7 +500,7 @@
. = 1 // Default to returning true.
if(user && !target_zone)
target_zone = user.zone_selected
if(has_trait(TRAIT_PIERCEIMMUNE) && !bypass_immunity)
if(HAS_TRAIT(src, TRAIT_PIERCEIMMUNE) && !bypass_immunity)
. = 0
// If targeting the head, see if the head item is thin enough.
// If targeting anything else, see if the wear suit is thin enough.
@@ -604,7 +605,7 @@
threatcount += 4 //fuk u antags <3 //no you
//mindshield implants imply trustworthyness
if(has_trait(TRAIT_MINDSHIELD))
if(HAS_TRAIT(src, TRAIT_MINDSHIELD))
threatcount -= 1
//Agent cards lower threatlevel.
@@ -640,7 +641,7 @@
/mob/living/carbon/human/proc/do_cpr(mob/living/carbon/C)
CHECK_DNA_AND_SPECIES(C)
if(C.stat == DEAD || (C.has_trait(TRAIT_FAKEDEATH)))
if(C.stat == DEAD || (HAS_TRAIT(C, TRAIT_FAKEDEATH)))
to_chat(src, "<span class='warning'>[C.name] is dead!</span>")
return
if(is_mouth_covered())
@@ -657,7 +658,7 @@
to_chat(src, "<span class='warning'>You fail to perform CPR on [C]!</span>")
return 0
var/they_breathe = !C.has_trait(TRAIT_NOBREATH)
var/they_breathe = !HAS_TRAIT(C, TRAIT_NOBREATH)
var/they_lung = C.getorganslot(ORGAN_SLOT_LUNGS)
if(C.health > C.crit_threshold)
@@ -724,12 +725,12 @@
remove_atom_colour(TEMPORARY_COLOUR_PRIORITY, "#000000")
cut_overlay(MA)
/mob/living/carbon/human/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE)
/mob/living/carbon/human/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE, no_tk=FALSE)
if(incapacitated() || lying )
to_chat(src, "<span class='warning'>You can't do that right now!</span>")
return FALSE
if(!Adjacent(M) && (M.loc != src))
if((be_close == 0) || (dna.check_mutation(TK) && tkMaxRangeCheck(src, M)))
if((be_close == 0) || (!no_tk && (dna.check_mutation(TK) && tkMaxRangeCheck(src, M))))
return TRUE
to_chat(src, "<span class='warning'>You are too far away!</span>")
return FALSE
@@ -851,19 +852,24 @@
/mob/living/carbon/human/MouseDrop_T(mob/living/target, mob/living/user)
//If they dragged themselves and we're currently aggressively grabbing them try to piggyback
if(user == target && can_piggyback(target) && pulling == target && grab_state >= GRAB_AGGRESSIVE && stat == CONSCIOUS)
if(user == target && can_piggyback(target) && pulling == target && (HAS_TRAIT(src, TRAIT_PACIFISM) || grab_state >= GRAB_AGGRESSIVE) && stat == CONSCIOUS)
buckle_mob(target,TRUE,TRUE)
. = ..()
/mob/living/carbon/human/proc/piggyback_instant(mob/living/M)
return buckle_mob(M, TRUE, TRUE, FALSE, TRUE)
//Can C try to piggyback at all.
/mob/living/carbon/human/proc/can_piggyback(mob/living/carbon/C)
if(istype(C) && C.stat == CONSCIOUS)
return TRUE
return FALSE
/mob/living/carbon/human/buckle_mob(mob/living/M, force = FALSE, check_loc = TRUE)
/mob/living/carbon/human/buckle_mob(mob/living/M, force = FALSE, check_loc = TRUE, bypass_piggybacking = FALSE, no_delay = FALSE)
if(!force)//humans are only meant to be ridden through piggybacking and special cases
return
if(bypass_piggybacking)
return ..()
if(!is_type_in_typecache(M, can_ride_typecache))
M.visible_message("<span class='warning'>[M] really can't seem to mount [src]...</span>")
return
@@ -876,7 +882,7 @@
if(can_piggyback(M))
riding_datum.ride_check_ridden_incapacitated = TRUE
visible_message("<span class='notice'>[M] starts to climb onto [src]...</span>")
if(do_after(M, 15, target = src))
if(no_delay || do_after(M, 15, target = src))
if(can_piggyback(M))
if(M.incapacitated(FALSE, TRUE) || incapacitated(FALSE, TRUE))
M.visible_message("<span class='warning'>[M] can't hang onto [src]!</span>")
@@ -54,7 +54,12 @@
else
visible_message("<span class='danger'>[src] deflects the projectile!</span>", "<span class='userdanger'>You deflect the projectile!</span>")
playsound(src, pick('sound/weapons/bulletflyby.ogg', 'sound/weapons/bulletflyby2.ogg', 'sound/weapons/bulletflyby3.ogg'), 75, 1)
return 0
if(!mind.martial_art.reroute_deflection)
return FALSE
else
P.firer = src
P.setAngle(rand(0, 360))//SHING
return FALSE
if(!(P.original == src && P.firer == src)) //can't block or reflect when shooting yourself
if(P.is_reflectable)
@@ -138,7 +143,7 @@
else if(I)
if(I.throw_speed >= EMBED_THROWSPEED_THRESHOLD)
if(can_embed(I))
if(prob(I.embedding.embed_chance) && !has_trait(TRAIT_PIERCEIMMUNE))
if(prob(I.embedding.embed_chance) && !HAS_TRAIT(src, TRAIT_PIERCEIMMUNE))
throw_alert("embeddedobject", /obj/screen/alert/embeddedobject)
var/obj/item/bodypart/L = pick(bodyparts)
L.embedded_objects |= I
@@ -153,7 +158,7 @@
return ..()
/mob/living/carbon/human/grabbedby(mob/living/carbon/user, supress_message = 0)
if(user == src && pulling && !pulling.anchored && grab_state >= GRAB_AGGRESSIVE && (has_trait(TRAIT_FAT)) && ismonkey(pulling))
if(user == src && pulling && !pulling.anchored && grab_state >= GRAB_AGGRESSIVE && (HAS_TRAIT(src, TRAIT_FAT)) && ismonkey(pulling))
devour_mob(pulling)
else
..()
@@ -256,7 +261,7 @@
var/obj/item/bodypart/affecting = get_bodypart(ran_zone(M.zone_selected))
if(!affecting)
affecting = get_bodypart(BODY_ZONE_CHEST)
var/armor_block = run_armor_check(affecting, "melee","","",10)
var/armor_block = run_armor_check(affecting, "melee", null, null,10)
playsound(loc, 'sound/weapons/slice.ogg', 25, 1, -1)
visible_message("<span class='danger'>[M] has slashed at [src]!</span>", \
@@ -614,7 +619,7 @@
facial_hair_style = "Shaved"
hair_style = "Bald"
update_hair()
add_trait(TRAIT_DISFIGURED, TRAIT_GENERIC)
ADD_TRAIT(src, TRAIT_DISFIGURED, TRAIT_GENERIC)
update_damage_overlays()
@@ -669,7 +674,7 @@
if(prob(30))
burndamage += rand(30,40)
if(has_trait(TRAIT_SELF_AWARE))
if(HAS_TRAIT(src, TRAIT_SELF_AWARE))
status = "[brutedamage] brute damage and [burndamage] burn damage"
if(!brutedamage && !burndamage)
status = "no damage"
@@ -696,7 +701,7 @@
var/no_damage
if(status == "OK" || status == "no damage")
no_damage = TRUE
to_send += "\t <span class='[no_damage ? "notice" : "warning"]'>Your [LB.name] [has_trait(TRAIT_SELF_AWARE) ? "has" : "is"] [status].</span>\n"
to_send += "\t <span class='[no_damage ? "notice" : "warning"]'>Your [LB.name] [HAS_TRAIT(src, TRAIT_SELF_AWARE) ? "has" : "is"] [status].</span>\n"
for(var/obj/item/I in LB.embedded_objects)
to_send += "\t <a href='?src=[REF(src)];embedded_object=[REF(I)];embedded_limb=[REF(LB)]' class='warning'>There is \a [I] embedded in your [LB.name]!</a>\n"
@@ -711,7 +716,7 @@
to_send += "<span class='info'>You're completely exhausted.</span>\n"
else
to_send += "<span class='info'>You feel fatigued.</span>\n"
if(has_trait(TRAIT_SELF_AWARE))
if(HAS_TRAIT(src, TRAIT_SELF_AWARE))
if(toxloss)
if(toxloss > 10)
to_send += "<span class='danger'>You feel sick.</span>\n"
@@ -751,7 +756,7 @@
else if(w_uniform)
w_uniform.add_fingerprint(M)
..()
..()
/mob/living/carbon/human/damage_clothes(damage_amount, damage_type = BRUTE, damage_flag = 0, def_zone)
@@ -22,11 +22,14 @@
var/lip_style = null //no lipstick by default- arguably misleading, as it could be used for general makeup
var/lip_color = "white"
var/age = 30 //Player's age (pure fluff)
var/age = 30 //Player's age
var/underwear = "Nude" //Which underwear the player wants
var/undie_color = "#FFFFFF"
var/undershirt = "Nude" //Which undershirt the player wants
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.
//Equipment slots
@@ -56,7 +56,7 @@
if( head && (head.flags_inv&HIDEFACE) )
return if_no_face //Likewise for hats
var/obj/item/bodypart/O = get_bodypart(BODY_ZONE_HEAD)
if( !O || (has_trait(TRAIT_DISFIGURED)) || (O.brutestate+O.burnstate)>2 || cloneloss>50 || !real_name || nameless) //disfigured. use id-name if possible
if( !O || (HAS_TRAIT(src, TRAIT_DISFIGURED)) || (O.brutestate+O.burnstate)>2 || cloneloss>50 || !real_name || nameless) //disfigured. use id-name if possible
return if_no_face
return real_name
@@ -92,7 +92,7 @@
/mob/living/carbon/human/IsAdvancedToolUser()
if(has_trait(TRAIT_MONKEYLIKE))
if(HAS_TRAIT(src, TRAIT_MONKEYLIKE))
return FALSE
return TRUE//Humans can use guns and such
@@ -138,7 +138,7 @@
if(src.dna.check_mutation(HULK))
to_chat(src, "<span class='warning'>Your meaty finger is much too large for the trigger guard!</span>")
return FALSE
if(has_trait(TRAIT_NOGUNS))
if(HAS_TRAIT(src, TRAIT_NOGUNS))
to_chat(src, "<span class='warning'>Your fingers don't fit in the trigger guard!</span>")
return FALSE
if(mind)
@@ -1,7 +1,7 @@
/mob/living/carbon/human/get_movespeed_modifiers()
var/list/considering = ..()
. = considering
if(has_trait(TRAIT_IGNORESLOWDOWN))
if(HAS_TRAIT(src, TRAIT_IGNORESLOWDOWN))
for(var/id in .)
var/list/data = .[id]
if(data[MOVESPEED_DATA_INDEX_FLAGS] & IGNORE_NOSLOW)
@@ -13,10 +13,10 @@
. += dna.species.movement_delay(src)
/mob/living/carbon/human/slip(knockdown_amount, obj/O, lube)
if(has_trait(TRAIT_NOSLIPALL))
if(HAS_TRAIT(src, TRAIT_NOSLIPALL))
return 0
if (!(lube&GALOSHES_DONT_HELP))
if(has_trait(TRAIT_NOSLIPWATER))
if(HAS_TRAIT(src, TRAIT_NOSLIPWATER))
return 0
if(shoes && istype(shoes, /obj/item/clothing))
var/obj/item/clothing/CS = shoes
@@ -187,7 +187,7 @@
if(G.tint)
update_tint()
if(G.vision_correction)
if(has_trait(TRAIT_NEARSIGHT))
if(HAS_TRAIT(src, TRAIT_NEARSIGHT))
overlay_fullscreen("nearsighted", /obj/screen/fullscreen/impaired, 1)
adjust_eye_damage(0)
if(G.vision_flags || G.darkness_view || G.invis_override || G.invis_view || !isnull(G.lighting_alpha))
+3 -3
View File
@@ -63,7 +63,7 @@
/mob/living/carbon/human/handle_traits()
if(eye_blind) //blindness, heals slowly over time
if(has_trait(TRAIT_BLIND, EYES_COVERED)) //covering your eyes heals blurry eyes faster
if(HAS_TRAIT_FROM(src, TRAIT_BLIND, EYES_COVERED)) //covering your eyes heals blurry eyes faster
adjust_blindness(-3)
else
adjust_blindness(-1)
@@ -95,7 +95,7 @@
if(!L)
if(health >= crit_threshold)
adjustOxyLoss(HUMAN_MAX_OXYLOSS + 1)
else if(!has_trait(TRAIT_NOCRITDAMAGE))
else if(!HAS_TRAIT(src, TRAIT_NOCRITDAMAGE))
adjustOxyLoss(HUMAN_CRIT_MAX_OXYLOSS)
failed_last_breath = 1
@@ -332,7 +332,7 @@
HM.on_life(src)
/mob/living/carbon/human/proc/handle_heart()
var/we_breath = !has_trait(TRAIT_NOBREATH, SPECIES_TRAIT)
var/we_breath = !HAS_TRAIT_FROM(src, TRAIT_NOBREATH, SPECIES_TRAIT)
if(!undergoing_cardiac_arrest())
return
+1 -24
View File
@@ -10,29 +10,6 @@
else
. = ..()
/mob/living/carbon/human/treat_message(message)
message = dna.species.handle_speech(message,src)
if(diseases.len)
for(var/datum/disease/pierrot_throat/D in diseases)
var/list/temp_message = splittext(message, " ") //List each word in the message
var/list/pick_list = list()
for(var/i = 1, i <= temp_message.len, i++) //Create a second list for excluding words down the line
pick_list += i
for(var/i=1, ((i <= D.stage) && (i <= temp_message.len)), i++) //Loop for each stage of the disease or until we run out of words
if(prob(3 * D.stage)) //Stage 1: 3% Stage 2: 6% Stage 3: 9% Stage 4: 12%
var/H = pick(pick_list)
if(findtext(temp_message[H], "*") || findtext(temp_message[H], ";") || findtext(temp_message[H], ":"))
continue
temp_message[H] = "HONK"
pick_list -= H //Make sure that you dont HONK the same word twice
message = jointext(temp_message, " ")
message = ..(message)
message = dna.mutations_say_mods(message)
return message
/mob/living/carbon/human/get_spans()
return ..() | dna.mutations_get_spans() | dna.species_get_spans()
/mob/living/carbon/human/GetVoice()
if(istype(wear_mask, /obj/item/clothing/mask/chameleon))
var/obj/item/clothing/mask/chameleon/V = wear_mask
@@ -54,7 +31,7 @@
/mob/living/carbon/human/IsVocal()
// how do species that don't breathe talk? magic, that's what.
if(!has_trait(TRAIT_NOBREATH, SPECIES_TRAIT) && !getorganslot(ORGAN_SLOT_LUNGS))
if(!HAS_TRAIT_FROM(src, TRAIT_NOBREATH, SPECIES_TRAIT) && !getorganslot(ORGAN_SLOT_LUNGS))
return FALSE
if(mind)
return !mind.miming
+138 -82
View File
@@ -44,6 +44,8 @@ GLOBAL_LIST_EMPTY(roundstart_races)
var/siemens_coeff = 1 //base electrocution coefficient
var/damage_overlay_type = "human" //what kind of damage overlays (if any) appear on our species when wounded?
var/fixed_mut_color = "" //to use MUTCOLOR with a fixed color that's independent of dna.feature["mcolor"]
var/list/special_step_sounds //Sounds to override barefeet walkng
var/grab_sound //Special sound for grabbing
// species-only traits. Can be found in DNA.dm
var/list/species_traits = list()
@@ -277,7 +279,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
if(mutanthands)
// Drop items in hands
// If you're lucky enough to have a NODROP_1 item, then it stays.
// If you're lucky enough to have a TRAIT_NODROP item, then it stays.
for(var/V in C.held_items)
var/obj/item/I = V
if(istype(I))
@@ -286,7 +288,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
C.put_in_hands(new mutanthands())
for(var/X in inherent_traits)
C.add_trait(X, SPECIES_TRAIT)
ADD_TRAIT(C, X, SPECIES_TRAIT)
if(TRAIT_VIRUSIMMUNE in inherent_traits)
for(var/datum/disease/A in C.diseases)
@@ -300,6 +302,11 @@ GLOBAL_LIST_EMPTY(roundstart_races)
else
if(C.client)
C.canbearoused = C.client.prefs.arousable
if(ishuman(C))
var/mob/living/carbon/human/H = C
if(NOGENITALS in H.dna.species.species_traits)
H.give_genitals(TRUE) //call the clean up proc to delete anything on the mob then return.
// EDIT ENDS
/datum/species/proc/on_species_loss(mob/living/carbon/human/C, datum/species/new_species, pref_load)
@@ -308,7 +315,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
if(DIGITIGRADE in species_traits)
C.Digitigrade_Leg_Swap(TRUE)
for(var/X in inherent_traits)
C.remove_trait(X, SPECIES_TRAIT)
REMOVE_TRAIT(C, X, SPECIES_TRAIT)
SEND_SIGNAL(C, COMSIG_SPECIES_LOSS, src)
@@ -317,7 +324,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
var/obj/item/bodypart/head/HD = H.get_bodypart(BODY_ZONE_HEAD)
if(!HD) //Decapitated
return
if(H.has_trait(TRAIT_HUSK))
if(HAS_TRAIT(H, TRAIT_HUSK))
return
var/datum/sprite_accessory/S
@@ -457,7 +464,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
var/obj/item/bodypart/head/HD = H.get_bodypart(BODY_ZONE_HEAD)
if(HD && !(H.has_trait(TRAIT_HUSK)))
if(HD && !(HAS_TRAIT(H, TRAIT_HUSK)))
// lipstick
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)
@@ -485,22 +492,45 @@ GLOBAL_LIST_EMPTY(roundstart_races)
//Underwear, Undershirts & Socks
if(!(NO_UNDERWEAR in species_traits))
if(H.underwear)
var/datum/sprite_accessory/underwear/underwear = GLOB.underwear_list[H.underwear]
if(underwear)
standing += mutable_appearance(underwear.icon, underwear.icon_state, -BODY_LAYER)
if(H.hidden_underwear)
H.underwear = "Nude"
else
H.saved_underwear = H.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)
if(UNDIE_COLORABLE(B))
MA.color = H.undie_color
standing += MA
if(H.undershirt)
var/datum/sprite_accessory/undershirt/undershirt = GLOB.undershirt_list[H.undershirt]
if(undershirt)
if(H.dna.species.sexes && H.gender == FEMALE)
standing += wear_female_version(undershirt.icon_state, undershirt.icon, BODY_LAYER)
else
standing += mutable_appearance(undershirt.icon, undershirt.icon_state, -BODY_LAYER)
if(H.hidden_undershirt)
H.undershirt = "Nude"
else
H.saved_undershirt = H.undershirt
var/datum/sprite_accessory/underwear/top/T = GLOB.undershirt_list[H.undershirt]
if(T)
var/mutable_appearance/MA
if(H.dna.species.sexes && H.gender == FEMALE)
MA = wear_female_version(T.icon_state, T.icon, BODY_LAYER)
else
MA = mutable_appearance(T.icon, T.icon_state, -BODY_LAYER)
if(UNDIE_COLORABLE(T))
MA.color = H.shirt_color
standing += MA
if(H.socks && H.get_num_legs(FALSE) >= 2 && !(DIGITIGRADE in species_traits))
var/datum/sprite_accessory/socks/socks = GLOB.socks_list[H.socks]
if(socks)
standing += mutable_appearance(socks.icon, socks.icon_state, -BODY_LAYER)
if(H.socks && H.get_num_legs(FALSE) >= 2)
if(H.hidden_socks)
H.socks = "Nude"
else
H.saved_socks = H.socks
var/datum/sprite_accessory/underwear/socks/S = GLOB.socks_list[H.socks]
if(S)
var/digilegs = (DIGITIGRADE in species_traits) ? "_d" : ""
var/mutable_appearance/MA = mutable_appearance(S.icon, "[S.icon_state][digilegs]", -BODY_LAYER)
if(UNDIE_COLORABLE(S))
MA.color = H.socks_color
standing += MA
if(standing.len)
H.overlays_standing[BODY_LAYER] = standing
@@ -752,7 +782,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
for(var/index=1, index<=colorlist.len, index++)
colorlist[index] = colorlist[index]/255
if(!(H.has_trait(TRAIT_HUSK)))
if(!HAS_TRAIT(H, TRAIT_HUSK))
if(!forced_colour)
switch(S.color_src)
if(SKINTONE)
@@ -911,11 +941,11 @@ GLOBAL_LIST_EMPTY(roundstart_races)
/datum/species/proc/spec_life(mob/living/carbon/human/H)
if(H.has_trait(TRAIT_NOBREATH))
if(HAS_TRAIT(H, TRAIT_NOBREATH))
H.setOxyLoss(0)
H.losebreath = 0
var/takes_crit_damage = (!H.has_trait(TRAIT_NOCRITDAMAGE))
var/takes_crit_damage = !HAS_TRAIT(H, TRAIT_NOCRITDAMAGE)
if((H.health < H.crit_threshold) && takes_crit_damage)
H.adjustBruteLoss(1)
@@ -1042,7 +1072,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
return FALSE
return equip_delay_self_check(I, H, bypass_equip_delay_self)
if(SLOT_L_STORE)
if(I.item_flags & NODROP) //Pockets aren't visible, so you can't move NODROP_1 items into them.
if(HAS_TRAIT(I, TRAIT_NODROP)) //Pockets aren't visible, so you can't move TRAIT_NODROP items into them.
return FALSE
if(H.l_store)
return FALSE
@@ -1058,7 +1088,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
if( I.w_class <= WEIGHT_CLASS_SMALL || (I.slot_flags & ITEM_SLOT_POCKET) )
return TRUE
if(SLOT_R_STORE)
if(I.item_flags & NODROP)
if(HAS_TRAIT(I, TRAIT_NODROP))
return FALSE
if(H.r_store)
return FALSE
@@ -1075,7 +1105,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
return TRUE
return FALSE
if(SLOT_S_STORE)
if(I.item_flags & NODROP)
if(HAS_TRAIT(I, TRAIT_NODROP))
return FALSE
if(H.s_store)
return FALSE
@@ -1136,13 +1166,6 @@ GLOBAL_LIST_EMPTY(roundstart_races)
return 1
return FALSE
/datum/species/proc/handle_speech(message, mob/living/carbon/human/H)
return message
//return a list of spans or an empty list
/datum/species/proc/get_spans()
return list()
/datum/species/proc/check_weakness(obj/item, mob/living/attacker)
return FALSE
@@ -1153,21 +1176,21 @@ GLOBAL_LIST_EMPTY(roundstart_races)
/datum/species/proc/handle_digestion(mob/living/carbon/human/H)
//The fucking TRAIT_FAT mutation is the dumbest shit ever. It makes the code so difficult to work with
if(H.has_trait(TRAIT_FAT))//I share your pain, past coder.
if(HAS_TRAIT(H, TRAIT_FAT))//I share your pain, past coder.
if(H.overeatduration < 100)
to_chat(H, "<span class='notice'>You feel fit again!</span>")
H.remove_trait(TRAIT_FAT, OBESITY)
REMOVE_TRAIT(H, TRAIT_FAT, OBESITY)
H.update_inv_w_uniform()
H.update_inv_wear_suit()
else
if(H.overeatduration >= 100)
to_chat(H, "<span class='danger'>You suddenly feel blubbery!</span>")
H.add_trait(TRAIT_FAT, OBESITY)
ADD_TRAIT(H, TRAIT_FAT, OBESITY)
H.update_inv_w_uniform()
H.update_inv_wear_suit()
// nutrition decrease and satiety
if (H.nutrition > 0 && H.stat != DEAD && !H.has_trait(TRAIT_NOHUNGER))
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)
@@ -1196,7 +1219,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
if(H.nutrition > NUTRITION_LEVEL_FAT)
H.metabolism_efficiency = 1
else if(H.nutrition > NUTRITION_LEVEL_FED && H.satiety > 80)
if(H.metabolism_efficiency != 1.25 && !H.has_trait(TRAIT_NOHUNGER))
if(H.metabolism_efficiency != 1.25 && !HAS_TRAIT(H, TRAIT_NOHUNGER))
to_chat(H, "<span class='notice'>You feel vigorous.</span>")
H.metabolism_efficiency = 1.25
else if(H.nutrition < NUTRITION_LEVEL_STARVING + 50)
@@ -1225,7 +1248,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
. = FALSE
var/radiation = H.radiation
if(H.has_trait(TRAIT_RADIMMUNE))
if(HAS_TRAIT(H, TRAIT_RADIMMUNE))
radiation = 0
return TRUE
@@ -1272,17 +1295,17 @@ GLOBAL_LIST_EMPTY(roundstart_races)
gravity = H.has_gravity()
if(gravity && !flight) //Check for chemicals and innate speedups and slowdowns if we're on the ground
if(H.has_trait(TRAIT_GOTTAGOFAST))
if(HAS_TRAIT(H, TRAIT_GOTTAGOFAST))
. -= 1
if(H.has_trait(TRAIT_GOTTAGOREALLYFAST))
if(HAS_TRAIT(H, TRAIT_GOTTAGOREALLYFAST))
. -= 2
. += speedmod
. += H.physiology.speed_mod
if (H.m_intent == MOVE_INTENT_WALK && H.has_trait(TRAIT_SPEEDY_STEP))
. -= 1
if (H.m_intent == MOVE_INTENT_WALK && HAS_TRAIT(H, TRAIT_SPEEDY_STEP))
. -= 1.5
if(H.has_trait(TRAIT_IGNORESLOWDOWN))
if(HAS_TRAIT(H, TRAIT_IGNORESLOWDOWN))
ignoreslow = 1
if(!gravity)
@@ -1333,9 +1356,9 @@ GLOBAL_LIST_EMPTY(roundstart_races)
if(SANITY_UNSTABLE to SANITY_DISTURBED)
. += 0.5
if(H.has_trait(TRAIT_FAT))
if(HAS_TRAIT(H, TRAIT_FAT))
. += (1.5 - flight)
if(H.bodytemperature < BODYTEMP_COLD_DAMAGE_LIMIT && !H.has_trait(TRAIT_RESISTCOLD))
if(H.bodytemperature < BODYTEMP_COLD_DAMAGE_LIMIT && !HAS_TRAIT(H, TRAIT_RESISTCOLD))
. += (BODYTEMP_COLD_DAMAGE_LIMIT - H.bodytemperature) / COLD_SLOWDOWN_FACTOR
return .
@@ -1348,13 +1371,13 @@ GLOBAL_LIST_EMPTY(roundstart_races)
//////////////////
/datum/species/proc/help(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style)
if(target.health >= 0 && !(target.has_trait(TRAIT_FAKEDEATH)))
if(target.health >= 0 && !HAS_TRAIT(target, TRAIT_FAKEDEATH))
target.help_shake_act(user)
if(target != user)
log_combat(user, target, "shaked")
return 1
else
var/we_breathe = !user.has_trait(TRAIT_NOBREATH)
var/we_breathe = !HAS_TRAIT(user, TRAIT_NOBREATH)
var/we_lung = user.getorganslot(ORGAN_SLOT_LUNGS)
if(we_breathe && we_lung)
@@ -1379,7 +1402,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
/datum/species/proc/harm(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style)
if(user.has_trait(TRAIT_PACIFISM))
if(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
@@ -1452,39 +1475,64 @@ GLOBAL_LIST_EMPTY(roundstart_races)
/datum/species/proc/disarm(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style)
// CITADEL EDIT slap mouthy gits and booty
var/aim_for_mouth = user.zone_selected == "mouth"
var/target_on_help_and_unarmed = target.a_intent == INTENT_HELP && !target.get_active_held_item()
var/aim_for_mouth = user.zone_selected == "mouth"
var/target_on_help = target.a_intent == INTENT_HELP
var/target_aiming_for_mouth = target.zone_selected == "mouth"
var/target_restrained = target.restrained()
if(aim_for_mouth && ( target_on_help_and_unarmed || target_restrained || target_aiming_for_mouth))
playsound(target.loc, 'sound/weapons/slap.ogg', 50, 1, -1)
user.visible_message("<span class='danger'>[user] slaps [target] in the face!</span>",
"<span class='notice'>You slap [target] in the face! </span>",\
"You hear a slap.")
if (!target.has_trait(TRAIT_NYMPHO))
stop_wagging_tail(target)
return FALSE
var/same_dir = (target.dir & user.dir)
var/aim_for_groin = user.zone_selected == "groin"
var/target_aiming_for_groin = target.zone_selected == "groin"
if(aim_for_groin && (target_on_help_and_unarmed || target_restrained || target_aiming_for_groin))
playsound(target.loc, 'sound/weapons/slap.ogg', 50, 1, -1)
user.visible_message("<span class='danger'>[user] slaps [target]'s ass!</span>",
"<span class='notice'>You slap [target]'s ass! </span>",\
"You hear a slap.")
if (target.canbearoused)
target.adjustArousalLoss(5)
if (target.getArousalLoss() >= 100 && ishuman(target) && target.has_trait(TRAIT_NYMPHO) && target.has_dna())
target.mob_climax(forced_climax=TRUE)
if (!target.has_trait(TRAIT_NYMPHO))
stop_wagging_tail(target)
return FALSE
else if(user.getStaminaLoss() >= STAMINA_SOFTCRIT)
to_chat(user, "<span class='warning'>You're too exhausted.</span>")
return FALSE
else if(target.check_block()) //END EDIT
if(target.check_block()) //END EDIT
target.visible_message("<span class='warning'>[target] blocks [user]'s disarm attempt!</span>")
return 0
if(attacker_style && attacker_style.disarm_act(user,target))
else if(user.getStaminaLoss() >= STAMINA_SOFTCRIT)
to_chat(user, "<span class='warning'>You're too exhausted!</span>")
return FALSE
else if(aim_for_mouth && ( target_on_help || target_restrained || target_aiming_for_mouth))
playsound(target.loc, 'sound/weapons/slap.ogg', 50, 1, -1)
user.visible_message(\
"<span class='danger'>\The [user] slaps \the [target] in the face!</span>",\
"<span class='notice'>You slap [user == target ? "yourself" : "\the [target]"] in the face! </span>",\
"You hear a slap."
)
if (!HAS_TRAIT(target, TRAIT_NYMPHO))
stop_wagging_tail(target)
user.do_attack_animation(target, ATTACK_EFFECT_FACE_SLAP)
user.adjustStaminaLossBuffered(3)
return FALSE
else if(aim_for_groin && (target == user || target.lying || same_dir) && (target_on_help || target_restrained || target_aiming_for_groin))
user.do_attack_animation(target, ATTACK_EFFECT_ASS_SLAP)
user.adjustStaminaLossBuffered(3)
if(HAS_TRAIT(target, TRAIT_ASSBLASTUSA))
var/hit_zone = (user.held_index_to_dir(user.active_hand_index) == "l" ? "l_":"r_") + "arm"
user.adjustStaminaLoss(20, affected_zone = hit_zone)
user.visible_message(\
"<span class='danger'>\The [user] slaps \the [target]'s ass, but their hand bounces off like they hit metal!</span>",\
"<span class='danger'>You slap [user == target ? "your" : "\the [target]'s"] ass, but feel an intense amount of pain as you realise their buns are harder than steel!</span>",\
"You hear a slap."
)
playsound(target.loc, 'sound/weapons/tap.ogg', 50, 1, -1)
user.emote("scream")
return FALSE
playsound(target.loc, 'sound/weapons/slap.ogg', 50, 1, -1)
user.visible_message(\
"<span class='danger'>\The [user] slaps \the [target]'s ass!</span>",\
"<span class='notice'>You slap [user == target ? "your" : "\the [target]'s"] ass!</span>",\
"You hear a slap."
)
if (target.canbearoused)
target.adjustArousalLoss(5)
if (target.getArousalLoss() >= 100 && ishuman(target) && HAS_TRAIT(target, TRAIT_MASO) && target.has_dna())
target.mob_climax(forced_climax=TRUE)
if (!HAS_TRAIT(target, TRAIT_NYMPHO))
stop_wagging_tail(target)
return FALSE
else if(attacker_style && attacker_style.disarm_act(user,target))
return 1
else
user.do_attack_animation(target, ATTACK_EFFECT_DISARM)
@@ -1615,7 +1663,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
//dismemberment
var/probability = I.get_dismemberment_chance(affecting)
if(prob(probability) || (H.has_trait(TRAIT_EASYDISMEMBER) && prob(probability))) //try twice
if(prob(probability) || (HAS_TRAIT(H, TRAIT_EASYDISMEMBER) && prob(probability))) //try twice
if(affecting.dismember(I.damtype))
I.add_mob_blood(H)
playsound(get_turf(H), I.get_dismember_sound(), 80, 1)
@@ -1649,8 +1697,11 @@ GLOBAL_LIST_EMPTY(roundstart_races)
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)
var/datum/antagonist/gang/gang = H.mind.has_antag_datum(/datum/antagonist/gang/)
if(rev)
rev.remove_revolutionary(FALSE, user)
if(gang)
H.mind.remove_antag_datum(/datum/antagonist/gang)
if(bloody) //Apply blood
if(H.wear_mask)
@@ -1710,6 +1761,11 @@ GLOBAL_LIST_EMPTY(roundstart_races)
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))
H.update_damage_overlays()
if(HAS_TRAIT(H, TRAIT_MASO))
H.adjustArousalLoss(damage * brutemod * H.physiology.brute_mod)
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)
if(BURN)
@@ -1754,7 +1810,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
/////////////
/datum/species/proc/breathe(mob/living/carbon/human/H)
if(H.has_trait(TRAIT_NOBREATH))
if(HAS_TRAIT(H, TRAIT_NOBREATH))
return TRUE
@@ -1802,7 +1858,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
H.throw_alert("temp", /obj/screen/alert/hot, 3)
// +/- 50 degrees from 310K is the 'safe' zone, where no damage is dealt.
if(H.bodytemperature > BODYTEMP_HEAT_DAMAGE_LIMIT && !H.has_trait(TRAIT_RESISTHEAT))
if(H.bodytemperature > BODYTEMP_HEAT_DAMAGE_LIMIT && !HAS_TRAIT(H, TRAIT_RESISTHEAT))
//Body temperature is too hot.
SEND_SIGNAL(H, COMSIG_CLEAR_MOOD_EVENT, "cold")
@@ -1820,7 +1876,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
H.emote("scream")
H.apply_damage(burn_damage, BURN)
else if(H.bodytemperature < BODYTEMP_COLD_DAMAGE_LIMIT && !H.has_trait(TRAIT_RESISTCOLD))
else if(H.bodytemperature < BODYTEMP_COLD_DAMAGE_LIMIT && !HAS_TRAIT(H, TRAIT_RESISTCOLD))
SEND_SIGNAL(H, COMSIG_CLEAR_MOOD_EVENT, "hot")
SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "cold", /datum/mood_event/cold)
switch(H.bodytemperature)
@@ -1839,7 +1895,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
var/adjusted_pressure = H.calculate_affecting_pressure(pressure) //Returns how much pressure actually affects the mob.
switch(adjusted_pressure)
if(HAZARD_HIGH_PRESSURE to INFINITY)
if(!H.has_trait(TRAIT_RESISTHIGHPRESSURE))
if(!HAS_TRAIT(H, TRAIT_RESISTHIGHPRESSURE))
H.adjustBruteLoss(min(((adjusted_pressure / HAZARD_HIGH_PRESSURE) -1 ) * PRESSURE_DAMAGE_COEFFICIENT, MAX_HIGH_PRESSURE_DAMAGE) * H.physiology.pressure_mod)
H.throw_alert("pressure", /obj/screen/alert/highpressure, 2)
else
@@ -1851,7 +1907,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
if(HAZARD_LOW_PRESSURE to WARNING_LOW_PRESSURE)
H.throw_alert("pressure", /obj/screen/alert/lowpressure, 1)
else
if(H.has_trait(TRAIT_RESISTLOWPRESSURE))
if(HAS_TRAIT(H, TRAIT_RESISTLOWPRESSURE))
H.clear_alert("pressure")
else
H.adjustBruteLoss(LOW_PRESSURE_DAMAGE * H.physiology.pressure_mod)
@@ -1862,7 +1918,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
//////////
/datum/species/proc/handle_fire(mob/living/carbon/human/H, no_protection = FALSE)
if(H.has_trait(TRAIT_NOFIRE))
if(HAS_TRAIT(H, TRAIT_NOFIRE))
return
if(H.on_fire)
//the fire tries to damage the exposed clothes and items
@@ -1930,7 +1986,7 @@ GLOBAL_LIST_EMPTY(roundstart_races)
SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "on_fire", /datum/mood_event/on_fire)
/datum/species/proc/CanIgniteMob(mob/living/carbon/human/H)
if(H.has_trait(TRAIT_NOFIRE))
if(HAS_TRAIT(H, TRAIT_NOFIRE))
return FALSE
return TRUE
@@ -3,7 +3,7 @@
id = "abductor"
say_mod = "gibbers"
sexes = FALSE
species_traits = list(NOBLOOD,NOEYES,NOGENITALS)
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
@@ -2,7 +2,7 @@
name = "Android"
id = "android"
say_mod = "states"
species_traits = list(NOBLOOD,NOGENITALS)
species_traits = list(NOBLOOD,NOGENITALS,NOAROUSAL)
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
@@ -23,7 +23,7 @@
if(ishuman(H) && !fly)
fly = new
fly.Grant(H)
H.add_trait(TRAIT_HOLY, SPECIES_TRAIT)
ADD_TRAIT(H, TRAIT_HOLY, SPECIES_TRAIT)
/datum/species/angel/on_species_loss(mob/living/carbon/human/H)
if(fly)
@@ -36,7 +36,7 @@
H.dna.species.mutant_bodyparts -= "wings"
H.dna.features["wings"] = "None"
H.update_body()
H.remove_trait(TRAIT_HOLY, SPECIES_TRAIT)
REMOVE_TRAIT(H, TRAIT_HOLY, SPECIES_TRAIT)
..()
/datum/species/angel/spec_life(mob/living/carbon/human/H)
@@ -68,17 +68,17 @@
/obj/item/organ/tongue/dullahan
zone = "abstract"
modifies_speech = TRUE
/obj/item/organ/tongue/dullahan/TongueSpeech(var/message)
/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")
var/datum/species/dullahan/D = H.dna.species
if(isobj(D.myhead.loc))
var/obj/O = D.myhead.loc
O.say(message)
message = ""
return message
O.say(speech_args[SPEECH_MESSAGE])
speech_args[SPEECH_MESSAGE] = ""
/obj/item/organ/ears/dullahan
zone = "abstract"
@@ -2,7 +2,7 @@
// Animated beings of stone. They have increased defenses, and do not need to breathe. They're also slow as fuuuck.
name = "Golem"
id = "iron golem"
species_traits = list(NOBLOOD,MUTCOLORS,NO_UNDERWEAR,NOGENITALS)
species_traits = list(NOBLOOD,MUTCOLORS,NO_UNDERWEAR,NOGENITALS,NOAROUSAL)
inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOFIRE,TRAIT_NOGUNS,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER)
inherent_biotypes = list(MOB_INORGANIC, MOB_HUMANOID)
mutant_organs = list(/obj/item/organ/adamantine_resonator)
@@ -30,6 +30,7 @@
var/list/special_names = list("Tarkus")
var/human_surname_chance = 3
var/special_name_chance = 5
var/owner //dobby is a free golem
/datum/species/golem/random_name(gender,unique,lastname)
var/golem_surname = pick(GLOB.golem_names)
@@ -74,10 +75,10 @@
/datum/species/golem/adamantine/on_species_gain(mob/living/carbon/C, datum/species/old_species)
..()
C.add_trait(TRAIT_ANTIMAGIC, SPECIES_TRAIT)
ADD_TRAIT(C, TRAIT_ANTIMAGIC, SPECIES_TRAIT)
/datum/species/golem/adamantine/on_species_loss(mob/living/carbon/C)
C.remove_trait(TRAIT_ANTIMAGIC, SPECIES_TRAIT)
REMOVE_TRAIT(C, TRAIT_ANTIMAGIC, SPECIES_TRAIT)
..()
//The suicide bombers of golemkind
@@ -175,10 +176,10 @@
/datum/species/golem/silver/on_species_gain(mob/living/carbon/C, datum/species/old_species)
..()
C.add_trait(TRAIT_HOLY, SPECIES_TRAIT)
ADD_TRAIT(C, TRAIT_HOLY, SPECIES_TRAIT)
/datum/species/golem/silver/on_species_loss(mob/living/carbon/C)
C.remove_trait(TRAIT_HOLY, SPECIES_TRAIT)
REMOVE_TRAIT(C, TRAIT_HOLY, SPECIES_TRAIT)
..()
//Harder to stun, deals more damage, but it's even slower
@@ -518,6 +519,11 @@
..()
last_banana = world.time
last_honk = world.time
RegisterSignal(C, COMSIG_MOB_SAY, .proc/handle_speech)
/datum/species/golem/bananium/on_species_loss(mob/living/carbon/C)
. = ..()
UnregisterSignal(C, COMSIG_MOB_SAY)
/datum/species/golem/bananium/random_name(gender,unique,lastname)
var/clown_name = pick(GLOB.clown_names)
@@ -566,9 +572,8 @@
/datum/species/golem/bananium/spec_death(gibbed, mob/living/carbon/human/H)
playsound(get_turf(H), 'sound/misc/sadtrombone.ogg', 70, 0)
/datum/species/golem/bananium/get_spans()
return list(SPAN_CLOWN)
/datum/species/golem/bananium/proc/handle_speech(datum/source, list/speech_args)
speech_args[SPEECH_SPANS] |= SPAN_CLOWN
/datum/species/golem/runic
name = "Runic Golem"
@@ -645,14 +650,16 @@
/datum/species/golem/clockwork/on_species_gain(mob/living/carbon/human/H)
. = ..()
H.faction |= "ratvar"
RegisterSignal(H, COMSIG_MOB_SAY, .proc/handle_speech)
/datum/species/golem/clockwork/on_species_loss(mob/living/carbon/human/H)
if(!is_servant_of_ratvar(H))
H.faction -= "ratvar"
UnregisterSignal(H, COMSIG_MOB_SAY)
. = ..()
/datum/species/golem/clockwork/get_spans()
return SPAN_ROBOT //beep
/datum/species/golem/clockwork/proc/handle_speech(datum/source, list/speech_args)
speech_args[SPEECH_SPANS] |= SPAN_ROBOT //beep
/datum/species/golem/clockwork/spec_death(gibbed, mob/living/carbon/human/H)
gibbed = !has_corpse ? FALSE : gibbed
@@ -698,10 +705,10 @@
/datum/species/golem/cloth/on_species_gain(mob/living/carbon/C, datum/species/old_species)
..()
C.add_trait(TRAIT_HOLY, SPECIES_TRAIT)
ADD_TRAIT(C, TRAIT_HOLY, SPECIES_TRAIT)
/datum/species/golem/cloth/on_species_loss(mob/living/carbon/C)
C.remove_trait(TRAIT_HOLY, SPECIES_TRAIT)
REMOVE_TRAIT(C, TRAIT_HOLY, SPECIES_TRAIT)
..()
/datum/species/golem/cloth/check_roundstart_eligible()
@@ -768,7 +775,7 @@
/obj/structure/cloth_pile/proc/revive()
if(QDELETED(src) || QDELETED(cloth_golem)) //QDELETED also checks for null, so if no cloth golem is set this won't runtime
return
if(cloth_golem.suiciding || cloth_golem.has_trait(TRAIT_NOCLONE))
if(cloth_golem.suiciding || HAS_TRAIT(cloth_golem, TRAIT_NOCLONE))
QDEL_NULL(cloth_golem)
return
@@ -807,3 +814,196 @@
/datum/species/golem/plastic/on_species_loss(mob/living/carbon/C)
. = ..()
C.ventcrawler = initial(C.ventcrawler)
/datum/species/golem/bronze
name = "Bronze Golem"
id = "bronze golem"
prefix = "Bronze"
special_names = list("Bell")
fixed_mut_color = "cd7f32"
info_text = "As a <span class='danger'>Bronze Golem</span>, you are very resistant to loud noises, and make loud noises if something hard hits you, however this ability does hurt your hearing."
special_step_sounds = list('sound/machines/clockcult/integration_cog_install.ogg', 'sound/magic/clockwork/fellowship_armory.ogg' )
attack_verb = "bonk"
mutantears = /obj/item/organ/ears/bronze
var/last_gong_time = 0
var/gong_cooldown = 150
/datum/species/golem/bronze/bullet_act(obj/item/projectile/P, mob/living/carbon/human/H)
if(!(world.time > last_gong_time + gong_cooldown))
return ..()
if(P.flag == "bullet" || P.flag == "bomb")
gong(H)
return ..()
/datum/species/golem/bronze/spec_hitby(atom/movable/AM, mob/living/carbon/human/H)
..()
if(world.time > last_gong_time + gong_cooldown)
gong(H)
/datum/species/golem/bronze/spec_attack_hand(mob/living/carbon/human/M, mob/living/carbon/human/H, datum/martial_art/attacker_style)
..()
if(world.time > last_gong_time + gong_cooldown && M.a_intent != INTENT_HELP)
gong(H)
/datum/species/golem/bronze/spec_attacked_by(obj/item/I, mob/living/user, obj/item/bodypart/affecting, intent, mob/living/carbon/human/H)
..()
if(world.time > last_gong_time + gong_cooldown)
gong(H)
/datum/species/golem/bronze/on_hit(obj/item/projectile/P, mob/living/carbon/human/H)
..()
if(world.time > last_gong_time + gong_cooldown)
gong(H)
/datum/species/golem/bronze/proc/gong(mob/living/carbon/human/H)
last_gong_time = world.time
for(var/mob/living/M in get_hearers_in_view(7,H))
if(M.stat == DEAD) //F
return
if(M == H)
H.show_message("<span class='narsiesmall'>You cringe with pain as your body rings around you!</span>", 2)
H.playsound_local(H, 'sound/effects/gong.ogg', 100, TRUE)
H.soundbang_act(2, 0, 100, 1)
H.jitteriness += 7
var/distance = max(0,get_dist(get_turf(H),get_turf(M)))
switch(distance)
if(0 to 1)
M.show_message("<span class='narsiesmall'>GONG!</span>", 2)
M.playsound_local(H, 'sound/effects/gong.ogg', 100, TRUE)
M.soundbang_act(1, 0, 30, 3)
M.confused += 10
M.jitteriness += 4
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "gonged", /datum/mood_event/loud_gong)
if(2 to 3)
M.show_message("<span class='cult'>GONG!</span>", 2)
M.playsound_local(H, 'sound/effects/gong.ogg', 75, TRUE)
M.soundbang_act(1, 0, 15, 2)
M.jitteriness += 3
SEND_SIGNAL(M, COMSIG_ADD_MOOD_EVENT, "gonged", /datum/mood_event/loud_gong)
else
M.show_message("<span class='warning'>GONG!</span>", 2)
M.playsound_local(H, 'sound/effects/gong.ogg', 50, TRUE)
/datum/species/golem/cardboard //Faster but weaker, can also make new shells on its own
name = "Cardboard Golem"
id = "cardboard golem"
prefix = "Cardboard"
special_names = list("Box")
info_text = "As a <span class='danger'>Cardboard Golem</span>, you aren't very strong, but you are a bit quicker and can easily create more brethren by using cardboard on yourself."
species_traits = list(NOBLOOD,NO_UNDERWEAR,NOGENITALS,NOAROUSAL,MUTCOLORS)
inherent_traits = list(TRAIT_NOBREATH, TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOGUNS,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER)
fixed_mut_color = "ffffff"
limbs_id = "c_golem" //special sprites
attack_verb = "bash"
armor = 25
burnmod = 1.25
heatmod = 2
speedmod = 1.5
punchdamagelow = 4
punchstunthreshold = 7
punchdamagehigh = 8
var/last_creation = 0
var/brother_creation_cooldown = 300
/datum/species/golem/cardboard/spec_attacked_by(obj/item/I, mob/living/user, obj/item/bodypart/affecting, intent, mob/living/carbon/human/H)
. = ..()
if(user != H)
return FALSE //forced reproduction is rape.
if(istype(I, /obj/item/stack/sheet/cardboard))
var/obj/item/stack/sheet/cardboard/C = I
if(last_creation + brother_creation_cooldown > world.time) //no cheesing dork
return
if(C.amount < 10)
to_chat(H, "<span class='warning'>You do not have enough cardboard!</span>")
return FALSE
to_chat(H, "<span class='notice'>You attempt to create a new cardboard brother.</span>")
if(do_after(user, 30, target = user))
if(last_creation + brother_creation_cooldown > world.time) //no cheesing dork
return
if(!C.use(10))
to_chat(H, "<span class='warning'>You do not have enough cardboard!</span>")
return FALSE
to_chat(H, "<span class='notice'>You create a new cardboard golem shell.</span>")
create_brother(H.loc)
/datum/species/golem/cardboard/proc/create_brother(var/location)
new /obj/effect/mob_spawn/human/golem/servant(location, /datum/species/golem/cardboard, owner)
last_creation = world.time
/datum/species/golem/leather
name = "Leather Golem"
id = "leather golem"
special_names = list("Face", "Man", "Belt") //Ah dude 4 strength 4 stam leather belt AHHH
inherent_traits = list(TRAIT_NOBREATH, TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOGUNS,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER, TRAIT_STRONG_GRABBER)
prefix = "Leather"
fixed_mut_color = "624a2e"
info_text = "As a <span class='danger'>Leather Golem</span>, you are flammable, but you can grab things with incredible ease, allowing all your grabs to start at a strong level."
attack_verb = "whipp"
grab_sound = 'sound/weapons/whipgrab.ogg'
attack_sound = 'sound/weapons/whip.ogg'
/datum/species/golem/bone
name = "Bone Golem"
id = "bone golem"
say_mod = "rattles"
prefix = "Bone"
limbs_id = "b_golem"
special_names = list("Head", "Broth", "Fracture", "Rattler", "Appetit")
liked_food = GROSS | MEAT | RAW
toxic_food = null
inherent_biotypes = list(MOB_UNDEAD, MOB_HUMANOID)
mutanttongue = /obj/item/organ/tongue/bone
sexes = FALSE
fixed_mut_color = "ffffff"
attack_verb = "rattl"
species_traits = list(NOBLOOD,NO_UNDERWEAR,NOGENITALS,NOAROUSAL,MUTCOLORS)
inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOFIRE,TRAIT_NOGUNS,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER,TRAIT_FAKEDEATH,TRAIT_CALCIUM_HEALER)
info_text = "As a <span class='danger'>Bone Golem</span>, You have a powerful spell that lets you chill your enemies with fear, and milk heals you! Just make sure to watch our for bone-hurting juice."
var/datum/action/innate/bonechill/bonechill
/datum/species/golem/bone/on_species_gain(mob/living/carbon/C, datum/species/old_species)
..()
if(ishuman(C))
bonechill = new
bonechill.Grant(C)
/datum/species/golem/bone/on_species_loss(mob/living/carbon/C)
if(bonechill)
bonechill.Remove(C)
..()
/datum/action/innate/bonechill
name = "Bone Chill"
desc = "Rattle your bones and strike fear into your enemies!"
check_flags = AB_CHECK_CONSCIOUS
icon_icon = 'icons/mob/actions/actions_spells.dmi'
button_icon_state = "bonechill"
var/cooldown = 600
var/last_use
var/snas_chance = 3
/datum/action/innate/bonechill/Activate()
if(world.time < last_use + cooldown)
to_chat("<span class='notice'>You aren't ready yet to rattle your bones again</span>")
return
owner.visible_message("<span class='warning'>[owner] rattles [owner.p_their()] bones harrowingly.</span>", "<span class='notice'>You rattle your bones</span>")
last_use = world.time
if(prob(snas_chance))
playsound(get_turf(owner),'sound/magic/RATTLEMEBONES2.ogg', 100)
if(ishuman(owner))
var/mob/living/carbon/human/H = owner
var/mutable_appearance/badtime = mutable_appearance('icons/mob/human_parts.dmi', "b_golem_eyes", -FIRE_LAYER-0.5)
badtime.appearance_flags = RESET_COLOR
H.overlays_standing[FIRE_LAYER+0.5] = badtime
H.apply_overlay(FIRE_LAYER+0.5)
addtimer(CALLBACK(H, /mob/living/carbon/.proc/remove_overlay, FIRE_LAYER+0.5), 25)
else
playsound(get_turf(owner),'sound/magic/RATTLEMEBONES.ogg', 100)
for(var/mob/living/L in orange(7, get_turf(owner)))
if((MOB_UNDEAD in L.mob_biotypes) || isgolem(L) || HAS_TRAIT(L, TRAIT_RESISTCOLD))
return //Do not affect our brothers
to_chat(L, "<span class='cultlarge'>A spine-chilling sound chills you to the bone!</span>")
L.apply_status_effect(/datum/status_effect/bonechill)
SEND_SIGNAL(L, COMSIG_ADD_MOOD_EVENT, "spooked", /datum/mood_event/spooked)
@@ -5,6 +5,7 @@
default_color = "00FF90"
say_mod = "chirps"
species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,NOBLOOD)
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
inherent_traits = list(TRAIT_TOXINLOVER)
@@ -594,7 +595,7 @@
/datum/species/jelly/stargazer/proc/link_mob(mob/living/M)
if(QDELETED(M) || M.stat == DEAD)
return FALSE
if(M.has_trait(TRAIT_MINDSHIELD)) //mindshield implant, no dice
if(HAS_TRAIT(M, TRAIT_MINDSHIELD)) //mindshield implant, no dice
return FALSE
if(M in linked_mobs)
return FALSE
@@ -97,6 +97,7 @@
brutemod = 0.9
/datum/species/lizard/ashwalker/on_species_gain(mob/living/carbon/human/C, datum/species/old_species)
if((C.dna.features["spines"] != "None" ) && (C.dna.features["tail"] == "None")) //tbh, it's kinda ugly for them not to have a tail yet have floating spines
C.dna.features["tail"] = "Smooth"
if((C.dna.features["spines"] != "None" ) && (C.dna.features["tail_lizard"] == "None")) //tbh, it's kinda ugly for them not to have a tail yet have floating spines
C.dna.features["tail_lizard"] = "Smooth"
C.update_body()
return ..()
@@ -9,7 +9,7 @@
nojumpsuit = TRUE
say_mod = "poofs" //what does a mushroom sound like
species_traits = list(MUTCOLORS, NOEYES, NO_UNDERWEAR,NOGENITALS)
species_traits = list(MUTCOLORS, NOEYES, NO_UNDERWEAR,NOGENITALS,NOAROUSAL)
inherent_traits = list(TRAIT_NOBREATH)
speedmod = 1.5 //faster than golems but not by much
@@ -5,7 +5,7 @@
sexes = 0
meat = /obj/item/stack/sheet/mineral/plasma
species_traits = list(NOBLOOD,NOTRANSSTING,NOGENITALS)
inherent_traits = list(TRAIT_RESISTCOLD,TRAIT_RADIMMUNE,TRAIT_NOHUNGER)
inherent_traits = list(TRAIT_RESISTCOLD,TRAIT_RADIMMUNE,TRAIT_NOHUNGER,TRAIT_CALCIUM_HEALER)
inherent_biotypes = list(MOB_INORGANIC, MOB_HUMANOID)
mutantlungs = /obj/item/organ/lungs/plasmaman
mutanttongue = /obj/item/organ/tongue/bone/plasmaman
@@ -33,7 +33,7 @@
if((!istype(H.w_uniform, /obj/item/clothing/under/plasmaman) || !istype(H.head, /obj/item/clothing/head/helmet/space/plasmaman)) && !atmos_sealed)
if(environment)
if(environment.total_moles())
if(environment.gases[/datum/gas/oxygen] && (environment.gases[/datum/gas/oxygen][MOLES]) >= 1) //Same threshhold that extinguishes fire
if(environment.gases[/datum/gas/oxygen] && (environment.gases[/datum/gas/oxygen]) >= 1) //Same threshhold that extinguishes fire
H.adjust_fire_stacks(0.5)
if(!H.on_fire && H.fire_stacks > 0)
H.visible_message("<span class='danger'>[H]'s body reacts with the atmosphere and bursts into flames!</span>","<span class='userdanger'>Your body reacts with the atmosphere and bursts into flame!</span>")
@@ -73,6 +73,9 @@
/datum/species/pod/pseudo_weak
id = "podweak"
limbs_id = "pod"
species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS,MUTCOLORS)
mutant_bodyparts = list("mam_tail", "mam_ears", "mam_body_markings", "mam_snouts", "taur", "legs")
default_features = list("mcolor" = "FFF","mcolor2" = "FFF","mcolor3" = "FFF", "mam_snouts" = "Husky", "mam_tail" = "Husky", "mam_ears" = "Husky", "mam_body_markings" = "Husky", "taur" = "None", "legs" = "Normal Legs")
light_nutrition_gain_factor = 7.5
light_bruteheal = 0.2
light_burnheal = 0.2
@@ -38,7 +38,7 @@
burnmod = 1.5
blacklisted = TRUE
no_equip = list(SLOT_WEAR_MASK, SLOT_WEAR_SUIT, SLOT_GLOVES, SLOT_SHOES, SLOT_W_UNIFORM, SLOT_S_STORE)
species_traits = list(NOBLOOD,NO_UNDERWEAR,NO_DNA_COPY,NOTRANSSTING,NOEYES,NOGENITALS)
species_traits = list(NOBLOOD,NO_UNDERWEAR,NO_DNA_COPY,NOTRANSSTING,NOEYES,NOGENITALS,NOAROUSAL)
inherent_traits = list(TRAIT_RESISTCOLD,TRAIT_NOBREATH,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_NOGUNS,TRAIT_RADIMMUNE,TRAIT_VIRUSIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NODISMEMBER,TRAIT_NOHUNGER)
mutanteyes = /obj/item/organ/eyes/night_vision/nightmare
mutant_organs = list(/obj/item/organ/heart/nightmare)
@@ -171,12 +171,13 @@
armour_penetration = 35
lefthand_file = 'icons/mob/inhands/antag/changeling_lefthand.dmi'
righthand_file = 'icons/mob/inhands/antag/changeling_righthand.dmi'
item_flags = ABSTRACT | NODROP | DROPDEL
item_flags = ABSTRACT | DROPDEL
w_class = WEIGHT_CLASS_HUGE
sharpness = IS_SHARP
/obj/item/light_eater/Initialize()
. = ..()
ADD_TRAIT(src, TRAIT_NODROP, HAND_REPLACEMENT_TRAIT)
AddComponent(/datum/component/butchering, 80, 70)
/obj/item/light_eater/afterattack(atom/movable/AM, mob/user, proximity)
@@ -6,8 +6,8 @@
blacklisted = 1
sexes = 0
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/skeleton
species_traits = list(NOBLOOD,NOGENITALS)
inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NOHUNGER,TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT,TRAIT_FAKEDEATH)
species_traits = list(NOBLOOD,NOGENITALS,NOAROUSAL)
inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NOHUNGER,TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT,TRAIT_FAKEDEATH, TRAIT_CALCIUM_HEALER)
inherent_biotypes = list(MOB_UNDEAD, MOB_HUMANOID)
mutanttongue = /obj/item/organ/tongue/bone
damage_overlay_type = ""//let's not show bloody wounds or burns over bones.
@@ -21,4 +21,4 @@
/datum/species/skeleton/pirate
name = "Space Queen's Skeleton"
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)
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)
@@ -3,7 +3,7 @@
id = "synth"
say_mod = "beep boops" //inherited from a user's real species
sexes = 0
species_traits = list(NOTRANSSTING,NOGENITALS) //all of these + whatever we inherit from the real species
species_traits = list(NOTRANSSTING,NOGENITALS,NOAROUSAL) //all of these + whatever we inherit from the real species
inherent_traits = list(TRAIT_VIRUSIMMUNE,TRAIT_NODISMEMBER,TRAIT_NOHUNGER,TRAIT_NOBREATH)
inherent_biotypes = list(MOB_ROBOTIC, MOB_HUMANOID)
dangerous_existence = 1
@@ -28,6 +28,11 @@
/datum/species/synth/on_species_gain(mob/living/carbon/human/H, datum/species/old_species)
..()
assume_disguise(old_species, H)
RegisterSignal(H, COMSIG_MOB_SAY, .proc/handle_speech)
/datum/species/synth/on_species_loss(mob/living/carbon/human/H)
. = ..()
UnregisterSignal(H, COMSIG_MOB_SAY)
/datum/species/synth/handle_chemicals(datum/reagent/chem, mob/living/carbon/human/H)
if(chem.id == "synthflesh")
@@ -110,18 +115,12 @@
else
return ..()
/datum/species/synth/get_spans()
if(fake_species)
return fake_species.get_spans()
return list()
/datum/species/synth/handle_speech(message, mob/living/carbon/human/H)
if(H.health > disguise_fail_health)
if(fake_species)
return fake_species.handle_speech(message,H)
else
return ..()
else
return ..()
/datum/species/synth/proc/handle_speech(datum/source, list/speech_args)
if (isliving(source)) // yeah it's gonna be living but just to be clean
var/mob/living/L = source
if(fake_species && L.health > disguise_fail_health)
switch (fake_species.type)
if (/datum/species/golem/bananium)
speech_args[SPEECH_SPANS] |= SPAN_CLOWN
if (/datum/species/golem/clockwork)
speech_args[SPEECH_SPANS] |= SPAN_ROBOT
@@ -9,12 +9,12 @@
/mob/living/carbon/human/Unconscious(amount, updating = 1, ignore_canunconscious = 0)
amount = dna.species.spec_stun(src,amount)
if(has_trait(TRAIT_HEAVY_SLEEPER))
if(HAS_TRAIT(src, TRAIT_HEAVY_SLEEPER))
amount *= rand(1.25, 1.3)
return ..()
/mob/living/carbon/human/Sleeping(amount, updating = 1, ignore_sleepimmune = 0)
if(has_trait(TRAIT_HEAVY_SLEEPER))
if(HAS_TRAIT(src, TRAIT_HEAVY_SLEEPER))
amount *= rand(1.25, 1.3)
return ..()
@@ -660,8 +660,10 @@ generate/load female uniform sprites matching all previously decided variables
. += "-[BP.dmg_overlay_type]"
if(BP.body_markings)
. += "-[BP.body_markings]"
else
. += "-no_marking"
if(has_trait(TRAIT_HUSK))
if(HAS_TRAIT(src, TRAIT_HUSK))
. += "-husk"
/mob/living/carbon/human/load_limb_from_cache()
@@ -703,7 +705,7 @@ generate/load female uniform sprites matching all previously decided variables
add_overlay(HD.get_limb_icon())
update_damage_overlays()
if(HD && !(has_trait(TRAIT_HUSK)))
if(HD && !(HAS_TRAIT(src, TRAIT_HUSK)))
// lipstick
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)
+54 -54
View File
@@ -116,7 +116,7 @@
air_update_turf()
/mob/living/carbon/proc/has_smoke_protection()
if(has_trait(TRAIT_NOBREATH))
if(HAS_TRAIT(src, TRAIT_NOBREATH))
return TRUE
return FALSE
@@ -150,10 +150,9 @@
var/breath_pressure = (breath.total_moles()*R_IDEAL_GAS_EQUATION*breath.temperature)/BREATH_VOLUME
var/list/breath_gases = breath.gases
breath.assert_gases(/datum/gas/oxygen, /datum/gas/plasma, /datum/gas/carbon_dioxide, /datum/gas/nitrous_oxide, /datum/gas/bz)
var/O2_partialpressure = (breath_gases[/datum/gas/oxygen][MOLES]/breath.total_moles())*breath_pressure
var/Toxins_partialpressure = (breath_gases[/datum/gas/plasma][MOLES]/breath.total_moles())*breath_pressure
var/CO2_partialpressure = (breath_gases[/datum/gas/carbon_dioxide][MOLES]/breath.total_moles())*breath_pressure
var/O2_partialpressure = (breath_gases[/datum/gas/oxygen]/breath.total_moles())*breath_pressure
var/Toxins_partialpressure = (breath_gases[/datum/gas/plasma]/breath.total_moles())*breath_pressure
var/CO2_partialpressure = (breath_gases[/datum/gas/carbon_dioxide]/breath.total_moles())*breath_pressure
//OXYGEN
@@ -177,7 +176,7 @@
var/ratio = 1 - O2_partialpressure/safe_oxy_min
adjustOxyLoss(min(5*ratio, 3))
failed_last_breath = 1
oxygen_used = breath_gases[/datum/gas/oxygen][MOLES]*ratio
oxygen_used = breath_gases[/datum/gas/oxygen]*ratio
else
adjustOxyLoss(3)
failed_last_breath = 1
@@ -189,12 +188,12 @@
o2overloadtime = 0 //reset our counter for this too
if(health >= crit_threshold)
adjustOxyLoss(-5)
oxygen_used = breath_gases[/datum/gas/oxygen][MOLES]
oxygen_used = breath_gases[/datum/gas/oxygen]
clear_alert("not_enough_oxy")
SEND_SIGNAL(src, COMSIG_CLEAR_MOOD_EVENT, "suffocation")
breath_gases[/datum/gas/oxygen][MOLES] -= oxygen_used
breath_gases[/datum/gas/carbon_dioxide][MOLES] += oxygen_used
breath_gases[/datum/gas/oxygen] -= oxygen_used
breath_gases[/datum/gas/carbon_dioxide] += oxygen_used
//CARBON DIOXIDE
if(CO2_partialpressure > safe_co2_max)
@@ -213,7 +212,7 @@
//TOXINS/PLASMA
if(Toxins_partialpressure > safe_tox_max)
var/ratio = (breath_gases[/datum/gas/plasma][MOLES]/safe_tox_max) * 10
var/ratio = (breath_gases[/datum/gas/plasma]/safe_tox_max) * 10
adjustToxLoss(CLAMP(ratio, MIN_TOXIC_GAS_DAMAGE, MAX_TOXIC_GAS_DAMAGE))
throw_alert("too_much_tox", /obj/screen/alert/too_much_tox)
else
@@ -221,7 +220,7 @@
//NITROUS OXIDE
if(breath_gases[/datum/gas/nitrous_oxide])
var/SA_partialpressure = (breath_gases[/datum/gas/nitrous_oxide][MOLES]/breath.total_moles())*breath_pressure
var/SA_partialpressure = (breath_gases[/datum/gas/nitrous_oxide]/breath.total_moles())*breath_pressure
if(SA_partialpressure > SA_para_min)
Unconscious(60)
if(SA_partialpressure > SA_sleep_min)
@@ -232,7 +231,7 @@
//BZ (Facepunch port of their Agent B)
if(breath_gases[/datum/gas/bz])
var/bz_partialpressure = (breath_gases[/datum/gas/bz][MOLES]/breath.total_moles())*breath_pressure
var/bz_partialpressure = (breath_gases[/datum/gas/bz]/breath.total_moles())*breath_pressure
if(bz_partialpressure > 1)
hallucination += 10
else if(bz_partialpressure > 0.01)
@@ -240,49 +239,50 @@
//TRITIUM
if(breath_gases[/datum/gas/tritium])
var/tritium_partialpressure = (breath_gases[/datum/gas/tritium][MOLES]/breath.total_moles())*breath_pressure
var/tritium_partialpressure = (breath_gases[/datum/gas/tritium]/breath.total_moles())*breath_pressure
radiation += tritium_partialpressure/10
//NITRYL
if(breath_gases[/datum/gas/nitryl])
var/nitryl_partialpressure = (breath_gases[/datum/gas/nitryl][MOLES]/breath.total_moles())*breath_pressure
var/nitryl_partialpressure = (breath_gases[/datum/gas/nitryl]/breath.total_moles())*breath_pressure
adjustFireLoss(nitryl_partialpressure/4)
//MIASMA
if(breath_gases[/datum/gas/miasma])
var/miasma_partialpressure = (breath_gases[/datum/gas/miasma][MOLES]/breath.total_moles())*breath_pressure
var/miasma_partialpressure = (breath_gases[/datum/gas/miasma]/breath.total_moles())*breath_pressure
if(miasma_partialpressure > MINIMUM_MOLES_DELTA_TO_MOVE)
if(prob(1 * miasma_partialpressure))
var/datum/disease/advance/miasma_disease = new /datum/disease/advance/random(2,3)
miasma_disease.name = "Unknown"
ForceContractDisease(miasma_disease, TRUE, TRUE)
if(prob(0.05 * miasma_partialpressure))
var/datum/disease/advance/miasma_disease = new /datum/disease/advance/random(2,3)
miasma_disease.name = "Unknown"
ForceContractDisease(miasma_disease, TRUE, TRUE)
//Miasma side effects
switch(miasma_partialpressure)
if(1 to 5)
// At lower pp, give out a little warning
SEND_SIGNAL(src, COMSIG_CLEAR_MOOD_EVENT, "smell")
if(prob(5))
to_chat(src, "<span class='notice'>There is an unpleasant smell in the air.</span>")
if(5 to 20)
//At somewhat higher pp, warning becomes more obvious
if(prob(15))
to_chat(src, "<span class='warning'>You smell something horribly decayed inside this room.</span>")
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "smell", /datum/mood_event/disgust/bad_smell)
if(15 to 30)
//Small chance to vomit. By now, people have internals on anyway
if(prob(5))
to_chat(src, "<span class='warning'>The stench of rotting carcasses is unbearable!</span>")
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "smell", /datum/mood_event/disgust/nauseating_stench)
vomit()
if(30 to INFINITY)
//Higher chance to vomit. Let the horror start
if(prob(25))
to_chat(src, "<span class='warning'>The stench of rotting carcasses is unbearable!</span>")
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "smell", /datum/mood_event/disgust/nauseating_stench)
vomit()
else
SEND_SIGNAL(src, COMSIG_CLEAR_MOOD_EVENT, "smell")
//Miasma side effects
switch(miasma_partialpressure)
if(1 to 5)
// At lower pp, give out a little warning
SEND_SIGNAL(src, COMSIG_CLEAR_MOOD_EVENT, "smell")
if(prob(5))
to_chat(src, "<span class='notice'>There is an unpleasant smell in the air.</span>")
if(5 to 20)
//At somewhat higher pp, warning becomes more obvious
if(prob(15))
to_chat(src, "<span class='warning'>You smell something horribly decayed inside this room.</span>")
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "smell", /datum/mood_event/disgust/bad_smell)
if(15 to 30)
//Small chance to vomit. By now, people have internals on anyway
if(prob(5))
to_chat(src, "<span class='warning'>The stench of rotting carcasses is unbearable!</span>")
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "smell", /datum/mood_event/disgust/nauseating_stench)
vomit()
if(30 to INFINITY)
//Higher chance to vomit. Let the horror start
if(prob(25))
to_chat(src, "<span class='warning'>The stench of rotting carcasses is unbearable!</span>")
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "smell", /datum/mood_event/disgust/nauseating_stench)
vomit()
else
SEND_SIGNAL(src, COMSIG_CLEAR_MOOD_EVENT, "smell")
//Clear all moods if no miasma at all
@@ -292,7 +292,7 @@
breath.garbage_collect()
GAS_GARBAGE_COLLECT(breath.gases)
//BREATH TEMPERATURE
handle_breath_temperature(breath)
@@ -324,7 +324,7 @@
return
// No decay if formaldehyde in corpse or when the corpse is charred
if(reagents.has_reagent("formaldehyde", 15) || has_trait(TRAIT_HUSK))
if(reagents.has_reagent("formaldehyde", 15) || HAS_TRAIT(src, TRAIT_HUSK))
return
// Also no decay if corpse chilled or not organic/undead
@@ -345,8 +345,7 @@
var/list/cached_gases = miasma_turf.air.gases
ASSERT_GAS(/datum/gas/miasma, miasma_turf.air)
cached_gases[/datum/gas/miasma][MOLES] += 0.02
cached_gases[/datum/gas/miasma] += 0.1
/mob/living/carbon/proc/handle_blood()
return
@@ -551,7 +550,7 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put
if(drunkenness >= 6)
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "drunk", /datum/mood_event/drunk)
jitteriness = max(jitteriness - 3, 0)
if(has_trait(TRAIT_DRUNK_HEALING))
if(HAS_TRAIT(src, TRAIT_DRUNK_HEALING))
adjustBruteLoss(-0.12, FALSE)
adjustFireLoss(-0.06, FALSE)
@@ -576,7 +575,7 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put
if(prob(25))
confused += 2
Dizzy(10)
if(has_trait(TRAIT_DRUNK_HEALING)) // effects stack with lower tiers
if(HAS_TRAIT(src, TRAIT_DRUNK_HEALING)) // effects stack with lower tiers
adjustBruteLoss(-0.3, FALSE)
adjustFireLoss(-0.15, FALSE)
@@ -589,7 +588,7 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put
if(drunkenness >= 61)
if(prob(50))
blur_eyes(5)
if(has_trait(TRAIT_DRUNK_HEALING))
if(HAS_TRAIT(src, TRAIT_DRUNK_HEALING))
adjustBruteLoss(-0.4, FALSE)
adjustFireLoss(-0.2, FALSE)
@@ -656,8 +655,9 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put
L.damage += d
/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(TRAIT_STABLEHEART))
if(HAS_TRAIT(src, TRAIT_STABLEHEART))
return
adjustToxLoss(4, TRUE, TRUE)
if(prob(30))
@@ -693,7 +693,7 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put
return TRUE
/mob/living/carbon/proc/needs_heart()
if(has_trait(TRAIT_STABLEHEART))
if(HAS_TRAIT(src, TRAIT_STABLEHEART))
return FALSE
if(dna && dna.species && (NOBLOOD in dna.species.species_traits)) //not all carbons have species!
return FALSE
+15 -32
View File
@@ -73,39 +73,21 @@
if(I.loc == src)
return TRUE
if(I.anchored)
if(I.anchored || !put_in_hands(I))
blacklistItems[I] ++
return FALSE
// WEAPONS
if(istype(I, /obj/item))
var/obj/item/W = I
if(W.force >= best_force)
put_in_hands(W)
best_force = W.force
return TRUE
// CLOTHING
else if(istype(I, /obj/item/clothing))
var/obj/item/clothing/C = I
monkeyDrop(C)
addtimer(CALLBACK(src, .proc/pickup_and_wear, C), 5)
return TRUE
// EVERYTHING ELSE
if(I.force >= best_force)
best_force = I.force
else
if(!get_item_for_held_index(1) || !get_item_for_held_index(2))
put_in_hands(I)
return TRUE
addtimer(CALLBACK(src, .proc/pickup_and_wear, I), 5)
blacklistItems[I] ++
return FALSE
return TRUE
/mob/living/carbon/monkey/proc/pickup_and_wear(var/obj/item/clothing/C)
if(!equip_to_appropriate_slot(C))
monkeyDrop(get_item_by_slot(C)) // remove the existing item if worn
sleep(5)
equip_to_appropriate_slot(C)
/mob/living/carbon/monkey/proc/pickup_and_wear(obj/item/I)
if(QDELETED(I) || I.loc != src)
return
equip_to_appropriate_slot(I)
/mob/living/carbon/monkey/resist_restraints()
var/obj/item/I = null
@@ -119,7 +101,7 @@
cuff_resist(I)
/mob/living/carbon/monkey/proc/should_target(var/mob/living/L)
if(has_trait(TRAIT_PACIFISM))
if(HAS_TRAIT(src, TRAIT_PACIFISM))
return FALSE
if(enemies[L])
@@ -133,7 +115,7 @@
/mob/living/carbon/monkey/proc/handle_combat()
if(pickupTarget)
if(restrained() || blacklistItems[pickupTarget] || (pickupTarget.item_flags & NODROP))
if(restrained() || blacklistItems[pickupTarget] || HAS_TRAIT(pickupTarget, TRAIT_NODROP))
pickupTarget = null
else
pickupTimer++
@@ -143,7 +125,7 @@
pickupTimer = 0
else
INVOKE_ASYNC(src, .proc/walk2derpless, pickupTarget.loc)
if(Adjacent(pickupTarget) || Adjacent(pickupTarget.loc)) // next to target
if(Adjacent(pickupTarget) || Adjacent(pickupTarget.loc)) // next to target
drop_all_held_items() // who cares about these items, i want that one!
if(isturf(pickupTarget.loc)) // on floor
equip_item(pickupTarget)
@@ -167,7 +149,7 @@
battle_screech()
retaliate(L)
return TRUE
else
else
bodyDisposal = locate(/obj/machinery/disposal/) in around
if(bodyDisposal)
target = L
@@ -311,7 +293,8 @@
if(I == pickupTarget)
M.visible_message("<span class='danger'>[src] snatches [pickupTarget] from [M].</span>", "<span class='userdanger'>[src] snatched [pickupTarget]!</span>")
if(M.temporarilyRemoveItemFromInventory(pickupTarget) && !QDELETED(pickupTarget))
equip_item(pickupTarget)
if(!equip_item(pickupTarget))
dropItemToGround(pickupTarget)
else
M.visible_message("<span class='danger'>[src] tried to snatch [pickupTarget] from [M], but failed!</span>", "<span class='userdanger'>[src] tried to grab [pickupTarget]!</span>")
pickpocketing = FALSE
@@ -81,7 +81,7 @@
adjust_bodytemperature(min((loc_temp - bodytemperature) / BODYTEMP_HEAT_DIVISOR, BODYTEMP_HEATING_MAX))
if(bodytemperature > BODYTEMP_HEAT_DAMAGE_LIMIT && !has_trait(TRAIT_RESISTHEAT))
if(bodytemperature > BODYTEMP_HEAT_DAMAGE_LIMIT && !HAS_TRAIT(src, TRAIT_RESISTHEAT))
switch(bodytemperature)
if(360 to 400)
throw_alert("temp", /obj/screen/alert/hot, 1)
@@ -96,7 +96,7 @@
else
apply_damage(HEAT_DAMAGE_LEVEL_2, BURN)
else if(bodytemperature < BODYTEMP_COLD_DAMAGE_LIMIT && !has_trait(TRAIT_RESISTCOLD))
else if(bodytemperature < BODYTEMP_COLD_DAMAGE_LIMIT && !HAS_TRAIT(src, TRAIT_RESISTCOLD))
if(!istype(loc, /obj/machinery/atmospherics/components/unary/cryo_cell))
switch(bodytemperature)
if(200 to 260)
@@ -147,7 +147,7 @@
threatcount += 4 //trigger look_for_perp() since they're nonhuman and very likely hostile
//mindshield implants imply trustworthyness
if(has_trait(TRAIT_MINDSHIELD))
if(HAS_TRAIT(src, TRAIT_MINDSHIELD))
threatcount -= 1
return threatcount
@@ -19,7 +19,7 @@
if(!HD) //Decapitated
return
if(has_trait(TRAIT_HUSK))
if(HAS_TRAIT(src, TRAIT_HUSK))
return
var/hair_hidden = 0
+16 -30
View File
@@ -1,37 +1,17 @@
/mob/living/carbon/treat_message(message)
for(var/datum/brain_trauma/trauma in get_traumas())
message = trauma.on_say(message)
message = ..(message)
var/obj/item/organ/tongue/T = getorganslot(ORGAN_SLOT_TONGUE)
if(!T) //hoooooouaah!
var/regex/tongueless_lower = new("\[gdntke]+", "g")
var/regex/tongueless_upper = new("\[GDNTKE]+", "g")
if(copytext(message, 1, 2) != "*")
message = tongueless_lower.Replace(message, pick("aa","oo","'"))
message = tongueless_upper.Replace(message, pick("AA","OO","'"))
else
message = T.TongueSpeech(message)
if(wear_mask)
message = wear_mask.speechModification(message)
if(head)
message = head.speechModification(message)
return message
/mob/living/carbon/proc/handle_tongueless_speech(mob/living/carbon/speaker, list/speech_args)
var/message = speech_args[SPEECH_MESSAGE]
var/static/regex/tongueless_lower = new("\[gdntke]+", "g")
var/static/regex/tongueless_upper = new("\[GDNTKE]+", "g")
if(message[1] != "*")
message = tongueless_lower.Replace(message, pick("aa","oo","'"))
message = tongueless_upper.Replace(message, pick("AA","OO","'"))
speech_args[SPEECH_MESSAGE] = message
/mob/living/carbon/can_speak_vocal(message)
if(silent)
return 0
return ..()
/mob/living/carbon/get_spans()
. = ..()
var/obj/item/organ/tongue/T = getorganslot(ORGAN_SLOT_TONGUE)
if(T)
. |= T.get_spans()
var/obj/item/I = get_active_held_item()
if(I)
. |= I.get_held_item_speechspans(src)
/mob/living/carbon/could_speak_in_language(datum/language/dt)
var/obj/item/organ/tongue/T = getorganslot(ORGAN_SLOT_TONGUE)
if(T)
@@ -39,10 +19,16 @@
else
. = initial(dt.flags) & TONGUELESS_SPEECH
/mob/living/carbon/Hear(message, atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, message_mode)
/mob/living/carbon/hear_intercept(message, atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, message_mode)
. = ..()
if(!client)
return
for(var/T in get_traumas())
var/datum/brain_trauma/trauma = T
message = trauma.on_hear(message, speaker, message_language, raw_message, radio_freq)
message = trauma.on_hear(message, speaker, message_language, raw_message, radio_freq)
if (src.mind.has_antag_datum(/datum/antagonist/traitor))
message = GLOB.syndicate_code_phrase_regex.Replace(message, "<span class='blue'>$1</span>")
message = GLOB.syndicate_code_response_regex.Replace(message, "<span class='red'>$1</span>")
return message
@@ -279,7 +279,7 @@
else
. += "-robotic"
if(has_trait(TRAIT_HUSK))
if(HAS_TRAIT(src, TRAIT_HUSK))
. += "-husk"
+2 -2
View File
@@ -101,14 +101,14 @@
if(EFFECT_SLUR)
slurring = max(slurring,(effect * hit_percent))
if(EFFECT_STUTTER)
if((status_flags & CANSTUN) && !has_trait(TRAIT_STUNIMMUNE)) // stun is usually associated with stutter
if((status_flags & CANSTUN) && !HAS_TRAIT(src, TRAIT_STUNIMMUNE)) // stun is usually associated with stutter
stuttering = max(stuttering,(effect * hit_percent))
if(EFFECT_EYE_BLUR)
blur_eyes(effect * hit_percent)
if(EFFECT_DROWSY)
drowsyness = max(drowsyness,(effect * hit_percent))
if(EFFECT_JITTER)
if((status_flags & CANSTUN) && !has_trait(TRAIT_STUNIMMUNE))
if((status_flags & CANSTUN) && !HAS_TRAIT(src, TRAIT_STUNIMMUNE))
jitteriness = max(jitteriness,(effect * hit_percent))
return 1
+2 -2
View File
@@ -109,7 +109,7 @@
ExtinguishMob()
return
var/datum/gas_mixture/G = loc.return_air() // Check if we're standing in an oxygenless environment
if(!G.gases[/datum/gas/oxygen] || G.gases[/datum/gas/oxygen][MOLES] < 1)
if(G.gases[/datum/gas/oxygen] < 1)
ExtinguishMob() //If there's no oxygen in the tile we're on, put out the fire
return
var/turf/location = get_turf(src)
@@ -126,7 +126,7 @@
/mob/living/proc/handle_traits()
//Eyes
if(eye_blind) //blindness, heals slowly over time
if(!stat && !(has_trait(TRAIT_BLIND)))
if(!stat && !(HAS_TRAIT(src, TRAIT_BLIND)))
eye_blind = max(eye_blind-1,0)
if(client && !eye_blind)
clear_alert("blind")
+67 -24
View File
@@ -103,21 +103,23 @@
//CIT CHANGES START HERE - makes it so resting stops you from moving through standing folks without a short delay
if(resting && !L.resting)
if(attemptingcrawl)
return TRUE
if(getStaminaLoss() >= STAMINA_SOFTCRIT)
to_chat(src, "<span class='warning'>You're too exhausted to crawl under [L].</span>")
return TRUE
attemptingcrawl = TRUE
var/origtargetloc = L.loc
visible_message("<span class='notice'>[src] is attempting to crawl under [L].</span>", "<span class='notice'>You are now attempting to crawl under [L].</span>")
if(do_after(src, CRAWLUNDER_DELAY, target = src))
if(resting)
var/src_passmob = (pass_flags & PASSMOB)
pass_flags |= PASSMOB
Move(origtargetloc)
if(!src_passmob)
pass_flags &= ~PASSMOB
if(!pulledby)
if(attemptingcrawl)
return TRUE
if(getStaminaLoss() >= STAMINA_SOFTCRIT)
to_chat(src, "<span class='warning'>You're too exhausted to crawl under [L].</span>")
return TRUE
attemptingcrawl = TRUE
visible_message("<span class='notice'>[src] is attempting to crawl under [L].</span>", "<span class='notice'>You are now attempting to crawl under [L].</span>")
if(!do_after(src, CRAWLUNDER_DELAY, target = src) || !resting)
attemptingcrawl = FALSE
return TRUE
var/src_passmob = (pass_flags & PASSMOB)
pass_flags |= PASSMOB
Move(origtargetloc)
if(!src_passmob)
pass_flags &= ~PASSMOB
attemptingcrawl = FALSE
return TRUE
//END OF CIT CHANGES
@@ -168,7 +170,7 @@
return 1
if(isliving(M))
var/mob/living/L = M
if(L.has_trait(TRAIT_PUSHIMMUNE))
if(HAS_TRAIT(L, TRAIT_PUSHIMMUNE))
return 1
//If they're a human, and they're not in help intent, block pushing
if(ishuman(M) && (M.a_intent != INTENT_HELP))
@@ -261,7 +263,7 @@
var/mob/M = AM
log_combat(src, M, "grabbed", addition="passive grab")
if(!supress_message)
if(!supress_message && !(iscarbon(AM) && HAS_TRAIT(src, TRAIT_STRONG_GRABBER)))
visible_message("<span class='warning'>[src] has grabbed [M][(zone_selected == "l_arm" || zone_selected == "r_arm")? " by their hands":" passively"]!</span>") //Cit change - And they thought ERP was bad.
if(!iscarbon(src))
M.LAssailant = null
@@ -280,6 +282,11 @@
if(D.spread_flags & DISEASE_SPREAD_CONTACT_SKIN)
ContactContractDisease(D)
if(iscarbon(L))
var/mob/living/carbon/C = L
if(HAS_TRAIT(src, TRAIT_STRONG_GRABBER))
C.grippedby(src)
//mob verbs are a lot faster than object verbs
//for more info on why this is not atom/pull, see examinate() in mob.dm
/mob/living/verb/pulled(atom/movable/AM as mob|obj in oview(1))
@@ -304,7 +311,7 @@
/mob/living/pointed(atom/A as mob|obj|turf in view())
if(incapacitated())
return FALSE
if(has_trait(TRAIT_DEATHCOMA))
if(HAS_TRAIT(src, TRAIT_DEATHCOMA))
return FALSE
if(!..())
return FALSE
@@ -692,13 +699,13 @@
// 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)
/mob/living/stripPanelUnequip(obj/item/what, mob/who, where)
if(what.item_flags & NODROP)
if(HAS_TRAIT(what, TRAIT_NODROP))
to_chat(src, "<span class='warning'>You can't remove \the [what.name], it appears to be stuck!</span>")
return
who.visible_message("<span class='danger'>[src] tries to remove [who]'s [what.name].</span>", \
"<span class='userdanger'>[src] tries to remove [who]'s [what.name].</span>")
what.add_fingerprint(src)
if(do_mob(src, who, what.strip_delay))
if(do_mob(src, who, what.strip_delay, ignorehelditem = TRUE))
if(what && Adjacent(who))
if(islist(where))
var/list/L = where
@@ -717,7 +724,7 @@
// Override if a certain mob should be behave differently when placing items (can't, for example)
/mob/living/stripPanelEquip(obj/item/what, mob/who, where)
what = src.get_active_held_item()
if(what && (what.item_flags & NODROP))
if(what && HAS_TRAIT(what, TRAIT_NODROP))
to_chat(src, "<span class='warning'>You can't put \the [what.name] on [who], it's stuck to your hand!</span>")
return
if(what)
@@ -812,7 +819,7 @@
/mob/living/proc/harvest(mob/living/user) //used for extra objects etc. in butchering
return
/mob/living/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE)
/mob/living/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE, no_tk=FALSE)
if(incapacitated())
to_chat(src, "<span class='warning'>You can't do that right now!</span>")
return FALSE
@@ -887,7 +894,7 @@
/mob/living/rad_act(amount)
. = ..()
if(!amount || (amount < RAD_MOB_SKIN_PROTECTION) || has_trait(TRAIT_RADIMMUNE))
if(!amount || (amount < RAD_MOB_SKIN_PROTECTION) || HAS_TRAIT(src, TRAIT_RADIMMUNE))
return
amount -= RAD_BACKGROUND_RADIATION // This will always be at least 1 because of how skin protection is calculated
@@ -903,7 +910,7 @@
. = ..()
if(.)
return
if((magic && has_trait(TRAIT_ANTIMAGIC)) || (holy && has_trait(TRAIT_HOLY)))
if((magic && HAS_TRAIT(src, TRAIT_ANTIMAGIC)) || (holy && HAS_TRAIT(src, TRAIT_HOLY)))
return src
/mob/living/proc/fakefireextinguish()
@@ -986,7 +993,7 @@
//Updates canmove, lying and icons. Could perhaps do with a rename but I can't think of anything to describe it.
//Robots, animals and brains have their own version so don't worry about them
/mob/living/proc/update_canmove()
var/ko = IsKnockdown() || IsUnconscious() || (stat && (stat != SOFT_CRIT || pulledby)) || (has_trait(TRAIT_DEATHCOMA))
var/ko = IsKnockdown() || IsUnconscious() || (stat && (stat != SOFT_CRIT || pulledby)) || (HAS_TRAIT(src, TRAIT_DEATHCOMA))
var/move_and_fall = stat == SOFT_CRIT && !pulledby
var/chokehold = pulledby && pulledby.grab_state >= GRAB_NECK
var/buckle_lying = !(buckled && !buckled.buckle_lying)
@@ -1180,3 +1187,39 @@
update_transform()
if("lighting_alpha")
sync_lighting_plane_alpha()
/mob/living/proc/do_adrenaline(
stamina_boost = 150,
put_on_feet = TRUE,
clamp_unconscious_to = 0,
clamp_immobility_to = 0,
reset_misc = TRUE,
healing_chems = list("inaprovaline" = 3, "synaptizine" = 10, "regen_jelly" = 10, "stimulants" = 10),
message = "<span class='boldnotice'>You feel a surge of energy!</span>",
stamina_buffer_boost = 0, //restores stamina buffer rather than just health
scale_stamina_loss_recovery, //defaults to null. if this is set, restores loss * this stamina. make sure it's a fraction.
stamina_loss_recovery_bypass = 0 //amount of stamina loss to ignore during calculation
)
to_chat(src, message)
if(AmountSleeping() > clamp_unconscious_to)
SetSleeping(clamp_unconscious_to)
if(AmountUnconscious() > clamp_unconscious_to)
SetUnconscious(clamp_unconscious_to)
if(AmountStun() > clamp_immobility_to)
SetStun(clamp_immobility_to)
if(AmountKnockdown() > clamp_immobility_to)
SetKnockdown(clamp_immobility_to)
adjustStaminaLoss(min(0, -stamina_boost))
adjustStaminaLossBuffered(min(0, -stamina_buffer_boost))
if(scale_stamina_loss_recovery)
adjustStaminaLoss(min(-((getStaminaLoss() - stamina_loss_recovery_bypass) * scale_stamina_loss_recovery), 0))
if(put_on_feet)
resting = FALSE
lying = FALSE
if(reset_misc)
stuttering = 0
updatehealth()
update_stamina()
update_canmove()
for(var/chem in healing_chems)
reagents.add_reagent(chem, healing_chems[chem])
+26 -20
View File
@@ -1,24 +1,18 @@
/mob/living/proc/run_armor_check(def_zone = null, attack_flag = "melee", absorb_text = null, soften_text = null, armour_penetration, penetrated_text)
/mob/living/proc/run_armor_check(def_zone = null, attack_flag = "melee", absorb_text = "Your armor absorbs the blow!", soften_text = "Your armor softens the blow!", armour_penetration, penetrated_text = "Your armor was penetrated!")
var/armor = getarmor(def_zone, attack_flag)
//the if "armor" check is because this is used for everything on /living, including humans
if(armor && armour_penetration)
armor = max(0, armor - armour_penetration)
if(penetrated_text)
to_chat(src, "<span class='userdanger'>[penetrated_text]</span>")
else
to_chat(src, "<span class='userdanger'>Your armor was penetrated!</span>")
to_chat(src, "<span class='danger'>[penetrated_text]</span>")
else if(armor >= 100)
if(absorb_text)
to_chat(src, "<span class='userdanger'>[absorb_text]</span>")
else
to_chat(src, "<span class='userdanger'>Your armor absorbs the blow!</span>")
to_chat(src, "<span class='danger'>[absorb_text]</span>")
else if(armor > 0)
if(soften_text)
to_chat(src, "<span class='userdanger'>[soften_text]</span>")
else
to_chat(src, "<span class='userdanger'>Your armor softens the blow!</span>")
to_chat(src, "<span class='danger'>[soften_text]</span>")
return armor
@@ -43,7 +37,7 @@
return
/mob/living/bullet_act(obj/item/projectile/P, def_zone)
var/armor = run_armor_check(def_zone, P.flag, "","",P.armour_penetration)
var/armor = run_armor_check(def_zone, P.flag, null, null, P.armour_penetration, null)
if(!P.nodamage)
apply_damage(P.damage, P.damage_type, def_zone, armor)
if(P.dismemberment)
@@ -130,6 +124,18 @@
if(user == anchored || !isturf(user.loc))
return FALSE
//pacifist vore check.
if(user.pulling && HAS_TRAIT(user, TRAIT_PACIFISM) && user.voremode) //they can only do heals, noisy guts, absorbing (technically not harm)
if(ismob(user.pulling))
var/mob/P = user.pulling
if(src != user)
to_chat(user, "<span class='notice'>You can't risk digestion!</span>")
return FALSE
else
user.vore_attack(user, P, user)
return
//normal vore check.
if(user.pulling && user.grab_state == GRAB_AGGRESSIVE && user.voremode)
if(ismob(user.pulling))
var/mob/P = user.pulling
@@ -143,11 +149,11 @@
user.start_pulling(src, supress_message)
return
if(!(status_flags & CANPUSH) || has_trait(TRAIT_PUSHIMMUNE))
if(!(status_flags & CANPUSH) || HAS_TRAIT(src, TRAIT_PUSHIMMUNE))
to_chat(user, "<span class='warning'>[src] can't be grabbed more aggressively!</span>")
return FALSE
if(user.has_trait(TRAIT_PACIFISM))
if(HAS_TRAIT(user, TRAIT_PACIFISM))
to_chat(user, "<span class='notice'>You don't want to risk hurting [src]!</span>")
return FALSE
@@ -210,7 +216,7 @@
M.Feedstop()
return // can't attack while eating!
if(has_trait(TRAIT_PACIFISM))
if(HAS_TRAIT(src, TRAIT_PACIFISM))
to_chat(M, "<span class='notice'>You don't want to hurt anyone!</span>")
return FALSE
@@ -227,7 +233,7 @@
M.visible_message("<span class='notice'>\The [M] [M.friendly] [src]!</span>")
return FALSE
else
if(M.has_trait(TRAIT_PACIFISM))
if(HAS_TRAIT(M, TRAIT_PACIFISM))
to_chat(M, "<span class='notice'>You don't want to hurt anyone!</span>")
return FALSE
@@ -246,7 +252,7 @@
return FALSE
if (M.a_intent == INTENT_HARM)
if(M.has_trait(TRAIT_PACIFISM))
if(HAS_TRAIT(M, TRAIT_PACIFISM))
to_chat(M, "<span class='notice'>You don't want to hurt anyone!</span>")
return FALSE
@@ -272,7 +278,7 @@
return FALSE
else
if(L.has_trait(TRAIT_PACIFISM))
if(HAS_TRAIT(L, TRAIT_PACIFISM))
to_chat(L, "<span class='notice'>You don't want to hurt anyone!</span>")
return
@@ -297,7 +303,7 @@
grabbedby(M)
return FALSE
if("harm")
if(M.has_trait(TRAIT_PACIFISM))
if(HAS_TRAIT(M, TRAIT_PACIFISM))
to_chat(M, "<span class='notice'>You don't want to hurt anyone!</span>")
return FALSE
M.do_attack_animation(src)
@@ -321,7 +327,7 @@
SEND_SIGNAL(src, COMSIG_LIVING_ELECTROCUTE_ACT, shock_damage)
if(tesla_shock && (flags_1 & TESLA_IGNORE_1))
return FALSE
if(has_trait(TRAIT_SHOCKIMMUNE))
if(HAS_TRAIT(src, TRAIT_SHOCKIMMUNE))
return FALSE
if(shock_damage > 0)
if(!illusion)
@@ -391,7 +397,7 @@
//called when the mob receives a bright flash
/mob/living/proc/flash_act(intensity = 1, override_blindness_check = 0, affect_silicon = 0, visual = 0, type = /obj/screen/fullscreen/flash)
if(get_eye_protection() < intensity && (override_blindness_check || !(has_trait(TRAIT_BLIND))))
if(get_eye_protection() < intensity && (override_blindness_check || !(HAS_TRAIT(src, TRAIT_BLIND))))
overlay_fullscreen("flash", type)
addtimer(CALLBACK(src, .proc/clear_fullscreen, "flash", 25), 25)
return TRUE
@@ -33,8 +33,6 @@
var/incorporeal_move = FALSE //FALSE is off, INCORPOREAL_MOVE_BASIC is normal, INCORPOREAL_MOVE_SHADOW is for ninjas
//and INCORPOREAL_MOVE_JAUNT is blocked by holy water/salt
var/list/status_traits = list()
var/list/roundstart_quirks = list()
var/list/surgeries = list() //a list of surgery datums. generally empty, they're added when the player wants them.
+17 -5
View File
@@ -175,13 +175,16 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
else
src.log_talk(message, LOG_SAY, forced_by=forced)
message = treat_message(message)
message = treat_message(message) // unfortunately we still need this
var/sigreturn = SEND_SIGNAL(src, COMSIG_MOB_SAY, args)
if (sigreturn & COMPONENT_UPPERCASE_SPEECH)
message = uppertext(message)
if(!message)
return
last_words = message
spans |= get_spans()
spans |= speech_span
if(language)
var/datum/language/L = GLOB.language_datum_instances[language]
@@ -229,9 +232,14 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
// Recompose message for AI hrefs, language incomprehension.
message = compose_message(speaker, message_language, raw_message, radio_freq, spans, message_mode)
message = hear_intercept(message, speaker, message_language, raw_message, radio_freq, spans, message_mode)
show_message(message, 2, deaf_message, deaf_type)
return message
/mob/living/proc/hear_intercept(message, atom/movable/speaker, datum/language/message_language, raw_message, radio_freq, list/spans, message_mode)
return message
/mob/living/send_speech(message, message_range = 6, obj/source = src, bubble_type = bubble_icon, list/spans, datum/language/message_language=null, message_mode)
var/static/list/eavesdropping_modes = list(MODE_WHISPER = TRUE, MODE_WHISPER_CRIT = TRUE)
var/eavesdrop_range = 0
@@ -301,7 +309,7 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
return 1
/mob/living/proc/can_speak_vocal(message) //Check AFTER handling of xeno and ling channels
if(has_trait(TRAIT_MUTE))
if(HAS_TRAIT(src, TRAIT_MUTE))
return 0
if(is_muzzled())
@@ -327,6 +335,10 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
return null
/mob/living/proc/treat_message(message)
if(HAS_TRAIT(src, TRAIT_UNINTELLIGIBLE_SPEECH))
message = unintelligize(message)
if(derpspeech)
message = derpspeech(message, stuttering)
@@ -389,8 +401,8 @@ GLOBAL_LIST_INIT(department_radio_keys, list(
else
. = ..()
/mob/living/whisper(message, bubble_type, var/list/spans = list(), sanitize = TRUE, datum/language/language = null)
say("#[message]", bubble_type, spans, sanitize, language)
/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)
/mob/living/get_language_holder(shadow=TRUE)
if(mind && shadow)
+39 -74
View File
@@ -86,12 +86,13 @@
var/datum/action/innate/deploy_last_shell/redeploy_action = new
var/chnotify = 0
var/multicam_on = FALSE
var/obj/screen/movable/pic_in_pic/ai/master_multicam
var/list/multicam_screens = list()
var/list/all_eyes = list()
var/max_multicams = 6
var/display_icon_override
/mob/living/silicon/ai/Initialize(mapload, datum/ai_laws/L, mob/target_ai)
. = ..()
@@ -127,6 +128,8 @@
create_eye()
apply_pref_name("ai")
set_core_display_icon()
holo_icon = getHologramIcon(icon('icons/mob/ai.dmi',"default"))
spark_system = new /datum/effect_system/spark_spread()
@@ -172,81 +175,34 @@
fire_stacks = 0
. = ..()
/mob/living/silicon/ai/proc/set_core_display_icon(input, client/C)
if(client && !C)
C = client
if(!input && !C?.prefs?.preferred_ai_core_display)
icon_state = initial(icon_state)
else
var/preferred_icon = input ? input : C.prefs.preferred_ai_core_display
icon_state = resolve_ai_icon(preferred_icon)
/mob/living/silicon/ai/verb/pick_icon()
set category = "AI Commands"
set name = "Set AI Core Display"
if(incapacitated())
return
var/list/iconstates = GLOB.ai_core_display_screens
for(var/option in iconstates)
if(option == "Random")
iconstates[option] = image(icon = src.icon, icon_state = "ai-random")
continue
iconstates[option] = image(icon = src.icon, icon_state = resolve_ai_icon(option))
var/icontype = input("Please, select a display!", "AI", null/*, null*/) in list("Clown", ":thinking:", "Monochrome", "Blue", "Inverted", "Firewall", "Green", "Red", "Static", "Red October", "House", "Heartline", "Hades", "Helios", "President", "Syndicat Meow", "Alien", "Too Deep", "Triumvirate", "Triumvirate-M", "Text", "Matrix", "Dorf", "Bliss", "Not Malf", "Fuzzy", "Goon", "Database", "Glitchman", "Murica", "Nanotrasen", "Gentoo", "Angel", "TechDemon") //CIT CHANGE - adds 'TechDemon
if(icontype == "Clown")
icon_state = "ai-clown2"
else if (icontype == ":thinking:")
icon_state = "ai-:thinking:"
else if(icontype == "Monochrome")
icon_state = "ai-mono"
else if(icontype == "Blue")
icon_state = "ai"
else if(icontype == "Inverted")
icon_state = "ai-u"
else if(icontype == "Firewall")
icon_state = "ai-magma"
else if(icontype == "Green")
icon_state = "ai-wierd"
else if(icontype == "Red")
icon_state = "ai-malf"
else if(icontype == "Static")
icon_state = "ai-static"
else if(icontype == "Red October")
icon_state = "ai-redoctober"
else if(icontype == "House")
icon_state = "ai-house"
else if(icontype == "Heartline")
icon_state = "ai-heartline"
else if(icontype == "Hades")
icon_state = "ai-hades"
else if(icontype == "Helios")
icon_state = "ai-helios"
else if(icontype == "President")
icon_state = "ai-pres"
else if(icontype == "Syndicat Meow")
icon_state = "ai-syndicatmeow"
else if(icontype == "Alien")
icon_state = "ai-alien"
else if(icontype == "Too Deep")
icon_state = "ai-toodeep"
else if(icontype == "Triumvirate")
icon_state = "ai-triumvirate"
else if(icontype == "Triumvirate-M")
icon_state = "ai-triumvirate-malf"
else if(icontype == "Text")
icon_state = "ai-text"
else if(icontype == "Matrix")
icon_state = "ai-matrix"
else if(icontype == "Dorf")
icon_state = "ai-dorf"
else if(icontype == "Bliss")
icon_state = "ai-bliss"
else if(icontype == "Not Malf")
icon_state = "ai-notmalf"
else if(icontype == "Fuzzy")
icon_state = "ai-fuzz"
else if(icontype == "Goon")
icon_state = "ai-goon"
else if(icontype == "Database")
icon_state = "ai-database"
else if(icontype == "Glitchman")
icon_state = "ai-glitchman"
else if(icontype == "Murica")
icon_state = "ai-murica"
else if(icontype == "Nanotrasen")
icon_state = "ai-nanotrasen"
else if(icontype == "Gentoo")
icon_state = "ai-gentoo"
else if(icontype == "Angel")
icon_state = "ai-angel"
else if(icontype == "TechDemon") //CIT CHANGE - adds 'TechDemon
icon_state = "ai-techdemon"
view_core()
var/ai_core_icon = show_radial_menu(src, src , iconstates, radius = 42)
if(!ai_core_icon || incapacitated())
return
display_icon_override = ai_core_icon
set_core_display_icon(ai_core_icon)
/mob/living/silicon/ai/Stat()
..()
@@ -332,8 +288,17 @@
/mob/living/silicon/ai/can_interact_with(atom/A)
. = ..()
var/turf/ai = get_turf(src)
var/turf/target = get_turf(A)
if (.)
return
if(!target)
return
if ((ai.z != target.z) && !is_station_level(ai.z))
return FALSE
if (istype(loc, /obj/item/aicard))
var/turf/T0 = get_turf(src)
var/turf/T1 = get_turf(A)
@@ -823,7 +788,7 @@
return TRUE
return ..()
/mob/living/silicon/ai/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE)
/mob/living/silicon/ai/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE, no_tk=FALSE)
if(control_disabled || incapacitated())
to_chat(src, "<span class='warning'>You can't do that right now!</span>")
return FALSE
@@ -915,9 +880,9 @@
clear_fullscreen("remote_view", 0)
/mob/living/silicon/ai/revive(full_heal = 0, admin_revive = 0)
if(..()) //successfully ressuscitated from death
icon_state = "ai"
. = 1
. = ..()
if(.) //successfully ressuscitated from death
set_core_display_icon(display_icon_override)
/mob/living/silicon/ai/proc/malfhacked(obj/machinery/power/apc/apc)
malfhack = null
+4 -1
View File
@@ -4,10 +4,13 @@
. = ..()
if("[icon_state]_dead" in icon_states(src.icon,1))
var/old_icon = icon_state
if("[icon_state]_dead" in icon_states(icon))
icon_state = "[icon_state]_dead"
else
icon_state = "ai_dead"
if("[old_icon]_death_transition" in icon_states(icon))
flick("[old_icon]_death_transition", src)
cameraFollow = null
+1 -1
View File
@@ -49,7 +49,7 @@
else
padloc = "(UNKNOWN)"
src.log_talk(message, LOG_SAY, tag="HOLOPAD in [padloc]")
send_speech(message, 7, T, "robot", get_spans(), language)
send_speech(message, 7, T, "robot", language = language)
to_chat(src, "<i><span class='game say'>Holopad transmitted, <span class='name'>[real_name]</span> <span class='message robot'>\"[message]\"</span></span></i>")
else
to_chat(src, "No holopad connected.")
+1 -1
View File
@@ -183,7 +183,7 @@
// See software.dm for Topic()
/mob/living/silicon/pai/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE)
/mob/living/silicon/pai/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE, no_tk=FALSE)
if(be_close && !in_range(M, src))
to_chat(src, "<span class='warning'>You are too far away!</span>")
return FALSE
@@ -29,6 +29,13 @@
if(!L.temporarilyRemoveItemFromInventory(card))
to_chat(src, "<span class='warning'>Error: Unable to expand to mobile form. Chassis is restrained by some device or person.</span>")
return FALSE
if(istype(card.loc, /obj/item/integrated_circuit/input/pAI_connector))
var/obj/item/integrated_circuit/input/pAI_connector/C = card.loc
C.RemovepAI()
C.visible_message("<span class='notice'>[src] ejects itself from [C]!</span>")
playsound(src, 'sound/items/Crowbar.ogg', 50, 1)
C.installed_pai = null
C.push_data()
forceMove(get_turf(card))
card.forceMove(src)
if(client)
@@ -544,9 +544,9 @@
if (total_moles)
for(var/id in env_gases)
var/gas_level = env_gases[id][MOLES]/total_moles
var/gas_level = env_gases[id]/total_moles
if(gas_level > 0.01)
dat += "[env_gases[id][GAS_META][META_GAS_NAME]]: [round(gas_level*100)]%<br>"
dat += "[GLOB.meta_gas_names[id]]: [round(gas_level*100)]%<br>"
dat += "Temperature: [round(environment.temperature-T0C)]&deg;C<br>"
dat += "<a href='byond://?src=[REF(src)];software=atmosensor;sub=0'>Refresh Reading</a> <br>"
dat += "<br>"
+14 -1
View File
@@ -580,6 +580,19 @@
else
return ..()
/mob/living/silicon/robot/crowbar_act(mob/living/user, obj/item/I) //TODO: make fucking everything up there in that attackby() proc use the proper tool_act() procs. But honestly, who has time for that? 'cause I know for sure that you, the person reading this, sure as hell doesn't.
var/validbreakout = FALSE
for(var/obj/item/dogborg/sleeper/S in held_items)
if(!LAZYLEN(S.contents))
continue
if(!validbreakout)
visible_message("<span class='notice'>[user] wedges [I] into the crevice separating [S] from [src]'s chassis, and begins to pry...</span>", "<span class='notice'>You wedge [I] into the crevice separating [S] from [src]'s chassis, and begin to pry...</span>")
validbreakout = TRUE
S.go_out()
if(validbreakout)
return TRUE
return ..()
/mob/living/silicon/robot/verb/unlock_own_cover()
set category = "Robot Commands"
set name = "Unlock Cover"
@@ -910,7 +923,7 @@
if(DISCONNECT) //Tampering with the wires
to_chat(connected_ai, "<br><br><span class='notice'>NOTICE - Remote telemetry lost with [name].</span><br>")
/mob/living/silicon/robot/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE)
/mob/living/silicon/robot/canUseTopic(atom/movable/M, be_close=FALSE, no_dextery=FALSE, no_tk=FALSE)
if(stat || lockcharge || low_power_mode)
to_chat(src, "<span class='warning'>You can't do that right now!</span>")
return FALSE
@@ -119,7 +119,7 @@
if(I.loc != src)
I.forceMove(src)
modules += I
I.item_flags |= NODROP
ADD_TRAIT(I, TRAIT_NODROP, CYBORG_ITEM_TRAIT)
I.mouse_opacity = MOUSE_OPACITY_OPAQUE
if(nonstandard)
added_modules += I
+1 -5
View File
@@ -1,14 +1,10 @@
/mob/living/silicon/get_spans()
return ..() | SPAN_ROBOT
/mob/living/proc/robot_talk(message)
log_talk(message, LOG_SAY)
var/desig = "Default Cyborg" //ezmode for taters
if(issilicon(src))
var/mob/living/silicon/S = src
desig = trim_left(S.designation + " " + S.job)
var/message_a = say_quote(message, get_spans())
var/message_a = say_quote(message)
var/rendered = "Robotic Talk, <span class='name'>[name]</span> <span class='message'>[message_a]</span>"
for(var/mob/M in GLOB.player_list)
if(M.binarycheck())
@@ -12,6 +12,7 @@
possible_a_intents = list(INTENT_HELP, INTENT_HARM)
mob_biotypes = list(MOB_ROBOTIC)
rad_flags = RAD_PROTECT_CONTENTS | RAD_NO_CONTAMINATE
speech_span = SPAN_ROBOT
var/datum/ai_laws/laws = null//Now... THEY ALL CAN ALL HAVE LAWS
var/last_lawchange_announce = 0
@@ -69,6 +70,9 @@
/mob/living/silicon/contents_explosion(severity, target)
return
/mob/living/silicon/prevent_content_explosion()
return TRUE
/mob/living/silicon/proc/cancelAlarm()
return
@@ -15,7 +15,7 @@
grabbedby(M)
if("harm", "disarm")
if(M.has_trait(TRAIT_PACIFISM))
if(HAS_TRAIT(M, TRAIT_PACIFISM))
to_chat(M, "<span class='notice'>You don't want to hurt [src]!</span>")
return
M.do_attack_animation(src, ATTACK_EFFECT_PUNCH)
@@ -29,7 +29,7 @@
/mob/living/simple_animal/attack_hulk(mob/living/carbon/human/user, does_attack_animation = 0)
if(user.a_intent == INTENT_HARM)
if(user.has_trait(TRAIT_PACIFISM))
if(HAS_TRAIT(user, TRAIT_PACIFISM))
to_chat(user, "<span class='notice'>You don't want to hurt [src]!</span>")
return FALSE
..(user, 1)
@@ -23,6 +23,7 @@
verb_yell = "alarms"
initial_language_holder = /datum/language_holder/synthetic
bubble_icon = "machine"
speech_span = SPAN_ROBOT
faction = list("neutral", "silicon" , "turret")
@@ -348,13 +349,10 @@
if((!on) || (!message))
return
if(channel && Radio.channels[channel])// Use radio if we have channel key
Radio.talk_into(src, message, channel, get_spans(), get_default_language())
Radio.talk_into(src, message, channel)
else
say(message)
/mob/living/simple_animal/bot/get_spans()
return ..() | SPAN_ROBOT
/mob/living/simple_animal/bot/radio(message, message_mode, list/spans, language)
. = ..()
if(. != 0)
@@ -505,3 +505,33 @@
to_chat(user, "<span class='notice'>You unbolt [src]'s energy swords</span>")
for(var/IS in 1 to swordamt)
new /obj/item/melee/transforming/energy/sword/saber(Tsec)
//Firebot Assembly
/obj/item/bot_assembly/firebot
name = "incomplete firebot assembly"
desc = "A fire extinguisher with an arm attached to it."
icon_state = "firebot_arm"
created_name = "Firebot"
/obj/item/bot_assembly/firebot/attackby(obj/item/I, mob/user, params)
..()
switch(build_step)
if(ASSEMBLY_FIRST_STEP)
if(istype(I, /obj/item/clothing/head/hardhat/red))
if(!user.temporarilyRemoveItemFromInventory(I))
return
to_chat(user,"<span class='notice'>You add the [I] to [src]!</span>")
icon_state = "firebot_helmet"
desc = "An incomplete firebot assembly with a fire helmet."
qdel(I)
build_step++
if(ASSEMBLY_SECOND_STEP)
if(isprox(I))
if(!can_finish_build(I, user))
return
to_chat(user, "<span class='notice'>You add the [I] to [src]! Beep Boop!</span>")
var/mob/living/simple_animal/bot/firebot/F = new(drop_location())
F.name = created_name
qdel(I)
qdel(src)
@@ -0,0 +1,325 @@
//Firebot
#define SPEECH_INTERVAL 300 // Time between idle speeches
#define DETECTED_VOICE_INTERVAL 300 // Time between fire detected callouts
#define FOAM_INTERVAL 50 // Time between deployment of fire fighting foam
/mob/living/simple_animal/bot/firebot
name = "\improper Firebot"
desc = "A little fire extinguishing bot. He looks rather anxious."
icon = 'icons/mob/aibots.dmi'
icon_state = "firebot"
density = FALSE
anchored = FALSE
health = 25
maxHealth = 25
spacewalk = TRUE
radio_key = /obj/item/encryptionkey/headset_eng
radio_channel = "Engineering"
bot_type = FIRE_BOT
model = "Firebot"
bot_core = /obj/machinery/bot_core/firebot
window_id = "autoextinguisher"
window_name = "Mobile Fire Extinguisher v1.0"
path_image_color = "#FFA500"
var/atom/target_fire
var/atom/old_target_fire
var/obj/item/extinguisher/internal_ext
var/last_found = 0
var/speech_cooldown = 0
var/detected_cooldown = 0
var/foam_cooldown = 0
var/extinguish_people = TRUE
var/extinguish_fires = TRUE
var/stationary_mode = FALSE
/mob/living/simple_animal/bot/firebot/Initialize()
. = ..()
update_icon()
var/datum/job/engineer/J = new/datum/job/engineer
access_card.access += J.get_access()
prev_access = access_card.access
create_extinguisher()
/mob/living/simple_animal/bot/firebot/bot_reset()
create_extinguisher()
/mob/living/simple_animal/bot/firebot/proc/create_extinguisher()
internal_ext = new /obj/item/extinguisher(src)
internal_ext.safety = FALSE
internal_ext.precision = TRUE
internal_ext.max_water = INFINITY
internal_ext.refill()
/mob/living/simple_animal/bot/firebot/UnarmedAttack(atom/A)
if(!on)
return
if(internal_ext)
internal_ext.afterattack(A, src)
else
return ..()
/mob/living/simple_animal/bot/firebot/RangedAttack(atom/A)
if(!on)
return
if(internal_ext)
internal_ext.afterattack(A, src)
else
return ..()
/mob/living/simple_animal/bot/firebot/turn_on()
. = ..()
update_icon()
/mob/living/simple_animal/bot/firebot/turn_off()
..()
update_icon()
/mob/living/simple_animal/bot/firebot/bot_reset()
..()
target_fire = null
old_target_fire = null
ignore_list = list()
anchored = FALSE
update_icon()
/mob/living/simple_animal/bot/firebot/proc/soft_reset()
path = list()
target_fire = null
mode = BOT_IDLE
last_found = world.time
update_icon()
/mob/living/simple_animal/bot/firebot/set_custom_texts()
text_hack = "You corrupt [name]'s safety protocols."
text_dehack = "You detect errors in [name] and reset his programming."
text_dehack_fail = "[name] is not responding to reset commands!"
/mob/living/simple_animal/bot/firebot/get_controls(mob/user)
var/dat
dat += hack(user)
dat += showpai(user)
dat += "<TT><B>Mobile Fire Extinguisher v1.0</B></TT><BR><BR>"
dat += "Status: <A href='?src=[REF(src)];power=1'>[on ? "On" : "Off"]</A><BR>"
dat += "Maintenance panel panel is [open ? "opened" : "closed"]<BR>"
dat += "Behaviour controls are [locked ? "locked" : "unlocked"]<BR>"
if(!locked || issilicon(user) || IsAdminGhost(user))
dat += "Extinguish Fires: <A href='?src=[REF(src)];operation=extinguish_fires'>[extinguish_fires ? "Yes" : "No"]</A><BR>"
dat += "Extinguish People: <A href='?src=[REF(src)];operation=extinguish_people'>[extinguish_people ? "Yes" : "No"]</A><BR>"
dat += "Patrol Station: <A href='?src=[REF(src)];operation=patrol'>[auto_patrol ? "Yes" : "No"]</A><BR>"
dat += "Stationary Mode: <a href='?src=[REF(src)];operation=stationary_mode'>[stationary_mode ? "Yes" : "No"]</a><br>"
return dat
/mob/living/simple_animal/bot/firebot/emag_act(mob/user)
..()
if(emagged == 1)
if(user)
to_chat(user, "<span class='danger'>[src] buzzes and beeps.</span>")
audible_message("<span class='danger'>[src] buzzes oddly!</span>")
playsound(src, "sparks", 75, TRUE)
if(user)
old_target_fire = user
extinguish_fires = FALSE
extinguish_people = TRUE
internal_ext.chem = "clf3" //Refill the internal extinguisher with liquid fire
internal_ext.power = 3
internal_ext.safety = FALSE
internal_ext.precision = FALSE
internal_ext.max_water = INFINITY
internal_ext.refill()
/mob/living/simple_animal/bot/firebot/Topic(href, href_list)
if(..())
return TRUE
switch(href_list["operation"])
if("extinguish_fires")
extinguish_fires = !extinguish_fires
if("extinguish_people")
extinguish_people = !extinguish_people
if("stationary_mode")
stationary_mode = !stationary_mode
update_controls()
update_icon()
/mob/living/simple_animal/bot/firebot/proc/is_burning(atom/target)
if(ismob(target))
var/mob/living/M = target
if(M.on_fire || (emagged == 1 && !M.on_fire))
return TRUE
else if(isturf(target))
var/turf/open/T = target
if(T.active_hotspot)
return TRUE
return FALSE
/mob/living/simple_animal/bot/firebot/handle_automated_action()
if(!..())
return
if(IsStun())
old_target_fire = target_fire
target_fire = null
mode = BOT_IDLE
return
if(prob(1) && target_fire == null)
var/list/messagevoice = list("No fires detected." = 'sound/voice/firebot/nofires.ogg',
"Only you can prevent station fires." = 'sound/voice/firebot/onlyyou.ogg',
"Temperature nominal." = 'sound/voice/firebot/tempnominal.ogg',
"Keep it cool." = 'sound/voice/firebot/keepitcool.ogg')
var/message = pick(messagevoice)
speak(message)
playsound(src, messagevoice[message], 50)
// Couldn't reach the target, reset and try again ignoring the old one
if(frustration > 8)
old_target_fire = target_fire
soft_reset()
// We extinguished our target or it was deleted
if(QDELETED(target_fire) || !is_burning(target_fire) || isdead(target_fire))
target_fire = null
var/scan_range = (stationary_mode ? 1 : DEFAULT_SCAN_RANGE)
if(extinguish_people)
target_fire = scan(/mob/living, old_target_fire, scan_range) // Scan for burning humans first
if(target_fire == null && extinguish_fires)
target_fire = scan(/turf/open, old_target_fire, scan_range) // Scan for burning turfs second
old_target_fire = target_fire
// Target reached ENGAGE WATER CANNON
if(target_fire && (get_dist(src, target_fire) <= (emagged == 1 ? 1 : 2))) // Make the bot spray water from afar when not emagged
if((speech_cooldown + SPEECH_INTERVAL) < world.time)
if(ishuman(target_fire))
speak("Stop, drop and roll!")
playsound(src, "sound/voice/firebot/stopdropnroll.ogg", 50, 0)
else
speak("Extinguishing!")
playsound(src, "sound/voice/firebot/extinguishing.ogg", 50, 0)
speech_cooldown = world.time
flick("firebot1_use", src)
spray_water(target_fire, src)
soft_reset()
// Target ran away
else if(target_fire && path.len && (get_dist(target_fire,path[path.len]) > 2))
path = list()
mode = BOT_IDLE
last_found = world.time
else if(target_fire && stationary_mode)
soft_reset()
return
if(target_fire && (get_dist(src, target_fire) > 2))
path = get_path_to(src, get_turf(target_fire), /turf/proc/Distance_cardinal, 0, 30, 1, id=access_card)
mode = BOT_MOVING
if(!path.len)
soft_reset()
if(path.len > 0 && target_fire)
if(!bot_move(path[path.len]))
old_target_fire = target_fire
soft_reset()
return
// We got a target but it's too far away from us
if(path.len > 8 && target_fire)
frustration++
if(auto_patrol && !target_fire && !stationary_mode)
if(mode == BOT_IDLE || mode == BOT_START_PATROL)
start_patrol()
if(mode == BOT_PATROL)
bot_patrol()
//Look for burning people or turfs around the bot
/mob/living/simple_animal/bot/firebot/process_scan(atom/scan_target)
var/result
if(scan_target == src)
return result
if(is_burning(scan_target))
if((detected_cooldown + DETECTED_VOICE_INTERVAL) < world.time)
speak("Fire detected!")
playsound(src, "sound/voice/firebot/detected.ogg", 50, 0)
detected_cooldown = world.time
result = scan_target
return result
/mob/living/simple_animal/bot/firebot/temperature_expose(datum/gas_mixture/air, temperature, volume)
if((temperature > T0C + 200 || temperature < BODYTEMP_COLD_DAMAGE_LIMIT) && foam_cooldown + FOAM_INTERVAL < world.time)
new /obj/effect/particle_effect/foam/firefighting(loc)
foam_cooldown = world.time
..()
/mob/living/simple_animal/bot/firebot/proc/spray_water(atom/target, mob/user)
if(stationary_mode)
flick("firebots_use", user)
else
flick("firebot1_use", user)
internal_ext.afterattack(target, user, null)
/mob/living/simple_animal/bot/firebot/update_icon()
if(!on)
icon_state = "firebot0"
return
if(IsStun())
icon_state = "firebots1"
else if(stationary_mode) //Bot has yellow light to indicate stationary mode.
icon_state = "firebots1"
else
icon_state = "firebot1"
/mob/living/simple_animal/bot/firebot/explode()
on = FALSE
visible_message("<span class='boldannounce'>[src] blows apart!</span>")
var/atom/Tsec = drop_location()
new /obj/item/assembly/prox_sensor(Tsec)
new /obj/item/clothing/head/hardhat/red(Tsec)
var/turf/T = get_turf(Tsec)
if(isopenturf(T))
var/turf/open/theturf = T
theturf.MakeSlippery(TURF_WET_WATER, min_wet_time = 10 SECONDS, wet_time_to_add = 5 SECONDS)
if(prob(50))
drop_part(robot_arm, Tsec)
do_sparks(3, TRUE, src)
..()
/obj/machinery/bot_core/firebot
req_one_access = list(ACCESS_CONSTRUCTION, ACCESS_ROBOTICS)
#undef SPEECH_INTERVAL
#undef DETECTED_VOICE_INTERVAL
#undef FOAM_INTERVAL
@@ -343,7 +343,7 @@
/mob/living/simple_animal/bot/medbot/proc/assess_patient(mob/living/carbon/C)
//Time to see if they need medical help!
if(C.stat == DEAD || (C.has_trait(TRAIT_FAKEDEATH)))
if(C.stat == DEAD || (HAS_TRAIT(C, TRAIT_FAKEDEATH)))
return FALSE //welp too late for them!
if(!(loc == C.loc) && !(isturf(C.loc) && isturf(loc)))
@@ -421,7 +421,7 @@
soft_reset()
return
if(C.stat == DEAD || (C.has_trait(TRAIT_FAKEDEATH)))
if(C.stat == DEAD || (HAS_TRAIT(C, TRAIT_FAKEDEATH)))
var/list/messagevoice = list("No! Stay with me!" = 'sound/voice/medbot/no.ogg',"Live, damnit! LIVE!" = 'sound/voice/medbot/live.ogg',"I...I've never lost a patient before. Not today, I mean." = 'sound/voice/medbot/lost.ogg')
var/message = pick(messagevoice)
speak(message)
@@ -343,7 +343,7 @@
/mob/living/simple_animal/hostile/construct/harvester/AttackingTarget()
if(iscarbon(target))
var/mob/living/carbon/C = target
if(C.has_trait(TRAIT_NODISMEMBER))
if(HAS_TRAIT(C, TRAIT_NODISMEMBER))
return ..() //ATTACK!
var/list/parts = list()
var/undismembermerable_limbs = 0
@@ -284,12 +284,8 @@
if(health < maxHealth)
adjustBruteLoss(-8) //Fast life regen
for(var/obj/item/reagent_containers/food/snacks/donut/D in range(1, src)) //Frosts nearby donuts!
if(D.icon_state != "donut2")
D.name = "frosted donut"
D.icon_state = "donut2"
D.reagents.add_reagent("sprinkles", 2)
D.bonus_reagents = list("sprinkles" = 2, "sugar" = 1)
D.filling_color = "#FF69B4"
if(!D.is_frosted)
D.frost_donut()
/mob/living/simple_animal/pet/cat/cak/attack_hand(mob/living/L)
..()
@@ -28,13 +28,29 @@
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab/corgi = 3, /obj/item/stack/sheet/animalhide/corgi = 1)
childtype = list(/mob/living/simple_animal/pet/dog/corgi/puppy = 95, /mob/living/simple_animal/pet/dog/corgi/puppy/void = 5)
animal_species = /mob/living/simple_animal/pet/dog
var/shaved = 0
var/obj/item/inventory_head
var/obj/item/inventory_back
var/nofur = 0 //Corgis that have risen past the material plane of existence.
gold_core_spawnable = FRIENDLY_SPAWN
can_be_held = TRUE
collar_type = "corgi"
var/obj/item/inventory_head
var/obj/item/inventory_back
var/shaved = FALSE
var/nofur = FALSE //Corgis that have risen past the material plane of existence.
/mob/living/simple_animal/pet/dog/corgi/Destroy()
QDEL_NULL(inventory_head)
QDEL_NULL(inventory_back)
return ..()
/mob/living/simple_animal/pet/dog/corgi/handle_atom_del(atom/A)
if(A == inventory_head)
inventory_head = null
update_corgi_fluff()
regenerate_icons()
if(A == inventory_back)
inventory_back = null
update_corgi_fluff()
regenerate_icons()
return ..()
/mob/living/simple_animal/pet/dog/pug
name = "\improper pug"
@@ -80,23 +96,17 @@
regenerate_icons()
/mob/living/simple_animal/pet/dog/corgi/show_inv(mob/user)
user.set_machine(src)
if(user.stat)
if(!user.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
return
user.set_machine(src)
var/dat = "<div align='center'><b>Inventory of [name]</b></div><p>"
if(inventory_head)
dat += "<br><b>Head:</b> [inventory_head] (<a href='?src=[REF(src)];remove_inv=head'>Remove</a>)"
else
dat += "<br><b>Head:</b> <a href='?src=[REF(src)];add_inv=head'>Nothing</a>"
if(inventory_back)
dat += "<br><b>Back:</b> [inventory_back] (<a href='?src=[REF(src)];remove_inv=back'>Remove</a>)"
else
dat += "<br><b>Back:</b> <a href='?src=[REF(src)];add_inv=back'>Nothing</a>"
dat += "<br><B>Head:</B> <A href='?src=[REF(src)];[inventory_head ? "remove_inv=head'>[inventory_head]" : "add_inv=head'>Nothing"]</A>"
dat += "<br><B>Back:</B> <A href='?src=[REF(src)];[inventory_back ? "remove_inv=back'>[inventory_back]" : "add_inv=back'>Nothing"]</A>"
dat += "<br><B>Collar:</B> <A href='?src=[REF(src)];[pcollar ? "remove_inv=collar'>[pcollar]" : "add_inv=collar'>Nothing"]</A>"
user << browse(dat, text("window=mob[];size=325x500", real_name))
onclose(user, "mob[real_name]")
return
user << browse(dat, "window=mob[REF(src)];size=325x500")
onclose(user, "mob[REF(src)]")
/mob/living/simple_animal/pet/dog/corgi/getarmor(def_zone, type)
var/armorval = 0
@@ -128,7 +138,7 @@
if(do_after(user, 50, target = src))
user.visible_message("[user] shaves [src]'s hair using \the [O].")
playsound(loc, 'sound/items/welder2.ogg', 20, 1)
shaved = 1
shaved = TRUE
icon_living = "[initial(icon_living)]_shaved"
icon_dead = "[initial(icon_living)]_shaved_dead"
if(stat == CONSCIOUS)
@@ -147,18 +157,18 @@
L.visible_message("<span class='warning'>[L] scoops up [src]!</span>")
/mob/living/simple_animal/pet/dog/corgi/Topic(href, href_list)
if(usr.stat)
if(!(iscarbon(usr) || iscyborg(usr)) || !usr.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
usr << browse(null, "window=mob[REF(src)]")
usr.unset_machine()
return
//Removing from inventory
if(href_list["remove_inv"])
if(!Adjacent(usr) || !(ishuman(usr) || ismonkey(usr) || iscyborg(usr) || isalienadult(usr)))
return
var/remove_from = href_list["remove_inv"]
switch(remove_from)
if(BODY_ZONE_HEAD)
if(inventory_head)
inventory_head.forceMove(drop_location())
usr.put_in_hands(inventory_head)
inventory_head = null
update_corgi_fluff()
regenerate_icons()
@@ -167,24 +177,32 @@
return
if("back")
if(inventory_back)
inventory_back.forceMove(drop_location())
usr.put_in_hands(inventory_back)
inventory_back = null
update_corgi_fluff()
regenerate_icons()
else
to_chat(usr, "<span class='danger'>There is nothing to remove from its [remove_from].</span>")
return
if("collar")
if(pcollar)
usr.put_in_hands(pcollar)
pcollar = null
update_corgi_fluff()
regenerate_icons()
show_inv(usr)
//Adding things to inventory
else if(href_list["add_inv"])
if(!Adjacent(usr) || !(ishuman(usr) || ismonkey(usr) || iscyborg(usr) || isalienadult(usr)))
return
var/add_to = href_list["add_inv"]
switch(add_to)
if("collar")
add_collar(usr.get_active_held_item(), usr)
update_corgi_fluff()
if(BODY_ZONE_HEAD)
place_on_head(usr.get_active_held_item(),usr)
@@ -229,7 +247,7 @@
show_inv(usr)
else
..()
return ..()
//Corgis are supposed to be simpler, so only a select few objects can actually be put
//to be compatible with them. The objects are below.
@@ -560,7 +578,7 @@
icon_state = "void_puppy"
icon_living = "void_puppy"
icon_dead = "void_puppy_dead"
nofur = 1
nofur = TRUE
unsuitable_atmos_damage = 0
minbodytemp = TCMB
maxbodytemp = T0C + 40
@@ -37,6 +37,7 @@
gender = NEUTER
mob_biotypes = list(MOB_ROBOTIC)
speak_emote = list("chirps")
speech_span = SPAN_ROBOT
bubble_icon = "machine"
initial_language_holder = /datum/language_holder/drone
mob_size = MOB_SIZE_SMALL
@@ -92,7 +93,7 @@
var/obj/item/I = new default_hatmask(src)
equip_to_slot_or_del(I, SLOT_HEAD)
access_card.item_flags |= NODROP
ADD_TRAIT(access_card, TRAIT_NODROP, ABSTRACT_ITEM_TRAIT)
alert_drones(DRONE_NET_CONNECT)
@@ -1,13 +1,3 @@
/////////////
//DRONE SAY//
/////////////
//Drone speach
/mob/living/simple_animal/drone/get_spans()
return ..() | SPAN_ROBOT
//Base proc for anything to call
/proc/_alert_drones(msg, dead_can_hear = 0, atom/source, mob/living/faction_checked_mob, exact_faction_match)
if (dead_can_hear && source)
@@ -31,7 +21,7 @@
/mob/living/simple_animal/drone/proc/drone_chat(msg)
alert_drones("<i>Drone Chat: <span class='name'>[name]</span> <span class='message'>[say_quote(msg, get_spans())]</span></i>", TRUE)
alert_drones("<i>Drone Chat: <span class='name'>[name]</span> <span class='message'>[say_quote(msg)]</span></i>", TRUE)
/mob/living/simple_animal/drone/binarycheck()
return TRUE
@@ -0,0 +1,20 @@
/mob/living/simple_animal/pet/redpanda
name = "Red panda"
desc = "Wah't a dork."
icon = 'icons/mob/pets.dmi'
icon_state = "red_panda"
icon_living = "red_panda"
icon_dead = "dead_panda"
speak = list("Churip","Chuuriip","Cheep-cheep","Chiteurp","squueeaacipt")
speak_emote = list("chirps", "huff-quacks")
emote_hear = list("squeak-chrips.", "huff-squacks.")
emote_see = list("shakes its head.", "rolls about.")
speak_chance = 1
turns_per_move = 5
see_in_dark = 6
butcher_results = list(/obj/item/reagent_containers/food/snacks/meat/slab = 3)
response_help = "pets"
response_disarm = "gently pushes aside"
response_harm = "kicks"
gold_core_spawnable = FRIENDLY_SPAWN
do_footstep = TRUE
@@ -2,21 +2,30 @@
icon = 'icons/mob/pets.dmi'
mob_size = MOB_SIZE_SMALL
mob_biotypes = list(MOB_ORGANIC, MOB_BEAST)
var/obj/item/clothing/neck/petcollar/pcollar
var/collar_type
var/unique_pet = FALSE
blood_volume = BLOOD_VOLUME_NORMAL
var/unique_pet = FALSE // if the mob can be renamed
var/obj/item/clothing/neck/petcollar/pcollar
var/collar_type //if the mob has collar sprites, define them.
/mob/living/simple_animal/pet/handle_atom_del(atom/A)
if(A == pcollar)
pcollar = null
return ..()
/mob/living/simple_animal/pet/proc/add_collar(obj/item/clothing/neck/petcollar/P, mob/user)
if(QDELETED(P) || pcollar)
return
if(!user.transferItemToLoc(P, src))
return
pcollar = P
regenerate_icons()
to_chat(user, "<span class='notice'>You put the [P] around [src]'s neck.</span>")
if(P.tagname && !unique_pet)
fully_replace_character_name(null, "\proper [P.tagname]")
/mob/living/simple_animal/pet/attackby(obj/item/O, mob/user, params)
if(istype(O, /obj/item/clothing/neck/petcollar) && !pcollar && collar_type)
var/obj/item/clothing/neck/petcollar/P = O
pcollar = P.type
regenerate_icons()
to_chat(user, "<span class='notice'>You put the [P] around [src]'s neck.</span>")
if(P.tagname && !unique_pet)
real_name = "\proper [P.tagname]"
name = real_name
qdel(P)
add_collar(O, user)
return
if(istype(O, /obj/item/newspaper))
@@ -35,12 +44,16 @@
pcollar = new(src)
regenerate_icons()
/mob/living/simple_animal/pet/Destroy()
QDEL_NULL(pcollar)
return ..()
/mob/living/simple_animal/pet/revive(full_heal = 0, admin_revive = 0)
if(..())
. = ..()
if(.)
if(collar_type)
collar_type = "[initial(collar_type)]"
regenerate_icons()
. = TRUE
/mob/living/simple_animal/pet/death(gibbed)
..(gibbed)
@@ -50,7 +63,8 @@
/mob/living/simple_animal/pet/gib()
if(pcollar)
new pcollar(drop_location())
pcollar.forceMove(drop_location())
pcollar = null
..()
/mob/living/simple_animal/pet/regenerate_icons()
@@ -596,6 +596,9 @@ GLOBAL_LIST_EMPTY(parasites) //all currently existing/living guardians
/obj/item/guardiancreator/tech/choose/traitor
possible_guardians = list("Assassin", "Chaos", "Charger", "Explosive", "Lightning", "Protector", "Ranged", "Standard", "Support")
/obj/item/guardiancreator/tech/choose/traitor/check_uplink_validity()
return !used
/obj/item/guardiancreator/tech/choose
random = FALSE
@@ -43,7 +43,7 @@
// Changeling egg can survive in aliens!
var/mob/living/carbon/C = target
if(C.stat == DEAD)
if(C.has_trait(TRAIT_XENO_HOST))
if(HAS_TRAIT(C, TRAIT_XENO_HOST))
to_chat(src, "<span class='userdanger'>A foreign presence repels us from this body. Perhaps we should try to infest another?</span>")
return
Infect(target)
@@ -348,7 +348,7 @@
if(vore_active)
if(isliving(target))
var/mob/living/L = target
if(L.Adjacent(src) && L.devourable) // aggressive check to ensure vore attacks can be made
if(!client && L.Adjacent(src) && L.devourable) // aggressive check to ensure vore attacks can be made
if(prob(voracious_chance))
vore_attack(src,L,src)
else
@@ -558,7 +558,7 @@ Difficulty: Very Hard
H.regenerate_limbs()
H.regenerate_organs()
H.revive(1,0)
H.add_trait(TRAIT_NOCLONE, MAGIC_TRAIT) //Free revives, but significantly limits your options for reviving except via the crystal
ADD_TRAIT(H, TRAIT_NOCLONE, MAGIC_TRAIT) //Free revives, but significantly limits your options for reviving except via the crystal
H.grab_ghost(force = TRUE)
/obj/machinery/anomalous_crystal/helpers //Lets ghost spawn as helpful creatures that can only heal people slightly. Incredibly fragile and they can't converse with humans
@@ -721,7 +721,7 @@ Difficulty: Very Hard
if(isliving(A) && holder_animal)
var/mob/living/L = A
L.notransform = 1
L.add_trait(TRAIT_MUTE, STASIS_MUTE)
ADD_TRAIT(L, TRAIT_MUTE, STASIS_MUTE)
L.status_flags |= GODMODE
L.mind.transfer_to(holder_animal)
var/obj/effect/proc_holder/spell/targeted/exit_possession/P = new /obj/effect/proc_holder/spell/targeted/exit_possession
@@ -731,7 +731,7 @@ Difficulty: Very Hard
/obj/structure/closet/stasis/dump_contents(var/kill = 1)
STOP_PROCESSING(SSobj, src)
for(var/mob/living/L in src)
L.remove_trait(TRAIT_MUTE, STASIS_MUTE)
REMOVE_TRAIT(L, TRAIT_MUTE, STASIS_MUTE)
L.status_flags &= ~GODMODE
L.notransform = 0
if(holder_animal)
@@ -30,7 +30,7 @@ Cross Blasts and the AoE burst gain additional range as Hierophant loses health,
When Hierophant dies, it stops trying to murder you and shrinks into a small form, which, while much weaker, is still quite effective.
- The smaller club can place a teleport beacon, allowing the user to teleport themself and their allies to the beacon.
Difficulty: Hard
Difficulty: Normal
*/
@@ -47,11 +47,11 @@ Difficulty: Hard
icon = 'icons/mob/lavaland/hierophant_new.dmi'
faction = list("boss") //asteroid mobs? get that shit out of my beautiful square house
speak_emote = list("preaches")
armour_penetration = 50
armour_penetration = 75
melee_damage_lower = 15
melee_damage_upper = 15
melee_damage_upper = 20
speed = 1
move_to_delay = 10
move_to_delay = 11
ranged = 1
ranged_cooldown_time = 40
aggro_vision_range = 21 //so it can see to one side of the arena to the other
@@ -41,6 +41,9 @@
QDEL_NULL(internal)
. = ..()
/mob/living/simple_animal/hostile/megafauna/prevent_content_explosion()
return TRUE
/mob/living/simple_animal/hostile/megafauna/death(gibbed)
if(health > 0)
return
@@ -130,7 +130,7 @@
/mob/living/simple_animal/hostile/syndicate/melee/bullet_act(obj/item/projectile/Proj)
if(!Proj)
return
if(prob(50))
if(prob(25))
return ..()
else
visible_message("<span class='danger'>[src] blocks [Proj] with its shield!</span>")
@@ -1,71 +1,71 @@
/mob/living/simple_animal/hostile/tree
name = "pine tree"
desc = "A pissed off tree-like alien. It seems annoyed with the festivities..."
icon = 'icons/obj/flora/pinetrees.dmi'
icon_state = "pine_1"
icon_living = "pine_1"
icon_dead = "pine_1"
icon_gib = "pine_1"
gender = NEUTER
speak_chance = 0
turns_per_move = 5
response_help = "brushes"
response_disarm = "pushes"
response_harm = "hits"
speed = 1
maxHealth = 250
health = 250
mob_size = MOB_SIZE_LARGE
pixel_x = -16
harm_intent_damage = 5
melee_damage_lower = 8
melee_damage_upper = 12
attacktext = "bites"
attack_sound = 'sound/weapons/bite.ogg'
speak_emote = list("pines")
emote_taunt = list("growls")
taunt_chance = 20
atmos_requirements = list("min_oxy" = 2, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
unsuitable_atmos_damage = 5
minbodytemp = 0
maxbodytemp = 1200
faction = list("hostile")
deathmessage = "is hacked into pieces!"
loot = list(/obj/item/stack/sheet/mineral/wood)
gold_core_spawnable = HOSTILE_SPAWN
del_on_death = 1
/mob/living/simple_animal/hostile/tree/Life()
..()
if(isopenturf(loc))
var/turf/open/T = src.loc
if(T.air && T.air.gases[/datum/gas/carbon_dioxide])
var/co2 = T.air.gases[/datum/gas/carbon_dioxide][MOLES]
if(co2 > 0)
if(prob(25))
var/amt = min(co2, 9)
T.air.gases[/datum/gas/carbon_dioxide][MOLES] -= amt
T.atmos_spawn_air("o2=[amt]")
/mob/living/simple_animal/hostile/tree/AttackingTarget()
. = ..()
if(iscarbon(target))
var/mob/living/carbon/C = target
if(prob(15))
C.Knockdown(60)
C.visible_message("<span class='danger'>\The [src] knocks down \the [C]!</span>", \
"<span class='userdanger'>\The [src] knocks you down!</span>")
/mob/living/simple_animal/hostile/tree/festivus
name = "festivus pole"
desc = "Serenity now... SERENITY NOW!"
icon_state = "festivus_pole"
icon_living = "festivus_pole"
icon_dead = "festivus_pole"
icon_gib = "festivus_pole"
loot = list(/obj/item/stack/rods)
speak_emote = list("polls")
/mob/living/simple_animal/hostile/tree
name = "pine tree"
desc = "A pissed off tree-like alien. It seems annoyed with the festivities..."
icon = 'icons/obj/flora/pinetrees.dmi'
icon_state = "pine_1"
icon_living = "pine_1"
icon_dead = "pine_1"
icon_gib = "pine_1"
gender = NEUTER
speak_chance = 0
turns_per_move = 5
response_help = "brushes"
response_disarm = "pushes"
response_harm = "hits"
speed = 1
maxHealth = 250
health = 250
mob_size = MOB_SIZE_LARGE
pixel_x = -16
harm_intent_damage = 5
melee_damage_lower = 8
melee_damage_upper = 12
attacktext = "bites"
attack_sound = 'sound/weapons/bite.ogg'
speak_emote = list("pines")
emote_taunt = list("growls")
taunt_chance = 20
atmos_requirements = list("min_oxy" = 2, "max_oxy" = 0, "min_tox" = 0, "max_tox" = 0, "min_co2" = 0, "max_co2" = 0, "min_n2" = 0, "max_n2" = 0)
unsuitable_atmos_damage = 5
minbodytemp = 0
maxbodytemp = 1200
faction = list("hostile")
deathmessage = "is hacked into pieces!"
loot = list(/obj/item/stack/sheet/mineral/wood)
gold_core_spawnable = HOSTILE_SPAWN
del_on_death = 1
/mob/living/simple_animal/hostile/tree/Life()
..()
if(isopenturf(loc))
var/turf/open/T = src.loc
if(T.air && T.air.gases[/datum/gas/carbon_dioxide])
var/co2 = T.air.gases[/datum/gas/carbon_dioxide]
if(co2 > 0)
if(prob(25))
var/amt = min(co2, 9)
T.air.gases[/datum/gas/carbon_dioxide] -= amt
T.atmos_spawn_air("o2=[amt]")
/mob/living/simple_animal/hostile/tree/AttackingTarget()
. = ..()
if(iscarbon(target))
var/mob/living/carbon/C = target
if(prob(15))
C.Knockdown(60)
C.visible_message("<span class='danger'>\The [src] knocks down \the [C]!</span>", \
"<span class='userdanger'>\The [src] knocks you down!</span>")
/mob/living/simple_animal/hostile/tree/festivus
name = "festivus pole"
desc = "Serenity now... SERENITY NOW!"
icon_state = "festivus_pole"
icon_living = "festivus_pole"
icon_dead = "festivus_pole"
icon_gib = "festivus_pole"
loot = list(/obj/item/stack/rods)
speak_emote = list("polls")
+65 -74
View File
@@ -181,94 +181,85 @@
*/
/mob/living/simple_animal/parrot/show_inv(mob/user)
user.set_machine(src)
var/dat = "<div align='center'><b>Inventory of [name]</b></div><p>"
if(ears)
dat += "<br><b>Headset:</b> [ears] (<a href='?src=[REF(src)];remove_inv=ears'>Remove</a>)"
else
dat += "<br><b>Headset:</b> <a href='?src=[REF(src)];add_inv=ears'>Nothing</a>"
user << browse(dat, "window=mob[real_name];size=325x500")
onclose(user, "mob[real_name]")
var/dat = "<div align='center'><b>Inventory of [name]</b></div><p>"
dat += "<br><B>Headset:</B> <A href='?src=[REF(src)];[ears ? "remove_inv=ears'>[ears]" : "add_inv=ears'>Nothing"]</A>"
user << browse(dat, "window=mob[REF(src)];size=325x500")
onclose(user, "window=mob[REF(src)]")
/mob/living/simple_animal/parrot/Topic(href, href_list)
//Can the usr physically do this?
if(usr.incapacitated() || !usr.Adjacent(loc))
if(!(iscarbon(usr) || iscyborg(usr)) || !usr.canUseTopic(src, BE_CLOSE, FALSE, NO_TK))
usr << browse(null, "window=mob[REF(src)]")
usr.unset_machine()
return
//Is the usr's mob type able to do this? (lolaliens)
if(ishuman(usr) || ismonkey(usr) || iscyborg(usr) || isalienadult(usr))
//Removing from inventory
if(href_list["remove_inv"])
var/remove_from = href_list["remove_inv"]
switch(remove_from)
if("ears")
if(!ears)
to_chat(usr, "<span class='warning'>There is nothing to remove from its [remove_from]!</span>")
return
if(!stat)
say("[available_channels.len ? "[pick(available_channels)] " : null]BAWWWWWK LEAVE THE HEADSET BAWKKKKK!")
ears.forceMove(drop_location())
ears = null
for(var/possible_phrase in speak)
if(copytext(possible_phrase,1,3) in GLOB.department_radio_keys)
possible_phrase = copytext(possible_phrase,3)
//Removing from inventory
if(href_list["remove_inv"])
var/remove_from = href_list["remove_inv"]
switch(remove_from)
if("ears")
if(ears)
if(!stat)
if(available_channels.len)
src.say("[pick(available_channels)] BAWWWWWK LEAVE THE HEADSET BAWKKKKK!")
else
src.say("BAWWWWWK LEAVE THE HEADSET BAWKKKKK!")
ears.forceMove(src.loc)
ears = null
for(var/possible_phrase in speak)
if(copytext(possible_phrase,1,3) in GLOB.department_radio_keys)
possible_phrase = copytext(possible_phrase,3)
else
to_chat(usr, "<span class='warning'>There is nothing to remove from its [remove_from]!</span>")
//Adding things to inventory
else if(href_list["add_inv"])
var/add_to = href_list["add_inv"]
if(!usr.get_active_held_item())
to_chat(usr, "<span class='warning'>You have nothing in your hand to put on its [add_to]!</span>")
return
switch(add_to)
if("ears")
if(ears)
to_chat(usr, "<span class='warning'>It's already wearing something!</span>")
return
else
var/obj/item/item_to_add = usr.get_active_held_item()
if(!item_to_add)
return
//Adding things to inventory
else if(href_list["add_inv"])
var/add_to = href_list["add_inv"]
if(!usr.get_active_held_item())
to_chat(usr, "<span class='warning'>You have nothing in your hand to put on its [add_to]!</span>")
return
switch(add_to)
if("ears")
if(ears)
to_chat(usr, "<span class='warning'>It's already wearing something!</span>")
if( !istype(item_to_add, /obj/item/radio/headset) )
to_chat(usr, "<span class='warning'>This object won't fit!</span>")
return
else
var/obj/item/item_to_add = usr.get_active_held_item()
if(!item_to_add)
return
if( !istype(item_to_add, /obj/item/radio/headset) )
to_chat(usr, "<span class='warning'>This object won't fit!</span>")
return
var/obj/item/radio/headset/headset_to_add = item_to_add
var/obj/item/radio/headset/headset_to_add = item_to_add
if(!usr.transferItemToLoc(headset_to_add, src))
return
ears = headset_to_add
to_chat(usr, "<span class='notice'>You fit the headset onto [src].</span>")
if(!usr.transferItemToLoc(headset_to_add, src))
return
src.ears = headset_to_add
to_chat(usr, "<span class='notice'>You fit the headset onto [src].</span>")
clearlist(available_channels)
for(var/ch in headset_to_add.channels)
switch(ch)
if("Engineering")
available_channels.Add(":e")
if("Command")
available_channels.Add(":c")
if("Security")
available_channels.Add(":s")
if("Science")
available_channels.Add(":n")
if("Medical")
available_channels.Add(":m")
if("Supply")
available_channels.Add(":u")
if("Service")
available_channels.Add(":v")
clearlist(available_channels)
for(var/ch in headset_to_add.channels)
switch(ch)
if("Engineering")
available_channels.Add(":e")
if("Command")
available_channels.Add(":c")
if("Security")
available_channels.Add(":s")
if("Science")
available_channels.Add(":n")
if("Medical")
available_channels.Add(":m")
if("Supply")
available_channels.Add(":u")
if("Service")
available_channels.Add(":v")
if(headset_to_add.translate_binary)
available_channels.Add(":b")
else
..()
if(headset_to_add.translate_binary)
available_channels.Add(":b")
else
return ..()
/*
File diff suppressed because it is too large Load Diff
@@ -61,7 +61,7 @@
break
if(Target in view(1,src))
if(issilicon(Target))
if(!CanFeedon(Target)) //If they're not able to be fed upon, ignore them.
if(!Atkcool)
Atkcool = 1
spawn(45)
@@ -132,7 +132,7 @@
if(stat != DEAD)
var/bz_percentage =0
if(environment.gases[/datum/gas/bz])
bz_percentage = environment.gases[/datum/gas/bz][MOLES] / environment.total_moles()
bz_percentage = environment.gases[/datum/gas/bz] / environment.total_moles()
var/stasis = (bz_percentage >= 0.05 && bodytemperature < (T0C + 100)) || force_stasis
if(stat == CONSCIOUS && stasis)
@@ -600,7 +600,8 @@
phrases += "[M]... friend..."
if (nutrition < get_hunger_nutrition())
phrases += "[M]... feed me..."
say (pick(phrases))
if(!stat)
say (pick(phrases))
/mob/living/simple_animal/slime/proc/get_max_nutrition() // Can't go above it
if (is_adult)
@@ -48,34 +48,58 @@
var/mob/living/simple_animal/slime/S = owner
S.Feed()
/mob/living/simple_animal/slime/proc/CanFeedon(mob/living/M)
/mob/living/simple_animal/slime/proc/CanFeedon(mob/living/M, silent = FALSE)
if(!Adjacent(M))
return 0
return FALSE
if(buckled)
Feedstop()
return 0
return FALSE
if(issilicon(M))
return FALSE
if(isanimal(M))
var/mob/living/simple_animal/S = M
if(S.damage_coeff[TOX] <= 0 && S.damage_coeff[CLONE] <= 0) //The creature wouldn't take any damage, it must be too weird even for us.
if(silent)
return FALSE
to_chat(src, "<span class='warning'>[pick("This subject is incompatible", \
"This subject does not have life energy", "This subject is empty", \
"I am not satisified", "I can not feed from this subject", \
"I do not feel nourished", "This subject is not food")]!</span>")
return FALSE
if(isslime(M))
if(silent)
return FALSE
to_chat(src, "<span class='warning'><i>I can't latch onto another slime...</i></span>")
return 0
return FALSE
if(docile)
if(silent)
return FALSE
to_chat(src, "<span class='notice'><i>I'm not hungry anymore...</i></span>")
return 0
return FALSE
if(stat)
if(silent)
return FALSE
to_chat(src, "<span class='warning'><i>I must be conscious to do this...</i></span>")
return 0
return FALSE
if(M.stat == DEAD)
if(silent)
return FALSE
to_chat(src, "<span class='warning'><i>This subject does not have a strong enough life energy...</i></span>")
return 0
return FALSE
if(locate(/mob/living/simple_animal/slime) in M.buckled_mobs)
if(silent)
return FALSE
to_chat(src, "<span class='warning'><i>Another slime is already feeding on this subject...</i></span>")
return 0
return 1
return FALSE
return TRUE
/mob/living/simple_animal/slime/proc/Feedon(mob/living/M)
M.unbuckle_all_mobs(force=1) //Slimes rip other mobs (eg: shoulder parrots) off (Slimes Vs Slimes is already handled in CanFeedon())
@@ -61,6 +61,8 @@
var/mood = "" // To show its face
var/mutator_used = FALSE //So you can't shove a dozen mutators into a single slime
var/force_stasis = FALSE
do_footstep = TRUE
var/static/regex/slime_name_regex = new("\\w+ (baby|adult) slime \\(\\d+\\)")
///////////TIME FOR SUBSPECIES

Some files were not shown because too many files have changed in this diff Show More