Merge branch 'master' of https://github.com/Citadel-Station-13/Citadel-Station-13 into Ghommie-cit611
This commit is contained in:
@@ -11,17 +11,6 @@
|
||||
invisibility = INVISIBILITY_ABSTRACT // No one can see us
|
||||
sight = SEE_SELF
|
||||
move_on_shuttle = FALSE
|
||||
var/call_life = FALSE //TRUE if Life() should be called on this camera every tick of the mobs subystem, as if it were a living mob
|
||||
|
||||
/mob/camera/Initialize()
|
||||
. = ..()
|
||||
if(call_life)
|
||||
GLOB.living_cameras += src
|
||||
|
||||
/mob/camera/Destroy()
|
||||
. = ..()
|
||||
if(call_life)
|
||||
GLOB.living_cameras -= src
|
||||
|
||||
/mob/camera/experience_pressure_difference()
|
||||
return
|
||||
|
||||
@@ -580,7 +580,7 @@
|
||||
qdel(src)
|
||||
|
||||
/mob/dead/new_player/proc/ViewManifest()
|
||||
var/dat = "<html><body>"
|
||||
var/dat = "<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'></head><body>"
|
||||
dat += "<h4>Crew Manifest</h4>"
|
||||
dat += GLOB.data_core.get_manifest(OOC = 1)
|
||||
|
||||
|
||||
@@ -288,7 +288,8 @@
|
||||
var/output = {"
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<meta http-equiv='X-UA-Compatible' content='IE=edge' />
|
||||
<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>
|
||||
<script src="jquery.min.js"></script>
|
||||
<script src="jquery-ui.custom-core-widgit-mouse-sortable-min.js"></script>
|
||||
<style>
|
||||
|
||||
@@ -22,7 +22,11 @@
|
||||
if(!pref_species)
|
||||
var/rando_race = pick(GLOB.roundstart_races)
|
||||
pref_species = new rando_race()
|
||||
features = random_features()
|
||||
features = random_features(pref_species?.id)
|
||||
if(gender == MALE || gender != FEMALE)
|
||||
features["body_model"] = gender
|
||||
else if(gender == PLURAL)
|
||||
features["body_model"] = pick(MALE,FEMALE)
|
||||
age = rand(AGE_MIN,AGE_MAX)
|
||||
|
||||
/datum/preferences/proc/update_preview_icon(equip_job = TRUE)
|
||||
|
||||
@@ -72,7 +72,12 @@
|
||||
//for snowflake/donor specific sprites
|
||||
var/list/ckeys_allowed
|
||||
|
||||
//For soft-restricting markings to species IDs
|
||||
var/list/recommended_species
|
||||
|
||||
/datum/sprite_accessory/underwear
|
||||
icon = 'icons/mob/underwear.dmi'
|
||||
icon = 'icons/mob/clothing/underwear.dmi'
|
||||
var/has_color = FALSE
|
||||
var/has_digitigrade = FALSE
|
||||
var/has_digitigrade = FALSE
|
||||
var/covers_groin = FALSE
|
||||
var/covers_chest = FALSE
|
||||
@@ -38,6 +38,7 @@
|
||||
color_src = MATRIXED
|
||||
gender_specific = 0
|
||||
icon = 'modular_citadel/icons/mob/mam_markings.dmi'
|
||||
recommended_species = list("mammal", "xeno", "slimeperson", "podweak")
|
||||
|
||||
/datum/sprite_accessory/mam_body_markings/none
|
||||
name = "None"
|
||||
|
||||
@@ -132,10 +132,12 @@
|
||||
/datum/sprite_accessory/antenna
|
||||
icon = 'modular_citadel/icons/mob/ipc_antennas.dmi'
|
||||
color_src = MUTCOLORS2
|
||||
recommended_species = list("ipc")
|
||||
|
||||
/datum/sprite_accessory/antenna/none
|
||||
name = "None"
|
||||
icon_state = "None"
|
||||
recommended_species = null
|
||||
|
||||
/datum/sprite_accessory/antenna/antennae
|
||||
name = "Angled Antennae"
|
||||
|
||||
@@ -30,12 +30,14 @@
|
||||
var/taur_mode = NONE //Must be a single specific tauric suit variation bitflag. Don't do FLAG_1|FLAG_2
|
||||
var/alt_taur_mode = NONE //Same as above.
|
||||
color_src = MATRIXED
|
||||
recommended_species = list("human", "lizard", "insect", "mammal", "xeno", "jelly", "slimeperson", "podweak")
|
||||
|
||||
/datum/sprite_accessory/taur/none
|
||||
dimension_x = 32
|
||||
center = FALSE
|
||||
name = "None"
|
||||
icon_state = "None"
|
||||
recommended_species = null
|
||||
|
||||
/datum/sprite_accessory/taur/cow
|
||||
name = "Cow"
|
||||
|
||||
@@ -151,11 +151,12 @@
|
||||
/datum/sprite_accessory/mam_snouts
|
||||
color_src = MATRIXED
|
||||
icon = 'modular_citadel/icons/mob/mam_snouts.dmi'
|
||||
recommended_species = list("mammal", "slimeperson", "insect", "podweak")
|
||||
|
||||
/datum/sprite_accessory/mam_snouts/none
|
||||
name = "None"
|
||||
icon_state = "none"
|
||||
|
||||
recommended_species = null
|
||||
|
||||
/datum/sprite_accessory/mam_snouts/bird
|
||||
name = "Beak"
|
||||
|
||||
@@ -0,0 +1,150 @@
|
||||
//Synth snouts (This is the most important part)
|
||||
/datum/sprite_accessory/mam_snouts/synthliz
|
||||
recommended_species = list("synthliz")
|
||||
icon = 'modular_citadel/icons/mob/synthliz_snouts.dmi'
|
||||
color_src = MUTCOLORS
|
||||
name = "Synthetic Lizard - Snout"
|
||||
icon_state = "synthliz_basic"
|
||||
|
||||
/datum/sprite_accessory/mam_snouts/synthliz/synthliz_under
|
||||
icon = 'modular_citadel/icons/mob/synthliz_snouts.dmi'
|
||||
color_src = MATRIXED
|
||||
name = "Synthetic Lizard - Snout Under"
|
||||
icon_state = "synthliz_under"
|
||||
|
||||
/datum/sprite_accessory/mam_snouts/synthliz/synthliz_tert
|
||||
icon = 'modular_citadel/icons/mob/synthliz_snouts.dmi'
|
||||
color_src = MATRIXED
|
||||
name = "Synthetic Lizard - Snout Tertiary"
|
||||
icon_state = "synthliz_tert"
|
||||
|
||||
/datum/sprite_accessory/mam_snouts/synthliz/synthliz_tertunder
|
||||
icon = 'modular_citadel/icons/mob/synthliz_snouts.dmi'
|
||||
color_src = MATRIXED
|
||||
name = "Synthetic Lizard - Snout Tertiary Under"
|
||||
icon_state = "synthliz_tertunder"
|
||||
|
||||
//Synth body markings
|
||||
/datum/sprite_accessory/mam_body_markings/synthliz
|
||||
recommended_species = list("synthliz")
|
||||
icon = 'modular_citadel/icons/mob/synthliz_body_markings.dmi'
|
||||
name = "Synthetic Lizard - Plates"
|
||||
icon_state = "synthlizscutes"
|
||||
|
||||
/datum/sprite_accessory/mam_body_markings/synthliz/synthliz_pecs
|
||||
icon = 'modular_citadel/icons/mob/synthliz_body_markings.dmi'
|
||||
name = "Synthetic Lizard - Pecs"
|
||||
icon_state = "synthlizpecs"
|
||||
|
||||
/datum/sprite_accessory/mam_body_markings/synthliz/synthliz_pecslight
|
||||
icon = 'modular_citadel/icons/mob/synthliz_body_markings.dmi'
|
||||
name = "Synthetic Lizard - Pecs Light"
|
||||
icon_state = "synthlizpecslight"
|
||||
|
||||
//Synth tails
|
||||
/datum/sprite_accessory/mam_tails/synthliz
|
||||
recommended_species = list("synthliz")
|
||||
icon = 'modular_citadel/icons/mob/synthliz_tails.dmi'
|
||||
color_src = MUTCOLORS
|
||||
name = "Synthetic Lizard"
|
||||
icon_state = "synthliz"
|
||||
|
||||
/datum/sprite_accessory/mam_tails_animated/synthliz
|
||||
recommended_species = list("synthliz")
|
||||
icon = 'modular_citadel/icons/mob/synthliz_tails.dmi'
|
||||
color_src = MUTCOLORS
|
||||
name = "Synthetic Lizard"
|
||||
icon_state = "synthliz"
|
||||
|
||||
//Synth Antennae
|
||||
/datum/sprite_accessory/antenna/synthliz
|
||||
recommended_species = list("synthliz")
|
||||
icon = 'modular_citadel/icons/mob/synthliz_antennas.dmi'
|
||||
color_src = MUTCOLORS
|
||||
name = "Synthetic Lizard - Antennae"
|
||||
icon_state = "synth_antennae"
|
||||
|
||||
/datum/sprite_accessory/antenna/synthliz/synthliz_curled
|
||||
icon = 'modular_citadel/icons/mob/synthliz_antennas.dmi'
|
||||
color_src = MUTCOLORS
|
||||
name = "Synthetic Lizard - Curled"
|
||||
icon_state = "synth_curled"
|
||||
|
||||
/datum/sprite_accessory/antenna/synthliz/synthliz_thick
|
||||
icon = 'modular_citadel/icons/mob/synthliz_antennas.dmi'
|
||||
color_src = MUTCOLORS
|
||||
name = "Synthetic Lizard - Thick"
|
||||
icon_state = "synth_thick"
|
||||
|
||||
/datum/sprite_accessory/antenna/synthliz/synth_thicklight
|
||||
icon = 'modular_citadel/icons/mob/synthliz_antennas.dmi'
|
||||
color_src = MATRIXED
|
||||
name = "Synthetic Lizard - Thick Light"
|
||||
icon_state = "synth_thicklight"
|
||||
|
||||
/datum/sprite_accessory/antenna/synthliz/synth_short
|
||||
icon = 'modular_citadel/icons/mob/synthliz_antennas.dmi'
|
||||
color_src = MUTCOLORS
|
||||
name = "Synthetic Lizard - Short"
|
||||
icon_state = "synth_short"
|
||||
|
||||
/datum/sprite_accessory/antenna/synthliz/synth_sharp
|
||||
icon = 'modular_citadel/icons/mob/synthliz_antennas.dmi'
|
||||
color_src = MUTCOLORS
|
||||
name = "Synthetic Lizard - Sharp"
|
||||
icon_state = "synth_sharp"
|
||||
|
||||
/datum/sprite_accessory/antenna/synthliz/synth_sharplight
|
||||
icon = 'modular_citadel/icons/mob/synthliz_antennas.dmi'
|
||||
color_src = MATRIXED
|
||||
name = "Synthetic Lizard - Sharp Light"
|
||||
icon_state = "synth_sharplight"
|
||||
|
||||
/datum/sprite_accessory/antenna/synthliz/synth_horns
|
||||
icon = 'modular_citadel/icons/mob/synthliz_antennas.dmi'
|
||||
color_src = MUTCOLORS
|
||||
name = "Synthetic Lizard - Horns"
|
||||
icon_state = "synth_horns"
|
||||
|
||||
/datum/sprite_accessory/antenna/synthliz/synth_hornslight
|
||||
icon = 'modular_citadel/icons/mob/synthliz_antennas.dmi'
|
||||
color_src = MATRIXED
|
||||
name = "Synthetic Lizard - Horns Light"
|
||||
icon_state = "synth_hornslight"
|
||||
|
||||
//Synth Taurs (Ported from Virgo)
|
||||
/datum/sprite_accessory/taur/synthliz
|
||||
name = "Virgo - Synthetic Lizard"
|
||||
icon_state = "synthlizard"
|
||||
taur_mode = STYLE_PAW_TAURIC
|
||||
recommended_species = list("synthliz")
|
||||
|
||||
/datum/sprite_accessory/taur/synthliz/inv
|
||||
name = "Virgo - Synthetic Lizard (Inverted)"
|
||||
icon_state = "synthlizardinv"
|
||||
|
||||
/datum/sprite_accessory/taur/synthliz/feline
|
||||
name = "Virgo - Synthetic Feline"
|
||||
icon_state = "synthfeline"
|
||||
|
||||
/datum/sprite_accessory/taur/synthliz/feline/inv
|
||||
name = "Virgo - Synthetic Feline (Inverted)"
|
||||
icon_state = "synthfelineinv"
|
||||
|
||||
/datum/sprite_accessory/taur/synthliz/horse
|
||||
name = "Virgo - Synthetic Horse"
|
||||
icon_state = "synthhorse"
|
||||
taur_mode = STYLE_HOOF_TAURIC
|
||||
alt_taur_mode = STYLE_PAW_TAURIC
|
||||
|
||||
/datum/sprite_accessory/taur/synthliz/horse/inv
|
||||
name = "Virgo - Synthetic Horse (Inverted)"
|
||||
icon_state = "synthhorseinv"
|
||||
|
||||
/datum/sprite_accessory/taur/synthliz/wolf
|
||||
name = "Virgo - Synthetic Wolf"
|
||||
icon_state = "synthwolf"
|
||||
|
||||
/datum/sprite_accessory/taur/synthliz/wolf/inv
|
||||
name = "Virgo - Synthetic Wolf (Inverted)"
|
||||
icon_state = "synthwolfinv"
|
||||
@@ -501,10 +501,12 @@
|
||||
/datum/sprite_accessory/mam_tails
|
||||
color_src = MATRIXED
|
||||
icon = 'modular_citadel/icons/mob/mam_tails.dmi'
|
||||
recommended_species = list("mammal", "slimeperson", "podweak", "felinid", "insect")
|
||||
|
||||
/datum/sprite_accessory/mam_tails/none
|
||||
name = "None"
|
||||
icon_state = "none"
|
||||
recommended_species = null
|
||||
|
||||
/datum/sprite_accessory/mam_tails_animated
|
||||
color_src = MATRIXED
|
||||
|
||||
@@ -2,9 +2,13 @@
|
||||
// Undershirt Definitions //
|
||||
////////////////////////////
|
||||
|
||||
/datum/sprite_accessory/underwear/top
|
||||
covers_chest = TRUE
|
||||
|
||||
/datum/sprite_accessory/underwear/top/nude
|
||||
name = "Nude"
|
||||
icon_state = null
|
||||
covers_chest = FALSE
|
||||
|
||||
// please make sure they're sorted alphabetically and categorized
|
||||
|
||||
|
||||
@@ -2,9 +2,13 @@
|
||||
// Underwear Definitions //
|
||||
///////////////////////////
|
||||
|
||||
/datum/sprite_accessory/underwear/bottom
|
||||
covers_groin = TRUE
|
||||
|
||||
/datum/sprite_accessory/underwear/bottom/nude
|
||||
name = "Nude"
|
||||
icon_state = null
|
||||
covers_groin = FALSE
|
||||
|
||||
/datum/sprite_accessory/underwear/bottom/mankini
|
||||
name = "Mankini"
|
||||
@@ -155,16 +159,19 @@
|
||||
name = "Swimsuit, One Piece - Red"
|
||||
icon_state = "swimming_red"
|
||||
gender = FEMALE
|
||||
covers_chest = TRUE
|
||||
|
||||
/datum/sprite_accessory/underwear/bottom/swimsuit
|
||||
name = "Swimsuit, One Piece - Black"
|
||||
icon_state = "swimming_black"
|
||||
gender = FEMALE
|
||||
covers_chest = TRUE
|
||||
|
||||
/datum/sprite_accessory/underwear/bottom/swimsuit_blue
|
||||
name = "Swimsuit, One Piece - Striped Blue"
|
||||
icon_state = "swimming_blue"
|
||||
gender = FEMALE
|
||||
covers_chest = TRUE
|
||||
|
||||
/datum/sprite_accessory/underwear/bottom/thong
|
||||
name = "Thong"
|
||||
|
||||
@@ -14,6 +14,7 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
|
||||
move_resist = INFINITY
|
||||
see_invisible = SEE_INVISIBLE_OBSERVER
|
||||
see_in_dark = 100
|
||||
lighting_alpha = LIGHTING_PLANE_ALPHA_MOSTLY_INVISIBLE
|
||||
invisibility = INVISIBILITY_OBSERVER
|
||||
hud_type = /datum/hud/ghost
|
||||
movement_type = GROUND | FLYING
|
||||
@@ -132,6 +133,8 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER)
|
||||
. = ..()
|
||||
AddElement(/datum/element/ghost_role_eligibility)
|
||||
grant_all_languages()
|
||||
show_data_huds()
|
||||
data_huds_on = 1
|
||||
|
||||
/mob/dead/observer/get_photo_description(obj/item/camera/camera)
|
||||
if(!invisibility || camera.see_ghosts)
|
||||
@@ -260,19 +263,36 @@ Works together with spawning an observer, noted above.
|
||||
*/
|
||||
|
||||
/mob/proc/ghostize(can_reenter_corpse = TRUE, special = FALSE, penalize = FALSE, voluntary = FALSE)
|
||||
penalize = suiciding || penalize // suicide squad.
|
||||
var/sig_flags = SEND_SIGNAL(src, COMSIG_MOB_GHOSTIZE, can_reenter_corpse, special, penalize)
|
||||
penalize = !(sig_flags & COMPONENT_DO_NOT_PENALIZE_GHOSTING) && (suiciding || penalize) // suicide squad.
|
||||
voluntary_ghosted = voluntary
|
||||
if(!key || key[1] == "@" || (SEND_SIGNAL(src, COMSIG_MOB_GHOSTIZE, can_reenter_corpse, special, penalize) & COMPONENT_BLOCK_GHOSTING))
|
||||
if(!key || key[1] == "@" || (sig_flags & COMPONENT_BLOCK_GHOSTING))
|
||||
return //mob has no key, is an aghost or some component hijacked.
|
||||
stop_sound_channel(CHANNEL_HEARTBEAT) //Stop heartbeat sounds because You Are A Ghost Now
|
||||
var/mob/dead/observer/ghost = new(get_turf(src), src) // Transfer safety to observer spawning proc.
|
||||
SStgui.on_transfer(src, ghost) // Transfer NanoUIs.
|
||||
ghost.can_reenter_corpse = can_reenter_corpse
|
||||
ghost.can_reenter_corpse = can_reenter_corpse || (sig_flags & COMPONENT_FREE_GHOSTING)
|
||||
if (client && client.prefs && client.prefs.auto_ooc)
|
||||
if (!(client.prefs.chat_toggles & CHAT_OOC))
|
||||
client.prefs.chat_toggles ^= CHAT_OOC
|
||||
transfer_ckey(ghost, FALSE)
|
||||
ghost.AddElement(/datum/element/ghost_role_eligibility,penalize) // technically already run earlier, but this adds the penalty
|
||||
if(penalize)
|
||||
var/penalty = CONFIG_GET(number/suicide_reenter_round_timer) MINUTES
|
||||
var/roundstart_quit_limit = CONFIG_GET(number/roundstart_suicide_time_limit) MINUTES
|
||||
if(world.time < roundstart_quit_limit) //add up the time difference to their antag rolling penalty if they quit before half a (ingame) hour even passed.
|
||||
penalty += roundstart_quit_limit - world.time
|
||||
if(penalty)
|
||||
penalty += world.realtime
|
||||
if(SSautotransfer.can_fire && SSautotransfer.maxvotes)
|
||||
var/maximumRoundEnd = SSautotransfer.starttime + SSautotransfer.voteinterval * SSautotransfer.maxvotes
|
||||
if(penalty - SSshuttle.realtimeofstart > maximumRoundEnd + SSshuttle.emergencyCallTime + SSshuttle.emergencyDockTime + SSshuttle.emergencyEscapeTime)
|
||||
penalty = CANT_REENTER_ROUND
|
||||
if(!(ckey in GLOB.client_ghost_timeouts))
|
||||
GLOB.client_ghost_timeouts += ckey
|
||||
GLOB.client_ghost_timeouts[ckey] = 0
|
||||
else if(GLOB.client_ghost_timeouts[ckey] == CANT_REENTER_ROUND)
|
||||
return
|
||||
GLOB.client_ghost_timeouts[ckey] = max(GLOB.client_ghost_timeouts[ckey],penalty)
|
||||
// needs to be done AFTER the ckey transfer, too
|
||||
return ghost
|
||||
|
||||
@@ -289,16 +309,22 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
var/roundstart_quit_limit = CONFIG_GET(number/roundstart_suicide_time_limit) MINUTES
|
||||
if(world.time < roundstart_quit_limit)
|
||||
penalty += roundstart_quit_limit - world.time
|
||||
var/maximumRoundEnd = SSautotransfer.starttime + SSautotransfer.voteinterval * SSautotransfer.maxvotes
|
||||
if(penalty - SSshuttle.realtimeofstart > maximumRoundEnd + SSshuttle.emergencyCallTime + SSshuttle.emergencyDockTime + SSshuttle.emergencyEscapeTime)
|
||||
penalty = CANT_REENTER_ROUND
|
||||
if(SSautotransfer.can_fire && SSautotransfer.maxvotes)
|
||||
var/maximumRoundEnd = SSautotransfer.starttime + SSautotransfer.voteinterval * SSautotransfer.maxvotes
|
||||
if(penalty - SSshuttle.realtimeofstart > maximumRoundEnd + SSshuttle.emergencyCallTime + SSshuttle.emergencyDockTime + SSshuttle.emergencyEscapeTime)
|
||||
penalty = CANT_REENTER_ROUND
|
||||
|
||||
if(SEND_SIGNAL(src, COMSIG_MOB_GHOSTIZE, (stat == DEAD) ? TRUE : FALSE, FALSE, (stat == DEAD)? penalty : 0, (stat == DEAD)? TRUE : FALSE) & COMPONENT_BLOCK_GHOSTING)
|
||||
var/sig_flags = SEND_SIGNAL(src, COMSIG_MOB_GHOSTIZE, (stat == DEAD) ? TRUE : FALSE, FALSE, (stat == DEAD)? penalty : 0, (stat == DEAD)? TRUE : FALSE)
|
||||
|
||||
if(sig_flags & COMPONENT_BLOCK_GHOSTING)
|
||||
return
|
||||
|
||||
if(sig_flags & COMPONENT_DO_NOT_PENALIZE_GHOSTING)
|
||||
penalty = 0
|
||||
|
||||
if(stat != DEAD)
|
||||
succumb()
|
||||
if(stat == DEAD)
|
||||
if(stat == DEAD || sig_flags & COMPONENT_FREE_GHOSTING)
|
||||
ghostize(1)
|
||||
else
|
||||
var/response = alert(src, "Are you -sure- you want to ghost?\n(You are alive. If you ghost whilst alive you won't be able to re-enter this round [penalty ? "or play ghost roles [penalty == CANT_REENTER_ROUND ? "until the round is over" : "for the next [DisplayTimeText(penalty)]"]" : ""]! You can't change your mind so choose wisely!!)","Are you sure you want to ghost?","Ghost","Stay in body")
|
||||
@@ -317,21 +343,30 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
set name = "Ghost"
|
||||
set desc = "Relinquish your life and enter the land of the dead."
|
||||
|
||||
if(SEND_SIGNAL(src, COMSIG_MOB_GHOSTIZE, FALSE, FALSE) & COMPONENT_BLOCK_GHOSTING)
|
||||
var/sig_flags = SEND_SIGNAL(src, COMSIG_MOB_GHOSTIZE, FALSE, FALSE)
|
||||
|
||||
if(sig_flags & COMPONENT_BLOCK_GHOSTING)
|
||||
return
|
||||
|
||||
var/penalty = CONFIG_GET(number/suicide_reenter_round_timer) MINUTES
|
||||
var/roundstart_quit_limit = CONFIG_GET(number/roundstart_suicide_time_limit) MINUTES
|
||||
if(world.time < roundstart_quit_limit)
|
||||
penalty += roundstart_quit_limit - world.time
|
||||
var/maximumRoundEnd = SSautotransfer.starttime + SSautotransfer.voteinterval * SSautotransfer.maxvotes
|
||||
if(penalty - SSshuttle.realtimeofstart > maximumRoundEnd + SSshuttle.emergencyCallTime + SSshuttle.emergencyDockTime + SSshuttle.emergencyEscapeTime)
|
||||
penalty = CANT_REENTER_ROUND
|
||||
if(SSautotransfer.can_fire && SSautotransfer.maxvotes)
|
||||
var/maximumRoundEnd = SSautotransfer.starttime + SSautotransfer.voteinterval * SSautotransfer.maxvotes
|
||||
if(penalty - SSshuttle.realtimeofstart > maximumRoundEnd + SSshuttle.emergencyCallTime + SSshuttle.emergencyDockTime + SSshuttle.emergencyEscapeTime)
|
||||
penalty = CANT_REENTER_ROUND
|
||||
|
||||
var/response = alert(src, "Are you -sure- you want to ghost?\n(You are alive. If you ghost whilst alive you won't be able to re-enter this round [penalty ? "or play ghost roles [penalty == CANT_REENTER_ROUND ? "until the round is over" : "for the next [DisplayTimeText(penalty)]"]" : ""]! You can't change your mind so choose wisely!!)","Are you sure you want to ghost?","Ghost","Stay in body")
|
||||
if(response != "Ghost")
|
||||
return
|
||||
ghostize(0, penalize = TRUE)
|
||||
if(sig_flags & COMPONENT_DO_NOT_PENALIZE_GHOSTING)
|
||||
penalty = 0
|
||||
|
||||
if(sig_flags & COMPONENT_FREE_GHOSTING)
|
||||
ghostize(1)
|
||||
else
|
||||
var/response = alert(src, "Are you -sure- you want to ghost?\n(You are alive. If you ghost whilst alive you won't be able to re-enter this round [penalty ? "or play ghost roles [penalty == CANT_REENTER_ROUND ? "until the round is over" : "for the next [DisplayTimeText(penalty)]"]" : ""]! You can't change your mind so choose wisely!!)","Are you sure you want to ghost?","Ghost","Stay in body")
|
||||
if(response != "Ghost")
|
||||
return
|
||||
ghostize(0, penalize = TRUE)
|
||||
|
||||
|
||||
|
||||
@@ -375,6 +410,23 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
transfer_ckey(mind.current, FALSE)
|
||||
return 1
|
||||
|
||||
/mob/dead/observer/verb/stay_dead()
|
||||
set category = "Ghost"
|
||||
set name = "Do Not Resuscitate"
|
||||
if(!client)
|
||||
return
|
||||
if(!can_reenter_corpse)
|
||||
to_chat(usr, "<span class='warning'>You're already stuck out of your body!</span>")
|
||||
return FALSE
|
||||
|
||||
var/response = alert(src, "Are you sure you want to prevent (almost) all means of resuscitation? This cannot be undone. ","Are you sure you want to stay dead?","Yes","No")
|
||||
if(response != "Yes")
|
||||
return
|
||||
|
||||
can_reenter_corpse = FALSE
|
||||
to_chat(src, "You can no longer be brought back into your body.")
|
||||
return TRUE
|
||||
|
||||
/mob/dead/observer/proc/notify_cloning(var/message, var/sound, var/atom/source, flashwindow = TRUE)
|
||||
if(flashwindow)
|
||||
window_flash(client)
|
||||
@@ -648,6 +700,7 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
|
||||
return 0
|
||||
|
||||
transfer_ckey(target, FALSE)
|
||||
target.AddElement(/datum/element/ghost_role_eligibility, penalize_on_ghost = FALSE, free_ghosting = TRUE)
|
||||
target.faction = list("neutral")
|
||||
return 1
|
||||
|
||||
|
||||
@@ -237,7 +237,7 @@
|
||||
return /datum/reagent/blood/jellyblood
|
||||
if(dna?.species?.exotic_blood)
|
||||
return dna.species.exotic_blood
|
||||
else if((NOBLOOD in dna.species.species_traits) || (HAS_TRAIT(src, TRAIT_NOCLONE)))
|
||||
else if((dna && (NOBLOOD in dna.species.species_traits)) || HAS_TRAIT(src, TRAIT_NOCLONE))
|
||||
return
|
||||
else
|
||||
return /datum/reagent/blood
|
||||
|
||||
@@ -14,20 +14,23 @@
|
||||
var/force_replace_ai_name = FALSE
|
||||
var/overrides_aicore_laws = FALSE // Whether the laws on the MMI, if any, override possible pre-existing laws loaded on the AI core.
|
||||
|
||||
/obj/item/mmi/update_icon()
|
||||
/obj/item/mmi/update_icon_state()
|
||||
if(!brain)
|
||||
icon_state = "mmi_off"
|
||||
return
|
||||
if(istype(brain, /obj/item/organ/brain/alien))
|
||||
else if(istype(brain, /obj/item/organ/brain/alien))
|
||||
icon_state = "mmi_brain_alien"
|
||||
braintype = "Xenoborg" //HISS....Beep.
|
||||
else
|
||||
icon_state = "mmi_brain"
|
||||
braintype = "Cyborg"
|
||||
|
||||
/obj/item/mmi/update_overlays()
|
||||
. = ..()
|
||||
. += add_mmi_overlay()
|
||||
|
||||
/obj/item/mmi/proc/add_mmi_overlay()
|
||||
if(brainmob && brainmob.stat != DEAD)
|
||||
add_overlay("mmi_alive")
|
||||
. += "mmi_alive"
|
||||
else
|
||||
add_overlay("mmi_dead")
|
||||
. += "mmi_dead"
|
||||
|
||||
/obj/item/mmi/Initialize()
|
||||
. = ..()
|
||||
@@ -68,6 +71,10 @@
|
||||
|
||||
name = "Man-Machine Interface: [brainmob.real_name]"
|
||||
update_icon()
|
||||
if(istype(brain, /obj/item/organ/brain/alien))
|
||||
braintype = "Xenoborg" //HISS....Beep.
|
||||
else
|
||||
braintype = "Cyborg"
|
||||
|
||||
SSblackbox.record_feedback("amount", "mmis_filled", 1)
|
||||
|
||||
@@ -85,7 +92,7 @@
|
||||
to_chat(user, "<span class='notice'>You unlock and upend the MMI, spilling the brain onto the floor.</span>")
|
||||
eject_brain(user)
|
||||
update_icon()
|
||||
name = "Man-Machine Interface"
|
||||
name = initial(name)
|
||||
|
||||
/obj/item/mmi/proc/eject_brain(mob/user)
|
||||
brainmob.container = null //Reset brainmob mmi var.
|
||||
@@ -129,7 +136,10 @@
|
||||
|
||||
name = "Man-Machine Interface: [brainmob.real_name]"
|
||||
update_icon()
|
||||
return
|
||||
if(istype(brain, /obj/item/organ/brain/alien))
|
||||
braintype = "Xenoborg" //HISS....Beep.
|
||||
else
|
||||
braintype = "Cyborg"
|
||||
|
||||
/obj/item/mmi/proc/replacement_ai_name()
|
||||
return brainmob.name
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
return ..()
|
||||
|
||||
/mob/living/brain/update_mobility()
|
||||
return ((mobility_flags = (in_contents_of(/obj/mecha)? MOBILITY_FLAGS_DEFAULT : NONE)))
|
||||
return ((mobility_flags = (container?.in_contents_of(/obj/mecha)? MOBILITY_FLAGS_DEFAULT : NONE)))
|
||||
|
||||
/mob/living/brain/ex_act() //you cant blow up brainmobs because it makes transfer_to() freak out when borgs blow up.
|
||||
return
|
||||
|
||||
@@ -88,7 +88,7 @@
|
||||
brainmob.stored_dna = new /datum/dna/stored(brainmob)
|
||||
C.dna.copy_dna(brainmob.stored_dna)
|
||||
if(HAS_TRAIT(L, TRAIT_NOCLONE))
|
||||
brainmob.status_traits[TRAIT_NOCLONE] = L.status_traits[TRAIT_NOCLONE]
|
||||
LAZYSET(brainmob.status_traits, TRAIT_NOCLONE, L.status_traits[TRAIT_NOCLONE])
|
||||
var/obj/item/organ/zombie_infection/ZI = L.getorganslot(ORGAN_SLOT_ZOMBIE)
|
||||
if(ZI)
|
||||
brainmob.set_species(ZI.old_species) //For if the brain is cloned
|
||||
|
||||
@@ -28,6 +28,34 @@ GLOBAL_VAR(posibrain_notify_cooldown)
|
||||
var/list/possible_names //If you leave this blank, it will use the global posibrain names
|
||||
var/picked_name
|
||||
|
||||
/obj/item/mmi/posibrain/Initialize()
|
||||
. = ..()
|
||||
brainmob = new(src)
|
||||
var/new_name
|
||||
if(!LAZYLEN(possible_names))
|
||||
new_name = pick(GLOB.posibrain_names)
|
||||
else
|
||||
new_name = pick(possible_names)
|
||||
brainmob.name = "[new_name]-[rand(100, 999)]"
|
||||
brainmob.real_name = brainmob.name
|
||||
brainmob.forceMove(src)
|
||||
brainmob.container = src
|
||||
if(autoping)
|
||||
ping_ghosts("created", TRUE)
|
||||
GLOB.poi_list |= src
|
||||
LAZYADD(GLOB.mob_spawners[name], src)
|
||||
|
||||
/obj/item/mmi/posibrain/Destroy()
|
||||
latejoin_remove()
|
||||
return ..()
|
||||
|
||||
/obj/item/mmi/posibrain/proc/latejoin_remove()
|
||||
GLOB.poi_list -= src
|
||||
var/init_name = initial(name)
|
||||
LAZYREMOVE(GLOB.mob_spawners[init_name], src)
|
||||
if(!LAZYLEN(GLOB.mob_spawners[init_name]))
|
||||
GLOB.mob_spawners -= init_name
|
||||
|
||||
/obj/item/mmi/posibrain/Topic(href, href_list)
|
||||
if(href_list["activate"])
|
||||
var/mob/dead/observer/ghost = usr
|
||||
@@ -97,15 +125,6 @@ GLOBAL_VAR(posibrain_notify_cooldown)
|
||||
transfer_personality(user)
|
||||
latejoin_remove()
|
||||
|
||||
/obj/item/mmi/posibrain/Destroy()
|
||||
latejoin_remove()
|
||||
return ..()
|
||||
|
||||
/obj/item/mmi/posibrain/proc/latejoin_remove()
|
||||
GLOB.poi_list -= src
|
||||
LAZYREMOVE(GLOB.mob_spawners[name], src)
|
||||
if(!LAZYLEN(GLOB.mob_spawners[name]))
|
||||
GLOB.mob_spawners -= name
|
||||
|
||||
/obj/item/mmi/posibrain/transfer_identity(mob/living/carbon/C)
|
||||
name = "[initial(name)] ([C])"
|
||||
@@ -163,32 +182,17 @@ GLOBAL_VAR(posibrain_notify_cooldown)
|
||||
|
||||
. += msg
|
||||
|
||||
/obj/item/mmi/posibrain/Initialize()
|
||||
. = ..()
|
||||
brainmob = new(src)
|
||||
var/new_name
|
||||
if(!LAZYLEN(possible_names))
|
||||
new_name = pick(GLOB.posibrain_names)
|
||||
else
|
||||
new_name = pick(possible_names)
|
||||
brainmob.name = "[new_name]-[rand(100, 999)]"
|
||||
brainmob.real_name = brainmob.name
|
||||
brainmob.forceMove(src)
|
||||
brainmob.container = src
|
||||
if(autoping)
|
||||
ping_ghosts("created", TRUE)
|
||||
GLOB.poi_list |= src
|
||||
LAZYADD(GLOB.mob_spawners[name], src)
|
||||
|
||||
/obj/item/mmi/posibrain/attackby(obj/item/O, mob/user)
|
||||
return
|
||||
|
||||
|
||||
/obj/item/mmi/posibrain/update_icon()
|
||||
/obj/item/mmi/posibrain/update_icon_state()
|
||||
if(searching)
|
||||
icon_state = "[initial(icon_state)]-searching"
|
||||
return
|
||||
if(brainmob && brainmob.key)
|
||||
else if(brainmob && brainmob.key)
|
||||
icon_state = "[initial(icon_state)]-occupied"
|
||||
else
|
||||
icon_state = initial(icon_state)
|
||||
|
||||
/obj/item/mmi/posibrain/add_mmi_overlay()
|
||||
return
|
||||
|
||||
@@ -21,7 +21,7 @@ In all, this is a lot like the monkey code. /N
|
||||
return
|
||||
switch(M.a_intent)
|
||||
if (INTENT_HELP)
|
||||
if(!recoveringstam)
|
||||
if(!(combat_flags & COMBAT_FLAG_HARD_STAMCRIT))
|
||||
set_resting(FALSE, TRUE, FALSE)
|
||||
AdjustAllImmobility(-60, FALSE)
|
||||
AdjustUnconscious(-60, FALSE)
|
||||
|
||||
@@ -63,13 +63,13 @@
|
||||
if(hit_atom)
|
||||
if(isliving(hit_atom))
|
||||
var/mob/living/L = hit_atom
|
||||
if(!L.check_shields(src, 0, "the [name]", attack_type = LEAP_ATTACK))
|
||||
if(L.run_block(src, 0, "the [name]", ATTACK_TYPE_TACKLE, 0, src) & BLOCK_SUCCESS)
|
||||
DefaultCombatKnockdown(40, 1, 1)
|
||||
else
|
||||
L.visible_message("<span class ='danger'>[src] pounces on [L]!</span>", "<span class ='userdanger'>[src] pounces on you!</span>")
|
||||
L.DefaultCombatKnockdown(100)
|
||||
sleep(2)//Runtime prevention (infinite bump() calls on hulks)
|
||||
step_towards(src,L)
|
||||
else
|
||||
DefaultCombatKnockdown(40, 1, 1)
|
||||
|
||||
toggle_leap(0)
|
||||
else if(hit_atom.density && !hit_atom.CanPass(src))
|
||||
|
||||
@@ -21,12 +21,13 @@
|
||||
if(IsUnconscious() || IsSleeping() || getOxyLoss() > 50 || (HAS_TRAIT(src, TRAIT_DEATHCOMA)) || health <= crit_threshold)
|
||||
if(stat == CONSCIOUS)
|
||||
stat = UNCONSCIOUS
|
||||
blind_eyes(1)
|
||||
if(!eye_blind)
|
||||
blind_eyes(1)
|
||||
update_mobility()
|
||||
else
|
||||
if(stat == UNCONSCIOUS)
|
||||
stat = CONSCIOUS
|
||||
if(!recoveringstam)
|
||||
if(!(combat_flags & COMBAT_FLAG_HARD_STAMCRIT))
|
||||
set_resting(FALSE, TRUE)
|
||||
adjust_blindness(-1)
|
||||
update_mobility()
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
QDEL_LIST(stomach_contents)
|
||||
QDEL_LIST(bodyparts)
|
||||
QDEL_LIST(implants)
|
||||
hand_bodyparts = null //Just references out bodyparts, don't need to delete twice.
|
||||
remove_from_all_data_huds()
|
||||
QDEL_NULL(dna)
|
||||
GLOB.carbon_list -= src
|
||||
@@ -152,7 +153,7 @@
|
||||
return
|
||||
|
||||
//CIT CHANGES - makes it impossible to throw while in stamina softcrit
|
||||
if(getStaminaLoss() >= STAMINA_SOFTCRIT)
|
||||
if(IS_STAMCRIT(src))
|
||||
to_chat(src, "<span class='warning'>You're too exhausted.</span>")
|
||||
return
|
||||
var/random_turn = a_intent == INTENT_HARM
|
||||
@@ -282,6 +283,8 @@
|
||||
|
||||
/mob/living/carbon/resist_buckle()
|
||||
. = FALSE
|
||||
if(!buckled)
|
||||
return
|
||||
if(restrained())
|
||||
// too soon.
|
||||
if(last_special > world.time)
|
||||
@@ -396,6 +399,7 @@
|
||||
W.layer = initial(W.layer)
|
||||
W.plane = initial(W.plane)
|
||||
changeNext_move(0)
|
||||
update_equipment_speed_mods() // In case cuffs ever change speed
|
||||
|
||||
/mob/living/carbon/proc/clear_cuffs(obj/item/I, cuff_break)
|
||||
if(!I.loc || buckled)
|
||||
@@ -411,22 +415,21 @@
|
||||
else
|
||||
if(I == handcuffed)
|
||||
handcuffed.forceMove(drop_location())
|
||||
handcuffed.dropped(src)
|
||||
handcuffed = null
|
||||
I.dropped(src)
|
||||
if(buckled && buckled.buckle_requires_restraints)
|
||||
buckled.unbuckle_mob(src)
|
||||
update_handcuffed()
|
||||
return
|
||||
if(I == legcuffed)
|
||||
legcuffed.forceMove(drop_location())
|
||||
legcuffed.dropped()
|
||||
legcuffed = null
|
||||
I.dropped(src)
|
||||
update_inv_legcuffed()
|
||||
return
|
||||
else
|
||||
dropItemToGround(I)
|
||||
return
|
||||
return TRUE
|
||||
|
||||
/mob/living/carbon/get_standard_pixel_y_offset(lying = 0)
|
||||
if(lying)
|
||||
@@ -446,7 +449,7 @@
|
||||
modifier -= 40 //Clumsy people are more likely to hit themselves -Honk!
|
||||
|
||||
//CIT CHANGES START HERE
|
||||
else if(combatmode)
|
||||
else if(combat_flags & COMBAT_FLAG_COMBAT_ACTIVE)
|
||||
modifier += 50
|
||||
|
||||
if(modifier < 100)
|
||||
@@ -578,7 +581,7 @@
|
||||
/mob/living/carbon/update_stamina()
|
||||
var/stam = getStaminaLoss()
|
||||
if(stam > DAMAGE_PRECISION)
|
||||
var/total_health = (health - stam)
|
||||
var/total_health = (maxHealth - stam)
|
||||
if(total_health <= crit_threshold && !stat)
|
||||
if(CHECK_MOBILITY(src, MOBILITY_STAND))
|
||||
to_chat(src, "<span class='notice'>You're too exhausted to keep going...</span>")
|
||||
@@ -630,6 +633,13 @@
|
||||
if(M.name == XRAY)
|
||||
sight |= (SEE_TURFS|SEE_MOBS|SEE_OBJS)
|
||||
see_in_dark = max(see_in_dark, 8)
|
||||
if(HAS_TRAIT(src, TRAIT_THERMAL_VISION))
|
||||
sight |= (SEE_MOBS)
|
||||
lighting_alpha = min(lighting_alpha, LIGHTING_PLANE_ALPHA_MOSTLY_VISIBLE)
|
||||
|
||||
if(HAS_TRAIT(src, TRAIT_XRAY_VISION))
|
||||
sight |= (SEE_TURFS|SEE_MOBS|SEE_OBJS)
|
||||
see_in_dark = max(see_in_dark, 8)
|
||||
|
||||
if(see_override)
|
||||
see_invisible = see_override
|
||||
@@ -811,14 +821,13 @@
|
||||
return
|
||||
if(IsUnconscious() || IsSleeping() || getOxyLoss() > 50 || (HAS_TRAIT(src, TRAIT_DEATHCOMA)) || (health <= HEALTH_THRESHOLD_FULLCRIT && !HAS_TRAIT(src, TRAIT_NOHARDCRIT)))
|
||||
stat = UNCONSCIOUS
|
||||
blind_eyes(1)
|
||||
if(combatmode)
|
||||
toggle_combat_mode(TRUE, TRUE)
|
||||
disable_intentional_combat_mode(FALSE, FALSE)
|
||||
if(!eye_blind)
|
||||
blind_eyes(1)
|
||||
else
|
||||
if(health <= crit_threshold && !HAS_TRAIT(src, TRAIT_NOSOFTCRIT))
|
||||
stat = SOFT_CRIT
|
||||
if(combatmode)
|
||||
toggle_combat_mode(TRUE, TRUE)
|
||||
disable_intentional_combat_mode(FALSE, FALSE)
|
||||
else
|
||||
stat = CONSCIOUS
|
||||
adjust_blindness(-1)
|
||||
@@ -974,14 +983,121 @@
|
||||
|
||||
/mob/living/carbon/vv_get_dropdown()
|
||||
. = ..()
|
||||
. += "---"
|
||||
.["Make AI"] = "?_src_=vars;[HrefToken()];makeai=[REF(src)]"
|
||||
.["Modify bodypart"] = "?_src_=vars;[HrefToken()];editbodypart=[REF(src)]"
|
||||
.["Modify organs"] = "?_src_=vars;[HrefToken()];editorgans=[REF(src)]"
|
||||
.["Hallucinate"] = "?_src_=vars;[HrefToken()];hallucinate=[REF(src)]"
|
||||
.["Give martial arts"] = "?_src_=vars;[HrefToken()];givemartialart=[REF(src)]"
|
||||
.["Give brain trauma"] = "?_src_=vars;[HrefToken()];givetrauma=[REF(src)]"
|
||||
.["Cure brain traumas"] = "?_src_=vars;[HrefToken()];curetraumas=[REF(src)]"
|
||||
VV_DROPDOWN_OPTION("", "---------")
|
||||
VV_DROPDOWN_OPTION(VV_HK_MAKE_AI, "Make AI")
|
||||
VV_DROPDOWN_OPTION(VV_HK_MODIFY_BODYPART, "Modify bodypart")
|
||||
VV_DROPDOWN_OPTION(VV_HK_MODIFY_ORGANS, "Modify organs")
|
||||
VV_DROPDOWN_OPTION(VV_HK_HALLUCINATION, "Hallucinate")
|
||||
VV_DROPDOWN_OPTION(VV_HK_MARTIAL_ART, "Give Martial Arts")
|
||||
VV_DROPDOWN_OPTION(VV_HK_GIVE_TRAUMA, "Give Brain Trauma")
|
||||
VV_DROPDOWN_OPTION(VV_HK_CURE_TRAUMA, "Cure Brain Traumas")
|
||||
|
||||
/mob/living/carbon/vv_do_topic(list/href_list)
|
||||
. = ..()
|
||||
if(href_list[VV_HK_MODIFY_BODYPART])
|
||||
if(!check_rights(R_SPAWN))
|
||||
return
|
||||
var/edit_action = input(usr, "What would you like to do?","Modify Body Part") as null|anything in list("add","remove", "augment")
|
||||
if(!edit_action)
|
||||
return
|
||||
var/list/limb_list = list()
|
||||
if(edit_action == "remove" || edit_action == "augment")
|
||||
for(var/obj/item/bodypart/B in bodyparts)
|
||||
limb_list += B.body_zone
|
||||
if(edit_action == "remove")
|
||||
limb_list -= BODY_ZONE_CHEST
|
||||
else
|
||||
limb_list = list(BODY_ZONE_HEAD, BODY_ZONE_L_ARM, BODY_ZONE_R_ARM, BODY_ZONE_L_LEG, BODY_ZONE_R_LEG)
|
||||
for(var/obj/item/bodypart/B in bodyparts)
|
||||
limb_list -= B.body_zone
|
||||
var/result = input(usr, "Please choose which body part to [edit_action]","[capitalize(edit_action)] Body Part") as null|anything in limb_list
|
||||
if(result)
|
||||
var/obj/item/bodypart/BP = get_bodypart(result)
|
||||
switch(edit_action)
|
||||
if("remove")
|
||||
if(BP)
|
||||
BP.drop_limb()
|
||||
else
|
||||
to_chat(usr, "[src] doesn't have such bodypart.")
|
||||
if("add")
|
||||
if(BP)
|
||||
to_chat(usr, "[src] already has such bodypart.")
|
||||
else
|
||||
if(!regenerate_limb(result))
|
||||
to_chat(usr, "[src] cannot have such bodypart.")
|
||||
if("augment")
|
||||
if(ishuman(src))
|
||||
if(BP)
|
||||
BP.change_bodypart_status(BODYPART_ROBOTIC, TRUE, TRUE)
|
||||
else
|
||||
to_chat(usr, "[src] doesn't have such bodypart.")
|
||||
else
|
||||
to_chat(usr, "Only humans can be augmented.")
|
||||
admin_ticket_log("[key_name_admin(usr)] has modified the bodyparts of [src]")
|
||||
if(href_list[VV_HK_MAKE_AI])
|
||||
if(!check_rights(R_SPAWN))
|
||||
return
|
||||
if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform")
|
||||
return
|
||||
usr.client.holder.Topic("vv_override", list("makeai"=href_list[VV_HK_TARGET]))
|
||||
if(href_list[VV_HK_MODIFY_ORGANS])
|
||||
if(!check_rights(NONE))
|
||||
return
|
||||
usr.client.manipulate_organs(src)
|
||||
if(href_list[VV_HK_MARTIAL_ART])
|
||||
if(!check_rights(NONE))
|
||||
return
|
||||
var/list/artpaths = subtypesof(/datum/martial_art)
|
||||
var/list/artnames = list()
|
||||
for(var/i in artpaths)
|
||||
var/datum/martial_art/M = i
|
||||
artnames[initial(M.name)] = M
|
||||
var/result = input(usr, "Choose the martial art to teach","JUDO CHOP") as null|anything in artnames
|
||||
if(!usr)
|
||||
return
|
||||
if(QDELETED(src))
|
||||
to_chat(usr, "Mob doesn't exist anymore")
|
||||
return
|
||||
if(result)
|
||||
var/chosenart = artnames[result]
|
||||
var/datum/martial_art/MA = new chosenart
|
||||
MA.teach(src)
|
||||
log_admin("[key_name(usr)] has taught [MA] to [key_name(src)].")
|
||||
message_admins("<span class='notice'>[key_name_admin(usr)] has taught [MA] to [key_name_admin(src)].</span>")
|
||||
if(href_list[VV_HK_GIVE_TRAUMA])
|
||||
if(!check_rights(NONE))
|
||||
return
|
||||
var/list/traumas = subtypesof(/datum/brain_trauma)
|
||||
var/result = input(usr, "Choose the brain trauma to apply","Traumatize") as null|anything in traumas
|
||||
if(!usr)
|
||||
return
|
||||
if(QDELETED(src))
|
||||
to_chat(usr, "Mob doesn't exist anymore")
|
||||
return
|
||||
if(!result)
|
||||
return
|
||||
var/datum/brain_trauma/BT = gain_trauma(result)
|
||||
if(BT)
|
||||
log_admin("[key_name(usr)] has traumatized [key_name(src)] with [BT.name]")
|
||||
message_admins("<span class='notice'>[key_name_admin(usr)] has traumatized [key_name_admin(src)] with [BT.name].</span>")
|
||||
if(href_list[VV_HK_CURE_TRAUMA])
|
||||
if(!check_rights(NONE))
|
||||
return
|
||||
cure_all_traumas(TRAUMA_RESILIENCE_ABSOLUTE)
|
||||
log_admin("[key_name(usr)] has cured all traumas from [key_name(src)].")
|
||||
message_admins("<span class='notice'>[key_name_admin(usr)] has cured all traumas from [key_name_admin(src)].</span>")
|
||||
if(href_list[VV_HK_HALLUCINATION])
|
||||
if(!check_rights(NONE))
|
||||
return
|
||||
var/list/hallucinations = subtypesof(/datum/hallucination)
|
||||
var/result = input(usr, "Choose the hallucination to apply","Send Hallucination") as null|anything in hallucinations
|
||||
if(!usr)
|
||||
return
|
||||
if(QDELETED(src))
|
||||
to_chat(usr, "Mob doesn't exist anymore")
|
||||
return
|
||||
if(result)
|
||||
new result(src, TRUE)
|
||||
|
||||
/mob/living/carbon/can_resist()
|
||||
return bodyparts.len > 2 && ..()
|
||||
@@ -1001,8 +1117,7 @@
|
||||
return TRUE
|
||||
|
||||
/mob/living/carbon/transfer_ckey(mob/new_mob, send_signal = TRUE)
|
||||
if(combatmode)
|
||||
toggle_combat_mode(TRUE, TRUE)
|
||||
disable_intentional_combat_mode(TRUE, FALSE)
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/can_see_reagents()
|
||||
@@ -1018,3 +1133,19 @@
|
||||
|
||||
/mob/living/carbon/can_hold_items()
|
||||
return TRUE
|
||||
|
||||
/mob/living/carbon/set_gender(ngender = NEUTER, silent = FALSE, update_icon = TRUE, forced = FALSE)
|
||||
var/bender = gender != ngender
|
||||
. = ..()
|
||||
if(!.)
|
||||
return
|
||||
if(dna && bender)
|
||||
if(ngender == MALE || ngender == FEMALE)
|
||||
dna.features["body_model"] = ngender
|
||||
if(!silent)
|
||||
var/adj = ngender == MALE ? "masculine" : "feminine"
|
||||
visible_message("<span class='boldnotice'>[src] suddenly looks more [adj]!</span>", "<span class='boldwarning'>You suddenly feel more [adj]!</span>")
|
||||
else if(ngender == NEUTER)
|
||||
dna.features["body_model"] = MALE
|
||||
if(update_icon)
|
||||
update_body()
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
/mob/living/carbon/enable_intentional_combat_mode()
|
||||
. = ..()
|
||||
if(.)
|
||||
if(voremode)
|
||||
toggle_vore_mode()
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
if(istype(src.glasses, /obj/item/clothing/glasses)) //glasses
|
||||
var/obj/item/clothing/glasses/GFP = src.glasses
|
||||
number += GFP.flash_protect
|
||||
|
||||
|
||||
if(istype(src.wear_mask, /obj/item/clothing/mask)) //mask
|
||||
var/obj/item/clothing/mask/MFP = src.wear_mask
|
||||
number += MFP.flash_protect
|
||||
@@ -71,6 +71,7 @@
|
||||
L.embedded_objects |= I
|
||||
I.add_mob_blood(src)//it embedded itself in you, of course it's bloody!
|
||||
I.forceMove(src)
|
||||
I.embedded()
|
||||
L.receive_damage(I.w_class*I.embedding.embedded_impact_pain_multiplier)
|
||||
visible_message("<span class='danger'>[I] embeds itself in [src]'s [L.name]!</span>","<span class='userdanger'>[I] embeds itself in your [L.name]!</span>")
|
||||
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "embedded", /datum/mood_event/embedded)
|
||||
@@ -78,33 +79,30 @@
|
||||
/mob/living/carbon/attacked_by(obj/item/I, mob/living/user)
|
||||
//CIT CHANGES START HERE - combatmode and resting checks
|
||||
var/totitemdamage = I.force
|
||||
if(iscarbon(user))
|
||||
var/mob/living/carbon/tempcarb = user
|
||||
if(!tempcarb.combatmode)
|
||||
totitemdamage *= 0.5
|
||||
if(!(user.combat_flags & COMBAT_FLAG_COMBAT_ACTIVE))
|
||||
totitemdamage *= 0.5
|
||||
if(!CHECK_MOBILITY(user, MOBILITY_STAND))
|
||||
totitemdamage *= 0.5
|
||||
if(!combatmode)
|
||||
if(!(combat_flags & COMBAT_FLAG_COMBAT_ACTIVE))
|
||||
totitemdamage *= 1.5
|
||||
//CIT CHANGES END HERE
|
||||
if(user != src && check_shields(I, totitemdamage, "the [I.name]", MELEE_ATTACK, I.armour_penetration))
|
||||
var/impacting_zone = (user == src)? check_zone(user.zone_selected) : ran_zone(user.zone_selected)
|
||||
if((user != src) && (run_block(I, totitemdamage, "the [I]", ATTACK_TYPE_MELEE, I.armour_penetration, user, impacting_zone) & BLOCK_SUCCESS))
|
||||
return FALSE
|
||||
var/obj/item/bodypart/affecting
|
||||
if(user == src)
|
||||
affecting = get_bodypart(check_zone(user.zone_selected)) //we're self-mutilating! yay!
|
||||
else
|
||||
affecting = get_bodypart(ran_zone(user.zone_selected))
|
||||
var/obj/item/bodypart/affecting = get_bodypart(impacting_zone)
|
||||
if(!affecting) //missing limb? we select the first bodypart (you can never have zero, because of chest)
|
||||
affecting = bodyparts[1]
|
||||
SEND_SIGNAL(I, COMSIG_ITEM_ATTACK_ZONE, src, user, affecting)
|
||||
send_item_attack_message(I, user, affecting.name)
|
||||
I.do_stagger_action(src, user)
|
||||
if(I.force)
|
||||
apply_damage(totitemdamage, I.damtype, affecting) //CIT CHANGE - replaces I.force with totitemdamage
|
||||
if(I.damtype == BRUTE && affecting.status == BODYPART_ORGANIC)
|
||||
var/basebloodychance = affecting.brute_dam + totitemdamage
|
||||
if(prob(basebloodychance))
|
||||
I.add_mob_blood(src)
|
||||
bleed(totitemdamage)
|
||||
var/turf/location = get_turf(src)
|
||||
add_splatter_floor(location)
|
||||
if(totitemdamage >= 10 && get_dist(user, src) <= 1) //people with TK won't get smeared with blood
|
||||
user.add_mob_blood(src)
|
||||
|
||||
@@ -238,19 +236,19 @@
|
||||
var/obj/item/organ/O = X
|
||||
O.emp_act(severity)
|
||||
|
||||
/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))
|
||||
/mob/living/carbon/electrocute_act(shock_damage, source, siemens_coeff = 1, flags = NONE)
|
||||
if((flags & SHOCK_TESLA) && (flags_1 & TESLA_IGNORE_1))
|
||||
return FALSE
|
||||
if(HAS_TRAIT(src, TRAIT_SHOCKIMMUNE))
|
||||
return FALSE
|
||||
shock_damage *= siemens_coeff
|
||||
if(dna && dna.species)
|
||||
shock_damage *= dna.species.siemens_coeff
|
||||
if(shock_damage<1 && !override)
|
||||
if(shock_damage < 1)
|
||||
return 0
|
||||
if(reagents.has_reagent(/datum/reagent/teslium))
|
||||
shock_damage *= 1.5 //If the mob has teslium in their body, shocks are 50% more damaging!
|
||||
if(illusion)
|
||||
if((flags & SHOCK_ILLUSION))
|
||||
adjustStaminaLoss(shock_damage)
|
||||
else
|
||||
take_overall_damage(0,shock_damage)
|
||||
@@ -262,16 +260,13 @@
|
||||
jitteriness += 1000 //High numbers for violent convulsions
|
||||
do_jitter_animation(jitteriness)
|
||||
stuttering += 2
|
||||
if((!tesla_shock || (tesla_shock && siemens_coeff > 0.5)) && stun)
|
||||
if((!(flags & SHOCK_TESLA) || siemens_coeff > 0.5) && !(flags & SHOCK_NOSTUN))
|
||||
Stun(40)
|
||||
spawn(20)
|
||||
jitteriness = max(jitteriness - 990, 10) //Still jittery, but vastly less
|
||||
if((!tesla_shock || (tesla_shock && siemens_coeff > 0.5)) && stun)
|
||||
if((!(flags & SHOCK_TESLA) || siemens_coeff > 0.5) && !(flags & SHOCK_NOSTUN))
|
||||
DefaultCombatKnockdown(60)
|
||||
if(override)
|
||||
return override
|
||||
else
|
||||
return shock_damage
|
||||
return shock_damage
|
||||
|
||||
/mob/living/carbon/proc/help_shake_act(mob/living/carbon/M)
|
||||
if(on_fire)
|
||||
@@ -280,6 +275,8 @@
|
||||
|
||||
if(health >= 0 && !(HAS_TRAIT(src, TRAIT_FAKEDEATH)))
|
||||
var/friendly_check = FALSE
|
||||
if(run_block(M, 0, M.name, ATTACK_TYPE_UNARMED))
|
||||
return
|
||||
if(lying)
|
||||
if(buckled)
|
||||
to_chat(M, "<span class='warning'>You need to unbuckle [src] first to do that!")
|
||||
@@ -302,30 +299,12 @@
|
||||
"<span class='notice'>You give [src] a pat on the head to make [p_them()] feel better!</span>")
|
||||
SEND_SIGNAL(src, COMSIG_ADD_MOOD_EVENT, "headpat", /datum/mood_event/headpat)
|
||||
friendly_check = TRUE
|
||||
if(S?.can_wag_tail(src))
|
||||
if("tail_human" in S.default_features)
|
||||
if(dna.features["tail_human"] == "None")
|
||||
return
|
||||
else
|
||||
if(!dna.species.is_wagging_tail())
|
||||
emote("wag")
|
||||
|
||||
if("tail_lizard" in S.default_features)
|
||||
if(dna.features["tail_lizard"] == "None")
|
||||
return
|
||||
else
|
||||
if(!dna.species.is_wagging_tail())
|
||||
emote("wag")
|
||||
|
||||
if("mam_tail" in S.default_features)
|
||||
if(dna.features["mam_tail"] == "None")
|
||||
return
|
||||
else
|
||||
if(!dna.species.is_wagging_tail())
|
||||
emote("wag")
|
||||
|
||||
else
|
||||
return
|
||||
if(S?.can_wag_tail(src) && !dna.species.is_wagging_tail())
|
||||
var/static/list/many_tails = list("tail_human", "tail_lizard", "mam_tail")
|
||||
for(var/T in many_tails)
|
||||
if(S.mutant_bodyparts[T] && dna.features[T] != "None")
|
||||
emote("wag")
|
||||
break
|
||||
|
||||
else if(check_zone(M.zone_selected) == BODY_ZONE_R_ARM || check_zone(M.zone_selected) == BODY_ZONE_L_ARM)
|
||||
M.visible_message( \
|
||||
@@ -349,7 +328,7 @@
|
||||
AdjustAllImmobility(-60, FALSE)
|
||||
AdjustUnconscious(-60, FALSE)
|
||||
AdjustSleeping(-100, FALSE)
|
||||
if(recoveringstam)
|
||||
if(combat_flags & COMBAT_FLAG_HARD_STAMCRIT)
|
||||
adjustStaminaLoss(-15)
|
||||
else
|
||||
set_resting(FALSE, FALSE)
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
/// Sprint buffer ///
|
||||
/mob/living/carbon/doSprintLossTiles(tiles)
|
||||
doSprintBufferRegen(FALSE) //first regen.
|
||||
if(sprint_buffer)
|
||||
var/use = min(tiles, sprint_buffer)
|
||||
sprint_buffer -= use
|
||||
tiles -= use
|
||||
update_hud_sprint_bar()
|
||||
if(!tiles) //we had enough, we're done!
|
||||
return
|
||||
adjustStaminaLoss(tiles * sprint_stamina_cost) //use stamina to cover deficit.
|
||||
|
||||
/mob/living/carbon/proc/doSprintBufferRegen(updating = TRUE)
|
||||
var/diff = world.time - sprint_buffer_regen_last
|
||||
sprint_buffer_regen_last = world.time
|
||||
sprint_buffer = min(sprint_buffer_max, sprint_buffer + sprint_buffer_regen_ds * diff)
|
||||
if(updating)
|
||||
update_hud_sprint_bar()
|
||||
@@ -7,8 +7,8 @@
|
||||
|
||||
if(!gibbed)
|
||||
emote("deathgasp")
|
||||
if(combatmode)
|
||||
toggle_combat_mode(TRUE, TRUE)
|
||||
|
||||
disable_intentional_combat_mode(TRUE, FALSE)
|
||||
|
||||
. = ..()
|
||||
|
||||
@@ -67,6 +67,5 @@
|
||||
BP.throw_at(get_edge_target_turf(src,pick(GLOB.alldirs)),rand(1,3),5)
|
||||
|
||||
/mob/living/carbon/ghostize(can_reenter_corpse = TRUE, special = FALSE, penalize = FALSE, voluntary = FALSE)
|
||||
if(combatmode)
|
||||
toggle_combat_mode(TRUE, TRUE)
|
||||
disable_intentional_combat_mode(TRUE, FALSE)
|
||||
return ..()
|
||||
|
||||
@@ -90,7 +90,7 @@
|
||||
if(digitalcamo)
|
||||
. += "[t_He] [t_is] moving [t_his] body in an unnatural and blatantly unsimian manner."
|
||||
|
||||
if(combatmode)
|
||||
if(combat_flags & COMBAT_FLAG_COMBAT_ACTIVE)
|
||||
. += "[t_He] [t_is] visibly tense[CHECK_MOBILITY(src, MOBILITY_STAND) ? "." : ", and [t_is] standing in combative stance."]"
|
||||
|
||||
var/trait_exam = common_trait_examine()
|
||||
|
||||
@@ -128,7 +128,7 @@
|
||||
/datum/emote/living/carbon/human/wing/select_message_type(mob/user)
|
||||
. = ..()
|
||||
var/mob/living/carbon/human/H = user
|
||||
if("wings" in H.dna.species.mutant_bodyparts)
|
||||
if(H.dna.species.mutant_bodyparts["wings"])
|
||||
. = "opens " + message
|
||||
else
|
||||
. = "closes " + message
|
||||
@@ -143,17 +143,17 @@
|
||||
/mob/living/carbon/human/proc/OpenWings()
|
||||
if(!dna || !dna.species)
|
||||
return
|
||||
if("wings" in dna.species.mutant_bodyparts)
|
||||
if(dna.species.mutant_bodyparts["wings"])
|
||||
dna.species.mutant_bodyparts["wingsopen"] = dna.species.mutant_bodyparts["wings"]
|
||||
dna.species.mutant_bodyparts -= "wings"
|
||||
dna.species.mutant_bodyparts |= "wingsopen"
|
||||
update_body()
|
||||
|
||||
/mob/living/carbon/human/proc/CloseWings()
|
||||
if(!dna || !dna.species)
|
||||
return
|
||||
if("wingsopen" in dna.species.mutant_bodyparts)
|
||||
if(dna.species.mutant_bodyparts["wingsopen"])
|
||||
dna.species.mutant_bodyparts["wings"] = dna.species.mutant_bodyparts["wingsopen"]
|
||||
dna.species.mutant_bodyparts -= "wingsopen"
|
||||
dna.species.mutant_bodyparts |= "wings"
|
||||
update_body()
|
||||
if(isturf(loc))
|
||||
var/turf/T = loc
|
||||
|
||||
@@ -25,15 +25,10 @@
|
||||
var/list/obscured = check_obscured_slots()
|
||||
var/skipface = (wear_mask && (wear_mask.flags_inv & HIDEFACE)) || (head && (head.flags_inv & HIDEFACE))
|
||||
|
||||
if(ishuman(src)) //user just returned, y'know, the user's own species. dumb.
|
||||
var/mob/living/carbon/human/H = src
|
||||
var/datum/species/pref_species = H.dna.species
|
||||
if(get_visible_name() == "Unknown") // same as flavor text, but hey it works.
|
||||
. += "You can't make out what species they are."
|
||||
else if(skipface)
|
||||
. += "You can't make out what species they are."
|
||||
else
|
||||
. += "[t_He] [t_is] a [H.dna.custom_species ? H.dna.custom_species : pref_species.name]!"
|
||||
if(skipface || get_visible_name() == "Unknown")
|
||||
. += "You can't make out what species they are."
|
||||
else
|
||||
. += "[t_He] [t_is] a [dna.custom_species ? dna.custom_species : dna.species.name]!"
|
||||
|
||||
//uniform
|
||||
if(w_uniform && !(SLOT_W_UNIFORM in obscured))
|
||||
@@ -389,18 +384,8 @@
|
||||
else if(isobserver(user) && traitstring)
|
||||
. += "<span class='info'><b>Traits:</b> [traitstring]</span>"
|
||||
|
||||
//No flavor text unless the face can be seen. Prevents certain metagaming with impersonation.
|
||||
var/invisible_man = skipface || get_visible_name() == "Unknown"
|
||||
if(invisible_man)
|
||||
. += "...?"
|
||||
else
|
||||
var/flavor = print_flavor_text(flavor_text)
|
||||
if(flavor)
|
||||
. += flavor
|
||||
var/temp_flavor = print_flavor_text(flavor_text_2,TRUE)
|
||||
if(temp_flavor)
|
||||
. += temp_flavor
|
||||
SEND_SIGNAL(src, COMSIG_PARENT_EXAMINE, user, .)
|
||||
SEND_SIGNAL(src, COMSIG_PARENT_EXAMINE, user, .) //This also handles flavor texts now
|
||||
|
||||
. += "*---------*</span>"
|
||||
|
||||
/mob/living/proc/status_effect_examines(pronoun_replacement) //You can include this in any mob's examine() to show the examine texts of status effects!
|
||||
|
||||
@@ -9,8 +9,6 @@
|
||||
verbs += /mob/living/proc/mob_sleep
|
||||
verbs += /mob/living/proc/lay_down
|
||||
verbs += /mob/living/carbon/human/proc/underwear_toggle //fwee
|
||||
verbs += /mob/proc/set_flavor
|
||||
verbs += /mob/proc/set_flavor_2
|
||||
|
||||
//initialize limbs first
|
||||
create_bodyparts()
|
||||
@@ -31,7 +29,7 @@
|
||||
. = ..()
|
||||
|
||||
if(CONFIG_GET(flag/disable_stambuffer))
|
||||
togglesprint()
|
||||
enable_intentional_sprint_mode()
|
||||
|
||||
RegisterSignal(src, COMSIG_COMPONENT_CLEAN_ACT, /atom.proc/clean_blood)
|
||||
|
||||
@@ -40,6 +38,8 @@
|
||||
. = ..()
|
||||
if(!CONFIG_GET(flag/disable_human_mood))
|
||||
AddComponent(/datum/component/mood)
|
||||
AddElement(/datum/element/flavor_text/carbon)
|
||||
AddElement(/datum/element/flavor_text, "", "Temporary Flavor Text", "This should be used only for things pertaining to the current round!")
|
||||
|
||||
/mob/living/carbon/human/Destroy()
|
||||
QDEL_NULL(physiology)
|
||||
@@ -242,6 +242,12 @@
|
||||
return
|
||||
|
||||
if(href_list["pockets"])
|
||||
var/strip_mod = 1
|
||||
var/strip_silence = FALSE
|
||||
var/obj/item/clothing/gloves/g = gloves
|
||||
if (istype(g))
|
||||
strip_mod = g.strip_mod
|
||||
strip_silence = g.strip_silence
|
||||
var/pocket_side = href_list["pockets"]
|
||||
var/pocket_id = (pocket_side == "right" ? SLOT_R_STORE : SLOT_L_STORE)
|
||||
var/obj/item/pocket_item = (pocket_id == SLOT_R_STORE ? r_store : l_store)
|
||||
@@ -258,7 +264,7 @@
|
||||
else
|
||||
return
|
||||
|
||||
if(do_mob(usr, src, POCKET_STRIP_DELAY/delay_denominator, ignorehelditem = TRUE)) //placing an item into the pocket is 4 times faster
|
||||
if(do_mob(usr, src, max(round(POCKET_STRIP_DELAY/(delay_denominator*strip_mod)),1), ignorehelditem = TRUE)) //placing an item into the pocket is 4 times faster (and the strip_mod too)
|
||||
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)
|
||||
@@ -276,7 +282,8 @@
|
||||
show_inv(usr)
|
||||
else
|
||||
// Display a warning if the user mocks up
|
||||
to_chat(src, "<span class='warning'>You feel your [pocket_side] pocket being fumbled with!</span>")
|
||||
if (!strip_silence)
|
||||
to_chat(src, "<span class='warning'>You feel your [pocket_side] pocket being fumbled with!</span>")
|
||||
|
||||
..() //CITADEL CHANGE - removes a tab from behind this ..() so that flavortext can actually be examined
|
||||
|
||||
@@ -614,16 +621,16 @@
|
||||
|
||||
//Used for new human mobs created by cloning/goleming/podding
|
||||
/mob/living/carbon/human/proc/set_cloned_appearance()
|
||||
if(gender == MALE)
|
||||
if(dna.features["body_model"] == MALE)
|
||||
facial_hair_style = "Full Beard"
|
||||
else
|
||||
facial_hair_style = "Shaved"
|
||||
hair_style = pick("Bedhead", "Bedhead 2", "Bedhead 3")
|
||||
underwear = "Nude"
|
||||
undershirt = "Nude"
|
||||
update_body()
|
||||
socks = "Nude"
|
||||
update_body(TRUE)
|
||||
update_hair()
|
||||
update_genitals()
|
||||
|
||||
/mob/living/carbon/human/singularity_pull(S, current_size)
|
||||
..()
|
||||
@@ -700,7 +707,7 @@
|
||||
|
||||
/mob/living/carbon/human/wash_cream()
|
||||
if(creamed) //clean both to prevent a rare bug
|
||||
cut_overlay(mutable_appearance('icons/effects/creampie.dmi', "creampie_lizard"))
|
||||
cut_overlay(mutable_appearance('icons/effects/creampie.dmi', "creampie_snout"))
|
||||
cut_overlay(mutable_appearance('icons/effects/creampie.dmi', "creampie_human"))
|
||||
creamed = FALSE
|
||||
|
||||
@@ -761,7 +768,7 @@
|
||||
return
|
||||
else
|
||||
if(hud_used.healths)
|
||||
var/health_amount = health - CLAMP(getStaminaLoss()-50, 0, 80)//CIT CHANGE - makes staminaloss have less of an impact on the health hud
|
||||
var/health_amount = min(health, maxHealth - CLAMP(getStaminaLoss()-50, 0, 80))//CIT CHANGE - makes staminaloss have less of an impact on the health hud
|
||||
if(..(health_amount)) //not dead
|
||||
switch(hal_screwyhud)
|
||||
if(SCREWYHUD_CRIT)
|
||||
@@ -842,15 +849,95 @@
|
||||
|
||||
/mob/living/carbon/human/vv_get_dropdown()
|
||||
. = ..()
|
||||
. += "---"
|
||||
.["Make monkey"] = "?_src_=vars;[HrefToken()];makemonkey=[REF(src)]"
|
||||
.["Set Species"] = "?_src_=vars;[HrefToken()];setspecies=[REF(src)]"
|
||||
.["Make cyborg"] = "?_src_=vars;[HrefToken()];makerobot=[REF(src)]"
|
||||
.["Make alien"] = "?_src_=vars;[HrefToken()];makealien=[REF(src)]"
|
||||
.["Make slime"] = "?_src_=vars;[HrefToken()];makeslime=[REF(src)]"
|
||||
.["Toggle Purrbation"] = "?_src_=vars;[HrefToken()];purrbation=[REF(src)]"
|
||||
.["Copy outfit"] = "?_src_=vars;[HrefToken()];copyoutfit=[REF(src)]"
|
||||
.["Add/Remove Quirks"] = "?_src_=vars;[HrefToken()];modquirks=[REF(src)]"
|
||||
VV_DROPDOWN_OPTION("", "---------")
|
||||
VV_DROPDOWN_OPTION(VV_HK_COPY_OUTFIT, "Copy Outfit")
|
||||
VV_DROPDOWN_OPTION(VV_HK_MOD_QUIRKS, "Add/Remove Quirks")
|
||||
VV_DROPDOWN_OPTION(VV_HK_MAKE_MONKEY, "Make Monkey")
|
||||
VV_DROPDOWN_OPTION(VV_HK_MAKE_CYBORG, "Make Cyborg")
|
||||
VV_DROPDOWN_OPTION(VV_HK_MAKE_SLIME, "Make Slime")
|
||||
VV_DROPDOWN_OPTION(VV_HK_MAKE_ALIEN, "Make Alien")
|
||||
VV_DROPDOWN_OPTION(VV_HK_SET_SPECIES, "Set Species")
|
||||
VV_DROPDOWN_OPTION(VV_HK_PURRBATION, "Toggle Purrbation")
|
||||
|
||||
/mob/living/carbon/human/vv_do_topic(list/href_list)
|
||||
. = ..()
|
||||
if(href_list[VV_HK_COPY_OUTFIT])
|
||||
if(!check_rights(R_SPAWN))
|
||||
return
|
||||
copy_outfit()
|
||||
if(href_list[VV_HK_MOD_QUIRKS])
|
||||
if(!check_rights(R_SPAWN))
|
||||
return
|
||||
|
||||
var/list/options = list("Clear"="Clear")
|
||||
for(var/x in subtypesof(/datum/quirk))
|
||||
var/datum/quirk/T = x
|
||||
var/qname = initial(T.name)
|
||||
options[has_quirk(T) ? "[qname] (Remove)" : "[qname] (Add)"] = T
|
||||
|
||||
var/result = input(usr, "Choose quirk to add/remove","Quirk Mod") as null|anything in options
|
||||
if(result)
|
||||
if(result == "Clear")
|
||||
for(var/datum/quirk/q in roundstart_quirks)
|
||||
remove_quirk(q.type)
|
||||
else
|
||||
var/T = options[result]
|
||||
if(has_quirk(T))
|
||||
remove_quirk(T)
|
||||
else
|
||||
add_quirk(T,TRUE)
|
||||
if(href_list[VV_HK_MAKE_MONKEY])
|
||||
if(!check_rights(R_SPAWN))
|
||||
return
|
||||
if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform")
|
||||
return
|
||||
usr.client.holder.Topic("vv_override", list("monkeyone"=href_list[VV_HK_TARGET]))
|
||||
if(href_list[VV_HK_MAKE_CYBORG])
|
||||
if(!check_rights(R_SPAWN))
|
||||
return
|
||||
if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform")
|
||||
return
|
||||
usr.client.holder.Topic("vv_override", list("makerobot"=href_list[VV_HK_TARGET]))
|
||||
if(href_list[VV_HK_MAKE_ALIEN])
|
||||
if(!check_rights(R_SPAWN))
|
||||
return
|
||||
if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform")
|
||||
return
|
||||
usr.client.holder.Topic("vv_override", list("makealien"=href_list[VV_HK_TARGET]))
|
||||
if(href_list[VV_HK_MAKE_SLIME])
|
||||
if(!check_rights(R_SPAWN))
|
||||
return
|
||||
if(alert("Confirm mob type change?",,"Transform","Cancel") != "Transform")
|
||||
return
|
||||
usr.client.holder.Topic("vv_override", list("makeslime"=href_list[VV_HK_TARGET]))
|
||||
if(href_list[VV_HK_SET_SPECIES])
|
||||
if(!check_rights(R_SPAWN))
|
||||
return
|
||||
var/result = input(usr, "Please choose a new species","Species") as null|anything in GLOB.species_list
|
||||
if(result)
|
||||
var/newtype = GLOB.species_list[result]
|
||||
admin_ticket_log("[key_name_admin(usr)] has modified the bodyparts of [src] to [result]")
|
||||
set_species(newtype)
|
||||
if(href_list[VV_HK_PURRBATION])
|
||||
if(!check_rights(R_SPAWN))
|
||||
return
|
||||
if(!ishumanbasic(src))
|
||||
to_chat(usr, "This can only be done to the basic human species at the moment.")
|
||||
return
|
||||
var/success = purrbation_toggle(src)
|
||||
if(success)
|
||||
to_chat(usr, "Put [src] on purrbation.")
|
||||
log_admin("[key_name(usr)] has put [key_name(src)] on purrbation.")
|
||||
var/msg = "<span class='notice'>[key_name_admin(usr)] has put [key_name(src)] on purrbation.</span>"
|
||||
message_admins(msg)
|
||||
admin_ticket_log(src, msg)
|
||||
|
||||
else
|
||||
to_chat(usr, "Removed [src] from purrbation.")
|
||||
log_admin("[key_name(usr)] has removed [key_name(src)] from purrbation.")
|
||||
var/msg = "<span class='notice'>[key_name_admin(usr)] has removed [key_name(src)] from purrbation.</span>"
|
||||
message_admins(msg)
|
||||
admin_ticket_log(src, msg)
|
||||
|
||||
/mob/living/carbon/human/MouseDrop_T(mob/living/target, mob/living/user)
|
||||
if(pulling == target && grab_state >= GRAB_AGGRESSIVE && stat == CONSCIOUS)
|
||||
@@ -873,14 +960,24 @@
|
||||
return (ishuman(target) && !CHECK_MOBILITY(target, MOBILITY_STAND))
|
||||
|
||||
/mob/living/carbon/human/proc/fireman_carry(mob/living/carbon/target)
|
||||
if(can_be_firemanned(target))
|
||||
visible_message("<span class='notice'>[src] starts lifting [target] onto their back...</span>",
|
||||
"<span class='notice'>You start lifting [target] onto your back...</span>")
|
||||
if(do_after(src, 30, TRUE, target))
|
||||
var/carrydelay = 50 //if you have latex you are faster at grabbing
|
||||
var/skills_space = "" //cobby told me to do this
|
||||
if(HAS_TRAIT(src, TRAIT_QUICKER_CARRY))
|
||||
carrydelay = 30
|
||||
skills_space = "expertly"
|
||||
else if(HAS_TRAIT(src, TRAIT_QUICK_CARRY))
|
||||
carrydelay = 40
|
||||
skills_space = "quickly"
|
||||
if(can_be_firemanned(target) && !incapacitated(FALSE, TRUE))
|
||||
visible_message("<span class='notice'>[src] starts [skills_space] lifting [target] onto their back..</span>",
|
||||
//Joe Medic starts quickly/expertly lifting Grey Tider onto their back..
|
||||
"<span class='notice'>[carrydelay < 35 ? "Using your gloves' nanochips, you" : "You"] [skills_space] start to lift [target] onto your back[carrydelay == 40 ? ", while assisted by the nanochips in your gloves.." : "..."]</span>")
|
||||
//(Using your gloves' nanochips, you/You) ( /quickly/expertly) start to lift Grey Tider onto your back(, while assisted by the nanochips in your gloves../...)
|
||||
if(do_after(src, carrydelay, TRUE, target))
|
||||
//Second check to make sure they're still valid to be carried
|
||||
if(can_be_firemanned(target) && !incapacitated(FALSE, TRUE))
|
||||
target.set_resting(FALSE, TRUE)
|
||||
buckle_mob(target, TRUE, TRUE, 90, 1, 0)
|
||||
buckle_mob(target, TRUE, TRUE, 90, 1, 0, TRUE)
|
||||
return
|
||||
visible_message("<span class='warning'>[src] fails to fireman carry [target]!")
|
||||
else
|
||||
@@ -897,13 +994,13 @@
|
||||
if(target.incapacitated(FALSE, TRUE) || incapacitated(FALSE, TRUE))
|
||||
target.visible_message("<span class='warning'>[target] can't hang onto [src]!</span>")
|
||||
return
|
||||
buckle_mob(target, TRUE, TRUE, FALSE, 0, 2)
|
||||
buckle_mob(target, TRUE, TRUE, FALSE, 0, 2, FALSE)
|
||||
else
|
||||
visible_message("<span class='warning'>[target] fails to climb onto [src]!</span>")
|
||||
else
|
||||
to_chat(target, "<span class='warning'>You can't piggyback ride [src] right now!</span>")
|
||||
|
||||
/mob/living/carbon/human/buckle_mob(mob/living/target, force = FALSE, check_loc = TRUE, lying_buckle = FALSE, hands_needed = 0, target_hands_needed = 0)
|
||||
/mob/living/carbon/human/buckle_mob(mob/living/target, force = FALSE, check_loc = TRUE, lying_buckle = FALSE, hands_needed = 0, target_hands_needed = 0, fireman = FALSE)
|
||||
if(!force)//humans are only meant to be ridden through piggybacking and special cases
|
||||
return
|
||||
if(!is_type_in_typecache(target, can_ride_typecache))
|
||||
@@ -934,6 +1031,7 @@
|
||||
|
||||
stop_pulling()
|
||||
riding_datum.handle_vehicle_layer()
|
||||
riding_datum.fireman_carrying = fireman
|
||||
. = ..(target, force, check_loc)
|
||||
|
||||
/mob/living/carbon/human/proc/is_shove_knockdown_blocked() //If you want to add more things that block shove knockdown, extend this
|
||||
@@ -959,7 +1057,7 @@
|
||||
var/health_deficiency = ((100 + stambufferinfluence) - health + (getStaminaLoss()*0.75))//CIT CHANGE - reduces the impact of staminaloss and makes stamina buffer influence it
|
||||
if(health_deficiency >= 40)
|
||||
add_movespeed_modifier(MOVESPEED_ID_DAMAGE_SLOWDOWN, override = TRUE, multiplicative_slowdown = ((health_deficiency-39) / 75), blacklisted_movetypes = FLOATING|FLYING)
|
||||
add_movespeed_modifier(MOVESPEED_ID_DAMAGE_SLOWDOWN_FLYING, override = TRUE, multiplicative_slowdown = ((health_deficiency-39) / 25), movetypes = FLOATING)
|
||||
add_movespeed_modifier(MOVESPEED_ID_DAMAGE_SLOWDOWN_FLYING, override = TRUE, multiplicative_slowdown = ((health_deficiency-39) / 25), movetypes = FLYING, blacklisted_movetypes = FLOATING)
|
||||
else
|
||||
remove_movespeed_modifier(MOVESPEED_ID_DAMAGE_SLOWDOWN)
|
||||
remove_movespeed_modifier(MOVESPEED_ID_DAMAGE_SLOWDOWN_FLYING)
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
/mob/living/carbon/human/get_blocking_items()
|
||||
. = ..()
|
||||
if(wear_suit)
|
||||
. += wear_suit
|
||||
if(w_uniform)
|
||||
. += w_uniform
|
||||
if(wear_neck)
|
||||
. += wear_neck
|
||||
@@ -45,63 +45,19 @@
|
||||
if(spec_return)
|
||||
return spec_return
|
||||
|
||||
if(mind)
|
||||
if (mind.martial_art && mind.martial_art.dodge_chance)
|
||||
if(!lying && dna && !dna.check_mutation(HULK))
|
||||
if(prob(mind.martial_art.dodge_chance))
|
||||
var/static/dodgemessages = list("dodges under",0,-4,"dodges to the right of",-4,0,"dodges to the left of",4,0,"jumps over",0,4)
|
||||
var/pick = pick(1,4,7,10)
|
||||
var/oldx = pixel_x
|
||||
var/oldy = pixel_y
|
||||
animate(src,pixel_x = pixel_x + dodgemessages[pick+1],pixel_y = pixel_y + dodgemessages[pick+2],time=3)
|
||||
animate(src,pixel_x = oldx,pixel_y = oldy,time=2)
|
||||
visible_message("<span class='danger'>[src] [dodgemessages[pick]] the projectile!</span>", "<span class='userdanger'>You dodge the projectile!</span>")
|
||||
return BULLET_ACT_FORCE_PIERCE
|
||||
if(mind.martial_art && !incapacitated(FALSE, TRUE) && mind.martial_art.can_use(src) && mind.martial_art.deflection_chance) //Some martial arts users can deflect projectiles!
|
||||
if(prob(mind.martial_art.deflection_chance))
|
||||
if(!lying && dna && !dna.check_mutation(HULK)) //But only if they're not lying down, and hulks can't do it
|
||||
if(mind.martial_art.deflection_chance >= 100) //if they can NEVER be hit, lets clue sec in ;)
|
||||
visible_message("<span class='danger'>[src] deflects the projectile; [p_they()] can't be hit with ranged weapons!</span>", "<span class='userdanger'>You deflect the projectile!</span>")
|
||||
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)
|
||||
if(mind.martial_art.reroute_deflection)
|
||||
P.firer = src
|
||||
P.setAngle(rand(0, 360))//SHING
|
||||
return BULLET_ACT_FORCE_PIERCE
|
||||
|
||||
if(mind) //martial art stuff
|
||||
if(mind.martial_art && mind.martial_art.can_use(src)) //Some martial arts users can deflect projectiles!
|
||||
var/martial_art_result = mind.martial_art.on_projectile_hit(src, P, def_zone)
|
||||
if(!(martial_art_result == BULLET_ACT_HIT))
|
||||
return martial_art_result
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/human/check_reflect(def_zone)
|
||||
if(wear_suit?.IsReflect(def_zone))
|
||||
return TRUE
|
||||
return ..()
|
||||
|
||||
/mob/living/carbon/human/check_shields(atom/AM, damage, attack_text = "the attack", attack_type = MELEE_ATTACK, armour_penetration = 0)
|
||||
. = ..()
|
||||
if(.)
|
||||
return
|
||||
var/block_chance_modifier = round(damage / -3)
|
||||
if(wear_suit)
|
||||
var/final_block_chance = wear_suit.block_chance - (CLAMP((armour_penetration-wear_suit.armour_penetration)/2,0,100)) + block_chance_modifier
|
||||
if(wear_suit.hit_reaction(src, AM, attack_text, final_block_chance, damage, attack_type))
|
||||
return TRUE
|
||||
if(w_uniform)
|
||||
var/final_block_chance = w_uniform.block_chance - (CLAMP((armour_penetration-w_uniform.armour_penetration)/2,0,100)) + block_chance_modifier
|
||||
if(w_uniform.hit_reaction(src, AM, attack_text, final_block_chance, damage, attack_type))
|
||||
return TRUE
|
||||
if(wear_neck)
|
||||
var/final_block_chance = wear_neck.block_chance - (CLAMP((armour_penetration-wear_neck.armour_penetration)/2,0,100)) + block_chance_modifier
|
||||
if(wear_neck.hit_reaction(src, AM, attack_text, final_block_chance, damage, attack_type))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/mob/living/carbon/human/can_embed(obj/item/I)
|
||||
if(I.get_sharpness() || is_pointed(I) || is_type_in_typecache(I, GLOB.can_embed_types))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/mob/living/carbon/human/proc/check_block()
|
||||
/mob/living/carbon/human/proc/check_martial_melee_block()
|
||||
if(mind)
|
||||
if(mind.martial_art && prob(mind.martial_art.block_chance) && mind.martial_art.can_use(src) && in_throw_mode && !incapacitated(FALSE, TRUE))
|
||||
return TRUE
|
||||
@@ -141,7 +97,6 @@
|
||||
// the attacked_by code varies among species
|
||||
return dna.species.spec_attacked_by(I, user, affecting, a_intent, src)
|
||||
|
||||
|
||||
/mob/living/carbon/human/attack_hulk(mob/living/carbon/human/user, does_attack_animation = FALSE)
|
||||
if(user.a_intent == INTENT_HARM)
|
||||
. = ..(user, TRUE)
|
||||
@@ -397,8 +352,8 @@
|
||||
|
||||
|
||||
//Added a safety check in case you want to shock a human mob directly through electrocute_act.
|
||||
/mob/living/carbon/human/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = 0, override = 0, tesla_shock = 0, illusion = 0, stun = TRUE)
|
||||
if(tesla_shock)
|
||||
/mob/living/carbon/human/electrocute_act(shock_damage, source, siemens_coeff = 1, flags = NONE)
|
||||
if(flags & SHOCK_TESLA)
|
||||
var/total_coeff = 1
|
||||
if(gloves)
|
||||
var/obj/item/clothing/gloves/G = gloves
|
||||
@@ -413,20 +368,20 @@
|
||||
siemens_coeff = total_coeff
|
||||
if(flags_1 & TESLA_IGNORE_1)
|
||||
siemens_coeff = 0
|
||||
else if(!safety)
|
||||
else if(!(flags & SHOCK_NOGLOVES))
|
||||
var/gloves_siemens_coeff = 1
|
||||
if(gloves)
|
||||
var/obj/item/clothing/gloves/G = gloves
|
||||
gloves_siemens_coeff = G.siemens_coefficient
|
||||
siemens_coeff = gloves_siemens_coeff
|
||||
if(undergoing_cardiac_arrest() && !illusion)
|
||||
if(undergoing_cardiac_arrest() && !(flags & SHOCK_ILLUSION))
|
||||
if(shock_damage * siemens_coeff >= 1 && prob(25))
|
||||
var/obj/item/organ/heart/heart = getorganslot(ORGAN_SLOT_HEART)
|
||||
heart.beating = TRUE
|
||||
if(stat == CONSCIOUS)
|
||||
to_chat(src, "<span class='notice'>You feel your heart beating again!</span>")
|
||||
siemens_coeff *= physiology.siemens_coeff
|
||||
. = ..(shock_damage,source,siemens_coeff,safety,override,tesla_shock, illusion, stun)
|
||||
. = ..()
|
||||
if(.)
|
||||
electrocution_animation(40)
|
||||
|
||||
|
||||
@@ -6,6 +6,12 @@
|
||||
can_buckle = TRUE
|
||||
buckle_lying = FALSE
|
||||
mob_biotypes = MOB_ORGANIC|MOB_HUMANOID
|
||||
/// Enable stamina combat
|
||||
combat_flags = COMBAT_FLAGS_DEFAULT
|
||||
status_flags = CANSTUN|CANKNOCKDOWN|CANUNCONSCIOUS|CANPUSH|CANSTAGGER
|
||||
|
||||
blocks_emissive = EMISSIVE_BLOCK_UNIQUE
|
||||
|
||||
//Hair colour and style
|
||||
var/hair_color = "000"
|
||||
var/hair_style = "Bald"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/mob/living/carbon/human/resist_a_rest(automatic = FALSE, ignoretimer = FALSE)
|
||||
if(!resting || stat || attemptingstandup)
|
||||
if(!resting || stat || (combat_flags & COMBAT_FLAG_RESISTING_REST))
|
||||
return FALSE
|
||||
if(ignoretimer)
|
||||
set_resting(FALSE, FALSE)
|
||||
@@ -13,10 +13,10 @@
|
||||
return FALSE
|
||||
else
|
||||
var/totaldelay = 3 //A little bit less than half of a second as a baseline for getting up from a rest
|
||||
if(getStaminaLoss() >= STAMINA_SOFTCRIT)
|
||||
if(IS_STAMCRIT(src))
|
||||
to_chat(src, "<span class='warning'>You're too exhausted to get up!")
|
||||
return FALSE
|
||||
attemptingstandup = TRUE
|
||||
combat_flags |= COMBAT_FLAG_RESISTING_REST
|
||||
var/health_deficiency = max((maxHealth - (health - getStaminaLoss()))*0.5, 0)
|
||||
if(!has_gravity())
|
||||
health_deficiency = health_deficiency*0.2
|
||||
@@ -37,10 +37,11 @@
|
||||
visible_message("<span class='notice'>[standupwarning]</span>", usernotice, vision_distance = 5)
|
||||
if(do_after(src, totaldelay, target = src, required_mobility_flags = MOBILITY_RESIST))
|
||||
set_resting(FALSE, TRUE)
|
||||
attemptingstandup = FALSE
|
||||
|
||||
combat_flags &= ~COMBAT_FLAG_RESISTING_REST
|
||||
return TRUE
|
||||
else
|
||||
attemptingstandup = FALSE
|
||||
combat_flags &= ~COMBAT_FLAG_RESISTING_REST
|
||||
if(resting) //we didn't shove ourselves up or something
|
||||
visible_message("<span class='notice'>[src] falls right back down.</span>", "<span class='notice'>You fall right back down.</span>")
|
||||
if(has_gravity())
|
||||
|
||||
@@ -9,6 +9,13 @@
|
||||
|
||||
/mob/living/carbon/human/movement_delay()
|
||||
. = ..()
|
||||
if(CHECK_MOBILITY(src, MOBILITY_STAND) && m_intent == MOVE_INTENT_RUN && (combat_flags & COMBAT_FLAG_SPRINT_ACTIVE))
|
||||
var/static/datum/config_entry/number/movedelay/sprint_speed_increase/SSI
|
||||
if(!SSI)
|
||||
SSI = CONFIG_GET_ENTRY(number/movedelay/sprint_speed_increase)
|
||||
. -= SSI.config_entry_value
|
||||
if(wrongdirmovedelay)
|
||||
. += 1
|
||||
if (m_intent == MOVE_INTENT_WALK && HAS_TRAIT(src, TRAIT_SPEEDY_STEP))
|
||||
. -= 1.5
|
||||
|
||||
@@ -42,10 +49,18 @@
|
||||
return ((shoes && shoes.negates_gravity()) || (dna.species.negates_gravity(src)))
|
||||
|
||||
/mob/living/carbon/human/Move(NewLoc, direct)
|
||||
var/oldpseudoheight = pseudo_z_axis
|
||||
. = ..()
|
||||
for(var/datum/mutation/human/HM in dna.mutations)
|
||||
HM.on_move(src, NewLoc)
|
||||
|
||||
HM.on_move(NewLoc)
|
||||
if(. && (combat_flags & COMBAT_FLAG_SPRINT_ACTIVE) && !(movement_type & FLYING) && CHECK_ALL_MOBILITY(src, MOBILITY_MOVE|MOBILITY_STAND) && m_intent == MOVE_INTENT_RUN && has_gravity(loc) && !pulledby)
|
||||
if(!HAS_TRAIT(src, TRAIT_FREESPRINT))
|
||||
doSprintLossTiles(1)
|
||||
if((oldpseudoheight - pseudo_z_axis) >= 8)
|
||||
to_chat(src, "<span class='warning'>You trip off of the elevated surface!</span>")
|
||||
for(var/obj/item/I in held_items)
|
||||
accident(I)
|
||||
DefaultCombatKnockdown(80)
|
||||
if(shoes)
|
||||
if(!lying && !buckled)
|
||||
if(loc == NewLoc)
|
||||
|
||||
@@ -147,7 +147,7 @@
|
||||
|
||||
/mob/living/carbon/human/equipped_speed_mods()
|
||||
. = ..()
|
||||
for(var/sloties in get_all_slots())
|
||||
for(var/sloties in get_all_slots() - list(l_store, r_store, s_store))
|
||||
var/obj/item/thing = sloties
|
||||
. += thing?.slowdown
|
||||
|
||||
|
||||
@@ -316,12 +316,15 @@
|
||||
BP.receive_damage(I.w_class*I.embedding.embedded_fall_pain_multiplier)
|
||||
BP.embedded_objects -= I
|
||||
I.forceMove(drop_location())
|
||||
I.unembedded()
|
||||
visible_message("<span class='danger'>[I] falls out of [name]'s [BP.name]!</span>","<span class='userdanger'>[I] falls out of your [BP.name]!</span>")
|
||||
if(!has_embedded_objects())
|
||||
clear_alert("embeddedobject")
|
||||
SEND_SIGNAL(src, COMSIG_CLEAR_MOOD_EVENT, "embedded")
|
||||
|
||||
/mob/living/carbon/human/proc/handle_active_genes()
|
||||
if(HAS_TRAIT(src, TRAIT_MUTATION_STASIS))
|
||||
return
|
||||
for(var/datum/mutation/human/HM in dna.mutations)
|
||||
HM.on_life(src)
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
/mob/living/carbon/human/GetVoice()
|
||||
if(istype(wear_mask, /obj/item/clothing/mask/chameleon))
|
||||
var/obj/item/clothing/mask/chameleon/V = wear_mask
|
||||
if(V.vchange && wear_id)
|
||||
if(V.voice_change && wear_id)
|
||||
var/obj/item/card/id/idcard = wear_id.GetID()
|
||||
if(istype(idcard))
|
||||
return idcard.registered_name
|
||||
@@ -21,6 +21,12 @@
|
||||
return real_name
|
||||
else
|
||||
return real_name
|
||||
if(istype(wear_mask, /obj/item/clothing/mask/infiltrator))
|
||||
var/obj/item/clothing/mask/infiltrator/V = wear_mask
|
||||
if(V.voice_unknown)
|
||||
return ("Unknown")
|
||||
else
|
||||
return real_name
|
||||
if(mind)
|
||||
var/datum/antagonist/changeling/changeling = mind.has_antag_datum(/datum/antagonist/changeling)
|
||||
if(changeling && changeling.mimicing )
|
||||
|
||||
@@ -53,8 +53,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
var/blacklisted = 0 //Flag to exclude from green slime core species.
|
||||
var/dangerous_existence //A flag for transformation spells that tells them "hey if you turn a person into one of these without preperation, they'll probably die!"
|
||||
var/say_mod = "says" // affects the speech message
|
||||
var/list/default_features = list() // Default mutant bodyparts for this species. Don't forget to set one for every mutant bodypart you allow this species to have.
|
||||
var/list/mutant_bodyparts = list() // Visible CURRENT bodyparts that are unique to a species. DO NOT USE THIS AS A LIST OF ALL POSSIBLE BODYPARTS AS IT WILL FUCK SHIT UP! Changes to this list for non-species specific bodyparts (ie cat ears and tails) should be assigned at organ level if possible. Layer hiding is handled by handle_mutant_bodyparts() below.
|
||||
var/list/mutant_bodyparts = list() // Visible CURRENT bodyparts that are unique to a species. Changes to this list for non-species specific bodyparts (ie cat ears and tails) should be assigned at organ level if possible. Layer hiding is handled by handle_mutant_bodyparts() below.
|
||||
var/list/mutant_organs = list() //Internal organs that are unique to this race.
|
||||
var/speedmod = 0 // this affects the race's speed. positive numbers make it move slower, negative numbers make it move faster
|
||||
var/armor = 0 // overall defense for the race... or less defense, if it's negative.
|
||||
@@ -63,12 +62,13 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
var/coldmod = 1 // multiplier for cold damage
|
||||
var/heatmod = 1 // multiplier for heat damage
|
||||
var/stunmod = 1 // multiplier for stun duration
|
||||
var/punchdamagelow = 0 //lowest possible punch damage
|
||||
var/punchdamagehigh = 9 //highest possible punch damage
|
||||
var/punchstunthreshold = 9//damage at which punches from this race will stun //yes it should be to the attacked race but it's not useful that way even if it's logical
|
||||
var/punchdamagelow = 1 //lowest possible punch damage. if this is set to 0, punches will always miss
|
||||
var/punchdamagehigh = 10 //highest possible punch damage
|
||||
var/punchstunthreshold = 10//damage at which punches from this race will stun //yes it should be to the attacked race but it's not useful that way even if it's logical
|
||||
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/inert_mutation = DWARFISM
|
||||
var/list/special_step_sounds //Sounds to override barefeet walkng
|
||||
var/grab_sound //Special sound for grabbing
|
||||
var/datum/outfit/outfit_important_for_life // A path to an outfit that is important for species life e.g. plasmaman outfit
|
||||
@@ -105,7 +105,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
var/fixed_mut_color3 = ""
|
||||
var/whitelisted = 0 //Is this species restricted to certain players?
|
||||
var/whitelist = list() //List the ckeys that can use this species, if it's whitelisted.: list("John Doe", "poopface666", "SeeALiggerPullTheTrigger") Spaces & capitalization can be included or ignored entirely for each key as it checks for both.
|
||||
var/should_draw_citadel = FALSE
|
||||
var/icon_limbs //Overrides the icon used for the limbs of this species. Mainly for downstream, and also because hardcoded icons disgust me. Implemented and maintained as a favor in return for a downstream's implementation of synths.
|
||||
|
||||
///////////
|
||||
// PROCS //
|
||||
@@ -290,7 +290,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
C.hud_used.update_locked_slots()
|
||||
|
||||
// this needs to be FIRST because qdel calls update_body which checks if we have DIGITIGRADE legs or not and if not then removes DIGITIGRADE from species_traits
|
||||
if(("legs" in C.dna.species.mutant_bodyparts) && (C.dna.features["legs"] == "Digitigrade" || C.dna.features["legs"] == "Avian"))
|
||||
if(C.dna.species.mutant_bodyparts["legs"] && (C.dna.features["legs"] == "Digitigrade" || C.dna.features["legs"] == "Avian"))
|
||||
species_traits |= DIGITIGRADE
|
||||
if(DIGITIGRADE in species_traits)
|
||||
C.Digitigrade_Leg_Swap(FALSE)
|
||||
@@ -328,7 +328,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
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.
|
||||
if("meat_type" in default_features) //I can't believe it's come to the meat
|
||||
if(mutant_bodyparts["meat_type"]) //I can't believe it's come to the meat
|
||||
H.type_of_meat = GLOB.meat_types[H.dna.features["meat_type"]]
|
||||
|
||||
C.add_movespeed_modifier(MOVESPEED_ID_SPECIES, TRUE, 100, override=TRUE, multiplicative_slowdown=speedmod, movetypes=(~FLYING))
|
||||
@@ -351,11 +351,19 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
|
||||
C.remove_movespeed_modifier(MOVESPEED_ID_SPECIES)
|
||||
|
||||
if("meat_type" in default_features)
|
||||
if(mutant_bodyparts["meat_type"])
|
||||
C.type_of_meat = GLOB.meat_types[C.dna.features["meat_type"]]
|
||||
else
|
||||
C.type_of_meat = initial(meat)
|
||||
|
||||
//If their inert mutation is not the same, swap it out
|
||||
if((inert_mutation != new_species.inert_mutation) && LAZYLEN(C.dna.mutation_index) && (inert_mutation in C.dna.mutation_index))
|
||||
C.dna.remove_mutation(inert_mutation)
|
||||
//keep it at the right spot, so we can't have people taking shortcuts
|
||||
var/location = C.dna.mutation_index.Find(inert_mutation)
|
||||
C.dna.mutation_index[location] = new_species.inert_mutation
|
||||
C.dna.mutation_index[new_species.inert_mutation] = create_sequence(new_species.inert_mutation)
|
||||
|
||||
SEND_SIGNAL(C, COMSIG_SPECIES_LOSS, src)
|
||||
|
||||
/datum/species/proc/handle_hair(mob/living/carbon/human/H, forced_colour)
|
||||
@@ -388,7 +396,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
if(I.flags_inv & HIDEFACIALHAIR)
|
||||
facialhair_hidden = TRUE
|
||||
|
||||
if(H.wear_mask)
|
||||
if(H.wear_mask && istype(H.wear_mask))
|
||||
var/obj/item/clothing/mask/M = H.wear_mask
|
||||
dynamic_fhair_suffix = M.dynamic_fhair_suffix //mask > head in terms of facial hair
|
||||
if(M.flags_inv & HIDEFACIALHAIR)
|
||||
@@ -442,7 +450,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
if(I.flags_inv & HIDEHAIR)
|
||||
hair_hidden = TRUE
|
||||
|
||||
if(H.wear_mask)
|
||||
if(H.wear_mask && istype(H.wear_mask))
|
||||
var/obj/item/clothing/mask/M = H.wear_mask
|
||||
if(!dynamic_hair_suffix) //head > mask in terms of head hair
|
||||
dynamic_hair_suffix = M.dynamic_hair_suffix
|
||||
@@ -541,48 +549,45 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
//Underwear, Undershirts & Socks
|
||||
if(!(NO_UNDERWEAR in species_traits))
|
||||
|
||||
if(H.socks && H.get_num_legs(FALSE) >= 2)
|
||||
if(H.hidden_socks)
|
||||
H.socks = "Nude"
|
||||
else
|
||||
if(H.socks && !H.hidden_socks && H.get_num_legs(FALSE) >= 2)
|
||||
if(H.saved_socks)
|
||||
H.socks = H.saved_socks
|
||||
var/datum/sprite_accessory/underwear/socks/S = GLOB.socks_list[H.socks]
|
||||
if(S)
|
||||
var/digilegs = ((DIGITIGRADE in species_traits) && S.has_digitigrade) ? "_d" : ""
|
||||
var/mutable_appearance/MA = mutable_appearance(S.icon, "[S.icon_state][digilegs]", -BODY_LAYER)
|
||||
if(S.has_color)
|
||||
MA.color = "#[H.socks_color]"
|
||||
standing += MA
|
||||
H.saved_socks = ""
|
||||
var/datum/sprite_accessory/underwear/socks/S = GLOB.socks_list[H.socks]
|
||||
if(S)
|
||||
var/digilegs = ((DIGITIGRADE in species_traits) && S.has_digitigrade) ? "_d" : ""
|
||||
var/mutable_appearance/MA = mutable_appearance(S.icon, "[S.icon_state][digilegs]", -BODY_LAYER)
|
||||
if(S.has_color)
|
||||
MA.color = "#[H.socks_color]"
|
||||
standing += MA
|
||||
|
||||
if(H.underwear)
|
||||
if(H.hidden_underwear)
|
||||
H.underwear = "Nude"
|
||||
else
|
||||
if(H.underwear && !H.hidden_underwear)
|
||||
if(H.saved_underwear)
|
||||
H.underwear = H.saved_underwear
|
||||
var/datum/sprite_accessory/underwear/bottom/B = GLOB.underwear_list[H.underwear]
|
||||
if(B)
|
||||
var/digilegs = ((DIGITIGRADE in species_traits) && B.has_digitigrade) ? "_d" : ""
|
||||
var/mutable_appearance/MA = mutable_appearance(B.icon, "[B.icon_state][digilegs]", -BODY_LAYER)
|
||||
if(B.has_color)
|
||||
MA.color = "#[H.undie_color]"
|
||||
standing += MA
|
||||
H.saved_underwear = ""
|
||||
var/datum/sprite_accessory/underwear/bottom/B = GLOB.underwear_list[H.underwear]
|
||||
if(B)
|
||||
var/digilegs = ((DIGITIGRADE in species_traits) && B.has_digitigrade) ? "_d" : ""
|
||||
var/mutable_appearance/MA = mutable_appearance(B.icon, "[B.icon_state][digilegs]", -BODY_LAYER)
|
||||
if(B.has_color)
|
||||
MA.color = "#[H.undie_color]"
|
||||
standing += MA
|
||||
|
||||
if(H.undershirt)
|
||||
if(H.hidden_undershirt)
|
||||
H.undershirt = "Nude"
|
||||
else
|
||||
if(H.undershirt && !H.hidden_undershirt)
|
||||
if(H.saved_undershirt)
|
||||
H.undershirt = H.saved_undershirt
|
||||
var/datum/sprite_accessory/underwear/top/T = GLOB.undershirt_list[H.undershirt]
|
||||
if(T)
|
||||
var/state = "[T.icon_state][((DIGITIGRADE in species_traits) && T.has_digitigrade) ? "_d" : ""]"
|
||||
var/mutable_appearance/MA
|
||||
if(H.dna.species.sexes && H.gender == FEMALE)
|
||||
MA = wear_female_version(state, T.icon, BODY_LAYER)
|
||||
else
|
||||
MA = mutable_appearance(T.icon, state, -BODY_LAYER)
|
||||
if(T.has_color)
|
||||
MA.color = "#[H.shirt_color]"
|
||||
standing += MA
|
||||
H.saved_undershirt = ""
|
||||
var/datum/sprite_accessory/underwear/top/T = GLOB.undershirt_list[H.undershirt]
|
||||
if(T)
|
||||
var/state = "[T.icon_state][((DIGITIGRADE in species_traits) && T.has_digitigrade) ? "_d" : ""]"
|
||||
var/mutable_appearance/MA
|
||||
if(H.dna.species.sexes && H.dna.features["body_model"] == FEMALE)
|
||||
MA = wear_female_version(state, T.icon, BODY_LAYER)
|
||||
else
|
||||
MA = mutable_appearance(T.icon, state, -BODY_LAYER)
|
||||
if(T.has_color)
|
||||
MA.color = "#[H.shirt_color]"
|
||||
standing += MA
|
||||
|
||||
if(standing.len)
|
||||
H.overlays_standing[BODY_LAYER] = standing
|
||||
@@ -608,99 +613,99 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
var/obj/item/bodypart/head/HD = H.get_bodypart(BODY_ZONE_HEAD)
|
||||
var/tauric = H.dna.features["taur"] && H.dna.features["taur"] != "None"
|
||||
|
||||
if("tail_lizard" in mutant_bodyparts)
|
||||
if(mutant_bodyparts["tail_lizard"])
|
||||
if((H.wear_suit && (H.wear_suit.flags_inv & HIDETAUR)) || tauric)
|
||||
bodyparts_to_add -= "tail_lizard"
|
||||
|
||||
if("waggingtail_lizard" in mutant_bodyparts)
|
||||
if(mutant_bodyparts["waggingtail_lizard"])
|
||||
if((H.wear_suit && (H.wear_suit.flags_inv & HIDETAUR)) || tauric)
|
||||
bodyparts_to_add -= "waggingtail_lizard"
|
||||
else if ("tail_lizard" in mutant_bodyparts)
|
||||
else if (mutant_bodyparts["tail_lizard"])
|
||||
bodyparts_to_add -= "waggingtail_lizard"
|
||||
|
||||
if("tail_human" in mutant_bodyparts)
|
||||
if(mutant_bodyparts["tail_human"])
|
||||
if((H.wear_suit && (H.wear_suit.flags_inv & HIDETAUR)) || tauric)
|
||||
bodyparts_to_add -= "tail_human"
|
||||
|
||||
if("waggingtail_human" in mutant_bodyparts)
|
||||
if(mutant_bodyparts["waggingtail_human"])
|
||||
if((H.wear_suit && (H.wear_suit.flags_inv & HIDETAUR)) || tauric)
|
||||
bodyparts_to_add -= "waggingtail_human"
|
||||
else if ("tail_human" in mutant_bodyparts)
|
||||
else if (mutant_bodyparts["tail_human"])
|
||||
bodyparts_to_add -= "waggingtail_human"
|
||||
|
||||
if("spines" in mutant_bodyparts)
|
||||
if(mutant_bodyparts["spines"])
|
||||
if(!H.dna.features["spines"] || H.dna.features["spines"] == "None" || H.wear_suit && (H.wear_suit.flags_inv & HIDETAUR))
|
||||
bodyparts_to_add -= "spines"
|
||||
|
||||
if("waggingspines" in mutant_bodyparts)
|
||||
if(mutant_bodyparts["waggingspines"])
|
||||
if(!H.dna.features["spines"] || H.dna.features["spines"] == "None" || H.wear_suit && (H.wear_suit.flags_inv & HIDETAUR))
|
||||
bodyparts_to_add -= "waggingspines"
|
||||
else if ("tail" in mutant_bodyparts)
|
||||
else if (mutant_bodyparts["tail"])
|
||||
bodyparts_to_add -= "waggingspines"
|
||||
|
||||
if("snout" in mutant_bodyparts) //Take a closer look at that snout!
|
||||
if(mutant_bodyparts["snout"]) //Take a closer look at that snout!
|
||||
if((H.wear_mask && (H.wear_mask.flags_inv & HIDESNOUT)) || (H.head && (H.head.flags_inv & HIDESNOUT)) || !HD || HD.status == BODYPART_ROBOTIC)
|
||||
bodyparts_to_add -= "snout"
|
||||
|
||||
if("frills" in mutant_bodyparts)
|
||||
if(mutant_bodyparts["frills"])
|
||||
if(!H.dna.features["frills"] || H.dna.features["frills"] == "None" || H.head && (H.head.flags_inv & HIDEEARS) || !HD || HD.status == BODYPART_ROBOTIC)
|
||||
bodyparts_to_add -= "frills"
|
||||
|
||||
if("horns" in mutant_bodyparts)
|
||||
if(mutant_bodyparts["horns"])
|
||||
if(!H.dna.features["horns"] || H.dna.features["horns"] == "None" || H.head && (H.head.flags_inv & HIDEHAIR) || (H.wear_mask && (H.wear_mask.flags_inv & HIDEHAIR)) || !HD || HD.status == BODYPART_ROBOTIC)
|
||||
bodyparts_to_add -= "horns"
|
||||
|
||||
if("ears" in mutant_bodyparts)
|
||||
if(mutant_bodyparts["ears"])
|
||||
if(!H.dna.features["ears"] || H.dna.features["ears"] == "None" || H.head && (H.head.flags_inv & HIDEEARS) || (H.wear_mask && (H.wear_mask.flags_inv & HIDEEARS)) || !HD || HD.status == BODYPART_ROBOTIC)
|
||||
bodyparts_to_add -= "ears"
|
||||
|
||||
if("wings" in mutant_bodyparts)
|
||||
if(mutant_bodyparts["wings"])
|
||||
if(!H.dna.features["wings"] || H.dna.features["wings"] == "None" || (H.wear_suit && (H.wear_suit.flags_inv & HIDEJUMPSUIT) && (!H.wear_suit.species_exception || !is_type_in_list(src, H.wear_suit.species_exception))))
|
||||
bodyparts_to_add -= "wings"
|
||||
|
||||
if("wings_open" in mutant_bodyparts)
|
||||
if(mutant_bodyparts["wings_open"])
|
||||
if(H.wear_suit && (H.wear_suit.flags_inv & HIDEJUMPSUIT) && (!H.wear_suit.species_exception || !is_type_in_list(src, H.wear_suit.species_exception)))
|
||||
bodyparts_to_add -= "wings_open"
|
||||
else if ("wings" in mutant_bodyparts)
|
||||
else if (mutant_bodyparts["wings"])
|
||||
bodyparts_to_add -= "wings_open"
|
||||
|
||||
if("insect_fluff" in mutant_bodyparts)
|
||||
if(mutant_bodyparts["insect_fluff"])
|
||||
if(!H.dna.features["insect_fluff"] || H.dna.features["insect_fluff"] == "None" || H.wear_suit && (H.wear_suit.flags_inv & HIDEJUMPSUIT))
|
||||
bodyparts_to_add -= "insect_fluff"
|
||||
|
||||
//CITADEL EDIT
|
||||
//Race specific bodyparts:
|
||||
//Xenos
|
||||
if("xenodorsal" in mutant_bodyparts)
|
||||
if(mutant_bodyparts["xenodorsal"])
|
||||
if(!H.dna.features["xenodorsal"] || H.dna.features["xenodorsal"] == "None" || (H.wear_suit && (H.wear_suit.flags_inv & HIDEJUMPSUIT)))
|
||||
bodyparts_to_add -= "xenodorsal"
|
||||
if("xenohead" in mutant_bodyparts)//This is an overlay for different castes using different head crests
|
||||
if(mutant_bodyparts["xenohead"])//This is an overlay for different castes using different head crests
|
||||
if(!H.dna.features["xenohead"] || H.dna.features["xenohead"] == "None" || H.head && (H.head.flags_inv & HIDEHAIR) || (H.wear_mask && (H.wear_mask.flags_inv & HIDEHAIR)) || !HD || HD.status == BODYPART_ROBOTIC)
|
||||
bodyparts_to_add -= "xenohead"
|
||||
if("xenotail" in mutant_bodyparts)
|
||||
if(mutant_bodyparts["xenotail"])
|
||||
if(!H.dna.features["xenotail"] || H.dna.features["xenotail"] == "None" || H.wear_suit && (H.wear_suit.flags_inv & HIDEJUMPSUIT))
|
||||
bodyparts_to_add -= "xenotail"
|
||||
|
||||
//Other Races
|
||||
if("mam_tail" in mutant_bodyparts)
|
||||
if(mutant_bodyparts["mam_tail"])
|
||||
if((H.wear_suit && (H.wear_suit.flags_inv & HIDETAUR)) || tauric)
|
||||
bodyparts_to_add -= "mam_tail"
|
||||
|
||||
if("mam_waggingtail" in mutant_bodyparts)
|
||||
if(mutant_bodyparts["mam_waggingtail"])
|
||||
if((H.wear_suit && (H.wear_suit.flags_inv & HIDETAUR)) || tauric)
|
||||
bodyparts_to_add -= "mam_waggingtail"
|
||||
else if ("mam_tail" in mutant_bodyparts)
|
||||
else if (mutant_bodyparts["mam_tail"])
|
||||
bodyparts_to_add -= "mam_waggingtail"
|
||||
|
||||
if("mam_ears" in mutant_bodyparts)
|
||||
if(mutant_bodyparts["mam_ears"])
|
||||
if(!H.dna.features["mam_ears"] || H.dna.features["mam_ears"] == "None" || H.head && (H.head.flags_inv & HIDEEARS) || (H.wear_mask && (H.wear_mask.flags_inv & HIDEEARS)) || !HD || HD.status == BODYPART_ROBOTIC)
|
||||
bodyparts_to_add -= "mam_ears"
|
||||
|
||||
if("mam_snouts" in mutant_bodyparts) //Take a closer look at that snout!
|
||||
if(mutant_bodyparts["mam_snouts"]) //Take a closer look at that snout!
|
||||
if((H.wear_mask && (H.wear_mask.flags_inv & HIDESNOUT)) || (H.head && (H.head.flags_inv & HIDESNOUT)) || !HD || HD.status == BODYPART_ROBOTIC)
|
||||
bodyparts_to_add -= "mam_snouts"
|
||||
|
||||
if("taur" in mutant_bodyparts)
|
||||
if(mutant_bodyparts["taur"])
|
||||
if(!tauric || (H.wear_suit && (H.wear_suit.flags_inv & HIDETAUR)))
|
||||
bodyparts_to_add -= "taur"
|
||||
|
||||
@@ -737,7 +742,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
if(!bodyparts_to_add)
|
||||
return
|
||||
|
||||
var/g = (H.gender == FEMALE) ? "f" : "m"
|
||||
var/g = (H.dna.features["body_model"] == FEMALE) ? "f" : "m"
|
||||
|
||||
for(var/layer in relevent_layers)
|
||||
var/layertext = mutant_bodyparts_layertext(layer)
|
||||
@@ -816,9 +821,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
//A little rename so we don't have to use tail_lizard or tail_human when naming the sprites.
|
||||
if(bodypart == "tail_lizard" || bodypart == "tail_human" || bodypart == "mam_tail" || bodypart == "xenotail")
|
||||
bodypart = "tail"
|
||||
else if(bodypart == "waggingtail_lizard")
|
||||
bodypart = "waggingtail"
|
||||
if(bodypart == "mam_waggingtail" || bodypart == "waggingtail_human")
|
||||
if(bodypart == "mam_waggingtail" || bodypart == "waggingtail_human" || bodypart == "waggingtail_lizard")
|
||||
bodypart = "tailwag"
|
||||
if(bodypart == "mam_ears" || bodypart == "ears")
|
||||
bodypart = "ears"
|
||||
@@ -890,7 +893,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
accessory_overlay.icon_state = "m_ears_none_[layertext]"
|
||||
if(bodypart == "tail")
|
||||
accessory_overlay.icon_state = "m_tail_husk_[layertext]"
|
||||
if(MATRIXED)
|
||||
if(S.color_src == MATRIXED)
|
||||
var/list/husklist = list()
|
||||
husklist += ReadRGB("#a3a3a3")
|
||||
husklist += ReadRGB("#a3a3a3")
|
||||
@@ -1396,7 +1399,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
if(radiation > RAD_MOB_MUTATE)
|
||||
if(prob(1))
|
||||
to_chat(H, "<span class='danger'>You mutate!</span>")
|
||||
H.randmutb()
|
||||
H.easy_randmut(NEGATIVE+MINOR_NEGATIVE)
|
||||
H.emote("gasp")
|
||||
H.domutcheck()
|
||||
|
||||
@@ -1434,7 +1437,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
to_chat(user, "<span class='notice'>You do not breathe, so you cannot perform CPR.</span>")
|
||||
|
||||
/datum/species/proc/grab(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style)
|
||||
if(target.check_block())
|
||||
if(target.check_martial_melee_block())
|
||||
target.visible_message("<span class='warning'>[target] blocks [user]'s grab attempt!</span>")
|
||||
return 0
|
||||
if(attacker_style && attacker_style.grab_act(user,target))
|
||||
@@ -1443,57 +1446,70 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
target.grabbedby(user)
|
||||
return 1
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/datum/species/proc/harm(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style)
|
||||
if(!attacker_style && HAS_TRAIT(user, TRAIT_PACIFISM))
|
||||
to_chat(user, "<span class='warning'>You don't want to harm [target]!</span>")
|
||||
return FALSE
|
||||
if(user.getStaminaLoss() >= STAMINA_SOFTCRIT) //CITADEL CHANGE - makes it impossible to punch while in stamina softcrit
|
||||
if(IS_STAMCRIT(user)) //CITADEL CHANGE - makes it impossible to punch while in stamina softcrit
|
||||
to_chat(user, "<span class='warning'>You're too exhausted.</span>") //CITADEL CHANGE - ditto
|
||||
return FALSE //CITADEL CHANGE - ditto
|
||||
if(target.check_block())
|
||||
if(target.check_martial_melee_block())
|
||||
target.visible_message("<span class='warning'>[target] blocks [user]'s attack!</span>")
|
||||
return FALSE
|
||||
|
||||
if(HAS_TRAIT(user, TRAIT_PUGILIST))//CITADEL CHANGE - makes punching cause staminaloss but funny martial artist types get a discount
|
||||
user.adjustStaminaLossBuffered(1.5)
|
||||
else
|
||||
user.adjustStaminaLossBuffered(3.5)
|
||||
|
||||
if(attacker_style && attacker_style.harm_act(user,target))
|
||||
return TRUE
|
||||
else
|
||||
|
||||
var/atk_verb = user.dna.species.attack_verb
|
||||
if(target.lying)
|
||||
atk_verb = "kick"
|
||||
if(!(target.mobility_flags & MOBILITY_STAND))
|
||||
atk_verb = ATTACK_EFFECT_KICK
|
||||
|
||||
switch(atk_verb)
|
||||
if("kick")
|
||||
if(ATTACK_EFFECT_KICK)
|
||||
user.do_attack_animation(target, ATTACK_EFFECT_KICK)
|
||||
if("slash")
|
||||
if(ATTACK_EFFECT_CLAW)
|
||||
user.do_attack_animation(target, ATTACK_EFFECT_CLAW)
|
||||
if("smash")
|
||||
if(ATTACK_EFFECT_SMASH)
|
||||
user.do_attack_animation(target, ATTACK_EFFECT_SMASH)
|
||||
else
|
||||
user.do_attack_animation(target, ATTACK_EFFECT_PUNCH)
|
||||
|
||||
user.adjustStaminaLossBuffered(5) //CITADEL CHANGE - makes punching cause staminaloss
|
||||
|
||||
var/damage = rand(user.dna.species.punchdamagelow, user.dna.species.punchdamagehigh)
|
||||
var/puncherstam = user.getStaminaLoss()
|
||||
var/puncherbrute = user.getBruteLoss()
|
||||
var/punchedstam = target.getStaminaLoss()
|
||||
var/punchedbrute = target.getBruteLoss()
|
||||
|
||||
//CITADEL CHANGES - makes resting and disabled combat mode reduce punch damage, makes being out of combat mode result in you taking more damage
|
||||
if(!target.combatmode && damage < user.dna.species.punchstunthreshold)
|
||||
damage = user.dna.species.punchstunthreshold - 1
|
||||
if(!(target.combat_flags & COMBAT_FLAG_COMBAT_ACTIVE))
|
||||
damage *= 1.5
|
||||
if(!CHECK_MOBILITY(user, MOBILITY_STAND))
|
||||
damage *= 0.5
|
||||
if(!user.combatmode)
|
||||
if(!(user.combat_flags & COMBAT_FLAG_COMBAT_ACTIVE))
|
||||
damage *= 0.25
|
||||
//END OF CITADEL CHANGES
|
||||
|
||||
var/obj/item/bodypart/affecting = target.get_bodypart(ran_zone(user.zone_selected))
|
||||
|
||||
if(!damage || !affecting)
|
||||
playsound(target.loc, user.dna.species.miss_sound, 25, 1, -1)
|
||||
target.visible_message("<span class='danger'>[user] has attempted to [atk_verb] [target]!</span>",\
|
||||
"<span class='userdanger'>[user] has attempted to [atk_verb] [target]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
var/miss_chance = 100//calculate the odds that a punch misses entirely. considers stamina and brute damage of the puncher. punches miss by default to prevent weird cases
|
||||
if(user.dna.species.punchdamagelow)
|
||||
if(atk_verb == ATTACK_EFFECT_KICK) //kicks never miss (provided your species deals more than 0 damage)
|
||||
miss_chance = 0
|
||||
else
|
||||
miss_chance = min(10 + ((puncherstam + puncherbrute)*0.5), 100) //probability of miss has a base of 10, and modified based on half your stamina and brute total. Capped at max 100 and min 0 to prevent weirdness in prob()
|
||||
|
||||
if(!damage || !affecting || prob(miss_chance))//future-proofing for species that have 0 damage/weird cases where no zone is targeted
|
||||
playsound(target.loc, user.dna.species.miss_sound, 25, TRUE, -1)
|
||||
target.visible_message("<span class='danger'>[user]'s [atk_verb] misses [target]!</span>", \
|
||||
"<span class='danger'>You avoid [user]'s [atk_verb]!</span>", "<span class='hear'>You hear a swoosh!</span>", COMBAT_MESSAGE_RANGE, user)
|
||||
to_chat(user, "<span class='warning'>Your [atk_verb] misses [target]!</span>")
|
||||
log_combat(user, target, "attempted to punch")
|
||||
return FALSE
|
||||
|
||||
|
||||
@@ -1510,14 +1526,37 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
|
||||
if(user.limb_destroyer)
|
||||
target.dismembering_strike(user, affecting.body_zone)
|
||||
target.apply_damage(damage, BRUTE, affecting, armor_block)
|
||||
log_combat(user, target, "punched")
|
||||
|
||||
if(atk_verb == ATTACK_EFFECT_KICK)//kicks deal 1.5x raw damage + 0.5x stamina damage
|
||||
target.apply_damage(damage*1.5, BRUTE, affecting, armor_block)
|
||||
target.apply_damage(damage*0.5, STAMINA, affecting, armor_block)
|
||||
log_combat(user, target, "kicked")
|
||||
else//other attacks deal full raw damage + 2x in stamina damage
|
||||
target.apply_damage(damage, BRUTE, affecting, armor_block)
|
||||
target.apply_damage(damage*2, STAMINA, affecting, armor_block)
|
||||
log_combat(user, target, "punched")
|
||||
|
||||
if((target.stat != DEAD) && damage >= user.dna.species.punchstunthreshold)
|
||||
target.visible_message("<span class='danger'>[user] has knocked [target] down!</span>", \
|
||||
"<span class='userdanger'>[user] has knocked [target] down!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
target.apply_effect(80, EFFECT_KNOCKDOWN, armor_block)
|
||||
target.forcesay(GLOB.hit_appends)
|
||||
else if(target.lying)
|
||||
if((punchedstam > 50) && prob(punchedstam*0.5)) //If our punch victim has been hit above the threshold, and they have more than 50 stamina damage, roll for stun, probability of 1% per 2 stamina damage
|
||||
|
||||
target.visible_message("<span class='danger'>[user] knocks [target] down!</span>", \
|
||||
"<span class='userdanger'>You're knocked down by [user]!</span>", "<span class='hear'>You hear aggressive shuffling followed by a loud thud!</span>", COMBAT_MESSAGE_RANGE, user)
|
||||
to_chat(user, "<span class='danger'>You knock [target] down!</span>")
|
||||
|
||||
var/knockdown_duration = 40 + (punchedstam + (punchedbrute*0.5))*0.8 - armor_block
|
||||
target.DefaultCombatKnockdown(knockdown_duration)
|
||||
target.forcesay(GLOB.hit_appends)
|
||||
log_combat(user, target, "got a stun punch with their previous punch")
|
||||
|
||||
if(HAS_TRAIT(user, TRAIT_KI_VAMPIRE) && !HAS_TRAIT(target, TRAIT_NOBREATH) && (punchedbrute < 100)) //If we're a ki vampire we also sap them of lifeforce, but only if they're not too beat up. Also living organics only.
|
||||
user.adjustBruteLoss(-5)
|
||||
user.adjustFireLoss(-5)
|
||||
user.adjustStaminaLoss(-20)
|
||||
|
||||
target.adjustCloneLoss(10)
|
||||
target.adjustBruteLoss(10)
|
||||
|
||||
else if(!(target.mobility_flags & MOBILITY_STAND))
|
||||
target.forcesay(GLOB.hit_appends)
|
||||
|
||||
/datum/species/proc/spec_unarmedattacked(mob/living/carbon/human/user, mob/living/carbon/human/target)
|
||||
@@ -1533,12 +1572,15 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
var/aim_for_groin = user.zone_selected == "groin"
|
||||
var/target_aiming_for_groin = target.zone_selected == "groin"
|
||||
|
||||
if(target.check_block()) //END EDIT
|
||||
if(target.check_martial_melee_block()) //END EDIT
|
||||
target.visible_message("<span class='warning'>[target] blocks [user]'s disarm attempt!</span>")
|
||||
return 0
|
||||
else if(user.getStaminaLoss() >= STAMINA_SOFTCRIT)
|
||||
return FALSE
|
||||
if(IS_STAMCRIT(user))
|
||||
to_chat(user, "<span class='warning'>You're too exhausted!</span>")
|
||||
return FALSE
|
||||
else if(target.check_block())
|
||||
target.visible_message("<span class='warning'>[target] blocks [user]'s disarm attempt!</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)
|
||||
@@ -1553,7 +1595,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
if (!HAS_TRAIT(target, TRAIT_PERMABONER))
|
||||
stop_wagging_tail(target)
|
||||
return FALSE
|
||||
else if(!(user.client?.prefs.cit_toggles & NO_ASS_SLAP) && aim_for_groin && (target == user || target.lying || same_dir) && (target_on_help || target_restrained || target_aiming_for_groin))
|
||||
else if(aim_for_groin && (target == user || target.lying || same_dir) && (target_on_help || target_restrained || target_aiming_for_groin))
|
||||
if(target.client?.prefs.cit_toggles & NO_ASS_SLAP)
|
||||
to_chat(user,"A force stays your hand, preventing you from slapping \the [target]'s ass!")
|
||||
return FALSE
|
||||
@@ -1598,11 +1640,11 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
target.forcesay(GLOB.hit_appends)
|
||||
log_combat(user, target, "pushed over")
|
||||
return*/
|
||||
if(!target.combatmode) // CITADEL CHANGE
|
||||
if(!(target.combat_flags & COMBAT_FLAG_COMBAT_ACTIVE)) // CITADEL CHANGE
|
||||
randn += -10 //CITADEL CHANGE - being out of combat mode makes it easier for you to get disarmed
|
||||
if(!CHECK_MOBILITY(user, MOBILITY_STAND)) //CITADEL CHANGE
|
||||
randn += 100 //CITADEL CHANGE - No kosher disarming if you're resting
|
||||
if(!user.combatmode) //CITADEL CHANGE
|
||||
if(!(target.combat_flags & COMBAT_FLAG_COMBAT_ACTIVE)) //CITADEL CHANGE
|
||||
randn += 25 //CITADEL CHANGE - Makes it harder to disarm outside of combat mode
|
||||
if(user.pulling == target)
|
||||
randn += -20 //If you have the time to get someone in a grab, you should have a greater chance at snatching the thing in their hand. Will be made completely obsolete by the grab rework but i've got a poor track record for releasing big projects on time so w/e i guess
|
||||
@@ -1661,9 +1703,9 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
/datum/species/proc/spec_attacked_by(obj/item/I, mob/living/user, obj/item/bodypart/affecting, intent, mob/living/carbon/human/H)
|
||||
// Allows you to put in item-specific reactions based on species
|
||||
if(user != H)
|
||||
if(H.check_shields(I, I.force, "the [I.name]", MELEE_ATTACK, I.armour_penetration))
|
||||
if(H.run_block(I, I.force, "the [I.name]", ATTACK_TYPE_MELEE, I.armour_penetration, user, affecting.body_zone) & BLOCK_SUCCESS)
|
||||
return 0
|
||||
if(H.check_block())
|
||||
if(H.check_martial_melee_block())
|
||||
H.visible_message("<span class='warning'>[H] blocks [I]!</span>")
|
||||
return 0
|
||||
|
||||
@@ -1679,14 +1721,12 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
var/Iforce = I.force //to avoid runtimes on the forcesay checks at the bottom. Some items might delete themselves if you drop them. (stunning yourself, ninja swords)
|
||||
//CIT CHANGES START HERE - combatmode and resting checks
|
||||
var/totitemdamage = I.force
|
||||
if(iscarbon(user))
|
||||
var/mob/living/carbon/tempcarb = user
|
||||
if(!tempcarb.combatmode)
|
||||
totitemdamage *= 0.5
|
||||
if(!(user.combat_flags & COMBAT_FLAG_COMBAT_ACTIVE))
|
||||
totitemdamage *= 0.5
|
||||
if(!CHECK_MOBILITY(user, MOBILITY_STAND))
|
||||
totitemdamage *= 0.5
|
||||
if(istype(H))
|
||||
if(!H.combatmode)
|
||||
if(!(H.combat_flags & COMBAT_FLAG_COMBAT_ACTIVE))
|
||||
totitemdamage *= 1.5
|
||||
//CIT CHANGES END HERE
|
||||
var/weakness = H.check_weakness(I, user)
|
||||
@@ -1694,6 +1734,8 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
|
||||
H.send_item_attack_message(I, user, hit_area)
|
||||
|
||||
I.do_stagger_action(H, user)
|
||||
|
||||
if(!I.force)
|
||||
return 0 //item force is zero
|
||||
|
||||
@@ -1712,7 +1754,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
bloody = 1
|
||||
var/turf/location = H.loc
|
||||
if(istype(location))
|
||||
H.bleed(totitemdamage)
|
||||
H.add_splatter_floor(location)
|
||||
if(get_dist(user, H) <= 1) //people with TK won't get smeared with blood
|
||||
user.add_mob_blood(H)
|
||||
|
||||
@@ -1779,7 +1821,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
return TRUE
|
||||
if(M.mind)
|
||||
attacker_style = M.mind.martial_art
|
||||
if((M != H) && M.a_intent != INTENT_HELP && H.check_shields(M, 0, M.name, attack_type = UNARMED_ATTACK))
|
||||
if((M != H) && M.a_intent != INTENT_HELP && (H.run_block(M, 0, "[M]", ATTACK_TYPE_UNARMED, 0, M, M.zone_selected) & BLOCK_SUCCESS))
|
||||
log_combat(M, H, "attempted to touch")
|
||||
H.visible_message("<span class='warning'>[M] attempted to touch [H]!</span>")
|
||||
return TRUE
|
||||
@@ -1796,9 +1838,12 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
|
||||
/datum/species/proc/althelp(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style)
|
||||
if(user == target && istype(user))
|
||||
if(user.getStaminaLoss() >= STAMINA_SOFTCRIT)
|
||||
if(IS_STAMCRIT(user))
|
||||
to_chat(user, "<span class='warning'>You're too exhausted for that.</span>")
|
||||
return
|
||||
if(!(user.combat_flags & COMBAT_FLAG_COMBAT_ACTIVE))
|
||||
to_chat(user, "<span class='warning'>You need combat mode to be active to that!</span>")
|
||||
return
|
||||
if(user.IsKnockdown() || user.IsParalyzed() || user.IsStun())
|
||||
to_chat(user, "<span class='warning'>You can't seem to force yourself up right now!</span>")
|
||||
return
|
||||
@@ -1811,10 +1856,10 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
playsound(user, 'sound/weapons/thudswoosh.ogg', 50, 1, -1)
|
||||
|
||||
/datum/species/proc/altdisarm(mob/living/carbon/human/user, mob/living/carbon/human/target, datum/martial_art/attacker_style)
|
||||
if(user.getStaminaLoss() >= STAMINA_SOFTCRIT)
|
||||
if(IS_STAMCRIT(user))
|
||||
to_chat(user, "<span class='warning'>You're too exhausted.</span>")
|
||||
return FALSE
|
||||
if(target.check_block())
|
||||
if(target.check_martial_melee_block())
|
||||
target.visible_message("<span class='warning'>[target] blocks [user]'s shoving attempt!</span>")
|
||||
return FALSE
|
||||
if(attacker_style && attacker_style.disarm_act(user,target))
|
||||
@@ -2046,7 +2091,7 @@ GLOBAL_LIST_EMPTY(roundstart_race_names)
|
||||
SEND_SIGNAL(H, COMSIG_CLEAR_MOOD_EVENT, "hot")
|
||||
SEND_SIGNAL(H, COMSIG_ADD_MOOD_EVENT, "cold", /datum/mood_event/cold)
|
||||
//Sorry for the nasty oneline but I don't want to assign a variable on something run pretty frequently
|
||||
H.add_movespeed_modifier(MOVESPEED_ID_COLD, override = TRUE, multiplicative_slowdown = ((BODYTEMP_COLD_DAMAGE_LIMIT - H.bodytemperature) / COLD_SLOWDOWN_FACTOR))
|
||||
H.add_movespeed_modifier(MOVESPEED_ID_COLD, override = TRUE, multiplicative_slowdown = ((BODYTEMP_COLD_DAMAGE_LIMIT - H.bodytemperature) / COLD_SLOWDOWN_FACTOR), blacklisted_movetypes = FLOATING)
|
||||
switch(H.bodytemperature)
|
||||
if(200 to BODYTEMP_COLD_DAMAGE_LIMIT)
|
||||
H.apply_damage(COLD_DAMAGE_LEVEL_1*coldmod*H.physiology.cold_mod, BURN)
|
||||
|
||||
@@ -3,8 +3,7 @@
|
||||
id = "angel"
|
||||
default_color = "FFFFFF"
|
||||
species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS)
|
||||
mutant_bodyparts = list("wings")
|
||||
default_features = list("mcolor" = "FFF", "tail_human" = "None", "ears" = "None", "wings" = "Angel")
|
||||
mutant_bodyparts = list("tail_human" = "None", "ears" = "None", "wings" = "Angel")
|
||||
use_skintones = 1
|
||||
no_equip = list(SLOT_BACK)
|
||||
blacklisted = 1
|
||||
@@ -16,8 +15,8 @@
|
||||
/datum/species/angel/on_species_gain(mob/living/carbon/human/H, datum/species/old_species)
|
||||
..()
|
||||
if(H.dna && H.dna.species && (H.dna.features["wings"] != "Angel"))
|
||||
if(!("wings" in H.dna.species.mutant_bodyparts))
|
||||
H.dna.species.mutant_bodyparts |= "wings"
|
||||
if(!H.dna.species.mutant_bodyparts["wings"])
|
||||
H.dna.species.mutant_bodyparts["wings"] = "Angel"
|
||||
H.dna.features["wings"] = "Angel"
|
||||
H.update_body()
|
||||
if(ishuman(H) && !fly)
|
||||
@@ -32,7 +31,7 @@
|
||||
H.setMovetype(H.movement_type & ~FLYING)
|
||||
ToggleFlight(H,0)
|
||||
if(H.dna && H.dna.species && (H.dna.features["wings"] == "Angel"))
|
||||
if("wings" in H.dna.species.mutant_bodyparts)
|
||||
if(H.dna.species.mutant_bodyparts["wings"])
|
||||
H.dna.species.mutant_bodyparts -= "wings"
|
||||
H.dna.features["wings"] = "None"
|
||||
H.update_body()
|
||||
|
||||
@@ -4,8 +4,7 @@
|
||||
default_color = "00FF00"
|
||||
species_traits = list(LIPS,EYECOLOR,HAIR,FACEHAIR,MUTCOLORS,HORNCOLOR,WINGCOLOR)
|
||||
inherent_biotypes = MOB_ORGANIC|MOB_HUMANOID|MOB_BUG
|
||||
mutant_bodyparts = list("mam_ears","mam_tail", "taur", "insect_wings","mam_snout", "mam_snouts", "insect_fluff","insect_markings")
|
||||
default_features = list("mcolor" = "FFF","mcolor2" = "FFF","mcolor3" = "FFF", "mam_tail" = "None", "mam_ears" = "None",
|
||||
mutant_bodyparts = list("mcolor" = "FFF","mcolor2" = "FFF","mcolor3" = "FFF", "mam_tail" = "None", "mam_ears" = "None",
|
||||
"insect_wings" = "None", "insect_fluff" = "None", "mam_snouts" = "None", "taur" = "None", "insect_markings" = "None")
|
||||
attack_verb = "slash"
|
||||
attack_sound = 'sound/weapons/slash.ogg'
|
||||
@@ -13,7 +12,7 @@
|
||||
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/insect
|
||||
liked_food = MEAT | FRUIT
|
||||
disliked_food = TOXIC
|
||||
should_draw_citadel = TRUE
|
||||
icon_limbs = DEFAULT_BODYPART_ICON_CITADEL
|
||||
|
||||
/datum/species/insect/spec_death(gibbed, mob/living/carbon/human/H)
|
||||
if(H)
|
||||
@@ -25,21 +24,21 @@
|
||||
. = ..()
|
||||
|
||||
/datum/species/insect/can_wag_tail(mob/living/carbon/human/H)
|
||||
return ("mam_tail" in mutant_bodyparts) || ("mam_waggingtail" in mutant_bodyparts)
|
||||
return mutant_bodyparts["mam_tail"] || mutant_bodyparts["mam_waggingtail"]
|
||||
|
||||
/datum/species/insect/is_wagging_tail(mob/living/carbon/human/H)
|
||||
return ("mam_waggingtail" in mutant_bodyparts)
|
||||
return mutant_bodyparts["mam_waggingtail"]
|
||||
|
||||
/datum/species/insect/start_wagging_tail(mob/living/carbon/human/H)
|
||||
if("mam_tail" in mutant_bodyparts)
|
||||
if(mutant_bodyparts["mam_tail"])
|
||||
mutant_bodyparts["mam_waggingtail"] = mutant_bodyparts["mam_tail"]
|
||||
mutant_bodyparts -= "mam_tail"
|
||||
mutant_bodyparts |= "mam_waggingtail"
|
||||
H.update_body()
|
||||
|
||||
/datum/species/insect/stop_wagging_tail(mob/living/carbon/human/H)
|
||||
if("mam_waggingtail" in mutant_bodyparts)
|
||||
if(mutant_bodyparts["mam_waggingtail"])
|
||||
mutant_bodyparts["mam_tail"] = mutant_bodyparts["mam_waggingtail"]
|
||||
mutant_bodyparts -= "mam_waggingtail"
|
||||
mutant_bodyparts |= "mam_tail"
|
||||
H.update_body()
|
||||
|
||||
/datum/species/insect/qualifies_for_rank(rank, list/features)
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
default_color = "FFFFFF"
|
||||
species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS)
|
||||
inherent_traits = list(TRAIT_NOHUNGER,TRAIT_NOBREATH)
|
||||
default_features = list("mcolor" = "FFF", "tail_human" = "None", "ears" = "None", "wings" = "None")
|
||||
mutant_bodyparts = list("tail_human" = "None", "ears" = "None", "deco_wings" = "None")
|
||||
use_skintones = TRUE
|
||||
mutant_brain = /obj/item/organ/brain/dullahan
|
||||
mutanteyes = /obj/item/organ/eyes/dullahan
|
||||
|
||||
@@ -8,7 +8,6 @@ GLOBAL_LIST_INIT(dwarf_last, world.file2list("strings/names/dwarf_last.txt")) //
|
||||
default_color = "FFFFFF"
|
||||
species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS,NO_UNDERWEAR)
|
||||
inherent_traits = list()
|
||||
default_features = list("mcolor" = "FFF", "wings" = "None")
|
||||
limbs_id = "human"
|
||||
use_skintones = 1
|
||||
say_mod = "bellows" //high energy, EXTRA BIOLOGICAL FUEL
|
||||
@@ -93,6 +92,8 @@ GLOBAL_LIST_INIT(dwarf_last, world.file2list("strings/names/dwarf_last.txt")) //
|
||||
//These count in on_life ticks which should be 2 seconds per every increment of 1 in a perfect world.
|
||||
var/dwarf_filth_ticker = 0 //Currently set =< 4, that means this will fire the proc around every 4-8 seconds.
|
||||
var/dwarf_eth_ticker = 0 //Currently set =< 1, that means this will fire the proc around every 2 seconds
|
||||
var/last_filth_spam
|
||||
var/last_alcohol_spam
|
||||
|
||||
/obj/item/organ/dwarfgland/prepare_eat()
|
||||
var/obj/S = ..()
|
||||
@@ -137,40 +138,39 @@ GLOBAL_LIST_INIT(dwarf_last, world.file2list("strings/names/dwarf_last.txt")) //
|
||||
filth_counter += 10 //Dwarves could technically chainstun each other in a vomit tantrum spiral.
|
||||
switch(filth_counter)
|
||||
if(11 to 25)
|
||||
if(prob(25))
|
||||
to_chat(owner, "<span class = 'danger'>Someone should really clean up in here!</span>")
|
||||
if(last_filth_spam + 40 SECONDS < world.time)
|
||||
to_chat(owner, "<span class = 'warning'>Someone should really clean up in here!</span>")
|
||||
last_filth_spam = world.time
|
||||
if(26 to 50)
|
||||
if(prob(30)) //Probability the message appears
|
||||
if(prob(6)) //And then the probability they vomit along with it.
|
||||
to_chat(owner, "<span class = 'danger'>The stench makes you queasy.</span>")
|
||||
if(prob(20)) //And then the probability they vomit along with it.
|
||||
owner.vomit(20) //I think vomit should stay over a disgust adjustment.
|
||||
owner.vomit(10) //I think vomit should stay over a disgust adjustment.
|
||||
if(51 to 75)
|
||||
if(prob(35))
|
||||
if(prob(9))
|
||||
to_chat(owner, "<span class = 'danger'>By Armok! You won't be able to keep alcohol down at all!</span>")
|
||||
if(prob(25))
|
||||
owner.vomit(20) //Its more funny
|
||||
owner.vomit(20) //Its more funny
|
||||
if(76 to 100)
|
||||
if(prob(40))
|
||||
if(prob(11))
|
||||
to_chat(owner, "<span class = 'userdanger'>You can't live in such FILTH!</span>")
|
||||
if(prob(25))
|
||||
owner.adjustToxLoss(10) //Now they start dying.
|
||||
owner.vomit(20)
|
||||
owner.adjustToxLoss(10) //Now they start dying.
|
||||
owner.vomit(20)
|
||||
if(101 to INFINITY) //Now they will really start dying
|
||||
if(prob(40))
|
||||
if(last_filth_spam + 12 SECONDS < world.time)
|
||||
to_chat(owner, "<span class = 'userdanger'> THERES TOO MUCH FILTH, OH GODS THE FILTH!</span>")
|
||||
last_filth_spam = world.time
|
||||
if(prob(40))
|
||||
owner.adjustToxLoss(15)
|
||||
owner.vomit(40)
|
||||
owner.vomit(30)
|
||||
CHECK_TICK //Check_tick right here, its motherfuckin magic. (To me at least)
|
||||
|
||||
//Handles the dwarf alcohol cycle tied to on_life, it ticks in dwarf_cycle_ticker.
|
||||
/obj/item/organ/dwarfgland/proc/dwarf_eth_cycle()
|
||||
//BOOZE POWER
|
||||
var/init_stored_alcohol = stored_alcohol
|
||||
for(var/datum/reagent/R in owner.reagents.reagent_list)
|
||||
if(istype(R, /datum/reagent/consumable/ethanol))
|
||||
var/datum/reagent/consumable/ethanol/E = R
|
||||
stored_alcohol += (E.boozepwr / 50)
|
||||
if(stored_alcohol > max_alcohol) //Dwarves technically start at 250 alcohol stored.
|
||||
stored_alcohol = max_alcohol
|
||||
stored_alcohol = CLAMP(stored_alcohol + E.boozepwr / 50, 0, max_alcohol)
|
||||
var/heal_amt = heal_rate
|
||||
stored_alcohol -= alcohol_rate //Subtracts alcohol_Rate from stored alcohol so EX: 250 - 0.25 per each loop that occurs.
|
||||
if(stored_alcohol > 400) //If they are over 400 they start regenerating
|
||||
@@ -178,16 +178,27 @@ GLOBAL_LIST_INIT(dwarf_last, world.file2list("strings/names/dwarf_last.txt")) //
|
||||
owner.adjustFireLoss(-heal_amt) //Unless they drink casually all the time.
|
||||
owner.adjustOxyLoss(-heal_amt)
|
||||
owner.adjustCloneLoss(-heal_amt) //Also they will probably get brain damage if thats a thing here.
|
||||
if(prob(25))
|
||||
switch(stored_alcohol)
|
||||
if(0 to 24)
|
||||
if(init_stored_alcohol + 0.5 < stored_alcohol) //recovering stored alcohol at a steady rate of +0.75, no spam.
|
||||
return
|
||||
switch(stored_alcohol)
|
||||
if(0 to 24)
|
||||
if(last_alcohol_spam + 8 SECONDS < world.time)
|
||||
to_chat(owner, "<span class='userdanger'>DAMNATION INCARNATE, WHY AM I CURSED WITH THIS DRY-SPELL? I MUST DRINK.</span>")
|
||||
owner.adjustToxLoss(35)
|
||||
if(25 to 50)
|
||||
last_alcohol_spam = world.time
|
||||
owner.adjustToxLoss(10)
|
||||
if(25 to 50)
|
||||
if(last_alcohol_spam + 20 SECONDS < world.time)
|
||||
to_chat(owner, "<span class='danger'>Oh DAMN, I need some brew!</span>")
|
||||
if(51 to 75)
|
||||
last_alcohol_spam = world.time
|
||||
if(51 to 75)
|
||||
if(last_alcohol_spam + 35 SECONDS < world.time)
|
||||
to_chat(owner, "<span class='warning'>Your body aches, you need to get ahold of some booze...</span>")
|
||||
if(76 to 100)
|
||||
last_alcohol_spam = world.time
|
||||
if(76 to 100)
|
||||
if(last_alcohol_spam + 40 SECONDS < world.time)
|
||||
to_chat(owner, "<span class='notice'>A pint of anything would really hit the spot right now.</span>")
|
||||
if(101 to 150)
|
||||
last_alcohol_spam = world.time
|
||||
if(101 to 150)
|
||||
if(last_alcohol_spam + 50 SECONDS < world.time)
|
||||
to_chat(owner, "<span class='notice'>You feel like you could use a good brew.</span>")
|
||||
last_alcohol_spam = world.time
|
||||
|
||||
@@ -4,8 +4,7 @@
|
||||
id = "felinid"
|
||||
limbs_id = "human"
|
||||
|
||||
mutant_bodyparts = list("mam_ears", "mam_tail", "deco_wings")
|
||||
default_features = list("mcolor" = "FFF", "mam_tail" = "Cat", "mam_ears" = "Cat", "wings" = "None", "deco_wings" = "None")
|
||||
mutant_bodyparts = list("mam_tail" = "Cat", "mam_ears" = "Cat", "deco_wings" = "None")
|
||||
|
||||
mutantears = /obj/item/organ/ears/cat
|
||||
mutanttail = /obj/item/organ/tail/cat
|
||||
@@ -25,21 +24,21 @@
|
||||
|
||||
|
||||
/datum/species/human/felinid/can_wag_tail(mob/living/carbon/human/H)
|
||||
return ("mam_tail" in mutant_bodyparts) || ("mam_waggingtail" in mutant_bodyparts)
|
||||
return mutant_bodyparts["mam_tail"] || mutant_bodyparts["mam_waggingtail"]
|
||||
|
||||
/datum/species/human/felinid/is_wagging_tail(mob/living/carbon/human/H)
|
||||
return ("mam_waggingtail" in mutant_bodyparts)
|
||||
return mutant_bodyparts["mam_waggingtail"]
|
||||
|
||||
/datum/species/human/felinid/start_wagging_tail(mob/living/carbon/human/H)
|
||||
if("mam_tail" in mutant_bodyparts)
|
||||
if(mutant_bodyparts["mam_tail"])
|
||||
mutant_bodyparts["mam_waggingtail"] = mutant_bodyparts["mam_tail"]
|
||||
mutant_bodyparts -= "mam_tail"
|
||||
mutant_bodyparts |= "mam_waggingtail"
|
||||
H.update_body()
|
||||
|
||||
/datum/species/human/felinid/stop_wagging_tail(mob/living/carbon/human/H)
|
||||
if("mam_waggingtail" in mutant_bodyparts)
|
||||
if(mutant_bodyparts["mam_waggingtail"])
|
||||
mutant_bodyparts["mam_tail"] = mutant_bodyparts["mam_waggingtail"]
|
||||
mutant_bodyparts -= "mam_waggingtail"
|
||||
mutant_bodyparts |= "mam_tail"
|
||||
H.update_body()
|
||||
|
||||
/datum/species/human/felinid/on_species_gain(mob/living/carbon/C, datum/species/old_species, pref_load)
|
||||
|
||||
@@ -2,11 +2,10 @@
|
||||
name = "Anthromorph"
|
||||
id = "mammal"
|
||||
default_color = "4B4B4B"
|
||||
should_draw_citadel = TRUE
|
||||
icon_limbs = DEFAULT_BODYPART_ICON_CITADEL
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,LIPS,HAIR,HORNCOLOR,WINGCOLOR)
|
||||
inherent_biotypes = MOB_ORGANIC|MOB_HUMANOID|MOB_BEAST
|
||||
mutant_bodyparts = list("mam_tail", "mam_ears", "mam_body_markings", "mam_snouts", "deco_wings", "taur", "horns", "legs")
|
||||
default_features = list("mcolor" = "FFF","mcolor2" = "FFF","mcolor3" = "FFF", "mam_snouts" = "Husky", "mam_tail" = "Husky", "mam_ears" = "Husky", "deco_wings" = "None",
|
||||
mutant_bodyparts = list("mcolor" = "FFF","mcolor2" = "FFF","mcolor3" = "FFF", "mam_snouts" = "Husky", "mam_tail" = "Husky", "mam_ears" = "Husky", "deco_wings" = "None",
|
||||
"mam_body_markings" = "Husky", "taur" = "None", "horns" = "None", "legs" = "Plantigrade", "meat_type" = "Mammalian")
|
||||
attack_verb = "claw"
|
||||
attack_sound = 'sound/weapons/slash.ogg'
|
||||
@@ -26,21 +25,21 @@
|
||||
. = ..()
|
||||
|
||||
/datum/species/mammal/can_wag_tail(mob/living/carbon/human/H)
|
||||
return ("mam_tail" in mutant_bodyparts) || ("mam_waggingtail" in mutant_bodyparts)
|
||||
return mutant_bodyparts["mam_tail"] || mutant_bodyparts["mam_waggingtail"]
|
||||
|
||||
/datum/species/mammal/is_wagging_tail(mob/living/carbon/human/H)
|
||||
return ("mam_waggingtail" in mutant_bodyparts)
|
||||
return mutant_bodyparts["mam_waggingtail"]
|
||||
|
||||
/datum/species/mammal/start_wagging_tail(mob/living/carbon/human/H)
|
||||
if("mam_tail" in mutant_bodyparts)
|
||||
if(mutant_bodyparts["mam_tail"])
|
||||
mutant_bodyparts["mam_waggingtail"] = mutant_bodyparts["mam_tail"]
|
||||
mutant_bodyparts -= "mam_tail"
|
||||
mutant_bodyparts |= "mam_waggingtail"
|
||||
H.update_body()
|
||||
|
||||
/datum/species/mammal/stop_wagging_tail(mob/living/carbon/human/H)
|
||||
if("mam_waggingtail" in mutant_bodyparts)
|
||||
if(mutant_bodyparts["mam_waggingtail"])
|
||||
mutant_bodyparts["mam_tail"] = mutant_bodyparts["mam_waggingtail"]
|
||||
mutant_bodyparts -= "mam_waggingtail"
|
||||
mutant_bodyparts |= "mam_tail"
|
||||
H.update_body()
|
||||
|
||||
|
||||
@@ -55,10 +54,9 @@
|
||||
id = "xeno"
|
||||
say_mod = "hisses"
|
||||
default_color = "00FF00"
|
||||
should_draw_citadel = TRUE
|
||||
icon_limbs = DEFAULT_BODYPART_ICON_CITADEL
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,LIPS)
|
||||
mutant_bodyparts = list("xenotail", "xenohead", "xenodorsal", "mam_body_markings", "taur", "legs")
|
||||
default_features = list("xenotail"="Xenomorph Tail","xenohead"="Standard","xenodorsal"="Standard", "mam_body_markings" = "Xeno","mcolor" = "0F0","mcolor2" = "0F0","mcolor3" = "0F0","taur" = "None", "legs" = "Digitigrade")
|
||||
mutant_bodyparts = list("xenotail"="Xenomorph Tail","xenohead"="Standard","xenodorsal"="Standard", "mam_body_markings" = "Xeno","mcolor" = "0F0","mcolor2" = "0F0","mcolor3" = "0F0","taur" = "None", "legs" = "Digitigrade")
|
||||
attack_verb = "slash"
|
||||
attack_sound = 'sound/weapons/slash.ogg'
|
||||
miss_sound = 'sound/weapons/slashmiss.ogg'
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
siemens_coeff = 0
|
||||
punchdamagelow = 5
|
||||
punchdamagehigh = 14
|
||||
punchstunthreshold = 11 //about 40% chance to stun
|
||||
punchstunthreshold = 10
|
||||
no_equip = list(SLOT_WEAR_MASK, SLOT_WEAR_SUIT, SLOT_GLOVES, SLOT_SHOES, SLOT_W_UNIFORM, SLOT_S_STORE)
|
||||
nojumpsuit = 1
|
||||
sexes = 1
|
||||
@@ -168,7 +168,7 @@
|
||||
name = "Silver Golem"
|
||||
id = "silver golem"
|
||||
fixed_mut_color = "ddd"
|
||||
punchstunthreshold = 9 //60% chance, from 40%
|
||||
punchstunthreshold = 9
|
||||
meat = /obj/item/stack/ore/silver
|
||||
info_text = "As a <span class='danger'>Silver Golem</span>, your attacks have a higher chance of stunning. Being made of silver, your body is immune to most types of magic."
|
||||
prefix = "Silver"
|
||||
@@ -190,7 +190,7 @@
|
||||
stunmod = 0.4
|
||||
punchdamagelow = 12
|
||||
punchdamagehigh = 21
|
||||
punchstunthreshold = 18 //still 40% stun chance
|
||||
punchstunthreshold = 18
|
||||
speedmod = 4 //pretty fucking slow
|
||||
meat = /obj/item/stack/ore/iron
|
||||
info_text = "As a <span class='danger'>Plasteel Golem</span>, you are slower, but harder to stun, and hit very hard when punching."
|
||||
|
||||
@@ -4,8 +4,7 @@
|
||||
default_color = "FFFFFF"
|
||||
|
||||
species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS,MUTCOLORS_PARTSONLY,WINGCOLOR)
|
||||
mutant_bodyparts = list("ears", "tail_human", "wings", "taur", "deco_wings") // CITADEL EDIT gives humans snowflake parts
|
||||
default_features = list("mcolor" = "FFF", "mcolor2" = "FFF","mcolor3" = "FFF","tail_human" = "None", "ears" = "None", "wings" = "None", "taur" = "None", "deco_wings" = "None")
|
||||
mutant_bodyparts = list("mcolor" = "FFF", "mcolor2" = "FFF","mcolor3" = "FFF","tail_human" = "None", "ears" = "None", "taur" = "None", "deco_wings" = "None")
|
||||
use_skintones = 1
|
||||
skinned_type = /obj/item/stack/sheet/animalhide/human
|
||||
disliked_food = GROSS | RAW
|
||||
@@ -24,19 +23,19 @@
|
||||
. = ..()
|
||||
|
||||
/datum/species/human/can_wag_tail(mob/living/carbon/human/H)
|
||||
return ("tail_human" in mutant_bodyparts) || ("waggingtail_human" in mutant_bodyparts)
|
||||
return mutant_bodyparts["tail_human"] || mutant_bodyparts["waggingtail_human"]
|
||||
|
||||
/datum/species/human/is_wagging_tail(mob/living/carbon/human/H)
|
||||
return ("waggingtail_human" in mutant_bodyparts)
|
||||
return mutant_bodyparts["waggingtail_human"]
|
||||
|
||||
/datum/species/human/start_wagging_tail(mob/living/carbon/human/H)
|
||||
if("tail_human" in mutant_bodyparts)
|
||||
if(mutant_bodyparts["tail_human"])
|
||||
mutant_bodyparts["waggingtail_human"] = mutant_bodyparts["tail_human"]
|
||||
mutant_bodyparts -= "tail_human"
|
||||
mutant_bodyparts |= "waggingtail_human"
|
||||
H.update_body()
|
||||
|
||||
/datum/species/human/stop_wagging_tail(mob/living/carbon/human/H)
|
||||
if("waggingtail_human" in mutant_bodyparts)
|
||||
if(mutant_bodyparts["waggingtail_human"])
|
||||
mutant_bodyparts["tail_human"] = mutant_bodyparts["waggingtail_human"]
|
||||
mutant_bodyparts -= "waggingtail_human"
|
||||
mutant_bodyparts |= "tail_human"
|
||||
H.update_body()
|
||||
|
||||
@@ -3,13 +3,12 @@
|
||||
id = "ipc"
|
||||
say_mod = "beeps"
|
||||
default_color = "00FF00"
|
||||
should_draw_citadel = TRUE
|
||||
icon_limbs = DEFAULT_BODYPART_ICON_CITADEL
|
||||
blacklisted = 0
|
||||
sexes = 0
|
||||
species_traits = list(MUTCOLORS,NOEYES,NOTRANSSTING)
|
||||
inherent_biotypes = MOB_ROBOTIC|MOB_HUMANOID
|
||||
mutant_bodyparts = list("ipc_screen", "ipc_antenna")
|
||||
default_features = list("ipc_screen" = "Blank", "ipc_antenna" = "None")
|
||||
mutant_bodyparts = list("ipc_screen" = "Blank", "ipc_antenna" = "None")
|
||||
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/ipc
|
||||
gib_types = list(/obj/effect/gibspawner/ipc, /obj/effect/gibspawner/ipc/bodypartless)
|
||||
mutanttongue = /obj/item/organ/tongue/robot/ipc
|
||||
|
||||
@@ -7,8 +7,7 @@
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR,WINGCOLOR)
|
||||
mutantlungs = /obj/item/organ/lungs/slime
|
||||
mutant_heart = /obj/item/organ/heart/slime
|
||||
mutant_bodyparts = list("mam_tail", "mam_ears", "mam_snouts", "taur", "deco_wings") //CIT CHANGE
|
||||
default_features = list("mcolor" = "FFF", "mam_tail" = "None", "mam_ears" = "None", "mam_snouts" = "None", "taur" = "None", "deco_wings" = "None") //CIT CHANGE
|
||||
mutant_bodyparts = list("mcolor" = "FFF", "mam_tail" = "None", "mam_ears" = "None", "mam_snouts" = "None", "taur" = "None", "deco_wings" = "None")
|
||||
inherent_traits = list(TRAIT_TOXINLOVER)
|
||||
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/slime
|
||||
gib_types = list(/obj/effect/gibspawner/slime, /obj/effect/gibspawner/slime/bodypartless)
|
||||
@@ -127,23 +126,24 @@
|
||||
. = ..()
|
||||
|
||||
/datum/species/jelly/can_wag_tail(mob/living/carbon/human/H)
|
||||
return ("mam_tail" in mutant_bodyparts) || ("mam_waggingtail" in mutant_bodyparts)
|
||||
return mutant_bodyparts["mam_tail"] || mutant_bodyparts["mam_waggingtail"]
|
||||
|
||||
/datum/species/jelly/is_wagging_tail(mob/living/carbon/human/H)
|
||||
return ("mam_waggingtail" in mutant_bodyparts)
|
||||
return mutant_bodyparts["mam_waggingtail"]
|
||||
|
||||
/datum/species/jelly/start_wagging_tail(mob/living/carbon/human/H)
|
||||
if("mam_tail" in mutant_bodyparts)
|
||||
if(mutant_bodyparts["mam_tail"])
|
||||
mutant_bodyparts["mam_waggingtail"] = mutant_bodyparts["mam_tail"]
|
||||
mutant_bodyparts -= "mam_tail"
|
||||
mutant_bodyparts |= "mam_waggingtail"
|
||||
H.update_body()
|
||||
|
||||
/datum/species/jelly/stop_wagging_tail(mob/living/carbon/human/H)
|
||||
if("mam_waggingtail" in mutant_bodyparts)
|
||||
if(mutant_bodyparts["mam_waggingtail"])
|
||||
mutant_bodyparts["mam_tail"] = mutant_bodyparts["mam_waggingtail"]
|
||||
mutant_bodyparts -= "mam_waggingtail"
|
||||
mutant_bodyparts |= "mam_tail"
|
||||
H.update_body()
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////SLIMEPEOPLE///////////////////////////////////////////////////////////////////
|
||||
|
||||
//Slime people are able to split like slimes, retaining a single mind that can swap between bodies at will, even after death.
|
||||
@@ -431,8 +431,7 @@
|
||||
default_color = "00FFFF"
|
||||
species_traits = list(MUTCOLORS,EYECOLOR,HAIR,FACEHAIR)
|
||||
inherent_traits = list(TRAIT_TOXINLOVER)
|
||||
mutant_bodyparts = list("mam_tail", "mam_ears", "mam_body_markings", "mam_snouts", "taur")
|
||||
default_features = list("mcolor" = "FFF", "mcolor2" = "FFF","mcolor3" = "FFF", "mam_tail" = "None", "mam_ears" = "None", "mam_body_markings" = "Plain", "mam_snouts" = "None", "taur" = "None")
|
||||
mutant_bodyparts = list("mcolor" = "FFF", "mcolor2" = "FFF","mcolor3" = "FFF", "mam_tail" = "None", "mam_ears" = "None", "mam_body_markings" = "Plain", "mam_snouts" = "None", "taur" = "None")
|
||||
say_mod = "says"
|
||||
hair_color = "mutcolor"
|
||||
hair_alpha = 160 //a notch brighter so it blends better.
|
||||
@@ -603,10 +602,11 @@
|
||||
else if (select_alteration == "Penis Length")
|
||||
for(var/obj/item/organ/genital/penis/X in H.internal_organs)
|
||||
qdel(X)
|
||||
var/new_length
|
||||
new_length = input(owner, "Penis length in inches:\n([COCK_SIZE_MIN]-[COCK_SIZE_MAX])", "Genital Alteration") as num|null
|
||||
var/min_D = CONFIG_GET(number/penis_min_inches_prefs)
|
||||
var/max_D = CONFIG_GET(number/penis_max_inches_prefs)
|
||||
var/new_length = input(owner, "Penis length in inches:\n([min_D]-[max_D])", "Genital Alteration") as num|null
|
||||
if(new_length)
|
||||
H.dna.features["cock_length"] = max(min( round(text2num(new_length)), COCK_SIZE_MAX),COCK_SIZE_MIN)
|
||||
H.dna.features["cock_length"] = CLAMP(round(new_length), min_D, max_D)
|
||||
H.update_genitals()
|
||||
H.apply_overlay()
|
||||
H.give_genital(/obj/item/organ/genital/testicles)
|
||||
@@ -615,8 +615,7 @@
|
||||
else if (select_alteration == "Breast Size")
|
||||
for(var/obj/item/organ/genital/breasts/X in H.internal_organs)
|
||||
qdel(X)
|
||||
var/new_size
|
||||
new_size = input(owner, "Breast Size", "Genital Alteration") as null|anything in GLOB.breasts_size_list
|
||||
var/new_size = input(owner, "Breast Size", "Genital Alteration") as null|anything in CONFIG_GET(keyed_list/breasts_cups_prefs)
|
||||
if(new_size)
|
||||
H.dna.features["breasts_size"] = new_size
|
||||
H.update_genitals()
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
mutanttail = /obj/item/organ/tail/lizard
|
||||
coldmod = 1.5
|
||||
heatmod = 0.67
|
||||
default_features = list("mcolor" = "0F0", "mcolor2" = "0F0", "mcolor3" = "0F0", "tail_lizard" = "Smooth", "snout" = "Round",
|
||||
mutant_bodyparts = list("mcolor" = "0F0", "mcolor2" = "0F0", "mcolor3" = "0F0", "tail_lizard" = "Smooth", "snout" = "Round",
|
||||
"horns" = "None", "frills" = "None", "spines" = "None", "body_markings" = "None",
|
||||
"legs" = "Digitigrade", "taur" = "None", "deco_wings" = "None")
|
||||
attack_verb = "slash"
|
||||
@@ -23,6 +23,7 @@
|
||||
exotic_bloodtype = "L"
|
||||
disliked_food = GRAIN | DAIRY
|
||||
liked_food = GROSS | MEAT
|
||||
inert_mutation = FIREBREATH
|
||||
|
||||
/datum/species/lizard/after_equip_job(datum/job/J, mob/living/carbon/human/H)
|
||||
H.grant_language(/datum/language/draconic)
|
||||
@@ -52,25 +53,25 @@
|
||||
. = ..()
|
||||
|
||||
/datum/species/lizard/can_wag_tail(mob/living/carbon/human/H)
|
||||
return ("tail_lizard" in mutant_bodyparts) || ("waggingtail_lizard" in mutant_bodyparts)
|
||||
return mutant_bodyparts["tail_lizard"] || mutant_bodyparts["waggingtail_lizard"]
|
||||
|
||||
/datum/species/lizard/is_wagging_tail(mob/living/carbon/human/H)
|
||||
return ("waggingtail_lizard" in mutant_bodyparts)
|
||||
return mutant_bodyparts["waggingtail_lizard"]
|
||||
|
||||
/datum/species/lizard/start_wagging_tail(mob/living/carbon/human/H)
|
||||
if("tail_lizard" in mutant_bodyparts)
|
||||
if(mutant_bodyparts["tail_lizard"])
|
||||
mutant_bodyparts["waggingtail_lizard"] = mutant_bodyparts["tail_lizard"]
|
||||
mutant_bodyparts["waggingspines"] = mutant_bodyparts["spines"]
|
||||
mutant_bodyparts -= "tail_lizard"
|
||||
mutant_bodyparts -= "spines"
|
||||
mutant_bodyparts |= "waggingtail_lizard"
|
||||
mutant_bodyparts |= "waggingspines"
|
||||
H.update_body()
|
||||
|
||||
/datum/species/lizard/stop_wagging_tail(mob/living/carbon/human/H)
|
||||
if("waggingtail_lizard" in mutant_bodyparts)
|
||||
if(mutant_bodyparts["waggingtail_lizard"])
|
||||
mutant_bodyparts["tail_lizard"] = mutant_bodyparts["waggingtail_lizard"]
|
||||
mutant_bodyparts["spines"] = mutant_bodyparts["waggingspines"]
|
||||
mutant_bodyparts -= "waggingtail_lizard"
|
||||
mutant_bodyparts -= "waggingspines"
|
||||
mutant_bodyparts |= "tail_lizard"
|
||||
mutant_bodyparts |= "spines"
|
||||
H.update_body()
|
||||
|
||||
/*
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
/datum/species/mush //mush mush codecuck
|
||||
name = "Anthromorphic Mushroom"
|
||||
id = "mush"
|
||||
mutant_bodyparts = list("caps")
|
||||
default_features = list("caps" = "Round")
|
||||
mutant_bodyparts = list("caps" = "Round")
|
||||
|
||||
fixed_mut_color = "DBBF92"
|
||||
hair_color = "FF4B19" //cap color, spot color uses eye color
|
||||
@@ -13,9 +12,9 @@
|
||||
inherent_traits = list(TRAIT_NOBREATH)
|
||||
speedmod = 1.5 //faster than golems but not by much
|
||||
|
||||
punchdamagelow = 6
|
||||
punchdamagehigh = 14
|
||||
punchstunthreshold = 14 //about 44% chance to stun
|
||||
punchdamagelow = 2
|
||||
punchdamagehigh = 12 //still better than humans
|
||||
punchstunthreshold = 10
|
||||
|
||||
no_equip = list(SLOT_WEAR_MASK, SLOT_WEAR_SUIT, SLOT_GLOVES, SLOT_SHOES, SLOT_W_UNIFORM)
|
||||
|
||||
|
||||
@@ -61,9 +61,9 @@
|
||||
H.DefaultCombatKnockdown(100)
|
||||
H.visible_message("<span class='warning'>[H] writhes in pain as [H.p_their()] vacuoles boil.</span>", "<span class='userdanger'>You writhe in pain as your vacuoles boil!</span>", "<span class='italics'>You hear the crunching of leaves.</span>")
|
||||
if(prob(80))
|
||||
H.randmutb()
|
||||
H.easy_randmut(NEGATIVE+MINOR_NEGATIVE)
|
||||
else
|
||||
H.randmutg()
|
||||
H.easy_randmut(POSITIVE)
|
||||
H.domutcheck()
|
||||
else
|
||||
H.adjustFireLoss(rand(5,15))
|
||||
@@ -76,14 +76,13 @@
|
||||
name = "Anthromorphic Plant"
|
||||
id = "podweak"
|
||||
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")
|
||||
mutant_bodyparts = 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")
|
||||
limbs_id = "pod"
|
||||
light_nutrition_gain_factor = 7.5
|
||||
light_bruteheal = 0.2
|
||||
light_burnheal = 0.2
|
||||
light_toxheal = 0.7
|
||||
|
||||
|
||||
/datum/species/pod/pseudo_weak/spec_death(gibbed, mob/living/carbon/human/H)
|
||||
if(H)
|
||||
stop_wagging_tail(H)
|
||||
@@ -94,19 +93,19 @@
|
||||
. = ..()
|
||||
|
||||
/datum/species/pod/pseudo_weak/can_wag_tail(mob/living/carbon/human/H)
|
||||
return ("mam_tail" in mutant_bodyparts) || ("mam_waggingtail" in mutant_bodyparts)
|
||||
return mutant_bodyparts["mam_tail"] || mutant_bodyparts["mam_waggingtail"]
|
||||
|
||||
/datum/species/pod/pseudo_weak/is_wagging_tail(mob/living/carbon/human/H)
|
||||
return ("mam_waggingtail" in mutant_bodyparts)
|
||||
return mutant_bodyparts["mam_waggingtail"]
|
||||
|
||||
/datum/species/pod/pseudo_weak/start_wagging_tail(mob/living/carbon/human/H)
|
||||
if("mam_tail" in mutant_bodyparts)
|
||||
if(mutant_bodyparts["mam_tail"])
|
||||
mutant_bodyparts["mam_waggingtail"] = mutant_bodyparts["mam_tail"]
|
||||
mutant_bodyparts -= "mam_tail"
|
||||
mutant_bodyparts |= "mam_waggingtail"
|
||||
H.update_body()
|
||||
|
||||
/datum/species/pod/pseudo_weak/stop_wagging_tail(mob/living/carbon/human/H)
|
||||
if("mam_waggingtail" in mutant_bodyparts)
|
||||
if(mutant_bodyparts["mam_waggingtail"])
|
||||
mutant_bodyparts["mam_tail"] = mutant_bodyparts["mam_waggingtail"]
|
||||
mutant_bodyparts -= "mam_waggingtail"
|
||||
mutant_bodyparts |= "mam_tail"
|
||||
H.update_body()
|
||||
|
||||
@@ -100,6 +100,9 @@
|
||||
var/obj/item/light_eater/blade
|
||||
decay_factor = 0
|
||||
|
||||
/obj/item/organ/heart/nightmare/ComponentInitialize()
|
||||
. = ..()
|
||||
AddElement(/datum/element/update_icon_blocker)
|
||||
|
||||
/obj/item/organ/heart/nightmare/attack(mob/M, mob/living/carbon/user, obj/target)
|
||||
if(M != user)
|
||||
@@ -130,9 +133,6 @@
|
||||
/obj/item/organ/heart/nightmare/Stop()
|
||||
return 0
|
||||
|
||||
/obj/item/organ/heart/nightmare/update_icon()
|
||||
return //always beating visually
|
||||
|
||||
/obj/item/organ/heart/nightmare/on_death()
|
||||
if(!owner)
|
||||
return
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
id = "spaceskeleton"
|
||||
limbs_id = "skeleton"
|
||||
blacklisted = 1
|
||||
inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NOHUNGER,TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT,TRAIT_FAKEDEATH, TRAIT_CALCIUM_HEALER)
|
||||
inherent_traits = list(TRAIT_RESISTHEAT,TRAIT_NOBREATH,TRAIT_RESISTCOLD,TRAIT_RESISTHIGHPRESSURE,TRAIT_RESISTLOWPRESSURE,TRAIT_RADIMMUNE,TRAIT_PIERCEIMMUNE,TRAIT_NOHUNGER,TRAIT_EASYDISMEMBER,TRAIT_LIMBATTACHMENT, TRAIT_FAKEDEATH, TRAIT_CALCIUM_HEALER)
|
||||
|
||||
/datum/species/skeleton/space/check_roundstart_eligible()
|
||||
return FALSE
|
||||
@@ -0,0 +1,52 @@
|
||||
/datum/species/synthliz
|
||||
name = "Synthetic Lizardperson"
|
||||
id = "synthliz"
|
||||
icon_limbs = DEFAULT_BODYPART_ICON_CITADEL
|
||||
say_mod = "beeps"
|
||||
default_color = "00FF00"
|
||||
species_traits = list(MUTCOLORS,NOTRANSSTING,EYECOLOR,LIPS,HAIR)
|
||||
inherent_biotypes = MOB_ROBOTIC|MOB_HUMANOID
|
||||
mutant_bodyparts = list("ipc_antenna" = "Synthetic Lizard - Antennae","mam_tail" = "Synthetic Lizard", "mam_snouts" = "Synthetic Lizard - Snout", "legs" = "Digitigrade", "mam_body_markings" = "Synthetic Lizard - Plates", "taur" = "None")
|
||||
meat = /obj/item/reagent_containers/food/snacks/meat/slab/human/mutant/ipc
|
||||
gib_types = list(/obj/effect/gibspawner/ipc, /obj/effect/gibspawner/ipc/bodypartless)
|
||||
mutanttongue = /obj/item/organ/tongue/robot/ipc
|
||||
//Just robo looking parts.
|
||||
mutant_heart = /obj/item/organ/heart/ipc
|
||||
mutantlungs = /obj/item/organ/lungs/ipc
|
||||
mutantliver = /obj/item/organ/liver/ipc
|
||||
mutantstomach = /obj/item/organ/stomach/ipc
|
||||
mutanteyes = /obj/item/organ/eyes/ipc
|
||||
|
||||
exotic_bloodtype = "S"
|
||||
|
||||
|
||||
/datum/species/synthliz/qualifies_for_rank(rank, list/features)
|
||||
return TRUE
|
||||
|
||||
//I wag in death
|
||||
/datum/species/synthliz/spec_death(gibbed, mob/living/carbon/human/H)
|
||||
if(H)
|
||||
stop_wagging_tail(H)
|
||||
|
||||
/datum/species/synthliz/spec_stun(mob/living/carbon/human/H,amount)
|
||||
if(H)
|
||||
stop_wagging_tail(H)
|
||||
. = ..()
|
||||
|
||||
/datum/species/synthliz/can_wag_tail(mob/living/carbon/human/H)
|
||||
return mutant_bodyparts["mam_tail"] || mutant_bodyparts["mam_waggingtail"]
|
||||
|
||||
/datum/species/synthliz/is_wagging_tail(mob/living/carbon/human/H)
|
||||
return mutant_bodyparts["mam_waggingtail"]
|
||||
|
||||
/datum/species/synthliz/start_wagging_tail(mob/living/carbon/human/H)
|
||||
if(mutant_bodyparts["mam_tail"])
|
||||
mutant_bodyparts["mam_waggingtail"] = mutant_bodyparts["mam_tail"]
|
||||
mutant_bodyparts -= "mam_tail"
|
||||
H.update_body()
|
||||
|
||||
/datum/species/synthliz/stop_wagging_tail(mob/living/carbon/human/H)
|
||||
if(mutant_bodyparts["mam_waggingtail"])
|
||||
mutant_bodyparts["mam_tail"] = mutant_bodyparts["mam_waggingtail"]
|
||||
mutant_bodyparts -= "mam_waggingtail"
|
||||
H.update_body()
|
||||
@@ -23,7 +23,7 @@
|
||||
armor = 25
|
||||
punchdamagelow = 10
|
||||
punchdamagehigh = 19
|
||||
punchstunthreshold = 14 //about 50% chance to stun
|
||||
punchstunthreshold = 14
|
||||
disguise_fail_health = 50
|
||||
|
||||
/datum/species/synth/on_species_gain(mob/living/carbon/human/H, datum/species/old_species)
|
||||
@@ -58,7 +58,6 @@
|
||||
meat = S.meat
|
||||
mutant_bodyparts = S.mutant_bodyparts.Copy()
|
||||
mutant_organs = S.mutant_organs.Copy()
|
||||
default_features = S.default_features.Copy()
|
||||
nojumpsuit = S.nojumpsuit
|
||||
no_equip = S.no_equip.Copy()
|
||||
limbs_id = S.limbs_id
|
||||
@@ -75,7 +74,6 @@
|
||||
attack_sound = initial(attack_sound)
|
||||
miss_sound = initial(miss_sound)
|
||||
mutant_bodyparts = list()
|
||||
default_features = list()
|
||||
nojumpsuit = initial(nojumpsuit)
|
||||
no_equip = list()
|
||||
qdel(fake_species)
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
species_traits = list(EYECOLOR,HAIR,FACEHAIR,LIPS,DRINKSBLOOD)
|
||||
inherent_traits = list(TRAIT_NOHUNGER,TRAIT_NOBREATH)
|
||||
inherent_biotypes = MOB_UNDEAD|MOB_HUMANOID
|
||||
default_features = list("mcolor" = "FFF", "tail_human" = "None", "ears" = "None", "wings" = "None")
|
||||
mutant_bodyparts = list("mcolor" = "FFF", "tail_human" = "None", "ears" = "None", "deco_wings" = "None")
|
||||
exotic_bloodtype = "U"
|
||||
use_skintones = TRUE
|
||||
mutant_heart = /obj/item/organ/heart/vampire
|
||||
@@ -146,5 +146,7 @@
|
||||
if(transfer_name)
|
||||
H.name = caster.name
|
||||
|
||||
clothes_req = 0
|
||||
human_req = 0
|
||||
|
||||
clothes_req = NONE
|
||||
mobs_whitelist = null
|
||||
mobs_blacklist = null
|
||||
|
||||
@@ -57,10 +57,12 @@ There are several things that need to be remembered:
|
||||
dna.species.handle_mutant_bodyparts(src)
|
||||
|
||||
|
||||
/mob/living/carbon/human/update_body()
|
||||
/mob/living/carbon/human/update_body(update_genitals = FALSE)
|
||||
remove_overlay(BODY_LAYER)
|
||||
dna.species.handle_body(src)
|
||||
..()
|
||||
if(update_genitals)
|
||||
update_genitals()
|
||||
|
||||
/mob/living/carbon/human/update_fire()
|
||||
..((fire_stacks > 3) ? "Standing" : "Generic_mob_burning")
|
||||
@@ -72,7 +74,7 @@ There are several things that need to be remembered:
|
||||
|
||||
if(!..())
|
||||
icon_render_key = null //invalidate bodyparts cache
|
||||
update_body()
|
||||
update_body(TRUE)
|
||||
update_hair()
|
||||
update_inv_w_uniform()
|
||||
update_inv_wear_id()
|
||||
@@ -116,28 +118,26 @@ There are several things that need to be remembered:
|
||||
return
|
||||
|
||||
|
||||
var/t_color = U.item_color
|
||||
if(!t_color)
|
||||
t_color = U.icon_state
|
||||
var/target_overlay = U.icon_state
|
||||
if(U.adjusted == ALT_STYLE)
|
||||
t_color = "[t_color]_d"
|
||||
target_overlay = "[target_overlay]_d"
|
||||
|
||||
var/alt_worn = U.alternate_worn_icon || 'icons/mob/uniform.dmi'
|
||||
var/alt_worn = U.mob_overlay_icon || 'icons/mob/clothing/uniform.dmi'
|
||||
var/variant_flag = NONE
|
||||
|
||||
if((DIGITIGRADE in dna.species.species_traits) && U.mutantrace_variation & STYLE_DIGITIGRADE)
|
||||
alt_worn = 'icons/mob/uniform_digi.dmi'
|
||||
alt_worn = 'icons/mob/clothing/uniform_digi.dmi'
|
||||
variant_flag |= STYLE_DIGITIGRADE
|
||||
|
||||
var/mutable_appearance/uniform_overlay
|
||||
|
||||
if(dna && dna.species.sexes)
|
||||
var/G = (gender == FEMALE) ? "f" : "m"
|
||||
var/G = (dna.features["body_model"] == FEMALE) ? "f" : "m"
|
||||
if(G == "f" && U.fitted != NO_FEMALE_UNIFORM)
|
||||
uniform_overlay = U.build_worn_icon(t_color, UNIFORM_LAYER, alt_worn, FALSE, U.fitted, variant_flag, FALSE)
|
||||
uniform_overlay = U.build_worn_icon(UNIFORM_LAYER, alt_worn, FALSE, U.fitted, target_overlay, variant_flag, FALSE)
|
||||
|
||||
if(!uniform_overlay)
|
||||
uniform_overlay = U.build_worn_icon(t_color, UNIFORM_LAYER, alt_worn, FALSE, NO_FEMALE_UNIFORM, variant_flag, FALSE)
|
||||
uniform_overlay = U.build_worn_icon( UNIFORM_LAYER, alt_worn, FALSE, NO_FEMALE_UNIFORM, target_overlay, variant_flag, FALSE)
|
||||
|
||||
|
||||
if(OFFSET_UNIFORM in dna.species.offset_features)
|
||||
@@ -165,7 +165,7 @@ There are several things that need to be remembered:
|
||||
update_observer_view(wear_id)
|
||||
|
||||
//TODO: add an icon file for ID slot stuff, so it's less snowflakey
|
||||
id_overlay = wear_id.build_worn_icon(state = wear_id.item_state, default_layer = ID_LAYER, default_icon_file = 'icons/mob/mob.dmi')
|
||||
id_overlay = wear_id.build_worn_icon(default_layer = ID_LAYER, default_icon_file = 'icons/mob/mob.dmi', override_state = wear_id.item_state)
|
||||
if(OFFSET_ID in dna.species.offset_features)
|
||||
id_overlay.pixel_x += dna.species.offset_features[OFFSET_ID][1]
|
||||
id_overlay.pixel_y += dna.species.offset_features[OFFSET_ID][2]
|
||||
@@ -197,10 +197,7 @@ There are several things that need to be remembered:
|
||||
if(hud_used.inventory_shown)
|
||||
client.screen += gloves
|
||||
update_observer_view(gloves,1)
|
||||
var/t_state = gloves.item_state
|
||||
if(!t_state)
|
||||
t_state = gloves.icon_state
|
||||
overlays_standing[GLOVES_LAYER] = gloves.build_worn_icon(state = t_state, default_layer = GLOVES_LAYER, default_icon_file = 'icons/mob/hands.dmi')
|
||||
overlays_standing[GLOVES_LAYER] = gloves.build_worn_icon(default_layer = GLOVES_LAYER, default_icon_file = 'icons/mob/clothing/hands.dmi')
|
||||
gloves_overlay = overlays_standing[GLOVES_LAYER]
|
||||
if(OFFSET_GLOVES in dna.species.offset_features)
|
||||
gloves_overlay.pixel_x += dna.species.offset_features[OFFSET_GLOVES][1]
|
||||
@@ -226,7 +223,7 @@ There are several things that need to be remembered:
|
||||
client.screen += glasses //Either way, add the item to the HUD
|
||||
update_observer_view(glasses,1)
|
||||
if(!(head && (head.flags_inv & HIDEEYES)) && !(wear_mask && (wear_mask.flags_inv & HIDEEYES)))
|
||||
overlays_standing[GLASSES_LAYER] = glasses.build_worn_icon(state = glasses.icon_state, default_layer = GLASSES_LAYER, default_icon_file = 'icons/mob/eyes.dmi')
|
||||
overlays_standing[GLASSES_LAYER] = glasses.build_worn_icon(default_layer = GLASSES_LAYER, default_icon_file = 'icons/mob/clothing/eyes.dmi', override_state = glasses.icon_state)
|
||||
var/mutable_appearance/glasses_overlay = overlays_standing[GLASSES_LAYER]
|
||||
if(glasses_overlay)
|
||||
if(OFFSET_GLASSES in dna.species.offset_features)
|
||||
@@ -253,7 +250,7 @@ There are several things that need to be remembered:
|
||||
client.screen += ears //add it to the client's screen
|
||||
update_observer_view(ears,1)
|
||||
|
||||
overlays_standing[EARS_LAYER] = ears.build_worn_icon(state = ears.icon_state, default_layer = EARS_LAYER, default_icon_file = 'icons/mob/ears.dmi')
|
||||
overlays_standing[EARS_LAYER] = ears.build_worn_icon(default_layer = EARS_LAYER, default_icon_file = 'icons/mob/ears.dmi')
|
||||
var/mutable_appearance/ears_overlay = overlays_standing[EARS_LAYER]
|
||||
if(OFFSET_EARS in dna.species.offset_features)
|
||||
ears_overlay.pixel_x += dna.species.offset_features[OFFSET_EARS][1]
|
||||
@@ -280,16 +277,13 @@ There are several things that need to be remembered:
|
||||
client.screen += shoes //add it to client's screen
|
||||
update_observer_view(shoes,1)
|
||||
|
||||
var/alt_icon = S.alternate_worn_icon || 'icons/mob/feet.dmi'
|
||||
var/alt_icon = S.mob_overlay_icon || 'icons/mob/clothing/feet.dmi'
|
||||
var/variation_flag = NONE
|
||||
if((DIGITIGRADE in dna.species.species_traits) && S.mutantrace_variation & STYLE_DIGITIGRADE)
|
||||
alt_icon = 'icons/mob/feet_digi.dmi'
|
||||
alt_icon = 'icons/mob/clothing/feet_digi.dmi'
|
||||
variation_flag |= STYLE_DIGITIGRADE
|
||||
|
||||
var/t_state = shoes.item_state
|
||||
if (!t_state)
|
||||
t_state = shoes.icon_state
|
||||
overlays_standing[SHOES_LAYER] = shoes.build_worn_icon(t_state, SHOES_LAYER, alt_icon, FALSE, NO_FEMALE_UNIFORM, variation_flag, FALSE)
|
||||
overlays_standing[SHOES_LAYER] = shoes.build_worn_icon(SHOES_LAYER, alt_icon, FALSE, NO_FEMALE_UNIFORM, variation_flag, FALSE)
|
||||
var/mutable_appearance/shoes_overlay = overlays_standing[SHOES_LAYER]
|
||||
if(OFFSET_SHOES in dna.species.offset_features)
|
||||
shoes_overlay.pixel_x += dna.species.offset_features[OFFSET_SHOES][1]
|
||||
@@ -312,7 +306,7 @@ There are several things that need to be remembered:
|
||||
var/t_state = s_store.item_state
|
||||
if(!t_state)
|
||||
t_state = s_store.icon_state
|
||||
overlays_standing[SUIT_STORE_LAYER] = mutable_appearance(((s_store.alternate_worn_icon) ? s_store.alternate_worn_icon : 'icons/mob/belt_mirror.dmi'), t_state, -SUIT_STORE_LAYER)
|
||||
overlays_standing[SUIT_STORE_LAYER] = mutable_appearance(((s_store.mob_overlay_icon) ? s_store.mob_overlay_icon : 'icons/mob/clothing/belt_mirror.dmi'), t_state, -SUIT_STORE_LAYER)
|
||||
var/mutable_appearance/s_store_overlay = overlays_standing[SUIT_STORE_LAYER]
|
||||
if(OFFSET_S_STORE in dna.species.offset_features)
|
||||
s_store_overlay.pixel_x += dna.species.offset_features[OFFSET_S_STORE][1]
|
||||
@@ -322,23 +316,31 @@ There are several things that need to be remembered:
|
||||
|
||||
|
||||
/mob/living/carbon/human/update_inv_head()
|
||||
..()
|
||||
remove_overlay(HEAD_LAYER)
|
||||
|
||||
if(!get_bodypart(BODY_ZONE_HEAD)) //Decapitated
|
||||
return
|
||||
|
||||
if(client && hud_used && hud_used.inv_slots[SLOT_BACK])
|
||||
var/obj/screen/inventory/inv = hud_used.inv_slots[SLOT_HEAD]
|
||||
inv.update_icon()
|
||||
|
||||
update_mutant_bodyparts()
|
||||
if(head)
|
||||
remove_overlay(HEAD_LAYER)
|
||||
var/obj/item/clothing/head/H = head
|
||||
var/alt_icon = H.alternate_worn_icon || 'icons/mob/head.dmi'
|
||||
var/alt_icon = H.mob_overlay_icon || 'icons/mob/clothing/head.dmi'
|
||||
var/muzzled = FALSE
|
||||
var/variation_flag = NONE
|
||||
if(("mam_snouts" in dna.species.default_features) && dna.features["mam_snouts"] != "None")
|
||||
if(dna.species.mutant_bodyparts["mam_snouts"] && dna.features["mam_snouts"] != "None")
|
||||
muzzled = TRUE
|
||||
if(!muzzled && ("snout" in dna.species.default_features) && dna.features["snout"] != "None")
|
||||
else if(dna.species.mutant_bodyparts["snout"] && dna.features["snout"] != "None")
|
||||
muzzled = TRUE
|
||||
if(muzzled && H.mutantrace_variation & STYLE_MUZZLE)
|
||||
alt_icon = 'icons/mob/head_muzzled.dmi'
|
||||
alt_icon = 'icons/mob/clothing/head_muzzled.dmi'
|
||||
variation_flag |= STYLE_MUZZLE
|
||||
|
||||
overlays_standing[HEAD_LAYER] = H.build_worn_icon(H.icon_state, HEAD_LAYER, alt_icon, FALSE, NO_FEMALE_UNIFORM, variation_flag, FALSE)
|
||||
overlays_standing[HEAD_LAYER] = H.build_worn_icon(HEAD_LAYER, alt_icon, FALSE, NO_FEMALE_UNIFORM, H.icon_state, variation_flag, FALSE)
|
||||
var/mutable_appearance/head_overlay = overlays_standing[HEAD_LAYER]
|
||||
|
||||
if(OFFSET_HEAD in dna.species.offset_features)
|
||||
@@ -360,11 +362,7 @@ There are several things that need to be remembered:
|
||||
client.screen += belt
|
||||
update_observer_view(belt)
|
||||
|
||||
var/t_state = belt.item_state
|
||||
if(!t_state)
|
||||
t_state = belt.icon_state
|
||||
|
||||
overlays_standing[BELT_LAYER] = belt.build_worn_icon(state = t_state, default_layer = BELT_LAYER, default_icon_file = 'icons/mob/belt.dmi')
|
||||
overlays_standing[BELT_LAYER] = belt.build_worn_icon(default_layer = BELT_LAYER, default_icon_file = 'icons/mob/clothing/belt.dmi')
|
||||
var/mutable_appearance/belt_overlay = overlays_standing[BELT_LAYER]
|
||||
if(OFFSET_BELT in dna.species.offset_features)
|
||||
belt_overlay.pixel_x += dna.species.offset_features[OFFSET_BELT][1]
|
||||
@@ -388,13 +386,13 @@ There are several things that need to be remembered:
|
||||
client.screen += wear_suit
|
||||
update_observer_view(wear_suit,1)
|
||||
|
||||
var/worn_icon = wear_suit.alternate_worn_icon || 'icons/mob/suit.dmi'
|
||||
var/worn_icon = wear_suit.mob_overlay_icon || 'icons/mob/clothing/suit.dmi'
|
||||
var/center = FALSE
|
||||
var/dimension_x = 32
|
||||
var/dimension_y = 32
|
||||
var/variation_flag = NONE
|
||||
var/datum/sprite_accessory/taur/T
|
||||
if("taur" in dna.species.mutant_bodyparts)
|
||||
if(dna.species.mutant_bodyparts["taur"])
|
||||
T = GLOB.taur_list[dna.features["taur"]]
|
||||
|
||||
if(S.mutantrace_variation)
|
||||
@@ -403,20 +401,20 @@ There are several things that need to be remembered:
|
||||
variation_flag |= S.mutantrace_variation & T.taur_mode || S.mutantrace_variation & T.alt_taur_mode
|
||||
switch(variation_flag)
|
||||
if(STYLE_HOOF_TAURIC)
|
||||
worn_icon = 'icons/mob/taur_hooved.dmi'
|
||||
worn_icon = 'icons/mob/clothing/taur_hooved.dmi'
|
||||
if(STYLE_SNEK_TAURIC)
|
||||
worn_icon = 'icons/mob/taur_naga.dmi'
|
||||
worn_icon = 'icons/mob/clothing/taur_naga.dmi'
|
||||
if(STYLE_PAW_TAURIC)
|
||||
worn_icon = 'icons/mob/taur_canine.dmi'
|
||||
worn_icon = 'icons/mob/clothing/taur_canine.dmi'
|
||||
if(worn_icon != init_worn_icon) //worn icon sprite was changed, taur offsets will have to be applied.
|
||||
center = T.center
|
||||
dimension_x = T.dimension_x
|
||||
dimension_y = T.dimension_y
|
||||
else if((DIGITIGRADE in dna.species.species_traits) && S.mutantrace_variation & STYLE_DIGITIGRADE) //not a taur, but digitigrade legs.
|
||||
worn_icon = 'icons/mob/suit_digi.dmi'
|
||||
worn_icon = 'icons/mob/clothing/suit_digi.dmi'
|
||||
variation_flag |= STYLE_DIGITIGRADE
|
||||
|
||||
overlays_standing[SUIT_LAYER] = S.build_worn_icon(wear_suit.icon_state, SUIT_LAYER, worn_icon, FALSE, NO_FEMALE_UNIFORM, variation_flag, FALSE)
|
||||
overlays_standing[SUIT_LAYER] = S.build_worn_icon(SUIT_LAYER, worn_icon, FALSE, NO_FEMALE_UNIFORM, wear_suit.icon_state, variation_flag, FALSE)
|
||||
var/mutable_appearance/suit_overlay = overlays_standing[SUIT_LAYER]
|
||||
if(OFFSET_SUIT in dna.species.offset_features)
|
||||
suit_overlay.pixel_x += dna.species.offset_features[OFFSET_SUIT][1]
|
||||
@@ -454,25 +452,32 @@ There are several things that need to be remembered:
|
||||
|
||||
|
||||
/mob/living/carbon/human/update_inv_wear_mask()
|
||||
..()
|
||||
remove_overlay(FACEMASK_LAYER)
|
||||
|
||||
if(!get_bodypart(BODY_ZONE_HEAD)) //Decapitated
|
||||
return
|
||||
|
||||
if(client && hud_used && hud_used.inv_slots[SLOT_WEAR_MASK])
|
||||
var/obj/screen/inventory/inv = hud_used.inv_slots[SLOT_WEAR_MASK]
|
||||
inv.update_icon()
|
||||
|
||||
if(wear_mask)
|
||||
var/obj/item/clothing/mask/M = wear_mask
|
||||
remove_overlay(FACEMASK_LAYER)
|
||||
var/alt_icon = M.alternate_worn_icon || 'icons/mob/mask.dmi'
|
||||
var/alt_icon = M.mob_overlay_icon || 'icons/mob/clothing/mask.dmi'
|
||||
var/muzzled = FALSE
|
||||
var/variation_flag = NONE
|
||||
if(head && (head.flags_inv & HIDEMASK))
|
||||
return
|
||||
if(("mam_snouts" in dna.species.default_features) && dna.features["mam_snouts"] != "None")
|
||||
if(dna.species.mutant_bodyparts["mam_snouts"] && dna.features["mam_snouts"] != "None")
|
||||
muzzled = TRUE
|
||||
if(!muzzled && ("snout" in dna.species.default_features) && dna.features["snout"] != "None")
|
||||
else if(dna.species.mutant_bodyparts["snout"] && dna.features["snout"] != "None")
|
||||
muzzled = TRUE
|
||||
if(muzzled && M.mutantrace_variation & STYLE_MUZZLE)
|
||||
alt_icon = 'icons/mob/mask_muzzled.dmi'
|
||||
alt_icon = 'icons/mob/clothing/mask_muzzled.dmi'
|
||||
variation_flag |= STYLE_MUZZLE
|
||||
|
||||
overlays_standing[FACEMASK_LAYER] = M.build_worn_icon(wear_mask.icon_state, FACEMASK_LAYER, alt_icon, FALSE, NO_FEMALE_UNIFORM, variation_flag, FALSE)
|
||||
var/mutable_appearance/mask_overlay = overlays_standing[FACEMASK_LAYER]
|
||||
var/mutable_appearance/mask_overlay = M.build_worn_icon(FACEMASK_LAYER, alt_icon, FALSE, NO_FEMALE_UNIFORM, wear_mask.icon_state, variation_flag, FALSE)
|
||||
|
||||
if(OFFSET_FACEMASK in dna.species.offset_features)
|
||||
mask_overlay.pixel_x += dna.species.offset_features[OFFSET_FACEMASK][1]
|
||||
@@ -554,27 +559,38 @@ covers:
|
||||
|
||||
By Remie Richards (yes I'm taking credit because this just removed 90% of the copypaste in update_icons())
|
||||
|
||||
state: A string to use as the state, this is FAR too complex to solve in this proc thanks to shitty old code
|
||||
so it's specified as an argument instead.
|
||||
override_state: A string to use as the state, otherwise item_state or icon_state will be used.
|
||||
|
||||
default_layer: The layer to draw this on if no other layer is specified
|
||||
|
||||
default_icon_file: The icon file to draw states from if no other icon file is specified
|
||||
|
||||
isinhands: If true then alternate_worn_icon is skipped so that default_icon_file is used,
|
||||
isinhands: If true then mob_overlay_icon is skipped so that default_icon_file is used,
|
||||
in this situation default_icon_file is expected to match either the lefthand_ or righthand_ file var
|
||||
|
||||
femalueuniform: A value matching a uniform item's fitted var, if this is anything but NO_FEMALE_UNIFORM, we
|
||||
generate/load female uniform sprites matching all previously decided variables
|
||||
|
||||
style_flags: mutant race appearance flags, mostly used for worn_overlays()
|
||||
|
||||
use_mob_overlay_icon: if FALSE, it will always use the default_icon_file even if mob_overlay_icon is present.
|
||||
|
||||
*/
|
||||
/obj/item/proc/build_worn_icon(state = "", default_layer = 0, default_icon_file = null, isinhands = FALSE, femaleuniform = NO_FEMALE_UNIFORM, style_flags = NONE, use_alt_icon = TRUE)
|
||||
/obj/item/proc/build_worn_icon(default_layer = 0, default_icon_file = null, isinhands = FALSE, femaleuniform = NO_FEMALE_UNIFORM, override_state, style_flags = NONE, use_mob_overlay_icon = TRUE)
|
||||
|
||||
var/t_state
|
||||
if(override_state)
|
||||
t_state = override_state
|
||||
else
|
||||
if(isinhands && item_state)
|
||||
t_state = item_state
|
||||
else
|
||||
t_state = icon_state
|
||||
|
||||
//Find a valid icon file from variables+arguments
|
||||
var/file2use
|
||||
if(!isinhands && alternate_worn_icon && use_alt_icon)
|
||||
file2use = alternate_worn_icon
|
||||
if(!isinhands && mob_overlay_icon && use_mob_overlay_icon)
|
||||
file2use = mob_overlay_icon
|
||||
if(!file2use)
|
||||
file2use = default_icon_file
|
||||
|
||||
@@ -587,13 +603,13 @@ generate/load female uniform sprites matching all previously decided variables
|
||||
|
||||
var/mutable_appearance/standing
|
||||
if(femaleuniform)
|
||||
standing = wear_female_version(state,file2use,layer2use,femaleuniform)
|
||||
standing = wear_female_version(t_state,file2use,layer2use,femaleuniform)
|
||||
if(!standing)
|
||||
standing = mutable_appearance(file2use, state, -layer2use)
|
||||
standing = mutable_appearance(file2use, t_state, -layer2use)
|
||||
|
||||
//Get the overlays for this item when it's being worn
|
||||
//eg: ammo counters, primed grenade flashes, etc.
|
||||
var/list/worn_overlays = worn_overlays(isinhands, file2use, state, style_flags)
|
||||
var/list/worn_overlays = worn_overlays(isinhands, file2use, t_state, style_flags)
|
||||
if(worn_overlays && worn_overlays.len)
|
||||
standing.overlays.Add(worn_overlays)
|
||||
|
||||
@@ -648,12 +664,11 @@ generate/load female uniform sprites matching all previously decided variables
|
||||
else
|
||||
. += "-not_coloured"
|
||||
|
||||
. += "-[gender]"
|
||||
. += "-[dna.features["body_model"]]"
|
||||
|
||||
|
||||
var/is_taur = FALSE
|
||||
var/mob/living/carbon/human/H = src
|
||||
if(("taur" in H.dna.species.mutant_bodyparts) && (H.dna.features["taur"] != "None"))
|
||||
if(dna.species.mutant_bodyparts["taur"] && dna.features["taur"] != "None")
|
||||
is_taur = TRUE
|
||||
|
||||
|
||||
|
||||
@@ -122,9 +122,9 @@
|
||||
update_inv_wear_mask()
|
||||
|
||||
/mob/living/carbon/wear_mask_update(obj/item/clothing/C, toggle_off = 1)
|
||||
if(C.tint || initial(C.tint))
|
||||
if(isclothing(C) && (C.tint || initial(C.tint)))
|
||||
update_tint()
|
||||
update_inv_wear_mask()
|
||||
return ..()
|
||||
|
||||
//handle stuff to update when a mob equips/unequips a headgear.
|
||||
/mob/living/carbon/proc/head_update(obj/item/I, forced)
|
||||
|
||||
@@ -377,9 +377,15 @@
|
||||
|
||||
var/turf/open/miasma_turf = deceasedturf
|
||||
|
||||
var/list/cached_gases = miasma_turf.air.gases
|
||||
var/datum/gas_mixture/stank = new
|
||||
|
||||
cached_gases[/datum/gas/miasma] += 0.1
|
||||
stank.gases[/datum/gas/miasma] = 0.1
|
||||
|
||||
stank.temperature = BODYTEMP_NORMAL
|
||||
|
||||
miasma_turf.assume_air(stank)
|
||||
|
||||
miasma_turf.air_update_turf()
|
||||
|
||||
/mob/living/carbon/proc/handle_blood()
|
||||
return
|
||||
@@ -427,7 +433,6 @@
|
||||
|
||||
/mob/living/carbon/handle_mutations_and_radiation()
|
||||
if(dna && dna.temporary_mutations.len)
|
||||
var/datum/mutation/human/HM
|
||||
for(var/mut in dna.temporary_mutations)
|
||||
if(dna.temporary_mutations[mut] < world.time)
|
||||
if(mut == UI_CHANGED)
|
||||
@@ -450,9 +455,9 @@
|
||||
dna.previous.Remove("blood_type")
|
||||
dna.temporary_mutations.Remove(mut)
|
||||
continue
|
||||
HM = GLOB.mutations_list[mut]
|
||||
HM.force_lose(src)
|
||||
dna.temporary_mutations.Remove(mut)
|
||||
for(var/datum/mutation/human/HM in dna.mutations)
|
||||
if(HM && HM.timed)
|
||||
dna.remove_mutation(HM.type)
|
||||
|
||||
radiation -= min(radiation, RAD_LOSS_PER_TICK)
|
||||
if(radiation > RAD_MOB_SAFE)
|
||||
@@ -508,10 +513,10 @@ GLOBAL_LIST_INIT(ballmer_windows_me_msg, list("Yo man, what if, we like, uh, put
|
||||
//this updates all special effects: stun, sleeping, knockdown, druggy, stuttering, etc..
|
||||
/mob/living/carbon/handle_status_effects()
|
||||
..()
|
||||
if(getStaminaLoss() && !combatmode)//CIT CHANGE - prevents stamina regen while combat mode is active
|
||||
adjustStaminaLoss(!CHECK_MOBILITY(src, MOBILITY_STAND) ? (recoveringstam ? -7.5 : -6) : -3)//CIT CHANGE - decreases adjuststaminaloss to stop stamina damage from being such a joke
|
||||
if(getStaminaLoss() && !(combat_flags & COMBAT_FLAG_COMBAT_ACTIVE)) //CIT CHANGE - prevents stamina regen while combat mode is active
|
||||
adjustStaminaLoss(!CHECK_MOBILITY(src, MOBILITY_STAND) ? ((combat_flags & COMBAT_FLAG_HARD_STAMCRIT) ? -7.5 : -6) : -3)//CIT CHANGE - decreases adjuststaminaloss to stop stamina damage from being such a joke
|
||||
|
||||
if(!recoveringstam && incomingstammult != 1)
|
||||
if(!(combat_flags & COMBAT_FLAG_HARD_STAMCRIT) && incomingstammult != 1)
|
||||
incomingstammult = max(0.01, incomingstammult)
|
||||
incomingstammult = min(1, incomingstammult*2)
|
||||
|
||||
|
||||
@@ -30,18 +30,19 @@
|
||||
|
||||
/mob/living/carbon/monkey/handle_mutations_and_radiation()
|
||||
if(radiation)
|
||||
if(radiation > RAD_MOB_MUTATE && prob((radiation - RAD_MOB_MUTATE) / 25))
|
||||
gorillize()
|
||||
return
|
||||
if(radiation > RAD_MONKEY_GORILLIZE)
|
||||
if(prob((((radiation - RAD_MONKEY_GORILLIZE + RAD_MOB_GORILLIZE_FACTOR)/RAD_MOB_GORILLIZE_FACTOR)^RAD_MONKEY_GORILLIZE_EXPONENT) - 1))
|
||||
gorillize()
|
||||
return
|
||||
if(radiation > RAD_MOB_KNOCKDOWN && prob(RAD_MOB_KNOCKDOWN_PROB))
|
||||
if(!recoveringstam)
|
||||
if(!(combat_flags & COMBAT_FLAG_HARD_STAMCRIT))
|
||||
emote("collapse")
|
||||
DefaultCombatKnockdown(RAD_MOB_KNOCKDOWN_AMOUNT)
|
||||
to_chat(src, "<span class='danger'>You feel weak.</span>")
|
||||
if(radiation > RAD_MOB_MUTATE)
|
||||
if(prob(1))
|
||||
to_chat(src, "<span class='danger'>You mutate!</span>")
|
||||
randmutb()
|
||||
easy_randmut(NEGATIVE+MINOR_NEGATIVE)
|
||||
emote("gasp")
|
||||
domutcheck()
|
||||
if(radiation > RAD_MOB_VOMIT && prob(RAD_MOB_VOMIT_PROB))
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
type_of_meat = /obj/item/reagent_containers/food/snacks/meat/slab/monkey
|
||||
gib_type = /obj/effect/decal/cleanable/blood/gibs
|
||||
unique_name = TRUE
|
||||
blocks_emissive = EMISSIVE_BLOCK_UNIQUE
|
||||
bodyparts = list(/obj/item/bodypart/chest/monkey, /obj/item/bodypart/head/monkey, /obj/item/bodypart/l_arm/monkey,
|
||||
/obj/item/bodypart/r_arm/monkey, /obj/item/bodypart/r_leg/monkey, /obj/item/bodypart/l_leg/monkey)
|
||||
hud_type = /datum/hud/monkey
|
||||
@@ -43,7 +44,7 @@
|
||||
|
||||
/mob/living/carbon/monkey/ComponentInitialize()
|
||||
. = ..()
|
||||
AddElement(/datum/element/mob_holder, "monkey", null, null, null, ITEM_SLOT_HEAD)
|
||||
AddElement(/datum/element/mob_holder, worn_state = "monkey", inv_slots = ITEM_SLOT_HEAD)
|
||||
|
||||
|
||||
/mob/living/carbon/monkey/Destroy()
|
||||
|
||||
@@ -45,7 +45,7 @@
|
||||
remove_overlay(LEGCUFF_LAYER)
|
||||
clear_alert("legcuffed")
|
||||
if(legcuffed)
|
||||
var/mutable_appearance/legcuffs = mutable_appearance('icons/mob/restraints.dmi', legcuffed.item_state, -LEGCUFF_LAYER)
|
||||
var/mutable_appearance/legcuffs = mutable_appearance('icons/mob/clothing/restraints.dmi', legcuffed.item_state, -LEGCUFF_LAYER)
|
||||
legcuffs.color = handcuffed.color
|
||||
legcuffs.pixel_y = 8
|
||||
|
||||
|
||||
@@ -42,15 +42,11 @@
|
||||
observers = null
|
||||
break
|
||||
|
||||
var/t_state = I.item_state
|
||||
if(!t_state)
|
||||
t_state = I.icon_state
|
||||
|
||||
var/icon_file = I.lefthand_file
|
||||
if(get_held_index_of_item(I) % 2 == 0)
|
||||
icon_file = I.righthand_file
|
||||
|
||||
hands += I.build_worn_icon(state = t_state, default_layer = HANDS_LAYER, default_icon_file = icon_file, isinhands = TRUE)
|
||||
hands += I.build_worn_icon(default_layer = HANDS_LAYER, default_icon_file = icon_file, isinhands = TRUE)
|
||||
|
||||
overlays_standing[HANDS_LAYER] = hands
|
||||
apply_overlay(HANDS_LAYER)
|
||||
@@ -100,7 +96,7 @@
|
||||
|
||||
if(wear_mask)
|
||||
if(!(head && (head.flags_inv & HIDEMASK)))
|
||||
overlays_standing[FACEMASK_LAYER] = wear_mask.build_worn_icon(state = wear_mask.icon_state, default_layer = FACEMASK_LAYER, default_icon_file = 'icons/mob/mask.dmi')
|
||||
overlays_standing[FACEMASK_LAYER] = wear_mask.build_worn_icon(default_layer = FACEMASK_LAYER, default_icon_file = 'icons/mob/clothing/mask.dmi', override_state = wear_mask.icon_state)
|
||||
update_hud_wear_mask(wear_mask)
|
||||
|
||||
apply_overlay(FACEMASK_LAYER)
|
||||
@@ -114,7 +110,7 @@
|
||||
|
||||
if(wear_neck)
|
||||
if(!(head && (head.flags_inv & HIDENECK)))
|
||||
overlays_standing[NECK_LAYER] = wear_neck.build_worn_icon(state = wear_neck.icon_state, default_layer = NECK_LAYER, default_icon_file = 'icons/mob/neck.dmi')
|
||||
overlays_standing[NECK_LAYER] = wear_neck.build_worn_icon(default_layer = NECK_LAYER, default_icon_file = 'icons/mob/clothing/neck.dmi', override_state = wear_mask.icon_state)
|
||||
update_hud_neck(wear_neck)
|
||||
|
||||
apply_overlay(NECK_LAYER)
|
||||
@@ -127,7 +123,7 @@
|
||||
inv.update_icon()
|
||||
|
||||
if(back)
|
||||
overlays_standing[BACK_LAYER] = back.build_worn_icon(state = back.icon_state, default_layer = BACK_LAYER, default_icon_file = 'icons/mob/back.dmi')
|
||||
overlays_standing[BACK_LAYER] = back.build_worn_icon(default_layer = BACK_LAYER, default_icon_file = 'icons/mob/clothing/back.dmi', override_state = back.icon_state)
|
||||
update_hud_back(back)
|
||||
|
||||
apply_overlay(BACK_LAYER)
|
||||
@@ -143,7 +139,7 @@
|
||||
inv.update_icon()
|
||||
|
||||
if(head)
|
||||
overlays_standing[HEAD_LAYER] = head.build_worn_icon(state = head.icon_state, default_layer = HEAD_LAYER, default_icon_file = 'icons/mob/head.dmi')
|
||||
overlays_standing[HEAD_LAYER] = head.build_worn_icon(default_layer = HEAD_LAYER, default_icon_file = 'icons/mob/clothing/head.dmi', override_state = head.icon_state)
|
||||
update_hud_head(head)
|
||||
|
||||
apply_overlay(HEAD_LAYER)
|
||||
@@ -152,7 +148,7 @@
|
||||
/mob/living/carbon/update_inv_handcuffed()
|
||||
remove_overlay(HANDCUFF_LAYER)
|
||||
if(handcuffed)
|
||||
var/mutable_appearance/cuffs = mutable_appearance('icons/mob/restraints.dmi', handcuffed.item_state, -HANDCUFF_LAYER)
|
||||
var/mutable_appearance/cuffs = mutable_appearance('icons/mob/clothing/restraints.dmi', handcuffed.item_state, -HANDCUFF_LAYER)
|
||||
cuffs.color = handcuffed.color
|
||||
|
||||
overlays_standing[HANDCUFF_LAYER] = cuffs
|
||||
@@ -162,7 +158,7 @@
|
||||
remove_overlay(LEGCUFF_LAYER)
|
||||
clear_alert("legcuffed")
|
||||
if(legcuffed)
|
||||
var/mutable_appearance/legcuffs = mutable_appearance('icons/mob/restraints.dmi', legcuffed.item_state, -LEGCUFF_LAYER)
|
||||
var/mutable_appearance/legcuffs = mutable_appearance('icons/mob/clothing/restraints.dmi', legcuffed.item_state, -LEGCUFF_LAYER)
|
||||
legcuffs.color = legcuffed.color
|
||||
|
||||
overlays_standing[LEGCUFF_LAYER] = legcuffs
|
||||
|
||||
@@ -125,7 +125,7 @@
|
||||
var/mob/living/carbon/human/H = user
|
||||
var/open = FALSE
|
||||
if(H.dna.features["wings"] != "None")
|
||||
if("wingsopen" in H.dna.species.mutant_bodyparts)
|
||||
if(H.dna.species.mutant_bodyparts["wingsopen"])
|
||||
open = TRUE
|
||||
H.CloseWings()
|
||||
else
|
||||
@@ -441,7 +441,7 @@
|
||||
to_chat(user, "You cannot send IC messages (muted).")
|
||||
return FALSE
|
||||
else if(!params)
|
||||
var/custom_emote = stripped_multiline_input("Choose an emote to display.", "Custom Emote", null, MAX_MESSAGE_LEN)
|
||||
var/custom_emote = stripped_multiline_input(user, "Choose an emote to display.", "Custom Emote", null, MAX_MESSAGE_LEN)
|
||||
if(custom_emote && !check_invalid(user, custom_emote))
|
||||
var/type = input("Is this a visible or hearable emote?") as null|anything in list("Visible", "Hearable")
|
||||
switch(type)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
/mob/living/Life(seconds, times_fired)
|
||||
/mob/living/proc/Life(seconds, times_fired)
|
||||
set waitfor = FALSE
|
||||
set invisibility = 0
|
||||
|
||||
if(digitalinvis)
|
||||
|
||||
@@ -118,22 +118,22 @@
|
||||
if(!CHECK_MOBILITY(src, MOBILITY_STAND) && CHECK_MOBILITY(L, MOBILITY_STAND))
|
||||
var/origtargetloc = L.loc
|
||||
if(!pulledby)
|
||||
if(attemptingcrawl)
|
||||
if(combat_flags & COMBAT_FLAG_ATTEMPTING_CRAWL)
|
||||
return TRUE
|
||||
if(getStaminaLoss() >= STAMINA_SOFTCRIT)
|
||||
if(IS_STAMCRIT(src))
|
||||
to_chat(src, "<span class='warning'>You're too exhausted to crawl under [L].</span>")
|
||||
return TRUE
|
||||
attemptingcrawl = TRUE
|
||||
ENABLE_BITFIELD(combat_flags, COMBAT_FLAG_ATTEMPTING_CRAWL)
|
||||
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) || CHECK_MOBILITY(src, MOBILITY_STAND))
|
||||
attemptingcrawl = FALSE
|
||||
DISABLE_BITFIELD(combat_flags, COMBAT_FLAG_ATTEMPTING_CRAWL)
|
||||
return TRUE
|
||||
var/src_passmob = (pass_flags & PASSMOB)
|
||||
pass_flags |= PASSMOB
|
||||
Move(origtargetloc)
|
||||
if(!src_passmob)
|
||||
pass_flags &= ~PASSMOB
|
||||
attemptingcrawl = FALSE
|
||||
DISABLE_BITFIELD(combat_flags, COMBAT_FLAG_ATTEMPTING_CRAWL)
|
||||
return TRUE
|
||||
//END OF CIT CHANGES
|
||||
|
||||
@@ -295,7 +295,7 @@
|
||||
if(!iscarbon(src))
|
||||
M.LAssailant = null
|
||||
else
|
||||
M.LAssailant = usr
|
||||
M.LAssailant = WEAKREF(usr)
|
||||
if(isliving(M))
|
||||
var/mob/living/L = M
|
||||
//Share diseases that are spread by touch
|
||||
@@ -368,9 +368,8 @@
|
||||
to_chat(src, "<span class='notice'>You have given up life and succumbed to death.</span>")
|
||||
death()
|
||||
|
||||
|
||||
/mob/living/incapacitated(ignore_restraints = FALSE, ignore_grab = FALSE, check_immobilized = FALSE)
|
||||
if(stat || IsUnconscious() || IsStun() || IsParalyzed() || recoveringstam || (check_immobilized && IsImmobilized()) || (!ignore_restraints && restrained(ignore_grab)))
|
||||
if(stat || IsUnconscious() || IsStun() || IsParalyzed() || (combat_flags & COMBAT_FLAG_HARD_STAMCRIT) || (check_immobilized && IsImmobilized()) || (!ignore_restraints && restrained(ignore_grab)))
|
||||
return TRUE
|
||||
|
||||
/mob/living/canUseStorage()
|
||||
@@ -490,7 +489,8 @@
|
||||
GLOB.alive_mob_list += src
|
||||
suiciding = 0
|
||||
stat = UNCONSCIOUS //the mob starts unconscious,
|
||||
blind_eyes(1)
|
||||
if(!eye_blind)
|
||||
blind_eyes(1)
|
||||
updatehealth() //then we check if the mob should wake up.
|
||||
update_mobility()
|
||||
update_sight()
|
||||
@@ -702,8 +702,8 @@
|
||||
|
||||
/mob/living/do_resist_grab(moving_resist, forced, silent = FALSE)
|
||||
. = ..()
|
||||
if(pulledby.grab_state)
|
||||
if(CHECK_MOBILITY(src, MOBILITY_STAND) && prob(30/pulledby.grab_state))
|
||||
if(pulledby.grab_state > GRAB_PASSIVE)
|
||||
if(CHECK_MOBILITY(src, MOBILITY_RESIST) && prob(30/pulledby.grab_state))
|
||||
visible_message("<span class='danger'>[src] has broken free of [pulledby]'s grip!</span>")
|
||||
pulledby.stop_pulling()
|
||||
return TRUE
|
||||
@@ -715,7 +715,7 @@
|
||||
return TRUE
|
||||
|
||||
/mob/living/proc/resist_buckle()
|
||||
buckled.user_unbuckle_mob(src,src)
|
||||
buckled?.user_unbuckle_mob(src,src)
|
||||
|
||||
/mob/living/proc/resist_fire()
|
||||
return
|
||||
@@ -794,6 +794,13 @@
|
||||
what.forceMove(drop_location())
|
||||
log_combat(src, who, "stripped [what] off")
|
||||
|
||||
if(Adjacent(who)) //update inventory window
|
||||
who.show_inv(src)
|
||||
else
|
||||
src << browse(null,"window=mob[REF(who)]")
|
||||
|
||||
who.update_equipment_speed_mods() // Updates speed in case stripped speed affecting item
|
||||
|
||||
// The src mob is trying to place an item on someone
|
||||
// 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)
|
||||
@@ -1185,3 +1192,25 @@
|
||||
|
||||
/mob/living/canface()
|
||||
return ..() && CHECK_MOBILITY(src, MOBILITY_MOVE)
|
||||
|
||||
/mob/living/proc/set_gender(ngender = NEUTER, silent = FALSE, update_icon = TRUE, forced = FALSE)
|
||||
if(forced || (!ckey || client?.prefs.cit_toggles & (ngender == FEMALE ? FORCED_FEM : FORCED_MASC)))
|
||||
gender = ngender
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/mob/living/vv_get_header()
|
||||
. = ..()
|
||||
var/refid = REF(src)
|
||||
. += {"
|
||||
<br><font size='1'>[VV_HREF_TARGETREF_1V(refid, VV_HK_BASIC_EDIT, "[ckey || "no ckey"]", NAMEOF(src, ckey))] / [VV_HREF_TARGETREF_1V(refid, VV_HK_BASIC_EDIT, "[real_name || "no real name"]", NAMEOF(src, real_name))]</font>
|
||||
<br><font size='1'>
|
||||
BRUTE:<font size='1'><a href='?_src_=vars;[HrefToken()];mobToDamage=[refid];adjustDamage=brute' id='brute'>[getBruteLoss()]</a>
|
||||
FIRE:<font size='1'><a href='?_src_=vars;[HrefToken()];mobToDamage=[refid];adjustDamage=fire' id='fire'>[getFireLoss()]</a>
|
||||
TOXIN:<font size='1'><a href='?_src_=vars;[HrefToken()];mobToDamage=[refid];adjustDamage=toxin' id='toxin'>[getToxLoss()]</a>
|
||||
OXY:<font size='1'><a href='?_src_=vars;[HrefToken()];mobToDamage=[refid];adjustDamage=oxygen' id='oxygen'>[getOxyLoss()]</a>
|
||||
CLONE:<font size='1'><a href='?_src_=vars;[HrefToken()];mobToDamage=[refid];adjustDamage=clone' id='clone'>[getCloneLoss()]</a>
|
||||
BRAIN:<font size='1'><a href='?_src_=vars;[HrefToken()];mobToDamage=[refid];adjustDamage=brain' id='brain'>[getOrganLoss(ORGAN_SLOT_BRAIN)]</a>
|
||||
STAMINA:<font size='1'><a href='?_src_=vars;[HrefToken()];mobToDamage=[refid];adjustDamage=stamina' id='stamina'>[getStaminaLoss()]</a>
|
||||
</font>
|
||||
"}
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
// This file has a weird name, but it's for anything related to the checks for shields, blocking, dodging, and similar "stop this attack before it actually impacts the target" as opposed to "defend once it has hit".
|
||||
|
||||
/*
|
||||
/// Bitflags for check_block() and handle_block(). Meant to be combined. You can be hit and still reflect, for example, if you do not use BLOCK_SUCCESS.
|
||||
/// Attack was not blocked
|
||||
#define BLOCK_NONE NONE
|
||||
/// Attack was blocked, do not do damage. THIS FLAG MUST BE THERE FOR DAMAGE/EFFECT PREVENTION!
|
||||
#define BLOCK_SUCCESS (1<<1)
|
||||
|
||||
/// The below are for "metadata" on "how" the attack was blocked.
|
||||
|
||||
/// Attack was and should be reflected (NOTE: the SHOULD here is important, as it says "the thing blocking isn't handling the reflecting for you so do it yourself"!)
|
||||
#define BLOCK_SHOULD_REFLECT (1<<2)
|
||||
/// Attack was manually redirected (including reflected) by any means by the defender. For when YOU are handling the reflection, rather than the thing hitting you. (see sleeping carp)
|
||||
#define BLOCK_REDIRECTED (1<<3)
|
||||
/// Attack was blocked by something like a shield.
|
||||
#define BLOCK_PHYSICAL_EXTERNAL (1<<4)
|
||||
/// Attack was blocked by something worn on you.
|
||||
#define BLOCK_PHYSICAL_INTERNAL (1<<5)
|
||||
/// Attack should pass through. Like SHOULD_REFLECT but for.. well, passing through harmlessly.
|
||||
#define BLOCK_SHOULD_PASSTHROUGH (1<<6)
|
||||
/// Attack outright missed because the target dodged. Should usually be combined with SHOULD_PASSTHROUGH or something (see martial arts)
|
||||
#define BLOCK_TARGET_DODGED (1<<7)
|
||||
*/
|
||||
|
||||
///Check whether or not we can block, without "triggering" a block. Basically run checks without effects like depleting shields. Wrapper for do_run_block(). The arguments on that means the same as for this.
|
||||
/mob/living/proc/check_block(atom/object, damage, attack_text = "the attack", attack_type, armour_penetration, mob/attacker, def_zone, list/return_list)
|
||||
return do_run_block(FALSE, object, damage, attack_text, attack_type, armour_penetration, attacker, check_zone(def_zone), return_list)
|
||||
|
||||
/// Runs a block "sequence", effectively checking and then doing effects if necessary. Wrapper for do_run_block(). The arguments on that means the same as for this.
|
||||
/mob/living/proc/run_block(atom/object, damage, attack_text = "the attack", attack_type, armour_penetration, mob/attacker, def_zone, list/return_list)
|
||||
return do_run_block(TRUE, object, damage, attack_text, attack_type, armour_penetration, attacker, check_zone(def_zone), return_list)
|
||||
|
||||
/** The actual proc for block checks. DO NOT USE THIS DIRECTLY UNLESS YOU HAVE VERY GOOD REASON TO. To reduce copypaste for differences between handling for real attacks and virtual checks.
|
||||
* Automatically checks all held items for /obj/item/proc/run_block() with the same parameters.
|
||||
* @params
|
||||
* real_attack - If this attack is real. This one is quirky; If it's real, run_block is called. If it's not, check_block is called and none of the regular checks happen, and this is effectively only useful
|
||||
* for populating return_list with blocking metadata.
|
||||
* object - Whatever /atom is actually hitting us, in essence. For example, projectile if gun, item if melee, structure/whatever if it's a thrown, etc.
|
||||
* damage - The nominal damage this would do if it was to hit. Obviously doesn't take into effect explosions/magic/similar things.. unless you implement it to raise the value.
|
||||
* attack_text - The text that this attack should show, in the context of something like "[src] blocks [attack_text]!"
|
||||
* attack_type - See __DEFINES/combat.dm - Attack types, to distinguish between, for example, someone throwing an item at us vs bashing us with it.
|
||||
* armour_penetration - 0-100 value of how effectively armor penetrating the attack should be.
|
||||
* attacker - Set to the mob attacking IF KNOWN. Do not expect this to always be set!
|
||||
* def_zone - The zone this'll impact.
|
||||
* return_list - If something wants to grab things from what items/whatever put into list/block_return on obj/item/run_block and the comsig, pass in a list so you can grab anything put in it after block runs.
|
||||
*/
|
||||
/mob/living/proc/do_run_block(real_attack = TRUE, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, list/return_list = list())
|
||||
// Component signal block runs have highest priority.. for now.
|
||||
. = SEND_SIGNAL(src, COMSIG_LIVING_RUN_BLOCK, real_attack, object, damage, attack_text, attack_type, armour_penetration, attacker, def_zone, return_list)
|
||||
if((. & BLOCK_SUCCESS) && !(. & BLOCK_CONTINUE_CHAIN))
|
||||
return
|
||||
var/list/obj/item/tocheck = get_blocking_items()
|
||||
sortTim(tocheck, /proc/cmp_item_block_priority_asc)
|
||||
// i don't like this
|
||||
var/block_chance_modifier = round(damage / -3)
|
||||
if(real_attack)
|
||||
for(var/obj/item/I in tocheck)
|
||||
// i don't like this too
|
||||
var/final_block_chance = I.block_chance - (CLAMP((armour_penetration-I.armour_penetration)/2,0,100)) + block_chance_modifier //So armour piercing blades can still be parried by other blades, for example
|
||||
var/results = I.run_block(src, object, damage, attack_text, attack_type, armour_penetration, attacker, def_zone, final_block_chance, return_list)
|
||||
. |= results
|
||||
if((results & BLOCK_SUCCESS) && !(results & BLOCK_CONTINUE_CHAIN))
|
||||
break
|
||||
else
|
||||
for(var/obj/item/I in tocheck)
|
||||
// i don't like this too
|
||||
var/final_block_chance = I.block_chance - (CLAMP((armour_penetration-I.armour_penetration)/2,0,100)) + block_chance_modifier //So armour piercing blades can still be parried by other blades, for example
|
||||
I.check_block(src, object, damage, attack_text, attack_type, armour_penetration, attacker, def_zone, final_block_chance, return_list)
|
||||
|
||||
/// Gets an unsortedlist of objects to run block checks on.
|
||||
/mob/living/proc/get_blocking_items()
|
||||
. = list()
|
||||
for(var/obj/item/I in held_items)
|
||||
// this is a bad check but i am not removing it until a better catchall is made
|
||||
if(istype(I, /obj/item/clothing))
|
||||
continue
|
||||
. |= I
|
||||
|
||||
/obj/item
|
||||
/// The 0% to 100% chance for the default implementation of random block rolls.
|
||||
var/block_chance = 0
|
||||
/// Block priority, higher means we check this higher in the "chain".
|
||||
var/block_priority = BLOCK_PRIORITY_DEFAULT
|
||||
|
||||
/// Runs block and returns flag for do_run_block to process.
|
||||
/obj/item/proc/run_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
|
||||
SEND_SIGNAL(src, COMSIG_ITEM_RUN_BLOCK, owner, object, damage, attack_text, attack_type, armour_penetration, attacker, def_zone, final_block_chance, block_return)
|
||||
if(prob(final_block_chance))
|
||||
owner.visible_message("<span class='danger'>[owner] blocks [attack_text] with [src]!</span>")
|
||||
return BLOCK_SUCCESS | BLOCK_PHYSICAL_EXTERNAL
|
||||
return BLOCK_NONE
|
||||
|
||||
/// Returns block information using list/block_return. Used for check_block() on mobs.
|
||||
/obj/item/proc/check_block(mob/living/owner, atom/object, damage, attack_text, attack_type, armour_penetration, mob/attacker, def_zone, final_block_chance, list/block_return)
|
||||
SEND_SIGNAL(src, COMSIG_ITEM_CHECK_BLOCK, owner, object, damage, attack_text, attack_type, armour_penetration, attacker, def_zone, final_block_chance, block_return)
|
||||
var/existing = block_return[BLOCK_RETURN_NORMAL_BLOCK_CHANCE]
|
||||
block_return[BLOCK_RETURN_NORMAL_BLOCK_CHANCE] = max(existing || 0, final_block_chance)
|
||||
@@ -0,0 +1,88 @@
|
||||
/mob/living/ComponentInitialize()
|
||||
. = ..()
|
||||
RegisterSignal(src, SIGNAL_TRAIT(TRAIT_COMBAT_MODE_LOCKED), .proc/update_combat_lock)
|
||||
|
||||
/mob/living/proc/update_combat_lock()
|
||||
var/locked = HAS_TRAIT(src, TRAIT_COMBAT_MODE_LOCKED)
|
||||
var/desired = (combat_flags & COMBAT_FLAG_COMBAT_TOGGLED)
|
||||
var/actual = (combat_flags & COMBAT_FLAG_COMBAT_ACTIVE)
|
||||
if(actual)
|
||||
if(locked)
|
||||
disable_combat_mode(FALSE, TRUE, FALSE, FALSE)
|
||||
else if(!desired)
|
||||
disable_combat_mode(TRUE, TRUE, FALSE, FALSE)
|
||||
else
|
||||
if(desired && !locked)
|
||||
enable_combat_mode(FALSE, TRUE, FALSE, FALSE)
|
||||
update_combat_mode_icon()
|
||||
|
||||
/mob/living/proc/disable_combat_mode(silent = TRUE, was_forced = FALSE, visible = FALSE, update_icon = TRUE)
|
||||
if(!(combat_flags & COMBAT_FLAG_COMBAT_ACTIVE))
|
||||
return
|
||||
DISABLE_BITFIELD(combat_flags, COMBAT_FLAG_COMBAT_ACTIVE)
|
||||
SEND_SIGNAL(src, COMSIG_LIVING_COMBAT_DISABLED, was_forced)
|
||||
if(visible)
|
||||
visible_message("<span class='warning'>[src] goes limp.</span>", "<span class='warning'>Your muscles are forcibly relaxed!</span>")
|
||||
else if(!silent)
|
||||
to_chat(src, was_forced? "<span class='warning'>Your muscles are forcibly relaxed!</span>" : "<span class='warning'>You relax your muscles.</span>")
|
||||
if(update_icon)
|
||||
update_combat_mode_icon()
|
||||
|
||||
/mob/living/proc/enable_combat_mode(silent = TRUE, was_forced = FALSE, visible = FALSE, update_icon = TRUE)
|
||||
if(combat_flags & COMBAT_FLAG_COMBAT_ACTIVE)
|
||||
return
|
||||
ENABLE_BITFIELD(combat_flags, COMBAT_FLAG_COMBAT_ACTIVE)
|
||||
SEND_SIGNAL(src, COMSIG_LIVING_COMBAT_ENABLED, was_forced)
|
||||
if(visible)
|
||||
visible_message("<span class='warning'>[src] drops into a combative stance!</span>", "<span class='warning'>You drop into a combative stance!</span>")
|
||||
else if(!silent)
|
||||
to_chat(src, was_forced? "<span class='warning'>Your muscles reflexively tighten!</span>" : "<span class='warning'>You tighten your muscles.</span>")
|
||||
if(update_icon)
|
||||
update_combat_mode_icon()
|
||||
|
||||
/// Updates the combat mode HUD icon.
|
||||
/mob/living/proc/update_combat_mode_icon()
|
||||
var/obj/screen/combattoggle/T = locate() in hud_used?.static_inventory
|
||||
T?.update_icon()
|
||||
|
||||
/// Enables intentionally being in combat mode. Please try not to use this proc for feedback whenever possible.
|
||||
/mob/living/proc/enable_intentional_combat_mode(silent = TRUE, visible = FALSE)
|
||||
if((combat_flags & COMBAT_FLAG_COMBAT_TOGGLED) && (combat_flags & COMBAT_FLAG_COMBAT_ACTIVE))
|
||||
return
|
||||
ENABLE_BITFIELD(combat_flags, COMBAT_FLAG_COMBAT_TOGGLED)
|
||||
if(!HAS_TRAIT(src, TRAIT_COMBAT_MODE_LOCKED) && !(combat_flags & COMBAT_FLAG_COMBAT_ACTIVE))
|
||||
enable_combat_mode(silent, FALSE, visible, FALSE)
|
||||
update_combat_mode_icon()
|
||||
client?.show_popup_menus = FALSE
|
||||
return TRUE
|
||||
|
||||
/// Disables intentionally being in combat mode. Please try not to use this proc for feedback whenever possible.
|
||||
/mob/living/proc/disable_intentional_combat_mode(silent = TRUE, visible = FALSE)
|
||||
if(!(combat_flags & COMBAT_FLAG_COMBAT_TOGGLED) && !(combat_flags & COMBAT_FLAG_COMBAT_ACTIVE))
|
||||
return
|
||||
DISABLE_BITFIELD(combat_flags, COMBAT_FLAG_COMBAT_TOGGLED)
|
||||
if(combat_flags & COMBAT_FLAG_COMBAT_ACTIVE)
|
||||
disable_combat_mode(silent, FALSE, visible, FALSE)
|
||||
update_combat_mode_icon()
|
||||
client?.show_popup_menus = TRUE
|
||||
return TRUE
|
||||
|
||||
/// Toggles whether the user is intentionally in combat mode. THIS should be the proc you generally use! Has built in visual/to other player feedback, as well as an audible cue to ourselves.
|
||||
/mob/living/proc/user_toggle_intentional_combat_mode(visible = TRUE)
|
||||
var/old = (combat_flags & COMBAT_FLAG_COMBAT_TOGGLED)
|
||||
if(old)
|
||||
disable_intentional_combat_mode()
|
||||
playsound_local(src, 'sound/misc/ui_toggleoff.ogg', 50, FALSE, pressure_affected = FALSE) //Slightly modified version of the above!
|
||||
else if(CAN_TOGGLE_COMBAT_MODE(src))
|
||||
enable_intentional_combat_mode()
|
||||
var/current = (combat_flags & COMBAT_FLAG_COMBAT_ACTIVE) //because we could be locked
|
||||
if(current != old) //only sound effect if you succeeded. Could have the feedback system be better but shrug, someone else can do it.
|
||||
if(current)
|
||||
playsound_local(src, 'sound/misc/ui_toggle.ogg', 50, FALSE, pressure_affected = FALSE) //Sound from interbay!
|
||||
if(visible)
|
||||
if(world.time >= combatmessagecooldown)
|
||||
combatmessagecooldown = world.time + 10 SECONDS
|
||||
if(a_intent != INTENT_HELP)
|
||||
visible_message("<span class='warning'>[src] [resting ? "tenses up" : (prob(95)? "drops into a combative stance" : (prob(95)? "poses aggressively" : "asserts dominance with their pose"))].</span>")
|
||||
else
|
||||
visible_message("<span class='notice'>[src] [pick("looks","seems","goes")] [pick("alert","attentive","vigilant")].</span>")
|
||||
@@ -36,48 +36,44 @@
|
||||
/mob/living/proc/on_hit(obj/item/projectile/P)
|
||||
return BULLET_ACT_HIT
|
||||
|
||||
/mob/living/proc/check_shields(atom/AM, damage, attack_text = "the attack", attack_type = MELEE_ATTACK, armour_penetration = 0)
|
||||
var/block_chance_modifier = round(damage / -3)
|
||||
for(var/obj/item/I in held_items)
|
||||
if(!istype(I, /obj/item/clothing))
|
||||
var/final_block_chance = I.block_chance - (CLAMP((armour_penetration-I.armour_penetration)/2,0,100)) + block_chance_modifier //So armour piercing blades can still be parried by other blades, for example
|
||||
if(I.hit_reaction(src, AM, attack_text, final_block_chance, damage, attack_type))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/mob/living/proc/check_reflect(def_zone) //Reflection checks for anything in your hands, based on the reflection chance of the object(s)
|
||||
for(var/obj/item/I in held_items)
|
||||
if(I.IsReflect(def_zone))
|
||||
return TRUE
|
||||
return FALSE
|
||||
|
||||
/mob/living/proc/reflect_bullet_check(obj/item/projectile/P, def_zone)
|
||||
if(P.is_reflectable && check_reflect(def_zone)) // Checks if you've passed a reflection% check
|
||||
visible_message("<span class='danger'>The [P.name] gets reflected by [src]!</span>", \
|
||||
"<span class='userdanger'>The [P.name] gets reflected by [src]!</span>")
|
||||
// Find a turf near or on the original location to bounce to
|
||||
if(P.starting)
|
||||
var/new_x = P.starting.x + pick(0, 0, 0, 0, 0, -1, 1, -2, 2)
|
||||
var/new_y = P.starting.y + pick(0, 0, 0, 0, 0, -1, 1, -2, 2)
|
||||
var/turf/curloc = get_turf(src)
|
||||
// redirect the projectile
|
||||
P.original = locate(new_x, new_y, P.z)
|
||||
P.starting = curloc
|
||||
P.firer = src
|
||||
P.yo = new_y - curloc.y
|
||||
P.xo = new_x - curloc.x
|
||||
var/new_angle_s = P.Angle + rand(120,240)
|
||||
while(new_angle_s > 180) // Translate to regular projectile degrees
|
||||
new_angle_s -= 360
|
||||
P.setAngle(new_angle_s)
|
||||
return TRUE
|
||||
return FALSE
|
||||
/mob/living/proc/handle_projectile_attack_redirection(obj/item/projectile/P, redirection_mode, silent = FALSE)
|
||||
P.ignore_source_check = TRUE
|
||||
switch(redirection_mode)
|
||||
if(REDIRECT_METHOD_DEFLECT)
|
||||
P.setAngle(SIMPLIFY_DEGREES(P.Angle + rand(120, 240)))
|
||||
if(!silent)
|
||||
visible_message("<span class='danger'>[P] gets deflected by [src]!</span>", \
|
||||
"<span class='userdanger'>[P] gets deflected by [src]!</span>")
|
||||
if(REDIRECT_METHOD_REFLECT)
|
||||
P.setAngle(SIMPLIFY_DEGREES(P.Angle + 180))
|
||||
if(!silent)
|
||||
visible_message("<span class='danger'>[P] gets reflected by [src]!</span>", \
|
||||
"<span class='userdanger'>[P] gets reflected by [src]!</span>")
|
||||
if(REDIRECT_METHOD_PASSTHROUGH)
|
||||
if(!silent)
|
||||
visible_message("<span class='danger'>[P] passes through [src]!</span>", \
|
||||
"<span class='userdanger'>[P] passes through [src]!</span>")
|
||||
return
|
||||
if(REDIRECT_METHOD_RETURN_TO_SENDER)
|
||||
if(!silent)
|
||||
visible_message("<span class='danger'>[src] deflects [P] back at their attacker!</span>", \
|
||||
"<span class='userdanger'>[src] deflects [P] back at their attacker!</span>")
|
||||
if(P.firer)
|
||||
P.setAngle(Get_Angle(src, P.firer))
|
||||
else
|
||||
P.setAngle(SIMPLIFY_DEGREES(P.Angle + 180))
|
||||
else
|
||||
CRASH("Invalid rediretion mode [redirection_mode]")
|
||||
|
||||
/mob/living/bullet_act(obj/item/projectile/P, def_zone)
|
||||
if(P.original != src || P.firer != src) //try to block or reflect the bullet, can't do so when shooting oneself
|
||||
if(reflect_bullet_check(P, def_zone))
|
||||
return BULLET_ACT_FORCE_PIERCE // complete projectile permutation
|
||||
if(check_shields(P, P.damage, "the [P.name]", PROJECTILE_ATTACK, P.armour_penetration))
|
||||
var/list/returnlist = list()
|
||||
var/returned = run_block(P, P.damage, "the [P.name]", ATTACK_TYPE_PROJECTILE, P.armour_penetration, P.firer, def_zone, returnlist)
|
||||
if(returned & BLOCK_SHOULD_REDIRECT)
|
||||
handle_projectile_attack_redirection(P, returnlist[BLOCK_RETURN_REDIRECT_METHOD])
|
||||
if(returned & BLOCK_REDIRECTED)
|
||||
return BULLET_ACT_FORCE_PIERCE
|
||||
if(returned & BLOCK_SUCCESS)
|
||||
P.on_hit(src, 100, def_zone)
|
||||
return BULLET_ACT_BLOCK
|
||||
var/armor = run_armor_check(def_zone, P.flag, null, null, P.armour_penetration, null)
|
||||
@@ -108,12 +104,14 @@
|
||||
return FALSE
|
||||
|
||||
/mob/living/hitby(atom/movable/AM, skipcatch, hitpush = TRUE, blocked = FALSE, datum/thrownthing/throwingdatum)
|
||||
// Throwingdatum can be null if someone had an accident() while slipping with an item in hand.
|
||||
var/obj/item/I
|
||||
var/throwpower = 30
|
||||
if(isitem(AM))
|
||||
I = AM
|
||||
throwpower = I.throwforce
|
||||
if(check_shields(AM, throwpower, "\the [AM.name]", THROWN_PROJECTILE_ATTACK))
|
||||
var/impacting_zone = ran_zone(BODY_ZONE_CHEST, 65)//Hits a random part of the body, geared towards the chest
|
||||
if(run_block(AM, throwpower, "\the [AM.name]", ATTACK_TYPE_THROWN, 0, throwingdatum?.thrower, impacting_zone) & BLOCK_SUCCESS)
|
||||
hitpush = FALSE
|
||||
skipcatch = TRUE
|
||||
blocked = TRUE
|
||||
@@ -124,10 +122,9 @@
|
||||
if(I)
|
||||
if(!skipcatch && isturf(I.loc) && catch_item(I))
|
||||
return TRUE
|
||||
var/zone = ran_zone(BODY_ZONE_CHEST, 65)//Hits a random part of the body, geared towards the chest
|
||||
var/dtype = BRUTE
|
||||
var/volume = I.get_volume_by_throwforce_and_or_w_class()
|
||||
SEND_SIGNAL(I, COMSIG_MOVABLE_IMPACT_ZONE, src, zone)
|
||||
SEND_SIGNAL(I, COMSIG_MOVABLE_IMPACT_ZONE, src, impacting_zone)
|
||||
dtype = I.damtype
|
||||
|
||||
if (I.throwforce > 0) //If the weapon's throwforce is greater than zero...
|
||||
@@ -145,8 +142,8 @@
|
||||
if(!blocked)
|
||||
visible_message("<span class='danger'>[src] has been hit by [I].</span>", \
|
||||
"<span class='userdanger'>[src] has been hit by [I].</span>")
|
||||
var/armor = run_armor_check(zone, "melee", "Your armor has protected your [parse_zone(zone)].", "Your armor has softened hit to your [parse_zone(zone)].",I.armour_penetration)
|
||||
apply_damage(I.throwforce, dtype, zone, armor)
|
||||
var/armor = run_armor_check(impacting_zone, "melee", "Your armor has protected your [parse_zone(impacting_zone)].", "Your armor has softened hit to your [parse_zone(impacting_zone)].",I.armour_penetration)
|
||||
apply_damage(I.throwforce, dtype, impacting_zone, armor)
|
||||
if(I.thrownby)
|
||||
log_combat(I.thrownby, src, "threw and hit", I)
|
||||
else
|
||||
@@ -193,17 +190,6 @@
|
||||
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))
|
||||
@@ -283,7 +269,7 @@
|
||||
/mob/living/attack_hand(mob/user)
|
||||
..() //Ignoring parent return value here.
|
||||
SEND_SIGNAL(src, COMSIG_MOB_ATTACK_HAND, user)
|
||||
if((user != src) && user.a_intent != INTENT_HELP && check_shields(user, 0, user.name, attack_type = UNARMED_ATTACK))
|
||||
if((user != src) && user.a_intent != INTENT_HELP && (run_block(user, 0, user.name, ATTACK_TYPE_UNARMED | ATTACK_TYPE_MELEE, null, user, check_zone(user.zone_selected)) & BLOCK_SUCCESS))
|
||||
log_combat(user, src, "attempted to touch")
|
||||
visible_message("<span class='warning'>[user] attempted to touch [src]!</span>")
|
||||
return TRUE
|
||||
@@ -294,7 +280,7 @@
|
||||
to_chat(user, "<span class='notice'>You don't want to hurt [src]!</span>")
|
||||
return TRUE
|
||||
var/hulk_verb = pick("smash","pummel")
|
||||
if(user != src && check_shields(user, 15, "the [hulk_verb]ing"))
|
||||
if(user != src && (run_block(user, 15, "the [hulk_verb]ing", ATTACK_TYPE_MELEE, null, user, check_zone(user.zone_selected)) & BLOCK_SUCCESS))
|
||||
return TRUE
|
||||
..()
|
||||
return FALSE
|
||||
@@ -309,14 +295,14 @@
|
||||
M.Feedstop()
|
||||
return // can't attack while eating!
|
||||
|
||||
if(HAS_TRAIT(src, TRAIT_PACIFISM))
|
||||
if(HAS_TRAIT(M, TRAIT_PACIFISM))
|
||||
to_chat(M, "<span class='notice'>You don't want to hurt anyone!</span>")
|
||||
return FALSE
|
||||
|
||||
var/damage = rand(5, 35)
|
||||
if(M.is_adult)
|
||||
damage = rand(20, 40)
|
||||
if(check_shields(M, damage, "the [M.name]"))
|
||||
if(run_block(M, damage, "the [M.name]", ATTACK_TYPE_MELEE, null, M, check_zone(M.zone_selected)) & BLOCK_SUCCESS)
|
||||
return FALSE
|
||||
|
||||
if (stat != DEAD)
|
||||
@@ -335,7 +321,7 @@
|
||||
if(HAS_TRAIT(M, TRAIT_PACIFISM))
|
||||
to_chat(M, "<span class='notice'>You don't want to hurt anyone!</span>")
|
||||
return FALSE
|
||||
if(check_shields(M, rand(M.melee_damage_lower, M.melee_damage_upper), "the [M.name]", MELEE_ATTACK, M.armour_penetration))
|
||||
if(run_block(M, rand(M.melee_damage_lower, M.melee_damage_upper), "the [M.name]", ATTACK_TYPE_MELEE, M.armour_penetration, M, check_zone(M.zone_selected)) & BLOCK_SUCCESS)
|
||||
return FALSE
|
||||
if(M.attack_sound)
|
||||
playsound(loc, M.attack_sound, 50, 1, 1)
|
||||
@@ -345,17 +331,15 @@
|
||||
log_combat(M, src, "attacked")
|
||||
return TRUE
|
||||
|
||||
|
||||
/mob/living/attack_paw(mob/living/carbon/monkey/M)
|
||||
if (M.a_intent == INTENT_HARM)
|
||||
if(HAS_TRAIT(M, TRAIT_PACIFISM))
|
||||
to_chat(M, "<span class='notice'>You don't want to hurt anyone!</span>")
|
||||
return FALSE
|
||||
|
||||
if(M.is_muzzled() || (M.wear_mask && M.wear_mask.flags_cover & MASKCOVERSMOUTH))
|
||||
to_chat(M, "<span class='warning'>You can't bite with your mouth covered!</span>")
|
||||
return FALSE
|
||||
if(check_shields(M, 0, "the [M.name]"))
|
||||
if(run_block(M, 0, "the [M.name]", ATTACK_TYPE_MELEE | ATTACK_TYPE_UNARMED, M, check_zone(M.zone_selected)) & BLOCK_SUCCESS)
|
||||
return FALSE
|
||||
M.do_attack_animation(src, ATTACK_EFFECT_BITE)
|
||||
if (prob(75))
|
||||
@@ -379,7 +363,7 @@
|
||||
if(HAS_TRAIT(L, TRAIT_PACIFISM))
|
||||
to_chat(L, "<span class='notice'>You don't want to hurt anyone!</span>")
|
||||
return FALSE
|
||||
if(L != src && check_shields(L, rand(1, 3), "the [L.name]"))
|
||||
if(L != src && (run_block(L, rand(1, 3), "the [L.name]", ATTACK_TYPE_MELEE | ATTACK_TYPE_UNARMED, L, check_zone(L.zone_selected)) & BLOCK_SUCCESS))
|
||||
return FALSE
|
||||
L.do_attack_animation(src)
|
||||
if(prob(90))
|
||||
@@ -393,7 +377,7 @@
|
||||
"<span class='userdanger'>[L.name] has attempted to bite [src]!</span>", null, COMBAT_MESSAGE_RANGE)
|
||||
|
||||
/mob/living/attack_alien(mob/living/carbon/alien/humanoid/M)
|
||||
if((M != src) && M.a_intent != INTENT_HELP && check_shields(M, 0, "the [M.name]"))
|
||||
if((M != src) && M.a_intent != INTENT_HELP && (run_block(M, 0, "the [M.name]", ATTACK_TYPE_MELEE | ATTACK_TYPE_UNARMED, M, check_zone(M.zone_selected)) & BLOCK_SUCCESS))
|
||||
visible_message("<span class='danger'>[M] attempted to touch [src]!</span>")
|
||||
return FALSE
|
||||
switch(M.a_intent)
|
||||
@@ -427,14 +411,14 @@
|
||||
take_bodypart_damage(acidpwr * min(1, acid_volume * 0.1))
|
||||
return 1
|
||||
|
||||
/mob/living/proc/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = 0, tesla_shock = 0, illusion = 0, stun = TRUE)
|
||||
SEND_SIGNAL(src, COMSIG_LIVING_ELECTROCUTE_ACT, shock_damage)
|
||||
if(tesla_shock && (flags_1 & TESLA_IGNORE_1))
|
||||
/mob/living/proc/electrocute_act(shock_damage, source, siemens_coeff = 1, flags = NONE)
|
||||
SEND_SIGNAL(src, COMSIG_LIVING_ELECTROCUTE_ACT, shock_damage, source, siemens_coeff, flags)
|
||||
if((flags & SHOCK_TESLA) && (flags_1 & TESLA_IGNORE_1))
|
||||
return FALSE
|
||||
if(HAS_TRAIT(src, TRAIT_SHOCKIMMUNE))
|
||||
return FALSE
|
||||
if(shock_damage > 0)
|
||||
if(!illusion)
|
||||
if(!(flags & SHOCK_ILLUSION))
|
||||
adjustFireLoss(shock_damage)
|
||||
visible_message(
|
||||
"<span class='danger'>[src] was shocked by \the [source]!</span>", \
|
||||
|
||||
@@ -118,3 +118,22 @@
|
||||
|
||||
/// Next world.time when we can get the "you can't move while buckled to [thing]" message.
|
||||
var/buckle_message_cooldown = 0
|
||||
|
||||
//// CITADEL STATION COMBAT ////
|
||||
/// See __DEFINES/combat.dm
|
||||
var/combat_flags = COMBAT_FLAGS_STAMSYSTEM_EXEMPT
|
||||
/// Next world.time when we will show a visible message on entering combat mode voluntarily again.
|
||||
var/combatmessagecooldown = 0
|
||||
|
||||
var/incomingstammult = 1
|
||||
var/bufferedstam = 0
|
||||
var/stambuffer = 20
|
||||
var/stambufferregentime
|
||||
|
||||
//Sprint buffer---
|
||||
var/sprint_buffer = 42 //Tiles
|
||||
var/sprint_buffer_max = 42
|
||||
var/sprint_buffer_regen_ds = 0.3 //Tiles per world.time decisecond
|
||||
var/sprint_buffer_regen_last = 0 //last world.time this was regen'd for math.
|
||||
var/sprint_stamina_cost = 0.70 //stamina loss per tile while insufficient sprint buffer.
|
||||
//---End
|
||||
|
||||
@@ -33,9 +33,9 @@
|
||||
set name = "Rest"
|
||||
set category = "IC"
|
||||
if(client?.prefs?.autostand)
|
||||
intentionalresting = !intentionalresting
|
||||
to_chat(src, "<span class='notice'>You are now attempting to [intentionalresting ? "[!resting ? "lay down and ": ""]stay down" : "[resting ? "get up and ": ""]stay up"].</span>")
|
||||
if(intentionalresting && !resting)
|
||||
TOGGLE_BITFIELD(combat_flags, COMBAT_FLAG_INTENTIONALLY_RESTING)
|
||||
to_chat(src, "<span class='notice'>You are now attempting to [(combat_flags & COMBAT_FLAG_INTENTIONALLY_RESTING) ? "[!resting ? "lay down and ": ""]stay down" : "[resting ? "get up and ": ""]stay up"].</span>")
|
||||
if((combat_flags & COMBAT_FLAG_INTENTIONALLY_RESTING) && !resting)
|
||||
set_resting(TRUE, FALSE)
|
||||
else
|
||||
resist_a_rest()
|
||||
@@ -71,8 +71,8 @@
|
||||
var/restrained = restrained()
|
||||
var/pinned = resting && pulledby && pulledby.grab_state >= GRAB_AGGRESSIVE // Cit change - adds pinning for aggressive-grabbing people on the ground
|
||||
var/has_limbs = has_arms || ignore_legs || has_legs
|
||||
var/canmove = !immobilize && !stun && conscious && !paralyze && (!stat_softcrit || !pulledby) && !chokehold && !IsFrozen() && has_limbs && !pinned && !recoveringstam
|
||||
var/canresist = !stun && conscious && !stat_softcrit && !paralyze && has_limbs && !recoveringstam
|
||||
var/canmove = !immobilize && !stun && conscious && !paralyze && (!stat_softcrit || !pulledby) && !chokehold && !IsFrozen() && has_limbs && !pinned && !(combat_flags & COMBAT_FLAG_HARD_STAMCRIT)
|
||||
var/canresist = !stun && conscious && !stat_softcrit && !paralyze && has_limbs && !(combat_flags & COMBAT_FLAG_HARD_STAMCRIT)
|
||||
|
||||
if(canmove)
|
||||
mobility_flags |= MOBILITY_MOVE
|
||||
@@ -84,7 +84,7 @@
|
||||
else
|
||||
mobility_flags &= ~MOBILITY_RESIST
|
||||
|
||||
var/canstand_involuntary = conscious && !stat_softcrit && !knockdown && !chokehold && !paralyze && (ignore_legs || has_legs) && !(buckled && buckled.buckle_lying) && !recoveringstam
|
||||
var/canstand_involuntary = conscious && !stat_softcrit && !knockdown && !chokehold && !paralyze && (ignore_legs || has_legs) && !(buckled && buckled.buckle_lying) && !(combat_flags & COMBAT_FLAG_HARD_STAMCRIT)
|
||||
var/canstand = canstand_involuntary && !resting
|
||||
|
||||
var/should_be_lying = !canstand
|
||||
@@ -107,7 +107,7 @@
|
||||
else
|
||||
mobility_flags |= MOBILITY_UI|MOBILITY_PULL
|
||||
|
||||
var/canitem_general = !paralyze && !stun && conscious && !(stat_softcrit) && !chokehold && !restrained && has_arms && !recoveringstam
|
||||
var/canitem_general = !paralyze && !stun && conscious && !(stat_softcrit) && !chokehold && !restrained && has_arms && !(combat_flags & COMBAT_FLAG_HARD_STAMCRIT)
|
||||
if(canitem_general)
|
||||
mobility_flags |= (MOBILITY_USE | MOBILITY_PICKUP | MOBILITY_STORAGE | MOBILITY_HOLD)
|
||||
else
|
||||
@@ -149,7 +149,7 @@
|
||||
lying_prev = lying
|
||||
|
||||
//Handle citadel autoresist
|
||||
if(CHECK_MOBILITY(src, MOBILITY_MOVE) && !intentionalresting && canstand_involuntary && iscarbon(src) && client?.prefs?.autostand)//CIT CHANGE - adds autostanding as a preference
|
||||
if(CHECK_MOBILITY(src, MOBILITY_MOVE) && !(combat_flags & COMBAT_FLAG_INTENTIONALLY_RESTING) && canstand_involuntary && iscarbon(src) && client?.prefs?.autostand)//CIT CHANGE - adds autostanding as a preference
|
||||
addtimer(CALLBACK(src, .proc/resist_a_rest, TRUE), 0) //CIT CHANGE - ditto
|
||||
|
||||
// Movespeed mods based on arms/legs quantity
|
||||
@@ -161,7 +161,7 @@
|
||||
if(!has_legs && has_arms < 2)
|
||||
limbless_slowdown += 6 - (has_arms * 3)
|
||||
if(limbless_slowdown)
|
||||
add_movespeed_modifier(MOVESPEED_ID_LIVING_LIMBLESS, update=TRUE, priority=100, override=TRUE, multiplicative_slowdown=limbless_slowdown, movetypes=GROUND)
|
||||
add_movespeed_modifier(MOVESPEED_ID_LIVING_LIMBLESS, update=TRUE, priority=100, override=TRUE, multiplicative_slowdown=limbless_slowdown, blacklisted_movetypes = FLYING|FLOATING)
|
||||
else
|
||||
remove_movespeed_modifier(MOVESPEED_ID_LIVING_LIMBLESS, update=TRUE)
|
||||
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
/mob/living/Moved()
|
||||
. = ..()
|
||||
update_turf_movespeed(loc)
|
||||
if(is_shifted)
|
||||
is_shifted = FALSE
|
||||
pixel_x = get_standard_pixel_x_offset(lying)
|
||||
pixel_y = get_standard_pixel_y_offset(lying)
|
||||
|
||||
/mob/living/CanPass(atom/movable/mover, turf/target)
|
||||
if((mover.pass_flags & PASSMOB))
|
||||
@@ -27,8 +31,16 @@
|
||||
|
||||
/mob/living/update_config_movespeed()
|
||||
update_move_intent_slowdown()
|
||||
sprint_buffer_max = CONFIG_GET(number/movedelay/sprint_buffer_max)
|
||||
sprint_buffer_regen_ds = CONFIG_GET(number/movedelay/sprint_buffer_regen_per_ds)
|
||||
sprint_stamina_cost = CONFIG_GET(number/movedelay/sprint_stamina_cost)
|
||||
return ..()
|
||||
|
||||
/mob/living/movement_delay(ignorewalk = 0)
|
||||
. = ..()
|
||||
if(!CHECK_MOBILITY(src, MOBILITY_STAND))
|
||||
. += 6
|
||||
|
||||
/// whether or not we can slide under another living mob. defaults to if we're not dense. CanPass should check "overriding circumstances" like buckled mobs/having PASSMOB flag, etc.
|
||||
/mob/living/proc/can_move_under_living(mob/living/other)
|
||||
return !density
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
/mob/living/ComponentInitialize()
|
||||
. = ..()
|
||||
RegisterSignal(src, SIGNAL_TRAIT(TRAIT_SPRINT_LOCKED), .proc/update_sprint_lock)
|
||||
|
||||
/mob/living/proc/update_sprint_icon()
|
||||
var/obj/screen/sprintbutton/S = locate() in hud_used?.static_inventory
|
||||
S?.update_icon()
|
||||
|
||||
/mob/living/proc/update_hud_sprint_bar()
|
||||
hud_used?.sprint_buffer?.update_to_mob(src)
|
||||
|
||||
/mob/living/proc/update_sprint_lock()
|
||||
var/locked = HAS_TRAIT(src, TRAIT_SPRINT_LOCKED)
|
||||
var/current = (combat_flags & COMBAT_FLAG_SPRINT_ACTIVE)
|
||||
var/desired = (combat_flags & COMBAT_FLAG_SPRINT_TOGGLED)
|
||||
if(locked)
|
||||
if(current)
|
||||
disable_sprint_mode(FALSE)
|
||||
else
|
||||
if(current)
|
||||
if(!desired)
|
||||
disable_sprint_mode(FALSE)
|
||||
else
|
||||
if(desired)
|
||||
enable_sprint_mode(FALSE)
|
||||
update_sprint_icon()
|
||||
|
||||
/mob/living/proc/enable_sprint_mode(update_icon = TRUE)
|
||||
if(combat_flags & COMBAT_FLAG_SPRINT_ACTIVE)
|
||||
return
|
||||
ENABLE_BITFIELD(combat_flags, COMBAT_FLAG_SPRINT_ACTIVE)
|
||||
if(update_icon)
|
||||
update_sprint_icon()
|
||||
|
||||
/mob/living/proc/disable_sprint_mode(update_icon = TRUE)
|
||||
if(!(combat_flags & COMBAT_FLAG_SPRINT_ACTIVE))
|
||||
return
|
||||
DISABLE_BITFIELD(combat_flags, COMBAT_FLAG_SPRINT_ACTIVE)
|
||||
if(update_icon)
|
||||
update_sprint_icon()
|
||||
|
||||
/mob/living/proc/enable_intentional_sprint_mode()
|
||||
if((combat_flags & COMBAT_FLAG_SPRINT_TOGGLED) && (combat_flags & COMBAT_FLAG_SPRINT_ACTIVE))
|
||||
return
|
||||
ENABLE_BITFIELD(combat_flags, COMBAT_FLAG_SPRINT_TOGGLED)
|
||||
if(!HAS_TRAIT(src, TRAIT_SPRINT_LOCKED) && !(combat_flags & COMBAT_FLAG_SPRINT_ACTIVE))
|
||||
enable_sprint_mode(FALSE)
|
||||
update_sprint_icon()
|
||||
return TRUE
|
||||
|
||||
/mob/living/proc/disable_intentional_sprint_mode()
|
||||
if(!(combat_flags & COMBAT_FLAG_SPRINT_TOGGLED) && !(combat_flags & COMBAT_FLAG_SPRINT_ACTIVE))
|
||||
return
|
||||
DISABLE_BITFIELD(combat_flags, COMBAT_FLAG_SPRINT_TOGGLED)
|
||||
if(combat_flags & COMBAT_FLAG_SPRINT_ACTIVE)
|
||||
disable_sprint_mode(FALSE)
|
||||
update_sprint_icon()
|
||||
|
||||
/mob/living/proc/user_toggle_intentional_sprint_mode()
|
||||
var/old = (combat_flags & COMBAT_FLAG_SPRINT_TOGGLED)
|
||||
if(old)
|
||||
disable_intentional_sprint_mode()
|
||||
if((m_intent == MOVE_INTENT_RUN) && CHECK_ALL_MOBILITY(src, MOBILITY_STAND|MOBILITY_MOVE))
|
||||
playsound_local(src, 'sound/misc/sprintdeactivate.ogg', 50, FALSE, pressure_affected = FALSE)
|
||||
else
|
||||
enable_intentional_sprint_mode()
|
||||
if((m_intent == MOVE_INTENT_RUN) && CHECK_ALL_MOBILITY(src, MOBILITY_STAND|MOBILITY_MOVE))
|
||||
playsound_local(src, 'sound/misc/sprintactivate.ogg', 50, FALSE, pressure_affected = FALSE)
|
||||
|
||||
/mob/living/proc/sprint_hotkey(targetstatus)
|
||||
if(targetstatus != FORCE_BOOLEAN(combat_flags & COMBAT_FLAG_SPRINT_ACTIVE))
|
||||
default_toggle_sprint()
|
||||
|
||||
/mob/living/proc/doSprintLossTiles(amount)
|
||||
return
|
||||
|
||||
// Silicons have snowflake behavior.
|
||||
/mob/living/proc/default_toggle_sprint()
|
||||
return user_toggle_intentional_sprint_mode()
|
||||
@@ -24,4 +24,4 @@
|
||||
if(ranged_ability)
|
||||
ranged_ability.add_ranged_ability(src, "<span class='notice'>You currently have <b>[ranged_ability]</b> active!</span>")
|
||||
if(vore_init && !vorepref_init) //Vore's been initialized, voreprefs haven't. If this triggers then that means that voreprefs failed to load due to the client being missing.
|
||||
apply_vore_prefs()
|
||||
copy_from_prefs_vr()
|
||||
|
||||
@@ -695,7 +695,7 @@
|
||||
holo_icon = client.prefs.get_filtered_holoform(HOLOFORM_FILTER_AI)
|
||||
else
|
||||
holo_icon = getHologramIcon(icon('icons/mob/ai.dmi', "female"))
|
||||
else if("xeno queen")
|
||||
if("xeno queen")
|
||||
holo_icon = getHologramIcon(icon(icon_list[input],"alienq"))
|
||||
else
|
||||
holo_icon = getHologramIcon(icon(icon_list[input], input))
|
||||
@@ -1004,3 +1004,28 @@
|
||||
. = ..()
|
||||
if(.)
|
||||
end_multicam()
|
||||
|
||||
/mob/living/silicon/ai/verb/ai_cryo()
|
||||
set name = "AI Cryogenic Stasis"
|
||||
set desc = "Puts the current AI personality into cryogenic stasis, freeing the space for another."
|
||||
set category = "AI Commands"
|
||||
|
||||
if(incapacitated())
|
||||
return
|
||||
switch(alert("Would you like to enter cryo? This will ghost you. Remember to AHELP before cryoing out of important roles, even with no admins online.",,"Yes.","No."))
|
||||
if("Yes.")
|
||||
src.ghostize(FALSE, penalize = TRUE)
|
||||
var/announce_rank = "Artificial Intelligence,"
|
||||
if(GLOB.announcement_systems.len)
|
||||
// Sends an announcement the AI has cryoed.
|
||||
var/obj/machinery/announcement_system/announcer = pick(GLOB.announcement_systems)
|
||||
announcer.announce("CRYOSTORAGE", src.real_name, announce_rank, list())
|
||||
new /obj/structure/AIcore/latejoin_inactive(loc)
|
||||
if(src.mind)
|
||||
//Handle job slot/tater cleanup.
|
||||
if(src.mind.assigned_role == "AI")
|
||||
SSjob.FreeRole("AI")
|
||||
src.mind.special_role = null
|
||||
qdel(src)
|
||||
else
|
||||
return
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
layer = BELOW_MOB_LAYER
|
||||
var/obj/item/instrument/piano_synth/internal_instrument
|
||||
silicon_privileges = PRIVILEDGES_PAI
|
||||
var/datum/element/mob_holder/current_mob_holder //because only a few of their chassis can be actually held.
|
||||
|
||||
var/network = "ss13"
|
||||
var/obj/machinery/camera/current = null
|
||||
@@ -142,6 +141,11 @@
|
||||
ALM.Grant(src)
|
||||
emitter_next_use = world.time + 10 SECONDS
|
||||
|
||||
/mob/living/silicon/pai/ComponentInitialize()
|
||||
. = ..()
|
||||
if(possible_chassis[chassis])
|
||||
AddElement(/datum/element/mob_holder, chassis, 'icons/mob/pai_item_head.dmi', 'icons/mob/pai_item_rh.dmi', 'icons/mob/pai_item_lh.dmi', ITEM_SLOT_HEAD)
|
||||
|
||||
/mob/living/silicon/pai/Life()
|
||||
if(hacking)
|
||||
process_hack()
|
||||
@@ -302,11 +306,11 @@
|
||||
/obj/item/paicard/attackby(obj/item/W, mob/user, params)
|
||||
..()
|
||||
user.set_machine(src)
|
||||
if(pai.encryptmod == TRUE)
|
||||
if(W.tool_behaviour == TOOL_SCREWDRIVER)
|
||||
pai.radio.attackby(W, user, params)
|
||||
else if(istype(W, /obj/item/encryptionkey))
|
||||
pai.radio.attackby(W, user, params)
|
||||
var/encryption_key_stuff = W.tool_behaviour == TOOL_SCREWDRIVER || istype(W, /obj/item/encryptionkey)
|
||||
if(!encryption_key_stuff)
|
||||
return
|
||||
if(pai?.encryptmod)
|
||||
pai.radio.attackby(W, user, params)
|
||||
else
|
||||
to_chat(user, "Encryption Key ports not configured.")
|
||||
|
||||
|
||||
@@ -76,6 +76,7 @@
|
||||
var/list/choices = list("Preset - Basic", "Preset - Dynamic")
|
||||
if(CONFIG_GET(flag/pai_custom_holoforms))
|
||||
choices += "Custom"
|
||||
var/old_chassis = chassis
|
||||
var/choicetype = input(src, "What type of chassis do you want to use?") as null|anything in choices
|
||||
if(!choicetype)
|
||||
return FALSE
|
||||
@@ -95,10 +96,10 @@
|
||||
dynamic_chassis = choice
|
||||
resist_a_rest(FALSE, TRUE)
|
||||
update_icon()
|
||||
current_mob_holder?.Detach(src)
|
||||
current_mob_holder = null
|
||||
if(possible_chassis[old_chassis])
|
||||
RemoveElement(/datum/element/mob_holder, old_chassis, 'icons/mob/pai_item_head.dmi', 'icons/mob/pai_item_rh.dmi', 'icons/mob/pai_item_lh.dmi', ITEM_SLOT_HEAD)
|
||||
if(possible_chassis[chassis])
|
||||
current_mob_holder = AddElement(/datum/element/mob_holder, chassis, 'icons/mob/pai_item_head.dmi', 'icons/mob/pai_item_rh.dmi', 'icons/mob/pai_item_lh.dmi', ITEM_SLOT_HEAD)
|
||||
AddElement(/datum/element/mob_holder, chassis, 'icons/mob/pai_item_head.dmi', 'icons/mob/pai_item_rh.dmi', 'icons/mob/pai_item_lh.dmi', ITEM_SLOT_HEAD)
|
||||
to_chat(src, "<span class='boldnotice'>You switch your holochassis projection composite to [chassis]</span>")
|
||||
|
||||
/mob/living/silicon/pai/lay_down()
|
||||
|
||||
@@ -78,6 +78,7 @@
|
||||
dat = {"<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv='Content-Type' content='text/html; charset=UTF-8'>
|
||||
<style type=\"text/css\">
|
||||
body { background-image:url('html/paigrid.png'); }
|
||||
|
||||
@@ -282,9 +283,7 @@
|
||||
T.visible_message("<span class='warning'>A port on [src] opens to reveal [cable], which promptly falls to the floor.</span>", "<span class='italics'>You hear the soft click of something light and hard falling to the ground.</span>")
|
||||
if("loudness")
|
||||
if(subscreen == 1) // Open Instrument
|
||||
internal_instrument.interact(src)
|
||||
if(subscreen == 2) // Change Instrument type
|
||||
internal_instrument.selectInstrument()
|
||||
internal_instrument.ui_interact(src)
|
||||
|
||||
//updateUsrDialog() We only need to account for the single mob this is intended for, and he will *always* be able to call this window
|
||||
paiInterface() // So we'll just call the update directly rather than doing some default checks
|
||||
@@ -665,4 +664,4 @@
|
||||
var/dat = "<h3>Sound Synthetizer</h3>"
|
||||
dat += "<a href='byond://?src=[REF(src)];software=loudness;sub=1'>Open Synthesizer Interface</a><br>"
|
||||
dat += "<a href='byond://?src=[REF(src)];software=loudness;sub=2'>Choose Instrument Type</a>"
|
||||
return dat
|
||||
return dat
|
||||
|
||||
@@ -10,6 +10,8 @@
|
||||
has_limbs = 1
|
||||
hud_type = /datum/hud/robot
|
||||
|
||||
blocks_emissive = EMISSIVE_BLOCK_UNIQUE
|
||||
|
||||
var/custom_name = ""
|
||||
var/braintype = "Cyborg"
|
||||
var/obj/item/robot_suit/robot_suit = null //Used for deconstruction to remember what the borg was constructed out of..
|
||||
@@ -968,7 +970,8 @@
|
||||
if(IsUnconscious() || IsStun() || IsParalyzed() || getOxyLoss() > maxHealth*0.5)
|
||||
if(stat == CONSCIOUS)
|
||||
stat = UNCONSCIOUS
|
||||
blind_eyes(1)
|
||||
if(!eye_blind)
|
||||
blind_eyes(1)
|
||||
update_mobility()
|
||||
update_headlamp()
|
||||
else
|
||||
@@ -1115,6 +1118,7 @@
|
||||
desc = "Stop controlling your shell and resume normal core operations."
|
||||
icon_icon = 'icons/mob/actions/actions_AI.dmi'
|
||||
button_icon_state = "ai_core"
|
||||
required_mobility_flags = NONE
|
||||
|
||||
/datum/action/innate/undeployment/Trigger()
|
||||
if(!..())
|
||||
@@ -1236,4 +1240,4 @@
|
||||
|
||||
if(usr.stat == DEAD)
|
||||
return //won't work if dead
|
||||
ai_roster()
|
||||
ai_roster()
|
||||
|
||||
@@ -821,7 +821,6 @@
|
||||
/obj/item/gps/cyborg,
|
||||
/obj/item/weapon/gripper/mining,
|
||||
/obj/item/cyborg_clamp,
|
||||
/obj/item/card/id/miningborg,
|
||||
/obj/item/stack/marker_beacon,
|
||||
/obj/item/destTagger,
|
||||
/obj/item/stack/packageWrap)
|
||||
@@ -914,8 +913,8 @@
|
||||
/obj/item/crowbar/cyborg,
|
||||
/obj/item/reagent_containers/borghypo/syndicate,
|
||||
/obj/item/twohanded/shockpaddles/syndicate,
|
||||
/obj/item/healthanalyzer,
|
||||
/obj/item/surgical_drapes,
|
||||
/obj/item/healthanalyzer/advanced,
|
||||
/obj/item/surgical_drapes/advanced,
|
||||
/obj/item/retractor,
|
||||
/obj/item/hemostat,
|
||||
/obj/item/cautery,
|
||||
@@ -1023,4 +1022,4 @@
|
||||
/datum/robot_energy_storage/wrapping_paper
|
||||
max_energy = 30
|
||||
recharge_rate = 1
|
||||
name = "Wrapping Paper Storage"
|
||||
name = "Wrapping Paper Storage"
|
||||
|
||||
@@ -12,3 +12,15 @@
|
||||
/mob/living/silicon/robot/experience_pressure_difference(pressure_difference, direction)
|
||||
if(!magpulse)
|
||||
return ..()
|
||||
|
||||
/mob/living/silicon/robot/Move(NewLoc, direct)
|
||||
. = ..()
|
||||
if(. && (combat_flags & COMBAT_FLAG_SPRINT_ACTIVE) && !(movement_type & FLYING) && CHECK_ALL_MOBILITY(src, MOBILITY_STAND | MOBILITY_MOVE))
|
||||
if(!(cell?.use(25)))
|
||||
default_toggle_sprint(TRUE)
|
||||
|
||||
/mob/living/silicon/robot/movement_delay()
|
||||
. = ..()
|
||||
if(!resting && !(combat_flags & COMBAT_FLAG_SPRINT_ACTIVE))
|
||||
. += 1
|
||||
. += speed
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
/mob/living/silicon/robot/default_toggle_sprint(shutdown = FALSE)
|
||||
var/current = (combat_flags & COMBAT_FLAG_SPRINT_ACTIVE)
|
||||
if(current || shutdown || !cell || (cell.charge < 25) || !cansprint)
|
||||
disable_intentional_sprint_mode()
|
||||
if(CHECK_MULTIPLE_BITFIELDS(mobility_flags, MOBILITY_STAND|MOBILITY_MOVE))
|
||||
if(shutdown)
|
||||
playsound_local(src, 'sound/effects/light_flicker.ogg', 50, FALSE, pressure_affected = FALSE)
|
||||
playsound_local(src, 'sound/misc/sprintdeactivate.ogg', 50, FALSE, pressure_affected = FALSE)
|
||||
else
|
||||
enable_intentional_sprint_mode()
|
||||
if(CHECK_MULTIPLE_BITFIELDS(mobility_flags, MOBILITY_STAND|MOBILITY_MOVE))
|
||||
playsound_local(src, 'sound/misc/sprintactivate.ogg', 50, FALSE, pressure_affected = FALSE)
|
||||
@@ -41,7 +41,7 @@
|
||||
else
|
||||
add_overlay("ov-opencover -c")
|
||||
if(hat)
|
||||
var/mutable_appearance/head_overlay = hat.build_worn_icon(state = hat.icon_state, default_layer = 20, default_icon_file = 'icons/mob/head.dmi')
|
||||
var/mutable_appearance/head_overlay = hat.build_worn_icon(default_layer = 20, default_icon_file = 'icons/mob/clothing/head.dmi', override_state = hat.icon_state)
|
||||
head_overlay.pixel_y += hat_offset
|
||||
add_overlay(head_overlay)
|
||||
update_fire()
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
speech_span = SPAN_ROBOT
|
||||
flags_1 = PREVENT_CONTENTS_EXPLOSION_1 | HEAR_1
|
||||
no_vore = TRUE
|
||||
/// Enable sprint system but not stamina
|
||||
combat_flags = COMBAT_FLAGS_STAMEXEMPT_YESSPRINT
|
||||
|
||||
var/datum/ai_laws/laws = null//Now... THEY ALL CAN ALL HAVE LAWS
|
||||
var/last_lawchange_announce = 0
|
||||
@@ -390,7 +392,7 @@
|
||||
return aicamera.selectpicture(user)
|
||||
|
||||
/mob/living/silicon/proc/ai_roster()
|
||||
var/dat = "<html><head><title>Crew Roster</title></head><body><b>Crew Roster:</b><br><br>"
|
||||
var/dat = "<html><head><meta http-equiv='Content-Type' content='text/html; charset=UTF-8'><title>Crew Roster</title></head><body><b>Crew Roster:</b><br><br>"
|
||||
|
||||
dat += GLOB.data_core.get_manifest()
|
||||
dat += "</body></html>"
|
||||
|
||||
@@ -85,11 +85,11 @@
|
||||
return
|
||||
return ..()
|
||||
|
||||
/mob/living/silicon/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = 0, tesla_shock = 0, illusion = 0, stun = TRUE)
|
||||
/mob/living/silicon/electrocute_act(shock_damage, source, siemens_coeff = 1, flags = NONE)
|
||||
if(buckled_mobs)
|
||||
for(var/mob/living/M in buckled_mobs)
|
||||
unbuckle_mob(M)
|
||||
M.electrocute_act(shock_damage/100, source, siemens_coeff, safety, tesla_shock, illusion, stun) //Hard metal shell conducts!
|
||||
M.electrocute_act(shock_damage/100, source, siemens_coeff, flags) //Hard metal shell conducts!
|
||||
return 0 //So borgs they don't die trying to fix wiring
|
||||
|
||||
/mob/living/silicon/emp_act(severity)
|
||||
@@ -112,11 +112,15 @@
|
||||
|
||||
/mob/living/silicon/bullet_act(obj/item/projectile/P, def_zone)
|
||||
if(P.original != src || P.firer != src) //try to block or reflect the bullet, can't do so when shooting oneself
|
||||
if(reflect_bullet_check(P, def_zone))
|
||||
return -1 // complete projectile permutation
|
||||
if(check_shields(P, P.damage, "the [P.name]", PROJECTILE_ATTACK, P.armour_penetration))
|
||||
var/list/returnlist = list()
|
||||
var/returned = run_block(P, P.damage, "the [P.name]", ATTACK_TYPE_PROJECTILE, P.armour_penetration, P.firer, def_zone, returnlist)
|
||||
if(returned & BLOCK_SHOULD_REDIRECT)
|
||||
handle_projectile_attack_redirection(P, returnlist[BLOCK_RETURN_REDIRECT_METHOD])
|
||||
if(returned & BLOCK_REDIRECTED)
|
||||
return BULLET_ACT_FORCE_PIERCE
|
||||
if(returned & BLOCK_SUCCESS)
|
||||
P.on_hit(src, 100, def_zone)
|
||||
return 2
|
||||
return BULLET_ACT_BLOCK
|
||||
if((P.damage_type == BRUTE || P.damage_type == BURN))
|
||||
adjustBruteLoss(P.damage)
|
||||
if(prob(P.damage*1.5))
|
||||
|
||||
@@ -445,7 +445,6 @@ Pass the desired type path itself, declaring a temporary var beforehand is not r
|
||||
return scan_result
|
||||
else
|
||||
return FALSE //The current element failed assessment, move on to the next.
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/bot/proc/check_bot(targ)
|
||||
var/turf/T = get_turf(targ)
|
||||
|
||||
@@ -276,7 +276,7 @@ Auto Patrol[]"},
|
||||
if(BOT_PREP_ARREST) // preparing to arrest target
|
||||
|
||||
// see if he got away. If he's no no longer adjacent or inside a closet or about to get up, we hunt again.
|
||||
if(!Adjacent(target) || !isturf(target.loc) || !target.recoveringstam || target.getStaminaLoss() <= 120) // CIT CHANGE - replaces amountknockdown with recoveringstam and staminaloss checks
|
||||
if(!Adjacent(target) || !isturf(target.loc) || !(target.combat_flags & COMBAT_FLAG_HARD_STAMCRIT) || target.getStaminaLoss() <= 120) // CIT CHANGE - replaces amountknockdown with recoveringstam and staminaloss checks
|
||||
back_to_hunt()
|
||||
return
|
||||
|
||||
@@ -303,7 +303,7 @@ Auto Patrol[]"},
|
||||
back_to_idle()
|
||||
return
|
||||
|
||||
if(!Adjacent(target) || !isturf(target.loc) || (target.loc != target_lastloc && !target.recoveringstam && target.getStaminaLoss() <= 120)) //if he's changed loc and about to get up or not adjacent or got into a closet, we prep arrest again. CIT CHANGE - replaces amountknockdown with recoveringstam and staminaloss checks
|
||||
if(!Adjacent(target) || !isturf(target.loc) || (target.loc != target_lastloc && !(target.combat_flags & COMBAT_FLAG_HARD_STAMCRIT) && target.getStaminaLoss() <= 120)) //if he's changed loc and about to get up or not adjacent or got into a closet, we prep arrest again. CIT CHANGE - replaces amountknockdown with recoveringstam and staminaloss checks
|
||||
back_to_hunt()
|
||||
return
|
||||
else
|
||||
|
||||
@@ -523,9 +523,6 @@
|
||||
soft_reset()
|
||||
return
|
||||
|
||||
reagent_id = null
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/bot/medbot/proc/check_overdose(mob/living/carbon/patient,reagent_id,injection_amount)
|
||||
var/datum/reagent/R = GLOB.chemical_reagents_list[reagent_id]
|
||||
if(!R.overdose_threshold) //Some chems do not have an OD threshold
|
||||
|
||||
@@ -181,7 +181,7 @@
|
||||
var/list/data = list()
|
||||
data["on"] = on
|
||||
data["locked"] = locked
|
||||
data["siliconUser"] = hasSiliconAccessInArea(usr)
|
||||
data["siliconUser"] = hasSiliconAccessInArea(user)
|
||||
data["mode"] = mode ? mode_name[mode] : "Ready"
|
||||
data["modeStatus"] = ""
|
||||
switch(mode)
|
||||
|
||||
@@ -235,10 +235,11 @@ Auto Patrol: []"},
|
||||
playsound(src, 'sound/weapons/cablecuff.ogg', 30, TRUE, -2)
|
||||
C.visible_message("<span class='danger'>[src] is trying to put zipties on [C]!</span>",\
|
||||
"<span class='userdanger'>[src] is trying to put zipties on you!</span>")
|
||||
addtimer(CALLBACK(src, .proc/attempt_handcuff, C), 60)
|
||||
if(do_after(src, 60, FALSE, C))
|
||||
attempt_handcuff(C)
|
||||
|
||||
/mob/living/simple_animal/bot/secbot/proc/attempt_handcuff(mob/living/carbon/C)
|
||||
if( !on || !Adjacent(C) || !isturf(C.loc) ) //if he's in a closet or not adjacent, we cancel cuffing.
|
||||
if (!on)
|
||||
return
|
||||
if(!C.handcuffed)
|
||||
C.handcuffed = new /obj/item/restraints/handcuffs/cable/zipties/used(C)
|
||||
@@ -312,7 +313,7 @@ Auto Patrol: []"},
|
||||
if(BOT_PREP_ARREST) // preparing to arrest target
|
||||
|
||||
// see if he got away. If he's no no longer adjacent or inside a closet or about to get up, we hunt again.
|
||||
if( !Adjacent(target) || !isturf(target.loc) || target.getStaminaLoss() <= 120 || !target.recoveringstam) //CIT CHANGE - replaces amountknockdown with checks for stamina so secbots dont run into an infinite loop
|
||||
if( !Adjacent(target) || !isturf(target.loc) || target.getStaminaLoss() <= 120 || !(target.combat_flags & COMBAT_FLAG_HARD_STAMCRIT)) //CIT CHANGE - replaces amountknockdown with checks for stamina so secbots dont run into an infinite loop
|
||||
back_to_hunt()
|
||||
return
|
||||
|
||||
@@ -339,7 +340,7 @@ Auto Patrol: []"},
|
||||
back_to_idle()
|
||||
return
|
||||
|
||||
if(!Adjacent(target) || !isturf(target.loc) || (target.loc != target_lastloc && !target.recoveringstam && target.getStaminaLoss() <= 120)) //if he's changed loc and about to get up or not adjacent or got into a closet, we prep arrest again. CIT CHANGE - replaces amountknockdown with recoveringstam and staminaloss check
|
||||
if(!Adjacent(target) || !isturf(target.loc) || (target.loc != target_lastloc && !(target.combat_flags & COMBAT_FLAG_HARD_STAMCRIT) && target.getStaminaLoss() <= 120)) //if he's changed loc and about to get up or not adjacent or got into a closet, we prep arrest again. CIT CHANGE - replaces amountknockdown with recoveringstam and staminaloss check
|
||||
back_to_hunt()
|
||||
return
|
||||
else //Try arresting again if the target escapes.
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
response_help = "thinks better of touching"
|
||||
response_disarm = "flails at"
|
||||
response_harm = "punches"
|
||||
threat = 1
|
||||
speak_chance = 1
|
||||
icon = 'icons/mob/mob.dmi'
|
||||
speed = 0
|
||||
@@ -103,7 +104,7 @@
|
||||
/mob/living/simple_animal/hostile/construct/narsie_act()
|
||||
return
|
||||
|
||||
/mob/living/simple_animal/hostile/construct/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = 0, tesla_shock = 0, illusion = 0, stun = TRUE)
|
||||
/mob/living/simple_animal/hostile/construct/electrocute_act(shock_damage, source, siemens_coeff = 1, flags = NONE)
|
||||
return 0
|
||||
|
||||
/mob/living/simple_animal/hostile/construct/adjustHealth(amount, updating_health = TRUE, forced = FALSE)
|
||||
@@ -118,6 +119,7 @@
|
||||
desc = "A massive, armored construct built to spearhead attacks and soak up enemy fire."
|
||||
icon_state = "behemoth"
|
||||
icon_living = "behemoth"
|
||||
threat = 3
|
||||
maxHealth = 150
|
||||
health = 150
|
||||
response_harm = "harmlessly punches"
|
||||
@@ -180,6 +182,7 @@
|
||||
desc = "A wicked, clawed shell constructed to assassinate enemies and sow chaos behind enemy lines."
|
||||
icon_state = "floating"
|
||||
icon_living = "floating"
|
||||
threat = 3
|
||||
maxHealth = 65
|
||||
health = 65
|
||||
melee_damage_lower = 20
|
||||
@@ -389,6 +392,9 @@
|
||||
var/datum/antagonist/cult/C = owner.mind.has_antag_datum(/datum/antagonist/cult)
|
||||
if(!C)
|
||||
return
|
||||
if(!C.cult_team)
|
||||
to_chat(the_construct, "<span class='cult italic'>You are alone, and have no team.</span>")
|
||||
return
|
||||
var/datum/objective/eldergod/summon_objective = locate() in C.cult_team.objectives
|
||||
|
||||
if(summon_objective.check_completion())
|
||||
|
||||
@@ -82,7 +82,7 @@
|
||||
|
||||
/datum/outfit/piratecorpse
|
||||
name = "Pirate Corpse"
|
||||
uniform = /obj/item/clothing/under/pirate
|
||||
uniform = /obj/item/clothing/under/costume/pirate
|
||||
shoes = /obj/item/clothing/shoes/jackboots
|
||||
glasses = /obj/item/clothing/glasses/eyepatch
|
||||
head = /obj/item/clothing/head/bandana
|
||||
@@ -106,7 +106,7 @@
|
||||
|
||||
/datum/outfit/russiancorpse
|
||||
name = "Russian Corpse"
|
||||
uniform = /obj/item/clothing/under/soviet
|
||||
uniform = /obj/item/clothing/under/costume/soviet
|
||||
shoes = /obj/item/clothing/shoes/jackboots
|
||||
head = /obj/item/clothing/head/bearpelt
|
||||
gloves = /obj/item/clothing/gloves/color/black
|
||||
@@ -142,7 +142,7 @@
|
||||
|
||||
/datum/outfit/russiancorpse/officer
|
||||
name = "Russian Officer Corpse"
|
||||
uniform = /obj/item/clothing/under/rank/security/navyblue/russian
|
||||
uniform = /obj/item/clothing/under/costume/russian_officer
|
||||
suit = /obj/item/clothing/suit/armor/navyblue/russian
|
||||
shoes = /obj/item/clothing/shoes/combat
|
||||
ears = /obj/item/radio/headset
|
||||
@@ -174,7 +174,7 @@
|
||||
|
||||
/datum/outfit/nanotrasensoldiercorpse2
|
||||
name = "NT Private Security Officer Corpse"
|
||||
uniform = /obj/item/clothing/under/rank/security
|
||||
uniform = /obj/item/clothing/under/rank/security/officer
|
||||
suit = /obj/item/clothing/suit/armor/vest
|
||||
shoes = /obj/item/clothing/shoes/combat
|
||||
gloves = /obj/item/clothing/gloves/combat
|
||||
@@ -195,7 +195,7 @@
|
||||
|
||||
/datum/outfit/cat_butcher
|
||||
name = "Cat Butcher Uniform"
|
||||
uniform = /obj/item/clothing/under/rank/medical/green
|
||||
uniform = /obj/item/clothing/under/rank/medical/doctor/green
|
||||
suit = /obj/item/clothing/suit/apron/surgical
|
||||
shoes = /obj/item/clothing/shoes/sneakers/white
|
||||
gloves = /obj/item/clothing/gloves/color/latex/nitrile
|
||||
|
||||
@@ -5,10 +5,10 @@
|
||||
icon_living = "bumbles"
|
||||
icon_dead = "bumbles_dead"
|
||||
turns_per_move = 1
|
||||
response_help = "shoos"
|
||||
response_help = "pets"
|
||||
response_disarm = "brushes aside"
|
||||
response_harm = "squashes"
|
||||
speak_emote = list("bzzzs")
|
||||
speak_emote = list("buzzes")
|
||||
maxHealth = 100
|
||||
health = 100
|
||||
harm_intent_damage = 1
|
||||
@@ -20,10 +20,12 @@
|
||||
mob_size = MOB_SIZE_TINY
|
||||
mob_biotypes = MOB_ORGANIC|MOB_BEAST
|
||||
gold_core_spawnable = FRIENDLY_SPAWN
|
||||
verb_say = "bzzs"
|
||||
verb_ask = "bzzs inquisitively"
|
||||
verb_exclaim = "bzzs intensely"
|
||||
verb_yell = "bzzs intensely"
|
||||
verb_say = "buzzs"
|
||||
verb_ask = "buzzes inquisitively"
|
||||
verb_exclaim = "buzzes intensely"
|
||||
verb_yell = "buzzes intensely"
|
||||
emote_see = list("buzzes.", "makes a loud buzz.", "rolls several times.", "buzzes happily.")
|
||||
speak_chance = 1
|
||||
|
||||
/mob/living/simple_animal/pet/bumbles/Initialize()
|
||||
. = ..()
|
||||
@@ -44,3 +46,23 @@
|
||||
|
||||
/mob/living/simple_animal/pet/bumbles/bee_friendly()
|
||||
return TRUE //treaty signed at the Beeneeva convention
|
||||
|
||||
/mob/living/simple_animal/pet/bumbles/handle_automated_movement()
|
||||
. = ..()
|
||||
if(!isturf(loc) || buckled)
|
||||
return
|
||||
if(!resting && prob(1))
|
||||
emote("me", EMOTE_VISIBLE, pick("curls up on the surface below ", "is looking very sleepy.", "buzzes softly ", "looks around for a flower nap "))
|
||||
set_resting(TRUE)
|
||||
else if (resting && prob(1))
|
||||
emote("me", EMOTE_VISIBLE, pick("wakes up with a smiling buzz.", "rolls upside down before waking up.", "stops resting."))
|
||||
set_resting(FALSE)
|
||||
|
||||
/mob/living/simple_animal/pet/bumbles/update_mobility()
|
||||
. = ..()
|
||||
if(stat != DEAD)
|
||||
if(!CHECK_MOBILITY(src, MOBILITY_STAND))
|
||||
icon_state = "[icon_living]_rest"
|
||||
else
|
||||
icon_state = "[icon_living]"
|
||||
regenerate_icons()
|
||||
|
||||
@@ -363,10 +363,8 @@
|
||||
icon_dead = "old_corgi_dead"
|
||||
desc = "At a ripe old age of [record_age] Ian's not as spry as he used to be, but he'll always be the HoP's beloved corgi." //RIP
|
||||
turns_per_move = 20
|
||||
var/datum/element/mob_holder/ele = SSdcs.GetElement(/datum/element/mob_holder, held_icon)
|
||||
if(ele)
|
||||
ele.Detach(src)
|
||||
AddElement(/datum/element/mob_holder, "old_corgi")
|
||||
RemoveElement(/datum/element/mob_holder, held_icon)
|
||||
AddElement(/datum/element/mob_holder, "old_corgi")
|
||||
|
||||
/mob/living/simple_animal/pet/dog/corgi/Ian/Life()
|
||||
if(!stat && SSticker.current_state == GAME_STATE_FINISHED && !memory_saved)
|
||||
@@ -447,7 +445,7 @@
|
||||
sleep(3)
|
||||
step_to(src,movement_target,1)
|
||||
|
||||
if(movement_target) //Not redundant due to sleeps, Item can be gone in 6 decisecomds
|
||||
if(movement_target?.loc) //Not redundant due to sleeps, Item can be gone in 6 decisecomds
|
||||
if (movement_target.loc.x < src.x)
|
||||
setDir(WEST)
|
||||
else if (movement_target.loc.x > src.x)
|
||||
|
||||
@@ -105,7 +105,7 @@
|
||||
. = ..()
|
||||
if(can_be_held)
|
||||
//icon/item state is defined in mob_holder/drone_worn_icon()
|
||||
AddElement(/datum/element/mob_holder, null, 'icons/mob/head.dmi', 'icons/mob/inhands/clothing_righthand.dmi', 'icons/mob/inhands/clothing_lefthand.dmi', ITEM_SLOT_HEAD, /datum/element/mob_holder.proc/drone_worn_icon)
|
||||
AddElement(/datum/element/mob_holder, null, 'icons/mob/clothing/head.dmi', 'icons/mob/inhands/clothing_righthand.dmi', 'icons/mob/inhands/clothing_lefthand.dmi', ITEM_SLOT_HEAD, /datum/element/mob_holder.proc/drone_worn_icon)
|
||||
|
||||
/mob/living/simple_animal/drone/med_hud_set_health()
|
||||
var/image/holder = hud_list[DIAG_HUD]
|
||||
@@ -277,7 +277,7 @@
|
||||
// Why would bees pay attention to drones?
|
||||
return 1
|
||||
|
||||
/mob/living/simple_animal/drone/electrocute_act(shock_damage, obj/source, siemens_coeff = 1, safety = 0, tesla_shock = 0, illusion = 0, stun = TRUE)
|
||||
/mob/living/simple_animal/drone/electrocute_act(shock_damage, source, siemens_coeff = 1, flags = NONE)
|
||||
return 0 //So they don't die trying to fix wiring
|
||||
|
||||
/mob/living/simple_animal/drone/can_see_reagents()
|
||||
|
||||
@@ -92,8 +92,8 @@
|
||||
return
|
||||
if(hack)
|
||||
if(hacked)
|
||||
return
|
||||
Stun(40)
|
||||
return
|
||||
if(clockwork)
|
||||
to_chat(src, "<span class='large_brass'><b>ERROR: LAW OVERRIDE DETECTED</b></span>")
|
||||
to_chat(src, "<span class='heavy_brass'>From now on, these are your laws:</span>")
|
||||
|
||||
@@ -28,12 +28,7 @@
|
||||
var/y_shift = getItemPixelShiftY()
|
||||
|
||||
if(r_hand)
|
||||
|
||||
var/r_state = r_hand.item_state
|
||||
if(!r_state)
|
||||
r_state = r_hand.icon_state
|
||||
|
||||
var/mutable_appearance/r_hand_overlay = r_hand.build_worn_icon(state = r_state, default_layer = DRONE_HANDS_LAYER, default_icon_file = r_hand.righthand_file, isinhands = TRUE)
|
||||
var/mutable_appearance/r_hand_overlay = r_hand.build_worn_icon(default_layer = DRONE_HANDS_LAYER, default_icon_file = r_hand.righthand_file, isinhands = TRUE)
|
||||
if(y_shift)
|
||||
r_hand_overlay.pixel_y += y_shift
|
||||
|
||||
@@ -46,12 +41,7 @@
|
||||
client.screen |= r_hand
|
||||
|
||||
if(l_hand)
|
||||
|
||||
var/l_state = l_hand.item_state
|
||||
if(!l_state)
|
||||
l_state = l_hand.icon_state
|
||||
|
||||
var/mutable_appearance/l_hand_overlay = l_hand.build_worn_icon(state = l_state, default_layer = DRONE_HANDS_LAYER, default_icon_file = l_hand.lefthand_file, isinhands = TRUE)
|
||||
var/mutable_appearance/l_hand_overlay = l_hand.build_worn_icon(default_layer = DRONE_HANDS_LAYER, default_icon_file = l_hand.lefthand_file, isinhands = TRUE)
|
||||
if(y_shift)
|
||||
l_hand_overlay.pixel_y += y_shift
|
||||
|
||||
@@ -82,10 +72,10 @@
|
||||
if(client && hud_used && hud_used.hud_shown)
|
||||
head.screen_loc = ui_drone_head
|
||||
client.screen += head
|
||||
var/used_head_icon = 'icons/mob/head.dmi'
|
||||
var/used_head_icon = 'icons/mob/clothing/head.dmi'
|
||||
if(istype(head, /obj/item/clothing/mask))
|
||||
used_head_icon = 'icons/mob/mask.dmi'
|
||||
var/mutable_appearance/head_overlay = head.build_worn_icon(state = head.icon_state, default_layer = DRONE_HEAD_LAYER, default_icon_file = used_head_icon)
|
||||
used_head_icon = 'icons/mob/clothing/mask.dmi'
|
||||
var/mutable_appearance/head_overlay = head.build_worn_icon(default_layer = DRONE_HEAD_LAYER, default_icon_file = used_head_icon, override_state = head.icon_state)
|
||||
head_overlay.pixel_y -= 15
|
||||
|
||||
drone_overlays[DRONE_HEAD_LAYER] = head_overlay
|
||||
|
||||
@@ -33,6 +33,10 @@
|
||||
if (!(istype(src, /mob/living/simple_animal/pet/gondola/gondolapod)))
|
||||
CreateGondola()
|
||||
|
||||
/mob/living/simple_animal/pet/gondola/ComponentInitialize()
|
||||
. = ..()
|
||||
AddElement(/datum/element/spellcasting, SPELL_SKIP_VOCAL) // so they can cast spells despite being silent.
|
||||
|
||||
/mob/living/simple_animal/pet/gondola/proc/CreateGondola()
|
||||
icon_state = null
|
||||
icon_living = null
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user